diff options
Diffstat (limited to 'drivers/i2c/i2c-dev.c')
| -rw-r--r-- | drivers/i2c/i2c-dev.c | 72 |
1 files changed, 35 insertions, 37 deletions
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c index 3f869033ed70..ac5bd2a7ca99 100644 --- a/drivers/i2c/i2c-dev.c +++ b/drivers/i2c/i2c-dev.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | i2c-dev.c - i2c-bus driver, char device interface | 2 | i2c-dev.c - i2c-bus driver, char device interface |
| 3 | 3 | ||
| 4 | Copyright (C) 1995-97 Simon G. Vogl | 4 | Copyright (C) 1995-97 Simon G. Vogl |
| 5 | Copyright (C) 1998-99 Frodo Looijaard <frodol@dds.nl> | 5 | Copyright (C) 1998-99 Frodo Looijaard <frodol@dds.nl> |
| @@ -42,7 +42,7 @@ static struct i2c_driver i2cdev_driver; | |||
| 42 | struct i2c_dev { | 42 | struct i2c_dev { |
| 43 | struct list_head list; | 43 | struct list_head list; |
| 44 | struct i2c_adapter *adap; | 44 | struct i2c_adapter *adap; |
| 45 | struct class_device *class_dev; | 45 | struct device *dev; |
| 46 | }; | 46 | }; |
| 47 | 47 | ||
| 48 | #define I2C_MINORS 256 | 48 | #define I2C_MINORS 256 |
| @@ -90,17 +90,19 @@ static void return_i2c_dev(struct i2c_dev *i2c_dev) | |||
| 90 | spin_lock(&i2c_dev_list_lock); | 90 | spin_lock(&i2c_dev_list_lock); |
| 91 | list_del(&i2c_dev->list); | 91 | list_del(&i2c_dev->list); |
| 92 | spin_unlock(&i2c_dev_list_lock); | 92 | spin_unlock(&i2c_dev_list_lock); |
| 93 | kfree(i2c_dev); | ||
| 93 | } | 94 | } |
| 94 | 95 | ||
| 95 | static ssize_t show_adapter_name(struct class_device *class_dev, char *buf) | 96 | static ssize_t show_adapter_name(struct device *dev, |
| 97 | struct device_attribute *attr, char *buf) | ||
| 96 | { | 98 | { |
| 97 | struct i2c_dev *i2c_dev = i2c_dev_get_by_minor(MINOR(class_dev->devt)); | 99 | struct i2c_dev *i2c_dev = i2c_dev_get_by_minor(MINOR(dev->devt)); |
| 98 | 100 | ||
| 99 | if (!i2c_dev) | 101 | if (!i2c_dev) |
| 100 | return -ENODEV; | 102 | return -ENODEV; |
| 101 | return sprintf(buf, "%s\n", i2c_dev->adap->name); | 103 | return sprintf(buf, "%s\n", i2c_dev->adap->name); |
| 102 | } | 104 | } |
| 103 | static CLASS_DEVICE_ATTR(name, S_IRUGO, show_adapter_name, NULL); | 105 | static DEVICE_ATTR(name, S_IRUGO, show_adapter_name, NULL); |
| 104 | 106 | ||
| 105 | static ssize_t i2cdev_read (struct file *file, char __user *buf, size_t count, | 107 | static ssize_t i2cdev_read (struct file *file, char __user *buf, size_t count, |
| 106 | loff_t *offset) | 108 | loff_t *offset) |
| @@ -118,7 +120,7 @@ static ssize_t i2cdev_read (struct file *file, char __user *buf, size_t count, | |||
| 118 | return -ENOMEM; | 120 | return -ENOMEM; |
| 119 | 121 | ||
| 120 | pr_debug("i2c-dev: i2c-%d reading %zd bytes.\n", | 122 | pr_debug("i2c-dev: i2c-%d reading %zd bytes.\n", |
| 121 | iminor(file->f_dentry->d_inode), count); | 123 | iminor(file->f_path.dentry->d_inode), count); |
| 122 | 124 | ||
| 123 | ret = i2c_master_recv(client,tmp,count); | 125 | ret = i2c_master_recv(client,tmp,count); |
| 124 | if (ret >= 0) | 126 | if (ret >= 0) |
| @@ -146,7 +148,7 @@ static ssize_t i2cdev_write (struct file *file, const char __user *buf, size_t c | |||
| 146 | } | 148 | } |
| 147 | 149 | ||
| 148 | pr_debug("i2c-dev: i2c-%d writing %zd bytes.\n", | 150 | pr_debug("i2c-dev: i2c-%d writing %zd bytes.\n", |
| 149 | iminor(file->f_dentry->d_inode), count); | 151 | iminor(file->f_path.dentry->d_inode), count); |
| 150 | 152 | ||
| 151 | ret = i2c_master_send(client,tmp,count); | 153 | ret = i2c_master_send(client,tmp,count); |
| 152 | kfree(tmp); | 154 | kfree(tmp); |
| @@ -171,7 +173,7 @@ static int i2cdev_ioctl(struct inode *inode, struct file *file, | |||
| 171 | switch ( cmd ) { | 173 | switch ( cmd ) { |
| 172 | case I2C_SLAVE: | 174 | case I2C_SLAVE: |
| 173 | case I2C_SLAVE_FORCE: | 175 | case I2C_SLAVE_FORCE: |
| 174 | if ((arg > 0x3ff) || | 176 | if ((arg > 0x3ff) || |
| 175 | (((client->flags & I2C_M_TEN) == 0) && arg > 0x7f)) | 177 | (((client->flags & I2C_M_TEN) == 0) && arg > 0x7f)) |
| 176 | return -EINVAL; | 178 | return -EINVAL; |
| 177 | if ((cmd == I2C_SLAVE) && i2c_check_addr(client->adapter,arg)) | 179 | if ((cmd == I2C_SLAVE) && i2c_check_addr(client->adapter,arg)) |
| @@ -192,12 +194,11 @@ static int i2cdev_ioctl(struct inode *inode, struct file *file, | |||
| 192 | return 0; | 194 | return 0; |
| 193 | case I2C_FUNCS: | 195 | case I2C_FUNCS: |
| 194 | funcs = i2c_get_functionality(client->adapter); | 196 | funcs = i2c_get_functionality(client->adapter); |
| 195 | return (copy_to_user((unsigned long __user *)arg, &funcs, | 197 | return put_user(funcs, (unsigned long __user *)arg); |
| 196 | sizeof(unsigned long)))?-EFAULT:0; | ||
| 197 | 198 | ||
| 198 | case I2C_RDWR: | 199 | case I2C_RDWR: |
| 199 | if (copy_from_user(&rdwr_arg, | 200 | if (copy_from_user(&rdwr_arg, |
| 200 | (struct i2c_rdwr_ioctl_data __user *)arg, | 201 | (struct i2c_rdwr_ioctl_data __user *)arg, |
| 201 | sizeof(rdwr_arg))) | 202 | sizeof(rdwr_arg))) |
| 202 | return -EFAULT; | 203 | return -EFAULT; |
| 203 | 204 | ||
| @@ -205,9 +206,9 @@ static int i2cdev_ioctl(struct inode *inode, struct file *file, | |||
| 205 | * be sent at once */ | 206 | * be sent at once */ |
| 206 | if (rdwr_arg.nmsgs > I2C_RDRW_IOCTL_MAX_MSGS) | 207 | if (rdwr_arg.nmsgs > I2C_RDRW_IOCTL_MAX_MSGS) |
| 207 | return -EINVAL; | 208 | return -EINVAL; |
| 208 | 209 | ||
| 209 | rdwr_pa = (struct i2c_msg *) | 210 | rdwr_pa = (struct i2c_msg *) |
| 210 | kmalloc(rdwr_arg.nmsgs * sizeof(struct i2c_msg), | 211 | kmalloc(rdwr_arg.nmsgs * sizeof(struct i2c_msg), |
| 211 | GFP_KERNEL); | 212 | GFP_KERNEL); |
| 212 | 213 | ||
| 213 | if (rdwr_pa == NULL) return -ENOMEM; | 214 | if (rdwr_pa == NULL) return -ENOMEM; |
| @@ -277,9 +278,9 @@ static int i2cdev_ioctl(struct inode *inode, struct file *file, | |||
| 277 | (struct i2c_smbus_ioctl_data __user *) arg, | 278 | (struct i2c_smbus_ioctl_data __user *) arg, |
| 278 | sizeof(struct i2c_smbus_ioctl_data))) | 279 | sizeof(struct i2c_smbus_ioctl_data))) |
| 279 | return -EFAULT; | 280 | return -EFAULT; |
| 280 | if ((data_arg.size != I2C_SMBUS_BYTE) && | 281 | if ((data_arg.size != I2C_SMBUS_BYTE) && |
| 281 | (data_arg.size != I2C_SMBUS_QUICK) && | 282 | (data_arg.size != I2C_SMBUS_QUICK) && |
| 282 | (data_arg.size != I2C_SMBUS_BYTE_DATA) && | 283 | (data_arg.size != I2C_SMBUS_BYTE_DATA) && |
| 283 | (data_arg.size != I2C_SMBUS_WORD_DATA) && | 284 | (data_arg.size != I2C_SMBUS_WORD_DATA) && |
| 284 | (data_arg.size != I2C_SMBUS_PROC_CALL) && | 285 | (data_arg.size != I2C_SMBUS_PROC_CALL) && |
| 285 | (data_arg.size != I2C_SMBUS_BLOCK_DATA) && | 286 | (data_arg.size != I2C_SMBUS_BLOCK_DATA) && |
| @@ -290,11 +291,11 @@ static int i2cdev_ioctl(struct inode *inode, struct file *file, | |||
| 290 | data_arg.size); | 291 | data_arg.size); |
| 291 | return -EINVAL; | 292 | return -EINVAL; |
| 292 | } | 293 | } |
| 293 | /* Note that I2C_SMBUS_READ and I2C_SMBUS_WRITE are 0 and 1, | 294 | /* Note that I2C_SMBUS_READ and I2C_SMBUS_WRITE are 0 and 1, |
| 294 | so the check is valid if size==I2C_SMBUS_QUICK too. */ | 295 | so the check is valid if size==I2C_SMBUS_QUICK too. */ |
| 295 | if ((data_arg.read_write != I2C_SMBUS_READ) && | 296 | if ((data_arg.read_write != I2C_SMBUS_READ) && |
| 296 | (data_arg.read_write != I2C_SMBUS_WRITE)) { | 297 | (data_arg.read_write != I2C_SMBUS_WRITE)) { |
| 297 | dev_dbg(&client->adapter->dev, | 298 | dev_dbg(&client->adapter->dev, |
| 298 | "read_write out of range (%x) in ioctl I2C_SMBUS.\n", | 299 | "read_write out of range (%x) in ioctl I2C_SMBUS.\n", |
| 299 | data_arg.read_write); | 300 | data_arg.read_write); |
| 300 | return -EINVAL; | 301 | return -EINVAL; |
| @@ -303,7 +304,7 @@ static int i2cdev_ioctl(struct inode *inode, struct file *file, | |||
| 303 | /* Note that command values are always valid! */ | 304 | /* Note that command values are always valid! */ |
| 304 | 305 | ||
| 305 | if ((data_arg.size == I2C_SMBUS_QUICK) || | 306 | if ((data_arg.size == I2C_SMBUS_QUICK) || |
| 306 | ((data_arg.size == I2C_SMBUS_BYTE) && | 307 | ((data_arg.size == I2C_SMBUS_BYTE) && |
| 307 | (data_arg.read_write == I2C_SMBUS_WRITE))) | 308 | (data_arg.read_write == I2C_SMBUS_WRITE))) |
| 308 | /* These are special: we do not use data */ | 309 | /* These are special: we do not use data */ |
| 309 | return i2c_smbus_xfer(client->adapter, client->addr, | 310 | return i2c_smbus_xfer(client->adapter, client->addr, |
| @@ -321,14 +322,14 @@ static int i2cdev_ioctl(struct inode *inode, struct file *file, | |||
| 321 | if ((data_arg.size == I2C_SMBUS_BYTE_DATA) || | 322 | if ((data_arg.size == I2C_SMBUS_BYTE_DATA) || |
| 322 | (data_arg.size == I2C_SMBUS_BYTE)) | 323 | (data_arg.size == I2C_SMBUS_BYTE)) |
| 323 | datasize = sizeof(data_arg.data->byte); | 324 | datasize = sizeof(data_arg.data->byte); |
| 324 | else if ((data_arg.size == I2C_SMBUS_WORD_DATA) || | 325 | else if ((data_arg.size == I2C_SMBUS_WORD_DATA) || |
| 325 | (data_arg.size == I2C_SMBUS_PROC_CALL)) | 326 | (data_arg.size == I2C_SMBUS_PROC_CALL)) |
| 326 | datasize = sizeof(data_arg.data->word); | 327 | datasize = sizeof(data_arg.data->word); |
| 327 | else /* size == smbus block, i2c block, or block proc. call */ | 328 | else /* size == smbus block, i2c block, or block proc. call */ |
| 328 | datasize = sizeof(data_arg.data->block); | 329 | datasize = sizeof(data_arg.data->block); |
| 329 | 330 | ||
| 330 | if ((data_arg.size == I2C_SMBUS_PROC_CALL) || | 331 | if ((data_arg.size == I2C_SMBUS_PROC_CALL) || |
| 331 | (data_arg.size == I2C_SMBUS_BLOCK_PROC_CALL) || | 332 | (data_arg.size == I2C_SMBUS_BLOCK_PROC_CALL) || |
| 332 | (data_arg.read_write == I2C_SMBUS_WRITE)) { | 333 | (data_arg.read_write == I2C_SMBUS_WRITE)) { |
| 333 | if (copy_from_user(&temp, data_arg.data, datasize)) | 334 | if (copy_from_user(&temp, data_arg.data, datasize)) |
| 334 | return -EFAULT; | 335 | return -EFAULT; |
| @@ -336,8 +337,8 @@ static int i2cdev_ioctl(struct inode *inode, struct file *file, | |||
| 336 | res = i2c_smbus_xfer(client->adapter,client->addr,client->flags, | 337 | res = i2c_smbus_xfer(client->adapter,client->addr,client->flags, |
| 337 | data_arg.read_write, | 338 | data_arg.read_write, |
| 338 | data_arg.command,data_arg.size,&temp); | 339 | data_arg.command,data_arg.size,&temp); |
| 339 | if (! res && ((data_arg.size == I2C_SMBUS_PROC_CALL) || | 340 | if (! res && ((data_arg.size == I2C_SMBUS_PROC_CALL) || |
| 340 | (data_arg.size == I2C_SMBUS_BLOCK_PROC_CALL) || | 341 | (data_arg.size == I2C_SMBUS_BLOCK_PROC_CALL) || |
| 341 | (data_arg.read_write == I2C_SMBUS_READ))) { | 342 | (data_arg.read_write == I2C_SMBUS_READ))) { |
| 342 | if (copy_to_user(data_arg.data, &temp, datasize)) | 343 | if (copy_to_user(data_arg.data, &temp, datasize)) |
| 343 | return -EFAULT; | 344 | return -EFAULT; |
| @@ -413,15 +414,14 @@ static int i2cdev_attach_adapter(struct i2c_adapter *adap) | |||
| 413 | return PTR_ERR(i2c_dev); | 414 | return PTR_ERR(i2c_dev); |
| 414 | 415 | ||
| 415 | /* register this i2c device with the driver core */ | 416 | /* register this i2c device with the driver core */ |
| 416 | i2c_dev->class_dev = class_device_create(i2c_dev_class, NULL, | 417 | i2c_dev->dev = device_create(i2c_dev_class, &adap->dev, |
| 417 | MKDEV(I2C_MAJOR, adap->nr), | 418 | MKDEV(I2C_MAJOR, adap->nr), |
| 418 | &adap->dev, "i2c-%d", | 419 | "i2c-%d", adap->nr); |
| 419 | adap->nr); | 420 | if (IS_ERR(i2c_dev->dev)) { |
| 420 | if (!i2c_dev->class_dev) { | 421 | res = PTR_ERR(i2c_dev->dev); |
| 421 | res = -ENODEV; | ||
| 422 | goto error; | 422 | goto error; |
| 423 | } | 423 | } |
| 424 | res = class_device_create_file(i2c_dev->class_dev, &class_device_attr_name); | 424 | res = device_create_file(i2c_dev->dev, &dev_attr_name); |
| 425 | if (res) | 425 | if (res) |
| 426 | goto error_destroy; | 426 | goto error_destroy; |
| 427 | 427 | ||
| @@ -429,10 +429,9 @@ static int i2cdev_attach_adapter(struct i2c_adapter *adap) | |||
| 429 | adap->name, adap->nr); | 429 | adap->name, adap->nr); |
| 430 | return 0; | 430 | return 0; |
| 431 | error_destroy: | 431 | error_destroy: |
| 432 | class_device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, adap->nr)); | 432 | device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, adap->nr)); |
| 433 | error: | 433 | error: |
| 434 | return_i2c_dev(i2c_dev); | 434 | return_i2c_dev(i2c_dev); |
| 435 | kfree(i2c_dev); | ||
| 436 | return res; | 435 | return res; |
| 437 | } | 436 | } |
| 438 | 437 | ||
| @@ -444,10 +443,9 @@ static int i2cdev_detach_adapter(struct i2c_adapter *adap) | |||
| 444 | if (!i2c_dev) /* attach_adapter must have failed */ | 443 | if (!i2c_dev) /* attach_adapter must have failed */ |
| 445 | return 0; | 444 | return 0; |
| 446 | 445 | ||
| 447 | class_device_remove_file(i2c_dev->class_dev, &class_device_attr_name); | 446 | device_remove_file(i2c_dev->dev, &dev_attr_name); |
| 448 | return_i2c_dev(i2c_dev); | 447 | return_i2c_dev(i2c_dev); |
| 449 | class_device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, adap->nr)); | 448 | device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, adap->nr)); |
| 450 | kfree(i2c_dev); | ||
| 451 | 449 | ||
| 452 | pr_debug("i2c-dev: adapter [%s] unregistered\n", adap->name); | 450 | pr_debug("i2c-dev: adapter [%s] unregistered\n", adap->name); |
| 453 | return 0; | 451 | return 0; |
