Merge tag 'mmc-v5.3' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 12 Jul 2019 01:11:21 +0000 (18:11 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 12 Jul 2019 01:11:21 +0000 (18:11 -0700)
Pull MMC updates from Ulf Hansson:
 "MMC core:
   - Let the dma map ops deal with bouncing and drop dma_max_pfn() from
     the dma-mapping interface for ARM
   - Convert the generic MMC DT doc to YAML schemas
   - Drop questionable support for powered-on re-init of SDIO cards at
     runtime resume and for SDIO HW reset
   - Prevent questionable re-init of powered-on removable SDIO cards at
     system resume
   - Cleanup and clarify some SDIO core code

  MMC host:
   - tmio: Make runtime PM enablement more flexible for variants
   - tmio/renesas_sdhi: Rename DT doc tmio_mmc.txt to renesas,sdhi.txt
     to clarify
   - sdhci-pci: Add support for Intel EHL
   - sdhci-pci-o2micro: Enable support for 8-bit bus
   - sdhci-msm: Prevent acquiring a mutex while holding a spin_lock
   - sdhci-of-esdhc: Improve clock management and tuning
   - sdhci_am654: Enable support for 4 and 8-bit bus on J721E
   - sdhci-sprd: Use pinctrl for a proper signal voltage switch
   - sdhci-sprd: Add support for HS400 enhanced strobe mode
   - sdhci-sprd: Enable PHY DLL and allow delay config to stabilize the
     clock
   - sdhci-sprd: Add support for optional gate clock
   - sunxi-mmc: Convert DT doc to YAML schemas
   - meson-gx: Add support for broken DRAM access for DMA

  MEMSTICK core:
   - Fixup error path of memstick_init()"

* tag 'mmc-v5.3' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc: (52 commits)
  mmc: sdhci_am654: Add dependency on MMC_SDHCI_AM654
  mmc: alcor: remove a redundant greater or equal to zero comparison
  mmc: sdhci-msm: fix mutex while in spinlock
  mmc: sdhci_am654: Make some symbols static
  dma-mapping: remove dma_max_pfn
  mmc: core: let the dma map ops handle bouncing
  dt-binding: mmc: rename tmio_mmc.txt to renesas,sdhi.txt
  mmc: sdhci-sprd: Add pin control support for voltage switch
  dt-bindings: mmc: sprd: Add pinctrl support
  mmc: sdhci-sprd: Add start_signal_voltage_switch ops
  mmc: sdhci-pci: Add support for Intel EHL
  mmc: tmio: Use dma_max_mapping_size() instead of a workaround
  mmc: sdio: Drop unused in-parameter from mmc_sdio_init_card()
  mmc: sdio: Drop unused in-parameter to mmc_sdio_reinit_card()
  mmc: sdio: Don't re-initialize powered-on removable SDIO cards at resume
  mmc: sdio: Drop powered-on re-init at runtime resume and HW reset
  mmc: sdio: Move comment about re-initialization to mmc_sdio_reinit_card()
  mmc: sdio: Drop mmc_claim|release_host() in mmc_sdio_power_restore()
  mmc: sdio: Turn sdio_run_irqs() into static
  mmc: sdhci: Fix indenting on SDHCI_CTRL_8BITBUS
  ...

39 files changed:
Documentation/devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/mmc/amlogic,meson-gx.txt
Documentation/devicetree/bindings/mmc/mmc-controller.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/mmc/mmc.txt
Documentation/devicetree/bindings/mmc/renesas,sdhi.txt [new file with mode: 0644]
Documentation/devicetree/bindings/mmc/sdhci-am654.txt
Documentation/devicetree/bindings/mmc/sdhci-sprd.txt
Documentation/devicetree/bindings/mmc/sunxi-mmc.txt [deleted file]
Documentation/devicetree/bindings/mmc/tmio_mmc.txt [deleted file]
arch/arm/include/asm/dma-mapping.h
drivers/memstick/core/memstick.c
drivers/mmc/core/debugfs.c
drivers/mmc/core/mmc_test.c
drivers/mmc/core/queue.c
drivers/mmc/core/sdio.c
drivers/mmc/core/sdio_irq.c
drivers/mmc/host/Kconfig
drivers/mmc/host/alcor.c
drivers/mmc/host/android-goldfish.c
drivers/mmc/host/atmel-mci.c
drivers/mmc/host/dw_mmc.c
drivers/mmc/host/meson-gx-mmc.c
drivers/mmc/host/renesas_sdhi_core.c
drivers/mmc/host/s3cmci.c
drivers/mmc/host/s3cmci.h
drivers/mmc/host/sdhci-msm.c
drivers/mmc/host/sdhci-of-esdhc.c
drivers/mmc/host/sdhci-pci-core.c
drivers/mmc/host/sdhci-pci-o2micro.c
drivers/mmc/host/sdhci-pci.h
drivers/mmc/host/sdhci-sprd.c
drivers/mmc/host/sdhci-tegra.c
drivers/mmc/host/sdhci.h
drivers/mmc/host/sdhci_am654.c
drivers/mmc/host/tmio_mmc.c
drivers/mmc/host/tmio_mmc_core.c
drivers/mmc/host/uniphier-sd.c
include/linux/dma-mapping.h
include/linux/mmc/host.h

diff --git a/Documentation/devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml b/Documentation/devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml
new file mode 100644 (file)
index 0000000..df0280e
--- /dev/null
@@ -0,0 +1,98 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mmc/allwinner,sun4i-a10-mmc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Allwinner A10 MMC Controller Device Tree Bindings
+
+allOf:
+  - $ref: "mmc-controller.yaml"
+
+maintainers:
+  - Chen-Yu Tsai <wens@csie.org>
+  - Maxime Ripard <maxime.ripard@bootlin.com>
+
+properties:
+  "#address-cells": true
+  "#size-cells": true
+
+  compatible:
+    oneOf:
+      - const: allwinner,sun4i-a10-mmc
+      - const: allwinner,sun5i-a13-mmc
+      - const: allwinner,sun7i-a20-mmc
+      - const: allwinner,sun8i-a83t-emmc
+      - const: allwinner,sun9i-a80-mmc
+      - const: allwinner,sun50i-a64-emmc
+      - const: allwinner,sun50i-a64-mmc
+      - items:
+          - const: allwinner,sun8i-a83t-mmc
+          - const: allwinner,sun7i-a20-mmc
+      - items:
+          - const: allwinner,sun50i-h6-emmc
+          - const: allwinner,sun50i-a64-emmc
+      - items:
+          - const: allwinner,sun50i-h6-mmc
+          - const: allwinner,sun50i-a64-mmc
+      - items:
+          - const: allwinner,sun8i-r40-emmc
+          - const: allwinner,sun50i-a64-emmc
+      - items:
+          - const: allwinner,sun8i-r40-mmc
+          - const: allwinner,sun50i-a64-mmc
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    minItems: 2
+    maxItems: 4
+    items:
+      - description: Bus Clock
+      - description: Module Clock
+      - description: Output Clock
+      - description: Sample Clock
+
+  clock-names:
+    minItems: 2
+    maxItems: 4
+    items:
+      - const: ahb
+      - const: mmc
+      - const: output
+      - const: sample
+
+  resets:
+    maxItems: 1
+
+  reset-names:
+    const: ahb
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+
+examples:
+  - |
+    mmc0: mmc@1c0f000 {
+        compatible = "allwinner,sun5i-a13-mmc";
+        reg = <0x01c0f000 0x1000>;
+        clocks = <&ahb_gates 8>, <&mmc0_clk>;
+        clock-names = "ahb", "mmc";
+        interrupts = <32>;
+        bus-width = <4>;
+        cd-gpios = <&pio 7 1 0>;
+    };
+
+# FIXME: We should set it, but it would report all the generic
+# properties as additional properties.
+# additionalProperties: false
+
+...
index 13e70409e8ac6250676eba2d6e31be6187410168..ccc5358db1316508abae3c2f50f90acb6fc07047 100644 (file)
@@ -22,6 +22,10 @@ Required properties:
   clock rate requested by the MMC core.
 - resets     : phandle of the internal reset line
 
+Optional properties:
+- amlogic,dram-access-quirk: set when controller's internal DMA engine cannot access the
+  DRAM memory, like on the G12A dedicated SDIO controller.
+
 Example:
 
        sd_emmc_a: mmc@70000 {
diff --git a/Documentation/devicetree/bindings/mmc/mmc-controller.yaml b/Documentation/devicetree/bindings/mmc/mmc-controller.yaml
new file mode 100644 (file)
index 0000000..080754e
--- /dev/null
@@ -0,0 +1,374 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mmc/mmc-controller.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MMC Controller Generic Binding
+
+maintainers:
+  - Ulf Hansson <ulf.hansson@linaro.org>
+
+description: |
+  These properties are common to multiple MMC host controllers. Any host
+  that requires the respective functionality should implement them using
+  these definitions.
+
+properties:
+  $nodename:
+    pattern: "^mmc(@.*)?$"
+
+  "#address-cells":
+    const: 1
+    description: |
+      The cell is the slot ID if a function subnode is used.
+
+  "#size-cells":
+    const: 0
+
+  # Card Detection.
+  # If none of these properties are supplied, the host native card
+  # detect will be used. Only one of them should be provided.
+
+  broken-cd:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      There is no card detection available; polling must be used.
+
+  cd-gpios:
+    description:
+      The card detection will be done using the GPIO provided.
+
+  non-removable:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      Non-removable slot (like eMMC); assume always present.
+
+  # *NOTE* on CD and WP polarity. To use common for all SD/MMC host
+  # controllers line polarity properties, we have to fix the meaning
+  # of the "normal" and "inverted" line levels. We choose to follow
+  # the SDHCI standard, which specifies both those lines as "active
+  # low." Therefore, using the "cd-inverted" property means, that the
+  # CD line is active high, i.e. it is high, when a card is
+  # inserted. Similar logic applies to the "wp-inverted" property.
+  #
+  # CD and WP lines can be implemented on the hardware in one of two
+  # ways: as GPIOs, specified in cd-gpios and wp-gpios properties, or
+  # as dedicated pins. Polarity of dedicated pins can be specified,
+  # using *-inverted properties. GPIO polarity can also be specified
+  # using the GPIO_ACTIVE_LOW flag. This creates an ambiguity in the
+  # latter case. We choose to use the XOR logic for GPIO CD and WP
+  # lines.  This means, the two properties are "superimposed," for
+  # example leaving the GPIO_ACTIVE_LOW flag clear and specifying the
+  # respective *-inverted property property results in a
+  # double-inversion and actually means the "normal" line polarity is
+  # in effect.
+  wp-inverted:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      The Write Protect line polarity is inverted.
+
+  cd-inverted:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      The CD line polarity is inverted.
+
+  # Other properties
+
+  bus-width:
+    allOf:
+      - $ref: /schemas/types.yaml#/definitions/uint32
+      - enum: [1, 4, 8]
+        default: 1
+    description:
+      Number of data lines.
+
+  max-frequency:
+    allOf:
+      - $ref: /schemas/types.yaml#/definitions/uint32
+      - minimum: 400000
+      - maximum: 200000000
+    description:
+      Maximum operating frequency of the bus.
+
+  disable-wp:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      When set, no physical write-protect line is present. This
+      property should only be specified when the controller has a
+      dedicated write-protect detection logic. If a GPIO is always
+      used for the write-protect detection. If a GPIO is always used
+      for the write-protect detection logic, it is sufficient to not
+      specify the wp-gpios property in the absence of a write-protect
+      line.
+
+  wp-gpios:
+    description:
+      GPIO to use for the write-protect detection.
+
+  cd-debounce-delay-ms:
+    description:
+      Set delay time before detecting card after card insert
+      interrupt.
+
+  no-1-8-v:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      When specified, denotes that 1.8V card voltage is not supported
+      on this system, even if the controller claims it.
+
+  cap-sd-highspeed:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      SD high-speed timing is supported.
+
+  cap-mmc-highspeed:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      MMC high-speed timing is supported.
+
+  sd-uhs-sdr12:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      SD UHS SDR12 speed is supported.
+
+  sd-uhs-sdr25:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      SD UHS SDR25 speed is supported.
+
+  sd-uhs-sdr50:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      SD UHS SDR50 speed is supported.
+
+  sd-uhs-sdr104:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      SD UHS SDR104 speed is supported.
+
+  sd-uhs-ddr50:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      SD UHS DDR50 speed is supported.
+
+  cap-power-off-card:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      Powering off the card is safe.
+
+  cap-mmc-hw-reset:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      eMMC hardware reset is supported
+
+  cap-sdio-irq:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      enable SDIO IRQ signalling on this interface
+
+  full-pwr-cycle:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      Full power cycle of the card is supported.
+
+  mmc-ddr-1_2v:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      eMMC high-speed DDR mode (1.2V I/O) is supported.
+
+  mmc-ddr-1_8v:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      eMMC high-speed DDR mode (1.8V I/O) is supported.
+
+  mmc-ddr-3_3v:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      eMMC high-speed DDR mode (3.3V I/O) is supported.
+
+  mmc-hs200-1_2v:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      eMMC HS200 mode (1.2V I/O) is supported.
+
+  mmc-hs200-1_8v:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      eMMC HS200 mode (1.8V I/O) is supported.
+
+  mmc-hs400-1_2v:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      eMMC HS400 mode (1.2V I/O) is supported.
+
+  mmc-hs400-1_8v:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      eMMC HS400 mode (1.8V I/O) is supported.
+
+  mmc-hs400-enhanced-strobe:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      eMMC HS400 enhanced strobe mode is supported
+
+  dsr:
+    allOf:
+      - $ref: /schemas/types.yaml#/definitions/uint32
+      - minimum: 0
+      - maximum: 0xffff
+    description:
+      Value the card Driver Stage Register (DSR) should be programmed
+      with.
+
+  no-sdio:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      Controller is limited to send SDIO commands during
+      initialization.
+
+  no-sd:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      Controller is limited to send SD commands during initialization.
+
+  no-mmc:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      Controller is limited to send MMC commands during
+      initialization.
+
+  fixed-emmc-driver-type:
+    allOf:
+      - $ref: /schemas/types.yaml#/definitions/uint32
+      - minimum: 0
+      - maximum: 4
+    description:
+      For non-removable eMMC, enforce this driver type. The value is
+      the driver type as specified in the eMMC specification (table
+      206 in spec version 5.1)
+
+  post-power-on-delay-ms:
+    allOf:
+      - $ref: /schemas/types.yaml#/definitions/uint32
+      - default: 10
+    description:
+      It was invented for MMC pwrseq-simple which could be referred to
+      mmc-pwrseq-simple.txt. But now it\'s reused as a tunable delay
+      waiting for I/O signalling and card power supply to be stable,
+      regardless of whether pwrseq-simple is used. Default to 10ms if
+      no available.
+
+  supports-cqe:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      The presence of this property indicates that the corresponding
+      MMC host controller supports HW command queue feature.
+
+  disable-cqe-dcmd:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      The presence of this property indicates that the MMC
+      controller\'s command queue engine (CQE) does not support direct
+      commands (DCMDs).
+
+  keep-power-in-suspend:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      SDIO only. Preserves card power during a suspend/resume cycle.
+
+  # Deprecated: enable-sdio-wakeup
+  wakeup-source:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      SDIO only. Enables wake up of host system on SDIO IRQ assertion.
+
+  vmmc-supply:
+    description:
+      Supply for the card power
+
+  vqmmc-supply:
+    description:
+      Supply for the bus IO line power
+
+  mmc-pwrseq:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      System-on-Chip designs may specify a specific MMC power
+      sequence. To successfully detect an (e)MMC/SD/SDIO card, that
+      power sequence must be maintained while initializing the card.
+
+patternProperties:
+  "^.*@[0-9]+$":
+    type: object
+    description: |
+      On embedded systems the cards connected to a host may need
+      additional properties. These can be specified in subnodes to the
+      host controller node. The subnodes are identified by the
+      standard \'reg\' property. Which information exactly can be
+      specified depends on the bindings for the SDIO function driver
+      for the subnode, as specified by the compatible string.
+
+    properties:
+      compatible:
+        description: |
+          Name of SDIO function following generic names recommended
+          practice
+
+      reg:
+        items:
+          - minimum: 0
+            maximum: 7
+            description:
+              Must contain the SDIO function number of the function this
+              subnode describes. A value of 0 denotes the memory SD
+              function, values from 1 to 7 denote the SDIO functions.
+
+      broken-hpi:
+        $ref: /schemas/types.yaml#/definitions/flag
+        description:
+          Use this to indicate that the mmc-card has a broken hpi
+          implementation, and that hpi should not be used.
+
+    required:
+      - reg
+
+dependencies:
+  cd-debounce-delay-ms: [ cd-gpios ]
+  fixed-emmc-driver-type: [ non-removable ]
+
+examples:
+  - |
+    sdhci@ab000000 {
+        compatible = "sdhci";
+        reg = <0xab000000 0x200>;
+        interrupts = <23>;
+        bus-width = <4>;
+        cd-gpios = <&gpio 69 0>;
+        cd-inverted;
+        wp-gpios = <&gpio 70 0>;
+        max-frequency = <50000000>;
+        keep-power-in-suspend;
+        wakeup-source;
+        mmc-pwrseq = <&sdhci0_pwrseq>;
+    };
+
+  - |
+    mmc3: mmc@1c12000 {
+        #address-cells = <1>;
+        #size-cells = <0>;
+        pinctrl-names = "default";
+        pinctrl-0 = <&mmc3_pins_a>;
+        vmmc-supply = <&reg_vmmc3>;
+        bus-width = <4>;
+        non-removable;
+        mmc-pwrseq = <&sdhci0_pwrseq>;
+
+        brcmf: bcrmf@1 {
+            reg = <1>;
+            compatible = "brcm,bcm43xx-fmac";
+            interrupt-parent = <&pio>;
+            interrupts = <10 8>;
+            interrupt-names = "host-wake";
+        };
+    };
index c269dbe384feab159be98e713a328585499e473a..bf9d7d3febf102e8265b3cc1010b7da92e0320ed 100644 (file)
@@ -1,177 +1 @@
-These properties are common to multiple MMC host controllers. Any host
-that requires the respective functionality should implement them using
-these definitions.
-
-Interpreted by the OF core:
-- reg: Registers location and length.
-- interrupts: Interrupts used by the MMC controller.
-
-Card detection:
-If no property below is supplied, host native card detect is used.
-Only one of the properties in this section should be supplied:
-  - broken-cd: There is no card detection available; polling must be used.
-  - cd-gpios: Specify GPIOs for card detection, see gpio binding
-  - non-removable: non-removable slot (like eMMC); assume always present.
-
-Optional properties:
-- bus-width: Number of data lines, can be <1>, <4>, or <8>.  The default
-  will be <1> if the property is absent.
-- wp-gpios: Specify GPIOs for write protection, see gpio binding
-- cd-inverted: when present, polarity on the CD line is inverted. See the note
-  below for the case, when a GPIO is used for the CD line
-- cd-debounce-delay-ms: Set delay time before detecting card after card insert interrupt.
-  It's only valid when cd-gpios is present.
-- wp-inverted: when present, polarity on the WP line is inverted. See the note
-  below for the case, when a GPIO is used for the WP line
-- disable-wp: When set no physical WP line is present. This property should
-  only be specified when the controller has a dedicated write-protect
-  detection logic. If a GPIO is always used for the write-protect detection
-  logic it is sufficient to not specify wp-gpios property in the absence of a WP
-  line.
-- max-frequency: maximum operating clock frequency
-- no-1-8-v: when present, denotes that 1.8v card voltage is not supported on
-  this system, even if the controller claims it is.
-- cap-sd-highspeed: SD high-speed timing is supported
-- cap-mmc-highspeed: MMC high-speed timing is supported
-- sd-uhs-sdr12: SD UHS SDR12 speed is supported
-- sd-uhs-sdr25: SD UHS SDR25 speed is supported
-- sd-uhs-sdr50: SD UHS SDR50 speed is supported
-- sd-uhs-sdr104: SD UHS SDR104 speed is supported
-- sd-uhs-ddr50: SD UHS DDR50 speed is supported
-- cap-power-off-card: powering off the card is safe
-- cap-mmc-hw-reset: eMMC hardware reset is supported
-- cap-sdio-irq: enable SDIO IRQ signalling on this interface
-- full-pwr-cycle: full power cycle of the card is supported
-- mmc-ddr-3_3v: eMMC high-speed DDR mode(3.3V I/O) is supported
-- mmc-ddr-1_8v: eMMC high-speed DDR mode(1.8V I/O) is supported
-- mmc-ddr-1_2v: eMMC high-speed DDR mode(1.2V I/O) is supported
-- mmc-hs200-1_8v: eMMC HS200 mode(1.8V I/O) is supported
-- mmc-hs200-1_2v: eMMC HS200 mode(1.2V I/O) is supported
-- mmc-hs400-1_8v: eMMC HS400 mode(1.8V I/O) is supported
-- mmc-hs400-1_2v: eMMC HS400 mode(1.2V I/O) is supported
-- mmc-hs400-enhanced-strobe: eMMC HS400 enhanced strobe mode is supported
-- dsr: Value the card's (optional) Driver Stage Register (DSR) should be
-  programmed with. Valid range: [0 .. 0xffff].
-- no-sdio: controller is limited to send sdio cmd during initialization
-- no-sd: controller is limited to send sd cmd during initialization
-- no-mmc: controller is limited to send mmc cmd during initialization
-- fixed-emmc-driver-type: for non-removable eMMC, enforce this driver type.
-  The value <n> is the driver type as specified in the eMMC specification
-  (table 206 in spec version 5.1).
-- post-power-on-delay-ms : It was invented for MMC pwrseq-simple which could
-  be referred to mmc-pwrseq-simple.txt. But now it's reused as a tunable delay
-  waiting for I/O signalling and card power supply to be stable, regardless of
-  whether pwrseq-simple is used. Default to 10ms if no available.
-- supports-cqe : The presence of this property indicates that the corresponding
-  MMC host controller supports HW command queue feature.
-- disable-cqe-dcmd: This property indicates that the MMC controller's command
-  queue engine (CQE) does not support direct commands (DCMDs).
-
-*NOTE* on CD and WP polarity. To use common for all SD/MMC host controllers line
-polarity properties, we have to fix the meaning of the "normal" and "inverted"
-line levels. We choose to follow the SDHCI standard, which specifies both those
-lines as "active low." Therefore, using the "cd-inverted" property means, that
-the CD line is active high, i.e. it is high, when a card is inserted. Similar
-logic applies to the "wp-inverted" property.
-
-CD and WP lines can be implemented on the hardware in one of two ways: as GPIOs,
-specified in cd-gpios and wp-gpios properties, or as dedicated pins. Polarity of
-dedicated pins can be specified, using *-inverted properties. GPIO polarity can
-also be specified using the GPIO_ACTIVE_LOW flag. This creates an ambiguity
-in the latter case. We choose to use the XOR logic for GPIO CD and WP lines.
-This means, the two properties are "superimposed," for example leaving the
-GPIO_ACTIVE_LOW flag clear and specifying the respective *-inverted property
-property results in a double-inversion and actually means the "normal" line
-polarity is in effect.
-
-Optional SDIO properties:
-- keep-power-in-suspend: Preserves card power during a suspend/resume cycle
-- wakeup-source: Enables wake up of host system on SDIO IRQ assertion
-                (Legacy property supported: "enable-sdio-wakeup")
-
-MMC power
----------
-
-Controllers may implement power control from both the connected cards and
-the IO signaling (for example to change to high-speed 1.8V signalling). If
-the system supports this, then the following two properties should point
-to valid regulator nodes:
-
-- vqmmc-supply: supply node for IO line power
-- vmmc-supply: supply node for card's power
-
-
-MMC power sequences:
---------------------
-
-System on chip designs may specify a specific MMC power sequence. To
-successfully detect an (e)MMC/SD/SDIO card, that power sequence must be
-maintained while initializing the card.
-
-Optional property:
-- mmc-pwrseq: phandle to the MMC power sequence node. See "mmc-pwrseq-*"
-       for documentation of MMC power sequence bindings.
-
-
-Use of Function subnodes
-------------------------
-
-On embedded systems the cards connected to a host may need additional
-properties. These can be specified in subnodes to the host controller node.
-The subnodes are identified by the standard 'reg' property.
-Which information exactly can be specified depends on the bindings for the
-SDIO function driver for the subnode, as specified by the compatible string.
-
-Required host node properties when using function subnodes:
-- #address-cells: should be one. The cell is the slot id.
-- #size-cells: should be zero.
-
-Required function subnode properties:
-- reg: Must contain the SDIO function number of the function this subnode
-       describes. A value of 0 denotes the memory SD function, values from
-       1 to 7 denote the SDIO functions.
-
-Optional function subnode properties:
-- compatible: name of SDIO function following generic names recommended practice
-
-
-Examples
---------
-
-Basic example:
-
-sdhci@ab000000 {
-       compatible = "sdhci";
-       reg = <0xab000000 0x200>;
-       interrupts = <23>;
-       bus-width = <4>;
-       cd-gpios = <&gpio 69 0>;
-       cd-inverted;
-       wp-gpios = <&gpio 70 0>;
-       max-frequency = <50000000>;
-       keep-power-in-suspend;
-       wakeup-source;
-       mmc-pwrseq = <&sdhci0_pwrseq>
-}
-
-Example with sdio function subnode:
-
-mmc3: mmc@1c12000 {
-       #address-cells = <1>;
-       #size-cells = <0>;
-
-       pinctrl-names = "default";
-       pinctrl-0 = <&mmc3_pins_a>;
-       vmmc-supply = <&reg_vmmc3>;
-       bus-width = <4>;
-       non-removable;
-       mmc-pwrseq = <&sdhci0_pwrseq>
-
-       brcmf: bcrmf@1 {
-               reg = <1>;
-               compatible = "brcm,bcm43xx-fmac";
-               interrupt-parent = <&pio>;
-               interrupts = <10 8>; /* PH10 / EINT10 */
-               interrupt-names = "host-wake";
-       };
-};
+This file has moved to mmc-controller.yaml.
diff --git a/Documentation/devicetree/bindings/mmc/renesas,sdhi.txt b/Documentation/devicetree/bindings/mmc/renesas,sdhi.txt
new file mode 100644 (file)
index 0000000..dd08d03
--- /dev/null
@@ -0,0 +1,111 @@
+* Renesas SDHI SD/MMC controller
+
+Required properties:
+- compatible: should contain one or more of the following:
+               "renesas,sdhi-sh73a0" - SDHI IP on SH73A0 SoC
+               "renesas,sdhi-r7s72100" - SDHI IP on R7S72100 SoC
+               "renesas,sdhi-r7s9210" - SDHI IP on R7S9210 SoC
+               "renesas,sdhi-r8a73a4" - SDHI IP on R8A73A4 SoC
+               "renesas,sdhi-r8a7740" - SDHI IP on R8A7740 SoC
+               "renesas,sdhi-r8a7743" - SDHI IP on R8A7743 SoC
+               "renesas,sdhi-r8a7744" - SDHI IP on R8A7744 SoC
+               "renesas,sdhi-r8a7745" - SDHI IP on R8A7745 SoC
+               "renesas,sdhi-r8a774a1" - SDHI IP on R8A774A1 SoC
+               "renesas,sdhi-r8a774c0" - SDHI IP on R8A774C0 SoC
+               "renesas,sdhi-r8a77470" - SDHI IP on R8A77470 SoC
+               "renesas,sdhi-mmc-r8a77470" - SDHI/MMC IP on R8A77470 SoC
+               "renesas,sdhi-r8a7778" - SDHI IP on R8A7778 SoC
+               "renesas,sdhi-r8a7779" - SDHI IP on R8A7779 SoC
+               "renesas,sdhi-r8a7790" - SDHI IP on R8A7790 SoC
+               "renesas,sdhi-r8a7791" - SDHI IP on R8A7791 SoC
+               "renesas,sdhi-r8a7792" - SDHI IP on R8A7792 SoC
+               "renesas,sdhi-r8a7793" - SDHI IP on R8A7793 SoC
+               "renesas,sdhi-r8a7794" - SDHI IP on R8A7794 SoC
+               "renesas,sdhi-r8a7795" - SDHI IP on R8A7795 SoC
+               "renesas,sdhi-r8a7796" - SDHI IP on R8A7796 SoC
+               "renesas,sdhi-r8a77965" - SDHI IP on R8A77965 SoC
+               "renesas,sdhi-r8a77970" - SDHI IP on R8A77970 SoC
+               "renesas,sdhi-r8a77980" - SDHI IP on R8A77980 SoC
+               "renesas,sdhi-r8a77990" - SDHI IP on R8A77990 SoC
+               "renesas,sdhi-r8a77995" - SDHI IP on R8A77995 SoC
+               "renesas,sdhi-shmobile" - a generic sh-mobile SDHI controller
+               "renesas,rcar-gen1-sdhi" - a generic R-Car Gen1 SDHI controller
+               "renesas,rcar-gen2-sdhi" - a generic R-Car Gen2 and RZ/G1 SDHI
+                                          (not SDHI/MMC) controller
+               "renesas,rcar-gen3-sdhi" - a generic R-Car Gen3 or RZ/G2
+                                          SDHI controller
+
+
+               When compatible with the generic version, nodes must list
+               the SoC-specific version corresponding to the platform
+               first followed by the generic version.
+
+- clocks: Most controllers only have 1 clock source per channel. However, on
+         some variations of this controller, the internal card detection
+         logic that exists in this controller is sectioned off to be run by a
+         separate second clock source to allow the main core clock to be turned
+         off to save power.
+         If 2 clocks are specified by the hardware, you must name them as
+         "core" and "cd". If the controller only has 1 clock, naming is not
+         required.
+         Devices which have more than 1 clock are listed below:
+         2: R7S72100, R7S9210
+
+Optional properties:
+- pinctrl-names: should be "default", "state_uhs"
+- pinctrl-0: should contain default/high speed pin ctrl
+- pinctrl-1: should contain uhs mode pin ctrl
+
+Example: R8A7790 (R-Car H2) SDHI controller nodes
+
+       sdhi0: sd@ee100000 {
+               compatible = "renesas,sdhi-r8a7790", "renesas,rcar-gen2-sdhi";
+               reg = <0 0xee100000 0 0x328>;
+               interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cpg CPG_MOD 314>;
+               dmas = <&dmac0 0xcd>, <&dmac0 0xce>,
+                      <&dmac1 0xcd>, <&dmac1 0xce>;
+               dma-names = "tx", "rx", "tx", "rx";
+               max-frequency = <195000000>;
+               power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+               resets = <&cpg 314>;
+       };
+
+       sdhi1: sd@ee120000 {
+               compatible = "renesas,sdhi-r8a7790", "renesas,rcar-gen2-sdhi";
+               reg = <0 0xee120000 0 0x328>;
+               interrupts = <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cpg CPG_MOD 313>;
+               dmas = <&dmac0 0xc9>, <&dmac0 0xca>,
+                      <&dmac1 0xc9>, <&dmac1 0xca>;
+               dma-names = "tx", "rx", "tx", "rx";
+               max-frequency = <195000000>;
+               power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+               resets = <&cpg 313>;
+       };
+
+       sdhi2: sd@ee140000 {
+               compatible = "renesas,sdhi-r8a7790", "renesas,rcar-gen2-sdhi";
+               reg = <0 0xee140000 0 0x100>;
+               interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cpg CPG_MOD 312>;
+               dmas = <&dmac0 0xc1>, <&dmac0 0xc2>,
+                      <&dmac1 0xc1>, <&dmac1 0xc2>;
+               dma-names = "tx", "rx", "tx", "rx";
+               max-frequency = <97500000>;
+               power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+               resets = <&cpg 312>;
+       };
+
+       sdhi3: sd@ee160000 {
+               compatible = "renesas,sdhi-r8a7790", "renesas,rcar-gen2-sdhi";
+               reg = <0 0xee160000 0 0x100>;
+               interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cpg CPG_MOD 311>;
+               dmas = <&dmac0 0xd3>, <&dmac0 0xd4>,
+                      <&dmac1 0xd3>, <&dmac1 0xd4>;
+               dma-names = "tx", "rx", "tx", "rx";
+               max-frequency = <97500000>;
+               power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+               resets = <&cpg 311>;
+       };
index 15dbbbace27eb35be924af9c1657bbd374ffaf79..50e87df479718f0a2f4fac762301ff4cd7c3eb91 100644 (file)
@@ -8,7 +8,10 @@ Only deviations are documented here.
   [3] Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
 
 Required Properties:
-       - compatible: should be "ti,am654-sdhci-5.1"
+       - compatible: should be one of:
+                       "ti,am654-sdhci-5.1": SDHCI on AM654 device.
+                       "ti,j721e-sdhci-8bit": 8 bit SDHCI on J721E device.
+                       "ti,j721e-sdhci-4bit": 4 bit SDHCI on J721E device.
        - reg: Must be two entries.
                - The first should be the sdhci register space
                - The second should the subsystem/phy register space
@@ -16,9 +19,13 @@ Required Properties:
        - clock-names: Tuple including "clk_xin" and "clk_ahb"
        - interrupts: Interrupt specifiers
        - ti,otap-del-sel: Output Tap Delay select
+
+Optional Properties (Required for ti,am654-sdhci-5.1 and ti,j721e-sdhci-8bit):
        - ti,trm-icp: DLL trim select
        - ti,driver-strength-ohm: driver strength in ohms.
                                  Valid values are 33, 40, 50, 66 and 100 ohms.
+Optional Properties:
+       - ti,strobe-sel: strobe select delay for HS400 speed mode. Default value: 0x0.
 
 Example:
 
index 45c9978aad7b091229865577d1a3efd2a98288ce..eb7eb1b529f070be3236f3cdedb61a494fe46fb0 100644 (file)
@@ -14,10 +14,31 @@ Required properties:
 - clock-names: Should contain the following:
        "sdio" - SDIO source clock (required)
        "enable" - gate clock which used for enabling/disabling the device (required)
+       "2x_enable" - gate clock controlling the device for some special platforms (optional)
 
 Optional properties:
 - assigned-clocks: the same with "sdio" clock
 - assigned-clock-parents: the default parent of "sdio" clock
+- pinctrl-names: should be "default", "state_uhs"
+- pinctrl-0: should contain default/high speed pin control
+- pinctrl-1: should contain uhs mode pin control
+
+PHY DLL delays are used to delay the data valid window, and align the window
+to sampling clock. PHY DLL delays can be configured by following properties,
+and each property contains 4 cells which are used to configure the clock data
+write line delay value, clock read command line delay value, clock read data
+positive edge delay value and clock read data negative edge delay value.
+Each cell's delay value unit is cycle of the PHY clock.
+
+- sprd,phy-delay-legacy: Delay value for legacy timing.
+- sprd,phy-delay-sd-highspeed: Delay value for SD high-speed timing.
+- sprd,phy-delay-sd-uhs-sdr50: Delay value for SD UHS SDR50 timing.
+- sprd,phy-delay-sd-uhs-sdr104: Delay value for SD UHS SDR50 timing.
+- sprd,phy-delay-mmc-highspeed: Delay value for MMC high-speed timing.
+- sprd,phy-delay-mmc-ddr52: Delay value for MMC DDR52 timing.
+- sprd,phy-delay-mmc-hs200: Delay value for MMC HS200 timing.
+- sprd,phy-delay-mmc-hs400: Delay value for MMC HS400 timing.
+- sprd,phy-delay-mmc-hs400es: Delay value for MMC HS400 enhanced strobe timing.
 
 Examples:
 
@@ -32,6 +53,11 @@ sdio0: sdio@20600000 {
        assigned-clocks = <&ap_clk CLK_EMMC_2X>;
        assigned-clock-parents = <&rpll CLK_RPLL_390M>;
 
+       pinctrl-names = "default", "state_uhs";
+       pinctrl-0 = <&sd0_pins_default>;
+       pinctrl-1 = <&sd0_pins_uhs>;
+
+       sprd,phy-delay-sd-uhs-sdr104 = <0x3f 0x7f 0x2e 0x2e>;
        bus-width = <8>;
        non-removable;
        no-sdio;
diff --git a/Documentation/devicetree/bindings/mmc/sunxi-mmc.txt b/Documentation/devicetree/bindings/mmc/sunxi-mmc.txt
deleted file mode 100644 (file)
index e9cb3ec..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-* Allwinner sunxi MMC controller
-
-The highspeed MMC host controller on Allwinner SoCs provides an interface
-for MMC, SD and SDIO types of memory cards.
-
-Supported maximum speeds are the ones of the eMMC standard 4.5 as well
-as the speed of SD standard 3.0.
-Absolute maximum transfer rate is 200MB/s
-
-Required properties:
- - compatible : should be one of:
-   * "allwinner,sun4i-a10-mmc"
-   * "allwinner,sun5i-a13-mmc"
-   * "allwinner,sun7i-a20-mmc"
-   * "allwinner,sun8i-a83t-emmc"
-   * "allwinner,sun9i-a80-mmc"
-   * "allwinner,sun50i-a64-emmc"
-   * "allwinner,sun50i-a64-mmc"
-   * "allwinner,sun50i-h6-emmc", "allwinner.sun50i-a64-emmc"
-   * "allwinner,sun50i-h6-mmc", "allwinner.sun50i-a64-mmc"
- - reg : mmc controller base registers
- - clocks : a list with 4 phandle + clock specifier pairs
- - clock-names : must contain "ahb", "mmc", "output" and "sample"
- - interrupts : mmc controller interrupt
-
-Optional properties:
- - resets : phandle + reset specifier pair
- - reset-names : must contain "ahb"
- - for cd, bus-width and additional generic mmc parameters
-   please refer to mmc.txt within this directory
-
-Examples:
-       - Within .dtsi:
-       mmc0: mmc@1c0f000 {
-               compatible = "allwinner,sun5i-a13-mmc";
-               reg = <0x01c0f000 0x1000>;
-               clocks = <&ahb_gates 8>, <&mmc0_clk>, <&mmc0_output_clk>, <&mmc0_sample_clk>;
-               clock-names = "ahb", "mod", "output", "sample";
-               interrupts = <0 32 4>;
-               status = "disabled";
-       };
-
-       - Within dts:
-       mmc0: mmc@1c0f000 {
-               pinctrl-names = "default", "default";
-               pinctrl-0 = <&mmc0_pins_a>;
-               pinctrl-1 = <&mmc0_cd_pin_reference_design>;
-               bus-width = <4>;
-               cd-gpios = <&pio 7 1 0>; /* PH1 */
-               cd-inverted;
-               status = "okay";
-       };
diff --git a/Documentation/devicetree/bindings/mmc/tmio_mmc.txt b/Documentation/devicetree/bindings/mmc/tmio_mmc.txt
deleted file mode 100644 (file)
index 2b4f17c..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-* Toshiba Mobile IO SD/MMC controller
-
-The tmio-mmc driver doesn't probe its devices actively, instead its binding to
-devices is managed by either MFD drivers or by the sh_mobile_sdhi platform
-driver. Those drivers supply the tmio-mmc driver with platform data, that either
-describe hardware capabilities, known to them, or are obtained by them from
-their own platform data or from their DT information. In the latter case all
-compulsory and any optional properties, common to all SD/MMC drivers, as
-described in mmc.txt, can be used. Additionally the following tmio_mmc-specific
-optional bindings can be used.
-
-Required properties:
-- compatible: should contain one or more of the following:
-               "renesas,sdhi-sh73a0" - SDHI IP on SH73A0 SoC
-               "renesas,sdhi-r7s72100" - SDHI IP on R7S72100 SoC
-               "renesas,sdhi-r7s9210" - SDHI IP on R7S9210 SoC
-               "renesas,sdhi-r8a73a4" - SDHI IP on R8A73A4 SoC
-               "renesas,sdhi-r8a7740" - SDHI IP on R8A7740 SoC
-               "renesas,sdhi-r8a7743" - SDHI IP on R8A7743 SoC
-               "renesas,sdhi-r8a7744" - SDHI IP on R8A7744 SoC
-               "renesas,sdhi-r8a7745" - SDHI IP on R8A7745 SoC
-               "renesas,sdhi-r8a774a1" - SDHI IP on R8A774A1 SoC
-               "renesas,sdhi-r8a774c0" - SDHI IP on R8A774C0 SoC
-               "renesas,sdhi-r8a77470" - SDHI IP on R8A77470 SoC
-               "renesas,sdhi-mmc-r8a77470" - SDHI/MMC IP on R8A77470 SoC
-               "renesas,sdhi-r8a7778" - SDHI IP on R8A7778 SoC
-               "renesas,sdhi-r8a7779" - SDHI IP on R8A7779 SoC
-               "renesas,sdhi-r8a7790" - SDHI IP on R8A7790 SoC
-               "renesas,sdhi-r8a7791" - SDHI IP on R8A7791 SoC
-               "renesas,sdhi-r8a7792" - SDHI IP on R8A7792 SoC
-               "renesas,sdhi-r8a7793" - SDHI IP on R8A7793 SoC
-               "renesas,sdhi-r8a7794" - SDHI IP on R8A7794 SoC
-               "renesas,sdhi-r8a7795" - SDHI IP on R8A7795 SoC
-               "renesas,sdhi-r8a7796" - SDHI IP on R8A7796 SoC
-               "renesas,sdhi-r8a77965" - SDHI IP on R8A77965 SoC
-               "renesas,sdhi-r8a77970" - SDHI IP on R8A77970 SoC
-               "renesas,sdhi-r8a77980" - SDHI IP on R8A77980 SoC
-               "renesas,sdhi-r8a77990" - SDHI IP on R8A77990 SoC
-               "renesas,sdhi-r8a77995" - SDHI IP on R8A77995 SoC
-               "renesas,sdhi-shmobile" - a generic sh-mobile SDHI controller
-               "renesas,rcar-gen1-sdhi" - a generic R-Car Gen1 SDHI controller
-               "renesas,rcar-gen2-sdhi" - a generic R-Car Gen2 and RZ/G1 SDHI
-                                          (not SDHI/MMC) controller
-               "renesas,rcar-gen3-sdhi" - a generic R-Car Gen3 or RZ/G2
-                                          SDHI controller
-
-
-               When compatible with the generic version, nodes must list
-               the SoC-specific version corresponding to the platform
-               first followed by the generic version.
-
-- clocks: Most controllers only have 1 clock source per channel. However, on
-         some variations of this controller, the internal card detection
-         logic that exists in this controller is sectioned off to be run by a
-         separate second clock source to allow the main core clock to be turned
-         off to save power.
-         If 2 clocks are specified by the hardware, you must name them as
-         "core" and "cd". If the controller only has 1 clock, naming is not
-         required.
-         Devices which have more than 1 clock are listed below:
-         2: R7S72100, R7S9210
-
-Optional properties:
-- pinctrl-names: should be "default", "state_uhs"
-- pinctrl-0: should contain default/high speed pin ctrl
-- pinctrl-1: should contain uhs mode pin ctrl
-
-Example: R8A7790 (R-Car H2) SDHI controller nodes
-
-       sdhi0: sd@ee100000 {
-               compatible = "renesas,sdhi-r8a7790", "renesas,rcar-gen2-sdhi";
-               reg = <0 0xee100000 0 0x328>;
-               interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>;
-               clocks = <&cpg CPG_MOD 314>;
-               dmas = <&dmac0 0xcd>, <&dmac0 0xce>,
-                      <&dmac1 0xcd>, <&dmac1 0xce>;
-               dma-names = "tx", "rx", "tx", "rx";
-               max-frequency = <195000000>;
-               power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-               resets = <&cpg 314>;
-       };
-
-       sdhi1: sd@ee120000 {
-               compatible = "renesas,sdhi-r8a7790", "renesas,rcar-gen2-sdhi";
-               reg = <0 0xee120000 0 0x328>;
-               interrupts = <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>;
-               clocks = <&cpg CPG_MOD 313>;
-               dmas = <&dmac0 0xc9>, <&dmac0 0xca>,
-                      <&dmac1 0xc9>, <&dmac1 0xca>;
-               dma-names = "tx", "rx", "tx", "rx";
-               max-frequency = <195000000>;
-               power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-               resets = <&cpg 313>;
-       };
-
-       sdhi2: sd@ee140000 {
-               compatible = "renesas,sdhi-r8a7790", "renesas,rcar-gen2-sdhi";
-               reg = <0 0xee140000 0 0x100>;
-               interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>;
-               clocks = <&cpg CPG_MOD 312>;
-               dmas = <&dmac0 0xc1>, <&dmac0 0xc2>,
-                      <&dmac1 0xc1>, <&dmac1 0xc2>;
-               dma-names = "tx", "rx", "tx", "rx";
-               max-frequency = <97500000>;
-               power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-               resets = <&cpg 312>;
-       };
-
-       sdhi3: sd@ee160000 {
-               compatible = "renesas,sdhi-r8a7790", "renesas,rcar-gen2-sdhi";
-               reg = <0 0xee160000 0 0x100>;
-               interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
-               clocks = <&cpg CPG_MOD 311>;
-               dmas = <&dmac0 0xd3>, <&dmac0 0xd4>,
-                      <&dmac1 0xd3>, <&dmac1 0xd4>;
-               dma-names = "tx", "rx", "tx", "rx";
-               max-frequency = <97500000>;
-               power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
-               resets = <&cpg 311>;
-       };
index 03ba90ffc0f8f1130dd56fef97ecb9bf7a058a44..7e0486ad1318cdf3037b0689340f4faa407ed13b 100644 (file)
@@ -89,13 +89,6 @@ static inline dma_addr_t virt_to_dma(struct device *dev, void *addr)
 }
 #endif
 
-/* The ARM override for dma_max_pfn() */
-static inline unsigned long dma_max_pfn(struct device *dev)
-{
-       return dma_to_pfn(dev, *dev->dma_mask);
-}
-#define dma_max_pfn(dev) dma_max_pfn(dev)
-
 /* do not use this function in a driver */
 static inline bool is_device_dma_coherent(struct device *dev)
 {
index 6cfb293396f2c4639c08bd11d5b0e744bef1d596..693ee73eb2912c05abdbfbe4955757cc767c0731 100644 (file)
@@ -625,13 +625,18 @@ static int __init memstick_init(void)
                return -ENOMEM;
 
        rc = bus_register(&memstick_bus_type);
-       if (!rc)
-               rc = class_register(&memstick_host_class);
+       if (rc)
+               goto error_destroy_workqueue;
 
-       if (!rc)
-               return 0;
+       rc = class_register(&memstick_host_class);
+       if (rc)
+               goto error_bus_unregister;
+
+       return 0;
 
+error_bus_unregister:
        bus_unregister(&memstick_bus_type);
+error_destroy_workqueue:
        destroy_workqueue(workqueue);
 
        return rc;
index 2797771a5fa8b033cd6a8d0a28f3ea502cc2d2be..09e0c765946917e77517ac41cb0f114152abee70 100644 (file)
@@ -227,45 +227,21 @@ void mmc_add_host_debugfs(struct mmc_host *host)
        struct dentry *root;
 
        root = debugfs_create_dir(mmc_hostname(host), NULL);
-       if (IS_ERR(root))
-               /* Don't complain -- debugfs just isn't enabled */
-               return;
-       if (!root)
-               /* Complain -- debugfs is enabled, but it failed to
-                * create the directory. */
-               goto err_root;
-
        host->debugfs_root = root;
 
-       if (!debugfs_create_file("ios", S_IRUSR, root, host, &mmc_ios_fops))
-               goto err_node;
-
-       if (!debugfs_create_x32("caps", S_IRUSR, root, &host->caps))
-               goto err_node;
-
-       if (!debugfs_create_x32("caps2", S_IRUSR, root, &host->caps2))
-               goto err_node;
-
-       if (!debugfs_create_file("clock", S_IRUSR | S_IWUSR, root, host,
-                       &mmc_clock_fops))
-               goto err_node;
+       debugfs_create_file("ios", S_IRUSR, root, host, &mmc_ios_fops);
+       debugfs_create_x32("caps", S_IRUSR, root, &host->caps);
+       debugfs_create_x32("caps2", S_IRUSR, root, &host->caps2);
+       debugfs_create_file("clock", S_IRUSR | S_IWUSR, root, host,
+                           &mmc_clock_fops);
 
 #ifdef CONFIG_FAIL_MMC_REQUEST
        if (fail_request)
                setup_fault_attr(&fail_default_attr, fail_request);
        host->fail_mmc_request = fail_default_attr;
-       if (IS_ERR(fault_create_debugfs_attr("fail_mmc_request",
-                                            root,
-                                            &host->fail_mmc_request)))
-               goto err_node;
+       fault_create_debugfs_attr("fail_mmc_request", root,
+                                 &host->fail_mmc_request);
 #endif
-       return;
-
-err_node:
-       debugfs_remove_recursive(root);
-       host->debugfs_root = NULL;
-err_root:
-       dev_err(&host->class_dev, "failed to initialize debugfs\n");
 }
 
 void mmc_remove_host_debugfs(struct mmc_host *host)
@@ -282,25 +258,9 @@ void mmc_add_card_debugfs(struct mmc_card *card)
                return;
 
        root = debugfs_create_dir(mmc_card_id(card), host->debugfs_root);
-       if (IS_ERR(root))
-               /* Don't complain -- debugfs just isn't enabled */
-               return;
-       if (!root)
-               /* Complain -- debugfs is enabled, but it failed to
-                * create the directory. */
-               goto err;
-
        card->debugfs_root = root;
 
-       if (!debugfs_create_x32("state", S_IRUSR, root, &card->state))
-               goto err;
-
-       return;
-
-err:
-       debugfs_remove_recursive(root);
-       card->debugfs_root = NULL;
-       dev_err(&card->dev, "failed to initialize debugfs\n");
+       debugfs_create_x32("state", S_IRUSR, root, &card->state);
 }
 
 void mmc_remove_card_debugfs(struct mmc_card *card)
index b27df2d2b5ae19ee7ee72a7a5aa0a9c8f8eec29b..492dd45963142b72ad359067fa648a32a533b572 100644 (file)
@@ -3167,15 +3167,7 @@ static int __mmc_test_register_dbgfs_file(struct mmc_card *card,
        struct mmc_test_dbgfs_file *df;
 
        if (card->debugfs_root)
-               file = debugfs_create_file(name, mode, card->debugfs_root,
-                       card, fops);
-
-       if (IS_ERR_OR_NULL(file)) {
-               dev_err(&card->dev,
-                       "Can't create %s. Perhaps debugfs is disabled.\n",
-                       name);
-               return -ENODEV;
-       }
+               debugfs_create_file(name, mode, card->debugfs_root, card, fops);
 
        df = kmalloc(sizeof(*df), GFP_KERNEL);
        if (!df) {
index 3557d5c51141da7cec0d961947d54dbeec7390f4..e327f80ebe7048ea74ff70a67cfa0e350b15a0e0 100644 (file)
@@ -350,18 +350,15 @@ static const struct blk_mq_ops mmc_mq_ops = {
 static void mmc_setup_queue(struct mmc_queue *mq, struct mmc_card *card)
 {
        struct mmc_host *host = card->host;
-       u64 limit = BLK_BOUNCE_HIGH;
        unsigned block_size = 512;
 
-       if (mmc_dev(host)->dma_mask && *mmc_dev(host)->dma_mask)
-               limit = (u64)dma_max_pfn(mmc_dev(host)) << PAGE_SHIFT;
-
        blk_queue_flag_set(QUEUE_FLAG_NONROT, mq->queue);
        blk_queue_flag_clear(QUEUE_FLAG_ADD_RANDOM, mq->queue);
        if (mmc_can_erase(card))
                mmc_queue_setup_discard(mq->queue, card);
 
-       blk_queue_bounce_limit(mq->queue, limit);
+       if (!mmc_dev(host)->dma_mask || !*mmc_dev(host)->dma_mask)
+               blk_queue_bounce_limit(mq->queue, BLK_BOUNCE_HIGH);
        blk_queue_max_hw_sectors(mq->queue,
                min(host->max_blk_count, host->max_req_size / 512));
        blk_queue_max_segments(mq->queue, host->max_segs);
index 712a7742765e992023e804544dbc987f89e99521..8dd8fc32eccafb748ce4551fd55199d001b987b8 100644 (file)
@@ -559,7 +559,7 @@ static void mmc_sdio_resend_if_cond(struct mmc_host *host,
  * we're trying to reinitialise.
  */
 static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
-                             struct mmc_card *oldcard, int powered_resume)
+                             struct mmc_card *oldcard)
 {
        struct mmc_card *card;
        int err;
@@ -582,11 +582,9 @@ try_again:
        /*
         * Inform the card of the voltage
         */
-       if (!powered_resume) {
-               err = mmc_send_io_op_cond(host, ocr, &rocr);
-               if (err)
-                       goto err;
-       }
+       err = mmc_send_io_op_cond(host, ocr, &rocr);
+       if (err)
+               goto err;
 
        /*
         * For SPI, enable CRC as appropriate.
@@ -645,7 +643,7 @@ try_again:
         * try to init uhs card. sdio_read_cccr will take over this task
         * to make sure which speed mode should work.
         */
-       if (!powered_resume && (rocr & ocr & R4_18V_PRESENT)) {
+       if (rocr & ocr & R4_18V_PRESENT) {
                err = mmc_set_uhs_voltage(host, ocr_card);
                if (err == -EAGAIN) {
                        mmc_sdio_resend_if_cond(host, card);
@@ -659,7 +657,7 @@ try_again:
        /*
         * For native busses:  set card RCA and quit open drain mode.
         */
-       if (!powered_resume && !mmc_host_is_spi(host)) {
+       if (!mmc_host_is_spi(host)) {
                err = mmc_send_relative_addr(host, &card->rca);
                if (err)
                        goto remove;
@@ -687,7 +685,7 @@ try_again:
        /*
         * Select card, as all following commands rely on that.
         */
-       if (!powered_resume && !mmc_host_is_spi(host)) {
+       if (!mmc_host_is_spi(host)) {
                err = mmc_select_card(card);
                if (err)
                        goto remove;
@@ -816,10 +814,27 @@ err:
        return err;
 }
 
-static int mmc_sdio_reinit_card(struct mmc_host *host, bool powered_resume)
+static int mmc_sdio_reinit_card(struct mmc_host *host)
 {
        int ret;
 
+       /*
+        * Reset the card by performing the same steps that are taken by
+        * mmc_rescan_try_freq() and mmc_attach_sdio() during a "normal" probe.
+        *
+        * sdio_reset() is technically not needed. Having just powered up the
+        * hardware, it should already be in reset state. However, some
+        * platforms (such as SD8686 on OLPC) do not instantly cut power,
+        * meaning that a reset is required when restoring power soon after
+        * powering off. It is harmless in other cases.
+        *
+        * The CMD5 reset (mmc_send_io_op_cond()), according to the SDIO spec,
+        * is not necessary for non-removable cards. However, it is required
+        * for OLPC SD8686 (which expects a [CMD5,5,3,7] init sequence), and
+        * harmless in other situations.
+        *
+        */
+
        sdio_reset(host);
        mmc_go_idle(host);
        mmc_send_if_cond(host, host->card->ocr);
@@ -828,8 +843,7 @@ static int mmc_sdio_reinit_card(struct mmc_host *host, bool powered_resume)
        if (ret)
                return ret;
 
-       return mmc_sdio_init_card(host, host->card->ocr, host->card,
-                                 powered_resume);
+       return mmc_sdio_init_card(host, host->card->ocr, host->card);
 }
 
 /*
@@ -965,7 +979,11 @@ static int mmc_sdio_resume(struct mmc_host *host)
        /* Basic card reinitialization. */
        mmc_claim_host(host);
 
-       /* Restore power if needed */
+       /*
+        * Restore power and reinitialize the card when needed. Note that a
+        * removable card is checked from a detect work later on in the resume
+        * process.
+        */
        if (!mmc_card_keep_power(host)) {
                mmc_power_up(host, host->card->ocr);
                /*
@@ -979,12 +997,8 @@ static int mmc_sdio_resume(struct mmc_host *host)
                        pm_runtime_set_active(&host->card->dev);
                        pm_runtime_enable(&host->card->dev);
                }
-       }
-
-       /* No need to reinitialize powered-resumed nonremovable cards */
-       if (mmc_card_is_removable(host) || !mmc_card_keep_power(host)) {
-               err = mmc_sdio_reinit_card(host, mmc_card_keep_power(host));
-       } else if (mmc_card_keep_power(host) && mmc_card_wake_sdio_irq(host)) {
+               err = mmc_sdio_reinit_card(host);
+       } else if (mmc_card_wake_sdio_irq(host)) {
                /* We may have switched to 1-bit mode during suspend */
                err = sdio_enable_4bit_bus(host->card);
        }
@@ -1009,38 +1023,6 @@ out:
        return err;
 }
 
-static int mmc_sdio_power_restore(struct mmc_host *host)
-{
-       int ret;
-
-       /*
-        * Reset the card by performing the same steps that are taken by
-        * mmc_rescan_try_freq() and mmc_attach_sdio() during a "normal" probe.
-        *
-        * sdio_reset() is technically not needed. Having just powered up the
-        * hardware, it should already be in reset state. However, some
-        * platforms (such as SD8686 on OLPC) do not instantly cut power,
-        * meaning that a reset is required when restoring power soon after
-        * powering off. It is harmless in other cases.
-        *
-        * The CMD5 reset (mmc_send_io_op_cond()), according to the SDIO spec,
-        * is not necessary for non-removable cards. However, it is required
-        * for OLPC SD8686 (which expects a [CMD5,5,3,7] init sequence), and
-        * harmless in other situations.
-        *
-        */
-
-       mmc_claim_host(host);
-
-       ret = mmc_sdio_reinit_card(host, mmc_card_keep_power(host));
-       if (!ret && host->sdio_irqs)
-               mmc_signal_sdio_irq(host);
-
-       mmc_release_host(host);
-
-       return ret;
-}
-
 static int mmc_sdio_runtime_suspend(struct mmc_host *host)
 {
        /* No references to the card, cut the power to it. */
@@ -1058,7 +1040,7 @@ static int mmc_sdio_runtime_resume(struct mmc_host *host)
        /* Restore power and re-initialize. */
        mmc_claim_host(host);
        mmc_power_up(host, host->card->ocr);
-       ret = mmc_sdio_power_restore(host);
+       ret = mmc_sdio_reinit_card(host);
        mmc_release_host(host);
 
        return ret;
@@ -1067,7 +1049,7 @@ static int mmc_sdio_runtime_resume(struct mmc_host *host)
 static int mmc_sdio_hw_reset(struct mmc_host *host)
 {
        mmc_power_cycle(host, host->card->ocr);
-       return mmc_sdio_power_restore(host);
+       return mmc_sdio_reinit_card(host);
 }
 
 static int mmc_sdio_sw_reset(struct mmc_host *host)
@@ -1079,7 +1061,7 @@ static int mmc_sdio_sw_reset(struct mmc_host *host)
        mmc_set_initial_state(host);
        mmc_set_initial_signal_voltage(host);
 
-       return mmc_sdio_reinit_card(host, 0);
+       return mmc_sdio_reinit_card(host);
 }
 
 static const struct mmc_bus_ops mmc_sdio_ops = {
@@ -1129,7 +1111,7 @@ int mmc_attach_sdio(struct mmc_host *host)
        /*
         * Detect and init the card.
         */
-       err = mmc_sdio_init_card(host, rocr, NULL, 0);
+       err = mmc_sdio_init_card(host, rocr, NULL);
        if (err)
                goto err;
 
index 9f54a259a1b36ed4053d56c1b6c5e054386bfd3d..0bcc5e83bd1a0b6774635d37d9cab881cee869b0 100644 (file)
@@ -92,7 +92,7 @@ static int process_sdio_pending_irqs(struct mmc_host *host)
        return ret;
 }
 
-void sdio_run_irqs(struct mmc_host *host)
+static void sdio_run_irqs(struct mmc_host *host)
 {
        mmc_claim_host(host);
        if (host->sdio_irqs) {
@@ -103,7 +103,6 @@ void sdio_run_irqs(struct mmc_host *host)
        }
        mmc_release_host(host);
 }
-EXPORT_SYMBOL_GPL(sdio_run_irqs);
 
 void sdio_irq_work(struct work_struct *work)
 {
index 931770f17087c420251805d09e9fbcf964d9133d..14d89a108edd2274c264fd43f460e90d91123223 100644 (file)
@@ -996,7 +996,7 @@ config MMC_SDHCI_OMAP
 
 config MMC_SDHCI_AM654
        tristate "Support for the SDHCI Controller in TI's AM654 SOCs"
-       depends on MMC_SDHCI_PLTFM && OF
+       depends on MMC_SDHCI_PLTFM && OF && REGMAP_MMIO
        select MMC_SDHCI_IO_ACCESSORS
        help
          This selects the Secure Digital Host Controller Interface (SDHCI)
index e481535cba2ba90c51056328b2aa34deaf39bba5..1aee485d56d4c4a13b9b899f1e1bba88613ac1cd 100644 (file)
@@ -672,7 +672,7 @@ static void alcor_set_clock(struct alcor_sdmmc_host *host, unsigned int clock)
                tmp_clock = DIV_ROUND_UP(cfg->clk_src_freq, tmp_div);
                tmp_diff = abs(clock - tmp_clock);
 
-               if (tmp_diff >= 0 && tmp_diff < diff) {
+               if (tmp_diff < diff) {
                        diff = tmp_diff;
                        clk_src = cfg->clk_src_reg;
                        clk_div = tmp_div;
index 11a208cfba04a2992343af7e7ed2b0fd845b0817..914e17bab3bed56ad1baccb0554a0b56a130a63f 100644 (file)
@@ -110,7 +110,6 @@ struct goldfish_mmc_host {
        struct mmc_request      *mrq;
        struct mmc_command      *cmd;
        struct mmc_data         *data;
-       struct mmc_host         *mmc;
        struct device           *dev;
        unsigned char           id; /* 16xx chips have 2 MMC blocks */
        void                    *virt_base;
@@ -172,7 +171,7 @@ goldfish_mmc_start_command(struct goldfish_mmc_host *host, struct mmc_command *c
                resptype = 3;
                break;
        default:
-               dev_err(mmc_dev(host->mmc),
+               dev_err(mmc_dev(mmc_from_priv(host)),
                        "Invalid response type: %04x\n", mmc_resp_type(cmd));
                break;
        }
@@ -218,8 +217,8 @@ static void goldfish_mmc_xfer_done(struct goldfish_mmc_host *host,
                                        data->sg->length);
                }
                host->data->bytes_xfered += data->sg->length;
-               dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->sg_len,
-                            dma_data_dir);
+               dma_unmap_sg(mmc_dev(mmc_from_priv(host)), data->sg,
+                            host->sg_len, dma_data_dir);
        }
 
        host->data = NULL;
@@ -233,7 +232,7 @@ static void goldfish_mmc_xfer_done(struct goldfish_mmc_host *host,
 
        if (!data->stop) {
                host->mrq = NULL;
-               mmc_request_done(host->mmc, data->mrq);
+               mmc_request_done(mmc_from_priv(host), data->mrq);
                return;
        }
 
@@ -275,7 +274,7 @@ static void goldfish_mmc_cmd_done(struct goldfish_mmc_host *host,
 
        if (host->data == NULL || cmd->error) {
                host->mrq = NULL;
-               mmc_request_done(host->mmc, cmd->mrq);
+               mmc_request_done(mmc_from_priv(host), cmd->mrq);
        }
 }
 
@@ -310,7 +309,7 @@ static irqreturn_t goldfish_mmc_irq(int irq, void *dev_id)
                struct mmc_request *mrq = host->mrq;
                mrq->cmd->error = -ETIMEDOUT;
                host->mrq = NULL;
-               mmc_request_done(host->mmc, mrq);
+               mmc_request_done(mmc_from_priv(host), mrq);
        }
 
        if (end_command)
@@ -336,12 +335,13 @@ static irqreturn_t goldfish_mmc_irq(int irq, void *dev_id)
                u32 state = GOLDFISH_MMC_READ(host, MMC_STATE);
                pr_info("%s: Card detect now %d\n", __func__,
                        (state & MMC_STATE_INSERTED));
-               mmc_detect_change(host->mmc, 0);
+               mmc_detect_change(mmc_from_priv(host), 0);
        }
 
        if (!end_command && !end_transfer && !state_changed && !cmd_timeout) {
                status = GOLDFISH_MMC_READ(host, MMC_INT_STATUS);
-               dev_info(mmc_dev(host->mmc),"spurious irq 0x%04x\n", status);
+               dev_info(mmc_dev(mmc_from_priv(host)), "spurious irq 0x%04x\n",
+                        status);
                if (status != 0) {
                        GOLDFISH_MMC_WRITE(host, MMC_INT_STATUS, status);
                        GOLDFISH_MMC_WRITE(host, MMC_INT_ENABLE, 0);
@@ -380,7 +380,7 @@ static void goldfish_mmc_prepare_data(struct goldfish_mmc_host *host,
 
        dma_data_dir = mmc_get_dma_dir(data);
 
-       host->sg_len = dma_map_sg(mmc_dev(host->mmc), data->sg,
+       host->sg_len = dma_map_sg(mmc_dev(mmc_from_priv(host)), data->sg,
                                  sg_len, dma_data_dir);
        host->dma_done = 0;
        host->dma_in_use = 1;
@@ -458,7 +458,6 @@ static int goldfish_mmc_probe(struct platform_device *pdev)
        }
 
        host = mmc_priv(mmc);
-       host->mmc = mmc;
 
        pr_err("mmc: Mapping %lX to %lX\n", (long)res->start, (long)res->end);
        host->reg_base = ioremap(res->start, resource_size(res));
@@ -505,8 +504,7 @@ static int goldfish_mmc_probe(struct platform_device *pdev)
 
        ret = device_create_file(&pdev->dev, &dev_attr_cover_switch);
        if (ret)
-               dev_warn(mmc_dev(host->mmc),
-                        "Unable to create sysfs attributes\n");
+               dev_warn(mmc_dev(mmc), "Unable to create sysfs attributes\n");
 
        GOLDFISH_MMC_WRITE(host, MMC_SET_BUFFER, host->phys_base);
        GOLDFISH_MMC_WRITE(host, MMC_INT_ENABLE,
@@ -522,7 +520,7 @@ err_request_irq_failed:
 dma_alloc_failed:
        iounmap(host->reg_base);
 ioremap_failed:
-       mmc_free_host(host->mmc);
+       mmc_free_host(mmc);
 err_alloc_host_failed:
        return ret;
 }
@@ -530,14 +528,15 @@ err_alloc_host_failed:
 static int goldfish_mmc_remove(struct platform_device *pdev)
 {
        struct goldfish_mmc_host *host = platform_get_drvdata(pdev);
+       struct mmc_host *mmc = mmc_from_priv(host);
 
        BUG_ON(host == NULL);
 
-       mmc_remove_host(host->mmc);
+       mmc_remove_host(mmc);
        free_irq(host->irq, host);
        dma_free_coherent(&pdev->dev, BUFFER_SIZE, host->virt_base, host->phys_base);
        iounmap(host->reg_base);
-       mmc_free_host(host->mmc);
+       mmc_free_host(mmc);
        return 0;
 }
 
index 392a1f87c638311bfe3ddb5047507061d5ce749a..9ee0bc0ce6d0cac1f9d77c89ed7cc4d7ac4ae0c2 100644 (file)
@@ -576,42 +576,18 @@ static void atmci_init_debugfs(struct atmel_mci_slot *slot)
        struct mmc_host         *mmc = slot->mmc;
        struct atmel_mci        *host = slot->host;
        struct dentry           *root;
-       struct dentry           *node;
 
        root = mmc->debugfs_root;
        if (!root)
                return;
 
-       node = debugfs_create_file("regs", S_IRUSR, root, host,
-                                  &atmci_regs_fops);
-       if (IS_ERR(node))
-               return;
-       if (!node)
-               goto err;
-
-       node = debugfs_create_file("req", S_IRUSR, root, slot,
-                                  &atmci_req_fops);
-       if (!node)
-               goto err;
-
-       node = debugfs_create_u32("state", S_IRUSR, root, (u32 *)&host->state);
-       if (!node)
-               goto err;
-
-       node = debugfs_create_x32("pending_events", S_IRUSR, root,
-                                    (u32 *)&host->pending_events);
-       if (!node)
-               goto err;
-
-       node = debugfs_create_x32("completed_events", S_IRUSR, root,
-                                    (u32 *)&host->completed_events);
-       if (!node)
-               goto err;
-
-       return;
-
-err:
-       dev_err(&mmc->class_dev, "failed to initialize debugfs for slot\n");
+       debugfs_create_file("regs", S_IRUSR, root, host, &atmci_regs_fops);
+       debugfs_create_file("req", S_IRUSR, root, slot, &atmci_req_fops);
+       debugfs_create_u32("state", S_IRUSR, root, (u32 *)&host->state);
+       debugfs_create_x32("pending_events", S_IRUSR, root,
+                          (u32 *)&host->pending_events);
+       debugfs_create_x32("completed_events", S_IRUSR, root,
+                          (u32 *)&host->completed_events);
 }
 
 #if defined(CONFIG_OF)
index b53b6b7d4dd46abd07c4955fd13fb310026a309a..faaaf52a46d278409c2f183cea9969f75f90d069 100644 (file)
@@ -169,40 +169,18 @@ static void dw_mci_init_debugfs(struct dw_mci_slot *slot)
        struct mmc_host *mmc = slot->mmc;
        struct dw_mci *host = slot->host;
        struct dentry *root;
-       struct dentry *node;
 
        root = mmc->debugfs_root;
        if (!root)
                return;
 
-       node = debugfs_create_file("regs", S_IRUSR, root, host,
-                                  &dw_mci_regs_fops);
-       if (!node)
-               goto err;
-
-       node = debugfs_create_file("req", S_IRUSR, root, slot,
-                                  &dw_mci_req_fops);
-       if (!node)
-               goto err;
-
-       node = debugfs_create_u32("state", S_IRUSR, root, (u32 *)&host->state);
-       if (!node)
-               goto err;
-
-       node = debugfs_create_x32("pending_events", S_IRUSR, root,
-                                 (u32 *)&host->pending_events);
-       if (!node)
-               goto err;
-
-       node = debugfs_create_x32("completed_events", S_IRUSR, root,
-                                 (u32 *)&host->completed_events);
-       if (!node)
-               goto err;
-
-       return;
-
-err:
-       dev_err(&mmc->class_dev, "failed to initialize debugfs for slot\n");
+       debugfs_create_file("regs", S_IRUSR, root, host, &dw_mci_regs_fops);
+       debugfs_create_file("req", S_IRUSR, root, slot, &dw_mci_req_fops);
+       debugfs_create_u32("state", S_IRUSR, root, (u32 *)&host->state);
+       debugfs_create_x32("pending_events", S_IRUSR, root,
+                          (u32 *)&host->pending_events);
+       debugfs_create_x32("completed_events", S_IRUSR, root,
+                          (u32 *)&host->completed_events);
 }
 #endif /* defined(CONFIG_DEBUG_FS) */
 
index fb842255de4941081591194192205c7c55518e5b..037311db3551f2ec98318eaf1da1b4196b09da3a 100644 (file)
 #define SD_EMMC_TXD 0x94
 #define SD_EMMC_LAST_REG SD_EMMC_TXD
 
+#define SD_EMMC_SRAM_DATA_BUF_LEN 1536
+#define SD_EMMC_SRAM_DATA_BUF_OFF 0x200
+
 #define SD_EMMC_CFG_BLK_SIZE 512 /* internal buffer max: 512 bytes */
 #define SD_EMMC_CFG_RESP_TIMEOUT 256 /* in clock cycles */
 #define SD_EMMC_CMD_TIMEOUT 1024 /* in ms */
@@ -155,6 +158,8 @@ struct meson_host {
        unsigned long req_rate;
        bool ddr;
 
+       bool dram_access_quirk;
+
        struct pinctrl *pinctrl;
        struct pinctrl_state *pins_default;
        struct pinctrl_state *pins_clk_gate;
@@ -219,11 +224,20 @@ static struct mmc_command *meson_mmc_get_next_command(struct mmc_command *cmd)
 static void meson_mmc_get_transfer_mode(struct mmc_host *mmc,
                                        struct mmc_request *mrq)
 {
+       struct meson_host *host = mmc_priv(mmc);
        struct mmc_data *data = mrq->data;
        struct scatterlist *sg;
        int i;
        bool use_desc_chain_mode = true;
 
+       /*
+        * When Controller DMA cannot directly access DDR memory, disable
+        * support for Chain Mode to directly use the internal SRAM using
+        * the bounce buffer mode.
+        */
+       if (host->dram_access_quirk)
+               return;
+
        /*
         * Broken SDIO with AP6255-based WiFi on Khadas VIM Pro has been
         * reported. For some strange reason this occurs in descriptor
@@ -1036,6 +1050,10 @@ static int meson_mmc_probe(struct platform_device *pdev)
        host->dev = &pdev->dev;
        dev_set_drvdata(&pdev->dev, host);
 
+       /* The G12A SDIO Controller needs an SRAM bounce buffer */
+       host->dram_access_quirk = device_property_read_bool(&pdev->dev,
+                                       "amlogic,dram-access-quirk");
+
        /* Get regulators and the supported OCR mask */
        host->vqmmc_enabled = false;
        ret = mmc_regulator_get_supply(mmc);
@@ -1133,9 +1151,16 @@ static int meson_mmc_probe(struct platform_device *pdev)
                goto err_init_clk;
 
        mmc->caps |= MMC_CAP_CMD23;
-       mmc->max_blk_count = CMD_CFG_LENGTH_MASK;
+       if (host->dram_access_quirk) {
+               /* Limit to the available sram memory */
+               mmc->max_segs = SD_EMMC_SRAM_DATA_BUF_LEN / mmc->max_blk_size;
+               mmc->max_blk_count = mmc->max_segs;
+       } else {
+               mmc->max_blk_count = CMD_CFG_LENGTH_MASK;
+               mmc->max_segs = SD_EMMC_DESC_BUF_LEN /
+                               sizeof(struct sd_emmc_desc);
+       }
        mmc->max_req_size = mmc->max_blk_count * mmc->max_blk_size;
-       mmc->max_segs = SD_EMMC_DESC_BUF_LEN / sizeof(struct sd_emmc_desc);
        mmc->max_seg_size = mmc->max_req_size;
 
        /*
@@ -1145,15 +1170,27 @@ static int meson_mmc_probe(struct platform_device *pdev)
         */
        mmc->caps2 &= ~MMC_CAP2_HS400;
 
-       /* data bounce buffer */
-       host->bounce_buf_size = mmc->max_req_size;
-       host->bounce_buf =
-               dma_alloc_coherent(host->dev, host->bounce_buf_size,
-                                  &host->bounce_dma_addr, GFP_KERNEL);
-       if (host->bounce_buf == NULL) {
-               dev_err(host->dev, "Unable to map allocate DMA bounce buffer.\n");
-               ret = -ENOMEM;
-               goto err_free_irq;
+       if (host->dram_access_quirk) {
+               /*
+                * The MMC Controller embeds 1,5KiB of internal SRAM
+                * that can be used to be used as bounce buffer.
+                * In the case of the G12A SDIO controller, use these
+                * instead of the DDR memory
+                */
+               host->bounce_buf_size = SD_EMMC_SRAM_DATA_BUF_LEN;
+               host->bounce_buf = host->regs + SD_EMMC_SRAM_DATA_BUF_OFF;
+               host->bounce_dma_addr = res->start + SD_EMMC_SRAM_DATA_BUF_OFF;
+       } else {
+               /* data bounce buffer */
+               host->bounce_buf_size = mmc->max_req_size;
+               host->bounce_buf =
+                       dma_alloc_coherent(host->dev, host->bounce_buf_size,
+                                          &host->bounce_dma_addr, GFP_KERNEL);
+               if (host->bounce_buf == NULL) {
+                       dev_err(host->dev, "Unable to map allocate DMA bounce buffer.\n");
+                       ret = -ENOMEM;
+                       goto err_free_irq;
+               }
        }
 
        host->descs = dma_alloc_coherent(host->dev, SD_EMMC_DESC_BUF_LEN,
@@ -1170,8 +1207,9 @@ static int meson_mmc_probe(struct platform_device *pdev)
        return 0;
 
 err_bounce_buf:
-       dma_free_coherent(host->dev, host->bounce_buf_size,
-                         host->bounce_buf, host->bounce_dma_addr);
+       if (!host->dram_access_quirk)
+               dma_free_coherent(host->dev, host->bounce_buf_size,
+                                 host->bounce_buf, host->bounce_dma_addr);
 err_free_irq:
        free_irq(host->irq, host);
 err_init_clk:
@@ -1195,8 +1233,10 @@ static int meson_mmc_remove(struct platform_device *pdev)
 
        dma_free_coherent(host->dev, SD_EMMC_DESC_BUF_LEN,
                          host->descs, host->descs_dma_addr);
-       dma_free_coherent(host->dev, host->bounce_buf_size,
-                         host->bounce_buf, host->bounce_dma_addr);
+
+       if (!host->dram_access_quirk)
+               dma_free_coherent(host->dev, host->bounce_buf_size,
+                                 host->bounce_buf, host->bounce_dma_addr);
 
        clk_disable_unprepare(host->mmc_clk);
        clk_disable_unprepare(host->core_clk);
index 5f8d57ac084ff1217f11e4473e3144e74d306521..64d3b5fb7fe563e0c958dc21e2a8090ce3e0d2d2 100644 (file)
@@ -610,13 +610,12 @@ static void renesas_sdhi_enable_dma(struct tmio_mmc_host *host, bool enable)
        renesas_sdhi_sdbuf_width(host, enable ? width : 16);
 }
 
-static const struct renesas_sdhi_quirks sdhi_quirks_h3_m3w_es1 = {
+static const struct renesas_sdhi_quirks sdhi_quirks_4tap_nohs400 = {
        .hs400_disabled = true,
        .hs400_4taps = true,
 };
 
-static const struct renesas_sdhi_quirks sdhi_quirks_h3_es2 = {
-       .hs400_disabled = false,
+static const struct renesas_sdhi_quirks sdhi_quirks_4tap = {
        .hs400_4taps = true,
 };
 
@@ -625,10 +624,10 @@ static const struct renesas_sdhi_quirks sdhi_quirks_nohs400 = {
 };
 
 static const struct soc_device_attribute sdhi_quirks_match[]  = {
-       { .soc_id = "r8a7795", .revision = "ES1.*", .data = &sdhi_quirks_h3_m3w_es1 },
-       { .soc_id = "r8a7795", .revision = "ES2.0", .data = &sdhi_quirks_h3_es2 },
-       { .soc_id = "r8a7796", .revision = "ES1.[012]", .data = &sdhi_quirks_h3_m3w_es1 },
-       { .soc_id = "r8a774a1", .revision = "ES1.[012]", .data = &sdhi_quirks_h3_m3w_es1 },
+       { .soc_id = "r8a7795", .revision = "ES1.*", .data = &sdhi_quirks_4tap_nohs400 },
+       { .soc_id = "r8a7795", .revision = "ES2.0", .data = &sdhi_quirks_4tap },
+       { .soc_id = "r8a7796", .revision = "ES1.[012]", .data = &sdhi_quirks_4tap_nohs400 },
+       { .soc_id = "r8a774a1", .revision = "ES1.[012]", .data = &sdhi_quirks_4tap_nohs400 },
        { .soc_id = "r8a77980", .data = &sdhi_quirks_nohs400 },
        { /* Sentinel. */ },
 };
@@ -775,6 +774,8 @@ int renesas_sdhi_probe(struct platform_device *pdev,
        /* All SDHI have SDIO status bits which must be 1 */
        mmc_data->flags |= TMIO_MMC_SDIO_STATUS_SETBITS;
 
+       pm_runtime_enable(&pdev->dev);
+
        ret = renesas_sdhi_clk_enable(host);
        if (ret)
                goto efree;
@@ -855,6 +856,8 @@ edisclk:
 efree:
        tmio_mmc_host_free(host);
 
+       pm_runtime_disable(&pdev->dev);
+
        return ret;
 }
 EXPORT_SYMBOL_GPL(renesas_sdhi_probe);
@@ -866,6 +869,8 @@ int renesas_sdhi_remove(struct platform_device *pdev)
        tmio_mmc_host_remove(host);
        renesas_sdhi_clk_disable(host);
 
+       pm_runtime_disable(&pdev->dev);
+
        return 0;
 }
 EXPORT_SYMBOL_GPL(renesas_sdhi_remove);
index b1d3f828873248371b99e29b112be627b7f9f8ea..ccc5f095775f36fb75683e867f026a3dc2053809 100644 (file)
@@ -1449,33 +1449,18 @@ DEFINE_SHOW_ATTRIBUTE(s3cmci_regs);
 static void s3cmci_debugfs_attach(struct s3cmci_host *host)
 {
        struct device *dev = &host->pdev->dev;
+       struct dentry *root;
 
-       host->debug_root = debugfs_create_dir(dev_name(dev), NULL);
-       if (IS_ERR(host->debug_root)) {
-               dev_err(dev, "failed to create debugfs root\n");
-               return;
-       }
-
-       host->debug_state = debugfs_create_file("state", 0444,
-                                               host->debug_root, host,
-                                               &s3cmci_state_fops);
-
-       if (IS_ERR(host->debug_state))
-               dev_err(dev, "failed to create debug state file\n");
-
-       host->debug_regs = debugfs_create_file("regs", 0444,
-                                              host->debug_root, host,
-                                              &s3cmci_regs_fops);
+       root = debugfs_create_dir(dev_name(dev), NULL);
+       host->debug_root = root;
 
-       if (IS_ERR(host->debug_regs))
-               dev_err(dev, "failed to create debug regs file\n");
+       debugfs_create_file("state", 0444, root, host, &s3cmci_state_fops);
+       debugfs_create_file("regs", 0444, root, host, &s3cmci_regs_fops);
 }
 
 static void s3cmci_debugfs_remove(struct s3cmci_host *host)
 {
-       debugfs_remove(host->debug_regs);
-       debugfs_remove(host->debug_state);
-       debugfs_remove(host->debug_root);
+       debugfs_remove_recursive(host->debug_root);
 }
 
 #else
index 7ca1d9d639c4b60f7f7956432fb2d816ad8d50b2..8b65d7ad9f97de1440698a1d5ccf319f48386e9b 100644 (file)
@@ -67,8 +67,6 @@ struct s3cmci_host {
 
 #ifdef CONFIG_DEBUG_FS
        struct dentry           *debug_root;
-       struct dentry           *debug_state;
-       struct dentry           *debug_regs;
 #endif
 
 #ifdef CONFIG_ARM_S3C24XX_CPUFREQ
index 5fc76a1993d09348b6dfdde30335eae42d1ab04d..9cf14b359c144f788b6686e799d458052c61b63d 100644 (file)
@@ -575,11 +575,14 @@ static int msm_init_cm_dll(struct sdhci_host *host)
        struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
        struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);
        int wait_cnt = 50;
-       unsigned long flags;
+       unsigned long flags, xo_clk = 0;
        u32 config;
        const struct sdhci_msm_offset *msm_offset =
                                        msm_host->offset;
 
+       if (msm_host->use_14lpp_dll_reset && !IS_ERR_OR_NULL(msm_host->xo_clk))
+               xo_clk = clk_get_rate(msm_host->xo_clk);
+
        spin_lock_irqsave(&host->lock, flags);
 
        /*
@@ -627,10 +630,10 @@ static int msm_init_cm_dll(struct sdhci_host *host)
                config &= CORE_FLL_CYCLE_CNT;
                if (config)
                        mclk_freq = DIV_ROUND_CLOSEST_ULL((host->clock * 8),
-                                       clk_get_rate(msm_host->xo_clk));
+                                       xo_clk);
                else
                        mclk_freq = DIV_ROUND_CLOSEST_ULL((host->clock * 4),
-                                       clk_get_rate(msm_host->xo_clk));
+                                       xo_clk);
 
                config = readl_relaxed(host->ioaddr +
                                msm_offset->core_dll_config_2);
index 68c5866f5c853b64f72f57e5e9ed7cfeca468378..4dd43b1adf2cb70150319a6a680d35768ac33a33 100644 (file)
@@ -830,9 +830,17 @@ static int esdhc_execute_tuning(struct mmc_host *mmc, u32 opcode)
        struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
        struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host);
        bool hs400_tuning;
+       unsigned int clk;
        u32 val;
        int ret;
 
+       /* For tuning mode, the sd clock divisor value
+        * must be larger than 3 according to reference manual.
+        */
+       clk = esdhc->peripheral_clock / 3;
+       if (host->clock > clk)
+               esdhc_of_set_clock(host, clk);
+
        if (esdhc->quirk_limited_clk_division &&
            host->flags & SDHCI_HS400_TUNING)
                esdhc_of_set_clock(host, host->clock);
@@ -1040,11 +1048,12 @@ static void esdhc_init(struct platform_device *pdev, struct sdhci_host *host)
                /*
                 * esdhc->peripheral_clock would be assigned with a value
                 * which is eSDHC base clock when use periperal clock.
-                * For ls1046a, the clock value got by common clk API is
-                * peripheral clock while the eSDHC base clock is 1/2
-                * peripheral clock.
+                * For some platforms, the clock value got by common clk
+                * API is peripheral clock while the eSDHC base clock is
+                * 1/2 peripheral clock.
                 */
-               if (of_device_is_compatible(np, "fsl,ls1046a-esdhc"))
+               if (of_device_is_compatible(np, "fsl,ls1046a-esdhc") ||
+                   of_device_is_compatible(np, "fsl,ls1028a-esdhc"))
                        esdhc->peripheral_clock = clk_get_rate(clk) / 2;
                else
                        esdhc->peripheral_clock = clk_get_rate(clk);
index 4154ee11b47dc59a6927ffc50e06c388f962c88c..4041878eb0f3ab92c2873d0f8787a3f8d528c06c 100644 (file)
@@ -1668,6 +1668,8 @@ static const struct pci_device_id pci_ids[] = {
        SDHCI_PCI_DEVICE(INTEL, CNPH_SD,   intel_byt_sd),
        SDHCI_PCI_DEVICE(INTEL, ICP_EMMC,  intel_glk_emmc),
        SDHCI_PCI_DEVICE(INTEL, ICP_SD,    intel_byt_sd),
+       SDHCI_PCI_DEVICE(INTEL, EHL_EMMC,  intel_glk_emmc),
+       SDHCI_PCI_DEVICE(INTEL, EHL_SD,    intel_byt_sd),
        SDHCI_PCI_DEVICE(INTEL, CML_EMMC,  intel_glk_emmc),
        SDHCI_PCI_DEVICE(INTEL, CML_SD,    intel_byt_sd),
        SDHCI_PCI_DEVICE(O2, 8120,     o2),
@@ -2040,8 +2042,6 @@ static int sdhci_pci_probe(struct pci_dev *pdev,
 
        slots = PCI_SLOT_INFO_SLOTS(slots) + 1;
        dev_dbg(&pdev->dev, "found %d slot(s)\n", slots);
-       if (slots == 0)
-               return -ENODEV;
 
        BUG_ON(slots > MAX_SLOTS);
 
index dd21315922c87da795852e75ac24a7de4a9a19cf..9dc4548271b4b25d95c82f035b98f4f62f1e3c29 100644 (file)
@@ -395,11 +395,21 @@ int sdhci_pci_o2_probe_slot(struct sdhci_pci_slot *slot)
 {
        struct sdhci_pci_chip *chip;
        struct sdhci_host *host;
-       u32 reg;
+       u32 reg, caps;
        int ret;
 
        chip = slot->chip;
        host = slot->host;
+
+       caps = sdhci_readl(host, SDHCI_CAPABILITIES);
+
+       /*
+        * mmc_select_bus_width() will test the bus to determine the actual bus
+        * width.
+        */
+       if (caps & SDHCI_CAN_DO_8BIT)
+               host->mmc->caps |= MMC_CAP_8_BIT_DATA;
+
        switch (chip->pdev->device) {
        case PCI_DEVICE_ID_O2_SDS0:
        case PCI_DEVICE_ID_O2_SEABIRD0:
index e5dc6e44c7a4f463fe957dc07a98378b4f4597fa..cdd15f357d018be6367e240451956318df83f659 100644 (file)
@@ -50,6 +50,8 @@
 #define PCI_DEVICE_ID_INTEL_CNPH_SD    0xa375
 #define PCI_DEVICE_ID_INTEL_ICP_EMMC   0x34c4
 #define PCI_DEVICE_ID_INTEL_ICP_SD     0x34f8
+#define PCI_DEVICE_ID_INTEL_EHL_EMMC   0x4b47
+#define PCI_DEVICE_ID_INTEL_EHL_SD     0x4b48
 #define PCI_DEVICE_ID_INTEL_CML_EMMC   0x02c4
 #define PCI_DEVICE_ID_INTEL_CML_SD     0x02f5
 
index 9a822e2e9f0b61967c3ae2c703bcc35527d73a0e..6ee340a3fb3a252632b1a714d82eab678173e457 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/of_gpio.h>
+#include <linux/pinctrl/consumer.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/regulator/consumer.h>
 /* SDHCI_ARGUMENT2 register high 16bit */
 #define SDHCI_SPRD_ARG2_STUFF          GENMASK(31, 16)
 
+#define SDHCI_SPRD_REG_32_DLL_CFG      0x200
+#define  SDHCI_SPRD_DLL_ALL_CPST_EN    (BIT(18) | BIT(24) | BIT(25) | BIT(26) | BIT(27))
+#define  SDHCI_SPRD_DLL_EN             BIT(21)
+#define  SDHCI_SPRD_DLL_SEARCH_MODE    BIT(16)
+#define  SDHCI_SPRD_DLL_INIT_COUNT     0xc00
+#define  SDHCI_SPRD_DLL_PHASE_INTERNAL 0x3
+
+#define SDHCI_SPRD_REG_32_DLL_DLY      0x204
+
 #define SDHCI_SPRD_REG_32_DLL_DLY_OFFSET       0x208
 #define  SDHCIBSPRD_IT_WR_DLY_INV              BIT(5)
 #define  SDHCI_SPRD_BIT_CMD_DLY_INV            BIT(13)
@@ -41,6 +51,7 @@
 /* SDHCI_HOST_CONTROL2 */
 #define  SDHCI_SPRD_CTRL_HS200         0x0005
 #define  SDHCI_SPRD_CTRL_HS400         0x0006
+#define  SDHCI_SPRD_CTRL_HS400ES       0x0007
 
 /*
  * According to the standard specification, BIT(3) of SDHCI_SOFTWARE_RESET is
 #define SDHCI_SPRD_CLK_MAX_DIV         1023
 
 #define SDHCI_SPRD_CLK_DEF_RATE                26000000
+#define SDHCI_SPRD_PHY_DLL_CLK         52000000
 
 struct sdhci_sprd_host {
        u32 version;
        struct clk *clk_sdio;
        struct clk *clk_enable;
+       struct clk *clk_2x_enable;
+       struct pinctrl *pinctrl;
+       struct pinctrl_state *pins_uhs;
+       struct pinctrl_state *pins_default;
        u32 base_rate;
        int flags; /* backup of host attribute */
+       u32 phy_delay[MMC_TIMING_MMC_HS400 + 2];
+};
+
+struct sdhci_sprd_phy_cfg {
+       const char *property;
+       u8 timing;
+};
+
+static const struct sdhci_sprd_phy_cfg sdhci_sprd_phy_cfgs[] = {
+       { "sprd,phy-delay-legacy", MMC_TIMING_LEGACY, },
+       { "sprd,phy-delay-sd-highspeed", MMC_TIMING_SD_HS, },
+       { "sprd,phy-delay-sd-uhs-sdr50", MMC_TIMING_UHS_SDR50, },
+       { "sprd,phy-delay-sd-uhs-sdr104", MMC_TIMING_UHS_SDR104, },
+       { "sprd,phy-delay-mmc-highspeed", MMC_TIMING_MMC_HS, },
+       { "sprd,phy-delay-mmc-ddr52", MMC_TIMING_MMC_DDR52, },
+       { "sprd,phy-delay-mmc-hs200", MMC_TIMING_MMC_HS200, },
+       { "sprd,phy-delay-mmc-hs400", MMC_TIMING_MMC_HS400, },
+       { "sprd,phy-delay-mmc-hs400es", MMC_TIMING_MMC_HS400 + 1, },
 };
 
 #define TO_SPRD_HOST(host) sdhci_pltfm_priv(sdhci_priv(host))
@@ -131,6 +165,15 @@ static inline void sdhci_sprd_sd_clk_off(struct sdhci_host *host)
        sdhci_writew(host, ctrl, SDHCI_CLOCK_CONTROL);
 }
 
+static inline void sdhci_sprd_sd_clk_on(struct sdhci_host *host)
+{
+       u16 ctrl;
+
+       ctrl = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
+       ctrl |= SDHCI_CLOCK_CARD_EN;
+       sdhci_writew(host, ctrl, SDHCI_CLOCK_CONTROL);
+}
+
 static inline void
 sdhci_sprd_set_dll_invert(struct sdhci_host *host, u32 mask, bool en)
 {
@@ -189,9 +232,33 @@ static inline void _sdhci_sprd_set_clock(struct sdhci_host *host,
        }
 }
 
+static void sdhci_sprd_enable_phy_dll(struct sdhci_host *host)
+{
+       u32 tmp;
+
+       tmp = sdhci_readl(host, SDHCI_SPRD_REG_32_DLL_CFG);
+       tmp &= ~(SDHCI_SPRD_DLL_EN | SDHCI_SPRD_DLL_ALL_CPST_EN);
+       sdhci_writel(host, tmp, SDHCI_SPRD_REG_32_DLL_CFG);
+       /* wait 1ms */
+       usleep_range(1000, 1250);
+
+       tmp = sdhci_readl(host, SDHCI_SPRD_REG_32_DLL_CFG);
+       tmp |= SDHCI_SPRD_DLL_ALL_CPST_EN | SDHCI_SPRD_DLL_SEARCH_MODE |
+               SDHCI_SPRD_DLL_INIT_COUNT | SDHCI_SPRD_DLL_PHASE_INTERNAL;
+       sdhci_writel(host, tmp, SDHCI_SPRD_REG_32_DLL_CFG);
+       /* wait 1ms */
+       usleep_range(1000, 1250);
+
+       tmp = sdhci_readl(host, SDHCI_SPRD_REG_32_DLL_CFG);
+       tmp |= SDHCI_SPRD_DLL_EN;
+       sdhci_writel(host, tmp, SDHCI_SPRD_REG_32_DLL_CFG);
+       /* wait 1ms */
+       usleep_range(1000, 1250);
+}
+
 static void sdhci_sprd_set_clock(struct sdhci_host *host, unsigned int clock)
 {
-       bool en = false;
+       bool en = false, clk_changed = false;
 
        if (clock == 0) {
                sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
@@ -203,9 +270,19 @@ static void sdhci_sprd_set_clock(struct sdhci_host *host, unsigned int clock)
                        en = true;
                sdhci_sprd_set_dll_invert(host, SDHCI_SPRD_BIT_CMD_DLY_INV |
                                          SDHCI_SPRD_BIT_POSRD_DLY_INV, en);
+               clk_changed = true;
        } else {
                _sdhci_sprd_set_clock(host, clock);
        }
+
+       /*
+        * According to the Spreadtrum SD host specification, when we changed
+        * the clock to be more than 52M, we should enable the PHY DLL which
+        * is used to track the clock frequency to make the clock work more
+        * stable. Otherwise deviation may occur of the higher clock.
+        */
+       if (clk_changed && clock > SDHCI_SPRD_PHY_DLL_CLK)
+               sdhci_sprd_enable_phy_dll(host);
 }
 
 static unsigned int sdhci_sprd_get_max_clock(struct sdhci_host *host)
@@ -223,6 +300,9 @@ static unsigned int sdhci_sprd_get_min_clock(struct sdhci_host *host)
 static void sdhci_sprd_set_uhs_signaling(struct sdhci_host *host,
                                         unsigned int timing)
 {
+       struct sdhci_sprd_host *sprd_host = TO_SPRD_HOST(host);
+       struct mmc_host *mmc = host->mmc;
+       u32 *p = sprd_host->phy_delay;
        u16 ctrl_2;
 
        if (timing == host->timing)
@@ -261,6 +341,9 @@ static void sdhci_sprd_set_uhs_signaling(struct sdhci_host *host,
        }
 
        sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
+
+       if (!mmc->ios.enhanced_strobe)
+               sdhci_writel(host, p[timing], SDHCI_SPRD_REG_32_DLL_DLY);
 }
 
 static void sdhci_sprd_hw_reset(struct sdhci_host *host)
@@ -284,6 +367,12 @@ static void sdhci_sprd_hw_reset(struct sdhci_host *host)
        usleep_range(300, 500);
 }
 
+static unsigned int sdhci_sprd_get_max_timeout_count(struct sdhci_host *host)
+{
+       /* The Spredtrum controller actual maximum timeout count is 1 << 31 */
+       return 1 << 31;
+}
+
 static struct sdhci_ops sdhci_sprd_ops = {
        .read_l = sdhci_sprd_readl,
        .write_l = sdhci_sprd_writel,
@@ -295,6 +384,7 @@ static struct sdhci_ops sdhci_sprd_ops = {
        .reset = sdhci_reset,
        .set_uhs_signaling = sdhci_sprd_set_uhs_signaling,
        .hw_reset = sdhci_sprd_hw_reset,
+       .get_max_timeout_count = sdhci_sprd_get_max_timeout_count,
 };
 
 static void sdhci_sprd_request(struct mmc_host *mmc, struct mmc_request *mrq)
@@ -317,6 +407,99 @@ static void sdhci_sprd_request(struct mmc_host *mmc, struct mmc_request *mrq)
        sdhci_request(mmc, mrq);
 }
 
+static int sdhci_sprd_voltage_switch(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+       struct sdhci_host *host = mmc_priv(mmc);
+       struct sdhci_sprd_host *sprd_host = TO_SPRD_HOST(host);
+       int ret;
+
+       if (!IS_ERR(mmc->supply.vqmmc)) {
+               ret = mmc_regulator_set_vqmmc(mmc, ios);
+               if (ret) {
+                       pr_err("%s: Switching signalling voltage failed\n",
+                              mmc_hostname(mmc));
+                       return ret;
+               }
+       }
+
+       if (IS_ERR(sprd_host->pinctrl))
+               return 0;
+
+       switch (ios->signal_voltage) {
+       case MMC_SIGNAL_VOLTAGE_180:
+               ret = pinctrl_select_state(sprd_host->pinctrl,
+                                          sprd_host->pins_uhs);
+               if (ret) {
+                       pr_err("%s: failed to select uhs pin state\n",
+                              mmc_hostname(mmc));
+                       return ret;
+               }
+               break;
+
+       default:
+               /* fall-through */
+       case MMC_SIGNAL_VOLTAGE_330:
+               ret = pinctrl_select_state(sprd_host->pinctrl,
+                                          sprd_host->pins_default);
+               if (ret) {
+                       pr_err("%s: failed to select default pin state\n",
+                              mmc_hostname(mmc));
+                       return ret;
+               }
+               break;
+       }
+
+       /* Wait for 300 ~ 500 us for pin state stable */
+       usleep_range(300, 500);
+       sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
+
+       return 0;
+}
+
+static void sdhci_sprd_hs400_enhanced_strobe(struct mmc_host *mmc,
+                                            struct mmc_ios *ios)
+{
+       struct sdhci_host *host = mmc_priv(mmc);
+       struct sdhci_sprd_host *sprd_host = TO_SPRD_HOST(host);
+       u32 *p = sprd_host->phy_delay;
+       u16 ctrl_2;
+
+       if (!ios->enhanced_strobe)
+               return;
+
+       sdhci_sprd_sd_clk_off(host);
+
+       /* Set HS400 enhanced strobe mode */
+       ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
+       ctrl_2 &= ~SDHCI_CTRL_UHS_MASK;
+       ctrl_2 |= SDHCI_SPRD_CTRL_HS400ES;
+       sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
+
+       sdhci_sprd_sd_clk_on(host);
+
+       /* Set the PHY DLL delay value for HS400 enhanced strobe mode */
+       sdhci_writel(host, p[MMC_TIMING_MMC_HS400 + 1],
+                    SDHCI_SPRD_REG_32_DLL_DLY);
+}
+
+static void sdhci_sprd_phy_param_parse(struct sdhci_sprd_host *sprd_host,
+                                      struct device_node *np)
+{
+       u32 *p = sprd_host->phy_delay;
+       int ret, i, index;
+       u32 val[4];
+
+       for (i = 0; i < ARRAY_SIZE(sdhci_sprd_phy_cfgs); i++) {
+               ret = of_property_read_u32_array(np,
+                               sdhci_sprd_phy_cfgs[i].property, val, 4);
+               if (ret)
+                       continue;
+
+               index = sdhci_sprd_phy_cfgs[i].timing;
+               p[index] = val[0] | (val[1] << 8) | (val[2] << 16) | (val[3] << 24);
+       }
+}
+
 static const struct sdhci_pltfm_data sdhci_sprd_pdata = {
        .quirks = SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK,
        .quirks2 = SDHCI_QUIRK2_BROKEN_HS200 |
@@ -338,6 +521,16 @@ static int sdhci_sprd_probe(struct platform_device *pdev)
        host->dma_mask = DMA_BIT_MASK(64);
        pdev->dev.dma_mask = &host->dma_mask;
        host->mmc_host_ops.request = sdhci_sprd_request;
+       host->mmc_host_ops.hs400_enhanced_strobe =
+               sdhci_sprd_hs400_enhanced_strobe;
+       /*
+        * We can not use the standard ops to change and detect the voltage
+        * signal for Spreadtrum SD host controller, since our voltage regulator
+        * for I/O is fixed in hardware, that means we do not need control
+        * the standard SD host controller to change the I/O voltage.
+        */
+       host->mmc_host_ops.start_signal_voltage_switch =
+               sdhci_sprd_voltage_switch;
 
        host->mmc->caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED |
                MMC_CAP_ERASE | MMC_CAP_CMD23;
@@ -346,6 +539,24 @@ static int sdhci_sprd_probe(struct platform_device *pdev)
                goto pltfm_free;
 
        sprd_host = TO_SPRD_HOST(host);
+       sdhci_sprd_phy_param_parse(sprd_host, pdev->dev.of_node);
+
+       sprd_host->pinctrl = devm_pinctrl_get(&pdev->dev);
+       if (!IS_ERR(sprd_host->pinctrl)) {
+               sprd_host->pins_uhs =
+                       pinctrl_lookup_state(sprd_host->pinctrl, "state_uhs");
+               if (IS_ERR(sprd_host->pins_uhs)) {
+                       ret = PTR_ERR(sprd_host->pins_uhs);
+                       goto pltfm_free;
+               }
+
+               sprd_host->pins_default =
+                       pinctrl_lookup_state(sprd_host->pinctrl, "default");
+               if (IS_ERR(sprd_host->pins_default)) {
+                       ret = PTR_ERR(sprd_host->pins_default);
+                       goto pltfm_free;
+               }
+       }
 
        clk = devm_clk_get(&pdev->dev, "sdio");
        if (IS_ERR(clk)) {
@@ -364,14 +575,22 @@ static int sdhci_sprd_probe(struct platform_device *pdev)
        }
        sprd_host->clk_enable = clk;
 
+       clk = devm_clk_get(&pdev->dev, "2x_enable");
+       if (!IS_ERR(clk))
+               sprd_host->clk_2x_enable = clk;
+
        ret = clk_prepare_enable(sprd_host->clk_sdio);
        if (ret)
                goto pltfm_free;
 
-       clk_prepare_enable(sprd_host->clk_enable);
+       ret = clk_prepare_enable(sprd_host->clk_enable);
        if (ret)
                goto clk_disable;
 
+       ret = clk_prepare_enable(sprd_host->clk_2x_enable);
+       if (ret)
+               goto clk_disable2;
+
        sdhci_sprd_init_config(host);
        host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
        sprd_host->version = ((host->version & SDHCI_VENDOR_VER_MASK) >>
@@ -408,6 +627,9 @@ pm_runtime_disable:
        pm_runtime_disable(&pdev->dev);
        pm_runtime_set_suspended(&pdev->dev);
 
+       clk_disable_unprepare(sprd_host->clk_2x_enable);
+
+clk_disable2:
        clk_disable_unprepare(sprd_host->clk_enable);
 
 clk_disable:
@@ -427,6 +649,7 @@ static int sdhci_sprd_remove(struct platform_device *pdev)
        mmc_remove_host(mmc);
        clk_disable_unprepare(sprd_host->clk_sdio);
        clk_disable_unprepare(sprd_host->clk_enable);
+       clk_disable_unprepare(sprd_host->clk_2x_enable);
 
        mmc_free_host(mmc);
 
@@ -449,6 +672,7 @@ static int sdhci_sprd_runtime_suspend(struct device *dev)
 
        clk_disable_unprepare(sprd_host->clk_sdio);
        clk_disable_unprepare(sprd_host->clk_enable);
+       clk_disable_unprepare(sprd_host->clk_2x_enable);
 
        return 0;
 }
@@ -459,19 +683,28 @@ static int sdhci_sprd_runtime_resume(struct device *dev)
        struct sdhci_sprd_host *sprd_host = TO_SPRD_HOST(host);
        int ret;
 
-       ret = clk_prepare_enable(sprd_host->clk_enable);
+       ret = clk_prepare_enable(sprd_host->clk_2x_enable);
        if (ret)
                return ret;
 
+       ret = clk_prepare_enable(sprd_host->clk_enable);
+       if (ret)
+               goto clk_2x_disable;
+
        ret = clk_prepare_enable(sprd_host->clk_sdio);
-       if (ret) {
-               clk_disable_unprepare(sprd_host->clk_enable);
-               return ret;
-       }
+       if (ret)
+               goto clk_disable;
 
        sdhci_runtime_resume_host(host);
-
        return 0;
+
+clk_disable:
+       clk_disable_unprepare(sprd_host->clk_enable);
+
+clk_2x_disable:
+       clk_disable_unprepare(sprd_host->clk_2x_enable);
+
+       return ret;
 }
 #endif
 
index 781a3e106d9a08d8ee1a6f5f180ad3e248731e13..f4d4761cf20ab4f700e1f4054dc8dfbf9318962c 100644 (file)
@@ -1541,8 +1541,11 @@ static int sdhci_tegra_probe(struct platform_device *pdev)
 
        clk = devm_clk_get(mmc_dev(host->mmc), NULL);
        if (IS_ERR(clk)) {
-               dev_err(mmc_dev(host->mmc), "clk err\n");
                rc = PTR_ERR(clk);
+
+               if (rc != -EPROBE_DEFER)
+                       dev_err(&pdev->dev, "failed to get clock: %d\n", rc);
+
                goto err_clk_get;
        }
        clk_prepare_enable(clk);
index 199712e7adbb3dad5c1ab6e306448d6fd32648a2..89fd96596a1f75e18f600761a41302d455124f64 100644 (file)
@@ -89,7 +89,7 @@
 #define   SDHCI_CTRL_ADMA32    0x10
 #define   SDHCI_CTRL_ADMA64    0x18
 #define   SDHCI_CTRL_ADMA3     0x18
-#define   SDHCI_CTRL_8BITBUS   0x20
+#define  SDHCI_CTRL_8BITBUS    0x20
 #define  SDHCI_CTRL_CDTEST_INS 0x40
 #define  SDHCI_CTRL_CDTEST_EN  0x80
 
index 3222ea4d584d30c98c63b8d26ef76e53b4d389a8..bb90757ecace12242aa86e43296bcea0c1c19095 100644 (file)
@@ -6,6 +6,7 @@
  *
  */
 #include <linux/clk.h>
+#include <linux/of.h>
 #include <linux/module.h>
 #include <linux/pm_runtime.h>
 #include <linux/property.h>
 #define OTAPDLYSEL_SHIFT       12
 #define OTAPDLYSEL_MASK                GENMASK(15, 12)
 #define STRBSEL_SHIFT          24
-#define STRBSEL_MASK           GENMASK(27, 24)
+#define STRBSEL_4BIT_MASK      GENMASK(27, 24)
+#define STRBSEL_8BIT_MASK      GENMASK(31, 24)
 #define SEL50_SHIFT            8
 #define SEL50_MASK             BIT(SEL50_SHIFT)
 #define SEL100_SHIFT           9
 #define SEL100_MASK            BIT(SEL100_SHIFT)
+#define FREQSEL_SHIFT          8
+#define FREQSEL_MASK           GENMASK(10, 8)
 #define DLL_TRIM_ICP_SHIFT     4
 #define DLL_TRIM_ICP_MASK      GENMASK(7, 4)
 #define DR_TY_SHIFT            20
@@ -77,19 +81,29 @@ struct sdhci_am654_data {
        int trm_icp;
        int drv_strength;
        bool dll_on;
+       int strb_sel;
+       u32 flags;
+};
+
+struct sdhci_am654_driver_data {
+       const struct sdhci_pltfm_data *pdata;
+       u32 flags;
+#define IOMUX_PRESENT  (1 << 0)
+#define FREQSEL_2_BIT  (1 << 1)
+#define STRBSEL_4_BIT  (1 << 2)
+#define DLL_PRESENT    (1 << 3)
 };
 
 static void sdhci_am654_set_clock(struct sdhci_host *host, unsigned int clock)
 {
        struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
        struct sdhci_am654_data *sdhci_am654 = sdhci_pltfm_priv(pltfm_host);
-       int sel50, sel100;
+       int sel50, sel100, freqsel;
        u32 mask, val;
        int ret;
 
        if (sdhci_am654->dll_on) {
-               regmap_update_bits(sdhci_am654->base, PHY_CTRL1,
-                                  ENDLL_MASK, 0);
+               regmap_update_bits(sdhci_am654->base, PHY_CTRL1, ENDLL_MASK, 0);
 
                sdhci_am654->dll_on = false;
        }
@@ -101,27 +115,53 @@ static void sdhci_am654_set_clock(struct sdhci_host *host, unsigned int clock)
                mask = OTAPDLYENA_MASK | OTAPDLYSEL_MASK;
                val = (1 << OTAPDLYENA_SHIFT) |
                      (sdhci_am654->otap_del_sel << OTAPDLYSEL_SHIFT);
-               regmap_update_bits(sdhci_am654->base, PHY_CTRL4,
-                                  mask, val);
-               switch (clock) {
-               case 200000000:
-                       sel50 = 0;
-                       sel100 = 0;
-                       break;
-               case 100000000:
-                       sel50 = 0;
-                       sel100 = 1;
-                       break;
-               default:
-                       sel50 = 1;
-                       sel100 = 0;
+               regmap_update_bits(sdhci_am654->base, PHY_CTRL4, mask, val);
+               /* Write to STRBSEL for HS400 speed mode */
+               if (host->mmc->ios.timing == MMC_TIMING_MMC_HS400) {
+                       if (sdhci_am654->flags & STRBSEL_4_BIT)
+                               mask = STRBSEL_4BIT_MASK;
+                       else
+                               mask = STRBSEL_8BIT_MASK;
+
+                       regmap_update_bits(sdhci_am654->base, PHY_CTRL4, mask,
+                                          sdhci_am654->strb_sel <<
+                                          STRBSEL_SHIFT);
+               }
+
+               if (sdhci_am654->flags & FREQSEL_2_BIT) {
+                       switch (clock) {
+                       case 200000000:
+                               sel50 = 0;
+                               sel100 = 0;
+                               break;
+                       case 100000000:
+                               sel50 = 0;
+                               sel100 = 1;
+                               break;
+                       default:
+                               sel50 = 1;
+                               sel100 = 0;
+                       }
+
+                       /* Configure PHY DLL frequency */
+                       mask = SEL50_MASK | SEL100_MASK;
+                       val = (sel50 << SEL50_SHIFT) | (sel100 << SEL100_SHIFT);
+                       regmap_update_bits(sdhci_am654->base, PHY_CTRL5, mask,
+                                          val);
+               } else {
+                       switch (clock) {
+                       case 200000000:
+                               freqsel = 0x0;
+                               break;
+                       default:
+                               freqsel = 0x4;
+                       }
+
+                       regmap_update_bits(sdhci_am654->base, PHY_CTRL5,
+                                          FREQSEL_MASK,
+                                          freqsel << FREQSEL_SHIFT);
                }
 
-               /* Configure PHY DLL frequency */
-               mask = SEL50_MASK | SEL100_MASK;
-               val = (sel50 << SEL50_SHIFT) | (sel100 << SEL100_SHIFT);
-               regmap_update_bits(sdhci_am654->base, PHY_CTRL5,
-                                  mask, val);
                /* Configure DLL TRIM */
                mask = DLL_TRIM_ICP_MASK;
                val = sdhci_am654->trm_icp << DLL_TRIM_ICP_SHIFT;
@@ -129,24 +169,41 @@ static void sdhci_am654_set_clock(struct sdhci_host *host, unsigned int clock)
                /* Configure DLL driver strength */
                mask |= DR_TY_MASK;
                val |= sdhci_am654->drv_strength << DR_TY_SHIFT;
-               regmap_update_bits(sdhci_am654->base, PHY_CTRL1,
-                                  mask, val);
+               regmap_update_bits(sdhci_am654->base, PHY_CTRL1, mask, val);
                /* Enable DLL */
-               regmap_update_bits(sdhci_am654->base, PHY_CTRL1,
-                                  ENDLL_MASK, 0x1 << ENDLL_SHIFT);
+               regmap_update_bits(sdhci_am654->base, PHY_CTRL1, ENDLL_MASK,
+                                  0x1 << ENDLL_SHIFT);
                /*
                 * Poll for DLL ready. Use a one second timeout.
                 * Works in all experiments done so far
                 */
-               ret = regmap_read_poll_timeout(sdhci_am654->base,
-                                        PHY_STAT1, val,
-                                        val & DLLRDY_MASK,
-                                        1000, 1000000);
+               ret = regmap_read_poll_timeout(sdhci_am654->base, PHY_STAT1,
+                                              val, val & DLLRDY_MASK, 1000,
+                                              1000000);
+               if (ret) {
+                       dev_err(mmc_dev(host->mmc), "DLL failed to relock\n");
+                       return;
+               }
 
                sdhci_am654->dll_on = true;
        }
 }
 
+static void sdhci_j721e_4bit_set_clock(struct sdhci_host *host,
+                                      unsigned int clock)
+{
+       struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+       struct sdhci_am654_data *sdhci_am654 = sdhci_pltfm_priv(pltfm_host);
+       int val, mask;
+
+       mask = OTAPDLYENA_MASK | OTAPDLYSEL_MASK;
+       val = (1 << OTAPDLYENA_SHIFT) |
+             (sdhci_am654->otap_del_sel << OTAPDLYSEL_SHIFT);
+       regmap_update_bits(sdhci_am654->base, PHY_CTRL4, mask, val);
+
+       sdhci_set_clock(host, clock);
+}
+
 static void sdhci_am654_set_power(struct sdhci_host *host, unsigned char mode,
                                  unsigned short vdd)
 {
@@ -197,6 +254,56 @@ static const struct sdhci_pltfm_data sdhci_am654_pdata = {
        .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN,
 };
 
+static const struct sdhci_am654_driver_data sdhci_am654_drvdata = {
+       .pdata = &sdhci_am654_pdata,
+       .flags = IOMUX_PRESENT | FREQSEL_2_BIT | STRBSEL_4_BIT | DLL_PRESENT,
+};
+
+static struct sdhci_ops sdhci_j721e_8bit_ops = {
+       .get_max_clock = sdhci_pltfm_clk_get_max_clock,
+       .get_timeout_clock = sdhci_pltfm_clk_get_max_clock,
+       .set_uhs_signaling = sdhci_set_uhs_signaling,
+       .set_bus_width = sdhci_set_bus_width,
+       .set_power = sdhci_am654_set_power,
+       .set_clock = sdhci_am654_set_clock,
+       .write_b = sdhci_am654_write_b,
+       .reset = sdhci_reset,
+};
+
+static const struct sdhci_pltfm_data sdhci_j721e_8bit_pdata = {
+       .ops = &sdhci_j721e_8bit_ops,
+       .quirks = SDHCI_QUIRK_INVERTED_WRITE_PROTECT |
+                 SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12,
+       .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN,
+};
+
+static const struct sdhci_am654_driver_data sdhci_j721e_8bit_drvdata = {
+       .pdata = &sdhci_j721e_8bit_pdata,
+       .flags = DLL_PRESENT,
+};
+
+static struct sdhci_ops sdhci_j721e_4bit_ops = {
+       .get_max_clock = sdhci_pltfm_clk_get_max_clock,
+       .get_timeout_clock = sdhci_pltfm_clk_get_max_clock,
+       .set_uhs_signaling = sdhci_set_uhs_signaling,
+       .set_bus_width = sdhci_set_bus_width,
+       .set_power = sdhci_am654_set_power,
+       .set_clock = sdhci_j721e_4bit_set_clock,
+       .write_b = sdhci_am654_write_b,
+       .reset = sdhci_reset,
+};
+
+static const struct sdhci_pltfm_data sdhci_j721e_4bit_pdata = {
+       .ops = &sdhci_j721e_4bit_ops,
+       .quirks = SDHCI_QUIRK_INVERTED_WRITE_PROTECT |
+                 SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12,
+       .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN,
+};
+
+static const struct sdhci_am654_driver_data sdhci_j721e_4bit_drvdata = {
+       .pdata = &sdhci_j721e_4bit_pdata,
+       .flags = IOMUX_PRESENT,
+};
 static int sdhci_am654_init(struct sdhci_host *host)
 {
        struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@@ -208,30 +315,34 @@ static int sdhci_am654_init(struct sdhci_host *host)
 
        /* Reset OTAP to default value */
        mask = OTAPDLYENA_MASK | OTAPDLYSEL_MASK;
-       regmap_update_bits(sdhci_am654->base, PHY_CTRL4,
-                                  mask, 0x0);
-
-       regmap_read(sdhci_am654->base, PHY_STAT1, &val);
-       if (~val & CALDONE_MASK) {
-               /* Calibrate IO lines */
-               regmap_update_bits(sdhci_am654->base, PHY_CTRL1,
-                                  PDB_MASK, PDB_MASK);
-               ret = regmap_read_poll_timeout(sdhci_am654->base, PHY_STAT1,
-                                              val, val & CALDONE_MASK, 1, 20);
-               if (ret)
-                       return ret;
+       regmap_update_bits(sdhci_am654->base, PHY_CTRL4, mask, 0x0);
+
+       if (sdhci_am654->flags & DLL_PRESENT) {
+               regmap_read(sdhci_am654->base, PHY_STAT1, &val);
+               if (~val & CALDONE_MASK) {
+                       /* Calibrate IO lines */
+                       regmap_update_bits(sdhci_am654->base, PHY_CTRL1,
+                                          PDB_MASK, PDB_MASK);
+                       ret = regmap_read_poll_timeout(sdhci_am654->base,
+                                                      PHY_STAT1, val,
+                                                      val & CALDONE_MASK,
+                                                      1, 20);
+                       if (ret)
+                               return ret;
+               }
        }
 
        /* Enable pins by setting IO mux to 0 */
-       regmap_update_bits(sdhci_am654->base, PHY_CTRL1,
-                          IOMUX_ENABLE_MASK, 0);
+       if (sdhci_am654->flags & IOMUX_PRESENT)
+               regmap_update_bits(sdhci_am654->base, PHY_CTRL1,
+                                  IOMUX_ENABLE_MASK, 0);
 
        /* Set slot type based on SD or eMMC */
        if (host->mmc->caps & MMC_CAP_NONREMOVABLE)
                ctl_cfg_2 = SLOTTYPE_EMBEDDED;
 
-       regmap_update_bits(sdhci_am654->base, CTL_CFG_2,
-                          SLOTTYPE_MASK, ctl_cfg_2);
+       regmap_update_bits(sdhci_am654->base, CTL_CFG_2, SLOTTYPE_MASK,
+                          ctl_cfg_2);
 
        return sdhci_add_host(host);
 }
@@ -243,51 +354,73 @@ static int sdhci_am654_get_of_property(struct platform_device *pdev,
        int drv_strength;
        int ret;
 
-       ret = device_property_read_u32(dev, "ti,trm-icp",
-                                      &sdhci_am654->trm_icp);
-       if (ret)
-               return ret;
-
        ret = device_property_read_u32(dev, "ti,otap-del-sel",
                                       &sdhci_am654->otap_del_sel);
        if (ret)
                return ret;
 
-       ret = device_property_read_u32(dev, "ti,driver-strength-ohm",
-                                      &drv_strength);
-       if (ret)
-               return ret;
+       if (sdhci_am654->flags & DLL_PRESENT) {
+               ret = device_property_read_u32(dev, "ti,trm-icp",
+                                              &sdhci_am654->trm_icp);
+               if (ret)
+                       return ret;
 
-       switch (drv_strength) {
-       case 50:
-               sdhci_am654->drv_strength = DRIVER_STRENGTH_50_OHM;
-               break;
-       case 33:
-               sdhci_am654->drv_strength = DRIVER_STRENGTH_33_OHM;
-               break;
-       case 66:
-               sdhci_am654->drv_strength = DRIVER_STRENGTH_66_OHM;
-               break;
-       case 100:
-               sdhci_am654->drv_strength = DRIVER_STRENGTH_100_OHM;
-               break;
-       case 40:
-               sdhci_am654->drv_strength = DRIVER_STRENGTH_40_OHM;
-               break;
-       default:
-               dev_err(dev, "Invalid driver strength\n");
-               return -EINVAL;
+               ret = device_property_read_u32(dev, "ti,driver-strength-ohm",
+                                              &drv_strength);
+               if (ret)
+                       return ret;
+
+               switch (drv_strength) {
+               case 50:
+                       sdhci_am654->drv_strength = DRIVER_STRENGTH_50_OHM;
+                       break;
+               case 33:
+                       sdhci_am654->drv_strength = DRIVER_STRENGTH_33_OHM;
+                       break;
+               case 66:
+                       sdhci_am654->drv_strength = DRIVER_STRENGTH_66_OHM;
+                       break;
+               case 100:
+                       sdhci_am654->drv_strength = DRIVER_STRENGTH_100_OHM;
+                       break;
+               case 40:
+                       sdhci_am654->drv_strength = DRIVER_STRENGTH_40_OHM;
+                       break;
+               default:
+                       dev_err(dev, "Invalid driver strength\n");
+                       return -EINVAL;
+               }
        }
 
+       device_property_read_u32(dev, "ti,strobe-sel", &sdhci_am654->strb_sel);
+
        sdhci_get_of_property(pdev);
 
        return 0;
 }
 
+static const struct of_device_id sdhci_am654_of_match[] = {
+       {
+               .compatible = "ti,am654-sdhci-5.1",
+               .data = &sdhci_am654_drvdata,
+       },
+       {
+               .compatible = "ti,j721e-sdhci-8bit",
+               .data = &sdhci_j721e_8bit_drvdata,
+       },
+       {
+               .compatible = "ti,j721e-sdhci-4bit",
+               .data = &sdhci_j721e_4bit_drvdata,
+       },
+       { /* sentinel */ }
+};
+
 static int sdhci_am654_probe(struct platform_device *pdev)
 {
+       const struct sdhci_am654_driver_data *drvdata;
        struct sdhci_pltfm_host *pltfm_host;
        struct sdhci_am654_data *sdhci_am654;
+       const struct of_device_id *match;
        struct sdhci_host *host;
        struct resource *res;
        struct clk *clk_xin;
@@ -295,12 +428,15 @@ static int sdhci_am654_probe(struct platform_device *pdev)
        void __iomem *base;
        int ret;
 
-       host = sdhci_pltfm_init(pdev, &sdhci_am654_pdata, sizeof(*sdhci_am654));
+       match = of_match_node(sdhci_am654_of_match, pdev->dev.of_node);
+       drvdata = match->data;
+       host = sdhci_pltfm_init(pdev, drvdata->pdata, sizeof(*sdhci_am654));
        if (IS_ERR(host))
                return PTR_ERR(host);
 
        pltfm_host = sdhci_priv(host);
        sdhci_am654 = sdhci_pltfm_priv(pltfm_host);
+       sdhci_am654->flags = drvdata->flags;
 
        clk_xin = devm_clk_get(dev, "clk_xin");
        if (IS_ERR(clk_xin)) {
@@ -375,11 +511,6 @@ static int sdhci_am654_remove(struct platform_device *pdev)
        return 0;
 }
 
-static const struct of_device_id sdhci_am654_of_match[] = {
-       { .compatible = "ti,am654-sdhci-5.1" },
-       { /* sentinel */ }
-};
-
 static struct platform_driver sdhci_am654_driver = {
        .driver = {
                .name = "sdhci-am654",
index 93e83ad25976e756bdb04408b51c506925b02534..8539e10784b4096186024319c18f0df4e555e435 100644 (file)
@@ -172,6 +172,8 @@ static int tmio_mmc_probe(struct platform_device *pdev)
        host->mmc->f_max = pdata->hclk;
        host->mmc->f_min = pdata->hclk / 512;
 
+       pm_runtime_enable(&pdev->dev);
+
        ret = tmio_mmc_host_probe(host);
        if (ret)
                goto host_free;
@@ -191,6 +193,7 @@ host_remove:
        tmio_mmc_host_remove(host);
 host_free:
        tmio_mmc_host_free(host);
+       pm_runtime_disable(&pdev->dev);
 cell_disable:
        if (cell->disable)
                cell->disable(pdev);
@@ -207,6 +210,8 @@ static int tmio_mmc_remove(struct platform_device *pdev)
        if (cell->disable)
                cell->disable(pdev);
 
+       pm_runtime_disable(&pdev->dev);
+
        return 0;
 }
 
index 84cb7d2aacdf0a999e6e84fe172de73ca46bc611..2cb3f951c3e2b793761726feb2bfa7a3ac45a980 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <linux/delay.h>
 #include <linux/device.h>
+#include <linux/dma-mapping.h>
 #include <linux/highmem.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
@@ -45,7 +46,6 @@
 #include <linux/scatterlist.h>
 #include <linux/sizes.h>
 #include <linux/spinlock.h>
-#include <linux/swiotlb.h>
 #include <linux/workqueue.h>
 
 #include "tmio_mmc.h"
@@ -1153,6 +1153,15 @@ void tmio_mmc_host_free(struct tmio_mmc_host *host)
 }
 EXPORT_SYMBOL_GPL(tmio_mmc_host_free);
 
+/**
+ * tmio_mmc_host_probe() - Common probe for all implementations
+ * @_host: Host to probe
+ *
+ * Perform tasks common to all implementations probe functions.
+ *
+ * The caller should have called pm_runtime_enable() prior to calling
+ * the common probe function.
+ */
 int tmio_mmc_host_probe(struct tmio_mmc_host *_host)
 {
        struct platform_device *pdev = _host->pdev;
@@ -1190,19 +1199,9 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host)
        mmc->max_blk_size = TMIO_MAX_BLK_SIZE;
        mmc->max_blk_count = pdata->max_blk_count ? :
                (PAGE_SIZE / mmc->max_blk_size) * mmc->max_segs;
-       mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
-       /*
-        * Since swiotlb has memory size limitation, this will calculate
-        * the maximum size locally (because we don't have any APIs for it now)
-        * and check the current max_req_size. And then, this will update
-        * the max_req_size if needed as a workaround.
-        */
-       if (swiotlb_max_segment()) {
-               unsigned int max_size = (1 << IO_TLB_SHIFT) * IO_TLB_SEGSIZE;
-
-               if (mmc->max_req_size > max_size)
-                       mmc->max_req_size = max_size;
-       }
+       mmc->max_req_size = min_t(size_t,
+                                 mmc->max_blk_size * mmc->max_blk_count,
+                                 dma_max_mapping_size(&pdev->dev));
        mmc->max_seg_size = mmc->max_req_size;
 
        if (mmc_can_gpio_ro(mmc))
@@ -1261,7 +1260,6 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host)
        pm_runtime_set_active(&pdev->dev);
        pm_runtime_set_autosuspend_delay(&pdev->dev, 50);
        pm_runtime_use_autosuspend(&pdev->dev);
-       pm_runtime_enable(&pdev->dev);
 
        ret = mmc_add_host(mmc);
        if (ret)
@@ -1297,7 +1295,6 @@ void tmio_mmc_host_remove(struct tmio_mmc_host *host)
 
        pm_runtime_dont_use_autosuspend(&pdev->dev);
        pm_runtime_put_sync(&pdev->dev);
-       pm_runtime_disable(&pdev->dev);
 }
 EXPORT_SYMBOL_GPL(tmio_mmc_host_remove);
 
index 91a2be41edf6196bd9fc7f73262ab206efa46d1f..49aad9a79c18d24aba0d45340964d24b5656aeb9 100644 (file)
@@ -631,6 +631,7 @@ static int uniphier_sd_probe(struct platform_device *pdev)
        host->clk_disable = uniphier_sd_clk_disable;
        host->set_clock = uniphier_sd_set_clock;
 
+       pm_runtime_enable(&pdev->dev);
        ret = uniphier_sd_clk_enable(host);
        if (ret)
                goto free_host;
@@ -652,6 +653,7 @@ static int uniphier_sd_probe(struct platform_device *pdev)
 
 free_host:
        tmio_mmc_host_free(host);
+       pm_runtime_disable(&pdev->dev);
 
        return ret;
 }
@@ -662,6 +664,7 @@ static int uniphier_sd_remove(struct platform_device *pdev)
 
        tmio_mmc_host_remove(host);
        uniphier_sd_clk_disable(host);
+       pm_runtime_disable(&pdev->dev);
 
        return 0;
 }
index 6309a721394bf52f3ad578a2144320b4732e9cbf..8d13e28a8e0751fb34b49e2c21af5db04600e2da 100644 (file)
@@ -729,13 +729,6 @@ static inline int dma_set_seg_boundary(struct device *dev, unsigned long mask)
        return -EIO;
 }
 
-#ifndef dma_max_pfn
-static inline unsigned long dma_max_pfn(struct device *dev)
-{
-       return (*dev->dma_mask >> PAGE_SHIFT) + dev->dma_pfn_offset;
-}
-#endif
-
 static inline int dma_get_cache_alignment(void)
 {
 #ifdef ARCH_DMA_MINALIGN
index 7ac3755444d3d5d6f27e246671258324429593c9..4a351cb7f20fc884df8720f66f0be9691d9eb6d3 100644 (file)
@@ -501,7 +501,6 @@ static inline void mmc_signal_sdio_irq(struct mmc_host *host)
                wake_up_process(host->sdio_irq_thread);
 }
 
-void sdio_run_irqs(struct mmc_host *host);
 void sdio_signal_irq(struct mmc_host *host);
 
 #ifdef CONFIG_REGULATOR