Commit 2e178ee1 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki

Merge branches 'acpi-bus' and 'acpi-scan'

Merge additional ACPI device enumeration code changes for 6.5-rc1.

 - Make acpi_companion_match() return a const pointer and update its
   callers accordingly (Andy Shevchenko).

 - Move the extern declaration of the acpi_root variable to a header
   file so as to address a compiler warning (Andy Shevchenko).

 - Address compiler warnings in the ACPI device enumeration code by
   adding a missing header file include to it (Ben Dooks).

 - Refine the SMB0001 quirk in the ACPI device enumeration code so as to
   address an i2c-scmi driver regression (Andy Shevchenko).

 - Clean up two pieces of the ACPI device enumeration code (Andy
   Shevchenko).

* acpi-bus:
  ACPI: bus: Constify acpi_companion_match() returned value

* acpi-scan:
  ACPI: scan: Use the acpi_match_acpi_device() helper
  ACPI: platform: Move SMB0001 HID to the header and reuse
  ACPI: platform: Ignore SMB0001 only when it has resources
  ACPI: bus: Introduce acpi_match_acpi_device() helper
  ACPI: scan: fix undeclared variable warnings by including sleep.h
  ACPI: scan: Move acpi_root to internal header
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
*/ */
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/bits.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -19,13 +20,16 @@ ...@@ -19,13 +20,16 @@
#include "internal.h" #include "internal.h"
/* Exclude devices that have no _CRS resources provided */
#define ACPI_ALLOW_WO_RESOURCES BIT(0)
static const struct acpi_device_id forbidden_id_list[] = { static const struct acpi_device_id forbidden_id_list[] = {
{"ACPI0009", 0}, /* IOxAPIC */ {"ACPI0009", 0}, /* IOxAPIC */
{"ACPI000A", 0}, /* IOAPIC */ {"ACPI000A", 0}, /* IOAPIC */
{"PNP0000", 0}, /* PIC */ {"PNP0000", 0}, /* PIC */
{"PNP0100", 0}, /* Timer */ {"PNP0100", 0}, /* Timer */
{"PNP0200", 0}, /* AT DMA Controller */ {"PNP0200", 0}, /* AT DMA Controller */
{"SMB0001", 0}, /* ACPI SMBUS virtual device */ {ACPI_SMBUS_MS_HID, ACPI_ALLOW_WO_RESOURCES}, /* ACPI SMBUS virtual device */
{ } { }
}; };
...@@ -83,6 +87,15 @@ static void acpi_platform_fill_resource(struct acpi_device *adev, ...@@ -83,6 +87,15 @@ static void acpi_platform_fill_resource(struct acpi_device *adev,
dest->parent = pci_find_resource(to_pci_dev(parent), dest); dest->parent = pci_find_resource(to_pci_dev(parent), dest);
} }
static unsigned int acpi_platform_resource_count(struct acpi_resource *ares, void *data)
{
bool *has_resources = data;
*has_resources = true;
return AE_CTRL_TERMINATE;
}
/** /**
* acpi_create_platform_device - Create platform device for ACPI device node * acpi_create_platform_device - Create platform device for ACPI device node
* @adev: ACPI device node to create a platform device for. * @adev: ACPI device node to create a platform device for.
...@@ -100,6 +113,7 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev, ...@@ -100,6 +113,7 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev,
struct acpi_device *parent = acpi_dev_parent(adev); struct acpi_device *parent = acpi_dev_parent(adev);
struct platform_device *pdev = NULL; struct platform_device *pdev = NULL;
struct platform_device_info pdevinfo; struct platform_device_info pdevinfo;
const struct acpi_device_id *match;
struct resource_entry *rentry; struct resource_entry *rentry;
struct list_head resource_list; struct list_head resource_list;
struct resource *resources = NULL; struct resource *resources = NULL;
...@@ -109,8 +123,19 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev, ...@@ -109,8 +123,19 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev,
if (adev->physical_node_count) if (adev->physical_node_count)
return NULL; return NULL;
if (!acpi_match_device_ids(adev, forbidden_id_list)) match = acpi_match_acpi_device(forbidden_id_list, adev);
return ERR_PTR(-EINVAL); if (match) {
if (match->driver_data & ACPI_ALLOW_WO_RESOURCES) {
bool has_resources = false;
acpi_walk_resources(adev->handle, METHOD_NAME__CRS,
acpi_platform_resource_count, &has_resources);
if (has_resources)
return ERR_PTR(-EINVAL);
} else {
return ERR_PTR(-EINVAL);
}
}
INIT_LIST_HEAD(&resource_list); INIT_LIST_HEAD(&resource_list);
count = acpi_dev_get_resources(adev, &resource_list, NULL, NULL); count = acpi_dev_get_resources(adev, &resource_list, NULL, NULL);
......
...@@ -682,7 +682,7 @@ bool acpi_device_is_first_physical_node(struct acpi_device *adev, ...@@ -682,7 +682,7 @@ bool acpi_device_is_first_physical_node(struct acpi_device *adev,
* resources available from it but they will be matched normally using functions * resources available from it but they will be matched normally using functions
* provided by their bus types (and analogously for their modalias). * provided by their bus types (and analogously for their modalias).
*/ */
struct acpi_device *acpi_companion_match(const struct device *dev) const struct acpi_device *acpi_companion_match(const struct device *dev)
{ {
struct acpi_device *adev; struct acpi_device *adev;
...@@ -706,7 +706,7 @@ struct acpi_device *acpi_companion_match(const struct device *dev) ...@@ -706,7 +706,7 @@ struct acpi_device *acpi_companion_match(const struct device *dev)
* identifiers and a _DSD object with the "compatible" property, use that * identifiers and a _DSD object with the "compatible" property, use that
* property to match against the given list of identifiers. * property to match against the given list of identifiers.
*/ */
static bool acpi_of_match_device(struct acpi_device *adev, static bool acpi_of_match_device(const struct acpi_device *adev,
const struct of_device_id *of_match_table, const struct of_device_id *of_match_table,
const struct of_device_id **of_id) const struct of_device_id **of_id)
{ {
...@@ -808,7 +808,7 @@ static bool __acpi_match_device_cls(const struct acpi_device_id *id, ...@@ -808,7 +808,7 @@ static bool __acpi_match_device_cls(const struct acpi_device_id *id,
return true; return true;
} }
static bool __acpi_match_device(struct acpi_device *device, static bool __acpi_match_device(const struct acpi_device *device,
const struct acpi_device_id *acpi_ids, const struct acpi_device_id *acpi_ids,
const struct of_device_id *of_ids, const struct of_device_id *of_ids,
const struct acpi_device_id **acpi_id, const struct acpi_device_id **acpi_id,
...@@ -850,6 +850,26 @@ static bool __acpi_match_device(struct acpi_device *device, ...@@ -850,6 +850,26 @@ static bool __acpi_match_device(struct acpi_device *device,
return true; return true;
} }
/**
* acpi_match_acpi_device - Match an ACPI device against a given list of ACPI IDs
* @ids: Array of struct acpi_device_id objects to match against.
* @adev: The ACPI device pointer to match.
*
* Match the ACPI device @adev against a given list of ACPI IDs @ids.
*
* Return:
* a pointer to the first matching ACPI ID on success or %NULL on failure.
*/
const struct acpi_device_id *acpi_match_acpi_device(const struct acpi_device_id *ids,
const struct acpi_device *adev)
{
const struct acpi_device_id *id = NULL;
__acpi_match_device(adev, ids, NULL, &id, NULL);
return id;
}
EXPORT_SYMBOL_GPL(acpi_match_acpi_device);
/** /**
* acpi_match_device - Match a struct device against a given list of ACPI IDs * acpi_match_device - Match a struct device against a given list of ACPI IDs
* @ids: Array of struct acpi_device_id object to match against. * @ids: Array of struct acpi_device_id object to match against.
...@@ -864,10 +884,7 @@ static bool __acpi_match_device(struct acpi_device *device, ...@@ -864,10 +884,7 @@ static bool __acpi_match_device(struct acpi_device *device,
const struct acpi_device_id *acpi_match_device(const struct acpi_device_id *ids, const struct acpi_device_id *acpi_match_device(const struct acpi_device_id *ids,
const struct device *dev) const struct device *dev)
{ {
const struct acpi_device_id *id = NULL; return acpi_match_acpi_device(ids, acpi_companion_match(dev));
__acpi_match_device(acpi_companion_match(dev), ids, NULL, &id, NULL);
return id;
} }
EXPORT_SYMBOL_GPL(acpi_match_device); EXPORT_SYMBOL_GPL(acpi_match_device);
......
...@@ -283,7 +283,7 @@ int acpi_device_uevent_modalias(const struct device *dev, struct kobj_uevent_env ...@@ -283,7 +283,7 @@ int acpi_device_uevent_modalias(const struct device *dev, struct kobj_uevent_env
} }
EXPORT_SYMBOL_GPL(acpi_device_uevent_modalias); EXPORT_SYMBOL_GPL(acpi_device_uevent_modalias);
static int __acpi_device_modalias(struct acpi_device *adev, char *buf, int size) static int __acpi_device_modalias(const struct acpi_device *adev, char *buf, int size)
{ {
int len, count; int len, count;
......
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
#include <linux/idr.h> #include <linux/idr.h>
extern struct acpi_device *acpi_root;
int early_acpi_osi_init(void); int early_acpi_osi_init(void);
int acpi_osi_init(void); int acpi_osi_init(void);
acpi_status acpi_os_initialize1(void); acpi_status acpi_os_initialize1(void);
...@@ -119,7 +121,7 @@ int acpi_bus_register_early_device(int type); ...@@ -119,7 +121,7 @@ int acpi_bus_register_early_device(int type);
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
Device Matching and Notification Device Matching and Notification
-------------------------------------------------------------------------- */ -------------------------------------------------------------------------- */
struct acpi_device *acpi_companion_match(const struct device *dev); const struct acpi_device *acpi_companion_match(const struct device *dev);
int __acpi_device_uevent_modalias(const struct acpi_device *adev, int __acpi_device_uevent_modalias(const struct acpi_device *adev,
struct kobj_uevent_env *env); struct kobj_uevent_env *env);
......
...@@ -23,8 +23,7 @@ ...@@ -23,8 +23,7 @@
#include <linux/dma-direct.h> #include <linux/dma-direct.h>
#include "internal.h" #include "internal.h"
#include "sleep.h"
extern struct acpi_device *acpi_root;
#define ACPI_BUS_CLASS "system_bus" #define ACPI_BUS_CLASS "system_bus"
#define ACPI_BUS_HID "LNXSYBUS" #define ACPI_BUS_HID "LNXSYBUS"
...@@ -930,26 +929,29 @@ static int acpi_bus_extract_wakeup_device_power_package(struct acpi_device *dev) ...@@ -930,26 +929,29 @@ static int acpi_bus_extract_wakeup_device_power_package(struct acpi_device *dev)
return err; return err;
} }
/* Do not use a button for S5 wakeup */
#define ACPI_AVOID_WAKE_FROM_S5 BIT(0)
static bool acpi_wakeup_gpe_init(struct acpi_device *device) static bool acpi_wakeup_gpe_init(struct acpi_device *device)
{ {
static const struct acpi_device_id button_device_ids[] = { static const struct acpi_device_id button_device_ids[] = {
{"PNP0C0C", 0}, /* Power button */ {"PNP0C0C", 0}, /* Power button */
{"PNP0C0D", 0}, /* Lid */ {"PNP0C0D", ACPI_AVOID_WAKE_FROM_S5}, /* Lid */
{"PNP0C0E", 0}, /* Sleep button */ {"PNP0C0E", ACPI_AVOID_WAKE_FROM_S5}, /* Sleep button */
{"", 0}, {"", 0},
}; };
struct acpi_device_wakeup *wakeup = &device->wakeup; struct acpi_device_wakeup *wakeup = &device->wakeup;
const struct acpi_device_id *match;
acpi_status status; acpi_status status;
wakeup->flags.notifier_present = 0; wakeup->flags.notifier_present = 0;
/* Power button, Lid switch always enable wakeup */ /* Power button, Lid switch always enable wakeup */
if (!acpi_match_device_ids(device, button_device_ids)) { match = acpi_match_acpi_device(button_device_ids, device);
if (!acpi_match_device_ids(device, &button_device_ids[1])) { if (match) {
/* Do not use Lid/sleep button for S5 wakeup */ if ((match->driver_data & ACPI_AVOID_WAKE_FROM_S5) &&
if (wakeup->sleep_state == ACPI_STATE_S5) wakeup->sleep_state == ACPI_STATE_S5)
wakeup->sleep_state = ACPI_STATE_S4; wakeup->sleep_state = ACPI_STATE_S4;
}
acpi_mark_gpe_for_wake(wakeup->gpe_device, wakeup->gpe_number); acpi_mark_gpe_for_wake(wakeup->gpe_device, wakeup->gpe_number);
device_set_wakeup_capable(&device->dev, true); device_set_wakeup_capable(&device->dev, true);
return true; return true;
......
...@@ -13,9 +13,6 @@ ...@@ -13,9 +13,6 @@
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/acpi.h> #include <linux/acpi.h>
/* SMBUS HID definition as supported by Microsoft Windows */
#define ACPI_SMBUS_MS_HID "SMB0001"
struct smbus_methods_t { struct smbus_methods_t {
char *mt_info; char *mt_info;
char *mt_sbr; char *mt_sbr;
......
...@@ -27,6 +27,8 @@ ...@@ -27,6 +27,8 @@
#define ACPI_BAY_HID "LNXIOBAY" #define ACPI_BAY_HID "LNXIOBAY"
#define ACPI_DOCK_HID "LNXDOCK" #define ACPI_DOCK_HID "LNXDOCK"
#define ACPI_ECDT_HID "LNXEC" #define ACPI_ECDT_HID "LNXEC"
/* SMBUS HID definition as supported by Microsoft Windows */
#define ACPI_SMBUS_MS_HID "SMB0001"
/* Quirk for broken IBM BIOSes */ /* Quirk for broken IBM BIOSes */
#define ACPI_SMBUS_IBM_HID "SMBUSIBM" #define ACPI_SMBUS_IBM_HID "SMBUSIBM"
......
...@@ -719,6 +719,9 @@ extern int acpi_nvs_register(__u64 start, __u64 size); ...@@ -719,6 +719,9 @@ extern int acpi_nvs_register(__u64 start, __u64 size);
extern int acpi_nvs_for_each_region(int (*func)(__u64, __u64, void *), extern int acpi_nvs_for_each_region(int (*func)(__u64, __u64, void *),
void *data); void *data);
const struct acpi_device_id *acpi_match_acpi_device(const struct acpi_device_id *ids,
const struct acpi_device *adev);
const struct acpi_device_id *acpi_match_device(const struct acpi_device_id *ids, const struct acpi_device_id *acpi_match_device(const struct acpi_device_id *ids,
const struct device *dev); const struct device *dev);
...@@ -935,6 +938,12 @@ static inline int acpi_nvs_for_each_region(int (*func)(__u64, __u64, void *), ...@@ -935,6 +938,12 @@ static inline int acpi_nvs_for_each_region(int (*func)(__u64, __u64, void *),
struct acpi_device_id; struct acpi_device_id;
static inline const struct acpi_device_id *acpi_match_acpi_device(
const struct acpi_device_id *ids, const struct acpi_device *adev)
{
return NULL;
}
static inline const struct acpi_device_id *acpi_match_device( static inline const struct acpi_device_id *acpi_match_device(
const struct acpi_device_id *ids, const struct device *dev) const struct acpi_device_id *ids, const struct device *dev)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment