diff --git a/[refs] b/[refs] index a76a6a3029ad..2ccb4b632151 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 172c11351576cf5daa8f1b02a265bf84de8bbed1 +refs/heads/master: 57e6fe7b888e17f814bd35b7700ded51aa9a6a83 diff --git a/trunk/arch/arm/mach-omap1/board-htcherald.c b/trunk/arch/arm/mach-omap1/board-htcherald.c index 7ea75c11653c..311899ff5ffc 100644 --- a/trunk/arch/arm/mach-omap1/board-htcherald.c +++ b/trunk/arch/arm/mach-omap1/board-htcherald.c @@ -30,13 +30,6 @@ #include #include #include -#include -#include -#include -#include -#include -#include -#include #include #include @@ -46,7 +39,6 @@ #include #include #include -#include #include @@ -60,123 +52,13 @@ #define OMAP_LCDC_CTRL_LCD_EN (1 << 0) #define OMAP_LCDC_STAT_DONE (1 << 0) -/* GPIO definitions for the power button and keyboard slide switch */ -#define HTCHERALD_GPIO_POWER 139 -#define HTCHERALD_GPIO_SLIDE 174 -#define HTCHERALD_GIRQ_BTNS 141 - -/* GPIO definitions for the touchscreen */ -#define HTCHERALD_GPIO_TS 76 - -/* HTCPLD definitions */ - -/* - * CPLD Logic - * - * Chip 3 - 0x03 - * - * Function 7 6 5 4 3 2 1 0 - * ------------------------------------ - * DPAD light x x x x x x x 1 - * SoundDev x x x x 1 x x x - * Screen white 1 x x x x x x x - * MMC power on x x x x x 1 x x - * Happy times (n) 0 x x x x 1 x x - * - * Chip 4 - 0x04 - * - * Function 7 6 5 4 3 2 1 0 - * ------------------------------------ - * Keyboard light x x x x x x x 1 - * LCD Bright (4) x x x x x 1 1 x - * LCD Bright (3) x x x x x 0 1 x - * LCD Bright (2) x x x x x 1 0 x - * LCD Bright (1) x x x x x 0 0 x - * LCD Off x x x x 0 x x x - * LCD image (fb) 1 x x x x x x x - * LCD image (white) 0 x x x x x x x - * Caps lock LED x x 1 x x x x x - * - * Chip 5 - 0x05 - * - * Function 7 6 5 4 3 2 1 0 - * ------------------------------------ - * Red (solid) x x x x x 1 x x - * Red (flash) x x x x x x 1 x - * Green (GSM flash) x x x x 1 x x x - * Green (GSM solid) x x x 1 x x x x - * Green (wifi flash) x x 1 x x x x x - * Blue (bt flash) x 1 x x x x x x - * DPAD Int Enable 1 x x x x x x 0 - * - * (Combinations of the above can be made for different colors.) - * The direction pad interrupt enable must be set each time the - * interrupt is handled. - * - * Chip 6 - 0x06 - * - * Function 7 6 5 4 3 2 1 0 - * ------------------------------------ - * Vibrator x x x x 1 x x x - * Alt LED x x x 1 x x x x - * Screen white 1 x x x x x x x - * Screen white x x 1 x x x x x - * Screen white x 0 x x x x x x - * Enable kbd dpad x x x x x x 0 x - * Happy Times 0 1 0 x x x 0 x - */ - -/* - * HTCPLD GPIO lines start 16 after OMAP_MAX_GPIO_LINES to account - * for the 16 MPUIO lines. - */ -#define HTCPLD_GPIO_START_OFFSET (OMAP_MAX_GPIO_LINES + 16) -#define HTCPLD_IRQ(chip, offset) (OMAP_IRQ_END + 8 * (chip) + (offset)) -#define HTCPLD_BASE(chip, offset) \ - (HTCPLD_GPIO_START_OFFSET + 8 * (chip) + (offset)) - -#define HTCPLD_GPIO_LED_DPAD HTCPLD_BASE(0, 0) -#define HTCPLD_GPIO_LED_KBD HTCPLD_BASE(1, 0) -#define HTCPLD_GPIO_LED_CAPS HTCPLD_BASE(1, 5) -#define HTCPLD_GPIO_LED_RED_FLASH HTCPLD_BASE(2, 1) -#define HTCPLD_GPIO_LED_RED_SOLID HTCPLD_BASE(2, 2) -#define HTCPLD_GPIO_LED_GREEN_FLASH HTCPLD_BASE(2, 3) -#define HTCPLD_GPIO_LED_GREEN_SOLID HTCPLD_BASE(2, 4) -#define HTCPLD_GPIO_LED_WIFI HTCPLD_BASE(2, 5) -#define HTCPLD_GPIO_LED_BT HTCPLD_BASE(2, 6) -#define HTCPLD_GPIO_LED_VIBRATE HTCPLD_BASE(3, 3) -#define HTCPLD_GPIO_LED_ALT HTCPLD_BASE(3, 4) - -#define HTCPLD_GPIO_RIGHT_KBD HTCPLD_BASE(6, 7) -#define HTCPLD_GPIO_UP_KBD HTCPLD_BASE(6, 6) -#define HTCPLD_GPIO_LEFT_KBD HTCPLD_BASE(6, 5) -#define HTCPLD_GPIO_DOWN_KBD HTCPLD_BASE(6, 4) - -#define HTCPLD_GPIO_RIGHT_DPAD HTCPLD_BASE(7, 7) -#define HTCPLD_GPIO_UP_DPAD HTCPLD_BASE(7, 6) -#define HTCPLD_GPIO_LEFT_DPAD HTCPLD_BASE(7, 5) -#define HTCPLD_GPIO_DOWN_DPAD HTCPLD_BASE(7, 4) -#define HTCPLD_GPIO_ENTER_DPAD HTCPLD_BASE(7, 3) +static struct omap_lcd_config htcherald_lcd_config __initdata = { + .ctrl_name = "internal", +}; -/* - * The htcpld chip requires a gpio write to a specific line - * to re-enable interrupts after one has occurred. - */ -#define HTCPLD_GPIO_INT_RESET_HI HTCPLD_BASE(2, 7) -#define HTCPLD_GPIO_INT_RESET_LO HTCPLD_BASE(2, 0) - -/* Chip 5 */ -#define HTCPLD_IRQ_RIGHT_KBD HTCPLD_IRQ(0, 7) -#define HTCPLD_IRQ_UP_KBD HTCPLD_IRQ(0, 6) -#define HTCPLD_IRQ_LEFT_KBD HTCPLD_IRQ(0, 5) -#define HTCPLD_IRQ_DOWN_KBD HTCPLD_IRQ(0, 4) - -/* Chip 6 */ -#define HTCPLD_IRQ_RIGHT_DPAD HTCPLD_IRQ(1, 7) -#define HTCPLD_IRQ_UP_DPAD HTCPLD_IRQ(1, 6) -#define HTCPLD_IRQ_LEFT_DPAD HTCPLD_IRQ(1, 5) -#define HTCPLD_IRQ_DOWN_DPAD HTCPLD_IRQ(1, 4) -#define HTCPLD_IRQ_ENTER_DPAD HTCPLD_IRQ(1, 3) +static struct omap_board_config_kernel htcherald_config[] __initdata = { + { OMAP_TAG_LCD, &htcherald_lcd_config }, +}; /* Keyboard definition */ @@ -258,129 +140,6 @@ static struct platform_device kp_device = { .resource = kp_resources, }; -/* GPIO buttons for keyboard slide and power button */ -static struct gpio_keys_button herald_gpio_keys_table[] = { - {BTN_0, HTCHERALD_GPIO_POWER, 1, "POWER", EV_KEY, 1, 20}, - {SW_LID, HTCHERALD_GPIO_SLIDE, 0, "SLIDE", EV_SW, 1, 20}, - - {KEY_LEFT, HTCPLD_GPIO_LEFT_KBD, 1, "LEFT", EV_KEY, 1, 20}, - {KEY_RIGHT, HTCPLD_GPIO_RIGHT_KBD, 1, "RIGHT", EV_KEY, 1, 20}, - {KEY_UP, HTCPLD_GPIO_UP_KBD, 1, "UP", EV_KEY, 1, 20}, - {KEY_DOWN, HTCPLD_GPIO_DOWN_KBD, 1, "DOWN", EV_KEY, 1, 20}, - - {KEY_LEFT, HTCPLD_GPIO_LEFT_DPAD, 1, "DLEFT", EV_KEY, 1, 20}, - {KEY_RIGHT, HTCPLD_GPIO_RIGHT_DPAD, 1, "DRIGHT", EV_KEY, 1, 20}, - {KEY_UP, HTCPLD_GPIO_UP_DPAD, 1, "DUP", EV_KEY, 1, 20}, - {KEY_DOWN, HTCPLD_GPIO_DOWN_DPAD, 1, "DDOWN", EV_KEY, 1, 20}, - {KEY_ENTER, HTCPLD_GPIO_ENTER_DPAD, 1, "DENTER", EV_KEY, 1, 20}, -}; - -static struct gpio_keys_platform_data herald_gpio_keys_data = { - .buttons = herald_gpio_keys_table, - .nbuttons = ARRAY_SIZE(herald_gpio_keys_table), - .rep = 1, -}; - -static struct platform_device herald_gpiokeys_device = { - .name = "gpio-keys", - .id = -1, - .dev = { - .platform_data = &herald_gpio_keys_data, - }, -}; - -/* LEDs for the Herald. These connect to the HTCPLD GPIO device. */ -static struct gpio_led gpio_leds[] = { - {"dpad", NULL, HTCPLD_GPIO_LED_DPAD, 0, 0, LEDS_GPIO_DEFSTATE_OFF}, - {"kbd", NULL, HTCPLD_GPIO_LED_KBD, 0, 0, LEDS_GPIO_DEFSTATE_OFF}, - {"vibrate", NULL, HTCPLD_GPIO_LED_VIBRATE, 0, 0, LEDS_GPIO_DEFSTATE_OFF}, - {"green_solid", NULL, HTCPLD_GPIO_LED_GREEN_SOLID, 0, 0, LEDS_GPIO_DEFSTATE_OFF}, - {"green_flash", NULL, HTCPLD_GPIO_LED_GREEN_FLASH, 0, 0, LEDS_GPIO_DEFSTATE_OFF}, - {"red_solid", "mmc0", HTCPLD_GPIO_LED_RED_SOLID, 0, 0, LEDS_GPIO_DEFSTATE_OFF}, - {"red_flash", NULL, HTCPLD_GPIO_LED_RED_FLASH, 0, 0, LEDS_GPIO_DEFSTATE_OFF}, - {"wifi", NULL, HTCPLD_GPIO_LED_WIFI, 0, 0, LEDS_GPIO_DEFSTATE_OFF}, - {"bt", NULL, HTCPLD_GPIO_LED_BT, 0, 0, LEDS_GPIO_DEFSTATE_OFF}, - {"caps", NULL, HTCPLD_GPIO_LED_CAPS, 0, 0, LEDS_GPIO_DEFSTATE_OFF}, - {"alt", NULL, HTCPLD_GPIO_LED_ALT, 0, 0, LEDS_GPIO_DEFSTATE_OFF}, -}; - -static struct gpio_led_platform_data gpio_leds_data = { - .leds = gpio_leds, - .num_leds = ARRAY_SIZE(gpio_leds), -}; - -static struct platform_device gpio_leds_device = { - .name = "leds-gpio", - .id = 0, - .dev = { - .platform_data = &gpio_leds_data, - }, -}; - -/* HTC PLD chips */ - -static struct resource htcpld_resources[] = { - [0] = { - .start = OMAP_GPIO_IRQ(HTCHERALD_GIRQ_BTNS), - .end = OMAP_GPIO_IRQ(HTCHERALD_GIRQ_BTNS), - .flags = IORESOURCE_IRQ, - }, -}; - -struct htcpld_chip_platform_data htcpld_chips[] = { - [0] = { - .addr = 0x03, - .reset = 0x04, - .num_gpios = 8, - .gpio_out_base = HTCPLD_BASE(0, 0), - .gpio_in_base = HTCPLD_BASE(4, 0), - }, - [1] = { - .addr = 0x04, - .reset = 0x8e, - .num_gpios = 8, - .gpio_out_base = HTCPLD_BASE(1, 0), - .gpio_in_base = HTCPLD_BASE(5, 0), - }, - [2] = { - .addr = 0x05, - .reset = 0x80, - .num_gpios = 8, - .gpio_out_base = HTCPLD_BASE(2, 0), - .gpio_in_base = HTCPLD_BASE(6, 0), - .irq_base = HTCPLD_IRQ(0, 0), - .num_irqs = 8, - }, - [3] = { - .addr = 0x06, - .reset = 0x40, - .num_gpios = 8, - .gpio_out_base = HTCPLD_BASE(3, 0), - .gpio_in_base = HTCPLD_BASE(7, 0), - .irq_base = HTCPLD_IRQ(1, 0), - .num_irqs = 8, - }, -}; - -struct htcpld_core_platform_data htcpld_pfdata = { - .int_reset_gpio_hi = HTCPLD_GPIO_INT_RESET_HI, - .int_reset_gpio_lo = HTCPLD_GPIO_INT_RESET_LO, - .i2c_adapter_id = 1, - - .chip = htcpld_chips, - .num_chip = ARRAY_SIZE(htcpld_chips), -}; - -static struct platform_device htcpld_device = { - .name = "i2c-htcpld", - .id = -1, - .resource = htcpld_resources, - .num_resources = ARRAY_SIZE(htcpld_resources), - .dev = { - .platform_data = &htcpld_pfdata, - }, -}; - /* USB Device */ static struct omap_usb_config htcherald_usb_config __initdata = { .otg = 0, @@ -391,72 +150,14 @@ static struct omap_usb_config htcherald_usb_config __initdata = { }; /* LCD Device resources */ -static struct omap_lcd_config htcherald_lcd_config __initdata = { - .ctrl_name = "internal", -}; - -static struct omap_board_config_kernel htcherald_config[] __initdata = { - { OMAP_TAG_LCD, &htcherald_lcd_config }, -}; - static struct platform_device lcd_device = { .name = "lcd_htcherald", .id = -1, }; -/* MMC Card */ -#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) -static struct omap_mmc_platform_data htc_mmc1_data = { - .nr_slots = 1, - .switch_slot = NULL, - .slots[0] = { - .ocr_mask = MMC_VDD_28_29 | MMC_VDD_30_31 | - MMC_VDD_32_33 | MMC_VDD_33_34, - .name = "mmcblk", - .nomux = 1, - .wires = 4, - .switch_pin = -1, - }, -}; - -static struct omap_mmc_platform_data *htc_mmc_data[1]; -#endif - - -/* Platform devices for the Herald */ static struct platform_device *devices[] __initdata = { &kp_device, &lcd_device, - &htcpld_device, - &gpio_leds_device, - &herald_gpiokeys_device, -}; - -/* - * Touchscreen - */ -static const struct ads7846_platform_data htcherald_ts_platform_data = { - .model = 7846, - .keep_vref_on = 1, - .x_plate_ohms = 496, - .gpio_pendown = HTCHERALD_GPIO_TS, - .pressure_max = 100000, - .pressure_min = 5000, - .x_min = 528, - .x_max = 3760, - .y_min = 624, - .y_max = 3760, -}; - -static struct spi_board_info __initdata htcherald_spi_board_info[] = { - { - .modalias = "ads7846", - .platform_data = &htcherald_ts_platform_data, - .irq = OMAP_GPIO_IRQ(HTCHERALD_GPIO_TS), - .max_speed_hz = 2500000, - .bus_num = 2, - .chip_select = 1, - } }; /* @@ -577,7 +278,6 @@ static void __init htcherald_init(void) { printk(KERN_INFO "HTC Herald init.\n"); - /* Do board initialization before we register all the devices */ omap_gpio_init(); omap_board_config = htcherald_config; @@ -588,16 +288,6 @@ static void __init htcherald_init(void) htcherald_usb_enable(); omap1_usb_init(&htcherald_usb_config); - - spi_register_board_info(htcherald_spi_board_info, - ARRAY_SIZE(htcherald_spi_board_info)); - - omap_register_i2c_bus(1, 100, NULL, 0); - -#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) - htc_mmc_data[0] = &htc_mmc1_data; - omap1_init_mmc(htc_mmc_data, 1); -#endif } static void __init htcherald_init_irq(void) diff --git a/trunk/arch/arm/mach-omap2/Makefile b/trunk/arch/arm/mach-omap2/Makefile index 826cb0980054..b48ca6039d83 100644 --- a/trunk/arch/arm/mach-omap2/Makefile +++ b/trunk/arch/arm/mach-omap2/Makefile @@ -5,7 +5,7 @@ # Common support obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer-gp.o pm.o -omap-2-3-common = irq.o sdrc.o prm2xxx_3xxx.o +omap-2-3-common = irq.o sdrc.o hwmod-common = omap_hwmod.o \ omap_hwmod_common_data.o prcm-common = prcm.o powerdomain.o @@ -15,7 +15,7 @@ clock-common = clock.o clock_common_data.o \ obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(prcm-common) $(hwmod-common) obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(prcm-common) $(hwmod-common) -obj-$(CONFIG_ARCH_OMAP4) += $(prcm-common) prm44xx.o $(hwmod-common) +obj-$(CONFIG_ARCH_OMAP4) += $(prcm-common) $(hwmod-common) obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o @@ -49,14 +49,18 @@ obj-$(CONFIG_ARCH_OMAP2) += sdrc2xxx.o # Power Management ifeq ($(CONFIG_PM),y) obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o -obj-$(CONFIG_ARCH_OMAP2) += sleep24xx.o -obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o cpuidle34xx.o -obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o +obj-$(CONFIG_ARCH_OMAP2) += sleep24xx.o pm_bus.o +obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o cpuidle34xx.o pm_bus.o +obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o pm_bus.o obj-$(CONFIG_PM_DEBUG) += pm-debug.o AFLAGS_sleep24xx.o :=-Wa,-march=armv6 AFLAGS_sleep34xx.o :=-Wa,-march=armv7-a +ifeq ($(CONFIG_PM_VERBOSE),y) +CFLAGS_pm_bus.o += -DDEBUG +endif + endif # PRCM @@ -87,7 +91,6 @@ obj-$(CONFIG_ARCH_OMAP2430) += opp2430_data.o obj-$(CONFIG_ARCH_OMAP2420) += omap_hwmod_2420_data.o obj-$(CONFIG_ARCH_OMAP2430) += omap_hwmod_2430_data.o obj-$(CONFIG_ARCH_OMAP3) += omap_hwmod_3xxx_data.o -obj-$(CONFIG_ARCH_OMAP4) += omap_hwmod_44xx_data.o # EMU peripherals obj-$(CONFIG_OMAP3_EMU) += emu.o diff --git a/trunk/arch/arm/mach-omap2/clockdomain.c b/trunk/arch/arm/mach-omap2/clockdomain.c index 6fb61b1a0d46..5d80cb897489 100644 --- a/trunk/arch/arm/mach-omap2/clockdomain.c +++ b/trunk/arch/arm/mach-omap2/clockdomain.c @@ -258,6 +258,97 @@ static void _omap2_clkdm_set_hwsup(struct clockdomain *clkdm, int enable) } +/** + * _init_wkdep_usecount - initialize wkdep usecounts to match hardware + * @clkdm: clockdomain to initialize wkdep usecounts + * + * Initialize the wakeup dependency usecount variables for clockdomain @clkdm. + * If a wakeup dependency is present in the hardware, the usecount will be + * set to 1; otherwise, it will be set to 0. Software should clear all + * software wakeup dependencies prior to calling this function if it wishes + * to ensure that all usecounts start at 0. No return value. + */ +static void _init_wkdep_usecount(struct clockdomain *clkdm) +{ + u32 v; + struct clkdm_dep *cd; + + if (!clkdm->wkdep_srcs) + return; + + for (cd = clkdm->wkdep_srcs; cd->clkdm_name; cd++) { + if (!omap_chip_is(cd->omap_chip)) + continue; + + if (!cd->clkdm && cd->clkdm_name) + cd->clkdm = _clkdm_lookup(cd->clkdm_name); + + if (!cd->clkdm) { + WARN(!cd->clkdm, "clockdomain: %s: wkdep clkdm %s not " + "found\n", clkdm->name, cd->clkdm_name); + continue; + } + + v = prm_read_mod_bits_shift(clkdm->pwrdm.ptr->prcm_offs, + PM_WKDEP, + (1 << cd->clkdm->dep_bit)); + + if (v) + pr_debug("clockdomain: %s: wakeup dependency already " + "set to wake up when %s wakes\n", + clkdm->name, cd->clkdm->name); + + atomic_set(&cd->wkdep_usecount, (v) ? 1 : 0); + } +} + +/** + * _init_sleepdep_usecount - initialize sleepdep usecounts to match hardware + * @clkdm: clockdomain to initialize sleepdep usecounts + * + * Initialize the sleep dependency usecount variables for clockdomain @clkdm. + * If a sleep dependency is present in the hardware, the usecount will be + * set to 1; otherwise, it will be set to 0. Software should clear all + * software sleep dependencies prior to calling this function if it wishes + * to ensure that all usecounts start at 0. No return value. + */ +static void _init_sleepdep_usecount(struct clockdomain *clkdm) +{ + u32 v; + struct clkdm_dep *cd; + + if (!cpu_is_omap34xx()) + return; + + if (!clkdm->sleepdep_srcs) + return; + + for (cd = clkdm->sleepdep_srcs; cd->clkdm_name; cd++) { + if (!omap_chip_is(cd->omap_chip)) + continue; + + if (!cd->clkdm && cd->clkdm_name) + cd->clkdm = _clkdm_lookup(cd->clkdm_name); + + if (!cd->clkdm) { + WARN(!cd->clkdm, "clockdomain: %s: sleepdep clkdm %s " + "not found\n", clkdm->name, cd->clkdm_name); + continue; + } + + v = prm_read_mod_bits_shift(clkdm->pwrdm.ptr->prcm_offs, + OMAP3430_CM_SLEEPDEP, + (1 << cd->clkdm->dep_bit)); + + if (v) + pr_debug("clockdomain: %s: sleep dependency already " + "set to prevent from idling until %s " + "idles\n", clkdm->name, cd->clkdm->name); + + atomic_set(&cd->sleepdep_usecount, (v) ? 1 : 0); + } +}; + /* Public functions */ /** @@ -288,17 +379,12 @@ void clkdm_init(struct clockdomain **clkdms, _autodep_lookup(autodep); /* - * Put all clockdomains into software-supervised mode; PM code - * should later enable hardware-supervised mode as appropriate + * Ensure that the *dep_usecount registers reflect the current + * state of the PRCM. */ list_for_each_entry(clkdm, &clkdm_list, node) { - if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP) - omap2_clkdm_wakeup(clkdm); - else if (clkdm->flags & CLKDM_CAN_DISABLE_AUTO) - omap2_clkdm_deny_idle(clkdm); - - clkdm_clear_all_wkdeps(clkdm); - clkdm_clear_all_sleepdeps(clkdm); + _init_wkdep_usecount(clkdm); + _init_sleepdep_usecount(clkdm); } } @@ -506,9 +592,6 @@ int clkdm_clear_all_wkdeps(struct clockdomain *clkdm) if (!omap_chip_is(cd->omap_chip)) continue; - if (!cd->clkdm && cd->clkdm_name) - cd->clkdm = _clkdm_lookup(cd->clkdm_name); - /* PRM accesses are slow, so minimize them */ mask |= 1 << cd->clkdm->dep_bit; atomic_set(&cd->wkdep_usecount, 0); @@ -669,9 +752,6 @@ int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm) if (!omap_chip_is(cd->omap_chip)) continue; - if (!cd->clkdm && cd->clkdm_name) - cd->clkdm = _clkdm_lookup(cd->clkdm_name); - /* PRM accesses are slow, so minimize them */ mask |= 1 << cd->clkdm->dep_bit; atomic_set(&cd->sleepdep_usecount, 0); diff --git a/trunk/arch/arm/mach-omap2/cpuidle34xx.c b/trunk/arch/arm/mach-omap2/cpuidle34xx.c index 8ea012ef0b5a..3d3d035db9af 100644 --- a/trunk/arch/arm/mach-omap2/cpuidle34xx.c +++ b/trunk/arch/arm/mach-omap2/cpuidle34xx.c @@ -60,8 +60,7 @@ struct omap3_processor_cx { struct omap3_processor_cx omap3_power_states[OMAP3_MAX_STATES]; struct omap3_processor_cx current_cx_state; -struct powerdomain *mpu_pd, *core_pd, *per_pd; -struct powerdomain *cam_pd; +struct powerdomain *mpu_pd, *core_pd; /* * The latencies/thresholds for various C states have @@ -234,62 +233,14 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev, struct cpuidle_state *state) { struct cpuidle_state *new_state = next_valid_state(dev, state); - u32 core_next_state, per_next_state = 0, per_saved_state = 0; - u32 cam_state; - struct omap3_processor_cx *cx; - int ret; if ((state->flags & CPUIDLE_FLAG_CHECK_BM) && omap3_idle_bm_check()) { BUG_ON(!dev->safe_state); new_state = dev->safe_state; - goto select_state; - } - - cx = cpuidle_get_statedata(state); - core_next_state = cx->core_state; - - /* - * FIXME: we currently manage device-specific idle states - * for PER and CORE in combination with CPU-specific - * idle states. This is wrong, and device-specific - * idle managment needs to be separated out into - * its own code. - */ - - /* - * Prevent idle completely if CAM is active. - * CAM does not have wakeup capability in OMAP3. - */ - cam_state = pwrdm_read_pwrst(cam_pd); - if (cam_state == PWRDM_POWER_ON) { - new_state = dev->safe_state; - goto select_state; - } - - /* - * Prevent PER off if CORE is not in retention or off as this - * would disable PER wakeups completely. - */ - per_next_state = per_saved_state = pwrdm_read_next_pwrst(per_pd); - if ((per_next_state == PWRDM_POWER_OFF) && - (core_next_state > PWRDM_POWER_RET)) { - per_next_state = PWRDM_POWER_RET; - pwrdm_set_next_pwrst(per_pd, per_next_state); } - /* Are we changing PER target state? */ - if (per_next_state != per_saved_state) - pwrdm_set_next_pwrst(per_pd, per_next_state); - -select_state: dev->last_state = new_state; - ret = omap3_enter_idle(dev, new_state); - - /* Restore original PER state if it was modified */ - if (per_next_state != per_saved_state) - pwrdm_set_next_pwrst(per_pd, per_saved_state); - - return ret; + return omap3_enter_idle(dev, new_state); } DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev); @@ -377,8 +328,7 @@ void omap_init_power_states(void) cpuidle_params_table[OMAP3_STATE_C2].threshold; omap3_power_states[OMAP3_STATE_C2].mpu_state = PWRDM_POWER_ON; omap3_power_states[OMAP3_STATE_C2].core_state = PWRDM_POWER_ON; - omap3_power_states[OMAP3_STATE_C2].flags = CPUIDLE_FLAG_TIME_VALID | - CPUIDLE_FLAG_CHECK_BM; + omap3_power_states[OMAP3_STATE_C2].flags = CPUIDLE_FLAG_TIME_VALID; /* C3 . MPU CSWR + Core inactive */ omap3_power_states[OMAP3_STATE_C3].valid = @@ -476,8 +426,6 @@ int __init omap3_idle_init(void) mpu_pd = pwrdm_lookup("mpu_pwrdm"); core_pd = pwrdm_lookup("core_pwrdm"); - per_pd = pwrdm_lookup("per_pwrdm"); - cam_pd = pwrdm_lookup("cam_pwrdm"); omap_init_power_states(); cpuidle_register_driver(&omap3_idle_driver); diff --git a/trunk/arch/arm/mach-omap2/io.c b/trunk/arch/arm/mach-omap2/io.c index 490d87082fad..b9ea70bce563 100644 --- a/trunk/arch/arm/mach-omap2/io.c +++ b/trunk/arch/arm/mach-omap2/io.c @@ -323,9 +323,6 @@ void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0, omap2430_hwmod_init(); else if (cpu_is_omap34xx()) omap3xxx_hwmod_init(); - else if (cpu_is_omap44xx()) - omap44xx_hwmod_init(); - /* The OPP tables have to be registered before a clk init */ omap_pm_if_early_init(mpu_opps, dsp_opps, l3_opps); @@ -345,7 +342,9 @@ void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0, #ifndef CONFIG_PM_RUNTIME skip_setup_idle = 1; #endif - omap_hwmod_late_init(skip_setup_idle); + if (cpu_is_omap24xx() || cpu_is_omap34xx()) /* FIXME: OMAP4 */ + omap_hwmod_late_init(skip_setup_idle); + if (cpu_is_omap24xx() || cpu_is_omap34xx()) { omap2_sdrc_init(sdrc_cs0, sdrc_cs1); _omap2_init_reprogram_sdrc(); diff --git a/trunk/arch/arm/mach-omap2/omap_hwmod.c b/trunk/arch/arm/mach-omap2/omap_hwmod.c index c3a5889d8add..cb911d7d1a3c 100644 --- a/trunk/arch/arm/mach-omap2/omap_hwmod.c +++ b/trunk/arch/arm/mach-omap2/omap_hwmod.c @@ -13,102 +13,10 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * - * Introduction - * ------------ - * One way to view an OMAP SoC is as a collection of largely unrelated - * IP blocks connected by interconnects. The IP blocks include - * devices such as ARM processors, audio serial interfaces, UARTs, - * etc. Some of these devices, like the DSP, are created by TI; - * others, like the SGX, largely originate from external vendors. In - * TI's documentation, on-chip devices are referred to as "OMAP - * modules." Some of these IP blocks are identical across several - * OMAP versions. Others are revised frequently. - * - * These OMAP modules are tied together by various interconnects. - * Most of the address and data flow between modules is via OCP-based - * interconnects such as the L3 and L4 buses; but there are other - * interconnects that distribute the hardware clock tree, handle idle - * and reset signaling, supply power, and connect the modules to - * various pads or balls on the OMAP package. - * - * OMAP hwmod provides a consistent way to describe the on-chip - * hardware blocks and their integration into the rest of the chip. - * This description can be automatically generated from the TI - * hardware database. OMAP hwmod provides a standard, consistent API - * to reset, enable, idle, and disable these hardware blocks. And - * hwmod provides a way for other core code, such as the Linux device - * code or the OMAP power management and address space mapping code, - * to query the hardware database. - * - * Using hwmod - * ----------- - * Drivers won't call hwmod functions directly. That is done by the - * omap_device code, and in rare occasions, by custom integration code - * in arch/arm/ *omap*. The omap_device code includes functions to - * build a struct platform_device using omap_hwmod data, and that is - * currently how hwmod data is communicated to drivers and to the - * Linux driver model. Most drivers will call omap_hwmod functions only - * indirectly, via pm_runtime*() functions. - * - * From a layering perspective, here is where the OMAP hwmod code - * fits into the kernel software stack: - * - * +-------------------------------+ - * | Device driver code | - * | (e.g., drivers/) | - * +-------------------------------+ - * | Linux driver model | - * | (platform_device / | - * | platform_driver data/code) | - * +-------------------------------+ - * | OMAP core-driver integration | - * |(arch/arm/mach-omap2/devices.c)| - * +-------------------------------+ - * | omap_device code | - * | (../plat-omap/omap_device.c) | - * +-------------------------------+ - * ----> | omap_hwmod code/data | <----- - * | (../mach-omap2/omap_hwmod*) | - * +-------------------------------+ - * | OMAP clock/PRCM/register fns | - * | (__raw_{read,write}l, clk*) | - * +-------------------------------+ - * - * Device drivers should not contain any OMAP-specific code or data in - * them. They should only contain code to operate the IP block that - * the driver is responsible for. This is because these IP blocks can - * also appear in other SoCs, either from TI (such as DaVinci) or from - * other manufacturers; and drivers should be reusable across other - * platforms. - * - * The OMAP hwmod code also will attempt to reset and idle all on-chip - * devices upon boot. The goal here is for the kernel to be - * completely self-reliant and independent from bootloaders. This is - * to ensure a repeatable configuration, both to ensure consistent - * runtime behavior, and to make it easier for others to reproduce - * bugs. - * - * OMAP module activity states - * --------------------------- - * The hwmod code considers modules to be in one of several activity - * states. IP blocks start out in an UNKNOWN state, then once they - * are registered via the hwmod code, proceed to the REGISTERED state. - * Once their clock names are resolved to clock pointers, the module - * enters the CLKS_INITED state; and finally, once the module has been - * reset and the integration registers programmed, the INITIALIZED state - * is entered. The hwmod code will then place the module into either - * the IDLE state to save power, or in the case of a critical system - * module, the ENABLED state. - * - * OMAP core integration code can then call omap_hwmod*() functions - * directly to move the module between the IDLE, ENABLED, and DISABLED - * states, as needed. This is done during both the PM idle loop, and - * in the OMAP core integration code's implementation of the PM runtime - * functions. - * - * References - * ---------- - * This is a partial list. + * This code manages "OMAP modules" (on-chip devices) and their + * integration with Linux device driver and bus code. + * + * References: * - OMAP2420 Multimedia Processor Silicon Revision 2.1.1, 2.2 (SWPU064) * - OMAP2430 Multimedia Device POP Silicon Revision 2.1 (SWPU090) * - OMAP34xx Multimedia Device Silicon Revision 3.1 (SWPU108) @@ -142,13 +50,11 @@ #include #include #include -#include #include "cm.h" -#include "prm.h" -/* Maximum microseconds to wait for OMAP module to softreset */ -#define MAX_MODULE_SOFTRESET_WAIT 10000 +/* Maximum microseconds to wait for OMAP module to reset */ +#define MAX_MODULE_RESET_WAIT 10000 /* Name of the OMAP hwmod for the MPU */ #define MPU_INITIATOR_NAME "mpu" @@ -638,36 +544,6 @@ static int _disable_clocks(struct omap_hwmod *oh) return 0; } -static void _enable_optional_clocks(struct omap_hwmod *oh) -{ - struct omap_hwmod_opt_clk *oc; - int i; - - pr_debug("omap_hwmod: %s: enabling optional clocks\n", oh->name); - - for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++) - if (oc->_clk) { - pr_debug("omap_hwmod: enable %s:%s\n", oc->role, - oc->_clk->name); - clk_enable(oc->_clk); - } -} - -static void _disable_optional_clocks(struct omap_hwmod *oh) -{ - struct omap_hwmod_opt_clk *oc; - int i; - - pr_debug("omap_hwmod: %s: disabling optional clocks\n", oh->name); - - for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++) - if (oc->_clk) { - pr_debug("omap_hwmod: disable %s:%s\n", oc->role, - oc->_clk->name); - clk_disable(oc->_clk); - } -} - /** * _find_mpu_port_index - find hwmod OCP slave port ID intended for MPU use * @oh: struct omap_hwmod * @@ -746,7 +622,7 @@ static void __iomem *_find_mpu_rt_base(struct omap_hwmod *oh, u8 index) } /** - * _enable_sysc - try to bring a module out of idle via OCP_SYSCONFIG + * _sysc_enable - try to bring a module out of idle via OCP_SYSCONFIG * @oh: struct omap_hwmod * * * If module is marked as SWSUP_SIDLE, force the module out of slave @@ -754,7 +630,7 @@ static void __iomem *_find_mpu_rt_base(struct omap_hwmod *oh, u8 index) * as SWSUP_MSUSPEND, force the module out of master standby; * otherwise, configure it for smart-standby. No return value. */ -static void _enable_sysc(struct omap_hwmod *oh) +static void _sysc_enable(struct omap_hwmod *oh) { u8 idlemode, sf; u32 v; @@ -783,6 +659,8 @@ static void _enable_sysc(struct omap_hwmod *oh) _set_module_autoidle(oh, idlemode, &v); } + /* XXX OCP ENAWAKEUP bit? */ + /* * XXX The clock framework should handle this, by * calling into this code. But this must wait until the @@ -793,14 +671,10 @@ static void _enable_sysc(struct omap_hwmod *oh) _set_clockactivity(oh, oh->class->sysc->clockact, &v); _write_sysconfig(v, oh); - - /* If slave is in SMARTIDLE, also enable wakeup */ - if ((sf & SYSC_HAS_SIDLEMODE) && !(oh->flags & HWMOD_SWSUP_SIDLE)) - _enable_wakeup(oh); } /** - * _idle_sysc - try to put a module into idle via OCP_SYSCONFIG + * _sysc_idle - try to put a module into idle via OCP_SYSCONFIG * @oh: struct omap_hwmod * * * If module is marked as SWSUP_SIDLE, force the module into slave @@ -808,7 +682,7 @@ static void _enable_sysc(struct omap_hwmod *oh) * as SWSUP_MSUSPEND, force the module into master standby; otherwise, * configure it for smart-standby. No return value. */ -static void _idle_sysc(struct omap_hwmod *oh) +static void _sysc_idle(struct omap_hwmod *oh) { u8 idlemode, sf; u32 v; @@ -835,13 +709,13 @@ static void _idle_sysc(struct omap_hwmod *oh) } /** - * _shutdown_sysc - force a module into idle via OCP_SYSCONFIG + * _sysc_shutdown - force a module into idle via OCP_SYSCONFIG * @oh: struct omap_hwmod * * * Force the module into slave idle and master suspend. No return * value. */ -static void _shutdown_sysc(struct omap_hwmod *oh) +static void _sysc_shutdown(struct omap_hwmod *oh) { u32 v; u8 sf; @@ -893,10 +767,10 @@ static struct omap_hwmod *_lookup(const char *name) * @data: not used; pass NULL * * Called by omap_hwmod_late_init() (after omap2_clk_init()). - * Resolves all clock names embedded in the hwmod. Returns -EINVAL if - * the omap_hwmod has not yet been registered or if the clocks have - * already been initialized, 0 on success, or a non-zero error on - * failure. + * Resolves all clock names embedded in the hwmod. Must be called + * with omap_hwmod_mutex held. Returns -EINVAL if the omap_hwmod + * has not yet been registered or if the clocks have already been + * initialized, 0 on success, or a non-zero error on failure. */ static int _init_clocks(struct omap_hwmod *oh, void *data) { @@ -959,203 +833,57 @@ static int _wait_target_ready(struct omap_hwmod *oh) return ret; } -/** - * _lookup_hardreset - return the register bit shift for this hwmod/reset line - * @oh: struct omap_hwmod * - * @name: name of the reset line in the context of this hwmod - * - * Return the bit position of the reset line that match the - * input name. Return -ENOENT if not found. - */ -static u8 _lookup_hardreset(struct omap_hwmod *oh, const char *name) -{ - int i; - - for (i = 0; i < oh->rst_lines_cnt; i++) { - const char *rst_line = oh->rst_lines[i].name; - if (!strcmp(rst_line, name)) { - u8 shift = oh->rst_lines[i].rst_shift; - pr_debug("omap_hwmod: %s: _lookup_hardreset: %s: %d\n", - oh->name, rst_line, shift); - - return shift; - } - } - - return -ENOENT; -} - -/** - * _assert_hardreset - assert the HW reset line of submodules - * contained in the hwmod module. - * @oh: struct omap_hwmod * - * @name: name of the reset line to lookup and assert - * - * Some IP like dsp, ipu or iva contain processor that require - * an HW reset line to be assert / deassert in order to enable fully - * the IP. - */ -static int _assert_hardreset(struct omap_hwmod *oh, const char *name) -{ - u8 shift; - - if (!oh) - return -EINVAL; - - shift = _lookup_hardreset(oh, name); - if (IS_ERR_VALUE(shift)) - return shift; - - if (cpu_is_omap24xx() || cpu_is_omap34xx()) - return omap2_prm_assert_hardreset(oh->prcm.omap2.module_offs, - shift); - else if (cpu_is_omap44xx()) - return omap4_prm_assert_hardreset(oh->prcm.omap4.rstctrl_reg, - shift); - else - return -EINVAL; -} - -/** - * _deassert_hardreset - deassert the HW reset line of submodules contained - * in the hwmod module. - * @oh: struct omap_hwmod * - * @name: name of the reset line to look up and deassert - * - * Some IP like dsp, ipu or iva contain processor that require - * an HW reset line to be assert / deassert in order to enable fully - * the IP. - */ -static int _deassert_hardreset(struct omap_hwmod *oh, const char *name) -{ - u8 shift; - int r; - - if (!oh) - return -EINVAL; - - shift = _lookup_hardreset(oh, name); - if (IS_ERR_VALUE(shift)) - return shift; - - if (cpu_is_omap24xx() || cpu_is_omap34xx()) - r = omap2_prm_deassert_hardreset(oh->prcm.omap2.module_offs, - shift); - else if (cpu_is_omap44xx()) - r = omap4_prm_deassert_hardreset(oh->prcm.omap4.rstctrl_reg, - shift); - else - return -EINVAL; - - if (r == -EBUSY) - pr_warning("omap_hwmod: %s: failed to hardreset\n", oh->name); - - return r; -} - -/** - * _read_hardreset - read the HW reset line state of submodules - * contained in the hwmod module - * @oh: struct omap_hwmod * - * @name: name of the reset line to look up and read - * - * Return the state of the reset line. - */ -static int _read_hardreset(struct omap_hwmod *oh, const char *name) -{ - u8 shift; - - if (!oh) - return -EINVAL; - - shift = _lookup_hardreset(oh, name); - if (IS_ERR_VALUE(shift)) - return shift; - - if (cpu_is_omap24xx() || cpu_is_omap34xx()) { - return omap2_prm_is_hardreset_asserted(oh->prcm.omap2.module_offs, - shift); - } else if (cpu_is_omap44xx()) { - return omap4_prm_is_hardreset_asserted(oh->prcm.omap4.rstctrl_reg, - shift); - } else { - return -EINVAL; - } -} - /** * _reset - reset an omap_hwmod * @oh: struct omap_hwmod * * * Resets an omap_hwmod @oh via the OCP_SYSCONFIG bit. hwmod must be - * enabled for this to work. Returns -EINVAL if the hwmod cannot be - * reset this way or if the hwmod is in the wrong state, -ETIMEDOUT if - * the module did not reset in time, or 0 upon success. - * - * In OMAP3 a specific SYSSTATUS register is used to get the reset status. - * Starting in OMAP4, some IPs does not have SYSSTATUS register and instead - * use the SYSCONFIG softreset bit to provide the status. - * - * Note that some IP like McBSP does have a reset control but no reset status. + * enabled for this to work. Must be called with omap_hwmod_mutex + * held. Returns -EINVAL if the hwmod cannot be reset this way or if + * the hwmod is in the wrong state, -ETIMEDOUT if the module did not + * reset in time, or 0 upon success. */ static int _reset(struct omap_hwmod *oh) { - u32 v; + u32 r, v; int c = 0; - int ret = 0; if (!oh->class->sysc || - !(oh->class->sysc->sysc_flags & SYSC_HAS_SOFTRESET)) + !(oh->class->sysc->sysc_flags & SYSC_HAS_SOFTRESET) || + (oh->class->sysc->sysc_flags & SYSS_MISSING)) return -EINVAL; /* clocks must be on for this operation */ if (oh->_state != _HWMOD_STATE_ENABLED) { - pr_warning("omap_hwmod: %s: reset can only be entered from " - "enabled state\n", oh->name); + WARN(1, "omap_hwmod: %s: reset can only be entered from " + "enabled state\n", oh->name); return -EINVAL; } - /* For some modules, all optionnal clocks need to be enabled as well */ - if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET) - _enable_optional_clocks(oh); - pr_debug("omap_hwmod: %s: resetting\n", oh->name); v = oh->_sysc_cache; - ret = _set_softreset(oh, &v); - if (ret) - goto dis_opt_clks; + r = _set_softreset(oh, &v); + if (r) + return r; _write_sysconfig(v, oh); - if (oh->class->sysc->sysc_flags & SYSS_HAS_RESET_STATUS) - omap_test_timeout((omap_hwmod_readl(oh, - oh->class->sysc->syss_offs) - & SYSS_RESETDONE_MASK), - MAX_MODULE_SOFTRESET_WAIT, c); - else if (oh->class->sysc->sysc_flags & SYSC_HAS_RESET_STATUS) - omap_test_timeout(!(omap_hwmod_readl(oh, - oh->class->sysc->sysc_offs) - & SYSC_TYPE2_SOFTRESET_MASK), - MAX_MODULE_SOFTRESET_WAIT, c); - - if (c == MAX_MODULE_SOFTRESET_WAIT) - pr_warning("omap_hwmod: %s: softreset failed (waited %d usec)\n", - oh->name, MAX_MODULE_SOFTRESET_WAIT); + omap_test_timeout((omap_hwmod_readl(oh, oh->class->sysc->syss_offs) & + SYSS_RESETDONE_MASK), + MAX_MODULE_RESET_WAIT, c); + + if (c == MAX_MODULE_RESET_WAIT) + WARN(1, "omap_hwmod: %s: failed to reset in %d usec\n", + oh->name, MAX_MODULE_RESET_WAIT); else - pr_debug("omap_hwmod: %s: softreset in %d usec\n", oh->name, c); + pr_debug("omap_hwmod: %s: reset in %d usec\n", oh->name, c); /* * XXX add _HWMOD_STATE_WEDGED for modules that don't come back from * _wait_target_ready() or _reset() */ - ret = (c == MAX_MODULE_SOFTRESET_WAIT) ? -ETIMEDOUT : 0; - -dis_opt_clks: - if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET) - _disable_optional_clocks(oh); - - return ret; + return (c == MAX_MODULE_RESET_WAIT) ? -ETIMEDOUT : 0; } /** @@ -1163,11 +891,9 @@ static int _reset(struct omap_hwmod *oh) * @oh: struct omap_hwmod * * * Enables an omap_hwmod @oh such that the MPU can access the hwmod's - * register target. (This function has a full name -- - * _omap_hwmod_enable() rather than simply _enable() -- because it is - * currently required by the pm34xx.c idle loop.) Returns -EINVAL if - * the hwmod is in the wrong state or passes along the return value of - * _wait_target_ready(). + * register target. Must be called with omap_hwmod_mutex held. + * Returns -EINVAL if the hwmod is in the wrong state or passes along + * the return value of _wait_target_ready(). */ int _omap_hwmod_enable(struct omap_hwmod *oh) { @@ -1183,15 +909,6 @@ int _omap_hwmod_enable(struct omap_hwmod *oh) pr_debug("omap_hwmod: %s: enabling\n", oh->name); - /* - * If an IP contains only one HW reset line, then de-assert it in order - * to allow to enable the clocks. Otherwise the PRCM will return - * Intransition status, and the init will failed. - */ - if ((oh->_state == _HWMOD_STATE_INITIALIZED || - oh->_state == _HWMOD_STATE_DISABLED) && oh->rst_lines_cnt == 1) - _deassert_hardreset(oh, oh->rst_lines[0].name); - /* XXX mux balls */ _add_initiator_dep(oh, mpu_oh); @@ -1205,7 +922,7 @@ int _omap_hwmod_enable(struct omap_hwmod *oh) if (oh->class->sysc) { if (!(oh->_int_flags & _HWMOD_SYSCONFIG_LOADED)) _update_sysc_cache(oh); - _enable_sysc(oh); + _sysc_enable(oh); } } else { pr_debug("omap_hwmod: %s: _wait_target_ready: %d\n", @@ -1216,14 +933,12 @@ int _omap_hwmod_enable(struct omap_hwmod *oh) } /** - * _omap_hwmod_idle - idle an omap_hwmod + * _idle - idle an omap_hwmod * @oh: struct omap_hwmod * * * Idles an omap_hwmod @oh. This should be called once the hwmod has - * no further work. (This function has a full name -- - * _omap_hwmod_idle() rather than simply _idle() -- because it is - * currently required by the pm34xx.c idle loop.) Returns -EINVAL if - * the hwmod is in the wrong state or returns 0. + * no further work. Returns -EINVAL if the hwmod is in the wrong + * state or returns 0. */ int _omap_hwmod_idle(struct omap_hwmod *oh) { @@ -1236,7 +951,7 @@ int _omap_hwmod_idle(struct omap_hwmod *oh) pr_debug("omap_hwmod: %s: idling\n", oh->name); if (oh->class->sysc) - _idle_sysc(oh); + _sysc_idle(oh); _del_initiator_dep(oh, mpu_oh); _disable_clocks(oh); @@ -1266,21 +981,10 @@ static int _shutdown(struct omap_hwmod *oh) pr_debug("omap_hwmod: %s: disabling\n", oh->name); if (oh->class->sysc) - _shutdown_sysc(oh); - - /* - * If an IP contains only one HW reset line, then assert it - * before disabling the clocks and shutting down the IP. - */ - if (oh->rst_lines_cnt == 1) - _assert_hardreset(oh, oh->rst_lines[0].name); - - /* clocks and deps are already disabled in idle */ - if (oh->_state == _HWMOD_STATE_ENABLED) { - _del_initiator_dep(oh, mpu_oh); - /* XXX what about the other system initiators here? dma, dsp */ - _disable_clocks(oh); - } + _sysc_shutdown(oh); + _del_initiator_dep(oh, mpu_oh); + /* XXX what about the other system initiators here? DMA, tesla, d2d */ + _disable_clocks(oh); /* XXX Should this code also force-disable the optional clocks? */ /* XXX mux any associated balls to safe mode */ @@ -1296,10 +1000,11 @@ static int _shutdown(struct omap_hwmod *oh) * @skip_setup_idle_p: do not idle hwmods at the end of the fn if 1 * * Writes the CLOCKACTIVITY bits @clockact to the hwmod @oh - * OCP_SYSCONFIG register. @skip_setup_idle is intended to be used on - * a system that will not call omap_hwmod_enable() to enable devices - * (e.g., a system without PM runtime). Returns -EINVAL if the hwmod - * is in the wrong state or returns 0. + * OCP_SYSCONFIG register. Must be called with omap_hwmod_mutex held. + * @skip_setup_idle is intended to be used on a system that will not + * call omap_hwmod_enable() to enable devices (e.g., a system without + * PM runtime). Returns -EINVAL if the hwmod is in the wrong state or + * returns 0. */ static int _setup(struct omap_hwmod *oh, void *data) { @@ -1329,19 +1034,8 @@ static int _setup(struct omap_hwmod *oh, void *data) } } - mutex_init(&oh->_mutex); oh->_state = _HWMOD_STATE_INITIALIZED; - /* - * In the case of hwmod with hardreset that should not be - * de-assert at boot time, we have to keep the module - * initialized, because we cannot enable it properly with the - * reset asserted. Exit without warning because that behavior is - * expected. - */ - if ((oh->flags & HWMOD_INIT_NO_RESET) && oh->rst_lines_cnt == 1) - return 0; - r = _omap_hwmod_enable(oh); if (r) { pr_warning("omap_hwmod: %s: cannot be enabled (%d)\n", @@ -1350,16 +1044,16 @@ static int _setup(struct omap_hwmod *oh, void *data) } if (!(oh->flags & HWMOD_INIT_NO_RESET)) { - _reset(oh); - /* - * OCP_SYSCONFIG bits need to be reprogrammed after a softreset. - * The _omap_hwmod_enable() function should be split to - * avoid the rewrite of the OCP_SYSCONFIG register. + * XXX Do the OCP_SYSCONFIG bits need to be + * reprogrammed after a reset? If not, then this can + * be removed. If they do, then probably the + * _omap_hwmod_enable() function should be split to avoid the + * rewrite of the OCP_SYSCONFIG register. */ if (oh->class->sysc) { _update_sysc_cache(oh); - _enable_sysc(oh); + _sysc_enable(oh); } } @@ -1615,7 +1309,7 @@ int omap_hwmod_unregister(struct omap_hwmod *oh) * omap_hwmod_enable - enable an omap_hwmod * @oh: struct omap_hwmod * * - * Enable an omap_hwmod @oh. Intended to be called by omap_device_enable(). + * Enable an omap_hwomd @oh. Intended to be called by omap_device_enable(). * Returns -EINVAL on error or passes along the return value from _enable(). */ int omap_hwmod_enable(struct omap_hwmod *oh) @@ -1625,9 +1319,9 @@ int omap_hwmod_enable(struct omap_hwmod *oh) if (!oh) return -EINVAL; - mutex_lock(&oh->_mutex); + mutex_lock(&omap_hwmod_mutex); r = _omap_hwmod_enable(oh); - mutex_unlock(&oh->_mutex); + mutex_unlock(&omap_hwmod_mutex); return r; } @@ -1637,7 +1331,7 @@ int omap_hwmod_enable(struct omap_hwmod *oh) * omap_hwmod_idle - idle an omap_hwmod * @oh: struct omap_hwmod * * - * Idle an omap_hwmod @oh. Intended to be called by omap_device_idle(). + * Idle an omap_hwomd @oh. Intended to be called by omap_device_idle(). * Returns -EINVAL on error or passes along the return value from _idle(). */ int omap_hwmod_idle(struct omap_hwmod *oh) @@ -1645,9 +1339,9 @@ int omap_hwmod_idle(struct omap_hwmod *oh) if (!oh) return -EINVAL; - mutex_lock(&oh->_mutex); + mutex_lock(&omap_hwmod_mutex); _omap_hwmod_idle(oh); - mutex_unlock(&oh->_mutex); + mutex_unlock(&omap_hwmod_mutex); return 0; } @@ -1656,7 +1350,7 @@ int omap_hwmod_idle(struct omap_hwmod *oh) * omap_hwmod_shutdown - shutdown an omap_hwmod * @oh: struct omap_hwmod * * - * Shutdown an omap_hwmod @oh. Intended to be called by + * Shutdown an omap_hwomd @oh. Intended to be called by * omap_device_shutdown(). Returns -EINVAL on error or passes along * the return value from _shutdown(). */ @@ -1665,9 +1359,9 @@ int omap_hwmod_shutdown(struct omap_hwmod *oh) if (!oh) return -EINVAL; - mutex_lock(&oh->_mutex); + mutex_lock(&omap_hwmod_mutex); _shutdown(oh); - mutex_unlock(&oh->_mutex); + mutex_unlock(&omap_hwmod_mutex); return 0; } @@ -1680,9 +1374,9 @@ int omap_hwmod_shutdown(struct omap_hwmod *oh) */ int omap_hwmod_enable_clocks(struct omap_hwmod *oh) { - mutex_lock(&oh->_mutex); + mutex_lock(&omap_hwmod_mutex); _enable_clocks(oh); - mutex_unlock(&oh->_mutex); + mutex_unlock(&omap_hwmod_mutex); return 0; } @@ -1695,9 +1389,9 @@ int omap_hwmod_enable_clocks(struct omap_hwmod *oh) */ int omap_hwmod_disable_clocks(struct omap_hwmod *oh) { - mutex_lock(&oh->_mutex); + mutex_lock(&omap_hwmod_mutex); _disable_clocks(oh); - mutex_unlock(&oh->_mutex); + mutex_unlock(&omap_hwmod_mutex); return 0; } @@ -1736,18 +1430,20 @@ void omap_hwmod_ocp_barrier(struct omap_hwmod *oh) * * Under some conditions, a driver may wish to reset the entire device. * Called from omap_device code. Returns -EINVAL on error or passes along - * the return value from _reset(). + * the return value from _reset()/_enable(). */ int omap_hwmod_reset(struct omap_hwmod *oh) { int r; - if (!oh) + if (!oh || !(oh->_state & _HWMOD_STATE_ENABLED)) return -EINVAL; - mutex_lock(&oh->_mutex); + mutex_lock(&omap_hwmod_mutex); r = _reset(oh); - mutex_unlock(&oh->_mutex); + if (!r) + r = _omap_hwmod_enable(oh); + mutex_unlock(&omap_hwmod_mutex); return r; } @@ -1772,7 +1468,7 @@ int omap_hwmod_count_resources(struct omap_hwmod *oh) { int ret, i; - ret = oh->mpu_irqs_cnt + oh->sdma_reqs_cnt; + ret = oh->mpu_irqs_cnt + oh->sdma_chs_cnt; for (i = 0; i < oh->slaves_cnt; i++) ret += oh->slaves[i]->addr_cnt; @@ -1805,10 +1501,10 @@ int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res) r++; } - for (i = 0; i < oh->sdma_reqs_cnt; i++) { - (res + r)->name = (oh->sdma_reqs + i)->name; - (res + r)->start = (oh->sdma_reqs + i)->dma_req; - (res + r)->end = (oh->sdma_reqs + i)->dma_req; + for (i = 0; i < oh->sdma_chs_cnt; i++) { + (res + r)->name = (oh->sdma_chs + i)->name; + (res + r)->start = (oh->sdma_chs + i)->dma_ch; + (res + r)->end = (oh->sdma_chs + i)->dma_ch; (res + r)->flags = IORESOURCE_DMA; r++; } @@ -1948,9 +1644,9 @@ int omap_hwmod_enable_wakeup(struct omap_hwmod *oh) !(oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)) return -EINVAL; - mutex_lock(&oh->_mutex); + mutex_lock(&omap_hwmod_mutex); _enable_wakeup(oh); - mutex_unlock(&oh->_mutex); + mutex_unlock(&omap_hwmod_mutex); return 0; } @@ -1973,91 +1669,13 @@ int omap_hwmod_disable_wakeup(struct omap_hwmod *oh) !(oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)) return -EINVAL; - mutex_lock(&oh->_mutex); + mutex_lock(&omap_hwmod_mutex); _disable_wakeup(oh); - mutex_unlock(&oh->_mutex); + mutex_unlock(&omap_hwmod_mutex); return 0; } -/** - * omap_hwmod_assert_hardreset - assert the HW reset line of submodules - * contained in the hwmod module. - * @oh: struct omap_hwmod * - * @name: name of the reset line to lookup and assert - * - * Some IP like dsp, ipu or iva contain processor that require - * an HW reset line to be assert / deassert in order to enable fully - * the IP. Returns -EINVAL if @oh is null or if the operation is not - * yet supported on this OMAP; otherwise, passes along the return value - * from _assert_hardreset(). - */ -int omap_hwmod_assert_hardreset(struct omap_hwmod *oh, const char *name) -{ - int ret; - - if (!oh) - return -EINVAL; - - mutex_lock(&oh->_mutex); - ret = _assert_hardreset(oh, name); - mutex_unlock(&oh->_mutex); - - return ret; -} - -/** - * omap_hwmod_deassert_hardreset - deassert the HW reset line of submodules - * contained in the hwmod module. - * @oh: struct omap_hwmod * - * @name: name of the reset line to look up and deassert - * - * Some IP like dsp, ipu or iva contain processor that require - * an HW reset line to be assert / deassert in order to enable fully - * the IP. Returns -EINVAL if @oh is null or if the operation is not - * yet supported on this OMAP; otherwise, passes along the return value - * from _deassert_hardreset(). - */ -int omap_hwmod_deassert_hardreset(struct omap_hwmod *oh, const char *name) -{ - int ret; - - if (!oh) - return -EINVAL; - - mutex_lock(&oh->_mutex); - ret = _deassert_hardreset(oh, name); - mutex_unlock(&oh->_mutex); - - return ret; -} - -/** - * omap_hwmod_read_hardreset - read the HW reset line state of submodules - * contained in the hwmod module - * @oh: struct omap_hwmod * - * @name: name of the reset line to look up and read - * - * Return the current state of the hwmod @oh's reset line named @name: - * returns -EINVAL upon parameter error or if this operation - * is unsupported on the current OMAP; otherwise, passes along the return - * value from _read_hardreset(). - */ -int omap_hwmod_read_hardreset(struct omap_hwmod *oh, const char *name) -{ - int ret; - - if (!oh) - return -EINVAL; - - mutex_lock(&oh->_mutex); - ret = _read_hardreset(oh, name); - mutex_unlock(&oh->_mutex); - - return ret; -} - - /** * omap_hwmod_for_each_by_class - call @fn for each hwmod of class @classname * @classname: struct omap_hwmod_class name to search for diff --git a/trunk/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/trunk/arch/arm/mach-omap2/omap_hwmod_44xx_data.c deleted file mode 100644 index e20b0eebc6d9..000000000000 --- a/trunk/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ /dev/null @@ -1,482 +0,0 @@ -/* - * Hardware modules present on the OMAP44xx chips - * - * Copyright (C) 2009-2010 Texas Instruments, Inc. - * Copyright (C) 2009-2010 Nokia Corporation - * - * Paul Walmsley - * Benoit Cousson - * - * This file is automatically generated from the OMAP hardware databases. - * We respectfully ask that any modifications to this file be coordinated - * with the public linux-omap@vger.kernel.org mailing list and the - * authors above to ensure that the autogeneration scripts are kept - * up-to-date with the file contents. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include - -#include -#include - -#include "omap_hwmod_common_data.h" - -#include "cm.h" -#include "prm-regbits-44xx.h" - -/* Base offset for all OMAP4 interrupts external to MPUSS */ -#define OMAP44XX_IRQ_GIC_START 32 - -/* Base offset for all OMAP4 dma requests */ -#define OMAP44XX_DMA_REQ_START 1 - -/* Backward references (IPs with Bus Master capability) */ -static struct omap_hwmod omap44xx_dmm_hwmod; -static struct omap_hwmod omap44xx_emif_fw_hwmod; -static struct omap_hwmod omap44xx_l3_instr_hwmod; -static struct omap_hwmod omap44xx_l3_main_1_hwmod; -static struct omap_hwmod omap44xx_l3_main_2_hwmod; -static struct omap_hwmod omap44xx_l3_main_3_hwmod; -static struct omap_hwmod omap44xx_l4_abe_hwmod; -static struct omap_hwmod omap44xx_l4_cfg_hwmod; -static struct omap_hwmod omap44xx_l4_per_hwmod; -static struct omap_hwmod omap44xx_l4_wkup_hwmod; -static struct omap_hwmod omap44xx_mpu_hwmod; -static struct omap_hwmod omap44xx_mpu_private_hwmod; - -/* - * Interconnects omap_hwmod structures - * hwmods that compose the global OMAP interconnect - */ - -/* - * 'dmm' class - * instance(s): dmm - */ -static struct omap_hwmod_class omap44xx_dmm_hwmod_class = { - .name = "dmm", -}; - -/* dmm interface data */ -/* l3_main_1 -> dmm */ -static struct omap_hwmod_ocp_if omap44xx_l3_main_1__dmm = { - .master = &omap44xx_l3_main_1_hwmod, - .slave = &omap44xx_dmm_hwmod, - .clk = "l3_div_ck", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* mpu -> dmm */ -static struct omap_hwmod_ocp_if omap44xx_mpu__dmm = { - .master = &omap44xx_mpu_hwmod, - .slave = &omap44xx_dmm_hwmod, - .clk = "l3_div_ck", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* dmm slave ports */ -static struct omap_hwmod_ocp_if *omap44xx_dmm_slaves[] = { - &omap44xx_l3_main_1__dmm, - &omap44xx_mpu__dmm, -}; - -static struct omap_hwmod_irq_info omap44xx_dmm_irqs[] = { - { .irq = 113 + OMAP44XX_IRQ_GIC_START }, -}; - -static struct omap_hwmod omap44xx_dmm_hwmod = { - .name = "dmm", - .class = &omap44xx_dmm_hwmod_class, - .slaves = omap44xx_dmm_slaves, - .slaves_cnt = ARRAY_SIZE(omap44xx_dmm_slaves), - .mpu_irqs = omap44xx_dmm_irqs, - .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_dmm_irqs), - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -}; - -/* - * 'emif_fw' class - * instance(s): emif_fw - */ -static struct omap_hwmod_class omap44xx_emif_fw_hwmod_class = { - .name = "emif_fw", -}; - -/* emif_fw interface data */ -/* dmm -> emif_fw */ -static struct omap_hwmod_ocp_if omap44xx_dmm__emif_fw = { - .master = &omap44xx_dmm_hwmod, - .slave = &omap44xx_emif_fw_hwmod, - .clk = "l3_div_ck", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* l4_cfg -> emif_fw */ -static struct omap_hwmod_ocp_if omap44xx_l4_cfg__emif_fw = { - .master = &omap44xx_l4_cfg_hwmod, - .slave = &omap44xx_emif_fw_hwmod, - .clk = "l4_div_ck", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* emif_fw slave ports */ -static struct omap_hwmod_ocp_if *omap44xx_emif_fw_slaves[] = { - &omap44xx_dmm__emif_fw, - &omap44xx_l4_cfg__emif_fw, -}; - -static struct omap_hwmod omap44xx_emif_fw_hwmod = { - .name = "emif_fw", - .class = &omap44xx_emif_fw_hwmod_class, - .slaves = omap44xx_emif_fw_slaves, - .slaves_cnt = ARRAY_SIZE(omap44xx_emif_fw_slaves), - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -}; - -/* - * 'l3' class - * instance(s): l3_instr, l3_main_1, l3_main_2, l3_main_3 - */ -static struct omap_hwmod_class omap44xx_l3_hwmod_class = { - .name = "l3", -}; - -/* l3_instr interface data */ -/* l3_main_3 -> l3_instr */ -static struct omap_hwmod_ocp_if omap44xx_l3_main_3__l3_instr = { - .master = &omap44xx_l3_main_3_hwmod, - .slave = &omap44xx_l3_instr_hwmod, - .clk = "l3_div_ck", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* l3_instr slave ports */ -static struct omap_hwmod_ocp_if *omap44xx_l3_instr_slaves[] = { - &omap44xx_l3_main_3__l3_instr, -}; - -static struct omap_hwmod omap44xx_l3_instr_hwmod = { - .name = "l3_instr", - .class = &omap44xx_l3_hwmod_class, - .slaves = omap44xx_l3_instr_slaves, - .slaves_cnt = ARRAY_SIZE(omap44xx_l3_instr_slaves), - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -}; - -/* l3_main_2 -> l3_main_1 */ -static struct omap_hwmod_ocp_if omap44xx_l3_main_2__l3_main_1 = { - .master = &omap44xx_l3_main_2_hwmod, - .slave = &omap44xx_l3_main_1_hwmod, - .clk = "l3_div_ck", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* l4_cfg -> l3_main_1 */ -static struct omap_hwmod_ocp_if omap44xx_l4_cfg__l3_main_1 = { - .master = &omap44xx_l4_cfg_hwmod, - .slave = &omap44xx_l3_main_1_hwmod, - .clk = "l4_div_ck", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* mpu -> l3_main_1 */ -static struct omap_hwmod_ocp_if omap44xx_mpu__l3_main_1 = { - .master = &omap44xx_mpu_hwmod, - .slave = &omap44xx_l3_main_1_hwmod, - .clk = "l3_div_ck", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* l3_main_1 slave ports */ -static struct omap_hwmod_ocp_if *omap44xx_l3_main_1_slaves[] = { - &omap44xx_l3_main_2__l3_main_1, - &omap44xx_l4_cfg__l3_main_1, - &omap44xx_mpu__l3_main_1, -}; - -static struct omap_hwmod omap44xx_l3_main_1_hwmod = { - .name = "l3_main_1", - .class = &omap44xx_l3_hwmod_class, - .slaves = omap44xx_l3_main_1_slaves, - .slaves_cnt = ARRAY_SIZE(omap44xx_l3_main_1_slaves), - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -}; - -/* l3_main_2 interface data */ -/* l3_main_1 -> l3_main_2 */ -static struct omap_hwmod_ocp_if omap44xx_l3_main_1__l3_main_2 = { - .master = &omap44xx_l3_main_1_hwmod, - .slave = &omap44xx_l3_main_2_hwmod, - .clk = "l3_div_ck", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* l4_cfg -> l3_main_2 */ -static struct omap_hwmod_ocp_if omap44xx_l4_cfg__l3_main_2 = { - .master = &omap44xx_l4_cfg_hwmod, - .slave = &omap44xx_l3_main_2_hwmod, - .clk = "l4_div_ck", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* l3_main_2 slave ports */ -static struct omap_hwmod_ocp_if *omap44xx_l3_main_2_slaves[] = { - &omap44xx_l3_main_1__l3_main_2, - &omap44xx_l4_cfg__l3_main_2, -}; - -static struct omap_hwmod omap44xx_l3_main_2_hwmod = { - .name = "l3_main_2", - .class = &omap44xx_l3_hwmod_class, - .slaves = omap44xx_l3_main_2_slaves, - .slaves_cnt = ARRAY_SIZE(omap44xx_l3_main_2_slaves), - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -}; - -/* l3_main_3 interface data */ -/* l3_main_1 -> l3_main_3 */ -static struct omap_hwmod_ocp_if omap44xx_l3_main_1__l3_main_3 = { - .master = &omap44xx_l3_main_1_hwmod, - .slave = &omap44xx_l3_main_3_hwmod, - .clk = "l3_div_ck", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* l3_main_2 -> l3_main_3 */ -static struct omap_hwmod_ocp_if omap44xx_l3_main_2__l3_main_3 = { - .master = &omap44xx_l3_main_2_hwmod, - .slave = &omap44xx_l3_main_3_hwmod, - .clk = "l3_div_ck", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* l4_cfg -> l3_main_3 */ -static struct omap_hwmod_ocp_if omap44xx_l4_cfg__l3_main_3 = { - .master = &omap44xx_l4_cfg_hwmod, - .slave = &omap44xx_l3_main_3_hwmod, - .clk = "l4_div_ck", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* l3_main_3 slave ports */ -static struct omap_hwmod_ocp_if *omap44xx_l3_main_3_slaves[] = { - &omap44xx_l3_main_1__l3_main_3, - &omap44xx_l3_main_2__l3_main_3, - &omap44xx_l4_cfg__l3_main_3, -}; - -static struct omap_hwmod omap44xx_l3_main_3_hwmod = { - .name = "l3_main_3", - .class = &omap44xx_l3_hwmod_class, - .slaves = omap44xx_l3_main_3_slaves, - .slaves_cnt = ARRAY_SIZE(omap44xx_l3_main_3_slaves), - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -}; - -/* - * 'l4' class - * instance(s): l4_abe, l4_cfg, l4_per, l4_wkup - */ -static struct omap_hwmod_class omap44xx_l4_hwmod_class = { - .name = "l4", -}; - -/* l4_abe interface data */ -/* l3_main_1 -> l4_abe */ -static struct omap_hwmod_ocp_if omap44xx_l3_main_1__l4_abe = { - .master = &omap44xx_l3_main_1_hwmod, - .slave = &omap44xx_l4_abe_hwmod, - .clk = "l3_div_ck", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* mpu -> l4_abe */ -static struct omap_hwmod_ocp_if omap44xx_mpu__l4_abe = { - .master = &omap44xx_mpu_hwmod, - .slave = &omap44xx_l4_abe_hwmod, - .clk = "ocp_abe_iclk", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* l4_abe slave ports */ -static struct omap_hwmod_ocp_if *omap44xx_l4_abe_slaves[] = { - &omap44xx_l3_main_1__l4_abe, - &omap44xx_mpu__l4_abe, -}; - -static struct omap_hwmod omap44xx_l4_abe_hwmod = { - .name = "l4_abe", - .class = &omap44xx_l4_hwmod_class, - .slaves = omap44xx_l4_abe_slaves, - .slaves_cnt = ARRAY_SIZE(omap44xx_l4_abe_slaves), - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -}; - -/* l4_cfg interface data */ -/* l3_main_1 -> l4_cfg */ -static struct omap_hwmod_ocp_if omap44xx_l3_main_1__l4_cfg = { - .master = &omap44xx_l3_main_1_hwmod, - .slave = &omap44xx_l4_cfg_hwmod, - .clk = "l3_div_ck", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* l4_cfg slave ports */ -static struct omap_hwmod_ocp_if *omap44xx_l4_cfg_slaves[] = { - &omap44xx_l3_main_1__l4_cfg, -}; - -static struct omap_hwmod omap44xx_l4_cfg_hwmod = { - .name = "l4_cfg", - .class = &omap44xx_l4_hwmod_class, - .slaves = omap44xx_l4_cfg_slaves, - .slaves_cnt = ARRAY_SIZE(omap44xx_l4_cfg_slaves), - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -}; - -/* l4_per interface data */ -/* l3_main_2 -> l4_per */ -static struct omap_hwmod_ocp_if omap44xx_l3_main_2__l4_per = { - .master = &omap44xx_l3_main_2_hwmod, - .slave = &omap44xx_l4_per_hwmod, - .clk = "l3_div_ck", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* l4_per slave ports */ -static struct omap_hwmod_ocp_if *omap44xx_l4_per_slaves[] = { - &omap44xx_l3_main_2__l4_per, -}; - -static struct omap_hwmod omap44xx_l4_per_hwmod = { - .name = "l4_per", - .class = &omap44xx_l4_hwmod_class, - .slaves = omap44xx_l4_per_slaves, - .slaves_cnt = ARRAY_SIZE(omap44xx_l4_per_slaves), - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -}; - -/* l4_wkup interface data */ -/* l4_cfg -> l4_wkup */ -static struct omap_hwmod_ocp_if omap44xx_l4_cfg__l4_wkup = { - .master = &omap44xx_l4_cfg_hwmod, - .slave = &omap44xx_l4_wkup_hwmod, - .clk = "l4_div_ck", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* l4_wkup slave ports */ -static struct omap_hwmod_ocp_if *omap44xx_l4_wkup_slaves[] = { - &omap44xx_l4_cfg__l4_wkup, -}; - -static struct omap_hwmod omap44xx_l4_wkup_hwmod = { - .name = "l4_wkup", - .class = &omap44xx_l4_hwmod_class, - .slaves = omap44xx_l4_wkup_slaves, - .slaves_cnt = ARRAY_SIZE(omap44xx_l4_wkup_slaves), - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -}; - -/* - * 'mpu_bus' class - * instance(s): mpu_private - */ -static struct omap_hwmod_class omap44xx_mpu_bus_hwmod_class = { - .name = "mpu_bus", -}; - -/* mpu_private interface data */ -/* mpu -> mpu_private */ -static struct omap_hwmod_ocp_if omap44xx_mpu__mpu_private = { - .master = &omap44xx_mpu_hwmod, - .slave = &omap44xx_mpu_private_hwmod, - .clk = "l3_div_ck", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* mpu_private slave ports */ -static struct omap_hwmod_ocp_if *omap44xx_mpu_private_slaves[] = { - &omap44xx_mpu__mpu_private, -}; - -static struct omap_hwmod omap44xx_mpu_private_hwmod = { - .name = "mpu_private", - .class = &omap44xx_mpu_bus_hwmod_class, - .slaves = omap44xx_mpu_private_slaves, - .slaves_cnt = ARRAY_SIZE(omap44xx_mpu_private_slaves), - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -}; - -/* - * 'mpu' class - * mpu sub-system - */ - -static struct omap_hwmod_class omap44xx_mpu_hwmod_class = { - .name = "mpu", -}; - -/* mpu */ -static struct omap_hwmod_irq_info omap44xx_mpu_irqs[] = { - { .name = "pl310", .irq = 0 + OMAP44XX_IRQ_GIC_START }, - { .name = "cti0", .irq = 1 + OMAP44XX_IRQ_GIC_START }, - { .name = "cti1", .irq = 2 + OMAP44XX_IRQ_GIC_START }, -}; - -/* mpu master ports */ -static struct omap_hwmod_ocp_if *omap44xx_mpu_masters[] = { - &omap44xx_mpu__l3_main_1, - &omap44xx_mpu__l4_abe, - &omap44xx_mpu__dmm, -}; - -static struct omap_hwmod omap44xx_mpu_hwmod = { - .name = "mpu", - .class = &omap44xx_mpu_hwmod_class, - .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET), - .mpu_irqs = omap44xx_mpu_irqs, - .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mpu_irqs), - .main_clk = "dpll_mpu_m2_ck", - .prcm = { - .omap4 = { - .clkctrl_reg = OMAP4430_CM_MPU_MPU_CLKCTRL, - }, - }, - .masters = omap44xx_mpu_masters, - .masters_cnt = ARRAY_SIZE(omap44xx_mpu_masters), - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -}; - -static __initdata struct omap_hwmod *omap44xx_hwmods[] = { - /* dmm class */ - &omap44xx_dmm_hwmod, - /* emif_fw class */ - &omap44xx_emif_fw_hwmod, - /* l3 class */ - &omap44xx_l3_instr_hwmod, - &omap44xx_l3_main_1_hwmod, - &omap44xx_l3_main_2_hwmod, - &omap44xx_l3_main_3_hwmod, - /* l4 class */ - &omap44xx_l4_abe_hwmod, - &omap44xx_l4_cfg_hwmod, - &omap44xx_l4_per_hwmod, - &omap44xx_l4_wkup_hwmod, - /* mpu_bus class */ - &omap44xx_mpu_private_hwmod, - - /* mpu class */ - &omap44xx_mpu_hwmod, - NULL, -}; - -int __init omap44xx_hwmod_init(void) -{ - return omap_hwmod_init(omap44xx_hwmods); -} - diff --git a/trunk/arch/arm/mach-omap2/pm-debug.c b/trunk/arch/arm/mach-omap2/pm-debug.c index af00c174d7a9..723b44e252fd 100644 --- a/trunk/arch/arm/mach-omap2/pm-debug.c +++ b/trunk/arch/arm/mach-omap2/pm-debug.c @@ -31,17 +31,12 @@ #include #include #include -#include #include "prm.h" #include "cm.h" #include "pm.h" int omap2_pm_debug; -u32 enable_off_mode; -u32 sleep_while_idle; -u32 wakeup_timer_seconds; -u32 wakeup_timer_milliseconds; #define DUMP_PRM_MOD_REG(mod, reg) \ regs[reg_count].name = #mod "." #reg; \ @@ -354,23 +349,6 @@ void pm_dbg_update_time(struct powerdomain *pwrdm, int prev) pwrdm->timer = t; } -void omap2_pm_wakeup_on_timer(u32 seconds, u32 milliseconds) -{ - u32 tick_rate, cycles; - - if (!seconds && !milliseconds) - return; - - tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer_wakeup)); - cycles = tick_rate * seconds + tick_rate * milliseconds / 1000; - omap_dm_timer_stop(gptimer_wakeup); - omap_dm_timer_set_load_start(gptimer_wakeup, 0, 0xffffffff - cycles); - - pr_info("PM: Resume timer in %u.%03u secs" - " (%d ticks at %d ticks/sec.)\n", - seconds, milliseconds, cycles, tick_rate); -} - static int clkdm_dbg_show_counter(struct clockdomain *clkdm, void *user) { struct seq_file *s = (struct seq_file *)user; @@ -516,10 +494,8 @@ int pm_dbg_regset_init(int reg_set) static int pwrdm_suspend_get(void *data, u64 *val) { - int ret = -EINVAL; - - if (cpu_is_omap34xx()) - ret = omap3_pm_get_suspend_state((struct powerdomain *)data); + int ret; + ret = omap3_pm_get_suspend_state((struct powerdomain *)data); *val = ret; if (ret >= 0) @@ -529,10 +505,7 @@ static int pwrdm_suspend_get(void *data, u64 *val) static int pwrdm_suspend_set(void *data, u64 val) { - if (cpu_is_omap34xx()) - return omap3_pm_set_suspend_state( - (struct powerdomain *)data, (int)val); - return -EINVAL; + return omap3_pm_set_suspend_state((struct powerdomain *)data, (int)val); } DEFINE_SIMPLE_ATTRIBUTE(pwrdm_suspend_fops, pwrdm_suspend_get, @@ -580,10 +553,8 @@ static int option_set(void *data, u64 val) *option = val; - if (option == &enable_off_mode) { - if (cpu_is_omap34xx()) - omap3_pm_off_mode_enable(val); - } + if (option == &enable_off_mode) + omap3_pm_off_mode_enable(val); return 0; } @@ -638,9 +609,6 @@ static int __init pm_dbg_init(void) &sleep_while_idle, &pm_dbg_option_fops); (void) debugfs_create_file("wakeup_timer_seconds", S_IRUGO | S_IWUGO, d, &wakeup_timer_seconds, &pm_dbg_option_fops); - (void) debugfs_create_file("wakeup_timer_milliseconds", - S_IRUGO | S_IWUGO, d, &wakeup_timer_milliseconds, - &pm_dbg_option_fops); pm_dbg_init_done = 1; return 0; diff --git a/trunk/arch/arm/mach-omap2/pm.c b/trunk/arch/arm/mach-omap2/pm.c index 59ca03b0e691..68f9f2e95891 100644 --- a/trunk/arch/arm/mach-omap2/pm.c +++ b/trunk/arch/arm/mach-omap2/pm.c @@ -18,15 +18,11 @@ #include #include -#include -#include - static struct omap_device_pm_latency *pm_lats; static struct device *mpu_dev; -static struct device *iva_dev; -static struct device *l3_dev; static struct device *dsp_dev; +static struct device *l3_dev; struct device *omap2_get_mpuss_device(void) { @@ -34,10 +30,10 @@ struct device *omap2_get_mpuss_device(void) return mpu_dev; } -struct device *omap2_get_iva_device(void) +struct device *omap2_get_dsp_device(void) { - WARN_ON_ONCE(!iva_dev); - return iva_dev; + WARN_ON_ONCE(!dsp_dev); + return dsp_dev; } struct device *omap2_get_l3_device(void) @@ -46,13 +42,6 @@ struct device *omap2_get_l3_device(void) return l3_dev; } -struct device *omap4_get_dsp_device(void) -{ - WARN_ON_ONCE(!dsp_dev); - return dsp_dev; -} -EXPORT_SYMBOL(omap4_get_dsp_device); - /* static int _init_omap_device(struct omap_hwmod *oh, void *user) */ static int _init_omap_device(char *name, struct device **new_dev) { @@ -80,60 +69,8 @@ static int _init_omap_device(char *name, struct device **new_dev) static void omap2_init_processor_devices(void) { _init_omap_device("mpu", &mpu_dev); - _init_omap_device("iva", &iva_dev); - if (cpu_is_omap44xx()) { - _init_omap_device("l3_main_1", &l3_dev); - _init_omap_device("dsp", &dsp_dev); - } else { - _init_omap_device("l3_main", &l3_dev); - } -} - -/* - * This sets pwrdm state (other than mpu & core. Currently only ON & - * RET are supported. Function is assuming that clkdm doesn't have - * hw_sup mode enabled. - */ -int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state) -{ - u32 cur_state; - int sleep_switch = 0; - int ret = 0; - - if (pwrdm == NULL || IS_ERR(pwrdm)) - return -EINVAL; - - while (!(pwrdm->pwrsts & (1 << state))) { - if (state == PWRDM_POWER_OFF) - return ret; - state--; - } - - cur_state = pwrdm_read_next_pwrst(pwrdm); - if (cur_state == state) - return ret; - - if (pwrdm_read_pwrst(pwrdm) < PWRDM_POWER_ON) { - omap2_clkdm_wakeup(pwrdm->pwrdm_clkdms[0]); - sleep_switch = 1; - pwrdm_wait_transition(pwrdm); - } - - ret = pwrdm_set_next_pwrst(pwrdm, state); - if (ret) { - printk(KERN_ERR "Unable to set state of powerdomain: %s\n", - pwrdm->name); - goto err; - } - - if (sleep_switch) { - omap2_clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]); - pwrdm_wait_transition(pwrdm); - pwrdm_state_switch(pwrdm); - } - -err: - return ret; + _init_omap_device("iva", &dsp_dev); + _init_omap_device("l3_main", &l3_dev); } static int __init omap2_common_pm_init(void) diff --git a/trunk/arch/arm/mach-omap2/pm.h b/trunk/arch/arm/mach-omap2/pm.h index 77770a13cea8..3de6ece23fc8 100644 --- a/trunk/arch/arm/mach-omap2/pm.h +++ b/trunk/arch/arm/mach-omap2/pm.h @@ -20,7 +20,7 @@ extern void *omap3_secure_ram_storage; extern void omap3_pm_off_mode_enable(int); extern void omap_sram_idle(void); extern int omap3_can_sleep(void); -extern int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state); +extern int set_pwrdm_state(struct powerdomain *pwrdm, u32 state); extern int omap3_idle_init(void); struct cpuidle_params { @@ -48,11 +48,9 @@ extern struct omap_dm_timer *gptimer_wakeup; #ifdef CONFIG_PM_DEBUG extern void omap2_pm_dump(int mode, int resume, unsigned int us); -extern void omap2_pm_wakeup_on_timer(u32 seconds, u32 milliseconds); extern int omap2_pm_debug; #else #define omap2_pm_dump(mode, resume, us) do {} while (0); -#define omap2_pm_wakeup_on_timer(seconds, milliseconds) do {} while (0); #define omap2_pm_debug 0 #endif diff --git a/trunk/arch/arm/mach-omap2/pm34xx.c b/trunk/arch/arm/mach-omap2/pm34xx.c index d2b940c7215d..7b03426c72a3 100644 --- a/trunk/arch/arm/mach-omap2/pm34xx.c +++ b/trunk/arch/arm/mach-omap2/pm34xx.c @@ -38,6 +38,7 @@ #include #include #include +#include #include @@ -54,6 +55,11 @@ #define OMAP343X_TABLE_VALUE_OFFSET 0x30 #define OMAP343X_CONTROL_REG_VALUE_OFFSET 0x32 +u32 enable_off_mode; +u32 sleep_while_idle; +u32 wakeup_timer_seconds; +u32 wakeup_timer_milliseconds; + struct power_state { struct powerdomain *pwrdm; u32 next_state; @@ -345,6 +351,7 @@ void omap_sram_idle(void) int core_next_state = PWRDM_POWER_ON; int core_prev_state, per_prev_state; u32 sdrc_pwr = 0; + int per_state_modified = 0; if (!_omap_sram_idle) return; @@ -378,9 +385,9 @@ void omap_sram_idle(void) /* Enable IO-PAD and IO-CHAIN wakeups */ per_next_state = pwrdm_read_next_pwrst(per_pwrdm); core_next_state = pwrdm_read_next_pwrst(core_pwrdm); - if (omap3_has_io_wakeup() && - (per_next_state < PWRDM_POWER_ON || - core_next_state < PWRDM_POWER_ON)) { + if (omap3_has_io_wakeup() && \ + (per_next_state < PWRDM_POWER_ON || + core_next_state < PWRDM_POWER_ON)) { prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN); omap3_enable_io_chain(); } @@ -389,10 +396,19 @@ void omap_sram_idle(void) if (per_next_state < PWRDM_POWER_ON) { omap_uart_prepare_idle(2); omap2_gpio_prepare_for_idle(per_next_state); - if (per_next_state == PWRDM_POWER_OFF) + if (per_next_state == PWRDM_POWER_OFF) { + if (core_next_state == PWRDM_POWER_ON) { + per_next_state = PWRDM_POWER_RET; + pwrdm_set_next_pwrst(per_pwrdm, per_next_state); + per_state_modified = 1; + } else omap3_per_save_context(); + } } + if (pwrdm_read_pwrst(cam_pwrdm) == PWRDM_POWER_ON) + omap2_clkdm_deny_idle(mpu_pwrdm->pwrdm_clkdms[0]); + /* CORE */ if (core_next_state < PWRDM_POWER_ON) { omap_uart_prepare_idle(0); @@ -459,6 +475,8 @@ void omap_sram_idle(void) if (per_prev_state == PWRDM_POWER_OFF) omap3_per_restore_context(); omap_uart_resume_idle(2); + if (per_state_modified) + pwrdm_set_next_pwrst(per_pwrdm, PWRDM_POWER_OFF); } /* Disable IO-PAD and IO-CHAIN wakeup */ @@ -483,6 +501,51 @@ int omap3_can_sleep(void) return 1; } +/* This sets pwrdm state (other than mpu & core. Currently only ON & + * RET are supported. Function is assuming that clkdm doesn't have + * hw_sup mode enabled. */ +int set_pwrdm_state(struct powerdomain *pwrdm, u32 state) +{ + u32 cur_state; + int sleep_switch = 0; + int ret = 0; + + if (pwrdm == NULL || IS_ERR(pwrdm)) + return -EINVAL; + + while (!(pwrdm->pwrsts & (1 << state))) { + if (state == PWRDM_POWER_OFF) + return ret; + state--; + } + + cur_state = pwrdm_read_next_pwrst(pwrdm); + if (cur_state == state) + return ret; + + if (pwrdm_read_pwrst(pwrdm) < PWRDM_POWER_ON) { + omap2_clkdm_wakeup(pwrdm->pwrdm_clkdms[0]); + sleep_switch = 1; + pwrdm_wait_transition(pwrdm); + } + + ret = pwrdm_set_next_pwrst(pwrdm, state); + if (ret) { + printk(KERN_ERR "Unable to set state of powerdomain: %s\n", + pwrdm->name); + goto err; + } + + if (sleep_switch) { + omap2_clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]); + pwrdm_wait_transition(pwrdm); + pwrdm_state_switch(pwrdm); + } + +err: + return ret; +} + static void omap3_pm_idle(void) { local_irq_disable(); @@ -504,6 +567,23 @@ static void omap3_pm_idle(void) #ifdef CONFIG_SUSPEND static suspend_state_t suspend_state; +static void omap2_pm_wakeup_on_timer(u32 seconds, u32 milliseconds) +{ + u32 tick_rate, cycles; + + if (!seconds && !milliseconds) + return; + + tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer_wakeup)); + cycles = tick_rate * seconds + tick_rate * milliseconds / 1000; + omap_dm_timer_stop(gptimer_wakeup); + omap_dm_timer_set_load_start(gptimer_wakeup, 0, 0xffffffff - cycles); + + pr_info("PM: Resume timer in %u.%03u secs" + " (%d ticks at %d ticks/sec.)\n", + seconds, milliseconds, cycles, tick_rate); +} + static int omap3_pm_prepare(void) { disable_hlt(); @@ -524,7 +604,7 @@ static int omap3_pm_suspend(void) pwrst->saved_state = pwrdm_read_next_pwrst(pwrst->pwrdm); /* Set ones wanted by suspend */ list_for_each_entry(pwrst, &pwrst_list, node) { - if (omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state)) + if (set_pwrdm_state(pwrst->pwrdm, pwrst->next_state)) goto restore; if (pwrdm_clear_all_prev_pwrst(pwrst->pwrdm)) goto restore; @@ -545,7 +625,7 @@ static int omap3_pm_suspend(void) pwrst->pwrdm->name, pwrst->next_state); ret = -1; } - omap_set_pwrdm_state(pwrst->pwrdm, pwrst->saved_state); + set_pwrdm_state(pwrst->pwrdm, pwrst->saved_state); } if (ret) printk(KERN_ERR "Could not enter target state in pm_suspend\n"); @@ -894,7 +974,7 @@ void omap3_pm_off_mode_enable(int enable) list_for_each_entry(pwrst, &pwrst_list, node) { pwrst->next_state = state; - omap_set_pwrdm_state(pwrst->pwrdm, state); + set_pwrdm_state(pwrst->pwrdm, state); } } @@ -939,7 +1019,7 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused) if (pwrdm_has_hdwr_sar(pwrdm)) pwrdm_enable_hdwr_sar(pwrdm); - return omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state); + return set_pwrdm_state(pwrst->pwrdm, pwrst->next_state); } /* @@ -949,6 +1029,9 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused) */ static int __init clkdms_setup(struct clockdomain *clkdm, void *unused) { + clkdm_clear_all_wkdeps(clkdm); + clkdm_clear_all_sleepdeps(clkdm); + if (clkdm->flags & CLKDM_CAN_ENABLE_AUTO) omap2_clkdm_allow_idle(clkdm); else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP && diff --git a/trunk/arch/arm/mach-omap2/pm_bus.c b/trunk/arch/arm/mach-omap2/pm_bus.c new file mode 100644 index 000000000000..784989f8f2f5 --- /dev/null +++ b/trunk/arch/arm/mach-omap2/pm_bus.c @@ -0,0 +1,85 @@ +/* + * Runtime PM support code for OMAP + * + * Author: Kevin Hilman, Deep Root Systems, LLC + * + * Copyright (C) 2010 Texas Instruments, Inc. + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifdef CONFIG_PM_RUNTIME +int omap_pm_runtime_suspend(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + int r, ret = 0; + + dev_dbg(dev, "%s\n", __func__); + + ret = pm_generic_runtime_suspend(dev); + + if (!ret && dev->parent == &omap_device_parent) { + r = omap_device_idle(pdev); + WARN_ON(r); + } + + return ret; +}; + +int omap_pm_runtime_resume(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + int r; + + dev_dbg(dev, "%s\n", __func__); + + if (dev->parent == &omap_device_parent) { + r = omap_device_enable(pdev); + WARN_ON(r); + } + + return pm_generic_runtime_resume(dev); +}; +#else +#define omap_pm_runtime_suspend NULL +#define omap_pm_runtime_resume NULL +#endif /* CONFIG_PM_RUNTIME */ + +static int __init omap_pm_runtime_init(void) +{ + const struct dev_pm_ops *pm; + struct dev_pm_ops *omap_pm; + + pm = platform_bus_get_pm_ops(); + if (!pm) { + pr_err("%s: unable to get dev_pm_ops from platform_bus\n", + __func__); + return -ENODEV; + } + + omap_pm = kmemdup(pm, sizeof(struct dev_pm_ops), GFP_KERNEL); + if (!omap_pm) { + pr_err("%s: unable to alloc memory for new dev_pm_ops\n", + __func__); + return -ENOMEM; + } + + omap_pm->runtime_suspend = omap_pm_runtime_suspend; + omap_pm->runtime_resume = omap_pm_runtime_resume; + + platform_bus_set_pm_ops(omap_pm); + + return 0; +} +core_initcall(omap_pm_runtime_init); diff --git a/trunk/arch/arm/mach-omap2/prcm.c b/trunk/arch/arm/mach-omap2/prcm.c index d4388d34c26a..c20137497c92 100644 --- a/trunk/arch/arm/mach-omap2/prcm.c +++ b/trunk/arch/arm/mach-omap2/prcm.c @@ -33,7 +33,6 @@ #include "cm.h" #include "prm.h" #include "prm-regbits-24xx.h" -#include "prm-regbits-44xx.h" static void __iomem *prm_base; static void __iomem *cm_base; @@ -162,8 +161,8 @@ void omap_prcm_arch_reset(char mode, const char *cmd) prm_set_mod_reg_bits(OMAP_RST_DPLL3_MASK, prcm_offs, OMAP2_RM_RSTCTRL); if (cpu_is_omap44xx()) - prm_set_mod_reg_bits(OMAP4430_RST_GLOBAL_WARM_SW_MASK, - prcm_offs, OMAP4_RM_RSTCTRL); + prm_set_mod_reg_bits(OMAP_RST_DPLL3_MASK, prcm_offs, + OMAP4_RM_RSTCTRL); } static inline u32 __omap_prcm_read(void __iomem *base, s16 module, u16 reg) @@ -216,30 +215,6 @@ u32 prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask) return v; } -/* Read a PRM register, AND it, and shift the result down to bit 0 */ -u32 omap4_prm_read_bits_shift(void __iomem *reg, u32 mask) -{ - u32 v; - - v = __raw_readl(reg); - v &= mask; - v >>= __ffs(mask); - - return v; -} - -/* Read-modify-write a register in a PRM module. Caller must lock */ -u32 omap4_prm_rmw_reg_bits(u32 mask, u32 bits, void __iomem *reg) -{ - u32 v; - - v = __raw_readl(reg); - v &= ~mask; - v |= bits; - __raw_writel(v, reg); - - return v; -} /* Read a register in a CM module */ u32 cm_read_mod_reg(s16 module, u16 idx) { diff --git a/trunk/arch/arm/mach-omap2/prm.h b/trunk/arch/arm/mach-omap2/prm.h index 7be040b2fdab..588873b9303a 100644 --- a/trunk/arch/arm/mach-omap2/prm.h +++ b/trunk/arch/arm/mach-omap2/prm.h @@ -5,7 +5,7 @@ * OMAP2/3 Power/Reset Management (PRM) register definitions * * Copyright (C) 2007-2009 Texas Instruments, Inc. - * Copyright (C) 2010 Nokia Corporation + * Copyright (C) 2009 Nokia Corporation * * Written by Paul Walmsley * @@ -246,15 +246,6 @@ static inline u32 prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx) return prm_rmw_mod_reg_bits(bits, 0x0, module, idx); } -/* These omap2_ PRM functions apply to both OMAP2 and 3 */ -int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift); -int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift); -int omap2_prm_deassert_hardreset(s16 prm_mod, u8 shift); - -int omap4_prm_is_hardreset_asserted(void __iomem *rstctrl_reg, u8 shift); -int omap4_prm_assert_hardreset(void __iomem *rstctrl_reg, u8 shift); -int omap4_prm_deassert_hardreset(void __iomem *rstctrl_reg, u8 shift); - #endif /* @@ -407,11 +398,4 @@ int omap4_prm_deassert_hardreset(void __iomem *rstctrl_reg, u8 shift); #define OMAP_POWERSTATE_MASK (0x3 << 0) -/* - * MAX_MODULE_HARDRESET_WAIT: Maximum microseconds to wait for an OMAP - * submodule to exit hardreset - */ -#define MAX_MODULE_HARDRESET_WAIT 10000 - - #endif diff --git a/trunk/arch/arm/mach-omap2/prm2xxx_3xxx.c b/trunk/arch/arm/mach-omap2/prm2xxx_3xxx.c deleted file mode 100644 index 421771eee450..000000000000 --- a/trunk/arch/arm/mach-omap2/prm2xxx_3xxx.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * OMAP2/3 PRM module functions - * - * Copyright (C) 2010 Texas Instruments, Inc. - * Copyright (C) 2010 Nokia Corporation - * Benoît Cousson - * Paul Walmsley - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include - -#include -#include -#include - -#include "prm.h" -#include "prm-regbits-24xx.h" -#include "prm-regbits-34xx.h" - -/** - * omap2_prm_is_hardreset_asserted - read the HW reset line state of - * submodules contained in the hwmod module - * @prm_mod: PRM submodule base (e.g. CORE_MOD) - * @shift: register bit shift corresponding to the reset line to check - * - * Returns 1 if the (sub)module hardreset line is currently asserted, - * 0 if the (sub)module hardreset line is not currently asserted, or - * -EINVAL if called while running on a non-OMAP2/3 chip. - */ -int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift) -{ - if (!(cpu_is_omap24xx() || cpu_is_omap34xx())) - return -EINVAL; - - return prm_read_mod_bits_shift(prm_mod, OMAP2_RM_RSTCTRL, - (1 << shift)); -} - -/** - * omap2_prm_assert_hardreset - assert the HW reset line of a submodule - * @prm_mod: PRM submodule base (e.g. CORE_MOD) - * @shift: register bit shift corresponding to the reset line to assert - * - * Some IPs like dsp or iva contain processors that require an HW - * reset line to be asserted / deasserted in order to fully enable the - * IP. These modules may have multiple hard-reset lines that reset - * different 'submodules' inside the IP block. This function will - * place the submodule into reset. Returns 0 upon success or -EINVAL - * upon an argument error. - */ -int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift) -{ - u32 mask; - - if (!(cpu_is_omap24xx() || cpu_is_omap34xx())) - return -EINVAL; - - mask = 1 << shift; - prm_rmw_mod_reg_bits(mask, mask, prm_mod, OMAP2_RM_RSTCTRL); - - return 0; -} - -/** - * omap2_prm_deassert_hardreset - deassert a submodule hardreset line and wait - * @prm_mod: PRM submodule base (e.g. CORE_MOD) - * @shift: register bit shift corresponding to the reset line to deassert - * - * Some IPs like dsp or iva contain processors that require an HW - * reset line to be asserted / deasserted in order to fully enable the - * IP. These modules may have multiple hard-reset lines that reset - * different 'submodules' inside the IP block. This function will - * take the submodule out of reset and wait until the PRCM indicates - * that the reset has completed before returning. Returns 0 upon success or - * -EINVAL upon an argument error, -EEXIST if the submodule was already out - * of reset, or -EBUSY if the submodule did not exit reset promptly. - */ -int omap2_prm_deassert_hardreset(s16 prm_mod, u8 shift) -{ - u32 mask; - int c; - - if (!(cpu_is_omap24xx() || cpu_is_omap34xx())) - return -EINVAL; - - mask = 1 << shift; - - /* Check the current status to avoid de-asserting the line twice */ - if (prm_read_mod_bits_shift(prm_mod, OMAP2_RM_RSTCTRL, mask) == 0) - return -EEXIST; - - /* Clear the reset status by writing 1 to the status bit */ - prm_rmw_mod_reg_bits(0xffffffff, mask, prm_mod, OMAP2_RM_RSTST); - /* de-assert the reset control line */ - prm_rmw_mod_reg_bits(mask, 0, prm_mod, OMAP2_RM_RSTCTRL); - /* wait the status to be set */ - omap_test_timeout(prm_read_mod_bits_shift(prm_mod, OMAP2_RM_RSTST, - mask), - MAX_MODULE_HARDRESET_WAIT, c); - - return (c == MAX_MODULE_HARDRESET_WAIT) ? -EBUSY : 0; -} - diff --git a/trunk/arch/arm/mach-omap2/prm44xx.c b/trunk/arch/arm/mach-omap2/prm44xx.c deleted file mode 100644 index a1ff918d9bed..000000000000 --- a/trunk/arch/arm/mach-omap2/prm44xx.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * OMAP4 PRM module functions - * - * Copyright (C) 2010 Texas Instruments, Inc. - * Copyright (C) 2010 Nokia Corporation - * Benoît Cousson - * Paul Walmsley - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include - -#include -#include -#include - -#include "prm.h" -#include "prm-regbits-44xx.h" - -/* - * Address offset (in bytes) between the reset control and the reset - * status registers: 4 bytes on OMAP4 - */ -#define OMAP4_RST_CTRL_ST_OFFSET 4 - -/** - * omap4_prm_is_hardreset_asserted - read the HW reset line state of - * submodules contained in the hwmod module - * @rstctrl_reg: RM_RSTCTRL register address for this module - * @shift: register bit shift corresponding to the reset line to check - * - * Returns 1 if the (sub)module hardreset line is currently asserted, - * 0 if the (sub)module hardreset line is not currently asserted, or - * -EINVAL upon parameter error. - */ -int omap4_prm_is_hardreset_asserted(void __iomem *rstctrl_reg, u8 shift) -{ - if (!cpu_is_omap44xx() || !rstctrl_reg) - return -EINVAL; - - return omap4_prm_read_bits_shift(rstctrl_reg, (1 << shift)); -} - -/** - * omap4_prm_assert_hardreset - assert the HW reset line of a submodule - * @rstctrl_reg: RM_RSTCTRL register address for this module - * @shift: register bit shift corresponding to the reset line to assert - * - * Some IPs like dsp, ipu or iva contain processors that require an HW - * reset line to be asserted / deasserted in order to fully enable the - * IP. These modules may have multiple hard-reset lines that reset - * different 'submodules' inside the IP block. This function will - * place the submodule into reset. Returns 0 upon success or -EINVAL - * upon an argument error. - */ -int omap4_prm_assert_hardreset(void __iomem *rstctrl_reg, u8 shift) -{ - u32 mask; - - if (!cpu_is_omap44xx() || !rstctrl_reg) - return -EINVAL; - - mask = 1 << shift; - omap4_prm_rmw_reg_bits(mask, mask, rstctrl_reg); - - return 0; -} - -/** - * omap4_prm_deassert_hardreset - deassert a submodule hardreset line and wait - * @rstctrl_reg: RM_RSTCTRL register address for this module - * @shift: register bit shift corresponding to the reset line to deassert - * - * Some IPs like dsp, ipu or iva contain processors that require an HW - * reset line to be asserted / deasserted in order to fully enable the - * IP. These modules may have multiple hard-reset lines that reset - * different 'submodules' inside the IP block. This function will - * take the submodule out of reset and wait until the PRCM indicates - * that the reset has completed before returning. Returns 0 upon success or - * -EINVAL upon an argument error, -EEXIST if the submodule was already out - * of reset, or -EBUSY if the submodule did not exit reset promptly. - */ -int omap4_prm_deassert_hardreset(void __iomem *rstctrl_reg, u8 shift) -{ - u32 mask; - void __iomem *rstst_reg; - int c; - - if (!cpu_is_omap44xx() || !rstctrl_reg) - return -EINVAL; - - rstst_reg = rstctrl_reg + OMAP4_RST_CTRL_ST_OFFSET; - - mask = 1 << shift; - - /* Check the current status to avoid de-asserting the line twice */ - if (omap4_prm_read_bits_shift(rstctrl_reg, mask) == 0) - return -EEXIST; - - /* Clear the reset status by writing 1 to the status bit */ - omap4_prm_rmw_reg_bits(0xffffffff, mask, rstst_reg); - /* de-assert the reset control line */ - omap4_prm_rmw_reg_bits(mask, 0, rstctrl_reg); - /* wait the status to be set */ - omap_test_timeout(omap4_prm_read_bits_shift(rstst_reg, mask), - MAX_MODULE_HARDRESET_WAIT, c); - - return (c == MAX_MODULE_HARDRESET_WAIT) ? -EBUSY : 0; -} - diff --git a/trunk/arch/arm/plat-omap/Makefile b/trunk/arch/arm/plat-omap/Makefile index 2a151917ef52..9405831b746a 100644 --- a/trunk/arch/arm/plat-omap/Makefile +++ b/trunk/arch/arm/plat-omap/Makefile @@ -31,4 +31,4 @@ obj-y += $(i2c-omap-m) $(i2c-omap-y) # OMAP mailbox framework obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox.o -obj-$(CONFIG_OMAP_PM_NOOP) += omap-pm-noop.o +obj-$(CONFIG_OMAP_PM_NOOP) += omap-pm-noop.o \ No newline at end of file diff --git a/trunk/arch/arm/plat-omap/gpio.c b/trunk/arch/arm/plat-omap/gpio.c index 11c5b0eefb85..7951eefe1a0e 100644 --- a/trunk/arch/arm/plat-omap/gpio.c +++ b/trunk/arch/arm/plat-omap/gpio.c @@ -2085,9 +2085,8 @@ void omap2_gpio_prepare_for_idle(int power_state) for (i = min; i < gpio_bank_count; i++) { struct gpio_bank *bank = &gpio_bank[i]; u32 l1, l2; - int j; - for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++) + if (bank->dbck_enable_mask) clk_disable(bank->dbck); if (power_state > PWRDM_POWER_OFF) @@ -2153,9 +2152,8 @@ void omap2_gpio_resume_after_idle(void) for (i = min; i < gpio_bank_count; i++) { struct gpio_bank *bank = &gpio_bank[i]; u32 l, gen, gen0, gen1; - int j; - for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++) + if (bank->dbck_enable_mask) clk_enable(bank->dbck); if (!workaround_enabled) diff --git a/trunk/arch/arm/plat-omap/include/plat/common.h b/trunk/arch/arm/plat-omap/include/plat/common.h index c45dbb975e09..9776b41ad76f 100644 --- a/trunk/arch/arm/plat-omap/include/plat/common.h +++ b/trunk/arch/arm/plat-omap/include/plat/common.h @@ -91,8 +91,7 @@ void omap3_map_io(void); }) extern struct device *omap2_get_mpuss_device(void); -extern struct device *omap2_get_iva_device(void); +extern struct device *omap2_get_dsp_device(void); extern struct device *omap2_get_l3_device(void); -extern struct device *omap4_get_dsp_device(void); #endif /* __ARCH_ARM_MACH_OMAP_COMMON_H */ diff --git a/trunk/arch/arm/plat-omap/include/plat/omap_device.h b/trunk/arch/arm/plat-omap/include/plat/omap_device.h index 28e2d1a78433..25cd9ac3b095 100644 --- a/trunk/arch/arm/plat-omap/include/plat/omap_device.h +++ b/trunk/arch/arm/plat-omap/include/plat/omap_device.h @@ -36,8 +36,6 @@ #include -extern struct device omap_device_parent; - /* omap_device._state values */ #define OMAP_DEVICE_STATE_UNKNOWN 0 #define OMAP_DEVICE_STATE_ENABLED 1 @@ -64,6 +62,7 @@ extern struct device omap_device_parent; * */ struct omap_device { + u32 magic; struct platform_device pdev; struct omap_hwmod **hwmods; struct omap_device_pm_latency *pm_lats; @@ -83,6 +82,7 @@ int omap_device_shutdown(struct platform_device *pdev); /* Core code interface */ +bool omap_device_is_valid(struct omap_device *od); int omap_device_count_resources(struct omap_device *od); int omap_device_fill_resources(struct omap_device *od, struct resource *res); diff --git a/trunk/arch/arm/plat-omap/include/plat/omap_hwmod.h b/trunk/arch/arm/plat-omap/include/plat/omap_hwmod.h index c1835afc238d..a4e508dfaba2 100644 --- a/trunk/arch/arm/plat-omap/include/plat/omap_hwmod.h +++ b/trunk/arch/arm/plat-omap/include/plat/omap_hwmod.h @@ -14,16 +14,19 @@ * * These headers and macros are used to define OMAP on-chip module * data and their integration with other OMAP modules and Linux. - * Copious documentation and references can also be found in the - * omap_hwmod code, in arch/arm/mach-omap2/omap_hwmod.c (as of this - * writing). + * + * References: + * - OMAP2420 Multimedia Processor Silicon Revision 2.1.1, 2.2 (SWPU064) + * - OMAP2430 Multimedia Device POP Silicon Revision 2.1 (SWPU090) + * - OMAP34xx Multimedia Device Silicon Revision 3.1 (SWPU108) + * - OMAP4430 Multimedia Device Silicon Revision 1.0 (SWPU140) + * - Open Core Protocol Specification 2.2 * * To do: * - add interconnect error log structures * - add pinmuxing * - init_conn_id_bit (CONNID_BIT_VECTOR) * - implement default hwmod SMS/SDRC flags? - * - remove unused fields * */ #ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD_H @@ -32,7 +35,6 @@ #include #include #include -#include #include struct omap_device; @@ -94,7 +96,7 @@ struct omap_hwmod_irq_info { /** * struct omap_hwmod_dma_info - DMA channels used by the hwmod * @name: name of the DMA channel (module local name) - * @dma_req: DMA request ID + * @dma_ch: DMA channel ID * * @name should be something short, e.g., "tx" or "rx". It is for use * by platform_get_resource_byname(). It is defined locally to the @@ -102,20 +104,7 @@ struct omap_hwmod_irq_info { */ struct omap_hwmod_dma_info { const char *name; - u16 dma_req; -}; - -/** - * struct omap_hwmod_rst_info - IPs reset lines use by hwmod - * @name: name of the reset line (module local name) - * @rst_shift: Offset of the reset bit - * - * @name should be something short, e.g., "cpu0" or "rst". It is defined - * locally to the hwmod. - */ -struct omap_hwmod_rst_info { - const char *name; - u8 rst_shift; + u16 dma_ch; }; /** @@ -248,9 +237,8 @@ struct omap_hwmod_ocp_if { #define SYSC_HAS_CLOCKACTIVITY (1 << 4) #define SYSC_HAS_SIDLEMODE (1 << 5) #define SYSC_HAS_MIDLEMODE (1 << 6) -#define SYSS_HAS_RESET_STATUS (1 << 7) +#define SYSS_MISSING (1 << 7) #define SYSC_NO_CACHE (1 << 8) /* XXX SW flag, belongs elsewhere */ -#define SYSC_HAS_RESET_STATUS (1 << 9) /* omap_hwmod_sysconfig.clockact flags */ #define CLOCKACT_TEST_BOTH 0x0 @@ -339,12 +327,10 @@ struct omap_hwmod_omap2_prcm { /** * struct omap_hwmod_omap4_prcm - OMAP4-specific PRCM data * @clkctrl_reg: PRCM address of the clock control register - * @rstctrl_reg: adress of the XXX_RSTCTRL register located in the PRM * @submodule_wkdep_bit: bit shift of the WKDEP range */ struct omap_hwmod_omap4_prcm { void __iomem *clkctrl_reg; - void __iomem *rstctrl_reg; u8 submodule_wkdep_bit; }; @@ -366,10 +352,6 @@ struct omap_hwmod_omap4_prcm { * HWMOD_SET_DEFAULT_CLOCKACT: program CLOCKACTIVITY bits at startup * HWMOD_NO_IDLEST : this module does not have idle status - this is the case * only for few initiator modules on OMAP2 & 3. - * HWMOD_CONTROL_OPT_CLKS_IN_RESET: Enable all optional clocks during reset. - * This is needed for devices like DSS that require optional clocks enabled - * in order to complete the reset. Optional clocks will be disabled - * again after the reset. */ #define HWMOD_SWSUP_SIDLE (1 << 0) #define HWMOD_SWSUP_MSTANDBY (1 << 1) @@ -378,7 +360,6 @@ struct omap_hwmod_omap4_prcm { #define HWMOD_NO_OCP_AUTOIDLE (1 << 4) #define HWMOD_SET_DEFAULT_CLOCKACT (1 << 5) #define HWMOD_NO_IDLEST (1 << 6) -#define HWMOD_CONTROL_OPT_CLKS_IN_RESET (1 << 7) /* * omap_hwmod._int_flags definitions @@ -429,7 +410,7 @@ struct omap_hwmod_class { * @class: struct omap_hwmod_class * to the class of this hwmod * @od: struct omap_device currently associated with this hwmod (internal use) * @mpu_irqs: ptr to an array of MPU IRQs (see also mpu_irqs_cnt) - * @sdma_reqs: ptr to an array of System DMA request IDs (see sdma_reqs_cnt) + * @sdma_chs: ptr to an array of SDMA channel IDs (see also sdma_chs_cnt) * @prcm: PRCM data pertaining to this hwmod * @main_clk: main clock: OMAP clock name * @_clk: pointer to the main struct clk (filled in at runtime) @@ -443,7 +424,7 @@ struct omap_hwmod_class { * @msuspendmux_reg_id: CONTROL_MSUSPENDMUX register ID (1-6) * @msuspendmux_shift: CONTROL_MSUSPENDMUX register bit shift * @mpu_irqs_cnt: number of @mpu_irqs - * @sdma_reqs_cnt: number of @sdma_reqs + * @sdma_chs_cnt: number of @sdma_chs * @opt_clks_cnt: number of @opt_clks * @master_cnt: number of @master entries * @slaves_cnt: number of @slave entries @@ -452,7 +433,6 @@ struct omap_hwmod_class { * @_state: internal-use hwmod state * @flags: hwmod flags (documented below) * @omap_chip: OMAP chips this hwmod is present on - * @_mutex: mutex serializing operations on this hwmod * @node: list node for hwmod list (internal use) * * @main_clk refers to this module's "main clock," which for our @@ -468,8 +448,7 @@ struct omap_hwmod { struct omap_hwmod_class *class; struct omap_device *od; struct omap_hwmod_irq_info *mpu_irqs; - struct omap_hwmod_dma_info *sdma_reqs; - struct omap_hwmod_rst_info *rst_lines; + struct omap_hwmod_dma_info *sdma_chs; union { struct omap_hwmod_omap2_prcm omap2; struct omap_hwmod_omap4_prcm omap4; @@ -482,7 +461,6 @@ struct omap_hwmod { void *dev_attr; u32 _sysc_cache; void __iomem *_mpu_rt_va; - struct mutex _mutex; struct list_head node; u16 flags; u8 _mpu_port_index; @@ -490,8 +468,7 @@ struct omap_hwmod { u8 msuspendmux_shift; u8 response_lat; u8 mpu_irqs_cnt; - u8 sdma_reqs_cnt; - u8 rst_lines_cnt; + u8 sdma_chs_cnt; u8 opt_clks_cnt; u8 masters_cnt; u8 slaves_cnt; @@ -515,10 +492,6 @@ int omap_hwmod_idle(struct omap_hwmod *oh); int _omap_hwmod_idle(struct omap_hwmod *oh); int omap_hwmod_shutdown(struct omap_hwmod *oh); -int omap_hwmod_assert_hardreset(struct omap_hwmod *oh, const char *name); -int omap_hwmod_deassert_hardreset(struct omap_hwmod *oh, const char *name); -int omap_hwmod_read_hardreset(struct omap_hwmod *oh, const char *name); - int omap_hwmod_enable_clocks(struct omap_hwmod *oh); int omap_hwmod_disable_clocks(struct omap_hwmod *oh); @@ -561,6 +534,5 @@ int omap_hwmod_for_each_by_class(const char *classname, extern int omap2420_hwmod_init(void); extern int omap2430_hwmod_init(void); extern int omap3xxx_hwmod_init(void); -extern int omap44xx_hwmod_init(void); #endif diff --git a/trunk/arch/arm/plat-omap/include/plat/prcm.h b/trunk/arch/arm/plat-omap/include/plat/prcm.h index ab77442e42ab..9fbd91419cd1 100644 --- a/trunk/arch/arm/plat-omap/include/plat/prcm.h +++ b/trunk/arch/arm/plat-omap/include/plat/prcm.h @@ -38,8 +38,6 @@ u32 prm_read_mod_reg(s16 module, u16 idx); void prm_write_mod_reg(u32 val, s16 module, u16 idx); u32 prm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx); u32 prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask); -u32 omap4_prm_read_bits_shift(void __iomem *reg, u32 mask); -u32 omap4_prm_rmw_reg_bits(u32 mask, u32 bits, void __iomem *reg); u32 cm_read_mod_reg(s16 module, u16 idx); void cm_write_mod_reg(u32 val, s16 module, u16 idx); u32 cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx); diff --git a/trunk/arch/arm/plat-omap/omap_device.c b/trunk/arch/arm/plat-omap/omap_device.c index b5e5f6074b0b..d2b160942ccc 100644 --- a/trunk/arch/arm/plat-omap/omap_device.c +++ b/trunk/arch/arm/plat-omap/omap_device.c @@ -82,7 +82,6 @@ #include #include #include -#include #include #include @@ -91,6 +90,12 @@ #define USE_WAKEUP_LAT 0 #define IGNORE_WAKEUP_LAT 1 +/* + * OMAP_DEVICE_MAGIC: used to determine whether a struct omap_device + * obtained via container_of() is in fact a struct omap_device + */ +#define OMAP_DEVICE_MAGIC 0xf00dcafe + /* Private functions */ /** @@ -238,44 +243,6 @@ static inline struct omap_device *_find_by_pdev(struct platform_device *pdev) return container_of(pdev, struct omap_device, pdev); } -/** - * _add_optional_clock_alias - Add clock alias for hwmod optional clocks - * @od: struct omap_device *od - * - * For every optional clock present per hwmod per omap_device, this function - * adds an entry in the clocks list of the form - * if an entry is already present in it with the form - * - * The function is called from inside omap_device_build_ss(), after - * omap_device_register. - * - * This allows drivers to get a pointer to its optional clocks based on its role - * by calling clk_get(, ). - * - * No return value. - */ -static void _add_optional_clock_alias(struct omap_device *od, - struct omap_hwmod *oh) -{ - int i; - - for (i = 0; i < oh->opt_clks_cnt; i++) { - struct omap_hwmod_opt_clk *oc; - int r; - - oc = &oh->opt_clks[i]; - - if (!oc->_clk) - continue; - - r = clk_add_alias(oc->role, dev_name(&od->pdev.dev), - (char *)oc->clk, &od->pdev.dev); - if (r) - pr_err("omap_device: %s: clk_add_alias for %s failed\n", - dev_name(&od->pdev.dev), oc->role); - } -} - /* Public functions for use by core code */ @@ -447,15 +414,15 @@ struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id, od->pm_lats = pm_lats; od->pm_lats_cnt = pm_lats_cnt; + od->magic = OMAP_DEVICE_MAGIC; + if (is_early_device) ret = omap_early_device_register(od); else ret = omap_device_register(od); - for (i = 0; i < oh_cnt; i++) { + for (i = 0; i < oh_cnt; i++) hwmods[i]->od = od; - _add_optional_clock_alias(od, hwmods[i]); - } if (ret) goto odbs_exit4; @@ -506,7 +473,6 @@ int omap_device_register(struct omap_device *od) { pr_debug("omap_device: %s: registering\n", od->pdev.name); - od->pdev.dev.parent = &omap_device_parent; return platform_device_register(&od->pdev); } @@ -660,6 +626,18 @@ int omap_device_align_pm_lat(struct platform_device *pdev, return ret; } +/** + * omap_device_is_valid - Check if pointer is a valid omap_device + * @od: struct omap_device * + * + * Return whether struct omap_device pointer @od points to a valid + * omap_device. + */ +bool omap_device_is_valid(struct omap_device *od) +{ + return (od && od->magic == OMAP_DEVICE_MAGIC); +} + /** * omap_device_get_pwrdm - return the powerdomain * associated with @od * @od: struct omap_device * @@ -779,14 +757,3 @@ int omap_device_enable_clocks(struct omap_device *od) /* XXX pass along return value here? */ return 0; } - -struct device omap_device_parent = { - .init_name = "omap", - .parent = &platform_bus, -}; - -static int __init omap_device_init(void) -{ - return device_register(&omap_device_parent); -} -core_initcall(omap_device_init);