diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-12 15:42:32 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-12 15:42:32 -0400 |
commit | bae14e7a2dcb726476b5020396923a24ccc4c40b (patch) | |
tree | 8da2102b927e14b9406db34e41b0ecc192616e2f /drivers/mfd | |
parent | 171c062188c6bc6ca5d28b2a9b9acc272ac1244e (diff) | |
parent | 43fef47f94a1ae46fb2720dada32fa3b5547bee2 (diff) |
Merge tag 'mfd-for-linus-3.16-1' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd
Pull more MFD updates from Lee Jones:
"I missed collecting these patches due to a branch/tag naming
ambiguity. Completely my own fault, as I mindlessly named a branch
and tag identically. Sorry for the fuss.
This pull-request contains some misplaced patches from Tony Lindgren
that should have been part of the initial one"
* tag 'mfd-for-linus-3.16-1' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd:
mfd: twl4030-power: Add a configuration to turn off oscillator during off-idle
mfd: twl4030-power: Add support for board specific configuration
mfd: twl4030-power: Add recommended idle configuration
mfd: twl4030-power: Add generic reset configuration
mfd: twl4030-power: Fix some defines for SW_EVENTS
mfd: twl4030-power: Fix hang on reboot if sleep configuration was loaded earlier
Diffstat (limited to 'drivers/mfd')
-rw-r--r-- | drivers/mfd/twl4030-power.c | 286 |
1 files changed, 261 insertions, 25 deletions
diff --git a/drivers/mfd/twl4030-power.c b/drivers/mfd/twl4030-power.c index 96162b62f3c0..3bc969a5916b 100644 --- a/drivers/mfd/twl4030-power.c +++ b/drivers/mfd/twl4030-power.c | |||
@@ -29,13 +29,21 @@ | |||
29 | #include <linux/i2c/twl.h> | 29 | #include <linux/i2c/twl.h> |
30 | #include <linux/platform_device.h> | 30 | #include <linux/platform_device.h> |
31 | #include <linux/of.h> | 31 | #include <linux/of.h> |
32 | #include <linux/of_device.h> | ||
32 | 33 | ||
33 | #include <asm/mach-types.h> | 34 | #include <asm/mach-types.h> |
34 | 35 | ||
35 | static u8 twl4030_start_script_address = 0x2b; | 36 | static u8 twl4030_start_script_address = 0x2b; |
36 | 37 | ||
37 | #define PWR_P1_SW_EVENTS 0x10 | 38 | /* Register bits for P1, P2 and P3_SW_EVENTS */ |
38 | #define PWR_DEVOFF (1 << 0) | 39 | #define PWR_STOPON_PRWON BIT(6) |
40 | #define PWR_STOPON_SYSEN BIT(5) | ||
41 | #define PWR_ENABLE_WARMRESET BIT(4) | ||
42 | #define PWR_LVL_WAKEUP BIT(3) | ||
43 | #define PWR_DEVACT BIT(2) | ||
44 | #define PWR_DEVSLP BIT(1) | ||
45 | #define PWR_DEVOFF BIT(0) | ||
46 | |||
39 | #define SEQ_OFFSYNC (1 << 0) | 47 | #define SEQ_OFFSYNC (1 << 0) |
40 | 48 | ||
41 | #define PHY_TO_OFF_PM_MASTER(p) (p - 0x36) | 49 | #define PHY_TO_OFF_PM_MASTER(p) (p - 0x36) |
@@ -52,10 +60,6 @@ static u8 twl4030_start_script_address = 0x2b; | |||
52 | #define R_CFG_P2_TRANSITION PHY_TO_OFF_PM_MASTER(0x37) | 60 | #define R_CFG_P2_TRANSITION PHY_TO_OFF_PM_MASTER(0x37) |
53 | #define R_CFG_P3_TRANSITION PHY_TO_OFF_PM_MASTER(0x38) | 61 | #define R_CFG_P3_TRANSITION PHY_TO_OFF_PM_MASTER(0x38) |
54 | 62 | ||
55 | #define LVL_WAKEUP 0x08 | ||
56 | |||
57 | #define ENABLE_WARMRESET (1<<4) | ||
58 | |||
59 | #define END_OF_SCRIPT 0x3f | 63 | #define END_OF_SCRIPT 0x3f |
60 | 64 | ||
61 | #define R_SEQ_ADD_A2S PHY_TO_OFF_PM_MASTER(0x55) | 65 | #define R_SEQ_ADD_A2S PHY_TO_OFF_PM_MASTER(0x55) |
@@ -125,6 +129,53 @@ static u8 res_config_addrs[] = { | |||
125 | [RES_MAIN_REF] = 0x94, | 129 | [RES_MAIN_REF] = 0x94, |
126 | }; | 130 | }; |
127 | 131 | ||
132 | /* | ||
133 | * Usable values for .remap_sleep and .remap_off | ||
134 | * Based on table "5.3.3 Resource Operating modes" | ||
135 | */ | ||
136 | enum { | ||
137 | TWL_REMAP_OFF = 0, | ||
138 | TWL_REMAP_SLEEP = 8, | ||
139 | TWL_REMAP_ACTIVE = 9, | ||
140 | }; | ||
141 | |||
142 | /* | ||
143 | * Macros to configure the PM register states for various resources. | ||
144 | * Note that we can make MSG_SINGULAR etc private to this driver once | ||
145 | * omap3 has been made DT only. | ||
146 | */ | ||
147 | #define TWL_DFLT_DELAY 2 /* typically 2 32 KiHz cycles */ | ||
148 | #define TWL_DEV_GRP_P123 (DEV_GRP_P1 | DEV_GRP_P2 | DEV_GRP_P3) | ||
149 | #define TWL_RESOURCE_SET(res, state) \ | ||
150 | { MSG_SINGULAR(DEV_GRP_NULL, (res), (state)), TWL_DFLT_DELAY } | ||
151 | #define TWL_RESOURCE_ON(res) TWL_RESOURCE_SET(res, RES_STATE_ACTIVE) | ||
152 | #define TWL_RESOURCE_OFF(res) TWL_RESOURCE_SET(res, RES_STATE_OFF) | ||
153 | #define TWL_RESOURCE_RESET(res) TWL_RESOURCE_SET(res, RES_STATE_WRST) | ||
154 | /* | ||
155 | * It seems that type1 and type2 is just the resource init order | ||
156 | * number for the type1 and type2 group. | ||
157 | */ | ||
158 | #define TWL_RESOURCE_SET_ACTIVE(res, state) \ | ||
159 | { MSG_SINGULAR(DEV_GRP_NULL, (res), RES_STATE_ACTIVE), (state) } | ||
160 | #define TWL_RESOURCE_GROUP_RESET(group, type1, type2) \ | ||
161 | { MSG_BROADCAST(DEV_GRP_NULL, (group), (type1), (type2), \ | ||
162 | RES_STATE_WRST), TWL_DFLT_DELAY } | ||
163 | #define TWL_RESOURCE_GROUP_SLEEP(group, type, type2) \ | ||
164 | { MSG_BROADCAST(DEV_GRP_NULL, (group), (type), (type2), \ | ||
165 | RES_STATE_SLEEP), TWL_DFLT_DELAY } | ||
166 | #define TWL_RESOURCE_GROUP_ACTIVE(group, type, type2) \ | ||
167 | { MSG_BROADCAST(DEV_GRP_NULL, (group), (type), (type2), \ | ||
168 | RES_STATE_ACTIVE), TWL_DFLT_DELAY } | ||
169 | #define TWL_REMAP_SLEEP(res, devgrp, typ, typ2) \ | ||
170 | { .resource = (res), .devgroup = (devgrp), \ | ||
171 | .type = (typ), .type2 = (typ2), \ | ||
172 | .remap_off = TWL_REMAP_OFF, \ | ||
173 | .remap_sleep = TWL_REMAP_SLEEP, } | ||
174 | #define TWL_REMAP_OFF(res, devgrp, typ, typ2) \ | ||
175 | { .resource = (res), .devgroup = (devgrp), \ | ||
176 | .type = (typ), .type2 = (typ2), \ | ||
177 | .remap_off = TWL_REMAP_OFF, .remap_sleep = TWL_REMAP_OFF, } | ||
178 | |||
128 | static int twl4030_write_script_byte(u8 address, u8 byte) | 179 | static int twl4030_write_script_byte(u8 address, u8 byte) |
129 | { | 180 | { |
130 | int err; | 181 | int err; |
@@ -196,7 +247,7 @@ static int twl4030_config_wakeup3_sequence(u8 address) | |||
196 | err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &data, R_P3_SW_EVENTS); | 247 | err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &data, R_P3_SW_EVENTS); |
197 | if (err) | 248 | if (err) |
198 | goto out; | 249 | goto out; |
199 | data |= LVL_WAKEUP; | 250 | data |= PWR_LVL_WAKEUP; |
200 | err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, data, R_P3_SW_EVENTS); | 251 | err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, data, R_P3_SW_EVENTS); |
201 | out: | 252 | out: |
202 | if (err) | 253 | if (err) |
@@ -219,7 +270,7 @@ static int twl4030_config_wakeup12_sequence(u8 address) | |||
219 | if (err) | 270 | if (err) |
220 | goto out; | 271 | goto out; |
221 | 272 | ||
222 | data |= LVL_WAKEUP; | 273 | data |= PWR_LVL_WAKEUP; |
223 | err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, data, R_P1_SW_EVENTS); | 274 | err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, data, R_P1_SW_EVENTS); |
224 | if (err) | 275 | if (err) |
225 | goto out; | 276 | goto out; |
@@ -228,7 +279,7 @@ static int twl4030_config_wakeup12_sequence(u8 address) | |||
228 | if (err) | 279 | if (err) |
229 | goto out; | 280 | goto out; |
230 | 281 | ||
231 | data |= LVL_WAKEUP; | 282 | data |= PWR_LVL_WAKEUP; |
232 | err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, data, R_P2_SW_EVENTS); | 283 | err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, data, R_P2_SW_EVENTS); |
233 | if (err) | 284 | if (err) |
234 | goto out; | 285 | goto out; |
@@ -281,7 +332,7 @@ static int twl4030_config_warmreset_sequence(u8 address) | |||
281 | if (err) | 332 | if (err) |
282 | goto out; | 333 | goto out; |
283 | 334 | ||
284 | rd_data |= ENABLE_WARMRESET; | 335 | rd_data |= PWR_ENABLE_WARMRESET; |
285 | err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, rd_data, R_P1_SW_EVENTS); | 336 | err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, rd_data, R_P1_SW_EVENTS); |
286 | if (err) | 337 | if (err) |
287 | goto out; | 338 | goto out; |
@@ -290,7 +341,7 @@ static int twl4030_config_warmreset_sequence(u8 address) | |||
290 | if (err) | 341 | if (err) |
291 | goto out; | 342 | goto out; |
292 | 343 | ||
293 | rd_data |= ENABLE_WARMRESET; | 344 | rd_data |= PWR_ENABLE_WARMRESET; |
294 | err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, rd_data, R_P2_SW_EVENTS); | 345 | err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, rd_data, R_P2_SW_EVENTS); |
295 | if (err) | 346 | if (err) |
296 | goto out; | 347 | goto out; |
@@ -299,7 +350,7 @@ static int twl4030_config_warmreset_sequence(u8 address) | |||
299 | if (err) | 350 | if (err) |
300 | goto out; | 351 | goto out; |
301 | 352 | ||
302 | rd_data |= ENABLE_WARMRESET; | 353 | rd_data |= PWR_ENABLE_WARMRESET; |
303 | err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, rd_data, R_P3_SW_EVENTS); | 354 | err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, rd_data, R_P3_SW_EVENTS); |
304 | out: | 355 | out: |
305 | if (err) | 356 | if (err) |
@@ -421,6 +472,12 @@ static int load_twl4030_script(struct twl4030_script *tscript, | |||
421 | goto out; | 472 | goto out; |
422 | } | 473 | } |
423 | if (tscript->flags & TWL4030_WAKEUP12_SCRIPT) { | 474 | if (tscript->flags & TWL4030_WAKEUP12_SCRIPT) { |
475 | /* Reset any existing sleep script to avoid hangs on reboot */ | ||
476 | err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT, | ||
477 | R_SEQ_ADD_A2S); | ||
478 | if (err) | ||
479 | goto out; | ||
480 | |||
424 | err = twl4030_config_wakeup12_sequence(address); | 481 | err = twl4030_config_wakeup12_sequence(address); |
425 | if (err) | 482 | if (err) |
426 | goto out; | 483 | goto out; |
@@ -493,7 +550,8 @@ int twl4030_remove_script(u8 flags) | |||
493 | return err; | 550 | return err; |
494 | } | 551 | } |
495 | 552 | ||
496 | static int twl4030_power_configure_scripts(struct twl4030_power_data *pdata) | 553 | static int |
554 | twl4030_power_configure_scripts(const struct twl4030_power_data *pdata) | ||
497 | { | 555 | { |
498 | int err; | 556 | int err; |
499 | int i; | 557 | int i; |
@@ -509,12 +567,34 @@ static int twl4030_power_configure_scripts(struct twl4030_power_data *pdata) | |||
509 | return 0; | 567 | return 0; |
510 | } | 568 | } |
511 | 569 | ||
512 | static int twl4030_power_configure_resources(struct twl4030_power_data *pdata) | 570 | static void twl4030_patch_rconfig(struct twl4030_resconfig *common, |
571 | struct twl4030_resconfig *board) | ||
572 | { | ||
573 | while (common->resource) { | ||
574 | struct twl4030_resconfig *b = board; | ||
575 | |||
576 | while (b->resource) { | ||
577 | if (b->resource == common->resource) { | ||
578 | *common = *b; | ||
579 | break; | ||
580 | } | ||
581 | b++; | ||
582 | } | ||
583 | common++; | ||
584 | } | ||
585 | } | ||
586 | |||
587 | static int | ||
588 | twl4030_power_configure_resources(const struct twl4030_power_data *pdata) | ||
513 | { | 589 | { |
514 | struct twl4030_resconfig *resconfig = pdata->resource_config; | 590 | struct twl4030_resconfig *resconfig = pdata->resource_config; |
591 | struct twl4030_resconfig *boardconf = pdata->board_config; | ||
515 | int err; | 592 | int err; |
516 | 593 | ||
517 | if (resconfig) { | 594 | if (resconfig) { |
595 | if (boardconf) | ||
596 | twl4030_patch_rconfig(resconfig, boardconf); | ||
597 | |||
518 | while (resconfig->resource) { | 598 | while (resconfig->resource) { |
519 | err = twl4030_configure_resource(resconfig); | 599 | err = twl4030_configure_resource(resconfig); |
520 | if (err) | 600 | if (err) |
@@ -541,7 +621,7 @@ void twl4030_power_off(void) | |||
541 | pr_err("TWL4030 Unable to power off\n"); | 621 | pr_err("TWL4030 Unable to power off\n"); |
542 | } | 622 | } |
543 | 623 | ||
544 | static bool twl4030_power_use_poweroff(struct twl4030_power_data *pdata, | 624 | static bool twl4030_power_use_poweroff(const struct twl4030_power_data *pdata, |
545 | struct device_node *node) | 625 | struct device_node *node) |
546 | { | 626 | { |
547 | if (pdata && pdata->use_poweroff) | 627 | if (pdata && pdata->use_poweroff) |
@@ -553,10 +633,170 @@ static bool twl4030_power_use_poweroff(struct twl4030_power_data *pdata, | |||
553 | return false; | 633 | return false; |
554 | } | 634 | } |
555 | 635 | ||
636 | #ifdef CONFIG_OF | ||
637 | |||
638 | /* Generic warm reset configuration for omap3 */ | ||
639 | |||
640 | static struct twl4030_ins omap3_wrst_seq[] = { | ||
641 | TWL_RESOURCE_OFF(RES_NRES_PWRON), | ||
642 | TWL_RESOURCE_OFF(RES_RESET), | ||
643 | TWL_RESOURCE_RESET(RES_MAIN_REF), | ||
644 | TWL_RESOURCE_GROUP_RESET(RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2), | ||
645 | TWL_RESOURCE_RESET(RES_VUSB_3V1), | ||
646 | TWL_RESOURCE_GROUP_RESET(RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R1), | ||
647 | TWL_RESOURCE_GROUP_RESET(RES_GRP_RC, RES_TYPE_ALL, RES_TYPE2_R0), | ||
648 | TWL_RESOURCE_ON(RES_RESET), | ||
649 | TWL_RESOURCE_ON(RES_NRES_PWRON), | ||
650 | }; | ||
651 | |||
652 | static struct twl4030_script omap3_wrst_script = { | ||
653 | .script = omap3_wrst_seq, | ||
654 | .size = ARRAY_SIZE(omap3_wrst_seq), | ||
655 | .flags = TWL4030_WRST_SCRIPT, | ||
656 | }; | ||
657 | |||
658 | static struct twl4030_script *omap3_reset_scripts[] = { | ||
659 | &omap3_wrst_script, | ||
660 | }; | ||
661 | |||
662 | static struct twl4030_resconfig omap3_rconfig[] = { | ||
663 | TWL_REMAP_SLEEP(RES_HFCLKOUT, DEV_GRP_P3, -1, -1), | ||
664 | TWL_REMAP_SLEEP(RES_VDD1, DEV_GRP_P1, -1, -1), | ||
665 | TWL_REMAP_SLEEP(RES_VDD2, DEV_GRP_P1, -1, -1), | ||
666 | { 0, 0 }, | ||
667 | }; | ||
668 | |||
669 | static struct twl4030_power_data omap3_reset = { | ||
670 | .scripts = omap3_reset_scripts, | ||
671 | .num = ARRAY_SIZE(omap3_reset_scripts), | ||
672 | .resource_config = omap3_rconfig, | ||
673 | }; | ||
674 | |||
675 | /* Recommended generic default idle configuration for off-idle */ | ||
676 | |||
677 | /* Broadcast message to put res to sleep */ | ||
678 | static struct twl4030_ins omap3_idle_sleep_on_seq[] = { | ||
679 | TWL_RESOURCE_GROUP_SLEEP(RES_GRP_ALL, RES_TYPE_ALL, 0), | ||
680 | }; | ||
681 | |||
682 | static struct twl4030_script omap3_idle_sleep_on_script = { | ||
683 | .script = omap3_idle_sleep_on_seq, | ||
684 | .size = ARRAY_SIZE(omap3_idle_sleep_on_seq), | ||
685 | .flags = TWL4030_SLEEP_SCRIPT, | ||
686 | }; | ||
687 | |||
688 | /* Broadcast message to put res to active */ | ||
689 | static struct twl4030_ins omap3_idle_wakeup_p12_seq[] = { | ||
690 | TWL_RESOURCE_GROUP_ACTIVE(RES_GRP_ALL, RES_TYPE_ALL, 0), | ||
691 | }; | ||
692 | |||
693 | static struct twl4030_script omap3_idle_wakeup_p12_script = { | ||
694 | .script = omap3_idle_wakeup_p12_seq, | ||
695 | .size = ARRAY_SIZE(omap3_idle_wakeup_p12_seq), | ||
696 | .flags = TWL4030_WAKEUP12_SCRIPT, | ||
697 | }; | ||
698 | |||
699 | /* Broadcast message to put res to active */ | ||
700 | static struct twl4030_ins omap3_idle_wakeup_p3_seq[] = { | ||
701 | TWL_RESOURCE_SET_ACTIVE(RES_CLKEN, 0x37), | ||
702 | TWL_RESOURCE_GROUP_ACTIVE(RES_GRP_ALL, RES_TYPE_ALL, 0), | ||
703 | }; | ||
704 | |||
705 | static struct twl4030_script omap3_idle_wakeup_p3_script = { | ||
706 | .script = omap3_idle_wakeup_p3_seq, | ||
707 | .size = ARRAY_SIZE(omap3_idle_wakeup_p3_seq), | ||
708 | .flags = TWL4030_WAKEUP3_SCRIPT, | ||
709 | }; | ||
710 | |||
711 | static struct twl4030_script *omap3_idle_scripts[] = { | ||
712 | &omap3_idle_wakeup_p12_script, | ||
713 | &omap3_idle_wakeup_p3_script, | ||
714 | &omap3_wrst_script, | ||
715 | &omap3_idle_sleep_on_script, | ||
716 | }; | ||
717 | |||
718 | /* | ||
719 | * Recommended configuration based on "Recommended Sleep | ||
720 | * Sequences for the Zoom Platform": | ||
721 | * http://omappedia.com/wiki/File:Recommended_Sleep_Sequences_Zoom.pdf | ||
722 | * Note that the type1 and type2 seem to be just the init order number | ||
723 | * for type1 and type2 groups as specified in the document mentioned | ||
724 | * above. | ||
725 | */ | ||
726 | static struct twl4030_resconfig omap3_idle_rconfig[] = { | ||
727 | TWL_REMAP_SLEEP(RES_VAUX1, DEV_GRP_NULL, 0, 0), | ||
728 | TWL_REMAP_SLEEP(RES_VAUX2, DEV_GRP_NULL, 0, 0), | ||
729 | TWL_REMAP_SLEEP(RES_VAUX3, DEV_GRP_NULL, 0, 0), | ||
730 | TWL_REMAP_SLEEP(RES_VAUX4, DEV_GRP_NULL, 0, 0), | ||
731 | TWL_REMAP_SLEEP(RES_VMMC1, DEV_GRP_NULL, 0, 0), | ||
732 | TWL_REMAP_SLEEP(RES_VMMC2, DEV_GRP_NULL, 0, 0), | ||
733 | TWL_REMAP_OFF(RES_VPLL1, DEV_GRP_P1, 3, 1), | ||
734 | TWL_REMAP_SLEEP(RES_VPLL2, DEV_GRP_P1, 0, 0), | ||
735 | TWL_REMAP_SLEEP(RES_VSIM, DEV_GRP_NULL, 0, 0), | ||
736 | TWL_REMAP_SLEEP(RES_VDAC, DEV_GRP_NULL, 0, 0), | ||
737 | TWL_REMAP_SLEEP(RES_VINTANA1, TWL_DEV_GRP_P123, 1, 2), | ||
738 | TWL_REMAP_SLEEP(RES_VINTANA2, TWL_DEV_GRP_P123, 0, 2), | ||
739 | TWL_REMAP_SLEEP(RES_VINTDIG, TWL_DEV_GRP_P123, 1, 2), | ||
740 | TWL_REMAP_SLEEP(RES_VIO, TWL_DEV_GRP_P123, 2, 2), | ||
741 | TWL_REMAP_OFF(RES_VDD1, DEV_GRP_P1, 4, 1), | ||
742 | TWL_REMAP_OFF(RES_VDD2, DEV_GRP_P1, 3, 1), | ||
743 | TWL_REMAP_SLEEP(RES_VUSB_1V5, DEV_GRP_NULL, 0, 0), | ||
744 | TWL_REMAP_SLEEP(RES_VUSB_1V8, DEV_GRP_NULL, 0, 0), | ||
745 | TWL_REMAP_SLEEP(RES_VUSB_3V1, TWL_DEV_GRP_P123, 0, 0), | ||
746 | /* Resource #20 USB charge pump skipped */ | ||
747 | TWL_REMAP_SLEEP(RES_REGEN, TWL_DEV_GRP_P123, 2, 1), | ||
748 | TWL_REMAP_SLEEP(RES_NRES_PWRON, TWL_DEV_GRP_P123, 0, 1), | ||
749 | TWL_REMAP_SLEEP(RES_CLKEN, TWL_DEV_GRP_P123, 3, 2), | ||
750 | TWL_REMAP_SLEEP(RES_SYSEN, TWL_DEV_GRP_P123, 6, 1), | ||
751 | TWL_REMAP_SLEEP(RES_HFCLKOUT, DEV_GRP_P3, 0, 2), | ||
752 | TWL_REMAP_SLEEP(RES_32KCLKOUT, TWL_DEV_GRP_P123, 0, 0), | ||
753 | TWL_REMAP_SLEEP(RES_RESET, TWL_DEV_GRP_P123, 6, 0), | ||
754 | TWL_REMAP_SLEEP(RES_MAIN_REF, TWL_DEV_GRP_P123, 0, 0), | ||
755 | { /* Terminator */ }, | ||
756 | }; | ||
757 | |||
758 | static struct twl4030_power_data omap3_idle = { | ||
759 | .scripts = omap3_idle_scripts, | ||
760 | .num = ARRAY_SIZE(omap3_idle_scripts), | ||
761 | .resource_config = omap3_idle_rconfig, | ||
762 | }; | ||
763 | |||
764 | /* Disable 32 KiHz oscillator during idle */ | ||
765 | static struct twl4030_resconfig osc_off_rconfig[] = { | ||
766 | TWL_REMAP_OFF(RES_CLKEN, DEV_GRP_P1 | DEV_GRP_P3, 3, 2), | ||
767 | { /* Terminator */ }, | ||
768 | }; | ||
769 | |||
770 | static struct twl4030_power_data osc_off_idle = { | ||
771 | .scripts = omap3_idle_scripts, | ||
772 | .num = ARRAY_SIZE(omap3_idle_scripts), | ||
773 | .resource_config = omap3_idle_rconfig, | ||
774 | .board_config = osc_off_rconfig, | ||
775 | }; | ||
776 | |||
777 | static struct of_device_id twl4030_power_of_match[] = { | ||
778 | { | ||
779 | .compatible = "ti,twl4030-power-reset", | ||
780 | .data = &omap3_reset, | ||
781 | }, | ||
782 | { | ||
783 | .compatible = "ti,twl4030-power-idle", | ||
784 | .data = &omap3_idle, | ||
785 | }, | ||
786 | { | ||
787 | .compatible = "ti,twl4030-power-idle-osc-off", | ||
788 | .data = &osc_off_idle, | ||
789 | }, | ||
790 | { }, | ||
791 | }; | ||
792 | MODULE_DEVICE_TABLE(of, twl4030_power_of_match); | ||
793 | #endif /* CONFIG_OF */ | ||
794 | |||
556 | static int twl4030_power_probe(struct platform_device *pdev) | 795 | static int twl4030_power_probe(struct platform_device *pdev) |
557 | { | 796 | { |
558 | struct twl4030_power_data *pdata = dev_get_platdata(&pdev->dev); | 797 | const struct twl4030_power_data *pdata = dev_get_platdata(&pdev->dev); |
559 | struct device_node *node = pdev->dev.of_node; | 798 | struct device_node *node = pdev->dev.of_node; |
799 | const struct of_device_id *match; | ||
560 | int err = 0; | 800 | int err = 0; |
561 | int err2 = 0; | 801 | int err2 = 0; |
562 | u8 val; | 802 | u8 val; |
@@ -577,8 +817,12 @@ static int twl4030_power_probe(struct platform_device *pdev) | |||
577 | return err; | 817 | return err; |
578 | } | 818 | } |
579 | 819 | ||
820 | match = of_match_device(of_match_ptr(twl4030_power_of_match), | ||
821 | &pdev->dev); | ||
822 | if (match && match->data) | ||
823 | pdata = match->data; | ||
824 | |||
580 | if (pdata) { | 825 | if (pdata) { |
581 | /* TODO: convert to device tree */ | ||
582 | err = twl4030_power_configure_scripts(pdata); | 826 | err = twl4030_power_configure_scripts(pdata); |
583 | if (err) { | 827 | if (err) { |
584 | pr_err("TWL4030 failed to load scripts\n"); | 828 | pr_err("TWL4030 failed to load scripts\n"); |
@@ -628,14 +872,6 @@ static int twl4030_power_remove(struct platform_device *pdev) | |||
628 | return 0; | 872 | return 0; |
629 | } | 873 | } |
630 | 874 | ||
631 | #ifdef CONFIG_OF | ||
632 | static const struct of_device_id twl4030_power_of_match[] = { | ||
633 | {.compatible = "ti,twl4030-power", }, | ||
634 | { }, | ||
635 | }; | ||
636 | MODULE_DEVICE_TABLE(of, twl4030_power_of_match); | ||
637 | #endif | ||
638 | |||
639 | static struct platform_driver twl4030_power_driver = { | 875 | static struct platform_driver twl4030_power_driver = { |
640 | .driver = { | 876 | .driver = { |
641 | .name = "twl4030_power", | 877 | .name = "twl4030_power", |