Hotplug for openfirmware/macio devices
Subsystems (8)
PATCH 1/1 Hotplug for openfirmware/macio devices
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Hey all -
Many devices on the macintosh hardware platform are hidden behind a macio asic that places devices beyond the PCI bus for hotplug. Loading the driver manually works fine, but we have this wonderful hotplug system now. Why should macio be a second class citizen?
At least for me, the most noticable one was my airport card, but there may be others. I only have an ibook and a powermac.
Attached are three patches, which do the following:
* kernel-of-hotplug.diff; against 2.6.9-rc2 (mainline)
~ - exports OF information to userspace
~ - removes struct of_device in favor of struct of_device_id, which
~ uses character arrays such that the structure can be more easily ~ used by module-init-tools [the renaming is required to use the ~ MODULE_DEVICE_TABLE macro] ~ - changes the semantics of OF_MATCH_ANY to be an empty string ~ - adds the name, type, and compat strings to the macio sysfs tree ~ - adds a hotplug filter to pass the name, type, and compat info
~ to hotplug
~ - adds the appropriate MODULE_DEVICE_TABLE entries so that
~ module-init-tools can know about macio devices
~ - (Yes, I know this information is available via /proc/device_tree,
~ but sysfs is a much more natural fit)
* hotplug-macio.diff
~ - macio.rc: handles coldplugging of devices by traversing
~ the macio sysfs tree
~ - macio.agent: handles macio hotplug events
* module-init-tools-3.0-pre10-openfirmware.diff
~ - adds support for a modules.ofmap table so that the hotplug scripts
~ can determine which modules to load based on the OF information.
Is there a limit for the length of the various OF strings? I've assumed 32 for the sake of testing, but it's completely arbitrary.
Take a look if you're interested. My familiarity with the PPC world is peripheral at best. I'd love feedback.
- -Jeff
- --
Jeff Mahoney
SuSE Labs
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org
iD8DBQFBSfKpLPWxlyuTD7IRAjogAJ0YN3ikH4Vdlc0HFL8VqmudfXdWPgCff6D6 8AwEoPW6w5nUGlzAiHmiq4I=
=pF7H
-----END PGP SIGNATURE-----
etc/hotplug/macio.rc new file +96 -0
@@ -0,0 +1,96 @@ +#!/bin/bash +# $Id: ccw.rc,v 1.3 2004/05/13 11:59:50 hare Exp $ +# vim: syntax=sh +# +# macio.rc configure macio devices. +# + +SYSFS=needed +cd /etc/hotplug +. hotplug.functions + +if [ ! -d ${SYSFS}/bus/macio ]; then + echo "No macio bus support" + exit 0 +fi + +HWUP=/sbin/hwup +macio_call_hotplug () { + # There may be /etc/hotplug.d/default/eventrecorder.hotplug + # that logs the environment of every hotplug events. Therefore + # we keep environment clean. +# echo " "\ + eval \ + $ENV \ + ${ACTION:+ ACTION=$ACTION} \ + ${DEVPATH:+ DEVPATH="$DEVPATH"} \ + ${OF_NAME:+ OF_NAME="$OF_NAME"} \ + ${OF_TYPE:+ OF_TYPE="$OF_TYPE"} \ + ${OF_COMPATIBLE:+ OF_COMPATIBLE="$OF_COMPATIBLE"} \ + ${HOTPLUG_TRACE:+ HOTPLUG_TRACE="$HOTPLUG_TRACE"} \ + /sbin/hotplug macio \ + < /dev/null > /dev/null 2>&1 & +} +macio_boot_events_sysfs () { + cd /sys/bus/macio/devices + for i in *; do + + if [ -d /sys/bus/macio/drivers/*/$i \ + -a "$SKIP_DRIVEN_DEVICES" != no ]; then + echo -n . >&3 + fi + OF_NAME=`cat $i/name` + OF_TYPE=`cat $i/type` + OF_COMPATIBLE=`cat $i/compatible` + DEVPATH=`cd $i/ ; /bin/pwd` + echo -n "*" >&3 + macio_call_hotplug + done +} + +macio_boot_events () { + macio_boot_events_sysfs +} + +# See how we were called. +case "$1" in + start) + ACTION=add + macio_boot_events; + + # Configure all macio devices for which a hwcfg file is found + cd /etc/sysconfig/hardware + for cfg in hwcfg-bus-macio*; do + # Skip all symbolic links, only use the actual configuration + if [ -f "$cfg" -a ! -L "$cfg" ] ; then + cfgname=`echo $cfg | sed -n 's,hwcfg-.*-bus,bus,p;s,hwcfg-.*-id,id,p;s,hwcfg-bus,bus,p'` + if [ "$cfgname" ]; then + debug_mesg "Calling ${HWUP} ${cfgname}" + ${HWUP} ${cfgname} + echo -n "*" >&3 + else + echo -n "." >&3 + fi + fi + done + + + ;; + stop) + # echo "$0 stop -- ignored" + ;; + status) + # echo "$0 status -- ignored" + ;; + status-verbose) + # echo "$0 status-verbose -- ignored" + ;; + restart) + # always invoke by absolute path, else PATH=$PATH: + $0 stop && $0 start + ;; + *) + echo $"Usage: $0 {start|stop|status[-verbose]|restart}" + exit 1 + ;; +esac
etc/hotplug/macio.agent new file +84 -0
84 lines not on this page · raw message
module-init-tools-3.0-pre10/depmod.c +1 -0
@@ -648,6 +648,7 @@ static struct depfile depfiles[] = { { "modules.ieee1394map", output_ieee1394_table }, { "modules.isapnpmap", output_isapnp_table }, { "modules.inputmap", output_input_table }, + { "modules.ofmap", output_of_table }, { "modules.alias", output_aliases }, { "modules.symbols", output_symbols }, };
module-init-tools-3.0-pre10/depmod.h +2 -0
@@ -47,6 +47,8 @@ struct modulevoid *pnp_card_table;unsigned int input_size;void *input_table; +unsigned int of_size; +void *of_table;/* File contents and length. */ void *data;
module-init-tools-3.0-pre10/moduleops_core.c +5 -0
@@ -192,6 +192,11 @@ static void PERBIT(fetch_tables)(struct module->input_size =PERBIT (INPUT_DEVICE_SIZE ); module->input_table =PERBIT (deref_sym)(module->data,"__mod_input_device_table" ); + + module->of_size =PERBIT (OF_DEVICE_SIZE ); + module->of_table =PERBIT (deref_sym)(module->data, +"__mod_of_device_table" ); + }struct module_ops PERBIT (mod_ops ) = {
module-init-tools-3.0-pre10/tables.c +30 -0
@@ -340,3 +340,33 @@ void output_input_table(struct module *m } } } + +/* We set driver_data to zero */ +static void output_of_entry (struct of_device_id *dev,char *name,FILE *out) +{ + +fprintf (out,"%-20s %-20s %-20s %s\n" , + name, + dev->name[0 ] ? dev->name :"*" , + dev->type[0 ] ? dev->type :"*" , + dev->compatible[0 ] ? dev->compatible :"*" ); +} + +void output_of_table (struct module *modules,FILE *out) +{ +struct module *i; + +fprintf (out,"# of module name type compatible\n" ); +for (i = modules; i; i = i->next) { +struct of_device_id *e; +char shortname[strlen (i->pathname) +1 ]; + +if (!i->of_table) +continue ; + +make_shortname (shortname, i->pathname); +for (e = i->of_table; e->name[0 ]|e->type[0 ]|e->compatible[0 ]; + e = (void *)e + i->of_size) +output_of_entry (e, shortname, out); + } +}
module-init-tools-3.0-pre10/tables.h +11 -0
@@ -116,6 +116,16 @@ struct input_device_id_32 {#define INPUT_DEVICE_SIZE32 (4 + 4 * 2 + 4 + 16 * 4 + 4 + 2 * 4 + 4 + 4 + 4 + 4 * 4 + 4)#define INPUT_DEVICE_SIZE64 (8 + 4 * 2 + 8 + 8 * 8 + 8 + 8 + 8 + 8 + 8 + 2 * 8 + 8) +#define MAX_OF_NAMELEN (32) +struct of_device_id { +char name[MAX_OF_NAMELEN ]; +char type[MAX_OF_NAMELEN ]; +char compatible[MAX_OF_NAMELEN ]; +}; + +#define OF_DEVICE_SIZE32 (MAX_OF_NAMELEN * 3 + 4) +#define OF_DEVICE_SIZE64 (MAX_OF_NAMELEN * 3 + 8) +/* Functions provided by tables.c */ struct module ;void output_usb_table (struct module *modules,FILE *out);
@@ -124,5 +134,6 @@ void output_pci_table(struct module *modvoid output_ccw_table (struct module *modules,FILE *out);void output_isapnp_table (struct module *modules,FILE *out);void output_input_table (struct module *modules,FILE *out); +void output_of_table (struct module *modules,FILE *out);#endif /* MODINITTOOLS_TABLES_H */
arch/ppc/syslib/of_device.c +8 -7
@@ -3,6 +3,7 @@#include <linux/kernel.h> #include <linux/init.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <asm/errno.h> #include <asm/of_device.h>
@@ -15,20 +16,20 @@* Used by a driver to check whether an of_device present in the * system is in its list of supported devices. */ -const struct of_match *of_match_device (const struct of_match *matches, +const struct of_device_id *of_match_device (const struct of_device_id *matches,const struct of_device *dev) {if (!dev->node)return NULL ; -while (matches->name || matches->type || matches->compatible) { +while (matches->name[0 ] || matches->type[0 ] || matches->compatible[0 ]) {int match =1 ; -if (matches->name && matches->name !=OF_ANY_MATCH ) +if (matches->name[0 ]) match &= dev->node->name && !strcmp (matches->name, dev->node->name); -if (matches->type && matches->type !=OF_ANY_MATCH ) +if (matches->type[0 ]) match &= dev->node->type && !strcmp (matches->type, dev->node->type); -if (matches->compatible && matches->compatible !=OF_ANY_MATCH ) +if (matches->compatible[0 ]) match &=device_is_compatible (dev->node, matches->compatible);if (match)
@@ -42,7 +43,7 @@ static int of_platform_bus_match(struct {struct of_device * of_dev =to_of_device (dev);struct of_platform_driver * of_drv =to_of_platform_driver (drv); -const struct of_match * matches = of_drv->match_table; +const struct of_device_id * matches = of_drv->match_table;if (!matches)return 0 ;
@@ -75,7 +76,7 @@ static int of_device_probe(struct deviceint error = -ENODEV ;struct of_platform_driver *drv;struct of_device *of_dev; -const struct of_match *match; +const struct of_device_id *match; drv =to_of_platform_driver (dev->driver); of_dev =to_of_device (dev);
drivers/i2c/busses/i2c-keywest.c +3 -4
@@ -694,7 +694,7 @@ dispose_iface(struct device *dev) }static int -create_iface_macio (struct macio_dev * dev,const struct of_match *match) +create_iface_macio (struct macio_dev * dev,const struct of_device_id *match) {return create_iface (dev->ofdev.node, &dev->ofdev.dev); }
@@ -706,7 +706,7 @@ dispose_iface_macio(struct macio_dev* de }static int -create_iface_of_platform (struct of_device * dev,const struct of_match *match) +create_iface_of_platform (struct of_device * dev,const struct of_device_id *match) {return create_iface (dev->node, &dev->dev); }
@@ -717,10 +717,9 @@ dispose_iface_of_platform(struct of_devireturn dispose_iface (&dev->dev); } -static struct of_match i2c_keywest_match[] = +static struct of_device_id i2c_keywest_match[] = { { - .name =OF_ANY_MATCH , .type ="i2c" , .compatible ="keywest" },
drivers/ide/ppc/pmac.c +2 -10
@@ -1279,7 +1279,7 @@ pmac_ide_setup_device(pmac_ide_hwif_t *p* Attach to a macio probed interface */ static int __devinit -pmac_ide_macio_attach (struct macio_dev *mdev,const struct of_match *match) +pmac_ide_macio_attach (struct macio_dev *mdev,const struct of_device_id *match) {unsigned long base, regbase;int irq;
@@ -1500,27 +1500,19 @@ pmac_ide_pci_resume(struct pci_dev *pdevreturn rc; } -static struct of_match pmac_ide_macio_match[] = +static struct of_device_id pmac_ide_macio_match[] = { { .name ="IDE" , - .type =OF_ANY_MATCH , - .compatible =OF_ANY_MATCH }, { .name ="ATA" , - .type =OF_ANY_MATCH , - .compatible =OF_ANY_MATCH }, { - .name =OF_ANY_MATCH , .type ="ide" , - .compatible =OF_ANY_MATCH }, { - .name =OF_ANY_MATCH , .type ="ata" , - .compatible =OF_ANY_MATCH }, {}, };
drivers/macintosh/macio_asic.c +71 -2
96 lines not on this page · raw message
drivers/macintosh/macio_sysfs.c +49 -0
49 lines not on this page · raw message
drivers/macintosh/Makefile +1 -1
@@ -4,7 +4,7 @@ # Each configuration option enables a list of files. -obj-$(CONFIG_PPC_PMAC) += macio_asic.o +obj-$(CONFIG_PPC_PMAC) += macio_asic.o macio_sysfs.o obj-$(CONFIG_PMAC_PBOOK) += mediabay.o obj-$(CONFIG_MAC_SERIAL) += macserial.o
drivers/macintosh/mediabay.c +2 -5
@@ -648,7 +648,7 @@ static int __pmac media_bay_task(void *x } } -static int __devinit media_bay_attach (struct macio_dev *mdev,const struct of_match *match) +static int __devinit media_bay_attach (struct macio_dev *mdev,const struct of_device_id *match) {struct media_bay_info * bay;volatile u32 *regbase;
@@ -802,23 +802,20 @@ static struct mb_ops keylargo_mb_ops __p* Therefore we do it all by polling the media bay once each tick. */ -static struct of_match media_bay_match[] = +static struct of_device_id media_bay_match[] = { { .name ="media-bay" , - .type =OF_ANY_MATCH , .compatible ="keylargo-media-bay" , .data = &keylargo_mb_ops, }, { .name ="media-bay" , - .type =OF_ANY_MATCH , .compatible ="heathrow-media-bay" , .data = &heathrow_mb_ops, }, { .name ="media-bay" , - .type =OF_ANY_MATCH , .compatible ="ohare-media-bay" , .data = &ohare_mb_ops, },
drivers/macintosh/therm_windtunnel.c +3 -3
@@ -43,6 +43,7 @@#include <asm/system.h> #include <asm/sections.h> #include <asm/of_device.h> +#include <asm/macio.h> #define LOG_TEMP 0/* continously log temperature */
@@ -453,7 +454,7 @@ do_probe( struct i2c_adapter *adapter, i/************************************************************************/ static int -therm_of_probe (struct of_device *dev,const struct of_match *match ) +therm_of_probe (struct of_device *dev,const struct of_device_id *match ) {return i2c_add_driver ( &g4fan_driver ); }
@@ -464,9 +465,8 @@ therm_of_remove( struct of_device *dev )return i2c_del_driver ( &g4fan_driver ); } -static struct of_match therm_of_match[] = {{ +static struct of_device_id therm_of_match[] = {{ .name ="fan" , - .type =OF_ANY_MATCH , .compatible ="adm1030" }, {} };
drivers/net/wireless/airport.c +4 -4
@@ -188,7 +188,7 @@ static int airport_hard_reset(struct ori }static int -airport_attach (struct macio_dev *mdev,const struct of_match *match) +airport_attach (struct macio_dev *mdev,const struct of_device_id *match) {struct orinoco_private *priv;struct net_device *dev;
@@ -272,16 +272,16 @@ MODULE_AUTHOR("Benjamin Herrenschmidt <bMODULE_DESCRIPTION ("Driver for the Apple Airport wireless card." );MODULE_LICENSE ("Dual MPL/GPL" ); -static struct of_match airport_match[] = +static struct of_device_id airport_match[] = { { .name ="radio" , - .type =OF_ANY_MATCH , - .compatible =OF_ANY_MATCH }, {}, }; +MODULE_DEVICE_TABLE (of, airport_match); +static struct macio_driver airport_driver = { .name =DRIVER_NAME ,
Files linux-2.6.8/drivers/pci/gen-devlist and linux-2.6.8.devel/drivers/pci/gen-devlist differ
drivers/scsi/mac53c94.c +3 -4
@@ -425,7 +425,7 @@ static struct scsi_host_template mac53c9 .use_clustering = DISABLE_CLUSTERING, }; -static int mac53c94_probe (struct macio_dev *mdev,const struct of_match *match) +static int mac53c94_probe (struct macio_dev *mdev,const struct of_device_id *match) {struct device_node *node =macio_get_of_node (mdev);struct pci_dev *pdev =macio_get_pci_dev (mdev);
@@ -545,15 +545,14 @@ static int mac53c94_remove(struct macio_ } -static struct of_match mac53c94_match[] = +static struct of_device_id mac53c94_match[] = { { .name ="53c94" , - .type =OF_ANY_MATCH , - .compatible =OF_ANY_MATCH }, {}, }; +MODULE_DEVICE_TABLE (of, mac53c94_match);static struct macio_driver mac53c94_driver = {
drivers/scsi/mesh.c +3 -5
@@ -1847,7 +1847,7 @@ static struct scsi_host_template mesh_te .use_clustering = DISABLE_CLUSTERING, }; -static int mesh_probe (struct macio_dev *mdev,const struct of_match *match) +static int mesh_probe (struct macio_dev *mdev,const struct of_device_id *match) {struct device_node *mesh =macio_get_of_node (mdev);struct pci_dev * pdev =macio_get_pci_dev (mdev);
@@ -2014,20 +2014,18 @@ static int mesh_remove(struct macio_dev } -static struct of_match mesh_match[] = +static struct of_device_id mesh_match[] = { { .name ="mesh" , - .type =OF_ANY_MATCH , - .compatible =OF_ANY_MATCH }, { - .name =OF_ANY_MATCH , .type ="scsi" , .compatible ="chrp,mesh0" }, {}, }; +MODULE_DEVICE_TABLE (of, mesh_match);static struct macio_driver mesh_driver = {
drivers/serial/pmac_zilog.c +3 -6
@@ -1520,7 +1520,7 @@ static void pmz_dispose_port(struct uart/* * Called upon match with an escc node in the devive-tree. */ -static int pmz_attach (struct macio_dev *mdev,const struct of_match *match) +static int pmz_attach (struct macio_dev *mdev,const struct of_device_id *match) {int i;
@@ -1826,20 +1826,17 @@ err_out:return rc; } -static struct of_match pmz_match[] = +static struct of_device_id pmz_match[] = { { .name ="ch-a" , - .type =OF_ANY_MATCH , - .compatible =OF_ANY_MATCH }, { .name ="ch-b" , - .type =OF_ANY_MATCH , - .compatible =OF_ANY_MATCH }, {}, }; +MODULE_DEVICE_TABLE (of, pmz_match);static struct macio_driver pmz_driver = {
include/asm-ppc/macio.h +3 -2
@@ -1,6 +1,7 @@#ifndef __MACIO_ASIC_H__#define __MACIO_ASIC_H__ +#include <linux/mod_devicetable.h> #include <asm/of_device.h> extern struct bus_type macio_bus_type;
@@ -120,10 +121,10 @@ static inline struct pci_dev *macio_get_struct macio_driver {char *name; -struct of_match *match_table; +struct of_device_id *match_table;struct module *owner; -int (*probe)(struct macio_dev * dev,const struct of_match *match); +int (*probe)(struct macio_dev * dev,const struct of_device_id *match);int (*remove)(struct macio_dev * dev);int (*suspend)(struct macio_dev * dev,u32 state);
include/asm-ppc/of_device.h +4 -16
@@ -24,20 +24,8 @@ struct of_device };#define to_of_device (d) container_of(d, struct of_device, dev) -/* -* Struct used for matching a device -*/ -struct of_match -{ -char *name; -char *type; -char *compatible; -void *data; -}; -#define OF_ANY_MATCH ((char *)-1L) - -extern const struct of_match *of_match_device ( -const struct of_match *matches,const struct of_device *dev); +extern const struct of_device_id *of_match_device ( +const struct of_device_id *matches,const struct of_device *dev);extern struct of_device *of_dev_get (struct of_device *dev);extern void of_dev_put (struct of_device *dev);
@@ -49,10 +37,10 @@ extern void of_dev_put(struct of_devicestruct of_platform_driver {char *name; -struct of_match *match_table; +struct of_device_id *match_table;struct module *owner; -int (*probe)(struct of_device * dev,const struct of_match *match); +int (*probe)(struct of_device * dev,const struct of_device_id *match);int (*remove)(struct of_device * dev);int (*suspend)(struct of_device * dev,u32 state);
include/linux/mod_devicetable.h +11 -0
@@ -164,5 +164,16 @@ struct pnp_card_device_id { } devs[PNP_MAX_DEVICES]; }; +/* +* Struct used for matching a device +*/ +struct of_device_id +{ +char name[32 ]; +char type[32 ]; +char compatible[32 ]; +void *data; +}; +#endif /* LINUX_MOD_DEVICETABLE_H */
scripts/mod/file2alias.c +13 -0
@@ -199,6 +199,15 @@ static int do_pnp_card_entry(const charreturn 1 ; } +static int do_macio_entry (const char *filename,struct of_device_id *of,char *alias) +{ +sprintf (alias,"macio:N%sT%sC%s" , + of->name[0 ] ? of->name :"*" , + of->type[0 ] ? of->type :"*" , + of->compatible[0 ] ? of->compatible :"*" ); +return 1 ; +} +/* Ignore any prefix, eg. v850 prepends _ */ static inline int sym_is (const char *symbol,const char *name) {
@@ -271,6 +280,10 @@ void handle_moddevtable(struct module *melse if (sym_is (symname,"__mod_pnp_card_device_table" ))do_table (symval, sym->st_size,sizeof (struct pnp_card_device_id ), do_pnp_card_entry, mod); +else if (sym_is (symname,"__mod_macio_device_table" )) +do_table (symval, sym->st_size,sizeof (struct of_device_id ), + do_macio_entry, mod); + }/* Now add out buffered information to the generated C source */
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Jeff Mahoney wrote:
| | Hey all - | | Many devices on the macintosh hardware platform are hidden behind a | macio asic that places devices beyond the PCI bus for hotplug. Loading | the driver manually works fine, but we have this wonderful hotplug | system now. Why should macio be a second class citizen? | | At least for me, the most noticable one was my airport card, but there | may be others. I only have an ibook and a powermac. | | Attached are three patches, which do the following: | * kernel-of-hotplug.diff; against 2.6.9-rc2 (mainline)
| Take a look if you're interested. My familiarity with the PPC world is | peripheral at best. I'd love feedback.
As a quick note, it's been pointed out to me that some of the drivers won't compile as is.
I only compile tested with the drivers I use, so stuff slipped by. I'll have an updated kernel patch in a little bit.
- -Jeff
- --
Jeff Mahoney
SuSE Labs
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org
iD8DBQFBSgEeLPWxlyuTD7IRArijAJwOG/8WGId3foGajgKTu3/s4gRJMQCePHMq CggbvmovKdA0YBkED6aLkJs=
=6pUe
-----END PGP SIGNATURE-----
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Jeff Mahoney wrote:
| | Hey all - | | Many devices on the macintosh hardware platform are hidden behind a | macio asic that places devices beyond the PCI bus for hotplug. Loading | the driver manually works fine, but we have this wonderful hotplug | system now. Why should macio be a second class citizen? | | At least for me, the most noticable one was my airport card, but there | may be others. I only have an ibook and a powermac. | | Attached are three patches, which do the following: | * kernel-of-hotplug.diff; against 2.6.9-rc2 (mainline) | ~ - exports OF information to userspace | ~ - removes struct of_device in favor of struct of_device_id, which | ~ uses character arrays such that the structure can be more easily | ~ used by module-init-tools [the renaming is required to use the | ~ MODULE_DEVICE_TABLE macro] | ~ - changes the semantics of OF_MATCH_ANY to be an empty string | ~ - adds the name, type, and compat strings to the macio sysfs tree | ~ - adds a hotplug filter to pass the name, type, and compat info | ~ to hotplug | ~ - adds the appropriate MODULE_DEVICE_TABLE entries so that | ~ module-init-tools can know about macio devices | ~ - (Yes, I know this information is available via /proc/device_tree, | ~ but sysfs is a much more natural fit) | * hotplug-macio.diff | ~ - macio.rc: handles coldplugging of devices by traversing | ~ the macio sysfs tree | ~ - macio.agent: handles macio hotplug events | * module-init-tools-3.0-pre10-openfirmware.diff | ~ - adds support for a modules.ofmap table so that the hotplug scripts | ~ can determine which modules to load based on the OF information. | | Is there a limit for the length of the various OF strings? I've assumed | 32 for the sake of testing, but it's completely arbitrary. | | Take a look if you're interested. My familiarity with the PPC world is | peripheral at best. I'd love feedback.
As promised, updated kernel patch.
- -Jeff
- --
Jeff Mahoney
SuSE Labs
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org
iD8DBQFBShNkLPWxlyuTD7IRAioJAJsFWzAyp3AbXLd8Q7c2VQVYOMt4EwCeLGF2 /fUIjnQUXqJHPK4H9CeUI4k=
=HFZy
-----END PGP SIGNATURE-----
arch/ppc/syslib/of_device.c +8 -7
@@ -3,6 +3,7 @@#include <linux/kernel.h> #include <linux/init.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <asm/errno.h> #include <asm/of_device.h>
@@ -15,20 +16,20 @@* Used by a driver to check whether an of_device present in the * system is in its list of supported devices. */ -const struct of_match *of_match_device (const struct of_match *matches, +const struct of_device_id *of_match_device (const struct of_device_id *matches,const struct of_device *dev) {if (!dev->node)return NULL ; -while (matches->name || matches->type || matches->compatible) { +while (matches->name[0 ] || matches->type[0 ] || matches->compatible[0 ]) {int match =1 ; -if (matches->name && matches->name !=OF_ANY_MATCH ) +if (matches->name[0 ]) match &= dev->node->name && !strcmp (matches->name, dev->node->name); -if (matches->type && matches->type !=OF_ANY_MATCH ) +if (matches->type[0 ]) match &= dev->node->type && !strcmp (matches->type, dev->node->type); -if (matches->compatible && matches->compatible !=OF_ANY_MATCH ) +if (matches->compatible[0 ]) match &=device_is_compatible (dev->node, matches->compatible);if (match)
@@ -42,7 +43,7 @@ static int of_platform_bus_match(struct {struct of_device * of_dev =to_of_device (dev);struct of_platform_driver * of_drv =to_of_platform_driver (drv); -const struct of_match * matches = of_drv->match_table; +const struct of_device_id * matches = of_drv->match_table;if (!matches)return 0 ;
@@ -75,7 +76,7 @@ static int of_device_probe(struct deviceint error = -ENODEV ;struct of_platform_driver *drv;struct of_device *of_dev; -const struct of_match *match; +const struct of_device_id *match; drv =to_of_platform_driver (dev->driver); of_dev =to_of_device (dev);
drivers/i2c/busses/i2c-keywest.c +3 -4
@@ -694,7 +694,7 @@ dispose_iface(struct device *dev) }static int -create_iface_macio (struct macio_dev * dev,const struct of_match *match) +create_iface_macio (struct macio_dev * dev,const struct of_device_id *match) {return create_iface (dev->ofdev.node, &dev->ofdev.dev); }
@@ -706,7 +706,7 @@ dispose_iface_macio(struct macio_dev* de }static int -create_iface_of_platform (struct of_device * dev,const struct of_match *match) +create_iface_of_platform (struct of_device * dev,const struct of_device_id *match) {return create_iface (dev->node, &dev->dev); }
@@ -717,10 +717,9 @@ dispose_iface_of_platform(struct of_devireturn dispose_iface (&dev->dev); } -static struct of_match i2c_keywest_match[] = +static struct of_device_id i2c_keywest_match[] = { { - .name =OF_ANY_MATCH , .type ="i2c" , .compatible ="keywest" },
drivers/ide/ppc/pmac.c +2 -10
@@ -1279,7 +1279,7 @@ pmac_ide_setup_device(pmac_ide_hwif_t *p* Attach to a macio probed interface */ static int __devinit -pmac_ide_macio_attach (struct macio_dev *mdev,const struct of_match *match) +pmac_ide_macio_attach (struct macio_dev *mdev,const struct of_device_id *match) {unsigned long base, regbase;int irq;
@@ -1500,27 +1500,19 @@ pmac_ide_pci_resume(struct pci_dev *pdevreturn rc; } -static struct of_match pmac_ide_macio_match[] = +static struct of_device_id pmac_ide_macio_match[] = { { .name ="IDE" , - .type =OF_ANY_MATCH , - .compatible =OF_ANY_MATCH }, { .name ="ATA" , - .type =OF_ANY_MATCH , - .compatible =OF_ANY_MATCH }, { - .name =OF_ANY_MATCH , .type ="ide" , - .compatible =OF_ANY_MATCH }, { - .name =OF_ANY_MATCH , .type ="ata" , - .compatible =OF_ANY_MATCH }, {}, };
drivers/macintosh/macio_asic.c +71 -2
96 lines not on this page · raw message
drivers/macintosh/macio_sysfs.c +49 -0
49 lines not on this page · raw message
drivers/macintosh/Makefile +1 -1
@@ -4,7 +4,7 @@ # Each configuration option enables a list of files. -obj-$(CONFIG_PPC_PMAC) += macio_asic.o +obj-$(CONFIG_PPC_PMAC) += macio_asic.o macio_sysfs.o obj-$(CONFIG_PMAC_PBOOK) += mediabay.o obj-$(CONFIG_MAC_SERIAL) += macserial.o
drivers/macintosh/mediabay.c +2 -5
@@ -648,7 +648,7 @@ static int __pmac media_bay_task(void *x } } -static int __devinit media_bay_attach (struct macio_dev *mdev,const struct of_match *match) +static int __devinit media_bay_attach (struct macio_dev *mdev,const struct of_device_id *match) {struct media_bay_info * bay;volatile u32 *regbase;
@@ -802,23 +802,20 @@ static struct mb_ops keylargo_mb_ops __p* Therefore we do it all by polling the media bay once each tick. */ -static struct of_match media_bay_match[] = +static struct of_device_id media_bay_match[] = { { .name ="media-bay" , - .type =OF_ANY_MATCH , .compatible ="keylargo-media-bay" , .data = &keylargo_mb_ops, }, { .name ="media-bay" , - .type =OF_ANY_MATCH , .compatible ="heathrow-media-bay" , .data = &heathrow_mb_ops, }, { .name ="media-bay" , - .type =OF_ANY_MATCH , .compatible ="ohare-media-bay" , .data = &ohare_mb_ops, },
drivers/macintosh/therm_windtunnel.c +3 -3
@@ -43,6 +43,7 @@#include <asm/system.h> #include <asm/sections.h> #include <asm/of_device.h> +#include <asm/macio.h> #define LOG_TEMP 0/* continously log temperature */
@@ -453,7 +454,7 @@ do_probe( struct i2c_adapter *adapter, i/************************************************************************/ static int -therm_of_probe (struct of_device *dev,const struct of_match *match ) +therm_of_probe (struct of_device *dev,const struct of_device_id *match ) {return i2c_add_driver ( &g4fan_driver ); }
@@ -464,9 +465,8 @@ therm_of_remove( struct of_device *dev )return i2c_del_driver ( &g4fan_driver ); } -static struct of_match therm_of_match[] = {{ +static struct of_device_id therm_of_match[] = {{ .name ="fan" , - .type =OF_ANY_MATCH , .compatible ="adm1030" }, {} };
drivers/net/bmac.c +2 -5
@@ -1261,7 +1261,7 @@ static void bmac_reset_and_enable(structspin_unlock_irqrestore (&bp->lock, flags); } -static int __devinit bmac_probe (struct macio_dev *mdev,const struct of_match *match) +static int __devinit bmac_probe (struct macio_dev *mdev,const struct of_device_id *match) {int j, rev, ret;struct bmac_data *bp;
@@ -1649,16 +1649,13 @@ static int __devexit bmac_remove(structreturn 0 ; } -static struct of_match bmac_match[] = +static struct of_device_id bmac_match[] = { { .name ="bmac" , - .type =OF_ANY_MATCH , - .compatible =OF_ANY_MATCH , .data = (void *)0 , }, { - .name =OF_ANY_MATCH , .type ="network" , .compatible ="bmac+" , .data = (void *)1 ,
drivers/net/mace.c +2 -4
@@ -109,7 +109,7 @@ bitrev(int b) } -static int __devinit mace_probe (struct macio_dev *mdev,const struct of_match *match) +static int __devinit mace_probe (struct macio_dev *mdev,const struct of_device_id *match) {struct device_node *mace =macio_get_of_node (mdev);struct net_device *dev;
@@ -1011,12 +1011,10 @@ static irqreturn_t mace_rxdma_intr(int ireturn IRQ_HANDLED ; } -static struct of_match mace_match[] = +static struct of_device_id mace_match[] = { { .name ="mace" , - .type =OF_ANY_MATCH , - .compatible =OF_ANY_MATCH }, {}, };
drivers/net/wireless/airport.c +4 -4
@@ -188,7 +188,7 @@ static int airport_hard_reset(struct ori }static int -airport_attach (struct macio_dev *mdev,const struct of_match *match) +airport_attach (struct macio_dev *mdev,const struct of_device_id *match) {struct orinoco_private *priv;struct net_device *dev;
@@ -272,16 +272,16 @@ MODULE_AUTHOR("Benjamin Herrenschmidt <bMODULE_DESCRIPTION ("Driver for the Apple Airport wireless card." );MODULE_LICENSE ("Dual MPL/GPL" ); -static struct of_match airport_match[] = +static struct of_device_id airport_match[] = { { .name ="radio" , - .type =OF_ANY_MATCH , - .compatible =OF_ANY_MATCH }, {}, }; +MODULE_DEVICE_TABLE (of, airport_match); +static struct macio_driver airport_driver = { .name =DRIVER_NAME ,
drivers/scsi/mac53c94.c +3 -4
@@ -425,7 +425,7 @@ static struct scsi_host_template mac53c9 .use_clustering = DISABLE_CLUSTERING, }; -static int mac53c94_probe (struct macio_dev *mdev,const struct of_match *match) +static int mac53c94_probe (struct macio_dev *mdev,const struct of_device_id *match) {struct device_node *node =macio_get_of_node (mdev);struct pci_dev *pdev =macio_get_pci_dev (mdev);
@@ -545,15 +545,14 @@ static int mac53c94_remove(struct macio_ } -static struct of_match mac53c94_match[] = +static struct of_device_id mac53c94_match[] = { { .name ="53c94" , - .type =OF_ANY_MATCH , - .compatible =OF_ANY_MATCH }, {}, }; +MODULE_DEVICE_TABLE (of, mac53c94_match);static struct macio_driver mac53c94_driver = {
drivers/scsi/mesh.c +3 -5
@@ -1847,7 +1847,7 @@ static struct scsi_host_template mesh_te .use_clustering = DISABLE_CLUSTERING, }; -static int mesh_probe (struct macio_dev *mdev,const struct of_match *match) +static int mesh_probe (struct macio_dev *mdev,const struct of_device_id *match) {struct device_node *mesh =macio_get_of_node (mdev);struct pci_dev * pdev =macio_get_pci_dev (mdev);
@@ -2014,20 +2014,18 @@ static int mesh_remove(struct macio_dev } -static struct of_match mesh_match[] = +static struct of_device_id mesh_match[] = { { .name ="mesh" , - .type =OF_ANY_MATCH , - .compatible =OF_ANY_MATCH }, { - .name =OF_ANY_MATCH , .type ="scsi" , .compatible ="chrp,mesh0" }, {}, }; +MODULE_DEVICE_TABLE (of, mesh_match);static struct macio_driver mesh_driver = {
drivers/serial/pmac_zilog.c +3 -6
@@ -1520,7 +1520,7 @@ static void pmz_dispose_port(struct uart/* * Called upon match with an escc node in the devive-tree. */ -static int pmz_attach (struct macio_dev *mdev,const struct of_match *match) +static int pmz_attach (struct macio_dev *mdev,const struct of_device_id *match) {int i;
@@ -1826,20 +1826,17 @@ err_out:return rc; } -static struct of_match pmz_match[] = +static struct of_device_id pmz_match[] = { { .name ="ch-a" , - .type =OF_ANY_MATCH , - .compatible =OF_ANY_MATCH }, { .name ="ch-b" , - .type =OF_ANY_MATCH , - .compatible =OF_ANY_MATCH }, {}, }; +MODULE_DEVICE_TABLE (of, pmz_match);static struct macio_driver pmz_driver = {
drivers/video/platinumfb.c +2 -4
@@ -523,7 +523,7 @@ int __init platinumfb_setup(char *option#define invalidate_cache (addr)#endif -static int __devinit platinumfb_probe (struct of_device * odev,const struct of_match *match) +static int __devinit platinumfb_probe (struct of_device * odev,const struct of_device_id *match) {struct device_node *dp = odev->node;struct fb_info *info;
@@ -647,12 +647,10 @@ static int __devexit platinumfb_remove(sreturn 0 ; } -static struct of_match platinumfb_match[] = +static struct of_device_id platinumfb_match[] = { { .name ="platinum" , - .type =OF_ANY_MATCH , - .compatible =OF_ANY_MATCH , }, {}, };
include/asm-ppc/macio.h +3 -2
@@ -1,6 +1,7 @@#ifndef __MACIO_ASIC_H__#define __MACIO_ASIC_H__ +#include <linux/mod_devicetable.h> #include <asm/of_device.h> extern struct bus_type macio_bus_type;
@@ -120,10 +121,10 @@ static inline struct pci_dev *macio_get_struct macio_driver {char *name; -struct of_match *match_table; +struct of_device_id *match_table;struct module *owner; -int (*probe)(struct macio_dev * dev,const struct of_match *match); +int (*probe)(struct macio_dev * dev,const struct of_device_id *match);int (*remove)(struct macio_dev * dev);int (*suspend)(struct macio_dev * dev,u32 state);
include/asm-ppc/of_device.h +4 -16
@@ -24,20 +24,8 @@ struct of_device };#define to_of_device (d) container_of(d, struct of_device, dev) -/* -* Struct used for matching a device -*/ -struct of_match -{ -char *name; -char *type; -char *compatible; -void *data; -}; -#define OF_ANY_MATCH ((char *)-1L) - -extern const struct of_match *of_match_device ( -const struct of_match *matches,const struct of_device *dev); +extern const struct of_device_id *of_match_device ( +const struct of_device_id *matches,const struct of_device *dev);extern struct of_device *of_dev_get (struct of_device *dev);extern void of_dev_put (struct of_device *dev);
@@ -49,10 +37,10 @@ extern void of_dev_put(struct of_devicestruct of_platform_driver {char *name; -struct of_match *match_table; +struct of_device_id *match_table;struct module *owner; -int (*probe)(struct of_device * dev,const struct of_match *match); +int (*probe)(struct of_device * dev,const struct of_device_id *match);int (*remove)(struct of_device * dev);int (*suspend)(struct of_device * dev,u32 state);
include/linux/mod_devicetable.h +11 -0
@@ -164,5 +164,16 @@ struct pnp_card_device_id { } devs[PNP_MAX_DEVICES]; }; +/* +* Struct used for matching a device +*/ +struct of_device_id +{ +char name[32 ]; +char type[32 ]; +char compatible[32 ]; +void *data; +}; +#endif /* LINUX_MOD_DEVICETABLE_H */
scripts/mod/file2alias.c +13 -0
@@ -199,6 +199,15 @@ static int do_pnp_card_entry(const charreturn 1 ; } +static int do_macio_entry (const char *filename,struct of_device_id *of,char *alias) +{ +sprintf (alias,"macio:N%sT%sC%s" , + of->name[0 ] ? of->name :"*" , + of->type[0 ] ? of->type :"*" , + of->compatible[0 ] ? of->compatible :"*" ); +return 1 ; +} +/* Ignore any prefix, eg. v850 prepends _ */ static inline int sym_is (const char *symbol,const char *name) {
@@ -271,6 +280,10 @@ void handle_moddevtable(struct module *melse if (sym_is (symname,"__mod_pnp_card_device_table" ))do_table (symval, sym->st_size,sizeof (struct pnp_card_device_id ), do_pnp_card_entry, mod); +else if (sym_is (symname,"__mod_macio_device_table" )) +do_table (symval, sym->st_size,sizeof (struct of_device_id ), + do_macio_entry, mod); + }/* Now add out buffered information to the generated C source */