diff options
author | Jean Delvare <khali@linux-fr.org> | 2009-12-06 11:06:24 -0500 |
---|---|---|
committer | Jean Delvare <khali@linux-fr.org> | 2009-12-06 11:06:24 -0500 |
commit | c7b25a9e96dc89954ae8d8f473f56fae62030f84 (patch) | |
tree | cc1f924445517a16e3923112e77edbfe33cd3b25 | |
parent | abe38388e50f4d89726fd0c0cceea61563c7026b (diff) |
i2c: Drop probe, ignore and force module parameters
The legacy probe and force module parameters are obsolete now, the
same can be achieved using the new_device sysfs interface, which is
both more flexible and cheaper (it is implemented by i2c-core rather
than replicated in every driver module.)
The legacy ignore module parameters can be dropped as well. Ignoring
can be done by instantiating a "dummy" device at the problematic
address.
This is the first step of a huge cleanup to i2c-core's i2c_detect
function, i2c.h's I2C_CLIENT_INSMOD* macros, and all drivers that made
use of them.
Signed-off-by: Jean Delvare <khali@linux-fr.org>
-rw-r--r-- | Documentation/i2c/old-module-parameters | 44 | ||||
-rw-r--r-- | drivers/i2c/i2c-core.c | 65 | ||||
-rw-r--r-- | include/linux/i2c.h | 91 |
3 files changed, 46 insertions, 154 deletions
diff --git a/Documentation/i2c/old-module-parameters b/Documentation/i2c/old-module-parameters new file mode 100644 index 000000000000..8e2b629d533c --- /dev/null +++ b/Documentation/i2c/old-module-parameters | |||
@@ -0,0 +1,44 @@ | |||
1 | I2C device driver binding control from user-space | ||
2 | ================================================= | ||
3 | |||
4 | Up to kernel 2.6.32, many i2c drivers used helper macros provided by | ||
5 | <linux/i2c.h> which created standard module parameters to let the user | ||
6 | control how the driver would probe i2c buses and attach to devices. These | ||
7 | parameters were known as "probe" (to let the driver probe for an extra | ||
8 | address), "force" (to forcibly attach the driver to a given device) and | ||
9 | "ignore" (to prevent a driver from probing a given address). | ||
10 | |||
11 | With the conversion of the i2c subsystem to the standard device driver | ||
12 | binding model, it became clear that these per-module parameters were no | ||
13 | longer needed, and that a centralized implementation was possible. The new, | ||
14 | sysfs-based interface is described in the documentation file | ||
15 | "instantiating-devices", section "Method 4: Instantiate from user-space". | ||
16 | |||
17 | Below is a mapping from the old module parameters to the new interface. | ||
18 | |||
19 | Attaching a driver to an I2C device | ||
20 | ----------------------------------- | ||
21 | |||
22 | Old method (module parameters): | ||
23 | # modprobe <driver> probe=1,0x2d | ||
24 | # modprobe <driver> force=1,0x2d | ||
25 | # modprobe <driver> force_<device>=1,0x2d | ||
26 | |||
27 | New method (sysfs interface): | ||
28 | # echo <device> 0x2d > /sys/bus/i2c/devices/i2c-1/new_device | ||
29 | |||
30 | Preventing a driver from attaching to an I2C device | ||
31 | --------------------------------------------------- | ||
32 | |||
33 | Old method (module parameters): | ||
34 | # modprobe <driver> ignore=1,0x2f | ||
35 | |||
36 | New method (sysfs interface): | ||
37 | # echo dummy 0x2f > /sys/bus/i2c/devices/i2c-1/new_device | ||
38 | # modprobe <driver> | ||
39 | |||
40 | Of course, it is important to instantiate the "dummy" device before loading | ||
41 | the driver. The dummy device will be handled by i2c-core itself, preventing | ||
42 | other drivers from binding to it later on. If there is a real device at the | ||
43 | problematic address, and you want another driver to bind to it, then simply | ||
44 | pass the name of the device in question instead of "dummy". | ||
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index d664b4a97a31..fdfaebdf3bfe 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
@@ -1259,40 +1259,13 @@ static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver) | |||
1259 | return -ENOMEM; | 1259 | return -ENOMEM; |
1260 | temp_client->adapter = adapter; | 1260 | temp_client->adapter = adapter; |
1261 | 1261 | ||
1262 | /* Force entries are done first, and are not affected by ignore | ||
1263 | entries */ | ||
1264 | if (address_data->forces) { | ||
1265 | const unsigned short * const *forces = address_data->forces; | ||
1266 | int kind; | ||
1267 | |||
1268 | for (kind = 0; forces[kind]; kind++) { | ||
1269 | for (i = 0; forces[kind][i] != I2C_CLIENT_END; | ||
1270 | i += 2) { | ||
1271 | if (forces[kind][i] == adap_id | ||
1272 | || forces[kind][i] == ANY_I2C_BUS) { | ||
1273 | dev_dbg(&adapter->dev, "found force " | ||
1274 | "parameter for adapter %d, " | ||
1275 | "addr 0x%02x, kind %d\n", | ||
1276 | adap_id, forces[kind][i + 1], | ||
1277 | kind); | ||
1278 | temp_client->addr = forces[kind][i + 1]; | ||
1279 | err = i2c_detect_address(temp_client, | ||
1280 | kind, driver); | ||
1281 | if (err) | ||
1282 | goto exit_free; | ||
1283 | } | ||
1284 | } | ||
1285 | } | ||
1286 | } | ||
1287 | |||
1288 | /* Stop here if the classes do not match */ | 1262 | /* Stop here if the classes do not match */ |
1289 | if (!(adapter->class & driver->class)) | 1263 | if (!(adapter->class & driver->class)) |
1290 | goto exit_free; | 1264 | goto exit_free; |
1291 | 1265 | ||
1292 | /* Stop here if we can't use SMBUS_QUICK */ | 1266 | /* Stop here if we can't use SMBUS_QUICK */ |
1293 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_QUICK)) { | 1267 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_QUICK)) { |
1294 | if (address_data->probe[0] == I2C_CLIENT_END | 1268 | if (address_data->normal_i2c[0] == I2C_CLIENT_END) |
1295 | && address_data->normal_i2c[0] == I2C_CLIENT_END) | ||
1296 | goto exit_free; | 1269 | goto exit_free; |
1297 | 1270 | ||
1298 | dev_warn(&adapter->dev, "SMBus Quick command not supported, " | 1271 | dev_warn(&adapter->dev, "SMBus Quick command not supported, " |
@@ -1301,43 +1274,7 @@ static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver) | |||
1301 | goto exit_free; | 1274 | goto exit_free; |
1302 | } | 1275 | } |
1303 | 1276 | ||
1304 | /* Probe entries are done second, and are not affected by ignore | ||
1305 | entries either */ | ||
1306 | for (i = 0; address_data->probe[i] != I2C_CLIENT_END; i += 2) { | ||
1307 | if (address_data->probe[i] == adap_id | ||
1308 | || address_data->probe[i] == ANY_I2C_BUS) { | ||
1309 | dev_dbg(&adapter->dev, "found probe parameter for " | ||
1310 | "adapter %d, addr 0x%02x\n", adap_id, | ||
1311 | address_data->probe[i + 1]); | ||
1312 | temp_client->addr = address_data->probe[i + 1]; | ||
1313 | err = i2c_detect_address(temp_client, -1, driver); | ||
1314 | if (err) | ||
1315 | goto exit_free; | ||
1316 | } | ||
1317 | } | ||
1318 | |||
1319 | /* Normal entries are done last, unless shadowed by an ignore entry */ | ||
1320 | for (i = 0; address_data->normal_i2c[i] != I2C_CLIENT_END; i += 1) { | 1277 | for (i = 0; address_data->normal_i2c[i] != I2C_CLIENT_END; i += 1) { |
1321 | int j, ignore; | ||
1322 | |||
1323 | ignore = 0; | ||
1324 | for (j = 0; address_data->ignore[j] != I2C_CLIENT_END; | ||
1325 | j += 2) { | ||
1326 | if ((address_data->ignore[j] == adap_id || | ||
1327 | address_data->ignore[j] == ANY_I2C_BUS) | ||
1328 | && address_data->ignore[j + 1] | ||
1329 | == address_data->normal_i2c[i]) { | ||
1330 | dev_dbg(&adapter->dev, "found ignore " | ||
1331 | "parameter for adapter %d, " | ||
1332 | "addr 0x%02x\n", adap_id, | ||
1333 | address_data->ignore[j + 1]); | ||
1334 | ignore = 1; | ||
1335 | break; | ||
1336 | } | ||
1337 | } | ||
1338 | if (ignore) | ||
1339 | continue; | ||
1340 | |||
1341 | dev_dbg(&adapter->dev, "found normal entry for adapter %d, " | 1278 | dev_dbg(&adapter->dev, "found normal entry for adapter %d, " |
1342 | "addr 0x%02x\n", adap_id, | 1279 | "addr 0x%02x\n", adap_id, |
1343 | address_data->normal_i2c[i]); | 1280 | address_data->normal_i2c[i]); |
diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 52317fb5917e..419ab546b266 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h | |||
@@ -110,7 +110,7 @@ extern s32 i2c_smbus_write_i2c_block_data(struct i2c_client *client, | |||
110 | * @driver: Device driver model driver | 110 | * @driver: Device driver model driver |
111 | * @id_table: List of I2C devices supported by this driver | 111 | * @id_table: List of I2C devices supported by this driver |
112 | * @detect: Callback for device detection | 112 | * @detect: Callback for device detection |
113 | * @address_data: The I2C addresses to probe, ignore or force (for detect) | 113 | * @address_data: The I2C addresses to probe (for detect) |
114 | * @clients: List of detected clients we created (for i2c-core use only) | 114 | * @clients: List of detected clients we created (for i2c-core use only) |
115 | * | 115 | * |
116 | * The driver.owner field should be set to the module owner of this driver. | 116 | * The driver.owner field should be set to the module owner of this driver. |
@@ -397,9 +397,6 @@ static inline void i2c_unlock_adapter(struct i2c_adapter *adapter) | |||
397 | */ | 397 | */ |
398 | struct i2c_client_address_data { | 398 | struct i2c_client_address_data { |
399 | const unsigned short *normal_i2c; | 399 | const unsigned short *normal_i2c; |
400 | const unsigned short *probe; | ||
401 | const unsigned short *ignore; | ||
402 | const unsigned short * const *forces; | ||
403 | }; | 400 | }; |
404 | 401 | ||
405 | /* Internal numbers to terminate lists */ | 402 | /* Internal numbers to terminate lists */ |
@@ -613,134 +610,48 @@ union i2c_smbus_data { | |||
613 | module_param_array(var, short, &var##_num, 0); \ | 610 | module_param_array(var, short, &var##_num, 0); \ |
614 | MODULE_PARM_DESC(var, desc) | 611 | MODULE_PARM_DESC(var, desc) |
615 | 612 | ||
616 | #define I2C_CLIENT_MODULE_PARM_FORCE(name) \ | ||
617 | I2C_CLIENT_MODULE_PARM(force_##name, \ | ||
618 | "List of adapter,address pairs which are " \ | ||
619 | "unquestionably assumed to contain a `" \ | ||
620 | # name "' chip") | ||
621 | |||
622 | |||
623 | #define I2C_CLIENT_INSMOD_COMMON \ | 613 | #define I2C_CLIENT_INSMOD_COMMON \ |
624 | I2C_CLIENT_MODULE_PARM(probe, "List of adapter,address pairs to scan " \ | ||
625 | "additionally"); \ | ||
626 | I2C_CLIENT_MODULE_PARM(ignore, "List of adapter,address pairs not to " \ | ||
627 | "scan"); \ | ||
628 | static const struct i2c_client_address_data addr_data = { \ | 614 | static const struct i2c_client_address_data addr_data = { \ |
629 | .normal_i2c = normal_i2c, \ | 615 | .normal_i2c = normal_i2c, \ |
630 | .probe = probe, \ | ||
631 | .ignore = ignore, \ | ||
632 | .forces = forces, \ | ||
633 | } | 616 | } |
634 | 617 | ||
635 | #define I2C_CLIENT_FORCE_TEXT \ | ||
636 | "List of adapter,address pairs to boldly assume to be present" | ||
637 | |||
638 | /* These are the ones you want to use in your own drivers. Pick the one | 618 | /* These are the ones you want to use in your own drivers. Pick the one |
639 | which matches the number of devices the driver differenciates between. */ | 619 | which matches the number of devices the driver differenciates between. */ |
640 | #define I2C_CLIENT_INSMOD \ | 620 | #define I2C_CLIENT_INSMOD \ |
641 | I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT); \ | ||
642 | static const unsigned short * const forces[] = { force, NULL }; \ | ||
643 | I2C_CLIENT_INSMOD_COMMON | 621 | I2C_CLIENT_INSMOD_COMMON |
644 | 622 | ||
645 | #define I2C_CLIENT_INSMOD_1(chip1) \ | 623 | #define I2C_CLIENT_INSMOD_1(chip1) \ |
646 | enum chips { any_chip, chip1 }; \ | 624 | enum chips { any_chip, chip1 }; \ |
647 | I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT); \ | ||
648 | I2C_CLIENT_MODULE_PARM_FORCE(chip1); \ | ||
649 | static const unsigned short * const forces[] = { force, \ | ||
650 | force_##chip1, NULL }; \ | ||
651 | I2C_CLIENT_INSMOD_COMMON | 625 | I2C_CLIENT_INSMOD_COMMON |
652 | 626 | ||
653 | #define I2C_CLIENT_INSMOD_2(chip1, chip2) \ | 627 | #define I2C_CLIENT_INSMOD_2(chip1, chip2) \ |
654 | enum chips { any_chip, chip1, chip2 }; \ | 628 | enum chips { any_chip, chip1, chip2 }; \ |
655 | I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT); \ | ||
656 | I2C_CLIENT_MODULE_PARM_FORCE(chip1); \ | ||
657 | I2C_CLIENT_MODULE_PARM_FORCE(chip2); \ | ||
658 | static const unsigned short * const forces[] = { force, \ | ||
659 | force_##chip1, force_##chip2, NULL }; \ | ||
660 | I2C_CLIENT_INSMOD_COMMON | 629 | I2C_CLIENT_INSMOD_COMMON |
661 | 630 | ||
662 | #define I2C_CLIENT_INSMOD_3(chip1, chip2, chip3) \ | 631 | #define I2C_CLIENT_INSMOD_3(chip1, chip2, chip3) \ |
663 | enum chips { any_chip, chip1, chip2, chip3 }; \ | 632 | enum chips { any_chip, chip1, chip2, chip3 }; \ |
664 | I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT); \ | ||
665 | I2C_CLIENT_MODULE_PARM_FORCE(chip1); \ | ||
666 | I2C_CLIENT_MODULE_PARM_FORCE(chip2); \ | ||
667 | I2C_CLIENT_MODULE_PARM_FORCE(chip3); \ | ||
668 | static const unsigned short * const forces[] = { force, \ | ||
669 | force_##chip1, force_##chip2, force_##chip3, NULL }; \ | ||
670 | I2C_CLIENT_INSMOD_COMMON | 633 | I2C_CLIENT_INSMOD_COMMON |
671 | 634 | ||
672 | #define I2C_CLIENT_INSMOD_4(chip1, chip2, chip3, chip4) \ | 635 | #define I2C_CLIENT_INSMOD_4(chip1, chip2, chip3, chip4) \ |
673 | enum chips { any_chip, chip1, chip2, chip3, chip4 }; \ | 636 | enum chips { any_chip, chip1, chip2, chip3, chip4 }; \ |
674 | I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT); \ | ||
675 | I2C_CLIENT_MODULE_PARM_FORCE(chip1); \ | ||
676 | I2C_CLIENT_MODULE_PARM_FORCE(chip2); \ | ||
677 | I2C_CLIENT_MODULE_PARM_FORCE(chip3); \ | ||
678 | I2C_CLIENT_MODULE_PARM_FORCE(chip4); \ | ||
679 | static const unsigned short * const forces[] = { force, \ | ||
680 | force_##chip1, force_##chip2, force_##chip3, \ | ||
681 | force_##chip4, NULL}; \ | ||
682 | I2C_CLIENT_INSMOD_COMMON | 637 | I2C_CLIENT_INSMOD_COMMON |
683 | 638 | ||
684 | #define I2C_CLIENT_INSMOD_5(chip1, chip2, chip3, chip4, chip5) \ | 639 | #define I2C_CLIENT_INSMOD_5(chip1, chip2, chip3, chip4, chip5) \ |
685 | enum chips { any_chip, chip1, chip2, chip3, chip4, chip5 }; \ | 640 | enum chips { any_chip, chip1, chip2, chip3, chip4, chip5 }; \ |
686 | I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT); \ | ||
687 | I2C_CLIENT_MODULE_PARM_FORCE(chip1); \ | ||
688 | I2C_CLIENT_MODULE_PARM_FORCE(chip2); \ | ||
689 | I2C_CLIENT_MODULE_PARM_FORCE(chip3); \ | ||
690 | I2C_CLIENT_MODULE_PARM_FORCE(chip4); \ | ||
691 | I2C_CLIENT_MODULE_PARM_FORCE(chip5); \ | ||
692 | static const unsigned short * const forces[] = { force, \ | ||
693 | force_##chip1, force_##chip2, force_##chip3, \ | ||
694 | force_##chip4, force_##chip5, NULL }; \ | ||
695 | I2C_CLIENT_INSMOD_COMMON | 641 | I2C_CLIENT_INSMOD_COMMON |
696 | 642 | ||
697 | #define I2C_CLIENT_INSMOD_6(chip1, chip2, chip3, chip4, chip5, chip6) \ | 643 | #define I2C_CLIENT_INSMOD_6(chip1, chip2, chip3, chip4, chip5, chip6) \ |
698 | enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6 }; \ | 644 | enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6 }; \ |
699 | I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT); \ | ||
700 | I2C_CLIENT_MODULE_PARM_FORCE(chip1); \ | ||
701 | I2C_CLIENT_MODULE_PARM_FORCE(chip2); \ | ||
702 | I2C_CLIENT_MODULE_PARM_FORCE(chip3); \ | ||
703 | I2C_CLIENT_MODULE_PARM_FORCE(chip4); \ | ||
704 | I2C_CLIENT_MODULE_PARM_FORCE(chip5); \ | ||
705 | I2C_CLIENT_MODULE_PARM_FORCE(chip6); \ | ||
706 | static const unsigned short * const forces[] = { force, \ | ||
707 | force_##chip1, force_##chip2, force_##chip3, \ | ||
708 | force_##chip4, force_##chip5, force_##chip6, NULL }; \ | ||
709 | I2C_CLIENT_INSMOD_COMMON | 645 | I2C_CLIENT_INSMOD_COMMON |
710 | 646 | ||
711 | #define I2C_CLIENT_INSMOD_7(chip1, chip2, chip3, chip4, chip5, chip6, chip7) \ | 647 | #define I2C_CLIENT_INSMOD_7(chip1, chip2, chip3, chip4, chip5, chip6, chip7) \ |
712 | enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6, \ | 648 | enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6, \ |
713 | chip7 }; \ | 649 | chip7 }; \ |
714 | I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT); \ | ||
715 | I2C_CLIENT_MODULE_PARM_FORCE(chip1); \ | ||
716 | I2C_CLIENT_MODULE_PARM_FORCE(chip2); \ | ||
717 | I2C_CLIENT_MODULE_PARM_FORCE(chip3); \ | ||
718 | I2C_CLIENT_MODULE_PARM_FORCE(chip4); \ | ||
719 | I2C_CLIENT_MODULE_PARM_FORCE(chip5); \ | ||
720 | I2C_CLIENT_MODULE_PARM_FORCE(chip6); \ | ||
721 | I2C_CLIENT_MODULE_PARM_FORCE(chip7); \ | ||
722 | static const unsigned short * const forces[] = { force, \ | ||
723 | force_##chip1, force_##chip2, force_##chip3, \ | ||
724 | force_##chip4, force_##chip5, force_##chip6, \ | ||
725 | force_##chip7, NULL }; \ | ||
726 | I2C_CLIENT_INSMOD_COMMON | 650 | I2C_CLIENT_INSMOD_COMMON |
727 | 651 | ||
728 | #define I2C_CLIENT_INSMOD_8(chip1, chip2, chip3, chip4, chip5, chip6, chip7, chip8) \ | 652 | #define I2C_CLIENT_INSMOD_8(chip1, chip2, chip3, chip4, chip5, chip6, chip7, chip8) \ |
729 | enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6, \ | 653 | enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6, \ |
730 | chip7, chip8 }; \ | 654 | chip7, chip8 }; \ |
731 | I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT); \ | ||
732 | I2C_CLIENT_MODULE_PARM_FORCE(chip1); \ | ||
733 | I2C_CLIENT_MODULE_PARM_FORCE(chip2); \ | ||
734 | I2C_CLIENT_MODULE_PARM_FORCE(chip3); \ | ||
735 | I2C_CLIENT_MODULE_PARM_FORCE(chip4); \ | ||
736 | I2C_CLIENT_MODULE_PARM_FORCE(chip5); \ | ||
737 | I2C_CLIENT_MODULE_PARM_FORCE(chip6); \ | ||
738 | I2C_CLIENT_MODULE_PARM_FORCE(chip7); \ | ||
739 | I2C_CLIENT_MODULE_PARM_FORCE(chip8); \ | ||
740 | static const unsigned short * const forces[] = { force, \ | ||
741 | force_##chip1, force_##chip2, force_##chip3, \ | ||
742 | force_##chip4, force_##chip5, force_##chip6, \ | ||
743 | force_##chip7, force_##chip8, NULL }; \ | ||
744 | I2C_CLIENT_INSMOD_COMMON | 655 | I2C_CLIENT_INSMOD_COMMON |
745 | #endif /* __KERNEL__ */ | 656 | #endif /* __KERNEL__ */ |
746 | #endif /* _LINUX_I2C_H */ | 657 | #endif /* _LINUX_I2C_H */ |