diff options
Diffstat (limited to 'drivers/i2c/i2c-core.c')
-rw-r--r-- | drivers/i2c/i2c-core.c | 3831 |
1 files changed, 0 insertions, 3831 deletions
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c deleted file mode 100644 index 82576aaccc90..000000000000 --- a/drivers/i2c/i2c-core.c +++ /dev/null @@ -1,3831 +0,0 @@ -/* i2c-core.c - a device driver for the iic-bus interface */ -/* ------------------------------------------------------------------------- */ -/* Copyright (C) 1995-99 Simon G. Vogl - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. */ -/* ------------------------------------------------------------------------- */ - -/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi>. - All SMBus-related things are written by Frodo Looijaard <frodol@dds.nl> - SMBus 2.0 support by Mark Studebaker <mdsxyz123@yahoo.com> and - Jean Delvare <jdelvare@suse.de> - Mux support by Rodolfo Giometti <giometti@enneenne.com> and - Michael Lawnick <michael.lawnick.ext@nsn.com> - OF support is copyright (c) 2008 Jochen Friedrich <jochen@scram.de> - (based on a previous patch from Jon Smirl <jonsmirl@gmail.com>) and - (c) 2013 Wolfram Sang <wsa@the-dreams.de> - I2C ACPI code Copyright (C) 2014 Intel Corp - Author: Lan Tianyu <tianyu.lan@intel.com> - I2C slave support (c) 2014 by Wolfram Sang <wsa@sang-engineering.com> - */ - -#define pr_fmt(fmt) "i2c-core: " fmt - -#include <dt-bindings/i2c/i2c.h> -#include <linux/uaccess.h> -#include <linux/acpi.h> -#include <linux/clk/clk-conf.h> -#include <linux/completion.h> -#include <linux/delay.h> -#include <linux/err.h> -#include <linux/errno.h> -#include <linux/gpio.h> -#include <linux/hardirq.h> -#include <linux/i2c.h> -#include <linux/idr.h> -#include <linux/init.h> -#include <linux/irqflags.h> -#include <linux/jump_label.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/mutex.h> -#include <linux/of_device.h> -#include <linux/of.h> -#include <linux/of_irq.h> -#include <linux/pm_domain.h> -#include <linux/pm_runtime.h> -#include <linux/pm_wakeirq.h> -#include <linux/property.h> -#include <linux/rwsem.h> -#include <linux/slab.h> - -#include "i2c-core.h" - -#define CREATE_TRACE_POINTS -#include <trace/events/i2c.h> - -#define I2C_ADDR_OFFSET_TEN_BIT 0xa000 -#define I2C_ADDR_OFFSET_SLAVE 0x1000 - -#define I2C_ADDR_7BITS_MAX 0x77 -#define I2C_ADDR_7BITS_COUNT (I2C_ADDR_7BITS_MAX + 1) - -/* core_lock protects i2c_adapter_idr, and guarantees - that device detection, deletion of detected devices, and attach_adapter - calls are serialized */ -static DEFINE_MUTEX(core_lock); -static DEFINE_IDR(i2c_adapter_idr); - -static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver); - -static struct static_key i2c_trace_msg = STATIC_KEY_INIT_FALSE; -static bool is_registered; - -int i2c_transfer_trace_reg(void) -{ - static_key_slow_inc(&i2c_trace_msg); - return 0; -} - -void i2c_transfer_trace_unreg(void) -{ - static_key_slow_dec(&i2c_trace_msg); -} - -#if defined(CONFIG_ACPI) -struct i2c_acpi_handler_data { - struct acpi_connection_info info; - struct i2c_adapter *adapter; -}; - -struct gsb_buffer { - u8 status; - u8 len; - union { - u16 wdata; - u8 bdata; - u8 data[0]; - }; -} __packed; - -struct i2c_acpi_lookup { - struct i2c_board_info *info; - acpi_handle adapter_handle; - acpi_handle device_handle; - acpi_handle search_handle; - int n; - int index; - u32 speed; - u32 min_speed; -}; - -static int i2c_acpi_fill_info(struct acpi_resource *ares, void *data) -{ - struct i2c_acpi_lookup *lookup = data; - struct i2c_board_info *info = lookup->info; - struct acpi_resource_i2c_serialbus *sb; - acpi_status status; - - if (info->addr || ares->type != ACPI_RESOURCE_TYPE_SERIAL_BUS) - return 1; - - sb = &ares->data.i2c_serial_bus; - if (sb->type != ACPI_RESOURCE_SERIAL_TYPE_I2C) - return 1; - - if (lookup->index != -1 && lookup->n++ != lookup->index) - return 1; - - status = acpi_get_handle(lookup->device_handle, - sb->resource_source.string_ptr, - &lookup->adapter_handle); - if (!ACPI_SUCCESS(status)) - return 1; - - info->addr = sb->slave_address; - lookup->speed = sb->connection_speed; - if (sb->access_mode == ACPI_I2C_10BIT_MODE) - info->flags |= I2C_CLIENT_TEN; - - return 1; -} - -static int i2c_acpi_do_lookup(struct acpi_device *adev, - struct i2c_acpi_lookup *lookup) -{ - struct i2c_board_info *info = lookup->info; - struct list_head resource_list; - int ret; - - if (acpi_bus_get_status(adev) || !adev->status.present || - acpi_device_enumerated(adev)) - return -EINVAL; - - memset(info, 0, sizeof(*info)); - lookup->device_handle = acpi_device_handle(adev); - - /* Look up for I2cSerialBus resource */ - INIT_LIST_HEAD(&resource_list); - ret = acpi_dev_get_resources(adev, &resource_list, - i2c_acpi_fill_info, lookup); - acpi_dev_free_resource_list(&resource_list); - - if (ret < 0 || !info->addr) - return -EINVAL; - - return 0; -} - -static int i2c_acpi_get_info(struct acpi_device *adev, - struct i2c_board_info *info, - struct i2c_adapter *adapter, - acpi_handle *adapter_handle) -{ - struct list_head resource_list; - struct resource_entry *entry; - struct i2c_acpi_lookup lookup; - int ret; - - memset(&lookup, 0, sizeof(lookup)); - lookup.info = info; - lookup.index = -1; - - ret = i2c_acpi_do_lookup(adev, &lookup); - if (ret) - return ret; - - if (adapter) { - /* The adapter must match the one in I2cSerialBus() connector */ - if (ACPI_HANDLE(&adapter->dev) != lookup.adapter_handle) - return -ENODEV; - } else { - struct acpi_device *adapter_adev; - - /* The adapter must be present */ - if (acpi_bus_get_device(lookup.adapter_handle, &adapter_adev)) - return -ENODEV; - if (acpi_bus_get_status(adapter_adev) || - !adapter_adev->status.present) - return -ENODEV; - } - - info->fwnode = acpi_fwnode_handle(adev); - if (adapter_handle) - *adapter_handle = lookup.adapter_handle; - - /* Then fill IRQ number if any */ - INIT_LIST_HEAD(&resource_list); - ret = acpi_dev_get_resources(adev, &resource_list, NULL, NULL); - if (ret < 0) - return -EINVAL; - - 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); - - acpi_set_modalias(adev, dev_name(&adev->dev), info->type, - sizeof(info->type)); - - return 0; -} - -static void i2c_acpi_register_device(struct i2c_adapter *adapter, - struct acpi_device *adev, - struct i2c_board_info *info) -{ - adev->power.flags.ignore_parent = true; - acpi_device_set_enumerated(adev); - - if (!i2c_new_device(adapter, info)) { - adev->power.flags.ignore_parent = false; - dev_err(&adapter->dev, - "failed to add I2C device %s from ACPI\n", - dev_name(&adev->dev)); - } -} - -static acpi_status i2c_acpi_add_device(acpi_handle handle, u32 level, - void *data, void **return_value) -{ - struct i2c_adapter *adapter = data; - struct acpi_device *adev; - struct i2c_board_info info; - - if (acpi_bus_get_device(handle, &adev)) - return AE_OK; - - if (i2c_acpi_get_info(adev, &info, adapter, NULL)) - return AE_OK; - - i2c_acpi_register_device(adapter, adev, &info); - - return AE_OK; -} - -#define I2C_ACPI_MAX_SCAN_DEPTH 32 - -/** - * i2c_acpi_register_devices - enumerate I2C slave devices behind adapter - * @adap: pointer to adapter - * - * Enumerate all I2C slave devices behind this adapter by walking the ACPI - * namespace. When a device is found it will be added to the Linux device - * model and bound to the corresponding ACPI handle. - */ -static void i2c_acpi_register_devices(struct i2c_adapter *adap) -{ - acpi_status status; - - if (!has_acpi_companion(&adap->dev)) - return; - - status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, - I2C_ACPI_MAX_SCAN_DEPTH, - i2c_acpi_add_device, NULL, - adap, NULL); - if (ACPI_FAILURE(status)) - dev_warn(&adap->dev, "failed to enumerate I2C slaves\n"); -} - -static acpi_status i2c_acpi_lookup_speed(acpi_handle handle, u32 level, - void *data, void **return_value) -{ - struct i2c_acpi_lookup *lookup = data; - struct acpi_device *adev; - - if (acpi_bus_get_device(handle, &adev)) - return AE_OK; - - if (i2c_acpi_do_lookup(adev, lookup)) - return AE_OK; - - if (lookup->search_handle != lookup->adapter_handle) - return AE_OK; - - if (lookup->speed <= lookup->min_speed) - lookup->min_speed = lookup->speed; - - return AE_OK; -} - -/** - * i2c_acpi_find_bus_speed - find I2C bus speed from ACPI - * @dev: The device owning the bus - * - * Find the I2C bus speed by walking the ACPI namespace for all I2C slaves - * devices connected to this bus and use the speed of slowest device. - * - * Returns the speed in Hz or zero - */ -u32 i2c_acpi_find_bus_speed(struct device *dev) -{ - struct i2c_acpi_lookup lookup; - struct i2c_board_info dummy; - acpi_status status; - - if (!has_acpi_companion(dev)) - return 0; - - memset(&lookup, 0, sizeof(lookup)); - lookup.search_handle = ACPI_HANDLE(dev); - lookup.min_speed = UINT_MAX; - lookup.info = &dummy; - lookup.index = -1; - - status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, - I2C_ACPI_MAX_SCAN_DEPTH, - i2c_acpi_lookup_speed, NULL, - &lookup, NULL); - - if (ACPI_FAILURE(status)) { - dev_warn(dev, "unable to find I2C bus speed from ACPI\n"); - return 0; - } - - return lookup.min_speed != UINT_MAX ? lookup.min_speed : 0; -} -EXPORT_SYMBOL_GPL(i2c_acpi_find_bus_speed); - -static int i2c_acpi_match_adapter(struct device *dev, void *data) -{ - struct i2c_adapter *adapter = i2c_verify_adapter(dev); - - if (!adapter) - return 0; - - return ACPI_HANDLE(dev) == (acpi_handle)data; -} - -static int i2c_acpi_match_device(struct device *dev, void *data) -{ - return ACPI_COMPANION(dev) == data; -} - -static struct i2c_adapter *i2c_acpi_find_adapter_by_handle(acpi_handle handle) -{ - struct device *dev; - - dev = bus_find_device(&i2c_bus_type, NULL, handle, - i2c_acpi_match_adapter); - return dev ? i2c_verify_adapter(dev) : NULL; -} - -static struct i2c_client *i2c_acpi_find_client_by_adev(struct acpi_device *adev) -{ - struct device *dev; - - dev = bus_find_device(&i2c_bus_type, NULL, adev, i2c_acpi_match_device); - return dev ? i2c_verify_client(dev) : NULL; -} - -static int i2c_acpi_notify(struct notifier_block *nb, unsigned long value, - void *arg) -{ - struct acpi_device *adev = arg; - struct i2c_board_info info; - acpi_handle adapter_handle; - struct i2c_adapter *adapter; - struct i2c_client *client; - - switch (value) { - case ACPI_RECONFIG_DEVICE_ADD: - if (i2c_acpi_get_info(adev, &info, NULL, &adapter_handle)) - break; - - adapter = i2c_acpi_find_adapter_by_handle(adapter_handle); - if (!adapter) - break; - - i2c_acpi_register_device(adapter, adev, &info); - break; - case ACPI_RECONFIG_DEVICE_REMOVE: - if (!acpi_device_enumerated(adev)) - break; - - client = i2c_acpi_find_client_by_adev(adev); - if (!client) - break; - - i2c_unregister_device(client); - put_device(&client->dev); - break; - } - - return NOTIFY_OK; -} - -static struct notifier_block i2c_acpi_notifier = { - .notifier_call = i2c_acpi_notify, -}; - -/** - * i2c_acpi_new_device - Create i2c-client for the Nth I2cSerialBus resource - * @dev: Device owning the ACPI resources to get the client from - * @index: Index of ACPI resource to get - * @info: describes the I2C device; note this is modified (addr gets set) - * Context: can sleep - * - * By default the i2c subsys creates an i2c-client for the first I2cSerialBus - * resource of an acpi_device, but some acpi_devices have multiple I2cSerialBus - * resources, in that case this function can be used to create an i2c-client - * for other I2cSerialBus resources in the Current Resource Settings table. - * - * Also see i2c_new_device, which this function calls to create the i2c-client. - * - * Returns a pointer to the new i2c-client, or NULL if the adapter is not found. - */ -struct i2c_client *i2c_acpi_new_device(struct device *dev, int index, - struct i2c_board_info *info) -{ - struct i2c_acpi_lookup lookup; - struct i2c_adapter *adapter; - struct acpi_device *adev; - LIST_HEAD(resource_list); - int ret; - - adev = ACPI_COMPANION(dev); - if (!adev) - return NULL; - - memset(&lookup, 0, sizeof(lookup)); - lookup.info = info; - lookup.device_handle = acpi_device_handle(adev); - lookup.index = index; - - ret = acpi_dev_get_resources(adev, &resource_list, - i2c_acpi_fill_info, &lookup); - acpi_dev_free_resource_list(&resource_list); - - if (ret < 0 || !info->addr) - return NULL; - - adapter = i2c_acpi_find_adapter_by_handle(lookup.adapter_handle); - if (!adapter) - return NULL; - - return i2c_new_device(adapter, info); -} -EXPORT_SYMBOL_GPL(i2c_acpi_new_device); -#else /* CONFIG_ACPI */ -static inline void i2c_acpi_register_devices(struct i2c_adapter *adap) { } -extern struct notifier_block i2c_acpi_notifier; -#endif /* CONFIG_ACPI */ - -#ifdef CONFIG_ACPI_I2C_OPREGION -static int acpi_gsb_i2c_read_bytes(struct i2c_client *client, - u8 cmd, u8 *data, u8 data_len) -{ - - struct i2c_msg msgs[2]; - int ret; - u8 *buffer; - - buffer = kzalloc(data_len, GFP_KERNEL); - if (!buffer) - return AE_NO_MEMORY; - - msgs[0].addr = client->addr; - msgs[0].flags = client->flags; - msgs[0].len = 1; - msgs[0].buf = &cmd; - - msgs[1].addr = client->addr; - msgs[1].flags = client->flags | I2C_M_RD; - msgs[1].len = data_len; - msgs[1].buf = buffer; - - ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); - if (ret < 0) - dev_err(&client->adapter->dev, "i2c read failed\n"); - else - memcpy(data, buffer, data_len); - - kfree(buffer); - return ret; -} - -static int acpi_gsb_i2c_write_bytes(struct i2c_client *client, - u8 cmd, u8 *data, u8 data_len) -{ - - struct i2c_msg msgs[1]; - u8 *buffer; - int ret = AE_OK; - - buffer = kzalloc(data_len + 1, GFP_KERNEL); - if (!buffer) - return AE_NO_MEMORY; - - buffer[0] = cmd; - memcpy(buffer + 1, data, data_len); - - msgs[0].addr = client->addr; - msgs[0].flags = client->flags; - msgs[0].len = data_len + 1; - msgs[0].buf = buffer; - - ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); - if (ret < 0) - dev_err(&client->adapter->dev, "i2c write failed\n"); - - kfree(buffer); - return ret; -} - -static acpi_status -i2c_acpi_space_handler(u32 function, acpi_physical_address command, - u32 bits, u64 *value64, - void *handler_context, void *region_context) -{ - struct gsb_buffer *gsb = (struct gsb_buffer *)value64; - struct i2c_acpi_handler_data *data = handler_context; - struct acpi_connection_info *info = &data->info; - struct acpi_resource_i2c_serialbus *sb; - struct i2c_adapter *adapter = data->adapter; - struct i2c_client *client; - struct acpi_resource *ares; - u32 accessor_type = function >> 16; - u8 action = function & ACPI_IO_MASK; - acpi_status ret; - int status; - - ret = acpi_buffer_to_resource(info->connection, info->length, &ares); - if (ACPI_FAILURE(ret)) - return ret; - - client = kzalloc(sizeof(*client), GFP_KERNEL); - if (!client) { - ret = AE_NO_MEMORY; - goto err; - } - - if (!value64 || ares->type != ACPI_RESOURCE_TYPE_SERIAL_BUS) { - ret = AE_BAD_PARAMETER; - goto err; - } - - sb = &ares->data.i2c_serial_bus; - if (sb->type != ACPI_RESOURCE_SERIAL_TYPE_I2C) { - ret = AE_BAD_PARAMETER; - goto err; - } - - client->adapter = adapter; - client->addr = sb->slave_address; - - if (sb->access_mode == ACPI_I2C_10BIT_MODE) - client->flags |= I2C_CLIENT_TEN; - - switch (accessor_type) { - case ACPI_GSB_ACCESS_ATTRIB_SEND_RCV: - if (action == ACPI_READ) { - status = i2c_smbus_read_byte(client); - if (status >= 0) { - gsb->bdata = status; - status = 0; - } - } else { - status = i2c_smbus_write_byte(client, gsb->bdata); - } - break; - - case ACPI_GSB_ACCESS_ATTRIB_BYTE: - if (action == ACPI_READ) { - status = i2c_smbus_read_byte_data(client, command); - if (status >= 0) { - gsb->bdata = status; - status = 0; - } - } else { - status = i2c_smbus_write_byte_data(client, command, - gsb->bdata); - } - break; - - case ACPI_GSB_ACCESS_ATTRIB_WORD: - if (action == ACPI_READ) { - status = i2c_smbus_read_word_data(client, command); - if (status >= 0) { - gsb->wdata = status; - status = 0; - } - } else { - status = i2c_smbus_write_word_data(client, command, - gsb->wdata); - } - break; - - case ACPI_GSB_ACCESS_ATTRIB_BLOCK: - if (action == ACPI_READ) { - status = i2c_smbus_read_block_data(client, command, - gsb->data); - if (status >= 0) { - gsb->len = status; - status = 0; - } - } else { - status = i2c_smbus_write_block_data(client, command, - gsb->len, gsb->data); - } - break; - - case ACPI_GSB_ACCESS_ATTRIB_MULTIBYTE: - if (action == ACPI_READ) { - status = acpi_gsb_i2c_read_bytes(client, command, - gsb->data, info->access_length); - if (status > 0) - status = 0; - } else { - status = acpi_gsb_i2c_write_bytes(client, command, - gsb->data, info->access_length); - } - break; - - default: - dev_warn(&adapter->dev, "protocol 0x%02x not supported for client 0x%02x\n", - accessor_type, client->addr); - ret = AE_BAD_PARAMETER; - goto err; - } - - gsb->status = status; - - err: - kfree(client); - ACPI_FREE(ares); - return ret; -} - - -static int i2c_acpi_install_space_handler(struct i2c_adapter *adapter) -{ - acpi_handle handle; - struct i2c_acpi_handler_data *data; - acpi_status status; - - if (!adapter->dev.parent) - return -ENODEV; - - handle = ACPI_HANDLE(adapter->dev.parent); - - if (!handle) - return -ENODEV; - - data = kzalloc(sizeof(struct i2c_acpi_handler_data), - GFP_KERNEL); - if (!data) - return -ENOMEM; - - data->adapter = adapter; - status = acpi_bus_attach_private_data(handle, (void *)data); - if (ACPI_FAILURE(status)) { - kfree(data); - return -ENOMEM; - } - - status = acpi_install_address_space_handler(handle, - ACPI_ADR_SPACE_GSBUS, - &i2c_acpi_space_handler, - NULL, - data); - if (ACPI_FAILURE(status)) { - dev_err(&adapter->dev, "Error installing i2c space handler\n"); - acpi_bus_detach_private_data(handle); - kfree(data); - return -ENOMEM; - } - - acpi_walk_dep_device_list(handle); - return 0; -} - -static void i2c_acpi_remove_space_handler(struct i2c_adapter *adapter) -{ - acpi_handle handle; - struct i2c_acpi_handler_data *data; - acpi_status status; - - if (!adapter->dev.parent) - return; - - handle = ACPI_HANDLE(adapter->dev.parent); - - if (!handle) - return; - - acpi_remove_address_space_handler(handle, - ACPI_ADR_SPACE_GSBUS, - &i2c_acpi_space_handler); - - status = acpi_bus_get_private_data(handle, (void **)&data); - if (ACPI_SUCCESS(status)) - kfree(data); - - acpi_bus_detach_private_data(handle); -} -#else /* CONFIG_ACPI_I2C_OPREGION */ -static inline void i2c_acpi_remove_space_handler(struct i2c_adapter *adapter) -{ } - -static inline int i2c_acpi_install_space_handler(struct i2c_adapter *adapter) -{ return 0; } -#endif /* CONFIG_ACPI_I2C_OPREGION */ - -/* ------------------------------------------------------------------------- */ - -const struct i2c_device_id *i2c_match_id(const struct i2c_device_id *id, - const struct i2c_client *client) -{ - if (!(id && client)) - return NULL; - - while (id->name[0]) { - if (strcmp(client->name, id->name) == 0) - return id; - id++; - } - return NULL; -} -EXPORT_SYMBOL_GPL(i2c_match_id); - -static int i2c_device_match(struct device *dev, struct device_driver *drv) -{ - struct i2c_client *client = i2c_verify_client(dev); - struct i2c_driver *driver; - - - /* Attempt an OF style match */ - if (i2c_of_match_device(drv->of_match_table, client)) - return 1; - - /* Then ACPI style match */ - if (acpi_driver_match_device(dev, drv)) - return 1; - - driver = to_i2c_driver(drv); - - /* Finally an I2C match */ - if (i2c_match_id(driver->id_table, client)) - return 1; - - return 0; -} - -static int i2c_device_uevent(struct device *dev, struct kobj_uevent_env *env) -{ - struct i2c_client *client = to_i2c_client(dev); - int rc; - - rc = acpi_device_uevent_modalias(dev, env); - if (rc != -ENODEV) - return rc; - - return add_uevent_var(env, "MODALIAS=%s%s", I2C_MODULE_PREFIX, client->name); -} - -/* i2c bus recovery routines */ -static int get_scl_gpio_value(struct i2c_adapter *adap) -{ - return gpio_get_value(adap->bus_recovery_info->scl_gpio); -} - -static void set_scl_gpio_value(struct i2c_adapter *adap, int val) -{ - gpio_set_value(adap->bus_recovery_info->scl_gpio, val); -} - -static int get_sda_gpio_value(struct i2c_adapter *adap) -{ - return gpio_get_value(adap->bus_recovery_info->sda_gpio); -} - -static int i2c_get_gpios_for_recovery(struct i2c_adapter *adap) -{ - struct i2c_bus_recovery_info *bri = adap->bus_recovery_info; - struct device *dev = &adap->dev; - int ret = 0; - - ret = gpio_request_one(bri->scl_gpio, GPIOF_OPEN_DRAIN | - GPIOF_OUT_INIT_HIGH, "i2c-scl"); - if (ret) { - dev_warn(dev, "Can't get SCL gpio: %d\n", bri->scl_gpio); - return ret; - } - - if (bri->get_sda) { - if (gpio_request_one(bri->sda_gpio, GPIOF_IN, "i2c-sda")) { - /* work without SDA polling */ - dev_warn(dev, "Can't get SDA gpio: %d. Not using SDA polling\n", - bri->sda_gpio); - bri->get_sda = NULL; - } - } - - return ret; -} - -static void i2c_put_gpios_for_recovery(struct i2c_adapter *adap) -{ - struct i2c_bus_recovery_info *bri = adap->bus_recovery_info; - - if (bri->get_sda) - gpio_free(bri->sda_gpio); - - gpio_free(bri->scl_gpio); -} - -/* - * We are generating clock pulses. ndelay() determines durating of clk pulses. - * We will generate clock with rate 100 KHz and so duration of both clock levels - * is: delay in ns = (10^6 / 100) / 2 - */ -#define RECOVERY_NDELAY 5000 -#define RECOVERY_CLK_CNT 9 - -static int i2c_generic_recovery(struct i2c_adapter *adap) -{ - struct i2c_bus_recovery_info *bri = adap->bus_recovery_info; - int i = 0, val = 1, ret = 0; - - if (bri->prepare_recovery) - bri->prepare_recovery(adap); - - bri->set_scl(adap, val); - ndelay(RECOVERY_NDELAY); - - /* - * By this time SCL is high, as we need to give 9 falling-rising edges - */ - while (i++ < RECOVERY_CLK_CNT * 2) { - if (val) { - /* Break if SDA is high */ - if (bri->get_sda && bri->get_sda(adap)) - break; - /* SCL shouldn't be low here */ - if (!bri->get_scl(adap)) { - dev_err(&adap->dev, - "SCL is stuck low, exit recovery\n"); - ret = -EBUSY; - break; - } - } - - val = !val; - bri->set_scl(adap, val); - ndelay(RECOVERY_NDELAY); - } - - if (bri->unprepare_recovery) - bri->unprepare_recovery(adap); - - return ret; -} - -int i2c_generic_scl_recovery(struct i2c_adapter *adap) -{ - return i2c_generic_recovery(adap); -} -EXPORT_SYMBOL_GPL(i2c_generic_scl_recovery); - -int i2c_generic_gpio_recovery(struct i2c_adapter *adap) -{ - int ret; - - ret = i2c_get_gpios_for_recovery(adap); - if (ret) - return ret; - - ret = i2c_generic_recovery(adap); - i2c_put_gpios_for_recovery(adap); - - return ret; -} -EXPORT_SYMBOL_GPL(i2c_generic_gpio_recovery); - -int i2c_recover_bus(struct i2c_adapter *adap) -{ - if (!adap->bus_recovery_info) - return -EOPNOTSUPP; - - dev_dbg(&adap->dev, "Trying i2c bus recovery\n"); - return adap->bus_recovery_info->recover_bus(adap); -} -EXPORT_SYMBOL_GPL(i2c_recover_bus); - -static void i2c_init_recovery(struct i2c_adapter *adap) -{ - struct i2c_bus_recovery_info *bri = adap->bus_recovery_info; - char *err_str; - - if (!bri) - return; - - if (!bri->recover_bus) { - err_str = "no recover_bus() found"; - goto err; - } - - /* Generic GPIO recovery */ - if (bri->recover_bus == i2c_generic_gpio_recovery) { - if (!gpio_is_valid(bri->scl_gpio)) { - err_str = "invalid SCL gpio"; - goto err; - } - - if (gpio_is_valid(bri->sda_gpio)) - bri->get_sda = get_sda_gpio_value; - else - bri->get_sda = NULL; - - bri->get_scl = get_scl_gpio_value; - bri->set_scl = set_scl_gpio_value; - } else if (bri->recover_bus == i2c_generic_scl_recovery) { - /* Generic SCL recovery */ - if (!bri->set_scl || !bri->get_scl) { - err_str = "no {get|set}_scl() found"; - goto err; - } - } - - return; - err: - dev_err(&adap->dev, "Not using recovery: %s\n", err_str); - adap->bus_recovery_info = NULL; -} - -static int i2c_smbus_host_notify_to_irq(const struct i2c_client *client) -{ - struct i2c_adapter *adap = client->adapter; - unsigned int irq; - - if (!adap->host_notify_domain) - return -ENXIO; - - if (client->flags & I2C_CLIENT_TEN) - return -EINVAL; - - irq = irq_find_mapping(adap->host_notify_domain, client->addr); - if (!irq) - irq = irq_create_mapping(adap->host_notify_domain, - client->addr); - - return irq > 0 ? irq : -ENXIO; -} - -static int i2c_device_probe(struct device *dev) -{ - struct i2c_client *client = i2c_verify_client(dev); - struct i2c_driver *driver; - int status; - - if (!client) - return 0; - - driver = to_i2c_driver(dev->driver); - - if (!client->irq && !driver->disable_i2c_core_irq_mapping) { - int irq = -ENOENT; - - if (client->flags & I2C_CLIENT_HOST_NOTIFY) { - dev_dbg(dev, "Using Host Notify IRQ\n"); - irq = i2c_smbus_host_notify_to_irq(client); - } else if (dev->of_node) { - irq = of_irq_get_byname(dev->of_node, "irq"); - if (irq == -EINVAL || irq == -ENODATA) - irq = of_irq_get(dev->of_node, 0); - } else if (ACPI_COMPANION(dev)) { - irq = acpi_dev_gpio_irq_get(ACPI_COMPANION(dev), 0); - } - if (irq == -EPROBE_DEFER) - return irq; - - if (irq < 0) - irq = 0; - - client->irq = irq; - } - - /* - * An I2C ID table is not mandatory, if and only if, a suitable Device - * Tree match table entry is supplied for the probing device. - */ - if (!driver->id_table && - !i2c_of_match_device(dev->driver->of_match_table, client)) - return -ENODEV; - - if (client->flags & I2C_CLIENT_WAKE) { - int wakeirq = -ENOENT; - - if (dev->of_node) { - wakeirq = of_irq_get_byname(dev->of_node, "wakeup"); - if (wakeirq == -EPROBE_DEFER) - return wakeirq; - } - - device_init_wakeup(&client->dev, true); - - if (wakeirq > 0 && wakeirq != client->irq) - status = dev_pm_set_dedicated_wake_irq(dev, wakeirq); - else if (client->irq > 0) - status = dev_pm_set_wake_irq(dev, client->irq); - else - status = 0; - - if (status) - dev_warn(&client->dev, "failed to set up wakeup irq\n"); - } - - dev_dbg(dev, "probe\n"); - - status = of_clk_set_defaults(dev->of_node, false); - if (status < 0) - goto err_clear_wakeup_irq; - - status = dev_pm_domain_attach(&client->dev, true); - if (status == -EPROBE_DEFER) - goto err_clear_wakeup_irq; - - /* - * When there are no more users of probe(), - * rename probe_new to probe. - */ - if (driver->probe_new) - status = driver->probe_new(client); - else if (driver->probe) - status = driver->probe(client, - i2c_match_id(driver->id_table, client)); - else - status = -EINVAL; - - if (status) - goto err_detach_pm_domain; - - return 0; - -err_detach_pm_domain: - dev_pm_domain_detach(&client->dev, true); -err_clear_wakeup_irq: - dev_pm_clear_wake_irq(&client->dev); - device_init_wakeup(&client->dev, false); - return status; -} - -static int i2c_device_remove(struct device *dev) -{ - struct i2c_client *client = i2c_verify_client(dev); - struct i2c_driver *driver; - int status = 0; - - if (!client || !dev->driver) - return 0; - - driver = to_i2c_driver(dev->driver); - if (driver->remove) { - dev_dbg(dev, "remove\n"); - status = driver->remove(client); - } - - dev_pm_domain_detach(&client->dev, true); - - dev_pm_clear_wake_irq(&client->dev); - device_init_wakeup(&client->dev, false); - - return status; -} - -static void i2c_device_shutdown(struct device *dev) -{ - struct i2c_client *client = i2c_verify_client(dev); - struct i2c_driver *driver; - - if (!client || !dev->driver) - return; - driver = to_i2c_driver(dev->driver); - if (driver->shutdown) - driver->shutdown(client); -} - -static void i2c_client_dev_release(struct device *dev) -{ - kfree(to_i2c_client(dev)); -} - -static ssize_t -show_name(struct device *dev, struct device_attribute *attr, char *buf) -{ - return sprintf(buf, "%s\n", dev->type == &i2c_client_type ? - to_i2c_client(dev)->name : to_i2c_adapter(dev)->name); -} -static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); - -static ssize_t -show_modalias(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - int len; - - len = acpi_device_modalias(dev, buf, PAGE_SIZE -1); - if (len != -ENODEV) - return len; - - return sprintf(buf, "%s%s\n", I2C_MODULE_PREFIX, client->name); -} -static DEVICE_ATTR(modalias, S_IRUGO, show_modalias, NULL); - -static struct attribute *i2c_dev_attrs[] = { - &dev_attr_name.attr, - /* modalias helps coldplug: modprobe $(cat .../modalias) */ - &dev_attr_modalias.attr, - NULL -}; -ATTRIBUTE_GROUPS(i2c_dev); - -struct bus_type i2c_bus_type = { - .name = "i2c", - .match = i2c_device_match, - .probe = i2c_device_probe, - .remove = i2c_device_remove, - .shutdown = i2c_device_shutdown, -}; -EXPORT_SYMBOL_GPL(i2c_bus_type); - -struct device_type i2c_client_type = { - .groups = i2c_dev_groups, - .uevent = i2c_device_uevent, - .release = i2c_client_dev_release, -}; -EXPORT_SYMBOL_GPL(i2c_client_type); - - -/** - * i2c_verify_client - return parameter as i2c_client, or NULL - * @dev: device, probably from some driver model iterator - * - * When traversing the driver model tree, perhaps using driver model - * iterators like @device_for_each_child(), you can't assume very much - * about the nodes you find. Use this function to avoid oopses caused - * by wrongly treating some non-I2C device as an i2c_client. - */ -struct i2c_client *i2c_verify_client(struct device *dev) -{ - return (dev->type == &i2c_client_type) - ? to_i2c_client(dev) - : NULL; -} -EXPORT_SYMBOL(i2c_verify_client); - - -/* Return a unique address which takes the flags of the client into account */ -static unsigned short i2c_encode_flags_to_addr(struct i2c_client *client) -{ - unsigned short addr = client->addr; - - /* For some client flags, add an arbitrary offset to avoid collisions */ - if (client->flags & I2C_CLIENT_TEN) - addr |= I2C_ADDR_OFFSET_TEN_BIT; - - if (client->flags & I2C_CLIENT_SLAVE) - addr |= I2C_ADDR_OFFSET_SLAVE; - - return addr; -} - -/* This is a permissive address validity check, I2C address map constraints - * are purposely not enforced, except for the general call address. */ -static int i2c_check_addr_validity(unsigned addr, unsigned short flags) -{ - if (flags & I2C_CLIENT_TEN) { - /* 10-bit address, all values are valid */ |