Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.9-rc8 103 lines 2.7 kB view raw
1/* 2 * ACPI I2C enumeration support 3 * 4 * Copyright (C) 2012, Intel Corporation 5 * Author: Mika Westerberg <mika.westerberg@linux.intel.com> 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as 9 * published by the Free Software Foundation. 10 */ 11 12#include <linux/acpi.h> 13#include <linux/device.h> 14#include <linux/export.h> 15#include <linux/i2c.h> 16#include <linux/ioport.h> 17 18ACPI_MODULE_NAME("i2c"); 19 20static int acpi_i2c_add_resource(struct acpi_resource *ares, void *data) 21{ 22 struct i2c_board_info *info = data; 23 24 if (ares->type == ACPI_RESOURCE_TYPE_SERIAL_BUS) { 25 struct acpi_resource_i2c_serialbus *sb; 26 27 sb = &ares->data.i2c_serial_bus; 28 if (sb->type == ACPI_RESOURCE_SERIAL_TYPE_I2C) { 29 info->addr = sb->slave_address; 30 if (sb->access_mode == ACPI_I2C_10BIT_MODE) 31 info->flags |= I2C_CLIENT_TEN; 32 } 33 } else if (info->irq < 0) { 34 struct resource r; 35 36 if (acpi_dev_resource_interrupt(ares, 0, &r)) 37 info->irq = r.start; 38 } 39 40 /* Tell the ACPI core to skip this resource */ 41 return 1; 42} 43 44static acpi_status acpi_i2c_add_device(acpi_handle handle, u32 level, 45 void *data, void **return_value) 46{ 47 struct i2c_adapter *adapter = data; 48 struct list_head resource_list; 49 struct i2c_board_info info; 50 struct acpi_device *adev; 51 int ret; 52 53 if (acpi_bus_get_device(handle, &adev)) 54 return AE_OK; 55 if (acpi_bus_get_status(adev) || !adev->status.present) 56 return AE_OK; 57 58 memset(&info, 0, sizeof(info)); 59 info.acpi_node.handle = handle; 60 info.irq = -1; 61 62 INIT_LIST_HEAD(&resource_list); 63 ret = acpi_dev_get_resources(adev, &resource_list, 64 acpi_i2c_add_resource, &info); 65 acpi_dev_free_resource_list(&resource_list); 66 67 if (ret < 0 || !info.addr) 68 return AE_OK; 69 70 strlcpy(info.type, dev_name(&adev->dev), sizeof(info.type)); 71 if (!i2c_new_device(adapter, &info)) { 72 dev_err(&adapter->dev, 73 "failed to add I2C device %s from ACPI\n", 74 dev_name(&adev->dev)); 75 } 76 77 return AE_OK; 78} 79 80/** 81 * acpi_i2c_register_devices - enumerate I2C slave devices behind adapter 82 * @adapter: pointer to adapter 83 * 84 * Enumerate all I2C slave devices behind this adapter by walking the ACPI 85 * namespace. When a device is found it will be added to the Linux device 86 * model and bound to the corresponding ACPI handle. 87 */ 88void acpi_i2c_register_devices(struct i2c_adapter *adapter) 89{ 90 acpi_handle handle; 91 acpi_status status; 92 93 handle = ACPI_HANDLE(adapter->dev.parent); 94 if (!handle) 95 return; 96 97 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1, 98 acpi_i2c_add_device, NULL, 99 adapter, NULL); 100 if (ACPI_FAILURE(status)) 101 dev_warn(&adapter->dev, "failed to enumerate I2C slaves\n"); 102} 103EXPORT_SYMBOL_GPL(acpi_i2c_register_devices);