Merge tag 'mmc-updates-for-3.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 18 Nov 2013 22:47:30 +0000 (14:47 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 18 Nov 2013 22:47:30 +0000 (14:47 -0800)
Pull MMC updates from Chris Ball:
 "MMC highlights for 3.13:

  Core:
   - Improve runtime PM support, remove mmc_{suspend,resume}_host().
   - Add MMC_CAP_RUNTIME_RESUME, for delaying MMC resume until we're
     outside of the resume sequence (in runtime_resume) to decrease
     system resume time.

  Drivers:
   - dw_mmc: Support HS200 mode.
   - sdhci-eshdc-imx: Support SD3.0 SDR clock tuning, DDR on IMX6.
   - sdhci-pci: Add support for Intel Clovertrail and Merrifield"

* tag 'mmc-updates-for-3.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc: (108 commits)
  mmc: wbsd: Silence compiler warning
  mmc: core: Silence compiler warning in __mmc_switch
  mmc: sh_mmcif: Convert to clk_prepare|unprepare
  mmc: sh_mmcif: Convert to PM macros when defining dev_pm_ops
  mmc: dw_mmc: exynos: Revert the sdr_timing assignment
  mmc: sdhci: Avoid needless loop while handling SDIO interrupts in sdhci_irq
  mmc: core: Add MMC_CAP_RUNTIME_RESUME to resume at runtime_resume
  mmc: core: Improve runtime PM support during suspend/resume for sd/mmc
  mmc: core: Remove redundant mmc_power_up|off at runtime callbacks
  mmc: Don't force card to active state when entering suspend/shutdown
  MIPS: db1235: Don't use MMC_CLKGATE
  mmc: core: Remove deprecated mmc_suspend|resume_host APIs
  mmc: mmci: Move away from using deprecated APIs
  mmc: via-sdmmc: Move away from using deprecated APIs
  mmc: tmio: Move away from using deprecated APIs
  mmc: sh_mmcif: Move away from using deprecated APIs
  mmc: sdricoh_cs: Move away from using deprecated APIs
  mmc: rtsx: Remove redundant suspend and resume callbacks
  mmc: wbsd: Move away from using deprecated APIs
  mmc: pxamci: Remove redundant suspend and resume callbacks
  ...

1  2 
Documentation/devicetree/bindings/mmc/synopsys-dw-mshc.txt
drivers/mmc/core/bus.c
drivers/mmc/host/mmci.c
drivers/mmc/host/mvsdio.c

index 066a78b034ca8589e4de4d31183075768496f81a,0000000000000000000000000000000000000000..8f3f13315358028f20a5a79720e6a27266caf2be
mode 100644,000000..100644
--- /dev/null
@@@ -1,107 -1,0 +1,116 @@@
 +* Synopsys Designware Mobile Storage Host Controller
 +
 +The Synopsys designware mobile storage host controller is used to interface
 +a SoC with storage medium such as eMMC or SD/MMC cards. This file documents
 +differences between the core mmc properties described by mmc.txt and the
 +properties used by the Synopsys Designware Mobile Storage Host Controller.
 +
 +Required Properties:
 +
 +* compatible: should be
 +      - snps,dw-mshc: for controllers compliant with synopsys dw-mshc.
 +* #address-cells: should be 1.
 +* #size-cells: should be 0.
 +
 +# Slots: The slot specific information are contained within child-nodes with
 +  each child-node representing a supported slot. There should be atleast one
 +  child node representing a card slot. The name of the child node representing
 +  the slot is recommended to be slot@n where n is the unique number of the slot
 +  connnected to the controller. The following are optional properties which
 +  can be included in the slot child node.
 +
 +      * reg: specifies the physical slot number. The valid values of this
 +        property is 0 to (num-slots -1), where num-slots is the value
 +        specified by the num-slots property.
 +
 +      * bus-width: as documented in mmc core bindings.
 +
 +      * wp-gpios: specifies the write protect gpio line. The format of the
 +        gpio specifier depends on the gpio controller. If a GPIO is not used
 +        for write-protect, this property is optional.
 +
 +      * disable-wp: If the wp-gpios property isn't present then (by default)
 +        we'd assume that the write protect is hooked up directly to the
 +        controller's special purpose write protect line (accessible via
 +        the WRTPRT register).  However, it's possible that we simply don't
 +        want write protect.  In that case specify 'disable-wp'.
 +        NOTE: This property is not required for slots known to always
 +        connect to eMMC or SDIO cards.
 +
 +Optional properties:
 +
 +* clocks: from common clock binding: handle to biu and ciu clocks for the
 +  bus interface unit clock and the card interface unit clock.
 +
 +* clock-names: from common clock binding: Shall be "biu" and "ciu".
 +  If the biu clock is missing we'll simply skip enabling it.  If the
 +  ciu clock is missing we'll just assume that the clock is running at
 +  clock-frequency.  It is an error to omit both the ciu clock and the
 +  clock-frequency.
 +
 +* clock-frequency: should be the frequency (in Hz) of the ciu clock.  If this
 +  is specified and the ciu clock is specified then we'll try to set the ciu
 +  clock to this at probe time.
 +
++* clock-freq-min-max: Minimum and Maximum clock frequency for card output
++  clock(cclk_out). If it's not specified, max is 200MHZ and min is 400KHz by default.
++
 +* num-slots: specifies the number of slots supported by the controller.
 +  The number of physical slots actually used could be equal or less than the
 +  value specified by num-slots. If this property is not specified, the value
 +  of num-slot property is assumed to be 1.
 +
 +* fifo-depth: The maximum size of the tx/rx fifo's. If this property is not
 +  specified, the default value of the fifo size is determined from the
 +  controller registers.
 +
 +* card-detect-delay: Delay in milli-seconds before detecting card after card
 +  insert event. The default value is 0.
 +
 +* supports-highspeed: Enables support for high speed cards (up to 50MHz)
 +
++* caps2-mmc-hs200-1_8v: Supports mmc HS200 SDR 1.8V mode
++
++* caps2-mmc-hs200-1_2v: Supports mmc HS200 SDR 1.2V mode
++
 +* broken-cd: as documented in mmc core bindings.
 +
 +* vmmc-supply: The phandle to the regulator to use for vmmc.  If this is
 +  specified we'll defer probe until we can find this regulator.
 +
 +Aliases:
 +
 +- All the MSHC controller nodes should be represented in the aliases node using
 +  the following format 'mshc{n}' where n is a unique number for the alias.
 +
 +Example:
 +
 +The MSHC controller node can be split into two portions, SoC specific and
 +board specific portions as listed below.
 +
 +      dwmmc0@12200000 {
 +              compatible = "snps,dw-mshc";
 +              clocks = <&clock 351>, <&clock 132>;
 +              clock-names = "biu", "ciu";
 +              reg = <0x12200000 0x1000>;
 +              interrupts = <0 75 0>;
 +              #address-cells = <1>;
 +              #size-cells = <0>;
 +      };
 +
 +      dwmmc0@12200000 {
 +              clock-frequency = <400000000>;
++              clock-freq-min-max = <400000 200000000>;
 +              num-slots = <1>;
 +              supports-highspeed;
++              caps2-mmc-hs200-1_8v;
 +              broken-cd;
 +              fifo-depth = <0x80>;
 +              card-detect-delay = <200>;
 +              vmmc-supply = <&buck8>;
 +
 +              slot@0 {
 +                      reg = <0>;
 +                      bus-width = <8>;
 +              };
 +      };
diff --combined drivers/mmc/core/bus.c
index 3e227bd91e81935eaf3f4ffce830de99b3e1321d,cdca8a70da38bfcc9cace78dde9afe563afaef24..64145a32b917b37ce862e392fe3600417c99c336
@@@ -27,7 -27,7 +27,7 @@@
  
  #define to_mmc_driver(d)      container_of(d, struct mmc_driver, drv)
  
 -static ssize_t mmc_type_show(struct device *dev,
 +static ssize_t type_show(struct device *dev,
        struct device_attribute *attr, char *buf)
  {
        struct mmc_card *card = mmc_dev_to_card(dev);
                return -EFAULT;
        }
  }
 +static DEVICE_ATTR_RO(type);
  
 -static struct device_attribute mmc_dev_attrs[] = {
 -      __ATTR(type, S_IRUGO, mmc_type_show, NULL),
 -      __ATTR_NULL,
 +static struct attribute *mmc_dev_attrs[] = {
 +      &dev_attr_type.attr,
 +      NULL,
  };
 +ATTRIBUTE_GROUPS(mmc_dev);
  
  /*
   * This currently matches any MMC driver to any MMC card - drivers
@@@ -220,7 -218,7 +220,7 @@@ static const struct dev_pm_ops mmc_bus_
  
  static struct bus_type mmc_bus_type = {
        .name           = "mmc",
 -      .dev_attrs      = mmc_dev_attrs,
 +      .dev_groups     = mmc_dev_groups,
        .match          = mmc_bus_match,
        .uevent         = mmc_bus_uevent,
        .probe          = mmc_bus_probe,
@@@ -342,7 -340,7 +342,7 @@@ int mmc_add_card(struct mmc_card *card
                break;
        }
  
-       if (mmc_sd_card_uhs(card) &&
+       if (mmc_card_uhs(card) &&
                (card->sd_bus_speed < ARRAY_SIZE(uhs_speeds)))
                uhs_bus_speed_mode = uhs_speeds[card->sd_bus_speed];
  
diff --combined drivers/mmc/host/mmci.c
index d135c76c4855b825175370e215979bd528e4b2d4,9e8a482310d8fce94e418afad22e3b25daab6d12..f32057972dd77fe9a7487f74aa2ab727c2126db6
@@@ -62,7 -62,6 +62,7 @@@ static unsigned int fmax = 515633
   * @signal_direction: input/out direction of bus signals can be indicated
   * @pwrreg_clkgate: MMCIPOWER register must be used to gate the clock
   * @busy_detect: true if busy detection on dat0 is supported
 + * @pwrreg_nopower: bits in MMCIPOWER don't controls ext. power supply
   */
  struct variant_data {
        unsigned int            clkreg;
@@@ -77,7 -76,6 +77,7 @@@
        bool                    signal_direction;
        bool                    pwrreg_clkgate;
        bool                    busy_detect;
 +      bool                    pwrreg_nopower;
  };
  
  static struct variant_data variant_arm = {
@@@ -111,7 -109,6 +111,7 @@@ static struct variant_data variant_u30
        .pwrreg_powerup         = MCI_PWR_ON,
        .signal_direction       = true,
        .pwrreg_clkgate         = true,
 +      .pwrreg_nopower         = true,
  };
  
  static struct variant_data variant_nomadik = {
        .pwrreg_powerup         = MCI_PWR_ON,
        .signal_direction       = true,
        .pwrreg_clkgate         = true,
 +      .pwrreg_nopower         = true,
  };
  
  static struct variant_data variant_ux500 = {
        .signal_direction       = true,
        .pwrreg_clkgate         = true,
        .busy_detect            = true,
 +      .pwrreg_nopower         = true,
  };
  
  static struct variant_data variant_ux500v2 = {
        .signal_direction       = true,
        .pwrreg_clkgate         = true,
        .busy_detect            = true,
 +      .pwrreg_nopower         = true,
  };
  
  static int mmci_card_busy(struct mmc_host *mmc)
@@@ -195,21 -189,6 +195,21 @@@ static int mmci_validate_data(struct mm
        return 0;
  }
  
 +static void mmci_reg_delay(struct mmci_host *host)
 +{
 +      /*
 +       * According to the spec, at least three feedback clock cycles
 +       * of max 52 MHz must pass between two writes to the MMCICLOCK reg.
 +       * Three MCLK clock cycles must pass between two MMCIPOWER reg writes.
 +       * Worst delay time during card init is at 100 kHz => 30 us.
 +       * Worst delay time when up and running is at 25 MHz => 120 ns.
 +       */
 +      if (host->cclk < 25000000)
 +              udelay(30);
 +      else
 +              ndelay(120);
 +}
 +
  /*
   * This must be called with host->lock held
   */
@@@ -1285,7 -1264,6 +1285,7 @@@ static void mmci_set_ios(struct mmc_hos
  
        mmci_set_clkreg(host, ios->clock);
        mmci_write_pwrreg(host, pwr);
 +      mmci_reg_delay(host);
  
        spin_unlock_irqrestore(&host->lock, flags);
  
@@@ -1532,6 -1510,23 +1532,6 @@@ static int mmci_probe(struct amba_devic
                mmc->f_max = min(host->mclk, fmax);
        dev_dbg(mmc_dev(mmc), "clocking block at %u Hz\n", mmc->f_max);
  
 -      host->pinctrl = devm_pinctrl_get(&dev->dev);
 -      if (IS_ERR(host->pinctrl)) {
 -              ret = PTR_ERR(host->pinctrl);
 -              goto clk_disable;
 -      }
 -
 -      host->pins_default = pinctrl_lookup_state(host->pinctrl,
 -                      PINCTRL_STATE_DEFAULT);
 -
 -      /* enable pins to be muxed in and configured */
 -      if (!IS_ERR(host->pins_default)) {
 -              ret = pinctrl_select_state(host->pinctrl, host->pins_default);
 -              if (ret)
 -                      dev_warn(&dev->dev, "could not set default pins\n");
 -      } else
 -              dev_warn(&dev->dev, "could not get default pinstate\n");
 -
        /* Get regulators and the supported OCR mask */
        mmc_regulator_get_supply(mmc);
        if (!mmc->ocr_avail)
@@@ -1730,76 -1725,32 +1730,67 @@@ static int mmci_suspend(struct device *
  {
        struct amba_device *adev = to_amba_device(dev);
        struct mmc_host *mmc = amba_get_drvdata(adev);
-       int ret = 0;
  
        if (mmc) {
                struct mmci_host *host = mmc_priv(mmc);
-               ret = mmc_suspend_host(mmc);
-               if (ret == 0) {
-                       pm_runtime_get_sync(dev);
-                       writel(0, host->base + MMCIMASK0);
-               }
+               pm_runtime_get_sync(dev);
+               writel(0, host->base + MMCIMASK0);
        }
  
-       return ret;
+       return 0;
  }
  
  static int mmci_resume(struct device *dev)
  {
        struct amba_device *adev = to_amba_device(dev);
        struct mmc_host *mmc = amba_get_drvdata(adev);
-       int ret = 0;
  
        if (mmc) {
                struct mmci_host *host = mmc_priv(mmc);
                writel(MCI_IRQENABLE, host->base + MMCIMASK0);
                pm_runtime_put(dev);
-               ret = mmc_resume_host(mmc);
        }
  
-       return ret;
+       return 0;
  }
  #endif
  
  #ifdef CONFIG_PM_RUNTIME
 +static void mmci_save(struct mmci_host *host)
 +{
 +      unsigned long flags;
 +
 +      if (host->variant->pwrreg_nopower) {
 +              spin_lock_irqsave(&host->lock, flags);
 +
 +              writel(0, host->base + MMCIMASK0);
 +              writel(0, host->base + MMCIDATACTRL);
 +              writel(0, host->base + MMCIPOWER);
 +              writel(0, host->base + MMCICLOCK);
 +              mmci_reg_delay(host);
 +
 +              spin_unlock_irqrestore(&host->lock, flags);
 +      }
 +
 +}
 +
 +static void mmci_restore(struct mmci_host *host)
 +{
 +      unsigned long flags;
 +
 +      if (host->variant->pwrreg_nopower) {
 +              spin_lock_irqsave(&host->lock, flags);
 +
 +              writel(host->clk_reg, host->base + MMCICLOCK);
 +              writel(host->datactrl_reg, host->base + MMCIDATACTRL);
 +              writel(host->pwr_reg, host->base + MMCIPOWER);
 +              writel(MCI_IRQENABLE, host->base + MMCIMASK0);
 +              mmci_reg_delay(host);
 +
 +              spin_unlock_irqrestore(&host->lock, flags);
 +      }
 +}
 +
  static int mmci_runtime_suspend(struct device *dev)
  {
        struct amba_device *adev = to_amba_device(dev);
  
        if (mmc) {
                struct mmci_host *host = mmc_priv(mmc);
 +              pinctrl_pm_select_sleep_state(dev);
 +              mmci_save(host);
                clk_disable_unprepare(host->clk);
        }
  
@@@ -1823,8 -1772,6 +1814,8 @@@ static int mmci_runtime_resume(struct d
        if (mmc) {
                struct mmci_host *host = mmc_priv(mmc);
                clk_prepare_enable(host->clk);
 +              mmci_restore(host);
 +              pinctrl_pm_select_default_state(dev);
        }
  
        return 0;
index deecee08c2881d0ee6ad34a9d049368e5d05ceec,22ba4d33e95bc15402b021edb15fc995e9f6e0b1..45aa2206741db8da3bebac2f6b94385add678ced
@@@ -655,7 -655,7 +655,7 @@@ static const struct mmc_host_ops mvsd_o
        .enable_sdio_irq        = mvsd_enable_sdio_irq,
  };
  
 -static void __init
 +static void
  mv_conf_mbus_windows(struct mvsd_host *host,
                     const struct mbus_dram_target_info *dram)
  {
        }
  }
  
 -static int __init mvsd_probe(struct platform_device *pdev)
 +static int mvsd_probe(struct platform_device *pdev)
  {
        struct device_node *np = pdev->dev.of_node;
        struct mmc_host *mmc = NULL;
  
        spin_lock_init(&host->lock);
  
-       host->base = devm_request_and_ioremap(&pdev->dev, r);
-       if (!host->base) {
-               ret = -ENOMEM;
+       host->base = devm_ioremap_resource(&pdev->dev, r);
+       if (IS_ERR(host->base)) {
+               ret = PTR_ERR(host->base);
                goto out;
        }
  
@@@ -819,7 -819,7 +819,7 @@@ out
        return ret;
  }
  
 -static int __exit mvsd_remove(struct platform_device *pdev)
 +static int mvsd_remove(struct platform_device *pdev)
  {
        struct mmc_host *mmc = platform_get_drvdata(pdev);
  
        return 0;
  }
  
- #ifdef CONFIG_PM
- static int mvsd_suspend(struct platform_device *dev, pm_message_t state)
- {
-       struct mmc_host *mmc = platform_get_drvdata(dev);
-       int ret = 0;
-       if (mmc)
-               ret = mmc_suspend_host(mmc);
-       return ret;
- }
- static int mvsd_resume(struct platform_device *dev)
- {
-       struct mmc_host *mmc = platform_get_drvdata(dev);
-       int ret = 0;
-       if (mmc)
-               ret = mmc_resume_host(mmc);
-       return ret;
- }
- #else
- #define mvsd_suspend  NULL
- #define mvsd_resume   NULL
- #endif
  static const struct of_device_id mvsdio_dt_ids[] = {
        { .compatible = "marvell,orion-sdio" },
        { /* sentinel */ }
  MODULE_DEVICE_TABLE(of, mvsdio_dt_ids);
  
  static struct platform_driver mvsd_driver = {
 -      .remove         = __exit_p(mvsd_remove),
 +      .probe          = mvsd_probe,
 +      .remove         = mvsd_remove,
-       .suspend        = mvsd_suspend,
-       .resume         = mvsd_resume,
        .driver         = {
                .name   = DRIVER_NAME,
                .of_match_table = mvsdio_dt_ids,
        },
  };
  
 -module_platform_driver_probe(mvsd_driver, mvsd_probe);
 +module_platform_driver(mvsd_driver);
  
  /* maximum card clock frequency (default 50MHz) */
  module_param(maxfreq, int, 0);