Loading drivers/soc/qcom/spcom.c +14 −182 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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. * Loading Loading @@ -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. Loading @@ -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"); Loading @@ -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"); Loading Loading @@ -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; } Loading Loading @@ -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: Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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"); Loading Loading
drivers/soc/qcom/spcom.c +14 −182 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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. * Loading Loading @@ -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. Loading @@ -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"); Loading @@ -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"); Loading Loading @@ -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; } Loading Loading @@ -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: Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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"); Loading