All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
To: linux-kernel@vger.kernel.org
Cc: sodaville@linutronix.de, x86@kernel.org,
	devicetree-discuss@lists.ozlabs.org,
	Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Subject: [PATCH TIP 08/14] x86/dtb: add support for PCI devices backed by dtb nodes
Date: Mon, 24 Jan 2011 09:58:56 +0530	[thread overview]
Message-ID: <1295843342-1122-9-git-send-email-bigeasy@linutronix.de> (raw)
In-Reply-To: <1295843342-1122-1-git-send-email-bigeasy@linutronix.de>

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      |   82 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 99 insertions(+), 0 deletions(-)

diff --git a/arch/x86/include/asm/prom.h b/arch/x86/include/asm/prom.h
index bd67ab2..3ed0bd6 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 16c124e..8525ca0 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];
@@ -99,6 +102,85 @@ void __init add_dtb(u64 data)
 	initial_dtb = data + offsetof(struct setup_data, data);
 }
 
+#ifdef CONFIG_PCI
+static int x86_of_pci_irq_enable(struct pci_dev *dev)
+{
+	struct of_irq oirq;
+	u32 virq;
+	int ret;
+	u8 pin;
+
+	ret = pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+	if (ret)
+		return ret;
+	if (!pin)
+		return 0;
+
+	ret = of_irq_map_pci(dev, &oirq);
+	if (ret)
+		return ret;
+
+	virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
+			oirq.size);
+	if (virq == 0)
+		return -EINVAL;
+	dev->irq = virq;
+	return 0;
+}
+
+static void x86_of_pci_irq_disable(struct pci_dev *dev)
+{
+}
+
+void __cpuinit x86_of_pci_init(void)
+{
+	struct device_node *np;
+
+	pcibios_enable_irq = x86_of_pci_irq_enable;
+	pcibios_disable_irq = x86_of_pci_irq_disable;
+
+	for_each_node_by_type(np, "pci") {
+		const void *prop;
+		struct pci_bus *bus;
+		unsigned int bus_min;
+		struct device_node *child;
+
+		prop = of_get_property(np, "bus-range", NULL);
+		if (!prop)
+			continue;
+		bus_min = be32_to_cpup(prop);
+
+		bus = pci_find_bus(0, bus_min);
+		if (!bus) {
+			printk(KERN_ERR "Can't find a node for bus %s.\n",
+					np->full_name);
+			continue;
+		}
+
+		if (bus->self)
+			bus->self->dev.of_node = np;
+		else
+			bus->dev.of_node = np;
+
+		for_each_child_of_node(np, child) {
+			struct pci_dev *dev;
+			u32 devfn;
+
+			prop = of_get_property(child, "reg", NULL);
+			if (!prop)
+				continue;
+
+			devfn = (be32_to_cpup(prop) >> 8) & 0xff;
+			dev = pci_get_slot(bus, devfn);
+			if (!dev)
+				continue;
+			dev->dev.of_node = child;
+			pci_dev_put(dev);
+		}
+	}
+}
+#endif
+
 static void __init dtb_setup_hpet(void)
 {
 	struct device_node *dn;
-- 
1.7.3.2


WARNING: multiple messages have this Message-ID (diff)
From: Sebastian Andrzej Siewior <bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: sodaville-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org,
	x86-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org,
	Sebastian Andrzej Siewior
	<bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
Subject: [PATCH TIP 08/14] x86/dtb: add support for PCI devices backed by dtb nodes
Date: Mon, 24 Jan 2011 09:58:56 +0530	[thread overview]
Message-ID: <1295843342-1122-9-git-send-email-bigeasy@linutronix.de> (raw)
In-Reply-To: <1295843342-1122-1-git-send-email-bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>

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      |   82 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 99 insertions(+), 0 deletions(-)

diff --git a/arch/x86/include/asm/prom.h b/arch/x86/include/asm/prom.h
index bd67ab2..3ed0bd6 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 16c124e..8525ca0 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];
@@ -99,6 +102,85 @@ void __init add_dtb(u64 data)
 	initial_dtb = data + offsetof(struct setup_data, data);
 }
 
+#ifdef CONFIG_PCI
+static int x86_of_pci_irq_enable(struct pci_dev *dev)
+{
+	struct of_irq oirq;
+	u32 virq;
+	int ret;
+	u8 pin;
+
+	ret = pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+	if (ret)
+		return ret;
+	if (!pin)
+		return 0;
+
+	ret = of_irq_map_pci(dev, &oirq);
+	if (ret)
+		return ret;
+
+	virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
+			oirq.size);
+	if (virq == 0)
+		return -EINVAL;
+	dev->irq = virq;
+	return 0;
+}
+
+static void x86_of_pci_irq_disable(struct pci_dev *dev)
+{
+}
+
+void __cpuinit x86_of_pci_init(void)
+{
+	struct device_node *np;
+
+	pcibios_enable_irq = x86_of_pci_irq_enable;
+	pcibios_disable_irq = x86_of_pci_irq_disable;
+
+	for_each_node_by_type(np, "pci") {
+		const void *prop;
+		struct pci_bus *bus;
+		unsigned int bus_min;
+		struct device_node *child;
+
+		prop = of_get_property(np, "bus-range", NULL);
+		if (!prop)
+			continue;
+		bus_min = be32_to_cpup(prop);
+
+		bus = pci_find_bus(0, bus_min);
+		if (!bus) {
+			printk(KERN_ERR "Can't find a node for bus %s.\n",
+					np->full_name);
+			continue;
+		}
+
+		if (bus->self)
+			bus->self->dev.of_node = np;
+		else
+			bus->dev.of_node = np;
+
+		for_each_child_of_node(np, child) {
+			struct pci_dev *dev;
+			u32 devfn;
+
+			prop = of_get_property(child, "reg", NULL);
+			if (!prop)
+				continue;
+
+			devfn = (be32_to_cpup(prop) >> 8) & 0xff;
+			dev = pci_get_slot(bus, devfn);
+			if (!dev)
+				continue;
+			dev->dev.of_node = child;
+			pci_dev_put(dev);
+		}
+	}
+}
+#endif
+
 static void __init dtb_setup_hpet(void)
 {
 	struct device_node *dn;
-- 
1.7.3.2

  parent reply	other threads:[~2011-01-24  4:29 UTC|newest]

Thread overview: 94+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-01-24  4:28 Device tree on x86, part v3 Sebastian Andrzej Siewior
2011-01-24  4:28 ` Sebastian Andrzej Siewior
2011-01-24  4:28 ` [PATCH TIP 01/14] x86/e820: remove conditional early mapping in parse_e820_ext Sebastian Andrzej Siewior
2011-01-24  4:28   ` Sebastian Andrzej Siewior
2011-02-03 20:57   ` Grant Likely
2011-01-24  4:28 ` [PATCH TIP 02/14] x86: Add device tree support Sebastian Andrzej Siewior
2011-01-24  4:28   ` Sebastian Andrzej Siewior
2011-01-24  4:34   ` Sebastian Andrzej Siewior
2011-01-24  4:34     ` Sebastian Andrzej Siewior
2011-02-16 21:27     ` Grant Likely
2011-02-16 21:27       ` Grant Likely
2011-02-17 11:05       ` [sodaville] " Sebastian Andrzej Siewior
2011-02-17 11:05         ` Sebastian Andrzej Siewior
2011-02-16 21:26   ` Grant Likely
2011-02-17 11:03     ` Sebastian Andrzej Siewior
2011-02-17 11:03       ` Sebastian Andrzej Siewior
2011-02-16 21:31   ` Grant Likely
2011-02-16 21:31     ` Grant Likely
2011-02-17 11:31     ` [sodaville] " Sebastian Andrzej Siewior
2011-02-17 11:31       ` Sebastian Andrzej Siewior
2011-02-17 17:02       ` Grant Likely
2011-01-24  4:28 ` [PATCH TIP 03/14] x86/dtb: Add a device tree for CE4100 Sebastian Andrzej Siewior
2011-01-24  4:28   ` Sebastian Andrzej Siewior
2011-01-27  5:00   ` David Gibson
2011-01-27  5:00     ` David Gibson
2011-01-27  9:11     ` Sebastian Andrzej Siewior
2011-01-27  9:11       ` Sebastian Andrzej Siewior
2011-02-03 20:59       ` Grant Likely
2011-02-03 21:32         ` Mitch Bradley
2011-02-03 21:32           ` Mitch Bradley
2011-02-04  9:40           ` Sebastian Andrzej Siewior
2011-02-04  9:40             ` Sebastian Andrzej Siewior
2011-02-02 18:58     ` [PATCH TIP v2 " Sebastian Andrzej Siewior
2011-02-02 18:58       ` Sebastian Andrzej Siewior
2011-02-03 21:07       ` Grant Likely
2011-02-03 21:07         ` Grant Likely
2011-02-04 10:06         ` Sebastian Andrzej Siewior
2011-02-04 10:06           ` Sebastian Andrzej Siewior
2011-02-16 21:44       ` Grant Likely
2011-02-16 21:44         ` Grant Likely
2011-02-22 11:21         ` [sodaville] " Sebastian Andrzej Siewior
2011-02-22 11:21           ` Sebastian Andrzej Siewior
2011-01-24  4:28 ` [PATCH TIP 04/14] x86/dtb: add irq domain abstraction Sebastian Andrzej Siewior
2011-01-24  4:28   ` Sebastian Andrzej Siewior
2011-01-24  4:28 ` [PATCH TIP 05/14] x86/dtb: add early parsing of APIC and IO APIC Sebastian Andrzej Siewior
2011-01-24  4:28   ` Sebastian Andrzej Siewior
2011-02-16 21:47   ` Grant Likely
2011-02-16 21:47     ` Grant Likely
2011-01-24  4:28 ` [PATCH TIP 06/14] x86/dtb: add support hpet Sebastian Andrzej Siewior
2011-01-24  4:28   ` Sebastian Andrzej Siewior
2011-01-24  4:28 ` [PATCH OF 07/14] of: move of_irq_map_pci() into generic code Sebastian Andrzej Siewior
2011-01-24  4:28   ` Sebastian Andrzej Siewior
2011-02-10 13:57   ` Michal Simek
2011-02-16 21:53   ` Grant Likely
2011-02-16 21:53     ` Grant Likely
2011-02-17  7:49     ` Michal Simek
2011-02-17  7:49       ` Michal Simek
2011-02-17  7:49       ` Michal Simek
2011-01-24  4:28 ` Sebastian Andrzej Siewior [this message]
2011-01-24  4:28   ` [PATCH TIP 08/14] x86/dtb: add support for PCI devices backed by dtb nodes Sebastian Andrzej Siewior
2011-02-16 21:59   ` Grant Likely
2011-02-16 21:59     ` Grant Likely
2011-02-22 11:21     ` [sodaville] " Sebastian Andrzej Siewior
2011-02-22 11:21       ` Sebastian Andrzej Siewior
2011-01-24  4:28 ` [PATCH TIP 09/14] x86/dtb: Add generic bus probe Sebastian Andrzej Siewior
2011-01-24  4:28   ` Sebastian Andrzej Siewior
2011-02-04 10:21   ` [PATCH v2 " Sebastian Andrzej Siewior
2011-02-04 10:21     ` Sebastian Andrzej Siewior
2011-02-16 22:04     ` Grant Likely
2011-02-16 22:04       ` Grant Likely
2011-01-24  4:28 ` [PATCH TIP 10/14] x86/ioapic: Add OF bindings for IO-APIC Sebastian Andrzej Siewior
2011-01-24  4:28   ` Sebastian Andrzej Siewior
2011-02-16 22:04   ` Grant Likely
2011-01-24  4:28 ` [PATCH TIP 11/14] x86/ce4100: use OF for ioapic Sebastian Andrzej Siewior
2011-01-24  4:28   ` Sebastian Andrzej Siewior
2011-01-24  4:29 ` [PATCH OF 12/14] x86/rtc: don't register rtc if we the DT blob Sebastian Andrzej Siewior
2011-01-24  4:29   ` Sebastian Andrzej Siewior
2011-02-16 22:08   ` Grant Likely
2011-02-16 22:08     ` Grant Likely
2011-02-16 22:09   ` Grant Likely
2011-02-16 22:09     ` Grant Likely
2011-02-17 13:13     ` [sodaville] " Sebastian Andrzej Siewior
2011-02-17 13:13       ` Sebastian Andrzej Siewior
2011-01-24  4:29 ` [PATCH OF 13/14] rtc/cmos: add OF bindings Sebastian Andrzej Siewior
2011-01-24  4:29   ` Sebastian Andrzej Siewior
2011-01-24  4:38   ` Sebastian Andrzej Siewior
2011-01-24  4:38     ` Sebastian Andrzej Siewior
2011-02-16 22:11   ` Grant Likely
2011-02-16 22:11     ` Grant Likely
2011-02-17 13:26     ` [sodaville] " Sebastian Andrzej Siewior
2011-02-17 13:26       ` Sebastian Andrzej Siewior
2011-02-17 16:46       ` Grant Likely
2011-01-24  4:29 ` [PATCH TIP 14/14] x86/pci: remove warning Sebastian Andrzej Siewior
2011-01-24  4:29   ` Sebastian Andrzej Siewior

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1295843342-1122-9-git-send-email-bigeasy@linutronix.de \
    --to=bigeasy@linutronix.de \
    --cc=devicetree-discuss@lists.ozlabs.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=sodaville@linutronix.de \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.