ACPI fix for v4.12-rc7

- I2C and SPI devices are expected to be enumerated by the
    I2C and SPI subsystems, respectively, but due to a change made
    during the 4.11 cycle, in some cases the ACPI core marks them
    as already enumerated which causes the I2C and SPI subsystems
    to overlook them, so fix that (Jarkko Nikula).
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2
 
 iQIcBAABCAAGBQJZTRdgAAoJEILEb/54YlRx+IgP/17SwIqNGDJMl6t/R+dRtLTv
 JWGzp967HLo0UchZUQpIvYT6CTPWytSV4hHxoCFSKSYLmQ8XI/qpu1fNysjsf0lK
 PZp6H/qsTRyh9MRbadEhJKYLvb7SVgSLRsht8ts5kiqc1TfgdfT8b/VJF0ggQ4+O
 z/QM3yMlnEIkAds23SdRbiy+Y0W45XTvPYHq9H03HIL809DvuQ5MdPTC9Cyr/PI9
 KyhGs8zx3ZOuWmuRVmGJvWqw40WMa2ZhUGXbQGYTaVHzcIIeiv345WQn6luWsYPL
 ln52ifM+T7wbNsmvCH4MtkW8Ix5yDJNkDM3x2gwkF07egJpYYOa7q/02sPmHz+2Z
 daQbh6mKb861a75UiEcZmF1DL4sCpcwGAvKv9ERvrWBsYX6y14K84SLas2j0lKO/
 9SzDhKKLVV46u/rmM0qz+9n6tEDoo1Hi7460FToucLEJpjc4aqsE8kUSjshlO+QX
 mqdlrHKlWfAq52Ccno7Sn2FhGJG+p9CoQk+BE9rExIoBMlLrtw+fe/oPiHVvTzs8
 TP7U5ioHyfdL9sRLfkKXHF21zAwpxvh7EVPED5LK3GwNZ0QjVryN5HAlnwGrDnUe
 zL32+hLEpRW5hPmsZOHjSzhZ4o7ihZwpcCTy62uG4zZVf+qLpIM0Xd0dFC1CpZTm
 F5/BD8Gj5Dl5n4SO7VM4
 =ORkn
 -----END PGP SIGNATURE-----

Merge tag 'acpi-4.12-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull ACPI fix from Rafael Wysocki:
 "This fixes the ACPI-based enumeration of some I2C and SPI devices
  broken in 4.11.

  Specifics:

   - I2C and SPI devices are expected to be enumerated by the I2C and
     SPI subsystems, respectively, but due to a change made during the
     4.11 cycle, in some cases the ACPI core marks them as already
     enumerated which causes the I2C and SPI subsystems to overlook
     them, so fix that (Jarkko Nikula)"

* tag 'acpi-4.12-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  ACPI / scan: Fix enumeration for special SPI and I2C devices
This commit is contained in:
Linus Torvalds 2017-06-23 17:49:12 -07:00
commit cd5545ae87
2 changed files with 39 additions and 31 deletions

View File

@ -1428,6 +1428,37 @@ static void acpi_init_coherency(struct acpi_device *adev)
adev->flags.coherent_dma = cca;
}
static int acpi_check_spi_i2c_slave(struct acpi_resource *ares, void *data)
{
bool *is_spi_i2c_slave_p = data;
if (ares->type != ACPI_RESOURCE_TYPE_SERIAL_BUS)
return 1;
/*
* devices that are connected to UART still need to be enumerated to
* platform bus
*/
if (ares->data.common_serial_bus.type != ACPI_RESOURCE_SERIAL_TYPE_UART)
*is_spi_i2c_slave_p = true;
/* no need to do more checking */
return -1;
}
static bool acpi_is_spi_i2c_slave(struct acpi_device *device)
{
struct list_head resource_list;
bool is_spi_i2c_slave = false;
INIT_LIST_HEAD(&resource_list);
acpi_dev_get_resources(device, &resource_list, acpi_check_spi_i2c_slave,
&is_spi_i2c_slave);
acpi_dev_free_resource_list(&resource_list);
return is_spi_i2c_slave;
}
void acpi_init_device_object(struct acpi_device *device, acpi_handle handle,
int type, unsigned long long sta)
{
@ -1443,6 +1474,7 @@ void acpi_init_device_object(struct acpi_device *device, acpi_handle handle,
acpi_bus_get_flags(device);
device->flags.match_driver = false;
device->flags.initialized = true;
device->flags.spi_i2c_slave = acpi_is_spi_i2c_slave(device);
acpi_device_clear_enumerated(device);
device_initialize(&device->dev);
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,
return AE_OK;
}
static int acpi_check_spi_i2c_slave(struct acpi_resource *ares, void *data)
{
bool *is_spi_i2c_slave_p = data;
if (ares->type != ACPI_RESOURCE_TYPE_SERIAL_BUS)
return 1;
/*
* devices that are connected to UART still need to be enumerated to
* platform bus
*/
if (ares->data.common_serial_bus.type != ACPI_RESOURCE_SERIAL_TYPE_UART)
*is_spi_i2c_slave_p = true;
/* no need to do more checking */
return -1;
}
static void acpi_default_enumeration(struct acpi_device *device)
{
struct list_head resource_list;
bool is_spi_i2c_slave = false;
/*
* Do not enumerate SPI/I2C slaves as they will be enumerated by their
* respective parents.
*/
INIT_LIST_HEAD(&resource_list);
acpi_dev_get_resources(device, &resource_list, acpi_check_spi_i2c_slave,
&is_spi_i2c_slave);
acpi_dev_free_resource_list(&resource_list);
if (!is_spi_i2c_slave) {
if (!device->flags.spi_i2c_slave) {
acpi_create_platform_device(device, NULL);
acpi_device_set_enumerated(device);
} else {
@ -1854,7 +1861,7 @@ static void acpi_bus_attach(struct acpi_device *device)
return;
device->flags.match_driver = true;
if (ret > 0) {
if (ret > 0 && !device->flags.spi_i2c_slave) {
acpi_device_set_enumerated(device);
goto ok;
}
@ -1863,10 +1870,10 @@ static void acpi_bus_attach(struct acpi_device *device)
if (ret < 0)
return;
if (device->pnp.type.platform_id)
acpi_default_enumeration(device);
else
if (!device->pnp.type.platform_id && !device->flags.spi_i2c_slave)
acpi_device_set_enumerated(device);
else
acpi_default_enumeration(device);
ok:
list_for_each_entry(child, &device->children, node)

View File

@ -210,7 +210,8 @@ struct acpi_device_flags {
u32 of_compatible_ok:1;
u32 coherent_dma:1;
u32 cca_seen:1;
u32 reserved:20;
u32 spi_i2c_slave:1;
u32 reserved:19;
};
/* File System */