Commit 4078aa68 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'ata-6.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/dlemoal/libata

Pull ata updates from Damien Le Moal:

 - Print the timeout value for internal command failures due to a
   timeout (from Tomas)

 - Improve parameter names in ata_dev_set_feature() to clarify this
   function use (from Niklas)

 - Improve the ahci driver low power mode setting initialization to
   allow more flexibility for the user (from Rafael)

 - Several patches to remove redundant variables in libata-core,
   libata-eh and the pata_macio driver and to fix typos in comments
   (from Jinpeng, Shaomin, Ye)

 - Some code simplifications and macro renaming (for clarity) in various
   functions of libata-core (from me)

 - Add a missing check for a potential failure of sata_scr_read() in
   sata_print_link_status() (from Li)

 - Cleanup of libata Kconfig PATA_PLATFORM and PATA_OF_PLATFORM options
   (from Lukas)

 - Cleanups of ata dt-bindings and improvements of libahci_platform,
   ahci and libahci code (from Serge)

 - New driver for Synopsys AHCI SATA controllers, based of the generic
   ahci code (from Serge). One compilation warning fix is added for this
   driver (from me)

 - Several fixes to macros used to discover a drive capabilities to be
   consistent with the ACS specifications (from Niklas)

 - A couple of simplifcations to some libata functions, removing
   unnecessary arguments (from Niklas)

 - An improvements to libata-eh code to avoid unnecessary link reset
   when revalidating a drive after a failed command. In practice, this
   extra, unneeded reset, reset does not cause any arm beyond slightly
   slowing down error recovery (from Niklas)

* tag 'ata-6.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/dlemoal/libata: (45 commits)
  ata: libata-eh: avoid needless hard reset when revalidating link
  ata: libata: drop superfluous ata_eh_analyze_tf() parameter
  ata: libata: drop superfluous ata_eh_request_sense() parameter
  ata: fix ata_id_has_dipm()
  ata: fix ata_id_has_ncq_autosense()
  ata: fix ata_id_has_devslp()
  ata: fix ata_id_sense_reporting_enabled() and ata_id_has_sense_reporting()
  ata: libata-eh: Remove the unneeded result variable
  ata: ahci_st: Enable compile test
  ata: ahci_st: Fix compilation warning
  MAINTAINERS: Add maintainers for DWC AHCI SATA driver
  ata: ahci-dwc: Add Baikal-T1 AHCI SATA interface support
  ata: ahci-dwc: Add platform-specific quirks support
  dt-bindings: ata: ahci: Add Baikal-T1 AHCI SATA controller DT schema
  ata: ahci: Add DWC AHCI SATA controller support
  ata: libahci_platform: Add function returning a clock-handle by id
  dt-bindings: ata: ahci: Add DWC AHCI SATA controller DT schema
  ata: ahci: Introduce firmware-specific caps initialization
  ata: ahci: Convert __ahci_port_base to accepting hpriv as arguments
  ata: libahci: Don't read AHCI version twice in the save-config method
  ...
parents 9d84bb40 71d7b6e5
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/ata/ahci-common.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Common Properties for Serial ATA AHCI controllers
maintainers:
- Hans de Goede <hdegoede@redhat.com>
- Damien Le Moal <damien.lemoal@opensource.wdc.com>
description:
This document defines device tree properties for a common AHCI SATA
controller implementation. It's hardware interface is supposed to
conform to the technical standard defined by Intel (see Serial ATA
Advanced Host Controller Interface specification for details). The
document doesn't constitute a DT-node binding by itself but merely
defines a set of common properties for the AHCI-compatible devices.
select: false
allOf:
- $ref: sata-common.yaml#
properties:
reg:
description:
Generic AHCI registers space conforming to the Serial ATA AHCI
specification.
reg-names:
description: CSR space IDs
contains:
const: ahci
interrupts:
description:
Generic AHCI state change interrupt. Can be implemented either as a
single line attached to the controller or as a set of the signals
indicating the particular port events.
minItems: 1
maxItems: 32
ahci-supply:
description: Power regulator for AHCI controller
target-supply:
description: Power regulator for SATA target device
phy-supply:
description: Power regulator for SATA PHY
phys:
description: Reference to the SATA PHY node
maxItems: 1
phy-names:
const: sata-phy
hba-cap:
$ref: '/schemas/types.yaml#/definitions/uint32'
description:
Bitfield of the HBA generic platform capabilities like Staggered
Spin-up or Mechanical Presence Switch support. It can be used to
appropriately initialize the HWinit fields of the HBA CAP register
in case if the system firmware hasn't done it.
ports-implemented:
$ref: '/schemas/types.yaml#/definitions/uint32'
description:
Mask that indicates which ports the HBA supports. Useful if PI is not
programmed by the BIOS, which is true for some embedded SoC's.
patternProperties:
"^sata-port@[0-9a-f]+$":
$ref: '#/$defs/ahci-port'
description:
It is optionally possible to describe the ports as sub-nodes so
to enable each port independently when dealing with multiple PHYs.
required:
- reg
- interrupts
additionalProperties: true
$defs:
ahci-port:
$ref: /schemas/ata/sata-common.yaml#/$defs/sata-port
properties:
reg:
description:
AHCI SATA port identifier. By design AHCI controller can't have
more than 32 ports due to the CAP.NP fields and PI register size
constraints.
minimum: 0
maximum: 31
phys:
description: Individual AHCI SATA port PHY
maxItems: 1
phy-names:
description: AHCI SATA port PHY ID
const: sata-phy
target-supply:
description: Power regulator for SATA port target device
hba-port-cap:
$ref: '/schemas/types.yaml#/definitions/uint32'
description:
Bitfield of the HBA port-specific platform capabilities like Hot
plugging, eSATA, FIS-based Switching, etc (see AHCI specification
for details). It can be used to initialize the HWinit fields of
the PxCMD register in case if the system firmware hasn't done it.
required:
- reg
...
...@@ -30,14 +30,11 @@ select: ...@@ -30,14 +30,11 @@ select:
- marvell,armada-3700-ahci - marvell,armada-3700-ahci
- marvell,armada-8k-ahci - marvell,armada-8k-ahci
- marvell,berlin2q-ahci - marvell,berlin2q-ahci
- snps,dwc-ahci
- snps,spear-ahci
required: required:
- compatible - compatible
allOf: allOf:
- $ref: "sata-common.yaml#" - $ref: "ahci-common.yaml#"
properties: properties:
compatible: compatible:
...@@ -49,17 +46,11 @@ properties: ...@@ -49,17 +46,11 @@ properties:
- marvell,berlin2-ahci - marvell,berlin2-ahci
- marvell,berlin2q-ahci - marvell,berlin2q-ahci
- const: generic-ahci - const: generic-ahci
- items:
- enum:
- rockchip,rk3568-dwc-ahci
- const: snps,dwc-ahci
- enum: - enum:
- cavium,octeon-7130-ahci - cavium,octeon-7130-ahci
- hisilicon,hisi-ahci - hisilicon,hisi-ahci
- ibm,476gtr-ahci - ibm,476gtr-ahci
- marvell,armada-3700-ahci - marvell,armada-3700-ahci
- snps,dwc-ahci
- snps,spear-ahci
reg: reg:
minItems: 1 minItems: 1
...@@ -69,92 +60,37 @@ properties: ...@@ -69,92 +60,37 @@ properties:
maxItems: 1 maxItems: 1
clocks: clocks:
description:
Clock IDs array as required by the controller.
minItems: 1 minItems: 1
maxItems: 3 maxItems: 3
clock-names: clock-names:
description:
Names of clocks corresponding to IDs in the clock property.
minItems: 1 minItems: 1
maxItems: 3 maxItems: 3
interrupts: interrupts:
maxItems: 1 maxItems: 1
ahci-supply:
description:
regulator for AHCI controller
dma-coherent: true
phy-supply:
description:
regulator for PHY power
phys:
description:
List of all PHYs on this controller
maxItems: 1
phy-names:
description:
Name specifier for the PHYs
maxItems: 1
ports-implemented:
$ref: '/schemas/types.yaml#/definitions/uint32'
description: |
Mask that indicates which ports that the HBA supports
are available for software to use. Useful if PORTS_IMPL
is not programmed by the BIOS, which is true with
some embedded SoCs.
maximum: 0x1f
power-domains: power-domains:
maxItems: 1 maxItems: 1
resets: resets:
maxItems: 1 maxItems: 1
target-supply:
description:
regulator for SATA target power
required:
- compatible
- reg
- interrupts
patternProperties: patternProperties:
"^sata-port@[0-9a-f]+$": "^sata-port@[0-9a-f]+$":
type: object $ref: /schemas/ata/ahci-common.yaml#/$defs/ahci-port
additionalProperties: false
description:
Subnode with configuration of the Ports.
properties:
reg:
maxItems: 1
phys:
maxItems: 1
phy-names:
maxItems: 1
target-supply:
description:
regulator for SATA target power
required:
- reg
anyOf: anyOf:
- required: [ phys ] - required: [ phys ]
- required: [ target-supply ] - required: [ target-supply ]
unevaluatedProperties: false
required:
- compatible
- reg
- interrupts
unevaluatedProperties: false unevaluatedProperties: false
examples: examples:
...@@ -167,6 +103,8 @@ examples: ...@@ -167,6 +103,8 @@ examples:
- | - |
#include <dt-bindings/interrupt-controller/arm-gic.h> #include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/clock/berlin2q.h> #include <dt-bindings/clock/berlin2q.h>
#include <dt-bindings/ata/ahci.h>
sata@f7e90000 { sata@f7e90000 {
compatible = "marvell,berlin2q-ahci", "generic-ahci"; compatible = "marvell,berlin2q-ahci", "generic-ahci";
reg = <0xf7e90000 0x1000>; reg = <0xf7e90000 0x1000>;
...@@ -175,15 +113,23 @@ examples: ...@@ -175,15 +113,23 @@ examples:
#address-cells = <1>; #address-cells = <1>;
#size-cells = <0>; #size-cells = <0>;
hba-cap = <HBA_SMPS>;
sata0: sata-port@0 { sata0: sata-port@0 {
reg = <0>; reg = <0>;
phys = <&sata_phy 0>; phys = <&sata_phy 0>;
target-supply = <&reg_sata0>; target-supply = <&reg_sata0>;
hba-port-cap = <(HBA_PORT_FBSCP | HBA_PORT_ESP)>;
}; };
sata1: sata-port@1 { sata1: sata-port@1 {
reg = <1>; reg = <1>;
phys = <&sata_phy 1>; phys = <&sata_phy 1>;
target-supply = <&reg_sata1>; target-supply = <&reg_sata1>;
hba-port-cap = <(HBA_PORT_HPCP | HBA_PORT_MPSP | HBA_PORT_FBSCP)>;
}; };
}; };
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/ata/baikal,bt1-ahci.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Baikal-T1 SoC AHCI SATA controller
maintainers:
- Serge Semin <fancer.lancer@gmail.com>
description:
AHCI SATA controller embedded into the Baikal-T1 SoC is based on the
DWC AHCI SATA v4.10a IP-core.
allOf:
- $ref: snps,dwc-ahci-common.yaml#
properties:
compatible:
const: baikal,bt1-ahci
clocks:
items:
- description: Peripheral APB bus clock
- description: Application AXI BIU clock
- description: SATA Ports reference clock
clock-names:
items:
- const: pclk
- const: aclk
- const: ref
resets:
items:
- description: Application AXI BIU domain reset
- description: SATA Ports clock domain reset
reset-names:
items:
- const: arst
- const: ref
ports-implemented:
maximum: 0x3
patternProperties:
"^sata-port@[0-1]$":
$ref: /schemas/ata/snps,dwc-ahci-common.yaml#/$defs/dwc-ahci-port
properties:
reg:
minimum: 0
maximum: 1
snps,tx-ts-max:
$ref: /schemas/types.yaml#/definitions/uint32
description:
Due to having AXI3 bus interface utilized the maximum Tx DMA
transaction size can't exceed 16 beats (AxLEN[3:0]).
enum: [ 1, 2, 4, 8, 16 ]
snps,rx-ts-max:
$ref: /schemas/types.yaml#/definitions/uint32
description:
Due to having AXI3 bus interface utilized the maximum Rx DMA
transaction size can't exceed 16 beats (AxLEN[3:0]).
enum: [ 1, 2, 4, 8, 16 ]
unevaluatedProperties: false
required:
- compatible
- reg
- interrupts
- clocks
- clock-names
- resets
unevaluatedProperties: false
examples:
- |
sata@1f050000 {
compatible = "baikal,bt1-ahci";
reg = <0x1f050000 0x2000>;
#address-cells = <1>;
#size-cells = <0>;
interrupts = <0 64 4>;
clocks = <&ccu_sys 1>, <&ccu_axi 2>, <&sata_ref_clk>;
clock-names = "pclk", "aclk", "ref";
resets = <&ccu_axi 2>, <&ccu_sys 0>;
reset-names = "arst", "ref";
ports-implemented = <0x3>;
sata-port@0 {
reg = <0>;
snps,tx-ts-max = <4>;
snps,rx-ts-max = <4>;
};
sata-port@1 {
reg = <1>;
snps,tx-ts-max = <4>;
snps,rx-ts-max = <4>;
};
};
...
...@@ -14,7 +14,7 @@ maintainers: ...@@ -14,7 +14,7 @@ maintainers:
- Florian Fainelli <f.fainelli@gmail.com> - Florian Fainelli <f.fainelli@gmail.com>
allOf: allOf:
- $ref: sata-common.yaml# - $ref: ahci-common.yaml#
properties: properties:
compatible: compatible:
...@@ -41,8 +41,6 @@ properties: ...@@ -41,8 +41,6 @@ properties:
interrupts: interrupts:
maxItems: 1 maxItems: 1
dma-coherent: true
if: if:
properties: properties:
compatible: compatible:
......
...@@ -31,22 +31,27 @@ properties: ...@@ -31,22 +31,27 @@ properties:
"#size-cells": "#size-cells":
const: 0 const: 0
dma-coherent: true
patternProperties: patternProperties:
"^sata-port@[0-9a-e]$": "^sata-port@[0-9a-e]$":
$ref: '#/$defs/sata-port'
description: | description: |
DT nodes for ports connected on the SATA host. The SATA port DT nodes for ports connected on the SATA host. The SATA port
nodes will be named "sata-port". nodes will be named "sata-port".
additionalProperties: true
$defs:
sata-port:
type: object type: object
properties: properties:
reg: reg:
minimum: 0 minimum: 0
maximum: 14
description: description:
The ID number of the drive port SATA can potentially use a port The ID number of the SATA port. Aside with being directly used,
multiplier making it possible to connect up to 15 disks to a single each port can have a Port Multiplier attached thus allowing to
SATA port. access more than one drive by means of a single SATA port.
additionalProperties: true
... ...
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/ata/snps,dwc-ahci-common.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Synopsys DWC AHCI SATA controller properties
maintainers:
- Serge Semin <fancer.lancer@gmail.com>
description:
This document defines device tree schema for the generic Synopsys DWC
AHCI controller properties.
select: false
allOf:
- $ref: ahci-common.yaml#
properties:
reg:
maxItems: 1
interrupts:
maxItems: 1
clocks:
description:
Basic DWC AHCI SATA clock sources like application AXI/AHB BIU clock,
PM-alive clock, RxOOB detection clock, embedded PHYs reference (Rx/Tx)
clock, etc.
minItems: 1
maxItems: 4
clock-names:
minItems: 1
maxItems: 4
items:
oneOf:
- description: Application APB/AHB/AXI BIU clock
enum:
- pclk
- aclk
- hclk
- sata
- description: Power Module keep-alive clock
const: pmalive
- description: RxOOB detection clock
const: rxoob
- description: SATA Ports reference clock
const: ref
resets:
description:
At least basic application and reference clock domains resets are
normally supported by the DWC AHCI SATA controller.
minItems: 1
maxItems: 4
reset-names:
minItems: 1
maxItems: 4
items:
oneOf:
- description: Application AHB/AXI BIU clock domain reset control
enum:
- arst
- hrst
- description: Power Module keep-alive clock domain reset control
const: pmalive
- description: RxOOB detection clock domain reset control
const: rxoob
- description: Reference clock domain reset control
const: ref
patternProperties:
"^sata-port@[0-9a-e]$":
$ref: '#/$defs/dwc-ahci-port'
additionalProperties: true
$defs:
dwc-ahci-port:
$ref: /schemas/ata/ahci-common.yaml#/$defs/ahci-port
properties:
reg:
minimum: 0
maximum: 7
snps,tx-ts-max:
$ref: /schemas/types.yaml#/definitions/uint32
description: Maximal size of Tx DMA transactions in FIFO words
enum: [ 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024 ]
snps,rx-ts-max:
$ref: /schemas/types.yaml#/definitions/uint32
description: Maximal size of Rx DMA transactions in FIFO words
enum: [ 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024 ]
...
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/ata/snps,dwc-ahci.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Synopsys DWC AHCI SATA controller
maintainers:
- Serge Semin <fancer.lancer@gmail.com>
description:
This document defines device tree bindings for the generic Synopsys DWC
implementation of the AHCI SATA controller.
allOf:
- $ref: snps,dwc-ahci-common.yaml#
properties:
compatible:
oneOf:
- description: Synopsys AHCI SATA-compatible devices
const: snps,dwc-ahci
- description: SPEAr1340 AHCI SATA device
const: snps,spear-ahci
- description: Rockhip RK3568 AHCI controller
items:
- const: rockchip,rk3568-dwc-ahci
- const: snps,dwc-ahci
patternProperties:
"^sata-port@[0-9a-e]$":
$ref: /schemas/ata/snps,dwc-ahci-common.yaml#/$defs/dwc-ahci-port
unevaluatedProperties: false
required:
- compatible
- reg
- interrupts
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/ata/ahci.h>
sata@122f0000 {
compatible = "snps,dwc-ahci";
reg = <0x122F0000 0x1ff>;
#address-cells = <1>;
#size-cells = <0>;
interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock1>, <&clock2>;
clock-names = "aclk", "ref";
phys = <&sata_phy>;
phy-names = "sata-phy";
ports-implemented = <0x1>;
sata-port@0 {
reg = <0>;
hba-port-cap = <HBA_PORT_FBSCP>;
snps,tx-ts-max = <512>;
snps,rx-ts-max = <512>;
};
};
...
...@@ -11584,6 +11584,15 @@ F: drivers/ata/ahci_platform.c ...@@ -11584,6 +11584,15 @@ F: drivers/ata/ahci_platform.c
F: drivers/ata/libahci_platform.c F: drivers/ata/libahci_platform.c
F: include/linux/ahci_platform.h F: include/linux/ahci_platform.h
LIBATA SATA AHCI SYNOPSYS DWC CONTROLLER DRIVER
M: Serge Semin <fancer.lancer@gmail.com>
L: linux-ide@vger.kernel.org
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/dlemoal/libata.git
F: Documentation/devicetree/bindings/ata/baikal,bt1-ahci.yaml
F: Documentation/devicetree/bindings/ata/snps,dwc-ahci.yaml
F: drivers/ata/ahci_dwc.c
LIBATA SATA PROMISE TX2/TX4 CONTROLLER DRIVER LIBATA SATA PROMISE TX2/TX4 CONTROLLER DRIVER
M: Mikael Pettersson <mikpelinux@gmail.com> M: Mikael Pettersson <mikpelinux@gmail.com>
L: linux-ide@vger.kernel.org L: linux-ide@vger.kernel.org
......
...@@ -256,7 +256,6 @@ menuconfig ARCH_VEXPRESS ...@@ -256,7 +256,6 @@ menuconfig ARCH_VEXPRESS
select GPIOLIB select GPIOLIB
select HAVE_ARM_SCU if SMP select HAVE_ARM_SCU if SMP
select HAVE_ARM_TWD if SMP select HAVE_ARM_TWD if SMP
select HAVE_PATA_PLATFORM
select CLK_ICST select CLK_ICST
select NO_IOPORT_MAP select NO_IOPORT_MAP
select PLAT_VERSATILE select PLAT_VERSATILE
......
...@@ -195,7 +195,6 @@ config ARM64 ...@@ -195,7 +195,6 @@ config ARM64
select HAVE_IRQ_TIME_ACCOUNTING select HAVE_IRQ_TIME_ACCOUNTING
select HAVE_KVM select HAVE_KVM
select HAVE_NMI select HAVE_NMI
select HAVE_PATA_PLATFORM
select HAVE_PERF_EVENTS select HAVE_PERF_EVENTS
select HAVE_PERF_REGS select HAVE_PERF_REGS
select HAVE_PERF_USER_STACK_DUMP select HAVE_PERF_USER_STACK_DUMP
......
...@@ -176,9 +176,19 @@ config AHCI_DM816 ...@@ -176,9 +176,19 @@ config AHCI_DM816
If unsure, say N. If unsure, say N.
config AHCI_DWC
tristate "Synopsys DWC AHCI SATA support"
select SATA_HOST
select MFD_SYSCON if (MIPS_BAIKAL_T1 || COMPILE_TEST)
help
This option enables support for the Synopsys DWC AHCI SATA
controller implementation.
If unsure, say N.
config AHCI_ST config AHCI_ST
tristate "ST AHCI SATA support" tristate "ST AHCI SATA support"
depends on ARCH_STI depends on ARCH_STI || COMPILE_TEST
select SATA_HOST select SATA_HOST
help help
This option enables support for ST AHCI SATA controller. This option enables support for ST AHCI SATA controller.
...@@ -1102,8 +1112,7 @@ config PATA_PCMCIA ...@@ -1102,8 +1112,7 @@ config PATA_PCMCIA
If unsure, say N. If unsure, say N.
config PATA_PLATFORM config PATA_PLATFORM
tristate "Generic platform device PATA support" tristate "Generic platform device PATA support" if HAVE_PATA_PLATFORM
depends on EXPERT || PPC || HAVE_PATA_PLATFORM
help help
This option enables support for generic directly connected ATA This option enables support for generic directly connected ATA
devices commonly found on embedded systems. devices commonly found on embedded systems.
...@@ -1112,7 +1121,8 @@ config PATA_PLATFORM ...@@ -1112,7 +1121,8 @@ config PATA_PLATFORM
config PATA_OF_PLATFORM config PATA_OF_PLATFORM
tristate "OpenFirmware platform device PATA support" tristate "OpenFirmware platform device PATA support"
depends on PATA_PLATFORM && OF depends on OF
select PATA_PLATFORM
help help
This option enables support for generic directly connected ATA This option enables support for generic directly connected ATA
devices commonly found on embedded systems with OpenFirmware devices commonly found on embedded systems with OpenFirmware
......
...@@ -17,6 +17,7 @@ obj-$(CONFIG_AHCI_BRCM) += ahci_brcm.o libahci.o libahci_platform.o ...@@ -17,6 +17,7 @@ obj-$(CONFIG_AHCI_BRCM) += ahci_brcm.o libahci.o libahci_platform.o
obj-$(CONFIG_AHCI_CEVA) += ahci_ceva.o libahci.o libahci_platform.o obj-$(CONFIG_AHCI_CEVA) += ahci_ceva.o libahci.o libahci_platform.o
obj-$(CONFIG_AHCI_DA850) += ahci_da850.o libahci.o libahci_platform.o obj-$(CONFIG_AHCI_DA850) += ahci_da850.o libahci.o libahci_platform.o
obj-$(CONFIG_AHCI_DM816) += ahci_dm816.o libahci.o libahci_platform.o obj-$(CONFIG_AHCI_DM816) += ahci_dm816.o libahci.o libahci_platform.o
obj-$(CONFIG_AHCI_DWC) += ahci_dwc.o libahci.o libahci_platform.o
obj-$(CONFIG_AHCI_IMX) += ahci_imx.o libahci.o libahci_platform.o obj-$(CONFIG_AHCI_IMX) += ahci_imx.o libahci.o libahci_platform.o
obj-$(CONFIG_AHCI_MTK) += ahci_mtk.o libahci.o libahci_platform.o obj-$(CONFIG_AHCI_MTK) += ahci_mtk.o libahci.o libahci_platform.o
obj-$(CONFIG_AHCI_MVEBU) += ahci_mvebu.o libahci.o libahci_platform.o obj-$(CONFIG_AHCI_MVEBU) += ahci_mvebu.o libahci.o libahci_platform.o
......
...@@ -657,7 +657,7 @@ static void ahci_pci_save_initial_config(struct pci_dev *pdev, ...@@ -657,7 +657,7 @@ static void ahci_pci_save_initial_config(struct pci_dev *pdev,
{ {
if (pdev->vendor == PCI_VENDOR_ID_JMICRON && pdev->device == 0x2361) { if (pdev->vendor == PCI_VENDOR_ID_JMICRON && pdev->device == 0x2361) {
dev_info(&pdev->dev, "JMB361 has only one port\n"); dev_info(&pdev->dev, "JMB361 has only one port\n");
hpriv->force_port_map = 1; hpriv->saved_port_map = 1;
} }
/* /*
...@@ -690,7 +690,7 @@ static void ahci_pci_init_controller(struct ata_host *host) ...@@ -690,7 +690,7 @@ static void ahci_pci_init_controller(struct ata_host *host)
mv = 2; mv = 2;
else else
mv = 4; mv = 4;
port_mmio = __ahci_port_base(host, mv); port_mmio = __ahci_port_base(hpriv, mv);
writel(0, port_mmio + PORT_IRQ_MASK); writel(0, port_mmio + PORT_IRQ_MASK);
...@@ -1609,15 +1609,12 @@ static void ahci_update_initial_lpm_policy(struct ata_port *ap, ...@@ -1609,15 +1609,12 @@ static void ahci_update_initial_lpm_policy(struct ata_port *ap,
goto update_policy; goto update_policy;
} }
#ifdef CONFIG_ACPI if (policy > ATA_LPM_MED_POWER && pm_suspend_default_s2idle()) {
if (policy > ATA_LPM_MED_POWER &&
(acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0)) {
if (hpriv->cap & HOST_CAP_PART) if (hpriv->cap & HOST_CAP_PART)
policy = ATA_LPM_MIN_POWER_WITH_PARTIAL; policy = ATA_LPM_MIN_POWER_WITH_PARTIAL;
else if (hpriv->cap & HOST_CAP_SSC) else if (hpriv->cap & HOST_CAP_SSC)
policy = ATA_LPM_MIN_POWER; policy = ATA_LPM_MIN_POWER;
} }
#endif
update_policy: update_policy:
if (policy >= ATA_LPM_UNKNOWN && policy <= ATA_LPM_MIN_POWER) if (policy >= ATA_LPM_UNKNOWN && policy <= ATA_LPM_MIN_POWER)
......
...@@ -38,7 +38,6 @@ ...@@ -38,7 +38,6 @@
enum { enum {
AHCI_MAX_PORTS = 32, AHCI_MAX_PORTS = 32,
AHCI_MAX_CLKS = 5,
AHCI_MAX_SG = 168, /* hardware max is 64K */ AHCI_MAX_SG = 168, /* hardware max is 64K */
AHCI_DMA_BOUNDARY = 0xffffffff, AHCI_DMA_BOUNDARY = 0xffffffff,
AHCI_MAX_CMDS = 32, AHCI_MAX_CMDS = 32,
...@@ -139,7 +138,7 @@ enum { ...@@ -139,7 +138,7 @@ enum {
PORT_IRQ_BAD_PMP = (1 << 23), /* incorrect port multiplier */ PORT_IRQ_BAD_PMP = (1 << 23), /* incorrect port multiplier */
PORT_IRQ_PHYRDY = (1 << 22), /* PhyRdy changed */ PORT_IRQ_PHYRDY = (1 << 22), /* PhyRdy changed */
PORT_IRQ_DEV_ILCK = (1 << 7), /* device interlock */ PORT_IRQ_DMPS = (1 << 7), /* mechanical presence status */
PORT_IRQ_CONNECT = (1 << 6), /* port connect change status */ PORT_IRQ_CONNECT = (1 << 6), /* port connect change status */
PORT_IRQ_SG_DONE = (1 << 5), /* descriptor processed */ PORT_IRQ_SG_DONE = (1 << 5), /* descriptor processed */
PORT_IRQ_UNK_FIS = (1 << 4), /* unknown FIS rx'd */ PORT_IRQ_UNK_FIS = (1 << 4), /* unknown FIS rx'd */
...@@ -167,6 +166,8 @@ enum { ...@@ -167,6 +166,8 @@ enum {
PORT_CMD_ATAPI = (1 << 24), /* Device is ATAPI */ PORT_CMD_ATAPI = (1 << 24), /* Device is ATAPI */
PORT_CMD_FBSCP = (1 << 22), /* FBS Capable Port */ PORT_CMD_FBSCP = (1 << 22), /* FBS Capable Port */
PORT_CMD_ESP = (1 << 21), /* External Sata Port */ PORT_CMD_ESP = (1 << 21), /* External Sata Port */
PORT_CMD_CPD = (1 << 20), /* Cold Presence Detection */
PORT_CMD_MPSP = (1 << 19), /* Mechanical Presence Switch */
PORT_CMD_HPCP = (1 << 18), /* HotPlug Capable Port */ PORT_CMD_HPCP = (1 << 18), /* HotPlug Capable Port */
PORT_CMD_PMP = (1 << 17), /* PMP attached */ PORT_CMD_PMP = (1 << 17), /* PMP attached */
PORT_CMD_LIST_ON = (1 << 15), /* cmd list DMA engine running */ PORT_CMD_LIST_ON = (1 << 15), /* cmd list DMA engine running */
...@@ -182,6 +183,10 @@ enum { ...@@ -182,6 +183,10 @@ enum {
PORT_CMD_ICC_PARTIAL = (0x2 << 28), /* Put i/f in partial state */ PORT_CMD_ICC_PARTIAL = (0x2 << 28), /* Put i/f in partial state */
PORT_CMD_ICC_SLUMBER = (0x6 << 28), /* Put i/f in slumber state */ PORT_CMD_ICC_SLUMBER = (0x6 << 28), /* Put i/f in slumber state */
/* PORT_CMD capabilities mask */
PORT_CMD_CAP = PORT_CMD_HPCP | PORT_CMD_MPSP |
PORT_CMD_CPD | PORT_CMD_ESP | PORT_CMD_FBSCP,
/* PORT_FBS bits */ /* PORT_FBS bits */
PORT_FBS_DWE_OFFSET = 16, /* FBS device with error offset */ PORT_FBS_DWE_OFFSET = 16, /* FBS device with error offset */
PORT_FBS_ADO_OFFSET = 12, /* FBS active dev optimization offset */ PORT_FBS_ADO_OFFSET = 12, /* FBS active dev optimization offset */
...@@ -323,7 +328,6 @@ struct ahci_port_priv { ...@@ -323,7 +328,6 @@ struct ahci_port_priv {
struct ahci_host_priv { struct ahci_host_priv {
/* Input fields */ /* Input fields */
unsigned int flags; /* AHCI_HFLAG_* */ unsigned int flags; /* AHCI_HFLAG_* */
u32 force_port_map; /* force port map */
u32 mask_port_map; /* mask out particular bits */ u32 mask_port_map; /* mask out particular bits */
void __iomem * mmio; /* bus-independent mem map */ void __iomem * mmio; /* bus-independent mem map */
...@@ -334,12 +338,15 @@ struct ahci_host_priv { ...@@ -334,12 +338,15 @@ struct ahci_host_priv {
u32 saved_cap; /* saved initial cap */ u32 saved_cap; /* saved initial cap */
u32 saved_cap2; /* saved initial cap2 */ u32 saved_cap2; /* saved initial cap2 */
u32 saved_port_map; /* saved initial port_map */ u32 saved_port_map; /* saved initial port_map */
u32 saved_port_cap[AHCI_MAX_PORTS]; /* saved port_cap */
u32 em_loc; /* enclosure management location */ u32 em_loc; /* enclosure management location */
u32 em_buf_sz; /* EM buffer size in byte */ u32 em_buf_sz; /* EM buffer size in byte */
u32 em_msg_type; /* EM message type */ u32 em_msg_type; /* EM message type */
u32 remapped_nvme; /* NVMe remapped device count */ u32 remapped_nvme; /* NVMe remapped device count */
bool got_runtime_pm; /* Did we do pm_runtime_get? */ bool got_runtime_pm; /* Did we do pm_runtime_get? */
struct clk *clks[AHCI_MAX_CLKS]; /* Optional */ unsigned int n_clks;
struct clk_bulk_data *clks; /* Optional */
unsigned int f_rsts;
struct reset_control *rsts; /* Optional */ struct reset_control *rsts; /* Optional */
struct regulator **target_pwrs; /* Optional */ struct regulator **target_pwrs; /* Optional */
struct regulator *ahci_regulator;/* Optional */ struct regulator *ahci_regulator;/* Optional */
...@@ -426,10 +433,9 @@ int ahci_host_activate(struct ata_host *host, struct scsi_host_template *sht); ...@@ -426,10 +433,9 @@ int ahci_host_activate(struct ata_host *host, struct scsi_host_template *sht);
void ahci_error_handler(struct ata_port *ap); void ahci_error_handler(struct ata_port *ap);
u32 ahci_handle_port_intr(struct ata_host *host, u32 irq_masked); u32 ahci_handle_port_intr(struct ata_host *host, u32 irq_masked);
static inline void __iomem *__ahci_port_base(struct ata_host *host, static inline void __iomem *__ahci_port_base(struct ahci_host_priv *hpriv,
unsigned int port_no) unsigned int port_no)
{ {
struct ahci_host_priv *hpriv = host->private_data;
void __iomem *mmio = hpriv->mmio; void __iomem *mmio = hpriv->mmio;
return mmio + 0x100 + (port_no * 0x80); return mmio + 0x100 + (port_no * 0x80);
...@@ -437,7 +443,9 @@ static inline void __iomem *__ahci_port_base(struct ata_host *host, ...@@ -437,7 +443,9 @@ static inline void __iomem *__ahci_port_base(struct ata_host *host,
static inline void __iomem *ahci_port_base(struct ata_port *ap) static inline void __iomem *ahci_port_base(struct ata_port *ap)
{ {
return __ahci_port_base(ap->host, ap->port_no); struct ahci_host_priv *hpriv = ap->host->private_data;
return __ahci_port_base(hpriv, ap->port_no);
} }
static inline int ahci_nr_ports(u32 cap) static inline int ahci_nr_ports(u32 cap)
......
...@@ -163,7 +163,6 @@ static int ahci_da850_probe(struct platform_device *pdev) ...@@ -163,7 +163,6 @@ static int ahci_da850_probe(struct platform_device *pdev)
struct ahci_host_priv *hpriv; struct ahci_host_priv *hpriv;
void __iomem *pwrdn_reg; void __iomem *pwrdn_reg;
struct resource *res; struct resource *res;
struct clk *clk;
u32 mpy; u32 mpy;
int rc; int rc;
...@@ -172,36 +171,28 @@ static int ahci_da850_probe(struct platform_device *pdev) ...@@ -172,36 +171,28 @@ static int ahci_da850_probe(struct platform_device *pdev)
return PTR_ERR(hpriv); return PTR_ERR(hpriv);
/* /*
* Internally ahci_platform_get_resources() calls clk_get(dev, NULL) * Internally ahci_platform_get_resources() calls the bulk clocks
* when trying to obtain the functional clock. This SATA controller * get method or falls back to using a single clk_get_optional().
* uses two clocks for which we specify two connection ids. If we don't * This AHCI SATA controller uses two clocks: functional clock
* have the functional clock at this point - call clk_get() again with * with "fck" connection id and external reference clock with
* con_id = "fck". * "refclk" id. If we haven't got all of them re-try the clocks
* getting procedure with the explicitly specified ids.
*/ */
if (!hpriv->clks[0]) { if (hpriv->n_clks < 2) {
clk = clk_get(dev, "fck"); hpriv->clks = devm_kcalloc(dev, 2, sizeof(*hpriv->clks), GFP_KERNEL);
if (IS_ERR(clk)) if (!hpriv->clks)
return PTR_ERR(clk); return -ENOMEM;
hpriv->clks[0] = clk; hpriv->clks[0].id = "fck";
} hpriv->clks[1].id = "refclk";
hpriv->n_clks = 2;
/*
* The second clock used by ahci-da850 is the external REFCLK. If we rc = devm_clk_bulk_get(dev, hpriv->n_clks, hpriv->clks);
* didn't get it from ahci_platform_get_resources(), let's try to if (rc)
* specify the con_id in clk_get(). return rc;
*/
if (!hpriv->clks[1]) {
clk = clk_get(dev, "refclk");
if (IS_ERR(clk)) {
dev_err(dev, "unable to obtain the reference clock");
return -ENODEV;
}
hpriv->clks[1] = clk;
} }
mpy = ahci_da850_calculate_mpy(clk_get_rate(hpriv->clks[1])); mpy = ahci_da850_calculate_mpy(clk_get_rate(hpriv->clks[1].clk));
if (mpy == 0) { if (mpy == 0) {
dev_err(dev, "invalid REFCLK multiplier value: 0x%x", mpy); dev_err(dev, "invalid REFCLK multiplier value: 0x%x", mpy);
return -EINVAL; return -EINVAL;
......
...@@ -69,12 +69,12 @@ static int ahci_dm816_phy_init(struct ahci_host_priv *hpriv, struct device *dev) ...@@ -69,12 +69,12 @@ static int ahci_dm816_phy_init(struct ahci_host_priv *hpriv, struct device *dev)
* keep-alive clock and the external reference clock. We need the * keep-alive clock and the external reference clock. We need the
* rate of the latter to calculate the correct value of MPY bits. * rate of the latter to calculate the correct value of MPY bits.
*/ */
if (!hpriv->clks[1]) { if (hpriv->n_clks < 2) {
dev_err(dev, "reference clock not supplied\n"); dev_err(dev, "reference clock not supplied\n");
return -EINVAL; return -EINVAL;
} }
refclk_rate = clk_get_rate(hpriv->clks[1]); refclk_rate = clk_get_rate(hpriv->clks[1].clk);
if ((refclk_rate % 100) != 0) { if ((refclk_rate % 100) != 0) {
dev_err(dev, "reference clock rate must be divisible by 100\n"); dev_err(dev, "reference clock rate must be divisible by 100\n");
return -EINVAL; return -EINVAL;
......
This diff is collapsed.
...@@ -118,8 +118,6 @@ static int mtk_ahci_parse_property(struct ahci_host_priv *hpriv, ...@@ -118,8 +118,6 @@ static int mtk_ahci_parse_property(struct ahci_host_priv *hpriv,
SYS_CFG_SATA_EN); SYS_CFG_SATA_EN);
} }
of_property_read_u32(np, "ports-implemented", &hpriv->force_port_map);
return 0; return 0;
} }
......
...@@ -56,9 +56,6 @@ static int ahci_probe(struct platform_device *pdev) ...@@ -56,9 +56,6 @@ static int ahci_probe(struct platform_device *pdev)
if (rc) if (rc)
return rc; return rc;
of_property_read_u32(dev->of_node,
"ports-implemented", &hpriv->force_port_map);
if (of_device_is_compatible(dev->of_node, "hisilicon,hisi-ahci")) if (of_device_is_compatible(dev->of_node, "hisilicon,hisi-ahci"))
hpriv->flags |= AHCI_HFLAG_NO_FBS | AHCI_HFLAG_NO_NCQ; hpriv->flags |= AHCI_HFLAG_NO_FBS | AHCI_HFLAG_NO_NCQ;
...@@ -83,9 +80,7 @@ static SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_platform_suspend, ...@@ -83,9 +80,7 @@ static SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_platform_suspend,
static const struct of_device_id ahci_of_match[] = { static const struct of_device_id ahci_of_match[] = {
{ .compatible = "generic-ahci", }, { .compatible = "generic-ahci", },
/* Keep the following compatibles for device tree compatibility */ /* Keep the following compatibles for device tree compatibility */
{ .compatible = "snps,spear-ahci", },
{ .compatible = "ibm,476gtr-ahci", }, { .compatible = "ibm,476gtr-ahci", },
{ .compatible = "snps,dwc-ahci", },
{ .compatible = "hisilicon,hisi-ahci", }, { .compatible = "hisilicon,hisi-ahci", },
{ .compatible = "cavium,octeon-7130-ahci", }, { .compatible = "cavium,octeon-7130-ahci", },
{ /* sentinel */ } { /* sentinel */ }
......
...@@ -144,7 +144,6 @@ static struct scsi_host_template ahci_platform_sht = { ...@@ -144,7 +144,6 @@ static struct scsi_host_template ahci_platform_sht = {
static int st_ahci_probe(struct platform_device *pdev) static int st_ahci_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev;
struct st_ahci_drv_data *drv_data; struct st_ahci_drv_data *drv_data;
struct ahci_host_priv *hpriv; struct ahci_host_priv *hpriv;
int err; int err;
...@@ -168,9 +167,6 @@ static int st_ahci_probe(struct platform_device *pdev) ...@@ -168,9 +167,6 @@ static int st_ahci_probe(struct platform_device *pdev)
st_ahci_configure_oob(hpriv->mmio); st_ahci_configure_oob(hpriv->mmio);
of_property_read_u32(dev->of_node,
"ports-implemented", &hpriv->force_port_map);
err = ahci_platform_init_host(pdev, hpriv, &st_ahci_port_info, err = ahci_platform_init_host(pdev, hpriv, &st_ahci_port_info,
&ahci_platform_sht); &ahci_platform_sht);
if (err) { if (err) {
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
* http://www.intel.com/technology/serialata/pdf/rev1_1.pdf * http://www.intel.com/technology/serialata/pdf/rev1_1.pdf
*/ */
#include <linux/bitops.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/gfp.h> #include <linux/gfp.h>
#include <linux/module.h> #include <linux/module.h>
...@@ -443,17 +444,28 @@ static ssize_t ahci_show_em_supported(struct device *dev, ...@@ -443,17 +444,28 @@ static ssize_t ahci_show_em_supported(struct device *dev,
void ahci_save_initial_config(struct device *dev, struct ahci_host_priv *hpriv) void ahci_save_initial_config(struct device *dev, struct ahci_host_priv *hpriv)
{ {
void __iomem *mmio = hpriv->mmio; void __iomem *mmio = hpriv->mmio;
u32 cap, cap2, vers, port_map; void __iomem *port_mmio;
unsigned long port_map;
u32 cap, cap2, vers;
int i; int i;
/* make sure AHCI mode is enabled before accessing CAP */ /* make sure AHCI mode is enabled before accessing CAP */
ahci_enable_ahci(mmio); ahci_enable_ahci(mmio);
/* Values prefixed with saved_ are written back to host after /*
* reset. Values without are used for driver operation. * Values prefixed with saved_ are written back to the HBA and ports
* registers after reset. Values without are used for driver operation.
*/
/*
* Override HW-init HBA capability fields with the platform-specific
* values. The rest of the HBA capabilities are defined as Read-only
* and can't be modified in CSR anyway.
*/ */
hpriv->saved_cap = cap = readl(mmio + HOST_CAP); cap = readl(mmio + HOST_CAP);
hpriv->saved_port_map = port_map = readl(mmio + HOST_PORTS_IMPL); if (hpriv->saved_cap)
cap = (cap & ~(HOST_CAP_SSS | HOST_CAP_MPS)) | hpriv->saved_cap;
hpriv->saved_cap = cap;
/* CAP2 register is only defined for AHCI 1.2 and later */ /* CAP2 register is only defined for AHCI 1.2 and later */
vers = readl(mmio + HOST_VERSION); vers = readl(mmio + HOST_VERSION);
...@@ -517,15 +529,18 @@ void ahci_save_initial_config(struct device *dev, struct ahci_host_priv *hpriv) ...@@ -517,15 +529,18 @@ void ahci_save_initial_config(struct device *dev, struct ahci_host_priv *hpriv)
cap &= ~HOST_CAP_SXS; cap &= ~HOST_CAP_SXS;
} }
if (hpriv->force_port_map && port_map != hpriv->force_port_map) { /* Override the HBA ports mapping if the platform needs it */
dev_info(dev, "forcing port_map 0x%x -> 0x%x\n", port_map = readl(mmio + HOST_PORTS_IMPL);
port_map, hpriv->force_port_map); if (hpriv->saved_port_map && port_map != hpriv->saved_port_map) {
port_map = hpriv->force_port_map; dev_info(dev, "forcing port_map 0x%lx -> 0x%x\n",
port_map, hpriv->saved_port_map);
port_map = hpriv->saved_port_map;
} else {
hpriv->saved_port_map = port_map; hpriv->saved_port_map = port_map;
} }
if (hpriv->mask_port_map) { if (hpriv->mask_port_map) {
dev_warn(dev, "masking port_map 0x%x -> 0x%x\n", dev_warn(dev, "masking port_map 0x%lx -> 0x%lx\n",
port_map, port_map,
port_map & hpriv->mask_port_map); port_map & hpriv->mask_port_map);
port_map &= hpriv->mask_port_map; port_map &= hpriv->mask_port_map;
...@@ -544,7 +559,7 @@ void ahci_save_initial_config(struct device *dev, struct ahci_host_priv *hpriv) ...@@ -544,7 +559,7 @@ void ahci_save_initial_config(struct device *dev, struct ahci_host_priv *hpriv)
*/ */
if (map_ports > ahci_nr_ports(cap)) { if (map_ports > ahci_nr_ports(cap)) {
dev_warn(dev, dev_warn(dev,
"implemented port map (0x%x) contains more ports than nr_ports (%u), using nr_ports\n", "implemented port map (0x%lx) contains more ports than nr_ports (%u), using nr_ports\n",
port_map, ahci_nr_ports(cap)); port_map, ahci_nr_ports(cap));
port_map = 0; port_map = 0;
} }
...@@ -553,16 +568,30 @@ void ahci_save_initial_config(struct device *dev, struct ahci_host_priv *hpriv) ...@@ -553,16 +568,30 @@ void ahci_save_initial_config(struct device *dev, struct ahci_host_priv *hpriv)
/* fabricate port_map from cap.nr_ports for < AHCI 1.3 */ /* fabricate port_map from cap.nr_ports for < AHCI 1.3 */
if (!port_map && vers < 0x10300) { if (!port_map && vers < 0x10300) {
port_map = (1 << ahci_nr_ports(cap)) - 1; port_map = (1 << ahci_nr_ports(cap)) - 1;
dev_warn(dev, "forcing PORTS_IMPL to 0x%x\n", port_map); dev_warn(dev, "forcing PORTS_IMPL to 0x%lx\n", port_map);
/* write the fixed up value to the PI register */ /* write the fixed up value to the PI register */
hpriv->saved_port_map = port_map; hpriv->saved_port_map = port_map;
} }
/*
* Preserve the ports capabilities defined by the platform. Note there
* is no need in storing the rest of the P#.CMD fields since they are
* volatile.
*/
for_each_set_bit(i, &port_map, AHCI_MAX_PORTS) {
if (hpriv->saved_port_cap[i])
continue;
port_mmio = __ahci_port_base(hpriv, i);
hpriv->saved_port_cap[i] =
readl(port_mmio + PORT_CMD) & PORT_CMD_CAP;
}
/* record values to use during operation */ /* record values to use during operation */
hpriv->cap = cap; hpriv->cap = cap;
hpriv->cap2 = cap2; hpriv->cap2 = cap2;
hpriv->version = readl(mmio + HOST_VERSION); hpriv->version = vers;
hpriv->port_map = port_map; hpriv->port_map = port_map;
if (!hpriv->start_engine) if (!hpriv->start_engine)
...@@ -588,13 +617,21 @@ EXPORT_SYMBOL_GPL(ahci_save_initial_config); ...@@ -588,13 +617,21 @@ EXPORT_SYMBOL_GPL(ahci_save_initial_config);
static void ahci_restore_initial_config(struct ata_host *host) static void ahci_restore_initial_config(struct ata_host *host)
{ {
struct ahci_host_priv *hpriv = host->private_data; struct ahci_host_priv *hpriv = host->private_data;
unsigned long port_map = hpriv->port_map;
void __iomem *mmio = hpriv->mmio; void __iomem *mmio = hpriv->mmio;
void __iomem *port_mmio;
int i;
writel(hpriv->saved_cap, mmio + HOST_CAP); writel(hpriv->saved_cap, mmio + HOST_CAP);
if (hpriv->saved_cap2) if (hpriv->saved_cap2)
writel(hpriv->saved_cap2, mmio + HOST_CAP2); writel(hpriv->saved_cap2, mmio + HOST_CAP2);
writel(hpriv->saved_port_map, mmio + HOST_PORTS_IMPL); writel(hpriv->saved_port_map, mmio + HOST_PORTS_IMPL);
(void) readl(mmio + HOST_PORTS_IMPL); /* flush */ (void) readl(mmio + HOST_PORTS_IMPL); /* flush */
for_each_set_bit(i, &port_map, AHCI_MAX_PORTS) {
port_mmio = __ahci_port_base(hpriv, i);
writel(hpriv->saved_port_cap[i], port_mmio + PORT_CMD);
}
} }
static unsigned ahci_scr_offset(struct ata_port *ap, unsigned int sc_reg) static unsigned ahci_scr_offset(struct ata_port *ap, unsigned int sc_reg)
......
This diff is collapsed.
...@@ -665,33 +665,33 @@ u64 ata_tf_read_block(const struct ata_taskfile *tf, struct ata_device *dev) ...@@ -665,33 +665,33 @@ u64 ata_tf_read_block(const struct ata_taskfile *tf, struct ata_device *dev)
/** /**
* ata_build_rw_tf - Build ATA taskfile for given read/write request * ata_build_rw_tf - Build ATA taskfile for given read/write request
* @tf: Target ATA taskfile * @qc: Metadata associated with the taskfile to build
* @dev: ATA device @tf belongs to
* @block: Block address * @block: Block address
* @n_block: Number of blocks * @n_block: Number of blocks
* @tf_flags: RW/FUA etc... * @tf_flags: RW/FUA etc...
* @tag: tag
* @class: IO priority class * @class: IO priority class
* *
* LOCKING: * LOCKING:
* None. * None.
* *
* Build ATA taskfile @tf for read/write request described by * Build ATA taskfile for the command @qc for read/write request described
* @block, @n_block, @tf_flags and @tag on @dev. * by @block, @n_block, @tf_flags and @class.
* *
* RETURNS: * RETURNS:
* *
* 0 on success, -ERANGE if the request is too large for @dev, * 0 on success, -ERANGE if the request is too large for @dev,
* -EINVAL if the request is invalid. * -EINVAL if the request is invalid.
*/ */
int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev, int ata_build_rw_tf(struct ata_queued_cmd *qc, u64 block, u32 n_block,
u64 block, u32 n_block, unsigned int tf_flags, unsigned int tf_flags, int class)
unsigned int tag, int class)
{ {
struct ata_taskfile *tf = &qc->tf;
struct ata_device *dev = qc->dev;
tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
tf->flags |= tf_flags; tf->flags |= tf_flags;
if (ata_ncq_enabled(dev) && !ata_tag_internal(tag)) { if (ata_ncq_enabled(dev)) {
/* yay, NCQ */ /* yay, NCQ */
if (!lba_48_ok(block, n_block)) if (!lba_48_ok(block, n_block))
return -ERANGE; return -ERANGE;
...@@ -704,7 +704,7 @@ int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev, ...@@ -704,7 +704,7 @@ int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev,
else else
tf->command = ATA_CMD_FPDMA_READ; tf->command = ATA_CMD_FPDMA_READ;
tf->nsect = tag << 3; tf->nsect = qc->hw_tag << 3;
tf->hob_feature = (n_block >> 8) & 0xff; tf->hob_feature = (n_block >> 8) & 0xff;
tf->feature = n_block & 0xff; tf->feature = n_block & 0xff;
...@@ -719,7 +719,7 @@ int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev, ...@@ -719,7 +719,7 @@ int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev,
if (tf->flags & ATA_TFLAG_FUA) if (tf->flags & ATA_TFLAG_FUA)
tf->device |= 1 << 7; tf->device |= 1 << 7;
if (dev->flags & ATA_DFLAG_NCQ_PRIO_ENABLE && if (dev->flags & ATA_DFLAG_NCQ_PRIO_ENABLED &&
class == IOPRIO_CLASS_RT) class == IOPRIO_CLASS_RT)
tf->hob_nsect |= ATA_PRIO_HIGH << ATA_SHIFT_PRIO; tf->hob_nsect |= ATA_PRIO_HIGH << ATA_SHIFT_PRIO;
} else if (dev->flags & ATA_DFLAG_LBA) { } else if (dev->flags & ATA_DFLAG_LBA) {
...@@ -1578,8 +1578,8 @@ static unsigned ata_exec_internal_sg(struct ata_device *dev, ...@@ -1578,8 +1578,8 @@ static unsigned ata_exec_internal_sg(struct ata_device *dev,
else else
ata_qc_complete(qc); ata_qc_complete(qc);
ata_dev_warn(dev, "qc timeout (cmd 0x%x)\n", ata_dev_warn(dev, "qc timeout after %u msecs (cmd 0x%x)\n",
command); timeout, command);
} }
spin_unlock_irqrestore(ap->lock, flags); spin_unlock_irqrestore(ap->lock, flags);
...@@ -2171,7 +2171,7 @@ static void ata_dev_config_ncq_prio(struct ata_device *dev) ...@@ -2171,7 +2171,7 @@ static void ata_dev_config_ncq_prio(struct ata_device *dev)
return; return;
not_supported: not_supported:
dev->flags &= ~ATA_DFLAG_NCQ_PRIO_ENABLE; dev->flags &= ~ATA_DFLAG_NCQ_PRIO_ENABLED;
dev->flags &= ~ATA_DFLAG_NCQ_PRIO; dev->flags &= ~ATA_DFLAG_NCQ_PRIO;
} }
...@@ -3021,7 +3021,8 @@ static void sata_print_link_status(struct ata_link *link) ...@@ -3021,7 +3021,8 @@ static void sata_print_link_status(struct ata_link *link)
if (sata_scr_read(link, SCR_STATUS, &sstatus)) if (sata_scr_read(link, SCR_STATUS, &sstatus))
return; return;
sata_scr_read(link, SCR_CONTROL, &scontrol); if (sata_scr_read(link, SCR_CONTROL, &scontrol))
return;
if (ata_phys_link_online(link)) { if (ata_phys_link_online(link)) {
tmp = (sstatus >> 4) & 0xf; tmp = (sstatus >> 4) & 0xf;
...@@ -4299,7 +4300,6 @@ static void ata_dev_xfermask(struct ata_device *dev) ...@@ -4299,7 +4300,6 @@ static void ata_dev_xfermask(struct ata_device *dev)
static unsigned int ata_dev_set_xfermode(struct ata_device *dev) static unsigned int ata_dev_set_xfermode(struct ata_device *dev)
{ {
struct ata_taskfile tf; struct ata_taskfile tf;
unsigned int err_mask;
/* set up set-features taskfile */ /* set up set-features taskfile */
ata_dev_dbg(dev, "set features - xfer mode\n"); ata_dev_dbg(dev, "set features - xfer mode\n");
...@@ -4321,20 +4321,20 @@ static unsigned int ata_dev_set_xfermode(struct ata_device *dev) ...@@ -4321,20 +4321,20 @@ static unsigned int ata_dev_set_xfermode(struct ata_device *dev)
else /* In the ancient relic department - skip all of this */ else /* In the ancient relic department - skip all of this */
return 0; return 0;
/* On some disks, this command causes spin-up, so we need longer timeout */ /*
err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 15000); * On some disks, this command causes spin-up, so we need longer
* timeout.
return err_mask; */
return ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 15000);
} }
/** /**
* ata_dev_set_feature - Issue SET FEATURES - SATA FEATURES * ata_dev_set_feature - Issue SET FEATURES
* @dev: Device to which command will be sent * @dev: Device to which command will be sent
* @enable: Whether to enable or disable the feature * @subcmd: The SET FEATURES subcommand to be sent
* @feature: The sector count represents the feature to set * @action: The sector count represents a subcommand specific action
* *
* Issue SET FEATURES - SATA FEATURES command to device @dev * Issue SET FEATURES command to device @dev on port @ap with sector count
* on port @ap with sector count
* *
* LOCKING: * LOCKING:
* PCI/etc. bus probe sem. * PCI/etc. bus probe sem.
...@@ -4342,28 +4342,26 @@ static unsigned int ata_dev_set_xfermode(struct ata_device *dev) ...@@ -4342,28 +4342,26 @@ static unsigned int ata_dev_set_xfermode(struct ata_device *dev)
* RETURNS: * RETURNS:
* 0 on success, AC_ERR_* mask otherwise. * 0 on success, AC_ERR_* mask otherwise.
*/ */
unsigned int ata_dev_set_feature(struct ata_device *dev, u8 enable, u8 feature) unsigned int ata_dev_set_feature(struct ata_device *dev, u8 subcmd, u8 action)
{ {
struct ata_taskfile tf; struct ata_taskfile tf;
unsigned int err_mask;
unsigned int timeout = 0; unsigned int timeout = 0;
/* set up set-features taskfile */ /* set up set-features taskfile */
ata_dev_dbg(dev, "set features - SATA features\n"); ata_dev_dbg(dev, "set features\n");
ata_tf_init(dev, &tf); ata_tf_init(dev, &tf);
tf.command = ATA_CMD_SET_FEATURES; tf.command = ATA_CMD_SET_FEATURES;
tf.feature = enable; tf.feature = subcmd;
tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
tf.protocol = ATA_PROT_NODATA; tf.protocol = ATA_PROT_NODATA;
tf.nsect = feature; tf.nsect = action;
if (enable == SETFEATURES_SPINUP) if (subcmd == SETFEATURES_SPINUP)
timeout = ata_probe_timeout ? timeout = ata_probe_timeout ?
ata_probe_timeout * 1000 : SETFEATURES_SPINUP_TIMEOUT; ata_probe_timeout * 1000 : SETFEATURES_SPINUP_TIMEOUT;
err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, timeout);
return err_mask; return ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, timeout);
} }
EXPORT_SYMBOL_GPL(ata_dev_set_feature); EXPORT_SYMBOL_GPL(ata_dev_set_feature);
......
...@@ -151,6 +151,8 @@ ata_eh_cmd_timeout_table[ATA_EH_CMD_TIMEOUT_TABLE_SIZE] = { ...@@ -151,6 +151,8 @@ ata_eh_cmd_timeout_table[ATA_EH_CMD_TIMEOUT_TABLE_SIZE] = {
#undef CMDS #undef CMDS
static void __ata_port_freeze(struct ata_port *ap); static void __ata_port_freeze(struct ata_port *ap);
static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
struct ata_device **r_failed_dev);
#ifdef CONFIG_PM #ifdef CONFIG_PM
static void ata_eh_handle_port_suspend(struct ata_port *ap); static void ata_eh_handle_port_suspend(struct ata_port *ap);
static void ata_eh_handle_port_resume(struct ata_port *ap); static void ata_eh_handle_port_resume(struct ata_port *ap);
...@@ -1086,14 +1088,11 @@ static void __ata_port_freeze(struct ata_port *ap) ...@@ -1086,14 +1088,11 @@ static void __ata_port_freeze(struct ata_port *ap)
*/ */
int ata_port_freeze(struct ata_port *ap) int ata_port_freeze(struct ata_port *ap)
{ {
int nr_aborted;
WARN_ON(!ap->ops->error_handler); WARN_ON(!ap->ops->error_handler);
__ata_port_freeze(ap); __ata_port_freeze(ap);
nr_aborted = ata_port_abort(ap);
return nr_aborted; return ata_port_abort(ap);
} }
EXPORT_SYMBOL_GPL(ata_port_freeze); EXPORT_SYMBOL_GPL(ata_port_freeze);
...@@ -1393,7 +1392,6 @@ unsigned int atapi_eh_tur(struct ata_device *dev, u8 *r_sense_key) ...@@ -1393,7 +1392,6 @@ unsigned int atapi_eh_tur(struct ata_device *dev, u8 *r_sense_key)
/** /**
* ata_eh_request_sense - perform REQUEST_SENSE_DATA_EXT * ata_eh_request_sense - perform REQUEST_SENSE_DATA_EXT
* @qc: qc to perform REQUEST_SENSE_SENSE_DATA_EXT to * @qc: qc to perform REQUEST_SENSE_SENSE_DATA_EXT to
* @cmd: scsi command for which the sense code should be set
* *
* Perform REQUEST_SENSE_DATA_EXT after the device reported CHECK * Perform REQUEST_SENSE_DATA_EXT after the device reported CHECK
* SENSE. This function is an EH helper. * SENSE. This function is an EH helper.
...@@ -1401,9 +1399,9 @@ unsigned int atapi_eh_tur(struct ata_device *dev, u8 *r_sense_key) ...@@ -1401,9 +1399,9 @@ unsigned int atapi_eh_tur(struct ata_device *dev, u8 *r_sense_key)
* LOCKING: * LOCKING:
* Kernel thread context (may sleep). * Kernel thread context (may sleep).
*/ */
static void ata_eh_request_sense(struct ata_queued_cmd *qc, static void ata_eh_request_sense(struct ata_queued_cmd *qc)
struct scsi_cmnd *cmd)
{ {
struct scsi_cmnd *cmd = qc->scsicmd;
struct ata_device *dev = qc->dev; struct ata_device *dev = qc->dev;
struct ata_taskfile tf; struct ata_taskfile tf;
unsigned int err_mask; unsigned int err_mask;
...@@ -1541,7 +1539,6 @@ static void ata_eh_analyze_serror(struct ata_link *link) ...@@ -1541,7 +1539,6 @@ static void ata_eh_analyze_serror(struct ata_link *link)
/** /**
* ata_eh_analyze_tf - analyze taskfile of a failed qc * ata_eh_analyze_tf - analyze taskfile of a failed qc
* @qc: qc to analyze * @qc: qc to analyze
* @tf: Taskfile registers to analyze
* *
* Analyze taskfile of @qc and further determine cause of * Analyze taskfile of @qc and further determine cause of
* failure. This function also requests ATAPI sense data if * failure. This function also requests ATAPI sense data if
...@@ -1553,9 +1550,9 @@ static void ata_eh_analyze_serror(struct ata_link *link) ...@@ -1553,9 +1550,9 @@ static void ata_eh_analyze_serror(struct ata_link *link)
* RETURNS: * RETURNS:
* Determined recovery action * Determined recovery action
*/ */
static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc, static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc)
const struct ata_taskfile *tf)
{ {
const struct ata_taskfile *tf = &qc->result_tf;
unsigned int tmp, action = 0; unsigned int tmp, action = 0;
u8 stat = tf->status, err = tf->error; u8 stat = tf->status, err = tf->error;
...@@ -1579,7 +1576,7 @@ static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc, ...@@ -1579,7 +1576,7 @@ static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc,
switch (qc->dev->class) { switch (qc->dev->class) {
case ATA_DEV_ZAC: case ATA_DEV_ZAC:
if (stat & ATA_SENSE) if (stat & ATA_SENSE)
ata_eh_request_sense(qc, qc->scsicmd); ata_eh_request_sense(qc);
fallthrough; fallthrough;
case ATA_DEV_ATA: case ATA_DEV_ATA:
if (err & ATA_ICRC) if (err & ATA_ICRC)
...@@ -1957,7 +1954,7 @@ static void ata_eh_link_autopsy(struct ata_link *link) ...@@ -1957,7 +1954,7 @@ static void ata_eh_link_autopsy(struct ata_link *link)
qc->err_mask |= ehc->i.err_mask; qc->err_mask |= ehc->i.err_mask;
/* analyze TF */ /* analyze TF */
ehc->i.action |= ata_eh_analyze_tf(qc, &qc->result_tf); ehc->i.action |= ata_eh_analyze_tf(qc);
/* DEV errors are probably spurious in case of ATA_BUS error */ /* DEV errors are probably spurious in case of ATA_BUS error */
if (qc->err_mask & AC_ERR_ATA_BUS) if (qc->err_mask & AC_ERR_ATA_BUS)
...@@ -2940,6 +2937,23 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link, ...@@ -2940,6 +2937,23 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link,
if ((action & ATA_EH_REVALIDATE) && ata_dev_enabled(dev)) { if ((action & ATA_EH_REVALIDATE) && ata_dev_enabled(dev)) {
WARN_ON(dev->class == ATA_DEV_PMP); WARN_ON(dev->class == ATA_DEV_PMP);
/*
* The link may be in a deep sleep, wake it up.
*
* If the link is in deep sleep, ata_phys_link_offline()
* will return true, causing the revalidation to fail,
* which leads to a (potentially) needless hard reset.
*
* ata_eh_recover() will later restore the link policy
* to ap->target_lpm_policy after revalidation is done.
*/
if (link->lpm_policy > ATA_LPM_MAX_POWER) {
rc = ata_eh_set_lpm(link, ATA_LPM_MAX_POWER,
r_failed_dev);
if (rc)
goto err;
}
if (ata_phys_link_offline(ata_dev_phys_link(dev))) { if (ata_phys_link_offline(ata_dev_phys_link(dev))) {
rc = -EIO; rc = -EIO;
goto err; goto err;
......
...@@ -870,7 +870,7 @@ static ssize_t ata_ncq_prio_enable_show(struct device *device, ...@@ -870,7 +870,7 @@ static ssize_t ata_ncq_prio_enable_show(struct device *device,
if (!dev) if (!dev)
rc = -ENODEV; rc = -ENODEV;
else else
ncq_prio_enable = dev->flags & ATA_DFLAG_NCQ_PRIO_ENABLE; ncq_prio_enable = dev->flags & ATA_DFLAG_NCQ_PRIO_ENABLED;
spin_unlock_irq(ap->lock); spin_unlock_irq(ap->lock);
return rc ? rc : sysfs_emit(buf, "%u\n", ncq_prio_enable); return rc ? rc : sysfs_emit(buf, "%u\n", ncq_prio_enable);
...@@ -905,9 +905,9 @@ static ssize_t ata_ncq_prio_enable_store(struct device *device, ...@@ -905,9 +905,9 @@ static ssize_t ata_ncq_prio_enable_store(struct device *device,
} }
if (input) if (input)
dev->flags |= ATA_DFLAG_NCQ_PRIO_ENABLE; dev->flags |= ATA_DFLAG_NCQ_PRIO_ENABLED;
else else
dev->flags &= ~ATA_DFLAG_NCQ_PRIO_ENABLE; dev->flags &= ~ATA_DFLAG_NCQ_PRIO_ENABLED;
unlock: unlock:
spin_unlock_irq(ap->lock); spin_unlock_irq(ap->lock);
......
...@@ -1603,9 +1603,7 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc) ...@@ -1603,9 +1603,7 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc)
qc->flags |= ATA_QCFLAG_IO; qc->flags |= ATA_QCFLAG_IO;
qc->nbytes = n_block * scmd->device->sector_size; qc->nbytes = n_block * scmd->device->sector_size;
rc = ata_build_rw_tf(&qc->tf, qc->dev, block, n_block, tf_flags, rc = ata_build_rw_tf(qc, block, n_block, tf_flags, class);
qc->hw_tag, class);
if (likely(rc == 0)) if (likely(rc == 0))
return 0; return 0;
......
...@@ -776,7 +776,7 @@ static void atapi_send_cdb(struct ata_port *ap, struct ata_queued_cmd *qc) ...@@ -776,7 +776,7 @@ static void atapi_send_cdb(struct ata_port *ap, struct ata_queued_cmd *qc)
* @qc: Command on going * @qc: Command on going
* @bytes: number of bytes * @bytes: number of bytes
* *
* Transfer Transfer data from/to the ATAPI device. * Transfer data from/to the ATAPI device.
* *
* LOCKING: * LOCKING:
* Inherited from caller. * Inherited from caller.
......
...@@ -44,9 +44,8 @@ static inline void ata_force_cbl(struct ata_port *ap) { } ...@@ -44,9 +44,8 @@ static inline void ata_force_cbl(struct ata_port *ap) { }
#endif #endif
extern u64 ata_tf_to_lba(const struct ata_taskfile *tf); extern u64 ata_tf_to_lba(const struct ata_taskfile *tf);
extern u64 ata_tf_to_lba48(const struct ata_taskfile *tf); extern u64 ata_tf_to_lba48(const struct ata_taskfile *tf);
extern int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev, extern int ata_build_rw_tf(struct ata_queued_cmd *qc, u64 block, u32 n_block,
u64 block, u32 n_block, unsigned int tf_flags, unsigned int tf_flags, int class);
unsigned int tag, int class);
extern u64 ata_tf_read_block(const struct ata_taskfile *tf, extern u64 ata_tf_read_block(const struct ata_taskfile *tf,
struct ata_device *dev); struct ata_device *dev);
extern unsigned ata_exec_internal(struct ata_device *dev, extern unsigned ata_exec_internal(struct ata_device *dev,
...@@ -64,7 +63,7 @@ extern int ata_dev_configure(struct ata_device *dev); ...@@ -64,7 +63,7 @@ extern int ata_dev_configure(struct ata_device *dev);
extern int sata_down_spd_limit(struct ata_link *link, u32 spd_limit); extern int sata_down_spd_limit(struct ata_link *link, u32 spd_limit);
extern int ata_down_xfermask_limit(struct ata_device *dev, unsigned int sel); extern int ata_down_xfermask_limit(struct ata_device *dev, unsigned int sel);
extern unsigned int ata_dev_set_feature(struct ata_device *dev, extern unsigned int ata_dev_set_feature(struct ata_device *dev,
u8 enable, u8 feature); u8 subcmd, u8 action);
extern void ata_qc_free(struct ata_queued_cmd *qc); extern void ata_qc_free(struct ata_queued_cmd *qc);
extern void ata_qc_issue(struct ata_queued_cmd *qc); extern void ata_qc_issue(struct ata_queued_cmd *qc);
extern void __ata_qc_complete(struct ata_queued_cmd *qc); extern void __ata_qc_complete(struct ata_queued_cmd *qc);
......
...@@ -666,8 +666,7 @@ static u8 pata_macio_bmdma_status(struct ata_port *ap) ...@@ -666,8 +666,7 @@ static u8 pata_macio_bmdma_status(struct ata_port *ap)
* a multi-block transfer. * a multi-block transfer.
* *
* - The dbdma fifo hasn't yet finished flushing to * - The dbdma fifo hasn't yet finished flushing to
* to system memory when the disk interrupt occurs. * system memory when the disk interrupt occurs.
*
*/ */
/* First check for errors */ /* First check for errors */
......
/* SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause */
/*
* This header provides constants for most AHCI bindings.
*/
#ifndef _DT_BINDINGS_ATA_AHCI_H
#define _DT_BINDINGS_ATA_AHCI_H
/* Host Bus Adapter generic platform capabilities */
#define HBA_SSS (1 << 27)
#define HBA_SMPS (1 << 28)
/* Host Bus Adapter port-specific platform capabilities */
#define HBA_PORT_HPCP (1 << 18)
#define HBA_PORT_MPSP (1 << 19)
#define HBA_PORT_CPD (1 << 20)
#define HBA_PORT_ESP (1 << 21)
#define HBA_PORT_FBSCP (1 << 22)
#endif
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <linux/compiler.h> #include <linux/compiler.h>
struct clk;
struct device; struct device;
struct ata_port_info; struct ata_port_info;
struct ahci_host_priv; struct ahci_host_priv;
...@@ -21,8 +22,12 @@ struct scsi_host_template; ...@@ -21,8 +22,12 @@ struct scsi_host_template;
int ahci_platform_enable_phys(struct ahci_host_priv *hpriv); int ahci_platform_enable_phys(struct ahci_host_priv *hpriv);
void ahci_platform_disable_phys(struct ahci_host_priv *hpriv); void ahci_platform_disable_phys(struct ahci_host_priv *hpriv);
struct clk *ahci_platform_find_clk(struct ahci_host_priv *hpriv,
const char *con_id);
int ahci_platform_enable_clks(struct ahci_host_priv *hpriv); int ahci_platform_enable_clks(struct ahci_host_priv *hpriv);
void ahci_platform_disable_clks(struct ahci_host_priv *hpriv); void ahci_platform_disable_clks(struct ahci_host_priv *hpriv);
int ahci_platform_deassert_rsts(struct ahci_host_priv *hpriv);
int ahci_platform_assert_rsts(struct ahci_host_priv *hpriv);
int ahci_platform_enable_regulators(struct ahci_host_priv *hpriv); int ahci_platform_enable_regulators(struct ahci_host_priv *hpriv);
void ahci_platform_disable_regulators(struct ahci_host_priv *hpriv); void ahci_platform_disable_regulators(struct ahci_host_priv *hpriv);
int ahci_platform_enable_resources(struct ahci_host_priv *hpriv); int ahci_platform_enable_resources(struct ahci_host_priv *hpriv);
...@@ -41,6 +46,7 @@ int ahci_platform_resume_host(struct device *dev); ...@@ -41,6 +46,7 @@ int ahci_platform_resume_host(struct device *dev);
int ahci_platform_suspend(struct device *dev); int ahci_platform_suspend(struct device *dev);
int ahci_platform_resume(struct device *dev); int ahci_platform_resume(struct device *dev);
#define AHCI_PLATFORM_GET_RESETS 0x01 #define AHCI_PLATFORM_GET_RESETS BIT(0)
#define AHCI_PLATFORM_RST_TRIGGER BIT(1)
#endif /* _AHCI_PLATFORM_H */ #endif /* _AHCI_PLATFORM_H */
...@@ -566,6 +566,18 @@ struct ata_bmdma_prd { ...@@ -566,6 +566,18 @@ struct ata_bmdma_prd {
((((id)[ATA_ID_SATA_CAPABILITY] != 0x0000) && \ ((((id)[ATA_ID_SATA_CAPABILITY] != 0x0000) && \
((id)[ATA_ID_SATA_CAPABILITY] != 0xffff)) && \ ((id)[ATA_ID_SATA_CAPABILITY] != 0xffff)) && \
((id)[ATA_ID_FEATURE_SUPP] & (1 << 2))) ((id)[ATA_ID_FEATURE_SUPP] & (1 << 2)))
#define ata_id_has_devslp(id) \
((((id)[ATA_ID_SATA_CAPABILITY] != 0x0000) && \
((id)[ATA_ID_SATA_CAPABILITY] != 0xffff)) && \
((id)[ATA_ID_FEATURE_SUPP] & (1 << 8)))
#define ata_id_has_ncq_autosense(id) \
((((id)[ATA_ID_SATA_CAPABILITY] != 0x0000) && \
((id)[ATA_ID_SATA_CAPABILITY] != 0xffff)) && \
((id)[ATA_ID_FEATURE_SUPP] & (1 << 7)))
#define ata_id_has_dipm(id) \
((((id)[ATA_ID_SATA_CAPABILITY] != 0x0000) && \
((id)[ATA_ID_SATA_CAPABILITY] != 0xffff)) && \
((id)[ATA_ID_FEATURE_SUPP] & (1 << 3)))
#define ata_id_iordy_disable(id) ((id)[ATA_ID_CAPABILITY] & (1 << 10)) #define ata_id_iordy_disable(id) ((id)[ATA_ID_CAPABILITY] & (1 << 10))
#define ata_id_has_iordy(id) ((id)[ATA_ID_CAPABILITY] & (1 << 11)) #define ata_id_has_iordy(id) ((id)[ATA_ID_CAPABILITY] & (1 << 11))
#define ata_id_u32(id,n) \ #define ata_id_u32(id,n) \
...@@ -578,9 +590,6 @@ struct ata_bmdma_prd { ...@@ -578,9 +590,6 @@ struct ata_bmdma_prd {
#define ata_id_cdb_intr(id) (((id)[ATA_ID_CONFIG] & 0x60) == 0x20) #define ata_id_cdb_intr(id) (((id)[ATA_ID_CONFIG] & 0x60) == 0x20)
#define ata_id_has_da(id) ((id)[ATA_ID_SATA_CAPABILITY_2] & (1 << 4)) #define ata_id_has_da(id) ((id)[ATA_ID_SATA_CAPABILITY_2] & (1 << 4))
#define ata_id_has_devslp(id) ((id)[ATA_ID_FEATURE_SUPP] & (1 << 8))
#define ata_id_has_ncq_autosense(id) \
((id)[ATA_ID_FEATURE_SUPP] & (1 << 7))
static inline bool ata_id_has_hipm(const u16 *id) static inline bool ata_id_has_hipm(const u16 *id)
{ {
...@@ -592,17 +601,6 @@ static inline bool ata_id_has_hipm(const u16 *id) ...@@ -592,17 +601,6 @@ static inline bool ata_id_has_hipm(const u16 *id)
return val & (1 << 9); return val & (1 << 9);
} }
static inline bool ata_id_has_dipm(const u16 *id)
{
u16 val = id[ATA_ID_FEATURE_SUPP];
if (val == 0 || val == 0xffff)
return false;
return val & (1 << 3);
}
static inline bool ata_id_has_fua(const u16 *id) static inline bool ata_id_has_fua(const u16 *id)
{ {
if ((id[ATA_ID_CFSSE] & 0xC000) != 0x4000) if ((id[ATA_ID_CFSSE] & 0xC000) != 0x4000)
...@@ -771,16 +769,21 @@ static inline bool ata_id_has_read_log_dma_ext(const u16 *id) ...@@ -771,16 +769,21 @@ static inline bool ata_id_has_read_log_dma_ext(const u16 *id)
static inline bool ata_id_has_sense_reporting(const u16 *id) static inline bool ata_id_has_sense_reporting(const u16 *id)
{ {
if (!(id[ATA_ID_CFS_ENABLE_2] & (1 << 15))) if (!(id[ATA_ID_CFS_ENABLE_2] & BIT(15)))
return false;
if ((id[ATA_ID_COMMAND_SET_3] & (BIT(15) | BIT(14))) != BIT(14))
return false; return false;
return id[ATA_ID_COMMAND_SET_3] & (1 << 6); return id[ATA_ID_COMMAND_SET_3] & BIT(6);
} }
static inline bool ata_id_sense_reporting_enabled(const u16 *id) static inline bool ata_id_sense_reporting_enabled(const u16 *id)
{ {
if (!(id[ATA_ID_CFS_ENABLE_2] & (1 << 15))) if (!ata_id_has_sense_reporting(id))
return false;
/* ata_id_has_sense_reporting() == true, word 86 must have bit 15 set */
if ((id[ATA_ID_COMMAND_SET_4] & (BIT(15) | BIT(14))) != BIT(14))
return false; return false;
return id[ATA_ID_COMMAND_SET_4] & (1 << 6); return id[ATA_ID_COMMAND_SET_4] & BIT(6);
} }
/** /**
......
...@@ -101,7 +101,7 @@ enum { ...@@ -101,7 +101,7 @@ enum {
ATA_DFLAG_UNLOCK_HPA = (1 << 18), /* unlock HPA */ ATA_DFLAG_UNLOCK_HPA = (1 << 18), /* unlock HPA */
ATA_DFLAG_NCQ_SEND_RECV = (1 << 19), /* device supports NCQ SEND and RECV */ ATA_DFLAG_NCQ_SEND_RECV = (1 << 19), /* device supports NCQ SEND and RECV */
ATA_DFLAG_NCQ_PRIO = (1 << 20), /* device supports NCQ priority */ ATA_DFLAG_NCQ_PRIO = (1 << 20), /* device supports NCQ priority */
ATA_DFLAG_NCQ_PRIO_ENABLE = (1 << 21), /* Priority cmds sent to dev */ ATA_DFLAG_NCQ_PRIO_ENABLED = (1 << 21), /* Priority cmds sent to dev */
ATA_DFLAG_INIT_MASK = (1 << 24) - 1, ATA_DFLAG_INIT_MASK = (1 << 24) - 1,
ATA_DFLAG_DETACH = (1 << 24), ATA_DFLAG_DETACH = (1 << 24),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment