aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/i2c/old-module-parameters44
-rw-r--r--drivers/i2c/i2c-core.c65
-rw-r--r--include/linux/i2c.h91
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 @@
1I2C device driver binding control from user-space
2=================================================
3
4Up 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
6control how the driver would probe i2c buses and attach to devices. These
7parameters were known as "probe" (to let the driver probe for an extra
8address), "force" (to forcibly attach the driver to a given device) and
9"ignore" (to prevent a driver from probing a given address).
10
11With the conversion of the i2c subsystem to the standard device driver
12binding model, it became clear that these per-module parameters were no
13longer needed, and that a centralized implementation was possible. The new,
14sysfs-based interface is described in the documentation file
15"instantiating-devices", section "Method 4: Instantiate from user-space".
16
17Below is a mapping from the old module parameters to the new interface.
18
19Attaching a driver to an I2C device
20-----------------------------------
21
22Old method (module parameters):
23# modprobe <driver> probe=1,0x2d
24# modprobe <driver> force=1,0x2d
25# modprobe <driver> force_<device>=1,0x2d
26
27New method (sysfs interface):
28# echo <device> 0x2d > /sys/bus/i2c/devices/i2c-1/new_device
29
30Preventing a driver from attaching to an I2C device
31---------------------------------------------------
32
33Old method (module parameters):
34# modprobe <driver> ignore=1,0x2f
35
36New method (sysfs interface):
37# echo dummy 0x2f > /sys/bus/i2c/devices/i2c-1/new_device
38# modprobe <driver>
39
40Of course, it is important to instantiate the "dummy" device before loading
41the driver. The dummy device will be handled by i2c-core itself, preventing
42other drivers from binding to it later on. If there is a real device at the
43problematic address, and you want another driver to bind to it, then simply
44pass 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 */
398struct i2c_client_address_data { 398struct 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) \
617I2C_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 \
624I2C_CLIENT_MODULE_PARM(probe, "List of adapter,address pairs to scan " \
625 "additionally"); \
626I2C_CLIENT_MODULE_PARM(ignore, "List of adapter,address pairs not to " \
627 "scan"); \
628static const struct i2c_client_address_data addr_data = { \ 614static 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 \
641I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT); \
642static const unsigned short * const forces[] = { force, NULL }; \
643I2C_CLIENT_INSMOD_COMMON 621I2C_CLIENT_INSMOD_COMMON
644 622
645#define I2C_CLIENT_INSMOD_1(chip1) \ 623#define I2C_CLIENT_INSMOD_1(chip1) \
646enum chips { any_chip, chip1 }; \ 624enum chips { any_chip, chip1 }; \
647I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT); \
648I2C_CLIENT_MODULE_PARM_FORCE(chip1); \
649static const unsigned short * const forces[] = { force, \
650 force_##chip1, NULL }; \
651I2C_CLIENT_INSMOD_COMMON 625I2C_CLIENT_INSMOD_COMMON
652 626
653#define I2C_CLIENT_INSMOD_2(chip1, chip2) \ 627#define I2C_CLIENT_INSMOD_2(chip1, chip2) \
654enum chips { any_chip, chip1, chip2 }; \ 628enum chips { any_chip, chip1, chip2 }; \
655I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT); \
656I2C_CLIENT_MODULE_PARM_FORCE(chip1); \
657I2C_CLIENT_MODULE_PARM_FORCE(chip2); \
658static const unsigned short * const forces[] = { force, \
659 force_##chip1, force_##chip2, NULL }; \
660I2C_CLIENT_INSMOD_COMMON 629I2C_CLIENT_INSMOD_COMMON
661 630
662#define I2C_CLIENT_INSMOD_3(chip1, chip2, chip3) \ 631#define I2C_CLIENT_INSMOD_3(chip1, chip2, chip3) \
663enum chips { any_chip, chip1, chip2, chip3 }; \ 632enum chips { any_chip, chip1, chip2, chip3 }; \
664I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT); \
665I2C_CLIENT_MODULE_PARM_FORCE(chip1); \
666I2C_CLIENT_MODULE_PARM_FORCE(chip2); \
667I2C_CLIENT_MODULE_PARM_FORCE(chip3); \
668static const unsigned short * const forces[] = { force, \
669 force_##chip1, force_##chip2, force_##chip3, NULL }; \
670I2C_CLIENT_INSMOD_COMMON 633I2C_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) \
673enum chips { any_chip, chip1, chip2, chip3, chip4 }; \ 636enum chips { any_chip, chip1, chip2, chip3, chip4 }; \
674I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT); \
675I2C_CLIENT_MODULE_PARM_FORCE(chip1); \
676I2C_CLIENT_MODULE_PARM_FORCE(chip2); \
677I2C_CLIENT_MODULE_PARM_FORCE(chip3); \
678I2C_CLIENT_MODULE_PARM_FORCE(chip4); \
679static const unsigned short * const forces[] = { force, \
680 force_##chip1, force_##chip2, force_##chip3, \
681 force_##chip4, NULL}; \
682I2C_CLIENT_INSMOD_COMMON 637I2C_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) \
685enum chips { any_chip, chip1, chip2, chip3, chip4, chip5 }; \ 640enum chips { any_chip, chip1, chip2, chip3, chip4, chip5 }; \
686I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT); \
687I2C_CLIENT_MODULE_PARM_FORCE(chip1); \
688I2C_CLIENT_MODULE_PARM_FORCE(chip2); \
689I2C_CLIENT_MODULE_PARM_FORCE(chip3); \
690I2C_CLIENT_MODULE_PARM_FORCE(chip4); \
691I2C_CLIENT_MODULE_PARM_FORCE(chip5); \
692static const unsigned short * const forces[] = { force, \
693 force_##chip1, force_##chip2, force_##chip3, \
694 force_##chip4, force_##chip5, NULL }; \
695I2C_CLIENT_INSMOD_COMMON 641I2C_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) \
698enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6 }; \ 644enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6 }; \
699I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT); \
700I2C_CLIENT_MODULE_PARM_FORCE(chip1); \
701I2C_CLIENT_MODULE_PARM_FORCE(chip2); \
702I2C_CLIENT_MODULE_PARM_FORCE(chip3); \
703I2C_CLIENT_MODULE_PARM_FORCE(chip4); \
704I2C_CLIENT_MODULE_PARM_FORCE(chip5); \
705I2C_CLIENT_MODULE_PARM_FORCE(chip6); \
706static const unsigned short * const forces[] = { force, \
707 force_##chip1, force_##chip2, force_##chip3, \
708 force_##chip4, force_##chip5, force_##chip6, NULL }; \
709I2C_CLIENT_INSMOD_COMMON 645I2C_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) \
712enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6, \ 648enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6, \
713 chip7 }; \ 649 chip7 }; \
714I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT); \
715I2C_CLIENT_MODULE_PARM_FORCE(chip1); \
716I2C_CLIENT_MODULE_PARM_FORCE(chip2); \
717I2C_CLIENT_MODULE_PARM_FORCE(chip3); \
718I2C_CLIENT_MODULE_PARM_FORCE(chip4); \
719I2C_CLIENT_MODULE_PARM_FORCE(chip5); \
720I2C_CLIENT_MODULE_PARM_FORCE(chip6); \
721I2C_CLIENT_MODULE_PARM_FORCE(chip7); \
722static const unsigned short * const forces[] = { force, \
723 force_##chip1, force_##chip2, force_##chip3, \
724 force_##chip4, force_##chip5, force_##chip6, \
725 force_##chip7, NULL }; \
726I2C_CLIENT_INSMOD_COMMON 650I2C_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) \
729enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6, \ 653enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6, \
730 chip7, chip8 }; \ 654 chip7, chip8 }; \
731I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT); \
732I2C_CLIENT_MODULE_PARM_FORCE(chip1); \
733I2C_CLIENT_MODULE_PARM_FORCE(chip2); \
734I2C_CLIENT_MODULE_PARM_FORCE(chip3); \
735I2C_CLIENT_MODULE_PARM_FORCE(chip4); \
736I2C_CLIENT_MODULE_PARM_FORCE(chip5); \
737I2C_CLIENT_MODULE_PARM_FORCE(chip6); \
738I2C_CLIENT_MODULE_PARM_FORCE(chip7); \
739I2C_CLIENT_MODULE_PARM_FORCE(chip8); \
740static 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 }; \
744I2C_CLIENT_INSMOD_COMMON 655I2C_CLIENT_INSMOD_COMMON
745#endif /* __KERNEL__ */ 656#endif /* __KERNEL__ */
746#endif /* _LINUX_I2C_H */ 657#endif /* _LINUX_I2C_H */