Commit ef60eb0e authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'mmc-v5.14' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc

Pull MMC and MEMSTICK updates from Ulf Hansson:
 "MMC core:
   - Add support for Cache Ctrl for SD cards
   - Add support for Power Off Notification for SD cards
   - Add support for read/write of the SD function extension registers
   - Allow broken eMMC HS400 mode to be disabled via DT
   - Allow UHS-I voltage switch for SDSC cards if supported
   - Disable command queueing in the ioctl path
   - Enable eMMC sleep commands to use HW busy polling to minimize delay
   - Extend re-use of the common polling loop to standardize behaviour
   - Take into account MMC_CAP_NEED_RSP_BUSY for eMMC HPI commands

  MMC host:
   - jz4740: Add support for the JZ4775 variant
   - sdhci-acpi: Disable write protect detection on Toshiba Encore 2 WT8-B
   - sdhci-esdhc-imx: Advertise HS400 support through MMC caps
   - sdhci-esdhc-imx: Enable support for system wakeup for SDIO
   - sdhci-iproc: Add support for the legacy sdhci controller on the BCM7211
   - vub3000: Fix control-request direction

  MEMSTICK:
   - A couple of fixes/cleanups"

* tag 'mmc-v5.14' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc: (54 commits)
  mmc: sdhci-iproc: Add support for the legacy sdhci controller on the BCM7211
  dt-bindings: mmc: sdhci-iproc: Add brcm,bcm7211a0-sdhci
  mmc: JZ4740: Add support for JZ4775
  dt-bindings: mmc: JZ4740: Add bindings for JZ4775
  mmc: sdhci-esdhc-imx: Enable support for system wakeup for SDIO
  mmc: Improve function name when aborting a tuning cmd
  mmc: sdhci-of-aspeed: Turn down a phase correction warning
  mmc: debugfs: add description for module parameter
  mmc: via-sdmmc: add a check against NULL pointer dereference
  mmc: sdhci-sprd: use sdhci_sprd_writew
  mmc: sdhci-esdhc-imx: remove unused is_imx6q_usdhc
  mmc: core: Allow UHS-I voltage switch for SDSC cards if supported
  mmc: mmc_spi: Imply container_of() to be no-op
  mmc: mmc_spi: Drop duplicate 'mmc_spi' in the debug messages
  mmc: dw_mmc-pltfm: Remove unused <linux/clk.h>
  mmc: sdhci-of-aspeed: Configure the SDHCIs as specified by the devicetree.
  mmc: core: Add a missing SPDX license header
  mmc: vub3000: fix control-request direction
  mmc: sdhci-omap: Use pm_runtime_resume_and_get() to replace open coding
  mmc: sdhci_am654: Use pm_runtime_resume_and_get() to replace open coding
  ...
parents 43bd8a67 98b5ce4c
...@@ -21,6 +21,7 @@ properties: ...@@ -21,6 +21,7 @@ properties:
- brcm,bcm2711-emmc2 - brcm,bcm2711-emmc2
- brcm,sdhci-iproc-cygnus - brcm,sdhci-iproc-cygnus
- brcm,sdhci-iproc - brcm,sdhci-iproc
- brcm,bcm7211a0-sdhci
reg: reg:
minItems: 1 minItems: 1
......
...@@ -19,6 +19,7 @@ properties: ...@@ -19,6 +19,7 @@ properties:
- ingenic,jz4740-mmc - ingenic,jz4740-mmc
- ingenic,jz4725b-mmc - ingenic,jz4725b-mmc
- ingenic,jz4760-mmc - ingenic,jz4760-mmc
- ingenic,jz4775-mmc
- ingenic,jz4780-mmc - ingenic,jz4780-mmc
- ingenic,x1000-mmc - ingenic,x1000-mmc
- items: - items:
......
...@@ -220,6 +220,11 @@ properties: ...@@ -220,6 +220,11 @@ properties:
description: description:
eMMC HS400 enhanced strobe mode is supported eMMC HS400 enhanced strobe mode is supported
no-mmc-hs400:
$ref: /schemas/types.yaml#/definitions/flag
description:
All eMMC HS400 modes are not supported.
dsr: dsr:
description: description:
Value the card Driver Stage Register (DSR) should be programmed Value the card Driver Stage Register (DSR) should be programmed
...@@ -357,22 +362,6 @@ dependencies: ...@@ -357,22 +362,6 @@ dependencies:
additionalProperties: true additionalProperties: true
examples: examples:
- |
mmc@ab000000 {
compatible = "sdhci";
reg = <0xab000000 0x200>;
interrupts = <23>;
bus-width = <4>;
cd-gpios = <&gpio 69 0>;
cd-inverted;
wp-gpios = <&gpio 70 0>;
max-frequency = <50000000>;
keep-power-in-suspend;
wakeup-source;
mmc-pwrseq = <&sdhci0_pwrseq>;
clk-phase-sd-hs = <63>, <72>;
};
- | - |
mmc3: mmc@1c12000 { mmc3: mmc@1c12000 {
#address-cells = <1>; #address-cells = <1>;
...@@ -385,9 +374,9 @@ examples: ...@@ -385,9 +374,9 @@ examples:
non-removable; non-removable;
mmc-pwrseq = <&sdhci0_pwrseq>; mmc-pwrseq = <&sdhci0_pwrseq>;
brcmf: bcrmf@1 { brcmf: wifi@1 {
reg = <1>; reg = <1>;
compatible = "brcm,bcm43xx-fmac"; compatible = "brcm,bcm4329-fmac";
interrupt-parent = <&pio>; interrupt-parent = <&pio>;
interrupts = <10 8>; interrupts = <10 8>;
interrupt-names = "host-wake"; interrupt-names = "host-wake";
......
* Renesas Multi Media Card Interface (MMCIF) Controller
This file documents differences between the core properties in mmc.txt
and the properties used by the MMCIF device.
Required properties:
- compatible: should be "renesas,mmcif-<soctype>", "renesas,sh-mmcif" as a
fallback. Examples with <soctype> are:
- "renesas,mmcif-r7s72100" for the MMCIF found in r7s72100 SoCs
- "renesas,mmcif-r8a73a4" for the MMCIF found in r8a73a4 SoCs
- "renesas,mmcif-r8a7740" for the MMCIF found in r8a7740 SoCs
- "renesas,mmcif-r8a7742" for the MMCIF found in r8a7742 SoCs
- "renesas,mmcif-r8a7743" for the MMCIF found in r8a7743 SoCs
- "renesas,mmcif-r8a7744" for the MMCIF found in r8a7744 SoCs
- "renesas,mmcif-r8a7745" for the MMCIF found in r8a7745 SoCs
- "renesas,mmcif-r8a7778" for the MMCIF found in r8a7778 SoCs
- "renesas,mmcif-r8a7790" for the MMCIF found in r8a7790 SoCs
- "renesas,mmcif-r8a7791" for the MMCIF found in r8a7791 SoCs
- "renesas,mmcif-r8a7793" for the MMCIF found in r8a7793 SoCs
- "renesas,mmcif-r8a7794" for the MMCIF found in r8a7794 SoCs
- "renesas,mmcif-sh73a0" for the MMCIF found in sh73a0 SoCs
- interrupts: Some SoCs have only 1 shared interrupt, while others have either
2 or 3 individual interrupts (error, int, card detect). Below is the number
of interrupts for each SoC:
1: r8a73a4, r8a7742, r8a7743, r8a7744, r8a7745, r8a7778, r8a7790, r8a7791,
r8a7793, r8a7794
2: r8a7740, sh73a0
3: r7s72100
- clocks: reference to the functional clock
- dmas: reference to the DMA channels, one per channel name listed in the
dma-names property.
- dma-names: must contain "tx" for the transmit DMA channel and "rx" for the
receive DMA channel.
- max-frequency: Maximum operating clock frequency, driver uses default clock
frequency if it is not set.
Example: R8A7790 (R-Car H2) MMCIF0
mmcif0: mmc@ee200000 {
compatible = "renesas,mmcif-r8a7790", "renesas,sh-mmcif";
reg = <0 0xee200000 0 0x80>;
interrupts = <0 169 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp3_clks R8A7790_CLK_MMCIF0>;
dmas = <&dmac0 0xd1>, <&dmac0 0xd2>;
dma-names = "tx", "rx";
max-frequency = <97500000>;
};
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/mmc/renesas,mmcif.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Renesas Multi Media Card Interface (MMCIF) Controller
maintainers:
- Wolfram Sang <wsa+renesas@sang-engineering.com>
allOf:
- $ref: "mmc-controller.yaml"
properties:
compatible:
items:
- enum:
- renesas,mmcif-r7s72100 # RZ/A1H
- renesas,mmcif-r8a73a4 # R-Mobile APE6
- renesas,mmcif-r8a7740 # R-Mobile A1
- renesas,mmcif-r8a7742 # RZ/G1H
- renesas,mmcif-r8a7743 # RZ/G1M
- renesas,mmcif-r8a7744 # RZ/G1N
- renesas,mmcif-r8a7745 # RZ/G1E
- renesas,mmcif-r8a7778 # R-Car M1A
- renesas,mmcif-r8a7790 # R-Car H2
- renesas,mmcif-r8a7791 # R-Car M2-W
- renesas,mmcif-r8a7793 # R-Car M2-N
- renesas,mmcif-r8a7794 # R-Car E2
- renesas,mmcif-sh73a0 # SH-Mobile AG5
- const: renesas,sh-mmcif
reg:
maxItems: 1
interrupts: true
clocks:
maxItems: 1
power-domains:
maxItems: 1
resets:
maxItems: 1
dmas:
minItems: 2
maxItems: 4
description:
Must contain a list of pairs of references to DMA specifiers, one for
transmission, and one for reception.
dma-names:
minItems: 2
maxItems: 4
items:
enum:
- tx
- rx
max-frequency: true
required:
- compatible
- reg
- interrupts
- clocks
- power-domains
if:
properties:
compatible:
contains:
const: renesas,mmcif-r7s72100
then:
properties:
interrupts:
items:
- description: Error interrupt
- description: Normal operation interrupt
- description: Card detection interrupt
else:
if:
properties:
compatible:
contains:
enum:
- renesas,mmcif-r8a7740
- renesas,mmcif-sh73a0
then:
properties:
interrupts:
items:
- description: Error interrupt
- description: Normal operation interrupt
else:
if:
properties:
compatible:
contains:
enum:
- renesas,mmcif-r8a73a4
- renesas,mmcif-r8a7778
then:
properties:
interrupts:
maxItems: 1
else:
properties:
interrupts:
maxItems: 1
required:
- resets
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/r8a7790-cpg-mssr.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/power/r8a7790-sysc.h>
mmcif0: mmc@ee200000 {
compatible = "renesas,mmcif-r8a7790", "renesas,sh-mmcif";
reg = <0xee200000 0x80>;
interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cpg CPG_MOD 315>;
power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
resets = <&cpg 315>;
dmas = <&dmac0 0xd1>, <&dmac0 0xd2>, <&dmac1 0xd1>, <&dmac1 0xd2>;
dma-names = "tx", "rx", "tx", "rx";
max-frequency = <97500000>;
};
...@@ -29,21 +29,15 @@ properties: ...@@ -29,21 +29,15 @@ properties:
- const: rockchip,rk3288-dw-mshc - const: rockchip,rk3288-dw-mshc
- items: - items:
- enum: - enum:
# for Rockchip PX30
- rockchip,px30-dw-mshc - rockchip,px30-dw-mshc
# for Rockchip RK3036 - rockchip,rk1808-dw-mshc
- rockchip,rk3036-dw-mshc - rockchip,rk3036-dw-mshc
# for Rockchip RK322x
- rockchip,rk3228-dw-mshc - rockchip,rk3228-dw-mshc
# for Rockchip RK3308
- rockchip,rk3308-dw-mshc - rockchip,rk3308-dw-mshc
# for Rockchip RK3328
- rockchip,rk3328-dw-mshc - rockchip,rk3328-dw-mshc
# for Rockchip RK3368
- rockchip,rk3368-dw-mshc - rockchip,rk3368-dw-mshc
# for Rockchip RK3399
- rockchip,rk3399-dw-mshc - rockchip,rk3399-dw-mshc
# for Rockchip RV1108 - rockchip,rk3568-dw-mshc
- rockchip,rv1108-dw-mshc - rockchip,rv1108-dw-mshc
- const: rockchip,rk3288-dw-mshc - const: rockchip,rk3288-dw-mshc
......
...@@ -19,7 +19,6 @@ properties: ...@@ -19,7 +19,6 @@ properties:
- const: ti,am654-sdhci-5.1 - const: ti,am654-sdhci-5.1
- const: ti,j721e-sdhci-8bit - const: ti,j721e-sdhci-8bit
- const: ti,j721e-sdhci-4bit - const: ti,j721e-sdhci-4bit
- const: ti,j721e-sdhci-4bit
- const: ti,am64-sdhci-8bit - const: ti,am64-sdhci-8bit
- const: ti,am64-sdhci-4bit - const: ti,am64-sdhci-4bit
- items: - items:
......
...@@ -129,7 +129,7 @@ static int msb_sg_compare_to_buffer(struct scatterlist *sg, ...@@ -129,7 +129,7 @@ static int msb_sg_compare_to_buffer(struct scatterlist *sg,
* Each zone consists of 512 eraseblocks, out of which in first * Each zone consists of 512 eraseblocks, out of which in first
* zone 494 are used and 496 are for all following zones. * zone 494 are used and 496 are for all following zones.
* Therefore zone #0 hosts blocks 0-493, zone #1 blocks 494-988, etc... * Therefore zone #0 hosts blocks 0-493, zone #1 blocks 494-988, etc...
*/ */
static int msb_get_zone_from_lba(int lba) static int msb_get_zone_from_lba(int lba)
{ {
if (lba < 494) if (lba < 494)
...@@ -348,8 +348,9 @@ static int h_msb_read_page(struct memstick_dev *card, ...@@ -348,8 +348,9 @@ static int h_msb_read_page(struct memstick_dev *card,
switch (msb->state) { switch (msb->state) {
case MSB_RP_SEND_BLOCK_ADDRESS: case MSB_RP_SEND_BLOCK_ADDRESS:
/* msb_write_regs sometimes "fails" because it needs to update /* msb_write_regs sometimes "fails" because it needs to update
the reg window, and thus it returns request for that. * the reg window, and thus it returns request for that.
Then we stay in this state and retry */ * Then we stay in this state and retry
*/
if (!msb_write_regs(msb, if (!msb_write_regs(msb,
offsetof(struct ms_register, param), offsetof(struct ms_register, param),
sizeof(struct ms_param_register), sizeof(struct ms_param_register),
...@@ -368,7 +369,8 @@ static int h_msb_read_page(struct memstick_dev *card, ...@@ -368,7 +369,8 @@ static int h_msb_read_page(struct memstick_dev *card,
case MSB_RP_SEND_INT_REQ: case MSB_RP_SEND_INT_REQ:
msb->state = MSB_RP_RECEIVE_INT_REQ_RESULT; msb->state = MSB_RP_RECEIVE_INT_REQ_RESULT;
/* If dont actually need to send the int read request (only in /* If dont actually need to send the int read request (only in
serial mode), then just fall through */ * serial mode), then just fall through
*/
if (msb_read_int_reg(msb, -1)) if (msb_read_int_reg(msb, -1))
return 0; return 0;
fallthrough; fallthrough;
...@@ -702,7 +704,8 @@ static int h_msb_parallel_switch(struct memstick_dev *card, ...@@ -702,7 +704,8 @@ static int h_msb_parallel_switch(struct memstick_dev *card,
case MSB_PS_SWICH_HOST: case MSB_PS_SWICH_HOST:
/* Set parallel interface on our side + send a dummy request /* Set parallel interface on our side + send a dummy request
to see if card responds */ * to see if card responds
*/
host->set_param(host, MEMSTICK_INTERFACE, MEMSTICK_PAR4); host->set_param(host, MEMSTICK_INTERFACE, MEMSTICK_PAR4);
memstick_init_req(mrq, MS_TPC_GET_INT, NULL, 1); memstick_init_req(mrq, MS_TPC_GET_INT, NULL, 1);
msb->state = MSB_PS_CONFIRM; msb->state = MSB_PS_CONFIRM;
...@@ -821,6 +824,7 @@ static int msb_mark_page_bad(struct msb_data *msb, int pba, int page) ...@@ -821,6 +824,7 @@ static int msb_mark_page_bad(struct msb_data *msb, int pba, int page)
static int msb_erase_block(struct msb_data *msb, u16 pba) static int msb_erase_block(struct msb_data *msb, u16 pba)
{ {
int error, try; int error, try;
if (msb->read_only) if (msb->read_only)
return -EROFS; return -EROFS;
...@@ -997,6 +1001,7 @@ static int msb_write_block(struct msb_data *msb, ...@@ -997,6 +1001,7 @@ static int msb_write_block(struct msb_data *msb,
u16 pba, u32 lba, struct scatterlist *sg, int offset) u16 pba, u32 lba, struct scatterlist *sg, int offset)
{ {
int error, current_try = 1; int error, current_try = 1;
BUG_ON(sg->length < msb->page_size); BUG_ON(sg->length < msb->page_size);
if (msb->read_only) if (msb->read_only)
...@@ -1045,11 +1050,12 @@ static int msb_write_block(struct msb_data *msb, ...@@ -1045,11 +1050,12 @@ static int msb_write_block(struct msb_data *msb,
error = msb_run_state_machine(msb, h_msb_write_block); error = msb_run_state_machine(msb, h_msb_write_block);
/* Sector we just wrote to is assumed erased since its pba /* Sector we just wrote to is assumed erased since its pba
was erased. If it wasn't erased, write will succeed * was erased. If it wasn't erased, write will succeed
and will just clear the bits that were set in the block * and will just clear the bits that were set in the block
thus test that what we have written, * thus test that what we have written,
matches what we expect. * matches what we expect.
We do trust the blocks that we erased */ * We do trust the blocks that we erased
*/
if (!error && (verify_writes || if (!error && (verify_writes ||
!test_bit(pba, msb->erased_blocks_bitmap))) !test_bit(pba, msb->erased_blocks_bitmap)))
error = msb_verify_block(msb, pba, sg, offset); error = msb_verify_block(msb, pba, sg, offset);
...@@ -1493,6 +1499,7 @@ static int msb_ftl_scan(struct msb_data *msb) ...@@ -1493,6 +1499,7 @@ static int msb_ftl_scan(struct msb_data *msb)
static void msb_cache_flush_timer(struct timer_list *t) static void msb_cache_flush_timer(struct timer_list *t)
{ {
struct msb_data *msb = from_timer(msb, t, cache_flush_timer); struct msb_data *msb = from_timer(msb, t, cache_flush_timer);
msb->need_flush_cache = true; msb->need_flush_cache = true;
queue_work(msb->io_queue, &msb->io_work); queue_work(msb->io_queue, &msb->io_work);
} }
...@@ -1673,7 +1680,8 @@ static int msb_cache_read(struct msb_data *msb, int lba, ...@@ -1673,7 +1680,8 @@ static int msb_cache_read(struct msb_data *msb, int lba,
* This table content isn't that importaint, * This table content isn't that importaint,
* One could put here different values, providing that they still * One could put here different values, providing that they still
* cover whole disk. * cover whole disk.
* 64 MB entry is what windows reports for my 64M memstick */ * 64 MB entry is what windows reports for my 64M memstick
*/
static const struct chs_entry chs_table[] = { static const struct chs_entry chs_table[] = {
/* size sectors cylynders heads */ /* size sectors cylynders heads */
...@@ -1706,8 +1714,9 @@ static int msb_init_card(struct memstick_dev *card) ...@@ -1706,8 +1714,9 @@ static int msb_init_card(struct memstick_dev *card)
return error; return error;
/* Due to a bug in Jmicron driver written by Alex Dubov, /* Due to a bug in Jmicron driver written by Alex Dubov,
its serial mode barely works, * its serial mode barely works,
so we switch to parallel mode right away */ * so we switch to parallel mode right away
*/
if (host->caps & MEMSTICK_CAP_PAR4) if (host->caps & MEMSTICK_CAP_PAR4)
msb_switch_to_parallel(msb); msb_switch_to_parallel(msb);
...@@ -2033,6 +2042,7 @@ static blk_status_t msb_queue_rq(struct blk_mq_hw_ctx *hctx, ...@@ -2033,6 +2042,7 @@ static blk_status_t msb_queue_rq(struct blk_mq_hw_ctx *hctx,
static int msb_check_card(struct memstick_dev *card) static int msb_check_card(struct memstick_dev *card)
{ {
struct msb_data *msb = memstick_get_drvdata(card); struct msb_data *msb = memstick_get_drvdata(card);
return (msb->card_dead == 0); return (msb->card_dead == 0);
} }
...@@ -2333,6 +2343,7 @@ static struct memstick_driver msb_driver = { ...@@ -2333,6 +2343,7 @@ static struct memstick_driver msb_driver = {
static int __init msb_init(void) static int __init msb_init(void)
{ {
int rc = memstick_register_driver(&msb_driver); int rc = memstick_register_driver(&msb_driver);
if (rc) if (rc)
pr_err("failed to register memstick driver (error %d)\n", rc); pr_err("failed to register memstick driver (error %d)\n", rc);
......
...@@ -799,9 +799,9 @@ static int rtsx_usb_ms_drv_probe(struct platform_device *pdev) ...@@ -799,9 +799,9 @@ static int rtsx_usb_ms_drv_probe(struct platform_device *pdev)
return 0; return 0;
err_out: err_out:
memstick_free_host(msh);
pm_runtime_disable(ms_dev(host)); pm_runtime_disable(ms_dev(host));
pm_runtime_put_noidle(ms_dev(host)); pm_runtime_put_noidle(ms_dev(host));
memstick_free_host(msh);
return err; return err;
} }
...@@ -828,9 +828,6 @@ static int rtsx_usb_ms_drv_remove(struct platform_device *pdev) ...@@ -828,9 +828,6 @@ static int rtsx_usb_ms_drv_remove(struct platform_device *pdev)
} }
mutex_unlock(&host->host_mutex); mutex_unlock(&host->host_mutex);
memstick_remove_host(msh);
memstick_free_host(msh);
/* Balance possible unbalanced usage count /* Balance possible unbalanced usage count
* e.g. unconditional module removal * e.g. unconditional module removal
*/ */
...@@ -838,10 +835,11 @@ static int rtsx_usb_ms_drv_remove(struct platform_device *pdev) ...@@ -838,10 +835,11 @@ static int rtsx_usb_ms_drv_remove(struct platform_device *pdev)
pm_runtime_put(ms_dev(host)); pm_runtime_put(ms_dev(host));
pm_runtime_disable(ms_dev(host)); pm_runtime_disable(ms_dev(host));
platform_set_drvdata(pdev, NULL); memstick_remove_host(msh);
dev_dbg(ms_dev(host), dev_dbg(ms_dev(host),
": Realtek USB Memstick controller has been removed\n"); ": Realtek USB Memstick controller has been removed\n");
memstick_free_host(msh);
platform_set_drvdata(pdev, NULL);
return 0; return 0;
} }
......
// SPDX-License-Identifier: GPL-2.0
/* /*
* Block driver for media (i.e., flash cards) * Block driver for media (i.e., flash cards)
* *
...@@ -1004,6 +1005,12 @@ static void mmc_blk_issue_drv_op(struct mmc_queue *mq, struct request *req) ...@@ -1004,6 +1005,12 @@ static void mmc_blk_issue_drv_op(struct mmc_queue *mq, struct request *req)
switch (mq_rq->drv_op) { switch (mq_rq->drv_op) {
case MMC_DRV_OP_IOCTL: case MMC_DRV_OP_IOCTL:
if (card->ext_csd.cmdq_en) {
ret = mmc_cmdq_disable(card);
if (ret)
break;
}
fallthrough;
case MMC_DRV_OP_IOCTL_RPMB: case MMC_DRV_OP_IOCTL_RPMB:
idata = mq_rq->drv_op_data; idata = mq_rq->drv_op_data;
for (i = 0, ret = 0; i < mq_rq->ioc_count; i++) { for (i = 0, ret = 0; i < mq_rq->ioc_count; i++) {
...@@ -1014,6 +1021,8 @@ static void mmc_blk_issue_drv_op(struct mmc_queue *mq, struct request *req) ...@@ -1014,6 +1021,8 @@ static void mmc_blk_issue_drv_op(struct mmc_queue *mq, struct request *req)
/* Always switch back to main area after RPMB access */ /* Always switch back to main area after RPMB access */
if (rpmb_ioctl) if (rpmb_ioctl)
mmc_blk_part_switch(card, 0); mmc_blk_part_switch(card, 0);
else if (card->reenable_cmdq && !card->ext_csd.cmdq_en)
mmc_cmdq_enable(card);
break; break;
case MMC_DRV_OP_BOOT_WP: case MMC_DRV_OP_BOOT_WP:
ret = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_WP, ret = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_WP,
...@@ -1159,7 +1168,7 @@ static void mmc_blk_issue_flush(struct mmc_queue *mq, struct request *req) ...@@ -1159,7 +1168,7 @@ static void mmc_blk_issue_flush(struct mmc_queue *mq, struct request *req)
struct mmc_card *card = md->queue.card; struct mmc_card *card = md->queue.card;
int ret = 0; int ret = 0;
ret = mmc_flush_cache(card); ret = mmc_flush_cache(card->host);
blk_mq_end_request(req, ret ? BLK_STS_IOERR : BLK_STS_OK); blk_mq_end_request(req, ret ? BLK_STS_IOERR : BLK_STS_OK);
} }
......
...@@ -1582,7 +1582,7 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from, ...@@ -1582,7 +1582,7 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from,
{ {
struct mmc_command cmd = {}; struct mmc_command cmd = {};
unsigned int qty = 0, busy_timeout = 0; unsigned int qty = 0, busy_timeout = 0;
bool use_r1b_resp = false; bool use_r1b_resp;
int err; int err;
mmc_retune_hold(card->host); mmc_retune_hold(card->host);
...@@ -1650,23 +1650,7 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from, ...@@ -1650,23 +1650,7 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from,
cmd.opcode = MMC_ERASE; cmd.opcode = MMC_ERASE;
cmd.arg = arg; cmd.arg = arg;
busy_timeout = mmc_erase_timeout(card, arg, qty); busy_timeout = mmc_erase_timeout(card, arg, qty);
/* use_r1b_resp = mmc_prepare_busy_cmd(card->host, &cmd, busy_timeout);
* If the host controller supports busy signalling and the timeout for
* the erase operation does not exceed the max_busy_timeout, we should
* use R1B response. Or we need to prevent the host from doing hw busy
* detection, which is done by converting to a R1 response instead.
* Note, some hosts requires R1B, which also means they are on their own
* when it comes to deal with the busy timeout.
*/
if (!(card->host->caps & MMC_CAP_NEED_RSP_BUSY) &&
card->host->max_busy_timeout &&
busy_timeout > card->host->max_busy_timeout) {
cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC;
} else {
cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC;
cmd.busy_timeout = busy_timeout;
use_r1b_resp = true;
}
err = mmc_wait_for_cmd(card->host, &cmd, 0); err = mmc_wait_for_cmd(card->host, &cmd, 0);
if (err) { if (err) {
...@@ -1687,7 +1671,7 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from, ...@@ -1687,7 +1671,7 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from,
goto out; goto out;
/* Let's poll to find out when the erase operation completes. */ /* Let's poll to find out when the erase operation completes. */
err = mmc_poll_for_busy(card, busy_timeout, MMC_BUSY_ERASE); err = mmc_poll_for_busy(card, busy_timeout, false, MMC_BUSY_ERASE);
out: out:
mmc_retune_release(card->host); mmc_retune_release(card->host);
......
...@@ -30,6 +30,7 @@ struct mmc_bus_ops { ...@@ -30,6 +30,7 @@ struct mmc_bus_ops {
int (*hw_reset)(struct mmc_host *); int (*hw_reset)(struct mmc_host *);
int (*sw_reset)(struct mmc_host *); int (*sw_reset)(struct mmc_host *);
bool (*cache_enabled)(struct mmc_host *); bool (*cache_enabled)(struct mmc_host *);
int (*flush_cache)(struct mmc_host *);
}; };
void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops); void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops);
...@@ -172,4 +173,12 @@ static inline bool mmc_cache_enabled(struct mmc_host *host) ...@@ -172,4 +173,12 @@ static inline bool mmc_cache_enabled(struct mmc_host *host)
return false; return false;
} }
static inline int mmc_flush_cache(struct mmc_host *host)
{
if (host->bus_ops->flush_cache)
return host->bus_ops->flush_cache(host);
return 0;
}
#endif #endif
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
static DECLARE_FAULT_ATTR(fail_default_attr); static DECLARE_FAULT_ATTR(fail_default_attr);
static char *fail_request; static char *fail_request;
module_param(fail_request, charp, 0); module_param(fail_request, charp, 0);
MODULE_PARM_DESC(fail_request, "default fault injection attributes");
#endif /* CONFIG_FAIL_MMC_REQUEST */ #endif /* CONFIG_FAIL_MMC_REQUEST */
......
...@@ -388,6 +388,9 @@ int mmc_of_parse(struct mmc_host *host) ...@@ -388,6 +388,9 @@ int mmc_of_parse(struct mmc_host *host)
host->caps2 |= MMC_CAP2_NO_SD; host->caps2 |= MMC_CAP2_NO_SD;
if (device_property_read_bool(dev, "no-mmc")) if (device_property_read_bool(dev, "no-mmc"))
host->caps2 |= MMC_CAP2_NO_MMC; host->caps2 |= MMC_CAP2_NO_MMC;
if (device_property_read_bool(dev, "no-mmc-hs400"))
host->caps2 &= ~(MMC_CAP2_HS400_1_8V | MMC_CAP2_HS400_1_2V |
MMC_CAP2_HS400_ES);
/* Must be after "non-removable" check */ /* Must be after "non-removable" check */
if (device_property_read_u32(dev, "fixed-emmc-driver-type", &drv_type) == 0) { if (device_property_read_u32(dev, "fixed-emmc-driver-type", &drv_type) == 0) {
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#define DEFAULT_CMD6_TIMEOUT_MS 500 #define DEFAULT_CMD6_TIMEOUT_MS 500
#define MIN_CACHE_EN_TIMEOUT_MS 1600 #define MIN_CACHE_EN_TIMEOUT_MS 1600
#define CACHE_FLUSH_TIMEOUT_MS 30000 /* 30s */
static const unsigned int tran_exp[] = { static const unsigned int tran_exp[] = {
10000, 100000, 1000000, 10000000, 10000, 100000, 1000000, 10000000,
...@@ -1905,11 +1906,20 @@ static int mmc_can_sleep(struct mmc_card *card) ...@@ -1905,11 +1906,20 @@ static int mmc_can_sleep(struct mmc_card *card)
return card->ext_csd.rev >= 3; return card->ext_csd.rev >= 3;
} }
static int mmc_sleep_busy_cb(void *cb_data, bool *busy)
{
struct mmc_host *host = cb_data;
*busy = host->ops->card_busy(host);
return 0;
}
static int mmc_sleep(struct mmc_host *host) static int mmc_sleep(struct mmc_host *host)
{ {
struct mmc_command cmd = {}; struct mmc_command cmd = {};
struct mmc_card *card = host->card; struct mmc_card *card = host->card;
unsigned int timeout_ms = DIV_ROUND_UP(card->ext_csd.sa_timeout, 10000); unsigned int timeout_ms = DIV_ROUND_UP(card->ext_csd.sa_timeout, 10000);
bool use_r1b_resp;
int err; int err;
/* Re-tuning can't be done once the card is deselected */ /* Re-tuning can't be done once the card is deselected */
...@@ -1922,35 +1932,27 @@ static int mmc_sleep(struct mmc_host *host) ...@@ -1922,35 +1932,27 @@ static int mmc_sleep(struct mmc_host *host)
cmd.opcode = MMC_SLEEP_AWAKE; cmd.opcode = MMC_SLEEP_AWAKE;
cmd.arg = card->rca << 16; cmd.arg = card->rca << 16;
cmd.arg |= 1 << 15; cmd.arg |= 1 << 15;
use_r1b_resp = mmc_prepare_busy_cmd(host, &cmd, timeout_ms);
/*
* If the max_busy_timeout of the host is specified, validate it against
* the sleep cmd timeout. A failure means we need to prevent the host
* from doing hw busy detection, which is done by converting to a R1
* response instead of a R1B. Note, some hosts requires R1B, which also
* means they are on their own when it comes to deal with the busy
* timeout.
*/
if (!(host->caps & MMC_CAP_NEED_RSP_BUSY) && host->max_busy_timeout &&
(timeout_ms > host->max_busy_timeout)) {
cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
} else {
cmd.flags = MMC_RSP_R1B | MMC_CMD_AC;
cmd.busy_timeout = timeout_ms;
}
err = mmc_wait_for_cmd(host, &cmd, 0); err = mmc_wait_for_cmd(host, &cmd, 0);
if (err) if (err)
goto out_release; goto out_release;
/* /*
* If the host does not wait while the card signals busy, then we will * If the host does not wait while the card signals busy, then we can
* will have to wait the sleep/awake timeout. Note, we cannot use the * try to poll, but only if the host supports HW polling, as the
* SEND_STATUS command to poll the status because that command (and most * SEND_STATUS cmd is not allowed. If we can't poll, then we simply need
* others) is invalid while the card sleeps. * to wait the sleep/awake timeout.
*/ */
if (!cmd.busy_timeout || !(host->caps & MMC_CAP_WAIT_WHILE_BUSY)) if (host->caps & MMC_CAP_WAIT_WHILE_BUSY && use_r1b_resp)
goto out_release;
if (!host->ops->card_busy) {
mmc_delay(timeout_ms); mmc_delay(timeout_ms);
goto out_release;
}
err = __mmc_poll_for_busy(card, timeout_ms, &mmc_sleep_busy_cb, host);
out_release: out_release:
mmc_retune_release(host); mmc_retune_release(host);
...@@ -2035,6 +2037,25 @@ static bool _mmc_cache_enabled(struct mmc_host *host) ...@@ -2035,6 +2037,25 @@ static bool _mmc_cache_enabled(struct mmc_host *host)
host->card->ext_csd.cache_ctrl & 1; host->card->ext_csd.cache_ctrl & 1;
} }
/*
* Flush the internal cache of the eMMC to non-volatile storage.
*/
static int _mmc_flush_cache(struct mmc_host *host)
{
int err = 0;
if (_mmc_cache_enabled(host)) {
err = mmc_switch(host->card, EXT_CSD_CMD_SET_NORMAL,
EXT_CSD_FLUSH_CACHE, 1,
CACHE_FLUSH_TIMEOUT_MS);
if (err)
pr_err("%s: cache flush error %d\n",
mmc_hostname(host), err);
}
return err;
}
static int _mmc_suspend(struct mmc_host *host, bool is_suspend) static int _mmc_suspend(struct mmc_host *host, bool is_suspend)
{ {
int err = 0; int err = 0;
...@@ -2046,7 +2067,7 @@ static int _mmc_suspend(struct mmc_host *host, bool is_suspend) ...@@ -2046,7 +2067,7 @@ static int _mmc_suspend(struct mmc_host *host, bool is_suspend)
if (mmc_card_suspended(host->card)) if (mmc_card_suspended(host->card))
goto out; goto out;
err = mmc_flush_cache(host->card); err = _mmc_flush_cache(host);
if (err) if (err)
goto out; goto out;
...@@ -2187,7 +2208,7 @@ static int _mmc_hw_reset(struct mmc_host *host) ...@@ -2187,7 +2208,7 @@ static int _mmc_hw_reset(struct mmc_host *host)
* In the case of recovery, we can't expect flushing the cache to work * In the case of recovery, we can't expect flushing the cache to work
* always, but we have a go and ignore errors. * always, but we have a go and ignore errors.
*/ */
mmc_flush_cache(host->card); _mmc_flush_cache(host);
if ((host->caps & MMC_CAP_HW_RESET) && host->ops->hw_reset && if ((host->caps & MMC_CAP_HW_RESET) && host->ops->hw_reset &&
mmc_can_reset(card)) { mmc_can_reset(card)) {
...@@ -2215,6 +2236,7 @@ static const struct mmc_bus_ops mmc_ops = { ...@@ -2215,6 +2236,7 @@ static const struct mmc_bus_ops mmc_ops = {
.shutdown = mmc_shutdown, .shutdown = mmc_shutdown,
.hw_reset = _mmc_hw_reset, .hw_reset = _mmc_hw_reset,
.cache_enabled = _mmc_cache_enabled, .cache_enabled = _mmc_cache_enabled,
.flush_cache = _mmc_flush_cache,
}; };
/* /*
......
This diff is collapsed.
...@@ -14,10 +14,12 @@ enum mmc_busy_cmd { ...@@ -14,10 +14,12 @@ enum mmc_busy_cmd {
MMC_BUSY_CMD6, MMC_BUSY_CMD6,
MMC_BUSY_ERASE, MMC_BUSY_ERASE,
MMC_BUSY_HPI, MMC_BUSY_HPI,
MMC_BUSY_EXTR_SINGLE,
}; };
struct mmc_host; struct mmc_host;
struct mmc_card; struct mmc_card;
struct mmc_command;
int mmc_select_card(struct mmc_card *card); int mmc_select_card(struct mmc_card *card);
int mmc_deselect_cards(struct mmc_host *host); int mmc_deselect_cards(struct mmc_host *host);
...@@ -25,6 +27,8 @@ int mmc_set_dsr(struct mmc_host *host); ...@@ -25,6 +27,8 @@ int mmc_set_dsr(struct mmc_host *host);
int mmc_go_idle(struct mmc_host *host); int mmc_go_idle(struct mmc_host *host);
int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr); int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr);
int mmc_set_relative_addr(struct mmc_card *card); int mmc_set_relative_addr(struct mmc_card *card);
int mmc_send_adtc_data(struct mmc_card *card, struct mmc_host *host, u32 opcode,
u32 args, void *buf, unsigned len);
int mmc_send_csd(struct mmc_card *card, u32 *csd); int mmc_send_csd(struct mmc_card *card, u32 *csd);
int __mmc_send_status(struct mmc_card *card, u32 *status, unsigned int retries); int __mmc_send_status(struct mmc_card *card, u32 *status, unsigned int retries);
int mmc_send_status(struct mmc_card *card, u32 *status); int mmc_send_status(struct mmc_card *card, u32 *status);
...@@ -35,15 +39,19 @@ int mmc_bus_test(struct mmc_card *card, u8 bus_width); ...@@ -35,15 +39,19 @@ int mmc_bus_test(struct mmc_card *card, u8 bus_width);
int mmc_can_ext_csd(struct mmc_card *card); int mmc_can_ext_csd(struct mmc_card *card);
int mmc_get_ext_csd(struct mmc_card *card, u8 **new_ext_csd); int mmc_get_ext_csd(struct mmc_card *card, u8 **new_ext_csd);
int mmc_switch_status(struct mmc_card *card, bool crc_err_fatal); int mmc_switch_status(struct mmc_card *card, bool crc_err_fatal);
bool mmc_prepare_busy_cmd(struct mmc_host *host, struct mmc_command *cmd,
unsigned int timeout_ms);
int __mmc_poll_for_busy(struct mmc_card *card, unsigned int timeout_ms,
int (*busy_cb)(void *cb_data, bool *busy),
void *cb_data);
int mmc_poll_for_busy(struct mmc_card *card, unsigned int timeout_ms, int mmc_poll_for_busy(struct mmc_card *card, unsigned int timeout_ms,
enum mmc_busy_cmd busy_cmd); bool retry_crc_err, enum mmc_busy_cmd busy_cmd);
int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
unsigned int timeout_ms, unsigned char timing, unsigned int timeout_ms, unsigned char timing,
bool send_status, bool retry_crc_err, unsigned int retries); bool send_status, bool retry_crc_err, unsigned int retries);
int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
unsigned int timeout_ms); unsigned int timeout_ms);
void mmc_run_bkops(struct mmc_card *card); void mmc_run_bkops(struct mmc_card *card);
int mmc_flush_cache(struct mmc_card *card);
int mmc_cmdq_enable(struct mmc_card *card); int mmc_cmdq_enable(struct mmc_card *card);
int mmc_cmdq_disable(struct mmc_card *card); int mmc_cmdq_disable(struct mmc_card *card);
int mmc_sanitize(struct mmc_card *card, unsigned int timeout_ms); int mmc_sanitize(struct mmc_card *card, unsigned int timeout_ms);
......
This diff is collapsed.
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "core.h" #include "core.h"
#include "sd_ops.h" #include "sd_ops.h"
#include "mmc_ops.h"
int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card) int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card)
{ {
...@@ -309,43 +310,18 @@ int mmc_app_send_scr(struct mmc_card *card) ...@@ -309,43 +310,18 @@ int mmc_app_send_scr(struct mmc_card *card)
int mmc_sd_switch(struct mmc_card *card, int mode, int group, int mmc_sd_switch(struct mmc_card *card, int mode, int group,
u8 value, u8 *resp) u8 value, u8 *resp)
{ {
struct mmc_request mrq = {}; u32 cmd_args;
struct mmc_command cmd = {};
struct mmc_data data = {};
struct scatterlist sg;
/* NOTE: caller guarantees resp is heap-allocated */ /* NOTE: caller guarantees resp is heap-allocated */
mode = !!mode; mode = !!mode;
value &= 0xF; value &= 0xF;
cmd_args = mode << 31 | 0x00FFFFFF;
cmd_args &= ~(0xF << (group * 4));
cmd_args |= value << (group * 4);
mrq.cmd = &cmd; return mmc_send_adtc_data(card, card->host, SD_SWITCH, cmd_args, resp,
mrq.data = &data; 64);
cmd.opcode = SD_SWITCH;
cmd.arg = mode << 31 | 0x00FFFFFF;
cmd.arg &= ~(0xF << (group * 4));
cmd.arg |= value << (group * 4);
cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
data.blksz = 64;
data.blocks = 1;
data.flags = MMC_DATA_READ;
data.sg = &sg;
data.sg_len = 1;
sg_init_one(&sg, resp, 64);
mmc_set_data_timeout(&data, card);
mmc_wait_for_req(card->host, &mrq);
if (cmd.error)
return cmd.error;
if (data.error)
return data.error;
return 0;
} }
int mmc_app_sd_status(struct mmc_card *card, void *ssr) int mmc_app_sd_status(struct mmc_card *card, void *ssr)
......
...@@ -937,11 +937,9 @@ static void mmc_sdio_detect(struct mmc_host *host) ...@@ -937,11 +937,9 @@ static void mmc_sdio_detect(struct mmc_host *host)
/* Make sure card is powered before detecting it */ /* Make sure card is powered before detecting it */
if (host->caps & MMC_CAP_POWER_OFF_CARD) { if (host->caps & MMC_CAP_POWER_OFF_CARD) {
err = pm_runtime_get_sync(&host->card->dev); err = pm_runtime_resume_and_get(&host->card->dev);
if (err < 0) { if (err < 0)
pm_runtime_put_noidle(&host->card->dev);
goto out; goto out;
}
} }
mmc_claim_host(host); mmc_claim_host(host);
......
...@@ -412,7 +412,7 @@ config MMC_SDHCI_MILBEAUT ...@@ -412,7 +412,7 @@ config MMC_SDHCI_MILBEAUT
config MMC_SDHCI_IPROC config MMC_SDHCI_IPROC
tristate "SDHCI support for the BCM2835 & iProc SD/MMC Controller" tristate "SDHCI support for the BCM2835 & iProc SD/MMC Controller"
depends on ARCH_BCM2835 || ARCH_BCM_IPROC || COMPILE_TEST depends on ARCH_BCM2835 || ARCH_BCM_IPROC || ARCH_BRCMSTB || COMPILE_TEST
depends on MMC_SDHCI_PLTFM depends on MMC_SDHCI_PLTFM
depends on OF || ACPI depends on OF || ACPI
default ARCH_BCM_IPROC default ARCH_BCM_IPROC
......
...@@ -45,17 +45,23 @@ static inline u8 *get_link_desc(struct cqhci_host *cq_host, u8 tag) ...@@ -45,17 +45,23 @@ static inline u8 *get_link_desc(struct cqhci_host *cq_host, u8 tag)
return desc + cq_host->task_desc_len; return desc + cq_host->task_desc_len;
} }
static inline size_t get_trans_desc_offset(struct cqhci_host *cq_host, u8 tag)
{
return cq_host->trans_desc_len * cq_host->mmc->max_segs * tag;
}
static inline dma_addr_t get_trans_desc_dma(struct cqhci_host *cq_host, u8 tag) static inline dma_addr_t get_trans_desc_dma(struct cqhci_host *cq_host, u8 tag)
{ {
return cq_host->trans_desc_dma_base + size_t offset = get_trans_desc_offset(cq_host, tag);
(cq_host->mmc->max_segs * tag *
cq_host->trans_desc_len); return cq_host->trans_desc_dma_base + offset;
} }
static inline u8 *get_trans_desc(struct cqhci_host *cq_host, u8 tag) static inline u8 *get_trans_desc(struct cqhci_host *cq_host, u8 tag)
{ {
return cq_host->trans_desc_base + size_t offset = get_trans_desc_offset(cq_host, tag);
(cq_host->trans_desc_len * cq_host->mmc->max_segs * tag);
return cq_host->trans_desc_base + offset;
} }
static void setup_trans_desc(struct cqhci_host *cq_host, u8 tag) static void setup_trans_desc(struct cqhci_host *cq_host, u8 tag)
...@@ -146,7 +152,7 @@ static void cqhci_dumpregs(struct cqhci_host *cq_host) ...@@ -146,7 +152,7 @@ static void cqhci_dumpregs(struct cqhci_host *cq_host)
} }
/* /*
* The allocated descriptor table for task, link & transfer descritors * The allocated descriptor table for task, link & transfer descriptors
* looks like: * looks like:
* |----------| * |----------|
* |task desc | |->|----------| * |task desc | |->|----------|
...@@ -194,8 +200,7 @@ static int cqhci_host_alloc_tdl(struct cqhci_host *cq_host) ...@@ -194,8 +200,7 @@ static int cqhci_host_alloc_tdl(struct cqhci_host *cq_host)
cq_host->desc_size = cq_host->slot_sz * cq_host->num_slots; cq_host->desc_size = cq_host->slot_sz * cq_host->num_slots;
cq_host->data_size = cq_host->trans_desc_len * cq_host->mmc->max_segs * cq_host->data_size = get_trans_desc_offset(cq_host, cq_host->mmc->cqe_qdepth);
cq_host->mmc->cqe_qdepth;
pr_debug("%s: cqhci: desc_size: %zu data_sz: %zu slot-sz: %d\n", pr_debug("%s: cqhci: desc_size: %zu data_sz: %zu slot-sz: %d\n",
mmc_hostname(cq_host->mmc), cq_host->desc_size, cq_host->data_size, mmc_hostname(cq_host->mmc), cq_host->desc_size, cq_host->data_size,
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include <linux/mmc/host.h> #include <linux/mmc/host.h>
#include <linux/mmc/mmc.h> #include <linux/mmc/mmc.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/clk.h>
#include "dw_mmc.h" #include "dw_mmc.h"
#include "dw_mmc-pltfm.h" #include "dw_mmc-pltfm.h"
......
...@@ -674,7 +674,7 @@ static void jz4740_mmc_send_command(struct jz4740_mmc_host *host, ...@@ -674,7 +674,7 @@ static void jz4740_mmc_send_command(struct jz4740_mmc_host *host,
cmdat |= JZ_MMC_CMDAT_WRITE; cmdat |= JZ_MMC_CMDAT_WRITE;
if (host->use_dma) { if (host->use_dma) {
/* /*
* The 4780's MMC controller has integrated DMA ability * The JZ4780's MMC controller has integrated DMA ability
* in addition to being able to use the external DMA * in addition to being able to use the external DMA
* controller. It moves DMA control bits to a separate * controller. It moves DMA control bits to a separate
* register. The DMA_SEL bit chooses the external * register. The DMA_SEL bit chooses the external
...@@ -866,7 +866,7 @@ static int jz4740_mmc_set_clock_rate(struct jz4740_mmc_host *host, int rate) ...@@ -866,7 +866,7 @@ static int jz4740_mmc_set_clock_rate(struct jz4740_mmc_host *host, int rate)
writew(div, host->base + JZ_REG_MMC_CLKRT); writew(div, host->base + JZ_REG_MMC_CLKRT);
if (real_rate > 25000000) { if (real_rate > 25000000) {
if (host->version >= JZ_MMC_X1000) { if (host->version >= JZ_MMC_JZ4780) {
writel(JZ_MMC_LPM_DRV_RISING_QTR_PHASE_DLY | writel(JZ_MMC_LPM_DRV_RISING_QTR_PHASE_DLY |
JZ_MMC_LPM_SMP_RISING_QTR_OR_HALF_PHASE_DLY | JZ_MMC_LPM_SMP_RISING_QTR_OR_HALF_PHASE_DLY |
JZ_MMC_LPM_LOW_POWER_MODE_EN, JZ_MMC_LPM_LOW_POWER_MODE_EN,
...@@ -959,6 +959,7 @@ static const struct of_device_id jz4740_mmc_of_match[] = { ...@@ -959,6 +959,7 @@ static const struct of_device_id jz4740_mmc_of_match[] = {
{ .compatible = "ingenic,jz4740-mmc", .data = (void *) JZ_MMC_JZ4740 }, { .compatible = "ingenic,jz4740-mmc", .data = (void *) JZ_MMC_JZ4740 },
{ .compatible = "ingenic,jz4725b-mmc", .data = (void *)JZ_MMC_JZ4725B }, { .compatible = "ingenic,jz4725b-mmc", .data = (void *)JZ_MMC_JZ4725B },
{ .compatible = "ingenic,jz4760-mmc", .data = (void *) JZ_MMC_JZ4760 }, { .compatible = "ingenic,jz4760-mmc", .data = (void *) JZ_MMC_JZ4760 },
{ .compatible = "ingenic,jz4775-mmc", .data = (void *) JZ_MMC_JZ4780 },
{ .compatible = "ingenic,jz4780-mmc", .data = (void *) JZ_MMC_JZ4780 }, { .compatible = "ingenic,jz4780-mmc", .data = (void *) JZ_MMC_JZ4780 },
{ .compatible = "ingenic,x1000-mmc", .data = (void *) JZ_MMC_X1000 }, { .compatible = "ingenic,x1000-mmc", .data = (void *) JZ_MMC_X1000 },
{}, {},
...@@ -1013,7 +1014,6 @@ static int jz4740_mmc_probe(struct platform_device* pdev) ...@@ -1013,7 +1014,6 @@ static int jz4740_mmc_probe(struct platform_device* pdev)
host->base = devm_ioremap_resource(&pdev->dev, host->mem_res); host->base = devm_ioremap_resource(&pdev->dev, host->mem_res);
if (IS_ERR(host->base)) { if (IS_ERR(host->base)) {
ret = PTR_ERR(host->base); ret = PTR_ERR(host->base);
dev_err(&pdev->dev, "Failed to ioremap base memory\n");
goto err_free_host; goto err_free_host;
} }
......
...@@ -504,7 +504,7 @@ mmc_spi_command_send(struct mmc_spi_host *host, ...@@ -504,7 +504,7 @@ mmc_spi_command_send(struct mmc_spi_host *host,
/* else: R1 (most commands) */ /* else: R1 (most commands) */
} }
dev_dbg(&host->spi->dev, " mmc_spi: CMD%d, resp %s\n", dev_dbg(&host->spi->dev, " CMD%d, resp %s\n",
cmd->opcode, maptype(cmd)); cmd->opcode, maptype(cmd));
/* send command, leaving chipselect active */ /* send command, leaving chipselect active */
...@@ -928,8 +928,7 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd, ...@@ -928,8 +928,7 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd,
while (length) { while (length) {
t->len = min(length, blk_size); t->len = min(length, blk_size);
dev_dbg(&host->spi->dev, dev_dbg(&host->spi->dev, " %s block, %d bytes\n",
" mmc_spi: %s block, %d bytes\n",
(direction == DMA_TO_DEVICE) ? "write" : "read", (direction == DMA_TO_DEVICE) ? "write" : "read",
t->len); t->len);
...@@ -974,7 +973,7 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd, ...@@ -974,7 +973,7 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd,
int tmp; int tmp;
const unsigned statlen = sizeof(scratch->status); const unsigned statlen = sizeof(scratch->status);
dev_dbg(&spi->dev, " mmc_spi: STOP_TRAN\n"); dev_dbg(&spi->dev, " STOP_TRAN\n");
/* Tweak the per-block message we set up earlier by morphing /* Tweak the per-block message we set up earlier by morphing
* it to hold single buffer with the token followed by some * it to hold single buffer with the token followed by some
...@@ -1175,7 +1174,7 @@ static void mmc_spi_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) ...@@ -1175,7 +1174,7 @@ static void mmc_spi_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
canpower = host->pdata && host->pdata->setpower; canpower = host->pdata && host->pdata->setpower;
dev_dbg(&host->spi->dev, "mmc_spi: power %s (%d)%s\n", dev_dbg(&host->spi->dev, "power %s (%d)%s\n",
mmc_powerstring(ios->power_mode), mmc_powerstring(ios->power_mode),
ios->vdd, ios->vdd,
canpower ? ", can switch" : ""); canpower ? ", can switch" : "");
...@@ -1248,8 +1247,7 @@ static void mmc_spi_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) ...@@ -1248,8 +1247,7 @@ static void mmc_spi_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
host->spi->max_speed_hz = ios->clock; host->spi->max_speed_hz = ios->clock;
status = spi_setup(host->spi); status = spi_setup(host->spi);
dev_dbg(&host->spi->dev, dev_dbg(&host->spi->dev, " clock to %d Hz, %d\n",
"mmc_spi: clock to %d Hz, %d\n",
host->spi->max_speed_hz, status); host->spi->max_speed_hz, status);
} }
} }
......
...@@ -724,10 +724,8 @@ static inline void msdc_dma_setup(struct msdc_host *host, struct msdc_dma *dma, ...@@ -724,10 +724,8 @@ static inline void msdc_dma_setup(struct msdc_host *host, struct msdc_dma *dma,
writel(lower_32_bits(dma->gpd_addr), host->base + MSDC_DMA_SA); writel(lower_32_bits(dma->gpd_addr), host->base + MSDC_DMA_SA);
} }
static void msdc_prepare_data(struct msdc_host *host, struct mmc_request *mrq) static void msdc_prepare_data(struct msdc_host *host, struct mmc_data *data)
{ {
struct mmc_data *data = mrq->data;
if (!(data->host_cookie & MSDC_PREPARE_FLAG)) { if (!(data->host_cookie & MSDC_PREPARE_FLAG)) {
data->host_cookie |= MSDC_PREPARE_FLAG; data->host_cookie |= MSDC_PREPARE_FLAG;
data->sg_count = dma_map_sg(host->dev, data->sg, data->sg_len, data->sg_count = dma_map_sg(host->dev, data->sg, data->sg_len,
...@@ -735,10 +733,8 @@ static void msdc_prepare_data(struct msdc_host *host, struct mmc_request *mrq) ...@@ -735,10 +733,8 @@ static void msdc_prepare_data(struct msdc_host *host, struct mmc_request *mrq)
} }
} }
static void msdc_unprepare_data(struct msdc_host *host, struct mmc_request *mrq) static void msdc_unprepare_data(struct msdc_host *host, struct mmc_data *data)
{ {
struct mmc_data *data = mrq->data;
if (data->host_cookie & MSDC_ASYNC_FLAG) if (data->host_cookie & MSDC_ASYNC_FLAG)
return; return;
...@@ -1140,7 +1136,7 @@ static void msdc_request_done(struct msdc_host *host, struct mmc_request *mrq) ...@@ -1140,7 +1136,7 @@ static void msdc_request_done(struct msdc_host *host, struct mmc_request *mrq)
msdc_track_cmd_data(host, mrq->cmd, mrq->data); msdc_track_cmd_data(host, mrq->cmd, mrq->data);
if (mrq->data) if (mrq->data)
msdc_unprepare_data(host, mrq); msdc_unprepare_data(host, mrq->data);
if (host->error) if (host->error)
msdc_reset_hw(host); msdc_reset_hw(host);
mmc_request_done(mmc_from_priv(host), mrq); mmc_request_done(mmc_from_priv(host), mrq);
...@@ -1311,7 +1307,7 @@ static void msdc_ops_request(struct mmc_host *mmc, struct mmc_request *mrq) ...@@ -1311,7 +1307,7 @@ static void msdc_ops_request(struct mmc_host *mmc, struct mmc_request *mrq)
host->mrq = mrq; host->mrq = mrq;
if (mrq->data) if (mrq->data)
msdc_prepare_data(host, mrq); msdc_prepare_data(host, mrq->data);
/* if SBC is required, we have HW option and SW option. /* if SBC is required, we have HW option and SW option.
* if HW option is enabled, and SBC does not have "special" flags, * if HW option is enabled, and SBC does not have "special" flags,
...@@ -1332,7 +1328,7 @@ static void msdc_pre_req(struct mmc_host *mmc, struct mmc_request *mrq) ...@@ -1332,7 +1328,7 @@ static void msdc_pre_req(struct mmc_host *mmc, struct mmc_request *mrq)
if (!data) if (!data)
return; return;
msdc_prepare_data(host, mrq); msdc_prepare_data(host, data);
data->host_cookie |= MSDC_ASYNC_FLAG; data->host_cookie |= MSDC_ASYNC_FLAG;
} }
...@@ -1340,19 +1336,18 @@ static void msdc_post_req(struct mmc_host *mmc, struct mmc_request *mrq, ...@@ -1340,19 +1336,18 @@ static void msdc_post_req(struct mmc_host *mmc, struct mmc_request *mrq,
int err) int err)
{ {
struct msdc_host *host = mmc_priv(mmc); struct msdc_host *host = mmc_priv(mmc);
struct mmc_data *data; struct mmc_data *data = mrq->data;
data = mrq->data;
if (!data) if (!data)
return; return;
if (data->host_cookie) { if (data->host_cookie) {
data->host_cookie &= ~MSDC_ASYNC_FLAG; data->host_cookie &= ~MSDC_ASYNC_FLAG;
msdc_unprepare_data(host, mrq); msdc_unprepare_data(host, data);
} }
} }
static void msdc_data_xfer_next(struct msdc_host *host, static void msdc_data_xfer_next(struct msdc_host *host, struct mmc_request *mrq)
struct mmc_request *mrq, struct mmc_data *data)
{ {
if (mmc_op_multi(mrq->cmd->opcode) && mrq->stop && !mrq->stop->error && if (mmc_op_multi(mrq->cmd->opcode) && mrq->stop && !mrq->stop->error &&
!mrq->sbc) !mrq->sbc)
...@@ -1411,7 +1406,7 @@ static bool msdc_data_xfer_done(struct msdc_host *host, u32 events, ...@@ -1411,7 +1406,7 @@ static bool msdc_data_xfer_done(struct msdc_host *host, u32 events,
(int)data->error, data->bytes_xfered); (int)data->error, data->bytes_xfered);
} }
msdc_data_xfer_next(host, mrq, data); msdc_data_xfer_next(host, mrq);
done = true; done = true;
} }
return done; return done;
......
...@@ -22,8 +22,8 @@ ...@@ -22,8 +22,8 @@
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
struct of_mmc_spi { struct of_mmc_spi {
int detect_irq;
struct mmc_spi_platform_data pdata; struct mmc_spi_platform_data pdata;
int detect_irq;
}; };
static struct of_mmc_spi *to_of_mmc_spi(struct device *dev) static struct of_mmc_spi *to_of_mmc_spi(struct device *dev)
......
...@@ -704,7 +704,7 @@ static int renesas_sdhi_execute_tuning(struct mmc_host *mmc, u32 opcode) ...@@ -704,7 +704,7 @@ static int renesas_sdhi_execute_tuning(struct mmc_host *mmc, u32 opcode)
set_bit(i, priv->smpcmp); set_bit(i, priv->smpcmp);
if (cmd_error) if (cmd_error)
mmc_abort_tuning(mmc, opcode); mmc_send_abort_tuning(mmc, opcode);
} }
ret = renesas_sdhi_select_tuning(host); ret = renesas_sdhi_select_tuning(host);
......
...@@ -1578,17 +1578,12 @@ static int s3cmci_probe(struct platform_device *pdev) ...@@ -1578,17 +1578,12 @@ static int s3cmci_probe(struct platform_device *pdev)
goto probe_iounmap; goto probe_iounmap;
} }
if (request_irq(host->irq, s3cmci_irq, 0, DRIVER_NAME, host)) { if (request_irq(host->irq, s3cmci_irq, IRQF_NO_AUTOEN, DRIVER_NAME, host)) {
dev_err(&pdev->dev, "failed to request mci interrupt.\n"); dev_err(&pdev->dev, "failed to request mci interrupt.\n");
ret = -ENOENT; ret = -ENOENT;
goto probe_iounmap; goto probe_iounmap;
} }
/* We get spurious interrupts even when we have set the IMSK
* register to ignore everything, so use disable_irq() to make
* ensure we don't lock the system with un-serviceable requests. */
disable_irq(host->irq);
host->irq_state = false; host->irq_state = false;
/* Depending on the dma state, get a DMA channel to use. */ /* Depending on the dma state, get a DMA channel to use. */
......
...@@ -822,6 +822,17 @@ static const struct dmi_system_id sdhci_acpi_quirks[] = { ...@@ -822,6 +822,17 @@ static const struct dmi_system_id sdhci_acpi_quirks[] = {
}, },
.driver_data = (void *)DMI_QUIRK_SD_NO_WRITE_PROTECT, .driver_data = (void *)DMI_QUIRK_SD_NO_WRITE_PROTECT,
}, },
{
/*
* The Toshiba WT8-B's microSD slot always reports the card being
* write-protected.
*/
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
DMI_MATCH(DMI_PRODUCT_NAME, "TOSHIBA ENCORE 2 WT8-B"),
},
.driver_data = (void *)DMI_QUIRK_SD_NO_WRITE_PROTECT,
},
{} /* Terminating entry */ {} /* Terminating entry */
}; };
......
...@@ -324,11 +324,6 @@ static inline int is_imx53_esdhc(struct pltfm_imx_data *data) ...@@ -324,11 +324,6 @@ static inline int is_imx53_esdhc(struct pltfm_imx_data *data)
return data->socdata == &esdhc_imx53_data; return data->socdata == &esdhc_imx53_data;
} }
static inline int is_imx6q_usdhc(struct pltfm_imx_data *data)
{
return data->socdata == &usdhc_imx6q_data;
}
static inline int esdhc_is_usdhc(struct pltfm_imx_data *data) static inline int esdhc_is_usdhc(struct pltfm_imx_data *data)
{ {
return !!(data->socdata->flags & ESDHC_FLAG_USDHC); return !!(data->socdata->flags & ESDHC_FLAG_USDHC);
...@@ -427,9 +422,6 @@ static u32 esdhc_readl_le(struct sdhci_host *host, int reg) ...@@ -427,9 +422,6 @@ static u32 esdhc_readl_le(struct sdhci_host *host, int reg)
| FIELD_PREP(SDHCI_RETUNING_MODE_MASK, | FIELD_PREP(SDHCI_RETUNING_MODE_MASK,
SDHCI_TUNING_MODE_3); SDHCI_TUNING_MODE_3);
if (imx_data->socdata->flags & ESDHC_FLAG_HS400)
val |= SDHCI_SUPPORT_HS400;
/* /*
* Do not advertise faster UHS modes if there are no * Do not advertise faster UHS modes if there are no
* pinctrl states for 100MHz/200MHz. * pinctrl states for 100MHz/200MHz.
...@@ -1591,7 +1583,7 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev) ...@@ -1591,7 +1583,7 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
host->quirks |= SDHCI_QUIRK_BROKEN_ADMA; host->quirks |= SDHCI_QUIRK_BROKEN_ADMA;
if (imx_data->socdata->flags & ESDHC_FLAG_HS400) if (imx_data->socdata->flags & ESDHC_FLAG_HS400)
host->quirks2 |= SDHCI_QUIRK2_CAPS_BIT63_FOR_HS400; host->mmc->caps2 |= MMC_CAP2_HS400;
if (imx_data->socdata->flags & ESDHC_FLAG_BROKEN_AUTO_CMD23) if (imx_data->socdata->flags & ESDHC_FLAG_BROKEN_AUTO_CMD23)
host->quirks2 |= SDHCI_QUIRK2_ACMD23_BROKEN; host->quirks2 |= SDHCI_QUIRK2_ACMD23_BROKEN;
...@@ -1628,6 +1620,14 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev) ...@@ -1628,6 +1620,14 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
if (err) if (err)
goto disable_ahb_clk; goto disable_ahb_clk;
/*
* Setup the wakeup capability here, let user to decide
* whether need to enable this wakeup through sysfs interface.
*/
if ((host->mmc->pm_caps & MMC_PM_KEEP_POWER) &&
(host->mmc->pm_caps & MMC_PM_WAKE_SDIO_IRQ))
device_set_wakeup_capable(&pdev->dev, true);
pm_runtime_set_active(&pdev->dev); pm_runtime_set_active(&pdev->dev);
pm_runtime_set_autosuspend_delay(&pdev->dev, 50); pm_runtime_set_autosuspend_delay(&pdev->dev, 50);
pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_use_autosuspend(&pdev->dev);
......
...@@ -286,11 +286,35 @@ static const struct sdhci_iproc_data bcm2711_data = { ...@@ -286,11 +286,35 @@ static const struct sdhci_iproc_data bcm2711_data = {
.mmc_caps = MMC_CAP_3_3V_DDR, .mmc_caps = MMC_CAP_3_3V_DDR,
}; };
static const struct sdhci_pltfm_data sdhci_bcm7211a0_pltfm_data = {
.quirks = SDHCI_QUIRK_MISSING_CAPS |
SDHCI_QUIRK_BROKEN_TIMEOUT_VAL |
SDHCI_QUIRK_BROKEN_DMA |
SDHCI_QUIRK_BROKEN_ADMA,
.ops = &sdhci_iproc_ops,
};
#define BCM7211A0_BASE_CLK_MHZ 100
static const struct sdhci_iproc_data bcm7211a0_data = {
.pdata = &sdhci_bcm7211a0_pltfm_data,
.caps = ((BCM7211A0_BASE_CLK_MHZ / 2) << SDHCI_TIMEOUT_CLK_SHIFT) |
(BCM7211A0_BASE_CLK_MHZ << SDHCI_CLOCK_BASE_SHIFT) |
((0x2 << SDHCI_MAX_BLOCK_SHIFT)
& SDHCI_MAX_BLOCK_MASK) |
SDHCI_CAN_VDD_330 |
SDHCI_CAN_VDD_180 |
SDHCI_CAN_DO_SUSPEND |
SDHCI_CAN_DO_HISPD,
.caps1 = SDHCI_DRIVER_TYPE_C |
SDHCI_DRIVER_TYPE_D,
};
static const struct of_device_id sdhci_iproc_of_match[] = { static const struct of_device_id sdhci_iproc_of_match[] = {
{ .compatible = "brcm,bcm2835-sdhci", .data = &bcm2835_data }, { .compatible = "brcm,bcm2835-sdhci", .data = &bcm2835_data },
{ .compatible = "brcm,bcm2711-emmc2", .data = &bcm2711_data }, { .compatible = "brcm,bcm2711-emmc2", .data = &bcm2711_data },
{ .compatible = "brcm,sdhci-iproc-cygnus", .data = &iproc_cygnus_data}, { .compatible = "brcm,sdhci-iproc-cygnus", .data = &iproc_cygnus_data},
{ .compatible = "brcm,sdhci-iproc", .data = &iproc_data }, { .compatible = "brcm,sdhci-iproc", .data = &iproc_data },
{ .compatible = "brcm,bcm7211a0-sdhci", .data = &bcm7211a0_data },
{ } { }
}; };
MODULE_DEVICE_TABLE(of, sdhci_iproc_of_match); MODULE_DEVICE_TABLE(of, sdhci_iproc_of_match);
...@@ -384,6 +408,11 @@ static int sdhci_iproc_probe(struct platform_device *pdev) ...@@ -384,6 +408,11 @@ static int sdhci_iproc_probe(struct platform_device *pdev)
return ret; return ret;
} }
static void sdhci_iproc_shutdown(struct platform_device *pdev)
{
sdhci_pltfm_suspend(&pdev->dev);
}
static struct platform_driver sdhci_iproc_driver = { static struct platform_driver sdhci_iproc_driver = {
.driver = { .driver = {
.name = "sdhci-iproc", .name = "sdhci-iproc",
...@@ -394,6 +423,7 @@ static struct platform_driver sdhci_iproc_driver = { ...@@ -394,6 +423,7 @@ static struct platform_driver sdhci_iproc_driver = {
}, },
.probe = sdhci_iproc_probe, .probe = sdhci_iproc_probe,
.remove = sdhci_pltfm_unregister, .remove = sdhci_pltfm_unregister,
.shutdown = sdhci_iproc_shutdown,
}; };
module_platform_driver(sdhci_iproc_driver); module_platform_driver(sdhci_iproc_driver);
......
...@@ -31,6 +31,11 @@ ...@@ -31,6 +31,11 @@
#define ASPEED_SDC_S0_PHASE_OUT_EN GENMASK(1, 0) #define ASPEED_SDC_S0_PHASE_OUT_EN GENMASK(1, 0)
#define ASPEED_SDC_PHASE_MAX 31 #define ASPEED_SDC_PHASE_MAX 31
/* SDIO{10,20} */
#define ASPEED_SDC_CAP1_1_8V (0 * 32 + 26)
/* SDIO{14,24} */
#define ASPEED_SDC_CAP2_SDR104 (1 * 32 + 1)
struct aspeed_sdc { struct aspeed_sdc {
struct clk *clk; struct clk *clk;
struct resource *res; struct resource *res;
...@@ -72,6 +77,37 @@ struct aspeed_sdhci { ...@@ -72,6 +77,37 @@ struct aspeed_sdhci {
const struct aspeed_sdhci_phase_desc *phase_desc; const struct aspeed_sdhci_phase_desc *phase_desc;
}; };
/*
* The function sets the mirror register for updating
* capbilities of the current slot.
*
* slot | capability | caps_reg | mirror_reg
* -----|-------------|----------|------------
* 0 | CAP1_1_8V | SDIO140 | SDIO10
* 0 | CAP2_SDR104 | SDIO144 | SDIO14
* 1 | CAP1_1_8V | SDIO240 | SDIO20
* 1 | CAP2_SDR104 | SDIO244 | SDIO24
*/
static void aspeed_sdc_set_slot_capability(struct sdhci_host *host, struct aspeed_sdc *sdc,
int capability, bool enable, u8 slot)
{
u32 mirror_reg_offset;
u32 cap_val;
u8 cap_reg;
if (slot > 1)
return;
cap_reg = capability / 32;
cap_val = sdhci_readl(host, 0x40 + (cap_reg * 4));
if (enable)
cap_val |= BIT(capability % 32);
else
cap_val &= ~BIT(capability % 32);
mirror_reg_offset = ((slot + 1) * 0x10) + (cap_reg * 4);
writel(cap_val, sdc->regs + mirror_reg_offset);
}
static void aspeed_sdc_configure_8bit_mode(struct aspeed_sdc *sdc, static void aspeed_sdc_configure_8bit_mode(struct aspeed_sdc *sdc,
struct aspeed_sdhci *sdhci, struct aspeed_sdhci *sdhci,
bool bus8) bool bus8)
...@@ -150,7 +186,7 @@ static int aspeed_sdhci_phase_to_tap(struct device *dev, unsigned long rate_hz, ...@@ -150,7 +186,7 @@ static int aspeed_sdhci_phase_to_tap(struct device *dev, unsigned long rate_hz,
tap = div_u64(phase_period_ps, prop_delay_ps); tap = div_u64(phase_period_ps, prop_delay_ps);
if (tap > ASPEED_SDHCI_NR_TAPS) { if (tap > ASPEED_SDHCI_NR_TAPS) {
dev_warn(dev, dev_dbg(dev,
"Requested out of range phase tap %d for %d degrees of phase compensation at %luHz, clamping to tap %d\n", "Requested out of range phase tap %d for %d degrees of phase compensation at %luHz, clamping to tap %d\n",
tap, phase_deg, rate_hz, ASPEED_SDHCI_NR_TAPS); tap, phase_deg, rate_hz, ASPEED_SDHCI_NR_TAPS);
tap = ASPEED_SDHCI_NR_TAPS; tap = ASPEED_SDHCI_NR_TAPS;
...@@ -328,6 +364,7 @@ static inline int aspeed_sdhci_calculate_slot(struct aspeed_sdhci *dev, ...@@ -328,6 +364,7 @@ static inline int aspeed_sdhci_calculate_slot(struct aspeed_sdhci *dev,
static int aspeed_sdhci_probe(struct platform_device *pdev) static int aspeed_sdhci_probe(struct platform_device *pdev)
{ {
const struct aspeed_sdhci_pdata *aspeed_pdata; const struct aspeed_sdhci_pdata *aspeed_pdata;
struct device_node *np = pdev->dev.of_node;
struct sdhci_pltfm_host *pltfm_host; struct sdhci_pltfm_host *pltfm_host;
struct aspeed_sdhci *dev; struct aspeed_sdhci *dev;
struct sdhci_host *host; struct sdhci_host *host;
...@@ -372,6 +409,17 @@ static int aspeed_sdhci_probe(struct platform_device *pdev) ...@@ -372,6 +409,17 @@ static int aspeed_sdhci_probe(struct platform_device *pdev)
sdhci_get_of_property(pdev); sdhci_get_of_property(pdev);
if (of_property_read_bool(np, "mmc-hs200-1_8v") ||
of_property_read_bool(np, "sd-uhs-sdr104")) {
aspeed_sdc_set_slot_capability(host, dev->parent, ASPEED_SDC_CAP1_1_8V,
true, slot);
}
if (of_property_read_bool(np, "sd-uhs-sdr104")) {
aspeed_sdc_set_slot_capability(host, dev->parent, ASPEED_SDC_CAP2_SDR104,
true, slot);
}
pltfm_host->clk = devm_clk_get(&pdev->dev, NULL); pltfm_host->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(pltfm_host->clk)) if (IS_ERR(pltfm_host->clk))
return PTR_ERR(pltfm_host->clk); return PTR_ERR(pltfm_host->clk);
......
...@@ -1173,10 +1173,9 @@ static int sdhci_omap_probe(struct platform_device *pdev) ...@@ -1173,10 +1173,9 @@ static int sdhci_omap_probe(struct platform_device *pdev)
* as part of pm_runtime_get_sync. * as part of pm_runtime_get_sync.
*/ */
pm_runtime_enable(dev); pm_runtime_enable(dev);
ret = pm_runtime_get_sync(dev); ret = pm_runtime_resume_and_get(dev);
if (ret < 0) { if (ret) {
dev_err(dev, "pm_runtime_get_sync failed\n"); dev_err(dev, "pm_runtime_get_sync failed\n");
pm_runtime_put_noidle(dev);
goto err_rpm_disable; goto err_rpm_disable;
} }
......
...@@ -94,7 +94,7 @@ ...@@ -94,7 +94,7 @@
#define PCIE_GLI_9763E_CFG2 0x8A4 #define PCIE_GLI_9763E_CFG2 0x8A4
#define GLI_9763E_CFG2_L1DLY GENMASK(28, 19) #define GLI_9763E_CFG2_L1DLY GENMASK(28, 19)
#define GLI_9763E_CFG2_L1DLY_MID 0x50 #define GLI_9763E_CFG2_L1DLY_MID 0x54
#define PCIE_GLI_9763E_MMC_CTRL 0x960 #define PCIE_GLI_9763E_MMC_CTRL 0x960
#define GLI_9763E_HS400_SLOW BIT(3) #define GLI_9763E_HS400_SLOW BIT(3)
...@@ -847,7 +847,7 @@ static void gli_set_gl9763e(struct sdhci_pci_slot *slot) ...@@ -847,7 +847,7 @@ static void gli_set_gl9763e(struct sdhci_pci_slot *slot)
pci_read_config_dword(pdev, PCIE_GLI_9763E_CFG2, &value); pci_read_config_dword(pdev, PCIE_GLI_9763E_CFG2, &value);
value &= ~GLI_9763E_CFG2_L1DLY; value &= ~GLI_9763E_CFG2_L1DLY;
/* set ASPM L1 entry delay to 20us */ /* set ASPM L1 entry delay to 21us */
value |= FIELD_PREP(GLI_9763E_CFG2_L1DLY, GLI_9763E_CFG2_L1DLY_MID); value |= FIELD_PREP(GLI_9763E_CFG2_L1DLY, GLI_9763E_CFG2_L1DLY_MID);
pci_write_config_dword(pdev, PCIE_GLI_9763E_CFG2, value); pci_write_config_dword(pdev, PCIE_GLI_9763E_CFG2, value);
......
...@@ -393,6 +393,7 @@ static void sdhci_sprd_request_done(struct sdhci_host *host, ...@@ -393,6 +393,7 @@ static void sdhci_sprd_request_done(struct sdhci_host *host,
static struct sdhci_ops sdhci_sprd_ops = { static struct sdhci_ops sdhci_sprd_ops = {
.read_l = sdhci_sprd_readl, .read_l = sdhci_sprd_readl,
.write_l = sdhci_sprd_writel, .write_l = sdhci_sprd_writel,
.write_w = sdhci_sprd_writew,
.write_b = sdhci_sprd_writeb, .write_b = sdhci_sprd_writeb,
.set_clock = sdhci_sprd_set_clock, .set_clock = sdhci_sprd_set_clock,
.get_max_clock = sdhci_sprd_get_max_clock, .get_max_clock = sdhci_sprd_get_max_clock,
......
...@@ -2680,7 +2680,7 @@ void sdhci_abort_tuning(struct sdhci_host *host, u32 opcode) ...@@ -2680,7 +2680,7 @@ void sdhci_abort_tuning(struct sdhci_host *host, u32 opcode)
sdhci_end_tuning(host); sdhci_end_tuning(host);
mmc_abort_tuning(host->mmc, opcode); mmc_send_abort_tuning(host->mmc, opcode);
} }
EXPORT_SYMBOL_GPL(sdhci_abort_tuning); EXPORT_SYMBOL_GPL(sdhci_abort_tuning);
......
...@@ -201,8 +201,10 @@ ...@@ -201,8 +201,10 @@
#define SDHCI_CAPABILITIES 0x40 #define SDHCI_CAPABILITIES 0x40
#define SDHCI_TIMEOUT_CLK_MASK GENMASK(5, 0) #define SDHCI_TIMEOUT_CLK_MASK GENMASK(5, 0)
#define SDHCI_TIMEOUT_CLK_SHIFT 0
#define SDHCI_TIMEOUT_CLK_UNIT 0x00000080 #define SDHCI_TIMEOUT_CLK_UNIT 0x00000080
#define SDHCI_CLOCK_BASE_MASK GENMASK(13, 8) #define SDHCI_CLOCK_BASE_MASK GENMASK(13, 8)
#define SDHCI_CLOCK_BASE_SHIFT 8
#define SDHCI_CLOCK_V3_BASE_MASK GENMASK(15, 8) #define SDHCI_CLOCK_V3_BASE_MASK GENMASK(15, 8)
#define SDHCI_MAX_BLOCK_MASK 0x00030000 #define SDHCI_MAX_BLOCK_MASK 0x00030000
#define SDHCI_MAX_BLOCK_SHIFT 16 #define SDHCI_MAX_BLOCK_SHIFT 16
......
...@@ -809,11 +809,9 @@ static int sdhci_am654_probe(struct platform_device *pdev) ...@@ -809,11 +809,9 @@ static int sdhci_am654_probe(struct platform_device *pdev)
/* Clocks are enabled using pm_runtime */ /* Clocks are enabled using pm_runtime */
pm_runtime_enable(dev); pm_runtime_enable(dev);
ret = pm_runtime_get_sync(dev); ret = pm_runtime_resume_and_get(dev);
if (ret < 0) { if (ret)
pm_runtime_put_noidle(dev);
goto pm_runtime_disable; goto pm_runtime_disable;
}
base = devm_platform_ioremap_resource(pdev, 1); base = devm_platform_ioremap_resource(pdev, 1);
if (IS_ERR(base)) { if (IS_ERR(base)) {
......
...@@ -1801,6 +1801,7 @@ static int usdhi6_probe(struct platform_device *pdev) ...@@ -1801,6 +1801,7 @@ static int usdhi6_probe(struct platform_device *pdev)
version = usdhi6_read(host, USDHI6_VERSION); version = usdhi6_read(host, USDHI6_VERSION);
if ((version & 0xfff) != 0xa0d) { if ((version & 0xfff) != 0xa0d) {
ret = -EPERM;
dev_err(dev, "Version not recognized %x\n", version); dev_err(dev, "Version not recognized %x\n", version);
goto e_clk_off; goto e_clk_off;
} }
......
...@@ -857,6 +857,9 @@ static void via_sdc_data_isr(struct via_crdr_mmc_host *host, u16 intmask) ...@@ -857,6 +857,9 @@ static void via_sdc_data_isr(struct via_crdr_mmc_host *host, u16 intmask)
{ {
BUG_ON(intmask == 0); BUG_ON(intmask == 0);
if (!host->data)
return;
if (intmask & VIA_CRDR_SDSTS_DT) if (intmask & VIA_CRDR_SDSTS_DT)
host->data->error = -ETIMEDOUT; host->data->error = -ETIMEDOUT;
else if (intmask & (VIA_CRDR_SDSTS_RC | VIA_CRDR_SDSTS_WC)) else if (intmask & (VIA_CRDR_SDSTS_RC | VIA_CRDR_SDSTS_WC))
......
...@@ -2279,7 +2279,7 @@ static int vub300_probe(struct usb_interface *interface, ...@@ -2279,7 +2279,7 @@ static int vub300_probe(struct usb_interface *interface,
if (retval < 0) if (retval < 0)
goto error5; goto error5;
retval = retval =
usb_control_msg(vub300->udev, usb_rcvctrlpipe(vub300->udev, 0), usb_control_msg(vub300->udev, usb_sndctrlpipe(vub300->udev, 0),
SET_ROM_WAIT_STATES, SET_ROM_WAIT_STATES,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
firmware_rom_wait_states, 0x0000, NULL, 0, HZ); firmware_rom_wait_states, 0x0000, NULL, 0, HZ);
......
...@@ -139,6 +139,8 @@ struct sd_scr { ...@@ -139,6 +139,8 @@ struct sd_scr {
unsigned char cmds; unsigned char cmds;
#define SD_SCR_CMD20_SUPPORT (1<<0) #define SD_SCR_CMD20_SUPPORT (1<<0)
#define SD_SCR_CMD23_SUPPORT (1<<1) #define SD_SCR_CMD23_SUPPORT (1<<1)
#define SD_SCR_CMD48_SUPPORT (1<<2)
#define SD_SCR_CMD58_SUPPORT (1<<3)
}; };
struct sd_ssr { struct sd_ssr {
...@@ -189,6 +191,25 @@ struct sd_switch_caps { ...@@ -189,6 +191,25 @@ struct sd_switch_caps {
#define SD_MAX_CURRENT_800 (1 << SD_SET_CURRENT_LIMIT_800) #define SD_MAX_CURRENT_800 (1 << SD_SET_CURRENT_LIMIT_800)
}; };
struct sd_ext_reg {
u8 fno;
u8 page;
u16 offset;
u8 rev;
u8 feature_enabled;
u8 feature_support;
/* Power Management Function. */
#define SD_EXT_POWER_OFF_NOTIFY (1<<0)
#define SD_EXT_POWER_SUSTENANCE (1<<1)
#define SD_EXT_POWER_DOWN_MODE (1<<2)
/* Performance Enhancement Function. */
#define SD_EXT_PERF_FX_EVENT (1<<0)
#define SD_EXT_PERF_CARD_MAINT (1<<1)
#define SD_EXT_PERF_HOST_MAINT (1<<2)
#define SD_EXT_PERF_CACHE (1<<3)
#define SD_EXT_PERF_CMD_QUEUE (1<<4)
};
struct sdio_cccr { struct sdio_cccr {
unsigned int sdio_vsn; unsigned int sdio_vsn;
unsigned int sd_vsn; unsigned int sd_vsn;
...@@ -290,6 +311,8 @@ struct mmc_card { ...@@ -290,6 +311,8 @@ struct mmc_card {
struct sd_scr scr; /* extra SD information */ struct sd_scr scr; /* extra SD information */
struct sd_ssr ssr; /* yet more SD information */ struct sd_ssr ssr; /* yet more SD information */
struct sd_switch_caps sw_caps; /* switch (CMD6) caps */ struct sd_switch_caps sw_caps; /* switch (CMD6) caps */
struct sd_ext_reg ext_power; /* SD extension reg for PM */
struct sd_ext_reg ext_perf; /* SD extension reg for PERF */
unsigned int sdio_funcs; /* number of SDIO functions */ unsigned int sdio_funcs; /* number of SDIO functions */
atomic_t sdio_funcs_probed; /* number of probed SDIO funcs */ atomic_t sdio_funcs_probed; /* number of probed SDIO funcs */
......
...@@ -632,6 +632,6 @@ static inline enum dma_data_direction mmc_get_dma_dir(struct mmc_data *data) ...@@ -632,6 +632,6 @@ static inline enum dma_data_direction mmc_get_dma_dir(struct mmc_data *data)
} }
int mmc_send_tuning(struct mmc_host *host, u32 opcode, int *cmd_error); int mmc_send_tuning(struct mmc_host *host, u32 opcode, int *cmd_error);
int mmc_abort_tuning(struct mmc_host *host, u32 opcode); int mmc_send_abort_tuning(struct mmc_host *host, u32 opcode);
#endif /* LINUX_MMC_HOST_H */ #endif /* LINUX_MMC_HOST_H */
...@@ -29,6 +29,10 @@ ...@@ -29,6 +29,10 @@
#define SD_APP_OP_COND 41 /* bcr [31:0] OCR R3 */ #define SD_APP_OP_COND 41 /* bcr [31:0] OCR R3 */
#define SD_APP_SEND_SCR 51 /* adtc R1 */ #define SD_APP_SEND_SCR 51 /* adtc R1 */
/* class 11 */
#define SD_READ_EXTR_SINGLE 48 /* adtc [31:0] R1 */
#define SD_WRITE_EXTR_SINGLE 49 /* adtc [31:0] R1 */
/* OCR bit definitions */ /* OCR bit definitions */
#define SD_OCR_S18R (1 << 24) /* 1.8V switching request */ #define SD_OCR_S18R (1 << 24) /* 1.8V switching request */
#define SD_ROCR_S18A SD_OCR_S18R /* 1.8V switching accepted by card */ #define SD_ROCR_S18A SD_OCR_S18R /* 1.8V switching accepted by card */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment