diff options
Diffstat (limited to 'arch/arm/mach-omap2')
30 files changed, 354 insertions, 145 deletions
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index d965da45160e..21a4095a1000 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -32,7 +32,7 @@ config ARCH_OMAP3 depends on ARCH_OMAP2PLUS default y select CPU_V7 - select USB_ARCH_HAS_EHCI + select USB_ARCH_HAS_EHCI if USB_SUPPORT select ARCH_HAS_OPP select PM_OPP if PM select ARM_CPU_SUSPEND if PM @@ -52,7 +52,7 @@ config ARCH_OMAP4 select ARM_ERRATA_720789 select ARCH_HAS_OPP select PM_OPP if PM - select USB_ARCH_HAS_EHCI + select USB_ARCH_HAS_EHCI if USB_SUPPORT select ARM_CPU_SUSPEND if PM comment "OMAP Core Type" @@ -364,8 +364,8 @@ config OMAP3_SDRC_AC_TIMING going on could result in system crashes; config OMAP4_ERRATA_I688 - bool "OMAP4 errata: Async Bridge Corruption (BROKEN)" - depends on ARCH_OMAP4 && BROKEN + bool "OMAP4 errata: Async Bridge Corruption" + depends on ARCH_OMAP4 select ARCH_HAS_BARRIERS help If a data is stalled inside asynchronous bridge because of back diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index bd76394ccaf8..56a6e98652cc 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -4,7 +4,7 @@ # Common support obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer.o pm.o \ - common.o gpio.o dma.o wd_timer.o display.o + common.o gpio.o dma.o wd_timer.o display.o i2c.o omap-2-3-common = irq.o sdrc.o hwmod-common = omap_hwmod.o \ @@ -182,9 +182,6 @@ obj-$(CONFIG_OMAP_IOMMU) += iommu2.o iommu-$(CONFIG_OMAP_IOMMU) := omap-iommu.o obj-y += $(iommu-m) $(iommu-y) -i2c-omap-$(CONFIG_I2C_OMAP) := i2c.o -obj-y += $(i2c-omap-m) $(i2c-omap-y) - ifneq ($(CONFIG_TIDSPBRIDGE),) obj-y += dsp.o endif diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c index ad497620539b..45fdfe2bd9d5 100644 --- a/arch/arm/mach-omap2/board-generic.c +++ b/arch/arm/mach-omap2/board-generic.c @@ -68,7 +68,7 @@ static void __init omap_generic_init(void) { struct device_node *node = of_find_matching_node(NULL, intc_match); if (node) - irq_domain_add_simple(node, 0); + irq_domain_add_legacy(node, 32, 0, 0, &irq_domain_simple_ops, NULL); omap_sdrc_init(NULL, NULL); diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c index 42a4d11fad23..672262717601 100644 --- a/arch/arm/mach-omap2/board-n8x0.c +++ b/arch/arm/mach-omap2/board-n8x0.c @@ -371,7 +371,11 @@ static void n8x0_mmc_callback(void *data, u8 card_mask) else *openp = 0; +#ifdef CONFIG_MMC_OMAP omap_mmc_notify_cover_event(mmc_device, index, *openp); +#else + pr_warn("MMC: notify cover event not available\n"); +#endif } static int n8x0_mmc_late_init(struct device *dev) diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c index c775bead1497..c877236a8442 100644 --- a/arch/arm/mach-omap2/board-omap3evm.c +++ b/arch/arm/mach-omap2/board-omap3evm.c @@ -381,7 +381,7 @@ static int omap3evm_twl_gpio_setup(struct device *dev, gpio_request_one(gpio + 7, GPIOF_OUT_INIT_LOW, "EN_DVI"); /* TWL4030_GPIO_MAX + 1 == ledB (out, active low LED) */ - gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1; + gpio_leds[0].gpio = gpio + TWL4030_GPIO_MAX + 1; platform_device_register(&leds_gpio); diff --git a/arch/arm/mach-omap2/board-zoom-display.c b/arch/arm/mach-omap2/board-zoom-display.c index d4683ba5f721..2a13b9f6c61c 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) static int zoom_set_bl_intensity(struct omap_dss_device *dssdev, int level) { +#ifdef CONFIG_TWL4030_CORE unsigned char c; u8 mux_pwm, enb_pwm; @@ -90,6 +91,9 @@ static int zoom_set_bl_intensity(struct omap_dss_device *dssdev, int level) c = ((50 * (100 - level)) / 100) + 1; twl_i2c_write_u8(TWL4030_MODULE_PWM1, 0x7F, TWL_LED_PWMOFF); twl_i2c_write_u8(TWL4030_MODULE_PWM1, c, TWL_LED_PWMON); +#else + pr_warn("Backlight not enabled\n"); +#endif return 0; } diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h index febffde2ff10..7e9338e8d684 100644 --- a/arch/arm/mach-omap2/common.h +++ b/arch/arm/mach-omap2/common.h @@ -132,6 +132,7 @@ void omap3_map_io(void); void am33xx_map_io(void); void omap4_map_io(void); void ti81xx_map_io(void); +void omap_barriers_init(void); /** * omap_test_timeout - busy-loop, testing a condition diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c index cfdbb86bc84e..72e018b9b260 100644 --- a/arch/arm/mach-omap2/cpuidle44xx.c +++ b/arch/arm/mach-omap2/cpuidle44xx.c @@ -65,7 +65,6 @@ static int omap4_enter_idle(struct cpuidle_device *dev, struct timespec ts_preidle, ts_postidle, ts_idle; u32 cpu1_state; int idle_time; - int new_state_idx; int cpu_id = smp_processor_id(); /* Used to keep track of the total time in idle */ @@ -84,8 +83,8 @@ static int omap4_enter_idle(struct cpuidle_device *dev, */ cpu1_state = pwrdm_read_pwrst(cpu1_pd); if (cpu1_state != PWRDM_POWER_OFF) { - new_state_idx = drv->safe_state_index; - cx = cpuidle_get_statedata(&dev->states_usage[new_state_idx]); + index = drv->safe_state_index; + cx = cpuidle_get_statedata(&dev->states_usage[index]); } if (index > 0) diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index 283d11eae693..3ffefe275ea0 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) /*-------------------------------------------------------------------------*/ #if defined(CONFIG_HDQ_MASTER_OMAP) || defined(CONFIG_HDQ_MASTER_OMAP_MODULE) -#if defined(CONFIG_SOC_OMAP2430) || defined(CONFIG_SOC_OMAP3430) #define OMAP_HDQ_BASE 0x480B2000 -#endif static struct resource omap_hdq_resources[] = { { .start = OMAP_HDQ_BASE, @@ -679,7 +677,10 @@ static struct platform_device omap_hdq_dev = { }; static inline void omap_hdq_init(void) { - (void) platform_device_register(&omap_hdq_dev); + if (cpu_is_omap2420()) + return; + + platform_device_register(&omap_hdq_dev); } #else static inline void omap_hdq_init(void) {} diff --git a/arch/arm/mach-omap2/emu.c b/arch/arm/mach-omap2/emu.c index 9c442e290ccb..ce91aad4cdad 100644 --- a/arch/arm/mach-omap2/emu.c +++ b/arch/arm/mach-omap2/emu.c @@ -30,29 +30,8 @@ MODULE_AUTHOR("Alexander Shishkin"); #define ETB_BASE (L4_EMU_34XX_PHYS + 0x1b000) #define DAPCTL (L4_EMU_34XX_PHYS + 0x1d000) -static struct amba_device omap3_etb_device = { - .dev = { - .init_name = "etb", - }, - .res = { - .start = ETB_BASE, - .end = ETB_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - .periphid = 0x000bb907, -}; - -static struct amba_device omap3_etm_device = { - .dev = { - .init_name = "etm", - }, - .res = { - .start = ETM_BASE, - .end = ETM_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - .periphid = 0x102bb921, -}; +static AMBA_APB_DEVICE(omap3_etb, "etb", 0x000bb907, ETB_BASE, { }, NULL); +static AMBA_APB_DEVICE(omap3_etm, "etm", 0x102bb921, ETM_BASE, { }, NULL); static int __init emu_init(void) { @@ -66,4 +45,3 @@ static int __init emu_init(void) } subsys_initcall(emu_init); - diff --git a/arch/arm/mach-omap2/gpmc-smsc911x.c b/arch/arm/mach-omap2/gpmc-smsc911x.c index 997033129d26..bbb870c04a5e 100644 --- a/arch/arm/mach-omap2/gpmc-smsc911x.c +++ b/arch/arm/mach-omap2/gpmc-smsc911x.c @@ -19,6 +19,8 @@ #include <linux/interrupt.h> #include <linux/io.h> #include <linux/smsc911x.h> +#include <linux/regulator/fixed.h> +#include <linux/regulator/machine.h> #include <plat/board.h> #include <plat/gpmc.h> @@ -42,6 +44,50 @@ static struct smsc911x_platform_config gpmc_smsc911x_config = { .flags = SMSC911X_USE_16BIT, }; +static struct regulator_consumer_supply gpmc_smsc911x_supply[] = { + REGULATOR_SUPPLY("vddvario", "smsc911x.0"), + REGULATOR_SUPPLY("vdd33a", "smsc911x.0"), +}; + +/* Generic regulator definition to satisfy smsc911x */ +static struct regulator_init_data gpmc_smsc911x_reg_init_data = { + .constraints = { + .min_uV = 3300000, + .max_uV = 3300000, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(gpmc_smsc911x_supply), + .consumer_supplies = gpmc_smsc911x_supply, +}; + +static struct fixed_voltage_config gpmc_smsc911x_fixed_reg_data = { + .supply_name = "gpmc_smsc911x", + .microvolts = 3300000, + .gpio = -EINVAL, + .startup_delay = 0, + .enable_high = 0, + .enabled_at_boot = 1, + .init_data = &gpmc_smsc911x_reg_init_data, +}; + +/* + * Platform device id of 42 is a temporary fix to avoid conflicts + * with other reg-fixed-voltage devices. The real fix should + * involve the driver core providing a way of dynamically + * assigning a unique id on registration for platform devices + * in the same name space. + */ +static struct platform_device gpmc_smsc911x_regulator = { + .name = "reg-fixed-voltage", + .id = 42, + .dev = { + .platform_data = &gpmc_smsc911x_fixed_reg_data, + }, +}; + /* * Initialize smsc911x device connected to the GPMC. Note that we * assume that pin multiplexing is done in the board-*.c file, @@ -55,6 +101,12 @@ void __init gpmc_smsc911x_init(struct omap_smsc911x_platform_data *board_data) gpmc_cfg = board_data; + ret = platform_device_register(&gpmc_smsc911x_regulator); + if (ret < 0) { + pr_err("Unable to register smsc911x regulators: %d\n", ret); + return; + } + if (gpmc_cs_request(gpmc_cfg->cs, SZ_16M, &cs_mem_base) < 0) { pr_err("Failed to request GPMC mem region\n"); return; diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c index b40c28895298..19dd1657245c 100644 --- a/arch/arm/mach-omap2/hsmmc.c +++ b/arch/arm/mach-omap2/hsmmc.c @@ -428,6 +428,7 @@ static int omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c, return 0; } +static int omap_hsmmc_done; #define MAX_OMAP_MMC_HWMOD_NAME_LEN 16 void omap_init_hsmmc(struct omap2_hsmmc_info *hsmmcinfo, int ctrl_nr) @@ -491,6 +492,11 @@ void omap2_hsmmc_init(struct omap2_hsmmc_info *controllers) { u32 reg; + if (omap_hsmmc_done) + return; + + omap_hsmmc_done = 1; + if (!cpu_is_omap44xx()) { if (cpu_is_omap2430()) { control_pbias_offset = OMAP243X_CONTROL_PBIAS_LITE; diff --git a/arch/arm/mach-omap2/include/mach/system.h b/arch/arm/mach-omap2/include/mach/system.h deleted file mode 100644 index d488721ab90b..000000000000 --- a/arch/arm/mach-omap2/include/mach/system.h +++ /dev/null @@ -1,5 +0,0 @@ -/* - * arch/arm/mach-omap2/include/mach/system.h - */ - -#include <plat/system.h> diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index eb50c29fb644..fb11b44fbdec 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -307,6 +307,7 @@ void __init omapam33xx_map_common_io(void) void __init omap44xx_map_common_io(void) { iotable_init(omap44xx_io_desc, ARRAY_SIZE(omap44xx_io_desc)); + omap_barriers_init(); } #endif diff --git a/arch/arm/mach-omap2/mailbox.c b/arch/arm/mach-omap2/mailbox.c index 609ea2ded7e3..2cc1aa004b94 100644 --- a/arch/arm/mach-omap2/mailbox.c +++ b/arch/arm/mach-omap2/mailbox.c @@ -281,8 +281,16 @@ static struct omap_mbox mbox_iva_info = { .ops = &omap2_mbox_ops, .priv = &omap2_mbox_iva_priv, }; +#endif -struct omap_mbox *omap2_mboxes[] = { &mbox_dsp_info, &mbox_iva_info, NULL }; +#ifdef CONFIG_ARCH_OMAP2 +struct omap_mbox *omap2_mboxes[] = { + &mbox_dsp_info, +#ifdef CONFIG_SOC_OMAP2420 + &mbox_iva_info, +#endif + NULL +}; #endif #if defined(CONFIG_ARCH_OMAP4) @@ -412,7 +420,8 @@ static void __exit omap2_mbox_exit(void) platform_driver_unregister(&omap2_mbox_driver); } -module_init(omap2_mbox_init); +/* must be ready before omap3isp is probed */ +subsys_initcall(omap2_mbox_init); module_exit(omap2_mbox_exit); MODULE_LICENSE("GPL v2"); diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c index fb8bc9fa43b1..611a0e3d54ca 100644 --- a/arch/arm/mach-omap2/mux.c +++ b/arch/arm/mach-omap2/mux.c @@ -218,7 +218,7 @@ static int _omap_mux_get_by_name(struct omap_mux_partition *partition, return -ENODEV; } -static int __init +static int omap_mux_get_by_name(const char *muxname, struct omap_mux_partition **found_partition, struct omap_mux **found_mux) diff --git a/arch/arm/mach-omap2/mux.h b/arch/arm/mach-omap2/mux.h index 2132308ad1e4..69fe060a0b75 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) { } -static struct omap_board_mux *board_mux __initdata __maybe_unused; +static struct omap_board_mux *board_mux __maybe_unused; #endif diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c index 40a8fbc07e4b..ebc595091312 100644 --- a/arch/arm/mach-omap2/omap4-common.c +++ b/arch/arm/mach-omap2/omap4-common.c @@ -24,6 +24,7 @@ #include <plat/irqs.h> #include <plat/sram.h> +#include <plat/omap-secure.h> #include <mach/hardware.h> #include <mach/omap-wakeupgen.h> @@ -43,6 +44,9 @@ static void __iomem *sar_ram_base; void __iomem *dram_sync, *sram_sync; +static phys_addr_t paddr; +static u32 size; + void omap_bus_sync(void) { if (dram_sync && sram_sync) { @@ -52,18 +56,20 @@ void omap_bus_sync(void) } } -static int __init omap_barriers_init(void) +/* Steal one page physical memory for barrier implementation */ +int __init omap_barrier_reserve_memblock(void) { - struct map_desc dram_io_desc[1]; - phys_addr_t paddr; - u32 size; - - if (!cpu_is_omap44xx()) - return -ENODEV; size = ALIGN(PAGE_SIZE, SZ_1M); paddr = arm_memblock_steal(size, SZ_1M); + return 0; +} + +void __init omap_barriers_init(void) +{ + struct map_desc dram_io_desc[1]; + dram_io_desc[0].virtual = OMAP4_DRAM_BARRIER_VA; dram_io_desc[0].pfn = __phys_to_pfn(paddr); dram_io_desc[0].length = size; @@ -75,9 +81,10 @@ static int __init omap_barriers_init(void) pr_info("OMAP4: Map 0x%08llx to 0x%08lx for dram barrier\n", (long long) paddr, dram_io_desc[0].virtual); - return 0; } -core_initcall(omap_barriers_init); +#else +void __init omap_barriers_init(void) +{} #endif void __init gic_init_irq(void) diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 3c8dd928628e..34b9766d1d23 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 @@ #include "omap_hwmod_common_data.h" +#include "smartreflex.h" #include "prm-regbits-34xx.h" #include "cm-regbits-34xx.h" #include "wd_timer.h" @@ -376,6 +377,16 @@ static struct omap_hwmod_ocp_if omap3_l4_core__i2c3 = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; +static struct omap_hwmod_irq_info omap3_smartreflex_mpu_irqs[] = { + { .irq = 18}, + { .irq = -1 } +}; + +static struct omap_hwmod_irq_info omap3_smartreflex_core_irqs[] = { + { .irq = 19}, + { .irq = -1 } +}; + /* L4 CORE -> SR1 interface */ static struct omap_hwmod_addr_space omap3_sr1_addr_space[] = { { @@ -2664,6 +2675,10 @@ static struct omap_hwmod_class omap36xx_smartreflex_hwmod_class = { }; /* SR1 */ +static struct omap_smartreflex_dev_attr sr1_dev_attr = { + .sensor_voltdm_name = "mpu_iva", +}; + static struct omap_hwmod_ocp_if *omap3_sr1_slaves[] = { &omap3_l4_core__sr1, }; @@ -2672,7 +2687,6 @@ static struct omap_hwmod omap34xx_sr1_hwmod = { .name = "sr1_hwmod", .class = &omap34xx_smartreflex_hwmod_class, .main_clk = "sr1_fck", - .vdd_name = "mpu_iva", .prcm = { .omap2 = { .prcm_reg_id = 1, @@ -2684,6 +2698,8 @@ static struct omap_hwmod omap34xx_sr1_hwmod = { }, .slaves = omap3_sr1_slaves, .slaves_cnt = ARRAY_SIZE(omap3_sr1_slaves), + .dev_attr = &sr1_dev_attr, + .mpu_irqs = omap3_smartreflex_mpu_irqs, .flags = HWMOD_SET_DEFAULT_CLOCKACT, }; @@ -2691,7 +2707,6 @@ static struct omap_hwmod omap36xx_sr1_hwmod = { .name = "sr1_hwmod", .class = &omap36xx_smartreflex_hwmod_class, .main_clk = "sr1_fck", - .vdd_name = "mpu_iva", .prcm = { .omap2 = { .prcm_reg_id = 1, @@ -2703,9 +2718,15 @@ static struct omap_hwmod omap36xx_sr1_hwmod = { }, .slaves = omap3_sr1_slaves, .slaves_cnt = ARRAY_SIZE(omap3_sr1_slaves), + .dev_attr = &sr1_dev_attr, + .mpu_irqs = omap3_smartreflex_mpu_irqs, }; /* SR2 */ +static struct omap_smartreflex_dev_attr sr2_dev_attr = { + .sensor_voltdm_name = "core", +}; + static struct omap_hwmod_ocp_if *omap3_sr2_slaves[] = { &omap3_l4_core__sr2, }; @@ -2714,7 +2735,6 @@ static struct omap_hwmod omap34xx_sr2_hwmod = { .name = "sr2_hwmod", .class = &omap34xx_smartreflex_hwmod_class, .main_clk = "sr2_fck", - .vdd_name = "core", .prcm = { .omap2 = { .prcm_reg_id = 1, @@ -2726,6 +2746,8 @@ static struct omap_hwmod omap34xx_sr2_hwmod = { }, .slaves = omap3_sr2_slaves, .slaves_cnt = ARRAY_SIZE(omap3_sr2_slaves), + .dev_attr = &sr2_dev_attr, + .mpu_irqs = omap3_smartreflex_core_irqs, .flags = HWMOD_SET_DEFAULT_CLOCKACT, }; @@ -2733,7 +2755,6 @@ static struct omap_hwmod omap36xx_sr2_hwmod = { .name = "sr2_hwmod", .class = &omap36xx_smartreflex_hwmod_class, .main_clk = "sr2_fck", - .vdd_name = "core", .prcm = { .omap2 = { .prcm_reg_id = 1, @@ -2745,6 +2766,8 @@ static struct omap_hwmod omap36xx_sr2_hwmod = { }, .slaves = omap3_sr2_slaves, .slaves_cnt = ARRAY_SIZE(omap3_sr2_slaves), + .dev_attr = &sr2_dev_attr, + .mpu_irqs = omap3_smartreflex_core_irqs, }; /* diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index ef0524c10a84..ee3624bd1996 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 @@ #include "omap_hwmod_common_data.h" +#include "smartreflex.h" #include "cm1_44xx.h" #include "cm2_44xx.h" #include "prm44xx.h" @@ -3963,6 +3964,10 @@ static struct omap_hwmod_class omap44xx_smartreflex_hwmod_class = { }; /* smartreflex_core */ +static struct omap_smartreflex_dev_attr smartreflex_core_dev_attr = { + .sensor_voltdm_name = "core", +}; + static struct omap_hwmod omap44xx_smartreflex_core_hwmod; static struct omap_hwmod_irq_info omap44xx_smartreflex_core_irqs[] = { { .irq = 19 + OMAP44XX_IRQ_GIC_START }, @@ -3999,7 +4004,6 @@ static struct omap_hwmod omap44xx_smartreflex_core_hwmod = { .mpu_irqs = omap44xx_smartreflex_core_irqs, .main_clk = "smartreflex_core_fck", - .vdd_name = "core", .prcm = { .omap4 = { .clkctrl_offs = OMAP4_CM_ALWON_SR_CORE_CLKCTRL_OFFSET, @@ -4009,9 +4013,14 @@ static struct omap_hwmod omap44xx_smartreflex_core_hwmod = { }, .slaves = omap44xx_smartreflex_core_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_smartreflex_core_slaves), + .dev_attr = &smartreflex_core_dev_attr, }; /* smartreflex_iva */ +static struct omap_smartreflex_dev_attr smartreflex_iva_dev_attr = { + .sensor_voltdm_name = "iva", +}; + static struct omap_hwmod omap44xx_smartreflex_iva_hwmod; static struct omap_hwmod_irq_info omap44xx_smartreflex_iva_irqs[] = { { .irq = 102 + OMAP44XX_IRQ_GIC_START }, @@ -4047,7 +4056,6 @@ static struct omap_hwmod omap44xx_smartreflex_iva_hwmod = { .clkdm_name = "l4_ao_clkdm", .mpu_irqs = omap44xx_smartreflex_iva_irqs, .main_clk = "smartreflex_iva_fck", - .vdd_name = "iva", .prcm = { .omap4 = { .clkctrl_offs = OMAP4_CM_ALWON_SR_IVA_CLKCTRL_OFFSET, @@ -4057,9 +4065,14 @@ static struct omap_hwmod omap44xx_smartreflex_iva_hwmod = { }, .slaves = omap44xx_smartreflex_iva_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_smartreflex_iva_slaves), + .dev_attr = &smartreflex_iva_dev_attr, }; /* smartreflex_mpu */ +static struct omap_smartreflex_dev_attr smartreflex_mpu_dev_attr = { + .sensor_voltdm_name = "mpu", +}; + static struct omap_hwmod omap44xx_smartreflex_mpu_hwmod; static struct omap_hwmod_irq_info omap44xx_smartreflex_mpu_irqs[] = { { .irq = 18 + OMAP44XX_IRQ_GIC_START }, @@ -4095,7 +4108,6 @@ static struct omap_hwmod omap44xx_smartreflex_mpu_hwmod = { .clkdm_name = "l4_ao_clkdm", .mpu_irqs = omap44xx_smartreflex_mpu_irqs, .main_clk = "smartreflex_mpu_fck", - .vdd_name = "mpu", .prcm = { .omap4 = { .clkctrl_offs = OMAP4_CM_ALWON_SR_MPU_CLKCTRL_OFFSET, @@ -4105,6 +4117,7 @@ static struct omap_hwmod omap44xx_smartreflex_mpu_hwmod = { }, .slaves = omap44xx_smartreflex_mpu_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_smartreflex_mpu_slaves), + .dev_attr = &smartreflex_mpu_dev_attr, }; /* diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index 1881fe915149..5a65dd04aa38 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c @@ -174,14 +174,17 @@ static int __init omap2_set_init_voltage(char *vdd_name, char *clk_name, freq = clk->rate; clk_put(clk); + rcu_read_lock(); opp = opp_find_freq_ceil(dev, &freq); if (IS_ERR(opp)) { + rcu_read_unlock(); pr_err("%s: unable to find boot up OPP for vdd_%s\n", __func__, vdd_name); goto exit; } bootup_volt = opp_get_voltage(opp); + rcu_read_unlock(); if (!bootup_volt) { pr_err("%s: unable to find voltage corresponding " "to the bootup OPP for vdd_%s\n", __func__, vdd_name); diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c index 23de98d03841..a4eb5c280435 100644 --- a/arch/arm/mach-omap2/pm24xx.c +++ b/arch/arm/mach-omap2/pm24xx.c @@ -226,7 +226,6 @@ static int omap2_can_sleep(void) static void omap2_pm_idle(void) { - local_irq_disable(); local_fiq_disable(); if (!omap2_can_sleep()) { @@ -243,7 +242,6 @@ static void omap2_pm_idle(void) out: local_fiq_enable(); - local_irq_enable(); } #ifdef CONFIG_SUSPEND @@ -462,7 +460,7 @@ static int __init omap2_pm_init(void) } suspend_set_ops(&omap_pm_ops); - pm_idle = omap2_pm_idle; + arm_pm_idle = omap2_pm_idle; return 0; } diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index fc6987578920..b77df735fa6c 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -418,10 +418,9 @@ void omap_sram_idle(void) static void omap3_pm_idle(void) { - local_irq_disable(); local_fiq_disable(); - if (omap_irq_pending() || need_resched()) + if (omap_irq_pending()) goto out; trace_power_start(POWER_CSTATE, 1, smp_processor_id()); @@ -434,7 +433,6 @@ static void omap3_pm_idle(void) out: local_fiq_enable(); - local_irq_enable(); } #ifdef CONFIG_SUSPEND @@ -848,7 +846,7 @@ static int __init omap3_pm_init(void) suspend_set_ops(&omap_pm_ops); #endif /* CONFIG_SUSPEND */ - pm_idle = omap3_pm_idle; + arm_pm_idle = omap3_pm_idle; omap3_idle_init(); /* diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c index c264ef7219c1..c840689df24a 100644 --- a/arch/arm/mach-omap2/pm44xx.c +++ b/arch/arm/mach-omap2/pm44xx.c @@ -173,18 +173,16 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused) * omap_default_idle - OMAP4 default ilde routine.' * * Implements OMAP4 memory, IO ordering requirements which can't be addressed - * with default arch_idle() hook. Used by all CPUs with !CONFIG_CPUIDLE and + * with default cpu_do_idle() hook. Used by all CPUs with !CONFIG_CPUIDLE and * by secondary CPU with CONFIG_CPUIDLE. */ static void omap_default_idle(void) { - local_irq_disable(); local_fiq_disable(); omap_do_wfi(); local_fiq_enable(); - local_irq_enable(); } /** @@ -255,8 +253,8 @@ static int __init omap4_pm_init(void) suspend_set_ops(&omap_pm_ops); #endif /* CONFIG_SUSPEND */ - /* Overwrite the default arch_idle() */ - pm_idle = omap_default_idle; + /* Overwrite the default cpu_do_idle() */ + arm_pm_idle = omap_default_idle; omap4_idle_init(); diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c index 860118ab43e2..873b51d494ea 100644 --- a/arch/arm/mach-omap2/prm_common.c +++ b/arch/arm/mach-omap2/prm_common.c @@ -24,7 +24,6 @@ #include <linux/interrupt.h> #include <linux/slab.h> -#include <mach/system.h> #include <plat/common.h> #include <plat/prcm.h> #include <plat/irqs.h> diff --git a/arch/arm/mach-omap2/smartreflex-class3.c b/arch/arm/mach-omap2/smartreflex-class3.c index 53d9d0a5b39d..955566eefac4 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) static int sr_class3_disable(struct voltagedomain *voltdm, int is_volt_reset) { + sr_disable_errgen(voltdm); omap_vp_disable(voltdm); sr_disable(voltdm); if (is_volt_reset) diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c index 7e755bb0ffc4..008fbd7b9352 100644 --- a/arch/arm/mach-omap2/smartreflex.c +++ b/arch/arm/mach-omap2/smartreflex.c @@ -36,6 +36,12 @@ #define SR_DISABLE_TIMEOUT 200 struct omap_sr { + struct list_head node; + struct platform_device *pdev; + struct omap_sr_nvalue_table *nvalue_table; + struct voltagedomain *voltdm; + struct dentry *dbg_dir; + unsigned int irq; int srid; int ip_type; int nvalue_count; @@ -49,13 +55,7 @@ struct omap_sr { u32 senp_avgweight; u32 senp_mod; u32 senn_mod; - unsigned int irq; void __iomem *base; - struct platform_device *pdev; - struct list_head node; - struct omap_sr_nvalue_table *nvalue_table; - struct voltagedomain *voltdm; - struct dentry *dbg_dir; }; /* 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, u32 value) { u32 reg_val; - u32 errconfig_offs = 0, errconfig_mask = 0; - - reg_val = __raw_readl(sr->base + offset); - reg_val &= ~mask; /* * 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, * if they are currently set, but does allow the caller to write * those bits. */ - if (sr->ip_type == SR_TYPE_V1) { - errconfig_offs = ERRCONFIG_V1; - errconfig_mask = ERRCONFIG_STATUS_V1_MASK; - } else if (sr->ip_type == SR_TYPE_V2) { - errconfig_offs = ERRCONFIG_V2; - errconfig_mask = ERRCONFIG_VPBOUNDINTST_V2; - } + if (sr->ip_type == SR_TYPE_V1 && offset == ERRCONFIG_V1) + mask |= ERRCONFIG_STATUS_V1_MASK; + else if (sr->ip_type == SR_TYPE_V2 && offset == ERRCONFIG_V2) + mask |= ERRCONFIG_VPBOUNDINTST_V2; + + reg_val = __raw_readl(sr->base + offset); + reg_val &= ~mask; - if (offset == errconfig_offs) - reg_val &= ~errconfig_mask; + value &= mask; reg_val |= value; @@ -128,21 +123,28 @@ static struct omap_sr *_sr_lookup(struct voltagedomain *voltdm) static irqreturn_t sr_interrupt(int irq, void *data) { - struct omap_sr *sr_info = (struct omap_sr *)data; + struct omap_sr *sr_info = data; u32 status = 0; - if (sr_info->ip_type == SR_TYPE_V1) { + switch (sr_info->ip_type) { + case SR_TYPE_V1: /* Read the status bits */ status = sr_read_reg(sr_info, ERRCONFIG_V1); /* Clear them by writing back */ sr_write_reg(sr_info, ERRCONFIG_V1, status); - } else if (sr_info->ip_type == SR_TYPE_V2) { + break; + case SR_TYPE_V2: /* Read the status bits */ status = sr_read_reg(sr_info, IRQSTATUS); /* Clear them by writing back */ sr_write_reg(sr_info, IRQSTATUS, status); + break; + default: + dev_err(&sr_info->pdev->dev, "UNKNOWN IP type %d\n", + sr_info->ip_type); + return IRQ_NONE; } if (sr_class->notify) @@ -166,6 +168,7 @@ static void sr_set_clk_length(struct omap_sr *sr) __func__); return; } + sys_clk_speed = clk_get_rate(sys_ck); clk_put(sys_ck); @@ -267,7 +270,7 @@ static int sr_late_init(struct omap_sr *sr_info) goto error; } ret = request_irq(sr_info->irq, sr_interrupt, - 0, name, (void *)sr_info); + 0, name, sr_info); if (ret) goto error; disable_irq(sr_info->irq); @@ -288,12 +291,15 @@ error: "not function as desired\n", __func__); kfree(name); kfree(sr_info); + return ret; } static void sr_v1_disable(struct omap_sr *sr) { int timeout = 0; + int errconf_val = ERRCONFIG_MCUACCUMINTST | ERRCONFIG_MCUVALIDINTST | + ERRCONFIG_MCUBOUNDINTST; /* Enable MCUDisableAcknowledge interrupt */ sr_modify_reg(sr, ERRCONFIG_V1, @@ -302,13 +308,13 @@ static void sr_v1_disable(struct omap_sr *sr) /* SRCONFIG - disable SR */ sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, 0x0); - /* Disable all other SR interrupts and clear the status */ + /* Disable all other SR interrupts and clear the status as needed */ + if (sr_read_reg(sr, ERRCONFIG_V1) & ERRCONFIG_VPBOUNDINTST_V1) + errconf_val |= ERRCONFIG_VPBOUNDINTST_V1; sr_modify_reg(sr, ERRCONFIG_V1, (ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUVALIDINTEN | ERRCONFIG_MCUBOUNDINTEN | ERRCONFIG_VPBOUNDINTEN_V1), - (ERRCONFIG_MCUACCUMINTST | ERRCONFIG_MCUVALIDINTST | - ERRCONFIG_MCUBOUNDINTST | - ERRCONFIG_VPBOUNDINTST_V1)); + errconf_val); /* * Wait for SR to be disabled. @@ -337,9 +343,17 @@ static void sr_v2_disable(struct omap_sr *sr) /* SRCONFIG - disable SR */ sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, 0x0); - /* Disable all other SR interrupts and clear the status */ - sr_modify_reg(sr, ERRCONFIG_V2, ERRCONFIG_VPBOUNDINTEN_V2, + /* + * Disable all other SR interrupts and clear the status + * write to status register ONLY on need basis - only if status + * is set. + */ + if (sr_read_reg(sr, ERRCONFIG_V2) & ERRCONFIG_VPBOUNDINTST_V2) + sr_modify_reg(sr, ERRCONFIG_V2, ERRCONFIG_VPBOUNDINTEN_V2, ERRCONFIG_VPBOUNDINTST_V2); + else + sr_modify_reg(sr, ERRCONFIG_V2, ERRCONFIG_VPBOUNDINTEN_V2, + 0x0); sr_write_reg(sr, IRQENABLE_CLR, (IRQENABLE_MCUACCUMINT | IRQENABLE_MCUVALIDINT | IRQENABLE_MCUBOUNDSINT)); @@ -398,15 +412,16 @@ static u32 sr_retrieve_nvalue(struct omap_sr *sr, u32 efuse_offs) */ int sr_configure_errgen(struct voltagedomain *voltdm) { - u32 sr_config, sr_errconfig, errconfig_offs, vpboundint_en; - u32 vpboundint_st, senp_en = 0, senn_en = 0; + u32 sr_config, sr_errconfig, errconfig_offs; + u32 vpboundint_en, vpboundint_st; + u32 senp_en = 0, senn_en = 0; u8 senp_shift, senn_shift; struct omap_sr *sr = _sr_lookup(voltdm); if (IS_ERR(sr)) { pr_warning("%s: omap_sr struct for sr_%s not found\n", __func__, voltdm->name); - return -EINVAL; + return PTR_ERR(sr); } if (!sr->clk_length) @@ -418,20 +433,23 @@ int sr_configure_errgen(struct voltagedomain *voltdm) sr_config = (sr->clk_length << SRCONFIG_SRCLKLENGTH_SHIFT) | SRCONFIG_SENENABLE | SRCONFIG_ERRGEN_EN; - if (sr->ip_type == SR_TYPE_V1) { + switch (sr->ip_type) { + case SR_TYPE_V1: sr_config |= SRCONFIG_DELAYCTRL; senn_shift = SRCONFIG_SENNENABLE_V1_SHIFT; senp_shift = SRCONFIG_SENPENABLE_V1_SHIFT; errconfig_offs = ERRCONFIG_V1; vpboundint_en = ERRCONFIG_VPBOUNDINTEN_V1; vpboundint_st = ERRCONFIG_VPBOUNDINTST_V1; - } else if (sr->ip_type == SR_TYPE_V2) { + break; + case SR_TYPE_V2: senn_shift = SRCONFIG_SENNENABLE_V2_SHIFT; senp_shift = SRCONFIG_SENPENABLE_V2_SHIFT; errconfig_offs = ERRCONFIG_V2; vpboundint_en = ERRCONFIG_VPBOUNDINTEN_V2; vpboundint_st = ERRCONFIG_VPBOUNDINTST_V2; - } else { + break; + default: dev_err(&sr->pdev->dev, "%s: Trying to Configure smartreflex" "module without specifying the ip\n", __func__); return -EINVAL; @@ -447,8 +465,55 @@ int sr_configure_errgen(struct voltagedomain *voltdm) sr_errconfig); /* Enabling the interrupts if the ERROR module is used */ - sr_modify_reg(sr, errconfig_offs, - vpboundint_en, (vpboundint_en | vpboundint_st)); + sr_modify_reg(sr, errconfig_offs, (vpboundint_en | vpboundint_st), + vpboundint_en); + + return 0; +} + +/** + * sr_disable_errgen() - Disables SmartReflex AVS module's errgen component + * @voltdm: VDD pointer to which the SR module to be configured belongs to. + * + * This API is to be called from the smartreflex class driver to + * disable the error generator module inside the smartreflex module. + * + * Returns 0 on success and error value in case of failure. + */ +int sr_disable_errgen(struct voltagedomain *voltdm) +{ + u32 errconfig_offs; + u32 vpboundint_en, vpboundint_st; + struct omap_sr *sr = _sr_lookup(voltdm); + + if (IS_ERR(sr)) { + pr_warning("%s: omap_sr struct for sr_%s not found\n", + __func__, voltdm->name); + return PTR_ERR(sr); + } + + switch (sr->ip_type) { + case SR_TYPE_V1: + errconfig_offs = ERRCONFIG_V1; + vpboundint_en = ERRCONFIG_VPBOUNDINTEN_V1; + vpboundint_st = ERRCONFIG_VPBOUNDINTST_V1; + break; + case SR_TYPE_V2: + errconfig_offs = ERRCONFIG_V2; + vpboundint_en = ERRCONFIG_VPBOUNDINTEN_V2; + vpboundint_st = ERRCONFIG_VPBOUNDINTST_V2; + break; + default: + dev_err(&sr->pdev->dev, "%s: Trying to Configure smartreflex" + "module without specifying the ip\n", __func__); + return -EINVAL; + } + + /* Disable the interrupts of ERROR module */ + sr_modify_reg(sr, errconfig_offs, vpboundint_en | vpboundint_st, 0); + + /* Disable the Sensor and errorgen */ + sr_modify_reg(sr, SRCONFIG, SRCONFIG_SENENABLE | SRCONFIG_ERRGEN_EN, 0); return 0; } @@ -475,7 +540,7 @@ int sr_configure_minmax(struct voltagedomain *voltdm) if (IS_ERR(sr)) { pr_warning("%s: omap_sr struct for sr_%s not found\n", __func__, voltdm->name); - return -EINVAL; + return PTR_ERR(sr); } if (!sr->clk_length) @@ -488,14 +553,17 @@ int sr_configure_minmax(struct voltagedomain *voltdm) SRCONFIG_SENENABLE | (sr->accum_data << SRCONFIG_ACCUMDATA_SHIFT); - if (sr->ip_type == SR_TYPE_V1) { + switch (sr->ip_type) { + case SR_TYPE_V1: sr_config |= SRCONFIG_DELAYCTRL; senn_shift = SRCONFIG_SENNENABLE_V1_SHIFT; senp_shift = SRCONFIG_SENPENABLE_V1_SHIFT; - } else if (sr->ip_type == SR_TYPE_V2) { + break; + case SR_TYPE_V2: senn_shift = SRCONFIG_SENNENABLE_V2_SHIFT; senp_shift = SRCONFIG_SENPENABLE_V2_SHIFT; - } else { + break; + default: dev_err(&sr->pdev->dev, "%s: Trying to Configure smartreflex" "module without specifying the ip\n", __func__); return -EINVAL; @@ -511,20 +579,27 @@ int sr_configure_minmax(struct voltagedomain *voltdm) * Enabling the interrupts if MINMAXAVG module is used. * TODO: check if all the interrupts are mandatory */ - if (sr->ip_type == SR_TYPE_V1) { + switch (sr->ip_type) { + case SR_TYPE_V1: sr_modify_reg(sr, ERRCONFIG_V1, (ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUVALIDINTEN | ERRCONFIG_MCUBOUNDINTEN), (ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUACCUMINTST | ERRCONFIG_MCUVALIDINTEN | ERRCONFIG_MCUVALIDINTST | ERRCONFIG_MCUBOUNDINTEN | ERRCONFIG_MCUBOUNDINTST)); - } else if (sr->ip_type == SR_TYPE_V2) { + break; + case SR_TYPE_V2: sr_write_reg(sr, IRQSTATUS, IRQSTATUS_MCUACCUMINT | IRQSTATUS_MCVALIDINT | IRQSTATUS_MCBOUNDSINT | IRQSTATUS_MCUDISABLEACKINT); sr_write_reg(sr, IRQENABLE_SET, IRQENABLE_MCUACCUMINT | IRQENABLE_MCUVALIDINT | IRQENABLE_MCUBOUNDSINT | IRQENABLE_MCUDISABLEACKINT); + break; + default: + dev_err(&sr->pdev->dev, "%s: Trying to Configure smartreflex" + "module without specifying the ip\n", __func__); + return -EINVAL; } return 0; @@ -543,15 +618,15 @@ int sr_configure_minmax(struct voltagedomain *voltdm) */ int sr_enable(struct voltagedomain *voltdm, unsigned long volt) { - u32 nvalue_reciprocal; struct omap_volt_data *volt_data; struct omap_sr *sr = _sr_lookup(voltdm); + u32 nvalue_reciprocal; int ret; if (IS_ERR(sr)) { pr_warning("%s: omap_sr struct for sr_%s not found\n", __func__, voltdm->name); - return -EINVAL; + return PTR_ERR(sr); } volt_data = omap_voltage_get_voltdata(sr->voltdm, volt); @@ -559,7 +634,7 @@ int sr_enable(struct voltagedomain *voltdm, unsigned long volt) if (IS_ERR(volt_data)) { dev_warn(&sr->pdev->dev, "%s: Unable to get voltage table" "for nominal voltage %ld\n", __func__, volt); - return -ENODATA; + return PTR_ERR(volt_data); } nvalue_reciprocal = sr_retrieve_nvalue(sr, volt_data->sr_efuse_offs); @@ -617,10 +692,17 @@ void sr_disable(struct voltagedomain *voltdm) * disable the clocks. */ if (sr_read_reg(sr, SRCONFIG) & SRCONFIG_SRENABLE) { - if (sr->ip_type == SR_TYPE_V1) + switch (sr->ip_type) { + case SR_TYPE_V1: sr_v1_disable(sr); - else if (sr->ip_type == SR_TYPE_V2) + break; + case SR_TYPE_V2: sr_v2_disable(sr); + break; + default: + dev_err(&sr->pdev->dev, "UNKNOWN IP type %d\n", + sr->ip_type); + } } pm_runtime_put_sync_suspend(&sr->pdev->dev); @@ -779,10 +861,10 @@ void omap_sr_register_pmic(struct omap_sr_pmic_data *pmic_data) sr_pmic_data = pmic_data; } -/* PM Debug Fs enteries to enable disable smartreflex. */ +/* PM Debug FS entries to enable and disable smartreflex. */ static int omap_sr_autocomp_show(void *data, u64 *val) { - struct omap_sr *sr_info = (struct omap_sr *) data; + struct omap_sr *sr_info = data; if (!sr_info) { pr_warning("%s: omap_sr struct not found\n", __func__); @@ -796,7 +878,7 @@ static int omap_sr_autocomp_show(void *data, u64 *val) static int omap_sr_autocomp_store(void *data, u64 val) { - struct omap_sr *sr_info = (struct omap_sr *) data; + struct omap_sr *sr_info = data; if (!sr_info) { pr_warning("%s: omap_sr struct not found\n", __func__); @@ -804,7 +886,7 @@ static int omap_sr_autocomp_store(void *data, u64 val) } /* Sanity check */ - if (val && (val != 1)) { + if (val > 1) { pr_warning("%s: Invalid argument %lld\n", __func__, val); return -EINVAL; } @@ -821,11 +903,11 @@ static int omap_sr_autocomp_store(void *data, u64 val) } DEFINE_SIMPLE_ATTRIBUTE(pm_sr_fops, omap_sr_autocomp_show, - omap_sr_autocomp_store, "%llu\n"); + omap_sr_autocomp_store, "%llu\n"); static int __init omap_sr_probe(struct platform_device *pdev) { - struct omap_sr *sr_info = kzalloc(sizeof(struct omap_sr), GFP_KERNEL); + struct omap_sr *sr_info; struct omap_sr_data *pdata = pdev->dev.platform_data; struct resource *mem, *irq; struct dentry *nvalue_dir; @@ -833,12 +915,15 @@ static int __init omap_sr_probe(struct platform_device *pdev) int i, ret = 0; char *name; + sr_info = kzalloc(sizeof(struct omap_sr), GFP_KERNEL); if (!sr_info) { dev_err(&pdev->dev, "%s: unable to allocate sr_info\n", __func__); return -ENOMEM; } + platform_set_drvdata(pdev, sr_info); + if (!pdata) { dev_err(&pdev->dev, "%s: platform data missing\n", __func__); ret = -EINVAL; @@ -904,7 +989,7 @@ static int __init omap_sr_probe(struct platform_device *pdev) dev_info(&pdev->dev, "%s: SmartReflex driver initialized\n", __func__); if (!sr_dbg_dir) { sr_dbg_dir = debugfs_create_dir("smartreflex", NULL); - if (!sr_dbg_dir) { + if (IS_ERR_OR_NULL(sr_dbg_dir)) { ret = PTR_ERR(sr_dbg_dir); pr_err("%s:sr debugfs dir creation failed(%d)\n", __func__, ret); @@ -921,7 +1006,7 @@ static int __init omap_sr_probe(struct platform_device *pdev) } sr_info->dbg_dir = debugfs_create_dir(name, sr_dbg_dir); kfree(name); - if (IS_ERR(sr_info->dbg_dir)) { + if (IS_ERR_OR_NULL(sr_info->dbg_dir)) { dev_err(&pdev->dev, "%s: Unable to create debugfs directory\n", __func__); ret = PTR_ERR(sr_info->dbg_dir); @@ -938,7 +1023,7 @@ static int __init omap_sr_probe(struct platform_device *pdev) &sr_info->err_minlimit); nvalue_dir = debugfs_create_dir("nvalue", sr_info->dbg_dir); - if (IS_ERR(nvalue_dir)) { + if (IS_ERR_OR_NULL(nvalue_dir)) { dev_err(&pdev->dev, "%s: Unable to create debugfs directory" "for n-values\n", __func__); ret = PTR_ERR(nvalue_dir); @@ -994,7 +1079,7 @@ static int __devexit omap_sr_remove(struct platform_device *pdev) if (IS_ERR(sr_info)) { dev_warn(&pdev->dev, "%s: omap_sr struct not found\n", __func__); - return -EINVAL; + return PTR_ERR(sr_info); } if (sr_info->autocomp_active) @@ -1011,8 +1096,32 @@ static int __devexit omap_sr_remove(struct platform_device *pdev) return 0; } +static void __devexit omap_sr_shutdown(struct platform_device *pdev) +{ + struct omap_sr_data *pdata = pdev->dev.platform_data; + struct omap_sr *sr_info; + + if (!pdata) { + dev_err(&pdev->dev, "%s: platform data missing\n", __func__); + return; + } + + sr_info = _sr_lookup(pdata->voltdm); + if (IS_ERR(sr_info)) { + dev_warn(&pdev->dev, "%s: omap_sr struct not found\n", + __func__); + return; + } + + if (sr_info->autocomp_active) + sr_stop_vddautocomp(sr_info); + + return; +} + static struct platform_driver smartreflex_driver = { - .remove = omap_sr_remove, + .remove = __devexit_p(omap_sr_remove), + .shutdown = __devexit_p(omap_sr_shutdown), .driver = { .name = "smartreflex", }, @@ -1042,12 +1151,12 @@ static int __init sr_init(void) return 0; } +late_initcall(sr_init); static void __exit sr_exit(void) { platform_driver_unregister(&smartreflex_driver); } -late_initcall(sr_init); module_exit(sr_exit); MODULE_DESCRIPTION("OMAP Smartreflex Driver"); diff --git a/arch/arm/mach-omap2/smartreflex.h b/arch/arm/mach-omap2/smartreflex.h index 5f35b9e25556..5809141171f8 100644 --- a/arch/arm/mach-omap2/smartreflex.h +++ b/arch/arm/mach-omap2/smartreflex.h @@ -152,6 +152,15 @@ struct omap_sr_pmic_data { void (*sr_pmic_init) (void); }; +/** + * struct omap_smartreflex_dev_attr - Smartreflex Device attribute. + * + * @sensor_voltdm_name: Name of voltdomain of SR instance + */ +struct omap_smartreflex_dev_attr { + const char *sensor_voltdm_name; +}; + #ifdef CONFIG_OMAP_SMARTREFLEX /* * 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); int sr_enable(struct voltagedomain *voltdm, unsigned long volt); void sr_disable(struct voltagedomain *voltdm); int sr_configure_errgen(struct voltagedomain *voltdm); +int sr_disable_errgen(struct voltagedomain *voltdm); int sr_configure_minmax(struct voltagedomain *voltdm); /* 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 9f43fcc05d3e..60293370a2a7 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) struct omap_sr_data *sr_data; struct platform_device *pdev; struct omap_volt_data *volt_data; + struct omap_smartreflex_dev_attr *sr_dev_attr; char *name = "smartreflex"; static int i; @@ -84,9 +85,11 @@ static int sr_dev_init(struct omap_hwmod *oh, void *user) return -ENOMEM; } - if (!oh->vdd_name) { + sr_dev_attr = (struct omap_smartreflex_dev_attr *)oh->dev_attr; + if (!sr_dev_attr || !sr_dev_attr->sensor_voltdm_name) { pr_err("%s: No voltage domain specified for %s." - "Cannot initialize\n", __func__, oh->name); + "Cannot initialize\n", __func__, + oh->name); goto exit; } @@ -94,10 +97,10 @@ static int sr_dev_init(struct omap_hwmod *oh, void *user) sr_data->senn_mod = 0x1; sr_data->senp_mod = 0x1; - sr_data->voltdm = voltdm_lookup(oh->vdd_name); + sr_data->voltdm = voltdm_lookup(sr_dev_attr->sensor_voltdm_name); if (IS_ERR(sr_data->voltdm)) { pr_err("%s: Unable to get voltage domain pointer for VDD %s\n", - __func__, oh->vdd_name); + __func__, sr_dev_attr->sensor_voltdm_name); goto exit; } diff --git a/arch/arm/mach-omap2/usb-host.c b/arch/arm/mach-omap2/usb-host.c index 771dc781b746..f51348dafafd 100644 --- a/arch/arm/mach-omap2/usb-host.c +++ b/arch/arm/mach-omap2/usb-host.c @@ -486,7 +486,7 @@ static void setup_4430ohci_io_mux(const enum usbhs_omap_port_mode *port_mode) void __init usbhs_init(const struct usbhs_omap_board_data *pdata) { struct omap_hwmod *oh[2]; - struct omap_device *od; + struct platform_device *pdev; int bus_id = -1; int i; @@ -522,11 +522,11 @@ void __init usbhs_init(const struct usbhs_omap_board_data *pdata) return; } - od = omap_device_build_ss(OMAP_USBHS_DEVICE, bus_id, oh, 2, + pdev = omap_device_build_ss(OMAP_USBHS_DEVICE, bus_id, oh, 2, (void *)&usbhs_data, sizeof(usbhs_data), omap_uhhtll_latency, ARRAY_SIZE(omap_uhhtll_latency), false); - if (IS_ERR(od)) { + if (IS_ERR(pdev)) { pr_err("Could not build hwmod devices %s,%s\n", USBHS_UHH_HWMODNAME, USBHS_TLL_HWMODNAME); return; |