1c942fddfSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds i2c-dev.c - i2c-bus driver, char device interface
41da177e4SLinus Torvalds
51da177e4SLinus Torvalds Copyright (C) 1995-97 Simon G. Vogl
61da177e4SLinus Torvalds Copyright (C) 1998-99 Frodo Looijaard <frodol@dds.nl>
71da177e4SLinus Torvalds Copyright (C) 2003 Greg Kroah-Hartman <greg@kroah.com>
81da177e4SLinus Torvalds
91da177e4SLinus Torvalds */
101da177e4SLinus Torvalds
111da177e4SLinus Torvalds /* Note that this is a complete rewrite of Simon Vogl's i2c-dev module.
121da177e4SLinus Torvalds But I have used so much of his original code and ideas that it seems
131da177e4SLinus Torvalds only fair to recognize him as co-author -- Frodo */
141da177e4SLinus Torvalds
151da177e4SLinus Torvalds /* The I2C_RDWR ioctl code is written by Kolja Waschk <waschk@telos.de> */
161da177e4SLinus Torvalds
17295e0e7bSAndy Shevchenko #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
18295e0e7bSAndy Shevchenko
19d6760b14SErico Nunes #include <linux/cdev.h>
20f01adfabSWolfram Sang #include <linux/compat.h>
219ea3e941SJean Delvare #include <linux/device.h>
221da177e4SLinus Torvalds #include <linux/fs.h>
231da177e4SLinus Torvalds #include <linux/i2c-dev.h>
24a8766073SWolfram Sang #include <linux/i2c.h>
25a8766073SWolfram Sang #include <linux/init.h>
26cd97f39bSJean Delvare #include <linux/jiffies.h>
27a8766073SWolfram Sang #include <linux/kernel.h>
28a8766073SWolfram Sang #include <linux/list.h>
29a8766073SWolfram Sang #include <linux/module.h>
30a8766073SWolfram Sang #include <linux/notifier.h>
31a8766073SWolfram Sang #include <linux/slab.h>
32ae5624fcSFarid Hammane #include <linux/uaccess.h>
331da177e4SLinus Torvalds
34907135aaSDavid Brownell /*
35907135aaSDavid Brownell * An i2c_dev represents an i2c_adapter ... an I2C or SMBus master, not a
36907135aaSDavid Brownell * slave (i2c_client) with which messages will be exchanged. It's coupled
37907135aaSDavid Brownell * with a character special file which is accessed by user mode drivers.
38907135aaSDavid Brownell *
39907135aaSDavid Brownell * The list of i2c_dev structures is parallel to the i2c_adapter lists
409ea3e941SJean Delvare * maintained by the driver model, and is updated using bus notifications.
41907135aaSDavid Brownell */
421da177e4SLinus Torvalds struct i2c_dev {
43f3b3aadbSJean Delvare struct list_head list;
441da177e4SLinus Torvalds struct i2c_adapter *adap;
451413ef63SKevin Hao struct device dev;
46d6760b14SErico Nunes struct cdev cdev;
471da177e4SLinus Torvalds };
481da177e4SLinus Torvalds
498a6d508aSChengguang Xu #define I2C_MINORS (MINORMASK + 1)
50f3b3aadbSJean Delvare static LIST_HEAD(i2c_dev_list);
51f3b3aadbSJean Delvare static DEFINE_SPINLOCK(i2c_dev_list_lock);
521da177e4SLinus Torvalds
i2c_dev_get_by_minor(unsigned index)531da177e4SLinus Torvalds static struct i2c_dev *i2c_dev_get_by_minor(unsigned index)
541da177e4SLinus Torvalds {
551da177e4SLinus Torvalds struct i2c_dev *i2c_dev;
561da177e4SLinus Torvalds
57f3b3aadbSJean Delvare spin_lock(&i2c_dev_list_lock);
58f3b3aadbSJean Delvare list_for_each_entry(i2c_dev, &i2c_dev_list, list) {
59f3b3aadbSJean Delvare if (i2c_dev->adap->nr == index)
60f3b3aadbSJean Delvare goto found;
61f3b3aadbSJean Delvare }
62f3b3aadbSJean Delvare i2c_dev = NULL;
63f3b3aadbSJean Delvare found:
64f3b3aadbSJean Delvare spin_unlock(&i2c_dev_list_lock);
651da177e4SLinus Torvalds return i2c_dev;
661da177e4SLinus Torvalds }
671da177e4SLinus Torvalds
get_free_i2c_dev(struct i2c_adapter * adap)681da177e4SLinus Torvalds static struct i2c_dev *get_free_i2c_dev(struct i2c_adapter *adap)
691da177e4SLinus Torvalds {
701da177e4SLinus Torvalds struct i2c_dev *i2c_dev;
711da177e4SLinus Torvalds
72f3b3aadbSJean Delvare if (adap->nr >= I2C_MINORS) {
73295e0e7bSAndy Shevchenko pr_err("Out of device minors (%d)\n", adap->nr);
74f3b3aadbSJean Delvare return ERR_PTR(-ENODEV);
75f3b3aadbSJean Delvare }
76f3b3aadbSJean Delvare
775263ebb5SDeepak Saxena i2c_dev = kzalloc(sizeof(*i2c_dev), GFP_KERNEL);
781da177e4SLinus Torvalds if (!i2c_dev)
791da177e4SLinus Torvalds return ERR_PTR(-ENOMEM);
809455e4c9SJean Delvare i2c_dev->adap = adap;
81f3b3aadbSJean Delvare
82f3b3aadbSJean Delvare spin_lock(&i2c_dev_list_lock);
83f3b3aadbSJean Delvare list_add_tail(&i2c_dev->list, &i2c_dev_list);
84f3b3aadbSJean Delvare spin_unlock(&i2c_dev_list_lock);
851da177e4SLinus Torvalds return i2c_dev;
861da177e4SLinus Torvalds }
871da177e4SLinus Torvalds
put_i2c_dev(struct i2c_dev * i2c_dev,bool del_cdev)881413ef63SKevin Hao static void put_i2c_dev(struct i2c_dev *i2c_dev, bool del_cdev)
891da177e4SLinus Torvalds {
90f3b3aadbSJean Delvare spin_lock(&i2c_dev_list_lock);
91f3b3aadbSJean Delvare list_del(&i2c_dev->list);
92f3b3aadbSJean Delvare spin_unlock(&i2c_dev_list_lock);
931413ef63SKevin Hao if (del_cdev)
941413ef63SKevin Hao cdev_device_del(&i2c_dev->cdev, &i2c_dev->dev);
951413ef63SKevin Hao put_device(&i2c_dev->dev);
961da177e4SLinus Torvalds }
971da177e4SLinus Torvalds
name_show(struct device * dev,struct device_attribute * attr,char * buf)9845f176aeSGuenter Roeck static ssize_t name_show(struct device *dev,
99ac11d060SGreg Kroah-Hartman struct device_attribute *attr, char *buf)
1001da177e4SLinus Torvalds {
101ac11d060SGreg Kroah-Hartman struct i2c_dev *i2c_dev = i2c_dev_get_by_minor(MINOR(dev->devt));
10279472132SGreg Kroah-Hartman
10379472132SGreg Kroah-Hartman if (!i2c_dev)
10479472132SGreg Kroah-Hartman return -ENODEV;
105b18f32d9SAndy Shevchenko return sysfs_emit(buf, "%s\n", i2c_dev->adap->name);
1061da177e4SLinus Torvalds }
10745f176aeSGuenter Roeck static DEVICE_ATTR_RO(name);
10845f176aeSGuenter Roeck
10945f176aeSGuenter Roeck static struct attribute *i2c_attrs[] = {
11045f176aeSGuenter Roeck &dev_attr_name.attr,
11145f176aeSGuenter Roeck NULL,
11245f176aeSGuenter Roeck };
11345f176aeSGuenter Roeck ATTRIBUTE_GROUPS(i2c);
1141da177e4SLinus Torvalds
115907135aaSDavid Brownell /* ------------------------------------------------------------------------- */
116907135aaSDavid Brownell
117907135aaSDavid Brownell /*
118907135aaSDavid Brownell * After opening an instance of this character special file, a file
119907135aaSDavid Brownell * descriptor starts out associated only with an i2c_adapter (and bus).
120907135aaSDavid Brownell *
121907135aaSDavid Brownell * Using the I2C_RDWR ioctl(), you can then *immediately* issue i2c_msg
122907135aaSDavid Brownell * traffic to any devices on the bus used by that adapter. That's because
123907135aaSDavid Brownell * the i2c_msg vectors embed all the addressing information they need, and
124907135aaSDavid Brownell * are submitted directly to an i2c_adapter. However, SMBus-only adapters
125907135aaSDavid Brownell * don't support that interface.
126907135aaSDavid Brownell *
127907135aaSDavid Brownell * To use read()/write() system calls on that file descriptor, or to use
128907135aaSDavid Brownell * SMBus interfaces (and work with SMBus-only hosts!), you must first issue
129907135aaSDavid Brownell * an I2C_SLAVE (or I2C_SLAVE_FORCE) ioctl. That configures an anonymous
130907135aaSDavid Brownell * (never registered) i2c_client so it holds the addressing information
131907135aaSDavid Brownell * needed by those system calls and by this SMBus interface.
132907135aaSDavid Brownell */
133907135aaSDavid Brownell
i2cdev_read(struct file * file,char __user * buf,size_t count,loff_t * offset)1341da177e4SLinus Torvalds static ssize_t i2cdev_read(struct file *file, char __user *buf, size_t count,
1351da177e4SLinus Torvalds loff_t *offset)
1361da177e4SLinus Torvalds {
1371da177e4SLinus Torvalds char *tmp;
1381da177e4SLinus Torvalds int ret;
1391da177e4SLinus Torvalds
1400be16c30SH Hartley Sweeten struct i2c_client *client = file->private_data;
1411da177e4SLinus Torvalds
1421da177e4SLinus Torvalds if (count > 8192)
1431da177e4SLinus Torvalds count = 8192;
1441da177e4SLinus Torvalds
14586ff25edSGreg Kroah-Hartman tmp = kzalloc(count, GFP_KERNEL);
1461da177e4SLinus Torvalds if (tmp == NULL)
1471da177e4SLinus Torvalds return -ENOMEM;
1481da177e4SLinus Torvalds
149295e0e7bSAndy Shevchenko pr_debug("i2c-%d reading %zu bytes.\n", iminor(file_inode(file)), count);
1501da177e4SLinus Torvalds
1511da177e4SLinus Torvalds ret = i2c_master_recv(client, tmp, count);
1521da177e4SLinus Torvalds if (ret >= 0)
15386ff25edSGreg Kroah-Hartman if (copy_to_user(buf, tmp, ret))
15486ff25edSGreg Kroah-Hartman ret = -EFAULT;
1551da177e4SLinus Torvalds kfree(tmp);
1561da177e4SLinus Torvalds return ret;
1571da177e4SLinus Torvalds }
1581da177e4SLinus Torvalds
i2cdev_write(struct file * file,const char __user * buf,size_t count,loff_t * offset)159ae5624fcSFarid Hammane static ssize_t i2cdev_write(struct file *file, const char __user *buf,
160ae5624fcSFarid Hammane size_t count, loff_t *offset)
1611da177e4SLinus Torvalds {
1621da177e4SLinus Torvalds int ret;
1631da177e4SLinus Torvalds char *tmp;
1640be16c30SH Hartley Sweeten struct i2c_client *client = file->private_data;
1651da177e4SLinus Torvalds
1661da177e4SLinus Torvalds if (count > 8192)
1671da177e4SLinus Torvalds count = 8192;
1681da177e4SLinus Torvalds
169f1c2e33cSJulia Lawall tmp = memdup_user(buf, count);
170f1c2e33cSJulia Lawall if (IS_ERR(tmp))
171f1c2e33cSJulia Lawall return PTR_ERR(tmp);
1721da177e4SLinus Torvalds
173295e0e7bSAndy Shevchenko pr_debug("i2c-%d writing %zu bytes.\n", iminor(file_inode(file)), count);
1741da177e4SLinus Torvalds
1751da177e4SLinus Torvalds ret = i2c_master_send(client, tmp, count);
1761da177e4SLinus Torvalds kfree(tmp);
1771da177e4SLinus Torvalds return ret;
1781da177e4SLinus Torvalds }
1791da177e4SLinus Torvalds
i2cdev_check(struct device * dev,void * addrp)1809b766b81SDavid Brownell static int i2cdev_check(struct device *dev, void *addrp)
1819b766b81SDavid Brownell {
1829b766b81SDavid Brownell struct i2c_client *client = i2c_verify_client(dev);
1839b766b81SDavid Brownell
1849b766b81SDavid Brownell if (!client || client->addr != *(unsigned int *)addrp)
1859b766b81SDavid Brownell return 0;
1869b766b81SDavid Brownell
1879b766b81SDavid Brownell return dev->driver ? -EBUSY : 0;
1889b766b81SDavid Brownell }
1899b766b81SDavid Brownell
1900826374bSMichael Lawnick /* walk up mux tree */
i2cdev_check_mux_parents(struct i2c_adapter * adapter,int addr)1910826374bSMichael Lawnick static int i2cdev_check_mux_parents(struct i2c_adapter *adapter, int addr)
1920826374bSMichael Lawnick {
19397cc4d49SJean Delvare struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter);
1940826374bSMichael Lawnick int result;
1950826374bSMichael Lawnick
1960826374bSMichael Lawnick result = device_for_each_child(&adapter->dev, &addr, i2cdev_check);
19797cc4d49SJean Delvare if (!result && parent)
19897cc4d49SJean Delvare result = i2cdev_check_mux_parents(parent, addr);
1990826374bSMichael Lawnick
2000826374bSMichael Lawnick return result;
2010826374bSMichael Lawnick }
2020826374bSMichael Lawnick
2030826374bSMichael Lawnick /* recurse down mux tree */
i2cdev_check_mux_children(struct device * dev,void * addrp)2040826374bSMichael Lawnick static int i2cdev_check_mux_children(struct device *dev, void *addrp)
2050826374bSMichael Lawnick {
2060826374bSMichael Lawnick int result;
2070826374bSMichael Lawnick
2080826374bSMichael Lawnick if (dev->type == &i2c_adapter_type)
2090826374bSMichael Lawnick result = device_for_each_child(dev, addrp,
2100826374bSMichael Lawnick i2cdev_check_mux_children);
2110826374bSMichael Lawnick else
2120826374bSMichael Lawnick result = i2cdev_check(dev, addrp);
2130826374bSMichael Lawnick
2140826374bSMichael Lawnick return result;
2150826374bSMichael Lawnick }
2160826374bSMichael Lawnick
217bd4217d8SJean Delvare /* This address checking function differs from the one in i2c-core
218bd4217d8SJean Delvare in that it considers an address with a registered device, but no
2199b766b81SDavid Brownell driver bound to it, as NOT busy. */
i2cdev_check_addr(struct i2c_adapter * adapter,unsigned int addr)220bd4217d8SJean Delvare static int i2cdev_check_addr(struct i2c_adapter *adapter, unsigned int addr)
221bd4217d8SJean Delvare {
22297cc4d49SJean Delvare struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter);
2230826374bSMichael Lawnick int result = 0;
2240826374bSMichael Lawnick
22597cc4d49SJean Delvare if (parent)
22697cc4d49SJean Delvare result = i2cdev_check_mux_parents(parent, addr);
2270826374bSMichael Lawnick
2280826374bSMichael Lawnick if (!result)
2290826374bSMichael Lawnick result = device_for_each_child(&adapter->dev, &addr,
2300826374bSMichael Lawnick i2cdev_check_mux_children);
2310826374bSMichael Lawnick
2320826374bSMichael Lawnick return result;
233bd4217d8SJean Delvare }
234bd4217d8SJean Delvare
i2cdev_ioctl_rdwr(struct i2c_client * client,unsigned nmsgs,struct i2c_msg * msgs)235c57d3e7aSJean Delvare static noinline int i2cdev_ioctl_rdwr(struct i2c_client *client,
2367d5cb456SAl Viro unsigned nmsgs, struct i2c_msg *msgs)
237dba7997aSJean Delvare {
238dba7997aSJean Delvare u8 __user **data_ptrs;
239dba7997aSJean Delvare int i, res;
240dba7997aSJean Delvare
2416da2ec56SKees Cook data_ptrs = kmalloc_array(nmsgs, sizeof(u8 __user *), GFP_KERNEL);
242dba7997aSJean Delvare if (data_ptrs == NULL) {
2437d5cb456SAl Viro kfree(msgs);
244dba7997aSJean Delvare return -ENOMEM;
245dba7997aSJean Delvare }
246dba7997aSJean Delvare
247dba7997aSJean Delvare res = 0;
2487d5cb456SAl Viro for (i = 0; i < nmsgs; i++) {
249838bfa60SJean Delvare /* Limit the size of the message to a sane amount */
2507d5cb456SAl Viro if (msgs[i].len > 8192) {
251dba7997aSJean Delvare res = -EINVAL;
252dba7997aSJean Delvare break;
253dba7997aSJean Delvare }
254838bfa60SJean Delvare
2557d5cb456SAl Viro data_ptrs[i] = (u8 __user *)msgs[i].buf;
2567d5cb456SAl Viro msgs[i].buf = memdup_user(data_ptrs[i], msgs[i].len);
2577d5cb456SAl Viro if (IS_ERR(msgs[i].buf)) {
2587d5cb456SAl Viro res = PTR_ERR(msgs[i].buf);
259dba7997aSJean Delvare break;
260dba7997aSJean Delvare }
261978336d4SWolfram Sang /* memdup_user allocates with GFP_KERNEL, so DMA is ok */
262978336d4SWolfram Sang msgs[i].flags |= I2C_M_DMA_SAFE;
263838bfa60SJean Delvare
264838bfa60SJean Delvare /*
265838bfa60SJean Delvare * If the message length is received from the slave (similar
266838bfa60SJean Delvare * to SMBus block read), we must ensure that the buffer will
267838bfa60SJean Delvare * be large enough to cope with a message length of
268838bfa60SJean Delvare * I2C_SMBUS_BLOCK_MAX as this is the maximum underlying bus
269838bfa60SJean Delvare * drivers allow. The first byte in the buffer must be
270838bfa60SJean Delvare * pre-filled with the number of extra bytes, which must be
271838bfa60SJean Delvare * at least one to hold the message length, but can be
272838bfa60SJean Delvare * greater (for example to account for a checksum byte at
273838bfa60SJean Delvare * the end of the message.)
274838bfa60SJean Delvare */
2757d5cb456SAl Viro if (msgs[i].flags & I2C_M_RECV_LEN) {
2767d5cb456SAl Viro if (!(msgs[i].flags & I2C_M_RD) ||
27723a27722SAlexander Popov msgs[i].len < 1 || msgs[i].buf[0] < 1 ||
2787d5cb456SAl Viro msgs[i].len < msgs[i].buf[0] +
279838bfa60SJean Delvare I2C_SMBUS_BLOCK_MAX) {
280a0692f0eSYingjoe Chen i++;
281838bfa60SJean Delvare res = -EINVAL;
282838bfa60SJean Delvare break;
283838bfa60SJean Delvare }
284838bfa60SJean Delvare
2857d5cb456SAl Viro msgs[i].len = msgs[i].buf[0];
286838bfa60SJean Delvare }
287dba7997aSJean Delvare }
288dba7997aSJean Delvare if (res < 0) {
289dba7997aSJean Delvare int j;
290dba7997aSJean Delvare for (j = 0; j < i; ++j)
2917d5cb456SAl Viro kfree(msgs[j].buf);
292dba7997aSJean Delvare kfree(data_ptrs);
2937d5cb456SAl Viro kfree(msgs);
294dba7997aSJean Delvare return res;
295dba7997aSJean Delvare }
296dba7997aSJean Delvare
2977d5cb456SAl Viro res = i2c_transfer(client->adapter, msgs, nmsgs);
298dba7997aSJean Delvare while (i-- > 0) {
2997d5cb456SAl Viro if (res >= 0 && (msgs[i].flags & I2C_M_RD)) {
3007d5cb456SAl Viro if (copy_to_user(data_ptrs[i], msgs[i].buf,
3017d5cb456SAl Viro msgs[i].len))
302dba7997aSJean Delvare res = -EFAULT;
303dba7997aSJean Delvare }
3047d5cb456SAl Viro kfree(msgs[i].buf);
305dba7997aSJean Delvare }
306dba7997aSJean Delvare kfree(data_ptrs);
3077d5cb456SAl Viro kfree(msgs);
308dba7997aSJean Delvare return res;
309dba7997aSJean Delvare }
310dba7997aSJean Delvare
i2cdev_ioctl_smbus(struct i2c_client * client,u8 read_write,u8 command,u32 size,union i2c_smbus_data __user * data)311dba7997aSJean Delvare static noinline int i2cdev_ioctl_smbus(struct i2c_client *client,
3127d5cb456SAl Viro u8 read_write, u8 command, u32 size,
3137d5cb456SAl Viro union i2c_smbus_data __user *data)
314dba7997aSJean Delvare {
31530f939feSVlad Tsyrklevich union i2c_smbus_data temp = {};
316dba7997aSJean Delvare int datasize, res;
317dba7997aSJean Delvare
3187d5cb456SAl Viro if ((size != I2C_SMBUS_BYTE) &&
3197d5cb456SAl Viro (size != I2C_SMBUS_QUICK) &&
3207d5cb456SAl Viro (size != I2C_SMBUS_BYTE_DATA) &&
3217d5cb456SAl Viro (size != I2C_SMBUS_WORD_DATA) &&
3227d5cb456SAl Viro (size != I2C_SMBUS_PROC_CALL) &&
3237d5cb456SAl Viro (size != I2C_SMBUS_BLOCK_DATA) &&
3247d5cb456SAl Viro (size != I2C_SMBUS_I2C_BLOCK_BROKEN) &&
3257d5cb456SAl Viro (size != I2C_SMBUS_I2C_BLOCK_DATA) &&
3267d5cb456SAl Viro (size != I2C_SMBUS_BLOCK_PROC_CALL)) {
327dba7997aSJean Delvare dev_dbg(&client->adapter->dev,
328dba7997aSJean Delvare "size out of range (%x) in ioctl I2C_SMBUS.\n",
3297d5cb456SAl Viro size);
330dba7997aSJean Delvare return -EINVAL;
331dba7997aSJean Delvare }
332dba7997aSJean Delvare /* Note that I2C_SMBUS_READ and I2C_SMBUS_WRITE are 0 and 1,
333dba7997aSJean Delvare so the check is valid if size==I2C_SMBUS_QUICK too. */
3347d5cb456SAl Viro if ((read_write != I2C_SMBUS_READ) &&
3357d5cb456SAl Viro (read_write != I2C_SMBUS_WRITE)) {
336dba7997aSJean Delvare dev_dbg(&client->adapter->dev,
337dba7997aSJean Delvare "read_write out of range (%x) in ioctl I2C_SMBUS.\n",
3387d5cb456SAl Viro read_write);
339dba7997aSJean Delvare return -EINVAL;
340dba7997aSJean Delvare }
341dba7997aSJean Delvare
342dba7997aSJean Delvare /* Note that command values are always valid! */
343dba7997aSJean Delvare
3447d5cb456SAl Viro if ((size == I2C_SMBUS_QUICK) ||
3457d5cb456SAl Viro ((size == I2C_SMBUS_BYTE) &&
3467d5cb456SAl Viro (read_write == I2C_SMBUS_WRITE)))
347dba7997aSJean Delvare /* These are special: we do not use data */
348dba7997aSJean Delvare return i2c_smbus_xfer(client->adapter, client->addr,
3497d5cb456SAl Viro client->flags, read_write,
3507d5cb456SAl Viro command, size, NULL);
351dba7997aSJean Delvare
3527d5cb456SAl Viro if (data == NULL) {
353dba7997aSJean Delvare dev_dbg(&client->adapter->dev,
354dba7997aSJean Delvare "data is NULL pointer in ioctl I2C_SMBUS.\n");
355dba7997aSJean Delvare return -EINVAL;
356dba7997aSJean Delvare }
357dba7997aSJean Delvare
3587d5cb456SAl Viro if ((size == I2C_SMBUS_BYTE_DATA) ||
3597d5cb456SAl Viro (size == I2C_SMBUS_BYTE))
3607d5cb456SAl Viro datasize = sizeof(data->byte);
3617d5cb456SAl Viro else if ((size == I2C_SMBUS_WORD_DATA) ||
3627d5cb456SAl Viro (size == I2C_SMBUS_PROC_CALL))
3637d5cb456SAl Viro datasize = sizeof(data->word);
364dba7997aSJean Delvare else /* size == smbus block, i2c block, or block proc. call */
3657d5cb456SAl Viro datasize = sizeof(data->block);
366dba7997aSJean Delvare
3677d5cb456SAl Viro if ((size == I2C_SMBUS_PROC_CALL) ||
3687d5cb456SAl Viro (size == I2C_SMBUS_BLOCK_PROC_CALL) ||
3697d5cb456SAl Viro (size == I2C_SMBUS_I2C_BLOCK_DATA) ||
3707d5cb456SAl Viro (read_write == I2C_SMBUS_WRITE)) {
3717d5cb456SAl Viro if (copy_from_user(&temp, data, datasize))
372dba7997aSJean Delvare return -EFAULT;
373dba7997aSJean Delvare }
3747d5cb456SAl Viro if (size == I2C_SMBUS_I2C_BLOCK_BROKEN) {
375dba7997aSJean Delvare /* Convert old I2C block commands to the new
376dba7997aSJean Delvare convention. This preserves binary compatibility. */
3777d5cb456SAl Viro size = I2C_SMBUS_I2C_BLOCK_DATA;
3787d5cb456SAl Viro if (read_write == I2C_SMBUS_READ)
379dba7997aSJean Delvare temp.block[0] = I2C_SMBUS_BLOCK_MAX;
380dba7997aSJean Delvare }
381dba7997aSJean Delvare res = i2c_smbus_xfer(client->adapter, client->addr, client->flags,
3827d5cb456SAl Viro read_write, command, size, &temp);
3837d5cb456SAl Viro if (!res && ((size == I2C_SMBUS_PROC_CALL) ||
3847d5cb456SAl Viro (size == I2C_SMBUS_BLOCK_PROC_CALL) ||
3857d5cb456SAl Viro (read_write == I2C_SMBUS_READ))) {
3867d5cb456SAl Viro if (copy_to_user(data, &temp, datasize))
387dba7997aSJean Delvare return -EFAULT;
388dba7997aSJean Delvare }
389dba7997aSJean Delvare return res;
390dba7997aSJean Delvare }
391dba7997aSJean Delvare
i2cdev_ioctl(struct file * file,unsigned int cmd,unsigned long arg)39277e38bffSAlan Cox static long i2cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
3931da177e4SLinus Torvalds {
3940be16c30SH Hartley Sweeten struct i2c_client *client = file->private_data;
3951da177e4SLinus Torvalds unsigned long funcs;
3961da177e4SLinus Torvalds
397e8aafcb2SJean Delvare dev_dbg(&client->adapter->dev, "ioctl, cmd=0x%02x, arg=0x%02lx\n",
398e8aafcb2SJean Delvare cmd, arg);
3991da177e4SLinus Torvalds
4001da177e4SLinus Torvalds switch (cmd) {
4011da177e4SLinus Torvalds case I2C_SLAVE:
4021da177e4SLinus Torvalds case I2C_SLAVE_FORCE:
4031da177e4SLinus Torvalds if ((arg > 0x3ff) ||
4041da177e4SLinus Torvalds (((client->flags & I2C_M_TEN) == 0) && arg > 0x7f))
4051da177e4SLinus Torvalds return -EINVAL;
406bd4217d8SJean Delvare if (cmd == I2C_SLAVE && i2cdev_check_addr(client->adapter, arg))
4071da177e4SLinus Torvalds return -EBUSY;
408bd4217d8SJean Delvare /* REVISIT: address could become busy later */
4091da177e4SLinus Torvalds client->addr = arg;
4101da177e4SLinus Torvalds return 0;
4111da177e4SLinus Torvalds case I2C_TENBIT:
4121da177e4SLinus Torvalds if (arg)
4131da177e4SLinus Torvalds client->flags |= I2C_M_TEN;
4141da177e4SLinus Torvalds else
4151da177e4SLinus Torvalds client->flags &= ~I2C_M_TEN;
4161da177e4SLinus Torvalds return 0;
4171da177e4SLinus Torvalds case I2C_PEC:
4189e685c84SJean Delvare /*
4199e685c84SJean Delvare * Setting the PEC flag here won't affect kernel drivers,
4209e685c84SJean Delvare * which will be using the i2c_client node registered with
4219e685c84SJean Delvare * the driver model core. Likewise, when that client has
4229e685c84SJean Delvare * the PEC flag already set, the i2c-dev driver won't see
4239e685c84SJean Delvare * (or use) this setting.
4249e685c84SJean Delvare */
4251da177e4SLinus Torvalds if (arg)
4261da177e4SLinus Torvalds client->flags |= I2C_CLIENT_PEC;
4271da177e4SLinus Torvalds else
4281da177e4SLinus Torvalds client->flags &= ~I2C_CLIENT_PEC;
4291da177e4SLinus Torvalds return 0;
4301da177e4SLinus Torvalds case I2C_FUNCS:
4311da177e4SLinus Torvalds funcs = i2c_get_functionality(client->adapter);
4322c003e8eSJean Delvare return put_user(funcs, (unsigned long __user *)arg);
4331da177e4SLinus Torvalds
4347d5cb456SAl Viro case I2C_RDWR: {
4357d5cb456SAl Viro struct i2c_rdwr_ioctl_data rdwr_arg;
4367d5cb456SAl Viro struct i2c_msg *rdwr_pa;
4371da177e4SLinus Torvalds
4387d5cb456SAl Viro if (copy_from_user(&rdwr_arg,
4397d5cb456SAl Viro (struct i2c_rdwr_ioctl_data __user *)arg,
4407d5cb456SAl Viro sizeof(rdwr_arg)))
4417d5cb456SAl Viro return -EFAULT;
4421da177e4SLinus Torvalds
44371581562SWolfram Sang if (!rdwr_arg.msgs || rdwr_arg.nmsgs == 0)
44471581562SWolfram Sang return -EINVAL;
44571581562SWolfram Sang
44671581562SWolfram Sang /*
44771581562SWolfram Sang * Put an arbitrary limit on the number of messages that can
44871581562SWolfram Sang * be sent at once
44971581562SWolfram Sang */
4507d5cb456SAl Viro if (rdwr_arg.nmsgs > I2C_RDWR_IOCTL_MAX_MSGS)
4517d5cb456SAl Viro return -EINVAL;
4527d5cb456SAl Viro
453*bef76b85SPhilipp Stanner rdwr_pa = memdup_array_user(rdwr_arg.msgs,
454*bef76b85SPhilipp Stanner rdwr_arg.nmsgs, sizeof(struct i2c_msg));
4557d5cb456SAl Viro if (IS_ERR(rdwr_pa))
4567d5cb456SAl Viro return PTR_ERR(rdwr_pa);
4577d5cb456SAl Viro
4587d5cb456SAl Viro return i2cdev_ioctl_rdwr(client, rdwr_arg.nmsgs, rdwr_pa);
4597d5cb456SAl Viro }
4607d5cb456SAl Viro
4617d5cb456SAl Viro case I2C_SMBUS: {
4627d5cb456SAl Viro struct i2c_smbus_ioctl_data data_arg;
4637d5cb456SAl Viro if (copy_from_user(&data_arg,
4647d5cb456SAl Viro (struct i2c_smbus_ioctl_data __user *) arg,
4657d5cb456SAl Viro sizeof(struct i2c_smbus_ioctl_data)))
4667d5cb456SAl Viro return -EFAULT;
4677d5cb456SAl Viro return i2cdev_ioctl_smbus(client, data_arg.read_write,
4687d5cb456SAl Viro data_arg.command,
4697d5cb456SAl Viro data_arg.size,
4707d5cb456SAl Viro data_arg.data);
4717d5cb456SAl Viro }
47253be7959SDavid Brownell case I2C_RETRIES:
4736ebec961SYi Zeng if (arg > INT_MAX)
4746ebec961SYi Zeng return -EINVAL;
4756ebec961SYi Zeng
47653be7959SDavid Brownell client->adapter->retries = arg;
47753be7959SDavid Brownell break;
47853be7959SDavid Brownell case I2C_TIMEOUT:
4796ebec961SYi Zeng if (arg > INT_MAX)
4806ebec961SYi Zeng return -EINVAL;
4816ebec961SYi Zeng
482cd97f39bSJean Delvare /* For historical reasons, user-space sets the timeout
483cd97f39bSJean Delvare * value in units of 10 ms.
484cd97f39bSJean Delvare */
485cd97f39bSJean Delvare client->adapter->timeout = msecs_to_jiffies(arg * 10);
48653be7959SDavid Brownell break;
4871da177e4SLinus Torvalds default:
48853be7959SDavid Brownell /* NOTE: returning a fault code here could cause trouble
48953be7959SDavid Brownell * in buggy userspace code. Some old kernel bugs returned
49053be7959SDavid Brownell * zero in this case, and userspace code might accidentally
49153be7959SDavid Brownell * have depended on that bug.
49253be7959SDavid Brownell */
49353be7959SDavid Brownell return -ENOTTY;
4941da177e4SLinus Torvalds }
4951da177e4SLinus Torvalds return 0;
4961da177e4SLinus Torvalds }
4971da177e4SLinus Torvalds
4987d5cb456SAl Viro #ifdef CONFIG_COMPAT
4997d5cb456SAl Viro
5007d5cb456SAl Viro struct i2c_smbus_ioctl_data32 {
5017d5cb456SAl Viro u8 read_write;
5027d5cb456SAl Viro u8 command;
5037d5cb456SAl Viro u32 size;
5047d5cb456SAl Viro compat_caddr_t data; /* union i2c_smbus_data *data */
5057d5cb456SAl Viro };
5067d5cb456SAl Viro
5077d5cb456SAl Viro struct i2c_msg32 {
5087d5cb456SAl Viro u16 addr;
5097d5cb456SAl Viro u16 flags;
5107d5cb456SAl Viro u16 len;
5117d5cb456SAl Viro compat_caddr_t buf;
5127d5cb456SAl Viro };
5137d5cb456SAl Viro
5147d5cb456SAl Viro struct i2c_rdwr_ioctl_data32 {
5157d5cb456SAl Viro compat_caddr_t msgs; /* struct i2c_msg __user *msgs */
5167d5cb456SAl Viro u32 nmsgs;
5177d5cb456SAl Viro };
5187d5cb456SAl Viro
compat_i2cdev_ioctl(struct file * file,unsigned int cmd,unsigned long arg)5197d5cb456SAl Viro static long compat_i2cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
5207d5cb456SAl Viro {
5217d5cb456SAl Viro struct i2c_client *client = file->private_data;
5227d5cb456SAl Viro unsigned long funcs;
5237d5cb456SAl Viro switch (cmd) {
5247d5cb456SAl Viro case I2C_FUNCS:
5257d5cb456SAl Viro funcs = i2c_get_functionality(client->adapter);
5267d5cb456SAl Viro return put_user(funcs, (compat_ulong_t __user *)arg);
5277d5cb456SAl Viro case I2C_RDWR: {
5287d5cb456SAl Viro struct i2c_rdwr_ioctl_data32 rdwr_arg;
5293265a7e6SAndreas Hecht struct i2c_msg32 __user *p;
5307d5cb456SAl Viro struct i2c_msg *rdwr_pa;
5317d5cb456SAl Viro int i;
5327d5cb456SAl Viro
5337d5cb456SAl Viro if (copy_from_user(&rdwr_arg,
5347d5cb456SAl Viro (struct i2c_rdwr_ioctl_data32 __user *)arg,
5357d5cb456SAl Viro sizeof(rdwr_arg)))
5367d5cb456SAl Viro return -EFAULT;
5377d5cb456SAl Viro
538bb436283SPavel Skripkin if (!rdwr_arg.msgs || rdwr_arg.nmsgs == 0)
539bb436283SPavel Skripkin return -EINVAL;
540bb436283SPavel Skripkin
5417d5cb456SAl Viro if (rdwr_arg.nmsgs > I2C_RDWR_IOCTL_MAX_MSGS)
5427d5cb456SAl Viro return -EINVAL;
5437d5cb456SAl Viro
5447d5cb456SAl Viro rdwr_pa = kmalloc_array(rdwr_arg.nmsgs, sizeof(struct i2c_msg),
5457d5cb456SAl Viro GFP_KERNEL);
5467d5cb456SAl Viro if (!rdwr_pa)
5477d5cb456SAl Viro return -ENOMEM;
5487d5cb456SAl Viro
5497d5cb456SAl Viro p = compat_ptr(rdwr_arg.msgs);
5507d5cb456SAl Viro for (i = 0; i < rdwr_arg.nmsgs; i++) {
5517d5cb456SAl Viro struct i2c_msg32 umsg;
5527d5cb456SAl Viro if (copy_from_user(&umsg, p + i, sizeof(umsg))) {
5537d5cb456SAl Viro kfree(rdwr_pa);
5547d5cb456SAl Viro return -EFAULT;
5557d5cb456SAl Viro }
5567d5cb456SAl Viro rdwr_pa[i] = (struct i2c_msg) {
5577d5cb456SAl Viro .addr = umsg.addr,
5587d5cb456SAl Viro .flags = umsg.flags,
5597d5cb456SAl Viro .len = umsg.len,
560aef80e2fSAndy Shevchenko .buf = (__force __u8 *)compat_ptr(umsg.buf),
5617d5cb456SAl Viro };
5627d5cb456SAl Viro }
5637d5cb456SAl Viro
5647d5cb456SAl Viro return i2cdev_ioctl_rdwr(client, rdwr_arg.nmsgs, rdwr_pa);
5657d5cb456SAl Viro }
5667d5cb456SAl Viro case I2C_SMBUS: {
5677d5cb456SAl Viro struct i2c_smbus_ioctl_data32 data32;
5687d5cb456SAl Viro if (copy_from_user(&data32,
5697d5cb456SAl Viro (void __user *) arg,
5707d5cb456SAl Viro sizeof(data32)))
5717d5cb456SAl Viro return -EFAULT;
5727d5cb456SAl Viro return i2cdev_ioctl_smbus(client, data32.read_write,
5737d5cb456SAl Viro data32.command,
5747d5cb456SAl Viro data32.size,
5757d5cb456SAl Viro compat_ptr(data32.data));
5767d5cb456SAl Viro }
5777d5cb456SAl Viro default:
5787d5cb456SAl Viro return i2cdev_ioctl(file, cmd, arg);
5797d5cb456SAl Viro }
5807d5cb456SAl Viro }
5817d5cb456SAl Viro #else
5827d5cb456SAl Viro #define compat_i2cdev_ioctl NULL
5837d5cb456SAl Viro #endif
5847d5cb456SAl Viro
i2cdev_open(struct inode * inode,struct file * file)5851da177e4SLinus Torvalds static int i2cdev_open(struct inode *inode, struct file *file)
5861da177e4SLinus Torvalds {
5871da177e4SLinus Torvalds unsigned int minor = iminor(inode);
5881da177e4SLinus Torvalds struct i2c_client *client;
5891da177e4SLinus Torvalds struct i2c_adapter *adap;
5901da177e4SLinus Torvalds
5915136ed4fSviresh kumar adap = i2c_get_adapter(minor);
5929669f541SVincent Sanders if (!adap)
5939669f541SVincent Sanders return -ENODEV;
5941da177e4SLinus Torvalds
595907135aaSDavid Brownell /* This creates an anonymous i2c_client, which may later be
596907135aaSDavid Brownell * pointed to some address using I2C_SLAVE or I2C_SLAVE_FORCE.
597907135aaSDavid Brownell *
598907135aaSDavid Brownell * This client is ** NEVER REGISTERED ** with the driver model
599907135aaSDavid Brownell * or I2C core code!! It just holds private copies of addressing
600907135aaSDavid Brownell * information and maybe a PEC flag.
601907135aaSDavid Brownell */
60222f76e74SJean Delvare client = kzalloc(sizeof(*client), GFP_KERNEL);
6031da177e4SLinus Torvalds if (!client) {
6041da177e4SLinus Torvalds i2c_put_adapter(adap);
6059669f541SVincent Sanders return -ENOMEM;
6061da177e4SLinus Torvalds }
60722f76e74SJean Delvare snprintf(client->name, I2C_NAME_SIZE, "i2c-dev %d", adap->nr);
6081da177e4SLinus Torvalds
6091da177e4SLinus Torvalds client->adapter = adap;
6101da177e4SLinus Torvalds file->private_data = client;
6111da177e4SLinus Torvalds
6129669f541SVincent Sanders return 0;
6131da177e4SLinus Torvalds }
6141da177e4SLinus Torvalds
i2cdev_release(struct inode * inode,struct file * file)6151da177e4SLinus Torvalds static int i2cdev_release(struct inode *inode, struct file *file)
6161da177e4SLinus Torvalds {
6171da177e4SLinus Torvalds struct i2c_client *client = file->private_data;
6181da177e4SLinus Torvalds
6191da177e4SLinus Torvalds i2c_put_adapter(client->adapter);
6201da177e4SLinus Torvalds kfree(client);
6211da177e4SLinus Torvalds file->private_data = NULL;
6221da177e4SLinus Torvalds
6231da177e4SLinus Torvalds return 0;
6241da177e4SLinus Torvalds }
6251da177e4SLinus Torvalds
6262b8693c0SArjan van de Ven static const struct file_operations i2cdev_fops = {
6271da177e4SLinus Torvalds .owner = THIS_MODULE,
6281da177e4SLinus Torvalds .llseek = no_llseek,
6291da177e4SLinus Torvalds .read = i2cdev_read,
6301da177e4SLinus Torvalds .write = i2cdev_write,
63177e38bffSAlan Cox .unlocked_ioctl = i2cdev_ioctl,
6327d5cb456SAl Viro .compat_ioctl = compat_i2cdev_ioctl,
6331da177e4SLinus Torvalds .open = i2cdev_open,
6341da177e4SLinus Torvalds .release = i2cdev_release,
6351da177e4SLinus Torvalds };
6361da177e4SLinus Torvalds
637907135aaSDavid Brownell /* ------------------------------------------------------------------------- */
638907135aaSDavid Brownell
63979472132SGreg Kroah-Hartman static struct class *i2c_dev_class;
6401da177e4SLinus Torvalds
i2cdev_dev_release(struct device * dev)6411413ef63SKevin Hao static void i2cdev_dev_release(struct device *dev)
6421413ef63SKevin Hao {
6431413ef63SKevin Hao struct i2c_dev *i2c_dev;
6441413ef63SKevin Hao
6451413ef63SKevin Hao i2c_dev = container_of(dev, struct i2c_dev, dev);
6461413ef63SKevin Hao kfree(i2c_dev);
6471413ef63SKevin Hao }
6481413ef63SKevin Hao
i2cdev_attach_adapter(struct device * dev)6499e5f81f9SGeert Uytterhoeven static int i2cdev_attach_adapter(struct device *dev)
6501da177e4SLinus Torvalds {
6519ea3e941SJean Delvare struct i2c_adapter *adap;
6521da177e4SLinus Torvalds struct i2c_dev *i2c_dev;
653defcb46eSJean Delvare int res;
6541da177e4SLinus Torvalds
6559ea3e941SJean Delvare if (dev->type != &i2c_adapter_type)
656cddf70d0SBartosz Golaszewski return NOTIFY_DONE;
6579ea3e941SJean Delvare adap = to_i2c_adapter(dev);
6589ea3e941SJean Delvare
6591da177e4SLinus Torvalds i2c_dev = get_free_i2c_dev(adap);
6601da177e4SLinus Torvalds if (IS_ERR(i2c_dev))
661cddf70d0SBartosz Golaszewski return NOTIFY_DONE;
6621da177e4SLinus Torvalds
663d6760b14SErico Nunes cdev_init(&i2c_dev->cdev, &i2cdev_fops);
664d6760b14SErico Nunes i2c_dev->cdev.owner = THIS_MODULE;
665d6760b14SErico Nunes
6661413ef63SKevin Hao device_initialize(&i2c_dev->dev);
6671413ef63SKevin Hao i2c_dev->dev.devt = MKDEV(I2C_MAJOR, adap->nr);
6681413ef63SKevin Hao i2c_dev->dev.class = i2c_dev_class;
6691413ef63SKevin Hao i2c_dev->dev.parent = &adap->dev;
6701413ef63SKevin Hao i2c_dev->dev.release = i2cdev_dev_release;
671993eb48fSAndy Shevchenko
672993eb48fSAndy Shevchenko res = dev_set_name(&i2c_dev->dev, "i2c-%d", adap->nr);
673993eb48fSAndy Shevchenko if (res)
674993eb48fSAndy Shevchenko goto err_put_i2c_dev;
6751413ef63SKevin Hao
6761413ef63SKevin Hao res = cdev_device_add(&i2c_dev->cdev, &i2c_dev->dev);
677993eb48fSAndy Shevchenko if (res)
678993eb48fSAndy Shevchenko goto err_put_i2c_dev;
679b32d20dcSJean Delvare
680295e0e7bSAndy Shevchenko pr_debug("adapter [%s] registered as minor %d\n", adap->name, adap->nr);
681cddf70d0SBartosz Golaszewski return NOTIFY_OK;
682993eb48fSAndy Shevchenko
683993eb48fSAndy Shevchenko err_put_i2c_dev:
684993eb48fSAndy Shevchenko put_i2c_dev(i2c_dev, false);
685cddf70d0SBartosz Golaszewski return NOTIFY_DONE;
6861da177e4SLinus Torvalds }
6871da177e4SLinus Torvalds
i2cdev_detach_adapter(struct device * dev)6889e5f81f9SGeert Uytterhoeven static int i2cdev_detach_adapter(struct device *dev)
6891da177e4SLinus Torvalds {
6909ea3e941SJean Delvare struct i2c_adapter *adap;
6911da177e4SLinus Torvalds struct i2c_dev *i2c_dev;
6921da177e4SLinus Torvalds
6939ea3e941SJean Delvare if (dev->type != &i2c_adapter_type)
694cddf70d0SBartosz Golaszewski return NOTIFY_DONE;
6959ea3e941SJean Delvare adap = to_i2c_adapter(dev);
6969ea3e941SJean Delvare
6979455e4c9SJean Delvare i2c_dev = i2c_dev_get_by_minor(adap->nr);
698b32d20dcSJean Delvare if (!i2c_dev) /* attach_adapter must have failed */
699cddf70d0SBartosz Golaszewski return NOTIFY_DONE;
7001da177e4SLinus Torvalds
7011413ef63SKevin Hao put_i2c_dev(i2c_dev, true);
7021da177e4SLinus Torvalds
703295e0e7bSAndy Shevchenko pr_debug("adapter [%s] unregistered\n", adap->name);
704cddf70d0SBartosz Golaszewski return NOTIFY_OK;
7051da177e4SLinus Torvalds }
7061da177e4SLinus Torvalds
i2cdev_notifier_call(struct notifier_block * nb,unsigned long action,void * data)707eff245c8SShubhrajyoti D static int i2cdev_notifier_call(struct notifier_block *nb, unsigned long action,
7089ea3e941SJean Delvare void *data)
7099ea3e941SJean Delvare {
7109ea3e941SJean Delvare struct device *dev = data;
7119ea3e941SJean Delvare
7129ea3e941SJean Delvare switch (action) {
7139ea3e941SJean Delvare case BUS_NOTIFY_ADD_DEVICE:
7149e5f81f9SGeert Uytterhoeven return i2cdev_attach_adapter(dev);
7159ea3e941SJean Delvare case BUS_NOTIFY_DEL_DEVICE:
7169e5f81f9SGeert Uytterhoeven return i2cdev_detach_adapter(dev);
7179ea3e941SJean Delvare }
7189ea3e941SJean Delvare
719cddf70d0SBartosz Golaszewski return NOTIFY_DONE;
7209ea3e941SJean Delvare }
7219ea3e941SJean Delvare
7229ea3e941SJean Delvare static struct notifier_block i2cdev_notifier = {
7239ea3e941SJean Delvare .notifier_call = i2cdev_notifier_call,
7241da177e4SLinus Torvalds };
7251da177e4SLinus Torvalds
726907135aaSDavid Brownell /* ------------------------------------------------------------------------- */
727907135aaSDavid Brownell
i2c_dev_attach_adapter(struct device * dev,void * dummy)7289e5f81f9SGeert Uytterhoeven static int __init i2c_dev_attach_adapter(struct device *dev, void *dummy)
7299e5f81f9SGeert Uytterhoeven {
7309e5f81f9SGeert Uytterhoeven i2cdev_attach_adapter(dev);
7319e5f81f9SGeert Uytterhoeven return 0;
7329e5f81f9SGeert Uytterhoeven }
7339e5f81f9SGeert Uytterhoeven
i2c_dev_detach_adapter(struct device * dev,void * dummy)7349e5f81f9SGeert Uytterhoeven static int __exit i2c_dev_detach_adapter(struct device *dev, void *dummy)
7359e5f81f9SGeert Uytterhoeven {
7369e5f81f9SGeert Uytterhoeven i2cdev_detach_adapter(dev);
7379e5f81f9SGeert Uytterhoeven return 0;
7389e5f81f9SGeert Uytterhoeven }
7399e5f81f9SGeert Uytterhoeven
740907135aaSDavid Brownell /*
741907135aaSDavid Brownell * module load/unload record keeping
742907135aaSDavid Brownell */
743907135aaSDavid Brownell
i2c_dev_init(void)7441da177e4SLinus Torvalds static int __init i2c_dev_init(void)
7451da177e4SLinus Torvalds {
7461da177e4SLinus Torvalds int res;
7471da177e4SLinus Torvalds
748295e0e7bSAndy Shevchenko pr_info("i2c /dev entries driver\n");
7491da177e4SLinus Torvalds
750d6760b14SErico Nunes res = register_chrdev_region(MKDEV(I2C_MAJOR, 0), I2C_MINORS, "i2c");
7511da177e4SLinus Torvalds if (res)
7521da177e4SLinus Torvalds goto out;
7531da177e4SLinus Torvalds
7541aaba11dSGreg Kroah-Hartman i2c_dev_class = class_create("i2c-dev");
755e74783ecSSven Wegener if (IS_ERR(i2c_dev_class)) {
756e74783ecSSven Wegener res = PTR_ERR(i2c_dev_class);
7571da177e4SLinus Torvalds goto out_unreg_chrdev;
758e74783ecSSven Wegener }
75945f176aeSGuenter Roeck i2c_dev_class->dev_groups = i2c_groups;
7601da177e4SLinus Torvalds
7619ea3e941SJean Delvare /* Keep track of adapters which will be added or removed later */
7629ea3e941SJean Delvare res = bus_register_notifier(&i2c_bus_type, &i2cdev_notifier);
7631da177e4SLinus Torvalds if (res)
7641da177e4SLinus Torvalds goto out_unreg_class;
7651da177e4SLinus Torvalds
7669ea3e941SJean Delvare /* Bind to already existing adapters right away */
7679e5f81f9SGeert Uytterhoeven i2c_for_each_dev(NULL, i2c_dev_attach_adapter);
7689ea3e941SJean Delvare
7691da177e4SLinus Torvalds return 0;
7701da177e4SLinus Torvalds
7711da177e4SLinus Torvalds out_unreg_class:
77279472132SGreg Kroah-Hartman class_destroy(i2c_dev_class);
7731da177e4SLinus Torvalds out_unreg_chrdev:
774d6760b14SErico Nunes unregister_chrdev_region(MKDEV(I2C_MAJOR, 0), I2C_MINORS);
7751da177e4SLinus Torvalds out:
776295e0e7bSAndy Shevchenko pr_err("Driver Initialisation failed\n");
7771da177e4SLinus Torvalds return res;
7781da177e4SLinus Torvalds }
7791da177e4SLinus Torvalds
i2c_dev_exit(void)7801da177e4SLinus Torvalds static void __exit i2c_dev_exit(void)
7811da177e4SLinus Torvalds {
7829ea3e941SJean Delvare bus_unregister_notifier(&i2c_bus_type, &i2cdev_notifier);
7839e5f81f9SGeert Uytterhoeven i2c_for_each_dev(NULL, i2c_dev_detach_adapter);
78479472132SGreg Kroah-Hartman class_destroy(i2c_dev_class);
785d6760b14SErico Nunes unregister_chrdev_region(MKDEV(I2C_MAJOR, 0), I2C_MINORS);
7861da177e4SLinus Torvalds }
7871da177e4SLinus Torvalds
788f80531c8SJarkko Nikula MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
789f80531c8SJarkko Nikula MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
7901da177e4SLinus Torvalds MODULE_DESCRIPTION("I2C /dev entries driver");
7911da177e4SLinus Torvalds MODULE_LICENSE("GPL");
7921da177e4SLinus Torvalds
7931da177e4SLinus Torvalds module_init(i2c_dev_init);
7941da177e4SLinus Torvalds module_exit(i2c_dev_exit);
795