summaryrefslogtreecommitdiff
path: root/target/mips/mikrotik-rb4xx/patches/4.1.10/0021-phy-add-mdio-boardinfo.patch
blob: 1c760927db8e33751f0fb96570389c0191f57cb5 (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
diff -Nur linux-4.1.6.orig/drivers/net/Makefile linux-4.1.6/drivers/net/Makefile
--- linux-4.1.6.orig/drivers/net/Makefile	2015-08-17 05:52:51.000000000 +0200
+++ linux-4.1.6/drivers/net/Makefile	2015-09-13 20:42:49.905256073 +0200
@@ -16,7 +16,7 @@
 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 -Nur linux-4.1.6.orig/drivers/net/phy/Kconfig linux-4.1.6/drivers/net/phy/Kconfig
--- linux-4.1.6.orig/drivers/net/phy/Kconfig	2015-08-17 05:52:51.000000000 +0200
+++ linux-4.1.6/drivers/net/phy/Kconfig	2015-09-13 20:43:24.979410253 +0200
@@ -12,6 +12,10 @@
 
 if PHYLIB
 
+config MDIO_BOARDINFO
+       bool
+       default y
+
 comment "MII PHY device drivers"
 
 config AT803X_PHY
diff -Nur linux-4.1.6.orig/drivers/net/phy/Makefile linux-4.1.6/drivers/net/phy/Makefile
--- linux-4.1.6.orig/drivers/net/phy/Makefile	2015-08-17 05:52:51.000000000 +0200
+++ linux-4.1.6/drivers/net/phy/Makefile	2015-09-13 20:42:49.917255441 +0200
@@ -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_MARVELL_PHY)	+= marvell.o
 obj-$(CONFIG_DAVICOM_PHY)	+= davicom.o
diff -Nur linux-4.1.6.orig/drivers/net/phy/mdio-boardinfo.c linux-4.1.6/drivers/net/phy/mdio-boardinfo.c
--- linux-4.1.6.orig/drivers/net/phy/mdio-boardinfo.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-4.1.6/drivers/net/phy/mdio-boardinfo.c	2015-09-13 20:42:49.917255441 +0200
@@ -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 -Nur linux-4.1.6.orig/drivers/net/phy/mdio-boardinfo.h linux-4.1.6/drivers/net/phy/mdio-boardinfo.h
--- linux-4.1.6.orig/drivers/net/phy/mdio-boardinfo.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-4.1.6/drivers/net/phy/mdio-boardinfo.h	2015-09-13 20:42:49.917255441 +0200
@@ -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 -Nur linux-4.1.6.orig/drivers/net/phy/mdio_bus.c linux-4.1.6/drivers/net/phy/mdio_bus.c
--- linux-4.1.6.orig/drivers/net/phy/mdio_bus.c	2015-08-17 05:52:51.000000000 +0200
+++ linux-4.1.6/drivers/net/phy/mdio_bus.c	2015-09-13 20:45:13.149717661 +0200
@@ -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.
@@ -335,15 +337,33 @@
 }
 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);
+
 	/*
 	 * For DT, see if the auto-probed phy has a correspoding child
 	 * in the bus node, and set the of_node pointer in this case.
diff -Nur linux-4.1.6.orig/include/linux/phy.h linux-4.1.6/include/linux/phy.h
--- linux-4.1.6.orig/include/linux/phy.h	2015-08-17 05:52:51.000000000 +0200
+++ linux-4.1.6/include/linux/phy.h	2015-09-13 20:46:09.506751805 +0200
@@ -787,6 +787,23 @@
 
 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
+
 /**
  * module_phy_driver() - Helper macro for registering PHY drivers
  * @__phy_drivers: array of PHY drivers to register