diff options
Diffstat (limited to 'meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.35-phylib-Support-phy-module-autoloading.patch')
-rw-r--r-- | meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.35-phylib-Support-phy-module-autoloading.patch | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.35-phylib-Support-phy-module-autoloading.patch b/meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.35-phylib-Support-phy-module-autoloading.patch new file mode 100644 index 000000000..fae435e96 --- /dev/null +++ b/meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.35-phylib-Support-phy-module-autoloading.patch @@ -0,0 +1,150 @@ +From 8626d3b4328061f5b82b11ae1d6918a0c3602f42 Mon Sep 17 00:00:00 2001 +From: David Woodhouse <dwmw2@infradead.org> +Date: Fri, 2 Apr 2010 01:05:27 +0000 +Subject: [PATCH] phylib: Support phy module autoloading +Patch-mainline: 2.6.35 +Git-commit: 8626d3b4328061f5b82b11ae1d6918a0c3602f42 +Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6.git + +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. + +[bwh: s/phy/mdio/ in module alias, kerneldoc for struct mdio_device_id] + +Signed-off-by: David Woodhouse <David.Woodhouse@intel.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +Acked-by: Andy Fleming <afleming@freescale.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/phy/phy_device.c | 12 ++++++++++++ + include/linux/mod_devicetable.h | 26 ++++++++++++++++++++++++++ + include/linux/phy.h | 1 + + scripts/mod/file2alias.c | 26 ++++++++++++++++++++++++++ + 4 files changed, 65 insertions(+), 0 deletions(-) + +diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c +index db17945..1a99bb2 100644 +--- a/drivers/net/phy/phy_device.c ++++ b/drivers/net/phy/phy_device.c +@@ -149,6 +149,7 @@ EXPORT_SYMBOL(phy_scan_fixups); + struct phy_device* phy_device_create(struct mii_bus *bus, int addr, int phy_id) + { + struct phy_device *dev; ++ + /* We allocate the device, and initialize the + * default values */ + dev = kzalloc(sizeof(*dev), GFP_KERNEL); +@@ -179,6 +180,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); + ++ /* Request the appropriate module unconditionally; don't ++ bother trying to do so only if it isn't already loaded, ++ because that gets complicated. A hotplug event would have ++ done an unconditional modprobe anyway. ++ We don't do normal hotplug because it 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. */ ++ request_module(MDIO_MODULE_PREFIX MDIO_ID_FMT, MDIO_ID_ARGS(phy_id)); ++ + return dev; + } + EXPORT_SYMBOL(phy_device_create); +diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h +index f58e9d8..55f1f9c 100644 +--- a/include/linux/mod_devicetable.h ++++ b/include/linux/mod_devicetable.h +@@ -474,4 +474,30 @@ struct platform_device_id { + __attribute__((aligned(sizeof(kernel_ulong_t)))); + }; + ++#define MDIO_MODULE_PREFIX "mdio:" ++ ++#define MDIO_ID_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 MDIO_ID_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 mdio_device_id - identifies PHY devices on an MDIO/MII bus ++ * @phy_id: The result of ++ * (mdio_read(&MII_PHYSID1) << 16 | mdio_read(&PHYSID2)) & @phy_id_mask ++ * for this PHY type ++ * @phy_id_mask: Defines the significant bits of @phy_id. A value of 0 ++ * is used to terminate an array of struct mdio_device_id. ++ */ ++struct mdio_device_id { ++ __u32 phy_id; ++ __u32 phy_id_mask; ++}; ++ + #endif /* LINUX_MOD_DEVICETABLE_H */ +diff --git a/include/linux/phy.h b/include/linux/phy.h +index d9bce4b..987e111 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..36a60a8 100644 +--- a/scripts/mod/file2alias.c ++++ b/scripts/mod/file2alias.c +@@ -796,6 +796,28 @@ static int do_platform_entry(const char *filename, + return 1; + } + ++static int do_mdio_entry(const char *filename, ++ struct mdio_device_id *id, char *alias) ++{ ++ int i; ++ ++ alias += sprintf(alias, MDIO_MODULE_PREFIX); ++ ++ for (i = 0; i < 32; i++) { ++ if (!((id->phy_id_mask >> (31-i)) & 1)) ++ *(alias++) = '?'; ++ else if ((id->phy_id >> (31-i)) & 1) ++ *(alias++) = '1'; ++ else ++ *(alias++) = '0'; ++ } ++ ++ /* Terminate the string */ ++ *alias = 0; ++ ++ return 1; ++} ++ + /* Ignore any prefix, eg. some architectures prepend _ */ + static inline int sym_is(const char *symbol, const char *name) + { +@@ -943,6 +965,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_mdio_device_table")) ++ do_table(symval, sym->st_size, ++ sizeof(struct mdio_device_id), "mdio", ++ do_mdio_entry, mod); + free(zeros); + } + +-- +1.6.5 + |