11// SPDX-License-Identifier: GPL-2.0
22/*
33 * ti-sysc.c - Texas Instruments sysc interconnect target driver
4+ *
5+ * TI SoCs have an interconnect target wrapper IP for many devices. The wrapper
6+ * IP manages clock gating, resets, and PM capabilities for the connected devices.
7+ *
8+ * Copyright (C) 2017-2024 Texas Instruments Incorporated - https://www.ti.com/
9+ *
10+ * Many features are based on the earlier omap_hwmod arch code with thanks to all
11+ * the people who developed and debugged the code over the years:
12+ *
13+ * Copyright (C) 2009-2011 Nokia Corporation
14+ * Copyright (C) 2011-2021 Texas Instruments Incorporated - https://www.ti.com/
415 */
516
617#include <linux/io.h>
@@ -1458,8 +1469,7 @@ static int __maybe_unused sysc_noirq_suspend(struct device *dev)
14581469
14591470 ddata = dev_get_drvdata (dev );
14601471
1461- if (ddata -> cfg .quirks &
1462- (SYSC_QUIRK_LEGACY_IDLE | SYSC_QUIRK_NO_IDLE ))
1472+ if (ddata -> cfg .quirks & SYSC_QUIRK_NO_IDLE )
14631473 return 0 ;
14641474
14651475 if (!ddata -> enabled )
@@ -1477,8 +1487,7 @@ static int __maybe_unused sysc_noirq_resume(struct device *dev)
14771487
14781488 ddata = dev_get_drvdata (dev );
14791489
1480- if (ddata -> cfg .quirks &
1481- (SYSC_QUIRK_LEGACY_IDLE | SYSC_QUIRK_NO_IDLE ))
1490+ if (ddata -> cfg .quirks & SYSC_QUIRK_NO_IDLE )
14821491 return 0 ;
14831492
14841493 if (ddata -> cfg .quirks & SYSC_QUIRK_REINIT_ON_RESUME ) {
@@ -1529,19 +1538,6 @@ struct sysc_revision_quirk {
15291538 }
15301539
15311540static const struct sysc_revision_quirk sysc_revision_quirks [] = {
1532- /* These drivers need to be fixed to not use pm_runtime_irq_safe() */
1533- SYSC_QUIRK ("uart" , 0 , 0x50 , 0x54 , 0x58 , 0x00000046 , 0xffffffff ,
1534- SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE ),
1535- SYSC_QUIRK ("uart" , 0 , 0x50 , 0x54 , 0x58 , 0x00000052 , 0xffffffff ,
1536- SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE ),
1537- /* Uarts on omap4 and later */
1538- SYSC_QUIRK ("uart" , 0 , 0x50 , 0x54 , 0x58 , 0x50411e03 , 0xffff00ff ,
1539- SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE ),
1540- SYSC_QUIRK ("uart" , 0 , 0x50 , 0x54 , 0x58 , 0x47422e03 , 0xffffffff ,
1541- SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE ),
1542- SYSC_QUIRK ("uart" , 0 , 0x50 , 0x54 , 0x58 , 0x47424e03 , 0xffffffff ,
1543- SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE ),
1544-
15451541 /* Quirks that need to be set based on the module address */
15461542 SYSC_QUIRK ("mcpdm" , 0x40132000 , 0 , 0x10 , - ENODEV , 0x50000800 , 0xffffffff ,
15471543 SYSC_QUIRK_EXT_OPT_CLOCK | SYSC_QUIRK_NO_RESET_ON_INIT |
@@ -1599,6 +1595,17 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = {
15991595 SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_SWSUP_MSTANDBY ),
16001596 SYSC_QUIRK ("sata" , 0 , 0xfc , 0x1100 , - ENODEV , 0x5e412000 , 0xffffffff ,
16011597 SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_SWSUP_MSTANDBY ),
1598+ SYSC_QUIRK ("uart" , 0 , 0x50 , 0x54 , 0x58 , 0x00000046 , 0xffffffff ,
1599+ SYSC_QUIRK_SWSUP_SIDLE_ACT ),
1600+ SYSC_QUIRK ("uart" , 0 , 0x50 , 0x54 , 0x58 , 0x00000052 , 0xffffffff ,
1601+ SYSC_QUIRK_SWSUP_SIDLE_ACT ),
1602+ /* Uarts on omap4 and later */
1603+ SYSC_QUIRK ("uart" , 0 , 0x50 , 0x54 , 0x58 , 0x50411e03 , 0xffff00ff ,
1604+ SYSC_QUIRK_SWSUP_SIDLE_ACT ),
1605+ SYSC_QUIRK ("uart" , 0 , 0x50 , 0x54 , 0x58 , 0x47422e03 , 0xffffffff ,
1606+ SYSC_QUIRK_SWSUP_SIDLE_ACT ),
1607+ SYSC_QUIRK ("uart" , 0 , 0x50 , 0x54 , 0x58 , 0x47424e03 , 0xffffffff ,
1608+ SYSC_QUIRK_SWSUP_SIDLE_ACT ),
16021609 SYSC_QUIRK ("usb_host_hs" , 0 , 0 , 0x10 , 0x14 , 0x50700100 , 0xffffffff ,
16031610 SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_SWSUP_MSTANDBY ),
16041611 SYSC_QUIRK ("usb_host_hs" , 0 , 0 , 0x10 , - ENODEV , 0x50700101 , 0xffffffff ,
@@ -2145,8 +2152,7 @@ static int sysc_reset(struct sysc *ddata)
21452152 sysc_offset = ddata -> offsets [SYSC_SYSCONFIG ];
21462153
21472154 if (ddata -> legacy_mode ||
2148- ddata -> cap -> regbits -> srst_shift < 0 ||
2149- ddata -> cfg .quirks & SYSC_QUIRK_NO_RESET_ON_INIT )
2155+ ddata -> cap -> regbits -> srst_shift < 0 )
21502156 return 0 ;
21512157
21522158 sysc_mask = BIT (ddata -> cap -> regbits -> srst_shift );
@@ -2240,12 +2246,14 @@ static int sysc_init_module(struct sysc *ddata)
22402246 goto err_main_clocks ;
22412247 }
22422248
2243- error = sysc_reset (ddata );
2244- if (error )
2245- dev_err (ddata -> dev , "Reset failed with %d\n" , error );
2249+ if (!(ddata -> cfg .quirks & SYSC_QUIRK_NO_RESET_ON_INIT )) {
2250+ error = sysc_reset (ddata );
2251+ if (error )
2252+ dev_err (ddata -> dev , "Reset failed with %d\n" , error );
22462253
2247- if (error && !ddata -> legacy_mode )
2248- sysc_disable_module (ddata -> dev );
2254+ if (error && !ddata -> legacy_mode )
2255+ sysc_disable_module (ddata -> dev );
2256+ }
22492257
22502258err_main_clocks :
22512259 if (error )
@@ -2447,89 +2455,6 @@ static int __maybe_unused sysc_child_runtime_resume(struct device *dev)
24472455 return pm_generic_runtime_resume (dev );
24482456}
24492457
2450- #ifdef CONFIG_PM_SLEEP
2451- static int sysc_child_suspend_noirq (struct device * dev )
2452- {
2453- struct sysc * ddata ;
2454- int error ;
2455-
2456- ddata = sysc_child_to_parent (dev );
2457-
2458- dev_dbg (ddata -> dev , "%s %s\n" , __func__ ,
2459- ddata -> name ? ddata -> name : "" );
2460-
2461- error = pm_generic_suspend_noirq (dev );
2462- if (error ) {
2463- dev_err (dev , "%s error at %i: %i\n" ,
2464- __func__ , __LINE__ , error );
2465-
2466- return error ;
2467- }
2468-
2469- if (!pm_runtime_status_suspended (dev )) {
2470- error = pm_generic_runtime_suspend (dev );
2471- if (error ) {
2472- dev_dbg (dev , "%s busy at %i: %i\n" ,
2473- __func__ , __LINE__ , error );
2474-
2475- return 0 ;
2476- }
2477-
2478- error = sysc_runtime_suspend (ddata -> dev );
2479- if (error ) {
2480- dev_err (dev , "%s error at %i: %i\n" ,
2481- __func__ , __LINE__ , error );
2482-
2483- return error ;
2484- }
2485-
2486- ddata -> child_needs_resume = true;
2487- }
2488-
2489- return 0 ;
2490- }
2491-
2492- static int sysc_child_resume_noirq (struct device * dev )
2493- {
2494- struct sysc * ddata ;
2495- int error ;
2496-
2497- ddata = sysc_child_to_parent (dev );
2498-
2499- dev_dbg (ddata -> dev , "%s %s\n" , __func__ ,
2500- ddata -> name ? ddata -> name : "" );
2501-
2502- if (ddata -> child_needs_resume ) {
2503- ddata -> child_needs_resume = false;
2504-
2505- error = sysc_runtime_resume (ddata -> dev );
2506- if (error )
2507- dev_err (ddata -> dev ,
2508- "%s runtime resume error: %i\n" ,
2509- __func__ , error );
2510-
2511- error = pm_generic_runtime_resume (dev );
2512- if (error )
2513- dev_err (ddata -> dev ,
2514- "%s generic runtime resume: %i\n" ,
2515- __func__ , error );
2516- }
2517-
2518- return pm_generic_resume_noirq (dev );
2519- }
2520- #endif
2521-
2522- static struct dev_pm_domain sysc_child_pm_domain = {
2523- .ops = {
2524- SET_RUNTIME_PM_OPS (sysc_child_runtime_suspend ,
2525- sysc_child_runtime_resume ,
2526- NULL )
2527- USE_PLATFORM_PM_SLEEP_OPS
2528- SET_NOIRQ_SYSTEM_SLEEP_PM_OPS (sysc_child_suspend_noirq ,
2529- sysc_child_resume_noirq )
2530- }
2531- };
2532-
25332458/* Caller needs to take list_lock if ever used outside of cpu_pm */
25342459static void sysc_reinit_modules (struct sysc_soc_info * soc )
25352460{
@@ -2600,25 +2525,6 @@ static void sysc_add_restored(struct sysc *ddata)
26002525 mutex_unlock (& sysc_soc -> list_lock );
26012526}
26022527
2603- /**
2604- * sysc_legacy_idle_quirk - handle children in omap_device compatible way
2605- * @ddata: device driver data
2606- * @child: child device driver
2607- *
2608- * Allow idle for child devices as done with _od_runtime_suspend().
2609- * Otherwise many child devices will not idle because of the permanent
2610- * parent usecount set in pm_runtime_irq_safe().
2611- *
2612- * Note that the long term solution is to just modify the child device
2613- * drivers to not set pm_runtime_irq_safe() and then this can be just
2614- * dropped.
2615- */
2616- static void sysc_legacy_idle_quirk (struct sysc * ddata , struct device * child )
2617- {
2618- if (ddata -> cfg .quirks & SYSC_QUIRK_LEGACY_IDLE )
2619- dev_pm_domain_set (child , & sysc_child_pm_domain );
2620- }
2621-
26222528static int sysc_notifier_call (struct notifier_block * nb ,
26232529 unsigned long event , void * device )
26242530{
@@ -2635,7 +2541,6 @@ static int sysc_notifier_call(struct notifier_block *nb,
26352541 error = sysc_child_add_clocks (ddata , dev );
26362542 if (error )
26372543 return error ;
2638- sysc_legacy_idle_quirk (ddata , dev );
26392544 break ;
26402545 default :
26412546 break ;
@@ -2859,8 +2764,7 @@ static const struct sysc_capabilities sysc_34xx_sr = {
28592764 .type = TI_SYSC_OMAP34XX_SR ,
28602765 .sysc_mask = SYSC_OMAP2_CLOCKACTIVITY ,
28612766 .regbits = & sysc_regbits_omap34xx_sr ,
2862- .mod_quirks = SYSC_QUIRK_USE_CLOCKACT | SYSC_QUIRK_UNCACHED |
2863- SYSC_QUIRK_LEGACY_IDLE ,
2767+ .mod_quirks = SYSC_QUIRK_USE_CLOCKACT | SYSC_QUIRK_UNCACHED ,
28642768};
28652769
28662770/*
@@ -2881,13 +2785,12 @@ static const struct sysc_capabilities sysc_36xx_sr = {
28812785 .type = TI_SYSC_OMAP36XX_SR ,
28822786 .sysc_mask = SYSC_OMAP3_SR_ENAWAKEUP ,
28832787 .regbits = & sysc_regbits_omap36xx_sr ,
2884- .mod_quirks = SYSC_QUIRK_UNCACHED | SYSC_QUIRK_LEGACY_IDLE ,
2788+ .mod_quirks = SYSC_QUIRK_UNCACHED ,
28852789};
28862790
28872791static const struct sysc_capabilities sysc_omap4_sr = {
28882792 .type = TI_SYSC_OMAP4_SR ,
28892793 .regbits = & sysc_regbits_omap36xx_sr ,
2890- .mod_quirks = SYSC_QUIRK_LEGACY_IDLE ,
28912794};
28922795
28932796/*
0 commit comments