]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge remote-tracking branch 'mmc-uh/next'
authorStephen Rothwell <sfr@canb.auug.org.au>
Thu, 11 Feb 2016 01:32:17 +0000 (12:32 +1100)
committerStephen Rothwell <sfr@canb.auug.org.au>
Thu, 11 Feb 2016 01:32:17 +0000 (12:32 +1100)
44 files changed:
Documentation/devicetree/bindings/mmc/brcm,sdhci-iproc.txt
Documentation/devicetree/bindings/mmc/microchip,sdhci-pic32.txt [new file with mode: 0644]
drivers/mmc/card/block.c
drivers/mmc/card/mmc_test.c
drivers/mmc/core/core.c
drivers/mmc/core/debugfs.c
drivers/mmc/core/host.c
drivers/mmc/core/mmc.c
drivers/mmc/core/mmc_ops.c
drivers/mmc/core/pwrseq_simple.c
drivers/mmc/core/sd_ops.c
drivers/mmc/core/sdio_ops.c
drivers/mmc/host/Kconfig
drivers/mmc/host/Makefile
drivers/mmc/host/atmel-mci.c
drivers/mmc/host/bfin_sdh.c
drivers/mmc/host/davinci_mmc.c
drivers/mmc/host/dw_mmc-exynos.c
drivers/mmc/host/dw_mmc-pltfm.c
drivers/mmc/host/dw_mmc-rockchip.c
drivers/mmc/host/dw_mmc.c
drivers/mmc/host/dw_mmc.h
drivers/mmc/host/jz4740_mmc.c
drivers/mmc/host/mmc_spi.c
drivers/mmc/host/mxcmmc.c
drivers/mmc/host/omap_hsmmc.c
drivers/mmc/host/pxamci.c
drivers/mmc/host/s3cmci.c
drivers/mmc/host/sdhci-acpi.c
drivers/mmc/host/sdhci-iproc.c
drivers/mmc/host/sdhci-of-arasan.c
drivers/mmc/host/sdhci-of-at91.c
drivers/mmc/host/sdhci-pic32.c [new file with mode: 0644]
drivers/mmc/host/sdricoh_cs.c
drivers/mmc/host/sh_mmcif.c
drivers/mmc/host/sh_mobile_sdhi.c
drivers/mmc/host/sunxi-mmc.c
drivers/mmc/host/tmio_mmc_dma.c
drivers/mmc/host/tmio_mmc_pio.c
drivers/mmc/host/usdhi6rol0.c
include/linux/mfd/tmio.h
include/linux/mmc/core.h
include/linux/mmc/dw_mmc.h
include/linux/mmc/tmio.h

index 72cc9cc95880ad8cd3915c8d1648c20ee0e8e363..be56d2bd474a0c309729128c97c4a3a91bc7b918 100644 (file)
@@ -4,7 +4,10 @@ This file documents differences between the core properties described
 by mmc.txt and the properties that represent the IPROC SDHCI controller.
 
 Required properties:
-- compatible : Should be "brcm,sdhci-iproc-cygnus".
+- compatible : Should be one of the following
+              "brcm,bcm2835-sdhci"
+              "brcm,sdhci-iproc-cygnus"
+
 - clocks : The clock feeding the SDHCI controller.
 
 Optional properties:
diff --git a/Documentation/devicetree/bindings/mmc/microchip,sdhci-pic32.txt b/Documentation/devicetree/bindings/mmc/microchip,sdhci-pic32.txt
new file mode 100644 (file)
index 0000000..71ad57e
--- /dev/null
@@ -0,0 +1,29 @@
+* Microchip PIC32 SDHCI Controller
+
+This file documents differences between the core properties in mmc.txt
+and the properties used by the sdhci-pic32 driver.
+
+Required properties:
+- compatible: Should be "microchip,pic32mzda-sdhci"
+- interrupts: Should contain interrupt
+- clock-names: Should be "base_clk", "sys_clk".
+               See: Documentation/devicetree/bindings/resource-names.txt
+- clocks: Phandle to the clock.
+          See: Documentation/devicetree/bindings/clock/clock-bindings.txt
+- pinctrl-names: A pinctrl state names "default" must be defined.
+- pinctrl-0: Phandle referencing pin configuration of the SDHCI controller.
+             See: Documentation/devicetree/bindings/pinctrl/pinctrl-binding.txt
+
+Example:
+
+       sdhci@1f8ec000 {
+               compatible = "microchip,pic32mzda-sdhci";
+               reg = <0x1f8ec000 0x100>;
+               interrupts = <191 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&REFCLKO4>, <&PBCLK5>;
+               clock-names = "base_clk", "sys_clk";
+               bus-width = <4>;
+               cap-sd-highspeed;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_sdhc1>;
+       };
index 5914263090fc81447e26130baab143802504c088..b3ec4fb0d344c15d550e2d85bd09d0f9d2ed97b7 100644 (file)
@@ -655,8 +655,10 @@ static int mmc_blk_ioctl_multi_cmd(struct block_device *bdev,
        }
 
        md = mmc_blk_get(bdev->bd_disk);
-       if (!md)
+       if (!md) {
+               err = -EINVAL;
                goto cmd_err;
+       }
 
        card = md->queue.card;
        if (IS_ERR(card)) {
@@ -1363,8 +1365,8 @@ static int mmc_blk_err_check(struct mmc_card *card,
 
        if (brq->data.error) {
                if (need_retune && !brq->retune_retry_done) {
-                       pr_info("%s: retrying because a re-tune was needed\n",
-                               req->rq_disk->disk_name);
+                       pr_debug("%s: retrying because a re-tune was needed\n",
+                                req->rq_disk->disk_name);
                        brq->retune_retry_done = 1;
                        return MMC_BLK_RETRY;
                }
@@ -1525,13 +1527,13 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
        }
        if (rq_data_dir(req) == READ) {
                brq->cmd.opcode = readcmd;
-               brq->data.flags |= MMC_DATA_READ;
+               brq->data.flags = MMC_DATA_READ;
                if (brq->mrq.stop)
                        brq->stop.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 |
                                        MMC_CMD_AC;
        } else {
                brq->cmd.opcode = writecmd;
-               brq->data.flags |= MMC_DATA_WRITE;
+               brq->data.flags = MMC_DATA_WRITE;
                if (brq->mrq.stop)
                        brq->stop.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B |
                                        MMC_CMD_AC;
@@ -1800,7 +1802,7 @@ static void mmc_blk_packed_hdr_wrq_prep(struct mmc_queue_req *mqrq,
 
        brq->data.blksz = 512;
        brq->data.blocks = packed->blocks + hdr_blocks;
-       brq->data.flags |= MMC_DATA_WRITE;
+       brq->data.flags = MMC_DATA_WRITE;
 
        brq->stop.opcode = MMC_STOP_TRANSMISSION;
        brq->stop.arg = 0;
index 7fc9174d46191a13c77fa4e220bb476a32dfe05e..c032eef45762c1dfb2ef810add07e1d3f980eee5 100644 (file)
@@ -2829,6 +2829,7 @@ static int mtf_testlist_show(struct seq_file *sf, void *data)
 
        mutex_lock(&mmc_test_lock);
 
+       seq_printf(sf, "0:\tRun all tests\n");
        for (i = 0; i < ARRAY_SIZE(mmc_test_cases); i++)
                seq_printf(sf, "%d:\t%s\n", i+1, mmc_test_cases[i].name);
 
index f95d41ffc766e5038059d0be82eaeb6aa4b0fe7a..41b1e761965f7459c0d8f2849f7feb2c73f2ca30 100644 (file)
@@ -1033,7 +1033,7 @@ static inline void mmc_set_ios(struct mmc_host *host)
                "width %u timing %u\n",
                 mmc_hostname(host), ios->clock, ios->bus_mode,
                 ios->power_mode, ios->chip_select, ios->vdd,
-                ios->bus_width, ios->timing);
+                1 << ios->bus_width, ios->timing);
 
        host->ops->set_ios(host, ios);
 }
@@ -1079,7 +1079,8 @@ int mmc_execute_tuning(struct mmc_card *card)
        err = host->ops->execute_tuning(host, opcode);
 
        if (err)
-               pr_err("%s: tuning execution failed\n", mmc_hostname(host));
+               pr_err("%s: tuning execution failed: %d\n",
+                       mmc_hostname(host), err);
        else
                mmc_retune_enable(host);
 
@@ -1204,8 +1205,9 @@ EXPORT_SYMBOL(mmc_vddrange_to_ocrmask);
  * @np: The device node need to be parsed.
  * @mask: mask of voltages available for MMC/SD/SDIO
  *
- * 1. Return zero on success.
- * 2. Return negative errno: voltage-range is invalid.
+ * Parse the "voltage-ranges" DT property, returning zero if it is not
+ * found, negative errno if the voltage-range specification is invalid,
+ * or one if the voltage-range is specified and successfully parsed.
  */
 int mmc_of_parse_voltage(struct device_node *np, u32 *mask)
 {
@@ -1214,8 +1216,12 @@ int mmc_of_parse_voltage(struct device_node *np, u32 *mask)
 
        voltage_ranges = of_get_property(np, "voltage-ranges", &num_ranges);
        num_ranges = num_ranges / sizeof(*voltage_ranges) / 2;
-       if (!voltage_ranges || !num_ranges) {
-               pr_info("%s: voltage-ranges unspecified\n", np->full_name);
+       if (!voltage_ranges) {
+               pr_debug("%s: voltage-ranges unspecified\n", np->full_name);
+               return 0;
+       }
+       if (!num_ranges) {
+               pr_err("%s: voltage-ranges empty\n", np->full_name);
                return -EINVAL;
        }
 
@@ -1234,7 +1240,7 @@ int mmc_of_parse_voltage(struct device_node *np, u32 *mask)
                *mask |= ocr_mask;
        }
 
-       return 0;
+       return 1;
 }
 EXPORT_SYMBOL(mmc_of_parse_voltage);
 
@@ -2532,7 +2538,7 @@ int mmc_detect_card_removed(struct mmc_host *host)
        if (!card)
                return 1;
 
-       if (host->caps & MMC_CAP_NONREMOVABLE)
+       if (!mmc_card_is_removable(host))
                return 0;
 
        ret = mmc_card_removed(card);
@@ -2570,7 +2576,7 @@ void mmc_rescan(struct work_struct *work)
                return;
 
        /* If there is a non-removable card registered, only scan once */
-       if ((host->caps & MMC_CAP_NONREMOVABLE) && host->rescan_entered)
+       if (!mmc_card_is_removable(host) && host->rescan_entered)
                return;
        host->rescan_entered = 1;
 
@@ -2587,8 +2593,7 @@ void mmc_rescan(struct work_struct *work)
         * if there is a _removable_ card registered, check whether it is
         * still present
         */
-       if (host->bus_ops && !host->bus_dead
-           && !(host->caps & MMC_CAP_NONREMOVABLE))
+       if (host->bus_ops && !host->bus_dead && mmc_card_is_removable(host))
                host->bus_ops->detect(host);
 
        host->detect_change = 0;
@@ -2613,7 +2618,7 @@ void mmc_rescan(struct work_struct *work)
        mmc_bus_put(host);
 
        mmc_claim_host(host);
-       if (!(host->caps & MMC_CAP_NONREMOVABLE) && host->ops->get_cd &&
+       if (mmc_card_is_removable(host) && host->ops->get_cd &&
                        host->ops->get_cd(host) == 0) {
                mmc_power_off(host);
                mmc_release_host(host);
index 65cc0ac9b82d2b9e1eb928131c7a1dea074f2d02..9382a57a5aa496f19c22353521fe475e1d253c91 100644 (file)
@@ -220,7 +220,7 @@ static int mmc_clock_opt_set(void *data, u64 val)
        struct mmc_host *host = data;
 
        /* We need this check due to input value is u64 */
-       if (val > host->f_max)
+       if (val != 0 && (val > host->f_max || val < host->f_min))
                return -EINVAL;
 
        mmc_claim_host(host);
index 0aecd5c00b866571a852c19c91af766591d4025e..1d94607611d888d0e409a152b4f67df6724273df 100644 (file)
@@ -339,6 +339,7 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
        host->class_dev.parent = dev;
        host->class_dev.class = &mmc_host_class;
        device_initialize(&host->class_dev);
+       device_enable_async_suspend(&host->class_dev);
 
        if (mmc_gpio_alloc(host)) {
                put_device(&host->class_dev);
index bf49e44571f20a21b88cda5c1f35a5c222cfcf32..4dbe3df8024b2cf3ed9206f8d76cff1ba660dc7e 100644 (file)
@@ -501,7 +501,7 @@ static int mmc_decode_ext_csd(struct mmc_card *card, u8 *ext_csd)
                        card->ext_csd.raw_bkops_status =
                                ext_csd[EXT_CSD_BKOPS_STATUS];
                        if (!card->ext_csd.man_bkops_en)
-                               pr_info("%s: MAN_BKOPS_EN bit is not set\n",
+                               pr_debug("%s: MAN_BKOPS_EN bit is not set\n",
                                        mmc_hostname(card->host));
                }
 
@@ -945,7 +945,7 @@ static int mmc_select_bus_width(struct mmc_card *card)
                        break;
                } else {
                        pr_warn("%s: switch to bus width %d failed\n",
-                               mmc_hostname(host), ext_csd_bits[idx]);
+                               mmc_hostname(host), 1 << bus_width);
                }
        }
 
index 2c90635c89afbb3782a48145fe830828dca4ec27..62355bda608f2ec598597df6b4be800e51eeb7c3 100644 (file)
@@ -90,7 +90,6 @@ int mmc_send_status(struct mmc_card *card, u32 *status)
 
 static int _mmc_select_card(struct mmc_host *host, struct mmc_card *card)
 {
-       int err;
        struct mmc_command cmd = {0};
 
        BUG_ON(!host);
@@ -105,11 +104,7 @@ static int _mmc_select_card(struct mmc_host *host, struct mmc_card *card)
                cmd.flags = MMC_RSP_NONE | MMC_CMD_AC;
        }
 
-       err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES);
-       if (err)
-               return err;
-
-       return 0;
+       return mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES);
 }
 
 int mmc_select_card(struct mmc_card *card)
@@ -244,7 +239,6 @@ int mmc_all_send_cid(struct mmc_host *host, u32 *cid)
 
 int mmc_set_relative_addr(struct mmc_card *card)
 {
-       int err;
        struct mmc_command cmd = {0};
 
        BUG_ON(!card);
@@ -254,11 +248,7 @@ int mmc_set_relative_addr(struct mmc_card *card)
        cmd.arg = card->rca << 16;
        cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
 
-       err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES);
-       if (err)
-               return err;
-
-       return 0;
+       return mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES);
 }
 
 static int
@@ -743,7 +733,7 @@ mmc_send_bus_test(struct mmc_card *card, struct mmc_host *host, u8 opcode,
 
 int mmc_bus_test(struct mmc_card *card, u8 bus_width)
 {
-       int err, width;
+       int width;
 
        if (bus_width == MMC_BUS_WIDTH_8)
                width = 8;
@@ -759,8 +749,7 @@ int mmc_bus_test(struct mmc_card *card, u8 bus_width)
         * is a problem.  This improves chances that the test will work.
         */
        mmc_send_bus_test(card, card->host, MMC_BUS_TEST_W, width);
-       err = mmc_send_bus_test(card, card->host, MMC_BUS_TEST_R, width);
-       return err;
+       return mmc_send_bus_test(card, card->host, MMC_BUS_TEST_R, width);
 }
 
 int mmc_send_hpi_cmd(struct mmc_card *card, u32 *status)
index aba786daebcadd9e193ffabe71e3a0124dd8ec62..bc173e18b71cd62843bf21a325b35fff7e7d82cf 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/slab.h>
 #include <linux/device.h>
 #include <linux/err.h>
-#include <linux/of_gpio.h>
 #include <linux/gpio/consumer.h>
 
 #include <linux/mmc/host.h>
index 48d0c93ba25a36590ac6e2c786c4ca923d35cde1..16b774c18e75fbc9b37c982bff30e38c18944304 100644 (file)
@@ -120,7 +120,6 @@ EXPORT_SYMBOL(mmc_wait_for_app_cmd);
 
 int mmc_app_set_bus_width(struct mmc_card *card, int width)
 {
-       int err;
        struct mmc_command cmd = {0};
 
        BUG_ON(!card);
@@ -140,11 +139,7 @@ int mmc_app_set_bus_width(struct mmc_card *card, int width)
                return -EINVAL;
        }
 
-       err = mmc_wait_for_app_cmd(card->host, card, &cmd, MMC_CMD_RETRIES);
-       if (err)
-               return err;
-
-       return 0;
+       return mmc_wait_for_app_cmd(card->host, card, &cmd, MMC_CMD_RETRIES);
 }
 
 int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)
index 62508b457c4f0c8563486f6d4d536135ddf80753..34f6e80153064a9fa963c5784cd3fbec7f7b8673 100644 (file)
@@ -217,7 +217,6 @@ int sdio_reset(struct mmc_host *host)
        else
                abort |= 0x08;
 
-       ret = mmc_io_rw_direct_host(host, 1, 0, SDIO_CCCR_ABORT, abort, NULL);
-       return ret;
+       return mmc_io_rw_direct_host(host, 1, 0, SDIO_CCCR_ABORT, abort, NULL);
 }
 
index 1526b8a10b094e88e52275e46446ff3e8b66afdf..4a35ebf5165d83d6cfdb62162c2ed9cb19961cce 100644 (file)
@@ -318,15 +318,15 @@ config MMC_SDHCI_F_SDH30
          If unsure, say N.
 
 config MMC_SDHCI_IPROC
-       tristate "SDHCI platform support for the iProc SD/MMC Controller"
-       depends on ARCH_BCM_IPROC || COMPILE_TEST
+       tristate "SDHCI support for the BCM2835 & iProc SD/MMC Controller"
+       depends on ARCH_BCM2835 || ARCH_BCM_IPROC || COMPILE_TEST
        depends on MMC_SDHCI_PLTFM
        default ARCH_BCM_IPROC
        select MMC_SDHCI_IO_ACCESSORS
        help
          This selects the iProc SD/MMC controller.
 
-         If you have an IPROC platform with SD or MMC devices,
+         If you have a BCM2835 or IPROC platform with SD or MMC devices,
          say Y or M here.
 
          If unsure, say N.
@@ -673,7 +673,7 @@ config MMC_DW_ROCKCHIP
 
 config MMC_SH_MMCIF
        tristate "SuperH Internal MMCIF support"
-       depends on MMC_BLOCK && HAS_DMA
+       depends on HAS_DMA
        depends on SUPERH || ARCH_SHMOBILE || COMPILE_TEST
        help
          This selects the MMC Host Interface controller (MMCIF).
@@ -786,3 +786,14 @@ config MMC_MTK
          If you have a machine with a integrated SD/MMC card reader, say Y or M here.
          This is needed if support for any SD/SDIO/MMC devices is required.
          If unsure, say N.
+
+config MMC_SDHCI_MICROCHIP_PIC32
+        tristate "Microchip PIC32MZDA SDHCI support"
+        depends on MMC_SDHCI && PIC32MZDA && MMC_SDHCI_PLTFM
+        help
+          This selects the Secure Digital Host Controller Interface (SDHCI)
+          for PIC32MZDA platform.
+
+          If you have a controller with this interface, say Y or M here.
+
+          If unsure, say N.
index 3595f83e89dd2caf9d56cdf6ceb875ef85ece719..af918d261ff9625d1d42146da1173031cd9917dd 100644 (file)
@@ -75,6 +75,7 @@ obj-$(CONFIG_MMC_SDHCI_BCM2835)               += sdhci-bcm2835.o
 obj-$(CONFIG_MMC_SDHCI_IPROC)          += sdhci-iproc.o
 obj-$(CONFIG_MMC_SDHCI_MSM)            += sdhci-msm.o
 obj-$(CONFIG_MMC_SDHCI_ST)             += sdhci-st.o
+obj-$(CONFIG_MMC_SDHCI_MICROCHIP_PIC32)        += sdhci-pic32.o
 
 ifeq ($(CONFIG_CB710_DEBUG),y)
        CFLAGS-cb710-mmc        += -DDEBUG
index 851ccd9ac868aa0e208cac5d48ee9d8a4eaa5be4..7f9d3de9f8700b3f1ea3767c5115dff9b43fa54e 100644 (file)
@@ -848,9 +848,7 @@ static u32 atmci_prepare_command(struct mmc_host *mmc,
                if (cmd->opcode == SD_IO_RW_EXTENDED) {
                        cmdr |= ATMCI_CMDR_SDIO_BLOCK;
                } else {
-                       if (data->flags & MMC_DATA_STREAM)
-                               cmdr |= ATMCI_CMDR_STREAM;
-                       else if (data->blocks > 1)
+                       if (data->blocks > 1)
                                cmdr |= ATMCI_CMDR_MULTI_BLOCK;
                        else
                                cmdr |= ATMCI_CMDR_BLOCK;
@@ -1371,10 +1369,7 @@ static void atmci_start_request(struct atmel_mci *host,
                host->stop_cmdr |= ATMCI_CMDR_STOP_XFER;
                if (!(data->flags & MMC_DATA_WRITE))
                        host->stop_cmdr |= ATMCI_CMDR_TRDIR_READ;
-               if (data->flags & MMC_DATA_STREAM)
-                       host->stop_cmdr |= ATMCI_CMDR_STREAM;
-               else
-                       host->stop_cmdr |= ATMCI_CMDR_MULTI_BLOCK;
+               host->stop_cmdr |= ATMCI_CMDR_MULTI_BLOCK;
        }
 
        /*
index 2b7f37e82ca94edf7c875c8cd32614675d625a54..526231e385831526c6f64f9dd8cb8d333c514de5 100644 (file)
@@ -126,9 +126,6 @@ static int sdh_setup_data(struct sdh_host *host, struct mmc_data *data)
        length = data->blksz * data->blocks;
        bfin_write_SDH_DATA_LGTH(length);
 
-       if (data->flags & MMC_DATA_STREAM)
-               data_ctl |= DTX_MODE;
-
        if (data->flags & MMC_DATA_READ)
                data_ctl |= DTX_DIR;
        /* Only supports power-of-2 block size */
index ea2a2ebc6b91320d928439518218b36a966396a3..693144e7427b1d9fefbe37c2dd936b602dab2af7 100644 (file)
@@ -346,10 +346,6 @@ static void mmc_davinci_start_command(struct mmc_davinci_host *host,
        if (cmd->data)
                cmd_reg |= MMCCMD_WDATX;
 
-       /* Setting whether stream or block transfer */
-       if (cmd->flags & MMC_DATA_STREAM)
-               cmd_reg |= MMCCMD_STRMTP;
-
        /* Setting whether data read or write */
        if (host->data_dir == DAVINCI_MMC_DATADIR_WRITE)
                cmd_reg |= MMCCMD_DTRW;
@@ -568,8 +564,7 @@ mmc_davinci_prepare_data(struct mmc_davinci_host *host, struct mmc_request *req)
                return;
        }
 
-       dev_dbg(mmc_dev(host->mmc), "%s %s, %d blocks of %d bytes\n",
-               (data->flags & MMC_DATA_STREAM) ? "stream" : "block",
+       dev_dbg(mmc_dev(host->mmc), "%s, %d blocks of %d bytes\n",
                (data->flags & MMC_DATA_WRITE) ? "write" : "read",
                data->blocks, data->blksz);
        dev_dbg(mmc_dev(host->mmc), "  DTO %d cycles + %d ns\n",
@@ -584,22 +579,18 @@ mmc_davinci_prepare_data(struct mmc_davinci_host *host, struct mmc_request *req)
        writel(data->blksz, host->base + DAVINCI_MMCBLEN);
 
        /* Configure the FIFO */
-       switch (data->flags & MMC_DATA_WRITE) {
-       case MMC_DATA_WRITE:
+       if (data->flags & MMC_DATA_WRITE) {
                host->data_dir = DAVINCI_MMC_DATADIR_WRITE;
                writel(fifo_lev | MMCFIFOCTL_FIFODIR_WR | MMCFIFOCTL_FIFORST,
                        host->base + DAVINCI_MMCFIFOCTL);
                writel(fifo_lev | MMCFIFOCTL_FIFODIR_WR,
                        host->base + DAVINCI_MMCFIFOCTL);
-               break;
-
-       default:
+       } else {
                host->data_dir = DAVINCI_MMC_DATADIR_READ;
                writel(fifo_lev | MMCFIFOCTL_FIFODIR_RD | MMCFIFOCTL_FIFORST,
                        host->base + DAVINCI_MMCFIFOCTL);
                writel(fifo_lev | MMCFIFOCTL_FIFODIR_RD,
                        host->base + DAVINCI_MMCFIFOCTL);
-               break;
        }
 
        host->buffer = NULL;
index 3a7e835a00339a3f1b4165ebc47c28c37d57fc85..8790f2afc057f3909f64b50d0bab558ea74fe53c 100644 (file)
@@ -145,6 +145,16 @@ static void dw_mci_exynos_set_clksel_timing(struct dw_mci *host, u32 timing)
                mci_writel(host, CLKSEL64, clksel);
        else
                mci_writel(host, CLKSEL, clksel);
+
+       /*
+        * Exynos4412 and Exynos5250 extends the use of CMD register with the
+        * use of bit 29 (which is reserved on standard MSHC controllers) for
+        * optionally bypassing the HOLD register for command and data. The
+        * HOLD register should be bypassed in case there is no phase shift
+        * applied on CMD/DATA that is sent to the card.
+        */
+       if (!SDMMC_CLKSEL_GET_DRV_WD3(clksel))
+               set_bit(DW_MMC_CARD_NO_USE_HOLD, &host->cur_slot->flags);
 }
 
 #ifdef CONFIG_PM_SLEEP
@@ -202,26 +212,6 @@ static int dw_mci_exynos_resume_noirq(struct device *dev)
 #define dw_mci_exynos_resume_noirq     NULL
 #endif /* CONFIG_PM_SLEEP */
 
-static void dw_mci_exynos_prepare_command(struct dw_mci *host, u32 *cmdr)
-{
-       struct dw_mci_exynos_priv_data *priv = host->priv;
-       /*
-        * Exynos4412 and Exynos5250 extends the use of CMD register with the
-        * use of bit 29 (which is reserved on standard MSHC controllers) for
-        * optionally bypassing the HOLD register for command and data. The
-        * HOLD register should be bypassed in case there is no phase shift
-        * applied on CMD/DATA that is sent to the card.
-        */
-       if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 ||
-               priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) {
-               if (SDMMC_CLKSEL_GET_DRV_WD3(mci_readl(host, CLKSEL64)))
-                       *cmdr |= SDMMC_CMD_USE_HOLD_REG;
-        } else {
-               if (SDMMC_CLKSEL_GET_DRV_WD3(mci_readl(host, CLKSEL)))
-                       *cmdr |= SDMMC_CMD_USE_HOLD_REG;
-       }
-}
-
 static void dw_mci_exynos_config_hs400(struct dw_mci *host, u32 timing)
 {
        struct dw_mci_exynos_priv_data *priv = host->priv;
@@ -500,7 +490,6 @@ static const struct dw_mci_drv_data exynos_drv_data = {
        .caps                   = exynos_dwmmc_caps,
        .init                   = dw_mci_exynos_priv_init,
        .setup_clock            = dw_mci_exynos_setup_clock,
-       .prepare_command        = dw_mci_exynos_prepare_command,
        .set_ios                = dw_mci_exynos_set_ios,
        .parse_dt               = dw_mci_exynos_parse_dt,
        .execute_tuning         = dw_mci_exynos_execute_tuning,
index 81bdeeb05a4d23426ecf39119a54d544eb8342f9..c0bb0c793e84b2744586db19a5f559f31d207cd2 100644 (file)
 #include "dw_mmc.h"
 #include "dw_mmc-pltfm.h"
 
-static void dw_mci_pltfm_prepare_command(struct dw_mci *host, u32 *cmdr)
-{
-       *cmdr |= SDMMC_CMD_USE_HOLD_REG;
-}
-
-static const struct dw_mci_drv_data socfpga_drv_data = {
-       .prepare_command        = dw_mci_pltfm_prepare_command,
-};
-
-static const struct dw_mci_drv_data pistachio_drv_data = {
-       .prepare_command        = dw_mci_pltfm_prepare_command,
-};
-
 int dw_mci_pltfm_register(struct platform_device *pdev,
                          const struct dw_mci_drv_data *drv_data)
 {
@@ -94,10 +81,8 @@ EXPORT_SYMBOL_GPL(dw_mci_pltfm_pmops);
 
 static const struct of_device_id dw_mci_pltfm_match[] = {
        { .compatible = "snps,dw-mshc", },
-       { .compatible = "altr,socfpga-dw-mshc",
-               .data = &socfpga_drv_data },
-       { .compatible = "img,pistachio-dw-mshc",
-               .data = &pistachio_drv_data },
+       { .compatible = "altr,socfpga-dw-mshc", },
+       { .compatible = "img,pistachio-dw-mshc", },
        {},
 };
 MODULE_DEVICE_TABLE(of, dw_mci_pltfm_match);
index d9c92f31da641e1c5d98e6d446f174ee61d6552a..84e50f3a64b69239b44fa11e96001fe953ed0948 100644 (file)
@@ -26,11 +26,6 @@ struct dw_mci_rockchip_priv_data {
        int                     default_sample_phase;
 };
 
-static void dw_mci_rockchip_prepare_command(struct dw_mci *host, u32 *cmdr)
-{
-       *cmdr |= SDMMC_CMD_USE_HOLD_REG;
-}
-
 static int dw_mci_rk3288_setup_clock(struct dw_mci *host)
 {
        host->bus_hz /= RK3288_CLKGEN_DIV;
@@ -240,12 +235,10 @@ static int dw_mci_rockchip_init(struct dw_mci *host)
 }
 
 static const struct dw_mci_drv_data rk2928_drv_data = {
-       .prepare_command        = dw_mci_rockchip_prepare_command,
        .init                   = dw_mci_rockchip_init,
 };
 
 static const struct dw_mci_drv_data rk3288_drv_data = {
-       .prepare_command        = dw_mci_rockchip_prepare_command,
        .set_ios                = dw_mci_rk3288_set_ios,
        .execute_tuning         = dw_mci_rk3288_execute_tuning,
        .parse_dt               = dw_mci_rk3288_parse_dt,
index 712835177e8b7ef0b49ff59155be3fef2bf5c678..242f9a0769bd5ef7edf0f6c245597e8dc2a85aa5 100644 (file)
@@ -234,7 +234,6 @@ static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd)
        struct mmc_data *data;
        struct dw_mci_slot *slot = mmc_priv(mmc);
        struct dw_mci *host = slot->host;
-       const struct dw_mci_drv_data *drv_data = slot->host->drv_data;
        u32 cmdr;
 
        cmd->error = -EINPROGRESS;
@@ -290,14 +289,12 @@ static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd)
        data = cmd->data;
        if (data) {
                cmdr |= SDMMC_CMD_DAT_EXP;
-               if (data->flags & MMC_DATA_STREAM)
-                       cmdr |= SDMMC_CMD_STRM_MODE;
                if (data->flags & MMC_DATA_WRITE)
                        cmdr |= SDMMC_CMD_DAT_WR;
        }
 
-       if (drv_data && drv_data->prepare_command)
-               drv_data->prepare_command(slot->host, &cmdr);
+       if (!test_bit(DW_MMC_CARD_NO_USE_HOLD, &slot->flags))
+               cmdr |= SDMMC_CMD_USE_HOLD_REG;
 
        return cmdr;
 }
@@ -1450,12 +1447,11 @@ static int dw_mci_get_cd(struct mmc_host *mmc)
 {
        int present;
        struct dw_mci_slot *slot = mmc_priv(mmc);
-       struct dw_mci_board *brd = slot->host->pdata;
        struct dw_mci *host = slot->host;
        int gpio_cd = mmc_gpio_get_cd(mmc);
 
        /* Use platform get_cd function, else try onboard card detect */
-       if ((brd->quirks & DW_MCI_QUIRK_BROKEN_CARD_DETECTION) ||
+       if ((mmc->caps & MMC_CAP_NEEDS_POLL) ||
            (mmc->caps & MMC_CAP_NONREMOVABLE))
                present = 1;
        else if (!IS_ERR_VALUE(gpio_cd))
@@ -1477,6 +1473,34 @@ static int dw_mci_get_cd(struct mmc_host *mmc)
        return present;
 }
 
+static void dw_mci_hw_reset(struct mmc_host *mmc)
+{
+       struct dw_mci_slot *slot = mmc_priv(mmc);
+       struct dw_mci *host = slot->host;
+       int reset;
+
+       if (host->use_dma == TRANS_MODE_IDMAC)
+               dw_mci_idmac_reset(host);
+
+       if (!dw_mci_ctrl_reset(host, SDMMC_CTRL_DMA_RESET |
+                                    SDMMC_CTRL_FIFO_RESET))
+               return;
+
+       /*
+        * According to eMMC spec, card reset procedure:
+        * tRstW >= 1us:   RST_n pulse width
+        * tRSCA >= 200us: RST_n to Command time
+        * tRSTH >= 1us:   RST_n high period
+        */
+       reset = mci_readl(host, RST_N);
+       reset &= ~(SDMMC_RST_HWACTIVE << slot->id);
+       mci_writel(host, RST_N, reset);
+       usleep_range(1, 2);
+       reset |= SDMMC_RST_HWACTIVE << slot->id;
+       mci_writel(host, RST_N, reset);
+       usleep_range(200, 300);
+}
+
 static void dw_mci_init_card(struct mmc_host *mmc, struct mmc_card *card)
 {
        struct dw_mci_slot *slot = mmc_priv(mmc);
@@ -1563,6 +1587,7 @@ static const struct mmc_host_ops dw_mci_ops = {
        .set_ios                = dw_mci_set_ios,
        .get_ro                 = dw_mci_get_ro,
        .get_cd                 = dw_mci_get_cd,
+       .hw_reset               = dw_mci_hw_reset,
        .enable_sdio_irq        = dw_mci_enable_sdio_irq,
        .execute_tuning         = dw_mci_execute_tuning,
        .card_busy              = dw_mci_card_busy,
@@ -2840,23 +2865,13 @@ static void dw_mci_dto_timer(unsigned long arg)
 }
 
 #ifdef CONFIG_OF
-static struct dw_mci_of_quirks {
-       char *quirk;
-       int id;
-} of_quirks[] = {
-       {
-               .quirk  = "broken-cd",
-               .id     = DW_MCI_QUIRK_BROKEN_CARD_DETECTION,
-       },
-};
-
 static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host)
 {
        struct dw_mci_board *pdata;
        struct device *dev = host->dev;
        struct device_node *np = dev->of_node;
        const struct dw_mci_drv_data *drv_data = host->drv_data;
-       int idx, ret;
+       int ret;
        u32 clock_frequency;
 
        pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
@@ -2864,17 +2879,7 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host)
                return ERR_PTR(-ENOMEM);
 
        /* find out number of slots supported */
-       if (of_property_read_u32(dev->of_node, "num-slots",
-                               &pdata->num_slots)) {
-               dev_info(dev,
-                        "num-slots property not found, assuming 1 slot is available\n");
-               pdata->num_slots = 1;
-       }
-
-       /* get quirks */
-       for (idx = 0; idx < ARRAY_SIZE(of_quirks); idx++)
-               if (of_get_property(np, of_quirks[idx].quirk, NULL))
-                       pdata->quirks |= of_quirks[idx].id;
+       of_property_read_u32(np, "num-slots", &pdata->num_slots);
 
        if (of_property_read_u32(np, "fifo-depth", &pdata->fifo_depth))
                dev_info(dev,
@@ -2908,18 +2913,19 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host)
 
 static void dw_mci_enable_cd(struct dw_mci *host)
 {
-       struct dw_mci_board *brd = host->pdata;
        unsigned long irqflags;
        u32 temp;
        int i;
+       struct dw_mci_slot *slot;
 
-       /* No need for CD if broken card detection */
-       if (brd->quirks & DW_MCI_QUIRK_BROKEN_CARD_DETECTION)
-               return;
-
-       /* No need for CD if all slots have a non-error GPIO */
+       /*
+        * No need for CD if all slots have a non-error GPIO
+        * as well as broken card detection is found.
+        */
        for (i = 0; i < host->num_slots; i++) {
-               struct dw_mci_slot *slot = host->slot[i];
+               slot = host->slot[i];
+               if (slot->mmc->caps & MMC_CAP_NEEDS_POLL)
+                       return;
 
                if (IS_ERR_VALUE(mmc_gpio_get_cd(slot->mmc)))
                        break;
@@ -2949,12 +2955,6 @@ int dw_mci_probe(struct dw_mci *host)
                }
        }
 
-       if (host->pdata->num_slots < 1) {
-               dev_err(host->dev,
-                       "Platform data must supply num_slots.\n");
-               return -ENODEV;
-       }
-
        host->biu_clk = devm_clk_get(host->dev, "biu");
        if (IS_ERR(host->biu_clk)) {
                dev_dbg(host->dev, "biu clock not available\n");
@@ -3052,8 +3052,10 @@ int dw_mci_probe(struct dw_mci *host)
        }
 
        /* Reset all blocks */
-       if (!dw_mci_ctrl_reset(host, SDMMC_CTRL_ALL_RESET_FLAGS))
-               return -ENODEV;
+       if (!dw_mci_ctrl_reset(host, SDMMC_CTRL_ALL_RESET_FLAGS)) {
+               ret = -ENODEV;
+               goto err_clk_ciu;
+       }
 
        host->dma_ops = host->pdata->dma_ops;
        dw_mci_init_dma(host);
@@ -3111,13 +3113,20 @@ int dw_mci_probe(struct dw_mci *host)
        if (host->pdata->num_slots)
                host->num_slots = host->pdata->num_slots;
        else
-               host->num_slots = SDMMC_GET_SLOT_NUM(mci_readl(host, HCON));
+               host->num_slots = 1;
+
+       if (host->num_slots < 1 ||
+           host->num_slots > SDMMC_GET_SLOT_NUM(mci_readl(host, HCON))) {
+               dev_err(host->dev,
+                       "Platform data must supply correct num_slots.\n");
+               ret = -ENODEV;
+               goto err_clk_ciu;
+       }
 
        /*
         * Enable interrupts for command done, data over, data empty,
         * receive ready and error such as transmit, receive timeout, crc error
         */
-       mci_writel(host, RINTSTS, 0xFFFFFFFF);
        mci_writel(host, INTMASK, SDMMC_INT_CMD_DONE | SDMMC_INT_DATA_OVER |
                   SDMMC_INT_TXDR | SDMMC_INT_RXDR |
                   DW_MCI_ERROR_FLAGS);
index f695b58f06135868ce934cae1e322899f3dc6545..68d5da2dfd191f5799f7af985534e00068f7116e 100644 (file)
@@ -46,6 +46,7 @@
 #define SDMMC_VERID            0x06c
 #define SDMMC_HCON             0x070
 #define SDMMC_UHS_REG          0x074
+#define SDMMC_RST_N            0x078
 #define SDMMC_BMOD             0x080
 #define SDMMC_PLDMND           0x084
 #define SDMMC_DBADDR           0x088
 #define SDMMC_IDMAC_ENABLE             BIT(7)
 #define SDMMC_IDMAC_FB                 BIT(1)
 #define SDMMC_IDMAC_SWRESET            BIT(0)
+/* H/W reset */
+#define SDMMC_RST_HWACTIVE             0x1
 /* Version ID register define */
 #define SDMMC_GET_VERID(x)             ((x) & 0xFFFF)
 /* Card read threshold */
@@ -265,6 +268,7 @@ struct dw_mci_slot {
 #define DW_MMC_CARD_PRESENT    0
 #define DW_MMC_CARD_NEED_INIT  1
 #define DW_MMC_CARD_NO_LOW_PWR 2
+#define DW_MMC_CARD_NO_USE_HOLD 3
        int                     id;
        int                     sdio_id;
 };
@@ -274,7 +278,6 @@ struct dw_mci_slot {
  * @caps: mmc subsystem specified capabilities of the controller(s).
  * @init: early implementation specific initialization.
  * @setup_clock: implementation specific clock configuration.
- * @prepare_command: handle CMD register extensions.
  * @set_ios: handle bus specific extensions.
  * @parse_dt: parse implementation specific device tree properties.
  * @execute_tuning: implementation specific tuning procedure.
@@ -287,7 +290,6 @@ struct dw_mci_drv_data {
        unsigned long   *caps;
        int             (*init)(struct dw_mci *host);
        int             (*setup_clock)(struct dw_mci *host);
-       void            (*prepare_command)(struct dw_mci *host, u32 *cmdr);
        void            (*set_ios)(struct dw_mci *host, struct mmc_ios *ios);
        int             (*parse_dt)(struct dw_mci *host);
        int             (*execute_tuning)(struct dw_mci_slot *slot, u32 opcode);
index 76e8bce6f46e7015bb6ae9e3dfe082d2cf58db35..03ddf0ecf4023c8ab09b9e516640626659eb1ae5 100644 (file)
@@ -660,8 +660,6 @@ static void jz4740_mmc_send_command(struct jz4740_mmc_host *host,
                cmdat |= JZ_MMC_CMDAT_DATA_EN;
                if (cmd->data->flags & MMC_DATA_WRITE)
                        cmdat |= JZ_MMC_CMDAT_WRITE;
-               if (cmd->data->flags & MMC_DATA_STREAM)
-                       cmdat |= JZ_MMC_CMDAT_STREAM;
                if (host->use_dma)
                        cmdat |= JZ_MMC_CMDAT_DMA_EN;
 
index 1c1b45ef3faf847d4087d61904ed18c1a6f7ce5e..3446097a43c01ca6cf7f8e163cc75dbbb3911f3f 100644 (file)
@@ -925,6 +925,10 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd,
 
                        dma_addr = dma_map_page(dma_dev, sg_page(sg), 0,
                                                PAGE_SIZE, dir);
+                       if (dma_mapping_error(dma_dev, dma_addr)) {
+                               data->error = -EFAULT;
+                               break;
+                       }
                        if (direction == DMA_TO_DEVICE)
                                t->tx_dma = dma_addr + sg->offset;
                        else
@@ -1393,10 +1397,12 @@ static int mmc_spi_probe(struct spi_device *spi)
                host->dma_dev = dev;
                host->ones_dma = dma_map_single(dev, ones,
                                MMC_SPI_BLOCKSIZE, DMA_TO_DEVICE);
+               if (dma_mapping_error(dev, host->ones_dma))
+                       goto fail_ones_dma;
                host->data_dma = dma_map_single(dev, host->data,
                                sizeof(*host->data), DMA_BIDIRECTIONAL);
-
-               /* REVISIT in theory those map operations can fail... */
+               if (dma_mapping_error(dev, host->data_dma))
+                       goto fail_data_dma;
 
                dma_sync_single_for_cpu(host->dma_dev,
                                host->data_dma, sizeof(*host->data),
@@ -1462,6 +1468,11 @@ fail_glue_init:
        if (host->dma_dev)
                dma_unmap_single(host->dma_dev, host->data_dma,
                                sizeof(*host->data), DMA_BIDIRECTIONAL);
+fail_data_dma:
+       if (host->dma_dev)
+               dma_unmap_single(host->dma_dev, host->ones_dma,
+                               MMC_SPI_BLOCKSIZE, DMA_TO_DEVICE);
+fail_ones_dma:
        kfree(host->data);
 
 fail_nobuf1:
index d110f9e98c4b45cc587378f740988acc2b3b3cfa..3d1ea5e0e54952821f730cc26e89a3aeeecb0c78 100644 (file)
@@ -307,9 +307,6 @@ static int mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data)
        enum dma_transfer_direction slave_dirn;
        int i, nents;
 
-       if (data->flags & MMC_DATA_STREAM)
-               nob = 0xffff;
-
        host->data = data;
        data->bytes_xfered = 0;
 
index b6639ea0bf18dbd37ccf0d639073119353b418b6..43097a76399cde95a813f7aa6ffb6a4dc275ca07 100644 (file)
@@ -503,8 +503,11 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host)
        host->pbias = devm_regulator_get_optional(host->dev, "pbias");
        if (IS_ERR(host->pbias)) {
                ret = PTR_ERR(host->pbias);
-               if ((ret != -ENODEV) && host->dev->of_node)
+               if ((ret != -ENODEV) && host->dev->of_node) {
+                       dev_err(host->dev,
+                       "SD card detect fail? enable CONFIG_REGULATOR_PBIAS\n");
                        return ret;
+               }
                dev_dbg(host->dev, "unable to get pbias regulator %ld\n",
                        PTR_ERR(host->pbias));
                host->pbias = NULL;
@@ -2159,7 +2162,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
                                                 &rx_req, &pdev->dev, "rx");
 
        if (!host->rx_chan) {
-               dev_err(mmc_dev(host->mmc), "unable to obtain RX DMA engine channel %u\n", rx_req);
+               dev_err(mmc_dev(host->mmc), "unable to obtain RX DMA engine channel\n");
                ret = -ENXIO;
                goto err_irq;
        }
@@ -2169,7 +2172,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
                                                 &tx_req, &pdev->dev, "tx");
 
        if (!host->tx_chan) {
-               dev_err(mmc_dev(host->mmc), "unable to obtain TX DMA engine channel %u\n", tx_req);
+               dev_err(mmc_dev(host->mmc), "unable to obtain TX DMA engine channel\n");
                ret = -ENXIO;
                goto err_irq;
        }
index ce08896b9d696b00440fe7807aeddf72b922f320..86fac3e8683378acde59d1da87a0fad3878bf481 100644 (file)
@@ -86,7 +86,7 @@ struct pxamci_host {
 static inline void pxamci_init_ocr(struct pxamci_host *host)
 {
 #ifdef CONFIG_REGULATOR
-       host->vcc = regulator_get_optional(mmc_dev(host->mmc), "vmmc");
+       host->vcc = devm_regulator_get_optional(mmc_dev(host->mmc), "vmmc");
 
        if (IS_ERR(host->vcc))
                host->vcc = NULL;
@@ -191,9 +191,6 @@ static void pxamci_setup_data(struct pxamci_host *host, struct mmc_data *data)
 
        host->data = data;
 
-       if (data->flags & MMC_DATA_STREAM)
-               nob = 0xffff;
-
        writel(nob, host->base + MMC_NOB);
        writel(data->blksz, host->base + MMC_BLKLEN);
 
@@ -443,9 +440,6 @@ static void pxamci_request(struct mmc_host *mmc, struct mmc_request *mrq)
                cmdat |= CMDAT_DATAEN | CMDAT_DMAEN;
                if (mrq->data->flags & MMC_DATA_WRITE)
                        cmdat |= CMDAT_WRITE;
-
-               if (mrq->data->flags & MMC_DATA_STREAM)
-                       cmdat |= CMDAT_STREAM;
        }
 
        pxamci_start_cmd(host, mrq->cmd, cmdat);
@@ -654,12 +648,8 @@ static int pxamci_probe(struct platform_device *pdev)
 
        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        irq = platform_get_irq(pdev, 0);
-       if (!r || irq < 0)
-               return -ENXIO;
-
-       r = request_mem_region(r->start, SZ_4K, DRIVER_NAME);
-       if (!r)
-               return -EBUSY;
+       if (irq < 0)
+               return irq;
 
        mmc = mmc_alloc_host(sizeof(struct pxamci_host), &pdev->dev);
        if (!mmc) {
@@ -695,7 +685,7 @@ static int pxamci_probe(struct platform_device *pdev)
        host->pdata = pdev->dev.platform_data;
        host->clkrt = CLKRT_OFF;
 
-       host->clk = clk_get(&pdev->dev, NULL);
+       host->clk = devm_clk_get(&pdev->dev, NULL);
        if (IS_ERR(host->clk)) {
                ret = PTR_ERR(host->clk);
                host->clk = NULL;
@@ -727,9 +717,9 @@ static int pxamci_probe(struct platform_device *pdev)
        host->irq = irq;
        host->imask = MMC_I_MASK_ALL;
 
-       host->base = ioremap(r->start, SZ_4K);
-       if (!host->base) {
-               ret = -ENOMEM;
+       host->base = devm_ioremap_resource(&pdev->dev, r);
+       if (IS_ERR(host->base)) {
+               ret = PTR_ERR(host->base);
                goto out;
        }
 
@@ -742,7 +732,8 @@ static int pxamci_probe(struct platform_device *pdev)
        writel(64, host->base + MMC_RESTO);
        writel(host->imask, host->base + MMC_I_MASK);
 
-       ret = request_irq(host->irq, pxamci_irq, 0, DRIVER_NAME, host);
+       ret = devm_request_irq(&pdev->dev, host->irq, pxamci_irq, 0,
+                              DRIVER_NAME, host);
        if (ret)
                goto out;
 
@@ -804,7 +795,7 @@ static int pxamci_probe(struct platform_device *pdev)
                dev_err(&pdev->dev, "Failed requesting gpio_ro %d\n", gpio_ro);
                goto out;
        } else {
-               mmc->caps |= host->pdata->gpio_card_ro_invert ?
+               mmc->caps2 |= host->pdata->gpio_card_ro_invert ?
                        0 : MMC_CAP2_RO_ACTIVE_HIGH;
        }
 
@@ -833,14 +824,9 @@ out:
                        dma_release_channel(host->dma_chan_rx);
                if (host->dma_chan_tx)
                        dma_release_channel(host->dma_chan_tx);
-               if (host->base)
-                       iounmap(host->base);
-               if (host->clk)
-                       clk_put(host->clk);
        }
        if (mmc)
                mmc_free_host(mmc);
-       release_resource(r);
        return ret;
 }
 
@@ -859,9 +845,6 @@ static int pxamci_remove(struct platform_device *pdev)
                        gpio_ro = host->pdata->gpio_card_ro;
                        gpio_power = host->pdata->gpio_power;
                }
-               if (host->vcc)
-                       regulator_put(host->vcc);
-
                if (host->pdata && host->pdata->exit)
                        host->pdata->exit(&pdev->dev, mmc);
 
@@ -870,16 +853,10 @@ static int pxamci_remove(struct platform_device *pdev)
                       END_CMD_RES|PRG_DONE|DATA_TRAN_DONE,
                       host->base + MMC_I_MASK);
 
-               free_irq(host->irq, host);
                dmaengine_terminate_all(host->dma_chan_rx);
                dmaengine_terminate_all(host->dma_chan_tx);
                dma_release_channel(host->dma_chan_rx);
                dma_release_channel(host->dma_chan_tx);
-               iounmap(host->base);
-
-               clk_put(host->clk);
-
-               release_resource(host->res);
 
                mmc_free_host(mmc);
        }
index 6291d5042ef2a5004212b1b14aff0d5a2f4c8613..39814f3dc96f652c46fb4abec59a8dc25503de51 100644 (file)
@@ -1014,8 +1014,7 @@ static int s3cmci_setup_data(struct s3cmci_host *host, struct mmc_data *data)
        if (host->bus_width == MMC_BUS_WIDTH_4)
                dcon |= S3C2410_SDIDCON_WIDEBUS;
 
-       if (!(data->flags & MMC_DATA_STREAM))
-               dcon |= S3C2410_SDIDCON_BLOCKMODE;
+       dcon |= S3C2410_SDIDCON_BLOCKMODE;
 
        if (data->flags & MMC_DATA_WRITE) {
                dcon |= S3C2410_SDIDCON_TXAFTERRESP;
index f6047fc9406204d6ee672b74544d0ec6866308cd..3d27f2de0054a51bf2e91e890df7ebaddc08dcd0 100644 (file)
@@ -388,6 +388,8 @@ static int sdhci_acpi_probe(struct platform_device *pdev)
                pm_runtime_enable(dev);
        }
 
+       device_enable_async_suspend(dev);
+
        return 0;
 
 err_free:
index 3b423b0ad8e7a2ce0d3c9c5a85aee92b42a54143..1110f73b08aa6334b931373e402896a038df8c0a 100644 (file)
@@ -26,6 +26,7 @@ struct sdhci_iproc_data {
        const struct sdhci_pltfm_data *pdata;
        u32 caps;
        u32 caps1;
+       u32 mmc_caps;
 };
 
 struct sdhci_iproc_host {
@@ -165,9 +166,25 @@ static const struct sdhci_iproc_data iproc_data = {
        .pdata = &sdhci_iproc_pltfm_data,
        .caps = 0x05E90000,
        .caps1 = 0x00000064,
+       .mmc_caps = MMC_CAP_1_8V_DDR,
+};
+
+static const struct sdhci_pltfm_data sdhci_bcm2835_pltfm_data = {
+       .quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION |
+                 SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
+                 SDHCI_QUIRK_MISSING_CAPS,
+       .ops = &sdhci_iproc_ops,
+};
+
+static const struct sdhci_iproc_data bcm2835_data = {
+       .pdata = &sdhci_bcm2835_pltfm_data,
+       .caps = SDHCI_CAN_VDD_330,
+       .caps1 = 0x00000000,
+       .mmc_caps = 0x00000000,
 };
 
 static const struct of_device_id sdhci_iproc_of_match[] = {
+       { .compatible = "brcm,bcm2835-sdhci", .data = &bcm2835_data },
        { .compatible = "brcm,sdhci-iproc-cygnus", .data = &iproc_data },
        { }
 };
@@ -199,32 +216,37 @@ static int sdhci_iproc_probe(struct platform_device *pdev)
        mmc_of_parse(host->mmc);
        sdhci_get_of_property(pdev);
 
-       /* Enable EMMC 1/8V DDR capable */
-       host->mmc->caps |= MMC_CAP_1_8V_DDR;
+       host->mmc->caps |= iproc_host->data->mmc_caps;
 
        pltfm_host->clk = devm_clk_get(&pdev->dev, NULL);
        if (IS_ERR(pltfm_host->clk)) {
                ret = PTR_ERR(pltfm_host->clk);
                goto err;
        }
+       ret = clk_prepare_enable(pltfm_host->clk);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to enable host clk\n");
+               goto err;
+       }
 
        if (iproc_host->data->pdata->quirks & SDHCI_QUIRK_MISSING_CAPS) {
                host->caps = iproc_host->data->caps;
                host->caps1 = iproc_host->data->caps1;
        }
 
-       return sdhci_add_host(host);
+       ret = sdhci_add_host(host);
+       if (ret)
+               goto err_clk;
+
+       return 0;
 
+err_clk:
+       clk_disable_unprepare(pltfm_host->clk);
 err:
        sdhci_pltfm_free(pdev);
        return ret;
 }
 
-static int sdhci_iproc_remove(struct platform_device *pdev)
-{
-       return sdhci_pltfm_unregister(pdev);
-}
-
 static struct platform_driver sdhci_iproc_driver = {
        .driver = {
                .name = "sdhci-iproc",
@@ -232,7 +254,7 @@ static struct platform_driver sdhci_iproc_driver = {
                .pm = SDHCI_PLTFM_PMOPS,
        },
        .probe = sdhci_iproc_probe,
-       .remove = sdhci_iproc_remove,
+       .remove = sdhci_pltfm_unregister,
 };
 module_platform_driver(sdhci_iproc_driver);
 
index 75379cb0fb354e7aa7749852ced8fca5973d435e..5d9fdb353446f2792f391281dd6fb1f0a0c22f42 100644 (file)
@@ -172,11 +172,6 @@ static int sdhci_arasan_probe(struct platform_device *pdev)
                goto clk_disable_all;
        }
 
-       if (of_device_is_compatible(pdev->dev.of_node, "arasan,sdhci-4.9a")) {
-               host->quirks |= SDHCI_QUIRK_NO_HISPD_BIT;
-               host->quirks2 |= SDHCI_QUIRK2_HOST_NO_CMD23;
-       }
-
        sdhci_get_of_property(pdev);
        pltfm_host = sdhci_priv(host);
        pltfm_host->priv = sdhci_arasan;
index 7e7d8f0c9438fe4ac41bfb1f1759ff4fde776089..9cb86fb25976f380530fe0029015bdfaf408d743 100644 (file)
@@ -217,6 +217,7 @@ static int sdhci_at91_probe(struct platform_device *pdev)
 pm_runtime_disable:
        pm_runtime_disable(&pdev->dev);
        pm_runtime_set_suspended(&pdev->dev);
+       pm_runtime_put_noidle(&pdev->dev);
 clocks_disable_unprepare:
        clk_disable_unprepare(priv->gck);
        clk_disable_unprepare(priv->mainck);
diff --git a/drivers/mmc/host/sdhci-pic32.c b/drivers/mmc/host/sdhci-pic32.c
new file mode 100644 (file)
index 0000000..059df70
--- /dev/null
@@ -0,0 +1,257 @@
+/*
+ * Support of SDHCI platform devices for Microchip PIC32.
+ *
+ * Copyright (C) 2015 Microchip
+ * Andrei Pistirica, Paul Thacker
+ *
+ * Inspired by sdhci-pltfm.c
+ *
+ * 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/clk.h>
+#include <linux/delay.h>
+#include <linux/highmem.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/slab.h>
+#include <linux/mmc/host.h>
+#include <linux/io.h>
+#include "sdhci.h"
+#include "sdhci-pltfm.h"
+#include <linux/platform_data/sdhci-pic32.h>
+
+#define SDH_SHARED_BUS_CTRL            0x000000E0
+#define SDH_SHARED_BUS_NR_CLK_PINS_MASK        0x7
+#define SDH_SHARED_BUS_NR_IRQ_PINS_MASK        0x30
+#define SDH_SHARED_BUS_CLK_PINS                0x10
+#define SDH_SHARED_BUS_IRQ_PINS                0x14
+#define SDH_CAPS_SDH_SLOT_TYPE_MASK    0xC0000000
+#define SDH_SLOT_TYPE_REMOVABLE                0x0
+#define SDH_SLOT_TYPE_EMBEDDED         0x1
+#define SDH_SLOT_TYPE_SHARED_BUS       0x2
+#define SDHCI_CTRL_CDSSEL              0x80
+#define SDHCI_CTRL_CDTLVL              0x40
+
+#define ADMA_FIFO_RD_THSHLD    512
+#define ADMA_FIFO_WR_THSHLD    512
+
+struct pic32_sdhci_priv {
+       struct platform_device  *pdev;
+       struct clk *sys_clk;
+       struct clk *base_clk;
+};
+
+static unsigned int pic32_sdhci_get_max_clock(struct sdhci_host *host)
+{
+       struct pic32_sdhci_priv *sdhci_pdata = sdhci_priv(host);
+
+       return clk_get_rate(sdhci_pdata->base_clk);
+}
+
+static void pic32_sdhci_set_bus_width(struct sdhci_host *host, int width)
+{
+       u8 ctrl;
+
+       ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
+       if (width == MMC_BUS_WIDTH_8) {
+               ctrl &= ~SDHCI_CTRL_4BITBUS;
+               if (host->version >= SDHCI_SPEC_300)
+                       ctrl |= SDHCI_CTRL_8BITBUS;
+       } else {
+               if (host->version >= SDHCI_SPEC_300)
+                       ctrl &= ~SDHCI_CTRL_8BITBUS;
+               if (width == MMC_BUS_WIDTH_4)
+                       ctrl |= SDHCI_CTRL_4BITBUS;
+               else
+                       ctrl &= ~SDHCI_CTRL_4BITBUS;
+       }
+
+       /* CD select and test bits must be set for errata workaround. */
+       ctrl &= ~SDHCI_CTRL_CDTLVL;
+       ctrl |= SDHCI_CTRL_CDSSEL;
+       sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
+}
+
+static unsigned int pic32_sdhci_get_ro(struct sdhci_host *host)
+{
+       /*
+        * The SDHCI_WRITE_PROTECT bit is unstable on current hardware so we
+        * can't depend on its value in any way.
+        */
+       return 0;
+}
+
+static const struct sdhci_ops pic32_sdhci_ops = {
+       .get_max_clock = pic32_sdhci_get_max_clock,
+       .set_clock = sdhci_set_clock,
+       .set_bus_width = pic32_sdhci_set_bus_width,
+       .reset = sdhci_reset,
+       .set_uhs_signaling = sdhci_set_uhs_signaling,
+       .get_ro = pic32_sdhci_get_ro,
+};
+
+static struct sdhci_pltfm_data sdhci_pic32_pdata = {
+       .ops = &pic32_sdhci_ops,
+       .quirks = SDHCI_QUIRK_NO_HISPD_BIT,
+       .quirks2 = SDHCI_QUIRK2_NO_1_8_V,
+};
+
+static void pic32_sdhci_shared_bus(struct platform_device *pdev)
+{
+       struct sdhci_host *host = platform_get_drvdata(pdev);
+       u32 bus = readl(host->ioaddr + SDH_SHARED_BUS_CTRL);
+       u32 clk_pins = (bus & SDH_SHARED_BUS_NR_CLK_PINS_MASK) >> 0;
+       u32 irq_pins = (bus & SDH_SHARED_BUS_NR_IRQ_PINS_MASK) >> 4;
+
+       /* select first clock */
+       if (clk_pins & 1)
+               bus |= (1 << SDH_SHARED_BUS_CLK_PINS);
+
+       /* select first interrupt */
+       if (irq_pins & 1)
+               bus |= (1 << SDH_SHARED_BUS_IRQ_PINS);
+
+       writel(bus, host->ioaddr + SDH_SHARED_BUS_CTRL);
+}
+
+static int pic32_sdhci_probe_platform(struct platform_device *pdev,
+                                     struct pic32_sdhci_priv *pdata)
+{
+       int ret = 0;
+       u32 caps_slot_type;
+       struct sdhci_host *host = platform_get_drvdata(pdev);
+
+       /* Check card slot connected on shared bus. */
+       host->caps = readl(host->ioaddr + SDHCI_CAPABILITIES);
+       caps_slot_type = (host->caps & SDH_CAPS_SDH_SLOT_TYPE_MASK) >> 30;
+       if (caps_slot_type == SDH_SLOT_TYPE_SHARED_BUS)
+               pic32_sdhci_shared_bus(pdev);
+
+       return ret;
+}
+
+static int pic32_sdhci_probe(struct platform_device *pdev)
+{
+       struct sdhci_host *host;
+       struct sdhci_pltfm_host *pltfm_host;
+       struct pic32_sdhci_priv *sdhci_pdata;
+       struct pic32_sdhci_platform_data *plat_data;
+       int ret;
+
+       host = sdhci_pltfm_init(pdev, &sdhci_pic32_pdata,
+                               sizeof(struct pic32_sdhci_priv));
+       if (IS_ERR(host)) {
+               ret = PTR_ERR(host);
+               goto err;
+       }
+
+       pltfm_host = sdhci_priv(host);
+       sdhci_pdata = sdhci_pltfm_priv(pltfm_host);
+
+       plat_data = pdev->dev.platform_data;
+       if (plat_data && plat_data->setup_dma) {
+               ret = plat_data->setup_dma(ADMA_FIFO_RD_THSHLD,
+                                          ADMA_FIFO_WR_THSHLD);
+               if (ret)
+                       goto err_host;
+       }
+
+       sdhci_pdata->sys_clk = devm_clk_get(&pdev->dev, "sys_clk");
+       if (IS_ERR(sdhci_pdata->sys_clk)) {
+               ret = PTR_ERR(sdhci_pdata->sys_clk);
+               dev_err(&pdev->dev, "Error getting clock\n");
+               goto err_host;
+       }
+
+       ret = clk_prepare_enable(sdhci_pdata->sys_clk);
+       if (ret) {
+               dev_err(&pdev->dev, "Error enabling clock\n");
+               goto err_host;
+       }
+
+       sdhci_pdata->base_clk = devm_clk_get(&pdev->dev, "base_clk");
+       if (IS_ERR(sdhci_pdata->base_clk)) {
+               ret = PTR_ERR(sdhci_pdata->base_clk);
+               dev_err(&pdev->dev, "Error getting clock\n");
+               goto err_sys_clk;
+       }
+
+       ret = clk_prepare_enable(sdhci_pdata->base_clk);
+       if (ret) {
+               dev_err(&pdev->dev, "Error enabling clock\n");
+               goto err_base_clk;
+       }
+
+       ret = mmc_of_parse(host->mmc);
+       if (ret)
+               goto err_base_clk;
+
+       ret = pic32_sdhci_probe_platform(pdev, sdhci_pdata);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to probe platform!\n");
+               goto err_base_clk;
+       }
+
+       ret = sdhci_add_host(host);
+       if (ret) {
+               dev_err(&pdev->dev, "error adding host\n");
+               goto err_base_clk;
+       }
+
+       dev_info(&pdev->dev, "Successfully added sdhci host\n");
+       return 0;
+
+err_base_clk:
+       clk_disable_unprepare(sdhci_pdata->base_clk);
+err_sys_clk:
+       clk_disable_unprepare(sdhci_pdata->sys_clk);
+err_host:
+       sdhci_pltfm_free(pdev);
+err:
+       dev_err(&pdev->dev, "pic32-sdhci probe failed: %d\n", ret);
+       return ret;
+}
+
+static int pic32_sdhci_remove(struct platform_device *pdev)
+{
+       struct sdhci_host *host = platform_get_drvdata(pdev);
+       struct pic32_sdhci_priv *sdhci_pdata = sdhci_priv(host);
+       u32 scratch;
+
+       scratch = readl(host->ioaddr + SDHCI_INT_STATUS);
+       sdhci_remove_host(host, scratch == (u32)~0);
+       clk_disable_unprepare(sdhci_pdata->base_clk);
+       clk_disable_unprepare(sdhci_pdata->sys_clk);
+       sdhci_pltfm_free(pdev);
+
+       return 0;
+}
+
+static const struct of_device_id pic32_sdhci_id_table[] = {
+       { .compatible = "microchip,pic32mzda-sdhci" },
+       {}
+};
+MODULE_DEVICE_TABLE(of, pic32_sdhci_id_table);
+
+static struct platform_driver pic32_sdhci_driver = {
+       .driver = {
+               .name   = "pic32-sdhci",
+               .owner  = THIS_MODULE,
+               .of_match_table = of_match_ptr(pic32_sdhci_id_table),
+       },
+       .probe          = pic32_sdhci_probe,
+       .remove         = pic32_sdhci_remove,
+};
+
+module_platform_driver(pic32_sdhci_driver);
+
+MODULE_DESCRIPTION("Microchip PIC32 SDHCI driver");
+MODULE_AUTHOR("Pistirica Sorin Andrei & Sandeep Sheriker");
+MODULE_LICENSE("GPL v2");
index b7e305775314fa75ccc58dd67752420bda8494ce..5ff26ab81eb180241c5cccfb58c4073237954e89 100644 (file)
@@ -398,10 +398,10 @@ static struct mmc_host_ops sdricoh_ops = {
 static int sdricoh_init_mmc(struct pci_dev *pci_dev,
                            struct pcmcia_device *pcmcia_dev)
 {
-       int result = 0;
-       void __iomem *iobase = NULL;
-       struct mmc_host *mmc = NULL;
-       struct sdricoh_host *host = NULL;
+       int result;
+       void __iomem *iobase;
+       struct mmc_host *mmc;
+       struct sdricoh_host *host;
        struct device *dev = &pcmcia_dev->dev;
        /* map iomem */
        if (pci_resource_len(pci_dev, SDRICOH_PCI_REGION) !=
@@ -419,7 +419,7 @@ static int sdricoh_init_mmc(struct pci_dev *pci_dev,
        if (readl(iobase + R104_VERSION) != 0x4000) {
                dev_dbg(dev, "no supported mmc controller found\n");
                result = -ENODEV;
-               goto err;
+               goto unmap_io;
        }
        /* allocate privdata */
        mmc = pcmcia_dev->priv =
@@ -427,7 +427,7 @@ static int sdricoh_init_mmc(struct pci_dev *pci_dev,
        if (!mmc) {
                dev_err(dev, "mmc_alloc_host failed\n");
                result = -ENOMEM;
-               goto err;
+               goto unmap_io;
        }
        host = mmc_priv(mmc);
 
@@ -451,8 +451,7 @@ static int sdricoh_init_mmc(struct pci_dev *pci_dev,
        if (sdricoh_reset(host)) {
                dev_dbg(dev, "could not reset\n");
                result = -EIO;
-               goto err;
-
+               goto free_host;
        }
 
        result = mmc_add_host(mmc);
@@ -461,13 +460,10 @@ static int sdricoh_init_mmc(struct pci_dev *pci_dev,
                dev_dbg(dev, "mmc host registered\n");
                return 0;
        }
-
-err:
-       if (iobase)
-               pci_iounmap(pci_dev, iobase);
-       if (mmc)
-               mmc_free_host(mmc);
-
+free_host:
+       mmc_free_host(mmc);
+unmap_io:
+       pci_iounmap(pci_dev, iobase);
        return result;
 }
 
index 1ca8a1359cbc1efd6a35cefb596c1c4534c77920..8d870ce9f9442ef9c672e3167f59660337c4cbc9 100644 (file)
@@ -445,7 +445,7 @@ static void sh_mmcif_request_dma(struct sh_mmcif_host *host)
                                                        pdata->slave_id_rx);
        } else {
                host->chan_tx = dma_request_slave_channel(dev, "tx");
-               host->chan_tx = dma_request_slave_channel(dev, "rx");
+               host->chan_rx = dma_request_slave_channel(dev, "rx");
        }
        dev_dbg(dev, "%s: got channel TX %p RX %p\n", __func__, host->chan_tx,
                host->chan_rx);
@@ -1395,7 +1395,7 @@ static irqreturn_t sh_mmcif_intr(int irq, void *dev_id)
 
 static void sh_mmcif_timeout_work(struct work_struct *work)
 {
-       struct delayed_work *d = container_of(work, struct delayed_work, work);
+       struct delayed_work *d = to_delayed_work(work);
        struct sh_mmcif_host *host = container_of(d, struct sh_mmcif_host, timeout_work);
        struct mmc_request *mrq = host->mrq;
        struct device *dev = sh_mmcif_host_to_dev(host);
index 354f4f335ed57ab7abed082700264beb11d804b9..557e2b9dadeec74b09803d83fb83a69e7f107257 100644 (file)
@@ -59,7 +59,7 @@ static const struct sh_mobile_sdhi_of_data of_rcar_gen1_compatible = {
 
 static const struct sh_mobile_sdhi_of_data of_rcar_gen2_compatible = {
        .tmio_flags     = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_WRPROTECT_DISABLE |
-                         TMIO_MMC_CLK_ACTUAL,
+                         TMIO_MMC_CLK_ACTUAL | TMIO_MMC_FAST_CLK_CHG,
        .capabilities   = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ,
        .dma_buswidth   = DMA_SLAVE_BUSWIDTH_4_BYTES,
        .dma_rx_offset  = 0x2000,
@@ -163,6 +163,7 @@ static int sh_mobile_sdhi_write16_hook(struct tmio_mmc_host *host, int addr)
        case CTL_SD_MEM_CARD_OPT:
        case CTL_TRANSACTION_CTL:
        case CTL_DMA_ENABLE:
+       case EXT_ACC:
                return sh_mobile_sdhi_wait_idle(host);
        }
 
@@ -213,10 +214,8 @@ static int sh_mobile_sdhi_probe(struct platform_device *pdev)
                return -EINVAL;
 
        priv = devm_kzalloc(&pdev->dev, sizeof(struct sh_mobile_sdhi), GFP_KERNEL);
-       if (priv == NULL) {
-               dev_err(&pdev->dev, "kzalloc failed\n");
+       if (!priv)
                return -ENOMEM;
-       }
 
        mmc_data = &priv->mmc_data;
        dma_priv = &priv->dma_priv;
index 83de82bceafc91a6dd6326d393a4285a5b9061ad..8372a413848c19f8ed61e8c38e6a3b8ebb0a4ba7 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
 #include <linux/reset.h>
+#include <linux/regulator/consumer.h>
 
 #include <linux/of_address.h>
 #include <linux/of_gpio.h>
 #define SDXC_CLK_25M           1
 #define SDXC_CLK_50M           2
 #define SDXC_CLK_50M_DDR       3
+#define SDXC_CLK_50M_DDR_8BIT  4
 
 struct sunxi_mmc_clk_delay {
        u32 output;
@@ -256,6 +258,9 @@ struct sunxi_mmc_host {
        struct mmc_request *mrq;
        struct mmc_request *manual_stop_mrq;
        int             ferror;
+
+       /* vqmmc */
+       bool            vqmmc_enabled;
 };
 
 static int sunxi_mmc_reset_host(struct sunxi_mmc_host *host)
@@ -284,16 +289,28 @@ static int sunxi_mmc_init_host(struct mmc_host *mmc)
        if (sunxi_mmc_reset_host(host))
                return -EIO;
 
+       /*
+        * Burst 8 transfers, RX trigger level: 7, TX trigger level: 8
+        *
+        * TODO: sun9i has a larger FIFO and supports higher trigger values
+        */
        mmc_writel(host, REG_FTRGL, 0x20070008);
+       /* Maximum timeout value */
        mmc_writel(host, REG_TMOUT, 0xffffffff);
+       /* Unmask SDIO interrupt if needed */
        mmc_writel(host, REG_IMASK, host->sdio_imask);
+       /* Clear all pending interrupts */
        mmc_writel(host, REG_RINTR, 0xffffffff);
+       /* Debug register? undocumented */
        mmc_writel(host, REG_DBGC, 0xdeb);
+       /* Enable CEATA support */
        mmc_writel(host, REG_FUNS, SDXC_CEATA_ON);
+       /* Set DMA descriptor list base address */
        mmc_writel(host, REG_DLBA, host->sg_dma);
 
        rval = mmc_readl(host, REG_GCTRL);
        rval |= SDXC_INTERRUPT_ENABLE_BIT;
+       /* Undocumented, but found in Allwinner code */
        rval &= ~SDXC_ACCESS_DONE_DIRECT;
        mmc_writel(host, REG_GCTRL, rval);
 
@@ -640,11 +657,17 @@ static int sunxi_mmc_clk_set_rate(struct sunxi_mmc_host *host,
                                  struct mmc_ios *ios)
 {
        u32 rate, oclk_dly, rval, sclk_dly;
+       u32 clock = ios->clock;
        int ret;
 
-       rate = clk_round_rate(host->clk_mmc, ios->clock);
+       /* 8 bit DDR requires a higher module clock */
+       if (ios->timing == MMC_TIMING_MMC_DDR52 &&
+           ios->bus_width == MMC_BUS_WIDTH_8)
+               clock <<= 1;
+
+       rate = clk_round_rate(host->clk_mmc, clock);
        dev_dbg(mmc_dev(host->mmc), "setting clk to %d, rounded %d\n",
-               ios->clock, rate);
+               clock, rate);
 
        /* setting clock rate */
        ret = clk_set_rate(host->clk_mmc, rate);
@@ -661,6 +684,12 @@ static int sunxi_mmc_clk_set_rate(struct sunxi_mmc_host *host,
        /* clear internal divider */
        rval = mmc_readl(host, REG_CLKCR);
        rval &= ~0xff;
+       /* set internal divider for 8 bit eMMC DDR, so card clock is right */
+       if (ios->timing == MMC_TIMING_MMC_DDR52 &&
+           ios->bus_width == MMC_BUS_WIDTH_8) {
+               rval |= 1;
+               rate >>= 1;
+       }
        mmc_writel(host, REG_CLKCR, rval);
 
        /* determine delays */
@@ -670,13 +699,17 @@ static int sunxi_mmc_clk_set_rate(struct sunxi_mmc_host *host,
        } else if (rate <= 25000000) {
                oclk_dly = host->clk_delays[SDXC_CLK_25M].output;
                sclk_dly = host->clk_delays[SDXC_CLK_25M].sample;
-       } else if (rate <= 50000000) {
-               if (ios->timing == MMC_TIMING_UHS_DDR50) {
-                       oclk_dly = host->clk_delays[SDXC_CLK_50M_DDR].output;
-                       sclk_dly = host->clk_delays[SDXC_CLK_50M_DDR].sample;
-               } else {
+       } else if (rate <= 52000000) {
+               if (ios->timing != MMC_TIMING_UHS_DDR50 &&
+                   ios->timing != MMC_TIMING_MMC_DDR52) {
                        oclk_dly = host->clk_delays[SDXC_CLK_50M].output;
                        sclk_dly = host->clk_delays[SDXC_CLK_50M].sample;
+               } else if (ios->bus_width == MMC_BUS_WIDTH_8) {
+                       oclk_dly = host->clk_delays[SDXC_CLK_50M_DDR_8BIT].output;
+                       sclk_dly = host->clk_delays[SDXC_CLK_50M_DDR_8BIT].sample;
+               } else {
+                       oclk_dly = host->clk_delays[SDXC_CLK_50M_DDR].output;
+                       sclk_dly = host->clk_delays[SDXC_CLK_50M_DDR].sample;
                }
        } else {
                return -EINVAL;
@@ -699,7 +732,20 @@ static void sunxi_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
                break;
 
        case MMC_POWER_UP:
-               mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, ios->vdd);
+               host->ferror = mmc_regulator_set_ocr(mmc, mmc->supply.vmmc,
+                                                    ios->vdd);
+               if (host->ferror)
+                       return;
+
+               if (!IS_ERR(mmc->supply.vqmmc)) {
+                       host->ferror = regulator_enable(mmc->supply.vqmmc);
+                       if (host->ferror) {
+                               dev_err(mmc_dev(mmc),
+                                       "failed to enable vqmmc\n");
+                               return;
+                       }
+                       host->vqmmc_enabled = true;
+               }
 
                host->ferror = sunxi_mmc_init_host(mmc);
                if (host->ferror)
@@ -712,6 +758,9 @@ static void sunxi_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
                dev_dbg(mmc_dev(mmc), "power off!\n");
                sunxi_mmc_reset_host(host);
                mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0);
+               if (!IS_ERR(mmc->supply.vqmmc) && host->vqmmc_enabled)
+                       regulator_disable(mmc->supply.vqmmc);
+               host->vqmmc_enabled = false;
                break;
        }
 
@@ -730,7 +779,8 @@ static void sunxi_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 
        /* set ddr mode */
        rval = mmc_readl(host, REG_GCTRL);
-       if (ios->timing == MMC_TIMING_UHS_DDR50)
+       if (ios->timing == MMC_TIMING_UHS_DDR50 ||
+           ios->timing == MMC_TIMING_MMC_DDR52)
                rval |= SDXC_DDR_MODE;
        else
                rval &= ~SDXC_DDR_MODE;
@@ -743,6 +793,19 @@ static void sunxi_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
        }
 }
 
+static int sunxi_mmc_volt_switch(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+       /* vqmmc regulator is available */
+       if (!IS_ERR(mmc->supply.vqmmc))
+               return mmc_regulator_set_vqmmc(mmc, ios);
+
+       /* no vqmmc regulator, assume fixed regulator at 3/3.3V */
+       if (mmc->ios.signal_voltage == MMC_SIGNAL_VOLTAGE_330)
+               return 0;
+
+       return -EINVAL;
+}
+
 static void sunxi_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
 {
        struct sunxi_mmc_host *host = mmc_priv(mmc);
@@ -815,11 +878,6 @@ static void sunxi_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
 
                if ((cmd->flags & MMC_CMD_MASK) == MMC_CMD_ADTC) {
                        cmd_val |= SDXC_DATA_EXPIRE | SDXC_WAIT_PRE_OVER;
-                       if (cmd->data->flags & MMC_DATA_STREAM) {
-                               imask |= SDXC_AUTO_COMMAND_DONE;
-                               cmd_val |= SDXC_SEQUENCE_MODE |
-                                          SDXC_SEND_AUTO_STOP;
-                       }
 
                        if (cmd->data->stop) {
                                imask |= SDXC_AUTO_COMMAND_DONE;
@@ -894,6 +952,7 @@ static struct mmc_host_ops sunxi_mmc_ops = {
        .get_ro          = mmc_gpio_get_ro,
        .get_cd          = mmc_gpio_get_cd,
        .enable_sdio_irq = sunxi_mmc_enable_sdio_irq,
+       .start_signal_voltage_switch = sunxi_mmc_volt_switch,
        .hw_reset        = sunxi_mmc_hw_reset,
        .card_busy       = sunxi_mmc_card_busy,
 };
@@ -903,6 +962,8 @@ static const struct sunxi_mmc_clk_delay sunxi_mmc_clk_delays[] = {
        [SDXC_CLK_25M]          = { .output = 180, .sample =  75 },
        [SDXC_CLK_50M]          = { .output =  90, .sample = 120 },
        [SDXC_CLK_50M_DDR]      = { .output =  60, .sample = 120 },
+       /* Value from A83T "new timing mode". Works but might not be right. */
+       [SDXC_CLK_50M_DDR_8BIT] = { .output =  90, .sample = 180 },
 };
 
 static const struct sunxi_mmc_clk_delay sun9i_mmc_clk_delays[] = {
@@ -910,6 +971,7 @@ static const struct sunxi_mmc_clk_delay sun9i_mmc_clk_delays[] = {
        [SDXC_CLK_25M]          = { .output = 180, .sample =  75 },
        [SDXC_CLK_50M]          = { .output = 150, .sample = 120 },
        [SDXC_CLK_50M_DDR]      = { .output =  90, .sample = 120 },
+       [SDXC_CLK_50M_DDR_8BIT] = { .output =  90, .sample = 120 },
 };
 
 static int sunxi_mmc_resource_request(struct sunxi_mmc_host *host,
@@ -1060,10 +1122,11 @@ static int sunxi_mmc_probe(struct platform_device *pdev)
        mmc->max_segs           = PAGE_SIZE / sizeof(struct sunxi_idma_des);
        mmc->max_seg_size       = (1 << host->idma_des_size_bits);
        mmc->max_req_size       = mmc->max_seg_size * mmc->max_segs;
-       /* 400kHz ~ 50MHz */
+       /* 400kHz ~ 52MHz */
        mmc->f_min              =   400000;
-       mmc->f_max              = 50000000;
+       mmc->f_max              = 52000000;
        mmc->caps              |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
+                                 MMC_CAP_1_8V_DDR |
                                  MMC_CAP_ERASE | MMC_CAP_SDIO_IRQ;
 
        ret = mmc_of_parse(mmc);
index 4a0d6b80eaa374e7749081c7f966ce85379ad3e2..675435873823126170602156ff99ca385e451d18 100644 (file)
@@ -94,10 +94,7 @@ static void tmio_mmc_start_dma_rx(struct tmio_mmc_host *host)
                        desc = NULL;
                        ret = cookie;
                }
-               dev_dbg(&host->pdev->dev, "%s(): mapped %d -> %d, cookie %d, rq %p\n",
-                       __func__, host->sg_len, ret, cookie, host->mrq);
        }
-
 pio:
        if (!desc) {
                /* DMA failed, fall back to PIO */
@@ -115,9 +112,6 @@ pio:
                dev_warn(&host->pdev->dev,
                         "DMA failed: %d, falling back to PIO\n", ret);
        }
-
-       dev_dbg(&host->pdev->dev, "%s(): desc %p, sg[%d]\n", __func__,
-               desc, host->sg_len);
 }
 
 static void tmio_mmc_start_dma_tx(struct tmio_mmc_host *host)
@@ -174,10 +168,7 @@ static void tmio_mmc_start_dma_tx(struct tmio_mmc_host *host)
                        desc = NULL;
                        ret = cookie;
                }
-               dev_dbg(&host->pdev->dev, "%s(): mapped %d -> %d, cookie %d, rq %p\n",
-                       __func__, host->sg_len, ret, cookie, host->mrq);
        }
-
 pio:
        if (!desc) {
                /* DMA failed, fall back to PIO */
@@ -195,8 +186,6 @@ pio:
                dev_warn(&host->pdev->dev,
                         "DMA failed: %d, falling back to PIO\n", ret);
        }
-
-       dev_dbg(&host->pdev->dev, "%s(): desc %p\n", __func__, desc);
 }
 
 void tmio_mmc_start_dma(struct tmio_mmc_host *host,
index a10fde40b6c3ddbed98e05a693336ea6b1bb1c65..03f6e74c190691c74e4845bdd94401710baaed5c 100644 (file)
@@ -1,6 +1,8 @@
 /*
  * linux/drivers/mmc/host/tmio_mmc_pio.c
  *
+ * Copyright (C) 2016 Sang Engineering, Wolfram Sang
+ * Copyright (C) 2015-16 Renesas Electronics Corporation
  * Copyright (C) 2011 Guennadi Liakhovetski
  * Copyright (C) 2007 Ian Molton
  * Copyright (C) 2004 Ian Molton
@@ -159,42 +161,44 @@ static void tmio_mmc_set_clock(struct tmio_mmc_host *host,
 
        if (new_clock) {
                for (clock = host->mmc->f_min, clk = 0x80000080;
-                       new_clock >= (clock<<1); clk >>= 1)
+                    new_clock >= (clock << 1);
+                    clk >>= 1)
                        clock <<= 1;
 
                /* 1/1 clock is option */
                if ((host->pdata->flags & TMIO_MMC_CLK_ACTUAL) &&
-                   ((clk >> 22) & 0x1))
+                  ((clk >> 22) & 0x1))
                        clk |= 0xff;
        }
 
        if (host->set_clk_div)
-               host->set_clk_div(host->pdev, (clk>>22) & 1);
+               host->set_clk_div(host->pdev, (clk >> 22) & 1);
 
-       sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, clk & 0x1ff);
-       msleep(10);
+       sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~CLK_CTL_SCLKEN &
+                       sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
+       sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, clk & CLK_CTL_DIV_MASK);
+       if (!(host->pdata->flags & TMIO_MMC_FAST_CLK_CHG))
+               msleep(10);
 }
 
 static void tmio_mmc_clk_stop(struct tmio_mmc_host *host)
 {
-       /* implicit BUG_ON(!res) */
        if (host->pdata->flags & TMIO_MMC_HAVE_HIGH_REG) {
                sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0000);
                msleep(10);
        }
 
-       sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~0x0100 &
+       sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~CLK_CTL_SCLKEN &
                sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
-       msleep(10);
+       msleep(host->pdata->flags & TMIO_MMC_FAST_CLK_CHG ? 5 : 10);
 }
 
 static void tmio_mmc_clk_start(struct tmio_mmc_host *host)
 {
-       sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, 0x0100 |
+       sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, CLK_CTL_SCLKEN |
                sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
-       msleep(10);
+       msleep(host->pdata->flags & TMIO_MMC_FAST_CLK_CHG ? 1 : 10);
 
-       /* implicit BUG_ON(!res) */
        if (host->pdata->flags & TMIO_MMC_HAVE_HIGH_REG) {
                sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0100);
                msleep(10);
@@ -205,7 +209,6 @@ static void tmio_mmc_reset(struct tmio_mmc_host *host)
 {
        /* FIXME - should we set stop clock reg here */
        sd_ctrl_write16(host, CTL_RESET_SD, 0x0000);
-       /* implicit BUG_ON(!res) */
        if (host->pdata->flags & TMIO_MMC_HAVE_HIGH_REG)
                sd_ctrl_write16(host, CTL_RESET_SDIO, 0x0000);
        msleep(10);
index b47122d3e8d8c71b435cdc47a275f349bf102a22..b2752fe711f2956d52e26d8d30c751919fcbde3e 100644 (file)
@@ -1630,7 +1630,7 @@ static irqreturn_t usdhi6_cd(int irq, void *dev_id)
  */
 static void usdhi6_timeout_work(struct work_struct *work)
 {
-       struct delayed_work *d = container_of(work, struct delayed_work, work);
+       struct delayed_work *d = to_delayed_work(work);
        struct usdhi6_host *host = container_of(d, struct usdhi6_host, timeout_work);
        struct mmc_request *mrq = host->mrq;
        struct mmc_data *data = mrq ? mrq->data : NULL;
index 24b86d538e8852eef94cc020a7f92230dcfacedd..05d58ee5e6a78fb4d8366b2391d84a2f4838aa82 100644 (file)
  * Some controllers can support SDIO IRQ signalling.
  */
 #define TMIO_MMC_SDIO_IRQ              (1 << 2)
+
+/* Some controllers don't need to wait 10ms for clock changes */
+#define TMIO_MMC_FAST_CLK_CHG          (1 << 3)
+
 /*
  * Some controllers require waiting for the SD bus to become
  * idle before writing to some registers.
index 37967b6da03cf542d7a5762342c2089d93054b7a..b01e77de1a74de9350fd96a66440566592a69bf5 100644 (file)
@@ -113,7 +113,6 @@ struct mmc_data {
 
 #define MMC_DATA_WRITE (1 << 8)
 #define MMC_DATA_READ  (1 << 9)
-#define MMC_DATA_STREAM        (1 << 10)
 
        unsigned int            bytes_xfered;
 
index 89df7abedd67298d00df558af49de438cccf8439..7b41c6db1bb6e704cba300f137b7de15e494b966 100644 (file)
@@ -235,21 +235,11 @@ struct dw_mci_dma_ops {
 };
 
 /* IP Quirks/flags. */
-/* Unreliable card detection */
-#define DW_MCI_QUIRK_BROKEN_CARD_DETECTION     BIT(0)
 /* Timer for broken data transfer over scheme */
-#define DW_MCI_QUIRK_BROKEN_DTO                        BIT(1)
+#define DW_MCI_QUIRK_BROKEN_DTO                        BIT(0)
 
 struct dma_pdata;
 
-struct block_settings {
-       unsigned short  max_segs;       /* see blk_queue_max_segments */
-       unsigned int    max_blk_size;   /* maximum size of one mmc block */
-       unsigned int    max_blk_count;  /* maximum number of blocks in one req*/
-       unsigned int    max_req_size;   /* maximum number of bytes in one req*/
-       unsigned int    max_seg_size;   /* see blk_queue_max_segment_size */
-};
-
 /* Board platform data */
 struct dw_mci_board {
        u32 num_slots;
index 84d9053b5dca3ef453ac611fd6b223c02e1903c6..5f5cd80e97650047a8d4752d0389c5598f2a56a7 100644 (file)
@@ -1,6 +1,8 @@
 /*
  * include/linux/mmc/tmio.h
  *
+ * Copyright (C) 2016 Sang Engineering, Wolfram Sang
+ * Copyright (C) 2015-16 Renesas Electronics Corporation
  * Copyright (C) 2007 Ian Molton
  * Copyright (C) 2004 Ian Molton
  *
@@ -61,6 +63,9 @@
 #define TMIO_STAT_CMD_BUSY      0x40000000
 #define TMIO_STAT_ILL_ACCESS    0x80000000
 
+#define        CLK_CTL_DIV_MASK        0xff
+#define        CLK_CTL_SCLKEN          BIT(8)
+
 #define TMIO_BBS               512             /* Boot block size */
 
 #endif /* LINUX_MMC_TMIO_H */