diff options
-rw-r--r-- | drivers/acpi/scan.c | 67 | ||||
-rw-r--r-- | include/acpi/acpi_bus.h | 3 |
2 files changed, 39 insertions, 31 deletions
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 3a10d7573477..d53162997f32 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -1428,6 +1428,37 @@ static void acpi_init_coherency(struct acpi_device *adev) | |||
1428 | adev->flags.coherent_dma = cca; | 1428 | adev->flags.coherent_dma = cca; |
1429 | } | 1429 | } |
1430 | 1430 | ||
1431 | static int acpi_check_spi_i2c_slave(struct acpi_resource *ares, void *data) | ||
1432 | { | ||
1433 | bool *is_spi_i2c_slave_p = data; | ||
1434 | |||
1435 | if (ares->type != ACPI_RESOURCE_TYPE_SERIAL_BUS) | ||
1436 | return 1; | ||
1437 | |||
1438 | /* | ||
1439 | * devices that are connected to UART still need to be enumerated to | ||
1440 | * platform bus | ||
1441 | */ | ||
1442 | if (ares->data.common_serial_bus.type != ACPI_RESOURCE_SERIAL_TYPE_UART) | ||
1443 | *is_spi_i2c_slave_p = true; | ||
1444 | |||
1445 | /* no need to do more checking */ | ||
1446 | return -1; | ||
1447 | } | ||
1448 | |||
1449 | static bool acpi_is_spi_i2c_slave(struct acpi_device *device) | ||
1450 | { | ||
1451 | struct list_head resource_list; | ||
1452 | bool is_spi_i2c_slave = false; | ||
1453 | |||
1454 | INIT_LIST_HEAD(&resource_list); | ||
1455 | acpi_dev_get_resources(device, &resource_list, acpi_check_spi_i2c_slave, | ||
1456 | &is_spi_i2c_slave); | ||
1457 | acpi_dev_free_resource_list(&resource_list); | ||
1458 | |||
1459 | return is_spi_i2c_slave; | ||
1460 | } | ||
1461 | |||
1431 | void acpi_init_device_object(struct acpi_device *device, acpi_handle handle, | 1462 | void acpi_init_device_object(struct acpi_device *device, acpi_handle handle, |
1432 | int type, unsigned long long sta) | 1463 | int type, unsigned long long sta) |
1433 | { | 1464 | { |
@@ -1443,6 +1474,7 @@ void acpi_init_device_object(struct acpi_device *device, acpi_handle handle, | |||
1443 | acpi_bus_get_flags(device); | 1474 | acpi_bus_get_flags(device); |
1444 | device->flags.match_driver = false; | 1475 | device->flags.match_driver = false; |
1445 | device->flags.initialized = true; | 1476 | device->flags.initialized = true; |
1477 | device->flags.spi_i2c_slave = acpi_is_spi_i2c_slave(device); | ||
1446 | acpi_device_clear_enumerated(device); | 1478 | acpi_device_clear_enumerated(device); |
1447 | device_initialize(&device->dev); | 1479 | device_initialize(&device->dev); |
1448 | dev_set_uevent_suppress(&device->dev, true); | 1480 | dev_set_uevent_suppress(&device->dev, true); |
@@ -1727,38 +1759,13 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used, | |||
1727 | return AE_OK; | 1759 | return AE_OK; |
1728 | } | 1760 | } |
1729 | 1761 | ||
1730 | static int acpi_check_spi_i2c_slave(struct acpi_resource *ares, void *data) | ||
1731 | { | ||
1732 | bool *is_spi_i2c_slave_p = data; | ||
1733 | |||
1734 | if (ares->type != ACPI_RESOURCE_TYPE_SERIAL_BUS) | ||
1735 | return 1; | ||
1736 | |||
1737 | /* | ||
1738 | * devices that are connected to UART still need to be enumerated to | ||
1739 | * platform bus | ||
1740 | */ | ||
1741 | if (ares->data.common_serial_bus.type != ACPI_RESOURCE_SERIAL_TYPE_UART) | ||
1742 | *is_spi_i2c_slave_p = true; | ||
1743 | |||
1744 | /* no need to do more checking */ | ||
1745 | return -1; | ||
1746 | } | ||
1747 | |||
1748 | static void acpi_default_enumeration(struct acpi_device *device) | 1762 | static void acpi_default_enumeration(struct acpi_device *device) |
1749 | { | 1763 | { |
1750 | struct list_head resource_list; | ||
1751 | bool is_spi_i2c_slave = false; | ||
1752 | |||
1753 | /* | 1764 | /* |
1754 | * Do not enumerate SPI/I2C slaves as they will be enumerated by their | 1765 | * Do not enumerate SPI/I2C slaves as they will be enumerated by their |
1755 | * respective parents. | 1766 | * respective parents. |
1756 | */ | 1767 | */ |
1757 | INIT_LIST_HEAD(&resource_list); | 1768 | if (!device->flags.spi_i2c_slave) { |
1758 | acpi_dev_get_resources(device, &resource_list, acpi_check_spi_i2c_slave, | ||
1759 | &is_spi_i2c_slave); | ||
1760 | acpi_dev_free_resource_list(&resource_list); | ||
1761 | if (!is_spi_i2c_slave) { | ||
1762 | acpi_create_platform_device(device, NULL); | 1769 | acpi_create_platform_device(device, NULL); |
1763 | acpi_device_set_enumerated(device); | 1770 | acpi_device_set_enumerated(device); |
1764 | } else { | 1771 | } else { |
@@ -1854,7 +1861,7 @@ static void acpi_bus_attach(struct acpi_device *device) | |||
1854 | return; | 1861 | return; |
1855 | 1862 | ||
1856 | device->flags.match_driver = true; | 1863 | device->flags.match_driver = true; |
1857 | if (ret > 0) { | 1864 | if (ret > 0 && !device->flags.spi_i2c_slave) { |
1858 | acpi_device_set_enumerated(device); | 1865 | acpi_device_set_enumerated(device); |
1859 | goto ok; | 1866 | goto ok; |
1860 | } | 1867 | } |
@@ -1863,10 +1870,10 @@ static void acpi_bus_attach(struct acpi_device *device) | |||
1863 | if (ret < 0) | 1870 | if (ret < 0) |
1864 | return; | 1871 | return; |
1865 | 1872 | ||
1866 | if (device->pnp.type.platform_id) | 1873 | if (!device->pnp.type.platform_id && !device->flags.spi_i2c_slave) |
1867 | acpi_default_enumeration(device); | ||
1868 | else | ||
1869 | acpi_device_set_enumerated(device); | 1874 | acpi_device_set_enumerated(device); |
1875 | else | ||
1876 | acpi_default_enumeration(device); | ||
1870 | 1877 | ||
1871 | ok: | 1878 | ok: |
1872 | list_for_each_entry(child, &device->children, node) | 1879 | list_for_each_entry(child, &device->children, node) |
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 197f3fffc9a7..408c7820e200 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h | |||
@@ -210,7 +210,8 @@ struct acpi_device_flags { | |||
210 | u32 of_compatible_ok:1; | 210 | u32 of_compatible_ok:1; |
211 | u32 coherent_dma:1; | 211 | u32 coherent_dma:1; |
212 | u32 cca_seen:1; | 212 | u32 cca_seen:1; |
213 | u32 reserved:20; | 213 | u32 spi_i2c_slave:1; |
214 | u32 reserved:19; | ||
214 | }; | 215 | }; |
215 | 216 | ||
216 | /* File System */ | 217 | /* File System */ |