linux/drivers/net/phy/mdio-boardinfo.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * mdio-boardinfo - Collect pre-declarations for MDIO devices
   4 */
   5
   6#include <linux/kernel.h>
   7#include <linux/slab.h>
   8#include <linux/export.h>
   9#include <linux/mutex.h>
  10#include <linux/list.h>
  11
  12#include "mdio-boardinfo.h"
  13
  14static LIST_HEAD(mdio_board_list);
  15static DEFINE_MUTEX(mdio_board_lock);
  16
  17/**
  18 * mdiobus_setup_mdiodev_from_board_info - create and setup MDIO devices
  19 * from pre-collected board specific MDIO information
  20 * @bus: Bus the board_info belongs to
  21 * @cb: Callback to create device on bus
  22 * Context: can sleep
  23 */
  24void mdiobus_setup_mdiodev_from_board_info(struct mii_bus *bus,
  25                                           int (*cb)
  26                                           (struct mii_bus *bus,
  27                                            struct mdio_board_info *bi))
  28{
  29        struct mdio_board_entry *be;
  30        struct mdio_board_entry *tmp;
  31        struct mdio_board_info *bi;
  32        int ret;
  33
  34        mutex_lock(&mdio_board_lock);
  35        list_for_each_entry_safe(be, tmp, &mdio_board_list, list) {
  36                bi = &be->board_info;
  37
  38                if (strcmp(bus->id, bi->bus_id))
  39                        continue;
  40
  41                mutex_unlock(&mdio_board_lock);
  42                ret = cb(bus, bi);
  43                mutex_lock(&mdio_board_lock);
  44                if (ret)
  45                        continue;
  46
  47        }
  48        mutex_unlock(&mdio_board_lock);
  49}
  50EXPORT_SYMBOL(mdiobus_setup_mdiodev_from_board_info);
  51
  52/**
  53 * mdiobus_register_board_info - register MDIO devices for a given board
  54 * @info: array of devices descriptors
  55 * @n: number of descriptors provided
  56 * Context: can sleep
  57 *
  58 * The board info passed can be marked with __initdata but be pointers
  59 * such as platform_data etc. are copied as-is
  60 */
  61int mdiobus_register_board_info(const struct mdio_board_info *info,
  62                                unsigned int n)
  63{
  64        struct mdio_board_entry *be;
  65        unsigned int i;
  66
  67        be = kcalloc(n, sizeof(*be), GFP_KERNEL);
  68        if (!be)
  69                return -ENOMEM;
  70
  71        for (i = 0; i < n; i++, be++, info++) {
  72                memcpy(&be->board_info, info, sizeof(*info));
  73                mutex_lock(&mdio_board_lock);
  74                list_add_tail(&be->list, &mdio_board_list);
  75                mutex_unlock(&mdio_board_lock);
  76        }
  77
  78        return 0;
  79}
  80EXPORT_SYMBOL(mdiobus_register_board_info);
  81