@@ -79,6 +79,7 @@ struct stm32_mbox {
7979
8080struct stm32_rproc {
8181 struct reset_control * rst ;
82+ struct reset_control * hold_boot_rst ;
8283 struct stm32_syscon hold_boot ;
8384 struct stm32_syscon pdds ;
8485 struct stm32_syscon m4_state ;
@@ -88,7 +89,7 @@ struct stm32_rproc {
8889 struct stm32_rproc_mem * rmems ;
8990 struct stm32_mbox mb [MBOX_NB_MBX ];
9091 struct workqueue_struct * workqueue ;
91- bool secured_soc ;
92+ bool hold_boot_smc ;
9293 void __iomem * rsc_va ;
9394};
9495
@@ -413,13 +414,28 @@ static int stm32_rproc_set_hold_boot(struct rproc *rproc, bool hold)
413414 struct arm_smccc_res smc_res ;
414415 int val , err ;
415416
417+ /*
418+ * Three ways to manage the hold boot
419+ * - using SCMI: the hold boot is managed as a reset,
420+ * - using Linux(no SCMI): the hold boot is managed as a syscon register
421+ * - using SMC call (deprecated): use SMC reset interface
422+ */
423+
416424 val = hold ? HOLD_BOOT : RELEASE_BOOT ;
417425
418- if (IS_ENABLED (CONFIG_HAVE_ARM_SMCCC ) && ddata -> secured_soc ) {
426+ if (ddata -> hold_boot_rst ) {
427+ /* Use the SCMI reset controller */
428+ if (!hold )
429+ err = reset_control_deassert (ddata -> hold_boot_rst );
430+ else
431+ err = reset_control_assert (ddata -> hold_boot_rst );
432+ } else if (IS_ENABLED (CONFIG_HAVE_ARM_SMCCC ) && ddata -> hold_boot_smc ) {
433+ /* Use the SMC call */
419434 arm_smccc_smc (STM32_SMC_RCC , STM32_SMC_REG_WRITE ,
420435 hold_boot .reg , val , 0 , 0 , 0 , 0 , & smc_res );
421436 err = smc_res .a0 ;
422437 } else {
438+ /* Use syscon */
423439 err = regmap_update_bits (hold_boot .map , hold_boot .reg ,
424440 hold_boot .mask , val );
425441 }
@@ -717,34 +733,52 @@ static int stm32_rproc_parse_dt(struct platform_device *pdev,
717733 dev_info (dev , "wdg irq registered\n" );
718734 }
719735
720- ddata -> rst = devm_reset_control_get_by_index (dev , 0 );
736+ ddata -> rst = devm_reset_control_get_optional (dev , "mcu_rst" );
737+ if (!ddata -> rst ) {
738+ /* Try legacy fallback method: get it by index */
739+ ddata -> rst = devm_reset_control_get_by_index (dev , 0 );
740+ }
721741 if (IS_ERR (ddata -> rst ))
722742 return dev_err_probe (dev , PTR_ERR (ddata -> rst ),
723743 "failed to get mcu_reset\n" );
724744
725745 /*
726- * if platform is secured the hold boot bit must be written by
727- * smc call and read normally.
728- * if not secure the hold boot bit could be read/write normally
746+ * Three ways to manage the hold boot
747+ * - using SCMI: the hold boot is managed as a reset
748+ * The DT "reset-mames" property should be defined with 2 items:
749+ * reset-names = "mcu_rst", "hold_boot";
750+ * - using SMC call (deprecated): use SMC reset interface
751+ * The DT "reset-mames" property is optional, "st,syscfg-tz" is required
752+ * - default(no SCMI, no SMC): the hold boot is managed as a syscon register
753+ * The DT "reset-mames" property is optional, "st,syscfg-holdboot" is required
729754 */
730- err = stm32_rproc_get_syscon (np , "st,syscfg-tz" , & tz );
731- if (err ) {
732- dev_err (dev , "failed to get tz syscfg\n" );
733- return err ;
734- }
735755
736- err = regmap_read (tz .map , tz .reg , & tzen );
737- if (err ) {
738- dev_err (dev , "failed to read tzen\n" );
739- return err ;
756+ ddata -> hold_boot_rst = devm_reset_control_get_optional (dev , "hold_boot" );
757+ if (IS_ERR (ddata -> hold_boot_rst ))
758+ return dev_err_probe (dev , PTR_ERR (ddata -> rst ),
759+ "failed to get hold_boot reset\n" );
760+
761+ if (!ddata -> hold_boot_rst && IS_ENABLED (CONFIG_HAVE_ARM_SMCCC )) {
762+ /* Manage the MCU_BOOT using SMC call */
763+ err = stm32_rproc_get_syscon (np , "st,syscfg-tz" , & tz );
764+ if (!err ) {
765+ err = regmap_read (tz .map , tz .reg , & tzen );
766+ if (err ) {
767+ dev_err (dev , "failed to read tzen\n" );
768+ return err ;
769+ }
770+ ddata -> hold_boot_smc = tzen & tz .mask ;
771+ }
740772 }
741- ddata -> secured_soc = tzen & tz .mask ;
742773
743- err = stm32_rproc_get_syscon (np , "st,syscfg-holdboot" ,
744- & ddata -> hold_boot );
745- if (err ) {
746- dev_err (dev , "failed to get hold boot\n" );
747- return err ;
774+ if (!ddata -> hold_boot_rst && !ddata -> hold_boot_smc ) {
775+ /* Default: hold boot manage it through the syscon controller */
776+ err = stm32_rproc_get_syscon (np , "st,syscfg-holdboot" ,
777+ & ddata -> hold_boot );
778+ if (err ) {
779+ dev_err (dev , "failed to get hold boot\n" );
780+ return err ;
781+ }
748782 }
749783
750784 err = stm32_rproc_get_syscon (np , "st,syscfg-pdds" , & ddata -> pdds );
0 commit comments