aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2019-05-27 07:51:53 -0400
committerTony Lindgren <tony@atomide.com>2019-05-28 08:19:14 -0400
commit2b2f7def058a5386838ef4dba70a860285f79e66 (patch)
treeaf41e7f719b73f1f10e73cab852d91fe7caefe2f
parent4ee23cd76c0ce8622976b3da0e2bc89e6d94f6d4 (diff)
bus: ti-sysc: Add support for missing clockdomain handling
We need to let ti-sysc driver manage clockdomain autoidle for the duration of of reset, enable and idle. And we need to do it before we enable the clock and after we disable it. Currently we are still relying on platform callbacks indirectly managing clockdomain autoidle. But I noticed that for device tree only probed drivers it now happens only after we enabling the clocks and before we disable the clocks, while it should be the other way around. So far I have not noticed any issues with this though. Let's add new ti_sysc_clkdm_deny_idle() and ti_sysc_clkdm_allow_idle() functions for ti-sysc driver to use to manage clockdomains directly via platform data callbacks. Note that we can implement the clockdomain functions in pdata-quirks.c as for probing devices without "ti,hwmods" custom property we don't need to use the other platform data callbacks. Let's do this in one patch as there's is still an unlikely chance we may need to apply this as a fix for v5.2 for dropping legacy platform data for some devices. We also do have the option of adding back the platform data if needed in case of trouble. Tested-by: Keerthy <j-keerthy@ti.com> Signed-off-by: Tony Lindgren <tony@atomide.com>
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c39
-rw-r--r--arch/arm/mach-omap2/pdata-quirks.c60
-rw-r--r--drivers/bus/ti-sysc.c127
-rw-r--r--include/linux/platform_data/ti-sysc.h8
4 files changed, 174 insertions, 60 deletions
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 405ac24def05..932ba221e8e7 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -3445,6 +3445,7 @@ static int omap_hwmod_check_module(struct device *dev,
3445 * @dev: struct device 3445 * @dev: struct device
3446 * @oh: module 3446 * @oh: module
3447 * @sysc_fields: sysc register bits 3447 * @sysc_fields: sysc register bits
3448 * @clockdomain: clockdomain
3448 * @rev_offs: revision register offset 3449 * @rev_offs: revision register offset
3449 * @sysc_offs: sysconfig register offset 3450 * @sysc_offs: sysconfig register offset
3450 * @syss_offs: sysstatus register offset 3451 * @syss_offs: sysstatus register offset
@@ -3456,6 +3457,7 @@ static int omap_hwmod_check_module(struct device *dev,
3456static int omap_hwmod_allocate_module(struct device *dev, struct omap_hwmod *oh, 3457static int omap_hwmod_allocate_module(struct device *dev, struct omap_hwmod *oh,
3457 const struct ti_sysc_module_data *data, 3458 const struct ti_sysc_module_data *data,
3458 struct sysc_regbits *sysc_fields, 3459 struct sysc_regbits *sysc_fields,
3460 struct clockdomain *clkdm,
3459 s32 rev_offs, s32 sysc_offs, 3461 s32 rev_offs, s32 sysc_offs,
3460 s32 syss_offs, u32 sysc_flags, 3462 s32 syss_offs, u32 sysc_flags,
3461 u32 idlemodes) 3463 u32 idlemodes)
@@ -3463,8 +3465,6 @@ static int omap_hwmod_allocate_module(struct device *dev, struct omap_hwmod *oh,
3463 struct omap_hwmod_class_sysconfig *sysc; 3465 struct omap_hwmod_class_sysconfig *sysc;
3464 struct omap_hwmod_class *class = NULL; 3466 struct omap_hwmod_class *class = NULL;
3465 struct omap_hwmod_ocp_if *oi = NULL; 3467 struct omap_hwmod_ocp_if *oi = NULL;
3466 struct clockdomain *clkdm = NULL;
3467 struct clk *clk = NULL;
3468 void __iomem *regs = NULL; 3468 void __iomem *regs = NULL;
3469 unsigned long flags; 3469 unsigned long flags;
3470 3470
@@ -3511,36 +3511,6 @@ static int omap_hwmod_allocate_module(struct device *dev, struct omap_hwmod *oh,
3511 oi->user = OCP_USER_MPU | OCP_USER_SDMA; 3511 oi->user = OCP_USER_MPU | OCP_USER_SDMA;
3512 } 3512 }
3513 3513
3514 if (!oh->_clk) {
3515 struct clk_hw_omap *hwclk;
3516
3517 clk = of_clk_get_by_name(dev->of_node, "fck");
3518 if (!IS_ERR(clk))
3519 clk_prepare(clk);
3520 else
3521 clk = NULL;
3522
3523 /*
3524 * Populate clockdomain based on dts clock. It is needed for
3525 * clkdm_deny_idle() and clkdm_allow_idle() until we have have
3526 * interconnect driver and reset driver capable of blocking
3527 * clockdomain idle during reset, enable and idle.
3528 */
3529 if (clk) {
3530 hwclk = to_clk_hw_omap(__clk_get_hw(clk));
3531 if (hwclk && hwclk->clkdm_name)
3532 clkdm = clkdm_lookup(hwclk->clkdm_name);
3533 }
3534
3535 /*
3536 * Note that we assume interconnect driver manages the clocks
3537 * and do not need to populate oh->_clk for dynamically
3538 * allocated modules.
3539 */
3540 clk_unprepare(clk);
3541 clk_put(clk);
3542 }
3543
3544 spin_lock_irqsave(&oh->_lock, flags); 3514 spin_lock_irqsave(&oh->_lock, flags);
3545 if (regs) 3515 if (regs)
3546 oh->_mpu_rt_va = regs; 3516 oh->_mpu_rt_va = regs;
@@ -3626,7 +3596,7 @@ int omap_hwmod_init_module(struct device *dev,
3626 u32 sysc_flags, idlemodes; 3596 u32 sysc_flags, idlemodes;
3627 int error; 3597 int error;
3628 3598
3629 if (!dev || !data) 3599 if (!dev || !data || !data->name || !cookie)
3630 return -EINVAL; 3600 return -EINVAL;
3631 3601
3632 oh = _lookup(data->name); 3602 oh = _lookup(data->name);
@@ -3697,7 +3667,8 @@ int omap_hwmod_init_module(struct device *dev,
3697 return error; 3667 return error;
3698 3668
3699 return omap_hwmod_allocate_module(dev, oh, data, sysc_fields, 3669 return omap_hwmod_allocate_module(dev, oh, data, sysc_fields,
3700 rev_offs, sysc_offs, syss_offs, 3670 cookie->clkdm, rev_offs,
3671 sysc_offs, syss_offs,
3701 sysc_flags, idlemodes); 3672 sysc_flags, idlemodes);
3702} 3673}
3703 3674
diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c
index a2ecc5e69abb..b09cc4e8d240 100644
--- a/arch/arm/mach-omap2/pdata-quirks.c
+++ b/arch/arm/mach-omap2/pdata-quirks.c
@@ -29,6 +29,7 @@
29#include <linux/platform_data/wkup_m3.h> 29#include <linux/platform_data/wkup_m3.h>
30#include <linux/platform_data/asoc-ti-mcbsp.h> 30#include <linux/platform_data/asoc-ti-mcbsp.h>
31 31
32#include "clockdomain.h"
32#include "common.h" 33#include "common.h"
33#include "common-board-devices.h" 34#include "common-board-devices.h"
34#include "control.h" 35#include "control.h"
@@ -463,6 +464,62 @@ static void __init dra7x_evm_mmc_quirk(void)
463} 464}
464#endif 465#endif
465 466
467static struct clockdomain *ti_sysc_find_one_clockdomain(struct clk *clk)
468{
469 struct clockdomain *clkdm = NULL;
470 struct clk_hw_omap *hwclk;
471
472 hwclk = to_clk_hw_omap(__clk_get_hw(clk));
473 if (hwclk && hwclk->clkdm_name)
474 clkdm = clkdm_lookup(hwclk->clkdm_name);
475
476 return clkdm;
477}
478
479/**
480 * ti_sysc_clkdm_init - find clockdomain based on clock
481 * @fck: device functional clock
482 * @ick: device interface clock
483 * @dev: struct device
484 *
485 * Populate clockdomain based on clock. It is needed for
486 * clkdm_deny_idle() and clkdm_allow_idle() for blocking clockdomain
487 * clockdomain idle during reset, enable and idle.
488 *
489 * Note that we assume interconnect driver manages the clocks
490 * and do not need to populate oh->_clk for dynamically
491 * allocated modules.
492 */
493static int ti_sysc_clkdm_init(struct device *dev,
494 struct clk *fck, struct clk *ick,
495 struct ti_sysc_cookie *cookie)
496{
497 if (fck)
498 cookie->clkdm = ti_sysc_find_one_clockdomain(fck);
499 if (cookie->clkdm)
500 return 0;
501 if (ick)
502 cookie->clkdm = ti_sysc_find_one_clockdomain(ick);
503 if (cookie->clkdm)
504 return 0;
505
506 return -ENODEV;
507}
508
509static void ti_sysc_clkdm_deny_idle(struct device *dev,
510 const struct ti_sysc_cookie *cookie)
511{
512 if (cookie->clkdm)
513 clkdm_deny_idle(cookie->clkdm);
514}
515
516static void ti_sysc_clkdm_allow_idle(struct device *dev,
517 const struct ti_sysc_cookie *cookie)
518{
519 if (cookie->clkdm)
520 clkdm_allow_idle(cookie->clkdm);
521}
522
466static int ti_sysc_enable_module(struct device *dev, 523static int ti_sysc_enable_module(struct device *dev,
467 const struct ti_sysc_cookie *cookie) 524 const struct ti_sysc_cookie *cookie)
468{ 525{
@@ -494,6 +551,9 @@ static struct of_dev_auxdata omap_auxdata_lookup[];
494 551
495static struct ti_sysc_platform_data ti_sysc_pdata = { 552static struct ti_sysc_platform_data ti_sysc_pdata = {
496 .auxdata = omap_auxdata_lookup, 553 .auxdata = omap_auxdata_lookup,
554 .init_clockdomain = ti_sysc_clkdm_init,
555 .clkdm_deny_idle = ti_sysc_clkdm_deny_idle,
556 .clkdm_allow_idle = ti_sysc_clkdm_allow_idle,
497 .init_module = omap_hwmod_init_module, 557 .init_module = omap_hwmod_init_module,
498 .enable_module = ti_sysc_enable_module, 558 .enable_module = ti_sysc_enable_module,
499 .idle_module = ti_sysc_idle_module, 559 .idle_module = ti_sysc_idle_module,
diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c
index b72741668c92..e86f7850206a 100644
--- a/drivers/bus/ti-sysc.c
+++ b/drivers/bus/ti-sysc.c
@@ -422,6 +422,30 @@ static void sysc_disable_opt_clocks(struct sysc *ddata)
422 } 422 }
423} 423}
424 424
425static void sysc_clkdm_deny_idle(struct sysc *ddata)
426{
427 struct ti_sysc_platform_data *pdata;
428
429 if (ddata->legacy_mode)
430 return;
431
432 pdata = dev_get_platdata(ddata->dev);
433 if (pdata && pdata->clkdm_deny_idle)
434 pdata->clkdm_deny_idle(ddata->dev, &ddata->cookie);
435}
436
437static void sysc_clkdm_allow_idle(struct sysc *ddata)
438{
439 struct ti_sysc_platform_data *pdata;
440
441 if (ddata->legacy_mode)
442 return;
443
444 pdata = dev_get_platdata(ddata->dev);
445 if (pdata && pdata->clkdm_allow_idle)
446 pdata->clkdm_allow_idle(ddata->dev, &ddata->cookie);
447}
448
425/** 449/**
426 * sysc_init_resets - init rstctrl reset line if configured 450 * sysc_init_resets - init rstctrl reset line if configured
427 * @ddata: device driver data 451 * @ddata: device driver data
@@ -795,6 +819,7 @@ static void sysc_show_registers(struct sysc *ddata)
795 819
796#define SYSC_IDLE_MASK (SYSC_NR_IDLEMODES - 1) 820#define SYSC_IDLE_MASK (SYSC_NR_IDLEMODES - 1)
797 821
822/* Caller needs to manage sysc_clkdm_deny_idle() and sysc_clkdm_allow_idle() */
798static int sysc_enable_module(struct device *dev) 823static int sysc_enable_module(struct device *dev)
799{ 824{
800 struct sysc *ddata; 825 struct sysc *ddata;
@@ -805,11 +830,6 @@ static int sysc_enable_module(struct device *dev)
805 if (ddata->offsets[SYSC_SYSCONFIG] == -ENODEV) 830 if (ddata->offsets[SYSC_SYSCONFIG] == -ENODEV)
806 return 0; 831 return 0;
807 832
808 /*
809 * TODO: Need to prevent clockdomain autoidle?
810 * See clkdm_deny_idle() in arch/mach-omap2/omap_hwmod.c
811 */
812
813 regbits = ddata->cap->regbits; 833 regbits = ddata->cap->regbits;
814 reg = sysc_read(ddata, ddata->offsets[SYSC_SYSCONFIG]); 834 reg = sysc_read(ddata, ddata->offsets[SYSC_SYSCONFIG]);
815 835
@@ -861,6 +881,7 @@ static int sysc_best_idle_mode(u32 idlemodes, u32 *best_mode)
861 return 0; 881 return 0;
862} 882}
863 883
884/* Caller needs to manage sysc_clkdm_deny_idle() and sysc_clkdm_allow_idle() */
864static int sysc_disable_module(struct device *dev) 885static int sysc_disable_module(struct device *dev)
865{ 886{
866 struct sysc *ddata; 887 struct sysc *ddata;
@@ -872,11 +893,6 @@ static int sysc_disable_module(struct device *dev)
872 if (ddata->offsets[SYSC_SYSCONFIG] == -ENODEV) 893 if (ddata->offsets[SYSC_SYSCONFIG] == -ENODEV)
873 return 0; 894 return 0;
874 895
875 /*
876 * TODO: Need to prevent clockdomain autoidle?
877 * See clkdm_deny_idle() in arch/mach-omap2/omap_hwmod.c
878 */
879
880 regbits = ddata->cap->regbits; 896 regbits = ddata->cap->regbits;
881 reg = sysc_read(ddata, ddata->offsets[SYSC_SYSCONFIG]); 897 reg = sysc_read(ddata, ddata->offsets[SYSC_SYSCONFIG]);
882 898
@@ -966,14 +982,16 @@ static int __maybe_unused sysc_runtime_suspend(struct device *dev)
966 if (!ddata->enabled) 982 if (!ddata->enabled)
967 return 0; 983 return 0;
968 984
985 sysc_clkdm_deny_idle(ddata);
986
969 if (ddata->legacy_mode) { 987 if (ddata->legacy_mode) {
970 error = sysc_runtime_suspend_legacy(dev, ddata); 988 error = sysc_runtime_suspend_legacy(dev, ddata);
971 if (error) 989 if (error)
972 return error; 990 goto err_allow_idle;
973 } else { 991 } else {
974 error = sysc_disable_module(dev); 992 error = sysc_disable_module(dev);
975 if (error) 993 if (error)
976 return error; 994 goto err_allow_idle;
977 } 995 }
978 996
979 sysc_disable_main_clocks(ddata); 997 sysc_disable_main_clocks(ddata);
@@ -983,6 +1001,9 @@ static int __maybe_unused sysc_runtime_suspend(struct device *dev)
983 1001
984 ddata->enabled = false; 1002 ddata->enabled = false;
985 1003
1004err_allow_idle:
1005 sysc_clkdm_allow_idle(ddata);
1006
986 return error; 1007 return error;
987} 1008}
988 1009
@@ -996,10 +1017,12 @@ static int __maybe_unused sysc_runtime_resume(struct device *dev)
996 if (ddata->enabled) 1017 if (ddata->enabled)
997 return 0; 1018 return 0;
998 1019
1020 sysc_clkdm_deny_idle(ddata);
1021
999 if (sysc_opt_clks_needed(ddata)) { 1022 if (sysc_opt_clks_needed(ddata)) {
1000 error = sysc_enable_opt_clocks(ddata); 1023 error = sysc_enable_opt_clocks(ddata);
1001 if (error) 1024 if (error)
1002 return error; 1025 goto err_allow_idle;
1003 } 1026 }
1004 1027
1005 error = sysc_enable_main_clocks(ddata); 1028 error = sysc_enable_main_clocks(ddata);
@@ -1018,6 +1041,8 @@ static int __maybe_unused sysc_runtime_resume(struct device *dev)
1018 1041
1019 ddata->enabled = true; 1042 ddata->enabled = true;
1020 1043
1044 sysc_clkdm_allow_idle(ddata);
1045
1021 return 0; 1046 return 0;
1022 1047
1023err_main_clocks: 1048err_main_clocks:
@@ -1025,6 +1050,8 @@ err_main_clocks:
1025err_opt_clocks: 1050err_opt_clocks:
1026 if (sysc_opt_clks_needed(ddata)) 1051 if (sysc_opt_clks_needed(ddata))
1027 sysc_disable_opt_clocks(ddata); 1052 sysc_disable_opt_clocks(ddata);
1053err_allow_idle:
1054 sysc_clkdm_allow_idle(ddata);
1028 1055
1029 return error; 1056 return error;
1030} 1057}
@@ -1245,6 +1272,33 @@ static void sysc_init_revision_quirks(struct sysc *ddata)
1245 } 1272 }
1246} 1273}
1247 1274
1275static int sysc_clockdomain_init(struct sysc *ddata)
1276{
1277 struct ti_sysc_platform_data *pdata = dev_get_platdata(ddata->dev);
1278 struct clk *fck = NULL, *ick = NULL;
1279 int error;
1280
1281 if (!pdata || !pdata->init_clockdomain)
1282 return 0;
1283
1284 switch (ddata->nr_clocks) {
1285 case 2:
1286 ick = ddata->clocks[SYSC_ICK];
1287 /* fallthrough */
1288 case 1:
1289 fck = ddata->clocks[SYSC_FCK];
1290 break;
1291 case 0:
1292 return 0;
1293 }
1294
1295 error = pdata->init_clockdomain(ddata->dev, fck, ick, &ddata->cookie);
1296 if (!error || error == -ENODEV)
1297 return 0;
1298
1299 return error;
1300}
1301
1248/* 1302/*
1249 * Note that pdata->init_module() typically does a reset first. After 1303 * Note that pdata->init_module() typically does a reset first. After
1250 * pdata->init_module() is done, PM runtime can be used for the interconnect 1304 * pdata->init_module() is done, PM runtime can be used for the interconnect
@@ -1255,7 +1309,7 @@ static int sysc_legacy_init(struct sysc *ddata)
1255 struct ti_sysc_platform_data *pdata = dev_get_platdata(ddata->dev); 1309 struct ti_sysc_platform_data *pdata = dev_get_platdata(ddata->dev);
1256 int error; 1310 int error;
1257 1311
1258 if (!ddata->legacy_mode || !pdata || !pdata->init_module) 1312 if (!pdata || !pdata->init_module)
1259 return 0; 1313 return 0;
1260 1314
1261 error = pdata->init_module(ddata->dev, ddata->mdata, &ddata->cookie); 1315 error = pdata->init_module(ddata->dev, ddata->mdata, &ddata->cookie);
@@ -1347,7 +1401,13 @@ static int sysc_init_module(struct sysc *ddata)
1347 (SYSC_QUIRK_NO_IDLE | SYSC_QUIRK_NO_IDLE_ON_INIT)) 1401 (SYSC_QUIRK_NO_IDLE | SYSC_QUIRK_NO_IDLE_ON_INIT))
1348 manage_clocks = false; 1402 manage_clocks = false;
1349 1403
1404 error = sysc_clockdomain_init(ddata);
1405 if (error)
1406 return error;
1407
1350 if (manage_clocks) { 1408 if (manage_clocks) {
1409 sysc_clkdm_deny_idle(ddata);
1410
1351 error = sysc_enable_opt_clocks(ddata); 1411 error = sysc_enable_opt_clocks(ddata);
1352 if (error) 1412 if (error)
1353 return error; 1413 return error;
@@ -1360,20 +1420,33 @@ static int sysc_init_module(struct sysc *ddata)
1360 ddata->revision = sysc_read_revision(ddata); 1420 ddata->revision = sysc_read_revision(ddata);
1361 sysc_init_revision_quirks(ddata); 1421 sysc_init_revision_quirks(ddata);
1362 1422
1363 error = sysc_legacy_init(ddata); 1423 if (ddata->legacy_mode) {
1364 if (error) 1424 error = sysc_legacy_init(ddata);
1365 goto err_main_clocks; 1425 if (error)
1426 goto err_main_clocks;
1427 }
1428
1429 if (!ddata->legacy_mode && manage_clocks) {
1430 error = sysc_enable_module(ddata->dev);
1431 if (error)
1432 goto err_main_clocks;
1433 }
1366 1434
1367 error = sysc_reset(ddata); 1435 error = sysc_reset(ddata);
1368 if (error) 1436 if (error)
1369 dev_err(ddata->dev, "Reset failed with %d\n", error); 1437 dev_err(ddata->dev, "Reset failed with %d\n", error);
1370 1438
1439 if (!ddata->legacy_mode && manage_clocks)
1440 sysc_disable_module(ddata->dev);
1441
1371err_main_clocks: 1442err_main_clocks:
1372 if (manage_clocks) 1443 if (manage_clocks)
1373 sysc_disable_main_clocks(ddata); 1444 sysc_disable_main_clocks(ddata);
1374err_opt_clocks: 1445err_opt_clocks:
1375 if (manage_clocks) 1446 if (manage_clocks) {
1376 sysc_disable_opt_clocks(ddata); 1447 sysc_disable_opt_clocks(ddata);
1448 sysc_clkdm_allow_idle(ddata);
1449 }
1377 1450
1378 return error; 1451 return error;
1379} 1452}
@@ -2012,20 +2085,22 @@ static int sysc_init_pdata(struct sysc *ddata)
2012 struct ti_sysc_platform_data *pdata = dev_get_platdata(ddata->dev); 2085 struct ti_sysc_platform_data *pdata = dev_get_platdata(ddata->dev);
2013 struct ti_sysc_module_data *mdata; 2086 struct ti_sysc_module_data *mdata;
2014 2087
2015 if (!pdata || !ddata->legacy_mode) 2088 if (!pdata)
2016 return 0; 2089 return 0;
2017 2090
2018 mdata = devm_kzalloc(ddata->dev, sizeof(*mdata), GFP_KERNEL); 2091 mdata = devm_kzalloc(ddata->dev, sizeof(*mdata), GFP_KERNEL);
2019 if (!mdata) 2092 if (!mdata)
2020 return -ENOMEM; 2093 return -ENOMEM;
2021 2094
2022 mdata->name = ddata->legacy_mode; 2095 if (ddata->legacy_mode) {
2023 mdata->module_pa = ddata->module_pa; 2096 mdata->name = ddata->legacy_mode;
2024 mdata->module_size = ddata->module_size; 2097 mdata->module_pa = ddata->module_pa;
2025 mdata->offsets = ddata->offsets; 2098 mdata->module_size = ddata->module_size;
2026 mdata->nr_offsets = SYSC_MAX_REGS; 2099 mdata->offsets = ddata->offsets;
2027 mdata->cap = ddata->cap; 2100 mdata->nr_offsets = SYSC_MAX_REGS;
2028 mdata->cfg = &ddata->cfg; 2101 mdata->cap = ddata->cap;
2102 mdata->cfg = &ddata->cfg;
2103 }
2029 2104
2030 ddata->mdata = mdata; 2105 ddata->mdata = mdata;
2031 2106
diff --git a/include/linux/platform_data/ti-sysc.h b/include/linux/platform_data/ti-sysc.h
index 9256c0305968..6626fd31e309 100644
--- a/include/linux/platform_data/ti-sysc.h
+++ b/include/linux/platform_data/ti-sysc.h
@@ -19,6 +19,7 @@ enum ti_sysc_module_type {
19 19
20struct ti_sysc_cookie { 20struct ti_sysc_cookie {
21 void *data; 21 void *data;
22 void *clkdm;
22}; 23};
23 24
24/** 25/**
@@ -125,9 +126,16 @@ struct ti_sysc_module_data {
125}; 126};
126 127
127struct device; 128struct device;
129struct clk;
128 130
129struct ti_sysc_platform_data { 131struct ti_sysc_platform_data {
130 struct of_dev_auxdata *auxdata; 132 struct of_dev_auxdata *auxdata;
133 int (*init_clockdomain)(struct device *dev, struct clk *fck,
134 struct clk *ick, struct ti_sysc_cookie *cookie);
135 void (*clkdm_deny_idle)(struct device *dev,
136 const struct ti_sysc_cookie *cookie);
137 void (*clkdm_allow_idle)(struct device *dev,
138 const struct ti_sysc_cookie *cookie);
131 int (*init_module)(struct device *dev, 139 int (*init_module)(struct device *dev,
132 const struct ti_sysc_module_data *data, 140 const struct ti_sysc_module_data *data,
133 struct ti_sysc_cookie *cookie); 141 struct ti_sysc_cookie *cookie);