USB: serial: ftdi_sio: Add support for new Xsens devices
[firefly-linux-kernel-4.4.55.git] / drivers / ata / libata-acpi.c
index 8a52dab412e2a8013f36bd547460924c79c996aa..cf4e7020adacde5e69881a21adb0c578d31d7a3e 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/pm_runtime.h>
-#include <linux/pm_qos.h>
 #include <scsi/scsi_device.h>
 #include "libata.h"
 
@@ -61,7 +60,8 @@ acpi_handle ata_ap_acpi_handle(struct ata_port *ap)
        if (ap->flags & ATA_FLAG_ACPI_SATA)
                return NULL;
 
-       return acpi_get_child(DEVICE_ACPI_HANDLE(ap->host->dev), ap->port_no);
+       return ap->scsi_host ?
+               DEVICE_ACPI_HANDLE(&ap->scsi_host->shost_gendev) : NULL;
 }
 EXPORT_SYMBOL(ata_ap_acpi_handle);
 
@@ -77,7 +77,7 @@ acpi_handle ata_dev_acpi_handle(struct ata_device *dev)
        acpi_integer adr;
        struct ata_port *ap = dev->link->ap;
 
-       if (dev->flags & ATA_DFLAG_ACPI_DISABLED)
+       if (libata_noacpi || dev->flags & ATA_DFLAG_ACPI_DISABLED)
                return NULL;
 
        if (ap->flags & ATA_FLAG_ACPI_SATA) {
@@ -156,8 +156,10 @@ static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev,
 
        spin_unlock_irqrestore(ap->lock, flags);
 
-       if (wait)
+       if (wait) {
                ata_port_wait_eh(ap);
+               flush_work(&ap->hotplug_task.work);
+       }
 }
 
 static void ata_acpi_dev_notify_dock(acpi_handle handle, u32 event, void *data)
@@ -214,6 +216,39 @@ static const struct acpi_dock_ops ata_acpi_ap_dock_ops = {
        .uevent = ata_acpi_ap_uevent,
 };
 
+void ata_acpi_hotplug_init(struct ata_host *host)
+{
+       int i;
+
+       for (i = 0; i < host->n_ports; i++) {
+               struct ata_port *ap = host->ports[i];
+               acpi_handle handle;
+               struct ata_device *dev;
+
+               if (!ap)
+                       continue;
+
+               handle = ata_ap_acpi_handle(ap);
+               if (handle) {
+                       /* we might be on a docking station */
+                       register_hotplug_dock_device(handle,
+                                                    &ata_acpi_ap_dock_ops, ap,
+                                                    NULL, NULL);
+               }
+
+               ata_for_each_dev(dev, &ap->link, ALL) {
+                       handle = ata_dev_acpi_handle(dev);
+                       if (!handle)
+                               continue;
+
+                       /* we might be on a docking station */
+                       register_hotplug_dock_device(handle,
+                                                    &ata_acpi_dev_dock_ops,
+                                                    dev, NULL, NULL);
+               }
+       }
+}
+
 /**
  * ata_acpi_dissociate - dissociate ATA host from ACPI objects
  * @host: target ATA host
@@ -240,28 +275,15 @@ void ata_acpi_dissociate(struct ata_host *host)
        }
 }
 
-/**
- * ata_acpi_gtm - execute _GTM
- * @ap: target ATA port
- * @gtm: out parameter for _GTM result
- *
- * Evaluate _GTM and store the result in @gtm.
- *
- * LOCKING:
- * EH context.
- *
- * RETURNS:
- * 0 on success, -ENOENT if _GTM doesn't exist, -errno on failure.
- */
-int ata_acpi_gtm(struct ata_port *ap, struct ata_acpi_gtm *gtm)
+static int __ata_acpi_gtm(struct ata_port *ap, acpi_handle handle,
+                         struct ata_acpi_gtm *gtm)
 {
        struct acpi_buffer output = { .length = ACPI_ALLOCATE_BUFFER };
        union acpi_object *out_obj;
        acpi_status status;
        int rc = 0;
 
-       status = acpi_evaluate_object(ata_ap_acpi_handle(ap), "_GTM", NULL,
-                                     &output);
+       status = acpi_evaluate_object(handle, "_GTM", NULL, &output);
 
        rc = -ENOENT;
        if (status == AE_NOT_FOUND)
@@ -295,6 +317,27 @@ int ata_acpi_gtm(struct ata_port *ap, struct ata_acpi_gtm *gtm)
        return rc;
 }
 
+/**
+ * ata_acpi_gtm - execute _GTM
+ * @ap: target ATA port
+ * @gtm: out parameter for _GTM result
+ *
+ * Evaluate _GTM and store the result in @gtm.
+ *
+ * LOCKING:
+ * EH context.
+ *
+ * RETURNS:
+ * 0 on success, -ENOENT if _GTM doesn't exist, -errno on failure.
+ */
+int ata_acpi_gtm(struct ata_port *ap, struct ata_acpi_gtm *gtm)
+{
+       if (ata_ap_acpi_handle(ap))
+               return __ata_acpi_gtm(ap, ata_ap_acpi_handle(ap), gtm);
+       else
+               return -EINVAL;
+}
+
 EXPORT_SYMBOL_GPL(ata_acpi_gtm);
 
 /**
@@ -1020,38 +1063,6 @@ void ata_acpi_on_disable(struct ata_device *dev)
        ata_acpi_clear_gtf(dev);
 }
 
-static void ata_acpi_register_power_resource(struct ata_device *dev)
-{
-       struct scsi_device *sdev = dev->sdev;
-       acpi_handle handle;
-
-       handle = ata_dev_acpi_handle(dev);
-       if (handle)
-               acpi_dev_pm_add_dependent(handle, &sdev->sdev_gendev);
-}
-
-static void ata_acpi_unregister_power_resource(struct ata_device *dev)
-{
-       struct scsi_device *sdev = dev->sdev;
-       acpi_handle handle;
-
-       handle = ata_dev_acpi_handle(dev);
-       if (handle)
-               acpi_dev_pm_remove_dependent(handle, &sdev->sdev_gendev);
-}
-
-void ata_acpi_bind(struct ata_device *dev)
-{
-       ata_acpi_register_power_resource(dev);
-       if (zpodd_dev_enabled(dev))
-               dev_pm_qos_expose_flags(&dev->sdev->sdev_gendev, 0);
-}
-
-void ata_acpi_unbind(struct ata_device *dev)
-{
-       ata_acpi_unregister_power_resource(dev);
-}
-
 static int compat_pci_ata(struct ata_port *ap)
 {
        struct device *dev = ap->tdev.parent;
@@ -1071,7 +1082,7 @@ static int compat_pci_ata(struct ata_port *ap)
 
 static int ata_acpi_bind_host(struct ata_port *ap, acpi_handle *handle)
 {
-       if (ap->flags & ATA_FLAG_ACPI_SATA)
+       if (libata_noacpi || ap->flags & ATA_FLAG_ACPI_SATA)
                return -ENODEV;
 
        *handle = acpi_get_child(DEVICE_ACPI_HANDLE(ap->tdev.parent),
@@ -1080,7 +1091,7 @@ static int ata_acpi_bind_host(struct ata_port *ap, acpi_handle *handle)
        if (!*handle)
                return -ENODEV;
 
-       if (ata_acpi_gtm(ap, &ap->__acpi_init_gtm) == 0)
+       if (__ata_acpi_gtm(ap, *handle, &ap->__acpi_init_gtm) == 0)
                ap->pflags |= ATA_PFLAG_INIT_GTM_VALID;
 
        return 0;