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 * @mdiodev: MDIO device pointer
  21 * Context: can sleep
  22 */
  23void mdiobus_setup_mdiodev_from_board_info(struct mii_bus *bus,
  24                                           int (*cb)
  25                                           (struct mii_bus *bus,
  26                                            struct mdio_board_info *bi))
  27{
  28        struct mdio_board_entry *be;
  29        struct mdio_board_entry *tmp;
  30        struct mdio_board_info *bi;
  31        int ret;
  32
  33        mutex_lock(&mdio_board_lock);
  34        list_for_each_entry_safe(be, tmp, &mdio_board_list, list) {
  35                bi = &be->board_info;
  36
  37                if (strcmp(bus->id, bi->bus_id))
  38                        continue;
  39
  40                mutex_unlock(&mdio_board_lock);
  41                ret = cb(bus, bi);
  42                mutex_lock(&mdio_board_lock);
  43                if (ret)
  44                        continue;
  45
  46        }
  47        mutex_unlock(&mdio_board_lock);
  48}
  49EXPORT_SYMBOL(mdiobus_setup_mdiodev_from_board_info);
  50
  51/**
  52 * mdio_register_board_info - register MDIO devices for a given board
  53 * @info: array of devices descriptors
  54 * @n: number of descriptors provided
  55 * Context: can sleep
  56 *
  57 * The board info passed can be marked with __initdata but be pointers
  58 * such as platform_data etc. are copied as-is
  59 */
  60int mdiobus_register_board_info(const struct mdio_board_info *info,
  61                                unsigned int n)
  62{
  63        struct mdio_board_entry *be;
  64        unsigned int i;
  65
  66        be = kcalloc(n, sizeof(*be), GFP_KERNEL);
  67        if (!be)
  68                return -ENOMEM;
  69
  70        for (i = 0; i < n; i++, be++, info++) {
  71                memcpy(&be->board_info, info, sizeof(*info));
  72                mutex_lock(&mdio_board_lock);
  73                list_add_tail(&be->list, &mdio_board_list);
  74                mutex_unlock(&mdio_board_lock);
  75        }
  76
  77        return 0;
  78}
  79EXPORT_SYMBOL(mdiobus_register_board_info);
  80