From 9cb7989392b71bdaad2a1a939b9abe6fd11d9f77 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Fri, 8 Aug 2003 19:40:09 -0700 Subject: [PATCH] [PATCH] PowerMac: Ground work for new driver model This provides the necessary infrastructure for PowerMac specific drivers (and actually some Open Firmware platform drivers on non-PowerMacs as well provided somebody port them) to be properly probed & referenced via the new driver model and be part of sysfs. As-is, this patch doesn't break anything nor change any driver. I'll send you individual driver patches as I clean them up & get them tested on as many machines as possible, though I don't expect much problems. --- arch/ppc/platforms/pmac_feature.c | 3 +- arch/ppc/platforms/pmac_setup.c | 27 ++ arch/ppc/syslib/Makefile | 2 +- arch/ppc/syslib/of_device.c | 249 +++++++++++++++ drivers/macintosh/Makefile | 2 + drivers/macintosh/macio_asic.c | 358 ++++++++++++++++++++++ include/asm-ppc/{macio_asic.h => macio.h} | 40 +-- include/asm-ppc/of_device.h | 70 +++++ include/asm-ppc/pmac_feature.h | 2 +- 9 files changed, 724 insertions(+), 29 deletions(-) create mode 100644 arch/ppc/syslib/of_device.c create mode 100644 drivers/macintosh/macio_asic.c rename include/asm-ppc/{macio_asic.h => macio.h} (60%) create mode 100644 include/asm-ppc/of_device.h diff --git a/arch/ppc/platforms/pmac_feature.c b/arch/ppc/platforms/pmac_feature.c index 5c4ae1fe15264..8eb746c064531 100644 --- a/arch/ppc/platforms/pmac_feature.c +++ b/arch/ppc/platforms/pmac_feature.c @@ -38,7 +38,6 @@ #include #include #include -#include #include #include #include @@ -2187,6 +2186,8 @@ probe_macios(void) macio_chips[0] = macio_chips[1]; macio_chips[1] = temp; } + macio_chips[0].lbus.index = 0; + macio_chips[1].lbus.index = 1; return (macio_chips[0].of_node == NULL) ? -ENODEV : 0; } diff --git a/arch/ppc/platforms/pmac_setup.c b/arch/ppc/platforms/pmac_setup.c index 6c3fb5538d5f5..15de29c7b5884 100644 --- a/arch/ppc/platforms/pmac_setup.c +++ b/arch/ppc/platforms/pmac_setup.c @@ -69,6 +69,7 @@ #include #include #include +#include #include "pmac_pic.h" #include "mem_pieces.h" @@ -670,3 +671,29 @@ pmac_progress(char *s, unsigned short hex) } } #endif /* CONFIG_BOOTX_TEXT */ + +static int __init +pmac_declare_of_platform_devices(void) +{ + struct device_node *np; + + np = find_devices("uni-n"); + if (np) { + for (np = np->child; np != NULL; np = np->sibling) + if (strncmp(np->name, "i2c", 3) == 0) { + of_platform_device_create(np, "uni-n-i2c"); + break; + } + } + + np = find_devices("valkyrie"); + if (np) + of_platform_device_create(np, "valkyrie"); + np = find_devices("platinum"); + if (np) + of_platform_device_create(np, "platinum"); + + return 0; +} + +device_initcall(pmac_declare_of_platform_devices); diff --git a/arch/ppc/syslib/Makefile b/arch/ppc/syslib/Makefile index 9fd63b6030a95..c4621a1459291 100644 --- a/arch/ppc/syslib/Makefile +++ b/arch/ppc/syslib/Makefile @@ -27,7 +27,7 @@ obj-$(CONFIG_8xx) += m8xx_setup.o ppc8xx_pic.o ifeq ($(CONFIG_8xx),y) obj-$(CONFIG_PCI) += qspan_pci.o i8259.o endif -obj-$(CONFIG_PPC_OF) += prom_init.o prom.o +obj-$(CONFIG_PPC_OF) += prom_init.o prom.o of_device.o obj-$(CONFIG_PPC_PMAC) += open_pic.o indirect_pci.o obj-$(CONFIG_PPC_CHRP) += open_pic.o indirect_pci.o i8259.o obj-$(CONFIG_PPC_PREP) += open_pic.o indirect_pci.o i8259.o diff --git a/arch/ppc/syslib/of_device.c b/arch/ppc/syslib/of_device.c new file mode 100644 index 0000000000000..2380497ebe307 --- /dev/null +++ b/arch/ppc/syslib/of_device.c @@ -0,0 +1,249 @@ +#include +#include +#include +#include +#include +#include +#include + +/** + * of_match_device - Tell if an of_device structure has a matching + * of_match structure + * @ids: array of of device match structures to search in + * @dev: the of device structure to match against + * + * 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 *dev) +{ + if (!dev->node) + return NULL; + while (matches->name || matches->type || matches->compatible) { + int match = 1; + if (matches->name && matches->name != OF_ANY_MATCH) + match &= dev->node->name + && !strcmp(matches->name, dev->node->name); + if (matches->type && matches->type != OF_ANY_MATCH) + match &= dev->node->type + && !strcmp(matches->type, dev->node->type); + if (matches->compatible && matches->compatible != OF_ANY_MATCH) + match &= device_is_compatible(dev->node, + matches->compatible); + if (match) + return matches; + matches++; + } + return NULL; +} + +static int +of_platform_bus_match(struct device *dev, struct device_driver *drv) +{ + 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; + + if (!matches) + return 0; + + return of_match_device(matches, of_dev) != NULL; +} + +struct bus_type of_platform_bus_type = { + name: "of_platform", + match: of_platform_bus_match, +}; + +static int __init +of_bus_driver_init(void) +{ + return bus_register(&of_platform_bus_type); +} + +postcore_initcall(of_bus_driver_init); + +static int +of_device_probe(struct device *dev) +{ + int error = -ENODEV; + struct of_platform_driver *drv; + struct of_device *of_dev; + const struct of_match *match; + + drv = to_of_platform_driver(dev->driver); + of_dev = to_of_device(dev); + + if (!drv->probe) + return error; + +/* if (!try_module_get(driver->owner)) { + printk(KERN_ERR "Can't get a module reference for %s\n", driver->name); + return error; + } +*/ + match = of_match_device(drv->match_table, of_dev); + if (match) + error = drv->probe(of_dev, match); +/* + module_put(driver->owner); +*/ + return error; +} + +static int +of_device_remove(struct device *dev) +{ + struct of_device * of_dev = to_of_device(dev); + struct of_platform_driver * drv = to_of_platform_driver(of_dev->dev.driver); + + if (drv && drv->remove) + drv->remove(of_dev); + return 0; +} + +static int +of_device_suspend(struct device *dev, u32 state, u32 level) +{ + struct of_device * of_dev = to_of_device(dev); + struct of_platform_driver * drv = to_of_platform_driver(of_dev->dev.driver); + int error = 0; + + if (drv && drv->suspend) + error = drv->suspend(of_dev, state, level); + return error; +} + +static int +of_device_resume(struct device * dev, u32 level) +{ + struct of_device * of_dev = to_of_device(dev); + struct of_platform_driver * drv = to_of_platform_driver(of_dev->dev.driver); + int error = 0; + + if (drv && drv->resume) + error = drv->resume(of_dev, level); + return error; +} + +int +of_register_driver(struct of_platform_driver *drv) +{ + int count = 0; + + /* initialize common driver fields */ + drv->driver.name = drv->name; + drv->driver.bus = &of_platform_bus_type; + drv->driver.probe = of_device_probe; + drv->driver.resume = of_device_resume; + drv->driver.suspend = of_device_suspend; + drv->driver.remove = of_device_remove; + + /* register with core */ + count = driver_register(&drv->driver); + return count ? count : 1; +} + +void +of_unregister_driver(struct of_platform_driver *drv) +{ + driver_unregister(&drv->driver); +} + + +static ssize_t +dev_show_devspec(struct device *dev, char *buf) +{ + struct of_device *ofdev; + + ofdev = to_of_device(dev); + return sprintf(buf, "%s", ofdev->node->full_name); +} + +static DEVICE_ATTR(devspec, S_IRUGO, dev_show_devspec, NULL); + +int +of_device_register(struct of_device *ofdev) +{ + int rc; + struct of_device **odprop; + + BUG_ON(ofdev->node == NULL); + + odprop = (struct of_device **)get_property(ofdev->node, "linux,device", NULL); + if (!odprop) { + struct property *new_prop; + + new_prop = kmalloc(sizeof(struct property) + sizeof(struct of_device *), + GFP_KERNEL); + if (new_prop == NULL) + return -ENOMEM; + new_prop->name = "linux,device"; + new_prop->length = sizeof(sizeof(struct of_device *)); + new_prop->value = (unsigned char *)&new_prop[1]; + odprop = (struct of_device **)new_prop->value; + *odprop = NULL; + prom_add_property(ofdev->node, new_prop); + } + *odprop = ofdev; + + rc = device_register(&ofdev->dev); + if (rc) + return rc; + + device_create_file(&ofdev->dev, &dev_attr_devspec); + + return 0; +} + +void +of_device_unregister(struct of_device *ofdev) +{ + struct of_device **odprop; + + device_remove_file(&ofdev->dev, &dev_attr_devspec); + device_unregister(&ofdev->dev); + + odprop = (struct of_device **)get_property(ofdev->node, "linux,device", NULL); + if (odprop) + *odprop = NULL; +} + +struct of_device* +of_platform_device_create(struct device_node *np, const char *bus_id) +{ + struct of_device *dev; + u32 *reg; + + dev = kmalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) + return NULL; + memset(dev, 0, sizeof(*dev)); + + dev->node = np; + dev->dma_mask = 0xffffffffUL; + dev->dev.dma_mask = &dev->dma_mask; + dev->dev.parent = NULL; + dev->dev.bus = &of_platform_bus_type; + + /* XXX Make something better here ? */ + snprintf(dev->dev.name, DEVICE_NAME_SIZE, "Platform device %s", np->name); + reg = (u32 *)get_property(np, "reg", NULL); + strlcpy(dev->dev.bus_id, bus_id, BUS_ID_SIZE); + + if (of_device_register(dev) != 0) { + kfree(dev); + return NULL; + } + + return dev; +} + +EXPORT_SYMBOL(of_match_device); +EXPORT_SYMBOL(of_platform_bus_type); +EXPORT_SYMBOL(of_register_driver); +EXPORT_SYMBOL(of_unregister_driver); +EXPORT_SYMBOL(of_device_register); +EXPORT_SYMBOL(of_device_unregister); +EXPORT_SYMBOL(of_platform_device_create); diff --git a/drivers/macintosh/Makefile b/drivers/macintosh/Makefile index cc3a05d97ad78..da5aadbd07da2 100644 --- a/drivers/macintosh/Makefile +++ b/drivers/macintosh/Makefile @@ -4,6 +4,8 @@ # Each configuration option enables a list of files. +obj-$(CONFIG_PPC_PMAC) += macio_asic.o + obj-$(CONFIG_PMAC_PBOOK) += mediabay.o obj-$(CONFIG_MAC_SERIAL) += macserial.o ifneq ($(CONFIG_MAC),y) diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c new file mode 100644 index 0000000000000..7e52af4bdd0da --- /dev/null +++ b/drivers/macintosh/macio_asic.c @@ -0,0 +1,358 @@ +/* + * Bus & driver management routines for devices within + * a MacIO ASIC. Interface to new driver model mostly + * stolen from the PCI version. + * + * TODO: + * + * - Don't probe below media bay by default, but instead provide + * some hooks for media bay to dynamically add/remove it's own + * sub-devices. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int +macio_bus_match(struct device *dev, struct device_driver *drv) +{ + struct macio_dev * macio_dev = to_macio_device(dev); + struct macio_driver * macio_drv = to_macio_driver(drv); + const struct of_match * matches = macio_drv->match_table; + + if (!matches) + return 0; + + return of_match_device(matches, &macio_dev->ofdev) != NULL; +} + +struct bus_type macio_bus_type = { + name: "macio", + match: macio_bus_match, +}; + +static int __init +macio_bus_driver_init(void) +{ + return bus_register(&macio_bus_type); +} + +postcore_initcall(macio_bus_driver_init); + +static int +macio_device_probe(struct device *dev) +{ + int error = -ENODEV; + struct macio_driver *drv; + struct macio_dev *macio_dev; + const struct of_match *match; + + drv = to_macio_driver(dev->driver); + macio_dev = to_macio_device(dev); + + if (!drv->probe) + return error; + +/* if (!try_module_get(driver->owner)) { + printk(KERN_ERR "Can't get a module reference for %s\n", driver->name); + return error; + } +*/ + match = of_match_device(drv->match_table, &macio_dev->ofdev); + if (match) + error = drv->probe(macio_dev, match); +/* + module_put(driver->owner); +*/ + return error; +} + +static int +macio_device_remove(struct device *dev) +{ + struct macio_dev * macio_dev = to_macio_device(dev); + struct macio_driver * drv = to_macio_driver(macio_dev->ofdev.dev.driver); + + if (drv && drv->remove) + drv->remove(macio_dev); + return 0; +} + +static int +macio_device_suspend(struct device *dev, u32 state, u32 level) +{ + struct macio_dev * macio_dev = to_macio_device(dev); + struct macio_driver * drv = to_macio_driver(macio_dev->ofdev.dev.driver); + int error = 0; + + if (drv && drv->suspend) + error = drv->suspend(macio_dev, state, level); + return error; +} + +static int +macio_device_resume(struct device * dev, u32 level) +{ + struct macio_dev * macio_dev = to_macio_device(dev); + struct macio_driver * drv = to_macio_driver(macio_dev->ofdev.dev.driver); + int error = 0; + + if (drv && drv->resume) + error = drv->resume(macio_dev, level); + return error; +} + +/** + * macio_add_one_device - Add one device from OF node to the device tree + * @chip: pointer to the macio_chip holding the device + * @np: pointer to the device node in the OF tree + * @in_bay: set to 1 if device is part of a media-bay + * + * When media-bay is changed to hotswap drivers, this function will + * be exposed to the bay driver some way... + */ +static struct macio_dev * +macio_add_one_device(struct macio_chip *chip, struct device *parent, + struct device_node *np, struct macio_dev *in_bay) +{ + struct macio_dev *dev; + u32 *reg; + + dev = kmalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) + return NULL; + memset(dev, 0, sizeof(*dev)); + + dev->bus = &chip->lbus; + dev->media_bay = in_bay; + dev->ofdev.node = np; + dev->ofdev.dma_mask = 0xffffffffUL; + dev->ofdev.dev.dma_mask = &dev->ofdev.dma_mask; + dev->ofdev.dev.parent = parent; + dev->ofdev.dev.bus = &macio_bus_type; + + /* XXX Make something better here ? */ + snprintf(dev->ofdev.dev.name, DEVICE_NAME_SIZE, "MacIO device %s", np->name); + + /* MacIO itself has a different reg, we use it's PCI base */ + if (np == chip->of_node) { + sprintf(dev->ofdev.dev.bus_id, "%1d.%08lx:%.8s", chip->lbus.index, +#ifdef CONFIG_PCI + pci_resource_start(chip->lbus.pdev, 0), +#else + 0, /* NuBus may want to do something better here */ +#endif + np->name); + } else { + reg = (u32 *)get_property(np, "reg", NULL); + sprintf(dev->ofdev.dev.bus_id, "%1d.%08x:%.8s", chip->lbus.index, + reg ? *reg : 0, np->name); + } + + if (of_device_register(&dev->ofdev) != 0) { + kfree(dev); + return NULL; + } + + return dev; +} + +static int +macio_skip_device(struct device_node *np) +{ + if (strncmp(np->name, "battery", 7) == 0) + return 1; + if (strncmp(np->name, "escc-legacy", 11) == 0) + return 1; + return 0; +} + +/** + * macio_pci_add_devices - Adds sub-devices of mac-io to the device tree + * @chip: pointer to the macio_chip holding the devices + * + * This function will do the job of extracting devices from the + * Open Firmware device tree, build macio_dev structures and add + * them to the Linux device tree. + * + * For now, childs of media-bay are added now as well. This will + * change rsn though. + */ +static void +macio_pci_add_devices(struct macio_chip *chip) +{ + struct device_node *np; + struct macio_dev *rdev, *mdev, *mbdev = NULL, *sdev = NULL; + struct device *parent = NULL; + + /* Add a node for the macio bus itself */ +#ifdef CONFIG_PCI + if (chip->lbus.pdev) + parent = &chip->lbus.pdev->dev; +#endif + rdev = macio_add_one_device(chip, parent, chip->of_node, NULL); + if (rdev == NULL) + return; + + /* First scan 1st level */ + for (np = chip->of_node->child; np != NULL; np = np->sibling) { + if (!macio_skip_device(np)) { + mdev = macio_add_one_device(chip, &rdev->ofdev.dev, np, NULL); + if (strncmp(np->name, "media-bay", 9) == 0) + mbdev = mdev; + else if (strncmp(np->name, "escc", 4) == 0) + sdev = mdev; + } + } + + /* Add media bay devices if any */ + if (mbdev) { + for (np = mbdev->ofdev.node->child; np != NULL; np = np->sibling) + if (!macio_skip_device(np)) + macio_add_one_device(chip, &mbdev->ofdev.dev, np, mbdev); + } + /* Add serial ports if any */ + if (sdev) { + for (np = sdev->ofdev.node->child; np != NULL; np = np->sibling) + if (!macio_skip_device(np)) + macio_add_one_device(chip, &sdev->ofdev.dev, np, NULL); + } +} + + +/** + * macio_register_driver - Registers a new MacIO device driver + * @drv: pointer to the driver definition structure + */ +int +macio_register_driver(struct macio_driver *drv) +{ + int count = 0; + + /* initialize common driver fields */ + drv->driver.name = drv->name; + drv->driver.bus = &macio_bus_type; + drv->driver.probe = macio_device_probe; + drv->driver.resume = macio_device_resume; + drv->driver.suspend = macio_device_suspend; + drv->driver.remove = macio_device_remove; + + /* register with core */ + count = driver_register(&drv->driver); + return count ? count : 1; +} + +/** + * macio_unregister_driver - Unregisters a new MacIO device driver + * @drv: pointer to the driver definition structure + */ +void +macio_unregister_driver(struct macio_driver *drv) +{ + driver_unregister(&drv->driver); +} + +#ifdef CONFIG_PCI + +static int __devinit +macio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + struct device_node* np; + struct macio_chip* chip; + + if (ent->vendor != PCI_VENDOR_ID_APPLE) + return -ENODEV; + + np = pci_device_to_OF_node(pdev); + if (np == NULL) + return -ENODEV; + + chip = macio_find(np, macio_unknown); + if (chip == NULL) + return -ENODEV; + + /* XXX Need locking */ + if (chip->lbus.pdev == NULL) { + chip->lbus.pdev = pdev; + chip->lbus.chip = chip; +// INIT_LIST_HEAD(&chip->lbus.devices); + pci_set_drvdata(pdev, &chip->lbus); + pci_set_master(pdev); + } + + printk(KERN_INFO "MacIO PCI driver attached to %s chipset\n", + chip->name); + + macio_pci_add_devices(chip); + + return 0; +} + +static void __devexit +macio_pci_remove(struct pci_dev* pdev) +{ + panic("removing of macio-asic not supported !\n"); +} + +/* + * MacIO is matched against any Apple ID, it's probe() function + * will then decide wether it applies or not + */ +static const struct pci_device_id __devinitdata pci_ids [] = { { + .vendor = PCI_VENDOR_ID_APPLE, + .device = PCI_ANY_ID, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + + }, { /* end: all zeroes */ } +}; +MODULE_DEVICE_TABLE (pci, pci_ids); + +/* pci driver glue; this is a "new style" PCI driver module */ +static struct pci_driver macio_pci_driver = { + .name = (char *) "macio", + .id_table = pci_ids, + + .probe = macio_pci_probe, + .remove = macio_pci_remove, +}; + +#endif /* CONFIG_PCI */ + +static int __init +macio_module_init (void) +{ +#ifdef CONFIG_PCI + int rc; + + rc = pci_module_init(&macio_pci_driver); + if (rc) + return rc; +#endif /* CONFIG_PCI */ + return 0; +} + +/* +static void __exit +macio_module_cleanup (void) +{ +#ifdef CONFIG_PCI + pci_unregister_driver(&macio_pci_driver); +#endif +} +module_exit(macio_module_cleanup); +*/ +module_init(macio_module_init); + +EXPORT_SYMBOL(macio_register_driver); +EXPORT_SYMBOL(macio_unregister_driver); diff --git a/include/asm-ppc/macio_asic.h b/include/asm-ppc/macio.h similarity index 60% rename from include/asm-ppc/macio_asic.h rename to include/asm-ppc/macio.h index 58d15c5b6c692..fea90e46aa099 100644 --- a/include/asm-ppc/macio_asic.h +++ b/include/asm-ppc/macio.h @@ -1,7 +1,7 @@ #ifndef __MACIO_ASIC_H__ #define __MACIO_ASIC_H__ -#include +#include extern struct bus_type macio_bus_type; @@ -17,12 +17,16 @@ struct macio_chip; * within a MacIO ASIC. It's typically provided by a macio_pci_asic * PCI device, but could be provided differently as well (nubus * machines using a fake OF tree). + * + * The pdev field can be NULL on non-PCI machines */ struct macio_bus { struct macio_chip *chip; /* macio_chip (private use) */ + int index; /* macio chip index in system */ +#ifdef CONFIG_PCI struct pci_dev *pdev; /* PCI device hosting this bus */ - struct list_head devices; /* list of devices on this bus */ +#endif }; /* @@ -31,39 +35,23 @@ struct macio_bus */ struct macio_dev { - struct macio_bus *bus; /* virtual bus this device is on */ - - struct device_node *node; /* OF node */ - struct macio_driver *driver; /* which driver allocated this device */ - void *driver_data; /* placeholder for driver specific stuffs */ - struct resource resources[MACIO_DEV_COUNT_RESOURCE]; /* I/O */ - int irqs[MACIO_DEV_COUNT_IRQS]; - - struct device dev; /* Generic device interface */ -}; -#define to_macio_device(d) container_of(d, struct macio_dev, dev) - -/* - * Struct used for matching a device - */ -struct macio_match -{ - char *name; - char *type; - char *compatible; + struct macio_bus *bus; /* macio bus this device is on */ + struct macio_dev *media_bay; /* Device is part of a media bay */ + struct of_device ofdev; }; -#define MACIO_ANY_MATCH ((char *)-1L) +#define to_macio_device(d) container_of(d, struct macio_dev, ofdev.dev) +#define of_to_macio_device(d) container_of(d, struct macio_dev, ofdev) /* * A driver for a mac-io chip based device */ struct macio_driver { - struct list_head node; char *name; - struct macio_match *match_table; + struct of_match *match_table; + struct module *owner; - int (*probe)(struct macio_dev* dev, const struct macio_match *match); + int (*probe)(struct macio_dev* dev, const struct of_match *match); int (*remove)(struct macio_dev* dev); int (*suspend)(struct macio_dev* dev, u32 state, u32 level); diff --git a/include/asm-ppc/of_device.h b/include/asm-ppc/of_device.h new file mode 100644 index 0000000000000..71a0a3708ea5e --- /dev/null +++ b/include/asm-ppc/of_device.h @@ -0,0 +1,70 @@ +#ifndef __OF_DEVICE_H__ +#define __OF_DEVICE_H__ + +#include +#include + +/* + * The of_platform_bus_type is a bus type used by drivers that do not + * attach to a macio or similar bus but still use OF probing + * mecanism + */ +extern struct bus_type of_platform_bus_type; + +/* + * The of_device is a kind of "base class" that is a superset of + * struct device for use by devices attached to an OF node and + * probed using OF properties + */ +struct of_device +{ + struct device_node *node; /* OF device node */ + u64 dma_mask; /* DMA mask */ + struct device dev; /* Generic device interface */ +}; +#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); + +/* + * An of_platform_driver driver is attached to a basic of_device on + * the "platform bus" (of_platform_bus_type) + */ +struct of_platform_driver +{ + char *name; + struct of_match *match_table; + struct module *owner; + + int (*probe)(struct of_device* dev, const struct of_match *match); + int (*remove)(struct of_device* dev); + + int (*suspend)(struct of_device* dev, u32 state, u32 level); + int (*resume)(struct of_device* dev, u32 level); + int (*shutdown)(struct of_device* dev); + + struct device_driver driver; +}; +#define to_of_platform_driver(drv) container_of(drv,struct of_platform_driver, driver) + +extern int of_register_driver(struct of_platform_driver *drv); +extern void of_unregister_driver(struct of_platform_driver *drv); +extern int of_device_register(struct of_device *ofdev); +extern void of_device_unregister(struct of_device *ofdev); +extern struct of_device *of_platform_device_create(struct device_node *np, const char *bus_id); + +#endif /* __OF_DEVICE_H__ */ + diff --git a/include/asm-ppc/pmac_feature.h b/include/asm-ppc/pmac_feature.h index eace23e7d6ca2..44eaa7543384a 100644 --- a/include/asm-ppc/pmac_feature.h +++ b/include/asm-ppc/pmac_feature.h @@ -31,7 +31,7 @@ #ifndef __PPC_ASM_PMAC_FEATURE_H #define __PPC_ASM_PMAC_FEATURE_H -#include +#include /* * Known Mac motherboard models -- 2.53.0