mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-09-18 22:09:30 +02:00
Merge tag 'mmc-v7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc
Pull MMC updates from Ulf Hansson: "MMC core: - Reject invalid perdev_minors for the block device before division - Document DT fixed-layout NVMEM provider support for eMMC cards MMC host: - Convert a couple of plain text DT bindings to the yaml format - bcm2835: DMA mapping improvements - cqhci: Fix sparse warnings for endian conversions - dw_mmc: Stop and complete DMA also in busy state - dw_mmc-rockchip: Add support for the RV1106 variant - litex_mmc: Add dynamic bus width support - moxart: Propagate error for DMA completion timeout - pxamci: Remove PXA remnants for the PXA93x support - rtsx_usb_sdmmc: Avoid USB I/O in runtime autosuspend - rtsx_usb_sdmmc: Suppress false CD after init timeout - sdhci_am654: Add Judith Mendez as maintainer - sdhci-esdhc-mcf: Do not use readl()/writel() on ColdFire - sdhci-msm: Extend the DT bindings for ICE - sdhci-tegra: Add support for Tegra264/Tegra238 variants - sunxi: Add support for the Allwinner A733 variant - via-sdmmc: Clean up card detect work at remove and in probe error path" * tag 'mmc-v7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc: (35 commits) ARM: PXA: Fix build error for PXA93x dt-bindings: mmc: sunxi: add compatible string for Allwinner A733 MMC0/1/2 dt-bindings: mmc: Document fixed-layout NVMEM provider support mmc: sdhci-tegra: Add Tegra264 SoC data dt-bindings: mmc: tegra: Document Tegra264 SDHCI mmc: sdhci-tegra: Add Tegra238 SoC data dt-bindings: mmc: tegra: Document Tegra238 SDHCI mmc: omap_hsmmc: use platform_get_irq_optional for wake IRQ mmc: via-sdmmc: cancel card-detect work on remove mmc: via-sdmmc: stop card-detect handling on probe failure mmc: moxart: use platform helpers for resource and IRQ mmc: host: Remove redundant dev_err()/dev_err_probe() mmc: bcm2835: DMA mapping improvements mmc: dw_mmc: move declaration of dw_mci_pmops dt-bindings: mmc: rockchip-dw-mshc: Add RV1106 compatible mmc: rtsx_usb_sdmmc: suppress false CD after init timeout misc: rtsx_usb: avoid USB I/O in runtime autosuspend mmc: sdhci-of-dwcmshc: Log eMMC reset calls mmc: block: reject invalid perdev_minors before division mmc: sdhci-of-ma35d1: add missing MODULE_DEVICE_TABLE() ...
This commit is contained in:
@@ -56,7 +56,9 @@ properties:
|
||||
- const: allwinner,sun50i-h616-mmc
|
||||
- const: allwinner,sun50i-a100-mmc
|
||||
- items:
|
||||
- const: allwinner,sun55i-a523-mmc
|
||||
- enum:
|
||||
- allwinner,sun55i-a523-mmc
|
||||
- allwinner,sun60i-a733-mmc
|
||||
- const: allwinner,sun20i-d1-mmc
|
||||
|
||||
reg:
|
||||
|
||||
@@ -38,7 +38,9 @@ patternProperties:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: fixed-partitions
|
||||
enum:
|
||||
- fixed-partitions
|
||||
- fixed-layout
|
||||
|
||||
required:
|
||||
- compatible
|
||||
@@ -86,6 +88,25 @@ examples:
|
||||
read-only;
|
||||
};
|
||||
};
|
||||
|
||||
partitions-boot2 {
|
||||
compatible = "fixed-layout";
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
mac-addr@4400 {
|
||||
compatible = "mac-base";
|
||||
reg = <0x4400 0x6>;
|
||||
#nvmem-cell-cells = <1>;
|
||||
};
|
||||
|
||||
bd-addr@5400 {
|
||||
compatible = "mac-base";
|
||||
reg = <0x5400 0x6>;
|
||||
#nvmem-cell-cells = <1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -39,6 +39,12 @@ properties:
|
||||
- nvidia,tegra234-sdhci
|
||||
- const: nvidia,tegra186-sdhci
|
||||
|
||||
- items:
|
||||
- enum:
|
||||
- nvidia,tegra238-sdhci
|
||||
- nvidia,tegra264-sdhci
|
||||
- const: nvidia,tegra194-sdhci
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
|
||||
@@ -145,6 +145,11 @@ properties:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: platform specific settings for DLL_CONFIG reg.
|
||||
|
||||
qcom,ice:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description:
|
||||
phandle to the Inline Crypto Engine (ICE) hardware block for this controller.
|
||||
|
||||
iommus:
|
||||
minItems: 1
|
||||
maxItems: 8
|
||||
@@ -198,35 +203,69 @@ allOf:
|
||||
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
|
||||
if:
|
||||
required:
|
||||
- qcom,ice
|
||||
then:
|
||||
properties:
|
||||
reg:
|
||||
minItems: 2
|
||||
items:
|
||||
- description: Host controller register map
|
||||
- description: SD Core register map
|
||||
- description: CQE register map
|
||||
reg-names:
|
||||
minItems: 2
|
||||
items:
|
||||
- const: hc
|
||||
- const: core
|
||||
- const: cqhci
|
||||
else:
|
||||
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
|
||||
if:
|
||||
required:
|
||||
- qcom,ice
|
||||
then:
|
||||
properties:
|
||||
reg:
|
||||
minItems: 1
|
||||
items:
|
||||
- description: Host controller register map
|
||||
- description: CQE register map
|
||||
reg-names:
|
||||
minItems: 1
|
||||
items:
|
||||
- const: hc
|
||||
- const: cqhci
|
||||
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
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ properties:
|
||||
- rockchip,rk3562-dw-mshc
|
||||
- rockchip,rk3568-dw-mshc
|
||||
- rockchip,rk3588-dw-mshc
|
||||
- rockchip,rv1106-dw-mshc
|
||||
- rockchip,rv1108-dw-mshc
|
||||
- rockchip,rv1126-dw-mshc
|
||||
- const: rockchip,rk3288-dw-mshc
|
||||
|
||||
@@ -1,110 +0,0 @@
|
||||
* STMicroelectronics sdhci-st MMC/SD controller
|
||||
|
||||
This file documents the differences between the core properties in
|
||||
Documentation/devicetree/bindings/mmc/mmc.txt and the properties
|
||||
used by the sdhci-st driver.
|
||||
|
||||
Required properties:
|
||||
- compatible: Must be "st,sdhci" and it can be compatible to "st,sdhci-stih407"
|
||||
to set the internal glue logic used for configuring the MMC
|
||||
subsystem (mmcss) inside the FlashSS (available in STiH407 SoC
|
||||
family).
|
||||
|
||||
- clock-names: Should be "mmc" and "icn". (NB: The latter is not compulsory)
|
||||
See: Documentation/devicetree/bindings/resource-names.txt
|
||||
- clocks: Phandle to the clock.
|
||||
See: Documentation/devicetree/bindings/clock/clock-bindings.txt
|
||||
|
||||
- interrupts: One mmc interrupt should be described here.
|
||||
- interrupt-names: Should be "mmcirq".
|
||||
|
||||
- pinctrl-names: A pinctrl state names "default" must be defined.
|
||||
- pinctrl-0: Phandle referencing pin configuration of the sd/emmc controller.
|
||||
See: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
|
||||
|
||||
- reg: This must provide the host controller base address and it can also
|
||||
contain the FlashSS Top register for TX/RX delay used by the driver
|
||||
to configure DLL inside the flashSS, if so reg-names must also be
|
||||
specified.
|
||||
|
||||
Optional properties:
|
||||
- reg-names: Should be "mmc" and "top-mmc-delay". "top-mmc-delay" is optional
|
||||
for eMMC on stih407 family silicon to configure DLL inside FlashSS.
|
||||
|
||||
- non-removable: Non-removable slot. Also used for configuring mmcss in STiH407 SoC
|
||||
family.
|
||||
See: Documentation/devicetree/bindings/mmc/mmc.txt.
|
||||
|
||||
- bus-width: Number of data lines.
|
||||
See: Documentation/devicetree/bindings/mmc/mmc.txt.
|
||||
|
||||
- max-frequency: Can be 200MHz, 100MHz or 50MHz (default) and used for
|
||||
configuring the CCONFIG3 in the mmcss.
|
||||
See: Documentation/devicetree/bindings/mmc/mmc.txt.
|
||||
|
||||
- resets: Phandle and reset specifier pair to softreset line of HC IP.
|
||||
See: Documentation/devicetree/bindings/reset/reset.txt
|
||||
|
||||
- vqmmc-supply: Phandle to the regulator dt node, mentioned as the vcc/vdd
|
||||
supply in eMMC/SD specs.
|
||||
|
||||
- sd-uhs-sdr50: To enable the SDR50 in the mmcss.
|
||||
See: Documentation/devicetree/bindings/mmc/mmc.txt.
|
||||
|
||||
- sd-uhs-sdr104: To enable the SDR104 in the mmcss.
|
||||
See: Documentation/devicetree/bindings/mmc/mmc.txt.
|
||||
|
||||
- sd-uhs-ddr50: To enable the DDR50 in the mmcss.
|
||||
See: Documentation/devicetree/bindings/mmc/mmc.txt.
|
||||
|
||||
Example:
|
||||
|
||||
/* Example stih416e eMMC configuration */
|
||||
|
||||
mmc0: sdhci@fe81e000 {
|
||||
compatible = "st,sdhci";
|
||||
reg = <0xfe81e000 0x1000>;
|
||||
interrupts = <GIC_SPI 127 IRQ_TYPE_NONE>;
|
||||
interrupt-names = "mmcirq";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_mmc0>;
|
||||
clock-names = "mmc";
|
||||
clocks = <&clk_s_a1_ls 1>;
|
||||
bus-width = <8>
|
||||
|
||||
/* Example SD stih407 family configuration */
|
||||
|
||||
mmc1: sdhci@9080000 {
|
||||
compatible = "st,sdhci-stih407", "st,sdhci";
|
||||
reg = <0x09080000 0x7ff>;
|
||||
reg-names = "mmc";
|
||||
interrupts = <GIC_SPI 90 IRQ_TYPE_NONE>;
|
||||
interrupt-names = "mmcirq";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_sd1>;
|
||||
clock-names = "mmc";
|
||||
clocks = <&clk_s_c0_flexgen CLK_MMC_1>;
|
||||
resets = <&softreset STIH407_MMC1_SOFTRESET>;
|
||||
bus-width = <4>;
|
||||
};
|
||||
|
||||
/* Example eMMC stih407 family configuration */
|
||||
|
||||
mmc0: sdhci@9060000 {
|
||||
compatible = "st,sdhci-stih407", "st,sdhci";
|
||||
reg = <0x09060000 0x7ff>, <0x9061008 0x20>;
|
||||
reg-names = "mmc", "top-mmc-delay";
|
||||
interrupts = <GIC_SPI 92 IRQ_TYPE_NONE>;
|
||||
interrupt-names = "mmcirq";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_mmc0>;
|
||||
clock-names = "mmc";
|
||||
clocks = <&clk_s_c0_flexgen CLK_MMC_0>;
|
||||
vqmmc-supply = <&vmmc_reg>;
|
||||
max-frequency = <200000000>;
|
||||
bus-width = <8>;
|
||||
non-removable;
|
||||
sd-uhs-sdr50;
|
||||
sd-uhs-sdr104;
|
||||
sd-uhs-ddr50;
|
||||
};
|
||||
@@ -0,0 +1,105 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/mmc/st,sdhci.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: STMicroelectronics SDHCI-ST MMC/SD Controller
|
||||
|
||||
maintainers:
|
||||
- Peter Griffin <peter.griffin@linaro.org>
|
||||
|
||||
description:
|
||||
The STMicroelectronics SDHCI-ST MMC/SD host controller is compliant with
|
||||
the SD Host Controller Interface (SDHCI) specification and is used to
|
||||
interface with MMC, SD and SDIO cards. The ST SDHCI controller extends the
|
||||
standard SDHCI capabilities with platform-specific configurations such as
|
||||
additional register regions, clock inputs, and delay control mechanisms
|
||||
required for signal timing adjustments to support high-speed modes across
|
||||
different ST SoCs.
|
||||
|
||||
allOf:
|
||||
- $ref: mmc-controller.yaml#
|
||||
- if:
|
||||
properties:
|
||||
reg:
|
||||
minItems: 2
|
||||
required:
|
||||
- reg
|
||||
then:
|
||||
required:
|
||||
- reg-names
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- const: st,sdhci
|
||||
- items:
|
||||
- const: st,sdhci-stih407
|
||||
- const: st,sdhci
|
||||
|
||||
reg:
|
||||
minItems: 1
|
||||
items:
|
||||
- description: MMC controller base registers
|
||||
- description: FlashSS Top registers for TX/RX DLL delay configuration
|
||||
|
||||
reg-names:
|
||||
minItems: 1
|
||||
items:
|
||||
- const: mmc
|
||||
- const: top-mmc-delay
|
||||
|
||||
clocks:
|
||||
minItems: 1
|
||||
items:
|
||||
- description: Clock for the MMC controller
|
||||
- description: Interconnect (ICN) clock
|
||||
|
||||
clock-names:
|
||||
minItems: 1
|
||||
items:
|
||||
- const: mmc
|
||||
- const: icn
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
interrupt-names:
|
||||
const: mmcirq
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
max-frequency:
|
||||
enum: [200000000, 100000000, 50000000]
|
||||
default: 50000000
|
||||
|
||||
required:
|
||||
- reg
|
||||
- compatible
|
||||
- clocks
|
||||
- clock-names
|
||||
- interrupts
|
||||
- interrupt-names
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/clock/stih407-clks.h>
|
||||
mmc@9060000 {
|
||||
compatible = "st,sdhci-stih407", "st,sdhci";
|
||||
reg = <0x09060000 0x7ff>, <0x9061008 0x20>;
|
||||
reg-names = "mmc", "top-mmc-delay";
|
||||
interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "mmcirq";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_mmc0>;
|
||||
clock-names = "mmc", "icn";
|
||||
clocks = <&clk_s_c0_flexgen CLK_MMC_0>,
|
||||
<&clk_s_c0_flexgen CLK_RX_ICN_HVA>;
|
||||
bus-width = <8>;
|
||||
};
|
||||
...
|
||||
@@ -0,0 +1,60 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/mmc/ti,omap2420-mmc.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Texas Instruments MMC host controller for OMAP1 and 2420
|
||||
|
||||
maintainers:
|
||||
- Eduard Bostina <egbostina@gmail.com>
|
||||
|
||||
description: |
|
||||
The MMC Host Controller on TI OMAP1 and 2420 family provides
|
||||
an interface for MMC, SD, and SDIO types of memory cards.
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/mmc/mmc-controller.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: ti,omap2420-mmc
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
ti,hwmods:
|
||||
description: |
|
||||
Name of the hwmod associated to the MMC controller. Must be
|
||||
"msdi<n>" where n is the controller instance starting from 1.
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
pattern: "^msdi([1-9]|[1-9][0-9]+)$"
|
||||
|
||||
dmas:
|
||||
maxItems: 2
|
||||
|
||||
dma-names:
|
||||
items:
|
||||
- const: tx
|
||||
- const: rx
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
mmc@4809c000 {
|
||||
compatible = "ti,omap2420-mmc";
|
||||
ti,hwmods = "msdi1";
|
||||
reg = <0x4809c000 0x80>;
|
||||
interrupts = <83>;
|
||||
dmas = <&sdma 61 &sdma 62>;
|
||||
dma-names = "tx", "rx";
|
||||
};
|
||||
@@ -1,26 +0,0 @@
|
||||
* TI MMC host controller for OMAP1 and 2420
|
||||
|
||||
The MMC Host Controller on TI OMAP1 and 2420 family provides
|
||||
an interface for MMC, SD, and SDIO types of memory cards.
|
||||
|
||||
This file documents differences between the core properties described
|
||||
by mmc.txt and the properties used by the omap mmc driver.
|
||||
|
||||
Note that this driver will not work with omap2430 or later omaps,
|
||||
please see the omap hsmmc driver for the current omaps.
|
||||
|
||||
Required properties:
|
||||
- compatible: Must be "ti,omap2420-mmc", for OMAP2420 controllers
|
||||
- ti,hwmods: For 2420, must be "msdi<n>", where n is controller
|
||||
instance starting 1
|
||||
|
||||
Examples:
|
||||
|
||||
msdi1: mmc@4809c000 {
|
||||
compatible = "ti,omap2420-mmc";
|
||||
ti,hwmods = "msdi1";
|
||||
reg = <0x4809c000 0x80>;
|
||||
interrupts = <83>;
|
||||
dmas = <&sdma 61 &sdma 62>;
|
||||
dma-names = "tx", "rx";
|
||||
};
|
||||
@@ -27100,6 +27100,13 @@ Q: http://patchwork.linuxtv.org/project/linux-media/list/
|
||||
T: git git://linuxtv.org/mhadli/v4l-dvb-davinci_devices.git
|
||||
F: drivers/media/platform/ti/am437x/
|
||||
|
||||
TI AM654 SDHCI DRIVER
|
||||
M: Judith Mendez <jm@ti.com>
|
||||
L: linux-mmc@vger.kernel.org
|
||||
S: Supported
|
||||
F: Documentation/devicetree/bindings/mmc/sdhci-am654.yaml
|
||||
F: drivers/mmc/host/sdhci_am654.c
|
||||
|
||||
TI BANDGAP AND THERMAL DRIVER
|
||||
M: Eduardo Valentin <edubezval@gmail.com>
|
||||
M: Keerthy <j-keerthy@ti.com>
|
||||
|
||||
@@ -596,7 +596,7 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
mmc0: sdhci@9060000 {
|
||||
mmc0: mmc@9060000 {
|
||||
compatible = "st,sdhci-stih407", "st,sdhci";
|
||||
status = "disabled";
|
||||
reg = <0x09060000 0x7ff>, <0x9061008 0x20>;
|
||||
@@ -611,7 +611,7 @@
|
||||
bus-width = <8>;
|
||||
};
|
||||
|
||||
mmc1: sdhci@9080000 {
|
||||
mmc1: mmc@9080000 {
|
||||
compatible = "st,sdhci-stih407", "st,sdhci";
|
||||
status = "disabled";
|
||||
reg = <0x09080000 0x7ff>;
|
||||
|
||||
@@ -141,14 +141,14 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
mmc0: sdhci@9060000 {
|
||||
mmc0: mmc@9060000 {
|
||||
pinctrl-0 = <&pinctrl_sd0>;
|
||||
bus-width = <4>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
/* high speed expansion connector */
|
||||
mmc1: sdhci@9080000 {
|
||||
mmc1: mmc@9080000 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
||||
@@ -82,11 +82,11 @@
|
||||
st,i2c-min-sda-pulse-width-us = <5>;
|
||||
};
|
||||
|
||||
mmc1: sdhci@9080000 {
|
||||
mmc1: mmc@9080000 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
mmc0: sdhci@9060000 {
|
||||
mmc0: mmc@9060000 {
|
||||
status = "okay";
|
||||
max-frequency = <200000000>;
|
||||
sd-uhs-sdr50;
|
||||
|
||||
@@ -136,7 +136,7 @@
|
||||
phy-names = "usb";
|
||||
};
|
||||
|
||||
mmc0: sdhci@9060000 {
|
||||
mmc0: mmc@9060000 {
|
||||
assigned-clocks = <&clk_s_c0_flexgen CLK_MMC_0>;
|
||||
assigned-clock-parents = <&clk_s_c0_pll1 0>;
|
||||
assigned-clock-rates = <200000000>;
|
||||
|
||||
@@ -312,6 +312,9 @@ int rtsx_usb_get_card_status(struct rtsx_ucr *ucr, u16 *status)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ucr->card_status_cache = *status;
|
||||
ucr->card_status_valid = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rtsx_usb_get_card_status);
|
||||
@@ -623,6 +626,7 @@ static int rtsx_usb_probe(struct usb_interface *intf,
|
||||
{
|
||||
struct usb_device *usb_dev = interface_to_usbdev(intf);
|
||||
struct rtsx_ucr *ucr;
|
||||
u16 status;
|
||||
int ret;
|
||||
|
||||
dev_dbg(&intf->dev,
|
||||
@@ -659,6 +663,9 @@ static int rtsx_usb_probe(struct usb_interface *intf,
|
||||
if (ret)
|
||||
goto out_init_fail;
|
||||
|
||||
/* Prime cached status for runtime autosuspend decisions. */
|
||||
rtsx_usb_get_card_status(ucr, &status);
|
||||
|
||||
/* initialize USB SG transfer timer */
|
||||
timer_setup(&ucr->sg_timer, rtsx_usb_sg_timed_out, 0);
|
||||
|
||||
@@ -713,22 +720,29 @@ static int rtsx_usb_suspend(struct usb_interface *intf, pm_message_t message)
|
||||
struct rtsx_ucr *ucr =
|
||||
(struct rtsx_ucr *)usb_get_intfdata(intf);
|
||||
u16 val = 0;
|
||||
bool valid = false;
|
||||
|
||||
dev_dbg(&intf->dev, "%s called with pm message 0x%04x\n",
|
||||
__func__, message.event);
|
||||
|
||||
if (PMSG_IS_AUTO(message)) {
|
||||
if (mutex_trylock(&ucr->dev_mutex)) {
|
||||
rtsx_usb_get_card_status(ucr, &val);
|
||||
valid = ucr->card_status_valid;
|
||||
if (valid)
|
||||
val = ucr->card_status_cache;
|
||||
mutex_unlock(&ucr->dev_mutex);
|
||||
|
||||
/* Defer the autosuspend if card exists */
|
||||
if (val & (SD_CD | MS_CD)) {
|
||||
/*
|
||||
* Do not issue USB commands from runtime autosuspend.
|
||||
* Raw SD_CD is not authoritative on tray-based readers,
|
||||
* while a real SD card is protected by the SD/MMC child
|
||||
* runtime-PM reference once the card is powered. Keep
|
||||
* the historical Memory Stick autosuspend deferral when
|
||||
* the cached status says MS media is present.
|
||||
*/
|
||||
if (valid && (val & MS_CD)) {
|
||||
device_for_each_child(&intf->dev, NULL, rtsx_usb_resume_child);
|
||||
return -EAGAIN;
|
||||
} else {
|
||||
/* if the card does not exists, clear OCP status */
|
||||
rtsx_usb_write_register(ucr, OCPCTL, MS_OCP_CLEAR, MS_OCP_CLEAR);
|
||||
}
|
||||
} else {
|
||||
/* There is an ongoing operation*/
|
||||
|
||||
@@ -3337,6 +3337,11 @@ static int __init mmc_blk_init(void)
|
||||
{
|
||||
int res;
|
||||
|
||||
if (perdev_minors <= 0) {
|
||||
pr_err("mmcblk: invalid minors per device: %d\n", perdev_minors);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
res = bus_register(&mmc_rpmb_bus_type);
|
||||
if (res < 0) {
|
||||
pr_err("mmcblk: could not register RPMB bus type\n");
|
||||
|
||||
@@ -1379,15 +1379,10 @@ out:
|
||||
|
||||
static int sd_enable_cache(struct mmc_card *card)
|
||||
{
|
||||
u8 *reg_buf;
|
||||
int err;
|
||||
|
||||
card->ext_perf.feature_enabled &= ~SD_EXT_PERF_CACHE;
|
||||
|
||||
reg_buf = kzalloc(512, GFP_KERNEL);
|
||||
if (!reg_buf)
|
||||
return -ENOMEM;
|
||||
|
||||
/*
|
||||
* Set Cache Enable at bit 0 in the performance enhancement register at
|
||||
* 260 bytes offset.
|
||||
@@ -1397,7 +1392,7 @@ static int sd_enable_cache(struct mmc_card *card)
|
||||
if (err) {
|
||||
pr_warn("%s: error %d writing Cache Enable bit\n",
|
||||
mmc_hostname(card->host), err);
|
||||
goto out;
|
||||
return err;
|
||||
}
|
||||
|
||||
err = mmc_poll_for_busy(card, SD_WRITE_EXTR_SINGLE_TIMEOUT_MS, false,
|
||||
@@ -1405,8 +1400,6 @@ static int sd_enable_cache(struct mmc_card *card)
|
||||
if (!err)
|
||||
card->ext_perf.feature_enabled |= SD_EXT_PERF_CACHE;
|
||||
|
||||
out:
|
||||
kfree(reg_buf);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
@@ -1103,8 +1103,7 @@ static int alcor_pci_sdmmc_drv_probe(struct platform_device *pdev)
|
||||
alcor_irq, alcor_irq_thread, IRQF_SHARED,
|
||||
DRV_NAME_ALCOR_PCI_SDMMC, host);
|
||||
if (ret)
|
||||
return dev_err_probe(&pdev->dev, ret,
|
||||
"Failed to get irq for data line\n");
|
||||
return ret;
|
||||
|
||||
mutex_init(&host->cmd_mutex);
|
||||
INIT_DELAYED_WORK(&host->timeout_work, alcor_timeout_timer);
|
||||
|
||||
+19
-18
@@ -188,7 +188,7 @@ struct bcm2835_host {
|
||||
u32 drain_words;
|
||||
struct page *drain_page;
|
||||
u32 drain_offset;
|
||||
bool use_dma;
|
||||
struct device *dma_dev;
|
||||
};
|
||||
|
||||
static void bcm2835_dumpcmd(struct bcm2835_host *host, struct mmc_command *cmd,
|
||||
@@ -494,8 +494,7 @@ void bcm2835_prepare_dma(struct bcm2835_host *host, struct mmc_data *data)
|
||||
&host->dma_cfg_rx :
|
||||
&host->dma_cfg_tx);
|
||||
|
||||
sg_len = dma_map_sg(dma_chan->device->dev, data->sg, data->sg_len,
|
||||
dir_data);
|
||||
sg_len = dma_map_sg(host->dma_dev, data->sg, data->sg_len, dir_data);
|
||||
if (!sg_len)
|
||||
return;
|
||||
|
||||
@@ -503,8 +502,7 @@ void bcm2835_prepare_dma(struct bcm2835_host *host, struct mmc_data *data)
|
||||
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
|
||||
|
||||
if (!desc) {
|
||||
dma_unmap_sg(dma_chan->device->dev, data->sg, data->sg_len,
|
||||
dir_data);
|
||||
dma_unmap_sg(host->dma_dev, data->sg, data->sg_len, dir_data);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1057,7 +1055,7 @@ static void bcm2835_dma_complete_work(struct work_struct *work)
|
||||
data = host->data;
|
||||
|
||||
if (host->dma_chan) {
|
||||
dma_unmap_sg(host->dma_chan->device->dev,
|
||||
dma_unmap_sg(host->dma_dev,
|
||||
data->sg, data->sg_len,
|
||||
host->dma_dir);
|
||||
|
||||
@@ -1201,7 +1199,7 @@ static void bcm2835_request(struct mmc_host *mmc, struct mmc_request *mrq)
|
||||
return;
|
||||
}
|
||||
|
||||
if (host->use_dma && mrq->data && (mrq->data->blocks > PIO_THRESHOLD))
|
||||
if (host->dma_dev && mrq->data && (mrq->data->blocks > PIO_THRESHOLD))
|
||||
bcm2835_prepare_dma(host, mrq->data);
|
||||
|
||||
host->use_sbc = !!mrq->sbc && host->mrq->data &&
|
||||
@@ -1281,10 +1279,7 @@ static int bcm2835_add_host(struct bcm2835_host *host)
|
||||
|
||||
if (!host->dma_chan_rxtx) {
|
||||
dev_warn(dev, "unable to initialise DMA channel. Falling back to PIO\n");
|
||||
host->use_dma = false;
|
||||
} else {
|
||||
host->use_dma = true;
|
||||
|
||||
host->dma_cfg_tx.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
|
||||
host->dma_cfg_tx.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
|
||||
host->dma_cfg_tx.direction = DMA_MEM_TO_DEV;
|
||||
@@ -1297,15 +1292,21 @@ static int bcm2835_add_host(struct bcm2835_host *host)
|
||||
host->dma_cfg_rx.src_addr = host->phys_addr + SDDATA;
|
||||
host->dma_cfg_rx.dst_addr = 0;
|
||||
|
||||
if (dmaengine_slave_config(host->dma_chan_rxtx,
|
||||
&host->dma_cfg_tx) != 0 ||
|
||||
dmaengine_slave_config(host->dma_chan_rxtx,
|
||||
&host->dma_cfg_rx) != 0)
|
||||
host->use_dma = false;
|
||||
if (!dmaengine_slave_config(host->dma_chan_rxtx,
|
||||
&host->dma_cfg_tx) &&
|
||||
!dmaengine_slave_config(host->dma_chan_rxtx,
|
||||
&host->dma_cfg_rx)) {
|
||||
host->dma_dev =
|
||||
dmaengine_get_dma_device(host->dma_chan_rxtx);
|
||||
}
|
||||
}
|
||||
|
||||
mmc->max_segs = 128;
|
||||
mmc->max_req_size = min_t(size_t, 524288, dma_max_mapping_size(dev));
|
||||
mmc->max_req_size = 524288;
|
||||
if (host->dma_dev) {
|
||||
mmc->max_req_size = min_t(size_t, mmc->max_req_size,
|
||||
dma_max_mapping_size(host->dma_dev));
|
||||
}
|
||||
mmc->max_seg_size = mmc->max_req_size;
|
||||
mmc->max_blk_size = 1024;
|
||||
mmc->max_blk_count = 65535;
|
||||
@@ -1336,10 +1337,10 @@ static int bcm2835_add_host(struct bcm2835_host *host)
|
||||
}
|
||||
|
||||
pio_limit_string[0] = '\0';
|
||||
if (host->use_dma && (PIO_THRESHOLD > 0))
|
||||
if (host->dma_dev && (PIO_THRESHOLD > 0))
|
||||
sprintf(pio_limit_string, " (>%d)", PIO_THRESHOLD);
|
||||
dev_info(dev, "loaded - DMA %s%s\n",
|
||||
host->use_dma ? "enabled" : "disabled", pio_limit_string);
|
||||
host->dma_dev ? "enabled" : "disabled", pio_limit_string);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -240,21 +240,15 @@ static int octeon_mmc_probe(struct platform_device *pdev)
|
||||
ret = devm_request_irq(&pdev->dev, mmc_irq[i],
|
||||
cvm_mmc_interrupt,
|
||||
0, cvm_mmc_irq_names[i], host);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "Error: devm_request_irq %d\n",
|
||||
mmc_irq[i]);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ret = devm_request_irq(&pdev->dev, mmc_irq[0],
|
||||
cvm_mmc_interrupt, 0, KBUILD_MODNAME,
|
||||
host);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "Error: devm_request_irq %d\n",
|
||||
mmc_irq[0]);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
host->global_pwr_gpiod = devm_gpiod_get_optional(&pdev->dev,
|
||||
|
||||
@@ -484,11 +484,11 @@ void cqhci_set_tran_desc(u8 *desc, dma_addr_t addr, int len, bool end,
|
||||
{
|
||||
__le32 *attr = (__le32 __force *)desc;
|
||||
|
||||
*attr = (CQHCI_VALID(1) |
|
||||
CQHCI_END(end ? 1 : 0) |
|
||||
CQHCI_INT(0) |
|
||||
CQHCI_ACT(0x4) |
|
||||
CQHCI_DAT_LENGTH(len));
|
||||
*attr = cpu_to_le32((CQHCI_VALID(1) |
|
||||
CQHCI_END(end ? 1 : 0) |
|
||||
CQHCI_INT(0) |
|
||||
CQHCI_ACT(0x4) |
|
||||
CQHCI_DAT_LENGTH(len)));
|
||||
|
||||
if (dma64) {
|
||||
__le64 *dataddr = (__le64 __force *)(desc + 4);
|
||||
@@ -542,7 +542,7 @@ static int cqhci_prep_tran_desc(struct mmc_request *mrq,
|
||||
static void cqhci_prep_dcmd_desc(struct mmc_host *mmc,
|
||||
struct mmc_request *mrq)
|
||||
{
|
||||
u64 *task_desc = NULL;
|
||||
__le64 *task_desc = NULL;
|
||||
u64 data = 0;
|
||||
u8 resp_type;
|
||||
u8 *desc;
|
||||
@@ -574,7 +574,7 @@ static void cqhci_prep_dcmd_desc(struct mmc_host *mmc,
|
||||
CQHCI_CMD_TIMING(timing) | CQHCI_RESP_TYPE(resp_type));
|
||||
if (cq_host->ops->update_dcmd_desc)
|
||||
cq_host->ops->update_dcmd_desc(mmc, mrq, &data);
|
||||
*task_desc |= data;
|
||||
*task_desc |= cpu_to_le64(data);
|
||||
desc = (u8 *)task_desc;
|
||||
pr_debug("%s: cqhci: dcmd: cmd: %d timing: %d resp: %d\n",
|
||||
mmc_hostname(mmc), mrq->cmd->opcode, timing, resp_type);
|
||||
@@ -819,8 +819,7 @@ static void cqhci_finish_mrq(struct mmc_host *mmc, unsigned int tag)
|
||||
mmc_cqe_request_done(mmc, mrq);
|
||||
}
|
||||
|
||||
irqreturn_t cqhci_irq(struct mmc_host *mmc, u32 intmask, int cmd_error,
|
||||
int data_error)
|
||||
irqreturn_t cqhci_irq(struct mmc_host *mmc, int cmd_error, int data_error)
|
||||
{
|
||||
u32 status;
|
||||
unsigned long tag = 0, comp_status;
|
||||
|
||||
@@ -315,8 +315,7 @@ static inline u32 cqhci_readl(struct cqhci_host *host, int reg)
|
||||
|
||||
struct platform_device;
|
||||
|
||||
irqreturn_t cqhci_irq(struct mmc_host *mmc, u32 intmask, int cmd_error,
|
||||
int data_error);
|
||||
irqreturn_t cqhci_irq(struct mmc_host *mmc, int cmd_error, int data_error);
|
||||
int cqhci_init(struct cqhci_host *cq_host, struct mmc_host *mmc, bool dma64);
|
||||
struct cqhci_host *cqhci_pltfm_init(struct platform_device *pdev);
|
||||
int cqhci_deactivate(struct mmc_host *mmc);
|
||||
|
||||
@@ -11,6 +11,5 @@
|
||||
extern int dw_mci_pltfm_register(struct platform_device *pdev,
|
||||
const struct dw_mci_drv_data *drv_data);
|
||||
extern void dw_mci_pltfm_remove(struct platform_device *pdev);
|
||||
extern const struct dev_pm_ops dw_mci_pmops;
|
||||
|
||||
#endif /* _DW_MMC_PLTFM_H_ */
|
||||
|
||||
@@ -2057,6 +2057,7 @@ static void dw_mci_work_func(struct work_struct *t)
|
||||
}
|
||||
|
||||
dw_mci_stop_fault_timer(host);
|
||||
dw_mci_stop_dma(host);
|
||||
host->data = NULL;
|
||||
set_bit(EVENT_DATA_COMPLETE, &host->completed_events);
|
||||
err = dw_mci_data_complete(host, data);
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/workqueue.h>
|
||||
|
||||
extern const struct dev_pm_ops dw_mci_pmops;
|
||||
|
||||
enum dw_mci_state {
|
||||
STATE_IDLE = 0,
|
||||
STATE_SENDING_CMD,
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#define LITEX_PHY_CLOCKERDIV 0x04
|
||||
#define LITEX_PHY_INITIALIZE 0x08
|
||||
#define LITEX_PHY_WRITESTATUS 0x0C
|
||||
#define LITEX_PHY_SETTINGS 0x18
|
||||
#define LITEX_CORE_CMDARG 0x00
|
||||
#define LITEX_CORE_CMDCMD 0x04
|
||||
#define LITEX_CORE_CMDSND 0x08
|
||||
@@ -71,6 +72,10 @@
|
||||
#define SD_INIT_DELAY_US 1000
|
||||
#define SD_INIT_CLK_HZ 400000
|
||||
|
||||
#define SD_PHY_SPEED_1X 0
|
||||
#define SD_PHY_SPEED_4X 1
|
||||
#define SD_PHY_SPEED_8X 2
|
||||
|
||||
#define SDIRQ_CARD_DETECT 1
|
||||
#define SDIRQ_SD_TO_MEM_DONE 2
|
||||
#define SDIRQ_MEM_TO_SD_DONE 4
|
||||
@@ -95,11 +100,9 @@ struct litex_mmc_host {
|
||||
unsigned int ref_clk;
|
||||
unsigned int sd_clk;
|
||||
|
||||
u32 resp[4];
|
||||
u16 rca;
|
||||
u8 width;
|
||||
|
||||
bool is_bus_width_set;
|
||||
bool app_cmd;
|
||||
u32 resp[4];
|
||||
};
|
||||
|
||||
static int litex_mmc_sdcard_wait_done(void __iomem *reg, struct device *dev)
|
||||
@@ -164,11 +167,6 @@ static int litex_mmc_send_cmd(struct litex_mmc_host *host,
|
||||
host->sdcore + LITEX_CORE_CMDRSP, 0x10);
|
||||
}
|
||||
|
||||
if (!host->app_cmd && cmd == SD_SEND_RELATIVE_ADDR)
|
||||
host->rca = (host->resp[3] >> 16);
|
||||
|
||||
host->app_cmd = (cmd == MMC_APP_CMD);
|
||||
|
||||
if (transfer == SD_CTL_DATA_XFER_NONE)
|
||||
return ret; /* OK from prior litex_mmc_sdcard_wait_done() */
|
||||
|
||||
@@ -190,51 +188,6 @@ static int litex_mmc_send_cmd(struct litex_mmc_host *host,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int litex_mmc_send_app_cmd(struct litex_mmc_host *host)
|
||||
{
|
||||
return litex_mmc_send_cmd(host, MMC_APP_CMD, host->rca << 16,
|
||||
SD_CTL_RESP_SHORT, SD_CTL_DATA_XFER_NONE);
|
||||
}
|
||||
|
||||
static int litex_mmc_send_set_bus_w_cmd(struct litex_mmc_host *host, u32 width)
|
||||
{
|
||||
return litex_mmc_send_cmd(host, SD_APP_SET_BUS_WIDTH, width,
|
||||
SD_CTL_RESP_SHORT, SD_CTL_DATA_XFER_NONE);
|
||||
}
|
||||
|
||||
static int litex_mmc_set_bus_width(struct litex_mmc_host *host)
|
||||
{
|
||||
bool app_cmd_sent;
|
||||
int ret;
|
||||
|
||||
if (host->is_bus_width_set)
|
||||
return 0;
|
||||
|
||||
/* Ensure 'app_cmd' precedes 'app_set_bus_width_cmd' */
|
||||
app_cmd_sent = host->app_cmd; /* was preceding command app_cmd? */
|
||||
if (!app_cmd_sent) {
|
||||
ret = litex_mmc_send_app_cmd(host);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* LiteSDCard only supports 4-bit bus width */
|
||||
ret = litex_mmc_send_set_bus_w_cmd(host, MMC_BUS_WIDTH_4);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Re-send 'app_cmd' if necessary */
|
||||
if (app_cmd_sent) {
|
||||
ret = litex_mmc_send_app_cmd(host);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
host->is_bus_width_set = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int litex_mmc_get_cd(struct mmc_host *mmc)
|
||||
{
|
||||
struct litex_mmc_host *host = mmc_priv(mmc);
|
||||
@@ -247,9 +200,6 @@ static int litex_mmc_get_cd(struct mmc_host *mmc)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Ensure bus width will be set (again) upon card (re)insertion */
|
||||
host->is_bus_width_set = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -365,39 +315,19 @@ static void litex_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
|
||||
litex_mmc_response_len(sbc),
|
||||
SD_CTL_DATA_XFER_NONE);
|
||||
if (sbc->error) {
|
||||
host->is_bus_width_set = false;
|
||||
mmc_request_done(mmc, mrq);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (data) {
|
||||
/*
|
||||
* LiteSDCard only supports 4-bit bus width; therefore, we MUST
|
||||
* inject a SET_BUS_WIDTH (acmd6) before the very first data
|
||||
* transfer, earlier than when the mmc subsystem would normally
|
||||
* get around to it!
|
||||
*/
|
||||
cmd->error = litex_mmc_set_bus_width(host);
|
||||
if (cmd->error) {
|
||||
dev_err(dev, "Can't set bus width!\n");
|
||||
mmc_request_done(mmc, mrq);
|
||||
return;
|
||||
}
|
||||
|
||||
if (data)
|
||||
litex_mmc_do_dma(host, data, &len, &direct, &transfer);
|
||||
}
|
||||
|
||||
do {
|
||||
cmd->error = litex_mmc_send_cmd(host, cmd->opcode, cmd->arg,
|
||||
response_len, transfer);
|
||||
} while (cmd->error && retries-- > 0);
|
||||
|
||||
if (cmd->error) {
|
||||
/* Card may be gone; don't assume bus width is still set */
|
||||
host->is_bus_width_set = false;
|
||||
}
|
||||
|
||||
if (response_len == SD_CTL_RESP_SHORT) {
|
||||
/* Pull short response fields from appropriate host registers */
|
||||
cmd->resp[0] = host->resp[3];
|
||||
@@ -410,13 +340,10 @@ static void litex_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
|
||||
}
|
||||
|
||||
/* Send stop-transmission command if required */
|
||||
if (stop && (cmd->error || !sbc)) {
|
||||
if (stop && (cmd->error || !sbc))
|
||||
stop->error = litex_mmc_send_cmd(host, stop->opcode, stop->arg,
|
||||
litex_mmc_response_len(stop),
|
||||
SD_CTL_DATA_XFER_NONE);
|
||||
if (stop->error)
|
||||
host->is_bus_width_set = false;
|
||||
}
|
||||
|
||||
if (data) {
|
||||
dma_unmap_sg(dev, data->sg, data->sg_len,
|
||||
@@ -450,6 +377,24 @@ static void litex_mmc_setclk(struct litex_mmc_host *host, unsigned int freq)
|
||||
static void litex_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
|
||||
{
|
||||
struct litex_mmc_host *host = mmc_priv(mmc);
|
||||
unsigned int bus_width = SD_PHY_SPEED_1X;
|
||||
|
||||
switch (ios->bus_width) {
|
||||
case MMC_BUS_WIDTH_1:
|
||||
bus_width = SD_PHY_SPEED_1X;
|
||||
break;
|
||||
case MMC_BUS_WIDTH_4:
|
||||
bus_width = SD_PHY_SPEED_4X;
|
||||
break;
|
||||
case MMC_BUS_WIDTH_8:
|
||||
bus_width = SD_PHY_SPEED_8X;
|
||||
break;
|
||||
}
|
||||
|
||||
if (host->width != ios->bus_width) {
|
||||
litex_write8(host->sdphy + LITEX_PHY_SETTINGS, bus_width);
|
||||
host->width = ios->bus_width;
|
||||
}
|
||||
|
||||
/*
|
||||
* The SD specification requires at least 74 idle clocks before CMD0.
|
||||
@@ -462,13 +407,6 @@ static void litex_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* NOTE: Ignore any ios->bus_width updates; they occur right after
|
||||
* the mmc core sends its own acmd6 bus-width change notification,
|
||||
* which is redundant since we snoop on the command flow and inject
|
||||
* an early acmd6 before the first data transfer command is sent!
|
||||
*/
|
||||
|
||||
/* Update sd_clk */
|
||||
if (ios->clock != host->sd_clk)
|
||||
litex_mmc_setclk(host, ios->clock);
|
||||
@@ -546,14 +484,7 @@ static int litex_mmc_probe(struct platform_device *pdev)
|
||||
return dev_err_probe(dev, PTR_ERR(clk), "can't get clock\n");
|
||||
host->ref_clk = clk_get_rate(clk);
|
||||
host->sd_clk = 0;
|
||||
|
||||
/*
|
||||
* LiteSDCard only supports 4-bit bus width; therefore, we MUST inject
|
||||
* a SET_BUS_WIDTH (acmd6) before the very first data transfer, earlier
|
||||
* than when the mmc subsystem would normally get around to it!
|
||||
*/
|
||||
host->is_bus_width_set = false;
|
||||
host->app_cmd = false;
|
||||
host->width = MMC_BUS_WIDTH_1;
|
||||
|
||||
/* LiteSDCard can support 64-bit DMA addressing */
|
||||
ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
|
||||
@@ -586,6 +517,9 @@ static int litex_mmc_probe(struct platform_device *pdev)
|
||||
litex_write8(host->sdreader + LITEX_BLK2MEM_ENA, 0);
|
||||
litex_write8(host->sdwriter + LITEX_MEM2BLK_ENA, 0);
|
||||
|
||||
/* Ensure the litex is at bus width x1 */
|
||||
litex_write8(host->sdphy + LITEX_PHY_SETTINGS, SD_PHY_SPEED_1X);
|
||||
|
||||
init_completion(&host->cmd_done);
|
||||
ret = litex_mmc_irq_init(pdev, host);
|
||||
if (ret)
|
||||
@@ -610,9 +544,8 @@ static int litex_mmc_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Force 4-bit bus_width (only width supported by hardware) */
|
||||
/* Only drop 8-bit bus_width support */
|
||||
mmc->caps &= ~MMC_CAP_8_BIT_DATA;
|
||||
mmc->caps |= MMC_CAP_4_BIT_DATA;
|
||||
|
||||
/* Set default capabilities */
|
||||
mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY |
|
||||
|
||||
@@ -683,11 +683,8 @@ static int meson_mx_mmc_probe(struct platform_device *pdev)
|
||||
meson_mx_mmc_irq,
|
||||
meson_mx_mmc_irq_thread, IRQF_ONESHOT,
|
||||
NULL, host);
|
||||
if (ret) {
|
||||
dev_err_probe(host->controller_dev, ret,
|
||||
"Failed to request IRQ\n");
|
||||
if (ret)
|
||||
goto error_unregister_slot_pdev;
|
||||
}
|
||||
|
||||
core_clk = devm_clk_get_enabled(host->controller_dev, "core");
|
||||
if (IS_ERR(core_clk)) {
|
||||
|
||||
@@ -26,8 +26,6 @@
|
||||
#include <linux/mmc/sd.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/of_dma.h>
|
||||
@@ -264,6 +262,7 @@ static void moxart_transfer_dma(struct mmc_data *data, struct moxart_host *host)
|
||||
u32 len, dir_slave;
|
||||
struct dma_async_tx_descriptor *desc = NULL;
|
||||
struct dma_chan *dma_chan;
|
||||
long timeout;
|
||||
|
||||
if (host->data_len == data->bytes_xfered)
|
||||
return;
|
||||
@@ -296,11 +295,17 @@ static void moxart_transfer_dma(struct mmc_data *data, struct moxart_host *host)
|
||||
dma_async_issue_pending(dma_chan);
|
||||
}
|
||||
|
||||
wait_for_completion_interruptible_timeout(&host->dma_complete,
|
||||
host->timeout);
|
||||
timeout = wait_for_completion_interruptible_timeout(&host->dma_complete,
|
||||
host->timeout);
|
||||
if (timeout <= 0) {
|
||||
dmaengine_terminate_sync(dma_chan);
|
||||
data->error = timeout ?: -ETIMEDOUT;
|
||||
goto unmap;
|
||||
}
|
||||
|
||||
data->bytes_xfered = host->data_len;
|
||||
|
||||
unmap:
|
||||
dma_unmap_sg(dma_chan->device->dev,
|
||||
data->sg, data->sg_len,
|
||||
mmc_get_dma_dir(data));
|
||||
@@ -548,8 +553,7 @@ static const struct mmc_host_ops moxart_ops = {
|
||||
static int moxart_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *node = dev->of_node;
|
||||
struct resource res_mmc;
|
||||
struct resource *res_mmc;
|
||||
struct mmc_host *mmc;
|
||||
struct moxart_host *host = NULL;
|
||||
struct dma_slave_config cfg;
|
||||
@@ -558,30 +562,24 @@ static int moxart_probe(struct platform_device *pdev)
|
||||
int irq, ret;
|
||||
u32 i;
|
||||
|
||||
reg_mmc = devm_platform_get_and_ioremap_resource(pdev, 0, &res_mmc);
|
||||
if (IS_ERR(reg_mmc))
|
||||
return PTR_ERR(reg_mmc);
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0)
|
||||
return irq;
|
||||
|
||||
mmc = devm_mmc_alloc_host(dev, sizeof(*host));
|
||||
if (!mmc) {
|
||||
dev_err(dev, "devm_mmc_alloc_host failed\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ret = of_address_to_resource(node, 0, &res_mmc);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret,
|
||||
"of_address_to_resource failed\n");
|
||||
|
||||
irq = irq_of_parse_and_map(node, 0);
|
||||
if (irq <= 0)
|
||||
return dev_err_probe(dev, -EINVAL,
|
||||
"irq_of_parse_and_map failed\n");
|
||||
|
||||
clk = devm_clk_get(dev, NULL);
|
||||
if (IS_ERR(clk))
|
||||
return PTR_ERR(clk);
|
||||
|
||||
reg_mmc = devm_ioremap_resource(dev, &res_mmc);
|
||||
if (IS_ERR(reg_mmc))
|
||||
return PTR_ERR(reg_mmc);
|
||||
|
||||
ret = mmc_of_parse(mmc);
|
||||
if (ret)
|
||||
return ret;
|
||||
@@ -589,7 +587,7 @@ static int moxart_probe(struct platform_device *pdev)
|
||||
host = mmc_priv(mmc);
|
||||
host->mmc = mmc;
|
||||
host->base = reg_mmc;
|
||||
host->reg_phys = res_mmc.start;
|
||||
host->reg_phys = res_mmc->start;
|
||||
host->timeout = msecs_to_jiffies(1000);
|
||||
host->sysclk = clk_get_rate(clk);
|
||||
host->fifo_width = readl(host->base + REG_FEATURE) << 2;
|
||||
|
||||
@@ -1805,7 +1805,7 @@ static irqreturn_t msdc_cmdq_irq(struct msdc_host *host, u32 intsts)
|
||||
cmd_err, dat_err, intsts);
|
||||
}
|
||||
|
||||
return cqhci_irq(mmc, 0, cmd_err, dat_err);
|
||||
return cqhci_irq(mmc, cmd_err, dat_err);
|
||||
}
|
||||
|
||||
static irqreturn_t msdc_irq(int irq, void *dev_id)
|
||||
|
||||
@@ -764,10 +764,8 @@ static int mvsd_probe(struct platform_device *pdev)
|
||||
mvsd_power_down(host);
|
||||
|
||||
ret = devm_request_irq(&pdev->dev, irq, mvsd_irq, 0, DRIVER_NAME, host);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "cannot assign irq %d\n", irq);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
timer_setup(&host->timer, mvsd_timeout_timer, 0);
|
||||
platform_set_drvdata(pdev, mmc);
|
||||
|
||||
@@ -1764,7 +1764,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
|
||||
struct mmc_host *mmc;
|
||||
struct omap_hsmmc_host *host = NULL;
|
||||
struct resource *res;
|
||||
int ret, irq;
|
||||
int ret, irq, wake_irq;
|
||||
const struct of_device_id *match;
|
||||
const struct omap_mmc_of_data *data;
|
||||
void __iomem *base;
|
||||
@@ -1792,6 +1792,11 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
|
||||
if (irq < 0)
|
||||
return irq;
|
||||
|
||||
wake_irq = platform_get_irq_optional(pdev, 1);
|
||||
if (wake_irq == -EPROBE_DEFER)
|
||||
return wake_irq;
|
||||
wake_irq = max(wake_irq, 0);
|
||||
|
||||
base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
@@ -1811,6 +1816,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
|
||||
host->use_dma = 1;
|
||||
host->dma_ch = -1;
|
||||
host->irq = irq;
|
||||
host->wake_irq = wake_irq;
|
||||
host->mapbase = res->start + pdata->reg_offset;
|
||||
host->base = base + pdata->reg_offset;
|
||||
host->power_mode = MMC_POWER_OFF;
|
||||
@@ -1820,9 +1826,6 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
|
||||
|
||||
platform_set_drvdata(pdev, host);
|
||||
|
||||
if (pdev->dev.of_node)
|
||||
host->wake_irq = irq_of_parse_and_map(pdev->dev.of_node, 1);
|
||||
|
||||
mmc->ops = &omap_hsmmc_ops;
|
||||
|
||||
mmc->f_min = OMAP_MMC_MIN_CLOCK;
|
||||
@@ -1915,10 +1918,8 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
|
||||
/* Request IRQ for MMC operations */
|
||||
ret = devm_request_irq(&pdev->dev, host->irq, omap_hsmmc_irq, 0,
|
||||
mmc_hostname(mmc), host);
|
||||
if (ret) {
|
||||
dev_err(mmc_dev(host->mmc), "Unable to grab HSMMC IRQ\n");
|
||||
if (ret)
|
||||
goto err_irq;
|
||||
}
|
||||
|
||||
ret = omap_hsmmc_reg_get(host);
|
||||
if (ret)
|
||||
|
||||
@@ -635,11 +635,8 @@ static int owl_mmc_probe(struct platform_device *pdev)
|
||||
|
||||
ret = devm_request_irq(&pdev->dev, owl_host->irq, owl_irq_handler,
|
||||
0, dev_name(&pdev->dev), owl_host);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Failed to request irq %d\n",
|
||||
owl_host->irq);
|
||||
if (ret)
|
||||
goto err_release_channel;
|
||||
}
|
||||
|
||||
ret = mmc_add_host(mmc);
|
||||
if (ret) {
|
||||
|
||||
@@ -43,8 +43,7 @@
|
||||
#define NR_SG 1
|
||||
#define CLKRT_OFF (~0)
|
||||
|
||||
#define mmc_has_26MHz() (cpu_is_pxa300() || cpu_is_pxa310() \
|
||||
|| cpu_is_pxa935())
|
||||
#define mmc_has_26MHz() (cpu_is_pxa300() || cpu_is_pxa310())
|
||||
|
||||
struct pxamci_host {
|
||||
struct mmc_host *mmc;
|
||||
|
||||
@@ -44,6 +44,7 @@ struct rtsx_usb_sdmmc {
|
||||
bool double_clk;
|
||||
bool host_removal;
|
||||
bool card_exist;
|
||||
bool suppress_cd;
|
||||
bool initial_mode;
|
||||
bool ddr_mode;
|
||||
|
||||
@@ -774,6 +775,7 @@ static int sdmmc_get_cd(struct mmc_host *mmc)
|
||||
struct rtsx_ucr *ucr = host->ucr;
|
||||
int err;
|
||||
u16 val;
|
||||
bool cd;
|
||||
|
||||
if (host->host_removal)
|
||||
return -ENOMEDIUM;
|
||||
@@ -791,8 +793,14 @@ static int sdmmc_get_cd(struct mmc_host *mmc)
|
||||
|
||||
/* get OCP status */
|
||||
host->ocp_stat = (val >> 4) & 0x03;
|
||||
cd = val & SD_CD;
|
||||
|
||||
if (val & SD_CD) {
|
||||
if (!cd) {
|
||||
WRITE_ONCE(host->suppress_cd, false);
|
||||
goto no_card;
|
||||
}
|
||||
|
||||
if (!READ_ONCE(host->suppress_cd)) {
|
||||
host->card_exist = true;
|
||||
return 1;
|
||||
}
|
||||
@@ -874,6 +882,8 @@ finish_detect_card:
|
||||
* detect card when fail to update card existence state and
|
||||
* speed up card removal when retry
|
||||
*/
|
||||
if (!mmc->card && cmd->error == -ETIMEDOUT)
|
||||
WRITE_ONCE(host->suppress_cd, true);
|
||||
sdmmc_get_cd(mmc);
|
||||
dev_dbg(sdmmc_dev(host), "cmd->error = %d\n", cmd->error);
|
||||
}
|
||||
@@ -1359,6 +1369,7 @@ static void rtsx_usb_init_host(struct rtsx_usb_sdmmc *host)
|
||||
|
||||
host->power_mode = MMC_POWER_OFF;
|
||||
host->ocp_stat = 0;
|
||||
host->suppress_cd = false;
|
||||
}
|
||||
|
||||
static int rtsx_usb_sdmmc_drv_probe(struct platform_device *pdev)
|
||||
|
||||
@@ -430,7 +430,7 @@ static u32 sdhci_brcmstb_cqhci_irq(struct sdhci_host *host, u32 intmask)
|
||||
if (!sdhci_cqe_irq(host, intmask, &cmd_error, &data_error))
|
||||
return intmask;
|
||||
|
||||
cqhci_irq(host->mmc, intmask, cmd_error, data_error);
|
||||
cqhci_irq(host->mmc, cmd_error, data_error);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1513,7 +1513,7 @@ static u32 esdhc_cqhci_irq(struct sdhci_host *host, u32 intmask)
|
||||
if (!sdhci_cqe_irq(host, intmask, &cmd_error, &data_error))
|
||||
return intmask;
|
||||
|
||||
cqhci_irq(host->mmc, intmask, cmd_error, data_error);
|
||||
cqhci_irq(host->mmc, cmd_error, data_error);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ static inline void esdhc_clrset_be(struct sdhci_host *host,
|
||||
if (reg == SDHCI_HOST_CONTROL)
|
||||
val |= ESDHC_PROCTL_D3CD;
|
||||
|
||||
writel((readl(base) & ~mask) | val, base);
|
||||
mcf_write32((mcf_read32(base) & ~mask) | val, base);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -71,7 +71,7 @@ static void esdhc_mcf_writeb_be(struct sdhci_host *host, u8 val, int reg)
|
||||
if (reg == SDHCI_HOST_CONTROL) {
|
||||
u32 host_ctrl = ESDHC_DEFAULT_HOST_CONTROL;
|
||||
u8 dma_bits = (val & SDHCI_CTRL_DMA_MASK) >> 3;
|
||||
u8 tmp = readb(host->ioaddr + SDHCI_HOST_CONTROL + 1);
|
||||
u8 tmp = mcf_read8(host->ioaddr + SDHCI_HOST_CONTROL + 1);
|
||||
|
||||
tmp &= ~0x03;
|
||||
tmp |= dma_bits;
|
||||
@@ -82,12 +82,12 @@ static void esdhc_mcf_writeb_be(struct sdhci_host *host, u8 val, int reg)
|
||||
*/
|
||||
host_ctrl |= val;
|
||||
host_ctrl |= (dma_bits << 8);
|
||||
writel(host_ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
|
||||
mcf_write32(host_ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
writel((readl(base) & mask) | (val << shift), base);
|
||||
mcf_write32((mcf_read32(base) & mask) | (val << shift), base);
|
||||
}
|
||||
|
||||
static void esdhc_mcf_writew_be(struct sdhci_host *host, u16 val, int reg)
|
||||
@@ -110,24 +110,24 @@ static void esdhc_mcf_writew_be(struct sdhci_host *host, u16 val, int reg)
|
||||
* As for the fsl driver,
|
||||
* we have to set the mode in a single write here.
|
||||
*/
|
||||
writel(val << 16 | mcf_data->aside,
|
||||
mcf_write32(val << 16 | mcf_data->aside,
|
||||
host->ioaddr + SDHCI_TRANSFER_MODE);
|
||||
return;
|
||||
}
|
||||
|
||||
writel((readl(base) & mask) | (val << shift), base);
|
||||
mcf_write32((mcf_read32(base) & mask) | (val << shift), base);
|
||||
}
|
||||
|
||||
static void esdhc_mcf_writel_be(struct sdhci_host *host, u32 val, int reg)
|
||||
{
|
||||
writel(val, host->ioaddr + reg);
|
||||
mcf_write32(val, host->ioaddr + reg);
|
||||
}
|
||||
|
||||
static u8 esdhc_mcf_readb_be(struct sdhci_host *host, int reg)
|
||||
{
|
||||
if (reg == SDHCI_HOST_CONTROL) {
|
||||
u8 __iomem *base = host->ioaddr + (reg & ~3);
|
||||
u16 val = readw(base + 2);
|
||||
u16 val = mcf_read16(base + 2);
|
||||
u8 dma_bits = (val >> 5) & SDHCI_CTRL_DMA_MASK;
|
||||
u8 host_ctrl = val & 0xff;
|
||||
|
||||
@@ -137,7 +137,7 @@ static u8 esdhc_mcf_readb_be(struct sdhci_host *host, int reg)
|
||||
return host_ctrl;
|
||||
}
|
||||
|
||||
return readb(host->ioaddr + (reg ^ 0x3));
|
||||
return mcf_read8(host->ioaddr + (reg ^ 0x3));
|
||||
}
|
||||
|
||||
static u16 esdhc_mcf_readw_be(struct sdhci_host *host, int reg)
|
||||
@@ -149,14 +149,14 @@ static u16 esdhc_mcf_readw_be(struct sdhci_host *host, int reg)
|
||||
if (reg == SDHCI_HOST_VERSION)
|
||||
reg -= 2;
|
||||
|
||||
return readw(host->ioaddr + (reg ^ 0x2));
|
||||
return mcf_read16(host->ioaddr + (reg ^ 0x2));
|
||||
}
|
||||
|
||||
static u32 esdhc_mcf_readl_be(struct sdhci_host *host, int reg)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = readl(host->ioaddr + reg);
|
||||
val = mcf_read32(host->ioaddr + reg);
|
||||
|
||||
/*
|
||||
* RM (25.3.9) sd pin clock must never exceed 25Mhz.
|
||||
@@ -245,7 +245,7 @@ static void esdhc_mcf_pltfm_set_clock(struct sdhci_host *host,
|
||||
* fvco = fsys * outdvi1 + 1
|
||||
* fshdc = fvco / outdiv3 + 1
|
||||
*/
|
||||
temp = readl(pll_dr);
|
||||
temp = mcf_read32(pll_dr);
|
||||
fsys = pltfm_host->clock;
|
||||
fvco = fsys * ((temp & 0x1f) + 1);
|
||||
fesdhc = fvco / (((temp >> 10) & 0x1f) + 1);
|
||||
|
||||
@@ -2165,7 +2165,7 @@ static u32 sdhci_msm_cqe_irq(struct sdhci_host *host, u32 intmask)
|
||||
if (!sdhci_cqe_irq(host, intmask, &cmd_error, &data_error))
|
||||
return intmask;
|
||||
|
||||
cqhci_irq(host->mmc, intmask, cmd_error, data_error);
|
||||
cqhci_irq(host->mmc, cmd_error, data_error);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2864,10 +2864,8 @@ static int sdhci_msm_probe(struct platform_device *pdev)
|
||||
ret = devm_request_threaded_irq(&pdev->dev, msm_host->pwr_irq, NULL,
|
||||
sdhci_msm_pwr_irq, IRQF_ONESHOT,
|
||||
dev_name(&pdev->dev), host);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Request IRQ failed (%d)\n", ret);
|
||||
if (ret)
|
||||
goto clk_disable;
|
||||
}
|
||||
|
||||
msm_host->mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY | MMC_CAP_NEED_RSP_BUSY;
|
||||
|
||||
|
||||
@@ -555,7 +555,7 @@ static u32 sdhci_arasan_cqhci_irq(struct sdhci_host *host, u32 intmask)
|
||||
if (!sdhci_cqe_irq(host, intmask, &cmd_error, &data_error))
|
||||
return intmask;
|
||||
|
||||
cqhci_irq(host->mmc, intmask, cmd_error, data_error);
|
||||
cqhci_irq(host->mmc, cmd_error, data_error);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -624,7 +624,7 @@ static u32 dwcmshc_cqe_irq_handler(struct sdhci_host *host, u32 intmask)
|
||||
if (!sdhci_cqe_irq(host, intmask, &cmd_error, &data_error))
|
||||
return intmask;
|
||||
|
||||
cqhci_irq(host->mmc, intmask, cmd_error, data_error);
|
||||
cqhci_irq(host->mmc, cmd_error, data_error);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -2013,6 +2013,7 @@ static void dwcmshc_bf3_hw_reset(struct sdhci_host *host)
|
||||
{
|
||||
struct arm_smccc_res res = { 0 };
|
||||
|
||||
pr_debug("%s: resetting...\n", __func__);
|
||||
arm_smccc_smc(BLUEFIELD_SMC_SET_EMMC_RST_N, 0, 0, 0, 0, 0, 0, 0, &res);
|
||||
|
||||
if (res.a0)
|
||||
|
||||
@@ -290,6 +290,7 @@ static const struct of_device_id sdhci_ma35_dt_ids[] = {
|
||||
{ .compatible = "nuvoton,ma35d1-sdhci" },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, sdhci_ma35_dt_ids);
|
||||
|
||||
static struct platform_driver sdhci_ma35_driver = {
|
||||
.driver = {
|
||||
|
||||
@@ -215,7 +215,7 @@ static u32 sdhci_cqhci_irq(struct sdhci_host *host, u32 intmask)
|
||||
if (!sdhci_cqe_irq(host, intmask, &cmd_error, &data_error))
|
||||
return intmask;
|
||||
|
||||
cqhci_irq(host->mmc, intmask, cmd_error, data_error);
|
||||
cqhci_irq(host->mmc, cmd_error, data_error);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1760,7 +1760,7 @@ static u32 sdhci_gl9763e_cqhci_irq(struct sdhci_host *host, u32 intmask)
|
||||
if (!sdhci_cqe_irq(host, intmask, &cmd_error, &data_error))
|
||||
return intmask;
|
||||
|
||||
cqhci_irq(host->mmc, intmask, cmd_error, data_error);
|
||||
cqhci_irq(host->mmc, cmd_error, data_error);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1280,7 +1280,7 @@ static u32 sdhci_tegra_cqhci_irq(struct sdhci_host *host, u32 intmask)
|
||||
if (!sdhci_cqe_irq(host, intmask, &cmd_error, &data_error))
|
||||
return intmask;
|
||||
|
||||
cqhci_irq(host->mmc, intmask, cmd_error, data_error);
|
||||
cqhci_irq(host->mmc, cmd_error, data_error);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1572,7 +1572,37 @@ static const struct sdhci_tegra_soc_data soc_data_tegra234 = {
|
||||
.max_tap_delay = 111,
|
||||
};
|
||||
|
||||
static const struct sdhci_tegra_soc_data soc_data_tegra264 = {
|
||||
.pdata = &sdhci_tegra186_pdata,
|
||||
.dma_mask = DMA_BIT_MASK(39),
|
||||
.nvquirks = NVQUIRK_NEEDS_PAD_CONTROL |
|
||||
NVQUIRK_HAS_PADCALIB |
|
||||
NVQUIRK_DIS_CARD_CLK_CONFIG_TAP |
|
||||
NVQUIRK_ENABLE_SDR50 |
|
||||
NVQUIRK_ENABLE_SDR104 |
|
||||
NVQUIRK_PROGRAM_STREAMID |
|
||||
NVQUIRK_HAS_TMCLK,
|
||||
.min_tap_delay = 95,
|
||||
.max_tap_delay = 111,
|
||||
};
|
||||
|
||||
static const struct sdhci_tegra_soc_data soc_data_tegra238 = {
|
||||
.pdata = &sdhci_tegra186_pdata,
|
||||
.dma_mask = DMA_BIT_MASK(39),
|
||||
.nvquirks = NVQUIRK_NEEDS_PAD_CONTROL |
|
||||
NVQUIRK_HAS_PADCALIB |
|
||||
NVQUIRK_DIS_CARD_CLK_CONFIG_TAP |
|
||||
NVQUIRK_ENABLE_SDR50 |
|
||||
NVQUIRK_ENABLE_SDR104 |
|
||||
NVQUIRK_PROGRAM_STREAMID |
|
||||
NVQUIRK_HAS_TMCLK,
|
||||
.min_tap_delay = 95,
|
||||
.max_tap_delay = 111,
|
||||
};
|
||||
|
||||
static const struct of_device_id sdhci_tegra_dt_match[] = {
|
||||
{ .compatible = "nvidia,tegra264-sdhci", .data = &soc_data_tegra264 },
|
||||
{ .compatible = "nvidia,tegra238-sdhci", .data = &soc_data_tegra238 },
|
||||
{ .compatible = "nvidia,tegra234-sdhci", .data = &soc_data_tegra234 },
|
||||
{ .compatible = "nvidia,tegra194-sdhci", .data = &soc_data_tegra194 },
|
||||
{ .compatible = "nvidia,tegra186-sdhci", .data = &soc_data_tegra186 },
|
||||
|
||||
@@ -462,7 +462,7 @@ static u32 sdhci_am654_cqhci_irq(struct sdhci_host *host, u32 intmask)
|
||||
if (!sdhci_cqe_irq(host, intmask, &cmd_error, &data_error))
|
||||
return intmask;
|
||||
|
||||
cqhci_irq(host->mmc, intmask, cmd_error, data_error);
|
||||
cqhci_irq(host->mmc, cmd_error, data_error);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1505,18 +1505,14 @@ static int sh_mmcif_probe(struct platform_device *pdev)
|
||||
name = irq[1] < 0 ? dev_name(dev) : "sh_mmc:error";
|
||||
ret = devm_request_threaded_irq(dev, irq[0], sh_mmcif_intr,
|
||||
sh_mmcif_irqt, 0, name, host);
|
||||
if (ret) {
|
||||
dev_err(dev, "request_irq error (%s)\n", name);
|
||||
if (ret)
|
||||
goto err_clk;
|
||||
}
|
||||
if (irq[1] >= 0) {
|
||||
ret = devm_request_threaded_irq(dev, irq[1],
|
||||
sh_mmcif_intr, sh_mmcif_irqt,
|
||||
0, "sh_mmc:int", host);
|
||||
if (ret) {
|
||||
dev_err(dev, "request_irq error (sh_mmc:int)\n");
|
||||
if (ret)
|
||||
goto err_clk;
|
||||
}
|
||||
}
|
||||
|
||||
mutex_init(&host->thread_lock);
|
||||
|
||||
@@ -1153,10 +1153,16 @@ static int via_sd_probe(struct pci_dev *pcidev,
|
||||
|
||||
ret = mmc_add_host(mmc);
|
||||
if (ret)
|
||||
goto unmap;
|
||||
goto free_irq;
|
||||
|
||||
return 0;
|
||||
|
||||
free_irq:
|
||||
writeb(0x0, sdhost->pcictrl_mmiobase + VIA_CRDR_PCIINTCTRL);
|
||||
free_irq(pcidev->irq, sdhost);
|
||||
cancel_work_sync(&sdhost->carddet_work);
|
||||
/* carddet_work may re-enable the interrupt via via_reset_pcictrl(). */
|
||||
writeb(0x0, sdhost->pcictrl_mmiobase + VIA_CRDR_PCIINTCTRL);
|
||||
unmap:
|
||||
iounmap(sdhost->mmiobase);
|
||||
release:
|
||||
@@ -1199,6 +1205,10 @@ static void via_sd_remove(struct pci_dev *pcidev)
|
||||
|
||||
free_irq(pcidev->irq, sdhost);
|
||||
|
||||
cancel_work_sync(&sdhost->carddet_work);
|
||||
/* carddet_work may re-enable the interrupt via via_reset_pcictrl(). */
|
||||
writeb(0x0, sdhost->pcictrl_mmiobase + VIA_CRDR_PCIINTCTRL);
|
||||
|
||||
timer_delete_sync(&sdhost->timer);
|
||||
|
||||
cancel_work_sync(&sdhost->finish_bh_work);
|
||||
|
||||
@@ -52,9 +52,9 @@
|
||||
#ifdef CONFIG_PNP
|
||||
|
||||
static const struct pnp_device_id pnp_dev_table[] = {
|
||||
{ "WEC0517", 0 },
|
||||
{ "WEC0518", 0 },
|
||||
{ "", 0 },
|
||||
{ .id = "WEC0517" },
|
||||
{ .id = "WEC0518" },
|
||||
{ }
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(pnp, pnp_dev_table);
|
||||
|
||||
@@ -61,6 +61,9 @@ struct rtsx_ucr {
|
||||
|
||||
struct timer_list sg_timer;
|
||||
struct mutex dev_mutex;
|
||||
|
||||
u16 card_status_cache;
|
||||
bool card_status_valid;
|
||||
};
|
||||
|
||||
/* buffer size */
|
||||
|
||||
@@ -46,14 +46,6 @@
|
||||
* PXA31x A2 0x69056892 0x2E649013
|
||||
* PXA32x B1 0x69056825 0x5E642013
|
||||
* PXA32x B2 0x69056826 0x6E642013
|
||||
*
|
||||
* PXA930 B0 0x69056835 0x5E643013
|
||||
* PXA930 B1 0x69056837 0x7E643013
|
||||
* PXA930 B2 0x69056838 0x8E643013
|
||||
*
|
||||
* PXA935 A0 0x56056931 0x1E653013
|
||||
* PXA935 B0 0x56056936 0x6E653013
|
||||
* PXA935 B1 0x56056938 0x8E653013
|
||||
*/
|
||||
#ifdef CONFIG_PXA25x
|
||||
#define __cpu_is_pxa210(id) \
|
||||
@@ -126,26 +118,6 @@
|
||||
#define __cpu_is_pxa320(id) (0)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CPU_PXA930
|
||||
#define __cpu_is_pxa930(id) \
|
||||
({ \
|
||||
unsigned int _id = (id) >> 4 & 0xfff; \
|
||||
_id == 0x683; \
|
||||
})
|
||||
#else
|
||||
#define __cpu_is_pxa930(id) (0)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CPU_PXA935
|
||||
#define __cpu_is_pxa935(id) \
|
||||
({ \
|
||||
unsigned int _id = (id) >> 4 & 0xfff; \
|
||||
_id == 0x693; \
|
||||
})
|
||||
#else
|
||||
#define __cpu_is_pxa935(id) (0)
|
||||
#endif
|
||||
|
||||
#define cpu_is_pxa210() \
|
||||
({ \
|
||||
__cpu_is_pxa210(read_cpuid_id()); \
|
||||
@@ -186,18 +158,6 @@
|
||||
__cpu_is_pxa320(read_cpuid_id()); \
|
||||
})
|
||||
|
||||
#define cpu_is_pxa930() \
|
||||
({ \
|
||||
__cpu_is_pxa930(read_cpuid_id()); \
|
||||
})
|
||||
|
||||
#define cpu_is_pxa935() \
|
||||
({ \
|
||||
__cpu_is_pxa935(read_cpuid_id()); \
|
||||
})
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* CPUID Core Generation Bit
|
||||
* <= 0x2 for pxa21x/pxa25x/pxa26x/pxa27x
|
||||
@@ -217,23 +177,12 @@
|
||||
({ \
|
||||
__cpu_is_pxa300(id) \
|
||||
|| __cpu_is_pxa310(id) \
|
||||
|| __cpu_is_pxa320(id) \
|
||||
|| __cpu_is_pxa93x(id); \
|
||||
|| __cpu_is_pxa320(id); \
|
||||
})
|
||||
#else
|
||||
#define __cpu_is_pxa3xx(id) (0)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_CPU_PXA930) || defined(CONFIG_CPU_PXA935)
|
||||
#define __cpu_is_pxa93x(id) \
|
||||
({ \
|
||||
__cpu_is_pxa930(id) \
|
||||
|| __cpu_is_pxa935(id); \
|
||||
})
|
||||
#else
|
||||
#define __cpu_is_pxa93x(id) (0)
|
||||
#endif
|
||||
|
||||
#define cpu_is_pxa2xx() \
|
||||
({ \
|
||||
__cpu_is_pxa2xx(read_cpuid_id()); \
|
||||
@@ -244,9 +193,4 @@
|
||||
__cpu_is_pxa3xx(read_cpuid_id()); \
|
||||
})
|
||||
|
||||
#define cpu_is_pxa93x() \
|
||||
({ \
|
||||
__cpu_is_pxa93x(read_cpuid_id()); \
|
||||
})
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user