aboutsummaryrefslogtreecommitdiff
path: root/drivers/ata
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/acard-ahci.c13
-rw-r--r--drivers/ata/ahci.c63
-rw-r--r--drivers/ata/ahci_platform.c10
-rw-r--r--drivers/ata/ata_generic.c15
-rw-r--r--drivers/ata/libata-acpi.c408
-rw-r--r--drivers/ata/libata-core.c16
-rw-r--r--drivers/ata/libata-eh.c59
-rw-r--r--drivers/ata/libata-pmp.c4
-rw-r--r--drivers/ata/libata-scsi.c3
-rw-r--r--drivers/ata/libata-transport.c6
-rw-r--r--drivers/ata/libata.h15
-rw-r--r--drivers/ata/pata_acpi.c18
-rw-r--r--drivers/ata/pata_amd.c13
-rw-r--r--drivers/ata/pata_arasan_cf.c4
-rw-r--r--drivers/ata/pata_artop.c13
-rw-r--r--drivers/ata/pata_atiixp.c14
-rw-r--r--drivers/ata/pata_atp867x.c13
-rw-r--r--drivers/ata/pata_cmd640.c13
-rw-r--r--drivers/ata/pata_cmd64x.c17
-rw-r--r--drivers/ata/pata_cs5520.c14
-rw-r--r--drivers/ata/pata_cs5530.c13
-rw-r--r--drivers/ata/pata_cs5535.c13
-rw-r--r--drivers/ata/pata_cs5536.c13
-rw-r--r--drivers/ata/pata_cypress.c15
-rw-r--r--drivers/ata/pata_efar.c14
-rw-r--r--drivers/ata/pata_hpt366.c13
-rw-r--r--drivers/ata/pata_hpt37x.c13
-rw-r--r--drivers/ata/pata_hpt3x2n.c13
-rw-r--r--drivers/ata/pata_hpt3x3.c15
-rw-r--r--drivers/ata/pata_imx.c10
-rw-r--r--drivers/ata/pata_it8213.c13
-rw-r--r--drivers/ata/pata_it821x.c14
-rw-r--r--drivers/ata/pata_jmicron.c13
-rw-r--r--drivers/ata/pata_marvell.c14
-rw-r--r--drivers/ata/pata_mpiix.c13
-rw-r--r--drivers/ata/pata_netcell.c14
-rw-r--r--drivers/ata/pata_ninja32.c13
-rw-r--r--drivers/ata/pata_ns87410.c13
-rw-r--r--drivers/ata/pata_ns87415.c13
-rw-r--r--drivers/ata/pata_oldpiix.c14
-rw-r--r--drivers/ata/pata_opti.c14
-rw-r--r--drivers/ata/pata_optidma.c13
-rw-r--r--drivers/ata/pata_pcmcia.c3
-rw-r--r--drivers/ata/pata_pdc2027x.c19
-rw-r--r--drivers/ata/pata_pdc202xx_old.c13
-rw-r--r--drivers/ata/pata_piccolo.c16
-rw-r--r--drivers/ata/pata_radisys.c14
-rw-r--r--drivers/ata/pata_rdc.c13
-rw-r--r--drivers/ata/pata_rz1000.c14
-rw-r--r--drivers/ata/pata_sc1200.c13
-rw-r--r--drivers/ata/pata_scc.c21
-rw-r--r--drivers/ata/pata_sch.c13
-rw-r--r--drivers/ata/pata_serverworks.c13
-rw-r--r--drivers/ata/pata_sil680.c13
-rw-r--r--drivers/ata/pata_sis.c14
-rw-r--r--drivers/ata/pata_sl82c105.c13
-rw-r--r--drivers/ata/pata_triflex.c13
-rw-r--r--drivers/ata/pata_via.c13
-rw-r--r--drivers/ata/pdc_adma.c13
-rwxr-xr-x[-rw-r--r--]drivers/ata/sata_dwc_460ex.c72
-rw-r--r--drivers/ata/sata_inic162x.c13
-rw-r--r--drivers/ata/sata_nv.c13
-rw-r--r--drivers/ata/sata_promise.c13
-rw-r--r--drivers/ata/sata_qstor.c13
-rw-r--r--drivers/ata/sata_sil.c14
-rw-r--r--drivers/ata/sata_sil24.c13
-rw-r--r--drivers/ata/sata_sis.c13
-rw-r--r--drivers/ata/sata_svw.c13
-rw-r--r--drivers/ata/sata_sx4.c16
-rw-r--r--drivers/ata/sata_uli.c14
-rw-r--r--drivers/ata/sata_via.c13
-rw-r--r--drivers/ata/sata_vsc.c13
72 files changed, 523 insertions, 965 deletions
diff --git a/drivers/ata/acard-ahci.c b/drivers/ata/acard-ahci.c
index 3bc8c79bf2c..4e94ba29cb8 100644
--- a/drivers/ata/acard-ahci.c
+++ b/drivers/ata/acard-ahci.c
@@ -503,21 +503,10 @@ static int acard_ahci_init_one(struct pci_dev *pdev, const struct pci_device_id
&acard_ahci_sht);
}
-static int __init acard_ahci_init(void)
-{
- return pci_register_driver(&acard_ahci_pci_driver);
-}
-
-static void __exit acard_ahci_exit(void)
-{
- pci_unregister_driver(&acard_ahci_pci_driver);
-}
+module_pci_driver(acard_ahci_pci_driver);
MODULE_AUTHOR("Jeff Garzik");
MODULE_DESCRIPTION("ACard AHCI SATA low-level driver");
MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, acard_ahci_pci_tbl);
MODULE_VERSION(DRV_VERSION);
-
-module_init(acard_ahci_init);
-module_exit(acard_ahci_exit);
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index ebaf67e4b2b..062e6a1a248 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -105,31 +105,27 @@ static struct ata_port_operations ahci_p5wdh_ops = {
static const struct ata_port_info ahci_port_info[] = {
/* by features */
- [board_ahci] =
- {
+ [board_ahci] = {
.flags = AHCI_FLAG_COMMON,
.pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_ops,
},
- [board_ahci_ign_iferr] =
- {
+ [board_ahci_ign_iferr] = {
AHCI_HFLAGS (AHCI_HFLAG_IGN_IRQ_IF_ERR),
.flags = AHCI_FLAG_COMMON,
.pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_ops,
},
- [board_ahci_nosntf] =
- {
+ [board_ahci_nosntf] = {
AHCI_HFLAGS (AHCI_HFLAG_NO_SNTF),
.flags = AHCI_FLAG_COMMON,
.pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_ops,
},
- [board_ahci_yes_fbs] =
- {
+ [board_ahci_yes_fbs] = {
AHCI_HFLAGS (AHCI_HFLAG_YES_FBS),
.flags = AHCI_FLAG_COMMON,
.pio_mask = ATA_PIO4,
@@ -137,8 +133,7 @@ static const struct ata_port_info ahci_port_info[] = {
.port_ops = &ahci_ops,
},
/* by chipsets */
- [board_ahci_mcp65] =
- {
+ [board_ahci_mcp65] = {
AHCI_HFLAGS (AHCI_HFLAG_NO_FPDMA_AA | AHCI_HFLAG_NO_PMP |
AHCI_HFLAG_YES_NCQ),
.flags = AHCI_FLAG_COMMON | ATA_FLAG_NO_DIPM,
@@ -146,24 +141,21 @@ static const struct ata_port_info ahci_port_info[] = {
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_ops,
},
- [board_ahci_mcp77] =
- {
+ [board_ahci_mcp77] = {
AHCI_HFLAGS (AHCI_HFLAG_NO_FPDMA_AA | AHCI_HFLAG_NO_PMP),
.flags = AHCI_FLAG_COMMON,
.pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_ops,
},
- [board_ahci_mcp89] =
- {
+ [board_ahci_mcp89] = {
AHCI_HFLAGS (AHCI_HFLAG_NO_FPDMA_AA),
.flags = AHCI_FLAG_COMMON,
.pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_ops,
},
- [board_ahci_mv] =
- {
+ [board_ahci_mv] = {
AHCI_HFLAGS (AHCI_HFLAG_NO_NCQ | AHCI_HFLAG_NO_MSI |
AHCI_HFLAG_MV_PATA | AHCI_HFLAG_NO_PMP),
.flags = ATA_FLAG_SATA | ATA_FLAG_PIO_DMA,
@@ -171,8 +163,7 @@ static const struct ata_port_info ahci_port_info[] = {
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_ops,
},
- [board_ahci_sb600] =
- {
+ [board_ahci_sb600] = {
AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL |
AHCI_HFLAG_NO_MSI | AHCI_HFLAG_SECT255 |
AHCI_HFLAG_32BIT_ONLY),
@@ -181,16 +172,14 @@ static const struct ata_port_info ahci_port_info[] = {
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_pmp_retry_srst_ops,
},
- [board_ahci_sb700] = /* for SB700 and SB800 */
- {
+ [board_ahci_sb700] = { /* for SB700 and SB800 */
AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL),
.flags = AHCI_FLAG_COMMON,
.pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_pmp_retry_srst_ops,
},
- [board_ahci_vt8251] =
- {
+ [board_ahci_vt8251] = {
AHCI_HFLAGS (AHCI_HFLAG_NO_NCQ | AHCI_HFLAG_NO_PMP),
.flags = AHCI_FLAG_COMMON,
.pio_mask = ATA_PIO4,
@@ -777,6 +766,22 @@ static bool ahci_sb600_enable_64bit(struct pci_dev *pdev)
},
},
/*
+ * All BIOS versions for the MSI K9AGM2 (MS-7327) support
+ * 64bit DMA.
+ *
+ * This board also had the typo mentioned above in the
+ * Manufacturer DMI field (fixed in BIOS version 1.5), so
+ * match on DMI_BOARD_VENDOR of "MICRO-STAR INTER" again.
+ */
+ {
+ .ident = "MSI K9AGM2",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR,
+ "MICRO-STAR INTER"),
+ DMI_MATCH(DMI_BOARD_NAME, "MS-7327"),
+ },
+ },
+ /*
* All BIOS versions for the Asus M3A support 64bit DMA.
* (all release versions from 0301 to 1206 were tested)
*/
@@ -1233,22 +1238,10 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
&ahci_sht);
}
-static int __init ahci_init(void)
-{
- return pci_register_driver(&ahci_pci_driver);
-}
-
-static void __exit ahci_exit(void)
-{
- pci_unregister_driver(&ahci_pci_driver);
-}
-
+module_pci_driver(ahci_pci_driver);
MODULE_AUTHOR("Jeff Garzik");
MODULE_DESCRIPTION("AHCI SATA low-level driver");
MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, ahci_pci_tbl);
MODULE_VERSION(DRV_VERSION);
-
-module_init(ahci_init);
-module_exit(ahci_exit);
diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c
index 9e419e1c200..09728e09cb3 100644
--- a/drivers/ata/ahci_platform.c
+++ b/drivers/ata/ahci_platform.c
@@ -15,6 +15,7 @@
#include <linux/kernel.h>
#include <linux/gfp.h>
#include <linux/module.h>
+#include <linux/pm.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/device.h>
@@ -271,13 +272,10 @@ static int ahci_resume(struct device *dev)
return 0;
}
-
-static struct dev_pm_ops ahci_pm_ops = {
- .suspend = &ahci_suspend,
- .resume = &ahci_resume,
-};
#endif
+SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_suspend, ahci_resume);
+
static const struct of_device_id ahci_of_match[] = {
{ .compatible = "calxeda,hb-ahci", },
{ .compatible = "snps,spear-ahci", },
@@ -291,9 +289,7 @@ static struct platform_driver ahci_driver = {
.name = "ahci",
.owner = THIS_MODULE,
.of_match_table = ahci_of_match,
-#ifdef CONFIG_PM
.pm = &ahci_pm_ops,
-#endif
},
.id_table = ahci_devtype,
};
diff --git a/drivers/ata/ata_generic.c b/drivers/ata/ata_generic.c
index aae115600b7..f8f38a08abc 100644
--- a/drivers/ata/ata_generic.c
+++ b/drivers/ata/ata_generic.c
@@ -255,17 +255,7 @@ static struct pci_driver ata_generic_pci_driver = {
#endif
};
-static int __init ata_generic_init(void)
-{
- return pci_register_driver(&ata_generic_pci_driver);
-}
-
-
-static void __exit ata_generic_exit(void)
-{
- pci_unregister_driver(&ata_generic_pci_driver);
-}
-
+module_pci_driver(ata_generic_pci_driver);
MODULE_AUTHOR("Alan Cox");
MODULE_DESCRIPTION("low-level driver for generic ATA");
@@ -273,7 +263,4 @@ MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, ata_generic);
MODULE_VERSION(DRV_VERSION);
-module_init(ata_generic_init);
-module_exit(ata_generic_exit);
-
module_param(all_generic_ide, int, 0);
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c
index bb7c5f1085c..902b5a45717 100644
--- a/drivers/ata/libata-acpi.c
+++ b/drivers/ata/libata-acpi.c
@@ -16,6 +16,7 @@
#include <linux/libata.h>
#include <linux/pci.h>
#include <linux/slab.h>
+#include <linux/pm_runtime.h>
#include <scsi/scsi_device.h>
#include "libata.h"
@@ -48,62 +49,53 @@ static void ata_acpi_clear_gtf(struct ata_device *dev)
}
/**
- * ata_acpi_associate_sata_port - associate SATA port with ACPI objects
- * @ap: target SATA port
+ * ata_ap_acpi_handle - provide the acpi_handle for an ata_port
+ * @ap: the acpi_handle returned will correspond to this port
*
- * Look up ACPI objects associated with @ap and initialize acpi_handle
- * fields of @ap, the port and devices accordingly.
- *
- * LOCKING:
- * EH context.
- *
- * RETURNS:
- * 0 on success, -errno on failure.
+ * Returns the acpi_handle for the ACPI namespace object corresponding to
+ * the ata_port passed into the function, or NULL if no such object exists
*/
-void ata_acpi_associate_sata_port(struct ata_port *ap)
+acpi_handle ata_ap_acpi_handle(struct ata_port *ap)
{
- WARN_ON(!(ap->flags & ATA_FLAG_ACPI_SATA));
-
- if (!sata_pmp_attached(ap)) {
- u64 adr = SATA_ADR(ap->port_no, NO_PORT_MULT);
-
- ap->link.device->acpi_handle =
- acpi_get_child(ap->host->acpi_handle, adr);
- } else {
- struct ata_link *link;
-
- ap->link.device->acpi_handle = NULL;
-
- ata_for_each_link(link, ap, EDGE) {
- u64 adr = SATA_ADR(ap->port_no, link->pmp);
+ if (ap->flags & ATA_FLAG_ACPI_SATA)
+ return NULL;
- link->device->acpi_handle =
- acpi_get_child(ap->host->acpi_handle, adr);
- }
- }
+ /*
+ * If acpi bind operation has already happened, we can get the handle
+ * for the port by checking the corresponding scsi_host device's
+ * firmware node, otherwise we will need to find out the handle from
+ * its parent's acpi node.
+ */
+ if (ap->scsi_host)
+ return DEVICE_ACPI_HANDLE(&ap->scsi_host->shost_gendev);
+ else
+ return acpi_get_child(DEVICE_ACPI_HANDLE(ap->host->dev),
+ ap->port_no);
}
+EXPORT_SYMBOL(ata_ap_acpi_handle);
-static void ata_acpi_associate_ide_port(struct ata_port *ap)
+/**
+ * ata_dev_acpi_handle - provide the acpi_handle for an ata_device
+ * @dev: the acpi_device returned will correspond to this port
+ *
+ * Returns the acpi_handle for the ACPI namespace object corresponding to
+ * the ata_device passed into the function, or NULL if no such object exists
+ */
+acpi_handle ata_dev_acpi_handle(struct ata_device *dev)
{
- int max_devices, i;
-
- ap->acpi_handle = acpi_get_child(ap->host->acpi_handle, ap->port_no);
- if (!ap->acpi_handle)
- return;
-
- max_devices = 1;
- if (ap->flags & ATA_FLAG_SLAVE_POSS)
- max_devices++;
-
- for (i = 0; i < max_devices; i++) {
- struct ata_device *dev = &ap->link.device[i];
-
- dev->acpi_handle = acpi_get_child(ap->acpi_handle, i);
- }
+ acpi_integer adr;
+ struct ata_port *ap = dev->link->ap;
- if (ata_acpi_gtm(ap, &ap->__acpi_init_gtm) == 0)
- ap->pflags |= ATA_PFLAG_INIT_GTM_VALID;
+ if (ap->flags & ATA_FLAG_ACPI_SATA) {
+ if (!sata_pmp_attached(ap))
+ adr = SATA_ADR(ap->port_no, NO_PORT_MULT);
+ else
+ adr = SATA_ADR(ap->port_no, dev->link->pmp);
+ return acpi_get_child(DEVICE_ACPI_HANDLE(ap->host->dev), adr);
+ } else
+ return acpi_get_child(ata_ap_acpi_handle(ap), dev->devno);
}
+EXPORT_SYMBOL(ata_dev_acpi_handle);
/* @ap and @dev are the same as ata_acpi_handle_hotplug() */
static void ata_acpi_detach_device(struct ata_port *ap, struct ata_device *dev)
@@ -229,56 +221,6 @@ static const struct acpi_dock_ops ata_acpi_ap_dock_ops = {
};
/**
- * ata_acpi_associate - associate ATA host with ACPI objects
- * @host: target ATA host
- *
- * Look up ACPI objects associated with @host and initialize
- * acpi_handle fields of @host, its ports and devices accordingly.
- *
- * LOCKING:
- * EH context.
- *
- * RETURNS:
- * 0 on success, -errno on failure.
- */
-void ata_acpi_associate(struct ata_host *host)
-{
- int i, j;
-
- if (!is_pci_dev(host->dev) || libata_noacpi)
- return;
-
- host->acpi_handle = DEVICE_ACPI_HANDLE(host->dev);
- if (!host->acpi_handle)
- return;
-
- for (i = 0; i < host->n_ports; i++) {
- struct ata_port *ap = host->ports[i];
-
- if (host->ports[0]->flags & ATA_FLAG_ACPI_SATA)
- ata_acpi_associate_sata_port(ap);
- else
- ata_acpi_associate_ide_port(ap);
-
- if (ap->acpi_handle) {
- /* we might be on a docking station */
- register_hotplug_dock_device(ap->acpi_handle,
- &ata_acpi_ap_dock_ops, ap);
- }
-
- for (j = 0; j < ata_link_max_devices(&ap->link); j++) {
- struct ata_device *dev = &ap->link.device[j];
-
- if (dev->acpi_handle) {
- /* we might be on a docking station */
- register_hotplug_dock_device(dev->acpi_handle,
- &ata_acpi_dev_dock_ops, dev);
- }
- }
- }
-}
-
-/**
* ata_acpi_dissociate - dissociate ATA host from ACPI objects
* @host: target ATA host
*
@@ -299,7 +241,7 @@ void ata_acpi_dissociate(struct ata_host *host)
struct ata_port *ap = host->ports[i];
const struct ata_acpi_gtm *gtm = ata_acpi_init_gtm(ap);
- if (ap->acpi_handle && gtm)
+ if (ata_ap_acpi_handle(ap) && gtm)
ata_acpi_stm(ap, gtm);
}
}
@@ -324,7 +266,8 @@ int ata_acpi_gtm(struct ata_port *ap, struct ata_acpi_gtm *gtm)
acpi_status status;
int rc = 0;
- status = acpi_evaluate_object(ap->acpi_handle, "_GTM", NULL, &output);
+ status = acpi_evaluate_object(ata_ap_acpi_handle(ap), "_GTM", NULL,
+ &output);
rc = -ENOENT;
if (status == AE_NOT_FOUND)
@@ -394,7 +337,8 @@ int ata_acpi_stm(struct ata_port *ap, const struct ata_acpi_gtm *stm)
input.count = 3;
input.pointer = in_params;
- status = acpi_evaluate_object(ap->acpi_handle, "_STM", &input, NULL);
+ status = acpi_evaluate_object(ata_ap_acpi_handle(ap), "_STM", &input,
+ NULL);
if (status == AE_NOT_FOUND)
return -ENOENT;
@@ -451,7 +395,8 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf)
__func__, ap->port_no);
/* _GTF has no input parameters */
- status = acpi_evaluate_object(dev->acpi_handle, "_GTF", NULL, &output);
+ status = acpi_evaluate_object(ata_dev_acpi_handle(dev), "_GTF", NULL,
+ &output);
out_obj = dev->gtf_cache = output.pointer;
if (ACPI_FAILURE(status)) {
@@ -817,7 +762,8 @@ static int ata_acpi_push_id(struct ata_device *dev)
/* It's OK for _SDD to be missing too. */
swap_buf_le16(dev->id, ATA_ID_WORDS);
- status = acpi_evaluate_object(dev->acpi_handle, "_SDD", &input, NULL);
+ status = acpi_evaluate_object(ata_dev_acpi_handle(dev), "_SDD", &input,
+ NULL);
swap_buf_le16(dev->id, ATA_ID_WORDS);
if (status == AE_NOT_FOUND)
@@ -867,7 +813,7 @@ void ata_acpi_on_resume(struct ata_port *ap)
const struct ata_acpi_gtm *gtm = ata_acpi_init_gtm(ap);
struct ata_device *dev;
- if (ap->acpi_handle && gtm) {
+ if (ata_ap_acpi_handle(ap) && gtm) {
/* _GTM valid */
/* restore timing parameters */
@@ -907,23 +853,39 @@ void ata_acpi_on_resume(struct ata_port *ap)
void ata_acpi_set_state(struct ata_port *ap, pm_message_t state)
{
struct ata_device *dev;
-
- if (!ap->acpi_handle || (ap->flags & ATA_FLAG_ACPI_SATA))
- return;
+ acpi_handle handle;
+ int acpi_state;
/* channel first and then drives for power on and vica versa
for power off */
- if (state.event == PM_EVENT_ON)
- acpi_bus_set_power(ap->acpi_handle, ACPI_STATE_D0);
+ handle = ata_ap_acpi_handle(ap);
+ if (handle && state.event == PM_EVENT_ON)
+ acpi_bus_set_power(handle, ACPI_STATE_D0);
ata_for_each_dev(dev, &ap->link, ENABLED) {
- if (dev->acpi_handle)
- acpi_bus_set_power(dev->acpi_handle,
- state.event == PM_EVENT_ON ?
- ACPI_STATE_D0 : ACPI_STATE_D3);
+ handle = ata_dev_acpi_handle(dev);
+ if (!handle)
+ continue;
+
+ if (state.event != PM_EVENT_ON) {
+ acpi_state = acpi_pm_device_sleep_state(
+ &dev->sdev->sdev_gendev, NULL, ACPI_STATE_D3);
+ if (acpi_state > 0)
+ acpi_bus_set_power(handle, acpi_state);
+ /* TBD: need to check if it's runtime pm request */
+ acpi_pm_device_run_wake(
+ &dev->sdev->sdev_gendev, true);
+ } else {
+ /* Ditto */
+ acpi_pm_device_run_wake(
+ &dev->sdev->sdev_gendev, false);
+ acpi_bus_set_power(handle, ACPI_STATE_D0);
+ }
}
- if (state.event != PM_EVENT_ON)
- acpi_bus_set_power(ap->acpi_handle, ACPI_STATE_D3);
+
+ handle = ata_ap_acpi_handle(ap);
+ if (handle && state.event != PM_EVENT_ON)
+ acpi_bus_set_power(handle, ACPI_STATE_D3);
}
/**
@@ -948,7 +910,7 @@ int ata_acpi_on_devcfg(struct ata_device *dev)
int nr_executed = 0;
int rc;
- if (!dev->acpi_handle)
+ if (!ata_dev_acpi_handle(dev))
return 0;
/* do we need to do _GTF? */
@@ -994,7 +956,6 @@ int ata_acpi_on_devcfg(struct ata_device *dev)
}
ata_dev_warn(dev, "ACPI: failed the second time, disabled\n");
- dev->acpi_handle = NULL;
/* We can safely continue if no _GTF command has been executed
* and port is not frozen.
@@ -1018,3 +979,218 @@ void ata_acpi_on_disable(struct ata_device *dev)
{
ata_acpi_clear_gtf(dev);
}
+
+static void ata_acpi_wake_dev(acpi_handle handle, u32 event, void *context)
+{
+ struct ata_device *ata_dev = context;
+
+ if (event == ACPI_NOTIFY_DEVICE_WAKE && ata_dev &&
+ pm_runtime_suspended(&ata_dev->sdev->sdev_gendev))
+ scsi_autopm_get_device(ata_dev->sdev);
+}
+
+static void ata_acpi_add_pm_notifier(struct ata_device *dev)
+{
+ struct acpi_device *acpi_dev;
+ acpi_handle handle;
+ acpi_status status;
+
+ handle = ata_dev_acpi_handle(dev);
+ if (!handle)
+ return;
+
+ status = acpi_bus_get_device(handle, &acpi_dev);
+ if (ACP