All of lore.kernel.org
 help / color / mirror / Atom feed
* Add device tree support for x86, v2
@ 2010-12-17 15:33 Sebastian Andrzej Siewior
  2010-12-17 15:33 ` [PATCH 01/15] x86/e820: remove conditional early mapping in parse_e820_ext Sebastian Andrzej Siewior
                   ` (14 more replies)
  0 siblings, 15 replies; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2010-12-17 15:33 UTC (permalink / raw)
  To: linux-kernel; +Cc: sodaville, x86, dirk.brandewie

This patchset introduces device tree support on x86. The device tree is 
passed by the bootloader via setup_data. It is used as an additional 
source of information and does not replace the "traditional" x86 boot
page.
Right now we get the the following information from it:
- hpet location
- apic & ioapic location
- ioapic's interrupt routing
- legacy devices which are not initialized by bios
- devices which are behind a bus which does not support enumeration like 
  i2c

Histrory:
- v1 initial post
- v2: Benh took my device tree apart so once this got fixed I refactor a
      lot of code. Here are the changes:
      - device tree is unflattenend before kmalloc() is working,
        alloc_bootmem() is used for that.
      - irq_host got renamed to irq_domain. This custom implementation
        will leave once the powerpc implementation is in generic shape
      - of_irq_map_pci() is moved from ppc & microblaze into drivers/of
	and used also by x86 instead of a tiny subset of it. Bridges are
        not handled at all on x86 (I don't have any so for so I worry
        later)
      - the device tree is relocated from its initial location. That
        means that the boot loader does not need to know anything about
        kernel's memory layout.

The series is based on the tip tree and is also available at
  git://git.linutronix.de/users/bigeasy/soda.git ce_of_v2

Sebastian Andrzej Siewior (15):
      x86/e820: remove conditional early mapping in parse_e820_ext
      x86: Add device tree support
      x86/dtb: Add a device tree for CE4100
      x86/dtb: add irq domain abstraction
      x86/dtb: add early parsing of APIC and IO APIC
      x86/dtb: add support hpet
      of: move of_irq_map_pci() into generic code
      x86/dtb: add support for PCI devices backed by dtb nodes
      x86/dtb: Add generic bus probe
      x86/ioapic: Add OF bindings for IO-APIC
      x86/ce4100: use OF for ioapic
      of/address: use propper endianess in get_flags
      x86/rtc: don't register rtc if we have an OF node for it
      rtc/cmos: add OF bindings
      x86/pci: remove warning

 Documentation/powerpc/dts-bindings/rtc-cmos.txt |   28 ++
 Documentation/x86/boot_with_dtb.txt             |   26 ++
 arch/microblaze/include/asm/prom.h              |   15 -
 arch/microblaze/kernel/prom_parse.c             |   77 -----
 arch/microblaze/pci/pci-common.c                |    1 +
 arch/powerpc/include/asm/prom.h                 |   17 +-
 arch/powerpc/kernel/pci-common.c                |    1 +
 arch/powerpc/kernel/prom_parse.c                |   84 ------
 arch/x86/Kconfig                                |    7 +
 arch/x86/include/asm/bootparam.h                |    1 +
 arch/x86/include/asm/e820.h                     |    2 +-
 arch/x86/include/asm/io_apic.h                  |    7 +
 arch/x86/include/asm/irq_controller.h           |   12 +
 arch/x86/include/asm/prom.h                     |   87 ++++++
 arch/x86/kernel/Makefile                        |    1 +
 arch/x86/kernel/apic/io_apic.c                  |   99 +++++++
 arch/x86/kernel/e820.c                          |    8 +-
 arch/x86/kernel/irqinit.c                       |    9 +-
 arch/x86/kernel/prom.c                          |  349 +++++++++++++++++++++++
 arch/x86/kernel/rtc.c                           |   23 ++
 arch/x86/kernel/setup.c                         |   24 ++-
 arch/x86/pci/ce4100.c                           |    2 +-
 arch/x86/platform/ce4100/ce4100.c               |   24 ++-
 arch/x86/platform/ce4100/falconfalls.dts        |  212 ++++++++++++++
 drivers/of/Makefile                             |    1 +
 drivers/of/address.c                            |   54 ++--
 drivers/of/of_pci.c                             |   97 +++++++
 drivers/rtc/rtc-cmos.c                          |   40 +++
 include/linux/of_address.h                      |    6 +-
 include/linux/of_pci.h                          |   24 ++
 30 files changed, 1097 insertions(+), 241 deletions(-)
 create mode 100644 Documentation/powerpc/dts-bindings/rtc-cmos.txt
 create mode 100644 Documentation/x86/boot_with_dtb.txt
 create mode 100644 arch/x86/include/asm/irq_controller.h
 create mode 100644 arch/x86/include/asm/prom.h
 create mode 100644 arch/x86/kernel/prom.c
 create mode 100644 arch/x86/platform/ce4100/falconfalls.dts
 create mode 100644 drivers/of/of_pci.c
 create mode 100644 include/linux/of_pci.h

Sebastian


^ permalink raw reply	[flat|nested] 106+ messages in thread

* [PATCH 01/15] x86/e820: remove conditional early mapping in parse_e820_ext
  2010-12-17 15:33 Add device tree support for x86, v2 Sebastian Andrzej Siewior
@ 2010-12-17 15:33 ` Sebastian Andrzej Siewior
  2010-12-30  8:37   ` Grant Likely
  2010-12-17 15:33   ` Sebastian Andrzej Siewior
                   ` (13 subsequent siblings)
  14 siblings, 1 reply; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2010-12-17 15:33 UTC (permalink / raw)
  To: linux-kernel; +Cc: sodaville, x86, dirk.brandewie, Sebastian Andrzej Siewior

This patch ensures that the memory passed from parse_setup_data() is
large enough to cover the complete data structure. That means that the
conditional mapping in parse_e820_ext() can go.

While here, I also attempt not to map two pages if the address is not
aligned to a page boundary.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Dirk Brandewie <dirk.brandewie@gmail.com>
---
 arch/x86/include/asm/e820.h |    2 +-
 arch/x86/kernel/e820.c      |    8 +-------
 arch/x86/kernel/setup.c     |   20 +++++++++++++++++---
 3 files changed, 19 insertions(+), 11 deletions(-)

diff --git a/arch/x86/include/asm/e820.h b/arch/x86/include/asm/e820.h
index 5be1542..e956492 100644
--- a/arch/x86/include/asm/e820.h
+++ b/arch/x86/include/asm/e820.h
@@ -93,7 +93,7 @@ extern void e820_setup_gap(void);
 extern int e820_search_gap(unsigned long *gapstart, unsigned long *gapsize,
 			unsigned long start_addr, unsigned long long end_addr);
 struct setup_data;
-extern void parse_e820_ext(struct setup_data *data, unsigned long pa_data);
+extern void parse_e820_ext(struct setup_data *data);
 
 #if defined(CONFIG_X86_64) || \
 	(defined(CONFIG_X86_32) && defined(CONFIG_HIBERNATION))
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index 0c2b7ef..33f6361 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -666,21 +666,15 @@ __init void e820_setup_gap(void)
  * boot_params.e820_map, others are passed via SETUP_E820_EXT node of
  * linked list of struct setup_data, which is parsed here.
  */
-void __init parse_e820_ext(struct setup_data *sdata, unsigned long pa_data)
+void __init parse_e820_ext(struct setup_data *sdata)
 {
-	u32 map_len;
 	int entries;
 	struct e820entry *extmap;
 
 	entries = sdata->len / sizeof(struct e820entry);
-	map_len = sdata->len + sizeof(struct setup_data);
-	if (map_len > PAGE_SIZE)
-		sdata = early_ioremap(pa_data, map_len);
 	extmap = (struct e820entry *)(sdata->data);
 	__append_e820_map(extmap, entries);
 	sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
-	if (map_len > PAGE_SIZE)
-		early_iounmap(sdata, map_len);
 	printk(KERN_INFO "extended physical RAM map:\n");
 	e820_print_map("extended");
 }
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 0afb8c7..577d06b 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -429,16 +429,30 @@ static void __init parse_setup_data(void)
 		return;
 	pa_data = boot_params.hdr.setup_data;
 	while (pa_data) {
-		data = early_memremap(pa_data, PAGE_SIZE);
+		u32 data_len;
+		u32 map_len;
+
+		map_len = max(PAGE_SIZE - (pa_data & ~PAGE_MASK),
+				(u64)sizeof(struct setup_data));
+		data = early_memremap(pa_data, map_len);
+		data_len = data->len + sizeof(struct setup_data);
+		if (data_len > map_len) {
+			early_iounmap(data, map_len);
+			data = early_memremap(pa_data, data_len);
+		}
+
 		switch (data->type) {
 		case SETUP_E820_EXT:
-			parse_e820_ext(data, pa_data);
+			parse_e820_ext(data);
 			break;
 		default:
 			break;
 		}
 		pa_data = data->next;
-		early_iounmap(data, PAGE_SIZE);
+		if (data_len > map_len)
+			early_iounmap(data, data_len);
+		else
+			early_iounmap(data, map_len);
 	}
 }
 
-- 
1.7.3.2


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 02/15] x86: Add device tree support
@ 2010-12-17 15:33   ` Sebastian Andrzej Siewior
  0 siblings, 0 replies; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2010-12-17 15:33 UTC (permalink / raw)
  To: linux-kernel
  Cc: sodaville, x86, dirk.brandewie, Sebastian Andrzej Siewior,
	devicetree-discuss

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@lists.ozlabs.org
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Dirk Brandewie <dirk.brandewie@gmail.com>
---
 Documentation/x86/boot_with_dtb.txt |   26 +++++++++++++++
 arch/x86/Kconfig                    |    7 ++++
 arch/x86/include/asm/bootparam.h    |    1 +
 arch/x86/include/asm/prom.h         |   59 +++++++++++++++++++++++++++++++++++
 arch/x86/kernel/Makefile            |    1 +
 arch/x86/kernel/irqinit.c           |    1 +
 arch/x86/kernel/prom.c              |   54 ++++++++++++++++++++++++++++++++
 arch/x86/kernel/setup.c             |    4 ++
 8 files changed, 153 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/x86/boot_with_dtb.txt
 create mode 100644 arch/x86/include/asm/prom.h
 create mode 100644 arch/x86/kernel/prom.c

diff --git a/Documentation/x86/boot_with_dtb.txt b/Documentation/x86/boot_with_dtb.txt
new file mode 100644
index 0000000..6a357aa
--- /dev/null
+++ b/Documentation/x86/boot_with_dtb.txt
@@ -0,0 +1,26 @@
+  Booting x86 with device tree
+=================================
+
+1. Introduction
+~~~~~~~~~~~~~~~
+This document contains device tree information which are specific to
+the x86 platform. Generic informations as bindings can be found in
+Documentation/powerpc/dts-bindings/
+
+2. Passing the device tree
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+The pointer to the device tree block (dtb) is passed via setup_data
+(see [0]) which requires at least boot protocol 2.09. The type filed is
+defined as
+
+#define SETUP_DTB                      2
+
+3. Purpose
+~~~~~~~~~~~
+The device tree is used as an extension to the "boot page". As such it does not
+parse / consider data which are already covered by the boot page. This includes
+memory size, 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.
+
+[0] Documentation/x86/boot.txt
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index b6fccb0..0522354 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -299,6 +299,13 @@ config X86_BIGSMP
 	---help---
 	  This option is needed for the systems that have more than 8 CPUs
 
+config X86_OF
+	bool "Support for device tree"
+	select OF
+	select OF_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/prom.h b/arch/x86/include/asm/prom.h
new file mode 100644
index 0000000..2fbe3e8
--- /dev/null
+++ b/arch/x86/include/asm/prom.h
@@ -0,0 +1,59 @@
+/*
+ * 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];
+/* This number is used when no interrupt has been assigned */
+#define NO_IRQ		(-1)
+
+#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__ */
+
+/*
+ * These includes are put at the bottom because they may contain things
+ * that are overridden by this file.  Ideally they shouldn't be included
+ * by this file, but there are a bunch of .c files that currently depend
+ * on it.  Eventually they will be cleaned up.
+ */
+#include <linux/of_fdt.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+
+#endif
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index f60153d..40bc33d 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -108,6 +108,7 @@ obj-$(CONFIG_MICROCODE)			+= microcode.o
 obj-$(CONFIG_X86_CHECK_BIOS_CORRUPTION) += check.o
 
 obj-$(CONFIG_SWIOTLB)			+= pci-swiotlb.o
+obj-$(CONFIG_X86_OF)			+= prom.o
 
 ###
 # 64 bit specific files
diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c
index c752e97..149c87f 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:
diff --git a/arch/x86/kernel/prom.c b/arch/x86/kernel/prom.c
new file mode 100644
index 0000000..249ebd3
--- /dev/null
+++ b/arch/x86/kernel/prom.c
@@ -0,0 +1,54 @@
+/*
+ * Architecture specific OF callbacks.
+ */
+#include <linux/bootmem.h>
+#include <linux/io.h>
+#include <linux/list.h>
+#include <linux/of.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();
+}
+
+u64 __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
+{
+	void *mem;
+
+	mem = __alloc_bootmem(size, align, __pa(MAX_DMA_ADDRESS));
+	return virt_to_phys(mem);
+}
+
+void __init add_dtb(u64 data)
+{
+	initial_boot_params = (struct boot_param_header *)
+		phys_to_virt((u64) (u32) data +
+				offsetof(struct setup_data, data));
+}
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 577d06b..26f2c9a 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.
@@ -445,6 +446,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.3.2


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 02/15] x86: Add device tree support
@ 2010-12-17 15:33   ` Sebastian Andrzej Siewior
  0 siblings, 0 replies; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2010-12-17 15:33 UTC (permalink / raw)
  To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
  Cc: sodaville-hfZtesqFncYOwBW4kG4KsQ, Sebastian Andrzej Siewior,
	x86-DgEjT+Ai2ygdnm+yROfE0A,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ

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
Signed-off-by: Sebastian Andrzej Siewior <bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
Signed-off-by: Dirk Brandewie <dirk.brandewie-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 Documentation/x86/boot_with_dtb.txt |   26 +++++++++++++++
 arch/x86/Kconfig                    |    7 ++++
 arch/x86/include/asm/bootparam.h    |    1 +
 arch/x86/include/asm/prom.h         |   59 +++++++++++++++++++++++++++++++++++
 arch/x86/kernel/Makefile            |    1 +
 arch/x86/kernel/irqinit.c           |    1 +
 arch/x86/kernel/prom.c              |   54 ++++++++++++++++++++++++++++++++
 arch/x86/kernel/setup.c             |    4 ++
 8 files changed, 153 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/x86/boot_with_dtb.txt
 create mode 100644 arch/x86/include/asm/prom.h
 create mode 100644 arch/x86/kernel/prom.c

diff --git a/Documentation/x86/boot_with_dtb.txt b/Documentation/x86/boot_with_dtb.txt
new file mode 100644
index 0000000..6a357aa
--- /dev/null
+++ b/Documentation/x86/boot_with_dtb.txt
@@ -0,0 +1,26 @@
+  Booting x86 with device tree
+=================================
+
+1. Introduction
+~~~~~~~~~~~~~~~
+This document contains device tree information which are specific to
+the x86 platform. Generic informations as bindings can be found in
+Documentation/powerpc/dts-bindings/
+
+2. Passing the device tree
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+The pointer to the device tree block (dtb) is passed via setup_data
+(see [0]) which requires at least boot protocol 2.09. The type filed is
+defined as
+
+#define SETUP_DTB                      2
+
+3. Purpose
+~~~~~~~~~~~
+The device tree is used as an extension to the "boot page". As such it does not
+parse / consider data which are already covered by the boot page. This includes
+memory size, 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.
+
+[0] Documentation/x86/boot.txt
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index b6fccb0..0522354 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -299,6 +299,13 @@ config X86_BIGSMP
 	---help---
 	  This option is needed for the systems that have more than 8 CPUs
 
+config X86_OF
+	bool "Support for device tree"
+	select OF
+	select OF_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/prom.h b/arch/x86/include/asm/prom.h
new file mode 100644
index 0000000..2fbe3e8
--- /dev/null
+++ b/arch/x86/include/asm/prom.h
@@ -0,0 +1,59 @@
+/*
+ * 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];
+/* This number is used when no interrupt has been assigned */
+#define NO_IRQ		(-1)
+
+#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__ */
+
+/*
+ * These includes are put at the bottom because they may contain things
+ * that are overridden by this file.  Ideally they shouldn't be included
+ * by this file, but there are a bunch of .c files that currently depend
+ * on it.  Eventually they will be cleaned up.
+ */
+#include <linux/of_fdt.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+
+#endif
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index f60153d..40bc33d 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -108,6 +108,7 @@ obj-$(CONFIG_MICROCODE)			+= microcode.o
 obj-$(CONFIG_X86_CHECK_BIOS_CORRUPTION) += check.o
 
 obj-$(CONFIG_SWIOTLB)			+= pci-swiotlb.o
+obj-$(CONFIG_X86_OF)			+= prom.o
 
 ###
 # 64 bit specific files
diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c
index c752e97..149c87f 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:
diff --git a/arch/x86/kernel/prom.c b/arch/x86/kernel/prom.c
new file mode 100644
index 0000000..249ebd3
--- /dev/null
+++ b/arch/x86/kernel/prom.c
@@ -0,0 +1,54 @@
+/*
+ * Architecture specific OF callbacks.
+ */
+#include <linux/bootmem.h>
+#include <linux/io.h>
+#include <linux/list.h>
+#include <linux/of.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();
+}
+
+u64 __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
+{
+	void *mem;
+
+	mem = __alloc_bootmem(size, align, __pa(MAX_DMA_ADDRESS));
+	return virt_to_phys(mem);
+}
+
+void __init add_dtb(u64 data)
+{
+	initial_boot_params = (struct boot_param_header *)
+		phys_to_virt((u64) (u32) data +
+				offsetof(struct setup_data, data));
+}
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 577d06b..26f2c9a 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.
@@ -445,6 +446,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.3.2

^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 03/15] x86/dtb: Add a device tree for CE4100
@ 2010-12-17 15:33   ` Sebastian Andrzej Siewior
  0 siblings, 0 replies; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2010-12-17 15:33 UTC (permalink / raw)
  To: linux-kernel
  Cc: sodaville, x86, dirk.brandewie, Sebastian Andrzej Siewior,
	devicetree-discuss

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/platform/ce4100/falconfalls.dts |  212 ++++++++++++++++++++++++++++++
 1 files changed, 212 insertions(+), 0 deletions(-)
 create mode 100644 arch/x86/platform/ce4100/falconfalls.dts

diff --git a/arch/x86/platform/ce4100/falconfalls.dts b/arch/x86/platform/ce4100/falconfalls.dts
new file mode 100644
index 0000000..24e67ca
--- /dev/null
+++ b/arch/x86/platform/ce4100/falconfalls.dts
@@ -0,0 +1,212 @@
+/*
+ * 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>;
+		device_type = "soc";
+		compatible = "Intel,ce4100";
+		ranges;
+
+		ioapic1: pic@fec00000 {
+			#interrupt-cells = <2>;
+			compatible = "Intel,ioapic";
+			interrupt-controller;
+			device_type = "interrupt-controller";
+			id = <1>;
+			reg = <0xfec00000 0x1000>;
+		};
+
+		hpet@fed00000 {
+			compatible = "Intel,hpet-ce4100", "Intel,hpet";
+			reg = <0xfed00000 0x200>;
+		};
+
+		lapic0: lapic@fee00000 {
+			compatible = "Intel,lapic-ce4100", "Intel,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
+				  0x0000000 0 0x0	 0x0	    0 0x100>;
+
+			isa@0 {
+				#address-cells = <2>;
+				#size-cells = <1>;
+				compatible = "isa";
+				ranges = <1 0 0 0 0 0x100>;
+
+				rtc@70 {
+					compatible = "motorola,mc146818";
+					interrupts = <8 3>;
+					interrupt-parent = <&ioapic1>;
+					ctrl-reg = <2>;
+					freq-reg = <0x26>;
+					reg = <1 0x70 2>;
+				};
+			};
+
+			/* Secondary IO-APIC */
+			ioapic2: pic@bffff000 {
+				#interrupt-cells = <2>;
+				compatible = "Intel,ioapic-ce4100", "Intel,ioapic";
+				interrupt-controller;
+				device_type = "interrupt-controller";
+				id = <2>;
+				reg = <0x100 0x0 0x0 0x0 0x0>;
+				assigned-addresses = <0x02000000 0x0 0xbffff000 0x0 0x1000>;
+			};
+
+			pci@av {
+				#address-cells = <3>;
+				#interrupt-cells = <1>;
+				#size-cells = <1>;
+				compatible = "Intel,ce4100-pci";
+				device_type = "pci";
+				bus-range = <1 1>;
+				interrupt-map-mask = <0xffffff 0x0 0x0 0x0>;
+				interrupt-map = <
+					/* GFX: 0x2E5B */
+					0x11000 0x0 0x0 0x0 &ioapic2 0 0x1
+					/* ***** FIXME ****** Compositing Engine: 0x2E72 */
+					/* 0x11100 0x0 0x0 0x1 &ioapic2 0 0x1 */
+					/* MFD: 0x2E5C */
+					0x11800 0x0 0x0 0x0 &ioapic2 2 0x1
+					/* TS Prefilter: 0x2E5D */
+					0x12000 0x0 0x0 0x0 &ioapic2 4 0x1
+					/* TS Demux: 0x2E5E */
+					0x12100 0x0 0x0 0x0 &ioapic2 5 0x1
+					/* ***** FIXME ***** Audio DSP: 0x2E5F */
+					/* 0x13000 0x0 0x0 0x1 &ioapic2 0 0x1 */
+					/* Audio Interfaces: 0x2E60 */
+					0x13200 0x0 0x0 0x0 &ioapic2 8 0x1
+					/* VDC: 0x2E61 */
+					0x14000 0x0 0x0 0x0 &ioapic2 9 0x1
+					/* DPE: 0x2E62 */
+					0x14100 0x0 0x0 0x0 &ioapic2 10 0x1
+					/* HDMI Tx: 0x2E63 */
+					0x14200 0x0 0x0 0x0 &ioapic2 11 0x1
+					/* SEC: 0x2E64 */
+					0x14800 0x0 0x0 0x0 &ioapic2 12 0x1
+					/* EXP: 0x2E65 */
+					0x15000 0x0 0x0 0x0 &ioapic2 13 0x1
+					/* UART0/1: 0x2E66 */
+					0x15800 0x0 0x0 0x0 &ioapic2 14 0x1
+					/* GPIO: 0x2E67 */
+					0x15900 0x0 0x0 0x0 &ioapic2 15 0x1
+					/* I2C0/1/2: 0x2E68 */
+					0x15a00 0x0 0x0 0x0 &ioapic2 16 0x1
+					/* Smart Card 0/1: 0x2E69 */
+					0x15b00 0x0 0x0 0x0 &ioapic2 15 0x1
+					/* SPI: 0x2E6A */
+					0x15c00 0x0 0x0 0x0 &ioapic2 15 0x1
+					/* MSPOD: 0x2E6B */
+					0x15d00 0x0 0x0 0x0 &ioapic2 19 0x1
+					/* IR: 0x2E6C */
+					0x15e00 0x0 0x0 0x0 &ioapic2 16 0x1
+					/* **** FIXME ***** DFX: 0x2E6D */
+					/* 0x15f00 0x0 0x0 0x1 &ioapic2 0x0 0x1 */
+					/* Gig Ethernet: 0x2E6E */
+					0x16000 0x0 0x0 0x0 &ioapic2 21 0x1
+					/* IEEE1588 and Clock Recovery Unit: 0x2E6F */
+					0x16100 0x0 0x0 0x0 &ioapic2 3 0x1
+					/* USB0: 0x2E70 */
+					0x16800 0x0 0x0 0x0 &ioapic2 22 0x3
+					/* USB1: 0x2E70 */
+					0x16900 0x0 0x0 0x0 &ioapic2 22 0x3
+					/* SATA: 0x2E71 */
+					0x17000 0x0 0x0 0x0 &ioapic2 23 0x3
+					>;
+
+				i2c@15a00 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0x15a00 0x0 0x0 0x0>;
+
+
+					i2c@0 {
+						reg = <0>;
+					};
+
+					i2c@1 {
+						#address-cells = <1>;
+						#size-cells = <0>;
+						reg = <1>;
+
+						pcf8575@26 {
+							compatible = "ti,pcf8575";
+							reg = <0x26>;
+						};
+					};
+
+					i2c@2 {
+						#address-cells = <1>;
+						#size-cells = <0>;
+						reg = <2>;
+
+						pcf8575@26 {
+							compatible = "ti,pcf8575";
+							reg = <0x26>;
+						};
+					};
+				};
+
+				spi@15c00 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0x15c00 0x0 0x0 0x0>;
+
+					pcm1755@0 {
+						compatible = "ti,pcm1755";
+						reg = <0>;
+						spi-max-frequency = <115200>;
+					};
+
+					pcm1609a@1 {
+						compatible = "ti,pcm1609a";
+						reg = <1>;
+						spi-max-frequency = <115200>;
+					};
+
+					at93c46@2 {
+						compatible = "atmel,at93c46";
+						reg = <2>;
+						spi-max-frequency = <115200>;
+					};
+				};
+			};
+		};
+	};
+};
-- 
1.7.3.2


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 03/15] x86/dtb: Add a device tree for CE4100
@ 2010-12-17 15:33   ` Sebastian Andrzej Siewior
  0 siblings, 0 replies; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2010-12-17 15:33 UTC (permalink / raw)
  To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
  Cc: sodaville-hfZtesqFncYOwBW4kG4KsQ, Sebastian Andrzej Siewior,
	x86-DgEjT+Ai2ygdnm+yROfE0A,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ

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/platform/ce4100/falconfalls.dts |  212 ++++++++++++++++++++++++++++++
 1 files changed, 212 insertions(+), 0 deletions(-)
 create mode 100644 arch/x86/platform/ce4100/falconfalls.dts

diff --git a/arch/x86/platform/ce4100/falconfalls.dts b/arch/x86/platform/ce4100/falconfalls.dts
new file mode 100644
index 0000000..24e67ca
--- /dev/null
+++ b/arch/x86/platform/ce4100/falconfalls.dts
@@ -0,0 +1,212 @@
+/*
+ * 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>;
+		device_type = "soc";
+		compatible = "Intel,ce4100";
+		ranges;
+
+		ioapic1: pic@fec00000 {
+			#interrupt-cells = <2>;
+			compatible = "Intel,ioapic";
+			interrupt-controller;
+			device_type = "interrupt-controller";
+			id = <1>;
+			reg = <0xfec00000 0x1000>;
+		};
+
+		hpet@fed00000 {
+			compatible = "Intel,hpet-ce4100", "Intel,hpet";
+			reg = <0xfed00000 0x200>;
+		};
+
+		lapic0: lapic@fee00000 {
+			compatible = "Intel,lapic-ce4100", "Intel,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
+				  0x0000000 0 0x0	 0x0	    0 0x100>;
+
+			isa@0 {
+				#address-cells = <2>;
+				#size-cells = <1>;
+				compatible = "isa";
+				ranges = <1 0 0 0 0 0x100>;
+
+				rtc@70 {
+					compatible = "motorola,mc146818";
+					interrupts = <8 3>;
+					interrupt-parent = <&ioapic1>;
+					ctrl-reg = <2>;
+					freq-reg = <0x26>;
+					reg = <1 0x70 2>;
+				};
+			};
+
+			/* Secondary IO-APIC */
+			ioapic2: pic@bffff000 {
+				#interrupt-cells = <2>;
+				compatible = "Intel,ioapic-ce4100", "Intel,ioapic";
+				interrupt-controller;
+				device_type = "interrupt-controller";
+				id = <2>;
+				reg = <0x100 0x0 0x0 0x0 0x0>;
+				assigned-addresses = <0x02000000 0x0 0xbffff000 0x0 0x1000>;
+			};
+
+			pci@av {
+				#address-cells = <3>;
+				#interrupt-cells = <1>;
+				#size-cells = <1>;
+				compatible = "Intel,ce4100-pci";
+				device_type = "pci";
+				bus-range = <1 1>;
+				interrupt-map-mask = <0xffffff 0x0 0x0 0x0>;
+				interrupt-map = <
+					/* GFX: 0x2E5B */
+					0x11000 0x0 0x0 0x0 &ioapic2 0 0x1
+					/* ***** FIXME ****** Compositing Engine: 0x2E72 */
+					/* 0x11100 0x0 0x0 0x1 &ioapic2 0 0x1 */
+					/* MFD: 0x2E5C */
+					0x11800 0x0 0x0 0x0 &ioapic2 2 0x1
+					/* TS Prefilter: 0x2E5D */
+					0x12000 0x0 0x0 0x0 &ioapic2 4 0x1
+					/* TS Demux: 0x2E5E */
+					0x12100 0x0 0x0 0x0 &ioapic2 5 0x1
+					/* ***** FIXME ***** Audio DSP: 0x2E5F */
+					/* 0x13000 0x0 0x0 0x1 &ioapic2 0 0x1 */
+					/* Audio Interfaces: 0x2E60 */
+					0x13200 0x0 0x0 0x0 &ioapic2 8 0x1
+					/* VDC: 0x2E61 */
+					0x14000 0x0 0x0 0x0 &ioapic2 9 0x1
+					/* DPE: 0x2E62 */
+					0x14100 0x0 0x0 0x0 &ioapic2 10 0x1
+					/* HDMI Tx: 0x2E63 */
+					0x14200 0x0 0x0 0x0 &ioapic2 11 0x1
+					/* SEC: 0x2E64 */
+					0x14800 0x0 0x0 0x0 &ioapic2 12 0x1
+					/* EXP: 0x2E65 */
+					0x15000 0x0 0x0 0x0 &ioapic2 13 0x1
+					/* UART0/1: 0x2E66 */
+					0x15800 0x0 0x0 0x0 &ioapic2 14 0x1
+					/* GPIO: 0x2E67 */
+					0x15900 0x0 0x0 0x0 &ioapic2 15 0x1
+					/* I2C0/1/2: 0x2E68 */
+					0x15a00 0x0 0x0 0x0 &ioapic2 16 0x1
+					/* Smart Card 0/1: 0x2E69 */
+					0x15b00 0x0 0x0 0x0 &ioapic2 15 0x1
+					/* SPI: 0x2E6A */
+					0x15c00 0x0 0x0 0x0 &ioapic2 15 0x1
+					/* MSPOD: 0x2E6B */
+					0x15d00 0x0 0x0 0x0 &ioapic2 19 0x1
+					/* IR: 0x2E6C */
+					0x15e00 0x0 0x0 0x0 &ioapic2 16 0x1
+					/* **** FIXME ***** DFX: 0x2E6D */
+					/* 0x15f00 0x0 0x0 0x1 &ioapic2 0x0 0x1 */
+					/* Gig Ethernet: 0x2E6E */
+					0x16000 0x0 0x0 0x0 &ioapic2 21 0x1
+					/* IEEE1588 and Clock Recovery Unit: 0x2E6F */
+					0x16100 0x0 0x0 0x0 &ioapic2 3 0x1
+					/* USB0: 0x2E70 */
+					0x16800 0x0 0x0 0x0 &ioapic2 22 0x3
+					/* USB1: 0x2E70 */
+					0x16900 0x0 0x0 0x0 &ioapic2 22 0x3
+					/* SATA: 0x2E71 */
+					0x17000 0x0 0x0 0x0 &ioapic2 23 0x3
+					>;
+
+				i2c@15a00 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0x15a00 0x0 0x0 0x0>;
+
+
+					i2c@0 {
+						reg = <0>;
+					};
+
+					i2c@1 {
+						#address-cells = <1>;
+						#size-cells = <0>;
+						reg = <1>;
+
+						pcf8575@26 {
+							compatible = "ti,pcf8575";
+							reg = <0x26>;
+						};
+					};
+
+					i2c@2 {
+						#address-cells = <1>;
+						#size-cells = <0>;
+						reg = <2>;
+
+						pcf8575@26 {
+							compatible = "ti,pcf8575";
+							reg = <0x26>;
+						};
+					};
+				};
+
+				spi@15c00 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0x15c00 0x0 0x0 0x0>;
+
+					pcm1755@0 {
+						compatible = "ti,pcm1755";
+						reg = <0>;
+						spi-max-frequency = <115200>;
+					};
+
+					pcm1609a@1 {
+						compatible = "ti,pcm1609a";
+						reg = <1>;
+						spi-max-frequency = <115200>;
+					};
+
+					at93c46@2 {
+						compatible = "atmel,at93c46";
+						reg = <2>;
+						spi-max-frequency = <115200>;
+					};
+				};
+			};
+		};
+	};
+};
-- 
1.7.3.2

^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 04/15] x86/dtb: add irq domain abstraction
@ 2010-12-17 15:33   ` Sebastian Andrzej Siewior
  0 siblings, 0 replies; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2010-12-17 15:33 UTC (permalink / raw)
  To: linux-kernel
  Cc: sodaville, x86, dirk.brandewie, Sebastian Andrzej Siewior,
	devicetree-discuss

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>
---
 arch/x86/include/asm/irq_controller.h |   12 ++++++++
 arch/x86/include/asm/prom.h           |    2 +
 arch/x86/kernel/prom.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 2fbe3e8..9076ae4 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/prom.c b/arch/x86/kernel/prom.c
index 249ebd3..53948cb 100644
--- a/arch/x86/kernel/prom.c
+++ b/arch/x86/kernel/prom.c
@@ -3,18 +3,63 @@
  */
 #include <linux/bootmem.h>
 #include <linux/io.h>
+#include <linux/interrupt.h>
 #include <linux/list.h>
 #include <linux/of.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 -ENODEV;
+	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.3.2


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 04/15] x86/dtb: add irq domain abstraction
@ 2010-12-17 15:33   ` Sebastian Andrzej Siewior
  0 siblings, 0 replies; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2010-12-17 15:33 UTC (permalink / raw)
  To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
  Cc: sodaville-hfZtesqFncYOwBW4kG4KsQ, Sebastian Andrzej Siewior,
	x86-DgEjT+Ai2ygdnm+yROfE0A,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ

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/prom.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 2fbe3e8..9076ae4 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/prom.c b/arch/x86/kernel/prom.c
index 249ebd3..53948cb 100644
--- a/arch/x86/kernel/prom.c
+++ b/arch/x86/kernel/prom.c
@@ -3,18 +3,63 @@
  */
 #include <linux/bootmem.h>
 #include <linux/io.h>
+#include <linux/interrupt.h>
 #include <linux/list.h>
 #include <linux/of.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 -ENODEV;
+	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.3.2

^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 05/15] x86/dtb: add early parsing of APIC and IO APIC
@ 2010-12-17 15:33   ` Sebastian Andrzej Siewior
  0 siblings, 0 replies; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2010-12-17 15:33 UTC (permalink / raw)
  To: linux-kernel
  Cc: sodaville, x86, dirk.brandewie, Sebastian Andrzej Siewior,
	devicetree-discuss

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@lists.ozlabs.org
Cc: Dirk Brandewie <dirk.brandewie@gmail.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
 arch/x86/include/asm/prom.h |    7 +++
 arch/x86/kernel/irqinit.c   |    2 +-
 arch/x86/kernel/prom.c      |  123 +++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 128 insertions(+), 4 deletions(-)

diff --git a/arch/x86/include/asm/prom.h b/arch/x86/include/asm/prom.h
index 9076ae4..3bc8ed5 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/irqinit.c b/arch/x86/kernel/irqinit.c
index 149c87f..4cadf86 100644
--- a/arch/x86/kernel/irqinit.c
+++ b/arch/x86/kernel/irqinit.c
@@ -244,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
diff --git a/arch/x86/kernel/prom.c b/arch/x86/kernel/prom.c
index 53948cb..9cbb52b 100644
--- a/arch/x86/kernel/prom.c
+++ b/arch/x86/kernel/prom.c
@@ -6,15 +6,20 @@
 #include <linux/interrupt.h>
 #include <linux/list.h>
 #include <linux/of.h>
+#include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <linux/slab.h>
 
 #include <asm/irq_controller.h>
+#include <asm/io_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;
@@ -93,7 +98,119 @@ u64 __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
 
 void __init add_dtb(u64 data)
 {
-	initial_boot_params = (struct boot_param_header *)
-		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 void __init dtb_add_ioapic(struct device_node *dn)
+{
+	unsigned int ioapic_id;
+	const __be32 *cell;
+	int len;
+	struct resource r;
+	int ret;
+
+	cell = of_get_property(dn, "id", &len);
+	if (!cell) {
+		printk(KERN_ERR "Node %s is missing id property.\n",
+				dn->full_name);
+		return;
+	}
+	ioapic_id = of_read_ulong(cell, len / 4);
+
+	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,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);
+	}
+
+	new_dtb = alloc_bootmem(size);
+	memcpy(new_dtb, initial_boot_params, size);
+	if (map_len < size)
+		early_iounmap(initial_boot_params, size);
+	else
+		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();
 }
-- 
1.7.3.2


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 05/15] x86/dtb: add early parsing of APIC and IO APIC
@ 2010-12-17 15:33   ` Sebastian Andrzej Siewior
  0 siblings, 0 replies; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2010-12-17 15:33 UTC (permalink / raw)
  To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
  Cc: sodaville-hfZtesqFncYOwBW4kG4KsQ, Sebastian Andrzej Siewior,
	x86-DgEjT+Ai2ygdnm+yROfE0A,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ

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>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
---
 arch/x86/include/asm/prom.h |    7 +++
 arch/x86/kernel/irqinit.c   |    2 +-
 arch/x86/kernel/prom.c      |  123 +++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 128 insertions(+), 4 deletions(-)

diff --git a/arch/x86/include/asm/prom.h b/arch/x86/include/asm/prom.h
index 9076ae4..3bc8ed5 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/irqinit.c b/arch/x86/kernel/irqinit.c
index 149c87f..4cadf86 100644
--- a/arch/x86/kernel/irqinit.c
+++ b/arch/x86/kernel/irqinit.c
@@ -244,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
diff --git a/arch/x86/kernel/prom.c b/arch/x86/kernel/prom.c
index 53948cb..9cbb52b 100644
--- a/arch/x86/kernel/prom.c
+++ b/arch/x86/kernel/prom.c
@@ -6,15 +6,20 @@
 #include <linux/interrupt.h>
 #include <linux/list.h>
 #include <linux/of.h>
+#include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <linux/slab.h>
 
 #include <asm/irq_controller.h>
+#include <asm/io_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;
@@ -93,7 +98,119 @@ u64 __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
 
 void __init add_dtb(u64 data)
 {
-	initial_boot_params = (struct boot_param_header *)
-		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 void __init dtb_add_ioapic(struct device_node *dn)
+{
+	unsigned int ioapic_id;
+	const __be32 *cell;
+	int len;
+	struct resource r;
+	int ret;
+
+	cell = of_get_property(dn, "id", &len);
+	if (!cell) {
+		printk(KERN_ERR "Node %s is missing id property.\n",
+				dn->full_name);
+		return;
+	}
+	ioapic_id = of_read_ulong(cell, len / 4);
+
+	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,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);
+	}
+
+	new_dtb = alloc_bootmem(size);
+	memcpy(new_dtb, initial_boot_params, size);
+	if (map_len < size)
+		early_iounmap(initial_boot_params, size);
+	else
+		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();
 }
-- 
1.7.3.2

^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 06/15] x86/dtb: add support hpet
@ 2010-12-17 15:33   ` Sebastian Andrzej Siewior
  0 siblings, 0 replies; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2010-12-17 15:33 UTC (permalink / raw)
  To: linux-kernel
  Cc: sodaville, x86, dirk.brandewie, Sebastian Andrzej Siewior,
	devicetree-discuss

Set hpet_address based on information provied form DTB

Cc: devicetree-discuss@lists.ozlabs.org
Cc: Dirk Brandewie <dirk.brandewie@gmail.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
 arch/x86/kernel/prom.c |   19 +++++++++++++++++++
 1 files changed, 19 insertions(+), 0 deletions(-)

diff --git a/arch/x86/kernel/prom.c b/arch/x86/kernel/prom.c
index 9cbb52b..40ad8c0 100644
--- a/arch/x86/kernel/prom.c
+++ b/arch/x86/kernel/prom.c
@@ -10,6 +10,7 @@
 #include <linux/of_platform.h>
 #include <linux/slab.h>
 
+#include <asm/hpet.h>
 #include <asm/irq_controller.h>
 #include <asm/io_apic.h>
 
@@ -101,6 +102,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,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
@@ -212,5 +230,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.3.2


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 06/15] x86/dtb: add support hpet
@ 2010-12-17 15:33   ` Sebastian Andrzej Siewior
  0 siblings, 0 replies; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2010-12-17 15:33 UTC (permalink / raw)
  To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
  Cc: sodaville-hfZtesqFncYOwBW4kG4KsQ, Sebastian Andrzej Siewior,
	x86-DgEjT+Ai2ygdnm+yROfE0A,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ

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>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
---
 arch/x86/kernel/prom.c |   19 +++++++++++++++++++
 1 files changed, 19 insertions(+), 0 deletions(-)

diff --git a/arch/x86/kernel/prom.c b/arch/x86/kernel/prom.c
index 9cbb52b..40ad8c0 100644
--- a/arch/x86/kernel/prom.c
+++ b/arch/x86/kernel/prom.c
@@ -10,6 +10,7 @@
 #include <linux/of_platform.h>
 #include <linux/slab.h>
 
+#include <asm/hpet.h>
 #include <asm/irq_controller.h>
 #include <asm/io_apic.h>
 
@@ -101,6 +102,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,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
@@ -212,5 +230,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.3.2

^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 07/15] of: move of_irq_map_pci() into generic code
@ 2010-12-17 15:33   ` Sebastian Andrzej Siewior
  0 siblings, 0 replies; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2010-12-17 15:33 UTC (permalink / raw)
  To: linux-kernel
  Cc: sodaville, x86, dirk.brandewie, Sebastian Andrzej Siewior,
	devicetree-discuss, Benjamin Herrenschmidt

From: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>

There is a tiny difference between PPC32 and PPC64. Microblaze uses the
PPC32 variant.

Cc: devicetree-discuss@lists.ozlabs.org
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
---
 arch/microblaze/include/asm/prom.h  |   15 -----
 arch/microblaze/kernel/prom_parse.c |   77 ---------------------------
 arch/microblaze/pci/pci-common.c    |    1 +
 arch/powerpc/include/asm/prom.h     |   15 -----
 arch/powerpc/kernel/pci-common.c    |    1 +
 arch/powerpc/kernel/prom_parse.c    |   84 ------------------------------
 drivers/of/Makefile                 |    1 +
 drivers/of/of_pci.c                 |   97 +++++++++++++++++++++++++++++++++++
 include/linux/of_pci.h              |   24 +++++++++
 9 files changed, 124 insertions(+), 191 deletions(-)
 create mode 100644 drivers/of/of_pci.c
 create mode 100644 include/linux/of_pci.h

diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h
index bdc3831..aa3ab12 100644
--- a/arch/microblaze/include/asm/prom.h
+++ b/arch/microblaze/include/asm/prom.h
@@ -67,21 +67,6 @@ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
 /* Get the MAC address */
 extern const void *of_get_mac_address(struct device_node *np);
 
-/**
- * of_irq_map_pci - Resolve the interrupt for a PCI device
- * @pdev:	the device whose interrupt is to be resolved
- * @out_irq:	structure of_irq filled by this function
- *
- * This function resolves the PCI interrupt for a given PCI device. If a
- * device-node exists for a given pci_dev, it will use normal OF tree
- * walking. If not, it will implement standard swizzling and walk up the
- * PCI tree until an device-node is found, at which point it will finish
- * resolving using the OF tree walking.
- */
-struct pci_dev;
-struct of_irq;
-extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
-
 #endif /* __ASSEMBLY__ */
 #endif /* __KERNEL__ */
 
diff --git a/arch/microblaze/kernel/prom_parse.c b/arch/microblaze/kernel/prom_parse.c
index 99d9b61..306f41d 100644
--- a/arch/microblaze/kernel/prom_parse.c
+++ b/arch/microblaze/kernel/prom_parse.c
@@ -2,88 +2,11 @@
 
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/pci_regs.h>
 #include <linux/module.h>
 #include <linux/ioport.h>
 #include <linux/etherdevice.h>
 #include <linux/of_address.h>
 #include <asm/prom.h>
-#include <asm/pci-bridge.h>
-
-#ifdef CONFIG_PCI
-int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
-{
-	struct device_node *dn, *ppnode;
-	struct pci_dev *ppdev;
-	u32 lspec;
-	u32 laddr[3];
-	u8 pin;
-	int rc;
-
-	/* Check if we have a device node, if yes, fallback to standard OF
-	 * parsing
-	 */
-	dn = pci_device_to_OF_node(pdev);
-	if (dn)
-		return of_irq_map_one(dn, 0, out_irq);
-
-	/* Ok, we don't, time to have fun. Let's start by building up an
-	 * interrupt spec.  we assume #interrupt-cells is 1, which is standard
-	 * for PCI. If you do different, then don't use that routine.
-	 */
-	rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
-	if (rc != 0)
-		return rc;
-	/* No pin, exit */
-	if (pin == 0)
-		return -ENODEV;
-
-	/* Now we walk up the PCI tree */
-	lspec = pin;
-	for (;;) {
-		/* Get the pci_dev of our parent */
-		ppdev = pdev->bus->self;
-
-		/* Ouch, it's a host bridge... */
-		if (ppdev == NULL) {
-			struct pci_controller *host;
-			host = pci_bus_to_host(pdev->bus);
-			ppnode = host ? host->dn : NULL;
-			/* No node for host bridge ? give up */
-			if (ppnode == NULL)
-				return -EINVAL;
-		} else
-			/* We found a P2P bridge, check if it has a node */
-			ppnode = pci_device_to_OF_node(ppdev);
-
-		/* Ok, we have found a parent with a device-node, hand over to
-		 * the OF parsing code.
-		 * We build a unit address from the linux device to be used for
-		 * resolution. Note that we use the linux bus number which may
-		 * not match your firmware bus numbering.
-		 * Fortunately, in most cases, interrupt-map-mask doesn't
-		 * include the bus number as part of the matching.
-		 * You should still be careful about that though if you intend
-		 * to rely on this function (you ship  a firmware that doesn't
-		 * create device nodes for all PCI devices).
-		 */
-		if (ppnode)
-			break;
-
-		/* We can only get here if we hit a P2P bridge with no node,
-		 * let's do standard swizzling and try again
-		 */
-		lspec = pci_swizzle_interrupt_pin(pdev, lspec);
-		pdev = ppdev;
-	}
-
-	laddr[0] = (pdev->bus->number << 16)
-		| (pdev->devfn << 8);
-	laddr[1]  = laddr[2] = 0;
-	return of_irq_map_raw(ppnode, &lspec, 1, laddr, out_irq);
-}
-EXPORT_SYMBOL_GPL(of_irq_map_pci);
-#endif /* CONFIG_PCI */
 
 void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
 		unsigned long *busno, unsigned long *phys, unsigned long *size)
diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c
index e363615..1e01a12 100644
--- a/arch/microblaze/pci/pci-common.c
+++ b/arch/microblaze/pci/pci-common.c
@@ -29,6 +29,7 @@
 #include <linux/slab.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/of_pci.h>
 
 #include <asm/processor.h>
 #include <asm/io.h>
diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h
index ae26f2e..01c3302 100644
--- a/arch/powerpc/include/asm/prom.h
+++ b/arch/powerpc/include/asm/prom.h
@@ -73,21 +73,6 @@ static inline int of_node_to_nid(struct device_node *device) { return 0; }
 #endif
 #define of_node_to_nid of_node_to_nid
 
-/**
- * of_irq_map_pci - Resolve the interrupt for a PCI device
- * @pdev:	the device whose interrupt is to be resolved
- * @out_irq:	structure of_irq filled by this function
- *
- * This function resolves the PCI interrupt for a given PCI device. If a
- * device-node exists for a given pci_dev, it will use normal OF tree
- * walking. If not, it will implement standard swizzling and walk up the
- * PCI tree until an device-node is found, at which point it will finish
- * resolving using the OF tree walking.
- */
-struct pci_dev;
-struct of_irq;
-extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
-
 extern void of_instantiate_rtc(void);
 
 /* These includes are put at the bottom because they may contain things
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 10a44e6..eb341be 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -22,6 +22,7 @@
 #include <linux/init.h>
 #include <linux/bootmem.h>
 #include <linux/of_address.h>
+#include <linux/of_pci.h>
 #include <linux/mm.h>
 #include <linux/list.h>
 #include <linux/syscalls.h>
diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c
index 88334af..306f41d 100644
--- a/arch/powerpc/kernel/prom_parse.c
+++ b/arch/powerpc/kernel/prom_parse.c
@@ -2,95 +2,11 @@
 
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/pci_regs.h>
 #include <linux/module.h>
 #include <linux/ioport.h>
 #include <linux/etherdevice.h>
 #include <linux/of_address.h>
 #include <asm/prom.h>
-#include <asm/pci-bridge.h>
-
-#ifdef CONFIG_PCI
-int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
-{
-	struct device_node *dn, *ppnode;
-	struct pci_dev *ppdev;
-	u32 lspec;
-	u32 laddr[3];
-	u8 pin;
-	int rc;
-
-	/* Check if we have a device node, if yes, fallback to standard OF
-	 * parsing
-	 */
-	dn = pci_device_to_OF_node(pdev);
-	if (dn) {
-		rc = of_irq_map_one(dn, 0, out_irq);
-		if (!rc)
-			return rc;
-	}
-
-	/* Ok, we don't, time to have fun. Let's start by building up an
-	 * interrupt spec.  we assume #interrupt-cells is 1, which is standard
-	 * for PCI. If you do different, then don't use that routine.
-	 */
-	rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
-	if (rc != 0)
-		return rc;
-	/* No pin, exit */
-	if (pin == 0)
-		return -ENODEV;
-
-	/* Now we walk up the PCI tree */
-	lspec = pin;
-	for (;;) {
-		/* Get the pci_dev of our parent */
-		ppdev = pdev->bus->self;
-
-		/* Ouch, it's a host bridge... */
-		if (ppdev == NULL) {
-#ifdef CONFIG_PPC64
-			ppnode = pci_bus_to_OF_node(pdev->bus);
-#else
-			struct pci_controller *host;
-			host = pci_bus_to_host(pdev->bus);
-			ppnode = host ? host->dn : NULL;
-#endif
-			/* No node for host bridge ? give up */
-			if (ppnode == NULL)
-				return -EINVAL;
-		} else
-			/* We found a P2P bridge, check if it has a node */
-			ppnode = pci_device_to_OF_node(ppdev);
-
-		/* Ok, we have found a parent with a device-node, hand over to
-		 * the OF parsing code.
-		 * We build a unit address from the linux device to be used for
-		 * resolution. Note that we use the linux bus number which may
-		 * not match your firmware bus numbering.
-		 * Fortunately, in most cases, interrupt-map-mask doesn't include
-		 * the bus number as part of the matching.
-		 * You should still be careful about that though if you intend
-		 * to rely on this function (you ship  a firmware that doesn't
-		 * create device nodes for all PCI devices).
-		 */
-		if (ppnode)
-			break;
-
-		/* We can only get here if we hit a P2P bridge with no node,
-		 * let's do standard swizzling and try again
-		 */
-		lspec = pci_swizzle_interrupt_pin(pdev, lspec);
-		pdev = ppdev;
-	}
-
-	laddr[0] = (pdev->bus->number << 16)
-		| (pdev->devfn << 8);
-	laddr[1]  = laddr[2] = 0;
-	return of_irq_map_raw(ppnode, &lspec, 1, laddr, out_irq);
-}
-EXPORT_SYMBOL_GPL(of_irq_map_pci);
-#endif /* CONFIG_PCI */
 
 void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
 		unsigned long *busno, unsigned long *phys, unsigned long *size)
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index 7888155..4dcb177 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_OF_GPIO)   += gpio.o
 obj-$(CONFIG_OF_I2C)	+= of_i2c.o
 obj-$(CONFIG_OF_SPI)	+= of_spi.o
 obj-$(CONFIG_OF_MDIO)	+= of_mdio.o
+obj-$(CONFIG_PCI)	+= of_pci.o
diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
new file mode 100644
index 0000000..5450d16
--- /dev/null
+++ b/drivers/of/of_pci.c
@@ -0,0 +1,97 @@
+#include <linux/kernel.h>
+#include <linux/of_pci.h>
+#include <asm/prom.h>
+
+#if defined(CONFIG_PPC64) || defined(CONFIG_X86)
+static struct device_node *pci_get_parent_node(struct pci_dev *pdev)
+{
+	return pci_bus_to_OF_node(pdev->bus);
+}
+#endif
+
+#if defined(CONFIG_PPC32) || defined(CONFIG_MICROBLAZE)
+static struct device_node *pci_get_parent_node(struct pci_dev *pdev)
+{
+	struct pci_controller *host;
+
+	host = pci_bus_to_host(pdev->bus);
+	return host ? host->dn : NULL;
+}
+#endif
+
+int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
+{
+	struct device_node *dn, *ppnode;
+	struct pci_dev *ppdev;
+	u32 lspec;
+	__be32 lspec_be;
+	__be32 laddr[3];
+	u8 pin;
+	int rc;
+
+	/* Check if we have a device node, if yes, fallback to standard OF
+	 * parsing
+	 */
+	dn = pci_device_to_OF_node(pdev);
+	if (dn) {
+		rc = of_irq_map_one(dn, 0, out_irq);
+		if (!rc)
+			return rc;
+	}
+
+	/* Ok, we don't, time to have fun. Let's start by building up an
+	 * interrupt spec.  we assume #interrupt-cells is 1, which is standard
+	 * for PCI. If you do different, then don't use that routine.
+	 */
+	rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
+	if (rc != 0)
+		return rc;
+	/* No pin, exit */
+	if (pin == 0)
+		return -ENODEV;
+
+	/* Now we walk up the PCI tree */
+	lspec = pin;
+	for (;;) {
+		/* Get the pci_dev of our parent */
+		ppdev = pdev->bus->self;
+
+		/* Ouch, it's a host bridge... */
+		if (ppdev == NULL) {
+			ppnode = pci_get_parent_node(pdev);
+
+			/* No node for host bridge ? give up */
+			if (ppnode == NULL)
+				return -EINVAL;
+		} else {
+			/* We found a P2P bridge, check if it has a node */
+			ppnode = pci_device_to_OF_node(ppdev);
+		}
+
+		/* Ok, we have found a parent with a device-node, hand over to
+		 * the OF parsing code.
+		 * We build a unit address from the linux device to be used for
+		 * resolution. Note that we use the linux bus number which may
+		 * not match your firmware bus numbering.
+		 * Fortunately, in most cases, interrupt-map-mask doesn't
+		 * include the bus number as part of the matching.
+		 * You should still be careful about that though if you intend
+		 * to rely on this function (you ship  a firmware that doesn't
+		 * create device nodes for all PCI devices).
+		 */
+		if (ppnode)
+			break;
+
+		/* We can only get here if we hit a P2P bridge with no node,
+		 * let's do standard swizzling and try again
+		 */
+		lspec = pci_swizzle_interrupt_pin(pdev, lspec);
+		pdev = ppdev;
+	}
+
+	lspec_be = cpu_to_be32(lspec);
+	laddr[0] = cpu_to_be32((pdev->bus->number << 16) | (pdev->devfn << 8));
+	laddr[1]  = laddr[2] = cpu_to_be32(0);
+	return of_irq_map_raw(ppnode, &lspec_be, 1, laddr, out_irq);
+}
+EXPORT_SYMBOL_GPL(of_irq_map_pci);
diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h
new file mode 100644
index 0000000..36b3cfa
--- /dev/null
+++ b/include/linux/of_pci.h
@@ -0,0 +1,24 @@
+#ifndef __OF_PCI_H
+#define __OF_PCI_H
+
+#include <linux/pci.h>
+
+#ifdef CONFIG_PPC_OF
+#include <asm/pci-bridge.h>
+#endif
+
+/**
+ * of_irq_map_pci - Resolve the interrupt for a PCI device
+ * @pdev:       the device whose interrupt is to be resolved
+ * @out_irq:    structure of_irq filled by this function
+ *
+ * This function resolves the PCI interrupt for a given PCI device. If a
+ * device-node exists for a given pci_dev, it will use normal OF tree
+ * walking. If not, it will implement standard swizzling and walk up the
+ * PCI tree until an device-node is found, at which point it will finish
+ * resolving using the OF tree walking.
+ */
+struct pci_dev;
+struct of_irq;
+int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
+#endif
-- 
1.7.3.2


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 07/15] of: move of_irq_map_pci() into generic code
@ 2010-12-17 15:33   ` Sebastian Andrzej Siewior
  0 siblings, 0 replies; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2010-12-17 15:33 UTC (permalink / raw)
  To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	x86-DgEjT+Ai2ygdnm+yROfE0A, sodaville-hfZtesqFncYOwBW4kG4KsQ,
	Sebastian Andrzej Siewior

From: Sebastian Andrzej Siewior <sebastian-E0PNVn5OA6ohrxcnuTQ+TQ@public.gmane.org>

There is a tiny difference between PPC32 and PPC64. Microblaze uses the
PPC32 variant.

Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
Cc: Benjamin Herrenschmidt <benh-XVmvHMARGAS8U2dJNN8I7kB+6BGkLq7r@public.gmane.org>
Signed-off-by: Sebastian Andrzej Siewior <sebastian-E0PNVn5OA6ohrxcnuTQ+TQ@public.gmane.org>
---
 arch/microblaze/include/asm/prom.h  |   15 -----
 arch/microblaze/kernel/prom_parse.c |   77 ---------------------------
 arch/microblaze/pci/pci-common.c    |    1 +
 arch/powerpc/include/asm/prom.h     |   15 -----
 arch/powerpc/kernel/pci-common.c    |    1 +
 arch/powerpc/kernel/prom_parse.c    |   84 ------------------------------
 drivers/of/Makefile                 |    1 +
 drivers/of/of_pci.c                 |   97 +++++++++++++++++++++++++++++++++++
 include/linux/of_pci.h              |   24 +++++++++
 9 files changed, 124 insertions(+), 191 deletions(-)
 create mode 100644 drivers/of/of_pci.c
 create mode 100644 include/linux/of_pci.h

diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h
index bdc3831..aa3ab12 100644
--- a/arch/microblaze/include/asm/prom.h
+++ b/arch/microblaze/include/asm/prom.h
@@ -67,21 +67,6 @@ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
 /* Get the MAC address */
 extern const void *of_get_mac_address(struct device_node *np);
 
-/**
- * of_irq_map_pci - Resolve the interrupt for a PCI device
- * @pdev:	the device whose interrupt is to be resolved
- * @out_irq:	structure of_irq filled by this function
- *
- * This function resolves the PCI interrupt for a given PCI device. If a
- * device-node exists for a given pci_dev, it will use normal OF tree
- * walking. If not, it will implement standard swizzling and walk up the
- * PCI tree until an device-node is found, at which point it will finish
- * resolving using the OF tree walking.
- */
-struct pci_dev;
-struct of_irq;
-extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
-
 #endif /* __ASSEMBLY__ */
 #endif /* __KERNEL__ */
 
diff --git a/arch/microblaze/kernel/prom_parse.c b/arch/microblaze/kernel/prom_parse.c
index 99d9b61..306f41d 100644
--- a/arch/microblaze/kernel/prom_parse.c
+++ b/arch/microblaze/kernel/prom_parse.c
@@ -2,88 +2,11 @@
 
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/pci_regs.h>
 #include <linux/module.h>
 #include <linux/ioport.h>
 #include <linux/etherdevice.h>
 #include <linux/of_address.h>
 #include <asm/prom.h>
-#include <asm/pci-bridge.h>
-
-#ifdef CONFIG_PCI
-int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
-{
-	struct device_node *dn, *ppnode;
-	struct pci_dev *ppdev;
-	u32 lspec;
-	u32 laddr[3];
-	u8 pin;
-	int rc;
-
-	/* Check if we have a device node, if yes, fallback to standard OF
-	 * parsing
-	 */
-	dn = pci_device_to_OF_node(pdev);
-	if (dn)
-		return of_irq_map_one(dn, 0, out_irq);
-
-	/* Ok, we don't, time to have fun. Let's start by building up an
-	 * interrupt spec.  we assume #interrupt-cells is 1, which is standard
-	 * for PCI. If you do different, then don't use that routine.
-	 */
-	rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
-	if (rc != 0)
-		return rc;
-	/* No pin, exit */
-	if (pin == 0)
-		return -ENODEV;
-
-	/* Now we walk up the PCI tree */
-	lspec = pin;
-	for (;;) {
-		/* Get the pci_dev of our parent */
-		ppdev = pdev->bus->self;
-
-		/* Ouch, it's a host bridge... */
-		if (ppdev == NULL) {
-			struct pci_controller *host;
-			host = pci_bus_to_host(pdev->bus);
-			ppnode = host ? host->dn : NULL;
-			/* No node for host bridge ? give up */
-			if (ppnode == NULL)
-				return -EINVAL;
-		} else
-			/* We found a P2P bridge, check if it has a node */
-			ppnode = pci_device_to_OF_node(ppdev);
-
-		/* Ok, we have found a parent with a device-node, hand over to
-		 * the OF parsing code.
-		 * We build a unit address from the linux device to be used for
-		 * resolution. Note that we use the linux bus number which may
-		 * not match your firmware bus numbering.
-		 * Fortunately, in most cases, interrupt-map-mask doesn't
-		 * include the bus number as part of the matching.
-		 * You should still be careful about that though if you intend
-		 * to rely on this function (you ship  a firmware that doesn't
-		 * create device nodes for all PCI devices).
-		 */
-		if (ppnode)
-			break;
-
-		/* We can only get here if we hit a P2P bridge with no node,
-		 * let's do standard swizzling and try again
-		 */
-		lspec = pci_swizzle_interrupt_pin(pdev, lspec);
-		pdev = ppdev;
-	}
-
-	laddr[0] = (pdev->bus->number << 16)
-		| (pdev->devfn << 8);
-	laddr[1]  = laddr[2] = 0;
-	return of_irq_map_raw(ppnode, &lspec, 1, laddr, out_irq);
-}
-EXPORT_SYMBOL_GPL(of_irq_map_pci);
-#endif /* CONFIG_PCI */
 
 void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
 		unsigned long *busno, unsigned long *phys, unsigned long *size)
diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c
index e363615..1e01a12 100644
--- a/arch/microblaze/pci/pci-common.c
+++ b/arch/microblaze/pci/pci-common.c
@@ -29,6 +29,7 @@
 #include <linux/slab.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/of_pci.h>
 
 #include <asm/processor.h>
 #include <asm/io.h>
diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h
index ae26f2e..01c3302 100644
--- a/arch/powerpc/include/asm/prom.h
+++ b/arch/powerpc/include/asm/prom.h
@@ -73,21 +73,6 @@ static inline int of_node_to_nid(struct device_node *device) { return 0; }
 #endif
 #define of_node_to_nid of_node_to_nid
 
-/**
- * of_irq_map_pci - Resolve the interrupt for a PCI device
- * @pdev:	the device whose interrupt is to be resolved
- * @out_irq:	structure of_irq filled by this function
- *
- * This function resolves the PCI interrupt for a given PCI device. If a
- * device-node exists for a given pci_dev, it will use normal OF tree
- * walking. If not, it will implement standard swizzling and walk up the
- * PCI tree until an device-node is found, at which point it will finish
- * resolving using the OF tree walking.
- */
-struct pci_dev;
-struct of_irq;
-extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
-
 extern void of_instantiate_rtc(void);
 
 /* These includes are put at the bottom because they may contain things
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 10a44e6..eb341be 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -22,6 +22,7 @@
 #include <linux/init.h>
 #include <linux/bootmem.h>
 #include <linux/of_address.h>
+#include <linux/of_pci.h>
 #include <linux/mm.h>
 #include <linux/list.h>
 #include <linux/syscalls.h>
diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c
index 88334af..306f41d 100644
--- a/arch/powerpc/kernel/prom_parse.c
+++ b/arch/powerpc/kernel/prom_parse.c
@@ -2,95 +2,11 @@
 
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/pci_regs.h>
 #include <linux/module.h>
 #include <linux/ioport.h>
 #include <linux/etherdevice.h>
 #include <linux/of_address.h>
 #include <asm/prom.h>
-#include <asm/pci-bridge.h>
-
-#ifdef CONFIG_PCI
-int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
-{
-	struct device_node *dn, *ppnode;
-	struct pci_dev *ppdev;
-	u32 lspec;
-	u32 laddr[3];
-	u8 pin;
-	int rc;
-
-	/* Check if we have a device node, if yes, fallback to standard OF
-	 * parsing
-	 */
-	dn = pci_device_to_OF_node(pdev);
-	if (dn) {
-		rc = of_irq_map_one(dn, 0, out_irq);
-		if (!rc)
-			return rc;
-	}
-
-	/* Ok, we don't, time to have fun. Let's start by building up an
-	 * interrupt spec.  we assume #interrupt-cells is 1, which is standard
-	 * for PCI. If you do different, then don't use that routine.
-	 */
-	rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
-	if (rc != 0)
-		return rc;
-	/* No pin, exit */
-	if (pin == 0)
-		return -ENODEV;
-
-	/* Now we walk up the PCI tree */
-	lspec = pin;
-	for (;;) {
-		/* Get the pci_dev of our parent */
-		ppdev = pdev->bus->self;
-
-		/* Ouch, it's a host bridge... */
-		if (ppdev == NULL) {
-#ifdef CONFIG_PPC64
-			ppnode = pci_bus_to_OF_node(pdev->bus);
-#else
-			struct pci_controller *host;
-			host = pci_bus_to_host(pdev->bus);
-			ppnode = host ? host->dn : NULL;
-#endif
-			/* No node for host bridge ? give up */
-			if (ppnode == NULL)
-				return -EINVAL;
-		} else
-			/* We found a P2P bridge, check if it has a node */
-			ppnode = pci_device_to_OF_node(ppdev);
-
-		/* Ok, we have found a parent with a device-node, hand over to
-		 * the OF parsing code.
-		 * We build a unit address from the linux device to be used for
-		 * resolution. Note that we use the linux bus number which may
-		 * not match your firmware bus numbering.
-		 * Fortunately, in most cases, interrupt-map-mask doesn't include
-		 * the bus number as part of the matching.
-		 * You should still be careful about that though if you intend
-		 * to rely on this function (you ship  a firmware that doesn't
-		 * create device nodes for all PCI devices).
-		 */
-		if (ppnode)
-			break;
-
-		/* We can only get here if we hit a P2P bridge with no node,
-		 * let's do standard swizzling and try again
-		 */
-		lspec = pci_swizzle_interrupt_pin(pdev, lspec);
-		pdev = ppdev;
-	}
-
-	laddr[0] = (pdev->bus->number << 16)
-		| (pdev->devfn << 8);
-	laddr[1]  = laddr[2] = 0;
-	return of_irq_map_raw(ppnode, &lspec, 1, laddr, out_irq);
-}
-EXPORT_SYMBOL_GPL(of_irq_map_pci);
-#endif /* CONFIG_PCI */
 
 void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
 		unsigned long *busno, unsigned long *phys, unsigned long *size)
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index 7888155..4dcb177 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_OF_GPIO)   += gpio.o
 obj-$(CONFIG_OF_I2C)	+= of_i2c.o
 obj-$(CONFIG_OF_SPI)	+= of_spi.o
 obj-$(CONFIG_OF_MDIO)	+= of_mdio.o
+obj-$(CONFIG_PCI)	+= of_pci.o
diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
new file mode 100644
index 0000000..5450d16
--- /dev/null
+++ b/drivers/of/of_pci.c
@@ -0,0 +1,97 @@
+#include <linux/kernel.h>
+#include <linux/of_pci.h>
+#include <asm/prom.h>
+
+#if defined(CONFIG_PPC64) || defined(CONFIG_X86)
+static struct device_node *pci_get_parent_node(struct pci_dev *pdev)
+{
+	return pci_bus_to_OF_node(pdev->bus);
+}
+#endif
+
+#if defined(CONFIG_PPC32) || defined(CONFIG_MICROBLAZE)
+static struct device_node *pci_get_parent_node(struct pci_dev *pdev)
+{
+	struct pci_controller *host;
+
+	host = pci_bus_to_host(pdev->bus);
+	return host ? host->dn : NULL;
+}
+#endif
+
+int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
+{
+	struct device_node *dn, *ppnode;
+	struct pci_dev *ppdev;
+	u32 lspec;
+	__be32 lspec_be;
+	__be32 laddr[3];
+	u8 pin;
+	int rc;
+
+	/* Check if we have a device node, if yes, fallback to standard OF
+	 * parsing
+	 */
+	dn = pci_device_to_OF_node(pdev);
+	if (dn) {
+		rc = of_irq_map_one(dn, 0, out_irq);
+		if (!rc)
+			return rc;
+	}
+
+	/* Ok, we don't, time to have fun. Let's start by building up an
+	 * interrupt spec.  we assume #interrupt-cells is 1, which is standard
+	 * for PCI. If you do different, then don't use that routine.
+	 */
+	rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
+	if (rc != 0)
+		return rc;
+	/* No pin, exit */
+	if (pin == 0)
+		return -ENODEV;
+
+	/* Now we walk up the PCI tree */
+	lspec = pin;
+	for (;;) {
+		/* Get the pci_dev of our parent */
+		ppdev = pdev->bus->self;
+
+		/* Ouch, it's a host bridge... */
+		if (ppdev == NULL) {
+			ppnode = pci_get_parent_node(pdev);
+
+			/* No node for host bridge ? give up */
+			if (ppnode == NULL)
+				return -EINVAL;
+		} else {
+			/* We found a P2P bridge, check if it has a node */
+			ppnode = pci_device_to_OF_node(ppdev);
+		}
+
+		/* Ok, we have found a parent with a device-node, hand over to
+		 * the OF parsing code.
+		 * We build a unit address from the linux device to be used for
+		 * resolution. Note that we use the linux bus number which may
+		 * not match your firmware bus numbering.
+		 * Fortunately, in most cases, interrupt-map-mask doesn't
+		 * include the bus number as part of the matching.
+		 * You should still be careful about that though if you intend
+		 * to rely on this function (you ship  a firmware that doesn't
+		 * create device nodes for all PCI devices).
+		 */
+		if (ppnode)
+			break;
+
+		/* We can only get here if we hit a P2P bridge with no node,
+		 * let's do standard swizzling and try again
+		 */
+		lspec = pci_swizzle_interrupt_pin(pdev, lspec);
+		pdev = ppdev;
+	}
+
+	lspec_be = cpu_to_be32(lspec);
+	laddr[0] = cpu_to_be32((pdev->bus->number << 16) | (pdev->devfn << 8));
+	laddr[1]  = laddr[2] = cpu_to_be32(0);
+	return of_irq_map_raw(ppnode, &lspec_be, 1, laddr, out_irq);
+}
+EXPORT_SYMBOL_GPL(of_irq_map_pci);
diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h
new file mode 100644
index 0000000..36b3cfa
--- /dev/null
+++ b/include/linux/of_pci.h
@@ -0,0 +1,24 @@
+#ifndef __OF_PCI_H
+#define __OF_PCI_H
+
+#include <linux/pci.h>
+
+#ifdef CONFIG_PPC_OF
+#include <asm/pci-bridge.h>
+#endif
+
+/**
+ * of_irq_map_pci - Resolve the interrupt for a PCI device
+ * @pdev:       the device whose interrupt is to be resolved
+ * @out_irq:    structure of_irq filled by this function
+ *
+ * This function resolves the PCI interrupt for a given PCI device. If a
+ * device-node exists for a given pci_dev, it will use normal OF tree
+ * walking. If not, it will implement standard swizzling and walk up the
+ * PCI tree until an device-node is found, at which point it will finish
+ * resolving using the OF tree walking.
+ */
+struct pci_dev;
+struct of_irq;
+int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
+#endif
-- 
1.7.3.2

^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 08/15] x86/dtb: add support for PCI devices backed by dtb nodes
@ 2010-12-17 15:33   ` Sebastian Andrzej Siewior
  0 siblings, 0 replies; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2010-12-17 15:33 UTC (permalink / raw)
  To: linux-kernel
  Cc: sodaville, x86, dirk.brandewie, Sebastian Andrzej Siewior,
	devicetree-discuss

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>
---
 arch/x86/include/asm/prom.h |   17 +++++++++
 arch/x86/kernel/prom.c      |   80 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 97 insertions(+), 0 deletions(-)

diff --git a/arch/x86/include/asm/prom.h b/arch/x86/include/asm/prom.h
index 3bc8ed5..9f7484e 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,24 @@ 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->dev.of_node;
+}
+
+static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
+{
+	if (bus->self)
+		return pci_device_to_OF_node(bus->self);
+	else
+		return NULL;
+}
+
 #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/prom.c b/arch/x86/kernel/prom.c
index 40ad8c0..a449dc6 100644
--- a/arch/x86/kernel/prom.c
+++ b/arch/x86/kernel/prom.c
@@ -9,10 +9,13 @@
 #include <linux/of_address.h>
 #include <linux/of_platform.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/io_apic.h>
+#include <asm/pci_x86.h>
 
 __initdata u64 initial_dtb;
 char __initdata cmd_line[COMMAND_LINE_SIZE];
@@ -102,6 +105,83 @@ void __init add_dtb(u64 data)
 	initial_dtb = data + offsetof(struct setup_data, data);
 }
 
+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 == NO_IRQ)
+		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);
+		}
+	}
+}
+
 static void __init dtb_setup_hpet(void)
 {
 	struct device_node *dn;
-- 
1.7.3.2


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 08/15] x86/dtb: add support for PCI devices backed by dtb nodes
@ 2010-12-17 15:33   ` Sebastian Andrzej Siewior
  0 siblings, 0 replies; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2010-12-17 15:33 UTC (permalink / raw)
  To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
  Cc: sodaville-hfZtesqFncYOwBW4kG4KsQ, Sebastian Andrzej Siewior,
	x86-DgEjT+Ai2ygdnm+yROfE0A,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ

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 |   17 +++++++++
 arch/x86/kernel/prom.c      |   80 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 97 insertions(+), 0 deletions(-)

diff --git a/arch/x86/include/asm/prom.h b/arch/x86/include/asm/prom.h
index 3bc8ed5..9f7484e 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,24 @@ 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->dev.of_node;
+}
+
+static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
+{
+	if (bus->self)
+		return pci_device_to_OF_node(bus->self);
+	else
+		return NULL;
+}
+
 #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/prom.c b/arch/x86/kernel/prom.c
index 40ad8c0..a449dc6 100644
--- a/arch/x86/kernel/prom.c
+++ b/arch/x86/kernel/prom.c
@@ -9,10 +9,13 @@
 #include <linux/of_address.h>
 #include <linux/of_platform.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/io_apic.h>
+#include <asm/pci_x86.h>
 
 __initdata u64 initial_dtb;
 char __initdata cmd_line[COMMAND_LINE_SIZE];
@@ -102,6 +105,83 @@ void __init add_dtb(u64 data)
 	initial_dtb = data + offsetof(struct setup_data, data);
 }
 
+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 == NO_IRQ)
+		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);
+		}
+	}
+}
+
 static void __init dtb_setup_hpet(void)
 {
 	struct device_node *dn;
-- 
1.7.3.2

^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 09/15] x86/dtb: Add generic bus probe
@ 2010-12-17 15:33   ` Sebastian Andrzej Siewior
  0 siblings, 0 replies; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2010-12-17 15:33 UTC (permalink / raw)
  To: linux-kernel
  Cc: sodaville, x86, dirk.brandewie, Sebastian Andrzej Siewior,
	devicetree-discuss

For now we probe these busses and we change is to board dependent probes
once we have to.

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/kernel/prom.c |   19 +++++++++++++++++++
 1 files changed, 19 insertions(+), 0 deletions(-)

diff --git a/arch/x86/kernel/prom.c b/arch/x86/kernel/prom.c
index a449dc6..6eddafd 100644
--- a/arch/x86/kernel/prom.c
+++ b/arch/x86/kernel/prom.c
@@ -105,6 +105,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[] = {
+	{ .type = "soc", },
+	{ .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);
+
 static int x86_of_pci_irq_enable(struct pci_dev *dev)
 {
 	struct of_irq oirq;
-- 
1.7.3.2


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 09/15] x86/dtb: Add generic bus probe
@ 2010-12-17 15:33   ` Sebastian Andrzej Siewior
  0 siblings, 0 replies; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2010-12-17 15:33 UTC (permalink / raw)
  To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
  Cc: sodaville-hfZtesqFncYOwBW4kG4KsQ, Sebastian Andrzej Siewior,
	x86-DgEjT+Ai2ygdnm+yROfE0A,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ

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
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/prom.c |   19 +++++++++++++++++++
 1 files changed, 19 insertions(+), 0 deletions(-)

diff --git a/arch/x86/kernel/prom.c b/arch/x86/kernel/prom.c
index a449dc6..6eddafd 100644
--- a/arch/x86/kernel/prom.c
+++ b/arch/x86/kernel/prom.c
@@ -105,6 +105,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[] = {
+	{ .type = "soc", },
+	{ .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);
+
 static int x86_of_pci_irq_enable(struct pci_dev *dev)
 {
 	struct of_irq oirq;
-- 
1.7.3.2

^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 10/15] x86/ioapic: Add OF bindings for IO-APIC
@ 2010-12-17 15:33   ` Sebastian Andrzej Siewior
  0 siblings, 0 replies; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2010-12-17 15:33 UTC (permalink / raw)
  To: linux-kernel
  Cc: sodaville, x86, dirk.brandewie, Sebastian Andrzej Siewior,
	devicetree-discuss

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/irqinit.c      |    6 ++
 arch/x86/kernel/prom.c         |   15 ++++++
 5 files changed, 129 insertions(+), 0 deletions(-)

diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index f327d38..5a8b950 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_X86_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 9f7484e..8386685 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);
@@ -46,6 +47,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 7eb0027..4dece80 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_X86_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;
 
@@ -4080,6 +4086,99 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
 	nr_ioapics++;
 }
 
+#ifdef CONFIG_X86_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/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
diff --git a/arch/x86/kernel/prom.c b/arch/x86/kernel/prom.c
index 6eddafd..edcaf1b 100644
--- a/arch/x86/kernel/prom.c
+++ b/arch/x86/kernel/prom.c
@@ -11,9 +11,11 @@
 #include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/of_pci.h>
+#include <linux/of_fdt.h>
 
 #include <asm/hpet.h>
 #include <asm/irq_controller.h>
+#include <asm/apic.h>
 #include <asm/io_apic.h>
 #include <asm/pci_x86.h>
 
@@ -332,3 +334,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_by_type(dp, "interrupt-controller") {
+		if (of_device_is_compatible(dp, "intel,ioapic"))
+			ioapic_add_ofnode(dp);
+	}
+}
-- 
1.7.3.2


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 10/15] x86/ioapic: Add OF bindings for IO-APIC
@ 2010-12-17 15:33   ` Sebastian Andrzej Siewior
  0 siblings, 0 replies; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2010-12-17 15:33 UTC (permalink / raw)
  To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
  Cc: sodaville-hfZtesqFncYOwBW4kG4KsQ, Sebastian Andrzej Siewior,
	x86-DgEjT+Ai2ygdnm+yROfE0A,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ

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/irqinit.c      |    6 ++
 arch/x86/kernel/prom.c         |   15 ++++++
 5 files changed, 129 insertions(+), 0 deletions(-)

diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index f327d38..5a8b950 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_X86_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 9f7484e..8386685 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);
@@ -46,6 +47,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 7eb0027..4dece80 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_X86_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;
 
@@ -4080,6 +4086,99 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
 	nr_ioapics++;
 }
 
+#ifdef CONFIG_X86_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/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
diff --git a/arch/x86/kernel/prom.c b/arch/x86/kernel/prom.c
index 6eddafd..edcaf1b 100644
--- a/arch/x86/kernel/prom.c
+++ b/arch/x86/kernel/prom.c
@@ -11,9 +11,11 @@
 #include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/of_pci.h>
+#include <linux/of_fdt.h>
 
 #include <asm/hpet.h>
 #include <asm/irq_controller.h>
+#include <asm/apic.h>
 #include <asm/io_apic.h>
 #include <asm/pci_x86.h>
 
@@ -332,3 +334,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_by_type(dp, "interrupt-controller") {
+		if (of_device_is_compatible(dp, "intel,ioapic"))
+			ioapic_add_ofnode(dp);
+	}
+}
-- 
1.7.3.2

^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 11/15] x86/ce4100: use OF for ioapic
  2010-12-17 15:33 Add device tree support for x86, v2 Sebastian Andrzej Siewior
                   ` (9 preceding siblings ...)
  2010-12-17 15:33   ` Sebastian Andrzej Siewior
@ 2010-12-17 15:33 ` Sebastian Andrzej Siewior
  2011-01-11 23:54   ` Grant Likely
  2010-12-17 15:33   ` Sebastian Andrzej Siewior
                   ` (3 subsequent siblings)
  14 siblings, 1 reply; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2010-12-17 15:33 UTC (permalink / raw)
  To: linux-kernel; +Cc: sodaville, x86, dirk.brandewie, Sebastian Andrzej Siewior

and hpet and a few others things....

Signed-off-by: Dirk Brandewie <dirk.brandewie@gmail.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
 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.3.2


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 12/15] of/address: use propper endianess in get_flags
@ 2010-12-17 15:33   ` Sebastian Andrzej Siewior
  0 siblings, 0 replies; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2010-12-17 15:33 UTC (permalink / raw)
  To: linux-kernel
  Cc: sodaville, x86, dirk.brandewie, Sebastian Andrzej Siewior,
	devicetree-discuss

This patch changes u32 to __be32 for all "ranges", "prop" and "addr" and
such. Those variables are pointing to the device tree which containts
intergers in big endian format.
Most functions are doing it right because they are using using
of_read_number() which is doing the right thing. of_bus_isa_get_flags(),
of_bus_pci_get_flags() and of_bus_isa_map() were accessing the data
directly and were doing it wrong.

Cc: devicetree-discuss@lists.ozlabs.org
Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
 arch/powerpc/include/asm/prom.h |    2 +-
 drivers/of/address.c            |   54 ++++++++++++++++++++------------------
 include/linux/of_address.h      |    6 ++--
 3 files changed, 32 insertions(+), 30 deletions(-)

diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h
index 01c3302..b891fdc 100644
--- a/arch/powerpc/include/asm/prom.h
+++ b/arch/powerpc/include/asm/prom.h
@@ -42,7 +42,7 @@ extern void pci_create_OF_bus_map(void);
 
 /* Translate a DMA address from device space to CPU space */
 extern u64 of_translate_dma_address(struct device_node *dev,
-				    const u32 *in_addr);
+				    const __be32 *in_addr);
 
 #ifdef CONFIG_PCI
 extern unsigned long pci_address_to_pio(phys_addr_t address);
diff --git a/drivers/of/address.c b/drivers/of/address.c
index 3a1c7e7..b4559c5 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -12,13 +12,13 @@
 			(ns) > 0)
 
 static struct of_bus *of_match_bus(struct device_node *np);
-static int __of_address_to_resource(struct device_node *dev, const u32 *addrp,
-				    u64 size, unsigned int flags,
+static int __of_address_to_resource(struct device_node *dev,
+		const __be32 *addrp, u64 size, unsigned int flags,
 				    struct resource *r);
 
 /* Debug utility */
 #ifdef DEBUG
-static void of_dump_addr(const char *s, const u32 *addr, int na)
+static void of_dump_addr(const char *s, const __be32 *addr, int na)
 {
 	printk(KERN_DEBUG "%s", s);
 	while (na--)
@@ -26,7 +26,7 @@ static void of_dump_addr(const char *s, const u32 *addr, int na)
 	printk("\n");
 }
 #else
-static void of_dump_addr(const char *s, const u32 *addr, int na) { }
+static void of_dump_addr(const char *s, const __be32 *addr, int na) { }
 #endif
 
 /* Callbacks for bus specific translators */
@@ -36,10 +36,10 @@ struct of_bus {
 	int		(*match)(struct device_node *parent);
 	void		(*count_cells)(struct device_node *child,
 				       int *addrc, int *sizec);
-	u64		(*map)(u32 *addr, const u32 *range,
+	u64		(*map)(u32 *addr, const __be32 *range,
 				int na, int ns, int pna);
 	int		(*translate)(u32 *addr, u64 offset, int na);
-	unsigned int	(*get_flags)(const u32 *addr);
+	unsigned int	(*get_flags)(const __be32 *addr);
 };
 
 /*
@@ -55,7 +55,7 @@ static void of_bus_default_count_cells(struct device_node *dev,
 		*sizec = of_n_size_cells(dev);
 }
 
-static u64 of_bus_default_map(u32 *addr, const u32 *range,
+static u64 of_bus_default_map(u32 *addr, const __be32 *range,
 		int na, int ns, int pna)
 {
 	u64 cp, s, da;
@@ -85,7 +85,7 @@ static int of_bus_default_translate(u32 *addr, u64 offset, int na)
 	return 0;
 }
 
-static unsigned int of_bus_default_get_flags(const u32 *addr)
+static unsigned int of_bus_default_get_flags(const __be32 *addr)
 {
 	return IORESOURCE_MEM;
 }
@@ -110,10 +110,10 @@ static void of_bus_pci_count_cells(struct device_node *np,
 		*sizec = 2;
 }
 
-static unsigned int of_bus_pci_get_flags(const u32 *addr)
+static unsigned int of_bus_pci_get_flags(const __be32 *addr)
 {
 	unsigned int flags = 0;
-	u32 w = addr[0];
+	u32 w = be32_to_cpup(addr);
 
 	switch((w >> 24) & 0x03) {
 	case 0x01:
@@ -129,7 +129,8 @@ static unsigned int of_bus_pci_get_flags(const u32 *addr)
 	return flags;
 }
 
-static u64 of_bus_pci_map(u32 *addr, const u32 *range, int na, int ns, int pna)
+static u64 of_bus_pci_map(u32 *addr, const __be32 *range, int na, int ns,
+		int pna)
 {
 	u64 cp, s, da;
 	unsigned int af, rf;
@@ -160,7 +161,7 @@ static int of_bus_pci_translate(u32 *addr, u64 offset, int na)
 	return of_bus_default_translate(addr + 1, offset, na - 1);
 }
 
-const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
+const __be32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
 			unsigned int *flags)
 {
 	const __be32 *prop;
@@ -207,7 +208,7 @@ EXPORT_SYMBOL(of_get_pci_address);
 int of_pci_address_to_resource(struct device_node *dev, int bar,
 			       struct resource *r)
 {
-	const u32	*addrp;
+	const __be32	*addrp;
 	u64		size;
 	unsigned int	flags;
 
@@ -237,12 +238,13 @@ static void of_bus_isa_count_cells(struct device_node *child,
 		*sizec = 1;
 }
 
-static u64 of_bus_isa_map(u32 *addr, const u32 *range, int na, int ns, int pna)
+static u64 of_bus_isa_map(u32 *addr, const __be32 *range, int na, int ns,
+		int pna)
 {
 	u64 cp, s, da;
 
 	/* Check address type match */
-	if ((addr[0] ^ range[0]) & 0x00000001)
+	if ((addr[0] ^ range[0]) & cpu_to_be32(1))
 		return OF_BAD_ADDR;
 
 	/* Read address values, skipping high cell */
@@ -264,10 +266,10 @@ static int of_bus_isa_translate(u32 *addr, u64 offset, int na)
 	return of_bus_default_translate(addr + 1, offset, na - 1);
 }
 
-static unsigned int of_bus_isa_get_flags(const u32 *addr)
+static unsigned int of_bus_isa_get_flags(const __be32 *addr)
 {
 	unsigned int flags = 0;
-	u32 w = addr[0];
+	u32 w = be32_to_cpup(addr);
 
 	if (w & 1)
 		flags |= IORESOURCE_IO;
@@ -330,7 +332,7 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus,
 			    struct of_bus *pbus, u32 *addr,
 			    int na, int ns, int pna, const char *rprop)
 {
-	const u32 *ranges;
+	const __be32 *ranges;
 	unsigned int rlen;
 	int rone;
 	u64 offset = OF_BAD_ADDR;
@@ -398,7 +400,7 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus,
  * that can be mapped to a cpu physical address). This is not really specified
  * that way, but this is traditionally the way IBM at least do things
  */
-u64 __of_translate_address(struct device_node *dev, const u32 *in_addr,
+u64 __of_translate_address(struct device_node *dev, const __be32 *in_addr,
 			   const char *rprop)
 {
 	struct device_node *parent = NULL;
@@ -475,22 +477,22 @@ u64 __of_translate_address(struct device_node *dev, const u32 *in_addr,
 	return result;
 }
 
-u64 of_translate_address(struct device_node *dev, const u32 *in_addr)
+u64 of_translate_address(struct device_node *dev, const __be32 *in_addr)
 {
 	return __of_translate_address(dev, in_addr, "ranges");
 }
 EXPORT_SYMBOL(of_translate_address);
 
-u64 of_translate_dma_address(struct device_node *dev, const u32 *in_addr)
+u64 of_translate_dma_address(struct device_node *dev, const __be32 *in_addr)
 {
 	return __of_translate_address(dev, in_addr, "dma-ranges");
 }
 EXPORT_SYMBOL(of_translate_dma_address);
 
-const u32 *of_get_address(struct device_node *dev, int index, u64 *size,
+const __be32 *of_get_address(struct device_node *dev, int index, u64 *size,
 		    unsigned int *flags)
 {
-	const u32 *prop;
+	const __be32 *prop;
 	unsigned int psize;
 	struct device_node *parent;
 	struct of_bus *bus;
@@ -525,8 +527,8 @@ const u32 *of_get_address(struct device_node *dev, int index, u64 *size,
 }
 EXPORT_SYMBOL(of_get_address);
 
-static int __of_address_to_resource(struct device_node *dev, const u32 *addrp,
-				    u64 size, unsigned int flags,
+static int __of_address_to_resource(struct device_node *dev,
+		const __be32 *addrp, u64 size, unsigned int flags,
 				    struct resource *r)
 {
 	u64 taddr;
@@ -564,7 +566,7 @@ static int __of_address_to_resource(struct device_node *dev, const u32 *addrp,
 int of_address_to_resource(struct device_node *dev, int index,
 			   struct resource *r)
 {
-	const u32	*addrp;
+	const __be32	*addrp;
 	u64		size;
 	unsigned int	flags;
 
diff --git a/include/linux/of_address.h b/include/linux/of_address.h
index 8aea06f..2feda6e 100644
--- a/include/linux/of_address.h
+++ b/include/linux/of_address.h
@@ -3,7 +3,7 @@
 #include <linux/ioport.h>
 #include <linux/of.h>
 
-extern u64 of_translate_address(struct device_node *np, const u32 *addr);
+extern u64 of_translate_address(struct device_node *np, const __be32 *addr);
 extern int of_address_to_resource(struct device_node *dev, int index,
 				  struct resource *r);
 extern void __iomem *of_iomap(struct device_node *device, int index);
@@ -21,7 +21,7 @@ static inline unsigned long pci_address_to_pio(phys_addr_t addr) { return -1; }
 #endif
 
 #ifdef CONFIG_PCI
-extern const u32 *of_get_pci_address(struct device_node *dev, int bar_no,
+extern const __be32 *of_get_pci_address(struct device_node *dev, int bar_no,
 			       u64 *size, unsigned int *flags);
 extern int of_pci_address_to_resource(struct device_node *dev, int bar,
 				      struct resource *r);
@@ -32,7 +32,7 @@ static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
 	return -ENOSYS;
 }
 
-static inline const u32 *of_get_pci_address(struct device_node *dev,
+static inline const __be32 *of_get_pci_address(struct device_node *dev,
 		int bar_no, u64 *size, unsigned int *flags)
 {
 	return NULL;
-- 
1.7.3.2


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 12/15] of/address: use propper endianess in get_flags
@ 2010-12-17 15:33   ` Sebastian Andrzej Siewior
  0 siblings, 0 replies; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2010-12-17 15:33 UTC (permalink / raw)
  To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
  Cc: sodaville-hfZtesqFncYOwBW4kG4KsQ, Sebastian Andrzej Siewior,
	x86-DgEjT+Ai2ygdnm+yROfE0A,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ

This patch changes u32 to __be32 for all "ranges", "prop" and "addr" and
such. Those variables are pointing to the device tree which containts
intergers in big endian format.
Most functions are doing it right because they are using using
of_read_number() which is doing the right thing. of_bus_isa_get_flags(),
of_bus_pci_get_flags() and of_bus_isa_map() were accessing the data
directly and were doing it wrong.

Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
Acked-by: Benjamin Herrenschmidt <benh-XVmvHMARGAS8U2dJNN8I7kB+6BGkLq7r@public.gmane.org>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
---
 arch/powerpc/include/asm/prom.h |    2 +-
 drivers/of/address.c            |   54 ++++++++++++++++++++------------------
 include/linux/of_address.h      |    6 ++--
 3 files changed, 32 insertions(+), 30 deletions(-)

diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h
index 01c3302..b891fdc 100644
--- a/arch/powerpc/include/asm/prom.h
+++ b/arch/powerpc/include/asm/prom.h
@@ -42,7 +42,7 @@ extern void pci_create_OF_bus_map(void);
 
 /* Translate a DMA address from device space to CPU space */
 extern u64 of_translate_dma_address(struct device_node *dev,
-				    const u32 *in_addr);
+				    const __be32 *in_addr);
 
 #ifdef CONFIG_PCI
 extern unsigned long pci_address_to_pio(phys_addr_t address);
diff --git a/drivers/of/address.c b/drivers/of/address.c
index 3a1c7e7..b4559c5 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -12,13 +12,13 @@
 			(ns) > 0)
 
 static struct of_bus *of_match_bus(struct device_node *np);
-static int __of_address_to_resource(struct device_node *dev, const u32 *addrp,
-				    u64 size, unsigned int flags,
+static int __of_address_to_resource(struct device_node *dev,
+		const __be32 *addrp, u64 size, unsigned int flags,
 				    struct resource *r);
 
 /* Debug utility */
 #ifdef DEBUG
-static void of_dump_addr(const char *s, const u32 *addr, int na)
+static void of_dump_addr(const char *s, const __be32 *addr, int na)
 {
 	printk(KERN_DEBUG "%s", s);
 	while (na--)
@@ -26,7 +26,7 @@ static void of_dump_addr(const char *s, const u32 *addr, int na)
 	printk("\n");
 }
 #else
-static void of_dump_addr(const char *s, const u32 *addr, int na) { }
+static void of_dump_addr(const char *s, const __be32 *addr, int na) { }
 #endif
 
 /* Callbacks for bus specific translators */
@@ -36,10 +36,10 @@ struct of_bus {
 	int		(*match)(struct device_node *parent);
 	void		(*count_cells)(struct device_node *child,
 				       int *addrc, int *sizec);
-	u64		(*map)(u32 *addr, const u32 *range,
+	u64		(*map)(u32 *addr, const __be32 *range,
 				int na, int ns, int pna);
 	int		(*translate)(u32 *addr, u64 offset, int na);
-	unsigned int	(*get_flags)(const u32 *addr);
+	unsigned int	(*get_flags)(const __be32 *addr);
 };
 
 /*
@@ -55,7 +55,7 @@ static void of_bus_default_count_cells(struct device_node *dev,
 		*sizec = of_n_size_cells(dev);
 }
 
-static u64 of_bus_default_map(u32 *addr, const u32 *range,
+static u64 of_bus_default_map(u32 *addr, const __be32 *range,
 		int na, int ns, int pna)
 {
 	u64 cp, s, da;
@@ -85,7 +85,7 @@ static int of_bus_default_translate(u32 *addr, u64 offset, int na)
 	return 0;
 }
 
-static unsigned int of_bus_default_get_flags(const u32 *addr)
+static unsigned int of_bus_default_get_flags(const __be32 *addr)
 {
 	return IORESOURCE_MEM;
 }
@@ -110,10 +110,10 @@ static void of_bus_pci_count_cells(struct device_node *np,
 		*sizec = 2;
 }
 
-static unsigned int of_bus_pci_get_flags(const u32 *addr)
+static unsigned int of_bus_pci_get_flags(const __be32 *addr)
 {
 	unsigned int flags = 0;
-	u32 w = addr[0];
+	u32 w = be32_to_cpup(addr);
 
 	switch((w >> 24) & 0x03) {
 	case 0x01:
@@ -129,7 +129,8 @@ static unsigned int of_bus_pci_get_flags(const u32 *addr)
 	return flags;
 }
 
-static u64 of_bus_pci_map(u32 *addr, const u32 *range, int na, int ns, int pna)
+static u64 of_bus_pci_map(u32 *addr, const __be32 *range, int na, int ns,
+		int pna)
 {
 	u64 cp, s, da;
 	unsigned int af, rf;
@@ -160,7 +161,7 @@ static int of_bus_pci_translate(u32 *addr, u64 offset, int na)
 	return of_bus_default_translate(addr + 1, offset, na - 1);
 }
 
-const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
+const __be32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
 			unsigned int *flags)
 {
 	const __be32 *prop;
@@ -207,7 +208,7 @@ EXPORT_SYMBOL(of_get_pci_address);
 int of_pci_address_to_resource(struct device_node *dev, int bar,
 			       struct resource *r)
 {
-	const u32	*addrp;
+	const __be32	*addrp;
 	u64		size;
 	unsigned int	flags;
 
@@ -237,12 +238,13 @@ static void of_bus_isa_count_cells(struct device_node *child,
 		*sizec = 1;
 }
 
-static u64 of_bus_isa_map(u32 *addr, const u32 *range, int na, int ns, int pna)
+static u64 of_bus_isa_map(u32 *addr, const __be32 *range, int na, int ns,
+		int pna)
 {
 	u64 cp, s, da;
 
 	/* Check address type match */
-	if ((addr[0] ^ range[0]) & 0x00000001)
+	if ((addr[0] ^ range[0]) & cpu_to_be32(1))
 		return OF_BAD_ADDR;
 
 	/* Read address values, skipping high cell */
@@ -264,10 +266,10 @@ static int of_bus_isa_translate(u32 *addr, u64 offset, int na)
 	return of_bus_default_translate(addr + 1, offset, na - 1);
 }
 
-static unsigned int of_bus_isa_get_flags(const u32 *addr)
+static unsigned int of_bus_isa_get_flags(const __be32 *addr)
 {
 	unsigned int flags = 0;
-	u32 w = addr[0];
+	u32 w = be32_to_cpup(addr);
 
 	if (w & 1)
 		flags |= IORESOURCE_IO;
@@ -330,7 +332,7 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus,
 			    struct of_bus *pbus, u32 *addr,
 			    int na, int ns, int pna, const char *rprop)
 {
-	const u32 *ranges;
+	const __be32 *ranges;
 	unsigned int rlen;
 	int rone;
 	u64 offset = OF_BAD_ADDR;
@@ -398,7 +400,7 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus,
  * that can be mapped to a cpu physical address). This is not really specified
  * that way, but this is traditionally the way IBM at least do things
  */
-u64 __of_translate_address(struct device_node *dev, const u32 *in_addr,
+u64 __of_translate_address(struct device_node *dev, const __be32 *in_addr,
 			   const char *rprop)
 {
 	struct device_node *parent = NULL;
@@ -475,22 +477,22 @@ u64 __of_translate_address(struct device_node *dev, const u32 *in_addr,
 	return result;
 }
 
-u64 of_translate_address(struct device_node *dev, const u32 *in_addr)
+u64 of_translate_address(struct device_node *dev, const __be32 *in_addr)
 {
 	return __of_translate_address(dev, in_addr, "ranges");
 }
 EXPORT_SYMBOL(of_translate_address);
 
-u64 of_translate_dma_address(struct device_node *dev, const u32 *in_addr)
+u64 of_translate_dma_address(struct device_node *dev, const __be32 *in_addr)
 {
 	return __of_translate_address(dev, in_addr, "dma-ranges");
 }
 EXPORT_SYMBOL(of_translate_dma_address);
 
-const u32 *of_get_address(struct device_node *dev, int index, u64 *size,
+const __be32 *of_get_address(struct device_node *dev, int index, u64 *size,
 		    unsigned int *flags)
 {
-	const u32 *prop;
+	const __be32 *prop;
 	unsigned int psize;
 	struct device_node *parent;
 	struct of_bus *bus;
@@ -525,8 +527,8 @@ const u32 *of_get_address(struct device_node *dev, int index, u64 *size,
 }
 EXPORT_SYMBOL(of_get_address);
 
-static int __of_address_to_resource(struct device_node *dev, const u32 *addrp,
-				    u64 size, unsigned int flags,
+static int __of_address_to_resource(struct device_node *dev,
+		const __be32 *addrp, u64 size, unsigned int flags,
 				    struct resource *r)
 {
 	u64 taddr;
@@ -564,7 +566,7 @@ static int __of_address_to_resource(struct device_node *dev, const u32 *addrp,
 int of_address_to_resource(struct device_node *dev, int index,
 			   struct resource *r)
 {
-	const u32	*addrp;
+	const __be32	*addrp;
 	u64		size;
 	unsigned int	flags;
 
diff --git a/include/linux/of_address.h b/include/linux/of_address.h
index 8aea06f..2feda6e 100644
--- a/include/linux/of_address.h
+++ b/include/linux/of_address.h
@@ -3,7 +3,7 @@
 #include <linux/ioport.h>
 #include <linux/of.h>
 
-extern u64 of_translate_address(struct device_node *np, const u32 *addr);
+extern u64 of_translate_address(struct device_node *np, const __be32 *addr);
 extern int of_address_to_resource(struct device_node *dev, int index,
 				  struct resource *r);
 extern void __iomem *of_iomap(struct device_node *device, int index);
@@ -21,7 +21,7 @@ static inline unsigned long pci_address_to_pio(phys_addr_t addr) { return -1; }
 #endif
 
 #ifdef CONFIG_PCI
-extern const u32 *of_get_pci_address(struct device_node *dev, int bar_no,
+extern const __be32 *of_get_pci_address(struct device_node *dev, int bar_no,
 			       u64 *size, unsigned int *flags);
 extern int of_pci_address_to_resource(struct device_node *dev, int bar,
 				      struct resource *r);
@@ -32,7 +32,7 @@ static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
 	return -ENOSYS;
 }
 
-static inline const u32 *of_get_pci_address(struct device_node *dev,
+static inline const __be32 *of_get_pci_address(struct device_node *dev,
 		int bar_no, u64 *size, unsigned int *flags)
 {
 	return NULL;
-- 
1.7.3.2

^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 13/15] x86/rtc: don't register rtc if we have an OF node for it
  2010-12-17 15:33 Add device tree support for x86, v2 Sebastian Andrzej Siewior
                   ` (11 preceding siblings ...)
  2010-12-17 15:33   ` Sebastian Andrzej Siewior
@ 2010-12-17 15:33 ` Sebastian Andrzej Siewior
  2010-12-30  8:59   ` Grant Likely
  2010-12-17 15:33   ` Sebastian Andrzej Siewior
  2010-12-17 15:33 ` [PATCH 15/15] x86/pci: remove warning Sebastian Andrzej Siewior
  14 siblings, 1 reply; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2010-12-17 15:33 UTC (permalink / raw)
  To: linux-kernel; +Cc: sodaville, x86, dirk.brandewie, Sebastian Andrzej Siewior

or we end up with two of those things.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
 arch/x86/kernel/rtc.c |   23 +++++++++++++++++++++++
 1 files changed, 23 insertions(+), 0 deletions(-)

diff --git a/arch/x86/kernel/rtc.c b/arch/x86/kernel/rtc.c
index 1cfbbfc..382c6cb 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>
@@ -218,6 +219,25 @@ static struct platform_device rtc_device = {
 	.num_resources	= ARRAY_SIZE(rtc_resources),
 };
 
+#ifdef CONFIG_OF
+static __init int have_rtc_of_node(void)
+{
+	struct device_node *n;
+
+	n = of_find_compatible_node(NULL, NULL, "motorola,mc146818");
+	if (n) {
+		of_node_put(n);
+		return 1;
+	}
+	return 0;
+}
+#else
+static inline int have_rtc_of_node(void)
+{
+	return 0;
+}
+#endif
+
 static __init int add_rtc_cmos(void)
 {
 #ifdef CONFIG_PNP
@@ -237,6 +257,9 @@ static __init int add_rtc_cmos(void)
 	}
 #endif
 
+	if (have_rtc_of_node())
+		return 0;
+
 	platform_device_register(&rtc_device);
 	dev_info(&rtc_device.dev,
 		 "registered platform RTC device (no PNP device found)\n");
-- 
1.7.3.2


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 14/15] rtc/cmos: add OF bindings
@ 2010-12-17 15:33   ` Sebastian Andrzej Siewior
  0 siblings, 0 replies; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2010-12-17 15:33 UTC (permalink / raw)
  To: linux-kernel
  Cc: sodaville, x86, dirk.brandewie, Sebastian Andrzej Siewior,
	rtc-linux, Alessandro Zummo, devicetree-discuss

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.

Cc: rtc-linux@googlegroups.com
Cc: Alessandro Zummo <a.zummo@towertech.it>
Cc: devicetree-discuss@lists.ozlabs.org
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Dirk Brandewie <dirk.brandewie@gmail.com>
---
 Documentation/powerpc/dts-bindings/rtc-cmos.txt |   28 ++++++++++++++++
 drivers/rtc/rtc-cmos.c                          |   40 +++++++++++++++++++++++
 2 files changed, 68 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/powerpc/dts-bindings/rtc-cmos.txt

diff --git a/Documentation/powerpc/dts-bindings/rtc-cmos.txt b/Documentation/powerpc/dts-bindings/rtc-cmos.txt
new file mode 100644
index 0000000..7382989
--- /dev/null
+++ b/Documentation/powerpc/dts-bindings/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/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
index 5856167..8cf0049 100644
--- a/drivers/rtc/rtc-cmos.c
+++ b/drivers/rtc/rtc-cmos.c
@@ -36,6 +36,8 @@
 #include <linux/platform_device.h>
 #include <linux/mod_devicetable.h>
 #include <linux/log2.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>
@@ -1121,6 +1123,15 @@ 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);
+#endif
 /*----------------------------------------------------------------*/
 
 /* Platform setup should have set up an RTC device, when PNP is
@@ -1129,6 +1140,32 @@ static struct pnp_driver cmos_pnp_driver = {
 
 static int __init cmos_platform_probe(struct platform_device *pdev)
 {
+#ifdef CONFIG_OF
+	if (pdev->dev.of_node) {
+		struct device_node *node = pdev->dev.of_node;
+		struct rtc_time time;
+		int ret;
+		const __be32 *val;
+
+		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);
+		}
+	}
+#endif
 	cmos_wake_setup(&pdev->dev);
 	return cmos_do_probe(&pdev->dev,
 			platform_get_resource(pdev, IORESOURCE_IO, 0),
@@ -1157,6 +1194,9 @@ static struct platform_driver cmos_platform_driver = {
 	.shutdown	= cmos_platform_shutdown,
 	.driver = {
 		.name		= (char *) driver_name,
+#if defined(CONFIG_OF)
+		.of_match_table = of_cmos_match,
+#endif
 		.suspend	= cmos_suspend,
 		.resume		= cmos_resume,
 	}
-- 
1.7.3.2


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 14/15] rtc/cmos: add OF bindings
@ 2010-12-17 15:33   ` Sebastian Andrzej Siewior
  0 siblings, 0 replies; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2010-12-17 15:33 UTC (permalink / raw)
  To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
  Cc: Alessandro Zummo, rtc-linux-/JYPxA39Uh5TLH3MbocFFw,
	Sebastian Andrzej Siewior, x86-DgEjT+Ai2ygdnm+yROfE0A,
	sodaville-hfZtesqFncYOwBW4kG4KsQ,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ

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.

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/powerpc/dts-bindings/rtc-cmos.txt |   28 ++++++++++++++++
 drivers/rtc/rtc-cmos.c                          |   40 +++++++++++++++++++++++
 2 files changed, 68 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/powerpc/dts-bindings/rtc-cmos.txt

diff --git a/Documentation/powerpc/dts-bindings/rtc-cmos.txt b/Documentation/powerpc/dts-bindings/rtc-cmos.txt
new file mode 100644
index 0000000..7382989
--- /dev/null
+++ b/Documentation/powerpc/dts-bindings/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/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
index 5856167..8cf0049 100644
--- a/drivers/rtc/rtc-cmos.c
+++ b/drivers/rtc/rtc-cmos.c
@@ -36,6 +36,8 @@
 #include <linux/platform_device.h>
 #include <linux/mod_devicetable.h>
 #include <linux/log2.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>
@@ -1121,6 +1123,15 @@ 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);
+#endif
 /*----------------------------------------------------------------*/
 
 /* Platform setup should have set up an RTC device, when PNP is
@@ -1129,6 +1140,32 @@ static struct pnp_driver cmos_pnp_driver = {
 
 static int __init cmos_platform_probe(struct platform_device *pdev)
 {
+#ifdef CONFIG_OF
+	if (pdev->dev.of_node) {
+		struct device_node *node = pdev->dev.of_node;
+		struct rtc_time time;
+		int ret;
+		const __be32 *val;
+
+		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);
+		}
+	}
+#endif
 	cmos_wake_setup(&pdev->dev);
 	return cmos_do_probe(&pdev->dev,
 			platform_get_resource(pdev, IORESOURCE_IO, 0),
@@ -1157,6 +1194,9 @@ static struct platform_driver cmos_platform_driver = {
 	.shutdown	= cmos_platform_shutdown,
 	.driver = {
 		.name		= (char *) driver_name,
+#if defined(CONFIG_OF)
+		.of_match_table = of_cmos_match,
+#endif
 		.suspend	= cmos_suspend,
 		.resume		= cmos_resume,
 	}
-- 
1.7.3.2

^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH 15/15] x86/pci: remove warning
  2010-12-17 15:33 Add device tree support for x86, v2 Sebastian Andrzej Siewior
                   ` (13 preceding siblings ...)
  2010-12-17 15:33   ` Sebastian Andrzej Siewior
@ 2010-12-17 15:33 ` Sebastian Andrzej Siewior
  2011-02-18 16:06   ` [tip:x86/platform] x86/pci: Remove unused variable tip-bot for Sebastian Andrzej Siewior
  14 siblings, 1 reply; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2010-12-17 15:33 UTC (permalink / raw)
  To: linux-kernel; +Cc: sodaville, x86, dirk.brandewie, Sebastian Andrzej Siewior

|arch/x86/pci/ce4100.c: In function `ce4100_conf_read':
|arch/x86/pci/ce4100.c:257:9: warning: unused variable `retval'

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
 arch/x86/pci/ce4100.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/x86/pci/ce4100.c b/arch/x86/pci/ce4100.c
index 85b68ef..c63c6d3 100644
--- a/arch/x86/pci/ce4100.c
+++ b/arch/x86/pci/ce4100.c
@@ -254,7 +254,7 @@ int bridge_read(unsigned int devfn, int reg, int len, u32 *value)
 static int ce4100_conf_read(unsigned int seg, unsigned int bus,
 			    unsigned int devfn, int reg, int len, u32 *value)
 {
-	int i, retval = 1;
+	int i;
 
 	if (bus == 1) {
 		for (i = 0; i < ARRAY_SIZE(bus1_fixups); i++) {
-- 
1.7.3.2


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* Re: [PATCH 07/15] of: move of_irq_map_pci() into generic code
  2010-12-17 15:33   ` Sebastian Andrzej Siewior
  (?)
@ 2010-12-17 21:16   ` Benjamin Herrenschmidt
  2011-01-04 14:27       ` Sebastian Andrzej Siewior
  -1 siblings, 1 reply; 106+ messages in thread
From: Benjamin Herrenschmidt @ 2010-12-17 21:16 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: linux-kernel, sodaville, x86, dirk.brandewie,
	Sebastian Andrzej Siewior, devicetree-discuss

On Fri, 2010-12-17 at 16:33 +0100, Sebastian Andrzej Siewior wrote:
> +
> +#if defined(CONFIG_PPC64) || defined(CONFIG_X86)
> +static struct device_node *pci_get_parent_node(struct pci_dev *pdev)
> +{
> +       return pci_bus_to_OF_node(pdev->bus);
> +}
> +#endif
> +
> +#if defined(CONFIG_PPC32) || defined(CONFIG_MICROBLAZE)
> +static struct device_node *pci_get_parent_node(struct pci_dev *pdev)
> +{
> +       struct pci_controller *host;
> +
> +       host = pci_bus_to_host(pdev->bus);
> +       return host ? host->dn : NULL;
> +}
> +#endif
> + 

I'd like it better if instead you added pci_bus_to_OF_node() to ppc32
and microblaze.

The easy way to do so is to do:

	struct pci_controller *host;

	if (bus->self)
		return pci_device_to_OF_node(bus->self);
	host = pci_bus_to_host(pdev->bus);
	return host ? host->dn : NULL;

Cheers,
Ben.



^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 01/15] x86/e820: remove conditional early mapping in parse_e820_ext
  2010-12-17 15:33 ` [PATCH 01/15] x86/e820: remove conditional early mapping in parse_e820_ext Sebastian Andrzej Siewior
@ 2010-12-30  8:37   ` Grant Likely
  2011-01-04 13:08     ` [PATCH v2 " Sebastian Andrzej Siewior
  0 siblings, 1 reply; 106+ messages in thread
From: Grant Likely @ 2010-12-30  8:37 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior; +Cc: linux-kernel, sodaville, x86, dirk.brandewie

On Fri, Dec 17, 2010 at 04:33:39PM +0100, Sebastian Andrzej Siewior wrote:
> This patch ensures that the memory passed from parse_setup_data() is
> large enough to cover the complete data structure. That means that the
> conditional mapping in parse_e820_ext() can go.
> 
> While here, I also attempt not to map two pages if the address is not
> aligned to a page boundary.
> 
> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> Signed-off-by: Dirk Brandewie <dirk.brandewie@gmail.com>
> ---

I assume this patch is a prereq for the rest of the series.  Should I
merge it via the devicetree tree when I pick up the other patches?

It looks okay to me.  One comment below, but not one that would prevent
picking up this patch.

g.

>  arch/x86/include/asm/e820.h |    2 +-
>  arch/x86/kernel/e820.c      |    8 +-------
>  arch/x86/kernel/setup.c     |   20 +++++++++++++++++---
>  3 files changed, 19 insertions(+), 11 deletions(-)
> 
> diff --git a/arch/x86/include/asm/e820.h b/arch/x86/include/asm/e820.h
> index 5be1542..e956492 100644
> --- a/arch/x86/include/asm/e820.h
> +++ b/arch/x86/include/asm/e820.h
> @@ -93,7 +93,7 @@ extern void e820_setup_gap(void);
>  extern int e820_search_gap(unsigned long *gapstart, unsigned long *gapsize,
>  			unsigned long start_addr, unsigned long long end_addr);
>  struct setup_data;
> -extern void parse_e820_ext(struct setup_data *data, unsigned long pa_data);
> +extern void parse_e820_ext(struct setup_data *data);
>  
>  #if defined(CONFIG_X86_64) || \
>  	(defined(CONFIG_X86_32) && defined(CONFIG_HIBERNATION))
> diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
> index 0c2b7ef..33f6361 100644
> --- a/arch/x86/kernel/e820.c
> +++ b/arch/x86/kernel/e820.c
> @@ -666,21 +666,15 @@ __init void e820_setup_gap(void)
>   * boot_params.e820_map, others are passed via SETUP_E820_EXT node of
>   * linked list of struct setup_data, which is parsed here.
>   */
> -void __init parse_e820_ext(struct setup_data *sdata, unsigned long pa_data)
> +void __init parse_e820_ext(struct setup_data *sdata)
>  {
> -	u32 map_len;
>  	int entries;
>  	struct e820entry *extmap;
>  
>  	entries = sdata->len / sizeof(struct e820entry);
> -	map_len = sdata->len + sizeof(struct setup_data);
> -	if (map_len > PAGE_SIZE)
> -		sdata = early_ioremap(pa_data, map_len);
>  	extmap = (struct e820entry *)(sdata->data);
>  	__append_e820_map(extmap, entries);
>  	sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
> -	if (map_len > PAGE_SIZE)
> -		early_iounmap(sdata, map_len);
>  	printk(KERN_INFO "extended physical RAM map:\n");
>  	e820_print_map("extended");
>  }
> diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
> index 0afb8c7..577d06b 100644
> --- a/arch/x86/kernel/setup.c
> +++ b/arch/x86/kernel/setup.c
> @@ -429,16 +429,30 @@ static void __init parse_setup_data(void)
>  		return;
>  	pa_data = boot_params.hdr.setup_data;
>  	while (pa_data) {
> -		data = early_memremap(pa_data, PAGE_SIZE);
> +		u32 data_len;
> +		u32 map_len;
> +
> +		map_len = max(PAGE_SIZE - (pa_data & ~PAGE_MASK),
> +				(u64)sizeof(struct setup_data));
> +		data = early_memremap(pa_data, map_len);
> +		data_len = data->len + sizeof(struct setup_data);
> +		if (data_len > map_len) {
> +			early_iounmap(data, map_len);
> +			data = early_memremap(pa_data, data_len);

if you add
+			map_len = data_len;
then...

> +		}
> +
>  		switch (data->type) {
>  		case SETUP_E820_EXT:
> -			parse_e820_ext(data, pa_data);
> +			parse_e820_ext(data);
>  			break;
>  		default:
>  			break;
>  		}
>  		pa_data = data->next;
> -		early_iounmap(data, PAGE_SIZE);
> +		if (data_len > map_len)
> +			early_iounmap(data, data_len);
> +		else
> +			early_iounmap(data, map_len);

...this can be simplified to:

-		early_iounmap(data, PAGE_SIZE);
+		early_iounmap(data, map_len);

>  	}
>  }
>  
> -- 
> 1.7.3.2
> 
> --
> 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/

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 02/15] x86: Add device tree support
  2010-12-17 15:33   ` Sebastian Andrzej Siewior
  (?)
@ 2010-12-30  8:43   ` Grant Likely
  2010-12-30 21:01       ` Grant Likely
  2011-01-03 12:20       ` Sebastian Andrzej Siewior
  -1 siblings, 2 replies; 106+ messages in thread
From: Grant Likely @ 2010-12-30  8:43 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: linux-kernel, sodaville, x86, devicetree-discuss

On Fri, Dec 17, 2010 at 04:33:40PM +0100, Sebastian Andrzej Siewior wrote:
> 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@lists.ozlabs.org
> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> Signed-off-by: Dirk Brandewie <dirk.brandewie@gmail.com>

Mostly looks good. Some comments below.

g.

> ---
>  Documentation/x86/boot_with_dtb.txt |   26 +++++++++++++++
>  arch/x86/Kconfig                    |    7 ++++
>  arch/x86/include/asm/bootparam.h    |    1 +
>  arch/x86/include/asm/prom.h         |   59 +++++++++++++++++++++++++++++++++++
>  arch/x86/kernel/Makefile            |    1 +
>  arch/x86/kernel/irqinit.c           |    1 +
>  arch/x86/kernel/prom.c              |   54 ++++++++++++++++++++++++++++++++
>  arch/x86/kernel/setup.c             |    4 ++
>  8 files changed, 153 insertions(+), 0 deletions(-)
>  create mode 100644 Documentation/x86/boot_with_dtb.txt
>  create mode 100644 arch/x86/include/asm/prom.h
>  create mode 100644 arch/x86/kernel/prom.c
> 
> diff --git a/Documentation/x86/boot_with_dtb.txt b/Documentation/x86/boot_with_dtb.txt
> new file mode 100644
> index 0000000..6a357aa
> --- /dev/null
> +++ b/Documentation/x86/boot_with_dtb.txt
> @@ -0,0 +1,26 @@
> +  Booting x86 with device tree
> +=================================
> +
> +1. Introduction
> +~~~~~~~~~~~~~~~
> +This document contains device tree information which are specific to
> +the x86 platform. Generic informations as bindings can be found in
> +Documentation/powerpc/dts-bindings/
> +
> +2. Passing the device tree
> +~~~~~~~~~~~~~~~~~~~~~~~~~~
> +The pointer to the device tree block (dtb) is passed via setup_data
> +(see [0]) which requires at least boot protocol 2.09. The type filed is
> +defined as
> +
> +#define SETUP_DTB                      2
> +
> +3. Purpose
> +~~~~~~~~~~~
> +The device tree is used as an extension to the "boot page". As such it does not
> +parse / consider data which are already covered by the boot page. This includes
> +memory size, 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.
> +
> +[0] Documentation/x86/boot.txt
> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
> index b6fccb0..0522354 100644
> --- a/arch/x86/Kconfig
> +++ b/arch/x86/Kconfig
> @@ -299,6 +299,13 @@ config X86_BIGSMP
>  	---help---
>  	  This option is needed for the systems that have more than 8 CPUs
>  
> +config X86_OF
> +	bool "Support for device tree"
> +	select OF
> +	select OF_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/prom.h b/arch/x86/include/asm/prom.h
> new file mode 100644
> index 0000000..2fbe3e8
> --- /dev/null
> +++ b/arch/x86/include/asm/prom.h
> @@ -0,0 +1,59 @@
> +/*
> + * 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];
> +/* This number is used when no interrupt has been assigned */
> +#define NO_IRQ		(-1)

0 means NO_IRQ on x86 and most architectures.  I will change this when
I pick up the patch.

> +
> +#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__ */
> +
> +/*
> + * These includes are put at the bottom because they may contain things
> + * that are overridden by this file.  Ideally they shouldn't be included
> + * by this file, but there are a bunch of .c files that currently depend
> + * on it.  Eventually they will be cleaned up.
> + */
> +#include <linux/of_fdt.h>
> +#include <linux/of_irq.h>
> +#include <linux/platform_device.h>
> +
> +#endif
> diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
> index f60153d..40bc33d 100644
> --- a/arch/x86/kernel/Makefile
> +++ b/arch/x86/kernel/Makefile
> @@ -108,6 +108,7 @@ obj-$(CONFIG_MICROCODE)			+= microcode.o
>  obj-$(CONFIG_X86_CHECK_BIOS_CORRUPTION) += check.o
>  
>  obj-$(CONFIG_SWIOTLB)			+= pci-swiotlb.o
> +obj-$(CONFIG_X86_OF)			+= prom.o
>  
>  ###
>  # 64 bit specific files
> diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c
> index c752e97..149c87f 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:
> diff --git a/arch/x86/kernel/prom.c b/arch/x86/kernel/prom.c
> new file mode 100644
> index 0000000..249ebd3
> --- /dev/null
> +++ b/arch/x86/kernel/prom.c
> @@ -0,0 +1,54 @@
> +/*
> + * Architecture specific OF callbacks.
> + */
> +#include <linux/bootmem.h>
> +#include <linux/io.h>
> +#include <linux/list.h>
> +#include <linux/of.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();
> +}
> +
> +u64 __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
> +{
> +	void *mem;
> +
> +	mem = __alloc_bootmem(size, align, __pa(MAX_DMA_ADDRESS));
> +	return virt_to_phys(mem);
> +}
> +
> +void __init add_dtb(u64 data)
> +{
> +	initial_boot_params = (struct boot_param_header *)
> +		phys_to_virt((u64) (u32) data +
> +				offsetof(struct setup_data, data));
> +}
> diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
> index 577d06b..26f2c9a 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.
> @@ -445,6 +446,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;

Why is the physical address being passed in when the virtual address
is needed to be stored in initial_boot_params by add_dtb()?


>  		default:
>  			break;
>  		}
> -- 
> 1.7.3.2
> 
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 03/15] x86/dtb: Add a device tree for CE4100
@ 2010-12-30  8:51     ` Grant Likely
  0 siblings, 0 replies; 106+ messages in thread
From: Grant Likely @ 2010-12-30  8:51 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: linux-kernel, sodaville, x86, devicetree-discuss

On Fri, Dec 17, 2010 at 04:33:41PM +0100, Sebastian Andrzej Siewior wrote:
> 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/platform/ce4100/falconfalls.dts |  212 ++++++++++++++++++++++++++++++
>  1 files changed, 212 insertions(+), 0 deletions(-)
>  create mode 100644 arch/x86/platform/ce4100/falconfalls.dts
> 
> diff --git a/arch/x86/platform/ce4100/falconfalls.dts b/arch/x86/platform/ce4100/falconfalls.dts
> new file mode 100644
> index 0000000..24e67ca
> --- /dev/null
> +++ b/arch/x86/platform/ce4100/falconfalls.dts
> @@ -0,0 +1,212 @@
> +/*
> + * 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";

To-date the convention has been to use all lowercase in compatible
properties.  Ditto throughout this file.

> +	#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>;
> +		device_type = "soc";

Drop device_type property.

> +		compatible = "Intel,ce4100";
> +		ranges;
> +
> +		ioapic1: pic@fec00000 {
> +			#interrupt-cells = <2>;
> +			compatible = "Intel,ioapic";
> +			interrupt-controller;
> +			device_type = "interrupt-controller";

Ditto

> +			id = <1>;
> +			reg = <0xfec00000 0x1000>;
> +		};
> +
> +		hpet@fed00000 {
> +			compatible = "Intel,hpet-ce4100", "Intel,hpet";
> +			reg = <0xfed00000 0x200>;
> +		};
> +
> +		lapic0: lapic@fee00000 {
> +			compatible = "Intel,lapic-ce4100", "Intel,lapic";
> +			reg = <0xfee00000 0x1000>;
> +		};
> +
> +		pci@3fc {
> +			#address-cells = <3>;
> +			#interrupt-cells = <1>;
> +			#size-cells = <2>;
> +			compatible = "Intel,ce4100-pci", "pci";
> +			device_type = "pci";

I'd like to say ditto here, but it might require a change to the
current kernel code.  I believe ePAPR specified a compatible value
alternative to 'device_type = "pci";'.

> +			bus-range = <0 0>;
> +			ranges = <0x2000000 0 0xbffff000 0xbffff000 0 0x1000
> +				  0x0000000 0 0x0	 0x0	    0 0x100>;
> +
> +			isa@0 {
> +				#address-cells = <2>;
> +				#size-cells = <1>;
> +				compatible = "isa";
> +				ranges = <1 0 0 0 0 0x100>;
> +
> +				rtc@70 {
> +					compatible = "motorola,mc146818";
> +					interrupts = <8 3>;
> +					interrupt-parent = <&ioapic1>;

If you put an interrupt-parent property in the root node, then it will
become the default interrupt controller for the system which is
usually convenient to have.

> +					ctrl-reg = <2>;
> +					freq-reg = <0x26>;
> +					reg = <1 0x70 2>;
> +				};
> +			};
> +
> +			/* Secondary IO-APIC */
> +			ioapic2: pic@bffff000 {
> +				#interrupt-cells = <2>;
> +				compatible = "Intel,ioapic-ce4100", "Intel,ioapic";
> +				interrupt-controller;
> +				device_type = "interrupt-controller";

Drop device_type.

> +				id = <2>;
> +				reg = <0x100 0x0 0x0 0x0 0x0>;
> +				assigned-addresses = <0x02000000 0x0 0xbffff000 0x0 0x1000>;
> +			};
> +
> +			pci@av {
> +				#address-cells = <3>;
> +				#interrupt-cells = <1>;
> +				#size-cells = <1>;
> +				compatible = "Intel,ce4100-pci";
> +				device_type = "pci";
> +				bus-range = <1 1>;
> +				interrupt-map-mask = <0xffffff 0x0 0x0 0x0>;
> +				interrupt-map = <
> +					/* GFX: 0x2E5B */
> +					0x11000 0x0 0x0 0x0 &ioapic2 0 0x1
> +					/* ***** FIXME ****** Compositing Engine: 0x2E72 */
> +					/* 0x11100 0x0 0x0 0x1 &ioapic2 0 0x1 */
> +					/* MFD: 0x2E5C */
> +					0x11800 0x0 0x0 0x0 &ioapic2 2 0x1
> +					/* TS Prefilter: 0x2E5D */
> +					0x12000 0x0 0x0 0x0 &ioapic2 4 0x1
> +					/* TS Demux: 0x2E5E */
> +					0x12100 0x0 0x0 0x0 &ioapic2 5 0x1
> +					/* ***** FIXME ***** Audio DSP: 0x2E5F */
> +					/* 0x13000 0x0 0x0 0x1 &ioapic2 0 0x1 */
> +					/* Audio Interfaces: 0x2E60 */
> +					0x13200 0x0 0x0 0x0 &ioapic2 8 0x1
> +					/* VDC: 0x2E61 */
> +					0x14000 0x0 0x0 0x0 &ioapic2 9 0x1
> +					/* DPE: 0x2E62 */
> +					0x14100 0x0 0x0 0x0 &ioapic2 10 0x1
> +					/* HDMI Tx: 0x2E63 */
> +					0x14200 0x0 0x0 0x0 &ioapic2 11 0x1
> +					/* SEC: 0x2E64 */
> +					0x14800 0x0 0x0 0x0 &ioapic2 12 0x1
> +					/* EXP: 0x2E65 */
> +					0x15000 0x0 0x0 0x0 &ioapic2 13 0x1
> +					/* UART0/1: 0x2E66 */
> +					0x15800 0x0 0x0 0x0 &ioapic2 14 0x1
> +					/* GPIO: 0x2E67 */
> +					0x15900 0x0 0x0 0x0 &ioapic2 15 0x1
> +					/* I2C0/1/2: 0x2E68 */
> +					0x15a00 0x0 0x0 0x0 &ioapic2 16 0x1
> +					/* Smart Card 0/1: 0x2E69 */
> +					0x15b00 0x0 0x0 0x0 &ioapic2 15 0x1
> +					/* SPI: 0x2E6A */
> +					0x15c00 0x0 0x0 0x0 &ioapic2 15 0x1
> +					/* MSPOD: 0x2E6B */
> +					0x15d00 0x0 0x0 0x0 &ioapic2 19 0x1
> +					/* IR: 0x2E6C */
> +					0x15e00 0x0 0x0 0x0 &ioapic2 16 0x1
> +					/* **** FIXME ***** DFX: 0x2E6D */
> +					/* 0x15f00 0x0 0x0 0x1 &ioapic2 0x0 0x1 */
> +					/* Gig Ethernet: 0x2E6E */
> +					0x16000 0x0 0x0 0x0 &ioapic2 21 0x1
> +					/* IEEE1588 and Clock Recovery Unit: 0x2E6F */
> +					0x16100 0x0 0x0 0x0 &ioapic2 3 0x1
> +					/* USB0: 0x2E70 */
> +					0x16800 0x0 0x0 0x0 &ioapic2 22 0x3
> +					/* USB1: 0x2E70 */
> +					0x16900 0x0 0x0 0x0 &ioapic2 22 0x3
> +					/* SATA: 0x2E71 */
> +					0x17000 0x0 0x0 0x0 &ioapic2 23 0x3
> +					>;
> +
> +				i2c@15a00 {
> +					#address-cells = <1>;
> +					#size-cells = <0>;
> +					reg = <0x15a00 0x0 0x0 0x0>;
> +
> +
> +					i2c@0 {
> +						reg = <0>;
> +					};
> +
> +					i2c@1 {
> +						#address-cells = <1>;
> +						#size-cells = <0>;
> +						reg = <1>;
> +
> +						pcf8575@26 {
> +							compatible = "ti,pcf8575";
> +							reg = <0x26>;
> +						};
> +					};
> +
> +					i2c@2 {
> +						#address-cells = <1>;
> +						#size-cells = <0>;
> +						reg = <2>;
> +
> +						pcf8575@26 {
> +							compatible = "ti,pcf8575";
> +							reg = <0x26>;
> +						};
> +					};

All these i2c bus controllers should have a compatible value so that
the OS knows what driver to bind to them.

Also, the node names for the i2c devices should reflect what the
device does, not what the part number is (grep ePAPR for 'generic
names')

> +				};
> +
> +				spi@15c00 {
> +					#address-cells = <1>;
> +					#size-cells = <0>;
> +					reg = <0x15c00 0x0 0x0 0x0>;
> +
> +					pcm1755@0 {
> +						compatible = "ti,pcm1755";
> +						reg = <0>;
> +						spi-max-frequency = <115200>;
> +					};
> +
> +					pcm1609a@1 {
> +						compatible = "ti,pcm1609a";
> +						reg = <1>;
> +						spi-max-frequency = <115200>;
> +					};
> +
> +					at93c46@2 {
> +						compatible = "atmel,at93c46";
> +						reg = <2>;
> +						spi-max-frequency = <115200>;
> +					};
> +				};

Ditto above comments for SPI bus and devices.

> +			};
> +		};
> +	};
> +};
> -- 
> 1.7.3.2
> 
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 03/15] x86/dtb: Add a device tree for CE4100
@ 2010-12-30  8:51     ` Grant Likely
  0 siblings, 0 replies; 106+ messages in thread
From: Grant Likely @ 2010-12-30  8:51 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: sodaville-hfZtesqFncYOwBW4kG4KsQ,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	x86-DgEjT+Ai2ygdnm+yROfE0A, linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Fri, Dec 17, 2010 at 04:33:41PM +0100, Sebastian Andrzej Siewior wrote:
> 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/platform/ce4100/falconfalls.dts |  212 ++++++++++++++++++++++++++++++
>  1 files changed, 212 insertions(+), 0 deletions(-)
>  create mode 100644 arch/x86/platform/ce4100/falconfalls.dts
> 
> diff --git a/arch/x86/platform/ce4100/falconfalls.dts b/arch/x86/platform/ce4100/falconfalls.dts
> new file mode 100644
> index 0000000..24e67ca
> --- /dev/null
> +++ b/arch/x86/platform/ce4100/falconfalls.dts
> @@ -0,0 +1,212 @@
> +/*
> + * 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";

To-date the convention has been to use all lowercase in compatible
properties.  Ditto throughout this file.

> +	#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>;
> +		device_type = "soc";

Drop device_type property.

> +		compatible = "Intel,ce4100";
> +		ranges;
> +
> +		ioapic1: pic@fec00000 {
> +			#interrupt-cells = <2>;
> +			compatible = "Intel,ioapic";
> +			interrupt-controller;
> +			device_type = "interrupt-controller";

Ditto

> +			id = <1>;
> +			reg = <0xfec00000 0x1000>;
> +		};
> +
> +		hpet@fed00000 {
> +			compatible = "Intel,hpet-ce4100", "Intel,hpet";
> +			reg = <0xfed00000 0x200>;
> +		};
> +
> +		lapic0: lapic@fee00000 {
> +			compatible = "Intel,lapic-ce4100", "Intel,lapic";
> +			reg = <0xfee00000 0x1000>;
> +		};
> +
> +		pci@3fc {
> +			#address-cells = <3>;
> +			#interrupt-cells = <1>;
> +			#size-cells = <2>;
> +			compatible = "Intel,ce4100-pci", "pci";
> +			device_type = "pci";

I'd like to say ditto here, but it might require a change to the
current kernel code.  I believe ePAPR specified a compatible value
alternative to 'device_type = "pci";'.

> +			bus-range = <0 0>;
> +			ranges = <0x2000000 0 0xbffff000 0xbffff000 0 0x1000
> +				  0x0000000 0 0x0	 0x0	    0 0x100>;
> +
> +			isa@0 {
> +				#address-cells = <2>;
> +				#size-cells = <1>;
> +				compatible = "isa";
> +				ranges = <1 0 0 0 0 0x100>;
> +
> +				rtc@70 {
> +					compatible = "motorola,mc146818";
> +					interrupts = <8 3>;
> +					interrupt-parent = <&ioapic1>;

If you put an interrupt-parent property in the root node, then it will
become the default interrupt controller for the system which is
usually convenient to have.

> +					ctrl-reg = <2>;
> +					freq-reg = <0x26>;
> +					reg = <1 0x70 2>;
> +				};
> +			};
> +
> +			/* Secondary IO-APIC */
> +			ioapic2: pic@bffff000 {
> +				#interrupt-cells = <2>;
> +				compatible = "Intel,ioapic-ce4100", "Intel,ioapic";
> +				interrupt-controller;
> +				device_type = "interrupt-controller";

Drop device_type.

> +				id = <2>;
> +				reg = <0x100 0x0 0x0 0x0 0x0>;
> +				assigned-addresses = <0x02000000 0x0 0xbffff000 0x0 0x1000>;
> +			};
> +
> +			pci@av {
> +				#address-cells = <3>;
> +				#interrupt-cells = <1>;
> +				#size-cells = <1>;
> +				compatible = "Intel,ce4100-pci";
> +				device_type = "pci";
> +				bus-range = <1 1>;
> +				interrupt-map-mask = <0xffffff 0x0 0x0 0x0>;
> +				interrupt-map = <
> +					/* GFX: 0x2E5B */
> +					0x11000 0x0 0x0 0x0 &ioapic2 0 0x1
> +					/* ***** FIXME ****** Compositing Engine: 0x2E72 */
> +					/* 0x11100 0x0 0x0 0x1 &ioapic2 0 0x1 */
> +					/* MFD: 0x2E5C */
> +					0x11800 0x0 0x0 0x0 &ioapic2 2 0x1
> +					/* TS Prefilter: 0x2E5D */
> +					0x12000 0x0 0x0 0x0 &ioapic2 4 0x1
> +					/* TS Demux: 0x2E5E */
> +					0x12100 0x0 0x0 0x0 &ioapic2 5 0x1
> +					/* ***** FIXME ***** Audio DSP: 0x2E5F */
> +					/* 0x13000 0x0 0x0 0x1 &ioapic2 0 0x1 */
> +					/* Audio Interfaces: 0x2E60 */
> +					0x13200 0x0 0x0 0x0 &ioapic2 8 0x1
> +					/* VDC: 0x2E61 */
> +					0x14000 0x0 0x0 0x0 &ioapic2 9 0x1
> +					/* DPE: 0x2E62 */
> +					0x14100 0x0 0x0 0x0 &ioapic2 10 0x1
> +					/* HDMI Tx: 0x2E63 */
> +					0x14200 0x0 0x0 0x0 &ioapic2 11 0x1
> +					/* SEC: 0x2E64 */
> +					0x14800 0x0 0x0 0x0 &ioapic2 12 0x1
> +					/* EXP: 0x2E65 */
> +					0x15000 0x0 0x0 0x0 &ioapic2 13 0x1
> +					/* UART0/1: 0x2E66 */
> +					0x15800 0x0 0x0 0x0 &ioapic2 14 0x1
> +					/* GPIO: 0x2E67 */
> +					0x15900 0x0 0x0 0x0 &ioapic2 15 0x1
> +					/* I2C0/1/2: 0x2E68 */
> +					0x15a00 0x0 0x0 0x0 &ioapic2 16 0x1
> +					/* Smart Card 0/1: 0x2E69 */
> +					0x15b00 0x0 0x0 0x0 &ioapic2 15 0x1
> +					/* SPI: 0x2E6A */
> +					0x15c00 0x0 0x0 0x0 &ioapic2 15 0x1
> +					/* MSPOD: 0x2E6B */
> +					0x15d00 0x0 0x0 0x0 &ioapic2 19 0x1
> +					/* IR: 0x2E6C */
> +					0x15e00 0x0 0x0 0x0 &ioapic2 16 0x1
> +					/* **** FIXME ***** DFX: 0x2E6D */
> +					/* 0x15f00 0x0 0x0 0x1 &ioapic2 0x0 0x1 */
> +					/* Gig Ethernet: 0x2E6E */
> +					0x16000 0x0 0x0 0x0 &ioapic2 21 0x1
> +					/* IEEE1588 and Clock Recovery Unit: 0x2E6F */
> +					0x16100 0x0 0x0 0x0 &ioapic2 3 0x1
> +					/* USB0: 0x2E70 */
> +					0x16800 0x0 0x0 0x0 &ioapic2 22 0x3
> +					/* USB1: 0x2E70 */
> +					0x16900 0x0 0x0 0x0 &ioapic2 22 0x3
> +					/* SATA: 0x2E71 */
> +					0x17000 0x0 0x0 0x0 &ioapic2 23 0x3
> +					>;
> +
> +				i2c@15a00 {
> +					#address-cells = <1>;
> +					#size-cells = <0>;
> +					reg = <0x15a00 0x0 0x0 0x0>;
> +
> +
> +					i2c@0 {
> +						reg = <0>;
> +					};
> +
> +					i2c@1 {
> +						#address-cells = <1>;
> +						#size-cells = <0>;
> +						reg = <1>;
> +
> +						pcf8575@26 {
> +							compatible = "ti,pcf8575";
> +							reg = <0x26>;
> +						};
> +					};
> +
> +					i2c@2 {
> +						#address-cells = <1>;
> +						#size-cells = <0>;
> +						reg = <2>;
> +
> +						pcf8575@26 {
> +							compatible = "ti,pcf8575";
> +							reg = <0x26>;
> +						};
> +					};

All these i2c bus controllers should have a compatible value so that
the OS knows what driver to bind to them.

Also, the node names for the i2c devices should reflect what the
device does, not what the part number is (grep ePAPR for 'generic
names')

> +				};
> +
> +				spi@15c00 {
> +					#address-cells = <1>;
> +					#size-cells = <0>;
> +					reg = <0x15c00 0x0 0x0 0x0>;
> +
> +					pcm1755@0 {
> +						compatible = "ti,pcm1755";
> +						reg = <0>;
> +						spi-max-frequency = <115200>;
> +					};
> +
> +					pcm1609a@1 {
> +						compatible = "ti,pcm1609a";
> +						reg = <1>;
> +						spi-max-frequency = <115200>;
> +					};
> +
> +					at93c46@2 {
> +						compatible = "atmel,at93c46";
> +						reg = <2>;
> +						spi-max-frequency = <115200>;
> +					};
> +				};

Ditto above comments for SPI bus and devices.

> +			};
> +		};
> +	};
> +};
> -- 
> 1.7.3.2
> 
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 05/15] x86/dtb: add early parsing of APIC and IO APIC
@ 2010-12-30  8:54     ` Grant Likely
  0 siblings, 0 replies; 106+ messages in thread
From: Grant Likely @ 2010-12-30  8:54 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: linux-kernel, sodaville, x86, devicetree-discuss

On Fri, Dec 17, 2010 at 04:33:43PM +0100, Sebastian Andrzej Siewior wrote:
> 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@lists.ozlabs.org
> Cc: Dirk Brandewie <dirk.brandewie@gmail.com>
> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> ---
>  arch/x86/include/asm/prom.h |    7 +++
>  arch/x86/kernel/irqinit.c   |    2 +-
>  arch/x86/kernel/prom.c      |  123 +++++++++++++++++++++++++++++++++++++++++-
>  3 files changed, 128 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/x86/include/asm/prom.h b/arch/x86/include/asm/prom.h
> index 9076ae4..3bc8ed5 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/irqinit.c b/arch/x86/kernel/irqinit.c
> index 149c87f..4cadf86 100644
> --- a/arch/x86/kernel/irqinit.c
> +++ b/arch/x86/kernel/irqinit.c
> @@ -244,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
> diff --git a/arch/x86/kernel/prom.c b/arch/x86/kernel/prom.c
> index 53948cb..9cbb52b 100644
> --- a/arch/x86/kernel/prom.c
> +++ b/arch/x86/kernel/prom.c
> @@ -6,15 +6,20 @@
>  #include <linux/interrupt.h>
>  #include <linux/list.h>
>  #include <linux/of.h>
> +#include <linux/of_address.h>
>  #include <linux/of_platform.h>
>  #include <linux/slab.h>
>  
>  #include <asm/irq_controller.h>
> +#include <asm/io_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;
> @@ -93,7 +98,119 @@ u64 __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
>  
>  void __init add_dtb(u64 data)
>  {
> -	initial_boot_params = (struct boot_param_header *)
> -		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 void __init dtb_add_ioapic(struct device_node *dn)
> +{
> +	unsigned int ioapic_id;
> +	const __be32 *cell;
> +	int len;
> +	struct resource r;
> +	int ret;
> +
> +	cell = of_get_property(dn, "id", &len);
> +	if (!cell) {
> +		printk(KERN_ERR "Node %s is missing id property.\n",
> +				dn->full_name);
> +		return;
> +	}
> +	ioapic_id = of_read_ulong(cell, len / 4);
> +
> +	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,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);

Add "map_len = size;" here eliminate the early_iounmap() dance done below.

> +	}
> +
> +	new_dtb = alloc_bootmem(size);
> +	memcpy(new_dtb, initial_boot_params, size);
> +	if (map_len < size)
> +		early_iounmap(initial_boot_params, size);
> +	else
> +		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();
>  }
> -- 
> 1.7.3.2
> 
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 05/15] x86/dtb: add early parsing of APIC and IO APIC
@ 2010-12-30  8:54     ` Grant Likely
  0 siblings, 0 replies; 106+ messages in thread
From: Grant Likely @ 2010-12-30  8:54 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: sodaville-hfZtesqFncYOwBW4kG4KsQ,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	x86-DgEjT+Ai2ygdnm+yROfE0A, linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Fri, Dec 17, 2010 at 04:33:43PM +0100, Sebastian Andrzej Siewior wrote:
> 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>
> Signed-off-by: Sebastian Andrzej Siewior <bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
> ---
>  arch/x86/include/asm/prom.h |    7 +++
>  arch/x86/kernel/irqinit.c   |    2 +-
>  arch/x86/kernel/prom.c      |  123 +++++++++++++++++++++++++++++++++++++++++-
>  3 files changed, 128 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/x86/include/asm/prom.h b/arch/x86/include/asm/prom.h
> index 9076ae4..3bc8ed5 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/irqinit.c b/arch/x86/kernel/irqinit.c
> index 149c87f..4cadf86 100644
> --- a/arch/x86/kernel/irqinit.c
> +++ b/arch/x86/kernel/irqinit.c
> @@ -244,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
> diff --git a/arch/x86/kernel/prom.c b/arch/x86/kernel/prom.c
> index 53948cb..9cbb52b 100644
> --- a/arch/x86/kernel/prom.c
> +++ b/arch/x86/kernel/prom.c
> @@ -6,15 +6,20 @@
>  #include <linux/interrupt.h>
>  #include <linux/list.h>
>  #include <linux/of.h>
> +#include <linux/of_address.h>
>  #include <linux/of_platform.h>
>  #include <linux/slab.h>
>  
>  #include <asm/irq_controller.h>
> +#include <asm/io_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;
> @@ -93,7 +98,119 @@ u64 __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
>  
>  void __init add_dtb(u64 data)
>  {
> -	initial_boot_params = (struct boot_param_header *)
> -		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 void __init dtb_add_ioapic(struct device_node *dn)
> +{
> +	unsigned int ioapic_id;
> +	const __be32 *cell;
> +	int len;
> +	struct resource r;
> +	int ret;
> +
> +	cell = of_get_property(dn, "id", &len);
> +	if (!cell) {
> +		printk(KERN_ERR "Node %s is missing id property.\n",
> +				dn->full_name);
> +		return;
> +	}
> +	ioapic_id = of_read_ulong(cell, len / 4);
> +
> +	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,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);

Add "map_len = size;" here eliminate the early_iounmap() dance done below.

> +	}
> +
> +	new_dtb = alloc_bootmem(size);
> +	memcpy(new_dtb, initial_boot_params, size);
> +	if (map_len < size)
> +		early_iounmap(initial_boot_params, size);
> +	else
> +		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();
>  }
> -- 
> 1.7.3.2
> 
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 13/15] x86/rtc: don't register rtc if we have an OF node for it
  2010-12-17 15:33 ` [PATCH 13/15] x86/rtc: don't register rtc if we have an OF node for it Sebastian Andrzej Siewior
@ 2010-12-30  8:59   ` Grant Likely
  2011-01-04 13:28     ` [PATCH v2 13/15] x86/rtc: don't register rtc if we the DT blob Sebastian Andrzej Siewior
  0 siblings, 1 reply; 106+ messages in thread
From: Grant Likely @ 2010-12-30  8:59 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior; +Cc: linux-kernel, sodaville, x86, dirk.brandewie

On Fri, Dec 17, 2010 at 04:33:51PM +0100, Sebastian Andrzej Siewior wrote:
> or we end up with two of those things.

More generically, rather than searching for an rtc node, I imagine
simply the presence of a device tree blob means that the rtc
registration should be suppressed.

g.

> 
> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> ---
>  arch/x86/kernel/rtc.c |   23 +++++++++++++++++++++++
>  1 files changed, 23 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/x86/kernel/rtc.c b/arch/x86/kernel/rtc.c
> index 1cfbbfc..382c6cb 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>
> @@ -218,6 +219,25 @@ static struct platform_device rtc_device = {
>  	.num_resources	= ARRAY_SIZE(rtc_resources),
>  };
>  
> +#ifdef CONFIG_OF
> +static __init int have_rtc_of_node(void)
> +{
> +	struct device_node *n;
> +
> +	n = of_find_compatible_node(NULL, NULL, "motorola,mc146818");
> +	if (n) {
> +		of_node_put(n);
> +		return 1;
> +	}
> +	return 0;
> +}
> +#else
> +static inline int have_rtc_of_node(void)
> +{
> +	return 0;
> +}
> +#endif
> +
>  static __init int add_rtc_cmos(void)
>  {
>  #ifdef CONFIG_PNP
> @@ -237,6 +257,9 @@ static __init int add_rtc_cmos(void)
>  	}
>  #endif
>  
> +	if (have_rtc_of_node())
> +		return 0;
> +
>  	platform_device_register(&rtc_device);
>  	dev_info(&rtc_device.dev,
>  		 "registered platform RTC device (no PNP device found)\n");
> -- 
> 1.7.3.2
> 
> --
> 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/

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 12/15] of/address: use propper endianess in get_flags
  2010-12-17 15:33   ` Sebastian Andrzej Siewior
  (?)
@ 2010-12-30  9:05   ` Grant Likely
  -1 siblings, 0 replies; 106+ messages in thread
From: Grant Likely @ 2010-12-30  9:05 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: linux-kernel, sodaville, x86, devicetree-discuss

On Fri, Dec 17, 2010 at 04:33:50PM +0100, Sebastian Andrzej Siewior wrote:
> This patch changes u32 to __be32 for all "ranges", "prop" and "addr" and
> such. Those variables are pointing to the device tree which containts
> intergers in big endian format.
> Most functions are doing it right because they are using using
> of_read_number() which is doing the right thing. of_bus_isa_get_flags(),
> of_bus_pci_get_flags() and of_bus_isa_map() were accessing the data
> directly and were doing it wrong.
> 
> Cc: devicetree-discuss@lists.ozlabs.org
> Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>

This one is already applied to my next-devicetree branch

g.

> ---
>  arch/powerpc/include/asm/prom.h |    2 +-
>  drivers/of/address.c            |   54 ++++++++++++++++++++------------------
>  include/linux/of_address.h      |    6 ++--
>  3 files changed, 32 insertions(+), 30 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h
> index 01c3302..b891fdc 100644
> --- a/arch/powerpc/include/asm/prom.h
> +++ b/arch/powerpc/include/asm/prom.h
> @@ -42,7 +42,7 @@ extern void pci_create_OF_bus_map(void);
>  
>  /* Translate a DMA address from device space to CPU space */
>  extern u64 of_translate_dma_address(struct device_node *dev,
> -				    const u32 *in_addr);
> +				    const __be32 *in_addr);
>  
>  #ifdef CONFIG_PCI
>  extern unsigned long pci_address_to_pio(phys_addr_t address);
> diff --git a/drivers/of/address.c b/drivers/of/address.c
> index 3a1c7e7..b4559c5 100644
> --- a/drivers/of/address.c
> +++ b/drivers/of/address.c
> @@ -12,13 +12,13 @@
>  			(ns) > 0)
>  
>  static struct of_bus *of_match_bus(struct device_node *np);
> -static int __of_address_to_resource(struct device_node *dev, const u32 *addrp,
> -				    u64 size, unsigned int flags,
> +static int __of_address_to_resource(struct device_node *dev,
> +		const __be32 *addrp, u64 size, unsigned int flags,
>  				    struct resource *r);
>  
>  /* Debug utility */
>  #ifdef DEBUG
> -static void of_dump_addr(const char *s, const u32 *addr, int na)
> +static void of_dump_addr(const char *s, const __be32 *addr, int na)
>  {
>  	printk(KERN_DEBUG "%s", s);
>  	while (na--)
> @@ -26,7 +26,7 @@ static void of_dump_addr(const char *s, const u32 *addr, int na)
>  	printk("\n");
>  }
>  #else
> -static void of_dump_addr(const char *s, const u32 *addr, int na) { }
> +static void of_dump_addr(const char *s, const __be32 *addr, int na) { }
>  #endif
>  
>  /* Callbacks for bus specific translators */
> @@ -36,10 +36,10 @@ struct of_bus {
>  	int		(*match)(struct device_node *parent);
>  	void		(*count_cells)(struct device_node *child,
>  				       int *addrc, int *sizec);
> -	u64		(*map)(u32 *addr, const u32 *range,
> +	u64		(*map)(u32 *addr, const __be32 *range,
>  				int na, int ns, int pna);
>  	int		(*translate)(u32 *addr, u64 offset, int na);
> -	unsigned int	(*get_flags)(const u32 *addr);
> +	unsigned int	(*get_flags)(const __be32 *addr);
>  };
>  
>  /*
> @@ -55,7 +55,7 @@ static void of_bus_default_count_cells(struct device_node *dev,
>  		*sizec = of_n_size_cells(dev);
>  }
>  
> -static u64 of_bus_default_map(u32 *addr, const u32 *range,
> +static u64 of_bus_default_map(u32 *addr, const __be32 *range,
>  		int na, int ns, int pna)
>  {
>  	u64 cp, s, da;
> @@ -85,7 +85,7 @@ static int of_bus_default_translate(u32 *addr, u64 offset, int na)
>  	return 0;
>  }
>  
> -static unsigned int of_bus_default_get_flags(const u32 *addr)
> +static unsigned int of_bus_default_get_flags(const __be32 *addr)
>  {
>  	return IORESOURCE_MEM;
>  }
> @@ -110,10 +110,10 @@ static void of_bus_pci_count_cells(struct device_node *np,
>  		*sizec = 2;
>  }
>  
> -static unsigned int of_bus_pci_get_flags(const u32 *addr)
> +static unsigned int of_bus_pci_get_flags(const __be32 *addr)
>  {
>  	unsigned int flags = 0;
> -	u32 w = addr[0];
> +	u32 w = be32_to_cpup(addr);
>  
>  	switch((w >> 24) & 0x03) {
>  	case 0x01:
> @@ -129,7 +129,8 @@ static unsigned int of_bus_pci_get_flags(const u32 *addr)
>  	return flags;
>  }
>  
> -static u64 of_bus_pci_map(u32 *addr, const u32 *range, int na, int ns, int pna)
> +static u64 of_bus_pci_map(u32 *addr, const __be32 *range, int na, int ns,
> +		int pna)
>  {
>  	u64 cp, s, da;
>  	unsigned int af, rf;
> @@ -160,7 +161,7 @@ static int of_bus_pci_translate(u32 *addr, u64 offset, int na)
>  	return of_bus_default_translate(addr + 1, offset, na - 1);
>  }
>  
> -const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
> +const __be32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
>  			unsigned int *flags)
>  {
>  	const __be32 *prop;
> @@ -207,7 +208,7 @@ EXPORT_SYMBOL(of_get_pci_address);
>  int of_pci_address_to_resource(struct device_node *dev, int bar,
>  			       struct resource *r)
>  {
> -	const u32	*addrp;
> +	const __be32	*addrp;
>  	u64		size;
>  	unsigned int	flags;
>  
> @@ -237,12 +238,13 @@ static void of_bus_isa_count_cells(struct device_node *child,
>  		*sizec = 1;
>  }
>  
> -static u64 of_bus_isa_map(u32 *addr, const u32 *range, int na, int ns, int pna)
> +static u64 of_bus_isa_map(u32 *addr, const __be32 *range, int na, int ns,
> +		int pna)
>  {
>  	u64 cp, s, da;
>  
>  	/* Check address type match */
> -	if ((addr[0] ^ range[0]) & 0x00000001)
> +	if ((addr[0] ^ range[0]) & cpu_to_be32(1))
>  		return OF_BAD_ADDR;
>  
>  	/* Read address values, skipping high cell */
> @@ -264,10 +266,10 @@ static int of_bus_isa_translate(u32 *addr, u64 offset, int na)
>  	return of_bus_default_translate(addr + 1, offset, na - 1);
>  }
>  
> -static unsigned int of_bus_isa_get_flags(const u32 *addr)
> +static unsigned int of_bus_isa_get_flags(const __be32 *addr)
>  {
>  	unsigned int flags = 0;
> -	u32 w = addr[0];
> +	u32 w = be32_to_cpup(addr);
>  
>  	if (w & 1)
>  		flags |= IORESOURCE_IO;
> @@ -330,7 +332,7 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus,
>  			    struct of_bus *pbus, u32 *addr,
>  			    int na, int ns, int pna, const char *rprop)
>  {
> -	const u32 *ranges;
> +	const __be32 *ranges;
>  	unsigned int rlen;
>  	int rone;
>  	u64 offset = OF_BAD_ADDR;
> @@ -398,7 +400,7 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus,
>   * that can be mapped to a cpu physical address). This is not really specified
>   * that way, but this is traditionally the way IBM at least do things
>   */
> -u64 __of_translate_address(struct device_node *dev, const u32 *in_addr,
> +u64 __of_translate_address(struct device_node *dev, const __be32 *in_addr,
>  			   const char *rprop)
>  {
>  	struct device_node *parent = NULL;
> @@ -475,22 +477,22 @@ u64 __of_translate_address(struct device_node *dev, const u32 *in_addr,
>  	return result;
>  }
>  
> -u64 of_translate_address(struct device_node *dev, const u32 *in_addr)
> +u64 of_translate_address(struct device_node *dev, const __be32 *in_addr)
>  {
>  	return __of_translate_address(dev, in_addr, "ranges");
>  }
>  EXPORT_SYMBOL(of_translate_address);
>  
> -u64 of_translate_dma_address(struct device_node *dev, const u32 *in_addr)
> +u64 of_translate_dma_address(struct device_node *dev, const __be32 *in_addr)
>  {
>  	return __of_translate_address(dev, in_addr, "dma-ranges");
>  }
>  EXPORT_SYMBOL(of_translate_dma_address);
>  
> -const u32 *of_get_address(struct device_node *dev, int index, u64 *size,
> +const __be32 *of_get_address(struct device_node *dev, int index, u64 *size,
>  		    unsigned int *flags)
>  {
> -	const u32 *prop;
> +	const __be32 *prop;
>  	unsigned int psize;
>  	struct device_node *parent;
>  	struct of_bus *bus;
> @@ -525,8 +527,8 @@ const u32 *of_get_address(struct device_node *dev, int index, u64 *size,
>  }
>  EXPORT_SYMBOL(of_get_address);
>  
> -static int __of_address_to_resource(struct device_node *dev, const u32 *addrp,
> -				    u64 size, unsigned int flags,
> +static int __of_address_to_resource(struct device_node *dev,
> +		const __be32 *addrp, u64 size, unsigned int flags,
>  				    struct resource *r)
>  {
>  	u64 taddr;
> @@ -564,7 +566,7 @@ static int __of_address_to_resource(struct device_node *dev, const u32 *addrp,
>  int of_address_to_resource(struct device_node *dev, int index,
>  			   struct resource *r)
>  {
> -	const u32	*addrp;
> +	const __be32	*addrp;
>  	u64		size;
>  	unsigned int	flags;
>  
> diff --git a/include/linux/of_address.h b/include/linux/of_address.h
> index 8aea06f..2feda6e 100644
> --- a/include/linux/of_address.h
> +++ b/include/linux/of_address.h
> @@ -3,7 +3,7 @@
>  #include <linux/ioport.h>
>  #include <linux/of.h>
>  
> -extern u64 of_translate_address(struct device_node *np, const u32 *addr);
> +extern u64 of_translate_address(struct device_node *np, const __be32 *addr);
>  extern int of_address_to_resource(struct device_node *dev, int index,
>  				  struct resource *r);
>  extern void __iomem *of_iomap(struct device_node *device, int index);
> @@ -21,7 +21,7 @@ static inline unsigned long pci_address_to_pio(phys_addr_t addr) { return -1; }
>  #endif
>  
>  #ifdef CONFIG_PCI
> -extern const u32 *of_get_pci_address(struct device_node *dev, int bar_no,
> +extern const __be32 *of_get_pci_address(struct device_node *dev, int bar_no,
>  			       u64 *size, unsigned int *flags);
>  extern int of_pci_address_to_resource(struct device_node *dev, int bar,
>  				      struct resource *r);
> @@ -32,7 +32,7 @@ static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
>  	return -ENOSYS;
>  }
>  
> -static inline const u32 *of_get_pci_address(struct device_node *dev,
> +static inline const __be32 *of_get_pci_address(struct device_node *dev,
>  		int bar_no, u64 *size, unsigned int *flags)
>  {
>  	return NULL;
> -- 
> 1.7.3.2
> 
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 02/15] x86: Add device tree support
@ 2010-12-30 21:01       ` Grant Likely
  0 siblings, 0 replies; 106+ messages in thread
From: Grant Likely @ 2010-12-30 21:01 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: linux-kernel, sodaville, x86, devicetree-discuss, H. Peter Anvin

Hi Peter,

Since this series is based on the tip tree, these should be merged via
the same route.  Aside from the comments below, I'm okay with patches
1 & 2 going in for 2.6.38 (assuming NO_IRQ is fixed).  I've picked up
patch 12 since it is a generic fix.  I haven't made a decision on the
remaining 14 yet.

g.

On Thu, Dec 30, 2010 at 1:43 AM, Grant Likely <grant.likely@secretlab.ca> wrote:
> On Fri, Dec 17, 2010 at 04:33:40PM +0100, Sebastian Andrzej Siewior wrote:
>> 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@lists.ozlabs.org
>> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
>> Signed-off-by: Dirk Brandewie <dirk.brandewie@gmail.com>
>
> Mostly looks good. Some comments below.
>
> g.
>
>> ---
>>  Documentation/x86/boot_with_dtb.txt |   26 +++++++++++++++
>>  arch/x86/Kconfig                    |    7 ++++
>>  arch/x86/include/asm/bootparam.h    |    1 +
>>  arch/x86/include/asm/prom.h         |   59 +++++++++++++++++++++++++++++++++++
>>  arch/x86/kernel/Makefile            |    1 +
>>  arch/x86/kernel/irqinit.c           |    1 +
>>  arch/x86/kernel/prom.c              |   54 ++++++++++++++++++++++++++++++++
>>  arch/x86/kernel/setup.c             |    4 ++
>>  8 files changed, 153 insertions(+), 0 deletions(-)
>>  create mode 100644 Documentation/x86/boot_with_dtb.txt
>>  create mode 100644 arch/x86/include/asm/prom.h
>>  create mode 100644 arch/x86/kernel/prom.c
>>
>> diff --git a/Documentation/x86/boot_with_dtb.txt b/Documentation/x86/boot_with_dtb.txt
>> new file mode 100644
>> index 0000000..6a357aa
>> --- /dev/null
>> +++ b/Documentation/x86/boot_with_dtb.txt
>> @@ -0,0 +1,26 @@
>> +  Booting x86 with device tree
>> +=================================
>> +
>> +1. Introduction
>> +~~~~~~~~~~~~~~~
>> +This document contains device tree information which are specific to
>> +the x86 platform. Generic informations as bindings can be found in
>> +Documentation/powerpc/dts-bindings/
>> +
>> +2. Passing the device tree
>> +~~~~~~~~~~~~~~~~~~~~~~~~~~
>> +The pointer to the device tree block (dtb) is passed via setup_data
>> +(see [0]) which requires at least boot protocol 2.09. The type filed is
>> +defined as
>> +
>> +#define SETUP_DTB                      2
>> +
>> +3. Purpose
>> +~~~~~~~~~~~
>> +The device tree is used as an extension to the "boot page". As such it does not
>> +parse / consider data which are already covered by the boot page. This includes
>> +memory size, 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.
>> +
>> +[0] Documentation/x86/boot.txt
>> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
>> index b6fccb0..0522354 100644
>> --- a/arch/x86/Kconfig
>> +++ b/arch/x86/Kconfig
>> @@ -299,6 +299,13 @@ config X86_BIGSMP
>>       ---help---
>>         This option is needed for the systems that have more than 8 CPUs
>>
>> +config X86_OF
>> +     bool "Support for device tree"
>> +     select OF
>> +     select OF_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/prom.h b/arch/x86/include/asm/prom.h
>> new file mode 100644
>> index 0000000..2fbe3e8
>> --- /dev/null
>> +++ b/arch/x86/include/asm/prom.h
>> @@ -0,0 +1,59 @@
>> +/*
>> + * 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];
>> +/* This number is used when no interrupt has been assigned */
>> +#define NO_IRQ               (-1)
>
> 0 means NO_IRQ on x86 and most architectures.  I will change this when
> I pick up the patch.
>
>> +
>> +#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__ */
>> +
>> +/*
>> + * These includes are put at the bottom because they may contain things
>> + * that are overridden by this file.  Ideally they shouldn't be included
>> + * by this file, but there are a bunch of .c files that currently depend
>> + * on it.  Eventually they will be cleaned up.
>> + */
>> +#include <linux/of_fdt.h>
>> +#include <linux/of_irq.h>
>> +#include <linux/platform_device.h>
>> +
>> +#endif
>> diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
>> index f60153d..40bc33d 100644
>> --- a/arch/x86/kernel/Makefile
>> +++ b/arch/x86/kernel/Makefile
>> @@ -108,6 +108,7 @@ obj-$(CONFIG_MICROCODE)                   += microcode.o
>>  obj-$(CONFIG_X86_CHECK_BIOS_CORRUPTION) += check.o
>>
>>  obj-$(CONFIG_SWIOTLB)                        += pci-swiotlb.o
>> +obj-$(CONFIG_X86_OF)                 += prom.o
>>
>>  ###
>>  # 64 bit specific files
>> diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c
>> index c752e97..149c87f 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:
>> diff --git a/arch/x86/kernel/prom.c b/arch/x86/kernel/prom.c
>> new file mode 100644
>> index 0000000..249ebd3
>> --- /dev/null
>> +++ b/arch/x86/kernel/prom.c
>> @@ -0,0 +1,54 @@
>> +/*
>> + * Architecture specific OF callbacks.
>> + */
>> +#include <linux/bootmem.h>
>> +#include <linux/io.h>
>> +#include <linux/list.h>
>> +#include <linux/of.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();
>> +}
>> +
>> +u64 __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
>> +{
>> +     void *mem;
>> +
>> +     mem = __alloc_bootmem(size, align, __pa(MAX_DMA_ADDRESS));
>> +     return virt_to_phys(mem);
>> +}
>> +
>> +void __init add_dtb(u64 data)
>> +{
>> +     initial_boot_params = (struct boot_param_header *)
>> +             phys_to_virt((u64) (u32) data +
>> +                             offsetof(struct setup_data, data));
>> +}
>> diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
>> index 577d06b..26f2c9a 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.
>> @@ -445,6 +446,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;
>
> Why is the physical address being passed in when the virtual address
> is needed to be stored in initial_boot_params by add_dtb()?
>
>
>>               default:
>>                       break;
>>               }
>> --
>> 1.7.3.2
>>
>> _______________________________________________
>> 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] 106+ messages in thread

* Re: [PATCH 02/15] x86: Add device tree support
@ 2010-12-30 21:01       ` Grant Likely
  0 siblings, 0 replies; 106+ messages in thread
From: Grant Likely @ 2010-12-30 21:01 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: sodaville-hfZtesqFncYOwBW4kG4KsQ,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	x86-DgEjT+Ai2ygdnm+yROfE0A, H. Peter Anvin,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

Hi Peter,

Since this series is based on the tip tree, these should be merged via
the same route.  Aside from the comments below, I'm okay with patches
1 & 2 going in for 2.6.38 (assuming NO_IRQ is fixed).  I've picked up
patch 12 since it is a generic fix.  I haven't made a decision on the
remaining 14 yet.

g.

On Thu, Dec 30, 2010 at 1:43 AM, Grant Likely <grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org> wrote:
> On Fri, Dec 17, 2010 at 04:33:40PM +0100, Sebastian Andrzej Siewior wrote:
>> 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
>> Signed-off-by: Sebastian Andrzej Siewior <bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
>> Signed-off-by: Dirk Brandewie <dirk.brandewie-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>
> Mostly looks good. Some comments below.
>
> g.
>
>> ---
>>  Documentation/x86/boot_with_dtb.txt |   26 +++++++++++++++
>>  arch/x86/Kconfig                    |    7 ++++
>>  arch/x86/include/asm/bootparam.h    |    1 +
>>  arch/x86/include/asm/prom.h         |   59 +++++++++++++++++++++++++++++++++++
>>  arch/x86/kernel/Makefile            |    1 +
>>  arch/x86/kernel/irqinit.c           |    1 +
>>  arch/x86/kernel/prom.c              |   54 ++++++++++++++++++++++++++++++++
>>  arch/x86/kernel/setup.c             |    4 ++
>>  8 files changed, 153 insertions(+), 0 deletions(-)
>>  create mode 100644 Documentation/x86/boot_with_dtb.txt
>>  create mode 100644 arch/x86/include/asm/prom.h
>>  create mode 100644 arch/x86/kernel/prom.c
>>
>> diff --git a/Documentation/x86/boot_with_dtb.txt b/Documentation/x86/boot_with_dtb.txt
>> new file mode 100644
>> index 0000000..6a357aa
>> --- /dev/null
>> +++ b/Documentation/x86/boot_with_dtb.txt
>> @@ -0,0 +1,26 @@
>> +  Booting x86 with device tree
>> +=================================
>> +
>> +1. Introduction
>> +~~~~~~~~~~~~~~~
>> +This document contains device tree information which are specific to
>> +the x86 platform. Generic informations as bindings can be found in
>> +Documentation/powerpc/dts-bindings/
>> +
>> +2. Passing the device tree
>> +~~~~~~~~~~~~~~~~~~~~~~~~~~
>> +The pointer to the device tree block (dtb) is passed via setup_data
>> +(see [0]) which requires at least boot protocol 2.09. The type filed is
>> +defined as
>> +
>> +#define SETUP_DTB                      2
>> +
>> +3. Purpose
>> +~~~~~~~~~~~
>> +The device tree is used as an extension to the "boot page". As such it does not
>> +parse / consider data which are already covered by the boot page. This includes
>> +memory size, 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.
>> +
>> +[0] Documentation/x86/boot.txt
>> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
>> index b6fccb0..0522354 100644
>> --- a/arch/x86/Kconfig
>> +++ b/arch/x86/Kconfig
>> @@ -299,6 +299,13 @@ config X86_BIGSMP
>>       ---help---
>>         This option is needed for the systems that have more than 8 CPUs
>>
>> +config X86_OF
>> +     bool "Support for device tree"
>> +     select OF
>> +     select OF_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/prom.h b/arch/x86/include/asm/prom.h
>> new file mode 100644
>> index 0000000..2fbe3e8
>> --- /dev/null
>> +++ b/arch/x86/include/asm/prom.h
>> @@ -0,0 +1,59 @@
>> +/*
>> + * 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];
>> +/* This number is used when no interrupt has been assigned */
>> +#define NO_IRQ               (-1)
>
> 0 means NO_IRQ on x86 and most architectures.  I will change this when
> I pick up the patch.
>
>> +
>> +#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__ */
>> +
>> +/*
>> + * These includes are put at the bottom because they may contain things
>> + * that are overridden by this file.  Ideally they shouldn't be included
>> + * by this file, but there are a bunch of .c files that currently depend
>> + * on it.  Eventually they will be cleaned up.
>> + */
>> +#include <linux/of_fdt.h>
>> +#include <linux/of_irq.h>
>> +#include <linux/platform_device.h>
>> +
>> +#endif
>> diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
>> index f60153d..40bc33d 100644
>> --- a/arch/x86/kernel/Makefile
>> +++ b/arch/x86/kernel/Makefile
>> @@ -108,6 +108,7 @@ obj-$(CONFIG_MICROCODE)                   += microcode.o
>>  obj-$(CONFIG_X86_CHECK_BIOS_CORRUPTION) += check.o
>>
>>  obj-$(CONFIG_SWIOTLB)                        += pci-swiotlb.o
>> +obj-$(CONFIG_X86_OF)                 += prom.o
>>
>>  ###
>>  # 64 bit specific files
>> diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c
>> index c752e97..149c87f 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:
>> diff --git a/arch/x86/kernel/prom.c b/arch/x86/kernel/prom.c
>> new file mode 100644
>> index 0000000..249ebd3
>> --- /dev/null
>> +++ b/arch/x86/kernel/prom.c
>> @@ -0,0 +1,54 @@
>> +/*
>> + * Architecture specific OF callbacks.
>> + */
>> +#include <linux/bootmem.h>
>> +#include <linux/io.h>
>> +#include <linux/list.h>
>> +#include <linux/of.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();
>> +}
>> +
>> +u64 __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
>> +{
>> +     void *mem;
>> +
>> +     mem = __alloc_bootmem(size, align, __pa(MAX_DMA_ADDRESS));
>> +     return virt_to_phys(mem);
>> +}
>> +
>> +void __init add_dtb(u64 data)
>> +{
>> +     initial_boot_params = (struct boot_param_header *)
>> +             phys_to_virt((u64) (u32) data +
>> +                             offsetof(struct setup_data, data));
>> +}
>> diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
>> index 577d06b..26f2c9a 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.
>> @@ -445,6 +446,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;
>
> Why is the physical address being passed in when the virtual address
> is needed to be stored in initial_boot_params by add_dtb()?
>
>
>>               default:
>>                       break;
>>               }
>> --
>> 1.7.3.2
>>
>> _______________________________________________
>> devicetree-discuss mailing list
>> devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
>> https://lists.ozlabs.org/listinfo/devicetree-discuss
>



-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 02/15] x86: Add device tree support
@ 2011-01-02  0:40         ` H. Peter Anvin
  0 siblings, 0 replies; 106+ messages in thread
From: H. Peter Anvin @ 2011-01-02  0:40 UTC (permalink / raw)
  To: Grant Likely
  Cc: Sebastian Andrzej Siewior, linux-kernel, sodaville, x86,
	devicetree-discuss, Thomas Gleixner

On 12/30/2010 01:01 PM, Grant Likely wrote:
> Hi Peter,
> 
> Since this series is based on the tip tree, these should be merged via
> the same route.  Aside from the comments below, I'm okay with patches
> 1 & 2 going in for 2.6.38 (assuming NO_IRQ is fixed).  I've picked up
> patch 12 since it is a generic fix.  I haven't made a decision on the
> remaining 14 yet.
> 

OK... I'll see if I can get it into -tip early next week.  I don't know
how much time there is left before the .38 merge window opens, but I
don't think there is too much.

(tglx: if you want to put it instead of me, go for it and feel free to
add my Ack.)

	-hpa

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 02/15] x86: Add device tree support
@ 2011-01-02  0:40         ` H. Peter Anvin
  0 siblings, 0 replies; 106+ messages in thread
From: H. Peter Anvin @ 2011-01-02  0:40 UTC (permalink / raw)
  To: Grant Likely
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	x86-DgEjT+Ai2ygdnm+yROfE0A, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	sodaville-hfZtesqFncYOwBW4kG4KsQ, Thomas Gleixner,
	Sebastian Andrzej Siewior

On 12/30/2010 01:01 PM, Grant Likely wrote:
> Hi Peter,
> 
> Since this series is based on the tip tree, these should be merged via
> the same route.  Aside from the comments below, I'm okay with patches
> 1 & 2 going in for 2.6.38 (assuming NO_IRQ is fixed).  I've picked up
> patch 12 since it is a generic fix.  I haven't made a decision on the
> remaining 14 yet.
> 

OK... I'll see if I can get it into -tip early next week.  I don't know
how much time there is left before the .38 merge window opens, but I
don't think there is too much.

(tglx: if you want to put it instead of me, go for it and feel free to
add my Ack.)

	-hpa

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 03/15] x86/dtb: Add a device tree for CE4100
@ 2011-01-03 11:28       ` Sebastian Andrzej Siewior
  0 siblings, 0 replies; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2011-01-03 11:28 UTC (permalink / raw)
  To: Grant Likely; +Cc: linux-kernel, sodaville, x86, devicetree-discuss

Grant Likely wrote:

>> diff --git a/arch/x86/platform/ce4100/falconfalls.dts b/arch/x86/platform/ce4100/falconfalls.dts
>> new file mode 100644
>> index 0000000..24e67ca
>> --- /dev/null
>> +++ b/arch/x86/platform/ce4100/falconfalls.dts
>> +
>> +				i2c@15a00 {
>> +					#address-cells = <1>;
>> +					#size-cells = <0>;
>> +					reg = <0x15a00 0x0 0x0 0x0>;
>> +
>> +
>> +					i2c@0 {
>> +						reg = <0>;
>> +					};
>> +
>> +					i2c@1 {
>> +						#address-cells = <1>;
>> +						#size-cells = <0>;
>> +						reg = <1>;
>> +
>> +						pcf8575@26 {
>> +							compatible = "ti,pcf8575";
>> +							reg = <0x26>;
>> +						};
>> +					};
>> +
>> +					i2c@2 {
>> +						#address-cells = <1>;
>> +						#size-cells = <0>;
>> +						reg = <2>;
>> +
>> +						pcf8575@26 {
>> +							compatible = "ti,pcf8575";
>> +							reg = <0x26>;
>> +						};
>> +					};
> 
> All these i2c bus controllers should have a compatible value so that
> the OS knows what driver to bind to them.

The node i2c@15a00 is the PCI device. This PCI device has three bars, each
bar is a complete i2c controller. All three controller share one IRQ. The
device is probed via its pci-id and therefore I have no compatible value
here. Do you want me to add compatible values based on "Vendor ID, Device
ID, Subsystem Vendor ID, ..." as mention in the PCI-bindings?

The child nodes here (i2c@0,...) represent the bars. I probably should
replace i2c@0 with bar@0 and the reg property with a bar property. Would
that be okay?

> Also, the node names for the i2c devices should reflect what the
> device does, not what the part number is (grep ePAPR for 'generic
> names')
Okay. This probably also means that I should replace pic@ with 
interrupt-controller and so on.

Sebastian

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 03/15] x86/dtb: Add a device tree for CE4100
@ 2011-01-03 11:28       ` Sebastian Andrzej Siewior
  0 siblings, 0 replies; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2011-01-03 11:28 UTC (permalink / raw)
  To: Grant Likely
  Cc: sodaville-hfZtesqFncYOwBW4kG4KsQ,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	x86-DgEjT+Ai2ygdnm+yROfE0A, linux-kernel-u79uwXL29TY76Z2rM5mHXA

Grant Likely wrote:

>> diff --git a/arch/x86/platform/ce4100/falconfalls.dts b/arch/x86/platform/ce4100/falconfalls.dts
>> new file mode 100644
>> index 0000000..24e67ca
>> --- /dev/null
>> +++ b/arch/x86/platform/ce4100/falconfalls.dts
>> +
>> +				i2c@15a00 {
>> +					#address-cells = <1>;
>> +					#size-cells = <0>;
>> +					reg = <0x15a00 0x0 0x0 0x0>;
>> +
>> +
>> +					i2c@0 {
>> +						reg = <0>;
>> +					};
>> +
>> +					i2c@1 {
>> +						#address-cells = <1>;
>> +						#size-cells = <0>;
>> +						reg = <1>;
>> +
>> +						pcf8575@26 {
>> +							compatible = "ti,pcf8575";
>> +							reg = <0x26>;
>> +						};
>> +					};
>> +
>> +					i2c@2 {
>> +						#address-cells = <1>;
>> +						#size-cells = <0>;
>> +						reg = <2>;
>> +
>> +						pcf8575@26 {
>> +							compatible = "ti,pcf8575";
>> +							reg = <0x26>;
>> +						};
>> +					};
> 
> All these i2c bus controllers should have a compatible value so that
> the OS knows what driver to bind to them.

The node i2c@15a00 is the PCI device. This PCI device has three bars, each
bar is a complete i2c controller. All three controller share one IRQ. The
device is probed via its pci-id and therefore I have no compatible value
here. Do you want me to add compatible values based on "Vendor ID, Device
ID, Subsystem Vendor ID, ..." as mention in the PCI-bindings?

The child nodes here (i2c@0,...) represent the bars. I probably should
replace i2c@0 with bar@0 and the reg property with a bar property. Would
that be okay?

> Also, the node names for the i2c devices should reflect what the
> device does, not what the part number is (grep ePAPR for 'generic
> names')
Okay. This probably also means that I should replace pic@ with 
interrupt-controller and so on.

Sebastian

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 02/15] x86: Add device tree support
@ 2011-01-03 12:20       ` Sebastian Andrzej Siewior
  0 siblings, 0 replies; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2011-01-03 12:20 UTC (permalink / raw)
  To: Grant Likely; +Cc: linux-kernel, sodaville, x86, devicetree-discuss

Grant Likely wrote:
>> +extern char cmd_line[COMMAND_LINE_SIZE];
>> +/* This number is used when no interrupt has been assigned */
>> +#define NO_IRQ		(-1)
> 
> 0 means NO_IRQ on x86 and most architectures.  I will change this when
> I pick up the patch.

cat /proc/interrupts
            CPU0
   0:         40   IO-APIC-edge      timer

>> diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
>> index 577d06b..26f2c9a 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.
>> @@ -445,6 +446,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;
> 
> Why is the physical address being passed in when the virtual address
> is needed to be stored in initial_boot_params by add_dtb()?

add_dtb() changes it via phys_to_virt() so it is stored as virtual. I
can't touch this memory that early in the boot process so it is passed as
phys. phys_to_virt() isn't working (yet) so you need a fixmap or an
early_ioremap(). Earlier I used the device tree very late so the
phys_to_virt() memory was working.

Later in the series add_dtb() stores it in a custom u64 variable because I 
might have to use the built-in dtb, I have to relocate the dtb (so the
boot loader does not have to care about kernel's memory layout) and I have
to use it "early" so I create a fixmap for it.

The dtb is not usable before the ->get_config() hook (x86_dtb_get_config, 
patch #5) is called. After that initial_boot_params is set and can be used.

>>  		default:
>>  			break;
>>  		}
>> -- 
>> 1.7.3.2

Sebastian

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 02/15] x86: Add device tree support
@ 2011-01-03 12:20       ` Sebastian Andrzej Siewior
  0 siblings, 0 replies; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2011-01-03 12:20 UTC (permalink / raw)
  To: Grant Likely
  Cc: sodaville-hfZtesqFncYOwBW4kG4KsQ,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	x86-DgEjT+Ai2ygdnm+yROfE0A, linux-kernel-u79uwXL29TY76Z2rM5mHXA

Grant Likely wrote:
>> +extern char cmd_line[COMMAND_LINE_SIZE];
>> +/* This number is used when no interrupt has been assigned */
>> +#define NO_IRQ		(-1)
> 
> 0 means NO_IRQ on x86 and most architectures.  I will change this when
> I pick up the patch.

cat /proc/interrupts
            CPU0
   0:         40   IO-APIC-edge      timer

>> diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
>> index 577d06b..26f2c9a 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.
>> @@ -445,6 +446,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;
> 
> Why is the physical address being passed in when the virtual address
> is needed to be stored in initial_boot_params by add_dtb()?

add_dtb() changes it via phys_to_virt() so it is stored as virtual. I
can't touch this memory that early in the boot process so it is passed as
phys. phys_to_virt() isn't working (yet) so you need a fixmap or an
early_ioremap(). Earlier I used the device tree very late so the
phys_to_virt() memory was working.

Later in the series add_dtb() stores it in a custom u64 variable because I 
might have to use the built-in dtb, I have to relocate the dtb (so the
boot loader does not have to care about kernel's memory layout) and I have
to use it "early" so I create a fixmap for it.

The dtb is not usable before the ->get_config() hook (x86_dtb_get_config, 
patch #5) is called. After that initial_boot_params is set and can be used.

>>  		default:
>>  			break;
>>  		}
>> -- 
>> 1.7.3.2

Sebastian

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 03/15] x86/dtb: Add a device tree for CE4100
  2011-01-03 11:28       ` Sebastian Andrzej Siewior
  (?)
@ 2011-01-03 17:45       ` Grant Likely
  2011-01-05  9:48           ` Sebastian Andrzej Siewior
  -1 siblings, 1 reply; 106+ messages in thread
From: Grant Likely @ 2011-01-03 17:45 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: linux-kernel, sodaville, x86, devicetree-discuss

On Mon, Jan 03, 2011 at 12:28:24PM +0100, Sebastian Andrzej Siewior wrote:
> Grant Likely wrote:
> 
> >>diff --git a/arch/x86/platform/ce4100/falconfalls.dts b/arch/x86/platform/ce4100/falconfalls.dts
> >>new file mode 100644
> >>index 0000000..24e67ca
> >>--- /dev/null
> >>+++ b/arch/x86/platform/ce4100/falconfalls.dts
> >>+
> >>+				i2c@15a00 {
> >>+					#address-cells = <1>;
> >>+					#size-cells = <0>;
> >>+					reg = <0x15a00 0x0 0x0 0x0>;
> >>+
> >>+
> >>+					i2c@0 {
> >>+						reg = <0>;
> >>+					};
> >>+
> >>+					i2c@1 {
> >>+						#address-cells = <1>;
> >>+						#size-cells = <0>;
> >>+						reg = <1>;
> >>+
> >>+						pcf8575@26 {
> >>+							compatible = "ti,pcf8575";
> >>+							reg = <0x26>;
> >>+						};
> >>+					};
> >>+
> >>+					i2c@2 {
> >>+						#address-cells = <1>;
> >>+						#size-cells = <0>;
> >>+						reg = <2>;
> >>+
> >>+						pcf8575@26 {
> >>+							compatible = "ti,pcf8575";
> >>+							reg = <0x26>;
> >>+						};
> >>+					};
> >
> >All these i2c bus controllers should have a compatible value so that
> >the OS knows what driver to bind to them.
> 
> The node i2c@15a00 is the PCI device. This PCI device has three bars, each
> bar is a complete i2c controller. All three controller share one IRQ. The
> device is probed via its pci-id and therefore I have no compatible value
> here. Do you want me to add compatible values based on "Vendor ID, Device
> ID, Subsystem Vendor ID, ..." as mention in the PCI-bindings?

If you have a node describing a device, then it *must* have a
compatible value.  Use the OF PCI binding to determine what the
compatible value should be something like:

compatible = "pciVVVV,DDDD,SSSS,ssss", "pciVVVV,DDDD"

See page 9 on this pdf: http://www.openbios.org/data/docs/bus.pci.pdf

The list of possible formats in the binding doc is long, but most of
them probably don't apply in your case (but include the other entries
if they do).

Also, since the i2c@15a00 is *not* an actual i2c bus, it should not be
named 'i2c@...'.  Name it something like i2c-controller@15a00,0,0.

You'll also note that I added ',0,0' to the end of the address.
That's because the node address reflects the parent bus address format
which uses 3 cells in this case.

> The child nodes here (i2c@0,...) represent the bars. I probably should
> replace i2c@0 with bar@0 and the reg property with a bar property. Would
> that be okay?

That depends.  Are the child nodes separately memory mapped devices?
Or are all three controlled by a shared register bank in the
controller?  If they are addressable (which they probably are) then
you need to use a ranges property to describe the translation from the
parent node to the child node.  Since you say that the registers
define describe the bars, it probably makes sense to use a 2 cell
addressing scheme: one cell for the bar# and one cell for the offset
off the bar base address (which will be 0 for each I expect).
Something like this:


	i2c-controller@15a00 {
		compatible = "intel,<blah>", "pciVVVV,DDDD,SSSS,ssss", "pciVVVV,DDDD";
		#address-cells = <2>;
		#size-cells = <1>;	// not 0!  0 is used for
					// devices that cannot be
					// memory mapped.
		reg = <0x15a00 0x0 0x0 0x0>;

		// 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 example assumes that each child node has it's
		// own range of memory mapped registers.
		ranges = <0 0   0x02000000 0 0xa0000000   0x1000>
			 <1 0   0x02000000 0 0xa0002000   0x1000>
			 <2 0   0x02000000 0 0xa0004000   0x1000>


		i2c@0,0 {
			#address-cells = <1>
			#size-cells = <0>;
			compatible = <need something here>;
			reg = <1 0  0x1000>;
		};

		i2c@1,0 {
			#address-cells = <1>;
			#size-cells = <0>;
			compatible = <need something here>;
			reg = <1 0 0x1000>;

			pcf8575@26 {
				compatible = "ti,pcf8575";
				reg = <0x26>;
			};
		};

		i2c@2,0 {
			#address-cells = <1>;
			#size-cells = <0>;
			compatible = <need something here>;
			reg = <2 0 0x1000>;

			pcf8575@26 {
				compatible = "ti,pcf8575";
				reg = <0x26>;
			};
		};

> 
> >Also, the node names for the i2c devices should reflect what the
> >device does, not what the part number is (grep ePAPR for 'generic
> >names')
> Okay. This probably also means that I should replace pic@ with
> interrupt-controller and so on.

Correct.

g.


^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [sodaville] [PATCH 02/15] x86: Add device tree support
  2011-01-03 12:20       ` Sebastian Andrzej Siewior
  (?)
@ 2011-01-03 18:05       ` H. Peter Anvin
  -1 siblings, 0 replies; 106+ messages in thread
From: H. Peter Anvin @ 2011-01-03 18:05 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: Grant Likely, sodaville, devicetree-discuss, x86, linux-kernel

On 01/03/2011 04:20 AM, Sebastian Andrzej Siewior wrote:
> Grant Likely wrote:
>>> +extern char cmd_line[COMMAND_LINE_SIZE];
>>> +/* This number is used when no interrupt has been assigned */
>>> +#define NO_IRQ		(-1)
>>
>> 0 means NO_IRQ on x86 and most architectures.  I will change this when
>> I pick up the patch.
> 
> cat /proc/interrupts
>             CPU0
>    0:         40   IO-APIC-edge      timer
> 

0 for the timer is special.  However, Linus has declared that NO_IRQ is
to be zero, and that only very special interrupts like the PIT timer are
allowed to break that.

	-hpa

^ permalink raw reply	[flat|nested] 106+ messages in thread

* [PATCH v2 01/15] x86/e820: remove conditional early mapping in parse_e820_ext
  2010-12-30  8:37   ` Grant Likely
@ 2011-01-04 13:08     ` Sebastian Andrzej Siewior
  2011-01-14  8:14       ` Grant Likely
  0 siblings, 1 reply; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2011-01-04 13:08 UTC (permalink / raw)
  To: Grant Likely
  Cc: Sebastian Andrzej Siewior, linux-kernel, sodaville, x86, dirk.brandewie

This patch ensures that the memory passed from parse_setup_data() is
large enough to cover the complete data structure. That means that the
conditional mapping in parse_e820_ext() can go.

While here, I also attempt not to map two pages if the address is not
aligned to a page boundary.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Dirk Brandewie <dirk.brandewie@gmail.com>
---
 arch/x86/include/asm/e820.h |    2 +-
 arch/x86/kernel/e820.c      |    8 +-------
 arch/x86/kernel/setup.c     |   18 +++++++++++++++---
 3 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/arch/x86/include/asm/e820.h b/arch/x86/include/asm/e820.h
index 5be1542..e956492 100644
--- a/arch/x86/include/asm/e820.h
+++ b/arch/x86/include/asm/e820.h
@@ -93,7 +93,7 @@ extern void e820_setup_gap(void);
 extern int e820_search_gap(unsigned long *gapstart, unsigned long *gapsize,
 			unsigned long start_addr, unsigned long long end_addr);
 struct setup_data;
-extern void parse_e820_ext(struct setup_data *data, unsigned long pa_data);
+extern void parse_e820_ext(struct setup_data *data);
 
 #if defined(CONFIG_X86_64) || \
 	(defined(CONFIG_X86_32) && defined(CONFIG_HIBERNATION))
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index 0c2b7ef..33f6361 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -666,21 +666,15 @@ __init void e820_setup_gap(void)
  * boot_params.e820_map, others are passed via SETUP_E820_EXT node of
  * linked list of struct setup_data, which is parsed here.
  */
-void __init parse_e820_ext(struct setup_data *sdata, unsigned long pa_data)
+void __init parse_e820_ext(struct setup_data *sdata)
 {
-	u32 map_len;
 	int entries;
 	struct e820entry *extmap;
 
 	entries = sdata->len / sizeof(struct e820entry);
-	map_len = sdata->len + sizeof(struct setup_data);
-	if (map_len > PAGE_SIZE)
-		sdata = early_ioremap(pa_data, map_len);
 	extmap = (struct e820entry *)(sdata->data);
 	__append_e820_map(extmap, entries);
 	sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
-	if (map_len > PAGE_SIZE)
-		early_iounmap(sdata, map_len);
 	printk(KERN_INFO "extended physical RAM map:\n");
 	e820_print_map("extended");
 }
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 0afb8c7..48e240e 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -429,16 +429,28 @@ static void __init parse_setup_data(void)
 		return;
 	pa_data = boot_params.hdr.setup_data;
 	while (pa_data) {
-		data = early_memremap(pa_data, PAGE_SIZE);
+		u32 data_len;
+		u32 map_len;
+
+		map_len = max(PAGE_SIZE - (pa_data & ~PAGE_MASK),
+				(u64)sizeof(struct setup_data));
+		data = early_memremap(pa_data, map_len);
+		data_len = data->len + sizeof(struct setup_data);
+		if (data_len > map_len) {
+			early_iounmap(data, map_len);
+			data = early_memremap(pa_data, data_len);
+			map_len = data_len;
+		}
+
 		switch (data->type) {
 		case SETUP_E820_EXT:
-			parse_e820_ext(data, pa_data);
+			parse_e820_ext(data);
 			break;
 		default:
 			break;
 		}
 		pa_data = data->next;
-		early_iounmap(data, PAGE_SIZE);
+		early_iounmap(data, map_len);
 	}
 }
 
-- 
1.7.3.2


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH v2 05/15] x86/dtb: add early parsing of APIC and IO APIC
  2010-12-30  8:54     ` Grant Likely
  (?)
@ 2011-01-04 13:23     ` Sebastian Andrzej Siewior
  2011-01-11 22:14         ` Grant Likely
  -1 siblings, 1 reply; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2011-01-04 13:23 UTC (permalink / raw)
  To: Grant Likely
  Cc: Sebastian Andrzej Siewior, linux-kernel, sodaville, x86,
	devicetree-discuss

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@lists.ozlabs.org
Cc: Dirk Brandewie <dirk.brandewie@gmail.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
 arch/x86/include/asm/prom.h |    7 +++
 arch/x86/kernel/irqinit.c   |    2 +-
 arch/x86/kernel/prom.c      |  121 +++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 126 insertions(+), 4 deletions(-)

diff --git a/arch/x86/include/asm/prom.h b/arch/x86/include/asm/prom.h
index 9076ae4..3bc8ed5 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/irqinit.c b/arch/x86/kernel/irqinit.c
index 149c87f..4cadf86 100644
--- a/arch/x86/kernel/irqinit.c
+++ b/arch/x86/kernel/irqinit.c
@@ -244,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
diff --git a/arch/x86/kernel/prom.c b/arch/x86/kernel/prom.c
index 53948cb..388fdff 100644
--- a/arch/x86/kernel/prom.c
+++ b/arch/x86/kernel/prom.c
@@ -6,15 +6,20 @@
 #include <linux/interrupt.h>
 #include <linux/list.h>
 #include <linux/of.h>
+#include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <linux/slab.h>
 
 #include <asm/irq_controller.h>
+#include <asm/io_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;
@@ -93,7 +98,117 @@ u64 __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
 
 void __init add_dtb(u64 data)
 {
-	initial_boot_params = (struct boot_param_header *)
-		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 void __init dtb_add_ioapic(struct device_node *dn)
+{
+	unsigned int ioapic_id;
+	const __be32 *cell;
+	int len;
+	struct resource r;
+	int ret;
+
+	cell = of_get_property(dn, "id", &len);
+	if (!cell) {
+		printk(KERN_ERR "Node %s is missing id property.\n",
+				dn->full_name);
+		return;
+	}
+	ioapic_id = of_read_ulong(cell, len / 4);
+
+	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,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();
 }
-- 
1.7.3.2


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH v2 13/15] x86/rtc: don't register rtc if we the DT blob
  2010-12-30  8:59   ` Grant Likely
@ 2011-01-04 13:28     ` Sebastian Andrzej Siewior
  2011-01-12  0:02       ` Grant Likely
  0 siblings, 1 reply; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2011-01-04 13:28 UTC (permalink / raw)
  To: Grant Likely
  Cc: Sebastian Andrzej Siewior, linux-kernel, sodaville, x86, dirk.brandewie

or we might end up with two device nodes for the same hardware.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
 arch/x86/kernel/rtc.c |   18 ++++++++++++++++++
 1 files changed, 18 insertions(+), 0 deletions(-)

diff --git a/arch/x86/kernel/rtc.c b/arch/x86/kernel/rtc.c
index 1cfbbfc..0cfa138 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>
@@ -218,6 +219,20 @@ static struct platform_device rtc_device = {
 	.num_resources	= ARRAY_SIZE(rtc_resources),
 };
 
+#ifdef CONFIG_OF
+static __init int have_DTB(void)
+{
+	if (initial_boot_params)
+		return 1;
+	return 0;
+}
+#else
+static inline int have_DTB(void)
+{
+	return 0;
+}
+#endif
+
 static __init int add_rtc_cmos(void)
 {
 #ifdef CONFIG_PNP
@@ -237,6 +252,9 @@ static __init int add_rtc_cmos(void)
 	}
 #endif
 
+	if (have_DTB())
+		return 0;
+
 	platform_device_register(&rtc_device);
 	dev_info(&rtc_device.dev,
 		 "registered platform RTC device (no PNP device found)\n");
-- 
1.7.3.2


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH v2 07/15] of: move of_irq_map_pci() into generic code
  2010-12-17 21:16   ` Benjamin Herrenschmidt
@ 2011-01-04 14:27       ` Sebastian Andrzej Siewior
  0 siblings, 0 replies; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2011-01-04 14:27 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Sebastian Andrzej Siewior, linux-kernel, sodaville, x86,
	dirk.brandewie, Sebastian Andrzej Siewior, devicetree-discuss

From: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>

There is a tiny difference between PPC32 and PPC64. Microblaze uses the
PPC32 variant.

Cc: devicetree-discuss@lists.ozlabs.org
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
---
 arch/microblaze/include/asm/pci-bridge.h |   10 ++++
 arch/microblaze/include/asm/prom.h       |   15 -----
 arch/microblaze/kernel/prom_parse.c      |   77 ---------------------------
 arch/microblaze/pci/pci-common.c         |    1 +
 arch/powerpc/include/asm/pci-bridge.h    |   10 ++++
 arch/powerpc/include/asm/prom.h          |   15 -----
 arch/powerpc/kernel/pci-common.c         |    1 +
 arch/powerpc/kernel/prom_parse.c         |   84 ------------------------------
 drivers/of/Makefile                      |    1 +
 drivers/of/of_pci.c                      |   80 ++++++++++++++++++++++++++++
 include/linux/of_pci.h                   |   20 +++++++
 11 files changed, 123 insertions(+), 191 deletions(-)
 create mode 100644 drivers/of/of_pci.c
 create mode 100644 include/linux/of_pci.h

diff --git a/arch/microblaze/include/asm/pci-bridge.h b/arch/microblaze/include/asm/pci-bridge.h
index 0c68764..0808217 100644
--- a/arch/microblaze/include/asm/pci-bridge.h
+++ b/arch/microblaze/include/asm/pci-bridge.h
@@ -109,6 +109,16 @@ static inline struct pci_controller *pci_bus_to_host(const struct pci_bus *bus)
 	return bus->sysdata;
 }
 
+static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
+{
+	struct pci_controller *host;
+
+	if (bus->self)
+		return pci_device_to_OF_node(bus->self);
+	host = pci_bus_to_host(bus);
+	return host ? host->dn : NULL;
+}
+
 static inline int isa_vaddr_is_ioport(void __iomem *address)
 {
 	/* No specific ISA handling on ppc32 at this stage, it
diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h
index bdc3831..aa3ab12 100644
--- a/arch/microblaze/include/asm/prom.h
+++ b/arch/microblaze/include/asm/prom.h
@@ -67,21 +67,6 @@ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
 /* Get the MAC address */
 extern const void *of_get_mac_address(struct device_node *np);
 
-/**
- * of_irq_map_pci - Resolve the interrupt for a PCI device
- * @pdev:	the device whose interrupt is to be resolved
- * @out_irq:	structure of_irq filled by this function
- *
- * This function resolves the PCI interrupt for a given PCI device. If a
- * device-node exists for a given pci_dev, it will use normal OF tree
- * walking. If not, it will implement standard swizzling and walk up the
- * PCI tree until an device-node is found, at which point it will finish
- * resolving using the OF tree walking.
- */
-struct pci_dev;
-struct of_irq;
-extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
-
 #endif /* __ASSEMBLY__ */
 #endif /* __KERNEL__ */
 
diff --git a/arch/microblaze/kernel/prom_parse.c b/arch/microblaze/kernel/prom_parse.c
index 99d9b61..306f41d 100644
--- a/arch/microblaze/kernel/prom_parse.c
+++ b/arch/microblaze/kernel/prom_parse.c
@@ -2,88 +2,11 @@
 
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/pci_regs.h>
 #include <linux/module.h>
 #include <linux/ioport.h>
 #include <linux/etherdevice.h>
 #include <linux/of_address.h>
 #include <asm/prom.h>
-#include <asm/pci-bridge.h>
-
-#ifdef CONFIG_PCI
-int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
-{
-	struct device_node *dn, *ppnode;
-	struct pci_dev *ppdev;
-	u32 lspec;
-	u32 laddr[3];
-	u8 pin;
-	int rc;
-
-	/* Check if we have a device node, if yes, fallback to standard OF
-	 * parsing
-	 */
-	dn = pci_device_to_OF_node(pdev);
-	if (dn)
-		return of_irq_map_one(dn, 0, out_irq);
-
-	/* Ok, we don't, time to have fun. Let's start by building up an
-	 * interrupt spec.  we assume #interrupt-cells is 1, which is standard
-	 * for PCI. If you do different, then don't use that routine.
-	 */
-	rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
-	if (rc != 0)
-		return rc;
-	/* No pin, exit */
-	if (pin == 0)
-		return -ENODEV;
-
-	/* Now we walk up the PCI tree */
-	lspec = pin;
-	for (;;) {
-		/* Get the pci_dev of our parent */
-		ppdev = pdev->bus->self;
-
-		/* Ouch, it's a host bridge... */
-		if (ppdev == NULL) {
-			struct pci_controller *host;
-			host = pci_bus_to_host(pdev->bus);
-			ppnode = host ? host->dn : NULL;
-			/* No node for host bridge ? give up */
-			if (ppnode == NULL)
-				return -EINVAL;
-		} else
-			/* We found a P2P bridge, check if it has a node */
-			ppnode = pci_device_to_OF_node(ppdev);
-
-		/* Ok, we have found a parent with a device-node, hand over to
-		 * the OF parsing code.
-		 * We build a unit address from the linux device to be used for
-		 * resolution. Note that we use the linux bus number which may
-		 * not match your firmware bus numbering.
-		 * Fortunately, in most cases, interrupt-map-mask doesn't
-		 * include the bus number as part of the matching.
-		 * You should still be careful about that though if you intend
-		 * to rely on this function (you ship  a firmware that doesn't
-		 * create device nodes for all PCI devices).
-		 */
-		if (ppnode)
-			break;
-
-		/* We can only get here if we hit a P2P bridge with no node,
-		 * let's do standard swizzling and try again
-		 */
-		lspec = pci_swizzle_interrupt_pin(pdev, lspec);
-		pdev = ppdev;
-	}
-
-	laddr[0] = (pdev->bus->number << 16)
-		| (pdev->devfn << 8);
-	laddr[1]  = laddr[2] = 0;
-	return of_irq_map_raw(ppnode, &lspec, 1, laddr, out_irq);
-}
-EXPORT_SYMBOL_GPL(of_irq_map_pci);
-#endif /* CONFIG_PCI */
 
 void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
 		unsigned long *busno, unsigned long *phys, unsigned long *size)
diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c
index e363615..1e01a12 100644
--- a/arch/microblaze/pci/pci-common.c
+++ b/arch/microblaze/pci/pci-common.c
@@ -29,6 +29,7 @@
 #include <linux/slab.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/of_pci.h>
 
 #include <asm/processor.h>
 #include <asm/io.h>
diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h
index 51e9e6f..edeb80f 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)
 	return bus->sysdata;
 }
 
+static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
+{
+	struct pci_controller *host;
+
+	if (bus->self)
+		return pci_device_to_OF_node(bus->self);
+	host = pci_bus_to_host(bus);
+	return host ? host->dn : NULL;
+}
+
 static inline int isa_vaddr_is_ioport(void __iomem *address)
 {
 	/* No specific ISA handling on ppc32 at this stage, it
diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h
index ae26f2e..01c3302 100644
--- a/arch/powerpc/include/asm/prom.h
+++ b/arch/powerpc/include/asm/prom.h
@@ -73,21 +73,6 @@ static inline int of_node_to_nid(struct device_node *device) { return 0; }
 #endif
 #define of_node_to_nid of_node_to_nid
 
-/**
- * of_irq_map_pci - Resolve the interrupt for a PCI device
- * @pdev:	the device whose interrupt is to be resolved
- * @out_irq:	structure of_irq filled by this function
- *
- * This function resolves the PCI interrupt for a given PCI device. If a
- * device-node exists for a given pci_dev, it will use normal OF tree
- * walking. If not, it will implement standard swizzling and walk up the
- * PCI tree until an device-node is found, at which point it will finish
- * resolving using the OF tree walking.
- */
-struct pci_dev;
-struct of_irq;
-extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
-
 extern void of_instantiate_rtc(void);
 
 /* These includes are put at the bottom because they may contain things
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 10a44e6..eb341be 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -22,6 +22,7 @@
 #include <linux/init.h>
 #include <linux/bootmem.h>
 #include <linux/of_address.h>
+#include <linux/of_pci.h>
 #include <linux/mm.h>
 #include <linux/list.h>
 #include <linux/syscalls.h>
diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c
index 88334af..306f41d 100644
--- a/arch/powerpc/kernel/prom_parse.c
+++ b/arch/powerpc/kernel/prom_parse.c
@@ -2,95 +2,11 @@
 
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/pci_regs.h>
 #include <linux/module.h>
 #include <linux/ioport.h>
 #include <linux/etherdevice.h>
 #include <linux/of_address.h>
 #include <asm/prom.h>
-#include <asm/pci-bridge.h>
-
-#ifdef CONFIG_PCI
-int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
-{
-	struct device_node *dn, *ppnode;
-	struct pci_dev *ppdev;
-	u32 lspec;
-	u32 laddr[3];
-	u8 pin;
-	int rc;
-
-	/* Check if we have a device node, if yes, fallback to standard OF
-	 * parsing
-	 */
-	dn = pci_device_to_OF_node(pdev);
-	if (dn) {
-		rc = of_irq_map_one(dn, 0, out_irq);
-		if (!rc)
-			return rc;
-	}
-
-	/* Ok, we don't, time to have fun. Let's start by building up an
-	 * interrupt spec.  we assume #interrupt-cells is 1, which is standard
-	 * for PCI. If you do different, then don't use that routine.
-	 */
-	rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
-	if (rc != 0)
-		return rc;
-	/* No pin, exit */
-	if (pin == 0)
-		return -ENODEV;
-
-	/* Now we walk up the PCI tree */
-	lspec = pin;
-	for (;;) {
-		/* Get the pci_dev of our parent */
-		ppdev = pdev->bus->self;
-
-		/* Ouch, it's a host bridge... */
-		if (ppdev == NULL) {
-#ifdef CONFIG_PPC64
-			ppnode = pci_bus_to_OF_node(pdev->bus);
-#else
-			struct pci_controller *host;
-			host = pci_bus_to_host(pdev->bus);
-			ppnode = host ? host->dn : NULL;
-#endif
-			/* No node for host bridge ? give up */
-			if (ppnode == NULL)
-				return -EINVAL;
-		} else
-			/* We found a P2P bridge, check if it has a node */
-			ppnode = pci_device_to_OF_node(ppdev);
-
-		/* Ok, we have found a parent with a device-node, hand over to
-		 * the OF parsing code.
-		 * We build a unit address from the linux device to be used for
-		 * resolution. Note that we use the linux bus number which may
-		 * not match your firmware bus numbering.
-		 * Fortunately, in most cases, interrupt-map-mask doesn't include
-		 * the bus number as part of the matching.
-		 * You should still be careful about that though if you intend
-		 * to rely on this function (you ship  a firmware that doesn't
-		 * create device nodes for all PCI devices).
-		 */
-		if (ppnode)
-			break;
-
-		/* We can only get here if we hit a P2P bridge with no node,
-		 * let's do standard swizzling and try again
-		 */
-		lspec = pci_swizzle_interrupt_pin(pdev, lspec);
-		pdev = ppdev;
-	}
-
-	laddr[0] = (pdev->bus->number << 16)
-		| (pdev->devfn << 8);
-	laddr[1]  = laddr[2] = 0;
-	return of_irq_map_raw(ppnode, &lspec, 1, laddr, out_irq);
-}
-EXPORT_SYMBOL_GPL(of_irq_map_pci);
-#endif /* CONFIG_PCI */
 
 void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
 		unsigned long *busno, unsigned long *phys, unsigned long *size)
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index 7888155..4dcb177 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_OF_GPIO)   += gpio.o
 obj-$(CONFIG_OF_I2C)	+= of_i2c.o
 obj-$(CONFIG_OF_SPI)	+= of_spi.o
 obj-$(CONFIG_OF_MDIO)	+= of_mdio.o
+obj-$(CONFIG_PCI)	+= of_pci.o
diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
new file mode 100644
index 0000000..dd862d2
--- /dev/null
+++ b/drivers/of/of_pci.c
@@ -0,0 +1,80 @@
+#include <linux/kernel.h>
+#include <linux/of_pci.h>
+#include <asm/prom.h>
+
+int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
+{
+	struct device_node *dn, *ppnode;
+	struct pci_dev *ppdev;
+	u32 lspec;
+	__be32 lspec_be;
+	__be32 laddr[3];
+	u8 pin;
+	int rc;
+
+	/* Check if we have a device node, if yes, fallback to standard OF
+	 * parsing
+	 */
+	dn = pci_device_to_OF_node(pdev);
+	if (dn) {
+		rc = of_irq_map_one(dn, 0, out_irq);
+		if (!rc)
+			return rc;
+	}
+
+	/* Ok, we don't, time to have fun. Let's start by building up an
+	 * interrupt spec.  we assume #interrupt-cells is 1, which is standard
+	 * for PCI. If you do different, then don't use that routine.
+	 */
+	rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
+	if (rc != 0)
+		return rc;
+	/* No pin, exit */
+	if (pin == 0)
+		return -ENODEV;
+
+	/* Now we walk up the PCI tree */
+	lspec = pin;
+	for (;;) {
+		/* Get the pci_dev of our parent */
+		ppdev = pdev->bus->self;
+
+		/* Ouch, it's a host bridge... */
+		if (ppdev == NULL) {
+			ppnode = pci_bus_to_OF_node(pdev->bus);
+
+			/* No node for host bridge ? give up */
+			if (ppnode == NULL)
+				return -EINVAL;
+		} else {
+			/* We found a P2P bridge, check if it has a node */
+			ppnode = pci_device_to_OF_node(ppdev);
+		}
+
+		/* Ok, we have found a parent with a device-node, hand over to
+		 * the OF parsing code.
+		 * We build a unit address from the linux device to be used for
+		 * resolution. Note that we use the linux bus number which may
+		 * not match your firmware bus numbering.
+		 * Fortunately, in most cases, interrupt-map-mask doesn't
+		 * include the bus number as part of the matching.
+		 * You should still be careful about that though if you intend
+		 * to rely on this function (you ship  a firmware that doesn't
+		 * create device nodes for all PCI devices).
+		 */
+		if (ppnode)
+			break;
+
+		/* We can only get here if we hit a P2P bridge with no node,
+		 * let's do standard swizzling and try again
+		 */
+		lspec = pci_swizzle_interrupt_pin(pdev, lspec);
+		pdev = ppdev;
+	}
+
+	lspec_be = cpu_to_be32(lspec);
+	laddr[0] = cpu_to_be32((pdev->bus->number << 16) | (pdev->devfn << 8));
+	laddr[1]  = laddr[2] = cpu_to_be32(0);
+	return of_irq_map_raw(ppnode, &lspec_be, 1, laddr, out_irq);
+}
+EXPORT_SYMBOL_GPL(of_irq_map_pci);
diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h
new file mode 100644
index 0000000..9b0ba67
--- /dev/null
+++ b/include/linux/of_pci.h
@@ -0,0 +1,20 @@
+#ifndef __OF_PCI_H
+#define __OF_PCI_H
+
+#include <linux/pci.h>
+
+/**
+ * of_irq_map_pci - Resolve the interrupt for a PCI device
+ * @pdev:       the device whose interrupt is to be resolved
+ * @out_irq:    structure of_irq filled by this function
+ *
+ * This function resolves the PCI interrupt for a given PCI device. If a
+ * device-node exists for a given pci_dev, it will use normal OF tree
+ * walking. If not, it will implement standard swizzling and walk up the
+ * PCI tree until an device-node is found, at which point it will finish
+ * resolving using the OF tree walking.
+ */
+struct pci_dev;
+struct of_irq;
+int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
+#endif
-- 
1.7.3.2


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH v2 07/15] of: move of_irq_map_pci() into generic code
@ 2011-01-04 14:27       ` Sebastian Andrzej Siewior
  0 siblings, 0 replies; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2011-01-04 14:27 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Sebastian Andrzej Siewior, x86-DgEjT+Ai2ygdnm+yROfE0A,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	sodaville-hfZtesqFncYOwBW4kG4KsQ, Sebastian Andrzej Siewior,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ

From: Sebastian Andrzej Siewior <sebastian-E0PNVn5OA6ohrxcnuTQ+TQ@public.gmane.org>

There is a tiny difference between PPC32 and PPC64. Microblaze uses the
PPC32 variant.

Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
Cc: Benjamin Herrenschmidt <benh-XVmvHMARGAS8U2dJNN8I7kB+6BGkLq7r@public.gmane.org>
Signed-off-by: Sebastian Andrzej Siewior <sebastian-E0PNVn5OA6ohrxcnuTQ+TQ@public.gmane.org>
---
 arch/microblaze/include/asm/pci-bridge.h |   10 ++++
 arch/microblaze/include/asm/prom.h       |   15 -----
 arch/microblaze/kernel/prom_parse.c      |   77 ---------------------------
 arch/microblaze/pci/pci-common.c         |    1 +
 arch/powerpc/include/asm/pci-bridge.h    |   10 ++++
 arch/powerpc/include/asm/prom.h          |   15 -----
 arch/powerpc/kernel/pci-common.c         |    1 +
 arch/powerpc/kernel/prom_parse.c         |   84 ------------------------------
 drivers/of/Makefile                      |    1 +
 drivers/of/of_pci.c                      |   80 ++++++++++++++++++++++++++++
 include/linux/of_pci.h                   |   20 +++++++
 11 files changed, 123 insertions(+), 191 deletions(-)
 create mode 100644 drivers/of/of_pci.c
 create mode 100644 include/linux/of_pci.h

diff --git a/arch/microblaze/include/asm/pci-bridge.h b/arch/microblaze/include/asm/pci-bridge.h
index 0c68764..0808217 100644
--- a/arch/microblaze/include/asm/pci-bridge.h
+++ b/arch/microblaze/include/asm/pci-bridge.h
@@ -109,6 +109,16 @@ static inline struct pci_controller *pci_bus_to_host(const struct pci_bus *bus)
 	return bus->sysdata;
 }
 
+static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
+{
+	struct pci_controller *host;
+
+	if (bus->self)
+		return pci_device_to_OF_node(bus->self);
+	host = pci_bus_to_host(bus);
+	return host ? host->dn : NULL;
+}
+
 static inline int isa_vaddr_is_ioport(void __iomem *address)
 {
 	/* No specific ISA handling on ppc32 at this stage, it
diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h
index bdc3831..aa3ab12 100644
--- a/arch/microblaze/include/asm/prom.h
+++ b/arch/microblaze/include/asm/prom.h
@@ -67,21 +67,6 @@ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
 /* Get the MAC address */
 extern const void *of_get_mac_address(struct device_node *np);
 
-/**
- * of_irq_map_pci - Resolve the interrupt for a PCI device
- * @pdev:	the device whose interrupt is to be resolved
- * @out_irq:	structure of_irq filled by this function
- *
- * This function resolves the PCI interrupt for a given PCI device. If a
- * device-node exists for a given pci_dev, it will use normal OF tree
- * walking. If not, it will implement standard swizzling and walk up the
- * PCI tree until an device-node is found, at which point it will finish
- * resolving using the OF tree walking.
- */
-struct pci_dev;
-struct of_irq;
-extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
-
 #endif /* __ASSEMBLY__ */
 #endif /* __KERNEL__ */
 
diff --git a/arch/microblaze/kernel/prom_parse.c b/arch/microblaze/kernel/prom_parse.c
index 99d9b61..306f41d 100644
--- a/arch/microblaze/kernel/prom_parse.c
+++ b/arch/microblaze/kernel/prom_parse.c
@@ -2,88 +2,11 @@
 
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/pci_regs.h>
 #include <linux/module.h>
 #include <linux/ioport.h>
 #include <linux/etherdevice.h>
 #include <linux/of_address.h>
 #include <asm/prom.h>
-#include <asm/pci-bridge.h>
-
-#ifdef CONFIG_PCI
-int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
-{
-	struct device_node *dn, *ppnode;
-	struct pci_dev *ppdev;
-	u32 lspec;
-	u32 laddr[3];
-	u8 pin;
-	int rc;
-
-	/* Check if we have a device node, if yes, fallback to standard OF
-	 * parsing
-	 */
-	dn = pci_device_to_OF_node(pdev);
-	if (dn)
-		return of_irq_map_one(dn, 0, out_irq);
-
-	/* Ok, we don't, time to have fun. Let's start by building up an
-	 * interrupt spec.  we assume #interrupt-cells is 1, which is standard
-	 * for PCI. If you do different, then don't use that routine.
-	 */
-	rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
-	if (rc != 0)
-		return rc;
-	/* No pin, exit */
-	if (pin == 0)
-		return -ENODEV;
-
-	/* Now we walk up the PCI tree */
-	lspec = pin;
-	for (;;) {
-		/* Get the pci_dev of our parent */
-		ppdev = pdev->bus->self;
-
-		/* Ouch, it's a host bridge... */
-		if (ppdev == NULL) {
-			struct pci_controller *host;
-			host = pci_bus_to_host(pdev->bus);
-			ppnode = host ? host->dn : NULL;
-			/* No node for host bridge ? give up */
-			if (ppnode == NULL)
-				return -EINVAL;
-		} else
-			/* We found a P2P bridge, check if it has a node */
-			ppnode = pci_device_to_OF_node(ppdev);
-
-		/* Ok, we have found a parent with a device-node, hand over to
-		 * the OF parsing code.
-		 * We build a unit address from the linux device to be used for
-		 * resolution. Note that we use the linux bus number which may
-		 * not match your firmware bus numbering.
-		 * Fortunately, in most cases, interrupt-map-mask doesn't
-		 * include the bus number as part of the matching.
-		 * You should still be careful about that though if you intend
-		 * to rely on this function (you ship  a firmware that doesn't
-		 * create device nodes for all PCI devices).
-		 */
-		if (ppnode)
-			break;
-
-		/* We can only get here if we hit a P2P bridge with no node,
-		 * let's do standard swizzling and try again
-		 */
-		lspec = pci_swizzle_interrupt_pin(pdev, lspec);
-		pdev = ppdev;
-	}
-
-	laddr[0] = (pdev->bus->number << 16)
-		| (pdev->devfn << 8);
-	laddr[1]  = laddr[2] = 0;
-	return of_irq_map_raw(ppnode, &lspec, 1, laddr, out_irq);
-}
-EXPORT_SYMBOL_GPL(of_irq_map_pci);
-#endif /* CONFIG_PCI */
 
 void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
 		unsigned long *busno, unsigned long *phys, unsigned long *size)
diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c
index e363615..1e01a12 100644
--- a/arch/microblaze/pci/pci-common.c
+++ b/arch/microblaze/pci/pci-common.c
@@ -29,6 +29,7 @@
 #include <linux/slab.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/of_pci.h>
 
 #include <asm/processor.h>
 #include <asm/io.h>
diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h
index 51e9e6f..edeb80f 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)
 	return bus->sysdata;
 }
 
+static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
+{
+	struct pci_controller *host;
+
+	if (bus->self)
+		return pci_device_to_OF_node(bus->self);
+	host = pci_bus_to_host(bus);
+	return host ? host->dn : NULL;
+}
+
 static inline int isa_vaddr_is_ioport(void __iomem *address)
 {
 	/* No specific ISA handling on ppc32 at this stage, it
diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h
index ae26f2e..01c3302 100644
--- a/arch/powerpc/include/asm/prom.h
+++ b/arch/powerpc/include/asm/prom.h
@@ -73,21 +73,6 @@ static inline int of_node_to_nid(struct device_node *device) { return 0; }
 #endif
 #define of_node_to_nid of_node_to_nid
 
-/**
- * of_irq_map_pci - Resolve the interrupt for a PCI device
- * @pdev:	the device whose interrupt is to be resolved
- * @out_irq:	structure of_irq filled by this function
- *
- * This function resolves the PCI interrupt for a given PCI device. If a
- * device-node exists for a given pci_dev, it will use normal OF tree
- * walking. If not, it will implement standard swizzling and walk up the
- * PCI tree until an device-node is found, at which point it will finish
- * resolving using the OF tree walking.
- */
-struct pci_dev;
-struct of_irq;
-extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
-
 extern void of_instantiate_rtc(void);
 
 /* These includes are put at the bottom because they may contain things
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 10a44e6..eb341be 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -22,6 +22,7 @@
 #include <linux/init.h>
 #include <linux/bootmem.h>
 #include <linux/of_address.h>
+#include <linux/of_pci.h>
 #include <linux/mm.h>
 #include <linux/list.h>
 #include <linux/syscalls.h>
diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c
index 88334af..306f41d 100644
--- a/arch/powerpc/kernel/prom_parse.c
+++ b/arch/powerpc/kernel/prom_parse.c
@@ -2,95 +2,11 @@
 
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/pci_regs.h>
 #include <linux/module.h>
 #include <linux/ioport.h>
 #include <linux/etherdevice.h>
 #include <linux/of_address.h>
 #include <asm/prom.h>
-#include <asm/pci-bridge.h>
-
-#ifdef CONFIG_PCI
-int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
-{
-	struct device_node *dn, *ppnode;
-	struct pci_dev *ppdev;
-	u32 lspec;
-	u32 laddr[3];
-	u8 pin;
-	int rc;
-
-	/* Check if we have a device node, if yes, fallback to standard OF
-	 * parsing
-	 */
-	dn = pci_device_to_OF_node(pdev);
-	if (dn) {
-		rc = of_irq_map_one(dn, 0, out_irq);
-		if (!rc)
-			return rc;
-	}
-
-	/* Ok, we don't, time to have fun. Let's start by building up an
-	 * interrupt spec.  we assume #interrupt-cells is 1, which is standard
-	 * for PCI. If you do different, then don't use that routine.
-	 */
-	rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
-	if (rc != 0)
-		return rc;
-	/* No pin, exit */
-	if (pin == 0)
-		return -ENODEV;
-
-	/* Now we walk up the PCI tree */
-	lspec = pin;
-	for (;;) {
-		/* Get the pci_dev of our parent */
-		ppdev = pdev->bus->self;
-
-		/* Ouch, it's a host bridge... */
-		if (ppdev == NULL) {
-#ifdef CONFIG_PPC64
-			ppnode = pci_bus_to_OF_node(pdev->bus);
-#else
-			struct pci_controller *host;
-			host = pci_bus_to_host(pdev->bus);
-			ppnode = host ? host->dn : NULL;
-#endif
-			/* No node for host bridge ? give up */
-			if (ppnode == NULL)
-				return -EINVAL;
-		} else
-			/* We found a P2P bridge, check if it has a node */
-			ppnode = pci_device_to_OF_node(ppdev);
-
-		/* Ok, we have found a parent with a device-node, hand over to
-		 * the OF parsing code.
-		 * We build a unit address from the linux device to be used for
-		 * resolution. Note that we use the linux bus number which may
-		 * not match your firmware bus numbering.
-		 * Fortunately, in most cases, interrupt-map-mask doesn't include
-		 * the bus number as part of the matching.
-		 * You should still be careful about that though if you intend
-		 * to rely on this function (you ship  a firmware that doesn't
-		 * create device nodes for all PCI devices).
-		 */
-		if (ppnode)
-			break;
-
-		/* We can only get here if we hit a P2P bridge with no node,
-		 * let's do standard swizzling and try again
-		 */
-		lspec = pci_swizzle_interrupt_pin(pdev, lspec);
-		pdev = ppdev;
-	}
-
-	laddr[0] = (pdev->bus->number << 16)
-		| (pdev->devfn << 8);
-	laddr[1]  = laddr[2] = 0;
-	return of_irq_map_raw(ppnode, &lspec, 1, laddr, out_irq);
-}
-EXPORT_SYMBOL_GPL(of_irq_map_pci);
-#endif /* CONFIG_PCI */
 
 void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
 		unsigned long *busno, unsigned long *phys, unsigned long *size)
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index 7888155..4dcb177 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_OF_GPIO)   += gpio.o
 obj-$(CONFIG_OF_I2C)	+= of_i2c.o
 obj-$(CONFIG_OF_SPI)	+= of_spi.o
 obj-$(CONFIG_OF_MDIO)	+= of_mdio.o
+obj-$(CONFIG_PCI)	+= of_pci.o
diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
new file mode 100644
index 0000000..dd862d2
--- /dev/null
+++ b/drivers/of/of_pci.c
@@ -0,0 +1,80 @@
+#include <linux/kernel.h>
+#include <linux/of_pci.h>
+#include <asm/prom.h>
+
+int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
+{
+	struct device_node *dn, *ppnode;
+	struct pci_dev *ppdev;
+	u32 lspec;
+	__be32 lspec_be;
+	__be32 laddr[3];
+	u8 pin;
+	int rc;
+
+	/* Check if we have a device node, if yes, fallback to standard OF
+	 * parsing
+	 */
+	dn = pci_device_to_OF_node(pdev);
+	if (dn) {
+		rc = of_irq_map_one(dn, 0, out_irq);
+		if (!rc)
+			return rc;
+	}
+
+	/* Ok, we don't, time to have fun. Let's start by building up an
+	 * interrupt spec.  we assume #interrupt-cells is 1, which is standard
+	 * for PCI. If you do different, then don't use that routine.
+	 */
+	rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
+	if (rc != 0)
+		return rc;
+	/* No pin, exit */
+	if (pin == 0)
+		return -ENODEV;
+
+	/* Now we walk up the PCI tree */
+	lspec = pin;
+	for (;;) {
+		/* Get the pci_dev of our parent */
+		ppdev = pdev->bus->self;
+
+		/* Ouch, it's a host bridge... */
+		if (ppdev == NULL) {
+			ppnode = pci_bus_to_OF_node(pdev->bus);
+
+			/* No node for host bridge ? give up */
+			if (ppnode == NULL)
+				return -EINVAL;
+		} else {
+			/* We found a P2P bridge, check if it has a node */
+			ppnode = pci_device_to_OF_node(ppdev);
+		}
+
+		/* Ok, we have found a parent with a device-node, hand over to
+		 * the OF parsing code.
+		 * We build a unit address from the linux device to be used for
+		 * resolution. Note that we use the linux bus number which may
+		 * not match your firmware bus numbering.
+		 * Fortunately, in most cases, interrupt-map-mask doesn't
+		 * include the bus number as part of the matching.
+		 * You should still be careful about that though if you intend
+		 * to rely on this function (you ship  a firmware that doesn't
+		 * create device nodes for all PCI devices).
+		 */
+		if (ppnode)
+			break;
+
+		/* We can only get here if we hit a P2P bridge with no node,
+		 * let's do standard swizzling and try again
+		 */
+		lspec = pci_swizzle_interrupt_pin(pdev, lspec);
+		pdev = ppdev;
+	}
+
+	lspec_be = cpu_to_be32(lspec);
+	laddr[0] = cpu_to_be32((pdev->bus->number << 16) | (pdev->devfn << 8));
+	laddr[1]  = laddr[2] = cpu_to_be32(0);
+	return of_irq_map_raw(ppnode, &lspec_be, 1, laddr, out_irq);
+}
+EXPORT_SYMBOL_GPL(of_irq_map_pci);
diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h
new file mode 100644
index 0000000..9b0ba67
--- /dev/null
+++ b/include/linux/of_pci.h
@@ -0,0 +1,20 @@
+#ifndef __OF_PCI_H
+#define __OF_PCI_H
+
+#include <linux/pci.h>
+
+/**
+ * of_irq_map_pci - Resolve the interrupt for a PCI device
+ * @pdev:       the device whose interrupt is to be resolved
+ * @out_irq:    structure of_irq filled by this function
+ *
+ * This function resolves the PCI interrupt for a given PCI device. If a
+ * device-node exists for a given pci_dev, it will use normal OF tree
+ * walking. If not, it will implement standard swizzling and walk up the
+ * PCI tree until an device-node is found, at which point it will finish
+ * resolving using the OF tree walking.
+ */
+struct pci_dev;
+struct of_irq;
+int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
+#endif
-- 
1.7.3.2

^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH v2 03/15] x86/dtb: Add a device tree for CE4100
@ 2011-01-05  9:48           ` Sebastian Andrzej Siewior
  0 siblings, 0 replies; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2011-01-05  9:48 UTC (permalink / raw)
  To: Grant Likely
  Cc: Sebastian Andrzej Siewior, linux-kernel, sodaville, x86,
	devicetree-discuss

Cc: devicetree-discuss@lists.ozlabs.org
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Dirk Brandewie <dirk.brandewie@gmail.com>
---
Okay I 
- 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 :)

 arch/x86/platform/ce4100/falconfalls.dts |  230 ++++++++++++++++++++++++++++++
 1 files changed, 230 insertions(+), 0 deletions(-)
 create mode 100644 arch/x86/platform/ce4100/falconfalls.dts

diff --git a/arch/x86/platform/ce4100/falconfalls.dts b/arch/x86/platform/ce4100/falconfalls.dts
new file mode 100644
index 0000000..4419864
--- /dev/null
+++ b/arch/x86/platform/ce4100/falconfalls.dts
@@ -0,0 +1,230 @@
+/*
+ * 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-immr";
+		ranges;
+
+		ioapic1: pic@fec00000 {
+			#interrupt-cells = <2>;
+			compatible = "intel,ioapic";
+			interrupt-controller;
+			id = <1>;
+			reg = <0xfec00000 0x1000>;
+		};
+
+		timer@fed00000 {
+			compatible = "intel,hpet-ce4100", "intel,hpet";
+			reg = <0xfed00000 0x200>;
+		};
+
+		lapic0: interrupt-controller@fee00000 {
+			compatible = "intel,lapic-ce4100", "intel,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>;
+
+			isa@0 {
+				#address-cells = <2>;
+				#size-cells = <1>;
+				compatible = "isa";
+				ranges = <1 0 0 0 0 0x100>;
+
+				rtc@70 {
+					compatible = "motorola,mc146818";
+					interrupts = <8 3>;
+					interrupt-parent = <&ioapic1>;
+					ctrl-reg = <2>;
+					freq-reg = <0x26>;
+					reg = <1 0x70 2>;
+				};
+			};
+
+			/* Secondary IO-APIC */
+			ioapic2: pic@bffff000 {
+				#interrupt-cells = <2>;
+				compatible = "intel,ioapic-ce4100", "intel,ioapic";
+				interrupt-controller;
+				id = <2>;
+				reg = <0x100 0x0 0x0 0x0 0x0>;
+				assigned-addresses = <0x02000000 0x0 0xbffff000 0x0 0x1000>;
+			};
+
+			pci@av {
+				#address-cells = <3>;
+				#interrupt-cells = <1>;
+				#size-cells = <2>;
+				compatible = "intel,ce4100-pci";
+				device_type = "pci";
+				bus-range = <1 1>;
+				ranges = <0x2000000 0 0xdffe0000 0x2000000 0 0xdffe0000 0 0x1000>;
+
+				interrupt-map-mask = <0xffffff 0x0 0x0 0x0>;
+				interrupt-map = <
+					/* GFX: 0x2E5B */
+					0x11000 0x0 0x0 0x0 &ioapic2 0 0x1
+					/* ***** FIXME ****** Compositing Engine: 0x2E72 */
+					/* 0x11100 0x0 0x0 0x1 &ioapic2 0 0x1 */
+					/* MFD: 0x2E5C */
+					0x11800 0x0 0x0 0x0 &ioapic2 2 0x1
+					/* TS Prefilter: 0x2E5D */
+					0x12000 0x0 0x0 0x0 &ioapic2 4 0x1
+					/* TS Demux: 0x2E5E */
+					0x12100 0x0 0x0 0x0 &ioapic2 5 0x1
+					/* ***** FIXME ***** Audio DSP: 0x2E5F */
+					/* 0x13000 0x0 0x0 0x1 &ioapic2 0 0x1 */
+					/* Audio Interfaces: 0x2E60 */
+					0x13200 0x0 0x0 0x0 &ioapic2 8 0x1
+					/* VDC: 0x2E61 */
+					0x14000 0x0 0x0 0x0 &ioapic2 9 0x1
+					/* DPE: 0x2E62 */
+					0x14100 0x0 0x0 0x0 &ioapic2 10 0x1
+					/* HDMI Tx: 0x2E63 */
+					0x14200 0x0 0x0 0x0 &ioapic2 11 0x1
+					/* SEC: 0x2E64 */
+					0x14800 0x0 0x0 0x0 &ioapic2 12 0x1
+					/* EXP: 0x2E65 */
+					0x15000 0x0 0x0 0x0 &ioapic2 13 0x1
+					/* UART0/1: 0x2E66 */
+					0x15800 0x0 0x0 0x0 &ioapic2 14 0x1
+					/* GPIO: 0x2E67 */
+					0x15900 0x0 0x0 0x0 &ioapic2 15 0x1
+					/* I2C0/1/2: 0x2E68 */
+					0x15a00 0x0 0x0 0x0 &ioapic2 16 0x1
+					/* Smart Card 0/1: 0x2E69 */
+					0x15b00 0x0 0x0 0x0 &ioapic2 15 0x1
+					/* SPI: 0x2E6A */
+					0x15c00 0x0 0x0 0x0 &ioapic2 15 0x1
+					/* MSPOD: 0x2E6B */
+					0x15d00 0x0 0x0 0x0 &ioapic2 19 0x1
+					/* IR: 0x2E6C */
+					0x15e00 0x0 0x0 0x0 &ioapic2 16 0x1
+					/* **** FIXME ***** DFX: 0x2E6D */
+					/* 0x15f00 0x0 0x0 0x1 &ioapic2 0x0 0x1 */
+					/* Gig Ethernet: 0x2E6E */
+					0x16000 0x0 0x0 0x0 &ioapic2 21 0x1
+					/* IEEE1588 and Clock Recovery Unit: 0x2E6F */
+					0x16100 0x0 0x0 0x0 &ioapic2 3 0x1
+					/* USB0: 0x2E70 */
+					0x16800 0x0 0x0 0x0 &ioapic2 22 0x3
+					/* USB1: 0x2E70 */
+					0x16900 0x0 0x0 0x0 &ioapic2 22 0x3
+					/* SATA: 0x2E71 */
+					0x17000 0x0 0x0 0x0 &ioapic2 23 0x3
+					>;
+
+				i2c-controller@15a00,0,0 {
+					#address-cells = <2>;
+					#size-cells = <1>;
+					compatible = "pci8086,2e68.2",
+						   "pci8086,2e68",
+						   "pciclass,ff0000",
+						   "pciclass,ff00";
+
+					reg = <0x15a00 0x0 0x0 0x0 0x0>;
+					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 {
+							compatible = "ti,pcf8575";
+							reg = <0x26>;
+						};
+					};
+
+					i2c@2 {
+						#address-cells = <1>;
+						#size-cells = <0>;
+						compatible = "intel,ce4100-i2c-controller";
+						reg = <2 0 0x100>;
+
+						gpio@26 {
+							compatible = "ti,pcf8575";
+							reg = <0x26>;
+						};
+					};
+				};
+
+				spi-controller@15c00,0,0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					compatible =
+						"pci8086,2e6a.2",
+						"pci8086,2e6a",
+						"pciclass,ff0000",
+						"pciclass,ff00";
+
+					reg = <0x15c00 0x0 0x0 0x0 0x0>;
+
+					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>;
+					};
+				};
+			};
+		};
+	};
+};
-- 
1.7.3.2


^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH v2 03/15] x86/dtb: Add a device tree for CE4100
@ 2011-01-05  9:48           ` Sebastian Andrzej Siewior
  0 siblings, 0 replies; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2011-01-05  9:48 UTC (permalink / raw)
  To: Grant Likely
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	sodaville-hfZtesqFncYOwBW4kG4KsQ, Sebastian Andrzej Siewior,
	x86-DgEjT+Ai2ygdnm+yROfE0A, linux-kernel-u79uwXL29TY76Z2rM5mHXA

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>
---
Okay I 
- 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 :)

 arch/x86/platform/ce4100/falconfalls.dts |  230 ++++++++++++++++++++++++++++++
 1 files changed, 230 insertions(+), 0 deletions(-)
 create mode 100644 arch/x86/platform/ce4100/falconfalls.dts

diff --git a/arch/x86/platform/ce4100/falconfalls.dts b/arch/x86/platform/ce4100/falconfalls.dts
new file mode 100644
index 0000000..4419864
--- /dev/null
+++ b/arch/x86/platform/ce4100/falconfalls.dts
@@ -0,0 +1,230 @@
+/*
+ * 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-immr";
+		ranges;
+
+		ioapic1: pic@fec00000 {
+			#interrupt-cells = <2>;
+			compatible = "intel,ioapic";
+			interrupt-controller;
+			id = <1>;
+			reg = <0xfec00000 0x1000>;
+		};
+
+		timer@fed00000 {
+			compatible = "intel,hpet-ce4100", "intel,hpet";
+			reg = <0xfed00000 0x200>;
+		};
+
+		lapic0: interrupt-controller@fee00000 {
+			compatible = "intel,lapic-ce4100", "intel,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>;
+
+			isa@0 {
+				#address-cells = <2>;
+				#size-cells = <1>;
+				compatible = "isa";
+				ranges = <1 0 0 0 0 0x100>;
+
+				rtc@70 {
+					compatible = "motorola,mc146818";
+					interrupts = <8 3>;
+					interrupt-parent = <&ioapic1>;
+					ctrl-reg = <2>;
+					freq-reg = <0x26>;
+					reg = <1 0x70 2>;
+				};
+			};
+
+			/* Secondary IO-APIC */
+			ioapic2: pic@bffff000 {
+				#interrupt-cells = <2>;
+				compatible = "intel,ioapic-ce4100", "intel,ioapic";
+				interrupt-controller;
+				id = <2>;
+				reg = <0x100 0x0 0x0 0x0 0x0>;
+				assigned-addresses = <0x02000000 0x0 0xbffff000 0x0 0x1000>;
+			};
+
+			pci@av {
+				#address-cells = <3>;
+				#interrupt-cells = <1>;
+				#size-cells = <2>;
+				compatible = "intel,ce4100-pci";
+				device_type = "pci";
+				bus-range = <1 1>;
+				ranges = <0x2000000 0 0xdffe0000 0x2000000 0 0xdffe0000 0 0x1000>;
+
+				interrupt-map-mask = <0xffffff 0x0 0x0 0x0>;
+				interrupt-map = <
+					/* GFX: 0x2E5B */
+					0x11000 0x0 0x0 0x0 &ioapic2 0 0x1
+					/* ***** FIXME ****** Compositing Engine: 0x2E72 */
+					/* 0x11100 0x0 0x0 0x1 &ioapic2 0 0x1 */
+					/* MFD: 0x2E5C */
+					0x11800 0x0 0x0 0x0 &ioapic2 2 0x1
+					/* TS Prefilter: 0x2E5D */
+					0x12000 0x0 0x0 0x0 &ioapic2 4 0x1
+					/* TS Demux: 0x2E5E */
+					0x12100 0x0 0x0 0x0 &ioapic2 5 0x1
+					/* ***** FIXME ***** Audio DSP: 0x2E5F */
+					/* 0x13000 0x0 0x0 0x1 &ioapic2 0 0x1 */
+					/* Audio Interfaces: 0x2E60 */
+					0x13200 0x0 0x0 0x0 &ioapic2 8 0x1
+					/* VDC: 0x2E61 */
+					0x14000 0x0 0x0 0x0 &ioapic2 9 0x1
+					/* DPE: 0x2E62 */
+					0x14100 0x0 0x0 0x0 &ioapic2 10 0x1
+					/* HDMI Tx: 0x2E63 */
+					0x14200 0x0 0x0 0x0 &ioapic2 11 0x1
+					/* SEC: 0x2E64 */
+					0x14800 0x0 0x0 0x0 &ioapic2 12 0x1
+					/* EXP: 0x2E65 */
+					0x15000 0x0 0x0 0x0 &ioapic2 13 0x1
+					/* UART0/1: 0x2E66 */
+					0x15800 0x0 0x0 0x0 &ioapic2 14 0x1
+					/* GPIO: 0x2E67 */
+					0x15900 0x0 0x0 0x0 &ioapic2 15 0x1
+					/* I2C0/1/2: 0x2E68 */
+					0x15a00 0x0 0x0 0x0 &ioapic2 16 0x1
+					/* Smart Card 0/1: 0x2E69 */
+					0x15b00 0x0 0x0 0x0 &ioapic2 15 0x1
+					/* SPI: 0x2E6A */
+					0x15c00 0x0 0x0 0x0 &ioapic2 15 0x1
+					/* MSPOD: 0x2E6B */
+					0x15d00 0x0 0x0 0x0 &ioapic2 19 0x1
+					/* IR: 0x2E6C */
+					0x15e00 0x0 0x0 0x0 &ioapic2 16 0x1
+					/* **** FIXME ***** DFX: 0x2E6D */
+					/* 0x15f00 0x0 0x0 0x1 &ioapic2 0x0 0x1 */
+					/* Gig Ethernet: 0x2E6E */
+					0x16000 0x0 0x0 0x0 &ioapic2 21 0x1
+					/* IEEE1588 and Clock Recovery Unit: 0x2E6F */
+					0x16100 0x0 0x0 0x0 &ioapic2 3 0x1
+					/* USB0: 0x2E70 */
+					0x16800 0x0 0x0 0x0 &ioapic2 22 0x3
+					/* USB1: 0x2E70 */
+					0x16900 0x0 0x0 0x0 &ioapic2 22 0x3
+					/* SATA: 0x2E71 */
+					0x17000 0x0 0x0 0x0 &ioapic2 23 0x3
+					>;
+
+				i2c-controller@15a00,0,0 {
+					#address-cells = <2>;
+					#size-cells = <1>;
+					compatible = "pci8086,2e68.2",
+						   "pci8086,2e68",
+						   "pciclass,ff0000",
+						   "pciclass,ff00";
+
+					reg = <0x15a00 0x0 0x0 0x0 0x0>;
+					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 {
+							compatible = "ti,pcf8575";
+							reg = <0x26>;
+						};
+					};
+
+					i2c@2 {
+						#address-cells = <1>;
+						#size-cells = <0>;
+						compatible = "intel,ce4100-i2c-controller";
+						reg = <2 0 0x100>;
+
+						gpio@26 {
+							compatible = "ti,pcf8575";
+							reg = <0x26>;
+						};
+					};
+				};
+
+				spi-controller@15c00,0,0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					compatible =
+						"pci8086,2e6a.2",
+						"pci8086,2e6a",
+						"pciclass,ff0000",
+						"pciclass,ff00";
+
+					reg = <0x15c00 0x0 0x0 0x0 0x0>;
+
+					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>;
+					};
+				};
+			};
+		};
+	};
+};
-- 
1.7.3.2

^ permalink raw reply related	[flat|nested] 106+ messages in thread

* Re: [PATCH 03/15] x86/dtb: Add a device tree for CE4100
@ 2011-01-05 10:01       ` Sebastian Andrzej Siewior
  0 siblings, 0 replies; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2011-01-05 10:01 UTC (permalink / raw)
  To: Grant Likely
  Cc: Sebastian Andrzej Siewior, linux-kernel, sodaville, x86,
	devicetree-discuss

* Grant Likely | 2010-12-30 01:51:22 [-0700]:

>> diff --git a/arch/x86/platform/ce4100/falconfalls.dts b/arch/x86/platform/ce4100/falconfalls.dts
>> new file mode 100644
>> index 0000000..24e67ca
>> --- /dev/null
>> +++ b/arch/x86/platform/ce4100/falconfalls.dts
>> @@ -0,0 +1,212 @@
>> +/*
>> + * 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";
>
>To-date the convention has been to use all lowercase in compatible
>properties.  Ditto throughout this file.
done

>> +	soc@0 {
>> +		#address-cells = <1>;
>> +		#size-cells = <1>;
>> +		device_type = "soc";
>
>Drop device_type property.
done

>> +		ioapic1: pic@fec00000 {
>> +			#interrupt-cells = <2>;
>> +			compatible = "Intel,ioapic";
>> +			interrupt-controller;
>> +			device_type = "interrupt-controller";
>
>Ditto
done

>> +		pci@3fc {
>> +			#address-cells = <3>;
>> +			#interrupt-cells = <1>;
>> +			#size-cells = <2>;
>> +			compatible = "Intel,ce4100-pci", "pci";
>> +			device_type = "pci";
>
>I'd like to say ditto here, but it might require a change to the
>current kernel code.  I believe ePAPR specified a compatible value
>alternative to 'device_type = "pci";'.
I have the pci property. So I drop the device_type once it is possible.

>> +			isa@0 {
>> +				#address-cells = <2>;
>> +				#size-cells = <1>;
>> +				compatible = "isa";
>> +				ranges = <1 0 0 0 0 0x100>;
>> +
>> +				rtc@70 {
>> +					compatible = "motorola,mc146818";
>> +					interrupts = <8 3>;
>> +					interrupt-parent = <&ioapic1>;
>
>If you put an interrupt-parent property in the root node, then it will
>become the default interrupt controller for the system which is
>usually convenient to have.
Okay, I mode it once I have more common devices. I have two interrupt
controller and most devices are attached to the second one (and are
assigned via interrupt-map).

>> +			/* Secondary IO-APIC */
>> +			ioapic2: pic@bffff000 {
>> +				#interrupt-cells = <2>;
>> +				compatible = "Intel,ioapic-ce4100", "Intel,ioapic";
>> +				interrupt-controller;
>> +				device_type = "interrupt-controller";
>
>Drop device_type.
done

Sebastian

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 03/15] x86/dtb: Add a device tree for CE4100
@ 2011-01-05 10:01       ` Sebastian Andrzej Siewior
  0 siblings, 0 replies; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2011-01-05 10:01 UTC (permalink / raw)
  To: Grant Likely
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	sodaville-hfZtesqFncYOwBW4kG4KsQ, Sebastian Andrzej Siewior,
	x86-DgEjT+Ai2ygdnm+yROfE0A, linux-kernel-u79uwXL29TY76Z2rM5mHXA

* Grant Likely | 2010-12-30 01:51:22 [-0700]:

>> diff --git a/arch/x86/platform/ce4100/falconfalls.dts b/arch/x86/platform/ce4100/falconfalls.dts
>> new file mode 100644
>> index 0000000..24e67ca
>> --- /dev/null
>> +++ b/arch/x86/platform/ce4100/falconfalls.dts
>> @@ -0,0 +1,212 @@
>> +/*
>> + * 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";
>
>To-date the convention has been to use all lowercase in compatible
>properties.  Ditto throughout this file.
done

>> +	soc@0 {
>> +		#address-cells = <1>;
>> +		#size-cells = <1>;
>> +		device_type = "soc";
>
>Drop device_type property.
done

>> +		ioapic1: pic@fec00000 {
>> +			#interrupt-cells = <2>;
>> +			compatible = "Intel,ioapic";
>> +			interrupt-controller;
>> +			device_type = "interrupt-controller";
>
>Ditto
done

>> +		pci@3fc {
>> +			#address-cells = <3>;
>> +			#interrupt-cells = <1>;
>> +			#size-cells = <2>;
>> +			compatible = "Intel,ce4100-pci", "pci";
>> +			device_type = "pci";
>
>I'd like to say ditto here, but it might require a change to the
>current kernel code.  I believe ePAPR specified a compatible value
>alternative to 'device_type = "pci";'.
I have the pci property. So I drop the device_type once it is possible.

>> +			isa@0 {
>> +				#address-cells = <2>;
>> +				#size-cells = <1>;
>> +				compatible = "isa";
>> +				ranges = <1 0 0 0 0 0x100>;
>> +
>> +				rtc@70 {
>> +					compatible = "motorola,mc146818";
>> +					interrupts = <8 3>;
>> +					interrupt-parent = <&ioapic1>;
>
>If you put an interrupt-parent property in the root node, then it will
>become the default interrupt controller for the system which is
>usually convenient to have.
Okay, I mode it once I have more common devices. I have two interrupt
controller and most devices are attached to the second one (and are
assigned via interrupt-map).

>> +			/* Secondary IO-APIC */
>> +			ioapic2: pic@bffff000 {
>> +				#interrupt-cells = <2>;
>> +				compatible = "Intel,ioapic-ce4100", "Intel,ioapic";
>> +				interrupt-controller;
>> +				device_type = "interrupt-controller";
>
>Drop device_type.
done

Sebastian

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 03/15] x86/dtb: Add a device tree for CE4100
@ 2011-01-05 23:20       ` David Gibson
  0 siblings, 0 replies; 106+ messages in thread
From: David Gibson @ 2011-01-05 23:20 UTC (permalink / raw)
  To: Grant Likely
  Cc: Sebastian Andrzej Siewior, sodaville, devicetree-discuss, x86,
	linux-kernel

On Thu, Dec 30, 2010 at 01:51:22AM -0700, Grant Likely wrote:
> On Fri, Dec 17, 2010 at 04:33:41PM +0100, Sebastian Andrzej Siewior wrote:
[snip]
> > +/dts-v1/;
> > +/ {
> > +	model = "Intel,FalconFalls";
> > +	compatible = "Intel,FalconFalls";
> 
> To-date the convention has been to use all lowercase in compatible
> properties.  Ditto throughout this file.

IEEE1275 actually explicitly gives the convention on p164, in the
context of the "name" property.  The vendor string can either be all
uppercase, in which case it must be a stock ticker symbol ("AAPL" is
seen in the wild, for example), or it can be another string with no
uppercase.

I'm sure some intel peripheral chips must have been used on existing
OF platforms at various points.  It might be worth seeking those out
and double checking what was used in those cases.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 03/15] x86/dtb: Add a device tree for CE4100
@ 2011-01-05 23:20       ` David Gibson
  0 siblings, 0 replies; 106+ messages in thread
From: David Gibson @ 2011-01-05 23:20 UTC (permalink / raw)
  To: Grant Likely
  Cc: sodaville-hfZtesqFncYOwBW4kG4KsQ, Sebastian Andrzej Siewior,
	x86-DgEjT+Ai2ygdnm+yROfE0A,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Thu, Dec 30, 2010 at 01:51:22AM -0700, Grant Likely wrote:
> On Fri, Dec 17, 2010 at 04:33:41PM +0100, Sebastian Andrzej Siewior wrote:
[snip]
> > +/dts-v1/;
> > +/ {
> > +	model = "Intel,FalconFalls";
> > +	compatible = "Intel,FalconFalls";
> 
> To-date the convention has been to use all lowercase in compatible
> properties.  Ditto throughout this file.

IEEE1275 actually explicitly gives the convention on p164, in the
context of the "name" property.  The vendor string can either be all
uppercase, in which case it must be a stock ticker symbol ("AAPL" is
seen in the wild, for example), or it can be another string with no
uppercase.

I'm sure some intel peripheral chips must have been used on existing
OF platforms at various points.  It might be worth seeking those out
and double checking what was used in those cases.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 04/15] x86/dtb: add irq domain abstraction
  2010-12-17 15:33   ` Sebastian Andrzej Siewior
  (?)
@ 2011-01-11 22:03   ` Grant Likely
  2011-01-23 13:06       ` Sebastian Andrzej Siewior
  -1 siblings, 1 reply; 106+ messages in thread
From: Grant Likely @ 2011-01-11 22:03 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: linux-kernel, sodaville, x86, devicetree-discuss

On Fri, Dec 17, 2010 at 04:33:42PM +0100, Sebastian Andrzej Siewior 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>
> ---
>  arch/x86/include/asm/irq_controller.h |   12 ++++++++
>  arch/x86/include/asm/prom.h           |    2 +
>  arch/x86/kernel/prom.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;
> +};

True, it's not a full implementation, but I'd rather the same
structure be used for both powerpc and x86.

Thomas, this only touches x86, so I have no objection to you merging
it, but I'd like to see a follow up patch to merge the x86 and powerpc
irq_host/irq_domain structures.

However, there is a defect below that must be fixed first....

>  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 -ENODEV;

Return value is an unsigned int.  0 or NO_IRQ is the correct thing to
return if an IRQ cannot be mapped.

> +	ret = ih->xlate(ih, intspec, intsize, &virq, &type);
> +	if (ret)
> +		return ret;

Ditto here.  xlate is also supposed to return a virq number, not an
error code, so the failure condition must be "if (!ret)" or
"if (reg == NO_IRQ)".  The former is preferred since we're trying to
eliminate references to NO_IRQ, not add more of them.

> +	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.3.2
> 
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH v2 05/15] x86/dtb: add early parsing of APIC and IO APIC
@ 2011-01-11 22:14         ` Grant Likely
  0 siblings, 0 replies; 106+ messages in thread
From: Grant Likely @ 2011-01-11 22:14 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: linux-kernel, sodaville, x86, devicetree-discuss

On Tue, Jan 04, 2011 at 02:23:02PM +0100, Sebastian Andrzej Siewior wrote:
> 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.

Hi Sebastian,

Some comments below...

> 
> Cc: devicetree-discuss@lists.ozlabs.org
> Cc: Dirk Brandewie <dirk.brandewie@gmail.com>
> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> ---
>  arch/x86/include/asm/prom.h |    7 +++
>  arch/x86/kernel/irqinit.c   |    2 +-
>  arch/x86/kernel/prom.c      |  121 +++++++++++++++++++++++++++++++++++++++++-
>  3 files changed, 126 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/x86/include/asm/prom.h b/arch/x86/include/asm/prom.h
> index 9076ae4..3bc8ed5 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

Nit: Personally, I prefer static inlines over preprocessor macros, but
that isn't anything that will block this patch.

>  #endif
>  
>  extern char cmd_line[COMMAND_LINE_SIZE];
> diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c
> index 149c87f..4cadf86 100644
> --- a/arch/x86/kernel/irqinit.c
> +++ b/arch/x86/kernel/irqinit.c
> @@ -244,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
> diff --git a/arch/x86/kernel/prom.c b/arch/x86/kernel/prom.c
> index 53948cb..388fdff 100644
> --- a/arch/x86/kernel/prom.c
> +++ b/arch/x86/kernel/prom.c
> @@ -6,15 +6,20 @@
>  #include <linux/interrupt.h>
>  #include <linux/list.h>
>  #include <linux/of.h>
> +#include <linux/of_address.h>
>  #include <linux/of_platform.h>
>  #include <linux/slab.h>
>  
>  #include <asm/irq_controller.h>
> +#include <asm/io_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;
> @@ -93,7 +98,117 @@ u64 __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
>  
>  void __init add_dtb(u64 data)
>  {
> -	initial_boot_params = (struct boot_param_header *)
> -		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 void __init dtb_add_ioapic(struct device_node *dn)
> +{
> +	unsigned int ioapic_id;
> +	const __be32 *cell;
> +	int len;
> +	struct resource r;
> +	int ret;
> +
> +	cell = of_get_property(dn, "id", &len);
> +	if (!cell) {
> +		printk(KERN_ERR "Node %s is missing id property.\n",
> +				dn->full_name);
> +		return;
> +	}
> +	ioapic_id = of_read_ulong(cell, len / 4);

This looks like poor usage practise for the device tree.  'id' or any
kind of enumeration property in a device tree node is strongly
discouraged.  As much as possible, let Linux dynamically enumerate
devices rather than trying to explicitly specify the numbering.  Since
you can explicitly describe the relationship between device nodes in
the tree, you should find that explicitly specifying numbers is almost
never required.

If you *really* need to enumerate devices in the device tree, then use
properties in the /aliases node to assign globally unique numbers.

> +
> +	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,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();
>  }
> -- 
> 1.7.3.2
> 

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH v2 05/15] x86/dtb: add early parsing of APIC and IO APIC
@ 2011-01-11 22:14         ` Grant Likely
  0 siblings, 0 replies; 106+ messages in thread
From: Grant Likely @ 2011-01-11 22:14 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: sodaville-hfZtesqFncYOwBW4kG4KsQ,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	x86-DgEjT+Ai2ygdnm+yROfE0A, linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Tue, Jan 04, 2011 at 02:23:02PM +0100, Sebastian Andrzej Siewior wrote:
> 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.

Hi Sebastian,

Some comments below...

> 
> Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
> Cc: 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 |    7 +++
>  arch/x86/kernel/irqinit.c   |    2 +-
>  arch/x86/kernel/prom.c      |  121 +++++++++++++++++++++++++++++++++++++++++-
>  3 files changed, 126 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/x86/include/asm/prom.h b/arch/x86/include/asm/prom.h
> index 9076ae4..3bc8ed5 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

Nit: Personally, I prefer static inlines over preprocessor macros, but
that isn't anything that will block this patch.

>  #endif
>  
>  extern char cmd_line[COMMAND_LINE_SIZE];
> diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c
> index 149c87f..4cadf86 100644
> --- a/arch/x86/kernel/irqinit.c
> +++ b/arch/x86/kernel/irqinit.c
> @@ -244,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
> diff --git a/arch/x86/kernel/prom.c b/arch/x86/kernel/prom.c
> index 53948cb..388fdff 100644
> --- a/arch/x86/kernel/prom.c
> +++ b/arch/x86/kernel/prom.c
> @@ -6,15 +6,20 @@
>  #include <linux/interrupt.h>
>  #include <linux/list.h>
>  #include <linux/of.h>
> +#include <linux/of_address.h>
>  #include <linux/of_platform.h>
>  #include <linux/slab.h>
>  
>  #include <asm/irq_controller.h>
> +#include <asm/io_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;
> @@ -93,7 +98,117 @@ u64 __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
>  
>  void __init add_dtb(u64 data)
>  {
> -	initial_boot_params = (struct boot_param_header *)
> -		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 void __init dtb_add_ioapic(struct device_node *dn)
> +{
> +	unsigned int ioapic_id;
> +	const __be32 *cell;
> +	int len;
> +	struct resource r;
> +	int ret;
> +
> +	cell = of_get_property(dn, "id", &len);
> +	if (!cell) {
> +		printk(KERN_ERR "Node %s is missing id property.\n",
> +				dn->full_name);
> +		return;
> +	}
> +	ioapic_id = of_read_ulong(cell, len / 4);

This looks like poor usage practise for the device tree.  'id' or any
kind of enumeration property in a device tree node is strongly
discouraged.  As much as possible, let Linux dynamically enumerate
devices rather than trying to explicitly specify the numbering.  Since
you can explicitly describe the relationship between device nodes in
the tree, you should find that explicitly specifying numbers is almost
never required.

If you *really* need to enumerate devices in the device tree, then use
properties in the /aliases node to assign globally unique numbers.

> +
> +	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,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();
>  }
> -- 
> 1.7.3.2
> 

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 06/15] x86/dtb: add support hpet
@ 2011-01-11 22:26     ` Grant Likely
  0 siblings, 0 replies; 106+ messages in thread
From: Grant Likely @ 2011-01-11 22:26 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: linux-kernel, sodaville, x86, devicetree-discuss

On Fri, Dec 17, 2010 at 04:33:44PM +0100, Sebastian Andrzej Siewior wrote:
> Set hpet_address based on information provied form DTB
> 
> Cc: devicetree-discuss@lists.ozlabs.org
> Cc: 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/kernel/prom.c |   19 +++++++++++++++++++
>  1 files changed, 19 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/x86/kernel/prom.c b/arch/x86/kernel/prom.c
> index 9cbb52b..40ad8c0 100644
> --- a/arch/x86/kernel/prom.c
> +++ b/arch/x86/kernel/prom.c
> @@ -10,6 +10,7 @@
>  #include <linux/of_platform.h>
>  #include <linux/slab.h>
>  
> +#include <asm/hpet.h>
>  #include <asm/irq_controller.h>
>  #include <asm/io_apic.h>
>  
> @@ -101,6 +102,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,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
> @@ -212,5 +230,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.3.2
> 
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 06/15] x86/dtb: add support hpet
@ 2011-01-11 22:26     ` Grant Likely
  0 siblings, 0 replies; 106+ messages in thread
From: Grant Likely @ 2011-01-11 22:26 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: sodaville-hfZtesqFncYOwBW4kG4KsQ,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	x86-DgEjT+Ai2ygdnm+yROfE0A, linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Fri, Dec 17, 2010 at 04:33:44PM +0100, Sebastian Andrzej Siewior wrote:
> 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>
> Signed-off-by: Sebastian Andrzej Siewior <bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>

Acked-by: Grant Likely <grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org>

> ---
>  arch/x86/kernel/prom.c |   19 +++++++++++++++++++
>  1 files changed, 19 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/x86/kernel/prom.c b/arch/x86/kernel/prom.c
> index 9cbb52b..40ad8c0 100644
> --- a/arch/x86/kernel/prom.c
> +++ b/arch/x86/kernel/prom.c
> @@ -10,6 +10,7 @@
>  #include <linux/of_platform.h>
>  #include <linux/slab.h>
>  
> +#include <asm/hpet.h>
>  #include <asm/irq_controller.h>
>  #include <asm/io_apic.h>
>  
> @@ -101,6 +102,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,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
> @@ -212,5 +230,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.3.2
> 
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH v2 07/15] of: move of_irq_map_pci() into generic code
@ 2011-01-11 23:27         ` Grant Likely
  0 siblings, 0 replies; 106+ messages in thread
From: Grant Likely @ 2011-01-11 23:27 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: Benjamin Herrenschmidt, x86, linux-kernel, sodaville,
	Sebastian Andrzej Siewior, devicetree-discuss

On Tue, Jan 04, 2011 at 03:27:54PM +0100, Sebastian Andrzej Siewior wrote:
> From: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
> 
> There is a tiny difference between PPC32 and PPC64. Microblaze uses the
> PPC32 variant.

Mostly looks good, but breaks both Sparc and microblaze which is kind
of important to fix before I merge it.  :-)

Sparc
-----
  CC      drivers/of/of_pci.o
/home/grant/hacking/linux-2.6/drivers/of/of_pci.c: In function 'of_irq_map_pci':
/home/grant/hacking/linux-2.6/drivers/of/of_pci.c:20: error: implicit declaration of function 'of_irq_map_one'
/home/grant/hacking/linux-2.6/drivers/of/of_pci.c:44: error: implicit declaration of function 'pci_bus_to_OF_node'
/home/grant/hacking/linux-2.6/drivers/of/of_pci.c:44: warning: assignment makes pointer from integer without a cast
/home/grant/hacking/linux-2.6/drivers/of/of_pci.c:78: error: implicit declaration of function 'of_irq_map_raw'
make[3]: *** [drivers/of/of_pci.o] Error 1


Microblaze
----------
  CC      arch/microblaze/kernel/prom.o
In file included from /home/grant/hacking/linux-2.6/arch/microblaze/include/asm/pci.h:23,
                 from /home/grant/hacking/linux-2.6/include/linux/pci.h:1230,
                 from /home/grant/hacking/linux-2.6/arch/microblaze/kernel/prom.c:23:
/home/grant/hacking/linux-2.6/arch/microblaze/include/asm/pci-bridge.h: In function 'pci_bus_to_OF_node':
/home/grant/hacking/linux-2.6/arch/microblaze/include/asm/pci-bridge.h:117: error: implicit declaration of function 'pci_device_to_OF_node'
/home/grant/hacking/linux-2.6/arch/microblaze/include/asm/pci-bridge.h:117: warning: return makes pointer from integer without a cast
make[2]: *** [arch/microblaze/kernel/prom.o] Error 1
make[1]: *** [arch/microblaze/kernel] Error 2
make: *** [sub-make] Error 2


> 
> Cc: devicetree-discuss@lists.ozlabs.org
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Signed-off-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
> ---
>  arch/microblaze/include/asm/pci-bridge.h |   10 ++++
>  arch/microblaze/include/asm/prom.h       |   15 -----
>  arch/microblaze/kernel/prom_parse.c      |   77 ---------------------------
>  arch/microblaze/pci/pci-common.c         |    1 +
>  arch/powerpc/include/asm/pci-bridge.h    |   10 ++++
>  arch/powerpc/include/asm/prom.h          |   15 -----
>  arch/powerpc/kernel/pci-common.c         |    1 +
>  arch/powerpc/kernel/prom_parse.c         |   84 ------------------------------
>  drivers/of/Makefile                      |    1 +
>  drivers/of/of_pci.c                      |   80 ++++++++++++++++++++++++++++
>  include/linux/of_pci.h                   |   20 +++++++
>  11 files changed, 123 insertions(+), 191 deletions(-)
>  create mode 100644 drivers/of/of_pci.c
>  create mode 100644 include/linux/of_pci.h
> 
> diff --git a/arch/microblaze/include/asm/pci-bridge.h b/arch/microblaze/include/asm/pci-bridge.h
> index 0c68764..0808217 100644
> --- a/arch/microblaze/include/asm/pci-bridge.h
> +++ b/arch/microblaze/include/asm/pci-bridge.h
> @@ -109,6 +109,16 @@ static inline struct pci_controller *pci_bus_to_host(const struct pci_bus *bus)
>  	return bus->sysdata;
>  }


>  
> +static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
> +{
> +	struct pci_controller *host;
> +
> +	if (bus->self)
> +		return pci_device_to_OF_node(bus->self);
> +	host = pci_bus_to_host(bus);
> +	return host ? host->dn : NULL;
> +}
> +
>  static inline int isa_vaddr_is_ioport(void __iomem *address)
>  {
>  	/* No specific ISA handling on ppc32 at this stage, it
> diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h
> index bdc3831..aa3ab12 100644
> --- a/arch/microblaze/include/asm/prom.h
> +++ b/arch/microblaze/include/asm/prom.h
> @@ -67,21 +67,6 @@ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
>  /* Get the MAC address */
>  extern const void *of_get_mac_address(struct device_node *np);
>  
> -/**
> - * of_irq_map_pci - Resolve the interrupt for a PCI device
> - * @pdev:	the device whose interrupt is to be resolved
> - * @out_irq:	structure of_irq filled by this function
> - *
> - * This function resolves the PCI interrupt for a given PCI device. If a
> - * device-node exists for a given pci_dev, it will use normal OF tree
> - * walking. If not, it will implement standard swizzling and walk up the
> - * PCI tree until an device-node is found, at which point it will finish
> - * resolving using the OF tree walking.
> - */
> -struct pci_dev;
> -struct of_irq;
> -extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
> -
>  #endif /* __ASSEMBLY__ */
>  #endif /* __KERNEL__ */
>  
> diff --git a/arch/microblaze/kernel/prom_parse.c b/arch/microblaze/kernel/prom_parse.c
> index 99d9b61..306f41d 100644
> --- a/arch/microblaze/kernel/prom_parse.c
> +++ b/arch/microblaze/kernel/prom_parse.c
> @@ -2,88 +2,11 @@
>  
>  #include <linux/kernel.h>
>  #include <linux/string.h>
> -#include <linux/pci_regs.h>
>  #include <linux/module.h>
>  #include <linux/ioport.h>
>  #include <linux/etherdevice.h>
>  #include <linux/of_address.h>
>  #include <asm/prom.h>
> -#include <asm/pci-bridge.h>
> -
> -#ifdef CONFIG_PCI
> -int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
> -{
> -	struct device_node *dn, *ppnode;
> -	struct pci_dev *ppdev;
> -	u32 lspec;
> -	u32 laddr[3];
> -	u8 pin;
> -	int rc;
> -
> -	/* Check if we have a device node, if yes, fallback to standard OF
> -	 * parsing
> -	 */
> -	dn = pci_device_to_OF_node(pdev);
> -	if (dn)
> -		return of_irq_map_one(dn, 0, out_irq);
> -
> -	/* Ok, we don't, time to have fun. Let's start by building up an
> -	 * interrupt spec.  we assume #interrupt-cells is 1, which is standard
> -	 * for PCI. If you do different, then don't use that routine.
> -	 */
> -	rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
> -	if (rc != 0)
> -		return rc;
> -	/* No pin, exit */
> -	if (pin == 0)
> -		return -ENODEV;
> -
> -	/* Now we walk up the PCI tree */
> -	lspec = pin;
> -	for (;;) {
> -		/* Get the pci_dev of our parent */
> -		ppdev = pdev->bus->self;
> -
> -		/* Ouch, it's a host bridge... */
> -		if (ppdev == NULL) {
> -			struct pci_controller *host;
> -			host = pci_bus_to_host(pdev->bus);
> -			ppnode = host ? host->dn : NULL;
> -			/* No node for host bridge ? give up */
> -			if (ppnode == NULL)
> -				return -EINVAL;
> -		} else
> -			/* We found a P2P bridge, check if it has a node */
> -			ppnode = pci_device_to_OF_node(ppdev);
> -
> -		/* Ok, we have found a parent with a device-node, hand over to
> -		 * the OF parsing code.
> -		 * We build a unit address from the linux device to be used for
> -		 * resolution. Note that we use the linux bus number which may
> -		 * not match your firmware bus numbering.
> -		 * Fortunately, in most cases, interrupt-map-mask doesn't
> -		 * include the bus number as part of the matching.
> -		 * You should still be careful about that though if you intend
> -		 * to rely on this function (you ship  a firmware that doesn't
> -		 * create device nodes for all PCI devices).
> -		 */
> -		if (ppnode)
> -			break;
> -
> -		/* We can only get here if we hit a P2P bridge with no node,
> -		 * let's do standard swizzling and try again
> -		 */
> -		lspec = pci_swizzle_interrupt_pin(pdev, lspec);
> -		pdev = ppdev;
> -	}
> -
> -	laddr[0] = (pdev->bus->number << 16)
> -		| (pdev->devfn << 8);
> -	laddr[1]  = laddr[2] = 0;
> -	return of_irq_map_raw(ppnode, &lspec, 1, laddr, out_irq);
> -}
> -EXPORT_SYMBOL_GPL(of_irq_map_pci);
> -#endif /* CONFIG_PCI */
>  
>  void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
>  		unsigned long *busno, unsigned long *phys, unsigned long *size)
> diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c
> index e363615..1e01a12 100644
> --- a/arch/microblaze/pci/pci-common.c
> +++ b/arch/microblaze/pci/pci-common.c
> @@ -29,6 +29,7 @@
>  #include <linux/slab.h>
>  #include <linux/of.h>
>  #include <linux/of_address.h>
> +#include <linux/of_pci.h>
>  
>  #include <asm/processor.h>
>  #include <asm/io.h>
> diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h
> index 51e9e6f..edeb80f 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)
>  	return bus->sysdata;
>  }
>  
> +static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
> +{
> +	struct pci_controller *host;
> +
> +	if (bus->self)
> +		return pci_device_to_OF_node(bus->self);
> +	host = pci_bus_to_host(bus);
> +	return host ? host->dn : NULL;
> +}
> +
>  static inline int isa_vaddr_is_ioport(void __iomem *address)
>  {
>  	/* No specific ISA handling on ppc32 at this stage, it
> diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h
> index ae26f2e..01c3302 100644
> --- a/arch/powerpc/include/asm/prom.h
> +++ b/arch/powerpc/include/asm/prom.h
> @@ -73,21 +73,6 @@ static inline int of_node_to_nid(struct device_node *device) { return 0; }
>  #endif
>  #define of_node_to_nid of_node_to_nid
>  
> -/**
> - * of_irq_map_pci - Resolve the interrupt for a PCI device
> - * @pdev:	the device whose interrupt is to be resolved
> - * @out_irq:	structure of_irq filled by this function
> - *
> - * This function resolves the PCI interrupt for a given PCI device. If a
> - * device-node exists for a given pci_dev, it will use normal OF tree
> - * walking. If not, it will implement standard swizzling and walk up the
> - * PCI tree until an device-node is found, at which point it will finish
> - * resolving using the OF tree walking.
> - */
> -struct pci_dev;
> -struct of_irq;
> -extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
> -
>  extern void of_instantiate_rtc(void);
>  
>  /* These includes are put at the bottom because they may contain things
> diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
> index 10a44e6..eb341be 100644
> --- a/arch/powerpc/kernel/pci-common.c
> +++ b/arch/powerpc/kernel/pci-common.c
> @@ -22,6 +22,7 @@
>  #include <linux/init.h>
>  #include <linux/bootmem.h>
>  #include <linux/of_address.h>
> +#include <linux/of_pci.h>
>  #include <linux/mm.h>
>  #include <linux/list.h>
>  #include <linux/syscalls.h>
> diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c
> index 88334af..306f41d 100644
> --- a/arch/powerpc/kernel/prom_parse.c
> +++ b/arch/powerpc/kernel/prom_parse.c
> @@ -2,95 +2,11 @@
>  
>  #include <linux/kernel.h>
>  #include <linux/string.h>
> -#include <linux/pci_regs.h>
>  #include <linux/module.h>
>  #include <linux/ioport.h>
>  #include <linux/etherdevice.h>
>  #include <linux/of_address.h>
>  #include <asm/prom.h>
> -#include <asm/pci-bridge.h>
> -
> -#ifdef CONFIG_PCI
> -int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
> -{
> -	struct device_node *dn, *ppnode;
> -	struct pci_dev *ppdev;
> -	u32 lspec;
> -	u32 laddr[3];
> -	u8 pin;
> -	int rc;
> -
> -	/* Check if we have a device node, if yes, fallback to standard OF
> -	 * parsing
> -	 */
> -	dn = pci_device_to_OF_node(pdev);
> -	if (dn) {
> -		rc = of_irq_map_one(dn, 0, out_irq);
> -		if (!rc)
> -			return rc;
> -	}
> -
> -	/* Ok, we don't, time to have fun. Let's start by building up an
> -	 * interrupt spec.  we assume #interrupt-cells is 1, which is standard
> -	 * for PCI. If you do different, then don't use that routine.
> -	 */
> -	rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
> -	if (rc != 0)
> -		return rc;
> -	/* No pin, exit */
> -	if (pin == 0)
> -		return -ENODEV;
> -
> -	/* Now we walk up the PCI tree */
> -	lspec = pin;
> -	for (;;) {
> -		/* Get the pci_dev of our parent */
> -		ppdev = pdev->bus->self;
> -
> -		/* Ouch, it's a host bridge... */
> -		if (ppdev == NULL) {
> -#ifdef CONFIG_PPC64
> -			ppnode = pci_bus_to_OF_node(pdev->bus);
> -#else
> -			struct pci_controller *host;
> -			host = pci_bus_to_host(pdev->bus);
> -			ppnode = host ? host->dn : NULL;
> -#endif
> -			/* No node for host bridge ? give up */
> -			if (ppnode == NULL)
> -				return -EINVAL;
> -		} else
> -			/* We found a P2P bridge, check if it has a node */
> -			ppnode = pci_device_to_OF_node(ppdev);
> -
> -		/* Ok, we have found a parent with a device-node, hand over to
> -		 * the OF parsing code.
> -		 * We build a unit address from the linux device to be used for
> -		 * resolution. Note that we use the linux bus number which may
> -		 * not match your firmware bus numbering.
> -		 * Fortunately, in most cases, interrupt-map-mask doesn't include
> -		 * the bus number as part of the matching.
> -		 * You should still be careful about that though if you intend
> -		 * to rely on this function (you ship  a firmware that doesn't
> -		 * create device nodes for all PCI devices).
> -		 */
> -		if (ppnode)
> -			break;
> -
> -		/* We can only get here if we hit a P2P bridge with no node,
> -		 * let's do standard swizzling and try again
> -		 */
> -		lspec = pci_swizzle_interrupt_pin(pdev, lspec);
> -		pdev = ppdev;
> -	}
> -
> -	laddr[0] = (pdev->bus->number << 16)
> -		| (pdev->devfn << 8);
> -	laddr[1]  = laddr[2] = 0;
> -	return of_irq_map_raw(ppnode, &lspec, 1, laddr, out_irq);
> -}
> -EXPORT_SYMBOL_GPL(of_irq_map_pci);
> -#endif /* CONFIG_PCI */
>  
>  void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
>  		unsigned long *busno, unsigned long *phys, unsigned long *size)
> diff --git a/drivers/of/Makefile b/drivers/of/Makefile
> index 7888155..4dcb177 100644
> --- a/drivers/of/Makefile
> +++ b/drivers/of/Makefile
> @@ -8,3 +8,4 @@ obj-$(CONFIG_OF_GPIO)   += gpio.o
>  obj-$(CONFIG_OF_I2C)	+= of_i2c.o
>  obj-$(CONFIG_OF_SPI)	+= of_spi.o
>  obj-$(CONFIG_OF_MDIO)	+= of_mdio.o
> +obj-$(CONFIG_PCI)	+= of_pci.o
> diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
> new file mode 100644
> index 0000000..dd862d2
> --- /dev/null
> +++ b/drivers/of/of_pci.c
> @@ -0,0 +1,80 @@
> +#include <linux/kernel.h>
> +#include <linux/of_pci.h>
> +#include <asm/prom.h>
> +
> +int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
> +{
> +	struct device_node *dn, *ppnode;
> +	struct pci_dev *ppdev;
> +	u32 lspec;
> +	__be32 lspec_be;
> +	__be32 laddr[3];
> +	u8 pin;
> +	int rc;
> +
> +	/* Check if we have a device node, if yes, fallback to standard OF
> +	 * parsing
> +	 */
> +	dn = pci_device_to_OF_node(pdev);
> +	if (dn) {
> +		rc = of_irq_map_one(dn, 0, out_irq);
> +		if (!rc)
> +			return rc;
> +	}
> +
> +	/* Ok, we don't, time to have fun. Let's start by building up an
> +	 * interrupt spec.  we assume #interrupt-cells is 1, which is standard
> +	 * for PCI. If you do different, then don't use that routine.
> +	 */
> +	rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
> +	if (rc != 0)
> +		return rc;
> +	/* No pin, exit */
> +	if (pin == 0)
> +		return -ENODEV;
> +
> +	/* Now we walk up the PCI tree */
> +	lspec = pin;
> +	for (;;) {
> +		/* Get the pci_dev of our parent */
> +		ppdev = pdev->bus->self;
> +
> +		/* Ouch, it's a host bridge... */
> +		if (ppdev == NULL) {
> +			ppnode = pci_bus_to_OF_node(pdev->bus);
> +
> +			/* No node for host bridge ? give up */
> +			if (ppnode == NULL)
> +				return -EINVAL;
> +		} else {
> +			/* We found a P2P bridge, check if it has a node */
> +			ppnode = pci_device_to_OF_node(ppdev);
> +		}
> +
> +		/* Ok, we have found a parent with a device-node, hand over to
> +		 * the OF parsing code.
> +		 * We build a unit address from the linux device to be used for
> +		 * resolution. Note that we use the linux bus number which may
> +		 * not match your firmware bus numbering.
> +		 * Fortunately, in most cases, interrupt-map-mask doesn't
> +		 * include the bus number as part of the matching.
> +		 * You should still be careful about that though if you intend
> +		 * to rely on this function (you ship  a firmware that doesn't
> +		 * create device nodes for all PCI devices).
> +		 */
> +		if (ppnode)
> +			break;
> +
> +		/* We can only get here if we hit a P2P bridge with no node,
> +		 * let's do standard swizzling and try again
> +		 */
> +		lspec = pci_swizzle_interrupt_pin(pdev, lspec);
> +		pdev = ppdev;
> +	}
> +
> +	lspec_be = cpu_to_be32(lspec);
> +	laddr[0] = cpu_to_be32((pdev->bus->number << 16) | (pdev->devfn << 8));
> +	laddr[1]  = laddr[2] = cpu_to_be32(0);
> +	return of_irq_map_raw(ppnode, &lspec_be, 1, laddr, out_irq);
> +}
> +EXPORT_SYMBOL_GPL(of_irq_map_pci);
> diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h
> new file mode 100644
> index 0000000..9b0ba67
> --- /dev/null
> +++ b/include/linux/of_pci.h
> @@ -0,0 +1,20 @@
> +#ifndef __OF_PCI_H
> +#define __OF_PCI_H
> +
> +#include <linux/pci.h>
> +
> +/**
> + * of_irq_map_pci - Resolve the interrupt for a PCI device
> + * @pdev:       the device whose interrupt is to be resolved
> + * @out_irq:    structure of_irq filled by this function
> + *
> + * This function resolves the PCI interrupt for a given PCI device. If a
> + * device-node exists for a given pci_dev, it will use normal OF tree
> + * walking. If not, it will implement standard swizzling and walk up the
> + * PCI tree until an device-node is found, at which point it will finish
> + * resolving using the OF tree walking.
> + */
> +struct pci_dev;
> +struct of_irq;
> +int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
> +#endif
> -- 
> 1.7.3.2
> 
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH v2 07/15] of: move of_irq_map_pci() into generic code
@ 2011-01-11 23:27         ` Grant Likely
  0 siblings, 0 replies; 106+ messages in thread
From: Grant Likely @ 2011-01-11 23:27 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	x86-DgEjT+Ai2ygdnm+yROfE0A, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	sodaville-hfZtesqFncYOwBW4kG4KsQ, Sebastian Andrzej Siewior

On Tue, Jan 04, 2011 at 03:27:54PM +0100, Sebastian Andrzej Siewior wrote:
> From: Sebastian Andrzej Siewior <sebastian-E0PNVn5OA6ohrxcnuTQ+TQ@public.gmane.org>
> 
> There is a tiny difference between PPC32 and PPC64. Microblaze uses the
> PPC32 variant.

Mostly looks good, but breaks both Sparc and microblaze which is kind
of important to fix before I merge it.  :-)

Sparc
-----
  CC      drivers/of/of_pci.o
/home/grant/hacking/linux-2.6/drivers/of/of_pci.c: In function 'of_irq_map_pci':
/home/grant/hacking/linux-2.6/drivers/of/of_pci.c:20: error: implicit declaration of function 'of_irq_map_one'
/home/grant/hacking/linux-2.6/drivers/of/of_pci.c:44: error: implicit declaration of function 'pci_bus_to_OF_node'
/home/grant/hacking/linux-2.6/drivers/of/of_pci.c:44: warning: assignment makes pointer from integer without a cast
/home/grant/hacking/linux-2.6/drivers/of/of_pci.c:78: error: implicit declaration of function 'of_irq_map_raw'
make[3]: *** [drivers/of/of_pci.o] Error 1


Microblaze
----------
  CC      arch/microblaze/kernel/prom.o
In file included from /home/grant/hacking/linux-2.6/arch/microblaze/include/asm/pci.h:23,
                 from /home/grant/hacking/linux-2.6/include/linux/pci.h:1230,
                 from /home/grant/hacking/linux-2.6/arch/microblaze/kernel/prom.c:23:
/home/grant/hacking/linux-2.6/arch/microblaze/include/asm/pci-bridge.h: In function 'pci_bus_to_OF_node':
/home/grant/hacking/linux-2.6/arch/microblaze/include/asm/pci-bridge.h:117: error: implicit declaration of function 'pci_device_to_OF_node'
/home/grant/hacking/linux-2.6/arch/microblaze/include/asm/pci-bridge.h:117: warning: return makes pointer from integer without a cast
make[2]: *** [arch/microblaze/kernel/prom.o] Error 1
make[1]: *** [arch/microblaze/kernel] Error 2
make: *** [sub-make] Error 2


> 
> Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
> Cc: Benjamin Herrenschmidt <benh-XVmvHMARGAS8U2dJNN8I7kB+6BGkLq7r@public.gmane.org>
> Signed-off-by: Sebastian Andrzej Siewior <sebastian-E0PNVn5OA6ohrxcnuTQ+TQ@public.gmane.org>
> ---
>  arch/microblaze/include/asm/pci-bridge.h |   10 ++++
>  arch/microblaze/include/asm/prom.h       |   15 -----
>  arch/microblaze/kernel/prom_parse.c      |   77 ---------------------------
>  arch/microblaze/pci/pci-common.c         |    1 +
>  arch/powerpc/include/asm/pci-bridge.h    |   10 ++++
>  arch/powerpc/include/asm/prom.h          |   15 -----
>  arch/powerpc/kernel/pci-common.c         |    1 +
>  arch/powerpc/kernel/prom_parse.c         |   84 ------------------------------
>  drivers/of/Makefile                      |    1 +
>  drivers/of/of_pci.c                      |   80 ++++++++++++++++++++++++++++
>  include/linux/of_pci.h                   |   20 +++++++
>  11 files changed, 123 insertions(+), 191 deletions(-)
>  create mode 100644 drivers/of/of_pci.c
>  create mode 100644 include/linux/of_pci.h
> 
> diff --git a/arch/microblaze/include/asm/pci-bridge.h b/arch/microblaze/include/asm/pci-bridge.h
> index 0c68764..0808217 100644
> --- a/arch/microblaze/include/asm/pci-bridge.h
> +++ b/arch/microblaze/include/asm/pci-bridge.h
> @@ -109,6 +109,16 @@ static inline struct pci_controller *pci_bus_to_host(const struct pci_bus *bus)
>  	return bus->sysdata;
>  }


>  
> +static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
> +{
> +	struct pci_controller *host;
> +
> +	if (bus->self)
> +		return pci_device_to_OF_node(bus->self);
> +	host = pci_bus_to_host(bus);
> +	return host ? host->dn : NULL;
> +}
> +
>  static inline int isa_vaddr_is_ioport(void __iomem *address)
>  {
>  	/* No specific ISA handling on ppc32 at this stage, it
> diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h
> index bdc3831..aa3ab12 100644
> --- a/arch/microblaze/include/asm/prom.h
> +++ b/arch/microblaze/include/asm/prom.h
> @@ -67,21 +67,6 @@ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
>  /* Get the MAC address */
>  extern const void *of_get_mac_address(struct device_node *np);
>  
> -/**
> - * of_irq_map_pci - Resolve the interrupt for a PCI device
> - * @pdev:	the device whose interrupt is to be resolved
> - * @out_irq:	structure of_irq filled by this function
> - *
> - * This function resolves the PCI interrupt for a given PCI device. If a
> - * device-node exists for a given pci_dev, it will use normal OF tree
> - * walking. If not, it will implement standard swizzling and walk up the
> - * PCI tree until an device-node is found, at which point it will finish
> - * resolving using the OF tree walking.
> - */
> -struct pci_dev;
> -struct of_irq;
> -extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
> -
>  #endif /* __ASSEMBLY__ */
>  #endif /* __KERNEL__ */
>  
> diff --git a/arch/microblaze/kernel/prom_parse.c b/arch/microblaze/kernel/prom_parse.c
> index 99d9b61..306f41d 100644
> --- a/arch/microblaze/kernel/prom_parse.c
> +++ b/arch/microblaze/kernel/prom_parse.c
> @@ -2,88 +2,11 @@
>  
>  #include <linux/kernel.h>
>  #include <linux/string.h>
> -#include <linux/pci_regs.h>
>  #include <linux/module.h>
>  #include <linux/ioport.h>
>  #include <linux/etherdevice.h>
>  #include <linux/of_address.h>
>  #include <asm/prom.h>
> -#include <asm/pci-bridge.h>
> -
> -#ifdef CONFIG_PCI
> -int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
> -{
> -	struct device_node *dn, *ppnode;
> -	struct pci_dev *ppdev;
> -	u32 lspec;
> -	u32 laddr[3];
> -	u8 pin;
> -	int rc;
> -
> -	/* Check if we have a device node, if yes, fallback to standard OF
> -	 * parsing
> -	 */
> -	dn = pci_device_to_OF_node(pdev);
> -	if (dn)
> -		return of_irq_map_one(dn, 0, out_irq);
> -
> -	/* Ok, we don't, time to have fun. Let's start by building up an
> -	 * interrupt spec.  we assume #interrupt-cells is 1, which is standard
> -	 * for PCI. If you do different, then don't use that routine.
> -	 */
> -	rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
> -	if (rc != 0)
> -		return rc;
> -	/* No pin, exit */
> -	if (pin == 0)
> -		return -ENODEV;
> -
> -	/* Now we walk up the PCI tree */
> -	lspec = pin;
> -	for (;;) {
> -		/* Get the pci_dev of our parent */
> -		ppdev = pdev->bus->self;
> -
> -		/* Ouch, it's a host bridge... */
> -		if (ppdev == NULL) {
> -			struct pci_controller *host;
> -			host = pci_bus_to_host(pdev->bus);
> -			ppnode = host ? host->dn : NULL;
> -			/* No node for host bridge ? give up */
> -			if (ppnode == NULL)
> -				return -EINVAL;
> -		} else
> -			/* We found a P2P bridge, check if it has a node */
> -			ppnode = pci_device_to_OF_node(ppdev);
> -
> -		/* Ok, we have found a parent with a device-node, hand over to
> -		 * the OF parsing code.
> -		 * We build a unit address from the linux device to be used for
> -		 * resolution. Note that we use the linux bus number which may
> -		 * not match your firmware bus numbering.
> -		 * Fortunately, in most cases, interrupt-map-mask doesn't
> -		 * include the bus number as part of the matching.
> -		 * You should still be careful about that though if you intend
> -		 * to rely on this function (you ship  a firmware that doesn't
> -		 * create device nodes for all PCI devices).
> -		 */
> -		if (ppnode)
> -			break;
> -
> -		/* We can only get here if we hit a P2P bridge with no node,
> -		 * let's do standard swizzling and try again
> -		 */
> -		lspec = pci_swizzle_interrupt_pin(pdev, lspec);
> -		pdev = ppdev;
> -	}
> -
> -	laddr[0] = (pdev->bus->number << 16)
> -		| (pdev->devfn << 8);
> -	laddr[1]  = laddr[2] = 0;
> -	return of_irq_map_raw(ppnode, &lspec, 1, laddr, out_irq);
> -}
> -EXPORT_SYMBOL_GPL(of_irq_map_pci);
> -#endif /* CONFIG_PCI */
>  
>  void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
>  		unsigned long *busno, unsigned long *phys, unsigned long *size)
> diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c
> index e363615..1e01a12 100644
> --- a/arch/microblaze/pci/pci-common.c
> +++ b/arch/microblaze/pci/pci-common.c
> @@ -29,6 +29,7 @@
>  #include <linux/slab.h>
>  #include <linux/of.h>
>  #include <linux/of_address.h>
> +#include <linux/of_pci.h>
>  
>  #include <asm/processor.h>
>  #include <asm/io.h>
> diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h
> index 51e9e6f..edeb80f 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)
>  	return bus->sysdata;
>  }
>  
> +static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
> +{
> +	struct pci_controller *host;
> +
> +	if (bus->self)
> +		return pci_device_to_OF_node(bus->self);
> +	host = pci_bus_to_host(bus);
> +	return host ? host->dn : NULL;
> +}
> +
>  static inline int isa_vaddr_is_ioport(void __iomem *address)
>  {
>  	/* No specific ISA handling on ppc32 at this stage, it
> diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h
> index ae26f2e..01c3302 100644
> --- a/arch/powerpc/include/asm/prom.h
> +++ b/arch/powerpc/include/asm/prom.h
> @@ -73,21 +73,6 @@ static inline int of_node_to_nid(struct device_node *device) { return 0; }
>  #endif
>  #define of_node_to_nid of_node_to_nid
>  
> -/**
> - * of_irq_map_pci - Resolve the interrupt for a PCI device
> - * @pdev:	the device whose interrupt is to be resolved
> - * @out_irq:	structure of_irq filled by this function
> - *
> - * This function resolves the PCI interrupt for a given PCI device. If a
> - * device-node exists for a given pci_dev, it will use normal OF tree
> - * walking. If not, it will implement standard swizzling and walk up the
> - * PCI tree until an device-node is found, at which point it will finish
> - * resolving using the OF tree walking.
> - */
> -struct pci_dev;
> -struct of_irq;
> -extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
> -
>  extern void of_instantiate_rtc(void);
>  
>  /* These includes are put at the bottom because they may contain things
> diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
> index 10a44e6..eb341be 100644
> --- a/arch/powerpc/kernel/pci-common.c
> +++ b/arch/powerpc/kernel/pci-common.c
> @@ -22,6 +22,7 @@
>  #include <linux/init.h>
>  #include <linux/bootmem.h>
>  #include <linux/of_address.h>
> +#include <linux/of_pci.h>
>  #include <linux/mm.h>
>  #include <linux/list.h>
>  #include <linux/syscalls.h>
> diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c
> index 88334af..306f41d 100644
> --- a/arch/powerpc/kernel/prom_parse.c
> +++ b/arch/powerpc/kernel/prom_parse.c
> @@ -2,95 +2,11 @@
>  
>  #include <linux/kernel.h>
>  #include <linux/string.h>
> -#include <linux/pci_regs.h>
>  #include <linux/module.h>
>  #include <linux/ioport.h>
>  #include <linux/etherdevice.h>
>  #include <linux/of_address.h>
>  #include <asm/prom.h>
> -#include <asm/pci-bridge.h>
> -
> -#ifdef CONFIG_PCI
> -int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
> -{
> -	struct device_node *dn, *ppnode;
> -	struct pci_dev *ppdev;
> -	u32 lspec;
> -	u32 laddr[3];
> -	u8 pin;
> -	int rc;
> -
> -	/* Check if we have a device node, if yes, fallback to standard OF
> -	 * parsing
> -	 */
> -	dn = pci_device_to_OF_node(pdev);
> -	if (dn) {
> -		rc = of_irq_map_one(dn, 0, out_irq);
> -		if (!rc)
> -			return rc;
> -	}
> -
> -	/* Ok, we don't, time to have fun. Let's start by building up an
> -	 * interrupt spec.  we assume #interrupt-cells is 1, which is standard
> -	 * for PCI. If you do different, then don't use that routine.
> -	 */
> -	rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
> -	if (rc != 0)
> -		return rc;
> -	/* No pin, exit */
> -	if (pin == 0)
> -		return -ENODEV;
> -
> -	/* Now we walk up the PCI tree */
> -	lspec = pin;
> -	for (;;) {
> -		/* Get the pci_dev of our parent */
> -		ppdev = pdev->bus->self;
> -
> -		/* Ouch, it's a host bridge... */
> -		if (ppdev == NULL) {
> -#ifdef CONFIG_PPC64
> -			ppnode = pci_bus_to_OF_node(pdev->bus);
> -#else
> -			struct pci_controller *host;
> -			host = pci_bus_to_host(pdev->bus);
> -			ppnode = host ? host->dn : NULL;
> -#endif
> -			/* No node for host bridge ? give up */
> -			if (ppnode == NULL)
> -				return -EINVAL;
> -		} else
> -			/* We found a P2P bridge, check if it has a node */
> -			ppnode = pci_device_to_OF_node(ppdev);
> -
> -		/* Ok, we have found a parent with a device-node, hand over to
> -		 * the OF parsing code.
> -		 * We build a unit address from the linux device to be used for
> -		 * resolution. Note that we use the linux bus number which may
> -		 * not match your firmware bus numbering.
> -		 * Fortunately, in most cases, interrupt-map-mask doesn't include
> -		 * the bus number as part of the matching.
> -		 * You should still be careful about that though if you intend
> -		 * to rely on this function (you ship  a firmware that doesn't
> -		 * create device nodes for all PCI devices).
> -		 */
> -		if (ppnode)
> -			break;
> -
> -		/* We can only get here if we hit a P2P bridge with no node,
> -		 * let's do standard swizzling and try again
> -		 */
> -		lspec = pci_swizzle_interrupt_pin(pdev, lspec);
> -		pdev = ppdev;
> -	}
> -
> -	laddr[0] = (pdev->bus->number << 16)
> -		| (pdev->devfn << 8);
> -	laddr[1]  = laddr[2] = 0;
> -	return of_irq_map_raw(ppnode, &lspec, 1, laddr, out_irq);
> -}
> -EXPORT_SYMBOL_GPL(of_irq_map_pci);
> -#endif /* CONFIG_PCI */
>  
>  void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
>  		unsigned long *busno, unsigned long *phys, unsigned long *size)
> diff --git a/drivers/of/Makefile b/drivers/of/Makefile
> index 7888155..4dcb177 100644
> --- a/drivers/of/Makefile
> +++ b/drivers/of/Makefile
> @@ -8,3 +8,4 @@ obj-$(CONFIG_OF_GPIO)   += gpio.o
>  obj-$(CONFIG_OF_I2C)	+= of_i2c.o
>  obj-$(CONFIG_OF_SPI)	+= of_spi.o
>  obj-$(CONFIG_OF_MDIO)	+= of_mdio.o
> +obj-$(CONFIG_PCI)	+= of_pci.o
> diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
> new file mode 100644
> index 0000000..dd862d2
> --- /dev/null
> +++ b/drivers/of/of_pci.c
> @@ -0,0 +1,80 @@
> +#include <linux/kernel.h>
> +#include <linux/of_pci.h>
> +#include <asm/prom.h>
> +
> +int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
> +{
> +	struct device_node *dn, *ppnode;
> +	struct pci_dev *ppdev;
> +	u32 lspec;
> +	__be32 lspec_be;
> +	__be32 laddr[3];
> +	u8 pin;
> +	int rc;
> +
> +	/* Check if we have a device node, if yes, fallback to standard OF
> +	 * parsing
> +	 */
> +	dn = pci_device_to_OF_node(pdev);
> +	if (dn) {
> +		rc = of_irq_map_one(dn, 0, out_irq);
> +		if (!rc)
> +			return rc;
> +	}
> +
> +	/* Ok, we don't, time to have fun. Let's start by building up an
> +	 * interrupt spec.  we assume #interrupt-cells is 1, which is standard
> +	 * for PCI. If you do different, then don't use that routine.
> +	 */
> +	rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
> +	if (rc != 0)
> +		return rc;
> +	/* No pin, exit */
> +	if (pin == 0)
> +		return -ENODEV;
> +
> +	/* Now we walk up the PCI tree */
> +	lspec = pin;
> +	for (;;) {
> +		/* Get the pci_dev of our parent */
> +		ppdev = pdev->bus->self;
> +
> +		/* Ouch, it's a host bridge... */
> +		if (ppdev == NULL) {
> +			ppnode = pci_bus_to_OF_node(pdev->bus);
> +
> +			/* No node for host bridge ? give up */
> +			if (ppnode == NULL)
> +				return -EINVAL;
> +		} else {
> +			/* We found a P2P bridge, check if it has a node */
> +			ppnode = pci_device_to_OF_node(ppdev);
> +		}
> +
> +		/* Ok, we have found a parent with a device-node, hand over to
> +		 * the OF parsing code.
> +		 * We build a unit address from the linux device to be used for
> +		 * resolution. Note that we use the linux bus number which may
> +		 * not match your firmware bus numbering.
> +		 * Fortunately, in most cases, interrupt-map-mask doesn't
> +		 * include the bus number as part of the matching.
> +		 * You should still be careful about that though if you intend
> +		 * to rely on this function (you ship  a firmware that doesn't
> +		 * create device nodes for all PCI devices).
> +		 */
> +		if (ppnode)
> +			break;
> +
> +		/* We can only get here if we hit a P2P bridge with no node,
> +		 * let's do standard swizzling and try again
> +		 */
> +		lspec = pci_swizzle_interrupt_pin(pdev, lspec);
> +		pdev = ppdev;
> +	}
> +
> +	lspec_be = cpu_to_be32(lspec);
> +	laddr[0] = cpu_to_be32((pdev->bus->number << 16) | (pdev->devfn << 8));
> +	laddr[1]  = laddr[2] = cpu_to_be32(0);
> +	return of_irq_map_raw(ppnode, &lspec_be, 1, laddr, out_irq);
> +}
> +EXPORT_SYMBOL_GPL(of_irq_map_pci);
> diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h
> new file mode 100644
> index 0000000..9b0ba67
> --- /dev/null
> +++ b/include/linux/of_pci.h
> @@ -0,0 +1,20 @@
> +#ifndef __OF_PCI_H
> +#define __OF_PCI_H
> +
> +#include <linux/pci.h>
> +
> +/**
> + * of_irq_map_pci - Resolve the interrupt for a PCI device
> + * @pdev:       the device whose interrupt is to be resolved
> + * @out_irq:    structure of_irq filled by this function
> + *
> + * This function resolves the PCI interrupt for a given PCI device. If a
> + * device-node exists for a given pci_dev, it will use normal OF tree
> + * walking. If not, it will implement standard swizzling and walk up the
> + * PCI tree until an device-node is found, at which point it will finish
> + * resolving using the OF tree walking.
> + */
> +struct pci_dev;
> +struct of_irq;
> +int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
> +#endif
> -- 
> 1.7.3.2
> 
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 08/15] x86/dtb: add support for PCI devices backed by dtb nodes
@ 2011-01-11 23:47     ` Grant Likely
  0 siblings, 0 replies; 106+ messages in thread
From: Grant Likely @ 2011-01-11 23:47 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: linux-kernel, sodaville, x86, devicetree-discuss

On Fri, Dec 17, 2010 at 04:33:46PM +0100, Sebastian Andrzej Siewior 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>
> ---
>  arch/x86/include/asm/prom.h |   17 +++++++++
>  arch/x86/kernel/prom.c      |   80 +++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 97 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/x86/include/asm/prom.h b/arch/x86/include/asm/prom.h
> index 3bc8ed5..9f7484e 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,24 @@ 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->dev.of_node;
> +}
> +
> +static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
> +{
> +	if (bus->self)
> +		return pci_device_to_OF_node(bus->self);
> +	else
> +		return NULL;
> +}
> +

Hmmm, maybe pci_device_to_OF_node() should be checking for
bus->self == NULL.  It would probably be safer overall.

Otherwise, the patch looks good to me.

g.


>  #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/prom.c b/arch/x86/kernel/prom.c
> index 40ad8c0..a449dc6 100644
> --- a/arch/x86/kernel/prom.c
> +++ b/arch/x86/kernel/prom.c
> @@ -9,10 +9,13 @@
>  #include <linux/of_address.h>
>  #include <linux/of_platform.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/io_apic.h>
> +#include <asm/pci_x86.h>
>  
>  __initdata u64 initial_dtb;
>  char __initdata cmd_line[COMMAND_LINE_SIZE];
> @@ -102,6 +105,83 @@ void __init add_dtb(u64 data)
>  	initial_dtb = data + offsetof(struct setup_data, data);
>  }
>  
> +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 == NO_IRQ)
> +		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);
> +		}
> +	}
> +}
> +
>  static void __init dtb_setup_hpet(void)
>  {
>  	struct device_node *dn;
> -- 
> 1.7.3.2
> 
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 08/15] x86/dtb: add support for PCI devices backed by dtb nodes
@ 2011-01-11 23:47     ` Grant Likely
  0 siblings, 0 replies; 106+ messages in thread
From: Grant Likely @ 2011-01-11 23:47 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: sodaville-hfZtesqFncYOwBW4kG4KsQ,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	x86-DgEjT+Ai2ygdnm+yROfE0A, linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Fri, Dec 17, 2010 at 04:33:46PM +0100, Sebastian Andrzej Siewior 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-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 |   17 +++++++++
>  arch/x86/kernel/prom.c      |   80 +++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 97 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/x86/include/asm/prom.h b/arch/x86/include/asm/prom.h
> index 3bc8ed5..9f7484e 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,24 @@ 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->dev.of_node;
> +}
> +
> +static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
> +{
> +	if (bus->self)
> +		return pci_device_to_OF_node(bus->self);
> +	else
> +		return NULL;
> +}
> +

Hmmm, maybe pci_device_to_OF_node() should be checking for
bus->self == NULL.  It would probably be safer overall.

Otherwise, the patch looks good to me.

g.


>  #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/prom.c b/arch/x86/kernel/prom.c
> index 40ad8c0..a449dc6 100644
> --- a/arch/x86/kernel/prom.c
> +++ b/arch/x86/kernel/prom.c
> @@ -9,10 +9,13 @@
>  #include <linux/of_address.h>
>  #include <linux/of_platform.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/io_apic.h>
> +#include <asm/pci_x86.h>
>  
>  __initdata u64 initial_dtb;
>  char __initdata cmd_line[COMMAND_LINE_SIZE];
> @@ -102,6 +105,83 @@ void __init add_dtb(u64 data)
>  	initial_dtb = data + offsetof(struct setup_data, data);
>  }
>  
> +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 == NO_IRQ)
> +		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);
> +		}
> +	}
> +}
> +
>  static void __init dtb_setup_hpet(void)
>  {
>  	struct device_node *dn;
> -- 
> 1.7.3.2
> 
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 09/15] x86/dtb: Add generic bus probe
@ 2011-01-11 23:48     ` Grant Likely
  0 siblings, 0 replies; 106+ messages in thread
From: Grant Likely @ 2011-01-11 23:48 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: linux-kernel, sodaville, x86, devicetree-discuss

On Fri, Dec 17, 2010 at 04:33:47PM +0100, Sebastian Andrzej Siewior wrote:
> For now we probe these busses and we change is to board dependent probes
> once we have to.
> 
> 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>

> ---
>  arch/x86/kernel/prom.c |   19 +++++++++++++++++++
>  1 files changed, 19 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/x86/kernel/prom.c b/arch/x86/kernel/prom.c
> index a449dc6..6eddafd 100644
> --- a/arch/x86/kernel/prom.c
> +++ b/arch/x86/kernel/prom.c
> @@ -105,6 +105,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[] = {
> +	{ .type = "soc", },
> +	{ .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);
> +
>  static int x86_of_pci_irq_enable(struct pci_dev *dev)
>  {
>  	struct of_irq oirq;
> -- 
> 1.7.3.2
> 
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 09/15] x86/dtb: Add generic bus probe
@ 2011-01-11 23:48     ` Grant Likely
  0 siblings, 0 replies; 106+ messages in thread
From: Grant Likely @ 2011-01-11 23:48 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: sodaville-hfZtesqFncYOwBW4kG4KsQ,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	x86-DgEjT+Ai2ygdnm+yROfE0A, linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Fri, Dec 17, 2010 at 04:33:47PM +0100, Sebastian Andrzej Siewior wrote:
> 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
> Signed-off-by: Sebastian Andrzej Siewior <bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
> Signed-off-by: Dirk Brandewie <dirk.brandewie-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

Acked-by: Grant Likely <grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org>

> ---
>  arch/x86/kernel/prom.c |   19 +++++++++++++++++++
>  1 files changed, 19 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/x86/kernel/prom.c b/arch/x86/kernel/prom.c
> index a449dc6..6eddafd 100644
> --- a/arch/x86/kernel/prom.c
> +++ b/arch/x86/kernel/prom.c
> @@ -105,6 +105,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[] = {
> +	{ .type = "soc", },
> +	{ .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);
> +
>  static int x86_of_pci_irq_enable(struct pci_dev *dev)
>  {
>  	struct of_irq oirq;
> -- 
> 1.7.3.2
> 
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 10/15] x86/ioapic: Add OF bindings for IO-APIC
@ 2011-01-11 23:53     ` Grant Likely
  0 siblings, 0 replies; 106+ messages in thread
From: Grant Likely @ 2011-01-11 23:53 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: linux-kernel, sodaville, x86, devicetree-discuss

On Fri, Dec 17, 2010 at 04:33:48PM +0100, Sebastian Andrzej Siewior 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.

One question below, but otherwise looks okay to me.

g.

> 
> 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/irqinit.c      |    6 ++
>  arch/x86/kernel/prom.c         |   15 ++++++
>  5 files changed, 129 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
> index f327d38..5a8b950 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_X86_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 9f7484e..8386685 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);
> @@ -46,6 +47,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 7eb0027..4dece80 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_X86_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;
>  
> @@ -4080,6 +4086,99 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
>  	nr_ioapics++;
>  }
>  
> +#ifdef CONFIG_X86_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;
> +		}

I'm confused here.  Are there multiple ioapic's described by a single
device tree node?

> +	}
> +	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/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
> diff --git a/arch/x86/kernel/prom.c b/arch/x86/kernel/prom.c
> index 6eddafd..edcaf1b 100644
> --- a/arch/x86/kernel/prom.c
> +++ b/arch/x86/kernel/prom.c
> @@ -11,9 +11,11 @@
>  #include <linux/slab.h>
>  #include <linux/pci.h>
>  #include <linux/of_pci.h>
> +#include <linux/of_fdt.h>
>  
>  #include <asm/hpet.h>
>  #include <asm/irq_controller.h>
> +#include <asm/apic.h>
>  #include <asm/io_apic.h>
>  #include <asm/pci_x86.h>
>  
> @@ -332,3 +334,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_by_type(dp, "interrupt-controller") {
> +		if (of_device_is_compatible(dp, "intel,ioapic"))
> +			ioapic_add_ofnode(dp);
> +	}
> +}
> -- 
> 1.7.3.2
> 
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 10/15] x86/ioapic: Add OF bindings for IO-APIC
@ 2011-01-11 23:53     ` Grant Likely
  0 siblings, 0 replies; 106+ messages in thread
From: Grant Likely @ 2011-01-11 23:53 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: sodaville-hfZtesqFncYOwBW4kG4KsQ,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	x86-DgEjT+Ai2ygdnm+yROfE0A, linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Fri, Dec 17, 2010 at 04:33:48PM +0100, Sebastian Andrzej Siewior 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.

One question below, but otherwise looks okay to me.

g.

> 
> 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/irqinit.c      |    6 ++
>  arch/x86/kernel/prom.c         |   15 ++++++
>  5 files changed, 129 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
> index f327d38..5a8b950 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_X86_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 9f7484e..8386685 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);
> @@ -46,6 +47,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 7eb0027..4dece80 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_X86_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;
>  
> @@ -4080,6 +4086,99 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
>  	nr_ioapics++;
>  }
>  
> +#ifdef CONFIG_X86_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;
> +		}

I'm confused here.  Are there multiple ioapic's described by a single
device tree node?

> +	}
> +	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/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
> diff --git a/arch/x86/kernel/prom.c b/arch/x86/kernel/prom.c
> index 6eddafd..edcaf1b 100644
> --- a/arch/x86/kernel/prom.c
> +++ b/arch/x86/kernel/prom.c
> @@ -11,9 +11,11 @@
>  #include <linux/slab.h>
>  #include <linux/pci.h>
>  #include <linux/of_pci.h>
> +#include <linux/of_fdt.h>
>  
>  #include <asm/hpet.h>
>  #include <asm/irq_controller.h>
> +#include <asm/apic.h>
>  #include <asm/io_apic.h>
>  #include <asm/pci_x86.h>
>  
> @@ -332,3 +334,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_by_type(dp, "interrupt-controller") {
> +		if (of_device_is_compatible(dp, "intel,ioapic"))
> +			ioapic_add_ofnode(dp);
> +	}
> +}
> -- 
> 1.7.3.2
> 
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 11/15] x86/ce4100: use OF for ioapic
  2010-12-17 15:33 ` [PATCH 11/15] x86/ce4100: use OF for ioapic Sebastian Andrzej Siewior
@ 2011-01-11 23:54   ` Grant Likely
  0 siblings, 0 replies; 106+ messages in thread
From: Grant Likely @ 2011-01-11 23:54 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior; +Cc: linux-kernel, sodaville, x86, dirk.brandewie

On Fri, Dec 17, 2010 at 04:33:49PM +0100, Sebastian Andrzej Siewior wrote:
> and hpet and a few others things....
> 
> Signed-off-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/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.3.2
> 
> --
> 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/

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH v2 13/15] x86/rtc: don't register rtc if we the DT blob
  2011-01-04 13:28     ` [PATCH v2 13/15] x86/rtc: don't register rtc if we the DT blob Sebastian Andrzej Siewior
@ 2011-01-12  0:02       ` Grant Likely
  2011-01-12 18:29         ` Sebastian Andrzej Siewior
  0 siblings, 1 reply; 106+ messages in thread
From: Grant Likely @ 2011-01-12  0:02 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior; +Cc: linux-kernel, sodaville, x86, dirk.brandewie

On Tue, Jan 04, 2011 at 02:28:46PM +0100, Sebastian Andrzej Siewior wrote:
> or we might end up with two device nodes for the same hardware.
> 
> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> ---
>  arch/x86/kernel/rtc.c |   18 ++++++++++++++++++
>  1 files changed, 18 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/x86/kernel/rtc.c b/arch/x86/kernel/rtc.c
> index 1cfbbfc..0cfa138 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>
> @@ -218,6 +219,20 @@ static struct platform_device rtc_device = {
>  	.num_resources	= ARRAY_SIZE(rtc_resources),
>  };
>  
> +#ifdef CONFIG_OF
> +static __init int have_DTB(void)
> +{
> +	if (initial_boot_params)
> +		return 1;
> +	return 0;
> +}
> +#else
> +static inline int have_DTB(void)
> +{
> +	return 0;
> +}
> +#endif
> +

Not quite the right test.  For instance, OLPC has real openfirmware so
initial_boot_params will be zero even though there is a fully
populated device tree.  Should test the allnodes value instead.

Also, this test is useful to more than just rtc I'm sure.  It could
easily live in linux/of.h.

Finally one minor nit.  This is more verbose than it needs to be.  It
could instead be:  "return allnodes != NULL;", and the __init is
unnecessary on a static inline.

g.

>  static __init int add_rtc_cmos(void)
>  {
>  #ifdef CONFIG_PNP
> @@ -237,6 +252,9 @@ static __init int add_rtc_cmos(void)
>  	}
>  #endif
>  
> +	if (have_DTB())
> +		return 0;
> +
>  	platform_device_register(&rtc_device);
>  	dev_info(&rtc_device.dev,
>  		 "registered platform RTC device (no PNP device found)\n");
> -- 
> 1.7.3.2
> 

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 14/15] rtc/cmos: add OF bindings
@ 2011-01-12  0:04     ` Grant Likely
  0 siblings, 0 replies; 106+ messages in thread
From: Grant Likely @ 2011-01-12  0:04 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: linux-kernel, Alessandro Zummo, rtc-linux, x86, sodaville,
	devicetree-discuss

On Fri, Dec 17, 2010 at 04:33:52PM +0100, Sebastian Andrzej Siewior wrote:
> 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.
> 
> Cc: rtc-linux@googlegroups.com
> Cc: Alessandro Zummo <a.zummo@towertech.it>
> Cc: devicetree-discuss@lists.ozlabs.org
> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> Signed-off-by: Dirk Brandewie <dirk.brandewie@gmail.com>
> ---
>  Documentation/powerpc/dts-bindings/rtc-cmos.txt |   28 ++++++++++++++++
>  drivers/rtc/rtc-cmos.c                          |   40 +++++++++++++++++++++++
>  2 files changed, 68 insertions(+), 0 deletions(-)
>  create mode 100644 Documentation/powerpc/dts-bindings/rtc-cmos.txt
> 
> diff --git a/Documentation/powerpc/dts-bindings/rtc-cmos.txt b/Documentation/powerpc/dts-bindings/rtc-cmos.txt
> new file mode 100644
> index 0000000..7382989
> --- /dev/null
> +++ b/Documentation/powerpc/dts-bindings/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/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
> index 5856167..8cf0049 100644
> --- a/drivers/rtc/rtc-cmos.c
> +++ b/drivers/rtc/rtc-cmos.c
> @@ -36,6 +36,8 @@
>  #include <linux/platform_device.h>
>  #include <linux/mod_devicetable.h>
>  #include <linux/log2.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>
> @@ -1121,6 +1123,15 @@ 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);
> +#endif
>  /*----------------------------------------------------------------*/
>  
>  /* Platform setup should have set up an RTC device, when PNP is
> @@ -1129,6 +1140,32 @@ static struct pnp_driver cmos_pnp_driver = {
>  
>  static int __init cmos_platform_probe(struct platform_device *pdev)
>  {
> +#ifdef CONFIG_OF
> +	if (pdev->dev.of_node) {
> +		struct device_node *node = pdev->dev.of_node;
> +		struct rtc_time time;
> +		int ret;
> +		const __be32 *val;
> +
> +		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);
> +		}
> +	}
> +#endif

It's usually cleaner to break the of-specific probe stuff into a
separate function that can be #ifdef'ed out as a whole instead of
having #ifdef blocks inside the probe functions.  Aside from that this
patch looks good to me.

>  	cmos_wake_setup(&pdev->dev);
>  	return cmos_do_probe(&pdev->dev,
>  			platform_get_resource(pdev, IORESOURCE_IO, 0),
> @@ -1157,6 +1194,9 @@ static struct platform_driver cmos_platform_driver = {
>  	.shutdown	= cmos_platform_shutdown,
>  	.driver = {
>  		.name		= (char *) driver_name,
> +#if defined(CONFIG_OF)
> +		.of_match_table = of_cmos_match,
> +#endif
>  		.suspend	= cmos_suspend,
>  		.resume		= cmos_resume,
>  	}
> -- 
> 1.7.3.2
> 
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 14/15] rtc/cmos: add OF bindings
@ 2011-01-12  0:04     ` Grant Likely
  0 siblings, 0 replies; 106+ messages in thread
From: Grant Likely @ 2011-01-12  0:04 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: Alessandro Zummo, rtc-linux-/JYPxA39Uh5TLH3MbocFFw,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	x86-DgEjT+Ai2ygdnm+yROfE0A, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	sodaville-hfZtesqFncYOwBW4kG4KsQ

On Fri, Dec 17, 2010 at 04:33:52PM +0100, Sebastian Andrzej Siewior wrote:
> 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.
> 
> 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/powerpc/dts-bindings/rtc-cmos.txt |   28 ++++++++++++++++
>  drivers/rtc/rtc-cmos.c                          |   40 +++++++++++++++++++++++
>  2 files changed, 68 insertions(+), 0 deletions(-)
>  create mode 100644 Documentation/powerpc/dts-bindings/rtc-cmos.txt
> 
> diff --git a/Documentation/powerpc/dts-bindings/rtc-cmos.txt b/Documentation/powerpc/dts-bindings/rtc-cmos.txt
> new file mode 100644
> index 0000000..7382989
> --- /dev/null
> +++ b/Documentation/powerpc/dts-bindings/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/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
> index 5856167..8cf0049 100644
> --- a/drivers/rtc/rtc-cmos.c
> +++ b/drivers/rtc/rtc-cmos.c
> @@ -36,6 +36,8 @@
>  #include <linux/platform_device.h>
>  #include <linux/mod_devicetable.h>
>  #include <linux/log2.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>
> @@ -1121,6 +1123,15 @@ 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);
> +#endif
>  /*----------------------------------------------------------------*/
>  
>  /* Platform setup should have set up an RTC device, when PNP is
> @@ -1129,6 +1140,32 @@ static struct pnp_driver cmos_pnp_driver = {
>  
>  static int __init cmos_platform_probe(struct platform_device *pdev)
>  {
> +#ifdef CONFIG_OF
> +	if (pdev->dev.of_node) {
> +		struct device_node *node = pdev->dev.of_node;
> +		struct rtc_time time;
> +		int ret;
> +		const __be32 *val;
> +
> +		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);
> +		}
> +	}
> +#endif

It's usually cleaner to break the of-specific probe stuff into a
separate function that can be #ifdef'ed out as a whole instead of
having #ifdef blocks inside the probe functions.  Aside from that this
patch looks good to me.

>  	cmos_wake_setup(&pdev->dev);
>  	return cmos_do_probe(&pdev->dev,
>  			platform_get_resource(pdev, IORESOURCE_IO, 0),
> @@ -1157,6 +1194,9 @@ static struct platform_driver cmos_platform_driver = {
>  	.shutdown	= cmos_platform_shutdown,
>  	.driver = {
>  		.name		= (char *) driver_name,
> +#if defined(CONFIG_OF)
> +		.of_match_table = of_cmos_match,
> +#endif
>  		.suspend	= cmos_suspend,
>  		.resume		= cmos_resume,
>  	}
> -- 
> 1.7.3.2
> 
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 10/15] x86/ioapic: Add OF bindings for IO-APIC
@ 2011-01-12 17:07       ` Sebastian Andrzej Siewior
  0 siblings, 0 replies; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2011-01-12 17:07 UTC (permalink / raw)
  To: Grant Likely
  Cc: Sebastian Andrzej Siewior, linux-kernel, sodaville, x86,
	devicetree-discuss

* Grant Likely | 2011-01-11 16:53:53 [-0700]:

>> +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;
>> +		}
>
>I'm confused here.  Are there multiple ioapic's described by a single
>device tree node?

Yes, the CE4100 has two IO-APICs. It looks like the first one is
responsible for the "legacy devices" (like RTC) and the second one is
used for the "extra devices" like SPI controller, USB, ... The UART
however is not on the first IO-APIC but on the second.

Those two IO-APICs are not cascaded. The device tree contains the line
number of device to the io apic. The kernel computes then interrupt
number based on gsi_base + line_number where gsi_base is incremented by
the number of entries[0]. This interrupt number (gsi_base + line) is then
sent via apic bus to lapic which reports it as the active interrupt
source.

Sebastian

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 10/15] x86/ioapic: Add OF bindings for IO-APIC
@ 2011-01-12 17:07       ` Sebastian Andrzej Siewior
  0 siblings, 0 replies; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2011-01-12 17:07 UTC (permalink / raw)
  To: Grant Likely
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	sodaville-hfZtesqFncYOwBW4kG4KsQ, Sebastian Andrzej Siewior,
	x86-DgEjT+Ai2ygdnm+yROfE0A, linux-kernel-u79uwXL29TY76Z2rM5mHXA

* Grant Likely | 2011-01-11 16:53:53 [-0700]:

>> +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;
>> +		}
>
>I'm confused here.  Are there multiple ioapic's described by a single
>device tree node?

Yes, the CE4100 has two IO-APICs. It looks like the first one is
responsible for the "legacy devices" (like RTC) and the second one is
used for the "extra devices" like SPI controller, USB, ... The UART
however is not on the first IO-APIC but on the second.

Those two IO-APICs are not cascaded. The device tree contains the line
number of device to the io apic. The kernel computes then interrupt
number based on gsi_base + line_number where gsi_base is incremented by
the number of entries[0]. This interrupt number (gsi_base + line) is then
sent via apic bus to lapic which reports it as the active interrupt
source.

Sebastian

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [sodaville] [PATCH 10/15] x86/ioapic: Add OF bindings for IO-APIC
@ 2011-01-12 17:19         ` H. Peter Anvin
  0 siblings, 0 replies; 106+ messages in thread
From: H. Peter Anvin @ 2011-01-12 17:19 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: Grant Likely, devicetree-discuss, sodaville, x86, linux-kernel

On 01/12/2011 09:07 AM, Sebastian Andrzej Siewior wrote:
>>
>> I'm confused here.  Are there multiple ioapic's described by a single
>> device tree node?
> 
> Yes, the CE4100 has two IO-APICs. It looks like the first one is
> responsible for the "legacy devices" (like RTC) and the second one is
> used for the "extra devices" like SPI controller, USB, ... The UART
> however is not on the first IO-APIC but on the second.
> 
> Those two IO-APICs are not cascaded. The device tree contains the line
> number of device to the io apic. The kernel computes then interrupt
> number based on gsi_base + line_number where gsi_base is incremented by
> the number of entries[0]. This interrupt number (gsi_base + line) is then
> sent via apic bus to lapic which reports it as the active interrupt
> source.
> 

That's normal multiple IOAPIC behavior (and multiple IOAPICs is a common
thing), but why use the same device tree node for both?

	-hpa

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [sodaville] [PATCH 10/15] x86/ioapic: Add OF bindings for IO-APIC
@ 2011-01-12 17:19         ` H. Peter Anvin
  0 siblings, 0 replies; 106+ messages in thread
From: H. Peter Anvin @ 2011-01-12 17:19 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: sodaville-hfZtesqFncYOwBW4kG4KsQ,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	x86-DgEjT+Ai2ygdnm+yROfE0A, linux-kernel-u79uwXL29TY76Z2rM5mHXA

On 01/12/2011 09:07 AM, Sebastian Andrzej Siewior wrote:
>>
>> I'm confused here.  Are there multiple ioapic's described by a single
>> device tree node?
> 
> Yes, the CE4100 has two IO-APICs. It looks like the first one is
> responsible for the "legacy devices" (like RTC) and the second one is
> used for the "extra devices" like SPI controller, USB, ... The UART
> however is not on the first IO-APIC but on the second.
> 
> Those two IO-APICs are not cascaded. The device tree contains the line
> number of device to the io apic. The kernel computes then interrupt
> number based on gsi_base + line_number where gsi_base is incremented by
> the number of entries[0]. This interrupt number (gsi_base + line) is then
> sent via apic bus to lapic which reports it as the active interrupt
> source.
> 

That's normal multiple IOAPIC behavior (and multiple IOAPICs is a common
thing), but why use the same device tree node for both?

	-hpa

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH v2 07/15] of: move of_irq_map_pci() into generic code
@ 2011-01-12 18:21           ` Sebastian Andrzej Siewior
  0 siblings, 0 replies; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2011-01-12 18:21 UTC (permalink / raw)
  To: Grant Likely
  Cc: Sebastian Andrzej Siewior, Benjamin Herrenschmidt, x86,
	linux-kernel, sodaville, Sebastian Andrzej Siewior,
	devicetree-discuss

>From 558ec33d76f6f0f4ec7398e6f3af1ea8892d981f Mon Sep 17 00:00:00 2001
From: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
Date: Wed, 1 Dec 2010 21:55:12 +0100
Subject: [PATCH] of: move of_irq_map_pci() into generic code

There is a tiny difference between PPC32 and PPC64. Microblaze uses the
PPC32 variant.

Cc: devicetree-discuss@lists.ozlabs.org
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
---
* Grant Likely | 2011-01-11 16:27:26 [-0700]:

>Mostly looks good, but breaks both Sparc and microblaze which is kind
>of important to fix before I merge it.  :-)
You could note that ppc32/ppc64 built because now it looks like I did
not test it all :)

>Sparc
>-----
>  CC      drivers/of/of_pci.o
>/home/grant/hacking/linux-2.6/drivers/of/of_pci.c: In function 'of_irq_map_pci':
>/home/grant/hacking/linux-2.6/drivers/of/of_pci.c:20: error: implicit declaration of function 'of_irq_map_one'
>/home/grant/hacking/linux-2.6/drivers/of/of_pci.c:44: error: implicit declaration of function 'pci_bus_to_OF_node'
>/home/grant/hacking/linux-2.6/drivers/of/of_pci.c:44: warning: assignment makes pointer from integer without a cast
>/home/grant/hacking/linux-2.6/drivers/of/of_pci.c:78: error: implicit declaration of function 'of_irq_map_raw'
>make[3]: *** [drivers/of/of_pci.o] Error 1
Yeah, I did not expect that. I add some Kconfig magic like that for I2C
and others in order to exclude it on sparc.

>Microblaze
>----------
>  CC      arch/microblaze/kernel/prom.o
>In file included from /home/grant/hacking/linux-2.6/arch/microblaze/include/asm/pci.h:23,
>                 from /home/grant/hacking/linux-2.6/include/linux/pci.h:1230,
>                 from /home/grant/hacking/linux-2.6/arch/microblaze/kernel/prom.c:23:
>/home/grant/hacking/linux-2.6/arch/microblaze/include/asm/pci-bridge.h: In function 'pci_bus_to_OF_node':
>/home/grant/hacking/linux-2.6/arch/microblaze/include/asm/pci-bridge.h:117: error: implicit declaration of function 'pci_device_to_OF_node'
>/home/grant/hacking/linux-2.6/arch/microblaze/include/asm/pci-bridge.h:117: warning: return makes pointer from integer without a cast
>make[2]: *** [arch/microblaze/kernel/prom.o] Error 1
>make[1]: *** [arch/microblaze/kernel] Error 2
>make: *** [sub-make] Error 2

The non-pci case of course. CONFIG_PCI is around pci_device_to_OF_node()
pci.h. I add some of those around the three static inline in
pci-bridge.h. I looks kinda wrong to export all this PCI stuff even that
we don't have PCI around.

 arch/microblaze/include/asm/pci-bridge.h |   12 ++++
 arch/microblaze/include/asm/prom.h       |   15 -----
 arch/microblaze/kernel/prom_parse.c      |   77 ---------------------------
 arch/microblaze/pci/pci-common.c         |    1 +
 arch/powerpc/include/asm/pci-bridge.h    |   10 ++++
 arch/powerpc/include/asm/prom.h          |   15 -----
 arch/powerpc/kernel/pci-common.c         |    1 +
 arch/powerpc/kernel/prom_parse.c         |   84 ------------------------------
 drivers/of/Kconfig                       |    6 ++
 drivers/of/Makefile                      |    1 +
 drivers/of/of_pci.c                      |   80 ++++++++++++++++++++++++++++
 include/linux/of_pci.h                   |   20 +++++++
 12 files changed, 131 insertions(+), 191 deletions(-)
 create mode 100644 drivers/of/of_pci.c
 create mode 100644 include/linux/of_pci.h

diff --git a/arch/microblaze/include/asm/pci-bridge.h b/arch/microblaze/include/asm/pci-bridge.h
index 0c68764..c2a40a4 100644
--- a/arch/microblaze/include/asm/pci-bridge.h
+++ b/arch/microblaze/include/asm/pci-bridge.h
@@ -104,11 +104,22 @@ struct pci_controller {
 	int global_number;	/* PCI domain number */
 };
 
+#ifdef CONFIG_PCI
 static inline struct pci_controller *pci_bus_to_host(const struct pci_bus *bus)
 {
 	return bus->sysdata;
 }
 
+static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
+{
+	struct pci_controller *host;
+
+	if (bus->self)
+		return pci_device_to_OF_node(bus->self);
+	host = pci_bus_to_host(bus);
+	return host ? host->dn : NULL;
+}
+
 static inline int isa_vaddr_is_ioport(void __iomem *address)
 {
 	/* No specific ISA handling on ppc32 at this stage, it
@@ -116,6 +127,7 @@ static inline int isa_vaddr_is_ioport(void __iomem *address)
 	 */
 	return 0;
 }
+#endif
 
 /* These are used for config access before all the PCI probing
    has been done. */
diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h
index bdc3831..aa3ab12 100644
--- a/arch/microblaze/include/asm/prom.h
+++ b/arch/microblaze/include/asm/prom.h
@@ -67,21 +67,6 @@ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
 /* Get the MAC address */
 extern const void *of_get_mac_address(struct device_node *np);
 
-/**
- * of_irq_map_pci - Resolve the interrupt for a PCI device
- * @pdev:	the device whose interrupt is to be resolved
- * @out_irq:	structure of_irq filled by this function
- *
- * This function resolves the PCI interrupt for a given PCI device. If a
- * device-node exists for a given pci_dev, it will use normal OF tree
- * walking. If not, it will implement standard swizzling and walk up the
- * PCI tree until an device-node is found, at which point it will finish
- * resolving using the OF tree walking.
- */
-struct pci_dev;
-struct of_irq;
-extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
-
 #endif /* __ASSEMBLY__ */
 #endif /* __KERNEL__ */
 
diff --git a/arch/microblaze/kernel/prom_parse.c b/arch/microblaze/kernel/prom_parse.c
index 99d9b61..306f41d 100644
--- a/arch/microblaze/kernel/prom_parse.c
+++ b/arch/microblaze/kernel/prom_parse.c
@@ -2,88 +2,11 @@
 
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/pci_regs.h>
 #include <linux/module.h>
 #include <linux/ioport.h>
 #include <linux/etherdevice.h>
 #include <linux/of_address.h>
 #include <asm/prom.h>
-#include <asm/pci-bridge.h>
-
-#ifdef CONFIG_PCI
-int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
-{
-	struct device_node *dn, *ppnode;
-	struct pci_dev *ppdev;
-	u32 lspec;
-	u32 laddr[3];
-	u8 pin;
-	int rc;
-
-	/* Check if we have a device node, if yes, fallback to standard OF
-	 * parsing
-	 */
-	dn = pci_device_to_OF_node(pdev);
-	if (dn)
-		return of_irq_map_one(dn, 0, out_irq);
-
-	/* Ok, we don't, time to have fun. Let's start by building up an
-	 * interrupt spec.  we assume #interrupt-cells is 1, which is standard
-	 * for PCI. If you do different, then don't use that routine.
-	 */
-	rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
-	if (rc != 0)
-		return rc;
-	/* No pin, exit */
-	if (pin == 0)
-		return -ENODEV;
-
-	/* Now we walk up the PCI tree */
-	lspec = pin;
-	for (;;) {
-		/* Get the pci_dev of our parent */
-		ppdev = pdev->bus->self;
-
-		/* Ouch, it's a host bridge... */
-		if (ppdev == NULL) {
-			struct pci_controller *host;
-			host = pci_bus_to_host(pdev->bus);
-			ppnode = host ? host->dn : NULL;
-			/* No node for host bridge ? give up */
-			if (ppnode == NULL)
-				return -EINVAL;
-		} else
-			/* We found a P2P bridge, check if it has a node */
-			ppnode = pci_device_to_OF_node(ppdev);
-
-		/* Ok, we have found a parent with a device-node, hand over to
-		 * the OF parsing code.
-		 * We build a unit address from the linux device to be used for
-		 * resolution. Note that we use the linux bus number which may
-		 * not match your firmware bus numbering.
-		 * Fortunately, in most cases, interrupt-map-mask doesn't
-		 * include the bus number as part of the matching.
-		 * You should still be careful about that though if you intend
-		 * to rely on this function (you ship  a firmware that doesn't
-		 * create device nodes for all PCI devices).
-		 */
-		if (ppnode)
-			break;
-
-		/* We can only get here if we hit a P2P bridge with no node,
-		 * let's do standard swizzling and try again
-		 */
-		lspec = pci_swizzle_interrupt_pin(pdev, lspec);
-		pdev = ppdev;
-	}
-
-	laddr[0] = (pdev->bus->number << 16)
-		| (pdev->devfn << 8);
-	laddr[1]  = laddr[2] = 0;
-	return of_irq_map_raw(ppnode, &lspec, 1, laddr, out_irq);
-}
-EXPORT_SYMBOL_GPL(of_irq_map_pci);
-#endif /* CONFIG_PCI */
 
 void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
 		unsigned long *busno, unsigned long *phys, unsigned long *size)
diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c
index e363615..1e01a12 100644
--- a/arch/microblaze/pci/pci-common.c
+++ b/arch/microblaze/pci/pci-common.c
@@ -29,6 +29,7 @@
 #include <linux/slab.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/of_pci.h>
 
 #include <asm/processor.h>
 #include <asm/io.h>
diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h
index 51e9e6f..edeb80f 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)
 	return bus->sysdata;
 }
 
+static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
+{
+	struct pci_controller *host;
+
+	if (bus->self)
+		return pci_device_to_OF_node(bus->self);
+	host = pci_bus_to_host(bus);
+	return host ? host->dn : NULL;
+}
+
 static inline int isa_vaddr_is_ioport(void __iomem *address)
 {
 	/* No specific ISA handling on ppc32 at this stage, it
diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h
index ae26f2e..01c3302 100644
--- a/arch/powerpc/include/asm/prom.h
+++ b/arch/powerpc/include/asm/prom.h
@@ -73,21 +73,6 @@ static inline int of_node_to_nid(struct device_node *device) { return 0; }
 #endif
 #define of_node_to_nid of_node_to_nid
 
-/**
- * of_irq_map_pci - Resolve the interrupt for a PCI device
- * @pdev:	the device whose interrupt is to be resolved
- * @out_irq:	structure of_irq filled by this function
- *
- * This function resolves the PCI interrupt for a given PCI device. If a
- * device-node exists for a given pci_dev, it will use normal OF tree
- * walking. If not, it will implement standard swizzling and walk up the
- * PCI tree until an device-node is found, at which point it will finish
- * resolving using the OF tree walking.
- */
-struct pci_dev;
-struct of_irq;
-extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
-
 extern void of_instantiate_rtc(void);
 
 /* These includes are put at the bottom because they may contain things
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 10a44e6..eb341be 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -22,6 +22,7 @@
 #include <linux/init.h>
 #include <linux/bootmem.h>
 #include <linux/of_address.h>
+#include <linux/of_pci.h>
 #include <linux/mm.h>
 #include <linux/list.h>
 #include <linux/syscalls.h>
diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c
index 88334af..306f41d 100644
--- a/arch/powerpc/kernel/prom_parse.c
+++ b/arch/powerpc/kernel/prom_parse.c
@@ -2,95 +2,11 @@
 
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/pci_regs.h>
 #include <linux/module.h>
 #include <linux/ioport.h>
 #include <linux/etherdevice.h>
 #include <linux/of_address.h>
 #include <asm/prom.h>
-#include <asm/pci-bridge.h>
-
-#ifdef CONFIG_PCI
-int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
-{
-	struct device_node *dn, *ppnode;
-	struct pci_dev *ppdev;
-	u32 lspec;
-	u32 laddr[3];
-	u8 pin;
-	int rc;
-
-	/* Check if we have a device node, if yes, fallback to standard OF
-	 * parsing
-	 */
-	dn = pci_device_to_OF_node(pdev);
-	if (dn) {
-		rc = of_irq_map_one(dn, 0, out_irq);
-		if (!rc)
-			return rc;
-	}
-
-	/* Ok, we don't, time to have fun. Let's start by building up an
-	 * interrupt spec.  we assume #interrupt-cells is 1, which is standard
-	 * for PCI. If you do different, then don't use that routine.
-	 */
-	rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
-	if (rc != 0)
-		return rc;
-	/* No pin, exit */
-	if (pin == 0)
-		return -ENODEV;
-
-	/* Now we walk up the PCI tree */
-	lspec = pin;
-	for (;;) {
-		/* Get the pci_dev of our parent */
-		ppdev = pdev->bus->self;
-
-		/* Ouch, it's a host bridge... */
-		if (ppdev == NULL) {
-#ifdef CONFIG_PPC64
-			ppnode = pci_bus_to_OF_node(pdev->bus);
-#else
-			struct pci_controller *host;
-			host = pci_bus_to_host(pdev->bus);
-			ppnode = host ? host->dn : NULL;
-#endif
-			/* No node for host bridge ? give up */
-			if (ppnode == NULL)
-				return -EINVAL;
-		} else
-			/* We found a P2P bridge, check if it has a node */
-			ppnode = pci_device_to_OF_node(ppdev);
-
-		/* Ok, we have found a parent with a device-node, hand over to
-		 * the OF parsing code.
-		 * We build a unit address from the linux device to be used for
-		 * resolution. Note that we use the linux bus number which may
-		 * not match your firmware bus numbering.
-		 * Fortunately, in most cases, interrupt-map-mask doesn't include
-		 * the bus number as part of the matching.
-		 * You should still be careful about that though if you intend
-		 * to rely on this function (you ship  a firmware that doesn't
-		 * create device nodes for all PCI devices).
-		 */
-		if (ppnode)
-			break;
-
-		/* We can only get here if we hit a P2P bridge with no node,
-		 * let's do standard swizzling and try again
-		 */
-		lspec = pci_swizzle_interrupt_pin(pdev, lspec);
-		pdev = ppdev;
-	}
-
-	laddr[0] = (pdev->bus->number << 16)
-		| (pdev->devfn << 8);
-	laddr[1]  = laddr[2] = 0;
-	return of_irq_map_raw(ppnode, &lspec, 1, laddr, out_irq);
-}
-EXPORT_SYMBOL_GPL(of_irq_map_pci);
-#endif /* CONFIG_PCI */
 
 void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
 		unsigned long *busno, unsigned long *phys, unsigned long *size)
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index aa675eb..9379a74 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -61,4 +61,10 @@ config OF_MDIO
 	help
 	  OpenFirmware MDIO bus (Ethernet PHY) accessors
 
+config OF_PCI
+	def_tristate PCI
+	depends on PCI && !SPARC
+	help
+	  OpenFirmware PCI bus accessors
+
 endmenu # OF
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index 7888155..4e0c1ef 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_OF_GPIO)   += gpio.o
 obj-$(CONFIG_OF_I2C)	+= of_i2c.o
 obj-$(CONFIG_OF_SPI)	+= of_spi.o
 obj-$(CONFIG_OF_MDIO)	+= of_mdio.o
+obj-$(CONFIG_OF_PCI)	+= of_pci.o
diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
new file mode 100644
index 0000000..dd862d2
--- /dev/null
+++ b/drivers/of/of_pci.c
@@ -0,0 +1,80 @@
+#include <linux/kernel.h>
+#include <linux/of_pci.h>
+#include <asm/prom.h>
+
+int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
+{
+	struct device_node *dn, *ppnode;
+	struct pci_dev *ppdev;
+	u32 lspec;
+	__be32 lspec_be;
+	__be32 laddr[3];
+	u8 pin;
+	int rc;
+
+	/* Check if we have a device node, if yes, fallback to standard OF
+	 * parsing
+	 */
+	dn = pci_device_to_OF_node(pdev);
+	if (dn) {
+		rc = of_irq_map_one(dn, 0, out_irq);
+		if (!rc)
+			return rc;
+	}
+
+	/* Ok, we don't, time to have fun. Let's start by building up an
+	 * interrupt spec.  we assume #interrupt-cells is 1, which is standard
+	 * for PCI. If you do different, then don't use that routine.
+	 */
+	rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
+	if (rc != 0)
+		return rc;
+	/* No pin, exit */
+	if (pin == 0)
+		return -ENODEV;
+
+	/* Now we walk up the PCI tree */
+	lspec = pin;
+	for (;;) {
+		/* Get the pci_dev of our parent */
+		ppdev = pdev->bus->self;
+
+		/* Ouch, it's a host bridge... */
+		if (ppdev == NULL) {
+			ppnode = pci_bus_to_OF_node(pdev->bus);
+
+			/* No node for host bridge ? give up */
+			if (ppnode == NULL)
+				return -EINVAL;
+		} else {
+			/* We found a P2P bridge, check if it has a node */
+			ppnode = pci_device_to_OF_node(ppdev);
+		}
+
+		/* Ok, we have found a parent with a device-node, hand over to
+		 * the OF parsing code.
+		 * We build a unit address from the linux device to be used for
+		 * resolution. Note that we use the linux bus number which may
+		 * not match your firmware bus numbering.
+		 * Fortunately, in most cases, interrupt-map-mask doesn't
+		 * include the bus number as part of the matching.
+		 * You should still be careful about that though if you intend
+		 * to rely on this function (you ship  a firmware that doesn't
+		 * create device nodes for all PCI devices).
+		 */
+		if (ppnode)
+			break;
+
+		/* We can only get here if we hit a P2P bridge with no node,
+		 * let's do standard swizzling and try again
+		 */
+		lspec = pci_swizzle_interrupt_pin(pdev, lspec);
+		pdev = ppdev;
+	}
+
+	lspec_be = cpu_to_be32(lspec);
+	laddr[0] = cpu_to_be32((pdev->bus->number << 16) | (pdev->devfn << 8));
+	laddr[1]  = laddr[2] = cpu_to_be32(0);
+	return of_irq_map_raw(ppnode, &lspec_be, 1, laddr, out_irq);
+}
+EXPORT_SYMBOL_GPL(of_irq_map_pci);
diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h
new file mode 100644
index 0000000..9b0ba67
--- /dev/null
+++ b/include/linux/of_pci.h
@@ -0,0 +1,20 @@
+#ifndef __OF_PCI_H
+#define __OF_PCI_H
+
+#include <linux/pci.h>
+
+/**
+ * of_irq_map_pci - Resolve the interrupt for a PCI device
+ * @pdev:       the device whose interrupt is to be resolved
+ * @out_irq:    structure of_irq filled by this function
+ *
+ * This function resolves the PCI interrupt for a given PCI device. If a
+ * device-node exists for a given pci_dev, it will use normal OF tree
+ * walking. If not, it will implement standard swizzling and walk up the
+ * PCI tree until an device-node is found, at which point it will finish
+ * resolving using the OF tree walking.
+ */
+struct pci_dev;
+struct of_irq;
+int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
+#endif
-- 
1.7.3.2

Sebastian

^ permalink raw reply related	[flat|nested] 106+ messages in thread

* Re: [PATCH v2 07/15] of: move of_irq_map_pci() into generic code
@ 2011-01-12 18:21           ` Sebastian Andrzej Siewior
  0 siblings, 0 replies; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2011-01-12 18:21 UTC (permalink / raw)
  To: Grant Likely
  Cc: Sebastian Andrzej Siewior, x86-DgEjT+Ai2ygdnm+yROfE0A,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	sodaville-hfZtesqFncYOwBW4kG4KsQ, Sebastian Andrzej Siewior,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ

>From 558ec33d76f6f0f4ec7398e6f3af1ea8892d981f Mon Sep 17 00:00:00 2001
From: Sebastian Andrzej Siewior <sebastian-E0PNVn5OA6ohrxcnuTQ+TQ@public.gmane.org>
Date: Wed, 1 Dec 2010 21:55:12 +0100
Subject: [PATCH] of: move of_irq_map_pci() into generic code

There is a tiny difference between PPC32 and PPC64. Microblaze uses the
PPC32 variant.

Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
Cc: Benjamin Herrenschmidt <benh-XVmvHMARGAS8U2dJNN8I7kB+6BGkLq7r@public.gmane.org>
Signed-off-by: Sebastian Andrzej Siewior <sebastian-E0PNVn5OA6ohrxcnuTQ+TQ@public.gmane.org>
---
* Grant Likely | 2011-01-11 16:27:26 [-0700]:

>Mostly looks good, but breaks both Sparc and microblaze which is kind
>of important to fix before I merge it.  :-)
You could note that ppc32/ppc64 built because now it looks like I did
not test it all :)

>Sparc
>-----
>  CC      drivers/of/of_pci.o
>/home/grant/hacking/linux-2.6/drivers/of/of_pci.c: In function 'of_irq_map_pci':
>/home/grant/hacking/linux-2.6/drivers/of/of_pci.c:20: error: implicit declaration of function 'of_irq_map_one'
>/home/grant/hacking/linux-2.6/drivers/of/of_pci.c:44: error: implicit declaration of function 'pci_bus_to_OF_node'
>/home/grant/hacking/linux-2.6/drivers/of/of_pci.c:44: warning: assignment makes pointer from integer without a cast
>/home/grant/hacking/linux-2.6/drivers/of/of_pci.c:78: error: implicit declaration of function 'of_irq_map_raw'
>make[3]: *** [drivers/of/of_pci.o] Error 1
Yeah, I did not expect that. I add some Kconfig magic like that for I2C
and others in order to exclude it on sparc.

>Microblaze
>----------
>  CC      arch/microblaze/kernel/prom.o
>In file included from /home/grant/hacking/linux-2.6/arch/microblaze/include/asm/pci.h:23,
>                 from /home/grant/hacking/linux-2.6/include/linux/pci.h:1230,
>                 from /home/grant/hacking/linux-2.6/arch/microblaze/kernel/prom.c:23:
>/home/grant/hacking/linux-2.6/arch/microblaze/include/asm/pci-bridge.h: In function 'pci_bus_to_OF_node':
>/home/grant/hacking/linux-2.6/arch/microblaze/include/asm/pci-bridge.h:117: error: implicit declaration of function 'pci_device_to_OF_node'
>/home/grant/hacking/linux-2.6/arch/microblaze/include/asm/pci-bridge.h:117: warning: return makes pointer from integer without a cast
>make[2]: *** [arch/microblaze/kernel/prom.o] Error 1
>make[1]: *** [arch/microblaze/kernel] Error 2
>make: *** [sub-make] Error 2

The non-pci case of course. CONFIG_PCI is around pci_device_to_OF_node()
pci.h. I add some of those around the three static inline in
pci-bridge.h. I looks kinda wrong to export all this PCI stuff even that
we don't have PCI around.

 arch/microblaze/include/asm/pci-bridge.h |   12 ++++
 arch/microblaze/include/asm/prom.h       |   15 -----
 arch/microblaze/kernel/prom_parse.c      |   77 ---------------------------
 arch/microblaze/pci/pci-common.c         |    1 +
 arch/powerpc/include/asm/pci-bridge.h    |   10 ++++
 arch/powerpc/include/asm/prom.h          |   15 -----
 arch/powerpc/kernel/pci-common.c         |    1 +
 arch/powerpc/kernel/prom_parse.c         |   84 ------------------------------
 drivers/of/Kconfig                       |    6 ++
 drivers/of/Makefile                      |    1 +
 drivers/of/of_pci.c                      |   80 ++++++++++++++++++++++++++++
 include/linux/of_pci.h                   |   20 +++++++
 12 files changed, 131 insertions(+), 191 deletions(-)
 create mode 100644 drivers/of/of_pci.c
 create mode 100644 include/linux/of_pci.h

diff --git a/arch/microblaze/include/asm/pci-bridge.h b/arch/microblaze/include/asm/pci-bridge.h
index 0c68764..c2a40a4 100644
--- a/arch/microblaze/include/asm/pci-bridge.h
+++ b/arch/microblaze/include/asm/pci-bridge.h
@@ -104,11 +104,22 @@ struct pci_controller {
 	int global_number;	/* PCI domain number */
 };
 
+#ifdef CONFIG_PCI
 static inline struct pci_controller *pci_bus_to_host(const struct pci_bus *bus)
 {
 	return bus->sysdata;
 }
 
+static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
+{
+	struct pci_controller *host;
+
+	if (bus->self)
+		return pci_device_to_OF_node(bus->self);
+	host = pci_bus_to_host(bus);
+	return host ? host->dn : NULL;
+}
+
 static inline int isa_vaddr_is_ioport(void __iomem *address)
 {
 	/* No specific ISA handling on ppc32 at this stage, it
@@ -116,6 +127,7 @@ static inline int isa_vaddr_is_ioport(void __iomem *address)
 	 */
 	return 0;
 }
+#endif
 
 /* These are used for config access before all the PCI probing
    has been done. */
diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h
index bdc3831..aa3ab12 100644
--- a/arch/microblaze/include/asm/prom.h
+++ b/arch/microblaze/include/asm/prom.h
@@ -67,21 +67,6 @@ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
 /* Get the MAC address */
 extern const void *of_get_mac_address(struct device_node *np);
 
-/**
- * of_irq_map_pci - Resolve the interrupt for a PCI device
- * @pdev:	the device whose interrupt is to be resolved
- * @out_irq:	structure of_irq filled by this function
- *
- * This function resolves the PCI interrupt for a given PCI device. If a
- * device-node exists for a given pci_dev, it will use normal OF tree
- * walking. If not, it will implement standard swizzling and walk up the
- * PCI tree until an device-node is found, at which point it will finish
- * resolving using the OF tree walking.
- */
-struct pci_dev;
-struct of_irq;
-extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
-
 #endif /* __ASSEMBLY__ */
 #endif /* __KERNEL__ */
 
diff --git a/arch/microblaze/kernel/prom_parse.c b/arch/microblaze/kernel/prom_parse.c
index 99d9b61..306f41d 100644
--- a/arch/microblaze/kernel/prom_parse.c
+++ b/arch/microblaze/kernel/prom_parse.c
@@ -2,88 +2,11 @@
 
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/pci_regs.h>
 #include <linux/module.h>
 #include <linux/ioport.h>
 #include <linux/etherdevice.h>
 #include <linux/of_address.h>
 #include <asm/prom.h>
-#include <asm/pci-bridge.h>
-
-#ifdef CONFIG_PCI
-int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
-{
-	struct device_node *dn, *ppnode;
-	struct pci_dev *ppdev;
-	u32 lspec;
-	u32 laddr[3];
-	u8 pin;
-	int rc;
-
-	/* Check if we have a device node, if yes, fallback to standard OF
-	 * parsing
-	 */
-	dn = pci_device_to_OF_node(pdev);
-	if (dn)
-		return of_irq_map_one(dn, 0, out_irq);
-
-	/* Ok, we don't, time to have fun. Let's start by building up an
-	 * interrupt spec.  we assume #interrupt-cells is 1, which is standard
-	 * for PCI. If you do different, then don't use that routine.
-	 */
-	rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
-	if (rc != 0)
-		return rc;
-	/* No pin, exit */
-	if (pin == 0)
-		return -ENODEV;
-
-	/* Now we walk up the PCI tree */
-	lspec = pin;
-	for (;;) {
-		/* Get the pci_dev of our parent */
-		ppdev = pdev->bus->self;
-
-		/* Ouch, it's a host bridge... */
-		if (ppdev == NULL) {
-			struct pci_controller *host;
-			host = pci_bus_to_host(pdev->bus);
-			ppnode = host ? host->dn : NULL;
-			/* No node for host bridge ? give up */
-			if (ppnode == NULL)
-				return -EINVAL;
-		} else
-			/* We found a P2P bridge, check if it has a node */
-			ppnode = pci_device_to_OF_node(ppdev);
-
-		/* Ok, we have found a parent with a device-node, hand over to
-		 * the OF parsing code.
-		 * We build a unit address from the linux device to be used for
-		 * resolution. Note that we use the linux bus number which may
-		 * not match your firmware bus numbering.
-		 * Fortunately, in most cases, interrupt-map-mask doesn't
-		 * include the bus number as part of the matching.
-		 * You should still be careful about that though if you intend
-		 * to rely on this function (you ship  a firmware that doesn't
-		 * create device nodes for all PCI devices).
-		 */
-		if (ppnode)
-			break;
-
-		/* We can only get here if we hit a P2P bridge with no node,
-		 * let's do standard swizzling and try again
-		 */
-		lspec = pci_swizzle_interrupt_pin(pdev, lspec);
-		pdev = ppdev;
-	}
-
-	laddr[0] = (pdev->bus->number << 16)
-		| (pdev->devfn << 8);
-	laddr[1]  = laddr[2] = 0;
-	return of_irq_map_raw(ppnode, &lspec, 1, laddr, out_irq);
-}
-EXPORT_SYMBOL_GPL(of_irq_map_pci);
-#endif /* CONFIG_PCI */
 
 void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
 		unsigned long *busno, unsigned long *phys, unsigned long *size)
diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c
index e363615..1e01a12 100644
--- a/arch/microblaze/pci/pci-common.c
+++ b/arch/microblaze/pci/pci-common.c
@@ -29,6 +29,7 @@
 #include <linux/slab.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/of_pci.h>
 
 #include <asm/processor.h>
 #include <asm/io.h>
diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h
index 51e9e6f..edeb80f 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)
 	return bus->sysdata;
 }
 
+static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
+{
+	struct pci_controller *host;
+
+	if (bus->self)
+		return pci_device_to_OF_node(bus->self);
+	host = pci_bus_to_host(bus);
+	return host ? host->dn : NULL;
+}
+
 static inline int isa_vaddr_is_ioport(void __iomem *address)
 {
 	/* No specific ISA handling on ppc32 at this stage, it
diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h
index ae26f2e..01c3302 100644
--- a/arch/powerpc/include/asm/prom.h
+++ b/arch/powerpc/include/asm/prom.h
@@ -73,21 +73,6 @@ static inline int of_node_to_nid(struct device_node *device) { return 0; }
 #endif
 #define of_node_to_nid of_node_to_nid
 
-/**
- * of_irq_map_pci - Resolve the interrupt for a PCI device
- * @pdev:	the device whose interrupt is to be resolved
- * @out_irq:	structure of_irq filled by this function
- *
- * This function resolves the PCI interrupt for a given PCI device. If a
- * device-node exists for a given pci_dev, it will use normal OF tree
- * walking. If not, it will implement standard swizzling and walk up the
- * PCI tree until an device-node is found, at which point it will finish
- * resolving using the OF tree walking.
- */
-struct pci_dev;
-struct of_irq;
-extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
-
 extern void of_instantiate_rtc(void);
 
 /* These includes are put at the bottom because they may contain things
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 10a44e6..eb341be 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -22,6 +22,7 @@
 #include <linux/init.h>
 #include <linux/bootmem.h>
 #include <linux/of_address.h>
+#include <linux/of_pci.h>
 #include <linux/mm.h>
 #include <linux/list.h>
 #include <linux/syscalls.h>
diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c
index 88334af..306f41d 100644
--- a/arch/powerpc/kernel/prom_parse.c
+++ b/arch/powerpc/kernel/prom_parse.c
@@ -2,95 +2,11 @@
 
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/pci_regs.h>
 #include <linux/module.h>
 #include <linux/ioport.h>
 #include <linux/etherdevice.h>
 #include <linux/of_address.h>
 #include <asm/prom.h>
-#include <asm/pci-bridge.h>
-
-#ifdef CONFIG_PCI
-int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
-{
-	struct device_node *dn, *ppnode;
-	struct pci_dev *ppdev;
-	u32 lspec;
-	u32 laddr[3];
-	u8 pin;
-	int rc;
-
-	/* Check if we have a device node, if yes, fallback to standard OF
-	 * parsing
-	 */
-	dn = pci_device_to_OF_node(pdev);
-	if (dn) {
-		rc = of_irq_map_one(dn, 0, out_irq);
-		if (!rc)
-			return rc;
-	}
-
-	/* Ok, we don't, time to have fun. Let's start by building up an
-	 * interrupt spec.  we assume #interrupt-cells is 1, which is standard
-	 * for PCI. If you do different, then don't use that routine.
-	 */
-	rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
-	if (rc != 0)
-		return rc;
-	/* No pin, exit */
-	if (pin == 0)
-		return -ENODEV;
-
-	/* Now we walk up the PCI tree */
-	lspec = pin;
-	for (;;) {
-		/* Get the pci_dev of our parent */
-		ppdev = pdev->bus->self;
-
-		/* Ouch, it's a host bridge... */
-		if (ppdev == NULL) {
-#ifdef CONFIG_PPC64
-			ppnode = pci_bus_to_OF_node(pdev->bus);
-#else
-			struct pci_controller *host;
-			host = pci_bus_to_host(pdev->bus);
-			ppnode = host ? host->dn : NULL;
-#endif
-			/* No node for host bridge ? give up */
-			if (ppnode == NULL)
-				return -EINVAL;
-		} else
-			/* We found a P2P bridge, check if it has a node */
-			ppnode = pci_device_to_OF_node(ppdev);
-
-		/* Ok, we have found a parent with a device-node, hand over to
-		 * the OF parsing code.
-		 * We build a unit address from the linux device to be used for
-		 * resolution. Note that we use the linux bus number which may
-		 * not match your firmware bus numbering.
-		 * Fortunately, in most cases, interrupt-map-mask doesn't include
-		 * the bus number as part of the matching.
-		 * You should still be careful about that though if you intend
-		 * to rely on this function (you ship  a firmware that doesn't
-		 * create device nodes for all PCI devices).
-		 */
-		if (ppnode)
-			break;
-
-		/* We can only get here if we hit a P2P bridge with no node,
-		 * let's do standard swizzling and try again
-		 */
-		lspec = pci_swizzle_interrupt_pin(pdev, lspec);
-		pdev = ppdev;
-	}
-
-	laddr[0] = (pdev->bus->number << 16)
-		| (pdev->devfn << 8);
-	laddr[1]  = laddr[2] = 0;
-	return of_irq_map_raw(ppnode, &lspec, 1, laddr, out_irq);
-}
-EXPORT_SYMBOL_GPL(of_irq_map_pci);
-#endif /* CONFIG_PCI */
 
 void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
 		unsigned long *busno, unsigned long *phys, unsigned long *size)
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index aa675eb..9379a74 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -61,4 +61,10 @@ config OF_MDIO
 	help
 	  OpenFirmware MDIO bus (Ethernet PHY) accessors
 
+config OF_PCI
+	def_tristate PCI
+	depends on PCI && !SPARC
+	help
+	  OpenFirmware PCI bus accessors
+
 endmenu # OF
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index 7888155..4e0c1ef 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_OF_GPIO)   += gpio.o
 obj-$(CONFIG_OF_I2C)	+= of_i2c.o
 obj-$(CONFIG_OF_SPI)	+= of_spi.o
 obj-$(CONFIG_OF_MDIO)	+= of_mdio.o
+obj-$(CONFIG_OF_PCI)	+= of_pci.o
diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
new file mode 100644
index 0000000..dd862d2
--- /dev/null
+++ b/drivers/of/of_pci.c
@@ -0,0 +1,80 @@
+#include <linux/kernel.h>
+#include <linux/of_pci.h>
+#include <asm/prom.h>
+
+int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
+{
+	struct device_node *dn, *ppnode;
+	struct pci_dev *ppdev;
+	u32 lspec;
+	__be32 lspec_be;
+	__be32 laddr[3];
+	u8 pin;
+	int rc;
+
+	/* Check if we have a device node, if yes, fallback to standard OF
+	 * parsing
+	 */
+	dn = pci_device_to_OF_node(pdev);
+	if (dn) {
+		rc = of_irq_map_one(dn, 0, out_irq);
+		if (!rc)
+			return rc;
+	}
+
+	/* Ok, we don't, time to have fun. Let's start by building up an
+	 * interrupt spec.  we assume #interrupt-cells is 1, which is standard
+	 * for PCI. If you do different, then don't use that routine.
+	 */
+	rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
+	if (rc != 0)
+		return rc;
+	/* No pin, exit */
+	if (pin == 0)
+		return -ENODEV;
+
+	/* Now we walk up the PCI tree */
+	lspec = pin;
+	for (;;) {
+		/* Get the pci_dev of our parent */
+		ppdev = pdev->bus->self;
+
+		/* Ouch, it's a host bridge... */
+		if (ppdev == NULL) {
+			ppnode = pci_bus_to_OF_node(pdev->bus);
+
+			/* No node for host bridge ? give up */
+			if (ppnode == NULL)
+				return -EINVAL;
+		} else {
+			/* We found a P2P bridge, check if it has a node */
+			ppnode = pci_device_to_OF_node(ppdev);
+		}
+
+		/* Ok, we have found a parent with a device-node, hand over to
+		 * the OF parsing code.
+		 * We build a unit address from the linux device to be used for
+		 * resolution. Note that we use the linux bus number which may
+		 * not match your firmware bus numbering.
+		 * Fortunately, in most cases, interrupt-map-mask doesn't
+		 * include the bus number as part of the matching.
+		 * You should still be careful about that though if you intend
+		 * to rely on this function (you ship  a firmware that doesn't
+		 * create device nodes for all PCI devices).
+		 */
+		if (ppnode)
+			break;
+
+		/* We can only get here if we hit a P2P bridge with no node,
+		 * let's do standard swizzling and try again
+		 */
+		lspec = pci_swizzle_interrupt_pin(pdev, lspec);
+		pdev = ppdev;
+	}
+
+	lspec_be = cpu_to_be32(lspec);
+	laddr[0] = cpu_to_be32((pdev->bus->number << 16) | (pdev->devfn << 8));
+	laddr[1]  = laddr[2] = cpu_to_be32(0);
+	return of_irq_map_raw(ppnode, &lspec_be, 1, laddr, out_irq);
+}
+EXPORT_SYMBOL_GPL(of_irq_map_pci);
diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h
new file mode 100644
index 0000000..9b0ba67
--- /dev/null
+++ b/include/linux/of_pci.h
@@ -0,0 +1,20 @@
+#ifndef __OF_PCI_H
+#define __OF_PCI_H
+
+#include <linux/pci.h>
+
+/**
+ * of_irq_map_pci - Resolve the interrupt for a PCI device
+ * @pdev:       the device whose interrupt is to be resolved
+ * @out_irq:    structure of_irq filled by this function
+ *
+ * This function resolves the PCI interrupt for a given PCI device. If a
+ * device-node exists for a given pci_dev, it will use normal OF tree
+ * walking. If not, it will implement standard swizzling and walk up the
+ * PCI tree until an device-node is found, at which point it will finish
+ * resolving using the OF tree walking.
+ */
+struct pci_dev;
+struct of_irq;
+int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
+#endif
-- 
1.7.3.2

Sebastian

^ permalink raw reply related	[flat|nested] 106+ messages in thread

* Re: [PATCH v2 13/15] x86/rtc: don't register rtc if we the DT blob
  2011-01-12  0:02       ` Grant Likely
@ 2011-01-12 18:29         ` Sebastian Andrzej Siewior
  2011-01-14 22:16           ` Grant Likely
  0 siblings, 1 reply; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2011-01-12 18:29 UTC (permalink / raw)
  To: Grant Likely
  Cc: Sebastian Andrzej Siewior, linux-kernel, sodaville, x86, dirk.brandewie

* Grant Likely | 2011-01-11 17:02:24 [-0700]:

>> +static __init int have_DTB(void)
>> +{
>> +	if (initial_boot_params)
>> +		return 1;
>> +	return 0;
>> +}

>Not quite the right test.  For instance, OLPC has real openfirmware so
>initial_boot_params will be zero even though there is a fully
>populated device tree.  Should test the allnodes value instead.
Oh really? They do have a device tree and their initial_boot_params is
NULL? I assumed they boot via OF but I saw no evidence of the device
tree as it. In fact I noticed that they have a static PCI bus living in
arch/x86 and I assumed that is the place where their devices are comming
from.
However, this _could_ change the behavior of OLPC and they could lack an
RTC now if it is not comming via isa_pnp thing or via the device tree
(which had no bindings until recently).

>Also, this test is useful to more than just rtc I'm sure.  It could
>easily live in linux/of.h.
Okay.

>Finally one minor nit.  This is more verbose than it needs to be.  It
>could instead be:  "return allnodes != NULL;", and the __init is
>unnecessary on a static inline.

Okay. The static line has no __init just the non inline has __init :)

>g.

Sebastian

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [sodaville] [PATCH 10/15] x86/ioapic: Add OF bindings for IO-APIC
@ 2011-01-13 10:38           ` Sebastian Andrzej Siewior
  0 siblings, 0 replies; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2011-01-13 10:38 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Sebastian Andrzej Siewior, Grant Likely, devicetree-discuss,
	sodaville, x86, linux-kernel

* H. Peter Anvin | 2011-01-12 09:19:53 [-0800]:

>On 01/12/2011 09:07 AM, Sebastian Andrzej Siewior wrote:
>>>
>>> I'm confused here.  Are there multiple ioapic's described by a single
>>> device tree node?
>
>That's normal multiple IOAPIC behavior (and multiple IOAPICs is a common
>thing), but why use the same device tree node for both?

I'm sorry, I miss understood Grant's question. The two io apics in the
system are described by two nodes. ioapic_add_ofnode() is called for one
node:

> +     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;
> +             }

and once it matches the previously registered io apic it calls
add_interrupt_host() on it and returns. x86_add_irq_domains() calls it
for every io apic node so it calls add_interrupt_host() twice.

>	-hpa

Sebastian

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [sodaville] [PATCH 10/15] x86/ioapic: Add OF bindings for IO-APIC
@ 2011-01-13 10:38           ` Sebastian Andrzej Siewior
  0 siblings, 0 replies; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2011-01-13 10:38 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Sebastian Andrzej Siewior, x86-DgEjT+Ai2ygdnm+yROfE0A,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	sodaville-hfZtesqFncYOwBW4kG4KsQ,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ

* H. Peter Anvin | 2011-01-12 09:19:53 [-0800]:

>On 01/12/2011 09:07 AM, Sebastian Andrzej Siewior wrote:
>>>
>>> I'm confused here.  Are there multiple ioapic's described by a single
>>> device tree node?
>
>That's normal multiple IOAPIC behavior (and multiple IOAPICs is a common
>thing), but why use the same device tree node for both?

I'm sorry, I miss understood Grant's question. The two io apics in the
system are described by two nodes. ioapic_add_ofnode() is called for one
node:

> +     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;
> +             }

and once it matches the previously registered io apic it calls
add_interrupt_host() on it and returns. x86_add_irq_domains() calls it
for every io apic node so it calls add_interrupt_host() twice.

>	-hpa

Sebastian

^ permalink raw reply	[flat|nested] 106+ messages in thread

* [PATCH v2] rtc/cmos: add OF bindings
@ 2011-01-13 10:50       ` Sebastian Andrzej Siewior
  0 siblings, 0 replies; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2011-01-13 10:50 UTC (permalink / raw)
  To: Grant Likely
  Cc: Sebastian Andrzej Siewior, linux-kernel, Alessandro Zummo,
	rtc-linux, x86, sodaville, devicetree-discuss

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.

Cc: rtc-linux@googlegroups.com
Cc: Alessandro Zummo <a.zummo@towertech.it>
Cc: devicetree-discuss@lists.ozlabs.org
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Dirk Brandewie <dirk.brandewie@gmail.com>
---

* Grant Likely | 2011-01-11 17:04:42 [-0700]:

>It's usually cleaner to break the of-specific probe stuff into a
>separate function that can be #ifdef'ed out as a whole instead of
>having #ifdef blocks inside the probe functions.  Aside from that this
>patch looks good to me.

Done.

 Documentation/powerpc/dts-bindings/rtc-cmos.txt |   28 ++++++++++++++
 drivers/rtc/rtc-cmos.c                          |   46 +++++++++++++++++++++++
 2 files changed, 74 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/powerpc/dts-bindings/rtc-cmos.txt

diff --git a/Documentation/powerpc/dts-bindings/rtc-cmos.txt b/Documentation/powerpc/dts-bindings/rtc-cmos.txt
new file mode 100644
index 0000000..7382989
--- /dev/null
+++ b/Documentation/powerpc/dts-bindings/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/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
index 5856167..95a08dd 100644
--- a/drivers/rtc/rtc-cmos.c
+++ b/drivers/rtc/rtc-cmos.c
@@ -36,6 +36,8 @@
 #include <linux/platform_device.h>
 #include <linux/mod_devicetable.h>
 #include <linux/log2.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>
@@ -1121,6 +1123,46 @@ 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) {}
+#endif
 /*----------------------------------------------------------------*/
 
 /* Platform setup should have set up an RTC device, when PNP is
@@ -1129,6 +1171,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),
@@ -1157,6 +1200,9 @@ static struct platform_driver cmos_platform_driver = {
 	.shutdown	= cmos_platform_shutdown,
 	.driver = {
 		.name		= (char *) driver_name,
+#if defined(CONFIG_OF)
+		.of_match_table = of_cmos_match,
+#endif
 		.suspend	= cmos_suspend,
 		.resume		= cmos_resume,
 	}
-- 
1.7.3.2



Sebastian

^ permalink raw reply related	[flat|nested] 106+ messages in thread

* [PATCH v2] rtc/cmos: add OF bindings
@ 2011-01-13 10:50       ` Sebastian Andrzej Siewior
  0 siblings, 0 replies; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2011-01-13 10:50 UTC (permalink / raw)
  To: Grant Likely
  Cc: Alessandro Zummo, rtc-linux-/JYPxA39Uh5TLH3MbocFFw,
	Sebastian Andrzej Siewior, x86-DgEjT+Ai2ygdnm+yROfE0A,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	sodaville-hfZtesqFncYOwBW4kG4KsQ,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ

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.

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>
---

* Grant Likely | 2011-01-11 17:04:42 [-0700]:

>It's usually cleaner to break the of-specific probe stuff into a
>separate function that can be #ifdef'ed out as a whole instead of
>having #ifdef blocks inside the probe functions.  Aside from that this
>patch looks good to me.

Done.

 Documentation/powerpc/dts-bindings/rtc-cmos.txt |   28 ++++++++++++++
 drivers/rtc/rtc-cmos.c                          |   46 +++++++++++++++++++++++
 2 files changed, 74 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/powerpc/dts-bindings/rtc-cmos.txt

diff --git a/Documentation/powerpc/dts-bindings/rtc-cmos.txt b/Documentation/powerpc/dts-bindings/rtc-cmos.txt
new file mode 100644
index 0000000..7382989
--- /dev/null
+++ b/Documentation/powerpc/dts-bindings/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/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
index 5856167..95a08dd 100644
--- a/drivers/rtc/rtc-cmos.c
+++ b/drivers/rtc/rtc-cmos.c
@@ -36,6 +36,8 @@
 #include <linux/platform_device.h>
 #include <linux/mod_devicetable.h>
 #include <linux/log2.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>
@@ -1121,6 +1123,46 @@ 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) {}
+#endif
 /*----------------------------------------------------------------*/
 
 /* Platform setup should have set up an RTC device, when PNP is
@@ -1129,6 +1171,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),
@@ -1157,6 +1200,9 @@ static struct platform_driver cmos_platform_driver = {
 	.shutdown	= cmos_platform_shutdown,
 	.driver = {
 		.name		= (char *) driver_name,
+#if defined(CONFIG_OF)
+		.of_match_table = of_cmos_match,
+#endif
 		.suspend	= cmos_suspend,
 		.resume		= cmos_resume,
 	}
-- 
1.7.3.2



Sebastian

^ permalink raw reply related	[flat|nested] 106+ messages in thread

* Re: [PATCH v2 01/15] x86/e820: remove conditional early mapping in parse_e820_ext
  2011-01-04 13:08     ` [PATCH v2 " Sebastian Andrzej Siewior
@ 2011-01-14  8:14       ` Grant Likely
  2011-01-14 10:57         ` Sebastian Andrzej Siewior
  0 siblings, 1 reply; 106+ messages in thread
From: Grant Likely @ 2011-01-14  8:14 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior; +Cc: linux-kernel, sodaville, x86, dirk.brandewie

Hey Sebastian,

Can you please repost this series after the merge window closes?  Some
of the patches have been reworked and reposted, but I've kind of lost
track of which ones need my attention.  Also, some of the patches have
gone in via the tip tree, so it would be useful to regroup and figure
out which ones are no longer needed.

I'll be able to take a fresh look and pick up the ones that are ready
after the merge window closes.

Thanks,
g.


On Tue, Jan 04, 2011 at 02:08:39PM +0100, Sebastian Andrzej Siewior wrote:
> This patch ensures that the memory passed from parse_setup_data() is
> large enough to cover the complete data structure. That means that the
> conditional mapping in parse_e820_ext() can go.
> 
> While here, I also attempt not to map two pages if the address is not
> aligned to a page boundary.
> 
> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> Signed-off-by: Dirk Brandewie <dirk.brandewie@gmail.com>
> ---
>  arch/x86/include/asm/e820.h |    2 +-
>  arch/x86/kernel/e820.c      |    8 +-------
>  arch/x86/kernel/setup.c     |   18 +++++++++++++++---
>  3 files changed, 17 insertions(+), 11 deletions(-)
> 
> diff --git a/arch/x86/include/asm/e820.h b/arch/x86/include/asm/e820.h
> index 5be1542..e956492 100644
> --- a/arch/x86/include/asm/e820.h
> +++ b/arch/x86/include/asm/e820.h
> @@ -93,7 +93,7 @@ extern void e820_setup_gap(void);
>  extern int e820_search_gap(unsigned long *gapstart, unsigned long *gapsize,
>  			unsigned long start_addr, unsigned long long end_addr);
>  struct setup_data;
> -extern void parse_e820_ext(struct setup_data *data, unsigned long pa_data);
> +extern void parse_e820_ext(struct setup_data *data);
>  
>  #if defined(CONFIG_X86_64) || \
>  	(defined(CONFIG_X86_32) && defined(CONFIG_HIBERNATION))
> diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
> index 0c2b7ef..33f6361 100644
> --- a/arch/x86/kernel/e820.c
> +++ b/arch/x86/kernel/e820.c
> @@ -666,21 +666,15 @@ __init void e820_setup_gap(void)
>   * boot_params.e820_map, others are passed via SETUP_E820_EXT node of
>   * linked list of struct setup_data, which is parsed here.
>   */
> -void __init parse_e820_ext(struct setup_data *sdata, unsigned long pa_data)
> +void __init parse_e820_ext(struct setup_data *sdata)
>  {
> -	u32 map_len;
>  	int entries;
>  	struct e820entry *extmap;
>  
>  	entries = sdata->len / sizeof(struct e820entry);
> -	map_len = sdata->len + sizeof(struct setup_data);
> -	if (map_len > PAGE_SIZE)
> -		sdata = early_ioremap(pa_data, map_len);
>  	extmap = (struct e820entry *)(sdata->data);
>  	__append_e820_map(extmap, entries);
>  	sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
> -	if (map_len > PAGE_SIZE)
> -		early_iounmap(sdata, map_len);
>  	printk(KERN_INFO "extended physical RAM map:\n");
>  	e820_print_map("extended");
>  }
> diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
> index 0afb8c7..48e240e 100644
> --- a/arch/x86/kernel/setup.c
> +++ b/arch/x86/kernel/setup.c
> @@ -429,16 +429,28 @@ static void __init parse_setup_data(void)
>  		return;
>  	pa_data = boot_params.hdr.setup_data;
>  	while (pa_data) {
> -		data = early_memremap(pa_data, PAGE_SIZE);
> +		u32 data_len;
> +		u32 map_len;
> +
> +		map_len = max(PAGE_SIZE - (pa_data & ~PAGE_MASK),
> +				(u64)sizeof(struct setup_data));
> +		data = early_memremap(pa_data, map_len);
> +		data_len = data->len + sizeof(struct setup_data);
> +		if (data_len > map_len) {
> +			early_iounmap(data, map_len);
> +			data = early_memremap(pa_data, data_len);
> +			map_len = data_len;
> +		}
> +
>  		switch (data->type) {
>  		case SETUP_E820_EXT:
> -			parse_e820_ext(data, pa_data);
> +			parse_e820_ext(data);
>  			break;
>  		default:
>  			break;
>  		}
>  		pa_data = data->next;
> -		early_iounmap(data, PAGE_SIZE);
> +		early_iounmap(data, map_len);
>  	}
>  }
>  
> -- 
> 1.7.3.2
> 

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH v2 01/15] x86/e820: remove conditional early mapping in parse_e820_ext
  2011-01-14  8:14       ` Grant Likely
@ 2011-01-14 10:57         ` Sebastian Andrzej Siewior
  2011-01-14 21:43           ` Andres Salomon
  0 siblings, 1 reply; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2011-01-14 10:57 UTC (permalink / raw)
  To: Grant Likely
  Cc: Sebastian Andrzej Siewior, linux-kernel, sodaville, x86,
	dirk.brandewie, Andres Salomon

* Grant Likely | 2011-01-14 01:14:46 [-0700]:

>Hey Sebastian,
Hi Grant,

thanks for doing this.

>Can you please repost this series after the merge window closes?  Some
>of the patches have been reworked and reposted, but I've kind of lost
>track of which ones need my attention.  Also, some of the patches have
Yes, this was my secret plan :) I also had to rework patches because of
other patches either because they no longer applied or because the code
had to change in order to work again.

In case "[v2,13/15] x86/rtc: don't register rtc if we the DT blob" [0]
goes into the category "lost track" and not "had no time to reply" could
please take a look? The important part is where it could change behavior
for OLPC and it migh end up without a RTC. I Cc Andres Salomon as might
know where the RTC on OLPC is comming from.

>gone in via the tip tree, so it would be useful to regroup and figure
>out which ones are no longer needed.
I try to regroup and a add TIP or OF prefix.

>I'll be able to take a fresh look and pick up the ones that are ready
>after the merge window closes.
Okay.

>Thanks,
>g.

[0] https://patchwork.kernel.org/patch/450681/

Sebastian

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH v2 01/15] x86/e820: remove conditional early mapping in parse_e820_ext
  2011-01-14 10:57         ` Sebastian Andrzej Siewior
@ 2011-01-14 21:43           ` Andres Salomon
  2011-01-27 19:54             ` Daniel Drake
  0 siblings, 1 reply; 106+ messages in thread
From: Andres Salomon @ 2011-01-14 21:43 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: Grant Likely, linux-kernel, sodaville, x86, dirk.brandewie, dsd

On Fri, 14 Jan 2011 11:57:09 +0100
Sebastian Andrzej Siewior <bigeasy@linutronix.de> wrote:

> * Grant Likely | 2011-01-14 01:14:46 [-0700]:
> 
> >Hey Sebastian,
> Hi Grant,
> 
> thanks for doing this.
> 
> >Can you please repost this series after the merge window closes?
> >Some of the patches have been reworked and reposted, but I've kind
> >of lost track of which ones need my attention.  Also, some of the
> >patches have
> Yes, this was my secret plan :) I also had to rework patches because
> of other patches either because they no longer applied or because the
> code had to change in order to work again.
> 
> In case "[v2,13/15] x86/rtc: don't register rtc if we the DT blob" [0]
> goes into the category "lost track" and not "had no time to reply"
> could please take a look? The important part is where it could change
> behavior for OLPC and it migh end up without a RTC. I Cc Andres
> Salomon as might know where the RTC on OLPC is comming from.

The RTC that OLPC uses for XO-1 was interspersed w/ the power management
stuff, so it hasn't gone upstream yet (dsd is still working on the pm
stuff). Thus, for Linus kernels the XO-1 uses rtc_cmos; so yes, this
could break things.

On OLPC kernels on the XO-1, we read RTC information from the
CS5536's MSRs (note that there's nothing there that's OLPC-specific, so
this should probably become a generic geode RTC driver).  I'm unfamiliar
with the XO-1.5, but it appears we use the VX855 RTC (at least for
wakeups). I don't see a specific RTC driver for it, so I suspect it
relies on rtc_cmos.


> 
> >gone in via the tip tree, so it would be useful to regroup and figure
> >out which ones are no longer needed.
> I try to regroup and a add TIP or OF prefix.
> 
> >I'll be able to take a fresh look and pick up the ones that are ready
> >after the merge window closes.
> Okay.
> 
> >Thanks,
> >g.
> 
> [0] https://patchwork.kernel.org/patch/450681/
> 
> Sebastian

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH v2 13/15] x86/rtc: don't register rtc if we the DT blob
  2011-01-12 18:29         ` Sebastian Andrzej Siewior
@ 2011-01-14 22:16           ` Grant Likely
  0 siblings, 0 replies; 106+ messages in thread
From: Grant Likely @ 2011-01-14 22:16 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior, Andres Salomon
  Cc: linux-kernel, sodaville, x86, dirk.brandewie

On Wed, Jan 12, 2011 at 11:29 AM, Sebastian Andrzej Siewior
<bigeasy@linutronix.de> wrote:
> * Grant Likely | 2011-01-11 17:02:24 [-0700]:
>
>>> +static __init int have_DTB(void)
>>> +{
>>> +    if (initial_boot_params)
>>> +            return 1;
>>> +    return 0;
>>> +}
>
>>Not quite the right test.  For instance, OLPC has real openfirmware so
>>initial_boot_params will be zero even though there is a fully
>>populated device tree.  Should test the allnodes value instead.
> Oh really? They do have a device tree and their initial_boot_params is
> NULL? I assumed they boot via OF but I saw no evidence of the device
> tree as it. In fact I noticed that they have a static PCI bus living in
> arch/x86 and I assumed that is the place where their devices are comming
> from.

I'm not sure how much of it has gone upstream yet (some stuff is going
via tip tree), but when OLPC device tree support gets fully merged, it
will be creating the live tree by poking OFW directly like Sparc does.
 It will not generate a flattree first like PowerPC.  Therefore,
initial_boot_params will be NULL on OLPC.

> However, this _could_ change the behavior of OLPC and they could lack an
> RTC now if it is not comming via isa_pnp thing or via the device tree
> (which had no bindings until recently).

Yes, you'll need to coordinate with Andres to make sure everything
still works.  In fact, I'll be happiest if OLPC and embedded-x86 are
using the same RTC bindings.  However, that point might be moot since
Andres has told me that he has no intention of actually registering
devices from the tree, but rather to just export it to userspace.

g.

-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH v2 05/15] x86/dtb: add early parsing of APIC and IO APIC
@ 2011-01-18 14:56           ` Sebastian Andrzej Siewior
  0 siblings, 0 replies; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2011-01-18 14:56 UTC (permalink / raw)
  To: Grant Likely; +Cc: linux-kernel, sodaville, x86, devicetree-discuss

Grant Likely wrote:
> Hi Sebastian,
Hi Grant,

>> diff --git a/arch/x86/include/asm/prom.h b/arch/x86/include/asm/prom.h
>> index 9076ae4..3bc8ed5 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
> 
> Nit: Personally, I prefer static inlines over preprocessor macros, but
> that isn't anything that will block this patch.

Right. x86 does similar for ioapic function callbacks for CONFIG_IOAPIC
case. So I keep this unless x86 folks want it different.

>> +#ifdef CONFIG_X86_IO_APIC
>> +static void __init dtb_add_ioapic(struct device_node *dn)
>> +{
>> +	unsigned int ioapic_id;
>> +	const __be32 *cell;
>> +	int len;
>> +	struct resource r;
>> +	int ret;
>> +
>> +	cell = of_get_property(dn, "id", &len);
>> +	if (!cell) {
>> +		printk(KERN_ERR "Node %s is missing id property.\n",
>> +				dn->full_name);
>> +		return;
>> +	}
>> +	ioapic_id = of_read_ulong(cell, len / 4);
> 
> This looks like poor usage practise for the device tree.  'id' or any
> kind of enumeration property in a device tree node is strongly
> discouraged.  As much as possible, let Linux dynamically enumerate
> devices rather than trying to explicitly specify the numbering.  Since
> you can explicitly describe the relationship between device nodes in
> the tree, you should find that explicitly specifying numbers is almost
> never required.

Good point. I removed the id property and let linux statically enumerate
it. I don't see any relationship and spec. says only to keep it unique.

Sebastian

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH v2 05/15] x86/dtb: add early parsing of APIC and IO APIC
@ 2011-01-18 14:56           ` Sebastian Andrzej Siewior
  0 siblings, 0 replies; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2011-01-18 14:56 UTC (permalink / raw)
  To: Grant Likely
  Cc: sodaville-hfZtesqFncYOwBW4kG4KsQ,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	x86-DgEjT+Ai2ygdnm+yROfE0A, linux-kernel-u79uwXL29TY76Z2rM5mHXA

Grant Likely wrote:
> Hi Sebastian,
Hi Grant,

>> diff --git a/arch/x86/include/asm/prom.h b/arch/x86/include/asm/prom.h
>> index 9076ae4..3bc8ed5 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
> 
> Nit: Personally, I prefer static inlines over preprocessor macros, but
> that isn't anything that will block this patch.

Right. x86 does similar for ioapic function callbacks for CONFIG_IOAPIC
case. So I keep this unless x86 folks want it different.

>> +#ifdef CONFIG_X86_IO_APIC
>> +static void __init dtb_add_ioapic(struct device_node *dn)
>> +{
>> +	unsigned int ioapic_id;
>> +	const __be32 *cell;
>> +	int len;
>> +	struct resource r;
>> +	int ret;
>> +
>> +	cell = of_get_property(dn, "id", &len);
>> +	if (!cell) {
>> +		printk(KERN_ERR "Node %s is missing id property.\n",
>> +				dn->full_name);
>> +		return;
>> +	}
>> +	ioapic_id = of_read_ulong(cell, len / 4);
> 
> This looks like poor usage practise for the device tree.  'id' or any
> kind of enumeration property in a device tree node is strongly
> discouraged.  As much as possible, let Linux dynamically enumerate
> devices rather than trying to explicitly specify the numbering.  Since
> you can explicitly describe the relationship between device nodes in
> the tree, you should find that explicitly specifying numbers is almost
> never required.

Good point. I removed the id property and let linux statically enumerate
it. I don't see any relationship and spec. says only to keep it unique.

Sebastian

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 04/15] x86/dtb: add irq domain abstraction
@ 2011-01-23 13:06       ` Sebastian Andrzej Siewior
  0 siblings, 0 replies; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2011-01-23 13:06 UTC (permalink / raw)
  To: Grant Likely
  Cc: Sebastian Andrzej Siewior, linux-kernel, sodaville, x86,
	devicetree-discuss

* Grant Likely | 2011-01-11 15:03:17 [-0700]:

>>  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 -ENODEV;
>
>Return value is an unsigned int.  0 or NO_IRQ is the correct thing to
>return if an IRQ cannot be mapped.
fixed.

>> +	ret = ih->xlate(ih, intspec, intsize, &virq, &type);
>> +	if (ret)
>> +		return ret;
>
>Ditto here.  xlate is also supposed to return a virq number, not an
>error code, so the failure condition must be "if (!ret)" or
are you sure on that? The relevant part of powerpc's
irq_create_of_mapping() looks like:

| if (host->ops->xlate(host, controller, intspec, intsize,
|                           &hwirq, &type))
|       return NO_IRQ;

so xlate here returns 0 on success and hwirq via a pointer. I do the
same thing here except I return directly virq instead of
irq_hw_number_t. I add powerpc's irq_create_mapping() including virq <->
hwirq mapping once it is generic. I shouldn't need unless we use
non-ioapics are irq controllers.

>"if (reg == NO_IRQ)".  The former is preferred since we're trying to
>eliminate references to NO_IRQ, not add more of them.
Okay. So try to get rid of NO_IRQ in my series.

Sebastian

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 04/15] x86/dtb: add irq domain abstraction
@ 2011-01-23 13:06       ` Sebastian Andrzej Siewior
  0 siblings, 0 replies; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2011-01-23 13:06 UTC (permalink / raw)
  To: Grant Likely
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	sodaville-hfZtesqFncYOwBW4kG4KsQ, Sebastian Andrzej Siewior,
	x86-DgEjT+Ai2ygdnm+yROfE0A, linux-kernel-u79uwXL29TY76Z2rM5mHXA

* Grant Likely | 2011-01-11 15:03:17 [-0700]:

>>  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 -ENODEV;
>
>Return value is an unsigned int.  0 or NO_IRQ is the correct thing to
>return if an IRQ cannot be mapped.
fixed.

>> +	ret = ih->xlate(ih, intspec, intsize, &virq, &type);
>> +	if (ret)
>> +		return ret;
>
>Ditto here.  xlate is also supposed to return a virq number, not an
>error code, so the failure condition must be "if (!ret)" or
are you sure on that? The relevant part of powerpc's
irq_create_of_mapping() looks like:

| if (host->ops->xlate(host, controller, intspec, intsize,
|                           &hwirq, &type))
|       return NO_IRQ;

so xlate here returns 0 on success and hwirq via a pointer. I do the
same thing here except I return directly virq instead of
irq_hw_number_t. I add powerpc's irq_create_mapping() including virq <->
hwirq mapping once it is generic. I shouldn't need unless we use
non-ioapics are irq controllers.

>"if (reg == NO_IRQ)".  The former is preferred since we're trying to
>eliminate references to NO_IRQ, not add more of them.
Okay. So try to get rid of NO_IRQ in my series.

Sebastian

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH v2 01/15] x86/e820: remove conditional early mapping in parse_e820_ext
  2011-01-14 21:43           ` Andres Salomon
@ 2011-01-27 19:54             ` Daniel Drake
  2011-02-01 13:21               ` Sebastian Andrzej Siewior
  2011-02-02 18:59               ` H. Peter Anvin
  0 siblings, 2 replies; 106+ messages in thread
From: Daniel Drake @ 2011-01-27 19:54 UTC (permalink / raw)
  To: Andres Salomon
  Cc: Sebastian Andrzej Siewior, Grant Likely, linux-kernel, sodaville,
	x86, dirk.brandewie

Hi,



On 14 January 2011 21:43, Andres Salomon <dilinger@queued.net> wrote:
>> In case "[v2,13/15] x86/rtc: don't register rtc if we the DT blob" [0]
>> goes into the category "lost track" and not "had no time to reply"
>> could please take a look? The important part is where it could change
>> behavior for OLPC and it migh end up without a RTC. I Cc Andres
>> Salomon as might know where the RTC on OLPC is comming from.
>
> The RTC that OLPC uses for XO-1 was interspersed w/ the power management
> stuff, so it hasn't gone upstream yet (dsd is still working on the pm
> stuff). Thus, for Linus kernels the XO-1 uses rtc_cmos; so yes, this
> could break things.
>
> On OLPC kernels on the XO-1, we read RTC information from the
> CS5536's MSRs (note that there's nothing there that's OLPC-specific, so
> this should probably become a generic geode RTC driver).  I'm unfamiliar
> with the XO-1.5, but it appears we use the VX855 RTC (at least for
> wakeups). I don't see a specific RTC driver for it, so I suspect it
> relies on rtc_cmos.

Context: https://patchwork.kernel.org/patch/450681/

This patch will indeed cause problems for OLPC. Thanks for bringing it
to our attention.

On OLPC, the device tree is not used as a source of devices like on
other platforms, it is simply used to present information to the
kernel and userspace (in read-only fashion).

If I understand it correctly, the above patch is saying: if we have a
device tree, don't add the standard x86 RTC device.

However, what we need it to say is: if we have a device tree *and* the
device tree is being used as a source of devices, don't add the
standard x86 RTC device.

Therefore in the OLPC case, this particular bail-out condition will
never be met, because the device tree is not being used as a source of
devices.

Does that make sense?

Thanks,
Daniel

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH v2 01/15] x86/e820: remove conditional early mapping in parse_e820_ext
  2011-01-27 19:54             ` Daniel Drake
@ 2011-02-01 13:21               ` Sebastian Andrzej Siewior
  2011-02-01 18:36                 ` Andres Salomon
  2011-02-02 18:59               ` H. Peter Anvin
  1 sibling, 1 reply; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2011-02-01 13:21 UTC (permalink / raw)
  To: Daniel Drake
  Cc: Andres Salomon, Grant Likely, linux-kernel, sodaville, x86,
	dirk.brandewie

Daniel Drake wrote:
> Hi,
Hi,

> Context: https://patchwork.kernel.org/patch/450681/
> 
> This patch will indeed cause problems for OLPC. Thanks for bringing it
> to our attention.
> 
> On OLPC, the device tree is not used as a source of devices like on
> other platforms, it is simply used to present information to the
> kernel and userspace (in read-only fashion).
> 
> If I understand it correctly, the above patch is saying: if we have a
> device tree, don't add the standard x86 RTC device.
Yes.

> However, what we need it to say is: if we have a device tree *and* the
> device tree is being used as a source of devices, don't add the
> standard x86 RTC device.
> 
> Therefore in the OLPC case, this particular bail-out condition will
> never be met, because the device tree is not being used as a source of
> devices.
So it is not case now. Will it ever be?

> 
> Does that make sense?

I don't quite get how or what for do you use the device tree. Could you 
please answer me the following questions:
- is the variable allnodes NULL in your case?
- variable initial_boot_params should be NULL in your case, right?
- how should I checked for "device tree is being used as a source of
   devices"? The nodes on in the device tree are not probed unless one
   calls of_platform_bus_probe() with a few ids. However I do this now
   unconditionally which is not a problem unless you have a device tree ...

> Thanks,
> Daniel

Sebastian

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH v2 01/15] x86/e820: remove conditional early mapping in parse_e820_ext
  2011-02-01 13:21               ` Sebastian Andrzej Siewior
@ 2011-02-01 18:36                 ` Andres Salomon
  2011-02-02  3:10                   ` Grant Likely
  0 siblings, 1 reply; 106+ messages in thread
From: Andres Salomon @ 2011-02-01 18:36 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: Daniel Drake, Grant Likely, linux-kernel, sodaville, x86, dirk.brandewie

On Tue, 01 Feb 2011 14:21:22 +0100
Sebastian Andrzej Siewior <bigeasy@linutronix.de> wrote:

> Daniel Drake wrote:
> > Hi,
> Hi,
> 
> > Context: https://patchwork.kernel.org/patch/450681/
> > 
> > This patch will indeed cause problems for OLPC. Thanks for bringing
> > it to our attention.
> > 
> > On OLPC, the device tree is not used as a source of devices like on
> > other platforms, it is simply used to present information to the
> > kernel and userspace (in read-only fashion).
> > 
> > If I understand it correctly, the above patch is saying: if we have
> > a device tree, don't add the standard x86 RTC device.
> Yes.
> 
> > However, what we need it to say is: if we have a device tree *and*
> > the device tree is being used as a source of devices, don't add the
> > standard x86 RTC device.
> > 
> > Therefore in the OLPC case, this particular bail-out condition will
> > never be met, because the device tree is not being used as a source
> > of devices.
> So it is not case now. Will it ever be?
> 

That is unclear.  For now, it's not, and there aren't plans to make it
so.

> > 
> > Does that make sense?
> 
> I don't quite get how or what for do you use the device tree. Could
> you please answer me the following questions:
> - is the variable allnodes NULL in your case?

No.

> - variable initial_boot_params should be NULL in your case, right?

Yes.

> - how should I checked for "device tree is being used as a source of
>    devices"? The nodes on in the device tree are not probed unless one
>    calls of_platform_bus_probe() with a few ids. However I do this now
>    unconditionally which is not a problem unless you have a device
> tree ...

Perhaps it should be specifically checking for a fdt (by way of
initial_boot_params)?   Sparc also does not have initial_boot_params,
so one might even be able to drop an #ifdef in the process.

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH v2 01/15] x86/e820: remove conditional early mapping in parse_e820_ext
  2011-02-01 18:36                 ` Andres Salomon
@ 2011-02-02  3:10                   ` Grant Likely
  2011-02-02 16:22                     ` Sebastian Andrzej Siewior
  2011-02-03 18:40                     ` Andres Salomon
  0 siblings, 2 replies; 106+ messages in thread
From: Grant Likely @ 2011-02-02  3:10 UTC (permalink / raw)
  To: Andres Salomon
  Cc: Sebastian Andrzej Siewior, Daniel Drake, linux-kernel, sodaville,
	x86, dirk.brandewie

On Tue, Feb 1, 2011 at 11:36 AM, Andres Salomon <dilinger@queued.net> wrote:
> On Tue, 01 Feb 2011 14:21:22 +0100
> Sebastian Andrzej Siewior <bigeasy@linutronix.de> wrote:
>
>> Daniel Drake wrote:
>> > Hi,
>> Hi,
>>
>> > Context: https://patchwork.kernel.org/patch/450681/
>> >
>> > This patch will indeed cause problems for OLPC. Thanks for bringing
>> > it to our attention.
>> >
>> > On OLPC, the device tree is not used as a source of devices like on
>> > other platforms, it is simply used to present information to the
>> > kernel and userspace (in read-only fashion).
>> >
>> > If I understand it correctly, the above patch is saying: if we have
>> > a device tree, don't add the standard x86 RTC device.
>> Yes.
>>
>> > However, what we need it to say is: if we have a device tree *and*
>> > the device tree is being used as a source of devices, don't add the
>> > standard x86 RTC device.
>> >
>> > Therefore in the OLPC case, this particular bail-out condition will
>> > never be met, because the device tree is not being used as a source
>> > of devices.
>> So it is not case now. Will it ever be?
>>
>
> That is unclear.  For now, it's not, and there aren't plans to make it
> so.
>
>> >
>> > Does that make sense?
>>
>> I don't quite get how or what for do you use the device tree. Could
>> you please answer me the following questions:
>> - is the variable allnodes NULL in your case?
>
> No.
>
>> - variable initial_boot_params should be NULL in your case, right?
>
> Yes.
>
>> - how should I checked for "device tree is being used as a source of
>>    devices"? The nodes on in the device tree are not probed unless one
>>    calls of_platform_bus_probe() with a few ids. However I do this now
>>    unconditionally which is not a problem unless you have a device
>> tree ...
>
> Perhaps it should be specifically checking for a fdt (by way of
> initial_boot_params)?   Sparc also does not have initial_boot_params,
> so one might even be able to drop an #ifdef in the process.

OLPC is very much the oddball in this case.  Everyone else uses
devicetree for registering devices.  It could be solved by making OLPC
explicitly register the RTC.

g.

-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH v2 01/15] x86/e820: remove conditional early mapping in parse_e820_ext
  2011-02-02  3:10                   ` Grant Likely
@ 2011-02-02 16:22                     ` Sebastian Andrzej Siewior
  2011-02-03 18:40                     ` Andres Salomon
  1 sibling, 0 replies; 106+ messages in thread
From: Sebastian Andrzej Siewior @ 2011-02-02 16:22 UTC (permalink / raw)
  To: Grant Likely
  Cc: Andres Salomon, Daniel Drake, linux-kernel, sodaville, x86,
	dirk.brandewie

Grant Likely wrote:
>> Perhaps it should be specifically checking for a fdt (by way of
>> initial_boot_params)?   Sparc also does not have initial_boot_params,
>> so one might even be able to drop an #ifdef in the process.
> 
> OLPC is very much the oddball in this case.  Everyone else uses
> devicetree for registering devices.  It could be solved by making OLPC
> explicitly register the RTC.

I second that :)

> 
> g.
> 

Sebastian

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [sodaville] [PATCH v2 01/15] x86/e820: remove conditional early mapping in parse_e820_ext
  2011-01-27 19:54             ` Daniel Drake
  2011-02-01 13:21               ` Sebastian Andrzej Siewior
@ 2011-02-02 18:59               ` H. Peter Anvin
  1 sibling, 0 replies; 106+ messages in thread
From: H. Peter Anvin @ 2011-02-02 18:59 UTC (permalink / raw)
  To: Daniel Drake
  Cc: Andres Salomon, Sebastian Andrzej Siewior, x86, linux-kernel,
	Grant Likely, sodaville

On 01/27/2011 11:54 AM, Daniel Drake wrote:
> 
> This patch will indeed cause problems for OLPC. Thanks for bringing it
> to our attention.
> 
> On OLPC, the device tree is not used as a source of devices like on
> other platforms, it is simply used to present information to the
> kernel and userspace (in read-only fashion).
> 
> If I understand it correctly, the above patch is saying: if we have a
> device tree, don't add the standard x86 RTC device.
> 
> However, what we need it to say is: if we have a device tree *and* the
> device tree is being used as a source of devices, don't add the
> standard x86 RTC device.
> 
> Therefore in the OLPC case, this particular bail-out condition will
> never be met, because the device tree is not being used as a source of
> devices.
> 
> Does that make sense?
> 

It makes sense in the abstract, but it sounds like OLPC is a total WTF
in this sense...

	-hpa

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH v2 01/15] x86/e820: remove conditional early mapping in parse_e820_ext
  2011-02-02  3:10                   ` Grant Likely
  2011-02-02 16:22                     ` Sebastian Andrzej Siewior
@ 2011-02-03 18:40                     ` Andres Salomon
  2011-02-03 19:44                       ` [sodaville] " H. Peter Anvin
  1 sibling, 1 reply; 106+ messages in thread
From: Andres Salomon @ 2011-02-03 18:40 UTC (permalink / raw)
  To: Grant Likely
  Cc: Sebastian Andrzej Siewior, Daniel Drake, linux-kernel, sodaville,
	x86, dirk.brandewie

On Tue, 1 Feb 2011 20:10:13 -0700
Grant Likely <grant.likely@secretlab.ca> wrote:

> On Tue, Feb 1, 2011 at 11:36 AM, Andres Salomon <dilinger@queued.net>
> wrote:
> > On Tue, 01 Feb 2011 14:21:22 +0100
> > Sebastian Andrzej Siewior <bigeasy@linutronix.de> wrote:
> >
> >> Daniel Drake wrote:
> >> > Hi,
> >> Hi,
> >>
> >> > Context: https://patchwork.kernel.org/patch/450681/
> >> >
> >> > This patch will indeed cause problems for OLPC. Thanks for
> >> > bringing it to our attention.
> >> >
> >> > On OLPC, the device tree is not used as a source of devices like
> >> > on other platforms, it is simply used to present information to
> >> > the kernel and userspace (in read-only fashion).
> >> >
> >> > If I understand it correctly, the above patch is saying: if we
> >> > have a device tree, don't add the standard x86 RTC device.
> >> Yes.
> >>
> >> > However, what we need it to say is: if we have a device tree
> >> > *and* the device tree is being used as a source of devices,
> >> > don't add the standard x86 RTC device.
> >> >
> >> > Therefore in the OLPC case, this particular bail-out condition
> >> > will never be met, because the device tree is not being used as
> >> > a source of devices.
> >> So it is not case now. Will it ever be?
> >>
> >
> > That is unclear.  For now, it's not, and there aren't plans to make
> > it so.
> >
> >> >
> >> > Does that make sense?
> >>
> >> I don't quite get how or what for do you use the device tree. Could
> >> you please answer me the following questions:
> >> - is the variable allnodes NULL in your case?
> >
> > No.
> >
> >> - variable initial_boot_params should be NULL in your case, right?
> >
> > Yes.
> >
> >> - how should I checked for "device tree is being used as a source
> >> of devices"? The nodes on in the device tree are not probed unless
> >> one calls of_platform_bus_probe() with a few ids. However I do
> >> this now unconditionally which is not a problem unless you have a
> >> device tree ...
> >
> > Perhaps it should be specifically checking for a fdt (by way of
> > initial_boot_params)?   Sparc also does not have
> > initial_boot_params, so one might even be able to drop an #ifdef in
> > the process.
> 
> OLPC is very much the oddball in this case.  Everyone else uses
> devicetree for registering devices.  It could be solved by making OLPC
> explicitly register the RTC.
> 
> g.
> 

That's actually what the plan is; the code just depends on PM features,
which is still being worked on.


^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [sodaville] [PATCH v2 01/15] x86/e820: remove conditional early mapping in parse_e820_ext
  2011-02-03 18:40                     ` Andres Salomon
@ 2011-02-03 19:44                       ` H. Peter Anvin
  2011-02-03 20:09                         ` Andres Salomon
  0 siblings, 1 reply; 106+ messages in thread
From: H. Peter Anvin @ 2011-02-03 19:44 UTC (permalink / raw)
  To: Andres Salomon
  Cc: Grant Likely, Daniel Drake, Sebastian Andrzej Siewior, x86,
	linux-kernel, sodaville

On 02/03/2011 10:40 AM, Andres Salomon wrote:
> 
> That's actually what the plan is; the code just depends on PM features,
> which is still being worked on.
> 

I really don't understand what this is supposed to mean in this context
at all.

	-hpa

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [sodaville] [PATCH v2 01/15] x86/e820: remove conditional early mapping in parse_e820_ext
  2011-02-03 19:44                       ` [sodaville] " H. Peter Anvin
@ 2011-02-03 20:09                         ` Andres Salomon
  2011-02-03 20:16                           ` H. Peter Anvin
  0 siblings, 1 reply; 106+ messages in thread
From: Andres Salomon @ 2011-02-03 20:09 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Grant Likely, Daniel Drake, Sebastian Andrzej Siewior, x86,
	linux-kernel, sodaville

On Thu, 03 Feb 2011 11:44:15 -0800
"H. Peter Anvin" <hpa@linux.intel.com> wrote:

> On 02/03/2011 10:40 AM, Andres Salomon wrote:
> > 
> > That's actually what the plan is; the code just depends on PM
> > features, which is still being worked on.
> > 
> 
> I really don't understand what this is supposed to mean in this
> context at all.
> 
> 	-hpa


Daniel has a patch set that includes the following:

0010-OLPC-add-XO-1-rtc-driver.patch

+++ b/arch/x86/platform/olpc/olpc.c
@@ -311,6 +311,8 @@ static int __init add_xo1_platform_devices(void)
 {
        struct platform_device *pdev;

+       olpc_xo1_rtc_init();
+
        pdev = platform_device_register_simple("xo1-rfkill", -1, NULL,
  0);


This registers a specific rtc device for XO-1 machines (using the
CS5536 RTC).  XO-1.5 uses ACPI and a Via-based board, so the RTC device
should be handled there automatically.  The corner case is for machines
where the OLPC DT is enabled, but OLPC_XO1_RTC is not enabled.  We
still need to figure out what to do in that case, but I think it's more
appropriate to focus on getting the PM and XO1_RTC stuff upstream
first.  As of right now, it's the *only* case.  We'll change that, by
getting OLPC_XO1_RTC upstream.

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [sodaville] [PATCH v2 01/15] x86/e820: remove conditional early mapping in parse_e820_ext
  2011-02-03 20:09                         ` Andres Salomon
@ 2011-02-03 20:16                           ` H. Peter Anvin
  2011-02-03 20:39                             ` Andres Salomon
  0 siblings, 1 reply; 106+ messages in thread
From: H. Peter Anvin @ 2011-02-03 20:16 UTC (permalink / raw)
  To: Andres Salomon
  Cc: Grant Likely, Daniel Drake, Sebastian Andrzej Siewior, x86,
	linux-kernel, sodaville

On 02/03/2011 12:09 PM, Andres Salomon wrote:
> 
> Daniel has a patch set that includes the following:
> 
> 0010-OLPC-add-XO-1-rtc-driver.patch
> 
> +++ b/arch/x86/platform/olpc/olpc.c
> @@ -311,6 +311,8 @@ static int __init add_xo1_platform_devices(void)
>  {
>         struct platform_device *pdev;
> 
> +       olpc_xo1_rtc_init();
> +
>         pdev = platform_device_register_simple("xo1-rfkill", -1, NULL,
>   0);
> 
> 
> This registers a specific rtc device for XO-1 machines (using the
> CS5536 RTC).  XO-1.5 uses ACPI and a Via-based board, so the RTC device
> should be handled there automatically.  The corner case is for machines
> where the OLPC DT is enabled, but OLPC_XO1_RTC is not enabled.  We
> still need to figure out what to do in that case, but I think it's more
> appropriate to focus on getting the PM and XO1_RTC stuff upstream
> first.  As of right now, it's the *only* case.  We'll change that, by
> getting OLPC_XO1_RTC upstream.

OK, so how about "you're -----d anyway, so please don't block other
development because you haven't gotten your own driver upstream?"

	-hpa

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [sodaville] [PATCH v2 01/15] x86/e820: remove conditional early mapping in parse_e820_ext
  2011-02-03 20:16                           ` H. Peter Anvin
@ 2011-02-03 20:39                             ` Andres Salomon
  2011-02-03 21:04                               ` H. Peter Anvin
  0 siblings, 1 reply; 106+ messages in thread
From: Andres Salomon @ 2011-02-03 20:39 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Grant Likely, Daniel Drake, Sebastian Andrzej Siewior, x86,
	linux-kernel, sodaville

On Thu, 03 Feb 2011 12:16:24 -0800
"H. Peter Anvin" <hpa@linux.intel.com> wrote:

> On 02/03/2011 12:09 PM, Andres Salomon wrote:
> > 
> > Daniel has a patch set that includes the following:
> > 
> > 0010-OLPC-add-XO-1-rtc-driver.patch
> > 
> > +++ b/arch/x86/platform/olpc/olpc.c
> > @@ -311,6 +311,8 @@ static int __init add_xo1_platform_devices(void)
> >  {
> >         struct platform_device *pdev;
> > 
> > +       olpc_xo1_rtc_init();
> > +
> >         pdev = platform_device_register_simple("xo1-rfkill", -1,
> > NULL, 0);
> > 
> > 
> > This registers a specific rtc device for XO-1 machines (using the
> > CS5536 RTC).  XO-1.5 uses ACPI and a Via-based board, so the RTC
> > device should be handled there automatically.  The corner case is
> > for machines where the OLPC DT is enabled, but OLPC_XO1_RTC is not
> > enabled.  We still need to figure out what to do in that case, but
> > I think it's more appropriate to focus on getting the PM and
> > XO1_RTC stuff upstream first.  As of right now, it's the *only*
> > case.  We'll change that, by getting OLPC_XO1_RTC upstream.
> 
> OK, so how about "you're -----d anyway, so please don't block other
> development because you haven't gotten your own driver upstream?"
> 
> 	-hpa

Sorry if I hadn't made that clear, but that's what I was saying.  Go
ahead with the x86 DT stuff, we'll deal with OLPC breakage later.

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [sodaville] [PATCH v2 01/15] x86/e820: remove conditional early mapping in parse_e820_ext
  2011-02-03 20:39                             ` Andres Salomon
@ 2011-02-03 21:04                               ` H. Peter Anvin
  0 siblings, 0 replies; 106+ messages in thread
From: H. Peter Anvin @ 2011-02-03 21:04 UTC (permalink / raw)
  To: Andres Salomon
  Cc: Grant Likely, Daniel Drake, Sebastian Andrzej Siewior, x86,
	linux-kernel, sodaville

On 02/03/2011 12:39 PM, Andres Salomon wrote:
> Sorry if I hadn't made that clear, but that's what I was saying.  Go
> ahead with the x86 DT stuff, we'll deal with OLPC breakage later.

Ah, ok, cool.

	-hpa


^ permalink raw reply	[flat|nested] 106+ messages in thread

* [tip:x86/platform] x86/pci: Remove unused variable
  2010-12-17 15:33 ` [PATCH 15/15] x86/pci: remove warning Sebastian Andrzej Siewior
@ 2011-02-18 16:06   ` tip-bot for Sebastian Andrzej Siewior
  0 siblings, 0 replies; 106+ messages in thread
From: tip-bot for Sebastian Andrzej Siewior @ 2011-02-18 16:06 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: linux-kernel, hpa, mingo, bigeasy, tglx

Commit-ID:  13884c6680973f0ce3483dc59b636b4962d6dafe
Gitweb:     http://git.kernel.org/tip/13884c6680973f0ce3483dc59b636b4962d6dafe
Author:     Sebastian Andrzej Siewior <bigeasy@linutronix.de>
AuthorDate: Fri, 17 Dec 2010 16:33:53 +0100
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Fri, 18 Feb 2011 16:57:18 +0100

x86/pci: Remove unused variable

|arch/x86/pci/ce4100.c: In function `ce4100_conf_read':
|arch/x86/pci/ce4100.c:257:9: warning: unused variable `retval'

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Cc: dirk.brandewie@gmail.com
LKML-Reference: <1292600033-12271-16-git-send-email-bigeasy@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/pci/ce4100.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/x86/pci/ce4100.c b/arch/x86/pci/ce4100.c
index 85b68ef..c63c6d3 100644
--- a/arch/x86/pci/ce4100.c
+++ b/arch/x86/pci/ce4100.c
@@ -254,7 +254,7 @@ int bridge_read(unsigned int devfn, int reg, int len, u32 *value)
 static int ce4100_conf_read(unsigned int seg, unsigned int bus,
 			    unsigned int devfn, int reg, int len, u32 *value)
 {
-	int i, retval = 1;
+	int i;
 
 	if (bus == 1) {
 		for (i = 0; i < ARRAY_SIZE(bus1_fixups); i++) {

^ permalink raw reply related	[flat|nested] 106+ messages in thread

end of thread, other threads:[~2011-02-18 16:07 UTC | newest]

Thread overview: 106+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-12-17 15:33 Add device tree support for x86, v2 Sebastian Andrzej Siewior
2010-12-17 15:33 ` [PATCH 01/15] x86/e820: remove conditional early mapping in parse_e820_ext Sebastian Andrzej Siewior
2010-12-30  8:37   ` Grant Likely
2011-01-04 13:08     ` [PATCH v2 " Sebastian Andrzej Siewior
2011-01-14  8:14       ` Grant Likely
2011-01-14 10:57         ` Sebastian Andrzej Siewior
2011-01-14 21:43           ` Andres Salomon
2011-01-27 19:54             ` Daniel Drake
2011-02-01 13:21               ` Sebastian Andrzej Siewior
2011-02-01 18:36                 ` Andres Salomon
2011-02-02  3:10                   ` Grant Likely
2011-02-02 16:22                     ` Sebastian Andrzej Siewior
2011-02-03 18:40                     ` Andres Salomon
2011-02-03 19:44                       ` [sodaville] " H. Peter Anvin
2011-02-03 20:09                         ` Andres Salomon
2011-02-03 20:16                           ` H. Peter Anvin
2011-02-03 20:39                             ` Andres Salomon
2011-02-03 21:04                               ` H. Peter Anvin
2011-02-02 18:59               ` H. Peter Anvin
2010-12-17 15:33 ` [PATCH 02/15] x86: Add device tree support Sebastian Andrzej Siewior
2010-12-17 15:33   ` Sebastian Andrzej Siewior
2010-12-30  8:43   ` Grant Likely
2010-12-30 21:01     ` Grant Likely
2010-12-30 21:01       ` Grant Likely
2011-01-02  0:40       ` H. Peter Anvin
2011-01-02  0:40         ` H. Peter Anvin
2011-01-03 12:20     ` Sebastian Andrzej Siewior
2011-01-03 12:20       ` Sebastian Andrzej Siewior
2011-01-03 18:05       ` [sodaville] " H. Peter Anvin
2010-12-17 15:33 ` [PATCH 03/15] x86/dtb: Add a device tree for CE4100 Sebastian Andrzej Siewior
2010-12-17 15:33   ` Sebastian Andrzej Siewior
2010-12-30  8:51   ` Grant Likely
2010-12-30  8:51     ` Grant Likely
2011-01-03 11:28     ` Sebastian Andrzej Siewior
2011-01-03 11:28       ` Sebastian Andrzej Siewior
2011-01-03 17:45       ` Grant Likely
2011-01-05  9:48         ` [PATCH v2 " Sebastian Andrzej Siewior
2011-01-05  9:48           ` Sebastian Andrzej Siewior
2011-01-05 10:01     ` [PATCH " Sebastian Andrzej Siewior
2011-01-05 10:01       ` Sebastian Andrzej Siewior
2011-01-05 23:20     ` David Gibson
2011-01-05 23:20       ` David Gibson
2010-12-17 15:33 ` [PATCH 04/15] x86/dtb: add irq domain abstraction Sebastian Andrzej Siewior
2010-12-17 15:33   ` Sebastian Andrzej Siewior
2011-01-11 22:03   ` Grant Likely
2011-01-23 13:06     ` Sebastian Andrzej Siewior
2011-01-23 13:06       ` Sebastian Andrzej Siewior
2010-12-17 15:33 ` [PATCH 05/15] x86/dtb: add early parsing of APIC and IO APIC Sebastian Andrzej Siewior
2010-12-17 15:33   ` Sebastian Andrzej Siewior
2010-12-30  8:54   ` Grant Likely
2010-12-30  8:54     ` Grant Likely
2011-01-04 13:23     ` [PATCH v2 " Sebastian Andrzej Siewior
2011-01-11 22:14       ` Grant Likely
2011-01-11 22:14         ` Grant Likely
2011-01-18 14:56         ` Sebastian Andrzej Siewior
2011-01-18 14:56           ` Sebastian Andrzej Siewior
2010-12-17 15:33 ` [PATCH 06/15] x86/dtb: add support hpet Sebastian Andrzej Siewior
2010-12-17 15:33   ` Sebastian Andrzej Siewior
2011-01-11 22:26   ` Grant Likely
2011-01-11 22:26     ` Grant Likely
2010-12-17 15:33 ` [PATCH 07/15] of: move of_irq_map_pci() into generic code Sebastian Andrzej Siewior
2010-12-17 15:33   ` Sebastian Andrzej Siewior
2010-12-17 21:16   ` Benjamin Herrenschmidt
2011-01-04 14:27     ` [PATCH v2 " Sebastian Andrzej Siewior
2011-01-04 14:27       ` Sebastian Andrzej Siewior
2011-01-11 23:27       ` Grant Likely
2011-01-11 23:27         ` Grant Likely
2011-01-12 18:21         ` Sebastian Andrzej Siewior
2011-01-12 18:21           ` Sebastian Andrzej Siewior
2010-12-17 15:33 ` [PATCH 08/15] x86/dtb: add support for PCI devices backed by dtb nodes Sebastian Andrzej Siewior
2010-12-17 15:33   ` Sebastian Andrzej Siewior
2011-01-11 23:47   ` Grant Likely
2011-01-11 23:47     ` Grant Likely
2010-12-17 15:33 ` [PATCH 09/15] x86/dtb: Add generic bus probe Sebastian Andrzej Siewior
2010-12-17 15:33   ` Sebastian Andrzej Siewior
2011-01-11 23:48   ` Grant Likely
2011-01-11 23:48     ` Grant Likely
2010-12-17 15:33 ` [PATCH 10/15] x86/ioapic: Add OF bindings for IO-APIC Sebastian Andrzej Siewior
2010-12-17 15:33   ` Sebastian Andrzej Siewior
2011-01-11 23:53   ` Grant Likely
2011-01-11 23:53     ` Grant Likely
2011-01-12 17:07     ` Sebastian Andrzej Siewior
2011-01-12 17:07       ` Sebastian Andrzej Siewior
2011-01-12 17:19       ` [sodaville] " H. Peter Anvin
2011-01-12 17:19         ` H. Peter Anvin
2011-01-13 10:38         ` Sebastian Andrzej Siewior
2011-01-13 10:38           ` Sebastian Andrzej Siewior
2010-12-17 15:33 ` [PATCH 11/15] x86/ce4100: use OF for ioapic Sebastian Andrzej Siewior
2011-01-11 23:54   ` Grant Likely
2010-12-17 15:33 ` [PATCH 12/15] of/address: use propper endianess in get_flags Sebastian Andrzej Siewior
2010-12-17 15:33   ` Sebastian Andrzej Siewior
2010-12-30  9:05   ` Grant Likely
2010-12-17 15:33 ` [PATCH 13/15] x86/rtc: don't register rtc if we have an OF node for it Sebastian Andrzej Siewior
2010-12-30  8:59   ` Grant Likely
2011-01-04 13:28     ` [PATCH v2 13/15] x86/rtc: don't register rtc if we the DT blob Sebastian Andrzej Siewior
2011-01-12  0:02       ` Grant Likely
2011-01-12 18:29         ` Sebastian Andrzej Siewior
2011-01-14 22:16           ` Grant Likely
2010-12-17 15:33 ` [PATCH 14/15] rtc/cmos: add OF bindings Sebastian Andrzej Siewior
2010-12-17 15:33   ` Sebastian Andrzej Siewior
2011-01-12  0:04   ` Grant Likely
2011-01-12  0:04     ` Grant Likely
2011-01-13 10:50     ` [PATCH v2] " Sebastian Andrzej Siewior
2011-01-13 10:50       ` Sebastian Andrzej Siewior
2010-12-17 15:33 ` [PATCH 15/15] x86/pci: remove warning Sebastian Andrzej Siewior
2011-02-18 16:06   ` [tip:x86/platform] x86/pci: Remove unused variable tip-bot for Sebastian Andrzej Siewior

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.