Skip to content

Commit 9e5f81f

Browse files
geertuwsakernel
authored andcommitted
i2c: dev: Fix bus callback return values
The i2cdev_{at,de}tach_adapter() callbacks are used for two purposes: 1. As notifier callbacks, when (un)registering I2C adapters created or destroyed after i2c_dev_init(), 2. As bus iterator callbacks, for registering already existing adapters from i2c_dev_init(), and for cleanup. Unfortunately both use cases expect different return values: the former expects NOTIFY_* return codes, while the latter expects zero or error codes, and aborts in case of error. Hence in case 2, as soon as i2cdev_{at,de}tach_adapter() returns (non-zero) NOTIFY_OK, the bus iterator aborts. This causes (a) only the first already existing adapter to be registered, leading to missing /dev/i2c-* entries, and (b) a failure to unregister all but the first I2C adapter during cleanup. Fix this by introducing separate callbacks for the bus iterator, wrapping the notifier functions, and always returning succes. Any errors inside these callback functions are unlikely to happen, and are fatal anyway. Fixes: cddf70d ("i2c: dev: fix notifier return values") Signed-off-by: Geert Uytterhoeven <[email protected]> Reviewed-by: Bartosz Golaszewski <[email protected]> Signed-off-by: Wolfram Sang <[email protected]>
1 parent 834a9dc commit 9e5f81f

File tree

1 file changed

+18
-6
lines changed

1 file changed

+18
-6
lines changed

drivers/i2c/i2c-dev.c

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -646,7 +646,7 @@ static void i2cdev_dev_release(struct device *dev)
646646
kfree(i2c_dev);
647647
}
648648

649-
static int i2cdev_attach_adapter(struct device *dev, void *dummy)
649+
static int i2cdev_attach_adapter(struct device *dev)
650650
{
651651
struct i2c_adapter *adap;
652652
struct i2c_dev *i2c_dev;
@@ -685,7 +685,7 @@ static int i2cdev_attach_adapter(struct device *dev, void *dummy)
685685
return NOTIFY_DONE;
686686
}
687687

688-
static int i2cdev_detach_adapter(struct device *dev, void *dummy)
688+
static int i2cdev_detach_adapter(struct device *dev)
689689
{
690690
struct i2c_adapter *adap;
691691
struct i2c_dev *i2c_dev;
@@ -711,9 +711,9 @@ static int i2cdev_notifier_call(struct notifier_block *nb, unsigned long action,
711711

712712
switch (action) {
713713
case BUS_NOTIFY_ADD_DEVICE:
714-
return i2cdev_attach_adapter(dev, NULL);
714+
return i2cdev_attach_adapter(dev);
715715
case BUS_NOTIFY_DEL_DEVICE:
716-
return i2cdev_detach_adapter(dev, NULL);
716+
return i2cdev_detach_adapter(dev);
717717
}
718718

719719
return NOTIFY_DONE;
@@ -725,6 +725,18 @@ static struct notifier_block i2cdev_notifier = {
725725

726726
/* ------------------------------------------------------------------------- */
727727

728+
static int __init i2c_dev_attach_adapter(struct device *dev, void *dummy)
729+
{
730+
i2cdev_attach_adapter(dev);
731+
return 0;
732+
}
733+
734+
static int __exit i2c_dev_detach_adapter(struct device *dev, void *dummy)
735+
{
736+
i2cdev_detach_adapter(dev);
737+
return 0;
738+
}
739+
728740
/*
729741
* module load/unload record keeping
730742
*/
@@ -752,7 +764,7 @@ static int __init i2c_dev_init(void)
752764
goto out_unreg_class;
753765

754766
/* Bind to already existing adapters right away */
755-
i2c_for_each_dev(NULL, i2cdev_attach_adapter);
767+
i2c_for_each_dev(NULL, i2c_dev_attach_adapter);
756768

757769
return 0;
758770

@@ -768,7 +780,7 @@ static int __init i2c_dev_init(void)
768780
static void __exit i2c_dev_exit(void)
769781
{
770782
bus_unregister_notifier(&i2c_bus_type, &i2cdev_notifier);
771-
i2c_for_each_dev(NULL, i2cdev_detach_adapter);
783+
i2c_for_each_dev(NULL, i2c_dev_detach_adapter);
772784
class_destroy(i2c_dev_class);
773785
unregister_chrdev_region(MKDEV(I2C_MAJOR, 0), I2C_MINORS);
774786
}

0 commit comments

Comments
 (0)