* [PATCH 02/11] x86: Add device tree support
[not found] ` <1298405266-1624-1-git-send-email-bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
@ 2011-02-22 20:07 ` Sebastian Andrzej Siewior
2011-02-22 20:07 ` [PATCH 03/11] x86/dtb: Add a device tree for CE4100 Sebastian Andrzej Siewior
` (8 subsequent siblings)
9 siblings, 0 replies; 23+ messages in thread
From: Sebastian Andrzej Siewior @ 2011-02-22 20:07 UTC (permalink / raw)
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
Cc: sodaville-hfZtesqFncYOwBW4kG4KsQ,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
x86-DgEjT+Ai2ygdnm+yROfE0A, Sebastian Andrzej Siewior
This patch adds minimal support for device tree support on x86. It will
be passed to the kernel via setup_data which requires atleast boot
protocol 2.09.
Memory size, restricted memory regions, boot arguments are gathered the
traditional way so things like cmd_line are just here to let the code
compile.
The current plan is use the device tree as an extension and to gather
informations from it which can not be enumerated and have to be
hardcoded otherwise. This includes things like
- which devices are on this I2C/ SPI bus?
- how are the interrupts wired to IO APIC?
- where could my hpet be?
Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
Acked-by: Grant Likely <grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
Signed-off-by: Dirk Brandewie <dirk.brandewie-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
Documentation/devicetree/booting-without-of.txt | 20 +++++++++
arch/x86/Kconfig | 7 +++
arch/x86/include/asm/bootparam.h | 1 +
arch/x86/include/asm/irq.h | 3 -
arch/x86/include/asm/prom.h | 47 ++++++++++++++++++++-
arch/x86/kernel/Makefile | 1 +
arch/x86/kernel/devicetree.c | 51 +++++++++++++++++++++++
arch/x86/kernel/irq.c | 9 ----
arch/x86/kernel/setup.c | 4 ++
9 files changed, 130 insertions(+), 13 deletions(-)
create mode 100644 arch/x86/kernel/devicetree.c
diff --git a/Documentation/devicetree/booting-without-of.txt b/Documentation/devicetree/booting-without-of.txt
index 28b1c9d..55fd262 100644
--- a/Documentation/devicetree/booting-without-of.txt
+++ b/Documentation/devicetree/booting-without-of.txt
@@ -13,6 +13,7 @@ Table of Contents
I - Introduction
1) Entry point for arch/powerpc
+ 2) Entry point for arch/x86
II - The DT block format
1) Header
@@ -225,6 +226,25 @@ it with special cases.
cannot support both configurations with Book E and configurations
with classic Powerpc architectures.
+2) Entry point for arch/x86
+-------------------------------
+
+ There is one single 32bit entry point to the kernel at code32_start,
+ the decompressor (the real mode entry point goes to the same 32bit
+ entry point once it switched into protected mode). That entry point
+ supports one calling convention which is documented in
+ Documentation/x86/boot.txt
+ The physical pointer to the device-tree block (defined in chapter II)
+ is passed via setup_data which requires at least boot protocol 2.09.
+ The type filed is defined as
+
+ #define SETUP_DTB 2
+
+ This device-tree is used as an extension to the "boot page". As such it
+ does not parse / consider data which is already covered by the boot
+ page. This includes memory size, reserved ranges, command line arguments
+ or initrd address. It simply holds information which can not be retrieved
+ otherwise like interrupt routing or a list of devices behind an I2C bus.
II - The DT block format
========================
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index d5ed94d..ce7c7b9 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -297,6 +297,13 @@ config X86_BIGSMP
---help---
This option is needed for the systems that have more than 8 CPUs
+config USE_OF
+ bool "Support for device tree"
+ select OF
+ select OF_EARLY_FLATTREE
+ ---help---
+ Device tree support on X86.
+
if X86_32
config X86_EXTENDED_PLATFORM
bool "Support for extended (non-PC) x86 platforms"
diff --git a/arch/x86/include/asm/bootparam.h b/arch/x86/include/asm/bootparam.h
index c8bfe63..e020d88 100644
--- a/arch/x86/include/asm/bootparam.h
+++ b/arch/x86/include/asm/bootparam.h
@@ -12,6 +12,7 @@
/* setup data types */
#define SETUP_NONE 0
#define SETUP_E820_EXT 1
+#define SETUP_DTB 2
/* extensible setup data list node */
struct setup_data {
diff --git a/arch/x86/include/asm/irq.h b/arch/x86/include/asm/irq.h
index c704b38..ba870bb 100644
--- a/arch/x86/include/asm/irq.h
+++ b/arch/x86/include/asm/irq.h
@@ -10,9 +10,6 @@
#include <asm/apicdef.h>
#include <asm/irq_vectors.h>
-/* Even though we don't support this, supply it to appease OF */
-static inline void irq_dispose_mapping(unsigned int virq) { }
-
static inline int irq_canonicalize(int irq)
{
return ((irq == 2) ? 9 : irq);
diff --git a/arch/x86/include/asm/prom.h b/arch/x86/include/asm/prom.h
index b4ec95f..841697d 100644
--- a/arch/x86/include/asm/prom.h
+++ b/arch/x86/include/asm/prom.h
@@ -1 +1,46 @@
-/* dummy prom.h; here to make linux/of.h's #includes happy */
+/*
+ * Definitions for Device tree / OpenFirmware handling on X86
+ *
+ * based on arch/powerpc/include/asm/prom.h which is
+ * Copyright (C) 1996-2005 Paul Mackerras.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_X86_PROM_H
+#define _ASM_X86_PROM_H
+#ifndef __ASSEMBLY__
+
+#include <linux/of.h>
+#include <linux/types.h>
+#include <asm/irq.h>
+#include <asm/atomic.h>
+#include <asm/setup.h>
+
+#ifdef CONFIG_OF
+extern void add_dtb(u64 data);
+#else
+static inline void add_dtb(u64 data) { }
+#endif
+
+extern char cmd_line[COMMAND_LINE_SIZE];
+
+#define pci_address_to_pio pci_address_to_pio
+unsigned long pci_address_to_pio(phys_addr_t addr);
+
+/**
+ * irq_dispose_mapping - Unmap an interrupt
+ * @virq: linux virq number of the interrupt to unmap
+ *
+ * FIXME: We really should implement proper virq handling like power,
+ * but that's going to be major surgery.
+ */
+static inline void irq_dispose_mapping(unsigned int virq) { }
+
+#define HAVE_ARCH_DEVTREE_FIXUPS
+
+#endif /* __ASSEMBLY__ */
+#endif
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 34244b2..6ac5036 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -109,6 +109,7 @@ obj-$(CONFIG_MICROCODE) += microcode.o
obj-$(CONFIG_X86_CHECK_BIOS_CORRUPTION) += check.o
obj-$(CONFIG_SWIOTLB) += pci-swiotlb.o
+obj-$(CONFIG_OF) += devicetree.o
###
# 64 bit specific files
diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c
new file mode 100644
index 0000000..b86c65e
--- /dev/null
+++ b/arch/x86/kernel/devicetree.c
@@ -0,0 +1,51 @@
+/*
+ * Architecture specific OF callbacks.
+ */
+#include <linux/bootmem.h>
+#include <linux/io.h>
+#include <linux/list.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include <linux/of_platform.h>
+#include <linux/slab.h>
+
+char __initdata cmd_line[COMMAND_LINE_SIZE];
+
+unsigned int irq_create_of_mapping(struct device_node *controller,
+ const u32 *intspec, unsigned int intsize)
+{
+ return intspec[0];
+
+}
+EXPORT_SYMBOL_GPL(irq_create_of_mapping);
+
+unsigned long pci_address_to_pio(phys_addr_t address)
+{
+ /*
+ * The ioport address can be directly used by inX / outX
+ */
+ BUG_ON(address >= (1 << 16));
+ return (unsigned long)address;
+}
+EXPORT_SYMBOL_GPL(pci_address_to_pio);
+
+void __init early_init_dt_scan_chosen_arch(unsigned long node)
+{
+ BUG();
+}
+
+void __init early_init_dt_add_memory_arch(u64 base, u64 size)
+{
+ BUG();
+}
+
+void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
+{
+ return __alloc_bootmem(size, align, __pa(MAX_DMA_ADDRESS));
+}
+
+void __init add_dtb(u64 data)
+{
+ initial_boot_params = phys_to_virt((u64) (u32) data +
+ offsetof(struct setup_data, data));
+}
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
index 387b6a0..7531360 100644
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@ -276,15 +276,6 @@ void smp_x86_platform_ipi(struct pt_regs *regs)
EXPORT_SYMBOL_GPL(vector_used_by_percpu_irq);
-#ifdef CONFIG_OF
-unsigned int irq_create_of_mapping(struct device_node *controller,
- const u32 *intspec, unsigned int intsize)
-{
- return intspec[0];
-}
-EXPORT_SYMBOL_GPL(irq_create_of_mapping);
-#endif
-
#ifdef CONFIG_HOTPLUG_CPU
/* A cpu has been removed from cpu_online_mask. Reset irq affinities. */
void fixup_irqs(void)
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 96cdb9c..046bcbc 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -113,6 +113,7 @@
#endif
#include <asm/mce.h>
#include <asm/alternative.h>
+#include <asm/prom.h>
/*
* end_pfn only includes RAM, while max_pfn_mapped includes all e820 entries.
@@ -446,6 +447,9 @@ static void __init parse_setup_data(void)
case SETUP_E820_EXT:
parse_e820_ext(data);
break;
+ case SETUP_DTB:
+ add_dtb(pa_data);
+ break;
default:
break;
}
--
1.7.4
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 03/11] x86/dtb: Add a device tree for CE4100
[not found] ` <1298405266-1624-1-git-send-email-bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
2011-02-22 20:07 ` [PATCH 02/11] x86: Add device tree support Sebastian Andrzej Siewior
@ 2011-02-22 20:07 ` Sebastian Andrzej Siewior
2011-02-22 20:59 ` Grant Likely
2011-02-22 20:07 ` [PATCH 04/11] x86/dtb: add irq domain abstraction Sebastian Andrzej Siewior
` (7 subsequent siblings)
9 siblings, 1 reply; 23+ messages in thread
From: Sebastian Andrzej Siewior @ 2011-02-22 20:07 UTC (permalink / raw)
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
Cc: sodaville-hfZtesqFncYOwBW4kG4KsQ,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
x86-DgEjT+Ai2ygdnm+yROfE0A, Sebastian Andrzej Siewior
History:
v1..v2:
- dropped device_type except for cpu & pci. I have the compatible string
for pci so I can drop the device_type once it is possible
- I lowercased all compatible types. I will need to resend some patches
which have upper case intel
- The cpu had the same compatible string as the soc node. So I added to
the soc node -immr for internel memory mapped registers.
- I added generic names for all parts.
- I reworked the i2c bars matching the way you suggested. I added a
compatible node for the PCI device which only the PCI ids in its
compatible string. The bars (each represents a complete i2c
controller) have a "intel,ce4100-i2c-controller" compatible node. It
is not used by the driver.
The driver is probed via PCI ids (by the pci subsystem not OF) and
matches the bar address against the ressource in the child node. Once
there is a hit the node is attached.
- The SPI driver is also probed via pci. However I also attached a
compatible property based on PCI ids
v2..v3:
- intel,ce4100-immr become intel,ce4100-cp. cp stands for core
peripherals. The Atom data sheet talks here about ACPI devices. Since
we don't have ACPI this does not apply here.
- The interrupt map is gone. There are now plenty of device nodes.
- The "unit address string" got fixed, it uses not DD,V format.
v3..v4:
- added descriptions for compatible nodes introduced here:
- intel,ce4100-ioapic
- intel,ce4100-lapic
- intel,ce4100-hpet
- intel,ce4100
- intel,ce4100-cp
- intel,ce4100-pci
- added a description about I2C controller magic.
- Added gpio-controller and gpio-cells property to gpio devices. Those
properties are not (yet) used.
Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
Signed-off-by: Sebastian Andrzej Siewior <bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
Signed-off-by: Dirk Brandewie <dirk.brandewie-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
.../devicetree/bindings/i2c/ce4100-i2c.txt | 93 +++++
Documentation/devicetree/bindings/x86/ce4100.txt | 38 ++
.../devicetree/bindings/x86/interrupt.txt | 29 ++
Documentation/devicetree/bindings/x86/timer.txt | 6 +
arch/x86/platform/ce4100/falconfalls.dts | 430 ++++++++++++++++++++
5 files changed, 596 insertions(+), 0 deletions(-)
create mode 100644 Documentation/devicetree/bindings/i2c/ce4100-i2c.txt
create mode 100644 Documentation/devicetree/bindings/x86/ce4100.txt
create mode 100644 Documentation/devicetree/bindings/x86/interrupt.txt
create mode 100644 Documentation/devicetree/bindings/x86/timer.txt
create mode 100644 arch/x86/platform/ce4100/falconfalls.dts
diff --git a/Documentation/devicetree/bindings/i2c/ce4100-i2c.txt b/Documentation/devicetree/bindings/i2c/ce4100-i2c.txt
new file mode 100644
index 0000000..569b162
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/ce4100-i2c.txt
@@ -0,0 +1,93 @@
+CE4100 I2C
+----------
+
+CE4100 has one PCI device which is described as the I2C-Controller. This
+PCI device has three PCI-bars, each bar contains a complete I2C
+controller. So we have a total of three independent I2C-Controllers
+which share only an interrupt line.
+The driver is probed via the PCI-ID and is gathering the information of
+attached devices from the devices tree.
+Grant Likely recommended to use the ranges property to map the PCI-Bar
+number to its physical address and to use this to find the child nodes
+of the specific I2C controller. This were his exact words:
+
+ Here's where the magic happens. Each entry in
+ ranges describes how the parent pci address space
+ (middle group of 3) is translated to the local
+ address space (first group of 2) and the size of
+ each range (last cell). In this particular case,
+ the first cell of the local address is chosen to be
+ 1:1 mapped to the BARs, and the second is the
+ offset from be base of the BAR (which would be
+ non-zero if you had 2 or more devices mapped off
+ the same BAR)
+
+ ranges allows the address mapping to be described
+ in a way that the OS can interpret without
+ requiring custom device driver code.
+
+This is an example which is used on FalconFalls:
+------------------------------------------------
+ i2c-controller@b,2 {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ compatible = "pci8086,2e68.2",
+ "pci8086,2e68",
+ "pciclass,ff0000",
+ "pciclass,ff00";
+
+ reg = <0x15a00 0x0 0x0 0x0 0x0>;
+ interrupts = <16 1>;
+
+ /* as described by Grant, the first number in the group of
+ * three is the bar number followed by the 64bit bar address
+ * followed by size of the mapping. The bar address
+ * requires also a valid translation in parents ranges
+ * property.
+ */
+ ranges = <0 0 0x02000000 0 0xdffe0500 0x100
+ 1 0 0x02000000 0 0xdffe0600 0x100
+ 2 0 0x02000000 0 0xdffe0700 0x100>;
+
+ i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "intel,ce4100-i2c-controller";
+
+ /* The first number in the reg property is the
+ * number of the bar
+ */
+ reg = <0 0 0x100>;
+
+ /* This I2C controller has no devices */
+ };
+
+ i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "intel,ce4100-i2c-controller";
+ reg = <1 0 0x100>;
+
+ /* This I2C controller has one gpio controller */
+ gpio@26 {
+ #gpio-cells = <2>;
+ compatible = "ti,pcf8575";
+ reg = <0x26>;
+ gpio-controller;
+ };
+ };
+
+ i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "intel,ce4100-i2c-controller";
+ reg = <2 0 0x100>;
+
+ gpio@26 {
+ #gpio-cells = <2>;
+ compatible = "ti,pcf8575";
+ reg = <0x26>;
+ gpio-controller;
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/x86/ce4100.txt b/Documentation/devicetree/bindings/x86/ce4100.txt
new file mode 100644
index 0000000..b49ae59
--- /dev/null
+++ b/Documentation/devicetree/bindings/x86/ce4100.txt
@@ -0,0 +1,38 @@
+CE4100 Device Tree Bindings
+---------------------------
+
+The CE4100 SoC uses for in core peripherals the following compatible
+format: <vendor>,<chip>-<device>.
+Many of the "generic" devices like HPET or IO APIC have the ce4100
+name in their compatible property because they first appeared in this
+SoC.
+
+The CPU node
+------------
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "intel,ce4100";
+ reg = <0>;
+ lapic = <&lapic0>;
+ };
+
+The reg property describes the CPU number. The lapic property points to
+the local APIC timer.
+
+The SoC node
+------------
+
+This node describes the in-core peripherals. Required property:
+ compatible = "intel,ce4100-cp";
+
+The PCI node
+------------
+This node describes the PCI bus on the SoC. Its property should be
+ compatible = "intel,ce4100-pci", "pci";
+
+If the OS is using the IO-APIC for interrupt routing then the reported
+interrupt numbers for devices is no longer true. In order to obtain the
+correct interrupt number, the child node which represents the device has
+to contain the interrupt property. Besides the interrupt property it has
+to contain at least the reg property containing the PCI bus address and
+compatible property according to "PCI Bus Binding Revision 2.1".
diff --git a/Documentation/devicetree/bindings/x86/interrupt.txt b/Documentation/devicetree/bindings/x86/interrupt.txt
new file mode 100644
index 0000000..8b0efb0
--- /dev/null
+++ b/Documentation/devicetree/bindings/x86/interrupt.txt
@@ -0,0 +1,29 @@
+Interrupt chips
+---------------
+
+* Intel I/O Advanced Programmable Interrupt Controller (IO APIC)
+
+ Required properties:
+ --------------------
+ compatible = "intel,ce4100-ioapic";
+ #interrupt-cells = <2>;
+
+ Device's interrupt property:
+
+ interrupts = <P S>;
+
+ The first number (P) represents the interrupt pin which is wired to the
+ IO APIC. The second number (S) represents the sense of interrupt which
+ should be configured and can be one of:
+ 0 - Edge Rising
+ 1 - Level Low
+ 2 - Level High
+ 3 - Edge Falling
+
+* Local APIC
+ Required property:
+
+ compatible = "intel,ce4100-lapic";
+
+ This node is currently unused by Linux as the address of the local APIC
+ read from a MSR.
diff --git a/Documentation/devicetree/bindings/x86/timer.txt b/Documentation/devicetree/bindings/x86/timer.txt
new file mode 100644
index 0000000..c688af5
--- /dev/null
+++ b/Documentation/devicetree/bindings/x86/timer.txt
@@ -0,0 +1,6 @@
+Timers
+------
+
+* High Precision Event Timer (HPET)
+ Required property:
+ compatible = "intel,ce4100-hpet";
diff --git a/arch/x86/platform/ce4100/falconfalls.dts b/arch/x86/platform/ce4100/falconfalls.dts
new file mode 100644
index 0000000..e28de4c
--- /dev/null
+++ b/arch/x86/platform/ce4100/falconfalls.dts
@@ -0,0 +1,430 @@
+/*
+ * CE4100 on Falcon Falls
+ *
+ * (c) Copyright 2010 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2 of the License.
+ */
+/dts-v1/;
+/ {
+ model = "intel,falconfalls";
+ compatible = "intel,falconfalls";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "intel,ce4100";
+ reg = <0>;
+ lapic = <&lapic0>;
+ };
+ };
+
+ soc@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "intel,ce4100-cp";
+ ranges;
+
+ ioapic1: interrupt-controller@fec00000 {
+ #interrupt-cells = <2>;
+ compatible = "intel,ce4100-ioapic";
+ interrupt-controller;
+ reg = <0xfec00000 0x1000>;
+ };
+
+ timer@fed00000 {
+ compatible = "intel,ce4100-hpet";
+ reg = <0xfed00000 0x200>;
+ };
+
+ lapic0: interrupt-controller@fee00000 {
+ compatible = "intel,ce4100-lapic";
+ reg = <0xfee00000 0x1000>;
+ };
+
+ pci@3fc {
+ #address-cells = <3>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ compatible = "intel,ce4100-pci", "pci";
+ device_type = "pci";
+ bus-range = <0 0>;
+ ranges = <0x2000000 0 0xbffff000 0xbffff000 0 0x1000
+ 0x2000000 0 0xdffe0000 0xdffe0000 0 0x1000
+ 0x0000000 0 0x0 0x0 0 0x100>;
+
+ /* Secondary IO-APIC */
+ ioapic2: interrupt-controller@0,1 {
+ #interrupt-cells = <2>;
+ compatible = "intel,ce4100-ioapic";
+ interrupt-controller;
+ reg = <0x100 0x0 0x0 0x0 0x0>;
+ assigned-addresses = <0x02000000 0x0 0xbffff000 0x0 0x1000>;
+ };
+
+ pci@1,0 {
+ #address-cells = <3>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ compatible = "intel,ce4100-pci", "pci";
+ device_type = "pci";
+ bus-range = <1 1>;
+ ranges = <0x2000000 0 0xdffe0000 0x2000000 0 0xdffe0000 0 0x1000>;
+
+ interrupt-parent = <&ioapic2>;
+
+ display@2,0 {
+ compatible = "pci8086,2e5b.2",
+ "pci8086,2e5b",
+ "pciclass038000",
+ "pciclass0380";
+
+ reg = <0x11000 0x0 0x0 0x0 0x0>;
+ interrupts = <0 1>;
+ };
+
+ multimedia@3,0 {
+ compatible = "pci8086,2e5c.2",
+ "pci8086,2e5c",
+ "pciclass048000",
+ "pciclass0480";
+
+ reg = <0x11800 0x0 0x0 0x0 0x0>;
+ interrupts = <2 1>;
+ };
+
+ multimedia@4,0 {
+ compatible = "pci8086,2e5d.2",
+ "pci8086,2e5d",
+ "pciclass048000",
+ "pciclass0480";
+
+ reg = <0x12000 0x0 0x0 0x0 0x0>;
+ interrupts = <4 1>;
+ };
+
+ multimedia@4,1 {
+ compatible = "pci8086,2e5e.2",
+ "pci8086,2e5e",
+ "pciclass048000",
+ "pciclass0480";
+
+ reg = <0x12100 0x0 0x0 0x0 0x0>;
+ interrupts = <5 1>;
+ };
+
+ sound@6,0 {
+ compatible = "pci8086,2e5f.2",
+ "pci8086,2e5f",
+ "pciclass040100",
+ "pciclass0401";
+
+ reg = <0x13000 0x0 0x0 0x0 0x0>;
+ interrupts = <6 1>;
+ };
+
+ sound@6,1 {
+ compatible = "pci8086,2e5f.2",
+ "pci8086,2e5f",
+ "pciclass040100",
+ "pciclass0401";
+
+ reg = <0x13100 0x0 0x0 0x0 0x0>;
+ interrupts = <7 1>;
+ };
+
+ sound@6,2 {
+ compatible = "pci8086,2e60.2",
+ "pci8086,2e60",
+ "pciclass040100",
+ "pciclass0401";
+
+ reg = <0x13200 0x0 0x0 0x0 0x0>;
+ interrupts = <8 1>;
+ };
+
+ display@8,0 {
+ compatible = "pci8086,2e61.2",
+ "pci8086,2e61",
+ "pciclass038000",
+ "pciclass0380";
+
+ reg = <0x14000 0x0 0x0 0x0 0x0>;
+ interrupts = <9 1>;
+ };
+
+ display@8,1 {
+ compatible = "pci8086,2e62.2",
+ "pci8086,2e62",
+ "pciclass038000",
+ "pciclass0380";
+
+ reg = <0x14100 0x0 0x0 0x0 0x0>;
+ interrupts = <10 1>;
+ };
+
+ multimedia@8,2 {
+ compatible = "pci8086,2e63.2",
+ "pci8086,2e63",
+ "pciclass048000",
+ "pciclass0480";
+
+ reg = <0x14200 0x0 0x0 0x0 0x0>;
+ interrupts = <11 1>;
+ };
+
+ entertainment-encryption@9,0 {
+ compatible = "pci8086,2e64.2",
+ "pci8086,2e64",
+ "pciclass101000",
+ "pciclass1010";
+
+ reg = <0x14800 0x0 0x0 0x0 0x0>;
+ interrupts = <12 1>;
+ };
+
+ localbus@a,0 {
+ compatible = "pci8086,2e65.2",
+ "pci8086,2e65",
+ "pciclassff0000",
+ "pciclassff00";
+
+ reg = <0x15000 0x0 0x0 0x0 0x0>;
+ };
+
+ serial@b,0 {
+ compatible = "pci8086,2e66.2",
+ "pci8086,2e66",
+ "pciclass070003",
+ "pciclass0700";
+
+ reg = <0x15800 0x0 0x0 0x0 0x0>;
+ interrupts = <14 1>;
+ };
+
+ gpio@b,1 {
+ compatible = "pci8086,2e67.2",
+ "pci8086,2e67",
+ "pciclassff0000",
+ "pciclassff00";
+
+ #gpio-cells = <2>;
+ reg = <0x15900 0x0 0x0 0x0 0x0>;
+ interrupts = <15 1>;
+ gpio-controller;
+ };
+
+ i2c-controller@b,2 {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ compatible = "pci8086,2e68.2",
+ "pci8086,2e68",
+ "pciclass,ff0000",
+ "pciclass,ff00";
+
+ reg = <0x15a00 0x0 0x0 0x0 0x0>;
+ interrupts = <16 1>;
+ ranges = <0 0 0x02000000 0 0xdffe0500 0x100
+ 1 0 0x02000000 0 0xdffe0600 0x100
+ 2 0 0x02000000 0 0xdffe0700 0x100>;
+
+ i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "intel,ce4100-i2c-controller";
+ reg = <0 0 0x100>;
+ };
+
+ i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "intel,ce4100-i2c-controller";
+ reg = <1 0 0x100>;
+
+ gpio@26 {
+ #gpio-cells = <2>;
+ compatible = "ti,pcf8575";
+ reg = <0x26>;
+ gpio-controller;
+ };
+ };
+
+ i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "intel,ce4100-i2c-controller";
+ reg = <2 0 0x100>;
+
+ gpio@26 {
+ #gpio-cells = <2>;
+ compatible = "ti,pcf8575";
+ reg = <0x26>;
+ gpio-controller;
+ };
+ };
+ };
+
+ smard-card@b,3 {
+ compatible = "pci8086,2e69.2",
+ "pci8086,2e69",
+ "pciclass070500",
+ "pciclass0705";
+
+ reg = <0x15b00 0x0 0x0 0x0 0x0>;
+ interrupts = <15 1>;
+ };
+
+ spi-controller@b,4 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible =
+ "pci8086,2e6a.2",
+ "pci8086,2e6a",
+ "pciclass,ff0000",
+ "pciclass,ff00";
+
+ reg = <0x15c00 0x0 0x0 0x0 0x0>;
+ interrupts = <15 1>;
+
+ dac@0 {
+ compatible = "ti,pcm1755";
+ reg = <0>;
+ spi-max-frequency = <115200>;
+ };
+
+ dac@1 {
+ compatible = "ti,pcm1609a";
+ reg = <1>;
+ spi-max-frequency = <115200>;
+ };
+
+ eeprom@2 {
+ compatible = "atmel,at93c46";
+ reg = <2>;
+ spi-max-frequency = <115200>;
+ };
+ };
+
+ multimedia@b,7 {
+ compatible = "pci8086,2e6d.2",
+ "pci8086,2e6d",
+ "pciclassff0000",
+ "pciclassff00";
+
+ reg = <0x15f00 0x0 0x0 0x0 0x0>;
+ };
+
+ ethernet@c,0 {
+ compatible = "pci8086,2e6e.2",
+ "pci8086,2e6e",
+ "pciclass020000",
+ "pciclass0200";
+
+ reg = <0x16000 0x0 0x0 0x0 0x0>;
+ interrupts = <21 1>;
+ };
+
+ clock@c,1 {
+ compatible = "pci8086,2e6f.2",
+ "pci8086,2e6f",
+ "pciclassff0000",
+ "pciclassff00";
+
+ reg = <0x16100 0x0 0x0 0x0 0x0>;
+ interrupts = <3 1>;
+ };
+
+ usb@d,0 {
+ compatible = "pci8086,2e70.2",
+ "pci8086,2e70",
+ "pciclass0c0320",
+ "pciclass0c03";
+
+ reg = <0x16800 0x0 0x0 0x0 0x0>;
+ interrupts = <22 3>;
+ };
+
+ usb@d,1 {
+ compatible = "pci8086,2e70.2",
+ "pci8086,2e70",
+ "pciclass0c0320",
+ "pciclass0c03";
+
+ reg = <0x16900 0x0 0x0 0x0 0x0>;
+ interrupts = <22 3>;
+ };
+
+ sata@e,0 {
+ compatible = "pci8086,2e71.0",
+ "pci8086,2e71",
+ "pciclass010601",
+ "pciclass0106";
+
+ reg = <0x17000 0x0 0x0 0x0 0x0>;
+ interrupts = <23 3>;
+ };
+
+ flash@f,0 {
+ compatible = "pci8086,701.1",
+ "pci8086,701",
+ "pciclass050100",
+ "pciclass0501";
+
+ reg = <0x17800 0x0 0x0 0x0 0x0>;
+ interrupts = <13 1>;
+ };
+
+ entertainment-encryption@10,0 {
+ compatible = "pci8086,702.1",
+ "pci8086,702",
+ "pciclass101000",
+ "pciclass1010";
+
+ reg = <0x18000 0x0 0x0 0x0 0x0>;
+ };
+
+ co-processor@11,0 {
+ compatible = "pci8086,703.1",
+ "pci8086,703",
+ "pciclass0b4000",
+ "pciclass0b40";
+
+ reg = <0x18800 0x0 0x0 0x0 0x0>;
+ interrupts = <1 1>;
+ };
+
+ multimedia@12,0 {
+ compatible = "pci8086,704.0",
+ "pci8086,704",
+ "pciclass048000",
+ "pciclass0480";
+
+ reg = <0x19000 0x0 0x0 0x0 0x0>;
+ };
+ };
+
+ isa@1f,0 {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ compatible = "isa";
+ ranges = <1 0 0 0 0 0x100>;
+
+ rtc@70 {
+ compatible = "intel,ce4100-rtc", "motorola,mc146818";
+ interrupts = <8 3>;
+ interrupt-parent = <&ioapic1>;
+ ctrl-reg = <2>;
+ freq-reg = <0x26>;
+ reg = <1 0x70 2>;
+ };
+ };
+ };
+ };
+};
--
1.7.4
^ permalink raw reply related [flat|nested] 23+ messages in thread* Re: [PATCH 03/11] x86/dtb: Add a device tree for CE4100
2011-02-22 20:07 ` [PATCH 03/11] x86/dtb: Add a device tree for CE4100 Sebastian Andrzej Siewior
@ 2011-02-22 20:59 ` Grant Likely
0 siblings, 0 replies; 23+ messages in thread
From: Grant Likely @ 2011-02-22 20:59 UTC (permalink / raw)
To: Sebastian Andrzej Siewior
Cc: linux-kernel, sodaville, devicetree-discuss, x86
On Tue, Feb 22, 2011 at 1:07 PM, Sebastian Andrzej Siewior
<bigeasy@linutronix.de> wrote:
> History:
> v1..v2:
> - dropped device_type except for cpu & pci. I have the compatible string
> for pci so I can drop the device_type once it is possible
> - I lowercased all compatible types. I will need to resend some patches
> which have upper case intel
> - The cpu had the same compatible string as the soc node. So I added to
> the soc node -immr for internel memory mapped registers.
> - I added generic names for all parts.
> - I reworked the i2c bars matching the way you suggested. I added a
> compatible node for the PCI device which only the PCI ids in its
> compatible string. The bars (each represents a complete i2c
> controller) have a "intel,ce4100-i2c-controller" compatible node. It
> is not used by the driver.
> The driver is probed via PCI ids (by the pci subsystem not OF) and
> matches the bar address against the ressource in the child node. Once
> there is a hit the node is attached.
> - The SPI driver is also probed via pci. However I also attached a
> compatible property based on PCI ids
>
> v2..v3:
> - intel,ce4100-immr become intel,ce4100-cp. cp stands for core
> peripherals. The Atom data sheet talks here about ACPI devices. Since
> we don't have ACPI this does not apply here.
> - The interrupt map is gone. There are now plenty of device nodes.
> - The "unit address string" got fixed, it uses not DD,V format.
>
> v3..v4:
> - added descriptions for compatible nodes introduced here:
> - intel,ce4100-ioapic
> - intel,ce4100-lapic
> - intel,ce4100-hpet
> - intel,ce4100
> - intel,ce4100-cp
> - intel,ce4100-pci
> - added a description about I2C controller magic.
> - Added gpio-controller and gpio-cells property to gpio devices. Those
> properties are not (yet) used.
>
> Cc: devicetree-discuss@lists.ozlabs.org
> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> Signed-off-by: Dirk Brandewie <dirk.brandewie@gmail.com>
Acked-by: Grant Likely <grant.likely@secretlab.ca>
plus one note below...
> ---
> .../devicetree/bindings/i2c/ce4100-i2c.txt | 93 +++++
> Documentation/devicetree/bindings/x86/ce4100.txt | 38 ++
> .../devicetree/bindings/x86/interrupt.txt | 29 ++
> Documentation/devicetree/bindings/x86/timer.txt | 6 +
> arch/x86/platform/ce4100/falconfalls.dts | 430 ++++++++++++++++++++
Next step will be to migrate most of the static soc data out of this
file and into a .dts include file so that multiple boards can use it;
but that can be done later (it's a relatively new feature to dtc).
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH 04/11] x86/dtb: add irq domain abstraction
[not found] ` <1298405266-1624-1-git-send-email-bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
2011-02-22 20:07 ` [PATCH 02/11] x86: Add device tree support Sebastian Andrzej Siewior
2011-02-22 20:07 ` [PATCH 03/11] x86/dtb: Add a device tree for CE4100 Sebastian Andrzej Siewior
@ 2011-02-22 20:07 ` Sebastian Andrzej Siewior
2011-02-22 21:06 ` Grant Likely
2011-02-22 20:07 ` [PATCH 05/11] x86/dtb: add early parsing of IO APIC Sebastian Andrzej Siewior
` (6 subsequent siblings)
9 siblings, 1 reply; 23+ messages in thread
From: Sebastian Andrzej Siewior @ 2011-02-22 20:07 UTC (permalink / raw)
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
Cc: sodaville-hfZtesqFncYOwBW4kG4KsQ,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
x86-DgEjT+Ai2ygdnm+yROfE0A, Sebastian Andrzej Siewior
The here introduced irq_domain abstraction represents a generic irq
controller. It is a subset of powerpc's irq_host which is going to be
renamed to irq_domain and then become generic. This implementation will
be removed once it is generic.
The xlate callback is resposible to parse irq informations like irq type
and number and returns the hardware irq number which is reported by the
hardware as active.
Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
Signed-off-by: Sebastian Andrzej Siewior <bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
Tested-by: Dirk Brandewie <dirk.brandewie-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
arch/x86/include/asm/irq_controller.h | 12 ++++++++
arch/x86/include/asm/prom.h | 2 +
arch/x86/kernel/devicetree.c | 47 ++++++++++++++++++++++++++++++++-
3 files changed, 60 insertions(+), 1 deletions(-)
create mode 100644 arch/x86/include/asm/irq_controller.h
diff --git a/arch/x86/include/asm/irq_controller.h b/arch/x86/include/asm/irq_controller.h
new file mode 100644
index 0000000..423bbbd
--- /dev/null
+++ b/arch/x86/include/asm/irq_controller.h
@@ -0,0 +1,12 @@
+#ifndef __IRQ_CONTROLLER__
+#define __IRQ_CONTROLLER__
+
+struct irq_domain {
+ int (*xlate)(struct irq_domain *h, const u32 *intspec, u32 intsize,
+ u32 *out_hwirq, u32 *out_type);
+ void *priv;
+ struct device_node *controller;
+ struct list_head l;
+};
+
+#endif
diff --git a/arch/x86/include/asm/prom.h b/arch/x86/include/asm/prom.h
index 841697d..70467d1 100644
--- a/arch/x86/include/asm/prom.h
+++ b/arch/x86/include/asm/prom.h
@@ -19,9 +19,11 @@
#include <asm/irq.h>
#include <asm/atomic.h>
#include <asm/setup.h>
+#include <asm/irq_controller.h>
#ifdef CONFIG_OF
extern void add_dtb(u64 data);
+void add_interrupt_host(struct irq_domain *ih);
#else
static inline void add_dtb(u64 data) { }
#endif
diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c
index b86c65e..f2f159c 100644
--- a/arch/x86/kernel/devicetree.c
+++ b/arch/x86/kernel/devicetree.c
@@ -3,19 +3,64 @@
*/
#include <linux/bootmem.h>
#include <linux/io.h>
+#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/of.h>
#include <linux/of_fdt.h>
#include <linux/of_platform.h>
#include <linux/slab.h>
+#include <asm/irq_controller.h>
+
char __initdata cmd_line[COMMAND_LINE_SIZE];
+static LIST_HEAD(irq_domains);
+static DEFINE_RAW_SPINLOCK(big_irq_lock);
+
+void add_interrupt_host(struct irq_domain *ih)
+{
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&big_irq_lock, flags);
+ list_add(&ih->l, &irq_domains);
+ raw_spin_unlock_irqrestore(&big_irq_lock, flags);
+}
+
+static struct irq_domain *get_ih_from_node(struct device_node *controller)
+{
+ struct irq_domain *ih, *found = NULL;
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&big_irq_lock, flags);
+ list_for_each_entry(ih, &irq_domains, l) {
+ if (ih->controller == controller) {
+ found = ih;
+ break;
+ }
+ }
+ raw_spin_unlock_irqrestore(&big_irq_lock, flags);
+ return found;
+}
unsigned int irq_create_of_mapping(struct device_node *controller,
const u32 *intspec, unsigned int intsize)
{
- return intspec[0];
+ struct irq_domain *ih;
+ u32 virq;
+ u32 type;
+ int ret;
+ ih = get_ih_from_node(controller);
+ if (!ih)
+ return 0;
+ ret = ih->xlate(ih, intspec, intsize, &virq, &type);
+ if (ret)
+ return ret;
+ if (type == IRQ_TYPE_NONE)
+ return virq;
+ /* set the mask if it is different from current */
+ if (type == (irq_to_desc(virq)->status & IRQF_TRIGGER_MASK))
+ set_irq_type(virq, type);
+ return virq;
}
EXPORT_SYMBOL_GPL(irq_create_of_mapping);
--
1.7.4
^ permalink raw reply related [flat|nested] 23+ messages in thread* Re: [PATCH 04/11] x86/dtb: add irq domain abstraction
2011-02-22 20:07 ` [PATCH 04/11] x86/dtb: add irq domain abstraction Sebastian Andrzej Siewior
@ 2011-02-22 21:06 ` Grant Likely
0 siblings, 0 replies; 23+ messages in thread
From: Grant Likely @ 2011-02-22 21:06 UTC (permalink / raw)
To: Sebastian Andrzej Siewior
Cc: linux-kernel, sodaville, devicetree-discuss, x86
On Tue, Feb 22, 2011 at 1:07 PM, Sebastian Andrzej Siewior
<bigeasy@linutronix.de> wrote:
> The here introduced irq_domain abstraction represents a generic irq
> controller. It is a subset of powerpc's irq_host which is going to be
> renamed to irq_domain and then become generic. This implementation will
> be removed once it is generic.
>
> The xlate callback is resposible to parse irq informations like irq type
> and number and returns the hardware irq number which is reported by the
> hardware as active.
>
> Cc: devicetree-discuss@lists.ozlabs.org
> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> Tested-by: Dirk Brandewie <dirk.brandewie@gmail.com>
Acked-by: Grant Likely <grant.likely@secretlab.ca>
> ---
> arch/x86/include/asm/irq_controller.h | 12 ++++++++
> arch/x86/include/asm/prom.h | 2 +
> arch/x86/kernel/devicetree.c | 47 ++++++++++++++++++++++++++++++++-
> 3 files changed, 60 insertions(+), 1 deletions(-)
> create mode 100644 arch/x86/include/asm/irq_controller.h
>
> diff --git a/arch/x86/include/asm/irq_controller.h b/arch/x86/include/asm/irq_controller.h
> new file mode 100644
> index 0000000..423bbbd
> --- /dev/null
> +++ b/arch/x86/include/asm/irq_controller.h
> @@ -0,0 +1,12 @@
> +#ifndef __IRQ_CONTROLLER__
> +#define __IRQ_CONTROLLER__
> +
> +struct irq_domain {
> + int (*xlate)(struct irq_domain *h, const u32 *intspec, u32 intsize,
> + u32 *out_hwirq, u32 *out_type);
> + void *priv;
> + struct device_node *controller;
> + struct list_head l;
> +};
> +
> +#endif
> diff --git a/arch/x86/include/asm/prom.h b/arch/x86/include/asm/prom.h
> index 841697d..70467d1 100644
> --- a/arch/x86/include/asm/prom.h
> +++ b/arch/x86/include/asm/prom.h
> @@ -19,9 +19,11 @@
> #include <asm/irq.h>
> #include <asm/atomic.h>
> #include <asm/setup.h>
> +#include <asm/irq_controller.h>
>
> #ifdef CONFIG_OF
> extern void add_dtb(u64 data);
> +void add_interrupt_host(struct irq_domain *ih);
> #else
> static inline void add_dtb(u64 data) { }
> #endif
> diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c
> index b86c65e..f2f159c 100644
> --- a/arch/x86/kernel/devicetree.c
> +++ b/arch/x86/kernel/devicetree.c
> @@ -3,19 +3,64 @@
> */
> #include <linux/bootmem.h>
> #include <linux/io.h>
> +#include <linux/interrupt.h>
> #include <linux/list.h>
> #include <linux/of.h>
> #include <linux/of_fdt.h>
> #include <linux/of_platform.h>
> #include <linux/slab.h>
>
> +#include <asm/irq_controller.h>
> +
> char __initdata cmd_line[COMMAND_LINE_SIZE];
> +static LIST_HEAD(irq_domains);
> +static DEFINE_RAW_SPINLOCK(big_irq_lock);
> +
> +void add_interrupt_host(struct irq_domain *ih)
> +{
> + unsigned long flags;
> +
> + raw_spin_lock_irqsave(&big_irq_lock, flags);
> + list_add(&ih->l, &irq_domains);
> + raw_spin_unlock_irqrestore(&big_irq_lock, flags);
> +}
> +
> +static struct irq_domain *get_ih_from_node(struct device_node *controller)
> +{
> + struct irq_domain *ih, *found = NULL;
> + unsigned long flags;
> +
> + raw_spin_lock_irqsave(&big_irq_lock, flags);
> + list_for_each_entry(ih, &irq_domains, l) {
> + if (ih->controller == controller) {
> + found = ih;
> + break;
> + }
> + }
> + raw_spin_unlock_irqrestore(&big_irq_lock, flags);
> + return found;
> +}
>
> unsigned int irq_create_of_mapping(struct device_node *controller,
> const u32 *intspec, unsigned int intsize)
> {
> - return intspec[0];
> + struct irq_domain *ih;
> + u32 virq;
> + u32 type;
> + int ret;
>
> + ih = get_ih_from_node(controller);
> + if (!ih)
> + return 0;
> + ret = ih->xlate(ih, intspec, intsize, &virq, &type);
> + if (ret)
> + return ret;
> + if (type == IRQ_TYPE_NONE)
> + return virq;
> + /* set the mask if it is different from current */
> + if (type == (irq_to_desc(virq)->status & IRQF_TRIGGER_MASK))
> + set_irq_type(virq, type);
> + return virq;
> }
> EXPORT_SYMBOL_GPL(irq_create_of_mapping);
>
> --
> 1.7.4
>
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss
>
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH 05/11] x86/dtb: add early parsing of IO APIC
[not found] ` <1298405266-1624-1-git-send-email-bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
` (2 preceding siblings ...)
2011-02-22 20:07 ` [PATCH 04/11] x86/dtb: add irq domain abstraction Sebastian Andrzej Siewior
@ 2011-02-22 20:07 ` Sebastian Andrzej Siewior
2011-02-22 20:07 ` [PATCH 06/11] x86/dtb: add support hpet Sebastian Andrzej Siewior
` (5 subsequent siblings)
9 siblings, 0 replies; 23+ messages in thread
From: Sebastian Andrzej Siewior @ 2011-02-22 20:07 UTC (permalink / raw)
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
Cc: sodaville-hfZtesqFncYOwBW4kG4KsQ,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
x86-DgEjT+Ai2ygdnm+yROfE0A, Sebastian Andrzej Siewior
The apic & ioapic have to be added to system early because
native_init_IRQ() requires it. In order to obtain the address of the
ioapic the device tree has to be unflattened because
of_address_to_resource() has to work.
The device tree is relocated to ensure it is always covered by the
kernel and the boot loader does not have to make assumptions about
kernel's memory layout.
Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
Cc: Dirk Brandewie <dirk.brandewie-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Acked-by: Grant Likely <grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
---
arch/x86/include/asm/prom.h | 7 +++
arch/x86/kernel/devicetree.c | 111 +++++++++++++++++++++++++++++++++++++++++-
arch/x86/kernel/irqinit.c | 3 +-
3 files changed, 118 insertions(+), 3 deletions(-)
diff --git a/arch/x86/include/asm/prom.h b/arch/x86/include/asm/prom.h
index 70467d1..5aa2c32 100644
--- a/arch/x86/include/asm/prom.h
+++ b/arch/x86/include/asm/prom.h
@@ -22,10 +22,17 @@
#include <asm/irq_controller.h>
#ifdef CONFIG_OF
+extern int of_ioapic;
+extern u64 initial_dtb;
extern void add_dtb(u64 data);
+void x86_dtb_find_config(void);
+void x86_dtb_get_config(unsigned int unused);
void add_interrupt_host(struct irq_domain *ih);
#else
static inline void add_dtb(u64 data) { }
+#define x86_dtb_find_config x86_init_noop
+#define x86_dtb_get_config x86_init_uint_noop
+#define of_ioapic 0
#endif
extern char cmd_line[COMMAND_LINE_SIZE];
diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c
index f2f159c..72cc3e2 100644
--- a/arch/x86/kernel/devicetree.c
+++ b/arch/x86/kernel/devicetree.c
@@ -7,15 +7,20 @@
#include <linux/list.h>
#include <linux/of.h>
#include <linux/of_fdt.h>
+#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/slab.h>
#include <asm/irq_controller.h>
+#include <asm/apic.h>
+__initdata u64 initial_dtb;
char __initdata cmd_line[COMMAND_LINE_SIZE];
static LIST_HEAD(irq_domains);
static DEFINE_RAW_SPINLOCK(big_irq_lock);
+int __initdata of_ioapic;
+
void add_interrupt_host(struct irq_domain *ih)
{
unsigned long flags;
@@ -91,6 +96,108 @@ void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
void __init add_dtb(u64 data)
{
- initial_boot_params = phys_to_virt((u64) (u32) data +
- offsetof(struct setup_data, data));
+ initial_dtb = data + offsetof(struct setup_data, data);
+}
+
+static void __init dtb_lapic_setup(void)
+{
+#ifdef CONFIG_X86_LOCAL_APIC
+ if (apic_force_enable())
+ return;
+
+ smp_found_config = 1;
+ pic_mode = 1;
+ /* Required for ioapic registration */
+ set_fixmap_nocache(FIX_APIC_BASE, mp_lapic_addr);
+ if (boot_cpu_physical_apicid == -1U)
+ boot_cpu_physical_apicid = read_apic_id();
+
+ generic_processor_info(boot_cpu_physical_apicid,
+ GET_APIC_VERSION(apic_read(APIC_LVR)));
+#endif
+}
+
+#ifdef CONFIG_X86_IO_APIC
+static unsigned int ioapic_id;
+
+static void __init dtb_add_ioapic(struct device_node *dn)
+{
+ struct resource r;
+ int ret;
+
+ ret = of_address_to_resource(dn, 0, &r);
+ if (ret) {
+ printk(KERN_ERR "Can't obtain address from node %s.\n",
+ dn->full_name);
+ return;
+ }
+ mp_register_ioapic(++ioapic_id, r.start, gsi_top);
+}
+
+static void __init dtb_ioapic_setup(void)
+{
+ struct device_node *dn;
+
+ if (!smp_found_config)
+ return;
+
+ for_each_compatible_node(dn, NULL, "intel,ce4100-ioapic")
+ dtb_add_ioapic(dn);
+
+ if (nr_ioapics) {
+ of_ioapic = 1;
+ return;
+ }
+ printk(KERN_ERR "Error: No information about IO-APIC in OF.\n");
+ smp_found_config = 0;
+}
+#else
+static void __init dtb_ioapic_setup(void) {}
+#endif
+
+static void __init dtb_apic_setup(void)
+{
+ dtb_lapic_setup();
+ dtb_ioapic_setup();
+}
+
+void __init x86_dtb_find_config(void)
+{
+ if (initial_dtb)
+ smp_found_config = 1;
+ else
+ printk(KERN_ERR "Missing device tree!.\n");
+}
+
+void __init x86_dtb_get_config(unsigned int unused)
+{
+ u32 size;
+ u32 map_len;
+ void *new_dtb;
+
+ if (!initial_dtb)
+ return;
+
+ map_len = max(PAGE_SIZE - (initial_dtb & ~PAGE_MASK),
+ (u64)sizeof(struct boot_param_header));
+
+ initial_boot_params = early_memremap(initial_dtb, map_len);
+ size = be32_to_cpu(initial_boot_params->totalsize);
+ if (map_len < size) {
+ early_iounmap(initial_boot_params, map_len);
+ initial_boot_params = early_memremap(initial_dtb, size);
+ map_len = size;
+ }
+
+ new_dtb = alloc_bootmem(size);
+ memcpy(new_dtb, initial_boot_params, size);
+ early_iounmap(initial_boot_params, map_len);
+
+ initial_boot_params = new_dtb;
+
+ /* root level address cells */
+ of_scan_flat_dt(early_init_dt_scan_root, NULL);
+
+ unflatten_device_tree();
+ dtb_apic_setup();
}
diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c
index c752e97..4cadf86 100644
--- a/arch/x86/kernel/irqinit.c
+++ b/arch/x86/kernel/irqinit.c
@@ -25,6 +25,7 @@
#include <asm/setup.h>
#include <asm/i8259.h>
#include <asm/traps.h>
+#include <asm/prom.h>
/*
* ISA PIC or low IO-APIC triggered (INTA-cycle or APIC) interrupts:
@@ -243,7 +244,7 @@ void __init native_init_IRQ(void)
set_intr_gate(i, interrupt[i-FIRST_EXTERNAL_VECTOR]);
}
- if (!acpi_ioapic)
+ if (!acpi_ioapic && !of_ioapic)
setup_irq(2, &irq2);
#ifdef CONFIG_X86_32
--
1.7.4
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 06/11] x86/dtb: add support hpet
[not found] ` <1298405266-1624-1-git-send-email-bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
` (3 preceding siblings ...)
2011-02-22 20:07 ` [PATCH 05/11] x86/dtb: add early parsing of IO APIC Sebastian Andrzej Siewior
@ 2011-02-22 20:07 ` Sebastian Andrzej Siewior
2011-02-22 20:07 ` [PATCH 07/11] x86/dtb: add support for PCI devices backed by dtb nodes Sebastian Andrzej Siewior
` (4 subsequent siblings)
9 siblings, 0 replies; 23+ messages in thread
From: Sebastian Andrzej Siewior @ 2011-02-22 20:07 UTC (permalink / raw)
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
Cc: sodaville-hfZtesqFncYOwBW4kG4KsQ,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
x86-DgEjT+Ai2ygdnm+yROfE0A, Sebastian Andrzej Siewior
Set hpet_address based on information provied form DTB
Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
Cc: Dirk Brandewie <dirk.brandewie-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Acked-by: Grant Likely <grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
---
arch/x86/kernel/devicetree.c | 19 +++++++++++++++++++
1 files changed, 19 insertions(+), 0 deletions(-)
diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c
index 72cc3e2..8d7a2eb 100644
--- a/arch/x86/kernel/devicetree.c
+++ b/arch/x86/kernel/devicetree.c
@@ -11,6 +11,7 @@
#include <linux/of_platform.h>
#include <linux/slab.h>
+#include <asm/hpet.h>
#include <asm/irq_controller.h>
#include <asm/apic.h>
@@ -99,6 +100,23 @@ void __init add_dtb(u64 data)
initial_dtb = data + offsetof(struct setup_data, data);
}
+static void __init dtb_setup_hpet(void)
+{
+ struct device_node *dn;
+ struct resource r;
+ int ret;
+
+ dn = of_find_compatible_node(NULL, NULL, "intel,ce4100-hpet");
+ if (!dn)
+ return;
+ ret = of_address_to_resource(dn, 0, &r);
+ if (ret) {
+ WARN_ON(1);
+ return;
+ }
+ hpet_address = r.start;
+}
+
static void __init dtb_lapic_setup(void)
{
#ifdef CONFIG_X86_LOCAL_APIC
@@ -199,5 +217,6 @@ void __init x86_dtb_get_config(unsigned int unused)
of_scan_flat_dt(early_init_dt_scan_root, NULL);
unflatten_device_tree();
+ dtb_setup_hpet();
dtb_apic_setup();
}
--
1.7.4
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 07/11] x86/dtb: add support for PCI devices backed by dtb nodes
[not found] ` <1298405266-1624-1-git-send-email-bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
` (4 preceding siblings ...)
2011-02-22 20:07 ` [PATCH 06/11] x86/dtb: add support hpet Sebastian Andrzej Siewior
@ 2011-02-22 20:07 ` Sebastian Andrzej Siewior
2011-02-22 21:08 ` Grant Likely
2011-02-22 20:07 ` [PATCH 08/11] x86/dtb: Add generic bus probe Sebastian Andrzej Siewior
` (3 subsequent siblings)
9 siblings, 1 reply; 23+ messages in thread
From: Sebastian Andrzej Siewior @ 2011-02-22 20:07 UTC (permalink / raw)
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
Cc: sodaville-hfZtesqFncYOwBW4kG4KsQ,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
x86-DgEjT+Ai2ygdnm+yROfE0A, Sebastian Andrzej Siewior
x86_of_pci_init() does two things:
- it provides a generic irq enable and disable function. enable queries
the device tree for the interrupt information, calls ->xlate on the
irq host and updates the pci->irq information for the device.
- it walks through PCI buss(es) in the device tree and adds its children
(devices) nodes to appropriate pci_dev nodes in kernel. So the dtb
node information is available at probe time of the PCI device.
Adding a PCI bus based on the information in the device tree is
currently not supported. Right now direct access via ioports is used.
Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
Tested-by: Dirk Brandewie <dirk.brandewie-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
---
arch/x86/include/asm/prom.h | 14 +++++++
arch/x86/kernel/devicetree.c | 83 ++++++++++++++++++++++++++++++++++++++++++
drivers/of/Kconfig | 2 +-
drivers/of/of_pci.c | 1 +
4 files changed, 99 insertions(+), 1 deletions(-)
diff --git a/arch/x86/include/asm/prom.h b/arch/x86/include/asm/prom.h
index 5aa2c32..3e441b3 100644
--- a/arch/x86/include/asm/prom.h
+++ b/arch/x86/include/asm/prom.h
@@ -16,6 +16,7 @@
#include <linux/of.h>
#include <linux/types.h>
+#include <linux/pci.h>
#include <asm/irq.h>
#include <asm/atomic.h>
#include <asm/setup.h>
@@ -28,8 +29,21 @@ extern void add_dtb(u64 data);
void x86_dtb_find_config(void);
void x86_dtb_get_config(unsigned int unused);
void add_interrupt_host(struct irq_domain *ih);
+void __cpuinit x86_of_pci_init(void);
+
+static inline struct device_node *pci_device_to_OF_node(struct pci_dev *pdev)
+{
+ return pdev ? pdev->dev.of_node : NULL;
+}
+
+static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
+{
+ return pci_device_to_OF_node(bus->self);
+}
+
#else
static inline void add_dtb(u64 data) { }
+static inline void x86_of_pci_init(void) { }
#define x86_dtb_find_config x86_init_noop
#define x86_dtb_get_config x86_init_uint_noop
#define of_ioapic 0
diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c
index 8d7a2eb..b778ae5 100644
--- a/arch/x86/kernel/devicetree.c
+++ b/arch/x86/kernel/devicetree.c
@@ -9,11 +9,15 @@
#include <linux/of_fdt.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
+#include <linux/of_irq.h>
#include <linux/slab.h>
+#include <linux/pci.h>
+#include <linux/of_pci.h>
#include <asm/hpet.h>
#include <asm/irq_controller.h>
#include <asm/apic.h>
+#include <asm/pci_x86.h>
__initdata u64 initial_dtb;
char __initdata cmd_line[COMMAND_LINE_SIZE];
@@ -100,6 +104,85 @@ void __init add_dtb(u64 data)
initial_dtb = data + offsetof(struct setup_data, data);
}
+#ifdef CONFIG_PCI
+static int x86_of_pci_irq_enable(struct pci_dev *dev)
+{
+ struct of_irq oirq;
+ u32 virq;
+ int ret;
+ u8 pin;
+
+ ret = pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+ if (ret)
+ return ret;
+ if (!pin)
+ return 0;
+
+ ret = of_irq_map_pci(dev, &oirq);
+ if (ret)
+ return ret;
+
+ virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
+ oirq.size);
+ if (virq == 0)
+ return -EINVAL;
+ dev->irq = virq;
+ return 0;
+}
+
+static void x86_of_pci_irq_disable(struct pci_dev *dev)
+{
+}
+
+void __cpuinit x86_of_pci_init(void)
+{
+ struct device_node *np;
+
+ pcibios_enable_irq = x86_of_pci_irq_enable;
+ pcibios_disable_irq = x86_of_pci_irq_disable;
+
+ for_each_node_by_type(np, "pci") {
+ const void *prop;
+ struct pci_bus *bus;
+ unsigned int bus_min;
+ struct device_node *child;
+
+ prop = of_get_property(np, "bus-range", NULL);
+ if (!prop)
+ continue;
+ bus_min = be32_to_cpup(prop);
+
+ bus = pci_find_bus(0, bus_min);
+ if (!bus) {
+ printk(KERN_ERR "Can't find a node for bus %s.\n",
+ np->full_name);
+ continue;
+ }
+
+ if (bus->self)
+ bus->self->dev.of_node = np;
+ else
+ bus->dev.of_node = np;
+
+ for_each_child_of_node(np, child) {
+ struct pci_dev *dev;
+ u32 devfn;
+
+ prop = of_get_property(child, "reg", NULL);
+ if (!prop)
+ continue;
+
+ devfn = (be32_to_cpup(prop) >> 8) & 0xff;
+ dev = pci_get_slot(bus, devfn);
+ if (!dev)
+ continue;
+ dev->dev.of_node = child;
+ pci_dev_put(dev);
+ }
+ }
+}
+#endif
+
static void __init dtb_setup_hpet(void)
{
struct device_node *dn;
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index efabbf9..d06a637 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -71,7 +71,7 @@ config OF_MDIO
config OF_PCI
def_tristate PCI
- depends on PCI && (PPC || MICROBLAZE)
+ depends on PCI && (PPC || MICROBLAZE || X86)
help
OpenFirmware PCI bus accessors
diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
index 314535f..ac1ec54 100644
--- a/drivers/of/of_pci.c
+++ b/drivers/of/of_pci.c
@@ -1,5 +1,6 @@
#include <linux/kernel.h>
#include <linux/of_pci.h>
+#include <linux/of_irq.h>
#include <asm/prom.h>
/**
--
1.7.4
^ permalink raw reply related [flat|nested] 23+ messages in thread* Re: [PATCH 07/11] x86/dtb: add support for PCI devices backed by dtb nodes
2011-02-22 20:07 ` [PATCH 07/11] x86/dtb: add support for PCI devices backed by dtb nodes Sebastian Andrzej Siewior
@ 2011-02-22 21:08 ` Grant Likely
0 siblings, 0 replies; 23+ messages in thread
From: Grant Likely @ 2011-02-22 21:08 UTC (permalink / raw)
To: Sebastian Andrzej Siewior
Cc: linux-kernel, sodaville, devicetree-discuss, x86
On Tue, Feb 22, 2011 at 1:07 PM, Sebastian Andrzej Siewior
<bigeasy@linutronix.de> wrote:
> x86_of_pci_init() does two things:
> - it provides a generic irq enable and disable function. enable queries
> the device tree for the interrupt information, calls ->xlate on the
> irq host and updates the pci->irq information for the device.
>
> - it walks through PCI buss(es) in the device tree and adds its children
> (devices) nodes to appropriate pci_dev nodes in kernel. So the dtb
> node information is available at probe time of the PCI device.
>
> Adding a PCI bus based on the information in the device tree is
> currently not supported. Right now direct access via ioports is used.
>
> Cc: devicetree-discuss@lists.ozlabs.org
> Tested-by: Dirk Brandewie <dirk.brandewie@gmail.com>
> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Acked-by: Grant Likely <grant.likely@secretlab.ca>
> ---
> arch/x86/include/asm/prom.h | 14 +++++++
> arch/x86/kernel/devicetree.c | 83 ++++++++++++++++++++++++++++++++++++++++++
> drivers/of/Kconfig | 2 +-
> drivers/of/of_pci.c | 1 +
> 4 files changed, 99 insertions(+), 1 deletions(-)
>
> diff --git a/arch/x86/include/asm/prom.h b/arch/x86/include/asm/prom.h
> index 5aa2c32..3e441b3 100644
> --- a/arch/x86/include/asm/prom.h
> +++ b/arch/x86/include/asm/prom.h
> @@ -16,6 +16,7 @@
>
> #include <linux/of.h>
> #include <linux/types.h>
> +#include <linux/pci.h>
> #include <asm/irq.h>
> #include <asm/atomic.h>
> #include <asm/setup.h>
> @@ -28,8 +29,21 @@ extern void add_dtb(u64 data);
> void x86_dtb_find_config(void);
> void x86_dtb_get_config(unsigned int unused);
> void add_interrupt_host(struct irq_domain *ih);
> +void __cpuinit x86_of_pci_init(void);
> +
> +static inline struct device_node *pci_device_to_OF_node(struct pci_dev *pdev)
> +{
> + return pdev ? pdev->dev.of_node : NULL;
> +}
> +
> +static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
> +{
> + return pci_device_to_OF_node(bus->self);
> +}
> +
> #else
> static inline void add_dtb(u64 data) { }
> +static inline void x86_of_pci_init(void) { }
> #define x86_dtb_find_config x86_init_noop
> #define x86_dtb_get_config x86_init_uint_noop
> #define of_ioapic 0
> diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c
> index 8d7a2eb..b778ae5 100644
> --- a/arch/x86/kernel/devicetree.c
> +++ b/arch/x86/kernel/devicetree.c
> @@ -9,11 +9,15 @@
> #include <linux/of_fdt.h>
> #include <linux/of_address.h>
> #include <linux/of_platform.h>
> +#include <linux/of_irq.h>
> #include <linux/slab.h>
> +#include <linux/pci.h>
> +#include <linux/of_pci.h>
>
> #include <asm/hpet.h>
> #include <asm/irq_controller.h>
> #include <asm/apic.h>
> +#include <asm/pci_x86.h>
>
> __initdata u64 initial_dtb;
> char __initdata cmd_line[COMMAND_LINE_SIZE];
> @@ -100,6 +104,85 @@ void __init add_dtb(u64 data)
> initial_dtb = data + offsetof(struct setup_data, data);
> }
>
> +#ifdef CONFIG_PCI
> +static int x86_of_pci_irq_enable(struct pci_dev *dev)
> +{
> + struct of_irq oirq;
> + u32 virq;
> + int ret;
> + u8 pin;
> +
> + ret = pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
> + if (ret)
> + return ret;
> + if (!pin)
> + return 0;
> +
> + ret = of_irq_map_pci(dev, &oirq);
> + if (ret)
> + return ret;
> +
> + virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
> + oirq.size);
> + if (virq == 0)
> + return -EINVAL;
> + dev->irq = virq;
> + return 0;
> +}
> +
> +static void x86_of_pci_irq_disable(struct pci_dev *dev)
> +{
> +}
> +
> +void __cpuinit x86_of_pci_init(void)
> +{
> + struct device_node *np;
> +
> + pcibios_enable_irq = x86_of_pci_irq_enable;
> + pcibios_disable_irq = x86_of_pci_irq_disable;
> +
> + for_each_node_by_type(np, "pci") {
> + const void *prop;
> + struct pci_bus *bus;
> + unsigned int bus_min;
> + struct device_node *child;
> +
> + prop = of_get_property(np, "bus-range", NULL);
> + if (!prop)
> + continue;
> + bus_min = be32_to_cpup(prop);
> +
> + bus = pci_find_bus(0, bus_min);
> + if (!bus) {
> + printk(KERN_ERR "Can't find a node for bus %s.\n",
> + np->full_name);
> + continue;
> + }
> +
> + if (bus->self)
> + bus->self->dev.of_node = np;
> + else
> + bus->dev.of_node = np;
> +
> + for_each_child_of_node(np, child) {
> + struct pci_dev *dev;
> + u32 devfn;
> +
> + prop = of_get_property(child, "reg", NULL);
> + if (!prop)
> + continue;
> +
> + devfn = (be32_to_cpup(prop) >> 8) & 0xff;
> + dev = pci_get_slot(bus, devfn);
> + if (!dev)
> + continue;
> + dev->dev.of_node = child;
> + pci_dev_put(dev);
> + }
> + }
> +}
> +#endif
> +
> static void __init dtb_setup_hpet(void)
> {
> struct device_node *dn;
> diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
> index efabbf9..d06a637 100644
> --- a/drivers/of/Kconfig
> +++ b/drivers/of/Kconfig
> @@ -71,7 +71,7 @@ config OF_MDIO
>
> config OF_PCI
> def_tristate PCI
> - depends on PCI && (PPC || MICROBLAZE)
> + depends on PCI && (PPC || MICROBLAZE || X86)
> help
> OpenFirmware PCI bus accessors
>
> diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
> index 314535f..ac1ec54 100644
> --- a/drivers/of/of_pci.c
> +++ b/drivers/of/of_pci.c
> @@ -1,5 +1,6 @@
> #include <linux/kernel.h>
> #include <linux/of_pci.h>
> +#include <linux/of_irq.h>
> #include <asm/prom.h>
>
> /**
> --
> 1.7.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH 08/11] x86/dtb: Add generic bus probe
[not found] ` <1298405266-1624-1-git-send-email-bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
` (5 preceding siblings ...)
2011-02-22 20:07 ` [PATCH 07/11] x86/dtb: add support for PCI devices backed by dtb nodes Sebastian Andrzej Siewior
@ 2011-02-22 20:07 ` Sebastian Andrzej Siewior
2011-02-22 20:07 ` [PATCH 09/11] x86/ioapic: Add OF bindings for IO-APIC Sebastian Andrzej Siewior
` (2 subsequent siblings)
9 siblings, 0 replies; 23+ messages in thread
From: Sebastian Andrzej Siewior @ 2011-02-22 20:07 UTC (permalink / raw)
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
Cc: sodaville-hfZtesqFncYOwBW4kG4KsQ,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
x86-DgEjT+Ai2ygdnm+yROfE0A, Sebastian Andrzej Siewior
For now we probe these busses and we change is to board dependent probes
once we have to.
Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
Acked-by: Grant Likely <grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
Signed-off-by: Dirk Brandewie <dirk.brandewie-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
arch/x86/kernel/devicetree.c | 19 +++++++++++++++++++
1 files changed, 19 insertions(+), 0 deletions(-)
diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c
index b778ae5..179833f 100644
--- a/arch/x86/kernel/devicetree.c
+++ b/arch/x86/kernel/devicetree.c
@@ -104,6 +104,25 @@ void __init add_dtb(u64 data)
initial_dtb = data + offsetof(struct setup_data, data);
}
+/*
+ * CE4100 ids. Will be moved to machine_device_initcall() once we have it.
+ */
+static struct of_device_id __initdata ce4100_ids[] = {
+ { .compatible = "intel,ce4100-cp", },
+ { .compatible = "isa", },
+ { .compatible = "pci", },
+ {},
+};
+
+static int __init add_bus_probe(void)
+{
+ if (!initial_boot_params)
+ return 0;
+
+ return of_platform_bus_probe(NULL, ce4100_ids, NULL);
+}
+module_init(add_bus_probe);
+
#ifdef CONFIG_PCI
static int x86_of_pci_irq_enable(struct pci_dev *dev)
{
--
1.7.4
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 09/11] x86/ioapic: Add OF bindings for IO-APIC
[not found] ` <1298405266-1624-1-git-send-email-bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
` (6 preceding siblings ...)
2011-02-22 20:07 ` [PATCH 08/11] x86/dtb: Add generic bus probe Sebastian Andrzej Siewior
@ 2011-02-22 20:07 ` Sebastian Andrzej Siewior
2011-02-22 21:14 ` Grant Likely
2011-02-22 20:07 ` [PATCH 10/11] x86/ce4100: use OF for ioapic Sebastian Andrzej Siewior
2011-02-22 20:07 ` [PATCH 11/11] rtc/cmos: add OF bindings Sebastian Andrzej Siewior
9 siblings, 1 reply; 23+ messages in thread
From: Sebastian Andrzej Siewior @ 2011-02-22 20:07 UTC (permalink / raw)
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
Cc: sodaville-hfZtesqFncYOwBW4kG4KsQ,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
x86-DgEjT+Ai2ygdnm+yROfE0A, Sebastian Andrzej Siewior
ioapic_xlate provides a translation from the information in device tree
to ioapic related informations. This includes
- obtaining hw irq which is the vector number "=> pin number + gsi"
- obtaining type (level/edge/..)
- programming this information into ioapic
ioapic_add_ofnode adds an irq_domain based on informations from the device
tree. This information (irq_domain) is required in order to map a device to
its proper interrupt controller.
Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
Signed-off-by: Sebastian Andrzej Siewior <bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
Signed-off-by: Dirk Brandewie <dirk.brandewie-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
arch/x86/include/asm/io_apic.h | 7 +++
arch/x86/include/asm/prom.h | 2 +
arch/x86/kernel/apic/io_apic.c | 99 ++++++++++++++++++++++++++++++++++++++++
arch/x86/kernel/devicetree.c | 13 +++++
arch/x86/kernel/irqinit.c | 6 ++
5 files changed, 127 insertions(+), 0 deletions(-)
diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index f327d38..fe88a73 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -177,6 +177,13 @@ struct mp_ioapic_gsi{
u32 gsi_base;
u32 gsi_end;
};
+#ifdef CONFIG_OF
+struct mp_of_ioapic {
+ struct device_node *node;
+};
+extern struct mp_of_ioapic mp_of_ioapic[MAX_IO_APICS];
+void __init ioapic_add_ofnode(struct device_node *np);
+#endif
extern struct mp_ioapic_gsi mp_gsi_routing[];
extern u32 gsi_top;
int mp_find_ioapic(u32 gsi);
diff --git a/arch/x86/include/asm/prom.h b/arch/x86/include/asm/prom.h
index 3e441b3..98b9a73 100644
--- a/arch/x86/include/asm/prom.h
+++ b/arch/x86/include/asm/prom.h
@@ -26,6 +26,7 @@
extern int of_ioapic;
extern u64 initial_dtb;
extern void add_dtb(u64 data);
+extern void x86_add_irq_domains(void);
void x86_dtb_find_config(void);
void x86_dtb_get_config(unsigned int unused);
void add_interrupt_host(struct irq_domain *ih);
@@ -43,6 +44,7 @@ static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
#else
static inline void add_dtb(u64 data) { }
+static inline void x86_add_irq_domains(void) { }
static inline void x86_of_pci_init(void) { }
#define x86_dtb_find_config x86_init_noop
#define x86_dtb_get_config x86_init_uint_noop
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index ca9e2a3..c172452 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -43,6 +43,7 @@
#include <linux/bootmem.h>
#include <linux/dmar.h>
#include <linux/hpet.h>
+#include <linux/of_address.h>
#include <asm/idle.h>
#include <asm/io.h>
@@ -60,6 +61,7 @@
#include <asm/irq_remapping.h>
#include <asm/hpet.h>
#include <asm/hw_irq.h>
+#include <asm/irq_controller.h>
#include <asm/apic.h>
@@ -88,6 +90,10 @@ int nr_ioapics;
/* IO APIC gsi routing info */
struct mp_ioapic_gsi mp_gsi_routing[MAX_IO_APICS];
+#ifdef CONFIG_OF
+/* OF -> IO APIC lookup */
+struct mp_of_ioapic mp_of_ioapic[MAX_IO_APICS];
+#endif
/* The one past the highest gsi number used */
u32 gsi_top;
@@ -4083,6 +4089,99 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
nr_ioapics++;
}
+#ifdef CONFIG_OF
+static int ioapic_xlate(struct irq_domain *id, const u32 *intspec, u32 intsize,
+ u32 *out_hwirq, u32 *out_type)
+{
+ u32 line;
+ u32 idx;
+ u32 type;
+ u32 trigger;
+ u32 polarity;
+ struct irq_cfg *cfg;
+ struct irq_desc *desc;
+
+ if (intsize < 1)
+ return -EINVAL;
+
+ line = *intspec;
+ idx = (u32) id->priv;
+ *out_hwirq = line + mp_gsi_routing[idx].gsi_base;
+ if (intsize > 1) {
+ intspec++;
+ type = *intspec;
+ switch (type) {
+ case 0:
+ *out_type = IRQ_TYPE_EDGE_RISING;
+ trigger = IOAPIC_EDGE;
+ polarity = 1;
+ break;
+ case 1:
+ *out_type = IRQ_TYPE_LEVEL_LOW;
+ trigger = IOAPIC_LEVEL;
+ polarity = 0;
+ break;
+ case 2:
+ *out_type = IRQ_TYPE_LEVEL_HIGH;
+ trigger = IOAPIC_LEVEL;
+ polarity = 1;
+ break;
+ case 3:
+ *out_type = IRQ_TYPE_EDGE_FALLING;
+ trigger = IOAPIC_EDGE;
+ polarity = 0;
+ break;
+ default:
+ *out_type = IRQ_TYPE_NONE;
+ trigger = IOAPIC_AUTO;
+ polarity = 0;
+ break;
+ };
+ } else {
+ *out_type = IRQ_TYPE_NONE;
+ trigger = IOAPIC_AUTO;
+ polarity = 0;
+ }
+ /* And now tell the IO APIC to make the line ready */
+ desc = irq_to_desc_alloc_node(*out_hwirq, 0);
+ cfg = irq_cfg(*out_hwirq);
+ add_pin_to_irq_node(cfg, 0, idx, line);
+ /* make it edge by default, settype will update it */
+ setup_ioapic_irq(idx, line, *out_hwirq, cfg, trigger, polarity);
+ return 0;
+}
+
+void __init ioapic_add_ofnode(struct device_node *np)
+{
+ int i;
+ int ret;
+ struct resource r;
+
+ ret = of_address_to_resource(np, 0, &r);
+ if (ret) {
+ printk(KERN_ERR "Failed to obtain address for %s\n",
+ np->full_name);
+ return;
+ }
+
+ for (i = 0; i < nr_ioapics; i++) {
+ if (r.start == mp_ioapics[i].apicaddr) {
+ struct irq_domain *id;
+
+ mp_of_ioapic[i].node = np;
+ id = kzalloc(sizeof(*id), GFP_KERNEL);
+ BUG_ON(!id);
+ id->controller = np;
+ id->xlate = ioapic_xlate;
+ id->priv = (void *)i;
+ add_interrupt_host(id);
+ return;
+ }
+ }
+ printk(KERN_ERR "IOxAPIC at %s is not registered.\n", np->full_name);
+}
+#endif
+
/* Enable IOAPIC early just for system timer */
void __init pre_init_apic_IRQ0(void)
{
diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c
index 179833f..62d0072 100644
--- a/arch/x86/kernel/devicetree.c
+++ b/arch/x86/kernel/devicetree.c
@@ -322,3 +322,16 @@ void __init x86_dtb_get_config(unsigned int unused)
dtb_setup_hpet();
dtb_apic_setup();
}
+
+void __init x86_add_irq_domains(void)
+{
+ struct device_node *dp;
+
+ if (!initial_boot_params)
+ return;
+
+ for_each_node_with_property(dp, "interrupt-controller") {
+ if (of_device_is_compatible(dp, "intel,ce4100-ioapic"))
+ ioapic_add_ofnode(dp);
+ }
+}
diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c
index 4cadf86..9f76f89 100644
--- a/arch/x86/kernel/irqinit.c
+++ b/arch/x86/kernel/irqinit.c
@@ -119,6 +119,12 @@ void __init init_IRQ(void)
int i;
/*
+ * We probably need a better place for this, but it works for
+ * now ...
+ */
+ x86_add_irq_domains();
+
+ /*
* On cpu 0, Assign IRQ0_VECTOR..IRQ15_VECTOR's to IRQ 0..15.
* If these IRQ's are handled by legacy interrupt-controllers like PIC,
* then this configuration will likely be static after the boot. If
--
1.7.4
^ permalink raw reply related [flat|nested] 23+ messages in thread* Re: [PATCH 09/11] x86/ioapic: Add OF bindings for IO-APIC
2011-02-22 20:07 ` [PATCH 09/11] x86/ioapic: Add OF bindings for IO-APIC Sebastian Andrzej Siewior
@ 2011-02-22 21:14 ` Grant Likely
0 siblings, 0 replies; 23+ messages in thread
From: Grant Likely @ 2011-02-22 21:14 UTC (permalink / raw)
To: Sebastian Andrzej Siewior
Cc: linux-kernel, sodaville, devicetree-discuss, x86, Dirk Brandewie
On Tue, Feb 22, 2011 at 1:07 PM, Sebastian Andrzej Siewior
<bigeasy@linutronix.de> wrote:
> ioapic_xlate provides a translation from the information in device tree
> to ioapic related informations. This includes
> - obtaining hw irq which is the vector number "=> pin number + gsi"
> - obtaining type (level/edge/..)
> - programming this information into ioapic
>
> ioapic_add_ofnode adds an irq_domain based on informations from the device
> tree. This information (irq_domain) is required in order to map a device to
> its proper interrupt controller.
>
> Cc: devicetree-discuss@lists.ozlabs.org
> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> Signed-off-by: Dirk Brandewie <dirk.brandewie@gmail.com>
> ---
> arch/x86/include/asm/io_apic.h | 7 +++
> arch/x86/include/asm/prom.h | 2 +
> arch/x86/kernel/apic/io_apic.c | 99 ++++++++++++++++++++++++++++++++++++++++
> arch/x86/kernel/devicetree.c | 13 +++++
> arch/x86/kernel/irqinit.c | 6 ++
> 5 files changed, 127 insertions(+), 0 deletions(-)
>
> diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
> index f327d38..fe88a73 100644
> --- a/arch/x86/include/asm/io_apic.h
> +++ b/arch/x86/include/asm/io_apic.h
> @@ -177,6 +177,13 @@ struct mp_ioapic_gsi{
> u32 gsi_base;
> u32 gsi_end;
> };
> +#ifdef CONFIG_OF
> +struct mp_of_ioapic {
> + struct device_node *node;
> +};
> +extern struct mp_of_ioapic mp_of_ioapic[MAX_IO_APICS];
> +void __init ioapic_add_ofnode(struct device_node *np);
> +#endif
> extern struct mp_ioapic_gsi mp_gsi_routing[];
> extern u32 gsi_top;
> int mp_find_ioapic(u32 gsi);
> diff --git a/arch/x86/include/asm/prom.h b/arch/x86/include/asm/prom.h
> index 3e441b3..98b9a73 100644
> --- a/arch/x86/include/asm/prom.h
> +++ b/arch/x86/include/asm/prom.h
> @@ -26,6 +26,7 @@
> extern int of_ioapic;
> extern u64 initial_dtb;
> extern void add_dtb(u64 data);
> +extern void x86_add_irq_domains(void);
> void x86_dtb_find_config(void);
> void x86_dtb_get_config(unsigned int unused);
> void add_interrupt_host(struct irq_domain *ih);
> @@ -43,6 +44,7 @@ static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
>
> #else
> static inline void add_dtb(u64 data) { }
> +static inline void x86_add_irq_domains(void) { }
> static inline void x86_of_pci_init(void) { }
> #define x86_dtb_find_config x86_init_noop
> #define x86_dtb_get_config x86_init_uint_noop
> diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
> index ca9e2a3..c172452 100644
> --- a/arch/x86/kernel/apic/io_apic.c
> +++ b/arch/x86/kernel/apic/io_apic.c
> @@ -43,6 +43,7 @@
> #include <linux/bootmem.h>
> #include <linux/dmar.h>
> #include <linux/hpet.h>
> +#include <linux/of_address.h>
>
> #include <asm/idle.h>
> #include <asm/io.h>
> @@ -60,6 +61,7 @@
> #include <asm/irq_remapping.h>
> #include <asm/hpet.h>
> #include <asm/hw_irq.h>
> +#include <asm/irq_controller.h>
>
> #include <asm/apic.h>
>
> @@ -88,6 +90,10 @@ int nr_ioapics;
> /* IO APIC gsi routing info */
> struct mp_ioapic_gsi mp_gsi_routing[MAX_IO_APICS];
>
> +#ifdef CONFIG_OF
> +/* OF -> IO APIC lookup */
> +struct mp_of_ioapic mp_of_ioapic[MAX_IO_APICS];
> +#endif
> /* The one past the highest gsi number used */
> u32 gsi_top;
>
> @@ -4083,6 +4089,99 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
> nr_ioapics++;
> }
>
> +#ifdef CONFIG_OF
> +static int ioapic_xlate(struct irq_domain *id, const u32 *intspec, u32 intsize,
> + u32 *out_hwirq, u32 *out_type)
> +{
> + u32 line;
> + u32 idx;
> + u32 type;
> + u32 trigger;
> + u32 polarity;
> + struct irq_cfg *cfg;
> + struct irq_desc *desc;
> +
> + if (intsize < 1)
> + return -EINVAL;
> +
> + line = *intspec;
> + idx = (u32) id->priv;
> + *out_hwirq = line + mp_gsi_routing[idx].gsi_base;
> + if (intsize > 1) {
> + intspec++;
> + type = *intspec;
> + switch (type) {
> + case 0:
> + *out_type = IRQ_TYPE_EDGE_RISING;
> + trigger = IOAPIC_EDGE;
> + polarity = 1;
> + break;
> + case 1:
> + *out_type = IRQ_TYPE_LEVEL_LOW;
> + trigger = IOAPIC_LEVEL;
> + polarity = 0;
> + break;
> + case 2:
> + *out_type = IRQ_TYPE_LEVEL_HIGH;
> + trigger = IOAPIC_LEVEL;
> + polarity = 1;
> + break;
> + case 3:
> + *out_type = IRQ_TYPE_EDGE_FALLING;
> + trigger = IOAPIC_EDGE;
> + polarity = 0;
> + break;
This seems to beg for a lookup table. :-)
But that can be changed later if you agree.
> + default:
> + *out_type = IRQ_TYPE_NONE;
> + trigger = IOAPIC_AUTO;
> + polarity = 0;
> + break;
> + };
> + } else {
> + *out_type = IRQ_TYPE_NONE;
> + trigger = IOAPIC_AUTO;
> + polarity = 0;
> + }
Actually, if the irq specifier is invalid (both for the default case,
and the case where the size is too small), then this function should
flat out refuse to xlate the irq and complain loudly. Force users to
provide good data. Again, this can be fixed up with a followon patch.
> + /* And now tell the IO APIC to make the line ready */
> + desc = irq_to_desc_alloc_node(*out_hwirq, 0);
> + cfg = irq_cfg(*out_hwirq);
> + add_pin_to_irq_node(cfg, 0, idx, line);
> + /* make it edge by default, settype will update it */
> + setup_ioapic_irq(idx, line, *out_hwirq, cfg, trigger, polarity);
> + return 0;
> +}
> +
> +void __init ioapic_add_ofnode(struct device_node *np)
> +{
> + int i;
> + int ret;
> + struct resource r;
> +
> + ret = of_address_to_resource(np, 0, &r);
> + if (ret) {
> + printk(KERN_ERR "Failed to obtain address for %s\n",
> + np->full_name);
> + return;
> + }
> +
> + for (i = 0; i < nr_ioapics; i++) {
> + if (r.start == mp_ioapics[i].apicaddr) {
> + struct irq_domain *id;
> +
> + mp_of_ioapic[i].node = np;
> + id = kzalloc(sizeof(*id), GFP_KERNEL);
> + BUG_ON(!id);
> + id->controller = np;
> + id->xlate = ioapic_xlate;
> + id->priv = (void *)i;
> + add_interrupt_host(id);
> + return;
> + }
> + }
> + printk(KERN_ERR "IOxAPIC at %s is not registered.\n", np->full_name);
> +}
> +#endif
> +
> /* Enable IOAPIC early just for system timer */
> void __init pre_init_apic_IRQ0(void)
> {
> diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c
> index 179833f..62d0072 100644
> --- a/arch/x86/kernel/devicetree.c
> +++ b/arch/x86/kernel/devicetree.c
> @@ -322,3 +322,16 @@ void __init x86_dtb_get_config(unsigned int unused)
> dtb_setup_hpet();
> dtb_apic_setup();
> }
> +
> +void __init x86_add_irq_domains(void)
> +{
> + struct device_node *dp;
> +
> + if (!initial_boot_params)
> + return;
> +
> + for_each_node_with_property(dp, "interrupt-controller") {
> + if (of_device_is_compatible(dp, "intel,ce4100-ioapic"))
> + ioapic_add_ofnode(dp);
> + }
> +}
> diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c
> index 4cadf86..9f76f89 100644
> --- a/arch/x86/kernel/irqinit.c
> +++ b/arch/x86/kernel/irqinit.c
> @@ -119,6 +119,12 @@ void __init init_IRQ(void)
> int i;
>
> /*
> + * We probably need a better place for this, but it works for
> + * now ...
> + */
> + x86_add_irq_domains();
> +
> + /*
> * On cpu 0, Assign IRQ0_VECTOR..IRQ15_VECTOR's to IRQ 0..15.
> * If these IRQ's are handled by legacy interrupt-controllers like PIC,
> * then this configuration will likely be static after the boot. If
> --
> 1.7.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH 10/11] x86/ce4100: use OF for ioapic
[not found] ` <1298405266-1624-1-git-send-email-bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
` (7 preceding siblings ...)
2011-02-22 20:07 ` [PATCH 09/11] x86/ioapic: Add OF bindings for IO-APIC Sebastian Andrzej Siewior
@ 2011-02-22 20:07 ` Sebastian Andrzej Siewior
2011-02-22 20:07 ` [PATCH 11/11] rtc/cmos: add OF bindings Sebastian Andrzej Siewior
9 siblings, 0 replies; 23+ messages in thread
From: Sebastian Andrzej Siewior @ 2011-02-22 20:07 UTC (permalink / raw)
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
Cc: sodaville-hfZtesqFncYOwBW4kG4KsQ,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
x86-DgEjT+Ai2ygdnm+yROfE0A, Sebastian Andrzej Siewior
and hpet and a few others things....
Signed-off-by: Dirk Brandewie <dirk.brandewie-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Acked-by: Grant Likely <grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
---
arch/x86/platform/ce4100/ce4100.c | 24 +++++++++++++++++-------
1 files changed, 17 insertions(+), 7 deletions(-)
diff --git a/arch/x86/platform/ce4100/ce4100.c b/arch/x86/platform/ce4100/ce4100.c
index d2c0d51..7877453 100644
--- a/arch/x86/platform/ce4100/ce4100.c
+++ b/arch/x86/platform/ce4100/ce4100.c
@@ -15,21 +15,19 @@
#include <linux/serial_reg.h>
#include <linux/serial_8250.h>
+#include <asm/prom.h>
#include <asm/setup.h>
+#include <asm/i8259.h>
#include <asm/io.h>
+#include <asm/io_apic.h>
static int ce4100_i8042_detect(void)
{
return 0;
}
-static void __init sdv_find_smp_config(void)
-{
-}
-
#ifdef CONFIG_SERIAL_8250
-
static unsigned int mem_serial_in(struct uart_port *p, int offset)
{
offset = offset << p->regshift;
@@ -118,6 +116,13 @@ static void __init sdv_arch_setup(void)
sdv_serial_fixup();
}
+static void __cpuinit sdv_pci_init(void)
+{
+ x86_of_pci_init();
+ /* We can't set this earlier, because we need calibrate the timer */
+ legacy_pic = &null_legacy_pic;
+}
+
/*
* CE4100 specific x86_init function overrides and early setup
* calls.
@@ -127,6 +132,11 @@ void __init x86_ce4100_early_setup(void)
x86_init.oem.arch_setup = sdv_arch_setup;
x86_platform.i8042_detect = ce4100_i8042_detect;
x86_init.resources.probe_roms = x86_init_noop;
- x86_init.mpparse.get_smp_config = x86_init_uint_noop;
- x86_init.mpparse.find_smp_config = sdv_find_smp_config;
+ x86_init.mpparse.get_smp_config = x86_dtb_get_config;
+ x86_init.mpparse.find_smp_config = x86_dtb_find_config;
+
+#ifdef CONFIG_X86_IO_APIC
+ x86_init.pci.init_irq = sdv_pci_init;
+ x86_init.mpparse.setup_ioapic_ids = setup_ioapic_ids_from_mpc_nocheck;
+#endif
}
--
1.7.4
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 11/11] rtc/cmos: add OF bindings
[not found] ` <1298405266-1624-1-git-send-email-bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
` (8 preceding siblings ...)
2011-02-22 20:07 ` [PATCH 10/11] x86/ce4100: use OF for ioapic Sebastian Andrzej Siewior
@ 2011-02-22 20:07 ` Sebastian Andrzej Siewior
[not found] ` <1298405266-1624-12-git-send-email-bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
9 siblings, 1 reply; 23+ messages in thread
From: Sebastian Andrzej Siewior @ 2011-02-22 20:07 UTC (permalink / raw)
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
Cc: Alessandro Zummo, rtc-linux-/JYPxA39Uh5TLH3MbocFFw,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
x86-DgEjT+Ai2ygdnm+yROfE0A, sodaville-hfZtesqFncYOwBW4kG4KsQ,
Sebastian Andrzej Siewior
This allows to load the OF driver based informations from the device
tree. Systems without BIOS may need to perform some initialization.
PowerPC creates a PNP device from the OF information and performs this
kind of initialization in their private PCI quirk. This looks more
generic.
This patch also avoids registering the platform RTC driver on X86 if we
have a device tree blob. Without it we end up with of this devices. It
is in this hunk in order to remain bisectable.
Cc: rtc-linux-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
Cc: Alessandro Zummo <a.zummo-BfzFCNDTiLLj+vYz1yj4TQ@public.gmane.org>
Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
Signed-off-by: Sebastian Andrzej Siewior <bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
Signed-off-by: Dirk Brandewie <dirk.brandewie-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
Documentation/devicetree/bindings/rtc/rtc-cmos.txt | 28 ++++++++++++
arch/x86/kernel/rtc.c | 3 +
drivers/rtc/rtc-cmos.c | 45 ++++++++++++++++++++
include/linux/of.h | 12 +++++
4 files changed, 88 insertions(+), 0 deletions(-)
create mode 100644 Documentation/devicetree/bindings/rtc/rtc-cmos.txt
diff --git a/Documentation/devicetree/bindings/rtc/rtc-cmos.txt b/Documentation/devicetree/bindings/rtc/rtc-cmos.txt
new file mode 100644
index 0000000..7382989
--- /dev/null
+++ b/Documentation/devicetree/bindings/rtc/rtc-cmos.txt
@@ -0,0 +1,28 @@
+ Motorola mc146818 compatible RTC
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Required properties:
+ - compatible : "motorola,mc146818"
+ - reg : should contain registers location and length.
+
+Optional properties:
+ - interrupts : should contain interrupt.
+ - interrupt-parent : interrupt source phandle.
+ - ctrl-reg : Contains the initial value of the control register also
+ called "Register B".
+ - freq-reg : Contains the initial value of the frequency register also
+ called "Regsiter A".
+
+"Register A" and "B" are usually initialized by the firmware (BIOS for
+instance). If this is not done, it can be performed by the driver.
+
+ISA Example:
+
+ rtc@70 {
+ compatible = "motorola,mc146818";
+ interrupts = <8 3>;
+ interrupt-parent = <&ioapic1>;
+ ctrl-reg = <2>;
+ freq-reg = <0x26>;
+ reg = <1 0x70 2>;
+ };
diff --git a/arch/x86/kernel/rtc.c b/arch/x86/kernel/rtc.c
index 6f39cab..3f2ad26 100644
--- a/arch/x86/kernel/rtc.c
+++ b/arch/x86/kernel/rtc.c
@@ -6,6 +6,7 @@
#include <linux/acpi.h>
#include <linux/bcd.h>
#include <linux/pnp.h>
+#include <linux/of.h>
#include <asm/vsyscall.h>
#include <asm/x86_init.h>
@@ -236,6 +237,8 @@ static __init int add_rtc_cmos(void)
}
}
#endif
+ if (of_have_populated_dt())
+ return 0;
platform_device_register(&rtc_device);
dev_info(&rtc_device.dev,
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
index c7ff8df..159b95e 100644
--- a/drivers/rtc/rtc-cmos.c
+++ b/drivers/rtc/rtc-cmos.c
@@ -37,6 +37,8 @@
#include <linux/mod_devicetable.h>
#include <linux/log2.h>
#include <linux/pm.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
/* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */
#include <asm-generic/rtc.h>
@@ -1123,6 +1125,47 @@ static struct pnp_driver cmos_pnp_driver = {
#endif /* CONFIG_PNP */
+#ifdef CONFIG_OF
+static const struct of_device_id of_cmos_match[] = {
+ {
+ .compatible = "motorola,mc146818",
+ },
+ { },
+};
+MODULE_DEVICE_TABLE(of, of_cmos_match);
+
+static __init void cmos_of_init(struct platform_device *pdev)
+{
+ struct device_node *node = pdev->dev.of_node;
+ struct rtc_time time;
+ int ret;
+ const __be32 *val;
+
+ if (!node)
+ return;
+
+ val = of_get_property(node, "ctrl-reg", NULL);
+ if (val)
+ CMOS_WRITE(be32_to_cpup(val), RTC_CONTROL);
+
+ val = of_get_property(node, "freq-reg", NULL);
+ if (val)
+ CMOS_WRITE(be32_to_cpup(val), RTC_FREQ_SELECT);
+
+ get_rtc_time(&time);
+ ret = rtc_valid_tm(&time);
+ if (ret) {
+ struct rtc_time def_time = {
+ .tm_year = 1,
+ .tm_mday = 1,
+ };
+ set_rtc_time(&def_time);
+ }
+}
+#else
+static inline void cmos_of_init(struct platform_device *pdev) {}
+#define of_cmos_match NULL
+#endif
/*----------------------------------------------------------------*/
/* Platform setup should have set up an RTC device, when PNP is
@@ -1131,6 +1174,7 @@ static struct pnp_driver cmos_pnp_driver = {
static int __init cmos_platform_probe(struct platform_device *pdev)
{
+ cmos_of_init(pdev);
cmos_wake_setup(&pdev->dev);
return cmos_do_probe(&pdev->dev,
platform_get_resource(pdev, IORESOURCE_IO, 0),
@@ -1162,6 +1206,7 @@ static struct platform_driver cmos_platform_driver = {
#ifdef CONFIG_PM
.pm = &cmos_pm_ops,
#endif
+ .of_match_table = of_cmos_match,
}
};
diff --git a/include/linux/of.h b/include/linux/of.h
index d9dd664..8de7c29 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -70,6 +70,11 @@ extern struct device_node *allnodes;
extern struct device_node *of_chosen;
extern rwlock_t devtree_lock;
+static inline int of_have_populated_dt(void)
+{
+ return allnodes != NULL;
+}
+
static inline bool of_node_is_root(const struct device_node *node)
{
return node && (node->parent == NULL);
@@ -222,5 +227,12 @@ extern void of_attach_node(struct device_node *);
extern void of_detach_node(struct device_node *);
#endif
+#else
+
+static inline int of_have_populated_dt(void)
+{
+ return 0;
+}
+
#endif /* CONFIG_OF */
#endif /* _LINUX_OF_H */
--
1.7.4
^ permalink raw reply related [flat|nested] 23+ messages in thread