Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'omap-for-v5.16/ti-sysc-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap into arm/drivers

Driver changes for ti-sysc for v5.16

Changes for ti-sysc driver for improved system suspend and resume
support as some drivers need to be reinitialized on resume. Also
a non-urgent resume warning fix, and dropping of legacy flags for
gpio and sham:

- Fix timekeeping suspended warning on resume. Probably no need to merge
this into fixes as it's gone unnoticed for a while.

- Check for context loss for reinit of a module

- Add add quirk handling to reinit on context loss, and also fix a
build warning it caused

- Add quirk handling to reset on reinit

- Use context loss quirk for gpmc and otg

- Handle otg force-idle quirk even if no driver is loaded

- Drop legacy flags for gpio and sham

* tag 'omap-for-v5.16/ti-sysc-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap:
bus: ti-sysc: Fix variable set but not used warning for reinit_modules
bus: ti-sysc: Drop legacy quirk flag for sham
bus: ti-sysc: Drop legacy quirk flag for gpio
bus: ti-sysc: Handle otg force idle quirk
bus: ti-sysc: Use context lost quirk for otg
bus: ti-sysc: Use context lost quirks for gpmc
bus: ti-sysc: Add quirk handling for reset on re-init
bus: ti-sysc: Add quirk handling for reinit on context lost
bus: ti-sysc: Check for lost context in sysc_reinit_module()
bus: ti-sysc: Fix timekeeping_suspended warning on resume

Link: https://lore.kernel.org/r/pull-1633950030-501948@atomide.com-2
Signed-off-by: Arnd Bergmann <arnd@arndb.de>

+244 -35
+241 -35
drivers/bus/ti-sysc.c
··· 6 6 #include <linux/io.h> 7 7 #include <linux/clk.h> 8 8 #include <linux/clkdev.h> 9 + #include <linux/cpu_pm.h> 9 10 #include <linux/delay.h> 10 11 #include <linux/list.h> 11 12 #include <linux/module.h> ··· 18 17 #include <linux/of_platform.h> 19 18 #include <linux/slab.h> 20 19 #include <linux/sys_soc.h> 20 + #include <linux/timekeeping.h> 21 21 #include <linux/iopoll.h> 22 22 23 23 #include <linux/platform_data/ti-sysc.h> ··· 53 51 struct list_head node; 54 52 }; 55 53 54 + struct sysc_module { 55 + struct sysc *ddata; 56 + struct list_head node; 57 + }; 58 + 56 59 struct sysc_soc_info { 57 60 unsigned long general_purpose:1; 58 61 enum sysc_soc soc; 59 - struct mutex list_lock; /* disabled modules list lock */ 62 + struct mutex list_lock; /* disabled and restored modules list lock */ 60 63 struct list_head disabled_modules; 64 + struct list_head restored_modules; 65 + struct notifier_block nb; 61 66 }; 62 67 63 68 enum sysc_clocks { ··· 140 131 struct ti_sysc_cookie cookie; 141 132 const char *name; 142 133 u32 revision; 134 + u32 sysconfig; 143 135 unsigned int reserved:1; 144 136 unsigned int enabled:1; 145 137 unsigned int needs_resume:1; ··· 157 147 158 148 static void sysc_parse_dts_quirks(struct sysc *ddata, struct device_node *np, 159 149 bool is_child); 150 + static int sysc_reset(struct sysc *ddata); 160 151 161 152 static void sysc_write(struct sysc *ddata, int offset, u32 value) 162 153 { ··· 234 223 return sysc_read(ddata, offset); 235 224 } 236 225 237 - /* Poll on reset status */ 238 - static int sysc_wait_softreset(struct sysc *ddata) 226 + static int sysc_poll_reset_sysstatus(struct sysc *ddata) 239 227 { 240 - u32 sysc_mask, syss_done, rstval; 241 - int syss_offset, error = 0; 242 - 243 - if (ddata->cap->regbits->srst_shift < 0) 244 - return 0; 245 - 246 - syss_offset = ddata->offsets[SYSC_SYSSTATUS]; 247 - sysc_mask = BIT(ddata->cap->regbits->srst_shift); 228 + int error, retries; 229 + u32 syss_done, rstval; 248 230 249 231 if (ddata->cfg.quirks & SYSS_QUIRK_RESETDONE_INVERTED) 250 232 syss_done = 0; 251 233 else 252 234 syss_done = ddata->cfg.syss_mask; 253 235 254 - if (syss_offset >= 0) { 236 + if (likely(!timekeeping_suspended)) { 255 237 error = readx_poll_timeout_atomic(sysc_read_sysstatus, ddata, 256 238 rstval, (rstval & ddata->cfg.syss_mask) == 257 239 syss_done, 100, MAX_MODULE_SOFTRESET_WAIT); 240 + } else { 241 + retries = MAX_MODULE_SOFTRESET_WAIT; 242 + while (retries--) { 243 + rstval = sysc_read_sysstatus(ddata); 244 + if ((rstval & ddata->cfg.syss_mask) == syss_done) 245 + return 0; 246 + udelay(2); /* Account for udelay flakeyness */ 247 + } 248 + error = -ETIMEDOUT; 249 + } 258 250 259 - } else if (ddata->cfg.quirks & SYSC_QUIRK_RESET_STATUS) { 251 + return error; 252 + } 253 + 254 + static int sysc_poll_reset_sysconfig(struct sysc *ddata) 255 + { 256 + int error, retries; 257 + u32 sysc_mask, rstval; 258 + 259 + sysc_mask = BIT(ddata->cap->regbits->srst_shift); 260 + 261 + if (likely(!timekeeping_suspended)) { 260 262 error = readx_poll_timeout_atomic(sysc_read_sysconfig, ddata, 261 263 rstval, !(rstval & sysc_mask), 262 264 100, MAX_MODULE_SOFTRESET_WAIT); 265 + } else { 266 + retries = MAX_MODULE_SOFTRESET_WAIT; 267 + while (retries--) { 268 + rstval = sysc_read_sysconfig(ddata); 269 + if (!(rstval & sysc_mask)) 270 + return 0; 271 + udelay(2); /* Account for udelay flakeyness */ 272 + } 273 + error = -ETIMEDOUT; 263 274 } 275 + 276 + return error; 277 + } 278 + 279 + /* Poll on reset status */ 280 + static int sysc_wait_softreset(struct sysc *ddata) 281 + { 282 + int syss_offset, error = 0; 283 + 284 + if (ddata->cap->regbits->srst_shift < 0) 285 + return 0; 286 + 287 + syss_offset = ddata->offsets[SYSC_SYSSTATUS]; 288 + 289 + if (syss_offset >= 0) 290 + error = sysc_poll_reset_sysstatus(ddata); 291 + else if (ddata->cfg.quirks & SYSC_QUIRK_RESET_STATUS) 292 + error = sysc_poll_reset_sysconfig(ddata); 264 293 265 294 return error; 266 295 } ··· 1145 1094 best_mode = fls(ddata->cfg.midlemodes) - 1; 1146 1095 if (best_mode > SYSC_IDLE_MASK) { 1147 1096 dev_err(dev, "%s: invalid midlemode\n", __func__); 1148 - return -EINVAL; 1097 + error = -EINVAL; 1098 + goto save_context; 1149 1099 } 1150 1100 1151 1101 if (ddata->cfg.quirks & SYSC_QUIRK_SWSUP_MSTANDBY) ··· 1164 1112 sysc_write_sysconfig(ddata, reg); 1165 1113 } 1166 1114 1167 - /* Flush posted write */ 1168 - sysc_read(ddata, ddata->offsets[SYSC_SYSCONFIG]); 1115 + error = 0; 1116 + 1117 + save_context: 1118 + /* Save context and flush posted write */ 1119 + ddata->sysconfig = sysc_read(ddata, ddata->offsets[SYSC_SYSCONFIG]); 1169 1120 1170 1121 if (ddata->module_enable_quirk) 1171 1122 ddata->module_enable_quirk(ddata); 1172 1123 1173 - return 0; 1124 + return error; 1174 1125 } 1175 1126 1176 1127 static int sysc_best_idle_mode(u32 idlemodes, u32 *best_mode) ··· 1230 1175 set_sidle: 1231 1176 /* Set SIDLE mode */ 1232 1177 idlemodes = ddata->cfg.sidlemodes; 1233 - if (!idlemodes || regbits->sidle_shift < 0) 1234 - return 0; 1178 + if (!idlemodes || regbits->sidle_shift < 0) { 1179 + ret = 0; 1180 + goto save_context; 1181 + } 1235 1182 1236 1183 if (ddata->cfg.quirks & SYSC_QUIRK_SWSUP_SIDLE) { 1237 1184 best_mode = SYSC_IDLE_FORCE; ··· 1241 1184 ret = sysc_best_idle_mode(idlemodes, &best_mode); 1242 1185 if (ret) { 1243 1186 dev_err(dev, "%s: invalid sidlemode\n", __func__); 1244 - return ret; 1187 + ret = -EINVAL; 1188 + goto save_context; 1245 1189 } 1246 1190 } 1247 1191 ··· 1253 1195 reg |= 1 << regbits->autoidle_shift; 1254 1196 sysc_write_sysconfig(ddata, reg); 1255 1197 1256 - /* Flush posted write */ 1257 - sysc_read(ddata, ddata->offsets[SYSC_SYSCONFIG]); 1198 + ret = 0; 1258 1199 1259 - return 0; 1200 + save_context: 1201 + /* Save context and flush posted write */ 1202 + ddata->sysconfig = sysc_read(ddata, ddata->offsets[SYSC_SYSCONFIG]); 1203 + 1204 + return ret; 1260 1205 } 1261 1206 1262 1207 static int __maybe_unused sysc_runtime_suspend_legacy(struct device *dev, ··· 1397 1336 return error; 1398 1337 } 1399 1338 1339 + /* 1340 + * Checks if device context was lost. Assumes the sysconfig register value 1341 + * after lost context is different from the configured value. Only works for 1342 + * enabled devices. 1343 + * 1344 + * Eventually we may want to also add support to using the context lost 1345 + * registers that some SoCs have. 1346 + */ 1347 + static int sysc_check_context(struct sysc *ddata) 1348 + { 1349 + u32 reg; 1350 + 1351 + if (!ddata->enabled) 1352 + return -ENODATA; 1353 + 1354 + reg = sysc_read(ddata, ddata->offsets[SYSC_SYSCONFIG]); 1355 + if (reg == ddata->sysconfig) 1356 + return 0; 1357 + 1358 + return -EACCES; 1359 + } 1360 + 1400 1361 static int sysc_reinit_module(struct sysc *ddata, bool leave_enabled) 1401 1362 { 1402 1363 struct device *dev = ddata->dev; 1403 1364 int error; 1404 1365 1405 - /* Disable target module if it is enabled */ 1406 1366 if (ddata->enabled) { 1367 + /* Nothing to do if enabled and context not lost */ 1368 + error = sysc_check_context(ddata); 1369 + if (!error) 1370 + return 0; 1371 + 1372 + /* Disable target module if it is enabled */ 1407 1373 error = sysc_runtime_suspend(dev); 1408 1374 if (error) 1409 1375 dev_warn(dev, "reinit suspend failed: %i\n", error); ··· 1440 1352 error = sysc_runtime_resume(dev); 1441 1353 if (error) 1442 1354 dev_warn(dev, "reinit resume failed: %i\n", error); 1355 + 1356 + /* Some modules like am335x gpmc need reset and restore of sysconfig */ 1357 + if (ddata->cfg.quirks & SYSC_QUIRK_RESET_ON_CTX_LOST) { 1358 + error = sysc_reset(ddata); 1359 + if (error) 1360 + dev_warn(dev, "reinit reset failed: %i\n", error); 1361 + 1362 + sysc_write_sysconfig(ddata, ddata->sysconfig); 1363 + } 1443 1364 1444 1365 if (leave_enabled) 1445 1366 return error; ··· 1539 1442 1540 1443 static const struct sysc_revision_quirk sysc_revision_quirks[] = { 1541 1444 /* These drivers need to be fixed to not use pm_runtime_irq_safe() */ 1542 - SYSC_QUIRK("gpio", 0, 0, 0x10, 0x114, 0x50600801, 0xffff00ff, 1543 - SYSC_QUIRK_LEGACY_IDLE | SYSC_QUIRK_OPT_CLKS_IN_RESET), 1544 - SYSC_QUIRK("sham", 0, 0x100, 0x110, 0x114, 0x40000c03, 0xffffffff, 1545 - SYSC_QUIRK_LEGACY_IDLE), 1546 1445 SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x00000046, 0xffffffff, 1547 1446 SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE), 1548 1447 SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x00000052, 0xffffffff, ··· 1569 1476 SYSC_QUIRK_CLKDM_NOAUTO), 1570 1477 SYSC_QUIRK("dwc3", 0x488c0000, 0, 0x10, -ENODEV, 0x500a0200, 0xffffffff, 1571 1478 SYSC_QUIRK_CLKDM_NOAUTO), 1479 + SYSC_QUIRK("gpio", 0, 0, 0x10, 0x114, 0x50600801, 0xffff00ff, 1480 + SYSC_QUIRK_OPT_CLKS_IN_RESET), 1572 1481 SYSC_QUIRK("gpmc", 0, 0, 0x10, 0x14, 0x00000060, 0xffffffff, 1482 + SYSC_QUIRK_REINIT_ON_CTX_LOST | SYSC_QUIRK_RESET_ON_CTX_LOST | 1573 1483 SYSC_QUIRK_GPMC_DEBUG), 1574 1484 SYSC_QUIRK("hdmi", 0, 0, 0x10, -ENODEV, 0x50030200, 0xffffffff, 1575 1485 SYSC_QUIRK_OPT_CLKS_NEEDED), ··· 1608 1512 SYSC_QUIRK("usb_host_hs", 0, 0, 0x10, -ENODEV, 0x50700101, 0xffffffff, 1609 1513 SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_SWSUP_MSTANDBY), 1610 1514 SYSC_QUIRK("usb_otg_hs", 0, 0x400, 0x404, 0x408, 0x00000050, 1611 - 0xffffffff, SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_SWSUP_MSTANDBY), 1515 + 0xffffffff, SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_SWSUP_MSTANDBY | 1516 + SYSC_MODULE_QUIRK_OTG), 1612 1517 SYSC_QUIRK("usb_otg_hs", 0, 0, 0x10, -ENODEV, 0x4ea2080d, 0xffffffff, 1613 1518 SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_SWSUP_MSTANDBY | 1614 - SYSC_QUIRK_REINIT_ON_RESUME), 1519 + SYSC_QUIRK_REINIT_ON_CTX_LOST), 1615 1520 SYSC_QUIRK("wdt", 0, 0, 0x10, 0x14, 0x502a0500, 0xfffff0f0, 1616 1521 SYSC_MODULE_QUIRK_WDT), 1617 1522 /* PRUSS on am3, am4 and am5 */ ··· 1677 1580 SYSC_QUIRK("sdio", 0, 0, 0x10, -ENODEV, 0x40202301, 0xffff0ff0, 0), 1678 1581 SYSC_QUIRK("sdio", 0, 0x2fc, 0x110, 0x114, 0x31010000, 0xffffffff, 0), 1679 1582 SYSC_QUIRK("sdma", 0, 0, 0x2c, 0x28, 0x00010900, 0xffffffff, 0), 1583 + SYSC_QUIRK("sham", 0, 0x100, 0x110, 0x114, 0x40000c03, 0xffffffff, 0), 1680 1584 SYSC_QUIRK("slimbus", 0, 0, 0x10, -ENODEV, 0x40000902, 0xffffffff, 0), 1681 1585 SYSC_QUIRK("slimbus", 0, 0, 0x10, -ENODEV, 0x40002903, 0xffffffff, 0), 1682 1586 SYSC_QUIRK("smartreflex", 0, -ENODEV, 0x24, -ENODEV, 0x00000000, 0xffffffff, 0), ··· 1969 1871 sysc_quirk_rtc(ddata, true); 1970 1872 } 1971 1873 1874 + /* OTG omap2430 glue layer up to omap4 needs OTG_FORCESTDBY configured */ 1875 + static void sysc_module_enable_quirk_otg(struct sysc *ddata) 1876 + { 1877 + int offset = 0x414; /* OTG_FORCESTDBY */ 1878 + 1879 + sysc_write(ddata, offset, 0); 1880 + } 1881 + 1882 + static void sysc_module_disable_quirk_otg(struct sysc *ddata) 1883 + { 1884 + int offset = 0x414; /* OTG_FORCESTDBY */ 1885 + u32 val = BIT(0); /* ENABLEFORCE */ 1886 + 1887 + sysc_write(ddata, offset, val); 1888 + } 1889 + 1972 1890 /* 36xx SGX needs a quirk for to bypass OCP IPG interrupt logic */ 1973 1891 static void sysc_module_enable_quirk_sgx(struct sysc *ddata) 1974 1892 { ··· 2065 1951 ddata->module_lock_quirk = sysc_module_lock_quirk_rtc; 2066 1952 2067 1953 return; 1954 + } 1955 + 1956 + if (ddata->cfg.quirks & SYSC_MODULE_QUIRK_OTG) { 1957 + ddata->module_enable_quirk = sysc_module_enable_quirk_otg; 1958 + ddata->module_disable_quirk = sysc_module_disable_quirk_otg; 2068 1959 } 2069 1960 2070 1961 if (ddata->cfg.quirks & SYSC_MODULE_QUIRK_SGX) ··· 2516 2397 sysc_child_resume_noirq) 2517 2398 } 2518 2399 }; 2400 + 2401 + /* Caller needs to take list_lock if ever used outside of cpu_pm */ 2402 + static void sysc_reinit_modules(struct sysc_soc_info *soc) 2403 + { 2404 + struct sysc_module *module; 2405 + struct list_head *pos; 2406 + struct sysc *ddata; 2407 + 2408 + list_for_each(pos, &sysc_soc->restored_modules) { 2409 + module = list_entry(pos, struct sysc_module, node); 2410 + ddata = module->ddata; 2411 + sysc_reinit_module(ddata, ddata->enabled); 2412 + } 2413 + } 2414 + 2415 + /** 2416 + * sysc_context_notifier - optionally reset and restore module after idle 2417 + * @nb: notifier block 2418 + * @cmd: unused 2419 + * @v: unused 2420 + * 2421 + * Some interconnect target modules need to be restored, or reset and restored 2422 + * on CPU_PM CPU_PM_CLUSTER_EXIT notifier. This is needed at least for am335x 2423 + * OTG and GPMC target modules even if the modules are unused. 2424 + */ 2425 + static int sysc_context_notifier(struct notifier_block *nb, unsigned long cmd, 2426 + void *v) 2427 + { 2428 + struct sysc_soc_info *soc; 2429 + 2430 + soc = container_of(nb, struct sysc_soc_info, nb); 2431 + 2432 + switch (cmd) { 2433 + case CPU_CLUSTER_PM_ENTER: 2434 + break; 2435 + case CPU_CLUSTER_PM_ENTER_FAILED: /* No need to restore context */ 2436 + break; 2437 + case CPU_CLUSTER_PM_EXIT: 2438 + sysc_reinit_modules(soc); 2439 + break; 2440 + } 2441 + 2442 + return NOTIFY_OK; 2443 + } 2444 + 2445 + /** 2446 + * sysc_add_restored - optionally add reset and restore quirk hanlling 2447 + * @ddata: device data 2448 + */ 2449 + static void sysc_add_restored(struct sysc *ddata) 2450 + { 2451 + struct sysc_module *restored_module; 2452 + 2453 + restored_module = kzalloc(sizeof(*restored_module), GFP_KERNEL); 2454 + if (!restored_module) 2455 + return; 2456 + 2457 + restored_module->ddata = ddata; 2458 + 2459 + mutex_lock(&sysc_soc->list_lock); 2460 + 2461 + list_add(&restored_module->node, &sysc_soc->restored_modules); 2462 + 2463 + if (sysc_soc->nb.notifier_call) 2464 + goto out_unlock; 2465 + 2466 + sysc_soc->nb.notifier_call = sysc_context_notifier; 2467 + cpu_pm_register_notifier(&sysc_soc->nb); 2468 + 2469 + out_unlock: 2470 + mutex_unlock(&sysc_soc->list_lock); 2471 + } 2519 2472 2520 2473 /** 2521 2474 * sysc_legacy_idle_quirk - handle children in omap_device compatible way ··· 3088 2897 } 3089 2898 3090 2899 /* 3091 - * One time init to detect the booted SoC and disable unavailable features. 2900 + * One time init to detect the booted SoC, disable unavailable features 2901 + * and initialize list for optional cpu_pm notifier. 2902 + * 3092 2903 * Note that we initialize static data shared across all ti-sysc instances 3093 2904 * so ddata is only used for SoC type. This can be called from module_init 3094 2905 * once we no longer need to rely on platform data. 3095 2906 */ 3096 - static int sysc_init_soc(struct sysc *ddata) 2907 + static int sysc_init_static_data(struct sysc *ddata) 3097 2908 { 3098 2909 const struct soc_device_attribute *match; 3099 2910 struct ti_sysc_platform_data *pdata; ··· 3111 2918 3112 2919 mutex_init(&sysc_soc->list_lock); 3113 2920 INIT_LIST_HEAD(&sysc_soc->disabled_modules); 2921 + INIT_LIST_HEAD(&sysc_soc->restored_modules); 3114 2922 sysc_soc->general_purpose = true; 3115 2923 3116 2924 pdata = dev_get_platdata(ddata->dev); ··· 3175 2981 return 0; 3176 2982 } 3177 2983 3178 - static void sysc_cleanup_soc(void) 2984 + static void sysc_cleanup_static_data(void) 3179 2985 { 2986 + struct sysc_module *restored_module; 3180 2987 struct sysc_address *disabled_module; 3181 2988 struct list_head *pos, *tmp; 3182 2989 3183 2990 if (!sysc_soc) 3184 2991 return; 3185 2992 2993 + if (sysc_soc->nb.notifier_call) 2994 + cpu_pm_unregister_notifier(&sysc_soc->nb); 2995 + 3186 2996 mutex_lock(&sysc_soc->list_lock); 2997 + list_for_each_safe(pos, tmp, &sysc_soc->restored_modules) { 2998 + restored_module = list_entry(pos, struct sysc_module, node); 2999 + list_del(pos); 3000 + kfree(restored_module); 3001 + } 3187 3002 list_for_each_safe(pos, tmp, &sysc_soc->disabled_modules) { 3188 3003 disabled_module = list_entry(pos, struct sysc_address, node); 3189 3004 list_del(pos); ··· 3260 3057 ddata->dev = &pdev->dev; 3261 3058 platform_set_drvdata(pdev, ddata); 3262 3059 3263 - error = sysc_init_soc(ddata); 3060 + error = sysc_init_static_data(ddata); 3264 3061 if (error) 3265 3062 return error; 3266 3063 ··· 3358 3155 pm_runtime_put(&pdev->dev); 3359 3156 } 3360 3157 3158 + if (ddata->cfg.quirks & SYSC_QUIRK_REINIT_ON_CTX_LOST) 3159 + sysc_add_restored(ddata); 3160 + 3361 3161 return 0; 3362 3162 3363 3163 err: ··· 3442 3236 { 3443 3237 bus_unregister_notifier(&platform_bus_type, &sysc_nb); 3444 3238 platform_driver_unregister(&sysc_driver); 3445 - sysc_cleanup_soc(); 3239 + sysc_cleanup_static_data(); 3446 3240 } 3447 3241 module_exit(sysc_exit); 3448 3242
+3
include/linux/platform_data/ti-sysc.h
··· 50 50 s8 emufree_shift; 51 51 }; 52 52 53 + #define SYSC_MODULE_QUIRK_OTG BIT(30) 54 + #define SYSC_QUIRK_RESET_ON_CTX_LOST BIT(29) 55 + #define SYSC_QUIRK_REINIT_ON_CTX_LOST BIT(28) 53 56 #define SYSC_QUIRK_REINIT_ON_RESUME BIT(27) 54 57 #define SYSC_QUIRK_GPMC_DEBUG BIT(26) 55 58 #define SYSC_MODULE_QUIRK_ENA_RESETDONE BIT(25)