diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-03-18 23:06:46 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-03-18 23:06:46 -0400 |
commit | fcab86add71623e3963d7565c0d61bb9d99aea7c (patch) | |
tree | e13baa15ad18c48678b0259afb54e22a22ceef1e | |
parent | ef504fa591aae6f6ebdf26edbe6ec0bfd32ea7d3 (diff) | |
parent | 8134233e8d346aaa1c929dc510e75482ae318bce (diff) |
Merge branch 'for-4.6' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata
Pull libata updates from Tejun Heo:
- ahci grew runtime power management support so that the controller can
be turned off if no devices are attached.
- sata_via isn't dead yet. It got hotplug support and more refined
workaround for certain WD drives.
- Misc cleanups. There's a merge from for-4.5-fixes to avoid confusing
conflicts in ahci PCI ID table.
* 'for-4.6' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata:
ata: ahci_xgene: dereferencing uninitialized pointer in probe
AHCI: Remove obsolete Intel Lewisburg SATA RAID device IDs
ata: sata_rcar: Use ARCH_RENESAS
sata_via: Implement hotplug for VT6421
sata_via: Apply WD workaround only when needed on VT6421
ahci: Add runtime PM support for the host controller
ahci: Add functions to manage runtime PM of AHCI ports
ahci: Convert driver to use modern PM hooks
ahci: Cache host controller version
scsi: Drop runtime PM usage count after host is added
scsi: Set request queue runtime PM status back to active on resume
block: Add blk_set_runtime_active()
ata: ahci_mvebu: add support for Armada 3700 variant
libata: fix unbalanced spin_lock_irqsave/spin_unlock_irq() in ata_scsi_park_show()
libata: support AHCI on OCTEON platform
-rw-r--r-- | Documentation/devicetree/bindings/ata/ahci-platform.txt | 1 | ||||
-rw-r--r-- | Documentation/devicetree/bindings/mips/cavium/sata-uctl.txt | 42 | ||||
-rw-r--r-- | arch/mips/include/asm/octeon/cvmx.h | 9 | ||||
-rw-r--r-- | block/blk-core.c | 24 | ||||
-rw-r--r-- | drivers/ata/Kconfig | 11 | ||||
-rw-r--r-- | drivers/ata/Makefile | 1 | ||||
-rw-r--r-- | drivers/ata/ahci.c | 108 | ||||
-rw-r--r-- | drivers/ata/ahci.h | 1 | ||||
-rw-r--r-- | drivers/ata/ahci_mvebu.c | 14 | ||||
-rw-r--r-- | drivers/ata/ahci_octeon.c | 105 | ||||
-rw-r--r-- | drivers/ata/ahci_platform.c | 1 | ||||
-rw-r--r-- | drivers/ata/ahci_xgene.c | 4 | ||||
-rw-r--r-- | drivers/ata/libahci.c | 55 | ||||
-rw-r--r-- | drivers/ata/libata-scsi.c | 4 | ||||
-rw-r--r-- | drivers/ata/sata_via.c | 133 | ||||
-rw-r--r-- | drivers/scsi/hosts.c | 7 | ||||
-rw-r--r-- | drivers/scsi/scsi_pm.c | 10 | ||||
-rw-r--r-- | include/linux/blkdev.h | 2 |
18 files changed, 475 insertions, 57 deletions
diff --git a/Documentation/devicetree/bindings/ata/ahci-platform.txt b/Documentation/devicetree/bindings/ata/ahci-platform.txt index c2340eeeb97f..3d84dcae8475 100644 --- a/Documentation/devicetree/bindings/ata/ahci-platform.txt +++ b/Documentation/devicetree/bindings/ata/ahci-platform.txt | |||
@@ -11,6 +11,7 @@ Required properties: | |||
11 | - compatible : compatible string, one of: | 11 | - compatible : compatible string, one of: |
12 | - "allwinner,sun4i-a10-ahci" | 12 | - "allwinner,sun4i-a10-ahci" |
13 | - "hisilicon,hisi-ahci" | 13 | - "hisilicon,hisi-ahci" |
14 | - "cavium,octeon-7130-ahci" | ||
14 | - "ibm,476gtr-ahci" | 15 | - "ibm,476gtr-ahci" |
15 | - "marvell,armada-380-ahci" | 16 | - "marvell,armada-380-ahci" |
16 | - "snps,dwc-ahci" | 17 | - "snps,dwc-ahci" |
diff --git a/Documentation/devicetree/bindings/mips/cavium/sata-uctl.txt b/Documentation/devicetree/bindings/mips/cavium/sata-uctl.txt new file mode 100644 index 000000000000..3bd3c2f0b9b1 --- /dev/null +++ b/Documentation/devicetree/bindings/mips/cavium/sata-uctl.txt | |||
@@ -0,0 +1,42 @@ | |||
1 | * UCTL SATA controller glue | ||
2 | |||
3 | UCTL is the bridge unit between the I/O interconnect (an internal bus) | ||
4 | and the SATA AHCI host controller (UAHC). It performs the following functions: | ||
5 | - provides interfaces for the applications to access the UAHC AHCI | ||
6 | registers on the CN71XX I/O space. | ||
7 | - provides a bridge for UAHC to fetch AHCI command table entries and data | ||
8 | buffers from Level 2 Cache. | ||
9 | - posts interrupts to the CIU. | ||
10 | - contains registers that: | ||
11 | - control the behavior of the UAHC | ||
12 | - control the clock/reset generation to UAHC | ||
13 | - control endian swapping for all UAHC registers and DMA accesses | ||
14 | |||
15 | Properties: | ||
16 | |||
17 | - compatible: "cavium,octeon-7130-sata-uctl" | ||
18 | |||
19 | Compatibility with the cn7130 SOC. | ||
20 | |||
21 | - reg: The base address of the UCTL register bank. | ||
22 | |||
23 | - #address-cells, #size-cells, ranges and dma-ranges must be present and hold | ||
24 | suitable values to map all child nodes. | ||
25 | |||
26 | Example: | ||
27 | |||
28 | uctl@118006c000000 { | ||
29 | compatible = "cavium,octeon-7130-sata-uctl"; | ||
30 | reg = <0x11800 0x6c000000 0x0 0x100>; | ||
31 | ranges; /* Direct mapping */ | ||
32 | dma-ranges; | ||
33 | #address-cells = <2>; | ||
34 | #size-cells = <2>; | ||
35 | |||
36 | sata: sata@16c0000000000 { | ||
37 | compatible = "cavium,octeon-7130-ahci"; | ||
38 | reg = <0x16c00 0x00000000 0x0 0x200>; | ||
39 | interrupt-parent = <&cibsata>; | ||
40 | interrupts = <2 4>; /* Bit: 2, level */ | ||
41 | }; | ||
42 | }; | ||
diff --git a/arch/mips/include/asm/octeon/cvmx.h b/arch/mips/include/asm/octeon/cvmx.h index 774bb45834cb..19e139c9f337 100644 --- a/arch/mips/include/asm/octeon/cvmx.h +++ b/arch/mips/include/asm/octeon/cvmx.h | |||
@@ -275,6 +275,11 @@ static inline void cvmx_write_csr(uint64_t csr_addr, uint64_t val) | |||
275 | cvmx_read64(CVMX_MIO_BOOT_BIST_STAT); | 275 | cvmx_read64(CVMX_MIO_BOOT_BIST_STAT); |
276 | } | 276 | } |
277 | 277 | ||
278 | static inline void cvmx_writeq_csr(void __iomem *csr_addr, uint64_t val) | ||
279 | { | ||
280 | cvmx_write_csr((__force uint64_t)csr_addr, val); | ||
281 | } | ||
282 | |||
278 | static inline void cvmx_write_io(uint64_t io_addr, uint64_t val) | 283 | static inline void cvmx_write_io(uint64_t io_addr, uint64_t val) |
279 | { | 284 | { |
280 | cvmx_write64(io_addr, val); | 285 | cvmx_write64(io_addr, val); |
@@ -287,6 +292,10 @@ static inline uint64_t cvmx_read_csr(uint64_t csr_addr) | |||
287 | return val; | 292 | return val; |
288 | } | 293 | } |
289 | 294 | ||
295 | static inline uint64_t cvmx_readq_csr(void __iomem *csr_addr) | ||
296 | { | ||
297 | return cvmx_read_csr((__force uint64_t) csr_addr); | ||
298 | } | ||
290 | 299 | ||
291 | static inline void cvmx_send_single(uint64_t data) | 300 | static inline void cvmx_send_single(uint64_t data) |
292 | { | 301 | { |
diff --git a/block/blk-core.c b/block/blk-core.c index 45f4d7efbf34..827f8badd143 100644 --- a/block/blk-core.c +++ b/block/blk-core.c | |||
@@ -3529,6 +3529,30 @@ void blk_post_runtime_resume(struct request_queue *q, int err) | |||
3529 | spin_unlock_irq(q->queue_lock); | 3529 | spin_unlock_irq(q->queue_lock); |
3530 | } | 3530 | } |
3531 | EXPORT_SYMBOL(blk_post_runtime_resume); | 3531 | EXPORT_SYMBOL(blk_post_runtime_resume); |
3532 | |||
3533 | /** | ||
3534 | * blk_set_runtime_active - Force runtime status of the queue to be active | ||
3535 | * @q: the queue of the device | ||
3536 | * | ||
3537 | * If the device is left runtime suspended during system suspend the resume | ||
3538 | * hook typically resumes the device and corrects runtime status | ||
3539 | * accordingly. However, that does not affect the queue runtime PM status | ||
3540 | * which is still "suspended". This prevents processing requests from the | ||
3541 | * queue. | ||
3542 | * | ||
3543 | * This function can be used in driver's resume hook to correct queue | ||
3544 | * runtime PM status and re-enable peeking requests from the queue. It | ||
3545 | * should be called before first request is added to the queue. | ||
3546 | */ | ||
3547 | void blk_set_runtime_active(struct request_queue *q) | ||
3548 | { | ||
3549 | spin_lock_irq(q->queue_lock); | ||
3550 | q->rpm_status = RPM_ACTIVE; | ||
3551 | pm_runtime_mark_last_busy(q->dev); | ||
3552 | pm_request_autosuspend(q->dev); | ||
3553 | spin_unlock_irq(q->queue_lock); | ||
3554 | } | ||
3555 | EXPORT_SYMBOL(blk_set_runtime_active); | ||
3532 | #endif | 3556 | #endif |
3533 | 3557 | ||
3534 | int __init blk_dev_init(void) | 3558 | int __init blk_dev_init(void) |
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 861643ea91b5..5083f85efea7 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig | |||
@@ -151,6 +151,15 @@ config AHCI_MVEBU | |||
151 | 151 | ||
152 | If unsure, say N. | 152 | If unsure, say N. |
153 | 153 | ||
154 | config AHCI_OCTEON | ||
155 | tristate "Cavium Octeon Soc Serial ATA" | ||
156 | depends on SATA_AHCI_PLATFORM && CAVIUM_OCTEON_SOC | ||
157 | default y | ||
158 | help | ||
159 | This option enables support for Cavium Octeon SoC Serial ATA. | ||
160 | |||
161 | If unsure, say N. | ||
162 | |||
154 | config AHCI_SUNXI | 163 | config AHCI_SUNXI |
155 | tristate "Allwinner sunxi AHCI SATA support" | 164 | tristate "Allwinner sunxi AHCI SATA support" |
156 | depends on ARCH_SUNXI | 165 | depends on ARCH_SUNXI |
@@ -355,7 +364,7 @@ config SATA_PROMISE | |||
355 | 364 | ||
356 | config SATA_RCAR | 365 | config SATA_RCAR |
357 | tristate "Renesas R-Car SATA support" | 366 | tristate "Renesas R-Car SATA support" |
358 | depends on ARCH_SHMOBILE || COMPILE_TEST | 367 | depends on ARCH_RENESAS || COMPILE_TEST |
359 | help | 368 | help |
360 | This option enables support for Renesas R-Car Serial ATA. | 369 | This option enables support for Renesas R-Car Serial ATA. |
361 | 370 | ||
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index af45effac18c..18579521464e 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile | |||
@@ -15,6 +15,7 @@ obj-$(CONFIG_AHCI_CEVA) += ahci_ceva.o libahci.o libahci_platform.o | |||
15 | 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 |
16 | 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 |
17 | 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 |
18 | obj-$(CONFIG_AHCI_OCTEON) += ahci_octeon.o | ||
18 | obj-$(CONFIG_AHCI_SUNXI) += ahci_sunxi.o libahci.o libahci_platform.o | 19 | obj-$(CONFIG_AHCI_SUNXI) += ahci_sunxi.o libahci.o libahci_platform.o |
19 | obj-$(CONFIG_AHCI_ST) += ahci_st.o libahci.o libahci_platform.o | 20 | obj-$(CONFIG_AHCI_ST) += ahci_st.o libahci.o libahci_platform.o |
20 | obj-$(CONFIG_AHCI_TEGRA) += ahci_tegra.o libahci.o libahci_platform.o | 21 | obj-$(CONFIG_AHCI_TEGRA) += ahci_tegra.o libahci.o libahci_platform.o |
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 146dc0b8ec61..a83bbcc58b4c 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -85,6 +85,7 @@ enum board_ids { | |||
85 | }; | 85 | }; |
86 | 86 | ||
87 | static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); | 87 | static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); |
88 | static void ahci_remove_one(struct pci_dev *dev); | ||
88 | static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class, | 89 | static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class, |
89 | unsigned long deadline); | 90 | unsigned long deadline); |
90 | static int ahci_avn_hardreset(struct ata_link *link, unsigned int *class, | 91 | static int ahci_avn_hardreset(struct ata_link *link, unsigned int *class, |
@@ -94,9 +95,13 @@ static bool is_mcp89_apple(struct pci_dev *pdev); | |||
94 | static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class, | 95 | static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class, |
95 | unsigned long deadline); | 96 | unsigned long deadline); |
96 | #ifdef CONFIG_PM | 97 | #ifdef CONFIG_PM |
97 | static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg); | 98 | static int ahci_pci_device_runtime_suspend(struct device *dev); |
98 | static int ahci_pci_device_resume(struct pci_dev *pdev); | 99 | static int ahci_pci_device_runtime_resume(struct device *dev); |
100 | #ifdef CONFIG_PM_SLEEP | ||
101 | static int ahci_pci_device_suspend(struct device *dev); | ||
102 | static int ahci_pci_device_resume(struct device *dev); | ||
99 | #endif | 103 | #endif |
104 | #endif /* CONFIG_PM */ | ||
100 | 105 | ||
101 | static struct scsi_host_template ahci_sht = { | 106 | static struct scsi_host_template ahci_sht = { |
102 | AHCI_SHT("ahci"), | 107 | AHCI_SHT("ahci"), |
@@ -371,15 +376,11 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
371 | { PCI_VDEVICE(INTEL, 0x2826), board_ahci }, /* Lewisburg RAID*/ | 376 | { PCI_VDEVICE(INTEL, 0x2826), board_ahci }, /* Lewisburg RAID*/ |
372 | { PCI_VDEVICE(INTEL, 0x2827), board_ahci }, /* Lewisburg RAID*/ | 377 | { PCI_VDEVICE(INTEL, 0x2827), board_ahci }, /* Lewisburg RAID*/ |
373 | { PCI_VDEVICE(INTEL, 0xa182), board_ahci }, /* Lewisburg AHCI*/ | 378 | { PCI_VDEVICE(INTEL, 0xa182), board_ahci }, /* Lewisburg AHCI*/ |
374 | { PCI_VDEVICE(INTEL, 0xa184), board_ahci }, /* Lewisburg RAID*/ | ||
375 | { PCI_VDEVICE(INTEL, 0xa186), board_ahci }, /* Lewisburg RAID*/ | 379 | { PCI_VDEVICE(INTEL, 0xa186), board_ahci }, /* Lewisburg RAID*/ |
376 | { PCI_VDEVICE(INTEL, 0xa18e), board_ahci }, /* Lewisburg RAID*/ | ||
377 | { PCI_VDEVICE(INTEL, 0xa1d2), board_ahci }, /* Lewisburg RAID*/ | 380 | { PCI_VDEVICE(INTEL, 0xa1d2), board_ahci }, /* Lewisburg RAID*/ |
378 | { PCI_VDEVICE(INTEL, 0xa1d6), board_ahci }, /* Lewisburg RAID*/ | 381 | { PCI_VDEVICE(INTEL, 0xa1d6), board_ahci }, /* Lewisburg RAID*/ |
379 | { PCI_VDEVICE(INTEL, 0xa202), board_ahci }, /* Lewisburg AHCI*/ | 382 | { PCI_VDEVICE(INTEL, 0xa202), board_ahci }, /* Lewisburg AHCI*/ |
380 | { PCI_VDEVICE(INTEL, 0xa204), board_ahci }, /* Lewisburg RAID*/ | ||
381 | { PCI_VDEVICE(INTEL, 0xa206), board_ahci }, /* Lewisburg RAID*/ | 383 | { PCI_VDEVICE(INTEL, 0xa206), board_ahci }, /* Lewisburg RAID*/ |
382 | { PCI_VDEVICE(INTEL, 0xa20e), board_ahci }, /* Lewisburg RAID*/ | ||
383 | { PCI_VDEVICE(INTEL, 0xa252), board_ahci }, /* Lewisburg RAID*/ | 384 | { PCI_VDEVICE(INTEL, 0xa252), board_ahci }, /* Lewisburg RAID*/ |
384 | { PCI_VDEVICE(INTEL, 0xa256), board_ahci }, /* Lewisburg RAID*/ | 385 | { PCI_VDEVICE(INTEL, 0xa256), board_ahci }, /* Lewisburg RAID*/ |
385 | 386 | ||
@@ -563,16 +564,20 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
563 | { } /* terminate list */ | 564 | { } /* terminate list */ |
564 | }; | 565 | }; |
565 | 566 | ||
567 | static const struct dev_pm_ops ahci_pci_pm_ops = { | ||
568 | SET_SYSTEM_SLEEP_PM_OPS(ahci_pci_device_suspend, ahci_pci_device_resume) | ||
569 | SET_RUNTIME_PM_OPS(ahci_pci_device_runtime_suspend, | ||
570 | ahci_pci_device_runtime_resume, NULL) | ||
571 | }; | ||
566 | 572 | ||
567 | static struct pci_driver ahci_pci_driver = { | 573 | static struct pci_driver ahci_pci_driver = { |
568 | .name = DRV_NAME, | 574 | .name = DRV_NAME, |
569 | .id_table = ahci_pci_tbl, | 575 | .id_table = ahci_pci_tbl, |
570 | .probe = ahci_init_one, | 576 | .probe = ahci_init_one, |
571 | .remove = ata_pci_remove_one, | 577 | .remove = ahci_remove_one, |
572 | #ifdef CONFIG_PM | 578 | .driver = { |
573 | .suspend = ahci_pci_device_suspend, | 579 | .pm = &ahci_pci_pm_ops, |
574 | .resume = ahci_pci_device_resume, | 580 | }, |
575 | #endif | ||
576 | }; | 581 | }; |
577 | 582 | ||
578 | #if defined(CONFIG_PATA_MARVELL) || defined(CONFIG_PATA_MARVELL_MODULE) | 583 | #if defined(CONFIG_PATA_MARVELL) || defined(CONFIG_PATA_MARVELL_MODULE) |
@@ -801,42 +806,66 @@ static int ahci_avn_hardreset(struct ata_link *link, unsigned int *class, | |||
801 | 806 | ||
802 | 807 | ||
803 | #ifdef CONFIG_PM | 808 | #ifdef CONFIG_PM |
804 | static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg) | 809 | static void ahci_pci_disable_interrupts(struct ata_host *host) |
805 | { | 810 | { |
806 | struct ata_host *host = pci_get_drvdata(pdev); | ||
807 | struct ahci_host_priv *hpriv = host->private_data; | 811 | struct ahci_host_priv *hpriv = host->private_data; |
808 | void __iomem *mmio = hpriv->mmio; | 812 | void __iomem *mmio = hpriv->mmio; |
809 | u32 ctl; | 813 | u32 ctl; |
810 | 814 | ||
811 | if (mesg.event & PM_EVENT_SUSPEND && | 815 | /* AHCI spec rev1.1 section 8.3.3: |
812 | hpriv->flags & AHCI_HFLAG_NO_SUSPEND) { | 816 | * Software must disable interrupts prior to requesting a |
813 | dev_err(&pdev->dev, | 817 | * transition of the HBA to D3 state. |
814 | "BIOS update required for suspend/resume\n"); | 818 | */ |
815 | return -EIO; | 819 | ctl = readl(mmio + HOST_CTL); |
816 | } | 820 | ctl &= ~HOST_IRQ_EN; |
821 | writel(ctl, mmio + HOST_CTL); | ||
822 | readl(mmio + HOST_CTL); /* flush */ | ||
823 | } | ||
817 | 824 | ||
818 | if (mesg.event & PM_EVENT_SLEEP) { | 825 | static int ahci_pci_device_runtime_suspend(struct device *dev) |
819 | /* AHCI spec rev1.1 section 8.3.3: | 826 | { |
820 | * Software must disable interrupts prior to requesting a | 827 | struct pci_dev *pdev = to_pci_dev(dev); |
821 | * transition of the HBA to D3 state. | 828 | struct ata_host *host = pci_get_drvdata(pdev); |
822 | */ | ||
823 | ctl = readl(mmio + HOST_CTL); | ||
824 | ctl &= ~HOST_IRQ_EN; | ||
825 | writel(ctl, mmio + HOST_CTL); | ||
826 | readl(mmio + HOST_CTL); /* flush */ | ||
827 | } | ||
828 | 829 | ||
829 | return ata_pci_device_suspend(pdev, mesg); | 830 | ahci_pci_disable_interrupts(host); |
831 | return 0; | ||
830 | } | 832 | } |
831 | 833 | ||
832 | static int ahci_pci_device_resume(struct pci_dev *pdev) | 834 | static int ahci_pci_device_runtime_resume(struct device *dev) |
833 | { | 835 | { |
836 | struct pci_dev *pdev = to_pci_dev(dev); | ||
834 | struct ata_host *host = pci_get_drvdata(pdev); | 837 | struct ata_host *host = pci_get_drvdata(pdev); |
835 | int rc; | 838 | int rc; |
836 | 839 | ||
837 | rc = ata_pci_device_do_resume(pdev); | 840 | rc = ahci_pci_reset_controller(host); |
838 | if (rc) | 841 | if (rc) |
839 | return rc; | 842 | return rc; |
843 | ahci_pci_init_controller(host); | ||
844 | return 0; | ||
845 | } | ||
846 | |||
847 | #ifdef CONFIG_PM_SLEEP | ||
848 | static int ahci_pci_device_suspend(struct device *dev) | ||
849 | { | ||
850 | struct pci_dev *pdev = to_pci_dev(dev); | ||
851 | struct ata_host *host = pci_get_drvdata(pdev); | ||
852 | struct ahci_host_priv *hpriv = host->private_data; | ||
853 | |||
854 | if (hpriv->flags & AHCI_HFLAG_NO_SUSPEND) { | ||
855 | dev_err(&pdev->dev, | ||
856 | "BIOS update required for suspend/resume\n"); | ||
857 | return -EIO; | ||
858 | } | ||
859 | |||
860 | ahci_pci_disable_interrupts(host); | ||
861 | return ata_host_suspend(host, PMSG_SUSPEND); | ||
862 | } | ||
863 | |||
864 | static int ahci_pci_device_resume(struct device *dev) | ||
865 | { | ||
866 | struct pci_dev *pdev = to_pci_dev(dev); | ||
867 | struct ata_host *host = pci_get_drvdata(pdev); | ||
868 | int rc; | ||
840 | 869 | ||
841 | /* Apple BIOS helpfully mangles the registers on resume */ | 870 | /* Apple BIOS helpfully mangles the registers on resume */ |
842 | if (is_mcp89_apple(pdev)) | 871 | if (is_mcp89_apple(pdev)) |
@@ -856,6 +885,8 @@ static int ahci_pci_device_resume(struct pci_dev *pdev) | |||
856 | } | 885 | } |
857 | #endif | 886 | #endif |
858 | 887 | ||
888 | #endif /* CONFIG_PM */ | ||
889 | |||
859 | static int ahci_configure_dma_masks(struct pci_dev *pdev, int using_dac) | 890 | static int ahci_configure_dma_masks(struct pci_dev *pdev, int using_dac) |
860 | { | 891 | { |
861 | int rc; | 892 | int rc; |
@@ -1718,7 +1749,18 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1718 | 1749 | ||
1719 | pci_set_master(pdev); | 1750 | pci_set_master(pdev); |
1720 | 1751 | ||
1721 | return ahci_host_activate(host, &ahci_sht); | 1752 | rc = ahci_host_activate(host, &ahci_sht); |
1753 | if (rc) | ||
1754 | return rc; | ||
1755 | |||
1756 | pm_runtime_put_noidle(&pdev->dev); | ||
1757 | return 0; | ||
1758 | } | ||
1759 | |||
1760 | static void ahci_remove_one(struct pci_dev *pdev) | ||
1761 | { | ||
1762 | pm_runtime_get_noresume(&pdev->dev); | ||
1763 | ata_pci_remove_one(pdev); | ||
1722 | } | 1764 | } |
1723 | 1765 | ||
1724 | module_pci_driver(ahci_pci_driver); | 1766 | module_pci_driver(ahci_pci_driver); |
diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h index 167ba7e3b92e..70b06bcfb7e3 100644 --- a/drivers/ata/ahci.h +++ b/drivers/ata/ahci.h | |||
@@ -335,6 +335,7 @@ struct ahci_host_priv { | |||
335 | void __iomem * mmio; /* bus-independent mem map */ | 335 | void __iomem * mmio; /* bus-independent mem map */ |
336 | u32 cap; /* cap to use */ | 336 | u32 cap; /* cap to use */ |
337 | u32 cap2; /* cap2 to use */ | 337 | u32 cap2; /* cap2 to use */ |
338 | u32 version; /* cached version */ | ||
338 | u32 port_map; /* port map to use */ | 339 | u32 port_map; /* port map to use */ |
339 | u32 saved_cap; /* saved initial cap */ | 340 | u32 saved_cap; /* saved initial cap */ |
340 | u32 saved_cap2; /* saved initial cap2 */ | 341 | u32 saved_cap2; /* saved initial cap2 */ |
diff --git a/drivers/ata/ahci_mvebu.c b/drivers/ata/ahci_mvebu.c index f7a7fa81740e..de7128d81e9c 100644 --- a/drivers/ata/ahci_mvebu.c +++ b/drivers/ata/ahci_mvebu.c | |||
@@ -112,12 +112,15 @@ static int ahci_mvebu_probe(struct platform_device *pdev) | |||
112 | if (rc) | 112 | if (rc) |
113 | return rc; | 113 | return rc; |
114 | 114 | ||
115 | dram = mv_mbus_dram_info(); | 115 | if (of_device_is_compatible(pdev->dev.of_node, |
116 | if (!dram) | 116 | "marvell,armada-380-ahci")) { |
117 | return -ENODEV; | 117 | dram = mv_mbus_dram_info(); |
118 | if (!dram) | ||
119 | return -ENODEV; | ||
118 | 120 | ||
119 | ahci_mvebu_mbus_config(hpriv, dram); | 121 | ahci_mvebu_mbus_config(hpriv, dram); |
120 | ahci_mvebu_regret_option(hpriv); | 122 | ahci_mvebu_regret_option(hpriv); |
123 | } | ||
121 | 124 | ||
122 | rc = ahci_platform_init_host(pdev, hpriv, &ahci_mvebu_port_info, | 125 | rc = ahci_platform_init_host(pdev, hpriv, &ahci_mvebu_port_info, |
123 | &ahci_platform_sht); | 126 | &ahci_platform_sht); |
@@ -133,6 +136,7 @@ disable_resources: | |||
133 | 136 | ||
134 | static const struct of_device_id ahci_mvebu_of_match[] = { | 137 | static const struct of_device_id ahci_mvebu_of_match[] = { |
135 | { .compatible = "marvell,armada-380-ahci", }, | 138 | { .compatible = "marvell,armada-380-ahci", }, |
139 | { .compatible = "marvell,armada-3700-ahci", }, | ||
136 | { }, | 140 | { }, |
137 | }; | 141 | }; |
138 | MODULE_DEVICE_TABLE(of, ahci_mvebu_of_match); | 142 | MODULE_DEVICE_TABLE(of, ahci_mvebu_of_match); |
diff --git a/drivers/ata/ahci_octeon.c b/drivers/ata/ahci_octeon.c new file mode 100644 index 000000000000..ea865fe953e1 --- /dev/null +++ b/drivers/ata/ahci_octeon.c | |||
@@ -0,0 +1,105 @@ | |||
1 | /* | ||
2 | * SATA glue for Cavium Octeon III SOCs. | ||
3 | * | ||
4 | * | ||
5 | * This file is subject to the terms and conditions of the GNU General Public | ||
6 | * License. See the file "COPYING" in the main directory of this archive | ||
7 | * for more details. | ||
8 | * | ||
9 | * Copyright (C) 2010-2015 Cavium Networks | ||
10 | * | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/dma-mapping.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | #include <linux/of_platform.h> | ||
17 | |||
18 | #include <asm/octeon/octeon.h> | ||
19 | #include <asm/bitfield.h> | ||
20 | |||
21 | #define CVMX_SATA_UCTL_SHIM_CFG 0xE8 | ||
22 | |||
23 | #define SATA_UCTL_ENDIAN_MODE_BIG 1 | ||
24 | #define SATA_UCTL_ENDIAN_MODE_LITTLE 0 | ||
25 | #define SATA_UCTL_ENDIAN_MODE_MASK 3 | ||
26 | |||
27 | #define SATA_UCTL_DMA_ENDIAN_MODE_SHIFT 8 | ||
28 | #define SATA_UCTL_CSR_ENDIAN_MODE_SHIFT 0 | ||
29 | #define SATA_UCTL_DMA_READ_CMD_SHIFT 12 | ||
30 | |||
31 | static int ahci_octeon_probe(struct platform_device *pdev) | ||
32 | { | ||
33 | struct device *dev = &pdev->dev; | ||
34 | struct device_node *node = dev->of_node; | ||
35 | struct resource *res; | ||
36 | void __iomem *base; | ||
37 | u64 cfg; | ||
38 | int ret; | ||
39 | |||
40 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
41 | if (!res) { | ||
42 | dev_err(&pdev->dev, "Platform resource[0] is missing\n"); | ||
43 | return -ENODEV; | ||
44 | } | ||
45 | |||
46 | base = devm_ioremap_resource(&pdev->dev, res); | ||
47 | if (IS_ERR(base)) | ||
48 | return PTR_ERR(base); | ||
49 | |||
50 | cfg = cvmx_readq_csr(base + CVMX_SATA_UCTL_SHIM_CFG); | ||
51 | |||
52 | cfg &= ~(SATA_UCTL_ENDIAN_MODE_MASK << SATA_UCTL_DMA_ENDIAN_MODE_SHIFT); | ||
53 | cfg &= ~(SATA_UCTL_ENDIAN_MODE_MASK << SATA_UCTL_CSR_ENDIAN_MODE_SHIFT); | ||
54 | |||
55 | #ifdef __BIG_ENDIAN | ||
56 | cfg |= SATA_UCTL_ENDIAN_MODE_BIG << SATA_UCTL_DMA_ENDIAN_MODE_SHIFT; | ||
57 | cfg |= SATA_UCTL_ENDIAN_MODE_BIG << SATA_UCTL_CSR_ENDIAN_MODE_SHIFT; | ||
58 | #else | ||
59 | cfg |= SATA_UCTL_ENDIAN_MODE_LITTLE << SATA_UCTL_DMA_ENDIAN_MODE_SHIFT; | ||
60 | cfg |= SATA_UCTL_ENDIAN_MODE_LITTLE << SATA_UCTL_CSR_ENDIAN_MODE_SHIFT; | ||
61 | #endif | ||
62 | |||
63 | cfg |= 1 << SATA_UCTL_DMA_READ_CMD_SHIFT; | ||
64 | |||
65 | cvmx_writeq_csr(base + CVMX_SATA_UCTL_SHIM_CFG, cfg); | ||
66 | |||
67 | if (!node) { | ||
68 | dev_err(dev, "no device node, failed to add octeon sata\n"); | ||
69 | return -ENODEV; | ||
70 | } | ||
71 | |||
72 | ret = of_platform_populate(node, NULL, NULL, dev); | ||
73 | if (ret) { | ||
74 | dev_err(dev, "failed to add ahci-platform core\n"); | ||
75 | return ret; | ||
76 | } | ||
77 | |||
78 | return 0; | ||
79 | } | ||
80 | |||
81 | static int ahci_octeon_remove(struct platform_device *pdev) | ||
82 | { | ||
83 | return 0; | ||
84 | } | ||
85 | |||
86 | static const struct of_device_id octeon_ahci_match[] = { | ||
87 | { .compatible = "cavium,octeon-7130-sata-uctl", }, | ||
88 | {}, | ||
89 | }; | ||
90 | MODULE_DEVICE_TABLE(of, octeon_ahci_match); | ||
91 | |||
92 | static struct platform_driver ahci_octeon_driver = { | ||
93 | .probe = ahci_octeon_probe, | ||
94 | .remove = ahci_octeon_remove, | ||
95 | .driver = { | ||
96 | .name = "octeon-ahci", | ||
97 | .of_match_table = octeon_ahci_match, | ||
98 | }, | ||
99 | }; | ||
100 | |||
101 | module_platform_driver(ahci_octeon_driver); | ||
102 | |||
103 | MODULE_LICENSE("GPL"); | ||
104 | MODULE_AUTHOR("Cavium, Inc. <support@cavium.com>"); | ||
105 | MODULE_DESCRIPTION("Cavium Inc. sata config."); | ||
diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c index 04975b851c23..40442332bfa7 100644 --- a/drivers/ata/ahci_platform.c +++ b/drivers/ata/ahci_platform.c | |||
@@ -76,6 +76,7 @@ static const struct of_device_id ahci_of_match[] = { | |||
76 | { .compatible = "ibm,476gtr-ahci", }, | 76 | { .compatible = "ibm,476gtr-ahci", }, |
77 | { .compatible = "snps,dwc-ahci", }, | 77 | { .compatible = "snps,dwc-ahci", }, |
78 | { .compatible = "hisilicon,hisi-ahci", }, | 78 | { .compatible = "hisilicon,hisi-ahci", }, |
79 | { .compatible = "cavium,octeon-7130-ahci", }, | ||
79 | {}, | 80 | {}, |
80 | }; | 81 | }; |
81 | MODULE_DEVICE_TABLE(of, ahci_of_match); | 82 | MODULE_DEVICE_TABLE(of, ahci_of_match); |
diff --git a/drivers/ata/ahci_xgene.c b/drivers/ata/ahci_xgene.c index 8e3f7faf00d3..73b19b277138 100644 --- a/drivers/ata/ahci_xgene.c +++ b/drivers/ata/ahci_xgene.c | |||
@@ -821,9 +821,9 @@ static int xgene_ahci_probe(struct platform_device *pdev) | |||
821 | dev_warn(&pdev->dev, "%s: Error reading device info. Assume version1\n", | 821 | dev_warn(&pdev->dev, "%s: Error reading device info. Assume version1\n", |
822 | __func__); | 822 | __func__); |
823 | version = XGENE_AHCI_V1; | 823 | version = XGENE_AHCI_V1; |
824 | } | 824 | } else if (info->valid & ACPI_VALID_CID) { |
825 | if (info->valid & ACPI_VALID_CID) | ||
826 | version = XGENE_AHCI_V2; | 825 | version = XGENE_AHCI_V2; |
826 | } | ||
827 | } | 827 | } |
828 | } | 828 | } |
829 | #endif | 829 | #endif |
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index 85ea5142a095..3982054060b8 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c | |||
@@ -225,6 +225,31 @@ static void ahci_enable_ahci(void __iomem *mmio) | |||
225 | WARN_ON(1); | 225 | WARN_ON(1); |
226 | } | 226 | } |
227 | 227 | ||
228 | /** | ||
229 | * ahci_rpm_get_port - Make sure the port is powered on | ||
230 | * @ap: Port to power on | ||
231 | * | ||
232 | * Whenever there is need to access the AHCI host registers outside of | ||
233 | * normal execution paths, call this function to make sure the host is | ||
234 | * actually powered on. | ||
235 | */ | ||
236 | static int ahci_rpm_get_port(struct ata_port *ap) | ||
237 | { | ||
238 | return pm_runtime_get_sync(ap->dev); | ||
239 | } | ||
240 | |||
241 | /** | ||
242 | * ahci_rpm_put_port - Undoes ahci_rpm_get_port() | ||
243 | * @ap: Port to power down | ||
244 | * | ||
245 | * Undoes ahci_rpm_get_port() and possibly powers down the AHCI host | ||
246 | * if it has no more active users. | ||
247 | */ | ||
248 | static void ahci_rpm_put_port(struct ata_port *ap) | ||
249 | { | ||
250 | pm_runtime_put(ap->dev); | ||
251 | } | ||
252 | |||
228 | static ssize_t ahci_show_host_caps(struct device *dev, | 253 | static ssize_t ahci_show_host_caps(struct device *dev, |
229 | struct device_attribute *attr, char *buf) | 254 | struct device_attribute *attr, char *buf) |
230 | { | 255 | { |
@@ -251,9 +276,8 @@ static ssize_t ahci_show_host_version(struct device *dev, | |||
251 | struct Scsi_Host *shost = class_to_shost(dev); | 276 | struct Scsi_Host *shost = class_to_shost(dev); |
252 | struct ata_port *ap = ata_shost_to_port(shost); | 277 | struct ata_port *ap = ata_shost_to_port(shost); |
253 | struct ahci_host_priv *hpriv = ap->host->private_data; | 278 | struct ahci_host_priv *hpriv = ap->host->private_data; |
254 | void __iomem *mmio = hpriv->mmio; | ||
255 | 279 | ||
256 | return sprintf(buf, "%x\n", readl(mmio + HOST_VERSION)); | 280 | return sprintf(buf, "%x\n", hpriv->version); |
257 | } | 281 | } |
258 | 282 | ||
259 | static ssize_t ahci_show_port_cmd(struct device *dev, | 283 | static ssize_t ahci_show_port_cmd(struct device *dev, |
@@ -262,8 +286,13 @@ static ssize_t ahci_show_port_cmd(struct device *dev, | |||
262 | struct Scsi_Host *shost = class_to_shost(dev); | 286 | struct Scsi_Host *shost = class_to_shost(dev); |
263 | struct ata_port *ap = ata_shost_to_port(shost); | 287 | struct ata_port *ap = ata_shost_to_port(shost); |
264 | void __iomem *port_mmio = ahci_port_base(ap); | 288 | void __iomem *port_mmio = ahci_port_base(ap); |
289 | ssize_t ret; | ||
290 | |||
291 | ahci_rpm_get_port(ap); | ||
292 | ret = sprintf(buf, "%x\n", readl(port_mmio + PORT_CMD)); | ||
293 | ahci_rpm_put_port(ap); | ||
265 | 294 | ||
266 | return sprintf(buf, "%x\n", readl(port_mmio + PORT_CMD)); | 295 | return ret; |
267 | } | 296 | } |
268 | 297 | ||
269 | static ssize_t ahci_read_em_buffer(struct device *dev, | 298 | static ssize_t ahci_read_em_buffer(struct device *dev, |
@@ -279,17 +308,20 @@ static ssize_t ahci_read_em_buffer(struct device *dev, | |||
279 | size_t count; | 308 | size_t count; |
280 | int i; | 309 | int i; |
281 | 310 | ||
311 | ahci_rpm_get_port(ap); | ||
282 | spin_lock_irqsave(ap->lock, flags); | 312 | spin_lock_irqsave(ap->lock, flags); |
283 | 313 | ||
284 | em_ctl = readl(mmio + HOST_EM_CTL); | 314 | em_ctl = readl(mmio + HOST_EM_CTL); |
285 | if (!(ap->flags & ATA_FLAG_EM) || em_ctl & EM_CTL_XMT || | 315 | if (!(ap->flags & ATA_FLAG_EM) || em_ctl & EM_CTL_XMT || |
286 | !(hpriv->em_msg_type & EM_MSG_TYPE_SGPIO)) { | 316 | !(hpriv->em_msg_type & EM_MSG_TYPE_SGPIO)) { |
287 | spin_unlock_irqrestore(ap->lock, flags); | 317 | spin_unlock_irqrestore(ap->lock, flags); |
318 | ahci_rpm_put_port(ap); | ||
288 | return -EINVAL; | 319 | return -EINVAL; |
289 | } | 320 | } |
290 | 321 | ||
291 | if (!(em_ctl & EM_CTL_MR)) { | 322 | if (!(em_ctl & EM_CTL_MR)) { |
292 | spin_unlock_irqrestore(ap->lock, flags); | 323 | spin_unlock_irqrestore(ap->lock, flags); |
324 | ahci_rpm_put_port(ap); | ||
293 | return -EAGAIN; | 325 | return -EAGAIN; |
294 | } | 326 | } |
295 | 327 | ||
@@ -317,6 +349,7 @@ static ssize_t ahci_read_em_buffer(struct device *dev, | |||
317 | } | 349 | } |
318 | 350 | ||
319 | spin_unlock_irqrestore(ap->lock, flags); | 351 | spin_unlock_irqrestore(ap->lock, flags); |
352 | ahci_rpm_put_port(ap); | ||
320 | 353 | ||
321 | return i; | 354 | return i; |
322 | } | 355 | } |
@@ -341,11 +374,13 @@ static ssize_t ahci_store_em_buffer(struct device *dev, | |||
341 | size % 4 || size > hpriv->em_buf_sz) | 374 | size % 4 || size > hpriv->em_buf_sz) |
342 | return -EINVAL; | 375 | return -EINVAL; |
343 | 376 | ||
377 | ahci_rpm_get_port(ap); | ||
344 | spin_lock_irqsave(ap->lock, flags); | 378 | spin_lock_irqsave(ap->lock, flags); |
345 | 379 | ||
346 | em_ctl = readl(mmio + HOST_EM_CTL); | 380 | em_ctl = readl(mmio + HOST_EM_CTL); |
347 | if (em_ctl & EM_CTL_TM) { | 381 | if (em_ctl & EM_CTL_TM) { |
348 | spin_unlock_irqrestore(ap->lock, flags); | 382 | spin_unlock_irqrestore(ap->lock, flags); |
383 | ahci_rpm_put_port(ap); | ||
349 | return -EBUSY; | 384 | return -EBUSY; |
350 | } | 385 | } |
351 | 386 | ||
@@ -358,6 +393,7 @@ static ssize_t ahci_store_em_buffer(struct device *dev, | |||
358 | writel(em_ctl | EM_CTL_TM, mmio + HOST_EM_CTL); | 393 | writel(em_ctl | EM_CTL_TM, mmio + HOST_EM_CTL); |
359 | 394 | ||
360 | spin_unlock_irqrestore(ap->lock, flags); | 395 | spin_unlock_irqrestore(ap->lock, flags); |
396 | ahci_rpm_put_port(ap); | ||
361 | 397 | ||
362 | return size; | 398 | return size; |
363 | } | 399 | } |
@@ -371,7 +407,9 @@ static ssize_t ahci_show_em_supported(struct device *dev, | |||
371 | void __iomem *mmio = hpriv->mmio; | 407 | void __iomem *mmio = hpriv->mmio; |
372 | u32 em_ctl; | 408 | u32 em_ctl; |
373 | 409 | ||
410 | ahci_rpm_get_port(ap); | ||
374 | em_ctl = readl(mmio + HOST_EM_CTL); | 411 | em_ctl = readl(mmio + HOST_EM_CTL); |
412 | ahci_rpm_put_port(ap); | ||
375 | 413 | ||
376 | return sprintf(buf, "%s%s%s%s\n", | 414 | return sprintf(buf, "%s%s%s%s\n", |
377 | em_ctl & EM_CTL_LED ? "led " : "", | 415 | em_ctl & EM_CTL_LED ? "led " : "", |
@@ -509,6 +547,7 @@ void ahci_save_initial_config(struct device *dev, struct ahci_host_priv *hpriv) | |||
509 | /* record values to use during operation */ | 547 | /* record values to use during operation */ |
510 | hpriv->cap = cap; | 548 | hpriv->cap = cap; |
511 | hpriv->cap2 = cap2; | 549 | hpriv->cap2 = cap2; |
550 | hpriv->version = readl(mmio + HOST_VERSION); | ||
512 | hpriv->port_map = port_map; | 551 | hpriv->port_map = port_map; |
513 | 552 | ||
514 | if (!hpriv->start_engine) | 553 | if (!hpriv->start_engine) |
@@ -1014,6 +1053,7 @@ static ssize_t ahci_transmit_led_message(struct ata_port *ap, u32 state, | |||
1014 | else | 1053 | else |
1015 | return -EINVAL; | 1054 | return -EINVAL; |
1016 | 1055 | ||
1056 | ahci_rpm_get_port(ap); | ||
1017 | spin_lock_irqsave(ap->lock, flags); | 1057 | spin_lock_irqsave(ap->lock, flags); |
1018 | 1058 | ||
1019 | /* | 1059 | /* |
@@ -1023,6 +1063,7 @@ static ssize_t ahci_transmit_led_message(struct ata_port *ap, u32 state, | |||
1023 | em_ctl = readl(mmio + HOST_EM_CTL); | 1063 | em_ctl = readl(mmio + HOST_EM_CTL); |
1024 | if (em_ctl & EM_CTL_TM) { | 1064 | if (em_ctl & EM_CTL_TM) { |
1025 | spin_unlock_irqrestore(ap->lock, flags); | 1065 | spin_unlock_irqrestore(ap->lock, flags); |
1066 | ahci_rpm_put_port(ap); | ||
1026 | return -EBUSY; | 1067 | return -EBUSY; |
1027 | } | 1068 | } |
1028 | 1069 | ||
@@ -1050,6 +1091,8 @@ static ssize_t ahci_transmit_led_message(struct ata_port *ap, u32 state, | |||
1050 | emp->led_state = state; | 1091 | emp->led_state = state; |
1051 | 1092 | ||
1052 | spin_unlock_irqrestore(ap->lock, flags); | 1093 | spin_unlock_irqrestore(ap->lock, flags); |
1094 | ahci_rpm_put_port(ap); | ||
1095 | |||
1053 | return size; | 1096 | return size; |
1054 | } | 1097 | } |
1055 | 1098 | ||
@@ -2215,6 +2258,8 @@ static void ahci_pmp_detach(struct ata_port *ap) | |||
2215 | 2258 | ||
2216 | int ahci_port_resume(struct ata_port *ap) | 2259 | int ahci_port_resume(struct ata_port *ap) |
2217 | { | 2260 | { |
2261 | ahci_rpm_get_port(ap); | ||
2262 | |||
2218 | ahci_power_up(ap); | 2263 | ahci_power_up(ap); |
2219 | ahci_start_port(ap); | 2264 | ahci_start_port(ap); |
2220 | 2265 | ||
@@ -2241,6 +2286,7 @@ static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg) | |||
2241 | ata_port_freeze(ap); | 2286 | ata_port_freeze(ap); |
2242 | } | 2287 | } |
2243 | 2288 | ||
2289 | ahci_rpm_put_port(ap); | ||
2244 | return rc; | 2290 | return rc; |
2245 | } | 2291 | } |
2246 | #endif | 2292 | #endif |
@@ -2356,11 +2402,10 @@ static void ahci_port_stop(struct ata_port *ap) | |||
2356 | void ahci_print_info(struct ata_host *host, const char *scc_s) | 2402 | void ahci_print_info(struct ata_host *host, const char *scc_s) |
2357 | { | 2403 | { |
2358 | struct ahci_host_priv *hpriv = host->private_data; | 2404 | struct ahci_host_priv *hpriv = host->private_data; |
2359 | void __iomem *mmio = hpriv->mmio; | ||
2360 | u32 vers, cap, cap2, impl, speed; | 2405 | u32 vers, cap, cap2, impl, speed; |
2361 | const char *speed_s; | 2406 | const char *speed_s; |
2362 | 2407 | ||
2363 | vers = readl(mmio + HOST_VERSION); | 2408 | vers = hpriv->version; |
2364 | cap = hpriv->cap; | 2409 | cap = hpriv->cap; |
2365 | cap2 = hpriv->cap2; | 2410 | cap2 = hpriv->cap2; |
2366 | impl = hpriv->port_map; | 2411 | impl = hpriv->port_map; |
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index e417e1a1d02c..567859ce0512 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c | |||
@@ -174,13 +174,13 @@ static ssize_t ata_scsi_park_show(struct device *device, | |||
174 | struct ata_port *ap; | 174 | struct ata_port *ap; |
175 | struct ata_link *link; | 175 | struct ata_link *link; |
176 | struct ata_device *dev; | 176 | struct ata_device *dev; |
177 | unsigned long flags, now; | 177 | unsigned long now; |
178 | unsigned int uninitialized_var(msecs); | 178 | unsigned int uninitialized_var(msecs); |
179 | int rc = 0; | 179 | int rc = 0; |
180 | 180 | ||
181 | ap = ata_shost_to_port(sdev->host); | 181 | ap = ata_shost_to_port(sdev->host); |
182 | 182 | ||
183 | spin_lock_irqsave(ap->lock, flags); | 183 | spin_lock_irq(ap->lock); |
184 | dev = ata_scsi_find_dev(ap, sdev); | 184 | dev = ata_scsi_find_dev(ap, sdev); |
185 | if (!dev) { | 185 | if (!dev) { |
186 | rc = -ENODEV; | 186 | rc = -ENODEV; |
diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c index 17d31fc009ab..0636d84fbefe 100644 --- a/drivers/ata/sata_via.c +++ b/drivers/ata/sata_via.c | |||
@@ -61,6 +61,7 @@ enum { | |||
61 | SATA_CHAN_ENAB = 0x40, /* SATA channel enable */ | 61 | SATA_CHAN_ENAB = 0x40, /* SATA channel enable */ |
62 | SATA_INT_GATE = 0x41, /* SATA interrupt gating */ | 62 | SATA_INT_GATE = 0x41, /* SATA interrupt gating */ |
63 | SATA_NATIVE_MODE = 0x42, /* Native mode enable */ | 63 | SATA_NATIVE_MODE = 0x42, /* Native mode enable */ |
64 | SVIA_MISC_3 = 0x46, /* Miscellaneous Control III */ | ||
64 | PATA_UDMA_TIMING = 0xB3, /* PATA timing for DMA/ cable detect */ | 65 | PATA_UDMA_TIMING = 0xB3, /* PATA timing for DMA/ cable detect */ |
65 | PATA_PIO_TIMING = 0xAB, /* PATA timing register */ | 66 | PATA_PIO_TIMING = 0xAB, /* PATA timing register */ |
66 | 67 | ||
@@ -71,9 +72,18 @@ enum { | |||
71 | NATIVE_MODE_ALL = (1 << 7) | (1 << 6) | (1 << 5) | (1 << 4), | 72 | NATIVE_MODE_ALL = (1 << 7) | (1 << 6) | (1 << 5) | (1 << 4), |
72 | 73 | ||
73 | SATA_EXT_PHY = (1 << 6), /* 0==use PATA, 1==ext phy */ | 74 | SATA_EXT_PHY = (1 << 6), /* 0==use PATA, 1==ext phy */ |
75 | |||
76 | SATA_HOTPLUG = (1 << 5), /* enable IRQ on hotplug */ | ||
77 | }; | ||
78 | |||
79 | struct svia_priv { | ||
80 | bool wd_workaround; | ||
74 | }; | 81 | }; |
75 | 82 | ||
76 | static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); | 83 | static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); |
84 | #ifdef CONFIG_PM_SLEEP | ||
85 | static int svia_pci_device_resume(struct pci_dev *pdev); | ||
86 | #endif | ||
77 | static int svia_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val); | 87 | static int svia_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val); |
78 | static int svia_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val); | 88 | static int svia_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val); |
79 | static int vt8251_scr_read(struct ata_link *link, unsigned int scr, u32 *val); | 89 | static int vt8251_scr_read(struct ata_link *link, unsigned int scr, u32 *val); |
@@ -85,6 +95,7 @@ static void vt6420_bmdma_start(struct ata_queued_cmd *qc); | |||
85 | static int vt6421_pata_cable_detect(struct ata_port *ap); | 95 | static int vt6421_pata_cable_detect(struct ata_port *ap); |
86 | static void vt6421_set_pio_mode(struct ata_port *ap, struct ata_device *adev); | 96 | static void vt6421_set_pio_mode(struct ata_port *ap, struct ata_device *adev); |
87 | static void vt6421_set_dma_mode(struct ata_port *ap, struct ata_device *adev); | 97 | static void vt6421_set_dma_mode(struct ata_port *ap, struct ata_device *adev); |
98 | static void vt6421_error_handler(struct ata_port *ap); | ||
88 | 99 | ||
89 | static const struct pci_device_id svia_pci_tbl[] = { | 100 | static const struct pci_device_id svia_pci_tbl[] = { |
90 | { PCI_VDEVICE(VIA, 0x5337), vt6420 }, | 101 | { PCI_VDEVICE(VIA, 0x5337), vt6420 }, |
@@ -105,7 +116,7 @@ static struct pci_driver svia_pci_driver = { | |||
105 | .probe = svia_init_one, | 116 | .probe = svia_init_one, |
106 | #ifdef CONFIG_PM_SLEEP | 117 | #ifdef CONFIG_PM_SLEEP |
107 | .suspend = ata_pci_device_suspend, | 118 | .suspend = ata_pci_device_suspend, |
108 | .resume = ata_pci_device_resume, | 119 | .resume = svia_pci_device_resume, |
109 | #endif | 120 | #endif |
110 | .remove = ata_pci_remove_one, | 121 | .remove = ata_pci_remove_one, |
111 | }; | 122 | }; |
@@ -137,6 +148,7 @@ static struct ata_port_operations vt6421_sata_ops = { | |||
137 | .inherits = &svia_base_ops, | 148 | .inherits = &svia_base_ops, |
138 | .scr_read = svia_scr_read, | 149 | .scr_read = svia_scr_read, |
139 | .scr_write = svia_scr_write, | 150 | .scr_write = svia_scr_write, |
151 | .error_handler = vt6421_error_handler, | ||
140 | }; | 152 | }; |
141 | 153 | ||
142 | static struct ata_port_operations vt8251_ops = { | 154 | static struct ata_port_operations vt8251_ops = { |
@@ -536,7 +548,67 @@ static int vt8251_prepare_host(struct pci_dev *pdev, struct ata_host **r_host) | |||
536 | return 0; | 548 | return 0; |
537 | } | 549 | } |
538 | 550 | ||
539 | static void svia_configure(struct pci_dev *pdev, int board_id) | 551 | static void svia_wd_fix(struct pci_dev *pdev) |
552 | { | ||
553 | u8 tmp8; | ||
554 | |||
555 | pci_read_config_byte(pdev, 0x52, &tmp8); | ||
556 | pci_write_config_byte(pdev, 0x52, tmp8 | BIT(2)); | ||
557 | } | ||
558 | |||
559 | static irqreturn_t vt6421_interrupt(int irq, void *dev_instance) | ||
560 | { | ||
561 | struct ata_host *host = dev_instance; | ||
562 | irqreturn_t rc = ata_bmdma_interrupt(irq, dev_instance); | ||
563 | |||
564 | /* if the IRQ was not handled, it might be a hotplug IRQ */ | ||
565 | if (rc != IRQ_HANDLED) { | ||
566 | u32 serror; | ||
567 | unsigned long flags; | ||
568 | |||
569 | spin_lock_irqsave(&host->lock, flags); | ||
570 | /* check for hotplug on port 0 */ | ||
571 | svia_scr_read(&host->ports[0]->link, SCR_ERROR, &serror); | ||
572 | if (serror & SERR_PHYRDY_CHG) { | ||
573 | ata_ehi_hotplugged(&host->ports[0]->link.eh_info); | ||
574 | ata_port_freeze(host->ports[0]); | ||
575 | rc = IRQ_HANDLED; | ||
576 | } | ||
577 | /* check for hotplug on port 1 */ | ||
578 | svia_scr_read(&host->ports[1]->link, SCR_ERROR, &serror); | ||
579 | if (serror & SERR_PHYRDY_CHG) { | ||
580 | ata_ehi_hotplugged(&host->ports[1]->link.eh_info); | ||
581 | ata_port_freeze(host->ports[1]); | ||
582 | rc = IRQ_HANDLED; | ||
583 | } | ||
584 | spin_unlock_irqrestore(&host->lock, flags); | ||
585 | } | ||
586 | |||
587 | return rc; | ||
588 | } | ||
589 | |||
590 | static void vt6421_error_handler(struct ata_port *ap) | ||
591 | { | ||
592 | struct svia_priv *hpriv = ap->host->private_data; | ||
593 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); | ||
594 | u32 serror; | ||
595 | |||
596 | /* see svia_configure() for description */ | ||
597 | if (!hpriv->wd_workaround) { | ||
598 | svia_scr_read(&ap->link, SCR_ERROR, &serror); | ||
599 | if (serror == 0x1000500) { | ||
600 | ata_port_warn(ap, "Incompatible drive: enabling workaround. This slows down transfer rate to ~60 MB/s"); | ||
601 | svia_wd_fix(pdev); | ||
602 | hpriv->wd_workaround = true; | ||
603 | ap->link.eh_context.i.flags |= ATA_EHI_QUIET; | ||
604 | } | ||
605 | } | ||
606 | |||
607 | ata_sff_error_handler(ap); | ||
608 | } | ||
609 | |||
610 | static void svia_configure(struct pci_dev *pdev, int board_id, | ||
611 | struct svia_priv *hpriv) | ||
540 | { | 612 | { |
541 | u8 tmp8; | 613 | u8 tmp8; |
542 | 614 | ||
@@ -572,6 +644,16 @@ static void svia_configure(struct pci_dev *pdev, int board_id) | |||
572 | pci_write_config_byte(pdev, SATA_NATIVE_MODE, tmp8); | 644 | pci_write_config_byte(pdev, SATA_NATIVE_MODE, tmp8); |
573 | } | 645 | } |
574 | 646 | ||
647 | /* enable IRQ on hotplug */ | ||
648 | pci_read_config_byte(pdev, SVIA_MISC_3, &tmp8); | ||
649 | if ((tmp8 & SATA_HOTPLUG) != SATA_HOTPLUG) { | ||
650 | dev_dbg(&pdev->dev, | ||
651 | "enabling SATA hotplug (0x%x)\n", | ||
652 | (int) tmp8); | ||
653 | tmp8 |= SATA_HOTPLUG; | ||
654 | pci_write_config_byte(pdev, SVIA_MISC_3, tmp8); | ||
655 | } | ||
656 | |||
575 | /* | 657 | /* |
576 | * vt6420/1 has problems talking to some drives. The following | 658 | * vt6420/1 has problems talking to some drives. The following |
577 | * is the fix from Joseph Chan <JosephChan@via.com.tw>. | 659 | * is the fix from Joseph Chan <JosephChan@via.com.tw>. |
@@ -593,11 +675,15 @@ static void svia_configure(struct pci_dev *pdev, int board_id) | |||
593 | * https://bugzilla.kernel.org/show_bug.cgi?id=15173 | 675 | * https://bugzilla.kernel.org/show_bug.cgi?id=15173 |
594 | * http://article.gmane.org/gmane.linux.ide/46352 | 676 | * http://article.gmane.org/gmane.linux.ide/46352 |
595 | * http://thread.gmane.org/gmane.linux.kernel/1062139 | 677 | * http://thread.gmane.org/gmane.linux.kernel/1062139 |
678 | * | ||
679 | * As the fix slows down data transfer, apply it only if the error | ||
680 | * actually appears - see vt6421_error_handler() | ||
681 | * Apply the fix always on vt6420 as we don't know if SCR_ERROR can be | ||
682 | * read safely. | ||
596 | */ | 683 | */ |
597 | if (board_id == vt6420 || board_id == vt6421) { | 684 | if (board_id == vt6420) { |
598 | pci_read_config_byte(pdev, 0x52, &tmp8); | 685 | svia_wd_fix(pdev); |
599 | tmp8 |= 1 << 2; | 686 | hpriv->wd_workaround = true; |
600 | pci_write_config_byte(pdev, 0x52, tmp8); | ||
601 | } | 687 | } |
602 | } | 688 | } |
603 | 689 | ||
@@ -608,6 +694,7 @@ static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
608 | struct ata_host *host = NULL; | 694 | struct ata_host *host = NULL; |
609 | int board_id = (int) ent->driver_data; | 695 | int board_id = (int) ent->driver_data; |
610 | const unsigned *bar_sizes; | 696 | const unsigned *bar_sizes; |
697 | struct svia_priv *hpriv; | ||
611 | 698 | ||
612 | ata_print_version_once(&pdev->dev, DRV_VERSION); | 699 | ata_print_version_once(&pdev->dev, DRV_VERSION); |
613 | 700 | ||
@@ -647,11 +734,39 @@ static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
647 | if (rc) | 734 | if (rc) |
648 | return rc; | 735 | return rc; |
649 | 736 | ||
650 | svia_configure(pdev, board_id); | 737 | hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL); |
738 | if (!hpriv) | ||
739 | return -ENOMEM; | ||
740 | host->private_data = hpriv; | ||
741 | |||
742 | svia_configure(pdev, board_id, hpriv); | ||
651 | 743 | ||
652 | pci_set_master(pdev); | 744 | pci_set_master(pdev); |
653 | return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt, | 745 | if (board_id == vt6421) |
654 | IRQF_SHARED, &svia_sht); | 746 | return ata_host_activate(host, pdev->irq, vt6421_interrupt, |
747 | IRQF_SHARED, &svia_sht); | ||
748 | else | ||
749 | return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt, | ||
750 | IRQF_SHARED, &svia_sht); | ||
751 | } | ||
752 | |||
753 | #ifdef CONFIG_PM_SLEEP | ||
754 | static int svia_pci_device_resume(struct pci_dev *pdev) | ||
755 | { | ||
756 | struct ata_host *host = pci_get_drvdata(pdev); | ||
757 | struct svia_priv *hpriv = host->private_data; | ||
758 | int rc; | ||
759 | |||
760 | rc = ata_pci_device_do_resume(pdev); | ||
761 | if (rc) | ||
762 | return rc; | ||
763 | |||
764 | if (hpriv->wd_workaround) | ||
765 | svia_wd_fix(pdev); | ||
766 | ata_host_resume(host); | ||
767 | |||
768 | return 0; | ||
655 | } | 769 | } |
770 | #endif | ||
656 | 771 | ||
657 | module_pci_driver(svia_pci_driver); | 772 | module_pci_driver(svia_pci_driver); |
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index 94025c5cf797..1547bd93c70b 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c | |||
@@ -250,6 +250,12 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev, | |||
250 | if (error) | 250 | if (error) |
251 | goto out_destroy_freelist; | 251 | goto out_destroy_freelist; |
252 | 252 | ||
253 | /* | ||
254 | * Increase usage count temporarily here so that calling | ||
255 | * scsi_autopm_put_host() will trigger runtime idle if there is | ||
256 | * nothing else preventing suspending the device. | ||
257 | */ | ||
258 | pm_runtime_get_noresume(&shost->shost_gendev); | ||
253 | pm_runtime_set_active(&shost->shost_gendev); | 259 | pm_runtime_set_active(&shost->shost_gendev); |
254 | pm_runtime_enable(&shost->shost_gendev); | 260 | pm_runtime_enable(&shost->shost_gendev); |
255 | device_enable_async_suspend(&shost->shost_gendev); | 261 | device_enable_async_suspend(&shost->shost_gendev); |
@@ -290,6 +296,7 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev, | |||
290 | goto out_destroy_host; | 296 | goto out_destroy_host; |
291 | 297 | ||
292 | scsi_proc_host_add(shost); | 298 | scsi_proc_host_add(shost); |
299 | scsi_autopm_put_host(shost); | ||
293 | return error; | 300 | return error; |
294 | 301 | ||
295 | out_destroy_host: | 302 | out_destroy_host: |
diff --git a/drivers/scsi/scsi_pm.c b/drivers/scsi/scsi_pm.c index 459abe1dcc87..b44c1bb687a2 100644 --- a/drivers/scsi/scsi_pm.c +++ b/drivers/scsi/scsi_pm.c | |||
@@ -139,6 +139,16 @@ static int scsi_bus_resume_common(struct device *dev, | |||
139 | else | 139 | else |
140 | fn = NULL; | 140 | fn = NULL; |
141 | 141 | ||
142 | /* | ||
143 | * Forcibly set runtime PM status of request queue to "active" to | ||
144 | * make sure we can again get requests from the queue (see also | ||
145 | * blk_pm_peek_request()). | ||
146 | * | ||
147 | * The resume hook will correct runtime PM status of the disk. | ||
148 | */ | ||
149 | if (scsi_is_sdev_device(dev) && pm_runtime_suspended(dev)) | ||
150 | blk_set_runtime_active(to_scsi_device(dev)->request_queue); | ||
151 | |||
142 | if (fn) { | 152 | if (fn) { |
143 | async_schedule_domain(fn, dev, &scsi_sd_pm_domain); | 153 | async_schedule_domain(fn, dev, &scsi_sd_pm_domain); |
144 | 154 | ||
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 413c84fbc4ed..8a11b69dfc08 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h | |||
@@ -1029,6 +1029,7 @@ extern int blk_pre_runtime_suspend(struct request_queue *q); | |||
1029 | extern void blk_post_runtime_suspend(struct request_queue *q, int err); | 1029 | extern void blk_post_runtime_suspend(struct request_queue *q, int err); |
1030 | extern void blk_pre_runtime_resume(struct request_queue *q); | 1030 | extern void blk_pre_runtime_resume(struct request_queue *q); |
1031 | extern void blk_post_runtime_resume(struct request_queue *q, int err); | 1031 | extern void blk_post_runtime_resume(struct request_queue *q, int err); |
1032 | extern void blk_set_runtime_active(struct request_queue *q); | ||
1032 | #else | 1033 | #else |
1033 | static inline void blk_pm_runtime_init(struct request_queue *q, | 1034 | static inline void blk_pm_runtime_init(struct request_queue *q, |
1034 | struct device *dev) {} | 1035 | struct device *dev) {} |
@@ -1039,6 +1040,7 @@ static inline int blk_pre_runtime_suspend(struct request_queue *q) | |||
1039 | static inline void blk_post_runtime_suspend(struct request_queue *q, int err) {} | 1040 | static inline void blk_post_runtime_suspend(struct request_queue *q, int err) {} |
1040 | static inline void blk_pre_runtime_resume(struct request_queue *q) {} | 1041 | static inline void blk_pre_runtime_resume(struct request_queue *q) {} |
1041 | static inline void blk_post_runtime_resume(struct request_queue *q, int err) {} | 1042 | static inline void blk_post_runtime_resume(struct request_queue *q, int err) {} |
1043 | extern inline void blk_set_runtime_active(struct request_queue *q) {} | ||
1042 | #endif | 1044 | #endif |
1043 | 1045 | ||
1044 | /* | 1046 | /* |