Skip to content

Commit cefbd80

Browse files
andy-shevrafaeljw
authored andcommitted
ACPI: platform: Ignore SMB0001 only when it has resources
After switching i2c-scmi driver to be a platform one, it stopped being enumerated on number of Kontron platforms, because it's listed in the forbidden_id_list. To resolve the situation, add a flag to driver data to allow devices with no resources in _CRS to be enumerated via platform bus. Fixes: 03d4287 ("i2c: scmi: Convert to be a platform driver") Closes: https://lore.kernel.org/r/[email protected] Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Andy Shevchenko <[email protected]> Reviewed-by: Andi Shyti <[email protected]> [ rjw: Move has_resource definition to the block in which it is used and initialize it to 'false' ] Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent 2b5ae96 commit cefbd80

File tree

1 file changed

+28
-3
lines changed

1 file changed

+28
-3
lines changed

drivers/acpi/acpi_platform.c

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
*/
1010

1111
#include <linux/acpi.h>
12+
#include <linux/bits.h>
1213
#include <linux/device.h>
1314
#include <linux/err.h>
1415
#include <linux/kernel.h>
@@ -19,13 +20,16 @@
1920

2021
#include "internal.h"
2122

23+
/* Exclude devices that have no _CRS resources provided */
24+
#define ACPI_ALLOW_WO_RESOURCES BIT(0)
25+
2226
static const struct acpi_device_id forbidden_id_list[] = {
2327
{"ACPI0009", 0}, /* IOxAPIC */
2428
{"ACPI000A", 0}, /* IOAPIC */
2529
{"PNP0000", 0}, /* PIC */
2630
{"PNP0100", 0}, /* Timer */
2731
{"PNP0200", 0}, /* AT DMA Controller */
28-
{"SMB0001", 0}, /* ACPI SMBUS virtual device */
32+
{"SMB0001", ACPI_ALLOW_WO_RESOURCES}, /* ACPI SMBUS virtual device */
2933
{ }
3034
};
3135

@@ -83,6 +87,15 @@ static void acpi_platform_fill_resource(struct acpi_device *adev,
8387
dest->parent = pci_find_resource(to_pci_dev(parent), dest);
8488
}
8589

90+
static unsigned int acpi_platform_resource_count(struct acpi_resource *ares, void *data)
91+
{
92+
bool *has_resources = data;
93+
94+
*has_resources = true;
95+
96+
return AE_CTRL_TERMINATE;
97+
}
98+
8699
/**
87100
* acpi_create_platform_device - Create platform device for ACPI device node
88101
* @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,
100113
struct acpi_device *parent = acpi_dev_parent(adev);
101114
struct platform_device *pdev = NULL;
102115
struct platform_device_info pdevinfo;
116+
const struct acpi_device_id *match;
103117
struct resource_entry *rentry;
104118
struct list_head resource_list;
105119
struct resource *resources = NULL;
@@ -109,8 +123,19 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev,
109123
if (adev->physical_node_count)
110124
return NULL;
111125

112-
if (!acpi_match_device_ids(adev, forbidden_id_list))
113-
return ERR_PTR(-EINVAL);
126+
match = acpi_match_acpi_device(forbidden_id_list, adev);
127+
if (match) {
128+
if (match->driver_data & ACPI_ALLOW_WO_RESOURCES) {
129+
bool has_resources = false;
130+
131+
acpi_walk_resources(adev->handle, METHOD_NAME__CRS,
132+
acpi_platform_resource_count, &has_resources);
133+
if (has_resources)
134+
return ERR_PTR(-EINVAL);
135+
} else {
136+
return ERR_PTR(-EINVAL);
137+
}
138+
}
114139

115140
INIT_LIST_HEAD(&resource_list);
116141
count = acpi_dev_get_resources(adev, &resource_list, NULL, NULL);

0 commit comments

Comments
 (0)