| 1 | // SPDX-License-Identifier: GPL-2.0-or-later | 
|---|
| 2 | /* | 
|---|
| 3 | * i2c-boardinfo.c - collect pre-declarations of I2C devices | 
|---|
| 4 | */ | 
|---|
| 5 |  | 
|---|
| 6 | #include <linux/export.h> | 
|---|
| 7 | #include <linux/i2c.h> | 
|---|
| 8 | #include <linux/kernel.h> | 
|---|
| 9 | #include <linux/property.h> | 
|---|
| 10 | #include <linux/rwsem.h> | 
|---|
| 11 | #include <linux/slab.h> | 
|---|
| 12 |  | 
|---|
| 13 | #include "i2c-core.h" | 
|---|
| 14 |  | 
|---|
| 15 |  | 
|---|
| 16 | /* These symbols are exported ONLY FOR the i2c core. | 
|---|
| 17 | * No other users will be supported. | 
|---|
| 18 | */ | 
|---|
| 19 | DECLARE_RWSEM(__i2c_board_lock); | 
|---|
| 20 | EXPORT_SYMBOL_GPL(__i2c_board_lock); | 
|---|
| 21 |  | 
|---|
| 22 | LIST_HEAD(__i2c_board_list); | 
|---|
| 23 | EXPORT_SYMBOL_GPL(__i2c_board_list); | 
|---|
| 24 |  | 
|---|
| 25 | int __i2c_first_dynamic_bus_num __ro_after_init; | 
|---|
| 26 | EXPORT_SYMBOL_GPL(__i2c_first_dynamic_bus_num); | 
|---|
| 27 |  | 
|---|
| 28 |  | 
|---|
| 29 | /** | 
|---|
| 30 | * i2c_register_board_info - statically declare I2C devices | 
|---|
| 31 | * @busnum: identifies the bus to which these devices belong | 
|---|
| 32 | * @info: vector of i2c device descriptors | 
|---|
| 33 | * @len: how many descriptors in the vector; may be zero to reserve | 
|---|
| 34 | *	the specified bus number. | 
|---|
| 35 | * | 
|---|
| 36 | * Systems using the Linux I2C driver stack can declare tables of board info | 
|---|
| 37 | * while they initialize.  This should be done in board-specific init code | 
|---|
| 38 | * near arch_initcall() time, or equivalent, before any I2C adapter driver is | 
|---|
| 39 | * registered.  For example, mainboard init code could define several devices, | 
|---|
| 40 | * as could the init code for each daughtercard in a board stack. | 
|---|
| 41 | * | 
|---|
| 42 | * The I2C devices will be created later, after the adapter for the relevant | 
|---|
| 43 | * bus has been registered.  After that moment, standard driver model tools | 
|---|
| 44 | * are used to bind "new style" I2C drivers to the devices.  The bus number | 
|---|
| 45 | * for any device declared using this routine is not available for dynamic | 
|---|
| 46 | * allocation. | 
|---|
| 47 | * | 
|---|
| 48 | * The board info passed can safely be __initdata, but be careful of embedded | 
|---|
| 49 | * pointers (for platform_data, functions, etc) since that won't be copied. | 
|---|
| 50 | */ | 
|---|
| 51 | int __init i2c_register_board_info(int busnum, struct i2c_board_info const *info, unsigned len) | 
|---|
| 52 | { | 
|---|
| 53 | int status; | 
|---|
| 54 |  | 
|---|
| 55 | down_write(sem: &__i2c_board_lock); | 
|---|
| 56 |  | 
|---|
| 57 | /* dynamic bus numbers will be assigned after the last static one */ | 
|---|
| 58 | if (busnum >= __i2c_first_dynamic_bus_num) | 
|---|
| 59 | __i2c_first_dynamic_bus_num = busnum + 1; | 
|---|
| 60 |  | 
|---|
| 61 | for (status = 0; len; len--, info++) { | 
|---|
| 62 | struct i2c_devinfo	*devinfo; | 
|---|
| 63 |  | 
|---|
| 64 | devinfo = kzalloc(sizeof(*devinfo), GFP_KERNEL); | 
|---|
| 65 | if (!devinfo) { | 
|---|
| 66 | pr_debug( "i2c-core: can't register boardinfo!\n"); | 
|---|
| 67 | status = -ENOMEM; | 
|---|
| 68 | break; | 
|---|
| 69 | } | 
|---|
| 70 |  | 
|---|
| 71 | devinfo->busnum = busnum; | 
|---|
| 72 | devinfo->board_info = *info; | 
|---|
| 73 |  | 
|---|
| 74 | if (info->resources) { | 
|---|
| 75 | devinfo->board_info.resources = | 
|---|
| 76 | kmemdup(info->resources, | 
|---|
| 77 | info->num_resources * | 
|---|
| 78 | sizeof(*info->resources), | 
|---|
| 79 | GFP_KERNEL); | 
|---|
| 80 | if (!devinfo->board_info.resources) { | 
|---|
| 81 | status = -ENOMEM; | 
|---|
| 82 | kfree(objp: devinfo); | 
|---|
| 83 | break; | 
|---|
| 84 | } | 
|---|
| 85 | } | 
|---|
| 86 |  | 
|---|
| 87 | list_add_tail(new: &devinfo->list, head: &__i2c_board_list); | 
|---|
| 88 | } | 
|---|
| 89 |  | 
|---|
| 90 | up_write(sem: &__i2c_board_lock); | 
|---|
| 91 |  | 
|---|
| 92 | return status; | 
|---|
| 93 | } | 
|---|
| 94 |  | 
|---|