Skip to content

Commit 10c7e20

Browse files
Octavian Purdilarafaeljw
authored andcommitted
ACPI / scan: fix enumeration (visited) flags for bus rescans
If the ACPI tables change as a result of a dinamically loaded table and a bus rescan is required the enumeration/visited flag are not consistent. I2C/SPI are not directly enumerated in acpi_bus_attach(), however the visited flag is set. This makes it impossible to check if an ACPI device has already been enumerated by the I2C and SPI subsystems. To fix this issue we only set the visited flags if the device is not I2C or SPI. With this change we also need to remove setting visited to false from acpi_bus_attach(), otherwise if we rescan already enumerated I2C/SPI devices we try to re-enumerate them. Note that I2C/SPI devices can be enumerated either via a scan handler (when using PRP0001) or via regular device_attach(). In either case the flow goes through acpi_default_enumeration() which makes it the ideal place to mark the ACPI device as enumerated. Signed-off-by: Octavian Purdila <[email protected]> Reviewed-by: Mika Westerberg <[email protected]> Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent 14d24c3 commit 10c7e20

File tree

2 files changed

+25
-6
lines changed

2 files changed

+25
-6
lines changed

drivers/acpi/scan.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1406,7 +1406,7 @@ void acpi_init_device_object(struct acpi_device *device, acpi_handle handle,
14061406
acpi_bus_get_flags(device);
14071407
device->flags.match_driver = false;
14081408
device->flags.initialized = true;
1409-
device->flags.visited = false;
1409+
acpi_device_clear_enumerated(device);
14101410
device_initialize(&device->dev);
14111411
dev_set_uevent_suppress(&device->dev, true);
14121412
acpi_init_coherency(device);
@@ -1683,8 +1683,10 @@ static void acpi_default_enumeration(struct acpi_device *device)
16831683
acpi_dev_get_resources(device, &resource_list, acpi_check_spi_i2c_slave,
16841684
&is_spi_i2c_slave);
16851685
acpi_dev_free_resource_list(&resource_list);
1686-
if (!is_spi_i2c_slave)
1686+
if (!is_spi_i2c_slave) {
16871687
acpi_create_platform_device(device);
1688+
acpi_device_set_enumerated(device);
1689+
}
16881690
}
16891691

16901692
static const struct acpi_device_id generic_device_ids[] = {
@@ -1751,7 +1753,7 @@ static void acpi_bus_attach(struct acpi_device *device)
17511753
acpi_bus_get_status(device);
17521754
/* Skip devices that are not present. */
17531755
if (!acpi_device_is_present(device)) {
1754-
device->flags.visited = false;
1756+
acpi_device_clear_enumerated(device);
17551757
device->flags.power_manageable = 0;
17561758
return;
17571759
}
@@ -1766,7 +1768,7 @@ static void acpi_bus_attach(struct acpi_device *device)
17661768

17671769
device->flags.initialized = true;
17681770
}
1769-
device->flags.visited = false;
1771+
17701772
ret = acpi_scan_attach_handler(device);
17711773
if (ret < 0)
17721774
return;
@@ -1780,7 +1782,6 @@ static void acpi_bus_attach(struct acpi_device *device)
17801782
if (!ret && device->pnp.type.platform_id)
17811783
acpi_default_enumeration(device);
17821784
}
1783-
device->flags.visited = true;
17841785

17851786
ok:
17861787
list_for_each_entry(child, &device->children, node)
@@ -1872,7 +1873,7 @@ void acpi_bus_trim(struct acpi_device *adev)
18721873
*/
18731874
acpi_device_set_power(adev, ACPI_STATE_D3_COLD);
18741875
adev->flags.initialized = false;
1875-
adev->flags.visited = false;
1876+
acpi_device_clear_enumerated(adev);
18761877
}
18771878
EXPORT_SYMBOL_GPL(acpi_bus_trim);
18781879

include/linux/acpi.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,16 @@ void acpi_walk_dep_device_list(acpi_handle handle);
531531
struct platform_device *acpi_create_platform_device(struct acpi_device *);
532532
#define ACPI_PTR(_ptr) (_ptr)
533533

534+
static inline void acpi_device_set_enumerated(struct acpi_device *adev)
535+
{
536+
adev->flags.visited = true;
537+
}
538+
539+
static inline void acpi_device_clear_enumerated(struct acpi_device *adev)
540+
{
541+
adev->flags.visited = false;
542+
}
543+
534544
#else /* !CONFIG_ACPI */
535545

536546
#define acpi_disabled 1
@@ -676,6 +686,14 @@ static inline enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev)
676686

677687
#define ACPI_PTR(_ptr) (NULL)
678688

689+
static inline void acpi_device_set_enumerated(struct acpi_device *adev)
690+
{
691+
}
692+
693+
static inline void acpi_device_clear_enumerated(struct acpi_device *adev)
694+
{
695+
}
696+
679697
#endif /* !CONFIG_ACPI */
680698

681699
#ifdef CONFIG_ACPI

0 commit comments

Comments
 (0)