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:
Linus Torvalds
2026-08-21 11:58:08 -07:00
50 changed files with 488 additions and 460 deletions
@@ -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";
};
+7
View File
@@ -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>
+2 -2
View File
@@ -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>;
+2 -2
View File
@@ -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";
};
+2 -2
View File
@@ -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;
+1 -1
View File
@@ -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>;
+20 -6
View File
@@ -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*/
+5
View File
@@ -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");
+1 -8
View File
@@ -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;
}
+1 -2
View File
@@ -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
View File
@@ -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;
}
+2 -8
View File
@@ -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,
+8 -9
View File
@@ -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;
+1 -2
View File
@@ -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);
-1
View File
@@ -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_ */
+1
View File
@@ -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);
+2
View File
@@ -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,
+32 -99
View File
@@ -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 |
+1 -4
View File
@@ -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)) {
+19 -21
View File
@@ -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;
+1 -1
View File
@@ -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)
+1 -3
View File
@@ -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);
+8 -7
View File
@@ -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)
+1 -4
View File
@@ -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) {
+1 -2
View File
@@ -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;
+12 -1
View File
@@ -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)
+1 -1
View File
@@ -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;
}
+1 -1
View File
@@ -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;
}
+12 -12
View File
@@ -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);
+2 -4
View File
@@ -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;
+1 -1
View File
@@ -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;
}
+2 -1
View File
@@ -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)
+1
View File
@@ -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 = {
+1 -1
View File
@@ -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;
}
+1 -1
View File
@@ -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;
}
+31 -1
View File
@@ -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 },
+1 -1
View File
@@ -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;
}
+2 -6
View File
@@ -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);
+11 -1
View File
@@ -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);
+3 -3
View File
@@ -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);
+3
View File
@@ -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 */
+1 -57
View File
@@ -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