mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-04 17:44:14 +08:00
Merge branch 'acpi-scan'
* acpi-scan: ata: ahci_platform: Add ACPI _CLS matching ACPI / scan: Add support for ACPI _CLS device matching
This commit is contained in:
commit
8076ca480f
@ -1019,6 +1019,29 @@ static bool acpi_of_match_device(struct acpi_device *adev,
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool __acpi_match_device_cls(const struct acpi_device_id *id,
|
||||
struct acpi_hardware_id *hwid)
|
||||
{
|
||||
int i, msk, byte_shift;
|
||||
char buf[3];
|
||||
|
||||
if (!id->cls)
|
||||
return false;
|
||||
|
||||
/* Apply class-code bitmask, before checking each class-code byte */
|
||||
for (i = 1; i <= 3; i++) {
|
||||
byte_shift = 8 * (3 - i);
|
||||
msk = (id->cls_msk >> byte_shift) & 0xFF;
|
||||
if (!msk)
|
||||
continue;
|
||||
|
||||
sprintf(buf, "%02x", (id->cls >> byte_shift) & msk);
|
||||
if (strncmp(buf, &hwid->id[(i - 1) * 2], 2))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static const struct acpi_device_id *__acpi_match_device(
|
||||
struct acpi_device *device,
|
||||
const struct acpi_device_id *ids,
|
||||
@ -1036,9 +1059,12 @@ static const struct acpi_device_id *__acpi_match_device(
|
||||
|
||||
list_for_each_entry(hwid, &device->pnp.ids, list) {
|
||||
/* First, check the ACPI/PNP IDs provided by the caller. */
|
||||
for (id = ids; id->id[0]; id++)
|
||||
if (!strcmp((char *) id->id, hwid->id))
|
||||
for (id = ids; id->id[0] || id->cls; id++) {
|
||||
if (id->id[0] && !strcmp((char *) id->id, hwid->id))
|
||||
return id;
|
||||
else if (id->cls && __acpi_match_device_cls(id, hwid))
|
||||
return id;
|
||||
}
|
||||
|
||||
/*
|
||||
* Next, check ACPI_DT_NAMESPACE_HID and try to match the
|
||||
@ -2101,6 +2127,8 @@ static void acpi_set_pnp_ids(acpi_handle handle, struct acpi_device_pnp *pnp,
|
||||
if (info->valid & ACPI_VALID_UID)
|
||||
pnp->unique_id = kstrdup(info->unique_id.string,
|
||||
GFP_KERNEL);
|
||||
if (info->valid & ACPI_VALID_CLS)
|
||||
acpi_add_id(pnp, info->class_code.string);
|
||||
|
||||
kfree(info);
|
||||
|
||||
|
@ -48,7 +48,7 @@ config ATA_VERBOSE_ERROR
|
||||
|
||||
config ATA_ACPI
|
||||
bool "ATA ACPI Support"
|
||||
depends on ACPI && PCI
|
||||
depends on ACPI
|
||||
default y
|
||||
help
|
||||
This option adds support for ATA-related ACPI objects.
|
||||
|
@ -20,6 +20,8 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/libata.h>
|
||||
#include <linux/ahci_platform.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/pci_ids.h>
|
||||
#include "ahci.h"
|
||||
|
||||
#define DRV_NAME "ahci"
|
||||
@ -79,12 +81,19 @@ static const struct of_device_id ahci_of_match[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ahci_of_match);
|
||||
|
||||
static const struct acpi_device_id ahci_acpi_match[] = {
|
||||
{ ACPI_DEVICE_CLASS(PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff) },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, ahci_acpi_match);
|
||||
|
||||
static struct platform_driver ahci_driver = {
|
||||
.probe = ahci_probe,
|
||||
.remove = ata_platform_remove_one,
|
||||
.driver = {
|
||||
.name = DRV_NAME,
|
||||
.of_match_table = ahci_of_match,
|
||||
.acpi_match_table = ahci_acpi_match,
|
||||
.pm = &ahci_pm_ops,
|
||||
},
|
||||
};
|
||||
|
@ -58,6 +58,19 @@ static inline acpi_handle acpi_device_handle(struct acpi_device *adev)
|
||||
acpi_fwnode_handle(adev) : NULL)
|
||||
#define ACPI_HANDLE(dev) acpi_device_handle(ACPI_COMPANION(dev))
|
||||
|
||||
/**
|
||||
* ACPI_DEVICE_CLASS - macro used to describe an ACPI device with
|
||||
* the PCI-defined class-code information
|
||||
*
|
||||
* @_cls : the class, subclass, prog-if triple for this device
|
||||
* @_msk : the class mask for this device
|
||||
*
|
||||
* This macro is used to create a struct acpi_device_id that matches a
|
||||
* specific PCI class. The .id and .driver_data fields will be left
|
||||
* initialized with the default value.
|
||||
*/
|
||||
#define ACPI_DEVICE_CLASS(_cls, _msk) .cls = (_cls), .cls_msk = (_msk),
|
||||
|
||||
static inline bool has_acpi_companion(struct device *dev)
|
||||
{
|
||||
return is_acpi_node(dev->fwnode);
|
||||
@ -443,6 +456,7 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *);
|
||||
#define ACPI_COMPANION(dev) (NULL)
|
||||
#define ACPI_COMPANION_SET(dev, adev) do { } while (0)
|
||||
#define ACPI_HANDLE(dev) (NULL)
|
||||
#define ACPI_DEVICE_CLASS(_cls, _msk) .cls = (0), .cls_msk = (0),
|
||||
|
||||
struct fwnode_handle;
|
||||
|
||||
|
@ -189,6 +189,8 @@ struct css_device_id {
|
||||
struct acpi_device_id {
|
||||
__u8 id[ACPI_ID_LEN];
|
||||
kernel_ulong_t driver_data;
|
||||
__u32 cls;
|
||||
__u32 cls_msk;
|
||||
};
|
||||
|
||||
#define PNP_ID_LEN 8
|
||||
|
@ -63,6 +63,8 @@ int main(void)
|
||||
|
||||
DEVID(acpi_device_id);
|
||||
DEVID_FIELD(acpi_device_id, id);
|
||||
DEVID_FIELD(acpi_device_id, cls);
|
||||
DEVID_FIELD(acpi_device_id, cls_msk);
|
||||
|
||||
DEVID(pnp_device_id);
|
||||
DEVID_FIELD(pnp_device_id, id);
|
||||
|
@ -523,12 +523,40 @@ static int do_serio_entry(const char *filename,
|
||||
}
|
||||
ADD_TO_DEVTABLE("serio", serio_device_id, do_serio_entry);
|
||||
|
||||
/* looks like: "acpi:ACPI0003 or acpi:PNP0C0B" or "acpi:LNXVIDEO" */
|
||||
/* looks like: "acpi:ACPI0003" or "acpi:PNP0C0B" or "acpi:LNXVIDEO" or
|
||||
* "acpi:bbsspp" (bb=base-class, ss=sub-class, pp=prog-if)
|
||||
*
|
||||
* NOTE: Each driver should use one of the following : _HID, _CIDs
|
||||
* or _CLS. Also, bb, ss, and pp can be substituted with ??
|
||||
* as don't care byte.
|
||||
*/
|
||||
static int do_acpi_entry(const char *filename,
|
||||
void *symval, char *alias)
|
||||
{
|
||||
DEF_FIELD_ADDR(symval, acpi_device_id, id);
|
||||
sprintf(alias, "acpi*:%s:*", *id);
|
||||
DEF_FIELD_ADDR(symval, acpi_device_id, cls);
|
||||
DEF_FIELD_ADDR(symval, acpi_device_id, cls_msk);
|
||||
|
||||
if (id && strlen((const char *)*id))
|
||||
sprintf(alias, "acpi*:%s:*", *id);
|
||||
else if (cls) {
|
||||
int i, byte_shift, cnt = 0;
|
||||
unsigned int msk;
|
||||
|
||||
sprintf(&alias[cnt], "acpi*:");
|
||||
cnt = 6;
|
||||
for (i = 1; i <= 3; i++) {
|
||||
byte_shift = 8 * (3-i);
|
||||
msk = (*cls_msk >> byte_shift) & 0xFF;
|
||||
if (msk)
|
||||
sprintf(&alias[cnt], "%02x",
|
||||
(*cls >> byte_shift) & 0xFF);
|
||||
else
|
||||
sprintf(&alias[cnt], "??");
|
||||
cnt += 2;
|
||||
}
|
||||
sprintf(&alias[cnt], ":*");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
ADD_TO_DEVTABLE("acpi", acpi_device_id, do_acpi_entry);
|
||||
|
Loading…
Reference in New Issue
Block a user