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

mmc: pxamci: fix card detect with slot-gpio API

Move pxamci to mmc slot-gpio API to fix interrupt request.

It fixes the case where the card detection is on a gpio expander, on I2C
for example on zylonite board. In this case, the card detect netsted
interrupt is called from a threaded interrupt. The request_irq() fails,
because a hard irq cannot be a nested interrupt from a threaded
interrupt (set __setup_irq()).

This was tested on zylonite and mioa701 boards.

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
Cc: Petr Cvek <petr.cvek@tul.cz>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>

authored by

Robert Jarzmik and committed by
Ulf Hansson
fd546ee6 51424b28

+22 -44
+22 -44
drivers/mmc/host/pxamci.c
··· 28 28 #include <linux/clk.h> 29 29 #include <linux/err.h> 30 30 #include <linux/mmc/host.h> 31 + #include <linux/mmc/slot-gpio.h> 31 32 #include <linux/io.h> 32 33 #include <linux/regulator/consumer.h> 33 34 #include <linux/gpio.h> ··· 455 454 { 456 455 struct pxamci_host *host = mmc_priv(mmc); 457 456 458 - if (host->pdata && gpio_is_valid(host->pdata->gpio_card_ro)) { 459 - if (host->pdata->gpio_card_ro_invert) 460 - return !gpio_get_value(host->pdata->gpio_card_ro); 461 - else 462 - return gpio_get_value(host->pdata->gpio_card_ro); 463 - } 457 + if (host->pdata && gpio_is_valid(host->pdata->gpio_card_ro)) 458 + return mmc_gpio_get_ro(mmc); 464 459 if (host->pdata && host->pdata->get_ro) 465 460 return !!host->pdata->get_ro(mmc_dev(mmc)); 466 461 /* ··· 548 551 549 552 static const struct mmc_host_ops pxamci_ops = { 550 553 .request = pxamci_request, 554 + .get_cd = mmc_gpio_get_cd, 551 555 .get_ro = pxamci_get_ro, 552 556 .set_ios = pxamci_set_ios, 553 557 .enable_sdio_irq = pxamci_enable_sdio_irq, ··· 788 790 gpio_power = host->pdata->gpio_power; 789 791 } 790 792 if (gpio_is_valid(gpio_power)) { 791 - ret = gpio_request(gpio_power, "mmc card power"); 793 + ret = devm_gpio_request(&pdev->dev, gpio_power, 794 + "mmc card power"); 792 795 if (ret) { 793 - dev_err(&pdev->dev, "Failed requesting gpio_power %d\n", gpio_power); 796 + dev_err(&pdev->dev, "Failed requesting gpio_power %d\n", 797 + gpio_power); 794 798 goto out; 795 799 } 796 800 gpio_direction_output(gpio_power, 797 801 host->pdata->gpio_power_invert); 798 802 } 799 - if (gpio_is_valid(gpio_ro)) { 800 - ret = gpio_request(gpio_ro, "mmc card read only"); 801 - if (ret) { 802 - dev_err(&pdev->dev, "Failed requesting gpio_ro %d\n", gpio_ro); 803 - goto err_gpio_ro; 804 - } 805 - gpio_direction_input(gpio_ro); 803 + if (gpio_is_valid(gpio_ro)) 804 + ret = mmc_gpio_request_ro(mmc, gpio_ro); 805 + if (ret) { 806 + dev_err(&pdev->dev, "Failed requesting gpio_ro %d\n", gpio_ro); 807 + goto out; 808 + } else { 809 + mmc->caps |= host->pdata->gpio_card_ro_invert ? 810 + MMC_CAP2_RO_ACTIVE_HIGH : 0; 806 811 } 807 - if (gpio_is_valid(gpio_cd)) { 808 - ret = gpio_request(gpio_cd, "mmc card detect"); 809 - if (ret) { 810 - dev_err(&pdev->dev, "Failed requesting gpio_cd %d\n", gpio_cd); 811 - goto err_gpio_cd; 812 - } 813 - gpio_direction_input(gpio_cd); 814 812 815 - ret = request_irq(gpio_to_irq(gpio_cd), pxamci_detect_irq, 816 - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, 817 - "mmc card detect", mmc); 818 - if (ret) { 819 - dev_err(&pdev->dev, "failed to request card detect IRQ\n"); 820 - goto err_request_irq; 821 - } 813 + if (gpio_is_valid(gpio_cd)) 814 + ret = mmc_gpio_request_cd(mmc, gpio_cd, 0); 815 + if (ret) { 816 + dev_err(&pdev->dev, "Failed requesting gpio_cd %d\n", gpio_cd); 817 + goto out; 822 818 } 823 819 824 820 if (host->pdata && host->pdata->init) ··· 827 835 828 836 return 0; 829 837 830 - err_request_irq: 831 - gpio_free(gpio_cd); 832 - err_gpio_cd: 833 - gpio_free(gpio_ro); 834 - err_gpio_ro: 835 - gpio_free(gpio_power); 836 - out: 838 + out: 837 839 if (host) { 838 840 if (host->dma_chan_rx) 839 841 dma_release_channel(host->dma_chan_rx); ··· 859 873 gpio_ro = host->pdata->gpio_card_ro; 860 874 gpio_power = host->pdata->gpio_power; 861 875 } 862 - if (gpio_is_valid(gpio_cd)) { 863 - free_irq(gpio_to_irq(gpio_cd), mmc); 864 - gpio_free(gpio_cd); 865 - } 866 - if (gpio_is_valid(gpio_ro)) 867 - gpio_free(gpio_ro); 868 - if (gpio_is_valid(gpio_power)) 869 - gpio_free(gpio_power); 870 876 if (host->vcc) 871 877 regulator_put(host->vcc); 872 878