]> git.karo-electronics.de Git - mv-sheeva.git/commitdiff
Merge branch 'devel-boards' into omap-for-linus
authorTony Lindgren <tony@atomide.com>
Mon, 27 Sep 2010 17:19:44 +0000 (10:19 -0700)
committerTony Lindgren <tony@atomide.com>
Mon, 27 Sep 2010 17:19:44 +0000 (10:19 -0700)
63 files changed:
arch/arm/mach-omap1/Makefile
arch/arm/mach-omap1/board-htcherald.c
arch/arm/mach-omap1/pm_bus.c [new file with mode: 0644]
arch/arm/mach-omap2/Makefile
arch/arm/mach-omap2/board-2430sdp.c
arch/arm/mach-omap2/board-3430sdp.c
arch/arm/mach-omap2/board-4430sdp.c
arch/arm/mach-omap2/board-cm-t35.c
arch/arm/mach-omap2/board-devkit8000.c
arch/arm/mach-omap2/board-igep0020.c
arch/arm/mach-omap2/board-ldp.c
arch/arm/mach-omap2/board-n8x0.c
arch/arm/mach-omap2/board-omap3beagle.c
arch/arm/mach-omap2/board-omap3evm.c
arch/arm/mach-omap2/board-omap3pandora.c
arch/arm/mach-omap2/board-omap3stalker.c
arch/arm/mach-omap2/board-omap3touchbook.c
arch/arm/mach-omap2/board-omap4panda.c
arch/arm/mach-omap2/board-overo.c
arch/arm/mach-omap2/board-rx51-peripherals.c
arch/arm/mach-omap2/board-zoom-peripherals.c
arch/arm/mach-omap2/clock2420_data.c
arch/arm/mach-omap2/clock2430_data.c
arch/arm/mach-omap2/clock3xxx_data.c
arch/arm/mach-omap2/clockdomain.c
arch/arm/mach-omap2/cm4xxx.c
arch/arm/mach-omap2/cpuidle34xx.c
arch/arm/mach-omap2/devices.c
arch/arm/mach-omap2/hsmmc.c
arch/arm/mach-omap2/hsmmc.h
arch/arm/mach-omap2/id.c
arch/arm/mach-omap2/io.c
arch/arm/mach-omap2/mcbsp.c
arch/arm/mach-omap2/mux.c
arch/arm/mach-omap2/omap4-common.c
arch/arm/mach-omap2/omap_hwmod.c
arch/arm/mach-omap2/omap_hwmod_44xx_data.c [new file with mode: 0644]
arch/arm/mach-omap2/pm-debug.c
arch/arm/mach-omap2/pm.c
arch/arm/mach-omap2/pm.h
arch/arm/mach-omap2/pm34xx.c
arch/arm/mach-omap2/pm_bus.c [new file with mode: 0644]
arch/arm/mach-omap2/prcm.c
arch/arm/mach-omap2/prm.h
arch/arm/mach-omap2/prm2xxx_3xxx.c [new file with mode: 0644]
arch/arm/mach-omap2/prm44xx.c [new file with mode: 0644]
arch/arm/plat-omap/Makefile
arch/arm/plat-omap/dmtimer.c
arch/arm/plat-omap/gpio.c
arch/arm/plat-omap/include/plat/common.h
arch/arm/plat-omap/include/plat/cpu.h
arch/arm/plat-omap/include/plat/i2c.h
arch/arm/plat-omap/include/plat/mmc.h
arch/arm/plat-omap/include/plat/omap_device.h
arch/arm/plat-omap/include/plat/omap_hwmod.h
arch/arm/plat-omap/include/plat/prcm.h
arch/arm/plat-omap/include/plat/uncompress.h
arch/arm/plat-omap/include/plat/usb.h
arch/arm/plat-omap/mcbsp.c
arch/arm/plat-omap/omap_device.c
arch/arm/plat-omap/sram.c
drivers/mmc/host/omap.c
drivers/mmc/host/omap_hsmmc.c

index facfaeb1ae5cb2837ff71903f793b9453e1b769c..9a304d854e3343486d4410ce6696d80a67aebffe 100644 (file)
@@ -12,7 +12,7 @@ obj-$(CONFIG_OMAP_MPU_TIMER)  += time.o
 obj-$(CONFIG_OMAP_32K_TIMER)   += timer32k.o
 
 # Power Management
-obj-$(CONFIG_PM) += pm.o sleep.o
+obj-$(CONFIG_PM) += pm.o sleep.o pm_bus.o
 
 # DSP
 obj-$(CONFIG_OMAP_MBOX_FWK)    += mailbox_mach.o
index 311899ff5ffcdfee5425f2f949cd1828863eea2b..7ea75c11653c25178dbaa16c02a1f31c5bd31edb 100644 (file)
 #include <linux/input.h>
 #include <linux/io.h>
 #include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+#include <linux/htcpld.h>
+#include <linux/leds.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -39,6 +46,7 @@
 #include <plat/board.h>
 #include <plat/keypad.h>
 #include <plat/usb.h>
+#include <plat/mmc.h>
 
 #include <mach/irqs.h>
 
 #define       OMAP_LCDC_CTRL_LCD_EN           (1 << 0)
 #define       OMAP_LCDC_STAT_DONE             (1 << 0)
 
-static struct omap_lcd_config htcherald_lcd_config __initdata = {
-       .ctrl_name      = "internal",
-};
+/* 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
 
-static struct omap_board_config_kernel htcherald_config[] __initdata = {
-       { OMAP_TAG_LCD, &htcherald_lcd_config },
-};
+/* 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)
+
+/*
+ * 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)
 
 /* Keyboard definition */
 
@@ -140,6 +258,129 @@ 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,
@@ -150,14 +391,72 @@ 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,
+       }
 };
 
 /*
@@ -278,6 +577,7 @@ 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;
@@ -288,6 +588,16 @@ 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/arch/arm/mach-omap1/pm_bus.c b/arch/arm/mach-omap1/pm_bus.c
new file mode 100644 (file)
index 0000000..8b66392
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * Runtime PM support code for OMAP1
+ *
+ * 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 <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/pm_runtime.h>
+#include <linux/platform_device.h>
+#include <linux/mutex.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include <plat/omap_device.h>
+#include <plat/omap-pm.h>
+
+#ifdef CONFIG_PM_RUNTIME
+static int omap1_pm_runtime_suspend(struct device *dev)
+{
+       struct clk *iclk, *fclk;
+       int ret = 0;
+
+       dev_dbg(dev, "%s\n", __func__);
+
+       ret = pm_generic_runtime_suspend(dev);
+
+       fclk = clk_get(dev, "fck");
+       if (!IS_ERR(fclk)) {
+               clk_disable(fclk);
+               clk_put(fclk);
+       }
+
+       iclk = clk_get(dev, "ick");
+       if (!IS_ERR(iclk)) {
+               clk_disable(iclk);
+               clk_put(iclk);
+       }
+
+       return 0;
+};
+
+static int omap1_pm_runtime_resume(struct device *dev)
+{
+       int ret = 0;
+       struct clk *iclk, *fclk;
+
+       dev_dbg(dev, "%s\n", __func__);
+
+       iclk = clk_get(dev, "ick");
+       if (!IS_ERR(iclk)) {
+               clk_enable(iclk);
+               clk_put(iclk);
+       }
+
+       fclk = clk_get(dev, "fck");
+       if (!IS_ERR(fclk)) {
+               clk_enable(fclk);
+               clk_put(fclk);
+       }
+
+       return pm_generic_runtime_resume(dev);
+};
+
+static int __init omap1_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 = omap1_pm_runtime_suspend;
+       omap_pm->runtime_resume = omap1_pm_runtime_resume;
+
+       platform_bus_set_pm_ops(omap_pm);
+
+       return 0;
+}
+core_initcall(omap1_pm_runtime_init);
+#endif /* CONFIG_PM_RUNTIME */
index 88d3a1e920f583110a88aa8c90bbe7903b098f8f..e599ae2a5de42ff44a374bb6ecf5fe76473d327d 100644 (file)
@@ -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
+omap-2-3-common                                = irq.o sdrc.o prm2xxx_3xxx.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) $(hwmod-common)
+obj-$(CONFIG_ARCH_OMAP4) += $(prcm-common) prm44xx.o $(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,6 +91,7 @@ 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
index 8538e4131d27670de9b7f0c4a2a32c075f6cf27b..fc178a022dd24fcb931deb3898845ffb179bfdc2 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/physmap.h>
+#include <linux/mmc/host.h>
 #include <linux/delay.h>
 #include <linux/i2c/twl.h>
 #include <linux/err.h>
@@ -190,7 +191,7 @@ static int __init omap2430_i2c_init(void)
 static struct omap2_hsmmc_info mmc[] __initdata = {
        {
                .mmc            = 1,
-               .wires          = 4,
+               .caps           = MMC_CAP_4_BIT_DATA,
                .gpio_cd        = -EINVAL,
                .gpio_wp        = -EINVAL,
                .ext_clock      = 1,
index 67b95b5f1a2f62d8270a92a5a5cf1d7bcee57b0e..3eb9839e33ed165783cf40c7d62c17cff4f31d41 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/regulator/machine.h>
 #include <linux/io.h>
 #include <linux/gpio.h>
+#include <linux/mmc/host.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
@@ -353,12 +354,12 @@ static struct omap2_hsmmc_info mmc[] = {
                /* 8 bits (default) requires S6.3 == ON,
                 * so the SIM card isn't used; else 4 bits.
                 */
-               .wires          = 8,
+               .caps           = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
                .gpio_wp        = 4,
        },
        {
                .mmc            = 2,
-               .wires          = 8,
+               .caps           = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
                .gpio_wp        = 7,
        },
        {}      /* Terminator */
index d2b917382b423ef656e2ad4f13995013dd551ded..1bed1e666a60d88130e62b45f8753d33f063614f 100644 (file)
@@ -233,12 +233,12 @@ static struct omap_musb_board_data musb_board_data = {
 static struct omap2_hsmmc_info mmc[] = {
        {
                .mmc            = 1,
-               .wires          = 8,
+               .caps           = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
                .gpio_wp        = -EINVAL,
        },
        {
                .mmc            = 2,
-               .wires          = 8,
+               .caps           =  MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
                .gpio_cd        = -EINVAL,
                .gpio_wp        = -EINVAL,
                .nonremovable   = true,
index e10bc109415c4d3793b89b3e6e6ac1580311645a..b72009a50f01724d4d68139e18c6b382885c1267 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/i2c/at24.h>
 #include <linux/i2c/twl.h>
 #include <linux/regulator/machine.h>
+#include <linux/mmc/host.h>
 
 #include <linux/spi/spi.h>
 #include <linux/spi/tdo24m.h>
@@ -579,14 +580,14 @@ static struct twl4030_keypad_data cm_t35_kp_data = {
 static struct omap2_hsmmc_info mmc[] = {
        {
                .mmc            = 1,
-               .wires          = 4,
+               .caps           = MMC_CAP_4_BIT_DATA,
                .gpio_cd        = -EINVAL,
                .gpio_wp        = -EINVAL,
 
        },
        {
                .mmc            = 2,
-               .wires          = 4,
+               .caps           = MMC_CAP_4_BIT_DATA,
                .transceiver    = 1,
                .gpio_cd        = -EINVAL,
                .gpio_wp        = -EINVAL,
index a07086d6a0b26b6cb7d7fbe7d810ea330bcdae28..de5e2c2f4e80421c400af1e096881368d43355b2 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/nand.h>
+#include <linux/mmc/host.h>
 
 #include <linux/regulator/machine.h>
 #include <linux/i2c/twl.h>
@@ -105,7 +106,7 @@ static struct omap_nand_platform_data devkit8000_nand_data = {
 static struct omap2_hsmmc_info mmc[] = {
        {
                .mmc            = 1,
-               .wires          = 8,
+               .caps           = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
                .gpio_wp        = 29,
        },
        {}      /* Terminator */
index 175f043397612df6bc764a668338789d301e69c2..f3f0280569168db441e61fea37e0f50da2075ca0 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <linux/regulator/machine.h>
 #include <linux/i2c/twl.h>
+#include <linux/mmc/host.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -248,13 +249,13 @@ static struct regulator_init_data igep2_vmmc2 = {
 static struct omap2_hsmmc_info mmc[] = {
        {
                .mmc            = 1,
-               .wires          = 4,
+               .caps           = MMC_CAP_4_BIT_DATA,
                .gpio_cd        = -EINVAL,
                .gpio_wp        = -EINVAL,
        },
        {
                .mmc            = 2,
-               .wires          = 4,
+               .caps           = MMC_CAP_4_BIT_DATA,
                .gpio_cd        = -EINVAL,
                .gpio_wp        = -EINVAL,
        },
index 00d9b13b01c5938e0118ced2a8801595dede232f..58698e359ccf62ef463505adb262259fdb1beacb 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/i2c/twl.h>
 #include <linux/io.h>
 #include <linux/smsc911x.h>
+#include <linux/mmc/host.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
@@ -362,7 +363,7 @@ static int __init omap_i2c_init(void)
 static struct omap2_hsmmc_info mmc[] __initdata = {
        {
                .mmc            = 1,
-               .wires          = 4,
+               .caps           = MMC_CAP_4_BIT_DATA,
                .gpio_cd        = -EINVAL,
                .gpio_wp        = -EINVAL,
        },
index a3e2b49aa39f001046c0994b09c64aa14cd10581..7a93bd5b24c522e6654e54bb4903131bf8b1fb9d 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/i2c.h>
 #include <linux/spi/spi.h>
 #include <linux/usb/musb.h>
+#include <sound/tlv320aic3x.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
@@ -487,7 +488,7 @@ static struct omap_mmc_platform_data mmc1_data = {
        .max_freq                       = 24000000,
        .dma_mask                       = 0xffffffff,
        .slots[0] = {
-               .wires                  = 4,
+               .caps                   = MMC_CAP_4_BIT_DATA,
                .set_power              = n8x0_mmc_set_power,
                .set_bus_mode           = n8x0_mmc_set_bus_mode,
                .get_cover_state        = n8x0_mmc_get_cover_state,
@@ -614,29 +615,35 @@ static int n8x0_menelaus_late_init(struct device *dev)
        return 0;
 }
 
-static struct i2c_board_info __initdata n8x0_i2c_board_info_1[] = {
+#else
+static int n8x0_menelaus_late_init(struct device *dev)
+{
+       return 0;
+}
+#endif
+
+static struct menelaus_platform_data n8x0_menelaus_platform_data __initdata = {
+       .late_init = n8x0_menelaus_late_init,
+};
+
+static struct i2c_board_info __initdata n8x0_i2c_board_info_1[] __initdata = {
        {
                I2C_BOARD_INFO("menelaus", 0x72),
                .irq = INT_24XX_SYS_NIRQ,
+               .platform_data = &n8x0_menelaus_platform_data,
        },
 };
 
-static struct menelaus_platform_data n8x0_menelaus_platform_data = {
-       .late_init = n8x0_menelaus_late_init,
+static struct aic3x_pdata n810_aic33_data __initdata = {
+       .gpio_reset = 118,
 };
 
-static void __init n8x0_menelaus_init(void)
-{
-       n8x0_i2c_board_info_1[0].platform_data = &n8x0_menelaus_platform_data;
-       omap_register_i2c_bus(1, 400, n8x0_i2c_board_info_1,
-                             ARRAY_SIZE(n8x0_i2c_board_info_1));
-}
-
-#else
-static inline void __init n8x0_menelaus_init(void)
-{
-}
-#endif
+static struct i2c_board_info n810_i2c_board_info_2[] __initdata = {
+       {
+               I2C_BOARD_INFO("tlv320aic3x", 0x18),
+               .platform_data = &n810_aic33_data,
+       },
+};
 
 static void __init n8x0_map_io(void)
 {
@@ -653,6 +660,11 @@ static void __init n8x0_init_irq(void)
 
 #ifdef CONFIG_OMAP_MUX
 static struct omap_board_mux board_mux[] __initdata = {
+       /* I2S codec port pins for McBSP block */
+       OMAP2420_MUX(EAC_AC_SCLK, OMAP_MUX_MODE1 | OMAP_PIN_INPUT),
+       OMAP2420_MUX(EAC_AC_FS, OMAP_MUX_MODE1 | OMAP_PIN_INPUT),
+       OMAP2420_MUX(EAC_AC_DIN, OMAP_MUX_MODE1 | OMAP_PIN_INPUT),
+       OMAP2420_MUX(EAC_AC_DOUT, OMAP_MUX_MODE1 | OMAP_PIN_OUTPUT),
        { .reg_offset = OMAP_MUX_TERMINATOR },
 };
 #else
@@ -665,9 +677,14 @@ static void __init n8x0_init_machine(void)
        /* FIXME: add n810 spi devices */
        spi_register_board_info(n800_spi_board_info,
                                ARRAY_SIZE(n800_spi_board_info));
+       omap_register_i2c_bus(1, 400, n8x0_i2c_board_info_1,
+                             ARRAY_SIZE(n8x0_i2c_board_info_1));
+       omap_register_i2c_bus(2, 400, NULL, 0);
+       if (machine_is_nokia_n810())
+               i2c_register_board_info(2, n810_i2c_board_info_2,
+                                       ARRAY_SIZE(n810_i2c_board_info_2));
 
        omap_serial_init();
-       n8x0_menelaus_init();
        n8x0_onenand_init();
        n8x0_mmc_init();
        n8x0_usb_init();
index e27f3bf45a3524735095819e0cc240f3e2cfb5b7..7e7048878649265f48ebbd89125ef7503986db01 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/nand.h>
+#include <linux/mmc/host.h>
 
 #include <linux/regulator/machine.h>
 #include <linux/i2c/twl.h>
@@ -253,7 +254,7 @@ static void __init beagle_display_init(void)
 static struct omap2_hsmmc_info mmc[] = {
        {
                .mmc            = 1,
-               .wires          = 8,
+               .caps           = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
                .gpio_wp        = 29,
        },
        {}      /* Terminator */
index f76d9c0a47a1e83c8220977d75908c181899d53c..523ba551ee7b88645b08753c566f0a321734f946 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/smsc911x.h>
 
 #include <linux/regulator/machine.h>
+#include <linux/mmc/host.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
@@ -370,7 +371,7 @@ static struct regulator_init_data omap3evm_vsim = {
 static struct omap2_hsmmc_info mmc[] = {
        {
                .mmc            = 1,
-               .wires          = 4,
+               .caps           = MMC_CAP_4_BIT_DATA,
                .gpio_cd        = -EINVAL,
                .gpio_wp        = 63,
        },
index dd3af2be13be2a79e14a52360088c8cbb9db575b..2d2e6fc127ace9692cd5cbfbc32250749e5f2bc3 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/input.h>
 #include <linux/input/matrix_keypad.h>
 #include <linux/gpio_keys.h>
+#include <linux/mmc/host.h>
 #include <linux/mmc/card.h>
 
 #include <asm/mach-types.h>
@@ -276,14 +277,14 @@ static void pandora_wl1251_init_card(struct mmc_card *card)
 static struct omap2_hsmmc_info omap3pandora_mmc[] = {
        {
                .mmc            = 1,
-               .wires          = 4,
+               .caps           = MMC_CAP_4_BIT_DATA,
                .gpio_cd        = -EINVAL,
                .gpio_wp        = 126,
                .ext_clock      = 0,
        },
        {
                .mmc            = 2,
-               .wires          = 4,
+               .caps           = MMC_CAP_4_BIT_DATA,
                .gpio_cd        = -EINVAL,
                .gpio_wp        = 127,
                .ext_clock      = 1,
@@ -291,7 +292,7 @@ static struct omap2_hsmmc_info omap3pandora_mmc[] = {
        },
        {
                .mmc            = 3,
-               .wires          = 4,
+               .caps           = MMC_CAP_4_BIT_DATA,
                .gpio_cd        = -EINVAL,
                .gpio_wp        = -EINVAL,
                .init_card      = pandora_wl1251_init_card,
index bcd01d278c656f0b09a742a31370e5e278b1fb9e..c1b881d3d8ae4413f29f51279030e5a478def594 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <linux/regulator/machine.h>
 #include <linux/i2c/twl.h>
+#include <linux/mmc/host.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
@@ -275,7 +276,7 @@ static struct regulator_init_data omap3stalker_vsim = {
 static struct omap2_hsmmc_info mmc[] = {
        {
         .mmc           = 1,
-        .wires         = 4,
+        .caps          = MMC_CAP_4_BIT_DATA,
         .gpio_cd       = -EINVAL,
         .gpio_wp       = 23,
         },
index 663c62d271e8bfa0fcdec35bd9f03333ac0af87c..9ab18fdd974cfaf724750b212e61d50cac68b82c 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/nand.h>
+#include <linux/mmc/host.h>
 
 #include <plat/mcspi.h>
 #include <linux/spi/spi.h>
@@ -108,7 +109,7 @@ static struct omap_nand_platform_data omap3touchbook_nand_data = {
 static struct omap2_hsmmc_info mmc[] = {
        {
                .mmc            = 1,
-               .wires          = 8,
+               .caps           = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
                .gpio_wp        = 29,
        },
        {}      /* Terminator */
index 22a8fd30f9ffddec29afa1727ef7987c721260a0..aa8296e7e9d45b078b0191d39565a79859cdde27 100644 (file)
@@ -87,7 +87,7 @@ static struct omap_musb_board_data musb_board_data = {
 static struct omap2_hsmmc_info mmc[] = {
        {
                .mmc            = 1,
-               .wires          = 8,
+               .caps           = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
                .gpio_wp        = -EINVAL,
        },
        {}      /* Terminator */
@@ -305,8 +305,6 @@ static int __init omap4_panda_i2c_init(void)
 }
 static void __init omap4_panda_init(void)
 {
-       int status;
-
        omap4_panda_i2c_init();
        platform_add_devices(panda_devices, ARRAY_SIZE(panda_devices));
        omap_serial_init();
index 4c484361835063d17de2df8fe27c7fb28be7984f..93441e5b36ef5c8113dde8bbb9f53acf6bc7b3b9 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
+#include <linux/mmc/host.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -303,13 +304,13 @@ static void __init overo_flash_init(void)
 static struct omap2_hsmmc_info mmc[] = {
        {
                .mmc            = 1,
-               .wires          = 4,
+               .caps           = MMC_CAP_4_BIT_DATA,
                .gpio_cd        = -EINVAL,
                .gpio_wp        = -EINVAL,
        },
        {
                .mmc            = 2,
-               .wires          = 4,
+               .caps           = MMC_CAP_4_BIT_DATA,
                .gpio_cd        = -EINVAL,
                .gpio_wp        = -EINVAL,
                .transceiver    = true,
index 9a5eb87425fcf91dc3164acf3b1386e38e655be7..a3dbaa7b86322417a2ef52ed9310e0ce047cb526 100644 (file)
@@ -302,7 +302,7 @@ static struct omap2_hsmmc_info mmc[] __initdata = {
        {
                .name           = "external",
                .mmc            = 1,
-               .wires          = 4,
+               .caps           = MMC_CAP_4_BIT_DATA,
                .cover_only     = true,
                .gpio_cd        = 160,
                .gpio_wp        = -EINVAL,
@@ -311,7 +311,8 @@ static struct omap2_hsmmc_info mmc[] __initdata = {
        {
                .name           = "internal",
                .mmc            = 2,
-               .wires          = 8, /* See also rx51_mmc2_remux */
+               .caps           = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
+                                               /* See also rx51_mmc2_remux */
                .gpio_cd        = -EINVAL,
                .gpio_wp        = -EINVAL,
                .nonremovable   = true,
index 6b3984964cc59696a98b21872f5f768eccac71d6..e5eac46bbac9d227b9367babea1442fccea090ea 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/gpio.h>
 #include <linux/i2c/twl.h>
 #include <linux/regulator/machine.h>
+#include <linux/mmc/host.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -155,14 +156,14 @@ static struct omap2_hsmmc_info mmc[] __initdata = {
        {
                .name           = "external",
                .mmc            = 1,
-               .wires          = 4,
+               .caps           = MMC_CAP_4_BIT_DATA,
                .gpio_wp        = -EINVAL,
                .power_saving   = true,
        },
        {
                .name           = "internal",
                .mmc            = 2,
-               .wires          = 8,
+               .caps           = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
                .gpio_cd        = -EINVAL,
                .gpio_wp        = -EINVAL,
                .nonremovable   = true,
index 37d65d62ed8f067a317aac86ea9062d0cd617774..5f2066a6ba7460343d9ed535167e6aec92acdaaf 100644 (file)
@@ -1838,7 +1838,7 @@ static struct omap_clk omap2420_clks[] = {
        CLK(NULL,       "des_ick",      &des_ick,       CK_242X),
        CLK("omap-sham",        "ick",  &sha_ick,       CK_242X),
        CLK("omap_rng", "ick",          &rng_ick,       CK_242X),
-       CLK(NULL,       "aes_ick",      &aes_ick,       CK_242X),
+       CLK("omap-aes", "ick",  &aes_ick,       CK_242X),
        CLK(NULL,       "pka_ick",      &pka_ick,       CK_242X),
        CLK(NULL,       "usb_fck",      &usb_fck,       CK_242X),
        CLK("musb_hdrc",        "fck",  &osc_ck,        CK_242X),
index b33118fb6a87fd69a6f4484f6f0f697d006a32ac..701a1716019ebbda3a973cbb1317a008e758ef58 100644 (file)
@@ -1926,7 +1926,7 @@ static struct omap_clk omap2430_clks[] = {
        CLK(NULL,       "des_ick",      &des_ick,       CK_243X),
        CLK("omap-sham",        "ick",  &sha_ick,       CK_243X),
        CLK("omap_rng", "ick",          &rng_ick,       CK_243X),
-       CLK(NULL,       "aes_ick",      &aes_ick,       CK_243X),
+       CLK("omap-aes", "ick",  &aes_ick,       CK_243X),
        CLK(NULL,       "pka_ick",      &pka_ick,       CK_243X),
        CLK(NULL,       "usb_fck",      &usb_fck,       CK_243X),
        CLK("musb_hdrc",        "ick",  &usbhs_ick,     CK_243X),
index dfdce2d8277992b3e6ccb9fcfbc247e3b8df3708..c73906d1745833cb0d44511404439d808a9ab556 100644 (file)
@@ -3288,7 +3288,7 @@ static struct omap_clk omap3xxx_clks[] = {
        CLK(NULL,       "usbtll_ick",   &usbtll_ick,    CK_3430ES2 | CK_AM35XX),
        CLK("mmci-omap-hs.2",   "ick",  &mmchs3_ick,    CK_3430ES2 | CK_AM35XX),
        CLK(NULL,       "icr_ick",      &icr_ick,       CK_343X),
-       CLK(NULL,       "aes2_ick",     &aes2_ick,      CK_343X),
+       CLK("omap-aes", "ick",  &aes2_ick,      CK_343X),
        CLK("omap-sham",        "ick",  &sha12_ick,     CK_343X),
        CLK(NULL,       "des2_ick",     &des2_ick,      CK_343X),
        CLK("mmci-omap-hs.1",   "ick",  &mmchs2_ick,    CK_3XXX),
index 5d80cb897489505839a847c460cc9ade5e1bb05b..6fb61b1a0d46105f7d18fb8434d3d91caaa4be41 100644 (file)
@@ -258,97 +258,6 @@ 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 */
 
 /**
@@ -379,12 +288,17 @@ void clkdm_init(struct clockdomain **clkdms,
                        _autodep_lookup(autodep);
 
        /*
-        * Ensure that the *dep_usecount registers reflect the current
-        * state of the PRCM.
+        * Put all clockdomains into software-supervised mode; PM code
+        * should later enable hardware-supervised mode as appropriate
         */
        list_for_each_entry(clkdm, &clkdm_list, node) {
-               _init_wkdep_usecount(clkdm);
-               _init_sleepdep_usecount(clkdm);
+               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);
        }
 }
 
@@ -592,6 +506,9 @@ 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);
@@ -752,6 +669,9 @@ 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);
index b101091e95d638505e8c4874bb2b0fbef494e99e..f8a660a1a4a6f5303a5c5bc2e335add1d833ff1f 100644 (file)
@@ -43,7 +43,6 @@
  *                 using separate functional clock
  *   0x3 disabled: Module is disabled and cannot be accessed
  *
- * TODO: Need to handle module accessible in idle state
  */
 int omap4_cm_wait_module_ready(void __iomem *clkctrl_reg)
 {
@@ -52,9 +51,11 @@ int omap4_cm_wait_module_ready(void __iomem *clkctrl_reg)
        if (!clkctrl_reg)
                return 0;
 
-       omap_test_timeout(((__raw_readl(clkctrl_reg) &
-                           OMAP4430_IDLEST_MASK) == 0),
-                         MAX_MODULE_READY_TIME, i);
+       omap_test_timeout((
+               ((__raw_readl(clkctrl_reg) & OMAP4430_IDLEST_MASK) == 0) ||
+                (((__raw_readl(clkctrl_reg) & OMAP4430_IDLEST_MASK) >>
+                 OMAP4430_IDLEST_SHIFT) == 0x2)),
+               MAX_MODULE_READY_TIME, i);
 
        return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY;
 }
index 3d3d035db9aff62ce522e0080e570cfdbf8e70cc..8ea012ef0b5a7f5b34ca9c6467ac1c942e71c3cb 100644 (file)
@@ -60,7 +60,8 @@ 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;
+struct powerdomain *mpu_pd, *core_pd, *per_pd;
+struct powerdomain *cam_pd;
 
 /*
  * The latencies/thresholds for various C states have
@@ -233,14 +234,62 @@ 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;
-       return omap3_enter_idle(dev, 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;
 }
 
 DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev);
@@ -328,7 +377,8 @@ 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;
+       omap3_power_states[OMAP3_STATE_C2].flags = CPUIDLE_FLAG_TIME_VALID |
+                               CPUIDLE_FLAG_CHECK_BM;
 
        /* C3 . MPU CSWR + Core inactive */
        omap3_power_states[OMAP3_STATE_C3].valid =
@@ -426,6 +476,8 @@ 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);
index 2dbb265bedd4e914c6ceac472dbe9a0b8bddbf0b..9e5d51bee94a2f750680ec6df3351c7e5ad5dadc 100644 (file)
@@ -498,6 +498,76 @@ static void omap_init_sham(void)
 static inline void omap_init_sham(void) { }
 #endif
 
+#if defined(CONFIG_CRYPTO_DEV_OMAP_AES) || defined(CONFIG_CRYPTO_DEV_OMAP_AES_MODULE)
+
+#ifdef CONFIG_ARCH_OMAP2
+static struct resource omap2_aes_resources[] = {
+       {
+               .start  = OMAP24XX_SEC_AES_BASE,
+               .end    = OMAP24XX_SEC_AES_BASE + 0x4C,
+               .flags  = IORESOURCE_MEM,
+       },
+       {
+               .start  = OMAP24XX_DMA_AES_TX,
+               .flags  = IORESOURCE_DMA,
+       },
+       {
+               .start  = OMAP24XX_DMA_AES_RX,
+               .flags  = IORESOURCE_DMA,
+       }
+};
+static int omap2_aes_resources_sz = ARRAY_SIZE(omap2_aes_resources);
+#else
+#define omap2_aes_resources            NULL
+#define omap2_aes_resources_sz         0
+#endif
+
+#ifdef CONFIG_ARCH_OMAP3
+static struct resource omap3_aes_resources[] = {
+       {
+               .start  = OMAP34XX_SEC_AES_BASE,
+               .end    = OMAP34XX_SEC_AES_BASE + 0x4C,
+               .flags  = IORESOURCE_MEM,
+       },
+       {
+               .start  = OMAP34XX_DMA_AES2_TX,
+               .flags  = IORESOURCE_DMA,
+       },
+       {
+               .start  = OMAP34XX_DMA_AES2_RX,
+               .flags  = IORESOURCE_DMA,
+       }
+};
+static int omap3_aes_resources_sz = ARRAY_SIZE(omap3_aes_resources);
+#else
+#define omap3_aes_resources            NULL
+#define omap3_aes_resources_sz         0
+#endif
+
+static struct platform_device aes_device = {
+       .name           = "omap-aes",
+       .id             = -1,
+};
+
+static void omap_init_aes(void)
+{
+       if (cpu_is_omap24xx()) {
+               aes_device.resource = omap2_aes_resources;
+               aes_device.num_resources = omap2_aes_resources_sz;
+       } else if (cpu_is_omap34xx()) {
+               aes_device.resource = omap3_aes_resources;
+               aes_device.num_resources = omap3_aes_resources_sz;
+       } else {
+               pr_err("%s: platform not supported\n", __func__);
+               return;
+       }
+       platform_device_register(&aes_device);
+}
+
+#else
+static inline void omap_init_aes(void) { }
+#endif
+
 /*-------------------------------------------------------------------------*/
 
 #if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
@@ -624,7 +694,7 @@ static inline void omap2_mmc_mux(struct omap_mmc_platform_data *mmc_controller,
                omap_mux_init_signal("sdmmc_dat0", 0);
                omap_mux_init_signal("sdmmc_dat_dir0", 0);
                omap_mux_init_signal("sdmmc_cmd_dir", 0);
-               if (mmc_controller->slots[0].wires == 4) {
+               if (mmc_controller->slots[0].caps & MMC_CAP_4_BIT_DATA) {
                        omap_mux_init_signal("sdmmc_dat1", 0);
                        omap_mux_init_signal("sdmmc_dat2", 0);
                        omap_mux_init_signal("sdmmc_dat3", 0);
@@ -652,8 +722,8 @@ static inline void omap2_mmc_mux(struct omap_mmc_platform_data *mmc_controller,
                                OMAP_PIN_INPUT_PULLUP);
                        omap_mux_init_signal("sdmmc1_dat0",
                                OMAP_PIN_INPUT_PULLUP);
-                       if (mmc_controller->slots[0].wires == 4 ||
-                               mmc_controller->slots[0].wires == 8) {
+                       if (mmc_controller->slots[0].caps &
+                               (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA)) {
                                omap_mux_init_signal("sdmmc1_dat1",
                                        OMAP_PIN_INPUT_PULLUP);
                                omap_mux_init_signal("sdmmc1_dat2",
@@ -661,7 +731,8 @@ static inline void omap2_mmc_mux(struct omap_mmc_platform_data *mmc_controller,
                                omap_mux_init_signal("sdmmc1_dat3",
                                        OMAP_PIN_INPUT_PULLUP);
                        }
-                       if (mmc_controller->slots[0].wires == 8) {
+                       if (mmc_controller->slots[0].caps &
+                                               MMC_CAP_8_BIT_DATA) {
                                omap_mux_init_signal("sdmmc1_dat4",
                                        OMAP_PIN_INPUT_PULLUP);
                                omap_mux_init_signal("sdmmc1_dat5",
@@ -685,8 +756,8 @@ static inline void omap2_mmc_mux(struct omap_mmc_platform_data *mmc_controller,
                         * For 8 wire configurations, Lines DAT4, 5, 6 and 7 need to be muxed
                         * in the board-*.c files
                         */
-                       if (mmc_controller->slots[0].wires == 4 ||
-                               mmc_controller->slots[0].wires == 8) {
+                       if (mmc_controller->slots[0].caps &
+                               (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA)) {
                                omap_mux_init_signal("sdmmc2_dat1",
                                        OMAP_PIN_INPUT_PULLUP);
                                omap_mux_init_signal("sdmmc2_dat2",
@@ -694,7 +765,8 @@ static inline void omap2_mmc_mux(struct omap_mmc_platform_data *mmc_controller,
                                omap_mux_init_signal("sdmmc2_dat3",
                                        OMAP_PIN_INPUT_PULLUP);
                        }
-                       if (mmc_controller->slots[0].wires == 8) {
+                       if (mmc_controller->slots[0].caps &
+                                                       MMC_CAP_8_BIT_DATA) {
                                omap_mux_init_signal("sdmmc2_dat4.sdmmc2_dat4",
                                        OMAP_PIN_INPUT_PULLUP);
                                omap_mux_init_signal("sdmmc2_dat5.sdmmc2_dat5",
@@ -854,6 +926,7 @@ static int __init omap2_init_devices(void)
        omap_hdq_init();
        omap_init_sti();
        omap_init_sham();
+       omap_init_aes();
        omap_init_vout();
 
        return 0;
index c8f647b6205e4707f432de5b0ec4ef4d014499da..87ce6ffccefca113792d3e210d2baa7b6b79b903 100644 (file)
@@ -258,7 +258,7 @@ void __init omap2_hsmmc_init(struct omap2_hsmmc_info *controllers)
                                "mmc%islot%i", c->mmc, 1);
                mmc->slots[0].name = hc->name;
                mmc->nr_slots = 1;
-               mmc->slots[0].wires = c->wires;
+               mmc->slots[0].caps = c->caps;
                mmc->slots[0].internal_clock = !c->ext_clock;
                mmc->dma_mask = 0xffffffff;
 
@@ -316,16 +316,20 @@ void __init omap2_hsmmc_init(struct omap2_hsmmc_info *controllers)
                        }
 
                        /* Omap3630 HSMMC1 supports only 4-bit */
-                       if (cpu_is_omap3630() && c->wires > 4) {
-                               c->wires = 4;
-                               mmc->slots[0].wires = c->wires;
+                       if (cpu_is_omap3630() &&
+                                       (c->caps & MMC_CAP_8_BIT_DATA)) {
+                               c->caps &= ~MMC_CAP_8_BIT_DATA;
+                               c->caps |= MMC_CAP_4_BIT_DATA;
+                               mmc->slots[0].caps = c->caps;
                        }
                        break;
                case 2:
                        if (c->ext_clock)
                                c->transceiver = 1;
-                       if (c->transceiver && c->wires > 4)
-                               c->wires = 4;
+                       if (c->transceiver && (c->caps & MMC_CAP_8_BIT_DATA)) {
+                               c->caps &= ~MMC_CAP_8_BIT_DATA;
+                               c->caps |= MMC_CAP_4_BIT_DATA;
+                       }
                        /* FALLTHROUGH */
                case 3:
                        if (mmc->slots[0].features & HSMMC_HAS_PBIAS) {
index 1fe6f0187177bba349be1573af8f906553e40989..281e97287adf988493efd1ca94b19ab8588b7aaf 100644 (file)
@@ -10,7 +10,8 @@ struct mmc_card;
 
 struct omap2_hsmmc_info {
        u8      mmc;            /* controller 1/2/3 */
-       u8      wires;          /* 1/4/8 wires */
+       u32     caps;           /* 4/8 wires and any additional host
+                                * capabilities OR'd (ref. linux/mmc/host.h) */
        bool    transceiver;    /* MMC-2 option */
        bool    ext_clock;      /* use external pin for input clock */
        bool    cover_only;     /* No card detect - just cover switch */
index 9a879f9595098dd5e3fcb303b8d205af744d3a28..91d7df402b350e45845c1654749fd780147dc505 100644 (file)
@@ -298,7 +298,6 @@ static void __init omap4_check_revision(void)
        u32 idcode;
        u16 hawkeye;
        u8 rev;
-       char *rev_name = "ES1.0";
 
        /*
         * The IC rev detection is done with hawkeye and rev.
@@ -309,14 +308,39 @@ static void __init omap4_check_revision(void)
        hawkeye = (idcode >> 12) & 0xffff;
        rev = (idcode >> 28) & 0xff;
 
-       if ((hawkeye == 0xb852) && (rev == 0x0)) {
-               omap_revision = OMAP4430_REV_ES1_0;
-               omap_chip.oc |= CHIP_IS_OMAP4430ES1;
-               pr_info("OMAP%04x %s\n", omap_rev() >> 16, rev_name);
-               return;
+       /*
+        * Few initial ES2.0 samples IDCODE is same as ES1.0
+        * Use ARM register to detect the correct ES version
+        */
+       if (!rev) {
+               idcode = read_cpuid(CPUID_ID);
+               rev = (idcode & 0xf) - 1;
+       }
+
+       switch (hawkeye) {
+       case 0xb852:
+               switch (rev) {
+               case 0:
+                       omap_revision = OMAP4430_REV_ES1_0;
+                       omap_chip.oc |= CHIP_IS_OMAP4430ES1;
+                       break;
+               case 1:
+                       omap_revision = OMAP4430_REV_ES2_0;
+                       omap_chip.oc |= CHIP_IS_OMAP4430ES2;
+                       break;
+               default:
+                       omap_revision = OMAP4430_REV_ES2_0;
+                       omap_chip.oc |= CHIP_IS_OMAP4430ES2;
+       }
+       break;
+       default:
+               /* Unknown default to latest silicon rev as default*/
+               omap_revision = OMAP4430_REV_ES2_0;
+               omap_chip.oc |= CHIP_IS_OMAP4430ES2;
        }
 
-       pr_err("Unknown OMAP4 CPU id\n");
+       pr_info("OMAP%04x ES%d.0\n",
+                       omap_rev() >> 16, ((omap_rev() >> 12) & 0xf) + 1);
 }
 
 #define OMAP3_SHOW_FEATURE(feat)               \
index b9ea70bce5635d431ef2651058bd72b0619420df..490d87082fad6162b5098921b772b489eaeaece3 100644 (file)
@@ -323,6 +323,9 @@ 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);
 
@@ -342,9 +345,7 @@ void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0,
 #ifndef CONFIG_PM_RUNTIME
        skip_setup_idle = 1;
 #endif
-       if (cpu_is_omap24xx() || cpu_is_omap34xx())   /* FIXME: OMAP4 */
-               omap_hwmod_late_init(skip_setup_idle);
-
+       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();
index 467aae245781c91c6ac4535a5d7d7295e5251ec6..88b8790e4fec6a0509671bd69c22fd88c7c8ca22 100644 (file)
 #include <plat/cpu.h>
 #include <plat/mcbsp.h>
 
-#include "mux.h"
-
-static void omap2_mcbsp2_mux_setup(void)
-{
-       omap_mux_init_signal("eac_ac_sclk.mcbsp2_clkx", OMAP_PULL_ENA);
-       omap_mux_init_signal("eac_ac_fs.mcbsp2_fsx", OMAP_PULL_ENA);
-       omap_mux_init_signal("eac_ac_din.mcbsp2_dr", OMAP_PULL_ENA);
-       omap_mux_init_signal("eac_ac_dout.mcbsp2_dx", OMAP_PULL_ENA);
-       omap_mux_init_gpio(117, OMAP_PULL_ENA);
-       /*
-        * TODO: Need to add MUX settings for OMAP 2430 SDP
-        */
-}
-
-static void omap2_mcbsp_request(unsigned int id)
-{
-       if (cpu_is_omap2420() && (id == OMAP_MCBSP2))
-               omap2_mcbsp2_mux_setup();
-}
-
-static struct omap_mcbsp_ops omap2_mcbsp_ops = {
-       .request        = omap2_mcbsp_request,
-};
 
 #ifdef CONFIG_ARCH_OMAP2420
 static struct omap_mcbsp_platform_data omap2420_mcbsp_pdata[] = {
@@ -55,7 +32,6 @@ static struct omap_mcbsp_platform_data omap2420_mcbsp_pdata[] = {
                .dma_tx_sync    = OMAP24XX_DMA_MCBSP1_TX,
                .rx_irq         = INT_24XX_MCBSP1_IRQ_RX,
                .tx_irq         = INT_24XX_MCBSP1_IRQ_TX,
-               .ops            = &omap2_mcbsp_ops,
        },
        {
                .phys_base      = OMAP24XX_MCBSP2_BASE,
@@ -63,7 +39,6 @@ static struct omap_mcbsp_platform_data omap2420_mcbsp_pdata[] = {
                .dma_tx_sync    = OMAP24XX_DMA_MCBSP2_TX,
                .rx_irq         = INT_24XX_MCBSP2_IRQ_RX,
                .tx_irq         = INT_24XX_MCBSP2_IRQ_TX,
-               .ops            = &omap2_mcbsp_ops,
        },
 };
 #define OMAP2420_MCBSP_PDATA_SZ                ARRAY_SIZE(omap2420_mcbsp_pdata)
@@ -82,7 +57,6 @@ static struct omap_mcbsp_platform_data omap2430_mcbsp_pdata[] = {
                .dma_tx_sync    = OMAP24XX_DMA_MCBSP1_TX,
                .rx_irq         = INT_24XX_MCBSP1_IRQ_RX,
                .tx_irq         = INT_24XX_MCBSP1_IRQ_TX,
-               .ops            = &omap2_mcbsp_ops,
        },
        {
                .phys_base      = OMAP24XX_MCBSP2_BASE,
@@ -90,7 +64,6 @@ static struct omap_mcbsp_platform_data omap2430_mcbsp_pdata[] = {
                .dma_tx_sync    = OMAP24XX_DMA_MCBSP2_TX,
                .rx_irq         = INT_24XX_MCBSP2_IRQ_RX,
                .tx_irq         = INT_24XX_MCBSP2_IRQ_TX,
-               .ops            = &omap2_mcbsp_ops,
        },
        {
                .phys_base      = OMAP2430_MCBSP3_BASE,
@@ -98,7 +71,6 @@ static struct omap_mcbsp_platform_data omap2430_mcbsp_pdata[] = {
                .dma_tx_sync    = OMAP24XX_DMA_MCBSP3_TX,
                .rx_irq         = INT_24XX_MCBSP3_IRQ_RX,
                .tx_irq         = INT_24XX_MCBSP3_IRQ_TX,
-               .ops            = &omap2_mcbsp_ops,
        },
        {
                .phys_base      = OMAP2430_MCBSP4_BASE,
@@ -106,7 +78,6 @@ static struct omap_mcbsp_platform_data omap2430_mcbsp_pdata[] = {
                .dma_tx_sync    = OMAP24XX_DMA_MCBSP4_TX,
                .rx_irq         = INT_24XX_MCBSP4_IRQ_RX,
                .tx_irq         = INT_24XX_MCBSP4_IRQ_TX,
-               .ops            = &omap2_mcbsp_ops,
        },
        {
                .phys_base      = OMAP2430_MCBSP5_BASE,
@@ -114,7 +85,6 @@ static struct omap_mcbsp_platform_data omap2430_mcbsp_pdata[] = {
                .dma_tx_sync    = OMAP24XX_DMA_MCBSP5_TX,
                .rx_irq         = INT_24XX_MCBSP5_IRQ_RX,
                .tx_irq         = INT_24XX_MCBSP5_IRQ_TX,
-               .ops            = &omap2_mcbsp_ops,
        },
 };
 #define OMAP2430_MCBSP_PDATA_SZ                ARRAY_SIZE(omap2430_mcbsp_pdata)
@@ -133,7 +103,6 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
                .dma_tx_sync    = OMAP24XX_DMA_MCBSP1_TX,
                .rx_irq         = INT_24XX_MCBSP1_IRQ_RX,
                .tx_irq         = INT_24XX_MCBSP1_IRQ_TX,
-               .ops            = &omap2_mcbsp_ops,
                .buffer_size    = 0x80, /* The FIFO has 128 locations */
        },
        {
@@ -143,7 +112,6 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
                .dma_tx_sync    = OMAP24XX_DMA_MCBSP2_TX,
                .rx_irq         = INT_24XX_MCBSP2_IRQ_RX,
                .tx_irq         = INT_24XX_MCBSP2_IRQ_TX,
-               .ops            = &omap2_mcbsp_ops,
                .buffer_size    = 0x500, /* The FIFO has 1024 + 256 locations */
        },
        {
@@ -153,7 +121,6 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
                .dma_tx_sync    = OMAP24XX_DMA_MCBSP3_TX,
                .rx_irq         = INT_24XX_MCBSP3_IRQ_RX,
                .tx_irq         = INT_24XX_MCBSP3_IRQ_TX,
-               .ops            = &omap2_mcbsp_ops,
                .buffer_size    = 0x80, /* The FIFO has 128 locations */
        },
        {
@@ -162,7 +129,6 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
                .dma_tx_sync    = OMAP24XX_DMA_MCBSP4_TX,
                .rx_irq         = INT_24XX_MCBSP4_IRQ_RX,
                .tx_irq         = INT_24XX_MCBSP4_IRQ_TX,
-               .ops            = &omap2_mcbsp_ops,
                .buffer_size    = 0x80, /* The FIFO has 128 locations */
        },
        {
@@ -171,7 +137,6 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
                .dma_tx_sync    = OMAP24XX_DMA_MCBSP5_TX,
                .rx_irq         = INT_24XX_MCBSP5_IRQ_RX,
                .tx_irq         = INT_24XX_MCBSP5_IRQ_TX,
-               .ops            = &omap2_mcbsp_ops,
                .buffer_size    = 0x80, /* The FIFO has 128 locations */
        },
 };
@@ -189,28 +154,24 @@ static struct omap_mcbsp_platform_data omap44xx_mcbsp_pdata[] = {
                .dma_rx_sync    = OMAP44XX_DMA_MCBSP1_RX,
                .dma_tx_sync    = OMAP44XX_DMA_MCBSP1_TX,
                .tx_irq         = OMAP44XX_IRQ_MCBSP1,
-               .ops            = &omap2_mcbsp_ops,
        },
        {
                .phys_base      = OMAP44XX_MCBSP2_BASE,
                .dma_rx_sync    = OMAP44XX_DMA_MCBSP2_RX,
                .dma_tx_sync    = OMAP44XX_DMA_MCBSP2_TX,
                .tx_irq         = OMAP44XX_IRQ_MCBSP2,
-               .ops            = &omap2_mcbsp_ops,
        },
        {
                .phys_base      = OMAP44XX_MCBSP3_BASE,
                .dma_rx_sync    = OMAP44XX_DMA_MCBSP3_RX,
                .dma_tx_sync    = OMAP44XX_DMA_MCBSP3_TX,
                .tx_irq         = OMAP44XX_IRQ_MCBSP3,
-               .ops            = &omap2_mcbsp_ops,
        },
        {
                .phys_base      = OMAP44XX_MCBSP4_BASE,
                .dma_rx_sync    = OMAP44XX_DMA_MCBSP4_RX,
                .dma_tx_sync    = OMAP44XX_DMA_MCBSP4_TX,
                .tx_irq         = OMAP44XX_IRQ_MCBSP4,
-               .ops            = &omap2_mcbsp_ops,
        },
 };
 #define OMAP44XX_MCBSP_PDATA_SZ                ARRAY_SIZE(omap44xx_mcbsp_pdata)
index ab403b2ed26befb6058309e26e3b75688eb46905..6c2f8f0c0edb2bb80aa4dc7b64b453290a72e120 100644 (file)
@@ -87,7 +87,7 @@ static char *omap_mux_options;
 int __init omap_mux_init_gpio(int gpio, int val)
 {
        struct omap_mux_entry *e;
-       struct omap_mux *gpio_mux;
+       struct omap_mux *gpio_mux = NULL;
        u16 old_mode;
        u16 mux_mode;
        int found = 0;
index 13dc9794dcc2ea68fe9115cff7be9cd8c074a484..923f9f5f91ce96fc2588f41503b53795e6cdea21 100644 (file)
@@ -61,10 +61,14 @@ static int __init omap_l2_cache_init(void)
        omap_smc1(0x102, 0x1);
 
        /*
-        * 32KB way size, 16-way associativity,
-        * parity disabled
+        * 16-way associativity, parity disabled
+        * Way size - 32KB (es1.0)
+        * Way size - 64KB (es2.0 +)
         */
-       l2x0_init(l2cache_base, 0x0e050000, 0xc0000fff);
+       if (omap_rev() == OMAP4430_REV_ES1_0)
+               l2x0_init(l2cache_base, 0x0e050000, 0xc0000fff);
+       else
+               l2x0_init(l2cache_base, 0x0e070000, 0xc0000fff);
 
        return 0;
 }
index cb911d7d1a3c1535ba88eda74577ea6ef2e1ecd0..955861acc0c4ed7757580fd75c351afeed6ba569 100644 (file)
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  *
- * This code manages "OMAP modules" (on-chip devices) and their
- * integration with Linux device driver and bus code.
- *
- * References:
+ * 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.
  * - 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)
 #include <plat/powerdomain.h>
 #include <plat/clock.h>
 #include <plat/omap_hwmod.h>
+#include <plat/prcm.h>
 
 #include "cm.h"
+#include "prm.h"
 
-/* Maximum microseconds to wait for OMAP module to reset */
-#define MAX_MODULE_RESET_WAIT          10000
+/* Maximum microseconds to wait for OMAP module to softreset */
+#define MAX_MODULE_SOFTRESET_WAIT      10000
 
 /* Name of the OMAP hwmod for the MPU */
 #define MPU_INITIATOR_NAME             "mpu"
@@ -544,6 +638,36 @@ 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 *
@@ -622,7 +746,7 @@ static void __iomem *_find_mpu_rt_base(struct omap_hwmod *oh, u8 index)
 }
 
 /**
- * _sysc_enable - try to bring a module out of idle via OCP_SYSCONFIG
+ * _enable_sysc - 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
@@ -630,7 +754,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 _sysc_enable(struct omap_hwmod *oh)
+static void _enable_sysc(struct omap_hwmod *oh)
 {
        u8 idlemode, sf;
        u32 v;
@@ -653,14 +777,6 @@ static void _sysc_enable(struct omap_hwmod *oh)
                _set_master_standbymode(oh, idlemode, &v);
        }
 
-       if (sf & SYSC_HAS_AUTOIDLE) {
-               idlemode = (oh->flags & HWMOD_NO_OCP_AUTOIDLE) ?
-                       0 : 1;
-               _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
@@ -671,10 +787,25 @@ static void _sysc_enable(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);
+
+       /*
+        * Set the autoidle bit only after setting the smartidle bit
+        * Setting this will not have any impact on the other modules.
+        */
+       if (sf & SYSC_HAS_AUTOIDLE) {
+               idlemode = (oh->flags & HWMOD_NO_OCP_AUTOIDLE) ?
+                       0 : 1;
+               _set_module_autoidle(oh, idlemode, &v);
+               _write_sysconfig(v, oh);
+       }
 }
 
 /**
- * _sysc_idle - try to put a module into idle via OCP_SYSCONFIG
+ * _idle_sysc - 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
@@ -682,7 +813,7 @@ static void _sysc_enable(struct omap_hwmod *oh)
  * as SWSUP_MSUSPEND, force the module into master standby; otherwise,
  * configure it for smart-standby.  No return value.
  */
-static void _sysc_idle(struct omap_hwmod *oh)
+static void _idle_sysc(struct omap_hwmod *oh)
 {
        u8 idlemode, sf;
        u32 v;
@@ -709,13 +840,13 @@ static void _sysc_idle(struct omap_hwmod *oh)
 }
 
 /**
- * _sysc_shutdown - force a module into idle via OCP_SYSCONFIG
+ * _shutdown_sysc - 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 _sysc_shutdown(struct omap_hwmod *oh)
+static void _shutdown_sysc(struct omap_hwmod *oh)
 {
        u32 v;
        u8 sf;
@@ -767,10 +898,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.  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.
+ * 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.
  */
 static int _init_clocks(struct omap_hwmod *oh, void *data)
 {
@@ -833,57 +964,203 @@ 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.  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.
+ * 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.
  */
 static int _reset(struct omap_hwmod *oh)
 {
-       u32 r, v;
+       u32 v;
        int c = 0;
+       int ret = 0;
 
        if (!oh->class->sysc ||
-           !(oh->class->sysc->sysc_flags & SYSC_HAS_SOFTRESET) ||
-           (oh->class->sysc->sysc_flags & SYSS_MISSING))
+           !(oh->class->sysc->sysc_flags & SYSC_HAS_SOFTRESET))
                return -EINVAL;
 
        /* clocks must be on for this operation */
        if (oh->_state != _HWMOD_STATE_ENABLED) {
-               WARN(1, "omap_hwmod: %s: reset can only be entered from "
-                    "enabled state\n", oh->name);
+               pr_warning("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;
-       r = _set_softreset(oh, &v);
-       if (r)
-               return r;
+       ret = _set_softreset(oh, &v);
+       if (ret)
+               goto dis_opt_clks;
        _write_sysconfig(v, oh);
 
-       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);
+       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);
        else
-               pr_debug("omap_hwmod: %s: reset in %d usec\n", oh->name, c);
+               pr_debug("omap_hwmod: %s: softreset 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()
         */
 
-       return (c == MAX_MODULE_RESET_WAIT) ? -ETIMEDOUT : 0;
+       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;
 }
 
 /**
@@ -891,9 +1168,11 @@ 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.  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().
+ * 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().
  */
 int _omap_hwmod_enable(struct omap_hwmod *oh)
 {
@@ -909,6 +1188,15 @@ 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);
@@ -922,7 +1210,7 @@ int _omap_hwmod_enable(struct omap_hwmod *oh)
                if (oh->class->sysc) {
                        if (!(oh->_int_flags & _HWMOD_SYSCONFIG_LOADED))
                                _update_sysc_cache(oh);
-                       _sysc_enable(oh);
+                       _enable_sysc(oh);
                }
        } else {
                pr_debug("omap_hwmod: %s: _wait_target_ready: %d\n",
@@ -933,12 +1221,14 @@ int _omap_hwmod_enable(struct omap_hwmod *oh)
 }
 
 /**
- * _idle - idle an omap_hwmod
+ * _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.  Returns -EINVAL if the hwmod is in the wrong
- * state or returns 0.
+ * 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.
  */
 int _omap_hwmod_idle(struct omap_hwmod *oh)
 {
@@ -951,7 +1241,7 @@ int _omap_hwmod_idle(struct omap_hwmod *oh)
        pr_debug("omap_hwmod: %s: idling\n", oh->name);
 
        if (oh->class->sysc)
-               _sysc_idle(oh);
+               _idle_sysc(oh);
        _del_initiator_dep(oh, mpu_oh);
        _disable_clocks(oh);
 
@@ -981,10 +1271,21 @@ static int _shutdown(struct omap_hwmod *oh)
        pr_debug("omap_hwmod: %s: disabling\n", oh->name);
 
        if (oh->class->sysc)
-               _sysc_shutdown(oh);
-       _del_initiator_dep(oh, mpu_oh);
-       /* XXX what about the other system initiators here? DMA, tesla, d2d */
-       _disable_clocks(oh);
+               _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);
+       }
        /* XXX Should this code also force-disable the optional clocks? */
 
        /* XXX mux any associated balls to safe mode */
@@ -1000,11 +1301,10 @@ 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.  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.
+ * 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.
  */
 static int _setup(struct omap_hwmod *oh, void *data)
 {
@@ -1034,8 +1334,19 @@ 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",
@@ -1044,16 +1355,16 @@ static int _setup(struct omap_hwmod *oh, void *data)
        }
 
        if (!(oh->flags & HWMOD_INIT_NO_RESET)) {
+               _reset(oh);
+
                /*
-                * 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.
+                * 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.
                 */
                if (oh->class->sysc) {
                        _update_sysc_cache(oh);
-                       _sysc_enable(oh);
+                       _enable_sysc(oh);
                }
        }
 
@@ -1309,7 +1620,7 @@ int omap_hwmod_unregister(struct omap_hwmod *oh)
  * omap_hwmod_enable - enable an omap_hwmod
  * @oh: struct omap_hwmod *
  *
- * Enable an omap_hwomd @oh.  Intended to be called by omap_device_enable().
+ * Enable an omap_hwmod @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)
@@ -1319,9 +1630,9 @@ int omap_hwmod_enable(struct omap_hwmod *oh)
        if (!oh)
                return -EINVAL;
 
-       mutex_lock(&omap_hwmod_mutex);
+       mutex_lock(&oh->_mutex);
        r = _omap_hwmod_enable(oh);
-       mutex_unlock(&omap_hwmod_mutex);
+       mutex_unlock(&oh->_mutex);
 
        return r;
 }
@@ -1331,7 +1642,7 @@ int omap_hwmod_enable(struct omap_hwmod *oh)
  * omap_hwmod_idle - idle an omap_hwmod
  * @oh: struct omap_hwmod *
  *
- * Idle an omap_hwomd @oh.  Intended to be called by omap_device_idle().
+ * Idle an omap_hwmod @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)
@@ -1339,9 +1650,9 @@ int omap_hwmod_idle(struct omap_hwmod *oh)
        if (!oh)
                return -EINVAL;
 
-       mutex_lock(&omap_hwmod_mutex);
+       mutex_lock(&oh->_mutex);
        _omap_hwmod_idle(oh);
-       mutex_unlock(&omap_hwmod_mutex);
+       mutex_unlock(&oh->_mutex);
 
        return 0;
 }
@@ -1350,7 +1661,7 @@ int omap_hwmod_idle(struct omap_hwmod *oh)
  * omap_hwmod_shutdown - shutdown an omap_hwmod
  * @oh: struct omap_hwmod *
  *
- * Shutdown an omap_hwomd @oh.  Intended to be called by
+ * Shutdown an omap_hwmod @oh.  Intended to be called by
  * omap_device_shutdown().  Returns -EINVAL on error or passes along
  * the return value from _shutdown().
  */
@@ -1359,9 +1670,9 @@ int omap_hwmod_shutdown(struct omap_hwmod *oh)
        if (!oh)
                return -EINVAL;
 
-       mutex_lock(&omap_hwmod_mutex);
+       mutex_lock(&oh->_mutex);
        _shutdown(oh);
-       mutex_unlock(&omap_hwmod_mutex);
+       mutex_unlock(&oh->_mutex);
 
        return 0;
 }
@@ -1374,9 +1685,9 @@ int omap_hwmod_shutdown(struct omap_hwmod *oh)
  */
 int omap_hwmod_enable_clocks(struct omap_hwmod *oh)
 {
-       mutex_lock(&omap_hwmod_mutex);
+       mutex_lock(&oh->_mutex);
        _enable_clocks(oh);
-       mutex_unlock(&omap_hwmod_mutex);
+       mutex_unlock(&oh->_mutex);
 
        return 0;
 }
@@ -1389,9 +1700,9 @@ int omap_hwmod_enable_clocks(struct omap_hwmod *oh)
  */
 int omap_hwmod_disable_clocks(struct omap_hwmod *oh)
 {
-       mutex_lock(&omap_hwmod_mutex);
+       mutex_lock(&oh->_mutex);
        _disable_clocks(oh);
-       mutex_unlock(&omap_hwmod_mutex);
+       mutex_unlock(&oh->_mutex);
 
        return 0;
 }
@@ -1430,20 +1741,18 @@ 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()/_enable().
+ * the return value from _reset().
  */
 int omap_hwmod_reset(struct omap_hwmod *oh)
 {
        int r;
 
-       if (!oh || !(oh->_state & _HWMOD_STATE_ENABLED))
+       if (!oh)
                return -EINVAL;
 
-       mutex_lock(&omap_hwmod_mutex);
+       mutex_lock(&oh->_mutex);
        r = _reset(oh);
-       if (!r)
-               r = _omap_hwmod_enable(oh);
-       mutex_unlock(&omap_hwmod_mutex);
+       mutex_unlock(&oh->_mutex);
 
        return r;
 }
@@ -1468,7 +1777,7 @@ int omap_hwmod_count_resources(struct omap_hwmod *oh)
 {
        int ret, i;
 
-       ret = oh->mpu_irqs_cnt + oh->sdma_chs_cnt;
+       ret = oh->mpu_irqs_cnt + oh->sdma_reqs_cnt;
 
        for (i = 0; i < oh->slaves_cnt; i++)
                ret += oh->slaves[i]->addr_cnt;
@@ -1501,10 +1810,10 @@ int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res)
                r++;
        }
 
-       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;
+       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;
                (res + r)->flags = IORESOURCE_DMA;
                r++;
        }
@@ -1644,9 +1953,9 @@ int omap_hwmod_enable_wakeup(struct omap_hwmod *oh)
            !(oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP))
                return -EINVAL;
 
-       mutex_lock(&omap_hwmod_mutex);
+       mutex_lock(&oh->_mutex);
        _enable_wakeup(oh);
-       mutex_unlock(&omap_hwmod_mutex);
+       mutex_unlock(&oh->_mutex);
 
        return 0;
 }
@@ -1669,13 +1978,91 @@ int omap_hwmod_disable_wakeup(struct omap_hwmod *oh)
            !(oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP))
                return -EINVAL;
 
-       mutex_lock(&omap_hwmod_mutex);
+       mutex_lock(&oh->_mutex);
        _disable_wakeup(oh);
-       mutex_unlock(&omap_hwmod_mutex);
+       mutex_unlock(&oh->_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/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
new file mode 100644 (file)
index 0000000..e20b0ee
--- /dev/null
@@ -0,0 +1,482 @@
+/*
+ * 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 <linux/io.h>
+
+#include <plat/omap_hwmod.h>
+#include <plat/cpu.h>
+
+#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);
+}
+
index 723b44e252fdc4ab5924a8b16d96f0645b22a2c0..af00c174d7a9bc8848d72c40018527dc29ab76a6 100644 (file)
 #include <plat/board.h>
 #include <plat/powerdomain.h>
 #include <plat/clockdomain.h>
+#include <plat/dmtimer.h>
 
 #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; \
@@ -349,6 +354,23 @@ 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;
@@ -494,8 +516,10 @@ int pm_dbg_regset_init(int reg_set)
 
 static int pwrdm_suspend_get(void *data, u64 *val)
 {
-       int ret;
-       ret = omap3_pm_get_suspend_state((struct powerdomain *)data);
+       int ret = -EINVAL;
+
+       if (cpu_is_omap34xx())
+               ret = omap3_pm_get_suspend_state((struct powerdomain *)data);
        *val = ret;
 
        if (ret >= 0)
@@ -505,7 +529,10 @@ static int pwrdm_suspend_get(void *data, u64 *val)
 
 static int pwrdm_suspend_set(void *data, u64 val)
 {
-       return omap3_pm_set_suspend_state((struct powerdomain *)data, (int)val);
+       if (cpu_is_omap34xx())
+               return omap3_pm_set_suspend_state(
+                       (struct powerdomain *)data, (int)val);
+       return -EINVAL;
 }
 
 DEFINE_SIMPLE_ATTRIBUTE(pwrdm_suspend_fops, pwrdm_suspend_get,
@@ -553,8 +580,10 @@ static int option_set(void *data, u64 val)
 
        *option = val;
 
-       if (option == &enable_off_mode)
-               omap3_pm_off_mode_enable(val);
+       if (option == &enable_off_mode) {
+               if (cpu_is_omap34xx())
+                       omap3_pm_off_mode_enable(val);
+       }
 
        return 0;
 }
@@ -609,6 +638,9 @@ 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;
index 68f9f2e958917290f5814b7b186c33135d2ec2c4..59ca03b0e691c4dda171d68ffc30fce327352dbd 100644 (file)
 #include <plat/omap_device.h>
 #include <plat/common.h>
 
+#include <plat/powerdomain.h>
+#include <plat/clockdomain.h>
+
 static struct omap_device_pm_latency *pm_lats;
 
 static struct device *mpu_dev;
-static struct device *dsp_dev;
+static struct device *iva_dev;
 static struct device *l3_dev;
+static struct device *dsp_dev;
 
 struct device *omap2_get_mpuss_device(void)
 {
@@ -30,10 +34,10 @@ struct device *omap2_get_mpuss_device(void)
        return mpu_dev;
 }
 
-struct device *omap2_get_dsp_device(void)
+struct device *omap2_get_iva_device(void)
 {
-       WARN_ON_ONCE(!dsp_dev);
-       return dsp_dev;
+       WARN_ON_ONCE(!iva_dev);
+       return iva_dev;
 }
 
 struct device *omap2_get_l3_device(void)
@@ -42,6 +46,13 @@ 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)
 {
@@ -69,8 +80,60 @@ 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", &dsp_dev);
-       _init_omap_device("l3_main", &l3_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;
 }
 
 static int __init omap2_common_pm_init(void)
index 3de6ece23fc8b306653fde7af790926df2e05e1e..77770a13cea8f7a1e0863058a64dbf30115aad77 100644 (file)
@@ -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 set_pwrdm_state(struct powerdomain *pwrdm, u32 state);
+extern int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state);
 extern int omap3_idle_init(void);
 
 struct cpuidle_params {
@@ -48,9 +48,11 @@ 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
 
index 7b03426c72a317307db1df3931a5018443117b33..d2b940c7215da92213ba7bed3030abdc641afc53 100644 (file)
@@ -38,7 +38,6 @@
 #include <plat/prcm.h>
 #include <plat/gpmc.h>
 #include <plat/dma.h>
-#include <plat/dmtimer.h>
 
 #include <asm/tlbflush.h>
 
 #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;
@@ -351,7 +345,6 @@ 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;
@@ -385,9 +378,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();
        }
@@ -396,19 +389,10 @@ 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 (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
+               if (per_next_state == PWRDM_POWER_OFF)
                                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);
@@ -475,8 +459,6 @@ 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 */
@@ -501,51 +483,6 @@ 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();
@@ -567,23 +504,6 @@ out:
 #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();
@@ -604,7 +524,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 (set_pwrdm_state(pwrst->pwrdm, pwrst->next_state))
+               if (omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state))
                        goto restore;
                if (pwrdm_clear_all_prev_pwrst(pwrst->pwrdm))
                        goto restore;
@@ -625,7 +545,7 @@ restore:
                               pwrst->pwrdm->name, pwrst->next_state);
                        ret = -1;
                }
-               set_pwrdm_state(pwrst->pwrdm, pwrst->saved_state);
+               omap_set_pwrdm_state(pwrst->pwrdm, pwrst->saved_state);
        }
        if (ret)
                printk(KERN_ERR "Could not enter target state in pm_suspend\n");
@@ -974,7 +894,7 @@ void omap3_pm_off_mode_enable(int enable)
 
        list_for_each_entry(pwrst, &pwrst_list, node) {
                pwrst->next_state = state;
-               set_pwrdm_state(pwrst->pwrdm, state);
+               omap_set_pwrdm_state(pwrst->pwrdm, state);
        }
 }
 
@@ -1019,7 +939,7 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
        if (pwrdm_has_hdwr_sar(pwrdm))
                pwrdm_enable_hdwr_sar(pwrdm);
 
-       return set_pwrdm_state(pwrst->pwrdm, pwrst->next_state);
+       return omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state);
 }
 
 /*
@@ -1029,9 +949,6 @@ 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/arch/arm/mach-omap2/pm_bus.c b/arch/arm/mach-omap2/pm_bus.c
new file mode 100644 (file)
index 0000000..784989f
--- /dev/null
@@ -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 <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/pm_runtime.h>
+#include <linux/platform_device.h>
+#include <linux/mutex.h>
+
+#include <plat/omap_device.h>
+#include <plat/omap-pm.h>
+
+#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);
index c20137497c92fe3f88bcb16b1d9fa72b1b8013f0..d4388d34c26a0707594af067e7394eb775d947dc 100644 (file)
@@ -33,6 +33,7 @@
 #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;
@@ -161,8 +162,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(OMAP_RST_DPLL3_MASK, prcm_offs,
-                                                OMAP4_RM_RSTCTRL);
+               prm_set_mod_reg_bits(OMAP4430_RST_GLOBAL_WARM_SW_MASK,
+                                    prcm_offs, OMAP4_RM_RSTCTRL);
 }
 
 static inline u32 __omap_prcm_read(void __iomem *base, s16 module, u16 reg)
@@ -215,6 +216,30 @@ 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)
 {
index 588873b9303aa57c38bc716cb3c8b81a61b8d1d9..7be040b2fdab138ad180b5f140866f775b2c79ae 100644 (file)
@@ -5,7 +5,7 @@
  * OMAP2/3 Power/Reset Management (PRM) register definitions
  *
  * Copyright (C) 2007-2009 Texas Instruments, Inc.
- * Copyright (C) 2009 Nokia Corporation
+ * Copyright (C) 2010 Nokia Corporation
  *
  * Written by Paul Walmsley
  *
@@ -246,6 +246,15 @@ 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
 
 /*
@@ -398,4 +407,11 @@ static inline u32 prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx)
 #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/arch/arm/mach-omap2/prm2xxx_3xxx.c b/arch/arm/mach-omap2/prm2xxx_3xxx.c
new file mode 100644 (file)
index 0000000..421771e
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * 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 <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+
+#include <plat/common.h>
+#include <plat/cpu.h>
+#include <plat/prcm.h>
+
+#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/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c
new file mode 100644 (file)
index 0000000..a1ff918
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * 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 <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+
+#include <plat/common.h>
+#include <plat/cpu.h>
+#include <plat/prcm.h>
+
+#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;
+}
+
index 9405831b746a5e63dd4dc3a2a6220afce032713c..2a151917ef52874b38fe4f857ffd34d6601efd89 100644 (file)
@@ -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
\ No newline at end of file
+obj-$(CONFIG_OMAP_PM_NOOP) += omap-pm-noop.o
index 44bafdab2dceaa94d7d6facbcfd422b2f65b660c..1d706cf63ca0e697521d38ab814d9889a1b70435 100644 (file)
@@ -581,7 +581,7 @@ int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
         * When the functional clock disappears, too quick writes seem
         * to cause an abort. XXX Is this still necessary?
         */
-       __delay(150000);
+       __delay(300000);
 
        return ret;
 }
index 7951eefe1a0e90d634c315882427f94fc9c32faa..c05c653d1674e1e8945835b64471893135702c11 100644 (file)
@@ -2084,9 +2084,10 @@ 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;
+               u32 l1 = 0, l2 = 0;
+               int j;
 
-               if (bank->dbck_enable_mask)
+               for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++)
                        clk_disable(bank->dbck);
 
                if (power_state > PWRDM_POWER_OFF)
@@ -2151,9 +2152,10 @@ void omap2_gpio_resume_after_idle(void)
                min = 1;
        for (i = min; i < gpio_bank_count; i++) {
                struct gpio_bank *bank = &gpio_bank[i];
-               u32 l, gen, gen0, gen1;
+               u32 l = 0, gen, gen0, gen1;
+               int j;
 
-               if (bank->dbck_enable_mask)
+               for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++)
                        clk_enable(bank->dbck);
 
                if (!workaround_enabled)
index 9776b41ad76f57a9f63bd3be3e1044f2f58481af..c45dbb975e09bbd11a30ae400c206233309713b1 100644 (file)
@@ -91,7 +91,8 @@ void omap3_map_io(void);
 })
 
 extern struct device *omap2_get_mpuss_device(void);
-extern struct device *omap2_get_dsp_device(void);
+extern struct device *omap2_get_iva_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 */
index 2e2ae530fced338a7b08fe16bc715582cd27cb44..9b38e4bddf577f193f7b28f741e3a6ff831e2ef1 100644 (file)
@@ -391,6 +391,7 @@ IS_OMAP_TYPE(3517, 0x3517)
 
 #define OMAP443X_CLASS         0x44300044
 #define OMAP4430_REV_ES1_0     0x44300044
+#define OMAP4430_REV_ES2_0     0x44301044
 
 /*
  * omap_chip bits
@@ -417,10 +418,12 @@ IS_OMAP_TYPE(3517, 0x3517)
 #define CHIP_IS_OMAP4430ES1            (1 << 8)
 #define CHIP_IS_OMAP3630ES1_1           (1 << 9)
 #define CHIP_IS_OMAP3630ES1_2           (1 << 10)
+#define CHIP_IS_OMAP4430ES2            (1 << 11)
 
 #define CHIP_IS_OMAP24XX               (CHIP_IS_OMAP2420 | CHIP_IS_OMAP2430)
 
-#define CHIP_IS_OMAP4430               (CHIP_IS_OMAP4430ES1)
+#define CHIP_IS_OMAP4430               (CHIP_IS_OMAP4430ES1 | \
+                                                CHIP_IS_OMAP4430ES2)
 
 /*
  * "GE" here represents "greater than or equal to" in terms of ES
index 87f6bf2ea4fafbf2864a9f72f630cc5ec56da9a9..36a0befd6168e82c5acc3f7cc75602d0158a40ea 100644 (file)
@@ -18,6 +18,8 @@
  * 02110-1301 USA
  *
  */
+#ifndef __ASM__ARCH_OMAP_I2C_H
+#define __ASM__ARCH_OMAP_I2C_H
 
 #include <linux/i2c.h>
 
@@ -36,3 +38,5 @@ static inline int omap_register_i2c_bus(int bus_id, u32 clkrate,
 
 void __init omap1_i2c_mux_pins(int bus_id);
 void __init omap2_i2c_mux_pins(int bus_id);
+
+#endif /* __ASM__ARCH_OMAP_I2C_H */
index 9b89ec601ee2788535c75f8fa572b149d85af957..4f819fc261b721d71ca62220e8ae3d1a69a2491d 100644 (file)
@@ -73,10 +73,9 @@ struct omap_mmc_platform_data {
 
        struct omap_mmc_slot_data {
 
-               /* 4 wire signaling is optional, and is used for SD/SDIO/HSMMC;
-                * 8 wire signaling is also optional, and is used with HSMMC
-                */
-               u8 wires;
+               /* 4/8 wires and any additional host capabilities
+                * need to OR'd all capabilities (ref. linux/mmc/host.h) */
+               u32 caps;
 
                /*
                 * nomux means "standard" muxing is wrong on this board, and
index 25cd9ac3b0958eb1a61d166b485731be2a480dab..28e2d1a78433b6d57c94e40b4050bb8ab521717c 100644 (file)
@@ -36,6 +36,8 @@
 
 #include <plat/omap_hwmod.h>
 
+extern struct device omap_device_parent;
+
 /* omap_device._state values */
 #define OMAP_DEVICE_STATE_UNKNOWN      0
 #define OMAP_DEVICE_STATE_ENABLED      1
@@ -62,7 +64,6 @@
  *
  */
 struct omap_device {
-       u32                             magic;
        struct platform_device          pdev;
        struct omap_hwmod               **hwmods;
        struct omap_device_pm_latency   *pm_lats;
@@ -82,7 +83,6 @@ 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);
 
index a4e508dfaba2716a46a9d20d1ac59337dce1fae2..c1835afc238d5235434f58ccf344e25840eb331a 100644 (file)
  *
  * These headers and macros are used to define OMAP on-chip module
  * data and their integration with other OMAP modules and Linux.
- *
- * 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
+ * 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).
  *
  * 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
@@ -35,6 +32,7 @@
 #include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/ioport.h>
+#include <linux/mutex.h>
 #include <plat/cpu.h>
 
 struct omap_device;
@@ -96,7 +94,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_ch: DMA channel ID
+ * @dma_req: DMA request 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
@@ -104,7 +102,20 @@ struct omap_hwmod_irq_info {
  */
 struct omap_hwmod_dma_info {
        const char      *name;
-       u16             dma_ch;
+       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;
 };
 
 /**
@@ -237,8 +248,9 @@ 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_MISSING           (1 << 7)
+#define SYSS_HAS_RESET_STATUS  (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
@@ -327,10 +339,12 @@ 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;
 };
 
@@ -352,6 +366,10 @@ 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)
@@ -360,6 +378,7 @@ 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
@@ -410,7 +429,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_chs: ptr to an array of SDMA channel IDs (see also sdma_chs_cnt)
+ * @sdma_reqs: ptr to an array of System DMA request IDs (see sdma_reqs_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)
@@ -424,7 +443,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_chs_cnt: number of @sdma_chs
+ * @sdma_reqs_cnt: number of @sdma_reqs
  * @opt_clks_cnt: number of @opt_clks
  * @master_cnt: number of @master entries
  * @slaves_cnt: number of @slave entries
@@ -433,6 +452,7 @@ 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
@@ -448,7 +468,8 @@ 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_chs;
+       struct omap_hwmod_dma_info      *sdma_reqs;
+       struct omap_hwmod_rst_info      *rst_lines;
        union {
                struct omap_hwmod_omap2_prcm omap2;
                struct omap_hwmod_omap4_prcm omap4;
@@ -461,6 +482,7 @@ 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;
@@ -468,7 +490,8 @@ struct omap_hwmod {
        u8                              msuspendmux_shift;
        u8                              response_lat;
        u8                              mpu_irqs_cnt;
-       u8                              sdma_chs_cnt;
+       u8                              sdma_reqs_cnt;
+       u8                              rst_lines_cnt;
        u8                              opt_clks_cnt;
        u8                              masters_cnt;
        u8                              slaves_cnt;
@@ -492,6 +515,10 @@ 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);
 
@@ -534,5 +561,6 @@ 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
index 9fbd91419cd15b2849460eed590165e47b820c2a..ab77442e42ab1649cb1b0363f4a95af46c9470f3 100644 (file)
@@ -38,6 +38,8 @@ 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);
index ddf723be48dc997c867226ec5838dd27fe55db05..57dffa7e3ea6f9fcee8bbdc4e9aeb764889402c9 100644 (file)
@@ -153,6 +153,7 @@ static inline void __arch_decomp_setup(unsigned long arch_id)
 
                /* omap4 based boards using UART3 */
                DEBUG_LL_OMAP4(3, omap_4430sdp);
+               DEBUG_LL_OMAP4(3, omap4_panda);
 
                /* zoom2/3 external uart */
                DEBUG_LL_ZOOM(omap_zoom2);
index 2a9427c8cc485430a28b4184afc4b20fd654dc7c..667456228a12ec83e3784b2e1145a0f4e17f4e68 100644 (file)
@@ -105,7 +105,7 @@ static inline void omap1_usb_init(struct omap_usb_config *pdata)
 #if defined(CONFIG_ARCH_OMAP_OTG) || defined(CONFIG_ARCH_OMAP_OTG_MODULE)
 void omap2_usbfs_init(struct omap_usb_config *pdata);
 #else
-static inline omap2_usbfs_init(struct omap_usb_config *pdata)
+static inline void omap2_usbfs_init(struct omap_usb_config *pdata)
 {
 }
 #endif
index e31496e35b0f452d4ff9e375855718fc0a078d40..ecbfe398a309bdf674ba03f0c706ec0a40d5b148 100644 (file)
@@ -878,7 +878,7 @@ EXPORT_SYMBOL(omap_mcbsp_free);
 void omap_mcbsp_start(unsigned int id, int tx, int rx)
 {
        struct omap_mcbsp *mcbsp;
-       int idle;
+       int enable_srg = 0;
        u16 w;
 
        if (!omap_mcbsp_check_valid_id(id)) {
@@ -893,10 +893,13 @@ void omap_mcbsp_start(unsigned int id, int tx, int rx)
        mcbsp->rx_word_length = (MCBSP_READ_CACHE(mcbsp, RCR1) >> 5) & 0x7;
        mcbsp->tx_word_length = (MCBSP_READ_CACHE(mcbsp, XCR1) >> 5) & 0x7;
 
-       idle = !((MCBSP_READ_CACHE(mcbsp, SPCR2) |
-                       MCBSP_READ_CACHE(mcbsp, SPCR1)) & 1);
+       /* Only enable SRG, if McBSP is master */
+       w = MCBSP_READ_CACHE(mcbsp, PCR0);
+       if (w & (FSXM | FSRM | CLKXM | CLKRM))
+               enable_srg = !((MCBSP_READ_CACHE(mcbsp, SPCR2) |
+                               MCBSP_READ_CACHE(mcbsp, SPCR1)) & 1);
 
-       if (idle) {
+       if (enable_srg) {
                /* Start the sample generator */
                w = MCBSP_READ_CACHE(mcbsp, SPCR2);
                MCBSP_WRITE(mcbsp, SPCR2, w | (1 << 6));
@@ -919,7 +922,7 @@ void omap_mcbsp_start(unsigned int id, int tx, int rx)
         */
        udelay(500);
 
-       if (idle) {
+       if (enable_srg) {
                /* Start frame sync */
                w = MCBSP_READ_CACHE(mcbsp, SPCR2);
                MCBSP_WRITE(mcbsp, SPCR2, w | (1 << 7));
index d2b160942ccc5ec0a2e0fb2efe3e7e288da9cb12..abe933cd8f0926c99b059d2a214bda900e5326eb 100644 (file)
@@ -82,6 +82,7 @@
 #include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/io.h>
+#include <linux/clk.h>
 
 #include <plat/omap_device.h>
 #include <plat/omap_hwmod.h>
 #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 */
 
 /**
@@ -243,6 +238,44 @@ 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 <dev-id=dev_name, con-id=role>
+ * if an entry is already present in it with the form <dev-id=NULL, con-id=role>
+ *
+ * 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(<dev*>, <role>).
+ *
+ * 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 */
 
@@ -257,12 +290,11 @@ static inline struct omap_device *_find_by_pdev(struct platform_device *pdev)
  */
 int omap_device_count_resources(struct omap_device *od)
 {
-       struct omap_hwmod *oh;
        int c = 0;
        int i;
 
-       for (i = 0, oh = *od->hwmods; i < od->hwmods_cnt; i++, oh++)
-               c += omap_hwmod_count_resources(oh);
+       for (i = 0; i < od->hwmods_cnt; i++)
+               c += omap_hwmod_count_resources(od->hwmods[i]);
 
        pr_debug("omap_device: %s: counted %d total resources across %d "
                 "hwmods\n", od->pdev.name, c, od->hwmods_cnt);
@@ -289,12 +321,11 @@ int omap_device_count_resources(struct omap_device *od)
  */
 int omap_device_fill_resources(struct omap_device *od, struct resource *res)
 {
-       struct omap_hwmod *oh;
        int c = 0;
        int i, r;
 
-       for (i = 0, oh = *od->hwmods; i < od->hwmods_cnt; i++, oh++) {
-               r = omap_hwmod_fill_resources(oh, res);
+       for (i = 0; i < od->hwmods_cnt; i++) {
+               r = omap_hwmod_fill_resources(od->hwmods[i], res);
                res += r;
                c += r;
        }
@@ -414,15 +445,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;
@@ -473,6 +504,7 @@ 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);
 }
 
@@ -566,7 +598,6 @@ int omap_device_shutdown(struct platform_device *pdev)
 {
        int ret, i;
        struct omap_device *od;
-       struct omap_hwmod *oh;
 
        od = _find_by_pdev(pdev);
 
@@ -579,8 +610,8 @@ int omap_device_shutdown(struct platform_device *pdev)
 
        ret = _omap_device_deactivate(od, IGNORE_WAKEUP_LAT);
 
-       for (i = 0, oh = *od->hwmods; i < od->hwmods_cnt; i++, oh++)
-               omap_hwmod_shutdown(oh);
+       for (i = 0; i < od->hwmods_cnt; i++)
+               omap_hwmod_shutdown(od->hwmods[i]);
 
        od->_state = OMAP_DEVICE_STATE_SHUTDOWN;
 
@@ -626,18 +657,6 @@ 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 *
@@ -692,11 +711,10 @@ void __iomem *omap_device_get_rt_va(struct omap_device *od)
  */
 int omap_device_enable_hwmods(struct omap_device *od)
 {
-       struct omap_hwmod *oh;
        int i;
 
-       for (i = 0, oh = *od->hwmods; i < od->hwmods_cnt; i++, oh++)
-               omap_hwmod_enable(oh);
+       for (i = 0; i < od->hwmods_cnt; i++)
+               omap_hwmod_enable(od->hwmods[i]);
 
        /* XXX pass along return value here? */
        return 0;
@@ -710,11 +728,10 @@ int omap_device_enable_hwmods(struct omap_device *od)
  */
 int omap_device_idle_hwmods(struct omap_device *od)
 {
-       struct omap_hwmod *oh;
        int i;
 
-       for (i = 0, oh = *od->hwmods; i < od->hwmods_cnt; i++, oh++)
-               omap_hwmod_idle(oh);
+       for (i = 0; i < od->hwmods_cnt; i++)
+               omap_hwmod_idle(od->hwmods[i]);
 
        /* XXX pass along return value here? */
        return 0;
@@ -729,11 +746,10 @@ int omap_device_idle_hwmods(struct omap_device *od)
  */
 int omap_device_disable_clocks(struct omap_device *od)
 {
-       struct omap_hwmod *oh;
        int i;
 
-       for (i = 0, oh = *od->hwmods; i < od->hwmods_cnt; i++, oh++)
-               omap_hwmod_disable_clocks(oh);
+       for (i = 0; i < od->hwmods_cnt; i++)
+               omap_hwmod_disable_clocks(od->hwmods[i]);
 
        /* XXX pass along return value here? */
        return 0;
@@ -748,12 +764,22 @@ int omap_device_disable_clocks(struct omap_device *od)
  */
 int omap_device_enable_clocks(struct omap_device *od)
 {
-       struct omap_hwmod *oh;
        int i;
 
-       for (i = 0, oh = *od->hwmods; i < od->hwmods_cnt; i++, oh++)
-               omap_hwmod_enable_clocks(oh);
+       for (i = 0; i < od->hwmods_cnt; i++)
+               omap_hwmod_enable_clocks(od->hwmods[i]);
 
        /* 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);
index 226b2e858d6c9617243a91138821fb0e355daf56..98c86ff172059e51ab75998da1431f33b32510b7 100644 (file)
@@ -53,7 +53,7 @@
 #define OMAP4_SRAM_PUB_PA      (OMAP4_SRAM_PA + 0x4000)
 #define OMAP4_SRAM_PUB_VA      (OMAP4_SRAM_VA + 0x4000)
 
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
+#if defined(CONFIG_ARCH_OMAP2PLUS)
 #define SRAM_BOOTLOADER_SZ     0x00
 #else
 #define SRAM_BOOTLOADER_SZ     0x80
@@ -93,16 +93,7 @@ extern unsigned long omapfb_reserve_sram(unsigned long sram_pstart,
  */
 static int is_sram_locked(void)
 {
-       int type = 0;
-
-       if (cpu_is_omap44xx())
-               /* Not yet supported */
-               return 0;
-
-       if (cpu_is_omap242x())
-               type = omap_rev() & OMAP2_DEVICETYPE_MASK;
-
-       if (type == GP_DEVICE) {
+       if (OMAP2_DEVICE_TYPE_GP == omap_type()) {
                /* RAMFW: R/W access to all initiators for all qualifier sets */
                if (cpu_is_omap242x()) {
                        __raw_writel(0xFF, OMAP24XX_VA_REQINFOPERM0); /* all q-vects */
index d98ddcfac5e5cb2e0ddf1fd32fac9318cc09b29b..a9d62cfa87a2cc8261c2552b840837654c2d994d 100644 (file)
@@ -1317,7 +1317,7 @@ static int __init mmc_omap_new_slot(struct mmc_omap_host *host, int id)
        host->slots[id] = slot;
 
        mmc->caps = 0;
-       if (host->pdata->slots[id].wires >= 4)
+       if (host->pdata->slots[id].caps & MMC_CAP_8_BIT_DATA)
                mmc->caps |= MMC_CAP_4_BIT_DATA;
 
        mmc->ops = &mmc_omap_ops;
index 4526d2791f2990229acbe9ef0f5c88286819807f..53f8fa599cf5fc8d686e75a9eae53d1a9a882d6e 100644 (file)
@@ -2116,23 +2116,9 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev)
        mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
                     MMC_CAP_WAIT_WHILE_BUSY | MMC_CAP_ERASE;
 
-       switch (mmc_slot(host).wires) {
-       case 8:
-               mmc->caps |= MMC_CAP_8_BIT_DATA;
-               /* Fall through */
-       case 4:
+       mmc->caps |= mmc_slot(host).caps;
+       if (mmc->caps & MMC_CAP_8_BIT_DATA)
                mmc->caps |= MMC_CAP_4_BIT_DATA;
-               break;
-       case 1:
-               /* Nothing to crib here */
-       case 0:
-               /* Assuming nothing was given by board, Core use's 1-Bit */
-               break;
-       default:
-               /* Completely unexpected.. Core goes with 1-Bit Width */
-               dev_crit(mmc_dev(host->mmc), "Invalid width %d\n used!"
-                       "using 1 instead\n", mmc_slot(host).wires);
-       }
 
        if (mmc_slot(host).nonremovable)
                mmc->caps |= MMC_CAP_NONREMOVABLE;