/* 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.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* ------------------------------------------------------------------------- */
/* 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 <khali@linux-fr.org> */
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/idr.h>
#include <linux/seq_file.h>
#include <linux/platform_device.h>
#include <linux/mutex.h>
#include <linux/completion.h>
#include <asm/uaccess.h>
static LIST_HEAD(adapters);
static LIST_HEAD(drivers);
static DEFINE_MUTEX(core_lists);
static DEFINE_IDR(i2c_adapter_idr);
#define is_newstyle_driver(d) ((d)->probe || (d)->remove)
/* ------------------------------------------------------------------------- */
static int i2c_device_match(struct device *dev, struct device_driver *drv)
{
struct i2c_client *client = to_i2c_client(dev);
struct i2c_driver *driver = to_i2c_driver(drv);
/* make legacy i2c drivers bypass driver model probing entirely;
* such drivers scan each i2c adapter/bus themselves.
*/
if (!is_newstyle_driver(driver))
return 0;
/* new style drivers use the same kind of driver matching policy
* as platform devices or SPI: compare device and driver IDs.
*/
return strcmp(client->driver_name, drv->name) == 0;
}
#ifdef CONFIG_HOTPLUG
/* uevent helps with hotplug: modprobe -q $(MODALIAS) */
static int i2c_device_uevent(struct device *dev, char **envp, int num_envp,
char *buffer, int buffer_size)
{
struct i2c_client *client = to_i2c_client(dev);
int i = 0, length = 0;
/* by definition, legacy drivers can't hotplug */
if (dev->driver || !client->driver_name)
return 0;
if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
"MODALIAS=%s", client->driver_name))
return -ENOMEM;
envp[i] = NULL;
dev_dbg(dev, "uevent\n");
return 0;
}
#else
#define i2c_device_uevent NULL
#endif /* CONFIG_HOTPLUG */
static int i2c_device_probe(