mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 03:15:31 +09:00
Merge 5bebe2c9ae ("Merge tag 'mmc-v5.18' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc") into android-mainline
Steps on the way to 5.18-rc1 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: I2875a49300a6e99c263a8cec36ac4a98c98af8aa
This commit is contained in:
@@ -24,6 +24,7 @@ properties:
|
||||
- const: allwinner,sun7i-a20-mmc
|
||||
- const: allwinner,sun8i-a83t-emmc
|
||||
- const: allwinner,sun9i-a80-mmc
|
||||
- const: allwinner,sun20i-d1-mmc
|
||||
- const: allwinner,sun50i-a64-emmc
|
||||
- const: allwinner,sun50i-a64-mmc
|
||||
- const: allwinner,sun50i-a100-emmc
|
||||
@@ -49,12 +50,18 @@ properties:
|
||||
- items:
|
||||
- const: allwinner,sun50i-h6-mmc
|
||||
- const: allwinner,sun50i-a64-mmc
|
||||
- items:
|
||||
- const: allwinner,sun20i-d1-emmc
|
||||
- const: allwinner,sun50i-a100-emmc
|
||||
- items:
|
||||
- const: allwinner,sun50i-h616-emmc
|
||||
- const: allwinner,sun50i-a100-emmc
|
||||
- items:
|
||||
- const: allwinner,sun50i-h616-mmc
|
||||
- const: allwinner,sun50i-a100-mmc
|
||||
- items:
|
||||
- const: allwinner,suniv-f1c100s-mmc
|
||||
- const: allwinner,sun7i-a20-mmc
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
@@ -47,6 +47,7 @@ properties:
|
||||
- const: fsl,imx7d-usdhc
|
||||
- items:
|
||||
- enum:
|
||||
- fsl,imx93-usdhc
|
||||
- fsl,imx8ulp-usdhc
|
||||
- const: fsl,imx8mm-usdhc
|
||||
|
||||
|
||||
78
Documentation/devicetree/bindings/mmc/litex,mmc.yaml
Normal file
78
Documentation/devicetree/bindings/mmc/litex,mmc.yaml
Normal file
@@ -0,0 +1,78 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/mmc/litex,mmc.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: LiteX LiteSDCard device
|
||||
|
||||
maintainers:
|
||||
- Gabriel Somlo <gsomlo@gmail.com>
|
||||
|
||||
description: |
|
||||
LiteSDCard is a small footprint, configurable SDCard core for FPGA based
|
||||
system on chips.
|
||||
|
||||
The hardware source is Open Source and can be found on at
|
||||
https://github.com/enjoy-digital/litesdcard/.
|
||||
|
||||
allOf:
|
||||
- $ref: mmc-controller.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: litex,mmc
|
||||
|
||||
reg:
|
||||
items:
|
||||
- description: PHY registers
|
||||
- description: CORE registers
|
||||
- description: DMA Reader buffer
|
||||
- description: DMA Writer buffer
|
||||
- description: IRQ registers
|
||||
minItems: 4
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: phy
|
||||
- const: core
|
||||
- const: reader
|
||||
- const: writer
|
||||
- const: irq
|
||||
minItems: 4
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
description:
|
||||
Handle to reference clock.
|
||||
|
||||
vmmc-supply:
|
||||
description:
|
||||
Handle to fixed-voltage supply for the card power.
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- clocks
|
||||
- vmmc-supply
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
mmc: mmc@12005000 {
|
||||
compatible = "litex,mmc";
|
||||
reg = <0x12005000 0x100>,
|
||||
<0x12003800 0x100>,
|
||||
<0x12003000 0x100>,
|
||||
<0x12004800 0x100>,
|
||||
<0x12004000 0x100>;
|
||||
reg-names = "phy", "core", "reader", "writer", "irq";
|
||||
clocks = <&reference_clk>;
|
||||
vmmc-supply = <&vreg_mmc>;
|
||||
interrupts = <4>;
|
||||
};
|
||||
@@ -29,6 +29,9 @@ properties:
|
||||
- items:
|
||||
- const: mediatek,mt7623-mmc
|
||||
- const: mediatek,mt2701-mmc
|
||||
- items:
|
||||
- const: mediatek,mt8186-mmc
|
||||
- const: mediatek,mt8183-mmc
|
||||
- items:
|
||||
- const: mediatek,mt8192-mmc
|
||||
- const: mediatek,mt8183-mmc
|
||||
|
||||
@@ -57,7 +57,9 @@ properties:
|
||||
- renesas,sdhi-r8a77990 # R-Car E3
|
||||
- renesas,sdhi-r8a77995 # R-Car D3
|
||||
- renesas,sdhi-r8a779a0 # R-Car V3U
|
||||
- renesas,sdhi-r9a07g043 # RZ/G2UL
|
||||
- renesas,sdhi-r9a07g044 # RZ/G2{L,LC}
|
||||
- renesas,sdhi-r9a07g054 # RZ/V2L
|
||||
- const: renesas,rcar-gen3-sdhi # R-Car Gen3 or RZ/G2
|
||||
|
||||
reg:
|
||||
@@ -107,7 +109,10 @@ allOf:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: renesas,sdhi-r9a07g044
|
||||
enum:
|
||||
- renesas,sdhi-r9a07g043
|
||||
- renesas,sdhi-r9a07g044
|
||||
- renesas,sdhi-r9a07g054
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
|
||||
@@ -21,6 +21,7 @@ properties:
|
||||
- const: ti,j721e-sdhci-4bit
|
||||
- const: ti,am64-sdhci-8bit
|
||||
- const: ti,am64-sdhci-4bit
|
||||
- const: ti,am62-sdhci
|
||||
- items:
|
||||
- const: ti,j7200-sdhci-8bit
|
||||
- const: ti,j721e-sdhci-8bit
|
||||
|
||||
@@ -14,6 +14,7 @@ Required properties:
|
||||
full compatible strings with SoC and version:
|
||||
"qcom,apq8084-sdhci", "qcom,sdhci-msm-v4"
|
||||
"qcom,msm8226-sdhci", "qcom,sdhci-msm-v4"
|
||||
"qcom,msm8953-sdhci", "qcom,sdhci-msm-v4"
|
||||
"qcom,msm8974-sdhci", "qcom,sdhci-msm-v4"
|
||||
"qcom,msm8916-sdhci", "qcom,sdhci-msm-v4"
|
||||
"qcom,msm8992-sdhci", "qcom,sdhci-msm-v4"
|
||||
|
||||
@@ -11165,12 +11165,17 @@ F: lib/list-test.c
|
||||
LITEX PLATFORM
|
||||
M: Karol Gugala <kgugala@antmicro.com>
|
||||
M: Mateusz Holenko <mholenko@antmicro.com>
|
||||
M: Gabriel Somlo <gsomlo@gmail.com>
|
||||
M: Joel Stanley <joel@jms.id.au>
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/*/litex,*.yaml
|
||||
F: arch/openrisc/boot/dts/or1klitex.dts
|
||||
F: drivers/soc/litex/litex_soc_ctrl.c
|
||||
F: drivers/tty/serial/liteuart.c
|
||||
F: include/linux/litex.h
|
||||
F: drivers/tty/serial/liteuart.c
|
||||
F: drivers/soc/litex/*
|
||||
F: drivers/net/ethernet/litex/*
|
||||
F: drivers/mmc/host/litex_mmc.c
|
||||
N: litex
|
||||
|
||||
LIVE PATCHING
|
||||
M: Josh Poimboeuf <jpoimboe@redhat.com>
|
||||
|
||||
@@ -115,14 +115,14 @@ config SATA_AHCI
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config SATA_MOBILE_LPM_POLICY
|
||||
int "Default SATA Link Power Management policy for mobile chipsets"
|
||||
config SATA_LPM_POLICY
|
||||
int "Default SATA Link Power Management policy for low power chipsets"
|
||||
range 0 4
|
||||
default 0
|
||||
depends on SATA_AHCI
|
||||
help
|
||||
Select the Default SATA Link Power Management (LPM) policy to use
|
||||
for mobile / laptop variants of chipsets / "South Bridges".
|
||||
for chipsets / "South Bridges" designated as supporting low power.
|
||||
|
||||
The value set has the following meanings:
|
||||
0 => Keep firmware settings
|
||||
@@ -283,7 +283,7 @@ config SATA_FSL
|
||||
|
||||
config SATA_GEMINI
|
||||
tristate "Gemini SATA bridge support"
|
||||
depends on ARCH_GEMINI || COMPILE_TEST
|
||||
depends on ARCH_GEMINI || (OF && COMPILE_TEST)
|
||||
select SATA_HOST
|
||||
default ARCH_GEMINI
|
||||
help
|
||||
|
||||
@@ -265,7 +265,7 @@ static bool acard_ahci_qc_fill_rtf(struct ata_queued_cmd *qc)
|
||||
if (qc->tf.protocol == ATA_PROT_PIO && qc->dma_dir == DMA_FROM_DEVICE &&
|
||||
!(qc->flags & ATA_QCFLAG_FAILED)) {
|
||||
ata_tf_from_fis(rx_fis + RX_FIS_PIO_SETUP, &qc->result_tf);
|
||||
qc->result_tf.command = (rx_fis + RX_FIS_PIO_SETUP)[15];
|
||||
qc->result_tf.status = (rx_fis + RX_FIS_PIO_SETUP)[15];
|
||||
} else
|
||||
ata_tf_from_fis(rx_fis + RX_FIS_D2H_REG, &qc->result_tf);
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ enum board_ids {
|
||||
/* board IDs by feature in alphabetical order */
|
||||
board_ahci,
|
||||
board_ahci_ign_iferr,
|
||||
board_ahci_mobile,
|
||||
board_ahci_low_power,
|
||||
board_ahci_no_debounce_delay,
|
||||
board_ahci_nomsi,
|
||||
board_ahci_noncq,
|
||||
@@ -135,8 +135,8 @@ static const struct ata_port_info ahci_port_info[] = {
|
||||
.udma_mask = ATA_UDMA6,
|
||||
.port_ops = &ahci_ops,
|
||||
},
|
||||
[board_ahci_mobile] = {
|
||||
AHCI_HFLAGS (AHCI_HFLAG_IS_MOBILE),
|
||||
[board_ahci_low_power] = {
|
||||
AHCI_HFLAGS (AHCI_HFLAG_USE_LPM_POLICY),
|
||||
.flags = AHCI_FLAG_COMMON,
|
||||
.pio_mask = ATA_PIO4,
|
||||
.udma_mask = ATA_UDMA6,
|
||||
@@ -275,13 +275,13 @@ static const struct pci_device_id ahci_pci_tbl[] = {
|
||||
{ PCI_VDEVICE(INTEL, 0x2924), board_ahci }, /* ICH9 */
|
||||
{ PCI_VDEVICE(INTEL, 0x2925), board_ahci }, /* ICH9 */
|
||||
{ PCI_VDEVICE(INTEL, 0x2927), board_ahci }, /* ICH9 */
|
||||
{ PCI_VDEVICE(INTEL, 0x2929), board_ahci_mobile }, /* ICH9M */
|
||||
{ PCI_VDEVICE(INTEL, 0x292a), board_ahci_mobile }, /* ICH9M */
|
||||
{ PCI_VDEVICE(INTEL, 0x292b), board_ahci_mobile }, /* ICH9M */
|
||||
{ PCI_VDEVICE(INTEL, 0x292c), board_ahci_mobile }, /* ICH9M */
|
||||
{ PCI_VDEVICE(INTEL, 0x292f), board_ahci_mobile }, /* ICH9M */
|
||||
{ PCI_VDEVICE(INTEL, 0x2929), board_ahci_low_power }, /* ICH9M */
|
||||
{ PCI_VDEVICE(INTEL, 0x292a), board_ahci_low_power }, /* ICH9M */
|
||||
{ PCI_VDEVICE(INTEL, 0x292b), board_ahci_low_power }, /* ICH9M */
|
||||
{ PCI_VDEVICE(INTEL, 0x292c), board_ahci_low_power }, /* ICH9M */
|
||||
{ PCI_VDEVICE(INTEL, 0x292f), board_ahci_low_power }, /* ICH9M */
|
||||
{ PCI_VDEVICE(INTEL, 0x294d), board_ahci }, /* ICH9 */
|
||||
{ PCI_VDEVICE(INTEL, 0x294e), board_ahci_mobile }, /* ICH9M */
|
||||
{ PCI_VDEVICE(INTEL, 0x294e), board_ahci_low_power }, /* ICH9M */
|
||||
{ PCI_VDEVICE(INTEL, 0x502a), board_ahci }, /* Tolapai */
|
||||
{ PCI_VDEVICE(INTEL, 0x502b), board_ahci }, /* Tolapai */
|
||||
{ PCI_VDEVICE(INTEL, 0x3a05), board_ahci }, /* ICH10 */
|
||||
@@ -291,9 +291,9 @@ static const struct pci_device_id ahci_pci_tbl[] = {
|
||||
{ PCI_VDEVICE(INTEL, 0x3b23), board_ahci }, /* PCH AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x3b24), board_ahci }, /* PCH RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x3b25), board_ahci }, /* PCH RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x3b29), board_ahci_mobile }, /* PCH M AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x3b29), board_ahci_low_power }, /* PCH M AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x3b2b), board_ahci }, /* PCH RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x3b2c), board_ahci_mobile }, /* PCH M RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x3b2c), board_ahci_low_power }, /* PCH M RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x3b2f), board_ahci }, /* PCH AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x19b0), board_ahci_pcs7 }, /* DNV AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x19b1), board_ahci_pcs7 }, /* DNV AHCI */
|
||||
@@ -316,9 +316,9 @@ static const struct pci_device_id ahci_pci_tbl[] = {
|
||||
{ PCI_VDEVICE(INTEL, 0x19cE), board_ahci_pcs7 }, /* DNV AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x19cF), board_ahci_pcs7 }, /* DNV AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x1c02), board_ahci }, /* CPT AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x1c03), board_ahci_mobile }, /* CPT M AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x1c03), board_ahci_low_power }, /* CPT M AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x1c04), board_ahci }, /* CPT RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x1c05), board_ahci_mobile }, /* CPT M RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x1c05), board_ahci_low_power }, /* CPT M RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x1c06), board_ahci }, /* CPT RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x1c07), board_ahci }, /* CPT RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x1d02), board_ahci }, /* PBG AHCI */
|
||||
@@ -327,29 +327,29 @@ static const struct pci_device_id ahci_pci_tbl[] = {
|
||||
{ PCI_VDEVICE(INTEL, 0x2826), board_ahci }, /* PBG/Lewisburg RAID*/
|
||||
{ PCI_VDEVICE(INTEL, 0x2323), board_ahci }, /* DH89xxCC AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x1e02), board_ahci }, /* Panther Point AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x1e03), board_ahci_mobile }, /* Panther M AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x1e03), board_ahci_low_power }, /* Panther M AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x1e04), board_ahci }, /* Panther Point RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x1e05), board_ahci }, /* Panther Point RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x1e06), board_ahci }, /* Panther Point RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x1e07), board_ahci_mobile }, /* Panther M RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x1e07), board_ahci_low_power }, /* Panther M RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x1e0e), board_ahci }, /* Panther Point RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x8c02), board_ahci }, /* Lynx Point AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x8c03), board_ahci_mobile }, /* Lynx M AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x8c03), board_ahci_low_power }, /* Lynx M AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x8c04), board_ahci }, /* Lynx Point RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x8c05), board_ahci_mobile }, /* Lynx M RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x8c05), board_ahci_low_power }, /* Lynx M RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x8c06), board_ahci }, /* Lynx Point RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x8c07), board_ahci_mobile }, /* Lynx M RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x8c07), board_ahci_low_power }, /* Lynx M RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x8c0e), board_ahci }, /* Lynx Point RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x8c0f), board_ahci_mobile }, /* Lynx M RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x9c02), board_ahci_mobile }, /* Lynx LP AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x9c03), board_ahci_mobile }, /* Lynx LP AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x9c04), board_ahci_mobile }, /* Lynx LP RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x9c05), board_ahci_mobile }, /* Lynx LP RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x9c06), board_ahci_mobile }, /* Lynx LP RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x9c07), board_ahci_mobile }, /* Lynx LP RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x9c0e), board_ahci_mobile }, /* Lynx LP RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x9c0f), board_ahci_mobile }, /* Lynx LP RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x9dd3), board_ahci_mobile }, /* Cannon Lake PCH-LP AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x8c0f), board_ahci_low_power }, /* Lynx M RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x9c02), board_ahci_low_power }, /* Lynx LP AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x9c03), board_ahci_low_power }, /* Lynx LP AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x9c04), board_ahci_low_power }, /* Lynx LP RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x9c05), board_ahci_low_power }, /* Lynx LP RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x9c06), board_ahci_low_power }, /* Lynx LP RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x9c07), board_ahci_low_power }, /* Lynx LP RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x9c0e), board_ahci_low_power }, /* Lynx LP RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x9c0f), board_ahci_low_power }, /* Lynx LP RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x9dd3), board_ahci_low_power }, /* Cannon Lake PCH-LP AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x1f22), board_ahci }, /* Avoton AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x1f23), board_ahci }, /* Avoton AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x1f24), board_ahci }, /* Avoton RAID */
|
||||
@@ -381,26 +381,26 @@ static const struct pci_device_id ahci_pci_tbl[] = {
|
||||
{ PCI_VDEVICE(INTEL, 0x8d66), board_ahci }, /* Wellsburg RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x8d6e), board_ahci }, /* Wellsburg RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x23a3), board_ahci }, /* Coleto Creek AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x9c83), board_ahci_mobile }, /* Wildcat LP AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x9c85), board_ahci_mobile }, /* Wildcat LP RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x9c87), board_ahci_mobile }, /* Wildcat LP RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x9c8f), board_ahci_mobile }, /* Wildcat LP RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x9c83), board_ahci_low_power }, /* Wildcat LP AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x9c85), board_ahci_low_power }, /* Wildcat LP RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x9c87), board_ahci_low_power }, /* Wildcat LP RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x9c8f), board_ahci_low_power }, /* Wildcat LP RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x8c82), board_ahci }, /* 9 Series AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x8c83), board_ahci_mobile }, /* 9 Series M AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x8c83), board_ahci_low_power }, /* 9 Series M AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x8c84), board_ahci }, /* 9 Series RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x8c85), board_ahci_mobile }, /* 9 Series M RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x8c85), board_ahci_low_power }, /* 9 Series M RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x8c86), board_ahci }, /* 9 Series RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x8c87), board_ahci_mobile }, /* 9 Series M RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x8c87), board_ahci_low_power }, /* 9 Series M RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x8c8e), board_ahci }, /* 9 Series RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x8c8f), board_ahci_mobile }, /* 9 Series M RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x9d03), board_ahci_mobile }, /* Sunrise LP AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x9d05), board_ahci_mobile }, /* Sunrise LP RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x9d07), board_ahci_mobile }, /* Sunrise LP RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x8c8f), board_ahci_low_power }, /* 9 Series M RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x9d03), board_ahci_low_power }, /* Sunrise LP AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x9d05), board_ahci_low_power }, /* Sunrise LP RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x9d07), board_ahci_low_power }, /* Sunrise LP RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0xa102), board_ahci }, /* Sunrise Point-H AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0xa103), board_ahci_mobile }, /* Sunrise M AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0xa103), board_ahci_low_power }, /* Sunrise M AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0xa105), board_ahci }, /* Sunrise Point-H RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0xa106), board_ahci }, /* Sunrise Point-H RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0xa107), board_ahci_mobile }, /* Sunrise M RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0xa107), board_ahci_low_power }, /* Sunrise M RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0xa10f), board_ahci }, /* Sunrise Point-H RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0xa182), board_ahci }, /* Lewisburg AHCI*/
|
||||
{ PCI_VDEVICE(INTEL, 0xa186), board_ahci }, /* Lewisburg RAID*/
|
||||
@@ -413,13 +413,13 @@ static const struct pci_device_id ahci_pci_tbl[] = {
|
||||
{ PCI_VDEVICE(INTEL, 0xa356), board_ahci }, /* Cannon Lake PCH-H RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x06d7), board_ahci }, /* Comet Lake-H RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0xa386), board_ahci }, /* Comet Lake PCH-V RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x0f22), board_ahci_mobile }, /* Bay Trail AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x0f23), board_ahci_mobile }, /* Bay Trail AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x22a3), board_ahci_mobile }, /* Cherry Tr. AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x5ae3), board_ahci_mobile }, /* ApolloLake AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x34d3), board_ahci_mobile }, /* Ice Lake LP AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x02d3), board_ahci_mobile }, /* Comet Lake PCH-U AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x02d7), board_ahci_mobile }, /* Comet Lake PCH RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x0f22), board_ahci_low_power }, /* Bay Trail AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x0f23), board_ahci_low_power }, /* Bay Trail AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x22a3), board_ahci_low_power }, /* Cherry Tr. AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x5ae3), board_ahci_low_power }, /* ApolloLake AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x34d3), board_ahci_low_power }, /* Ice Lake LP AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x02d3), board_ahci_low_power }, /* Comet Lake PCH-U AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x02d7), board_ahci_low_power }, /* Comet Lake PCH RAID */
|
||||
|
||||
/* JMicron 360/1/3/5/6, match class to avoid IDE function */
|
||||
{ PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
|
||||
@@ -447,7 +447,7 @@ static const struct pci_device_id ahci_pci_tbl[] = {
|
||||
{ PCI_VDEVICE(AMD, 0x7800), board_ahci }, /* AMD Hudson-2 */
|
||||
{ PCI_VDEVICE(AMD, 0x7801), board_ahci_no_debounce_delay }, /* AMD Hudson-2 (AHCI mode) */
|
||||
{ PCI_VDEVICE(AMD, 0x7900), board_ahci }, /* AMD CZ */
|
||||
{ PCI_VDEVICE(AMD, 0x7901), board_ahci_mobile }, /* AMD Green Sardine */
|
||||
{ PCI_VDEVICE(AMD, 0x7901), board_ahci_low_power }, /* AMD Green Sardine */
|
||||
/* AMD is using RAID class only for ahci controllers */
|
||||
{ PCI_VENDOR_ID_AMD, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
|
||||
PCI_CLASS_STORAGE_RAID << 8, 0xffffff, board_ahci },
|
||||
@@ -582,6 +582,8 @@ static const struct pci_device_id ahci_pci_tbl[] = {
|
||||
.driver_data = board_ahci_yes_fbs },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9230),
|
||||
.driver_data = board_ahci_yes_fbs },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9235),
|
||||
.driver_data = board_ahci_no_debounce_delay },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_TTI, 0x0642), /* highpoint rocketraid 642L */
|
||||
.driver_data = board_ahci_yes_fbs },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_TTI, 0x0645), /* highpoint rocketraid 644L */
|
||||
@@ -737,7 +739,7 @@ static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class,
|
||||
|
||||
/* clear D2H reception area to properly wait for D2H FIS */
|
||||
ata_tf_init(link->device, &tf);
|
||||
tf.command = ATA_BUSY;
|
||||
tf.status = ATA_BUSY;
|
||||
ata_tf_to_fis(&tf, 0, 0, d2h_fis);
|
||||
|
||||
rc = sata_link_hardreset(link, sata_ehc_deb_timing(&link->eh_context),
|
||||
@@ -806,7 +808,7 @@ static int ahci_avn_hardreset(struct ata_link *link, unsigned int *class,
|
||||
|
||||
/* clear D2H reception area to properly wait for D2H FIS */
|
||||
ata_tf_init(link->device, &tf);
|
||||
tf.command = ATA_BUSY;
|
||||
tf.status = ATA_BUSY;
|
||||
ata_tf_to_fis(&tf, 0, 0, d2h_fis);
|
||||
|
||||
rc = sata_link_hardreset(link, timing, deadline, &online,
|
||||
@@ -889,7 +891,8 @@ static int ahci_pci_device_suspend(struct device *dev)
|
||||
}
|
||||
|
||||
ahci_pci_disable_interrupts(host);
|
||||
return ata_host_suspend(host, PMSG_SUSPEND);
|
||||
ata_host_suspend(host, PMSG_SUSPEND);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ahci_pci_device_resume(struct device *dev)
|
||||
@@ -1592,11 +1595,11 @@ static int ahci_init_msi(struct pci_dev *pdev, unsigned int n_ports,
|
||||
static void ahci_update_initial_lpm_policy(struct ata_port *ap,
|
||||
struct ahci_host_priv *hpriv)
|
||||
{
|
||||
int policy = CONFIG_SATA_MOBILE_LPM_POLICY;
|
||||
int policy = CONFIG_SATA_LPM_POLICY;
|
||||
|
||||
|
||||
/* Ignore processing for non mobile platforms */
|
||||
if (!(hpriv->flags & AHCI_HFLAG_IS_MOBILE))
|
||||
/* Ignore processing for chipsets that don't use policy */
|
||||
if (!(hpriv->flags & AHCI_HFLAG_USE_LPM_POLICY))
|
||||
return;
|
||||
|
||||
/* user modified policy via module param */
|
||||
|
||||
@@ -235,8 +235,8 @@ enum {
|
||||
AHCI_HFLAG_YES_ALPM = (1 << 23), /* force ALPM cap on */
|
||||
AHCI_HFLAG_NO_WRITE_TO_RO = (1 << 24), /* don't write to read
|
||||
only registers */
|
||||
AHCI_HFLAG_IS_MOBILE = (1 << 25), /* mobile chipset, use
|
||||
SATA_MOBILE_LPM_POLICY
|
||||
AHCI_HFLAG_USE_LPM_POLICY = (1 << 25), /* chipset that should use
|
||||
SATA_LPM_POLICY
|
||||
as default lpm_policy */
|
||||
AHCI_HFLAG_SUSPEND_PHYS = (1 << 26), /* handle PHYs during
|
||||
suspend/resume */
|
||||
|
||||
@@ -427,7 +427,7 @@ static const struct of_device_id ahci_of_match[] = {
|
||||
{.compatible = "brcm,bcm63138-ahci", .data = (void *)BRCM_SATA_BCM7445},
|
||||
{.compatible = "brcm,bcm-nsp-ahci", .data = (void *)BRCM_SATA_NSP},
|
||||
{.compatible = "brcm,bcm7216-ahci", .data = (void *)BRCM_SATA_BCM7216},
|
||||
{},
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ahci_of_match);
|
||||
|
||||
|
||||
@@ -363,7 +363,7 @@ static SIMPLE_DEV_PM_OPS(ahci_ceva_pm_ops, ceva_ahci_suspend, ceva_ahci_resume);
|
||||
|
||||
static const struct of_device_id ceva_ahci_of_match[] = {
|
||||
{ .compatible = "ceva,ahci-1v84" },
|
||||
{},
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ceva_ahci_of_match);
|
||||
|
||||
|
||||
@@ -241,7 +241,7 @@ static SIMPLE_DEV_PM_OPS(ahci_da850_pm_ops, ahci_platform_suspend,
|
||||
|
||||
static const struct of_device_id ahci_da850_of_match[] = {
|
||||
{ .compatible = "ti,da850-ahci", },
|
||||
{ },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ahci_da850_of_match);
|
||||
|
||||
|
||||
@@ -176,7 +176,7 @@ static SIMPLE_DEV_PM_OPS(ahci_dm816_pm_ops,
|
||||
|
||||
static const struct of_device_id ahci_dm816_of_match[] = {
|
||||
{ .compatible = "ti,dm816-ahci", },
|
||||
{ },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ahci_dm816_of_match);
|
||||
|
||||
|
||||
@@ -811,7 +811,7 @@ static const struct of_device_id imx_ahci_of_match[] = {
|
||||
{ .compatible = "fsl,imx6q-ahci", .data = (void *)AHCI_IMX6Q },
|
||||
{ .compatible = "fsl,imx6qp-ahci", .data = (void *)AHCI_IMX6QP },
|
||||
{ .compatible = "fsl,imx8qm-ahci", .data = (void *)AHCI_IMX8QM },
|
||||
{},
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, imx_ahci_of_match);
|
||||
|
||||
|
||||
@@ -169,7 +169,7 @@ static SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_platform_suspend,
|
||||
|
||||
static const struct of_device_id ahci_of_match[] = {
|
||||
{ .compatible = "mediatek,mtk-ahci", },
|
||||
{},
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ahci_of_match);
|
||||
|
||||
|
||||
@@ -239,7 +239,7 @@ static const struct of_device_id ahci_mvebu_of_match[] = {
|
||||
.compatible = "marvell,armada-3700-ahci",
|
||||
.data = &ahci_mvebu_armada_3700_plat_data,
|
||||
},
|
||||
{ },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ahci_mvebu_of_match);
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ static int ahci_octeon_remove(struct platform_device *pdev)
|
||||
|
||||
static const struct of_device_id octeon_ahci_match[] = {
|
||||
{ .compatible = "cavium,octeon-7130-sata-uctl", },
|
||||
{},
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, octeon_ahci_match);
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@ static const struct of_device_id ahci_of_match[] = {
|
||||
{ .compatible = "snps,dwc-ahci", },
|
||||
{ .compatible = "hisilicon,hisi-ahci", },
|
||||
{ .compatible = "cavium,octeon-7130-ahci", },
|
||||
{},
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ahci_of_match);
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ static const struct of_device_id ahci_qoriq_of_match[] = {
|
||||
{ .compatible = "fsl,ls1088a-ahci", .data = (void *)AHCI_LS1088A},
|
||||
{ .compatible = "fsl,ls2088a-ahci", .data = (void *)AHCI_LS2088A},
|
||||
{ .compatible = "fsl,lx2160a-ahci", .data = (void *)AHCI_LX2160A},
|
||||
{},
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ahci_qoriq_of_match);
|
||||
|
||||
@@ -123,7 +123,7 @@ static int ahci_qoriq_hardreset(struct ata_link *link, unsigned int *class,
|
||||
|
||||
/* clear D2H reception area to properly wait for D2H FIS */
|
||||
ata_tf_init(link->device, &tf);
|
||||
tf.command = ATA_BUSY;
|
||||
tf.status = ATA_BUSY;
|
||||
ata_tf_to_fis(&tf, 0, 0, d2h_fis);
|
||||
|
||||
rc = sata_link_hardreset(link, timing, deadline, &online,
|
||||
|
||||
@@ -232,7 +232,7 @@ static SIMPLE_DEV_PM_OPS(st_ahci_pm_ops, st_ahci_suspend, st_ahci_resume);
|
||||
|
||||
static const struct of_device_id st_ahci_match[] = {
|
||||
{ .compatible = "st,ahci", },
|
||||
{},
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, st_ahci_match);
|
||||
|
||||
|
||||
@@ -286,7 +286,7 @@ static SIMPLE_DEV_PM_OPS(ahci_sunxi_pm_ops, ahci_platform_suspend,
|
||||
static const struct of_device_id ahci_sunxi_of_match[] = {
|
||||
{ .compatible = "allwinner,sun4i-a10-ahci", },
|
||||
{ .compatible = "allwinner,sun8i-r40-ahci", },
|
||||
{ },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ahci_sunxi_of_match);
|
||||
|
||||
|
||||
@@ -365,7 +365,7 @@ static int xgene_ahci_do_hardreset(struct ata_link *link,
|
||||
do {
|
||||
/* clear D2H reception area to properly wait for D2H FIS */
|
||||
ata_tf_init(link->device, &tf);
|
||||
tf.command = ATA_BUSY;
|
||||
tf.status = ATA_BUSY;
|
||||
ata_tf_to_fis(&tf, 0, 0, d2h_fis);
|
||||
rc = sata_link_hardreset(link, timing, deadline, online,
|
||||
ahci_check_ready);
|
||||
@@ -726,7 +726,7 @@ MODULE_DEVICE_TABLE(acpi, xgene_ahci_acpi_match);
|
||||
static const struct of_device_id xgene_ahci_of_match[] = {
|
||||
{.compatible = "apm,xgene-ahci", .data = (void *) XGENE_AHCI_V1},
|
||||
{.compatible = "apm,xgene-ahci-v2", .data = (void *) XGENE_AHCI_V2},
|
||||
{},
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, xgene_ahci_of_match);
|
||||
|
||||
|
||||
@@ -993,11 +993,8 @@ static int piix_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg)
|
||||
{
|
||||
struct ata_host *host = pci_get_drvdata(pdev);
|
||||
unsigned long flags;
|
||||
int rc = 0;
|
||||
|
||||
rc = ata_host_suspend(host, mesg);
|
||||
if (rc)
|
||||
return rc;
|
||||
ata_host_suspend(host, mesg);
|
||||
|
||||
/* Some braindamaged ACPI suspend implementations expect the
|
||||
* controller to be awake on entry; otherwise, it burns cpu
|
||||
|
||||
@@ -1561,7 +1561,7 @@ int ahci_do_hardreset(struct ata_link *link, unsigned int *class,
|
||||
|
||||
/* clear D2H reception area to properly wait for D2H FIS */
|
||||
ata_tf_init(link->device, &tf);
|
||||
tf.command = ATA_BUSY;
|
||||
tf.status = ATA_BUSY;
|
||||
ata_tf_to_fis(&tf, 0, 0, d2h_fis);
|
||||
|
||||
rc = sata_link_hardreset(link, timing, deadline, online,
|
||||
@@ -2033,7 +2033,7 @@ static bool ahci_qc_fill_rtf(struct ata_queued_cmd *qc)
|
||||
if (qc->tf.protocol == ATA_PROT_PIO && qc->dma_dir == DMA_FROM_DEVICE &&
|
||||
!(qc->flags & ATA_QCFLAG_FAILED)) {
|
||||
ata_tf_from_fis(rx_fis + RX_FIS_PIO_SETUP, &qc->result_tf);
|
||||
qc->result_tf.command = (rx_fis + RX_FIS_PIO_SETUP)[15];
|
||||
qc->result_tf.status = (rx_fis + RX_FIS_PIO_SETUP)[15];
|
||||
} else
|
||||
ata_tf_from_fis(rx_fis + RX_FIS_D2H_REG, &qc->result_tf);
|
||||
|
||||
|
||||
@@ -733,7 +733,8 @@ int ahci_platform_suspend_host(struct device *dev)
|
||||
if (hpriv->flags & AHCI_HFLAG_SUSPEND_PHYS)
|
||||
ahci_platform_disable_phys(hpriv);
|
||||
|
||||
return ata_host_suspend(host, PMSG_SUSPEND);
|
||||
ata_host_suspend(host, PMSG_SUSPEND);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ahci_platform_suspend_host);
|
||||
|
||||
|
||||
@@ -546,13 +546,13 @@ static void ata_acpi_gtf_to_tf(struct ata_device *dev,
|
||||
|
||||
tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
|
||||
tf->protocol = ATA_PROT_NODATA;
|
||||
tf->feature = gtf->tf[0]; /* 0x1f1 */
|
||||
tf->error = gtf->tf[0]; /* 0x1f1 */
|
||||
tf->nsect = gtf->tf[1]; /* 0x1f2 */
|
||||
tf->lbal = gtf->tf[2]; /* 0x1f3 */
|
||||
tf->lbam = gtf->tf[3]; /* 0x1f4 */
|
||||
tf->lbah = gtf->tf[4]; /* 0x1f5 */
|
||||
tf->device = gtf->tf[5]; /* 0x1f6 */
|
||||
tf->command = gtf->tf[6]; /* 0x1f7 */
|
||||
tf->status = gtf->tf[6]; /* 0x1f7 */
|
||||
}
|
||||
|
||||
static int ata_acpi_filter_tf(struct ata_device *dev,
|
||||
@@ -679,7 +679,7 @@ static int ata_acpi_run_tf(struct ata_device *dev,
|
||||
"(%s) rejected by device (Stat=0x%02x Err=0x%02x)",
|
||||
tf.command, tf.feature, tf.nsect, tf.lbal,
|
||||
tf.lbam, tf.lbah, tf.device, descr,
|
||||
rtf.command, rtf.feature);
|
||||
rtf.status, rtf.error);
|
||||
rc = 0;
|
||||
break;
|
||||
|
||||
@@ -689,7 +689,7 @@ static int ata_acpi_run_tf(struct ata_device *dev,
|
||||
"(%s) failed (Emask=0x%x Stat=0x%02x Err=0x%02x)",
|
||||
tf.command, tf.feature, tf.nsect, tf.lbal,
|
||||
tf.lbam, tf.lbah, tf.device, descr,
|
||||
err_mask, rtf.command, rtf.feature);
|
||||
err_mask, rtf.status, rtf.error);
|
||||
rc = -EIO;
|
||||
break;
|
||||
}
|
||||
@@ -799,27 +799,6 @@ static int ata_acpi_push_id(struct ata_device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_acpi_on_suspend - ATA ACPI hook called on suspend
|
||||
* @ap: target ATA port
|
||||
*
|
||||
* This function is called when @ap is about to be suspended. All
|
||||
* devices are already put to sleep but the port_suspend() callback
|
||||
* hasn't been executed yet. Error return from this function aborts
|
||||
* suspend.
|
||||
*
|
||||
* LOCKING:
|
||||
* EH context.
|
||||
*
|
||||
* RETURNS:
|
||||
* 0 on success, -errno on failure.
|
||||
*/
|
||||
int ata_acpi_on_suspend(struct ata_port *ap)
|
||||
{
|
||||
/* nada */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_acpi_on_resume - ATA ACPI hook called on resume
|
||||
* @ap: target ATA port
|
||||
|
||||
@@ -1171,7 +1171,7 @@ static int ata_read_native_max_address(struct ata_device *dev, u64 *max_sectors)
|
||||
ata_dev_warn(dev,
|
||||
"failed to read native max address (err_mask=0x%x)\n",
|
||||
err_mask);
|
||||
if (err_mask == AC_ERR_DEV && (tf.feature & ATA_ABORTED))
|
||||
if (err_mask == AC_ERR_DEV && (tf.error & ATA_ABORTED))
|
||||
return -EACCES;
|
||||
return -EIO;
|
||||
}
|
||||
@@ -1235,7 +1235,7 @@ static int ata_set_max_sectors(struct ata_device *dev, u64 new_sectors)
|
||||
"failed to set max address (err_mask=0x%x)\n",
|
||||
err_mask);
|
||||
if (err_mask == AC_ERR_DEV &&
|
||||
(tf.feature & (ATA_ABORTED | ATA_IDNF)))
|
||||
(tf.error & (ATA_ABORTED | ATA_IDNF)))
|
||||
return -EACCES;
|
||||
return -EIO;
|
||||
}
|
||||
@@ -1584,7 +1584,7 @@ unsigned ata_exec_internal_sg(struct ata_device *dev,
|
||||
|
||||
/* perform minimal error analysis */
|
||||
if (qc->flags & ATA_QCFLAG_FAILED) {
|
||||
if (qc->result_tf.command & (ATA_ERR | ATA_DF))
|
||||
if (qc->result_tf.status & (ATA_ERR | ATA_DF))
|
||||
qc->err_mask |= AC_ERR_DEV;
|
||||
|
||||
if (!qc->err_mask)
|
||||
@@ -1593,7 +1593,7 @@ unsigned ata_exec_internal_sg(struct ata_device *dev,
|
||||
if (qc->err_mask & ~AC_ERR_OTHER)
|
||||
qc->err_mask &= ~AC_ERR_OTHER;
|
||||
} else if (qc->tf.command == ATA_CMD_REQ_SENSE_DATA) {
|
||||
qc->result_tf.command |= ATA_SENSE;
|
||||
qc->result_tf.status |= ATA_SENSE;
|
||||
}
|
||||
|
||||
/* finish up */
|
||||
@@ -1813,7 +1813,7 @@ retry:
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((err_mask == AC_ERR_DEV) && (tf.feature & ATA_ABORTED)) {
|
||||
if ((err_mask == AC_ERR_DEV) && (tf.error & ATA_ABORTED)) {
|
||||
/* Device or controller might have reported
|
||||
* the wrong device class. Give a shot at the
|
||||
* other IDENTIFY if the current one is
|
||||
@@ -3569,7 +3569,7 @@ EXPORT_SYMBOL_GPL(ata_wait_after_reset);
|
||||
* Kernel thread context (may sleep)
|
||||
*
|
||||
* RETURNS:
|
||||
* 0 on success, -errno otherwise.
|
||||
* Always 0.
|
||||
*/
|
||||
int ata_std_prereset(struct ata_link *link, unsigned long deadline)
|
||||
{
|
||||
@@ -4384,7 +4384,7 @@ static unsigned int ata_dev_init_params(struct ata_device *dev,
|
||||
/* A clean abort indicates an original or just out of spec drive
|
||||
and we should continue as we issue the setup based on the
|
||||
drive reported working geometry */
|
||||
if (err_mask == AC_ERR_DEV && (tf.feature & ATA_ABORTED))
|
||||
if (err_mask == AC_ERR_DEV && (tf.error & ATA_ABORTED))
|
||||
err_mask = 0;
|
||||
|
||||
return err_mask;
|
||||
@@ -5179,10 +5179,9 @@ EXPORT_SYMBOL_GPL(ata_sas_port_resume);
|
||||
*
|
||||
* Suspend @host. Actual operation is performed by port suspend.
|
||||
*/
|
||||
int ata_host_suspend(struct ata_host *host, pm_message_t mesg)
|
||||
void ata_host_suspend(struct ata_host *host, pm_message_t mesg)
|
||||
{
|
||||
host->dev->power.power_state = mesg;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_host_suspend);
|
||||
|
||||
@@ -6099,11 +6098,8 @@ EXPORT_SYMBOL_GPL(ata_pci_device_do_resume);
|
||||
int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg)
|
||||
{
|
||||
struct ata_host *host = pci_get_drvdata(pdev);
|
||||
int rc = 0;
|
||||
|
||||
rc = ata_host_suspend(host, mesg);
|
||||
if (rc)
|
||||
return rc;
|
||||
ata_host_suspend(host, mesg);
|
||||
|
||||
ata_pci_device_do_suspend(pdev, mesg);
|
||||
|
||||
|
||||
@@ -1386,7 +1386,7 @@ unsigned int atapi_eh_tur(struct ata_device *dev, u8 *r_sense_key)
|
||||
|
||||
err_mask = ata_exec_internal(dev, &tf, cdb, DMA_NONE, NULL, 0, 0);
|
||||
if (err_mask == AC_ERR_DEV)
|
||||
*r_sense_key = tf.feature >> 4;
|
||||
*r_sense_key = tf.error >> 4;
|
||||
return err_mask;
|
||||
}
|
||||
|
||||
@@ -1429,12 +1429,12 @@ static void ata_eh_request_sense(struct ata_queued_cmd *qc,
|
||||
|
||||
err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0);
|
||||
/* Ignore err_mask; ATA_ERR might be set */
|
||||
if (tf.command & ATA_SENSE) {
|
||||
if (tf.status & ATA_SENSE) {
|
||||
ata_scsi_set_sense(dev, cmd, tf.lbah, tf.lbam, tf.lbal);
|
||||
qc->flags |= ATA_QCFLAG_SENSE_VALID;
|
||||
} else {
|
||||
ata_dev_warn(dev, "request sense failed stat %02x emask %x\n",
|
||||
tf.command, err_mask);
|
||||
tf.status, err_mask);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1557,7 +1557,7 @@ static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc,
|
||||
const struct ata_taskfile *tf)
|
||||
{
|
||||
unsigned int tmp, action = 0;
|
||||
u8 stat = tf->command, err = tf->feature;
|
||||
u8 stat = tf->status, err = tf->error;
|
||||
|
||||
if ((stat & (ATA_BUSY | ATA_DRQ | ATA_DRDY)) != ATA_DRDY) {
|
||||
qc->err_mask |= AC_ERR_HSM;
|
||||
@@ -1594,7 +1594,7 @@ static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc,
|
||||
if (!(qc->ap->pflags & ATA_PFLAG_FROZEN)) {
|
||||
tmp = atapi_eh_request_sense(qc->dev,
|
||||
qc->scsicmd->sense_buffer,
|
||||
qc->result_tf.feature >> 4);
|
||||
qc->result_tf.error >> 4);
|
||||
if (!tmp)
|
||||
qc->flags |= ATA_QCFLAG_SENSE_VALID;
|
||||
else
|
||||
@@ -2360,7 +2360,7 @@ static void ata_eh_link_report(struct ata_link *link)
|
||||
cmd->hob_feature, cmd->hob_nsect,
|
||||
cmd->hob_lbal, cmd->hob_lbam, cmd->hob_lbah,
|
||||
cmd->device, qc->tag, data_buf, cdb_buf,
|
||||
res->command, res->feature, res->nsect,
|
||||
res->status, res->error, res->nsect,
|
||||
res->lbal, res->lbam, res->lbah,
|
||||
res->hob_feature, res->hob_nsect,
|
||||
res->hob_lbal, res->hob_lbam, res->hob_lbah,
|
||||
@@ -2368,28 +2368,28 @@ static void ata_eh_link_report(struct ata_link *link)
|
||||
qc->err_mask & AC_ERR_NCQ ? " <F>" : "");
|
||||
|
||||
#ifdef CONFIG_ATA_VERBOSE_ERROR
|
||||
if (res->command & (ATA_BUSY | ATA_DRDY | ATA_DF | ATA_DRQ |
|
||||
ATA_SENSE | ATA_ERR)) {
|
||||
if (res->command & ATA_BUSY)
|
||||
if (res->status & (ATA_BUSY | ATA_DRDY | ATA_DF | ATA_DRQ |
|
||||
ATA_SENSE | ATA_ERR)) {
|
||||
if (res->status & ATA_BUSY)
|
||||
ata_dev_err(qc->dev, "status: { Busy }\n");
|
||||
else
|
||||
ata_dev_err(qc->dev, "status: { %s%s%s%s%s}\n",
|
||||
res->command & ATA_DRDY ? "DRDY " : "",
|
||||
res->command & ATA_DF ? "DF " : "",
|
||||
res->command & ATA_DRQ ? "DRQ " : "",
|
||||
res->command & ATA_SENSE ? "SENSE " : "",
|
||||
res->command & ATA_ERR ? "ERR " : "");
|
||||
res->status & ATA_DRDY ? "DRDY " : "",
|
||||
res->status & ATA_DF ? "DF " : "",
|
||||
res->status & ATA_DRQ ? "DRQ " : "",
|
||||
res->status & ATA_SENSE ? "SENSE " : "",
|
||||
res->status & ATA_ERR ? "ERR " : "");
|
||||
}
|
||||
|
||||
if (cmd->command != ATA_CMD_PACKET &&
|
||||
(res->feature & (ATA_ICRC | ATA_UNC | ATA_AMNF |
|
||||
ATA_IDNF | ATA_ABORTED)))
|
||||
(res->error & (ATA_ICRC | ATA_UNC | ATA_AMNF | ATA_IDNF |
|
||||
ATA_ABORTED)))
|
||||
ata_dev_err(qc->dev, "error: { %s%s%s%s%s}\n",
|
||||
res->feature & ATA_ICRC ? "ICRC " : "",
|
||||
res->feature & ATA_UNC ? "UNC " : "",
|
||||
res->feature & ATA_AMNF ? "AMNF " : "",
|
||||
res->feature & ATA_IDNF ? "IDNF " : "",
|
||||
res->feature & ATA_ABORTED ? "ABRT " : "");
|
||||
res->error & ATA_ICRC ? "ICRC " : "",
|
||||
res->error & ATA_UNC ? "UNC " : "",
|
||||
res->error & ATA_AMNF ? "AMNF " : "",
|
||||
res->error & ATA_IDNF ? "IDNF " : "",
|
||||
res->error & ATA_ABORTED ? "ABRT " : "");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -3902,11 +3902,6 @@ static void ata_eh_handle_port_suspend(struct ata_port *ap)
|
||||
}
|
||||
}
|
||||
|
||||
/* tell ACPI we're suspending */
|
||||
rc = ata_acpi_on_suspend(ap);
|
||||
if (rc)
|
||||
goto out;
|
||||
|
||||
/* suspend */
|
||||
ata_eh_freeze_port(ap);
|
||||
|
||||
@@ -3914,7 +3909,7 @@ static void ata_eh_handle_port_suspend(struct ata_port *ap)
|
||||
rc = ap->ops->port_suspend(ap, ap->pm_mesg);
|
||||
|
||||
ata_acpi_set_state(ap, ap->pm_mesg);
|
||||
out:
|
||||
|
||||
/* update the flags */
|
||||
spin_lock_irqsave(ap->lock, flags);
|
||||
|
||||
|
||||
@@ -191,8 +191,8 @@ EXPORT_SYMBOL_GPL(ata_tf_to_fis);
|
||||
|
||||
void ata_tf_from_fis(const u8 *fis, struct ata_taskfile *tf)
|
||||
{
|
||||
tf->command = fis[2]; /* status */
|
||||
tf->feature = fis[3]; /* error */
|
||||
tf->status = fis[2];
|
||||
tf->error = fis[3];
|
||||
|
||||
tf->lbal = fis[4];
|
||||
tf->lbam = fis[5];
|
||||
@@ -1406,8 +1406,8 @@ static int ata_eh_read_log_10h(struct ata_device *dev,
|
||||
|
||||
*tag = buf[0] & 0x1f;
|
||||
|
||||
tf->command = buf[2];
|
||||
tf->feature = buf[3];
|
||||
tf->status = buf[2];
|
||||
tf->error = buf[3];
|
||||
tf->lbal = buf[4];
|
||||
tf->lbam = buf[5];
|
||||
tf->lbah = buf[6];
|
||||
@@ -1482,7 +1482,7 @@ void ata_eh_analyze_ncq_error(struct ata_link *link)
|
||||
qc->result_tf.flags = ATA_TFLAG_ISADDR | ATA_TFLAG_LBA | ATA_TFLAG_LBA48;
|
||||
qc->err_mask |= AC_ERR_DEV | AC_ERR_NCQ;
|
||||
if (dev->class == ATA_DEV_ZAC &&
|
||||
((qc->result_tf.command & ATA_SENSE) || qc->result_tf.auxiliary)) {
|
||||
((qc->result_tf.status & ATA_SENSE) || qc->result_tf.auxiliary)) {
|
||||
char sense_key, asc, ascq;
|
||||
|
||||
sense_key = (qc->result_tf.auxiliary >> 16) & 0xff;
|
||||
|
||||
@@ -680,7 +680,7 @@ static void ata_qc_set_pc_nbytes(struct ata_queued_cmd *qc)
|
||||
*/
|
||||
static void ata_dump_status(struct ata_port *ap, struct ata_taskfile *tf)
|
||||
{
|
||||
u8 stat = tf->command, err = tf->feature;
|
||||
u8 stat = tf->status, err = tf->error;
|
||||
|
||||
if (stat & ATA_BUSY) {
|
||||
ata_port_warn(ap, "status=0x%02x {Busy} ", stat);
|
||||
@@ -871,8 +871,8 @@ static void ata_gen_passthru_sense(struct ata_queued_cmd *qc)
|
||||
* onto sense key, asc & ascq.
|
||||
*/
|
||||
if (qc->err_mask ||
|
||||
tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) {
|
||||
ata_to_sense_error(qc->ap->print_id, tf->command, tf->feature,
|
||||
tf->status & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) {
|
||||
ata_to_sense_error(qc->ap->print_id, tf->status, tf->error,
|
||||
&sense_key, &asc, &ascq, verbose);
|
||||
ata_scsi_set_sense(qc->dev, cmd, sense_key, asc, ascq);
|
||||
} else {
|
||||
@@ -901,13 +901,13 @@ static void ata_gen_passthru_sense(struct ata_queued_cmd *qc)
|
||||
* Copy registers into sense buffer.
|
||||
*/
|
||||
desc[2] = 0x00;
|
||||
desc[3] = tf->feature; /* == error reg */
|
||||
desc[3] = tf->error;
|
||||
desc[5] = tf->nsect;
|
||||
desc[7] = tf->lbal;
|
||||
desc[9] = tf->lbam;
|
||||
desc[11] = tf->lbah;
|
||||
desc[12] = tf->device;
|
||||
desc[13] = tf->command; /* == status reg */
|
||||
desc[13] = tf->status;
|
||||
|
||||
/*
|
||||
* Fill in Extend bit, and the high order bytes
|
||||
@@ -922,8 +922,8 @@ static void ata_gen_passthru_sense(struct ata_queued_cmd *qc)
|
||||
}
|
||||
} else {
|
||||
/* Fixed sense format */
|
||||
desc[0] = tf->feature;
|
||||
desc[1] = tf->command; /* status */
|
||||
desc[0] = tf->error;
|
||||
desc[1] = tf->status;
|
||||
desc[2] = tf->device;
|
||||
desc[3] = tf->nsect;
|
||||
desc[7] = 0;
|
||||
@@ -972,14 +972,14 @@ static void ata_gen_ata_sense(struct ata_queued_cmd *qc)
|
||||
* onto sense key, asc & ascq.
|
||||
*/
|
||||
if (qc->err_mask ||
|
||||
tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) {
|
||||
ata_to_sense_error(qc->ap->print_id, tf->command, tf->feature,
|
||||
tf->status & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) {
|
||||
ata_to_sense_error(qc->ap->print_id, tf->status, tf->error,
|
||||
&sense_key, &asc, &ascq, verbose);
|
||||
ata_scsi_set_sense(dev, cmd, sense_key, asc, ascq);
|
||||
} else {
|
||||
/* Could not decode error */
|
||||
ata_dev_warn(dev, "could not decode error status 0x%x err_mask 0x%x\n",
|
||||
tf->command, qc->err_mask);
|
||||
tf->status, qc->err_mask);
|
||||
ata_scsi_set_sense(dev, cmd, ABORTED_COMMAND, 0, 0);
|
||||
return;
|
||||
}
|
||||
@@ -1314,21 +1314,10 @@ static void scsi_6_lba_len(const u8 *cdb, u64 *plba, u32 *plen)
|
||||
* @plba: the LBA
|
||||
* @plen: the transfer length
|
||||
*/
|
||||
static void scsi_10_lba_len(const u8 *cdb, u64 *plba, u32 *plen)
|
||||
static inline void scsi_10_lba_len(const u8 *cdb, u64 *plba, u32 *plen)
|
||||
{
|
||||
u64 lba = 0;
|
||||
u32 len = 0;
|
||||
|
||||
lba |= ((u64)cdb[2]) << 24;
|
||||
lba |= ((u64)cdb[3]) << 16;
|
||||
lba |= ((u64)cdb[4]) << 8;
|
||||
lba |= ((u64)cdb[5]);
|
||||
|
||||
len |= ((u32)cdb[7]) << 8;
|
||||
len |= ((u32)cdb[8]);
|
||||
|
||||
*plba = lba;
|
||||
*plen = len;
|
||||
*plba = get_unaligned_be32(&cdb[2]);
|
||||
*plen = get_unaligned_be16(&cdb[7]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1341,27 +1330,10 @@ static void scsi_10_lba_len(const u8 *cdb, u64 *plba, u32 *plen)
|
||||
* @plba: the LBA
|
||||
* @plen: the transfer length
|
||||
*/
|
||||
static void scsi_16_lba_len(const u8 *cdb, u64 *plba, u32 *plen)
|
||||
static inline void scsi_16_lba_len(const u8 *cdb, u64 *plba, u32 *plen)
|
||||
{
|
||||
u64 lba = 0;
|
||||
u32 len = 0;
|
||||
|
||||
lba |= ((u64)cdb[2]) << 56;
|
||||
lba |= ((u64)cdb[3]) << 48;
|
||||
lba |= ((u64)cdb[4]) << 40;
|
||||
lba |= ((u64)cdb[5]) << 32;
|
||||
lba |= ((u64)cdb[6]) << 24;
|
||||
lba |= ((u64)cdb[7]) << 16;
|
||||
lba |= ((u64)cdb[8]) << 8;
|
||||
lba |= ((u64)cdb[9]);
|
||||
|
||||
len |= ((u32)cdb[10]) << 24;
|
||||
len |= ((u32)cdb[11]) << 16;
|
||||
len |= ((u32)cdb[12]) << 8;
|
||||
len |= ((u32)cdb[13]);
|
||||
|
||||
*plba = lba;
|
||||
*plen = len;
|
||||
*plba = get_unaligned_be64(&cdb[2]);
|
||||
*plen = get_unaligned_be32(&cdb[10]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1390,19 +1362,22 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc)
|
||||
tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
|
||||
tf->protocol = ATA_PROT_NODATA;
|
||||
|
||||
if (cdb[0] == VERIFY) {
|
||||
switch (cdb[0]) {
|
||||
case VERIFY:
|
||||
if (scmd->cmd_len < 10) {
|
||||
fp = 9;
|
||||
goto invalid_fld;
|
||||
}
|
||||
scsi_10_lba_len(cdb, &block, &n_block);
|
||||
} else if (cdb[0] == VERIFY_16) {
|
||||
break;
|
||||
case VERIFY_16:
|
||||
if (scmd->cmd_len < 16) {
|
||||
fp = 15;
|
||||
goto invalid_fld;
|
||||
}
|
||||
scsi_16_lba_len(cdb, &block, &n_block);
|
||||
} else {
|
||||
break;
|
||||
default:
|
||||
fp = 0;
|
||||
goto invalid_fld;
|
||||
}
|
||||
@@ -1534,8 +1509,13 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc)
|
||||
int rc;
|
||||
u16 fp = 0;
|
||||
|
||||
if (cdb[0] == WRITE_10 || cdb[0] == WRITE_6 || cdb[0] == WRITE_16)
|
||||
switch (cdb[0]) {
|
||||
case WRITE_6:
|
||||
case WRITE_10:
|
||||
case WRITE_16:
|
||||
tf_flags |= ATA_TFLAG_WRITE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Calculate the SCSI LBA, transfer length and FUA. */
|
||||
switch (cdb[0]) {
|
||||
@@ -2493,7 +2473,7 @@ static void atapi_request_sense(struct ata_queued_cmd *qc)
|
||||
|
||||
/* fill these in, for the case where they are -not- overwritten */
|
||||
cmd->sense_buffer[0] = 0x70;
|
||||
cmd->sense_buffer[2] = qc->tf.feature >> 4;
|
||||
cmd->sense_buffer[2] = qc->tf.error >> 4;
|
||||
|
||||
ata_qc_reinit(qc);
|
||||
|
||||
@@ -2845,7 +2825,8 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
|
||||
* 12 and 16 byte CDBs use different offsets to
|
||||
* provide the various register values.
|
||||
*/
|
||||
if (cdb[0] == ATA_16) {
|
||||
switch (cdb[0]) {
|
||||
case ATA_16:
|
||||
/*
|
||||
* 16-byte CDB - may contain extended commands.
|
||||
*
|
||||
@@ -2871,7 +2852,8 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
|
||||
tf->lbah = cdb[12];
|
||||
tf->device = cdb[13];
|
||||
tf->command = cdb[14];
|
||||
} else if (cdb[0] == ATA_12) {
|
||||
break;
|
||||
case ATA_12:
|
||||
/*
|
||||
* 12-byte CDB - incapable of extended commands.
|
||||
*/
|
||||
@@ -2884,7 +2866,8 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
|
||||
tf->lbah = cdb[7];
|
||||
tf->device = cdb[8];
|
||||
tf->command = cdb[9];
|
||||
} else {
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
* 32-byte CDB - may contain extended command fields.
|
||||
*
|
||||
@@ -2908,6 +2891,7 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
|
||||
tf->device = cdb[24];
|
||||
tf->command = cdb[25];
|
||||
tf->auxiliary = get_unaligned_be32(&cdb[28]);
|
||||
break;
|
||||
}
|
||||
|
||||
/* For NCQ commands copy the tag value */
|
||||
@@ -3672,7 +3656,7 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc)
|
||||
goto invalid_fld;
|
||||
}
|
||||
|
||||
len = (cdb[7] << 8) + cdb[8];
|
||||
len = get_unaligned_be16(&cdb[7]);
|
||||
hdr_len = 8;
|
||||
}
|
||||
|
||||
@@ -3698,7 +3682,7 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc)
|
||||
if (six_byte)
|
||||
bd_len = p[3];
|
||||
else
|
||||
bd_len = (p[6] << 8) + p[7];
|
||||
bd_len = get_unaligned_be16(&p[6]);
|
||||
|
||||
len -= hdr_len;
|
||||
p += hdr_len;
|
||||
@@ -3722,7 +3706,7 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc)
|
||||
goto invalid_param_len;
|
||||
|
||||
spg = p[1];
|
||||
pg_len = (p[2] << 8) | p[3];
|
||||
pg_len = get_unaligned_be16(&p[2]);
|
||||
p += 4;
|
||||
len -= 4;
|
||||
} else {
|
||||
@@ -3933,7 +3917,6 @@ static inline ata_xlat_func_t ata_get_xlat_func(struct ata_device *dev, u8 cmd)
|
||||
case MODE_SELECT:
|
||||
case MODE_SELECT_10:
|
||||
return ata_scsi_mode_select_xlat;
|
||||
break;
|
||||
|
||||
case ZBC_IN:
|
||||
return ata_scsi_zbc_in_xlat;
|
||||
|
||||
@@ -70,22 +70,35 @@ EXPORT_SYMBOL_GPL(ata_sff_check_status);
|
||||
/**
|
||||
* ata_sff_altstatus - Read device alternate status reg
|
||||
* @ap: port where the device is
|
||||
* @status: pointer to a status value
|
||||
*
|
||||
* Reads ATA taskfile alternate status register for
|
||||
* currently-selected device and return its value.
|
||||
* Reads ATA alternate status register for currently-selected device
|
||||
* and return its value.
|
||||
*
|
||||
* Note: may NOT be used as the check_altstatus() entry in
|
||||
* ata_port_operations.
|
||||
* RETURN:
|
||||
* true if the register exists, false if not.
|
||||
*
|
||||
* LOCKING:
|
||||
* Inherited from caller.
|
||||
*/
|
||||
static u8 ata_sff_altstatus(struct ata_port *ap)
|
||||
static bool ata_sff_altstatus(struct ata_port *ap, u8 *status)
|
||||
{
|
||||
if (ap->ops->sff_check_altstatus)
|
||||
return ap->ops->sff_check_altstatus(ap);
|
||||
u8 tmp;
|
||||
|
||||
return ioread8(ap->ioaddr.altstatus_addr);
|
||||
if (ap->ops->sff_check_altstatus) {
|
||||
tmp = ap->ops->sff_check_altstatus(ap);
|
||||
goto read;
|
||||
}
|
||||
if (ap->ioaddr.altstatus_addr) {
|
||||
tmp = ioread8(ap->ioaddr.altstatus_addr);
|
||||
goto read;
|
||||
}
|
||||
return false;
|
||||
|
||||
read:
|
||||
if (status)
|
||||
*status = tmp;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -104,12 +117,9 @@ static u8 ata_sff_irq_status(struct ata_port *ap)
|
||||
{
|
||||
u8 status;
|
||||
|
||||
if (ap->ops->sff_check_altstatus || ap->ioaddr.altstatus_addr) {
|
||||
status = ata_sff_altstatus(ap);
|
||||
/* Not us: We are busy */
|
||||
if (status & ATA_BUSY)
|
||||
return status;
|
||||
}
|
||||
/* Not us: We are busy */
|
||||
if (ata_sff_altstatus(ap, &status) && (status & ATA_BUSY))
|
||||
return status;
|
||||
/* Clear INTRQ latch */
|
||||
status = ap->ops->sff_check_status(ap);
|
||||
return status;
|
||||
@@ -129,10 +139,7 @@ static u8 ata_sff_irq_status(struct ata_port *ap)
|
||||
|
||||
static void ata_sff_sync(struct ata_port *ap)
|
||||
{
|
||||
if (ap->ops->sff_check_altstatus)
|
||||
ap->ops->sff_check_altstatus(ap);
|
||||
else if (ap->ioaddr.altstatus_addr)
|
||||
ioread8(ap->ioaddr.altstatus_addr);
|
||||
ata_sff_altstatus(ap, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -164,12 +171,12 @@ EXPORT_SYMBOL_GPL(ata_sff_pause);
|
||||
|
||||
void ata_sff_dma_pause(struct ata_port *ap)
|
||||
{
|
||||
if (ap->ops->sff_check_altstatus || ap->ioaddr.altstatus_addr) {
|
||||
/* An altstatus read will cause the needed delay without
|
||||
messing up the IRQ status */
|
||||
ata_sff_altstatus(ap);
|
||||
/*
|
||||
* An altstatus read will cause the needed delay without
|
||||
* messing up the IRQ status
|
||||
*/
|
||||
if (ata_sff_altstatus(ap, NULL))
|
||||
return;
|
||||
}
|
||||
/* There are no DMA controllers without ctl. BUG here to ensure
|
||||
we never violate the HDMA1:0 transition timing and risk
|
||||
corruption. */
|
||||
@@ -265,20 +272,26 @@ EXPORT_SYMBOL_GPL(ata_sff_wait_ready);
|
||||
* @ap: port where the device is
|
||||
* @ctl: value to write
|
||||
*
|
||||
* Writes ATA taskfile device control register.
|
||||
* Writes ATA device control register.
|
||||
*
|
||||
* Note: may NOT be used as the sff_set_devctl() entry in
|
||||
* ata_port_operations.
|
||||
* RETURN:
|
||||
* true if the register exists, false if not.
|
||||
*
|
||||
* LOCKING:
|
||||
* Inherited from caller.
|
||||
*/
|
||||
static void ata_sff_set_devctl(struct ata_port *ap, u8 ctl)
|
||||
static bool ata_sff_set_devctl(struct ata_port *ap, u8 ctl)
|
||||
{
|
||||
if (ap->ops->sff_set_devctl)
|
||||
if (ap->ops->sff_set_devctl) {
|
||||
ap->ops->sff_set_devctl(ap, ctl);
|
||||
else
|
||||
return true;
|
||||
}
|
||||
if (ap->ioaddr.ctl_addr) {
|
||||
iowrite8(ctl, ap->ioaddr.ctl_addr);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -357,8 +370,6 @@ static void ata_dev_select(struct ata_port *ap, unsigned int device,
|
||||
*/
|
||||
void ata_sff_irq_on(struct ata_port *ap)
|
||||
{
|
||||
struct ata_ioports *ioaddr = &ap->ioaddr;
|
||||
|
||||
if (ap->ops->sff_irq_on) {
|
||||
ap->ops->sff_irq_on(ap);
|
||||
return;
|
||||
@@ -367,8 +378,7 @@ void ata_sff_irq_on(struct ata_port *ap)
|
||||
ap->ctl &= ~ATA_NIEN;
|
||||
ap->last_ctl = ap->ctl;
|
||||
|
||||
if (ap->ops->sff_set_devctl || ioaddr->ctl_addr)
|
||||
ata_sff_set_devctl(ap, ap->ctl);
|
||||
ata_sff_set_devctl(ap, ap->ctl);
|
||||
ata_wait_idle(ap);
|
||||
|
||||
if (ap->ops->sff_irq_clear)
|
||||
@@ -439,8 +449,8 @@ void ata_sff_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
|
||||
{
|
||||
struct ata_ioports *ioaddr = &ap->ioaddr;
|
||||
|
||||
tf->command = ata_sff_check_status(ap);
|
||||
tf->feature = ioread8(ioaddr->error_addr);
|
||||
tf->status = ata_sff_check_status(ap);
|
||||
tf->error = ioread8(ioaddr->error_addr);
|
||||
tf->nsect = ioread8(ioaddr->nsect_addr);
|
||||
tf->lbal = ioread8(ioaddr->lbal_addr);
|
||||
tf->lbam = ioread8(ioaddr->lbam_addr);
|
||||
@@ -1634,14 +1644,14 @@ void ata_sff_lost_interrupt(struct ata_port *ap)
|
||||
return;
|
||||
/* See if the controller thinks it is still busy - if so the command
|
||||
isn't a lost IRQ but is still in progress */
|
||||
status = ata_sff_altstatus(ap);
|
||||
if (WARN_ON_ONCE(!ata_sff_altstatus(ap, &status)))
|
||||
return;
|
||||
if (status & ATA_BUSY)
|
||||
return;
|
||||
|
||||
/* There was a command running, we are no longer busy and we have
|
||||
no interrupt. */
|
||||
ata_port_warn(ap, "lost interrupt (Status 0x%x)\n",
|
||||
status);
|
||||
ata_port_warn(ap, "lost interrupt (Status 0x%x)\n", status);
|
||||
/* Run the host interrupt logic as if the interrupt had not been
|
||||
lost */
|
||||
ata_sff_port_intr(ap, qc);
|
||||
@@ -1662,8 +1672,7 @@ void ata_sff_freeze(struct ata_port *ap)
|
||||
ap->ctl |= ATA_NIEN;
|
||||
ap->last_ctl = ap->ctl;
|
||||
|
||||
if (ap->ops->sff_set_devctl || ap->ioaddr.ctl_addr)
|
||||
ata_sff_set_devctl(ap, ap->ctl);
|
||||
ata_sff_set_devctl(ap, ap->ctl);
|
||||
|
||||
/* Under certain circumstances, some controllers raise IRQ on
|
||||
* ATA_NIEN manipulation. Also, many controllers fail to mask
|
||||
@@ -1708,16 +1717,15 @@ EXPORT_SYMBOL_GPL(ata_sff_thaw);
|
||||
* Kernel thread context (may sleep)
|
||||
*
|
||||
* RETURNS:
|
||||
* 0 on success, -errno otherwise.
|
||||
* Always 0.
|
||||
*/
|
||||
int ata_sff_prereset(struct ata_link *link, unsigned long deadline)
|
||||
{
|
||||
struct ata_eh_context *ehc = &link->eh_context;
|
||||
int rc;
|
||||
|
||||
rc = ata_std_prereset(link, deadline);
|
||||
if (rc)
|
||||
return rc;
|
||||
/* The standard prereset is best-effort and always returns 0 */
|
||||
ata_std_prereset(link, deadline);
|
||||
|
||||
/* if we're about to do hardreset, nothing more to do */
|
||||
if (ehc->i.action & ATA_EH_HARDRESET)
|
||||
@@ -1752,10 +1760,13 @@ EXPORT_SYMBOL_GPL(ata_sff_prereset);
|
||||
* correctly storing and echoing back the
|
||||
* ATA shadow register contents.
|
||||
*
|
||||
* RETURN:
|
||||
* true if device is present, false if not.
|
||||
*
|
||||
* LOCKING:
|
||||
* caller.
|
||||
*/
|
||||
static unsigned int ata_devchk(struct ata_port *ap, unsigned int device)
|
||||
static bool ata_devchk(struct ata_port *ap, unsigned int device)
|
||||
{
|
||||
struct ata_ioports *ioaddr = &ap->ioaddr;
|
||||
u8 nsect, lbal;
|
||||
@@ -1775,9 +1786,9 @@ static unsigned int ata_devchk(struct ata_port *ap, unsigned int device)
|
||||
lbal = ioread8(ioaddr->lbal_addr);
|
||||
|
||||
if ((nsect == 0x55) && (lbal == 0xaa))
|
||||
return 1; /* we found a device */
|
||||
return true; /* we found a device */
|
||||
|
||||
return 0; /* nothing found */
|
||||
return false; /* nothing found */
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1814,7 +1825,7 @@ unsigned int ata_sff_dev_classify(struct ata_device *dev, int present,
|
||||
memset(&tf, 0, sizeof(tf));
|
||||
|
||||
ap->ops->sff_tf_read(ap, &tf);
|
||||
err = tf.feature;
|
||||
err = tf.error;
|
||||
if (r_err)
|
||||
*r_err = err;
|
||||
|
||||
@@ -1831,9 +1842,10 @@ unsigned int ata_sff_dev_classify(struct ata_device *dev, int present,
|
||||
|
||||
/* determine if device is ATA or ATAPI */
|
||||
class = ata_port_classify(ap, &tf);
|
||||
|
||||
if (class == ATA_DEV_UNKNOWN) {
|
||||
/* If the device failed diagnostic, it's likely to
|
||||
switch (class) {
|
||||
case ATA_DEV_UNKNOWN:
|
||||
/*
|
||||
* If the device failed diagnostic, it's likely to
|
||||
* have reported incorrect device signature too.
|
||||
* Assume ATA device if the device seems present but
|
||||
* device signature is invalid with diagnostic
|
||||
@@ -1843,10 +1855,12 @@ unsigned int ata_sff_dev_classify(struct ata_device *dev, int present,
|
||||
class = ATA_DEV_ATA;
|
||||
else
|
||||
class = ATA_DEV_NONE;
|
||||
} else if ((class == ATA_DEV_ATA) &&
|
||||
(ap->ops->sff_check_status(ap) == 0))
|
||||
class = ATA_DEV_NONE;
|
||||
|
||||
break;
|
||||
case ATA_DEV_ATA:
|
||||
if (ap->ops->sff_check_status(ap) == 0)
|
||||
class = ATA_DEV_NONE;
|
||||
break;
|
||||
}
|
||||
return class;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_sff_dev_classify);
|
||||
@@ -2059,10 +2073,8 @@ void ata_sff_postreset(struct ata_link *link, unsigned int *classes)
|
||||
return;
|
||||
|
||||
/* set up device control */
|
||||
if (ap->ops->sff_set_devctl || ap->ioaddr.ctl_addr) {
|
||||
ata_sff_set_devctl(ap, ap->ctl);
|
||||
if (ata_sff_set_devctl(ap, ap->ctl))
|
||||
ap->last_ctl = ap->ctl;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_sff_postreset);
|
||||
|
||||
@@ -2172,18 +2184,18 @@ EXPORT_SYMBOL_GPL(ata_sff_std_ports);
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
|
||||
static int ata_resources_present(struct pci_dev *pdev, int port)
|
||||
static bool ata_resources_present(struct pci_dev *pdev, int port)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Check the PCI resources for this channel are enabled */
|
||||
port = port * 2;
|
||||
port *= 2;
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (pci_resource_start(pdev, port + i) == 0 ||
|
||||
pci_resource_len(pdev, port + i) == 0)
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -107,7 +107,6 @@ static inline void ata_sas_free_tag(unsigned int tag, struct ata_port *ap) { }
|
||||
#ifdef CONFIG_ATA_ACPI
|
||||
extern unsigned int ata_acpi_gtf_filter;
|
||||
extern void ata_acpi_dissociate(struct ata_host *host);
|
||||
extern int ata_acpi_on_suspend(struct ata_port *ap);
|
||||
extern void ata_acpi_on_resume(struct ata_port *ap);
|
||||
extern int ata_acpi_on_devcfg(struct ata_device *dev);
|
||||
extern void ata_acpi_on_disable(struct ata_device *dev);
|
||||
@@ -117,7 +116,6 @@ extern void ata_acpi_bind_dev(struct ata_device *dev);
|
||||
extern acpi_handle ata_dev_acpi_handle(struct ata_device *dev);
|
||||
#else
|
||||
static inline void ata_acpi_dissociate(struct ata_host *host) { }
|
||||
static inline int ata_acpi_on_suspend(struct ata_port *ap) { return 0; }
|
||||
static inline void ata_acpi_on_resume(struct ata_port *ap) { }
|
||||
static inline int ata_acpi_on_devcfg(struct ata_device *dev) { return 0; }
|
||||
static inline void ata_acpi_on_disable(struct ata_device *dev) { }
|
||||
|
||||
@@ -937,7 +937,8 @@ static int arasan_cf_suspend(struct device *dev)
|
||||
dmaengine_terminate_all(acdev->dma_chan);
|
||||
|
||||
cf_exit(acdev);
|
||||
return ata_host_suspend(host, PMSG_SUSPEND);
|
||||
ata_host_suspend(host, PMSG_SUSPEND);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int arasan_cf_resume(struct device *dev)
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#include <linux/ata.h>
|
||||
|
||||
#define DRV_NAME "pata_artop"
|
||||
#define DRV_VERSION "0.4.6"
|
||||
#define DRV_VERSION "0.4.8"
|
||||
|
||||
/*
|
||||
* The ARTOP has 33 Mhz and "over clocked" timing tables. Until we
|
||||
@@ -315,12 +315,15 @@ static struct ata_port_operations artop6260_ops = {
|
||||
|
||||
static void atp8xx_fixup(struct pci_dev *pdev)
|
||||
{
|
||||
if (pdev->device == 0x0005)
|
||||
u8 reg;
|
||||
|
||||
switch (pdev->device) {
|
||||
case 0x0005:
|
||||
/* BIOS may have left us in UDMA, clear it before libata probe */
|
||||
pci_write_config_byte(pdev, 0x54, 0);
|
||||
else if (pdev->device == 0x0008 || pdev->device == 0x0009) {
|
||||
u8 reg;
|
||||
|
||||
break;
|
||||
case 0x0008:
|
||||
case 0x0009:
|
||||
/* Mac systems come up with some registers not set as we
|
||||
will need them */
|
||||
|
||||
@@ -338,6 +341,7 @@ static void atp8xx_fixup(struct pci_dev *pdev)
|
||||
/* Enable IRQ output and burst mode */
|
||||
pci_read_config_byte(pdev, 0x4a, ®);
|
||||
pci_write_config_byte(pdev, 0x4a, (reg & ~0x01) | 0x80);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -394,16 +398,19 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
if (id->driver_data == 0) /* 6210 variant */
|
||||
switch (id->driver_data) {
|
||||
case 0: /* 6210 variant */
|
||||
ppi[0] = &info_6210;
|
||||
else if (id->driver_data == 1) /* 6260 */
|
||||
break;
|
||||
case 1: /* 6260 */
|
||||
ppi[0] = &info_626x;
|
||||
else if (id->driver_data == 2) { /* 6280 or 6280 + fast */
|
||||
unsigned long io = pci_resource_start(pdev, 4);
|
||||
|
||||
ppi[0] = &info_628x;
|
||||
if (inb(io) & 0x10)
|
||||
break;
|
||||
case 2: /* 6280 or 6280 + fast */
|
||||
if (inb(pci_resource_start(pdev, 4)) & 0x10)
|
||||
ppi[0] = &info_628x_fast;
|
||||
else
|
||||
ppi[0] = &info_628x;
|
||||
break;
|
||||
}
|
||||
|
||||
BUG_ON(ppi[0] == NULL);
|
||||
|
||||
@@ -102,7 +102,7 @@ static int atiixp_prereset(struct ata_link *link, unsigned long deadline)
|
||||
|
||||
static void atiixp_set_pio_timing(struct ata_port *ap, struct ata_device *adev, int pio)
|
||||
{
|
||||
static u8 pio_timings[5] = { 0x5D, 0x47, 0x34, 0x22, 0x20 };
|
||||
static const u8 pio_timings[5] = { 0x5D, 0x47, 0x34, 0x22, 0x20 };
|
||||
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
int dn = 2 * ap->port_no + adev->devno;
|
||||
@@ -149,7 +149,7 @@ static void atiixp_set_piomode(struct ata_port *ap, struct ata_device *adev)
|
||||
|
||||
static void atiixp_set_dmamode(struct ata_port *ap, struct ata_device *adev)
|
||||
{
|
||||
static u8 mwdma_timings[5] = { 0x77, 0x21, 0x20 };
|
||||
static const u8 mwdma_timings[5] = { 0x77, 0x21, 0x20 };
|
||||
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
int dma = adev->dma_mode;
|
||||
|
||||
@@ -259,11 +259,8 @@ static int cs5520_reinit_one(struct pci_dev *pdev)
|
||||
static int cs5520_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg)
|
||||
{
|
||||
struct ata_host *host = pci_get_drvdata(pdev);
|
||||
int rc = 0;
|
||||
|
||||
rc = ata_host_suspend(host, mesg);
|
||||
if (rc)
|
||||
return rc;
|
||||
ata_host_suspend(host, mesg);
|
||||
|
||||
pci_save_state(pdev);
|
||||
return 0;
|
||||
|
||||
@@ -416,8 +416,8 @@ static void ep93xx_pata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
|
||||
{
|
||||
struct ep93xx_pata_data *drv_data = ap->host->private_data;
|
||||
|
||||
tf->command = ep93xx_pata_check_status(ap);
|
||||
tf->feature = ep93xx_pata_read_reg(drv_data, IDECTRL_ADDR_FEATURE);
|
||||
tf->status = ep93xx_pata_check_status(ap);
|
||||
tf->error = ep93xx_pata_read_reg(drv_data, IDECTRL_ADDR_FEATURE);
|
||||
tf->nsect = ep93xx_pata_read_reg(drv_data, IDECTRL_ADDR_NSECT);
|
||||
tf->lbal = ep93xx_pata_read_reg(drv_data, IDECTRL_ADDR_LBAL);
|
||||
tf->lbam = ep93xx_pata_read_reg(drv_data, IDECTRL_ADDR_LBAM);
|
||||
|
||||
@@ -554,10 +554,8 @@ static int pata_ftide010_remove(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
static const struct of_device_id pata_ftide010_of_match[] = {
|
||||
{
|
||||
.compatible = "faraday,ftide010",
|
||||
},
|
||||
{},
|
||||
{ .compatible = "faraday,ftide010", },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static struct platform_driver pata_ftide010_driver = {
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include <linux/libata.h>
|
||||
|
||||
#define DRV_NAME "pata_hpt366"
|
||||
#define DRV_VERSION "0.6.11"
|
||||
#define DRV_VERSION "0.6.13"
|
||||
|
||||
struct hpt_clock {
|
||||
u8 xfer_mode;
|
||||
@@ -278,6 +278,40 @@ static void hpt366_set_dmamode(struct ata_port *ap, struct ata_device *adev)
|
||||
hpt366_set_mode(ap, adev, adev->dma_mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* hpt366_prereset - reset the hpt36x bus
|
||||
* @link: ATA link to reset
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* Perform the initial reset handling for the 36x series controllers.
|
||||
* Reset the hardware and state machine,
|
||||
*/
|
||||
|
||||
static int hpt366_prereset(struct ata_link *link, unsigned long deadline)
|
||||
{
|
||||
struct ata_port *ap = link->ap;
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
/*
|
||||
* HPT36x chips have one channel per function and have
|
||||
* both channel enable bits located differently and visible
|
||||
* to both functions -- really stupid design decision... :-(
|
||||
* Bit 4 is for the primary channel, bit 5 for the secondary.
|
||||
*/
|
||||
static const struct pci_bits hpt366_enable_bits = {
|
||||
0x50, 1, 0x30, 0x30
|
||||
};
|
||||
u8 mcr2;
|
||||
|
||||
if (!pci_test_config_bits(pdev, &hpt366_enable_bits))
|
||||
return -ENOENT;
|
||||
|
||||
pci_read_config_byte(pdev, 0x51, &mcr2);
|
||||
if (mcr2 & 0x80)
|
||||
pci_write_config_byte(pdev, 0x51, mcr2 & ~0x80);
|
||||
|
||||
return ata_sff_prereset(link, deadline);
|
||||
}
|
||||
|
||||
static struct scsi_host_template hpt36x_sht = {
|
||||
ATA_BMDMA_SHT(DRV_NAME),
|
||||
};
|
||||
@@ -288,6 +322,7 @@ static struct scsi_host_template hpt36x_sht = {
|
||||
|
||||
static struct ata_port_operations hpt366_port_ops = {
|
||||
.inherits = &ata_bmdma_port_ops,
|
||||
.prereset = hpt366_prereset,
|
||||
.cable_detect = hpt36x_cable_detect,
|
||||
.mode_filter = hpt366_filter,
|
||||
.set_piomode = hpt366_set_piomode,
|
||||
@@ -304,16 +339,20 @@ static struct ata_port_operations hpt366_port_ops = {
|
||||
|
||||
static void hpt36x_init_chipset(struct pci_dev *dev)
|
||||
{
|
||||
u8 drive_fast;
|
||||
u8 mcr1;
|
||||
|
||||
pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (L1_CACHE_BYTES / 4));
|
||||
pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x78);
|
||||
pci_write_config_byte(dev, PCI_MIN_GNT, 0x08);
|
||||
pci_write_config_byte(dev, PCI_MAX_LAT, 0x08);
|
||||
|
||||
pci_read_config_byte(dev, 0x51, &drive_fast);
|
||||
if (drive_fast & 0x80)
|
||||
pci_write_config_byte(dev, 0x51, drive_fast & ~0x80);
|
||||
/*
|
||||
* Now we'll have to force both channels enabled if at least one
|
||||
* of them has been enabled by BIOS...
|
||||
*/
|
||||
pci_read_config_byte(dev, 0x50, &mcr1);
|
||||
if (mcr1 & 0x30)
|
||||
pci_write_config_byte(dev, 0x50, mcr1 | 0x30);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include <linux/libata.h>
|
||||
|
||||
#define DRV_NAME "pata_hpt37x"
|
||||
#define DRV_VERSION "0.6.23"
|
||||
#define DRV_VERSION "0.6.25"
|
||||
|
||||
struct hpt_clock {
|
||||
u8 xfer_speed;
|
||||
@@ -394,6 +394,7 @@ static int hpt37x_pre_reset(struct ata_link *link, unsigned long deadline)
|
||||
{ 0x50, 1, 0x04, 0x04 },
|
||||
{ 0x54, 1, 0x04, 0x04 }
|
||||
};
|
||||
u8 mcr2;
|
||||
|
||||
if (!pci_test_config_bits(pdev, &hpt37x_enable_bits[ap->port_no]))
|
||||
return -ENOENT;
|
||||
@@ -402,25 +403,29 @@ static int hpt37x_pre_reset(struct ata_link *link, unsigned long deadline)
|
||||
pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
|
||||
udelay(100);
|
||||
|
||||
/*
|
||||
* Disable the "fast interrupt" prediction. Don't hold off
|
||||
* on interrupts. (== 0x01 despite what the docs say)
|
||||
*/
|
||||
pci_read_config_byte(pdev, 0x51 + 4 * ap->port_no, &mcr2);
|
||||
/* Is it HPT370/A? */
|
||||
if (pdev->device == PCI_DEVICE_ID_TTI_HPT366 && pdev->revision < 5) {
|
||||
mcr2 &= ~0x02;
|
||||
mcr2 |= 0x01;
|
||||
} else {
|
||||
mcr2 &= ~0x07;
|
||||
}
|
||||
pci_write_config_byte(pdev, 0x51 + 4 * ap->port_no, mcr2);
|
||||
|
||||
return ata_sff_prereset(link, deadline);
|
||||
}
|
||||
|
||||
static void hpt370_set_mode(struct ata_port *ap, struct ata_device *adev,
|
||||
static void hpt37x_set_mode(struct ata_port *ap, struct ata_device *adev,
|
||||
u8 mode)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
u32 addr1, addr2;
|
||||
int addr = 0x40 + 4 * (adev->devno + 2 * ap->port_no);
|
||||
u32 reg, timing, mask;
|
||||
u8 fast;
|
||||
|
||||
addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no);
|
||||
addr2 = 0x51 + 4 * ap->port_no;
|
||||
|
||||
/* Fast interrupt prediction disable, hold off interrupt disable */
|
||||
pci_read_config_byte(pdev, addr2, &fast);
|
||||
fast &= ~0x02;
|
||||
fast |= 0x01;
|
||||
pci_write_config_byte(pdev, addr2, fast);
|
||||
|
||||
/* Determine timing mask and find matching mode entry */
|
||||
if (mode < XFER_MW_DMA_0)
|
||||
@@ -432,34 +437,34 @@ static void hpt370_set_mode(struct ata_port *ap, struct ata_device *adev,
|
||||
|
||||
timing = hpt37x_find_mode(ap, mode);
|
||||
|
||||
pci_read_config_dword(pdev, addr1, ®);
|
||||
pci_read_config_dword(pdev, addr, ®);
|
||||
reg = (reg & ~mask) | (timing & mask);
|
||||
pci_write_config_dword(pdev, addr1, reg);
|
||||
pci_write_config_dword(pdev, addr, reg);
|
||||
}
|
||||
/**
|
||||
* hpt370_set_piomode - PIO setup
|
||||
* hpt37x_set_piomode - PIO setup
|
||||
* @ap: ATA interface
|
||||
* @adev: device on the interface
|
||||
*
|
||||
* Perform PIO mode setup.
|
||||
*/
|
||||
|
||||
static void hpt370_set_piomode(struct ata_port *ap, struct ata_device *adev)
|
||||
static void hpt37x_set_piomode(struct ata_port *ap, struct ata_device *adev)
|
||||
{
|
||||
hpt370_set_mode(ap, adev, adev->pio_mode);
|
||||
hpt37x_set_mode(ap, adev, adev->pio_mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* hpt370_set_dmamode - DMA timing setup
|
||||
* hpt37x_set_dmamode - DMA timing setup
|
||||
* @ap: ATA interface
|
||||
* @adev: Device being configured
|
||||
*
|
||||
* Set up the channel for MWDMA or UDMA modes.
|
||||
*/
|
||||
|
||||
static void hpt370_set_dmamode(struct ata_port *ap, struct ata_device *adev)
|
||||
static void hpt37x_set_dmamode(struct ata_port *ap, struct ata_device *adev)
|
||||
{
|
||||
hpt370_set_mode(ap, adev, adev->dma_mode);
|
||||
hpt37x_set_mode(ap, adev, adev->dma_mode);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -499,63 +504,6 @@ static void hpt370_bmdma_stop(struct ata_queued_cmd *qc)
|
||||
ata_bmdma_stop(qc);
|
||||
}
|
||||
|
||||
static void hpt372_set_mode(struct ata_port *ap, struct ata_device *adev,
|
||||
u8 mode)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
u32 addr1, addr2;
|
||||
u32 reg, timing, mask;
|
||||
u8 fast;
|
||||
|
||||
addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no);
|
||||
addr2 = 0x51 + 4 * ap->port_no;
|
||||
|
||||
/* Fast interrupt prediction disable, hold off interrupt disable */
|
||||
pci_read_config_byte(pdev, addr2, &fast);
|
||||
fast &= ~0x07;
|
||||
pci_write_config_byte(pdev, addr2, fast);
|
||||
|
||||
/* Determine timing mask and find matching mode entry */
|
||||
if (mode < XFER_MW_DMA_0)
|
||||
mask = 0xcfc3ffff;
|
||||
else if (mode < XFER_UDMA_0)
|
||||
mask = 0x31c001ff;
|
||||
else
|
||||
mask = 0x303c0000;
|
||||
|
||||
timing = hpt37x_find_mode(ap, mode);
|
||||
|
||||
pci_read_config_dword(pdev, addr1, ®);
|
||||
reg = (reg & ~mask) | (timing & mask);
|
||||
pci_write_config_dword(pdev, addr1, reg);
|
||||
}
|
||||
|
||||
/**
|
||||
* hpt372_set_piomode - PIO setup
|
||||
* @ap: ATA interface
|
||||
* @adev: device on the interface
|
||||
*
|
||||
* Perform PIO mode setup.
|
||||
*/
|
||||
|
||||
static void hpt372_set_piomode(struct ata_port *ap, struct ata_device *adev)
|
||||
{
|
||||
hpt372_set_mode(ap, adev, adev->pio_mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* hpt372_set_dmamode - DMA timing setup
|
||||
* @ap: ATA interface
|
||||
* @adev: Device being configured
|
||||
*
|
||||
* Set up the channel for MWDMA or UDMA modes.
|
||||
*/
|
||||
|
||||
static void hpt372_set_dmamode(struct ata_port *ap, struct ata_device *adev)
|
||||
{
|
||||
hpt372_set_mode(ap, adev, adev->dma_mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* hpt37x_bmdma_stop - DMA engine stop
|
||||
* @qc: ATA command
|
||||
@@ -593,8 +541,8 @@ static struct ata_port_operations hpt370_port_ops = {
|
||||
|
||||
.mode_filter = hpt370_filter,
|
||||
.cable_detect = hpt37x_cable_detect,
|
||||
.set_piomode = hpt370_set_piomode,
|
||||
.set_dmamode = hpt370_set_dmamode,
|
||||
.set_piomode = hpt37x_set_piomode,
|
||||
.set_dmamode = hpt37x_set_dmamode,
|
||||
.prereset = hpt37x_pre_reset,
|
||||
};
|
||||
|
||||
@@ -608,8 +556,7 @@ static struct ata_port_operations hpt370a_port_ops = {
|
||||
};
|
||||
|
||||
/*
|
||||
* Configuration for HPT371 and HPT302. Slightly different PIO and DMA
|
||||
* mode setting functionality.
|
||||
* Configuration for HPT371 and HPT302.
|
||||
*/
|
||||
|
||||
static struct ata_port_operations hpt302_port_ops = {
|
||||
@@ -618,8 +565,8 @@ static struct ata_port_operations hpt302_port_ops = {
|
||||
.bmdma_stop = hpt37x_bmdma_stop,
|
||||
|
||||
.cable_detect = hpt37x_cable_detect,
|
||||
.set_piomode = hpt372_set_piomode,
|
||||
.set_dmamode = hpt372_set_dmamode,
|
||||
.set_piomode = hpt37x_set_piomode,
|
||||
.set_dmamode = hpt37x_set_dmamode,
|
||||
.prereset = hpt37x_pre_reset,
|
||||
};
|
||||
|
||||
|
||||
@@ -24,10 +24,9 @@
|
||||
#include <linux/libata.h>
|
||||
|
||||
#define DRV_NAME "pata_hpt3x2n"
|
||||
#define DRV_VERSION "0.3.15"
|
||||
#define DRV_VERSION "0.3.18"
|
||||
|
||||
enum {
|
||||
HPT_PCI_FAST = (1 << 31),
|
||||
PCI66 = (1 << 1),
|
||||
USE_DPLL = (1 << 0)
|
||||
};
|
||||
@@ -37,11 +36,6 @@ struct hpt_clock {
|
||||
u32 timing;
|
||||
};
|
||||
|
||||
struct hpt_chip {
|
||||
const char *name;
|
||||
struct hpt_clock *clocks[3];
|
||||
};
|
||||
|
||||
/* key for bus clock timings
|
||||
* bit
|
||||
* 0:3 data_high_time. Inactive time of DIOW_/DIOR_ for PIO and MW DMA.
|
||||
@@ -168,11 +162,24 @@ static int hpt3x2n_pre_reset(struct ata_link *link, unsigned long deadline)
|
||||
{
|
||||
struct ata_port *ap = link->ap;
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
static const struct pci_bits hpt3x2n_enable_bits[] = {
|
||||
{ 0x50, 1, 0x04, 0x04 },
|
||||
{ 0x54, 1, 0x04, 0x04 }
|
||||
};
|
||||
u8 mcr2;
|
||||
|
||||
if (!pci_test_config_bits(pdev, &hpt3x2n_enable_bits[ap->port_no]))
|
||||
return -ENOENT;
|
||||
|
||||
/* Reset the state machine */
|
||||
pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
|
||||
udelay(100);
|
||||
|
||||
/* Fast interrupt prediction disable, hold off interrupt disable */
|
||||
pci_read_config_byte(pdev, 0x51 + 4 * ap->port_no, &mcr2);
|
||||
mcr2 &= ~0x07;
|
||||
pci_write_config_byte(pdev, 0x51 + 4 * ap->port_no, mcr2);
|
||||
|
||||
return ata_sff_prereset(link, deadline);
|
||||
}
|
||||
|
||||
@@ -180,17 +187,8 @@ static void hpt3x2n_set_mode(struct ata_port *ap, struct ata_device *adev,
|
||||
u8 mode)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
u32 addr1, addr2;
|
||||
int addr = 0x40 + 4 * (adev->devno + 2 * ap->port_no);
|
||||
u32 reg, timing, mask;
|
||||
u8 fast;
|
||||
|
||||
addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no);
|
||||
addr2 = 0x51 + 4 * ap->port_no;
|
||||
|
||||
/* Fast interrupt prediction disable, hold off interrupt disable */
|
||||
pci_read_config_byte(pdev, addr2, &fast);
|
||||
fast &= ~0x07;
|
||||
pci_write_config_byte(pdev, addr2, fast);
|
||||
|
||||
/* Determine timing mask and find matching mode entry */
|
||||
if (mode < XFER_MW_DMA_0)
|
||||
@@ -202,9 +200,9 @@ static void hpt3x2n_set_mode(struct ata_port *ap, struct ata_device *adev,
|
||||
|
||||
timing = hpt3x2n_find_mode(ap, mode);
|
||||
|
||||
pci_read_config_dword(pdev, addr1, ®);
|
||||
pci_read_config_dword(pdev, addr, ®);
|
||||
reg = (reg & ~mask) | (timing & mask);
|
||||
pci_write_config_dword(pdev, addr1, reg);
|
||||
pci_write_config_dword(pdev, addr, reg);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -244,7 +242,7 @@ static void hpt3x2n_bmdma_stop(struct ata_queued_cmd *qc)
|
||||
{
|
||||
struct ata_port *ap = qc->ap;
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
int mscreg = 0x50 + 2 * ap->port_no;
|
||||
int mscreg = 0x50 + 4 * ap->port_no;
|
||||
u8 bwsr_stat, msc_stat;
|
||||
|
||||
pci_read_config_byte(pdev, 0x6A, &bwsr_stat);
|
||||
|
||||
@@ -223,17 +223,14 @@ static int pata_imx_suspend(struct device *dev)
|
||||
{
|
||||
struct ata_host *host = dev_get_drvdata(dev);
|
||||
struct pata_imx_priv *priv = host->private_data;
|
||||
int ret;
|
||||
|
||||
ret = ata_host_suspend(host, PMSG_SUSPEND);
|
||||
if (!ret) {
|
||||
__raw_writel(0, priv->host_regs + PATA_IMX_ATA_INT_EN);
|
||||
priv->ata_ctl =
|
||||
__raw_readl(priv->host_regs + PATA_IMX_ATA_CONTROL);
|
||||
clk_disable_unprepare(priv->clk);
|
||||
}
|
||||
ata_host_suspend(host, PMSG_SUSPEND);
|
||||
|
||||
return ret;
|
||||
__raw_writel(0, priv->host_regs + PATA_IMX_ATA_INT_EN);
|
||||
priv->ata_ctl = __raw_readl(priv->host_regs + PATA_IMX_ATA_CONTROL);
|
||||
clk_disable_unprepare(priv->clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pata_imx_resume(struct device *dev)
|
||||
|
||||
@@ -293,7 +293,7 @@ static int ixp4xx_pata_probe(struct platform_device *pdev)
|
||||
|
||||
static const struct of_device_id ixp4xx_pata_of_match[] = {
|
||||
{ .compatible = "intel,ixp4xx-compact-flash", },
|
||||
{ },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static struct platform_driver ixp4xx_pata_platform_driver = {
|
||||
|
||||
@@ -853,12 +853,8 @@ static int pata_macio_slave_config(struct scsi_device *sdev)
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int pata_macio_do_suspend(struct pata_macio_priv *priv, pm_message_t mesg)
|
||||
{
|
||||
int rc;
|
||||
|
||||
/* First, core libata suspend to do most of the work */
|
||||
rc = ata_host_suspend(priv->host, mesg);
|
||||
if (rc)
|
||||
return rc;
|
||||
ata_host_suspend(priv->host, mesg);
|
||||
|
||||
/* Restore to default timings */
|
||||
pata_macio_default_timings(priv);
|
||||
@@ -1333,19 +1329,11 @@ static int pata_macio_pci_resume(struct pci_dev *pdev)
|
||||
|
||||
static const struct of_device_id pata_macio_match[] =
|
||||
{
|
||||
{
|
||||
.name = "IDE",
|
||||
},
|
||||
{
|
||||
.name = "ATA",
|
||||
},
|
||||
{
|
||||
.type = "ide",
|
||||
},
|
||||
{
|
||||
.type = "ata",
|
||||
},
|
||||
{},
|
||||
{ .name = "IDE", },
|
||||
{ .name = "ATA", },
|
||||
{ .type = "ide", },
|
||||
{ .type = "ata", },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, pata_macio_match);
|
||||
|
||||
|
||||
@@ -736,7 +736,7 @@ static int mpc52xx_ata_probe(struct platform_device *op)
|
||||
}
|
||||
|
||||
/* Prepare our private structure */
|
||||
priv = devm_kzalloc(&op->dev, sizeof(*priv), GFP_ATOMIC);
|
||||
priv = devm_kzalloc(&op->dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv) {
|
||||
rv = -ENOMEM;
|
||||
goto err1;
|
||||
@@ -824,7 +824,8 @@ mpc52xx_ata_suspend(struct platform_device *op, pm_message_t state)
|
||||
{
|
||||
struct ata_host *host = platform_get_drvdata(op);
|
||||
|
||||
return ata_host_suspend(host, state);
|
||||
ata_host_suspend(host, state);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -849,7 +850,7 @@ mpc52xx_ata_resume(struct platform_device *op)
|
||||
static const struct of_device_id mpc52xx_ata_of_match[] = {
|
||||
{ .compatible = "fsl,mpc5200-ata", },
|
||||
{ .compatible = "mpc5200-ata", },
|
||||
{},
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -264,8 +264,8 @@ void ns87560_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
|
||||
{
|
||||
struct ata_ioports *ioaddr = &ap->ioaddr;
|
||||
|
||||
tf->command = ns87560_check_status(ap);
|
||||
tf->feature = ioread8(ioaddr->error_addr);
|
||||
tf->status = ns87560_check_status(ap);
|
||||
tf->error = ioread8(ioaddr->error_addr);
|
||||
tf->nsect = ioread8(ioaddr->nsect_addr);
|
||||
tf->lbal = ioread8(ioaddr->lbal_addr);
|
||||
tf->lbam = ioread8(ioaddr->lbam_addr);
|
||||
|
||||
@@ -382,7 +382,7 @@ static void octeon_cf_tf_read16(struct ata_port *ap, struct ata_taskfile *tf)
|
||||
void __iomem *base = ap->ioaddr.data_addr;
|
||||
|
||||
blob = __raw_readw(base + 0xc);
|
||||
tf->feature = blob >> 8;
|
||||
tf->error = blob >> 8;
|
||||
|
||||
blob = __raw_readw(base + 2);
|
||||
tf->nsect = blob & 0xff;
|
||||
@@ -394,7 +394,7 @@ static void octeon_cf_tf_read16(struct ata_port *ap, struct ata_taskfile *tf)
|
||||
|
||||
blob = __raw_readw(base + 6);
|
||||
tf->device = blob & 0xff;
|
||||
tf->command = blob >> 8;
|
||||
tf->status = blob >> 8;
|
||||
|
||||
if (tf->flags & ATA_TFLAG_LBA48) {
|
||||
if (likely(ap->ioaddr.ctl_addr)) {
|
||||
@@ -1006,10 +1006,8 @@ static void octeon_cf_shutdown(struct device *dev)
|
||||
}
|
||||
|
||||
static const struct of_device_id octeon_cf_match[] = {
|
||||
{
|
||||
.compatible = "cavium,ebt3000-compact-flash",
|
||||
},
|
||||
{},
|
||||
{ .compatible = "cavium,ebt3000-compact-flash", },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, octeon_cf_match);
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ static int pata_of_platform_probe(struct platform_device *ofdev)
|
||||
|
||||
static const struct of_device_id pata_of_platform_match[] = {
|
||||
{ .compatible = "ata-generic", },
|
||||
{ },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, pata_of_platform_match);
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ static void pdc202xx_configure_piomode(struct ata_port *ap, struct ata_device *a
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
int port = 0x60 + 8 * ap->port_no + 4 * adev->devno;
|
||||
static u16 pio_timing[5] = {
|
||||
static const u16 pio_timing[5] = {
|
||||
0x0913, 0x050C , 0x0308, 0x0206, 0x0104
|
||||
};
|
||||
u8 r_ap, r_bp;
|
||||
|
||||
@@ -200,22 +200,16 @@ static int pata_platform_probe(struct platform_device *pdev)
|
||||
/*
|
||||
* Get the I/O base first
|
||||
*/
|
||||
io_res = platform_get_resource(pdev, IORESOURCE_IO, 0);
|
||||
if (io_res == NULL) {
|
||||
io_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (unlikely(io_res == NULL))
|
||||
return -EINVAL;
|
||||
}
|
||||
io_res = platform_get_mem_or_io(pdev, 0);
|
||||
if (!io_res)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* Then the CTL base
|
||||
*/
|
||||
ctl_res = platform_get_resource(pdev, IORESOURCE_IO, 1);
|
||||
if (ctl_res == NULL) {
|
||||
ctl_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
||||
if (unlikely(ctl_res == NULL))
|
||||
return -EINVAL;
|
||||
}
|
||||
ctl_res = platform_get_mem_or_io(pdev, 1);
|
||||
if (!ctl_res)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* And the IRQ
|
||||
|
||||
@@ -164,10 +164,10 @@ static int pxa_ata_probe(struct platform_device *pdev)
|
||||
struct resource *cmd_res;
|
||||
struct resource *ctl_res;
|
||||
struct resource *dma_res;
|
||||
struct resource *irq_res;
|
||||
struct pata_pxa_pdata *pdata = dev_get_platdata(&pdev->dev);
|
||||
struct dma_slave_config config;
|
||||
int ret = 0;
|
||||
int irq;
|
||||
|
||||
/*
|
||||
* Resource validation, three resources are needed:
|
||||
@@ -205,9 +205,9 @@ static int pxa_ata_probe(struct platform_device *pdev)
|
||||
/*
|
||||
* IRQ pin
|
||||
*/
|
||||
irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
||||
if (unlikely(irq_res == NULL))
|
||||
return -EINVAL;
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0)
|
||||
return irq;
|
||||
|
||||
/*
|
||||
* Allocate the host
|
||||
@@ -287,7 +287,7 @@ static int pxa_ata_probe(struct platform_device *pdev)
|
||||
/*
|
||||
* Activate the ATA host
|
||||
*/
|
||||
ret = ata_host_activate(host, irq_res->start, ata_sff_interrupt,
|
||||
ret = ata_host_activate(host, irq, ata_sff_interrupt,
|
||||
pdata->irq_flags, &pxa_ata_sht);
|
||||
if (ret)
|
||||
dma_release_channel(data->dma_chan);
|
||||
|
||||
@@ -213,7 +213,7 @@ static void pata_s3c_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
|
||||
{
|
||||
struct ata_ioports *ioaddr = &ap->ioaddr;
|
||||
|
||||
tf->feature = ata_inb(ap->host, ioaddr->error_addr);
|
||||
tf->error = ata_inb(ap->host, ioaddr->error_addr);
|
||||
tf->nsect = ata_inb(ap->host, ioaddr->nsect_addr);
|
||||
tf->lbal = ata_inb(ap->host, ioaddr->lbal_addr);
|
||||
tf->lbam = ata_inb(ap->host, ioaddr->lbam_addr);
|
||||
@@ -308,8 +308,7 @@ static void pata_s3c_dev_select(struct ata_port *ap, unsigned int device)
|
||||
/*
|
||||
* pata_s3c_devchk - PATA device presence detection
|
||||
*/
|
||||
static unsigned int pata_s3c_devchk(struct ata_port *ap,
|
||||
unsigned int device)
|
||||
static bool pata_s3c_devchk(struct ata_port *ap, unsigned int device)
|
||||
{
|
||||
struct ata_ioports *ioaddr = &ap->ioaddr;
|
||||
u8 nsect, lbal;
|
||||
@@ -329,9 +328,9 @@ static unsigned int pata_s3c_devchk(struct ata_port *ap,
|
||||
lbal = ata_inb(ap->host, ioaddr->lbal_addr);
|
||||
|
||||
if ((nsect == 0x55) && (lbal == 0xaa))
|
||||
return 1; /* we found a device */
|
||||
return true; /* we found a device */
|
||||
|
||||
return 0; /* nothing found */
|
||||
return false; /* nothing found */
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -608,7 +607,8 @@ static int pata_s3c_suspend(struct device *dev)
|
||||
{
|
||||
struct ata_host *host = dev_get_drvdata(dev);
|
||||
|
||||
return ata_host_suspend(host, PMSG_SUSPEND);
|
||||
ata_host_suspend(host, PMSG_SUSPEND);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pata_s3c_resume(struct device *dev)
|
||||
|
||||
@@ -198,11 +198,8 @@ static const struct pci_device_id triflex[] = {
|
||||
static int triflex_ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg)
|
||||
{
|
||||
struct ata_host *host = pci_get_drvdata(pdev);
|
||||
int rc = 0;
|
||||
|
||||
rc = ata_host_suspend(host, mesg);
|
||||
if (rc)
|
||||
return rc;
|
||||
ata_host_suspend(host, mesg);
|
||||
|
||||
/*
|
||||
* We must not disable or powerdown the device.
|
||||
|
||||
@@ -1544,7 +1544,9 @@ static int sata_fsl_remove(struct platform_device *ofdev)
|
||||
static int sata_fsl_suspend(struct platform_device *op, pm_message_t state)
|
||||
{
|
||||
struct ata_host *host = platform_get_drvdata(op);
|
||||
return ata_host_suspend(host, state);
|
||||
|
||||
ata_host_suspend(host, state);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sata_fsl_resume(struct platform_device *op)
|
||||
@@ -1577,13 +1579,9 @@ static int sata_fsl_resume(struct platform_device *op)
|
||||
#endif
|
||||
|
||||
static const struct of_device_id fsl_sata_match[] = {
|
||||
{
|
||||
.compatible = "fsl,pq-sata",
|
||||
},
|
||||
{
|
||||
.compatible = "fsl,pq-sata-v2",
|
||||
},
|
||||
{},
|
||||
{ .compatible = "fsl,pq-sata", },
|
||||
{ .compatible = "fsl,pq-sata-v2", },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(of, fsl_sata_match);
|
||||
|
||||
@@ -419,10 +419,8 @@ static int gemini_sata_remove(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
static const struct of_device_id gemini_sata_of_match[] = {
|
||||
{
|
||||
.compatible = "cortina,gemini-sata-bridge",
|
||||
},
|
||||
{},
|
||||
{ .compatible = "cortina,gemini-sata-bridge", },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static struct platform_driver gemini_sata_driver = {
|
||||
|
||||
@@ -400,7 +400,7 @@ static int ahci_highbank_hardreset(struct ata_link *link, unsigned int *class,
|
||||
|
||||
/* clear D2H reception area to properly wait for D2H FIS */
|
||||
ata_tf_init(link->device, &tf);
|
||||
tf.command = ATA_BUSY;
|
||||
tf.status = ATA_BUSY;
|
||||
ata_tf_to_fis(&tf, 0, 0, d2h_fis);
|
||||
|
||||
do {
|
||||
@@ -444,7 +444,7 @@ static struct scsi_host_template ahci_highbank_platform_sht = {
|
||||
|
||||
static const struct of_device_id ahci_of_match[] = {
|
||||
{ .compatible = "calxeda,hb-ahci" },
|
||||
{},
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ahci_of_match);
|
||||
|
||||
@@ -587,7 +587,8 @@ static int ahci_highbank_suspend(struct device *dev)
|
||||
writel(ctl, mmio + HOST_CTL);
|
||||
readl(mmio + HOST_CTL); /* flush */
|
||||
|
||||
return ata_host_suspend(host, PMSG_SUSPEND);
|
||||
ata_host_suspend(host, PMSG_SUSPEND);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ahci_highbank_resume(struct device *dev)
|
||||
|
||||
@@ -557,13 +557,13 @@ static void inic_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
|
||||
{
|
||||
void __iomem *port_base = inic_port_base(ap);
|
||||
|
||||
tf->feature = readb(port_base + PORT_TF_FEATURE);
|
||||
tf->error = readb(port_base + PORT_TF_FEATURE);
|
||||
tf->nsect = readb(port_base + PORT_TF_NSECT);
|
||||
tf->lbal = readb(port_base + PORT_TF_LBAL);
|
||||
tf->lbam = readb(port_base + PORT_TF_LBAM);
|
||||
tf->lbah = readb(port_base + PORT_TF_LBAH);
|
||||
tf->device = readb(port_base + PORT_TF_DEVICE);
|
||||
tf->command = readb(port_base + PORT_TF_COMMAND);
|
||||
tf->status = readb(port_base + PORT_TF_COMMAND);
|
||||
}
|
||||
|
||||
static bool inic_qc_fill_rtf(struct ata_queued_cmd *qc)
|
||||
@@ -580,11 +580,11 @@ static bool inic_qc_fill_rtf(struct ata_queued_cmd *qc)
|
||||
*/
|
||||
inic_tf_read(qc->ap, &tf);
|
||||
|
||||
if (!(tf.command & ATA_ERR))
|
||||
if (!(tf.status & ATA_ERR))
|
||||
return false;
|
||||
|
||||
rtf->command = tf.command;
|
||||
rtf->feature = tf.feature;
|
||||
rtf->status = tf.status;
|
||||
rtf->error = tf.error;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -4235,10 +4235,10 @@ static int mv_platform_remove(struct platform_device *pdev)
|
||||
static int mv_platform_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
{
|
||||
struct ata_host *host = platform_get_drvdata(pdev);
|
||||
|
||||
if (host)
|
||||
return ata_host_suspend(host, state);
|
||||
else
|
||||
return 0;
|
||||
ata_host_suspend(host, state);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mv_platform_resume(struct platform_device *pdev)
|
||||
@@ -4277,7 +4277,7 @@ static int mv_platform_resume(struct platform_device *pdev)
|
||||
static const struct of_device_id mv_sata_dt_ids[] = {
|
||||
{ .compatible = "marvell,armada-370-sata", },
|
||||
{ .compatible = "marvell,orion-sata", },
|
||||
{},
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mv_sata_dt_ids);
|
||||
#endif
|
||||
|
||||
@@ -18,10 +18,6 @@
|
||||
|
||||
#define DRV_NAME "sata_rcar"
|
||||
|
||||
/* SH-Navi2G/ATAPI-ATA compatible task registers */
|
||||
#define DATA_REG 0x100
|
||||
#define SDEVCON_REG 0x138
|
||||
|
||||
/* SH-Navi2G/ATAPI module compatible control registers */
|
||||
#define ATAPI_CONTROL1_REG 0x180
|
||||
#define ATAPI_STATUS_REG 0x184
|
||||
@@ -283,8 +279,7 @@ static void sata_rcar_dev_select(struct ata_port *ap, unsigned int device)
|
||||
ata_sff_pause(ap); /* needed; also flushes, for mmio */
|
||||
}
|
||||
|
||||
static unsigned int sata_rcar_ata_devchk(struct ata_port *ap,
|
||||
unsigned int device)
|
||||
static bool sata_rcar_ata_devchk(struct ata_port *ap, unsigned int device)
|
||||
{
|
||||
struct ata_ioports *ioaddr = &ap->ioaddr;
|
||||
u8 nsect, lbal;
|
||||
@@ -304,9 +299,9 @@ static unsigned int sata_rcar_ata_devchk(struct ata_port *ap,
|
||||
lbal = ioread32(ioaddr->lbal_addr);
|
||||
|
||||
if (nsect == 0x55 && lbal == 0xaa)
|
||||
return 1; /* found a device */
|
||||
return true; /* found a device */
|
||||
|
||||
return 0; /* nothing found */
|
||||
return false; /* nothing found */
|
||||
}
|
||||
|
||||
static int sata_rcar_wait_after_reset(struct ata_link *link,
|
||||
@@ -399,8 +394,8 @@ static void sata_rcar_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
|
||||
{
|
||||
struct ata_ioports *ioaddr = &ap->ioaddr;
|
||||
|
||||
tf->command = sata_rcar_check_status(ap);
|
||||
tf->feature = ioread32(ioaddr->error_addr);
|
||||
tf->status = sata_rcar_check_status(ap);
|
||||
tf->error = ioread32(ioaddr->error_addr);
|
||||
tf->nsect = ioread32(ioaddr->nsect_addr);
|
||||
tf->lbal = ioread32(ioaddr->lbal_addr);
|
||||
tf->lbam = ioread32(ioaddr->lbam_addr);
|
||||
@@ -857,7 +852,7 @@ static const struct of_device_id sata_rcar_match[] = {
|
||||
.compatible = "renesas,rcar-gen3-sata",
|
||||
.data = (void *)RCAR_GEN3_SATA
|
||||
},
|
||||
{ },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, sata_rcar_match);
|
||||
|
||||
@@ -945,19 +940,17 @@ static int sata_rcar_suspend(struct device *dev)
|
||||
struct ata_host *host = dev_get_drvdata(dev);
|
||||
struct sata_rcar_priv *priv = host->private_data;
|
||||
void __iomem *base = priv->base;
|
||||
int ret;
|
||||
|
||||
ret = ata_host_suspend(host, PMSG_SUSPEND);
|
||||
if (!ret) {
|
||||
/* disable interrupts */
|
||||
iowrite32(0, base + ATAPI_INT_ENABLE_REG);
|
||||
/* mask */
|
||||
iowrite32(priv->sataint_mask, base + SATAINTMASK_REG);
|
||||
ata_host_suspend(host, PMSG_SUSPEND);
|
||||
|
||||
pm_runtime_put(dev);
|
||||
}
|
||||
/* disable interrupts */
|
||||
iowrite32(0, base + ATAPI_INT_ENABLE_REG);
|
||||
/* mask */
|
||||
iowrite32(priv->sataint_mask, base + SATAINTMASK_REG);
|
||||
|
||||
return ret;
|
||||
pm_runtime_put(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sata_rcar_resume(struct device *dev)
|
||||
|
||||
@@ -194,24 +194,24 @@ static void k2_sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
|
||||
static void k2_sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
|
||||
{
|
||||
struct ata_ioports *ioaddr = &ap->ioaddr;
|
||||
u16 nsect, lbal, lbam, lbah, feature;
|
||||
u16 nsect, lbal, lbam, lbah, error;
|
||||
|
||||
tf->command = k2_stat_check_status(ap);
|
||||
tf->status = k2_stat_check_status(ap);
|
||||
tf->device = readw(ioaddr->device_addr);
|
||||
feature = readw(ioaddr->error_addr);
|
||||
error = readw(ioaddr->error_addr);
|
||||
nsect = readw(ioaddr->nsect_addr);
|
||||
lbal = readw(ioaddr->lbal_addr);
|
||||
lbam = readw(ioaddr->lbam_addr);
|
||||
lbah = readw(ioaddr->lbah_addr);
|
||||
|
||||
tf->feature = feature;
|
||||
tf->error = error;
|
||||
tf->nsect = nsect;
|
||||
tf->lbal = lbal;
|
||||
tf->lbam = lbam;
|
||||
tf->lbah = lbah;
|
||||
|
||||
if (tf->flags & ATA_TFLAG_LBA48) {
|
||||
tf->hob_feature = feature >> 8;
|
||||
tf->hob_feature = error >> 8;
|
||||
tf->hob_nsect = nsect >> 8;
|
||||
tf->hob_lbal = lbal >> 8;
|
||||
tf->hob_lbam = lbam >> 8;
|
||||
|
||||
@@ -183,24 +183,24 @@ static void vsc_sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
|
||||
static void vsc_sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
|
||||
{
|
||||
struct ata_ioports *ioaddr = &ap->ioaddr;
|
||||
u16 nsect, lbal, lbam, lbah, feature;
|
||||
u16 nsect, lbal, lbam, lbah, error;
|
||||
|
||||
tf->command = ata_sff_check_status(ap);
|
||||
tf->status = ata_sff_check_status(ap);
|
||||
tf->device = readw(ioaddr->device_addr);
|
||||
feature = readw(ioaddr->error_addr);
|
||||
error = readw(ioaddr->error_addr);
|
||||
nsect = readw(ioaddr->nsect_addr);
|
||||
lbal = readw(ioaddr->lbal_addr);
|
||||
lbam = readw(ioaddr->lbam_addr);
|
||||
lbah = readw(ioaddr->lbah_addr);
|
||||
|
||||
tf->feature = feature;
|
||||
tf->error = error;
|
||||
tf->nsect = nsect;
|
||||
tf->lbal = lbal;
|
||||
tf->lbam = lbam;
|
||||
tf->lbah = lbah;
|
||||
|
||||
if (tf->flags & ATA_TFLAG_LBA48) {
|
||||
tf->hob_feature = feature >> 8;
|
||||
tf->hob_feature = error >> 8;
|
||||
tf->hob_nsect = nsect >> 8;
|
||||
tf->hob_lbal = lbal >> 8;
|
||||
tf->hob_lbam = lbam >> 8;
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <linux/stat.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/sysfs.h>
|
||||
|
||||
#include <linux/mmc/card.h>
|
||||
#include <linux/mmc/host.h>
|
||||
@@ -34,13 +35,13 @@ static ssize_t type_show(struct device *dev,
|
||||
|
||||
switch (card->type) {
|
||||
case MMC_TYPE_MMC:
|
||||
return sprintf(buf, "MMC\n");
|
||||
return sysfs_emit(buf, "MMC\n");
|
||||
case MMC_TYPE_SD:
|
||||
return sprintf(buf, "SD\n");
|
||||
return sysfs_emit(buf, "SD\n");
|
||||
case MMC_TYPE_SDIO:
|
||||
return sprintf(buf, "SDIO\n");
|
||||
return sysfs_emit(buf, "SDIO\n");
|
||||
case MMC_TYPE_SD_COMBO:
|
||||
return sprintf(buf, "SDcombo\n");
|
||||
return sysfs_emit(buf, "SDcombo\n");
|
||||
default:
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#define _MMC_CORE_BUS_H
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/sysfs.h>
|
||||
|
||||
struct mmc_host;
|
||||
struct mmc_card;
|
||||
@@ -17,7 +18,7 @@ struct mmc_card;
|
||||
static ssize_t mmc_##name##_show (struct device *dev, struct device_attribute *attr, char *buf) \
|
||||
{ \
|
||||
struct mmc_card *card = mmc_dev_to_card(dev); \
|
||||
return sprintf(buf, fmt, args); \
|
||||
return sysfs_emit(buf, fmt, args); \
|
||||
} \
|
||||
static DEVICE_ATTR(name, S_IRUGO, mmc_##name##_show, NULL)
|
||||
|
||||
|
||||
@@ -588,6 +588,25 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
|
||||
|
||||
EXPORT_SYMBOL(mmc_alloc_host);
|
||||
|
||||
static int mmc_validate_host_caps(struct mmc_host *host)
|
||||
{
|
||||
struct device *dev = host->parent;
|
||||
u32 caps = host->caps, caps2 = host->caps2;
|
||||
|
||||
if (caps & MMC_CAP_SDIO_IRQ && !host->ops->enable_sdio_irq) {
|
||||
dev_warn(dev, "missing ->enable_sdio_irq() ops\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (caps2 & (MMC_CAP2_HS400_ES | MMC_CAP2_HS400) &&
|
||||
!(caps & MMC_CAP_8_BIT_DATA)) {
|
||||
dev_warn(dev, "drop HS400 support since no 8-bit bus\n");
|
||||
host->caps2 = caps2 & ~MMC_CAP2_HS400_ES & ~MMC_CAP2_HS400;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* mmc_add_host - initialise host hardware
|
||||
* @host: mmc host
|
||||
@@ -600,8 +619,9 @@ int mmc_add_host(struct mmc_host *host)
|
||||
{
|
||||
int err;
|
||||
|
||||
WARN_ON((host->caps & MMC_CAP_SDIO_IRQ) &&
|
||||
!host->ops->enable_sdio_irq);
|
||||
err = mmc_validate_host_caps(host);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = device_add(&host->class_dev);
|
||||
if (err)
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/stat.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/sysfs.h>
|
||||
|
||||
#include <linux/mmc/host.h>
|
||||
#include <linux/mmc/card.h>
|
||||
@@ -812,12 +813,11 @@ static ssize_t mmc_fwrev_show(struct device *dev,
|
||||
{
|
||||
struct mmc_card *card = mmc_dev_to_card(dev);
|
||||
|
||||
if (card->ext_csd.rev < 7) {
|
||||
return sprintf(buf, "0x%x\n", card->cid.fwrev);
|
||||
} else {
|
||||
return sprintf(buf, "0x%*phN\n", MMC_FIRMWARE_LEN,
|
||||
card->ext_csd.fwrev);
|
||||
}
|
||||
if (card->ext_csd.rev < 7)
|
||||
return sysfs_emit(buf, "0x%x\n", card->cid.fwrev);
|
||||
else
|
||||
return sysfs_emit(buf, "0x%*phN\n", MMC_FIRMWARE_LEN,
|
||||
card->ext_csd.fwrev);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(fwrev, S_IRUGO, mmc_fwrev_show, NULL);
|
||||
@@ -830,10 +830,10 @@ static ssize_t mmc_dsr_show(struct device *dev,
|
||||
struct mmc_host *host = card->host;
|
||||
|
||||
if (card->csd.dsr_imp && host->dsr_req)
|
||||
return sprintf(buf, "0x%x\n", host->dsr);
|
||||
return sysfs_emit(buf, "0x%x\n", host->dsr);
|
||||
else
|
||||
/* return default DSR value */
|
||||
return sprintf(buf, "0x%x\n", 0x404);
|
||||
return sysfs_emit(buf, "0x%x\n", 0x404);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(dsr, S_IRUGO, mmc_dsr_show, NULL);
|
||||
@@ -1355,11 +1355,6 @@ static int mmc_select_hs400es(struct mmc_card *card)
|
||||
int err = -EINVAL;
|
||||
u8 val;
|
||||
|
||||
if (!(host->caps & MMC_CAP_8_BIT_DATA)) {
|
||||
err = -ENOTSUPP;
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400_1_2V)
|
||||
err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120);
|
||||
|
||||
@@ -1523,13 +1518,23 @@ static int mmc_select_timing(struct mmc_card *card)
|
||||
if (!mmc_can_ext_csd(card))
|
||||
goto bus_speed;
|
||||
|
||||
if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400ES)
|
||||
if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400ES) {
|
||||
err = mmc_select_hs400es(card);
|
||||
else if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200) {
|
||||
err = mmc_select_hs200(card);
|
||||
else if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS)
|
||||
if (err == -EBADMSG)
|
||||
card->mmc_avail_type &= ~EXT_CSD_CARD_TYPE_HS200;
|
||||
else
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS)
|
||||
err = mmc_select_hs(card);
|
||||
|
||||
out:
|
||||
if (err && err != -EBADMSG)
|
||||
return err;
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <linux/stat.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/scatterlist.h>
|
||||
#include <linux/sysfs.h>
|
||||
|
||||
#include <linux/mmc/host.h>
|
||||
#include <linux/mmc/card.h>
|
||||
@@ -708,18 +709,16 @@ MMC_DEV_ATTR(ocr, "0x%08x\n", card->ocr);
|
||||
MMC_DEV_ATTR(rca, "0x%04x\n", card->rca);
|
||||
|
||||
|
||||
static ssize_t mmc_dsr_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
static ssize_t mmc_dsr_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct mmc_card *card = mmc_dev_to_card(dev);
|
||||
struct mmc_host *host = card->host;
|
||||
struct mmc_card *card = mmc_dev_to_card(dev);
|
||||
struct mmc_host *host = card->host;
|
||||
|
||||
if (card->csd.dsr_imp && host->dsr_req)
|
||||
return sprintf(buf, "0x%x\n", host->dsr);
|
||||
else
|
||||
/* return default DSR value */
|
||||
return sprintf(buf, "0x%x\n", 0x404);
|
||||
if (card->csd.dsr_imp && host->dsr_req)
|
||||
return sysfs_emit(buf, "0x%x\n", host->dsr);
|
||||
/* return default DSR value */
|
||||
return sysfs_emit(buf, "0x%x\n", 0x404);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(dsr, S_IRUGO, mmc_dsr_show, NULL);
|
||||
@@ -735,9 +734,9 @@ static ssize_t info##num##_show(struct device *dev, struct device_attribute *att
|
||||
\
|
||||
if (num > card->num_info) \
|
||||
return -ENODATA; \
|
||||
if (!card->info[num-1][0]) \
|
||||
if (!card->info[num - 1][0]) \
|
||||
return 0; \
|
||||
return sprintf(buf, "%s\n", card->info[num-1]); \
|
||||
return sysfs_emit(buf, "%s\n", card->info[num - 1]); \
|
||||
} \
|
||||
static DEVICE_ATTR_RO(info##num)
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include <linux/err.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/sysfs.h>
|
||||
|
||||
#include <linux/mmc/host.h>
|
||||
#include <linux/mmc/card.h>
|
||||
@@ -40,9 +41,9 @@ static ssize_t info##num##_show(struct device *dev, struct device_attribute *att
|
||||
\
|
||||
if (num > card->num_info) \
|
||||
return -ENODATA; \
|
||||
if (!card->info[num-1][0]) \
|
||||
if (!card->info[num - 1][0]) \
|
||||
return 0; \
|
||||
return sprintf(buf, "%s\n", card->info[num-1]); \
|
||||
return sysfs_emit(buf, "%s\n", card->info[num - 1]); \
|
||||
} \
|
||||
static DEVICE_ATTR_RO(info##num)
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/pm_domain.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/sysfs.h>
|
||||
|
||||
#include <linux/mmc/card.h>
|
||||
#include <linux/mmc/host.h>
|
||||
@@ -35,7 +36,7 @@ field##_show(struct device *dev, struct device_attribute *attr, char *buf) \
|
||||
struct sdio_func *func; \
|
||||
\
|
||||
func = dev_to_sdio_func (dev); \
|
||||
return sprintf(buf, format_string, args); \
|
||||
return sysfs_emit(buf, format_string, args); \
|
||||
} \
|
||||
static DEVICE_ATTR_RO(field)
|
||||
|
||||
@@ -52,9 +53,9 @@ static ssize_t info##num##_show(struct device *dev, struct device_attribute *att
|
||||
\
|
||||
if (num > func->num_info) \
|
||||
return -ENODATA; \
|
||||
if (!func->info[num-1][0]) \
|
||||
if (!func->info[num - 1][0]) \
|
||||
return 0; \
|
||||
return sprintf(buf, "%s\n", func->info[num-1]); \
|
||||
return sysfs_emit(buf, "%s\n", func->info[num - 1]); \
|
||||
} \
|
||||
static DEVICE_ATTR_RO(info##num)
|
||||
|
||||
|
||||
@@ -1094,3 +1094,16 @@ config MMC_OWL
|
||||
|
||||
config MMC_SDHCI_EXTERNAL_DMA
|
||||
bool
|
||||
|
||||
config MMC_LITEX
|
||||
tristate "LiteX MMC Host Controller support"
|
||||
depends on ((PPC_MICROWATT || LITEX) && OF && HAVE_CLK) || COMPILE_TEST
|
||||
select REGULATOR
|
||||
select REGULATOR_FIXED_VOLTAGE
|
||||
help
|
||||
This selects support for the MMC Host Controller found in LiteX SoCs.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called litex_mmc.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
@@ -101,6 +101,7 @@ obj-$(CONFIG_MMC_CQHCI) += cqhci.o
|
||||
cqhci-y += cqhci-core.o
|
||||
cqhci-$(CONFIG_MMC_CRYPTO) += cqhci-crypto.o
|
||||
obj-$(CONFIG_MMC_HSQ) += mmc_hsq.o
|
||||
obj-$(CONFIG_MMC_LITEX) += litex_mmc.o
|
||||
|
||||
ifeq ($(CONFIG_CB710_DEBUG),y)
|
||||
CFLAGS-cb710-mmc += -DDEBUG
|
||||
|
||||
@@ -1189,7 +1189,6 @@ static int mmc_davinci_parse_pdata(struct mmc_host *mmc)
|
||||
|
||||
static int davinci_mmcsd_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct of_device_id *match;
|
||||
struct mmc_davinci_host *host = NULL;
|
||||
struct mmc_host *mmc = NULL;
|
||||
struct resource *r, *mem = NULL;
|
||||
@@ -1235,9 +1234,8 @@ static int davinci_mmcsd_probe(struct platform_device *pdev)
|
||||
|
||||
host->mmc_input_clk = clk_get_rate(host->clk);
|
||||
|
||||
match = of_match_device(davinci_mmc_dt_ids, &pdev->dev);
|
||||
if (match) {
|
||||
pdev->id_entry = match->data;
|
||||
pdev->id_entry = of_device_get_match_data(&pdev->dev);
|
||||
if (pdev->id_entry) {
|
||||
ret = mmc_of_parse(mmc);
|
||||
if (ret) {
|
||||
dev_err_probe(&pdev->dev, ret,
|
||||
@@ -1375,8 +1373,12 @@ static int davinci_mmcsd_suspend(struct device *dev)
|
||||
static int davinci_mmcsd_resume(struct device *dev)
|
||||
{
|
||||
struct mmc_davinci_host *host = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
|
||||
ret = clk_enable(host->clk);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
clk_enable(host->clk);
|
||||
mmc_davinci_reset_ctrl(host, 0);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -15,7 +15,9 @@
|
||||
#include "dw_mmc.h"
|
||||
#include "dw_mmc-pltfm.h"
|
||||
|
||||
#define RK3288_CLKGEN_DIV 2
|
||||
#define RK3288_CLKGEN_DIV 2
|
||||
|
||||
static const unsigned int freqs[] = { 100000, 200000, 300000, 400000 };
|
||||
|
||||
struct dw_mci_rockchip_priv_data {
|
||||
struct clk *drv_clk;
|
||||
@@ -51,7 +53,7 @@ static void dw_mci_rk3288_set_ios(struct dw_mci *host, struct mmc_ios *ios)
|
||||
|
||||
ret = clk_set_rate(host->ciu_clk, cclkin);
|
||||
if (ret)
|
||||
dev_warn(host->dev, "failed to set rate %uHz\n", ios->clock);
|
||||
dev_warn(host->dev, "failed to set rate %uHz err: %d\n", cclkin, ret);
|
||||
|
||||
bus_hz = clk_get_rate(host->ciu_clk) / RK3288_CLKGEN_DIV;
|
||||
if (bus_hz != host->bus_hz) {
|
||||
@@ -290,13 +292,30 @@ static int dw_mci_rk3288_parse_dt(struct dw_mci *host)
|
||||
|
||||
static int dw_mci_rockchip_init(struct dw_mci *host)
|
||||
{
|
||||
int ret, i;
|
||||
|
||||
/* It is slot 8 on Rockchip SoCs */
|
||||
host->sdio_id0 = 8;
|
||||
|
||||
if (of_device_is_compatible(host->dev->of_node,
|
||||
"rockchip,rk3288-dw-mshc"))
|
||||
if (of_device_is_compatible(host->dev->of_node, "rockchip,rk3288-dw-mshc")) {
|
||||
host->bus_hz /= RK3288_CLKGEN_DIV;
|
||||
|
||||
/* clock driver will fail if the clock is less than the lowest source clock
|
||||
* divided by the internal clock divider. Test for the lowest available
|
||||
* clock and set the minimum freq to clock / clock divider.
|
||||
*/
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(freqs); i++) {
|
||||
ret = clk_round_rate(host->ciu_clk, freqs[i] * RK3288_CLKGEN_DIV);
|
||||
if (ret > 0) {
|
||||
host->minimum_speed = ret / RK3288_CLKGEN_DIV;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ret < 0)
|
||||
dev_warn(host->dev, "no valid minimum freq: %d\n", ret);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -2898,7 +2898,12 @@ static int dw_mci_init_slot_caps(struct dw_mci_slot *slot)
|
||||
if (host->pdata->caps2)
|
||||
mmc->caps2 = host->pdata->caps2;
|
||||
|
||||
mmc->f_min = DW_MCI_FREQ_MIN;
|
||||
/* if host has set a minimum_freq, we should respect it */
|
||||
if (host->minimum_speed)
|
||||
mmc->f_min = host->minimum_speed;
|
||||
else
|
||||
mmc->f_min = DW_MCI_FREQ_MIN;
|
||||
|
||||
if (!mmc->f_max)
|
||||
mmc->f_max = DW_MCI_FREQ_MAX;
|
||||
|
||||
@@ -3057,8 +3062,7 @@ static void dw_mci_init_dma(struct dw_mci *host)
|
||||
dev_info(host->dev, "Using internal DMA controller.\n");
|
||||
} else {
|
||||
/* TRANS_MODE_EDMAC: check dma bindings again */
|
||||
if ((device_property_read_string_array(dev, "dma-names",
|
||||
NULL, 0) < 0) ||
|
||||
if ((device_property_string_array_count(dev, "dma-names") < 0) ||
|
||||
!device_property_present(dev, "dmas")) {
|
||||
goto no_dma;
|
||||
}
|
||||
@@ -3568,7 +3572,7 @@ int dw_mci_runtime_resume(struct device *dev)
|
||||
mci_writel(host, CTRL, SDMMC_CTRL_INT_ENABLE);
|
||||
|
||||
|
||||
if (host->slot->mmc->pm_flags & MMC_PM_KEEP_POWER)
|
||||
if (host->slot && host->slot->mmc->pm_flags & MMC_PM_KEEP_POWER)
|
||||
dw_mci_set_ios(host->slot->mmc, &host->slot->mmc->ios);
|
||||
|
||||
/* Force setup bus to guarantee available clock output */
|
||||
|
||||
@@ -99,6 +99,7 @@ struct dw_mci_dma_slave {
|
||||
* @bus_hz: The rate of @mck in Hz. This forms the basis for MMC bus
|
||||
* rate and timeout calculations.
|
||||
* @current_speed: Configured rate of the controller.
|
||||
* @minimum_speed: Stored minimum rate of the controller.
|
||||
* @fifoth_val: The value of FIFOTH register.
|
||||
* @verid: Denote Version ID.
|
||||
* @dev: Device associated with the MMC controller.
|
||||
@@ -201,6 +202,7 @@ struct dw_mci {
|
||||
|
||||
u32 bus_hz;
|
||||
u32 current_speed;
|
||||
u32 minimum_speed;
|
||||
u32 fifoth_val;
|
||||
u16 verid;
|
||||
struct device *dev;
|
||||
|
||||
661
drivers/mmc/host/litex_mmc.c
Normal file
661
drivers/mmc/host/litex_mmc.c
Normal file
@@ -0,0 +1,661 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* LiteX LiteSDCard driver
|
||||
*
|
||||
* Copyright (C) 2019-2020 Antmicro <contact@antmicro.com>
|
||||
* Copyright (C) 2019-2020 Kamil Rakoczy <krakoczy@antmicro.com>
|
||||
* Copyright (C) 2019-2020 Maciej Dudek <mdudek@internships.antmicro.com>
|
||||
* Copyright (C) 2020 Paul Mackerras <paulus@ozlabs.org>
|
||||
* Copyright (C) 2020-2022 Gabriel Somlo <gsomlo@gmail.com>
|
||||
*/
|
||||
|
||||
#include <linux/bits.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/litex.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include <linux/mmc/host.h>
|
||||
#include <linux/mmc/mmc.h>
|
||||
#include <linux/mmc/sd.h>
|
||||
|
||||
#define LITEX_PHY_CARDDETECT 0x00
|
||||
#define LITEX_PHY_CLOCKERDIV 0x04
|
||||
#define LITEX_PHY_INITIALIZE 0x08
|
||||
#define LITEX_PHY_WRITESTATUS 0x0C
|
||||
#define LITEX_CORE_CMDARG 0x00
|
||||
#define LITEX_CORE_CMDCMD 0x04
|
||||
#define LITEX_CORE_CMDSND 0x08
|
||||
#define LITEX_CORE_CMDRSP 0x0C
|
||||
#define LITEX_CORE_CMDEVT 0x1C
|
||||
#define LITEX_CORE_DATEVT 0x20
|
||||
#define LITEX_CORE_BLKLEN 0x24
|
||||
#define LITEX_CORE_BLKCNT 0x28
|
||||
#define LITEX_BLK2MEM_BASE 0x00
|
||||
#define LITEX_BLK2MEM_LEN 0x08
|
||||
#define LITEX_BLK2MEM_ENA 0x0C
|
||||
#define LITEX_BLK2MEM_DONE 0x10
|
||||
#define LITEX_BLK2MEM_LOOP 0x14
|
||||
#define LITEX_MEM2BLK_BASE 0x00
|
||||
#define LITEX_MEM2BLK_LEN 0x08
|
||||
#define LITEX_MEM2BLK_ENA 0x0C
|
||||
#define LITEX_MEM2BLK_DONE 0x10
|
||||
#define LITEX_MEM2BLK_LOOP 0x14
|
||||
#define LITEX_MEM2BLK 0x18
|
||||
#define LITEX_IRQ_STATUS 0x00
|
||||
#define LITEX_IRQ_PENDING 0x04
|
||||
#define LITEX_IRQ_ENABLE 0x08
|
||||
|
||||
#define SD_CTL_DATA_XFER_NONE 0
|
||||
#define SD_CTL_DATA_XFER_READ 1
|
||||
#define SD_CTL_DATA_XFER_WRITE 2
|
||||
|
||||
#define SD_CTL_RESP_NONE 0
|
||||
#define SD_CTL_RESP_SHORT 1
|
||||
#define SD_CTL_RESP_LONG 2
|
||||
#define SD_CTL_RESP_SHORT_BUSY 3
|
||||
|
||||
#define SD_BIT_DONE BIT(0)
|
||||
#define SD_BIT_WR_ERR BIT(1)
|
||||
#define SD_BIT_TIMEOUT BIT(2)
|
||||
#define SD_BIT_CRC_ERR BIT(3)
|
||||
|
||||
#define SD_SLEEP_US 5
|
||||
#define SD_TIMEOUT_US 20000
|
||||
|
||||
#define SDIRQ_CARD_DETECT 1
|
||||
#define SDIRQ_SD_TO_MEM_DONE 2
|
||||
#define SDIRQ_MEM_TO_SD_DONE 4
|
||||
#define SDIRQ_CMD_DONE 8
|
||||
|
||||
struct litex_mmc_host {
|
||||
struct mmc_host *mmc;
|
||||
|
||||
void __iomem *sdphy;
|
||||
void __iomem *sdcore;
|
||||
void __iomem *sdreader;
|
||||
void __iomem *sdwriter;
|
||||
void __iomem *sdirq;
|
||||
|
||||
void *buffer;
|
||||
size_t buf_size;
|
||||
dma_addr_t dma;
|
||||
|
||||
struct completion cmd_done;
|
||||
int irq;
|
||||
|
||||
unsigned int ref_clk;
|
||||
unsigned int sd_clk;
|
||||
|
||||
u32 resp[4];
|
||||
u16 rca;
|
||||
|
||||
bool is_bus_width_set;
|
||||
bool app_cmd;
|
||||
};
|
||||
|
||||
static int litex_mmc_sdcard_wait_done(void __iomem *reg, struct device *dev)
|
||||
{
|
||||
u8 evt;
|
||||
int ret;
|
||||
|
||||
ret = readx_poll_timeout(litex_read8, reg, evt, evt & SD_BIT_DONE,
|
||||
SD_SLEEP_US, SD_TIMEOUT_US);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (evt == SD_BIT_DONE)
|
||||
return 0;
|
||||
if (evt & SD_BIT_WR_ERR)
|
||||
return -EIO;
|
||||
if (evt & SD_BIT_TIMEOUT)
|
||||
return -ETIMEDOUT;
|
||||
if (evt & SD_BIT_CRC_ERR)
|
||||
return -EILSEQ;
|
||||
dev_err(dev, "%s: unknown error (evt=%x)\n", __func__, evt);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int litex_mmc_send_cmd(struct litex_mmc_host *host,
|
||||
u8 cmd, u32 arg, u8 response_len, u8 transfer)
|
||||
{
|
||||
struct device *dev = mmc_dev(host->mmc);
|
||||
void __iomem *reg;
|
||||
int ret;
|
||||
u8 evt;
|
||||
|
||||
litex_write32(host->sdcore + LITEX_CORE_CMDARG, arg);
|
||||
litex_write32(host->sdcore + LITEX_CORE_CMDCMD,
|
||||
cmd << 8 | transfer << 5 | response_len);
|
||||
litex_write8(host->sdcore + LITEX_CORE_CMDSND, 1);
|
||||
|
||||
/*
|
||||
* Wait for an interrupt if we have an interrupt and either there is
|
||||
* data to be transferred, or if the card can report busy via DAT0.
|
||||
*/
|
||||
if (host->irq > 0 &&
|
||||
(transfer != SD_CTL_DATA_XFER_NONE ||
|
||||
response_len == SD_CTL_RESP_SHORT_BUSY)) {
|
||||
reinit_completion(&host->cmd_done);
|
||||
litex_write32(host->sdirq + LITEX_IRQ_ENABLE,
|
||||
SDIRQ_CMD_DONE | SDIRQ_CARD_DETECT);
|
||||
wait_for_completion(&host->cmd_done);
|
||||
}
|
||||
|
||||
ret = litex_mmc_sdcard_wait_done(host->sdcore + LITEX_CORE_CMDEVT, dev);
|
||||
if (ret) {
|
||||
dev_err(dev, "Command (cmd %d) error, status %d\n", cmd, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (response_len != SD_CTL_RESP_NONE) {
|
||||
/*
|
||||
* NOTE: this matches the semantics of litex_read32()
|
||||
* regardless of underlying arch endianness!
|
||||
*/
|
||||
memcpy_fromio(host->resp,
|
||||
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() */
|
||||
|
||||
ret = litex_mmc_sdcard_wait_done(host->sdcore + LITEX_CORE_DATEVT, dev);
|
||||
if (ret) {
|
||||
dev_err(dev, "Data xfer (cmd %d) error, status %d\n", cmd, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Wait for completion of (read or write) DMA transfer */
|
||||
reg = (transfer == SD_CTL_DATA_XFER_READ) ?
|
||||
host->sdreader + LITEX_BLK2MEM_DONE :
|
||||
host->sdwriter + LITEX_MEM2BLK_DONE;
|
||||
ret = readx_poll_timeout(litex_read8, reg, evt, evt & SD_BIT_DONE,
|
||||
SD_SLEEP_US, SD_TIMEOUT_US);
|
||||
if (ret)
|
||||
dev_err(dev, "DMA timeout (cmd %d)\n", cmd);
|
||||
|
||||
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);
|
||||
int ret;
|
||||
|
||||
if (!mmc_card_is_removable(mmc))
|
||||
return 1;
|
||||
|
||||
ret = !litex_read8(host->sdphy + LITEX_PHY_CARDDETECT);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Ensure bus width will be set (again) upon card (re)insertion */
|
||||
host->is_bus_width_set = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static irqreturn_t litex_mmc_interrupt(int irq, void *arg)
|
||||
{
|
||||
struct mmc_host *mmc = arg;
|
||||
struct litex_mmc_host *host = mmc_priv(mmc);
|
||||
u32 pending = litex_read32(host->sdirq + LITEX_IRQ_PENDING);
|
||||
irqreturn_t ret = IRQ_NONE;
|
||||
|
||||
/* Check for card change interrupt */
|
||||
if (pending & SDIRQ_CARD_DETECT) {
|
||||
litex_write32(host->sdirq + LITEX_IRQ_PENDING,
|
||||
SDIRQ_CARD_DETECT);
|
||||
mmc_detect_change(mmc, msecs_to_jiffies(10));
|
||||
ret = IRQ_HANDLED;
|
||||
}
|
||||
|
||||
/* Check for command completed */
|
||||
if (pending & SDIRQ_CMD_DONE) {
|
||||
/* Disable it so it doesn't keep interrupting */
|
||||
litex_write32(host->sdirq + LITEX_IRQ_ENABLE,
|
||||
SDIRQ_CARD_DETECT);
|
||||
complete(&host->cmd_done);
|
||||
ret = IRQ_HANDLED;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static u32 litex_mmc_response_len(struct mmc_command *cmd)
|
||||
{
|
||||
if (cmd->flags & MMC_RSP_136)
|
||||
return SD_CTL_RESP_LONG;
|
||||
if (!(cmd->flags & MMC_RSP_PRESENT))
|
||||
return SD_CTL_RESP_NONE;
|
||||
if (cmd->flags & MMC_RSP_BUSY)
|
||||
return SD_CTL_RESP_SHORT_BUSY;
|
||||
return SD_CTL_RESP_SHORT;
|
||||
}
|
||||
|
||||
static void litex_mmc_do_dma(struct litex_mmc_host *host, struct mmc_data *data,
|
||||
unsigned int *len, bool *direct, u8 *transfer)
|
||||
{
|
||||
struct device *dev = mmc_dev(host->mmc);
|
||||
dma_addr_t dma;
|
||||
int sg_count;
|
||||
|
||||
/*
|
||||
* Try to DMA directly to/from the data buffer.
|
||||
* We can do that if the buffer can be mapped for DMA
|
||||
* in one contiguous chunk.
|
||||
*/
|
||||
dma = host->dma;
|
||||
*len = data->blksz * data->blocks;
|
||||
sg_count = dma_map_sg(dev, data->sg, data->sg_len,
|
||||
mmc_get_dma_dir(data));
|
||||
if (sg_count == 1) {
|
||||
dma = sg_dma_address(data->sg);
|
||||
*len = sg_dma_len(data->sg);
|
||||
*direct = true;
|
||||
} else if (*len > host->buf_size)
|
||||
*len = host->buf_size;
|
||||
|
||||
if (data->flags & MMC_DATA_READ) {
|
||||
litex_write8(host->sdreader + LITEX_BLK2MEM_ENA, 0);
|
||||
litex_write64(host->sdreader + LITEX_BLK2MEM_BASE, dma);
|
||||
litex_write32(host->sdreader + LITEX_BLK2MEM_LEN, *len);
|
||||
litex_write8(host->sdreader + LITEX_BLK2MEM_ENA, 1);
|
||||
*transfer = SD_CTL_DATA_XFER_READ;
|
||||
} else if (data->flags & MMC_DATA_WRITE) {
|
||||
if (!*direct)
|
||||
sg_copy_to_buffer(data->sg, data->sg_len,
|
||||
host->buffer, *len);
|
||||
litex_write8(host->sdwriter + LITEX_MEM2BLK_ENA, 0);
|
||||
litex_write64(host->sdwriter + LITEX_MEM2BLK_BASE, dma);
|
||||
litex_write32(host->sdwriter + LITEX_MEM2BLK_LEN, *len);
|
||||
litex_write8(host->sdwriter + LITEX_MEM2BLK_ENA, 1);
|
||||
*transfer = SD_CTL_DATA_XFER_WRITE;
|
||||
} else {
|
||||
dev_warn(dev, "Data present w/o read or write flag.\n");
|
||||
/* Continue: set cmd status, mark req done */
|
||||
}
|
||||
|
||||
litex_write16(host->sdcore + LITEX_CORE_BLKLEN, data->blksz);
|
||||
litex_write32(host->sdcore + LITEX_CORE_BLKCNT, data->blocks);
|
||||
}
|
||||
|
||||
static void litex_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
|
||||
{
|
||||
struct litex_mmc_host *host = mmc_priv(mmc);
|
||||
struct device *dev = mmc_dev(mmc);
|
||||
struct mmc_command *cmd = mrq->cmd;
|
||||
struct mmc_command *sbc = mrq->sbc;
|
||||
struct mmc_data *data = mrq->data;
|
||||
struct mmc_command *stop = mrq->stop;
|
||||
unsigned int retries = cmd->retries;
|
||||
unsigned int len = 0;
|
||||
bool direct = false;
|
||||
u32 response_len = litex_mmc_response_len(cmd);
|
||||
u8 transfer = SD_CTL_DATA_XFER_NONE;
|
||||
|
||||
/* First check that the card is still there */
|
||||
if (!litex_mmc_get_cd(mmc)) {
|
||||
cmd->error = -ENOMEDIUM;
|
||||
mmc_request_done(mmc, mrq);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Send set-block-count command if needed */
|
||||
if (sbc) {
|
||||
sbc->error = litex_mmc_send_cmd(host, sbc->opcode, sbc->arg,
|
||||
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;
|
||||
}
|
||||
|
||||
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];
|
||||
cmd->resp[1] = host->resp[2] & 0xFF;
|
||||
} else if (response_len == SD_CTL_RESP_LONG) {
|
||||
cmd->resp[0] = host->resp[0];
|
||||
cmd->resp[1] = host->resp[1];
|
||||
cmd->resp[2] = host->resp[2];
|
||||
cmd->resp[3] = host->resp[3];
|
||||
}
|
||||
|
||||
/* Send stop-transmission command if required */
|
||||
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,
|
||||
mmc_get_dma_dir(data));
|
||||
}
|
||||
|
||||
if (!cmd->error && transfer != SD_CTL_DATA_XFER_NONE) {
|
||||
data->bytes_xfered = min(len, mmc->max_req_size);
|
||||
if (transfer == SD_CTL_DATA_XFER_READ && !direct) {
|
||||
sg_copy_from_buffer(data->sg, sg_nents(data->sg),
|
||||
host->buffer, data->bytes_xfered);
|
||||
}
|
||||
}
|
||||
|
||||
mmc_request_done(mmc, mrq);
|
||||
}
|
||||
|
||||
static void litex_mmc_setclk(struct litex_mmc_host *host, unsigned int freq)
|
||||
{
|
||||
struct device *dev = mmc_dev(host->mmc);
|
||||
u32 div;
|
||||
|
||||
div = freq ? host->ref_clk / freq : 256U;
|
||||
div = roundup_pow_of_two(div);
|
||||
div = clamp(div, 2U, 256U);
|
||||
dev_dbg(dev, "sd_clk_freq=%d: set to %d via div=%d\n",
|
||||
freq, host->ref_clk / div, div);
|
||||
litex_write16(host->sdphy + LITEX_PHY_CLOCKERDIV, div);
|
||||
host->sd_clk = freq;
|
||||
}
|
||||
|
||||
static void litex_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
|
||||
{
|
||||
struct litex_mmc_host *host = mmc_priv(mmc);
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
static const struct mmc_host_ops litex_mmc_ops = {
|
||||
.get_cd = litex_mmc_get_cd,
|
||||
.request = litex_mmc_request,
|
||||
.set_ios = litex_mmc_set_ios,
|
||||
};
|
||||
|
||||
static int litex_mmc_irq_init(struct platform_device *pdev,
|
||||
struct litex_mmc_host *host)
|
||||
{
|
||||
struct device *dev = mmc_dev(host->mmc);
|
||||
int ret;
|
||||
|
||||
ret = platform_get_irq_optional(pdev, 0);
|
||||
if (ret < 0 && ret != -ENXIO)
|
||||
return ret;
|
||||
if (ret > 0)
|
||||
host->irq = ret;
|
||||
else {
|
||||
dev_warn(dev, "Failed to get IRQ, using polling\n");
|
||||
goto use_polling;
|
||||
}
|
||||
|
||||
host->sdirq = devm_platform_ioremap_resource_byname(pdev, "irq");
|
||||
if (IS_ERR(host->sdirq))
|
||||
return PTR_ERR(host->sdirq);
|
||||
|
||||
ret = devm_request_irq(dev, host->irq, litex_mmc_interrupt, 0,
|
||||
"litex-mmc", host->mmc);
|
||||
if (ret < 0) {
|
||||
dev_warn(dev, "IRQ request error %d, using polling\n", ret);
|
||||
goto use_polling;
|
||||
}
|
||||
|
||||
/* Clear & enable card-change interrupts */
|
||||
litex_write32(host->sdirq + LITEX_IRQ_PENDING, SDIRQ_CARD_DETECT);
|
||||
litex_write32(host->sdirq + LITEX_IRQ_ENABLE, SDIRQ_CARD_DETECT);
|
||||
|
||||
return 0;
|
||||
|
||||
use_polling:
|
||||
host->mmc->caps |= MMC_CAP_NEEDS_POLL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void litex_mmc_free_host_wrapper(void *mmc)
|
||||
{
|
||||
mmc_free_host(mmc);
|
||||
}
|
||||
|
||||
static int litex_mmc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct litex_mmc_host *host;
|
||||
struct mmc_host *mmc;
|
||||
struct clk *clk;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* NOTE: defaults to max_[req,seg]_size=PAGE_SIZE, max_blk_size=512,
|
||||
* and max_blk_count accordingly set to 8;
|
||||
* If for some reason we need to modify max_blk_count, we must also
|
||||
* re-calculate `max_[req,seg]_size = max_blk_size * max_blk_count;`
|
||||
*/
|
||||
mmc = mmc_alloc_host(sizeof(struct litex_mmc_host), dev);
|
||||
if (!mmc)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = devm_add_action_or_reset(dev, litex_mmc_free_host_wrapper, mmc);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret,
|
||||
"Can't register mmc_free_host action\n");
|
||||
|
||||
host = mmc_priv(mmc);
|
||||
host->mmc = mmc;
|
||||
|
||||
/* Initialize clock source */
|
||||
clk = devm_clk_get(dev, NULL);
|
||||
if (IS_ERR(clk))
|
||||
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;
|
||||
|
||||
/* LiteSDCard can support 64-bit DMA addressing */
|
||||
ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
host->buf_size = mmc->max_req_size * 2;
|
||||
host->buffer = dmam_alloc_coherent(dev, host->buf_size,
|
||||
&host->dma, GFP_KERNEL);
|
||||
if (host->buffer == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
host->sdphy = devm_platform_ioremap_resource_byname(pdev, "phy");
|
||||
if (IS_ERR(host->sdphy))
|
||||
return PTR_ERR(host->sdphy);
|
||||
|
||||
host->sdcore = devm_platform_ioremap_resource_byname(pdev, "core");
|
||||
if (IS_ERR(host->sdcore))
|
||||
return PTR_ERR(host->sdcore);
|
||||
|
||||
host->sdreader = devm_platform_ioremap_resource_byname(pdev, "reader");
|
||||
if (IS_ERR(host->sdreader))
|
||||
return PTR_ERR(host->sdreader);
|
||||
|
||||
host->sdwriter = devm_platform_ioremap_resource_byname(pdev, "writer");
|
||||
if (IS_ERR(host->sdwriter))
|
||||
return PTR_ERR(host->sdwriter);
|
||||
|
||||
/* Ensure DMA bus masters are disabled */
|
||||
litex_write8(host->sdreader + LITEX_BLK2MEM_ENA, 0);
|
||||
litex_write8(host->sdwriter + LITEX_MEM2BLK_ENA, 0);
|
||||
|
||||
init_completion(&host->cmd_done);
|
||||
ret = litex_mmc_irq_init(pdev, host);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
mmc->ops = &litex_mmc_ops;
|
||||
|
||||
ret = mmc_regulator_get_supply(mmc);
|
||||
if (ret || mmc->ocr_avail == 0) {
|
||||
dev_warn(dev, "can't get voltage, defaulting to 3.3V\n");
|
||||
mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set default sd_clk frequency range based on empirical observations
|
||||
* of LiteSDCard gateware behavior on typical SDCard media
|
||||
*/
|
||||
mmc->f_min = 12.5e6;
|
||||
mmc->f_max = 50e6;
|
||||
|
||||
ret = mmc_of_parse(mmc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Force 4-bit bus_width (only width supported by hardware) */
|
||||
mmc->caps &= ~MMC_CAP_8_BIT_DATA;
|
||||
mmc->caps |= MMC_CAP_4_BIT_DATA;
|
||||
|
||||
/* Set default capabilities */
|
||||
mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY |
|
||||
MMC_CAP_DRIVER_TYPE_D |
|
||||
MMC_CAP_CMD23;
|
||||
mmc->caps2 |= MMC_CAP2_NO_WRITE_PROTECT |
|
||||
MMC_CAP2_NO_SDIO |
|
||||
MMC_CAP2_NO_MMC;
|
||||
|
||||
platform_set_drvdata(pdev, host);
|
||||
|
||||
ret = mmc_add_host(mmc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
dev_info(dev, "LiteX MMC controller initialized.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int litex_mmc_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct litex_mmc_host *host = platform_get_drvdata(pdev);
|
||||
|
||||
mmc_remove_host(host->mmc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id litex_match[] = {
|
||||
{ .compatible = "litex,mmc" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, litex_match);
|
||||
|
||||
static struct platform_driver litex_mmc_driver = {
|
||||
.probe = litex_mmc_probe,
|
||||
.remove = litex_mmc_remove,
|
||||
.driver = {
|
||||
.name = "litex-mmc",
|
||||
.of_match_table = litex_match,
|
||||
},
|
||||
};
|
||||
module_platform_driver(litex_mmc_driver);
|
||||
|
||||
MODULE_DESCRIPTION("LiteX SDCard driver");
|
||||
MODULE_AUTHOR("Antmicro <contact@antmicro.com>");
|
||||
MODULE_AUTHOR("Kamil Rakoczy <krakoczy@antmicro.com>");
|
||||
MODULE_AUTHOR("Maciej Dudek <mdudek@internships.antmicro.com>");
|
||||
MODULE_AUTHOR("Paul Mackerras <paulus@ozlabs.org>");
|
||||
MODULE_AUTHOR("Gabriel Somlo <gsomlo@gmail.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
@@ -1911,8 +1911,8 @@ static struct msdc_delay_phase get_best_delay(struct msdc_host *host, u32 delay)
|
||||
final_phase = (start_final + len_final / 3) % PAD_DELAY_MAX;
|
||||
else
|
||||
final_phase = (start_final + len_final / 2) % PAD_DELAY_MAX;
|
||||
dev_info(host->dev, "phase: [map:%x] [maxlen:%d] [final:%d]\n",
|
||||
delay, len_final, final_phase);
|
||||
dev_dbg(host->dev, "phase: [map:%x] [maxlen:%d] [final:%d]\n",
|
||||
delay, len_final, final_phase);
|
||||
|
||||
delay_phase.maxlen = len_final;
|
||||
delay_phase.start = start_final;
|
||||
|
||||
@@ -212,7 +212,7 @@ static const struct soc_device_attribute sdhi_quirks_match[] = {
|
||||
{ .soc_id = "r8a7795", .revision = "ES2.0", .data = &sdhi_quirks_4tap },
|
||||
{ .soc_id = "r8a7796", .revision = "ES1.[012]", .data = &sdhi_quirks_4tap_nohs400 },
|
||||
{ .soc_id = "r8a7796", .revision = "ES1.*", .data = &sdhi_quirks_r8a7796_es13 },
|
||||
{ /* Sentinel. */ },
|
||||
{ /* Sentinel. */ }
|
||||
};
|
||||
|
||||
static const struct renesas_sdhi_of_data_with_quirks of_r8a7795_compatible = {
|
||||
|
||||
@@ -38,10 +38,7 @@ struct realtek_pci_sdmmc {
|
||||
bool double_clk;
|
||||
bool eject;
|
||||
bool initial_mode;
|
||||
int power_state;
|
||||
#define SDMMC_POWER_ON 1
|
||||
#define SDMMC_POWER_OFF 0
|
||||
|
||||
int prev_power_state;
|
||||
int sg_count;
|
||||
s32 cookie;
|
||||
int cookie_sg_count;
|
||||
@@ -905,7 +902,7 @@ static int sd_set_bus_width(struct realtek_pci_sdmmc *host,
|
||||
return err;
|
||||
}
|
||||
|
||||
static int sd_power_on(struct realtek_pci_sdmmc *host)
|
||||
static int sd_power_on(struct realtek_pci_sdmmc *host, unsigned char power_mode)
|
||||
{
|
||||
struct rtsx_pcr *pcr = host->pcr;
|
||||
struct mmc_host *mmc = host->mmc;
|
||||
@@ -913,9 +910,14 @@ static int sd_power_on(struct realtek_pci_sdmmc *host)
|
||||
u32 val;
|
||||
u8 test_mode;
|
||||
|
||||
if (host->power_state == SDMMC_POWER_ON)
|
||||
if (host->prev_power_state == MMC_POWER_ON)
|
||||
return 0;
|
||||
|
||||
if (host->prev_power_state == MMC_POWER_UP) {
|
||||
rtsx_pci_write_register(pcr, SD_BUS_STAT, SD_CLK_TOGGLE_EN, 0);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
msleep(100);
|
||||
|
||||
rtsx_pci_init_cmd(pcr);
|
||||
@@ -936,10 +938,15 @@ static int sd_power_on(struct realtek_pci_sdmmc *host)
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
mdelay(1);
|
||||
|
||||
err = rtsx_pci_write_register(pcr, CARD_OE, SD_OUTPUT_EN, SD_OUTPUT_EN);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
/* send at least 74 clocks */
|
||||
rtsx_pci_write_register(pcr, SD_BUS_STAT, SD_CLK_TOGGLE_EN, SD_CLK_TOGGLE_EN);
|
||||
|
||||
if (PCI_PID(pcr) == PID_5261) {
|
||||
/*
|
||||
* If test mode is set switch to SD Express mandatorily,
|
||||
@@ -964,7 +971,8 @@ static int sd_power_on(struct realtek_pci_sdmmc *host)
|
||||
}
|
||||
}
|
||||
|
||||
host->power_state = SDMMC_POWER_ON;
|
||||
finish:
|
||||
host->prev_power_state = power_mode;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -973,7 +981,7 @@ static int sd_power_off(struct realtek_pci_sdmmc *host)
|
||||
struct rtsx_pcr *pcr = host->pcr;
|
||||
int err;
|
||||
|
||||
host->power_state = SDMMC_POWER_OFF;
|
||||
host->prev_power_state = MMC_POWER_OFF;
|
||||
|
||||
rtsx_pci_init_cmd(pcr);
|
||||
|
||||
@@ -999,7 +1007,7 @@ static int sd_set_power_mode(struct realtek_pci_sdmmc *host,
|
||||
if (power_mode == MMC_POWER_OFF)
|
||||
err = sd_power_off(host);
|
||||
else
|
||||
err = sd_power_on(host);
|
||||
err = sd_power_on(host, power_mode);
|
||||
|
||||
return err;
|
||||
}
|
||||
@@ -1482,10 +1490,11 @@ static int rtsx_pci_sdmmc_drv_probe(struct platform_device *pdev)
|
||||
|
||||
host = mmc_priv(mmc);
|
||||
host->pcr = pcr;
|
||||
mmc->ios.power_delay_ms = 5;
|
||||
host->mmc = mmc;
|
||||
host->pdev = pdev;
|
||||
host->cookie = -1;
|
||||
host->power_state = SDMMC_POWER_OFF;
|
||||
host->prev_power_state = MMC_POWER_OFF;
|
||||
INIT_WORK(&host->work, sd_request);
|
||||
platform_set_drvdata(pdev, host);
|
||||
pcr->slots[RTSX_SD_CARD].p_dev = pdev;
|
||||
|
||||
@@ -308,17 +308,15 @@ static const struct dev_pm_ops sdhci_at91_dev_pm_ops = {
|
||||
|
||||
static int sdhci_at91_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct of_device_id *match;
|
||||
const struct sdhci_at91_soc_data *soc_data;
|
||||
struct sdhci_host *host;
|
||||
struct sdhci_pltfm_host *pltfm_host;
|
||||
struct sdhci_at91_priv *priv;
|
||||
int ret;
|
||||
|
||||
match = of_match_device(sdhci_at91_dt_match, &pdev->dev);
|
||||
if (!match)
|
||||
soc_data = of_device_get_match_data(&pdev->dev);
|
||||
if (!soc_data)
|
||||
return -EINVAL;
|
||||
soc_data = match->data;
|
||||
|
||||
host = sdhci_pltfm_init(pdev, soc_data->pdata, sizeof(*priv));
|
||||
if (IS_ERR(host))
|
||||
|
||||
@@ -934,7 +934,7 @@ static struct soc_device_attribute soc_tuning_erratum_type1[] = {
|
||||
{ .family = "QorIQ T1040", },
|
||||
{ .family = "QorIQ T2080", },
|
||||
{ .family = "QorIQ LS1021A", },
|
||||
{ },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static struct soc_device_attribute soc_tuning_erratum_type2[] = {
|
||||
@@ -944,7 +944,7 @@ static struct soc_device_attribute soc_tuning_erratum_type2[] = {
|
||||
{ .family = "QorIQ LS1080A", },
|
||||
{ .family = "QorIQ LS2080A", },
|
||||
{ .family = "QorIQ LA1575A", },
|
||||
{ },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static void esdhc_tuning_block_enable(struct sdhci_host *host, bool enable)
|
||||
@@ -1316,21 +1316,21 @@ static const struct sdhci_pltfm_data sdhci_esdhc_le_pdata = {
|
||||
static struct soc_device_attribute soc_incorrect_hostver[] = {
|
||||
{ .family = "QorIQ T4240", .revision = "1.0", },
|
||||
{ .family = "QorIQ T4240", .revision = "2.0", },
|
||||
{ },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static struct soc_device_attribute soc_fixup_sdhc_clkdivs[] = {
|
||||
{ .family = "QorIQ LX2160A", .revision = "1.0", },
|
||||
{ .family = "QorIQ LX2160A", .revision = "2.0", },
|
||||
{ .family = "QorIQ LS1028A", .revision = "1.0", },
|
||||
{ },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static struct soc_device_attribute soc_unreliable_pulse_detection[] = {
|
||||
{ .family = "QorIQ LX2160A", .revision = "1.0", },
|
||||
{ .family = "QorIQ LX2160A", .revision = "2.0", },
|
||||
{ .family = "QorIQ LS1028A", .revision = "1.0", },
|
||||
{ },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static void esdhc_init(struct platform_device *pdev, struct sdhci_host *host)
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <linux/mmc/mmc.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include "sdhci.h"
|
||||
#include "sdhci-pci.h"
|
||||
#include "cqhci.h"
|
||||
@@ -63,6 +64,7 @@
|
||||
#define GLI_9750_MISC_RX_INV_OFF 0x0
|
||||
#define GLI_9750_MISC_RX_INV_VALUE GLI_9750_MISC_RX_INV_OFF
|
||||
#define GLI_9750_MISC_TX1_DLY_VALUE 0x5
|
||||
#define SDHCI_GLI_9750_MISC_SSC_OFF BIT(26)
|
||||
|
||||
#define SDHCI_GLI_9750_TUNING_CONTROL 0x540
|
||||
#define SDHCI_GLI_9750_TUNING_CONTROL_EN BIT(4)
|
||||
@@ -137,6 +139,9 @@
|
||||
#define PCI_GLI_9755_SerDes 0x70
|
||||
#define PCI_GLI_9755_SCP_DIS BIT(19)
|
||||
|
||||
#define PCI_GLI_9755_MISC 0x78
|
||||
#define PCI_GLI_9755_MISC_SSC_OFF BIT(26)
|
||||
|
||||
#define GLI_MAX_TUNING_LOOP 40
|
||||
|
||||
/* Genesys Logic chipset */
|
||||
@@ -371,6 +376,19 @@ static void gl9750_set_pll(struct sdhci_host *host, u8 dir, u16 ldiv, u8 pdiv)
|
||||
mdelay(1);
|
||||
}
|
||||
|
||||
static bool gl9750_ssc_enable(struct sdhci_host *host)
|
||||
{
|
||||
u32 misc;
|
||||
u8 off;
|
||||
|
||||
gl9750_wt_on(host);
|
||||
misc = sdhci_readl(host, SDHCI_GLI_9750_MISC);
|
||||
off = FIELD_GET(SDHCI_GLI_9750_MISC_SSC_OFF, misc);
|
||||
gl9750_wt_off(host);
|
||||
|
||||
return !off;
|
||||
}
|
||||
|
||||
static void gl9750_set_ssc(struct sdhci_host *host, u8 enable, u8 step, u16 ppm)
|
||||
{
|
||||
u32 pll;
|
||||
@@ -392,11 +410,31 @@ static void gl9750_set_ssc(struct sdhci_host *host, u8 enable, u8 step, u16 ppm)
|
||||
|
||||
static void gl9750_set_ssc_pll_205mhz(struct sdhci_host *host)
|
||||
{
|
||||
/* set pll to 205MHz and enable ssc */
|
||||
gl9750_set_ssc(host, 0x1, 0x1F, 0xFFE7);
|
||||
bool enable = gl9750_ssc_enable(host);
|
||||
|
||||
/* set pll to 205MHz and ssc */
|
||||
gl9750_set_ssc(host, enable, 0xF, 0x5A1D);
|
||||
gl9750_set_pll(host, 0x1, 0x246, 0x0);
|
||||
}
|
||||
|
||||
static void gl9750_set_ssc_pll_100mhz(struct sdhci_host *host)
|
||||
{
|
||||
bool enable = gl9750_ssc_enable(host);
|
||||
|
||||
/* set pll to 100MHz and ssc */
|
||||
gl9750_set_ssc(host, enable, 0xE, 0x51EC);
|
||||
gl9750_set_pll(host, 0x1, 0x244, 0x1);
|
||||
}
|
||||
|
||||
static void gl9750_set_ssc_pll_50mhz(struct sdhci_host *host)
|
||||
{
|
||||
bool enable = gl9750_ssc_enable(host);
|
||||
|
||||
/* set pll to 50MHz and ssc */
|
||||
gl9750_set_ssc(host, enable, 0xE, 0x51EC);
|
||||
gl9750_set_pll(host, 0x1, 0x244, 0x3);
|
||||
}
|
||||
|
||||
static void sdhci_gl9750_set_clock(struct sdhci_host *host, unsigned int clock)
|
||||
{
|
||||
struct mmc_ios *ios = &host->mmc->ios;
|
||||
@@ -414,6 +452,10 @@ static void sdhci_gl9750_set_clock(struct sdhci_host *host, unsigned int clock)
|
||||
if (clock == 200000000 && ios->timing == MMC_TIMING_UHS_SDR104) {
|
||||
host->mmc->actual_clock = 205000000;
|
||||
gl9750_set_ssc_pll_205mhz(host);
|
||||
} else if (clock == 100000000) {
|
||||
gl9750_set_ssc_pll_100mhz(host);
|
||||
} else if (clock == 50000000) {
|
||||
gl9750_set_ssc_pll_50mhz(host);
|
||||
}
|
||||
|
||||
sdhci_enable_clk(host, clk);
|
||||
@@ -514,6 +556,19 @@ static void gl9755_set_pll(struct pci_dev *pdev, u8 dir, u16 ldiv, u8 pdiv)
|
||||
mdelay(1);
|
||||
}
|
||||
|
||||
static bool gl9755_ssc_enable(struct pci_dev *pdev)
|
||||
{
|
||||
u32 misc;
|
||||
u8 off;
|
||||
|
||||
gl9755_wt_on(pdev);
|
||||
pci_read_config_dword(pdev, PCI_GLI_9755_MISC, &misc);
|
||||
off = FIELD_GET(PCI_GLI_9755_MISC_SSC_OFF, misc);
|
||||
gl9755_wt_off(pdev);
|
||||
|
||||
return !off;
|
||||
}
|
||||
|
||||
static void gl9755_set_ssc(struct pci_dev *pdev, u8 enable, u8 step, u16 ppm)
|
||||
{
|
||||
u32 pll;
|
||||
@@ -535,11 +590,31 @@ static void gl9755_set_ssc(struct pci_dev *pdev, u8 enable, u8 step, u16 ppm)
|
||||
|
||||
static void gl9755_set_ssc_pll_205mhz(struct pci_dev *pdev)
|
||||
{
|
||||
/* set pll to 205MHz and enable ssc */
|
||||
gl9755_set_ssc(pdev, 0x1, 0x1F, 0xFFE7);
|
||||
bool enable = gl9755_ssc_enable(pdev);
|
||||
|
||||
/* set pll to 205MHz and ssc */
|
||||
gl9755_set_ssc(pdev, enable, 0xF, 0x5A1D);
|
||||
gl9755_set_pll(pdev, 0x1, 0x246, 0x0);
|
||||
}
|
||||
|
||||
static void gl9755_set_ssc_pll_100mhz(struct pci_dev *pdev)
|
||||
{
|
||||
bool enable = gl9755_ssc_enable(pdev);
|
||||
|
||||
/* set pll to 100MHz and ssc */
|
||||
gl9755_set_ssc(pdev, enable, 0xE, 0x51EC);
|
||||
gl9755_set_pll(pdev, 0x1, 0x244, 0x1);
|
||||
}
|
||||
|
||||
static void gl9755_set_ssc_pll_50mhz(struct pci_dev *pdev)
|
||||
{
|
||||
bool enable = gl9755_ssc_enable(pdev);
|
||||
|
||||
/* set pll to 50MHz and ssc */
|
||||
gl9755_set_ssc(pdev, enable, 0xE, 0x51EC);
|
||||
gl9755_set_pll(pdev, 0x1, 0x244, 0x3);
|
||||
}
|
||||
|
||||
static void sdhci_gl9755_set_clock(struct sdhci_host *host, unsigned int clock)
|
||||
{
|
||||
struct sdhci_pci_slot *slot = sdhci_priv(host);
|
||||
@@ -560,6 +635,10 @@ static void sdhci_gl9755_set_clock(struct sdhci_host *host, unsigned int clock)
|
||||
if (clock == 200000000 && ios->timing == MMC_TIMING_UHS_SDR104) {
|
||||
host->mmc->actual_clock = 205000000;
|
||||
gl9755_set_ssc_pll_205mhz(pdev);
|
||||
} else if (clock == 100000000) {
|
||||
gl9755_set_ssc_pll_100mhz(pdev);
|
||||
} else if (clock == 50000000) {
|
||||
gl9755_set_ssc_pll_50mhz(pdev);
|
||||
}
|
||||
|
||||
sdhci_enable_clk(host, clk);
|
||||
@@ -873,6 +952,47 @@ static void gli_set_gl9763e(struct sdhci_pci_slot *slot)
|
||||
pci_write_config_dword(pdev, PCIE_GLI_9763E_VHS, value);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int gl9763e_runtime_suspend(struct sdhci_pci_chip *chip)
|
||||
{
|
||||
struct sdhci_pci_slot *slot = chip->slots[0];
|
||||
struct sdhci_host *host = slot->host;
|
||||
u16 clock;
|
||||
|
||||
clock = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
|
||||
clock &= ~(SDHCI_CLOCK_PLL_EN | SDHCI_CLOCK_CARD_EN);
|
||||
sdhci_writew(host, clock, SDHCI_CLOCK_CONTROL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gl9763e_runtime_resume(struct sdhci_pci_chip *chip)
|
||||
{
|
||||
struct sdhci_pci_slot *slot = chip->slots[0];
|
||||
struct sdhci_host *host = slot->host;
|
||||
u16 clock;
|
||||
|
||||
clock = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
|
||||
|
||||
clock |= SDHCI_CLOCK_PLL_EN;
|
||||
clock &= ~SDHCI_CLOCK_INT_STABLE;
|
||||
sdhci_writew(host, clock, SDHCI_CLOCK_CONTROL);
|
||||
|
||||
/* Wait max 150 ms */
|
||||
if (read_poll_timeout(sdhci_readw, clock, (clock & SDHCI_CLOCK_INT_STABLE),
|
||||
1000, 150000, false, host, SDHCI_CLOCK_CONTROL)) {
|
||||
pr_err("%s: PLL clock never stabilised.\n",
|
||||
mmc_hostname(host->mmc));
|
||||
sdhci_dumpregs(host);
|
||||
}
|
||||
|
||||
clock |= SDHCI_CLOCK_CARD_EN;
|
||||
sdhci_writew(host, clock, SDHCI_CLOCK_CONTROL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int gli_probe_slot_gl9763e(struct sdhci_pci_slot *slot)
|
||||
{
|
||||
struct pci_dev *pdev = slot->chip->pdev;
|
||||
@@ -982,6 +1102,11 @@ const struct sdhci_pci_fixes sdhci_gl9763e = {
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
.resume = sdhci_cqhci_gli_resume,
|
||||
.suspend = sdhci_cqhci_gli_suspend,
|
||||
#endif
|
||||
#ifdef CONFIG_PM
|
||||
.runtime_suspend = gl9763e_runtime_suspend,
|
||||
.runtime_resume = gl9763e_runtime_resume,
|
||||
.allow_runtime_pm = true,
|
||||
#endif
|
||||
.add_host = gl9763e_add_host,
|
||||
};
|
||||
|
||||
@@ -1618,7 +1618,6 @@ cleanup:
|
||||
|
||||
static int sdhci_tegra_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct of_device_id *match;
|
||||
const struct sdhci_tegra_soc_data *soc_data;
|
||||
struct sdhci_host *host;
|
||||
struct sdhci_pltfm_host *pltfm_host;
|
||||
@@ -1626,10 +1625,9 @@ static int sdhci_tegra_probe(struct platform_device *pdev)
|
||||
struct clk *clk;
|
||||
int rc;
|
||||
|
||||
match = of_match_device(sdhci_tegra_dt_match, &pdev->dev);
|
||||
if (!match)
|
||||
soc_data = of_device_get_match_data(&pdev->dev);
|
||||
if (!soc_data)
|
||||
return -EINVAL;
|
||||
soc_data = match->data;
|
||||
|
||||
host = sdhci_pltfm_init(pdev, soc_data->pdata, sizeof(*tegra_host));
|
||||
if (IS_ERR(host))
|
||||
@@ -1673,6 +1671,9 @@ static int sdhci_tegra_probe(struct platform_device *pdev)
|
||||
/* HW busy detection is supported, but R1B responses are required. */
|
||||
host->mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY | MMC_CAP_NEED_RSP_BUSY;
|
||||
|
||||
/* GPIO CD can be set as a wakeup source */
|
||||
host->mmc->caps |= MMC_CAP_CD_WAKE;
|
||||
|
||||
tegra_sdhci_parse_dt(host);
|
||||
|
||||
tegra_host->power_gpio = devm_gpiod_get_optional(&pdev->dev, "power",
|
||||
@@ -1840,7 +1841,7 @@ static int sdhci_tegra_suspend(struct device *dev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return mmc_gpio_set_cd_wake(host->mmc, true);
|
||||
}
|
||||
|
||||
static int sdhci_tegra_resume(struct device *dev)
|
||||
@@ -1848,6 +1849,10 @@ static int sdhci_tegra_resume(struct device *dev)
|
||||
struct sdhci_host *host = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
|
||||
ret = mmc_gpio_set_cd_wake(host->mmc, false);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = pm_runtime_force_resume(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -514,26 +514,6 @@ static const struct sdhci_am654_driver_data sdhci_j721e_4bit_drvdata = {
|
||||
.flags = IOMUX_PRESENT,
|
||||
};
|
||||
|
||||
static const struct sdhci_pltfm_data sdhci_am64_8bit_pdata = {
|
||||
.ops = &sdhci_j721e_8bit_ops,
|
||||
.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN,
|
||||
};
|
||||
|
||||
static const struct sdhci_am654_driver_data sdhci_am64_8bit_drvdata = {
|
||||
.pdata = &sdhci_am64_8bit_pdata,
|
||||
.flags = DLL_PRESENT | DLL_CALIB,
|
||||
};
|
||||
|
||||
static const struct sdhci_pltfm_data sdhci_am64_4bit_pdata = {
|
||||
.ops = &sdhci_j721e_4bit_ops,
|
||||
.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN,
|
||||
};
|
||||
|
||||
static const struct sdhci_am654_driver_data sdhci_am64_4bit_drvdata = {
|
||||
.pdata = &sdhci_am64_4bit_pdata,
|
||||
.flags = IOMUX_PRESENT,
|
||||
};
|
||||
|
||||
static const struct soc_device_attribute sdhci_am654_devices[] = {
|
||||
{ .family = "AM65X",
|
||||
.revision = "SR1.0",
|
||||
@@ -759,11 +739,15 @@ static const struct of_device_id sdhci_am654_of_match[] = {
|
||||
},
|
||||
{
|
||||
.compatible = "ti,am64-sdhci-8bit",
|
||||
.data = &sdhci_am64_8bit_drvdata,
|
||||
.data = &sdhci_j721e_8bit_drvdata,
|
||||
},
|
||||
{
|
||||
.compatible = "ti,am64-sdhci-4bit",
|
||||
.data = &sdhci_am64_4bit_drvdata,
|
||||
.data = &sdhci_j721e_4bit_drvdata,
|
||||
},
|
||||
{
|
||||
.compatible = "ti,am62-sdhci",
|
||||
.data = &sdhci_j721e_4bit_drvdata,
|
||||
},
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
@@ -521,8 +521,7 @@ static void sh_mmcif_clock_control(struct sh_mmcif_host *host, unsigned int clk)
|
||||
}
|
||||
|
||||
dev_dbg(dev, "clk %u/%u (%u, 0x%x)\n",
|
||||
(best_freq / (1 << (clkdiv + 1))), clk,
|
||||
best_freq, clkdiv);
|
||||
(best_freq >> (clkdiv + 1)), clk, best_freq, clkdiv);
|
||||
|
||||
clk_set_rate(host->clk, best_freq);
|
||||
clkdiv = clkdiv << 16;
|
||||
@@ -1012,8 +1011,8 @@ static void sh_mmcif_clk_setup(struct sh_mmcif_host *host)
|
||||
*/
|
||||
host->clkdiv_map = 0x3ff;
|
||||
|
||||
host->mmc->f_max = f_max / (1 << ffs(host->clkdiv_map));
|
||||
host->mmc->f_min = f_min / (1 << fls(host->clkdiv_map));
|
||||
host->mmc->f_max = f_max >> ffs(host->clkdiv_map);
|
||||
host->mmc->f_min = f_min >> fls(host->clkdiv_map);
|
||||
} else {
|
||||
unsigned int clk = clk_get_rate(host->clk);
|
||||
|
||||
|
||||
@@ -1167,6 +1167,14 @@ static const struct sunxi_mmc_cfg sun9i_a80_cfg = {
|
||||
.can_calibrate = false,
|
||||
};
|
||||
|
||||
static const struct sunxi_mmc_cfg sun20i_d1_cfg = {
|
||||
.idma_des_size_bits = 13,
|
||||
.idma_des_shift = 2,
|
||||
.can_calibrate = true,
|
||||
.mask_data0 = true,
|
||||
.needs_new_timings = true,
|
||||
};
|
||||
|
||||
static const struct sunxi_mmc_cfg sun50i_a64_cfg = {
|
||||
.idma_des_size_bits = 16,
|
||||
.clk_delays = NULL,
|
||||
@@ -1205,6 +1213,7 @@ static const struct of_device_id sunxi_mmc_of_match[] = {
|
||||
{ .compatible = "allwinner,sun7i-a20-mmc", .data = &sun7i_a20_cfg },
|
||||
{ .compatible = "allwinner,sun8i-a83t-emmc", .data = &sun8i_a83t_emmc_cfg },
|
||||
{ .compatible = "allwinner,sun9i-a80-mmc", .data = &sun9i_a80_cfg },
|
||||
{ .compatible = "allwinner,sun20i-d1-mmc", .data = &sun20i_d1_cfg },
|
||||
{ .compatible = "allwinner,sun50i-a64-mmc", .data = &sun50i_a64_cfg },
|
||||
{ .compatible = "allwinner,sun50i-a64-emmc", .data = &sun50i_a64_emmc_cfg },
|
||||
{ .compatible = "allwinner,sun50i-a100-mmc", .data = &sun50i_a100_cfg },
|
||||
|
||||
@@ -186,10 +186,6 @@ struct tmio_mmc_host {
|
||||
void (*fixup_request)(struct tmio_mmc_host *host, struct mmc_request *mrq);
|
||||
unsigned int (*get_timeout_cycles)(struct tmio_mmc_host *host);
|
||||
|
||||
void (*prepare_hs400_tuning)(struct tmio_mmc_host *host);
|
||||
void (*hs400_downgrade)(struct tmio_mmc_host *host);
|
||||
void (*hs400_complete)(struct tmio_mmc_host *host);
|
||||
|
||||
const struct tmio_mmc_dma_ops *dma_ops;
|
||||
};
|
||||
|
||||
|
||||
@@ -751,19 +751,16 @@ static int wmt_mci_probe(struct platform_device *pdev)
|
||||
struct mmc_host *mmc;
|
||||
struct wmt_mci_priv *priv;
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
const struct of_device_id *of_id =
|
||||
of_match_device(wmt_mci_dt_ids, &pdev->dev);
|
||||
const struct wmt_mci_caps *wmt_caps;
|
||||
int ret;
|
||||
int regular_irq, dma_irq;
|
||||
|
||||
if (!of_id || !of_id->data) {
|
||||
wmt_caps = of_device_get_match_data(&pdev->dev);
|
||||
if (!wmt_caps) {
|
||||
dev_err(&pdev->dev, "Controller capabilities data missing\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
wmt_caps = of_id->data;
|
||||
|
||||
if (!np) {
|
||||
dev_err(&pdev->dev, "Missing SDMMC description in devicetree\n");
|
||||
return -EFAULT;
|
||||
|
||||
@@ -28,58 +28,34 @@ enum kunit_assert_type {
|
||||
KUNIT_EXPECTATION,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct kunit_loc - Identifies the source location of a line of code.
|
||||
* @line: the line number in the file.
|
||||
* @file: the file name.
|
||||
*/
|
||||
struct kunit_loc {
|
||||
int line;
|
||||
const char *file;
|
||||
};
|
||||
|
||||
#define KUNIT_CURRENT_LOC { .file = __FILE__, .line = __LINE__ }
|
||||
|
||||
/**
|
||||
* struct kunit_assert - Data for printing a failed assertion or expectation.
|
||||
* @test: the test case this expectation/assertion is associated with.
|
||||
* @type: the type (either an expectation or an assertion) of this kunit_assert.
|
||||
* @line: the source code line number that the expectation/assertion is at.
|
||||
* @file: the file path of the source file that the expectation/assertion is in.
|
||||
* @message: an optional message to provide additional context.
|
||||
* @format: a function which formats the data in this kunit_assert to a string.
|
||||
*
|
||||
* Represents a failed expectation/assertion. Contains all the data necessary to
|
||||
* format a string to a user reporting the failure.
|
||||
*/
|
||||
struct kunit_assert {
|
||||
struct kunit *test;
|
||||
enum kunit_assert_type type;
|
||||
int line;
|
||||
const char *file;
|
||||
struct va_format message;
|
||||
void (*format)(const struct kunit_assert *assert,
|
||||
const struct va_format *message,
|
||||
struct string_stream *stream);
|
||||
};
|
||||
|
||||
/**
|
||||
* KUNIT_INIT_VA_FMT_NULL - Default initializer for struct va_format.
|
||||
*
|
||||
* Used inside a struct initialization block to initialize struct va_format to
|
||||
* default values where fmt and va are null.
|
||||
*/
|
||||
#define KUNIT_INIT_VA_FMT_NULL { .fmt = NULL, .va = NULL }
|
||||
|
||||
/**
|
||||
* KUNIT_INIT_ASSERT_STRUCT() - Initializer for a &struct kunit_assert.
|
||||
* @kunit: The test case that this expectation/assertion is associated with.
|
||||
* @assert_type: The type (assertion or expectation) of this kunit_assert.
|
||||
* @fmt: The formatting function which builds a string out of this kunit_assert.
|
||||
*
|
||||
* The base initializer for a &struct kunit_assert.
|
||||
*/
|
||||
#define KUNIT_INIT_ASSERT_STRUCT(kunit, assert_type, fmt) { \
|
||||
.test = kunit, \
|
||||
.type = assert_type, \
|
||||
.file = __FILE__, \
|
||||
.line = __LINE__, \
|
||||
.message = KUNIT_INIT_VA_FMT_NULL, \
|
||||
.format = fmt \
|
||||
}
|
||||
|
||||
void kunit_base_assert_format(const struct kunit_assert *assert,
|
||||
struct string_stream *stream);
|
||||
|
||||
void kunit_assert_print_msg(const struct kunit_assert *assert,
|
||||
struct string_stream *stream);
|
||||
void kunit_assert_prologue(const struct kunit_loc *loc,
|
||||
enum kunit_assert_type type,
|
||||
struct string_stream *stream);
|
||||
|
||||
/**
|
||||
* struct kunit_fail_assert - Represents a plain fail expectation/assertion.
|
||||
@@ -92,20 +68,17 @@ struct kunit_fail_assert {
|
||||
};
|
||||
|
||||
void kunit_fail_assert_format(const struct kunit_assert *assert,
|
||||
const struct va_format *message,
|
||||
struct string_stream *stream);
|
||||
|
||||
/**
|
||||
* KUNIT_INIT_FAIL_ASSERT_STRUCT() - Initializer for &struct kunit_fail_assert.
|
||||
* @test: The test case that this expectation/assertion is associated with.
|
||||
* @type: The type (assertion or expectation) of this kunit_assert.
|
||||
* KUNIT_INIT_FAIL_ASSERT_STRUCT - Initializer for &struct kunit_fail_assert.
|
||||
*
|
||||
* Initializes a &struct kunit_fail_assert. Intended to be used in
|
||||
* KUNIT_EXPECT_* and KUNIT_ASSERT_* macros.
|
||||
*/
|
||||
#define KUNIT_INIT_FAIL_ASSERT_STRUCT(test, type) { \
|
||||
.assert = KUNIT_INIT_ASSERT_STRUCT(test, \
|
||||
type, \
|
||||
kunit_fail_assert_format) \
|
||||
#define KUNIT_INIT_FAIL_ASSERT_STRUCT { \
|
||||
.assert = { .format = kunit_fail_assert_format }, \
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -125,22 +98,19 @@ struct kunit_unary_assert {
|
||||
};
|
||||
|
||||
void kunit_unary_assert_format(const struct kunit_assert *assert,
|
||||
const struct va_format *message,
|
||||
struct string_stream *stream);
|
||||
|
||||
/**
|
||||
* KUNIT_INIT_UNARY_ASSERT_STRUCT() - Initializes &struct kunit_unary_assert.
|
||||
* @test: The test case that this expectation/assertion is associated with.
|
||||
* @type: The type (assertion or expectation) of this kunit_assert.
|
||||
* @cond: A string representation of the expression asserted true or false.
|
||||
* @expect_true: True if of type KUNIT_{EXPECT|ASSERT}_TRUE, false otherwise.
|
||||
*
|
||||
* Initializes a &struct kunit_unary_assert. Intended to be used in
|
||||
* KUNIT_EXPECT_* and KUNIT_ASSERT_* macros.
|
||||
*/
|
||||
#define KUNIT_INIT_UNARY_ASSERT_STRUCT(test, type, cond, expect_true) { \
|
||||
.assert = KUNIT_INIT_ASSERT_STRUCT(test, \
|
||||
type, \
|
||||
kunit_unary_assert_format), \
|
||||
#define KUNIT_INIT_UNARY_ASSERT_STRUCT(cond, expect_true) { \
|
||||
.assert = { .format = kunit_unary_assert_format }, \
|
||||
.condition = cond, \
|
||||
.expected_true = expect_true \
|
||||
}
|
||||
@@ -162,35 +132,43 @@ struct kunit_ptr_not_err_assert {
|
||||
};
|
||||
|
||||
void kunit_ptr_not_err_assert_format(const struct kunit_assert *assert,
|
||||
const struct va_format *message,
|
||||
struct string_stream *stream);
|
||||
|
||||
/**
|
||||
* KUNIT_INIT_PTR_NOT_ERR_ASSERT_STRUCT() - Initializes a
|
||||
* &struct kunit_ptr_not_err_assert.
|
||||
* @test: The test case that this expectation/assertion is associated with.
|
||||
* @type: The type (assertion or expectation) of this kunit_assert.
|
||||
* @txt: A string representation of the expression passed to the expectation.
|
||||
* @val: The actual evaluated pointer value of the expression.
|
||||
*
|
||||
* Initializes a &struct kunit_ptr_not_err_assert. Intended to be used in
|
||||
* KUNIT_EXPECT_* and KUNIT_ASSERT_* macros.
|
||||
*/
|
||||
#define KUNIT_INIT_PTR_NOT_ERR_STRUCT(test, type, txt, val) { \
|
||||
.assert = KUNIT_INIT_ASSERT_STRUCT(test, \
|
||||
type, \
|
||||
kunit_ptr_not_err_assert_format), \
|
||||
#define KUNIT_INIT_PTR_NOT_ERR_STRUCT(txt, val) { \
|
||||
.assert = { .format = kunit_ptr_not_err_assert_format }, \
|
||||
.text = txt, \
|
||||
.value = val \
|
||||
}
|
||||
|
||||
/**
|
||||
* struct kunit_binary_assert_text - holds strings for &struct
|
||||
* kunit_binary_assert and friends to try and make the structs smaller.
|
||||
* @operation: A string representation of the comparison operator (e.g. "==").
|
||||
* @left_text: A string representation of the left expression (e.g. "2+2").
|
||||
* @right_text: A string representation of the right expression (e.g. "2+2").
|
||||
*/
|
||||
struct kunit_binary_assert_text {
|
||||
const char *operation;
|
||||
const char *left_text;
|
||||
const char *right_text;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct kunit_binary_assert - An expectation/assertion that compares two
|
||||
* non-pointer values (for example, KUNIT_EXPECT_EQ(test, 1 + 1, 2)).
|
||||
* @assert: The parent of this type.
|
||||
* @operation: A string representation of the comparison operator (e.g. "==").
|
||||
* @left_text: A string representation of the expression in the left slot.
|
||||
* @text: Holds the textual representations of the operands and op (e.g. "==").
|
||||
* @left_value: The actual evaluated value of the expression in the left slot.
|
||||
* @right_text: A string representation of the expression in the right slot.
|
||||
* @right_value: The actual evaluated value of the expression in the right slot.
|
||||
*
|
||||
* Represents an expectation/assertion that compares two non-pointer values. For
|
||||
@@ -199,44 +177,36 @@ void kunit_ptr_not_err_assert_format(const struct kunit_assert *assert,
|
||||
*/
|
||||
struct kunit_binary_assert {
|
||||
struct kunit_assert assert;
|
||||
const char *operation;
|
||||
const char *left_text;
|
||||
const struct kunit_binary_assert_text *text;
|
||||
long long left_value;
|
||||
const char *right_text;
|
||||
long long right_value;
|
||||
};
|
||||
|
||||
void kunit_binary_assert_format(const struct kunit_assert *assert,
|
||||
const struct va_format *message,
|
||||
struct string_stream *stream);
|
||||
|
||||
/**
|
||||
* KUNIT_INIT_BINARY_ASSERT_STRUCT() - Initializes a
|
||||
* &struct kunit_binary_assert.
|
||||
* @test: The test case that this expectation/assertion is associated with.
|
||||
* @type: The type (assertion or expectation) of this kunit_assert.
|
||||
* @op_str: A string representation of the comparison operator (e.g. "==").
|
||||
* @left_str: A string representation of the expression in the left slot.
|
||||
* KUNIT_INIT_BINARY_ASSERT_STRUCT() - Initializes a binary assert like
|
||||
* kunit_binary_assert, kunit_binary_ptr_assert, etc.
|
||||
*
|
||||
* @format_func: a function which formats the assert to a string.
|
||||
* @text_: Pointer to a kunit_binary_assert_text.
|
||||
* @left_val: The actual evaluated value of the expression in the left slot.
|
||||
* @right_str: A string representation of the expression in the right slot.
|
||||
* @right_val: The actual evaluated value of the expression in the right slot.
|
||||
*
|
||||
* Initializes a &struct kunit_binary_assert. Intended to be used in
|
||||
* KUNIT_EXPECT_* and KUNIT_ASSERT_* macros.
|
||||
* Initializes a binary assert like kunit_binary_assert,
|
||||
* kunit_binary_ptr_assert, etc. This relies on these structs having the same
|
||||
* fields but with different types for left_val/right_val.
|
||||
* This is ultimately used by binary assertion macros like KUNIT_EXPECT_EQ, etc.
|
||||
*/
|
||||
#define KUNIT_INIT_BINARY_ASSERT_STRUCT(test, \
|
||||
type, \
|
||||
op_str, \
|
||||
left_str, \
|
||||
#define KUNIT_INIT_BINARY_ASSERT_STRUCT(format_func, \
|
||||
text_, \
|
||||
left_val, \
|
||||
right_str, \
|
||||
right_val) { \
|
||||
.assert = KUNIT_INIT_ASSERT_STRUCT(test, \
|
||||
type, \
|
||||
kunit_binary_assert_format), \
|
||||
.operation = op_str, \
|
||||
.left_text = left_str, \
|
||||
.assert = { .format = format_func }, \
|
||||
.text = text_, \
|
||||
.left_value = left_val, \
|
||||
.right_text = right_str, \
|
||||
.right_value = right_val \
|
||||
}
|
||||
|
||||
@@ -244,10 +214,8 @@ void kunit_binary_assert_format(const struct kunit_assert *assert,
|
||||
* struct kunit_binary_ptr_assert - An expectation/assertion that compares two
|
||||
* pointer values (for example, KUNIT_EXPECT_PTR_EQ(test, foo, bar)).
|
||||
* @assert: The parent of this type.
|
||||
* @operation: A string representation of the comparison operator (e.g. "==").
|
||||
* @left_text: A string representation of the expression in the left slot.
|
||||
* @text: Holds the textual representations of the operands and op (e.g. "==").
|
||||
* @left_value: The actual evaluated value of the expression in the left slot.
|
||||
* @right_text: A string representation of the expression in the right slot.
|
||||
* @right_value: The actual evaluated value of the expression in the right slot.
|
||||
*
|
||||
* Represents an expectation/assertion that compares two pointer values. For
|
||||
@@ -256,55 +224,21 @@ void kunit_binary_assert_format(const struct kunit_assert *assert,
|
||||
*/
|
||||
struct kunit_binary_ptr_assert {
|
||||
struct kunit_assert assert;
|
||||
const char *operation;
|
||||
const char *left_text;
|
||||
const struct kunit_binary_assert_text *text;
|
||||
const void *left_value;
|
||||
const char *right_text;
|
||||
const void *right_value;
|
||||
};
|
||||
|
||||
void kunit_binary_ptr_assert_format(const struct kunit_assert *assert,
|
||||
const struct va_format *message,
|
||||
struct string_stream *stream);
|
||||
|
||||
/**
|
||||
* KUNIT_INIT_BINARY_PTR_ASSERT_STRUCT() - Initializes a
|
||||
* &struct kunit_binary_ptr_assert.
|
||||
* @test: The test case that this expectation/assertion is associated with.
|
||||
* @type: The type (assertion or expectation) of this kunit_assert.
|
||||
* @op_str: A string representation of the comparison operator (e.g. "==").
|
||||
* @left_str: A string representation of the expression in the left slot.
|
||||
* @left_val: The actual evaluated value of the expression in the left slot.
|
||||
* @right_str: A string representation of the expression in the right slot.
|
||||
* @right_val: The actual evaluated value of the expression in the right slot.
|
||||
*
|
||||
* Initializes a &struct kunit_binary_ptr_assert. Intended to be used in
|
||||
* KUNIT_EXPECT_* and KUNIT_ASSERT_* macros.
|
||||
*/
|
||||
#define KUNIT_INIT_BINARY_PTR_ASSERT_STRUCT(test, \
|
||||
type, \
|
||||
op_str, \
|
||||
left_str, \
|
||||
left_val, \
|
||||
right_str, \
|
||||
right_val) { \
|
||||
.assert = KUNIT_INIT_ASSERT_STRUCT(test, \
|
||||
type, \
|
||||
kunit_binary_ptr_assert_format), \
|
||||
.operation = op_str, \
|
||||
.left_text = left_str, \
|
||||
.left_value = left_val, \
|
||||
.right_text = right_str, \
|
||||
.right_value = right_val \
|
||||
}
|
||||
|
||||
/**
|
||||
* struct kunit_binary_str_assert - An expectation/assertion that compares two
|
||||
* string values (for example, KUNIT_EXPECT_STREQ(test, foo, "bar")).
|
||||
* @assert: The parent of this type.
|
||||
* @operation: A string representation of the comparison operator (e.g. "==").
|
||||
* @left_text: A string representation of the expression in the left slot.
|
||||
* @text: Holds the textual representations of the operands and comparator.
|
||||
* @left_value: The actual evaluated value of the expression in the left slot.
|
||||
* @right_text: A string representation of the expression in the right slot.
|
||||
* @right_value: The actual evaluated value of the expression in the right slot.
|
||||
*
|
||||
* Represents an expectation/assertion that compares two string values. For
|
||||
@@ -313,45 +247,13 @@ void kunit_binary_ptr_assert_format(const struct kunit_assert *assert,
|
||||
*/
|
||||
struct kunit_binary_str_assert {
|
||||
struct kunit_assert assert;
|
||||
const char *operation;
|
||||
const char *left_text;
|
||||
const struct kunit_binary_assert_text *text;
|
||||
const char *left_value;
|
||||
const char *right_text;
|
||||
const char *right_value;
|
||||
};
|
||||
|
||||
void kunit_binary_str_assert_format(const struct kunit_assert *assert,
|
||||
const struct va_format *message,
|
||||
struct string_stream *stream);
|
||||
|
||||
/**
|
||||
* KUNIT_INIT_BINARY_STR_ASSERT_STRUCT() - Initializes a
|
||||
* &struct kunit_binary_str_assert.
|
||||
* @test: The test case that this expectation/assertion is associated with.
|
||||
* @type: The type (assertion or expectation) of this kunit_assert.
|
||||
* @op_str: A string representation of the comparison operator (e.g. "==").
|
||||
* @left_str: A string representation of the expression in the left slot.
|
||||
* @left_val: The actual evaluated value of the expression in the left slot.
|
||||
* @right_str: A string representation of the expression in the right slot.
|
||||
* @right_val: The actual evaluated value of the expression in the right slot.
|
||||
*
|
||||
* Initializes a &struct kunit_binary_str_assert. Intended to be used in
|
||||
* KUNIT_EXPECT_* and KUNIT_ASSERT_* macros.
|
||||
*/
|
||||
#define KUNIT_INIT_BINARY_STR_ASSERT_STRUCT(test, \
|
||||
type, \
|
||||
op_str, \
|
||||
left_str, \
|
||||
left_val, \
|
||||
right_str, \
|
||||
right_val) { \
|
||||
.assert = KUNIT_INIT_ASSERT_STRUCT(test, \
|
||||
type, \
|
||||
kunit_binary_str_assert_format), \
|
||||
.operation = op_str, \
|
||||
.left_text = left_str, \
|
||||
.left_value = left_val, \
|
||||
.right_text = right_str, \
|
||||
.right_value = right_val \
|
||||
}
|
||||
|
||||
#endif /* _KUNIT_ASSERT_H */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -519,7 +519,10 @@ struct ata_taskfile {
|
||||
u8 hob_lbam;
|
||||
u8 hob_lbah;
|
||||
|
||||
u8 feature;
|
||||
union {
|
||||
u8 error;
|
||||
u8 feature;
|
||||
};
|
||||
u8 nsect;
|
||||
u8 lbal;
|
||||
u8 lbam;
|
||||
@@ -527,7 +530,10 @@ struct ata_taskfile {
|
||||
|
||||
u8 device;
|
||||
|
||||
u8 command; /* IO operation */
|
||||
union {
|
||||
u8 status;
|
||||
u8 command;
|
||||
};
|
||||
|
||||
u32 auxiliary; /* auxiliary field */
|
||||
/* from SATA 3.1 and */
|
||||
@@ -1081,7 +1087,7 @@ extern int ata_sas_scsi_ioctl(struct ata_port *ap, struct scsi_device *dev,
|
||||
extern bool ata_link_online(struct ata_link *link);
|
||||
extern bool ata_link_offline(struct ata_link *link);
|
||||
#ifdef CONFIG_PM
|
||||
extern int ata_host_suspend(struct ata_host *host, pm_message_t mesg);
|
||||
extern void ata_host_suspend(struct ata_host *host, pm_message_t mesg);
|
||||
extern void ata_host_resume(struct ata_host *host);
|
||||
extern void ata_sas_port_suspend(struct ata_port *ap);
|
||||
extern void ata_sas_port_resume(struct ata_port *ap);
|
||||
|
||||
@@ -6255,6 +6255,7 @@ static void cgroup_css_set_put_fork(struct kernel_clone_args *kargs)
|
||||
/**
|
||||
* cgroup_can_fork - called on a new task before the process is exposed
|
||||
* @child: the child process
|
||||
* @kargs: the arguments passed to create the child process
|
||||
*
|
||||
* This prepares a new css_set for the child process which the child will
|
||||
* be attached to in cgroup_post_fork().
|
||||
@@ -6317,6 +6318,7 @@ void cgroup_cancel_fork(struct task_struct *child,
|
||||
/**
|
||||
* cgroup_post_fork - finalize cgroup setup for the child process
|
||||
* @child: the child process
|
||||
* @kargs: the arguments passed to create the child process
|
||||
*
|
||||
* Attach the child process to its css_set calling the subsystem fork()
|
||||
* callbacks.
|
||||
|
||||
@@ -73,7 +73,7 @@ DEFINE_STATIC_KEY_FALSE(cpusets_enabled_key);
|
||||
|
||||
/*
|
||||
* There could be abnormal cpuset configurations for cpu or memory
|
||||
* node binding, add this key to provide a quick low-cost judgement
|
||||
* node binding, add this key to provide a quick low-cost judgment
|
||||
* of the situation.
|
||||
*/
|
||||
DEFINE_STATIC_KEY_FALSE(cpusets_insane_config_key);
|
||||
@@ -1192,7 +1192,7 @@ enum subparts_cmd {
|
||||
* effective_cpus. The function will return 0 if all the CPUs listed in
|
||||
* cpus_allowed can be granted or an error code will be returned.
|
||||
*
|
||||
* For partcmd_disable, the cpuset is being transofrmed from a partition
|
||||
* For partcmd_disable, the cpuset is being transformed from a partition
|
||||
* root back to a non-partition root. Any CPUs in cpus_allowed that are in
|
||||
* parent's subparts_cpus will be taken away from that cpumask and put back
|
||||
* into parent's effective_cpus. 0 should always be returned.
|
||||
@@ -2040,7 +2040,7 @@ out:
|
||||
}
|
||||
|
||||
/*
|
||||
* update_prstate - update partititon_root_state
|
||||
* update_prstate - update partition_root_state
|
||||
* cs: the cpuset to update
|
||||
* new_prs: new partition root state
|
||||
*
|
||||
@@ -2892,7 +2892,7 @@ static int cpuset_css_online(struct cgroup_subsys_state *css)
|
||||
/*
|
||||
* Clone @parent's configuration if CGRP_CPUSET_CLONE_CHILDREN is
|
||||
* set. This flag handling is implemented in cgroup core for
|
||||
* histrical reasons - the flag may be specified during mount.
|
||||
* historical reasons - the flag may be specified during mount.
|
||||
*
|
||||
* Currently, if any sibling cpusets have exclusive cpus or mem, we
|
||||
* refuse to clone the configuration - thereby refusing the task to
|
||||
@@ -3092,7 +3092,7 @@ hotplug_update_tasks_legacy(struct cpuset *cs,
|
||||
|
||||
/*
|
||||
* Don't call update_tasks_cpumask() if the cpuset becomes empty,
|
||||
* as the tasks will be migratecd to an ancestor.
|
||||
* as the tasks will be migrated to an ancestor.
|
||||
*/
|
||||
if (cpus_updated && !cpumask_empty(cs->cpus_allowed))
|
||||
update_tasks_cpumask(cs);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//SPDX-License-Identifier: GPL-2.0
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include <linux/cgroup.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/sched/task.h>
|
||||
|
||||
@@ -315,7 +315,7 @@ static void cgroup_base_stat_flush(struct cgroup *cgrp, int cpu)
|
||||
{
|
||||
struct cgroup_rstat_cpu *rstatc = cgroup_rstat_cpu(cgrp, cpu);
|
||||
struct cgroup *parent = cgroup_parent(cgrp);
|
||||
struct cgroup_base_stat cur, delta;
|
||||
struct cgroup_base_stat delta;
|
||||
unsigned seq;
|
||||
|
||||
/* Root-level stats are sourced from system-wide CPU stats */
|
||||
@@ -325,11 +325,10 @@ static void cgroup_base_stat_flush(struct cgroup *cgrp, int cpu)
|
||||
/* fetch the current per-cpu values */
|
||||
do {
|
||||
seq = __u64_stats_fetch_begin(&rstatc->bsync);
|
||||
cur.cputime = rstatc->bstat.cputime;
|
||||
delta = rstatc->bstat;
|
||||
} while (__u64_stats_fetch_retry(&rstatc->bsync, seq));
|
||||
|
||||
/* propagate percpu delta to global */
|
||||
delta = cur;
|
||||
cgroup_base_stat_sub(&delta, &rstatc->last_bstat);
|
||||
cgroup_base_stat_add(&cgrp->bstat, &delta);
|
||||
cgroup_base_stat_add(&rstatc->last_bstat, &delta);
|
||||
|
||||
@@ -158,15 +158,20 @@ struct worker_pool {
|
||||
|
||||
unsigned long watchdog_ts; /* L: watchdog timestamp */
|
||||
|
||||
/* The current concurrency level. */
|
||||
atomic_t nr_running;
|
||||
/*
|
||||
* The counter is incremented in a process context on the associated CPU
|
||||
* w/ preemption disabled, and decremented or reset in the same context
|
||||
* but w/ pool->lock held. The readers grab pool->lock and are
|
||||
* guaranteed to see if the counter reached zero.
|
||||
*/
|
||||
int nr_running;
|
||||
|
||||
struct list_head worklist; /* L: list of pending works */
|
||||
|
||||
int nr_workers; /* L: total number of workers */
|
||||
int nr_idle; /* L: currently idle workers */
|
||||
|
||||
struct list_head idle_list; /* X: list of idle workers */
|
||||
struct list_head idle_list; /* L: list of idle workers */
|
||||
struct timer_list idle_timer; /* L: worker idle timeout */
|
||||
struct timer_list mayday_timer; /* L: SOS timer for workers */
|
||||
|
||||
@@ -781,7 +786,7 @@ static bool work_is_canceling(struct work_struct *work)
|
||||
|
||||
static bool __need_more_worker(struct worker_pool *pool)
|
||||
{
|
||||
return !atomic_read(&pool->nr_running);
|
||||
return !pool->nr_running;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -806,8 +811,7 @@ static bool may_start_working(struct worker_pool *pool)
|
||||
/* Do I need to keep working? Called from currently running workers. */
|
||||
static bool keep_working(struct worker_pool *pool)
|
||||
{
|
||||
return !list_empty(&pool->worklist) &&
|
||||
atomic_read(&pool->nr_running) <= 1;
|
||||
return !list_empty(&pool->worklist) && (pool->nr_running <= 1);
|
||||
}
|
||||
|
||||
/* Do we need a new worker? Called from manager. */
|
||||
@@ -830,7 +834,7 @@ static bool too_many_workers(struct worker_pool *pool)
|
||||
* Wake up functions.
|
||||
*/
|
||||
|
||||
/* Return the first idle worker. Safe with preemption disabled */
|
||||
/* Return the first idle worker. Called with pool->lock held. */
|
||||
static struct worker *first_idle_worker(struct worker_pool *pool)
|
||||
{
|
||||
if (unlikely(list_empty(&pool->idle_list)))
|
||||
@@ -877,7 +881,7 @@ void wq_worker_running(struct task_struct *task)
|
||||
*/
|
||||
preempt_disable();
|
||||
if (!(worker->flags & WORKER_NOT_RUNNING))
|
||||
atomic_inc(&worker->pool->nr_running);
|
||||
worker->pool->nr_running++;
|
||||
preempt_enable();
|
||||
worker->sleeping = 0;
|
||||
}
|
||||
@@ -891,7 +895,7 @@ void wq_worker_running(struct task_struct *task)
|
||||
*/
|
||||
void wq_worker_sleeping(struct task_struct *task)
|
||||
{
|
||||
struct worker *next, *worker = kthread_data(task);
|
||||
struct worker *worker = kthread_data(task);
|
||||
struct worker_pool *pool;
|
||||
|
||||
/*
|
||||
@@ -921,23 +925,9 @@ void wq_worker_sleeping(struct task_struct *task)
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* The counterpart of the following dec_and_test, implied mb,
|
||||
* worklist not empty test sequence is in insert_work().
|
||||
* Please read comment there.
|
||||
*
|
||||
* NOT_RUNNING is clear. This means that we're bound to and
|
||||
* running on the local cpu w/ rq lock held and preemption
|
||||
* disabled, which in turn means that none else could be
|
||||
* manipulating idle_list, so dereferencing idle_list without pool
|
||||
* lock is safe.
|
||||
*/
|
||||
if (atomic_dec_and_test(&pool->nr_running) &&
|
||||
!list_empty(&pool->worklist)) {
|
||||
next = first_idle_worker(pool);
|
||||
if (next)
|
||||
wake_up_process(next->task);
|
||||
}
|
||||
pool->nr_running--;
|
||||
if (need_more_worker(pool))
|
||||
wake_up_worker(pool);
|
||||
raw_spin_unlock_irq(&pool->lock);
|
||||
}
|
||||
|
||||
@@ -991,7 +981,7 @@ static inline void worker_set_flags(struct worker *worker, unsigned int flags)
|
||||
/* If transitioning into NOT_RUNNING, adjust nr_running. */
|
||||
if ((flags & WORKER_NOT_RUNNING) &&
|
||||
!(worker->flags & WORKER_NOT_RUNNING)) {
|
||||
atomic_dec(&pool->nr_running);
|
||||
pool->nr_running--;
|
||||
}
|
||||
|
||||
worker->flags |= flags;
|
||||
@@ -1023,7 +1013,7 @@ static inline void worker_clr_flags(struct worker *worker, unsigned int flags)
|
||||
*/
|
||||
if ((flags & WORKER_NOT_RUNNING) && (oflags & WORKER_NOT_RUNNING))
|
||||
if (!(worker->flags & WORKER_NOT_RUNNING))
|
||||
atomic_inc(&pool->nr_running);
|
||||
pool->nr_running++;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1376,13 +1366,6 @@ static void insert_work(struct pool_workqueue *pwq, struct work_struct *work,
|
||||
list_add_tail(&work->entry, head);
|
||||
get_pwq(pwq);
|
||||
|
||||
/*
|
||||
* Ensure either wq_worker_sleeping() sees the above
|
||||
* list_add_tail() or we see zero nr_running to avoid workers lying
|
||||
* around lazily while there are works to be processed.
|
||||
*/
|
||||
smp_mb();
|
||||
|
||||
if (__need_more_worker(pool))
|
||||
wake_up_worker(pool);
|
||||
}
|
||||
@@ -1831,8 +1814,7 @@ static void worker_enter_idle(struct worker *worker)
|
||||
mod_timer(&pool->idle_timer, jiffies + IDLE_WORKER_TIMEOUT);
|
||||
|
||||
/* Sanity check nr_running. */
|
||||
WARN_ON_ONCE(pool->nr_workers == pool->nr_idle &&
|
||||
atomic_read(&pool->nr_running));
|
||||
WARN_ON_ONCE(pool->nr_workers == pool->nr_idle && pool->nr_running);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -5010,7 +4992,7 @@ static void unbind_workers(int cpu)
|
||||
* an unbound (in terms of concurrency management) pool which
|
||||
* are served by workers tied to the pool.
|
||||
*/
|
||||
atomic_set(&pool->nr_running, 0);
|
||||
pool->nr_running = 0;
|
||||
|
||||
/*
|
||||
* With concurrency management just turned off, a busy
|
||||
|
||||
@@ -10,12 +10,13 @@
|
||||
|
||||
#include "string-stream.h"
|
||||
|
||||
void kunit_base_assert_format(const struct kunit_assert *assert,
|
||||
void kunit_assert_prologue(const struct kunit_loc *loc,
|
||||
enum kunit_assert_type type,
|
||||
struct string_stream *stream)
|
||||
{
|
||||
const char *expect_or_assert = NULL;
|
||||
|
||||
switch (assert->type) {
|
||||
switch (type) {
|
||||
case KUNIT_EXPECTATION:
|
||||
expect_or_assert = "EXPECTATION";
|
||||
break;
|
||||
@@ -25,34 +26,33 @@ void kunit_base_assert_format(const struct kunit_assert *assert,
|
||||
}
|
||||
|
||||
string_stream_add(stream, "%s FAILED at %s:%d\n",
|
||||
expect_or_assert, assert->file, assert->line);
|
||||
expect_or_assert, loc->file, loc->line);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(kunit_base_assert_format);
|
||||
EXPORT_SYMBOL_GPL(kunit_assert_prologue);
|
||||
|
||||
void kunit_assert_print_msg(const struct kunit_assert *assert,
|
||||
struct string_stream *stream)
|
||||
static void kunit_assert_print_msg(const struct va_format *message,
|
||||
struct string_stream *stream)
|
||||
{
|
||||
if (assert->message.fmt)
|
||||
string_stream_add(stream, "\n%pV", &assert->message);
|
||||
if (message->fmt)
|
||||
string_stream_add(stream, "\n%pV", message);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(kunit_assert_print_msg);
|
||||
|
||||
void kunit_fail_assert_format(const struct kunit_assert *assert,
|
||||
const struct va_format *message,
|
||||
struct string_stream *stream)
|
||||
{
|
||||
kunit_base_assert_format(assert, stream);
|
||||
string_stream_add(stream, "%pV", &assert->message);
|
||||
string_stream_add(stream, "%pV", message);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(kunit_fail_assert_format);
|
||||
|
||||
void kunit_unary_assert_format(const struct kunit_assert *assert,
|
||||
const struct va_format *message,
|
||||
struct string_stream *stream)
|
||||
{
|
||||
struct kunit_unary_assert *unary_assert;
|
||||
|
||||
unary_assert = container_of(assert, struct kunit_unary_assert, assert);
|
||||
|
||||
kunit_base_assert_format(assert, stream);
|
||||
if (unary_assert->expected_true)
|
||||
string_stream_add(stream,
|
||||
KUNIT_SUBTEST_INDENT "Expected %s to be true, but is false\n",
|
||||
@@ -61,11 +61,12 @@ void kunit_unary_assert_format(const struct kunit_assert *assert,
|
||||
string_stream_add(stream,
|
||||
KUNIT_SUBTEST_INDENT "Expected %s to be false, but is true\n",
|
||||
unary_assert->condition);
|
||||
kunit_assert_print_msg(assert, stream);
|
||||
kunit_assert_print_msg(message, stream);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(kunit_unary_assert_format);
|
||||
|
||||
void kunit_ptr_not_err_assert_format(const struct kunit_assert *assert,
|
||||
const struct va_format *message,
|
||||
struct string_stream *stream)
|
||||
{
|
||||
struct kunit_ptr_not_err_assert *ptr_assert;
|
||||
@@ -73,7 +74,6 @@ void kunit_ptr_not_err_assert_format(const struct kunit_assert *assert,
|
||||
ptr_assert = container_of(assert, struct kunit_ptr_not_err_assert,
|
||||
assert);
|
||||
|
||||
kunit_base_assert_format(assert, stream);
|
||||
if (!ptr_assert->value) {
|
||||
string_stream_add(stream,
|
||||
KUNIT_SUBTEST_INDENT "Expected %s is not null, but is\n",
|
||||
@@ -84,7 +84,7 @@ void kunit_ptr_not_err_assert_format(const struct kunit_assert *assert,
|
||||
ptr_assert->text,
|
||||
PTR_ERR(ptr_assert->value));
|
||||
}
|
||||
kunit_assert_print_msg(assert, stream);
|
||||
kunit_assert_print_msg(message, stream);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(kunit_ptr_not_err_assert_format);
|
||||
|
||||
@@ -112,6 +112,7 @@ static bool is_literal(struct kunit *test, const char *text, long long value,
|
||||
}
|
||||
|
||||
void kunit_binary_assert_format(const struct kunit_assert *assert,
|
||||
const struct va_format *message,
|
||||
struct string_stream *stream)
|
||||
{
|
||||
struct kunit_binary_assert *binary_assert;
|
||||
@@ -119,27 +120,27 @@ void kunit_binary_assert_format(const struct kunit_assert *assert,
|
||||
binary_assert = container_of(assert, struct kunit_binary_assert,
|
||||
assert);
|
||||
|
||||
kunit_base_assert_format(assert, stream);
|
||||
string_stream_add(stream,
|
||||
KUNIT_SUBTEST_INDENT "Expected %s %s %s, but\n",
|
||||
binary_assert->left_text,
|
||||
binary_assert->operation,
|
||||
binary_assert->right_text);
|
||||
if (!is_literal(stream->test, binary_assert->left_text,
|
||||
binary_assert->text->left_text,
|
||||
binary_assert->text->operation,
|
||||
binary_assert->text->right_text);
|
||||
if (!is_literal(stream->test, binary_assert->text->left_text,
|
||||
binary_assert->left_value, stream->gfp))
|
||||
string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == %lld\n",
|
||||
binary_assert->left_text,
|
||||
binary_assert->text->left_text,
|
||||
binary_assert->left_value);
|
||||
if (!is_literal(stream->test, binary_assert->right_text,
|
||||
if (!is_literal(stream->test, binary_assert->text->right_text,
|
||||
binary_assert->right_value, stream->gfp))
|
||||
string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == %lld",
|
||||
binary_assert->right_text,
|
||||
binary_assert->text->right_text,
|
||||
binary_assert->right_value);
|
||||
kunit_assert_print_msg(assert, stream);
|
||||
kunit_assert_print_msg(message, stream);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(kunit_binary_assert_format);
|
||||
|
||||
void kunit_binary_ptr_assert_format(const struct kunit_assert *assert,
|
||||
const struct va_format *message,
|
||||
struct string_stream *stream)
|
||||
{
|
||||
struct kunit_binary_ptr_assert *binary_assert;
|
||||
@@ -147,19 +148,18 @@ void kunit_binary_ptr_assert_format(const struct kunit_assert *assert,
|
||||
binary_assert = container_of(assert, struct kunit_binary_ptr_assert,
|
||||
assert);
|
||||
|
||||
kunit_base_assert_format(assert, stream);
|
||||
string_stream_add(stream,
|
||||
KUNIT_SUBTEST_INDENT "Expected %s %s %s, but\n",
|
||||
binary_assert->left_text,
|
||||
binary_assert->operation,
|
||||
binary_assert->right_text);
|
||||
binary_assert->text->left_text,
|
||||
binary_assert->text->operation,
|
||||
binary_assert->text->right_text);
|
||||
string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == %px\n",
|
||||
binary_assert->left_text,
|
||||
binary_assert->text->left_text,
|
||||
binary_assert->left_value);
|
||||
string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == %px",
|
||||
binary_assert->right_text,
|
||||
binary_assert->text->right_text,
|
||||
binary_assert->right_value);
|
||||
kunit_assert_print_msg(assert, stream);
|
||||
kunit_assert_print_msg(message, stream);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(kunit_binary_ptr_assert_format);
|
||||
|
||||
@@ -180,6 +180,7 @@ static bool is_str_literal(const char *text, const char *value)
|
||||
}
|
||||
|
||||
void kunit_binary_str_assert_format(const struct kunit_assert *assert,
|
||||
const struct va_format *message,
|
||||
struct string_stream *stream)
|
||||
{
|
||||
struct kunit_binary_str_assert *binary_assert;
|
||||
@@ -187,20 +188,19 @@ void kunit_binary_str_assert_format(const struct kunit_assert *assert,
|
||||
binary_assert = container_of(assert, struct kunit_binary_str_assert,
|
||||
assert);
|
||||
|
||||
kunit_base_assert_format(assert, stream);
|
||||
string_stream_add(stream,
|
||||
KUNIT_SUBTEST_INDENT "Expected %s %s %s, but\n",
|
||||
binary_assert->left_text,
|
||||
binary_assert->operation,
|
||||
binary_assert->right_text);
|
||||
if (!is_str_literal(binary_assert->left_text, binary_assert->left_value))
|
||||
binary_assert->text->left_text,
|
||||
binary_assert->text->operation,
|
||||
binary_assert->text->right_text);
|
||||
if (!is_str_literal(binary_assert->text->left_text, binary_assert->left_value))
|
||||
string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == \"%s\"\n",
|
||||
binary_assert->left_text,
|
||||
binary_assert->text->left_text,
|
||||
binary_assert->left_value);
|
||||
if (!is_str_literal(binary_assert->right_text, binary_assert->right_value))
|
||||
if (!is_str_literal(binary_assert->text->right_text, binary_assert->right_value))
|
||||
string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == \"%s\"",
|
||||
binary_assert->right_text,
|
||||
binary_assert->text->right_text,
|
||||
binary_assert->right_value);
|
||||
kunit_assert_print_msg(assert, stream);
|
||||
kunit_assert_print_msg(message, stream);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(kunit_binary_str_assert_format);
|
||||
|
||||
@@ -69,6 +69,47 @@ static void example_mark_skipped_test(struct kunit *test)
|
||||
/* This line should run */
|
||||
kunit_info(test, "You should see this line.");
|
||||
}
|
||||
|
||||
/*
|
||||
* This test shows off all the types of KUNIT_EXPECT macros.
|
||||
*/
|
||||
static void example_all_expect_macros_test(struct kunit *test)
|
||||
{
|
||||
/* Boolean assertions */
|
||||
KUNIT_EXPECT_TRUE(test, true);
|
||||
KUNIT_EXPECT_FALSE(test, false);
|
||||
|
||||
/* Integer assertions */
|
||||
KUNIT_EXPECT_EQ(test, 1, 1); /* check == */
|
||||
KUNIT_EXPECT_GE(test, 1, 1); /* check >= */
|
||||
KUNIT_EXPECT_LE(test, 1, 1); /* check <= */
|
||||
KUNIT_EXPECT_NE(test, 1, 0); /* check != */
|
||||
KUNIT_EXPECT_GT(test, 1, 0); /* check > */
|
||||
KUNIT_EXPECT_LT(test, 0, 1); /* check < */
|
||||
|
||||
/* Pointer assertions */
|
||||
KUNIT_EXPECT_NOT_ERR_OR_NULL(test, test);
|
||||
KUNIT_EXPECT_PTR_EQ(test, NULL, NULL);
|
||||
KUNIT_EXPECT_PTR_NE(test, test, NULL);
|
||||
|
||||
/* String assertions */
|
||||
KUNIT_EXPECT_STREQ(test, "hi", "hi");
|
||||
KUNIT_EXPECT_STRNEQ(test, "hi", "bye");
|
||||
|
||||
/*
|
||||
* There are also ASSERT variants of all of the above that abort test
|
||||
* execution if they fail. Useful for memory allocations, etc.
|
||||
*/
|
||||
KUNIT_ASSERT_GT(test, sizeof(char), 0);
|
||||
|
||||
/*
|
||||
* There are also _MSG variants of all of the above that let you include
|
||||
* additional text on failure.
|
||||
*/
|
||||
KUNIT_EXPECT_GT_MSG(test, sizeof(int), 0, "Your ints are 0-bit?!");
|
||||
KUNIT_ASSERT_GT_MSG(test, sizeof(int), 0, "Your ints are 0-bit?!");
|
||||
}
|
||||
|
||||
/*
|
||||
* Here we make a list of all the test cases we want to add to the test suite
|
||||
* below.
|
||||
@@ -83,6 +124,7 @@ static struct kunit_case example_test_cases[] = {
|
||||
KUNIT_CASE(example_simple_test),
|
||||
KUNIT_CASE(example_skip_test),
|
||||
KUNIT_CASE(example_mark_skipped_test),
|
||||
KUNIT_CASE(example_all_expect_macros_test),
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user