@@ -398,6 +398,9 @@ static void ti_sci_put_one_xfer(struct ti_sci_xfers_info *minfo,
398398static inline int ti_sci_do_xfer (struct ti_sci_info * info ,
399399 struct ti_sci_xfer * xfer )
400400{
401+ struct ti_sci_msg_hdr * hdr = (struct ti_sci_msg_hdr * )xfer -> tx_message .buf ;
402+ bool response_expected = !!(hdr -> flags & (TI_SCI_FLAG_REQ_ACK_ON_PROCESSED |
403+ TI_SCI_FLAG_REQ_ACK_ON_RECEIVED ));
401404 int ret ;
402405 int timeout ;
403406 struct device * dev = info -> dev ;
@@ -409,12 +412,12 @@ static inline int ti_sci_do_xfer(struct ti_sci_info *info,
409412
410413 ret = 0 ;
411414
412- if (system_state <= SYSTEM_RUNNING ) {
415+ if (response_expected && system_state <= SYSTEM_RUNNING ) {
413416 /* And we wait for the response. */
414417 timeout = msecs_to_jiffies (info -> desc -> max_rx_timeout_ms );
415418 if (!wait_for_completion_timeout (& xfer -> done , timeout ))
416419 ret = - ETIMEDOUT ;
417- } else {
420+ } else if ( response_expected ) {
418421 /*
419422 * If we are !running, we cannot use wait_for_completion_timeout
420423 * during noirq phase, so we must manually poll the completion.
@@ -1670,6 +1673,9 @@ static int ti_sci_cmd_clk_get_freq(const struct ti_sci_handle *handle,
16701673static int ti_sci_cmd_prepare_sleep (const struct ti_sci_handle * handle , u8 mode ,
16711674 u32 ctx_lo , u32 ctx_hi , u32 debug_flags )
16721675{
1676+ u32 msg_flags = mode == TISCI_MSG_VALUE_SLEEP_MODE_PARTIAL_IO ?
1677+ TI_SCI_FLAG_REQ_GENERIC_NORESPONSE :
1678+ TI_SCI_FLAG_REQ_ACK_ON_PROCESSED ;
16731679 struct ti_sci_info * info ;
16741680 struct ti_sci_msg_req_prepare_sleep * req ;
16751681 struct ti_sci_msg_hdr * resp ;
@@ -1686,7 +1692,7 @@ static int ti_sci_cmd_prepare_sleep(const struct ti_sci_handle *handle, u8 mode,
16861692 dev = info -> dev ;
16871693
16881694 xfer = ti_sci_get_one_xfer (info , TI_SCI_MSG_PREPARE_SLEEP ,
1689- TI_SCI_FLAG_REQ_ACK_ON_PROCESSED ,
1695+ msg_flags ,
16901696 sizeof (* req ), sizeof (* resp ));
16911697 if (IS_ERR (xfer )) {
16921698 ret = PTR_ERR (xfer );
@@ -1706,11 +1712,12 @@ static int ti_sci_cmd_prepare_sleep(const struct ti_sci_handle *handle, u8 mode,
17061712 goto fail ;
17071713 }
17081714
1709- resp = (struct ti_sci_msg_hdr * )xfer -> xfer_buf ;
1710-
1711- if (!ti_sci_is_response_ack (resp )) {
1712- dev_err (dev , "Failed to prepare sleep\n" );
1713- ret = - ENODEV ;
1715+ if (msg_flags == TI_SCI_FLAG_REQ_ACK_ON_PROCESSED ) {
1716+ resp = (struct ti_sci_msg_hdr * )xfer -> xfer_buf ;
1717+ if (!ti_sci_is_response_ack (resp )) {
1718+ dev_err (dev , "Failed to prepare sleep\n" );
1719+ ret = - ENODEV ;
1720+ }
17141721 }
17151722
17161723fail :
@@ -3664,6 +3671,78 @@ devm_ti_sci_get_resource(const struct ti_sci_handle *handle, struct device *dev,
36643671}
36653672EXPORT_SYMBOL_GPL (devm_ti_sci_get_resource );
36663673
3674+ /*
3675+ * Iterate all device nodes that have a wakeup-source property and check if one
3676+ * of the possible phandles points to a Partial-IO system state. If it
3677+ * does resolve the device node to an actual device and check if wakeup is
3678+ * enabled.
3679+ */
3680+ static bool ti_sci_partial_io_wakeup_enabled (struct ti_sci_info * info )
3681+ {
3682+ struct device_node * wakeup_node = NULL ;
3683+
3684+ for_each_node_with_property (wakeup_node , "wakeup-source" ) {
3685+ struct of_phandle_iterator it ;
3686+ int err ;
3687+
3688+ of_for_each_phandle (& it , err , wakeup_node , "wakeup-source" , NULL , 0 ) {
3689+ struct platform_device * pdev ;
3690+ bool may_wakeup ;
3691+
3692+ /*
3693+ * Continue if idle-state-name is not off-wake. Return
3694+ * value is the index of the string which should be 0 if
3695+ * off-wake is present.
3696+ */
3697+ if (of_property_match_string (it .node , "idle-state-name" , "off-wake" ))
3698+ continue ;
3699+
3700+ pdev = of_find_device_by_node (wakeup_node );
3701+ if (!pdev )
3702+ continue ;
3703+
3704+ may_wakeup = device_may_wakeup (& pdev -> dev );
3705+ put_device (& pdev -> dev );
3706+
3707+ if (may_wakeup ) {
3708+ dev_dbg (info -> dev , "%pOF identified as wakeup source for Partial-IO\n" ,
3709+ wakeup_node );
3710+ of_node_put (it .node );
3711+ of_node_put (wakeup_node );
3712+ return true;
3713+ }
3714+ }
3715+ }
3716+
3717+ return false;
3718+ }
3719+
3720+ static int ti_sci_sys_off_handler (struct sys_off_data * data )
3721+ {
3722+ struct ti_sci_info * info = data -> cb_data ;
3723+ const struct ti_sci_handle * handle = & info -> handle ;
3724+ bool enter_partial_io = ti_sci_partial_io_wakeup_enabled (info );
3725+ int ret ;
3726+
3727+ if (!enter_partial_io )
3728+ return NOTIFY_DONE ;
3729+
3730+ dev_info (info -> dev , "Entering Partial-IO because a powered wakeup-enabled device was found.\n" );
3731+
3732+ ret = ti_sci_cmd_prepare_sleep (handle , TISCI_MSG_VALUE_SLEEP_MODE_PARTIAL_IO , 0 , 0 , 0 );
3733+ if (ret ) {
3734+ dev_err (info -> dev ,
3735+ "Failed to enter Partial-IO %pe, trying to do an emergency restart\n" ,
3736+ ERR_PTR (ret ));
3737+ emergency_restart ();
3738+ }
3739+
3740+ mdelay (5000 );
3741+ emergency_restart ();
3742+
3743+ return NOTIFY_DONE ;
3744+ }
3745+
36673746static int tisci_reboot_handler (struct sys_off_data * data )
36683747{
36693748 struct ti_sci_info * info = data -> cb_data ;
@@ -3706,7 +3785,7 @@ static int ti_sci_prepare_system_suspend(struct ti_sci_info *info)
37063785 }
37073786}
37083787
3709- static int __maybe_unused ti_sci_suspend (struct device * dev )
3788+ static int ti_sci_suspend (struct device * dev )
37103789{
37113790 struct ti_sci_info * info = dev_get_drvdata (dev );
37123791 struct device * cpu_dev , * cpu_dev_max = NULL ;
@@ -3746,19 +3825,21 @@ static int __maybe_unused ti_sci_suspend(struct device *dev)
37463825 return 0 ;
37473826}
37483827
3749- static int __maybe_unused ti_sci_suspend_noirq (struct device * dev )
3828+ static int ti_sci_suspend_noirq (struct device * dev )
37503829{
37513830 struct ti_sci_info * info = dev_get_drvdata (dev );
37523831 int ret = 0 ;
37533832
3754- ret = ti_sci_cmd_set_io_isolation (& info -> handle , TISCI_MSG_VALUE_IO_ENABLE );
3755- if (ret )
3756- return ret ;
3833+ if (info -> fw_caps & MSG_FLAG_CAPS_IO_ISOLATION ) {
3834+ ret = ti_sci_cmd_set_io_isolation (& info -> handle , TISCI_MSG_VALUE_IO_ENABLE );
3835+ if (ret )
3836+ return ret ;
3837+ }
37573838
37583839 return 0 ;
37593840}
37603841
3761- static int __maybe_unused ti_sci_resume_noirq (struct device * dev )
3842+ static int ti_sci_resume_noirq (struct device * dev )
37623843{
37633844 struct ti_sci_info * info = dev_get_drvdata (dev );
37643845 int ret = 0 ;
@@ -3767,9 +3848,11 @@ static int __maybe_unused ti_sci_resume_noirq(struct device *dev)
37673848 u8 pin ;
37683849 u8 mode ;
37693850
3770- ret = ti_sci_cmd_set_io_isolation (& info -> handle , TISCI_MSG_VALUE_IO_DISABLE );
3771- if (ret )
3772- return ret ;
3851+ if (info -> fw_caps & MSG_FLAG_CAPS_IO_ISOLATION ) {
3852+ ret = ti_sci_cmd_set_io_isolation (& info -> handle , TISCI_MSG_VALUE_IO_DISABLE );
3853+ if (ret )
3854+ return ret ;
3855+ }
37733856
37743857 ret = ti_sci_msg_cmd_lpm_wake_reason (& info -> handle , & source , & time , & pin , & mode );
37753858 /* Do not fail to resume on error as the wake reason is not critical */
@@ -3780,7 +3863,7 @@ static int __maybe_unused ti_sci_resume_noirq(struct device *dev)
37803863 return 0 ;
37813864}
37823865
3783- static void __maybe_unused ti_sci_pm_complete (struct device * dev )
3866+ static void ti_sci_pm_complete (struct device * dev )
37843867{
37853868 struct ti_sci_info * info = dev_get_drvdata (dev );
37863869
@@ -3791,12 +3874,10 @@ static void __maybe_unused ti_sci_pm_complete(struct device *dev)
37913874}
37923875
37933876static const struct dev_pm_ops ti_sci_pm_ops = {
3794- #ifdef CONFIG_PM_SLEEP
3795- .suspend = ti_sci_suspend ,
3796- .suspend_noirq = ti_sci_suspend_noirq ,
3797- .resume_noirq = ti_sci_resume_noirq ,
3798- .complete = ti_sci_pm_complete ,
3799- #endif
3877+ .suspend = pm_sleep_ptr (ti_sci_suspend ),
3878+ .suspend_noirq = pm_sleep_ptr (ti_sci_suspend_noirq ),
3879+ .resume_noirq = pm_sleep_ptr (ti_sci_resume_noirq ),
3880+ .complete = pm_sleep_ptr (ti_sci_pm_complete ),
38003881};
38013882
38023883/* Description for K2G */
@@ -3928,11 +4009,12 @@ static int ti_sci_probe(struct platform_device *pdev)
39284009 }
39294010
39304011 ti_sci_msg_cmd_query_fw_caps (& info -> handle , & info -> fw_caps );
3931- dev_dbg (dev , "Detected firmware capabilities: %s%s%s%s\n" ,
4012+ dev_dbg (dev , "Detected firmware capabilities: %s%s%s%s%s \n" ,
39324013 info -> fw_caps & MSG_FLAG_CAPS_GENERIC ? "Generic" : "" ,
39334014 info -> fw_caps & MSG_FLAG_CAPS_LPM_PARTIAL_IO ? " Partial-IO" : "" ,
39344015 info -> fw_caps & MSG_FLAG_CAPS_LPM_DM_MANAGED ? " DM-Managed" : "" ,
3935- info -> fw_caps & MSG_FLAG_CAPS_LPM_ABORT ? " LPM-Abort" : ""
4016+ info -> fw_caps & MSG_FLAG_CAPS_LPM_ABORT ? " LPM-Abort" : "" ,
4017+ info -> fw_caps & MSG_FLAG_CAPS_IO_ISOLATION ? " IO-Isolation" : ""
39364018 );
39374019
39384020 ti_sci_setup_ops (info );
@@ -3943,6 +4025,19 @@ static int ti_sci_probe(struct platform_device *pdev)
39434025 goto out ;
39444026 }
39454027
4028+ if (info -> fw_caps & MSG_FLAG_CAPS_LPM_PARTIAL_IO ) {
4029+ ret = devm_register_sys_off_handler (dev ,
4030+ SYS_OFF_MODE_POWER_OFF ,
4031+ SYS_OFF_PRIO_FIRMWARE ,
4032+ ti_sci_sys_off_handler ,
4033+ info );
4034+ if (ret ) {
4035+ dev_err (dev , "Failed to register sys_off_handler %pe\n" ,
4036+ ERR_PTR (ret ));
4037+ goto out ;
4038+ }
4039+ }
4040+
39464041 dev_info (dev , "ABI: %d.%d (firmware rev 0x%04x '%s')\n" ,
39474042 info -> handle .version .abi_major , info -> handle .version .abi_minor ,
39484043 info -> handle .version .firmware_revision ,
@@ -3952,7 +4047,13 @@ static int ti_sci_probe(struct platform_device *pdev)
39524047 list_add_tail (& info -> node , & ti_sci_list );
39534048 mutex_unlock (& ti_sci_list_mutex );
39544049
3955- return of_platform_populate (dev -> of_node , NULL , NULL , dev );
4050+ ret = of_platform_populate (dev -> of_node , NULL , NULL , dev );
4051+ if (ret ) {
4052+ dev_err (dev , "platform_populate failed %pe\n" , ERR_PTR (ret ));
4053+ goto out ;
4054+ }
4055+ return 0 ;
4056+
39564057out :
39574058 if (!IS_ERR (info -> chan_tx ))
39584059 mbox_free_channel (info -> chan_tx );
0 commit comments