diff options
26 files changed, 988 insertions, 82 deletions
diff --git a/Documentation/ABI/testing/sysfs-ata b/Documentation/ABI/testing/sysfs-ata index 0a932155cbba..aa4296498859 100644 --- a/Documentation/ABI/testing/sysfs-ata +++ b/Documentation/ABI/testing/sysfs-ata | |||
@@ -90,6 +90,17 @@ gscr | |||
90 | 130: SATA_PMP_GSCR_SII_GPIO | 90 | 130: SATA_PMP_GSCR_SII_GPIO |
91 | Only valid if the device is a PM. | 91 | Only valid if the device is a PM. |
92 | 92 | ||
93 | trim | ||
94 | |||
95 | Shows the DSM TRIM mode currently used by the device. Valid | ||
96 | values are: | ||
97 | unsupported: Drive does not support DSM TRIM | ||
98 | unqueued: Drive supports unqueued DSM TRIM only | ||
99 | queued: Drive supports queued DSM TRIM | ||
100 | forced_unqueued: Drive's queued DSM support is known to be | ||
101 | buggy and only unqueued TRIM commands | ||
102 | are sent | ||
103 | |||
93 | spdn_cnt | 104 | spdn_cnt |
94 | 105 | ||
95 | Number of time libata decided to lower the speed of link due to errors. | 106 | Number of time libata decided to lower the speed of link due to errors. |
diff --git a/Documentation/devicetree/bindings/ata/ahci-ceva.txt b/Documentation/devicetree/bindings/ata/ahci-ceva.txt new file mode 100644 index 000000000000..7ca8b976c13a --- /dev/null +++ b/Documentation/devicetree/bindings/ata/ahci-ceva.txt | |||
@@ -0,0 +1,20 @@ | |||
1 | Binding for CEVA AHCI SATA Controller | ||
2 | |||
3 | Required properties: | ||
4 | - reg: Physical base address and size of the controller's register area. | ||
5 | - compatible: Compatibility string. Must be 'ceva,ahci-1v84'. | ||
6 | - clocks: Input clock specifier. Refer to common clock bindings. | ||
7 | - interrupts: Interrupt specifier. Refer to interrupt binding. | ||
8 | |||
9 | Optional properties: | ||
10 | - ceva,broken-gen2: limit to gen1 speed instead of gen2. | ||
11 | |||
12 | Examples: | ||
13 | ahci@fd0c0000 { | ||
14 | compatible = "ceva,ahci-1v84"; | ||
15 | reg = <0xfd0c0000 0x200>; | ||
16 | interrupt-parent = <&gic>; | ||
17 | interrupts = <0 133 4>; | ||
18 | clocks = <&clkc SATA_CLK_ID>; | ||
19 | ceva,broken-gen2; | ||
20 | }; | ||
diff --git a/Documentation/devicetree/bindings/ata/ahci-platform.txt b/Documentation/devicetree/bindings/ata/ahci-platform.txt index c2340eeeb97f..a2321819e7f5 100644 --- a/Documentation/devicetree/bindings/ata/ahci-platform.txt +++ b/Documentation/devicetree/bindings/ata/ahci-platform.txt | |||
@@ -16,6 +16,8 @@ Required properties: | |||
16 | - "snps,dwc-ahci" | 16 | - "snps,dwc-ahci" |
17 | - "snps,exynos5440-ahci" | 17 | - "snps,exynos5440-ahci" |
18 | - "snps,spear-ahci" | 18 | - "snps,spear-ahci" |
19 | - "fsl,qoriq-ahci" : for qoriq series socs which include ls1021, ls2085, etc. | ||
20 | - "fsl,<chip>-ahci" : chip could be ls1021, ls2085 etc. | ||
19 | - "generic-ahci" | 21 | - "generic-ahci" |
20 | - interrupts : <interrupt mapping for SATA IRQ> | 22 | - interrupts : <interrupt mapping for SATA IRQ> |
21 | - reg : <registers mapping> | 23 | - reg : <registers mapping> |
diff --git a/Documentation/devicetree/bindings/ata/brcm,sata-brcmstb.txt b/Documentation/devicetree/bindings/ata/brcm,sata-brcmstb.txt new file mode 100644 index 000000000000..20ac9bbfa1fd --- /dev/null +++ b/Documentation/devicetree/bindings/ata/brcm,sata-brcmstb.txt | |||
@@ -0,0 +1,34 @@ | |||
1 | * Broadcom SATA3 AHCI Controller for STB | ||
2 | |||
3 | SATA nodes are defined to describe on-chip Serial ATA controllers. | ||
4 | Each SATA controller should have its own node. | ||
5 | |||
6 | Required properties: | ||
7 | - compatible : compatible list, may contain "brcm,bcm7445-ahci" and/or | ||
8 | "brcm,sata3-ahci" | ||
9 | - reg : register mappings for AHCI and SATA_TOP_CTRL | ||
10 | - reg-names : "ahci" and "top-ctrl" | ||
11 | - interrupts : interrupt mapping for SATA IRQ | ||
12 | |||
13 | Also see ahci-platform.txt. | ||
14 | |||
15 | Example: | ||
16 | |||
17 | sata@f045a000 { | ||
18 | compatible = "brcm,bcm7445-ahci", "brcm,sata3-ahci"; | ||
19 | reg = <0xf045a000 0xa9c>, <0xf0458040 0x24>; | ||
20 | reg-names = "ahci", "top-ctrl"; | ||
21 | interrupts = <0 30 0>; | ||
22 | #address-cells = <1>; | ||
23 | #size-cells = <0>; | ||
24 | |||
25 | sata0: sata-port@0 { | ||
26 | reg = <0>; | ||
27 | phys = <&sata_phy 0>; | ||
28 | }; | ||
29 | |||
30 | sata1: sata-port@1 { | ||
31 | reg = <1>; | ||
32 | phys = <&sata_phy 1>; | ||
33 | }; | ||
34 | }; | ||
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index fd66d220c115..c84d078a6376 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -1791,6 +1791,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
1791 | 1791 | ||
1792 | * [no]ncq: Turn on or off NCQ. | 1792 | * [no]ncq: Turn on or off NCQ. |
1793 | 1793 | ||
1794 | * [no]ncqtrim: Turn off queued DSM TRIM. | ||
1795 | |||
1794 | * nohrst, nosrst, norst: suppress hard, soft | 1796 | * nohrst, nosrst, norst: suppress hard, soft |
1795 | and both resets. | 1797 | and both resets. |
1796 | 1798 | ||
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 9dca4b995be0..b11470a7bd8f 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig | |||
@@ -98,6 +98,15 @@ config SATA_AHCI_PLATFORM | |||
98 | 98 | ||
99 | If unsure, say N. | 99 | If unsure, say N. |
100 | 100 | ||
101 | config AHCI_BRCMSTB | ||
102 | tristate "Broadcom STB AHCI SATA support" | ||
103 | depends on ARCH_BRCMSTB | ||
104 | help | ||
105 | This option enables support for the AHCI SATA3 controller found on | ||
106 | STB SoC's. | ||
107 | |||
108 | If unsure, say N. | ||
109 | |||
101 | config AHCI_DA850 | 110 | config AHCI_DA850 |
102 | tristate "DaVinci DA850 AHCI SATA support" | 111 | tristate "DaVinci DA850 AHCI SATA support" |
103 | depends on ARCH_DAVINCI_DA850 | 112 | depends on ARCH_DAVINCI_DA850 |
@@ -124,6 +133,15 @@ config AHCI_IMX | |||
124 | 133 | ||
125 | If unsure, say N. | 134 | If unsure, say N. |
126 | 135 | ||
136 | config AHCI_CEVA | ||
137 | tristate "CEVA AHCI SATA support" | ||
138 | depends on OF | ||
139 | help | ||
140 | This option enables support for the CEVA AHCI SATA. | ||
141 | It can be found on the Xilinx Zynq UltraScale+ MPSoC. | ||
142 | |||
143 | If unsure, say N. | ||
144 | |||
127 | config AHCI_MVEBU | 145 | config AHCI_MVEBU |
128 | tristate "Marvell EBU AHCI SATA support" | 146 | tristate "Marvell EBU AHCI SATA support" |
129 | depends on ARCH_MVEBU | 147 | depends on ARCH_MVEBU |
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index 40f7865f20a1..af70919f7dde 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile | |||
@@ -10,6 +10,8 @@ obj-$(CONFIG_SATA_INIC162X) += sata_inic162x.o | |||
10 | obj-$(CONFIG_SATA_SIL24) += sata_sil24.o | 10 | obj-$(CONFIG_SATA_SIL24) += sata_sil24.o |
11 | obj-$(CONFIG_SATA_DWC) += sata_dwc_460ex.o | 11 | obj-$(CONFIG_SATA_DWC) += sata_dwc_460ex.o |
12 | obj-$(CONFIG_SATA_HIGHBANK) += sata_highbank.o libahci.o | 12 | obj-$(CONFIG_SATA_HIGHBANK) += sata_highbank.o libahci.o |
13 | obj-$(CONFIG_AHCI_BRCMSTB) += ahci_brcmstb.o libahci.o libahci_platform.o | ||
14 | obj-$(CONFIG_AHCI_CEVA) += ahci_ceva.o libahci.o libahci_platform.o | ||
13 | obj-$(CONFIG_AHCI_DA850) += ahci_da850.o libahci.o libahci_platform.o | 15 | obj-$(CONFIG_AHCI_DA850) += ahci_da850.o libahci.o libahci_platform.o |
14 | obj-$(CONFIG_AHCI_IMX) += ahci_imx.o libahci.o libahci_platform.o | 16 | obj-$(CONFIG_AHCI_IMX) += ahci_imx.o libahci.o libahci_platform.o |
15 | obj-$(CONFIG_AHCI_MVEBU) += ahci_mvebu.o libahci.o libahci_platform.o | 17 | obj-$(CONFIG_AHCI_MVEBU) += ahci_mvebu.o libahci.o libahci_platform.o |
diff --git a/drivers/ata/acard-ahci.c b/drivers/ata/acard-ahci.c index 12489ce863c4..ed6a30cd681a 100644 --- a/drivers/ata/acard-ahci.c +++ b/drivers/ata/acard-ahci.c | |||
@@ -433,6 +433,8 @@ static int acard_ahci_init_one(struct pci_dev *pdev, const struct pci_device_id | |||
433 | hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL); | 433 | hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL); |
434 | if (!hpriv) | 434 | if (!hpriv) |
435 | return -ENOMEM; | 435 | return -ENOMEM; |
436 | |||
437 | hpriv->irq = pdev->irq; | ||
436 | hpriv->flags |= (unsigned long)pi.private_data; | 438 | hpriv->flags |= (unsigned long)pi.private_data; |
437 | 439 | ||
438 | if (!(hpriv->flags & AHCI_HFLAG_NO_MSI)) | 440 | if (!(hpriv->flags & AHCI_HFLAG_NO_MSI)) |
@@ -498,7 +500,7 @@ static int acard_ahci_init_one(struct pci_dev *pdev, const struct pci_device_id | |||
498 | acard_ahci_pci_print_info(host); | 500 | acard_ahci_pci_print_info(host); |
499 | 501 | ||
500 | pci_set_master(pdev); | 502 | pci_set_master(pdev); |
501 | return ahci_host_activate(host, pdev->irq, &acard_ahci_sht); | 503 | return ahci_host_activate(host, &acard_ahci_sht); |
502 | } | 504 | } |
503 | 505 | ||
504 | module_pci_driver(acard_ahci_pci_driver); | 506 | module_pci_driver(acard_ahci_pci_driver); |
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 65ee94454bbd..7e62751abfac 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <linux/device.h> | 42 | #include <linux/device.h> |
43 | #include <linux/dmi.h> | 43 | #include <linux/dmi.h> |
44 | #include <linux/gfp.h> | 44 | #include <linux/gfp.h> |
45 | #include <linux/msi.h> | ||
45 | #include <scsi/scsi_host.h> | 46 | #include <scsi/scsi_host.h> |
46 | #include <scsi/scsi_cmnd.h> | 47 | #include <scsi/scsi_cmnd.h> |
47 | #include <linux/libata.h> | 48 | #include <linux/libata.h> |
@@ -52,6 +53,7 @@ | |||
52 | 53 | ||
53 | enum { | 54 | enum { |
54 | AHCI_PCI_BAR_STA2X11 = 0, | 55 | AHCI_PCI_BAR_STA2X11 = 0, |
56 | AHCI_PCI_BAR_CAVIUM = 0, | ||
55 | AHCI_PCI_BAR_ENMOTUS = 2, | 57 | AHCI_PCI_BAR_ENMOTUS = 2, |
56 | AHCI_PCI_BAR_STANDARD = 5, | 58 | AHCI_PCI_BAR_STANDARD = 5, |
57 | }; | 59 | }; |
@@ -1288,17 +1290,60 @@ static inline void ahci_gtf_filter_workaround(struct ata_host *host) | |||
1288 | {} | 1290 | {} |
1289 | #endif | 1291 | #endif |
1290 | 1292 | ||
1291 | static int ahci_init_interrupts(struct pci_dev *pdev, unsigned int n_ports, | 1293 | /* |
1292 | struct ahci_host_priv *hpriv) | 1294 | * ahci_init_msix() only implements single MSI-X support, not multiple |
1295 | * MSI-X per-port interrupts. This is needed for host controllers that only | ||
1296 | * have MSI-X support implemented, but no MSI or intx. | ||
1297 | */ | ||
1298 | static int ahci_init_msix(struct pci_dev *pdev, unsigned int n_ports, | ||
1299 | struct ahci_host_priv *hpriv) | ||
1293 | { | 1300 | { |
1294 | int rc, nvec; | 1301 | int rc, nvec; |
1302 | struct msix_entry entry = {}; | ||
1295 | 1303 | ||
1304 | /* Do not init MSI-X if MSI is disabled for the device */ | ||
1296 | if (hpriv->flags & AHCI_HFLAG_NO_MSI) | 1305 | if (hpriv->flags & AHCI_HFLAG_NO_MSI) |
1297 | goto intx; | 1306 | return -ENODEV; |
1307 | |||
1308 | nvec = pci_msix_vec_count(pdev); | ||
1309 | if (nvec < 0) | ||
1310 | return nvec; | ||
1311 | |||
1312 | if (!nvec) { | ||
1313 | rc = -ENODEV; | ||
1314 | goto fail; | ||
1315 | } | ||
1316 | |||
1317 | /* | ||
1318 | * There can be more than one vector (e.g. for error detection or | ||
1319 | * hdd hotplug). Only the first vector (entry.entry = 0) is used. | ||
1320 | */ | ||
1321 | rc = pci_enable_msix_exact(pdev, &entry, 1); | ||
1322 | if (rc < 0) | ||
1323 | goto fail; | ||
1324 | |||
1325 | hpriv->irq = entry.vector; | ||
1326 | |||
1327 | return 1; | ||
1328 | fail: | ||
1329 | dev_err(&pdev->dev, | ||
1330 | "failed to enable MSI-X with error %d, # of vectors: %d\n", | ||
1331 | rc, nvec); | ||
1332 | |||
1333 | return rc; | ||
1334 | } | ||
1335 | |||
1336 | static int ahci_init_msi(struct pci_dev *pdev, unsigned int n_ports, | ||
1337 | struct ahci_host_priv *hpriv) | ||
1338 | { | ||
1339 | int rc, nvec; | ||
1340 | |||
1341 | if (hpriv->flags & AHCI_HFLAG_NO_MSI) | ||
1342 | return -ENODEV; | ||
1298 | 1343 | ||
1299 | nvec = pci_msi_vec_count(pdev); | 1344 | nvec = pci_msi_vec_count(pdev); |
1300 | if (nvec < 0) | 1345 | if (nvec < 0) |
1301 | goto intx; | 1346 | return nvec; |
1302 | 1347 | ||
1303 | /* | 1348 | /* |
1304 | * If number of MSIs is less than number of ports then Sharing Last | 1349 | * If number of MSIs is less than number of ports then Sharing Last |
@@ -1311,8 +1356,8 @@ static int ahci_init_interrupts(struct pci_dev *pdev, unsigned int n_ports, | |||
1311 | rc = pci_enable_msi_exact(pdev, nvec); | 1356 | rc = pci_enable_msi_exact(pdev, nvec); |
1312 | if (rc == -ENOSPC) | 1357 | if (rc == -ENOSPC) |
1313 | goto single_msi; | 1358 | goto single_msi; |
1314 | else if (rc < 0) | 1359 | if (rc < 0) |
1315 | goto intx; | 1360 | return rc; |
1316 | 1361 | ||
1317 | /* fallback to single MSI mode if the controller enforced MRSM mode */ | 1362 | /* fallback to single MSI mode if the controller enforced MRSM mode */ |
1318 | if (readl(hpriv->mmio + HOST_CTL) & HOST_MRSM) { | 1363 | if (readl(hpriv->mmio + HOST_CTL) & HOST_MRSM) { |
@@ -1324,15 +1369,42 @@ static int ahci_init_interrupts(struct pci_dev *pdev, unsigned int n_ports, | |||
1324 | if (nvec > 1) | 1369 | if (nvec > 1) |
1325 | hpriv->flags |= AHCI_HFLAG_MULTI_MSI; | 1370 | hpriv->flags |= AHCI_HFLAG_MULTI_MSI; |
1326 | 1371 | ||
1327 | return nvec; | 1372 | goto out; |
1328 | 1373 | ||
1329 | single_msi: | 1374 | single_msi: |
1330 | if (pci_enable_msi(pdev)) | 1375 | nvec = 1; |
1331 | goto intx; | 1376 | |
1332 | return 1; | 1377 | rc = pci_enable_msi(pdev); |
1378 | if (rc < 0) | ||
1379 | return rc; | ||
1380 | out: | ||
1381 | hpriv->irq = pdev->irq; | ||
1382 | |||
1383 | return nvec; | ||
1384 | } | ||
1385 | |||
1386 | static int ahci_init_interrupts(struct pci_dev *pdev, unsigned int n_ports, | ||
1387 | struct ahci_host_priv *hpriv) | ||
1388 | { | ||
1389 | int nvec; | ||
1390 | |||
1391 | nvec = ahci_init_msi(pdev, n_ports, hpriv); | ||
1392 | if (nvec >= 0) | ||
1393 | return nvec; | ||
1394 | |||
1395 | /* | ||
1396 | * Currently, MSI-X support only implements single IRQ mode and | ||
1397 | * exists for controllers which can't do other types of IRQ. Only | ||
1398 | * set it up if MSI fails. | ||
1399 | */ | ||
1400 | nvec = ahci_init_msix(pdev, n_ports, hpriv); | ||
1401 | if (nvec >= 0) | ||
1402 | return nvec; | ||
1333 | 1403 | ||
1334 | intx: | 1404 | /* lagacy intx interrupts */ |
1335 | pci_intx(pdev, 1); | 1405 | pci_intx(pdev, 1); |
1406 | hpriv->irq = pdev->irq; | ||
1407 | |||
1336 | return 0; | 1408 | return 0; |
1337 | } | 1409 | } |
1338 | 1410 | ||
@@ -1371,11 +1443,13 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1371 | dev_info(&pdev->dev, | 1443 | dev_info(&pdev->dev, |
1372 | "PDC42819 can only drive SATA devices with this driver\n"); | 1444 | "PDC42819 can only drive SATA devices with this driver\n"); |
1373 | 1445 | ||
1374 | /* Both Connext and Enmotus devices use non-standard BARs */ | 1446 | /* Some devices use non-standard BARs */ |
1375 | if (pdev->vendor == PCI_VENDOR_ID_STMICRO && pdev->device == 0xCC06) | 1447 | if (pdev->vendor == PCI_VENDOR_ID_STMICRO && pdev->device == 0xCC06) |
1376 | ahci_pci_bar = AHCI_PCI_BAR_STA2X11; | 1448 | ahci_pci_bar = AHCI_PCI_BAR_STA2X11; |
1377 | else if (pdev->vendor == 0x1c44 && pdev->device == 0x8000) | 1449 | else if (pdev->vendor == 0x1c44 && pdev->device == 0x8000) |
1378 | ahci_pci_bar = AHCI_PCI_BAR_ENMOTUS; | 1450 | ahci_pci_bar = AHCI_PCI_BAR_ENMOTUS; |
1451 | else if (pdev->vendor == 0x177d && pdev->device == 0xa01c) | ||
1452 | ahci_pci_bar = AHCI_PCI_BAR_CAVIUM; | ||
1379 | 1453 | ||
1380 | /* | 1454 | /* |
1381 | * The JMicron chip 361/363 contains one SATA controller and one | 1455 | * The JMicron chip 361/363 contains one SATA controller and one |
@@ -1497,13 +1571,13 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1497 | */ | 1571 | */ |
1498 | n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map)); | 1572 | n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map)); |
1499 | 1573 | ||
1500 | ahci_init_interrupts(pdev, n_ports, hpriv); | ||
1501 | |||
1502 | host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports); | 1574 | host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports); |
1503 | if (!host) | 1575 | if (!host) |
1504 | return -ENOMEM; | 1576 | return -ENOMEM; |
1505 | host->private_data = hpriv; | 1577 | host->private_data = hpriv; |
1506 | 1578 | ||
1579 | ahci_init_interrupts(pdev, n_ports, hpriv); | ||
1580 | |||
1507 | if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss) | 1581 | if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss) |
1508 | host->flags |= ATA_HOST_PARALLEL_SCAN; | 1582 | host->flags |= ATA_HOST_PARALLEL_SCAN; |
1509 | else | 1583 | else |
@@ -1549,7 +1623,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1549 | 1623 | ||
1550 | pci_set_master(pdev); | 1624 | pci_set_master(pdev); |
1551 | 1625 | ||
1552 | return ahci_host_activate(host, pdev->irq, &ahci_sht); | 1626 | return ahci_host_activate(host, &ahci_sht); |
1553 | } | 1627 | } |
1554 | 1628 | ||
1555 | module_pci_driver(ahci_pci_driver); | 1629 | module_pci_driver(ahci_pci_driver); |
diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h index 71262e08648e..5b8e8a0fab48 100644 --- a/drivers/ata/ahci.h +++ b/drivers/ata/ahci.h | |||
@@ -238,6 +238,8 @@ enum { | |||
238 | AHCI_HFLAG_MULTI_MSI = (1 << 16), /* multiple PCI MSIs */ | 238 | AHCI_HFLAG_MULTI_MSI = (1 << 16), /* multiple PCI MSIs */ |
239 | AHCI_HFLAG_NO_DEVSLP = (1 << 17), /* no device sleep */ | 239 | AHCI_HFLAG_NO_DEVSLP = (1 << 17), /* no device sleep */ |
240 | AHCI_HFLAG_NO_FBS = (1 << 18), /* no FBS */ | 240 | AHCI_HFLAG_NO_FBS = (1 << 18), /* no FBS */ |
241 | AHCI_HFLAG_EDGE_IRQ = (1 << 19), /* HOST_IRQ_STAT behaves as | ||
242 | Edge Triggered */ | ||
241 | 243 | ||
242 | /* ap->flags bits */ | 244 | /* ap->flags bits */ |
243 | 245 | ||
@@ -341,6 +343,7 @@ struct ahci_host_priv { | |||
341 | struct phy **phys; | 343 | struct phy **phys; |
342 | unsigned nports; /* Number of ports */ | 344 | unsigned nports; /* Number of ports */ |
343 | void *plat_data; /* Other platform data */ | 345 | void *plat_data; /* Other platform data */ |
346 | unsigned int irq; /* interrupt line */ | ||
344 | /* | 347 | /* |
345 | * Optional ahci_start_engine override, if not set this gets set to the | 348 | * Optional ahci_start_engine override, if not set this gets set to the |
346 | * default ahci_start_engine during ahci_save_initial_config, this can | 349 | * default ahci_start_engine during ahci_save_initial_config, this can |
@@ -393,8 +396,7 @@ void ahci_set_em_messages(struct ahci_host_priv *hpriv, | |||
393 | struct ata_port_info *pi); | 396 | struct ata_port_info *pi); |
394 | int ahci_reset_em(struct ata_host *host); | 397 | int ahci_reset_em(struct ata_host *host); |
395 | void ahci_print_info(struct ata_host *host, const char *scc_s); | 398 | void ahci_print_info(struct ata_host *host, const char *scc_s); |
396 | int ahci_host_activate(struct ata_host *host, int irq, | 399 | int ahci_host_activate(struct ata_host *host, struct scsi_host_template *sht); |
397 | struct scsi_host_template *sht); | ||
398 | void ahci_error_handler(struct ata_port *ap); | 400 | void ahci_error_handler(struct ata_port *ap); |
399 | 401 | ||
400 | static inline void __iomem *__ahci_port_base(struct ata_host *host, | 402 | static inline void __iomem *__ahci_port_base(struct ata_host *host, |
diff --git a/drivers/ata/ahci_brcmstb.c b/drivers/ata/ahci_brcmstb.c new file mode 100644 index 000000000000..ce1e3a885981 --- /dev/null +++ b/drivers/ata/ahci_brcmstb.c | |||
@@ -0,0 +1,322 @@ | |||
1 | /* | ||
2 | * Broadcom SATA3 AHCI Controller Driver | ||
3 | * | ||
4 | * Copyright © 2009-2015 Broadcom Corporation | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2, or (at your option) | ||
9 | * any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | */ | ||
16 | |||
17 | #include <linux/ahci_platform.h> | ||
18 | #include <linux/compiler.h> | ||
19 | #include <linux/device.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/io.h> | ||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/libata.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/of.h> | ||
27 | #include <linux/platform_device.h> | ||
28 | #include <linux/string.h> | ||
29 | |||
30 | #include "ahci.h" | ||
31 | |||
32 | #define DRV_NAME "brcm-ahci" | ||
33 | |||
34 | #define SATA_TOP_CTRL_VERSION 0x0 | ||
35 | #define SATA_TOP_CTRL_BUS_CTRL 0x4 | ||
36 | #define MMIO_ENDIAN_SHIFT 0 /* CPU->AHCI */ | ||
37 | #define DMADESC_ENDIAN_SHIFT 2 /* AHCI->DDR */ | ||
38 | #define DMADATA_ENDIAN_SHIFT 4 /* AHCI->DDR */ | ||
39 | #define PIODATA_ENDIAN_SHIFT 6 | ||
40 | #define ENDIAN_SWAP_NONE 0 | ||
41 | #define ENDIAN_SWAP_FULL 2 | ||
42 | #define OVERRIDE_HWINIT BIT(16) | ||
43 | #define SATA_TOP_CTRL_TP_CTRL 0x8 | ||
44 | #define SATA_TOP_CTRL_PHY_CTRL 0xc | ||
45 | #define SATA_TOP_CTRL_PHY_CTRL_1 0x0 | ||
46 | #define SATA_TOP_CTRL_1_PHY_DEFAULT_POWER_STATE BIT(14) | ||
47 | #define SATA_TOP_CTRL_PHY_CTRL_2 0x4 | ||
48 | #define SATA_TOP_CTRL_2_SW_RST_MDIOREG BIT(0) | ||
49 | #define SATA_TOP_CTRL_2_SW_RST_OOB BIT(1) | ||
50 | #define SATA_TOP_CTRL_2_SW_RST_RX BIT(2) | ||
51 | #define SATA_TOP_CTRL_2_SW_RST_TX BIT(3) | ||
52 | #define SATA_TOP_CTRL_2_PHY_GLOBAL_RESET BIT(14) | ||
53 | #define SATA_TOP_CTRL_PHY_OFFS 0x8 | ||
54 | #define SATA_TOP_MAX_PHYS 2 | ||
55 | #define SATA_TOP_CTRL_SATA_TP_OUT 0x1c | ||
56 | #define SATA_TOP_CTRL_CLIENT_INIT_CTRL 0x20 | ||
57 | |||
58 | /* On big-endian MIPS, buses are reversed to big endian, so switch them back */ | ||
59 | #if defined(CONFIG_MIPS) && defined(__BIG_ENDIAN) | ||
60 | #define DATA_ENDIAN 2 /* AHCI->DDR inbound accesses */ | ||
61 | #define MMIO_ENDIAN 2 /* CPU->AHCI outbound accesses */ | ||
62 | #else | ||
63 | #define DATA_ENDIAN 0 | ||
64 | #define MMIO_ENDIAN 0 | ||
65 | #endif | ||
66 | |||
67 | #define BUS_CTRL_ENDIAN_CONF \ | ||
68 | ((DATA_ENDIAN << DMADATA_ENDIAN_SHIFT) | \ | ||
69 | (DATA_ENDIAN << DMADESC_ENDIAN_SHIFT) | \ | ||
70 | (MMIO_ENDIAN << MMIO_ENDIAN_SHIFT)) | ||
71 | |||
72 | struct brcm_ahci_priv { | ||
73 | struct device *dev; | ||
74 | void __iomem *top_ctrl; | ||
75 | u32 port_mask; | ||
76 | }; | ||
77 | |||
78 | static const struct ata_port_info ahci_brcm_port_info = { | ||
79 | .flags = AHCI_FLAG_COMMON, | ||
80 | .pio_mask = ATA_PIO4, | ||
81 | .udma_mask = ATA_UDMA6, | ||
82 | .port_ops = &ahci_platform_ops, | ||
83 | }; | ||
84 | |||
85 | static inline u32 brcm_sata_readreg(void __iomem *addr) | ||
86 | { | ||
87 | /* | ||
88 | * MIPS endianness is configured by boot strap, which also reverses all | ||
89 | * bus endianness (i.e., big-endian CPU + big endian bus ==> native | ||
90 | * endian I/O). | ||
91 | * | ||
92 | * Other architectures (e.g., ARM) either do not support big endian, or | ||
93 | * else leave I/O in little endian mode. | ||
94 | */ | ||
95 | if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(__BIG_ENDIAN)) | ||
96 | return __raw_readl(addr); | ||
97 | else | ||
98 | return readl_relaxed(addr); | ||
99 | } | ||
100 | |||
101 | static inline void brcm_sata_writereg(u32 val, void __iomem *addr) | ||
102 | { | ||
103 | /* See brcm_sata_readreg() comments */ | ||
104 | if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(__BIG_ENDIAN)) | ||
105 | __raw_writel(val, addr); | ||
106 | else | ||
107 | writel_relaxed(val, addr); | ||
108 | } | ||
109 | |||
110 | static void brcm_sata_phy_enable(struct brcm_ahci_priv *priv, int port) | ||
111 | { | ||
112 | void __iomem *phyctrl = priv->top_ctrl + SATA_TOP_CTRL_PHY_CTRL + | ||
113 | (port * SATA_TOP_CTRL_PHY_OFFS); | ||
114 | void __iomem *p; | ||
115 | u32 reg; | ||
116 | |||
117 | /* clear PHY_DEFAULT_POWER_STATE */ | ||
118 | p = phyctrl + SATA_TOP_CTRL_PHY_CTRL_1; | ||
119 | reg = brcm_sata_readreg(p); | ||
120 | reg &= ~SATA_TOP_CTRL_1_PHY_DEFAULT_POWER_STATE; | ||
121 | brcm_sata_writereg(reg, p); | ||
122 | |||
123 | /* reset the PHY digital logic */ | ||
124 | p = phyctrl + SATA_TOP_CTRL_PHY_CTRL_2; | ||
125 | reg = brcm_sata_readreg(p); | ||
126 | reg &= ~(SATA_TOP_CTRL_2_SW_RST_MDIOREG | SATA_TOP_CTRL_2_SW_RST_OOB | | ||
127 | SATA_TOP_CTRL_2_SW_RST_RX); | ||
128 | reg |= SATA_TOP_CTRL_2_SW_RST_TX; | ||
129 | brcm_sata_writereg(reg, p); | ||
130 | reg = brcm_sata_readreg(p); | ||
131 | reg |= SATA_TOP_CTRL_2_PHY_GLOBAL_RESET; | ||
132 | brcm_sata_writereg(reg, p); | ||
133 | reg = brcm_sata_readreg(p); | ||
134 | reg &= ~SATA_TOP_CTRL_2_PHY_GLOBAL_RESET; | ||
135 | brcm_sata_writereg(reg, p); | ||
136 | (void)brcm_sata_readreg(p); | ||
137 | } | ||
138 | |||
139 | static void brcm_sata_phy_disable(struct brcm_ahci_priv *priv, int port) | ||
140 | { | ||
141 | void __iomem *phyctrl = priv->top_ctrl + SATA_TOP_CTRL_PHY_CTRL + | ||
142 | (port * SATA_TOP_CTRL_PHY_OFFS); | ||
143 | void __iomem *p; | ||
144 | u32 reg; | ||
145 | |||
146 | /* power-off the PHY digital logic */ | ||
147 | p = phyctrl + SATA_TOP_CTRL_PHY_CTRL_2; | ||
148 | reg = brcm_sata_readreg(p); | ||
149 | reg |= (SATA_TOP_CTRL_2_SW_RST_MDIOREG | SATA_TOP_CTRL_2_SW_RST_OOB | | ||
150 | SATA_TOP_CTRL_2_SW_RST_RX | SATA_TOP_CTRL_2_SW_RST_TX | | ||
151 | SATA_TOP_CTRL_2_PHY_GLOBAL_RESET); | ||
152 | brcm_sata_writereg(reg, p); | ||
153 | |||
154 | /* set PHY_DEFAULT_POWER_STATE */ | ||
155 | p = phyctrl + SATA_TOP_CTRL_PHY_CTRL_1; | ||
156 | reg = brcm_sata_readreg(p); | ||
157 | reg |= SATA_TOP_CTRL_1_PHY_DEFAULT_POWER_STATE; | ||
158 | brcm_sata_writereg(reg, p); | ||
159 | } | ||
160 | |||
161 | static void brcm_sata_phys_enable(struct brcm_ahci_priv *priv) | ||
162 | { | ||
163 | int i; | ||
164 | |||
165 | for (i = 0; i < SATA_TOP_MAX_PHYS; i++) | ||
166 | if (priv->port_mask & BIT(i)) | ||
167 | brcm_sata_phy_enable(priv, i); | ||
168 | } | ||
169 | |||
170 | static void brcm_sata_phys_disable(struct brcm_ahci_priv *priv) | ||
171 | { | ||
172 | int i; | ||
173 | |||
174 | for (i = 0; i < SATA_TOP_MAX_PHYS; i++) | ||
175 | if (priv->port_mask & BIT(i)) | ||
176 | brcm_sata_phy_disable(priv, i); | ||
177 | } | ||
178 | |||
179 | static u32 brcm_ahci_get_portmask(struct platform_device *pdev, | ||
180 | struct brcm_ahci_priv *priv) | ||
181 | { | ||
182 | void __iomem *ahci; | ||
183 | struct resource *res; | ||
184 | u32 impl; | ||
185 | |||
186 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ahci"); | ||
187 | ahci = devm_ioremap_resource(&pdev->dev, res); | ||
188 | if (IS_ERR(ahci)) | ||
189 | return 0; | ||
190 | |||
191 | impl = readl(ahci + HOST_PORTS_IMPL); | ||
192 | |||
193 | if (fls(impl) > SATA_TOP_MAX_PHYS) | ||
194 | dev_warn(priv->dev, "warning: more ports than PHYs (%#x)\n", | ||
195 | impl); | ||
196 | else if (!impl) | ||
197 | dev_info(priv->dev, "no ports found\n"); | ||
198 | |||
199 | devm_iounmap(&pdev->dev, ahci); | ||
200 | devm_release_mem_region(&pdev->dev, res->start, resource_size(res)); | ||
201 | |||
202 | return impl; | ||
203 | } | ||
204 | |||
205 | static void brcm_sata_init(struct brcm_ahci_priv *priv) | ||
206 | { | ||
207 | /* Configure endianness */ | ||
208 | brcm_sata_writereg(BUS_CTRL_ENDIAN_CONF, | ||
209 | priv->top_ctrl + SATA_TOP_CTRL_BUS_CTRL); | ||
210 | } | ||
211 | |||
212 | static int brcm_ahci_suspend(struct device *dev) | ||
213 | { | ||
214 | struct ata_host *host = dev_get_drvdata(dev); | ||
215 | struct ahci_host_priv *hpriv = host->private_data; | ||
216 | struct brcm_ahci_priv *priv = hpriv->plat_data; | ||
217 | int ret; | ||
218 | |||
219 | ret = ahci_platform_suspend(dev); | ||
220 | brcm_sata_phys_disable(priv); | ||
221 | return ret; | ||
222 | } | ||
223 | |||
224 | static int brcm_ahci_resume(struct device *dev) | ||
225 | { | ||
226 | struct ata_host *host = dev_get_drvdata(dev); | ||
227 | struct ahci_host_priv *hpriv = host->private_data; | ||
228 | struct brcm_ahci_priv *priv = hpriv->plat_data; | ||
229 | |||
230 | brcm_sata_init(priv); | ||
231 | brcm_sata_phys_enable(priv); | ||
232 | return ahci_platform_resume(dev); | ||
233 | } | ||
234 | |||
235 | static struct scsi_host_template ahci_platform_sht = { | ||
236 | AHCI_SHT(DRV_NAME), | ||
237 | }; | ||
238 | |||
239 | static int brcm_ahci_probe(struct platform_device *pdev) | ||
240 | { | ||
241 | struct device *dev = &pdev->dev; | ||
242 | struct brcm_ahci_priv *priv; | ||
243 | struct ahci_host_priv *hpriv; | ||
244 | struct resource *res; | ||
245 | int ret; | ||
246 | |||
247 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); | ||
248 | if (!priv) | ||
249 | return -ENOMEM; | ||
250 | priv->dev = dev; | ||
251 | |||
252 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "top-ctrl"); | ||
253 | priv->top_ctrl = devm_ioremap_resource(dev, res); | ||
254 | if (IS_ERR(priv->top_ctrl)) | ||
255 | return PTR_ERR(priv->top_ctrl); | ||
256 | |||
257 | brcm_sata_init(priv); | ||
258 | |||
259 | priv->port_mask = brcm_ahci_get_portmask(pdev, priv); | ||
260 | if (!priv->port_mask) | ||
261 | return -ENODEV; | ||
262 | |||
263 | brcm_sata_phys_enable(priv); | ||
264 | |||
265 | hpriv = ahci_platform_get_resources(pdev); | ||
266 | if (IS_ERR(hpriv)) | ||
267 | return PTR_ERR(hpriv); | ||
268 | hpriv->plat_data = priv; | ||
269 | |||
270 | ret = ahci_platform_enable_resources(hpriv); | ||
271 | if (ret) | ||
272 | return ret; | ||
273 | |||
274 | ret = ahci_platform_init_host(pdev, hpriv, &ahci_brcm_port_info, | ||
275 | &ahci_platform_sht); | ||
276 | if (ret) | ||
277 | return ret; | ||
278 | |||
279 | dev_info(dev, "Broadcom AHCI SATA3 registered\n"); | ||
280 | |||
281 | return 0; | ||
282 | } | ||
283 | |||
284 | static int brcm_ahci_remove(struct platform_device *pdev) | ||
285 | { | ||
286 | struct ata_host *host = dev_get_drvdata(&pdev->dev); | ||
287 | struct ahci_host_priv *hpriv = host->private_data; | ||
288 | struct brcm_ahci_priv *priv = hpriv->plat_data; | ||
289 | int ret; | ||
290 | |||
291 | ret = ata_platform_remove_one(pdev); | ||
292 | if (ret) | ||
293 | return ret; | ||
294 | |||
295 | brcm_sata_phys_disable(priv); | ||
296 | |||
297 | return 0; | ||
298 | } | ||
299 | |||
300 | static const struct of_device_id ahci_of_match[] = { | ||
301 | {.compatible = "brcm,bcm7445-ahci"}, | ||
302 | {}, | ||
303 | }; | ||
304 | MODULE_DEVICE_TABLE(of, ahci_of_match); | ||
305 | |||
306 | static SIMPLE_DEV_PM_OPS(ahci_brcm_pm_ops, brcm_ahci_suspend, brcm_ahci_resume); | ||
307 | |||
308 | static struct platform_driver brcm_ahci_driver = { | ||
309 | .probe = brcm_ahci_probe, | ||
310 | .remove = brcm_ahci_remove, | ||
311 | .driver = { | ||
312 | .name = DRV_NAME, | ||
313 | .of_match_table = ahci_of_match, | ||
314 | .pm = &ahci_brcm_pm_ops, | ||
315 | }, | ||
316 | }; | ||
317 | module_platform_driver(brcm_ahci_driver); | ||
318 | |||
319 | MODULE_DESCRIPTION("Broadcom SATA3 AHCI Controller Driver"); | ||
320 | MODULE_AUTHOR("Brian Norris"); | ||
321 | MODULE_LICENSE("GPL"); | ||
322 | MODULE_ALIAS("platform:sata-brcmstb"); | ||
diff --git a/drivers/ata/ahci_ceva.c b/drivers/ata/ahci_ceva.c new file mode 100644 index 000000000000..207649d323c5 --- /dev/null +++ b/drivers/ata/ahci_ceva.c | |||
@@ -0,0 +1,238 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2015 Xilinx, Inc. | ||
3 | * CEVA AHCI SATA platform driver | ||
4 | * | ||
5 | * based on the AHCI SATA platform driver by Jeff Garzik and Anton Vorontsov | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms and conditions of the GNU General Public License, | ||
9 | * version 2, as published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
14 | * more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along with | ||
17 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
18 | */ | ||
19 | |||
20 | #include <linux/ahci_platform.h> | ||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/libata.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/of_device.h> | ||
25 | #include <linux/platform_device.h> | ||
26 | #include "ahci.h" | ||
27 | |||
28 | /* Vendor Specific Register Offsets */ | ||
29 | #define AHCI_VEND_PCFG 0xA4 | ||
30 | #define AHCI_VEND_PPCFG 0xA8 | ||
31 | #define AHCI_VEND_PP2C 0xAC | ||
32 | #define AHCI_VEND_PP3C 0xB0 | ||
33 | #define AHCI_VEND_PP4C 0xB4 | ||
34 | #define AHCI_VEND_PP5C 0xB8 | ||
35 | #define AHCI_VEND_PAXIC 0xC0 | ||
36 | #define AHCI_VEND_PTC 0xC8 | ||
37 | |||
38 | /* Vendor Specific Register bit definitions */ | ||
39 | #define PAXIC_ADBW_BW64 0x1 | ||
40 | #define PAXIC_MAWIDD (1 << 8) | ||
41 | #define PAXIC_MARIDD (1 << 16) | ||
42 | #define PAXIC_OTL (0x4 << 20) | ||
43 | |||
44 | #define PCFG_TPSS_VAL (0x32 << 16) | ||
45 | #define PCFG_TPRS_VAL (0x2 << 12) | ||
46 | #define PCFG_PAD_VAL 0x2 | ||
47 | |||
48 | #define PPCFG_TTA 0x1FFFE | ||
49 | #define PPCFG_PSSO_EN (1 << 28) | ||
50 | #define PPCFG_PSS_EN (1 << 29) | ||
51 | #define PPCFG_ESDF_EN (1 << 31) | ||
52 | |||
53 | #define PP2C_CIBGMN 0x0F | ||
54 | #define PP2C_CIBGMX (0x25 << 8) | ||
55 | #define PP2C_CIBGN (0x18 << 16) | ||
56 | #define PP2C_CINMP (0x29 << 24) | ||
57 | |||
58 | #define PP3C_CWBGMN 0x04 | ||
59 | #define PP3C_CWBGMX (0x0B << 8) | ||
60 | #define PP3C_CWBGN (0x08 << 16) | ||
61 | #define PP3C_CWNMP (0x0F << 24) | ||
62 | |||
63 | #define PP4C_BMX 0x0a | ||
64 | #define PP4C_BNM (0x08 << 8) | ||
65 | #define PP4C_SFD (0x4a << 16) | ||
66 | #define PP4C_PTST (0x06 << 24) | ||
67 | |||
68 | #define PP5C_RIT 0x60216 | ||
69 | #define PP5C_RCT (0x7f0 << 20) | ||
70 | |||
71 | #define PTC_RX_WM_VAL 0x40 | ||
72 | #define PTC_RSVD (1 << 27) | ||
73 | |||
74 | #define PORT0_BASE 0x100 | ||
75 | #define PORT1_BASE 0x180 | ||
76 | |||
77 | /* Port Control Register Bit Definitions */ | ||
78 | #define PORT_SCTL_SPD_GEN2 (0x2 << 4) | ||
79 | #define PORT_SCTL_SPD_GEN1 (0x1 << 4) | ||
80 | #define PORT_SCTL_IPM (0x3 << 8) | ||
81 | |||
82 | #define PORT_BASE 0x100 | ||
83 | #define PORT_OFFSET 0x80 | ||
84 | #define NR_PORTS 2 | ||
85 | #define DRV_NAME "ahci-ceva" | ||
86 | #define CEVA_FLAG_BROKEN_GEN2 1 | ||
87 | |||
88 | struct ceva_ahci_priv { | ||
89 | struct platform_device *ahci_pdev; | ||
90 | int flags; | ||
91 | }; | ||
92 | |||
93 | static struct ata_port_operations ahci_ceva_ops = { | ||
94 | .inherits = &ahci_platform_ops, | ||
95 | }; | ||
96 | |||
97 | static const struct ata_port_info ahci_ceva_port_info = { | ||
98 | .flags = AHCI_FLAG_COMMON, | ||
99 | .pio_mask = ATA_PIO4, | ||
100 | .udma_mask = ATA_UDMA6, | ||
101 | .port_ops = &ahci_ceva_ops, | ||
102 | }; | ||
103 | |||
104 | static void ahci_ceva_setup(struct ahci_host_priv *hpriv) | ||
105 | { | ||
106 | void __iomem *mmio = hpriv->mmio; | ||
107 | struct ceva_ahci_priv *cevapriv = hpriv->plat_data; | ||
108 | u32 tmp; | ||
109 | int i; | ||
110 | |||
111 | /* | ||
112 | * AXI Data bus width to 64 | ||
113 | * Set Mem Addr Read, Write ID for data transfers | ||
114 | * Transfer limit to 72 DWord | ||
115 | */ | ||
116 | tmp = PAXIC_ADBW_BW64 | PAXIC_MAWIDD | PAXIC_MARIDD | PAXIC_OTL; | ||
117 | writel(tmp, mmio + AHCI_VEND_PAXIC); | ||
118 | |||
119 | /* Set AHCI Enable */ | ||
120 | tmp = readl(mmio + HOST_CTL); | ||
121 | tmp |= HOST_AHCI_EN; | ||
122 | writel(tmp, mmio + HOST_CTL); | ||
123 | |||
124 | for (i = 0; i < NR_PORTS; i++) { | ||
125 | /* TPSS TPRS scalars, CISE and Port Addr */ | ||
126 | tmp = PCFG_TPSS_VAL | PCFG_TPRS_VAL | (PCFG_PAD_VAL + i); | ||
127 | writel(tmp, mmio + AHCI_VEND_PCFG); | ||
128 | |||
129 | /* Port Phy Cfg register enables */ | ||
130 | tmp = PPCFG_TTA | PPCFG_PSS_EN | PPCFG_ESDF_EN; | ||
131 | writel(tmp, mmio + AHCI_VEND_PPCFG); | ||
132 | |||
133 | /* Phy Control OOB timing parameters COMINIT */ | ||
134 | tmp = PP2C_CIBGMN | PP2C_CIBGMX | PP2C_CIBGN | PP2C_CINMP; | ||
135 | writel(tmp, mmio + AHCI_VEND_PP2C); | ||
136 | |||
137 | /* Phy Control OOB timing parameters COMWAKE */ | ||
138 | tmp = PP3C_CWBGMN | PP3C_CWBGMX | PP3C_CWBGN | PP3C_CWNMP; | ||
139 | writel(tmp, mmio + AHCI_VEND_PP3C); | ||
140 | |||
141 | /* Phy Control Burst timing setting */ | ||
142 | tmp = PP4C_BMX | PP4C_BNM | PP4C_SFD | PP4C_PTST; | ||
143 | writel(tmp, mmio + AHCI_VEND_PP4C); | ||
144 | |||
145 | /* Rate Change Timer and Retry Interval Timer setting */ | ||
146 | tmp = PP5C_RIT | PP5C_RCT; | ||
147 | writel(tmp, mmio + AHCI_VEND_PP5C); | ||
148 | |||
149 | /* Rx Watermark setting */ | ||
150 | tmp = PTC_RX_WM_VAL | PTC_RSVD; | ||
151 | writel(tmp, mmio + AHCI_VEND_PTC); | ||
152 | |||
153 | /* Default to Gen 2 Speed and Gen 1 if Gen2 is broken */ | ||
154 | tmp = PORT_SCTL_SPD_GEN2 | PORT_SCTL_IPM; | ||
155 | if (cevapriv->flags & CEVA_FLAG_BROKEN_GEN2) | ||
156 | tmp = PORT_SCTL_SPD_GEN1 | PORT_SCTL_IPM; | ||
157 | writel(tmp, mmio + PORT_SCR_CTL + PORT_BASE + PORT_OFFSET * i); | ||
158 | } | ||
159 | } | ||
160 | |||
161 | static struct scsi_host_template ahci_platform_sht = { | ||
162 | AHCI_SHT(DRV_NAME), | ||
163 | }; | ||
164 | |||
165 | static int ceva_ahci_probe(struct platform_device *pdev) | ||
166 | { | ||
167 | struct device_node *np = pdev->dev.of_node; | ||
168 | struct device *dev = &pdev->dev; | ||
169 | struct ahci_host_priv *hpriv; | ||
170 | struct ceva_ahci_priv *cevapriv; | ||
171 | int rc; | ||
172 | |||
173 | cevapriv = devm_kzalloc(dev, sizeof(*cevapriv), GFP_KERNEL); | ||
174 | if (!cevapriv) | ||
175 | return -ENOMEM; | ||
176 | |||
177 | cevapriv->ahci_pdev = pdev; | ||
178 | |||
179 | hpriv = ahci_platform_get_resources(pdev); | ||
180 | if (IS_ERR(hpriv)) | ||
181 | return PTR_ERR(hpriv); | ||
182 | |||
183 | rc = ahci_platform_enable_resources(hpriv); | ||
184 | if (rc) | ||
185 | return rc; | ||
186 | |||
187 | if (of_property_read_bool(np, "ceva,broken-gen2")) | ||
188 | cevapriv->flags = CEVA_FLAG_BROKEN_GEN2; | ||
189 | |||
190 | hpriv->plat_data = cevapriv; | ||
191 | |||
192 | /* CEVA specific initialization */ | ||
193 | ahci_ceva_setup(hpriv); | ||
194 | |||
195 | rc = ahci_platform_init_host(pdev, hpriv, &ahci_ceva_port_info, | ||
196 | &ahci_platform_sht); | ||
197 | if (rc) | ||
198 | goto disable_resources; | ||
199 | |||
200 | return 0; | ||
201 | |||
202 | disable_resources: | ||
203 | ahci_platform_disable_resources(hpriv); | ||
204 | return rc; | ||
205 | } | ||
206 | |||
207 | static int __maybe_unused ceva_ahci_suspend(struct device *dev) | ||
208 | { | ||
209 | return ahci_platform_suspend_host(dev); | ||
210 | } | ||
211 | |||
212 | static int __maybe_unused ceva_ahci_resume(struct device *dev) | ||
213 | { | ||
214 | return ahci_platform_resume_host(dev); | ||
215 | } | ||
216 | |||
217 | static SIMPLE_DEV_PM_OPS(ahci_ceva_pm_ops, ceva_ahci_suspend, ceva_ahci_resume); | ||
218 | |||
219 | static const struct of_device_id ceva_ahci_of_match[] = { | ||
220 | { .compatible = "ceva,ahci-1v84" }, | ||
221 | {}, | ||
222 | }; | ||
223 | MODULE_DEVICE_TABLE(of, ceva_ahci_of_match); | ||
224 | |||
225 | static struct platform_driver ceva_ahci_driver = { | ||
226 | .probe = ceva_ahci_probe, | ||
227 | .remove = ata_platform_remove_one, | ||
228 | .driver = { | ||
229 | .name = DRV_NAME, | ||
230 | .of_match_table = ceva_ahci_of_match, | ||
231 | .pm = &ahci_ceva_pm_ops, | ||
232 | }, | ||
233 | }; | ||
234 | module_platform_driver(ceva_ahci_driver); | ||
235 | |||
236 | MODULE_DESCRIPTION("CEVA AHCI SATA platform driver"); | ||
237 | MODULE_AUTHOR("Xilinx Inc."); | ||
238 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/ata/ahci_mvebu.c b/drivers/ata/ahci_mvebu.c index 5928d0746a27..8490d37aee2a 100644 --- a/drivers/ata/ahci_mvebu.c +++ b/drivers/ata/ahci_mvebu.c | |||
@@ -62,6 +62,26 @@ static void ahci_mvebu_regret_option(struct ahci_host_priv *hpriv) | |||
62 | writel(0x80, hpriv->mmio + AHCI_VENDOR_SPECIFIC_0_DATA); | 62 | writel(0x80, hpriv->mmio + AHCI_VENDOR_SPECIFIC_0_DATA); |
63 | } | 63 | } |
64 | 64 | ||
65 | static int ahci_mvebu_suspend(struct platform_device *pdev, pm_message_t state) | ||
66 | { | ||
67 | return ahci_platform_suspend_host(&pdev->dev); | ||
68 | } | ||
69 | |||
70 | static int ahci_mvebu_resume(struct platform_device *pdev) | ||
71 | { | ||
72 | struct ata_host *host = platform_get_drvdata(pdev); | ||
73 | struct ahci_host_priv *hpriv = host->private_data; | ||
74 | const struct mbus_dram_target_info *dram; | ||
75 | |||
76 | dram = mv_mbus_dram_info(); | ||
77 | if (dram) | ||
78 | ahci_mvebu_mbus_config(hpriv, dram); | ||
79 | |||
80 | ahci_mvebu_regret_option(hpriv); | ||
81 | |||
82 | return ahci_platform_resume_host(&pdev->dev); | ||
83 | } | ||
84 | |||
65 | static const struct ata_port_info ahci_mvebu_port_info = { | 85 | static const struct ata_port_info ahci_mvebu_port_info = { |
66 | .flags = AHCI_FLAG_COMMON, | 86 | .flags = AHCI_FLAG_COMMON, |
67 | .pio_mask = ATA_PIO4, | 87 | .pio_mask = ATA_PIO4, |
@@ -120,6 +140,8 @@ MODULE_DEVICE_TABLE(of, ahci_mvebu_of_match); | |||
120 | static struct platform_driver ahci_mvebu_driver = { | 140 | static struct platform_driver ahci_mvebu_driver = { |
121 | .probe = ahci_mvebu_probe, | 141 | .probe = ahci_mvebu_probe, |
122 | .remove = ata_platform_remove_one, | 142 | .remove = ata_platform_remove_one, |
143 | .suspend = ahci_mvebu_suspend, | ||
144 | .resume = ahci_mvebu_resume, | ||
123 | .driver = { | 145 | .driver = { |
124 | .name = DRV_NAME, | 146 | .name = DRV_NAME, |
125 | .of_match_table = ahci_mvebu_of_match, | 147 | .of_match_table = ahci_mvebu_of_match, |
diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c index 78d6ae0b90c4..614c78f510f0 100644 --- a/drivers/ata/ahci_platform.c +++ b/drivers/ata/ahci_platform.c | |||
@@ -74,6 +74,7 @@ static const struct of_device_id ahci_of_match[] = { | |||
74 | { .compatible = "ibm,476gtr-ahci", }, | 74 | { .compatible = "ibm,476gtr-ahci", }, |
75 | { .compatible = "snps,dwc-ahci", }, | 75 | { .compatible = "snps,dwc-ahci", }, |
76 | { .compatible = "hisilicon,hisi-ahci", }, | 76 | { .compatible = "hisilicon,hisi-ahci", }, |
77 | { .compatible = "fsl,qoriq-ahci", }, | ||
77 | {}, | 78 | {}, |
78 | }; | 79 | }; |
79 | MODULE_DEVICE_TABLE(of, ahci_of_match); | 80 | MODULE_DEVICE_TABLE(of, ahci_of_match); |
diff --git a/drivers/ata/ahci_xgene.c b/drivers/ata/ahci_xgene.c index 2b78510d94dd..e2c6d9e0c5ac 100644 --- a/drivers/ata/ahci_xgene.c +++ b/drivers/ata/ahci_xgene.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/platform_device.h> | 27 | #include <linux/platform_device.h> |
28 | #include <linux/ahci_platform.h> | 28 | #include <linux/ahci_platform.h> |
29 | #include <linux/of_address.h> | 29 | #include <linux/of_address.h> |
30 | #include <linux/of_device.h> | ||
30 | #include <linux/of_irq.h> | 31 | #include <linux/of_irq.h> |
31 | #include <linux/phy/phy.h> | 32 | #include <linux/phy/phy.h> |
32 | #include "ahci.h" | 33 | #include "ahci.h" |
@@ -84,6 +85,11 @@ | |||
84 | /* Max retry for link down */ | 85 | /* Max retry for link down */ |
85 | #define MAX_LINK_DOWN_RETRY 3 | 86 | #define MAX_LINK_DOWN_RETRY 3 |
86 | 87 | ||
88 | enum xgene_ahci_version { | ||
89 | XGENE_AHCI_V1 = 1, | ||
90 | XGENE_AHCI_V2, | ||
91 | }; | ||
92 | |||
87 | struct xgene_ahci_context { | 93 | struct xgene_ahci_context { |
88 | struct ahci_host_priv *hpriv; | 94 | struct ahci_host_priv *hpriv; |
89 | struct device *dev; | 95 | struct device *dev; |
@@ -542,7 +548,7 @@ softreset_retry: | |||
542 | return rc; | 548 | return rc; |
543 | } | 549 | } |
544 | 550 | ||
545 | static struct ata_port_operations xgene_ahci_ops = { | 551 | static struct ata_port_operations xgene_ahci_v1_ops = { |
546 | .inherits = &ahci_ops, | 552 | .inherits = &ahci_ops, |
547 | .host_stop = xgene_ahci_host_stop, | 553 | .host_stop = xgene_ahci_host_stop, |
548 | .hardreset = xgene_ahci_hardreset, | 554 | .hardreset = xgene_ahci_hardreset, |
@@ -552,11 +558,25 @@ static struct ata_port_operations xgene_ahci_ops = { | |||
552 | .pmp_softreset = xgene_ahci_pmp_softreset | 558 | .pmp_softreset = xgene_ahci_pmp_softreset |
553 | }; | 559 | }; |
554 | 560 | ||
555 | static const struct ata_port_info xgene_ahci_port_info = { | 561 | static const struct ata_port_info xgene_ahci_v1_port_info = { |
562 | .flags = AHCI_FLAG_COMMON | ATA_FLAG_PMP, | ||
563 | .pio_mask = ATA_PIO4, | ||
564 | .udma_mask = ATA_UDMA6, | ||
565 | .port_ops = &xgene_ahci_v1_ops, | ||
566 | }; | ||
567 | |||
568 | static struct ata_port_operations xgene_ahci_v2_ops = { | ||
569 | .inherits = &ahci_ops, | ||
570 | .host_stop = xgene_ahci_host_stop, | ||
571 | .hardreset = xgene_ahci_hardreset, | ||
572 | .read_id = xgene_ahci_read_id, | ||
573 | }; | ||
574 | |||
575 | static const struct ata_port_info xgene_ahci_v2_port_info = { | ||
556 | .flags = AHCI_FLAG_COMMON | ATA_FLAG_PMP, | 576 | .flags = AHCI_FLAG_COMMON | ATA_FLAG_PMP, |
557 | .pio_mask = ATA_PIO4, | 577 | .pio_mask = ATA_PIO4, |
558 | .udma_mask = ATA_UDMA6, | 578 | .udma_mask = ATA_UDMA6, |
559 | .port_ops = &xgene_ahci_ops, | 579 | .port_ops = &xgene_ahci_v2_ops, |
560 | }; | 580 | }; |
561 | 581 | ||
562 | static int xgene_ahci_hw_init(struct ahci_host_priv *hpriv) | 582 | static int xgene_ahci_hw_init(struct ahci_host_priv *hpriv) |
@@ -629,12 +649,32 @@ static struct scsi_host_template ahci_platform_sht = { | |||
629 | AHCI_SHT(DRV_NAME), | 649 | AHCI_SHT(DRV_NAME), |
630 | }; | 650 | }; |
631 | 651 | ||
652 | #ifdef CONFIG_ACPI | ||
653 | static const struct acpi_device_id xgene_ahci_acpi_match[] = { | ||
654 | { "APMC0D0D", XGENE_AHCI_V1}, | ||
655 | { "APMC0D32", XGENE_AHCI_V2}, | ||
656 | {}, | ||
657 | }; | ||
658 | MODULE_DEVICE_TABLE(acpi, xgene_ahci_acpi_match); | ||
659 | #endif | ||
660 | |||
661 | static const struct of_device_id xgene_ahci_of_match[] = { | ||
662 | {.compatible = "apm,xgene-ahci", .data = (void *) XGENE_AHCI_V1}, | ||
663 | {.compatible = "apm,xgene-ahci-v2", .data = (void *) XGENE_AHCI_V2}, | ||
664 | {}, | ||
665 | }; | ||
666 | MODULE_DEVICE_TABLE(of, xgene_ahci_of_match); | ||
667 | |||
632 | static int xgene_ahci_probe(struct platform_device *pdev) | 668 | static int xgene_ahci_probe(struct platform_device *pdev) |
633 | { | 669 | { |
634 | struct device *dev = &pdev->dev; | 670 | struct device *dev = &pdev->dev; |
635 | struct ahci_host_priv *hpriv; | 671 | struct ahci_host_priv *hpriv; |
636 | struct xgene_ahci_context *ctx; | 672 | struct xgene_ahci_context *ctx; |
637 | struct resource *res; | 673 | struct resource *res; |
674 | const struct of_device_id *of_devid; | ||
675 | enum xgene_ahci_version version = XGENE_AHCI_V1; | ||
676 | const struct ata_port_info *ppi[] = { &xgene_ahci_v1_port_info, | ||
677 | &xgene_ahci_v2_port_info }; | ||
638 | int rc; | 678 | int rc; |
639 | 679 | ||
640 | hpriv = ahci_platform_get_resources(pdev); | 680 | hpriv = ahci_platform_get_resources(pdev); |
@@ -677,6 +717,35 @@ static int xgene_ahci_probe(struct platform_device *pdev) | |||
677 | ctx->csr_mux = csr; | 717 | ctx->csr_mux = csr; |
678 | } | 718 | } |
679 | 719 | ||
720 | of_devid = of_match_device(xgene_ahci_of_match, dev); | ||
721 | if (of_devid) { | ||
722 | if (of_devid->data) | ||
723 | version = (enum xgene_ahci_version) of_devid->data; | ||
724 | } | ||
725 | #ifdef CONFIG_ACPI | ||
726 | else { | ||
727 | const struct acpi_device_id *acpi_id; | ||
728 | struct acpi_device_info *info; | ||
729 | acpi_status status; | ||
730 | |||
731 | acpi_id = acpi_match_device(xgene_ahci_acpi_match, &pdev->dev); | ||
732 | if (!acpi_id) { | ||
733 | dev_warn(&pdev->dev, "No node entry in ACPI table. Assume version1\n"); | ||
734 | version = XGENE_AHCI_V1; | ||
735 | } else if (acpi_id->driver_data) { | ||
736 | version = (enum xgene_ahci_version) acpi_id->driver_data; | ||
737 | status = acpi_get_object_info(ACPI_HANDLE(&pdev->dev), &info); | ||
738 | if (ACPI_FAILURE(status)) { | ||
739 | dev_warn(&pdev->dev, "%s: Error reading device info. Assume version1\n", | ||
740 | __func__); | ||
741 | version = XGENE_AHCI_V1; | ||
742 | } | ||
743 | if (info->valid & ACPI_VALID_CID) | ||
744 | version = XGENE_AHCI_V2; | ||
745 | } | ||
746 | } | ||
747 | #endif | ||
748 | |||
680 | dev_dbg(dev, "VAddr 0x%p Mmio VAddr 0x%p\n", ctx->csr_core, | 749 | dev_dbg(dev, "VAddr 0x%p Mmio VAddr 0x%p\n", ctx->csr_core, |
681 | hpriv->mmio); | 750 | hpriv->mmio); |
682 | 751 | ||
@@ -704,9 +773,19 @@ static int xgene_ahci_probe(struct platform_device *pdev) | |||
704 | /* Configure the host controller */ | 773 | /* Configure the host controller */ |
705 | xgene_ahci_hw_init(hpriv); | 774 | xgene_ahci_hw_init(hpriv); |
706 | skip_clk_phy: | 775 | skip_clk_phy: |
707 | hpriv->flags = AHCI_HFLAG_NO_PMP | AHCI_HFLAG_NO_NCQ; | ||
708 | 776 | ||
709 | rc = ahci_platform_init_host(pdev, hpriv, &xgene_ahci_port_info, | 777 | switch (version) { |
778 | case XGENE_AHCI_V1: | ||
779 | hpriv->flags = AHCI_HFLAG_NO_NCQ; | ||
780 | break; | ||
781 | case XGENE_AHCI_V2: | ||
782 | hpriv->flags |= AHCI_HFLAG_YES_FBS | AHCI_HFLAG_EDGE_IRQ; | ||
783 | break; | ||
784 | default: | ||
785 | break; | ||
786 | } | ||
787 | |||
788 | rc = ahci_platform_init_host(pdev, hpriv, ppi[version - 1], | ||
710 | &ahci_platform_sht); | 789 | &ahci_platform_sht); |
711 | if (rc) | 790 | if (rc) |
712 | goto disable_resources; | 791 | goto disable_resources; |
@@ -719,20 +798,6 @@ disable_resources: | |||
719 | return rc; | 798 | return rc; |
720 | } | 799 | } |
721 | 800 | ||
722 | #ifdef CONFIG_ACPI | ||
723 | static const struct acpi_device_id xgene_ahci_acpi_match[] = { | ||
724 | { "APMC0D0D", }, | ||
725 | { } | ||
726 | }; | ||
727 | MODULE_DEVICE_TABLE(acpi, xgene_ahci_acpi_match); | ||
728 | #endif | ||
729 | |||
730 | static const struct of_device_id xgene_ahci_of_match[] = { | ||
731 | {.compatible = "apm,xgene-ahci"}, | ||
732 | {}, | ||
733 | }; | ||
734 | MODULE_DEVICE_TABLE(of, xgene_ahci_of_match); | ||
735 | |||
736 | static struct platform_driver xgene_ahci_driver = { | 801 | static struct platform_driver xgene_ahci_driver = { |
737 | .probe = xgene_ahci_probe, | 802 | .probe = xgene_ahci_probe, |
738 | .remove = ata_platform_remove_one, | 803 | .remove = ata_platform_remove_one, |
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index 287c4ba0219f..d256a66158be 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c | |||
@@ -1825,11 +1825,38 @@ static irqreturn_t ahci_multi_irqs_intr(int irq, void *dev_instance) | |||
1825 | return IRQ_WAKE_THREAD; | 1825 | return IRQ_WAKE_THREAD; |
1826 | } | 1826 | } |
1827 | 1827 | ||
1828 | static irqreturn_t ahci_single_irq_intr(int irq, void *dev_instance) | 1828 | static u32 ahci_handle_port_intr(struct ata_host *host, u32 irq_masked) |
1829 | { | ||
1830 | unsigned int i, handled = 0; | ||
1831 | |||
1832 | for (i = 0; i < host->n_ports; i++) { | ||
1833 | struct ata_port *ap; | ||
1834 | |||
1835 | if (!(irq_masked & (1 << i))) | ||
1836 | continue; | ||
1837 | |||
1838 | ap = host->ports[i]; | ||
1839 | if (ap) { | ||
1840 | ahci_port_intr(ap); | ||
1841 | VPRINTK("port %u\n", i); | ||
1842 | } else { | ||
1843 | VPRINTK("port %u (no irq)\n", i); | ||
1844 | if (ata_ratelimit()) | ||
1845 | dev_warn(host->dev, | ||
1846 | "interrupt on disabled port %u\n", i); | ||
1847 | } | ||
1848 | |||
1849 | handled = 1; | ||
1850 | } | ||
1851 | |||
1852 | return handled; | ||
1853 | } | ||
1854 | |||
1855 | static irqreturn_t ahci_single_edge_irq_intr(int irq, void *dev_instance) | ||
1829 | { | 1856 | { |
1830 | struct ata_host *host = dev_instance; | 1857 | struct ata_host *host = dev_instance; |
1831 | struct ahci_host_priv *hpriv; | 1858 | struct ahci_host_priv *hpriv; |
1832 | unsigned int i, handled = 0; | 1859 | unsigned int rc = 0; |
1833 | void __iomem *mmio; | 1860 | void __iomem *mmio; |
1834 | u32 irq_stat, irq_masked; | 1861 | u32 irq_stat, irq_masked; |
1835 | 1862 | ||
@@ -1847,25 +1874,44 @@ static irqreturn_t ahci_single_irq_intr(int irq, void *dev_instance) | |||
1847 | 1874 | ||
1848 | spin_lock(&host->lock); | 1875 | spin_lock(&host->lock); |
1849 | 1876 | ||
1850 | for (i = 0; i < host->n_ports; i++) { | 1877 | /* |
1851 | struct ata_port *ap; | 1878 | * HOST_IRQ_STAT behaves as edge triggered latch meaning that |
1879 | * it should be cleared before all the port events are cleared. | ||
1880 | */ | ||
1881 | writel(irq_stat, mmio + HOST_IRQ_STAT); | ||
1852 | 1882 | ||
1853 | if (!(irq_masked & (1 << i))) | 1883 | rc = ahci_handle_port_intr(host, irq_masked); |
1854 | continue; | ||
1855 | 1884 | ||
1856 | ap = host->ports[i]; | 1885 | spin_unlock(&host->lock); |
1857 | if (ap) { | ||
1858 | ahci_port_intr(ap); | ||
1859 | VPRINTK("port %u\n", i); | ||
1860 | } else { | ||
1861 | VPRINTK("port %u (no irq)\n", i); | ||
1862 | if (ata_ratelimit()) | ||
1863 | dev_warn(host->dev, | ||
1864 | "interrupt on disabled port %u\n", i); | ||
1865 | } | ||
1866 | 1886 | ||
1867 | handled = 1; | 1887 | VPRINTK("EXIT\n"); |
1868 | } | 1888 | |
1889 | return IRQ_RETVAL(rc); | ||
1890 | } | ||
1891 | |||
1892 | static irqreturn_t ahci_single_level_irq_intr(int irq, void *dev_instance) | ||
1893 | { | ||
1894 | struct ata_host *host = dev_instance; | ||
1895 | struct ahci_host_priv *hpriv; | ||
1896 | unsigned int rc = 0; | ||
1897 | void __iomem *mmio; | ||
1898 | u32 irq_stat, irq_masked; | ||
1899 | |||
1900 | VPRINTK("ENTER\n"); | ||
1901 | |||
1902 | hpriv = host->private_data; | ||
1903 | mmio = hpriv->mmio; | ||
1904 | |||
1905 | /* sigh. 0xffffffff is a valid return from h/w */ | ||
1906 | irq_stat = readl(mmio + HOST_IRQ_STAT); | ||
1907 | if (!irq_stat) | ||
1908 | return IRQ_NONE; | ||
1909 | |||
1910 | irq_masked = irq_stat & hpriv->port_map; | ||
1911 | |||
1912 | spin_lock(&host->lock); | ||
1913 | |||
1914 | rc = ahci_handle_port_intr(host, irq_masked); | ||
1869 | 1915 | ||
1870 | /* HOST_IRQ_STAT behaves as level triggered latch meaning that | 1916 | /* HOST_IRQ_STAT behaves as level triggered latch meaning that |
1871 | * it should be cleared after all the port events are cleared; | 1917 | * it should be cleared after all the port events are cleared; |
@@ -1882,7 +1928,7 @@ static irqreturn_t ahci_single_irq_intr(int irq, void *dev_instance) | |||
1882 | 1928 | ||
1883 | VPRINTK("EXIT\n"); | 1929 | VPRINTK("EXIT\n"); |
1884 | 1930 | ||
1885 | return IRQ_RETVAL(handled); | 1931 | return IRQ_RETVAL(rc); |
1886 | } | 1932 | } |
1887 | 1933 | ||
1888 | unsigned int ahci_qc_issue(struct ata_queued_cmd *qc) | 1934 | unsigned int ahci_qc_issue(struct ata_queued_cmd *qc) |
@@ -2297,7 +2343,7 @@ static int ahci_port_start(struct ata_port *ap) | |||
2297 | /* | 2343 | /* |
2298 | * Switch to per-port locking in case each port has its own MSI vector. | 2344 | * Switch to per-port locking in case each port has its own MSI vector. |
2299 | */ | 2345 | */ |
2300 | if ((hpriv->flags & AHCI_HFLAG_MULTI_MSI)) { | 2346 | if (hpriv->flags & AHCI_HFLAG_MULTI_MSI) { |
2301 | spin_lock_init(&pp->lock); | 2347 | spin_lock_init(&pp->lock); |
2302 | ap->lock = &pp->lock; | 2348 | ap->lock = &pp->lock; |
2303 | } | 2349 | } |
@@ -2425,7 +2471,10 @@ static int ahci_host_activate_multi_irqs(struct ata_host *host, int irq, | |||
2425 | rc = ata_host_start(host); | 2471 | rc = ata_host_start(host); |
2426 | if (rc) | 2472 | if (rc) |
2427 | return rc; | 2473 | return rc; |
2428 | 2474 | /* | |
2475 | * Requests IRQs according to AHCI-1.1 when multiple MSIs were | ||
2476 | * allocated. That is one MSI per port, starting from @irq. | ||
2477 | */ | ||
2429 | for (i = 0; i < host->n_ports; i++) { | 2478 | for (i = 0; i < host->n_ports; i++) { |
2430 | struct ahci_port_priv *pp = host->ports[i]->private_data; | 2479 | struct ahci_port_priv *pp = host->ports[i]->private_data; |
2431 | 2480 | ||
@@ -2464,29 +2513,27 @@ out_free_irqs: | |||
2464 | /** | 2513 | /** |
2465 | * ahci_host_activate - start AHCI host, request IRQs and register it | 2514 | * ahci_host_activate - start AHCI host, request IRQs and register it |
2466 | * @host: target ATA host | 2515 | * @host: target ATA host |
2467 | * @irq: base IRQ number to request | ||
2468 | * @sht: scsi_host_template to use when registering the host | 2516 | * @sht: scsi_host_template to use when registering the host |
2469 | * | 2517 | * |
2470 | * Similar to ata_host_activate, but requests IRQs according to AHCI-1.1 | ||
2471 | * when multiple MSIs were allocated. That is one MSI per port, starting | ||
2472 | * from @irq. | ||
2473 | * | ||
2474 | * LOCKING: | 2518 | * LOCKING: |
2475 | * Inherited from calling layer (may sleep). | 2519 | * Inherited from calling layer (may sleep). |
2476 | * | 2520 | * |
2477 | * RETURNS: | 2521 | * RETURNS: |
2478 | * 0 on success, -errno otherwise. | 2522 | * 0 on success, -errno otherwise. |
2479 | */ | 2523 | */ |
2480 | int ahci_host_activate(struct ata_host *host, int irq, | 2524 | int ahci_host_activate(struct ata_host *host, struct scsi_host_template *sht) |
2481 | struct scsi_host_template *sht) | ||
2482 | { | 2525 | { |
2483 | struct ahci_host_priv *hpriv = host->private_data; | 2526 | struct ahci_host_priv *hpriv = host->private_data; |
2527 | int irq = hpriv->irq; | ||
2484 | int rc; | 2528 | int rc; |
2485 | 2529 | ||
2486 | if (hpriv->flags & AHCI_HFLAG_MULTI_MSI) | 2530 | if (hpriv->flags & AHCI_HFLAG_MULTI_MSI) |
2487 | rc = ahci_host_activate_multi_irqs(host, irq, sht); | 2531 | rc = ahci_host_activate_multi_irqs(host, irq, sht); |
2532 | else if (hpriv->flags & AHCI_HFLAG_EDGE_IRQ) | ||
2533 | rc = ata_host_activate(host, irq, ahci_single_edge_irq_intr, | ||
2534 | IRQF_SHARED, sht); | ||
2488 | else | 2535 | else |
2489 | rc = ata_host_activate(host, irq, ahci_single_irq_intr, | 2536 | rc = ata_host_activate(host, irq, ahci_single_level_irq_intr, |
2490 | IRQF_SHARED, sht); | 2537 | IRQF_SHARED, sht); |
2491 | return rc; | 2538 | return rc; |
2492 | } | 2539 | } |
diff --git a/drivers/ata/libahci_platform.c b/drivers/ata/libahci_platform.c index d89305d289f6..aaa761b9081c 100644 --- a/drivers/ata/libahci_platform.c +++ b/drivers/ata/libahci_platform.c | |||
@@ -518,6 +518,8 @@ int ahci_platform_init_host(struct platform_device *pdev, | |||
518 | return -EINVAL; | 518 | return -EINVAL; |
519 | } | 519 | } |
520 | 520 | ||
521 | hpriv->irq = irq; | ||
522 | |||
521 | /* prepare host */ | 523 | /* prepare host */ |
522 | pi.private_data = (void *)(unsigned long)hpriv->flags; | 524 | pi.private_data = (void *)(unsigned long)hpriv->flags; |
523 | 525 | ||
@@ -588,7 +590,7 @@ int ahci_platform_init_host(struct platform_device *pdev, | |||
588 | ahci_init_controller(host); | 590 | ahci_init_controller(host); |
589 | ahci_print_info(host, "platform"); | 591 | ahci_print_info(host, "platform"); |
590 | 592 | ||
591 | return ahci_host_activate(host, irq, sht); | 593 | return ahci_host_activate(host, sht); |
592 | } | 594 | } |
593 | EXPORT_SYMBOL_GPL(ahci_platform_init_host); | 595 | EXPORT_SYMBOL_GPL(ahci_platform_init_host); |
594 | 596 | ||
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 577849c6611a..e83fc3d0da9c 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -3654,7 +3654,7 @@ int sata_link_resume(struct ata_link *link, const unsigned long *params, | |||
3654 | * EH context. | 3654 | * EH context. |
3655 | * | 3655 | * |
3656 | * RETURNS: | 3656 | * RETURNS: |
3657 | * 0 on succes, -errno otherwise. | 3657 | * 0 on success, -errno otherwise. |
3658 | */ | 3658 | */ |
3659 | int sata_link_scr_lpm(struct ata_link *link, enum ata_lpm_policy policy, | 3659 | int sata_link_scr_lpm(struct ata_link *link, enum ata_lpm_policy policy, |
3660 | bool spm_wakeup) | 3660 | bool spm_wakeup) |
@@ -4225,7 +4225,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { | |||
4225 | { "PIONEER DVD-RW DVR-216D", NULL, ATA_HORKAGE_NOSETXFER }, | 4225 | { "PIONEER DVD-RW DVR-216D", NULL, ATA_HORKAGE_NOSETXFER }, |
4226 | 4226 | ||
4227 | /* devices that don't properly handle queued TRIM commands */ | 4227 | /* devices that don't properly handle queued TRIM commands */ |
4228 | { "Micron_M500*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | | 4228 | { "Micron_M500_*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | |
4229 | ATA_HORKAGE_ZERO_AFTER_TRIM, }, | 4229 | ATA_HORKAGE_ZERO_AFTER_TRIM, }, |
4230 | { "Crucial_CT*M500*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | | 4230 | { "Crucial_CT*M500*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | |
4231 | ATA_HORKAGE_ZERO_AFTER_TRIM, }, | 4231 | ATA_HORKAGE_ZERO_AFTER_TRIM, }, |
@@ -6456,12 +6456,7 @@ static int __init ata_parse_force_one(char **cur, | |||
6456 | struct ata_force_ent *force_ent, | 6456 | struct ata_force_ent *force_ent, |
6457 | const char **reason) | 6457 | const char **reason) |
6458 | { | 6458 | { |
6459 | /* FIXME: Currently, there's no way to tag init const data and | 6459 | static const struct ata_force_param force_tbl[] __initconst = { |
6460 | * using __initdata causes build failure on some versions of | ||
6461 | * gcc. Once __initdataconst is implemented, add const to the | ||
6462 | * following structure. | ||
6463 | */ | ||
6464 | static struct ata_force_param force_tbl[] __initdata = { | ||
6465 | { "40c", .cbl = ATA_CBL_PATA40 }, | 6460 | { "40c", .cbl = ATA_CBL_PATA40 }, |
6466 | { "80c", .cbl = ATA_CBL_PATA80 }, | 6461 | { "80c", .cbl = ATA_CBL_PATA80 }, |
6467 | { "short40c", .cbl = ATA_CBL_PATA40_SHORT }, | 6462 | { "short40c", .cbl = ATA_CBL_PATA40_SHORT }, |
@@ -6472,6 +6467,8 @@ static int __init ata_parse_force_one(char **cur, | |||
6472 | { "3.0Gbps", .spd_limit = 2 }, | 6467 | { "3.0Gbps", .spd_limit = 2 }, |
6473 | { "noncq", .horkage_on = ATA_HORKAGE_NONCQ }, | 6468 | { "noncq", .horkage_on = ATA_HORKAGE_NONCQ }, |
6474 | { "ncq", .horkage_off = ATA_HORKAGE_NONCQ }, | 6469 | { "ncq", .horkage_off = ATA_HORKAGE_NONCQ }, |
6470 | { "noncqtrim", .horkage_on = ATA_HORKAGE_NO_NCQ_TRIM }, | ||
6471 | { "ncqtrim", .horkage_off = ATA_HORKAGE_NO_NCQ_TRIM }, | ||
6475 | { "dump_id", .horkage_on = ATA_HORKAGE_DUMP_ID }, | 6472 | { "dump_id", .horkage_on = ATA_HORKAGE_DUMP_ID }, |
6476 | { "pio0", .xfer_mask = 1 << (ATA_SHIFT_PIO + 0) }, | 6473 | { "pio0", .xfer_mask = 1 << (ATA_SHIFT_PIO + 0) }, |
6477 | { "pio1", .xfer_mask = 1 << (ATA_SHIFT_PIO + 1) }, | 6474 | { "pio1", .xfer_mask = 1 << (ATA_SHIFT_PIO + 1) }, |
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index cf0022ec07f2..7465031a893c 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c | |||
@@ -1507,16 +1507,21 @@ unsigned int ata_read_log_page(struct ata_device *dev, u8 log, | |||
1507 | { | 1507 | { |
1508 | struct ata_taskfile tf; | 1508 | struct ata_taskfile tf; |
1509 | unsigned int err_mask; | 1509 | unsigned int err_mask; |
1510 | bool dma = false; | ||
1510 | 1511 | ||
1511 | DPRINTK("read log page - log 0x%x, page 0x%x\n", log, page); | 1512 | DPRINTK("read log page - log 0x%x, page 0x%x\n", log, page); |
1512 | 1513 | ||
1514 | retry: | ||
1513 | ata_tf_init(dev, &tf); | 1515 | ata_tf_init(dev, &tf); |
1514 | if (dev->dma_mode && ata_id_has_read_log_dma_ext(dev->id)) { | 1516 | if (dev->dma_mode && ata_id_has_read_log_dma_ext(dev->id) && |
1517 | !(dev->horkage & ATA_HORKAGE_NO_NCQ_LOG)) { | ||
1515 | tf.command = ATA_CMD_READ_LOG_DMA_EXT; | 1518 | tf.command = ATA_CMD_READ_LOG_DMA_EXT; |
1516 | tf.protocol = ATA_PROT_DMA; | 1519 | tf.protocol = ATA_PROT_DMA; |
1520 | dma = true; | ||
1517 | } else { | 1521 | } else { |
1518 | tf.command = ATA_CMD_READ_LOG_EXT; | 1522 | tf.command = ATA_CMD_READ_LOG_EXT; |
1519 | tf.protocol = ATA_PROT_PIO; | 1523 | tf.protocol = ATA_PROT_PIO; |
1524 | dma = false; | ||
1520 | } | 1525 | } |
1521 | tf.lbal = log; | 1526 | tf.lbal = log; |
1522 | tf.lbam = page; | 1527 | tf.lbam = page; |
@@ -1527,6 +1532,12 @@ unsigned int ata_read_log_page(struct ata_device *dev, u8 log, | |||
1527 | err_mask = ata_exec_internal(dev, &tf, NULL, DMA_FROM_DEVICE, | 1532 | err_mask = ata_exec_internal(dev, &tf, NULL, DMA_FROM_DEVICE, |
1528 | buf, sectors * ATA_SECT_SIZE, 0); | 1533 | buf, sectors * ATA_SECT_SIZE, 0); |
1529 | 1534 | ||
1535 | if (err_mask && dma) { | ||
1536 | dev->horkage |= ATA_HORKAGE_NO_NCQ_LOG; | ||
1537 | ata_dev_warn(dev, "READ LOG DMA EXT failed, trying unqueued\n"); | ||
1538 | goto retry; | ||
1539 | } | ||
1540 | |||
1530 | DPRINTK("EXIT, err_mask=%x\n", err_mask); | 1541 | DPRINTK("EXIT, err_mask=%x\n", err_mask); |
1531 | return err_mask; | 1542 | return err_mask; |
1532 | } | 1543 | } |
diff --git a/drivers/ata/libata-transport.c b/drivers/ata/libata-transport.c index 3227b7c8a05f..d6c37bcd416d 100644 --- a/drivers/ata/libata-transport.c +++ b/drivers/ata/libata-transport.c | |||
@@ -560,6 +560,27 @@ show_ata_dev_gscr(struct device *dev, | |||
560 | 560 | ||
561 | static DEVICE_ATTR(gscr, S_IRUGO, show_ata_dev_gscr, NULL); | 561 | static DEVICE_ATTR(gscr, S_IRUGO, show_ata_dev_gscr, NULL); |
562 | 562 | ||
563 | static ssize_t | ||
564 | show_ata_dev_trim(struct device *dev, | ||
565 | struct device_attribute *attr, char *buf) | ||
566 | { | ||
567 | struct ata_device *ata_dev = transport_class_to_dev(dev); | ||
568 | unsigned char *mode; | ||
569 | |||
570 | if (!ata_id_has_trim(ata_dev->id)) | ||
571 | mode = "unsupported"; | ||
572 | else if (ata_dev->horkage & ATA_HORKAGE_NO_NCQ_TRIM) | ||
573 | mode = "forced_unqueued"; | ||
574 | else if (ata_fpdma_dsm_supported(ata_dev)) | ||
575 | mode = "queued"; | ||
576 | else | ||
577 | mode = "unqueued"; | ||
578 | |||
579 | return snprintf(buf, 20, "%s\n", mode); | ||
580 | } | ||
581 | |||
582 | static DEVICE_ATTR(trim, S_IRUGO, show_ata_dev_trim, NULL); | ||
583 | |||
563 | static DECLARE_TRANSPORT_CLASS(ata_dev_class, | 584 | static DECLARE_TRANSPORT_CLASS(ata_dev_class, |
564 | "ata_device", NULL, NULL, NULL); | 585 | "ata_device", NULL, NULL, NULL); |
565 | 586 | ||
@@ -733,6 +754,7 @@ struct scsi_transport_template *ata_attach_transport(void) | |||
733 | SETUP_DEV_ATTRIBUTE(ering); | 754 | SETUP_DEV_ATTRIBUTE(ering); |
734 | SETUP_DEV_ATTRIBUTE(id); | 755 | SETUP_DEV_ATTRIBUTE(id); |
735 | SETUP_DEV_ATTRIBUTE(gscr); | 756 | SETUP_DEV_ATTRIBUTE(gscr); |
757 | SETUP_DEV_ATTRIBUTE(trim); | ||
736 | BUG_ON(count > ATA_DEV_ATTRS); | 758 | BUG_ON(count > ATA_DEV_ATTRS); |
737 | i->dev_attrs[count] = NULL; | 759 | i->dev_attrs[count] = NULL; |
738 | 760 | ||
diff --git a/drivers/ata/pata_hpt366.c b/drivers/ata/pata_hpt366.c index cbc3de793d1d..0038dc4c06c7 100644 --- a/drivers/ata/pata_hpt366.c +++ b/drivers/ata/pata_hpt366.c | |||
@@ -352,7 +352,7 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
352 | }; | 352 | }; |
353 | const struct ata_port_info *ppi[] = { &info_hpt366, NULL }; | 353 | const struct ata_port_info *ppi[] = { &info_hpt366, NULL }; |
354 | 354 | ||
355 | void *hpriv = NULL; | 355 | const void *hpriv = NULL; |
356 | u32 reg1; | 356 | u32 reg1; |
357 | int rc; | 357 | int rc; |
358 | 358 | ||
@@ -383,7 +383,7 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
383 | break; | 383 | break; |
384 | } | 384 | } |
385 | /* Now kick off ATA set up */ | 385 | /* Now kick off ATA set up */ |
386 | return ata_pci_bmdma_init_one(dev, ppi, &hpt36x_sht, hpriv, 0); | 386 | return ata_pci_bmdma_init_one(dev, ppi, &hpt36x_sht, (void *)hpriv, 0); |
387 | } | 387 | } |
388 | 388 | ||
389 | #ifdef CONFIG_PM_SLEEP | 389 | #ifdef CONFIG_PM_SLEEP |
diff --git a/drivers/ata/pata_samsung_cf.c b/drivers/ata/pata_samsung_cf.c index fa44eb2872db..cbb5a471eb9d 100644 --- a/drivers/ata/pata_samsung_cf.c +++ b/drivers/ata/pata_samsung_cf.c | |||
@@ -638,7 +638,7 @@ static const struct dev_pm_ops pata_s3c_pm_ops = { | |||
638 | #endif | 638 | #endif |
639 | 639 | ||
640 | /* driver device registration */ | 640 | /* driver device registration */ |
641 | static struct platform_device_id pata_s3c_driver_ids[] = { | 641 | static const struct platform_device_id pata_s3c_driver_ids[] = { |
642 | { | 642 | { |
643 | .name = "s3c64xx-pata", | 643 | .name = "s3c64xx-pata", |
644 | .driver_data = TYPE_S3C64XX, | 644 | .driver_data = TYPE_S3C64XX, |
diff --git a/drivers/ata/sata_highbank.c b/drivers/ata/sata_highbank.c index 24e311fe2c1c..8638d575b2b9 100644 --- a/drivers/ata/sata_highbank.c +++ b/drivers/ata/sata_highbank.c | |||
@@ -499,6 +499,7 @@ static int ahci_highbank_probe(struct platform_device *pdev) | |||
499 | return -ENOMEM; | 499 | return -ENOMEM; |
500 | } | 500 | } |
501 | 501 | ||
502 | hpriv->irq = irq; | ||
502 | hpriv->flags |= (unsigned long)pi.private_data; | 503 | hpriv->flags |= (unsigned long)pi.private_data; |
503 | 504 | ||
504 | hpriv->mmio = devm_ioremap(dev, mem->start, resource_size(mem)); | 505 | hpriv->mmio = devm_ioremap(dev, mem->start, resource_size(mem)); |
@@ -568,7 +569,7 @@ static int ahci_highbank_probe(struct platform_device *pdev) | |||
568 | ahci_init_controller(host); | 569 | ahci_init_controller(host); |
569 | ahci_print_info(host, "platform"); | 570 | ahci_print_info(host, "platform"); |
570 | 571 | ||
571 | rc = ahci_host_activate(host, irq, &ahci_highbank_platform_sht); | 572 | rc = ahci_host_activate(host, &ahci_highbank_platform_sht); |
572 | if (rc) | 573 | if (rc) |
573 | goto err0; | 574 | goto err0; |
574 | 575 | ||
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index 7ece85f43020..734f563b8d37 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c | |||
@@ -599,7 +599,7 @@ MODULE_DEVICE_TABLE(pci, nv_pci_tbl); | |||
599 | MODULE_VERSION(DRV_VERSION); | 599 | MODULE_VERSION(DRV_VERSION); |
600 | 600 | ||
601 | static bool adma_enabled; | 601 | static bool adma_enabled; |
602 | static bool swncq_enabled = 1; | 602 | static bool swncq_enabled = true; |
603 | static bool msi_enabled; | 603 | static bool msi_enabled; |
604 | 604 | ||
605 | static void nv_adma_register_mode(struct ata_port *ap) | 605 | static void nv_adma_register_mode(struct ata_port *ap) |
diff --git a/include/linux/ata.h b/include/linux/ata.h index b666b773e111..fed36418dd1c 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h | |||
@@ -704,9 +704,19 @@ static inline bool ata_id_wcache_enabled(const u16 *id) | |||
704 | 704 | ||
705 | static inline bool ata_id_has_read_log_dma_ext(const u16 *id) | 705 | static inline bool ata_id_has_read_log_dma_ext(const u16 *id) |
706 | { | 706 | { |
707 | /* Word 86 must have bit 15 set */ | ||
707 | if (!(id[ATA_ID_CFS_ENABLE_2] & (1 << 15))) | 708 | if (!(id[ATA_ID_CFS_ENABLE_2] & (1 << 15))) |
708 | return false; | 709 | return false; |
709 | return id[ATA_ID_COMMAND_SET_3] & (1 << 3); | 710 | |
711 | /* READ LOG DMA EXT support can be signaled either from word 119 | ||
712 | * or from word 120. The format is the same for both words: Bit | ||
713 | * 15 must be cleared, bit 14 set and bit 3 set. | ||
714 | */ | ||
715 | if ((id[ATA_ID_COMMAND_SET_3] & 0xC008) == 0x4008 || | ||
716 | (id[ATA_ID_COMMAND_SET_4] & 0xC008) == 0x4008) | ||
717 | return true; | ||
718 | |||
719 | return false; | ||
710 | } | 720 | } |
711 | 721 | ||
712 | static inline bool ata_id_has_sense_reporting(const u16 *id) | 722 | static inline bool ata_id_has_sense_reporting(const u16 *id) |
diff --git a/include/linux/libata.h b/include/linux/libata.h index 51cb312d9bb9..36ce37bcc963 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
@@ -430,6 +430,7 @@ enum { | |||
430 | ATA_HORKAGE_NOLPM = (1 << 20), /* don't use LPM */ | 430 | ATA_HORKAGE_NOLPM = (1 << 20), /* don't use LPM */ |
431 | ATA_HORKAGE_WD_BROKEN_LPM = (1 << 21), /* some WDs have broken LPM */ | 431 | ATA_HORKAGE_WD_BROKEN_LPM = (1 << 21), /* some WDs have broken LPM */ |
432 | ATA_HORKAGE_ZERO_AFTER_TRIM = (1 << 22),/* guarantees zero after trim */ | 432 | ATA_HORKAGE_ZERO_AFTER_TRIM = (1 << 22),/* guarantees zero after trim */ |
433 | ATA_HORKAGE_NO_NCQ_LOG = (1 << 23), /* don't use NCQ for log read */ | ||
433 | 434 | ||
434 | /* DMA mask for user DMA control: User visible values; DO NOT | 435 | /* DMA mask for user DMA control: User visible values; DO NOT |
435 | renumber */ | 436 | renumber */ |