diff options
56 files changed, 1478 insertions, 417 deletions
diff --git a/Documentation/devicetree/bindings/i2c/ce4100-i2c.txt b/Documentation/devicetree/bindings/i2c/ce4100-i2c.txt new file mode 100644 index 00000000000..569b1624851 --- /dev/null +++ b/Documentation/devicetree/bindings/i2c/ce4100-i2c.txt | |||
| @@ -0,0 +1,93 @@ | |||
| 1 | CE4100 I2C | ||
| 2 | ---------- | ||
| 3 | |||
| 4 | CE4100 has one PCI device which is described as the I2C-Controller. This | ||
| 5 | PCI device has three PCI-bars, each bar contains a complete I2C | ||
| 6 | controller. So we have a total of three independent I2C-Controllers | ||
| 7 | which share only an interrupt line. | ||
| 8 | The driver is probed via the PCI-ID and is gathering the information of | ||
| 9 | attached devices from the devices tree. | ||
| 10 | Grant Likely recommended to use the ranges property to map the PCI-Bar | ||
| 11 | number to its physical address and to use this to find the child nodes | ||
| 12 | of the specific I2C controller. This were his exact words: | ||
| 13 | |||
| 14 | Here's where the magic happens. Each entry in | ||
| 15 | ranges describes how the parent pci address space | ||
| 16 | (middle group of 3) is translated to the local | ||
| 17 | address space (first group of 2) and the size of | ||
| 18 | each range (last cell). In this particular case, | ||
| 19 | the first cell of the local address is chosen to be | ||
| 20 | 1:1 mapped to the BARs, and the second is the | ||
| 21 | offset from be base of the BAR (which would be | ||
| 22 | non-zero if you had 2 or more devices mapped off | ||
| 23 | the same BAR) | ||
| 24 | |||
| 25 | ranges allows the address mapping to be described | ||
| 26 | in a way that the OS can interpret without | ||
| 27 | requiring custom device driver code. | ||
| 28 | |||
| 29 | This is an example which is used on FalconFalls: | ||
| 30 | ------------------------------------------------ | ||
| 31 | i2c-controller@b,2 { | ||
| 32 | #address-cells = <2>; | ||
| 33 | #size-cells = <1>; | ||
| 34 | compatible = "pci8086,2e68.2", | ||
| 35 | "pci8086,2e68", | ||
| 36 | "pciclass,ff0000", | ||
| 37 | "pciclass,ff00"; | ||
| 38 | |||
| 39 | reg = <0x15a00 0x0 0x0 0x0 0x0>; | ||
| 40 | interrupts = <16 1>; | ||
| 41 | |||
| 42 | /* as described by Grant, the first number in the group of | ||
| 43 | * three is the bar number followed by the 64bit bar address | ||
| 44 | * followed by size of the mapping. The bar address | ||
| 45 | * requires also a valid translation in parents ranges | ||
| 46 | * property. | ||
| 47 | */ | ||
| 48 | ranges = <0 0 0x02000000 0 0xdffe0500 0x100 | ||
| 49 | 1 0 0x02000000 0 0xdffe0600 0x100 | ||
| 50 | 2 0 0x02000000 0 0xdffe0700 0x100>; | ||
| 51 | |||
| 52 | i2c@0 { | ||
| 53 | #address-cells = <1>; | ||
| 54 | #size-cells = <0>; | ||
| 55 | compatible = "intel,ce4100-i2c-controller"; | ||
| 56 | |||
| 57 | /* The first number in the reg property is the | ||
| 58 | * number of the bar | ||
| 59 | */ | ||
| 60 | reg = <0 0 0x100>; | ||
| 61 | |||
| 62 | /* This I2C controller has no devices */ | ||
| 63 | }; | ||
| 64 | |||
| 65 | i2c@1 { | ||
| 66 | #address-cells = <1>; | ||
| 67 | #size-cells = <0>; | ||
| 68 | compatible = "intel,ce4100-i2c-controller"; | ||
| 69 | reg = <1 0 0x100>; | ||
| 70 | |||
| 71 | /* This I2C controller has one gpio controller */ | ||
| 72 | gpio@26 { | ||
| 73 | #gpio-cells = <2>; | ||
| 74 | compatible = "ti,pcf8575"; | ||
| 75 | reg = <0x26>; | ||
| 76 | gpio-controller; | ||
| 77 | }; | ||
| 78 | }; | ||
| 79 | |||
| 80 | i2c@2 { | ||
| 81 | #address-cells = <1>; | ||
| 82 | #size-cells = <0>; | ||
| 83 | compatible = "intel,ce4100-i2c-controller"; | ||
| 84 | reg = <2 0 0x100>; | ||
| 85 | |||
| 86 | gpio@26 { | ||
| 87 | #gpio-cells = <2>; | ||
| 88 | compatible = "ti,pcf8575"; | ||
| 89 | reg = <0x26>; | ||
| 90 | gpio-controller; | ||
| 91 | }; | ||
| 92 | }; | ||
| 93 | }; | ||
diff --git a/Documentation/devicetree/bindings/rtc/rtc-cmos.txt b/Documentation/devicetree/bindings/rtc/rtc-cmos.txt new file mode 100644 index 00000000000..7382989b305 --- /dev/null +++ b/Documentation/devicetree/bindings/rtc/rtc-cmos.txt | |||
| @@ -0,0 +1,28 @@ | |||
| 1 | Motorola mc146818 compatible RTC | ||
| 2 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| 3 | |||
| 4 | Required properties: | ||
| 5 | - compatible : "motorola,mc146818" | ||
| 6 | - reg : should contain registers location and length. | ||
| 7 | |||
| 8 | Optional properties: | ||
| 9 | - interrupts : should contain interrupt. | ||
| 10 | - interrupt-parent : interrupt source phandle. | ||
| 11 | - ctrl-reg : Contains the initial value of the control register also | ||
| 12 | called "Register B". | ||
| 13 | - freq-reg : Contains the initial value of the frequency register also | ||
| 14 | called "Regsiter A". | ||
| 15 | |||
| 16 | "Register A" and "B" are usually initialized by the firmware (BIOS for | ||
| 17 | instance). If this is not done, it can be performed by the driver. | ||
| 18 | |||
| 19 | ISA Example: | ||
| 20 | |||
| 21 | rtc@70 { | ||
| 22 | compatible = "motorola,mc146818"; | ||
| 23 | interrupts = <8 3>; | ||
| 24 | interrupt-parent = <&ioapic1>; | ||
| 25 | ctrl-reg = <2>; | ||
| 26 | freq-reg = <0x26>; | ||
| 27 | reg = <1 0x70 2>; | ||
| 28 | }; | ||
diff --git a/Documentation/devicetree/bindings/x86/ce4100.txt b/Documentation/devicetree/bindings/x86/ce4100.txt new file mode 100644 index 00000000000..b49ae593a60 --- /dev/null +++ b/Documentation/devicetree/bindings/x86/ce4100.txt | |||
| @@ -0,0 +1,38 @@ | |||
| 1 | CE4100 Device Tree Bindings | ||
| 2 | --------------------------- | ||
| 3 | |||
| 4 | The CE4100 SoC uses for in core peripherals the following compatible | ||
| 5 | format: <vendor>,<chip>-<device>. | ||
| 6 | Many of the "generic" devices like HPET or IO APIC have the ce4100 | ||
| 7 | name in their compatible property because they first appeared in this | ||
| 8 | SoC. | ||
| 9 | |||
| 10 | The CPU node | ||
| 11 | ------------ | ||
| 12 | cpu@0 { | ||
| 13 | device_type = "cpu"; | ||
| 14 | compatible = "intel,ce4100"; | ||
| 15 | reg = <0>; | ||
| 16 | lapic = <&lapic0>; | ||
| 17 | }; | ||
| 18 | |||
| 19 | The reg property describes the CPU number. The lapic property points to | ||
| 20 | the local APIC timer. | ||
| 21 | |||
| 22 | The SoC node | ||
| 23 | ------------ | ||
| 24 | |||
| 25 | This node describes the in-core peripherals. Required property: | ||
| 26 | compatible = "intel,ce4100-cp"; | ||
| 27 | |||
| 28 | The PCI node | ||
| 29 | ------------ | ||
| 30 | This node describes the PCI bus on the SoC. Its property should be | ||
| 31 | compatible = "intel,ce4100-pci", "pci"; | ||
| 32 | |||
| 33 | If the OS is using the IO-APIC for interrupt routing then the reported | ||
| 34 | interrupt numbers for devices is no longer true. In order to obtain the | ||
| 35 | correct interrupt number, the child node which represents the device has | ||
| 36 | to contain the interrupt property. Besides the interrupt property it has | ||
| 37 | to contain at least the reg property containing the PCI bus address and | ||
| 38 | 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 index 00000000000..7d19f494f19 --- /dev/null +++ b/Documentation/devicetree/bindings/x86/interrupt.txt | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | Interrupt chips | ||
| 2 | --------------- | ||
| 3 | |||
| 4 | * Intel I/O Advanced Programmable Interrupt Controller (IO APIC) | ||
| 5 | |||
| 6 | Required properties: | ||
| 7 | -------------------- | ||
| 8 | compatible = "intel,ce4100-ioapic"; | ||
| 9 | #interrupt-cells = <2>; | ||
| 10 | |||
| 11 | Device's interrupt property: | ||
| 12 | |||
| 13 | interrupts = <P S>; | ||
| 14 | |||
| 15 | The first number (P) represents the interrupt pin which is wired to the | ||
| 16 | IO APIC. The second number (S) represents the sense of interrupt which | ||
| 17 | should be configured and can be one of: | ||
| 18 | 0 - Edge Rising | ||
| 19 | 1 - Level Low | ||
| 20 | 2 - Level High | ||
| 21 | 3 - Edge Falling | ||
| 22 | |||
| 23 | * Local APIC | ||
| 24 | Required property: | ||
| 25 | |||
| 26 | compatible = "intel,ce4100-lapic"; | ||
diff --git a/Documentation/devicetree/bindings/x86/timer.txt b/Documentation/devicetree/bindings/x86/timer.txt new file mode 100644 index 00000000000..c688af58e3b --- /dev/null +++ b/Documentation/devicetree/bindings/x86/timer.txt | |||
| @@ -0,0 +1,6 @@ | |||
| 1 | Timers | ||
| 2 | ------ | ||
| 3 | |||
| 4 | * High Precision Event Timer (HPET) | ||
| 5 | Required property: | ||
| 6 | compatible = "intel,ce4100-hpet"; | ||
diff --git a/Documentation/devicetree/booting-without-of.txt b/Documentation/devicetree/booting-without-of.txt index 28b1c9d3d35..55fd2623445 100644 --- a/Documentation/devicetree/booting-without-of.txt +++ b/Documentation/devicetree/booting-without-of.txt | |||
| @@ -13,6 +13,7 @@ Table of Contents | |||
| 13 | 13 | ||
| 14 | I - Introduction | 14 | I - Introduction |
| 15 | 1) Entry point for arch/powerpc | 15 | 1) Entry point for arch/powerpc |
| 16 | 2) Entry point for arch/x86 | ||
| 16 | 17 | ||
| 17 | II - The DT block format | 18 | II - The DT block format |
| 18 | 1) Header | 19 | 1) Header |
| @@ -225,6 +226,25 @@ it with special cases. | |||
| 225 | cannot support both configurations with Book E and configurations | 226 | cannot support both configurations with Book E and configurations |
| 226 | with classic Powerpc architectures. | 227 | with classic Powerpc architectures. |
| 227 | 228 | ||
| 229 | 2) Entry point for arch/x86 | ||
| 230 | ------------------------------- | ||
| 231 | |||
| 232 | There is one single 32bit entry point to the kernel at code32_start, | ||
| 233 | the decompressor (the real mode entry point goes to the same 32bit | ||
| 234 | entry point once it switched into protected mode). That entry point | ||
| 235 | supports one calling convention which is documented in | ||
| 236 | Documentation/x86/boot.txt | ||
| 237 | The physical pointer to the device-tree block (defined in chapter II) | ||
| 238 | is passed via setup_data which requires at least boot protocol 2.09. | ||
| 239 | The type filed is defined as | ||
| 240 | |||
| 241 | #define SETUP_DTB 2 | ||
| 242 | |||
| 243 | This device-tree is used as an extension to the "boot page". As such it | ||
| 244 | does not parse / consider data which is already covered by the boot | ||
| 245 | page. This includes memory size, reserved ranges, command line arguments | ||
| 246 | or initrd address. It simply holds information which can not be retrieved | ||
| 247 | otherwise like interrupt routing or a list of devices behind an I2C bus. | ||
| 228 | 248 | ||
| 229 | II - The DT block format | 249 | II - The DT block format |
| 230 | ======================== | 250 | ======================== |
diff --git a/arch/microblaze/include/asm/pci-bridge.h b/arch/microblaze/include/asm/pci-bridge.h index 0c68764ab54..10717669e0c 100644 --- a/arch/microblaze/include/asm/pci-bridge.h +++ b/arch/microblaze/include/asm/pci-bridge.h | |||
| @@ -104,11 +104,22 @@ struct pci_controller { | |||
| 104 | int global_number; /* PCI domain number */ | 104 | int global_number; /* PCI domain number */ |
| 105 | }; | 105 | }; |
| 106 | 106 | ||
| 107 | #ifdef CONFIG_PCI | ||
| 107 | static inline struct pci_controller *pci_bus_to_host(const struct pci_bus *bus) | 108 | static inline struct pci_controller *pci_bus_to_host(const struct pci_bus *bus) |
| 108 | { | 109 | { |
| 109 | return bus->sysdata; | 110 | return bus->sysdata; |
| 110 | } | 111 | } |
| 111 | 112 | ||
| 113 | static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus) | ||
| 114 | { | ||
| 115 | struct pci_controller *host; | ||
| 116 | |||
| 117 | if (bus->self) | ||
| 118 | return pci_device_to_OF_node(bus->self); | ||
| 119 | host = pci_bus_to_host(bus); | ||
| 120 | return host ? host->dn : NULL; | ||
| 121 | } | ||
| 122 | |||
| 112 | static inline int isa_vaddr_is_ioport(void __iomem *address) | 123 | static inline int isa_vaddr_is_ioport(void __iomem *address) |
| 113 | { | 124 | { |
| 114 | /* No specific ISA handling on ppc32 at this stage, it | 125 | /* No specific ISA handling on ppc32 at this stage, it |
| @@ -116,6 +127,7 @@ static inline int isa_vaddr_is_ioport(void __iomem *address) | |||
| 116 | */ | 127 | */ |
| 117 | return 0; | 128 | return 0; |
| 118 | } | 129 | } |
| 130 | #endif /* CONFIG_PCI */ | ||
| 119 | 131 | ||
| 120 | /* These are used for config access before all the PCI probing | 132 | /* These are used for config access before all the PCI probing |
| 121 | has been done. */ | 133 | has been done. */ |
diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h index 2e72af078b0..d0890d36ef6 100644 --- a/arch/microblaze/include/asm/prom.h +++ b/arch/microblaze/include/asm/prom.h | |||
| @@ -64,21 +64,6 @@ extern void kdump_move_device_tree(void); | |||
| 64 | /* CPU OF node matching */ | 64 | /* CPU OF node matching */ |
| 65 | struct device_node *of_get_cpu_node(int cpu, unsigned int *thread); | 65 | struct device_node *of_get_cpu_node(int cpu, unsigned int *thread); |
| 66 | 66 | ||
| 67 | /** | ||
| 68 | * of_irq_map_pci - Resolve the interrupt for a PCI device | ||
| 69 | * @pdev: the device whose interrupt is to be resolved | ||
| 70 | * @out_irq: structure of_irq filled by this function | ||
| 71 | * | ||
| 72 | * This function resolves the PCI interrupt for a given PCI device. If a | ||
| 73 | * device-node exists for a given pci_dev, it will use normal OF tree | ||
| 74 | * walking. If not, it will implement standard swizzling and walk up the | ||
| 75 | * PCI tree until an device-node is found, at which point it will finish | ||
| 76 | * resolving using the OF tree walking. | ||
| 77 | */ | ||
| 78 | struct pci_dev; | ||
| 79 | struct of_irq; | ||
| 80 | extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq); | ||
| 81 | |||
| 82 | #endif /* __ASSEMBLY__ */ | 67 | #endif /* __ASSEMBLY__ */ |
| 83 | #endif /* __KERNEL__ */ | 68 | #endif /* __KERNEL__ */ |
| 84 | 69 | ||
diff --git a/arch/microblaze/kernel/prom_parse.c b/arch/microblaze/kernel/prom_parse.c index 9ae24f4b882..47187cc2cf0 100644 --- a/arch/microblaze/kernel/prom_parse.c +++ b/arch/microblaze/kernel/prom_parse.c | |||
| @@ -2,88 +2,11 @@ | |||
| 2 | 2 | ||
| 3 | #include <linux/kernel.h> | 3 | #include <linux/kernel.h> |
| 4 | #include <linux/string.h> | 4 | #include <linux/string.h> |
| 5 | #include <linux/pci_regs.h> | ||
| 6 | #include <linux/module.h> | 5 | #include <linux/module.h> |
| 7 | #include <linux/ioport.h> | 6 | #include <linux/ioport.h> |
| 8 | #include <linux/etherdevice.h> | 7 | #include <linux/etherdevice.h> |
| 9 | #include <linux/of_address.h> | 8 | #include <linux/of_address.h> |
| 10 | #include <asm/prom.h> | 9 | #include <asm/prom.h> |
| 11 | #include <asm/pci-bridge.h> | ||
| 12 | |||
| 13 | #ifdef CONFIG_PCI | ||
| 14 | int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq) | ||
| 15 | { | ||
| 16 | struct device_node *dn, *ppnode; | ||
| 17 | struct pci_dev *ppdev; | ||
| 18 | u32 lspec; | ||
| 19 | u32 laddr[3]; | ||
| 20 | u8 pin; | ||
| 21 | int rc; | ||
| 22 | |||
| 23 | /* Check if we have a device node, if yes, fallback to standard OF | ||
| 24 | * parsing | ||
| 25 | */ | ||
| 26 | dn = pci_device_to_OF_node(pdev); | ||
| 27 | if (dn) | ||
| 28 | return of_irq_map_one(dn, 0, out_irq); | ||
| 29 | |||
| 30 | /* Ok, we don't, time to have fun. Let's start by building up an | ||
| 31 | * interrupt spec. we assume #interrupt-cells is 1, which is standard | ||
| 32 | * for PCI. If you do different, then don't use that routine. | ||
| 33 | */ | ||
| 34 | rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin); | ||
| 35 | if (rc != 0) | ||
| 36 | return rc; | ||
| 37 | /* No pin, exit */ | ||
| 38 | if (pin == 0) | ||
| 39 | return -ENODEV; | ||
| 40 | |||
| 41 | /* Now we walk up the PCI tree */ | ||
| 42 | lspec = pin; | ||
| 43 | for (;;) { | ||
| 44 | /* Get the pci_dev of our parent */ | ||
| 45 | ppdev = pdev->bus->self; | ||
| 46 | |||
| 47 | /* Ouch, it's a host bridge... */ | ||
| 48 | if (ppdev == NULL) { | ||
| 49 | struct pci_controller *host; | ||
| 50 | host = pci_bus_to_host(pdev->bus); | ||
| 51 | ppnode = host ? host->dn : NULL; | ||
| 52 | /* No node for host bridge ? give up */ | ||
| 53 | if (ppnode == NULL) | ||
| 54 | return -EINVAL; | ||
| 55 | } else | ||
| 56 | /* We found a P2P bridge, check if it has a node */ | ||
| 57 | ppnode = pci_device_to_OF_node(ppdev); | ||
| 58 | |||
| 59 | /* Ok, we have found a parent with a device-node, hand over to | ||
| 60 | * the OF parsing code. | ||
| 61 | * We build a unit address from the linux device to be used for | ||
| 62 | * resolution. Note that we use the linux bus number which may | ||
| 63 | * not match your firmware bus numbering. | ||
| 64 | * Fortunately, in most cases, interrupt-map-mask doesn't | ||
| 65 | * include the bus number as part of the matching. | ||
| 66 | * You should still be careful about that though if you intend | ||
| 67 | * to rely on this function (you ship a firmware that doesn't | ||
| 68 | * create device nodes for all PCI devices). | ||
| 69 | */ | ||
| 70 | if (ppnode) | ||
| 71 | break; | ||
| 72 | |||
| 73 | /* We can only get here if we hit a P2P bridge with no node, | ||
| 74 | * let's do standard swizzling and try again | ||
| 75 | */ | ||
| 76 | lspec = pci_swizzle_interrupt_pin(pdev, lspec); | ||
| 77 | pdev = ppdev; | ||
| 78 | } | ||
| 79 | |||
| 80 | laddr[0] = (pdev->bus->number << 16) | ||
| 81 | | (pdev->devfn << 8); | ||
| 82 | laddr[1] = laddr[2] = 0; | ||
| 83 | return of_irq_map_raw(ppnode, &lspec, 1, laddr, out_irq); | ||
| 84 | } | ||
| 85 | EXPORT_SYMBOL_GPL(of_irq_map_pci); | ||
| 86 | #endif /* CONFIG_PCI */ | ||
| 87 | 10 | ||
| 88 | void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop, | 11 | void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop, |
| 89 | unsigned long *busno, unsigned long *phys, unsigned long *size) | 12 | unsigned long *busno, unsigned long *phys, unsigned long *size) |
diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c index e363615d679..1e01a125363 100644 --- a/arch/microblaze/pci/pci-common.c +++ b/arch/microblaze/pci/pci-common.c | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
| 30 | #include <linux/of.h> | 30 | #include <linux/of.h> |
| 31 | #include <linux/of_address.h> | 31 | #include <linux/of_address.h> |
| 32 | #include <linux/of_pci.h> | ||
| 32 | 33 | ||
| 33 | #include <asm/processor.h> | 34 | #include <asm/processor.h> |
| 34 | #include <asm/io.h> | 35 | #include <asm/io.h> |
diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h index 51e9e6f90d1..edeb80fdd2c 100644 --- a/arch/powerpc/include/asm/pci-bridge.h +++ b/arch/powerpc/include/asm/pci-bridge.h | |||
| @@ -171,6 +171,16 @@ static inline struct pci_controller *pci_bus_to_host(const struct pci_bus *bus) | |||
| 171 | return bus->sysdata; | 171 | return bus->sysdata; |
| 172 | } | 172 | } |
| 173 | 173 | ||
| 174 | static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus) | ||
| 175 | { | ||
| 176 | struct pci_controller *host; | ||
| 177 | |||
| 178 | if (bus->self) | ||
| 179 | return pci_device_to_OF_node(bus->self); | ||
| 180 | host = pci_bus_to_host(bus); | ||
| 181 | return host ? host->dn : NULL; | ||
| 182 | } | ||
| 183 | |||
| 174 | static inline int isa_vaddr_is_ioport(void __iomem *address) | 184 | static inline int isa_vaddr_is_ioport(void __iomem *address) |
| 175 | { | 185 | { |
| 176 | /* No specific ISA handling on ppc32 at this stage, it | 186 | /* No specific ISA handling on ppc32 at this stage, it |
diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h index d7275758559..c189aa5fe1f 100644 --- a/arch/powerpc/include/asm/prom.h +++ b/arch/powerpc/include/asm/prom.h | |||
| @@ -70,21 +70,6 @@ static inline int of_node_to_nid(struct device_node *device) { return 0; } | |||
| 70 | #endif | 70 | #endif |
| 71 | #define of_node_to_nid of_node_to_nid | 71 | #define of_node_to_nid of_node_to_nid |
| 72 | 72 | ||
| 73 | /** | ||
| 74 | * of_irq_map_pci - Resolve the interrupt for a PCI device | ||
| 75 | * @pdev: the device whose interrupt is to be resolved | ||
| 76 | * @out_irq: structure of_irq filled by this function | ||
| 77 | * | ||
| 78 | * This function resolves the PCI interrupt for a given PCI device. If a | ||
| 79 | * device-node exists for a given pci_dev, it will use normal OF tree | ||
| 80 | * walking. If not, it will implement standard swizzling and walk up the | ||
| 81 | * PCI tree until an device-node is found, at which point it will finish | ||
| 82 | * resolving using the OF tree walking. | ||
| 83 | */ | ||
| 84 | struct pci_dev; | ||
| 85 | struct of_irq; | ||
| 86 | extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq); | ||
| 87 | |||
| 88 | extern void of_instantiate_rtc(void); | 73 | extern void of_instantiate_rtc(void); |
| 89 | 74 | ||
| 90 | /* These includes are put at the bottom because they may contain things | 75 | /* These includes are put at the bottom because they may contain things |
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index 10a44e68ef1..eb341be9a4d 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | #include <linux/init.h> | 22 | #include <linux/init.h> |
| 23 | #include <linux/bootmem.h> | 23 | #include <linux/bootmem.h> |
| 24 | #include <linux/of_address.h> | 24 | #include <linux/of_address.h> |
| 25 | #include <linux/of_pci.h> | ||
| 25 | #include <linux/mm.h> | 26 | #include <linux/mm.h> |
| 26 | #include <linux/list.h> | 27 | #include <linux/list.h> |
| 27 | #include <linux/syscalls.h> | 28 | #include <linux/syscalls.h> |
diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c index c2b7a07cc3d..47187cc2cf0 100644 --- a/arch/powerpc/kernel/prom_parse.c +++ b/arch/powerpc/kernel/prom_parse.c | |||
| @@ -2,95 +2,11 @@ | |||
| 2 | 2 | ||
| 3 | #include <linux/kernel.h> | 3 | #include <linux/kernel.h> |
| 4 | #include <linux/string.h> | 4 | #include <linux/string.h> |
| 5 | #include <linux/pci_regs.h> | ||
| 6 | #include <linux/module.h> | 5 | #include <linux/module.h> |
| 7 | #include <linux/ioport.h> | 6 | #include <linux/ioport.h> |
| 8 | #include <linux/etherdevice.h> | 7 | #include <linux/etherdevice.h> |
| 9 | #include <linux/of_address.h> | 8 | #include <linux/of_address.h> |
| 10 | #include <asm/prom.h> | 9 | #include <asm/prom.h> |
| 11 | #include <asm/pci-bridge.h> | ||
| 12 | |||
| 13 | #ifdef CONFIG_PCI | ||
| 14 | int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq) | ||
| 15 | { | ||
| 16 | struct device_node *dn, *ppnode; | ||
| 17 | struct pci_dev *ppdev; | ||
| 18 | u32 lspec; | ||
| 19 | u32 laddr[3]; | ||
| 20 | u8 pin; | ||
| 21 | int rc; | ||
| 22 | |||
| 23 | /* Check if we have a device node, if yes, fallback to standard OF | ||
| 24 | * parsing | ||
| 25 | */ | ||
| 26 | dn = pci_device_to_OF_node(pdev); | ||
| 27 | if (dn) { | ||
| 28 | rc = of_irq_map_one(dn, 0, out_irq); | ||
| 29 | if (!rc) | ||
| 30 | return rc; | ||
| 31 | } | ||
| 32 | |||
| 33 | /* Ok, we don't, time to have fun. Let's start by building up an | ||
| 34 | * interrupt spec. we assume #interrupt-cells is 1, which is standard | ||
| 35 | * for PCI. If you do different, then don't use that routine. | ||
| 36 | */ | ||
| 37 | rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin); | ||
| 38 | if (rc != 0) | ||
| 39 | return rc; | ||
| 40 | /* No pin, exit */ | ||
| 41 | if (pin == 0) | ||
| 42 | return -ENODEV; | ||
| 43 | |||
| 44 | /* Now we walk up the PCI tree */ | ||
| 45 | lspec = pin; | ||
| 46 | for (;;) { | ||
| 47 | /* Get the pci_dev of our parent */ | ||
| 48 | ppdev = pdev->bus->self; | ||
| 49 | |||
| 50 | /* Ouch, it's a host bridge... */ | ||
| 51 | if (ppdev == NULL) { | ||
| 52 | #ifdef CONFIG_PPC64 | ||
| 53 | ppnode = pci_bus_to_OF_node(pdev->bus); | ||
| 54 | #else | ||
| 55 | struct pci_controller *host; | ||
| 56 | host = pci_bus_to_host(pdev->bus); | ||
| 57 | ppnode = host ? host->dn : NULL; | ||
| 58 | #endif | ||
| 59 | /* No node for host bridge ? give up */ | ||
| 60 | if (ppnode == NULL) | ||
| 61 | return -EINVAL; | ||
| 62 | } else | ||
| 63 | /* We found a P2P bridge, check if it has a node */ | ||
| 64 | ppnode = pci_device_to_OF_node(ppdev); | ||
| 65 | |||
| 66 | /* Ok, we have found a parent with a device-node, hand over to | ||
| 67 | * the OF parsing code. | ||
| 68 | * We build a unit address from the linux device to be used for | ||
| 69 | * resolution. Note that we use the linux bus number which may | ||
| 70 | * not match your firmware bus numbering. | ||
| 71 | * Fortunately, in most cases, interrupt-map-mask doesn't include | ||
| 72 | * the bus number as part of the matching. | ||
| 73 | * You should still be careful about that though if you intend | ||
| 74 | * to rely on this function (you ship a firmware that doesn't | ||
| 75 | * create device nodes for all PCI devices). | ||
| 76 | */ | ||
| 77 | if (ppnode) | ||
| 78 | break; | ||
| 79 | |||
| 80 | /* We can only get here if we hit a P2P bridge with no node, | ||
| 81 | * let's do standard swizzling and try again | ||
| 82 | */ | ||
| 83 | lspec = pci_swizzle_interrupt_pin(pdev, lspec); | ||
| 84 | pdev = ppdev; | ||
| 85 | } | ||
| 86 | |||
| 87 | laddr[0] = (pdev->bus->number << 16) | ||
| 88 | | (pdev->devfn << 8); | ||
| 89 | laddr[1] = laddr[2] = 0; | ||
| 90 | return of_irq_map_raw(ppnode, &lspec, 1, laddr, out_irq); | ||
| 91 | } | ||
| 92 | EXPORT_SYMBOL_GPL(of_irq_map_pci); | ||
| 93 | #endif /* CONFIG_PCI */ | ||
| 94 | 10 | ||
| 95 | void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop, | 11 | void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop, |
| 96 | unsigned long *busno, unsigned long *phys, unsigned long *size) | 12 | unsigned long *busno, unsigned long *phys, unsigned long *size) |
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 159c2ff9c12..f8958b01b97 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
| @@ -386,6 +386,8 @@ config X86_INTEL_CE | |||
| 386 | depends on X86_32 | 386 | depends on X86_32 |
| 387 | depends on X86_EXTENDED_PLATFORM | 387 | depends on X86_EXTENDED_PLATFORM |
| 388 | select X86_REBOOTFIXUPS | 388 | select X86_REBOOTFIXUPS |
| 389 | select OF | ||
| 390 | select OF_EARLY_FLATTREE | ||
| 389 | ---help--- | 391 | ---help--- |
| 390 | Select for the Intel CE media processor (CE4100) SOC. | 392 | Select for the Intel CE media processor (CE4100) SOC. |
| 391 | This option compiles in support for the CE4100 SOC for settop | 393 | This option compiles in support for the CE4100 SOC for settop |
| @@ -2070,9 +2072,10 @@ config SCx200HR_TIMER | |||
| 2070 | 2072 | ||
| 2071 | config OLPC | 2073 | config OLPC |
| 2072 | bool "One Laptop Per Child support" | 2074 | bool "One Laptop Per Child support" |
| 2075 | depends on !X86_PAE | ||
| 2073 | select GPIOLIB | 2076 | select GPIOLIB |
| 2074 | select OLPC_OPENFIRMWARE | 2077 | select OF |
| 2075 | depends on !X86_64 && !X86_PAE | 2078 | select OF_PROMTREE if PROC_DEVICETREE |
| 2076 | ---help--- | 2079 | ---help--- |
| 2077 | Add support for detecting the unique features of the OLPC | 2080 | Add support for detecting the unique features of the OLPC |
| 2078 | XO hardware. | 2081 | XO hardware. |
| @@ -2083,21 +2086,6 @@ config OLPC_XO1 | |||
| 2083 | ---help--- | 2086 | ---help--- |
| 2084 | Add support for non-essential features of the OLPC XO-1 laptop. | 2087 | Add support for non-essential features of the OLPC XO-1 laptop. |
| 2085 | 2088 | ||
| 2086 | config OLPC_OPENFIRMWARE | ||
| 2087 | bool "Support for OLPC's Open Firmware" | ||
| 2088 | depends on !X86_64 && !X86_PAE | ||
| 2089 | default n | ||
| 2090 | select OF | ||
| 2091 | help | ||
| 2092 | This option adds support for the implementation of Open Firmware | ||
| 2093 | that is used on the OLPC XO-1 Children's Machine. | ||
| 2094 | If unsure, say N here. | ||
| 2095 | |||
| 2096 | config OLPC_OPENFIRMWARE_DT | ||
| 2097 | bool | ||
| 2098 | default y if OLPC_OPENFIRMWARE && PROC_DEVICETREE | ||
| 2099 | select OF_PROMTREE | ||
| 2100 | |||
| 2101 | endif # X86_32 | 2089 | endif # X86_32 |
| 2102 | 2090 | ||
| 2103 | config AMD_NB | 2091 | config AMD_NB |
diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index b8a3484d69e..a279d98ea95 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h | |||
| @@ -220,7 +220,6 @@ extern void enable_IR_x2apic(void); | |||
| 220 | 220 | ||
| 221 | extern int get_physical_broadcast(void); | 221 | extern int get_physical_broadcast(void); |
| 222 | 222 | ||
| 223 | extern void apic_disable(void); | ||
| 224 | extern int lapic_get_maxlvt(void); | 223 | extern int lapic_get_maxlvt(void); |
| 225 | extern void clear_local_APIC(void); | 224 | extern void clear_local_APIC(void); |
| 226 | extern void connect_bsp_APIC(void); | 225 | extern void connect_bsp_APIC(void); |
| @@ -228,7 +227,6 @@ extern void disconnect_bsp_APIC(int virt_wire_setup); | |||
| 228 | extern void disable_local_APIC(void); | 227 | extern void disable_local_APIC(void); |
| 229 | extern void lapic_shutdown(void); | 228 | extern void lapic_shutdown(void); |
| 230 | extern int verify_local_APIC(void); | 229 | extern int verify_local_APIC(void); |
| 231 | extern void cache_APIC_registers(void); | ||
| 232 | extern void sync_Arb_IDs(void); | 230 | extern void sync_Arb_IDs(void); |
| 233 | extern void init_bsp_APIC(void); | 231 | extern void init_bsp_APIC(void); |
| 234 | extern void setup_local_APIC(void); | 232 | extern void setup_local_APIC(void); |
| @@ -239,8 +237,7 @@ void register_lapic_address(unsigned long address); | |||
| 239 | extern void setup_boot_APIC_clock(void); | 237 | extern void setup_boot_APIC_clock(void); |
| 240 | extern void setup_secondary_APIC_clock(void); | 238 | extern void setup_secondary_APIC_clock(void); |
| 241 | extern int APIC_init_uniprocessor(void); | 239 | extern int APIC_init_uniprocessor(void); |
| 242 | extern void enable_NMI_through_LVT0(void); | 240 | extern int apic_force_enable(unsigned long addr); |
| 243 | extern int apic_force_enable(void); | ||
| 244 | 241 | ||
| 245 | /* | 242 | /* |
| 246 | * On 32bit this is mach-xxx local | 243 | * On 32bit this is mach-xxx local |
| @@ -261,7 +258,6 @@ static inline void lapic_shutdown(void) { } | |||
| 261 | #define local_apic_timer_c2_ok 1 | 258 | #define local_apic_timer_c2_ok 1 |
| 262 | static inline void init_apic_mappings(void) { } | 259 | static inline void init_apic_mappings(void) { } |
| 263 | static inline void disable_local_APIC(void) { } | 260 | static inline void disable_local_APIC(void) { } |
| 264 | static inline void apic_disable(void) { } | ||
| 265 | # define setup_boot_APIC_clock x86_init_noop | 261 | # define setup_boot_APIC_clock x86_init_noop |
| 266 | # define setup_secondary_APIC_clock x86_init_noop | 262 | # define setup_secondary_APIC_clock x86_init_noop |
| 267 | #endif /* !CONFIG_X86_LOCAL_APIC */ | 263 | #endif /* !CONFIG_X86_LOCAL_APIC */ |
diff --git a/arch/x86/include/asm/bootparam.h b/arch/x86/include/asm/bootparam.h index c8bfe63a06d..e020d88ec02 100644 --- a/arch/x86/include/asm/bootparam.h +++ b/arch/x86/include/asm/bootparam.h | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | /* setup data types */ | 12 | /* setup data types */ |
| 13 | #define SETUP_NONE 0 | 13 | #define SETUP_NONE 0 |
| 14 | #define SETUP_E820_EXT 1 | 14 | #define SETUP_E820_EXT 1 |
| 15 | #define SETUP_DTB 2 | ||
| 15 | 16 | ||
| 16 | /* extensible setup data list node */ | 17 | /* extensible setup data list node */ |
| 17 | struct setup_data { | 18 | struct setup_data { |
diff --git a/arch/x86/include/asm/e820.h b/arch/x86/include/asm/e820.h index e99d55d74df..908b96957d8 100644 --- a/arch/x86/include/asm/e820.h +++ b/arch/x86/include/asm/e820.h | |||
| @@ -96,7 +96,7 @@ extern void e820_setup_gap(void); | |||
| 96 | extern int e820_search_gap(unsigned long *gapstart, unsigned long *gapsize, | 96 | extern int e820_search_gap(unsigned long *gapstart, unsigned long *gapsize, |
| 97 | unsigned long start_addr, unsigned long long end_addr); | 97 | unsigned long start_addr, unsigned long long end_addr); |
| 98 | struct setup_data; | 98 | struct setup_data; |
| 99 | extern void parse_e820_ext(struct setup_data *data, unsigned long pa_data); | 99 | extern void parse_e820_ext(struct setup_data *data); |
| 100 | 100 | ||
| 101 | #if defined(CONFIG_X86_64) || \ | 101 | #if defined(CONFIG_X86_64) || \ |
| 102 | (defined(CONFIG_X86_32) && defined(CONFIG_HIBERNATION)) | 102 | (defined(CONFIG_X86_32) && defined(CONFIG_HIBERNATION)) |
diff --git a/arch/x86/include/asm/irq.h b/arch/x86/include/asm/irq.h index c704b38c57a..ba870bb6dd8 100644 --- a/arch/x86/include/asm/irq.h +++ b/arch/x86/include/asm/irq.h | |||
| @@ -10,9 +10,6 @@ | |||
| 10 | #include <asm/apicdef.h> | 10 | #include <asm/apicdef.h> |
| 11 | #include <asm/irq_vectors.h> | 11 | #include <asm/irq_vectors.h> |
| 12 | 12 | ||
| 13 | /* Even though we don't support this, supply it to appease OF */ | ||
| 14 | static inline void irq_dispose_mapping(unsigned int virq) { } | ||
| 15 | |||
| 16 | static inline int irq_canonicalize(int irq) | 13 | static inline int irq_canonicalize(int irq) |
| 17 | { | 14 | { |
| 18 | return ((irq == 2) ? 9 : irq); | 15 | 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 index 00000000000..423bbbddf36 --- /dev/null +++ b/arch/x86/include/asm/irq_controller.h | |||
| @@ -0,0 +1,12 @@ | |||
| 1 | #ifndef __IRQ_CONTROLLER__ | ||
| 2 | #define __IRQ_CONTROLLER__ | ||
| 3 | |||
| 4 | struct irq_domain { | ||
| 5 | int (*xlate)(struct irq_domain *h, const u32 *intspec, u32 intsize, | ||
| 6 | u32 *out_hwirq, u32 *out_type); | ||
| 7 | void *priv; | ||
| 8 | struct device_node *controller; | ||
| 9 | struct list_head l; | ||
| 10 | }; | ||
| 11 | |||
| 12 | #endif | ||
diff --git a/arch/x86/include/asm/olpc_ofw.h b/arch/x86/include/asm/olpc_ofw.h index 641988efe06..c5d3a5abbb9 100644 --- a/arch/x86/include/asm/olpc_ofw.h +++ b/arch/x86/include/asm/olpc_ofw.h | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | 6 | ||
| 7 | #define OLPC_OFW_SIG 0x2057464F /* aka "OFW " */ | 7 | #define OLPC_OFW_SIG 0x2057464F /* aka "OFW " */ |
| 8 | 8 | ||
| 9 | #ifdef CONFIG_OLPC_OPENFIRMWARE | 9 | #ifdef CONFIG_OLPC |
| 10 | 10 | ||
| 11 | extern bool olpc_ofw_is_installed(void); | 11 | extern bool olpc_ofw_is_installed(void); |
| 12 | 12 | ||
| @@ -26,19 +26,15 @@ extern void setup_olpc_ofw_pgd(void); | |||
| 26 | /* check if OFW was detected during boot */ | 26 | /* check if OFW was detected during boot */ |
| 27 | extern bool olpc_ofw_present(void); | 27 | extern bool olpc_ofw_present(void); |
| 28 | 28 | ||
| 29 | #else /* !CONFIG_OLPC_OPENFIRMWARE */ | 29 | #else /* !CONFIG_OLPC */ |
| 30 | |||
| 31 | static inline bool olpc_ofw_is_installed(void) { return false; } | ||
| 32 | static inline void olpc_ofw_detect(void) { } | 30 | static inline void olpc_ofw_detect(void) { } |
| 33 | static inline void setup_olpc_ofw_pgd(void) { } | 31 | static inline void setup_olpc_ofw_pgd(void) { } |
| 34 | static inline bool olpc_ofw_present(void) { return false; } | 32 | #endif /* !CONFIG_OLPC */ |
| 35 | |||
| 36 | #endif /* !CONFIG_OLPC_OPENFIRMWARE */ | ||
| 37 | 33 | ||
| 38 | #ifdef CONFIG_OLPC_OPENFIRMWARE_DT | 34 | #ifdef CONFIG_OF_PROMTREE |
| 39 | extern void olpc_dt_build_devicetree(void); | 35 | extern void olpc_dt_build_devicetree(void); |
| 40 | #else | 36 | #else |
| 41 | static inline void olpc_dt_build_devicetree(void) { } | 37 | static inline void olpc_dt_build_devicetree(void) { } |
| 42 | #endif /* CONFIG_OLPC_OPENFIRMWARE_DT */ | 38 | #endif |
| 43 | 39 | ||
| 44 | #endif /* _ASM_X86_OLPC_OFW_H */ | 40 | #endif /* _ASM_X86_OLPC_OFW_H */ |
diff --git a/arch/x86/include/asm/prom.h b/arch/x86/include/asm/prom.h index b4ec95f0751..971e0b46446 100644 --- a/arch/x86/include/asm/prom.h +++ b/arch/x86/include/asm/prom.h | |||
| @@ -1 +1,69 @@ | |||
| 1 | /* dummy prom.h; here to make linux/of.h's #includes happy */ | 1 | /* |
| 2 | * Definitions for Device tree / OpenFirmware handling on X86 | ||
| 3 | * | ||
| 4 | * based on arch/powerpc/include/asm/prom.h which is | ||
| 5 | * Copyright (C) 1996-2005 Paul Mackerras. | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or | ||
| 8 | * modify it under the terms of the GNU General Public License | ||
| 9 | * as published by the Free Software Foundation; either version | ||
| 10 | * 2 of the License, or (at your option) any later version. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #ifndef _ASM_X86_PROM_H | ||
| 14 | #define _ASM_X86_PROM_H | ||
| 15 | #ifndef __ASSEMBLY__ | ||
| 16 | |||
| 17 | #include <linux/of.h> | ||
| 18 | #include <linux/types.h> | ||
| 19 | #include <linux/pci.h> | ||
| 20 | |||
| 21 | #include <asm/irq.h> | ||
| 22 | #include <asm/atomic.h> | ||
| 23 | #include <asm/setup.h> | ||
| 24 | #include <asm/irq_controller.h> | ||
| 25 | |||
| 26 | #ifdef CONFIG_OF | ||
| 27 | extern int of_ioapic; | ||
| 28 | extern u64 initial_dtb; | ||
| 29 | extern void add_dtb(u64 data); | ||
| 30 | extern void x86_add_irq_domains(void); | ||
| 31 | void __cpuinit x86_of_pci_init(void); | ||
| 32 | void x86_dtb_init(void); | ||
| 33 | |||
| 34 | static inline struct device_node *pci_device_to_OF_node(struct pci_dev *pdev) | ||
| 35 | { | ||
| 36 | return pdev ? pdev->dev.of_node : NULL; | ||
| 37 | } | ||
| 38 | |||
| 39 | static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus) | ||
| 40 | { | ||
| 41 | return pci_device_to_OF_node(bus->self); | ||
| 42 | } | ||
| 43 | |||
| 44 | #else | ||
| 45 | static inline void add_dtb(u64 data) { } | ||
| 46 | static inline void x86_add_irq_domains(void) { } | ||
| 47 | static inline void x86_of_pci_init(void) { } | ||
| 48 | static inline void x86_dtb_init(void) { } | ||
| 49 | #define of_ioapic 0 | ||
| 50 | #endif | ||
| 51 | |||
| 52 | extern char cmd_line[COMMAND_LINE_SIZE]; | ||
| 53 | |||
| 54 | #define pci_address_to_pio pci_address_to_pio | ||
| 55 | unsigned long pci_address_to_pio(phys_addr_t addr); | ||
| 56 | |||
| 57 | /** | ||
| 58 | * irq_dispose_mapping - Unmap an interrupt | ||
| 59 | * @virq: linux virq number of the interrupt to unmap | ||
| 60 | * | ||
| 61 | * FIXME: We really should implement proper virq handling like power, | ||
| 62 | * but that's going to be major surgery. | ||
| 63 | */ | ||
| 64 | static inline void irq_dispose_mapping(unsigned int virq) { } | ||
| 65 | |||
| 66 | #define HAVE_ARCH_DEVTREE_FIXUPS | ||
| 67 | |||
| 68 | #endif /* __ASSEMBLY__ */ | ||
| 69 | #endif | ||
diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h index 64642ad019f..643ebf2e2ad 100644 --- a/arch/x86/include/asm/x86_init.h +++ b/arch/x86/include/asm/x86_init.h | |||
| @@ -83,11 +83,13 @@ struct x86_init_paging { | |||
| 83 | * boot cpu | 83 | * boot cpu |
| 84 | * @tsc_pre_init: platform function called before TSC init | 84 | * @tsc_pre_init: platform function called before TSC init |
| 85 | * @timer_init: initialize the platform timer (default PIT/HPET) | 85 | * @timer_init: initialize the platform timer (default PIT/HPET) |
| 86 | * @wallclock_init: init the wallclock device | ||
| 86 | */ | 87 | */ |
| 87 | struct x86_init_timers { | 88 | struct x86_init_timers { |
| 88 | void (*setup_percpu_clockev)(void); | 89 | void (*setup_percpu_clockev)(void); |
| 89 | void (*tsc_pre_init)(void); | 90 | void (*tsc_pre_init)(void); |
| 90 | void (*timer_init)(void); | 91 | void (*timer_init)(void); |
| 92 | void (*wallclock_init)(void); | ||
| 91 | }; | 93 | }; |
| 92 | 94 | ||
| 93 | /** | 95 | /** |
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 34244b2cd88..62445ba2f8a 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile | |||
| @@ -66,9 +66,9 @@ obj-$(CONFIG_PCI) += early-quirks.o | |||
| 66 | apm-y := apm_32.o | 66 | apm-y := apm_32.o |
| 67 | obj-$(CONFIG_APM) += apm.o | 67 | obj-$(CONFIG_APM) += apm.o |
| 68 | obj-$(CONFIG_SMP) += smp.o | 68 | obj-$(CONFIG_SMP) += smp.o |
| 69 | obj-$(CONFIG_SMP) += smpboot.o tsc_sync.o | 69 | obj-$(CONFIG_SMP) += smpboot.o |
| 70 | obj-$(CONFIG_SMP) += tsc_sync.o | ||
| 70 | obj-$(CONFIG_SMP) += setup_percpu.o | 71 | obj-$(CONFIG_SMP) += setup_percpu.o |
| 71 | obj-$(CONFIG_X86_64_SMP) += tsc_sync.o | ||
| 72 | obj-$(CONFIG_X86_TRAMPOLINE) += trampoline_$(BITS).o | 72 | obj-$(CONFIG_X86_TRAMPOLINE) += trampoline_$(BITS).o |
| 73 | obj-$(CONFIG_X86_MPPARSE) += mpparse.o | 73 | obj-$(CONFIG_X86_MPPARSE) += mpparse.o |
| 74 | obj-y += apic/ | 74 | obj-y += apic/ |
| @@ -109,6 +109,7 @@ obj-$(CONFIG_MICROCODE) += microcode.o | |||
| 109 | obj-$(CONFIG_X86_CHECK_BIOS_CORRUPTION) += check.o | 109 | obj-$(CONFIG_X86_CHECK_BIOS_CORRUPTION) += check.o |
| 110 | 110 | ||
| 111 | obj-$(CONFIG_SWIOTLB) += pci-swiotlb.o | 111 | obj-$(CONFIG_SWIOTLB) += pci-swiotlb.o |
| 112 | obj-$(CONFIG_OF) += devicetree.o | ||
| 112 | 113 | ||
| 113 | ### | 114 | ### |
| 114 | # 64 bit specific files | 115 | # 64 bit specific files |
diff --git a/arch/x86/kernel/apb_timer.c b/arch/x86/kernel/apb_timer.c index 51d4e166306..1293c709ee8 100644 --- a/arch/x86/kernel/apb_timer.c +++ b/arch/x86/kernel/apb_timer.c | |||
| @@ -508,64 +508,12 @@ static int apbt_next_event(unsigned long delta, | |||
| 508 | return 0; | 508 | return 0; |
| 509 | } | 509 | } |
| 510 | 510 | ||
| 511 | /* | ||
| 512 | * APB timer clock is not in sync with pclk on Langwell, which translates to | ||
| 513 | * unreliable read value caused by sampling error. the error does not add up | ||
| 514 | * overtime and only happens when sampling a 0 as a 1 by mistake. so the time | ||
| 515 | * would go backwards. the following code is trying to prevent time traveling | ||
| 516 | * backwards. little bit paranoid. | ||
| 517 | */ | ||
| 518 | static cycle_t apbt_read_clocksource(struct clocksource *cs) | 511 | static cycle_t apbt_read_clocksource(struct clocksource *cs) |
| 519 | { | 512 | { |
| 520 | unsigned long t0, t1, t2; | 513 | unsigned long current_count; |
| 521 | static unsigned long last_read; | 514 | |
| 522 | 515 | current_count = apbt_readl(phy_cs_timer_id, APBTMR_N_CURRENT_VALUE); | |
| 523 | bad_count: | 516 | return (cycle_t)~current_count; |
| 524 | t1 = apbt_readl(phy_cs_timer_id, | ||
| 525 | APBTMR_N_CURRENT_VALUE); | ||
| 526 | t2 = apbt_readl(phy_cs_timer_id, | ||
| 527 | APBTMR_N_CURRENT_VALUE); | ||
| 528 | if (unlikely(t1 < t2)) { | ||
| 529 | pr_debug("APBT: read current count error %lx:%lx:%lx\n", | ||
| 530 | t1, t2, t2 - t1); | ||
| 531 | goto bad_count; | ||
| 532 | } | ||
| 533 | /* | ||
| 534 | * check against cached last read, makes sure time does not go back. | ||
| 535 | * it could be a normal rollover but we will do tripple check anyway | ||
| 536 | */ | ||
| 537 | if (unlikely(t2 > last_read)) { | ||
| 538 | /* check if we have a normal rollover */ | ||
| 539 | unsigned long raw_intr_status = | ||
| 540 | apbt_readl_reg(APBTMRS_RAW_INT_STATUS); | ||
| 541 | /* | ||
| 542 | * cs timer interrupt is masked but raw intr bit is set if | ||
| 543 | * rollover occurs. then we read EOI reg to clear it. | ||
| 544 | */ | ||
| 545 | if (raw_intr_status & (1 << phy_cs_timer_id)) { | ||
| 546 | apbt_readl(phy_cs_timer_id, APBTMR_N_EOI); | ||
| 547 | goto out; | ||
| 548 | } | ||
| 549 | pr_debug("APB CS going back %lx:%lx:%lx ", | ||
| 550 | t2, last_read, t2 - last_read); | ||
| 551 | bad_count_x3: | ||
| 552 | pr_debug("triple check enforced\n"); | ||
| 553 | t0 = apbt_readl(phy_cs_timer_id, | ||
| 554 | APBTMR_N_CURRENT_VALUE); | ||
| 555 | udelay(1); | ||
| 556 | t1 = apbt_readl(phy_cs_timer_id, | ||
| 557 | APBTMR_N_CURRENT_VALUE); | ||
| 558 | udelay(1); | ||
| 559 | t2 = apbt_readl(phy_cs_timer_id, | ||
| 560 | APBTMR_N_CURRENT_VALUE); | ||
| 561 | if ((t2 > t1) || (t1 > t0)) { | ||
| 562 | printk(KERN_ERR "Error: APB CS tripple check failed\n"); | ||
| 563 | goto bad_count_x3; | ||
| 564 | } | ||
| 565 | } | ||
| 566 | out: | ||
| 567 | last_read = t2; | ||
| 568 | return (cycle_t)~t2; | ||
| 569 | } | 517 | } |
| 570 | 518 | ||
| 571 | static int apbt_clocksource_register(void) | 519 | static int apbt_clocksource_register(void) |
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 562a8325cc1..966673f4414 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c | |||
| @@ -93,7 +93,7 @@ DEFINE_EARLY_PER_CPU(int, x86_cpu_to_logical_apicid, BAD_APICID); | |||
| 93 | * | 93 | * |
| 94 | * +1=force-enable | 94 | * +1=force-enable |
| 95 | */ | 95 | */ |
| 96 | static int force_enable_local_apic; | 96 | static int force_enable_local_apic __initdata; |
| 97 | /* | 97 | /* |
| 98 | * APIC command line parameters | 98 | * APIC command line parameters |
| 99 | */ | 99 | */ |
| @@ -163,7 +163,7 @@ early_param("nox2apic", setup_nox2apic); | |||
| 163 | unsigned long mp_lapic_addr; | 163 | unsigned long mp_lapic_addr; |
| 164 | int disable_apic; | 164 | int disable_apic; |
| 165 | /* Disable local APIC timer from the kernel commandline or via dmi quirk */ | 165 | /* Disable local APIC timer from the kernel commandline or via dmi quirk */ |
| 166 | static int disable_apic_timer __cpuinitdata; | 166 | static int disable_apic_timer __initdata; |
| 167 | /* Local APIC timer works in C2 */ | 167 | /* Local APIC timer works in C2 */ |
| 168 | int local_apic_timer_c2_ok; | 168 | int local_apic_timer_c2_ok; |
| 169 | EXPORT_SYMBOL_GPL(local_apic_timer_c2_ok); | 169 | EXPORT_SYMBOL_GPL(local_apic_timer_c2_ok); |
| @@ -187,29 +187,8 @@ static struct resource lapic_resource = { | |||
| 187 | 187 | ||
| 188 | static unsigned int calibration_result; | 188 | static unsigned int calibration_result; |
| 189 | 189 | ||
| 190 | static int lapic_next_event(unsigned long delta, | ||
| 191 | struct clock_event_device *evt); | ||
| 192 | static void lapic_timer_setup(enum clock_event_mode mode, | ||
| 193 | struct clock_event_device *evt); | ||
| 194 | static void lapic_timer_broadcast(const struct cpumask *mask); | ||
| 195 | static void apic_pm_activate(void); | 190 | static void apic_pm_activate(void); |
| 196 | 191 | ||
| 197 | /* | ||
| 198 | * The local apic timer can be used for any function which is CPU local. | ||
| 199 | */ | ||
| 200 | static struct clock_event_device lapic_clockevent = { | ||
| 201 | .name = "lapic", | ||
| 202 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT | ||
| 203 | | CLOCK_EVT_FEAT_C3STOP | CLOCK_EVT_FEAT_DUMMY, | ||
| 204 | .shift = 32, | ||
| 205 | .set_mode = lapic_timer_setup, | ||
| 206 | .set_next_event = lapic_next_event, | ||
| 207 | .broadcast = lapic_timer_broadcast, | ||
| 208 | .rating = 100, | ||
| 209 | .irq = -1, | ||
| 210 | }; | ||
| 211 | static DEFINE_PER_CPU(struct clock_event_device, lapic_events); | ||
| 212 | |||
| 213 | static unsigned long apic_phys; | 192 | static unsigned long apic_phys; |
| 214 | 193 | ||
| 215 | /* | 194 | /* |
| @@ -248,7 +227,7 @@ static int modern_apic(void) | |||
| 248 | * right after this call apic become NOOP driven | 227 | * right after this call apic become NOOP driven |
| 249 | * so apic->write/read doesn't do anything | 228 | * so apic->write/read doesn't do anything |
| 250 | */ | 229 | */ |
| 251 | void apic_disable(void) | 230 | static void __init apic_disable(void) |
| 252 | { | 231 | { |
| 253 | pr_info("APIC: switched to apic NOOP\n"); | 232 | pr_info("APIC: switched to apic NOOP\n"); |
| 254 | apic = &apic_noop; | 233 | apic = &apic_noop; |
| @@ -292,23 +271,6 @@ u64 native_apic_icr_read(void) | |||
| 292 | return icr1 | ((u64)icr2 << 32); | 271 | return icr1 | ((u64)icr2 << 32); |
| 293 | } | 272 | } |
| 294 | 273 | ||
| 295 | /** | ||
| 296 | * enable_NMI_through_LVT0 - enable NMI through local vector table 0 | ||
| 297 | */ | ||
| 298 | void __cpuinit enable_NMI_through_LVT0(void) | ||
| 299 | { | ||
| 300 | unsigned int v; | ||
| 301 | |||
| 302 | /* unmask and set to NMI */ | ||
| 303 | v = APIC_DM_NMI; | ||
| 304 | |||
| 305 | /* Level triggered for 82489DX (32bit mode) */ | ||
| 306 | if (!lapic_is_integrated()) | ||
| 307 | v |= APIC_LVT_LEVEL_TRIGGER; | ||
| 308 | |||
| 309 | apic_write(APIC_LVT0, v); | ||
| 310 | } | ||
| 311 | |||
| 312 | #ifdef CONFIG_X86_32 | 274 | #ifdef CONFIG_X86_32 |
| 313 | /** | 275 | /** |
| 314 | * get_physical_broadcast - Get number of physical broadcast IDs | 276 | * get_physical_broadcast - Get number of physical broadcast IDs |
| @@ -518,6 +480,23 @@ static void lapic_timer_broadcast(const struct cpumask *mask) | |||
| 518 | #endif | 480 | #endif |
| 519 | } | 481 | } |
| 520 | 482 | ||
| 483 | |||
| 484 | /* | ||
| 485 | * The local apic timer can be used for any function which is CPU local. | ||
| 486 | */ | ||
| 487 | static struct clock_event_device lapic_clockevent = { | ||
| 488 | .name = "lapic", | ||
| 489 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT | ||
| 490 | | CLOCK_EVT_FEAT_C3STOP | CLOCK_EVT_FEAT_DUMMY, | ||
| 491 | .shift = 32, | ||
| 492 | .set_mode = lapic_timer_setup, | ||
| 493 | .set_next_event = lapic_next_event, | ||
| 494 | .broadcast = lapic_timer_broadcast, | ||
| 495 | .rating = 100, | ||
| 496 | .irq = -1, | ||
| 497 | }; | ||
| 498 | static DEFINE_PER_CPU(struct clock_event_device, lapic_events); | ||
| 499 | |||
| 521 | /* | 500 | /* |
| 522 | * Setup the local APIC timer for this CPU. Copy the initialized values | 501 | * Setup the local APIC timer for this CPU. Copy the initialized values |
| 523 | * of the boot CPU and register the clock event in the framework. | 502 | * of the boot CPU and register the clock event in the framework. |
| @@ -1560,7 +1539,7 @@ static int __init detect_init_APIC(void) | |||
| 1560 | } | 1539 | } |
| 1561 | #else | 1540 | #else |
| 1562 | 1541 | ||
| 1563 | static int apic_verify(void) | 1542 | static int __init apic_verify(void) |
| 1564 | { | 1543 | { |
| 1565 | u32 features, h, l; | 1544 | u32 features, h, l; |
| 1566 | 1545 | ||
| @@ -1585,7 +1564,7 @@ static int apic_verify(void) | |||
| 1585 | return 0; | 1564 | return 0; |
| 1586 | } | 1565 | } |
| 1587 | 1566 | ||
| 1588 | int apic_force_enable(void) | 1567 | int __init apic_force_enable(unsigned long addr) |
| 1589 | { | 1568 | { |
| 1590 | u32 h, l; | 1569 | u32 h, l; |
| 1591 | 1570 | ||
| @@ -1601,7 +1580,7 @@ int apic_force_enable(void) | |||
| 1601 | if (!(l & MSR_IA32_APICBASE_ENABLE)) { | 1580 | if (!(l & MSR_IA32_APICBASE_ENABLE)) { |
| 1602 | pr_info("Local APIC disabled by BIOS -- reenabling.\n"); | 1581 | pr_info("Local APIC disabled by BIOS -- reenabling.\n"); |
| 1603 | l &= ~MSR_IA32_APICBASE_BASE; | 1582 | l &= ~MSR_IA32_APICBASE_BASE; |
| 1604 | l |= MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE; | 1583 | l |= MSR_IA32_APICBASE_ENABLE | addr; |
| 1605 | wrmsr(MSR_IA32_APICBASE, l, h); | 1584 | wrmsr(MSR_IA32_APICBASE, l, h); |
| 1606 | enabled_via_apicbase = 1; | 1585 | enabled_via_apicbase = 1; |
| 1607 | } | 1586 | } |
| @@ -1642,7 +1621,7 @@ static int __init detect_init_APIC(void) | |||
| 1642 | "you can enable it with \"lapic\"\n"); | 1621 | "you can enable it with \"lapic\"\n"); |
| 1643 | return -1; | 1622 | return -1; |
| 1644 | } | 1623 | } |
| 1645 | if (apic_force_enable()) | 1624 | if (apic_force_enable(APIC_DEFAULT_PHYS_BASE)) |
| 1646 | return -1; | 1625 | return -1; |
| 1647 | } else { | 1626 | } else { |
| 1648 | if (apic_verify()) | 1627 | if (apic_verify()) |
diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c new file mode 100644 index 00000000000..7a8cebc9ff2 --- /dev/null +++ b/arch/x86/kernel/devicetree.c | |||
| @@ -0,0 +1,441 @@ | |||
| 1 | /* | ||
| 2 | * Architecture specific OF callbacks. | ||
| 3 | */ | ||
| 4 | #include <linux/bootmem.h> | ||
| 5 | #include <linux/io.h> | ||
| 6 | #include <linux/interrupt.h> | ||
| 7 | #include <linux/list.h> | ||
| 8 | #include <linux/of.h> | ||
| 9 | #include <linux/of_fdt.h> | ||
| 10 | #include <linux/of_address.h> | ||
| 11 | #include <linux/of_platform.h> | ||
| 12 | #include <linux/of_irq.h> | ||
| 13 | #include <linux/slab.h> | ||
| 14 | #include <linux/pci.h> | ||
| 15 | #include <linux/of_pci.h> | ||
| 16 | |||
| 17 | #include <asm/hpet.h> | ||
| 18 | #include <asm/irq_controller.h> | ||
| 19 | #include <asm/apic.h> | ||
| 20 | #include <asm/pci_x86.h> | ||
| 21 | |||
| 22 | __initdata u64 initial_dtb; | ||
| 23 | char __initdata cmd_line[COMMAND_LINE_SIZE]; | ||
| 24 | static LIST_HEAD(irq_domains); | ||
| 25 | static DEFINE_RAW_SPINLOCK(big_irq_lock); | ||
| 26 | |||
| 27 | int __initdata of_ioapic; | ||
| 28 | |||
| 29 | #ifdef CONFIG_X86_IO_APIC | ||
| 30 | static void add_interrupt_host(struct irq_domain *ih) | ||
| 31 | { | ||
| 32 | unsigned long flags; | ||
| 33 | |||
| 34 | raw_spin_lock_irqsave(&big_irq_lock, flags); | ||
| 35 | list_add(&ih->l, &irq_domains); | ||
| 36 | raw_spin_unlock_irqrestore(&big_irq_lock, flags); | ||
| 37 | } | ||
| 38 | #endif | ||
| 39 | |||
| 40 | static struct irq_domain *get_ih_from_node(struct device_node *controller) | ||
| 41 | { | ||
| 42 | struct irq_domain *ih, *found = NULL; | ||
| 43 | unsigned long flags; | ||
| 44 | |||
| 45 | raw_spin_lock_irqsave(&big_irq_lock, flags); | ||
| 46 | list_for_each_entry(ih, &irq_domains, l) { | ||
| 47 | if (ih->controller == controller) { | ||
| 48 | found = ih; | ||
| 49 | break; | ||
| 50 | } | ||
| 51 | } | ||
| 52 | raw_spin_unlock_irqrestore(&big_irq_lock, flags); | ||
| 53 | return found; | ||
| 54 | } | ||
| 55 | |||
| 56 | unsigned int irq_create_of_mapping(struct device_node *controller, | ||
| 57 | const u32 *intspec, unsigned int intsize) | ||
| 58 | { | ||
| 59 | struct irq_domain *ih; | ||
| 60 | u32 virq, type; | ||
| 61 | int ret; | ||
| 62 | |||
| 63 | ih = get_ih_from_node(controller); | ||
| 64 | if (!ih) | ||
| 65 | return 0; | ||
| 66 | ret = ih->xlate(ih, intspec, intsize, &virq, &type); | ||
| 67 | if (ret) | ||
| 68 | return ret; | ||
| 69 | if (type == IRQ_TYPE_NONE) | ||
| 70 | return virq; | ||
| 71 | /* set the mask if it is different from current */ | ||
| 72 | if (type == (irq_to_desc(virq)->status & IRQF_TRIGGER_MASK)) | ||
| 73 | set_irq_type(virq, type); | ||
| 74 | return virq; | ||
| 75 | } | ||
| 76 | EXPORT_SYMBOL_GPL(irq_create_of_mapping); | ||
| 77 | |||
| 78 | unsigned long pci_address_to_pio(phys_addr_t address) | ||
| 79 | { | ||
| 80 | /* | ||
| 81 | * The ioport address can be directly used by inX / outX | ||
| 82 | */ | ||
| 83 | BUG_ON(address >= (1 << 16)); | ||
| 84 | return (unsigned long)address; | ||
| 85 | } | ||
| 86 | EXPORT_SYMBOL_GPL(pci_address_to_pio); | ||
| 87 | |||
| 88 | void __init early_init_dt_scan_chosen_arch(unsigned long node) | ||
| 89 | { | ||
| 90 | BUG(); | ||
| 91 | } | ||
| 92 | |||
| 93 | void __init early_init_dt_add_memory_arch(u64 base, u64 size) | ||
| 94 | { | ||
| 95 | BUG(); | ||
| 96 | } | ||
| 97 | |||
| 98 | void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) | ||
| 99 | { | ||
| 100 | return __alloc_bootmem(size, align, __pa(MAX_DMA_ADDRESS)); | ||
| 101 | } | ||
| 102 | |||
| 103 | void __init add_dtb(u64 data) | ||
| 104 | { | ||
| 105 | initial_dtb = data + offsetof(struct setup_data, data); | ||
| 106 | } | ||
| 107 | |||
| 108 | /* | ||
| 109 | * CE4100 ids. Will be moved to machine_device_initcall() once we have it. | ||
| 110 | */ | ||
| 111 | static struct of_device_id __initdata ce4100_ids[] = { | ||
| 112 | { .compatible = "intel,ce4100-cp", }, | ||
| 113 | { .compatible = "isa", }, | ||
| 114 | { .compatible = "pci", }, | ||
| 115 | {}, | ||
| 116 | }; | ||
| 117 | |||
| 118 | static int __init add_bus_probe(void) | ||
| 119 | { | ||
| 120 | if (!of_have_populated_dt()) | ||
| 121 | return 0; | ||
| 122 | |||
| 123 | return of_platform_bus_probe(NULL, ce4100_ids, NULL); | ||
| 124 | } | ||
| 125 | module_init(add_bus_probe); | ||
| 126 | |||
| 127 | #ifdef CONFIG_PCI | ||
| 128 | static int x86_of_pci_irq_enable(struct pci_dev *dev) | ||
| 129 | { | ||
| 130 | struct of_irq oirq; | ||
| 131 | u32 virq; | ||
| 132 | int ret; | ||
| 133 | u8 pin; | ||
| 134 | |||
| 135 | ret = pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); | ||
| 136 | if (ret) | ||
| 137 | return ret; | ||
| 138 | if (!pin) | ||
| 139 | return 0; | ||
| 140 | |||
| 141 | ret = of_irq_map_pci(dev, &oirq); | ||
| 142 | if (ret) | ||
| 143 | return ret; | ||
| 144 | |||
| 145 | virq = irq_create_of_mapping(oirq.controller, oirq.specifier, | ||
| 146 | oirq.size); | ||
| 147 | if (virq == 0) | ||
| 148 | return -EINVAL; | ||
| 149 | dev->irq = virq; | ||
| 150 | return 0; | ||
| 151 | } | ||
| 152 | |||
| 153 | static void x86_of_pci_irq_disable(struct pci_dev *dev) | ||
| 154 | { | ||
| 155 | } | ||
| 156 | |||
| 157 | void __cpuinit x86_of_pci_init(void) | ||
| 158 | { | ||
| 159 | struct device_node *np; | ||
| 160 | |||
| 161 | pcibios_enable_irq = x86_of_pci_irq_enable; | ||
| 162 | pcibios_disable_irq = x86_of_pci_irq_disable; | ||
| 163 | |||
| 164 | for_each_node_by_type(np, "pci") { | ||
| 165 | const void *prop; | ||
| 166 | struct pci_bus *bus; | ||
| 167 | unsigned int bus_min; | ||
| 168 | struct device_node *child; | ||
| 169 | |||
| 170 | prop = of_get_property(np, "bus-range", NULL); | ||
| 171 | if (!prop) | ||
| 172 | continue; | ||
| 173 | bus_min = be32_to_cpup(prop); | ||
| 174 | |||
| 175 | bus = pci_find_bus(0, bus_min); | ||
| 176 | if (!bus) { | ||
| 177 | printk(KERN_ERR "Can't find a node for bus %s.\n", | ||
| 178 | np->full_name); | ||
| 179 | continue; | ||
| 180 | } | ||
| 181 | |||
| 182 | if (bus->self) | ||
| 183 | bus->self->dev.of_node = np; | ||
| 184 | else | ||
| 185 | bus->dev.of_node = np; | ||
| 186 | |||
| 187 | for_each_child_of_node(np, child) { | ||
| 188 | struct pci_dev *dev; | ||
| 189 | u32 devfn; | ||
| 190 | |||
| 191 | prop = of_get_property(child, "reg", NULL); | ||
| 192 | if (!prop) | ||
| 193 | continue; | ||
| 194 | |||
| 195 | devfn = (be32_to_cpup(prop) >> 8) & 0xff; | ||
| 196 | dev = pci_get_slot(bus, devfn); | ||
| 197 | if (!dev) | ||
| 198 | continue; | ||
| 199 | dev->dev.of_node = child; | ||
| 200 | pci_dev_put(dev); | ||
| 201 | } | ||
| 202 | } | ||
| 203 | } | ||
| 204 | #endif | ||
| 205 | |||
| 206 | static void __init dtb_setup_hpet(void) | ||
| 207 | { | ||
| 208 | #ifdef CONFIG_HPET_TIMER | ||
| 209 | struct device_node *dn; | ||
| 210 | struct resource r; | ||
| 211 | int ret; | ||
| 212 | |||
| 213 | dn = of_find_compatible_node(NULL, NULL, "intel,ce4100-hpet"); | ||
| 214 | if (!dn) | ||
| 215 | return; | ||
| 216 | ret = of_address_to_resource(dn, 0, &r); | ||
| 217 | if (ret) { | ||
| 218 | WARN_ON(1); | ||
| 219 | return; | ||
| 220 | } | ||
| 221 | hpet_address = r.start; | ||
| 222 | #endif | ||
| 223 | } | ||
| 224 | |||
| 225 | static void __init dtb_lapic_setup(void) | ||
| 226 | { | ||
| 227 | #ifdef CONFIG_X86_LOCAL_APIC | ||
| 228 | struct device_node *dn; | ||
| 229 | struct resource r; | ||
| 230 | int ret; | ||
| 231 | |||
| 232 | dn = of_find_compatible_node(NULL, NULL, "intel,ce4100-lapic"); | ||
| 233 | if (!dn) | ||
| 234 | return; | ||
| 235 | |||
| 236 | ret = of_address_to_resource(dn, 0, &r); | ||
| 237 | if (WARN_ON(ret)) | ||
| 238 | return; | ||
| 239 | |||
| 240 | /* Did the boot loader setup the local APIC ? */ | ||
| 241 | if (!cpu_has_apic) { | ||
| 242 | if (apic_force_enable(r.start)) | ||
| 243 | return; | ||
| 244 | } | ||
| 245 | smp_found_config = 1; | ||
| 246 | pic_mode = 1; | ||
| 247 | register_lapic_address(r.start); | ||
| 248 | generic_processor_info(boot_cpu_physical_apicid, | ||
| 249 | GET_APIC_VERSION(apic_read(APIC_LVR))); | ||
| 250 | #endif | ||
| 251 | } | ||
| 252 | |||
| 253 | #ifdef CONFIG_X86_IO_APIC | ||
| 254 | static unsigned int ioapic_id; | ||
| 255 | |||
| 256 | static void __init dtb_add_ioapic(struct device_node *dn) | ||
| 257 | { | ||
| 258 | struct resource r; | ||
| 259 | int ret; | ||
| 260 | |||
| 261 | ret = of_address_to_resource(dn, 0, &r); | ||
| 262 | if (ret) { | ||
| 263 | printk(KERN_ERR "Can't obtain address from node %s.\n", | ||
| 264 | dn->full_name); | ||
| 265 | return; | ||
| 266 | } | ||
| 267 | mp_register_ioapic(++ioapic_id, r.start, gsi_top); | ||
| 268 | } | ||
| 269 | |||
| 270 | static void __init dtb_ioapic_setup(void) | ||
| 271 | { | ||
| 272 | struct device_node *dn; | ||
| 273 | |||
| 274 | for_each_compatible_node(dn, NULL, "intel,ce4100-ioapic") | ||
| 275 | dtb_add_ioapic(dn); | ||
| 276 | |||
| 277 | if (nr_ioapics) { | ||
| 278 | of_ioapic = 1; | ||
| 279 | return; | ||
| 280 | } | ||
| 281 | printk(KERN_ERR "Error: No information about IO-APIC in OF.\n"); | ||
| 282 | } | ||
| 283 | #else | ||
| 284 | static void __init dtb_ioapic_setup(void) {} | ||
| 285 | #endif | ||
| 286 | |||
| 287 | static void __init dtb_apic_setup(void) | ||
| 288 | { | ||
| 289 | dtb_lapic_setup(); | ||
| 290 | dtb_ioapic_setup(); | ||
| 291 | } | ||
| 292 | |||
| 293 | #ifdef CONFIG_OF_FLATTREE | ||
| 294 | static void __init x86_flattree_get_config(void) | ||
| 295 | { | ||
| 296 | u32 size, map_len; | ||
| 297 | void *new_dtb; | ||
| 298 | |||
| 299 | if (!initial_dtb) | ||
| 300 | return; | ||
| 301 | |||
| 302 | map_len = max(PAGE_SIZE - (initial_dtb & ~PAGE_MASK), | ||
| 303 | (u64)sizeof(struct boot_param_header)); | ||
| 304 | |||
| 305 | initial_boot_params = early_memremap(initial_dtb, map_len); | ||
| 306 | size = be32_to_cpu(initial_boot_params->totalsize); | ||
| 307 | if (map_len < size) { | ||
| 308 | early_iounmap(initial_boot_params, map_len); | ||
| 309 | initial_boot_params = early_memremap(initial_dtb, size); | ||
| 310 | map_len = size; | ||
| 311 | } | ||
| 312 | |||
| 313 | new_dtb = alloc_bootmem(size); | ||
| 314 | memcpy(new_dtb, initial_boot_params, size); | ||
| 315 | early_iounmap(initial_boot_params, map_len); | ||
| 316 | |||
| 317 | initial_boot_params = new_dtb; | ||
| 318 | |||
| 319 | /* root level address cells */ | ||
| 320 | of_scan_flat_dt(early_init_dt_scan_root, NULL); | ||
| 321 | |||
| 322 | unflatten_device_tree(); | ||
| 323 | } | ||
| 324 | #else | ||
| 325 | static inline void x86_flattree_get_config(void) { } | ||
| 326 | #endif | ||
| 327 | |||
| 328 | void __init x86_dtb_init(void) | ||
| 329 | { | ||
| 330 | x86_flattree_get_config(); | ||
| 331 | |||
| 332 | if (!of_have_populated_dt()) | ||
| 333 | return; | ||
| 334 | |||
| 335 | dtb_setup_hpet(); | ||
| 336 | dtb_apic_setup(); | ||
| 337 | } | ||
| 338 | |||
| 339 | #ifdef CONFIG_X86_IO_APIC | ||
| 340 | |||
| 341 | struct of_ioapic_type { | ||
| 342 | u32 out_type; | ||
| 343 | u32 trigger; | ||
| 344 | u32 polarity; | ||
| 345 | }; | ||
| 346 | |||
| 347 | static struct of_ioapic_type of_ioapic_type[] = | ||
| 348 | { | ||
| 349 | { | ||
| 350 | .out_type = IRQ_TYPE_EDGE_RISING, | ||
| 351 | .trigger = IOAPIC_EDGE, | ||
| 352 | .polarity = 1, | ||
| 353 | }, | ||
| 354 | { | ||
| 355 | .out_type = IRQ_TYPE_LEVEL_LOW, | ||
| 356 | .trigger = IOAPIC_LEVEL, | ||
| 357 | .polarity = 0, | ||
| 358 | }, | ||
| 359 | { | ||
| 360 | .out_type = IRQ_TYPE_LEVEL_HIGH, | ||
| 361 | .trigger = IOAPIC_LEVEL, | ||
| 362 | .polarity = 1, | ||
| 363 | }, | ||
| 364 | { | ||
| 365 | .out_type = IRQ_TYPE_EDGE_FALLING, | ||
| 366 | .trigger = IOAPIC_EDGE, | ||
| 367 | .polarity = 0, | ||
| 368 | }, | ||
| 369 | }; | ||
| 370 | |||
| 371 | static int ioapic_xlate(struct irq_domain *id, const u32 *intspec, u32 intsize, | ||
| 372 | u32 *out_hwirq, u32 *out_type) | ||
| 373 | { | ||
| 374 | struct io_apic_irq_attr attr; | ||
| 375 | struct of_ioapic_type *it; | ||
| 376 | u32 line, idx, type; | ||
| 377 | |||
| 378 | if (intsize < 2) | ||
| 379 | return -EINVAL; | ||
| 380 | |||
| 381 | line = *intspec; | ||
| 382 | idx = (u32) id->priv; | ||
| 383 | *out_hwirq = line + mp_gsi_routing[idx].gsi_base; | ||
| 384 | |||
| 385 | intspec++; | ||
| 386 | type = *intspec; | ||
| 387 | |||
| 388 | if (type >= ARRAY_SIZE(of_ioapic_type)) | ||
| 389 | return -EINVAL; | ||
| 390 | |||
| 391 | it = of_ioapic_type + type; | ||
| 392 | *out_type = it->out_type; | ||
| 393 | |||
| 394 | set_io_apic_irq_attr(&attr, idx, line, it->trigger, it->polarity); | ||
| 395 | |||
| 396 | return io_apic_setup_irq_pin(*out_hwirq, cpu_to_node(0), &attr); | ||
| 397 | } | ||
| 398 | |||
| 399 | static void __init ioapic_add_ofnode(struct device_node *np) | ||
| 400 | { | ||
| 401 | struct resource r; | ||
| 402 | int i, ret; | ||
| 403 | |||
| 404 | ret = of_address_to_resource(np, 0, &r); | ||
| 405 | if (ret) { | ||
| 406 | printk(KERN_ERR "Failed to obtain address for %s\n", | ||
| 407 | np->full_name); | ||
| 408 | return; | ||
| 409 | } | ||
| 410 | |||
| 411 | for (i = 0; i < nr_ioapics; i++) { | ||
| 412 | if (r.start == mp_ioapics[i].apicaddr) { | ||
| 413 | struct irq_domain *id; | ||
| 414 | |||
| 415 | id = kzalloc(sizeof(*id), GFP_KERNEL); | ||
| 416 | BUG_ON(!id); | ||
| 417 | id->controller = np; | ||
| 418 | id->xlate = ioapic_xlate; | ||
| 419 | id->priv = (void *)i; | ||
| 420 | add_interrupt_host(id); | ||
| 421 | return; | ||
| 422 | } | ||
| 423 | } | ||
| 424 | printk(KERN_ERR "IOxAPIC at %s is not registered.\n", np->full_name); | ||
| 425 | } | ||
| 426 | |||
| 427 | void __init x86_add_irq_domains(void) | ||
| 428 | { | ||
| 429 | struct device_node *dp; | ||
| 430 | |||
| 431 | if (!of_have_populated_dt()) | ||
| 432 | return; | ||
| 433 | |||
| 434 | for_each_node_with_property(dp, "interrupt-controller") { | ||
| 435 | if (of_device_is_compatible(dp, "intel,ce4100-ioapic")) | ||
| 436 | ioapic_add_ofnode(dp); | ||
| 437 | } | ||
| 438 | } | ||
| 439 | #else | ||
| 440 | void __init x86_add_irq_domains(void) { } | ||
| 441 | #endif | ||
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index 0b5e2b54656..cdf5bfd9d4d 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c | |||
| @@ -667,21 +667,15 @@ __init void e820_setup_gap(void) | |||
| 667 | * boot_params.e820_map, others are passed via SETUP_E820_EXT node of | 667 | * boot_params.e820_map, others are passed via SETUP_E820_EXT node of |
| 668 | * linked list of struct setup_data, which is parsed here. | 668 | * linked list of struct setup_data, which is parsed here. |
| 669 | */ | 669 | */ |
| 670 | void __init parse_e820_ext(struct setup_data *sdata, unsigned long pa_data) | 670 | void __init parse_e820_ext(struct setup_data *sdata) |
| 671 | { | 671 | { |
| 672 | u32 map_len; | ||
| 673 | int entries; | 672 | int entries; |
| 674 | struct e820entry *extmap; | 673 | struct e820entry *extmap; |
| 675 | 674 | ||
| 676 | entries = sdata->len / sizeof(struct e820entry); | 675 | entries = sdata->len / sizeof(struct e820entry); |
| 677 | map_len = sdata->len + sizeof(struct setup_data); | ||
| 678 | if (map_len > PAGE_SIZE) | ||
| 679 | sdata = early_ioremap(pa_data, map_len); | ||
| 680 | extmap = (struct e820entry *)(sdata->data); | 676 | extmap = (struct e820entry *)(sdata->data); |
| 681 | __append_e820_map(extmap, entries); | 677 | __append_e820_map(extmap, entries); |
| 682 | sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map); | 678 | sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map); |
| 683 | if (map_len > PAGE_SIZE) | ||
| 684 | early_iounmap(sdata, map_len); | ||
| 685 | printk(KERN_INFO "extended physical RAM map:\n"); | 679 | printk(KERN_INFO "extended physical RAM map:\n"); |
| 686 | e820_print_map("extended"); | 680 | e820_print_map("extended"); |
| 687 | } | 681 | } |
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S index 187aa63b321..ce0be7cd085 100644 --- a/arch/x86/kernel/head_32.S +++ b/arch/x86/kernel/head_32.S | |||
| @@ -137,7 +137,7 @@ ENTRY(startup_32) | |||
| 137 | movsl | 137 | movsl |
| 138 | 1: | 138 | 1: |
| 139 | 139 | ||
| 140 | #ifdef CONFIG_OLPC_OPENFIRMWARE | 140 | #ifdef CONFIG_OLPC |
| 141 | /* save OFW's pgdir table for later use when calling into OFW */ | 141 | /* save OFW's pgdir table for later use when calling into OFW */ |
| 142 | movl %cr3, %eax | 142 | movl %cr3, %eax |
| 143 | movl %eax, pa(olpc_ofw_pgd) | 143 | movl %eax, pa(olpc_ofw_pgd) |
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c index 5ee693faa11..948a31eae75 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c | |||
| @@ -223,15 +223,6 @@ void smp_x86_platform_ipi(struct pt_regs *regs) | |||
| 223 | 223 | ||
| 224 | EXPORT_SYMBOL_GPL(vector_used_by_percpu_irq); | 224 | EXPORT_SYMBOL_GPL(vector_used_by_percpu_irq); |
| 225 | 225 | ||
| 226 | #ifdef CONFIG_OF | ||
| 227 | unsigned int irq_create_of_mapping(struct device_node *controller, | ||
| 228 | const u32 *intspec, unsigned int intsize) | ||
| 229 | { | ||
| 230 | return intspec[0]; | ||
| 231 | } | ||
| 232 | EXPORT_SYMBOL_GPL(irq_create_of_mapping); | ||
| 233 | #endif | ||
| 234 | |||
| 235 | #ifdef CONFIG_HOTPLUG_CPU | 226 | #ifdef CONFIG_HOTPLUG_CPU |
| 236 | /* A cpu has been removed from cpu_online_mask. Reset irq affinities. */ | 227 | /* A cpu has been removed from cpu_online_mask. Reset irq affinities. */ |
| 237 | void fixup_irqs(void) | 228 | void fixup_irqs(void) |
diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c index d30854b18d2..f470e4ef993 100644 --- a/arch/x86/kernel/irqinit.c +++ b/arch/x86/kernel/irqinit.c | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | #include <asm/setup.h> | 25 | #include <asm/setup.h> |
| 26 | #include <asm/i8259.h> | 26 | #include <asm/i8259.h> |
| 27 | #include <asm/traps.h> | 27 | #include <asm/traps.h> |
| 28 | #include <asm/prom.h> | ||
| 28 | 29 | ||
| 29 | /* | 30 | /* |
| 30 | * ISA PIC or low IO-APIC triggered (INTA-cycle or APIC) interrupts: | 31 | * ISA PIC or low IO-APIC triggered (INTA-cycle or APIC) interrupts: |
| @@ -120,6 +121,12 @@ void __init init_IRQ(void) | |||
| 120 | int i; | 121 | int i; |
| 121 | 122 | ||
| 122 | /* | 123 | /* |
| 124 | * We probably need a better place for this, but it works for | ||
| 125 | * now ... | ||
| 126 | */ | ||
| 127 | x86_add_irq_domains(); | ||
| 128 | |||
| 129 | /* | ||
| 123 | * On cpu 0, Assign IRQ0_VECTOR..IRQ15_VECTOR's to IRQ 0..15. | 130 | * On cpu 0, Assign IRQ0_VECTOR..IRQ15_VECTOR's to IRQ 0..15. |
| 124 | * If these IRQ's are handled by legacy interrupt-controllers like PIC, | 131 | * If these IRQ's are handled by legacy interrupt-controllers like PIC, |
| 125 | * then this configuration will likely be static after the boot. If | 132 | * then this configuration will likely be static after the boot. If |
| @@ -308,7 +315,7 @@ void __init native_init_IRQ(void) | |||
| 308 | set_intr_gate(i, interrupt[i-FIRST_EXTERNAL_VECTOR]); | 315 | set_intr_gate(i, interrupt[i-FIRST_EXTERNAL_VECTOR]); |
| 309 | } | 316 | } |
| 310 | 317 | ||
| 311 | if (!acpi_ioapic) | 318 | if (!acpi_ioapic && !of_ioapic) |
| 312 | setup_irq(2, &irq2); | 319 | setup_irq(2, &irq2); |
| 313 | 320 | ||
| 314 | #ifdef CONFIG_X86_32 | 321 | #ifdef CONFIG_X86_32 |
diff --git a/arch/x86/kernel/rtc.c b/arch/x86/kernel/rtc.c index 6f39cab052d..3f2ad2640d8 100644 --- a/arch/x86/kernel/rtc.c +++ b/arch/x86/kernel/rtc.c | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | #include <linux/acpi.h> | 6 | #include <linux/acpi.h> |
| 7 | #include <linux/bcd.h> | 7 | #include <linux/bcd.h> |
| 8 | #include <linux/pnp.h> | 8 | #include <linux/pnp.h> |
| 9 | #include <linux/of.h> | ||
| 9 | 10 | ||
| 10 | #include <asm/vsyscall.h> | 11 | #include <asm/vsyscall.h> |
| 11 | #include <asm/x86_init.h> | 12 | #include <asm/x86_init.h> |
| @@ -236,6 +237,8 @@ static __init int add_rtc_cmos(void) | |||
| 236 | } | 237 | } |
| 237 | } | 238 | } |
| 238 | #endif | 239 | #endif |
| 240 | if (of_have_populated_dt()) | ||
| 241 | return 0; | ||
| 239 | 242 | ||
| 240 | platform_device_register(&rtc_device); | 243 | platform_device_register(&rtc_device); |
| 241 | dev_info(&rtc_device.dev, | 244 | dev_info(&rtc_device.dev, |
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index c3a606c41ce..b176f2b1f45 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c | |||
| @@ -113,6 +113,7 @@ | |||
| 113 | #endif | 113 | #endif |
| 114 | #include <asm/mce.h> | 114 | #include <asm/mce.h> |
| 115 | #include <asm/alternative.h> | 115 | #include <asm/alternative.h> |
| 116 | #include <asm/prom.h> | ||
| 116 | 117 | ||
| 117 | /* | 118 | /* |
| 118 | * end_pfn only includes RAM, while max_pfn_mapped includes all e820 entries. | 119 | * end_pfn only includes RAM, while max_pfn_mapped includes all e820 entries. |
| @@ -453,16 +454,30 @@ static void __init parse_setup_data(void) | |||
| 453 | return; | 454 | return; |
| 454 | pa_data = boot_params.hdr.setup_data; | 455 | pa_data = boot_params.hdr.setup_data; |
| 455 | while (pa_data) { | 456 | while (pa_data) { |
| 456 | data = early_memremap(pa_data, PAGE_SIZE); | 457 | u32 data_len, map_len; |
| 458 | |||
| 459 | map_len = max(PAGE_SIZE - (pa_data & ~PAGE_MASK), | ||
| 460 | (u64)sizeof(struct setup_data)); | ||
| 461 | data = early_memremap(pa_data, map_len); | ||
| 462 | data_len = data->len + sizeof(struct setup_data); | ||
| 463 | if (data_len > map_len) { | ||
| 464 | early_iounmap(data, map_len); | ||
| 465 | data = early_memremap(pa_data, data_len); | ||
| 466 | map_len = data_len; | ||
| 467 | } | ||
| 468 | |||
| 457 | switch (data->type) { | 469 | switch (data->type) { |
| 458 | case SETUP_E820_EXT: | 470 | case SETUP_E820_EXT: |
| 459 | parse_e820_ext(data, pa_data); | 471 | parse_e820_ext(data); |
| 472 | break; | ||
| 473 | case SETUP_DTB: | ||
| 474 | add_dtb(pa_data); | ||
| 460 | break; | 475 | break; |
| 461 | default: | 476 | default: |
| 462 | break; | 477 | break; |
| 463 | } | 478 | } |
| 464 | pa_data = data->next; | 479 | pa_data = data->next; |
| 465 | early_iounmap(data, PAGE_SIZE); | 480 | early_iounmap(data, map_len); |
| 466 | } | 481 | } |
| 467 | } | 482 | } |
| 468 | 483 | ||
| @@ -1030,8 +1045,8 @@ void __init setup_arch(char **cmdline_p) | |||
| 1030 | * Read APIC and some other early information from ACPI tables. | 1045 | * Read APIC and some other early information from ACPI tables. |
| 1031 | */ | 1046 | */ |
| 1032 | acpi_boot_init(); | 1047 | acpi_boot_init(); |
| 1033 | |||
| 1034 | sfi_init(); | 1048 | sfi_init(); |
| 1049 | x86_dtb_init(); | ||
| 1035 | 1050 | ||
| 1036 | /* | 1051 | /* |
| 1037 | * get boot-time SMP configuration: | 1052 | * get boot-time SMP configuration: |
| @@ -1065,6 +1080,8 @@ void __init setup_arch(char **cmdline_p) | |||
| 1065 | #endif | 1080 | #endif |
| 1066 | x86_init.oem.banner(); | 1081 | x86_init.oem.banner(); |
| 1067 | 1082 | ||
| 1083 | x86_init.timers.wallclock_init(); | ||
| 1084 | |||
| 1068 | mcheck_init(); | 1085 | mcheck_init(); |
| 1069 | 1086 | ||
| 1070 | local_irq_save(flags); | 1087 | local_irq_save(flags); |
diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c index ceb2911aa43..c11514e9128 100644 --- a/arch/x86/kernel/x86_init.c +++ b/arch/x86/kernel/x86_init.c | |||
| @@ -70,6 +70,7 @@ struct x86_init_ops x86_init __initdata = { | |||
| 70 | .setup_percpu_clockev = setup_boot_APIC_clock, | 70 | .setup_percpu_clockev = setup_boot_APIC_clock, |
| 71 | .tsc_pre_init = x86_init_noop, | 71 | .tsc_pre_init = x86_init_noop, |
| 72 | .timer_init = hpet_time_init, | 72 | .timer_init = hpet_time_init, |
| 73 | .wallclock_init = x86_init_noop, | ||
| 73 | }, | 74 | }, |
| 74 | 75 | ||
| 75 | .iommu = { | 76 | .iommu = { |
diff --git a/arch/x86/pci/ce4100.c b/arch/x86/pci/ce4100.c index 9260b3eb18d..67858be4b52 100644 --- a/arch/x86/pci/ce4100.c +++ b/arch/x86/pci/ce4100.c | |||
| @@ -255,7 +255,7 @@ int bridge_read(unsigned int devfn, int reg, int len, u32 *value) | |||
| 255 | static int ce4100_conf_read(unsigned int seg, unsigned int bus, | 255 | static int ce4100_conf_read(unsigned int seg, unsigned int bus, |
| 256 | unsigned int devfn, int reg, int len, u32 *value) | 256 | unsigned int devfn, int reg, int len, u32 *value) |
| 257 | { | 257 | { |
| 258 | int i, retval = 1; | 258 | int i; |
| 259 | 259 | ||
| 260 | if (bus == 1) { | 260 | if (bus == 1) { |
| 261 | for (i = 0; i < ARRAY_SIZE(bus1_fixups); i++) { | 261 | for (i = 0; i < ARRAY_SIZE(bus1_fixups); i++) { |
diff --git a/arch/x86/platform/ce4100/ce4100.c b/arch/x86/platform/ce4100/ce4100.c index cd6f184c3b3..28071bb31db 100644 --- a/arch/x86/platform/ce4100/ce4100.c +++ b/arch/x86/platform/ce4100/ce4100.c | |||
| @@ -16,21 +16,19 @@ | |||
| 16 | #include <linux/serial_8250.h> | 16 | #include <linux/serial_8250.h> |
| 17 | 17 | ||
| 18 | #include <asm/ce4100.h> | 18 | #include <asm/ce4100.h> |
| 19 | #include <asm/prom.h> | ||
| 19 | #include <asm/setup.h> | 20 | #include <asm/setup.h> |
| 21 | #include <asm/i8259.h> | ||
| 20 | #include <asm/io.h> | 22 | #include <asm/io.h> |
| 23 | #include <asm/io_apic.h> | ||
| 21 | 24 | ||
| 22 | static int ce4100_i8042_detect(void) | 25 | static int ce4100_i8042_detect(void) |
| 23 | { | 26 | { |
| 24 | return 0; | 27 | return 0; |
| 25 | } | 28 | } |
| 26 | 29 | ||
| 27 | static void __init sdv_find_smp_config(void) | ||
| 28 | { | ||
| 29 | } | ||
| 30 | |||
| 31 | #ifdef CONFIG_SERIAL_8250 | 30 | #ifdef CONFIG_SERIAL_8250 |
| 32 | 31 | ||
| 33 | |||
| 34 | static unsigned int mem_serial_in(struct uart_port *p, int offset) | 32 | static unsigned int mem_serial_in(struct uart_port *p, int offset) |
| 35 | { | 33 | { |
| 36 | offset = offset << p->regshift; | 34 | offset = offset << p->regshift; |
| @@ -119,6 +117,15 @@ static void __init sdv_arch_setup(void) | |||
| 119 | sdv_serial_fixup(); | 117 | sdv_serial_fixup(); |
| 120 | } | 118 | } |
| 121 | 119 | ||
| 120 | #ifdef CONFIG_X86_IO_APIC | ||
| 121 | static void __cpuinit sdv_pci_init(void) | ||
| 122 | { | ||
| 123 | x86_of_pci_init(); | ||
| 124 | /* We can't set this earlier, because we need to calibrate the timer */ | ||
| 125 | legacy_pic = &null_legacy_pic; | ||
| 126 | } | ||
| 127 | #endif | ||
| 128 | |||
| 122 | /* | 129 | /* |
| 123 | * CE4100 specific x86_init function overrides and early setup | 130 | * CE4100 specific x86_init function overrides and early setup |
| 124 | * calls. | 131 | * calls. |
| @@ -129,6 +136,11 @@ void __init x86_ce4100_early_setup(void) | |||
| 129 | x86_platform.i8042_detect = ce4100_i8042_detect; | 136 | x86_platform.i8042_detect = ce4100_i8042_detect; |
| 130 | x86_init.resources.probe_roms = x86_init_noop; | 137 | x86_init.resources.probe_roms = x86_init_noop; |
| 131 | x86_init.mpparse.get_smp_config = x86_init_uint_noop; | 138 | x86_init.mpparse.get_smp_config = x86_init_uint_noop; |
| 132 | x86_init.mpparse.find_smp_config = sdv_find_smp_config; | 139 | x86_init.mpparse.find_smp_config = x86_init_noop; |
| 133 | x86_init.pci.init = ce4100_pci_init; | 140 | x86_init.pci.init = ce4100_pci_init; |
| 141 | |||
| 142 | #ifdef CONFIG_X86_IO_APIC | ||
| 143 | x86_init.pci.init_irq = sdv_pci_init; | ||
| 144 | x86_init.mpparse.setup_ioapic_ids = setup_ioapic_ids_from_mpc_nocheck; | ||
| 145 | #endif | ||
| 134 | } | 146 | } |
diff --git a/arch/x86/platform/ce4100/falconfalls.dts b/arch/x86/platform/ce4100/falconfalls.dts new file mode 100644 index 00000000000..dc701ea5854 --- /dev/null +++ b/arch/x86/platform/ce4100/falconfalls.dts | |||
| @@ -0,0 +1,428 @@ | |||
| 1 | /* | ||
| 2 | * CE4100 on Falcon Falls | ||
| 3 | * | ||
| 4 | * (c) Copyright 2010 Intel Corporation | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify it | ||
| 7 | * under the terms of the GNU General Public License as published by the | ||
| 8 | * Free Software Foundation; version 2 of the License. | ||
| 9 | */ | ||
| 10 | /dts-v1/; | ||
| 11 | / { | ||
| 12 | model = "intel,falconfalls"; | ||
| 13 | compatible = "intel,falconfalls"; | ||
| 14 | #address-cells = <1>; | ||
| 15 | #size-cells = <1>; | ||
| 16 | |||
| 17 | cpus { | ||
| 18 | #address-cells = <1>; | ||
| 19 | #size-cells = <0>; | ||
| 20 | |||
| 21 | cpu@0 { | ||
| 22 | device_type = "cpu"; | ||
| 23 | compatible = "intel,ce4100"; | ||
| 24 | reg = <0>; | ||
| 25 | lapic = <&lapic0>; | ||
| 26 | }; | ||
| 27 | }; | ||
| 28 | |||
| 29 | soc@0 { | ||
| 30 | #address-cells = <1>; | ||
| 31 | #size-cells = <1>; | ||
| 32 | compatible = "intel,ce4100-cp"; | ||
| 33 | ranges; | ||
| 34 | |||
| 35 | ioapic1: interrupt-controller@fec00000 { | ||
| 36 | #interrupt-cells = <2>; | ||
| 37 | compatible = "intel,ce4100-ioapic"; | ||
| 38 | interrupt-controller; | ||
| 39 | reg = <0xfec00000 0x1000>; | ||
| 40 | }; | ||
| 41 | |||
| 42 | timer@fed00000 { | ||
| 43 | compatible = "intel,ce4100-hpet"; | ||
| 44 | reg = <0xfed00000 0x200>; | ||
| 45 | }; | ||
| 46 | |||
| 47 | lapic0: interrupt-controller@fee00000 { | ||
| 48 | compatible = "intel,ce4100-lapic"; | ||
| 49 | reg = <0xfee00000 0x1000>; | ||
| 50 | }; | ||
| 51 | |||
| 52 | pci@3fc { | ||
| 53 | #address-cells = <3>; | ||
| 54 | #size-cells = <2>; | ||
| 55 | compatible = "intel,ce4100-pci", "pci"; | ||
| 56 | device_type = "pci"; | ||
| 57 | bus-range = <0 0>; | ||
| 58 | ranges = <0x2000000 0 0xbffff000 0xbffff000 0 0x1000 | ||
| 59 | 0x2000000 0 0xdffe0000 0xdffe0000 0 0x1000 | ||
| 60 | 0x0000000 0 0x0 0x0 0 0x100>; | ||
| 61 | |||
| 62 | /* Secondary IO-APIC */ | ||
| 63 | ioapic2: interrupt-controller@0,1 { | ||
| 64 | #interrupt-cells = <2>; | ||
| 65 | compatible = "intel,ce4100-ioapic"; | ||
| 66 | interrupt-controller; | ||
| 67 | reg = <0x100 0x0 0x0 0x0 0x0>; | ||
| 68 | assigned-addresses = <0x02000000 0x0 0xbffff000 0x0 0x1000>; | ||
| 69 | }; | ||
| 70 | |||
| 71 | pci@1,0 { | ||
| 72 | #address-cells = <3>; | ||
| 73 | #size-cells = <2>; | ||
| 74 | compatible = "intel,ce4100-pci", "pci"; | ||
| 75 | device_type = "pci"; | ||
| 76 | bus-range = <1 1>; | ||
| 77 | ranges = <0x2000000 0 0xdffe0000 0x2000000 0 0xdffe0000 0 0x1000>; | ||
| 78 | |||
| 79 | interrupt-parent = <&ioapic2>; | ||
| 80 | |||
| 81 | display@2,0 { | ||
| 82 | compatible = "pci8086,2e5b.2", | ||
| 83 | "pci8086,2e5b", | ||
| 84 | "pciclass038000", | ||
| 85 | "pciclass0380"; | ||
| 86 | |||
| 87 | reg = <0x11000 0x0 0x0 0x0 0x0>; | ||
| 88 | interrupts = <0 1>; | ||
| 89 | }; | ||
| 90 | |||
| 91 | multimedia@3,0 { | ||
| 92 | compatible = "pci8086,2e5c.2", | ||
| 93 | "pci8086,2e5c", | ||
| 94 | "pciclass048000", | ||
| 95 | "pciclass0480"; | ||
| 96 | |||
| 97 | reg = <0x11800 0x0 0x0 0x0 0x0>; | ||
| 98 | interrupts = <2 1>; | ||
| 99 | }; | ||
| 100 | |||
| 101 | multimedia@4,0 { | ||
| 102 | compatible = "pci8086,2e5d.2", | ||
| 103 | "pci8086,2e5d", | ||
| 104 | "pciclass048000", | ||
| 105 | "pciclass0480"; | ||
| 106 | |||
| 107 | reg = <0x12000 0x0 0x0 0x0 0x0>; | ||
| 108 | interrupts = <4 1>; | ||
| 109 | }; | ||
| 110 | |||
| 111 | multimedia@4,1 { | ||
| 112 | compatible = "pci8086,2e5e.2", | ||
| 113 | "pci8086,2e5e", | ||
| 114 | "pciclass048000", | ||
| 115 | "pciclass0480"; | ||
| 116 | |||
| 117 | reg = <0x12100 0x0 0x0 0x0 0x0>; | ||
| 118 | interrupts = <5 1>; | ||
| 119 | }; | ||
| 120 | |||
| 121 | sound@6,0 { | ||
| 122 | compatible = "pci8086,2e5f.2", | ||
| 123 | "pci8086,2e5f", | ||
| 124 | "pciclass040100", | ||
| 125 | "pciclass0401"; | ||
| 126 | |||
| 127 | reg = <0x13000 0x0 0x0 0x0 0x0>; | ||
| 128 | interrupts = <6 1>; | ||
| 129 | }; | ||
| 130 | |||
| 131 | sound@6,1 { | ||
| 132 | compatible = "pci8086,2e5f.2", | ||
| 133 | "pci8086,2e5f", | ||
| 134 | "pciclass040100", | ||
| 135 | "pciclass0401"; | ||
| 136 | |||
| 137 | reg = <0x13100 0x0 0x0 0x0 0x0>; | ||
| 138 | interrupts = <7 1>; | ||
| 139 | }; | ||
| 140 | |||
| 141 | sound@6,2 { | ||
| 142 | compatible = "pci8086,2e60.2", | ||
| 143 | "pci8086,2e60", | ||
| 144 | "pciclass040100", | ||
| 145 | "pciclass0401"; | ||
| 146 | |||
| 147 | reg = <0x13200 0x0 0x0 0x0 0x0>; | ||
| 148 | interrupts = <8 1>; | ||
| 149 | }; | ||
| 150 | |||
| 151 | display@8,0 { | ||
| 152 | compatible = "pci8086,2e61.2", | ||
| 153 | "pci8086,2e61", | ||
| 154 | "pciclass038000", | ||
| 155 | "pciclass0380"; | ||
| 156 | |||
| 157 | reg = <0x14000 0x0 0x0 0x0 0x0>; | ||
| 158 | interrupts = <9 1>; | ||
| 159 | }; | ||
| 160 | |||
| 161 | display@8,1 { | ||
| 162 | compatible = "pci8086,2e62.2", | ||
| 163 | "pci8086,2e62", | ||
| 164 | "pciclass038000", | ||
| 165 | "pciclass0380"; | ||
| 166 | |||
| 167 | reg = <0x14100 0x0 0x0 0x0 0x0>; | ||
| 168 | interrupts = <10 1>; | ||
| 169 | }; | ||
| 170 | |||
| 171 | multimedia@8,2 { | ||
| 172 | compatible = "pci8086,2e63.2", | ||
| 173 | "pci8086,2e63", | ||
| 174 | "pciclass048000", | ||
| 175 | "pciclass0480"; | ||
| 176 | |||
| 177 | reg = <0x14200 0x0 0x0 0x0 0x0>; | ||
| 178 | interrupts = <11 1>; | ||
| 179 | }; | ||
| 180 | |||
| 181 | entertainment-encryption@9,0 { | ||
| 182 | compatible = "pci8086,2e64.2", | ||
| 183 | "pci8086,2e64", | ||
| 184 | "pciclass101000", | ||
| 185 | "pciclass1010"; | ||
| 186 | |||
| 187 | reg = <0x14800 0x0 0x0 0x0 0x0>; | ||
| 188 | interrupts = <12 1>; | ||
| 189 | }; | ||
| 190 | |||
| 191 | localbus@a,0 { | ||
| 192 | compatible = "pci8086,2e65.2", | ||
| 193 | "pci8086,2e65", | ||
| 194 | "pciclassff0000", | ||
| 195 | "pciclassff00"; | ||
| 196 | |||
| 197 | reg = <0x15000 0x0 0x0 0x0 0x0>; | ||
| 198 | }; | ||
| 199 | |||
| 200 | serial@b,0 { | ||
| 201 | compatible = "pci8086,2e66.2", | ||
| 202 | "pci8086,2e66", | ||
| 203 | "pciclass070003", | ||
| 204 | "pciclass0700"; | ||
| 205 | |||
| 206 | reg = <0x15800 0x0 0x0 0x0 0x0>; | ||
| 207 | interrupts = <14 1>; | ||
| 208 | }; | ||
| 209 | |||
| 210 | gpio@b,1 { | ||
| 211 | compatible = "pci8086,2e67.2", | ||
| 212 | "pci8086,2e67", | ||
| 213 | "pciclassff0000", | ||
| 214 | "pciclassff00"; | ||
| 215 | |||
| 216 | #gpio-cells = <2>; | ||
| 217 | reg = <0x15900 0x0 0x0 0x0 0x0>; | ||
| 218 | interrupts = <15 1>; | ||
| 219 | gpio-controller; | ||
| 220 | }; | ||
| 221 | |||
| 222 | i2c-controller@b,2 { | ||
| 223 | #address-cells = <2>; | ||
| 224 | #size-cells = <1>; | ||
| 225 | compatible = "pci8086,2e68.2", | ||
| 226 | "pci8086,2e68", | ||
| 227 | "pciclass,ff0000", | ||
| 228 | "pciclass,ff00"; | ||
| 229 | |||
| 230 | reg = <0x15a00 0x0 0x0 0x0 0x0>; | ||
| 231 | interrupts = <16 1>; | ||
| 232 | ranges = <0 0 0x02000000 0 0xdffe0500 0x100 | ||
| 233 | 1 0 0x02000000 0 0xdffe0600 0x100 | ||
| 234 | 2 0 0x02000000 0 0xdffe0700 0x100>; | ||
| 235 | |||
| 236 | i2c@0 { | ||
| 237 | #address-cells = <1>; | ||
| 238 | #size-cells = <0>; | ||
| 239 | compatible = "intel,ce4100-i2c-controller"; | ||
| 240 | reg = <0 0 0x100>; | ||
| 241 | }; | ||
| 242 | |||
| 243 | i2c@1 { | ||
| 244 | #address-cells = <1>; | ||
| 245 | #size-cells = <0>; | ||
| 246 | compatible = "intel,ce4100-i2c-controller"; | ||
| 247 | reg = <1 0 0x100>; | ||
| 248 | |||
| 249 | gpio@26 { | ||
| 250 | #gpio-cells = <2>; | ||
| 251 | compatible = "ti,pcf8575"; | ||
| 252 | reg = <0x26>; | ||
| 253 | gpio-controller; | ||
| 254 | }; | ||
| 255 | }; | ||
| 256 | |||
| 257 | i2c@2 { | ||
| 258 | #address-cells = <1>; | ||
| 259 | #size-cells = <0>; | ||
| 260 | compatible = "intel,ce4100-i2c-controller"; | ||
| 261 | reg = <2 0 0x100>; | ||
| 262 | |||
| 263 | gpio@26 { | ||
| 264 | #gpio-cells = <2>; | ||
| 265 | compatible = "ti,pcf8575"; | ||
| 266 | reg = <0x26>; | ||
| 267 | gpio-controller; | ||
| 268 | }; | ||
| 269 | }; | ||
| 270 | }; | ||
| 271 | |||
| 272 | smard-card@b,3 { | ||
| 273 | compatible = "pci8086,2e69.2", | ||
| 274 | "pci8086,2e69", | ||
| 275 | "pciclass070500", | ||
| 276 | "pciclass0705"; | ||
| 277 | |||
| 278 | reg = <0x15b00 0x0 0x0 0x0 0x0>; | ||
| 279 | interrupts = <15 1>; | ||
| 280 | }; | ||
| 281 | |||
| 282 | spi-controller@b,4 { | ||
| 283 | #address-cells = <1>; | ||
| 284 | #size-cells = <0>; | ||
| 285 | compatible = | ||
| 286 | "pci8086,2e6a.2", | ||
| 287 | "pci8086,2e6a", | ||
| 288 | "pciclass,ff0000", | ||
| 289 | "pciclass,ff00"; | ||
| 290 | |||
| 291 | reg = <0x15c00 0x0 0x0 0x0 0x0>; | ||
| 292 | interrupts = <15 1>; | ||
| 293 | |||
| 294 | dac@0 { | ||
| 295 | compatible = "ti,pcm1755"; | ||
| 296 | reg = <0>; | ||
| 297 | spi-max-frequency = <115200>; | ||
| 298 | }; | ||
| 299 | |||
| 300 | dac@1 { | ||
| 301 | compatible = "ti,pcm1609a"; | ||
| 302 | reg = <1>; | ||
| 303 | spi-max-frequency = <115200>; | ||
| 304 | }; | ||
| 305 | |||
| 306 | eeprom@2 { | ||
| 307 | compatible = "atmel,at93c46"; | ||
| 308 | reg = <2>; | ||
| 309 | spi-max-frequency = <115200>; | ||
| 310 | }; | ||
| 311 | }; | ||
| 312 | |||
| 313 | multimedia@b,7 { | ||
| 314 | compatible = "pci8086,2e6d.2", | ||
| 315 | "pci8086,2e6d", | ||
| 316 | "pciclassff0000", | ||
| 317 | "pciclassff00"; | ||
| 318 | |||
| 319 | reg = <0x15f00 0x0 0x0 0x0 0x0>; | ||
| 320 | }; | ||
| 321 | |||
| 322 | ethernet@c,0 { | ||
| 323 | compatible = "pci8086,2e6e.2", | ||
| 324 | "pci8086,2e6e", | ||
| 325 | "pciclass020000", | ||
| 326 | "pciclass0200"; | ||
| 327 | |||
| 328 | reg = <0x16000 0x0 0x0 0x0 0x0>; | ||
| 329 | interrupts = <21 1>; | ||
| 330 | }; | ||
| 331 | |||
| 332 | clock@c,1 { | ||
| 333 | compatible = "pci8086,2e6f.2", | ||
| 334 | "pci8086,2e6f", | ||
| 335 | "pciclassff0000", | ||
| 336 | "pciclassff00"; | ||
| 337 | |||
| 338 | reg = <0x16100 0x0 0x0 0x0 0x0>; | ||
| 339 | interrupts = <3 1>; | ||
| 340 | }; | ||
| 341 | |||
| 342 | usb@d,0 { | ||
| 343 | compatible = "pci8086,2e70.2", | ||
| 344 | "pci8086,2e70", | ||
| 345 | "pciclass0c0320", | ||
| 346 | "pciclass0c03"; | ||
| 347 | |||
| 348 | reg = <0x16800 0x0 0x0 0x0 0x0>; | ||
| 349 | interrupts = <22 3>; | ||
| 350 | }; | ||
| 351 | |||
| 352 | usb@d,1 { | ||
| 353 | compatible = "pci8086,2e70.2", | ||
| 354 | "pci8086,2e70", | ||
| 355 | "pciclass0c0320", | ||
| 356 | "pciclass0c03"; | ||
| 357 | |||
| 358 | reg = <0x16900 0x0 0x0 0x0 0x0>; | ||
| 359 | interrupts = <22 3>; | ||
| 360 | }; | ||
| 361 | |||
| 362 | sata@e,0 { | ||
| 363 | compatible = "pci8086,2e71.0", | ||
| 364 | "pci8086,2e71", | ||
| 365 | "pciclass010601", | ||
| 366 | "pciclass0106"; | ||
| 367 | |||
| 368 | reg = <0x17000 0x0 0x0 0x0 0x0>; | ||
| 369 | interrupts = <23 3>; | ||
| 370 | }; | ||
| 371 | |||
| 372 | flash@f,0 { | ||
| 373 | compatible = "pci8086,701.1", | ||
| 374 | "pci8086,701", | ||
| 375 | "pciclass050100", | ||
| 376 | "pciclass0501"; | ||
| 377 | |||
| 378 | reg = <0x17800 0x0 0x0 0x0 0x0>; | ||
| 379 | interrupts = <13 1>; | ||
| 380 | }; | ||
| 381 | |||
| 382 | entertainment-encryption@10,0 { | ||
| 383 | compatible = "pci8086,702.1", | ||
| 384 | "pci8086,702", | ||
| 385 | "pciclass101000", | ||
| 386 | "pciclass1010"; | ||
| 387 | |||
| 388 | reg = <0x18000 0x0 0x0 0x0 0x0>; | ||
| 389 | }; | ||
| 390 | |||
| 391 | co-processor@11,0 { | ||
| 392 | compatible = "pci8086,703.1", | ||
| 393 | "pci8086,703", | ||
| 394 | "pciclass0b4000", | ||
| 395 | "pciclass0b40"; | ||
| 396 | |||
| 397 | reg = <0x18800 0x0 0x0 0x0 0x0>; | ||
| 398 | interrupts = <1 1>; | ||
| 399 | }; | ||
| 400 | |||
| 401 | multimedia@12,0 { | ||
| 402 | compatible = "pci8086,704.0", | ||
| 403 | "pci8086,704", | ||
| 404 | "pciclass048000", | ||
| 405 | "pciclass0480"; | ||
| 406 | |||
| 407 | reg = <0x19000 0x0 0x0 0x0 0x0>; | ||
| 408 | }; | ||
| 409 | }; | ||
| 410 | |||
| 411 | isa@1f,0 { | ||
| 412 | #address-cells = <2>; | ||
| 413 | #size-cells = <1>; | ||
| 414 | compatible = "isa"; | ||
| 415 | ranges = <1 0 0 0 0 0x100>; | ||
| 416 | |||
| 417 | rtc@70 { | ||
| 418 | compatible = "intel,ce4100-rtc", "motorola,mc146818"; | ||
| 419 | interrupts = <8 3>; | ||
| 420 | interrupt-parent = <&ioapic1>; | ||
| 421 | ctrl-reg = <2>; | ||
| 422 | freq-reg = <0x26>; | ||
| 423 | reg = <1 0x70 2>; | ||
| 424 | }; | ||
| 425 | }; | ||
| 426 | }; | ||
| 427 | }; | ||
| 428 | }; | ||
diff --git a/arch/x86/platform/mrst/mrst.c b/arch/x86/platform/mrst/mrst.c index ea6529e93c6..5c0207bf959 100644 --- a/arch/x86/platform/mrst/mrst.c +++ b/arch/x86/platform/mrst/mrst.c | |||
| @@ -31,6 +31,7 @@ | |||
| 31 | #include <asm/apic.h> | 31 | #include <asm/apic.h> |
| 32 | #include <asm/io_apic.h> | 32 | #include <asm/io_apic.h> |
| 33 | #include <asm/mrst.h> | 33 | #include <asm/mrst.h> |
| 34 | #include <asm/mrst-vrtc.h> | ||
| 34 | #include <asm/io.h> | 35 | #include <asm/io.h> |
| 35 | #include <asm/i8259.h> | 36 | #include <asm/i8259.h> |
| 36 | #include <asm/intel_scu_ipc.h> | 37 | #include <asm/intel_scu_ipc.h> |
| @@ -268,6 +269,7 @@ void __init x86_mrst_early_setup(void) | |||
| 268 | 269 | ||
| 269 | x86_platform.calibrate_tsc = mrst_calibrate_tsc; | 270 | x86_platform.calibrate_tsc = mrst_calibrate_tsc; |
| 270 | x86_platform.i8042_detect = mrst_i8042_detect; | 271 | x86_platform.i8042_detect = mrst_i8042_detect; |
| 272 | x86_init.timers.wallclock_init = mrst_rtc_init; | ||
| 271 | x86_init.pci.init = pci_mrst_init; | 273 | x86_init.pci.init = pci_mrst_init; |
| 272 | x86_init.pci.fixup_irqs = x86_init_noop; | 274 | x86_init.pci.fixup_irqs = x86_init_noop; |
| 273 | 275 | ||
diff --git a/arch/x86/platform/mrst/vrtc.c b/arch/x86/platform/mrst/vrtc.c index 32cd7edd71a..04cf645feb9 100644 --- a/arch/x86/platform/mrst/vrtc.c +++ b/arch/x86/platform/mrst/vrtc.c | |||
| @@ -100,22 +100,14 @@ int vrtc_set_mmss(unsigned long nowtime) | |||
| 100 | 100 | ||
| 101 | void __init mrst_rtc_init(void) | 101 | void __init mrst_rtc_init(void) |
| 102 | { | 102 | { |
| 103 | unsigned long rtc_paddr; | 103 | unsigned long vrtc_paddr = sfi_mrtc_array[0].phys_addr; |
| 104 | void __iomem *virt_base; | ||
| 105 | 104 | ||
| 106 | sfi_table_parse(SFI_SIG_MRTC, NULL, NULL, sfi_parse_mrtc); | 105 | sfi_table_parse(SFI_SIG_MRTC, NULL, NULL, sfi_parse_mrtc); |
| 107 | if (!sfi_mrtc_num) | 106 | if (!sfi_mrtc_num || !vrtc_paddr) |
| 108 | return; | 107 | return; |
| 109 | 108 | ||
| 110 | rtc_paddr = sfi_mrtc_array[0].phys_addr; | 109 | vrtc_virt_base = (void __iomem *)set_fixmap_offset_nocache(FIX_LNW_VRTC, |
| 111 | 110 | vrtc_paddr); | |
| 112 | /* vRTC's register address may not be page aligned */ | ||
| 113 | set_fixmap_nocache(FIX_LNW_VRTC, rtc_paddr); | ||
| 114 | |||
| 115 | virt_base = (void __iomem *)__fix_to_virt(FIX_LNW_VRTC); | ||
| 116 | virt_base += rtc_paddr & ~PAGE_MASK; | ||
| 117 | vrtc_virt_base = virt_base; | ||
| 118 | |||
| 119 | x86_platform.get_wallclock = vrtc_get_time; | 111 | x86_platform.get_wallclock = vrtc_get_time; |
| 120 | x86_platform.set_wallclock = vrtc_set_mmss; | 112 | x86_platform.set_wallclock = vrtc_set_mmss; |
| 121 | } | 113 | } |
diff --git a/arch/x86/platform/olpc/Makefile b/arch/x86/platform/olpc/Makefile index e797428b163..c2a8cab65e5 100644 --- a/arch/x86/platform/olpc/Makefile +++ b/arch/x86/platform/olpc/Makefile | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | obj-$(CONFIG_OLPC) += olpc.o | 1 | obj-$(CONFIG_OLPC) += olpc.o |
| 2 | obj-$(CONFIG_OLPC_XO1) += olpc-xo1.o | 2 | obj-$(CONFIG_OLPC_XO1) += olpc-xo1.o |
| 3 | obj-$(CONFIG_OLPC_OPENFIRMWARE) += olpc_ofw.o | 3 | obj-$(CONFIG_OLPC) += olpc_ofw.o |
| 4 | obj-$(CONFIG_OLPC_OPENFIRMWARE_DT) += olpc_dt.o | 4 | obj-$(CONFIG_OF_PROMTREE) += olpc_dt.o |
diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c index 61653f07967..1b46a9d9f90 100644 --- a/drivers/i2c/busses/i2c-ocores.c +++ b/drivers/i2c/busses/i2c-ocores.c | |||
| @@ -330,9 +330,7 @@ static int __devinit ocores_i2c_probe(struct platform_device *pdev) | |||
| 330 | i2c->adap = ocores_adapter; | 330 | i2c->adap = ocores_adapter; |
| 331 | i2c_set_adapdata(&i2c->adap, i2c); | 331 | i2c_set_adapdata(&i2c->adap, i2c); |
| 332 | i2c->adap.dev.parent = &pdev->dev; | 332 | i2c->adap.dev.parent = &pdev->dev; |
| 333 | #ifdef CONFIG_OF | ||
| 334 | i2c->adap.dev.of_node = pdev->dev.of_node; | 333 | i2c->adap.dev.of_node = pdev->dev.of_node; |
| 335 | #endif | ||
| 336 | 334 | ||
| 337 | /* add i2c adapter to i2c tree */ | 335 | /* add i2c adapter to i2c tree */ |
| 338 | ret = i2c_add_adapter(&i2c->adap); | 336 | ret = i2c_add_adapter(&i2c->adap); |
| @@ -390,15 +388,11 @@ static int ocores_i2c_resume(struct platform_device *pdev) | |||
| 390 | #define ocores_i2c_resume NULL | 388 | #define ocores_i2c_resume NULL |
| 391 | #endif | 389 | #endif |
| 392 | 390 | ||
| 393 | #ifdef CONFIG_OF | ||
| 394 | static struct of_device_id ocores_i2c_match[] = { | 391 | static struct of_device_id ocores_i2c_match[] = { |
| 395 | { | 392 | { .compatible = "opencores,i2c-ocores", }, |
| 396 | .compatible = "opencores,i2c-ocores", | 393 | {}, |
| 397 | }, | ||
| 398 | {}, | ||
| 399 | }; | 394 | }; |
| 400 | MODULE_DEVICE_TABLE(of, ocores_i2c_match); | 395 | MODULE_DEVICE_TABLE(of, ocores_i2c_match); |
| 401 | #endif | ||
| 402 | 396 | ||
| 403 | /* work with hotplug and coldplug */ | 397 | /* work with hotplug and coldplug */ |
| 404 | MODULE_ALIAS("platform:ocores-i2c"); | 398 | MODULE_ALIAS("platform:ocores-i2c"); |
| @@ -411,9 +405,7 @@ static struct platform_driver ocores_i2c_driver = { | |||
| 411 | .driver = { | 405 | .driver = { |
| 412 | .owner = THIS_MODULE, | 406 | .owner = THIS_MODULE, |
| 413 | .name = "ocores-i2c", | 407 | .name = "ocores-i2c", |
| 414 | #ifdef CONFIG_OF | 408 | .of_match_table = ocores_i2c_match, |
| 415 | .of_match_table = ocores_i2c_match, | ||
| 416 | #endif | ||
| 417 | }, | 409 | }, |
| 418 | }; | 410 | }; |
| 419 | 411 | ||
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index f0bd5bcdf56..045ba6efea4 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
| @@ -537,9 +537,7 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info) | |||
| 537 | client->dev.parent = &client->adapter->dev; | 537 | client->dev.parent = &client->adapter->dev; |
| 538 | client->dev.bus = &i2c_bus_type; | 538 | client->dev.bus = &i2c_bus_type; |
| 539 | client->dev.type = &i2c_client_type; | 539 | client->dev.type = &i2c_client_type; |
| 540 | #ifdef CONFIG_OF | ||
| 541 | client->dev.of_node = info->of_node; | 540 | client->dev.of_node = info->of_node; |
| 542 | #endif | ||
| 543 | 541 | ||
| 544 | dev_set_name(&client->dev, "%d-%04x", i2c_adapter_id(adap), | 542 | dev_set_name(&client->dev, "%d-%04x", i2c_adapter_id(adap), |
| 545 | client->addr); | 543 | client->addr); |
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c index fd877f633dd..2f7fc0c5146 100644 --- a/drivers/mmc/host/mmc_spi.c +++ b/drivers/mmc/host/mmc_spi.c | |||
| @@ -1516,21 +1516,17 @@ static int __devexit mmc_spi_remove(struct spi_device *spi) | |||
| 1516 | return 0; | 1516 | return 0; |
| 1517 | } | 1517 | } |
| 1518 | 1518 | ||
| 1519 | #if defined(CONFIG_OF) | ||
| 1520 | static struct of_device_id mmc_spi_of_match_table[] __devinitdata = { | 1519 | static struct of_device_id mmc_spi_of_match_table[] __devinitdata = { |
| 1521 | { .compatible = "mmc-spi-slot", }, | 1520 | { .compatible = "mmc-spi-slot", }, |
| 1522 | {}, | 1521 | {}, |
| 1523 | }; | 1522 | }; |
| 1524 | #endif | ||
| 1525 | 1523 | ||
| 1526 | static struct spi_driver mmc_spi_driver = { | 1524 | static struct spi_driver mmc_spi_driver = { |
| 1527 | .driver = { | 1525 | .driver = { |
| 1528 | .name = "mmc_spi", | 1526 | .name = "mmc_spi", |
| 1529 | .bus = &spi_bus_type, | 1527 | .bus = &spi_bus_type, |
| 1530 | .owner = THIS_MODULE, | 1528 | .owner = THIS_MODULE, |
| 1531 | #if defined(CONFIG_OF) | ||
| 1532 | .of_match_table = mmc_spi_of_match_table, | 1529 | .of_match_table = mmc_spi_of_match_table, |
| 1533 | #endif | ||
| 1534 | }, | 1530 | }, |
| 1535 | .probe = mmc_spi_probe, | 1531 | .probe = mmc_spi_probe, |
| 1536 | .remove = __devexit_p(mmc_spi_remove), | 1532 | .remove = __devexit_p(mmc_spi_remove), |
diff --git a/drivers/net/ethoc.c b/drivers/net/ethoc.c index b79d7e1555d..db0290f05bd 100644 --- a/drivers/net/ethoc.c +++ b/drivers/net/ethoc.c | |||
| @@ -1163,15 +1163,11 @@ static int ethoc_resume(struct platform_device *pdev) | |||
| 1163 | # define ethoc_resume NULL | 1163 | # define ethoc_resume NULL |
| 1164 | #endif | 1164 | #endif |
| 1165 | 1165 | ||
| 1166 | #ifdef CONFIG_OF | ||
| 1167 | static struct of_device_id ethoc_match[] = { | 1166 | static struct of_device_id ethoc_match[] = { |
| 1168 | { | 1167 | { .compatible = "opencores,ethoc", }, |
| 1169 | .compatible = "opencores,ethoc", | ||
| 1170 | }, | ||
| 1171 | {}, | 1168 | {}, |
| 1172 | }; | 1169 | }; |
| 1173 | MODULE_DEVICE_TABLE(of, ethoc_match); | 1170 | MODULE_DEVICE_TABLE(of, ethoc_match); |
| 1174 | #endif | ||
| 1175 | 1171 | ||
| 1176 | static struct platform_driver ethoc_driver = { | 1172 | static struct platform_driver ethoc_driver = { |
| 1177 | .probe = ethoc_probe, | 1173 | .probe = ethoc_probe, |
| @@ -1181,9 +1177,7 @@ static struct platform_driver ethoc_driver = { | |||
| 1181 | .driver = { | 1177 | .driver = { |
| 1182 | .name = "ethoc", | 1178 | .name = "ethoc", |
| 1183 | .owner = THIS_MODULE, | 1179 | .owner = THIS_MODULE, |
| 1184 | #ifdef CONFIG_OF | ||
| 1185 | .of_match_table = ethoc_match, | 1180 | .of_match_table = ethoc_match, |
| 1186 | #endif | ||
| 1187 | }, | 1181 | }, |
| 1188 | }; | 1182 | }; |
| 1189 | 1183 | ||
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig index 3c6e100a3ad..d06a6374ed6 100644 --- a/drivers/of/Kconfig +++ b/drivers/of/Kconfig | |||
| @@ -69,4 +69,10 @@ config OF_MDIO | |||
| 69 | help | 69 | help |
| 70 | OpenFirmware MDIO bus (Ethernet PHY) accessors | 70 | OpenFirmware MDIO bus (Ethernet PHY) accessors |
| 71 | 71 | ||
| 72 | config OF_PCI | ||
| 73 | def_tristate PCI | ||
| 74 | depends on PCI && (PPC || MICROBLAZE || X86) | ||
| 75 | help | ||
| 76 | OpenFirmware PCI bus accessors | ||
| 77 | |||
| 72 | endmenu # OF | 78 | endmenu # OF |
diff --git a/drivers/of/Makefile b/drivers/of/Makefile index 3ab21a0a490..f7861ed2f28 100644 --- a/drivers/of/Makefile +++ b/drivers/of/Makefile | |||
| @@ -9,3 +9,4 @@ obj-$(CONFIG_OF_I2C) += of_i2c.o | |||
| 9 | obj-$(CONFIG_OF_NET) += of_net.o | 9 | obj-$(CONFIG_OF_NET) += of_net.o |
| 10 | obj-$(CONFIG_OF_SPI) += of_spi.o | 10 | obj-$(CONFIG_OF_SPI) += of_spi.o |
| 11 | obj-$(CONFIG_OF_MDIO) += of_mdio.o | 11 | obj-$(CONFIG_OF_MDIO) += of_mdio.o |
| 12 | 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 index 00000000000..ac1ec54e4fd --- /dev/null +++ b/drivers/of/of_pci.c | |||
| @@ -0,0 +1,92 @@ | |||
| 1 | #include <linux/kernel.h> | ||
| 2 | #include <linux/of_pci.h> | ||
| 3 | #include <linux/of_irq.h> | ||
| 4 | #include <asm/prom.h> | ||
| 5 | |||
| 6 | /** | ||
| 7 | * of_irq_map_pci - Resolve the interrupt for a PCI device | ||
| 8 | * @pdev: the device whose interrupt is to be resolved | ||
| 9 | * @out_irq: structure of_irq filled by this function | ||
| 10 | * | ||
| 11 | * This function resolves the PCI interrupt for a given PCI device. If a | ||
| 12 | * device-node exists for a given pci_dev, it will use normal OF tree | ||
| 13 | * walking. If not, it will implement standard swizzling and walk up the | ||
| 14 | * PCI tree until an device-node is found, at which point it will finish | ||
| 15 | * resolving using the OF tree walking. | ||
| 16 | */ | ||
| 17 | int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq) | ||
| 18 | { | ||
| 19 | struct device_node *dn, *ppnode; | ||
| 20 | struct pci_dev *ppdev; | ||
| 21 | u32 lspec; | ||
| 22 | __be32 lspec_be; | ||
| 23 | __be32 laddr[3]; | ||
| 24 | u8 pin; | ||
| 25 | int rc; | ||
| 26 | |||
| 27 | /* Check if we have a device node, if yes, fallback to standard | ||
| 28 | * device tree parsing | ||
| 29 | */ | ||
| 30 | dn = pci_device_to_OF_node(pdev); | ||
| 31 | if (dn) { | ||
| 32 | rc = of_irq_map_one(dn, 0, out_irq); | ||
| 33 | if (!rc) | ||
| 34 | return rc; | ||
| 35 | } | ||
| 36 | |||
| 37 | /* Ok, we don't, time to have fun. Let's start by building up an | ||
| 38 | * interrupt spec. we assume #interrupt-cells is 1, which is standard | ||
| 39 | * for PCI. If you do different, then don't use that routine. | ||
| 40 | */ | ||
| 41 | rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin); | ||
| 42 | if (rc != 0) | ||
| 43 | return rc; | ||
| 44 | /* No pin, exit */ | ||
| 45 | if (pin == 0) | ||
| 46 | return -ENODEV; | ||
| 47 | |||
| 48 | /* Now we walk up the PCI tree */ | ||
| 49 | lspec = pin; | ||
| 50 | for (;;) { | ||
| 51 | /* Get the pci_dev of our parent */ | ||
| 52 | ppdev = pdev->bus->self; | ||
| 53 | |||
| 54 | /* Ouch, it's a host bridge... */ | ||
| 55 | if (ppdev == NULL) { | ||
| 56 | ppnode = pci_bus_to_OF_node(pdev->bus); | ||
| 57 | |||
| 58 | /* No node for host bridge ? give up */ | ||
| 59 | if (ppnode == NULL) | ||
| 60 | return -EINVAL; | ||
| 61 | } else { | ||
| 62 | /* We found a P2P bridge, check if it has a node */ | ||
| 63 | ppnode = pci_device_to_OF_node(ppdev); | ||
| 64 | } | ||
| 65 | |||
| 66 | /* Ok, we have found a parent with a device-node, hand over to | ||
| 67 | * the OF parsing code. | ||
| 68 | * We build a unit address from the linux device to be used for | ||
| 69 | * resolution. Note that we use the linux bus number which may | ||
| 70 | * not match your firmware bus numbering. | ||
| 71 | * Fortunately, in most cases, interrupt-map-mask doesn't | ||
| 72 | * include the bus number as part of the matching. | ||
| 73 | * You should still be careful about that though if you intend | ||
| 74 | * to rely on this function (you ship a firmware that doesn't | ||
| 75 | * create device nodes for all PCI devices). | ||
| 76 | */ | ||
| 77 | if (ppnode) | ||
| 78 | break; | ||
| 79 | |||
| 80 | /* We can only get here if we hit a P2P bridge with no node, | ||
| 81 | * let's do standard swizzling and try again | ||
| 82 | */ | ||
| 83 | lspec = pci_swizzle_interrupt_pin(pdev, lspec); | ||
| 84 | pdev = ppdev; | ||
| 85 | } | ||
| 86 | |||
| 87 | lspec_be = cpu_to_be32(lspec); | ||
| 88 | laddr[0] = cpu_to_be32((pdev->bus->number << 16) | (pdev->devfn << 8)); | ||
| 89 | laddr[1] = laddr[2] = cpu_to_be32(0); | ||
| 90 | return of_irq_map_raw(ppnode, &lspec_be, 1, laddr, out_irq); | ||
| 91 | } | ||
| 92 | EXPORT_SYMBOL_GPL(of_irq_map_pci); | ||
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index dc2a0ba969c..911e75cdc12 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c | |||
| @@ -37,6 +37,8 @@ | |||
| 37 | #include <linux/mod_devicetable.h> | 37 | #include <linux/mod_devicetable.h> |
| 38 | #include <linux/log2.h> | 38 | #include <linux/log2.h> |
| 39 | #include <linux/pm.h> | 39 | #include <linux/pm.h> |
| 40 | #include <linux/of.h> | ||
| 41 | #include <linux/of_platform.h> | ||
| 40 | 42 | ||
| 41 | /* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */ | 43 | /* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */ |
| 42 | #include <asm-generic/rtc.h> | 44 | #include <asm-generic/rtc.h> |
| @@ -1057,6 +1059,47 @@ static struct pnp_driver cmos_pnp_driver = { | |||
| 1057 | 1059 | ||
| 1058 | #endif /* CONFIG_PNP */ | 1060 | #endif /* CONFIG_PNP */ |
| 1059 | 1061 | ||
| 1062 | #ifdef CONFIG_OF | ||
| 1063 | static const struct of_device_id of_cmos_match[] = { | ||
| 1064 | { | ||
| 1065 | .compatible = "motorola,mc146818", | ||
| 1066 | }, | ||
| 1067 | { }, | ||
| 1068 | }; | ||
| 1069 | MODULE_DEVICE_TABLE(of, of_cmos_match); | ||
| 1070 | |||
| 1071 | static __init void cmos_of_init(struct platform_device *pdev) | ||
| 1072 | { | ||
| 1073 | struct device_node *node = pdev->dev.of_node; | ||
| 1074 | struct rtc_time time; | ||
| 1075 | int ret; | ||
| 1076 | const __be32 *val; | ||
| 1077 | |||
| 1078 | if (!node) | ||
| 1079 | return; | ||
| 1080 | |||
| 1081 | val = of_get_property(node, "ctrl-reg", NULL); | ||
| 1082 | if (val) | ||
| 1083 | CMOS_WRITE(be32_to_cpup(val), RTC_CONTROL); | ||
| 1084 | |||
| 1085 | val = of_get_property(node, "freq-reg", NULL); | ||
| 1086 | if (val) | ||
| 1087 | CMOS_WRITE(be32_to_cpup(val), RTC_FREQ_SELECT); | ||
| 1088 | |||
| 1089 | get_rtc_time(&time); | ||
| 1090 | ret = rtc_valid_tm(&time); | ||
| 1091 | if (ret) { | ||
| 1092 | struct rtc_time def_time = { | ||
| 1093 | .tm_year = 1, | ||
| 1094 | .tm_mday = 1, | ||
| 1095 | }; | ||
| 1096 | set_rtc_time(&def_time); | ||
| 1097 | } | ||
| 1098 | } | ||
| 1099 | #else | ||
| 1100 | static inline void cmos_of_init(struct platform_device *pdev) {} | ||
| 1101 | #define of_cmos_match NULL | ||
| 1102 | #endif | ||
| 1060 | /*----------------------------------------------------------------*/ | 1103 | /*----------------------------------------------------------------*/ |
| 1061 | 1104 | ||
| 1062 | /* Platform setup should have set up an RTC device, when PNP is | 1105 | /* Platform setup should have set up an RTC device, when PNP is |
| @@ -1065,6 +1108,7 @@ static struct pnp_driver cmos_pnp_driver = { | |||
| 1065 | 1108 | ||
| 1066 | static int __init cmos_platform_probe(struct platform_device *pdev) | 1109 | static int __init cmos_platform_probe(struct platform_device *pdev) |
| 1067 | { | 1110 | { |
| 1111 | cmos_of_init(pdev); | ||
| 1068 | cmos_wake_setup(&pdev->dev); | 1112 | cmos_wake_setup(&pdev->dev); |
| 1069 | return cmos_do_probe(&pdev->dev, | 1113 | return cmos_do_probe(&pdev->dev, |
| 1070 | platform_get_resource(pdev, IORESOURCE_IO, 0), | 1114 | platform_get_resource(pdev, IORESOURCE_IO, 0), |
| @@ -1096,6 +1140,7 @@ static struct platform_driver cmos_platform_driver = { | |||
| 1096 | #ifdef CONFIG_PM | 1140 | #ifdef CONFIG_PM |
| 1097 | .pm = &cmos_pm_ops, | 1141 | .pm = &cmos_pm_ops, |
| 1098 | #endif | 1142 | #endif |
| 1143 | .of_match_table = of_cmos_match, | ||
| 1099 | } | 1144 | } |
| 1100 | }; | 1145 | }; |
| 1101 | 1146 | ||
diff --git a/drivers/rtc/rtc-mrst.c b/drivers/rtc/rtc-mrst.c index 4db96fa306f..b86bc328463 100644 --- a/drivers/rtc/rtc-mrst.c +++ b/drivers/rtc/rtc-mrst.c | |||
| @@ -62,6 +62,17 @@ static inline int is_intr(u8 rtc_intr) | |||
| 62 | return rtc_intr & RTC_IRQMASK; | 62 | return rtc_intr & RTC_IRQMASK; |
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | static inline unsigned char vrtc_is_updating(void) | ||
| 66 | { | ||
| 67 | unsigned char uip; | ||
| 68 | unsigned long flags; | ||
| 69 | |||
| 70 | spin_lock_irqsave(&rtc_lock, flags); | ||
| 71 | uip = (vrtc_cmos_read(RTC_FREQ_SELECT) & RTC_UIP); | ||
| 72 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
| 73 | return uip; | ||
| 74 | } | ||
| 75 | |||
| 65 | /* | 76 | /* |
| 66 | * rtc_time's year contains the increment over 1900, but vRTC's YEAR | 77 | * rtc_time's year contains the increment over 1900, but vRTC's YEAR |
| 67 | * register can't be programmed to value larger than 0x64, so vRTC | 78 | * 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) | |||
| 76 | { | 87 | { |
| 77 | unsigned long flags; | 88 | unsigned long flags; |
| 78 | 89 | ||
| 79 | if (rtc_is_updating()) | 90 | if (vrtc_is_updating()) |
| 80 | mdelay(20); | 91 | mdelay(20); |
| 81 | 92 | ||
| 82 | spin_lock_irqsave(&rtc_lock, flags); | 93 | spin_lock_irqsave(&rtc_lock, flags); |
diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c index 95928833855..a429b01d028 100644 --- a/drivers/spi/pxa2xx_spi.c +++ b/drivers/spi/pxa2xx_spi.c | |||
| @@ -1557,9 +1557,7 @@ static int __devinit pxa2xx_spi_probe(struct platform_device *pdev) | |||
| 1557 | drv_data->ssp = ssp; | 1557 | drv_data->ssp = ssp; |
| 1558 | 1558 | ||
| 1559 | master->dev.parent = &pdev->dev; | 1559 | master->dev.parent = &pdev->dev; |
| 1560 | #ifdef CONFIG_OF | ||
| 1561 | master->dev.of_node = pdev->dev.of_node; | 1560 | master->dev.of_node = pdev->dev.of_node; |
| 1562 | #endif | ||
| 1563 | /* the spi->mode bits understood by this driver: */ | 1561 | /* the spi->mode bits understood by this driver: */ |
| 1564 | master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; | 1562 | master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; |
| 1565 | 1563 | ||
diff --git a/drivers/spi/pxa2xx_spi_pci.c b/drivers/spi/pxa2xx_spi_pci.c index 19752b09e15..378e504f89e 100644 --- a/drivers/spi/pxa2xx_spi_pci.c +++ b/drivers/spi/pxa2xx_spi_pci.c | |||
| @@ -89,9 +89,7 @@ static int __devinit ce4100_spi_probe(struct pci_dev *dev, | |||
| 89 | goto err_nomem; | 89 | goto err_nomem; |
| 90 | 90 | ||
| 91 | pdev->dev.parent = &dev->dev; | 91 | pdev->dev.parent = &dev->dev; |
| 92 | #ifdef CONFIG_OF | ||
| 93 | pdev->dev.of_node = dev->dev.of_node; | 92 | pdev->dev.of_node = dev->dev.of_node; |
| 94 | #endif | ||
| 95 | ssp = &spi_info->ssp; | 93 | ssp = &spi_info->ssp; |
| 96 | ssp->phys_base = pci_resource_start(dev, 0); | 94 | ssp->phys_base = pci_resource_start(dev, 0); |
| 97 | ssp->mmio_base = ioremap(phys_beg, phys_len); | 95 | ssp->mmio_base = ioremap(phys_beg, phys_len); |
diff --git a/drivers/spi/xilinx_spi.c b/drivers/spi/xilinx_spi.c index 7adaef62a99..4d2c75df886 100644 --- a/drivers/spi/xilinx_spi.c +++ b/drivers/spi/xilinx_spi.c | |||
| @@ -351,14 +351,12 @@ static irqreturn_t xilinx_spi_irq(int irq, void *dev_id) | |||
| 351 | return IRQ_HANDLED; | 351 | return IRQ_HANDLED; |
| 352 | } | 352 | } |
| 353 | 353 | ||
| 354 | #ifdef CONFIG_OF | ||
| 355 | static const struct of_device_id xilinx_spi_of_match[] = { | 354 | static const struct of_device_id xilinx_spi_of_match[] = { |
| 356 | { .compatible = "xlnx,xps-spi-2.00.a", }, | 355 | { .compatible = "xlnx,xps-spi-2.00.a", }, |
| 357 | { .compatible = "xlnx,xps-spi-2.00.b", }, | 356 | { .compatible = "xlnx,xps-spi-2.00.b", }, |
| 358 | {} | 357 | {} |
| 359 | }; | 358 | }; |
| 360 | MODULE_DEVICE_TABLE(of, xilinx_spi_of_match); | 359 | MODULE_DEVICE_TABLE(of, xilinx_spi_of_match); |
| 361 | #endif | ||
| 362 | 360 | ||
| 363 | struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem, | 361 | struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem, |
| 364 | u32 irq, s16 bus_num, int num_cs, int little_endian, int bits_per_word) | 362 | 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, | |||
| 394 | 392 | ||
| 395 | master->bus_num = bus_num; | 393 | master->bus_num = bus_num; |
| 396 | master->num_chipselect = num_cs; | 394 | master->num_chipselect = num_cs; |
| 397 | #ifdef CONFIG_OF | ||
| 398 | master->dev.of_node = dev->of_node; | 395 | master->dev.of_node = dev->of_node; |
| 399 | #endif | ||
| 400 | 396 | ||
| 401 | xspi->mem = *mem; | 397 | xspi->mem = *mem; |
| 402 | xspi->irq = irq; | 398 | xspi->irq = irq; |
| @@ -539,9 +535,7 @@ static struct platform_driver xilinx_spi_driver = { | |||
| 539 | .driver = { | 535 | .driver = { |
| 540 | .name = XILINX_SPI_NAME, | 536 | .name = XILINX_SPI_NAME, |
| 541 | .owner = THIS_MODULE, | 537 | .owner = THIS_MODULE, |
| 542 | #ifdef CONFIG_OF | ||
| 543 | .of_match_table = xilinx_spi_of_match, | 538 | .of_match_table = xilinx_spi_of_match, |
| 544 | #endif | ||
| 545 | }, | 539 | }, |
| 546 | }; | 540 | }; |
| 547 | 541 | ||
diff --git a/include/linux/device.h b/include/linux/device.h index 1bf5cf0b451..ca5d25225aa 100644 --- a/include/linux/device.h +++ b/include/linux/device.h | |||
| @@ -128,9 +128,7 @@ struct device_driver { | |||
| 128 | 128 | ||
| 129 | bool suppress_bind_attrs; /* disables bind/unbind via sysfs */ | 129 | bool suppress_bind_attrs; /* disables bind/unbind via sysfs */ |
| 130 | 130 | ||
| 131 | #if defined(CONFIG_OF) | ||
| 132 | const struct of_device_id *of_match_table; | 131 | const struct of_device_id *of_match_table; |
| 133 | #endif | ||
| 134 | 132 | ||
| 135 | int (*probe) (struct device *dev); | 133 | int (*probe) (struct device *dev); |
| 136 | int (*remove) (struct device *dev); | 134 | int (*remove) (struct device *dev); |
| @@ -441,9 +439,8 @@ struct device { | |||
| 441 | override */ | 439 | override */ |
| 442 | /* arch specific additions */ | 440 | /* arch specific additions */ |
| 443 | struct dev_archdata archdata; | 441 | struct dev_archdata archdata; |
| 444 | #ifdef CONFIG_OF | 442 | |
| 445 | struct device_node *of_node; | 443 | struct device_node *of_node; /* associated device tree node */ |
| 446 | #endif | ||
| 447 | 444 | ||
| 448 | dev_t devt; /* dev_t, creates the sysfs "dev" */ | 445 | dev_t devt; /* dev_t, creates the sysfs "dev" */ |
| 449 | 446 | ||
diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 903576df88d..06a8d9c7de9 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h | |||
| @@ -258,9 +258,7 @@ struct i2c_board_info { | |||
| 258 | unsigned short addr; | 258 | unsigned short addr; |
| 259 | void *platform_data; | 259 | void *platform_data; |
| 260 | struct dev_archdata *archdata; | 260 | struct dev_archdata *archdata; |
| 261 | #ifdef CONFIG_OF | ||
| 262 | struct device_node *of_node; | 261 | struct device_node *of_node; |
| 263 | #endif | ||
| 264 | int irq; | 262 | int irq; |
| 265 | }; | 263 | }; |
| 266 | 264 | ||
diff --git a/include/linux/of.h b/include/linux/of.h index cad7cf0ab27..266db1d0baa 100644 --- a/include/linux/of.h +++ b/include/linux/of.h | |||
| @@ -23,8 +23,6 @@ | |||
| 23 | 23 | ||
| 24 | #include <asm/byteorder.h> | 24 | #include <asm/byteorder.h> |
| 25 | 25 | ||
| 26 | #ifdef CONFIG_OF | ||
| 27 | |||
| 28 | typedef u32 phandle; | 26 | typedef u32 phandle; |
| 29 | typedef u32 ihandle; | 27 | typedef u32 ihandle; |
| 30 | 28 | ||
| @@ -65,11 +63,18 @@ struct device_node { | |||
| 65 | #endif | 63 | #endif |
| 66 | }; | 64 | }; |
| 67 | 65 | ||
| 66 | #ifdef CONFIG_OF | ||
| 67 | |||
| 68 | /* Pointer for first entry in chain of all nodes. */ | 68 | /* Pointer for first entry in chain of all nodes. */ |
| 69 | extern struct device_node *allnodes; | 69 | extern struct device_node *allnodes; |
| 70 | extern struct device_node *of_chosen; | 70 | extern struct device_node *of_chosen; |
| 71 | extern rwlock_t devtree_lock; | 71 | extern rwlock_t devtree_lock; |
| 72 | 72 | ||
| 73 | static inline bool of_have_populated_dt(void) | ||
| 74 | { | ||
| 75 | return allnodes != NULL; | ||
| 76 | } | ||
| 77 | |||
| 73 | static inline bool of_node_is_root(const struct device_node *node) | 78 | static inline bool of_node_is_root(const struct device_node *node) |
| 74 | { | 79 | { |
| 75 | return node && (node->parent == NULL); | 80 | return node && (node->parent == NULL); |
| @@ -222,5 +227,12 @@ extern void of_attach_node(struct device_node *); | |||
| 222 | extern void of_detach_node(struct device_node *); | 227 | extern void of_detach_node(struct device_node *); |
| 223 | #endif | 228 | #endif |
| 224 | 229 | ||
| 230 | #else | ||
| 231 | |||
| 232 | static inline bool of_have_populated_dt(void) | ||
| 233 | { | ||
| 234 | return false; | ||
| 235 | } | ||
| 236 | |||
| 225 | #endif /* CONFIG_OF */ | 237 | #endif /* CONFIG_OF */ |
| 226 | #endif /* _LINUX_OF_H */ | 238 | #endif /* _LINUX_OF_H */ |
diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h new file mode 100644 index 00000000000..85a27b650d7 --- /dev/null +++ b/include/linux/of_pci.h | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | #ifndef __OF_PCI_H | ||
| 2 | #define __OF_PCI_H | ||
| 3 | |||
| 4 | #include <linux/pci.h> | ||
| 5 | |||
| 6 | struct pci_dev; | ||
| 7 | struct of_irq; | ||
| 8 | int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq); | ||
| 9 | #endif | ||
