summaryrefslogtreecommitdiff
path: root/target/mips/mikrotik-rb4xx/patches/3.14.28/0021-phy-add-mdio-boardinfo.patch
blob: 3ec15e1714b31ea263de33432dd15e2f2c5862b2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
From b8d5957374dc0e6ec8687c6e1b154ea066d27a5b Mon Sep 17 00:00:00 2001
From: Phil Sutter <phil@nwl.cc>
Date: Wed, 14 May 2014 02:44:43 +0200
Subject: [PATCH] phy: add mdio boardinfo

---
 drivers/net/Makefile             |  2 +-
 drivers/net/phy/Kconfig          |  4 +++
 drivers/net/phy/Makefile         |  2 ++
 drivers/net/phy/mdio-boardinfo.c | 58 ++++++++++++++++++++++++++++++++++++++++
 drivers/net/phy/mdio-boardinfo.h | 22 +++++++++++++++
 drivers/net/phy/mdio_bus.c       | 20 ++++++++++++++
 include/linux/phy.h              | 18 +++++++++++++
 7 files changed, 125 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/phy/mdio-boardinfo.c
 create mode 100644 drivers/net/phy/mdio-boardinfo.h

diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 3fef8a8..70b736b 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -15,7 +15,7 @@ obj-$(CONFIG_MII) += mii.o
 obj-$(CONFIG_MDIO) += mdio.o
 obj-$(CONFIG_NET) += Space.o loopback.o
 obj-$(CONFIG_NETCONSOLE) += netconsole.o
-obj-$(CONFIG_PHYLIB) += phy/
+obj-y += phy/
 obj-$(CONFIG_RIONET) += rionet.o
 obj-$(CONFIG_NET_TEAM) += team/
 obj-$(CONFIG_TUN) += tun.o
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 0414889..97ca8ec 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -12,6 +12,10 @@ menuconfig PHYLIB
 
 if PHYLIB
 
+config MDIO_BOARDINFO
+	bool
+	default y
+
 config SWCONFIG
 	tristate "Switch configuration API"
 	---help---
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 3c76ff8..0c990a4 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -2,6 +2,8 @@
 
 libphy-objs			:= phy.o phy_device.o mdio_bus.o
 
+obj-$(CONFIG_MDIO_BOARDINFO)	+= mdio-boardinfo.o
+
 obj-$(CONFIG_PHYLIB)		+= libphy.o
 obj-$(CONFIG_SWCONFIG)		+= swconfig.o
 obj-$(CONFIG_MARVELL_PHY)	+= marvell.o
diff --git a/drivers/net/phy/mdio-boardinfo.c b/drivers/net/phy/mdio-boardinfo.c
new file mode 100644
index 0000000..9b8aaed
--- /dev/null
+++ b/drivers/net/phy/mdio-boardinfo.c
@@ -0,0 +1,58 @@
+/*
+ * mdio-boardinfo.c - collect pre-declarations of PHY 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/phy.h>
+#include <linux/slab.h>
+#include <linux/export.h>
+#include <linux/mutex.h>
+#include <linux/phy.h>
+
+#include "mdio-boardinfo.h"
+
+/*
+ * These symbols are exported ONLY FOR the mdio_bus component.
+ * No other users will be supported.
+ */
+
+LIST_HEAD(__mdio_board_list);
+EXPORT_SYMBOL_GPL(__mdio_board_list);
+
+DEFINE_MUTEX(__mdio_board_lock);
+EXPORT_SYMBOL_GPL(__mdio_board_lock);
+
+/**
+ * mdio_register_board_info - register PHY devices for a given board
+ * @info: array of chip descriptors
+ * @n: how many descriptors are provided
+ * Context: can sleep
+ *
+ * The board info passed can safely be __initdata ... but be careful of
+ * any embedded pointers (platform_data, etc), they're copied as-is.
+ */
+int __init
+mdiobus_register_board_info(struct mdio_board_info const *info, unsigned n)
+{
+	struct mdio_board_entry *be;
+	int i;
+
+	be = kzalloc(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;
+}
diff --git a/drivers/net/phy/mdio-boardinfo.h b/drivers/net/phy/mdio-boardinfo.h
new file mode 100644
index 0000000..28fbc0d
--- /dev/null
+++ b/drivers/net/phy/mdio-boardinfo.h
@@ -0,0 +1,22 @@
+/*
+ * mdio-boardinfo.h - boardinfo interface internal to the mdio_bus component
+ *
+ * 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/mutex.h>
+
+struct mdio_board_entry {
+	struct list_head	list;
+	struct mdio_board_info	board_info;
+};
+
+/* __mdio_board_lock protects __mdio_board_list
+ * only mdio_bus components are allowed to use these symbols.
+ */
+extern struct mutex __mdio_board_lock;
+extern struct list_head __mdio_board_list;
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 71e4900..50fbe35 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -38,6 +38,8 @@
 
 #include <asm/irq.h>
 
+#include "mdio-boardinfo.h"
+
 /**
  * mdiobus_alloc_size - allocate a mii_bus structure
  * @size: extra amount of memory to allocate for private storage.
@@ -224,15 +226,33 @@ void mdiobus_free(struct mii_bus *bus)
 }
 EXPORT_SYMBOL(mdiobus_free);
 
+static void mdiobus_setup_phydev_from_boardinfo(struct mii_bus *bus,
+						struct phy_device *phydev,
+						struct mdio_board_info *bi)
+{
+	if (strcmp(bus->id, bi->bus_id) ||
+	    bi->phy_addr != phydev->addr)
+	    return;
+
+	phydev->dev.platform_data = (void *) bi->platform_data;
+}
+
 struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr)
 {
 	struct phy_device *phydev;
+	struct mdio_board_entry *be;
 	int err;
 
 	phydev = get_phy_device(bus, addr, false);
 	if (IS_ERR(phydev) || phydev == NULL)
 		return phydev;
 
+	mutex_lock(&__mdio_board_lock);
+	list_for_each_entry(be, &__mdio_board_list, list)
+		mdiobus_setup_phydev_from_boardinfo(bus, phydev,
+						    &be->board_info);
+	mutex_unlock(&__mdio_board_lock);
+
 	err = phy_device_register(phydev);
 	if (err) {
 		phy_device_free(phydev);
diff --git a/include/linux/phy.h b/include/linux/phy.h
index f1441b4..9dca415 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -658,4 +658,22 @@ int __init mdio_bus_init(void);
 void mdio_bus_exit(void);
 
 extern struct bus_type mdio_bus_type;
+
+struct mdio_board_info {
+	const char	*bus_id;
+	int		phy_addr;
+
+	const void	*platform_data;
+};
+
+#ifdef CONFIG_MDIO_BOARDINFO
+int mdiobus_register_board_info(const struct mdio_board_info *info, unsigned n);
+#else
+static inline int
+mdiobus_register_board_info(const struct mdio_board_info *info, unsigned n)
+{
+	return 0;
+}
+#endif
+
 #endif /* __PHY_H */
-- 
1.8.5.3