![Florian Fainelli](/assets/img/avatar_default.png)
mdio-boardinfo contains code that is helpful for platforms to register specific MDIO bus devices independent of how CONFIG_MDIO_DEVICE or CONFIG_PHYLIB will be selected (modular or built-in). In order to make that possible, let's do the following: - descend into drivers/net/phy/ unconditionally - make mdiobus_setup_mdiodev_from_board_info() take a callback argument which allows us not to expose the internal MDIO board info list and mutex, yet maintain the logic within the same file - relocate the code that creates a MDIO device into drivers/net/phy/mdio_bus.c - build mdio-boardinfo.o into the kernel as soon as MDIO_DEVICE is defined (y or m) Fixes:90eff9096c
("net: phy: Allow splitting MDIO bus/device support from PHYs") Fixes:648ea01340
("net: phy: Allow pre-declaration of MDIO devices") Signed-off-by: Florian Fainelli <f.fainelli@gmail.com> Tested-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: David S. Miller <davem@davemloft.net>
81 lines
2 KiB
C
81 lines
2 KiB
C
/*
|
|
* mdio-boardinfo - Collect pre-declarations for MDIO devices
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License as published by the
|
|
* Free Software Foundation; either version 2 of the License, or (at your
|
|
* option) any later version.
|
|
*/
|
|
|
|
#include <linux/kernel.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/export.h>
|
|
#include <linux/mutex.h>
|
|
#include <linux/list.h>
|
|
|
|
#include "mdio-boardinfo.h"
|
|
|
|
static LIST_HEAD(mdio_board_list);
|
|
static DEFINE_MUTEX(mdio_board_lock);
|
|
|
|
/**
|
|
* mdiobus_setup_mdiodev_from_board_info - create and setup MDIO devices
|
|
* from pre-collected board specific MDIO information
|
|
* @mdiodev: MDIO device pointer
|
|
* Context: can sleep
|
|
*/
|
|
void mdiobus_setup_mdiodev_from_board_info(struct mii_bus *bus,
|
|
int (*cb)
|
|
(struct mii_bus *bus,
|
|
struct mdio_board_info *bi))
|
|
{
|
|
struct mdio_board_entry *be;
|
|
struct mdio_board_info *bi;
|
|
int ret;
|
|
|
|
mutex_lock(&mdio_board_lock);
|
|
list_for_each_entry(be, &mdio_board_list, list) {
|
|
bi = &be->board_info;
|
|
|
|
if (strcmp(bus->id, bi->bus_id))
|
|
continue;
|
|
|
|
ret = cb(bus, bi);
|
|
if (ret)
|
|
continue;
|
|
|
|
}
|
|
mutex_unlock(&mdio_board_lock);
|
|
}
|
|
EXPORT_SYMBOL(mdiobus_setup_mdiodev_from_board_info);
|
|
|
|
/**
|
|
* mdio_register_board_info - register MDIO devices for a given board
|
|
* @info: array of devices descriptors
|
|
* @n: number of descriptors provided
|
|
* Context: can sleep
|
|
*
|
|
* The board info passed can be marked with __initdata but be pointers
|
|
* such as platform_data etc. are copied as-is
|
|
*/
|
|
int mdiobus_register_board_info(const struct mdio_board_info *info,
|
|
unsigned int n)
|
|
{
|
|
struct mdio_board_entry *be;
|
|
unsigned int i;
|
|
|
|
be = kcalloc(n, sizeof(*be), GFP_KERNEL);
|
|
if (!be)
|
|
return -ENOMEM;
|
|
|
|
for (i = 0; i < n; i++, be++, info++) {
|
|
memcpy(&be->board_info, info, sizeof(*info));
|
|
mutex_lock(&mdio_board_lock);
|
|
list_add_tail(&be->list, &mdio_board_list);
|
|
mutex_unlock(&mdio_board_lock);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
EXPORT_SYMBOL(mdiobus_register_board_info);
|