diff options
Diffstat (limited to 'drivers/mmc/host/atmel-mci.c')
-rw-r--r-- | drivers/mmc/host/atmel-mci.c | 55 |
1 files changed, 25 insertions, 30 deletions
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index bb585d94090..77250d4b197 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c @@ -17,6 +17,7 @@ #include <linux/gpio.h> #include <linux/init.h> #include <linux/interrupt.h> +#include <linux/io.h> #include <linux/ioport.h> #include <linux/module.h> #include <linux/of.h> @@ -2195,7 +2196,8 @@ static int __init atmci_init_slot(struct atmel_mci *host, /* Assume card is present initially */ set_bit(ATMCI_CARD_PRESENT, &slot->flags); if (gpio_is_valid(slot->detect_pin)) { - if (gpio_request(slot->detect_pin, "mmc_detect")) { + if (devm_gpio_request(&host->pdev->dev, slot->detect_pin, + "mmc_detect")) { dev_dbg(&mmc->class_dev, "no detect pin available\n"); slot->detect_pin = -EBUSY; } else if (gpio_get_value(slot->detect_pin) ^ @@ -2208,7 +2210,8 @@ static int __init atmci_init_slot(struct atmel_mci *host, mmc->caps |= MMC_CAP_NEEDS_POLL; if (gpio_is_valid(slot->wp_pin)) { - if (gpio_request(slot->wp_pin, "mmc_wp")) { + if (devm_gpio_request(&host->pdev->dev, slot->wp_pin, + "mmc_wp")) { dev_dbg(&mmc->class_dev, "no WP pin available\n"); slot->wp_pin = -EBUSY; } @@ -2232,7 +2235,6 @@ static int __init atmci_init_slot(struct atmel_mci *host, dev_dbg(&mmc->class_dev, "could not request IRQ %d for detect pin\n", gpio_to_irq(slot->detect_pin)); - gpio_free(slot->detect_pin); slot->detect_pin = -EBUSY; } } @@ -2242,7 +2244,7 @@ static int __init atmci_init_slot(struct atmel_mci *host, return 0; } -static void __exit atmci_cleanup_slot(struct atmel_mci_slot *slot, +static void atmci_cleanup_slot(struct atmel_mci_slot *slot, unsigned int id) { /* Debugfs stuff is cleaned up by mmc core */ @@ -2257,10 +2259,7 @@ static void __exit atmci_cleanup_slot(struct atmel_mci_slot *slot, free_irq(gpio_to_irq(pin), slot); del_timer_sync(&slot->detect_timer); - gpio_free(pin); } - if (gpio_is_valid(slot->wp_pin)) - gpio_free(slot->wp_pin); slot->host->slot[id] = NULL; mmc_free_host(slot->mmc); @@ -2344,6 +2343,7 @@ static void __init atmci_get_cap(struct atmel_mci *host) /* keep only major version number */ switch (version & 0xf00) { + case 0x600: case 0x500: host->caps.has_odd_clk_div = 1; case 0x400: @@ -2377,7 +2377,7 @@ static int __init atmci_probe(struct platform_device *pdev) struct resource *regs; unsigned int nr_slots; int irq; - int ret; + int ret, i; regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!regs) @@ -2395,7 +2395,7 @@ static int __init atmci_probe(struct platform_device *pdev) if (irq < 0) return irq; - host = kzalloc(sizeof(struct atmel_mci), GFP_KERNEL); + host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL); if (!host) return -ENOMEM; @@ -2403,20 +2403,18 @@ static int __init atmci_probe(struct platform_device *pdev) spin_lock_init(&host->lock); INIT_LIST_HEAD(&host->queue); - host->mck = clk_get(&pdev->dev, "mci_clk"); - if (IS_ERR(host->mck)) { - ret = PTR_ERR(host->mck); - goto err_clk_get; - } + host->mck = devm_clk_get(&pdev->dev, "mci_clk"); + if (IS_ERR(host->mck)) + return PTR_ERR(host->mck); - ret = -ENOMEM; - host->regs = ioremap(regs->start, resource_size(regs)); + host->regs = devm_ioremap(&pdev->dev, regs->start, resource_size(regs)); if (!host->regs) - goto err_ioremap; + return -ENOMEM; ret = clk_prepare_enable(host->mck); if (ret) - goto err_request_irq; + return ret; + atmci_writel(host, ATMCI_CR, ATMCI_CR_SWRST); host->bus_hz = clk_get_rate(host->mck); clk_disable_unprepare(host->mck); @@ -2427,7 +2425,7 @@ static int __init atmci_probe(struct platform_device *pdev) ret = request_irq(irq, atmci_interrupt, 0, dev_name(&pdev->dev), host); if (ret) - goto err_request_irq; + return ret; /* Get MCI capabilities and set operations according to it */ atmci_get_cap(host); @@ -2485,7 +2483,7 @@ static int __init atmci_probe(struct platform_device *pdev) if (!host->buffer) { ret = -ENOMEM; dev_err(&pdev->dev, "buffer allocation failed\n"); - goto err_init_slot; + goto err_dma_alloc; } } @@ -2495,16 +2493,16 @@ static int __init atmci_probe(struct platform_device *pdev) return 0; +err_dma_alloc: + for (i = 0; i < ATMCI_MAX_NR_SLOTS; i++) { + if (host->slot[i]) + atmci_cleanup_slot(host->slot[i], i); + } err_init_slot: + del_timer_sync(&host->timer); if (host->dma.chan) dma_release_channel(host->dma.chan); free_irq(irq, host); -err_request_irq: - iounmap(host->regs); -err_ioremap: - clk_put(host->mck); -err_clk_get: - kfree(host); return ret; } @@ -2528,14 +2526,11 @@ static int __exit atmci_remove(struct platform_device *pdev) atmci_readl(host, ATMCI_SR); clk_disable_unprepare(host->mck); + del_timer_sync(&host->timer); if (host->dma.chan) dma_release_channel(host->dma.chan); free_irq(platform_get_irq(pdev, 0), host); - iounmap(host->regs); - - clk_put(host->mck); - kfree(host); return 0; } |