brintos

brintos / linux-shallow public Read only

0
0
Text · 2.6 KiB · 4df8ad0 Raw
94 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * i2c-boardinfo.c - collect pre-declarations of I2C devices4 */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 */19DECLARE_RWSEM(__i2c_board_lock);20EXPORT_SYMBOL_GPL(__i2c_board_lock);21 22LIST_HEAD(__i2c_board_list);23EXPORT_SYMBOL_GPL(__i2c_board_list);24 25int __i2c_first_dynamic_bus_num;26EXPORT_SYMBOL_GPL(__i2c_first_dynamic_bus_num);27 28 29/**30 * i2c_register_board_info - statically declare I2C devices31 * @busnum: identifies the bus to which these devices belong32 * @info: vector of i2c device descriptors33 * @len: how many descriptors in the vector; may be zero to reserve34 *	the specified bus number.35 *36 * Systems using the Linux I2C driver stack can declare tables of board info37 * while they initialize.  This should be done in board-specific init code38 * near arch_initcall() time, or equivalent, before any I2C adapter driver is39 * 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 relevant43 * bus has been registered.  After that moment, standard driver model tools44 * are used to bind "new style" I2C drivers to the devices.  The bus number45 * for any device declared using this routine is not available for dynamic46 * allocation.47 *48 * The board info passed can safely be __initdata, but be careful of embedded49 * pointers (for platform_data, functions, etc) since that won't be copied.50 */51int i2c_register_board_info(int busnum, struct i2c_board_info const *info, unsigned len)52{53	int status;54 55	down_write(&__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(devinfo);83				break;84			}85		}86 87		list_add_tail(&devinfo->list, &__i2c_board_list);88	}89 90	up_write(&__i2c_board_lock);91 92	return status;93}94