Commit | Line | Data |
---|---|---|
a2443fd1 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
648ea013 FF |
2 | /* |
3 | * mdio-boardinfo - Collect pre-declarations for MDIO devices | |
648ea013 FF |
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 | ||
14 | static LIST_HEAD(mdio_board_list); | |
15 | static 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 | |
19c5a5fe AL |
20 | * @bus: Bus the board_info belongs to |
21 | * @cb: Callback to create device on bus | |
648ea013 FF |
22 | * Context: can sleep |
23 | */ | |
d0281a56 FF |
24 | void mdiobus_setup_mdiodev_from_board_info(struct mii_bus *bus, |
25 | int (*cb) | |
26 | (struct mii_bus *bus, | |
27 | struct mdio_board_info *bi)) | |
648ea013 FF |
28 | { |
29 | struct mdio_board_entry *be; | |
0263ea5c | 30 | struct mdio_board_entry *tmp; |
648ea013 FF |
31 | struct mdio_board_info *bi; |
32 | int ret; | |
33 | ||
34 | mutex_lock(&mdio_board_lock); | |
0263ea5c | 35 | list_for_each_entry_safe(be, tmp, &mdio_board_list, list) { |
648ea013 FF |
36 | bi = &be->board_info; |
37 | ||
38 | if (strcmp(bus->id, bi->bus_id)) | |
39 | continue; | |
40 | ||
0263ea5c | 41 | mutex_unlock(&mdio_board_lock); |
d0281a56 | 42 | ret = cb(bus, bi); |
0263ea5c | 43 | mutex_lock(&mdio_board_lock); |
d0281a56 | 44 | if (ret) |
648ea013 FF |
45 | continue; |
46 | ||
648ea013 FF |
47 | } |
48 | mutex_unlock(&mdio_board_lock); | |
49 | } | |
d0281a56 | 50 | EXPORT_SYMBOL(mdiobus_setup_mdiodev_from_board_info); |
648ea013 FF |
51 | |
52 | /** | |
4db0964a | 53 | * mdiobus_register_board_info - register MDIO devices for a given board |
648ea013 FF |
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 | } | |
90eff909 | 80 | EXPORT_SYMBOL(mdiobus_register_board_info); |