Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * mdio-boardinfo - Collect pre-declarations for MDIO devices
0004  */
0005 
0006 #include <linux/kernel.h>
0007 #include <linux/slab.h>
0008 #include <linux/export.h>
0009 #include <linux/mutex.h>
0010 #include <linux/list.h>
0011 
0012 #include "mdio-boardinfo.h"
0013 
0014 static LIST_HEAD(mdio_board_list);
0015 static DEFINE_MUTEX(mdio_board_lock);
0016 
0017 /**
0018  * mdiobus_setup_mdiodev_from_board_info - create and setup MDIO devices
0019  * from pre-collected board specific MDIO information
0020  * @bus: Bus the board_info belongs to
0021  * @cb: Callback to create device on bus
0022  * Context: can sleep
0023  */
0024 void mdiobus_setup_mdiodev_from_board_info(struct mii_bus *bus,
0025                        int (*cb)
0026                        (struct mii_bus *bus,
0027                         struct mdio_board_info *bi))
0028 {
0029     struct mdio_board_entry *be;
0030     struct mdio_board_entry *tmp;
0031     struct mdio_board_info *bi;
0032     int ret;
0033 
0034     mutex_lock(&mdio_board_lock);
0035     list_for_each_entry_safe(be, tmp, &mdio_board_list, list) {
0036         bi = &be->board_info;
0037 
0038         if (strcmp(bus->id, bi->bus_id))
0039             continue;
0040 
0041         mutex_unlock(&mdio_board_lock);
0042         ret = cb(bus, bi);
0043         mutex_lock(&mdio_board_lock);
0044         if (ret)
0045             continue;
0046 
0047     }
0048     mutex_unlock(&mdio_board_lock);
0049 }
0050 EXPORT_SYMBOL(mdiobus_setup_mdiodev_from_board_info);
0051 
0052 /**
0053  * mdiobus_register_board_info - register MDIO devices for a given board
0054  * @info: array of devices descriptors
0055  * @n: number of descriptors provided
0056  * Context: can sleep
0057  *
0058  * The board info passed can be marked with __initdata but be pointers
0059  * such as platform_data etc. are copied as-is
0060  */
0061 int mdiobus_register_board_info(const struct mdio_board_info *info,
0062                 unsigned int n)
0063 {
0064     struct mdio_board_entry *be;
0065     unsigned int i;
0066 
0067     be = kcalloc(n, sizeof(*be), GFP_KERNEL);
0068     if (!be)
0069         return -ENOMEM;
0070 
0071     for (i = 0; i < n; i++, be++, info++) {
0072         memcpy(&be->board_info, info, sizeof(*info));
0073         mutex_lock(&mdio_board_lock);
0074         list_add_tail(&be->list, &mdio_board_list);
0075         mutex_unlock(&mdio_board_lock);
0076     }
0077 
0078     return 0;
0079 }
0080 EXPORT_SYMBOL(mdiobus_register_board_info);