You've already forked linux-rockchip
mirror of
https://github.com/armbian/linux-rockchip.git
synced 2026-01-06 11:08:10 -08:00
Merge tag 'mmc-v5.20' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc
Pull MMC updates from Ulf Hansson: "MMC core: - Add support for the asynchronous SDIO wakeup interrupts - Skip redundant evaluation of eMMC HS400 caps when no-MMC-cap - Add support to store error stats from host drivers - Extend debugfs to show error stats from host drivers - Add single I/O read support in the recovery path for 4k sector cards MMC host: - dw_mmc-exynos: Convert corresponding DT bindings to the dtschema - dw_mmc-rockchip: Add support for the Rockchip RV1126 variant - mmc_spi: Convert corresponding DT bindings to the dtschema - mtk-sd: Extend support for interrupts/pinctrls for SDIO low-power mode - mtk-sd: Add support for SDIO wake irqs - mtk-sd: Add support for the Mediatek MT8188 variant - renesas_sdhi: Drop redundant manual tap correction for newer SoCs - renesas_sdhi: Add support for the R-Car S4-8 and generic Gen4 variants - sdhci/cqhci: Add support to capture stats from host errors - sdhci-brcmstb: Add ability to increase max clock rate for SDIO on 72116b0 - sdhci-msm: Add support for the MSM8998 and SM8450 variant - sdhci-of-at91: Fixup UHS-I mode by rewriting of MC1R - sdhci-of-dwcmshc: Add support for the Rockchip rk3588 variant - sdhci-of-dwcmshc: Enable reset support for the Rockchip variants - sdhci-pci-gli: Improve I/O read/write performance for GL9763E - sdhci-s3c: Convert corresponding DT bindings to the dtschema - tmio: Avoid glitches when resetting MEMSTICK core: - A couple of minor fixes and cleanups" * tag 'mmc-v5.20' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc: (61 commits) mmc: mediatek: add support for SDIO eint wakup IRQ mmc: core: Add support for SDIO wakeup interrupt dt-bindings: mmc: mtk-sd: extend interrupts and pinctrls properties dt-bindings: mmc: rockchip-dw-mshc: Document Rockchip RV1126 mmc: renesas_sdhi: newer SoCs don't need manual tap correction mmc: cavium-thunderx: Add of_node_put() when breaking out of loop mmc: cavium-octeon: Add of_node_put() when breaking out of loop mmc: core: quirks: Add of_node_put() when breaking out of loop mmc: sdhci-brcmstb: use clk_get_rate(base_clk) in PM resume dt-bindings: mmc: sdhci-msm: Document the SM8450 compatible mmc: sdhci-msm: drop redundant of_device_id entries dt-bindings: mmc: sdhci-msm: add MSM8998 mmc: block: Add single read for 4k sector cards mmc: mxcmmc: Use mmc_card_sdio macro mmc: core: Use mmc_card_* macro and add a new for the sd_combo type dt-bindings: mmc: sdhci-msm: constrain reg-names per variants dt-bindings: mmc: sdhci-msm: fix reg-names entries dt-bindings: mmc: Add compatible for MediaTek MT8188 dt-bindings: mmc: sdhci-msm: document resets mmc: sdhci-of-at91: fix set_uhs_signaling rewriting of MC1R ...
This commit is contained in:
@@ -10,9 +10,6 @@ maintainers:
|
||||
- Al Cooper <alcooperx@gmail.com>
|
||||
- Florian Fainelli <f.fainelli@gmail.com>
|
||||
|
||||
allOf:
|
||||
- $ref: mmc-controller.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
@@ -42,23 +39,46 @@ properties:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
description:
|
||||
handle to core clock for the sdhci controller.
|
||||
minItems: 1
|
||||
items:
|
||||
- description: handle to core clock for the sdhci controller
|
||||
- description: handle to improved 150Mhz clock for sdhci controller (Optional clock)
|
||||
|
||||
clock-names:
|
||||
minItems: 1
|
||||
items:
|
||||
- const: sw_sdio
|
||||
- const: sdio_freq # Optional clock
|
||||
|
||||
clock-frequency:
|
||||
description:
|
||||
Maximum operating frequency of sdio_freq sdhci controller clock
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 100000000
|
||||
maximum: 150000000
|
||||
|
||||
sdhci,auto-cmd12:
|
||||
type: boolean
|
||||
description: Specifies that controller should use auto CMD12
|
||||
|
||||
allOf:
|
||||
- $ref: mmc-controller.yaml#
|
||||
- if:
|
||||
properties:
|
||||
clock-names:
|
||||
contains:
|
||||
const: sdio_freq
|
||||
|
||||
then:
|
||||
required:
|
||||
- clock-frequency
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
- clock-names
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
* Samsung Exynos specific extensions to the Synopsys Designware Mobile
|
||||
Storage Host Controller
|
||||
|
||||
The Synopsys designware mobile storage host controller is used to interface
|
||||
a SoC with storage medium such as eMMC or SD/MMC cards. This file documents
|
||||
differences between the core Synopsys dw mshc controller properties described
|
||||
by synopsys-dw-mshc.txt and the properties used by the Samsung Exynos specific
|
||||
extensions to the Synopsys Designware Mobile Storage Host Controller.
|
||||
|
||||
Required Properties:
|
||||
|
||||
* compatible: should be
|
||||
- "samsung,exynos4210-dw-mshc": for controllers with Samsung Exynos4210
|
||||
specific extensions.
|
||||
- "samsung,exynos4412-dw-mshc": for controllers with Samsung Exynos4412
|
||||
specific extensions.
|
||||
- "samsung,exynos5250-dw-mshc": for controllers with Samsung Exynos5250
|
||||
specific extensions.
|
||||
- "samsung,exynos5420-dw-mshc": for controllers with Samsung Exynos5420
|
||||
specific extensions.
|
||||
- "samsung,exynos7-dw-mshc": for controllers with Samsung Exynos7
|
||||
specific extensions.
|
||||
- "samsung,exynos7-dw-mshc-smu": for controllers with Samsung Exynos7
|
||||
specific extensions having an SMU.
|
||||
- "axis,artpec8-dw-mshc": for controllers with ARTPEC-8 specific
|
||||
extensions.
|
||||
|
||||
* samsung,dw-mshc-ciu-div: Specifies the divider value for the card interface
|
||||
unit (ciu) clock. This property is applicable only for Exynos5 SoC's and
|
||||
ignored for Exynos4 SoC's. The valid range of divider value is 0 to 7.
|
||||
|
||||
* samsung,dw-mshc-sdr-timing: Specifies the value of CIU clock phase shift value
|
||||
in transmit mode and CIU clock phase shift value in receive mode for single
|
||||
data rate mode operation. Refer notes below for the order of the cells and the
|
||||
valid values.
|
||||
|
||||
* samsung,dw-mshc-ddr-timing: Specifies the value of CUI clock phase shift value
|
||||
in transmit mode and CIU clock phase shift value in receive mode for double
|
||||
data rate mode operation. Refer notes below for the order of the cells and the
|
||||
valid values.
|
||||
* samsung,dw-mshc-hs400-timing: Specifies the value of CIU TX and RX clock phase
|
||||
shift value for hs400 mode operation.
|
||||
|
||||
Notes for the sdr-timing and ddr-timing values:
|
||||
|
||||
The order of the cells should be
|
||||
- First Cell: CIU clock phase shift value for tx mode.
|
||||
- Second Cell: CIU clock phase shift value for rx mode.
|
||||
|
||||
Valid values for SDR and DDR CIU clock timing for Exynos5250:
|
||||
- valid value for tx phase shift and rx phase shift is 0 to 7.
|
||||
- when CIU clock divider value is set to 3, all possible 8 phase shift
|
||||
values can be used.
|
||||
- if CIU clock divider value is 0 (that is divide by 1), both tx and rx
|
||||
phase shift clocks should be 0.
|
||||
|
||||
* samsung,read-strobe-delay: RCLK (Data strobe) delay to control HS400 mode
|
||||
(Latency value for delay line in Read path)
|
||||
|
||||
Required properties for a slot (Deprecated - Recommend to use one slot per host):
|
||||
|
||||
* gpios: specifies a list of gpios used for command, clock and data bus. The
|
||||
first gpio is the command line and the second gpio is the clock line. The
|
||||
rest of the gpios (depending on the bus-width property) are the data lines in
|
||||
no particular order. The format of the gpio specifier depends on the gpio
|
||||
controller.
|
||||
(Deprecated - Refer to Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt)
|
||||
|
||||
Example:
|
||||
|
||||
The MSHC controller node can be split into two portions, SoC specific and
|
||||
board specific portions as listed below.
|
||||
|
||||
dwmmc0@12200000 {
|
||||
compatible = "samsung,exynos5250-dw-mshc";
|
||||
reg = <0x12200000 0x1000>;
|
||||
interrupts = <0 75 0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
|
||||
dwmmc0@12200000 {
|
||||
cap-mmc-highspeed;
|
||||
cap-sd-highspeed;
|
||||
broken-cd;
|
||||
fifo-depth = <0x80>;
|
||||
card-detect-delay = <200>;
|
||||
samsung,dw-mshc-ciu-div = <3>;
|
||||
samsung,dw-mshc-sdr-timing = <2 3>;
|
||||
samsung,dw-mshc-ddr-timing = <1 2>;
|
||||
samsung,dw-mshc-hs400-timing = <0 2>;
|
||||
samsung,read-strobe-delay = <90>;
|
||||
bus-width = <8>;
|
||||
};
|
||||
@@ -1,29 +0,0 @@
|
||||
MMC/SD/SDIO slot directly connected to a SPI bus
|
||||
|
||||
This file documents differences between the core properties described
|
||||
by mmc.txt and the properties used by the mmc_spi driver.
|
||||
|
||||
Required properties:
|
||||
- spi-max-frequency : maximum frequency for this device (Hz).
|
||||
|
||||
Optional properties:
|
||||
- voltage-ranges : two cells are required, first cell specifies minimum
|
||||
slot voltage (mV), second cell specifies maximum slot voltage (mV).
|
||||
Several ranges could be specified. If not provided, 3.2v..3.4v is assumed.
|
||||
- gpios : may specify GPIOs in this order: Card-Detect GPIO,
|
||||
Write-Protect GPIO. Note that this does not follow the
|
||||
binding from mmc.txt, for historical reasons.
|
||||
|
||||
Example:
|
||||
|
||||
mmc-slot@0 {
|
||||
compatible = "fsl,mpc8323rdb-mmc-slot",
|
||||
"mmc-spi-slot";
|
||||
reg = <0>;
|
||||
gpios = <&qe_pio_d 14 1
|
||||
&qe_pio_d 15 0>;
|
||||
voltage-ranges = <3300 3300>;
|
||||
spi-max-frequency = <50000000>;
|
||||
interrupts = <42>;
|
||||
interrupt-parent = <&PIC>;
|
||||
};
|
||||
77
Documentation/devicetree/bindings/mmc/mmc-spi-slot.yaml
Normal file
77
Documentation/devicetree/bindings/mmc/mmc-spi-slot.yaml
Normal file
@@ -0,0 +1,77 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/mmc/mmc-spi-slot.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: MMC/SD/SDIO slot directly connected to a SPI bus
|
||||
|
||||
maintainers:
|
||||
- Ulf Hansson <ulf.hansson@linaro.org>
|
||||
|
||||
allOf:
|
||||
- $ref: "mmc-controller.yaml"
|
||||
- $ref: /schemas/spi/spi-peripheral-props.yaml
|
||||
|
||||
description: |
|
||||
The extra properties used by an mmc connected via SPI.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: mmc-spi-slot
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
spi-max-frequency: true
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
voltage-ranges:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
description: |
|
||||
Two cells are required, first cell specifies minimum slot voltage (mV),
|
||||
second cell specifies maximum slot voltage (mV).
|
||||
items:
|
||||
- description: |
|
||||
value for minimum slot voltage in mV
|
||||
default: 3200
|
||||
- description: |
|
||||
value for maximum slot voltage in mV
|
||||
default: 3400
|
||||
|
||||
gpios:
|
||||
description: |
|
||||
For historical reasons, this does not follow the generic mmc-controller
|
||||
binding.
|
||||
minItems: 1
|
||||
items:
|
||||
- description: Card-Detect GPIO
|
||||
- description: Write-Protect GPIO
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- spi-max-frequency
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
spi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
mmc@0 {
|
||||
compatible = "mmc-spi-slot";
|
||||
reg = <0>;
|
||||
gpios = <&gpio 14 GPIO_ACTIVE_LOW>, <&gpio 15 GPIO_ACTIVE_HIGH>;
|
||||
voltage-ranges = <3300 3300>;
|
||||
spi-max-frequency = <50000000>;
|
||||
interrupts = <42>;
|
||||
interrupt-parent = <&PIC>;
|
||||
};
|
||||
};
|
||||
|
||||
...
|
||||
@@ -30,13 +30,11 @@ properties:
|
||||
- const: mediatek,mt7623-mmc
|
||||
- const: mediatek,mt2701-mmc
|
||||
- items:
|
||||
- const: mediatek,mt8186-mmc
|
||||
- const: mediatek,mt8183-mmc
|
||||
- items:
|
||||
- const: mediatek,mt8192-mmc
|
||||
- const: mediatek,mt8183-mmc
|
||||
- items:
|
||||
- const: mediatek,mt8195-mmc
|
||||
- enum:
|
||||
- mediatek,mt8186-mmc
|
||||
- mediatek,mt8188-mmc
|
||||
- mediatek,mt8192-mmc
|
||||
- mediatek,mt8195-mmc
|
||||
- const: mediatek,mt8183-mmc
|
||||
|
||||
reg:
|
||||
@@ -72,12 +70,27 @@ properties:
|
||||
- const: ahb_cg
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
description:
|
||||
Should at least contain MSDC GIC interrupt. To support SDIO in-band wakeup, an extended
|
||||
interrupt is required and be configured as wakeup source irq.
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
interrupt-names:
|
||||
items:
|
||||
- const: msdc
|
||||
- const: sdio_wakeup
|
||||
|
||||
pinctrl-names:
|
||||
description:
|
||||
Should at least contain default and state_uhs. To support SDIO in-band wakeup, dat1 pin
|
||||
will be switched between GPIO mode and SDIO DAT1 mode, state_eint is mandatory in this
|
||||
scenario.
|
||||
minItems: 2
|
||||
items:
|
||||
- const: default
|
||||
- const: state_uhs
|
||||
- const: state_eint
|
||||
|
||||
pinctrl-0:
|
||||
description:
|
||||
@@ -89,6 +102,11 @@ properties:
|
||||
should contain uhs mode pin ctrl.
|
||||
maxItems: 1
|
||||
|
||||
pinctrl-2:
|
||||
description:
|
||||
should switch dat1 pin to GPIO mode.
|
||||
maxItems: 1
|
||||
|
||||
assigned-clocks:
|
||||
description:
|
||||
PLL of the source clock.
|
||||
@@ -208,4 +226,32 @@ examples:
|
||||
mediatek,hs400-cmd-resp-sel-rising;
|
||||
};
|
||||
|
||||
mmc3: mmc@11260000 {
|
||||
compatible = "mediatek,mt8173-mmc";
|
||||
reg = <0x11260000 0x1000>;
|
||||
clock-names = "source", "hclk";
|
||||
clocks = <&pericfg CLK_PERI_MSDC30_3>,
|
||||
<&topckgen CLK_TOP_MSDC50_2_H_SEL>;
|
||||
interrupt-names = "msdc", "sdio_wakeup";
|
||||
interrupts-extended = <&gic GIC_SPI 74 IRQ_TYPE_LEVEL_LOW 0>,
|
||||
<&pio 23 IRQ_TYPE_LEVEL_LOW>;
|
||||
pinctrl-names = "default", "state_uhs", "state_eint";
|
||||
pinctrl-0 = <&mmc2_pins_default>;
|
||||
pinctrl-1 = <&mmc2_pins_uhs>;
|
||||
pinctrl-2 = <&mmc2_pins_eint>;
|
||||
bus-width = <4>;
|
||||
max-frequency = <200000000>;
|
||||
cap-sd-highspeed;
|
||||
sd-uhs-sdr104;
|
||||
keep-power-in-suspend;
|
||||
wakeup-source;
|
||||
cap-sdio-irq;
|
||||
no-mmc;
|
||||
no-sd;
|
||||
non-removable;
|
||||
vmmc-supply = <&sdio_fixed_3v3>;
|
||||
vqmmc-supply = <&mt6397_vgp3_reg>;
|
||||
mmc-pwrseq = <&wifi_pwrseq>;
|
||||
};
|
||||
|
||||
...
|
||||
|
||||
@@ -56,11 +56,15 @@ properties:
|
||||
- renesas,sdhi-r8a77980 # R-Car V3H
|
||||
- renesas,sdhi-r8a77990 # R-Car E3
|
||||
- renesas,sdhi-r8a77995 # R-Car D3
|
||||
- renesas,sdhi-r8a779a0 # R-Car V3U
|
||||
- renesas,sdhi-r9a07g043 # RZ/G2UL
|
||||
- renesas,sdhi-r9a07g044 # RZ/G2{L,LC}
|
||||
- renesas,sdhi-r9a07g054 # RZ/V2L
|
||||
- const: renesas,rcar-gen3-sdhi # R-Car Gen3 or RZ/G2
|
||||
- items:
|
||||
- enum:
|
||||
- renesas,sdhi-r8a779a0 # R-Car V3U
|
||||
- renesas,sdhi-r8a779f0 # R-Car S4-8
|
||||
- const: renesas,rcar-gen4-sdhi # R-Car Gen4
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
@@ -141,6 +145,7 @@ allOf:
|
||||
enum:
|
||||
- renesas,rcar-gen2-sdhi
|
||||
- renesas,rcar-gen3-sdhi
|
||||
- renesas,rcar-gen4-sdhi
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
|
||||
@@ -39,6 +39,7 @@ properties:
|
||||
- rockchip,rk3399-dw-mshc
|
||||
- rockchip,rk3568-dw-mshc
|
||||
- rockchip,rv1108-dw-mshc
|
||||
- rockchip,rv1126-dw-mshc
|
||||
- const: rockchip,rk3288-dw-mshc
|
||||
|
||||
reg:
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/mmc/samsung,exynos-dw-mshc.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title:
|
||||
Samsung Exynos SoC specific extensions to the Synopsys Designware Mobile
|
||||
Storage Host Controller
|
||||
|
||||
maintainers:
|
||||
- Jaehoon Chung <jh80.chung@samsung.com>
|
||||
- Krzysztof Kozlowski <krzk@kernel.org>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- samsung,exynos4210-dw-mshc
|
||||
- samsung,exynos4412-dw-mshc
|
||||
- samsung,exynos5250-dw-mshc
|
||||
- samsung,exynos5420-dw-mshc
|
||||
- samsung,exynos5420-dw-mshc-smu
|
||||
- samsung,exynos7-dw-mshc
|
||||
- samsung,exynos7-dw-mshc-smu
|
||||
- axis,artpec8-dw-mshc
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 2
|
||||
description:
|
||||
Handle to "biu" and "ciu" clocks for the
|
||||
bus interface unit clock and the card interface unit clock.
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: biu
|
||||
- const: ciu
|
||||
|
||||
samsung,dw-mshc-ciu-div:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 7
|
||||
description:
|
||||
The divider value for the card interface unit (ciu) clock.
|
||||
|
||||
samsung,dw-mshc-ddr-timing:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
items:
|
||||
- description: CIU clock phase shift value for tx mode
|
||||
minimum: 0
|
||||
maximum: 7
|
||||
- description: CIU clock phase shift value for rx mode
|
||||
minimum: 0
|
||||
maximum: 7
|
||||
description:
|
||||
The value of CUI clock phase shift value in transmit mode and CIU clock
|
||||
phase shift value in receive mode for double data rate mode operation.
|
||||
See also samsung,dw-mshc-hs400-timing property.
|
||||
|
||||
samsung,dw-mshc-hs400-timing:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
items:
|
||||
- description: CIU clock phase shift value for tx mode
|
||||
minimum: 0
|
||||
maximum: 7
|
||||
- description: CIU clock phase shift value for rx mode
|
||||
minimum: 0
|
||||
maximum: 7
|
||||
description: |
|
||||
The value of CIU TX and RX clock phase shift value for HS400 mode
|
||||
operation.
|
||||
Valid values for SDR and DDR CIU clock timing::
|
||||
- valid value for tx phase shift and rx phase shift is 0 to 7.
|
||||
- when CIU clock divider value is set to 3, all possible 8 phase shift
|
||||
values can be used.
|
||||
- if CIU clock divider value is 0 (that is divide by 1), both tx and rx
|
||||
phase shift clocks should be 0.
|
||||
If missing, values from samsung,dw-mshc-ddr-timing property are used.
|
||||
|
||||
samsung,dw-mshc-sdr-timing:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
items:
|
||||
- description: CIU clock phase shift value for tx mode
|
||||
minimum: 0
|
||||
maximum: 7
|
||||
- description: CIU clock phase shift value for rx mode
|
||||
minimum: 0
|
||||
maximum: 7
|
||||
description:
|
||||
The value of CIU clock phase shift value in transmit mode and CIU clock
|
||||
phase shift value in receive mode for single data rate mode operation.
|
||||
See also samsung,dw-mshc-hs400-timing property.
|
||||
|
||||
samsung,read-strobe-delay:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description:
|
||||
RCLK (Data strobe) delay to control HS400 mode (Latency value for delay
|
||||
line in Read path). If missing, default from hardware is used.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
- clock-names
|
||||
- samsung,dw-mshc-ddr-timing
|
||||
- samsung,dw-mshc-sdr-timing
|
||||
|
||||
allOf:
|
||||
- $ref: "synopsys-dw-mshc-common.yaml#"
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- samsung,exynos5250-dw-mshc
|
||||
- samsung,exynos5420-dw-mshc
|
||||
- samsung,exynos7-dw-mshc
|
||||
- samsung,exynos7-dw-mshc-smu
|
||||
- axis,artpec8-dw-mshc
|
||||
then:
|
||||
required:
|
||||
- samsung,dw-mshc-ciu-div
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/exynos5420.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
mmc@12220000 {
|
||||
compatible = "samsung,exynos5420-dw-mshc";
|
||||
interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0x12220000 0x1000>;
|
||||
clocks = <&clock CLK_MMC2>, <&clock CLK_SCLK_MMC2>;
|
||||
clock-names = "biu", "ciu";
|
||||
fifo-depth = <0x40>;
|
||||
card-detect-delay = <200>;
|
||||
samsung,dw-mshc-ciu-div = <3>;
|
||||
samsung,dw-mshc-sdr-timing = <0 4>;
|
||||
samsung,dw-mshc-ddr-timing = <0 2>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_wp &sd2_bus1 &sd2_bus4>;
|
||||
bus-width = <4>;
|
||||
cap-sd-highspeed;
|
||||
max-frequency = <200000000>;
|
||||
vmmc-supply = <&ldo19_reg>;
|
||||
vqmmc-supply = <&ldo13_reg>;
|
||||
sd-uhs-sdr50;
|
||||
sd-uhs-sdr104;
|
||||
sd-uhs-ddr50;
|
||||
};
|
||||
@@ -0,0 +1,81 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/mmc/samsung,s3c6410-sdhci.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Samsung SoC SDHCI Controller
|
||||
|
||||
maintainers:
|
||||
- Jaehoon Chung <jh80.chung@samsung.com>
|
||||
- Krzysztof Kozlowski <krzk@kernel.org>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- samsung,s3c6410-sdhci
|
||||
- samsung,exynos4210-sdhci
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
minItems: 2
|
||||
maxItems: 5
|
||||
|
||||
clock-names:
|
||||
minItems: 2
|
||||
items:
|
||||
- const: hsmmc
|
||||
- pattern: "^mmc_busclk.[0-3]$"
|
||||
- pattern: "^mmc_busclk.[0-3]$"
|
||||
- pattern: "^mmc_busclk.[0-3]$"
|
||||
- pattern: "^mmc_busclk.[0-3]$"
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
- clock-names
|
||||
|
||||
allOf:
|
||||
- $ref: mmc-controller.yaml#
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- samsung,exynos4210-sdhci
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
maxItems: 2
|
||||
clock-names:
|
||||
items:
|
||||
- const: hsmmc
|
||||
- const: mmc_busclk.2
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/exynos4.h>
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
mmc@12510000 {
|
||||
compatible = "samsung,exynos4210-sdhci";
|
||||
reg = <0x12510000 0x100>;
|
||||
interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&clock CLK_SDMMC0>, <&clock CLK_SCLK_MMC0>;
|
||||
clock-names = "hsmmc", "mmc_busclk.2";
|
||||
bus-width = <4>;
|
||||
cd-gpios = <&gpx3 4 GPIO_ACTIVE_LOW>;
|
||||
pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_bus4 &sdhci2_cd>;
|
||||
pinctrl-names = "default";
|
||||
vmmc-supply = <&ldo21_reg>;
|
||||
};
|
||||
@@ -1,32 +0,0 @@
|
||||
* Samsung's SDHCI Controller device tree bindings
|
||||
|
||||
Samsung's SDHCI controller is used as a connectivity interface with external
|
||||
MMC, SD and eMMC storage mediums. This file documents differences between the
|
||||
core mmc properties described by mmc.txt and the properties used by the
|
||||
Samsung implementation of the SDHCI controller.
|
||||
|
||||
Required SoC Specific Properties:
|
||||
- compatible: should be one of the following
|
||||
- "samsung,s3c6410-sdhci": For controllers compatible with s3c6410 sdhci
|
||||
controller.
|
||||
- "samsung,exynos4210-sdhci": For controllers compatible with Exynos4 sdhci
|
||||
controller.
|
||||
|
||||
Required Board Specific Properties:
|
||||
- pinctrl-0: Should specify pin control groups used for this controller.
|
||||
- pinctrl-names: Should contain only one value - "default".
|
||||
|
||||
Example:
|
||||
sdhci@12530000 {
|
||||
compatible = "samsung,exynos4210-sdhci";
|
||||
reg = <0x12530000 0x100>;
|
||||
interrupts = <0 75 0>;
|
||||
bus-width = <4>;
|
||||
cd-gpios = <&gpk2 2 0>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4>;
|
||||
};
|
||||
|
||||
Note: This example shows both SoC specific and board specific properties
|
||||
in a single device node. The properties can be actually be separated
|
||||
into SoC specific node and board specific node.
|
||||
@@ -17,6 +17,9 @@ description:
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- enum:
|
||||
- qcom,sdhci-msm-v4
|
||||
deprecated: true
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,apq8084-sdhci
|
||||
@@ -27,6 +30,10 @@ properties:
|
||||
- qcom,msm8992-sdhci
|
||||
- qcom,msm8994-sdhci
|
||||
- qcom,msm8996-sdhci
|
||||
- qcom,msm8998-sdhci
|
||||
- const: qcom,sdhci-msm-v4 # for sdcc versions less than 5.0
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,qcs404-sdhci
|
||||
- qcom,sc7180-sdhci
|
||||
- qcom,sc7280-sdhci
|
||||
@@ -38,20 +45,16 @@ properties:
|
||||
- qcom,sm6350-sdhci
|
||||
- qcom,sm8150-sdhci
|
||||
- qcom,sm8250-sdhci
|
||||
- enum:
|
||||
- qcom,sdhci-msm-v4 # for sdcc versions less than 5.0
|
||||
- qcom,sdhci-msm-v5 # for sdcc version 5.0
|
||||
- items:
|
||||
- const: qcom,sdhci-msm-v4 # Deprecated (only for backward compatibility)
|
||||
# for sdcc versions less than 5.0
|
||||
- qcom,sm8450-sdhci
|
||||
- const: qcom,sdhci-msm-v5 # for sdcc version 5.0
|
||||
|
||||
reg:
|
||||
minItems: 1
|
||||
items:
|
||||
- description: Host controller register map
|
||||
- description: SD Core register map
|
||||
- description: CQE register map
|
||||
- description: Inline Crypto Engine register map
|
||||
maxItems: 4
|
||||
|
||||
reg-names:
|
||||
minItems: 1
|
||||
maxItems: 4
|
||||
|
||||
clocks:
|
||||
minItems: 3
|
||||
@@ -93,6 +96,9 @@ properties:
|
||||
description:
|
||||
Should specify pin control groups used for this controller.
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
qcom,ddr-config:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: platform specific settings for DDR_CONFIG reg.
|
||||
@@ -121,6 +127,16 @@ properties:
|
||||
description: A phandle to sdhci power domain node
|
||||
maxItems: 1
|
||||
|
||||
mmc-ddr-1_8v: true
|
||||
|
||||
mmc-hs200-1_8v: true
|
||||
|
||||
mmc-hs400-1_8v: true
|
||||
|
||||
bus-width: true
|
||||
|
||||
max-frequency: true
|
||||
|
||||
patternProperties:
|
||||
'^opp-table(-[a-z0-9]+)?$':
|
||||
if:
|
||||
@@ -140,7 +156,47 @@ required:
|
||||
- clock-names
|
||||
- interrupts
|
||||
|
||||
additionalProperties: true
|
||||
allOf:
|
||||
- $ref: mmc-controller.yaml#
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,sdhci-msm-v4
|
||||
then:
|
||||
properties:
|
||||
reg:
|
||||
minItems: 2
|
||||
items:
|
||||
- description: Host controller register map
|
||||
- description: SD Core register map
|
||||
- description: CQE register map
|
||||
- description: Inline Crypto Engine register map
|
||||
reg-names:
|
||||
minItems: 2
|
||||
items:
|
||||
- const: hc
|
||||
- const: core
|
||||
- const: cqhci
|
||||
- const: ice
|
||||
else:
|
||||
properties:
|
||||
reg:
|
||||
minItems: 1
|
||||
items:
|
||||
- description: Host controller register map
|
||||
- description: CQE register map
|
||||
- description: Inline Crypto Engine register map
|
||||
reg-names:
|
||||
minItems: 1
|
||||
items:
|
||||
- const: hc
|
||||
- const: cqhci
|
||||
- const: ice
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
@@ -149,7 +205,7 @@ examples:
|
||||
#include <dt-bindings/clock/qcom,rpmh.h>
|
||||
#include <dt-bindings/power/qcom-rpmpd.h>
|
||||
|
||||
sdhc_2: sdhci@8804000 {
|
||||
sdhc_2: mmc@8804000 {
|
||||
compatible = "qcom,sm8250-sdhci", "qcom,sdhci-msm-v5";
|
||||
reg = <0 0x08804000 0 0x1000>;
|
||||
|
||||
|
||||
@@ -1341,17 +1341,17 @@ static int msb_ftl_initialize(struct msb_data *msb)
|
||||
msb->zone_count = msb->block_count / MS_BLOCKS_IN_ZONE;
|
||||
msb->logical_block_count = msb->zone_count * 496 - 2;
|
||||
|
||||
msb->used_blocks_bitmap = kzalloc(msb->block_count / 8, GFP_KERNEL);
|
||||
msb->erased_blocks_bitmap = kzalloc(msb->block_count / 8, GFP_KERNEL);
|
||||
msb->used_blocks_bitmap = bitmap_zalloc(msb->block_count, GFP_KERNEL);
|
||||
msb->erased_blocks_bitmap = bitmap_zalloc(msb->block_count, GFP_KERNEL);
|
||||
msb->lba_to_pba_table =
|
||||
kmalloc_array(msb->logical_block_count, sizeof(u16),
|
||||
GFP_KERNEL);
|
||||
|
||||
if (!msb->used_blocks_bitmap || !msb->lba_to_pba_table ||
|
||||
!msb->erased_blocks_bitmap) {
|
||||
kfree(msb->used_blocks_bitmap);
|
||||
bitmap_free(msb->used_blocks_bitmap);
|
||||
bitmap_free(msb->erased_blocks_bitmap);
|
||||
kfree(msb->lba_to_pba_table);
|
||||
kfree(msb->erased_blocks_bitmap);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
@@ -1946,7 +1946,8 @@ static DEFINE_MUTEX(msb_disk_lock); /* protects against races in open/release */
|
||||
static void msb_data_clear(struct msb_data *msb)
|
||||
{
|
||||
kfree(msb->boot_page);
|
||||
kfree(msb->used_blocks_bitmap);
|
||||
bitmap_free(msb->used_blocks_bitmap);
|
||||
bitmap_free(msb->erased_blocks_bitmap);
|
||||
kfree(msb->lba_to_pba_table);
|
||||
kfree(msb->cache);
|
||||
msb->card = NULL;
|
||||
@@ -2243,8 +2244,8 @@ static int msb_resume(struct memstick_dev *card)
|
||||
goto out;
|
||||
|
||||
if (msb->block_count != new_msb->block_count ||
|
||||
memcmp(msb->used_blocks_bitmap, new_msb->used_blocks_bitmap,
|
||||
msb->block_count / 8))
|
||||
!bitmap_equal(msb->used_blocks_bitmap, new_msb->used_blocks_bitmap,
|
||||
msb->block_count))
|
||||
goto out;
|
||||
|
||||
card_dead = false;
|
||||
|
||||
@@ -176,7 +176,7 @@ static inline int mmc_blk_part_switch(struct mmc_card *card,
|
||||
unsigned int part_type);
|
||||
static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
|
||||
struct mmc_card *card,
|
||||
int disable_multi,
|
||||
int recovery_mode,
|
||||
struct mmc_queue *mq);
|
||||
static void mmc_blk_hsq_req_done(struct mmc_request *mrq);
|
||||
|
||||
@@ -1302,7 +1302,7 @@ static void mmc_blk_eval_resp_error(struct mmc_blk_request *brq)
|
||||
}
|
||||
|
||||
static void mmc_blk_data_prep(struct mmc_queue *mq, struct mmc_queue_req *mqrq,
|
||||
int disable_multi, bool *do_rel_wr_p,
|
||||
int recovery_mode, bool *do_rel_wr_p,
|
||||
bool *do_data_tag_p)
|
||||
{
|
||||
struct mmc_blk_data *md = mq->blkdata;
|
||||
@@ -1368,12 +1368,12 @@ static void mmc_blk_data_prep(struct mmc_queue *mq, struct mmc_queue_req *mqrq,
|
||||
brq->data.blocks--;
|
||||
|
||||
/*
|
||||
* After a read error, we redo the request one sector
|
||||
* After a read error, we redo the request one (native) sector
|
||||
* at a time in order to accurately determine which
|
||||
* sectors can be read successfully.
|
||||
*/
|
||||
if (disable_multi)
|
||||
brq->data.blocks = 1;
|
||||
if (recovery_mode)
|
||||
brq->data.blocks = queue_physical_block_size(mq->queue) >> 9;
|
||||
|
||||
/*
|
||||
* Some controllers have HW issues while operating
|
||||
@@ -1590,7 +1590,7 @@ static int mmc_blk_cqe_issue_rw_rq(struct mmc_queue *mq, struct request *req)
|
||||
|
||||
static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
|
||||
struct mmc_card *card,
|
||||
int disable_multi,
|
||||
int recovery_mode,
|
||||
struct mmc_queue *mq)
|
||||
{
|
||||
u32 readcmd, writecmd;
|
||||
@@ -1599,7 +1599,7 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
|
||||
struct mmc_blk_data *md = mq->blkdata;
|
||||
bool do_rel_wr, do_data_tag;
|
||||
|
||||
mmc_blk_data_prep(mq, mqrq, disable_multi, &do_rel_wr, &do_data_tag);
|
||||
mmc_blk_data_prep(mq, mqrq, recovery_mode, &do_rel_wr, &do_data_tag);
|
||||
|
||||
brq->mrq.cmd = &brq->cmd;
|
||||
|
||||
@@ -1690,7 +1690,7 @@ static int mmc_blk_fix_state(struct mmc_card *card, struct request *req)
|
||||
|
||||
#define MMC_READ_SINGLE_RETRIES 2
|
||||
|
||||
/* Single sector read during recovery */
|
||||
/* Single (native) sector read during recovery */
|
||||
static void mmc_blk_read_single(struct mmc_queue *mq, struct request *req)
|
||||
{
|
||||
struct mmc_queue_req *mqrq = req_to_mmc_queue_req(req);
|
||||
@@ -1698,6 +1698,7 @@ static void mmc_blk_read_single(struct mmc_queue *mq, struct request *req)
|
||||
struct mmc_card *card = mq->card;
|
||||
struct mmc_host *host = card->host;
|
||||
blk_status_t error = BLK_STS_OK;
|
||||
size_t bytes_per_read = queue_physical_block_size(mq->queue);
|
||||
|
||||
do {
|
||||
u32 status;
|
||||
@@ -1732,13 +1733,13 @@ static void mmc_blk_read_single(struct mmc_queue *mq, struct request *req)
|
||||
else
|
||||
error = BLK_STS_OK;
|
||||
|
||||
} while (blk_update_request(req, error, 512));
|
||||
} while (blk_update_request(req, error, bytes_per_read));
|
||||
|
||||
return;
|
||||
|
||||
error_exit:
|
||||
mrq->data->bytes_xfered = 0;
|
||||
blk_update_request(req, BLK_STS_IOERR, 512);
|
||||
blk_update_request(req, BLK_STS_IOERR, bytes_per_read);
|
||||
/* Let it try the remaining request again */
|
||||
if (mqrq->retries > MMC_MAX_RETRIES - 1)
|
||||
mqrq->retries = MMC_MAX_RETRIES - 1;
|
||||
@@ -1879,10 +1880,9 @@ static void mmc_blk_mq_rw_recovery(struct mmc_queue *mq, struct request *req)
|
||||
return;
|
||||
}
|
||||
|
||||
/* FIXME: Missing single sector read for large sector size */
|
||||
if (!mmc_large_sector(card) && rq_data_dir(req) == READ &&
|
||||
brq->data.blocks > 1) {
|
||||
/* Read one sector at a time */
|
||||
if (rq_data_dir(req) == READ && brq->data.blocks >
|
||||
queue_physical_block_size(mq->queue) >> 9) {
|
||||
/* Read one (native) sector at a time */
|
||||
mmc_blk_read_single(mq, req);
|
||||
return;
|
||||
}
|
||||
@@ -2988,7 +2988,7 @@ static int mmc_blk_probe(struct mmc_card *card)
|
||||
* Don't enable runtime PM for SD-combo cards here. Leave that
|
||||
* decision to be taken during the SDIO init sequence instead.
|
||||
*/
|
||||
if (card->type != MMC_TYPE_SD_COMBO) {
|
||||
if (!mmc_card_sd_combo(card)) {
|
||||
pm_runtime_set_active(&card->dev);
|
||||
pm_runtime_enable(&card->dev);
|
||||
}
|
||||
@@ -3015,7 +3015,7 @@ static void mmc_blk_remove(struct mmc_card *card)
|
||||
mmc_blk_part_switch(card, md->part_type);
|
||||
mmc_release_host(card->host);
|
||||
}
|
||||
if (card->type != MMC_TYPE_SD_COMBO)
|
||||
if (!mmc_card_sd_combo(card))
|
||||
pm_runtime_disable(&card->dev);
|
||||
pm_runtime_put_noidle(&card->dev);
|
||||
mmc_blk_remove_req(md);
|
||||
|
||||
@@ -85,7 +85,7 @@ mmc_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
return retval;
|
||||
}
|
||||
|
||||
if (card->type == MMC_TYPE_SDIO || card->type == MMC_TYPE_SD_COMBO) {
|
||||
if (mmc_card_sdio(card) || mmc_card_sd_combo(card)) {
|
||||
retval = add_uevent_var(env, "SDIO_ID=%04X:%04X",
|
||||
card->cis.vendor, card->cis.device);
|
||||
if (retval)
|
||||
@@ -107,7 +107,7 @@ mmc_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
* SDIO (non-combo) cards are not handled by mmc_block driver and do not
|
||||
* have accessible CID register which used by mmc_card_name() function.
|
||||
*/
|
||||
if (card->type == MMC_TYPE_SDIO)
|
||||
if (mmc_card_sdio(card))
|
||||
return 0;
|
||||
|
||||
retval = add_uevent_var(env, "MMC_NAME=%s", mmc_card_name(card));
|
||||
|
||||
@@ -943,9 +943,11 @@ int mmc_execute_tuning(struct mmc_card *card)
|
||||
}
|
||||
|
||||
/* Only print error when we don't check for card removal */
|
||||
if (!host->detect_change)
|
||||
if (!host->detect_change) {
|
||||
pr_err("%s: tuning execution failed: %d\n",
|
||||
mmc_hostname(host), err);
|
||||
mmc_debugfs_err_stats_inc(host, MMC_ERR_TUNING);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
@@ -2244,6 +2246,12 @@ void mmc_rescan(struct work_struct *work)
|
||||
if (freqs[i] <= host->f_min)
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ignore the command timeout errors observed during
|
||||
* the card init as those are excepted.
|
||||
*/
|
||||
host->err_stats[MMC_ERR_CMD_TIMEOUT] = 0;
|
||||
mmc_release_host(host);
|
||||
|
||||
out:
|
||||
|
||||
@@ -223,6 +223,81 @@ static int mmc_clock_opt_set(void *data, u64 val)
|
||||
DEFINE_DEBUGFS_ATTRIBUTE(mmc_clock_fops, mmc_clock_opt_get, mmc_clock_opt_set,
|
||||
"%llu\n");
|
||||
|
||||
static int mmc_err_state_get(void *data, u64 *val)
|
||||
{
|
||||
struct mmc_host *host = data;
|
||||
int i;
|
||||
|
||||
if (!host)
|
||||
return -EINVAL;
|
||||
|
||||
*val = 0;
|
||||
for (i = 0; i < MMC_ERR_MAX; i++) {
|
||||
if (host->err_stats[i]) {
|
||||
*val = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_DEBUGFS_ATTRIBUTE(mmc_err_state, mmc_err_state_get, NULL, "%llu\n");
|
||||
|
||||
static int mmc_err_stats_show(struct seq_file *file, void *data)
|
||||
{
|
||||
struct mmc_host *host = (struct mmc_host *)file->private;
|
||||
const char *desc[MMC_ERR_MAX] = {
|
||||
[MMC_ERR_CMD_TIMEOUT] = "Command Timeout Occurred",
|
||||
[MMC_ERR_CMD_CRC] = "Command CRC Errors Occurred",
|
||||
[MMC_ERR_DAT_TIMEOUT] = "Data Timeout Occurred",
|
||||
[MMC_ERR_DAT_CRC] = "Data CRC Errors Occurred",
|
||||
[MMC_ERR_AUTO_CMD] = "Auto-Cmd Error Occurred",
|
||||
[MMC_ERR_ADMA] = "ADMA Error Occurred",
|
||||
[MMC_ERR_TUNING] = "Tuning Error Occurred",
|
||||
[MMC_ERR_CMDQ_RED] = "CMDQ RED Errors",
|
||||
[MMC_ERR_CMDQ_GCE] = "CMDQ GCE Errors",
|
||||
[MMC_ERR_CMDQ_ICCE] = "CMDQ ICCE Errors",
|
||||
[MMC_ERR_REQ_TIMEOUT] = "Request Timedout",
|
||||
[MMC_ERR_CMDQ_REQ_TIMEOUT] = "CMDQ Request Timedout",
|
||||
[MMC_ERR_ICE_CFG] = "ICE Config Errors",
|
||||
[MMC_ERR_CTRL_TIMEOUT] = "Controller Timedout errors",
|
||||
[MMC_ERR_UNEXPECTED_IRQ] = "Unexpected IRQ errors",
|
||||
};
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MMC_ERR_MAX; i++) {
|
||||
if (desc[i])
|
||||
seq_printf(file, "# %s:\t %d\n",
|
||||
desc[i], host->err_stats[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mmc_err_stats_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, mmc_err_stats_show, inode->i_private);
|
||||
}
|
||||
|
||||
static ssize_t mmc_err_stats_write(struct file *filp, const char __user *ubuf,
|
||||
size_t cnt, loff_t *ppos)
|
||||
{
|
||||
struct mmc_host *host = filp->f_mapping->host->i_private;
|
||||
|
||||
pr_debug("%s: Resetting MMC error statistics\n", __func__);
|
||||
memset(host->err_stats, 0, sizeof(host->err_stats));
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
static const struct file_operations mmc_err_stats_fops = {
|
||||
.open = mmc_err_stats_open,
|
||||
.read = seq_read,
|
||||
.write = mmc_err_stats_write,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
void mmc_add_host_debugfs(struct mmc_host *host)
|
||||
{
|
||||
struct dentry *root;
|
||||
@@ -236,6 +311,11 @@ void mmc_add_host_debugfs(struct mmc_host *host)
|
||||
debugfs_create_file_unsafe("clock", S_IRUSR | S_IWUSR, root, host,
|
||||
&mmc_clock_fops);
|
||||
|
||||
debugfs_create_file_unsafe("err_state", 0600, root, host,
|
||||
&mmc_err_state);
|
||||
debugfs_create_file("err_stats", 0600, root, host,
|
||||
&mmc_err_stats_fops);
|
||||
|
||||
#ifdef CONFIG_FAIL_MMC_REQUEST
|
||||
if (fail_request)
|
||||
setup_fault_attr(&fail_default_attr, fail_request);
|
||||
|
||||
@@ -599,7 +599,7 @@ static int mmc_validate_host_caps(struct mmc_host *host)
|
||||
}
|
||||
|
||||
if (caps2 & (MMC_CAP2_HS400_ES | MMC_CAP2_HS400) &&
|
||||
!(caps & MMC_CAP_8_BIT_DATA)) {
|
||||
!(caps & MMC_CAP_8_BIT_DATA) && !(caps2 & MMC_CAP2_NO_MMC)) {
|
||||
dev_warn(dev, "drop HS400 support since no 8-bit bus\n");
|
||||
host->caps2 = caps2 & ~MMC_CAP2_HS400_ES & ~MMC_CAP2_HS400;
|
||||
}
|
||||
|
||||
@@ -163,8 +163,10 @@ static inline bool mmc_fixup_of_compatible_match(struct mmc_card *card,
|
||||
struct device_node *np;
|
||||
|
||||
for_each_child_of_node(mmc_dev(card->host)->of_node, np) {
|
||||
if (of_device_is_compatible(np, compatible))
|
||||
if (of_device_is_compatible(np, compatible)) {
|
||||
of_node_put(np);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -793,7 +793,7 @@ static umode_t sd_std_is_visible(struct kobject *kobj, struct attribute *attr,
|
||||
attr == &dev_attr_info2.attr ||
|
||||
attr == &dev_attr_info3.attr ||
|
||||
attr == &dev_attr_info4.attr
|
||||
) && card->type != MMC_TYPE_SD_COMBO)
|
||||
) &&!mmc_card_sd_combo(card))
|
||||
return 0;
|
||||
|
||||
return attr->mode;
|
||||
@@ -870,7 +870,7 @@ try_again:
|
||||
* the CCS bit is set as well. We deliberately deviate from the spec in
|
||||
* regards to this, which allows UHS-I to be supported for SDSC cards.
|
||||
*/
|
||||
if (!mmc_host_is_spi(host) && rocr && (*rocr & 0x01000000)) {
|
||||
if (!mmc_host_is_spi(host) && rocr && (*rocr & SD_ROCR_S18A)) {
|
||||
err = mmc_set_uhs_voltage(host, pocr);
|
||||
if (err == -EAGAIN) {
|
||||
retries--;
|
||||
|
||||
@@ -226,6 +226,20 @@ static int sdio_read_cccr(struct mmc_card *card, u32 ocr)
|
||||
card->sw_caps.sd3_drv_type |= SD_DRIVER_TYPE_C;
|
||||
if (data & SDIO_DRIVE_SDTD)
|
||||
card->sw_caps.sd3_drv_type |= SD_DRIVER_TYPE_D;
|
||||
|
||||
ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_INTERRUPT_EXT, 0, &data);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
if (data & SDIO_INTERRUPT_EXT_SAI) {
|
||||
data |= SDIO_INTERRUPT_EXT_EAI;
|
||||
ret = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_INTERRUPT_EXT,
|
||||
data, NULL);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
card->cccr.enable_async_irq = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* if no uhs mode ensure we check for high speed */
|
||||
@@ -335,7 +349,7 @@ static int sdio_disable_4bit_bus(struct mmc_card *card)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (card->type == MMC_TYPE_SDIO)
|
||||
if (mmc_card_sdio(card))
|
||||
goto out;
|
||||
|
||||
if (!(card->host->caps & MMC_CAP_4_BIT_DATA))
|
||||
@@ -360,7 +374,7 @@ static int sdio_enable_4bit_bus(struct mmc_card *card)
|
||||
err = sdio_enable_wide(card);
|
||||
if (err <= 0)
|
||||
return err;
|
||||
if (card->type == MMC_TYPE_SDIO)
|
||||
if (mmc_card_sdio(card))
|
||||
goto out;
|
||||
|
||||
if (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4) {
|
||||
@@ -415,7 +429,7 @@ static int sdio_enable_hs(struct mmc_card *card)
|
||||
int ret;
|
||||
|
||||
ret = mmc_sdio_switch_hs(card, true);
|
||||
if (ret <= 0 || card->type == MMC_TYPE_SDIO)
|
||||
if (ret <= 0 || mmc_card_sdio(card))
|
||||
return ret;
|
||||
|
||||
ret = mmc_sd_switch_hs(card);
|
||||
@@ -441,7 +455,7 @@ static unsigned mmc_sdio_get_max_clock(struct mmc_card *card)
|
||||
max_dtr = card->cis.max_dtr;
|
||||
}
|
||||
|
||||
if (card->type == MMC_TYPE_SD_COMBO)
|
||||
if (mmc_card_sd_combo(card))
|
||||
max_dtr = min(max_dtr, mmc_sd_get_max_clock(card));
|
||||
|
||||
return max_dtr;
|
||||
@@ -689,7 +703,7 @@ try_again:
|
||||
mmc_sd_get_cid(host, ocr & rocr, card->raw_cid, NULL) == 0) {
|
||||
card->type = MMC_TYPE_SD_COMBO;
|
||||
|
||||
if (oldcard && (oldcard->type != MMC_TYPE_SD_COMBO ||
|
||||
if (oldcard && (!mmc_card_sd_combo(oldcard) ||
|
||||
memcmp(card->raw_cid, oldcard->raw_cid, sizeof(card->raw_cid)) != 0)) {
|
||||
err = -ENOENT;
|
||||
goto mismatch;
|
||||
@@ -697,7 +711,7 @@ try_again:
|
||||
} else {
|
||||
card->type = MMC_TYPE_SDIO;
|
||||
|
||||
if (oldcard && oldcard->type != MMC_TYPE_SDIO) {
|
||||
if (oldcard && !mmc_card_sdio(oldcard)) {
|
||||
err = -ENOENT;
|
||||
goto mismatch;
|
||||
}
|
||||
@@ -754,7 +768,7 @@ try_again:
|
||||
/*
|
||||
* Read CSD, before selecting the card
|
||||
*/
|
||||
if (!oldcard && card->type == MMC_TYPE_SD_COMBO) {
|
||||
if (!oldcard && mmc_card_sd_combo(card)) {
|
||||
err = mmc_sd_get_csd(card);
|
||||
if (err)
|
||||
goto remove;
|
||||
@@ -827,7 +841,7 @@ try_again:
|
||||
|
||||
mmc_fixup_device(card, sdio_fixup_methods);
|
||||
|
||||
if (card->type == MMC_TYPE_SD_COMBO) {
|
||||
if (mmc_card_sd_combo(card)) {
|
||||
err = mmc_sd_setup_card(host, card, oldcard != NULL);
|
||||
/* handle as SDIO-only card if memory init failed */
|
||||
if (err) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user