aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2012-07-03 15:57:48 -0400
committerArnd Bergmann <arnd@arndb.de>2012-07-03 15:57:48 -0400
commit0d1d76dd350a53c31e93442e573af8d14f89b2f0 (patch)
tree5e2f34564ae587d3e6aae5f0592a16a98853cd7b
parent839ab0c18fe4cf83dd99ca814f2b4cf822cd99be (diff)
parentbb0adf6ca6c78758c12b054fe3f25023033072ab (diff)
Merge tag 'omap-devel-driver-for-v3.6' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap into next/pm
From Tony Lindgren <tony@atomide.com>: Here are omap driver changes for v3.6 that were agreed to be merged via the omap tree. These changes convert omap HDQ1W driver to use runtime PM, and finally move omap SmartReflex driver from arch/arm to live under drivers. * tag 'omap-devel-driver-for-v3.6' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap: ARM: OMAP2+: do not allow SmartReflex to be built as a module ARM: OMAP2: Use hwmod to initialize mmc for 2420 W1: OMAP HDQ1W: use runtime PM ARM: OMAP2+: HDQ1W: use omap_device W1: OMAP HDQ1W: use 32-bit register accesses W1: OMAP HDQ1W: allow driver to be built on all OMAP2+ ARM: OMAP: SmartReflex: Move smartreflex driver to drivers/ ARM: OMAP2+: SmartReflex: add POWER_AVS Kconfig options ARM: OMAP2+: SmartReflex: Create per-opp debugfs node for errminlimit ARM: OMAP2+: SmartReflex: Use per-OPP data structure ARM: OMAP2+: Voltage: Move the omap_volt_data structure to plat ARM: OMAP2+: SmartReflex: introduce a busy loop condition test macro ARM: OMAP3: hwmod: rename the smartreflex entries ARM: OMAP2+: smartreflex: Use the names from hwmod data instead of voltage domains. ARM: OMAP3+: SmartReflex: class drivers should use struct omap_sr * ARM: OMAP2+: SmartReflex: move the smartreflex header to include/linux/power Signed-off-by: Arnd Bergmann <arnd@arndb.de>
-rw-r--r--arch/arm/mach-omap2/Makefile5
-rw-r--r--arch/arm/mach-omap2/devices.c108
-rw-r--r--arch/arm/mach-omap2/hdq1w.c26
-rw-r--r--arch/arm/mach-omap2/msdi.c73
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_3xxx_data.c12
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_44xx_data.c3
-rw-r--r--arch/arm/mach-omap2/pm.h2
-rw-r--r--arch/arm/mach-omap2/smartreflex-class3.c29
-rw-r--r--arch/arm/mach-omap2/sr_device.c39
-rw-r--r--arch/arm/mach-omap2/voltage.h21
-rw-r--r--arch/arm/plat-omap/Kconfig31
-rw-r--r--arch/arm/plat-omap/include/plat/voltage.h21
-rw-r--r--drivers/power/Kconfig2
-rw-r--r--drivers/power/Makefile1
-rw-r--r--drivers/power/avs/Kconfig12
-rw-r--r--drivers/power/avs/Makefile1
-rw-r--r--drivers/power/avs/smartreflex.c (renamed from arch/arm/mach-omap2/smartreflex.c)161
-rw-r--r--drivers/w1/masters/Kconfig2
-rw-r--r--drivers/w1/masters/omap_hdq.c86
-rw-r--r--include/linux/power/smartreflex.h (renamed from arch/arm/mach-omap2/smartreflex.h)74
20 files changed, 352 insertions, 357 deletions
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index fa742f3c2629..f74e975027b6 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -70,8 +70,9 @@ obj-$(CONFIG_ARCH_OMAP3) += cpuidle34xx.o
70obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o omap-mpuss-lowpower.o 70obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o omap-mpuss-lowpower.o
71obj-$(CONFIG_ARCH_OMAP4) += cpuidle44xx.o 71obj-$(CONFIG_ARCH_OMAP4) += cpuidle44xx.o
72obj-$(CONFIG_PM_DEBUG) += pm-debug.o 72obj-$(CONFIG_PM_DEBUG) += pm-debug.o
73obj-$(CONFIG_OMAP_SMARTREFLEX) += sr_device.o smartreflex.o 73
74obj-$(CONFIG_OMAP_SMARTREFLEX_CLASS3) += smartreflex-class3.o 74obj-$(CONFIG_POWER_AVS_OMAP) += sr_device.o
75obj-$(CONFIG_POWER_AVS_OMAP_CLASS3) += smartreflex-class3.o
75 76
76AFLAGS_sleep24xx.o :=-Wa,-march=armv6 77AFLAGS_sleep24xx.o :=-Wa,-march=armv6
77AFLAGS_sleep34xx.o :=-Wa,-march=armv7-a$(plus_sec) 78AFLAGS_sleep34xx.o :=-Wa,-march=armv7-a$(plus_sec)
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index 7b4b9327e543..91ef6699df5e 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -27,7 +27,6 @@
27 27
28#include "iomap.h" 28#include "iomap.h"
29#include <plat/board.h> 29#include <plat/board.h>
30#include <plat/mmc.h>
31#include <plat/dma.h> 30#include <plat/dma.h>
32#include <plat/omap_hwmod.h> 31#include <plat/omap_hwmod.h>
33#include <plat/omap_device.h> 32#include <plat/omap_device.h>
@@ -603,112 +602,6 @@ static inline void omap_init_aes(void) { }
603 602
604/*-------------------------------------------------------------------------*/ 603/*-------------------------------------------------------------------------*/
605 604
606#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
607
608static inline void omap242x_mmc_mux(struct omap_mmc_platform_data
609 *mmc_controller)
610{
611 if ((mmc_controller->slots[0].switch_pin > 0) && \
612 (mmc_controller->slots[0].switch_pin < OMAP_MAX_GPIO_LINES))
613 omap_mux_init_gpio(mmc_controller->slots[0].switch_pin,
614 OMAP_PIN_INPUT_PULLUP);
615 if ((mmc_controller->slots[0].gpio_wp > 0) && \
616 (mmc_controller->slots[0].gpio_wp < OMAP_MAX_GPIO_LINES))
617 omap_mux_init_gpio(mmc_controller->slots[0].gpio_wp,
618 OMAP_PIN_INPUT_PULLUP);
619
620 omap_mux_init_signal("sdmmc_cmd", 0);
621 omap_mux_init_signal("sdmmc_clki", 0);
622 omap_mux_init_signal("sdmmc_clko", 0);
623 omap_mux_init_signal("sdmmc_dat0", 0);
624 omap_mux_init_signal("sdmmc_dat_dir0", 0);
625 omap_mux_init_signal("sdmmc_cmd_dir", 0);
626 if (mmc_controller->slots[0].caps & MMC_CAP_4_BIT_DATA) {
627 omap_mux_init_signal("sdmmc_dat1", 0);
628 omap_mux_init_signal("sdmmc_dat2", 0);
629 omap_mux_init_signal("sdmmc_dat3", 0);
630 omap_mux_init_signal("sdmmc_dat_dir1", 0);
631 omap_mux_init_signal("sdmmc_dat_dir2", 0);
632 omap_mux_init_signal("sdmmc_dat_dir3", 0);
633 }
634
635 /*
636 * Use internal loop-back in MMC/SDIO Module Input Clock
637 * selection
638 */
639 if (mmc_controller->slots[0].internal_clock) {
640 u32 v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
641 v |= (1 << 24);
642 omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0);
643 }
644}
645
646void __init omap242x_init_mmc(struct omap_mmc_platform_data **mmc_data)
647{
648 struct platform_device *pdev;
649 struct omap_hwmod *oh;
650 int id = 0;
651 char *oh_name = "msdi1";
652 char *dev_name = "mmci-omap";
653
654 if (!mmc_data[0]) {
655 pr_err("%s fails: Incomplete platform data\n", __func__);
656 return;
657 }
658
659 omap242x_mmc_mux(mmc_data[0]);
660
661 oh = omap_hwmod_lookup(oh_name);
662 if (!oh) {
663 pr_err("Could not look up %s\n", oh_name);
664 return;
665 }
666 pdev = omap_device_build(dev_name, id, oh, mmc_data[0],
667 sizeof(struct omap_mmc_platform_data), NULL, 0, 0);
668 if (IS_ERR(pdev))
669 WARN(1, "Can'd build omap_device for %s:%s.\n",
670 dev_name, oh->name);
671}
672
673#endif
674
675/*-------------------------------------------------------------------------*/
676
677#if defined(CONFIG_HDQ_MASTER_OMAP) || defined(CONFIG_HDQ_MASTER_OMAP_MODULE)
678#define OMAP_HDQ_BASE 0x480B2000
679static struct resource omap_hdq_resources[] = {
680 {
681 .start = OMAP_HDQ_BASE,
682 .end = OMAP_HDQ_BASE + 0x1C,
683 .flags = IORESOURCE_MEM,
684 },
685 {
686 .start = INT_24XX_HDQ_IRQ,
687 .flags = IORESOURCE_IRQ,
688 },
689};
690static struct platform_device omap_hdq_dev = {
691 .name = "omap_hdq",
692 .id = 0,
693 .dev = {
694 .platform_data = NULL,
695 },
696 .num_resources = ARRAY_SIZE(omap_hdq_resources),
697 .resource = omap_hdq_resources,
698};
699static inline void omap_hdq_init(void)
700{
701 if (cpu_is_omap2420())
702 return;
703
704 platform_device_register(&omap_hdq_dev);
705}
706#else
707static inline void omap_hdq_init(void) {}
708#endif
709
710/*---------------------------------------------------------------------------*/
711
712#if defined(CONFIG_VIDEO_OMAP2_VOUT) || \ 605#if defined(CONFIG_VIDEO_OMAP2_VOUT) || \
713 defined(CONFIG_VIDEO_OMAP2_VOUT_MODULE) 606 defined(CONFIG_VIDEO_OMAP2_VOUT_MODULE)
714#if defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE) 607#if defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE)
@@ -753,7 +646,6 @@ static int __init omap2_init_devices(void)
753 omap_init_mcspi(); 646 omap_init_mcspi();
754 } 647 }
755 omap_init_pmu(); 648 omap_init_pmu();
756 omap_hdq_init();
757 omap_init_sti(); 649 omap_init_sti();
758 omap_init_sham(); 650 omap_init_sham();
759 omap_init_aes(); 651 omap_init_aes();
diff --git a/arch/arm/mach-omap2/hdq1w.c b/arch/arm/mach-omap2/hdq1w.c
index 297ebe03f09c..cdd6dda03828 100644
--- a/arch/arm/mach-omap2/hdq1w.c
+++ b/arch/arm/mach-omap2/hdq1w.c
@@ -22,7 +22,13 @@
22 * 02110-1301 USA 22 * 02110-1301 USA
23 */ 23 */
24 24
25#include <linux/kernel.h>
26#include <linux/init.h>
27#include <linux/err.h>
28#include <linux/platform_device.h>
29
25#include <plat/omap_hwmod.h> 30#include <plat/omap_hwmod.h>
31#include <plat/omap_device.h>
26#include <plat/hdq1w.h> 32#include <plat/hdq1w.h>
27 33
28#include "common.h" 34#include "common.h"
@@ -70,3 +76,23 @@ int omap_hdq1w_reset(struct omap_hwmod *oh)
70 76
71 return 0; 77 return 0;
72} 78}
79
80static int __init omap_init_hdq(void)
81{
82 int id = -1;
83 struct platform_device *pdev;
84 struct omap_hwmod *oh;
85 char *oh_name = "hdq1w";
86 char *devname = "omap_hdq";
87
88 oh = omap_hwmod_lookup(oh_name);
89 if (!oh)
90 return 0;
91
92 pdev = omap_device_build(devname, id, oh, NULL, 0, NULL, 0, 0);
93 WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s.\n",
94 devname, oh->name);
95
96 return 0;
97}
98arch_initcall(omap_init_hdq);
diff --git a/arch/arm/mach-omap2/msdi.c b/arch/arm/mach-omap2/msdi.c
index ef2a6924731a..fb5bc6cf3773 100644
--- a/arch/arm/mach-omap2/msdi.c
+++ b/arch/arm/mach-omap2/msdi.c
@@ -22,11 +22,15 @@
22 */ 22 */
23 23
24#include <linux/kernel.h> 24#include <linux/kernel.h>
25#include <linux/err.h>
25 26
26#include <plat/omap_hwmod.h> 27#include <plat/omap_hwmod.h>
28#include <plat/omap_device.h>
27#include <plat/mmc.h> 29#include <plat/mmc.h>
28 30
29#include "common.h" 31#include "common.h"
32#include "control.h"
33#include "mux.h"
30 34
31/* 35/*
32 * MSDI_CON_OFFSET: offset in bytes of the MSDI IP block's CON register 36 * MSDI_CON_OFFSET: offset in bytes of the MSDI IP block's CON register
@@ -86,3 +90,72 @@ int omap_msdi_reset(struct omap_hwmod *oh)
86 90
87 return 0; 91 return 0;
88} 92}
93
94#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
95
96static inline void omap242x_mmc_mux(struct omap_mmc_platform_data
97 *mmc_controller)
98{
99 if ((mmc_controller->slots[0].switch_pin > 0) && \
100 (mmc_controller->slots[0].switch_pin < OMAP_MAX_GPIO_LINES))
101 omap_mux_init_gpio(mmc_controller->slots[0].switch_pin,
102 OMAP_PIN_INPUT_PULLUP);
103 if ((mmc_controller->slots[0].gpio_wp > 0) && \
104 (mmc_controller->slots[0].gpio_wp < OMAP_MAX_GPIO_LINES))
105 omap_mux_init_gpio(mmc_controller->slots[0].gpio_wp,
106 OMAP_PIN_INPUT_PULLUP);
107
108 omap_mux_init_signal("sdmmc_cmd", 0);
109 omap_mux_init_signal("sdmmc_clki", 0);
110 omap_mux_init_signal("sdmmc_clko", 0);
111 omap_mux_init_signal("sdmmc_dat0", 0);
112 omap_mux_init_signal("sdmmc_dat_dir0", 0);
113 omap_mux_init_signal("sdmmc_cmd_dir", 0);
114 if (mmc_controller->slots[0].caps & MMC_CAP_4_BIT_DATA) {
115 omap_mux_init_signal("sdmmc_dat1", 0);
116 omap_mux_init_signal("sdmmc_dat2", 0);
117 omap_mux_init_signal("sdmmc_dat3", 0);
118 omap_mux_init_signal("sdmmc_dat_dir1", 0);
119 omap_mux_init_signal("sdmmc_dat_dir2", 0);
120 omap_mux_init_signal("sdmmc_dat_dir3", 0);
121 }
122
123 /*
124 * Use internal loop-back in MMC/SDIO Module Input Clock
125 * selection
126 */
127 if (mmc_controller->slots[0].internal_clock) {
128 u32 v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
129 v |= (1 << 24);
130 omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0);
131 }
132}
133
134void __init omap242x_init_mmc(struct omap_mmc_platform_data **mmc_data)
135{
136 struct platform_device *pdev;
137 struct omap_hwmod *oh;
138 int id = 0;
139 char *oh_name = "msdi1";
140 char *dev_name = "mmci-omap";
141
142 if (!mmc_data[0]) {
143 pr_err("%s fails: Incomplete platform data\n", __func__);
144 return;
145 }
146
147 omap242x_mmc_mux(mmc_data[0]);
148
149 oh = omap_hwmod_lookup(oh_name);
150 if (!oh) {
151 pr_err("Could not look up %s\n", oh_name);
152 return;
153 }
154 pdev = omap_device_build(dev_name, id, oh, mmc_data[0],
155 sizeof(struct omap_mmc_platform_data), NULL, 0, 0);
156 if (IS_ERR(pdev))
157 WARN(1, "Can'd build omap_device for %s:%s.\n",
158 dev_name, oh->name);
159}
160
161#endif
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index b26d3c9bca16..ab1f40125ffd 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -14,6 +14,8 @@
14 * 14 *
15 * XXX these should be marked initdata for multi-OMAP kernels 15 * XXX these should be marked initdata for multi-OMAP kernels
16 */ 16 */
17#include <linux/power/smartreflex.h>
18
17#include <plat/omap_hwmod.h> 19#include <plat/omap_hwmod.h>
18#include <mach/irqs.h> 20#include <mach/irqs.h>
19#include <plat/cpu.h> 21#include <plat/cpu.h>
@@ -29,8 +31,6 @@
29#include <plat/dmtimer.h> 31#include <plat/dmtimer.h>
30 32
31#include "omap_hwmod_common_data.h" 33#include "omap_hwmod_common_data.h"
32
33#include "smartreflex.h"
34#include "prm-regbits-34xx.h" 34#include "prm-regbits-34xx.h"
35#include "cm-regbits-34xx.h" 35#include "cm-regbits-34xx.h"
36#include "wd_timer.h" 36#include "wd_timer.h"
@@ -1325,7 +1325,7 @@ static struct omap_hwmod_irq_info omap3_smartreflex_mpu_irqs[] = {
1325}; 1325};
1326 1326
1327static struct omap_hwmod omap34xx_sr1_hwmod = { 1327static struct omap_hwmod omap34xx_sr1_hwmod = {
1328 .name = "sr1", 1328 .name = "smartreflex_mpu_iva",
1329 .class = &omap34xx_smartreflex_hwmod_class, 1329 .class = &omap34xx_smartreflex_hwmod_class,
1330 .main_clk = "sr1_fck", 1330 .main_clk = "sr1_fck",
1331 .prcm = { 1331 .prcm = {
@@ -1343,7 +1343,7 @@ static struct omap_hwmod omap34xx_sr1_hwmod = {
1343}; 1343};
1344 1344
1345static struct omap_hwmod omap36xx_sr1_hwmod = { 1345static struct omap_hwmod omap36xx_sr1_hwmod = {
1346 .name = "sr1", 1346 .name = "smartreflex_mpu_iva",
1347 .class = &omap36xx_smartreflex_hwmod_class, 1347 .class = &omap36xx_smartreflex_hwmod_class,
1348 .main_clk = "sr1_fck", 1348 .main_clk = "sr1_fck",
1349 .prcm = { 1349 .prcm = {
@@ -1370,7 +1370,7 @@ static struct omap_hwmod_irq_info omap3_smartreflex_core_irqs[] = {
1370}; 1370};
1371 1371
1372static struct omap_hwmod omap34xx_sr2_hwmod = { 1372static struct omap_hwmod omap34xx_sr2_hwmod = {
1373 .name = "sr2", 1373 .name = "smartreflex_core",
1374 .class = &omap34xx_smartreflex_hwmod_class, 1374 .class = &omap34xx_smartreflex_hwmod_class,
1375 .main_clk = "sr2_fck", 1375 .main_clk = "sr2_fck",
1376 .prcm = { 1376 .prcm = {
@@ -1388,7 +1388,7 @@ static struct omap_hwmod omap34xx_sr2_hwmod = {
1388}; 1388};
1389 1389
1390static struct omap_hwmod omap36xx_sr2_hwmod = { 1390static struct omap_hwmod omap36xx_sr2_hwmod = {
1391 .name = "sr2", 1391 .name = "smartreflex_core",
1392 .class = &omap36xx_smartreflex_hwmod_class, 1392 .class = &omap36xx_smartreflex_hwmod_class,
1393 .main_clk = "sr2_fck", 1393 .main_clk = "sr2_fck",
1394 .prcm = { 1394 .prcm = {
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index f30e861ce6d9..6b564c9c2cea 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -19,6 +19,7 @@
19 */ 19 */
20 20
21#include <linux/io.h> 21#include <linux/io.h>
22#include <linux/power/smartreflex.h>
22 23
23#include <plat/omap_hwmod.h> 24#include <plat/omap_hwmod.h>
24#include <plat/cpu.h> 25#include <plat/cpu.h>
@@ -32,8 +33,6 @@
32#include <plat/common.h> 33#include <plat/common.h>
33 34
34#include "omap_hwmod_common_data.h" 35#include "omap_hwmod_common_data.h"
35
36#include "smartreflex.h"
37#include "cm1_44xx.h" 36#include "cm1_44xx.h"
38#include "cm2_44xx.h" 37#include "cm2_44xx.h"
39#include "prm44xx.h" 38#include "prm44xx.h"
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index 78564895e914..9fac67d6c985 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -88,7 +88,7 @@ extern void enable_omap3630_toggle_l2_on_restore(void);
88static inline void enable_omap3630_toggle_l2_on_restore(void) { } 88static inline void enable_omap3630_toggle_l2_on_restore(void) { }
89#endif /* defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) */ 89#endif /* defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) */
90 90
91#ifdef CONFIG_OMAP_SMARTREFLEX 91#ifdef CONFIG_POWER_AVS_OMAP
92extern int omap_devinit_smartreflex(void); 92extern int omap_devinit_smartreflex(void);
93extern void omap_enable_smartreflex_on_init(void); 93extern void omap_enable_smartreflex_on_init(void);
94#else 94#else
diff --git a/arch/arm/mach-omap2/smartreflex-class3.c b/arch/arm/mach-omap2/smartreflex-class3.c
index 955566eefac4..1da8f03c479e 100644
--- a/arch/arm/mach-omap2/smartreflex-class3.c
+++ b/arch/arm/mach-omap2/smartreflex-class3.c
@@ -11,36 +11,37 @@
11 * published by the Free Software Foundation. 11 * published by the Free Software Foundation.
12 */ 12 */
13 13
14#include "smartreflex.h" 14#include <linux/power/smartreflex.h>
15#include "voltage.h"
15 16
16static int sr_class3_enable(struct voltagedomain *voltdm) 17static int sr_class3_enable(struct omap_sr *sr)
17{ 18{
18 unsigned long volt = voltdm_get_voltage(voltdm); 19 unsigned long volt = voltdm_get_voltage(sr->voltdm);
19 20
20 if (!volt) { 21 if (!volt) {
21 pr_warning("%s: Curr voltage unknown. Cannot enable sr_%s\n", 22 pr_warning("%s: Curr voltage unknown. Cannot enable %s\n",
22 __func__, voltdm->name); 23 __func__, sr->name);
23 return -ENODATA; 24 return -ENODATA;
24 } 25 }
25 26
26 omap_vp_enable(voltdm); 27 omap_vp_enable(sr->voltdm);
27 return sr_enable(voltdm, volt); 28 return sr_enable(sr->voltdm, volt);
28} 29}
29 30
30static int sr_class3_disable(struct voltagedomain *voltdm, int is_volt_reset) 31static int sr_class3_disable(struct omap_sr *sr, int is_volt_reset)
31{ 32{
32 sr_disable_errgen(voltdm); 33 sr_disable_errgen(sr->voltdm);
33 omap_vp_disable(voltdm); 34 omap_vp_disable(sr->voltdm);
34 sr_disable(voltdm); 35 sr_disable(sr->voltdm);
35 if (is_volt_reset) 36 if (is_volt_reset)
36 voltdm_reset(voltdm); 37 voltdm_reset(sr->voltdm);
37 38
38 return 0; 39 return 0;
39} 40}
40 41
41static int sr_class3_configure(struct voltagedomain *voltdm) 42static int sr_class3_configure(struct omap_sr *sr)
42{ 43{
43 return sr_configure_errgen(voltdm); 44 return sr_configure_errgen(sr->voltdm);
44} 45}
45 46
46/* SR class3 structure */ 47/* SR class3 structure */
diff --git a/arch/arm/mach-omap2/sr_device.c b/arch/arm/mach-omap2/sr_device.c
index a503e1e8358c..e107e3915a8a 100644
--- a/arch/arm/mach-omap2/sr_device.c
+++ b/arch/arm/mach-omap2/sr_device.c
@@ -17,6 +17,7 @@
17 * it under the terms of the GNU General Public License version 2 as 17 * it under the terms of the GNU General Public License version 2 as
18 * published by the Free Software Foundation. 18 * published by the Free Software Foundation.
19 */ 19 */
20#include <linux/power/smartreflex.h>
20 21
21#include <linux/err.h> 22#include <linux/err.h>
22#include <linux/slab.h> 23#include <linux/slab.h>
@@ -24,7 +25,6 @@
24 25
25#include <plat/omap_device.h> 26#include <plat/omap_device.h>
26 27
27#include "smartreflex.h"
28#include "voltage.h" 28#include "voltage.h"
29#include "control.h" 29#include "control.h"
30#include "pm.h" 30#include "pm.h"
@@ -36,7 +36,10 @@ static void __init sr_set_nvalues(struct omap_volt_data *volt_data,
36 struct omap_sr_data *sr_data) 36 struct omap_sr_data *sr_data)
37{ 37{
38 struct omap_sr_nvalue_table *nvalue_table; 38 struct omap_sr_nvalue_table *nvalue_table;
39 int i, count = 0; 39 int i, j, count = 0;
40
41 sr_data->nvalue_count = 0;
42 sr_data->nvalue_table = NULL;
40 43
41 while (volt_data[count].volt_nominal) 44 while (volt_data[count].volt_nominal)
42 count++; 45 count++;
@@ -44,8 +47,14 @@ static void __init sr_set_nvalues(struct omap_volt_data *volt_data,
44 nvalue_table = kzalloc(sizeof(struct omap_sr_nvalue_table)*count, 47 nvalue_table = kzalloc(sizeof(struct omap_sr_nvalue_table)*count,
45 GFP_KERNEL); 48 GFP_KERNEL);
46 49
47 for (i = 0; i < count; i++) { 50 if (!nvalue_table) {
51 pr_err("OMAP: SmartReflex: cannot allocate memory for n-value table\n");
52 return;
53 }
54
55 for (i = 0, j = 0; i < count; i++) {
48 u32 v; 56 u32 v;
57
49 /* 58 /*
50 * In OMAP4 the efuse registers are 24 bit aligned. 59 * In OMAP4 the efuse registers are 24 bit aligned.
51 * A __raw_readl will fail for non-32 bit aligned address 60 * A __raw_readl will fail for non-32 bit aligned address
@@ -58,15 +67,30 @@ static void __init sr_set_nvalues(struct omap_volt_data *volt_data,
58 omap_ctrl_readb(offset + 1) << 8 | 67 omap_ctrl_readb(offset + 1) << 8 |
59 omap_ctrl_readb(offset + 2) << 16; 68 omap_ctrl_readb(offset + 2) << 16;
60 } else { 69 } else {
61 v = omap_ctrl_readl(volt_data[i].sr_efuse_offs); 70 v = omap_ctrl_readl(volt_data[i].sr_efuse_offs);
62 } 71 }
63 72
64 nvalue_table[i].efuse_offs = volt_data[i].sr_efuse_offs; 73 /*
65 nvalue_table[i].nvalue = v; 74 * Many OMAP SoCs don't have the eFuse values set.
75 * For example, pretty much all OMAP3xxx before
76 * ES3.something.
77 *
78 * XXX There needs to be some way for board files or
79 * userspace to add these in.
80 */
81 if (v == 0)
82 continue;
83
84 nvalue_table[j].nvalue = v;
85 nvalue_table[j].efuse_offs = volt_data[i].sr_efuse_offs;
86 nvalue_table[j].errminlimit = volt_data[i].sr_errminlimit;
87 nvalue_table[j].volt_nominal = volt_data[i].volt_nominal;
88
89 j++;
66 } 90 }
67 91
68 sr_data->nvalue_table = nvalue_table; 92 sr_data->nvalue_table = nvalue_table;
69 sr_data->nvalue_count = count; 93 sr_data->nvalue_count = j;
70} 94}
71 95
72static int __init sr_dev_init(struct omap_hwmod *oh, void *user) 96static int __init sr_dev_init(struct omap_hwmod *oh, void *user)
@@ -93,6 +117,7 @@ static int __init sr_dev_init(struct omap_hwmod *oh, void *user)
93 goto exit; 117 goto exit;
94 } 118 }
95 119
120 sr_data->name = oh->name;
96 sr_data->ip_type = oh->class->rev; 121 sr_data->ip_type = oh->class->rev;
97 sr_data->senn_mod = 0x1; 122 sr_data->senn_mod = 0x1;
98 sr_data->senp_mod = 0x1; 123 sr_data->senp_mod = 0x1;
diff --git a/arch/arm/mach-omap2/voltage.h b/arch/arm/mach-omap2/voltage.h
index 16a1b092cf36..34ef504adafd 100644
--- a/arch/arm/mach-omap2/voltage.h
+++ b/arch/arm/mach-omap2/voltage.h
@@ -16,6 +16,8 @@
16 16
17#include <linux/err.h> 17#include <linux/err.h>
18 18
19#include <plat/voltage.h>
20
19#include "vc.h" 21#include "vc.h"
20#include "vp.h" 22#include "vp.h"
21 23
@@ -91,25 +93,6 @@ struct voltagedomain {
91}; 93};
92 94
93/** 95/**
94 * struct omap_volt_data - Omap voltage specific data.
95 * @voltage_nominal: The possible voltage value in uV
96 * @sr_efuse_offs: The offset of the efuse register(from system
97 * control module base address) from where to read
98 * the n-target value for the smartreflex module.
99 * @sr_errminlimit: Error min limit value for smartreflex. This value
100 * differs at differnet opp and thus is linked
101 * with voltage.
102 * @vp_errorgain: Error gain value for the voltage processor. This
103 * field also differs according to the voltage/opp.
104 */
105struct omap_volt_data {
106 u32 volt_nominal;
107 u32 sr_efuse_offs;
108 u8 sr_errminlimit;
109 u8 vp_errgain;
110};
111
112/**
113 * struct omap_voltdm_pmic - PMIC specific data required by voltage driver. 96 * struct omap_voltdm_pmic - PMIC specific data required by voltage driver.
114 * @slew_rate: PMIC slew rate (in uv/us) 97 * @slew_rate: PMIC slew rate (in uv/us)
115 * @step_size: PMIC voltage step size (in uv) 98 * @step_size: PMIC voltage step size (in uv)
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index ad95c7a5d009..816dec062f3c 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -45,31 +45,30 @@ config OMAP_DEBUG_LEDS
45 depends on OMAP_DEBUG_DEVICES 45 depends on OMAP_DEBUG_DEVICES
46 default y if LEDS_CLASS 46 default y if LEDS_CLASS
47 47
48config OMAP_SMARTREFLEX 48config POWER_AVS_OMAP
49 bool "SmartReflex support" 49 bool "AVS(Adaptive Voltage Scaling) support for OMAP IP versions 1&2"
50 depends on (ARCH_OMAP3 || ARCH_OMAP4) && PM 50 depends on POWER_AVS && (ARCH_OMAP3 || ARCH_OMAP4) && PM
51 help 51 help
52 Say Y if you want to enable SmartReflex. 52 Say Y to enable AVS(Adaptive Voltage Scaling)
53 53 support on OMAP containing the version 1 or
54 SmartReflex can perform continuous dynamic voltage 54 version 2 of the SmartReflex IP.
55 scaling around the nominal operating point voltage 55 V1 is the 65nm version used in OMAP3430.
56 according to silicon characteristics and operating 56 V2 is the update for the 45nm version of the IP used in OMAP3630
57 conditions. Enabling SmartReflex reduces power 57 and OMAP4430
58 consumption.
59 58
60 Please note, that by default SmartReflex is only 59 Please note, that by default SmartReflex is only
61 initialized. To enable the automatic voltage 60 initialized and not enabled. To enable the automatic voltage
62 compensation for vdd mpu and vdd core from user space, 61 compensation for vdd mpu and vdd core from user space,
63 user must write 1 to 62 user must write 1 to
64 /debug/voltage/vdd_<X>/smartreflex/autocomp, 63 /debug/smartreflex/sr_<X>/autocomp,
65 where X is mpu or core for OMAP3. 64 where X is mpu_iva or core for OMAP3.
66 Optionally autocompensation can be enabled in the kernel 65 Optionally autocompensation can be enabled in the kernel
67 by default during system init via the enable_on_init flag 66 by default during system init via the enable_on_init flag
68 which an be passed as platform data to the smartreflex driver. 67 which an be passed as platform data to the smartreflex driver.
69 68
70config OMAP_SMARTREFLEX_CLASS3 69config POWER_AVS_OMAP_CLASS3
71 bool "Class 3 mode of Smartreflex Implementation" 70 bool "Class 3 mode of Smartreflex Implementation"
72 depends on OMAP_SMARTREFLEX && TWL4030_CORE 71 depends on POWER_AVS_OMAP && TWL4030_CORE
73 help 72 help
74 Say Y to enable Class 3 implementation of Smartreflex 73 Say Y to enable Class 3 implementation of Smartreflex
75 74
diff --git a/arch/arm/plat-omap/include/plat/voltage.h b/arch/arm/plat-omap/include/plat/voltage.h
index 0a6a482ec014..5be4d5def427 100644
--- a/arch/arm/plat-omap/include/plat/voltage.h
+++ b/arch/arm/plat-omap/include/plat/voltage.h
@@ -11,10 +11,29 @@
11#ifndef __ARCH_ARM_OMAP_VOLTAGE_H 11#ifndef __ARCH_ARM_OMAP_VOLTAGE_H
12#define __ARCH_ARM_OMAP_VOLTAGE_H 12#define __ARCH_ARM_OMAP_VOLTAGE_H
13 13
14/**
15 * struct omap_volt_data - Omap voltage specific data.
16 * @voltage_nominal: The possible voltage value in uV
17 * @sr_efuse_offs: The offset of the efuse register(from system
18 * control module base address) from where to read
19 * the n-target value for the smartreflex module.
20 * @sr_errminlimit: Error min limit value for smartreflex. This value
21 * differs at differnet opp and thus is linked
22 * with voltage.
23 * @vp_errorgain: Error gain value for the voltage processor. This
24 * field also differs according to the voltage/opp.
25 */
26struct omap_volt_data {
27 u32 volt_nominal;
28 u32 sr_efuse_offs;
29 u8 sr_errminlimit;
30 u8 vp_errgain;
31};
14struct voltagedomain; 32struct voltagedomain;
15 33
16struct voltagedomain *voltdm_lookup(const char *name); 34struct voltagedomain *voltdm_lookup(const char *name);
17int voltdm_scale(struct voltagedomain *voltdm, unsigned long target_volt); 35int voltdm_scale(struct voltagedomain *voltdm, unsigned long target_volt);
18unsigned long voltdm_get_voltage(struct voltagedomain *voltdm); 36unsigned long voltdm_get_voltage(struct voltagedomain *voltdm);
19 37struct omap_volt_data *omap_voltage_get_voltdata(struct voltagedomain *voltdm,
38 unsigned long volt);
20#endif 39#endif
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index e3a3b4956f08..70b4a979a6ff 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -310,3 +310,5 @@ config AB8500_BATTERY_THERM_ON_BATCTRL
310 Say Y to enable battery temperature measurements using 310 Say Y to enable battery temperature measurements using
311 thermistor connected on BATCTRL ADC. 311 thermistor connected on BATCTRL ADC.
312endif # POWER_SUPPLY 312endif # POWER_SUPPLY
313
314source "drivers/power/avs/Kconfig"
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index b6b243416c0e..ee58afb1e71f 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -43,4 +43,5 @@ obj-$(CONFIG_CHARGER_GPIO) += gpio-charger.o
43obj-$(CONFIG_CHARGER_MANAGER) += charger-manager.o 43obj-$(CONFIG_CHARGER_MANAGER) += charger-manager.o
44obj-$(CONFIG_CHARGER_MAX8997) += max8997_charger.o 44obj-$(CONFIG_CHARGER_MAX8997) += max8997_charger.o
45obj-$(CONFIG_CHARGER_MAX8998) += max8998_charger.o 45obj-$(CONFIG_CHARGER_MAX8998) += max8998_charger.o
46obj-$(CONFIG_POWER_AVS) += avs/
46obj-$(CONFIG_CHARGER_SMB347) += smb347-charger.o 47obj-$(CONFIG_CHARGER_SMB347) += smb347-charger.o
diff --git a/drivers/power/avs/Kconfig b/drivers/power/avs/Kconfig
new file mode 100644
index 000000000000..2a1008b61121
--- /dev/null
+++ b/drivers/power/avs/Kconfig
@@ -0,0 +1,12 @@
1menuconfig POWER_AVS
2 bool "Adaptive Voltage Scaling class support"
3 help
4 AVS is a power management technique which finely controls the
5 operating voltage of a device in order to optimize (i.e. reduce)
6 its power consumption.
7 At a given operating point the voltage is adapted depending on
8 static factors (chip manufacturing process) and dynamic factors
9 (temperature depending performance).
10 AVS is also called SmartReflex on OMAP devices.
11
12 Say Y here to enable Adaptive Voltage Scaling class support.
diff --git a/drivers/power/avs/Makefile b/drivers/power/avs/Makefile
new file mode 100644
index 000000000000..0843386a6c19
--- /dev/null
+++ b/drivers/power/avs/Makefile
@@ -0,0 +1 @@
obj-$(CONFIG_POWER_AVS_OMAP) += smartreflex.o
diff --git a/arch/arm/mach-omap2/smartreflex.c b/drivers/power/avs/smartreflex.c
index 008fbd7b9352..44efc6e202af 100644
--- a/arch/arm/mach-omap2/smartreflex.c
+++ b/drivers/power/avs/smartreflex.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Author: Thara Gopinath <thara@ti.com> 4 * Author: Thara Gopinath <thara@ti.com>
5 * 5 *
6 * Copyright (C) 2010 Texas Instruments, Inc. 6 * Copyright (C) 2012 Texas Instruments, Inc.
7 * Thara Gopinath <thara@ti.com> 7 * Thara Gopinath <thara@ti.com>
8 * 8 *
9 * Copyright (C) 2008 Nokia Corporation 9 * Copyright (C) 2008 Nokia Corporation
@@ -25,39 +25,12 @@
25#include <linux/delay.h> 25#include <linux/delay.h>
26#include <linux/slab.h> 26#include <linux/slab.h>
27#include <linux/pm_runtime.h> 27#include <linux/pm_runtime.h>
28 28#include <linux/power/smartreflex.h>
29#include "common.h"
30
31#include "pm.h"
32#include "smartreflex.h"
33 29
34#define SMARTREFLEX_NAME_LEN 16 30#define SMARTREFLEX_NAME_LEN 16
35#define NVALUE_NAME_LEN 40 31#define NVALUE_NAME_LEN 40
36#define SR_DISABLE_TIMEOUT 200 32#define SR_DISABLE_TIMEOUT 200
37 33
38struct omap_sr {
39 struct list_head node;
40 struct platform_device *pdev;
41 struct omap_sr_nvalue_table *nvalue_table;
42 struct voltagedomain *voltdm;
43 struct dentry *dbg_dir;
44 unsigned int irq;
45 int srid;
46 int ip_type;
47 int nvalue_count;
48 bool autocomp_active;
49 u32 clk_length;
50 u32 err_weight;
51 u32 err_minlimit;
52 u32 err_maxlimit;
53 u32 accum_data;
54 u32 senn_avgweight;
55 u32 senp_avgweight;
56 u32 senp_mod;
57 u32 senn_mod;
58 void __iomem *base;
59};
60
61/* sr_list contains all the instances of smartreflex module */ 34/* sr_list contains all the instances of smartreflex module */
62static LIST_HEAD(sr_list); 35static LIST_HEAD(sr_list);
63 36
@@ -148,7 +121,7 @@ static irqreturn_t sr_interrupt(int irq, void *data)
148 } 121 }
149 122
150 if (sr_class->notify) 123 if (sr_class->notify)
151 sr_class->notify(sr_info->voltdm, status); 124 sr_class->notify(sr_info, status);
152 125
153 return IRQ_HANDLED; 126 return IRQ_HANDLED;
154} 127}
@@ -207,7 +180,7 @@ static void sr_set_regfields(struct omap_sr *sr)
207 sr->err_weight = OMAP3430_SR_ERRWEIGHT; 180 sr->err_weight = OMAP3430_SR_ERRWEIGHT;
208 sr->err_maxlimit = OMAP3430_SR_ERRMAXLIMIT; 181 sr->err_maxlimit = OMAP3430_SR_ERRMAXLIMIT;
209 sr->accum_data = OMAP3430_SR_ACCUMDATA; 182 sr->accum_data = OMAP3430_SR_ACCUMDATA;
210 if (!(strcmp(sr->voltdm->name, "mpu"))) { 183 if (!(strcmp(sr->name, "smartreflex_mpu_iva"))) {
211 sr->senn_avgweight = OMAP3430_SR1_SENNAVGWEIGHT; 184 sr->senn_avgweight = OMAP3430_SR1_SENNAVGWEIGHT;
212 sr->senp_avgweight = OMAP3430_SR1_SENPAVGWEIGHT; 185 sr->senp_avgweight = OMAP3430_SR1_SENPAVGWEIGHT;
213 } else { 186 } else {
@@ -226,7 +199,7 @@ static void sr_start_vddautocomp(struct omap_sr *sr)
226 return; 199 return;
227 } 200 }
228 201
229 if (!sr_class->enable(sr->voltdm)) 202 if (!sr_class->enable(sr))
230 sr->autocomp_active = true; 203 sr->autocomp_active = true;
231} 204}
232 205
@@ -240,7 +213,7 @@ static void sr_stop_vddautocomp(struct omap_sr *sr)
240 } 213 }
241 214
242 if (sr->autocomp_active) { 215 if (sr->autocomp_active) {
243 sr_class->disable(sr->voltdm, 1); 216 sr_class->disable(sr, 1);
244 sr->autocomp_active = false; 217 sr->autocomp_active = false;
245 } 218 }
246} 219}
@@ -258,19 +231,13 @@ static void sr_stop_vddautocomp(struct omap_sr *sr)
258 */ 231 */
259static int sr_late_init(struct omap_sr *sr_info) 232static int sr_late_init(struct omap_sr *sr_info)
260{ 233{
261 char *name;
262 struct omap_sr_data *pdata = sr_info->pdev->dev.platform_data; 234 struct omap_sr_data *pdata = sr_info->pdev->dev.platform_data;
263 struct resource *mem; 235 struct resource *mem;
264 int ret = 0; 236 int ret = 0;
265 237
266 if (sr_class->notify && sr_class->notify_flags && sr_info->irq) { 238 if (sr_class->notify && sr_class->notify_flags && sr_info->irq) {
267 name = kasprintf(GFP_KERNEL, "sr_%s", sr_info->voltdm->name);
268 if (name == NULL) {
269 ret = -ENOMEM;
270 goto error;
271 }
272 ret = request_irq(sr_info->irq, sr_interrupt, 239 ret = request_irq(sr_info->irq, sr_interrupt,
273 0, name, sr_info); 240 0, sr_info->name, sr_info);
274 if (ret) 241 if (ret)
275 goto error; 242 goto error;
276 disable_irq(sr_info->irq); 243 disable_irq(sr_info->irq);
@@ -289,7 +256,6 @@ error:
289 dev_err(&sr_info->pdev->dev, "%s: ERROR in registering" 256 dev_err(&sr_info->pdev->dev, "%s: ERROR in registering"
290 "interrupt handler. Smartreflex will" 257 "interrupt handler. Smartreflex will"
291 "not function as desired\n", __func__); 258 "not function as desired\n", __func__);
292 kfree(name);
293 kfree(sr_info); 259 kfree(sr_info);
294 260
295 return ret; 261 return ret;
@@ -320,9 +286,9 @@ static void sr_v1_disable(struct omap_sr *sr)
320 * Wait for SR to be disabled. 286 * Wait for SR to be disabled.
321 * wait until ERRCONFIG.MCUDISACKINTST = 1. Typical latency is 1us. 287 * wait until ERRCONFIG.MCUDISACKINTST = 1. Typical latency is 1us.
322 */ 288 */
323 omap_test_timeout((sr_read_reg(sr, ERRCONFIG_V1) & 289 sr_test_cond_timeout((sr_read_reg(sr, ERRCONFIG_V1) &
324 ERRCONFIG_MCUDISACKINTST), SR_DISABLE_TIMEOUT, 290 ERRCONFIG_MCUDISACKINTST), SR_DISABLE_TIMEOUT,
325 timeout); 291 timeout);
326 292
327 if (timeout >= SR_DISABLE_TIMEOUT) 293 if (timeout >= SR_DISABLE_TIMEOUT)
328 dev_warn(&sr->pdev->dev, "%s: Smartreflex disable timedout\n", 294 dev_warn(&sr->pdev->dev, "%s: Smartreflex disable timedout\n",
@@ -365,9 +331,9 @@ static void sr_v2_disable(struct omap_sr *sr)
365 * Wait for SR to be disabled. 331 * Wait for SR to be disabled.
366 * wait until IRQSTATUS.MCUDISACKINTST = 1. Typical latency is 1us. 332 * wait until IRQSTATUS.MCUDISACKINTST = 1. Typical latency is 1us.
367 */ 333 */
368 omap_test_timeout((sr_read_reg(sr, IRQSTATUS) & 334 sr_test_cond_timeout((sr_read_reg(sr, IRQSTATUS) &
369 IRQSTATUS_MCUDISABLEACKINT), SR_DISABLE_TIMEOUT, 335 IRQSTATUS_MCUDISABLEACKINT), SR_DISABLE_TIMEOUT,
370 timeout); 336 timeout);
371 337
372 if (timeout >= SR_DISABLE_TIMEOUT) 338 if (timeout >= SR_DISABLE_TIMEOUT)
373 dev_warn(&sr->pdev->dev, "%s: Smartreflex disable timedout\n", 339 dev_warn(&sr->pdev->dev, "%s: Smartreflex disable timedout\n",
@@ -378,22 +344,23 @@ static void sr_v2_disable(struct omap_sr *sr)
378 sr_write_reg(sr, IRQSTATUS, IRQSTATUS_MCUDISABLEACKINT); 344 sr_write_reg(sr, IRQSTATUS, IRQSTATUS_MCUDISABLEACKINT);
379} 345}
380 346
381static u32 sr_retrieve_nvalue(struct omap_sr *sr, u32 efuse_offs) 347static struct omap_sr_nvalue_table *sr_retrieve_nvalue_row(
348 struct omap_sr *sr, u32 efuse_offs)
382{ 349{
383 int i; 350 int i;
384 351
385 if (!sr->nvalue_table) { 352 if (!sr->nvalue_table) {
386 dev_warn(&sr->pdev->dev, "%s: Missing ntarget value table\n", 353 dev_warn(&sr->pdev->dev, "%s: Missing ntarget value table\n",
387 __func__); 354 __func__);
388 return 0; 355 return NULL;
389 } 356 }
390 357
391 for (i = 0; i < sr->nvalue_count; i++) { 358 for (i = 0; i < sr->nvalue_count; i++) {
392 if (sr->nvalue_table[i].efuse_offs == efuse_offs) 359 if (sr->nvalue_table[i].efuse_offs == efuse_offs)
393 return sr->nvalue_table[i].nvalue; 360 return &sr->nvalue_table[i];
394 } 361 }
395 362
396 return 0; 363 return NULL;
397} 364}
398 365
399/* Public Functions */ 366/* Public Functions */
@@ -419,8 +386,7 @@ int sr_configure_errgen(struct voltagedomain *voltdm)
419 struct omap_sr *sr = _sr_lookup(voltdm); 386 struct omap_sr *sr = _sr_lookup(voltdm);
420 387
421 if (IS_ERR(sr)) { 388 if (IS_ERR(sr)) {
422 pr_warning("%s: omap_sr struct for sr_%s not found\n", 389 pr_warning("%s: omap_sr struct for voltdm not found\n", __func__);
423 __func__, voltdm->name);
424 return PTR_ERR(sr); 390 return PTR_ERR(sr);
425 } 391 }
426 392
@@ -487,8 +453,7 @@ int sr_disable_errgen(struct voltagedomain *voltdm)
487 struct omap_sr *sr = _sr_lookup(voltdm); 453 struct omap_sr *sr = _sr_lookup(voltdm);
488 454
489 if (IS_ERR(sr)) { 455 if (IS_ERR(sr)) {
490 pr_warning("%s: omap_sr struct for sr_%s not found\n", 456 pr_warning("%s: omap_sr struct for voltdm not found\n", __func__);
491 __func__, voltdm->name);
492 return PTR_ERR(sr); 457 return PTR_ERR(sr);
493 } 458 }
494 459
@@ -538,8 +503,7 @@ int sr_configure_minmax(struct voltagedomain *voltdm)
538 struct omap_sr *sr = _sr_lookup(voltdm); 503 struct omap_sr *sr = _sr_lookup(voltdm);
539 504
540 if (IS_ERR(sr)) { 505 if (IS_ERR(sr)) {
541 pr_warning("%s: omap_sr struct for sr_%s not found\n", 506 pr_warning("%s: omap_sr struct for voltdm not found\n", __func__);
542 __func__, voltdm->name);
543 return PTR_ERR(sr); 507 return PTR_ERR(sr);
544 } 508 }
545 509
@@ -620,12 +584,11 @@ int sr_enable(struct voltagedomain *voltdm, unsigned long volt)
620{ 584{
621 struct omap_volt_data *volt_data; 585 struct omap_volt_data *volt_data;
622 struct omap_sr *sr = _sr_lookup(voltdm); 586 struct omap_sr *sr = _sr_lookup(voltdm);
623 u32 nvalue_reciprocal; 587 struct omap_sr_nvalue_table *nvalue_row;
624 int ret; 588 int ret;
625 589
626 if (IS_ERR(sr)) { 590 if (IS_ERR(sr)) {
627 pr_warning("%s: omap_sr struct for sr_%s not found\n", 591 pr_warning("%s: omap_sr struct for voltdm not found\n", __func__);
628 __func__, voltdm->name);
629 return PTR_ERR(sr); 592 return PTR_ERR(sr);
630 } 593 }
631 594
@@ -637,16 +600,16 @@ int sr_enable(struct voltagedomain *voltdm, unsigned long volt)
637 return PTR_ERR(volt_data); 600 return PTR_ERR(volt_data);
638 } 601 }
639 602
640 nvalue_reciprocal = sr_retrieve_nvalue(sr, volt_data->sr_efuse_offs); 603 nvalue_row = sr_retrieve_nvalue_row(sr, volt_data->sr_efuse_offs);
641 604
642 if (!nvalue_reciprocal) { 605 if (!nvalue_row) {
643 dev_warn(&sr->pdev->dev, "%s: NVALUE = 0 at voltage %ld\n", 606 dev_warn(&sr->pdev->dev, "%s: failure getting SR data for this voltage %ld\n",
644 __func__, volt); 607 __func__, volt);
645 return -ENODATA; 608 return -ENODATA;
646 } 609 }
647 610
648 /* errminlimit is opp dependent and hence linked to voltage */ 611 /* errminlimit is opp dependent and hence linked to voltage */
649 sr->err_minlimit = volt_data->sr_errminlimit; 612 sr->err_minlimit = nvalue_row->errminlimit;
650 613
651 pm_runtime_get_sync(&sr->pdev->dev); 614 pm_runtime_get_sync(&sr->pdev->dev);
652 615
@@ -655,11 +618,11 @@ int sr_enable(struct voltagedomain *voltdm, unsigned long volt)
655 return 0; 618 return 0;
656 619
657 /* Configure SR */ 620 /* Configure SR */
658 ret = sr_class->configure(voltdm); 621 ret = sr_class->configure(sr);
659 if (ret) 622 if (ret)
660 return ret; 623 return ret;
661 624
662 sr_write_reg(sr, NVALUERECIPROCAL, nvalue_reciprocal); 625 sr_write_reg(sr, NVALUERECIPROCAL, nvalue_row->nvalue);
663 626
664 /* SRCONFIG - enable SR */ 627 /* SRCONFIG - enable SR */
665 sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, SRCONFIG_SRENABLE); 628 sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, SRCONFIG_SRENABLE);
@@ -678,8 +641,7 @@ void sr_disable(struct voltagedomain *voltdm)
678 struct omap_sr *sr = _sr_lookup(voltdm); 641 struct omap_sr *sr = _sr_lookup(voltdm);
679 642
680 if (IS_ERR(sr)) { 643 if (IS_ERR(sr)) {
681 pr_warning("%s: omap_sr struct for sr_%s not found\n", 644 pr_warning("%s: omap_sr struct for voltdm not found\n", __func__);
682 __func__, voltdm->name);
683 return; 645 return;
684 } 646 }
685 647
@@ -759,8 +721,7 @@ void omap_sr_enable(struct voltagedomain *voltdm)
759 struct omap_sr *sr = _sr_lookup(voltdm); 721 struct omap_sr *sr = _sr_lookup(voltdm);
760 722
761 if (IS_ERR(sr)) { 723 if (IS_ERR(sr)) {
762 pr_warning("%s: omap_sr struct for sr_%s not found\n", 724 pr_warning("%s: omap_sr struct for voltdm not found\n", __func__);
763 __func__, voltdm->name);
764 return; 725 return;
765 } 726 }
766 727
@@ -773,7 +734,7 @@ void omap_sr_enable(struct voltagedomain *voltdm)
773 return; 734 return;
774 } 735 }
775 736
776 sr_class->enable(voltdm); 737 sr_class->enable(sr);
777} 738}
778 739
779/** 740/**
@@ -792,8 +753,7 @@ void omap_sr_disable(struct voltagedomain *voltdm)
792 struct omap_sr *sr = _sr_lookup(voltdm); 753 struct omap_sr *sr = _sr_lookup(voltdm);
793 754
794 if (IS_ERR(sr)) { 755 if (IS_ERR(sr)) {
795 pr_warning("%s: omap_sr struct for sr_%s not found\n", 756 pr_warning("%s: omap_sr struct for voltdm not found\n", __func__);
796 __func__, voltdm->name);
797 return; 757 return;
798 } 758 }
799 759
@@ -806,7 +766,7 @@ void omap_sr_disable(struct voltagedomain *voltdm)
806 return; 766 return;
807 } 767 }
808 768
809 sr_class->disable(voltdm, 0); 769 sr_class->disable(sr, 0);
810} 770}
811 771
812/** 772/**
@@ -825,8 +785,7 @@ void omap_sr_disable_reset_volt(struct voltagedomain *voltdm)
825 struct omap_sr *sr = _sr_lookup(voltdm); 785 struct omap_sr *sr = _sr_lookup(voltdm);
826 786
827 if (IS_ERR(sr)) { 787 if (IS_ERR(sr)) {
828 pr_warning("%s: omap_sr struct for sr_%s not found\n", 788 pr_warning("%s: omap_sr struct for voltdm not found\n", __func__);
829 __func__, voltdm->name);
830 return; 789 return;
831 } 790 }
832 791
@@ -839,7 +798,7 @@ void omap_sr_disable_reset_volt(struct voltagedomain *voltdm)
839 return; 798 return;
840 } 799 }
841 800
842 sr_class->disable(voltdm, 1); 801 sr_class->disable(sr, 1);
843} 802}
844 803
845/** 804/**
@@ -911,9 +870,7 @@ static int __init omap_sr_probe(struct platform_device *pdev)
911 struct omap_sr_data *pdata = pdev->dev.platform_data; 870 struct omap_sr_data *pdata = pdev->dev.platform_data;
912 struct resource *mem, *irq; 871 struct resource *mem, *irq;
913 struct dentry *nvalue_dir; 872 struct dentry *nvalue_dir;
914 struct omap_volt_data *volt_data;
915 int i, ret = 0; 873 int i, ret = 0;
916 char *name;
917 874
918 sr_info = kzalloc(sizeof(struct omap_sr), GFP_KERNEL); 875 sr_info = kzalloc(sizeof(struct omap_sr), GFP_KERNEL);
919 if (!sr_info) { 876 if (!sr_info) {
@@ -950,6 +907,14 @@ static int __init omap_sr_probe(struct platform_device *pdev)
950 pm_runtime_enable(&pdev->dev); 907 pm_runtime_enable(&pdev->dev);
951 pm_runtime_irq_safe(&pdev->dev); 908 pm_runtime_irq_safe(&pdev->dev);
952 909
910 sr_info->name = kasprintf(GFP_KERNEL, "%s", pdata->name);
911 if (!sr_info->name) {
912 dev_err(&pdev->dev, "%s: Unable to alloc SR instance name\n",
913 __func__);
914 ret = -ENOMEM;
915 goto err_release_region;
916 }
917
953 sr_info->pdev = pdev; 918 sr_info->pdev = pdev;
954 sr_info->srid = pdev->id; 919 sr_info->srid = pdev->id;
955 sr_info->voltdm = pdata->voltdm; 920 sr_info->voltdm = pdata->voltdm;
@@ -997,20 +962,12 @@ static int __init omap_sr_probe(struct platform_device *pdev)
997 } 962 }
998 } 963 }
999 964
1000 name = kasprintf(GFP_KERNEL, "sr_%s", sr_info->voltdm->name); 965 sr_info->dbg_dir = debugfs_create_dir(sr_info->name, sr_dbg_dir);
1001 if (!name) {
1002 dev_err(&pdev->dev, "%s: Unable to alloc debugfs name\n",
1003 __func__);
1004 ret = -ENOMEM;
1005 goto err_iounmap;
1006 }
1007 sr_info->dbg_dir = debugfs_create_dir(name, sr_dbg_dir);
1008 kfree(name);
1009 if (IS_ERR_OR_NULL(sr_info->dbg_dir)) { 966 if (IS_ERR_OR_NULL(sr_info->dbg_dir)) {
1010 dev_err(&pdev->dev, "%s: Unable to create debugfs directory\n", 967 dev_err(&pdev->dev, "%s: Unable to create debugfs directory\n",
1011 __func__); 968 __func__);
1012 ret = PTR_ERR(sr_info->dbg_dir); 969 ret = PTR_ERR(sr_info->dbg_dir);
1013 goto err_iounmap; 970 goto err_free_name;
1014 } 971 }
1015 972
1016 (void) debugfs_create_file("autocomp", S_IRUGO | S_IWUSR, 973 (void) debugfs_create_file("autocomp", S_IRUGO | S_IWUSR,
@@ -1019,8 +976,6 @@ static int __init omap_sr_probe(struct platform_device *pdev)
1019 &sr_info->err_weight); 976 &sr_info->err_weight);
1020 (void) debugfs_create_x32("errmaxlimit", S_IRUGO, sr_info->dbg_dir, 977 (void) debugfs_create_x32("errmaxlimit", S_IRUGO, sr_info->dbg_dir,
1021 &sr_info->err_maxlimit); 978 &sr_info->err_maxlimit);
1022 (void) debugfs_create_x32("errminlimit", S_IRUGO, sr_info->dbg_dir,
1023 &sr_info->err_minlimit);
1024 979
1025 nvalue_dir = debugfs_create_dir("nvalue", sr_info->dbg_dir); 980 nvalue_dir = debugfs_create_dir("nvalue", sr_info->dbg_dir);
1026 if (IS_ERR_OR_NULL(nvalue_dir)) { 981 if (IS_ERR_OR_NULL(nvalue_dir)) {
@@ -1030,12 +985,10 @@ static int __init omap_sr_probe(struct platform_device *pdev)
1030 goto err_debugfs; 985 goto err_debugfs;
1031 } 986 }
1032 987
1033 omap_voltage_get_volttable(sr_info->voltdm, &volt_data); 988 if (sr_info->nvalue_count == 0 || !sr_info->nvalue_table) {
1034 if (!volt_data) { 989 dev_warn(&pdev->dev, "%s: %s: No Voltage table for the corresponding vdd. Cannot create debugfs entries for n-values\n",
1035 dev_warn(&pdev->dev, "%s: No Voltage table for the" 990 __func__, sr_info->name);
1036 " corresponding vdd vdd_%s. Cannot create debugfs" 991
1037 "entries for n-values\n",
1038 __func__, sr_info->voltdm->name);
1039 ret = -ENODATA; 992 ret = -ENODATA;
1040 goto err_debugfs; 993 goto err_debugfs;
1041 } 994 }
@@ -1043,16 +996,23 @@ static int __init omap_sr_probe(struct platform_device *pdev)
1043 for (i = 0; i < sr_info->nvalue_count; i++) { 996 for (i = 0; i < sr_info->nvalue_count; i++) {
1044 char name[NVALUE_NAME_LEN + 1]; 997 char name[NVALUE_NAME_LEN + 1];
1045 998
1046 snprintf(name, sizeof(name), "volt_%d", 999 snprintf(name, sizeof(name), "volt_%lu",
1047 volt_data[i].volt_nominal); 1000 sr_info->nvalue_table[i].volt_nominal);
1048 (void) debugfs_create_x32(name, S_IRUGO | S_IWUSR, nvalue_dir, 1001 (void) debugfs_create_x32(name, S_IRUGO | S_IWUSR, nvalue_dir,
1049 &(sr_info->nvalue_table[i].nvalue)); 1002 &(sr_info->nvalue_table[i].nvalue));
1003 snprintf(name, sizeof(name), "errminlimit_%lu",
1004 sr_info->nvalue_table[i].volt_nominal);
1005 (void) debugfs_create_x32(name, S_IRUGO | S_IWUSR, nvalue_dir,
1006 &(sr_info->nvalue_table[i].errminlimit));
1007
1050 } 1008 }
1051 1009
1052 return ret; 1010 return ret;
1053 1011
1054err_debugfs: 1012err_debugfs:
1055 debugfs_remove_recursive(sr_info->dbg_dir); 1013 debugfs_remove_recursive(sr_info->dbg_dir);
1014err_free_name:
1015 kfree(sr_info->name);
1056err_iounmap: 1016err_iounmap:
1057 list_del(&sr_info->node); 1017 list_del(&sr_info->node);
1058 iounmap(sr_info->base); 1018 iounmap(sr_info->base);
@@ -1089,6 +1049,7 @@ static int __devexit omap_sr_remove(struct platform_device *pdev)
1089 1049
1090 list_del(&sr_info->node); 1050 list_del(&sr_info->node);
1091 iounmap(sr_info->base); 1051 iounmap(sr_info->base);
1052 kfree(sr_info->name);
1092 kfree(sr_info); 1053 kfree(sr_info);
1093 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1054 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1094 release_mem_region(mem->start, resource_size(mem)); 1055 release_mem_region(mem->start, resource_size(mem));
diff --git a/drivers/w1/masters/Kconfig b/drivers/w1/masters/Kconfig
index 979d6eed9a0f..5ceb1cd50195 100644
--- a/drivers/w1/masters/Kconfig
+++ b/drivers/w1/masters/Kconfig
@@ -60,7 +60,7 @@ config W1_MASTER_GPIO
60 60
61config HDQ_MASTER_OMAP 61config HDQ_MASTER_OMAP
62 tristate "OMAP HDQ driver" 62 tristate "OMAP HDQ driver"
63 depends on SOC_OMAP2430 || ARCH_OMAP3 63 depends on ARCH_OMAP2PLUS
64 help 64 help
65 Say Y here if you want support for the 1-wire or HDQ Interface 65 Say Y here if you want support for the 1-wire or HDQ Interface
66 on an OMAP processor. 66 on an OMAP processor.
diff --git a/drivers/w1/masters/omap_hdq.c b/drivers/w1/masters/omap_hdq.c
index 5ef385bfed18..291897c881be 100644
--- a/drivers/w1/masters/omap_hdq.c
+++ b/drivers/w1/masters/omap_hdq.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * drivers/w1/masters/omap_hdq.c 2 * drivers/w1/masters/omap_hdq.c
3 * 3 *
4 * Copyright (C) 2007 Texas Instruments, Inc. 4 * Copyright (C) 2007,2012 Texas Instruments, Inc.
5 * 5 *
6 * This file is licensed under the terms of the GNU General Public License 6 * This file is licensed under the terms of the GNU General Public License
7 * version 2. This program is licensed "as is" without any warranty of any 7 * version 2. This program is licensed "as is" without any warranty of any
@@ -14,9 +14,9 @@
14#include <linux/interrupt.h> 14#include <linux/interrupt.h>
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/err.h> 16#include <linux/err.h>
17#include <linux/clk.h>
18#include <linux/io.h> 17#include <linux/io.h>
19#include <linux/sched.h> 18#include <linux/sched.h>
19#include <linux/pm_runtime.h>
20 20
21#include <asm/irq.h> 21#include <asm/irq.h>
22#include <mach/hardware.h> 22#include <mach/hardware.h>
@@ -61,8 +61,6 @@ struct hdq_data {
61 /* lock status update */ 61 /* lock status update */
62 struct mutex hdq_mutex; 62 struct mutex hdq_mutex;
63 int hdq_usecount; 63 int hdq_usecount;
64 struct clk *hdq_ick;
65 struct clk *hdq_fck;
66 u8 hdq_irqstatus; 64 u8 hdq_irqstatus;
67 /* device lock */ 65 /* device lock */
68 spinlock_t hdq_spinlock; 66 spinlock_t hdq_spinlock;
@@ -102,20 +100,20 @@ static struct w1_bus_master omap_w1_master = {
102/* HDQ register I/O routines */ 100/* HDQ register I/O routines */
103static inline u8 hdq_reg_in(struct hdq_data *hdq_data, u32 offset) 101static inline u8 hdq_reg_in(struct hdq_data *hdq_data, u32 offset)
104{ 102{
105 return __raw_readb(hdq_data->hdq_base + offset); 103 return __raw_readl(hdq_data->hdq_base + offset);
106} 104}
107 105
108static inline void hdq_reg_out(struct hdq_data *hdq_data, u32 offset, u8 val) 106static inline void hdq_reg_out(struct hdq_data *hdq_data, u32 offset, u8 val)
109{ 107{
110 __raw_writeb(val, hdq_data->hdq_base + offset); 108 __raw_writel(val, hdq_data->hdq_base + offset);
111} 109}
112 110
113static inline u8 hdq_reg_merge(struct hdq_data *hdq_data, u32 offset, 111static inline u8 hdq_reg_merge(struct hdq_data *hdq_data, u32 offset,
114 u8 val, u8 mask) 112 u8 val, u8 mask)
115{ 113{
116 u8 new_val = (__raw_readb(hdq_data->hdq_base + offset) & ~mask) 114 u8 new_val = (__raw_readl(hdq_data->hdq_base + offset) & ~mask)
117 | (val & mask); 115 | (val & mask);
118 __raw_writeb(new_val, hdq_data->hdq_base + offset); 116 __raw_writel(new_val, hdq_data->hdq_base + offset);
119 117
120 return new_val; 118 return new_val;
121} 119}
@@ -419,17 +417,8 @@ static int omap_hdq_get(struct hdq_data *hdq_data)
419 hdq_data->hdq_usecount++; 417 hdq_data->hdq_usecount++;
420 try_module_get(THIS_MODULE); 418 try_module_get(THIS_MODULE);
421 if (1 == hdq_data->hdq_usecount) { 419 if (1 == hdq_data->hdq_usecount) {
422 if (clk_enable(hdq_data->hdq_ick)) { 420
423 dev_dbg(hdq_data->dev, "Can not enable ick\n"); 421 pm_runtime_get_sync(hdq_data->dev);
424 ret = -ENODEV;
425 goto clk_err;
426 }
427 if (clk_enable(hdq_data->hdq_fck)) {
428 dev_dbg(hdq_data->dev, "Can not enable fck\n");
429 clk_disable(hdq_data->hdq_ick);
430 ret = -ENODEV;
431 goto clk_err;
432 }
433 422
434 /* make sure HDQ is out of reset */ 423 /* make sure HDQ is out of reset */
435 if (!(hdq_reg_in(hdq_data, OMAP_HDQ_SYSSTATUS) & 424 if (!(hdq_reg_in(hdq_data, OMAP_HDQ_SYSSTATUS) &
@@ -450,9 +439,6 @@ static int omap_hdq_get(struct hdq_data *hdq_data)
450 } 439 }
451 } 440 }
452 441
453clk_err:
454 clk_put(hdq_data->hdq_ick);
455 clk_put(hdq_data->hdq_fck);
456out: 442out:
457 mutex_unlock(&hdq_data->hdq_mutex); 443 mutex_unlock(&hdq_data->hdq_mutex);
458rtn: 444rtn:
@@ -475,10 +461,8 @@ static int omap_hdq_put(struct hdq_data *hdq_data)
475 } else { 461 } else {
476 hdq_data->hdq_usecount--; 462 hdq_data->hdq_usecount--;
477 module_put(THIS_MODULE); 463 module_put(THIS_MODULE);
478 if (0 == hdq_data->hdq_usecount) { 464 if (0 == hdq_data->hdq_usecount)
479 clk_disable(hdq_data->hdq_ick); 465 pm_runtime_put_sync(hdq_data->dev);
480 clk_disable(hdq_data->hdq_fck);
481 }
482 } 466 }
483 mutex_unlock(&hdq_data->hdq_mutex); 467 mutex_unlock(&hdq_data->hdq_mutex);
484 468
@@ -591,35 +575,11 @@ static int __devinit omap_hdq_probe(struct platform_device *pdev)
591 goto err_ioremap; 575 goto err_ioremap;
592 } 576 }
593 577
594 /* get interface & functional clock objects */
595 hdq_data->hdq_ick = clk_get(&pdev->dev, "ick");
596 if (IS_ERR(hdq_data->hdq_ick)) {
597 dev_dbg(&pdev->dev, "Can't get HDQ ick clock object\n");
598 ret = PTR_ERR(hdq_data->hdq_ick);
599 goto err_ick;
600 }
601
602 hdq_data->hdq_fck = clk_get(&pdev->dev, "fck");
603 if (IS_ERR(hdq_data->hdq_fck)) {
604 dev_dbg(&pdev->dev, "Can't get HDQ fck clock object\n");
605 ret = PTR_ERR(hdq_data->hdq_fck);
606 goto err_fck;
607 }
608
609 hdq_data->hdq_usecount = 0; 578 hdq_data->hdq_usecount = 0;
610 mutex_init(&hdq_data->hdq_mutex); 579 mutex_init(&hdq_data->hdq_mutex);
611 580
612 if (clk_enable(hdq_data->hdq_ick)) { 581 pm_runtime_enable(&pdev->dev);
613 dev_dbg(&pdev->dev, "Can not enable ick\n"); 582 pm_runtime_get_sync(&pdev->dev);
614 ret = -ENODEV;
615 goto err_intfclk;
616 }
617
618 if (clk_enable(hdq_data->hdq_fck)) {
619 dev_dbg(&pdev->dev, "Can not enable fck\n");
620 ret = -ENODEV;
621 goto err_fnclk;
622 }
623 583
624 rev = hdq_reg_in(hdq_data, OMAP_HDQ_REVISION); 584 rev = hdq_reg_in(hdq_data, OMAP_HDQ_REVISION);
625 dev_info(&pdev->dev, "OMAP HDQ Hardware Rev %c.%c. Driver in %s mode\n", 585 dev_info(&pdev->dev, "OMAP HDQ Hardware Rev %c.%c. Driver in %s mode\n",
@@ -641,9 +601,7 @@ static int __devinit omap_hdq_probe(struct platform_device *pdev)
641 601
642 omap_hdq_break(hdq_data); 602 omap_hdq_break(hdq_data);
643 603
644 /* don't clock the HDQ until it is needed */ 604 pm_runtime_put_sync(&pdev->dev);
645 clk_disable(hdq_data->hdq_ick);
646 clk_disable(hdq_data->hdq_fck);
647 605
648 omap_w1_master.data = hdq_data; 606 omap_w1_master.data = hdq_data;
649 607
@@ -655,20 +613,11 @@ static int __devinit omap_hdq_probe(struct platform_device *pdev)
655 613
656 return 0; 614 return 0;
657 615
658err_w1:
659err_irq: 616err_irq:
660 clk_disable(hdq_data->hdq_fck); 617 pm_runtime_put_sync(&pdev->dev);
661 618err_w1:
662err_fnclk: 619 pm_runtime_disable(&pdev->dev);
663 clk_disable(hdq_data->hdq_ick);
664
665err_intfclk:
666 clk_put(hdq_data->hdq_fck);
667
668err_fck:
669 clk_put(hdq_data->hdq_ick);
670 620
671err_ick:
672 iounmap(hdq_data->hdq_base); 621 iounmap(hdq_data->hdq_base);
673 622
674err_ioremap: 623err_ioremap:
@@ -696,8 +645,7 @@ static int omap_hdq_remove(struct platform_device *pdev)
696 mutex_unlock(&hdq_data->hdq_mutex); 645 mutex_unlock(&hdq_data->hdq_mutex);
697 646
698 /* remove module dependency */ 647 /* remove module dependency */
699 clk_put(hdq_data->hdq_ick); 648 pm_runtime_disable(&pdev->dev);
700 clk_put(hdq_data->hdq_fck);
701 free_irq(INT_24XX_HDQ_IRQ, hdq_data); 649 free_irq(INT_24XX_HDQ_IRQ, hdq_data);
702 platform_set_drvdata(pdev, NULL); 650 platform_set_drvdata(pdev, NULL);
703 iounmap(hdq_data->hdq_base); 651 iounmap(hdq_data->hdq_base);
diff --git a/arch/arm/mach-omap2/smartreflex.h b/include/linux/power/smartreflex.h
index 5809141171f8..3101e62a1213 100644
--- a/arch/arm/mach-omap2/smartreflex.h
+++ b/include/linux/power/smartreflex.h
@@ -17,12 +17,13 @@
17 * published by the Free Software Foundation. 17 * published by the Free Software Foundation.
18 */ 18 */
19 19
20#ifndef __ASM_ARM_OMAP_SMARTREFLEX_H 20#ifndef __POWER_SMARTREFLEX_H
21#define __ASM_ARM_OMAP_SMARTREFLEX_H 21#define __POWER_SMARTREFLEX_H
22 22
23#include <linux/types.h>
23#include <linux/platform_device.h> 24#include <linux/platform_device.h>
24 25#include <linux/delay.h>
25#include "voltage.h" 26#include <plat/voltage.h>
26 27
27/* 28/*
28 * Different Smartreflex IPs version. The v1 is the 65nm version used in 29 * Different Smartreflex IPs version. The v1 is the 65nm version used in
@@ -142,6 +143,51 @@
142#define OMAP3430_SR_ERRWEIGHT 0x04 143#define OMAP3430_SR_ERRWEIGHT 0x04
143#define OMAP3430_SR_ERRMAXLIMIT 0x02 144#define OMAP3430_SR_ERRMAXLIMIT 0x02
144 145
146struct omap_sr {
147 char *name;
148 struct list_head node;
149 struct platform_device *pdev;
150 struct omap_sr_nvalue_table *nvalue_table;
151 struct voltagedomain *voltdm;
152 struct dentry *dbg_dir;
153 unsigned int irq;
154 int srid;
155 int ip_type;
156 int nvalue_count;
157 bool autocomp_active;
158 u32 clk_length;
159 u32 err_weight;
160 u32 err_minlimit;
161 u32 err_maxlimit;
162 u32 accum_data;
163 u32 senn_avgweight;
164 u32 senp_avgweight;
165 u32 senp_mod;
166 u32 senn_mod;
167 void __iomem *base;
168};
169
170/**
171 * test_cond_timeout - busy-loop, testing a condition
172 * @cond: condition to test until it evaluates to true
173 * @timeout: maximum number of microseconds in the timeout
174 * @index: loop index (integer)
175 *
176 * Loop waiting for @cond to become true or until at least @timeout
177 * microseconds have passed. To use, define some integer @index in the
178 * calling code. After running, if @index == @timeout, then the loop has
179 * timed out.
180 *
181 * Copied from omap_test_timeout */
182#define sr_test_cond_timeout(cond, timeout, index) \
183({ \
184 for (index = 0; index < timeout; index++) { \
185 if (cond) \
186 break; \
187 udelay(1); \
188 } \
189})
190
145/** 191/**
146 * struct omap_sr_pmic_data - Strucutre to be populated by pmic code to pass 192 * struct omap_sr_pmic_data - Strucutre to be populated by pmic code to pass
147 * pmic specific info to smartreflex driver 193 * pmic specific info to smartreflex driver
@@ -161,7 +207,7 @@ struct omap_smartreflex_dev_attr {
161 const char *sensor_voltdm_name; 207 const char *sensor_voltdm_name;
162}; 208};
163 209
164#ifdef CONFIG_OMAP_SMARTREFLEX 210#ifdef CONFIG_POWER_AVS_OMAP
165/* 211/*
166 * The smart reflex driver supports CLASS1 CLASS2 and CLASS3 SR. 212 * The smart reflex driver supports CLASS1 CLASS2 and CLASS3 SR.
167 * The smartreflex class driver should pass the class type. 213 * The smartreflex class driver should pass the class type.
@@ -186,10 +232,10 @@ struct omap_smartreflex_dev_attr {
186 * based decisions. 232 * based decisions.
187 */ 233 */
188struct omap_sr_class_data { 234struct omap_sr_class_data {
189 int (*enable)(struct voltagedomain *voltdm); 235 int (*enable)(struct omap_sr *sr);
190 int (*disable)(struct voltagedomain *voltdm, int is_volt_reset); 236 int (*disable)(struct omap_sr *sr, int is_volt_reset);
191 int (*configure)(struct voltagedomain *voltdm); 237 int (*configure)(struct omap_sr *sr);
192 int (*notify)(struct voltagedomain *voltdm, u32 status); 238 int (*notify)(struct omap_sr *sr, u32 status);
193 u8 notify_flags; 239 u8 notify_flags;
194 u8 class_type; 240 u8 class_type;
195}; 241};
@@ -197,17 +243,22 @@ struct omap_sr_class_data {
197/** 243/**
198 * struct omap_sr_nvalue_table - Smartreflex n-target value info 244 * struct omap_sr_nvalue_table - Smartreflex n-target value info
199 * 245 *
200 * @efuse_offs: The offset of the efuse where n-target values are stored. 246 * @efuse_offs: The offset of the efuse where n-target values are stored.
201 * @nvalue: The n-target value. 247 * @nvalue: The n-target value.
248 * @errminlimit: The value of the ERRMINLIMIT bitfield for this n-target
249 * @volt_nominal: microvolts DC that the VDD is initially programmed to
202 */ 250 */
203struct omap_sr_nvalue_table { 251struct omap_sr_nvalue_table {
204 u32 efuse_offs; 252 u32 efuse_offs;
205 u32 nvalue; 253 u32 nvalue;
254 u32 errminlimit;
255 unsigned long volt_nominal;
206}; 256};
207 257
208/** 258/**
209 * struct omap_sr_data - Smartreflex platform data. 259 * struct omap_sr_data - Smartreflex platform data.
210 * 260 *
261 * @name: instance name
211 * @ip_type: Smartreflex IP type. 262 * @ip_type: Smartreflex IP type.
212 * @senp_mod: SENPENABLE value for the sr 263 * @senp_mod: SENPENABLE value for the sr
213 * @senn_mod: SENNENABLE value for sr 264 * @senn_mod: SENNENABLE value for sr
@@ -219,6 +270,7 @@ struct omap_sr_nvalue_table {
219 * @voltdm: Pointer to the voltage domain associated with the SR 270 * @voltdm: Pointer to the voltage domain associated with the SR
220 */ 271 */
221struct omap_sr_data { 272struct omap_sr_data {
273 const char *name;
222 int ip_type; 274 int ip_type;
223 u32 senp_mod; 275 u32 senp_mod;
224 u32 senn_mod; 276 u32 senn_mod;