linux/drivers/i2c/i2c-boardinfo.c
<<
>>
Prefs
   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 */
  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 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 */
  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