Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ARM: 7219/1: mmc: mmci: Change vdd_handler to a generic ios_handler

The purpose of the vdd_handler does not make sense. We remove it
and use a generic approach instead. A new ios_handler is added, the
purpose of which e.g. can be to control GPIO pins to a levelshifter.

Previously the vdd_handler was also used for making additional
changes to the power register bits. This option is superfluous and is
therefore removed.

Adaptaptions from the old vdd_handler to the new ios_handler is done for
mach-ux500 board, which was the only one using the vdd_handler.

This patch is based upon a patch from Sebastian Rasmussen.

Tested-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Sebastian Rasmussen <sebastian.rasmussen@stericsson.com>
Signed-off-by: Ulf Hansson <ulf.hansson@stericsson.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>

authored by

Ulf Hansson and committed by
Russell King
bc521818 4d1a3a0d

+15 -20
+8 -13
arch/arm/mach-ux500/board-mop500-sdi.c
··· 31 31 * SDI 0 (MicroSD slot) 32 32 */ 33 33 34 - /* MMCIPOWER bits */ 35 - #define MCI_DATA2DIREN (1 << 2) 36 - #define MCI_CMDDIREN (1 << 3) 37 - #define MCI_DATA0DIREN (1 << 4) 38 - #define MCI_DATA31DIREN (1 << 5) 39 - #define MCI_FBCLKEN (1 << 7) 40 - 41 34 /* GPIO pins used by the sdi0 level shifter */ 42 35 static int sdi0_en = -1; 43 36 static int sdi0_vsel = -1; 44 37 45 - static u32 mop500_sdi0_vdd_handler(struct device *dev, unsigned int vdd, 46 - unsigned char power_mode) 38 + static int mop500_sdi0_ios_handler(struct device *dev, struct mmc_ios *ios) 47 39 { 48 - switch (power_mode) { 40 + switch (ios->power_mode) { 49 41 case MMC_POWER_UP: 50 42 case MMC_POWER_ON: 51 43 /* ··· 57 65 break; 58 66 } 59 67 60 - return MCI_FBCLKEN | MCI_CMDDIREN | MCI_DATA0DIREN | 61 - MCI_DATA2DIREN | MCI_DATA31DIREN; 68 + return 0; 62 69 } 63 70 64 71 #ifdef CONFIG_STE_DMA40 ··· 81 90 #endif 82 91 83 92 static struct mmci_platform_data mop500_sdi0_data = { 84 - .vdd_handler = mop500_sdi0_vdd_handler, 93 + .ios_handler = mop500_sdi0_ios_handler, 85 94 .ocr_mask = MMC_VDD_29_30, 86 95 .f_max = 50000000, 87 96 .capabilities = MMC_CAP_4_BIT_DATA | 88 97 MMC_CAP_SD_HIGHSPEED | 89 98 MMC_CAP_MMC_HIGHSPEED, 90 99 .gpio_wp = -1, 100 + .sigdir = MCI_ST_FBCLKEN | 101 + MCI_ST_CMDDIREN | 102 + MCI_ST_DATA0DIREN | 103 + MCI_ST_DATA2DIREN, 91 104 #ifdef CONFIG_STE_DMA40 92 105 .dma_filter = stedma40_filter, 93 106 .dma_rx_param = &mop500_sdi0_dma_cfg_rx,
+4 -4
drivers/mmc/host/mmci.c
··· 1026 1026 unsigned long flags; 1027 1027 int ret; 1028 1028 1029 + if (host->plat->ios_handler && 1030 + host->plat->ios_handler(mmc_dev(mmc), ios)) 1031 + dev_err(mmc_dev(mmc), "platform ios_handler failed\n"); 1032 + 1029 1033 switch (ios->power_mode) { 1030 1034 case MMC_POWER_OFF: 1031 1035 if (host->vcc) ··· 1049 1045 return; 1050 1046 } 1051 1047 } 1052 - if (host->plat->vdd_handler) 1053 - pwr |= host->plat->vdd_handler(mmc_dev(mmc), ios->vdd, 1054 - ios->power_mode); 1055 - 1056 1048 /* 1057 1049 * The ST Micro variant doesn't have the PL180s MCI_PWR_UP 1058 1050 * and instead uses MCI_PWR_ON so apply whatever value is
+3 -3
include/linux/amba/mmci.h
··· 31 31 * @ocr_mask: available voltages on the 4 pins from the block, this 32 32 * is ignored if a regulator is used, see the MMC_VDD_* masks in 33 33 * mmc/host.h 34 - * @vdd_handler: a callback function to translate a MMC_VDD_* 34 + * @ios_handler: a callback function to act on specfic ios changes, 35 + * used for example to control a levelshifter 35 36 * mask into a value to be binary (or set some other custom bits 36 37 * in MMCIPWR) or:ed and written into the MMCIPWR register of the 37 38 * block. May also control external power based on the power_mode. ··· 62 61 struct mmci_platform_data { 63 62 unsigned int f_max; 64 63 unsigned int ocr_mask; 65 - u32 (*vdd_handler)(struct device *, unsigned int vdd, 66 - unsigned char power_mode); 64 + int (*ios_handler)(struct device *, struct mmc_ios *); 67 65 unsigned int (*status)(struct device *); 68 66 int gpio_wp; 69 67 int gpio_cd;