aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/scan.c
diff options
context:
space:
mode:
authorToshi Kani <toshi.kani@hp.com>2013-03-04 16:30:43 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-03-24 18:49:39 -0400
commit6b772e8f9e9deb3528402ac14fd0aa186d84ae75 (patch)
treea516479f87c8693d8ad035e135da587bf31caf5a /drivers/acpi/scan.c
parentc0af41757f406651cdd32de3e915753746c2948a (diff)
ACPI: Update PNPID match handling for notify
When installing/removing a notify handler to/from an ACPI device object, ACPI core tries to match its associated scan handler to see if it supports hotplug. However, the matching logic of the notify handler is different from the matching logic of attaching a scan handler to an ACPI device object. This patch updates the matching logic of the notify handlers to be consistent with the attach handling. Signed-off-by: Toshi Kani <toshi.kani@hp.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/acpi/scan.c')
-rw-r--r--drivers/acpi/scan.c85
1 files changed, 52 insertions, 33 deletions
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index e9a71ed9954a..3f6ec0dd4fb6 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1703,24 +1703,47 @@ static bool acpi_scan_handler_matching(struct acpi_scan_handler *handler,
1703 return false; 1703 return false;
1704} 1704}
1705 1705
1706static struct acpi_scan_handler *acpi_scan_match_handler(char *idstr,
1707 const struct acpi_device_id **matchid)
1708{
1709 struct acpi_scan_handler *handler;
1710
1711 list_for_each_entry(handler, &acpi_scan_handlers_list, list_node)
1712 if (acpi_scan_handler_matching(handler, idstr, matchid))
1713 return handler;
1714
1715 return NULL;
1716}
1717
1706static acpi_status acpi_scan_hotplug_modify(acpi_handle handle, 1718static acpi_status acpi_scan_hotplug_modify(acpi_handle handle,
1707 u32 lvl_not_used, void *data, 1719 u32 lvl_not_used, void *data,
1708 void **ret_not_used) 1720 void **ret_not_used)
1709{ 1721{
1710 struct acpi_scan_handler *handler = data; 1722 struct acpi_device_pnp pnp = {};
1711 struct acpi_device_info *info; 1723 struct acpi_scan_handler *tgt_handler = data, *handler;
1724 struct acpi_hardware_id *hwid;
1725 unsigned long long sta_not_used;
1726 int type;
1712 bool match = false; 1727 bool match = false;
1713 1728
1714 if (ACPI_FAILURE(acpi_get_object_info(handle, &info))) 1729 if (acpi_bus_type_and_status(handle, &type, &sta_not_used))
1730 return AE_OK;
1731
1732 INIT_LIST_HEAD(&pnp.ids);
1733 acpi_set_pnp_ids(handle, &pnp, type);
1734
1735 if (!pnp.type.hardware_id)
1715 return AE_OK; 1736 return AE_OK;
1716 1737
1717 if (info->valid & ACPI_VALID_HID) { 1738 list_for_each_entry(hwid, &pnp.ids, list) {
1718 char *idstr = info->hardware_id.string; 1739 handler = acpi_scan_match_handler(hwid->id, NULL);
1719 match = acpi_scan_handler_matching(handler, idstr, NULL); 1740 if (handler && handler == tgt_handler) {
1741 match = true;
1742 break;
1743 }
1720 } 1744 }
1721 kfree(info);
1722 if (!match) 1745 if (!match)
1723 return AE_OK; 1746 goto out;
1724 1747
1725 if (handler->hotplug.enabled) 1748 if (handler->hotplug.enabled)
1726 acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, 1749 acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
@@ -1729,6 +1752,8 @@ static acpi_status acpi_scan_hotplug_modify(acpi_handle handle,
1729 acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY, 1752 acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
1730 acpi_hotplug_notify_cb); 1753 acpi_hotplug_notify_cb);
1731 1754
1755out:
1756 acpi_free_pnp_ids(&pnp);
1732 return AE_OK; 1757 return AE_OK;
1733} 1758}
1734 1759
@@ -1749,40 +1774,34 @@ void acpi_scan_hotplug_enabled(struct acpi_hotplug_profile *hotplug, bool val)
1749 mutex_unlock(&acpi_scan_lock); 1774 mutex_unlock(&acpi_scan_lock);
1750} 1775}
1751 1776
1752static struct acpi_scan_handler *acpi_scan_match_handler(char *idstr, 1777static void acpi_scan_init_hotplug(acpi_handle handle, int type)
1753 const struct acpi_device_id **matchid)
1754{
1755 struct acpi_scan_handler *handler;
1756
1757 list_for_each_entry(handler, &acpi_scan_handlers_list, list_node)
1758 if (acpi_scan_handler_matching(handler, idstr, matchid))
1759 return handler;
1760
1761 return NULL;
1762}
1763
1764static void acpi_scan_init_hotplug(acpi_handle handle)
1765{ 1778{
1766 struct acpi_device_info *info; 1779 struct acpi_device_pnp pnp = {};
1780 struct acpi_hardware_id *hwid;
1767 struct acpi_scan_handler *handler; 1781 struct acpi_scan_handler *handler;
1768 1782
1769 if (ACPI_FAILURE(acpi_get_object_info(handle, &info))) 1783 INIT_LIST_HEAD(&pnp.ids);
1770 return; 1784 acpi_set_pnp_ids(handle, &pnp, type);
1771 1785
1772 if (!(info->valid & ACPI_VALID_HID)) { 1786 if (!pnp.type.hardware_id)
1773 kfree(info);
1774 return; 1787 return;
1775 }
1776 1788
1777 /* 1789 /*
1778 * This relies on the fact that acpi_install_notify_handler() will not 1790 * This relies on the fact that acpi_install_notify_handler() will not
1779 * install the same notify handler routine twice for the same handle. 1791 * install the same notify handler routine twice for the same handle.
1780 */ 1792 */
1781 handler = acpi_scan_match_handler(info->hardware_id.string, NULL); 1793 list_for_each_entry(hwid, &pnp.ids, list) {
1782 kfree(info); 1794 handler = acpi_scan_match_handler(hwid->id, NULL);
1783 if (handler && handler->hotplug.enabled) 1795 if (handler) {
1784 acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, 1796 if (handler->hotplug.enabled)
1785 acpi_hotplug_notify_cb, NULL); 1797 acpi_install_notify_handler(handle,
1798 ACPI_SYSTEM_NOTIFY,
1799 acpi_hotplug_notify_cb, NULL);
1800 break;
1801 }
1802 }
1803
1804 acpi_free_pnp_ids(&pnp);
1786} 1805}
1787 1806
1788static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used, 1807static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used,
@@ -1807,7 +1826,7 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used,
1807 return AE_OK; 1826 return AE_OK;
1808 } 1827 }
1809 1828
1810 acpi_scan_init_hotplug(handle); 1829 acpi_scan_init_hotplug(handle, type);
1811 1830
1812 if (!(sta & ACPI_STA_DEVICE_PRESENT) && 1831 if (!(sta & ACPI_STA_DEVICE_PRESENT) &&
1813 !(sta & ACPI_STA_DEVICE_FUNCTIONING)) { 1832 !(sta & ACPI_STA_DEVICE_FUNCTIONING)) {