1 /* 2 * mdio-boardinfo - Collect pre-declarations for MDIO devices 3 * 4 * This program is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License as published by the 6 * Free Software Foundation; either version 2 of the License, or (at your 7 * option) any later version. 8 */ 9 10 #include <linux/kernel.h> 11 #include <linux/slab.h> 12 #include <linux/export.h> 13 #include <linux/mutex.h> 14 #include <linux/list.h> 15 16 #include "mdio-boardinfo.h" 17 18 static LIST_HEAD(mdio_board_list); 19 static DEFINE_MUTEX(mdio_board_lock); 20 21 /** 22 * mdiobus_setup_mdiodev_from_board_info - create and setup MDIO devices 23 * from pre-collected board specific MDIO information 24 * @mdiodev: MDIO device pointer 25 * Context: can sleep 26 */ 27 void mdiobus_setup_mdiodev_from_board_info(struct mii_bus *bus, 28 int (*cb) 29 (struct mii_bus *bus, 30 struct mdio_board_info *bi)) 31 { 32 struct mdio_board_entry *be; 33 struct mdio_board_info *bi; 34 int ret; 35 36 mutex_lock(&mdio_board_lock); 37 list_for_each_entry(be, &mdio_board_list, list) { 38 bi = &be->board_info; 39 40 if (strcmp(bus->id, bi->bus_id)) 41 continue; 42 43 ret = cb(bus, bi); 44 if (ret) 45 continue; 46 47 } 48 mutex_unlock(&mdio_board_lock); 49 } 50 EXPORT_SYMBOL(mdiobus_setup_mdiodev_from_board_info); 51 52 /** 53 * mdio_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 */ 61 int 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 } 80 EXPORT_SYMBOL(mdiobus_register_board_info); 81