diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-02 12:22:24 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-02 12:22:24 -0400 |
| commit | 6c52486dedbb30a1313da64945dcd686b4579c51 (patch) | |
| tree | cce3fcb1ee47ea30f0b74271e00e83039b9f9f92 | |
| parent | c9733c79f411b5df63f3dfd494fc37636a4d8fba (diff) | |
| parent | 8c3a05b489ef097f86bf87c64192456553f57781 (diff) | |
Merge tag 'mmc-v3.16-1' of git://git.linaro.org/people/ulf.hansson/mmc into next
Pull MMC update from Ulf Hansson:
"These patches are mainly updates for the mmci driver and have been
tested in linux-next.
Some ARM SoC related patches are also included and those have been
acked from the corresponding maintainers to go through my mmc tree.
Updates for mmci driver:
- Put the device into low power state at system suspend.
- Convert to the common mmc DT parser.
- Add missing DT bindings needed for ux500.
Updates for ARM ux500|u300:
- Convert to the common mmc DT bindings.
- Remove redundant board file for mmci platform data"
* tag 'mmc-v3.16-1' of git://git.linaro.org/people/ulf.hansson/mmc: (22 commits)
mmc: mmci: Enforce DMA configuration through DT
mmc: mmci: Enforce max frequency configuration through DT
mmc: mmci: Enforce mmc capabilities through DT
mmc: mmci: Enforce DT for signal direction and feedback clock
ARM: ux500: Remove redundant board file for mmci platform data
ARM: ux500: Add a vmmc regulator through DT for the poped eMMC for href
ARM: ux500: Add the mmc capabilities flags to DT
mmc: mmci: Enable MMC_CAP_CMD23
mmc: mmci: Mark the DT bindings for highspeed mode as deprecated
ARM: u300: Convert to the common mmc DT bindings for highspeed mode
ARM: nomadik: Convert to the common mmc DT bindings for highspeed mode
ARM: ux500: Convert to the common mmc DT bindings for highspeed mode
ARM: ux500: Add mmci signal directions and feeback clock in DT for href
mmc: mmci: Use the common mmc DT parser
mmc: mmci: Add DT bindings for feedback clock pin
mmc: mmci: Add DT bindings for signal direction
mmc: mmci: Update DT documentation
mmc: mmci: Convert to devm functions
mmc: mmci: Convert to the mmc gpio API
mmc: mmci: Put the device into low power state at system suspend
...
| -rw-r--r-- | Documentation/devicetree/bindings/mmc/mmci.txt | 54 | ||||
| -rw-r--r-- | arch/arm/boot/dts/ste-ccu9540.dts | 6 | ||||
| -rw-r--r-- | arch/arm/boot/dts/ste-href.dtsi | 19 | ||||
| -rw-r--r-- | arch/arm/boot/dts/ste-nomadik-stn8815.dtsi | 4 | ||||
| -rw-r--r-- | arch/arm/boot/dts/ste-snowball.dts | 4 | ||||
| -rw-r--r-- | arch/arm/boot/dts/ste-u300.dts | 4 | ||||
| -rw-r--r-- | arch/arm/mach-lpc32xx/phy3250.c | 3 | ||||
| -rw-r--r-- | arch/arm/mach-ux500/Makefile | 3 | ||||
| -rw-r--r-- | arch/arm/mach-ux500/board-mop500-sdi.c | 166 | ||||
| -rw-r--r-- | arch/arm/mach-ux500/board-mop500.h | 5 | ||||
| -rw-r--r-- | arch/arm/mach-ux500/cpu-db8500.c | 4 | ||||
| -rw-r--r-- | drivers/mmc/host/mmci.c | 324 | ||||
| -rw-r--r-- | drivers/mmc/host/mmci.h | 14 | ||||
| -rw-r--r-- | include/linux/amba/mmci.h | 42 |
14 files changed, 169 insertions, 483 deletions
diff --git a/Documentation/devicetree/bindings/mmc/mmci.txt b/Documentation/devicetree/bindings/mmc/mmci.txt index 2b584cae352a..03796cf2d3e7 100644 --- a/Documentation/devicetree/bindings/mmc/mmci.txt +++ b/Documentation/devicetree/bindings/mmc/mmci.txt | |||
| @@ -4,12 +4,58 @@ The ARM PrimeCell MMCI PL180 and PL181 provides an interface for | |||
| 4 | reading and writing to MultiMedia and SD cards alike. | 4 | reading and writing to MultiMedia and SD cards alike. |
| 5 | 5 | ||
| 6 | This file documents differences between the core properties described | 6 | This file documents differences between the core properties described |
| 7 | by mmc.txt and the properties used by the mmci driver. | 7 | by mmc.txt and the properties used by the mmci driver. Using "st" as |
| 8 | the prefix for a property, indicates support by the ST Micro variant. | ||
| 8 | 9 | ||
| 9 | Required properties: | 10 | Required properties: |
| 10 | - compatible : contains "arm,pl18x", "arm,primecell". | 11 | - compatible : contains "arm,pl18x", "arm,primecell". |
| 11 | - arm,primecell-periphid : contains the PrimeCell Peripheral ID. | 12 | - vmmc-supply : phandle to the regulator device tree node, mentioned |
| 13 | as the VCC/VDD supply in the eMMC/SD specs. | ||
| 12 | 14 | ||
| 13 | Optional properties: | 15 | Optional properties: |
| 14 | - mmc-cap-mmc-highspeed : indicates whether MMC is high speed capable | 16 | - arm,primecell-periphid : contains the PrimeCell Peripheral ID, it overrides |
| 15 | - mmc-cap-sd-highspeed : indicates whether SD is high speed capable | 17 | the ID provided by the HW |
| 18 | - vqmmc-supply : phandle to the regulator device tree node, mentioned | ||
| 19 | as the VCCQ/VDD_IO supply in the eMMC/SD specs. | ||
| 20 | - st,sig-dir-dat0 : bus signal direction pin used for DAT[0]. | ||
| 21 | - st,sig-dir-dat2 : bus signal direction pin used for DAT[2]. | ||
| 22 | - st,sig-dir-dat31 : bus signal direction pin used for DAT[3] and DAT[1]. | ||
| 23 | - st,sig-dir-dat74 : bus signal direction pin used for DAT[4] to DAT[7]. | ||
| 24 | - st,sig-dir-cmd : cmd signal direction pin used for CMD. | ||
| 25 | - st,sig-pin-fbclk : feedback clock signal pin used. | ||
| 26 | |||
| 27 | Deprecated properties: | ||
| 28 | - mmc-cap-mmc-highspeed : indicates whether MMC is high speed capable. | ||
| 29 | - mmc-cap-sd-highspeed : indicates whether SD is high speed capable. | ||
| 30 | |||
| 31 | Example: | ||
| 32 | |||
| 33 | sdi0_per1@80126000 { | ||
| 34 | compatible = "arm,pl18x", "arm,primecell"; | ||
| 35 | reg = <0x80126000 0x1000>; | ||
| 36 | interrupts = <0 60 IRQ_TYPE_LEVEL_HIGH>; | ||
| 37 | |||
| 38 | dmas = <&dma 29 0 0x2>, /* Logical - DevToMem */ | ||
| 39 | <&dma 29 0 0x0>; /* Logical - MemToDev */ | ||
| 40 | dma-names = "rx", "tx"; | ||
| 41 | |||
| 42 | clocks = <&prcc_kclk 1 5>, <&prcc_pclk 1 5>; | ||
| 43 | clock-names = "sdi", "apb_pclk"; | ||
| 44 | |||
| 45 | max-frequency = <100000000>; | ||
| 46 | bus-width = <4>; | ||
| 47 | cap-sd-highspeed; | ||
| 48 | cap-mmc-highspeed; | ||
| 49 | cd-gpios = <&gpio2 31 0x4>; // 95 | ||
| 50 | st,sig-dir-dat0; | ||
| 51 | st,sig-dir-dat2; | ||
| 52 | st,sig-dir-cmd; | ||
| 53 | st,sig-pin-fbclk; | ||
| 54 | |||
| 55 | vmmc-supply = <&ab8500_ldo_aux3_reg>; | ||
| 56 | vqmmc-supply = <&vmmci>; | ||
| 57 | |||
| 58 | pinctrl-names = "default", "sleep"; | ||
| 59 | pinctrl-0 = <&sdi0_default_mode>; | ||
| 60 | pinctrl-1 = <&sdi0_sleep_mode>; | ||
| 61 | }; | ||
diff --git a/arch/arm/boot/dts/ste-ccu9540.dts b/arch/arm/boot/dts/ste-ccu9540.dts index 229508750890..651c56d400a4 100644 --- a/arch/arm/boot/dts/ste-ccu9540.dts +++ b/arch/arm/boot/dts/ste-ccu9540.dts | |||
| @@ -38,8 +38,8 @@ | |||
| 38 | arm,primecell-periphid = <0x10480180>; | 38 | arm,primecell-periphid = <0x10480180>; |
| 39 | max-frequency = <100000000>; | 39 | max-frequency = <100000000>; |
| 40 | bus-width = <4>; | 40 | bus-width = <4>; |
| 41 | mmc-cap-sd-highspeed; | 41 | cap-sd-highspeed; |
| 42 | mmc-cap-mmc-highspeed; | 42 | cap-mmc-highspeed; |
| 43 | vmmc-supply = <&ab8500_ldo_aux3_reg>; | 43 | vmmc-supply = <&ab8500_ldo_aux3_reg>; |
| 44 | 44 | ||
| 45 | cd-gpios = <&gpio7 6 0x4>; // 230 | 45 | cd-gpios = <&gpio7 6 0x4>; // 230 |
| @@ -63,7 +63,7 @@ | |||
| 63 | arm,primecell-periphid = <0x10480180>; | 63 | arm,primecell-periphid = <0x10480180>; |
| 64 | max-frequency = <100000000>; | 64 | max-frequency = <100000000>; |
| 65 | bus-width = <8>; | 65 | bus-width = <8>; |
| 66 | mmc-cap-mmc-highspeed; | 66 | cap-mmc-highspeed; |
| 67 | vmmc-supply = <&ab8500_ldo_aux2_reg>; | 67 | vmmc-supply = <&ab8500_ldo_aux2_reg>; |
| 68 | 68 | ||
| 69 | status = "okay"; | 69 | status = "okay"; |
diff --git a/arch/arm/boot/dts/ste-href.dtsi b/arch/arm/boot/dts/ste-href.dtsi index 6cb9b68e2188..bf8f0eddc2c0 100644 --- a/arch/arm/boot/dts/ste-href.dtsi +++ b/arch/arm/boot/dts/ste-href.dtsi | |||
| @@ -116,8 +116,15 @@ | |||
| 116 | arm,primecell-periphid = <0x10480180>; | 116 | arm,primecell-periphid = <0x10480180>; |
| 117 | max-frequency = <100000000>; | 117 | max-frequency = <100000000>; |
| 118 | bus-width = <4>; | 118 | bus-width = <4>; |
| 119 | mmc-cap-sd-highspeed; | 119 | cap-sd-highspeed; |
| 120 | mmc-cap-mmc-highspeed; | 120 | cap-mmc-highspeed; |
| 121 | sd-uhs-sdr12; | ||
| 122 | sd-uhs-sdr25; | ||
| 123 | full-pwr-cycle; | ||
| 124 | st,sig-dir-dat0; | ||
| 125 | st,sig-dir-dat2; | ||
| 126 | st,sig-dir-cmd; | ||
| 127 | st,sig-pin-fbclk; | ||
| 121 | vmmc-supply = <&ab8500_ldo_aux3_reg>; | 128 | vmmc-supply = <&ab8500_ldo_aux3_reg>; |
| 122 | vqmmc-supply = <&vmmci>; | 129 | vqmmc-supply = <&vmmci>; |
| 123 | pinctrl-names = "default", "sleep"; | 130 | pinctrl-names = "default", "sleep"; |
| @@ -132,6 +139,7 @@ | |||
| 132 | arm,primecell-periphid = <0x10480180>; | 139 | arm,primecell-periphid = <0x10480180>; |
| 133 | max-frequency = <100000000>; | 140 | max-frequency = <100000000>; |
| 134 | bus-width = <4>; | 141 | bus-width = <4>; |
| 142 | non-removable; | ||
| 135 | pinctrl-names = "default", "sleep"; | 143 | pinctrl-names = "default", "sleep"; |
| 136 | pinctrl-0 = <&sdi1_default_mode>; | 144 | pinctrl-0 = <&sdi1_default_mode>; |
| 137 | pinctrl-1 = <&sdi1_sleep_mode>; | 145 | pinctrl-1 = <&sdi1_sleep_mode>; |
| @@ -144,7 +152,9 @@ | |||
| 144 | arm,primecell-periphid = <0x10480180>; | 152 | arm,primecell-periphid = <0x10480180>; |
| 145 | max-frequency = <100000000>; | 153 | max-frequency = <100000000>; |
| 146 | bus-width = <8>; | 154 | bus-width = <8>; |
| 147 | mmc-cap-mmc-highspeed; | 155 | cap-mmc-highspeed; |
| 156 | non-removable; | ||
| 157 | vmmc-supply = <&db8500_vsmps2_reg>; | ||
| 148 | pinctrl-names = "default", "sleep"; | 158 | pinctrl-names = "default", "sleep"; |
| 149 | pinctrl-0 = <&sdi2_default_mode>; | 159 | pinctrl-0 = <&sdi2_default_mode>; |
| 150 | pinctrl-1 = <&sdi2_sleep_mode>; | 160 | pinctrl-1 = <&sdi2_sleep_mode>; |
| @@ -157,7 +167,8 @@ | |||
| 157 | arm,primecell-periphid = <0x10480180>; | 167 | arm,primecell-periphid = <0x10480180>; |
| 158 | max-frequency = <100000000>; | 168 | max-frequency = <100000000>; |
| 159 | bus-width = <8>; | 169 | bus-width = <8>; |
| 160 | mmc-cap-mmc-highspeed; | 170 | cap-mmc-highspeed; |
| 171 | non-removable; | ||
| 161 | vmmc-supply = <&ab8500_ldo_aux2_reg>; | 172 | vmmc-supply = <&ab8500_ldo_aux2_reg>; |
| 162 | pinctrl-names = "default", "sleep"; | 173 | pinctrl-names = "default", "sleep"; |
| 163 | pinctrl-0 = <&sdi4_default_mode>; | 174 | pinctrl-0 = <&sdi4_default_mode>; |
diff --git a/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi b/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi index 5acc0449676a..d316c955bd5f 100644 --- a/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi +++ b/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi | |||
| @@ -840,8 +840,8 @@ | |||
| 840 | interrupts = <22>; | 840 | interrupts = <22>; |
| 841 | max-frequency = <48000000>; | 841 | max-frequency = <48000000>; |
| 842 | bus-width = <4>; | 842 | bus-width = <4>; |
| 843 | mmc-cap-mmc-highspeed; | 843 | cap-mmc-highspeed; |
| 844 | mmc-cap-sd-highspeed; | 844 | cap-sd-highspeed; |
| 845 | cd-gpios = <&gpio3 15 0x1>; | 845 | cd-gpios = <&gpio3 15 0x1>; |
| 846 | cd-inverted; | 846 | cd-inverted; |
| 847 | pinctrl-names = "default"; | 847 | pinctrl-names = "default"; |
diff --git a/arch/arm/boot/dts/ste-snowball.dts b/arch/arm/boot/dts/ste-snowball.dts index a2f632d0be2a..474ef83229cd 100644 --- a/arch/arm/boot/dts/ste-snowball.dts +++ b/arch/arm/boot/dts/ste-snowball.dts | |||
| @@ -156,7 +156,7 @@ | |||
| 156 | arm,primecell-periphid = <0x10480180>; | 156 | arm,primecell-periphid = <0x10480180>; |
| 157 | max-frequency = <100000000>; | 157 | max-frequency = <100000000>; |
| 158 | bus-width = <4>; | 158 | bus-width = <4>; |
| 159 | mmc-cap-mmc-highspeed; | 159 | cap-mmc-highspeed; |
| 160 | vmmc-supply = <&ab8500_ldo_aux3_reg>; | 160 | vmmc-supply = <&ab8500_ldo_aux3_reg>; |
| 161 | vqmmc-supply = <&vmmci>; | 161 | vqmmc-supply = <&vmmci>; |
| 162 | pinctrl-names = "default", "sleep"; | 162 | pinctrl-names = "default", "sleep"; |
| @@ -195,7 +195,7 @@ | |||
| 195 | arm,primecell-periphid = <0x10480180>; | 195 | arm,primecell-periphid = <0x10480180>; |
| 196 | max-frequency = <100000000>; | 196 | max-frequency = <100000000>; |
| 197 | bus-width = <8>; | 197 | bus-width = <8>; |
| 198 | mmc-cap-mmc-highspeed; | 198 | cap-mmc-highspeed; |
| 199 | vmmc-supply = <&ab8500_ldo_aux2_reg>; | 199 | vmmc-supply = <&ab8500_ldo_aux2_reg>; |
| 200 | pinctrl-names = "default", "sleep"; | 200 | pinctrl-names = "default", "sleep"; |
| 201 | pinctrl-0 = <&sdi4_default_mode>; | 201 | pinctrl-0 = <&sdi4_default_mode>; |
diff --git a/arch/arm/boot/dts/ste-u300.dts b/arch/arm/boot/dts/ste-u300.dts index 6fe688e9e4da..82a661677e97 100644 --- a/arch/arm/boot/dts/ste-u300.dts +++ b/arch/arm/boot/dts/ste-u300.dts | |||
| @@ -442,8 +442,8 @@ | |||
| 442 | clock-names = "apb_pclk", "mclk"; | 442 | clock-names = "apb_pclk", "mclk"; |
| 443 | max-frequency = <24000000>; | 443 | max-frequency = <24000000>; |
| 444 | bus-width = <4>; // SD-card slot | 444 | bus-width = <4>; // SD-card slot |
| 445 | mmc-cap-mmc-highspeed; | 445 | cap-mmc-highspeed; |
| 446 | mmc-cap-sd-highspeed; | 446 | cap-sd-highspeed; |
| 447 | cd-gpios = <&gpio 12 0x4>; | 447 | cd-gpios = <&gpio 12 0x4>; |
| 448 | cd-inverted; | 448 | cd-inverted; |
| 449 | vmmc-supply = <&ab3100_ldo_g_reg>; | 449 | vmmc-supply = <&ab3100_ldo_g_reg>; |
diff --git a/arch/arm/mach-lpc32xx/phy3250.c b/arch/arm/mach-lpc32xx/phy3250.c index 34932e0e31fa..7858d5b6f6ce 100644 --- a/arch/arm/mach-lpc32xx/phy3250.c +++ b/arch/arm/mach-lpc32xx/phy3250.c | |||
| @@ -202,9 +202,6 @@ static struct mmci_platform_data lpc32xx_mmci_data = { | |||
| 202 | .ocr_mask = MMC_VDD_30_31 | MMC_VDD_31_32 | | 202 | .ocr_mask = MMC_VDD_30_31 | MMC_VDD_31_32 | |
| 203 | MMC_VDD_32_33 | MMC_VDD_33_34, | 203 | MMC_VDD_32_33 | MMC_VDD_33_34, |
| 204 | .ios_handler = mmc_handle_ios, | 204 | .ios_handler = mmc_handle_ios, |
| 205 | .dma_filter = NULL, | ||
| 206 | /* No DMA for now since AMBA PL080 dmaengine driver only does scatter | ||
| 207 | * gather, and the MMCI driver doesn't do it this way */ | ||
| 208 | }; | 205 | }; |
| 209 | 206 | ||
| 210 | static struct lpc32xx_slc_platform_data lpc32xx_slc_data = { | 207 | static struct lpc32xx_slc_platform_data lpc32xx_slc_data = { |
diff --git a/arch/arm/mach-ux500/Makefile b/arch/arm/mach-ux500/Makefile index de544aabf292..9741de956b3e 100644 --- a/arch/arm/mach-ux500/Makefile +++ b/arch/arm/mach-ux500/Makefile | |||
| @@ -5,8 +5,7 @@ | |||
| 5 | obj-y := cpu.o id.o timer.o pm.o | 5 | obj-y := cpu.o id.o timer.o pm.o |
| 6 | obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o | 6 | obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o |
| 7 | obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o | 7 | obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o |
| 8 | obj-$(CONFIG_MACH_MOP500) += board-mop500-sdi.o \ | 8 | obj-$(CONFIG_MACH_MOP500) += board-mop500-regulators.o \ |
| 9 | board-mop500-regulators.o \ | ||
| 10 | board-mop500-audio.o | 9 | board-mop500-audio.o |
| 11 | obj-$(CONFIG_SMP) += platsmp.o headsmp.o | 10 | obj-$(CONFIG_SMP) += platsmp.o headsmp.o |
| 12 | obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o | 11 | obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o |
diff --git a/arch/arm/mach-ux500/board-mop500-sdi.c b/arch/arm/mach-ux500/board-mop500-sdi.c deleted file mode 100644 index fcbf3a13a539..000000000000 --- a/arch/arm/mach-ux500/board-mop500-sdi.c +++ /dev/null | |||
| @@ -1,166 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) ST-Ericsson SA 2010 | ||
| 3 | * | ||
| 4 | * Author: Hanumath Prasad <hanumath.prasad@stericsson.com> | ||
| 5 | * License terms: GNU General Public License (GPL) version 2 | ||
| 6 | */ | ||
| 7 | |||
| 8 | #include <linux/kernel.h> | ||
| 9 | #include <linux/gpio.h> | ||
| 10 | #include <linux/amba/bus.h> | ||
| 11 | #include <linux/amba/mmci.h> | ||
| 12 | #include <linux/mmc/host.h> | ||
| 13 | #include <linux/platform_device.h> | ||
| 14 | #include <linux/platform_data/dma-ste-dma40.h> | ||
| 15 | |||
| 16 | #include <asm/mach-types.h> | ||
| 17 | |||
| 18 | #include "db8500-regs.h" | ||
| 19 | #include "board-mop500.h" | ||
| 20 | #include "ste-dma40-db8500.h" | ||
| 21 | |||
| 22 | /* | ||
| 23 | * v2 has a new version of this block that need to be forced, the number found | ||
| 24 | * in hardware is incorrect | ||
| 25 | */ | ||
| 26 | #define U8500_SDI_V2_PERIPHID 0x10480180 | ||
| 27 | |||
| 28 | /* | ||
| 29 | * SDI 0 (MicroSD slot) | ||
| 30 | */ | ||
| 31 | |||
| 32 | #ifdef CONFIG_STE_DMA40 | ||
| 33 | struct stedma40_chan_cfg mop500_sdi0_dma_cfg_rx = { | ||
| 34 | .mode = STEDMA40_MODE_LOGICAL, | ||
| 35 | .dir = DMA_DEV_TO_MEM, | ||
| 36 | .dev_type = DB8500_DMA_DEV29_SD_MM0, | ||
| 37 | }; | ||
| 38 | |||
| 39 | static struct stedma40_chan_cfg mop500_sdi0_dma_cfg_tx = { | ||
| 40 | .mode = STEDMA40_MODE_LOGICAL, | ||
| 41 | .dir = DMA_MEM_TO_DEV, | ||
| 42 | .dev_type = DB8500_DMA_DEV29_SD_MM0, | ||
| 43 | }; | ||
| 44 | #endif | ||
| 45 | |||
| 46 | struct mmci_platform_data mop500_sdi0_data = { | ||
| 47 | .f_max = 100000000, | ||
| 48 | .capabilities = MMC_CAP_4_BIT_DATA | | ||
| 49 | MMC_CAP_SD_HIGHSPEED | | ||
| 50 | MMC_CAP_MMC_HIGHSPEED | | ||
| 51 | MMC_CAP_ERASE | | ||
| 52 | MMC_CAP_UHS_SDR12 | | ||
| 53 | MMC_CAP_UHS_SDR25, | ||
| 54 | .gpio_wp = -1, | ||
| 55 | .sigdir = MCI_ST_FBCLKEN | | ||
| 56 | MCI_ST_CMDDIREN | | ||
| 57 | MCI_ST_DATA0DIREN | | ||
| 58 | MCI_ST_DATA2DIREN, | ||
| 59 | #ifdef CONFIG_STE_DMA40 | ||
| 60 | .dma_filter = stedma40_filter, | ||
| 61 | .dma_rx_param = &mop500_sdi0_dma_cfg_rx, | ||
| 62 | .dma_tx_param = &mop500_sdi0_dma_cfg_tx, | ||
| 63 | #endif | ||
| 64 | }; | ||
| 65 | |||
| 66 | /* | ||
| 67 | * SDI1 (SDIO WLAN) | ||
| 68 | */ | ||
| 69 | #ifdef CONFIG_STE_DMA40 | ||
| 70 | static struct stedma40_chan_cfg sdi1_dma_cfg_rx = { | ||
| 71 | .mode = STEDMA40_MODE_LOGICAL, | ||
| 72 | .dir = DMA_DEV_TO_MEM, | ||
| 73 | .dev_type = DB8500_DMA_DEV32_SD_MM1, | ||
| 74 | }; | ||
| 75 | |||
| 76 | static struct stedma40_chan_cfg sdi1_dma_cfg_tx = { | ||
| 77 | .mode = STEDMA40_MODE_LOGICAL, | ||
| 78 | .dir = DMA_MEM_TO_DEV, | ||
| 79 | .dev_type = DB8500_DMA_DEV32_SD_MM1, | ||
| 80 | }; | ||
| 81 | #endif | ||
| 82 | |||
| 83 | struct mmci_platform_data mop500_sdi1_data = { | ||
| 84 | .ocr_mask = MMC_VDD_29_30, | ||
| 85 | .f_max = 100000000, | ||
| 86 | .capabilities = MMC_CAP_4_BIT_DATA | | ||
| 87 | MMC_CAP_NONREMOVABLE, | ||
| 88 | .gpio_cd = -1, | ||
| 89 | .gpio_wp = -1, | ||
| 90 | #ifdef CONFIG_STE_DMA40 | ||
| 91 | .dma_filter = stedma40_filter, | ||
| 92 | .dma_rx_param = &sdi1_dma_cfg_rx, | ||
| 93 | .dma_tx_param = &sdi1_dma_cfg_tx, | ||
| 94 | #endif | ||
| 95 | }; | ||
| 96 | |||
| 97 | /* | ||
| 98 | * SDI 2 (POP eMMC, not on DB8500ed) | ||
| 99 | */ | ||
| 100 | |||
| 101 | #ifdef CONFIG_STE_DMA40 | ||
| 102 | struct stedma40_chan_cfg mop500_sdi2_dma_cfg_rx = { | ||
| 103 | .mode = STEDMA40_MODE_LOGICAL, | ||
| 104 | .dir = DMA_DEV_TO_MEM, | ||
| 105 | .dev_type = DB8500_DMA_DEV28_SD_MM2, | ||
| 106 | }; | ||
| 107 | |||
| 108 | static struct stedma40_chan_cfg mop500_sdi2_dma_cfg_tx = { | ||
| 109 | .mode = STEDMA40_MODE_LOGICAL, | ||
| 110 | .dir = DMA_MEM_TO_DEV, | ||
| 111 | .dev_type = DB8500_DMA_DEV28_SD_MM2, | ||
| 112 | }; | ||
| 113 | #endif | ||
| 114 | |||
| 115 | struct mmci_platform_data mop500_sdi2_data = { | ||
| 116 | .ocr_mask = MMC_VDD_165_195, | ||
| 117 | .f_max = 100000000, | ||
| 118 | .capabilities = MMC_CAP_4_BIT_DATA | | ||
| 119 | MMC_CAP_8_BIT_DATA | | ||
| 120 | MMC_CAP_NONREMOVABLE | | ||
| 121 | MMC_CAP_MMC_HIGHSPEED | | ||
| 122 | MMC_CAP_ERASE | | ||
| 123 | MMC_CAP_CMD23, | ||
| 124 | .gpio_cd = -1, | ||
| 125 | .gpio_wp = -1, | ||
| 126 | #ifdef CONFIG_STE_DMA40 | ||
| 127 | .dma_filter = stedma40_filter, | ||
| 128 | .dma_rx_param = &mop500_sdi2_dma_cfg_rx, | ||
| 129 | .dma_tx_param = &mop500_sdi2_dma_cfg_tx, | ||
| 130 | #endif | ||
| 131 | }; | ||
| 132 | |||
| 133 | /* | ||
| 134 | * SDI 4 (on-board eMMC) | ||
| 135 | */ | ||
| 136 | |||
| 137 | #ifdef CONFIG_STE_DMA40 | ||
| 138 | struct stedma40_chan_cfg mop500_sdi4_dma_cfg_rx = { | ||
| 139 | .mode = STEDMA40_MODE_LOGICAL, | ||
| 140 | .dir = DMA_DEV_TO_MEM, | ||
| 141 | .dev_type = DB8500_DMA_DEV42_SD_MM4, | ||
| 142 | }; | ||
| 143 | |||
| 144 | static struct stedma40_chan_cfg mop500_sdi4_dma_cfg_tx = { | ||
| 145 | .mode = STEDMA40_MODE_LOGICAL, | ||
| 146 | .dir = DMA_MEM_TO_DEV, | ||
| 147 | .dev_type = DB8500_DMA_DEV42_SD_MM4, | ||
| 148 | }; | ||
| 149 | #endif | ||
| 150 | |||
| 151 | struct mmci_platform_data mop500_sdi4_data = { | ||
| 152 | .f_max = 100000000, | ||
| 153 | .capabilities = MMC_CAP_4_BIT_DATA | | ||
| 154 | MMC_CAP_8_BIT_DATA | | ||
| 155 | MMC_CAP_NONREMOVABLE | | ||
| 156 | MMC_CAP_MMC_HIGHSPEED | | ||
| 157 | MMC_CAP_ERASE | | ||
| 158 | MMC_CAP_CMD23, | ||
| 159 | .gpio_cd = -1, | ||
| 160 | .gpio_wp = -1, | ||
| 161 | #ifdef CONFIG_STE_DMA40 | ||
| 162 | .dma_filter = stedma40_filter, | ||
| 163 | .dma_rx_param = &mop500_sdi4_dma_cfg_rx, | ||
| 164 | .dma_tx_param = &mop500_sdi4_dma_cfg_tx, | ||
| 165 | #endif | ||
| 166 | }; | ||
diff --git a/arch/arm/mach-ux500/board-mop500.h b/arch/arm/mach-ux500/board-mop500.h index 32cc0d8d8a0e..7c7b0adca582 100644 --- a/arch/arm/mach-ux500/board-mop500.h +++ b/arch/arm/mach-ux500/board-mop500.h | |||
| @@ -8,12 +8,7 @@ | |||
| 8 | #define __BOARD_MOP500_H | 8 | #define __BOARD_MOP500_H |
| 9 | 9 | ||
| 10 | #include <linux/platform_data/asoc-ux500-msp.h> | 10 | #include <linux/platform_data/asoc-ux500-msp.h> |
| 11 | #include <linux/amba/mmci.h> | ||
| 12 | 11 | ||
| 13 | extern struct mmci_platform_data mop500_sdi0_data; | ||
| 14 | extern struct mmci_platform_data mop500_sdi1_data; | ||
| 15 | extern struct mmci_platform_data mop500_sdi2_data; | ||
| 16 | extern struct mmci_platform_data mop500_sdi4_data; | ||
| 17 | extern struct msp_i2s_platform_data msp0_platform_data; | 12 | extern struct msp_i2s_platform_data msp0_platform_data; |
| 18 | extern struct msp_i2s_platform_data msp1_platform_data; | 13 | extern struct msp_i2s_platform_data msp1_platform_data; |
| 19 | extern struct msp_i2s_platform_data msp2_platform_data; | 14 | extern struct msp_i2s_platform_data msp2_platform_data; |
diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c index 8820f602fcd2..fa308f07fae5 100644 --- a/arch/arm/mach-ux500/cpu-db8500.c +++ b/arch/arm/mach-ux500/cpu-db8500.c | |||
| @@ -146,10 +146,6 @@ static struct of_dev_auxdata u8500_auxdata_lookup[] __initdata = { | |||
| 146 | /* Requires call-back bindings. */ | 146 | /* Requires call-back bindings. */ |
| 147 | OF_DEV_AUXDATA("arm,cortex-a9-pmu", 0, "arm-pmu", &db8500_pmu_platdata), | 147 | OF_DEV_AUXDATA("arm,cortex-a9-pmu", 0, "arm-pmu", &db8500_pmu_platdata), |
| 148 | /* Requires DMA bindings. */ | 148 | /* Requires DMA bindings. */ |
| 149 | OF_DEV_AUXDATA("arm,pl18x", 0x80126000, "sdi0", &mop500_sdi0_data), | ||
| 150 | OF_DEV_AUXDATA("arm,pl18x", 0x80118000, "sdi1", &mop500_sdi1_data), | ||
| 151 | OF_DEV_AUXDATA("arm,pl18x", 0x80005000, "sdi2", &mop500_sdi2_data), | ||
| 152 | OF_DEV_AUXDATA("arm,pl18x", 0x80114000, "sdi4", &mop500_sdi4_data), | ||
| 153 | OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80123000, | 149 | OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80123000, |
| 154 | "ux500-msp-i2s.0", &msp0_platform_data), | 150 | "ux500-msp-i2s.0", &msp0_platform_data), |
| 155 | OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80124000, | 151 | OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80124000, |
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 771c60ab4a32..a084edd37af5 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
| 14 | #include <linux/ioport.h> | 14 | #include <linux/ioport.h> |
| 15 | #include <linux/device.h> | 15 | #include <linux/device.h> |
| 16 | #include <linux/io.h> | ||
| 16 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
| 17 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
| 18 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
| @@ -23,6 +24,7 @@ | |||
| 23 | #include <linux/mmc/pm.h> | 24 | #include <linux/mmc/pm.h> |
| 24 | #include <linux/mmc/host.h> | 25 | #include <linux/mmc/host.h> |
| 25 | #include <linux/mmc/card.h> | 26 | #include <linux/mmc/card.h> |
| 27 | #include <linux/mmc/slot-gpio.h> | ||
| 26 | #include <linux/amba/bus.h> | 28 | #include <linux/amba/bus.h> |
| 27 | #include <linux/clk.h> | 29 | #include <linux/clk.h> |
| 28 | #include <linux/scatterlist.h> | 30 | #include <linux/scatterlist.h> |
| @@ -364,7 +366,6 @@ static void mmci_init_sg(struct mmci_host *host, struct mmc_data *data) | |||
| 364 | #ifdef CONFIG_DMA_ENGINE | 366 | #ifdef CONFIG_DMA_ENGINE |
| 365 | static void mmci_dma_setup(struct mmci_host *host) | 367 | static void mmci_dma_setup(struct mmci_host *host) |
| 366 | { | 368 | { |
| 367 | struct mmci_platform_data *plat = host->plat; | ||
| 368 | const char *rxname, *txname; | 369 | const char *rxname, *txname; |
| 369 | dma_cap_mask_t mask; | 370 | dma_cap_mask_t mask; |
| 370 | 371 | ||
| @@ -378,25 +379,6 @@ static void mmci_dma_setup(struct mmci_host *host) | |||
| 378 | dma_cap_zero(mask); | 379 | dma_cap_zero(mask); |
| 379 | dma_cap_set(DMA_SLAVE, mask); | 380 | dma_cap_set(DMA_SLAVE, mask); |
| 380 | 381 | ||
| 381 | if (plat && plat->dma_filter) { | ||
| 382 | if (!host->dma_rx_channel && plat->dma_rx_param) { | ||
| 383 | host->dma_rx_channel = dma_request_channel(mask, | ||
| 384 | plat->dma_filter, | ||
| 385 | plat->dma_rx_param); | ||
| 386 | /* E.g if no DMA hardware is present */ | ||
| 387 | if (!host->dma_rx_channel) | ||
| 388 | dev_err(mmc_dev(host->mmc), "no RX DMA channel\n"); | ||
| 389 | } | ||
| 390 | |||
| 391 | if (!host->dma_tx_channel && plat->dma_tx_param) { | ||
| 392 | host->dma_tx_channel = dma_request_channel(mask, | ||
| 393 | plat->dma_filter, | ||
| 394 | plat->dma_tx_param); | ||
| 395 | if (!host->dma_tx_channel) | ||
| 396 | dev_warn(mmc_dev(host->mmc), "no TX DMA channel\n"); | ||
| 397 | } | ||
| 398 | } | ||
| 399 | |||
| 400 | /* | 382 | /* |
| 401 | * If only an RX channel is specified, the driver will | 383 | * If only an RX channel is specified, the driver will |
| 402 | * attempt to use it bidirectionally, however if it is | 384 | * attempt to use it bidirectionally, however if it is |
| @@ -444,11 +426,9 @@ static void mmci_dma_setup(struct mmci_host *host) | |||
| 444 | */ | 426 | */ |
| 445 | static inline void mmci_dma_release(struct mmci_host *host) | 427 | static inline void mmci_dma_release(struct mmci_host *host) |
| 446 | { | 428 | { |
| 447 | struct mmci_platform_data *plat = host->plat; | ||
| 448 | |||
| 449 | if (host->dma_rx_channel) | 429 | if (host->dma_rx_channel) |
| 450 | dma_release_channel(host->dma_rx_channel); | 430 | dma_release_channel(host->dma_rx_channel); |
| 451 | if (host->dma_tx_channel && plat->dma_tx_param) | 431 | if (host->dma_tx_channel) |
| 452 | dma_release_channel(host->dma_tx_channel); | 432 | dma_release_channel(host->dma_tx_channel); |
| 453 | host->dma_rx_channel = host->dma_tx_channel = NULL; | 433 | host->dma_rx_channel = host->dma_tx_channel = NULL; |
| 454 | } | 434 | } |
| @@ -1285,7 +1265,7 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
| 1285 | * indicating signal direction for the signals in | 1265 | * indicating signal direction for the signals in |
| 1286 | * the SD/MMC bus and feedback-clock usage. | 1266 | * the SD/MMC bus and feedback-clock usage. |
| 1287 | */ | 1267 | */ |
| 1288 | pwr |= host->plat->sigdir; | 1268 | pwr |= host->pwr_reg_add; |
| 1289 | 1269 | ||
| 1290 | if (ios->bus_width == MMC_BUS_WIDTH_4) | 1270 | if (ios->bus_width == MMC_BUS_WIDTH_4) |
| 1291 | pwr &= ~MCI_ST_DATA74DIREN; | 1271 | pwr &= ~MCI_ST_DATA74DIREN; |
| @@ -1326,35 +1306,18 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
| 1326 | pm_runtime_put_autosuspend(mmc_dev(mmc)); | 1306 | pm_runtime_put_autosuspend(mmc_dev(mmc)); |
| 1327 | } | 1307 | } |
| 1328 | 1308 | ||
| 1329 | static int mmci_get_ro(struct mmc_host *mmc) | ||
| 1330 | { | ||
| 1331 | struct mmci_host *host = mmc_priv(mmc); | ||
| 1332 | |||
| 1333 | if (host->gpio_wp == -ENOSYS) | ||
| 1334 | return -ENOSYS; | ||
| 1335 | |||
| 1336 | return gpio_get_value_cansleep(host->gpio_wp); | ||
| 1337 | } | ||
| 1338 | |||
| 1339 | static int mmci_get_cd(struct mmc_host *mmc) | 1309 | static int mmci_get_cd(struct mmc_host *mmc) |
| 1340 | { | 1310 | { |
| 1341 | struct mmci_host *host = mmc_priv(mmc); | 1311 | struct mmci_host *host = mmc_priv(mmc); |
| 1342 | struct mmci_platform_data *plat = host->plat; | 1312 | struct mmci_platform_data *plat = host->plat; |
| 1343 | unsigned int status; | 1313 | unsigned int status = mmc_gpio_get_cd(mmc); |
| 1344 | 1314 | ||
| 1345 | if (host->gpio_cd == -ENOSYS) { | 1315 | if (status == -ENOSYS) { |
| 1346 | if (!plat->status) | 1316 | if (!plat->status) |
| 1347 | return 1; /* Assume always present */ | 1317 | return 1; /* Assume always present */ |
| 1348 | 1318 | ||
| 1349 | status = plat->status(mmc_dev(host->mmc)); | 1319 | status = plat->status(mmc_dev(host->mmc)); |
| 1350 | } else | 1320 | } |
| 1351 | status = !!gpio_get_value_cansleep(host->gpio_cd) | ||
| 1352 | ^ plat->cd_invert; | ||
| 1353 | |||
| 1354 | /* | ||
| 1355 | * Use positive logic throughout - status is zero for no card, | ||
| 1356 | * non-zero for card inserted. | ||
| 1357 | */ | ||
| 1358 | return status; | 1321 | return status; |
| 1359 | } | 1322 | } |
| 1360 | 1323 | ||
| @@ -1391,70 +1354,44 @@ static int mmci_sig_volt_switch(struct mmc_host *mmc, struct mmc_ios *ios) | |||
| 1391 | return ret; | 1354 | return ret; |
| 1392 | } | 1355 | } |
| 1393 | 1356 | ||
| 1394 | static irqreturn_t mmci_cd_irq(int irq, void *dev_id) | ||
| 1395 | { | ||
| 1396 | struct mmci_host *host = dev_id; | ||
| 1397 | |||
| 1398 | mmc_detect_change(host->mmc, msecs_to_jiffies(500)); | ||
| 1399 | |||
| 1400 | return IRQ_HANDLED; | ||
| 1401 | } | ||
| 1402 | |||
| 1403 | static struct mmc_host_ops mmci_ops = { | 1357 | static struct mmc_host_ops mmci_ops = { |
| 1404 | .request = mmci_request, | 1358 | .request = mmci_request, |
| 1405 | .pre_req = mmci_pre_request, | 1359 | .pre_req = mmci_pre_request, |
| 1406 | .post_req = mmci_post_request, | 1360 | .post_req = mmci_post_request, |
| 1407 | .set_ios = mmci_set_ios, | 1361 | .set_ios = mmci_set_ios, |
| 1408 | .get_ro = mmci_get_ro, | 1362 | .get_ro = mmc_gpio_get_ro, |
| 1409 | .get_cd = mmci_get_cd, | 1363 | .get_cd = mmci_get_cd, |
| 1410 | .start_signal_voltage_switch = mmci_sig_volt_switch, | 1364 | .start_signal_voltage_switch = mmci_sig_volt_switch, |
| 1411 | }; | 1365 | }; |
| 1412 | 1366 | ||
| 1413 | #ifdef CONFIG_OF | 1367 | static int mmci_of_parse(struct device_node *np, struct mmc_host *mmc) |
| 1414 | static void mmci_dt_populate_generic_pdata(struct device_node *np, | ||
| 1415 | struct mmci_platform_data *pdata) | ||
| 1416 | { | 1368 | { |
| 1417 | int bus_width = 0; | 1369 | struct mmci_host *host = mmc_priv(mmc); |
| 1418 | 1370 | int ret = mmc_of_parse(mmc); | |
| 1419 | pdata->gpio_wp = of_get_named_gpio(np, "wp-gpios", 0); | ||
| 1420 | pdata->gpio_cd = of_get_named_gpio(np, "cd-gpios", 0); | ||
| 1421 | 1371 | ||
| 1422 | if (of_get_property(np, "cd-inverted", NULL)) | 1372 | if (ret) |
| 1423 | pdata->cd_invert = true; | 1373 | return ret; |
| 1424 | else | ||
| 1425 | pdata->cd_invert = false; | ||
| 1426 | 1374 | ||
| 1427 | of_property_read_u32(np, "max-frequency", &pdata->f_max); | 1375 | if (of_get_property(np, "st,sig-dir-dat0", NULL)) |
| 1428 | if (!pdata->f_max) | 1376 | host->pwr_reg_add |= MCI_ST_DATA0DIREN; |
| 1429 | pr_warn("%s has no 'max-frequency' property\n", np->full_name); | 1377 | if (of_get_property(np, "st,sig-dir-dat2", NULL)) |
| 1378 | host->pwr_reg_add |= MCI_ST_DATA2DIREN; | ||
| 1379 | if (of_get_property(np, "st,sig-dir-dat31", NULL)) | ||
| 1380 | host->pwr_reg_add |= MCI_ST_DATA31DIREN; | ||
| 1381 | if (of_get_property(np, "st,sig-dir-dat74", NULL)) | ||
| 1382 | host->pwr_reg_add |= MCI_ST_DATA74DIREN; | ||
| 1383 | if (of_get_property(np, "st,sig-dir-cmd", NULL)) | ||
| 1384 | host->pwr_reg_add |= MCI_ST_CMDDIREN; | ||
| 1385 | if (of_get_property(np, "st,sig-pin-fbclk", NULL)) | ||
| 1386 | host->pwr_reg_add |= MCI_ST_FBCLKEN; | ||
| 1430 | 1387 | ||
| 1431 | if (of_get_property(np, "mmc-cap-mmc-highspeed", NULL)) | 1388 | if (of_get_property(np, "mmc-cap-mmc-highspeed", NULL)) |
| 1432 | pdata->capabilities |= MMC_CAP_MMC_HIGHSPEED; | 1389 | mmc->caps |= MMC_CAP_MMC_HIGHSPEED; |
| 1433 | if (of_get_property(np, "mmc-cap-sd-highspeed", NULL)) | 1390 | if (of_get_property(np, "mmc-cap-sd-highspeed", NULL)) |
| 1434 | pdata->capabilities |= MMC_CAP_SD_HIGHSPEED; | 1391 | mmc->caps |= MMC_CAP_SD_HIGHSPEED; |
| 1435 | 1392 | ||
| 1436 | of_property_read_u32(np, "bus-width", &bus_width); | 1393 | return 0; |
| 1437 | switch (bus_width) { | ||
| 1438 | case 0 : | ||
| 1439 | /* No bus-width supplied. */ | ||
| 1440 | break; | ||
| 1441 | case 4 : | ||
| 1442 | pdata->capabilities |= MMC_CAP_4_BIT_DATA; | ||
| 1443 | break; | ||
| 1444 | case 8 : | ||
| 1445 | pdata->capabilities |= MMC_CAP_8_BIT_DATA; | ||
| 1446 | break; | ||
| 1447 | default : | ||
| 1448 | pr_warn("%s: Unsupported bus width\n", np->full_name); | ||
| 1449 | } | ||
| 1450 | } | ||
| 1451 | #else | ||
| 1452 | static void mmci_dt_populate_generic_pdata(struct device_node *np, | ||
| 1453 | struct mmci_platform_data *pdata) | ||
| 1454 | { | ||
| 1455 | return; | ||
| 1456 | } | 1394 | } |
| 1457 | #endif | ||
| 1458 | 1395 | ||
| 1459 | static int mmci_probe(struct amba_device *dev, | 1396 | static int mmci_probe(struct amba_device *dev, |
| 1460 | const struct amba_id *id) | 1397 | const struct amba_id *id) |
| @@ -1478,26 +1415,17 @@ static int mmci_probe(struct amba_device *dev, | |||
| 1478 | return -ENOMEM; | 1415 | return -ENOMEM; |
| 1479 | } | 1416 | } |
| 1480 | 1417 | ||
| 1481 | if (np) | 1418 | mmc = mmc_alloc_host(sizeof(struct mmci_host), &dev->dev); |
| 1482 | mmci_dt_populate_generic_pdata(np, plat); | 1419 | if (!mmc) |
| 1420 | return -ENOMEM; | ||
| 1483 | 1421 | ||
| 1484 | ret = amba_request_regions(dev, DRIVER_NAME); | 1422 | ret = mmci_of_parse(np, mmc); |
| 1485 | if (ret) | 1423 | if (ret) |
| 1486 | goto out; | 1424 | goto host_free; |
| 1487 | |||
| 1488 | mmc = mmc_alloc_host(sizeof(struct mmci_host), &dev->dev); | ||
| 1489 | if (!mmc) { | ||
| 1490 | ret = -ENOMEM; | ||
| 1491 | goto rel_regions; | ||
| 1492 | } | ||
| 1493 | 1425 | ||
| 1494 | host = mmc_priv(mmc); | 1426 | host = mmc_priv(mmc); |
| 1495 | host->mmc = mmc; | 1427 | host->mmc = mmc; |
| 1496 | 1428 | ||
| 1497 | host->gpio_wp = -ENOSYS; | ||
| 1498 | host->gpio_cd = -ENOSYS; | ||
| 1499 | host->gpio_cd_irq = -1; | ||
| 1500 | |||
| 1501 | host->hw_designer = amba_manf(dev); | 1429 | host->hw_designer = amba_manf(dev); |
| 1502 | host->hw_revision = amba_rev(dev); | 1430 | host->hw_revision = amba_rev(dev); |
| 1503 | dev_dbg(mmc_dev(mmc), "designer ID = 0x%02x\n", host->hw_designer); | 1431 | dev_dbg(mmc_dev(mmc), "designer ID = 0x%02x\n", host->hw_designer); |
| @@ -1529,10 +1457,11 @@ static int mmci_probe(struct amba_device *dev, | |||
| 1529 | dev_dbg(mmc_dev(mmc), "eventual mclk rate: %u Hz\n", | 1457 | dev_dbg(mmc_dev(mmc), "eventual mclk rate: %u Hz\n", |
| 1530 | host->mclk); | 1458 | host->mclk); |
| 1531 | } | 1459 | } |
| 1460 | |||
| 1532 | host->phybase = dev->res.start; | 1461 | host->phybase = dev->res.start; |
| 1533 | host->base = ioremap(dev->res.start, resource_size(&dev->res)); | 1462 | host->base = devm_ioremap_resource(&dev->dev, &dev->res); |
| 1534 | if (!host->base) { | 1463 | if (IS_ERR(host->base)) { |
| 1535 | ret = -ENOMEM; | 1464 | ret = PTR_ERR(host->base); |
| 1536 | goto clk_disable; | 1465 | goto clk_disable; |
| 1537 | } | 1466 | } |
| 1538 | 1467 | ||
| @@ -1546,15 +1475,13 @@ static int mmci_probe(struct amba_device *dev, | |||
| 1546 | else | 1475 | else |
| 1547 | mmc->f_min = DIV_ROUND_UP(host->mclk, 512); | 1476 | mmc->f_min = DIV_ROUND_UP(host->mclk, 512); |
| 1548 | /* | 1477 | /* |
| 1549 | * If the platform data supplies a maximum operating | 1478 | * If no maximum operating frequency is supplied, fall back to use |
| 1550 | * frequency, this takes precedence. Else, we fall back | 1479 | * the module parameter, which has a (low) default value in case it |
| 1551 | * to using the module parameter, which has a (low) | 1480 | * is not specified. Either value must not exceed the clock rate into |
| 1552 | * default value in case it is not specified. Either | 1481 | * the block, of course. |
| 1553 | * value must not exceed the clock rate into the block, | ||
| 1554 | * of course. | ||
| 1555 | */ | 1482 | */ |
| 1556 | if (plat->f_max) | 1483 | if (mmc->f_max) |
| 1557 | mmc->f_max = min(host->mclk, plat->f_max); | 1484 | mmc->f_max = min(host->mclk, mmc->f_max); |
| 1558 | else | 1485 | else |
| 1559 | mmc->f_max = min(host->mclk, fmax); | 1486 | mmc->f_max = min(host->mclk, fmax); |
| 1560 | dev_dbg(mmc_dev(mmc), "clocking block at %u Hz\n", mmc->f_max); | 1487 | dev_dbg(mmc_dev(mmc), "clocking block at %u Hz\n", mmc->f_max); |
| @@ -1566,8 +1493,15 @@ static int mmci_probe(struct amba_device *dev, | |||
| 1566 | else if (plat->ocr_mask) | 1493 | else if (plat->ocr_mask) |
| 1567 | dev_warn(mmc_dev(mmc), "Platform OCR mask is ignored\n"); | 1494 | dev_warn(mmc_dev(mmc), "Platform OCR mask is ignored\n"); |
| 1568 | 1495 | ||
| 1569 | mmc->caps = plat->capabilities; | 1496 | /* DT takes precedence over platform data. */ |
| 1570 | mmc->caps2 = plat->capabilities2; | 1497 | if (!np) { |
| 1498 | if (!plat->cd_invert) | ||
| 1499 | mmc->caps2 |= MMC_CAP2_CD_ACTIVE_HIGH; | ||
| 1500 | mmc->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH; | ||
| 1501 | } | ||
| 1502 | |||
| 1503 | /* We support these capabilities. */ | ||
| 1504 | mmc->caps |= MMC_CAP_CMD23; | ||
| 1571 | 1505 | ||
| 1572 | if (variant->busy_detect) { | 1506 | if (variant->busy_detect) { |
| 1573 | mmci_ops.card_busy = mmci_card_busy; | 1507 | mmci_ops.card_busy = mmci_card_busy; |
| @@ -1579,7 +1513,7 @@ static int mmci_probe(struct amba_device *dev, | |||
| 1579 | mmc->ops = &mmci_ops; | 1513 | mmc->ops = &mmci_ops; |
| 1580 | 1514 | ||
| 1581 | /* We support these PM capabilities. */ | 1515 | /* We support these PM capabilities. */ |
| 1582 | mmc->pm_caps = MMC_PM_KEEP_POWER; | 1516 | mmc->pm_caps |= MMC_PM_KEEP_POWER; |
| 1583 | 1517 | ||
| 1584 | /* | 1518 | /* |
| 1585 | * We can do SGIO | 1519 | * We can do SGIO |
| @@ -1616,62 +1550,30 @@ static int mmci_probe(struct amba_device *dev, | |||
| 1616 | writel(0, host->base + MMCIMASK1); | 1550 | writel(0, host->base + MMCIMASK1); |
| 1617 | writel(0xfff, host->base + MMCICLEAR); | 1551 | writel(0xfff, host->base + MMCICLEAR); |
| 1618 | 1552 | ||
| 1619 | if (plat->gpio_cd == -EPROBE_DEFER) { | 1553 | /* If DT, cd/wp gpios must be supplied through it. */ |
| 1620 | ret = -EPROBE_DEFER; | 1554 | if (!np && gpio_is_valid(plat->gpio_cd)) { |
| 1621 | goto err_gpio_cd; | 1555 | ret = mmc_gpio_request_cd(mmc, plat->gpio_cd, 0); |
| 1622 | } | 1556 | if (ret) |
| 1623 | if (gpio_is_valid(plat->gpio_cd)) { | 1557 | goto clk_disable; |
| 1624 | ret = gpio_request(plat->gpio_cd, DRIVER_NAME " (cd)"); | ||
| 1625 | if (ret == 0) | ||
| 1626 | ret = gpio_direction_input(plat->gpio_cd); | ||
| 1627 | if (ret == 0) | ||
| 1628 | host->gpio_cd = plat->gpio_cd; | ||
| 1629 | else if (ret != -ENOSYS) | ||
| 1630 | goto err_gpio_cd; | ||
| 1631 | |||
| 1632 | /* | ||
| 1633 | * A gpio pin that will detect cards when inserted and removed | ||
| 1634 | * will most likely want to trigger on the edges if it is | ||
| 1635 | * 0 when ejected and 1 when inserted (or mutatis mutandis | ||
| 1636 | * for the inverted case) so we request triggers on both | ||
| 1637 | * edges. | ||
| 1638 | */ | ||
| 1639 | ret = request_any_context_irq(gpio_to_irq(plat->gpio_cd), | ||
| 1640 | mmci_cd_irq, | ||
| 1641 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | ||
| 1642 | DRIVER_NAME " (cd)", host); | ||
| 1643 | if (ret >= 0) | ||
| 1644 | host->gpio_cd_irq = gpio_to_irq(plat->gpio_cd); | ||
| 1645 | } | ||
| 1646 | if (plat->gpio_wp == -EPROBE_DEFER) { | ||
| 1647 | ret = -EPROBE_DEFER; | ||
| 1648 | goto err_gpio_wp; | ||
| 1649 | } | 1558 | } |
| 1650 | if (gpio_is_valid(plat->gpio_wp)) { | 1559 | if (!np && gpio_is_valid(plat->gpio_wp)) { |
| 1651 | ret = gpio_request(plat->gpio_wp, DRIVER_NAME " (wp)"); | 1560 | ret = mmc_gpio_request_ro(mmc, plat->gpio_wp); |
| 1652 | if (ret == 0) | 1561 | if (ret) |
| 1653 | ret = gpio_direction_input(plat->gpio_wp); | 1562 | goto clk_disable; |
| 1654 | if (ret == 0) | ||
| 1655 | host->gpio_wp = plat->gpio_wp; | ||
| 1656 | else if (ret != -ENOSYS) | ||
| 1657 | goto err_gpio_wp; | ||
| 1658 | } | 1563 | } |
| 1659 | 1564 | ||
| 1660 | if ((host->plat->status || host->gpio_cd != -ENOSYS) | 1565 | ret = devm_request_irq(&dev->dev, dev->irq[0], mmci_irq, IRQF_SHARED, |
| 1661 | && host->gpio_cd_irq < 0) | 1566 | DRIVER_NAME " (cmd)", host); |
| 1662 | mmc->caps |= MMC_CAP_NEEDS_POLL; | ||
| 1663 | |||
| 1664 | ret = request_irq(dev->irq[0], mmci_irq, IRQF_SHARED, DRIVER_NAME " (cmd)", host); | ||
| 1665 | if (ret) | 1567 | if (ret) |
| 1666 | goto unmap; | 1568 | goto clk_disable; |
| 1667 | 1569 | ||
| 1668 | if (!dev->irq[1]) | 1570 | if (!dev->irq[1]) |
| 1669 | host->singleirq = true; | 1571 | host->singleirq = true; |
| 1670 | else { | 1572 | else { |
| 1671 | ret = request_irq(dev->irq[1], mmci_pio_irq, IRQF_SHARED, | 1573 | ret = devm_request_irq(&dev->dev, dev->irq[1], mmci_pio_irq, |
| 1672 | DRIVER_NAME " (pio)", host); | 1574 | IRQF_SHARED, DRIVER_NAME " (pio)", host); |
| 1673 | if (ret) | 1575 | if (ret) |
| 1674 | goto irq0_free; | 1576 | goto clk_disable; |
| 1675 | } | 1577 | } |
| 1676 | 1578 | ||
| 1677 | writel(MCI_IRQENABLE, host->base + MMCIMASK0); | 1579 | writel(MCI_IRQENABLE, host->base + MMCIMASK0); |
| @@ -1693,25 +1595,10 @@ static int mmci_probe(struct amba_device *dev, | |||
| 1693 | 1595 | ||
| 1694 | return 0; | 1596 | return 0; |
| 1695 | 1597 | ||
| 1696 | irq0_free: | ||
| 1697 | free_irq(dev->irq[0], host); | ||
| 1698 | unmap: | ||
| 1699 | if (host->gpio_wp != -ENOSYS) | ||
| 1700 | gpio_free(host->gpio_wp); | ||
| 1701 | err_gpio_wp: | ||
| 1702 | if (host->gpio_cd_irq >= 0) | ||
| 1703 | free_irq(host->gpio_cd_irq, host); | ||
| 1704 | if (host->gpio_cd != -ENOSYS) | ||
| 1705 | gpio_free(host->gpio_cd); | ||
| 1706 | err_gpio_cd: | ||
| 1707 | iounmap(host->base); | ||
| 1708 | clk_disable: | 1598 | clk_disable: |
| 1709 | clk_disable_unprepare(host->clk); | 1599 | clk_disable_unprepare(host->clk); |
| 1710 | host_free: | 1600 | host_free: |
| 1711 | mmc_free_host(mmc); | 1601 | mmc_free_host(mmc); |
| 1712 | rel_regions: | ||
| 1713 | amba_release_regions(dev); | ||
| 1714 | out: | ||
| 1715 | return ret; | 1602 | return ret; |
| 1716 | } | 1603 | } |
| 1717 | 1604 | ||
| @@ -1737,92 +1624,46 @@ static int mmci_remove(struct amba_device *dev) | |||
| 1737 | writel(0, host->base + MMCIDATACTRL); | 1624 | writel(0, host->base + MMCIDATACTRL); |
| 1738 | 1625 | ||
| 1739 | mmci_dma_release(host); | 1626 | mmci_dma_release(host); |
| 1740 | free_irq(dev->irq[0], host); | ||
| 1741 | if (!host->singleirq) | ||
| 1742 | free_irq(dev->irq[1], host); | ||
| 1743 | |||
| 1744 | if (host->gpio_wp != -ENOSYS) | ||
| 1745 | gpio_free(host->gpio_wp); | ||
| 1746 | if (host->gpio_cd_irq >= 0) | ||
| 1747 | free_irq(host->gpio_cd_irq, host); | ||
| 1748 | if (host->gpio_cd != -ENOSYS) | ||
| 1749 | gpio_free(host->gpio_cd); | ||
| 1750 | |||
| 1751 | iounmap(host->base); | ||
| 1752 | clk_disable_unprepare(host->clk); | 1627 | clk_disable_unprepare(host->clk); |
| 1753 | |||
| 1754 | mmc_free_host(mmc); | 1628 | mmc_free_host(mmc); |
| 1755 | |||
| 1756 | amba_release_regions(dev); | ||
| 1757 | } | ||
| 1758 | |||
| 1759 | return 0; | ||
| 1760 | } | ||
| 1761 | |||
| 1762 | #ifdef CONFIG_SUSPEND | ||
| 1763 | static int mmci_suspend(struct device *dev) | ||
| 1764 | { | ||
| 1765 | struct amba_device *adev = to_amba_device(dev); | ||
| 1766 | struct mmc_host *mmc = amba_get_drvdata(adev); | ||
| 1767 | |||
| 1768 | if (mmc) { | ||
| 1769 | struct mmci_host *host = mmc_priv(mmc); | ||
| 1770 | pm_runtime_get_sync(dev); | ||
| 1771 | writel(0, host->base + MMCIMASK0); | ||
| 1772 | } | 1629 | } |
| 1773 | 1630 | ||
| 1774 | return 0; | 1631 | return 0; |
| 1775 | } | 1632 | } |
| 1776 | 1633 | ||
| 1777 | static int mmci_resume(struct device *dev) | 1634 | #ifdef CONFIG_PM |
| 1778 | { | ||
| 1779 | struct amba_device *adev = to_amba_device(dev); | ||
| 1780 | struct mmc_host *mmc = amba_get_drvdata(adev); | ||
| 1781 | |||
| 1782 | if (mmc) { | ||
| 1783 | struct mmci_host *host = mmc_priv(mmc); | ||
| 1784 | writel(MCI_IRQENABLE, host->base + MMCIMASK0); | ||
| 1785 | pm_runtime_put(dev); | ||
| 1786 | } | ||
| 1787 | |||
| 1788 | return 0; | ||
| 1789 | } | ||
| 1790 | #endif | ||
| 1791 | |||
| 1792 | #ifdef CONFIG_PM_RUNTIME | ||
| 1793 | static void mmci_save(struct mmci_host *host) | 1635 | static void mmci_save(struct mmci_host *host) |
| 1794 | { | 1636 | { |
| 1795 | unsigned long flags; | 1637 | unsigned long flags; |
| 1796 | 1638 | ||
| 1797 | if (host->variant->pwrreg_nopower) { | 1639 | spin_lock_irqsave(&host->lock, flags); |
| 1798 | spin_lock_irqsave(&host->lock, flags); | ||
| 1799 | 1640 | ||
| 1800 | writel(0, host->base + MMCIMASK0); | 1641 | writel(0, host->base + MMCIMASK0); |
| 1642 | if (host->variant->pwrreg_nopower) { | ||
| 1801 | writel(0, host->base + MMCIDATACTRL); | 1643 | writel(0, host->base + MMCIDATACTRL); |
| 1802 | writel(0, host->base + MMCIPOWER); | 1644 | writel(0, host->base + MMCIPOWER); |
| 1803 | writel(0, host->base + MMCICLOCK); | 1645 | writel(0, host->base + MMCICLOCK); |
| 1804 | mmci_reg_delay(host); | ||
| 1805 | |||
| 1806 | spin_unlock_irqrestore(&host->lock, flags); | ||
| 1807 | } | 1646 | } |
| 1647 | mmci_reg_delay(host); | ||
| 1808 | 1648 | ||
| 1649 | spin_unlock_irqrestore(&host->lock, flags); | ||
| 1809 | } | 1650 | } |
| 1810 | 1651 | ||
| 1811 | static void mmci_restore(struct mmci_host *host) | 1652 | static void mmci_restore(struct mmci_host *host) |
| 1812 | { | 1653 | { |
| 1813 | unsigned long flags; | 1654 | unsigned long flags; |
| 1814 | 1655 | ||
| 1815 | if (host->variant->pwrreg_nopower) { | 1656 | spin_lock_irqsave(&host->lock, flags); |
| 1816 | spin_lock_irqsave(&host->lock, flags); | ||
| 1817 | 1657 | ||
| 1658 | if (host->variant->pwrreg_nopower) { | ||
| 1818 | writel(host->clk_reg, host->base + MMCICLOCK); | 1659 | writel(host->clk_reg, host->base + MMCICLOCK); |
| 1819 | writel(host->datactrl_reg, host->base + MMCIDATACTRL); | 1660 | writel(host->datactrl_reg, host->base + MMCIDATACTRL); |
| 1820 | writel(host->pwr_reg, host->base + MMCIPOWER); | 1661 | writel(host->pwr_reg, host->base + MMCIPOWER); |
| 1821 | writel(MCI_IRQENABLE, host->base + MMCIMASK0); | ||
| 1822 | mmci_reg_delay(host); | ||
| 1823 | |||
| 1824 | spin_unlock_irqrestore(&host->lock, flags); | ||
| 1825 | } | 1662 | } |
| 1663 | writel(MCI_IRQENABLE, host->base + MMCIMASK0); | ||
| 1664 | mmci_reg_delay(host); | ||
| 1665 | |||
| 1666 | spin_unlock_irqrestore(&host->lock, flags); | ||
| 1826 | } | 1667 | } |
| 1827 | 1668 | ||
| 1828 | static int mmci_runtime_suspend(struct device *dev) | 1669 | static int mmci_runtime_suspend(struct device *dev) |
| @@ -1857,8 +1698,9 @@ static int mmci_runtime_resume(struct device *dev) | |||
| 1857 | #endif | 1698 | #endif |
| 1858 | 1699 | ||
| 1859 | static const struct dev_pm_ops mmci_dev_pm_ops = { | 1700 | static const struct dev_pm_ops mmci_dev_pm_ops = { |
| 1860 | SET_SYSTEM_SLEEP_PM_OPS(mmci_suspend, mmci_resume) | 1701 | SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, |
| 1861 | SET_RUNTIME_PM_OPS(mmci_runtime_suspend, mmci_runtime_resume, NULL) | 1702 | pm_runtime_force_resume) |
| 1703 | SET_PM_RUNTIME_PM_OPS(mmci_runtime_suspend, mmci_runtime_resume, NULL) | ||
| 1862 | }; | 1704 | }; |
| 1863 | 1705 | ||
| 1864 | static struct amba_id mmci_ids[] = { | 1706 | static struct amba_id mmci_ids[] = { |
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h index 58b1b8896bf2..347d942d740b 100644 --- a/drivers/mmc/host/mmci.h +++ b/drivers/mmc/host/mmci.h | |||
| @@ -13,6 +13,16 @@ | |||
| 13 | #define MCI_PWR_ON 0x03 | 13 | #define MCI_PWR_ON 0x03 |
| 14 | #define MCI_OD (1 << 6) | 14 | #define MCI_OD (1 << 6) |
| 15 | #define MCI_ROD (1 << 7) | 15 | #define MCI_ROD (1 << 7) |
| 16 | /* | ||
| 17 | * The ST Micro version does not have ROD and reuse the voltage registers for | ||
| 18 | * direction settings. | ||
| 19 | */ | ||
| 20 | #define MCI_ST_DATA2DIREN (1 << 2) | ||
| 21 | #define MCI_ST_CMDDIREN (1 << 3) | ||
| 22 | #define MCI_ST_DATA0DIREN (1 << 4) | ||
| 23 | #define MCI_ST_DATA31DIREN (1 << 5) | ||
| 24 | #define MCI_ST_FBCLKEN (1 << 7) | ||
| 25 | #define MCI_ST_DATA74DIREN (1 << 8) | ||
| 16 | 26 | ||
| 17 | #define MMCICLOCK 0x004 | 27 | #define MMCICLOCK 0x004 |
| 18 | #define MCI_CLK_ENABLE (1 << 8) | 28 | #define MCI_CLK_ENABLE (1 << 8) |
| @@ -176,9 +186,6 @@ struct mmci_host { | |||
| 176 | struct mmc_data *data; | 186 | struct mmc_data *data; |
| 177 | struct mmc_host *mmc; | 187 | struct mmc_host *mmc; |
| 178 | struct clk *clk; | 188 | struct clk *clk; |
| 179 | int gpio_cd; | ||
| 180 | int gpio_wp; | ||
| 181 | int gpio_cd_irq; | ||
| 182 | bool singleirq; | 189 | bool singleirq; |
| 183 | 190 | ||
| 184 | spinlock_t lock; | 191 | spinlock_t lock; |
| @@ -186,6 +193,7 @@ struct mmci_host { | |||
| 186 | unsigned int mclk; | 193 | unsigned int mclk; |
| 187 | unsigned int cclk; | 194 | unsigned int cclk; |
| 188 | u32 pwr_reg; | 195 | u32 pwr_reg; |
| 196 | u32 pwr_reg_add; | ||
| 189 | u32 clk_reg; | 197 | u32 clk_reg; |
| 190 | u32 datactrl_reg; | 198 | u32 datactrl_reg; |
| 191 | u32 busy_status; | 199 | u32 busy_status; |
diff --git a/include/linux/amba/mmci.h b/include/linux/amba/mmci.h index 32a89cf5ec45..8c98113069ce 100644 --- a/include/linux/amba/mmci.h +++ b/include/linux/amba/mmci.h | |||
| @@ -6,28 +6,9 @@ | |||
| 6 | 6 | ||
| 7 | #include <linux/mmc/host.h> | 7 | #include <linux/mmc/host.h> |
| 8 | 8 | ||
| 9 | |||
| 10 | /* | ||
| 11 | * These defines is places here due to access is needed from machine | ||
| 12 | * configuration files. The ST Micro version does not have ROD and | ||
| 13 | * reuse the voltage registers for direction settings. | ||
| 14 | */ | ||
| 15 | #define MCI_ST_DATA2DIREN (1 << 2) | ||
| 16 | #define MCI_ST_CMDDIREN (1 << 3) | ||
| 17 | #define MCI_ST_DATA0DIREN (1 << 4) | ||
| 18 | #define MCI_ST_DATA31DIREN (1 << 5) | ||
| 19 | #define MCI_ST_FBCLKEN (1 << 7) | ||
| 20 | #define MCI_ST_DATA74DIREN (1 << 8) | ||
| 21 | |||
| 22 | /* Just some dummy forwarding */ | ||
| 23 | struct dma_chan; | ||
| 24 | |||
| 25 | /** | 9 | /** |
| 26 | * struct mmci_platform_data - platform configuration for the MMCI | 10 | * struct mmci_platform_data - platform configuration for the MMCI |
| 27 | * (also known as PL180) block. | 11 | * (also known as PL180) block. |
| 28 | * @f_max: the maximum operational frequency for this host in this | ||
| 29 | * platform configuration. When this is specified it takes precedence | ||
| 30 | * over the module parameter for the same frequency. | ||
| 31 | * @ocr_mask: available voltages on the 4 pins from the block, this | 12 | * @ocr_mask: available voltages on the 4 pins from the block, this |
| 32 | * is ignored if a regulator is used, see the MMC_VDD_* masks in | 13 | * is ignored if a regulator is used, see the MMC_VDD_* masks in |
| 33 | * mmc/host.h | 14 | * mmc/host.h |
| @@ -42,37 +23,14 @@ struct dma_chan; | |||
| 42 | * @gpio_wp: read this GPIO pin to see if the card is write protected | 23 | * @gpio_wp: read this GPIO pin to see if the card is write protected |
| 43 | * @gpio_cd: read this GPIO pin to detect card insertion | 24 | * @gpio_cd: read this GPIO pin to detect card insertion |
| 44 | * @cd_invert: true if the gpio_cd pin value is active low | 25 | * @cd_invert: true if the gpio_cd pin value is active low |
| 45 | * @capabilities: the capabilities of the block as implemented in | ||
| 46 | * this platform, signify anything MMC_CAP_* from mmc/host.h | ||
| 47 | * @capabilities2: more capabilities, MMC_CAP2_* from mmc/host.h | ||
| 48 | * @sigdir: a bit field indicating for what bits in the MMC bus the host | ||
| 49 | * should enable signal direction indication. | ||
| 50 | * @dma_filter: function used to select an appropriate RX and TX | ||
| 51 | * DMA channel to be used for DMA, if and only if you're deploying the | ||
| 52 | * generic DMA engine | ||
| 53 | * @dma_rx_param: parameter passed to the DMA allocation | ||
| 54 | * filter in order to select an appropriate RX channel. If | ||
| 55 | * there is a bidirectional RX+TX channel, then just specify | ||
| 56 | * this and leave dma_tx_param set to NULL | ||
| 57 | * @dma_tx_param: parameter passed to the DMA allocation | ||
| 58 | * filter in order to select an appropriate TX channel. If this | ||
| 59 | * is NULL the driver will attempt to use the RX channel as a | ||
| 60 | * bidirectional channel | ||
| 61 | */ | 26 | */ |
| 62 | struct mmci_platform_data { | 27 | struct mmci_platform_data { |
| 63 | unsigned int f_max; | ||
| 64 | unsigned int ocr_mask; | 28 | unsigned int ocr_mask; |
| 65 | int (*ios_handler)(struct device *, struct mmc_ios *); | 29 | int (*ios_handler)(struct device *, struct mmc_ios *); |
| 66 | unsigned int (*status)(struct device *); | 30 | unsigned int (*status)(struct device *); |
| 67 | int gpio_wp; | 31 | int gpio_wp; |
| 68 | int gpio_cd; | 32 | int gpio_cd; |
| 69 | bool cd_invert; | 33 | bool cd_invert; |
| 70 | unsigned long capabilities; | ||
| 71 | unsigned long capabilities2; | ||
| 72 | u32 sigdir; | ||
| 73 | bool (*dma_filter)(struct dma_chan *chan, void *filter_param); | ||
| 74 | void *dma_rx_param; | ||
| 75 | void *dma_tx_param; | ||
| 76 | }; | 34 | }; |
| 77 | 35 | ||
| 78 | #endif | 36 | #endif |
