Merge commit 'v2.6.35-rc6' into devicetree/next
Grant Likely [Sat, 24 Jul 2010 15:49:13 +0000 (09:49 -0600)]
Conflicts:
arch/sparc/kernel/prom_64.c

103 files changed:
arch/microblaze/Kconfig
arch/microblaze/include/asm/irq.h
arch/microblaze/include/asm/of_device.h
arch/microblaze/include/asm/of_platform.h
arch/microblaze/include/asm/page.h
arch/microblaze/include/asm/pci-bridge.h
arch/microblaze/include/asm/prom.h
arch/microblaze/kernel/Makefile
arch/microblaze/kernel/irq.c
arch/microblaze/kernel/of_device.c [deleted file]
arch/microblaze/kernel/of_platform.c
arch/microblaze/kernel/prom_parse.c
arch/microblaze/kernel/reset.c
arch/powerpc/Kconfig
arch/powerpc/include/asm/irq.h
arch/powerpc/include/asm/of_device.h
arch/powerpc/include/asm/of_platform.h
arch/powerpc/include/asm/pci-bridge.h
arch/powerpc/include/asm/prom.h
arch/powerpc/include/asm/smu.h
arch/powerpc/kernel/Makefile
arch/powerpc/kernel/irq.c
arch/powerpc/kernel/of_device.c [deleted file]
arch/powerpc/kernel/of_platform.c
arch/powerpc/kernel/prom_parse.c
arch/powerpc/platforms/52xx/mpc52xx_gpio.c
arch/powerpc/platforms/52xx/mpc52xx_gpt.c
arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c
arch/powerpc/platforms/86xx/gef_gpio.c
arch/powerpc/platforms/powermac/pic.c
arch/powerpc/sysdev/cpm1.c
arch/powerpc/sysdev/cpm_common.c
arch/powerpc/sysdev/mpc8xxx_gpio.c
arch/powerpc/sysdev/ppc4xx_gpio.c
arch/powerpc/sysdev/qe_lib/gpio.c
arch/powerpc/sysdev/simple_gpio.c
arch/sparc/Kconfig
arch/sparc/include/asm/device.h
arch/sparc/include/asm/floppy_64.h
arch/sparc/include/asm/of_device.h
arch/sparc/include/asm/parport.h
arch/sparc/include/asm/prom.h
arch/sparc/kernel/of_device_32.c
arch/sparc/kernel/of_device_64.c
arch/sparc/kernel/of_device_common.c
arch/sparc/kernel/pci.c
arch/sparc/kernel/pci_psycho.c
arch/sparc/kernel/pci_sabre.c
arch/sparc/kernel/pci_schizo.c
arch/sparc/kernel/power.c
arch/sparc/kernel/prom.h
arch/sparc/kernel/prom_64.c
arch/sparc/kernel/prom_common.c
drivers/atm/fore200e.c
drivers/gpio/gpiolib.c
drivers/gpio/xilinx_gpio.c
drivers/i2c/busses/i2c-cpm.c
drivers/i2c/busses/i2c-ibm_iic.c
drivers/i2c/busses/i2c-mpc.c
drivers/i2c/i2c-core.c
drivers/input/serio/i8042-sparcio.h
drivers/macintosh/macio_sysfs.c
drivers/mmc/host/mmc_spi.c
drivers/net/myri_sbus.c
drivers/net/niu.c
drivers/net/niu.h
drivers/net/sunbmac.c
drivers/net/sunhme.c
drivers/net/sunlance.c
drivers/net/sunqe.c
drivers/of/Kconfig
drivers/of/Makefile
drivers/of/address.c [new file with mode: 0644]
drivers/of/base.c
drivers/of/device.c
drivers/of/fdt.c
drivers/of/gpio.c
drivers/of/irq.c [new file with mode: 0644]
drivers/of/of_i2c.c
drivers/of/of_mdio.c
drivers/of/of_spi.c
drivers/of/platform.c
drivers/parport/parport_sunbpp.c
drivers/sbus/char/bbc_i2c.c
drivers/sbus/char/uctrl.c
drivers/scsi/qlogicpti.c
drivers/scsi/sun_esp.c
drivers/serial/sunhv.c
drivers/serial/sunsab.c
drivers/serial/sunsu.c
drivers/serial/sunzilog.c
drivers/watchdog/cpwd.c
include/asm-generic/gpio.h
include/linux/of.h
include/linux/of_address.h [new file with mode: 0644]
include/linux/of_device.h
include/linux/of_gpio.h
include/linux/of_i2c.h
include/linux/of_irq.h [new file with mode: 0644]
include/linux/of_platform.h
sound/sparc/amd7930.c
sound/sparc/cs4231.c
sound/sparc/dbri.c

index 505a085..206222a 100644 (file)
@@ -17,6 +17,8 @@ config MICROBLAZE
        select HAVE_DMA_ATTRS
        select HAVE_DMA_API_DEBUG
        select TRACING_SUPPORT
+       select OF
+       select OF_FLATTREE
 
 config SWAP
        def_bool n
@@ -75,9 +77,6 @@ config LOCKDEP_SUPPORT
 config HAVE_LATENCYTOP_SUPPORT
        def_bool y
 
-config DTC
-       def_bool y
-
 source "init/Kconfig"
 
 source "kernel/Kconfig.freezer"
@@ -124,18 +123,6 @@ config CMDLINE_FORCE
          Set this to have arguments from the default kernel command string
          override those passed by the boot loader.
 
-config OF
-       def_bool y
-       select OF_FLATTREE
-
-config PROC_DEVICETREE
-       bool "Support for device tree in /proc"
-       depends on PROC_FS
-       help
-         This option adds a device-tree directory under /proc which contains
-         an image of the device tree that the kernel copies from Open
-         Firmware or other boot firmware. If unsure, say Y here.
-
 endmenu
 
 menu "Advanced setup"
index 31a35c3..ec5583d 100644 (file)
@@ -27,17 +27,6 @@ extern unsigned int nr_irq;
 struct pt_regs;
 extern void do_IRQ(struct pt_regs *regs);
 
-/**
- * irq_of_parse_and_map - Parse and Map an interrupt into linux virq space
- * @device: Device node of the device whose interrupt is to be mapped
- * @index: Index of the interrupt to map
- *
- * This function is a wrapper that chains of_irq_map_one() and
- * irq_create_of_mapping() to make things easier to callers
- */
-struct device_node;
-extern unsigned int irq_of_parse_and_map(struct device_node *dev, int index);
-
 /** FIXME - not implement
  * irq_dispose_mapping - Unmap an interrupt
  * @virq: linux virq number of the interrupt to unmap
@@ -62,17 +51,4 @@ struct irq_host;
 extern unsigned int irq_create_mapping(struct irq_host *host,
                                        irq_hw_number_t hwirq);
 
-/**
- * irq_create_of_mapping - Map a hardware interrupt into linux virq space
- * @controller: Device node of the interrupt controller
- * @inspec: Interrupt specifier from the device-tree
- * @intsize: Size of the interrupt specifier from the device-tree
- *
- * This function is identical to irq_create_mapping except that it takes
- * as input informations straight from the device-tree (typically the results
- * of the of_irq_map_*() functions.
- */
-extern unsigned int irq_create_of_mapping(struct device_node *controller,
-                                       u32 *intspec, unsigned int intsize);
-
 #endif /* _ASM_MICROBLAZE_IRQ_H */
index 73cb980..47e8d42 100644 (file)
 
 #ifndef _ASM_MICROBLAZE_OF_DEVICE_H
 #define _ASM_MICROBLAZE_OF_DEVICE_H
-#ifdef __KERNEL__
-
-#include <linux/device.h>
-#include <linux/of.h>
-
-/*
- * 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           dev; /* Generic device interface */
-       struct pdev_archdata    archdata;
-};
-
-extern ssize_t of_device_get_modalias(struct of_device *ofdev,
-                                       char *str, ssize_t len);
-
-extern struct of_device *of_device_alloc(struct device_node *np,
-                                        const char *bus_id,
-                                        struct device *parent);
-
-extern int of_device_uevent(struct device *dev,
-                           struct kobj_uevent_env *env);
-
-extern void of_device_make_bus_id(struct of_device *dev);
-
-/* This is just here during the transition */
-#include <linux/of_device.h>
-
-#endif /* __KERNEL__ */
 #endif /* _ASM_MICROBLAZE_OF_DEVICE_H */
index 3749127..353d8f6 100644 (file)
 /* This is just here during the transition */
 #include <linux/of_platform.h>
 
-/*
- * The list of OF IDs below is used for matching bus types in the
- * system whose devices are to be exposed as of_platform_devices.
- *
- * This is the default list valid for most platforms. This file provides
- * functions who can take an explicit list if necessary though
- *
- * The search is always performed recursively looking for children of
- * the provided device_node and recursively if such a children matches
- * a bus type in the list
- */
-
-static const struct of_device_id of_default_bus_ids[] = {
-       { .type = "soc", },
-       { .compatible = "soc", },
-       { .type = "plb5", },
-       { .type = "plb4", },
-       { .type = "opb", },
-       { .type = "simple", },
-       {},
-};
-
-/* Platform devices and busses creation */
-extern struct of_device *of_platform_device_create(struct device_node *np,
-                                               const char *bus_id,
-                                               struct device *parent);
-/* pseudo "matches" value to not do deep probe */
-#define OF_NO_DEEP_PROBE ((struct of_device_id *)-1)
-
-extern int of_platform_bus_probe(struct device_node *root,
-                               const struct of_device_id *matches,
-                               struct device *parent);
-
-extern struct of_device *of_find_device_by_phandle(phandle ph);
-
 extern void of_instantiate_rtc(void);
 
 #endif /* _ASM_MICROBLAZE_OF_PLATFORM_H */
index 464ff32..2fd4761 100644 (file)
 #define PAGE_UP(addr)  (((addr)+((PAGE_SIZE)-1))&(~((PAGE_SIZE)-1)))
 #define PAGE_DOWN(addr)        ((addr)&(~((PAGE_SIZE)-1)))
 
-/* align addr on a size boundary - adjust address up/down if needed */
-#define _ALIGN_UP(addr, size)  (((addr)+((size)-1))&(~((size)-1)))
-#define _ALIGN_DOWN(addr, size)        ((addr)&(~((size)-1)))
-
-/* align addr on a size boundary - adjust address up if needed */
-#define _ALIGN(addr, size)     _ALIGN_UP(addr, size)
-
 #ifndef CONFIG_MMU
 /*
  * PAGE_OFFSET -- the first address of the first page of memory. When not
index 0c77cda..0c68764 100644 (file)
@@ -172,13 +172,8 @@ static inline int pci_has_flag(int flag)
 
 extern struct list_head hose_list;
 
-extern unsigned long pci_address_to_pio(phys_addr_t address);
 extern int pcibios_vaddr_is_ioport(void __iomem *address);
 #else
-static inline unsigned long pci_address_to_pio(phys_addr_t address)
-{
-       return (unsigned long)-1;
-}
 static inline int pcibios_vaddr_is_ioport(void __iomem *address)
 {
        return 0;
index e7d67a3..cb9c3dd 100644 (file)
@@ -20,6 +20,8 @@
 #ifndef __ASSEMBLY__
 
 #include <linux/types.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
 #include <linux/of_fdt.h>
 #include <linux/proc_fs.h>
 #include <linux/platform_device.h>
@@ -50,10 +52,6 @@ extern void pci_create_OF_bus_map(void);
  * OF address retreival & translation
  */
 
-/* Translate an OF address block into a CPU physical address
- */
-extern u64 of_translate_address(struct device_node *np, const u32 *addr);
-
 /* Extract an address from a device, returns the region size and
  * the address space flags too. The PCI version uses a BAR number
  * instead of an absolute index
@@ -63,17 +61,18 @@ extern const u32 *of_get_address(struct device_node *dev, int index,
 extern const u32 *of_get_pci_address(struct device_node *dev, int bar_no,
                        u64 *size, unsigned int *flags);
 
-/* Get an address as a resource. Note that if your address is
- * a PIO address, the conversion will fail if the physical address
- * can't be internally converted to an IO token with
- * pci_address_to_pio(), that is because it's either called to early
- * or it can't be matched to any host bridge IO space
- */
-extern int of_address_to_resource(struct device_node *dev, int index,
-                               struct resource *r);
 extern int of_pci_address_to_resource(struct device_node *dev, int bar,
                                struct resource *r);
 
+#ifdef CONFIG_PCI
+extern unsigned long pci_address_to_pio(phys_addr_t address);
+#else
+static inline unsigned long pci_address_to_pio(phys_addr_t address)
+{
+       return (unsigned long)-1;
+}
+#endif /* CONFIG_PCI */
+
 /* Parse the ibm,dma-window property of an OF node into the busno, phys and
  * size parameters.
  */
@@ -88,69 +87,6 @@ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
 /* Get the MAC address */
 extern const void *of_get_mac_address(struct device_node *np);
 
-/*
- * OF interrupt mapping
- */
-
-/* This structure is returned when an interrupt is mapped. The controller
- * field needs to be put() after use
- */
-
-#define OF_MAX_IRQ_SPEC                4 /* We handle specifiers of at most 4 cells */
-
-struct of_irq {
-       struct device_node *controller; /* Interrupt controller node */
-       u32 size; /* Specifier size */
-       u32 specifier[OF_MAX_IRQ_SPEC]; /* Specifier copy */
-};
-
-/**
- * of_irq_map_init - Initialize the irq remapper
- * @flags:     flags defining workarounds to enable
- *
- * Some machines have bugs in the device-tree which require certain workarounds
- * to be applied. Call this before any interrupt mapping attempts to enable
- * those workarounds.
- */
-#define OF_IMAP_OLDWORLD_MAC   0x00000001
-#define OF_IMAP_NO_PHANDLE     0x00000002
-
-extern void of_irq_map_init(unsigned int flags);
-
-/**
- * of_irq_map_raw - Low level interrupt tree parsing
- * @parent:    the device interrupt parent
- * @intspec:   interrupt specifier ("interrupts" property of the device)
- * @ointsize:  size of the passed in interrupt specifier
- * @addr:      address specifier (start of "reg" property of the device)
- * @out_irq:   structure of_irq filled by this function
- *
- * Returns 0 on success and a negative number on error
- *
- * This function is a low-level interrupt tree walking function. It
- * can be used to do a partial walk with synthetized reg and interrupts
- * properties, for example when resolving PCI interrupts when no device
- * node exist for the parent.
- *
- */
-
-extern int of_irq_map_raw(struct device_node *parent, const u32 *intspec,
-                       u32 ointsize, const u32 *addr,
-                       struct of_irq *out_irq);
-
-/**
- * of_irq_map_one - Resolve an interrupt for a device
- * @device:    the device whose interrupt is to be resolved
- * @index:     index of the interrupt to resolve
- * @out_irq:   structure of_irq filled by this function
- *
- * This function resolves an interrupt, walking the tree, for a given
- * device-tree node. It's the high level pendant to of_irq_map_raw().
- * It also implements the workarounds for OldWolrd Macs.
- */
-extern int of_irq_map_one(struct device_node *device, int index,
-                       struct of_irq *out_irq);
-
 /**
  * of_irq_map_pci - Resolve the interrupt for a PCI device
  * @pdev:      the device whose interrupt is to be resolved
@@ -165,18 +101,6 @@ extern int of_irq_map_one(struct device_node *device, int index,
 struct pci_dev;
 extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
 
-extern int of_irq_to_resource(struct device_node *dev, int index,
-                       struct resource *r);
-
-/**
- * of_iomap - Maps the memory mapped IO for a given device_node
- * @device:    the device whose io range will be mapped
- * @index:     index of the io range
- *
- * Returns a pointer to the mapped memory
- */
-extern void __iomem *of_iomap(struct device_node *device, int index);
-
 #endif /* __ASSEMBLY__ */
 #endif /* __KERNEL__ */
 #endif /* _ASM_MICROBLAZE_PROM_H */
index e51bc15..727e2cb 100644 (file)
@@ -15,7 +15,7 @@ endif
 extra-y := head.o vmlinux.lds
 
 obj-y += dma.o exceptions.o \
-       hw_exception_handler.o init_task.o intc.o irq.o of_device.o \
+       hw_exception_handler.o init_task.o intc.o irq.o \
        of_platform.o process.o prom.o prom_parse.o ptrace.o \
        setup.o signal.o sys_microblaze.o timer.o traps.o reset.o
 
index 8f120ac..dd32b09 100644 (file)
 #include <linux/seq_file.h>
 #include <linux/kernel_stat.h>
 #include <linux/irq.h>
+#include <linux/of_irq.h>
 
 #include <asm/prom.h>
 
-unsigned int irq_of_parse_and_map(struct device_node *dev, int index)
-{
-       struct of_irq oirq;
-
-       if (of_irq_map_one(dev, index, &oirq))
-               return NO_IRQ;
-
-       return oirq.specifier[0];
-}
-EXPORT_SYMBOL_GPL(irq_of_parse_and_map);
-
 static u32 concurrent_irq;
 
 void __irq_entry do_IRQ(struct pt_regs *regs)
@@ -104,7 +94,7 @@ unsigned int irq_create_mapping(struct irq_host *host, irq_hw_number_t hwirq)
 EXPORT_SYMBOL_GPL(irq_create_mapping);
 
 unsigned int irq_create_of_mapping(struct device_node *controller,
-                                       u32 *intspec, unsigned int intsize)
+                                  const u32 *intspec, unsigned int intsize)
 {
        return intspec[0];
 }
diff --git a/arch/microblaze/kernel/of_device.c b/arch/microblaze/kernel/of_device.c
deleted file mode 100644 (file)
index b372787..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/of.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/mod_devicetable.h>
-#include <linux/slab.h>
-#include <linux/of_device.h>
-
-#include <linux/errno.h>
-
-void of_device_make_bus_id(struct of_device *dev)
-{
-       static atomic_t bus_no_reg_magic;
-       struct device_node *node = dev->dev.of_node;
-       const u32 *reg;
-       u64 addr;
-       int magic;
-
-       /*
-        * For MMIO, get the physical address
-        */
-       reg = of_get_property(node, "reg", NULL);
-       if (reg) {
-               addr = of_translate_address(node, reg);
-               if (addr != OF_BAD_ADDR) {
-                       dev_set_name(&dev->dev, "%llx.%s",
-                                    (unsigned long long)addr, node->name);
-                       return;
-               }
-       }
-
-       /*
-        * No BusID, use the node name and add a globally incremented
-        * counter (and pray...)
-        */
-       magic = atomic_add_return(1, &bus_no_reg_magic);
-       dev_set_name(&dev->dev, "%s.%d", node->name, magic - 1);
-}
-EXPORT_SYMBOL(of_device_make_bus_id);
-
-struct of_device *of_device_alloc(struct device_node *np,
-                                 const char *bus_id,
-                                 struct device *parent)
-{
-       struct of_device *dev;
-
-       dev = kzalloc(sizeof(*dev), GFP_KERNEL);
-       if (!dev)
-               return NULL;
-
-       dev->dev.of_node = of_node_get(np);
-       dev->dev.dma_mask = &dev->archdata.dma_mask;
-       dev->dev.parent = parent;
-       dev->dev.release = of_release_dev;
-
-       if (bus_id)
-               dev_set_name(&dev->dev, bus_id);
-       else
-               of_device_make_bus_id(dev);
-
-       return dev;
-}
-EXPORT_SYMBOL(of_device_alloc);
-
-int of_device_uevent(struct device *dev, struct kobj_uevent_env *env)
-{
-       struct of_device *ofdev;
-       const char *compat;
-       int seen = 0, cplen, sl;
-
-       if (!dev)
-               return -ENODEV;
-
-       ofdev = to_of_device(dev);
-
-       if (add_uevent_var(env, "OF_NAME=%s", ofdev->dev.of_node->name))
-               return -ENOMEM;
-
-       if (add_uevent_var(env, "OF_TYPE=%s", ofdev->dev.of_node->type))
-               return -ENOMEM;
-
-       /* Since the compatible field can contain pretty much anything
-        * it's not really legal to split it out with commas. We split it
-        * up using a number of environment variables instead. */
-
-       compat = of_get_property(ofdev->dev.of_node, "compatible", &cplen);
-       while (compat && *compat && cplen > 0) {
-               if (add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat))
-                       return -ENOMEM;
-
-               sl = strlen(compat) + 1;
-               compat += sl;
-               cplen -= sl;
-               seen++;
-       }
-
-       if (add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen))
-               return -ENOMEM;
-
-       /* modalias is trickier, we add it in 2 steps */
-       if (add_uevent_var(env, "MODALIAS="))
-               return -ENOMEM;
-       sl = of_device_get_modalias(ofdev, &env->buf[env->buflen-1],
-                                   sizeof(env->buf) - env->buflen);
-       if (sl >= (sizeof(env->buf) - env->buflen))
-               return -ENOMEM;
-       env->buflen += sl;
-
-       return 0;
-}
-EXPORT_SYMBOL(of_device_uevent);
index ccf6f42..da79edf 100644 (file)
@@ -37,132 +37,27 @@ static int __init of_bus_driver_init(void)
 }
 postcore_initcall(of_bus_driver_init);
 
-struct of_device *of_platform_device_create(struct device_node *np,
-                                           const char *bus_id,
-                                           struct device *parent)
-{
-       struct of_device *dev;
-
-       dev = of_device_alloc(np, bus_id, parent);
-       if (!dev)
-               return NULL;
-
-       dev->archdata.dma_mask = 0xffffffffUL;
-       dev->dev.bus = &of_platform_bus_type;
-
-       /* We do not fill the DMA ops for platform devices by default.
-        * This is currently the responsibility of the platform code
-        * to do such, possibly using a device notifier
-        */
-
-       if (of_device_register(dev) != 0) {
-               of_device_free(dev);
-               return NULL;
-       }
-
-       return dev;
-}
-EXPORT_SYMBOL(of_platform_device_create);
-
-/**
- * of_platform_bus_create - Create an OF device for a bus node and all its
- * children. Optionally recursively instanciate matching busses.
- * @bus: device node of the bus to instanciate
- * @matches: match table, NULL to use the default, OF_NO_DEEP_PROBE to
- * disallow recursive creation of child busses
- */
-static int of_platform_bus_create(const struct device_node *bus,
-                                 const struct of_device_id *matches,
-                                 struct device *parent)
-{
-       struct device_node *child;
-       struct of_device *dev;
-       int rc = 0;
-
-       for_each_child_of_node(bus, child) {
-               pr_debug("   create child: %s\n", child->full_name);
-               dev = of_platform_device_create(child, NULL, parent);
-               if (dev == NULL)
-                       rc = -ENOMEM;
-               else if (!of_match_node(matches, child))
-                       continue;
-               if (rc == 0) {
-                       pr_debug("   and sub busses\n");
-                       rc = of_platform_bus_create(child, matches, &dev->dev);
-               }
-               if (rc) {
-                       of_node_put(child);
-                       break;
-               }
-       }
-       return rc;
-}
-
-
-/**
- * of_platform_bus_probe - Probe the device-tree for platform busses
- * @root: parent of the first level to probe or NULL for the root of the tree
- * @matches: match table, NULL to use the default
- * @parent: parent to hook devices from, NULL for toplevel
+/*
+ * The list of OF IDs below is used for matching bus types in the
+ * system whose devices are to be exposed as of_platform_devices.
+ *
+ * This is the default list valid for most platforms. This file provides
+ * functions who can take an explicit list if necessary though
  *
- * Note that children of the provided root are not instanciated as devices
- * unless the specified root itself matches the bus list and is not NULL.
+ * The search is always performed recursively looking for children of
+ * the provided device_node and recursively if such a children matches
+ * a bus type in the list
  */
 
-int of_platform_bus_probe(struct device_node *root,
-                         const struct of_device_id *matches,
-                         struct device *parent)
-{
-       struct device_node *child;
-       struct of_device *dev;
-       int rc = 0;
-
-       if (matches == NULL)
-               matches = of_default_bus_ids;
-       if (matches == OF_NO_DEEP_PROBE)
-               return -EINVAL;
-       if (root == NULL)
-               root = of_find_node_by_path("/");
-       else
-               of_node_get(root);
-
-       pr_debug("of_platform_bus_probe()\n");
-       pr_debug(" starting at: %s\n", root->full_name);
-
-       /* Do a self check of bus type, if there's a match, create
-        * children
-        */
-       if (of_match_node(matches, root)) {
-               pr_debug(" root match, create all sub devices\n");
-               dev = of_platform_device_create(root, NULL, parent);
-               if (dev == NULL) {
-                       rc = -ENOMEM;
-                       goto bail;
-               }
-               pr_debug(" create all sub busses\n");
-               rc = of_platform_bus_create(root, matches, &dev->dev);
-               goto bail;
-       }
-       for_each_child_of_node(root, child) {
-               if (!of_match_node(matches, child))
-                       continue;
-
-               pr_debug("  match: %s\n", child->full_name);
-               dev = of_platform_device_create(child, NULL, parent);
-               if (dev == NULL)
-                       rc = -ENOMEM;
-               else
-                       rc = of_platform_bus_create(child, matches, &dev->dev);
-               if (rc) {
-                       of_node_put(child);
-                       break;
-               }
-       }
- bail:
-       of_node_put(root);
-       return rc;
-}
-EXPORT_SYMBOL(of_platform_bus_probe);
+const struct of_device_id of_default_bus_ids[] = {
+       { .type = "soc", },
+       { .compatible = "soc", },
+       { .type = "plb5", },
+       { .type = "plb4", },
+       { .type = "opb", },
+       { .type = "simple", },
+       {},
+};
 
 static int of_dev_node_match(struct device *dev, void *data)
 {
@@ -180,21 +75,3 @@ struct of_device *of_find_device_by_node(struct device_node *np)
        return NULL;
 }
 EXPORT_SYMBOL(of_find_device_by_node);
-
-static int of_dev_phandle_match(struct device *dev, void *data)
-{
-       phandle *ph = data;
-       return to_of_device(dev)->dev.of_node->phandle == *ph;
-}
-
-struct of_device *of_find_device_by_phandle(phandle ph)
-{
-       struct device *dev;
-
-       dev = bus_find_device(&of_platform_bus_type,
-                             NULL, &ph, of_dev_phandle_match);
-       if (dev)
-               return to_of_device(dev);
-       return NULL;
-}
-EXPORT_SYMBOL(of_find_device_by_phandle);
index bf7e6c2..d33ba17 100644 (file)
 #include <linux/module.h>
 #include <linux/ioport.h>
 #include <linux/etherdevice.h>
+#include <linux/of_address.h>
 #include <asm/prom.h>
 #include <asm/pci-bridge.h>
 
-#define PRu64  "%llx"
-
-/* Max address size we deal with */
-#define OF_MAX_ADDR_CELLS      4
-#define OF_CHECK_COUNTS(na, ns)        ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS && \
-                       (ns) > 0)
-
-static struct of_bus *of_match_bus(struct device_node *np);
-static int __of_address_to_resource(struct device_node *dev,
-               const u32 *addrp, u64 size, unsigned int flags,
-               struct resource *r);
-
-/* Debug utility */
-#ifdef DEBUG
-static void of_dump_addr(const char *s, const u32 *addr, int na)
-{
-       printk(KERN_INFO "%s", s);
-       while (na--)
-               printk(KERN_INFO " %08x", *(addr++));
-       printk(KERN_INFO "\n");
-}
-#else
-static void of_dump_addr(const char *s, const u32 *addr, int na) { }
-#endif
-
-/* Callbacks for bus specific translators */
-struct of_bus {
-       const char      *name;
-       const char      *addresses;
-       int             (*match)(struct device_node *parent);
-       void            (*count_cells)(struct device_node *child,
-                                       int *addrc, int *sizec);
-       u64             (*map)(u32 *addr, const u32 *range,
-                               int na, int ns, int pna);
-       int             (*translate)(u32 *addr, u64 offset, int na);
-       unsigned int    (*get_flags)(const u32 *addr);
-};
-
-/*
- * Default translator (generic bus)
- */
-
-static void of_bus_default_count_cells(struct device_node *dev,
-                                       int *addrc, int *sizec)
-{
-       if (addrc)
-               *addrc = of_n_addr_cells(dev);
-       if (sizec)
-               *sizec = of_n_size_cells(dev);
-}
-
-static u64 of_bus_default_map(u32 *addr, const u32 *range,
-               int na, int ns, int pna)
-{
-       u64 cp, s, da;
-
-       cp = of_read_number(range, na);
-       s  = of_read_number(range + na + pna, ns);
-       da = of_read_number(addr, na);
-
-       pr_debug("OF: default map, cp="PRu64", s="PRu64", da="PRu64"\n",
-               cp, s, da);
-
-       if (da < cp || da >= (cp + s))
-               return OF_BAD_ADDR;
-       return da - cp;
-}
-
-static int of_bus_default_translate(u32 *addr, u64 offset, int na)
-{
-       u64 a = of_read_number(addr, na);
-       memset(addr, 0, na * 4);
-       a += offset;
-       if (na > 1)
-               addr[na - 2] = a >> 32;
-       addr[na - 1] = a & 0xffffffffu;
-
-       return 0;
-}
-
-static unsigned int of_bus_default_get_flags(const u32 *addr)
-{
-       return IORESOURCE_MEM;
-}
-
 #ifdef CONFIG_PCI
-/*
- * PCI bus specific translator
- */
-
-static int of_bus_pci_match(struct device_node *np)
-{
-       /* "vci" is for the /chaos bridge on 1st-gen PCI powermacs */
-       return !strcmp(np->type, "pci") || !strcmp(np->type, "vci");
-}
-
-static void of_bus_pci_count_cells(struct device_node *np,
-                               int *addrc, int *sizec)
-{
-       if (addrc)
-               *addrc = 3;
-       if (sizec)
-               *sizec = 2;
-}
-
-static u64 of_bus_pci_map(u32 *addr, const u32 *range, int na, int ns, int pna)
-{
-       u64 cp, s, da;
-
-       /* Check address type match */
-       if ((addr[0] ^ range[0]) & 0x03000000)
-               return OF_BAD_ADDR;
-
-       /* Read address values, skipping high cell */
-       cp = of_read_number(range + 1, na - 1);
-       s  = of_read_number(range + na + pna, ns);
-       da = of_read_number(addr + 1, na - 1);
-
-       pr_debug("OF: PCI map, cp="PRu64", s="PRu64", da="PRu64"\n", cp, s, da);
-
-       if (da < cp || da >= (cp + s))
-               return OF_BAD_ADDR;
-       return da - cp;
-}
-
-static int of_bus_pci_translate(u32 *addr, u64 offset, int na)
-{
-       return of_bus_default_translate(addr + 1, offset, na - 1);
-}
-
-static unsigned int of_bus_pci_get_flags(const u32 *addr)
-{
-       unsigned int flags = 0;
-       u32 w = addr[0];
-
-       switch ((w >> 24) & 0x03) {
-       case 0x01:
-               flags |= IORESOURCE_IO;
-               break;
-       case 0x02: /* 32 bits */
-       case 0x03: /* 64 bits */
-               flags |= IORESOURCE_MEM;
-               break;
-       }
-       if (w & 0x40000000)
-               flags |= IORESOURCE_PREFETCH;
-       return flags;
-}
-
-const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
-                       unsigned int *flags)
-{
-       const u32 *prop;
-       unsigned int psize;
-       struct device_node *parent;
-       struct of_bus *bus;
-       int onesize, i, na, ns;
-
-       /* Get parent & match bus type */
-       parent = of_get_parent(dev);
-       if (parent == NULL)
-               return NULL;
-       bus = of_match_bus(parent);
-       if (strcmp(bus->name, "pci")) {
-               of_node_put(parent);
-               return NULL;
-       }
-       bus->count_cells(dev, &na, &ns);
-       of_node_put(parent);
-       if (!OF_CHECK_COUNTS(na, ns))
-               return NULL;
-
-       /* Get "reg" or "assigned-addresses" property */
-       prop = of_get_property(dev, bus->addresses, &psize);
-       if (prop == NULL)
-               return NULL;
-       psize /= 4;
-
-       onesize = na + ns;
-       for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++)
-               if ((prop[0] & 0xff) == ((bar_no * 4) + PCI_BASE_ADDRESS_0)) {
-                       if (size)
-                               *size = of_read_number(prop + na, ns);
-                       if (flags)
-                               *flags = bus->get_flags(prop);
-                       return prop;
-               }
-       return NULL;
-}
-EXPORT_SYMBOL(of_get_pci_address);
-
-int of_pci_address_to_resource(struct device_node *dev, int bar,
-                               struct resource *r)
-{
-       const u32       *addrp;
-       u64             size;
-       unsigned int    flags;
-
-       addrp = of_get_pci_address(dev, bar, &size, &flags);
-       if (addrp == NULL)
-               return -EINVAL;
-       return __of_address_to_resource(dev, addrp, size, flags, r);
-}
-EXPORT_SYMBOL_GPL(of_pci_address_to_resource);
-
-static u8 of_irq_pci_swizzle(u8 slot, u8 pin)
-{
-       return (((pin - 1) + slot) % 4) + 1;
-}
-
 int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
 {
        struct device_node *dn, *ppnode;
@@ -293,331 +85,6 @@ int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
 EXPORT_SYMBOL_GPL(of_irq_map_pci);
 #endif /* CONFIG_PCI */
 
-/*
- * ISA bus specific translator
- */
-
-static int of_bus_isa_match(struct device_node *np)
-{
-       return !strcmp(np->name, "isa");
-}
-
-static void of_bus_isa_count_cells(struct device_node *child,
-                               int *addrc, int *sizec)
-{
-       if (addrc)
-               *addrc = 2;
-       if (sizec)
-               *sizec = 1;
-}
-
-static u64 of_bus_isa_map(u32 *addr, const u32 *range, int na, int ns, int pna)
-{
-       u64 cp, s, da;
-
-       /* Check address type match */
-       if ((addr[0] ^ range[0]) & 0x00000001)
-               return OF_BAD_ADDR;
-
-       /* Read address values, skipping high cell */
-       cp = of_read_number(range + 1, na - 1);
-       s  = of_read_number(range + na + pna, ns);
-       da = of_read_number(addr + 1, na - 1);
-
-       pr_debug("OF: ISA map, cp="PRu64", s="PRu64", da="PRu64"\n", cp, s, da);
-
-       if (da < cp || da >= (cp + s))
-               return OF_BAD_ADDR;
-       return da - cp;
-}
-
-static int of_bus_isa_translate(u32 *addr, u64 offset, int na)
-{
-       return of_bus_default_translate(addr + 1, offset, na - 1);
-}
-
-static unsigned int of_bus_isa_get_flags(const u32 *addr)
-{
-       unsigned int flags = 0;
-       u32 w = addr[0];
-
-       if (w & 1)
-               flags |= IORESOURCE_IO;
-       else
-               flags |= IORESOURCE_MEM;
-       return flags;
-}
-
-/*
- * Array of bus specific translators
- */
-
-static struct of_bus of_busses[] = {
-#ifdef CONFIG_PCI
-       /* PCI */
-       {
-               .name = "pci",
-               .addresses = "assigned-addresses",
-               .match = of_bus_pci_match,
-               .count_cells = of_bus_pci_count_cells,
-               .map = of_bus_pci_map,
-               .translate = of_bus_pci_translate,
-               .get_flags = of_bus_pci_get_flags,
-       },
-#endif /* CONFIG_PCI */
-       /* ISA */
-       {
-               .name = "isa",
-               .addresses = "reg",
-               .match = of_bus_isa_match,
-               .count_cells = of_bus_isa_count_cells,
-               .map = of_bus_isa_map,
-               .translate = of_bus_isa_translate,
-               .get_flags = of_bus_isa_get_flags,
-       },
-       /* Default */
-       {
-               .name = "default",
-               .addresses = "reg",
-               .match = NULL,
-               .count_cells = of_bus_default_count_cells,
-               .map = of_bus_default_map,
-               .translate = of_bus_default_translate,
-               .get_flags = of_bus_default_get_flags,
-       },
-};
-
-static struct of_bus *of_match_bus(struct device_node *np)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(of_busses); i++)
-               if (!of_busses[i].match || of_busses[i].match(np))
-                       return &of_busses[i];
-       BUG();
-       return NULL;
-}
-
-static int of_translate_one(struct device_node *parent, struct of_bus *bus,
-                       struct of_bus *pbus, u32 *addr,
-                       int na, int ns, int pna)
-{
-       const u32 *ranges;
-       unsigned int rlen;
-       int rone;
-       u64 offset = OF_BAD_ADDR;
-
-       /* Normally, an absence of a "ranges" property means we are
-        * crossing a non-translatable boundary, and thus the addresses
-        * below the current not cannot be converted to CPU physical ones.
-        * Unfortunately, while this is very clear in the spec, it's not
-        * what Apple understood, and they do have things like /uni-n or
-        * /ht nodes with no "ranges" property and a lot of perfectly
-        * useable mapped devices below them. Thus we treat the absence of
-        * "ranges" as equivalent to an empty "ranges" property which means
-        * a 1:1 translation at that level. It's up to the caller not to try
-        * to translate addresses that aren't supposed to be translated in
-        * the first place. --BenH.
-        */
-       ranges = of_get_property(parent, "ranges", (int *) &rlen);
-       if (ranges == NULL || rlen == 0) {
-               offset = of_read_number(addr, na);
-               memset(addr, 0, pna * 4);
-               pr_debug("OF: no ranges, 1:1 translation\n");
-               goto finish;
-       }
-
-       pr_debug("OF: walking ranges...\n");
-
-       /* Now walk through the ranges */
-       rlen /= 4;
-       rone = na + pna + ns;
-       for (; rlen >= rone; rlen -= rone, ranges += rone) {
-               offset = bus->map(addr, ranges, na, ns, pna);
-               if (offset != OF_BAD_ADDR)
-                       break;
-       }
-       if (offset == OF_BAD_ADDR) {
-               pr_debug("OF: not found !\n");
-               return 1;
-       }
-       memcpy(addr, ranges + na, 4 * pna);
-
- finish:
-       of_dump_addr("OF: parent translation for:", addr, pna);
-       pr_debug("OF: with offset: "PRu64"\n", offset);
-
-       /* Translate it into parent bus space */
-       return pbus->translate(addr, offset, pna);
-}
-
-/*
- * Translate an address from the device-tree into a CPU physical address,
- * this walks up the tree and applies the various bus mappings on the
- * way.
- *
- * Note: We consider that crossing any level with #size-cells == 0 to mean
- * that translation is impossible (that is we are not dealing with a value
- * that can be mapped to a cpu physical address). This is not really specified
- * that way, but this is traditionally the way IBM at least do things
- */
-u64 of_translate_address(struct device_node *dev, const u32 *in_addr)
-{
-       struct device_node *parent = NULL;
-       struct of_bus *bus, *pbus;
-       u32 addr[OF_MAX_ADDR_CELLS];
-       int na, ns, pna, pns;
-       u64 result = OF_BAD_ADDR;
-
-       pr_debug("OF: ** translation for device %s **\n", dev->full_name);
-
-       /* Increase refcount at current level */
-       of_node_get(dev);
-
-       /* Get parent & match bus type */
-       parent = of_get_parent(dev);
-       if (parent == NULL)
-               goto bail;
-       bus = of_match_bus(parent);
-
-       /* Cound address cells & copy address locally */
-       bus->count_cells(dev, &na, &ns);
-       if (!OF_CHECK_COUNTS(na, ns)) {
-               printk(KERN_ERR "prom_parse: Bad cell count for %s\n",
-                       dev->full_name);
-               goto bail;
-       }
-       memcpy(addr, in_addr, na * 4);
-
-       pr_debug("OF: bus is %s (na=%d, ns=%d) on %s\n",
-               bus->name, na, ns, parent->full_name);
-       of_dump_addr("OF: translating address:", addr, na);
-
-       /* Translate */
-       for (;;) {
-               /* Switch to parent bus */
-               of_node_put(dev);
-               dev = parent;
-               parent = of_get_parent(dev);
-
-               /* If root, we have finished */
-               if (parent == NULL) {
-                       pr_debug("OF: reached root node\n");
-                       result = of_read_number(addr, na);
-                       break;
-               }
-
-               /* Get new parent bus and counts */
-               pbus = of_match_bus(parent);
-               pbus->count_cells(dev, &pna, &pns);
-               if (!OF_CHECK_COUNTS(pna, pns)) {
-                       printk(KERN_ERR "prom_parse: Bad cell count for %s\n",
-                               dev->full_name);
-                       break;
-               }
-
-               pr_debug("OF: parent bus is %s (na=%d, ns=%d) on %s\n",
-                       pbus->name, pna, pns, parent->full_name);
-
-               /* Apply bus translation */
-               if (of_translate_one(dev, bus, pbus, addr, na, ns, pna))
-                       break;
-
-               /* Complete the move up one level */
-               na = pna;
-               ns = pns;
-               bus = pbus;
-
-               of_dump_addr("OF: one level translation:", addr, na);
-       }
- bail:
-       of_node_put(parent);
-       of_node_put(dev);
-
-       return result;
-}
-EXPORT_SYMBOL(of_translate_address);
-
-const u32 *of_get_address(struct device_node *dev, int index, u64 *size,
-                       unsigned int *flags)
-{
-       const u32 *prop;
-       unsigned int psize;
-       struct device_node *parent;
-       struct of_bus *bus;
-       int onesize, i, na, ns;
-
-       /* Get parent & match bus type */
-       parent = of_get_parent(dev);
-       if (parent == NULL)
-               return NULL;
-       bus = of_match_bus(parent);
-       bus->count_cells(dev, &na, &ns);
-       of_node_put(parent);
-       if (!OF_CHECK_COUNTS(na, ns))
-               return NULL;
-
-       /* Get "reg" or "assigned-addresses" property */
-       prop = of_get_property(dev, bus->addresses, (int *) &psize);
-       if (prop == NULL)
-               return NULL;
-       psize /= 4;
-
-       onesize = na + ns;
-       for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++)
-               if (i == index) {
-                       if (size)
-                               *size = of_read_number(prop + na, ns);
-                       if (flags)
-                               *flags = bus->get_flags(prop);
-                       return prop;
-               }
-       return NULL;
-}
-EXPORT_SYMBOL(of_get_address);
-
-static int __of_address_to_resource(struct device_node *dev, const u32 *addrp,
-                               u64 size, unsigned int flags,
-                               struct resource *r)
-{
-       u64 taddr;
-
-       if ((flags & (IORESOURCE_IO | IORESOURCE_MEM)) == 0)
-               return -EINVAL;
-       taddr = of_translate_address(dev, addrp);
-       if (taddr == OF_BAD_ADDR)
-               return -EINVAL;
-       memset(r, 0, sizeof(struct resource));
-       if (flags & IORESOURCE_IO) {
-               unsigned long port;
-               port = -1; /* pci_address_to_pio(taddr); */
-               if (port == (unsigned long)-1)
-                       return -EINVAL;
-               r->start = port;
-               r->end = port + size - 1;
-       } else {
-               r->start = taddr;
-               r->end = taddr + size - 1;
-       }
-       r->flags = flags;
-       r->name = dev->name;
-       return 0;
-}
-
-int of_address_to_resource(struct device_node *dev, int index,
-                       struct resource *r)
-{
-       const u32       *addrp;
-       u64             size;
-       unsigned int    flags;
-
-       addrp = of_get_address(dev, index, &size, &flags);
-       if (addrp == NULL)
-               return -EINVAL;
-       return __of_address_to_resource(dev, addrp, size, flags, r);
-}
-EXPORT_SYMBOL_GPL(of_address_to_resource);
-
 void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
                unsigned long *busno, unsigned long *phys, unsigned long *size)
 {
@@ -644,308 +111,6 @@ void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
        *size = of_read_number(dma_window, cells);
 }
 
-/*
- * Interrupt remapper
- */
-
-static unsigned int of_irq_workarounds;
-static struct device_node *of_irq_dflt_pic;
-
-static struct device_node *of_irq_find_parent(struct device_node *child)
-{
-       struct device_node *p;
-       const phandle *parp;
-
-       if (!of_node_get(child))
-               return NULL;
-
-       do {
-               parp = of_get_property(child, "interrupt-parent", NULL);
-               if (parp == NULL)
-                       p = of_get_parent(child);
-               else {
-                       if (of_irq_workarounds & OF_IMAP_NO_PHANDLE)
-                               p = of_node_get(of_irq_dflt_pic);
-                       else
-                               p = of_find_node_by_phandle(*parp);
-               }
-               of_node_put(child);
-               child = p;
-       } while (p && of_get_property(p, "#interrupt-cells", NULL) == NULL);
-
-       return p;
-}
-
-/* This doesn't need to be called if you don't have any special workaround
- * flags to pass
- */
-void of_irq_map_init(unsigned int flags)
-{
-       of_irq_workarounds = flags;
-
-       /* OldWorld, don't bother looking at other things */
-       if (flags & OF_IMAP_OLDWORLD_MAC)
-               return;
-
-       /* If we don't have phandles, let's try to locate a default interrupt
-        * controller (happens when booting with BootX). We do a first match
-        * here, hopefully, that only ever happens on machines with one
-        * controller.
-        */
-       if (flags & OF_IMAP_NO_PHANDLE) {
-               struct device_node *np;
-
-               for (np = NULL; (np = of_find_all_nodes(np)) != NULL;) {
-                       if (of_get_property(np, "interrupt-controller", NULL)
-                               == NULL)
-                               continue;
-                       /* Skip /chosen/interrupt-controller */
-                       if (strcmp(np->name, "chosen") == 0)
-                               continue;
-                       /* It seems like at least one person on this planet
-                        * wants to use BootX on a machine with an AppleKiwi
-                        * controller which happens to pretend to be an
-                        * interrupt controller too.
-                        */
-                       if (strcmp(np->name, "AppleKiwi") == 0)
-                               continue;
-                       /* I think we found one ! */
-                       of_irq_dflt_pic = np;
-                       break;
-               }
-       }
-
-}
-
-int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize,
-               const u32 *addr, struct of_irq *out_irq)
-{
-       struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL;
-       const u32 *tmp, *imap, *imask;
-       u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0;
-       int imaplen, match, i;
-
-       pr_debug("of_irq_map_raw: par=%s,intspec=[0x%08x 0x%08x...],"
-               "ointsize=%d\n",
-               parent->full_name, intspec[0], intspec[1], ointsize);
-
-       ipar = of_node_get(parent);
-
-       /* First get the #interrupt-cells property of the current cursor
-        * that tells us how to interpret the passed-in intspec. If there
-        * is none, we are nice and just walk up the tree
-        */
-       do {
-               tmp = of_get_property(ipar, "#interrupt-cells", NULL);
-               if (tmp != NULL) {
-                       intsize = *tmp;
-                       break;
-               }
-               tnode = ipar;
-               ipar = of_irq_find_parent(ipar);
-               of_node_put(tnode);
-       } while (ipar);
-       if (ipar == NULL) {
-               pr_debug(" -> no parent found !\n");
-               goto fail;
-       }
-
-       pr_debug("of_irq_map_raw: ipar=%s, size=%d\n",
-                       ipar->full_name, intsize);
-
-       if (ointsize != intsize)
-               return -EINVAL;
-
-       /* Look for this #address-cells. We have to implement the old linux
-        * trick of looking for the parent here as some device-trees rely on it
-        */
-       old = of_node_get(ipar);
-       do {
-               tmp = of_get_property(old, "#address-cells", NULL);
-               tnode = of_get_parent(old);
-               of_node_put(old);
-               old = tnode;
-       } while (old && tmp == NULL);
-       of_node_put(old);
-       old = NULL;
-       addrsize = (tmp == NULL) ? 2 : *tmp;
-
-       pr_debug(" -> addrsize=%d\n", addrsize);
-
-       /* Now start the actual "proper" walk of the interrupt tree */
-       while (ipar != NULL) {
-               /* Now check if cursor is an interrupt-controller and if it is
-                * then we are done
-                */
-               if (of_get_property(ipar, "interrupt-controller", NULL) !=
-                               NULL) {
-                       pr_debug(" -> got it !\n");
-                       memcpy(out_irq->specifier, intspec,
-                               intsize * sizeof(u32));
-                       out_irq->size = intsize;
-                       out_irq->controller = ipar;
-                       of_node_put(old);
-                       return 0;
-               }
-
-               /* Now look for an interrupt-map */
-               imap = of_get_property(ipar, "interrupt-map", &imaplen);
-               /* No interrupt map, check for an interrupt parent */
-               if (imap == NULL) {
-                       pr_debug(" -> no map, getting parent\n");
-                       newpar = of_irq_find_parent(ipar);
-                       goto skiplevel;
-               }
-               imaplen /= sizeof(u32);
-
-               /* Look for a mask */
-               imask = of_get_property(ipar, "interrupt-map-mask", NULL);
-
-               /* If we were passed no "reg" property and we attempt to parse
-                * an interrupt-map, then #address-cells must be 0.
-                * Fail if it's not.
-                */
-               if (addr == NULL && addrsize != 0) {
-                       pr_debug(" -> no reg passed in when needed !\n");
-                       goto fail;
-               }
-
-               /* Parse interrupt-map */
-               match = 0;
-               while (imaplen > (addrsize + intsize + 1) && !match) {
-                       /* Compare specifiers */
-                       match = 1;
-                       for (i = 0; i < addrsize && match; ++i) {
-                               u32 mask = imask ? imask[i] : 0xffffffffu;
-                               match = ((addr[i] ^ imap[i]) & mask) == 0;
-                       }
-                       for (; i < (addrsize + intsize) && match; ++i) {
-                               u32 mask = imask ? imask[i] : 0xffffffffu;
-                               match =
-                                       ((intspec[i-addrsize] ^ imap[i])
-                                               & mask) == 0;
-                       }
-                       imap += addrsize + intsize;
-                       imaplen -= addrsize + intsize;
-
-                       pr_debug(" -> match=%d (imaplen=%d)\n", match, imaplen);
-
-                       /* Get the interrupt parent */
-                       if (of_irq_workarounds & OF_IMAP_NO_PHANDLE)
-                               newpar = of_node_get(of_irq_dflt_pic);
-                       else
-                               newpar =
-                                       of_find_node_by_phandle((phandle)*imap);
-                       imap++;
-                       --imaplen;
-
-                       /* Check if not found */
-                       if (newpar == NULL) {
-                               pr_debug(" -> imap parent not found !\n");
-                               goto fail;
-                       }
-
-                       /* Get #interrupt-cells and #address-cells of new
-                        * parent
-                        */
-                       tmp = of_get_property(newpar, "#interrupt-cells", NULL);
-                       if (tmp == NULL) {
-                               pr_debug(" -> parent lacks "
-                                               "#interrupt-cells!\n");
-                               goto fail;
-                       }
-                       newintsize = *tmp;
-                       tmp = of_get_property(newpar, "#address-cells", NULL);
-                       newaddrsize = (tmp == NULL) ? 0 : *tmp;
-
-                       pr_debug(" -> newintsize=%d, newaddrsize=%d\n",
-                               newintsize, newaddrsize);
-
-                       /* Check for malformed properties */
-                       if (imaplen < (newaddrsize + newintsize))
-                               goto fail;
-
-                       imap += newaddrsize + newintsize;
-                       imaplen -= newaddrsize + newintsize;
-
-                       pr_debug(" -> imaplen=%d\n", imaplen);
-               }
-               if (!match)
-                       goto fail;
-
-               of_node_put(old);
-               old = of_node_get(newpar);
-               addrsize = newaddrsize;
-               intsize = newintsize;
-               intspec = imap - intsize;
-               addr = intspec - addrsize;
-
-skiplevel:
-               /* Iterate again with new parent */
-               pr_debug(" -> new parent: %s\n",
-                               newpar ? newpar->full_name : "<>");
-               of_node_put(ipar);
-               ipar = newpar;
-               newpar = NULL;
-       }
-fail:
-       of_node_put(ipar);
-       of_node_put(old);
-       of_node_put(newpar);
-
-       return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(of_irq_map_raw);
-
-int of_irq_map_one(struct device_node *device,
-                       int index, struct of_irq *out_irq)
-{
-       struct device_node *p;
-       const u32 *intspec, *tmp, *addr;
-       u32 intsize, intlen;
-       int res;
-
-       pr_debug("of_irq_map_one: dev=%s, index=%d\n",
-                       device->full_name, index);
-
-       /* Get the interrupts property */
-       intspec = of_get_property(device, "interrupts", (int *) &intlen);
-       if (intspec == NULL)
-               return -EINVAL;
-       intlen /= sizeof(u32);
-
-       pr_debug(" intspec=%d intlen=%d\n", *intspec, intlen);
-
-       /* Get the reg property (if any) */
-       addr = of_get_property(device, "reg", NULL);
-
-       /* Look for the interrupt parent. */
-       p = of_irq_find_parent(device);
-       if (p == NULL)
-               return -EINVAL;
-
-       /* Get size of interrupt specifier */
-       tmp = of_get_property(p, "#interrupt-cells", NULL);
-       if (tmp == NULL) {
-               of_node_put(p);
-               return -EINVAL;
-       }
-       intsize = *tmp;
-
-       pr_debug(" intsize=%d intlen=%d\n", intsize, intlen);
-
-       /* Check index */
-       if ((index + 1) * intsize > intlen)
-               return -EINVAL;
-
-       /* Get new specifier and map it */
-       res = of_irq_map_raw(p, intspec + index * intsize, intsize,
-                               addr, out_irq);
-       of_node_put(p);
-       return res;
-}
-EXPORT_SYMBOL_GPL(of_irq_map_one);
-
 /**
  * Search the device tree for the best MAC address to use.  'mac-address' is
  * checked first, because that is supposed to contain to "most recent" MAC
@@ -983,43 +148,3 @@ const void *of_get_mac_address(struct device_node *np)
        return NULL;
 }
 EXPORT_SYMBOL(of_get_mac_address);
-
-int of_irq_to_resource(struct device_node *dev, int index, struct resource *r)
-{
-       struct of_irq out_irq;
-       int irq;
-       int res;
-
-       res = of_irq_map_one(dev, index, &out_irq);
-
-       /* Get irq for the device */
-       if (res) {
-               pr_debug("IRQ not found... code = %d", res);
-               return NO_IRQ;
-       }
-       /* Assuming single interrupt controller... */
-       irq = out_irq.specifier[0];
-
-       pr_debug("IRQ found = %d", irq);
-
-       /* Only dereference the resource if both the
-        * resource and the irq are valid. */
-       if (r && irq != NO_IRQ) {
-               r->start = r->end = irq;
-               r->flags = IORESOURCE_IRQ;
-       }
-
-       return irq;
-}
-EXPORT_SYMBOL_GPL(of_irq_to_resource);
-
-void __iomem *of_iomap(struct device_node *np, int index)
-{
-       struct resource res;
-
-       if (of_address_to_resource(np, index, &res))
-               return NULL;
-
-       return ioremap(res.start, 1 + res.end - res.start);
-}
-EXPORT_SYMBOL(of_iomap);
index a1721a3..bd8ccab 100644 (file)
@@ -24,8 +24,8 @@ static int of_reset_gpio_handle(void)
        int ret; /* variable which stored handle reset gpio pin */
        struct device_node *root; /* root node */
        struct device_node *gpio; /* gpio node */
-       struct of_gpio_chip *of_gc = NULL;
-       enum of_gpio_flags flags ;
+       struct gpio_chip *gc;
+       u32 flags;
        const void *gpio_spec;
 
        /* find out root node */
@@ -39,19 +39,19 @@ static int of_reset_gpio_handle(void)
                goto err0;
        }
 
-       of_gc = gpio->data;
-       if (!of_gc) {
+       gc = of_node_to_gpiochip(gpio);
+       if (!gc) {
                pr_debug("%s: gpio controller %s isn't registered\n",
                         root->full_name, gpio->full_name);
                ret = -ENODEV;
                goto err1;
        }
 
-       ret = of_gc->xlate(of_gc, root, gpio_spec, &flags);
+       ret = gc->of_xlate(gc, root, gpio_spec, &flags);
        if (ret < 0)
                goto err1;
 
-       ret += of_gc->gc.base;
+       ret += gc->base;
 err1:
        of_node_put(gpio);
 err0:
index 2031a28..5bf3401 100644 (file)
@@ -120,6 +120,8 @@ config ARCH_NO_VIRT_TO_BUS
 config PPC
        bool
        default y
+       select OF
+       select OF_FLATTREE
        select HAVE_FTRACE_MCOUNT_RECORD
        select HAVE_DYNAMIC_FTRACE
        select HAVE_FUNCTION_TRACER
@@ -172,10 +174,6 @@ config ARCH_MAY_HAVE_PC_FDC
 config PPC_OF
        def_bool y
 
-config OF
-       def_bool y
-       select OF_FLATTREE
-
 config PPC_UDBG_16550
        bool
        default n
@@ -198,10 +196,6 @@ config SYS_SUPPORTS_APM_EMULATION
        default y if PMAC_APM_EMU
        bool
 
-config DTC
-       bool
-       default y
-
 config DEFAULT_UIMAGE
        bool
        help
@@ -578,14 +572,6 @@ config SCHED_SMT
          when dealing with POWER5 cpus at a cost of slightly increased
          overhead in some places. If unsure say N here.
 
-config PROC_DEVICETREE
-       bool "Support for device tree in /proc"
-       depends on PROC_FS
-       help
-         This option adds a device-tree directory under /proc which contains
-         an image of the device tree that the kernel copies from Open
-         Firmware or other boot firmware. If unsure, say Y here.
-
 config CMDLINE_BOOL
        bool "Default bootloader kernel arguments"
 
index ecba37a..67ab5fb 100644 (file)
@@ -300,34 +300,6 @@ extern unsigned int irq_alloc_virt(struct irq_host *host,
  */
 extern void irq_free_virt(unsigned int virq, unsigned int count);
 
-
-/* -- OF helpers -- */
-
-/**
- * irq_create_of_mapping - Map a hardware interrupt into linux virq space
- * @controller: Device node of the interrupt controller
- * @inspec: Interrupt specifier from the device-tree
- * @intsize: Size of the interrupt specifier from the device-tree
- *
- * This function is identical to irq_create_mapping except that it takes
- * as input informations straight from the device-tree (typically the results
- * of the of_irq_map_*() functions.
- */
-extern unsigned int irq_create_of_mapping(struct device_node *controller,
-                                         const u32 *intspec, unsigned int intsize);
-
-/**
- * irq_of_parse_and_map - Parse and Map an interrupt into linux virq space
- * @device: Device node of the device whose interrupt is to be mapped
- * @index: Index of the interrupt to map
- *
- * This function is a wrapper that chains of_irq_map_one() and
- * irq_create_of_mapping() to make things easier to callers
- */
-extern unsigned int irq_of_parse_and_map(struct device_node *dev, int index);
-
-/* -- End OF helpers -- */
-
 /**
  * irq_early_init - Init irq remapping subsystem
  */
index 444e97e..04f7671 100644 (file)
@@ -1,27 +1,3 @@
 #ifndef _ASM_POWERPC_OF_DEVICE_H
 #define _ASM_POWERPC_OF_DEVICE_H
-#ifdef __KERNEL__
-
-#include <linux/device.h>
-#include <linux/of.h>
-
-/*
- * 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           dev;            /* Generic device interface */
-       struct pdev_archdata    archdata;
-};
-
-extern struct of_device *of_device_alloc(struct device_node *np,
-                                        const char *bus_id,
-                                        struct device *parent);
-
-extern int of_device_uevent(struct device *dev,
-                           struct kobj_uevent_env *env);
-
-#endif /* __KERNEL__ */
 #endif /* _ASM_POWERPC_OF_DEVICE_H */
index d4aaa34..d506aa6 100644 (file)
  *
  */
 
-/* Platform devices and busses creation */
-extern struct of_device *of_platform_device_create(struct device_node *np,
-                                                  const char *bus_id,
-                                                  struct device *parent);
-/* pseudo "matches" value to not do deep probe */
-#define OF_NO_DEEP_PROBE ((struct of_device_id *)-1)
-
-extern int of_platform_bus_probe(struct device_node *root,
-                                const struct of_device_id *matches,
-                                struct device *parent);
-
-extern struct of_device *of_find_device_by_phandle(phandle ph);
-
 extern void of_instantiate_rtc(void);
 
 #endif /* _ASM_POWERPC_OF_PLATFORM_H */
index 76e1f31..51e9e6f 100644 (file)
@@ -303,13 +303,8 @@ extern void pcibios_free_controller(struct pci_controller *phb);
 extern void pcibios_setup_phb_resources(struct pci_controller *hose);
 
 #ifdef CONFIG_PCI
-extern unsigned long pci_address_to_pio(phys_addr_t address);
 extern int pcibios_vaddr_is_ioport(void __iomem *address);
 #else
-static inline unsigned long pci_address_to_pio(phys_addr_t address)
-{
-       return (unsigned long)-1;
-}
 static inline int pcibios_vaddr_is_ioport(void __iomem *address)
 {
        return 0;
index ddd408a..f864722 100644 (file)
@@ -18,6 +18,8 @@
  */
 #include <linux/types.h>
 #include <linux/of_fdt.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
 #include <linux/proc_fs.h>
 #include <linux/platform_device.h>
 #include <asm/irq.h>
@@ -43,10 +45,6 @@ extern void pci_create_OF_bus_map(void);
  * OF address retreival & translation
  */
 
-/* Translate an OF address block into a CPU physical address
- */
-extern u64 of_translate_address(struct device_node *np, const u32 *addr);
-
 /* Translate a DMA address from device space to CPU space */
 extern u64 of_translate_dma_address(struct device_node *dev,
                                    const u32 *in_addr);
@@ -68,14 +66,6 @@ static inline const u32 *of_get_pci_address(struct device_node *dev,
 }
 #endif /* CONFIG_PCI */
 
-/* Get an address as a resource. Note that if your address is
- * a PIO address, the conversion will fail if the physical address
- * can't be internally converted to an IO token with
- * pci_address_to_pio(), that is because it's either called to early
- * or it can't be matched to any host bridge IO space
- */
-extern int of_address_to_resource(struct device_node *dev, int index,
-                                 struct resource *r);
 #ifdef CONFIG_PCI
 extern int of_pci_address_to_resource(struct device_node *dev, int bar,
                                      struct resource *r);
@@ -87,6 +77,15 @@ static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
 }
 #endif /* CONFIG_PCI */
 
+#ifdef CONFIG_PCI
+extern unsigned long pci_address_to_pio(phys_addr_t address);
+#else
+static inline unsigned long pci_address_to_pio(phys_addr_t address)
+{
+       return (unsigned long)-1;
+}
+#endif /* CONFIG_PCI */
+
 /* Parse the ibm,dma-window property of an OF node into the busno, phys and
  * size parameters.
  */
@@ -104,70 +103,6 @@ struct device_node *of_find_next_cache_node(struct device_node *np);
 /* Get the MAC address */
 extern const void *of_get_mac_address(struct device_node *np);
 
-/*
- * OF interrupt mapping
- */
-
-/* This structure is returned when an interrupt is mapped. The controller
- * field needs to be put() after use
- */
-
-#define OF_MAX_IRQ_SPEC                 4 /* We handle specifiers of at most 4 cells */
-
-struct of_irq {
-       struct device_node *controller; /* Interrupt controller node */
-       u32 size;                       /* Specifier size */
-       u32 specifier[OF_MAX_IRQ_SPEC]; /* Specifier copy */
-};
-
-/**
- * of_irq_map_init - Initialize the irq remapper
- * @flags:     flags defining workarounds to enable
- *
- * Some machines have bugs in the device-tree which require certain workarounds
- * to be applied. Call this before any interrupt mapping attempts to enable
- * those workarounds.
- */
-#define OF_IMAP_OLDWORLD_MAC   0x00000001
-#define OF_IMAP_NO_PHANDLE     0x00000002
-
-extern void of_irq_map_init(unsigned int flags);
-
-/**
- * of_irq_map_raw - Low level interrupt tree parsing
- * @parent:    the device interrupt parent
- * @intspec:   interrupt specifier ("interrupts" property of the device)
- * @ointsize:   size of the passed in interrupt specifier
- * @addr:      address specifier (start of "reg" property of the device)
- * @out_irq:   structure of_irq filled by this function
- *
- * Returns 0 on success and a negative number on error
- *
- * This function is a low-level interrupt tree walking function. It
- * can be used to do a partial walk with synthetized reg and interrupts
- * properties, for example when resolving PCI interrupts when no device
- * node exist for the parent.
- *
- */
-
-extern int of_irq_map_raw(struct device_node *parent, const u32 *intspec,
-                         u32 ointsize, const u32 *addr,
-                         struct of_irq *out_irq);
-
-
-/**
- * of_irq_map_one - Resolve an interrupt for a device
- * @device:    the device whose interrupt is to be resolved
- * @index:             index of the interrupt to resolve
- * @out_irq:   structure of_irq filled by this function
- *
- * This function resolves an interrupt, walking the tree, for a given
- * device-tree node. It's the high level pendant to of_irq_map_raw().
- * It also implements the workarounds for OldWolrd Macs.
- */
-extern int of_irq_map_one(struct device_node *device, int index,
-                         struct of_irq *out_irq);
-
 /**
  * of_irq_map_pci - Resolve the interrupt for a PCI device
  * @pdev:      the device whose interrupt is to be resolved
@@ -182,17 +117,5 @@ extern int of_irq_map_one(struct device_node *device, int index,
 struct pci_dev;
 extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
 
-extern int of_irq_to_resource(struct device_node *dev, int index,
-                       struct resource *r);
-
-/**
- * of_iomap - Maps the memory mapped IO for a given device_node
- * @device:    the device whose io range will be mapped
- * @index:     index of the io range
- *
- * Returns a pointer to the mapped memory
- */
-extern void __iomem *of_iomap(struct device_node *device, int index);
-
 #endif /* __KERNEL__ */
 #endif /* _POWERPC_PROM_H */
index 7ae2753..e3bdada 100644 (file)
@@ -457,8 +457,8 @@ extern void smu_poll(void);
  */
 extern int smu_init(void);
 extern int smu_present(void);
-struct of_device;
-extern struct of_device *smu_get_ofdev(void);
+struct platform_device;
+extern struct platform_device *smu_get_ofdev(void);
 
 
 /*
index 58d0572..83aa1fd 100644 (file)
@@ -40,7 +40,7 @@ obj-$(CONFIG_PPC_BOOK3E_64)   += exceptions-64e.o
 obj-$(CONFIG_PPC64)            += vdso64/
 obj-$(CONFIG_ALTIVEC)          += vecemu.o
 obj-$(CONFIG_PPC_970_NAP)      += idle_power4.o
-obj-$(CONFIG_PPC_OF)           += of_device.o of_platform.o prom_parse.o
+obj-$(CONFIG_PPC_OF)           += of_platform.o prom_parse.o
 obj-$(CONFIG_PPC_CLOCK)                += clock.o
 procfs-y                       := proc_powerpc.o
 obj-$(CONFIG_PROC_FS)          += $(procfs-y)
index 77be3d0..60d39b7 100644 (file)
@@ -53,6 +53,8 @@
 #include <linux/bootmem.h>
 #include <linux/pci.h>
 #include <linux/debugfs.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -804,18 +806,6 @@ unsigned int irq_create_of_mapping(struct device_node *controller,
 }
 EXPORT_SYMBOL_GPL(irq_create_of_mapping);
 
-unsigned int irq_of_parse_and_map(struct device_node *dev, int index)
-{
-       struct of_irq oirq;
-
-       if (of_irq_map_one(dev, index, &oirq))
-               return NO_IRQ;
-
-       return irq_create_of_mapping(oirq.controller, oirq.specifier,
-                                    oirq.size);
-}
-EXPORT_SYMBOL_GPL(irq_of_parse_and_map);
-
 void irq_dispose_mapping(unsigned int virq)
 {
        struct irq_host *host;
diff --git a/arch/powerpc/kernel/of_device.c b/arch/powerpc/kernel/of_device.c
deleted file mode 100644 (file)
index df78e02..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/of.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/mod_devicetable.h>
-#include <linux/slab.h>
-#include <linux/of_device.h>
-
-#include <asm/errno.h>
-#include <asm/dcr.h>
-
-static void of_device_make_bus_id(struct of_device *dev)
-{
-       static atomic_t bus_no_reg_magic;
-       struct device_node *node = dev->dev.of_node;
-       const u32 *reg;
-       u64 addr;
-       int magic;
-
-       /*
-        * If it's a DCR based device, use 'd' for native DCRs
-        * and 'D' for MMIO DCRs.
-        */
-#ifdef CONFIG_PPC_DCR
-       reg = of_get_property(node, "dcr-reg", NULL);
-       if (reg) {
-#ifdef CONFIG_PPC_DCR_NATIVE
-               dev_set_name(&dev->dev, "d%x.%s", *reg, node->name);
-#else /* CONFIG_PPC_DCR_NATIVE */
-               addr = of_translate_dcr_address(node, *reg, NULL);
-               if (addr != OF_BAD_ADDR) {
-                       dev_set_name(&dev->dev, "D%llx.%s",
-                                    (unsigned long long)addr, node->name);
-                       return;
-               }
-#endif /* !CONFIG_PPC_DCR_NATIVE */
-       }
-#endif /* CONFIG_PPC_DCR */
-
-       /*
-        * For MMIO, get the physical address
-        */
-       reg = of_get_property(node, "reg", NULL);
-       if (reg) {
-               addr = of_translate_address(node, reg);
-               if (addr != OF_BAD_ADDR) {
-                       dev_set_name(&dev->dev, "%llx.%s",
-                                    (unsigned long long)addr, node->name);
-                       return;
-               }
-       }
-
-       /*
-        * No BusID, use the node name and add a globally incremented
-        * counter (and pray...)
-        */
-       magic = atomic_add_return(1, &bus_no_reg_magic);
-       dev_set_name(&dev->dev, "%s.%d", node->name, magic - 1);
-}
-
-struct of_device *of_device_alloc(struct device_node *np,
-                                 const char *bus_id,
-                                 struct device *parent)
-{
-       struct of_device *dev;
-
-       dev = kzalloc(sizeof(*dev), GFP_KERNEL);
-       if (!dev)
-               return NULL;
-
-       dev->dev.of_node = of_node_get(np);
-       dev->dev.dma_mask = &dev->archdata.dma_mask;
-       dev->dev.parent = parent;
-       dev->dev.release = of_release_dev;
-
-       if (bus_id)
-               dev_set_name(&dev->dev, "%s", bus_id);
-       else
-               of_device_make_bus_id(dev);
-
-       return dev;
-}
-EXPORT_SYMBOL(of_device_alloc);
-
-int of_device_uevent(struct device *dev, struct kobj_uevent_env *env)
-{
-       struct of_device *ofdev;
-       const char *compat;
-       int seen = 0, cplen, sl;
-
-       if (!dev)
-               return -ENODEV;
-
-       ofdev = to_of_device(dev);
-
-       if (add_uevent_var(env, "OF_NAME=%s", ofdev->dev.of_node->name))
-               return -ENOMEM;
-
-       if (add_uevent_var(env, "OF_TYPE=%s", ofdev->dev.of_node->type))
-               return -ENOMEM;
-
-        /* Since the compatible field can contain pretty much anything
-         * it's not really legal to split it out with commas. We split it
-         * up using a number of environment variables instead. */
-
-       compat = of_get_property(ofdev->dev.of_node, "compatible", &cplen);
-       while (compat && *compat && cplen > 0) {
-               if (add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat))
-                       return -ENOMEM;
-
-               sl = strlen (compat) + 1;
-               compat += sl;
-               cplen -= sl;
-               seen++;
-       }
-
-       if (add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen))
-               return -ENOMEM;
-
-       /* modalias is trickier, we add it in 2 steps */
-       if (add_uevent_var(env, "MODALIAS="))
-               return -ENOMEM;
-       sl = of_device_get_modalias(ofdev, &env->buf[env->buflen-1],
-                                   sizeof(env->buf) - env->buflen);
-       if (sl >= (sizeof(env->buf) - env->buflen))
-               return -ENOMEM;
-       env->buflen += sl;
-
-       return 0;
-}
-EXPORT_SYMBOL(of_device_uevent);
-EXPORT_SYMBOL(of_device_get_modalias);
index 487a988..4e0a2f7 100644 (file)
@@ -40,7 +40,7 @@
  * a bus type in the list
  */
 
-static const struct of_device_id of_default_bus_ids[] = {
+const struct of_device_id of_default_bus_ids[] = {
        { .type = "soc", },
        { .compatible = "soc", },
        { .type = "spider", },
@@ -64,135 +64,6 @@ static int __init of_bus_driver_init(void)
 
 postcore_initcall(of_bus_driver_init);
 
-struct of_device* of_platform_device_create(struct device_node *np,
-                                           const char *bus_id,
-                                           struct device *parent)
-{
-       struct of_device *dev;
-
-       dev = of_device_alloc(np, bus_id, parent);
-       if (!dev)
-               return NULL;
-
-       dev->archdata.dma_mask = 0xffffffffUL;
-       dev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
-
-       dev->dev.bus = &of_platform_bus_type;
-
-       /* We do not fill the DMA ops for platform devices by default.
-        * This is currently the responsibility of the platform code
-        * to do such, possibly using a device notifier
-        */
-
-       if (of_device_register(dev) != 0) {
-               of_device_free(dev);
-               return NULL;
-       }
-
-       return dev;
-}
-EXPORT_SYMBOL(of_platform_device_create);
-
-
-
-/**
- * of_platform_bus_create - Create an OF device for a bus node and all its
- * children. Optionally recursively instanciate matching busses.
- * @bus: device node of the bus to instanciate
- * @matches: match table, NULL to use the default, OF_NO_DEEP_PROBE to
- * disallow recursive creation of child busses
- */
-static int of_platform_bus_create(const struct device_node *bus,
-                                 const struct of_device_id *matches,
-                                 struct device *parent)
-{
-       struct device_node *child;
-       struct of_device *dev;
-       int rc = 0;
-
-       for_each_child_of_node(bus, child) {
-               pr_debug("   create child: %s\n", child->full_name);
-               dev = of_platform_device_create(child, NULL, parent);
-               if (dev == NULL)
-                       rc = -ENOMEM;
-               else if (!of_match_node(matches, child))
-                       continue;
-               if (rc == 0) {
-                       pr_debug("   and sub busses\n");
-                       rc = of_platform_bus_create(child, matches, &dev->dev);
-               } if (rc) {
-                       of_node_put(child);
-                       break;
-               }
-       }
-       return rc;
-}
-
-/**
- * of_platform_bus_probe - Probe the device-tree for platform busses
- * @root: parent of the first level to probe or NULL for the root of the tree
- * @matches: match table, NULL to use the default
- * @parent: parent to hook devices from, NULL for toplevel
- *
- * Note that children of the provided root are not instanciated as devices
- * unless the specified root itself matches the bus list and is not NULL.
- */
-
-int of_platform_bus_probe(struct device_node *root,
-                         const struct of_device_id *matches,
-                         struct device *parent)
-{
-       struct device_node *child;
-       struct of_device *dev;
-       int rc = 0;
-
-       if (matches == NULL)
-               matches = of_default_bus_ids;
-       if (matches == OF_NO_DEEP_PROBE)
-               return -EINVAL;
-       if (root == NULL)
-               root = of_find_node_by_path("/");
-       else
-               of_node_get(root);
-
-       pr_debug("of_platform_bus_probe()\n");
-       pr_debug(" starting at: %s\n", root->full_name);
-
-       /* Do a self check of bus type, if there's a match, create
-        * children
-        */
-       if (of_match_node(matches, root)) {
-               pr_debug(" root match, create all sub devices\n");
-               dev = of_platform_device_create(root, NULL, parent);
-               if (dev == NULL) {
-                       rc = -ENOMEM;
-                       goto bail;
-               }
-               pr_debug(" create all sub busses\n");
-               rc = of_platform_bus_create(root, matches, &dev->dev);
-               goto bail;
-       }
-       for_each_child_of_node(root, child) {
-               if (!of_match_node(matches, child))
-                       continue;
-
-               pr_debug("  match: %s\n", child->full_name);
-               dev = of_platform_device_create(child, NULL, parent);
-               if (dev == NULL)
-                       rc = -ENOMEM;
-               else
-                       rc = of_platform_bus_create(child, matches, &dev->dev);
-               if (rc) {
-                       of_node_put(child);
-                       break;
-               }
-       }
- bail:
-       of_node_put(root);
-       return rc;
-}
-EXPORT_SYMBOL(of_platform_bus_probe);
-
 static int of_dev_node_match(struct device *dev, void *data)
 {
        return to_of_device(dev)->dev.of_node == data;
@@ -210,25 +81,6 @@ struct of_device *of_find_device_by_node(struct device_node *np)
 }
 EXPORT_SYMBOL(of_find_device_by_node);
 
-static int of_dev_phandle_match(struct device *dev, void *data)
-{
-       phandle *ph = data;
-       return to_of_device(dev)->dev.of_node->phandle == *ph;
-}
-
-struct of_device *of_find_device_by_phandle(phandle ph)
-{
-       struct device *dev;
-
-       dev = bus_find_device(&of_platform_bus_type,
-                             NULL, &ph, of_dev_phandle_match);
-       if (dev)
-               return to_of_device(dev);
-       return NULL;
-}
-EXPORT_SYMBOL(of_find_device_by_phandle);
-
-
 #ifdef CONFIG_PPC_OF_PLATFORM_PCI
 
 /* The probing of PCI controllers from of_platform is currently
index 8362620..88334af 100644 (file)
 #include <linux/module.h>
 #include <linux/ioport.h>
 #include <linux/etherdevice.h>
+#include <linux/of_address.h>
 #include <asm/prom.h>
 #include <asm/pci-bridge.h>
 
-#ifdef DEBUG
-#define DBG(fmt...) do { printk(fmt); } while(0)
-#else
-#define DBG(fmt...) do { } while(0)
-#endif
-
-#ifdef CONFIG_PPC64
-#define PRu64  "%lx"
-#else
-#define PRu64  "%llx"
-#endif
-
-/* Max address size we deal with */
-#define OF_MAX_ADDR_CELLS      4
-#define OF_CHECK_COUNTS(na, ns)        ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS && \
-                       (ns) > 0)
-
-static struct of_bus *of_match_bus(struct device_node *np);
-static int __of_address_to_resource(struct device_node *dev,
-               const u32 *addrp, u64 size, unsigned int flags,
-               struct resource *r);
-
-
-/* Debug utility */
-#ifdef DEBUG
-static void of_dump_addr(const char *s, const u32 *addr, int na)
-{
-       printk("%s", s);
-       while(na--)
-               printk(" %08x", *(addr++));
-       printk("\n");
-}
-#else
-static void of_dump_addr(const char *s, const u32 *addr, int na) { }
-#endif
-
-
-/* Callbacks for bus specific translators */
-struct of_bus {
-       const char      *name;
-       const char      *addresses;
-       int             (*match)(struct device_node *parent);
-       void            (*count_cells)(struct device_node *child,
-                                      int *addrc, int *sizec);
-       u64             (*map)(u32 *addr, const u32 *range,
-                               int na, int ns, int pna);
-       int             (*translate)(u32 *addr, u64 offset, int na);
-       unsigned int    (*get_flags)(const u32 *addr);
-};
-
-
-/*
- * Default translator (generic bus)
- */
-
-static void of_bus_default_count_cells(struct device_node *dev,
-                                      int *addrc, int *sizec)
-{
-       if (addrc)
-               *addrc = of_n_addr_cells(dev);
-       if (sizec)
-               *sizec = of_n_size_cells(dev);
-}
-
-static u64 of_bus_default_map(u32 *addr, const u32 *range,
-               int na, int ns, int pna)
-{
-       u64 cp, s, da;
-
-       cp = of_read_number(range, na);
-       s  = of_read_number(range + na + pna, ns);
-       da = of_read_number(addr, na);
-
-       DBG("OF: default map, cp="PRu64", s="PRu64", da="PRu64"\n",
-           cp, s, da);
-
-       if (da < cp || da >= (cp + s))
-               return OF_BAD_ADDR;
-       return da - cp;
-}
-
-static int of_bus_default_translate(u32 *addr, u64 offset, int na)
-{
-       u64 a = of_read_number(addr, na);
-       memset(addr, 0, na * 4);
-       a += offset;
-       if (na > 1)
-               addr[na - 2] = a >> 32;
-       addr[na - 1] = a & 0xffffffffu;
-
-       return 0;
-}
-
-static unsigned int of_bus_default_get_flags(const u32 *addr)
-{
-       return IORESOURCE_MEM;
-}
-
-
 #ifdef CONFIG_PCI
-/*
- * PCI bus specific translator
- */
-
-static int of_bus_pci_match(struct device_node *np)
-{
-       /* "vci" is for the /chaos bridge on 1st-gen PCI powermacs */
-       return !strcmp(np->type, "pci") || !strcmp(np->type, "vci");
-}
-
-static void of_bus_pci_count_cells(struct device_node *np,
-                                  int *addrc, int *sizec)
-{
-       if (addrc)
-               *addrc = 3;
-       if (sizec)
-               *sizec = 2;
-}
-
-static unsigned int of_bus_pci_get_flags(const u32 *addr)
-{
-       unsigned int flags = 0;
-       u32 w = addr[0];
-
-       switch((w >> 24) & 0x03) {
-       case 0x01:
-               flags |= IORESOURCE_IO;
-               break;
-       case 0x02: /* 32 bits */
-       case 0x03: /* 64 bits */
-               flags |= IORESOURCE_MEM;
-               break;
-       }
-       if (w & 0x40000000)
-               flags |= IORESOURCE_PREFETCH;
-       return flags;
-}
-
-static u64 of_bus_pci_map(u32 *addr, const u32 *range, int na, int ns, int pna)
-{
-       u64 cp, s, da;
-       unsigned int af, rf;
-
-       af = of_bus_pci_get_flags(addr);
-       rf = of_bus_pci_get_flags(range);
-
-       /* Check address type match */
-       if ((af ^ rf) & (IORESOURCE_MEM | IORESOURCE_IO))
-               return OF_BAD_ADDR;
-
-       /* Read address values, skipping high cell */
-       cp = of_read_number(range + 1, na - 1);
-       s  = of_read_number(range + na + pna, ns);
-       da = of_read_number(addr + 1, na - 1);
-
-       DBG("OF: PCI map, cp="PRu64", s="PRu64", da="PRu64"\n", cp, s, da);
-
-       if (da < cp || da >= (cp + s))
-               return OF_BAD_ADDR;
-       return da - cp;
-}
-
-static int of_bus_pci_translate(u32 *addr, u64 offset, int na)
-{
-       return of_bus_default_translate(addr + 1, offset, na - 1);
-}
-
-const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
-                       unsigned int *flags)
-{
-       const u32 *prop;
-       unsigned int psize;
-       struct device_node *parent;
-       struct of_bus *bus;
-       int onesize, i, na, ns;
-
-       /* Get parent & match bus type */
-       parent = of_get_parent(dev);
-       if (parent == NULL)
-               return NULL;
-       bus = of_match_bus(parent);
-       if (strcmp(bus->name, "pci")) {
-               of_node_put(parent);
-               return NULL;
-       }
-       bus->count_cells(dev, &na, &ns);
-       of_node_put(parent);
-       if (!OF_CHECK_COUNTS(na, ns))
-               return NULL;
-
-       /* Get "reg" or "assigned-addresses" property */
-       prop = of_get_property(dev, bus->addresses, &psize);
-       if (prop == NULL)
-               return NULL;
-       psize /= 4;
-
-       onesize = na + ns;
-       for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++)
-               if ((prop[0] & 0xff) == ((bar_no * 4) + PCI_BASE_ADDRESS_0)) {
-                       if (size)
-                               *size = of_read_number(prop + na, ns);
-                       if (flags)
-                               *flags = bus->get_flags(prop);
-                       return prop;
-               }
-       return NULL;
-}
-EXPORT_SYMBOL(of_get_pci_address);
-
-int of_pci_address_to_resource(struct device_node *dev, int bar,
-                              struct resource *r)
-{
-       const u32       *addrp;
-       u64             size;
-       unsigned int    flags;
-
-       addrp = of_get_pci_address(dev, bar, &size, &flags);
-       if (addrp == NULL)
-               return -EINVAL;
-       return __of_address_to_resource(dev, addrp, size, flags, r);
-}
-EXPORT_SYMBOL_GPL(of_pci_address_to_resource);
-
 int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
 {
        struct device_node *dn, *ppnode;
@@ -313,345 +92,6 @@ int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
 EXPORT_SYMBOL_GPL(of_irq_map_pci);
 #endif /* CONFIG_PCI */
 
-/*
- * ISA bus specific translator
- */
-
-static int of_bus_isa_match(struct device_node *np)
-{
-       return !strcmp(np->name, "isa");
-}
-
-static void of_bus_isa_count_cells(struct device_node *child,
-                                  int *addrc, int *sizec)
-{
-       if (addrc)
-               *addrc = 2;
-       if (sizec)
-               *sizec = 1;
-}
-
-static u64 of_bus_isa_map(u32 *addr, const u32 *range, int na, int ns, int pna)
-{
-       u64 cp, s, da;
-
-       /* Check address type match */
-       if ((addr[0] ^ range[0]) & 0x00000001)
-               return OF_BAD_ADDR;
-
-       /* Read address values, skipping high cell */
-       cp = of_read_number(range + 1, na - 1);
-       s  = of_read_number(range + na + pna, ns);
-       da = of_read_number(addr + 1, na - 1);
-
-       DBG("OF: ISA map, cp="PRu64", s="PRu64", da="PRu64"\n", cp, s, da);
-
-       if (da < cp || da >= (cp + s))
-               return OF_BAD_ADDR;
-       return da - cp;
-}
-
-static int of_bus_isa_translate(u32 *addr, u64 offset, int na)
-{
-       return of_bus_default_translate(addr + 1, offset, na - 1);
-}
-
-static unsigned int of_bus_isa_get_flags(const u32 *addr)
-{
-       unsigned int flags = 0;
-       u32 w = addr[0];
-
-       if (w & 1)
-               flags |= IORESOURCE_IO;
-       else
-               flags |= IORESOURCE_MEM;
-       return flags;
-}
-
-
-/*
- * Array of bus specific translators
- */
-
-static struct of_bus of_busses[] = {
-#ifdef CONFIG_PCI
-       /* PCI */
-       {
-               .name = "pci",
-               .addresses = "assigned-addresses",
-               .match = of_bus_pci_match,
-               .count_cells = of_bus_pci_count_cells,
-               .map = of_bus_pci_map,
-               .translate = of_bus_pci_translate,
-               .get_flags = of_bus_pci_get_flags,
-       },
-#endif /* CONFIG_PCI */
-       /* ISA */
-       {
-               .name = "isa",
-               .addresses = "reg",
-               .match = of_bus_isa_match,
-               .count_cells = of_bus_isa_count_cells,
-               .map = of_bus_isa_map,
-               .translate = of_bus_isa_translate,
-               .get_flags = of_bus_isa_get_flags,
-       },
-       /* Default */
-       {
-               .name = "default",
-               .addresses = "reg",
-               .match = NULL,
-               .count_cells = of_bus_default_count_cells,
-               .map = of_bus_default_map,
-               .translate = of_bus_default_translate,
-               .get_flags = of_bus_default_get_flags,
-       },
-};
-
-static struct of_bus *of_match_bus(struct device_node *np)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(of_busses); i ++)
-               if (!of_busses[i].match || of_busses[i].match(np))
-                       return &of_busses[i];
-       BUG();
-       return NULL;
-}
-
-static int of_translate_one(struct device_node *parent, struct of_bus *bus,
-                           struct of_bus *pbus, u32 *addr,
-                           int na, int ns, int pna, const char *rprop)
-{
-       const u32 *ranges;
-       unsigned int rlen;
-       int rone;
-       u64 offset = OF_BAD_ADDR;
-
-       /* Normally, an absence of a "ranges" property means we are
-        * crossing a non-translatable boundary, and thus the addresses
-        * below the current not cannot be converted to CPU physical ones.
-        * Unfortunately, while this is very clear in the spec, it's not
-        * what Apple understood, and they do have things like /uni-n or
-        * /ht nodes with no "ranges" property and a lot of perfectly
-        * useable mapped devices below them. Thus we treat the absence of
-        * "ranges" as equivalent to an empty "ranges" property which means
-        * a 1:1 translation at that level. It's up to the caller not to try
-        * to translate addresses that aren't supposed to be translated in
-        * the first place. --BenH.
-        */
-       ranges = of_get_property(parent, rprop, &rlen);
-       if (ranges == NULL || rlen == 0) {
-               offset = of_read_number(addr, na);
-               memset(addr, 0, pna * 4);
-               DBG("OF: no ranges, 1:1 translation\n");
-               goto finish;
-       }
-
-       DBG("OF: walking ranges...\n");
-
-       /* Now walk through the ranges */
-       rlen /= 4;
-       rone = na + pna + ns;
-       for (; rlen >= rone; rlen -= rone, ranges += rone) {
-               offset = bus->map(addr, ranges, na, ns, pna);
-               if (offset != OF_BAD_ADDR)
-                       break;
-       }
-       if (offset == OF_BAD_ADDR) {
-               DBG("OF: not found !\n");
-               return 1;
-       }
-       memcpy(addr, ranges + na, 4 * pna);
-
- finish:
-       of_dump_addr("OF: parent translation for:", addr, pna);
-       DBG("OF: with offset: "PRu64"\n", offset);
-
-       /* Translate it into parent bus space */
-       return pbus->translate(addr, offset, pna);
-}
-
-
-/*
- * Translate an address from the device-tree into a CPU physical address,
- * this walks up the tree and applies the various bus mappings on the
- * way.
- *
- * Note: We consider that crossing any level with #size-cells == 0 to mean
- * that translation is impossible (that is we are not dealing with a value
- * that can be mapped to a cpu physical address). This is not really specified
- * that way, but this is traditionally the way IBM at least do things
- */
-u64 __of_translate_address(struct device_node *dev, const u32 *in_addr,
-                          const char *rprop)
-{
-       struct device_node *parent = NULL;
-       struct of_bus *bus, *pbus;
-       u32 addr[OF_MAX_ADDR_CELLS];
-       int na, ns, pna, pns;
-       u64 result = OF_BAD_ADDR;
-
-       DBG("OF: ** translation for device %s **\n", dev->full_name);
-
-       /* Increase refcount at current level */
-       of_node_get(dev);
-
-       /* Get parent & match bus type */
-       parent = of_get_parent(dev);
-       if (parent == NULL)
-               goto bail;
-       bus = of_match_bus(parent);
-
-       /* Cound address cells & copy address locally */
-       bus->count_cells(dev, &na, &ns);
-       if (!OF_CHECK_COUNTS(na, ns)) {
-               printk(KERN_ERR "prom_parse: Bad cell count for %s\n",
-                      dev->full_name);
-               goto bail;
-       }
-       memcpy(addr, in_addr, na * 4);
-
-       DBG("OF: bus is %s (na=%d, ns=%d) on %s\n",
-           bus->name, na, ns, parent->full_name);
-       of_dump_addr("OF: translating address:", addr, na);
-
-       /* Translate */
-       for (;;) {
-               /* Switch to parent bus */
-               of_node_put(dev);
-               dev = parent;
-               parent = of_get_parent(dev);
-
-               /* If root, we have finished */
-               if (parent == NULL) {
-                       DBG("OF: reached root node\n");
-                       result = of_read_number(addr, na);
-                       break;
-               }
-
-               /* Get new parent bus and counts */
-               pbus = of_match_bus(parent);
-               pbus->count_cells(dev, &pna, &pns);
-               if (!OF_CHECK_COUNTS(pna, pns)) {
-                       printk(KERN_ERR "prom_parse: Bad cell count for %s\n",
-                              dev->full_name);
-                       break;
-               }
-
-               DBG("OF: parent bus is %s (na=%d, ns=%d) on %s\n",
-                   pbus->name, pna, pns, parent->full_name);
-
-               /* Apply bus translation */
-               if (of_translate_one(dev, bus, pbus, addr, na, ns, pna, rprop))
-                       break;
-
-               /* Complete the move up one level */
-               na = pna;
-               ns = pns;
-               bus = pbus;
-
-               of_dump_addr("OF: one level translation:", addr, na);
-       }
- bail:
-       of_node_put(parent);
-       of_node_put(dev);
-
-       return result;
-}
-
-u64 of_translate_address(struct device_node *dev, const u32 *in_addr)
-{
-       return __of_translate_address(dev, in_addr, "ranges");
-}
-EXPORT_SYMBOL(of_translate_address);
-
-u64 of_translate_dma_address(struct device_node *dev, const u32 *in_addr)
-{
-       return __of_translate_address(dev, in_addr, "dma-ranges");
-}
-EXPORT_SYMBOL(of_translate_dma_address);
-
-const u32 *of_get_address(struct device_node *dev, int index, u64 *size,
-                   unsigned int *flags)
-{
-       const u32 *prop;
-       unsigned int psize;
-       struct device_node *parent;
-       struct of_bus *bus;
-       int onesize, i, na, ns;
-
-       /* Get parent & match bus type */
-       parent = of_get_parent(dev);
-       if (parent == NULL)
-               return NULL;
-       bus = of_match_bus(parent);
-       bus->count_cells(dev, &na, &ns);
-       of_node_put(parent);
-       if (!OF_CHECK_COUNTS(na, ns))
-               return NULL;
-
-       /* Get "reg" or "assigned-addresses" property */
-       prop = of_get_property(dev, bus->addresses, &psize);
-       if (prop == NULL)
-               return NULL;
-       psize /= 4;
-
-       onesize = na + ns;
-       for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++)
-               if (i == index) {
-                       if (size)
-                               *size = of_read_number(prop + na, ns);
-                       if (flags)
-                               *flags = bus->get_flags(prop);
-                       return prop;
-               }
-       return NULL;
-}
-EXPORT_SYMBOL(of_get_address);
-
-static int __of_address_to_resource(struct device_node *dev, const u32 *addrp,
-                                   u64 size, unsigned int flags,
-                                   struct resource *r)
-{
-       u64 taddr;
-
-       if ((flags & (IORESOURCE_IO | IORESOURCE_MEM)) == 0)
-               return -EINVAL;
-       taddr = of_translate_address(dev, addrp);
-       if (taddr == OF_BAD_ADDR)
-               return -EINVAL;
-       memset(r, 0, sizeof(struct resource));
-       if (flags & IORESOURCE_IO) {
-               unsigned long port;
-               port = pci_address_to_pio(taddr);
-               if (port == (unsigned long)-1)
-                       return -EINVAL;
-               r->start = port;
-               r->end = port + size - 1;
-       } else {
-               r->start = taddr;
-               r->end = taddr + size - 1;
-       }
-       r->flags = flags;
-       r->name = dev->name;
-       return 0;
-}
-
-int of_address_to_resource(struct device_node *dev, int index,
-                          struct resource *r)
-{
-       const u32       *addrp;
-       u64             size;
-       unsigned int    flags;
-
-       addrp = of_get_address(dev, index, &size, &flags);
-       if (addrp == NULL)
-               return -EINVAL;
-       return __of_address_to_resource(dev, addrp, size, flags, r);
-}
-EXPORT_SYMBOL_GPL(of_address_to_resource);
-
 void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
                unsigned long *busno, unsigned long *phys, unsigned long *size)
 {
@@ -678,342 +118,6 @@ void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
        *size = of_read_number(dma_window, cells);
 }
 
-/*
- * Interrupt remapper
- */
-
-static unsigned int of_irq_workarounds;
-static struct device_node *of_irq_dflt_pic;
-
-static struct device_node *of_irq_find_parent(struct device_node *child)
-{
-       struct device_node *p;
-       const phandle *parp;
-
-       if (!of_node_get(child))
-               return NULL;
-
-       do {
-               parp = of_get_property(child, "interrupt-parent", NULL);
-               if (parp == NULL)
-                       p = of_get_parent(child);
-               else {
-                       if (of_irq_workarounds & OF_IMAP_NO_PHANDLE)
-                               p = of_node_get(of_irq_dflt_pic);
-                       else
-                               p = of_find_node_by_phandle(*parp);
-               }
-               of_node_put(child);
-               child = p;
-       } while (p && of_get_property(p, "#interrupt-cells", NULL) == NULL);
-
-       return p;
-}
-
-/* This doesn't need to be called if you don't have any special workaround
- * flags to pass
- */
-void of_irq_map_init(unsigned int flags)
-{
-       of_irq_workarounds = flags;
-
-       /* OldWorld, don't bother looking at other things */
-       if (flags & OF_IMAP_OLDWORLD_MAC)
-               return;
-
-       /* If we don't have phandles, let's try to locate a default interrupt
-        * controller (happens when booting with BootX). We do a first match
-        * here, hopefully, that only ever happens on machines with one
-        * controller.
-        */
-       if (flags & OF_IMAP_NO_PHANDLE) {
-               struct device_node *np;
-
-               for_each_node_with_property(np, "interrupt-controller") {
-                       /* Skip /chosen/interrupt-controller */
-                       if (strcmp(np->name, "chosen") == 0)
-                               continue;
-                       /* It seems like at least one person on this planet wants
-                        * to use BootX on a machine with an AppleKiwi controller
-                        * which happens to pretend to be an interrupt
-                        * controller too.
-                        */
-                       if (strcmp(np->name, "AppleKiwi") == 0)
-                               continue;
-                       /* I think we found one ! */
-                       of_irq_dflt_pic = np;
-                       break;
-               }
-       }
-
-}
-
-int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize,
-               const u32 *addr, struct of_irq *out_irq)
-{
-       struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL;
-       const u32 *tmp, *imap, *imask;
-       u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0;
-       int imaplen, match, i;
-
-       DBG("of_irq_map_raw: par=%s,intspec=[0x%08x 0x%08x...],ointsize=%d\n",
-           parent->full_name, intspec[0], intspec[1], ointsize);
-
-       ipar = of_node_get(parent);
-
-       /* First get the #interrupt-cells property of the current cursor
-        * that tells us how to interpret the passed-in intspec. If there
-        * is none, we are nice and just walk up the tree
-        */
-       do {
-               tmp = of_get_property(ipar, "#interrupt-cells", NULL);
-               if (tmp != NULL) {
-                       intsize = *tmp;
-                       break;
-               }
-               tnode = ipar;
-               ipar = of_irq_find_parent(ipar);
-               of_node_put(tnode);
-       } while (ipar);
-       if (ipar == NULL) {
-               DBG(" -> no parent found !\n");
-               goto fail;
-       }
-
-       DBG("of_irq_map_raw: ipar=%s, size=%d\n", ipar->full_name, intsize);
-
-       if (ointsize != intsize)
-               return -EINVAL;
-
-       /* Look for this #address-cells. We have to implement the old linux
-        * trick of looking for the parent here as some device-trees rely on it
-        */
-       old = of_node_get(ipar);
-       do {
-               tmp = of_get_property(old, "#address-cells", NULL);
-               tnode = of_get_parent(old);
-               of_node_put(old);
-               old = tnode;
-       } while(old && tmp == NULL);
-       of_node_put(old);
-       old = NULL;
-       addrsize = (tmp == NULL) ? 2 : *tmp;
-
-       DBG(" -> addrsize=%d\n", addrsize);
-
-       /* Now start the actual "proper" walk of the interrupt tree */
-       while (ipar != NULL) {
-               /* Now check if cursor is an interrupt-controller and if it is
-                * then we are done
-                */
-               if (of_get_property(ipar, "interrupt-controller", NULL) !=
-                               NULL) {
-                       DBG(" -> got it !\n");
-                       memcpy(out_irq->specifier, intspec,
-                              intsize * sizeof(u32));
-                       out_irq->size = intsize;
-                       out_irq->controller = ipar;
-                       of_node_put(old);
-                       return 0;
-               }
-
-               /* Now look for an interrupt-map */
-               imap = of_get_property(ipar, "interrupt-map", &imaplen);
-               /* No interrupt map, check for an interrupt parent */
-               if (imap == NULL) {
-                       DBG(" -> no map, getting parent\n");
-                       newpar = of_irq_find_parent(ipar);
-                       goto skiplevel;
-               }
-               imaplen /= sizeof(u32);
-
-               /* Look for a mask */
-               imask = of_get_property(ipar, "interrupt-map-mask", NULL);
-
-               /* If we were passed no "reg" property and we attempt to parse
-                * an interrupt-map, then #address-cells must be 0.
-                * Fail if it's not.
-                */
-               if (addr == NULL && addrsize != 0) {
-                       DBG(" -> no reg passed in when needed !\n");
-                       goto fail;
-               }
-
-               /* Parse interrupt-map */
-               match = 0;
-               while (imaplen > (addrsize + intsize + 1) && !match) {
-                       /* Compare specifiers */
-                       match = 1;
-                       for (i = 0; i < addrsize && match; ++i) {
-                               u32 mask = imask ? imask[i] : 0xffffffffu;
-                               match = ((addr[i] ^ imap[i]) & mask) == 0;
-                       }
-                       for (; i < (addrsize + intsize) && match; ++i) {
-                               u32 mask = imask ? imask[i] : 0xffffffffu;
-                               match =
-                                  ((intspec[i-addrsize] ^ imap[i]) & mask) == 0;
-                       }
-                       imap += addrsize + intsize;
-                       imaplen -= addrsize + intsize;
-
-                       DBG(" -> match=%d (imaplen=%d)\n", match, imaplen);
-
-                       /* Get the interrupt parent */
-                       if (of_irq_workarounds & OF_IMAP_NO_PHANDLE)
-                               newpar = of_node_get(of_irq_dflt_pic);
-                       else
-                               newpar = of_find_node_by_phandle((phandle)*imap);
-                       imap++;
-                       --imaplen;
-
-                       /* Check if not found */
-                       if (newpar == NULL) {
-                               DBG(" -> imap parent not found !\n");
-                               goto fail;
-                       }
-
-                       /* Get #interrupt-cells and #address-cells of new
-                        * parent
-                        */
-                       tmp = of_get_property(newpar, "#interrupt-cells", NULL);
-                       if (tmp == NULL) {
-                               DBG(" -> parent lacks #interrupt-cells !\n");
-                               goto fail;
-                       }
-                       newintsize = *tmp;
-                       tmp = of_get_property(newpar, "#address-cells", NULL);
-                       newaddrsize = (tmp == NULL) ? 0 : *tmp;
-
-                       DBG(" -> newintsize=%d, newaddrsize=%d\n",
-                           newintsize, newaddrsize);
-
-                       /* Check for malformed properties */
-                       if (imaplen < (newaddrsize + newintsize))
-                               goto fail;
-
-                       imap += newaddrsize + newintsize;
-                       imaplen -= newaddrsize + newintsize;
-
-                       DBG(" -> imaplen=%d\n", imaplen);
-               }
-               if (!match)
-                       goto fail;
-
-               of_node_put(old);
-               old = of_node_get(newpar);
-               addrsize = newaddrsize;
-               intsize = newintsize;
-               intspec = imap - intsize;
-               addr = intspec - addrsize;
-
-       skiplevel:
-               /* Iterate again with new parent */
-               DBG(" -> new parent: %s\n", newpar ? newpar->full_name : "<>");
-               of_node_put(ipar);
-               ipar = newpar;
-               newpar = NULL;
-       }
- fail:
-       of_node_put(ipar);
-       of_node_put(old);
-       of_node_put(newpar);
-
-       return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(of_irq_map_raw);
-
-#if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32)
-static int of_irq_map_oldworld(struct device_node *device, int index,
-                              struct of_irq *out_irq)
-{
-       const u32 *ints = NULL;
-       int intlen;
-
-       /*
-        * Old machines just have a list of interrupt numbers
-        * and no interrupt-controller nodes. We also have dodgy
-        * cases where the APPL,interrupts property is completely
-        * missing behind pci-pci bridges and we have to get it
-        * from the parent (the bridge itself, as apple just wired
-        * everything together on these)
-        */
-       while (device) {
-               ints = of_get_property(device, "AAPL,interrupts", &intlen);
-               if (ints != NULL)
-                       break;
-               device = device->parent;
-               if (device && strcmp(device->type, "pci") != 0)
-                       break;
-       }
-       if (ints == NULL)
-               return -EINVAL;
-       intlen /= sizeof(u32);
-
-       if (index >= intlen)
-               return -EINVAL;
-
-       out_irq->controller = NULL;
-       out_irq->specifier[0] = ints[index];
-       out_irq->size = 1;
-
-       return 0;
-}
-#else /* defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32) */
-static int of_irq_map_oldworld(struct device_node *device, int index,
-                              struct of_irq *out_irq)
-{
-       return -EINVAL;
-}
-#endif /* !(defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32)) */
-
-int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq)
-{
-       struct device_node *p;
-       const u32 *intspec, *tmp, *addr;
-       u32 intsize, intlen;
-       int res = -EINVAL;
-
-       DBG("of_irq_map_one: dev=%s, index=%d\n", device->full_name, index);
-
-       /* OldWorld mac stuff is "special", handle out of line */
-       if (of_irq_workarounds & OF_IMAP_OLDWORLD_MAC)
-               return of_irq_map_oldworld(device, index, out_irq);
-
-       /* Get the interrupts property */
-       intspec = of_get_property(device, "interrupts", &intlen);
-       if (intspec == NULL)
-               return -EINVAL;
-       intlen /= sizeof(u32);
-
-       /* Get the reg property (if any) */
-       addr = of_get_property(device, "reg", NULL);
-
-       /* Look for the interrupt parent. */
-       p = of_irq_find_parent(device);
-       if (p == NULL)
-               return -EINVAL;
-
-       /* Get size of interrupt specifier */
-       tmp = of_get_property(p, "#interrupt-cells", NULL);
-       if (tmp == NULL)
-               goto out;
-       intsize = *tmp;
-
-       DBG(" intsize=%d intlen=%d\n", intsize, intlen);
-
-       /* Check index */
-       if ((index + 1) * intsize > intlen)
-               goto out;
-
-       /* Get new specifier and map it */
-       res = of_irq_map_raw(p, intspec + index * intsize, intsize,
-                            addr, out_irq);
-out:
-       of_node_put(p);
-       return res;
-}
-EXPORT_SYMBOL_GPL(of_irq_map_one);
-
 /**
  * Search the device tree for the best MAC address to use.  'mac-address' is
  * checked first, because that is supposed to contain to "most recent" MAC
@@ -1051,29 +155,3 @@ const void *of_get_mac_address(struct device_node *np)
        return NULL;
 }
 EXPORT_SYMBOL(of_get_mac_address);
-
-int of_irq_to_resource(struct device_node *dev, int index, struct resource *r)
-{
-       int irq = irq_of_parse_and_map(dev, index);
-
-       /* Only dereference the resource if both the
-        * resource and the irq are valid. */
-       if (r && irq != NO_IRQ) {
-               r->start = r->end = irq;
-               r->flags = IORESOURCE_IRQ;
-       }
-
-       return irq;
-}
-EXPORT_SYMBOL_GPL(of_irq_to_resource);
-
-void __iomem *of_iomap(struct device_node *np, int index)
-{
-       struct resource res;
-
-       if (of_address_to_resource(np, index, &res))
-               return NULL;
-
-       return ioremap(res.start, 1 + res.end - res.start);
-}
-EXPORT_SYMBOL(of_iomap);
index ca5305a..0855e80 100644 (file)
@@ -152,21 +152,20 @@ static int __devinit mpc52xx_wkup_gpiochip_probe(struct of_device *ofdev,
 {
        struct mpc52xx_gpiochip *chip;
        struct mpc52xx_gpio_wkup __iomem *regs;
-       struct of_gpio_chip *ofchip;
+       struct gpio_chip *gc;
        int ret;
 
        chip = kzalloc(sizeof(*chip), GFP_KERNEL);
        if (!chip)
                return -ENOMEM;
 
-       ofchip = &chip->mmchip.of_gc;
+       gc = &chip->mmchip.gc;
 
-       ofchip->gpio_cells          = 2;
-       ofchip->gc.ngpio            = 8;
-       ofchip->gc.direction_input  = mpc52xx_wkup_gpio_dir_in;
-       ofchip->gc.direction_output = mpc52xx_wkup_gpio_dir_out;
-       ofchip->gc.get              = mpc52xx_wkup_gpio_get;
-       ofchip->gc.set              = mpc52xx_wkup_gpio_set;
+       gc->ngpio            = 8;
+       gc->direction_input  = mpc52xx_wkup_gpio_dir_in;
+       gc->direction_output = mpc52xx_wkup_gpio_dir_out;
+       gc->get              = mpc52xx_wkup_gpio_get;
+       gc->set              = mpc52xx_wkup_gpio_set;
 
        ret = of_mm_gpiochip_add(ofdev->dev.of_node, &chip->mmchip);
        if (ret)
@@ -315,7 +314,7 @@ static int __devinit mpc52xx_simple_gpiochip_probe(struct of_device *ofdev,
                                        const struct of_device_id *match)
 {
        struct mpc52xx_gpiochip *chip;
-       struct of_gpio_chip *ofchip;
+       struct gpio_chip *gc;
        struct mpc52xx_gpio __iomem *regs;
        int ret;
 
@@ -323,14 +322,13 @@ static int __devinit mpc52xx_simple_gpiochip_probe(struct of_device *ofdev,
        if (!chip)
                return -ENOMEM;
 
-       ofchip = &chip->mmchip.of_gc;
+       gc = &chip->mmchip.gc;
 
-       ofchip->gpio_cells          = 2;
-       ofchip->gc.ngpio            = 32;
-       ofchip->gc.direction_input  = mpc52xx_simple_gpio_dir_in;
-       ofchip->gc.direction_output = mpc52xx_simple_gpio_dir_out;
-       ofchip->gc.get              = mpc52xx_simple_gpio_get;
-       ofchip->gc.set              = mpc52xx_simple_gpio_set;
+       gc->ngpio            = 32;
+       gc->direction_input  = mpc52xx_simple_gpio_dir_in;
+       gc->direction_output = mpc52xx_simple_gpio_dir_out;
+       gc->get              = mpc52xx_simple_gpio_get;
+       gc->set              = mpc52xx_simple_gpio_set;
 
        ret = of_mm_gpiochip_add(ofdev->dev.of_node, &chip->mmchip);
        if (ret)
index 46c9357..5d7d607 100644 (file)
@@ -78,7 +78,7 @@ MODULE_LICENSE("GPL");
  * @dev: pointer to device structure
  * @regs: virtual address of GPT registers
  * @lock: spinlock to coordinate between different functions.
- * @of_gc: of_gpio_chip instance structure; used when GPIO is enabled
+ * @gc: gpio_chip instance structure; used when GPIO is enabled
  * @irqhost: Pointer to irq_host instance; used when IRQ mode is supported
  * @wdt_mode: only relevant for gpt0: bit 0 (MPC52xx_GPT_CAN_WDT) indicates
  *   if the gpt may be used as wdt, bit 1 (MPC52xx_GPT_IS_WDT) indicates
@@ -94,7 +94,7 @@ struct mpc52xx_gpt_priv {
        u8 wdt_mode;
 
 #if defined(CONFIG_GPIOLIB)
-       struct of_gpio_chip of_gc;
+       struct gpio_chip gc;
 #endif
 };
 
@@ -280,7 +280,7 @@ mpc52xx_gpt_irq_setup(struct mpc52xx_gpt_priv *gpt, struct device_node *node)
 #if defined(CONFIG_GPIOLIB)
 static inline struct mpc52xx_gpt_priv *gc_to_mpc52xx_gpt(struct gpio_chip *gc)
 {
-       return container_of(to_of_gpio_chip(gc), struct mpc52xx_gpt_priv,of_gc);
+       return container_of(gc, struct mpc52xx_gpt_priv, gc);
 }
 
 static int mpc52xx_gpt_gpio_get(struct gpio_chip *gc, unsigned int gpio)
@@ -336,28 +336,25 @@ mpc52xx_gpt_gpio_setup(struct mpc52xx_gpt_priv *gpt, struct device_node *node)
        if (!of_find_property(node, "gpio-controller", NULL))
                return;
 
-       gpt->of_gc.gc.label = kstrdup(node->full_name, GFP_KERNEL);
-       if (!gpt->of_gc.gc.label) {
+       gpt->gc.label = kstrdup(node->full_name, GFP_KERNEL);
+       if (!gpt->gc.label) {
                dev_err(gpt->dev, "out of memory\n");
                return;
        }
 
-       gpt->of_gc.gpio_cells = 2;
-       gpt->of_gc.gc.ngpio = 1;
-       gpt->of_gc.gc.direction_input  = mpc52xx_gpt_gpio_dir_in;
-       gpt->of_gc.gc.direction_output = mpc52xx_gpt_gpio_dir_out;
-       gpt->of_gc.gc.get = mpc52xx_gpt_gpio_get;
-       gpt->of_gc.gc.set = mpc52xx_gpt_gpio_set;
-       gpt->of_gc.gc.base = -1;
-       gpt->of_gc.xlate = of_gpio_simple_xlate;
-       node->data = &gpt->of_gc;
-       of_node_get(node);
+       gpt->gc.ngpio = 1;
+       gpt->gc.direction_input  = mpc52xx_gpt_gpio_dir_in;
+       gpt->gc.direction_output = mpc52xx_gpt_gpio_dir_out;
+       gpt->gc.get = mpc52xx_gpt_gpio_get;
+       gpt->gc.set = mpc52xx_gpt_gpio_set;
+       gpt->gc.base = -1;
+       gpt->gc.of_node = node;
 
        /* Setup external pin in GPIO mode */
        clrsetbits_be32(&gpt->regs->mode, MPC52xx_GPT_MODE_MS_MASK,
                        MPC52xx_GPT_MODE_MS_GPIO);
 
-       rc = gpiochip_add(&gpt->of_gc.gc);
+       rc = gpiochip_add(&gpt->gc);
        if (rc)
                dev_err(gpt->dev, "gpiochip_add() failed; rc=%i\n", rc);
 
index d119a7c..70798ac 100644 (file)
@@ -35,9 +35,8 @@
 
 struct mcu {
        struct mutex lock;
-       struct device_node *np;
        struct i2c_client *client;
-       struct of_gpio_chip of_gc;
+       struct gpio_chip gc;
        u8 reg_ctrl;
 };
 
@@ -56,8 +55,7 @@ static void mcu_power_off(void)
 
 static void mcu_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
 {
-       struct of_gpio_chip *of_gc = to_of_gpio_chip(gc);
-       struct mcu *mcu = container_of(of_gc, struct mcu, of_gc);
+       struct mcu *mcu = container_of(gc, struct mcu, gc);
        u8 bit = 1 << (4 + gpio);
 
        mutex_lock(&mcu->lock);
@@ -79,9 +77,7 @@ static int mcu_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
 static int mcu_gpiochip_add(struct mcu *mcu)
 {
        struct device_node *np;
-       struct of_gpio_chip *of_gc = &mcu->of_gc;
-       struct gpio_chip *gc = &of_gc->gc;
-       int ret;
+       struct gpio_chip *gc = &mcu->gc;
 
        np = of_find_compatible_node(NULL, NULL, "fsl,mcu-mpc8349emitx");
        if (!np)
@@ -94,32 +90,14 @@ static int mcu_gpiochip_add(struct mcu *mcu)
        gc->base = -1;
        gc->set = mcu_gpio_set;
        gc->direction_output = mcu_gpio_dir_out;
-       of_gc->gpio_cells = 2;
-       of_gc->xlate = of_gpio_simple_xlate;
+       gc->of_node = np;
 
-       np->data = of_gc;
-       mcu->np = np;
-
-       /*
-        * We don't want to lose the node, its ->data and ->full_name...
-        * So, if succeeded, we don't put the node here.
-        */
-       ret = gpiochip_add(gc);
-       if (ret)
-               of_node_put(np);
-       return ret;
+       return gpiochip_add(gc);
 }
 
 static int mcu_gpiochip_remove(struct mcu *mcu)
 {
-       int ret;
-
-       ret = gpiochip_remove(&mcu->of_gc.gc);
-       if (ret)
-               return ret;
-       of_node_put(mcu->np);
-
-       return 0;
+       return gpiochip_remove(&mcu->gc);
 }
 
 static int __devinit mcu_probe(struct i2c_client *client,
@@ -182,10 +160,16 @@ static const struct i2c_device_id mcu_ids[] = {
 };
 MODULE_DEVICE_TABLE(i2c, mcu_ids);
 
+static struct of_device_id mcu_of_match_table[] __devinitdata = {
+       { .compatible = "fsl,mcu-mpc8349emitx", },
+       { },
+};
+
 static struct i2c_driver mcu_driver = {
        .driver = {
                .name = "mcu-mpc8349emitx",
                .owner = THIS_MODULE,
+               .of_match_table = mcu_of_match_table,
        },
        .probe = mcu_probe,
        .remove = __devexit_p(mcu_remove),
index b8cb08d..4ff7b1e 100644 (file)
@@ -118,12 +118,12 @@ static int __init gef_gpio_init(void)
                }
 
                /* Setup pointers to chip functions */
-               gef_gpio_chip->of_gc.gpio_cells = 2;
-               gef_gpio_chip->of_gc.gc.ngpio = 19;
-               gef_gpio_chip->of_gc.gc.direction_input = gef_gpio_dir_in;
-               gef_gpio_chip->of_gc.gc.direction_output = gef_gpio_dir_out;
-               gef_gpio_chip->of_gc.gc.get = gef_gpio_get;
-               gef_gpio_chip->of_gc.gc.set = gef_gpio_set;
+               gef_gpio_chip->gc.of_gpio_n_cells = 2;
+               gef_gpio_chip->gc.ngpio = 19;
+               gef_gpio_chip->gc.direction_input = gef_gpio_dir_in;
+               gef_gpio_chip->gc.direction_output = gef_gpio_dir_out;
+               gef_gpio_chip->gc.get = gef_gpio_get;
+               gef_gpio_chip->gc.set = gef_gpio_set;
 
                /* This function adds a memory mapped GPIO chip */
                retval = of_mm_gpiochip_add(np, gef_gpio_chip);
@@ -146,12 +146,12 @@ static int __init gef_gpio_init(void)
                }
 
                /* Setup pointers to chip functions */
-               gef_gpio_chip->of_gc.gpio_cells = 2;
-               gef_gpio_chip->of_gc.gc.ngpio = 6;
-               gef_gpio_chip->of_gc.gc.direction_input = gef_gpio_dir_in;
-               gef_gpio_chip->of_gc.gc.direction_output = gef_gpio_dir_out;
-               gef_gpio_chip->of_gc.gc.get = gef_gpio_get;
-               gef_gpio_chip->of_gc.gc.set = gef_gpio_set;
+               gef_gpio_chip->gc.of_gpio_n_cells = 2;
+               gef_gpio_chip->gc.ngpio = 6;
+               gef_gpio_chip->gc.direction_input = gef_gpio_dir_in;
+               gef_gpio_chip->gc.direction_output = gef_gpio_dir_out;
+               gef_gpio_chip->gc.get = gef_gpio_get;
+               gef_gpio_chip->gc.set = gef_gpio_set;
 
                /* This function adds a memory mapped GPIO chip */
                retval = of_mm_gpiochip_add(np, gef_gpio_chip);
index 630a533..890d5f7 100644 (file)
@@ -46,6 +46,10 @@ struct pmac_irq_hw {
         unsigned int    level;
 };
 
+/* Workaround flags for 32bit powermac machines */
+unsigned int of_irq_workarounds;
+struct device_node *of_irq_dflt_pic;
+
 /* Default addresses */
 static volatile struct pmac_irq_hw __iomem *pmac_irq_hw[4];
 
@@ -428,6 +432,42 @@ static void __init pmac_pic_probe_oldstyle(void)
        setup_irq(irq_create_mapping(NULL, 20), &xmon_action);
 #endif
 }
+
+int of_irq_map_oldworld(struct device_node *device, int index,
+                       struct of_irq *out_irq)
+{
+       const u32 *ints = NULL;
+       int intlen;
+
+       /*
+        * Old machines just have a list of interrupt numbers
+        * and no interrupt-controller nodes. We also have dodgy
+        * cases where the APPL,interrupts property is completely
+        * missing behind pci-pci bridges and we have to get it
+        * from the parent (the bridge itself, as apple just wired
+        * everything together on these)
+        */
+       while (device) {
+               ints = of_get_property(device, "AAPL,interrupts", &intlen);
+               if (ints != NULL)
+                       break;
+               device = device->parent;
+               if (device && strcmp(device->type, "pci") != 0)
+                       break;
+       }
+       if (ints == NULL)
+               return -EINVAL;
+       intlen /= sizeof(u32);
+
+       if (index >= intlen)
+               return -EINVAL;
+
+       out_irq->controller = NULL;
+       out_irq->specifier[0] = ints[index];
+       out_irq->size = 1;
+
+       return 0;
+}
 #endif /* CONFIG_PPC32 */
 
 static void pmac_u3_cascade(unsigned int irq, struct irq_desc *desc)
@@ -559,19 +599,39 @@ static int __init pmac_pic_probe_mpic(void)
 
 void __init pmac_pic_init(void)
 {
-       unsigned int flags = 0;
-
        /* We configure the OF parsing based on our oldworld vs. newworld
         * platform type and wether we were booted by BootX.
         */
 #ifdef CONFIG_PPC32
        if (!pmac_newworld)
-               flags |= OF_IMAP_OLDWORLD_MAC;
+               of_irq_workarounds |= OF_IMAP_OLDWORLD_MAC;
        if (of_get_property(of_chosen, "linux,bootx", NULL) != NULL)
-               flags |= OF_IMAP_NO_PHANDLE;
-#endif /* CONFIG_PPC_32 */
+               of_irq_workarounds |= OF_IMAP_NO_PHANDLE;
 
-       of_irq_map_init(flags);
+       /* If we don't have phandles on a newworld, then try to locate a
+        * default interrupt controller (happens when booting with BootX).
+        * We do a first match here, hopefully, that only ever happens on
+        * machines with one controller.
+        */
+       if (pmac_newworld && (of_irq_workarounds & OF_IMAP_NO_PHANDLE)) {
+               struct device_node *np;
+
+               for_each_node_with_property(np, "interrupt-controller") {
+                       /* Skip /chosen/interrupt-controller */
+                       if (strcmp(np->name, "chosen") == 0)
+                               continue;
+                       /* It seems like at least one person wants
+                        * to use BootX on a machine with an AppleKiwi
+                        * controller which happens to pretend to be an
+                        * interrupt controller too. */
+                       if (strcmp(np->name, "AppleKiwi") == 0)
+                               continue;
+                       /* I think we found one ! */
+                       of_irq_dflt_pic = np;
+                       break;
+               }
+       }
+#endif /* CONFIG_PPC32 */
 
        /* We first try to detect Apple's new Core99 chipset, since mac-io
         * is quite different on those machines and contains an IBM MPIC2.
index 8d103ca..0085212 100644 (file)
@@ -621,7 +621,6 @@ int cpm1_gpiochip_add16(struct device_node *np)
 {
        struct cpm1_gpio16_chip *cpm1_gc;
        struct of_mm_gpio_chip *mm_gc;
-       struct of_gpio_chip *of_gc;
        struct gpio_chip *gc;
 
        cpm1_gc = kzalloc(sizeof(*cpm1_gc), GFP_KERNEL);
@@ -631,11 +630,9 @@ int cpm1_gpiochip_add16(struct device_node *np)
        spin_lock_init(&cpm1_gc->lock);
 
        mm_gc = &cpm1_gc->mm_gc;
-       of_gc = &mm_gc->of_gc;
-       gc = &of_gc->gc;
+       gc = &mm_gc->gc;
 
        mm_gc->save_regs = cpm1_gpio16_save_regs;
-       of_gc->gpio_cells = 2;
        gc->ngpio = 16;
        gc->direction_input = cpm1_gpio16_dir_in;
        gc->direction_output = cpm1_gpio16_dir_out;
@@ -745,7 +742,6 @@ int cpm1_gpiochip_add32(struct device_node *np)
 {
        struct cpm1_gpio32_chip *cpm1_gc;
        struct of_mm_gpio_chip *mm_gc;
-       struct of_gpio_chip *of_gc;
        struct gpio_chip *gc;
 
        cpm1_gc = kzalloc(sizeof(*cpm1_gc), GFP_KERNEL);
@@ -755,11 +751,9 @@ int cpm1_gpiochip_add32(struct device_node *np)
        spin_lock_init(&cpm1_gc->lock);
 
        mm_gc = &cpm1_gc->mm_gc;
-       of_gc = &mm_gc->of_gc;
-       gc = &of_gc->gc;
+       gc = &mm_gc->gc;
 
        mm_gc->save_regs = cpm1_gpio32_save_regs;
-       of_gc->gpio_cells = 2;
        gc->ngpio = 32;
        gc->direction_input = cpm1_gpio32_dir_in;
        gc->direction_output = cpm1_gpio32_dir_out;
index 88b9812..2b69aa0 100644 (file)
@@ -325,7 +325,6 @@ int cpm2_gpiochip_add32(struct device_node *np)
 {
        struct cpm2_gpio32_chip *cpm2_gc;
        struct of_mm_gpio_chip *mm_gc;
-       struct of_gpio_chip *of_gc;
        struct gpio_chip *gc;
 
        cpm2_gc = kzalloc(sizeof(*cpm2_gc), GFP_KERNEL);
@@ -335,11 +334,9 @@ int cpm2_gpiochip_add32(struct device_node *np)
        spin_lock_init(&cpm2_gc->lock);
 
        mm_gc = &cpm2_gc->mm_gc;
-       of_gc = &mm_gc->of_gc;
-       gc = &of_gc->gc;
+       gc = &mm_gc->gc;
 
        mm_gc->save_regs = cpm2_gpio32_save_regs;
-       of_gc->gpio_cells = 2;
        gc->ngpio = 32;
        gc->direction_input = cpm2_gpio32_dir_in;
        gc->direction_output = cpm2_gpio32_dir_out;
index 83f5196..2b69084 100644 (file)
@@ -257,7 +257,6 @@ static void __init mpc8xxx_add_controller(struct device_node *np)
 {
        struct mpc8xxx_gpio_chip *mpc8xxx_gc;
        struct of_mm_gpio_chip *mm_gc;
-       struct of_gpio_chip *of_gc;
        struct gpio_chip *gc;
        unsigned hwirq;
        int ret;
@@ -271,11 +270,9 @@ static void __init mpc8xxx_add_controller(struct device_node *np)
        spin_lock_init(&mpc8xxx_gc->lock);
 
        mm_gc = &mpc8xxx_gc->mm_gc;
-       of_gc = &mm_gc->of_gc;
-       gc = &of_gc->gc;
+       gc = &mm_gc->gc;
 
        mm_gc->save_regs = mpc8xxx_gpio_save_regs;
-       of_gc->gpio_cells = 2;
        gc->ngpio = MPC8XXX_GPIO_PINS;
        gc->direction_input = mpc8xxx_gpio_dir_in;
        gc->direction_output = mpc8xxx_gpio_dir_out;
index 3812fc3..fc65ad1 100644 (file)
@@ -181,7 +181,6 @@ static int __init ppc4xx_add_gpiochips(void)
                int ret;
                struct ppc4xx_gpio_chip *ppc4xx_gc;
                struct of_mm_gpio_chip *mm_gc;
-               struct of_gpio_chip *of_gc;
                struct gpio_chip *gc;
 
                ppc4xx_gc = kzalloc(sizeof(*ppc4xx_gc), GFP_KERNEL);
@@ -193,10 +192,8 @@ static int __init ppc4xx_add_gpiochips(void)
                spin_lock_init(&ppc4xx_gc->lock);
 
                mm_gc = &ppc4xx_gc->mm_gc;
-               of_gc = &mm_gc->of_gc;
-               gc = &of_gc->gc;
+               gc = &mm_gc->gc;
 
-               of_gc->gpio_cells = 2;
                gc->ngpio = 32;
                gc->direction_input = ppc4xx_gpio_dir_in;
                gc->direction_output = ppc4xx_gpio_dir_out;
index dc8f8d6..36bf845 100644 (file)
@@ -138,8 +138,8 @@ struct qe_pin {
 struct qe_pin *qe_pin_request(struct device_node *np, int index)
 {
        struct qe_pin *qe_pin;
-       struct device_node *gc;
-       struct of_gpio_chip *of_gc = NULL;
+       struct device_node *gpio_np;
+       struct gpio_chip *gc;
        struct of_mm_gpio_chip *mm_gc;
        struct qe_gpio_chip *qe_gc;
        int err;
@@ -155,40 +155,40 @@ struct qe_pin *qe_pin_request(struct device_node *np, int index)
        }
 
        err = of_parse_phandles_with_args(np, "gpios", "#gpio-cells", index,
-                                         &gc, &gpio_spec);
+                                         &gpio_np, &gpio_spec);
        if (err) {
                pr_debug("%s: can't parse gpios property\n", __func__);
                goto err0;
        }
 
-       if (!of_device_is_compatible(gc, "fsl,mpc8323-qe-pario-bank")) {
+       if (!of_device_is_compatible(gpio_np, "fsl,mpc8323-qe-pario-bank")) {
                pr_debug("%s: tried to get a non-qe pin\n", __func__);
                err = -EINVAL;
                goto err1;
        }
 
-       of_gc = gc->data;
-       if (!of_gc) {
+       gc = of_node_to_gpiochip(gpio_np);
+       if (!gc) {
                pr_debug("%s: gpio controller %s isn't registered\n",
-                        np->full_name, gc->full_name);
+                        np->full_name, gpio_np->full_name);
                err = -ENODEV;
                goto err1;
        }
 
-       gpio_cells = of_get_property(gc, "#gpio-cells", &size);
+       gpio_cells = of_get_property(gpio_np, "#gpio-cells", &size);
        if (!gpio_cells || size != sizeof(*gpio_cells) ||
-                       *gpio_cells != of_gc->gpio_cells) {
+                       *gpio_cells != gc->of_gpio_n_cells) {
                pr_debug("%s: wrong #gpio-cells for %s\n",
-                        np->full_name, gc->full_name);
+                        np->full_name, gpio_np->full_name);
                err = -EINVAL;
                goto err1;
        }
 
-       err = of_gc->xlate(of_gc, np, gpio_spec, NULL);
+       err = gc->of_xlate(gc, np, gpio_spec, NULL);
        if (err < 0)
                goto err1;
 
-       mm_gc = to_of_mm_gpio_chip(&of_gc->gc);
+       mm_gc = to_of_mm_gpio_chip(gc);
        qe_gc = to_qe_gpio_chip(mm_gc);
 
        spin_lock_irqsave(&qe_gc->lock, flags);
@@ -206,7 +206,7 @@ struct qe_pin *qe_pin_request(struct device_node *np, int index)
        if (!err)
                return qe_pin;
 err1:
-       of_node_put(gc);
+       of_node_put(gpio_np);
 err0:
        kfree(qe_pin);
        pr_debug("%s failed with status %d\n", __func__, err);
@@ -307,7 +307,6 @@ static int __init qe_add_gpiochips(void)
                int ret;
                struct qe_gpio_chip *qe_gc;
                struct of_mm_gpio_chip *mm_gc;
-               struct of_gpio_chip *of_gc;
                struct gpio_chip *gc;
 
                qe_gc = kzalloc(sizeof(*qe_gc), GFP_KERNEL);
@@ -319,11 +318,9 @@ static int __init qe_add_gpiochips(void)
                spin_lock_init(&qe_gc->lock);
 
                mm_gc = &qe_gc->mm_gc;
-               of_gc = &mm_gc->of_gc;
-               gc = &of_gc->gc;
+               gc = &mm_gc->gc;
 
                mm_gc->save_regs = qe_gpio_save_regs;
-               of_gc->gpio_cells = 2;
                gc->ngpio = QE_PIO_PINS;
                gc->direction_input = qe_gpio_dir_in;
                gc->direction_output = qe_gpio_dir_out;
index d5fb173..b6defda 100644 (file)
@@ -91,7 +91,6 @@ static int __init u8_simple_gpiochip_add(struct device_node *np)
        int ret;
        struct u8_gpio_chip *u8_gc;
        struct of_mm_gpio_chip *mm_gc;
-       struct of_gpio_chip *of_gc;
        struct gpio_chip *gc;
 
        u8_gc = kzalloc(sizeof(*u8_gc), GFP_KERNEL);
@@ -101,11 +100,9 @@ static int __init u8_simple_gpiochip_add(struct device_node *np)
        spin_lock_init(&u8_gc->lock);
 
        mm_gc = &u8_gc->mm_gc;
-       of_gc = &mm_gc->of_gc;
-       gc = &of_gc->gc;
+       gc = &mm_gc->gc;
 
        mm_gc->save_regs = u8_gpio_save_regs;
-       of_gc->gpio_cells = 2;
        gc->ngpio = 8;
        gc->direction_input = u8_gpio_dir_in;
        gc->direction_output = u8_gpio_dir_out;
index c0015db..ba068c8 100644 (file)
@@ -18,6 +18,7 @@ config 64BIT
 config SPARC
        bool
        default y
+       select OF
        select HAVE_IDE
        select HAVE_OPROFILE
        select HAVE_ARCH_KGDB if !SMP || SPARC64
@@ -148,9 +149,6 @@ config GENERIC_GPIO
 config ARCH_NO_VIRT_TO_BUS
        def_bool y
 
-config OF
-       def_bool y
-
 config ARCH_SUPPORTS_DEBUG_PAGEALLOC
        def_bool y if SPARC64
 
index d4c4521..fb220e4 100644 (file)
@@ -6,18 +6,23 @@
 #ifndef _ASM_SPARC_DEVICE_H
 #define _ASM_SPARC_DEVICE_H
 
+#include <asm/openprom.h>
+
 struct device_node;
-struct of_device;
+struct platform_device;
 
 struct dev_archdata {
        void                    *iommu;
        void                    *stc;
        void                    *host_controller;
-       struct of_device        *op;
+       struct platform_device  *op;
        int                     numa_node;
 };
 
 struct pdev_archdata {
+       struct resource         resource[PROMREG_MAX];
+       unsigned int            irqs[PROMINTR_MAX];
+       int                     num_irqs;
 };
 
 #endif /* _ASM_SPARC_DEVICE_H */
index 8fac3ab..4f5bde6 100644 (file)
@@ -567,7 +567,7 @@ static unsigned long __init sun_floppy_init(void)
        }
        if (op) {
                floppy_op = op;
-               FLOPPY_IRQ = op->irqs[0];
+               FLOPPY_IRQ = op->archdata.irqs[0];
        } else {
                struct device_node *ebus_dp;
                void __iomem *auxio_reg;
@@ -593,7 +593,7 @@ static unsigned long __init sun_floppy_init(void)
                if (state_prop && !strncmp(state_prop, "disabled", 8))
                        return 0;
 
-               FLOPPY_IRQ = op->irqs[0];
+               FLOPPY_IRQ = op->archdata.irqs[0];
 
                /* Make sure the high density bit is set, some systems
                 * (most notably Ultra5/Ultra10) come up with it clear.
index f320246..22b9828 100644 (file)
@@ -7,25 +7,6 @@
 #include <linux/mod_devicetable.h>
 #include <asm/openprom.h>
 
-/*
- * 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                   dev;
-       struct resource                 resource[PROMREG_MAX];
-       unsigned int                    irqs[PROMINTR_MAX];
-       int                             num_irqs;
-
-       void                            *sysdata;
-
-       int                             slot;
-       int                             portid;
-       int                             clock_freq;
-};
-
 extern void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned long size, char *name);
 extern void of_iounmap(struct resource *res, void __iomem *base, unsigned long size);
 
index c333b8d..0c34a87 100644 (file)
@@ -116,7 +116,7 @@ static int __devinit ecpp_probe(struct of_device *op, const struct of_device_id
        parent = op->dev.of_node->parent;
        if (!strcmp(parent->name, "dma")) {
                p = parport_pc_probe_port(base, base + 0x400,
-                                         op->irqs[0], PARPORT_DMA_NOFIFO,
+                                         op->archdata.irqs[0], PARPORT_DMA_NOFIFO,
                                          op->dev.parent->parent, 0);
                if (!p)
                        return -ENOMEM;
@@ -166,7 +166,7 @@ static int __devinit ecpp_probe(struct of_device *op, const struct of_device_id
                       0, PTR_LPT_REG_DIR);
 
        p = parport_pc_probe_port(base, base + 0x400,
-                                 op->irqs[0],
+                                 op->archdata.irqs[0],
                                  slot,
                                  op->dev.parent,
                                  0);
index f845828..ac69574 100644 (file)
@@ -56,7 +56,6 @@ extern void of_fill_in_cpu_data(void);
  * register them in the of_device objects, whereas powerpc computes them
  * on request.
  */
-extern unsigned int irq_of_parse_and_map(struct device_node *node, int index);
 static inline void irq_dispose_mapping(unsigned int virq)
 {
 }
index 47e63f1..331de91 100644 (file)
@@ -267,6 +267,8 @@ static void __init build_device_resources(struct of_device *op,
        /* Conver to num-entries.  */
        num_reg /= na + ns;
 
+       op->resource = op->archdata.resource;
+       op->num_resources = num_reg;
        for (index = 0; index < num_reg; index++) {
                struct resource *r = &op->resource[index];
                u32 addr[OF_MAX_ADDR_CELLS];
@@ -349,27 +351,21 @@ static struct of_device * __init scan_one_device(struct device_node *dp,
 
        op->dev.of_node = dp;
 
-       op->clock_freq = of_getintprop_default(dp, "clock-frequency",
-                                              (25*1000*1000));
-       op->portid = of_getintprop_default(dp, "upa-portid", -1);
-       if (op->portid == -1)
-               op->portid = of_getintprop_default(dp, "portid", -1);
-
        intr = of_get_property(dp, "intr", &len);
        if (intr) {
-               op->num_irqs = len / sizeof(struct linux_prom_irqs);
-               for (i = 0; i < op->num_irqs; i++)
-                       op->irqs[i] = intr[i].pri;
+               op->archdata.num_irqs = len / sizeof(struct linux_prom_irqs);
+               for (i = 0; i < op->archdata.num_irqs; i++)
+                       op->archdata.irqs[i] = intr[i].pri;
        } else {
                const unsigned int *irq =
                        of_get_property(dp, "interrupts", &len);
 
                if (irq) {
-                       op->num_irqs = len / sizeof(unsigned int);
-                       for (i = 0; i < op->num_irqs; i++)
-                               op->irqs[i] = irq[i];
+                       op->archdata.num_irqs = len / sizeof(unsigned int);
+                       for (i = 0; i < op->archdata.num_irqs; i++)
+                               op->archdata.irqs[i] = irq[i];
                } else {
-                       op->num_irqs = 0;
+                       op->archdata.num_irqs = 0;
                }
        }
        if (sparc_cpu_model == sun4d) {
@@ -411,8 +407,8 @@ static struct of_device * __init scan_one_device(struct device_node *dp,
                        goto build_resources;
                }
 
-               for (i = 0; i < op->num_irqs; i++) {
-                       int this_irq = op->irqs[i];
+               for (i = 0; i < op->archdata.num_irqs; i++) {
+                       int this_irq = op->archdata.irqs[i];
                        int sbusl = pil_to_sbus[this_irq];
 
                        if (sbusl)
@@ -420,7 +416,7 @@ static struct of_device * __init scan_one_device(struct device_node *dp,
                                            (sbusl << 2) +
                                            slot);
 
-                       op->irqs[i] = this_irq;
+                       op->archdata.irqs[i] = this_irq;
                }
        }
 
index 1dae807..5e8cbb9 100644 (file)
@@ -344,6 +344,8 @@ static void __init build_device_resources(struct of_device *op,
                num_reg = PROMREG_MAX;
        }
 
+       op->resource = op->archdata.resource;
+       op->num_resources = num_reg;
        for (index = 0; index < num_reg; index++) {
                struct resource *r = &op->resource[index];
                u32 addr[OF_MAX_ADDR_CELLS];
@@ -644,31 +646,25 @@ static struct of_device * __init scan_one_device(struct device_node *dp,
 
        op->dev.of_node = dp;
 
-       op->clock_freq = of_getintprop_default(dp, "clock-frequency",
-                                              (25*1000*1000));
-       op->portid = of_getintprop_default(dp, "upa-portid", -1);
-       if (op->portid == -1)
-               op->portid = of_getintprop_default(dp, "portid", -1);
-
        irq = of_get_property(dp, "interrupts", &len);
        if (irq) {
-               op->num_irqs = len / 4;
+               op->archdata.num_irqs = len / 4;
 
                /* Prevent overrunning the op->irqs[] array.  */
-               if (op->num_irqs > PROMINTR_MAX) {
+               if (op->archdata.num_irqs > PROMINTR_MAX) {
                        printk(KERN_WARNING "%s: Too many irqs (%d), "
                               "limiting to %d.\n",
-                              dp->full_name, op->num_irqs, PROMINTR_MAX);
-                       op->num_irqs = PROMINTR_MAX;
+                              dp->full_name, op->archdata.num_irqs, PROMINTR_MAX);
+                       op->archdata.num_irqs = PROMINTR_MAX;
                }
-               memcpy(op->irqs, irq, op->num_irqs * 4);
+               memcpy(op->archdata.irqs, irq, op->archdata.num_irqs * 4);
        } else {
-               op->num_irqs = 0;
+               op->archdata.num_irqs = 0;
        }
 
        build_device_resources(op, parent);
-       for (i = 0; i < op->num_irqs; i++)
-               op->irqs[i] = build_one_device_irq(op, parent, op->irqs[i]);
+       for (i = 0; i < op->archdata.num_irqs; i++)
+               op->archdata.irqs[i] = build_one_device_irq(op, parent, op->archdata.irqs[i]);
 
        op->dev.parent = parent;
        op->dev.bus = &of_platform_bus_type;
index 10c6c36..016c947 100644 (file)
@@ -35,10 +35,10 @@ unsigned int irq_of_parse_and_map(struct device_node *node, int index)
 {
        struct of_device *op = of_find_device_by_node(node);
 
-       if (!op || index >= op->num_irqs)
+       if (!op || index >= op->archdata.num_irqs)
                return 0;
 
-       return op->irqs[index];
+       return op->archdata.irqs[index];
 }
 EXPORT_SYMBOL(irq_of_parse_and_map);
 
index 8a8363a..1523290 100644 (file)
@@ -340,7 +340,7 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm,
                dev->hdr_type = PCI_HEADER_TYPE_NORMAL;
                dev->rom_base_reg = PCI_ROM_ADDRESS;
 
-               dev->irq = sd->op->irqs[0];
+               dev->irq = sd->op->archdata.irqs[0];
                if (dev->irq == 0xffffffff)
                        dev->irq = PCI_IRQ_NONE;
        }
index 558a705..93011e6 100644 (file)
@@ -302,23 +302,23 @@ static void psycho_register_error_handlers(struct pci_pbm_info *pbm)
         * 5: POWER MANAGEMENT
         */
 
-       if (op->num_irqs < 6)
+       if (op->archdata.num_irqs < 6)
                return;
 
        /* We really mean to ignore the return result here.  Two
         * PCI controller share the same interrupt numbers and
         * drive the same front-end hardware.
         */
-       err = request_irq(op->irqs[1], psycho_ue_intr, IRQF_SHARED,
+       err = request_irq(op->archdata.irqs[1], psycho_ue_intr, IRQF_SHARED,
                          "PSYCHO_UE", pbm);
-       err = request_irq(op->irqs[2], psycho_ce_intr, IRQF_SHARED,
+       err = request_irq(op->archdata.irqs[2], psycho_ce_intr, IRQF_SHARED,
                          "PSYCHO_CE", pbm);
 
        /* This one, however, ought not to fail.  We can just warn
         * about it since the system can still operate properly even
         * if this fails.
         */
-       err = request_irq(op->irqs[0], psycho_pcierr_intr, IRQF_SHARED,
+       err = request_irq(op->archdata.irqs[0], psycho_pcierr_intr, IRQF_SHARED,
                          "PSYCHO_PCIERR", pbm);
        if (err)
                printk(KERN_WARNING "%s: Could not register PCIERR, "
index 6dad8e3..99c6dba 100644 (file)
@@ -329,7 +329,7 @@ static void sabre_register_error_handlers(struct pci_pbm_info *pbm)
         * 2: CE ERR
         * 3: POWER FAIL
         */
-       if (op->num_irqs < 4)
+       if (op->archdata.num_irqs < 4)
                return;
 
        /* We clear the error bits in the appropriate AFSR before
@@ -341,7 +341,7 @@ static void sabre_register_error_handlers(struct pci_pbm_info *pbm)
                    SABRE_UEAFSR_SDTE | SABRE_UEAFSR_PDTE),
                   base + SABRE_UE_AFSR);
 
-       err = request_irq(op->irqs[1], sabre_ue_intr, 0, "SABRE_UE", pbm);
+       err = request_irq(op->archdata.irqs[1], sabre_ue_intr, 0, "SABRE_UE", pbm);
        if (err)
                printk(KERN_WARNING "%s: Couldn't register UE, err=%d.\n",
                       pbm->name, err);
@@ -351,11 +351,11 @@ static void sabre_register_error_handlers(struct pci_pbm_info *pbm)
                   base + SABRE_CE_AFSR);
 
 
-       err = request_irq(op->irqs[2], sabre_ce_intr, 0, "SABRE_CE", pbm);
+       err = request_irq(op->archdata.irqs[2], sabre_ce_intr, 0, "SABRE_CE", pbm);
        if (err)
                printk(KERN_WARNING "%s: Couldn't register CE, err=%d.\n",
                       pbm->name, err);
-       err = request_irq(op->irqs[0], psycho_pcierr_intr, 0,
+       err = request_irq(op->archdata.irqs[0], psycho_pcierr_intr, 0,
                          "SABRE_PCIERR", pbm);
        if (err)
                printk(KERN_WARNING "%s: Couldn't register PCIERR, err=%d.\n",
index 97a1ae2..9041dae 100644 (file)
@@ -857,14 +857,14 @@ static void tomatillo_register_error_handlers(struct pci_pbm_info *pbm)
         */
 
        if (pbm_routes_this_ino(pbm, SCHIZO_UE_INO)) {
-               err = request_irq(op->irqs[1], schizo_ue_intr, 0,
+               err = request_irq(op->archdata.irqs[1], schizo_ue_intr, 0,
                                  "TOMATILLO_UE", pbm);
                if (err)
                        printk(KERN_WARNING "%s: Could not register UE, "
                               "err=%d\n", pbm->name, err);
        }
        if (pbm_routes_this_ino(pbm, SCHIZO_CE_INO)) {
-               err = request_irq(op->irqs[2], schizo_ce_intr, 0,
+               err = request_irq(op->archdata.irqs[2], schizo_ce_intr, 0,
                                  "TOMATILLO_CE", pbm);
                if (err)
                        printk(KERN_WARNING "%s: Could not register CE, "
@@ -872,10 +872,10 @@ static void tomatillo_register_error_handlers(struct pci_pbm_info *pbm)
        }
        err = 0;
        if (pbm_routes_this_ino(pbm, SCHIZO_PCIERR_A_INO)) {
-               err = request_irq(op->irqs[0], schizo_pcierr_intr, 0,
+               err = request_irq(op->archdata.irqs[0], schizo_pcierr_intr, 0,
                                  "TOMATILLO_PCIERR", pbm);
        } else if (pbm_routes_this_ino(pbm, SCHIZO_PCIERR_B_INO)) {
-               err = request_irq(op->irqs[0], schizo_pcierr_intr, 0,
+               err = request_irq(op->archdata.irqs[0], schizo_pcierr_intr, 0,
                                  "TOMATILLO_PCIERR", pbm);
        }
        if (err)
@@ -883,7 +883,7 @@ static void tomatillo_register_error_handlers(struct pci_pbm_info *pbm)
                       "err=%d\n", pbm->name, err);
 
        if (pbm_routes_this_ino(pbm, SCHIZO_SERR_INO)) {
-               err = request_irq(op->irqs[3], schizo_safarierr_intr, 0,
+               err = request_irq(op->archdata.irqs[3], schizo_safarierr_intr, 0,
                                  "TOMATILLO_SERR", pbm);
                if (err)
                        printk(KERN_WARNING "%s: Could not register SERR, "
@@ -952,14 +952,14 @@ static void schizo_register_error_handlers(struct pci_pbm_info *pbm)
         */
 
        if (pbm_routes_this_ino(pbm, SCHIZO_UE_INO)) {
-               err = request_irq(op->irqs[1], schizo_ue_intr, 0,
+               err = request_irq(op->archdata.irqs[1], schizo_ue_intr, 0,
                                  "SCHIZO_UE", pbm);
                if (err)
                        printk(KERN_WARNING "%s: Could not register UE, "
                               "err=%d\n", pbm->name, err);
        }
        if (pbm_routes_this_ino(pbm, SCHIZO_CE_INO)) {
-               err = request_irq(op->irqs[2], schizo_ce_intr, 0,
+               err = request_irq(op->archdata.irqs[2], schizo_ce_intr, 0,
                                  "SCHIZO_CE", pbm);
                if (err)
                        printk(KERN_WARNING "%s: Could not register CE, "
@@ -967,10 +967,10 @@ static void schizo_register_error_handlers(struct pci_pbm_info *pbm)
        }
        err = 0;
        if (pbm_routes_this_ino(pbm, SCHIZO_PCIERR_A_INO)) {
-               err = request_irq(op->irqs[0], schizo_pcierr_intr, 0,
+               err = request_irq(op->archdata.irqs[0], schizo_pcierr_intr, 0,
                                  "SCHIZO_PCIERR", pbm);
        } else if (pbm_routes_this_ino(pbm, SCHIZO_PCIERR_B_INO)) {
-               err = request_irq(op->irqs[0], schizo_pcierr_intr, 0,
+               err = request_irq(op->archdata.irqs[0], schizo_pcierr_intr, 0,
                                  "SCHIZO_PCIERR", pbm);
        }
        if (err)
@@ -978,7 +978,7 @@ static void schizo_register_error_handlers(struct pci_pbm_info *pbm)
                       "err=%d\n", pbm->name, err);
 
        if (pbm_routes_this_ino(pbm, SCHIZO_SERR_INO)) {
-               err = request_irq(op->irqs[3], schizo_safarierr_intr, 0,
+               err = request_irq(op->archdata.irqs[3], schizo_safarierr_intr, 0,
                                  "SCHIZO_SERR", pbm);
                if (err)
                        printk(KERN_WARNING "%s: Could not register SERR, "
index 168d4cb..1cfee57 100644 (file)
@@ -36,7 +36,7 @@ static int __devinit has_button_interrupt(unsigned int irq, struct device_node *
 static int __devinit power_probe(struct of_device *op, const struct of_device_id *match)
 {
        struct resource *res = &op->resource[0];
-       unsigned int irq= op->irqs[0];
+       unsigned int irq = op->archdata.irqs[0];
 
        power_reg = of_ioremap(res, 0, 0x4, "power");
 
index a8591ef..eeb04a7 100644 (file)
@@ -9,14 +9,6 @@ extern void irq_trans_init(struct device_node *dp);
 
 extern unsigned int prom_unique_id;
 
-static inline int is_root_node(const struct device_node *dp)
-{
-       if (!dp)
-               return 0;
-
-       return (dp->parent == NULL);
-}
-
 extern char *build_path_component(struct device_node *dp);
 extern void of_console_init(void);
 
index 466a327..86597d9 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/memblock.h>
-#include <linux/of_device.h>
+#include <linux/of.h>
 
 #include <asm/prom.h>
 #include <asm/oplib.h>
@@ -81,7 +81,7 @@ static void __init sun4v_path_component(struct device_node *dp, char *tmp_buf)
                return;
 
        regs = rprop->value;
-       if (!is_root_node(dp->parent)) {
+       if (!of_node_is_root(dp->parent)) {
                sprintf(tmp_buf, "%s@%x,%x",
                        dp->name,
                        (unsigned int) (regs->phys_addr >> 32UL),
@@ -121,7 +121,7 @@ static void __init sun4u_path_component(struct device_node *dp, char *tmp_buf)
                return;
 
        regs = prop->value;
-       if (!is_root_node(dp->parent)) {
+       if (!of_node_is_root(dp->parent)) {
                sprintf(tmp_buf, "%s@%x,%x",
                        dp->name,
                        (unsigned int) (regs->phys_addr >> 32UL),
index 57ac9e2..1f830da 100644 (file)
@@ -244,7 +244,7 @@ char * __init build_full_name(struct device_node *dp)
 
        n = prom_early_alloc(len);
        strcpy(n, dp->parent->full_name);
-       if (!is_root_node(dp->parent)) {
+       if (!of_node_is_root(dp->parent)) {
                strcpy(n + plen, "/");
                plen++;
        }
index da8f176..38df87b 100644 (file)
@@ -2657,7 +2657,7 @@ static int __devinit fore200e_sba_probe(struct of_device *op,
 
        fore200e->bus = bus;
        fore200e->bus_dev = op;
-       fore200e->irq = op->irqs[0];
+       fore200e->irq = op->archdata.irqs[0];
        fore200e->phys_base = op->resource[0].start;
 
        sprintf(fore200e->name, "%s-%d", bus->model_name, index);
index 3ca3654..83cbc34 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
 #include <linux/gpio.h>
+#include <linux/of_gpio.h>
 #include <linux/idr.h>
 #include <linux/slab.h>
 
@@ -1099,16 +1100,24 @@ int gpiochip_add(struct gpio_chip *chip)
                }
        }
 
+       of_gpiochip_add(chip);
+
 unlock:
        spin_unlock_irqrestore(&gpio_lock, flags);
-       if (status == 0)
-               status = gpiochip_export(chip);
+
+       if (status)
+               goto fail;
+
+       status = gpiochip_export(chip);
+       if (status)
+               goto fail;
+
+       return 0;
 fail:
        /* failures here can mean systems won't boot... */
-       if (status)
-               pr_err("gpiochip_add: gpios %d..%d (%s) failed to register\n",
-                       chip->base, chip->base + chip->ngpio - 1,
-                       chip->label ? : "generic");
+       pr_err("gpiochip_add: gpios %d..%d (%s) failed to register\n",
+               chip->base, chip->base + chip->ngpio - 1,
+               chip->label ? : "generic");
        return status;
 }
 EXPORT_SYMBOL_GPL(gpiochip_add);
@@ -1127,6 +1136,8 @@ int gpiochip_remove(struct gpio_chip *chip)
 
        spin_lock_irqsave(&gpio_lock, flags);
 
+       of_gpiochip_remove(chip);
+
        for (id = chip->base; id < chip->base + chip->ngpio; id++) {
                if (test_bit(FLAG_REQUESTED, &gpio_desc[id].flags)) {
                        status = -EBUSY;
@@ -1147,6 +1158,38 @@ int gpiochip_remove(struct gpio_chip *chip)
 }
 EXPORT_SYMBOL_GPL(gpiochip_remove);
 
+/**
+ * gpiochip_find() - iterator for locating a specific gpio_chip
+ * @data: data to pass to match function
+ * @callback: Callback function to check gpio_chip
+ *
+ * Similar to bus_find_device.  It returns a reference to a gpio_chip as
+ * determined by a user supplied @match callback.  The callback should return
+ * 0 if the device doesn't match and non-zero if it does.  If the callback is
+ * non-zero, this function will return to the caller and not iterate over any
+ * more gpio_chips.
+ */
+struct gpio_chip *gpiochip_find(void *data,
+                               int (*match)(struct gpio_chip *chip, void *data))
+{
+       struct gpio_chip *chip = NULL;
+       unsigned long flags;
+       int i;
+
+       spin_lock_irqsave(&gpio_lock, flags);
+       for (i = 0; i < ARCH_NR_GPIOS; i++) {
+               if (!gpio_desc[i].chip)
+                       continue;
+
+               if (match(gpio_desc[i].chip, data)) {
+                       chip = gpio_desc[i].chip;
+                       break;
+               }
+       }
+       spin_unlock_irqrestore(&gpio_lock, flags);
+
+       return chip;
+}
 
 /* These "optional" allocation calls help prevent drivers from stomping
  * on each other, and help provide better diagnostics in debugfs.
index b8fa65b..7096909 100644 (file)
@@ -161,14 +161,12 @@ static void xgpio_save_regs(struct of_mm_gpio_chip *mm_gc)
 static int __devinit xgpio_of_probe(struct device_node *np)
 {
        struct xgpio_instance *chip;
-       struct of_gpio_chip *ofchip;
        int status = 0;
        const u32 *tree_info;
 
        chip = kzalloc(sizeof(*chip), GFP_KERNEL);
        if (!chip)
                return -ENOMEM;
-       ofchip = &chip->mmchip.of_gc;
 
        /* Update GPIO state shadow register with default value */
        tree_info = of_get_property(np, "xlnx,dout-default", NULL);
@@ -182,21 +180,20 @@ static int __devinit xgpio_of_probe(struct device_node *np)
                chip->gpio_dir = *tree_info;
 
        /* Check device node and parent device node for device width */
-       ofchip->gc.ngpio = 32; /* By default assume full GPIO controller */
+       chip->mmchip.gc.ngpio = 32; /* By default assume full GPIO controller */
        tree_info = of_get_property(np, "xlnx,gpio-width", NULL);
        if (!tree_info)
                tree_info = of_get_property(np->parent,
                                            "xlnx,gpio-width", NULL);
        if (tree_info)
-               ofchip->gc.ngpio = *tree_info;
+               chip->mmchip.gc.ngpio = *tree_info;
 
        spin_lock_init(&chip->gpio_lock);
 
-       ofchip->gpio_cells = 2;
-       ofchip->gc.direction_input = xgpio_dir_in;
-       ofchip->gc.direction_output = xgpio_dir_out;
-       ofchip->gc.get = xgpio_get;
-       ofchip->gc.set = xgpio_set;
+       chip->mmchip.gc.direction_input = xgpio_dir_in;
+       chip->mmchip.gc.direction_output = xgpio_dir_out;
+       chip->mmchip.gc.get = xgpio_get;
+       chip->mmchip.gc.set = xgpio_set;
 
        chip->mmchip.save_regs = xgpio_save_regs;
 
index b02b453..e591de1 100644 (file)
@@ -652,6 +652,7 @@ static int __devinit cpm_i2c_probe(struct of_device *ofdev,
        cpm->adap = cpm_ops;
        i2c_set_adapdata(&cpm->adap, cpm);
        cpm->adap.dev.parent = &ofdev->dev;
+       cpm->adap.dev.of_node = of_node_get(ofdev->dev.of_node);
 
        result = cpm_i2c_setup(cpm);
        if (result) {
@@ -676,11 +677,6 @@ static int __devinit cpm_i2c_probe(struct of_device *ofdev,
        dev_dbg(&ofdev->dev, "hw routines for %s registered.\n",
                cpm->adap.name);
 
-       /*
-        * register OF I2C devices
-        */
-       of_register_i2c_devices(&cpm->adap, ofdev->dev.of_node);
-
        return 0;
 out_shut:
        cpm_i2c_shutdown(cpm);
index bf34413..1168d61 100644 (file)
@@ -745,6 +745,7 @@ static int __devinit iic_probe(struct of_device *ofdev,
        /* Register it with i2c layer */
        adap = &dev->adap;
        adap->dev.parent = &ofdev->dev;
+       adap->dev.of_node = of_node_get(np);
        strlcpy(adap->name, "IBM IIC", sizeof(adap->name));
        i2c_set_adapdata(adap, dev);
        adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
@@ -760,9 +761,6 @@ static int __devinit iic_probe(struct of_device *ofdev,
        dev_info(&ofdev->dev, "using %s mode\n",
                 dev->fast_mode ? "fast (400 kHz)" : "standard (100 kHz)");
 
-       /* Now register all the child nodes */
-       of_register_i2c_devices(adap, np);
-
        return 0;
 
 error_cleanup:
index df00eb1..9f7fef8 100644 (file)
@@ -600,13 +600,13 @@ static int __devinit fsl_i2c_probe(struct of_device *op,
        i2c->adap = mpc_ops;
        i2c_set_adapdata(&i2c->adap, i2c);
        i2c->adap.dev.parent = &op->dev;
+       i2c->adap.dev.of_node = of_node_get(op->dev.of_node);
 
        result = i2c_add_adapter(&i2c->adap);
        if (result < 0) {
                dev_err(i2c->dev, "failed to add adapter\n");
                goto fail_add;
        }
-       of_register_i2c_devices(&i2c->adap, op->dev.of_node);
 
        return result;
 
index 0815e10..df937df 100644 (file)
@@ -30,6 +30,8 @@
 #include <linux/init.h>
 #include <linux/idr.h>
 #include <linux/mutex.h>
+#include <linux/of_i2c.h>
+#include <linux/of_device.h>
 #include <linux/completion.h>
 #include <linux/hardirq.h>
 #include <linux/irqflags.h>
@@ -70,6 +72,10 @@ static int i2c_device_match(struct device *dev, struct device_driver *drv)
        if (!client)
                return 0;
 
+       /* Attempt an OF style match */
+       if (of_driver_match_device(dev, drv))
+               return 1;
+
        driver = to_i2c_driver(drv);
        /* match on an id table if there is one */
        if (driver->id_table)
@@ -790,6 +796,9 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
        if (adap->nr < __i2c_first_dynamic_bus_num)
                i2c_scan_static_board_info(adap);
 
+       /* Register devices from the device tree */
+       of_i2c_register_devices(adap);
+
        /* Notify drivers */
        mutex_lock(&core_lock);
        dummy = bus_for_each_drv(&i2c_bus_type, NULL, adap,
index 04e32f2..c7d50ff 100644 (file)
@@ -58,9 +58,9 @@ static int __devinit sparc_i8042_probe(struct of_device *op, const struct of_dev
                if (!strcmp(dp->name, OBP_PS2KBD_NAME1) ||
                    !strcmp(dp->name, OBP_PS2KBD_NAME2)) {
                        struct of_device *kbd = of_find_device_by_node(dp);
-                       unsigned int irq = kbd->irqs[0];
+                       unsigned int irq = kbd->archdata.irqs[0];
                        if (irq == 0xffffffff)
-                               irq = op->irqs[0];
+                               irq = op->archdata.irqs[0];
                        i8042_kbd_irq = irq;
                        kbd_iobase = of_ioremap(&kbd->resource[0],
                                                0, 8, "kbd");
@@ -68,9 +68,9 @@ static int __devinit sparc_i8042_probe(struct of_device *op, const struct of_dev
                } else if (!strcmp(dp->name, OBP_PS2MS_NAME1) ||
                           !strcmp(dp->name, OBP_PS2MS_NAME2)) {
                        struct of_device *ms = of_find_device_by_node(dp);
-                       unsigned int irq = ms->irqs[0];
+                       unsigned int irq = ms->archdata.irqs[0];
                        if (irq == 0xffffffff)
-                               irq = op->irqs[0];
+                               irq = op->archdata.irqs[0];
                        i8042_aux_irq = irq;
                }
 
index 6999ce5..6024038 100644 (file)
@@ -41,10 +41,7 @@ compatible_show (struct device *dev, struct device_attribute *attr, char *buf)
 static ssize_t modalias_show (struct device *dev, struct device_attribute *attr,
                              char *buf)
 {
-       struct of_device *ofdev = to_of_device(dev);
-       int len;
-
-       len = of_device_get_modalias(ofdev, buf, PAGE_SIZE - 2);
+       int len = of_device_get_modalias(dev, buf, PAGE_SIZE - 2);
 
        buf[len] = '\n';
        buf[len+1] = 0;
index ad847a2..7b0f3ef 100644 (file)
@@ -1533,12 +1533,20 @@ static int __devexit mmc_spi_remove(struct spi_device *spi)
        return 0;
 }
 
+#if defined(CONFIG_OF)
+static struct of_device_id mmc_spi_of_match_table[] __devinitdata = {
+       { .compatible = "mmc-spi-slot", },
+};
+#endif
 
 static struct spi_driver mmc_spi_driver = {
        .driver = {
                .name =         "mmc_spi",
                .bus =          &spi_bus_type,
                .owner =        THIS_MODULE,
+#if defined(CONFIG_OF)
+               .of_match_table = mmc_spi_of_match_table,
+#endif
        },
        .probe =        mmc_spi_probe,
        .remove =       __devexit_p(mmc_spi_remove),
index 1a57c3d..370d3c1 100644 (file)
@@ -1079,7 +1079,7 @@ static int __devinit myri_sbus_probe(struct of_device *op, const struct of_devic
 
        mp->dev = dev;
        dev->watchdog_timeo = 5*HZ;
-       dev->irq = op->irqs[0];
+       dev->irq = op->archdata.irqs[0];
        dev->netdev_ops = &myri_ops;
 
        /* Register interrupt handler now. */
index 63e8e38..f6ecf61 100644 (file)
 #include <linux/slab.h>
 
 #include <linux/io.h>
-
-#ifdef CONFIG_SPARC64
 #include <linux/of_device.h>
-#endif
 
 #include "niu.h"
 
@@ -9119,12 +9116,12 @@ static int __devinit niu_n2_irq_init(struct niu *np, u8 *ldg_num_map)
        if (!int_prop)
                return -ENODEV;
 
-       for (i = 0; i < op->num_irqs; i++) {
+       for (i = 0; i < op->archdata.num_irqs; i++) {
                ldg_num_map[i] = int_prop[i];
-               np->ldg[i].irq = op->irqs[i];
+               np->ldg[i].irq = op->archdata.irqs[i];
        }
 
-       np->num_ldg = op->num_irqs;
+       np->num_ldg = op->archdata.num_irqs;
 
        return 0;
 #else
index d671546..a41fa8e 100644 (file)
@@ -3236,7 +3236,7 @@ struct niu_phy_ops {
        int (*link_status)(struct niu *np, int *);
 };
 
-struct of_device;
+struct platform_device;
 struct niu {
        void __iomem                    *regs;
        struct net_device               *dev;
@@ -3297,7 +3297,7 @@ struct niu {
        struct niu_vpd                  vpd;
        u32                             eeprom_len;
 
-       struct of_device                *op;
+       struct platform_device          *op;
        void __iomem                    *vir_regs_1;
        void __iomem                    *vir_regs_2;
 };
index 367e96f..0b10d24 100644 (file)
@@ -1201,7 +1201,7 @@ static int __devinit bigmac_ether_init(struct of_device *op,
        dev->watchdog_timeo = 5*HZ;
 
        /* Finish net device registration. */
-       dev->irq = bp->bigmac_op->irqs[0];
+       dev->irq = bp->bigmac_op->archdata.irqs[0];
        dev->dma = 0;
 
        if (register_netdev(dev)) {
index 3d9650b..0a63ebe 100644 (file)
@@ -2561,7 +2561,7 @@ static int __init quattro_sbus_register_irqs(void)
                if (skip)
                        continue;
 
-               err = request_irq(op->irqs[0],
+               err = request_irq(op->archdata.irqs[0],
                                  quattro_sbus_interrupt,
                                  IRQF_SHARED, "Quattro",
                                  qp);
@@ -2590,7 +2590,7 @@ static void quattro_sbus_free_irqs(void)
                if (skip)
                        continue;
 
-               free_irq(op->irqs[0], qp);
+               free_irq(op->archdata.irqs[0], qp);
        }
 }
 #endif /* CONFIG_SBUS */
@@ -2790,7 +2790,7 @@ static int __devinit happy_meal_sbus_probe_one(struct of_device *op, int is_qfe)
        /* Happy Meal can do it all... */
        dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM;
 
-       dev->irq = op->irqs[0];
+       dev->irq = op->archdata.irqs[0];
 
 #if defined(CONFIG_SBUS) && defined(CONFIG_PCI)
        /* Hook up SBUS register/descriptor accessors. */
index 7d9c33d..c6bfdad 100644 (file)
@@ -1474,7 +1474,7 @@ no_link_test:
        dev->ethtool_ops = &sparc_lance_ethtool_ops;
        dev->netdev_ops = &sparc_lance_ops;
 
-       dev->irq = op->irqs[0];
+       dev->irq = op->archdata.irqs[0];
 
        /* We cannot sleep if the chip is busy during a
         * multicast list update event, because such events
index 72b579c..4465174 100644 (file)
@@ -803,7 +803,7 @@ static struct sunqec * __devinit get_qec(struct of_device *child)
 
                        qec_init_once(qecp, op);
 
-                       if (request_irq(op->irqs[0], qec_interrupt,
+                       if (request_irq(op->archdata.irqs[0], qec_interrupt,
                                        IRQF_SHARED, "qec", (void *) qecp)) {
                                printk(KERN_ERR "qec: Can't register irq.\n");
                                goto fail;
@@ -901,7 +901,7 @@ static int __devinit qec_ether_init(struct of_device *op)
        SET_NETDEV_DEV(dev, &op->dev);
 
        dev->watchdog_timeo = 5*HZ;
-       dev->irq = op->irqs[0];
+       dev->irq = op->archdata.irqs[0];
        dev->dma = 0;
        dev->ethtool_ops = &qe_ethtool_ops;
        dev->netdev_ops = &qec_ops;
@@ -999,7 +999,7 @@ static void __exit qec_exit(void)
                struct sunqec *next = root_qec_dev->next_module;
                struct of_device *op = root_qec_dev->op;
 
-               free_irq(op->irqs[0], (void *) root_qec_dev);
+               free_irq(op->archdata.irqs[0], (void *) root_qec_dev);
                of_iounmap(&op->resource[0], root_qec_dev->gregs,
                           GLOB_REG_SIZE);
                kfree(root_qec_dev);
index 7cecc8f..6acbff3 100644 (file)
@@ -1,35 +1,61 @@
-config OF_FLATTREE
+config DTC
+       bool
+
+config OF
        bool
+
+menu "Flattened Device Tree and Open Firmware support"
        depends on OF
 
+config PROC_DEVICETREE
+       bool "Support for device tree in /proc"
+       depends on PROC_FS && !SPARC
+       help
+         This option adds a device-tree directory under /proc which contains
+         an image of the device tree that the kernel copies from Open
+         Firmware or other boot firmware. If unsure, say Y here.
+
+config OF_FLATTREE
+       bool
+       select DTC
+
 config OF_DYNAMIC
        def_bool y
-       depends on OF && PPC_OF
+       depends on PPC_OF
+
+config OF_ADDRESS
+       def_bool y
+       depends on !SPARC
+
+config OF_IRQ
+       def_bool y
+       depends on !SPARC
 
 config OF_DEVICE
        def_bool y
-       depends on OF && (SPARC || PPC_OF || MICROBLAZE)
 
 config OF_GPIO
        def_bool y
-       depends on OF && (PPC_OF || MICROBLAZE) && GPIOLIB
+       depends on GPIOLIB && !SPARC
        help
          OpenFirmware GPIO accessors
 
 config OF_I2C
        def_tristate I2C
-       depends on (PPC_OF || MICROBLAZE) && I2C
+       depends on I2C && !SPARC
        help
          OpenFirmware I2C accessors
 
 config OF_SPI
        def_tristate SPI
-       depends on OF && (PPC_OF || MICROBLAZE) && SPI
+       depends on SPI && !SPARC
        help
          OpenFirmware SPI accessors
 
 config OF_MDIO
        def_tristate PHYLIB
-       depends on OF && PHYLIB
+       depends on PHYLIB
        help
          OpenFirmware MDIO bus (Ethernet PHY) accessors
+
+endmenu # OF
index f232cc9..0052c40 100644 (file)
@@ -1,5 +1,7 @@
 obj-y = base.o
 obj-$(CONFIG_OF_FLATTREE) += fdt.o
+obj-$(CONFIG_OF_ADDRESS)  += address.o
+obj-$(CONFIG_OF_IRQ)    += irq.o
 obj-$(CONFIG_OF_DEVICE) += device.o platform.o
 obj-$(CONFIG_OF_GPIO)   += gpio.o
 obj-$(CONFIG_OF_I2C)   += of_i2c.o
diff --git a/drivers/of/address.c b/drivers/of/address.c
new file mode 100644 (file)
index 0000000..fcadb72
--- /dev/null
@@ -0,0 +1,595 @@
+
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/pci_regs.h>
+#include <linux/string.h>
+
+/* Max address size we deal with */
+#define OF_MAX_ADDR_CELLS      4
+#define OF_CHECK_COUNTS(na, ns)        ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS && \
+                       (ns) > 0)
+
+static struct of_bus *of_match_bus(struct device_node *np);
+static int __of_address_to_resource(struct device_node *dev, const u32 *addrp,
+                                   u64 size, unsigned int flags,
+                                   struct resource *r);
+
+/* Debug utility */
+#ifdef DEBUG
+static void of_dump_addr(const char *s, const u32 *addr, int na)
+{
+       printk(KERN_DEBUG "%s", s);
+       while (na--)
+               printk(" %08x", be32_to_cpu(*(addr++)));
+       printk("\n");
+}
+#else
+static void of_dump_addr(const char *s, const u32 *addr, int na) { }
+#endif
+
+/* Callbacks for bus specific translators */
+struct of_bus {
+       const char      *name;
+       const char      *addresses;
+       int             (*match)(struct device_node *parent);
+       void            (*count_cells)(struct device_node *child,
+                                      int *addrc, int *sizec);
+       u64             (*map)(u32 *addr, const u32 *range,
+                               int na, int ns, int pna);
+       int             (*translate)(u32 *addr, u64 offset, int na);
+       unsigned int    (*get_flags)(const u32 *addr);
+};
+
+/*
+ * Default translator (generic bus)
+ */
+
+static void of_bus_default_count_cells(struct device_node *dev,
+                                      int *addrc, int *sizec)
+{
+       if (addrc)
+               *addrc = of_n_addr_cells(dev);
+       if (sizec)
+               *sizec = of_n_size_cells(dev);
+}
+
+static u64 of_bus_default_map(u32 *addr, const u32 *range,
+               int na, int ns, int pna)
+{
+       u64 cp, s, da;
+
+       cp = of_read_number(range, na);
+       s  = of_read_number(range + na + pna, ns);
+       da = of_read_number(addr, na);
+
+       pr_debug("OF: default map, cp=%llx, s=%llx, da=%llx\n",
+                (unsigned long long)cp, (unsigned long long)s,
+                (unsigned long long)da);
+
+       if (da < cp || da >= (cp + s))
+               return OF_BAD_ADDR;
+       return da - cp;
+}
+
+static int of_bus_default_translate(u32 *addr, u64 offset, int na)
+{
+       u64 a = of_read_number(addr, na);
+       memset(addr, 0, na * 4);
+       a += offset;
+       if (na > 1)
+               addr[na - 2] = cpu_to_be32(a >> 32);
+       addr[na - 1] = cpu_to_be32(a & 0xffffffffu);
+
+       return 0;
+}
+
+static unsigned int of_bus_default_get_flags(const u32 *addr)
+{
+       return IORESOURCE_MEM;
+}
+
+#ifdef CONFIG_PCI
+/*
+ * PCI bus specific translator
+ */
+
+static int of_bus_pci_match(struct device_node *np)
+{
+       /* "vci" is for the /chaos bridge on 1st-gen PCI powermacs */
+       return !strcmp(np->type, "pci") || !strcmp(np->type, "vci");
+}
+
+static void of_bus_pci_count_cells(struct device_node *np,
+                                  int *addrc, int *sizec)
+{
+       if (addrc)
+               *addrc = 3;
+       if (sizec)
+               *sizec = 2;
+}
+
+static unsigned int of_bus_pci_get_flags(const u32 *addr)
+{
+       unsigned int flags = 0;
+       u32 w = addr[0];
+
+       switch((w >> 24) & 0x03) {
+       case 0x01:
+               flags |= IORESOURCE_IO;
+               break;
+       case 0x02: /* 32 bits */
+       case 0x03: /* 64 bits */
+               flags |= IORESOURCE_MEM;
+               break;
+       }
+       if (w & 0x40000000)
+               flags |= IORESOURCE_PREFETCH;
+       return flags;
+}
+
+static u64 of_bus_pci_map(u32 *addr, const u32 *range, int na, int ns, int pna)
+{
+       u64 cp, s, da;
+       unsigned int af, rf;
+
+       af = of_bus_pci_get_flags(addr);
+       rf = of_bus_pci_get_flags(range);
+
+       /* Check address type match */
+       if ((af ^ rf) & (IORESOURCE_MEM | IORESOURCE_IO))
+               return OF_BAD_ADDR;
+
+       /* Read address values, skipping high cell */
+       cp = of_read_number(range + 1, na - 1);
+       s  = of_read_number(range + na + pna, ns);
+       da = of_read_number(addr + 1, na - 1);
+
+       pr_debug("OF: PCI map, cp=%llx, s=%llx, da=%llx\n",
+                (unsigned long long)cp, (unsigned long long)s,
+                (unsigned long long)da);
+
+       if (da < cp || da >= (cp + s))
+               return OF_BAD_ADDR;
+       return da - cp;
+}
+
+static int of_bus_pci_translate(u32 *addr, u64 offset, int na)
+{
+       return of_bus_default_translate(addr + 1, offset, na - 1);
+}
+
+const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
+                       unsigned int *flags)
+{
+       const u32 *prop;
+       unsigned int psize;
+       struct device_node *parent;
+       struct of_bus *bus;
+       int onesize, i, na, ns;
+
+       /* Get parent & match bus type */
+       parent = of_get_parent(dev);
+       if (parent == NULL)
+               return NULL;
+       bus = of_match_bus(parent);
+       if (strcmp(bus->name, "pci")) {
+               of_node_put(parent);
+               return NULL;
+       }
+       bus->count_cells(dev, &na, &ns);
+       of_node_put(parent);
+       if (!OF_CHECK_COUNTS(na, ns))
+               return NULL;
+
+       /* Get "reg" or "assigned-addresses" property */
+       prop = of_get_property(dev, bus->addresses, &psize);
+       if (prop == NULL)
+               return NULL;
+       psize /= 4;
+
+       onesize = na + ns;
+       for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++) {
+               u32 val = be32_to_cpu(prop[0]);
+               if ((val & 0xff) == ((bar_no * 4) + PCI_BASE_ADDRESS_0)) {
+                       if (size)
+                               *size = of_read_number(prop + na, ns);
+                       if (flags)
+                               *flags = bus->get_flags(prop);
+                       return prop;
+               }
+       }
+       return NULL;
+}
+EXPORT_SYMBOL(of_get_pci_address);
+
+int of_pci_address_to_resource(struct device_node *dev, int bar,
+                              struct resource *r)
+{
+       const u32       *addrp;
+       u64             size;
+       unsigned int    flags;
+
+       addrp = of_get_pci_address(dev, bar, &size, &flags);
+       if (addrp == NULL)
+               return -EINVAL;
+       return __of_address_to_resource(dev, addrp, size, flags, r);
+}
+EXPORT_SYMBOL_GPL(of_pci_address_to_resource);
+#endif /* CONFIG_PCI */
+
+/*
+ * ISA bus specific translator
+ */
+
+static int of_bus_isa_match(struct device_node *np)
+{
+       return !strcmp(np->name, "isa");
+}
+
+static void of_bus_isa_count_cells(struct device_node *child,
+                                  int *addrc, int *sizec)
+{
+       if (addrc)
+               *addrc = 2;
+       if (sizec)
+               *sizec = 1;
+}
+
+static u64 of_bus_isa_map(u32 *addr, const u32 *range, int na, int ns, int pna)
+{
+       u64 cp, s, da;
+
+       /* Check address type match */
+       if ((addr[0] ^ range[0]) & 0x00000001)
+               return OF_BAD_ADDR;
+
+       /* Read address values, skipping high cell */
+       cp = of_read_number(range + 1, na - 1);
+       s  = of_read_number(range + na + pna, ns);
+       da = of_read_number(addr + 1, na - 1);
+
+       pr_debug("OF: ISA map, cp=%llx, s=%llx, da=%llx\n",
+                (unsigned long long)cp, (unsigned long long)s,
+                (unsigned long long)da);
+
+       if (da < cp || da >= (cp + s))
+               return OF_BAD_ADDR;
+       return da - cp;
+}
+
+static int of_bus_isa_translate(u32 *addr, u64 offset, int na)
+{
+       return of_bus_default_translate(addr + 1, offset, na - 1);
+}
+
+static unsigned int of_bus_isa_get_flags(const u32 *addr)
+{
+       unsigned int flags = 0;
+       u32 w = addr[0];
+
+       if (w & 1)
+               flags |= IORESOURCE_IO;
+       else
+               flags |= IORESOURCE_MEM;
+       return flags;
+}
+
+/*
+ * Array of bus specific translators
+ */
+
+static struct of_bus of_busses[] = {
+#ifdef CONFIG_PCI
+       /* PCI */
+       {
+               .name = "pci",
+               .addresses = "assigned-addresses",
+               .match = of_bus_pci_match,
+               .count_cells = of_bus_pci_count_cells,
+               .map = of_bus_pci_map,
+               .translate = of_bus_pci_translate,
+               .get_flags = of_bus_pci_get_flags,
+       },
+#endif /* CONFIG_PCI */
+       /* ISA */
+       {
+               .name = "isa",
+               .addresses = "reg",
+               .match = of_bus_isa_match,
+               .count_cells = of_bus_isa_count_cells,
+               .map = of_bus_isa_map,
+               .translate = of_bus_isa_translate,
+               .get_flags = of_bus_isa_get_flags,
+       },
+       /* Default */
+       {
+               .name = "default",
+               .addresses = "reg",
+               .match = NULL,
+               .count_cells = of_bus_default_count_cells,
+               .map = of_bus_default_map,
+               .translate = of_bus_default_translate,
+               .get_flags = of_bus_default_get_flags,
+       },
+};
+
+static struct of_bus *of_match_bus(struct device_node *np)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(of_busses); i++)
+               if (!of_busses[i].match || of_busses[i].match(np))
+                       return &of_busses[i];
+       BUG();
+       return NULL;
+}
+
+static int of_translate_one(struct device_node *parent, struct of_bus *bus,
+                           struct of_bus *pbus, u32 *addr,
+                           int na, int ns, int pna, const char *rprop)
+{
+       const u32 *ranges;
+       unsigned int rlen;
+       int rone;
+       u64 offset = OF_BAD_ADDR;
+
+       /* Normally, an absence of a "ranges" property means we are
+        * crossing a non-translatable boundary, and thus the addresses
+        * below the current not cannot be converted to CPU physical ones.
+        * Unfortunately, while this is very clear in the spec, it's not
+        * what Apple understood, and they do have things like /uni-n or
+        * /ht nodes with no "ranges" property and a lot of perfectly
+        * useable mapped devices below them. Thus we treat the absence of
+        * "ranges" as equivalent to an empty "ranges" property which means
+        * a 1:1 translation at that level. It's up to the caller not to try
+        * to translate addresses that aren't supposed to be translated in
+        * the first place. --BenH.
+        *
+        * As far as we know, this damage only exists on Apple machines, so
+        * This code is only enabled on powerpc. --gcl
+        */
+       ranges = of_get_property(parent, rprop, &rlen);
+#if !defined(CONFIG_PPC)
+       if (ranges == NULL) {
+               pr_err("OF: no ranges; cannot translate\n");
+               return 1;
+       }
+#endif /* !defined(CONFIG_PPC) */
+       if (ranges == NULL || rlen == 0) {
+               offset = of_read_number(addr, na);
+               memset(addr, 0, pna * 4);
+               pr_debug("OF: empty ranges; 1:1 translation\n");
+               goto finish;
+       }
+
+       pr_debug("OF: walking ranges...\n");
+
+       /* Now walk through the ranges */
+       rlen /= 4;
+       rone = na + pna + ns;
+       for (; rlen >= rone; rlen -= rone, ranges += rone) {
+               offset = bus->map(addr, ranges, na, ns, pna);
+               if (offset != OF_BAD_ADDR)
+                       break;
+       }
+       if (offset == OF_BAD_ADDR) {
+               pr_debug("OF: not found !\n");
+               return 1;
+       }
+       memcpy(addr, ranges + na, 4 * pna);
+
+ finish:
+       of_dump_addr("OF: parent translation for:", addr, pna);
+       pr_debug("OF: with offset: %llx\n", (unsigned long long)offset);
+
+       /* Translate it into parent bus space */
+       return pbus->translate(addr, offset, pna);
+}
+
+/*
+ * Translate an address from the device-tree into a CPU physical address,
+ * this walks up the tree and applies the various bus mappings on the
+ * way.
+ *
+ * Note: We consider that crossing any level with #size-cells == 0 to mean
+ * that translation is impossible (that is we are not dealing with a value
+ * that can be mapped to a cpu physical address). This is not really specified
+ * that way, but this is traditionally the way IBM at least do things
+ */
+u64 __of_translate_address(struct device_node *dev, const u32 *in_addr,
+                          const char *rprop)
+{
+       struct device_node *parent = NULL;
+       struct of_bus *bus, *pbus;
+       u32 addr[OF_MAX_ADDR_CELLS];
+       int na, ns, pna, pns;
+       u64 result = OF_BAD_ADDR;
+
+       pr_debug("OF: ** translation for device %s **\n", dev->full_name);
+
+       /* Increase refcount at current level */
+       of_node_get(dev);
+
+       /* Get parent & match bus type */
+       parent = of_get_parent(dev);
+       if (parent == NULL)
+               goto bail;
+       bus = of_match_bus(parent);
+
+       /* Cound address cells & copy address locally */
+       bus->count_cells(dev, &na, &ns);
+       if (!OF_CHECK_COUNTS(na, ns)) {
+               printk(KERN_ERR "prom_parse: Bad cell count for %s\n",
+                      dev->full_name);
+               goto bail;
+       }
+       memcpy(addr, in_addr, na * 4);
+
+       pr_debug("OF: bus is %s (na=%d, ns=%d) on %s\n",
+           bus->name, na, ns, parent->full_name);
+       of_dump_addr("OF: translating address:", addr, na);
+
+       /* Translate */
+       for (;;) {
+               /* Switch to parent bus */
+               of_node_put(dev);
+               dev = parent;
+               parent = of_get_parent(dev);
+
+               /* If root, we have finished */
+               if (parent == NULL) {
+                       pr_debug("OF: reached root node\n");
+                       result = of_read_number(addr, na);
+                       break;
+               }
+
+               /* Get new parent bus and counts */
+               pbus = of_match_bus(parent);
+               pbus->count_cells(dev, &pna, &pns);
+               if (!OF_CHECK_COUNTS(pna, pns)) {
+                       printk(KERN_ERR "prom_parse: Bad cell count for %s\n",
+                              dev->full_name);
+                       break;
+               }
+
+               pr_debug("OF: parent bus is %s (na=%d, ns=%d) on %s\n",
+                   pbus->name, pna, pns, parent->full_name);
+
+               /* Apply bus translation */
+               if (of_translate_one(dev, bus, pbus, addr, na, ns, pna, rprop))
+                       break;
+
+               /* Complete the move up one level */
+               na = pna;
+               ns = pns;
+               bus = pbus;
+
+               of_dump_addr("OF: one level translation:", addr, na);
+       }
+ bail:
+       of_node_put(parent);
+       of_node_put(dev);
+
+       return result;
+}
+
+u64 of_translate_address(struct device_node *dev, const u32 *in_addr)
+{
+       return __of_translate_address(dev, in_addr, "ranges");
+}
+EXPORT_SYMBOL(of_translate_address);
+
+u64 of_translate_dma_address(struct device_node *dev, const u32 *in_addr)
+{
+       return __of_translate_address(dev, in_addr, "dma-ranges");
+}
+EXPORT_SYMBOL(of_translate_dma_address);
+
+const u32 *of_get_address(struct device_node *dev, int index, u64 *size,
+                   unsigned int *flags)
+{
+       const u32 *prop;
+       unsigned int psize;
+       struct device_node *parent;
+       struct of_bus *bus;
+       int onesize, i, na, ns;
+
+       /* Get parent & match bus type */
+       parent = of_get_parent(dev);
+       if (parent == NULL)
+               return NULL;
+       bus = of_match_bus(parent);
+       bus->count_cells(dev, &na, &ns);
+       of_node_put(parent);
+       if (!OF_CHECK_COUNTS(na, ns))
+               return NULL;
+
+       /* Get "reg" or "assigned-addresses" property */
+       prop = of_get_property(dev, bus->addresses, &psize);
+       if (prop == NULL)
+               return NULL;
+       psize /= 4;
+
+       onesize = na + ns;
+       for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++)
+               if (i == index) {
+                       if (size)
+                               *size = of_read_number(prop + na, ns);
+                       if (flags)
+                               *flags = bus->get_flags(prop);
+                       return prop;
+               }
+       return NULL;
+}
+EXPORT_SYMBOL(of_get_address);
+
+static int __of_address_to_resource(struct device_node *dev, const u32 *addrp,
+                                   u64 size, unsigned int flags,
+                                   struct resource *r)
+{
+       u64 taddr;
+
+       if ((flags & (IORESOURCE_IO | IORESOURCE_MEM)) == 0)
+               return -EINVAL;
+       taddr = of_translate_address(dev, addrp);
+       if (taddr == OF_BAD_ADDR)
+               return -EINVAL;
+       memset(r, 0, sizeof(struct resource));
+       if (flags & IORESOURCE_IO) {
+               unsigned long port;
+               port = pci_address_to_pio(taddr);
+               if (port == (unsigned long)-1)
+                       return -EINVAL;
+               r->start = port;
+               r->end = port + size - 1;
+       } else {
+               r->start = taddr;
+               r->end = taddr + size - 1;
+       }
+       r->flags = flags;
+       r->name = dev->full_name;
+       return 0;
+}
+
+/**
+ * of_address_to_resource - Translate device tree address and return as resource
+ *
+ * Note that if your address is a PIO address, the conversion will fail if
+ * the physical address can't be internally converted to an IO token with
+ * pci_address_to_pio(), that is because it's either called to early or it
+ * can't be matched to any host bridge IO space
+ */
+int of_address_to_resource(struct device_node *dev, int index,
+                          struct resource *r)
+{
+       const u32       *addrp;
+       u64             size;
+       unsigned int    flags;
+
+       addrp = of_get_address(dev, index, &size, &flags);
+       if (addrp == NULL)
+               return -EINVAL;
+       return __of_address_to_resource(dev, addrp, size, flags, r);
+}
+EXPORT_SYMBOL_GPL(of_address_to_resource);
+
+
+/**
+ * of_iomap - Maps the memory mapped IO for a given device_node
+ * @device:    the device whose io range will be mapped
+ * @index:     index of the io range
+ *
+ * Returns a pointer to the mapped memory
+ */
+void __iomem *of_iomap(struct device_node *np, int index)
+{
+       struct resource res;
+
+       if (of_address_to_resource(np, index, &res))
+               return NULL;
+
+       return ioremap(res.start, 1 + res.end - res.start);
+}
+EXPORT_SYMBOL(of_iomap);
index b5ad974..e3f7af8 100644 (file)
@@ -545,74 +545,28 @@ struct device_node *of_find_matching_node(struct device_node *from,
 EXPORT_SYMBOL(of_find_matching_node);
 
 /**
- * of_modalias_table: Table of explicit compatible ==> modalias mappings
- *
- * This table allows particulare compatible property values to be mapped
- * to modalias strings.  This is useful for busses which do not directly
- * understand the OF device tree but are populated based on data contained
- * within the device tree.  SPI and I2C are the two current users of this
- * table.
- *
- * In most cases, devices do not need to be listed in this table because
- * the modalias value can be derived directly from the compatible table.
- * However, if for any reason a value cannot be derived, then this table
- * provides a method to override the implicit derivation.
- *
- * At the moment, a single table is used for all bus types because it is
- * assumed that the data size is small and that the compatible values
- * should already be distinct enough to differentiate between SPI, I2C
- * and other devices.
- */
-struct of_modalias_table {
-       char *of_device;
-       char *modalias;
-};
-static struct of_modalias_table of_modalias_table[] = {
-       { "fsl,mcu-mpc8349emitx", "mcu-mpc8349emitx" },
-       { "mmc-spi-slot", "mmc_spi" },
-};
-
-/**
  * of_modalias_node - Lookup appropriate modalias for a device node
  * @node:      pointer to a device tree node
  * @modalias:  Pointer to buffer that modalias value will be copied into
  * @len:       Length of modalias value
  *
- * Based on the value of the compatible property, this routine will determine
- * an appropriate modalias value for a particular device tree node.  Two
- * separate methods are attempted to derive a modalias value.
+ * Based on the value of the compatible property, this routine will attempt
+ * to choose an appropriate modalias value for a particular device tree node.
+ * It does this by stripping the manufacturer prefix (as delimited by a ',')
+ * from the first entry in the compatible list property.
  *
- * First method is to lookup the compatible value in of_modalias_table.
- * Second is to strip off the manufacturer prefix from the first
- * compatible entry and use the remainder as modalias
- *
- * This routine returns 0 on success
+ * This routine returns 0 on success, <0 on failure.
  */
 int of_modalias_node(struct device_node *node, char *modalias, int len)
 {
-       int i, cplen;
-       const char *compatible;
-       const char *p;
-
-       /* 1. search for exception list entry */
-       for (i = 0; i < ARRAY_SIZE(of_modalias_table); i++) {
-               compatible = of_modalias_table[i].of_device;
-               if (!of_device_is_compatible(node, compatible))
-                       continue;
-               strlcpy(modalias, of_modalias_table[i].modalias, len);
-               return 0;
-       }
+       const char *compatible, *p;
+       int cplen;
 
        compatible = of_get_property(node, "compatible", &cplen);
-       if (!compatible)
+       if (!compatible || strlen(compatible) > cplen)
                return -ENODEV;
-
-       /* 2. take first compatible entry and strip manufacturer */
        p = strchr(compatible, ',');
-       if (!p)
-               return -ENODEV;
-       p++;
-       strlcpy(modalias, p, len);
+       strlcpy(modalias, p ? p + 1 : compatible, len);
        return 0;
 }
 EXPORT_SYMBOL_GPL(of_modalias_node);
index 7d18f8e..5282a20 100644 (file)
@@ -20,7 +20,7 @@
 const struct of_device_id *of_match_device(const struct of_device_id *matches,
                                           const struct device *dev)
 {
-       if (!dev->of_node)
+       if ((!matches) || (!dev->of_node))
                return NULL;
        return of_match_node(matches, dev->of_node);
 }
@@ -68,10 +68,7 @@ static ssize_t name_show(struct device *dev,
 static ssize_t modalias_show(struct device *dev,
                                struct device_attribute *attr, char *buf)
 {
-       struct of_device *ofdev = to_of_device(dev);
-       ssize_t len = 0;
-
-       len = of_device_get_modalias(ofdev, buf, PAGE_SIZE - 2);
+       ssize_t len = of_device_get_modalias(dev, buf, PAGE_SIZE - 2);
        buf[len] = '\n';
        buf[len+1] = 0;
        return len+1;
@@ -123,19 +120,18 @@ void of_device_unregister(struct of_device *ofdev)
 }
 EXPORT_SYMBOL(of_device_unregister);
 
-ssize_t of_device_get_modalias(struct of_device *ofdev,
-                               char *str, ssize_t len)
+ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len)
 {
        const char *compat;
        int cplen, i;
        ssize_t tsize, csize, repend;
 
        /* Name & Type */
-       csize = snprintf(str, len, "of:N%sT%s", ofdev->dev.of_node->name,
-                        ofdev->dev.of_node->type);
+       csize = snprintf(str, len, "of:N%sT%s", dev->of_node->name,
+                        dev->of_node->type);
 
        /* Get compatible property if any */
-       compat = of_get_property(ofdev->dev.of_node, "compatible", &cplen);
+       compat = of_get_property(dev->of_node, "compatible", &cplen);
        if (!compat)
                return csize;
 
@@ -170,3 +166,51 @@ ssize_t of_device_get_modalias(struct of_device *ofdev,
 
        return tsize;
 }
+
+/**
+ * of_device_uevent - Display OF related uevent information
+ */
+int of_device_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+       const char *compat;
+       int seen = 0, cplen, sl;
+
+       if ((!dev) || (!dev->of_node))
+               return -ENODEV;
+
+       if (add_uevent_var(env, "OF_NAME=%s", dev->of_node->name))
+               return -ENOMEM;
+
+       if (add_uevent_var(env, "OF_TYPE=%s", dev->of_node->type))
+               return -ENOMEM;
+
+       /* Since the compatible field can contain pretty much anything
+        * it's not really legal to split it out with commas. We split it
+        * up using a number of environment variables instead. */
+
+       compat = of_get_property(dev->of_node, "compatible", &cplen);
+       while (compat && *compat && cplen > 0) {
+               if (add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat))
+                       return -ENOMEM;
+
+               sl = strlen(compat) + 1;
+               compat += sl;
+               cplen -= sl;
+               seen++;
+       }
+
+       if (add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen))
+               return -ENOMEM;
+
+       /* modalias is trickier, we add it in 2 steps */
+       if (add_uevent_var(env, "MODALIAS="))
+               return -ENOMEM;
+
+       sl = of_device_get_modalias(dev, &env->buf[env->buflen-1],
+                                   sizeof(env->buf) - env->buflen);
+       if (sl >= (sizeof(env->buf) - env->buflen))
+               return -ENOMEM;
+       env->buflen += sl;
+
+       return 0;
+}
index b6987bb..d61fda8 100644 (file)
@@ -69,9 +69,9 @@ int __init of_scan_flat_dt(int (*it)(unsigned long node,
                        u32 sz = be32_to_cpup((__be32 *)p);
                        p += 8;
                        if (be32_to_cpu(initial_boot_params->version) < 0x10)
-                               p = _ALIGN(p, sz >= 8 ? 8 : 4);
+                               p = ALIGN(p, sz >= 8 ? 8 : 4);
                        p += sz;
-                       p = _ALIGN(p, 4);
+                       p = ALIGN(p, 4);
                        continue;
                }
                if (tag != OF_DT_BEGIN_NODE) {
@@ -80,7 +80,7 @@ int __init of_scan_flat_dt(int (*it)(unsigned long node,
                }
                depth++;
                pathp = (char *)p;
-               p = _ALIGN(p + strlen(pathp) + 1, 4);
+               p = ALIGN(p + strlen(pathp) + 1, 4);
                if ((*pathp) == '/') {
                        char *lp, *np;
                        for (lp = NULL, np = pathp; *np; np++)
@@ -109,7 +109,7 @@ unsigned long __init of_get_flat_dt_root(void)
                p += 4;
        BUG_ON(be32_to_cpup((__be32 *)p) != OF_DT_BEGIN_NODE);
        p += 4;
-       return _ALIGN(p + strlen((char *)p) + 1, 4);
+       return ALIGN(p + strlen((char *)p) + 1, 4);
 }
 
 /**
@@ -138,7 +138,7 @@ void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
                noff = be32_to_cpup((__be32 *)(p + 4));
                p += 8;
                if (be32_to_cpu(initial_boot_params->version) < 0x10)
-                       p = _ALIGN(p, sz >= 8 ? 8 : 4);
+                       p = ALIGN(p, sz >= 8 ? 8 : 4);
 
                nstr = find_flat_dt_string(noff);
                if (nstr == NULL) {
@@ -151,7 +151,7 @@ void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
                        return (void *)p;
                }
                p += sz;
-               p = _ALIGN(p, 4);
+               p = ALIGN(p, 4);
        } while (1);
 }
 
@@ -184,7 +184,7 @@ static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size,
 {
        void *res;
 
-       *mem = _ALIGN(*mem, align);
+       *mem = ALIGN(*mem, align);
        res = (void *)*mem;
        *mem += size;
 
@@ -220,7 +220,7 @@ unsigned long __init unflatten_dt_node(unsigned long mem,
        *p += 4;
        pathp = (char *)*p;
        l = allocl = strlen(pathp) + 1;
-       *p = _ALIGN(*p + l, 4);
+       *p = ALIGN(*p + l, 4);
 
        /* version 0x10 has a more compact unit name here instead of the full
         * path. we accumulate the full path size using "fpsize", we'll rebuild
@@ -299,7 +299,7 @@ unsigned long __init unflatten_dt_node(unsigned long mem,
                noff = be32_to_cpup((__be32 *)((*p) + 4));
                *p += 8;
                if (be32_to_cpu(initial_boot_params->version) < 0x10)
-                       *p = _ALIGN(*p, sz >= 8 ? 8 : 4);
+                       *p = ALIGN(*p, sz >= 8 ? 8 : 4);
 
                pname = find_flat_dt_string(noff);
                if (pname == NULL) {
@@ -333,7 +333,7 @@ unsigned long __init unflatten_dt_node(unsigned long mem,
                        *prev_pp = pp;
                        prev_pp = &pp->next;
                }
-               *p = _ALIGN((*p) + sz, 4);
+               *p = ALIGN((*p) + sz, 4);
        }
        /* with version 0x10 we may not have the name property, recreate
         * it here from the unit name if absent
index a1b31a4..9059603 100644 (file)
  * (at your option) any later version.
  */
 
-#include <linux/kernel.h>
+#include <linux/device.h>
 #include <linux/errno.h>
+#include <linux/module.h>
 #include <linux/io.h>
 #include <linux/of.h>
-#include <linux/slab.h>
+#include <linux/of_address.h>
 #include <linux/of_gpio.h>
-#include <asm/prom.h>
+#include <linux/slab.h>
 
 /**
  * of_get_gpio_flags - Get a GPIO number and flags to use with GPIO API
@@ -33,32 +34,32 @@ int of_get_gpio_flags(struct device_node *np, int index,
                      enum of_gpio_flags *flags)
 {
        int ret;
-       struct device_node *gc;
-       struct of_gpio_chip *of_gc = NULL;
+       struct device_node *gpio_np;
+       struct gpio_chip *gc;
        int size;
        const void *gpio_spec;
        const __be32 *gpio_cells;
 
        ret = of_parse_phandles_with_args(np, "gpios", "#gpio-cells", index,
-                                         &gc, &gpio_spec);
+                                         &gpio_np, &gpio_spec);
        if (ret) {
                pr_debug("%s: can't parse gpios property\n", __func__);
                goto err0;
        }
 
-       of_gc = gc->data;
-       if (!of_gc) {
+       gc = of_node_to_gpiochip(gpio_np);
+       if (!gc) {
                pr_debug("%s: gpio controller %s isn't registered\n",
-                        np->full_name, gc->full_name);
+                        np->full_name, gpio_np->full_name);
                ret = -ENODEV;
                goto err1;
        }
 
-       gpio_cells = of_get_property(gc, "#gpio-cells", &size);
+       gpio_cells = of_get_property(gpio_np, "#gpio-cells", &size);
        if (!gpio_cells || size != sizeof(*gpio_cells) ||
-                       be32_to_cpup(gpio_cells) != of_gc->gpio_cells) {
+                       be32_to_cpup(gpio_cells) != gc->of_gpio_n_cells) {
                pr_debug("%s: wrong #gpio-cells for %s\n",
-                        np->full_name, gc->full_name);
+                        np->full_name, gpio_np->full_name);
                ret = -EINVAL;
                goto err1;
        }
@@ -67,13 +68,13 @@ int of_get_gpio_flags(struct device_node *np, int index,
        if (flags)
                *flags = 0;
 
-       ret = of_gc->xlate(of_gc, np, gpio_spec, flags);
+       ret = gc->of_xlate(gc, np, gpio_spec, flags);
        if (ret < 0)
                goto err1;
 
-       ret += of_gc->gc.base;
+       ret += gc->base;
 err1:
-       of_node_put(gc);
+       of_node_put(gpio_np);
 err0:
        pr_debug("%s exited with status %d\n", __func__, ret);
        return ret;
@@ -116,7 +117,7 @@ EXPORT_SYMBOL(of_gpio_count);
 
 /**
  * of_gpio_simple_xlate - translate gpio_spec to the GPIO number and flags
- * @of_gc:     pointer to the of_gpio_chip structure
+ * @gc:                pointer to the gpio_chip structure
  * @np:                device node of the GPIO chip
  * @gpio_spec: gpio specifier as found in the device tree
  * @flags:     a flags pointer to fill in
@@ -125,8 +126,8 @@ EXPORT_SYMBOL(of_gpio_count);
  * gpio chips. This function performs only one sanity check: whether gpio
  * is less than ngpios (that is specified in the gpio_chip).
  */
-int of_gpio_simple_xlate(struct of_gpio_chip *of_gc, struct device_node *np,
-                        const void *gpio_spec, enum of_gpio_flags *flags)
+static int of_gpio_simple_xlate(struct gpio_chip *gc, struct device_node *np,
+                               const void *gpio_spec, u32 *flags)
 {
        const __be32 *gpio = gpio_spec;
        const u32 n = be32_to_cpup(gpio);
@@ -137,12 +138,12 @@ int of_gpio_simple_xlate(struct of_gpio_chip *of_gc, struct device_node *np,
         * number and the flags from a single gpio cell -- this is possible,
         * but not recommended).
         */
-       if (of_gc->gpio_cells < 2) {
+       if (gc->of_gpio_n_cells < 2) {
                WARN_ON(1);
                return -EINVAL;
        }
 
-       if (n > of_gc->gc.ngpio)
+       if (n > gc->ngpio)
                return -EINVAL;
 
        if (flags)
@@ -150,7 +151,6 @@ int of_gpio_simple_xlate(struct of_gpio_chip *of_gc, struct device_node *np,
 
        return n;
 }
-EXPORT_SYMBOL(of_gpio_simple_xlate);
 
 /**
  * of_mm_gpiochip_add - Add memory mapped GPIO chip (bank)
@@ -161,10 +161,8 @@ EXPORT_SYMBOL(of_gpio_simple_xlate);
  *
  * 1) In the gpio_chip structure:
  *    - all the callbacks
- *
- * 2) In the of_gpio_chip structure:
- *    - gpio_cells
- *    - xlate callback (optional)
+ *    - of_gpio_n_cells
+ *    - of_xlate callback (optional)
  *
  * 3) In the of_mm_gpio_chip structure:
  *    - save_regs callback (optional)
@@ -177,8 +175,7 @@ int of_mm_gpiochip_add(struct device_node *np,
                       struct of_mm_gpio_chip *mm_gc)
 {
        int ret = -ENOMEM;
-       struct of_gpio_chip *of_gc = &mm_gc->of_gc;
-       struct gpio_chip *gc = &of_gc->gc;
+       struct gpio_chip *gc = &mm_gc->gc;
 
        gc->label = kstrdup(np->full_name, GFP_KERNEL);
        if (!gc->label)
@@ -190,26 +187,19 @@ int of_mm_gpiochip_add(struct device_node *np,
 
        gc->base = -1;
 
-       if (!of_gc->xlate)
-               of_gc->xlate = of_gpio_simple_xlate;
-
        if (mm_gc->save_regs)
                mm_gc->save_regs(mm_gc);
 
-       np->data = of_gc;
+       mm_gc->gc.of_node = np;
 
        ret = gpiochip_add(gc);
        if (ret)
                goto err2;
 
-       /* We don't want to lose the node and its ->data */
-       of_node_get(np);
-
        pr_debug("%s: registered as generic GPIO chip, base is %d\n",
                 np->full_name, gc->base);
        return 0;
 err2:
-       np->data = NULL;
        iounmap(mm_gc->regs);
 err1:
        kfree(gc->label);
@@ -219,3 +209,36 @@ err0:
        return ret;
 }
 EXPORT_SYMBOL(of_mm_gpiochip_add);
+
+void of_gpiochip_add(struct gpio_chip *chip)
+{
+       if ((!chip->of_node) && (chip->dev))
+               chip->of_node = chip->dev->of_node;
+
+       if (!chip->of_node)
+               return;
+
+       if (!chip->of_xlate) {
+               chip->of_gpio_n_cells = 2;
+               chip->of_xlate = of_gpio_simple_xlate;
+       }
+
+       of_node_get(chip->of_node);
+}
+
+void of_gpiochip_remove(struct gpio_chip *chip)
+{
+       if (chip->of_node)
+               of_node_put(chip->of_node);
+}
+
+/* Private function for resolving node pointer to gpio_chip */
+static int of_gpiochip_is_match(struct gpio_chip *chip, void *data)
+{
+       return chip->of_node == data;
+}
+
+struct gpio_chip *of_node_to_gpiochip(struct device_node *np)
+{
+       return gpiochip_find(np, of_gpiochip_is_match);
+}
diff --git a/drivers/of/irq.c b/drivers/of/irq.c
new file mode 100644 (file)
index 0000000..6cfb307
--- /dev/null
@@ -0,0 +1,348 @@
+/*
+ *  Derived from arch/i386/kernel/irq.c
+ *    Copyright (C) 1992 Linus Torvalds
+ *  Adapted from arch/i386 by Gary Thomas
+ *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *  Updated and modified by Cort Dougan <cort@fsmlabs.com>
+ *    Copyright (C) 1996-2001 Cort Dougan
+ *  Adapted for Power Macintosh by Paul Mackerras
+ *    Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au)
+ *
+ * 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.
+ *
+ * This file contains the code used to make IRQ descriptions in the
+ * device tree to actual irq numbers on an interrupt controller
+ * driver.
+ */
+
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/string.h>
+
+/**
+ * irq_of_parse_and_map - Parse and map an interrupt into linux virq space
+ * @device: Device node of the device whose interrupt is to be mapped
+ * @index: Index of the interrupt to map
+ *
+ * This function is a wrapper that chains of_irq_map_one() and
+ * irq_create_of_mapping() to make things easier to callers
+ */
+unsigned int irq_of_parse_and_map(struct device_node *dev, int index)
+{
+       struct of_irq oirq;
+
+       if (of_irq_map_one(dev, index, &oirq))
+               return NO_IRQ;
+
+       return irq_create_of_mapping(oirq.controller, oirq.specifier,
+                                    oirq.size);
+}
+EXPORT_SYMBOL_GPL(irq_of_parse_and_map);
+
+/**
+ * of_irq_find_parent - Given a device node, find its interrupt parent node
+ * @child: pointer to device node
+ *
+ * Returns a pointer to the interrupt parent node, or NULL if the interrupt
+ * parent could not be determined.
+ */
+static struct device_node *of_irq_find_parent(struct device_node *child)
+{
+       struct device_node *p;
+       const phandle *parp;
+
+       if (!of_node_get(child))
+               return NULL;
+
+       do {
+               parp = of_get_property(child, "interrupt-parent", NULL);
+               if (parp == NULL)
+                       p = of_get_parent(child);
+               else {
+                       if (of_irq_workarounds & OF_IMAP_NO_PHANDLE)
+                               p = of_node_get(of_irq_dflt_pic);
+                       else
+                               p = of_find_node_by_phandle(*parp);
+               }
+               of_node_put(child);
+               child = p;
+       } while (p && of_get_property(p, "#interrupt-cells", NULL) == NULL);
+
+       return p;
+}
+
+/**
+ * of_irq_map_raw - Low level interrupt tree parsing
+ * @parent:    the device interrupt parent
+ * @intspec:   interrupt specifier ("interrupts" property of the device)
+ * @ointsize:   size of the passed in interrupt specifier
+ * @addr:      address specifier (start of "reg" property of the device)
+ * @out_irq:   structure of_irq filled by this function
+ *
+ * Returns 0 on success and a negative number on error
+ *
+ * This function is a low-level interrupt tree walking function. It
+ * can be used to do a partial walk with synthetized reg and interrupts
+ * properties, for example when resolving PCI interrupts when no device
+ * node exist for the parent.
+ */
+int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize,
+               const u32 *addr, struct of_irq *out_irq)
+{
+       struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL;
+       const __be32 *tmp, *imap, *imask;
+       u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0;
+       int imaplen, match, i;
+
+       pr_debug("of_irq_map_raw: par=%s,intspec=[0x%08x 0x%08x...],ointsize=%d\n",
+           parent->full_name, intspec[0], intspec[1], ointsize);
+
+       ipar = of_node_get(parent);
+
+       /* First get the #interrupt-cells property of the current cursor
+        * that tells us how to interpret the passed-in intspec. If there
+        * is none, we are nice and just walk up the tree
+        */
+       do {
+               tmp = of_get_property(ipar, "#interrupt-cells", NULL);
+               if (tmp != NULL) {
+                       intsize = be32_to_cpu(*tmp);
+                       break;
+               }
+               tnode = ipar;
+               ipar = of_irq_find_parent(ipar);
+               of_node_put(tnode);
+       } while (ipar);
+       if (ipar == NULL) {
+               pr_debug(" -> no parent found !\n");
+               goto fail;
+       }
+
+       pr_debug("of_irq_map_raw: ipar=%s, size=%d\n", ipar->full_name, intsize);
+
+       if (ointsize != intsize)
+               return -EINVAL;
+
+       /* Look for this #address-cells. We have to implement the old linux
+        * trick of looking for the parent here as some device-trees rely on it
+        */
+       old = of_node_get(ipar);
+       do {
+               tmp = of_get_property(old, "#address-cells", NULL);
+               tnode = of_get_parent(old);
+               of_node_put(old);
+               old = tnode;
+       } while (old && tmp == NULL);
+       of_node_put(old);
+       old = NULL;
+       addrsize = (tmp == NULL) ? 2 : be32_to_cpu(*tmp);
+
+       pr_debug(" -> addrsize=%d\n", addrsize);
+
+       /* Now start the actual "proper" walk of the interrupt tree */
+       while (ipar != NULL) {
+               /* Now check if cursor is an interrupt-controller and if it is
+                * then we are done
+                */
+               if (of_get_property(ipar, "interrupt-controller", NULL) !=
+                               NULL) {
+                       pr_debug(" -> got it !\n");
+                       for (i = 0; i < intsize; i++)
+                               out_irq->specifier[i] =
+                                               of_read_number(intspec +i, 1);
+                       out_irq->size = intsize;
+                       out_irq->controller = ipar;
+                       of_node_put(old);
+                       return 0;
+               }
+
+               /* Now look for an interrupt-map */
+               imap = of_get_property(ipar, "interrupt-map", &imaplen);
+               /* No interrupt map, check for an interrupt parent */
+               if (imap == NULL) {
+                       pr_debug(" -> no map, getting parent\n");
+                       newpar = of_irq_find_parent(ipar);
+                       goto skiplevel;
+               }
+               imaplen /= sizeof(u32);
+
+               /* Look for a mask */
+               imask = of_get_property(ipar, "interrupt-map-mask", NULL);
+
+               /* If we were passed no "reg" property and we attempt to parse
+                * an interrupt-map, then #address-cells must be 0.
+                * Fail if it's not.
+                */
+               if (addr == NULL && addrsize != 0) {
+                       pr_debug(" -> no reg passed in when needed !\n");
+                       goto fail;
+               }
+
+               /* Parse interrupt-map */
+               match = 0;
+               while (imaplen > (addrsize + intsize + 1) && !match) {
+                       /* Compare specifiers */
+                       match = 1;
+                       for (i = 0; i < addrsize && match; ++i) {
+                               u32 mask = imask ? imask[i] : 0xffffffffu;
+                               match = ((addr[i] ^ imap[i]) & mask) == 0;
+                       }
+                       for (; i < (addrsize + intsize) && match; ++i) {
+                               u32 mask = imask ? imask[i] : 0xffffffffu;
+                               match =
+                                  ((intspec[i-addrsize] ^ imap[i]) & mask) == 0;
+                       }
+                       imap += addrsize + intsize;
+                       imaplen -= addrsize + intsize;
+
+                       pr_debug(" -> match=%d (imaplen=%d)\n", match, imaplen);
+
+                       /* Get the interrupt parent */
+                       if (of_irq_workarounds & OF_IMAP_NO_PHANDLE)
+                               newpar = of_node_get(of_irq_dflt_pic);
+                       else
+                               newpar = of_find_node_by_phandle((phandle)*imap);
+                       imap++;
+                       --imaplen;
+
+                       /* Check if not found */
+                       if (newpar == NULL) {
+                               pr_debug(" -> imap parent not found !\n");
+                               goto fail;
+                       }
+
+                       /* Get #interrupt-cells and #address-cells of new
+                        * parent
+                        */
+                       tmp = of_get_property(newpar, "#interrupt-cells", NULL);
+                       if (tmp == NULL) {
+                               pr_debug(" -> parent lacks #interrupt-cells!\n");
+                               goto fail;
+                       }
+                       newintsize = be32_to_cpu(*tmp);
+                       tmp = of_get_property(newpar, "#address-cells", NULL);
+                       newaddrsize = (tmp == NULL) ? 0 : be32_to_cpu(*tmp);
+
+                       pr_debug(" -> newintsize=%d, newaddrsize=%d\n",
+                           newintsize, newaddrsize);
+
+                       /* Check for malformed properties */
+                       if (imaplen < (newaddrsize + newintsize))
+                               goto fail;
+
+                       imap += newaddrsize + newintsize;
+                       imaplen -= newaddrsize + newintsize;
+
+                       pr_debug(" -> imaplen=%d\n", imaplen);
+               }
+               if (!match)
+                       goto fail;
+
+               of_node_put(old);
+               old = of_node_get(newpar);
+               addrsize = newaddrsize;
+               intsize = newintsize;
+               intspec = imap - intsize;
+               addr = intspec - addrsize;
+
+       skiplevel:
+               /* Iterate again with new parent */
+               pr_debug(" -> new parent: %s\n", newpar ? newpar->full_name : "<>");
+               of_node_put(ipar);
+               ipar = newpar;
+               newpar = NULL;
+       }
+ fail:
+       of_node_put(ipar);
+       of_node_put(old);
+       of_node_put(newpar);
+
+       return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(of_irq_map_raw);
+
+/**
+ * of_irq_map_one - Resolve an interrupt for a device
+ * @device: the device whose interrupt is to be resolved
+ * @index: index of the interrupt to resolve
+ * @out_irq: structure of_irq filled by this function
+ *
+ * This function resolves an interrupt, walking the tree, for a given
+ * device-tree node. It's the high level pendant to of_irq_map_raw().
+ */
+int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq)
+{
+       struct device_node *p;
+       const u32 *intspec, *tmp, *addr;
+       u32 intsize, intlen;
+       int res = -EINVAL;
+
+       pr_debug("of_irq_map_one: dev=%s, index=%d\n", device->full_name, index);
+
+       /* OldWorld mac stuff is "special", handle out of line */
+       if (of_irq_workarounds & OF_IMAP_OLDWORLD_MAC)
+               return of_irq_map_oldworld(device, index, out_irq);
+
+       /* Get the interrupts property */
+       intspec = of_get_property(device, "interrupts", &intlen);
+       if (intspec == NULL)
+               return -EINVAL;
+       intlen /= sizeof(u32);
+
+       pr_debug(" intspec=%d intlen=%d\n", *intspec, intlen);
+
+       /* Get the reg property (if any) */
+       addr = of_get_property(device, "reg", NULL);
+
+       /* Look for the interrupt parent. */
+       p = of_irq_find_parent(device);
+       if (p == NULL)
+               return -EINVAL;
+
+       /* Get size of interrupt specifier */
+       tmp = of_get_property(p, "#interrupt-cells", NULL);
+       if (tmp == NULL)
+               goto out;
+       intsize = be32_to_cpu(*tmp);
+
+       pr_debug(" intsize=%d intlen=%d\n", intsize, intlen);
+
+       /* Check index */
+       if ((index + 1) * intsize > intlen)
+               goto out;
+
+       /* Get new specifier and map it */
+       res = of_irq_map_raw(p, intspec + index * intsize, intsize,
+                            addr, out_irq);
+ out:
+       of_node_put(p);
+       return res;
+}
+EXPORT_SYMBOL_GPL(of_irq_map_one);
+
+/**
+ * of_irq_to_resource - Decode a node's IRQ and return it as a resource
+ * @dev: pointer to device tree node
+ * @index: zero-based index of the irq
+ * @r: pointer to resource structure to return result into.
+ */
+int of_irq_to_resource(struct device_node *dev, int index, struct resource *r)
+{
+       int irq = irq_of_parse_and_map(dev, index);
+
+       /* Only dereference the resource if both the
+        * resource and the irq are valid. */
+       if (r && irq != NO_IRQ) {
+               r->start = r->end = irq;
+               r->flags = IORESOURCE_IRQ;
+               r->name = dev->full_name;
+       }
+
+       return irq;
+}
+EXPORT_SYMBOL_GPL(of_irq_to_resource);
index ab6522c..0a694de 100644 (file)
 #include <linux/i2c.h>
 #include <linux/of.h>
 #include <linux/of_i2c.h>
+#include <linux/of_irq.h>
 #include <linux/module.h>
 
-void of_register_i2c_devices(struct i2c_adapter *adap,
-                            struct device_node *adap_node)
+void of_i2c_register_devices(struct i2c_adapter *adap)
 {
        void *result;
        struct device_node *node;
 
-       for_each_child_of_node(adap_node, node) {
+       /* Only register child devices if the adapter has a node pointer set */
+       if (!adap->dev.of_node)
+               return;
+
+       dev_dbg(&adap->dev, "of_i2c: walking child nodes\n");
+
+       for_each_child_of_node(adap->dev.of_node, node) {
                struct i2c_board_info info = {};
                struct dev_archdata dev_ad = {};
                const __be32 *addr;
                int len;
 
-               if (of_modalias_node(node, info.type, sizeof(info.type)) < 0)
+               dev_dbg(&adap->dev, "of_i2c: register %s\n", node->full_name);
+
+               if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) {
+                       dev_err(&adap->dev, "of_i2c: modalias failure on %s\n",
+                               node->full_name);
                        continue;
+               }
 
                addr = of_get_property(node, "reg", &len);
-               if (!addr || len < sizeof(int) || *addr > (1 << 10) - 1) {
-                       printk(KERN_ERR
-                              "of-i2c: invalid i2c device entry\n");
+               if (!addr || (len < sizeof(int))) {
+                       dev_err(&adap->dev, "of_i2c: invalid reg on %s\n",
+                               node->full_name);
                        continue;
                }
 
-               info.irq = irq_of_parse_and_map(node, 0);
-
                info.addr = be32_to_cpup(addr);
+               if (info.addr > (1 << 10) - 1) {
+                       dev_err(&adap->dev, "of_i2c: invalid addr=%x on %s\n",
+                               info.addr, node->full_name);
+                       continue;
+               }
 
-               info.of_node = node;
+               info.irq = irq_of_parse_and_map(node, 0);
+               info.of_node = of_node_get(node);
                info.archdata = &dev_ad;
 
                request_module("%s", info.type);
 
                result = i2c_new_device(adap, &info);
                if (result == NULL) {
-                       printk(KERN_ERR
-                              "of-i2c: Failed to load driver for %s\n",
-                              info.type);
+                       dev_err(&adap->dev, "of_i2c: Failure registering %s\n",
+                               node->full_name);
+                       of_node_put(node);
                        irq_dispose_mapping(info.irq);
                        continue;
                }
-
-               /*
-                * Get the node to not lose the dev_archdata->of_node.
-                * Currently there is no way to put it back, as well as no
-                * of_unregister_i2c_devices() call.
-                */
-               of_node_get(node);
        }
 }
-EXPORT_SYMBOL(of_register_i2c_devices);
+EXPORT_SYMBOL(of_i2c_register_devices);
 
 static int of_dev_node_match(struct device *dev, void *data)
 {
index 42a6715..1fce00e 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/err.h>
 #include <linux/phy.h>
 #include <linux/of.h>
+#include <linux/of_irq.h>
 #include <linux/of_mdio.h>
 #include <linux/module.h>
 
index 5fed7e3..d504f1d 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/of.h>
 #include <linux/device.h>
 #include <linux/spi/spi.h>
+#include <linux/of_irq.h>
 #include <linux/of_spi.h>
 
 /**
index 7dacc1e..9d3d932 100644 (file)
 #include <linux/errno.h>
 #include <linux/module.h>
 #include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+#include <linux/of_address.h>
 #include <linux/of_device.h>
+#include <linux/of_irq.h>
 #include <linux/of_platform.h>
 
+#if defined(CONFIG_PPC_DCR)
+#include <asm/dcr.h>
+#endif
+
 extern struct device_attribute of_platform_device_attrs[];
 
 static int of_platform_bus_match(struct device *dev, struct device_driver *drv)
@@ -396,3 +404,263 @@ void of_unregister_driver(struct of_platform_driver *drv)
        driver_unregister(&drv->driver);
 }
 EXPORT_SYMBOL(of_unregister_driver);
+
+#if !defined(CONFIG_SPARC)
+/*
+ * The following routines scan a subtree and registers a device for
+ * each applicable node.
+ *
+ * Note: sparc doesn't use these routines because it has a different
+ * mechanism for creating devices from device tree nodes.
+ */
+
+/**
+ * of_device_make_bus_id - Use the device node data to assign a unique name
+ * @dev: pointer to device structure that is linked to a device tree node
+ *
+ * This routine will first try using either the dcr-reg or the reg property
+ * value to derive a unique name.  As a last resort it will use the node
+ * name followed by a unique number.
+ */
+static void of_device_make_bus_id(struct device *dev)
+{
+       static atomic_t bus_no_reg_magic;
+       struct device_node *node = dev->of_node;
+       const u32 *reg;
+       u64 addr;
+       int magic;
+
+#ifdef CONFIG_PPC_DCR
+       /*
+        * If it's a DCR based device, use 'd' for native DCRs
+        * and 'D' for MMIO DCRs.
+        */
+       reg = of_get_property(node, "dcr-reg", NULL);
+       if (reg) {
+#ifdef CONFIG_PPC_DCR_NATIVE
+               dev_set_name(dev, "d%x.%s", *reg, node->name);
+#else /* CONFIG_PPC_DCR_NATIVE */
+               u64 addr = of_translate_dcr_address(node, *reg, NULL);
+               if (addr != OF_BAD_ADDR) {
+                       dev_set_name(dev, "D%llx.%s",
+                                    (unsigned long long)addr, node->name);
+                       return;
+               }
+#endif /* !CONFIG_PPC_DCR_NATIVE */
+       }
+#endif /* CONFIG_PPC_DCR */
+
+       /*
+        * For MMIO, get the physical address
+        */
+       reg = of_get_property(node, "reg", NULL);
+       if (reg) {
+               addr = of_translate_address(node, reg);
+               if (addr != OF_BAD_ADDR) {
+                       dev_set_name(dev, "%llx.%s",
+                                    (unsigned long long)addr, node->name);
+                       return;
+               }
+       }
+
+       /*
+        * No BusID, use the node name and add a globally incremented
+        * counter (and pray...)
+        */
+       magic = atomic_add_return(1, &bus_no_reg_magic);
+       dev_set_name(dev, "%s.%d", node->name, magic - 1);
+}
+
+/**
+ * of_device_alloc - Allocate and initialize an of_device
+ * @np: device node to assign to device
+ * @bus_id: Name to assign to the device.  May be null to use default name.
+ * @parent: Parent device.
+ */
+struct of_device *of_device_alloc(struct device_node *np,
+                                 const char *bus_id,
+                                 struct device *parent)
+{
+       struct of_device *dev;
+       int rc, i, num_reg = 0, num_irq = 0;
+       struct resource *res, temp_res;
+
+       /* First count how many resources are needed */
+       while (of_address_to_resource(np, num_reg, &temp_res) == 0)
+               num_reg++;
+       while (of_irq_to_resource(np, num_irq, &temp_res) != NO_IRQ)
+               num_irq++;
+
+       /* Allocate memory for both the struct device and the resource table */
+       dev = kzalloc(sizeof(*dev) + (sizeof(*res) * (num_reg + num_irq)),
+                     GFP_KERNEL);
+       if (!dev)
+               return NULL;
+       res = (struct resource *) &dev[1];
+
+       /* Populate the resource table */
+       if (num_irq || num_reg) {
+               dev->num_resources = num_reg + num_irq;
+               dev->resource = res;
+               for (i = 0; i < num_reg; i++, res++) {
+                       rc = of_address_to_resource(np, i, res);
+                       WARN_ON(rc);
+               }
+               for (i = 0; i < num_irq; i++, res++) {
+                       rc = of_irq_to_resource(np, i, res);
+                       WARN_ON(rc == NO_IRQ);
+               }
+       }
+
+       dev->dev.of_node = of_node_get(np);
+#if defined(CONFIG_PPC) || defined(CONFIG_MICROBLAZE)
+       dev->dev.dma_mask = &dev->archdata.dma_mask;
+#endif
+       dev->dev.parent = parent;
+       dev->dev.release = of_release_dev;
+
+       if (bus_id)
+               dev_set_name(&dev->dev, "%s", bus_id);
+       else
+               of_device_make_bus_id(&dev->dev);
+
+       return dev;
+}
+EXPORT_SYMBOL(of_device_alloc);
+
+/**
+ * of_platform_device_create - Alloc, initialize and register an of_device
+ * @np: pointer to node to create device for
+ * @bus_id: name to assign device
+ * @parent: Linux device model parent device.
+ */
+struct of_device *of_platform_device_create(struct device_node *np,
+                                           const char *bus_id,
+                                           struct device *parent)
+{
+       struct of_device *dev;
+
+       dev = of_device_alloc(np, bus_id, parent);
+       if (!dev)
+               return NULL;
+
+#if defined(CONFIG_PPC) || defined(CONFIG_MICROBLAZE)
+       dev->archdata.dma_mask = 0xffffffffUL;
+#endif
+       dev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+       dev->dev.bus = &of_platform_bus_type;
+
+       /* We do not fill the DMA ops for platform devices by default.
+        * This is currently the responsibility of the platform code
+        * to do such, possibly using a device notifier
+        */
+
+       if (of_device_register(dev) != 0) {
+               of_device_free(dev);
+               return NULL;
+       }
+
+       return dev;
+}
+EXPORT_SYMBOL(of_platform_device_create);
+
+/**
+ * of_platform_bus_create - Create an OF device for a bus node and all its
+ * children. Optionally recursively instantiate matching busses.
+ * @bus: device node of the bus to instantiate
+ * @matches: match table, NULL to use the default, OF_NO_DEEP_PROBE to
+ * disallow recursive creation of child busses
+ */
+static int of_platform_bus_create(const struct device_node *bus,
+                                 const struct of_device_id *matches,
+                                 struct device *parent)
+{
+       struct device_node *child;
+       struct of_device *dev;
+       int rc = 0;
+
+       for_each_child_of_node(bus, child) {
+               pr_debug("   create child: %s\n", child->full_name);
+               dev = of_platform_device_create(child, NULL, parent);
+               if (dev == NULL)
+                       rc = -ENOMEM;
+               else if (!of_match_node(matches, child))
+                       continue;
+               if (rc == 0) {
+                       pr_debug("   and sub busses\n");
+                       rc = of_platform_bus_create(child, matches, &dev->dev);
+               }
+               if (rc) {
+                       of_node_put(child);
+                       break;
+               }
+       }
+       return rc;
+}
+
+/**
+ * of_platform_bus_probe - Probe the device-tree for platform busses
+ * @root: parent of the first level to probe or NULL for the root of the tree
+ * @matches: match table, NULL to use the default
+ * @parent: parent to hook devices from, NULL for toplevel
+ *
+ * Note that children of the provided root are not instantiated as devices
+ * unless the specified root itself matches the bus list and is not NULL.
+ */
+int of_platform_bus_probe(struct device_node *root,
+                         const struct of_device_id *matches,
+                         struct device *parent)
+{
+       struct device_node *child;
+       struct of_device *dev;
+       int rc = 0;
+
+       if (matches == NULL)
+               matches = of_default_bus_ids;
+       if (matches == OF_NO_DEEP_PROBE)
+               return -EINVAL;
+       if (root == NULL)
+               root = of_find_node_by_path("/");
+       else
+               of_node_get(root);
+       if (root == NULL)
+               return -EINVAL;
+
+       pr_debug("of_platform_bus_probe()\n");
+       pr_debug(" starting at: %s\n", root->full_name);
+
+       /* Do a self check of bus type, if there's a match, create
+        * children
+        */
+       if (of_match_node(matches, root)) {
+               pr_debug(" root match, create all sub devices\n");
+               dev = of_platform_device_create(root, NULL, parent);
+               if (dev == NULL) {
+                       rc = -ENOMEM;
+                       goto bail;
+               }
+               pr_debug(" create all sub busses\n");
+               rc = of_platform_bus_create(root, matches, &dev->dev);
+               goto bail;
+       }
+       for_each_child_of_node(root, child) {
+               if (!of_match_node(matches, child))
+                       continue;
+
+               pr_debug("  match: %s\n", child->full_name);
+               dev = of_platform_device_create(child, NULL, parent);
+               if (dev == NULL)
+                       rc = -ENOMEM;
+               else
+                       rc = of_platform_bus_create(child, matches, &dev->dev);
+               if (rc) {
+                       of_node_put(child);
+                       break;
+               }
+       }
+ bail:
+       of_node_put(root);
+       return rc;
+}
+EXPORT_SYMBOL(of_platform_bus_probe);
+#endif /* !CONFIG_SPARC */
index 9a5b4b8..3cdfe96 100644 (file)
@@ -295,7 +295,7 @@ static int __devinit bpp_probe(struct of_device *op, const struct of_device_id *
        void __iomem *base;
        struct parport *p;
 
-       irq = op->irqs[0];
+       irq = op->archdata.irqs[0];
        base = of_ioremap(&op->resource[0], 0,
                          resource_size(&op->resource[0]),
                          "sunbpp");
index 8bfdd63..40d7a1f 100644 (file)
@@ -317,7 +317,7 @@ static struct bbc_i2c_bus * __init attach_one_i2c(struct of_device *op, int inde
 
        bp->waiting = 0;
        init_waitqueue_head(&bp->wq);
-       if (request_irq(op->irqs[0], bbc_i2c_interrupt,
+       if (request_irq(op->archdata.irqs[0], bbc_i2c_interrupt,
                        IRQF_SHARED, "bbc_i2c", bp))
                goto fail;
 
@@ -373,7 +373,7 @@ static int __devinit bbc_i2c_probe(struct of_device *op,
 
        err = bbc_envctrl_init(bp);
        if (err) {
-               free_irq(op->irqs[0], bp);
+               free_irq(op->archdata.irqs[0], bp);
                if (bp->i2c_bussel_reg)
                        of_iounmap(&op->resource[0], bp->i2c_bussel_reg, 1);
                if (bp->i2c_control_regs)
@@ -392,7 +392,7 @@ static int __devexit bbc_i2c_remove(struct of_device *op)
 
        bbc_envctrl_cleanup(bp);
 
-       free_irq(op->irqs[0], bp);
+       free_irq(op->archdata.irqs[0], bp);
 
        if (bp->i2c_bussel_reg)
                of_iounmap(&op->resource[0], bp->i2c_bussel_reg, 1);
index 5f25366..b8b40e9 100644 (file)
@@ -367,7 +367,7 @@ static int __devinit uctrl_probe(struct of_device *op,
                goto out_free;
        }
 
-       p->irq = op->irqs[0];
+       p->irq = op->archdata.irqs[0];
        err = request_irq(p->irq, uctrl_interrupt, 0, "uctrl", p);
        if (err) {
                printk(KERN_ERR "uctrl: Unable to register irq.\n");
index ca5c15c..3f5b541 100644 (file)
@@ -729,7 +729,7 @@ static int __devinit qpti_register_irq(struct qlogicpti *qpti)
 {
        struct of_device *op = qpti->op;
 
-       qpti->qhost->irq = qpti->irq = op->irqs[0];
+       qpti->qhost->irq = qpti->irq = op->archdata.irqs[0];
 
        /* We used to try various overly-clever things to
         * reduce the interrupt processing overhead on
@@ -1302,7 +1302,7 @@ static int __devinit qpti_sbus_probe(struct of_device *op, const struct of_devic
        /* Sometimes Antares cards come up not completely
         * setup, and we get a report of a zero IRQ.
         */
-       if (op->irqs[0] == 0)
+       if (op->archdata.irqs[0] == 0)
                return -ENODEV;
 
        host = scsi_host_alloc(tpnt, sizeof(struct qlogicpti));
index 386dd9d..ddc221a 100644 (file)
@@ -116,7 +116,7 @@ static int __devinit esp_sbus_register_irq(struct esp *esp)
        struct Scsi_Host *host = esp->host;
        struct of_device *op = esp->dev;
 
-       host->irq = op->irqs[0];
+       host->irq = op->archdata.irqs[0];
        return request_irq(host->irq, scsi_esp_intr, IRQF_SHARED, "ESP", esp);
 }
 
index 890f917..36e2448 100644 (file)
@@ -525,7 +525,7 @@ static int __devinit hv_probe(struct of_device *op, const struct of_device_id *m
        unsigned long minor;
        int err;
 
-       if (op->irqs[0] == 0xffffffff)
+       if (op->archdata.irqs[0] == 0xffffffff)
                return -ENODEV;
 
        port = kzalloc(sizeof(struct uart_port), GFP_KERNEL);
@@ -557,7 +557,7 @@ static int __devinit hv_probe(struct of_device *op, const struct of_device_id *m
 
        port->membase = (unsigned char __iomem *) __pa(port);
 
-       port->irq = op->irqs[0];
+       port->irq = op->archdata.irqs[0];
 
        port->dev = &op->dev;
 
index 5e81bc6..0a7dd68 100644 (file)
@@ -969,7 +969,7 @@ static int __devinit sunsab_init_one(struct uart_sunsab_port *up,
                return -ENOMEM;
        up->regs = (union sab82532_async_regs __iomem *) up->port.membase;
 
-       up->port.irq = op->irqs[0];
+       up->port.irq = op->archdata.irqs[0];
 
        up->port.fifosize = SAB82532_XMIT_FIFO_SIZE;
        up->port.iotype = UPIO_MEM;
index ffbf455..5deafc8 100644 (file)
@@ -1443,7 +1443,7 @@ static int __devinit su_probe(struct of_device *op, const struct of_device_id *m
                return -ENOMEM;
        }
 
-       up->port.irq = op->irqs[0];
+       up->port.irq = op->archdata.irqs[0];
 
        up->port.dev = &op->dev;
 
index f9a24f4..fcbe20d 100644 (file)
@@ -1426,7 +1426,7 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m
        rp = sunzilog_chip_regs[inst];
 
        if (zilog_irq == -1)
-               zilog_irq = op->irqs[0];
+               zilog_irq = op->archdata.irqs[0];
 
        up = &sunzilog_port_table[inst * 2];
 
@@ -1434,7 +1434,7 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m
        up[0].port.mapbase = op->resource[0].start + 0x00;
        up[0].port.membase = (void __iomem *) &rp->channelA;
        up[0].port.iotype = UPIO_MEM;
-       up[0].port.irq = op->irqs[0];
+       up[0].port.irq = op->archdata.irqs[0];
        up[0].port.uartclk = ZS_CLOCK;
        up[0].port.fifosize = 1;
        up[0].port.ops = &sunzilog_pops;
@@ -1451,7 +1451,7 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m
        up[1].port.mapbase = op->resource[0].start + 0x04;
        up[1].port.membase = (void __iomem *) &rp->channelB;
        up[1].port.iotype = UPIO_MEM;
-       up[1].port.irq = op->irqs[0];
+       up[1].port.irq = op->archdata.irqs[0];
        up[1].port.uartclk = ZS_CLOCK;
        up[1].port.fifosize = 1;
        up[1].port.ops = &sunzilog_pops;
@@ -1492,12 +1492,12 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m
                       "is a %s\n",
       &