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 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 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 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 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 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 142*97ca843fSJean Delvare /* Adapter must support I2C transfers */ 143*97ca843fSJean Delvare if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) 144*97ca843fSJean Delvare return -EOPNOTSUPP; 145*97ca843fSJean Delvare 1461da177e4SLinus Torvalds if (count > 8192) 1471da177e4SLinus Torvalds count = 8192; 1481da177e4SLinus Torvalds 14986ff25edSGreg Kroah-Hartman tmp = kzalloc(count, GFP_KERNEL); 1501da177e4SLinus Torvalds if (tmp == NULL) 1511da177e4SLinus Torvalds return -ENOMEM; 1521da177e4SLinus Torvalds 153295e0e7bSAndy Shevchenko pr_debug("i2c-%d reading %zu bytes.\n", iminor(file_inode(file)), count); 1541da177e4SLinus Torvalds 1551da177e4SLinus Torvalds ret = i2c_master_recv(client, tmp, count); 1561da177e4SLinus Torvalds if (ret >= 0) 15786ff25edSGreg Kroah-Hartman if (copy_to_user(buf, tmp, ret)) 15886ff25edSGreg Kroah-Hartman ret = -EFAULT; 1591da177e4SLinus Torvalds kfree(tmp); 1601da177e4SLinus Torvalds return ret; 1611da177e4SLinus Torvalds } 1621da177e4SLinus Torvalds 163ae5624fcSFarid Hammane static ssize_t i2cdev_write(struct file *file, const char __user *buf, 164ae5624fcSFarid Hammane size_t count, loff_t *offset) 1651da177e4SLinus Torvalds { 1661da177e4SLinus Torvalds int ret; 1671da177e4SLinus Torvalds char *tmp; 1680be16c30SH Hartley Sweeten struct i2c_client *client = file->private_data; 1691da177e4SLinus Torvalds 170*97ca843fSJean Delvare /* Adapter must support I2C transfers */ 171*97ca843fSJean Delvare if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) 172*97ca843fSJean Delvare return -EOPNOTSUPP; 173*97ca843fSJean Delvare 1741da177e4SLinus Torvalds if (count > 8192) 1751da177e4SLinus Torvalds count = 8192; 1761da177e4SLinus Torvalds 177f1c2e33cSJulia Lawall tmp = memdup_user(buf, count); 178f1c2e33cSJulia Lawall if (IS_ERR(tmp)) 179f1c2e33cSJulia Lawall return PTR_ERR(tmp); 1801da177e4SLinus Torvalds 181295e0e7bSAndy Shevchenko pr_debug("i2c-%d writing %zu bytes.\n", iminor(file_inode(file)), count); 1821da177e4SLinus Torvalds 1831da177e4SLinus Torvalds ret = i2c_master_send(client, tmp, count); 1841da177e4SLinus Torvalds kfree(tmp); 1851da177e4SLinus Torvalds return ret; 1861da177e4SLinus Torvalds } 1871da177e4SLinus Torvalds 1889b766b81SDavid Brownell static int i2cdev_check(struct device *dev, void *addrp) 1899b766b81SDavid Brownell { 1909b766b81SDavid Brownell struct i2c_client *client = i2c_verify_client(dev); 1919b766b81SDavid Brownell 1929b766b81SDavid Brownell if (!client || client->addr != *(unsigned int *)addrp) 1939b766b81SDavid Brownell return 0; 1949b766b81SDavid Brownell 1959b766b81SDavid Brownell return dev->driver ? -EBUSY : 0; 1969b766b81SDavid Brownell } 1979b766b81SDavid Brownell 1980826374bSMichael Lawnick /* walk up mux tree */ 1990826374bSMichael Lawnick static int i2cdev_check_mux_parents(struct i2c_adapter *adapter, int addr) 2000826374bSMichael Lawnick { 20197cc4d49SJean Delvare struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter); 2020826374bSMichael Lawnick int result; 2030826374bSMichael Lawnick 2040826374bSMichael Lawnick result = device_for_each_child(&adapter->dev, &addr, i2cdev_check); 20597cc4d49SJean Delvare if (!result && parent) 20697cc4d49SJean Delvare result = i2cdev_check_mux_parents(parent, addr); 2070826374bSMichael Lawnick 2080826374bSMichael Lawnick return result; 2090826374bSMichael Lawnick } 2100826374bSMichael Lawnick 2110826374bSMichael Lawnick /* recurse down mux tree */ 2120826374bSMichael Lawnick static int i2cdev_check_mux_children(struct device *dev, void *addrp) 2130826374bSMichael Lawnick { 2140826374bSMichael Lawnick int result; 2150826374bSMichael Lawnick 2160826374bSMichael Lawnick if (dev->type == &i2c_adapter_type) 2170826374bSMichael Lawnick result = device_for_each_child(dev, addrp, 2180826374bSMichael Lawnick i2cdev_check_mux_children); 2190826374bSMichael Lawnick else 2200826374bSMichael Lawnick result = i2cdev_check(dev, addrp); 2210826374bSMichael Lawnick 2220826374bSMichael Lawnick return result; 2230826374bSMichael Lawnick } 2240826374bSMichael Lawnick 225bd4217d8SJean Delvare /* This address checking function differs from the one in i2c-core 226bd4217d8SJean Delvare in that it considers an address with a registered device, but no 2279b766b81SDavid Brownell driver bound to it, as NOT busy. */ 228bd4217d8SJean Delvare static int i2cdev_check_addr(struct i2c_adapter *adapter, unsigned int addr) 229bd4217d8SJean Delvare { 23097cc4d49SJean Delvare struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter); 2310826374bSMichael Lawnick int result = 0; 2320826374bSMichael Lawnick 23397cc4d49SJean Delvare if (parent) 23497cc4d49SJean Delvare result = i2cdev_check_mux_parents(parent, addr); 2350826374bSMichael Lawnick 2360826374bSMichael Lawnick if (!result) 2370826374bSMichael Lawnick result = device_for_each_child(&adapter->dev, &addr, 2380826374bSMichael Lawnick i2cdev_check_mux_children); 2390826374bSMichael Lawnick 2400826374bSMichael Lawnick return result; 241bd4217d8SJean Delvare } 242bd4217d8SJean Delvare 243c57d3e7aSJean Delvare static noinline int i2cdev_ioctl_rdwr(struct i2c_client *client, 2447d5cb456SAl Viro unsigned nmsgs, struct i2c_msg *msgs) 245dba7997aSJean Delvare { 246dba7997aSJean Delvare u8 __user **data_ptrs; 247dba7997aSJean Delvare int i, res; 248dba7997aSJean Delvare 249*97ca843fSJean Delvare /* Adapter must support I2C transfers */ 250*97ca843fSJean Delvare if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) 251*97ca843fSJean Delvare return -EOPNOTSUPP; 252*97ca843fSJean Delvare 2536da2ec56SKees Cook data_ptrs = kmalloc_array(nmsgs, sizeof(u8 __user *), GFP_KERNEL); 254dba7997aSJean Delvare if (data_ptrs == NULL) { 2557d5cb456SAl Viro kfree(msgs); 256dba7997aSJean Delvare return -ENOMEM; 257dba7997aSJean Delvare } 258dba7997aSJean Delvare 259dba7997aSJean Delvare res = 0; 2607d5cb456SAl Viro for (i = 0; i < nmsgs; i++) { 261838bfa60SJean Delvare /* Limit the size of the message to a sane amount */ 2627d5cb456SAl Viro if (msgs[i].len > 8192) { 263dba7997aSJean Delvare res = -EINVAL; 264dba7997aSJean Delvare break; 265dba7997aSJean Delvare } 266838bfa60SJean Delvare 2677d5cb456SAl Viro data_ptrs[i] = (u8 __user *)msgs[i].buf; 2687d5cb456SAl Viro msgs[i].buf = memdup_user(data_ptrs[i], msgs[i].len); 2697d5cb456SAl Viro if (IS_ERR(msgs[i].buf)) { 2707d5cb456SAl Viro res = PTR_ERR(msgs[i].buf); 271dba7997aSJean Delvare break; 272dba7997aSJean Delvare } 273978336d4SWolfram Sang /* memdup_user allocates with GFP_KERNEL, so DMA is ok */ 274978336d4SWolfram Sang msgs[i].flags |= I2C_M_DMA_SAFE; 275838bfa60SJean Delvare 276838bfa60SJean Delvare /* 277838bfa60SJean Delvare * If the message length is received from the slave (similar 278838bfa60SJean Delvare * to SMBus block read), we must ensure that the buffer will 279838bfa60SJean Delvare * be large enough to cope with a message length of 280838bfa60SJean Delvare * I2C_SMBUS_BLOCK_MAX as this is the maximum underlying bus 281838bfa60SJean Delvare * drivers allow. The first byte in the buffer must be 282838bfa60SJean Delvare * pre-filled with the number of extra bytes, which must be 283838bfa60SJean Delvare * at least one to hold the message length, but can be 284838bfa60SJean Delvare * greater (for example to account for a checksum byte at 285838bfa60SJean Delvare * the end of the message.) 286838bfa60SJean Delvare */ 2877d5cb456SAl Viro if (msgs[i].flags & I2C_M_RECV_LEN) { 2887d5cb456SAl Viro if (!(msgs[i].flags & I2C_M_RD) || 28923a27722SAlexander Popov msgs[i].len < 1 || msgs[i].buf[0] < 1 || 2907d5cb456SAl Viro msgs[i].len < msgs[i].buf[0] + 291838bfa60SJean Delvare I2C_SMBUS_BLOCK_MAX) { 292a0692f0eSYingjoe Chen i++; 293838bfa60SJean Delvare res = -EINVAL; 294838bfa60SJean Delvare break; 295838bfa60SJean Delvare } 296838bfa60SJean Delvare 2977d5cb456SAl Viro msgs[i].len = msgs[i].buf[0]; 298838bfa60SJean Delvare } 299dba7997aSJean Delvare } 300dba7997aSJean Delvare if (res < 0) { 301dba7997aSJean Delvare int j; 302dba7997aSJean Delvare for (j = 0; j < i; ++j) 3037d5cb456SAl Viro kfree(msgs[j].buf); 304dba7997aSJean Delvare kfree(data_ptrs); 3057d5cb456SAl Viro kfree(msgs); 306dba7997aSJean Delvare return res; 307dba7997aSJean Delvare } 308dba7997aSJean Delvare 3097d5cb456SAl Viro res = i2c_transfer(client->adapter, msgs, nmsgs); 310dba7997aSJean Delvare while (i-- > 0) { 3117d5cb456SAl Viro if (res >= 0 && (msgs[i].flags & I2C_M_RD)) { 3127d5cb456SAl Viro if (copy_to_user(data_ptrs[i], msgs[i].buf, 3137d5cb456SAl Viro msgs[i].len)) 314dba7997aSJean Delvare res = -EFAULT; 315dba7997aSJean Delvare } 3167d5cb456SAl Viro kfree(msgs[i].buf); 317dba7997aSJean Delvare } 318dba7997aSJean Delvare kfree(data_ptrs); 3197d5cb456SAl Viro kfree(msgs); 320dba7997aSJean Delvare return res; 321dba7997aSJean Delvare } 322dba7997aSJean Delvare 323dba7997aSJean Delvare static noinline int i2cdev_ioctl_smbus(struct i2c_client *client, 3247d5cb456SAl Viro u8 read_write, u8 command, u32 size, 3257d5cb456SAl Viro union i2c_smbus_data __user *data) 326dba7997aSJean Delvare { 32730f939feSVlad Tsyrklevich union i2c_smbus_data temp = {}; 328dba7997aSJean Delvare int datasize, res; 329dba7997aSJean Delvare 3307d5cb456SAl Viro if ((size != I2C_SMBUS_BYTE) && 3317d5cb456SAl Viro (size != I2C_SMBUS_QUICK) && 3327d5cb456SAl Viro (size != I2C_SMBUS_BYTE_DATA) && 3337d5cb456SAl Viro (size != I2C_SMBUS_WORD_DATA) && 3347d5cb456SAl Viro (size != I2C_SMBUS_PROC_CALL) && 3357d5cb456SAl Viro (size != I2C_SMBUS_BLOCK_DATA) && 3367d5cb456SAl Viro (size != I2C_SMBUS_I2C_BLOCK_BROKEN) && 3377d5cb456SAl Viro (size != I2C_SMBUS_I2C_BLOCK_DATA) && 3387d5cb456SAl Viro (size != I2C_SMBUS_BLOCK_PROC_CALL)) { 339dba7997aSJean Delvare dev_dbg(&client->adapter->dev, 340dba7997aSJean Delvare "size out of range (%x) in ioctl I2C_SMBUS.\n", 3417d5cb456SAl Viro size); 342dba7997aSJean Delvare return -EINVAL; 343dba7997aSJean Delvare } 344dba7997aSJean Delvare /* Note that I2C_SMBUS_READ and I2C_SMBUS_WRITE are 0 and 1, 345dba7997aSJean Delvare so the check is valid if size==I2C_SMBUS_QUICK too. */ 3467d5cb456SAl Viro if ((read_write != I2C_SMBUS_READ) && 3477d5cb456SAl Viro (read_write != I2C_SMBUS_WRITE)) { 348dba7997aSJean Delvare dev_dbg(&client->adapter->dev, 349dba7997aSJean Delvare "read_write out of range (%x) in ioctl I2C_SMBUS.\n", 3507d5cb456SAl Viro read_write); 351dba7997aSJean Delvare return -EINVAL; 352dba7997aSJean Delvare } 353dba7997aSJean Delvare 354dba7997aSJean Delvare /* Note that command values are always valid! */ 355dba7997aSJean Delvare 3567d5cb456SAl Viro if ((size == I2C_SMBUS_QUICK) || 3577d5cb456SAl Viro ((size == I2C_SMBUS_BYTE) && 3587d5cb456SAl Viro (read_write == I2C_SMBUS_WRITE))) 359dba7997aSJean Delvare /* These are special: we do not use data */ 360dba7997aSJean Delvare return i2c_smbus_xfer(client->adapter, client->addr, 3617d5cb456SAl Viro client->flags, read_write, 3627d5cb456SAl Viro command, size, NULL); 363dba7997aSJean Delvare 3647d5cb456SAl Viro if (data == NULL) { 365dba7997aSJean Delvare dev_dbg(&client->adapter->dev, 366dba7997aSJean Delvare "data is NULL pointer in ioctl I2C_SMBUS.\n"); 367dba7997aSJean Delvare return -EINVAL; 368dba7997aSJean Delvare } 369dba7997aSJean Delvare 3707d5cb456SAl Viro if ((size == I2C_SMBUS_BYTE_DATA) || 3717d5cb456SAl Viro (size == I2C_SMBUS_BYTE)) 3727d5cb456SAl Viro datasize = sizeof(data->byte); 3737d5cb456SAl Viro else if ((size == I2C_SMBUS_WORD_DATA) || 3747d5cb456SAl Viro (size == I2C_SMBUS_PROC_CALL)) 3757d5cb456SAl Viro datasize = sizeof(data->word); 376dba7997aSJean Delvare else /* size == smbus block, i2c block, or block proc. call */ 3777d5cb456SAl Viro datasize = sizeof(data->block); 378dba7997aSJean Delvare 3797d5cb456SAl Viro if ((size == I2C_SMBUS_PROC_CALL) || 3807d5cb456SAl Viro (size == I2C_SMBUS_BLOCK_PROC_CALL) || 3817d5cb456SAl Viro (size == I2C_SMBUS_I2C_BLOCK_DATA) || 3827d5cb456SAl Viro (read_write == I2C_SMBUS_WRITE)) { 3837d5cb456SAl Viro if (copy_from_user(&temp, data, datasize)) 384dba7997aSJean Delvare return -EFAULT; 385dba7997aSJean Delvare } 3867d5cb456SAl Viro if (size == I2C_SMBUS_I2C_BLOCK_BROKEN) { 387dba7997aSJean Delvare /* Convert old I2C block commands to the new 388dba7997aSJean Delvare convention. This preserves binary compatibility. */ 3897d5cb456SAl Viro size = I2C_SMBUS_I2C_BLOCK_DATA; 3907d5cb456SAl Viro if (read_write == I2C_SMBUS_READ) 391dba7997aSJean Delvare temp.block[0] = I2C_SMBUS_BLOCK_MAX; 392dba7997aSJean Delvare } 393dba7997aSJean Delvare res = i2c_smbus_xfer(client->adapter, client->addr, client->flags, 3947d5cb456SAl Viro read_write, command, size, &temp); 3957d5cb456SAl Viro if (!res && ((size == I2C_SMBUS_PROC_CALL) || 3967d5cb456SAl Viro (size == I2C_SMBUS_BLOCK_PROC_CALL) || 3977d5cb456SAl Viro (read_write == I2C_SMBUS_READ))) { 3987d5cb456SAl Viro if (copy_to_user(data, &temp, datasize)) 399dba7997aSJean Delvare return -EFAULT; 400dba7997aSJean Delvare } 401dba7997aSJean Delvare return res; 402dba7997aSJean Delvare } 403dba7997aSJean Delvare 40477e38bffSAlan Cox static long i2cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 4051da177e4SLinus Torvalds { 4060be16c30SH Hartley Sweeten struct i2c_client *client = file->private_data; 4071da177e4SLinus Torvalds unsigned long funcs; 4081da177e4SLinus Torvalds 409e8aafcb2SJean Delvare dev_dbg(&client->adapter->dev, "ioctl, cmd=0x%02x, arg=0x%02lx\n", 410e8aafcb2SJean Delvare cmd, arg); 4111da177e4SLinus Torvalds 4121da177e4SLinus Torvalds switch (cmd) { 4131da177e4SLinus Torvalds case I2C_SLAVE: 4141da177e4SLinus Torvalds case I2C_SLAVE_FORCE: 4151da177e4SLinus Torvalds if ((arg > 0x3ff) || 4161da177e4SLinus Torvalds (((client->flags & I2C_M_TEN) == 0) && arg > 0x7f)) 4171da177e4SLinus Torvalds return -EINVAL; 418bd4217d8SJean Delvare if (cmd == I2C_SLAVE && i2cdev_check_addr(client->adapter, arg)) 4191da177e4SLinus Torvalds return -EBUSY; 420bd4217d8SJean Delvare /* REVISIT: address could become busy later */ 4211da177e4SLinus Torvalds client->addr = arg; 4221da177e4SLinus Torvalds return 0; 4231da177e4SLinus Torvalds case I2C_TENBIT: 4241da177e4SLinus Torvalds if (arg) 4251da177e4SLinus Torvalds client->flags |= I2C_M_TEN; 4261da177e4SLinus Torvalds else 4271da177e4SLinus Torvalds client->flags &= ~I2C_M_TEN; 4281da177e4SLinus Torvalds return 0; 4291da177e4SLinus Torvalds case I2C_PEC: 4309e685c84SJean Delvare /* 4319e685c84SJean Delvare * Setting the PEC flag here won't affect kernel drivers, 4329e685c84SJean Delvare * which will be using the i2c_client node registered with 4339e685c84SJean Delvare * the driver model core. Likewise, when that client has 4349e685c84SJean Delvare * the PEC flag already set, the i2c-dev driver won't see 4359e685c84SJean Delvare * (or use) this setting. 4369e685c84SJean Delvare */ 4371da177e4SLinus Torvalds if (arg) 4381da177e4SLinus Torvalds client->flags |= I2C_CLIENT_PEC; 4391da177e4SLinus Torvalds else 4401da177e4SLinus Torvalds client->flags &= ~I2C_CLIENT_PEC; 4411da177e4SLinus Torvalds return 0; 4421da177e4SLinus Torvalds case I2C_FUNCS: 4431da177e4SLinus Torvalds funcs = i2c_get_functionality(client->adapter); 4442c003e8eSJean Delvare return put_user(funcs, (unsigned long __user *)arg); 4451da177e4SLinus Torvalds 4467d5cb456SAl Viro case I2C_RDWR: { 4477d5cb456SAl Viro struct i2c_rdwr_ioctl_data rdwr_arg; 4487d5cb456SAl Viro struct i2c_msg *rdwr_pa; 4491da177e4SLinus Torvalds 4507d5cb456SAl Viro if (copy_from_user(&rdwr_arg, 4517d5cb456SAl Viro (struct i2c_rdwr_ioctl_data __user *)arg, 4527d5cb456SAl Viro sizeof(rdwr_arg))) 4537d5cb456SAl Viro return -EFAULT; 4541da177e4SLinus Torvalds 45571581562SWolfram Sang if (!rdwr_arg.msgs || rdwr_arg.nmsgs == 0) 45671581562SWolfram Sang return -EINVAL; 45771581562SWolfram Sang 45871581562SWolfram Sang /* 45971581562SWolfram Sang * Put an arbitrary limit on the number of messages that can 46071581562SWolfram Sang * be sent at once 46171581562SWolfram Sang */ 4627d5cb456SAl Viro if (rdwr_arg.nmsgs > I2C_RDWR_IOCTL_MAX_MSGS) 4637d5cb456SAl Viro return -EINVAL; 4647d5cb456SAl Viro 465cc9c5423SPhilipp Stanner rdwr_pa = memdup_array_user(rdwr_arg.msgs, 466cc9c5423SPhilipp Stanner rdwr_arg.nmsgs, sizeof(struct i2c_msg)); 4677d5cb456SAl Viro if (IS_ERR(rdwr_pa)) 4687d5cb456SAl Viro return PTR_ERR(rdwr_pa); 4697d5cb456SAl Viro 4707d5cb456SAl Viro return i2cdev_ioctl_rdwr(client, rdwr_arg.nmsgs, rdwr_pa); 4717d5cb456SAl Viro } 4727d5cb456SAl Viro 4737d5cb456SAl Viro case I2C_SMBUS: { 4747d5cb456SAl Viro struct i2c_smbus_ioctl_data data_arg; 4757d5cb456SAl Viro if (copy_from_user(&data_arg, 4767d5cb456SAl Viro (struct i2c_smbus_ioctl_data __user *) arg, 4777d5cb456SAl Viro sizeof(struct i2c_smbus_ioctl_data))) 4787d5cb456SAl Viro return -EFAULT; 4797d5cb456SAl Viro return i2cdev_ioctl_smbus(client, data_arg.read_write, 4807d5cb456SAl Viro data_arg.command, 4817d5cb456SAl Viro data_arg.size, 4827d5cb456SAl Viro data_arg.data); 4837d5cb456SAl Viro } 48453be7959SDavid Brownell case I2C_RETRIES: 4856ebec961SYi Zeng if (arg > INT_MAX) 4866ebec961SYi Zeng return -EINVAL; 4876ebec961SYi Zeng 48853be7959SDavid Brownell client->adapter->retries = arg; 48953be7959SDavid Brownell break; 49053be7959SDavid Brownell case I2C_TIMEOUT: 4916ebec961SYi Zeng if (arg > INT_MAX) 4926ebec961SYi Zeng return -EINVAL; 4936ebec961SYi Zeng 494cd97f39bSJean Delvare /* For historical reasons, user-space sets the timeout 495cd97f39bSJean Delvare * value in units of 10 ms. 496cd97f39bSJean Delvare */ 497cd97f39bSJean Delvare client->adapter->timeout = msecs_to_jiffies(arg * 10); 49853be7959SDavid Brownell break; 4991da177e4SLinus Torvalds default: 50053be7959SDavid Brownell /* NOTE: returning a fault code here could cause trouble 50153be7959SDavid Brownell * in buggy userspace code. Some old kernel bugs returned 50253be7959SDavid Brownell * zero in this case, and userspace code might accidentally 50353be7959SDavid Brownell * have depended on that bug. 50453be7959SDavid Brownell */ 50553be7959SDavid Brownell return -ENOTTY; 5061da177e4SLinus Torvalds } 5071da177e4SLinus Torvalds return 0; 5081da177e4SLinus Torvalds } 5091da177e4SLinus Torvalds 5107d5cb456SAl Viro #ifdef CONFIG_COMPAT 5117d5cb456SAl Viro 5127d5cb456SAl Viro struct i2c_smbus_ioctl_data32 { 5137d5cb456SAl Viro u8 read_write; 5147d5cb456SAl Viro u8 command; 5157d5cb456SAl Viro u32 size; 5167d5cb456SAl Viro compat_caddr_t data; /* union i2c_smbus_data *data */ 5177d5cb456SAl Viro }; 5187d5cb456SAl Viro 5197d5cb456SAl Viro struct i2c_msg32 { 5207d5cb456SAl Viro u16 addr; 5217d5cb456SAl Viro u16 flags; 5227d5cb456SAl Viro u16 len; 5237d5cb456SAl Viro compat_caddr_t buf; 5247d5cb456SAl Viro }; 5257d5cb456SAl Viro 5267d5cb456SAl Viro struct i2c_rdwr_ioctl_data32 { 5277d5cb456SAl Viro compat_caddr_t msgs; /* struct i2c_msg __user *msgs */ 5287d5cb456SAl Viro u32 nmsgs; 5297d5cb456SAl Viro }; 5307d5cb456SAl Viro 5317d5cb456SAl Viro static long compat_i2cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 5327d5cb456SAl Viro { 5337d5cb456SAl Viro struct i2c_client *client = file->private_data; 5347d5cb456SAl Viro unsigned long funcs; 5357d5cb456SAl Viro switch (cmd) { 5367d5cb456SAl Viro case I2C_FUNCS: 5377d5cb456SAl Viro funcs = i2c_get_functionality(client->adapter); 5387d5cb456SAl Viro return put_user(funcs, (compat_ulong_t __user *)arg); 5397d5cb456SAl Viro case I2C_RDWR: { 5407d5cb456SAl Viro struct i2c_rdwr_ioctl_data32 rdwr_arg; 5413265a7e6SAndreas Hecht struct i2c_msg32 __user *p; 5427d5cb456SAl Viro struct i2c_msg *rdwr_pa; 5437d5cb456SAl Viro int i; 5447d5cb456SAl Viro 5457d5cb456SAl Viro if (copy_from_user(&rdwr_arg, 5467d5cb456SAl Viro (struct i2c_rdwr_ioctl_data32 __user *)arg, 5477d5cb456SAl Viro sizeof(rdwr_arg))) 5487d5cb456SAl Viro return -EFAULT; 5497d5cb456SAl Viro 550bb436283SPavel Skripkin if (!rdwr_arg.msgs || rdwr_arg.nmsgs == 0) 551bb436283SPavel Skripkin return -EINVAL; 552bb436283SPavel Skripkin 5537d5cb456SAl Viro if (rdwr_arg.nmsgs > I2C_RDWR_IOCTL_MAX_MSGS) 5547d5cb456SAl Viro return -EINVAL; 5557d5cb456SAl Viro 5567d5cb456SAl Viro rdwr_pa = kmalloc_array(rdwr_arg.nmsgs, sizeof(struct i2c_msg), 5577d5cb456SAl Viro GFP_KERNEL); 5587d5cb456SAl Viro if (!rdwr_pa) 5597d5cb456SAl Viro return -ENOMEM; 5607d5cb456SAl Viro 5617d5cb456SAl Viro p = compat_ptr(rdwr_arg.msgs); 5627d5cb456SAl Viro for (i = 0; i < rdwr_arg.nmsgs; i++) { 5637d5cb456SAl Viro struct i2c_msg32 umsg; 5647d5cb456SAl Viro if (copy_from_user(&umsg, p + i, sizeof(umsg))) { 5657d5cb456SAl Viro kfree(rdwr_pa); 5667d5cb456SAl Viro return -EFAULT; 5677d5cb456SAl Viro } 5687d5cb456SAl Viro rdwr_pa[i] = (struct i2c_msg) { 5697d5cb456SAl Viro .addr = umsg.addr, 5707d5cb456SAl Viro .flags = umsg.flags, 5717d5cb456SAl Viro .len = umsg.len, 572aef80e2fSAndy Shevchenko .buf = (__force __u8 *)compat_ptr(umsg.buf), 5737d5cb456SAl Viro }; 5747d5cb456SAl Viro } 5757d5cb456SAl Viro 5767d5cb456SAl Viro return i2cdev_ioctl_rdwr(client, rdwr_arg.nmsgs, rdwr_pa); 5777d5cb456SAl Viro } 5787d5cb456SAl Viro case I2C_SMBUS: { 5797d5cb456SAl Viro struct i2c_smbus_ioctl_data32 data32; 5807d5cb456SAl Viro if (copy_from_user(&data32, 5817d5cb456SAl Viro (void __user *) arg, 5827d5cb456SAl Viro sizeof(data32))) 5837d5cb456SAl Viro return -EFAULT; 5847d5cb456SAl Viro return i2cdev_ioctl_smbus(client, data32.read_write, 5857d5cb456SAl Viro data32.command, 5867d5cb456SAl Viro data32.size, 5877d5cb456SAl Viro compat_ptr(data32.data)); 5887d5cb456SAl Viro } 5897d5cb456SAl Viro default: 5907d5cb456SAl Viro return i2cdev_ioctl(file, cmd, arg); 5917d5cb456SAl Viro } 5927d5cb456SAl Viro } 5937d5cb456SAl Viro #else 5947d5cb456SAl Viro #define compat_i2cdev_ioctl NULL 5957d5cb456SAl Viro #endif 5967d5cb456SAl Viro 5971da177e4SLinus Torvalds static int i2cdev_open(struct inode *inode, struct file *file) 5981da177e4SLinus Torvalds { 5991da177e4SLinus Torvalds unsigned int minor = iminor(inode); 6001da177e4SLinus Torvalds struct i2c_client *client; 6011da177e4SLinus Torvalds struct i2c_adapter *adap; 6021da177e4SLinus Torvalds 6035136ed4fSviresh kumar adap = i2c_get_adapter(minor); 6049669f541SVincent Sanders if (!adap) 6059669f541SVincent Sanders return -ENODEV; 6061da177e4SLinus Torvalds 607907135aaSDavid Brownell /* This creates an anonymous i2c_client, which may later be 608907135aaSDavid Brownell * pointed to some address using I2C_SLAVE or I2C_SLAVE_FORCE. 609907135aaSDavid Brownell * 610907135aaSDavid Brownell * This client is ** NEVER REGISTERED ** with the driver model 611907135aaSDavid Brownell * or I2C core code!! It just holds private copies of addressing 612907135aaSDavid Brownell * information and maybe a PEC flag. 613907135aaSDavid Brownell */ 61422f76e74SJean Delvare client = kzalloc(sizeof(*client), GFP_KERNEL); 6151da177e4SLinus Torvalds if (!client) { 6161da177e4SLinus Torvalds i2c_put_adapter(adap); 6179669f541SVincent Sanders return -ENOMEM; 6181da177e4SLinus Torvalds } 61922f76e74SJean Delvare snprintf(client->name, I2C_NAME_SIZE, "i2c-dev %d", adap->nr); 6201da177e4SLinus Torvalds 6211da177e4SLinus Torvalds client->adapter = adap; 6221da177e4SLinus Torvalds file->private_data = client; 6231da177e4SLinus Torvalds 6249669f541SVincent Sanders return 0; 6251da177e4SLinus Torvalds } 6261da177e4SLinus Torvalds 6271da177e4SLinus Torvalds static int i2cdev_release(struct inode *inode, struct file *file) 6281da177e4SLinus Torvalds { 6291da177e4SLinus Torvalds struct i2c_client *client = file->private_data; 6301da177e4SLinus Torvalds 6311da177e4SLinus Torvalds i2c_put_adapter(client->adapter); 6321da177e4SLinus Torvalds kfree(client); 6331da177e4SLinus Torvalds file->private_data = NULL; 6341da177e4SLinus Torvalds 6351da177e4SLinus Torvalds return 0; 6361da177e4SLinus Torvalds } 6371da177e4SLinus Torvalds 6382b8693c0SArjan van de Ven static const struct file_operations i2cdev_fops = { 6391da177e4SLinus Torvalds .owner = THIS_MODULE, 6401da177e4SLinus Torvalds .read = i2cdev_read, 6411da177e4SLinus Torvalds .write = i2cdev_write, 64277e38bffSAlan Cox .unlocked_ioctl = i2cdev_ioctl, 6437d5cb456SAl Viro .compat_ioctl = compat_i2cdev_ioctl, 6441da177e4SLinus Torvalds .open = i2cdev_open, 6451da177e4SLinus Torvalds .release = i2cdev_release, 6461da177e4SLinus Torvalds }; 6471da177e4SLinus Torvalds 648907135aaSDavid Brownell /* ------------------------------------------------------------------------- */ 649907135aaSDavid Brownell 650cdb55bdbSIvan Orlov static const struct class i2c_dev_class = { 651cdb55bdbSIvan Orlov .name = "i2c-dev", 652cdb55bdbSIvan Orlov .dev_groups = i2c_groups, 653cdb55bdbSIvan Orlov }; 6541da177e4SLinus Torvalds 6551413ef63SKevin Hao static void i2cdev_dev_release(struct device *dev) 6561413ef63SKevin Hao { 6571413ef63SKevin Hao struct i2c_dev *i2c_dev; 6581413ef63SKevin Hao 6591413ef63SKevin Hao i2c_dev = container_of(dev, struct i2c_dev, dev); 6601413ef63SKevin Hao kfree(i2c_dev); 6611413ef63SKevin Hao } 6621413ef63SKevin Hao 6639e5f81f9SGeert Uytterhoeven static int i2cdev_attach_adapter(struct device *dev) 6641da177e4SLinus Torvalds { 6659ea3e941SJean Delvare struct i2c_adapter *adap; 6661da177e4SLinus Torvalds struct i2c_dev *i2c_dev; 667defcb46eSJean Delvare int res; 6681da177e4SLinus Torvalds 6699ea3e941SJean Delvare if (dev->type != &i2c_adapter_type) 670cddf70d0SBartosz Golaszewski return NOTIFY_DONE; 6719ea3e941SJean Delvare adap = to_i2c_adapter(dev); 6729ea3e941SJean Delvare 6731da177e4SLinus Torvalds i2c_dev = get_free_i2c_dev(adap); 6741da177e4SLinus Torvalds if (IS_ERR(i2c_dev)) 675cddf70d0SBartosz Golaszewski return NOTIFY_DONE; 6761da177e4SLinus Torvalds 677d6760b14SErico Nunes cdev_init(&i2c_dev->cdev, &i2cdev_fops); 678d6760b14SErico Nunes i2c_dev->cdev.owner = THIS_MODULE; 679d6760b14SErico Nunes 6801413ef63SKevin Hao device_initialize(&i2c_dev->dev); 6811413ef63SKevin Hao i2c_dev->dev.devt = MKDEV(I2C_MAJOR, adap->nr); 682cdb55bdbSIvan Orlov i2c_dev->dev.class = &i2c_dev_class; 6831413ef63SKevin Hao i2c_dev->dev.parent = &adap->dev; 6841413ef63SKevin Hao i2c_dev->dev.release = i2cdev_dev_release; 685993eb48fSAndy Shevchenko 686993eb48fSAndy Shevchenko res = dev_set_name(&i2c_dev->dev, "i2c-%d", adap->nr); 687993eb48fSAndy Shevchenko if (res) 688993eb48fSAndy Shevchenko goto err_put_i2c_dev; 6891413ef63SKevin Hao 6901413ef63SKevin Hao res = cdev_device_add(&i2c_dev->cdev, &i2c_dev->dev); 691993eb48fSAndy Shevchenko if (res) 692993eb48fSAndy Shevchenko goto err_put_i2c_dev; 693b32d20dcSJean Delvare 694295e0e7bSAndy Shevchenko pr_debug("adapter [%s] registered as minor %d\n", adap->name, adap->nr); 695cddf70d0SBartosz Golaszewski return NOTIFY_OK; 696993eb48fSAndy Shevchenko 697993eb48fSAndy Shevchenko err_put_i2c_dev: 698993eb48fSAndy Shevchenko put_i2c_dev(i2c_dev, false); 699cddf70d0SBartosz Golaszewski return NOTIFY_DONE; 7001da177e4SLinus Torvalds } 7011da177e4SLinus Torvalds 7029e5f81f9SGeert Uytterhoeven static int i2cdev_detach_adapter(struct device *dev) 7031da177e4SLinus Torvalds { 7049ea3e941SJean Delvare struct i2c_adapter *adap; 7051da177e4SLinus Torvalds struct i2c_dev *i2c_dev; 7061da177e4SLinus Torvalds 7079ea3e941SJean Delvare if (dev->type != &i2c_adapter_type) 708cddf70d0SBartosz Golaszewski return NOTIFY_DONE; 7099ea3e941SJean Delvare adap = to_i2c_adapter(dev); 7109ea3e941SJean Delvare 7119455e4c9SJean Delvare i2c_dev = i2c_dev_get_by_minor(adap->nr); 712b32d20dcSJean Delvare if (!i2c_dev) /* attach_adapter must have failed */ 713cddf70d0SBartosz Golaszewski return NOTIFY_DONE; 7141da177e4SLinus Torvalds 7151413ef63SKevin Hao put_i2c_dev(i2c_dev, true); 7161da177e4SLinus Torvalds 717295e0e7bSAndy Shevchenko pr_debug("adapter [%s] unregistered\n", adap->name); 718cddf70d0SBartosz Golaszewski return NOTIFY_OK; 7191da177e4SLinus Torvalds } 7201da177e4SLinus Torvalds 721eff245c8SShubhrajyoti D static int i2cdev_notifier_call(struct notifier_block *nb, unsigned long action, 7229ea3e941SJean Delvare void *data) 7239ea3e941SJean Delvare { 7249ea3e941SJean Delvare struct device *dev = data; 7259ea3e941SJean Delvare 7269ea3e941SJean Delvare switch (action) { 7279ea3e941SJean Delvare case BUS_NOTIFY_ADD_DEVICE: 7289e5f81f9SGeert Uytterhoeven return i2cdev_attach_adapter(dev); 7299ea3e941SJean Delvare case BUS_NOTIFY_DEL_DEVICE: 7309e5f81f9SGeert Uytterhoeven return i2cdev_detach_adapter(dev); 7319ea3e941SJean Delvare } 7329ea3e941SJean Delvare 733cddf70d0SBartosz Golaszewski return NOTIFY_DONE; 7349ea3e941SJean Delvare } 7359ea3e941SJean Delvare 7369ea3e941SJean Delvare static struct notifier_block i2cdev_notifier = { 7379ea3e941SJean Delvare .notifier_call = i2cdev_notifier_call, 7381da177e4SLinus Torvalds }; 7391da177e4SLinus Torvalds 740907135aaSDavid Brownell /* ------------------------------------------------------------------------- */ 741907135aaSDavid Brownell 7429e5f81f9SGeert Uytterhoeven static int __init i2c_dev_attach_adapter(struct device *dev, void *dummy) 7439e5f81f9SGeert Uytterhoeven { 7449e5f81f9SGeert Uytterhoeven i2cdev_attach_adapter(dev); 7459e5f81f9SGeert Uytterhoeven return 0; 7469e5f81f9SGeert Uytterhoeven } 7479e5f81f9SGeert Uytterhoeven 7489e5f81f9SGeert Uytterhoeven static int __exit i2c_dev_detach_adapter(struct device *dev, void *dummy) 7499e5f81f9SGeert Uytterhoeven { 7509e5f81f9SGeert Uytterhoeven i2cdev_detach_adapter(dev); 7519e5f81f9SGeert Uytterhoeven return 0; 7529e5f81f9SGeert Uytterhoeven } 7539e5f81f9SGeert Uytterhoeven 754907135aaSDavid Brownell /* 755907135aaSDavid Brownell * module load/unload record keeping 756907135aaSDavid Brownell */ 757907135aaSDavid Brownell 7581da177e4SLinus Torvalds static int __init i2c_dev_init(void) 7591da177e4SLinus Torvalds { 7601da177e4SLinus Torvalds int res; 7611da177e4SLinus Torvalds 762295e0e7bSAndy Shevchenko pr_info("i2c /dev entries driver\n"); 7631da177e4SLinus Torvalds 764d6760b14SErico Nunes res = register_chrdev_region(MKDEV(I2C_MAJOR, 0), I2C_MINORS, "i2c"); 7651da177e4SLinus Torvalds if (res) 7661da177e4SLinus Torvalds goto out; 7671da177e4SLinus Torvalds 768cdb55bdbSIvan Orlov res = class_register(&i2c_dev_class); 769cdb55bdbSIvan Orlov if (res) 7701da177e4SLinus Torvalds goto out_unreg_chrdev; 7711da177e4SLinus Torvalds 7729ea3e941SJean Delvare /* Keep track of adapters which will be added or removed later */ 7739ea3e941SJean Delvare res = bus_register_notifier(&i2c_bus_type, &i2cdev_notifier); 7741da177e4SLinus Torvalds if (res) 7751da177e4SLinus Torvalds goto out_unreg_class; 7761da177e4SLinus Torvalds 7779ea3e941SJean Delvare /* Bind to already existing adapters right away */ 7789e5f81f9SGeert Uytterhoeven i2c_for_each_dev(NULL, i2c_dev_attach_adapter); 7799ea3e941SJean Delvare 7801da177e4SLinus Torvalds return 0; 7811da177e4SLinus Torvalds 7821da177e4SLinus Torvalds out_unreg_class: 783cdb55bdbSIvan Orlov class_unregister(&i2c_dev_class); 7841da177e4SLinus Torvalds out_unreg_chrdev: 785d6760b14SErico Nunes unregister_chrdev_region(MKDEV(I2C_MAJOR, 0), I2C_MINORS); 7861da177e4SLinus Torvalds out: 787295e0e7bSAndy Shevchenko pr_err("Driver Initialisation failed\n"); 7881da177e4SLinus Torvalds return res; 7891da177e4SLinus Torvalds } 7901da177e4SLinus Torvalds 7911da177e4SLinus Torvalds static void __exit i2c_dev_exit(void) 7921da177e4SLinus Torvalds { 7939ea3e941SJean Delvare bus_unregister_notifier(&i2c_bus_type, &i2cdev_notifier); 7949e5f81f9SGeert Uytterhoeven i2c_for_each_dev(NULL, i2c_dev_detach_adapter); 795cdb55bdbSIvan Orlov class_unregister(&i2c_dev_class); 796d6760b14SErico Nunes unregister_chrdev_region(MKDEV(I2C_MAJOR, 0), I2C_MINORS); 7971da177e4SLinus Torvalds } 7981da177e4SLinus Torvalds 799f80531c8SJarkko Nikula MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>"); 800f80531c8SJarkko Nikula MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>"); 8011da177e4SLinus Torvalds MODULE_DESCRIPTION("I2C /dev entries driver"); 8021da177e4SLinus Torvalds MODULE_LICENSE("GPL"); 8031da177e4SLinus Torvalds 8041da177e4SLinus Torvalds module_init(i2c_dev_init); 8051da177e4SLinus Torvalds module_exit(i2c_dev_exit); 806