Merge branch 'i2c/for-4.4' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux
Pull i2c updates from Wolfram Sang: - New drivers: UniPhier (with and without FIFO) - some drivers got some bigger rework: ismt, designware, img-scb (rcar had to be reverted because issues were showing up just lately) - ACPI: reworked the device scanning and added support for muxes ... and quite a lot of driver bugfixes and cleanups this time. All files touched outside of the i2c realm have proper acks. * 'i2c/for-4.4' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: (70 commits) i2c: rcar: Revert the latest refactoring series i2c: pnx: remove superfluous assignment MAINTAINERS: i2c: drop i2c-pnx maintainer MAINTAINERS: i2c: mark also subdirectories as maintained i2c: cadence: enable driver for ARM64 i2c: i801: Document Intel DNV and Broxton i2c: at91: manage unexpected RXRDY flag when starting a transfer i2c: pnx: Use setup_timer instead of open coding it i2c: add ACPI support for I2C mux ports acpi: add acpi_preset_companion() stub i2c: pxa: Add support for pxa910/988 & new configuration features i2c: au1550: Convert to devm_kzalloc and devm_ioremap_resource i2c-dev: Fix I2C_SLAVE ioctl comment i2c-dev: Fix typo in ioctl name reference i2c: sirf: tune the divider to make i2c bus freq more accurate i2c: imx: Use -ENXIO as error in the NACK case i2c: i801: Add support for Intel Broxton i2c: i801: Add support for Intel DNV i2c: mediatek: add i2c resume support i2c: imx: implement bus recovery ...
This commit is contained in:
@@ -99,27 +99,40 @@ struct gsb_buffer {
|
||||
};
|
||||
} __packed;
|
||||
|
||||
static int acpi_i2c_add_resource(struct acpi_resource *ares, void *data)
|
||||
struct acpi_i2c_lookup {
|
||||
struct i2c_board_info *info;
|
||||
acpi_handle adapter_handle;
|
||||
acpi_handle device_handle;
|
||||
};
|
||||
|
||||
static int acpi_i2c_find_address(struct acpi_resource *ares, void *data)
|
||||
{
|
||||
struct i2c_board_info *info = data;
|
||||
struct acpi_i2c_lookup *lookup = data;
|
||||
struct i2c_board_info *info = lookup->info;
|
||||
struct acpi_resource_i2c_serialbus *sb;
|
||||
acpi_handle adapter_handle;
|
||||
acpi_status status;
|
||||
|
||||
if (ares->type == ACPI_RESOURCE_TYPE_SERIAL_BUS) {
|
||||
struct acpi_resource_i2c_serialbus *sb;
|
||||
if (info->addr || ares->type != ACPI_RESOURCE_TYPE_SERIAL_BUS)
|
||||
return 1;
|
||||
|
||||
sb = &ares->data.i2c_serial_bus;
|
||||
if (!info->addr && sb->type == ACPI_RESOURCE_SERIAL_TYPE_I2C) {
|
||||
info->addr = sb->slave_address;
|
||||
if (sb->access_mode == ACPI_I2C_10BIT_MODE)
|
||||
info->flags |= I2C_CLIENT_TEN;
|
||||
}
|
||||
} else if (!info->irq) {
|
||||
struct resource r;
|
||||
sb = &ares->data.i2c_serial_bus;
|
||||
if (sb->type != ACPI_RESOURCE_SERIAL_TYPE_I2C)
|
||||
return 1;
|
||||
|
||||
if (acpi_dev_resource_interrupt(ares, 0, &r))
|
||||
info->irq = r.start;
|
||||
/*
|
||||
* Extract the ResourceSource and make sure that the handle matches
|
||||
* with the I2C adapter handle.
|
||||
*/
|
||||
status = acpi_get_handle(lookup->device_handle,
|
||||
sb->resource_source.string_ptr,
|
||||
&adapter_handle);
|
||||
if (ACPI_SUCCESS(status) && adapter_handle == lookup->adapter_handle) {
|
||||
info->addr = sb->slave_address;
|
||||
if (sb->access_mode == ACPI_I2C_10BIT_MODE)
|
||||
info->flags |= I2C_CLIENT_TEN;
|
||||
}
|
||||
|
||||
/* Tell the ACPI core to skip this resource */
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -128,6 +141,8 @@ static acpi_status acpi_i2c_add_device(acpi_handle handle, u32 level,
|
||||
{
|
||||
struct i2c_adapter *adapter = data;
|
||||
struct list_head resource_list;
|
||||
struct acpi_i2c_lookup lookup;
|
||||
struct resource_entry *entry;
|
||||
struct i2c_board_info info;
|
||||
struct acpi_device *adev;
|
||||
int ret;
|
||||
@@ -140,14 +155,37 @@ static acpi_status acpi_i2c_add_device(acpi_handle handle, u32 level,
|
||||
memset(&info, 0, sizeof(info));
|
||||
info.fwnode = acpi_fwnode_handle(adev);
|
||||
|
||||
memset(&lookup, 0, sizeof(lookup));
|
||||
lookup.adapter_handle = ACPI_HANDLE(&adapter->dev);
|
||||
lookup.device_handle = handle;
|
||||
lookup.info = &info;
|
||||
|
||||
/*
|
||||
* Look up for I2cSerialBus resource with ResourceSource that
|
||||
* matches with this adapter.
|
||||
*/
|
||||
INIT_LIST_HEAD(&resource_list);
|
||||
ret = acpi_dev_get_resources(adev, &resource_list,
|
||||
acpi_i2c_add_resource, &info);
|
||||
acpi_i2c_find_address, &lookup);
|
||||
acpi_dev_free_resource_list(&resource_list);
|
||||
|
||||
if (ret < 0 || !info.addr)
|
||||
return AE_OK;
|
||||
|
||||
/* Then fill IRQ number if any */
|
||||
ret = acpi_dev_get_resources(adev, &resource_list, NULL, NULL);
|
||||
if (ret < 0)
|
||||
return AE_OK;
|
||||
|
||||
resource_list_for_each_entry(entry, &resource_list) {
|
||||
if (resource_type(entry->res) == IORESOURCE_IRQ) {
|
||||
info.irq = entry->res->start;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
acpi_dev_free_resource_list(&resource_list);
|
||||
|
||||
adev->power.flags.ignore_parent = true;
|
||||
strlcpy(info.type, dev_name(&adev->dev), sizeof(info.type));
|
||||
if (!i2c_new_device(adapter, &info)) {
|
||||
@@ -160,6 +198,8 @@ static acpi_status acpi_i2c_add_device(acpi_handle handle, u32 level,
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
#define ACPI_I2C_MAX_SCAN_DEPTH 32
|
||||
|
||||
/**
|
||||
* acpi_i2c_register_devices - enumerate I2C slave devices behind adapter
|
||||
* @adap: pointer to adapter
|
||||
@@ -170,17 +210,13 @@ static acpi_status acpi_i2c_add_device(acpi_handle handle, u32 level,
|
||||
*/
|
||||
static void acpi_i2c_register_devices(struct i2c_adapter *adap)
|
||||
{
|
||||
acpi_handle handle;
|
||||
acpi_status status;
|
||||
|
||||
if (!adap->dev.parent)
|
||||
if (!has_acpi_companion(&adap->dev))
|
||||
return;
|
||||
|
||||
handle = ACPI_HANDLE(adap->dev.parent);
|
||||
if (!handle)
|
||||
return;
|
||||
|
||||
status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
|
||||
status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
|
||||
ACPI_I2C_MAX_SCAN_DEPTH,
|
||||
acpi_i2c_add_device, NULL,
|
||||
adap, NULL);
|
||||
if (ACPI_FAILURE(status))
|
||||
|
Reference in New Issue
Block a user