[PATCH v3 7/7] ACPI / hotplug / PCI: Hotplug notifications from acpi_bus_notify()

2014-02-02 Thread Rafael J. Wysocki
From: Rafael J. Wysocki 

Since acpi_bus_notify() is executed on all notifications for all
devices anyway, make it execute acpi_device_hotplug() for all
hotplug events instead of installing notify handlers pointing to
the same function for all hotplug devices.

This change reduces both the size and complexity of ACPI-based device
hotplug code.  Moreover, since acpi_device_hotplug() only does
significant things for devices that have either an ACPI scan handler,
or a hotplug context with .eject() defined, and those devices
had notify handlers pointing to acpi_hotplug_notify_cb() installed
before anyway, this modification shouldn't change functionality.

Signed-off-by: Rafael J. Wysocki 
---
 drivers/acpi/bus.c |   60 +-
 drivers/acpi/internal.h|1 
 drivers/acpi/scan.c|  100 -
 drivers/pci/hotplug/acpiphp.h  |1 
 drivers/pci/hotplug/acpiphp_glue.c |   16 ++---
 include/acpi/acpi_bus.h|2 
 6 files changed, 46 insertions(+), 134 deletions(-)

Index: linux-pm/drivers/acpi/bus.c
===
--- linux-pm.orig/drivers/acpi/bus.c
+++ linux-pm/drivers/acpi/bus.c
@@ -340,62 +340,76 @@ static void acpi_bus_osc_support(void)
  */
 static void acpi_bus_notify(acpi_handle handle, u32 type, void *data)
 {
-   struct acpi_device *device = NULL;
+   struct acpi_device *adev;
struct acpi_driver *driver;
-
-   ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Notification %#02x to handle %p\n",
- type, handle));
+   acpi_status status;
+   u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE;
 
switch (type) {
-
case ACPI_NOTIFY_BUS_CHECK:
-   /* TBD */
+   acpi_handle_debug(handle, "ACPI_NOTIFY_BUS_CHECK event\n");
break;
 
case ACPI_NOTIFY_DEVICE_CHECK:
-   /* TBD */
+   acpi_handle_debug(handle, "ACPI_NOTIFY_DEVICE_CHECK event\n");
break;
 
case ACPI_NOTIFY_DEVICE_WAKE:
-   /* TBD */
+   acpi_handle_debug(handle, "ACPI_NOTIFY_DEVICE_WAKE event\n");
break;
 
case ACPI_NOTIFY_EJECT_REQUEST:
-   /* TBD */
+   acpi_handle_debug(handle, "ACPI_NOTIFY_EJECT_REQUEST event\n");
break;
 
case ACPI_NOTIFY_DEVICE_CHECK_LIGHT:
+   acpi_handle_debug(handle, "ACPI_NOTIFY_DEVICE_CHECK_LIGHT 
event\n");
/* TBD: Exactly what does 'light' mean? */
break;
 
case ACPI_NOTIFY_FREQUENCY_MISMATCH:
-   /* TBD */
+   acpi_handle_err(handle, "Device cannot be configured due "
+   "to a frequency mismatch\n");
break;
 
case ACPI_NOTIFY_BUS_MODE_MISMATCH:
-   /* TBD */
+   acpi_handle_err(handle, "Device cannot be configured due "
+   "to a bus mode mismatch\n");
break;
 
case ACPI_NOTIFY_POWER_FAULT:
-   /* TBD */
+   acpi_handle_err(handle, "Device has suffered a power fault\n");
break;
 
default:
-   ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Received unknown/unsupported notification 
[%08x]\n",
- type));
-   break;
+   acpi_handle_warn(handle, "Unsupported event type 0x%x\n", type);
+   ost_code = ACPI_OST_SC_UNRECOGNIZED_NOTIFY;
+   goto err;
}
 
-   acpi_bus_get_acpi_device(handle, );
-   if (device) {
-   driver = device->driver;
-   if (driver && driver->ops.notify &&
-   (driver->flags & ACPI_DRIVER_ALL_NOTIFY_EVENTS))
-   driver->ops.notify(device, type);
+   if (acpi_bus_get_acpi_device(handle, ))
+   goto err;
 
-   acpi_bus_put_acpi_device(device);
+   driver = adev->driver;
+   if (driver && driver->ops.notify &&
+   (driver->flags & ACPI_DRIVER_ALL_NOTIFY_EVENTS))
+   driver->ops.notify(adev, type);
+
+   switch (type) {
+   case ACPI_NOTIFY_BUS_CHECK:
+   case ACPI_NOTIFY_DEVICE_CHECK:
+   case ACPI_NOTIFY_EJECT_REQUEST:
+   status = acpi_hotplug_execute(acpi_device_hotplug, adev, type);
+   if (ACPI_SUCCESS(status))
+   return;
+   default:
+   break;
}
+   acpi_bus_put_acpi_device(adev);
+   return;
+
+ err:
+   acpi_evaluate_hotplug_ost(handle, type, ost_code, NULL);
 }
 
 /* --
Index: linux-pm/drivers/acpi/internal.h
===
--- linux-pm.orig/drivers/acpi/internal.h
+++ linux-pm/drivers/acpi/internal.h

[PATCH v3 7/7] ACPI / hotplug / PCI: Hotplug notifications from acpi_bus_notify()

2014-02-02 Thread Rafael J. Wysocki
From: Rafael J. Wysocki rafael.j.wyso...@intel.com

Since acpi_bus_notify() is executed on all notifications for all
devices anyway, make it execute acpi_device_hotplug() for all
hotplug events instead of installing notify handlers pointing to
the same function for all hotplug devices.

This change reduces both the size and complexity of ACPI-based device
hotplug code.  Moreover, since acpi_device_hotplug() only does
significant things for devices that have either an ACPI scan handler,
or a hotplug context with .eject() defined, and those devices
had notify handlers pointing to acpi_hotplug_notify_cb() installed
before anyway, this modification shouldn't change functionality.

Signed-off-by: Rafael J. Wysocki rafael.j.wyso...@intel.com
---
 drivers/acpi/bus.c |   60 +-
 drivers/acpi/internal.h|1 
 drivers/acpi/scan.c|  100 -
 drivers/pci/hotplug/acpiphp.h  |1 
 drivers/pci/hotplug/acpiphp_glue.c |   16 ++---
 include/acpi/acpi_bus.h|2 
 6 files changed, 46 insertions(+), 134 deletions(-)

Index: linux-pm/drivers/acpi/bus.c
===
--- linux-pm.orig/drivers/acpi/bus.c
+++ linux-pm/drivers/acpi/bus.c
@@ -340,62 +340,76 @@ static void acpi_bus_osc_support(void)
  */
 static void acpi_bus_notify(acpi_handle handle, u32 type, void *data)
 {
-   struct acpi_device *device = NULL;
+   struct acpi_device *adev;
struct acpi_driver *driver;
-
-   ACPI_DEBUG_PRINT((ACPI_DB_INFO, Notification %#02x to handle %p\n,
- type, handle));
+   acpi_status status;
+   u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE;
 
switch (type) {
-
case ACPI_NOTIFY_BUS_CHECK:
-   /* TBD */
+   acpi_handle_debug(handle, ACPI_NOTIFY_BUS_CHECK event\n);
break;
 
case ACPI_NOTIFY_DEVICE_CHECK:
-   /* TBD */
+   acpi_handle_debug(handle, ACPI_NOTIFY_DEVICE_CHECK event\n);
break;
 
case ACPI_NOTIFY_DEVICE_WAKE:
-   /* TBD */
+   acpi_handle_debug(handle, ACPI_NOTIFY_DEVICE_WAKE event\n);
break;
 
case ACPI_NOTIFY_EJECT_REQUEST:
-   /* TBD */
+   acpi_handle_debug(handle, ACPI_NOTIFY_EJECT_REQUEST event\n);
break;
 
case ACPI_NOTIFY_DEVICE_CHECK_LIGHT:
+   acpi_handle_debug(handle, ACPI_NOTIFY_DEVICE_CHECK_LIGHT 
event\n);
/* TBD: Exactly what does 'light' mean? */
break;
 
case ACPI_NOTIFY_FREQUENCY_MISMATCH:
-   /* TBD */
+   acpi_handle_err(handle, Device cannot be configured due 
+   to a frequency mismatch\n);
break;
 
case ACPI_NOTIFY_BUS_MODE_MISMATCH:
-   /* TBD */
+   acpi_handle_err(handle, Device cannot be configured due 
+   to a bus mode mismatch\n);
break;
 
case ACPI_NOTIFY_POWER_FAULT:
-   /* TBD */
+   acpi_handle_err(handle, Device has suffered a power fault\n);
break;
 
default:
-   ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- Received unknown/unsupported notification 
[%08x]\n,
- type));
-   break;
+   acpi_handle_warn(handle, Unsupported event type 0x%x\n, type);
+   ost_code = ACPI_OST_SC_UNRECOGNIZED_NOTIFY;
+   goto err;
}
 
-   acpi_bus_get_acpi_device(handle, device);
-   if (device) {
-   driver = device-driver;
-   if (driver  driver-ops.notify 
-   (driver-flags  ACPI_DRIVER_ALL_NOTIFY_EVENTS))
-   driver-ops.notify(device, type);
+   if (acpi_bus_get_acpi_device(handle, adev))
+   goto err;
 
-   acpi_bus_put_acpi_device(device);
+   driver = adev-driver;
+   if (driver  driver-ops.notify 
+   (driver-flags  ACPI_DRIVER_ALL_NOTIFY_EVENTS))
+   driver-ops.notify(adev, type);
+
+   switch (type) {
+   case ACPI_NOTIFY_BUS_CHECK:
+   case ACPI_NOTIFY_DEVICE_CHECK:
+   case ACPI_NOTIFY_EJECT_REQUEST:
+   status = acpi_hotplug_execute(acpi_device_hotplug, adev, type);
+   if (ACPI_SUCCESS(status))
+   return;
+   default:
+   break;
}
+   acpi_bus_put_acpi_device(adev);
+   return;
+
+ err:
+   acpi_evaluate_hotplug_ost(handle, type, ost_code, NULL);
 }
 
 /* --
Index: linux-pm/drivers/acpi/internal.h
===
--- linux-pm.orig/drivers/acpi/internal.h
+++