diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-12 11:30:02 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-12 11:30:02 -0800 |
commit | b1286f4e9ac14c8973140b338b4d3c5691264d3b (patch) | |
tree | 5a67788bb2276cd67230d24b5a6994ddafb10707 /drivers/mmc/host | |
parent | 6facac1ab68fbf9cbad31a9d521f3a0d6aa9470e (diff) | |
parent | 0fa5d3996dbda1ee9653c43d39b7ef159fb57ee7 (diff) |
Merge branch 'for-linus' of git://git.linaro.org/people/rmk/linux-arm
Pull ARM updates from Russell King:
"Here's the updates for ARM for this merge window, which cover quite a
variety of areas.
There's a bunch of patch series from Will tackling various bugs like
the PROT_NONE handling, ASID allocation, cluster boot protocol and
ASID TLB tagging updates.
We move to a build-time sorted exception table rather than doing the
sorting at run-time, add support for the secure computing filter, and
some updates to the perf code. We also have sorted out the placement
of some headers, fixed some build warnings, fixed some hotplug
problems with the per-cpu TWD code."
* 'for-linus' of git://git.linaro.org/people/rmk/linux-arm: (73 commits)
ARM: 7594/1: Add .smp entry for REALVIEW_EB
ARM: 7599/1: head: Remove boot-time HYP mode check for v5 and below
ARM: 7598/1: net: bpf_jit_32: fix sp-relative load/stores offsets.
ARM: 7595/1: syscall: rework ordering in syscall_trace_exit
ARM: 7596/1: mmci: replace readsl/writesl with ioread32_rep/iowrite32_rep
ARM: 7597/1: net: bpf_jit_32: fix kzalloc gfp/size mismatch.
ARM: 7593/1: nommu: do not enable DCACHE_WORD_ACCESS when !CONFIG_MMU
ARM: 7592/1: nommu: prevent generation of kernel unaligned memory accesses
ARM: 7591/1: nommu: Enable the strict alignment (CR_A) bit only if ARCH < v6
ARM: 7590/1: /proc/interrupts: limit the display of IPIs to online CPUs only
ARM: 7587/1: implement optimized percpu variable access
ARM: 7589/1: integrator: pass the lm resource to amba
ARM: 7588/1: amba: create a resource parent registrator
ARM: 7582/2: rename kvm_seq to vmalloc_seq so to avoid confusion with KVM
ARM: 7585/1: kernel: fix nr_cpu_ids check in DT logical map init
ARM: 7584/1: perf: fix link error when CONFIG_HW_PERF_EVENTS is not selected
ARM: gic: use a private mapping for CPU target interfaces
ARM: kernel: add logical mappings look-up
ARM: kernel: add cpu logical map DT init in setup_arch
ARM: kernel: add device tree init map function
...
Diffstat (limited to 'drivers/mmc/host')
-rw-r--r-- | drivers/mmc/host/mmci.c | 66 | ||||
-rw-r--r-- | drivers/mmc/host/mmci.h | 4 |
2 files changed, 49 insertions, 21 deletions
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index ec28d175d9c..150772395cc 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -33,6 +33,7 @@ #include <linux/amba/mmci.h> #include <linux/pm_runtime.h> #include <linux/types.h> +#include <linux/pinctrl/consumer.h> #include <asm/div64.h> #include <asm/io.h> @@ -654,9 +655,31 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) /* The ST Micro variants has a special bit to enable SDIO */ if (variant->sdio && host->mmc->card) - if (mmc_card_sdio(host->mmc->card)) + if (mmc_card_sdio(host->mmc->card)) { + /* + * The ST Micro variants has a special bit + * to enable SDIO. + */ + u32 clk; + datactrl |= MCI_ST_DPSM_SDIOEN; + /* + * The ST Micro variant for SDIO small write transfers + * needs to have clock H/W flow control disabled, + * otherwise the transfer will not start. The threshold + * depends on the rate of MCLK. + */ + if (data->flags & MMC_DATA_WRITE && + (host->size < 8 || + (host->size <= 8 && host->mclk > 50000000))) + clk = host->clk_reg & ~variant->clkreg_enable; + else + clk = host->clk_reg | variant->clkreg_enable; + + mmci_write_clkreg(host, clk); + } + /* * Attempt to use DMA operation mode, if this * should fail, fall back to PIO mode @@ -840,14 +863,14 @@ static int mmci_pio_read(struct mmci_host *host, char *buffer, unsigned int rema if (unlikely(count & 0x3)) { if (count < 4) { unsigned char buf[4]; - readsl(base + MMCIFIFO, buf, 1); + ioread32_rep(base + MMCIFIFO, buf, 1); memcpy(ptr, buf, count); } else { - readsl(base + MMCIFIFO, ptr, count >> 2); + ioread32_rep(base + MMCIFIFO, ptr, count >> 2); count &= ~0x3; } } else { - readsl(base + MMCIFIFO, ptr, count >> 2); + ioread32_rep(base + MMCIFIFO, ptr, count >> 2); } ptr += count; @@ -877,22 +900,6 @@ static int mmci_pio_write(struct mmci_host *host, char *buffer, unsigned int rem count = min(remain, maxcnt); /* - * The ST Micro variant for SDIO transfer sizes - * less then 8 bytes should have clock H/W flow - * control disabled. - */ - if (variant->sdio && - mmc_card_sdio(host->mmc->card)) { - u32 clk; - if (count < 8) - clk = host->clk_reg & ~variant->clkreg_enable; - else - clk = host->clk_reg | variant->clkreg_enable; - - mmci_write_clkreg(host, clk); - } - - /* * SDIO especially may want to send something that is * not divisible by 4 (as opposed to card sectors * etc), and the FIFO only accept full 32-bit writes. @@ -900,7 +907,7 @@ static int mmci_pio_write(struct mmci_host *host, char *buffer, unsigned int rem * byte become a 32bit write, 7 bytes will be two * 32bit writes etc. */ - writesl(base + MMCIFIFO, ptr, (count + 3) >> 2); + iowrite32_rep(base + MMCIFIFO, ptr, (count + 3) >> 2); ptr += count; remain -= count; @@ -1360,6 +1367,23 @@ static int mmci_probe(struct amba_device *dev, mmc->f_max = min(host->mclk, fmax); dev_dbg(mmc_dev(mmc), "clocking block at %u Hz\n", mmc->f_max); + host->pinctrl = devm_pinctrl_get(&dev->dev); + if (IS_ERR(host->pinctrl)) { + ret = PTR_ERR(host->pinctrl); + goto clk_disable; + } + + host->pins_default = pinctrl_lookup_state(host->pinctrl, + PINCTRL_STATE_DEFAULT); + + /* enable pins to be muxed in and configured */ + if (!IS_ERR(host->pins_default)) { + ret = pinctrl_select_state(host->pinctrl, host->pins_default); + if (ret) + dev_warn(&dev->dev, "could not set default pins\n"); + } else + dev_warn(&dev->dev, "could not get default pinstate\n"); + #ifdef CONFIG_REGULATOR /* If we're using the regulator framework, try to fetch a regulator */ host->vcc = regulator_get(&dev->dev, "vmmc"); diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h index d437ccf62d6..d34d8c0add8 100644 --- a/drivers/mmc/host/mmci.h +++ b/drivers/mmc/host/mmci.h @@ -195,6 +195,10 @@ struct mmci_host { unsigned int size; struct regulator *vcc; + /* pinctrl handles */ + struct pinctrl *pinctrl; + struct pinctrl_state *pins_default; + #ifdef CONFIG_DMA_ENGINE /* DMA stuff */ struct dma_chan *dma_current; |