]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge branch 'amba' of git://git.linaro.org/people/rmk/linux-arm
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 24 Mar 2012 00:36:29 +0000 (17:36 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 24 Mar 2012 00:36:29 +0000 (17:36 -0700)
Pull #2 ARM updates from Russell King:
 "Further ARM AMBA primecell updates which aren't included directly in
  the previous commit.  I wanted to keep these separate as they're
  touching stuff outside arch/arm/."

* 'amba' of git://git.linaro.org/people/rmk/linux-arm:
  ARM: 7362/1: AMBA: Add module_amba_driver() helper macro for amba_driver
  ARM: 7335/1: mach-u300: do away with MMC config files
  ARM: 7280/1: mmc: mmci: Cache MMCICLOCK and MMCIPOWER register
  ARM: 7309/1: realview: fix unconnected interrupts on EB11MP
  ARM: 7230/1: mmc: mmci: Fix PIO read for small SDIO packets
  ARM: 7227/1: mmc: mmci: Prepare for SDIO before setting up DMA job
  ARM: 7223/1: mmc: mmci: Fixup use of runtime PM and use autosuspend
  ARM: 7221/1: mmc: mmci: Change from using legacy suspend
  ARM: 7219/1: mmc: mmci: Change vdd_handler to a generic ios_handler
  ARM: 7218/1: mmc: mmci: Provide option to configure bus signal direction
  ARM: 7217/1: mmc: mmci: Put power register deviations in variant data
  ARM: 7216/1: mmc: mmci: Do not release spinlock in request_end
  ARM: 7215/1: mmc: mmci: Increase max_segs from 16 to 128

17 files changed:
arch/arm/mach-realview/include/mach/irqs-eb.h
arch/arm/mach-u300/Makefile
arch/arm/mach-u300/core.c
arch/arm/mach-u300/mmc.c [deleted file]
arch/arm/mach-u300/mmc.h [deleted file]
arch/arm/mach-ux500/board-mop500-sdi.c
drivers/char/hw_random/nomadik-rng.c
drivers/dma/pl330.c
drivers/input/serio/ambakmi.c
drivers/mmc/host/mmci.c
drivers/mmc/host/mmci.h
drivers/rtc/rtc-pl030.c
drivers/rtc/rtc-pl031.c
drivers/watchdog/sp805_wdt.c
include/linux/amba/bus.h
include/linux/amba/mmci.h
sound/arm/aaci.c

index 204d5378f309f28f6ca8ceac994ed3d7672e6c98..d6b5073692d2fdda8db2656a032f374894e57463 100644 (file)
 #define IRQ_EB11MP_L220_SLAVE  (IRQ_EB_GIC_START + 30)
 #define IRQ_EB11MP_L220_DECODE (IRQ_EB_GIC_START + 31)
 
-#define IRQ_EB11MP_UART2       -1
-#define IRQ_EB11MP_UART3       -1
-#define IRQ_EB11MP_CLCD                -1
-#define IRQ_EB11MP_DMA         -1
-#define IRQ_EB11MP_WDOG                -1
-#define IRQ_EB11MP_GPIO0       -1
-#define IRQ_EB11MP_GPIO1       -1
-#define IRQ_EB11MP_GPIO2       -1
-#define IRQ_EB11MP_SCI         -1
-#define IRQ_EB11MP_SSP         -1
+/*
+ * The 11MPcore tile leaves the following unconnected.
+ */
+#define IRQ_EB11MP_UART2       0
+#define IRQ_EB11MP_UART3       0
+#define IRQ_EB11MP_CLCD                0
+#define IRQ_EB11MP_DMA         0
+#define IRQ_EB11MP_WDOG                0
+#define IRQ_EB11MP_GPIO0       0
+#define IRQ_EB11MP_GPIO1       0
+#define IRQ_EB11MP_GPIO2       0
+#define IRQ_EB11MP_SCI         0
+#define IRQ_EB11MP_SSP         0
 
 #define NR_GIC_EB11MP          2
 
index 285538124e5e7d76b2f14540df86051fa4c085db..fd3a5c382f4766df4401167f8a845d02932f2a80 100644 (file)
@@ -8,7 +8,6 @@ obj-n           :=
 obj-           :=
 
 obj-$(CONFIG_ARCH_U300)                  += u300.o
-obj-$(CONFIG_MMC)                 += mmc.o
 obj-$(CONFIG_SPI_PL022)           += spi.o
 obj-$(CONFIG_MACH_U300_SPIDUMMY)  += dummyspichip.o
 obj-$(CONFIG_I2C_STU300)          += i2c.o
index b911590c8ae772f940214301c4b8e60c7d2f9f27..8b90c44d237f92d2afcb261cf698500979842fea 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/termios.h>
 #include <linux/dmaengine.h>
 #include <linux/amba/bus.h>
+#include <linux/amba/mmci.h>
 #include <linux/amba/serial.h>
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
@@ -44,9 +45,9 @@
 #include <mach/gpio-u300.h>
 
 #include "clock.h"
-#include "mmc.h"
 #include "spi.h"
 #include "i2c.h"
+#include "u300-gpio.h"
 
 /*
  * Static I/O mappings that are needed for booting the U300 platforms. The
@@ -117,11 +118,6 @@ static AMBA_APB_DEVICE(uart1, "uart1", 0, U300_UART1_BASE,
 /* AHB device at 0x4000 offset */
 static AMBA_APB_DEVICE(pl172, "pl172", 0, U300_EMIF_CFG_BASE, { }, NULL);
 
-
-/*
- * Everything within this next ifdef deals with external devices connected to
- * the APP SPI bus.
- */
 /* Fast device at 0x6000 offset */
 static AMBA_APB_DEVICE(pl022, "pl022", 0, U300_SPI_BASE,
        { IRQ_U300_SPI }, NULL);
@@ -129,8 +125,26 @@ static AMBA_APB_DEVICE(pl022, "pl022", 0, U300_SPI_BASE,
 /* Fast device at 0x1000 offset */
 #define U300_MMCSD_IRQS        { IRQ_U300_MMCSD_MCIINTR0, IRQ_U300_MMCSD_MCIINTR1 }
 
+static struct mmci_platform_data mmcsd_platform_data = {
+       /*
+        * Do not set ocr_mask or voltage translation function,
+        * we have a regulator we can control instead.
+        */
+       .f_max = 24000000,
+       .gpio_wp = -1,
+       .gpio_cd = U300_GPIO_PIN_MMC_CD,
+       .cd_invert = true,
+       .capabilities = MMC_CAP_MMC_HIGHSPEED |
+       MMC_CAP_SD_HIGHSPEED | MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
+#ifdef CONFIG_COH901318
+       .dma_filter = coh901318_filter_id,
+       .dma_rx_param = (void *) U300_DMA_MMCSD_RX_TX,
+       /* Don't specify a TX channel, this RX channel is bidirectional */
+#endif
+};
+
 static AMBA_APB_DEVICE(mmcsd, "mmci", 0, U300_MMCSD_BASE,
-       U300_MMCSD_IRQS, NULL);
+       U300_MMCSD_IRQS, &mmcsd_platform_data);
 
 /*
  * The order of device declaration may be important, since some devices
@@ -1830,16 +1844,6 @@ void __init u300_init_devices(void)
        writew(val, U300_SYSCON_VBASE + U300_SYSCON_SMCR);
 }
 
-static int core_module_init(void)
-{
-       /*
-        * This needs to be initialized later: it needs the input framework
-        * to be initialized first.
-        */
-       return mmc_init(&mmcsd_device);
-}
-module_init(core_module_init);
-
 /* Forward declare this function from the watchdog */
 void coh901327_watchdog_reset(void);
 
diff --git a/arch/arm/mach-u300/mmc.c b/arch/arm/mach-u300/mmc.c
deleted file mode 100644 (file)
index 05abd6a..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- *
- * arch/arm/mach-u300/mmc.c
- *
- *
- * Copyright (C) 2009 ST-Ericsson SA
- * License terms: GNU General Public License (GPL) version 2
- *
- * Author: Linus Walleij <linus.walleij@stericsson.com>
- * Author: Johan Lundin
- * Author: Jonas Aaberg <jonas.aberg@stericsson.com>
- */
-#include <linux/device.h>
-#include <linux/amba/bus.h>
-#include <linux/mmc/host.h>
-#include <linux/dmaengine.h>
-#include <linux/amba/mmci.h>
-#include <linux/slab.h>
-#include <mach/coh901318.h>
-#include <mach/dma_channels.h>
-
-#include "u300-gpio.h"
-#include "mmc.h"
-
-static struct mmci_platform_data mmc0_plat_data = {
-       /*
-        * Do not set ocr_mask or voltage translation function,
-        * we have a regulator we can control instead.
-        */
-       /* Nominally 2.85V on our platform */
-       .f_max = 24000000,
-       .gpio_wp = -1,
-       .gpio_cd = U300_GPIO_PIN_MMC_CD,
-       .cd_invert = true,
-       .capabilities = MMC_CAP_MMC_HIGHSPEED |
-       MMC_CAP_SD_HIGHSPEED | MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
-#ifdef CONFIG_COH901318
-       .dma_filter = coh901318_filter_id,
-       .dma_rx_param = (void *) U300_DMA_MMCSD_RX_TX,
-       /* Don't specify a TX channel, this RX channel is bidirectional */
-#endif
-};
-
-int __devinit mmc_init(struct amba_device *adev)
-{
-       struct device *mmcsd_device = &adev->dev;
-       int ret = 0;
-
-       mmcsd_device->platform_data = &mmc0_plat_data;
-
-       return ret;
-}
diff --git a/arch/arm/mach-u300/mmc.h b/arch/arm/mach-u300/mmc.h
deleted file mode 100644 (file)
index 92b8512..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- *
- * arch/arm/mach-u300/mmc.h
- *
- *
- * Copyright (C) 2009 ST-Ericsson AB
- * License terms: GNU General Public License (GPL) version 2
- *
- * Author: Jonas Aaberg <jonas.aberg@stericsson.com>
- */
-#ifndef MMC_H
-#define MMC_H
-
-#include <linux/amba/bus.h>
-
-int __devinit mmc_init(struct amba_device *adev);
-
-#endif
index 5dde4d4ebe882f37a6d826f008c5ffd4666c5a36..1daead3e583eb5de6c6d34f6571a9d78549847dd 100644 (file)
  * SDI 0 (MicroSD slot)
  */
 
-/* MMCIPOWER bits */
-#define MCI_DATA2DIREN         (1 << 2)
-#define MCI_CMDDIREN           (1 << 3)
-#define MCI_DATA0DIREN         (1 << 4)
-#define MCI_DATA31DIREN                (1 << 5)
-#define MCI_FBCLKEN            (1 << 7)
-
 /* GPIO pins used by the sdi0 level shifter */
 static int sdi0_en = -1;
 static int sdi0_vsel = -1;
 
-static u32 mop500_sdi0_vdd_handler(struct device *dev, unsigned int vdd,
-                                  unsigned char power_mode)
+static int mop500_sdi0_ios_handler(struct device *dev, struct mmc_ios *ios)
 {
-       switch (power_mode) {
+       switch (ios->power_mode) {
        case MMC_POWER_UP:
        case MMC_POWER_ON:
                /*
@@ -65,8 +57,7 @@ static u32 mop500_sdi0_vdd_handler(struct device *dev, unsigned int vdd,
                break;
        }
 
-       return MCI_FBCLKEN | MCI_CMDDIREN | MCI_DATA0DIREN |
-              MCI_DATA2DIREN | MCI_DATA31DIREN;
+       return 0;
 }
 
 #ifdef CONFIG_STE_DMA40
@@ -90,13 +81,17 @@ static struct stedma40_chan_cfg mop500_sdi0_dma_cfg_tx = {
 #endif
 
 static struct mmci_platform_data mop500_sdi0_data = {
-       .vdd_handler    = mop500_sdi0_vdd_handler,
+       .ios_handler    = mop500_sdi0_ios_handler,
        .ocr_mask       = MMC_VDD_29_30,
        .f_max          = 50000000,
        .capabilities   = MMC_CAP_4_BIT_DATA |
                                MMC_CAP_SD_HIGHSPEED |
                                MMC_CAP_MMC_HIGHSPEED,
        .gpio_wp        = -1,
+       .sigdir         = MCI_ST_FBCLKEN |
+                               MCI_ST_CMDDIREN |
+                               MCI_ST_DATA0DIREN |
+                               MCI_ST_DATA2DIREN,
 #ifdef CONFIG_STE_DMA40
        .dma_filter     = stedma40_filter,
        .dma_rx_param   = &mop500_sdi0_dma_cfg_rx,
index 3d3c1e6703b404e18944394b373452357e85a82b..96de0249e595812f778786380cac78866b3b408e 100644 (file)
@@ -107,17 +107,6 @@ static struct amba_driver nmk_rng_driver = {
        .id_table = nmk_rng_ids,
 };
 
-static int __init nmk_rng_init(void)
-{
-       return amba_driver_register(&nmk_rng_driver);
-}
-
-static void __devexit nmk_rng_exit(void)
-{
-       amba_driver_unregister(&nmk_rng_driver);
-}
-
-module_init(nmk_rng_init);
-module_exit(nmk_rng_exit);
+module_amba_driver(nmk_rng_driver);
 
 MODULE_LICENSE("GPL");
index b8ec03ee8e22e495e633ff95bf9faf0d02756dac..16b66c827f19984c47401b89d70338570c446f18 100644 (file)
@@ -1035,18 +1035,7 @@ static struct amba_driver pl330_driver = {
        .remove = pl330_remove,
 };
 
-static int __init pl330_init(void)
-{
-       return amba_driver_register(&pl330_driver);
-}
-module_init(pl330_init);
-
-static void __exit pl330_exit(void)
-{
-       amba_driver_unregister(&pl330_driver);
-       return;
-}
-module_exit(pl330_exit);
+module_amba_driver(pl330_driver);
 
 MODULE_AUTHOR("Jaswinder Singh <jassi.brar@samsung.com>");
 MODULE_DESCRIPTION("API Driver for PL330 DMAC");
index 8407d5b0ced8c3d1005e7346fbd7420f40703ba6..2ffd110bd5bc756e461051d39ba31238202a0fa7 100644 (file)
@@ -208,18 +208,7 @@ static struct amba_driver ambakmi_driver = {
        .resume         = amba_kmi_resume,
 };
 
-static int __init amba_kmi_init(void)
-{
-       return amba_driver_register(&ambakmi_driver);
-}
-
-static void __exit amba_kmi_exit(void)
-{
-       amba_driver_unregister(&ambakmi_driver);
-}
-
-module_init(amba_kmi_init);
-module_exit(amba_kmi_exit);
+module_amba_driver(ambakmi_driver);
 
 MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
 MODULE_DESCRIPTION("AMBA KMI controller driver");
index bdfd05517dd5ae22371e3bf73f4471263ec339a4..983e244eca769fcbd4be56b90780ff7c0156b84f 100644 (file)
@@ -53,6 +53,8 @@ static unsigned int fmax = 515633;
  * @sdio: variant supports SDIO
  * @st_clkdiv: true if using a ST-specific clock divider algorithm
  * @blksz_datactrl16: true if Block size is at b16..b30 position in datactrl register
+ * @pwrreg_powerup: power up value for MMCIPOWER register
+ * @signal_direction: input/out direction of bus signals can be indicated
  */
 struct variant_data {
        unsigned int            clkreg;
@@ -63,18 +65,22 @@ struct variant_data {
        bool                    sdio;
        bool                    st_clkdiv;
        bool                    blksz_datactrl16;
+       u32                     pwrreg_powerup;
+       bool                    signal_direction;
 };
 
 static struct variant_data variant_arm = {
        .fifosize               = 16 * 4,
        .fifohalfsize           = 8 * 4,
        .datalength_bits        = 16,
+       .pwrreg_powerup         = MCI_PWR_UP,
 };
 
 static struct variant_data variant_arm_extended_fifo = {
        .fifosize               = 128 * 4,
        .fifohalfsize           = 64 * 4,
        .datalength_bits        = 16,
+       .pwrreg_powerup         = MCI_PWR_UP,
 };
 
 static struct variant_data variant_u300 = {
@@ -83,6 +89,8 @@ static struct variant_data variant_u300 = {
        .clkreg_enable          = MCI_ST_U300_HWFCEN,
        .datalength_bits        = 16,
        .sdio                   = true,
+       .pwrreg_powerup         = MCI_PWR_ON,
+       .signal_direction       = true,
 };
 
 static struct variant_data variant_ux500 = {
@@ -93,6 +101,8 @@ static struct variant_data variant_ux500 = {
        .datalength_bits        = 24,
        .sdio                   = true,
        .st_clkdiv              = true,
+       .pwrreg_powerup         = MCI_PWR_ON,
+       .signal_direction       = true,
 };
 
 static struct variant_data variant_ux500v2 = {
@@ -104,8 +114,32 @@ static struct variant_data variant_ux500v2 = {
        .sdio                   = true,
        .st_clkdiv              = true,
        .blksz_datactrl16       = true,
+       .pwrreg_powerup         = MCI_PWR_ON,
+       .signal_direction       = true,
 };
 
+/*
+ * This must be called with host->lock held
+ */
+static void mmci_write_clkreg(struct mmci_host *host, u32 clk)
+{
+       if (host->clk_reg != clk) {
+               host->clk_reg = clk;
+               writel(clk, host->base + MMCICLOCK);
+       }
+}
+
+/*
+ * This must be called with host->lock held
+ */
+static void mmci_write_pwrreg(struct mmci_host *host, u32 pwr)
+{
+       if (host->pwr_reg != pwr) {
+               host->pwr_reg = pwr;
+               writel(pwr, host->base + MMCIPOWER);
+       }
+}
+
 /*
  * This must be called with host->lock held
  */
@@ -153,7 +187,7 @@ static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired)
        if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_8)
                clk |= MCI_ST_8BIT_BUS;
 
-       writel(clk, host->base + MMCICLOCK);
+       mmci_write_clkreg(host, clk);
 }
 
 static void
@@ -166,14 +200,10 @@ mmci_request_end(struct mmci_host *host, struct mmc_request *mrq)
        host->mrq = NULL;
        host->cmd = NULL;
 
-       /*
-        * Need to drop the host lock here; mmc_request_done may call
-        * back into the driver...
-        */
-       spin_unlock(&host->lock);
-       pm_runtime_put(mmc_dev(host->mmc));
        mmc_request_done(host->mmc, mrq);
-       spin_lock(&host->lock);
+
+       pm_runtime_mark_last_busy(mmc_dev(host->mmc));
+       pm_runtime_put_autosuspend(mmc_dev(host->mmc));
 }
 
 static void mmci_set_mask1(struct mmci_host *host, unsigned int mask)
@@ -607,6 +637,11 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
        if (data->flags & MMC_DATA_READ)
                datactrl |= MCI_DPSM_DIRECTION;
 
+       /* The ST Micro variants has a special bit to enable SDIO */
+       if (variant->sdio && host->mmc->card)
+               if (mmc_card_sdio(host->mmc->card))
+                       datactrl |= MCI_ST_DPSM_SDIOEN;
+
        /*
         * Attempt to use DMA operation mode, if this
         * should fail, fall back to PIO mode
@@ -635,11 +670,6 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
                irqmask = MCI_TXFIFOHALFEMPTYMASK;
        }
 
-       /* The ST Micro variants has a special bit to enable SDIO */
-       if (variant->sdio && host->mmc->card)
-               if (mmc_card_sdio(host->mmc->card))
-                       datactrl |= MCI_ST_DPSM_SDIOEN;
-
        writel(datactrl, base + MMCIDATACTRL);
        writel(readl(base + MMCIMASK0) & ~MCI_DATAENDMASK, base + MMCIMASK0);
        mmci_set_mask1(host, irqmask);
@@ -786,7 +816,24 @@ static int mmci_pio_read(struct mmci_host *host, char *buffer, unsigned int rema
                if (count <= 0)
                        break;
 
-               readsl(base + MMCIFIFO, ptr, count >> 2);
+               /*
+                * SDIO especially may want to send something that is
+                * not divisible by 4 (as opposed to card sectors
+                * etc). Therefore make sure to always read the last bytes
+                * while only doing full 32-bit reads towards the FIFO.
+                */
+               if (unlikely(count & 0x3)) {
+                       if (count < 4) {
+                               unsigned char buf[4];
+                               readsl(base + MMCIFIFO, buf, 1);
+                               memcpy(ptr, buf, count);
+                       } else {
+                               readsl(base + MMCIFIFO, ptr, count >> 2);
+                               count &= ~0x3;
+                       }
+               } else {
+                       readsl(base + MMCIFIFO, ptr, count >> 2);
+               }
 
                ptr += count;
                remain -= count;
@@ -821,14 +868,13 @@ static int mmci_pio_write(struct mmci_host *host, char *buffer, unsigned int rem
                 */
                if (variant->sdio &&
                    mmc_card_sdio(host->mmc->card)) {
+                       u32 clk;
                        if (count < 8)
-                               writel(readl(host->base + MMCICLOCK) &
-                                       ~variant->clkreg_enable,
-                                       host->base + MMCICLOCK);
+                               clk = host->clk_reg & ~variant->clkreg_enable;
                        else
-                               writel(readl(host->base + MMCICLOCK) |
-                                       variant->clkreg_enable,
-                                       host->base + MMCICLOCK);
+                               clk = host->clk_reg | variant->clkreg_enable;
+
+                       mmci_write_clkreg(host, clk);
                }
 
                /*
@@ -1015,10 +1061,17 @@ static void mmci_request(struct mmc_host *mmc, struct mmc_request *mrq)
 static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 {
        struct mmci_host *host = mmc_priv(mmc);
+       struct variant_data *variant = host->variant;
        u32 pwr = 0;
        unsigned long flags;
        int ret;
 
+       pm_runtime_get_sync(mmc_dev(mmc));
+
+       if (host->plat->ios_handler &&
+               host->plat->ios_handler(mmc_dev(mmc), ios))
+                       dev_err(mmc_dev(mmc), "platform ios_handler failed\n");
+
        switch (ios->power_mode) {
        case MMC_POWER_OFF:
                if (host->vcc)
@@ -1035,22 +1088,38 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
                                 * power should be rare so we print an error
                                 * and return here.
                                 */
-                               return;
+                               goto out;
                        }
                }
-               if (host->plat->vdd_handler)
-                       pwr |= host->plat->vdd_handler(mmc_dev(mmc), ios->vdd,
-                                                      ios->power_mode);
-               /* The ST version does not have this, fall through to POWER_ON */
-               if (host->hw_designer != AMBA_VENDOR_ST) {
-                       pwr |= MCI_PWR_UP;
-                       break;
-               }
+               /*
+                * The ST Micro variant doesn't have the PL180s MCI_PWR_UP
+                * and instead uses MCI_PWR_ON so apply whatever value is
+                * configured in the variant data.
+                */
+               pwr |= variant->pwrreg_powerup;
+
+               break;
        case MMC_POWER_ON:
                pwr |= MCI_PWR_ON;
                break;
        }
 
+       if (variant->signal_direction && ios->power_mode != MMC_POWER_OFF) {
+               /*
+                * The ST Micro variant has some additional bits
+                * indicating signal direction for the signals in
+                * the SD/MMC bus and feedback-clock usage.
+                */
+               pwr |= host->plat->sigdir;
+
+               if (ios->bus_width == MMC_BUS_WIDTH_4)
+                       pwr &= ~MCI_ST_DATA74DIREN;
+               else if (ios->bus_width == MMC_BUS_WIDTH_1)
+                       pwr &= (~MCI_ST_DATA74DIREN &
+                               ~MCI_ST_DATA31DIREN &
+                               ~MCI_ST_DATA2DIREN);
+       }
+
        if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) {
                if (host->hw_designer != AMBA_VENDOR_ST)
                        pwr |= MCI_ROD;
@@ -1066,13 +1135,13 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
        spin_lock_irqsave(&host->lock, flags);
 
        mmci_set_clkreg(host, ios->clock);
-
-       if (host->pwr != pwr) {
-               host->pwr = pwr;
-               writel(pwr, host->base + MMCIPOWER);
-       }
+       mmci_write_pwrreg(host, pwr);
 
        spin_unlock_irqrestore(&host->lock, flags);
+
+ out:
+       pm_runtime_mark_last_busy(mmc_dev(mmc));
+       pm_runtime_put_autosuspend(mmc_dev(mmc));
 }
 
 static int mmci_get_ro(struct mmc_host *mmc)
@@ -1346,6 +1415,8 @@ static int __devinit mmci_probe(struct amba_device *dev,
 
        mmci_dma_setup(host);
 
+       pm_runtime_set_autosuspend_delay(&dev->dev, 50);
+       pm_runtime_use_autosuspend(&dev->dev);
        pm_runtime_put(&dev->dev);
 
        mmc_add_host(mmc);
@@ -1430,43 +1501,49 @@ static int __devexit mmci_remove(struct amba_device *dev)
        return 0;
 }
 
-#ifdef CONFIG_PM
-static int mmci_suspend(struct amba_device *dev, pm_message_t state)
+#ifdef CONFIG_SUSPEND
+static int mmci_suspend(struct device *dev)
 {
-       struct mmc_host *mmc = amba_get_drvdata(dev);
+       struct amba_device *adev = to_amba_device(dev);
+       struct mmc_host *mmc = amba_get_drvdata(adev);
        int ret = 0;
 
        if (mmc) {
                struct mmci_host *host = mmc_priv(mmc);
 
                ret = mmc_suspend_host(mmc);
-               if (ret == 0)
+               if (ret == 0) {
+                       pm_runtime_get_sync(dev);
                        writel(0, host->base + MMCIMASK0);
+               }
        }
 
        return ret;
 }
 
-static int mmci_resume(struct amba_device *dev)
+static int mmci_resume(struct device *dev)
 {
-       struct mmc_host *mmc = amba_get_drvdata(dev);
+       struct amba_device *adev = to_amba_device(dev);
+       struct mmc_host *mmc = amba_get_drvdata(adev);
        int ret = 0;
 
        if (mmc) {
                struct mmci_host *host = mmc_priv(mmc);
 
                writel(MCI_IRQENABLE, host->base + MMCIMASK0);
+               pm_runtime_put(dev);
 
                ret = mmc_resume_host(mmc);
        }
 
        return ret;
 }
-#else
-#define mmci_suspend   NULL
-#define mmci_resume    NULL
 #endif
 
+static const struct dev_pm_ops mmci_dev_pm_ops = {
+       SET_SYSTEM_SLEEP_PM_OPS(mmci_suspend, mmci_resume)
+};
+
 static struct amba_id mmci_ids[] = {
        {
                .id     = 0x00041180,
@@ -1512,26 +1589,15 @@ MODULE_DEVICE_TABLE(amba, mmci_ids);
 static struct amba_driver mmci_driver = {
        .drv            = {
                .name   = DRIVER_NAME,
+               .pm     = &mmci_dev_pm_ops,
        },
        .probe          = mmci_probe,
        .remove         = __devexit_p(mmci_remove),
-       .suspend        = mmci_suspend,
-       .resume         = mmci_resume,
        .id_table       = mmci_ids,
 };
 
-static int __init mmci_init(void)
-{
-       return amba_driver_register(&mmci_driver);
-}
-
-static void __exit mmci_exit(void)
-{
-       amba_driver_unregister(&mmci_driver);
-}
+module_amba_driver(mmci_driver);
 
-module_init(mmci_init);
-module_exit(mmci_exit);
 module_param(fmax, uint, 0444);
 
 MODULE_DESCRIPTION("ARM PrimeCell PL180/181 Multimedia Card Interface driver");
index 79e4143ab9dfa1bbe78dbb64b46cecca670addac..d437ccf62d6bcc76a41862f68b48408f0711c5af 100644 (file)
 #define MCI_PWR_ON             0x03
 #define MCI_OD                 (1 << 6)
 #define MCI_ROD                        (1 << 7)
-/*
- * The ST Micro version does not have ROD and reuse the voltage registers
- * for direction settings
- */
-#define MCI_ST_DATA2DIREN      (1 << 2)
-#define MCI_ST_CMDDIREN                (1 << 3)
-#define MCI_ST_DATA0DIREN      (1 << 4)
-#define MCI_ST_DATA31DIREN     (1 << 5)
-#define MCI_ST_FBCLKEN         (1 << 7)
-#define MCI_ST_DATA74DIREN     (1 << 8)
 
 #define MMCICLOCK              0x004
 #define MCI_CLK_ENABLE         (1 << 8)
        (MCI_RXFIFOHALFFULLMASK | MCI_RXDATAAVLBLMASK | \
         MCI_TXFIFOHALFEMPTYMASK)
 
-#define NR_SG          16
+#define NR_SG          128
 
 struct clk;
 struct variant_data;
@@ -189,7 +179,8 @@ struct mmci_host {
 
        unsigned int            mclk;
        unsigned int            cclk;
-       u32                     pwr;
+       u32                     pwr_reg;
+       u32                     clk_reg;
        struct mmci_platform_data *plat;
        struct variant_data     *variant;
 
index a4a1e534ed42e2197be6e2b9ee2482be6c849445..22bacdbf9139dce42e82754ec9de7c061dea755e 100644 (file)
@@ -185,18 +185,7 @@ static struct amba_driver pl030_driver = {
        .id_table       = pl030_ids,
 };
 
-static int __init pl030_init(void)
-{
-       return amba_driver_register(&pl030_driver);
-}
-
-static void __exit pl030_exit(void)
-{
-       amba_driver_unregister(&pl030_driver);
-}
-
-module_init(pl030_init);
-module_exit(pl030_exit);
+module_amba_driver(pl030_driver);
 
 MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
 MODULE_DESCRIPTION("ARM AMBA PL030 RTC Driver");
index 3a470e291282862f5273d8e9eb23d6104eed7a4b..692de7360e94100dfbc28e5b1dda51d824c24b89 100644 (file)
@@ -431,18 +431,7 @@ static struct amba_driver pl031_driver = {
        .remove = pl031_remove,
 };
 
-static int __init pl031_init(void)
-{
-       return amba_driver_register(&pl031_driver);
-}
-
-static void __exit pl031_exit(void)
-{
-       amba_driver_unregister(&pl031_driver);
-}
-
-module_init(pl031_init);
-module_exit(pl031_exit);
+module_amba_driver(pl031_driver);
 
 MODULE_AUTHOR("Deepak Saxena <dsaxena@plexity.net");
 MODULE_DESCRIPTION("ARM AMBA PL031 RTC Driver");
index eef1524ae52eaeb90bed1dba3761c61ed83e1a29..3ff9e47bd2188da7fcf071a6220380c82a905d2e 100644 (file)
@@ -370,17 +370,7 @@ static struct amba_driver sp805_wdt_driver = {
        .remove = __devexit_p(sp805_wdt_remove),
 };
 
-static int __init sp805_wdt_init(void)
-{
-       return amba_driver_register(&sp805_wdt_driver);
-}
-module_init(sp805_wdt_init);
-
-static void __exit sp805_wdt_exit(void)
-{
-       amba_driver_unregister(&sp805_wdt_driver);
-}
-module_exit(sp805_wdt_exit);
+module_amba_driver(sp805_wdt_driver);
 
 module_param(nowayout, int, 0);
 MODULE_PARM_DESC(nowayout,
index a9fab831caf8fd8c3432c4805fd34ea9156daaa8..7847e197730ac86cc480092d5dd525499d106716 100644 (file)
@@ -125,4 +125,13 @@ struct amba_device name##_device = {                               \
        .periphid = id,                                         \
 }
 
+/*
+ * module_amba_driver() - Helper macro for drivers that don't do anything
+ * special in module init/exit.  This eliminates a lot of boilerplate.  Each
+ * module may only use this macro once, and calling it replaces module_init()
+ * and module_exit()
+ */
+#define module_amba_driver(__amba_drv) \
+       module_driver(__amba_drv, amba_driver_register, amba_driver_unregister)
+
 #endif
index 0101e9c17fa1ec022c75f3655646c16aca9dd948..32a89cf5ec4589b51734f6e65b91a5e9dd6ac53f 100644 (file)
@@ -6,6 +6,19 @@
 
 #include <linux/mmc/host.h>
 
+
+/*
+ * These defines is places here due to access is needed from machine
+ * configuration files. The ST Micro version does not have ROD and
+ * reuse the voltage registers for direction settings.
+ */
+#define MCI_ST_DATA2DIREN      (1 << 2)
+#define MCI_ST_CMDDIREN                (1 << 3)
+#define MCI_ST_DATA0DIREN      (1 << 4)
+#define MCI_ST_DATA31DIREN     (1 << 5)
+#define MCI_ST_FBCLKEN         (1 << 7)
+#define MCI_ST_DATA74DIREN     (1 << 8)
+
 /* Just some dummy forwarding */
 struct dma_chan;
 
@@ -18,7 +31,8 @@ struct dma_chan;
  * @ocr_mask: available voltages on the 4 pins from the block, this
  * is ignored if a regulator is used, see the MMC_VDD_* masks in
  * mmc/host.h
- * @vdd_handler: a callback function to translate a MMC_VDD_*
+ * @ios_handler: a callback function to act on specfic ios changes,
+ * used for example to control a levelshifter
  * mask into a value to be binary (or set some other custom bits
  * in MMCIPWR) or:ed and written into the MMCIPWR register of the
  * block.  May also control external power based on the power_mode.
@@ -31,6 +45,8 @@ struct dma_chan;
  * @capabilities: the capabilities of the block as implemented in
  * this platform, signify anything MMC_CAP_* from mmc/host.h
  * @capabilities2: more capabilities, MMC_CAP2_* from mmc/host.h
+ * @sigdir: a bit field indicating for what bits in the MMC bus the host
+ * should enable signal direction indication.
  * @dma_filter: function used to select an appropriate RX and TX
  * DMA channel to be used for DMA, if and only if you're deploying the
  * generic DMA engine
@@ -46,14 +62,14 @@ struct dma_chan;
 struct mmci_platform_data {
        unsigned int f_max;
        unsigned int ocr_mask;
-       u32 (*vdd_handler)(struct device *, unsigned int vdd,
-                          unsigned char power_mode);
+       int (*ios_handler)(struct device *, struct mmc_ios *);
        unsigned int (*status)(struct device *);
        int     gpio_wp;
        int     gpio_cd;
        bool    cd_invert;
        unsigned long capabilities;
        unsigned long capabilities2;
+       u32 sigdir;
        bool (*dma_filter)(struct dma_chan *chan, void *filter_param);
        void *dma_rx_param;
        void *dma_tx_param;
index b37b702a3a6a7e3ad6b906fe0a502b1172446cae..5119fdabcb98728a0d0520fd9a69c75a8fe11f6a 100644 (file)
@@ -1110,18 +1110,7 @@ static struct amba_driver aaci_driver = {
        .id_table       = aaci_ids,
 };
 
-static int __init aaci_init(void)
-{
-       return amba_driver_register(&aaci_driver);
-}
-
-static void __exit aaci_exit(void)
-{
-       amba_driver_unregister(&aaci_driver);
-}
-
-module_init(aaci_init);
-module_exit(aaci_exit);
+module_amba_driver(aaci_driver);
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("ARM PrimeCell PL041 Advanced Audio CODEC Interface driver");