diff options
Diffstat (limited to 'drivers/i2c/i2c-dev.c')
-rw-r--r-- | drivers/i2c/i2c-dev.c | 40 |
1 files changed, 21 insertions, 19 deletions
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c index d34c14c81c29..9d55c6383b23 100644 --- a/drivers/i2c/i2c-dev.c +++ b/drivers/i2c/i2c-dev.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/list.h> | 34 | #include <linux/list.h> |
35 | #include <linux/i2c.h> | 35 | #include <linux/i2c.h> |
36 | #include <linux/i2c-dev.h> | 36 | #include <linux/i2c-dev.h> |
37 | #include <linux/smp_lock.h> | ||
37 | #include <asm/uaccess.h> | 38 | #include <asm/uaccess.h> |
38 | 39 | ||
39 | static struct i2c_driver i2cdev_driver; | 40 | static struct i2c_driver i2cdev_driver; |
@@ -366,8 +367,7 @@ static noinline int i2cdev_ioctl_smbus(struct i2c_client *client, | |||
366 | return res; | 367 | return res; |
367 | } | 368 | } |
368 | 369 | ||
369 | static int i2cdev_ioctl(struct inode *inode, struct file *file, | 370 | static long i2cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
370 | unsigned int cmd, unsigned long arg) | ||
371 | { | 371 | { |
372 | struct i2c_client *client = (struct i2c_client *)file->private_data; | 372 | struct i2c_client *client = (struct i2c_client *)file->private_data; |
373 | unsigned long funcs; | 373 | unsigned long funcs; |
@@ -441,14 +441,20 @@ static int i2cdev_open(struct inode *inode, struct file *file) | |||
441 | struct i2c_client *client; | 441 | struct i2c_client *client; |
442 | struct i2c_adapter *adap; | 442 | struct i2c_adapter *adap; |
443 | struct i2c_dev *i2c_dev; | 443 | struct i2c_dev *i2c_dev; |
444 | int ret = 0; | ||
444 | 445 | ||
446 | lock_kernel(); | ||
445 | i2c_dev = i2c_dev_get_by_minor(minor); | 447 | i2c_dev = i2c_dev_get_by_minor(minor); |
446 | if (!i2c_dev) | 448 | if (!i2c_dev) { |
447 | return -ENODEV; | 449 | ret = -ENODEV; |
450 | goto out; | ||
451 | } | ||
448 | 452 | ||
449 | adap = i2c_get_adapter(i2c_dev->adap->nr); | 453 | adap = i2c_get_adapter(i2c_dev->adap->nr); |
450 | if (!adap) | 454 | if (!adap) { |
451 | return -ENODEV; | 455 | ret = -ENODEV; |
456 | goto out; | ||
457 | } | ||
452 | 458 | ||
453 | /* This creates an anonymous i2c_client, which may later be | 459 | /* This creates an anonymous i2c_client, which may later be |
454 | * pointed to some address using I2C_SLAVE or I2C_SLAVE_FORCE. | 460 | * pointed to some address using I2C_SLAVE or I2C_SLAVE_FORCE. |
@@ -460,7 +466,8 @@ static int i2cdev_open(struct inode *inode, struct file *file) | |||
460 | client = kzalloc(sizeof(*client), GFP_KERNEL); | 466 | client = kzalloc(sizeof(*client), GFP_KERNEL); |
461 | if (!client) { | 467 | if (!client) { |
462 | i2c_put_adapter(adap); | 468 | i2c_put_adapter(adap); |
463 | return -ENOMEM; | 469 | ret = -ENOMEM; |
470 | goto out; | ||
464 | } | 471 | } |
465 | snprintf(client->name, I2C_NAME_SIZE, "i2c-dev %d", adap->nr); | 472 | snprintf(client->name, I2C_NAME_SIZE, "i2c-dev %d", adap->nr); |
466 | client->driver = &i2cdev_driver; | 473 | client->driver = &i2cdev_driver; |
@@ -468,7 +475,9 @@ static int i2cdev_open(struct inode *inode, struct file *file) | |||
468 | client->adapter = adap; | 475 | client->adapter = adap; |
469 | file->private_data = client; | 476 | file->private_data = client; |
470 | 477 | ||
471 | return 0; | 478 | out: |
479 | unlock_kernel(); | ||
480 | return ret; | ||
472 | } | 481 | } |
473 | 482 | ||
474 | static int i2cdev_release(struct inode *inode, struct file *file) | 483 | static int i2cdev_release(struct inode *inode, struct file *file) |
@@ -487,7 +496,7 @@ static const struct file_operations i2cdev_fops = { | |||
487 | .llseek = no_llseek, | 496 | .llseek = no_llseek, |
488 | .read = i2cdev_read, | 497 | .read = i2cdev_read, |
489 | .write = i2cdev_write, | 498 | .write = i2cdev_write, |
490 | .ioctl = i2cdev_ioctl, | 499 | .unlocked_ioctl = i2cdev_ioctl, |
491 | .open = i2cdev_open, | 500 | .open = i2cdev_open, |
492 | .release = i2cdev_release, | 501 | .release = i2cdev_release, |
493 | }; | 502 | }; |
@@ -512,9 +521,9 @@ static int i2cdev_attach_adapter(struct i2c_adapter *adap) | |||
512 | return PTR_ERR(i2c_dev); | 521 | return PTR_ERR(i2c_dev); |
513 | 522 | ||
514 | /* register this i2c device with the driver core */ | 523 | /* register this i2c device with the driver core */ |
515 | i2c_dev->dev = device_create(i2c_dev_class, &adap->dev, | 524 | i2c_dev->dev = device_create_drvdata(i2c_dev_class, &adap->dev, |
516 | MKDEV(I2C_MAJOR, adap->nr), | 525 | MKDEV(I2C_MAJOR, adap->nr), |
517 | "i2c-%d", adap->nr); | 526 | NULL, "i2c-%d", adap->nr); |
518 | if (IS_ERR(i2c_dev->dev)) { | 527 | if (IS_ERR(i2c_dev->dev)) { |
519 | res = PTR_ERR(i2c_dev->dev); | 528 | res = PTR_ERR(i2c_dev->dev); |
520 | goto error; | 529 | goto error; |
@@ -549,19 +558,12 @@ static int i2cdev_detach_adapter(struct i2c_adapter *adap) | |||
549 | return 0; | 558 | return 0; |
550 | } | 559 | } |
551 | 560 | ||
552 | static int i2cdev_detach_client(struct i2c_client *client) | ||
553 | { | ||
554 | return 0; | ||
555 | } | ||
556 | |||
557 | static struct i2c_driver i2cdev_driver = { | 561 | static struct i2c_driver i2cdev_driver = { |
558 | .driver = { | 562 | .driver = { |
559 | .name = "dev_driver", | 563 | .name = "dev_driver", |
560 | }, | 564 | }, |
561 | .id = I2C_DRIVERID_I2CDEV, | ||
562 | .attach_adapter = i2cdev_attach_adapter, | 565 | .attach_adapter = i2cdev_attach_adapter, |
563 | .detach_adapter = i2cdev_detach_adapter, | 566 | .detach_adapter = i2cdev_detach_adapter, |
564 | .detach_client = i2cdev_detach_client, | ||
565 | }; | 567 | }; |
566 | 568 | ||
567 | /* ------------------------------------------------------------------------- */ | 569 | /* ------------------------------------------------------------------------- */ |