Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2d968914 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "soc: qcom: spcom: Provide retry mechanism for spss"

parents 608f2d38 c7034ffa
Loading
Loading
Loading
Loading
+14 −182
Original line number Diff line number Diff line
@@ -271,26 +271,13 @@ struct spcom_device {

	int32_t nvm_ion_fd;
	struct mutex ioctl_lock;
	atomic_t subsys_req;
};

/* Device Driver State */
static struct spcom_device *spcom_dev;
static void *spcom_ipc_log_context;

/* Physical address of SP2SOC RMB shared register */
/* SP_SCSR_RMB_SP2SOC_IRQ_SET_ADDR */
static u32 spcom_sp2soc_rmb_reg_addr;
/* SP_SCSR_SP2SOC_IRQ_SET_SW_INIT_DONE_BMSK */
static u32 spcom_sp2soc_initdone_mask;
/* SP_SCSR_SP2SOC_IRQ_SET_PBL_DONE_BMSK */
static u32 spcom_sp2soc_pbldone_mask;

/* Physical address of SOC2SP RMB shared register */
/* SP_SCSR_RMB_SOC2SP_IRQ_SET_ADDR */
static u32 spcom_soc2sp_rmb_reg_addr;
/* Bit used by spcom kernel for indicating SSR to SP */
static u32 spcom_soc2sp_rmb_sp_ssr_mask;

/* static functions declaration */
static int spcom_create_channel_chardev(const char *name, bool is_sharable);
static int spcom_destroy_channel_chardev(const char *name);
@@ -298,9 +285,6 @@ static struct spcom_channel *spcom_find_channel_by_name(const char *name);
static int spcom_register_rpmsg_drv(struct spcom_channel *ch);
static int spcom_unregister_rpmsg_drv(struct spcom_channel *ch);

/* PIL's original SSR function*/
int (*desc_powerup)(const struct subsys_desc *) = NULL;

/**
 * spcom_is_channel_open() - channel is open on this side.
 *
@@ -641,47 +625,6 @@ static int spcom_handle_create_channel_command(void *cmd_buf, int cmd_size)
	return ret;
}

/**
 * spcom_local_powerup() - Helper function that causes PIL boot to skip
 * powerup. This function sets the INIT DONE register.
 *
 * @subsys: subsystem descriptor.
 *
 * Return: 0 on successful operation, negative value otherwise.
 */
static int spcom_local_powerup(const struct subsys_desc *subsys)
{
	void __iomem *regs;

	regs = ioremap_nocache(spcom_sp2soc_rmb_reg_addr, sizeof(u32));
	if (!regs)
		return -ENOMEM;

	writel_relaxed(spcom_sp2soc_pbldone_mask|spcom_sp2soc_initdone_mask,
		regs);
	iounmap(regs);
	spcom_pr_dbg("spcom local powerup - SPSS cold boot\n");
	return 0;
}

/**
 * spcom_local_powerup_after_fota() - SSR is not allowed after FOTA -
 * might cause cryptographic erase. Reset the device
 *
 * @subsys: subsystem descriptor.
 *
 * Return: 0 on successful operation, negative value otherwise.
 */
static int spcom_local_powerup_after_fota(const struct subsys_desc *subsys)
{
	(void)subsys;

	spcom_pr_err("SSR after firmware update before calling IAR update - panic\n");
	panic("SSR after SPU firmware update\n");

	return 0;
}

/**
 * spcom_handle_restart_sp_command() - Handle Restart SP command from
 * user space.
@@ -695,8 +638,6 @@ static int spcom_handle_restart_sp_command(void *cmd_buf, int cmd_size)
{
	void *subsystem_get_retval = NULL;
	struct spcom_user_restart_sp_command *cmd = cmd_buf;
	struct subsys_desc *desc_p = NULL;
	int (*desc_powerup)(const struct subsys_desc *) = NULL;

	if (!cmd) {
		spcom_pr_err("NULL cmd_buf\n");
@@ -712,51 +653,16 @@ static int spcom_handle_restart_sp_command(void *cmd_buf, int cmd_size)
	spcom_pr_dbg("restart - PIL FW loading initiated: preloaded=%d\n",
		cmd->arg);

	if (cmd->arg) {
		subsystem_get_retval = find_subsys_device("spss");
		if (!subsystem_get_retval) {
			spcom_pr_err("restart - no device\n");
			return -ENODEV;
		}

		desc_p = *(struct subsys_desc **)subsystem_get_retval;
		if (!desc_p) {
			spcom_pr_err("restart - no device\n");
			return -ENODEV;
		}

		spcom_pr_dbg("restart - Name: %s FW name: %s Depends on: %s\n",
			desc_p->name, desc_p->fw_name, desc_p->pon_depends_on);
		desc_powerup = desc_p->powerup;
		/**
		 * Overwrite the subsys PIL powerup function with an spcom
		 * internal function which causes PIL to skip calling the
		 * PIL boot function. This is done because SP is already
		 * loaded in UEFI state and we do not want PIL to start
		 * loading the SP again. We still want to let PIL perform
		 * everything else wrt SP - hence calling the subsystem_get
		 * API with a spcom internal function that only writes the
		 * INIT DONE register on behalf of SP. Once done with this,
		 * we shall reset the PIL subsys power up function so that
		 * we let the PIL subsys to load/boot SP upon SSR
		 */
		desc_p->powerup = spcom_local_powerup;
	}

	subsystem_get_retval = subsystem_get("spss");
	if (!subsystem_get_retval) {
		spcom_pr_err("restart - unable to trigger PIL process for FW loading\n");
		return -EINVAL;
	if (IS_ERR_OR_NULL(subsystem_get_retval)) {
		spcom_pr_err("restart - spss crashed during device bootup\n");
		if (atomic_cmpxchg(&spcom_dev->subsys_req, 1, 0)) {
			subsystem_get_retval = subsystem_get("spss");
			if (IS_ERR_OR_NULL(subsystem_get_retval)) {
				spcom_pr_err("spss - restart - Failed start\n");
				return -ENODEV;
			}

	if (cmd->arg) {

		/* SPU got firmware update. Don't allow SSR*/
		if (cmd->is_updated) {
			desc_p->powerup = spcom_local_powerup_after_fota;
		} else {
			/* Reset the PIL subsystem power up function */
			desc_p->powerup = desc_powerup;
			spcom_pr_info("restart - spss started.\n");
		}
	}
	spcom_pr_dbg("restart - PIL FW loading process is complete\n");
@@ -1237,28 +1143,7 @@ static int spcom_handle_unlock_ion_buf_command(struct spcom_channel *ch,
 */
static int spcom_handle_enable_ssr_command(void)
{
	struct subsys_desc *desc_p = NULL;
	void *subsystem_get_retval = find_subsys_device("spss");

	if (!subsystem_get_retval) {
		spcom_pr_err("restart - no device\n");
		return -ENODEV;
	}

	desc_p = *(struct subsys_desc **)subsystem_get_retval;
	if (!desc_p) {
		spcom_pr_err("restart - no device\n");
		return -ENODEV;
	}

	if (!desc_powerup) {
		spcom_pr_err("no original SSR function\n");
		return -ENODEV;
	}

	desc_p->powerup = desc_powerup;
	spcom_pr_info("SSR is enabled after FOTA\n");

	spcom_pr_info("TBD: SSR is enabled after FOTA\n");
	return 0;
}

@@ -1893,8 +1778,6 @@ static inline int handle_poll(struct file *file,
	const char *name = file_to_filename(file);
	int ready = 0;
	int ret = 0;
	void __iomem *regs;


	switch (op->cmd_id) {
	case SPCOM_LINK_STATE_REQ:
@@ -1904,15 +1787,6 @@ static inline int handle_poll(struct file *file,
					  &spcom_dev->rpmsg_state_change);
			spcom_pr_dbg("ch [%s] link state change signaled\n",
				     name);
			regs = ioremap_nocache(spcom_soc2sp_rmb_reg_addr,
					sizeof(u32));
			if (regs) {
				writel_relaxed(spcom_soc2sp_rmb_sp_ssr_mask,
					regs);
				iounmap(regs);
			} else {
				spcom_pr_err("failed to set register indicating SSR\n");
			}
		}
		op->retval = atomic_read(&spcom_dev->rpmsg_dev_count) > 0;
		break;
@@ -2210,51 +2084,6 @@ static int spcom_parse_dt(struct device_node *np)
	int num_ch;
	int i;
	const char *name;
	u32 sp2soc_rmb_pbldone_bit = 0;
	u32 sp2soc_rmb_initdone_bit = 0;
	u32 soc2sp_rmb_sp_ssr_bit = 0;

	/* Read SP HLOS SCSR RMB IRQ register address */
	ret = of_property_read_u32(np, "qcom,spcom-sp2soc-rmb-reg-addr",
		&spcom_sp2soc_rmb_reg_addr);
	if (ret < 0) {
		spcom_pr_err("can't get sp2soc rmb reg addr\n");
		return ret;
	}

	ret = of_property_read_u32(np, "qcom,spcom-sp2soc-rmb-pbldone-bit",
		&sp2soc_rmb_pbldone_bit);
	if (ret < 0) {
		spcom_pr_err("can't get sp2soc rmb pbl done bit\n");
		return ret;
	}

	ret = of_property_read_u32(np, "qcom,spcom-sp2soc-rmb-initdone-bit",
		&sp2soc_rmb_initdone_bit);
	if (ret < 0) {
		spcom_pr_err("can't get sp2soc rmb sw init done bit\n");
		return ret;
	}

	spcom_sp2soc_pbldone_mask = BIT(sp2soc_rmb_pbldone_bit);
	spcom_sp2soc_initdone_mask = BIT(sp2soc_rmb_initdone_bit);

	/* Read SOC 2 SP SCSR RMB IRQ register address */
	ret = of_property_read_u32(np, "qcom,spcom-soc2sp-rmb-reg-addr",
		&spcom_soc2sp_rmb_reg_addr);
	if (ret < 0) {
		spcom_pr_err("can't get soc2sp rmb reg addr\n");
		return ret;
	}

	ret = of_property_read_u32(np, "qcom,spcom-soc2sp-rmb-sp-ssr-bit",
		&soc2sp_rmb_sp_ssr_bit);
	if (ret < 0) {
		spcom_pr_err("can't get soc2sp rmb SP SSR bit\n");
		return ret;
	}

	spcom_soc2sp_rmb_sp_ssr_mask = BIT(soc2sp_rmb_sp_ssr_bit);

	/* Get predefined channels info */
	num_ch = of_property_count_strings(np, propname);
@@ -2609,6 +2438,9 @@ static int spcom_probe(struct platform_device *pdev)
	if (ret < 0)
		goto fail_reg_chardev;

	if (of_property_read_bool(np, "qcom,boot-enabled"))
		atomic_set(&dev->subsys_req, 1);

	ret = spcom_create_predefined_channels_chardev();
	if (ret < 0) {
		pr_err("create character device failed\n");