netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/2] phylib: Support phy module autoloading
@ 2010-03-31  1:18 David Woodhouse
  2010-04-01  4:34 ` Ben Hutchings
  0 siblings, 1 reply; 13+ messages in thread
From: David Woodhouse @ 2010-03-31  1:18 UTC (permalink / raw)
  To: davem; +Cc: netdev

We don't use the normal hotplug mechanism because it doesn't work. It will
load the module some time after the device appears, but that's not good
enough for us -- we need the driver loaded _immediately_ because otherwise
the NIC driver may just abort and then the phy 'device' goes away.

Instead, we just issue a request_module() directly in phy_device_create().

The device aliases take the form 'phy:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
with a binary representation of the phy_id. This means that the "don't
care" bits of driver's phy_id_mask can be question marks which modprobe
will interpret correctly as wildcards.

So a driver with { .phy_id = 0x02345600, .phy_id_mask = 0x0fffff00 }
will have an alias of phy:????00100011010001010110???????? and will be
loaded whenever any matching phy is created by phy_device_create().

Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
---
 drivers/net/phy/phy_device.c    |   13 +++++++++++++
 include/linux/mod_devicetable.h |   20 ++++++++++++++++++++
 include/linux/phy.h             |    1 +
 scripts/mod/file2alias.c        |   25 +++++++++++++++++++++++++
 4 files changed, 59 insertions(+), 0 deletions(-)

diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index db17945..b35ec7e 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -149,6 +149,8 @@ EXPORT_SYMBOL(phy_scan_fixups);
 struct phy_device* phy_device_create(struct mii_bus *bus, int addr, int phy_id)
 {
 	struct phy_device *dev;
+	char modid[37];
+
 	/* We allocate the device, and initialize the
 	 * default values */
 	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
@@ -179,6 +181,17 @@ struct phy_device* phy_device_create(struct mii_bus *bus, int addr, int phy_id)
 	mutex_init(&dev->lock);
 	INIT_DELAYED_WORK(&dev->state_queue, phy_state_machine);
 
+#ifdef CONFIG_MODULES
+	/* Request the appropriate module unconditionally. A hotplug
+	   event would have done so anyway. But normal hotplug won't
+	   work for MDIO -- because it relies on the device staying
+	   around for long enough for the driver to get loaded. With
+	   MDIO, the NIC driver will get bored and give up as soon
+	   as it finds that there's no driver _already_ loaded. */
+	sprintf(modid, "phy:" PHYID_FMT, PHYID_ARGS(phy_id));
+	request_module(modid);
+#endif
+
 	return dev;
 }
 EXPORT_SYMBOL(phy_device_create);
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index f58e9d8..0c3e300 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -474,4 +474,24 @@ struct platform_device_id {
 			__attribute__((aligned(sizeof(kernel_ulong_t))));
 };
 
+#define PHY_MODULE_PREFIX	"phy:"
+
+#define PHYID_FMT "%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d"
+#define PHYID_ARGS(_id) \
+	(_id)>>31, ((_id)>>30) & 1, ((_id)>>29) & 1, ((_id)>>28) & 1,	\
+	((_id)>>27) & 1, ((_id)>>26) & 1, ((_id)>>25) & 1, ((_id)>>24) & 1, \
+	((_id)>>23) & 1, ((_id)>>22) & 1, ((_id)>>21) & 1, ((_id)>>20) & 1, \
+	((_id)>>19) & 1, ((_id)>>18) & 1, ((_id)>>17) & 1, ((_id)>>16) & 1, \
+	((_id)>>15) & 1, ((_id)>>14) & 1, ((_id)>>13) & 1, ((_id)>>12) & 1, \
+	((_id)>>11) & 1, ((_id)>>10) & 1, ((_id)>>9) & 1, ((_id)>>8) & 1, \
+	((_id)>>7) & 1, ((_id)>>6) & 1, ((_id)>>5) & 1, ((_id)>>4) & 1, \
+	((_id)>>3) & 1, ((_id)>>2) & 1, ((_id)>>1) & 1, (_id) & 1
+
+
+
+struct phy_device_id {
+	uint32_t phy_id;
+	uint32_t phy_id_mask;
+};
+
 #endif /* LINUX_MOD_DEVICETABLE_H */
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 14d7fdf..f269f1b 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -24,6 +24,7 @@
 #include <linux/mii.h>
 #include <linux/timer.h>
 #include <linux/workqueue.h>
+#include <linux/mod_devicetable.h>
 
 #include <asm/atomic.h>
 
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 220213e..b412185 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -796,6 +796,27 @@ static int do_platform_entry(const char *filename,
 	return 1;
 }
 
+static int do_phy_entry(const char *filename,
+			struct phy_device_id *id, char *alias)
+{
+	char str[33];
+	int i;
+
+	str[32] = 0;
+
+	for (i = 0; i < 32; i++) {
+		if (!((id->phy_id_mask >> (31-i)) & 1))
+			str[i] = '?';
+		else if ((id->phy_id >> (31-i)) & 1)
+			str[i] = '1';
+		else
+			str[i] = '0';
+	}
+
+	sprintf(alias, PHY_MODULE_PREFIX "%s", str);
+	return 1;
+}
+
 /* Ignore any prefix, eg. some architectures prepend _ */
 static inline int sym_is(const char *symbol, const char *name)
 {
@@ -943,6 +964,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
 		do_table(symval, sym->st_size,
 			 sizeof(struct platform_device_id), "platform",
 			 do_platform_entry, mod);
+	else if (sym_is(symname, "__mod_phy_device_table"))
+		do_table(symval, sym->st_size,
+			 sizeof(struct phy_device_id), "phy",
+			 do_phy_entry, mod);
 	free(zeros);
 }
 
-- 
1.6.6.1

-- 
David Woodhouse                            Open Source Technology Centre
David.Woodhouse@intel.com                              Intel Corporation


^ permalink raw reply related	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2010-04-02 21:31 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-03-31  1:18 [PATCH 1/2] phylib: Support phy module autoloading David Woodhouse
2010-04-01  4:34 ` Ben Hutchings
2010-04-01 17:03   ` David Woodhouse
2010-04-01 18:05     ` Ben Hutchings
2010-04-02  2:38       ` David Miller
2010-04-02 11:05         ` David Woodhouse
2010-04-02 17:51           ` Andy Fleming
2010-04-02 21:31           ` David Miller
2010-04-02 11:05         ` [PATCH 2/2] phylib: Add module table to all existing phy drivers David Woodhouse
2010-04-02 21:31           ` David Miller
2010-04-02 11:14         ` [PATCH 1/2] phylib: Support phy module autoloading David Woodhouse
2010-04-02 15:51           ` Ben Hutchings
2010-04-02 10:38   ` David Woodhouse

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).