| .. | .. |
|---|
| 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 | |
|---|