Merge branch 'thermal-intel' into linux-next
* thermal-intel:
thermal: intel: intel_tcc_cooling: Add CPU models in the support list
diff --git a/Documentation/power/runtime_pm.rst b/Documentation/power/runtime_pm.rst
index 455b9d1..a53ab09 100644
--- a/Documentation/power/runtime_pm.rst
+++ b/Documentation/power/runtime_pm.rst
@@ -712,10 +712,9 @@
* During system suspend pm_runtime_get_noresume() is called for every device
right before executing the subsystem-level .prepare() callback for it and
pm_runtime_barrier() is called for every device right before executing the
- subsystem-level .suspend() callback for it. In addition to that the PM core
- calls __pm_runtime_disable() with 'false' as the second argument for every
- device right before executing the subsystem-level .suspend_late() callback
- for it.
+ subsystem-level .suspend() callback for it. In addition to that, the PM
+ core disables runtime PM for every device right before executing the
+ subsystem-level .suspend_late() callback for it.
* During system resume pm_runtime_enable() and pm_runtime_put() are called for
every device right after executing the subsystem-level .resume_early()
diff --git a/drivers/acpi/acpi_pnp.c b/drivers/acpi/acpi_pnp.c
index 4ad8818..85d9f78 100644
--- a/drivers/acpi/acpi_pnp.c
+++ b/drivers/acpi/acpi_pnp.c
@@ -125,9 +125,6 @@ static const struct acpi_device_id acpi_pnp_device_ids[] = {
{"PNP0401"}, /* ECP Printer Port */
/* apple-gmux */
{"APP000B"},
- /* system */
- {"PNP0c02"}, /* General ID for reserving resources */
- {"PNP0c01"}, /* memory controller */
/* rtc_cmos */
{"PNP0b00"},
{"PNP0b01"},
@@ -346,24 +343,10 @@ static bool acpi_pnp_match(const char *idstr, const struct acpi_device_id **matc
return false;
}
-/*
- * If one of the device IDs below is present in the list of device IDs of a
- * given ACPI device object, the PNP scan handler will not attach to that
- * object, because there is a proper non-PNP driver in the kernel for the
- * device represented by it.
- */
-static const struct acpi_device_id acpi_nonpnp_device_ids[] = {
- {"INT3F0D"},
- {"INTC1080"},
- {"INTC1081"},
- {"INTC1099"},
- {""},
-};
-
static int acpi_pnp_attach(struct acpi_device *adev,
const struct acpi_device_id *id)
{
- return !!acpi_match_device_ids(adev, acpi_nonpnp_device_ids);
+ return true;
}
static struct acpi_scan_handler acpi_pnp_handler = {
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index a984ccd..d0cb47c 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -180,104 +180,237 @@ void acpi_bus_detach_private_data(acpi_handle handle)
}
EXPORT_SYMBOL_GPL(acpi_bus_detach_private_data);
-static void acpi_print_osc_error(acpi_handle handle,
- struct acpi_osc_context *context, char *error)
+static void acpi_dump_osc_data(acpi_handle handle, const guid_t *guid, int rev,
+ struct acpi_buffer *cap)
{
+ u32 *capbuf = cap->pointer;
int i;
- acpi_handle_debug(handle, "(%s): %s\n", context->uuid_str, error);
+ acpi_handle_debug(handle, "_OSC: UUID: %pUL, rev: %d\n", guid, rev);
+ for (i = 0; i < cap->length / sizeof(u32); i++)
+ acpi_handle_debug(handle, "_OSC: capabilities DWORD %i: [%08x]\n",
+ i, capbuf[i]);
+}
- pr_debug("_OSC request data:");
- for (i = 0; i < context->cap.length; i += sizeof(u32))
- pr_debug(" %x", *((u32 *)(context->cap.pointer + i)));
+#define OSC_ERROR_MASK (OSC_REQUEST_ERROR | OSC_INVALID_UUID_ERROR | \
+ OSC_INVALID_REVISION_ERROR | \
+ OSC_CAPABILITIES_MASK_ERROR)
- pr_debug("\n");
+static int acpi_eval_osc(acpi_handle handle, guid_t *guid, int rev,
+ struct acpi_buffer *cap,
+ union acpi_object in_params[at_least 4],
+ struct acpi_buffer *output)
+{
+ struct acpi_object_list input;
+ union acpi_object *out_obj;
+ acpi_status status;
+
+ in_params[0].type = ACPI_TYPE_BUFFER;
+ in_params[0].buffer.length = sizeof(*guid);
+ in_params[0].buffer.pointer = (u8 *)guid;
+ in_params[1].type = ACPI_TYPE_INTEGER;
+ in_params[1].integer.value = rev;
+ in_params[2].type = ACPI_TYPE_INTEGER;
+ in_params[2].integer.value = cap->length / sizeof(u32);
+ in_params[3].type = ACPI_TYPE_BUFFER;
+ in_params[3].buffer.length = cap->length;
+ in_params[3].buffer.pointer = cap->pointer;
+ input.pointer = in_params;
+ input.count = 4;
+
+ output->length = ACPI_ALLOCATE_BUFFER;
+ output->pointer = NULL;
+
+ status = acpi_evaluate_object(handle, "_OSC", &input, output);
+ if (ACPI_FAILURE(status) || !output->length)
+ return -ENODATA;
+
+ out_obj = output->pointer;
+ if (out_obj->type != ACPI_TYPE_BUFFER ||
+ out_obj->buffer.length != cap->length) {
+ acpi_handle_debug(handle, "Invalid _OSC return buffer\n");
+ acpi_dump_osc_data(handle, guid, rev, cap);
+ ACPI_FREE(out_obj);
+ return -ENODATA;
+ }
+
+ return 0;
+}
+
+static bool acpi_osc_error_check(acpi_handle handle, guid_t *guid, int rev,
+ struct acpi_buffer *cap, u32 *retbuf)
+{
+ /* Only take defined error bits into account. */
+ u32 errors = retbuf[OSC_QUERY_DWORD] & OSC_ERROR_MASK;
+ u32 *capbuf = cap->pointer;
+ bool fail;
+
+ /*
+ * If OSC_QUERY_ENABLE is set, ignore the "capabilities masked"
+ * bit because it merely means that some features have not been
+ * acknowledged which is not unexpected.
+ */
+ if (capbuf[OSC_QUERY_DWORD] & OSC_QUERY_ENABLE)
+ errors &= ~OSC_CAPABILITIES_MASK_ERROR;
+
+ if (!errors)
+ return false;
+
+ acpi_dump_osc_data(handle, guid, rev, cap);
+ /*
+ * As a rule, fail only if OSC_QUERY_ENABLE is set because otherwise the
+ * acknowledged features need to be controlled.
+ */
+ fail = !!(capbuf[OSC_QUERY_DWORD] & OSC_QUERY_ENABLE);
+
+ if (errors & OSC_REQUEST_ERROR)
+ acpi_handle_debug(handle, "_OSC: request failed\n");
+
+ if (errors & OSC_INVALID_UUID_ERROR) {
+ acpi_handle_debug(handle, "_OSC: invalid UUID\n");
+ /*
+ * Always fail if this bit is set because it means that the
+ * request could not be processed.
+ */
+ fail = true;
+ }
+
+ if (errors & OSC_INVALID_REVISION_ERROR)
+ acpi_handle_debug(handle, "_OSC: invalid revision\n");
+
+ if (errors & OSC_CAPABILITIES_MASK_ERROR)
+ acpi_handle_debug(handle, "_OSC: capability bits masked\n");
+
+ return fail;
}
acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context)
{
- acpi_status status;
- struct acpi_object_list input;
- union acpi_object in_params[4];
- union acpi_object *out_obj;
+ union acpi_object in_params[4], *out_obj;
+ struct acpi_buffer output;
+ acpi_status status = AE_OK;
guid_t guid;
- u32 errors;
- struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
+ u32 *retbuf;
+ int ret;
- if (!context)
+ if (!context || !context->cap.pointer ||
+ context->cap.length < 2 * sizeof(32) ||
+ guid_parse(context->uuid_str, &guid))
+ return AE_BAD_PARAMETER;
+
+ ret = acpi_eval_osc(handle, &guid, context->rev, &context->cap,
+ in_params, &output);
+ if (ret)
return AE_ERROR;
- if (guid_parse(context->uuid_str, &guid))
- return AE_ERROR;
- context->ret.length = ACPI_ALLOCATE_BUFFER;
- context->ret.pointer = NULL;
-
- /* Setting up input parameters */
- input.count = 4;
- input.pointer = in_params;
- in_params[0].type = ACPI_TYPE_BUFFER;
- in_params[0].buffer.length = 16;
- in_params[0].buffer.pointer = (u8 *)&guid;
- in_params[1].type = ACPI_TYPE_INTEGER;
- in_params[1].integer.value = context->rev;
- in_params[2].type = ACPI_TYPE_INTEGER;
- in_params[2].integer.value = context->cap.length/sizeof(u32);
- in_params[3].type = ACPI_TYPE_BUFFER;
- in_params[3].buffer.length = context->cap.length;
- in_params[3].buffer.pointer = context->cap.pointer;
-
- status = acpi_evaluate_object(handle, "_OSC", &input, &output);
- if (ACPI_FAILURE(status))
- return status;
-
- if (!output.length)
- return AE_NULL_OBJECT;
out_obj = output.pointer;
- if (out_obj->type != ACPI_TYPE_BUFFER
- || out_obj->buffer.length != context->cap.length) {
- acpi_print_osc_error(handle, context,
- "_OSC evaluation returned wrong type");
- status = AE_TYPE;
- goto out_kfree;
- }
- /* Need to ignore the bit0 in result code */
- errors = *((u32 *)out_obj->buffer.pointer) & ~(1 << 0);
- if (errors) {
- if (errors & OSC_REQUEST_ERROR)
- acpi_print_osc_error(handle, context,
- "_OSC request failed");
- if (errors & OSC_INVALID_UUID_ERROR)
- acpi_print_osc_error(handle, context,
- "_OSC invalid UUID");
- if (errors & OSC_INVALID_REVISION_ERROR)
- acpi_print_osc_error(handle, context,
- "_OSC invalid revision");
- if (errors & OSC_CAPABILITIES_MASK_ERROR) {
- if (((u32 *)context->cap.pointer)[OSC_QUERY_DWORD]
- & OSC_QUERY_ENABLE)
- goto out_success;
- status = AE_SUPPORT;
- goto out_kfree;
- }
+ retbuf = (u32 *)out_obj->buffer.pointer;
+
+ if (acpi_osc_error_check(handle, &guid, context->rev, &context->cap, retbuf)) {
status = AE_ERROR;
- goto out_kfree;
+ goto out;
}
-out_success:
+
context->ret.length = out_obj->buffer.length;
- context->ret.pointer = kmemdup(out_obj->buffer.pointer,
- context->ret.length, GFP_KERNEL);
+ context->ret.pointer = kmemdup(retbuf, context->ret.length, GFP_KERNEL);
if (!context->ret.pointer) {
status = AE_NO_MEMORY;
- goto out_kfree;
+ goto out;
}
status = AE_OK;
-out_kfree:
- kfree(output.pointer);
+out:
+ ACPI_FREE(out_obj);
return status;
}
EXPORT_SYMBOL(acpi_run_osc);
+static int acpi_osc_handshake(acpi_handle handle, const char *uuid_str,
+ int rev, struct acpi_buffer *cap)
+{
+ union acpi_object in_params[4], *out_obj;
+ size_t bufsize = cap->length / sizeof(u32);
+ struct acpi_object_list input;
+ struct acpi_buffer output;
+ u32 *capbuf, *retbuf, test;
+ guid_t guid;
+ int ret, i;
+
+ if (!cap || cap->length < 2 * sizeof(32) || guid_parse(uuid_str, &guid))
+ return -EINVAL;
+
+ /* First evaluate _OSC with OSC_QUERY_ENABLE set. */
+ capbuf = cap->pointer;
+ capbuf[OSC_QUERY_DWORD] = OSC_QUERY_ENABLE;
+
+ ret = acpi_eval_osc(handle, &guid, rev, cap, in_params, &output);
+ if (ret)
+ return ret;
+
+ out_obj = output.pointer;
+ retbuf = (u32 *)out_obj->buffer.pointer;
+
+ if (acpi_osc_error_check(handle, &guid, rev, cap, retbuf)) {
+ ret = -ENODATA;
+ goto out;
+ }
+
+ /*
+ * Clear the feature bits in the capabilities buffer that have not been
+ * acknowledged and clear the return buffer.
+ */
+ for (i = OSC_QUERY_DWORD + 1, test = 0; i < bufsize; i++) {
+ capbuf[i] &= retbuf[i];
+ test |= capbuf[i];
+ retbuf[i] = 0;
+ }
+ /*
+ * If none of the feature bits have been acknowledged, there's nothing
+ * more to do. capbuf[] contains a feature mask of all zeros.
+ */
+ if (!test)
+ goto out;
+
+ retbuf[OSC_QUERY_DWORD] = 0;
+ /*
+ * Now evaluate _OSC again (directly) with OSC_QUERY_ENABLE clear and
+ * the updated input and output buffers used before. Since the feature
+ * bits that were clear in the return buffer from the previous _OSC
+ * evaluation are also clear in the capabilities buffer now, this _OSC
+ * evaluation is not expected to fail.
+ */
+ capbuf[OSC_QUERY_DWORD] = 0;
+ /* Reuse in_params[] populated by acpi_eval_osc(). */
+ input.pointer = in_params;
+ input.count = 4;
+
+ if (ACPI_FAILURE(acpi_evaluate_object(handle, "_OSC", &input, &output))) {
+ ret = -ENODATA;
+ goto out;
+ }
+
+ /*
+ * Clear the feature bits in capbuf[] that have not been acknowledged.
+ * After that, capbuf[] contains the resultant feature mask.
+ */
+ for (i = OSC_QUERY_DWORD + 1; i < bufsize; i++)
+ capbuf[i] &= retbuf[i];
+
+ if (retbuf[OSC_QUERY_DWORD] & OSC_ERROR_MASK) {
+ /*
+ * Complain about the unexpected errors and print diagnostic
+ * information related to them.
+ */
+ acpi_handle_err(handle, "_OSC: errors while processing control request\n");
+ acpi_handle_err(handle, "_OSC: some features may be missing\n");
+ acpi_osc_error_check(handle, &guid, rev, cap, retbuf);
+ }
+
+out:
+ ACPI_FREE(out_obj);
+ return ret;
+}
+
bool osc_sb_apei_support_acked;
/*
@@ -309,101 +442,73 @@ EXPORT_SYMBOL_GPL(osc_sb_native_usb4_support_confirmed);
bool osc_sb_cppc2_support_acked;
-static u8 sb_uuid_str[] = "0811B06E-4A27-44F9-8D60-3CBBC22E7B48";
static void acpi_bus_osc_negotiate_platform_control(void)
{
- u32 capbuf[2], *capbuf_ret;
- struct acpi_osc_context context = {
- .uuid_str = sb_uuid_str,
- .rev = 1,
- .cap.length = 8,
- .cap.pointer = capbuf,
+ static const u8 sb_uuid_str[] = "0811B06E-4A27-44F9-8D60-3CBBC22E7B48";
+ u32 capbuf[2], feature_mask;
+ struct acpi_buffer cap = {
+ .pointer = capbuf,
+ .length = sizeof(capbuf),
};
acpi_handle handle;
- capbuf[OSC_QUERY_DWORD] = OSC_QUERY_ENABLE;
- capbuf[OSC_SUPPORT_DWORD] = OSC_SB_PR3_SUPPORT; /* _PR3 is in use */
+ feature_mask = OSC_SB_PR3_SUPPORT | OSC_SB_HOTPLUG_OST_SUPPORT |
+ OSC_SB_PCLPI_SUPPORT | OSC_SB_OVER_16_PSTATES_SUPPORT |
+ OSC_SB_GED_SUPPORT | OSC_SB_IRQ_RESOURCE_SOURCE_SUPPORT;
+
+ if (IS_ENABLED(CONFIG_ARM64) || IS_ENABLED(CONFIG_X86))
+ feature_mask |= OSC_SB_GENERIC_INITIATOR_SUPPORT;
+
+ if (IS_ENABLED(CONFIG_ACPI_CPPC_LIB)) {
+ feature_mask |= OSC_SB_CPC_SUPPORT | OSC_SB_CPCV2_SUPPORT |
+ OSC_SB_CPC_FLEXIBLE_ADR_SPACE;
+ if (IS_ENABLED(CONFIG_SCHED_MC_PRIO))
+ feature_mask |= OSC_SB_CPC_DIVERSE_HIGH_SUPPORT;
+ }
+
if (IS_ENABLED(CONFIG_ACPI_PROCESSOR_AGGREGATOR))
- capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_PAD_SUPPORT;
+ feature_mask |= OSC_SB_PAD_SUPPORT;
+
if (IS_ENABLED(CONFIG_ACPI_PROCESSOR))
- capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_PPC_OST_SUPPORT;
+ feature_mask |= OSC_SB_PPC_OST_SUPPORT;
+
if (IS_ENABLED(CONFIG_ACPI_THERMAL))
- capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_FAST_THERMAL_SAMPLING_SUPPORT;
+ feature_mask |= OSC_SB_FAST_THERMAL_SAMPLING_SUPPORT;
+
if (IS_ENABLED(CONFIG_ACPI_BATTERY))
- capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_BATTERY_CHARGE_LIMITING_SUPPORT;
+ feature_mask |= OSC_SB_BATTERY_CHARGE_LIMITING_SUPPORT;
- capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_HOTPLUG_OST_SUPPORT;
- capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_PCLPI_SUPPORT;
- capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_OVER_16_PSTATES_SUPPORT;
- capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_GED_SUPPORT;
- capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_IRQ_RESOURCE_SOURCE_SUPPORT;
if (IS_ENABLED(CONFIG_ACPI_PRMT))
- capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_PRM_SUPPORT;
+ feature_mask |= OSC_SB_PRM_SUPPORT;
+
if (IS_ENABLED(CONFIG_ACPI_FFH))
- capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_FFH_OPR_SUPPORT;
-
-#ifdef CONFIG_ARM64
- capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_GENERIC_INITIATOR_SUPPORT;
-#endif
-#ifdef CONFIG_X86
- capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_GENERIC_INITIATOR_SUPPORT;
-#endif
-
-#ifdef CONFIG_ACPI_CPPC_LIB
- capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_CPC_SUPPORT;
- capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_CPCV2_SUPPORT;
-#endif
-
- capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_CPC_FLEXIBLE_ADR_SPACE;
-
- if (IS_ENABLED(CONFIG_SCHED_MC_PRIO))
- capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_CPC_DIVERSE_HIGH_SUPPORT;
+ feature_mask |= OSC_SB_FFH_OPR_SUPPORT;
if (IS_ENABLED(CONFIG_USB4))
- capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_NATIVE_USB4_SUPPORT;
+ feature_mask |= OSC_SB_NATIVE_USB4_SUPPORT;
if (!ghes_disable)
- capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_APEI_SUPPORT;
+ feature_mask |= OSC_SB_APEI_SUPPORT;
+
if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &handle)))
return;
- if (ACPI_FAILURE(acpi_run_osc(handle, &context)))
+ capbuf[OSC_SUPPORT_DWORD] = feature_mask;
+
+ acpi_handle_info(handle, "platform _OSC: OS support mask [%08x]\n", feature_mask);
+
+ if (acpi_osc_handshake(handle, sb_uuid_str, 1, &cap))
return;
- capbuf_ret = context.ret.pointer;
- if (context.ret.length <= OSC_SUPPORT_DWORD) {
- kfree(context.ret.pointer);
- return;
- }
+ feature_mask = capbuf[OSC_SUPPORT_DWORD];
- /*
- * Now run _OSC again with query flag clear and with the caps
- * supported by both the OS and the platform.
- */
- capbuf[OSC_QUERY_DWORD] = 0;
- capbuf[OSC_SUPPORT_DWORD] = capbuf_ret[OSC_SUPPORT_DWORD];
- kfree(context.ret.pointer);
+ acpi_handle_info(handle, "platform _OSC: OS control mask [%08x]\n", feature_mask);
- if (ACPI_FAILURE(acpi_run_osc(handle, &context)))
- return;
-
- capbuf_ret = context.ret.pointer;
- if (context.ret.length > OSC_SUPPORT_DWORD) {
-#ifdef CONFIG_ACPI_CPPC_LIB
- osc_sb_cppc2_support_acked = capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_CPCV2_SUPPORT;
-#endif
-
- osc_sb_apei_support_acked =
- capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_APEI_SUPPORT;
- osc_pc_lpi_support_confirmed =
- capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_PCLPI_SUPPORT;
- osc_sb_native_usb4_support_confirmed =
- capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_NATIVE_USB4_SUPPORT;
- osc_cpc_flexible_adr_space_confirmed =
- capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_CPC_FLEXIBLE_ADR_SPACE;
- }
-
- kfree(context.ret.pointer);
+ osc_sb_cppc2_support_acked = feature_mask & OSC_SB_CPCV2_SUPPORT;
+ osc_sb_apei_support_acked = feature_mask & OSC_SB_APEI_SUPPORT;
+ osc_pc_lpi_support_confirmed = feature_mask & OSC_SB_PCLPI_SUPPORT;
+ osc_sb_native_usb4_support_confirmed = feature_mask & OSC_SB_NATIVE_USB4_SUPPORT;
+ osc_cpc_flexible_adr_space_confirmed = feature_mask & OSC_SB_CPC_FLEXIBLE_ADR_SPACE;
}
/*
@@ -423,19 +528,15 @@ static void acpi_bus_decode_usb_osc(const char *msg, u32 bits)
(bits & OSC_USB_XDOMAIN) ? '+' : '-');
}
-static u8 sb_usb_uuid_str[] = "23A0D13A-26AB-486C-9C5F-0FFA525A575A";
static void acpi_bus_osc_negotiate_usb_control(void)
{
- u32 capbuf[3], *capbuf_ret;
- struct acpi_osc_context context = {
- .uuid_str = sb_usb_uuid_str,
- .rev = 1,
- .cap.length = sizeof(capbuf),
- .cap.pointer = capbuf,
+ static const u8 sb_usb_uuid_str[] = "23A0D13A-26AB-486C-9C5F-0FFA525A575A";
+ u32 capbuf[3], control;
+ struct acpi_buffer cap = {
+ .pointer = capbuf,
+ .length = sizeof(capbuf),
};
acpi_handle handle;
- acpi_status status;
- u32 control;
if (!osc_sb_native_usb4_support_confirmed)
return;
@@ -446,54 +547,16 @@ static void acpi_bus_osc_negotiate_usb_control(void)
control = OSC_USB_USB3_TUNNELING | OSC_USB_DP_TUNNELING |
OSC_USB_PCIE_TUNNELING | OSC_USB_XDOMAIN;
- /*
- * Run _OSC first with query bit set, trying to get control over
- * all tunneling. The platform can then clear out bits in the
- * control dword that it does not want to grant to the OS.
- */
- capbuf[OSC_QUERY_DWORD] = OSC_QUERY_ENABLE;
capbuf[OSC_SUPPORT_DWORD] = 0;
capbuf[OSC_CONTROL_DWORD] = control;
- status = acpi_run_osc(handle, &context);
- if (ACPI_FAILURE(status))
+ if (acpi_osc_handshake(handle, sb_usb_uuid_str, 1, &cap))
return;
- if (context.ret.length != sizeof(capbuf)) {
- pr_info("USB4 _OSC: returned invalid length buffer\n");
- goto out_free;
- }
-
- /*
- * Run _OSC again now with query bit clear and the control dword
- * matching what the platform granted (which may not have all
- * the control bits set).
- */
- capbuf_ret = context.ret.pointer;
-
- capbuf[OSC_QUERY_DWORD] = 0;
- capbuf[OSC_CONTROL_DWORD] = capbuf_ret[OSC_CONTROL_DWORD];
-
- kfree(context.ret.pointer);
-
- status = acpi_run_osc(handle, &context);
- if (ACPI_FAILURE(status))
- return;
-
- if (context.ret.length != sizeof(capbuf)) {
- pr_info("USB4 _OSC: returned invalid length buffer\n");
- goto out_free;
- }
-
- osc_sb_native_usb4_control =
- control & acpi_osc_ctx_get_pci_control(&context);
+ osc_sb_native_usb4_control = capbuf[OSC_CONTROL_DWORD];
acpi_bus_decode_usb_osc("USB4 _OSC: OS supports", control);
- acpi_bus_decode_usb_osc("USB4 _OSC: OS controls",
- osc_sb_native_usb4_control);
-
-out_free:
- kfree(context.ret.pointer);
+ acpi_bus_decode_usb_osc("USB4 _OSC: OS controls", osc_sb_native_usb4_control);
}
/* --------------------------------------------------------------------------
diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
index 4e05832..cff3186 100644
--- a/drivers/acpi/device_pm.c
+++ b/drivers/acpi/device_pm.c
@@ -586,8 +586,7 @@ acpi_status acpi_add_pm_notifier(struct acpi_device *adev, struct device *dev,
goto out;
mutex_lock(&acpi_pm_notifier_lock);
- adev->wakeup.ws = wakeup_source_register(&adev->dev,
- dev_name(&adev->dev));
+ adev->wakeup.ws = wakeup_source_register(dev, dev_name(&adev->dev));
adev->wakeup.context.dev = dev;
adev->wakeup.context.func = func;
adev->wakeup.flags.notifier_present = true;
diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
index 3eb56b7..e19aba0 100644
--- a/drivers/acpi/nfit/core.c
+++ b/drivers/acpi/nfit/core.c
@@ -2,6 +2,7 @@
/*
* Copyright(c) 2013-2015 Intel Corporation. All rights reserved.
*/
+#include <linux/platform_device.h>
#include <linux/list_sort.h>
#include <linux/libnvdimm.h>
#include <linux/module.h>
@@ -89,15 +90,22 @@ static const guid_t *to_nfit_bus_uuid(int family)
static struct acpi_device *to_acpi_dev(struct acpi_nfit_desc *acpi_desc)
{
struct nvdimm_bus_descriptor *nd_desc = &acpi_desc->nd_desc;
+ struct acpi_device *adev;
- /*
- * If provider == 'ACPI.NFIT' we can assume 'dev' is a struct
- * acpi_device.
- */
+ /* If provider == 'ACPI.NFIT', a struct acpi_device is there. */
if (!nd_desc->provider_name
|| strcmp(nd_desc->provider_name, "ACPI.NFIT") != 0)
return NULL;
+ /*
+ * But it can be the ACPI companion of acpi_desc->dev when it cones from
+ * acpi_nfit_probe().
+ */
+ adev = ACPI_COMPANION(acpi_desc->dev);
+ if (adev)
+ return adev;
+
+ /* Or it is acpi_desc->dev itself when it comes from nfit_ctl_test(). */
return to_acpi_device(acpi_desc->dev);
}
@@ -3283,11 +3291,11 @@ static void acpi_nfit_put_table(void *table)
static void acpi_nfit_notify(acpi_handle handle, u32 event, void *data)
{
- struct acpi_device *adev = data;
+ struct device *dev = data;
- device_lock(&adev->dev);
- __acpi_nfit_notify(&adev->dev, handle, event);
- device_unlock(&adev->dev);
+ device_lock(dev);
+ __acpi_nfit_notify(dev, handle, event);
+ device_unlock(dev);
}
static void acpi_nfit_remove_notify_handler(void *data)
@@ -3328,18 +3336,19 @@ void acpi_nfit_shutdown(void *data)
}
EXPORT_SYMBOL_GPL(acpi_nfit_shutdown);
-static int acpi_nfit_add(struct acpi_device *adev)
+static int acpi_nfit_probe(struct platform_device *pdev)
{
struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL };
struct acpi_nfit_desc *acpi_desc;
- struct device *dev = &adev->dev;
+ struct device *dev = &pdev->dev;
+ struct acpi_device *adev = ACPI_COMPANION(dev);
struct acpi_table_header *tbl;
acpi_status status = AE_OK;
acpi_size sz;
int rc = 0;
rc = acpi_dev_install_notify_handler(adev, ACPI_DEVICE_NOTIFY,
- acpi_nfit_notify, adev);
+ acpi_nfit_notify, dev);
if (rc)
return rc;
@@ -3369,7 +3378,7 @@ static int acpi_nfit_add(struct acpi_device *adev)
acpi_desc = devm_kzalloc(dev, sizeof(*acpi_desc), GFP_KERNEL);
if (!acpi_desc)
return -ENOMEM;
- acpi_nfit_desc_init(acpi_desc, &adev->dev);
+ acpi_nfit_desc_init(acpi_desc, dev);
/* Save the acpi header for exporting the revision via sysfs */
acpi_desc->acpi_header = *tbl;
@@ -3474,11 +3483,11 @@ static const struct acpi_device_id acpi_nfit_ids[] = {
};
MODULE_DEVICE_TABLE(acpi, acpi_nfit_ids);
-static struct acpi_driver acpi_nfit_driver = {
- .name = KBUILD_MODNAME,
- .ids = acpi_nfit_ids,
- .ops = {
- .add = acpi_nfit_add,
+static struct platform_driver acpi_nfit_driver = {
+ .probe = acpi_nfit_probe,
+ .driver = {
+ .name = "acpi-nfit",
+ .acpi_match_table = acpi_nfit_ids,
},
};
@@ -3516,7 +3525,7 @@ static __init int nfit_init(void)
return -ENOMEM;
nfit_mce_register();
- ret = acpi_bus_register_driver(&acpi_nfit_driver);
+ ret = platform_driver_register(&acpi_nfit_driver);
if (ret) {
nfit_mce_unregister();
destroy_workqueue(nfit_wq);
@@ -3529,7 +3538,7 @@ static __init int nfit_init(void)
static __exit void nfit_exit(void)
{
nfit_mce_unregister();
- acpi_bus_unregister_driver(&acpi_nfit_driver);
+ platform_driver_unregister(&acpi_nfit_driver);
destroy_workqueue(nfit_wq);
WARN_ON(!list_empty(&acpi_descs));
}
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 74ade41..9d7f85d 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -738,7 +738,7 @@ static int acpi_pci_root_add(struct acpi_device *device,
if (no_aspm)
pcie_no_aspm();
- pci_acpi_add_bus_pm_notifier(device);
+ pci_acpi_add_root_pm_notifier(device, root);
device_set_wakeup_capable(root->bus->bridge, device->wakeup.flags.valid);
if (hotadd) {
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 416d87f..c90b38f 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -42,6 +42,7 @@ static LIST_HEAD(acpi_scan_handlers_list);
DEFINE_MUTEX(acpi_device_lock);
LIST_HEAD(acpi_wakeup_device_list);
static DEFINE_MUTEX(acpi_hp_context_lock);
+static LIST_HEAD(acpi_scan_system_dev_list);
/*
* The UART device described by the SPCR table is the only object which needs
@@ -1469,6 +1470,7 @@ static void acpi_set_pnp_ids(acpi_handle handle, struct acpi_device_pnp *pnp,
break;
case ACPI_BUS_TYPE_THERMAL:
acpi_add_id(pnp, ACPI_THERMAL_HID);
+ pnp->type.platform_id = 1;
break;
case ACPI_BUS_TYPE_POWER_BUTTON:
acpi_add_id(pnp, ACPI_BUTTON_HID_POWERF);
@@ -2203,19 +2205,48 @@ static acpi_status acpi_bus_check_add_2(acpi_handle handle, u32 lvl_not_used,
return acpi_bus_check_add(handle, false, (struct acpi_device **)ret_p);
}
+struct acpi_scan_system_dev {
+ struct list_head node;
+ struct acpi_device *adev;
+};
+
+static const char * const acpi_system_dev_ids[] = {
+ "PNP0C01", /* Memory controller */
+ "PNP0C02", /* Motherboard resource */
+ NULL
+};
+
static void acpi_default_enumeration(struct acpi_device *device)
{
/*
* Do not enumerate devices with enumeration_by_parent flag set as
* they will be enumerated by their respective parents.
*/
- if (!device->flags.enumeration_by_parent) {
- acpi_create_platform_device(device, NULL);
- acpi_device_set_enumerated(device);
- } else {
+ if (device->flags.enumeration_by_parent) {
blocking_notifier_call_chain(&acpi_reconfig_chain,
ACPI_RECONFIG_DEVICE_ADD, device);
+ return;
}
+ if (match_string(acpi_system_dev_ids, -1, acpi_device_hid(device)) >= 0) {
+ struct acpi_scan_system_dev *sd;
+
+ /*
+ * This is a generic system device, so there is no need to
+ * create a platform device for it, but its resources need to be
+ * reserved. However, that needs to be done after all of the
+ * other device objects have been processed and PCI has claimed
+ * BARs in case there are resource conflicts.
+ */
+ sd = kmalloc(sizeof(*sd), GFP_KERNEL);
+ if (sd) {
+ sd->adev = device;
+ list_add_tail(&sd->node, &acpi_scan_system_dev_list);
+ }
+ } else {
+ /* For a regular device object, create a platform device. */
+ acpi_create_platform_device(device, NULL);
+ }
+ acpi_device_set_enumerated(device);
}
static const struct acpi_device_id generic_device_ids[] = {
@@ -2571,6 +2602,88 @@ static void acpi_scan_postponed(void)
mutex_unlock(&acpi_dep_list_lock);
}
+static void acpi_scan_claim_resources(struct acpi_device *adev)
+{
+ struct list_head resource_list = LIST_HEAD_INIT(resource_list);
+ struct resource_entry *rentry;
+ unsigned int count = 0;
+ const char *regionid;
+
+ if (acpi_dev_get_resources(adev, &resource_list, NULL, NULL) <= 0)
+ return;
+
+ regionid = kstrdup(dev_name(&adev->dev), GFP_KERNEL);
+ if (!regionid)
+ goto exit;
+
+ list_for_each_entry(rentry, &resource_list, node) {
+ struct resource *res = rentry->res;
+ struct resource *r;
+
+ /* Skip disabled and invalid resources. */
+ if ((res->flags & IORESOURCE_DISABLED) || res->end < res->start)
+ continue;
+
+ if (res->flags & IORESOURCE_IO) {
+ /*
+ * Follow the PNP system driver and on x86 skip I/O
+ * resources that start below 0x100 (the "standard PC
+ * hardware" boundary).
+ */
+ if (IS_ENABLED(CONFIG_X86) && res->start < 0x100) {
+ dev_info(&adev->dev, "Skipped %pR\n", res);
+ continue;
+ }
+ r = request_region(res->start, resource_size(res), regionid);
+ } else if (res->flags & IORESOURCE_MEM) {
+ r = request_mem_region(res->start, resource_size(res), regionid);
+ } else {
+ continue;
+ }
+
+ if (r) {
+ r->flags &= ~IORESOURCE_BUSY;
+ dev_info(&adev->dev, "Reserved %pR\n", r);
+ count++;
+ } else {
+ /*
+ * Failures at this point are usually harmless. PCI
+ * quirks, for example, reserve resources they know
+ * about too, so there may well be double reservations.
+ */
+ dev_info(&adev->dev, "Could not reserve %pR\n", res);
+ }
+ }
+
+ if (!count)
+ kfree(regionid);
+
+exit:
+ acpi_dev_free_resource_list(&resource_list);
+}
+
+
+static int __init acpi_reserve_motherboard_resources(void)
+{
+ struct acpi_scan_system_dev *sd, *tmp;
+
+ guard(mutex)(&acpi_scan_lock);
+
+ list_for_each_entry_safe(sd, tmp, &acpi_scan_system_dev_list, node) {
+ acpi_scan_claim_resources(sd->adev);
+ list_del(&sd->node);
+ kfree(sd);
+ }
+
+ return 0;
+}
+
+/*
+ * Reserve motherboard resources after PCI claims BARs, but before PCI assigns
+ * resources for uninitialized PCI devices.
+ */
+fs_initcall(acpi_reserve_motherboard_resources);
+
/**
* acpi_bus_scan - Add ACPI device node objects in a given namespace scope.
* @handle: Root of the namespace scope to scan.
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index a511f9e..e9d3ab1 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -25,6 +25,7 @@
#include <linux/kmod.h>
#include <linux/reboot.h>
#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/thermal.h>
#include <linux/acpi.h>
#include <linux/workqueue.h>
@@ -670,8 +671,7 @@ static void acpi_thermal_unregister_thermal_zone(struct acpi_thermal *tz)
static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data)
{
- struct acpi_device *device = data;
- struct acpi_thermal *tz = acpi_driver_data(device);
+ struct acpi_thermal *tz = data;
if (!tz)
return;
@@ -685,8 +685,8 @@ static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data)
acpi_thermal_trips_update(tz, event);
break;
default:
- acpi_handle_debug(device->handle, "Unsupported event [0x%x]\n",
- event);
+ acpi_handle_debug(tz->device->handle,
+ "Unsupported event [0x%x]\n", event);
break;
}
}
@@ -777,9 +777,10 @@ static void acpi_thermal_free_thermal_zone(struct acpi_thermal *tz)
kfree(tz);
}
-static int acpi_thermal_add(struct acpi_device *device)
+static int acpi_thermal_probe(struct platform_device *pdev)
{
struct thermal_trip trip_table[ACPI_THERMAL_MAX_NR_TRIPS] = { 0 };
+ struct acpi_device *device = ACPI_COMPANION(&pdev->dev);
struct acpi_thermal_trip *acpi_trip;
struct thermal_trip *trip;
struct acpi_thermal *tz;
@@ -795,11 +796,12 @@ static int acpi_thermal_add(struct acpi_device *device)
if (!tz)
return -ENOMEM;
+ platform_set_drvdata(pdev, tz);
+
tz->device = device;
strscpy(tz->name, device->pnp.bus_id);
strscpy(acpi_device_name(device), ACPI_THERMAL_DEVICE_NAME);
strscpy(acpi_device_class(device), ACPI_THERMAL_CLASS);
- device->driver_data = tz;
acpi_thermal_aml_dependency_fix(tz);
@@ -881,7 +883,7 @@ static int acpi_thermal_add(struct acpi_device *device)
acpi_device_bid(device), deci_kelvin_to_celsius(tz->temp_dk));
result = acpi_dev_install_notify_handler(device, ACPI_DEVICE_NOTIFY,
- acpi_thermal_notify, device);
+ acpi_thermal_notify, tz);
if (result)
goto flush_wq;
@@ -896,16 +898,11 @@ static int acpi_thermal_add(struct acpi_device *device)
return result;
}
-static void acpi_thermal_remove(struct acpi_device *device)
+static void acpi_thermal_remove(struct platform_device *pdev)
{
- struct acpi_thermal *tz;
+ struct acpi_thermal *tz = platform_get_drvdata(pdev);
- if (!device || !acpi_driver_data(device))
- return;
-
- tz = acpi_driver_data(device);
-
- acpi_dev_remove_notify_handler(device, ACPI_DEVICE_NOTIFY,
+ acpi_dev_remove_notify_handler(tz->device, ACPI_DEVICE_NOTIFY,
acpi_thermal_notify);
flush_workqueue(acpi_thermal_pm_queue);
@@ -914,44 +911,26 @@ static void acpi_thermal_remove(struct acpi_device *device)
}
#ifdef CONFIG_PM_SLEEP
-static int acpi_thermal_suspend(struct device *dev)
+static int acpi_thermal_prepare(struct device *dev)
{
/* Make sure the previously queued thermal check work has been done */
flush_workqueue(acpi_thermal_pm_queue);
return 0;
}
-static int acpi_thermal_resume(struct device *dev)
+static void acpi_thermal_complete(struct device *dev)
{
- struct acpi_thermal *tz;
- int i, j;
-
- if (!dev)
- return -EINVAL;
-
- tz = acpi_driver_data(to_acpi_device(dev));
- if (!tz)
- return -EINVAL;
-
- for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
- struct acpi_thermal_trip *acpi_trip = &tz->trips.active[i].trip;
-
- if (!acpi_thermal_trip_valid(acpi_trip))
- break;
-
- for (j = 0; j < acpi_trip->devices.count; j++)
- acpi_bus_update_power(acpi_trip->devices.handles[j], NULL);
- }
-
- acpi_queue_thermal_check(tz);
-
- return AE_OK;
+ acpi_queue_thermal_check(dev_get_drvdata(dev));
}
-#else
-#define acpi_thermal_suspend NULL
-#define acpi_thermal_resume NULL
-#endif
-static SIMPLE_DEV_PM_OPS(acpi_thermal_pm, acpi_thermal_suspend, acpi_thermal_resume);
+
+static const struct dev_pm_ops acpi_thermal_pm_ops = {
+ .prepare = acpi_thermal_prepare,
+ .complete = acpi_thermal_complete,
+};
+#define ACPI_THERMAL_PM &acpi_thermal_pm_ops
+#else /* !CONFIG_PM_SLEEP */
+#define ACPI_THERMAL_PM NULL
+#endif /* CONFIG_PM_SLEEP */
static const struct acpi_device_id thermal_device_ids[] = {
{ACPI_THERMAL_HID, 0},
@@ -959,15 +938,14 @@ static const struct acpi_device_id thermal_device_ids[] = {
};
MODULE_DEVICE_TABLE(acpi, thermal_device_ids);
-static struct acpi_driver acpi_thermal_driver = {
- .name = "thermal",
- .class = ACPI_THERMAL_CLASS,
- .ids = thermal_device_ids,
- .ops = {
- .add = acpi_thermal_add,
- .remove = acpi_thermal_remove,
- },
- .drv.pm = &acpi_thermal_pm,
+static struct platform_driver acpi_thermal_driver = {
+ .probe = acpi_thermal_probe,
+ .remove = acpi_thermal_remove,
+ .driver = {
+ .name = "acpi-thermal",
+ .acpi_match_table = thermal_device_ids,
+ .pm = ACPI_THERMAL_PM,
+ },
};
static int thermal_act(const struct dmi_system_id *d)
@@ -1065,7 +1043,7 @@ static int __init acpi_thermal_init(void)
if (!acpi_thermal_pm_queue)
return -ENODEV;
- result = acpi_bus_register_driver(&acpi_thermal_driver);
+ result = platform_driver_register(&acpi_thermal_driver);
if (result < 0) {
destroy_workqueue(acpi_thermal_pm_queue);
return -ENODEV;
@@ -1076,7 +1054,7 @@ static int __init acpi_thermal_init(void)
static void __exit acpi_thermal_exit(void)
{
- acpi_bus_unregister_driver(&acpi_thermal_driver);
+ platform_driver_unregister(&acpi_thermal_driver);
destroy_workqueue(acpi_thermal_pm_queue);
}
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 97a8b4fc..189de52 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -1647,10 +1647,11 @@ static void device_suspend_late(struct device *dev, pm_message_t state, bool asy
goto Complete;
/*
- * Disable runtime PM for the device without checking if there is a
- * pending resume request for it.
+ * After this point, any runtime PM operations targeting the device
+ * will fail until the corresponding pm_runtime_enable() call in
+ * device_resume_early().
*/
- __pm_runtime_disable(dev, false);
+ pm_runtime_disable(dev);
if (dev->power.syscore)
goto Skip;
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 4472bb1..50dde29 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -2803,7 +2803,7 @@ static int cpufreq_boost_trigger_state(int state)
{
struct cpufreq_policy *policy;
unsigned long flags;
- int ret = 0;
+ int ret = -EOPNOTSUPP;
/*
* Don't compare 'cpufreq_driver->boost_enabled' with 'state' here to
@@ -2820,15 +2820,14 @@ static int cpufreq_boost_trigger_state(int state)
continue;
ret = policy_set_boost(policy, state);
- if (ret)
- goto err_reset_state;
+ if (unlikely(ret))
+ break;
}
+
cpus_read_unlock();
- return 0;
-
-err_reset_state:
- cpus_read_unlock();
+ if (likely(!ret))
+ return 0;
write_lock_irqsave(&cpufreq_driver_lock, flags);
cpufreq_driver->boost_enabled = !state;
diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c
index a6eb6bf..eefb2ba 100644
--- a/drivers/parisc/sba_iommu.c
+++ b/drivers/parisc/sba_iommu.c
@@ -578,8 +578,8 @@ sba_io_pdir_entry(__le64 *pdir_ptr, space_t sid, phys_addr_t pba,
pba &= IOVP_MASK;
pba |= (ci >> PAGE_SHIFT) & 0xff; /* move CI (8 bits) into lowest byte */
- pba |= SBA_PDIR_VALID_BIT; /* set "valid" bit */
- *pdir_ptr = cpu_to_le64(pba); /* swap and store into I/O Pdir */
+ /* set "valid" bit, swap and store into I/O Pdir */
+ *pdir_ptr = cpu_to_le64((unsigned long)pba | SBA_PDIR_VALID_BIT);
/*
* If the PDC_MODEL capabilities has Non-coherent IO-PDIR bit set
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index 93693777..7998020 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -847,12 +847,7 @@ bool shpchp_is_native(struct pci_dev *bridge)
*/
static void pci_acpi_wake_bus(struct acpi_device_wakeup_context *context)
{
- struct acpi_device *adev;
- struct acpi_pci_root *root;
-
- adev = container_of(context, struct acpi_device, wakeup.context);
- root = acpi_driver_data(adev);
- pci_pme_wakeup_bus(root->bus);
+ pci_pme_wakeup_bus(to_pci_host_bridge(context->dev)->bus);
}
/**
@@ -885,12 +880,14 @@ static void pci_acpi_wake_dev(struct acpi_device_wakeup_context *context)
}
/**
- * pci_acpi_add_bus_pm_notifier - Register PM notifier for root PCI bus.
+ * pci_acpi_add_root_pm_notifier - Register PM notifier for root PCI bus.
* @dev: PCI root bridge ACPI device.
+ * @root: PCI root corresponding to @dev.
*/
-acpi_status pci_acpi_add_bus_pm_notifier(struct acpi_device *dev)
+acpi_status pci_acpi_add_root_pm_notifier(struct acpi_device *dev,
+ struct acpi_pci_root *root)
{
- return acpi_add_pm_notifier(dev, NULL, pci_acpi_wake_bus);
+ return acpi_add_pm_notifier(dev, root->bus->bridge, pci_acpi_wake_bus);
}
/**
diff --git a/drivers/platform/x86/intel/hid.c b/drivers/platform/x86/intel/hid.c
index 560cc06..0f8684f 100644
--- a/drivers/platform/x86/intel/hid.c
+++ b/drivers/platform/x86/intel/hid.c
@@ -779,43 +779,4 @@ static struct platform_driver intel_hid_pl_driver = {
.remove = intel_hid_remove,
};
-/*
- * Unfortunately, some laptops provide a _HID="INT33D5" device with
- * _CID="PNP0C02". This causes the pnpacpi scan driver to claim the
- * ACPI node, so no platform device will be created. The pnpacpi
- * driver rejects this device in subsequent processing, so no physical
- * node is created at all.
- *
- * As a workaround until the ACPI core figures out how to handle
- * this corner case, manually ask the ACPI platform device code to
- * claim the ACPI node.
- */
-static acpi_status __init
-check_acpi_dev(acpi_handle handle, u32 lvl, void *context, void **rv)
-{
- const struct acpi_device_id *ids = context;
- struct acpi_device *dev = acpi_fetch_acpi_dev(handle);
-
- if (dev && acpi_match_device_ids(dev, ids) == 0)
- if (!IS_ERR_OR_NULL(acpi_create_platform_device(dev, NULL)))
- dev_info(&dev->dev,
- "intel-hid: created platform device\n");
-
- return AE_OK;
-}
-
-static int __init intel_hid_init(void)
-{
- acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
- ACPI_UINT32_MAX, check_acpi_dev, NULL,
- (void *)intel_hid_ids, NULL);
-
- return platform_driver_register(&intel_hid_pl_driver);
-}
-module_init(intel_hid_init);
-
-static void __exit intel_hid_exit(void)
-{
- platform_driver_unregister(&intel_hid_pl_driver);
-}
-module_exit(intel_hid_exit);
+module_platform_driver(intel_hid_pl_driver);
diff --git a/drivers/platform/x86/intel/vbtn.c b/drivers/platform/x86/intel/vbtn.c
index 232cd12..9ca87e7 100644
--- a/drivers/platform/x86/intel/vbtn.c
+++ b/drivers/platform/x86/intel/vbtn.c
@@ -390,32 +390,4 @@ static struct platform_driver intel_vbtn_pl_driver = {
.remove = intel_vbtn_remove,
};
-static acpi_status __init
-check_acpi_dev(acpi_handle handle, u32 lvl, void *context, void **rv)
-{
- const struct acpi_device_id *ids = context;
- struct acpi_device *dev = acpi_fetch_acpi_dev(handle);
-
- if (dev && acpi_match_device_ids(dev, ids) == 0)
- if (!IS_ERR_OR_NULL(acpi_create_platform_device(dev, NULL)))
- dev_info(&dev->dev,
- "intel-vbtn: created platform device\n");
-
- return AE_OK;
-}
-
-static int __init intel_vbtn_init(void)
-{
- acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
- ACPI_UINT32_MAX, check_acpi_dev, NULL,
- (void *)intel_vbtn_ids, NULL);
-
- return platform_driver_register(&intel_vbtn_pl_driver);
-}
-module_init(intel_vbtn_init);
-
-static void __exit intel_vbtn_exit(void)
-{
- platform_driver_unregister(&intel_vbtn_pl_driver);
-}
-module_exit(intel_vbtn_exit);
+module_platform_driver(intel_vbtn_pl_driver);
diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h
index 078225b..c0c54ba 100644
--- a/include/linux/pci-acpi.h
+++ b/include/linux/pci-acpi.h
@@ -12,7 +12,8 @@
#include <linux/acpi.h>
#ifdef CONFIG_ACPI
-extern acpi_status pci_acpi_add_bus_pm_notifier(struct acpi_device *dev);
+extern acpi_status pci_acpi_add_root_pm_notifier(struct acpi_device *dev,
+ struct acpi_pci_root *pci_root);
static inline acpi_status pci_acpi_remove_bus_pm_notifier(struct acpi_device *dev)
{
return acpi_remove_pm_notifier(dev);
diff --git a/kernel/power/main.c b/kernel/power/main.c
index 03b2c54..5f8c9e1 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -1125,7 +1125,7 @@ EXPORT_SYMBOL_GPL(pm_wq);
static int __init pm_start_workqueues(void)
{
- pm_wq = alloc_workqueue("pm", WQ_FREEZABLE | WQ_UNBOUND, 0);
+ pm_wq = alloc_workqueue("pm", WQ_UNBOUND, 0);
if (!pm_wq)
return -ENOMEM;