Merge branch 'x86-platform-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 16 Mar 2011 03:01:36 +0000 (20:01 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 16 Mar 2011 03:01:36 +0000 (20:01 -0700)
* 'x86-platform-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (27 commits)
  x86: Clean up apic.c and apic.h
  x86: Remove superflous goal definition of tsc_sync
  x86: dt: Correct local apic documentation in device tree bindings
  x86: dt: Cleanup local apic setup
  x86: dt: Fix OLPC=y/INTEL_CE=n build
  rtc: cmos: Add OF bindings
  x86: ce4100: Use OF to setup devices
  x86: ioapic: Add OF bindings for IO_APIC
  x86: dtb: Add generic bus probe
  x86: dtb: Add support for PCI devices backed by dtb nodes
  x86: dtb: Add device tree support for HPET
  x86: dtb: Add early parsing of IO_APIC
  x86: dtb: Add irq domain abstraction
  x86: dtb: Add a device tree for CE4100
  x86: Add device tree support
  x86: e820: Remove conditional early mapping in parse_e820_ext
  x86: OLPC: Make OLPC=n build again
  x86: OLPC: Remove extra OLPC_OPENFIRMWARE_DT indirection
  x86: OLPC: Cleanup config maze completely
  x86: OLPC: Hide OLPC_OPENFIRMWARE config switch
  ...

Fix up conflicts in arch/x86/platform/ce4100/ce4100.c

56 files changed:
Documentation/devicetree/bindings/i2c/ce4100-i2c.txt [new file with mode: 0644]
Documentation/devicetree/bindings/rtc/rtc-cmos.txt [new file with mode: 0644]
Documentation/devicetree/bindings/x86/ce4100.txt [new file with mode: 0644]
Documentation/devicetree/bindings/x86/interrupt.txt [new file with mode: 0644]
Documentation/devicetree/bindings/x86/timer.txt [new file with mode: 0644]
Documentation/devicetree/booting-without-of.txt
arch/microblaze/include/asm/pci-bridge.h
arch/microblaze/include/asm/prom.h
arch/microblaze/kernel/prom_parse.c
arch/microblaze/pci/pci-common.c
arch/powerpc/include/asm/pci-bridge.h
arch/powerpc/include/asm/prom.h
arch/powerpc/kernel/pci-common.c
arch/powerpc/kernel/prom_parse.c
arch/x86/Kconfig
arch/x86/include/asm/apic.h
arch/x86/include/asm/bootparam.h
arch/x86/include/asm/e820.h
arch/x86/include/asm/irq.h
arch/x86/include/asm/irq_controller.h [new file with mode: 0644]
arch/x86/include/asm/olpc_ofw.h
arch/x86/include/asm/prom.h
arch/x86/include/asm/x86_init.h
arch/x86/kernel/Makefile
arch/x86/kernel/apb_timer.c
arch/x86/kernel/apic/apic.c
arch/x86/kernel/devicetree.c [new file with mode: 0644]
arch/x86/kernel/e820.c
arch/x86/kernel/head_32.S
arch/x86/kernel/irq.c
arch/x86/kernel/irqinit.c
arch/x86/kernel/rtc.c
arch/x86/kernel/setup.c
arch/x86/kernel/x86_init.c
arch/x86/pci/ce4100.c
arch/x86/platform/ce4100/ce4100.c
arch/x86/platform/ce4100/falconfalls.dts [new file with mode: 0644]
arch/x86/platform/mrst/mrst.c
arch/x86/platform/mrst/vrtc.c
arch/x86/platform/olpc/Makefile
drivers/i2c/busses/i2c-ocores.c
drivers/i2c/i2c-core.c
drivers/mmc/host/mmc_spi.c
drivers/net/ethoc.c
drivers/of/Kconfig
drivers/of/Makefile
drivers/of/of_pci.c [new file with mode: 0644]
drivers/rtc/rtc-cmos.c
drivers/rtc/rtc-mrst.c
drivers/spi/pxa2xx_spi.c
drivers/spi/pxa2xx_spi_pci.c
drivers/spi/xilinx_spi.c
include/linux/device.h
include/linux/i2c.h
include/linux/of.h
include/linux/of_pci.h [new file with mode: 0644]

diff --git a/Documentation/devicetree/bindings/i2c/ce4100-i2c.txt b/Documentation/devicetree/bindings/i2c/ce4100-i2c.txt
new file mode 100644 (file)
index 0000000..569b162
--- /dev/null
@@ -0,0 +1,93 @@
+CE4100 I2C
+----------
+
+CE4100 has one PCI device which is described as the I2C-Controller. This
+PCI device has three PCI-bars, each bar contains a complete I2C
+controller. So we have a total of three independent I2C-Controllers
+which share only an interrupt line.
+The driver is probed via the PCI-ID and is gathering the information of
+attached devices from the devices tree.
+Grant Likely recommended to use the ranges property to map the PCI-Bar
+number to its physical address and to use this to find the child nodes
+of the specific I2C controller. This were his exact words:
+
+       Here's where the magic happens.  Each entry in
+       ranges describes how the parent pci address space
+       (middle group of 3) is translated to the local
+       address space (first group of 2) and the size of
+       each range (last cell).  In this particular case,
+       the first cell of the local address is chosen to be
+       1:1 mapped to the BARs, and the second is the
+       offset from be base of the BAR (which would be
+       non-zero if you had 2 or more devices mapped off
+       the same BAR)
+
+       ranges allows the address mapping to be described
+       in a way that the OS can interpret without
+       requiring custom device driver code.
+
+This is an example which is used on FalconFalls:
+------------------------------------------------
+       i2c-controller@b,2 {
+               #address-cells = <2>;
+               #size-cells = <1>;
+               compatible = "pci8086,2e68.2",
+                               "pci8086,2e68",
+                               "pciclass,ff0000",
+                               "pciclass,ff00";
+
+               reg = <0x15a00 0x0 0x0 0x0 0x0>;
+               interrupts = <16 1>;
+
+               /* as described by Grant, the first number in the group of
+               * three is the bar number followed by the 64bit bar address
+               * followed by size of the mapping. The bar address
+               * requires also a valid translation in parents ranges
+               * property.
+               */
+               ranges = <0 0   0x02000000 0 0xdffe0500 0x100
+                         1 0   0x02000000 0 0xdffe0600 0x100
+                         2 0   0x02000000 0 0xdffe0700 0x100>;
+
+               i2c@0 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "intel,ce4100-i2c-controller";
+
+                       /* The first number in the reg property is the
+                       * number of the bar
+                       */
+                       reg = <0 0 0x100>;
+
+                       /* This I2C controller has no devices */
+               };
+
+               i2c@1 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "intel,ce4100-i2c-controller";
+                       reg = <1 0 0x100>;
+
+                       /* This I2C controller has one gpio controller */
+                       gpio@26 {
+                               #gpio-cells = <2>;
+                               compatible = "ti,pcf8575";
+                               reg = <0x26>;
+                               gpio-controller;
+                       };
+               };
+
+               i2c@2 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "intel,ce4100-i2c-controller";
+                       reg = <2 0 0x100>;
+
+                       gpio@26 {
+                               #gpio-cells = <2>;
+                               compatible = "ti,pcf8575";
+                               reg = <0x26>;
+                               gpio-controller;
+                       };
+               };
+       };
diff --git a/Documentation/devicetree/bindings/rtc/rtc-cmos.txt b/Documentation/devicetree/bindings/rtc/rtc-cmos.txt
new file mode 100644 (file)
index 0000000..7382989
--- /dev/null
@@ -0,0 +1,28 @@
+ Motorola mc146818 compatible RTC
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Required properties:
+  - compatible : "motorola,mc146818"
+  - reg : should contain registers location and length.
+
+Optional properties:
+  - interrupts : should contain interrupt.
+  - interrupt-parent : interrupt source phandle.
+  - ctrl-reg : Contains the initial value of the control register also
+    called "Register B".
+  - freq-reg : Contains the initial value of the frequency register also
+    called "Regsiter A".
+
+"Register A" and "B" are usually initialized by the firmware (BIOS for
+instance). If this is not done, it can be performed by the driver.
+
+ISA Example:
+
+       rtc@70 {
+                compatible = "motorola,mc146818";
+                interrupts = <8 3>;
+                interrupt-parent = <&ioapic1>;
+                ctrl-reg = <2>;
+                freq-reg = <0x26>;
+                reg = <1 0x70 2>;
+        };
diff --git a/Documentation/devicetree/bindings/x86/ce4100.txt b/Documentation/devicetree/bindings/x86/ce4100.txt
new file mode 100644 (file)
index 0000000..b49ae59
--- /dev/null
@@ -0,0 +1,38 @@
+CE4100 Device Tree Bindings
+---------------------------
+
+The CE4100 SoC uses for in core peripherals the following compatible
+format: <vendor>,<chip>-<device>.
+Many of the "generic" devices like HPET or IO APIC have the ce4100
+name in their compatible property because they first appeared in this
+SoC.
+
+The CPU node
+------------
+       cpu@0 {
+               device_type = "cpu";
+               compatible = "intel,ce4100";
+               reg = <0>;
+               lapic = <&lapic0>;
+       };
+
+The reg property describes the CPU number. The lapic property points to
+the local APIC timer.
+
+The SoC node
+------------
+
+This node describes the in-core peripherals. Required property:
+  compatible = "intel,ce4100-cp";
+
+The PCI node
+------------
+This node describes the PCI bus on the SoC. Its property should be
+  compatible = "intel,ce4100-pci", "pci";
+
+If the OS is using the IO-APIC for interrupt routing then the reported
+interrupt numbers for devices is no longer true. In order to obtain the
+correct interrupt number, the child node which represents the device has
+to contain the interrupt property. Besides the interrupt property it has
+to contain at least the reg property containing the PCI bus address and
+compatible property according to "PCI Bus Binding Revision 2.1".
diff --git a/Documentation/devicetree/bindings/x86/interrupt.txt b/Documentation/devicetree/bindings/x86/interrupt.txt
new file mode 100644 (file)
index 0000000..7d19f49
--- /dev/null
@@ -0,0 +1,26 @@
+Interrupt chips
+---------------
+
+* Intel I/O Advanced Programmable Interrupt Controller (IO APIC)
+
+  Required properties:
+  --------------------
+     compatible = "intel,ce4100-ioapic";
+     #interrupt-cells = <2>;
+
+  Device's interrupt property:
+
+     interrupts = <P S>;
+
+  The first number (P) represents the interrupt pin which is wired to the
+  IO APIC. The second number (S) represents the sense of interrupt which
+  should be configured and can be one of:
+    0 - Edge Rising
+    1 - Level Low
+    2 - Level High
+    3 - Edge Falling
+
+* Local APIC
+  Required property:
+
+     compatible = "intel,ce4100-lapic";
diff --git a/Documentation/devicetree/bindings/x86/timer.txt b/Documentation/devicetree/bindings/x86/timer.txt
new file mode 100644 (file)
index 0000000..c688af5
--- /dev/null
@@ -0,0 +1,6 @@
+Timers
+------
+
+* High Precision Event Timer (HPET)
+  Required property:
+     compatible = "intel,ce4100-hpet";
index 28b1c9d3d3514b9afdc27c92bd585b9982ecb6db..55fd2623445b5d1ea02ab65a5a445eb0260e6d23 100644 (file)
@@ -13,6 +13,7 @@ Table of Contents
 
   I - Introduction
     1) Entry point for arch/powerpc
+    2) Entry point for arch/x86
 
   II - The DT block format
     1) Header
@@ -225,6 +226,25 @@ it with special cases.
   cannot support both configurations with Book E and configurations
   with classic Powerpc architectures.
 
+2) Entry point for arch/x86
+-------------------------------
+
+  There is one single 32bit entry point to the kernel at code32_start,
+  the decompressor (the real mode entry point goes to the same  32bit
+  entry point once it switched into protected mode). That entry point
+  supports one calling convention which is documented in
+  Documentation/x86/boot.txt
+  The physical pointer to the device-tree block (defined in chapter II)
+  is passed via setup_data which requires at least boot protocol 2.09.
+  The type filed is defined as
+
+  #define SETUP_DTB                      2
+
+  This device-tree is used as an extension to the "boot page". As such it
+  does not parse / consider data which is already covered by the boot
+  page. This includes memory size, reserved ranges, command line arguments
+  or initrd address. It simply holds information which can not be retrieved
+  otherwise like interrupt routing or a list of devices behind an I2C bus.
 
 II - The DT block format
 ========================
index 0c68764ab547ea938f2e5210d37f27fd597b4b23..10717669e0c2eca271a67ee032532d8ee0311e20 100644 (file)
@@ -104,11 +104,22 @@ struct pci_controller {
        int global_number;      /* PCI domain number */
 };
 
+#ifdef CONFIG_PCI
 static inline struct pci_controller *pci_bus_to_host(const struct pci_bus *bus)
 {
        return bus->sysdata;
 }
 
+static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
+{
+       struct pci_controller *host;
+
+       if (bus->self)
+               return pci_device_to_OF_node(bus->self);
+       host = pci_bus_to_host(bus);
+       return host ? host->dn : NULL;
+}
+
 static inline int isa_vaddr_is_ioport(void __iomem *address)
 {
        /* No specific ISA handling on ppc32 at this stage, it
@@ -116,6 +127,7 @@ static inline int isa_vaddr_is_ioport(void __iomem *address)
         */
        return 0;
 }
+#endif /* CONFIG_PCI */
 
 /* These are used for config access before all the PCI probing
    has been done. */
index 2e72af078b059dadd7512967aa14d6bf51d0bd0f..d0890d36ef617f7e85176016330c3dda5d244db7 100644 (file)
@@ -64,21 +64,6 @@ extern void kdump_move_device_tree(void);
 /* CPU OF node matching */
 struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
 
-/**
- * of_irq_map_pci - Resolve the interrupt for a PCI device
- * @pdev:      the device whose interrupt is to be resolved
- * @out_irq:   structure of_irq filled by this function
- *
- * This function resolves the PCI interrupt for a given PCI device. If a
- * device-node exists for a given pci_dev, it will use normal OF tree
- * walking. If not, it will implement standard swizzling and walk up the
- * PCI tree until an device-node is found, at which point it will finish
- * resolving using the OF tree walking.
- */
-struct pci_dev;
-struct of_irq;
-extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
-
 #endif /* __ASSEMBLY__ */
 #endif /* __KERNEL__ */
 
index 9ae24f4b882bfe792e6657c867c8af32b00908ee..47187cc2cf008c38e14c09667a7fff7b436d5dee 100644 (file)
@@ -2,88 +2,11 @@
 
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/pci_regs.h>
 #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 CONFIG_PCI
-int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
-{
-       struct device_node *dn, *ppnode;
-       struct pci_dev *ppdev;
-       u32 lspec;
-       u32 laddr[3];
-       u8 pin;
-       int rc;
-
-       /* Check if we have a device node, if yes, fallback to standard OF
-        * parsing
-        */
-       dn = pci_device_to_OF_node(pdev);
-       if (dn)
-               return of_irq_map_one(dn, 0, out_irq);
-
-       /* Ok, we don't, time to have fun. Let's start by building up an
-        * interrupt spec.  we assume #interrupt-cells is 1, which is standard
-        * for PCI. If you do different, then don't use that routine.
-        */
-       rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
-       if (rc != 0)
-               return rc;
-       /* No pin, exit */
-       if (pin == 0)
-               return -ENODEV;
-
-       /* Now we walk up the PCI tree */
-       lspec = pin;
-       for (;;) {
-               /* Get the pci_dev of our parent */
-               ppdev = pdev->bus->self;
-
-               /* Ouch, it's a host bridge... */
-               if (ppdev == NULL) {
-                       struct pci_controller *host;
-                       host = pci_bus_to_host(pdev->bus);
-                       ppnode = host ? host->dn : NULL;
-                       /* No node for host bridge ? give up */
-                       if (ppnode == NULL)
-                               return -EINVAL;
-               } else
-                       /* We found a P2P bridge, check if it has a node */
-                       ppnode = pci_device_to_OF_node(ppdev);
-
-               /* Ok, we have found a parent with a device-node, hand over to
-                * the OF parsing code.
-                * We build a unit address from the linux device to be used for
-                * resolution. Note that we use the linux bus number which may
-                * not match your firmware bus numbering.
-                * Fortunately, in most cases, interrupt-map-mask doesn't
-                * include the bus number as part of the matching.
-                * You should still be careful about that though if you intend
-                * to rely on this function (you ship  a firmware that doesn't
-                * create device nodes for all PCI devices).
-                */
-               if (ppnode)
-                       break;
-
-               /* We can only get here if we hit a P2P bridge with no node,
-                * let's do standard swizzling and try again
-                */
-               lspec = pci_swizzle_interrupt_pin(pdev, lspec);
-               pdev = ppdev;
-       }
-
-       laddr[0] = (pdev->bus->number << 16)
-               | (pdev->devfn << 8);
-       laddr[1]  = laddr[2] = 0;
-       return of_irq_map_raw(ppnode, &lspec, 1, laddr, out_irq);
-}
-EXPORT_SYMBOL_GPL(of_irq_map_pci);
-#endif /* CONFIG_PCI */
 
 void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
                unsigned long *busno, unsigned long *phys, unsigned long *size)
index e363615d67989da66ca3d8d2e981bddbb34edc47..1e01a1253631f11a548ddd817a5a99f8f19b130f 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/slab.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/of_pci.h>
 
 #include <asm/processor.h>
 #include <asm/io.h>
index 51e9e6f90d12110aa70ae04cb8c922164947c121..edeb80fdd2c3cc10ffea07ddf63e79586cf7995a 100644 (file)
@@ -171,6 +171,16 @@ static inline struct pci_controller *pci_bus_to_host(const struct pci_bus *bus)
        return bus->sysdata;
 }
 
+static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
+{
+       struct pci_controller *host;
+
+       if (bus->self)
+               return pci_device_to_OF_node(bus->self);
+       host = pci_bus_to_host(bus);
+       return host ? host->dn : NULL;
+}
+
 static inline int isa_vaddr_is_ioport(void __iomem *address)
 {
        /* No specific ISA handling on ppc32 at this stage, it
index d72757585595d956ee5eb597432446d2b836477e..c189aa5fe1f44d8a96f34d78d415a3f30ae69a2a 100644 (file)
@@ -70,21 +70,6 @@ static inline int of_node_to_nid(struct device_node *device) { return 0; }
 #endif
 #define of_node_to_nid of_node_to_nid
 
-/**
- * of_irq_map_pci - Resolve the interrupt for a PCI device
- * @pdev:      the device whose interrupt is to be resolved
- * @out_irq:   structure of_irq filled by this function
- *
- * This function resolves the PCI interrupt for a given PCI device. If a
- * device-node exists for a given pci_dev, it will use normal OF tree
- * walking. If not, it will implement standard swizzling and walk up the
- * PCI tree until an device-node is found, at which point it will finish
- * resolving using the OF tree walking.
- */
-struct pci_dev;
-struct of_irq;
-extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
-
 extern void of_instantiate_rtc(void);
 
 /* These includes are put at the bottom because they may contain things
index 10a44e68ef11eca50957467569b052fd796d6936..eb341be9a4d934505017e5e96af994b51076a91f 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/init.h>
 #include <linux/bootmem.h>
 #include <linux/of_address.h>
+#include <linux/of_pci.h>
 #include <linux/mm.h>
 #include <linux/list.h>
 #include <linux/syscalls.h>
index c2b7a07cc3d3f54aeb22f7abe061c3ab6943708c..47187cc2cf008c38e14c09667a7fff7b436d5dee 100644 (file)
@@ -2,95 +2,11 @@
 
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/pci_regs.h>
 #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 CONFIG_PCI
-int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
-{
-       struct device_node *dn, *ppnode;
-       struct pci_dev *ppdev;
-       u32 lspec;
-       u32 laddr[3];
-       u8 pin;
-       int rc;
-
-       /* Check if we have a device node, if yes, fallback to standard OF
-        * parsing
-        */
-       dn = pci_device_to_OF_node(pdev);
-       if (dn) {
-               rc = of_irq_map_one(dn, 0, out_irq);
-               if (!rc)
-                       return rc;
-       }
-
-       /* Ok, we don't, time to have fun. Let's start by building up an
-        * interrupt spec.  we assume #interrupt-cells is 1, which is standard
-        * for PCI. If you do different, then don't use that routine.
-        */
-       rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
-       if (rc != 0)
-               return rc;
-       /* No pin, exit */
-       if (pin == 0)
-               return -ENODEV;
-
-       /* Now we walk up the PCI tree */
-       lspec = pin;
-       for (;;) {
-               /* Get the pci_dev of our parent */
-               ppdev = pdev->bus->self;
-
-               /* Ouch, it's a host bridge... */
-               if (ppdev == NULL) {
-#ifdef CONFIG_PPC64
-                       ppnode = pci_bus_to_OF_node(pdev->bus);
-#else
-                       struct pci_controller *host;
-                       host = pci_bus_to_host(pdev->bus);
-                       ppnode = host ? host->dn : NULL;
-#endif
-                       /* No node for host bridge ? give up */
-                       if (ppnode == NULL)
-                               return -EINVAL;
-               } else
-                       /* We found a P2P bridge, check if it has a node */
-                       ppnode = pci_device_to_OF_node(ppdev);
-
-               /* Ok, we have found a parent with a device-node, hand over to
-                * the OF parsing code.
-                * We build a unit address from the linux device to be used for
-                * resolution. Note that we use the linux bus number which may
-                * not match your firmware bus numbering.
-                * Fortunately, in most cases, interrupt-map-mask doesn't include
-                * the bus number as part of the matching.
-                * You should still be careful about that though if you intend
-                * to rely on this function (you ship  a firmware that doesn't
-                * create device nodes for all PCI devices).
-                */
-               if (ppnode)
-                       break;
-
-               /* We can only get here if we hit a P2P bridge with no node,
-                * let's do standard swizzling and try again
-                */
-               lspec = pci_swizzle_interrupt_pin(pdev, lspec);
-               pdev = ppdev;
-       }
-
-       laddr[0] = (pdev->bus->number << 16)
-               | (pdev->devfn << 8);
-       laddr[1]  = laddr[2] = 0;
-       return of_irq_map_raw(ppnode, &lspec, 1, laddr, out_irq);
-}
-EXPORT_SYMBOL_GPL(of_irq_map_pci);
-#endif /* CONFIG_PCI */
 
 void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
                unsigned long *busno, unsigned long *phys, unsigned long *size)
index 159c2ff9c127710f870a3958cd6e9d3c0160abfa..f8958b01b97549bc4ab9f311025a6c73aeddadcb 100644 (file)
@@ -386,6 +386,8 @@ config X86_INTEL_CE
        depends on X86_32
        depends on X86_EXTENDED_PLATFORM
        select X86_REBOOTFIXUPS
+       select OF
+       select OF_EARLY_FLATTREE
        ---help---
          Select for the Intel CE media processor (CE4100) SOC.
          This option compiles in support for the CE4100 SOC for settop
@@ -2070,9 +2072,10 @@ config SCx200HR_TIMER
 
 config OLPC
        bool "One Laptop Per Child support"
+       depends on !X86_PAE
        select GPIOLIB
-       select OLPC_OPENFIRMWARE
-       depends on !X86_64 && !X86_PAE
+       select OF
+       select OF_PROMTREE if PROC_DEVICETREE
        ---help---
          Add support for detecting the unique features of the OLPC
          XO hardware.
@@ -2083,21 +2086,6 @@ config OLPC_XO1
        ---help---
          Add support for non-essential features of the OLPC XO-1 laptop.
 
-config OLPC_OPENFIRMWARE
-       bool "Support for OLPC's Open Firmware"
-       depends on !X86_64 && !X86_PAE
-       default n
-       select OF
-       help
-         This option adds support for the implementation of Open Firmware
-         that is used on the OLPC XO-1 Children's Machine.
-         If unsure, say N here.
-
-config OLPC_OPENFIRMWARE_DT
-       bool
-       default y if OLPC_OPENFIRMWARE && PROC_DEVICETREE
-       select OF_PROMTREE
-
 endif # X86_32
 
 config AMD_NB
index b8a3484d69e97156bc2e0926803f25b673adc7ea..a279d98ea95e9880d93fee697b3efd30646f9b5b 100644 (file)
@@ -220,7 +220,6 @@ extern void enable_IR_x2apic(void);
 
 extern int get_physical_broadcast(void);
 
-extern void apic_disable(void);
 extern int lapic_get_maxlvt(void);
 extern void clear_local_APIC(void);
 extern void connect_bsp_APIC(void);
@@ -228,7 +227,6 @@ extern void disconnect_bsp_APIC(int virt_wire_setup);
 extern void disable_local_APIC(void);
 extern void lapic_shutdown(void);
 extern int verify_local_APIC(void);
-extern void cache_APIC_registers(void);
 extern void sync_Arb_IDs(void);
 extern void init_bsp_APIC(void);
 extern void setup_local_APIC(void);
@@ -239,8 +237,7 @@ void register_lapic_address(unsigned long address);
 extern void setup_boot_APIC_clock(void);
 extern void setup_secondary_APIC_clock(void);
 extern int APIC_init_uniprocessor(void);
-extern void enable_NMI_through_LVT0(void);
-extern int apic_force_enable(void);
+extern int apic_force_enable(unsigned long addr);
 
 /*
  * On 32bit this is mach-xxx local
@@ -261,7 +258,6 @@ static inline void lapic_shutdown(void) { }
 #define local_apic_timer_c2_ok         1
 static inline void init_apic_mappings(void) { }
 static inline void disable_local_APIC(void) { }
-static inline void apic_disable(void) { }
 # define setup_boot_APIC_clock x86_init_noop
 # define setup_secondary_APIC_clock x86_init_noop
 #endif /* !CONFIG_X86_LOCAL_APIC */
index c8bfe63a06de289057321af73c114e3521d9088a..e020d88ec02dc2636800eee7203cf4a800dc2fb3 100644 (file)
@@ -12,6 +12,7 @@
 /* setup data types */
 #define SETUP_NONE                     0
 #define SETUP_E820_EXT                 1
+#define SETUP_DTB                      2
 
 /* extensible setup data list node */
 struct setup_data {
index e99d55d74df5023d72b763ca244c9d17bbd1dd53..908b96957d88adf11694f6e83652b47d06d3b8f0 100644 (file)
@@ -96,7 +96,7 @@ extern void e820_setup_gap(void);
 extern int e820_search_gap(unsigned long *gapstart, unsigned long *gapsize,
                        unsigned long start_addr, unsigned long long end_addr);
 struct setup_data;
-extern void parse_e820_ext(struct setup_data *data, unsigned long pa_data);
+extern void parse_e820_ext(struct setup_data *data);
 
 #if defined(CONFIG_X86_64) || \
        (defined(CONFIG_X86_32) && defined(CONFIG_HIBERNATION))
index c704b38c57a244b0067df81118b7cb2a344e1f27..ba870bb6dd8ef30ab81a317a8eb43dcb83066630 100644 (file)
@@ -10,9 +10,6 @@
 #include <asm/apicdef.h>
 #include <asm/irq_vectors.h>
 
-/* Even though we don't support this, supply it to appease OF */
-static inline void irq_dispose_mapping(unsigned int virq) { }
-
 static inline int irq_canonicalize(int irq)
 {
        return ((irq == 2) ? 9 : irq);
diff --git a/arch/x86/include/asm/irq_controller.h b/arch/x86/include/asm/irq_controller.h
new file mode 100644 (file)
index 0000000..423bbbd
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef __IRQ_CONTROLLER__
+#define __IRQ_CONTROLLER__
+
+struct irq_domain {
+       int (*xlate)(struct irq_domain *h, const u32 *intspec, u32 intsize,
+                       u32 *out_hwirq, u32 *out_type);
+       void *priv;
+       struct device_node *controller;
+       struct list_head l;
+};
+
+#endif
index 641988efe0635a8e2840a17f898c70af9eb6eec7..c5d3a5abbb9f4ec2757b468bc14459ce4d13d496 100644 (file)
@@ -6,7 +6,7 @@
 
 #define OLPC_OFW_SIG 0x2057464F        /* aka "OFW " */
 
-#ifdef CONFIG_OLPC_OPENFIRMWARE
+#ifdef CONFIG_OLPC
 
 extern bool olpc_ofw_is_installed(void);
 
@@ -26,19 +26,15 @@ extern void setup_olpc_ofw_pgd(void);
 /* check if OFW was detected during boot */
 extern bool olpc_ofw_present(void);
 
-#else /* !CONFIG_OLPC_OPENFIRMWARE */
-
-static inline bool olpc_ofw_is_installed(void) { return false; }
+#else /* !CONFIG_OLPC */
 static inline void olpc_ofw_detect(void) { }
 static inline void setup_olpc_ofw_pgd(void) { }
-static inline bool olpc_ofw_present(void) { return false; }
-
-#endif /* !CONFIG_OLPC_OPENFIRMWARE */
+#endif /* !CONFIG_OLPC */
 
-#ifdef CONFIG_OLPC_OPENFIRMWARE_DT
+#ifdef CONFIG_OF_PROMTREE
 extern void olpc_dt_build_devicetree(void);
 #else
 static inline void olpc_dt_build_devicetree(void) { }
-#endif /* CONFIG_OLPC_OPENFIRMWARE_DT */
+#endif
 
 #endif /* _ASM_X86_OLPC_OFW_H */
index b4ec95f07518ec9ddbe377d14043a5d2a927a1af..971e0b46446e091761ffe759d4f056d484fe980c 100644 (file)
@@ -1 +1,69 @@
-/* dummy prom.h; here to make linux/of.h's #includes happy */
+/*
+ * Definitions for Device tree / OpenFirmware handling on X86
+ *
+ * based on arch/powerpc/include/asm/prom.h which is
+ *         Copyright (C) 1996-2005 Paul Mackerras.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_X86_PROM_H
+#define _ASM_X86_PROM_H
+#ifndef __ASSEMBLY__
+
+#include <linux/of.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+
+#include <asm/irq.h>
+#include <asm/atomic.h>
+#include <asm/setup.h>
+#include <asm/irq_controller.h>
+
+#ifdef CONFIG_OF
+extern int of_ioapic;
+extern u64 initial_dtb;
+extern void add_dtb(u64 data);
+extern void x86_add_irq_domains(void);
+void __cpuinit x86_of_pci_init(void);
+void x86_dtb_init(void);
+
+static inline struct device_node *pci_device_to_OF_node(struct pci_dev *pdev)
+{
+       return pdev ? pdev->dev.of_node : NULL;
+}
+
+static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
+{
+       return pci_device_to_OF_node(bus->self);
+}
+
+#else
+static inline void add_dtb(u64 data) { }
+static inline void x86_add_irq_domains(void) { }
+static inline void x86_of_pci_init(void) { }
+static inline void x86_dtb_init(void) { }
+#define of_ioapic 0
+#endif
+
+extern char cmd_line[COMMAND_LINE_SIZE];
+
+#define pci_address_to_pio pci_address_to_pio
+unsigned long pci_address_to_pio(phys_addr_t addr);
+
+/**
+ * irq_dispose_mapping - Unmap an interrupt
+ * @virq: linux virq number of the interrupt to unmap
+ *
+ * FIXME: We really should implement proper virq handling like power,
+ * but that's going to be major surgery.
+ */
+static inline void irq_dispose_mapping(unsigned int virq) { }
+
+#define HAVE_ARCH_DEVTREE_FIXUPS
+
+#endif /* __ASSEMBLY__ */
+#endif
index 64642ad019fb78e14ce26416db13c3d340d6507c..643ebf2e2ad8733ddbec5ca884ee21bf405c0226 100644 (file)
@@ -83,11 +83,13 @@ struct x86_init_paging {
  *                             boot cpu
  * @tsc_pre_init:              platform function called before TSC init
  * @timer_init:                        initialize the platform timer (default PIT/HPET)
+ * @wallclock_init:            init the wallclock device
  */
 struct x86_init_timers {
        void (*setup_percpu_clockev)(void);
        void (*tsc_pre_init)(void);
        void (*timer_init)(void);
+       void (*wallclock_init)(void);
 };
 
 /**
index 34244b2cd880cff373e744ec34193adb8287ab2a..62445ba2f8a880b1f53c1d3911ae39b846eaa38b 100644 (file)
@@ -66,9 +66,9 @@ obj-$(CONFIG_PCI)             += early-quirks.o
 apm-y                          := apm_32.o
 obj-$(CONFIG_APM)              += apm.o
 obj-$(CONFIG_SMP)              += smp.o
-obj-$(CONFIG_SMP)              += smpboot.o tsc_sync.o
+obj-$(CONFIG_SMP)              += smpboot.o
+obj-$(CONFIG_SMP)              += tsc_sync.o
 obj-$(CONFIG_SMP)              += setup_percpu.o
-obj-$(CONFIG_X86_64_SMP)       += tsc_sync.o
 obj-$(CONFIG_X86_TRAMPOLINE)   += trampoline_$(BITS).o
 obj-$(CONFIG_X86_MPPARSE)      += mpparse.o
 obj-y                          += apic/
@@ -109,6 +109,7 @@ obj-$(CONFIG_MICROCODE)                     += microcode.o
 obj-$(CONFIG_X86_CHECK_BIOS_CORRUPTION) += check.o
 
 obj-$(CONFIG_SWIOTLB)                  += pci-swiotlb.o
+obj-$(CONFIG_OF)                       += devicetree.o
 
 ###
 # 64 bit specific files
index 51d4e16630669e6b0cf5b83f38140a3aa335e264..1293c709ee856599e02dd1570bbae71f392d4d9a 100644 (file)
@@ -508,64 +508,12 @@ static int apbt_next_event(unsigned long delta,
        return 0;
 }
 
-/*
- * APB timer clock is not in sync with pclk on Langwell, which translates to
- * unreliable read value caused by sampling error. the error does not add up
- * overtime and only happens when sampling a 0 as a 1 by mistake. so the time
- * would go backwards. the following code is trying to prevent time traveling
- * backwards. little bit paranoid.
- */
 static cycle_t apbt_read_clocksource(struct clocksource *cs)
 {
-       unsigned long t0, t1, t2;
-       static unsigned long last_read;
-
-bad_count:
-       t1 = apbt_readl(phy_cs_timer_id,
-                       APBTMR_N_CURRENT_VALUE);
-       t2 = apbt_readl(phy_cs_timer_id,
-                       APBTMR_N_CURRENT_VALUE);
-       if (unlikely(t1 < t2)) {
-               pr_debug("APBT: read current count error %lx:%lx:%lx\n",
-                        t1, t2, t2 - t1);
-               goto bad_count;
-       }
-       /*
-        * check against cached last read, makes sure time does not go back.
-        * it could be a normal rollover but we will do tripple check anyway
-        */
-       if (unlikely(t2 > last_read)) {
-               /* check if we have a normal rollover */
-               unsigned long raw_intr_status =
-                       apbt_readl_reg(APBTMRS_RAW_INT_STATUS);
-               /*
-                * cs timer interrupt is masked but raw intr bit is set if
-                * rollover occurs. then we read EOI reg to clear it.
-                */
-               if (raw_intr_status & (1 << phy_cs_timer_id)) {
-                       apbt_readl(phy_cs_timer_id, APBTMR_N_EOI);
-                       goto out;
-               }
-               pr_debug("APB CS going back %lx:%lx:%lx ",
-                        t2, last_read, t2 - last_read);
-bad_count_x3:
-               pr_debug("triple check enforced\n");
-               t0 = apbt_readl(phy_cs_timer_id,
-                               APBTMR_N_CURRENT_VALUE);
-               udelay(1);
-               t1 = apbt_readl(phy_cs_timer_id,
-                               APBTMR_N_CURRENT_VALUE);
-               udelay(1);
-               t2 = apbt_readl(phy_cs_timer_id,
-                               APBTMR_N_CURRENT_VALUE);
-               if ((t2 > t1) || (t1 > t0)) {
-                       printk(KERN_ERR "Error: APB CS tripple check failed\n");
-                       goto bad_count_x3;
-               }
-       }
-out:
-       last_read = t2;
-       return (cycle_t)~t2;
+       unsigned long current_count;
+
+       current_count = apbt_readl(phy_cs_timer_id, APBTMR_N_CURRENT_VALUE);
+       return (cycle_t)~current_count;
 }
 
 static int apbt_clocksource_register(void)
index 562a8325cc1c07c06d4dcbf51a84f5040a53d996..966673f44141ef1db7d5f8e1ab198fc28b53f6df 100644 (file)
@@ -93,7 +93,7 @@ DEFINE_EARLY_PER_CPU(int, x86_cpu_to_logical_apicid, BAD_APICID);
  *
  * +1=force-enable
  */
-static int force_enable_local_apic;
+static int force_enable_local_apic __initdata;
 /*
  * APIC command line parameters
  */
@@ -163,7 +163,7 @@ early_param("nox2apic", setup_nox2apic);
 unsigned long mp_lapic_addr;
 int disable_apic;
 /* Disable local APIC timer from the kernel commandline or via dmi quirk */
-static int disable_apic_timer __cpuinitdata;
+static int disable_apic_timer __initdata;
 /* Local APIC timer works in C2 */
 int local_apic_timer_c2_ok;
 EXPORT_SYMBOL_GPL(local_apic_timer_c2_ok);
@@ -187,29 +187,8 @@ static struct resource lapic_resource = {
 
 static unsigned int calibration_result;
 
-static int lapic_next_event(unsigned long delta,
-                           struct clock_event_device *evt);
-static void lapic_timer_setup(enum clock_event_mode mode,
-                             struct clock_event_device *evt);
-static void lapic_timer_broadcast(const struct cpumask *mask);
 static void apic_pm_activate(void);
 
-/*
- * The local apic timer can be used for any function which is CPU local.
- */
-static struct clock_event_device lapic_clockevent = {
-       .name           = "lapic",
-       .features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT
-                       | CLOCK_EVT_FEAT_C3STOP | CLOCK_EVT_FEAT_DUMMY,
-       .shift          = 32,
-       .set_mode       = lapic_timer_setup,
-       .set_next_event = lapic_next_event,
-       .broadcast      = lapic_timer_broadcast,
-       .rating         = 100,
-       .irq            = -1,
-};
-static DEFINE_PER_CPU(struct clock_event_device, lapic_events);
-
 static unsigned long apic_phys;
 
 /*
@@ -248,7 +227,7 @@ static int modern_apic(void)
  * right after this call apic become NOOP driven
  * so apic->write/read doesn't do anything
  */
-void apic_disable(void)
+static void __init apic_disable(void)
 {
        pr_info("APIC: switched to apic NOOP\n");
        apic = &apic_noop;
@@ -292,23 +271,6 @@ u64 native_apic_icr_read(void)
        return icr1 | ((u64)icr2 << 32);
 }
 
-/**
- * enable_NMI_through_LVT0 - enable NMI through local vector table 0
- */
-void __cpuinit enable_NMI_through_LVT0(void)
-{
-       unsigned int v;
-
-       /* unmask and set to NMI */
-       v = APIC_DM_NMI;
-
-       /* Level triggered for 82489DX (32bit mode) */
-       if (!lapic_is_integrated())
-               v |= APIC_LVT_LEVEL_TRIGGER;
-
-       apic_write(APIC_LVT0, v);
-}
-
 #ifdef CONFIG_X86_32
 /**
  * get_physical_broadcast - Get number of physical broadcast IDs
@@ -518,6 +480,23 @@ static void lapic_timer_broadcast(const struct cpumask *mask)
 #endif
 }
 
+
+/*
+ * The local apic timer can be used for any function which is CPU local.
+ */
+static struct clock_event_device lapic_clockevent = {
+       .name           = "lapic",
+       .features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT
+                       | CLOCK_EVT_FEAT_C3STOP | CLOCK_EVT_FEAT_DUMMY,
+       .shift          = 32,
+       .set_mode       = lapic_timer_setup,
+       .set_next_event = lapic_next_event,
+       .broadcast      = lapic_timer_broadcast,
+       .rating         = 100,
+       .irq            = -1,
+};
+static DEFINE_PER_CPU(struct clock_event_device, lapic_events);
+
 /*
  * Setup the local APIC timer for this CPU. Copy the initialized values
  * of the boot CPU and register the clock event in the framework.
@@ -1560,7 +1539,7 @@ static int __init detect_init_APIC(void)
 }
 #else
 
-static int apic_verify(void)
+static int __init apic_verify(void)
 {
        u32 features, h, l;
 
@@ -1585,7 +1564,7 @@ static int apic_verify(void)
        return 0;
 }
 
-int apic_force_enable(void)
+int __init apic_force_enable(unsigned long addr)
 {
        u32 h, l;
 
@@ -1601,7 +1580,7 @@ int apic_force_enable(void)
        if (!(l & MSR_IA32_APICBASE_ENABLE)) {
                pr_info("Local APIC disabled by BIOS -- reenabling.\n");
                l &= ~MSR_IA32_APICBASE_BASE;
-               l |= MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE;
+               l |= MSR_IA32_APICBASE_ENABLE | addr;
                wrmsr(MSR_IA32_APICBASE, l, h);
                enabled_via_apicbase = 1;
        }
@@ -1642,7 +1621,7 @@ static int __init detect_init_APIC(void)
                                "you can enable it with \"lapic\"\n");
                        return -1;
                }
-               if (apic_force_enable())
+               if (apic_force_enable(APIC_DEFAULT_PHYS_BASE))
                        return -1;
        } else {
                if (apic_verify())
diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c
new file mode 100644 (file)
index 0000000..7a8cebc
--- /dev/null
@@ -0,0 +1,441 @@
+/*
+ * Architecture specific OF callbacks.
+ */
+#include <linux/bootmem.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/of_irq.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <linux/of_pci.h>
+
+#include <asm/hpet.h>
+#include <asm/irq_controller.h>
+#include <asm/apic.h>
+#include <asm/pci_x86.h>
+
+__initdata u64 initial_dtb;
+char __initdata cmd_line[COMMAND_LINE_SIZE];
+static LIST_HEAD(irq_domains);
+static DEFINE_RAW_SPINLOCK(big_irq_lock);
+
+int __initdata of_ioapic;
+
+#ifdef CONFIG_X86_IO_APIC
+static void add_interrupt_host(struct irq_domain *ih)
+{
+       unsigned long flags;
+
+       raw_spin_lock_irqsave(&big_irq_lock, flags);
+       list_add(&ih->l, &irq_domains);
+       raw_spin_unlock_irqrestore(&big_irq_lock, flags);
+}
+#endif
+
+static struct irq_domain *get_ih_from_node(struct device_node *controller)
+{
+       struct irq_domain *ih, *found = NULL;
+       unsigned long flags;
+
+       raw_spin_lock_irqsave(&big_irq_lock, flags);
+       list_for_each_entry(ih, &irq_domains, l) {
+               if (ih->controller ==  controller) {
+                       found = ih;
+                       break;
+               }
+       }
+       raw_spin_unlock_irqrestore(&big_irq_lock, flags);
+       return found;
+}
+
+unsigned int irq_create_of_mapping(struct device_node *controller,
+                                  const u32 *intspec, unsigned int intsize)
+{
+       struct irq_domain *ih;
+       u32 virq, type;
+       int ret;
+
+       ih = get_ih_from_node(controller);
+       if (!ih)
+               return 0;
+       ret = ih->xlate(ih, intspec, intsize, &virq, &type);
+       if (ret)
+               return ret;
+       if (type == IRQ_TYPE_NONE)
+               return virq;
+       /* set the mask if it is different from current */
+       if (type == (irq_to_desc(virq)->status & IRQF_TRIGGER_MASK))
+               set_irq_type(virq, type);
+       return virq;
+}
+EXPORT_SYMBOL_GPL(irq_create_of_mapping);
+
+unsigned long pci_address_to_pio(phys_addr_t address)
+{
+       /*
+        * The ioport address can be directly used by inX / outX
+        */
+       BUG_ON(address >= (1 << 16));
+       return (unsigned long)address;
+}
+EXPORT_SYMBOL_GPL(pci_address_to_pio);
+
+void __init early_init_dt_scan_chosen_arch(unsigned long node)
+{
+       BUG();
+}
+
+void __init early_init_dt_add_memory_arch(u64 base, u64 size)
+{
+       BUG();
+}
+
+void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
+{
+       return __alloc_bootmem(size, align, __pa(MAX_DMA_ADDRESS));
+}
+
+void __init add_dtb(u64 data)
+{
+       initial_dtb = data + offsetof(struct setup_data, data);
+}
+
+/*
+ * CE4100 ids. Will be moved to machine_device_initcall() once we have it.
+ */
+static struct of_device_id __initdata ce4100_ids[] = {
+       { .compatible = "intel,ce4100-cp", },
+       { .compatible = "isa", },
+       { .compatible = "pci", },
+       {},
+};
+
+static int __init add_bus_probe(void)
+{
+       if (!of_have_populated_dt())
+               return 0;
+
+       return of_platform_bus_probe(NULL, ce4100_ids, NULL);
+}
+module_init(add_bus_probe);
+
+#ifdef CONFIG_PCI
+static int x86_of_pci_irq_enable(struct pci_dev *dev)
+{
+       struct of_irq oirq;
+       u32 virq;
+       int ret;
+       u8 pin;
+
+       ret = pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+       if (ret)
+               return ret;
+       if (!pin)
+               return 0;
+
+       ret = of_irq_map_pci(dev, &oirq);
+       if (ret)
+               return ret;
+
+       virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
+                       oirq.size);
+       if (virq == 0)
+               return -EINVAL;
+       dev->irq = virq;
+       return 0;
+}
+
+static void x86_of_pci_irq_disable(struct pci_dev *dev)
+{
+}
+
+void __cpuinit x86_of_pci_init(void)
+{
+       struct device_node *np;
+
+       pcibios_enable_irq = x86_of_pci_irq_enable;
+       pcibios_disable_irq = x86_of_pci_irq_disable;
+
+       for_each_node_by_type(np, "pci") {
+               const void *prop;
+               struct pci_bus *bus;
+               unsigned int bus_min;
+               struct device_node *child;
+
+               prop = of_get_property(np, "bus-range", NULL);
+               if (!prop)
+                       continue;
+               bus_min = be32_to_cpup(prop);
+
+               bus = pci_find_bus(0, bus_min);
+               if (!bus) {
+                       printk(KERN_ERR "Can't find a node for bus %s.\n",
+                                       np->full_name);
+                       continue;
+               }
+
+               if (bus->self)
+                       bus->self->dev.of_node = np;
+               else
+                       bus->dev.of_node = np;
+
+               for_each_child_of_node(np, child) {
+                       struct pci_dev *dev;
+                       u32 devfn;
+
+                       prop = of_get_property(child, "reg", NULL);
+                       if (!prop)
+                               continue;
+
+                       devfn = (be32_to_cpup(prop) >> 8) & 0xff;
+                       dev = pci_get_slot(bus, devfn);
+                       if (!dev)
+                               continue;
+                       dev->dev.of_node = child;
+                       pci_dev_put(dev);
+               }
+       }
+}
+#endif
+
+static void __init dtb_setup_hpet(void)
+{
+#ifdef CONFIG_HPET_TIMER
+       struct device_node *dn;
+       struct resource r;
+       int ret;
+
+       dn = of_find_compatible_node(NULL, NULL, "intel,ce4100-hpet");
+       if (!dn)
+               return;
+       ret = of_address_to_resource(dn, 0, &r);
+       if (ret) {
+               WARN_ON(1);
+               return;
+       }
+       hpet_address = r.start;
+#endif
+}
+
+static void __init dtb_lapic_setup(void)
+{
+#ifdef CONFIG_X86_LOCAL_APIC
+       struct device_node *dn;
+       struct resource r;
+       int ret;
+
+       dn = of_find_compatible_node(NULL, NULL, "intel,ce4100-lapic");
+       if (!dn)
+               return;
+
+       ret = of_address_to_resource(dn, 0, &r);
+       if (WARN_ON(ret))
+               return;
+
+       /* Did the boot loader setup the local APIC ? */
+       if (!cpu_has_apic) {
+               if (apic_force_enable(r.start))
+                       return;
+       }
+       smp_found_config = 1;
+       pic_mode = 1;
+       register_lapic_address(r.start);
+       generic_processor_info(boot_cpu_physical_apicid,
+                              GET_APIC_VERSION(apic_read(APIC_LVR)));
+#endif
+}
+
+#ifdef CONFIG_X86_IO_APIC
+static unsigned int ioapic_id;
+
+static void __init dtb_add_ioapic(struct device_node *dn)
+{
+       struct resource r;
+       int ret;
+
+       ret = of_address_to_resource(dn, 0, &r);
+       if (ret) {
+               printk(KERN_ERR "Can't obtain address from node %s.\n",
+                               dn->full_name);
+               return;
+       }
+       mp_register_ioapic(++ioapic_id, r.start, gsi_top);
+}
+
+static void __init dtb_ioapic_setup(void)
+{
+       struct device_node *dn;
+
+       for_each_compatible_node(dn, NULL, "intel,ce4100-ioapic")
+               dtb_add_ioapic(dn);
+
+       if (nr_ioapics) {
+               of_ioapic = 1;
+               return;
+       }
+       printk(KERN_ERR "Error: No information about IO-APIC in OF.\n");
+}
+#else
+static void __init dtb_ioapic_setup(void) {}
+#endif
+
+static void __init dtb_apic_setup(void)
+{
+       dtb_lapic_setup();
+       dtb_ioapic_setup();
+}
+
+#ifdef CONFIG_OF_FLATTREE
+static void __init x86_flattree_get_config(void)
+{
+       u32 size, map_len;
+       void *new_dtb;
+
+       if (!initial_dtb)
+               return;
+
+       map_len = max(PAGE_SIZE - (initial_dtb & ~PAGE_MASK),
+                       (u64)sizeof(struct boot_param_header));
+
+       initial_boot_params = early_memremap(initial_dtb, map_len);
+       size = be32_to_cpu(initial_boot_params->totalsize);
+       if (map_len < size) {
+               early_iounmap(initial_boot_params, map_len);
+               initial_boot_params = early_memremap(initial_dtb, size);
+               map_len = size;
+       }
+
+       new_dtb = alloc_bootmem(size);
+       memcpy(new_dtb, initial_boot_params, size);
+       early_iounmap(initial_boot_params, map_len);
+
+       initial_boot_params = new_dtb;
+
+       /* root level address cells */
+       of_scan_flat_dt(early_init_dt_scan_root, NULL);
+
+       unflatten_device_tree();
+}
+#else
+static inline void x86_flattree_get_config(void) { }
+#endif
+
+void __init x86_dtb_init(void)
+{
+       x86_flattree_get_config();
+
+       if (!of_have_populated_dt())
+               return;
+
+       dtb_setup_hpet();
+       dtb_apic_setup();
+}
+
+#ifdef CONFIG_X86_IO_APIC
+
+struct of_ioapic_type {
+       u32 out_type;
+       u32 trigger;
+       u32 polarity;
+};
+
+static struct of_ioapic_type of_ioapic_type[] =
+{
+       {
+               .out_type       = IRQ_TYPE_EDGE_RISING,
+               .trigger        = IOAPIC_EDGE,
+               .polarity       = 1,
+       },
+       {
+               .out_type       = IRQ_TYPE_LEVEL_LOW,
+               .trigger        = IOAPIC_LEVEL,
+               .polarity       = 0,
+       },
+       {
+               .out_type       = IRQ_TYPE_LEVEL_HIGH,
+               .trigger        = IOAPIC_LEVEL,
+               .polarity       = 1,
+       },
+       {
+               .out_type       = IRQ_TYPE_EDGE_FALLING,
+               .trigger        = IOAPIC_EDGE,
+               .polarity       = 0,
+       },
+};
+
+static int ioapic_xlate(struct irq_domain *id, const u32 *intspec, u32 intsize,
+                       u32 *out_hwirq, u32 *out_type)
+{
+       struct io_apic_irq_attr attr;
+       struct of_ioapic_type *it;
+       u32 line, idx, type;
+
+       if (intsize < 2)
+               return -EINVAL;
+
+       line = *intspec;
+       idx = (u32) id->priv;
+       *out_hwirq = line + mp_gsi_routing[idx].gsi_base;
+
+       intspec++;
+       type = *intspec;
+
+       if (type >= ARRAY_SIZE(of_ioapic_type))
+               return -EINVAL;
+
+       it = of_ioapic_type + type;
+       *out_type = it->out_type;
+
+       set_io_apic_irq_attr(&attr, idx, line, it->trigger, it->polarity);
+
+       return io_apic_setup_irq_pin(*out_hwirq, cpu_to_node(0), &attr);
+}
+
+static void __init ioapic_add_ofnode(struct device_node *np)
+{
+       struct resource r;
+       int i, ret;
+
+       ret = of_address_to_resource(np, 0, &r);
+       if (ret) {
+               printk(KERN_ERR "Failed to obtain address for %s\n",
+                               np->full_name);
+               return;
+       }
+
+       for (i = 0; i < nr_ioapics; i++) {
+               if (r.start == mp_ioapics[i].apicaddr) {
+                       struct irq_domain *id;
+
+                       id = kzalloc(sizeof(*id), GFP_KERNEL);
+                       BUG_ON(!id);
+                       id->controller = np;
+                       id->xlate = ioapic_xlate;
+                       id->priv = (void *)i;
+                       add_interrupt_host(id);
+                       return;
+               }
+       }
+       printk(KERN_ERR "IOxAPIC at %s is not registered.\n", np->full_name);
+}
+
+void __init x86_add_irq_domains(void)
+{
+       struct device_node *dp;
+
+       if (!of_have_populated_dt())
+               return;
+
+       for_each_node_with_property(dp, "interrupt-controller") {
+               if (of_device_is_compatible(dp, "intel,ce4100-ioapic"))
+                       ioapic_add_ofnode(dp);
+       }
+}
+#else
+void __init x86_add_irq_domains(void) { }
+#endif
index 0b5e2b546566f156a75b38a597b374f585975755..cdf5bfd9d4d50d8eb2503fd15c38b7d013e90f4a 100644 (file)
@@ -667,21 +667,15 @@ __init void e820_setup_gap(void)
  * boot_params.e820_map, others are passed via SETUP_E820_EXT node of
  * linked list of struct setup_data, which is parsed here.
  */
-void __init parse_e820_ext(struct setup_data *sdata, unsigned long pa_data)
+void __init parse_e820_ext(struct setup_data *sdata)
 {
-       u32 map_len;
        int entries;
        struct e820entry *extmap;
 
        entries = sdata->len / sizeof(struct e820entry);
-       map_len = sdata->len + sizeof(struct setup_data);
-       if (map_len > PAGE_SIZE)
-               sdata = early_ioremap(pa_data, map_len);
        extmap = (struct e820entry *)(sdata->data);
        __append_e820_map(extmap, entries);
        sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
-       if (map_len > PAGE_SIZE)
-               early_iounmap(sdata, map_len);
        printk(KERN_INFO "extended physical RAM map:\n");
        e820_print_map("extended");
 }
index 187aa63b321fa9e29565623769327b99a512af69..ce0be7cd085e025759da9b1fd6445d34e7772de0 100644 (file)
@@ -137,7 +137,7 @@ ENTRY(startup_32)
        movsl
 1:
 
-#ifdef CONFIG_OLPC_OPENFIRMWARE
+#ifdef CONFIG_OLPC
        /* save OFW's pgdir table for later use when calling into OFW */
        movl %cr3, %eax
        movl %eax, pa(olpc_ofw_pgd)
index 5ee693faa111fae5603ec6e34f0e469f9ce8d989..948a31eae75fdf837d9eee344108ce7b7fb4200d 100644 (file)
@@ -223,15 +223,6 @@ void smp_x86_platform_ipi(struct pt_regs *regs)
 
 EXPORT_SYMBOL_GPL(vector_used_by_percpu_irq);
 
-#ifdef CONFIG_OF
-unsigned int irq_create_of_mapping(struct device_node *controller,
-               const u32 *intspec, unsigned int intsize)
-{
-       return intspec[0];
-}
-EXPORT_SYMBOL_GPL(irq_create_of_mapping);
-#endif
-
 #ifdef CONFIG_HOTPLUG_CPU
 /* A cpu has been removed from cpu_online_mask.  Reset irq affinities. */
 void fixup_irqs(void)
index d30854b18d25f8f7a87c710cf531ab650292dd30..f470e4ef993e057f6f3fd67fd75aecaaec1ddc5c 100644 (file)
@@ -25,6 +25,7 @@
 #include <asm/setup.h>
 #include <asm/i8259.h>
 #include <asm/traps.h>
+#include <asm/prom.h>
 
 /*
  * ISA PIC or low IO-APIC triggered (INTA-cycle or APIC) interrupts:
@@ -119,6 +120,12 @@ void __init init_IRQ(void)
 {
        int i;
 
+       /*
+        * We probably need a better place for this, but it works for
+        * now ...
+        */
+       x86_add_irq_domains();
+
        /*
         * On cpu 0, Assign IRQ0_VECTOR..IRQ15_VECTOR's to IRQ 0..15.
         * If these IRQ's are handled by legacy interrupt-controllers like PIC,
@@ -308,7 +315,7 @@ void __init native_init_IRQ(void)
                        set_intr_gate(i, interrupt[i-FIRST_EXTERNAL_VECTOR]);
        }
 
-       if (!acpi_ioapic)
+       if (!acpi_ioapic && !of_ioapic)
                setup_irq(2, &irq2);
 
 #ifdef CONFIG_X86_32
index 6f39cab052d55df75d49ae78705d3954790ec288..3f2ad2640d8522410eb846341b9a8bd6f0d00f26 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/acpi.h>
 #include <linux/bcd.h>
 #include <linux/pnp.h>
+#include <linux/of.h>
 
 #include <asm/vsyscall.h>
 #include <asm/x86_init.h>
@@ -236,6 +237,8 @@ static __init int add_rtc_cmos(void)
                }
        }
 #endif
+       if (of_have_populated_dt())
+               return 0;
 
        platform_device_register(&rtc_device);
        dev_info(&rtc_device.dev,
index c3a606c41ce0ef81eaf70606f70bcfa85c6b83df..b176f2b1f45d8ddfd27fad371411e5c76ec832f5 100644 (file)
 #endif
 #include <asm/mce.h>
 #include <asm/alternative.h>
+#include <asm/prom.h>
 
 /*
  * end_pfn only includes RAM, while max_pfn_mapped includes all e820 entries.
@@ -453,16 +454,30 @@ static void __init parse_setup_data(void)
                return;
        pa_data = boot_params.hdr.setup_data;
        while (pa_data) {
-               data = early_memremap(pa_data, PAGE_SIZE);
+               u32 data_len, map_len;
+
+               map_len = max(PAGE_SIZE - (pa_data & ~PAGE_MASK),
+                             (u64)sizeof(struct setup_data));
+               data = early_memremap(pa_data, map_len);
+               data_len = data->len + sizeof(struct setup_data);
+               if (data_len > map_len) {
+                       early_iounmap(data, map_len);
+                       data = early_memremap(pa_data, data_len);
+                       map_len = data_len;
+               }
+
                switch (data->type) {
                case SETUP_E820_EXT:
-                       parse_e820_ext(data, pa_data);
+                       parse_e820_ext(data);
+                       break;
+               case SETUP_DTB:
+                       add_dtb(pa_data);
                        break;
                default:
                        break;
                }
                pa_data = data->next;
-               early_iounmap(data, PAGE_SIZE);
+               early_iounmap(data, map_len);
        }
 }
 
@@ -1030,8 +1045,8 @@ void __init setup_arch(char **cmdline_p)
         * Read APIC and some other early information from ACPI tables.
         */
        acpi_boot_init();
-
        sfi_init();
+       x86_dtb_init();
 
        /*
         * get boot-time SMP configuration:
@@ -1065,6 +1080,8 @@ void __init setup_arch(char **cmdline_p)
 #endif
        x86_init.oem.banner();
 
+       x86_init.timers.wallclock_init();
+
        mcheck_init();
 
        local_irq_save(flags);
index ceb2911aa439dcb87ac0ef07a8d700f4a5a274e7..c11514e9128b53cf0b6ad66d844c7703a6a8523a 100644 (file)
@@ -70,6 +70,7 @@ struct x86_init_ops x86_init __initdata = {
                .setup_percpu_clockev   = setup_boot_APIC_clock,
                .tsc_pre_init           = x86_init_noop,
                .timer_init             = hpet_time_init,
+               .wallclock_init         = x86_init_noop,
        },
 
        .iommu = {
index 9260b3eb18d41f82be4c1befa1a47e1aea567cf1..67858be4b52b8066201cd5f5cfda657806476e32 100644 (file)
@@ -255,7 +255,7 @@ int bridge_read(unsigned int devfn, int reg, int len, u32 *value)
 static int ce4100_conf_read(unsigned int seg, unsigned int bus,
                            unsigned int devfn, int reg, int len, u32 *value)
 {
-       int i, retval = 1;
+       int i;
 
        if (bus == 1) {
                for (i = 0; i < ARRAY_SIZE(bus1_fixups); i++) {
index cd6f184c3b3f181e5431a50e1639e746c917bb76..28071bb31db7bc1512242589dd10ad5184c976dc 100644 (file)
 #include <linux/serial_8250.h>
 
 #include <asm/ce4100.h>
+#include <asm/prom.h>
 #include <asm/setup.h>
+#include <asm/i8259.h>
 #include <asm/io.h>
+#include <asm/io_apic.h>
 
 static int ce4100_i8042_detect(void)
 {
        return 0;
 }
 
-static void __init sdv_find_smp_config(void)
-{
-}
-
 #ifdef CONFIG_SERIAL_8250
 
-
 static unsigned int mem_serial_in(struct uart_port *p, int offset)
 {
        offset = offset << p->regshift;
@@ -119,6 +117,15 @@ static void __init sdv_arch_setup(void)
        sdv_serial_fixup();
 }
 
+#ifdef CONFIG_X86_IO_APIC
+static void __cpuinit sdv_pci_init(void)
+{
+       x86_of_pci_init();
+       /* We can't set this earlier, because we need to calibrate the timer */
+       legacy_pic = &null_legacy_pic;
+}
+#endif
+
 /*
  * CE4100 specific x86_init function overrides and early setup
  * calls.
@@ -129,6 +136,11 @@ void __init x86_ce4100_early_setup(void)
        x86_platform.i8042_detect = ce4100_i8042_detect;
        x86_init.resources.probe_roms = x86_init_noop;
        x86_init.mpparse.get_smp_config = x86_init_uint_noop;
-       x86_init.mpparse.find_smp_config = sdv_find_smp_config;
+       x86_init.mpparse.find_smp_config = x86_init_noop;
        x86_init.pci.init = ce4100_pci_init;
+
+#ifdef CONFIG_X86_IO_APIC
+       x86_init.pci.init_irq = sdv_pci_init;
+       x86_init.mpparse.setup_ioapic_ids = setup_ioapic_ids_from_mpc_nocheck;
+#endif
 }
diff --git a/arch/x86/platform/ce4100/falconfalls.dts b/arch/x86/platform/ce4100/falconfalls.dts
new file mode 100644 (file)
index 0000000..dc701ea
--- /dev/null
@@ -0,0 +1,428 @@
+/*
+ * CE4100 on Falcon Falls
+ *
+ * (c) Copyright 2010 Intel Corporation
+ *
+ * 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; version 2 of the License.
+ */
+/dts-v1/;
+/ {
+       model = "intel,falconfalls";
+       compatible = "intel,falconfalls";
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu@0 {
+                       device_type = "cpu";
+                       compatible = "intel,ce4100";
+                       reg = <0>;
+                       lapic = <&lapic0>;
+               };
+       };
+
+       soc@0 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "intel,ce4100-cp";
+               ranges;
+
+               ioapic1: interrupt-controller@fec00000 {
+                       #interrupt-cells = <2>;
+                       compatible = "intel,ce4100-ioapic";
+                       interrupt-controller;
+                       reg = <0xfec00000 0x1000>;
+               };
+
+               timer@fed00000 {
+                       compatible = "intel,ce4100-hpet";
+                       reg = <0xfed00000 0x200>;
+               };
+
+               lapic0: interrupt-controller@fee00000 {
+                       compatible = "intel,ce4100-lapic";
+                       reg = <0xfee00000 0x1000>;
+               };
+
+               pci@3fc {
+                       #address-cells = <3>;
+                       #size-cells = <2>;
+                       compatible = "intel,ce4100-pci", "pci";
+                       device_type = "pci";
+                       bus-range = <0 0>;
+                       ranges = <0x2000000 0 0xbffff000 0xbffff000 0 0x1000
+                                 0x2000000 0 0xdffe0000 0xdffe0000 0 0x1000
+                                 0x0000000 0 0x0        0x0        0 0x100>;
+
+                       /* Secondary IO-APIC */
+                       ioapic2: interrupt-controller@0,1 {
+                               #interrupt-cells = <2>;
+                               compatible = "intel,ce4100-ioapic";
+                               interrupt-controller;
+                               reg = <0x100 0x0 0x0 0x0 0x0>;
+                               assigned-addresses = <0x02000000 0x0 0xbffff000 0x0 0x1000>;
+                       };
+
+                       pci@1,0 {
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               compatible = "intel,ce4100-pci", "pci";
+                               device_type = "pci";
+                               bus-range = <1 1>;
+                               ranges = <0x2000000 0 0xdffe0000 0x2000000 0 0xdffe0000 0 0x1000>;
+
+                               interrupt-parent = <&ioapic2>;
+
+                               display@2,0 {
+                                       compatible = "pci8086,2e5b.2",
+                                                  "pci8086,2e5b",
+                                                  "pciclass038000",
+                                                  "pciclass0380";
+
+                                       reg = <0x11000 0x0 0x0 0x0 0x0>;
+                                       interrupts = <0 1>;
+                               };
+
+                               multimedia@3,0 {
+                                       compatible = "pci8086,2e5c.2",
+                                                  "pci8086,2e5c",
+                                                  "pciclass048000",
+                                                  "pciclass0480";
+
+                                       reg = <0x11800 0x0 0x0 0x0 0x0>;
+                                       interrupts = <2 1>;
+                               };
+
+                               multimedia@4,0 {
+                                       compatible = "pci8086,2e5d.2",
+                                                  "pci8086,2e5d",
+                                                  "pciclass048000",
+                                                  "pciclass0480";
+
+                                       reg = <0x12000 0x0 0x0 0x0 0x0>;
+                                       interrupts = <4 1>;
+                               };
+
+                               multimedia@4,1 {
+                                       compatible = "pci8086,2e5e.2",
+                                                  "pci8086,2e5e",
+                                                  "pciclass048000",
+                                                  "pciclass0480";
+
+                                       reg = <0x12100 0x0 0x0 0x0 0x0>;
+                                       interrupts = <5 1>;
+                               };
+
+                               sound@6,0 {
+                                       compatible = "pci8086,2e5f.2",
+                                                  "pci8086,2e5f",
+                                                  "pciclass040100",
+                                                  "pciclass0401";
+
+                                       reg = <0x13000 0x0 0x0 0x0 0x0>;
+                                       interrupts = <6 1>;
+                               };
+
+                               sound@6,1 {
+                                       compatible = "pci8086,2e5f.2",
+                                                  "pci8086,2e5f",
+                                                  "pciclass040100",
+                                                  "pciclass0401";
+
+                                       reg = <0x13100 0x0 0x0 0x0 0x0>;
+                                       interrupts = <7 1>;
+                               };
+
+                               sound@6,2 {
+                                       compatible = "pci8086,2e60.2",
+                                                  "pci8086,2e60",
+                                                  "pciclass040100",
+                                                  "pciclass0401";
+
+                                       reg = <0x13200 0x0 0x0 0x0 0x0>;
+                                       interrupts = <8 1>;
+                               };
+
+                               display@8,0 {
+                                       compatible = "pci8086,2e61.2",
+                                                  "pci8086,2e61",
+                                                  "pciclass038000",
+                                                  "pciclass0380";
+
+                                       reg = <0x14000 0x0 0x0 0x0 0x0>;
+                                       interrupts = <9 1>;
+                               };
+
+                               display@8,1 {
+                                       compatible = "pci8086,2e62.2",
+                                                  "pci8086,2e62",
+                                                  "pciclass038000",
+                                                  "pciclass0380";
+
+                                       reg = <0x14100 0x0 0x0 0x0 0x0>;
+                                       interrupts = <10 1>;
+                               };
+
+                               multimedia@8,2 {
+                                       compatible = "pci8086,2e63.2",
+                                                  "pci8086,2e63",
+                                                  "pciclass048000",
+                                                  "pciclass0480";
+
+                                       reg = <0x14200 0x0 0x0 0x0 0x0>;
+                                       interrupts = <11 1>;
+                               };
+
+                               entertainment-encryption@9,0 {
+                                       compatible = "pci8086,2e64.2",
+                                                  "pci8086,2e64",
+                                                  "pciclass101000",
+                                                  "pciclass1010";
+
+                                       reg = <0x14800 0x0 0x0 0x0 0x0>;
+                                       interrupts = <12 1>;
+                               };
+
+                               localbus@a,0 {
+                                       compatible = "pci8086,2e65.2",
+                                                  "pci8086,2e65",
+                                                  "pciclassff0000",
+                                                  "pciclassff00";
+
+                                       reg = <0x15000 0x0 0x0 0x0 0x0>;
+                               };
+
+                               serial@b,0 {
+                                       compatible = "pci8086,2e66.2",
+                                                  "pci8086,2e66",
+                                                  "pciclass070003",
+                                                  "pciclass0700";
+
+                                       reg = <0x15800 0x0 0x0 0x0 0x0>;
+                                       interrupts = <14 1>;
+                               };
+
+                               gpio@b,1 {
+                                       compatible = "pci8086,2e67.2",
+                                                  "pci8086,2e67",
+                                                  "pciclassff0000",
+                                                  "pciclassff00";
+
+                                       #gpio-cells = <2>;
+                                       reg = <0x15900 0x0 0x0 0x0 0x0>;
+                                       interrupts = <15 1>;
+                                       gpio-controller;
+                               };
+
+                               i2c-controller@b,2 {
+                                       #address-cells = <2>;
+                                       #size-cells = <1>;
+                                       compatible = "pci8086,2e68.2",
+                                                  "pci8086,2e68",
+                                                  "pciclass,ff0000",
+                                                  "pciclass,ff00";
+
+                                       reg = <0x15a00 0x0 0x0 0x0 0x0>;
+                                       interrupts = <16 1>;
+                                       ranges = <0 0   0x02000000 0 0xdffe0500 0x100
+                                                 1 0   0x02000000 0 0xdffe0600 0x100
+                                                 2 0   0x02000000 0 0xdffe0700 0x100>;
+
+                                       i2c@0 {
+                                               #address-cells = <1>;
+                                               #size-cells = <0>;
+                                               compatible = "intel,ce4100-i2c-controller";
+                                               reg = <0 0 0x100>;
+                                       };
+
+                                       i2c@1 {
+                                               #address-cells = <1>;
+                                               #size-cells = <0>;
+                                               compatible = "intel,ce4100-i2c-controller";
+                                               reg = <1 0 0x100>;
+
+                                               gpio@26 {
+                                                       #gpio-cells = <2>;
+                                                       compatible = "ti,pcf8575";
+                                                       reg = <0x26>;
+                                                       gpio-controller;
+                                               };
+                                       };
+
+                                       i2c@2 {
+                                               #address-cells = <1>;
+                                               #size-cells = <0>;
+                                               compatible = "intel,ce4100-i2c-controller";
+                                               reg = <2 0 0x100>;
+
+                                               gpio@26 {
+                                                       #gpio-cells = <2>;
+                                                       compatible = "ti,pcf8575";
+                                                       reg = <0x26>;
+                                                       gpio-controller;
+                                               };
+                                       };
+                               };
+
+                               smard-card@b,3 {
+                                       compatible = "pci8086,2e69.2",
+                                                  "pci8086,2e69",
+                                                  "pciclass070500",
+                                                  "pciclass0705";
+
+                                       reg = <0x15b00 0x0 0x0 0x0 0x0>;
+                                       interrupts = <15 1>;
+                               };
+
+                               spi-controller@b,4 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       compatible =
+                                               "pci8086,2e6a.2",
+                                               "pci8086,2e6a",
+                                               "pciclass,ff0000",
+                                               "pciclass,ff00";
+
+                                       reg = <0x15c00 0x0 0x0 0x0 0x0>;
+                                       interrupts = <15 1>;
+
+                                       dac@0 {
+                                               compatible = "ti,pcm1755";
+                                               reg = <0>;
+                                               spi-max-frequency = <115200>;
+                                       };
+
+                                       dac@1 {
+                                               compatible = "ti,pcm1609a";
+                                               reg = <1>;
+                                               spi-max-frequency = <115200>;
+                                       };
+
+                                       eeprom@2 {
+                                               compatible = "atmel,at93c46";
+                                               reg = <2>;
+                                               spi-max-frequency = <115200>;
+                                       };
+                               };
+
+                               multimedia@b,7 {
+                                       compatible = "pci8086,2e6d.2",
+                                                  "pci8086,2e6d",
+                                                  "pciclassff0000",
+                                                  "pciclassff00";
+
+                                       reg = <0x15f00 0x0 0x0 0x0 0x0>;
+                               };
+
+                               ethernet@c,0 {
+                                       compatible = "pci8086,2e6e.2",
+                                                  "pci8086,2e6e",
+                                                  "pciclass020000",
+                                                  "pciclass0200";
+
+                                       reg = <0x16000 0x0 0x0 0x0 0x0>;
+                                       interrupts = <21 1>;
+                               };
+
+                               clock@c,1 {
+                                       compatible = "pci8086,2e6f.2",
+                                                  "pci8086,2e6f",
+                                                  "pciclassff0000",
+                                                  "pciclassff00";
+
+                                       reg = <0x16100 0x0 0x0 0x0 0x0>;
+                                       interrupts = <3 1>;
+                               };
+
+                               usb@d,0 {
+                                       compatible = "pci8086,2e70.2",
+                                                  "pci8086,2e70",
+                                                  "pciclass0c0320",
+                                                  "pciclass0c03";
+
+                                       reg = <0x16800 0x0 0x0 0x0 0x0>;
+                                       interrupts = <22 3>;
+                               };
+
+                               usb@d,1 {
+                                       compatible = "pci8086,2e70.2",
+                                                  "pci8086,2e70",
+                                                  "pciclass0c0320",
+                                                  "pciclass0c03";
+
+                                       reg = <0x16900 0x0 0x0 0x0 0x0>;
+                                       interrupts = <22 3>;
+                               };
+
+                               sata@e,0 {
+                                       compatible = "pci8086,2e71.0",
+                                                  "pci8086,2e71",
+                                                  "pciclass010601",
+                                                  "pciclass0106";
+
+                                       reg = <0x17000 0x0 0x0 0x0 0x0>;
+                                       interrupts = <23 3>;
+                               };
+
+                               flash@f,0 {
+                                       compatible = "pci8086,701.1",
+                                                  "pci8086,701",
+                                                  "pciclass050100",
+                                                  "pciclass0501";
+
+                                       reg = <0x17800 0x0 0x0 0x0 0x0>;
+                                       interrupts = <13 1>;
+                               };
+
+                               entertainment-encryption@10,0 {
+                                       compatible = "pci8086,702.1",
+                                                  "pci8086,702",
+                                                  "pciclass101000",
+                                                  "pciclass1010";
+
+                                       reg = <0x18000 0x0 0x0 0x0 0x0>;
+                               };
+
+                               co-processor@11,0 {
+                                       compatible = "pci8086,703.1",
+                                                  "pci8086,703",
+                                                  "pciclass0b4000",
+                                                  "pciclass0b40";
+
+                                       reg = <0x18800 0x0 0x0 0x0 0x0>;
+                                       interrupts = <1 1>;
+                               };
+
+                               multimedia@12,0 {
+                                       compatible = "pci8086,704.0",
+                                                  "pci8086,704",
+                                                  "pciclass048000",
+                                                  "pciclass0480";
+
+                                       reg = <0x19000 0x0 0x0 0x0 0x0>;
+                               };
+                       };
+
+                       isa@1f,0 {
+                               #address-cells = <2>;
+                               #size-cells = <1>;
+                               compatible = "isa";
+                               ranges = <1 0 0 0 0 0x100>;
+
+                               rtc@70 {
+                                       compatible = "intel,ce4100-rtc", "motorola,mc146818";
+                                       interrupts = <8 3>;
+                                       interrupt-parent = <&ioapic1>;
+                                       ctrl-reg = <2>;
+                                       freq-reg = <0x26>;
+                                       reg = <1 0x70 2>;
+                               };
+                       };
+               };
+       };
+};
index ea6529e93c6fb2389282a78b78e739551a8f26eb..5c0207bf959bc4a8490347d775eba452c13f2684 100644 (file)
@@ -31,6 +31,7 @@
 #include <asm/apic.h>
 #include <asm/io_apic.h>
 #include <asm/mrst.h>
+#include <asm/mrst-vrtc.h>
 #include <asm/io.h>
 #include <asm/i8259.h>
 #include <asm/intel_scu_ipc.h>
@@ -268,6 +269,7 @@ void __init x86_mrst_early_setup(void)
 
        x86_platform.calibrate_tsc = mrst_calibrate_tsc;
        x86_platform.i8042_detect = mrst_i8042_detect;
+       x86_init.timers.wallclock_init = mrst_rtc_init;
        x86_init.pci.init = pci_mrst_init;
        x86_init.pci.fixup_irqs = x86_init_noop;
 
index 32cd7edd71a0fab9ce4a2ac0f43875855406beb5..04cf645feb92018edf96bf32779ea4dde274782f 100644 (file)
@@ -100,22 +100,14 @@ int vrtc_set_mmss(unsigned long nowtime)
 
 void __init mrst_rtc_init(void)
 {
-       unsigned long rtc_paddr;
-       void __iomem *virt_base;
+       unsigned long vrtc_paddr = sfi_mrtc_array[0].phys_addr;
 
        sfi_table_parse(SFI_SIG_MRTC, NULL, NULL, sfi_parse_mrtc);
-       if (!sfi_mrtc_num)
+       if (!sfi_mrtc_num || !vrtc_paddr)
                return;
 
-       rtc_paddr = sfi_mrtc_array[0].phys_addr;
-
-       /* vRTC's register address may not be page aligned */
-       set_fixmap_nocache(FIX_LNW_VRTC, rtc_paddr);
-
-       virt_base = (void __iomem *)__fix_to_virt(FIX_LNW_VRTC);
-       virt_base += rtc_paddr & ~PAGE_MASK;
-       vrtc_virt_base = virt_base;
-
+       vrtc_virt_base = (void __iomem *)set_fixmap_offset_nocache(FIX_LNW_VRTC,
+                                                               vrtc_paddr);
        x86_platform.get_wallclock = vrtc_get_time;
        x86_platform.set_wallclock = vrtc_set_mmss;
 }
index e797428b163bb0b58d40cf7dc4b70518f7571dce..c2a8cab65e5d71f82404a9b6b118dc6556c79489 100644 (file)
@@ -1,4 +1,4 @@
 obj-$(CONFIG_OLPC)             += olpc.o
 obj-$(CONFIG_OLPC_XO1)         += olpc-xo1.o
-obj-$(CONFIG_OLPC_OPENFIRMWARE)        += olpc_ofw.o
-obj-$(CONFIG_OLPC_OPENFIRMWARE_DT)     += olpc_dt.o
+obj-$(CONFIG_OLPC)             += olpc_ofw.o
+obj-$(CONFIG_OF_PROMTREE)      += olpc_dt.o
index 61653f0796718a479d61e467fec689ae6c130b72..1b46a9d9f907336fb70526ca93881ce3b3934950 100644 (file)
@@ -330,9 +330,7 @@ static int __devinit ocores_i2c_probe(struct platform_device *pdev)
        i2c->adap = ocores_adapter;
        i2c_set_adapdata(&i2c->adap, i2c);
        i2c->adap.dev.parent = &pdev->dev;
-#ifdef CONFIG_OF
        i2c->adap.dev.of_node = pdev->dev.of_node;
-#endif
 
        /* add i2c adapter to i2c tree */
        ret = i2c_add_adapter(&i2c->adap);
@@ -390,15 +388,11 @@ static int ocores_i2c_resume(struct platform_device *pdev)
 #define ocores_i2c_resume      NULL
 #endif
 
-#ifdef CONFIG_OF
 static struct of_device_id ocores_i2c_match[] = {
-        {
-                .compatible = "opencores,i2c-ocores",
-        },
-        {},
+       { .compatible = "opencores,i2c-ocores", },
+       {},
 };
 MODULE_DEVICE_TABLE(of, ocores_i2c_match);
-#endif
 
 /* work with hotplug and coldplug */
 MODULE_ALIAS("platform:ocores-i2c");
@@ -411,9 +405,7 @@ static struct platform_driver ocores_i2c_driver = {
        .driver  = {
                .owner = THIS_MODULE,
                .name = "ocores-i2c",
-#ifdef CONFIG_OF
-                .of_match_table = ocores_i2c_match,
-#endif
+               .of_match_table = ocores_i2c_match,
        },
 };
 
index f0bd5bcdf56329294b5cab85a0fe41ce06600dd6..045ba6efea48fd24cbf651115e2d86a4f87781b4 100644 (file)
@@ -537,9 +537,7 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info)
        client->dev.parent = &client->adapter->dev;
        client->dev.bus = &i2c_bus_type;
        client->dev.type = &i2c_client_type;
-#ifdef CONFIG_OF
        client->dev.of_node = info->of_node;
-#endif
 
        dev_set_name(&client->dev, "%d-%04x", i2c_adapter_id(adap),
                     client->addr);
index fd877f633dd220eb4b3bd3e9e7d104af0aef603f..2f7fc0c5146f365a465d31bd9f5b3ab5e42c8c77 100644 (file)
@@ -1516,21 +1516,17 @@ 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 b79d7e1555d5e5e45b3d7475b47029f814bd856f..db0290f05bdf9ec00e6a16b07832de60204a2813 100644 (file)
@@ -1163,15 +1163,11 @@ static int ethoc_resume(struct platform_device *pdev)
 # define ethoc_resume  NULL
 #endif
 
-#ifdef CONFIG_OF
 static struct of_device_id ethoc_match[] = {
-       {
-               .compatible = "opencores,ethoc",
-       },
+       { .compatible = "opencores,ethoc", },
        {},
 };
 MODULE_DEVICE_TABLE(of, ethoc_match);
-#endif
 
 static struct platform_driver ethoc_driver = {
        .probe   = ethoc_probe,
@@ -1181,9 +1177,7 @@ static struct platform_driver ethoc_driver = {
        .driver  = {
                .name = "ethoc",
                .owner = THIS_MODULE,
-#ifdef CONFIG_OF
                .of_match_table = ethoc_match,
-#endif
        },
 };
 
index 3c6e100a3ad042d998e9fcf3085ae476cf83443e..d06a6374ed6ca6ffca60ccc0df1157c140a4952d 100644 (file)
@@ -69,4 +69,10 @@ config OF_MDIO
        help
          OpenFirmware MDIO bus (Ethernet PHY) accessors
 
+config OF_PCI
+       def_tristate PCI
+       depends on PCI && (PPC || MICROBLAZE || X86)
+       help
+         OpenFirmware PCI bus accessors
+
 endmenu # OF
index 3ab21a0a4907defc5c3470f40c1d0ed74d6db731..f7861ed2f287dbaddec018529eeaacdc96d9601d 100644 (file)
@@ -9,3 +9,4 @@ obj-$(CONFIG_OF_I2C)    += of_i2c.o
 obj-$(CONFIG_OF_NET)   += of_net.o
 obj-$(CONFIG_OF_SPI)   += of_spi.o
 obj-$(CONFIG_OF_MDIO)  += of_mdio.o
+obj-$(CONFIG_OF_PCI)   += of_pci.o
diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
new file mode 100644 (file)
index 0000000..ac1ec54
--- /dev/null
@@ -0,0 +1,92 @@
+#include <linux/kernel.h>
+#include <linux/of_pci.h>
+#include <linux/of_irq.h>
+#include <asm/prom.h>
+
+/**
+ * of_irq_map_pci - Resolve the interrupt for a PCI device
+ * @pdev:       the device whose interrupt is to be resolved
+ * @out_irq:    structure of_irq filled by this function
+ *
+ * This function resolves the PCI interrupt for a given PCI device. If a
+ * device-node exists for a given pci_dev, it will use normal OF tree
+ * walking. If not, it will implement standard swizzling and walk up the
+ * PCI tree until an device-node is found, at which point it will finish
+ * resolving using the OF tree walking.
+ */
+int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
+{
+       struct device_node *dn, *ppnode;
+       struct pci_dev *ppdev;
+       u32 lspec;
+       __be32 lspec_be;
+       __be32 laddr[3];
+       u8 pin;
+       int rc;
+
+       /* Check if we have a device node, if yes, fallback to standard
+        * device tree parsing
+        */
+       dn = pci_device_to_OF_node(pdev);
+       if (dn) {
+               rc = of_irq_map_one(dn, 0, out_irq);
+               if (!rc)
+                       return rc;
+       }
+
+       /* Ok, we don't, time to have fun. Let's start by building up an
+        * interrupt spec.  we assume #interrupt-cells is 1, which is standard
+        * for PCI. If you do different, then don't use that routine.
+        */
+       rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
+       if (rc != 0)
+               return rc;
+       /* No pin, exit */
+       if (pin == 0)
+               return -ENODEV;
+
+       /* Now we walk up the PCI tree */
+       lspec = pin;
+       for (;;) {
+               /* Get the pci_dev of our parent */
+               ppdev = pdev->bus->self;
+
+               /* Ouch, it's a host bridge... */
+               if (ppdev == NULL) {
+                       ppnode = pci_bus_to_OF_node(pdev->bus);
+
+                       /* No node for host bridge ? give up */
+                       if (ppnode == NULL)
+                               return -EINVAL;
+               } else {
+                       /* We found a P2P bridge, check if it has a node */
+                       ppnode = pci_device_to_OF_node(ppdev);
+               }
+
+               /* Ok, we have found a parent with a device-node, hand over to
+                * the OF parsing code.
+                * We build a unit address from the linux device to be used for
+                * resolution. Note that we use the linux bus number which may
+                * not match your firmware bus numbering.
+                * Fortunately, in most cases, interrupt-map-mask doesn't
+                * include the bus number as part of the matching.
+                * You should still be careful about that though if you intend
+                * to rely on this function (you ship  a firmware that doesn't
+                * create device nodes for all PCI devices).
+                */
+               if (ppnode)
+                       break;
+
+               /* We can only get here if we hit a P2P bridge with no node,
+                * let's do standard swizzling and try again
+                */
+               lspec = pci_swizzle_interrupt_pin(pdev, lspec);
+               pdev = ppdev;
+       }
+
+       lspec_be = cpu_to_be32(lspec);
+       laddr[0] = cpu_to_be32((pdev->bus->number << 16) | (pdev->devfn << 8));
+       laddr[1]  = laddr[2] = cpu_to_be32(0);
+       return of_irq_map_raw(ppnode, &lspec_be, 1, laddr, out_irq);
+}
+EXPORT_SYMBOL_GPL(of_irq_map_pci);
index dc2a0ba969cef74f7af07bed92fa512ef7ddb989..911e75cdc125107186a53518b748dbc10329afe8 100644 (file)
@@ -37,6 +37,8 @@
 #include <linux/mod_devicetable.h>
 #include <linux/log2.h>
 #include <linux/pm.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
 
 /* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */
 #include <asm-generic/rtc.h>
@@ -1057,6 +1059,47 @@ static struct pnp_driver cmos_pnp_driver = {
 
 #endif /* CONFIG_PNP */
 
+#ifdef CONFIG_OF
+static const struct of_device_id of_cmos_match[] = {
+       {
+               .compatible = "motorola,mc146818",
+       },
+       { },
+};
+MODULE_DEVICE_TABLE(of, of_cmos_match);
+
+static __init void cmos_of_init(struct platform_device *pdev)
+{
+       struct device_node *node = pdev->dev.of_node;
+       struct rtc_time time;
+       int ret;
+       const __be32 *val;
+
+       if (!node)
+               return;
+
+       val = of_get_property(node, "ctrl-reg", NULL);
+       if (val)
+               CMOS_WRITE(be32_to_cpup(val), RTC_CONTROL);
+
+       val = of_get_property(node, "freq-reg", NULL);
+       if (val)
+               CMOS_WRITE(be32_to_cpup(val), RTC_FREQ_SELECT);
+
+       get_rtc_time(&time);
+       ret = rtc_valid_tm(&time);
+       if (ret) {
+               struct rtc_time def_time = {
+                       .tm_year = 1,
+                       .tm_mday = 1,
+               };
+               set_rtc_time(&def_time);
+       }
+}
+#else
+static inline void cmos_of_init(struct platform_device *pdev) {}
+#define of_cmos_match NULL
+#endif
 /*----------------------------------------------------------------*/
 
 /* Platform setup should have set up an RTC device, when PNP is
@@ -1065,6 +1108,7 @@ static struct pnp_driver cmos_pnp_driver = {
 
 static int __init cmos_platform_probe(struct platform_device *pdev)
 {
+       cmos_of_init(pdev);
        cmos_wake_setup(&pdev->dev);
        return cmos_do_probe(&pdev->dev,
                        platform_get_resource(pdev, IORESOURCE_IO, 0),
@@ -1096,6 +1140,7 @@ static struct platform_driver cmos_platform_driver = {
 #ifdef CONFIG_PM
                .pm             = &cmos_pm_ops,
 #endif
+               .of_match_table = of_cmos_match,
        }
 };
 
index 4db96fa306fc3dcf5ed0c9a247bf9395b9365fc7..b86bc328463b2ec2731c0028f2b08fae90cc5e04 100644 (file)
@@ -62,6 +62,17 @@ static inline int is_intr(u8 rtc_intr)
        return rtc_intr & RTC_IRQMASK;
 }
 
+static inline unsigned char vrtc_is_updating(void)
+{
+       unsigned char uip;
+       unsigned long flags;
+
+       spin_lock_irqsave(&rtc_lock, flags);
+       uip = (vrtc_cmos_read(RTC_FREQ_SELECT) & RTC_UIP);
+       spin_unlock_irqrestore(&rtc_lock, flags);
+       return uip;
+}
+
 /*
  * rtc_time's year contains the increment over 1900, but vRTC's YEAR
  * register can't be programmed to value larger than 0x64, so vRTC
@@ -76,7 +87,7 @@ static int mrst_read_time(struct device *dev, struct rtc_time *time)
 {
        unsigned long flags;
 
-       if (rtc_is_updating())
+       if (vrtc_is_updating())
                mdelay(20);
 
        spin_lock_irqsave(&rtc_lock, flags);
index 95928833855b0e922bf5ee23ea6ff36241e8b2bb..a429b01d0285edba75055df0dd49b6a5184ec68f 100644 (file)
@@ -1557,9 +1557,7 @@ static int __devinit pxa2xx_spi_probe(struct platform_device *pdev)
        drv_data->ssp = ssp;
 
        master->dev.parent = &pdev->dev;
-#ifdef CONFIG_OF
        master->dev.of_node = pdev->dev.of_node;
-#endif
        /* the spi->mode bits understood by this driver: */
        master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
 
index 19752b09e155457a5dc0836b991da2c41802cd52..378e504f89ebdf8dd7b2b503e6c3a79d8820f269 100644 (file)
@@ -89,9 +89,7 @@ static int __devinit ce4100_spi_probe(struct pci_dev *dev,
                goto err_nomem;
 
        pdev->dev.parent = &dev->dev;
-#ifdef CONFIG_OF
        pdev->dev.of_node = dev->dev.of_node;
-#endif
        ssp = &spi_info->ssp;
        ssp->phys_base = pci_resource_start(dev, 0);
        ssp->mmio_base = ioremap(phys_beg, phys_len);
index 7adaef62a99122a0e7e7427207f2e47132d33469..4d2c75df886c88621e43a453db625e59e7876ccf 100644 (file)
@@ -351,14 +351,12 @@ static irqreturn_t xilinx_spi_irq(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
-#ifdef CONFIG_OF
 static const struct of_device_id xilinx_spi_of_match[] = {
        { .compatible = "xlnx,xps-spi-2.00.a", },
        { .compatible = "xlnx,xps-spi-2.00.b", },
        {}
 };
 MODULE_DEVICE_TABLE(of, xilinx_spi_of_match);
-#endif
 
 struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem,
        u32 irq, s16 bus_num, int num_cs, int little_endian, int bits_per_word)
@@ -394,9 +392,7 @@ struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem,
 
        master->bus_num = bus_num;
        master->num_chipselect = num_cs;
-#ifdef CONFIG_OF
        master->dev.of_node = dev->of_node;
-#endif
 
        xspi->mem = *mem;
        xspi->irq = irq;
@@ -539,9 +535,7 @@ static struct platform_driver xilinx_spi_driver = {
        .driver = {
                .name = XILINX_SPI_NAME,
                .owner = THIS_MODULE,
-#ifdef CONFIG_OF
                .of_match_table = xilinx_spi_of_match,
-#endif
        },
 };
 
index 1bf5cf0b45131015a857b0194a6b79f226e6dadd..ca5d25225aabd9ecaff16854ac483b14b3c635fa 100644 (file)
@@ -128,9 +128,7 @@ struct device_driver {
 
        bool suppress_bind_attrs;       /* disables bind/unbind via sysfs */
 
-#if defined(CONFIG_OF)
        const struct of_device_id       *of_match_table;
-#endif
 
        int (*probe) (struct device *dev);
        int (*remove) (struct device *dev);
@@ -441,9 +439,8 @@ struct device {
                                             override */
        /* arch specific additions */
        struct dev_archdata     archdata;
-#ifdef CONFIG_OF
-       struct device_node      *of_node;
-#endif
+
+       struct device_node      *of_node; /* associated device tree node */
 
        dev_t                   devt;   /* dev_t, creates the sysfs "dev" */
 
index 903576df88dcd6df2b4690991cf88df0b00195f0..06a8d9c7de98765c3b73e1093c346de452c0fbd5 100644 (file)
@@ -258,9 +258,7 @@ struct i2c_board_info {
        unsigned short  addr;
        void            *platform_data;
        struct dev_archdata     *archdata;
-#ifdef CONFIG_OF
        struct device_node *of_node;
-#endif
        int             irq;
 };
 
index cad7cf0ab27855f6fff3e35fb9b95a96867a9e91..266db1d0baa9d994c20b4665a774a8f96f3646cd 100644 (file)
@@ -23,8 +23,6 @@
 
 #include <asm/byteorder.h>
 
-#ifdef CONFIG_OF
-
 typedef u32 phandle;
 typedef u32 ihandle;
 
@@ -65,11 +63,18 @@ struct device_node {
 #endif
 };
 
+#ifdef CONFIG_OF
+
 /* Pointer for first entry in chain of all nodes. */
 extern struct device_node *allnodes;
 extern struct device_node *of_chosen;
 extern rwlock_t devtree_lock;
 
+static inline bool of_have_populated_dt(void)
+{
+       return allnodes != NULL;
+}
+
 static inline bool of_node_is_root(const struct device_node *node)
 {
        return node && (node->parent == NULL);
@@ -222,5 +227,12 @@ extern void of_attach_node(struct device_node *);
 extern void of_detach_node(struct device_node *);
 #endif
 
+#else
+
+static inline bool of_have_populated_dt(void)
+{
+       return false;
+}
+
 #endif /* CONFIG_OF */
 #endif /* _LINUX_OF_H */
diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h
new file mode 100644 (file)
index 0000000..85a27b6
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef __OF_PCI_H
+#define __OF_PCI_H
+
+#include <linux/pci.h>
+
+struct pci_dev;
+struct of_irq;
+int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
+#endif