aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2
diff options
context:
space:
mode:
authorOlof Johansson <olof@lixom.net>2012-03-10 12:13:28 -0500
committerOlof Johansson <olof@lixom.net>2012-03-10 12:13:28 -0500
commit04cc7bc61c666eb090b51dc5d058b209d01d03be (patch)
tree66103edeecea540149b6bfde5267bf0f5d10fdc7 /arch/arm/mach-omap2
parent2c76744b1b7850770712788a874f479d8033dc72 (diff)
parentbb887688bccb48d94fa873f0f6cc7e7e3e4dc05e (diff)
Merge branch 'sr' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap into next/drivers
* 'sr' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap: ARM: OMAP3+: SmartReflex: fix error handling ARM: OMAP3+: SmartReflex: fix the use of debugfs_create_* API ARM: OMAP3+: SmartReflex: micro-optimization for sanity check ARM: OMAP3+: SmartReflex: misc cleanups ARM: OMAP3+: SmartReflex: move late_initcall() closer to its argument ARM: OMAP3+: SmartReflex: add missing platform_set_drvdata() ARM: OMAP3+: hwmod: add SmartReflex IRQs ARM: OMAP3+: SmartReflex: clear ERRCONFIG_VPBOUNDINTST only on a need ARM: OMAP3+: SmartReflex: Fix status masking in ERRCONFIG register ARM: OMAP3+: SmartReflex: Add a shutdown hook ARM: OMAP3+: SmartReflex Class3: disable errorgen before disable VP ARM: OMAP3+: SmartReflex: fix err interrupt disable sequence ARM: OMAP3+: SmartReflex: use voltage domain name in device attributes ARM: OMAP2+: Fix devexit for smartreflex when CONFIG_HOTPLUG is not set ARM: OMAP2+: Fix zoom LCD backlight if TWL_CORE is not selected ARM: OMAP2+: Fix board_mux section type conflict when OMAP_MUX is not set ARM: OMAP2+: Fix OMAP_HDQ_BASE build error ARM: OMAP2+: Fix Kconfig dependencies for USB_ARCH_HAS_EHCI ARM: OMAP2+: I2C: always compile I2C reset code, even if I2C driver is not built
Diffstat (limited to 'arch/arm/mach-omap2')
-rw-r--r--arch/arm/mach-omap2/Kconfig4
-rw-r--r--arch/arm/mach-omap2/Makefile5
-rw-r--r--arch/arm/mach-omap2/board-zoom-display.c4
-rw-r--r--arch/arm/mach-omap2/devices.c7
-rw-r--r--arch/arm/mach-omap2/mux.h2
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_3xxx_data.c31
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_44xx_data.c19
-rw-r--r--arch/arm/mach-omap2/smartreflex-class3.c1
-rw-r--r--arch/arm/mach-omap2/smartreflex.c229
-rw-r--r--arch/arm/mach-omap2/smartreflex.h10
-rw-r--r--arch/arm/mach-omap2/sr_device.c11
11 files changed, 242 insertions, 81 deletions
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index e20c8ab80b0..21a4095a100 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -32,7 +32,7 @@ config ARCH_OMAP3
32 depends on ARCH_OMAP2PLUS 32 depends on ARCH_OMAP2PLUS
33 default y 33 default y
34 select CPU_V7 34 select CPU_V7
35 select USB_ARCH_HAS_EHCI 35 select USB_ARCH_HAS_EHCI if USB_SUPPORT
36 select ARCH_HAS_OPP 36 select ARCH_HAS_OPP
37 select PM_OPP if PM 37 select PM_OPP if PM
38 select ARM_CPU_SUSPEND if PM 38 select ARM_CPU_SUSPEND if PM
@@ -52,7 +52,7 @@ config ARCH_OMAP4
52 select ARM_ERRATA_720789 52 select ARM_ERRATA_720789
53 select ARCH_HAS_OPP 53 select ARCH_HAS_OPP
54 select PM_OPP if PM 54 select PM_OPP if PM
55 select USB_ARCH_HAS_EHCI 55 select USB_ARCH_HAS_EHCI if USB_SUPPORT
56 select ARM_CPU_SUSPEND if PM 56 select ARM_CPU_SUSPEND if PM
57 57
58comment "OMAP Core Type" 58comment "OMAP Core Type"
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index bd76394ccaf..56a6e98652c 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -4,7 +4,7 @@
4 4
5# Common support 5# Common support
6obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer.o pm.o \ 6obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer.o pm.o \
7 common.o gpio.o dma.o wd_timer.o display.o 7 common.o gpio.o dma.o wd_timer.o display.o i2c.o
8 8
9omap-2-3-common = irq.o sdrc.o 9omap-2-3-common = irq.o sdrc.o
10hwmod-common = omap_hwmod.o \ 10hwmod-common = omap_hwmod.o \
@@ -182,9 +182,6 @@ obj-$(CONFIG_OMAP_IOMMU) += iommu2.o
182iommu-$(CONFIG_OMAP_IOMMU) := omap-iommu.o 182iommu-$(CONFIG_OMAP_IOMMU) := omap-iommu.o
183obj-y += $(iommu-m) $(iommu-y) 183obj-y += $(iommu-m) $(iommu-y)
184 184
185i2c-omap-$(CONFIG_I2C_OMAP) := i2c.o
186obj-y += $(i2c-omap-m) $(i2c-omap-y)
187
188ifneq ($(CONFIG_TIDSPBRIDGE),) 185ifneq ($(CONFIG_TIDSPBRIDGE),)
189obj-y += dsp.o 186obj-y += dsp.o
190endif 187endif
diff --git a/arch/arm/mach-omap2/board-zoom-display.c b/arch/arm/mach-omap2/board-zoom-display.c
index d4683ba5f72..2a13b9f6c61 100644
--- a/arch/arm/mach-omap2/board-zoom-display.c
+++ b/arch/arm/mach-omap2/board-zoom-display.c
@@ -55,6 +55,7 @@ static void zoom_panel_disable_lcd(struct omap_dss_device *dssdev)
55 55
56static int zoom_set_bl_intensity(struct omap_dss_device *dssdev, int level) 56static int zoom_set_bl_intensity(struct omap_dss_device *dssdev, int level)
57{ 57{
58#ifdef CONFIG_TWL4030_CORE
58 unsigned char c; 59 unsigned char c;
59 u8 mux_pwm, enb_pwm; 60 u8 mux_pwm, enb_pwm;
60 61
@@ -90,6 +91,9 @@ static int zoom_set_bl_intensity(struct omap_dss_device *dssdev, int level)
90 c = ((50 * (100 - level)) / 100) + 1; 91 c = ((50 * (100 - level)) / 100) + 1;
91 twl_i2c_write_u8(TWL4030_MODULE_PWM1, 0x7F, TWL_LED_PWMOFF); 92 twl_i2c_write_u8(TWL4030_MODULE_PWM1, 0x7F, TWL_LED_PWMOFF);
92 twl_i2c_write_u8(TWL4030_MODULE_PWM1, c, TWL_LED_PWMON); 93 twl_i2c_write_u8(TWL4030_MODULE_PWM1, c, TWL_LED_PWMON);
94#else
95 pr_warn("Backlight not enabled\n");
96#endif
93 97
94 return 0; 98 return 0;
95} 99}
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index 283d11eae69..3ffefe275ea 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -654,9 +654,7 @@ void __init omap242x_init_mmc(struct omap_mmc_platform_data **mmc_data)
654/*-------------------------------------------------------------------------*/ 654/*-------------------------------------------------------------------------*/
655 655
656#if defined(CONFIG_HDQ_MASTER_OMAP) || defined(CONFIG_HDQ_MASTER_OMAP_MODULE) 656#if defined(CONFIG_HDQ_MASTER_OMAP) || defined(CONFIG_HDQ_MASTER_OMAP_MODULE)
657#if defined(CONFIG_SOC_OMAP2430) || defined(CONFIG_SOC_OMAP3430)
658#define OMAP_HDQ_BASE 0x480B2000 657#define OMAP_HDQ_BASE 0x480B2000
659#endif
660static struct resource omap_hdq_resources[] = { 658static struct resource omap_hdq_resources[] = {
661 { 659 {
662 .start = OMAP_HDQ_BASE, 660 .start = OMAP_HDQ_BASE,
@@ -679,7 +677,10 @@ static struct platform_device omap_hdq_dev = {
679}; 677};
680static inline void omap_hdq_init(void) 678static inline void omap_hdq_init(void)
681{ 679{
682 (void) platform_device_register(&omap_hdq_dev); 680 if (cpu_is_omap2420())
681 return;
682
683 platform_device_register(&omap_hdq_dev);
683} 684}
684#else 685#else
685static inline void omap_hdq_init(void) {} 686static inline void omap_hdq_init(void) {}
diff --git a/arch/arm/mach-omap2/mux.h b/arch/arm/mach-omap2/mux.h
index 2132308ad1e..69fe060a0b7 100644
--- a/arch/arm/mach-omap2/mux.h
+++ b/arch/arm/mach-omap2/mux.h
@@ -246,7 +246,7 @@ static inline void omap_hwmod_mux(struct omap_hwmod_mux_info *hmux, u8 state)
246{ 246{
247} 247}
248 248
249static struct omap_board_mux *board_mux __initdata __maybe_unused; 249static struct omap_board_mux *board_mux __maybe_unused;
250 250
251#endif 251#endif
252 252
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index 3c8dd928628..34b9766d1d2 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -29,6 +29,7 @@
29 29
30#include "omap_hwmod_common_data.h" 30#include "omap_hwmod_common_data.h"
31 31
32#include "smartreflex.h"
32#include "prm-regbits-34xx.h" 33#include "prm-regbits-34xx.h"
33#include "cm-regbits-34xx.h" 34#include "cm-regbits-34xx.h"
34#include "wd_timer.h" 35#include "wd_timer.h"
@@ -376,6 +377,16 @@ static struct omap_hwmod_ocp_if omap3_l4_core__i2c3 = {
376 .user = OCP_USER_MPU | OCP_USER_SDMA, 377 .user = OCP_USER_MPU | OCP_USER_SDMA,
377}; 378};
378 379
380static struct omap_hwmod_irq_info omap3_smartreflex_mpu_irqs[] = {
381 { .irq = 18},
382 { .irq = -1 }
383};
384
385static struct omap_hwmod_irq_info omap3_smartreflex_core_irqs[] = {
386 { .irq = 19},
387 { .irq = -1 }
388};
389
379/* L4 CORE -> SR1 interface */ 390/* L4 CORE -> SR1 interface */
380static struct omap_hwmod_addr_space omap3_sr1_addr_space[] = { 391static struct omap_hwmod_addr_space omap3_sr1_addr_space[] = {
381 { 392 {
@@ -2664,6 +2675,10 @@ static struct omap_hwmod_class omap36xx_smartreflex_hwmod_class = {
2664}; 2675};
2665 2676
2666/* SR1 */ 2677/* SR1 */
2678static struct omap_smartreflex_dev_attr sr1_dev_attr = {
2679 .sensor_voltdm_name = "mpu_iva",
2680};
2681
2667static struct omap_hwmod_ocp_if *omap3_sr1_slaves[] = { 2682static struct omap_hwmod_ocp_if *omap3_sr1_slaves[] = {
2668 &omap3_l4_core__sr1, 2683 &omap3_l4_core__sr1,
2669}; 2684};
@@ -2672,7 +2687,6 @@ static struct omap_hwmod omap34xx_sr1_hwmod = {
2672 .name = "sr1_hwmod", 2687 .name = "sr1_hwmod",
2673 .class = &omap34xx_smartreflex_hwmod_class, 2688 .class = &omap34xx_smartreflex_hwmod_class,
2674 .main_clk = "sr1_fck", 2689 .main_clk = "sr1_fck",
2675 .vdd_name = "mpu_iva",
2676 .prcm = { 2690 .prcm = {
2677 .omap2 = { 2691 .omap2 = {
2678 .prcm_reg_id = 1, 2692 .prcm_reg_id = 1,
@@ -2684,6 +2698,8 @@ static struct omap_hwmod omap34xx_sr1_hwmod = {
2684 }, 2698 },
2685 .slaves = omap3_sr1_slaves, 2699 .slaves = omap3_sr1_slaves,
2686 .slaves_cnt = ARRAY_SIZE(omap3_sr1_slaves), 2700 .slaves_cnt = ARRAY_SIZE(omap3_sr1_slaves),
2701 .dev_attr = &sr1_dev_attr,
2702 .mpu_irqs = omap3_smartreflex_mpu_irqs,
2687 .flags = HWMOD_SET_DEFAULT_CLOCKACT, 2703 .flags = HWMOD_SET_DEFAULT_CLOCKACT,
2688}; 2704};
2689 2705
@@ -2691,7 +2707,6 @@ static struct omap_hwmod omap36xx_sr1_hwmod = {
2691 .name = "sr1_hwmod", 2707 .name = "sr1_hwmod",
2692 .class = &omap36xx_smartreflex_hwmod_class, 2708 .class = &omap36xx_smartreflex_hwmod_class,
2693 .main_clk = "sr1_fck", 2709 .main_clk = "sr1_fck",
2694 .vdd_name = "mpu_iva",
2695 .prcm = { 2710 .prcm = {
2696 .omap2 = { 2711 .omap2 = {
2697 .prcm_reg_id = 1, 2712 .prcm_reg_id = 1,
@@ -2703,9 +2718,15 @@ static struct omap_hwmod omap36xx_sr1_hwmod = {
2703 }, 2718 },
2704 .slaves = omap3_sr1_slaves, 2719 .slaves = omap3_sr1_slaves,
2705 .slaves_cnt = ARRAY_SIZE(omap3_sr1_slaves), 2720 .slaves_cnt = ARRAY_SIZE(omap3_sr1_slaves),
2721 .dev_attr = &sr1_dev_attr,
2722 .mpu_irqs = omap3_smartreflex_mpu_irqs,
2706}; 2723};
2707 2724
2708/* SR2 */ 2725/* SR2 */
2726static struct omap_smartreflex_dev_attr sr2_dev_attr = {
2727 .sensor_voltdm_name = "core",
2728};
2729
2709static struct omap_hwmod_ocp_if *omap3_sr2_slaves[] = { 2730static struct omap_hwmod_ocp_if *omap3_sr2_slaves[] = {
2710 &omap3_l4_core__sr2, 2731 &omap3_l4_core__sr2,
2711}; 2732};
@@ -2714,7 +2735,6 @@ static struct omap_hwmod omap34xx_sr2_hwmod = {
2714 .name = "sr2_hwmod", 2735 .name = "sr2_hwmod",
2715 .class = &omap34xx_smartreflex_hwmod_class, 2736 .class = &omap34xx_smartreflex_hwmod_class,
2716 .main_clk = "sr2_fck", 2737 .main_clk = "sr2_fck",
2717 .vdd_name = "core",
2718 .prcm = { 2738 .prcm = {
2719 .omap2 = { 2739 .omap2 = {
2720 .prcm_reg_id = 1, 2740 .prcm_reg_id = 1,
@@ -2726,6 +2746,8 @@ static struct omap_hwmod omap34xx_sr2_hwmod = {
2726 }, 2746 },
2727 .slaves = omap3_sr2_slaves, 2747 .slaves = omap3_sr2_slaves,
2728 .slaves_cnt = ARRAY_SIZE(omap3_sr2_slaves), 2748 .slaves_cnt = ARRAY_SIZE(omap3_sr2_slaves),
2749 .dev_attr = &sr2_dev_attr,
2750 .mpu_irqs = omap3_smartreflex_core_irqs,
2729 .flags = HWMOD_SET_DEFAULT_CLOCKACT, 2751 .flags = HWMOD_SET_DEFAULT_CLOCKACT,
2730}; 2752};
2731 2753
@@ -2733,7 +2755,6 @@ static struct omap_hwmod omap36xx_sr2_hwmod = {
2733 .name = "sr2_hwmod", 2755 .name = "sr2_hwmod",
2734 .class = &omap36xx_smartreflex_hwmod_class, 2756 .class = &omap36xx_smartreflex_hwmod_class,
2735 .main_clk = "sr2_fck", 2757 .main_clk = "sr2_fck",
2736 .vdd_name = "core",
2737 .prcm = { 2758 .prcm = {
2738 .omap2 = { 2759 .omap2 = {
2739 .prcm_reg_id = 1, 2760 .prcm_reg_id = 1,
@@ -2745,6 +2766,8 @@ static struct omap_hwmod omap36xx_sr2_hwmod = {
2745 }, 2766 },
2746 .slaves = omap3_sr2_slaves, 2767 .slaves = omap3_sr2_slaves,
2747 .slaves_cnt = ARRAY_SIZE(omap3_sr2_slaves), 2768 .slaves_cnt = ARRAY_SIZE(omap3_sr2_slaves),
2769 .dev_attr = &sr2_dev_attr,
2770 .mpu_irqs = omap3_smartreflex_core_irqs,
2748}; 2771};
2749 2772
2750/* 2773/*
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index ef0524c10a8..ee3624bd199 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -34,6 +34,7 @@
34 34
35#include "omap_hwmod_common_data.h" 35#include "omap_hwmod_common_data.h"
36 36
37#include "smartreflex.h"
37#include "cm1_44xx.h" 38#include "cm1_44xx.h"
38#include "cm2_44xx.h" 39#include "cm2_44xx.h"
39#include "prm44xx.h" 40#include "prm44xx.h"
@@ -3963,6 +3964,10 @@ static struct omap_hwmod_class omap44xx_smartreflex_hwmod_class = {
3963}; 3964};
3964 3965
3965/* smartreflex_core */ 3966/* smartreflex_core */
3967static struct omap_smartreflex_dev_attr smartreflex_core_dev_attr = {
3968 .sensor_voltdm_name = "core",
3969};
3970
3966static struct omap_hwmod omap44xx_smartreflex_core_hwmod; 3971static struct omap_hwmod omap44xx_smartreflex_core_hwmod;
3967static struct omap_hwmod_irq_info omap44xx_smartreflex_core_irqs[] = { 3972static struct omap_hwmod_irq_info omap44xx_smartreflex_core_irqs[] = {
3968 { .irq = 19 + OMAP44XX_IRQ_GIC_START }, 3973 { .irq = 19 + OMAP44XX_IRQ_GIC_START },
@@ -3999,7 +4004,6 @@ static struct omap_hwmod omap44xx_smartreflex_core_hwmod = {
3999 .mpu_irqs = omap44xx_smartreflex_core_irqs, 4004 .mpu_irqs = omap44xx_smartreflex_core_irqs,
4000 4005
4001 .main_clk = "smartreflex_core_fck", 4006 .main_clk = "smartreflex_core_fck",
4002 .vdd_name = "core",
4003 .prcm = { 4007 .prcm = {
4004 .omap4 = { 4008 .omap4 = {
4005 .clkctrl_offs = OMAP4_CM_ALWON_SR_CORE_CLKCTRL_OFFSET, 4009 .clkctrl_offs = OMAP4_CM_ALWON_SR_CORE_CLKCTRL_OFFSET,
@@ -4009,9 +4013,14 @@ static struct omap_hwmod omap44xx_smartreflex_core_hwmod = {
4009 }, 4013 },
4010 .slaves = omap44xx_smartreflex_core_slaves, 4014 .slaves = omap44xx_smartreflex_core_slaves,
4011 .slaves_cnt = ARRAY_SIZE(omap44xx_smartreflex_core_slaves), 4015 .slaves_cnt = ARRAY_SIZE(omap44xx_smartreflex_core_slaves),
4016 .dev_attr = &smartreflex_core_dev_attr,
4012}; 4017};
4013 4018
4014/* smartreflex_iva */ 4019/* smartreflex_iva */
4020static struct omap_smartreflex_dev_attr smartreflex_iva_dev_attr = {
4021 .sensor_voltdm_name = "iva",
4022};
4023
4015static struct omap_hwmod omap44xx_smartreflex_iva_hwmod; 4024static struct omap_hwmod omap44xx_smartreflex_iva_hwmod;
4016static struct omap_hwmod_irq_info omap44xx_smartreflex_iva_irqs[] = { 4025static struct omap_hwmod_irq_info omap44xx_smartreflex_iva_irqs[] = {
4017 { .irq = 102 + OMAP44XX_IRQ_GIC_START }, 4026 { .irq = 102 + OMAP44XX_IRQ_GIC_START },
@@ -4047,7 +4056,6 @@ static struct omap_hwmod omap44xx_smartreflex_iva_hwmod = {
4047 .clkdm_name = "l4_ao_clkdm", 4056 .clkdm_name = "l4_ao_clkdm",
4048 .mpu_irqs = omap44xx_smartreflex_iva_irqs, 4057 .mpu_irqs = omap44xx_smartreflex_iva_irqs,
4049 .main_clk = "smartreflex_iva_fck", 4058 .main_clk = "smartreflex_iva_fck",
4050 .vdd_name = "iva",
4051 .prcm = { 4059 .prcm = {
4052 .omap4 = { 4060 .omap4 = {
4053 .clkctrl_offs = OMAP4_CM_ALWON_SR_IVA_CLKCTRL_OFFSET, 4061 .clkctrl_offs = OMAP4_CM_ALWON_SR_IVA_CLKCTRL_OFFSET,
@@ -4057,9 +4065,14 @@ static struct omap_hwmod omap44xx_smartreflex_iva_hwmod = {
4057 }, 4065 },
4058 .slaves = omap44xx_smartreflex_iva_slaves, 4066 .slaves = omap44xx_smartreflex_iva_slaves,
4059 .slaves_cnt = ARRAY_SIZE(omap44xx_smartreflex_iva_slaves), 4067 .slaves_cnt = ARRAY_SIZE(omap44xx_smartreflex_iva_slaves),
4068 .dev_attr = &smartreflex_iva_dev_attr,
4060}; 4069};
4061 4070
4062/* smartreflex_mpu */ 4071/* smartreflex_mpu */
4072static struct omap_smartreflex_dev_attr smartreflex_mpu_dev_attr = {
4073 .sensor_voltdm_name = "mpu",
4074};
4075
4063static struct omap_hwmod omap44xx_smartreflex_mpu_hwmod; 4076static struct omap_hwmod omap44xx_smartreflex_mpu_hwmod;
4064static struct omap_hwmod_irq_info omap44xx_smartreflex_mpu_irqs[] = { 4077static struct omap_hwmod_irq_info omap44xx_smartreflex_mpu_irqs[] = {
4065 { .irq = 18 + OMAP44XX_IRQ_GIC_START }, 4078 { .irq = 18 + OMAP44XX_IRQ_GIC_START },
@@ -4095,7 +4108,6 @@ static struct omap_hwmod omap44xx_smartreflex_mpu_hwmod = {
4095 .clkdm_name = "l4_ao_clkdm", 4108 .clkdm_name = "l4_ao_clkdm",
4096 .mpu_irqs = omap44xx_smartreflex_mpu_irqs, 4109 .mpu_irqs = omap44xx_smartreflex_mpu_irqs,
4097 .main_clk = "smartreflex_mpu_fck", 4110 .main_clk = "smartreflex_mpu_fck",
4098 .vdd_name = "mpu",
4099 .prcm = { 4111 .prcm = {
4100 .omap4 = { 4112 .omap4 = {
4101 .clkctrl_offs = OMAP4_CM_ALWON_SR_MPU_CLKCTRL_OFFSET, 4113 .clkctrl_offs = OMAP4_CM_ALWON_SR_MPU_CLKCTRL_OFFSET,
@@ -4105,6 +4117,7 @@ static struct omap_hwmod omap44xx_smartreflex_mpu_hwmod = {
4105 }, 4117 },
4106 .slaves = omap44xx_smartreflex_mpu_slaves, 4118 .slaves = omap44xx_smartreflex_mpu_slaves,
4107 .slaves_cnt = ARRAY_SIZE(omap44xx_smartreflex_mpu_slaves), 4119 .slaves_cnt = ARRAY_SIZE(omap44xx_smartreflex_mpu_slaves),
4120 .dev_attr = &smartreflex_mpu_dev_attr,
4108}; 4121};
4109 4122
4110/* 4123/*
diff --git a/arch/arm/mach-omap2/smartreflex-class3.c b/arch/arm/mach-omap2/smartreflex-class3.c
index 53d9d0a5b39..955566eefac 100644
--- a/arch/arm/mach-omap2/smartreflex-class3.c
+++ b/arch/arm/mach-omap2/smartreflex-class3.c
@@ -29,6 +29,7 @@ static int sr_class3_enable(struct voltagedomain *voltdm)
29 29
30static int sr_class3_disable(struct voltagedomain *voltdm, int is_volt_reset) 30static int sr_class3_disable(struct voltagedomain *voltdm, int is_volt_reset)
31{ 31{
32 sr_disable_errgen(voltdm);
32 omap_vp_disable(voltdm); 33 omap_vp_disable(voltdm);
33 sr_disable(voltdm); 34 sr_disable(voltdm);
34 if (is_volt_reset) 35 if (is_volt_reset)
diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
index 7e755bb0ffc..008fbd7b935 100644
--- a/arch/arm/mach-omap2/smartreflex.c
+++ b/arch/arm/mach-omap2/smartreflex.c
@@ -36,6 +36,12 @@
36#define SR_DISABLE_TIMEOUT 200 36#define SR_DISABLE_TIMEOUT 200
37 37
38struct omap_sr { 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;
39 int srid; 45 int srid;
40 int ip_type; 46 int ip_type;
41 int nvalue_count; 47 int nvalue_count;
@@ -49,13 +55,7 @@ struct omap_sr {
49 u32 senp_avgweight; 55 u32 senp_avgweight;
50 u32 senp_mod; 56 u32 senp_mod;
51 u32 senn_mod; 57 u32 senn_mod;
52 unsigned int irq;
53 void __iomem *base; 58 void __iomem *base;
54 struct platform_device *pdev;
55 struct list_head node;
56 struct omap_sr_nvalue_table *nvalue_table;
57 struct voltagedomain *voltdm;
58 struct dentry *dbg_dir;
59}; 59};
60 60
61/* sr_list contains all the instances of smartreflex module */ 61/* sr_list contains all the instances of smartreflex module */
@@ -74,10 +74,6 @@ static inline void sr_modify_reg(struct omap_sr *sr, unsigned offset, u32 mask,
74 u32 value) 74 u32 value)
75{ 75{
76 u32 reg_val; 76 u32 reg_val;
77 u32 errconfig_offs = 0, errconfig_mask = 0;
78
79 reg_val = __raw_readl(sr->base + offset);
80 reg_val &= ~mask;
81 77
82 /* 78 /*
83 * Smartreflex error config register is special as it contains 79 * Smartreflex error config register is special as it contains
@@ -88,16 +84,15 @@ static inline void sr_modify_reg(struct omap_sr *sr, unsigned offset, u32 mask,
88 * if they are currently set, but does allow the caller to write 84 * if they are currently set, but does allow the caller to write
89 * those bits. 85 * those bits.
90 */ 86 */
91 if (sr->ip_type == SR_TYPE_V1) { 87 if (sr->ip_type == SR_TYPE_V1 && offset == ERRCONFIG_V1)
92 errconfig_offs = ERRCONFIG_V1; 88 mask |= ERRCONFIG_STATUS_V1_MASK;
93 errconfig_mask = ERRCONFIG_STATUS_V1_MASK; 89 else if (sr->ip_type == SR_TYPE_V2 && offset == ERRCONFIG_V2)
94 } else if (sr->ip_type == SR_TYPE_V2) { 90 mask |= ERRCONFIG_VPBOUNDINTST_V2;
95 errconfig_offs = ERRCONFIG_V2; 91
96 errconfig_mask = ERRCONFIG_VPBOUNDINTST_V2; 92 reg_val = __raw_readl(sr->base + offset);
97 } 93 reg_val &= ~mask;
98 94
99 if (offset == errconfig_offs) 95 value &= mask;
100 reg_val &= ~errconfig_mask;
101 96
102 reg_val |= value; 97 reg_val |= value;
103 98
@@ -128,21 +123,28 @@ static struct omap_sr *_sr_lookup(struct voltagedomain *voltdm)
128 123
129static irqreturn_t sr_interrupt(int irq, void *data) 124static irqreturn_t sr_interrupt(int irq, void *data)
130{ 125{
131 struct omap_sr *sr_info = (struct omap_sr *)data; 126 struct omap_sr *sr_info = data;
132 u32 status = 0; 127 u32 status = 0;
133 128
134 if (sr_info->ip_type == SR_TYPE_V1) { 129 switch (sr_info->ip_type) {
130 case SR_TYPE_V1:
135 /* Read the status bits */ 131 /* Read the status bits */
136 status = sr_read_reg(sr_info, ERRCONFIG_V1); 132 status = sr_read_reg(sr_info, ERRCONFIG_V1);
137 133
138 /* Clear them by writing back */ 134 /* Clear them by writing back */
139 sr_write_reg(sr_info, ERRCONFIG_V1, status); 135 sr_write_reg(sr_info, ERRCONFIG_V1, status);
140 } else if (sr_info->ip_type == SR_TYPE_V2) { 136 break;
137 case SR_TYPE_V2:
141 /* Read the status bits */ 138 /* Read the status bits */
142 status = sr_read_reg(sr_info, IRQSTATUS); 139 status = sr_read_reg(sr_info, IRQSTATUS);
143 140
144 /* Clear them by writing back */ 141 /* Clear them by writing back */
145 sr_write_reg(sr_info, IRQSTATUS, status); 142 sr_write_reg(sr_info, IRQSTATUS, status);
143 break;
144 default:
145 dev_err(&sr_info->pdev->dev, "UNKNOWN IP type %d\n",
146 sr_info->ip_type);
147 return IRQ_NONE;
146 } 148 }
147 149
148 if (sr_class->notify) 150 if (sr_class->notify)
@@ -166,6 +168,7 @@ static void sr_set_clk_length(struct omap_sr *sr)
166 __func__); 168 __func__);
167 return; 169 return;
168 } 170 }
171
169 sys_clk_speed = clk_get_rate(sys_ck); 172 sys_clk_speed = clk_get_rate(sys_ck);
170 clk_put(sys_ck); 173 clk_put(sys_ck);
171 174
@@ -267,7 +270,7 @@ static int sr_late_init(struct omap_sr *sr_info)
267 goto error; 270 goto error;
268 } 271 }
269 ret = request_irq(sr_info->irq, sr_interrupt, 272 ret = request_irq(sr_info->irq, sr_interrupt,
270 0, name, (void *)sr_info); 273 0, name, sr_info);
271 if (ret) 274 if (ret)
272 goto error; 275 goto error;
273 disable_irq(sr_info->irq); 276 disable_irq(sr_info->irq);
@@ -288,12 +291,15 @@ error:
288 "not function as desired\n", __func__); 291 "not function as desired\n", __func__);
289 kfree(name); 292 kfree(name);
290 kfree(sr_info); 293 kfree(sr_info);
294
291 return ret; 295 return ret;
292} 296}
293 297
294static void sr_v1_disable(struct omap_sr *sr) 298static void sr_v1_disable(struct omap_sr *sr)
295{ 299{
296 int timeout = 0; 300 int timeout = 0;
301 int errconf_val = ERRCONFIG_MCUACCUMINTST | ERRCONFIG_MCUVALIDINTST |
302 ERRCONFIG_MCUBOUNDINTST;
297 303
298 /* Enable MCUDisableAcknowledge interrupt */ 304 /* Enable MCUDisableAcknowledge interrupt */
299 sr_modify_reg(sr, ERRCONFIG_V1, 305 sr_modify_reg(sr, ERRCONFIG_V1,
@@ -302,13 +308,13 @@ static void sr_v1_disable(struct omap_sr *sr)
302 /* SRCONFIG - disable SR */ 308 /* SRCONFIG - disable SR */
303 sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, 0x0); 309 sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, 0x0);
304 310
305 /* Disable all other SR interrupts and clear the status */ 311 /* Disable all other SR interrupts and clear the status as needed */
312 if (sr_read_reg(sr, ERRCONFIG_V1) & ERRCONFIG_VPBOUNDINTST_V1)
313 errconf_val |= ERRCONFIG_VPBOUNDINTST_V1;
306 sr_modify_reg(sr, ERRCONFIG_V1, 314 sr_modify_reg(sr, ERRCONFIG_V1,
307 (ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUVALIDINTEN | 315 (ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUVALIDINTEN |
308 ERRCONFIG_MCUBOUNDINTEN | ERRCONFIG_VPBOUNDINTEN_V1), 316 ERRCONFIG_MCUBOUNDINTEN | ERRCONFIG_VPBOUNDINTEN_V1),
309 (ERRCONFIG_MCUACCUMINTST | ERRCONFIG_MCUVALIDINTST | 317 errconf_val);
310 ERRCONFIG_MCUBOUNDINTST |
311 ERRCONFIG_VPBOUNDINTST_V1));
312 318
313 /* 319 /*
314 * Wait for SR to be disabled. 320 * Wait for SR to be disabled.
@@ -337,9 +343,17 @@ static void sr_v2_disable(struct omap_sr *sr)
337 /* SRCONFIG - disable SR */ 343 /* SRCONFIG - disable SR */
338 sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, 0x0); 344 sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, 0x0);
339 345
340 /* Disable all other SR interrupts and clear the status */ 346 /*
341 sr_modify_reg(sr, ERRCONFIG_V2, ERRCONFIG_VPBOUNDINTEN_V2, 347 * Disable all other SR interrupts and clear the status
348 * write to status register ONLY on need basis - only if status
349 * is set.
350 */
351 if (sr_read_reg(sr, ERRCONFIG_V2) & ERRCONFIG_VPBOUNDINTST_V2)
352 sr_modify_reg(sr, ERRCONFIG_V2, ERRCONFIG_VPBOUNDINTEN_V2,
342 ERRCONFIG_VPBOUNDINTST_V2); 353 ERRCONFIG_VPBOUNDINTST_V2);
354 else
355 sr_modify_reg(sr, ERRCONFIG_V2, ERRCONFIG_VPBOUNDINTEN_V2,
356 0x0);
343 sr_write_reg(sr, IRQENABLE_CLR, (IRQENABLE_MCUACCUMINT | 357 sr_write_reg(sr, IRQENABLE_CLR, (IRQENABLE_MCUACCUMINT |
344 IRQENABLE_MCUVALIDINT | 358 IRQENABLE_MCUVALIDINT |
345 IRQENABLE_MCUBOUNDSINT)); 359 IRQENABLE_MCUBOUNDSINT));
@@ -398,15 +412,16 @@ static u32 sr_retrieve_nvalue(struct omap_sr *sr, u32 efuse_offs)
398 */ 412 */
399int sr_configure_errgen(struct voltagedomain *voltdm) 413int sr_configure_errgen(struct voltagedomain *voltdm)
400{ 414{
401 u32 sr_config, sr_errconfig, errconfig_offs, vpboundint_en; 415 u32 sr_config, sr_errconfig, errconfig_offs;
402 u32 vpboundint_st, senp_en = 0, senn_en = 0; 416 u32 vpboundint_en, vpboundint_st;
417 u32 senp_en = 0, senn_en = 0;
403 u8 senp_shift, senn_shift; 418 u8 senp_shift, senn_shift;
404 struct omap_sr *sr = _sr_lookup(voltdm); 419 struct omap_sr *sr = _sr_lookup(voltdm);
405 420
406 if (IS_ERR(sr)) { 421 if (IS_ERR(sr)) {
407 pr_warning("%s: omap_sr struct for sr_%s not found\n", 422 pr_warning("%s: omap_sr struct for sr_%s not found\n",
408 __func__, voltdm->name); 423 __func__, voltdm->name);
409 return -EINVAL; 424 return PTR_ERR(sr);
410 } 425 }
411 426
412 if (!sr->clk_length) 427 if (!sr->clk_length)
@@ -418,20 +433,23 @@ int sr_configure_errgen(struct voltagedomain *voltdm)
418 sr_config = (sr->clk_length << SRCONFIG_SRCLKLENGTH_SHIFT) | 433 sr_config = (sr->clk_length << SRCONFIG_SRCLKLENGTH_SHIFT) |
419 SRCONFIG_SENENABLE | SRCONFIG_ERRGEN_EN; 434 SRCONFIG_SENENABLE | SRCONFIG_ERRGEN_EN;
420 435
421 if (sr->ip_type == SR_TYPE_V1) { 436 switch (sr->ip_type) {
437 case SR_TYPE_V1:
422 sr_config |= SRCONFIG_DELAYCTRL; 438 sr_config |= SRCONFIG_DELAYCTRL;
423 senn_shift = SRCONFIG_SENNENABLE_V1_SHIFT; 439 senn_shift = SRCONFIG_SENNENABLE_V1_SHIFT;
424 senp_shift = SRCONFIG_SENPENABLE_V1_SHIFT; 440 senp_shift = SRCONFIG_SENPENABLE_V1_SHIFT;
425 errconfig_offs = ERRCONFIG_V1; 441 errconfig_offs = ERRCONFIG_V1;
426 vpboundint_en = ERRCONFIG_VPBOUNDINTEN_V1; 442 vpboundint_en = ERRCONFIG_VPBOUNDINTEN_V1;
427 vpboundint_st = ERRCONFIG_VPBOUNDINTST_V1; 443 vpboundint_st = ERRCONFIG_VPBOUNDINTST_V1;
428 } else if (sr->ip_type == SR_TYPE_V2) { 444 break;
445 case SR_TYPE_V2:
429 senn_shift = SRCONFIG_SENNENABLE_V2_SHIFT; 446 senn_shift = SRCONFIG_SENNENABLE_V2_SHIFT;
430 senp_shift = SRCONFIG_SENPENABLE_V2_SHIFT; 447 senp_shift = SRCONFIG_SENPENABLE_V2_SHIFT;
431 errconfig_offs = ERRCONFIG_V2; 448 errconfig_offs = ERRCONFIG_V2;
432 vpboundint_en = ERRCONFIG_VPBOUNDINTEN_V2; 449 vpboundint_en = ERRCONFIG_VPBOUNDINTEN_V2;
433 vpboundint_st = ERRCONFIG_VPBOUNDINTST_V2; 450 vpboundint_st = ERRCONFIG_VPBOUNDINTST_V2;
434 } else { 451 break;
452 default:
435 dev_err(&sr->pdev->dev, "%s: Trying to Configure smartreflex" 453 dev_err(&sr->pdev->dev, "%s: Trying to Configure smartreflex"
436 "module without specifying the ip\n", __func__); 454 "module without specifying the ip\n", __func__);
437 return -EINVAL; 455 return -EINVAL;
@@ -447,8 +465,55 @@ int sr_configure_errgen(struct voltagedomain *voltdm)
447 sr_errconfig); 465 sr_errconfig);
448 466
449 /* Enabling the interrupts if the ERROR module is used */ 467 /* Enabling the interrupts if the ERROR module is used */
450 sr_modify_reg(sr, errconfig_offs, 468 sr_modify_reg(sr, errconfig_offs, (vpboundint_en | vpboundint_st),
451 vpboundint_en, (vpboundint_en | vpboundint_st)); 469 vpboundint_en);
470
471 return 0;
472}
473
474/**
475 * sr_disable_errgen() - Disables SmartReflex AVS module's errgen component
476 * @voltdm: VDD pointer to which the SR module to be configured belongs to.
477 *
478 * This API is to be called from the smartreflex class driver to
479 * disable the error generator module inside the smartreflex module.
480 *
481 * Returns 0 on success and error value in case of failure.
482 */
483int sr_disable_errgen(struct voltagedomain *voltdm)
484{
485 u32 errconfig_offs;
486 u32 vpboundint_en, vpboundint_st;
487 struct omap_sr *sr = _sr_lookup(voltdm);
488
489 if (IS_ERR(sr)) {
490 pr_warning("%s: omap_sr struct for sr_%s not found\n",
491 __func__, voltdm->name);
492 return PTR_ERR(sr);
493 }
494
495 switch (sr->ip_type) {
496 case SR_TYPE_V1:
497 errconfig_offs = ERRCONFIG_V1;
498 vpboundint_en = ERRCONFIG_VPBOUNDINTEN_V1;
499 vpboundint_st = ERRCONFIG_VPBOUNDINTST_V1;
500 break;
501 case SR_TYPE_V2:
502 errconfig_offs = ERRCONFIG_V2;
503 vpboundint_en = ERRCONFIG_VPBOUNDINTEN_V2;
504 vpboundint_st = ERRCONFIG_VPBOUNDINTST_V2;
505 break;
506 default:
507 dev_err(&sr->pdev->dev, "%s: Trying to Configure smartreflex"
508 "module without specifying the ip\n", __func__);
509 return -EINVAL;
510 }
511
512 /* Disable the interrupts of ERROR module */
513 sr_modify_reg(sr, errconfig_offs, vpboundint_en | vpboundint_st, 0);
514
515 /* Disable the Sensor and errorgen */
516 sr_modify_reg(sr, SRCONFIG, SRCONFIG_SENENABLE | SRCONFIG_ERRGEN_EN, 0);
452 517
453 return 0; 518 return 0;
454} 519}
@@ -475,7 +540,7 @@ int sr_configure_minmax(struct voltagedomain *voltdm)
475 if (IS_ERR(sr)) { 540 if (IS_ERR(sr)) {
476 pr_warning("%s: omap_sr struct for sr_%s not found\n", 541 pr_warning("%s: omap_sr struct for sr_%s not found\n",
477 __func__, voltdm->name); 542 __func__, voltdm->name);
478 return -EINVAL; 543 return PTR_ERR(sr);
479 } 544 }
480 545
481 if (!sr->clk_length) 546 if (!sr->clk_length)
@@ -488,14 +553,17 @@ int sr_configure_minmax(struct voltagedomain *voltdm)
488 SRCONFIG_SENENABLE | 553 SRCONFIG_SENENABLE |
489 (sr->accum_data << SRCONFIG_ACCUMDATA_SHIFT); 554 (sr->accum_data << SRCONFIG_ACCUMDATA_SHIFT);
490 555
491 if (sr->ip_type == SR_TYPE_V1) { 556 switch (sr->ip_type) {
557 case SR_TYPE_V1:
492 sr_config |= SRCONFIG_DELAYCTRL; 558 sr_config |= SRCONFIG_DELAYCTRL;
493 senn_shift = SRCONFIG_SENNENABLE_V1_SHIFT; 559 senn_shift = SRCONFIG_SENNENABLE_V1_SHIFT;
494 senp_shift = SRCONFIG_SENPENABLE_V1_SHIFT; 560 senp_shift = SRCONFIG_SENPENABLE_V1_SHIFT;
495 } else if (sr->ip_type == SR_TYPE_V2) { 561 break;
562 case SR_TYPE_V2:
496 senn_shift = SRCONFIG_SENNENABLE_V2_SHIFT; 563 senn_shift = SRCONFIG_SENNENABLE_V2_SHIFT;
497 senp_shift = SRCONFIG_SENPENABLE_V2_SHIFT; 564 senp_shift = SRCONFIG_SENPENABLE_V2_SHIFT;
498 } else { 565 break;
566 default:
499 dev_err(&sr->pdev->dev, "%s: Trying to Configure smartreflex" 567 dev_err(&sr->pdev->dev, "%s: Trying to Configure smartreflex"
500 "module without specifying the ip\n", __func__); 568 "module without specifying the ip\n", __func__);
501 return -EINVAL; 569 return -EINVAL;
@@ -511,20 +579,27 @@ int sr_configure_minmax(struct voltagedomain *voltdm)
511 * Enabling the interrupts if MINMAXAVG module is used. 579 * Enabling the interrupts if MINMAXAVG module is used.
512 * TODO: check if all the interrupts are mandatory 580 * TODO: check if all the interrupts are mandatory
513 */ 581 */
514 if (sr->ip_type == SR_TYPE_V1) { 582 switch (sr->ip_type) {
583 case SR_TYPE_V1:
515 sr_modify_reg(sr, ERRCONFIG_V1, 584 sr_modify_reg(sr, ERRCONFIG_V1,
516 (ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUVALIDINTEN | 585 (ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUVALIDINTEN |
517 ERRCONFIG_MCUBOUNDINTEN), 586 ERRCONFIG_MCUBOUNDINTEN),
518 (ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUACCUMINTST | 587 (ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUACCUMINTST |
519 ERRCONFIG_MCUVALIDINTEN | ERRCONFIG_MCUVALIDINTST | 588 ERRCONFIG_MCUVALIDINTEN | ERRCONFIG_MCUVALIDINTST |
520 ERRCONFIG_MCUBOUNDINTEN | ERRCONFIG_MCUBOUNDINTST)); 589 ERRCONFIG_MCUBOUNDINTEN | ERRCONFIG_MCUBOUNDINTST));
521 } else if (sr->ip_type == SR_TYPE_V2) { 590 break;
591 case SR_TYPE_V2:
522 sr_write_reg(sr, IRQSTATUS, 592 sr_write_reg(sr, IRQSTATUS,
523 IRQSTATUS_MCUACCUMINT | IRQSTATUS_MCVALIDINT | 593 IRQSTATUS_MCUACCUMINT | IRQSTATUS_MCVALIDINT |
524 IRQSTATUS_MCBOUNDSINT | IRQSTATUS_MCUDISABLEACKINT); 594 IRQSTATUS_MCBOUNDSINT | IRQSTATUS_MCUDISABLEACKINT);
525 sr_write_reg(sr, IRQENABLE_SET, 595 sr_write_reg(sr, IRQENABLE_SET,
526 IRQENABLE_MCUACCUMINT | IRQENABLE_MCUVALIDINT | 596 IRQENABLE_MCUACCUMINT | IRQENABLE_MCUVALIDINT |
527 IRQENABLE_MCUBOUNDSINT | IRQENABLE_MCUDISABLEACKINT); 597 IRQENABLE_MCUBOUNDSINT | IRQENABLE_MCUDISABLEACKINT);
598 break;
599 default:
600 dev_err(&sr->pdev->dev, "%s: Trying to Configure smartreflex"
601 "module without specifying the ip\n", __func__);
602 return -EINVAL;
528 } 603 }
529 604
530 return 0; 605 return 0;
@@ -543,15 +618,15 @@ int sr_configure_minmax(struct voltagedomain *voltdm)
543 */ 618 */
544int sr_enable(struct voltagedomain *voltdm, unsigned long volt) 619int sr_enable(struct voltagedomain *voltdm, unsigned long volt)
545{ 620{
546 u32 nvalue_reciprocal;
547 struct omap_volt_data *volt_data; 621 struct omap_volt_data *volt_data;
548 struct omap_sr *sr = _sr_lookup(voltdm); 622 struct omap_sr *sr = _sr_lookup(voltdm);
623 u32 nvalue_reciprocal;
549 int ret; 624 int ret;
550 625
551 if (IS_ERR(sr)) { 626 if (IS_ERR(sr)) {
552 pr_warning("%s: omap_sr struct for sr_%s not found\n", 627 pr_warning("%s: omap_sr struct for sr_%s not found\n",
553 __func__, voltdm->name); 628 __func__, voltdm->name);
554 return -EINVAL; 629 return PTR_ERR(sr);
555 } 630 }
556 631
557 volt_data = omap_voltage_get_voltdata(sr->voltdm, volt); 632 volt_data = omap_voltage_get_voltdata(sr->voltdm, volt);
@@ -559,7 +634,7 @@ int sr_enable(struct voltagedomain *voltdm, unsigned long volt)
559 if (IS_ERR(volt_data)) { 634 if (IS_ERR(volt_data)) {
560 dev_warn(&sr->pdev->dev, "%s: Unable to get voltage table" 635 dev_warn(&sr->pdev->dev, "%s: Unable to get voltage table"
561 "for nominal voltage %ld\n", __func__, volt); 636 "for nominal voltage %ld\n", __func__, volt);
562 return -ENODATA; 637 return PTR_ERR(volt_data);
563 } 638 }
564 639
565 nvalue_reciprocal = sr_retrieve_nvalue(sr, volt_data->sr_efuse_offs); 640 nvalue_reciprocal = sr_retrieve_nvalue(sr, volt_data->sr_efuse_offs);
@@ -617,10 +692,17 @@ void sr_disable(struct voltagedomain *voltdm)
617 * disable the clocks. 692 * disable the clocks.
618 */ 693 */
619 if (sr_read_reg(sr, SRCONFIG) & SRCONFIG_SRENABLE) { 694 if (sr_read_reg(sr, SRCONFIG) & SRCONFIG_SRENABLE) {
620 if (sr->ip_type == SR_TYPE_V1) 695 switch (sr->ip_type) {
696 case SR_TYPE_V1:
621 sr_v1_disable(sr); 697 sr_v1_disable(sr);
622 else if (sr->ip_type == SR_TYPE_V2) 698 break;
699 case SR_TYPE_V2:
623 sr_v2_disable(sr); 700 sr_v2_disable(sr);
701 break;
702 default:
703 dev_err(&sr->pdev->dev, "UNKNOWN IP type %d\n",
704 sr->ip_type);
705 }
624 } 706 }
625 707
626 pm_runtime_put_sync_suspend(&sr->pdev->dev); 708 pm_runtime_put_sync_suspend(&sr->pdev->dev);
@@ -779,10 +861,10 @@ void omap_sr_register_pmic(struct omap_sr_pmic_data *pmic_data)
779 sr_pmic_data = pmic_data; 861 sr_pmic_data = pmic_data;
780} 862}
781 863
782/* PM Debug Fs enteries to enable disable smartreflex. */ 864/* PM Debug FS entries to enable and disable smartreflex. */
783static int omap_sr_autocomp_show(void *data, u64 *val) 865static int omap_sr_autocomp_show(void *data, u64 *val)
784{ 866{
785 struct omap_sr *sr_info = (struct omap_sr *) data; 867 struct omap_sr *sr_info = data;
786 868
787 if (!sr_info) { 869 if (!sr_info) {
788 pr_warning("%s: omap_sr struct not found\n", __func__); 870 pr_warning("%s: omap_sr struct not found\n", __func__);
@@ -796,7 +878,7 @@ static int omap_sr_autocomp_show(void *data, u64 *val)
796 878
797static int omap_sr_autocomp_store(void *data, u64 val) 879static int omap_sr_autocomp_store(void *data, u64 val)
798{ 880{
799 struct omap_sr *sr_info = (struct omap_sr *) data; 881 struct omap_sr *sr_info = data;
800 882
801 if (!sr_info) { 883 if (!sr_info) {
802 pr_warning("%s: omap_sr struct not found\n", __func__); 884 pr_warning("%s: omap_sr struct not found\n", __func__);
@@ -804,7 +886,7 @@ static int omap_sr_autocomp_store(void *data, u64 val)
804 } 886 }
805 887
806 /* Sanity check */ 888 /* Sanity check */
807 if (val && (val != 1)) { 889 if (val > 1) {
808 pr_warning("%s: Invalid argument %lld\n", __func__, val); 890 pr_warning("%s: Invalid argument %lld\n", __func__, val);
809 return -EINVAL; 891 return -EINVAL;
810 } 892 }
@@ -821,11 +903,11 @@ static int omap_sr_autocomp_store(void *data, u64 val)
821} 903}
822 904
823DEFINE_SIMPLE_ATTRIBUTE(pm_sr_fops, omap_sr_autocomp_show, 905DEFINE_SIMPLE_ATTRIBUTE(pm_sr_fops, omap_sr_autocomp_show,
824 omap_sr_autocomp_store, "%llu\n"); 906 omap_sr_autocomp_store, "%llu\n");
825 907
826static int __init omap_sr_probe(struct platform_device *pdev) 908static int __init omap_sr_probe(struct platform_device *pdev)
827{ 909{
828 struct omap_sr *sr_info = kzalloc(sizeof(struct omap_sr), GFP_KERNEL); 910 struct omap_sr *sr_info;
829 struct omap_sr_data *pdata = pdev->dev.platform_data; 911 struct omap_sr_data *pdata = pdev->dev.platform_data;
830 struct resource *mem, *irq; 912 struct resource *mem, *irq;
831 struct dentry *nvalue_dir; 913 struct dentry *nvalue_dir;
@@ -833,12 +915,15 @@ static int __init omap_sr_probe(struct platform_device *pdev)
833 int i, ret = 0; 915 int i, ret = 0;
834 char *name; 916 char *name;
835 917
918 sr_info = kzalloc(sizeof(struct omap_sr), GFP_KERNEL);
836 if (!sr_info) { 919 if (!sr_info) {
837 dev_err(&pdev->dev, "%s: unable to allocate sr_info\n", 920 dev_err(&pdev->dev, "%s: unable to allocate sr_info\n",
838 __func__); 921 __func__);
839 return -ENOMEM; 922 return -ENOMEM;
840 } 923 }
841 924
925 platform_set_drvdata(pdev, sr_info);
926
842 if (!pdata) { 927 if (!pdata) {
843 dev_err(&pdev->dev, "%s: platform data missing\n", __func__); 928 dev_err(&pdev->dev, "%s: platform data missing\n", __func__);
844 ret = -EINVAL; 929 ret = -EINVAL;
@@ -904,7 +989,7 @@ static int __init omap_sr_probe(struct platform_device *pdev)
904 dev_info(&pdev->dev, "%s: SmartReflex driver initialized\n", __func__); 989 dev_info(&pdev->dev, "%s: SmartReflex driver initialized\n", __func__);
905 if (!sr_dbg_dir) { 990 if (!sr_dbg_dir) {
906 sr_dbg_dir = debugfs_create_dir("smartreflex", NULL); 991 sr_dbg_dir = debugfs_create_dir("smartreflex", NULL);
907 if (!sr_dbg_dir) { 992 if (IS_ERR_OR_NULL(sr_dbg_dir)) {
908 ret = PTR_ERR(sr_dbg_dir); 993 ret = PTR_ERR(sr_dbg_dir);
909 pr_err("%s:sr debugfs dir creation failed(%d)\n", 994 pr_err("%s:sr debugfs dir creation failed(%d)\n",
910 __func__, ret); 995 __func__, ret);
@@ -921,7 +1006,7 @@ static int __init omap_sr_probe(struct platform_device *pdev)
921 } 1006 }
922 sr_info->dbg_dir = debugfs_create_dir(name, sr_dbg_dir); 1007 sr_info->dbg_dir = debugfs_create_dir(name, sr_dbg_dir);
923 kfree(name); 1008 kfree(name);
924 if (IS_ERR(sr_info->dbg_dir)) { 1009 if (IS_ERR_OR_NULL(sr_info->dbg_dir)) {
925 dev_err(&pdev->dev, "%s: Unable to create debugfs directory\n", 1010 dev_err(&pdev->dev, "%s: Unable to create debugfs directory\n",
926 __func__); 1011 __func__);
927 ret = PTR_ERR(sr_info->dbg_dir); 1012 ret = PTR_ERR(sr_info->dbg_dir);
@@ -938,7 +1023,7 @@ static int __init omap_sr_probe(struct platform_device *pdev)
938 &sr_info->err_minlimit); 1023 &sr_info->err_minlimit);
939 1024
940 nvalue_dir = debugfs_create_dir("nvalue", sr_info->dbg_dir); 1025 nvalue_dir = debugfs_create_dir("nvalue", sr_info->dbg_dir);
941 if (IS_ERR(nvalue_dir)) { 1026 if (IS_ERR_OR_NULL(nvalue_dir)) {
942 dev_err(&pdev->dev, "%s: Unable to create debugfs directory" 1027 dev_err(&pdev->dev, "%s: Unable to create debugfs directory"
943 "for n-values\n", __func__); 1028 "for n-values\n", __func__);
944 ret = PTR_ERR(nvalue_dir); 1029 ret = PTR_ERR(nvalue_dir);
@@ -994,7 +1079,7 @@ static int __devexit omap_sr_remove(struct platform_device *pdev)
994 if (IS_ERR(sr_info)) { 1079 if (IS_ERR(sr_info)) {
995 dev_warn(&pdev->dev, "%s: omap_sr struct not found\n", 1080 dev_warn(&pdev->dev, "%s: omap_sr struct not found\n",
996 __func__); 1081 __func__);
997 return -EINVAL; 1082 return PTR_ERR(sr_info);
998 } 1083 }
999 1084
1000 if (sr_info->autocomp_active) 1085 if (sr_info->autocomp_active)
@@ -1011,8 +1096,32 @@ static int __devexit omap_sr_remove(struct platform_device *pdev)
1011 return 0; 1096 return 0;
1012} 1097}
1013 1098
1099static void __devexit omap_sr_shutdown(struct platform_device *pdev)
1100{
1101 struct omap_sr_data *pdata = pdev->dev.platform_data;
1102 struct omap_sr *sr_info;
1103
1104 if (!pdata) {
1105 dev_err(&pdev->dev, "%s: platform data missing\n", __func__);
1106 return;
1107 }
1108
1109 sr_info = _sr_lookup(pdata->voltdm);
1110 if (IS_ERR(sr_info)) {
1111 dev_warn(&pdev->dev, "%s: omap_sr struct not found\n",
1112 __func__);
1113 return;
1114 }
1115
1116 if (sr_info->autocomp_active)
1117 sr_stop_vddautocomp(sr_info);
1118
1119 return;
1120}
1121
1014static struct platform_driver smartreflex_driver = { 1122static struct platform_driver smartreflex_driver = {
1015 .remove = omap_sr_remove, 1123 .remove = __devexit_p(omap_sr_remove),
1124 .shutdown = __devexit_p(omap_sr_shutdown),
1016 .driver = { 1125 .driver = {
1017 .name = "smartreflex", 1126 .name = "smartreflex",
1018 }, 1127 },
@@ -1042,12 +1151,12 @@ static int __init sr_init(void)
1042 1151
1043 return 0; 1152 return 0;
1044} 1153}
1154late_initcall(sr_init);
1045 1155
1046static void __exit sr_exit(void) 1156static void __exit sr_exit(void)
1047{ 1157{
1048 platform_driver_unregister(&smartreflex_driver); 1158 platform_driver_unregister(&smartreflex_driver);
1049} 1159}
1050late_initcall(sr_init);
1051module_exit(sr_exit); 1160module_exit(sr_exit);
1052 1161
1053MODULE_DESCRIPTION("OMAP Smartreflex Driver"); 1162MODULE_DESCRIPTION("OMAP Smartreflex Driver");
diff --git a/arch/arm/mach-omap2/smartreflex.h b/arch/arm/mach-omap2/smartreflex.h
index 5f35b9e2555..5809141171f 100644
--- a/arch/arm/mach-omap2/smartreflex.h
+++ b/arch/arm/mach-omap2/smartreflex.h
@@ -152,6 +152,15 @@ struct omap_sr_pmic_data {
152 void (*sr_pmic_init) (void); 152 void (*sr_pmic_init) (void);
153}; 153};
154 154
155/**
156 * struct omap_smartreflex_dev_attr - Smartreflex Device attribute.
157 *
158 * @sensor_voltdm_name: Name of voltdomain of SR instance
159 */
160struct omap_smartreflex_dev_attr {
161 const char *sensor_voltdm_name;
162};
163
155#ifdef CONFIG_OMAP_SMARTREFLEX 164#ifdef CONFIG_OMAP_SMARTREFLEX
156/* 165/*
157 * The smart reflex driver supports CLASS1 CLASS2 and CLASS3 SR. 166 * The smart reflex driver supports CLASS1 CLASS2 and CLASS3 SR.
@@ -231,6 +240,7 @@ void omap_sr_register_pmic(struct omap_sr_pmic_data *pmic_data);
231int sr_enable(struct voltagedomain *voltdm, unsigned long volt); 240int sr_enable(struct voltagedomain *voltdm, unsigned long volt);
232void sr_disable(struct voltagedomain *voltdm); 241void sr_disable(struct voltagedomain *voltdm);
233int sr_configure_errgen(struct voltagedomain *voltdm); 242int sr_configure_errgen(struct voltagedomain *voltdm);
243int sr_disable_errgen(struct voltagedomain *voltdm);
234int sr_configure_minmax(struct voltagedomain *voltdm); 244int sr_configure_minmax(struct voltagedomain *voltdm);
235 245
236/* API to register the smartreflex class driver with the smartreflex driver */ 246/* API to register the smartreflex class driver with the smartreflex driver */
diff --git a/arch/arm/mach-omap2/sr_device.c b/arch/arm/mach-omap2/sr_device.c
index 9f43fcc05d3..60293370a2a 100644
--- a/arch/arm/mach-omap2/sr_device.c
+++ b/arch/arm/mach-omap2/sr_device.c
@@ -74,6 +74,7 @@ static int sr_dev_init(struct omap_hwmod *oh, void *user)
74 struct omap_sr_data *sr_data; 74 struct omap_sr_data *sr_data;
75 struct platform_device *pdev; 75 struct platform_device *pdev;
76 struct omap_volt_data *volt_data; 76 struct omap_volt_data *volt_data;
77 struct omap_smartreflex_dev_attr *sr_dev_attr;
77 char *name = "smartreflex"; 78 char *name = "smartreflex";
78 static int i; 79 static int i;
79 80
@@ -84,9 +85,11 @@ static int sr_dev_init(struct omap_hwmod *oh, void *user)
84 return -ENOMEM; 85 return -ENOMEM;
85 } 86 }
86 87
87 if (!oh->vdd_name) { 88 sr_dev_attr = (struct omap_smartreflex_dev_attr *)oh->dev_attr;
89 if (!sr_dev_attr || !sr_dev_attr->sensor_voltdm_name) {
88 pr_err("%s: No voltage domain specified for %s." 90 pr_err("%s: No voltage domain specified for %s."
89 "Cannot initialize\n", __func__, oh->name); 91 "Cannot initialize\n", __func__,
92 oh->name);
90 goto exit; 93 goto exit;
91 } 94 }
92 95
@@ -94,10 +97,10 @@ static int sr_dev_init(struct omap_hwmod *oh, void *user)
94 sr_data->senn_mod = 0x1; 97 sr_data->senn_mod = 0x1;
95 sr_data->senp_mod = 0x1; 98 sr_data->senp_mod = 0x1;
96 99
97 sr_data->voltdm = voltdm_lookup(oh->vdd_name); 100 sr_data->voltdm = voltdm_lookup(sr_dev_attr->sensor_voltdm_name);
98 if (IS_ERR(sr_data->voltdm)) { 101 if (IS_ERR(sr_data->voltdm)) {
99 pr_err("%s: Unable to get voltage domain pointer for VDD %s\n", 102 pr_err("%s: Unable to get voltage domain pointer for VDD %s\n",
100 __func__, oh->vdd_name); 103 __func__, sr_dev_attr->sensor_voltdm_name);
101 goto exit; 104 goto exit;
102 } 105 }
103 106