diff options
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/card/sdio_uart.c | 62 | ||||
-rw-r--r-- | drivers/mmc/core/core.c | 100 | ||||
-rw-r--r-- | drivers/mmc/host/Kconfig | 2 | ||||
-rw-r--r-- | drivers/mmc/host/mmci.c | 6 | ||||
-rw-r--r-- | drivers/mmc/host/mxcmmc.c | 4 | ||||
-rw-r--r-- | drivers/mmc/host/omap.c | 24 | ||||
-rw-r--r-- | drivers/mmc/host/omap_hsmmc.c | 4 | ||||
-rw-r--r-- | drivers/mmc/host/pxamci.c | 3 |
8 files changed, 148 insertions, 57 deletions
diff --git a/drivers/mmc/card/sdio_uart.c b/drivers/mmc/card/sdio_uart.c index 78ad48718ab0..36a8d53ad2a2 100644 --- a/drivers/mmc/card/sdio_uart.c +++ b/drivers/mmc/card/sdio_uart.c @@ -30,6 +30,7 @@ #include <linux/init.h> #include <linux/kernel.h> #include <linux/mutex.h> +#include <linux/seq_file.h> #include <linux/serial_reg.h> #include <linux/circ_buf.h> #include <linux/gfp.h> @@ -933,67 +934,64 @@ static int sdio_uart_tiocmset(struct tty_struct *tty, struct file *file, return result; } -static int sdio_uart_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) +static int sdio_uart_proc_show(struct seq_file *m, void *v) { - int i, len = 0; - off_t begin = 0; + int i; - len += sprintf(page, "serinfo:1.0 driver%s%s revision:%s\n", + seq_printf(m, "serinfo:1.0 driver%s%s revision:%s\n", "", "", ""); - for (i = 0; i < UART_NR && len < PAGE_SIZE - 96; i++) { + for (i = 0; i < UART_NR; i++) { struct sdio_uart_port *port = sdio_uart_port_get(i); if (port) { - len += sprintf(page+len, "%d: uart:SDIO", i); + seq_printf(m, "%d: uart:SDIO", i); if(capable(CAP_SYS_ADMIN)) { - len += sprintf(page + len, " tx:%d rx:%d", + seq_printf(m, " tx:%d rx:%d", port->icount.tx, port->icount.rx); if (port->icount.frame) - len += sprintf(page + len, " fe:%d", + seq_printf(m, " fe:%d", port->icount.frame); if (port->icount.parity) - len += sprintf(page + len, " pe:%d", + seq_printf(m, " pe:%d", port->icount.parity); if (port->icount.brk) - len += sprintf(page + len, " brk:%d", + seq_printf(m, " brk:%d", port->icount.brk); if (port->icount.overrun) - len += sprintf(page + len, " oe:%d", + seq_printf(m, " oe:%d", port->icount.overrun); if (port->icount.cts) - len += sprintf(page + len, " cts:%d", + seq_printf(m, " cts:%d", port->icount.cts); if (port->icount.dsr) - len += sprintf(page + len, " dsr:%d", + seq_printf(m, " dsr:%d", port->icount.dsr); if (port->icount.rng) - len += sprintf(page + len, " rng:%d", + seq_printf(m, " rng:%d", port->icount.rng); if (port->icount.dcd) - len += sprintf(page + len, " dcd:%d", + seq_printf(m, " dcd:%d", port->icount.dcd); } - strcat(page, "\n"); - len++; sdio_uart_port_put(port); - } - - if (len + begin > off + count) - goto done; - if (len + begin < off) { - begin += len; - len = 0; + seq_putc(m, '\n'); } } - *eof = 1; + return 0; +} -done: - if (off >= len + begin) - return 0; - *start = page + (off - begin); - return (count < begin + len - off) ? count : (begin + len - off); +static int sdio_uart_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, sdio_uart_proc_show, NULL); } +static const struct file_operations sdio_uart_proc_fops = { + .owner = THIS_MODULE, + .open = sdio_uart_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + static const struct tty_operations sdio_uart_ops = { .open = sdio_uart_open, .close = sdio_uart_close, @@ -1007,7 +1005,7 @@ static const struct tty_operations sdio_uart_ops = { .break_ctl = sdio_uart_break_ctl, .tiocmget = sdio_uart_tiocmget, .tiocmset = sdio_uart_tiocmset, - .read_proc = sdio_uart_read_proc, + .proc_fops = &sdio_uart_proc_fops, }; static struct tty_driver *sdio_uart_tty_driver; diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 5c83c67b186c..fa073ab3fa34 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -21,6 +21,7 @@ #include <linux/leds.h> #include <linux/scatterlist.h> #include <linux/log2.h> +#include <linux/regulator/consumer.h> #include <linux/mmc/card.h> #include <linux/mmc/host.h> @@ -538,6 +539,105 @@ u32 mmc_vddrange_to_ocrmask(int vdd_min, int vdd_max) } EXPORT_SYMBOL(mmc_vddrange_to_ocrmask); +#ifdef CONFIG_REGULATOR + +/** + * mmc_regulator_get_ocrmask - return mask of supported voltages + * @supply: regulator to use + * + * This returns either a negative errno, or a mask of voltages that + * can be provided to MMC/SD/SDIO devices using the specified voltage + * regulator. This would normally be called before registering the + * MMC host adapter. + */ +int mmc_regulator_get_ocrmask(struct regulator *supply) +{ + int result = 0; + int count; + int i; + + count = regulator_count_voltages(supply); + if (count < 0) + return count; + + for (i = 0; i < count; i++) { + int vdd_uV; + int vdd_mV; + + vdd_uV = regulator_list_voltage(supply, i); + if (vdd_uV <= 0) + continue; + + vdd_mV = vdd_uV / 1000; + result |= mmc_vddrange_to_ocrmask(vdd_mV, vdd_mV); + } + + return result; +} +EXPORT_SYMBOL(mmc_regulator_get_ocrmask); + +/** + * mmc_regulator_set_ocr - set regulator to match host->ios voltage + * @vdd_bit: zero for power off, else a bit number (host->ios.vdd) + * @supply: regulator to use + * + * Returns zero on success, else negative errno. + * + * MMC host drivers may use this to enable or disable a regulator using + * a particular supply voltage. This would normally be called from the + * set_ios() method. + */ +int mmc_regulator_set_ocr(struct regulator *supply, unsigned short vdd_bit) +{ + int result = 0; + int min_uV, max_uV; + int enabled; + + enabled = regulator_is_enabled(supply); + if (enabled < 0) + return enabled; + + if (vdd_bit) { + int tmp; + int voltage; + + /* REVISIT mmc_vddrange_to_ocrmask() may have set some + * bits this regulator doesn't quite support ... don't + * be too picky, most cards and regulators are OK with + * a 0.1V range goof (it's a small error percentage). + */ + tmp = vdd_bit - ilog2(MMC_VDD_165_195); + if (tmp == 0) { + min_uV = 1650 * 1000; + max_uV = 1950 * 1000; + } else { + min_uV = 1900 * 1000 + tmp * 100 * 1000; + max_uV = min_uV + 100 * 1000; + } + + /* avoid needless changes to this voltage; the regulator + * might not allow this operation + */ + voltage = regulator_get_voltage(supply); + if (voltage < 0) + result = voltage; + else if (voltage < min_uV || voltage > max_uV) + result = regulator_set_voltage(supply, min_uV, max_uV); + else + result = 0; + + if (result == 0 && !enabled) + result = regulator_enable(supply); + } else if (enabled) { + result = regulator_disable(supply); + } + + return result; +} +EXPORT_SYMBOL(mmc_regulator_set_ocr); + +#endif + /* * Mask off any voltages we don't support and select * the lowest voltage diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 126a0da095e4..b4cf691f3f64 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -206,7 +206,7 @@ config MMC_SPI select CRC7 select CRC_ITU_T help - Some systems accss MMC/SD/SDIO cards using a SPI controller + Some systems access MMC/SD/SDIO cards using a SPI controller instead of using a "native" MMC/SD/SDIO controller. This has a disadvantage of being relatively high overhead, but a compensating advantage of working on many systems without dedicated MMC/SD/SDIO diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 2909bbc8ad00..a663429b3d55 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -490,7 +490,7 @@ static void mmci_check_status(unsigned long data) mod_timer(&host->timer, jiffies + HZ); } -static int mmci_probe(struct amba_device *dev, void *id) +static int __devinit mmci_probe(struct amba_device *dev, void *id) { struct mmc_platform_data *plat = dev->dev.platform_data; struct mmci_host *host; @@ -633,7 +633,7 @@ static int mmci_probe(struct amba_device *dev, void *id) return ret; } -static int mmci_remove(struct amba_device *dev) +static int __devexit mmci_remove(struct amba_device *dev) { struct mmc_host *mmc = amba_get_drvdata(dev); @@ -730,7 +730,7 @@ static struct amba_driver mmci_driver = { .name = DRIVER_NAME, }, .probe = mmci_probe, - .remove = mmci_remove, + .remove = __devexit_p(mmci_remove), .suspend = mmci_suspend, .resume = mmci_resume, .id_table = mmci_ids, diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c index dda0be4e25dc..b4a615c55f28 100644 --- a/drivers/mmc/host/mxcmmc.c +++ b/drivers/mmc/host/mxcmmc.c @@ -42,7 +42,7 @@ #define HAS_DMA #endif -#define DRIVER_NAME "imx-mmc" +#define DRIVER_NAME "mxc-mmc" #define MMC_REG_STR_STP_CLK 0x00 #define MMC_REG_STATUS 0x04 @@ -707,7 +707,7 @@ static int mxcmci_probe(struct platform_device *pdev) host->res = r; host->irq = irq; - host->clk = clk_get(&pdev->dev, "sdhc_clk"); + host->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(host->clk)) { ret = PTR_ERR(host->clk); goto out_iounmap; diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c index 67d7b7fef084..5570849188cc 100644 --- a/drivers/mmc/host/omap.c +++ b/drivers/mmc/host/omap.c @@ -1460,18 +1460,12 @@ static int __init mmc_omap_probe(struct platform_device *pdev) if (!host->virt_base) goto err_ioremap; - if (cpu_is_omap24xx()) { - host->iclk = clk_get(&pdev->dev, "mmc_ick"); - if (IS_ERR(host->iclk)) - goto err_free_mmc_host; - clk_enable(host->iclk); - } - - if (!cpu_is_omap24xx()) - host->fclk = clk_get(&pdev->dev, "mmc_ck"); - else - host->fclk = clk_get(&pdev->dev, "mmc_fck"); + host->iclk = clk_get(&pdev->dev, "ick"); + if (IS_ERR(host->iclk)) + goto err_free_mmc_host; + clk_enable(host->iclk); + host->fclk = clk_get(&pdev->dev, "fck"); if (IS_ERR(host->fclk)) { ret = PTR_ERR(host->fclk); goto err_free_iclk; @@ -1536,10 +1530,10 @@ static int mmc_omap_remove(struct platform_device *pdev) if (host->pdata->cleanup) host->pdata->cleanup(&pdev->dev); - if (host->iclk && !IS_ERR(host->iclk)) - clk_put(host->iclk); - if (host->fclk && !IS_ERR(host->fclk)) - clk_put(host->fclk); + mmc_omap_fclk_enable(host, 0); + clk_put(host->fclk); + clk_disable(host->iclk); + clk_put(host->iclk); iounmap(host->virt_base); release_mem_region(pdev->resource[0].start, diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 488f222054f8..d183be6f2a5f 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -1020,13 +1020,13 @@ static int __init omap_mmc_probe(struct platform_device *pdev) sema_init(&host->sem, 1); - host->iclk = clk_get(&pdev->dev, "mmchs_ick"); + host->iclk = clk_get(&pdev->dev, "ick"); if (IS_ERR(host->iclk)) { ret = PTR_ERR(host->iclk); host->iclk = NULL; goto err1; } - host->fclk = clk_get(&pdev->dev, "mmchs_fck"); + host->fclk = clk_get(&pdev->dev, "fck"); if (IS_ERR(host->fclk)) { ret = PTR_ERR(host->fclk); host->fclk = NULL; diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c index 9702ad3774cf..430095725f9f 100644 --- a/drivers/mmc/host/pxamci.c +++ b/drivers/mmc/host/pxamci.c @@ -30,9 +30,8 @@ #include <asm/sizes.h> -#include <mach/dma.h> #include <mach/hardware.h> -#include <mach/pxa-regs.h> +#include <mach/dma.h> #include <mach/mmc.h> #include "pxamci.h" |