.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * linux/drivers/mmc/host/pxa.c - PXA MMCI driver |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright (C) 2003 Russell King, All Rights Reserved. |
---|
5 | | - * |
---|
6 | | - * This program is free software; you can redistribute it and/or modify |
---|
7 | | - * it under the terms of the GNU General Public License version 2 as |
---|
8 | | - * published by the Free Software Foundation. |
---|
9 | 6 | * |
---|
10 | 7 | * This hardware is really sick: |
---|
11 | 8 | * - No way to clear interrupts. |
---|
.. | .. |
---|
30 | 27 | #include <linux/mmc/slot-gpio.h> |
---|
31 | 28 | #include <linux/io.h> |
---|
32 | 29 | #include <linux/regulator/consumer.h> |
---|
33 | | -#include <linux/gpio.h> |
---|
| 30 | +#include <linux/gpio/consumer.h> |
---|
34 | 31 | #include <linux/gfp.h> |
---|
35 | 32 | #include <linux/of.h> |
---|
36 | | -#include <linux/of_gpio.h> |
---|
37 | 33 | #include <linux/of_device.h> |
---|
38 | 34 | |
---|
39 | | -#include <asm/sizes.h> |
---|
| 35 | +#include <linux/sizes.h> |
---|
40 | 36 | |
---|
41 | 37 | #include <mach/hardware.h> |
---|
42 | 38 | #include <linux/platform_data/mmc-pxamci.h> |
---|
.. | .. |
---|
63 | 59 | unsigned int imask; |
---|
64 | 60 | unsigned int power_mode; |
---|
65 | 61 | unsigned long detect_delay_ms; |
---|
| 62 | + bool use_ro_gpio; |
---|
| 63 | + struct gpio_desc *power; |
---|
66 | 64 | struct pxamci_platform_data *pdata; |
---|
67 | 65 | |
---|
68 | 66 | struct mmc_request *mrq; |
---|
.. | .. |
---|
101 | 99 | { |
---|
102 | 100 | struct mmc_host *mmc = host->mmc; |
---|
103 | 101 | struct regulator *supply = mmc->supply.vmmc; |
---|
104 | | - int on; |
---|
105 | 102 | |
---|
106 | 103 | if (!IS_ERR(supply)) |
---|
107 | 104 | return mmc_regulator_set_ocr(mmc, supply, vdd); |
---|
108 | 105 | |
---|
109 | | - if (host->pdata && |
---|
110 | | - gpio_is_valid(host->pdata->gpio_power)) { |
---|
111 | | - on = ((1 << vdd) & host->pdata->ocr_mask); |
---|
112 | | - gpio_set_value(host->pdata->gpio_power, |
---|
113 | | - !!on ^ host->pdata->gpio_power_invert); |
---|
| 106 | + if (host->power) { |
---|
| 107 | + bool on = !!((1 << vdd) & host->pdata->ocr_mask); |
---|
| 108 | + gpiod_set_value(host->power, on); |
---|
114 | 109 | } |
---|
115 | 110 | |
---|
116 | 111 | if (host->pdata && host->pdata->setpower) |
---|
.. | .. |
---|
432 | 427 | { |
---|
433 | 428 | struct pxamci_host *host = mmc_priv(mmc); |
---|
434 | 429 | |
---|
435 | | - if (host->pdata && gpio_is_valid(host->pdata->gpio_card_ro)) |
---|
| 430 | + if (host->use_ro_gpio) |
---|
436 | 431 | return mmc_gpio_get_ro(mmc); |
---|
437 | 432 | if (host->pdata && host->pdata->get_ro) |
---|
438 | 433 | return !!host->pdata->get_ro(mmc_dev(mmc)); |
---|
.. | .. |
---|
653 | 648 | |
---|
654 | 649 | ret = pxamci_of_init(pdev, mmc); |
---|
655 | 650 | if (ret) |
---|
656 | | - return ret; |
---|
| 651 | + goto out; |
---|
657 | 652 | |
---|
658 | 653 | host = mmc_priv(mmc); |
---|
659 | 654 | host->mmc = mmc; |
---|
.. | .. |
---|
677 | 672 | |
---|
678 | 673 | ret = pxamci_init_ocr(host); |
---|
679 | 674 | if (ret < 0) |
---|
680 | | - return ret; |
---|
| 675 | + goto out; |
---|
681 | 676 | |
---|
682 | 677 | mmc->caps = 0; |
---|
683 | 678 | host->cmdat = 0; |
---|
.. | .. |
---|
715 | 710 | |
---|
716 | 711 | platform_set_drvdata(pdev, mmc); |
---|
717 | 712 | |
---|
718 | | - host->dma_chan_rx = dma_request_slave_channel(dev, "rx"); |
---|
719 | | - if (host->dma_chan_rx == NULL) { |
---|
| 713 | + host->dma_chan_rx = dma_request_chan(dev, "rx"); |
---|
| 714 | + if (IS_ERR(host->dma_chan_rx)) { |
---|
720 | 715 | dev_err(dev, "unable to request rx dma channel\n"); |
---|
721 | | - ret = -ENODEV; |
---|
| 716 | + ret = PTR_ERR(host->dma_chan_rx); |
---|
| 717 | + host->dma_chan_rx = NULL; |
---|
722 | 718 | goto out; |
---|
723 | 719 | } |
---|
724 | 720 | |
---|
725 | | - host->dma_chan_tx = dma_request_slave_channel(dev, "tx"); |
---|
726 | | - if (host->dma_chan_tx == NULL) { |
---|
| 721 | + host->dma_chan_tx = dma_request_chan(dev, "tx"); |
---|
| 722 | + if (IS_ERR(host->dma_chan_tx)) { |
---|
727 | 723 | dev_err(dev, "unable to request tx dma channel\n"); |
---|
728 | | - ret = -ENODEV; |
---|
| 724 | + ret = PTR_ERR(host->dma_chan_tx); |
---|
| 725 | + host->dma_chan_tx = NULL; |
---|
729 | 726 | goto out; |
---|
730 | 727 | } |
---|
731 | 728 | |
---|
732 | 729 | if (host->pdata) { |
---|
733 | | - int gpio_cd = host->pdata->gpio_card_detect; |
---|
734 | | - int gpio_ro = host->pdata->gpio_card_ro; |
---|
735 | | - int gpio_power = host->pdata->gpio_power; |
---|
736 | | - |
---|
737 | 730 | host->detect_delay_ms = host->pdata->detect_delay_ms; |
---|
738 | 731 | |
---|
739 | | - if (gpio_is_valid(gpio_power)) { |
---|
740 | | - ret = devm_gpio_request(dev, gpio_power, |
---|
741 | | - "mmc card power"); |
---|
742 | | - if (ret) { |
---|
743 | | - dev_err(dev, |
---|
744 | | - "Failed requesting gpio_power %d\n", |
---|
745 | | - gpio_power); |
---|
746 | | - goto out; |
---|
747 | | - } |
---|
748 | | - gpio_direction_output(gpio_power, |
---|
749 | | - host->pdata->gpio_power_invert); |
---|
750 | | - } |
---|
751 | | - |
---|
752 | | - if (gpio_is_valid(gpio_ro)) { |
---|
753 | | - ret = mmc_gpio_request_ro(mmc, gpio_ro); |
---|
754 | | - if (ret) { |
---|
755 | | - dev_err(dev, |
---|
756 | | - "Failed requesting gpio_ro %d\n", |
---|
757 | | - gpio_ro); |
---|
758 | | - goto out; |
---|
759 | | - } else { |
---|
760 | | - mmc->caps2 |= host->pdata->gpio_card_ro_invert ? |
---|
761 | | - 0 : MMC_CAP2_RO_ACTIVE_HIGH; |
---|
762 | | - } |
---|
763 | | - } |
---|
764 | | - |
---|
765 | | - if (gpio_is_valid(gpio_cd)) |
---|
766 | | - ret = mmc_gpio_request_cd(mmc, gpio_cd, 0); |
---|
767 | | - if (ret) { |
---|
768 | | - dev_err(dev, "Failed requesting gpio_cd %d\n", |
---|
769 | | - gpio_cd); |
---|
| 732 | + host->power = devm_gpiod_get_optional(dev, "power", GPIOD_OUT_LOW); |
---|
| 733 | + if (IS_ERR(host->power)) { |
---|
| 734 | + ret = PTR_ERR(host->power); |
---|
| 735 | + dev_err(dev, "Failed requesting gpio_power\n"); |
---|
770 | 736 | goto out; |
---|
771 | 737 | } |
---|
| 738 | + |
---|
| 739 | + /* FIXME: should we pass detection delay to debounce? */ |
---|
| 740 | + ret = mmc_gpiod_request_cd(mmc, "cd", 0, false, 0); |
---|
| 741 | + if (ret && ret != -ENOENT) { |
---|
| 742 | + dev_err(dev, "Failed requesting gpio_cd\n"); |
---|
| 743 | + goto out; |
---|
| 744 | + } |
---|
| 745 | + |
---|
| 746 | + if (!host->pdata->gpio_card_ro_invert) |
---|
| 747 | + mmc->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH; |
---|
| 748 | + |
---|
| 749 | + ret = mmc_gpiod_request_ro(mmc, "wp", 0, 0); |
---|
| 750 | + if (ret && ret != -ENOENT) { |
---|
| 751 | + dev_err(dev, "Failed requesting gpio_ro\n"); |
---|
| 752 | + goto out; |
---|
| 753 | + } |
---|
| 754 | + if (!ret) |
---|
| 755 | + host->use_ro_gpio = true; |
---|
772 | 756 | |
---|
773 | 757 | if (host->pdata->init) |
---|
774 | 758 | host->pdata->init(dev, pxamci_detect_irq, mmc); |
---|
775 | 759 | |
---|
776 | | - if (gpio_is_valid(gpio_power) && host->pdata->setpower) |
---|
| 760 | + if (host->power && host->pdata->setpower) |
---|
777 | 761 | dev_warn(dev, "gpio_power and setpower() both defined\n"); |
---|
778 | | - if (gpio_is_valid(gpio_ro) && host->pdata->get_ro) |
---|
| 762 | + if (host->use_ro_gpio && host->pdata->get_ro) |
---|
779 | 763 | dev_warn(dev, "gpio_ro and get_ro() both defined\n"); |
---|
780 | 764 | } |
---|
781 | 765 | |
---|
782 | | - mmc_add_host(mmc); |
---|
| 766 | + ret = mmc_add_host(mmc); |
---|
| 767 | + if (ret) { |
---|
| 768 | + if (host->pdata && host->pdata->exit) |
---|
| 769 | + host->pdata->exit(dev, mmc); |
---|
| 770 | + goto out; |
---|
| 771 | + } |
---|
783 | 772 | |
---|
784 | 773 | return 0; |
---|
785 | 774 | |
---|
.. | .. |
---|
828 | 817 | .remove = pxamci_remove, |
---|
829 | 818 | .driver = { |
---|
830 | 819 | .name = DRIVER_NAME, |
---|
| 820 | + .probe_type = PROBE_PREFER_ASYNCHRONOUS, |
---|
831 | 821 | .of_match_table = of_match_ptr(pxa_mmc_dt_ids), |
---|
832 | 822 | }, |
---|
833 | 823 | }; |
---|