Skip to contentSkip to conversation

STA2X11 devicetree support for amba/pci

PATCH In review Alessandro Rubini 4 participants 35 messages Aug 7, 2013

Subsystems (15)
Device tree bindings x86 PCI GPIO +11 more subsystems
lore
Share & tools
lore
#0 lore raw

cover STA2X11 devicetree support for amba/pci

[DISCLAIMER : both of us (Alessandro and Davide) are not devicetree experts, so please understand how our issues and our dislike of the approach may result from some lack of knowledge. (any pointer is welcome).]

As some of you may remember, we're submitting patches adding support for the STA2X11 (aka Connext) ST chip. The device is a pci-express I/O HUB containing a number of AMBA peripherals (gpios, uarts, mmc/sd, dma, ST msps, spi, i2c). Being a PCI device, it's fully autoprobed:
we can even plug two evaluation boards in the same PC, and all devices in there are expected to work (and they do, with some of our patch-sets).

A first set of drivers for this chip was written by Wind River, by simply copying AMBA drivers and turning them into pci drivers. This of course worked, but implied tons of duplicated code. Our attempt was to recycle existing AMBA drivers by instantiating AMBA devices at runtime. This was done by a rather simple pci to amba "bridge" module, submitted several times, up to https://lkml.org/lkml/2013/2/20/698

The problem was that AMBA devices need platform data with some instance information. Platform code (under arch/x86/sta2x11/) was submitted for some Connext based boards, but it was rejected as "ARM shit" by Peter Anvin (https://lkml.org/lkml/2012/5/28/266). We agree the tables are not beautiful, so we didn't submit such stuff any more. Peter suggested that "the firmware should provide ACPI tables", but this is not possible for plug-in pci boards, or we should use devicetree (Peter's message: https://lkml.org/lkml/2012/5/29/38).

So we turned to devicetree, mostly because AMBA drivers usually already have devicetree support. Davide took over the effort, which turned out to be really big.

Some of the problems he found are:

* Passing a dtb to the kernel: we use a modified kexec at present because x86 boot loaders can't pass the DT blob, to our knowledge.

* Passing correct irq numbers to the AMBA drivers, because PCI MSI irq numbers are dynamically allocated (we solved this by using of_update_property() at runtime). We also had to register a new irq domain for msi irqs, otherwise of_irq_map_one() would complain about irqs lacking a corresponding domain.

* Switching to a new gpio driver with devicetree support (we took the Nomadik gpio/pinctrl because our device apparently has more or less the same gpio cell as the Nomadik chip). This requires implementation of writel_relaxed() and IRQF_VALID on x86: we hacked them internally but the patches are not part of this set. We're willing to solve these incompatibilities first, if there's interest.

* Writing a suitable dts: at present, a dts only exists for one of the STA2X11 based boards (Intel Northville). This includes a copy of all the physical addresses for the devices, as dts requires that, even if such addresses are automatically assigned by PCI. Clearly, with this approach we kill PCI autodetect: if you plug to a different slot you need a different dts.

This got us a more or less working kernel on the Northville board (where the device is soldered on the motherboard and acts as main chipset). The plug-in PCIe board cannot be supported by device tree, as far as we know, which in our opinion is a strong downside of device tree in favor of the platform data "shit".

Here's the list of amba devices after boot (we used a kernel with a common clock framework implementation for the Connext, patches to be (re)submitted shortly):

[root@localhost ~]# for d in ls /sys/bus/amba/devices/ ; \
do cat /sys/bus/amba/devices/$d/id ; done
00280080 # -> amba pl080
00380802 # -> amba pl011
00380802 # -> amba pl011
00380802 # -> amba pl011
00380802 # -> amba pl011
10480180 # -> amba mmci
10480180 # -> amba mmci
10480180 # -> amba mmci
10480180 # -> amba mmci
00080023 # -> amba pl023
00080023 # -> amba pl023
00080023 # -> amba pl023
00280080 # -> amba pl080

And the platform devices:

[root@localhost ~]# for d in ls /sys/bus/platform/devices/ ; \
do cat /sys/bus/platform/devices/$d/modalias ; done platform:alarmtimer
platform:apb-regs.3 # Connext apb-regs
platform:apb-soc-regs.3 # Connext apb-soc-regs
platform:gpio-0000:03:00.0-0 # Connext gpios 0..3
platform:gpio-0000:03:00.0-1 platform:gpio-0000:03:00.0-2 platform:gpio-0000:03:00.0-3
platform:microcode
platform:mmio-0000:05:00.5-0 # Connext esram memory
platform:pcspkr
platform:regulatory
platform:scr.3 # Connext scr (OTP)
platform:sctl.3 # Connext sysctl
platform:serial8250
platform:sta2x11-clock-regs # Connext virtual clock regs platform dev

But this awful pile of dts data will not work for he pluggable PCIe card. We need to regenerate the dts file at each and every boot, because PCI assignment may change according to what other cards are present.

So this devicetree stuff is killing all the autodetection of PCI, and is very difficult to pass over in the x86 world. On the other hand platform data is denied by x86 maintainers.

So the question is: what is the right way (and the right dts structure) to deal with a hotplug bus that instantiates AMBA devices, without killing del self-detection features?

Thanks
/alessandro

Alessandro Rubini (5):
x86: fix warning for sta2x11
DMA: PL330: use prefix in reg names to build under x86
mmc: Use the new <linux/sizes.h>
x86: add CONFIG_ARM_AMBA, selected by STA2X11 drivers/amba: add support for a PCI bridge

Davide Ciminaghi (21):
x86 STA2X11: select devicetree related config items.
OF platform: export of_amba_device_create()
OF platform, of_amba_device_create(): add parent resource to parameters. kernel irqdomain: export irq_domain_disassociate()
x86 devicetree: add irq domain for msi irqs
x86 devicetree: add functions for handling setup/teardown of MSI irqs x86 kernel apic: notify MSI irqdomain(s) on setup/teardown of MSI IRQs drivers/amba/pci-amba.c: use devicetree for amba device creation.
gpio: remove sta2x11-gpio
x86 STA2X11: remove the sta2x11-mfd driver.
x86 STA2X11 platform: add sta2x11_platform_init()
x86 STA2X11 platform: add sta2x11_instance_data helpers
x86 STA2X11 platform: add a common probe function for platform devices x86 STA2X11 platform: create sta2x11-clock-regs device
x86 STA2X11 platform: remove useless pr_info()'s
AMBA: pci-amba bridge: improve code readability
AMBA: pci-amba bridge: extend number of amba devs per pci device
AMBA: pci-amba bridge: export function creating pci-amba device names x86 STA2X11: add dts for Intel's Northville board drivers/clk: sta2x11 common clock framework implementation
pinctrl: add support for sta2x11 (via pinctrl-nomadik)

 .../devicetree/bindings/pinctrl/ste,nomadik.txt    |    2 +-
 .../devicetree/bindings/x86/interrupt.txt          |   14 +
 arch/x86/Kconfig                                   |   10 +
 arch/x86/include/asm/prom.h                        |    9 +
 arch/x86/include/asm/sta2x11.h                     |  358 ++++++++-
 arch/x86/kernel/apic/io_apic.c                     |    5 +
 arch/x86/kernel/devicetree.c                       |   60 ++
 arch/x86/pci/sta2x11-fixup.c                       |    9 +-
 arch/x86/platform/Makefile                         |    1 +
 arch/x86/platform/sta2x11/Makefile                 |    1 +
 arch/x86/platform/sta2x11/northville.dts           |  941 ++++++++++++++++++++
 arch/x86/platform/sta2x11/sta2x11.c                |  522 +++++++++++
 drivers/Kconfig                                    |    2 +
 drivers/amba/Kconfig                               |   10 +
 drivers/amba/Makefile                              |    1 +
 drivers/amba/pci-amba.c                            |  298 +++++++
 drivers/clk/Makefile                               |    1 +
 drivers/clk/sta2x11/Makefile                       |    1 +
 drivers/clk/sta2x11/clk-audio-pll.c                |  149 +++
 drivers/clk/sta2x11/clk-soc-pll.c                  |   95 ++
 drivers/clk/sta2x11/clk.c                          |  865 ++++++++++++++++++
 drivers/clk/sta2x11/clk.h                          |   88 ++
 drivers/dma/pl330.c                                |  107 ++--
 drivers/gpio/Kconfig                               |    8 -
 drivers/gpio/Makefile                              |    1 -
 drivers/gpio/gpio-sta2x11.c                        |  440 ---------
 drivers/mfd/Kconfig                                |    6 -
 drivers/mfd/Makefile                               |    1 -
 drivers/mfd/sta2x11-mfd.c                          |  680 --------------
 drivers/mmc/host/mmci.c                            |    2 +-
 drivers/mmc/host/msm_sdcc.c                        |    2 +-
 drivers/mmc/host/mvsdio.c                          |    2 +-
 drivers/mmc/host/pxamci.c                          |    3 +-
 drivers/of/platform.c                              |   24 +-
 drivers/pinctrl/Kconfig                            |    6 +-
 drivers/pinctrl/Makefile                           |    1 +
 drivers/pinctrl/pinctrl-nomadik-sta2x11.c          |  578 ++++++++++++
 drivers/pinctrl/pinctrl-nomadik.c                  |    7 +
 drivers/pinctrl/pinctrl-nomadik.h                  |   14 +
 include/linux/irqdomain.h                          |    3 +
 include/linux/mfd/sta2x11-mfd.h                    |  518 -----------
 include/linux/of_platform.h                        |    7 +-
 include/linux/pci-amba.h                           |   42 +
 kernel/irq/irqdomain.c                             |    3 +-
 44 files changed, 4167 insertions(+), 1730 deletions(-)
 create mode 100644 arch/x86/platform/sta2x11/Makefile
 create mode 100644 arch/x86/platform/sta2x11/northville.dts
 create mode 100644 arch/x86/platform/sta2x11/sta2x11.c
 create mode 100644 drivers/amba/Kconfig
 create mode 100644 drivers/amba/pci-amba.c
 create mode 100644 drivers/clk/sta2x11/Makefile
 create mode 100644 drivers/clk/sta2x11/clk-audio-pll.c
 create mode 100644 drivers/clk/sta2x11/clk-soc-pll.c
 create mode 100644 drivers/clk/sta2x11/clk.c
 create mode 100644 drivers/clk/sta2x11/clk.h
 delete mode 100644 drivers/gpio/gpio-sta2x11.c
 delete mode 100644 drivers/mfd/sta2x11-mfd.c
 create mode 100644 drivers/pinctrl/pinctrl-nomadik-sta2x11.c
 delete mode 100644 include/linux/mfd/sta2x11-mfd.h
 create mode 100644 include/linux/pci-amba.h
Signature · 1 line
1.7.7.2
#1 lore raw

PATCH 1/26 x86: fix warning for sta2x11

The .free fied of struct dma_map_ops features a prototype that is different from what lib/swiotlb.c offers. The new "attrs" argument in dma_ops.free is missing from the generic implementation.

This removes the build warning by providing a function that just calls swiotlb_free_coherent() without passing "attrs".

The real solution, in my opinion, would be adding "attrs" as argument to swiotlb_free_coherent() and remove this new empty function as well as the identical ones found in other 6 files within arch.

---
 arch/x86/pci/sta2x11-fixup.c |    9 ++++++++-
 1 files changed, 8 insertions(+), 1 deletions(-)
arch/x86/pci/sta2x11-fixup.c +8 -1
index 9d8a509..5c24ccb 100644
@@ -180,10 +180,17 @@ static void *sta2x11_swiotlb_alloc_coherent(struct device *dev,
 	return vaddr;
 }
 
+static void sta2x11_swiotlb_free_coherent(struct device *dev, size_t size,
+					  void *vaddr, dma_addr_t dma_addr,
+					  struct dma_attrs *attrs)
+{
+	swiotlb_free_coherent(dev, size, vaddr, dma_addr);
+}
+
 /* We have our own dma_ops: the same as swiotlb but from alloc (above) */
 static struct dma_map_ops sta2x11_dma_ops = {
 	.alloc = sta2x11_swiotlb_alloc_coherent,
-	.free = swiotlb_free_coherent,
+	.free = sta2x11_swiotlb_free_coherent,
 	.map_page = swiotlb_map_page,
 	.unmap_page = swiotlb_unmap_page,
 	.map_sg = swiotlb_map_sg_attrs,
Signature · 1 line
1.7.7.2
#2 lore raw

PATCH 6/26 x86 STA2X11: select devicetree related config items.

In reply to Alessandro Rubini

This patch selects some config items needed for adding device tree support to STA2X11 based machines. In particular:

* OF_DYNAMIC is needed to use of_detach_node() and avoid instantiating the same node twice.

* IRQ_DOMAIN is needed because irq_of_parse_and_map() needs irq_create_of_mapping(), which is part of the irqdomain stuff.

---
 arch/x86/Kconfig |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)
arch/x86/Kconfig +4 -0
index 490b001..0a779eb 100644
@@ -555,6 +555,10 @@ config STA2X11
 	select MFD_STA2X11
 	select ARCH_REQUIRE_GPIOLIB
 	select ARM_AMBA
+	select OF
+	select OF_EARLY_FLATTREE
+	select OF_DYNAMIC
+	select IRQ_DOMAIN
 	default n
 	---help---
 	  This adds support for boards based on the STA2X11 IO-Hub,
Signature · 1 line
1.7.7.2
#3 lore raw

PATCH 7/26 OF platform: export of_amba_device_create()

In reply to Alessandro Rubini

This is needed because the pci-amba bus will create one or more amba devices for each probed pci device. We cannot create all the devices belonging to the same amba bus with just one call to of_platform_populate()

---
 drivers/of/platform.c       |   17 +++++++++--------
 include/linux/of_platform.h |    6 +++++-
 2 files changed, 14 insertions(+), 9 deletions(-)
drivers/of/platform.c +9 -8
index b0d1ff8..57c6bbe 100644
@@ -249,10 +249,10 @@ struct platform_device *of_platform_device_create(struct device_node *np,
 EXPORT_SYMBOL(of_platform_device_create);
 
 #ifdef CONFIG_ARM_AMBA
-static struct amba_device *of_amba_device_create(struct device_node *node,
-						 const char *bus_id,
-						 void *platform_data,
-						 struct device *parent)
+struct amba_device *of_amba_device_create(struct device_node *node,
+					  const char *bus_id,
+					  void *platform_data,
+					  struct device *parent)
 {
 	struct amba_device *dev;
 	const void *prop;
@@ -304,14 +304,15 @@ err_free:
 	return NULL;
 }
 #else /* CONFIG_ARM_AMBA */
-static struct amba_device *of_amba_device_create(struct device_node *node,
-						 const char *bus_id,
-						 void *platform_data,
-						 struct device *parent)
+struct amba_device *of_amba_device_create(struct device_node *node,
+					  const char *bus_id,
+					  void *platform_data,
+					  struct device *parent)
 {
 	return NULL;
 }
 #endif /* CONFIG_ARM_AMBA */
+EXPORT_SYMBOL(of_amba_device_create);
 
 /**
  * of_devname_lookup() - Given a device node, lookup the preferred Linux name
include/linux/of_platform.h +5 -1
index 05cb4a9..6cd5ac2 100644
@@ -59,10 +59,14 @@ extern struct platform_device *of_device_alloc(struct device_node *np,
 					 struct device *parent);
 extern struct platform_device *of_find_device_by_node(struct device_node *np);
 
-/* Platform devices and busses creation */
+/* Platform and amba devices and busses creation */
 extern struct platform_device *of_platform_device_create(struct device_node *np,
 						   const char *bus_id,
 						   struct device *parent);
+extern struct amba_device *of_amba_device_create(struct device_node *node,
+						 const char *bus_id,
+						 void *platform_data,
+						 struct device *parent);
 
 extern int of_platform_bus_probe(struct device_node *root,
 				 const struct of_device_id *matches,
Signature · 1 line
1.7.7.2
#4 lore raw

PATCH 8/26 OF platform, of_amba_device_create(): add parent resource to parameters.

In reply to Alessandro Rubini

This is needed when creating pci-amba devices: an amba device's resource shall be child of the corresponding pci device's resource.

---
 drivers/of/platform.c       |   11 +++++++----
 include/linux/of_platform.h |    3 ++-
 2 files changed, 9 insertions(+), 5 deletions(-)
drivers/of/platform.c +7 -4
index 57c6bbe..bf75aaa 100644
@@ -252,7 +252,8 @@ EXPORT_SYMBOL(of_platform_device_create);
 struct amba_device *of_amba_device_create(struct device_node *node,
 					  const char *bus_id,
 					  void *platform_data,
-					  struct device *parent)
+					  struct device *parent,
+					  struct resource *parent_resource)
 {
 	struct amba_device *dev;
 	const void *prop;
@@ -293,7 +294,7 @@ struct amba_device *of_amba_device_create(struct device_node *node,
 	if (ret)
 		goto err_free;
 
-	ret = amba_device_add(dev, &iomem_resource);
+	ret = amba_device_add(dev, parent_resource);
 	if (ret)
 		goto err_free;
 
@@ -307,7 +308,8 @@ err_free:
 struct amba_device *of_amba_device_create(struct device_node *node,
 					  const char *bus_id,
 					  void *platform_data,
-					  struct device *parent)
+					  struct device *parent,
+					  struct resource *parent_resource)
 {
 	return NULL;
 }
@@ -375,7 +377,8 @@ static int of_platform_bus_create(struct device_node *bus,
 	}
 
 	if (of_device_is_compatible(bus, "arm,primecell")) {
-		of_amba_device_create(bus, bus_id, platform_data, parent);
+		of_amba_device_create(bus, bus_id, platform_data, parent,
+				      &iomem_resource);
 		return 0;
 	}
 
include/linux/of_platform.h +2 -1
index 6cd5ac2..be13538 100644
@@ -66,7 +66,8 @@ extern struct platform_device *of_platform_device_create(struct device_node *np,
 extern struct amba_device *of_amba_device_create(struct device_node *node,
 						 const char *bus_id,
 						 void *platform_data,
-						 struct device *parent);
+						 struct device *parent,
+						 struct resource *parent_res);
 
 extern int of_platform_bus_probe(struct device_node *root,
 				 const struct of_device_id *matches,
Signature · 1 line
1.7.7.2
#5 lore raw

PATCH 9/26 kernel irqdomain: export irq_domain_disassociate()

In reply to Alessandro Rubini

irq_create_of_mapping() requires an irqdomain to be registered for each interrupt controller node.
While extending devicetree usage on x86 to devices with MSI irqs, [at least] an msi interrupt controller node had to be added together with the relevant irqdomain.
Registering a nomap irqdomain for each msi controller and adding irqs to such domain in native_setup_msi_irqs() via irq_domain_associate() looked like the simplest and safest solution to the problem, but then of course irq_domain_disassociate() must be called by native_teardown_msi_irq().

---
 include/linux/irqdomain.h |    3 +++
 kernel/irq/irqdomain.c    |    3 ++-
 2 files changed, 5 insertions(+), 1 deletions(-)
include/linux/irqdomain.h +3 -0
index c983ed1..b7f0df4 100644
@@ -172,6 +172,9 @@ extern int irq_domain_associate(struct irq_domain *domain, unsigned int irq,
 extern void irq_domain_associate_many(struct irq_domain *domain,
 				      unsigned int irq_base,
 				      irq_hw_number_t hwirq_base, int count);
+extern void irq_domain_disassociate(struct irq_domain *domain,
+				    unsigned int irq);
+
 
 extern unsigned int irq_create_mapping(struct irq_domain *host,
 				       irq_hw_number_t hwirq);
kernel/irq/irqdomain.c +2 -1
index 706724e..a33e29c 100644
@@ -230,7 +230,7 @@ void irq_set_default_host(struct irq_domain *domain)
 }
 EXPORT_SYMBOL_GPL(irq_set_default_host);
 
-static void irq_domain_disassociate(struct irq_domain *domain, unsigned int irq)
+void irq_domain_disassociate(struct irq_domain *domain, unsigned int irq)
 {
 	struct irq_data *irq_data = irq_get_irq_data(irq);
 	irq_hw_number_t hwirq;
@@ -265,6 +265,7 @@ static void irq_domain_disassociate(struct irq_domain *domain, unsigned int irq)
 		mutex_unlock(&revmap_trees_mutex);
 	}
 }
+EXPORT_SYMBOL(irq_domain_disassociate);
 
 int irq_domain_associate(struct irq_domain *domain, unsigned int virq,
 			 irq_hw_number_t hwirq)
Signature · 1 line
1.7.7.2
#6 lore raw

PATCH 2/26 DMA: PL330: use prefix in reg names to build under x86

In reply to Alessandro Rubini

This driver would not compile if ARM_AMBA is selected under x86, because "CS" and "DS" are already defined there. But AMBA is used in the x86 world by a PCI-to-AMBA bridge, to be submitted.

The patch just adds the "PL330_" prefix to all registers, so it can be built by randomconfig after ARM_AMBA appears within x86. No other technical changes have been performed.
The patch was build-tested only.

Conflicts:

	drivers/dma/pl330.c
---
 drivers/dma/pl330.c |  107 ++++++++++++++++++++++++++-------------------------
 1 files changed, 54 insertions(+), 53 deletions(-)
drivers/dma/pl330.c +54 -53
index 4ad13eb..da67bee 100644
@@ -71,7 +71,7 @@ enum pl330_reqtype {
 };
 
 /* Register and Bit field Definitions */
-#define DS			0x0
+#define PL330_DS		0x0
 #define DS_ST_STOP		0x0
 #define DS_ST_EXEC		0x1
 #define DS_ST_CMISS		0x2
@@ -85,33 +85,33 @@ enum pl330_reqtype {
 #define DS_ST_FLTCMP		0xe
 #define DS_ST_FAULT		0xf
 
-#define DPC			0x4
-#define INTEN			0x20
-#define ES			0x24
-#define INTSTATUS		0x28
-#define INTCLR			0x2c
-#define FSM			0x30
-#define FSC			0x34
-#define FTM			0x38
+#define PL330_DPC		0x4
+#define PL330_INTEN		0x20
+#define PL330_ES		0x24
+#define PL330_INTSTATUS		0x28
+#define PL330_INTCLR		0x2c
+#define PL330_FSM		0x30
+#define PL330_FSC		0x34
+#define PL330_FTM		0x38
 
 #define _FTC			0x40
-#define FTC(n)			(_FTC + (n)*0x4)
+#define PL330_FTC(n)		(_FTC + (n)*0x4)
 
 #define _CS			0x100
-#define CS(n)			(_CS + (n)*0x8)
+#define PL330_CS(n)		(_CS + (n)*0x8)
 #define CS_CNS			(1 << 21)
 
 #define _CPC			0x104
-#define CPC(n)			(_CPC + (n)*0x8)
+#define PL330_CPC(n)		(_CPC + (n)*0x8)
 
 #define _SA			0x400
-#define SA(n)			(_SA + (n)*0x20)
+#define PL330_SA(n)		(_SA + (n)*0x20)
 
 #define _DA			0x404
-#define DA(n)			(_DA + (n)*0x20)
+#define PL330_DA(n)		(_DA + (n)*0x20)
 
 #define _CC			0x408
-#define CC(n)			(_CC + (n)*0x20)
+#define PL330_CC(n)		(_CC + (n)*0x20)
 
 #define CC_SRCINC		(1 << 0)
 #define CC_DSTINC		(1 << 14)
@@ -132,24 +132,24 @@ enum pl330_reqtype {
 #define CC_SWAP_SHFT		28
 
 #define _LC0			0x40c
-#define LC0(n)			(_LC0 + (n)*0x20)
+#define PL330_LC0(n)		(_LC0 + (n)*0x20)
 
 #define _LC1			0x410
-#define LC1(n)			(_LC1 + (n)*0x20)
+#define PL330_LC1(n)		(_LC1 + (n)*0x20)
 
-#define DBGSTATUS		0xd00
+#define PL330_DBGSTATUS		0xd00
 #define DBG_BUSY		(1 << 0)
 
-#define DBGCMD			0xd04
-#define DBGINST0		0xd08
-#define DBGINST1		0xd0c
+#define PL330_DBGCMD		0xd04
+#define PL330_DBGINST0		0xd08
+#define PL330_DBGINST1		0xd0c
 
-#define CR0			0xe00
-#define CR1			0xe04
-#define CR2			0xe08
-#define CR3			0xe0c
-#define CR4			0xe10
-#define CRD			0xe14
+#define PL330_CR0		0xe00
+#define PL330_CR1		0xe04
+#define PL330_CR2		0xe08
+#define PL330_CR3		0xe0c
+#define PL330_CR4		0xe10
+#define PL330_CRD		0xe14
 
 #define PERIPH_ID		0xfe0
 #define PERIPH_REV_SHIFT	20
@@ -1006,7 +1006,7 @@ static bool _until_dmac_idle(struct pl330_thread *thrd)
 
 	do {
 		/* Until Manager is Idle */
-		if (!(readl(regs + DBGSTATUS) & DBG_BUSY))
+		if (!(readl(regs + PL330_DBGSTATUS) & DBG_BUSY))
 			break;
 
 		cpu_relax();
@@ -1029,10 +1029,10 @@ static inline void _execute_DBGINSN(struct pl330_thread *thrd,
 		val |= (1 << 0);
 		val |= (thrd->id << 8); /* Channel Number */
 	}
-	writel(val, regs + DBGINST0);
+	writel(val, regs + PL330_DBGINST0);
 
 	val = *((u32 *)&insn[2]);
-	writel(val, regs + DBGINST1);
+	writel(val, regs + PL330_DBGINST1);
 
 	/* If timed out due to halted state-machine */
 	if (_until_dmac_idle(thrd)) {
@@ -1041,7 +1041,7 @@ static inline void _execute_DBGINSN(struct pl330_thread *thrd,
 	}
 
 	/* Get going */
-	writel(0, regs + DBGCMD);
+	writel(0, regs + PL330_DBGCMD);
 }
 
 /*
@@ -1066,9 +1066,9 @@ static inline u32 _state(struct pl330_thread *thrd)
 	u32 val;
 
 	if (is_manager(thrd))
-		val = readl(regs + DS) & 0xf;
+		val = readl(regs + PL330_DS) & 0xf;
 	else
-		val = readl(regs + CS(thrd->id)) & 0xf;
+		val = readl(regs + PL330_CS(thrd->id)) & 0xf;
 
 	switch (val) {
 	case DS_ST_STOP:
@@ -1135,7 +1135,8 @@ static void _stop(struct pl330_thread *thrd)
 	_emit_KILL(0, insn);
 
 	/* Stop generating interrupts for SEV */
-	writel(readl(regs + INTEN) & ~(1 << thrd->ev), regs + INTEN);
+	writel(readl(regs + PL330_INTEN) & ~(1 << thrd->ev),
+	       regs + PL330_INTEN);
 
 	_execute_DBGINSN(thrd, insn, is_manager(thrd));
 }
@@ -1174,7 +1175,7 @@ static bool _trigger(struct pl330_thread *thrd)
 
 	if (r->cfg)
 		ns = r->cfg->nonsecure ? 1 : 0;
-	else if (readl(regs + CS(thrd->id)) & CS_CNS)
+	else if (readl(regs + PL330_CS(thrd->id)) & CS_CNS)
 		ns = 1;
 	else
 		ns = 0;
@@ -1190,7 +1191,7 @@ static bool _trigger(struct pl330_thread *thrd)
 	_emit_GO(0, insn, &go);
 
 	/* Set to generate interrupts for SEV */
-	writel(readl(regs + INTEN) | (1 << thrd->ev), regs + INTEN);
+	writel(readl(regs + PL330_INTEN) | (1 << thrd->ev), regs + PL330_INTEN);
 
 	/* Only manager can execute GO */
 	_execute_DBGINSN(thrd, insn, true);
@@ -1565,7 +1566,7 @@ static int pl330_submit_req(void *ch_id, struct pl330_req *r)
 
 		ccr = _prepare_ccr(r->cfg);
 	} else {
-		ccr = readl(regs + CC(thrd->id));
+		ccr = readl(regs + PL330_CC(thrd->id));
 	}
 
 	/* If this req doesn't have valid xfer settings */
@@ -1642,7 +1643,7 @@ static void pl330_dotask(unsigned long data)
 
 			_stop(thrd);
 
-			if (readl(regs + FSC) & (1 << thrd->id))
+			if (readl(regs + PL330_FSC) & (1 << thrd->id))
 				err = PL330_ERR_FAIL;
 			else
 				err = PL330_ERR_ABORT;
@@ -1687,13 +1688,13 @@ static int pl330_update(const struct pl330_info *pi)
 
 	spin_lock_irqsave(&pl330->lock, flags);
 
-	val = readl(regs + FSM) & 0x1;
+	val = readl(regs + PL330_FSM) & 0x1;
 	if (val)
 		pl330->dmac_tbd.reset_mngr = true;
 	else
 		pl330->dmac_tbd.reset_mngr = false;
 
-	val = readl(regs + FSC) & ((1 << pi->pcfg.num_chan) - 1);
+	val = readl(regs + PL330_FSC) & ((1 << pi->pcfg.num_chan) - 1);
 	pl330->dmac_tbd.reset_chan |= val;
 	if (val) {
 		int i = 0;
@@ -1701,8 +1702,8 @@ static int pl330_update(const struct pl330_info *pi)
 			if (val & (1 << i)) {
 				dev_info(pi->dev,
 					"Reset Channel-%d\t CS-%x FTC-%x\n",
-						i, readl(regs + CS(i)),
-						readl(regs + FTC(i)));
+						i, readl(regs + PL330_CS(i)),
+						readl(regs + PL330_FTC(i)));
 				_stop(&pl330->channels[i]);
 			}
 			i++;
@@ -1710,7 +1711,7 @@ static int pl330_update(const struct pl330_info *pi)
 	}
 
 	/* Check which event happened i.e, thread notified */
-	val = readl(regs + ES);
+	val = readl(regs + PL330_ES);
 	if (pi->pcfg.num_events < 32
 			&& val & ~((1 << pi->pcfg.num_events) - 1)) {
 		pl330->dmac_tbd.reset_dmac = true;
@@ -1722,12 +1723,12 @@ static int pl330_update(const struct pl330_info *pi)
 	for (ev = 0; ev < pi->pcfg.num_events; ev++) {
 		if (val & (1 << ev)) { /* Event occurred */
 			struct pl330_thread *thrd;
-			u32 inten = readl(regs + INTEN);
+			u32 inten = readl(regs + PL330_INTEN);
 			int active;
 
 			/* Clear the event */
 			if (inten & (1 << ev))
-				writel(1 << ev, regs + INTCLR);
+				writel(1 << ev, regs + PL330_INTCLR);
 
 			ret = 1;
 
@@ -1934,41 +1935,41 @@ static void read_dmac_config(struct pl330_info *pi)
 	void __iomem *regs = pi->base;
 	u32 val;
 
-	val = readl(regs + CRD) >> CRD_DATA_WIDTH_SHIFT;
+	val = readl(regs + PL330_CRD) >> CRD_DATA_WIDTH_SHIFT;
 	val &= CRD_DATA_WIDTH_MASK;
 	pi->pcfg.data_bus_width = 8 * (1 << val);
 
-	val = readl(regs + CRD) >> CRD_DATA_BUFF_SHIFT;
+	val = readl(regs + PL330_CRD) >> CRD_DATA_BUFF_SHIFT;
 	val &= CRD_DATA_BUFF_MASK;
 	pi->pcfg.data_buf_dep = val + 1;
 
-	val = readl(regs + CR0) >> CR0_NUM_CHANS_SHIFT;
+	val = readl(regs + PL330_CR0) >> CR0_NUM_CHANS_SHIFT;
 	val &= CR0_NUM_CHANS_MASK;
 	val += 1;
 	pi->pcfg.num_chan = val;
 
-	val = readl(regs + CR0);
+	val = readl(regs + PL330_CR0);
 	if (val & CR0_PERIPH_REQ_SET) {
 		val = (val >> CR0_NUM_PERIPH_SHIFT) & CR0_NUM_PERIPH_MASK;
 		val += 1;
 		pi->pcfg.num_peri = val;
-		pi->pcfg.peri_ns = readl(regs + CR4);
+		pi->pcfg.peri_ns = readl(regs + PL330_CR4);
 	} else {
 		pi->pcfg.num_peri = 0;
 	}
 
-	val = readl(regs + CR0);
+	val = readl(regs + PL330_CR0);
 	if (val & CR0_BOOT_MAN_NS)
 		pi->pcfg.mode |= DMAC_MODE_NS;
 	else
 		pi->pcfg.mode &= ~DMAC_MODE_NS;
 
-	val = readl(regs + CR0) >> CR0_NUM_EVENTS_SHIFT;
+	val = readl(regs + PL330_CR0) >> CR0_NUM_EVENTS_SHIFT;
 	val &= CR0_NUM_EVENTS_MASK;
 	val += 1;
 	pi->pcfg.num_events = val;
 
-	pi->pcfg.irq_ns = readl(regs + CR3);
+	pi->pcfg.irq_ns = readl(regs + PL330_CR3);
 }
 
 static inline void _reset_thread(struct pl330_thread *thrd)
Signature · 1 line
1.7.7.2
#7 lore raw

PATCH 3/26 mmc: Use the new <linux/sizes.h>

In reply to Alessandro Rubini

For portability, use <linux/sizes.h>.

---
 drivers/mmc/host/mmci.c     |    2 +-
 drivers/mmc/host/msm_sdcc.c |    2 +-
 drivers/mmc/host/mvsdio.c   |    2 +-
 drivers/mmc/host/pxamci.c   |    3 +--
 4 files changed, 4 insertions(+), 5 deletions(-)
drivers/mmc/host/mmci.c +1 -1
index c3785ed..edd987e 100644
@@ -34,11 +34,11 @@
 #include <linux/amba/mmci.h>
 #include <linux/pm_runtime.h>
 #include <linux/types.h>
+#include <linux/sizes.h>
 #include <linux/pinctrl/consumer.h>
 
 #include <asm/div64.h>
 #include <asm/io.h>
-#include <asm/sizes.h>
 
 #include "mmci.h"
 
drivers/mmc/host/msm_sdcc.c +1 -1
index b900de4..405f0d8 100644
@@ -37,10 +37,10 @@
 #include <linux/memory.h>
 #include <linux/gfp.h>
 #include <linux/gpio.h>
+#include <linux/sizes.h>
 
 #include <asm/cacheflush.h>
 #include <asm/div64.h>
-#include <asm/sizes.h>
 
 #include <linux/platform_data/mmc-msm_sdcc.h>
 #include <mach/dma.h>
drivers/mmc/host/mvsdio.c +1 -1
index 4ddd83f..4dec50f 100644
@@ -23,11 +23,11 @@
 #include <linux/gpio.h>
 #include <linux/of_gpio.h>
 #include <linux/of_irq.h>
+#include <linux/sizes.h>
 #include <linux/mmc/host.h>
 #include <linux/mmc/slot-gpio.h>
 #include <linux/pinctrl/consumer.h>
 
-#include <asm/sizes.h>
 #include <asm/unaligned.h>
 #include <linux/platform_data/mmc-mvsdio.h>
 
drivers/mmc/host/pxamci.c +1 -2
index 1956a3d..3924f36 100644
@@ -33,8 +33,7 @@
 #include <linux/of.h>
 #include <linux/of_gpio.h>
 #include <linux/of_device.h>
-
-#include <asm/sizes.h>
+#include <linux/sizes.h>
 
 #include <mach/hardware.h>
 #include <mach/dma.h>
Signature · 1 line
1.7.7.2
#8 lore raw

PATCH 4/26 x86: add CONFIG_ARM_AMBA, selected by STA2X11

In reply to Alessandro Rubini

The sta2x11 I/O Hub is a bridge from PCIe to AMBA. It reuses a number of amba drivers and needs to activate core bus support.

---
 arch/x86/Kconfig |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)
arch/x86/Kconfig +4 -0
index 52432ab..490b001 100644
@@ -554,6 +554,7 @@ config STA2X11
 	select SWIOTLB
 	select MFD_STA2X11
 	select ARCH_REQUIRE_GPIOLIB
+	select ARM_AMBA
 	default n
 	---help---
 	  This adds support for boards based on the STA2X11 IO-Hub,
@@ -2255,6 +2256,9 @@ config TS5500
 
 endif # X86_32
 
+config ARM_AMBA
+        bool
+
 config AMD_NB
 	def_bool y
 	depends on CPU_SUP_AMD && PCI
Signature · 1 line
1.7.7.2
#9 lore raw

PATCH 5/26 drivers/amba: add support for a PCI bridge

In reply to Alessandro Rubini

This is a PCI driver that registers AMBA devices for the range of supported devices. It is currently used by STA2X11, which exports AMBA peripherals under PCIe. The original AMBA drivers work with no changes or minimal ones.

---
 drivers/Kconfig         |    2 +
 drivers/amba/Kconfig    |   10 +++++
 drivers/amba/Makefile   |    1 +
 drivers/amba/pci-amba.c |   93 +++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 106 insertions(+), 0 deletions(-)
 create mode 100644 drivers/amba/Kconfig
 create mode 100644 drivers/amba/pci-amba.c
drivers/Kconfig +2 -0
index aa43b91..5603bc3 100644
@@ -166,4 +166,6 @@ source "drivers/reset/Kconfig"
 
 source "drivers/fmc/Kconfig"
 
+source "drivers/amba/Kconfig"
+
 endmenu
drivers/amba/Kconfig new file +10 -0
new file mode 100644
index 0000000..b5b5aca
@@ -0,0 +1,10 @@
+
+config PCI_AMBA
+	tristate "PCI-to-AMBA bridge"
+	depends on ARM_AMBA && PCI
+	---help---
+	  This compiles a PCI driver that registers AMBA devices, so
+	  the respective AMBA driver can be used unchanged if you have
+	  a PCI to amba bridge. This is required for STA2X11 support.
+
+	  If uncertain, choose N.
drivers/amba/Makefile +1 -0
index 66e81c2..d30e947 100644
@@ -1,2 +1,3 @@
 obj-$(CONFIG_ARM_AMBA)		+= bus.o
+obj-$(CONFIG_PCI_AMBA)		+= pci-amba.o
 obj-$(CONFIG_TEGRA_AHB)		+= tegra-ahb.o
drivers/amba/pci-amba.c new file +93 -0

93 lines not on this page · raw message

Signature · 1 line
1.7.7.2
#10 lore raw

PATCH 10/26 x86 devicetree: add irq domain for msi irqs

In reply to Alessandro Rubini

An irqdomain is created for each MSI interrupt controller found in the tree. This is to make irq_create_of_mapping() happy later on.

---
 .../devicetree/bindings/x86/interrupt.txt          |   14 ++++++++++++++
 arch/x86/kernel/devicetree.c                       |   12 ++++++++++++
 2 files changed, 26 insertions(+), 0 deletions(-)
Documentation/devicetree/bindings/x86/interrupt.txt +14 -0
index 7d19f49..fa6e2f0 100644
@@ -24,3 +24,17 @@ Interrupt chips
   Required property:
 
      compatible = "intel,ce4100-lapic";
+
+* MSI interrupts (STA2X11)
+
+  Required properties:
+  -------------------
+     compatible = "intel,msi-irqs";
+     #interrupt-cells = <1>;
+
+  Device's interrupt property:
+
+     interrupts = <I>;
+
+  I is the MSI irq number. Should be left equal to zero in the devicetree
+  and updated at runtime, after the irq number has been allocated.
arch/x86/kernel/devicetree.c +12 -0
index 376dc78..d1dcfd0 100644
@@ -401,6 +401,16 @@ static void __init ioapic_add_ofnode(struct device_node *np)
 	printk(KERN_ERR "IOxAPIC at %s is not registered.\n", np->full_name);
 }
 
+static const struct irq_domain_ops msi_irq_domain_ops = {
+	.xlate = irq_domain_xlate_onecell,
+};
+
+static void __init add_msi_irq_domain(struct device_node *np)
+{
+	if (!irq_domain_add_nomap(np, nr_irqs, &msi_irq_domain_ops, NULL))
+		pr_err("%s: error creating msi domain\n", __func__);
+}
+
 void __init x86_add_irq_domains(void)
 {
 	struct device_node *dp;
@@ -411,6 +421,8 @@ void __init x86_add_irq_domains(void)
 	for_each_node_with_property(dp, "interrupt-controller") {
 		if (of_device_is_compatible(dp, "intel,ce4100-ioapic"))
 			ioapic_add_ofnode(dp);
+		if (of_device_is_compatible(dp, "intel,msi-irqs"))
+			add_msi_irq_domain(dp);
 	}
 }
 #else
Signature · 1 line
1.7.7.2
#11 lore raw

PATCH 11/26 x86 devicetree: add functions for handling setup/teardown of MSI irqs

In reply to Alessandro Rubini

This patch introduces x86_of_new_msi_irq() and x86_of_del_msi_irq(), which shall be invoked by native_setup_msi_irqs() and native_teardown_msi_irq() respectively to add/delete irq numbers to/from the "dummy" msi irqdomain.

---
 arch/x86/include/asm/prom.h  |    9 +++++++
 arch/x86/kernel/devicetree.c |   48 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 57 insertions(+), 0 deletions(-)
arch/x86/include/asm/prom.h +9 -0
index bade6ac..902b361 100644
@@ -27,11 +27,20 @@ extern int of_ioapic;
 extern u64 initial_dtb;
 extern void add_dtb(u64 data);
 extern void x86_add_irq_domains(void);
+extern int x86_of_new_msi_irq(struct pci_dev *pdev, unsigned int irq);
+extern void x86_of_del_msi_irq(unsigned int irq);
 void x86_of_pci_init(void);
 void x86_dtb_init(void);
 #else
 static inline void add_dtb(u64 data) { }
 static inline void x86_add_irq_domains(void) { }
+
+static inline int x86_of_new_msi_irq(struct pci_dev *pdev, unsigned int irq)
+{
+	return 0;
+}
+
+static inline void x86_of_del_msi_irq(unsigned int irq) { }
 static inline void x86_of_pci_init(void) { }
 static inline void x86_dtb_init(void) { }
 #define of_ioapic 0
arch/x86/kernel/devicetree.c +48 -0

54 lines not on this page · raw message

Signature · 1 line
1.7.7.2
#12 lore raw

PATCH 12/26 x86 kernel apic: notify MSI irqdomain(s) on etup/teardown of MSI IRQs

In reply to Alessandro Rubini

This patch should have no effect on non-OF x86 machines.

When CONFIG_OF is enabled, an irqdomain exists for each MSI controller in the devicetree. This patch invokes the functions taking care of adding/removing IRQs numbers to/from the MSI irqdomain they belong to.

---
 arch/x86/kernel/apic/io_apic.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)
arch/x86/kernel/apic/io_apic.c +5 -0
index 9ed796c..65db413 100644
@@ -60,6 +60,7 @@
 #include <asm/irq_remapping.h>
 #include <asm/hpet.h>
 #include <asm/hw_irq.h>
+#include <asm/prom.h>
 
 #include <asm/apic.h>
 
@@ -3154,6 +3155,9 @@ int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
 		ret = setup_msi_irq(dev, msidesc, irq, 0);
 		if (ret < 0)
 			goto error;
+		ret = x86_of_new_msi_irq(dev, irq);
+		if (ret < 0)
+			goto error;
 	}
 	return 0;
 
@@ -3164,6 +3168,7 @@ error:
 
 void native_teardown_msi_irq(unsigned int irq)
 {
+	x86_of_del_msi_irq(irq);
 	destroy_irq(irq);
 }
 
Signature · 1 line
1.7.7.2
#13 lore raw

PATCH 13/26 drivers/amba/pci-amba.c: use devicetree for amba device creation.

In reply to Alessandro Rubini

The following scheme applies for each pci-amba device within the devicetree:

	* sta2x11 pci express port (pci id = 0xcc17)
	  |
	  |
	  * pci-amba bridge node (pci id = 0xcc18)
	    |
	    +-------+
	    |	    |
	    |	    * amba-bus node (ranges, interrupt-map)
	    |	      |
	    |	      ...
	    ...	      |
	    |	      * amba side of pci-amba device
	    |
	    |
	    * pci side of pci-amba device

As far as the sta2x11 is concerned, there are 4 pci-amba bridge nodes (one for each pci express endpoint).
A pci-amba bridge node contains an amba bus and all the pci side parts of the pci-amba devices attached to the same pci express endpoint. Finally, each child node of the amba bus represents the amba side of a pci-amba device.

---
 drivers/amba/pci-amba.c |  126 ++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 109 insertions(+), 17 deletions(-)
drivers/amba/pci-amba.c +109 -17
index 8ce526a..e56717b 100644
@@ -12,42 +12,134 @@
 #include <linux/slab.h>
 #include <linux/irq.h>
 #include <linux/sizes.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+
+/*
+  Length of an interrupt map row:
+  Child unit address (amba node, length is 1) +
+  Child interrupt specifier (amba node, length is 1) +
+  Interrupt parent (phandle, length is 1) +
+  Parent unit address (parent is msi controller, length is 1)
+  Parent interrupt specifier (parent is msi controller, length is 1)
+*/
+#define IMAP_ROW_LEN (1 + 1 + 1 + 1 + 1)
 
 static int pci_amba_probe(struct pci_dev *pdev,
 			  const struct pci_device_id *id)
 {
 	struct amba_device *adev;
+	int i, ret, len;
+	struct device_node *n, *node, *pci_amba_bridge, *amba_bus = NULL,
+		*amba_node = NULL;
+	const void *p;
 	char *name;
-	int ret;
+	struct property *newimap;
+	u32 *newv, *ptr;
+	const u32 *reg;
+	int found;
 
 	pci_enable_msi(pdev);
 	ret = pci_enable_device(pdev);
 	if (ret)
 		return ret;
 
-	/* Create a name: each of them must be different */
+	/* This bridge can host both APB and AHB devices, so set master */
+	pci_set_master(pdev);
+
+	node = pdev->dev.of_node;
+	if (!node)
+		return -EINVAL;
+
+	/* Get a reference to the pci amba bridge (our pci parent) */
+	pci_amba_bridge = of_get_parent(node);
+	if (!pci_amba_bridge)
+		return -EINVAL;
+	if (of_node_cmp(pci_amba_bridge->type, "pci"))
+		return -EINVAL;
+
+	/* Look for the relevant amba bus node */
+	for_each_child_of_node(pci_amba_bridge, n) {
+		if (of_device_is_compatible(n, "arm,amba-bus")) {
+			amba_bus = n;
+			break;
+		}
+	}
+	of_node_put(pci_amba_bridge);
+	if (!amba_bus)
+		return -ENODEV;
+
+	/*
+	   Now find out what the relevant amba device is by looking for
+	   a resource with the same initial address of this pci device's BAR0
+	*/
+	for_each_child_of_node(amba_bus, n) {
+		struct resource r;
+		if (of_address_to_resource(n, 0, &r))
+			continue;
+		if (r.start == pdev->resource[0].start) {
+			amba_node = n;
+			break;
+		}
+	}
+	if (!amba_node)
+		return -ENODEV;
+
+	/* Create a unique name for the device */
 	name = devm_kzalloc(&pdev->dev, strlen(dev_name(&pdev->dev)) + 6,
-		GFP_KERNEL);
+			    GFP_KERNEL);
 	sprintf(name, "amba-%s", dev_name(&pdev->dev));
 
-	/* Simply build an amba device and register it */
-	adev = amba_device_alloc(name,  pdev->resource[0].start, SZ_4K);
-	if (!adev)
-		return -ENOMEM;
-	adev->irq[0] = pdev->irq;
+	/*
+	  Since we're dealing with MSI IRQs, the value of a device's IRQ
+	  number is known at runtime only. Update the amba bus interrupt
+	  map to fix things up.
+	*/
+	if (of_get_property(amba_node, "interrupts", NULL)) {
+		p = of_get_property(amba_bus, "interrupt-map", &len);
+		if (!p)
+			/* No amba bus interrupt-map property */
+			return -EINVAL;
 
-	/* This bridge can host both APB and AHB devices, so set master */
-	pci_set_master(pdev);
-	if (pdev->vendor == PCI_VENDOR_ID_STMICRO) {
-		/* Under sta2x11, DMA is there but limited to 512M */
-		adev->dma_mask = SZ_512M - 1;
-		adev->dev.coherent_dma_mask = SZ_512M - 1;
+		newimap = devm_kzalloc(&pdev->dev, sizeof(*newimap),
+				       GFP_KERNEL);
+		if (!newimap)
+			return -ENOMEM;
+
+		newimap->name = kstrdup("interrupt-map", GFP_KERNEL);
+		if (!newimap->name)
+			return -ENOMEM;
+
+		newv = devm_kzalloc(&pdev->dev, len, GFP_KERNEL);
+		if (!newv) {
+			kfree(newimap->name);
+			return -ENOMEM;
+		}
+
+		newimap->value = newv;
+		newimap->length = len;
+		memcpy(newv, p, len);
+		for (ptr = newv, i = 0, found = 0;
+		     i < len/sizeof(u32);
+		     ptr += IMAP_ROW_LEN, i += IMAP_ROW_LEN) {
+			reg = of_get_property(amba_node, "reg", NULL);
+			if (ptr[0] == reg[0]) {
+				ptr[IMAP_ROW_LEN - 1] = cpu_to_be32(pdev->irq);
+				found = 1;
+				break;
+			}
+		}
+		if (!found) {
+			pr_err("Could not update amba irq\n");
+			return -EINVAL;
+		}
+		of_update_property(amba_bus, newimap);
 	}
 
-	adev->dev.platform_data = pdev->dev.platform_data;
+	/* And finally create the amba device */
+	adev = of_amba_device_create(n, name, NULL, NULL, &pdev->resource[0]);
 	pci_set_drvdata(pdev, adev);
-
-	return amba_device_add(adev, &pdev->resource[0]);
+	return 0;
 };
 
 static void pci_amba_remove(struct pci_dev *pdev)
Signature · 1 line
1.7.7.2
#14 lore raw

PATCH 14/26 gpio: remove sta2x11-gpio

In reply to Alessandro Rubini

The Connext chip has 4 gpio cells looking very similar to those of the Nomadik, whose gpio/pinctrl driver (already featuring devicetree support) will be used instead of the sta2x11 specific one.

---
 drivers/gpio/Kconfig        |    8 -
 drivers/gpio/Makefile       |    1 -
 drivers/gpio/gpio-sta2x11.c |  440 -------------------------------------------
 3 files changed, 0 insertions(+), 449 deletions(-)
 delete mode 100644 drivers/gpio/gpio-sta2x11.c
drivers/gpio/Kconfig +0 -8
index 4b7ba53..c93b13a 100644
@@ -226,14 +226,6 @@ config GPIO_SPEAR_SPICS
 	help
 	  Say yes here to support ST SPEAr SPI Chip Select as GPIO device
 
-config GPIO_STA2X11
-	bool "STA2x11/ConneXt GPIO support"
-	depends on MFD_STA2X11
-	select GENERIC_IRQ_CHIP
-	help
-	  Say yes here to support the STA2x11/ConneXt GPIO device.
-	  The GPIO module has 128 GPIO pins with alternate functions.
-
 config GPIO_TS5500
 	tristate "TS-5500 DIO blocks and compatibles"
 	help
drivers/gpio/Makefile +0 -1
index 156fd28..62a8b41 100644
@@ -65,7 +65,6 @@ obj-$(CONFIG_ARCH_SA1100)	+= gpio-sa1100.o
 obj-$(CONFIG_GPIO_SCH)		+= gpio-sch.o
 obj-$(CONFIG_GPIO_SODAVILLE)	+= gpio-sodaville.o
 obj-$(CONFIG_GPIO_SPEAR_SPICS)	+= gpio-spear-spics.o
-obj-$(CONFIG_GPIO_STA2X11)	+= gpio-sta2x11.o
 obj-$(CONFIG_GPIO_STMPE)	+= gpio-stmpe.o
 obj-$(CONFIG_GPIO_STP_XWAY)	+= gpio-stp-xway.o
 obj-$(CONFIG_GPIO_SX150X)	+= gpio-sx150x.o
drivers/gpio/gpio-sta2x11.c deleted +0 -440

440 lines not on this page · raw message

Signature · 1 line
1.7.7.2
Acked-by on v1 14/26
#15 lore raw

Re: [PATCH 14/26] gpio: remove sta2x11-gpio

Quoted 6 lines · Davide Ciminaghi

The Connext chip has 4 gpio cells looking very similar to those of the Nomadik, whose gpio/pinctrl driver (already featuring devicetree support) will be used instead of the sta2x11 specific one.

Seems we should have discovered this earlier ;-)

I'd be happy to apply this too.

If you want I can apply this and the pinctrl patch to my pinctrl tree for a consistent switch-over.

Yours,
Linus Walleij

#16 lore raw

PATCH 15/26 x86 STA2X11: remove the sta2x11-mfd driver.

In reply to Alessandro Rubini

This patch removes the mfd driver for the Connext chip, the final goal being to create platform devices through the new OF enabled version of the pci to amba bridge.
Most of the sta2x11-mfd.h header file is moved to asm/sta2x11.h. Platform drivers for sctl, scr, apbreg and apb_soc_regs are moved under arch/x86/platform/sta2x11.c (but the common probe function is empty at the moment, since we have no struct sta2x11_mfd anymore). Makefiles and Kconfigs are updated accordingly (note that REGMAP_MMIO is now selected by CONFIG_STA2X11, not CONFIG_STA2X11_MFD, which does not exist anymore).

---
 arch/x86/Kconfig                    |    1 +
 arch/x86/include/asm/sta2x11.h      |  318 ++++++++++++++++-
 arch/x86/platform/Makefile          |    1 +
 arch/x86/platform/sta2x11/Makefile  |    1 +
 arch/x86/platform/sta2x11/sta2x11.c |  279 ++++++++++++++
 drivers/mfd/Kconfig                 |    6 -
 drivers/mfd/Makefile                |    1 -
 drivers/mfd/sta2x11-mfd.c           |  680 -----------------------------------
 include/linux/mfd/sta2x11-mfd.h     |  518 --------------------------
 9 files changed, 598 insertions(+), 1207 deletions(-)
 create mode 100644 arch/x86/platform/sta2x11/Makefile
 create mode 100644 arch/x86/platform/sta2x11/sta2x11.c
 delete mode 100644 drivers/mfd/sta2x11-mfd.c
 delete mode 100644 include/linux/mfd/sta2x11-mfd.h
arch/x86/Kconfig +1 -0
index 0a779eb..ae05df92 100644
@@ -559,6 +559,7 @@ config STA2X11
 	select OF_EARLY_FLATTREE
 	select OF_DYNAMIC
 	select IRQ_DOMAIN
+	select REGMAP_MMIO
 	default n
 	---help---
 	  This adds support for boards based on the STA2X11 IO-Hub,
arch/x86/include/asm/sta2x11.h +316 -2

328 lines not on this page · raw message

arch/x86/platform/Makefile +1 -0
index 01e0231..28fc10c 100644
@@ -11,3 +11,4 @@ obj-y	+= sfi/
 obj-y	+= ts5500/
 obj-y	+= visws/
 obj-y	+= uv/
+obj-y	+= sta2x11/
arch/x86/platform/sta2x11/Makefile new file +1 -0
new file mode 100644
index 0000000..798c497
@@ -0,0 +1 @@
+obj-$(CONFIG_STA2X11) = sta2x11.o
arch/x86/platform/sta2x11/sta2x11.c new file +279 -0

279 lines not on this page · raw message

drivers/mfd/Kconfig +0 -6
index 633ee43..372d221 100644
@@ -666,12 +666,6 @@ config STMPE_SPI
 	  This is used to enable SPI interface of STMPE
 endmenu
 
-config MFD_STA2X11
-	bool "STMicroelectronics STA2X11"
-	depends on STA2X11 && GENERIC_HARDIRQS
-	select MFD_CORE
-	select REGMAP_MMIO
-
 config MFD_SYSCON
 	bool "System Controller Register R/W Based on Regmap"
 	select REGMAP_MMIO
drivers/mfd/Makefile +0 -1
index 3c90051..4819411 100644
@@ -24,7 +24,6 @@ obj-$(CONFIG_MFD_DM355EVM_MSP)	+= dm355evm_msp.o
 obj-$(CONFIG_MFD_TI_SSP)	+= ti-ssp.o
 obj-$(CONFIG_MFD_TI_AM335X_TSCADC)	+= ti_am335x_tscadc.o
 
-obj-$(CONFIG_MFD_STA2X11)	+= sta2x11-mfd.o
 obj-$(CONFIG_MFD_STMPE)		+= stmpe.o
 obj-$(CONFIG_STMPE_I2C)		+= stmpe-i2c.o
 obj-$(CONFIG_STMPE_SPI)		+= stmpe-spi.o
drivers/mfd/sta2x11-mfd.c deleted +0 -680

680 lines not on this page · raw message

include/linux/mfd/sta2x11-mfd.h deleted +0 -518

518 lines not on this page · raw message

Signature · 1 line
1.7.7.2
#17 lore raw

PATCH 16/26 x86 STA2X11 platform: add sta2x11_platform_init()

In reply to Alessandro Rubini

This patch adds an init function which looks for connext nodes in the device tree (compatible "pci104a,cc17") and creates a list of sta2x11 related data structures (struct sta2x11_instance_data). For each sta2x11, the relevant four platform devices are also created (scr, apbreg, apb-soc-regs, sctl).
Finally, of_match_tables are added to the four struct platform_driver.

---
 arch/x86/include/asm/sta2x11.h      |   17 +++++-
 arch/x86/platform/sta2x11/sta2x11.c |  111 ++++++++++++++++++++++++++++++++++-
 2 files changed, 125 insertions(+), 3 deletions(-)
arch/x86/include/asm/sta2x11.h +16 -1
index cd76923..30dd761 100644
@@ -21,7 +21,7 @@
 #define __ASM_STA2X11_H
 
 #include <linux/types.h>
-#include <linux/pci.h>
+#include <linux/of.h>
 
 enum sta2x11_plat_dev {
 	sta2x11_sctl = 0,
@@ -34,6 +34,21 @@ enum sta2x11_plat_dev {
 	sta2x11_n_plat_devs,
 };
 
+/*
+ * Data structure representing a connext instance.
+ */
+struct sta2x11_instance_data {
+	/* Instance id */
+	int id;
+	/* Registers data */
+	struct sta2x11_platform_drv_data *sctl;
+	struct sta2x11_platform_drv_data *scr;
+	struct sta2x11_platform_drv_data *apbreg;
+	struct sta2x11_platform_drv_data *apb_soc_regs;
+	/* Do not touch this from outside arch/x86/platform/sta2x11/sta2x11.c */
+	struct list_head list;
+};
+
 #define STA2X11_SCTL_NAME		"sta2x11-sctl"
 #define STA2X11_GPIO_NAME		"sta2x11-gpio"
 #define STA2X11_SCR_NAME		"sta2x11-scr"
arch/x86/platform/sta2x11/sta2x11.c +109 -2

171 lines not on this page · raw message

Signature · 1 line
1.7.7.2
#18 lore raw

PATCH 17/26 x86 STA2X11 platform: add sta2x11_instance_data helpers

In reply to Alessandro Rubini

This patch adds functions to get a pointer to a sta2x11 instance data structure given a pointer to a connext device or device node. Such helpers will be used by the (now empty) common probe function, and maybe by the common clock framework.

---
 arch/x86/include/asm/sta2x11.h      |   13 ++++++++
 arch/x86/platform/sta2x11/sta2x11.c |   55 ++++++++++++++++++++++++++++++++++-
 2 files changed, 67 insertions(+), 1 deletions(-)
arch/x86/include/asm/sta2x11.h +13 -0
index 30dd761..6df0c87 100644
@@ -49,6 +49,19 @@ struct sta2x11_instance_data {
 	struct list_head list;
 };
 
+/*
+ * Helper functions: get the pointer to a sta2x11 instance given the pointer
+ * to a device/device node belonging to a connext chip
+ */
+extern struct sta2x11_instance_data *
+sta2x11_node_to_instance(struct device_node *);
+
+static inline
+struct sta2x11_instance_data *sta2x11_dev_to_instance(struct device *dev)
+{
+	return sta2x11_node_to_instance(dev->of_node);
+}
+
 #define STA2X11_SCTL_NAME		"sta2x11-sctl"
 #define STA2X11_GPIO_NAME		"sta2x11-gpio"
 #define STA2X11_SCR_NAME		"sta2x11-scr"
arch/x86/platform/sta2x11/sta2x11.c +54 -1

61 lines not on this page · raw message

Signature · 1 line
1.7.7.2
#19 lore raw

PATCH 18/26 x86 STA2X11 platform: add a common probe function for platform devices

In reply to Alessandro Rubini

This patch introduces a common probe method for the STA2X11 base platform drivers. The following steps are performed:

* Registers belonging to the probed device are ioremapped.
* devm_regmap_init_mmio() is invoked on such registers.
* A struct sta2x11_platform_drv_data containing device data is allocated, filled in, and "linked" to the struct sta2x11_instance_data representing the instance to which the probed device belongs.

---
 arch/x86/include/asm/sta2x11.h      |    9 +++++
 arch/x86/platform/sta2x11/sta2x11.c |   68 ++++++++++++++++++++++++++++++++++-
 2 files changed, 76 insertions(+), 1 deletions(-)
arch/x86/include/asm/sta2x11.h +9 -0
index 6df0c87..31fc648 100644
@@ -35,6 +35,15 @@ enum sta2x11_plat_dev {
 };
 
 /*
+ * Platform driver data for sta2x11 platform devices
+ */
+struct sta2x11_platform_drv_data {
+	void * __iomem regs;
+	spinlock_t lock;
+	struct regmap *regmap;
+};
+
+/*
  * Data structure representing a connext instance.
  */
 struct sta2x11_instance_data {
arch/x86/platform/sta2x11/sta2x11.c +67 -1

77 lines not on this page · raw message

Signature · 1 line
1.7.7.2
#20 lore raw

PATCH 19/26 x86 STA2X11 platform: create sta2x11-clock-regs device

In reply to Alessandro Rubini

This patch creates a virtual platform device each time the apb-soc-regs and sctl devices have been probed for a given sta2x11 instance. This will trigger clock registration for such instance.

---
 arch/x86/include/asm/sta2x11.h      |    1 +
 arch/x86/platform/sta2x11/sta2x11.c |   21 +++++++++++++++++++++
 2 files changed, 22 insertions(+), 0 deletions(-)
arch/x86/include/asm/sta2x11.h +1 -0
index 31fc648..3c5dee4 100644
@@ -78,6 +78,7 @@ struct sta2x11_instance_data *sta2x11_dev_to_instance(struct device *dev)
 #define STA2X11_APBREG_NAME		"sta2x11-apbreg"
 #define STA2X11_APB_SOC_REGS_NAME	"sta2x11-apb-soc-regs"
 #define STA2X11_VIC_NAME		"sta2x11-vic"
+#define STA2X11_CLOCK_REGS_NAME		"sta2x11-clock-regs"
 
 /* CAN and MLB */
 #define APBREG_BSR	0x00	/* Bridge Status Reg */
arch/x86/platform/sta2x11/sta2x11.c +21 -0
index 1f1d1af..57ed10d 100644
@@ -243,6 +243,20 @@ struct sta2x11_instance_data *sta2x11_node_to_instance(struct device_node *n)
 }
 EXPORT_SYMBOL(sta2x11_node_to_instance);
 
+static int create_clk_dev(struct sta2x11_instance_data *instance)
+{
+	int stat;
+	struct platform_device *cpd =
+		platform_device_alloc(STA2X11_CLOCK_REGS_NAME, instance->id);
+	if (!cpd)
+		return -ENOMEM;
+
+	cpd->dev.platform_data = instance;
+	stat = platform_device_add(cpd);
+	if (stat < 0)
+		platform_device_put(cpd);
+	return stat;
+}
 
 /* Common probe for the four platform devices */
 static int sta2x11_platform_probe(struct platform_device *dev,
@@ -312,6 +326,13 @@ static int sta2x11_platform_probe(struct platform_device *dev,
 	}
 	*dst = platform_drv_data;
 
+	/*
+	 * When both sctl and apb_soc_regs have been probed, we're ready for
+	 * creating the "sta2x11-clock-regs" platform device
+	 */
+	if (instance->sctl && instance->apb_soc_regs)
+		create_clk_dev(instance);
+
 	platform_set_drvdata(dev, platform_drv_data);
 	return 0;
 }
Signature · 1 line
1.7.7.2
#21 lore raw

PATCH 20/26 x86 STA2X11 platform: remove useless pr_info()'s

In reply to Alessandro Rubini
---
 arch/x86/platform/sta2x11/sta2x11.c |    4 ----
 1 files changed, 0 insertions(+), 4 deletions(-)
arch/x86/platform/sta2x11/sta2x11.c +0 -4
index 57ed10d..b3e9cec 100644
@@ -374,7 +374,6 @@ static struct platform_driver sta2x11_sctl_platform_driver = {
 
 static int __init sta2x11_sctl_init(void)
 {
-	pr_info("%s\n", __func__);
 	return platform_driver_register(&sta2x11_sctl_platform_driver);
 }
 
@@ -394,7 +393,6 @@ static struct platform_driver sta2x11_apbreg_platform_driver = {
 
 static int __init sta2x11_apbreg_init(void)
 {
-	pr_info("%s\n", __func__);
 	return platform_driver_register(&sta2x11_apbreg_platform_driver);
 }
 
@@ -414,7 +412,6 @@ static struct platform_driver sta2x11_apb_soc_regs_platform_driver = {
 
 static int __init sta2x11_apb_soc_regs_init(void)
 {
-	pr_info("%s\n", __func__);
 	return platform_driver_register(&sta2x11_apb_soc_regs_platform_driver);
 }
 
@@ -434,7 +431,6 @@ static struct platform_driver sta2x11_scr_platform_driver = {
 
 static int __init sta2x11_scr_init(void)
 {
-	pr_info("%s\n", __func__);
 	return platform_driver_register(&sta2x11_scr_platform_driver);
 }
 
Signature · 1 line
1.7.7.2
#22 lore raw

PATCH 21/26 AMBA: pci-amba bridge: improve code readability

In reply to Alessandro Rubini

This patch moves the code fixing up irq numbers for amba devices to a separate function (fixup_amba_irqs()).

---
 drivers/amba/pci-amba.c |   97 +++++++++++++++++++++++++---------------------
 1 files changed, 53 insertions(+), 44 deletions(-)
drivers/amba/pci-amba.c +53 -44
index e56717b..c825c7a 100644
@@ -25,19 +25,63 @@
 */
 #define IMAP_ROW_LEN (1 + 1 + 1 + 1 + 1)
 
+static int fixup_amba_irq(struct device_node *amba_node,
+			  struct device_node *amba_bus,
+			  struct pci_dev *pdev)
+{
+	const void *p;
+	struct property *newimap;
+	u32 *ptr, *newv;
+	const u32 *reg;
+	int i, len, found;
+
+	p = of_get_property(amba_bus, "interrupt-map", &len);
+	if (!p)
+		/* No amba bus interrupt-map property */
+		return -EINVAL;
+
+	newimap = devm_kzalloc(&pdev->dev, sizeof(*newimap), GFP_KERNEL);
+	if (!newimap)
+		return -ENOMEM;
+
+	newimap->name = kstrdup("interrupt-map", GFP_KERNEL);
+	if (!newimap->name)
+		return -ENOMEM;
+
+	newv = devm_kzalloc(&pdev->dev, len, GFP_KERNEL);
+	if (!newv) {
+		kfree(newimap->name);
+		return -ENOMEM;
+	}
+
+	newimap->value = newv;
+	newimap->length = len;
+	memcpy(newv, p, len);
+	for (ptr = newv, i = 0, found = 0;
+	     i < len/sizeof(u32); ptr += IMAP_ROW_LEN, i += IMAP_ROW_LEN) {
+		reg = of_get_property(amba_node, "reg", NULL);
+		if (ptr[0] == reg[0]) {
+			ptr[IMAP_ROW_LEN - 1] = cpu_to_be32(pdev->irq);
+			found = 1;
+			break;
+		}
+	}
+	if (!found) {
+		pr_err("Could not update amba irq\n");
+		return -EINVAL;
+	}
+	of_update_property(amba_bus, newimap);
+	return 0;
+}
+
 static int pci_amba_probe(struct pci_dev *pdev,
 			  const struct pci_device_id *id)
 {
 	struct amba_device *adev;
-	int i, ret, len;
+	int ret;
 	struct device_node *n, *node, *pci_amba_bridge, *amba_bus = NULL,
 		*amba_node = NULL;
-	const void *p;
 	char *name;
-	struct property *newimap;
-	u32 *newv, *ptr;
-	const u32 *reg;
-	int found;
 
 	pci_enable_msi(pdev);
 	ret = pci_enable_device(pdev);
@@ -96,44 +140,9 @@ static int pci_amba_probe(struct pci_dev *pdev,
 	  map to fix things up.
 	*/
 	if (of_get_property(amba_node, "interrupts", NULL)) {
-		p = of_get_property(amba_bus, "interrupt-map", &len);
-		if (!p)
-			/* No amba bus interrupt-map property */
-			return -EINVAL;
-
-		newimap = devm_kzalloc(&pdev->dev, sizeof(*newimap),
-				       GFP_KERNEL);
-		if (!newimap)
-			return -ENOMEM;
-
-		newimap->name = kstrdup("interrupt-map", GFP_KERNEL);
-		if (!newimap->name)
-			return -ENOMEM;
-
-		newv = devm_kzalloc(&pdev->dev, len, GFP_KERNEL);
-		if (!newv) {
-			kfree(newimap->name);
-			return -ENOMEM;
-		}
-
-		newimap->value = newv;
-		newimap->length = len;
-		memcpy(newv, p, len);
-		for (ptr = newv, i = 0, found = 0;
-		     i < len/sizeof(u32);
-		     ptr += IMAP_ROW_LEN, i += IMAP_ROW_LEN) {
-			reg = of_get_property(amba_node, "reg", NULL);
-			if (ptr[0] == reg[0]) {
-				ptr[IMAP_ROW_LEN - 1] = cpu_to_be32(pdev->irq);
-				found = 1;
-				break;
-			}
-		}
-		if (!found) {
-			pr_err("Could not update amba irq\n");
-			return -EINVAL;
-		}
-		of_update_property(amba_bus, newimap);
+		ret = fixup_amba_irq(amba_node, amba_bus, pdev);
+		if (ret < 0)
+			return ret;
 	}
 
 	/* And finally create the amba device */
Signature · 1 line
1.7.7.2
#23 lore raw

PATCH 22/26 AMBA: pci-amba bridge: extend number of amba devs per pci device

In reply to Alessandro Rubini

This patch makes it possible to create multiple AMBA devices per PCI device (multiple AMBA devices on the same PCI bar, or one/more AMBA devices referring to more than one PCI BAR). This feature is needed to completely support the Connext chip, which has, for instance, multiple devices on the same BAR (former mfd device) and multiple devices on multiple PCI BARs (6 msp ports, 2 ports per PCI BAR).

---
 drivers/amba/pci-amba.c |  152 +++++++++++++++++++++++++++++++++++++----------
 1 files changed, 121 insertions(+), 31 deletions(-)
drivers/amba/pci-amba.c +121 -31
index c825c7a..f272d38 100644
@@ -25,9 +25,47 @@
 */
 #define IMAP_ROW_LEN (1 + 1 + 1 + 1 + 1)
 
-static int fixup_amba_irq(struct device_node *amba_node,
-			  struct device_node *amba_bus,
-			  struct pci_dev *pdev)
+static inline int resource_fits(struct resource *r1, struct resource *r2)
+{
+	return (r1->start >= r2->start) && (r1->end <= r2->end);
+}
+
+static const char *get_platform_prefix(struct pci_dev *pdev)
+{
+	switch (pdev->device) {
+	case PCI_DEVICE_ID_STMICRO_ESRAM:
+		return "mmio";
+	case PCI_DEVICE_ID_STMICRO_GPIO:
+		return "gpio";
+	default:
+		return "pci-amba-platform";
+	}
+	return NULL;
+}
+
+static inline int is_platform_device(struct pci_dev *pdev)
+{
+	return pdev->device == PCI_DEVICE_ID_STMICRO_ESRAM ||
+		pdev->device == PCI_DEVICE_ID_STMICRO_GPIO ||
+		pdev->device == PCI_DEVICE_ID_STMICRO_VIC;
+}
+
+static int get_dev_name(char **name, struct pci_dev *pdev, int index)
+{
+	const char *prefix = is_platform_device(pdev) ?
+		get_platform_prefix(pdev) : "amba";
+	const char *core = dev_name(&pdev->dev);
+	*name = devm_kzalloc(&pdev->dev, strlen(core) + strlen(prefix) + 3,
+			     GFP_KERNEL);
+	if (!*name)
+		return -ENOMEM;
+	sprintf(*name, "%s-%s-%1d", prefix, core, index);
+	return 0;
+}
+
+static int fixup_irq(struct device_node *node,
+		     struct device_node *amba_bus,
+		     struct pci_dev *pdev)
 {
 	const void *p;
 	struct property *newimap;
@@ -59,7 +97,7 @@ static int fixup_amba_irq(struct device_node *amba_node,
 	memcpy(newv, p, len);
 	for (ptr = newv, i = 0, found = 0;
 	     i < len/sizeof(u32); ptr += IMAP_ROW_LEN, i += IMAP_ROW_LEN) {
-		reg = of_get_property(amba_node, "reg", NULL);
+		reg = of_get_property(node, "reg", NULL);
 		if (ptr[0] == reg[0]) {
 			ptr[IMAP_ROW_LEN - 1] = cpu_to_be32(pdev->irq);
 			found = 1;
@@ -77,10 +115,12 @@ static int fixup_amba_irq(struct device_node *amba_node,
 static int pci_amba_probe(struct pci_dev *pdev,
 			  const struct pci_device_id *id)
 {
-	struct amba_device *adev;
-	int ret;
+	struct amba_device **adev = NULL;
+	struct platform_device **platdev = NULL;
+	int ret, i, dncnt = 0;
+	void *drvdata;
 	struct device_node *n, *node, *pci_amba_bridge, *amba_bus = NULL,
-		*amba_node = NULL;
+		*dev_nodes[8];
 	char *name;
 
 	pci_enable_msi(pdev);
@@ -95,6 +135,8 @@ static int pci_amba_probe(struct pci_dev *pdev,
 	if (!node)
 		return -EINVAL;
 
+	memset(dev_nodes, 0, sizeof(dev_nodes));
+
 	/* Get a reference to the pci amba bridge (our pci parent) */
 	pci_amba_bridge = of_get_parent(node);
 	if (!pci_amba_bridge)
@@ -114,47 +156,93 @@ static int pci_amba_probe(struct pci_dev *pdev,
 		return -ENODEV;
 
 	/*
+	  Allocate an array of amba or platform devices pointers
+	*/
+	if (is_platform_device(pdev))
+		platdev = devm_kzalloc(&pdev->dev, sizeof(*platdev) * 8,
+				       GFP_KERNEL);
+	else
+		adev = devm_kzalloc(&pdev->dev, sizeof(*adev) * 8, GFP_KERNEL);
+	if (!adev && !platdev)
+		return -ENOMEM;
+
+	/*
 	   Now find out what the relevant amba device is by looking for
 	   a resource with the same initial address of this pci device's BAR0
 	*/
 	for_each_child_of_node(amba_bus, n) {
-		struct resource r;
-		if (of_address_to_resource(n, 0, &r))
+		struct resource r[8];
+		if (of_address_to_resource(n, 0, &r[dncnt]))
 			continue;
-		if (r.start == pdev->resource[0].start) {
-			amba_node = n;
-			break;
+		for (i = PCI_STD_RESOURCES; (i < PCI_STD_RESOURCE_END) &&
+			     (dncnt < ARRAY_SIZE(dev_nodes)); i++) {
+			if (resource_fits(&r[dncnt], &pdev->resource[i])) {
+				dev_nodes[dncnt++] = n;
+				break;
+			}
 		}
 	}
-	if (!amba_node)
+	if (!dncnt)
 		return -ENODEV;
 
-	/* Create a unique name for the device */
-	name = devm_kzalloc(&pdev->dev, strlen(dev_name(&pdev->dev)) + 6,
-			    GFP_KERNEL);
-	sprintf(name, "amba-%s", dev_name(&pdev->dev));
-
-	/*
-	  Since we're dealing with MSI IRQs, the value of a device's IRQ
-	  number is known at runtime only. Update the amba bus interrupt
-	  map to fix things up.
-	*/
-	if (of_get_property(amba_node, "interrupts", NULL)) {
-		ret = fixup_amba_irq(amba_node, amba_bus, pdev);
+	for (i = 0; i < dncnt && dev_nodes[i]; i++) {
+		/* Create a unique name for the device */
+		ret = get_dev_name(&name, pdev, i);
 		if (ret < 0)
 			return ret;
+		/*
+		  Since we're dealing with MSI IRQs, the value of a device's
+		  IRQ number is known at runtime only. Update the amba bus
+		  interrupt map property to fix things up.
+		*/
+		if (of_get_property(dev_nodes[i], "interrupts", NULL)) {
+			ret = fixup_irq(dev_nodes[i], amba_bus, pdev);
+			if (ret < 0)
+				return ret;
+		}
+		/* And finally create the amba or platform device */
+		if (is_platform_device(pdev)) {
+			platdev[i] = of_platform_device_create(dev_nodes[i],
+							       name, NULL);
+			continue;
+		}
+		adev[i] = of_amba_device_create(dev_nodes[i], name, NULL, NULL,
+						&pdev->resource[0]);
 	}
-
-	/* And finally create the amba device */
-	adev = of_amba_device_create(n, name, NULL, NULL, &pdev->resource[0]);
-	pci_set_drvdata(pdev, adev);
+	drvdata = is_platform_device(pdev) ? (void *)platdev : (void *)adev;
+	pci_set_drvdata(pdev, drvdata);
 	return 0;
 };
 
+static void platform_remove(void *__platdev)
+{
+	int i;
+	struct platform_device **platdev = __platdev;
+	for (i = 0; i < 8; i++) {
+		if (!platdev[i])
+			break;
+		platform_device_unregister(platdev[i]);
+	}
+}
+
+static void amba_remove(void *__ambadev)
+{
+	int i;
+	struct amba_device **ambadev = __ambadev;
+	for (i = 0; i < 8; i++) {
+		if (!ambadev[i])
+			break;
+		amba_device_unregister(ambadev[i]);
+	}
+}
+
 static void pci_amba_remove(struct pci_dev *pdev)
 {
-	struct amba_device *adev = pci_get_drvdata(pdev);
-	amba_device_unregister(adev);
+	void *drvdata = pci_get_drvdata(pdev);
+	if (is_platform_device(pdev))
+		platform_remove(drvdata);
+	else
+		amba_remove(drvdata);
 	pci_disable_msi(pdev);
 }
 
@@ -168,6 +256,8 @@ static DEFINE_PCI_DEVICE_TABLE(pci_amba_table) = {
 	{PCI_VDEVICE(STMICRO, PCI_DEVICE_ID_STMICRO_SDIO)},
 	{PCI_VDEVICE(STMICRO, PCI_DEVICE_ID_STMICRO_AUDIO_ROUTER_DMA)},
 	{PCI_VDEVICE(STMICRO, PCI_DEVICE_ID_STMICRO_AUDIO_ROUTER_MSPS)},
+	{PCI_VDEVICE(STMICRO, PCI_DEVICE_ID_STMICRO_ESRAM)},
+	{PCI_VDEVICE(STMICRO, PCI_DEVICE_ID_STMICRO_GPIO)},
 	{0,}
 };
 
Signature · 1 line
1.7.7.2
#24 lore raw

PATCH 23/26 AMBA: pci-amba bridge: export function creating pci-amba device names

In reply to Alessandro Rubini

pci_amba_get_dev_name() will be used by the sta2x11 common clock framework to register clkdevs with the same name as the corresponding amba or platform device.

---
 drivers/amba/pci-amba.c  |   14 ++++++++++++++
 include/linux/pci-amba.h |   42 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 56 insertions(+), 0 deletions(-)
 create mode 100644 include/linux/pci-amba.h
drivers/amba/pci-amba.c +14 -0
index f272d38..1beeefd 100644
@@ -9,6 +9,7 @@
 #include <linux/amba/bus.h>
 #include <linux/pci.h>
 #include <linux/pci_ids.h>
+#include <linux/pci-amba.h>
 #include <linux/slab.h>
 #include <linux/irq.h>
 #include <linux/sizes.h>
@@ -25,6 +26,8 @@
 */
 #define IMAP_ROW_LEN (1 + 1 + 1 + 1 + 1)
 
+static const struct pci_device_id pci_amba_table[];
+
 static inline int resource_fits(struct resource *r1, struct resource *r2)
 {
 	return (r1->start >= r2->start) && (r1->end <= r2->end);
@@ -63,6 +66,17 @@ static int get_dev_name(char **name, struct pci_dev *pdev, int index)
 	return 0;
 }
 
+int pci_amba_get_dev_name(char **name, struct pci_dev *pdev, int index)
+{
+	/* Check whether the device is a pci-amba one */
+	if (!pci_match_id(pci_amba_table, pdev))
+		return -ENODEV;
+	if (!name)
+		return -EINVAL;
+	return get_dev_name(name, pdev, index);
+}
+EXPORT_SYMBOL(pci_amba_get_dev_name);
+
 static int fixup_irq(struct device_node *node,
 		     struct device_node *amba_bus,
 		     struct pci_dev *pdev)
include/linux/pci-amba.h new file +42 -0

42 lines not on this page · raw message

Signature · 1 line
1.7.7.2
#25 lore raw

PATCH 24/26 x86 STA2X11: add dts for Intel's Northville board

In reply to Alessandro Rubini

The base for this dts was automatically generated to avoid typos, most of all in ranges and interrupt-map properties.
It was then hand-edited to add some details (for instance mmci1 gpio's). This dts is still incomplete. Yet, it contains most of the pci-amba devices and allows a northville board to boot with a serial console on /dev/ttyAMA1. A shell is also working on the same UART (interrupts are OK for UART's and apparently for most of the other

---
 arch/x86/platform/sta2x11/northville.dts |  941 ++++++++++++++++++++++++++++++
 1 files changed, 941 insertions(+), 0 deletions(-)
 create mode 100644 arch/x86/platform/sta2x11/northville.dts
arch/x86/platform/sta2x11/northville.dts new file +941 -0
new file mode 100644
index 0000000..b41c499
@@ -0,0 +1,941 @@
+/dts-v1/;
+/ {
+	compatible =  "intel,northville" ;
+	#address-cells = < 1 >;
+	#size-cells = < 1 >;
+	cpus@0 {
+		#address-cells = < 1 >;
+		#size-cells = < 0 >;
+		cpu@0 {
+			compatible =  "intel,e6600-cpu" ;
+			reg = < 0x00000000  >;
+
+		};
+
+	};
+	soc@2 {
+		compatible =  "intel,e6600-soc" ;
+		#address-cells = < 1 >;
+		#size-cells = < 1 >;
+		ranges;
+		pci@cf8 {
+			compatible =  "pci" ;
+			device_type =  "pci" ;
+			#address-cells = < 3 >;
+			#size-cells = < 2 >;
+			reg = < 0x00000cf8    0x00000008  >;
+			ranges = < 0x02000000    0x00000000    0x000a0000    0x000a0000    0x00000000    0x00020000
+				 0x02000000    0x00000000    0x40000000    0x40000000    0x00000000    0xc0000000  >;
+			bus-range = < 0x00000000    0x00000000  >;
+			/* pci host bridge, bus = 0, dev = 0, function = 0 ; */
+			/* name = Atom Processor E6xx PCI Host Bridge #1 */
+			pci@00000000 {
+				compatible =  "pci8086,4114.5",
+					"pci8086,4114",
+					"pciclass060000",
+					"pciclass0600" ;
+				reg = < 0x00000000    0x00000000    0x00000000    0x00000000    0x00000100  >;
+				device_type =  "pci" ;
+
+			};
+			/* pci host bridge, bus = 0, dev = 1, function = 0 ; */
+			/* name = Atom Processor E6xx Configuration Unit */
+			pci@00000800 {
+				compatible =  "pci8086,8183.2",
+					"pci8086,8183",
+					"pciclass060000",
+					"pciclass0600" ;
+				reg = < 0x00000800    0x00000000    0x00000000    0x00000000    0x00000100  >;
+				device_type =  "pci" ;
+
+			};
+			/* pci device, bus = 0, dev = 2, function = 0 ; */
+			/* name = Atom Processor E6xx Integrated Graphics Controller */
+			pci@02001000 {
+				compatible =  "pci8086,4108.5",
+					"pci8086,4108",
+					"pciclass030000",
+					"pciclass0300" ;
+				reg = < 0x02001000    0x00000000    0xd2a00000    0x00000000    0x00100000
+					 0x01001000    0x00000000    0x0000f010    0x00000000    0x00000008
+					 0x02001000    0x00000000    0xb0000000    0x00000000    0x10000000
+					 0x02001000    0x00000000    0xd2bc0000    0x00000000    0x00040000  >;
+				device_type =  "pci" ;
+
+			};
+			/* pci device, bus = 0, dev = 3, function = 0 ; */
+			/* name = Atom Processor E6xx Integrated Graphics Controller */
+			pci@02001800 {
+				compatible =  "pci8086,8182.2",
+					"pci8086,8182",
+					"pciclass040000",
+					"pciclass0400" ;
+				reg = < 0x02001800    0x00000000    0xd2b00000    0x00000000    0x00080000
+					 0x01001800    0x00000000    0x0000f000    0x00000000    0x00000008
+					 0x02001800    0x00000000    0xa0000000    0x00000000    0x10000000
+					 0x02001800    0x00000000    0xd2b80000    0x00000000    0x00040000  >;
+				device_type =  "pci" ;
+
+			};
+			/* pci-pci bridge, bus = 0, dev = 23, function = 0 ; */
+			/* name = Atom Processor E6xx PCI Express Port 1 */
+			pci@0000b800 {
+				compatible =  "pci8086,8184.2",
+					"pci8086,8184",
+					"pciclass060400",
+					"pciclass0604" ;
+				reg = < 0x0000b800    0x00000000    0x00000000    0x00000000    0x00000100  >;
+				device_type =  "pci" ;
+				#address-cells = < 3 >;
+				#size-cells = < 2 >;
+				bus-range = < 0x00000001    0x00000006  >;
+				ranges = < 0x0200b800    0x00000000    0xc0000000    0x02000000    0x00000000    0xc0000000    0x00000000    0x12900000  >;
+				/* pci-pci bridge, bus = 1, dev = 0, function = 0 ; */
+				/* name = Device cc17 */
+				pci@00010000 {
+					compatible =  "pci104a,cc17.0",
+						"pci104a,cc17",
+						"pciclass060400",
+						"pciclass0604" ;
+					reg = < 0x00010000    0x00000000    0x00000000    0x00000000    0x00000100  >;
+					device_type =  "pci" ;
+					interrupt-parent = <&msi>;
+					#interrupt-cells = <1>;
+
+					#address-cells = < 3 >;
+					#size-cells = < 2 >;
+					bus-range = < 0x00000002    0x00000006  >;
+					ranges = < 0x02010000    0x00000000    0xc0000000    0x0200b800    0x00000000    0xc0000000    0x00000000    0x12900000  >;
+					/* pci-pci bridge, bus = 2, dev = 0, function = 0 ; */
+					/* name = Device cc18 */
+					pci@00020000 {
+						compatible =  "pci104a,cc18.0",
+							"pci104a,cc18",
+							"pciclass060400",
+							"pciclass0604" ;
+						reg = < 0x00020000    0x00000000    0x00000000    0x00000000    0x00000100  >;
+						device_type =  "pci" ;
+						#address-cells = < 3 >;
+						#size-cells = < 2 >;
+						bus-range = < 0x00000003    0x00000003  >;
+						ranges = < 0x02020000    0x00000000    0xca800000    0x02010000    0x00000000    0xca800000    0x00000000    0x04000000  >;
+						/* pci device, bus = 3, dev = 0, function = 0 ; */
+						/* name = Device cc0c */
+						pci@02030000 {
+							compatible =  "pci104a,cc0c.0",
+								"pci104a,cc0c",
+								"pciclass088000",
+								"pciclass0880" ;
+							reg = < 0x02030000    0x00000000    0xce400000    0x00000000    0x00400000
+								 0x02030000    0x00000000    0xce000000    0x00000000    0x00400000  >;
+							device_type =  "pci" ;
+
+						};
+						/* pci device, bus = 3, dev = 0, function = 1 ; */
+						/* name = Device cc01 */
+						pci@02030100 {
+							compatible =  "pci104a,cc01.0",
+								"pci104a,cc01",
+								"pciclass0c0380",
+								"pciclass0c03" ;
+							reg = < 0x02030100    0x00000000    0xcdc00000    0x00000000    0x00400000
+								 0x02030100    0x00000000    0xcd800000    0x00000000    0x00400000  >;
+							device_type =  "pci" ;
+
+						};
+						/* pci device, bus = 3, dev = 0, function = 2 ; */
+						/* name = Connext usb host controller */
+						pci@02030200 {
+							compatible =  "pci104a,cc00.0",
+								"pci104a,cc00",
+								"pciclass0c0380",
+								"pciclass0c03" ;
+							reg = < 0x02030200    0x00000000    0xcd400000    0x00000000    0x00400000
+								 0x02030200    0x00000000    0xcd000000    0x00000000    0x00400000  >;
+							device_type =  "pci" ;
+
+						};
+						/* pci device, bus = 3, dev = 0, function = 3 ; */
+						/* name = Device cc02 */
+						pci@02030300 {
+							compatible =  "pci104a,cc02.0",
+								"pci104a,cc02",
+								"pciclass0c0380",
+								"pciclass0c03" ;
+							reg = < 0x02030300    0x00000000    0xccc00000    0x00000000    0x00400000
+								 0x02030300    0x00000000    0xcc800000    0x00000000    0x00400000  >;
+							device_type =  "pci" ;
+
+						};
+						/* pci device, bus = 3, dev = 0, function = 4 ; */
+						/* name = Device cc05 */
+						pci@02030400 {
+							compatible =  "pci104a,cc05.0",
+								"pci104a,cc05",
+								"pciclass080100",
+								"pciclass0801" ;
+							reg = < 0x02030400    0x00000000    0xcc400000    0x00000000    0x00400000
+								 0x02030400    0x00000000    0xcc000000    0x00000000    0x00400000  >;
+							device_type =  "pci" ;
+
+						};
+						/* pci device, bus = 3, dev = 0, function = 5 ; */
+						/* name = Device cc03 */
+						pci@02030500 {
+							compatible =  "pci104a,cc03.0",
+								"pci104a,cc03",
+								"pciclass070000",
+								"pciclass0700" ;
+							reg = < 0x02030500    0x00000000    0xcbc00000    0x00000000    0x00400000
+								 0x02030500    0x00000000    0xcb800000    0x00000000    0x00400000  >;
+							device_type =  "pci" ;
+
+						};
+						/* pci device, bus = 3, dev = 0, function = 6 ; */
+						/* name = Device cc03 */
+						pci@02030600 {
+							compatible =  "pci104a,cc03.0",
+								"pci104a,cc03",
+								"pciclass070000",
+								"pciclass0700" ;
+							reg = < 0x02030600    0x00000000    0xcb400000    0x00000000    0x00400000
+								 0x02030600    0x00000000    0xcb000000    0x00000000    0x00400000  >;
+							device_type =  "pci" ;
+
+						};
+						/* pci device, bus = 3, dev = 0, function = 7 ; */
+						/* name = Device cc04 */
+						pci@02030700 {
+							compatible =  "pci104a,cc04.0",
+								"pci104a,cc04",
+								"pciclass070000",
+								"pciclass0700" ;
+							reg = < 0x02030700    0x00000000    0xcac00000    0x00000000    0x00400000
+								 0x02030700    0x00000000    0xca800000    0x00000000    0x00400000  >;
+							device_type =  "pci" ;
+
+						};
+						amba@00020000 {
+							compatible =  "arm,amba-bus" ;
+							#address-cells = < 1 >;
+							#size-cells = < 1 >;
+							#interrupt-cells = < 1 >;
+							interrupt-map = < 0x50000000    0xffffffff    &msi    0xfee03000    0x00000000
+								 0x54005000    0x0000001f    &msi    0xfee03000    0x00000000
+								 0x54006000    0x00000020    &msi    0xfee03000    0x00000000
+								 0x54007000    0x00000021    &msi    0xfee03000    0x00000000
+								 0x54008000    0x00000022    &msi    0xfee03000    0x00000000
+								 0x54009000    0xffffffff    &msi    0xfee03000    0x00000000
+								 0x5400a000    0xffffffff    &msi    0xfee03000    0x00000000
+								 0x13000000    0x00000001    &msi    0xfee03000    0x00000000
+								 0x5c000000    0x0000001b    &msi    0xfee03000    0x00000000
+								 0x5c001000    0x0000001c    &msi    0xfee03000    0x00000000
+								 0x5c002000    0x0000001d    &msi    0xfee03000    0x00000000  >;
+							ranges = < 0x50000000    0x02030000    0x00000000    0xce000000    0x00001000
+								 0x54005000    0x02030000    0x00000000    0xce400000    0x00001000
+								 0x54006000    0x02030000    0x00000000    0xce401000    0x00001000
+								 0x54007000    0x02030000    0x00000000    0xce402000    0x00001000
+								 0x54008000    0x02030000    0x00000000    0xce403000    0x00001000
+								 0x54009000    0x02030000    0x00000000    0xce404000    0x00001000
+								 0x5400a000    0x02030000    0x00000000    0xce405000    0x00001000
+								 0x13000000    0x02030400    0x00000000    0xcc400000    0x00001000
+								 0x5c000000    0x02030500    0x00000000    0xcbc00000    0x00001000
+								 0x5c001000    0x02030600    0x00000000    0xcb400000    0x00001000
+								 0x5c002000    0x02030700    0x00000000    0xcac00000    0x00001000  >;
+							soc_dma_0: dma-controller@13000000 {
+								compatible =  "stericsson,pl080-nomadik",
+									"arm,primecell" ;
+								arm,primecell-periphid = < 0x00280080  >;
+								reg = < 0x13000000    0x00001000  >;
+								interrupts = < 0x00000001  >;
+
+							};
+							apb_regs_0: apb-regs@50000000 {
+								compatible =  "st,sta2x11-apb-regs" ;
+								reg = < 0x50000000    0x00010000  >;
+
+							};
+							gpio0_0: gpio@54005000 {
+								compatible =  "st,nomadik-gpio" ;
+								reg = < 0x54005000    0x00001000  >;
+								interrupts = < 0x0000001f  >;
+								interrupt-controller;
+								#interrupt-cells = < 2 >;
+								gpio-controller;
+								#gpio-cells = < 2 >;
+								gpio-bank = < 0 >;
+
+							};
+							gpio1_0: gpio@54006000 {
+								compatible =  "st,nomadik-gpio" ;
+								reg = < 0x54006000    0x00001000  >;
+								interrupts = < 0x00000020  >;
+								interrupt-controller;
+								#interrupt-cells = < 2 >;
+								gpio-controller;
+								#gpio-cells = < 2 >;
+								gpio-bank = < 1 >;
+
+							};
+							gpio2_0: gpio@54007000 {
+								compatible =  "st,nomadik-gpio" ;
+								reg = < 0x54007000    0x00001000  >;
+								interrupts = < 0x00000021  >;
+								interrupt-controller;
+								#interrupt-cells = < 2 >;
+								gpio-controller;
+								#gpio-cells = < 2 >;
+								gpio-bank = < 2 >;
+
+							};
+							gpio3_0: gpio@54008000 {
+								compatible =  "st,nomadik-gpio" ;
+								reg = < 0x54008000    0x00001000  >;
+								interrupts = < 0x00000022  >;
+								interrupt-controller;
+								#interrupt-cells = < 2 >;
+								gpio-controller;
+								#gpio-cells = < 2 >;
+								gpio-bank = < 3 >;
+
+							};
+							pinctrl {
+								compatible = "stericsson,nmk-pinctrl-sta2x11";
+								/* Pin configurations */
+								sdio1_default_mux: sdio1_mux {
+								       ste,function = "sdio1";
+								       ste,pins = "sdio1_a_1";
+								};
+								sdio1_default_mode: sdio1_mode {
+										    mmcsd_default_cfg1 {
+												       /* CD, WP */
+												       ste,pins = "GPIO124_J5",
+												       "GPIO123_J4";
+												       /* inputs with no pull up ? */
+												       ste,input = <0>;
+										     };
+										     mmcsd_default_cfg2 {
+												       /* PWR */
+												       ste,pins = "GPIO121_J3";
+												       /* output ? */
+												       ste,output = <2>;
+										     };
+									};
+							};
+							sctl_0: sctl@54009000 {
+								compatible =  "st,sta2x11-sctl" ;
+								reg = < 0x54009000    0x00001000  >;
+
+							};
+							scr_0: scr@5400a000 {
+								compatible =  "st,sta2x11-scr" ;
+								reg = < 0x5400a000    0x00001000  >;
+
+							};
+							uart0_0: serial@5c000000 {
+								compatible =  "stericsson,pl011",
+									"arm,primecell" ;
+								arm,primecell-periphid = < 0x00380802  >;
+								reg = < 0x5c000000    0x00001000  >;
+								interrupts = < 0x0000001b  >;
+
+							};
+							uart1_0: serial@5c001000 {
+								compatible =  "stericsson,pl011",
+									"arm,primecell" ;
+								arm,primecell-periphid = < 0x00380802  >;
+								reg = < 0x5c001000    0x00001000  >;
+								interrupts = < 0x0000001c  >;
+
+							};
+							uart2_0: serial@5c002000 {
+								compatible =  "stericsson,pl011",
+									"arm,primecell" ;
+								arm,primecell-periphid = < 0x00380802  >;
+								reg = < 0x5c002000    0x00001000  >;
+								interrupts = < 0x0000001d  >;
+
+							};
+
+						};
+
+					};
+					/* pci-pci bridge, bus = 2, dev = 1, function = 0 ; */
+					/* name = Device cc18 */
+					pci@00020800 {
+						compatible =  "pci104a,cc18.0",
+							"pci104a,cc18",
+							"pciclass060400",
+							"pciclass0604" ;
+						reg = < 0x00020800    0x00000000    0x00000000    0x00000000    0x00000100  >;
+						device_type =  "pci" ;
+						#address-cells = < 3 >;
+						#size-cells = < 2 >;
+						bus-range = < 0x00000004    0x00000004  >;
+						ranges = < 0x02020800    0x00000000    0xcec00000    0x02010000    0x00000000    0xcec00000    0x00000000    0x03d00000  >;
+						/* pci device, bus = 4, dev = 0, function = 0 ; */
+						/* name = Device cc06 */
+						pci@02040000 {
+							compatible =  "pci104a,cc06.0",
+								"pci104a,cc06",
+								"pciclass010600",
+								"pciclass0106" ;
+							reg = < 0x02040000    0x00000000    0xd2400000    0x00000000    0x00400000  >;
+							device_type =  "pci" ;
+
+						};
+						/* pci device, bus = 4, dev = 0, function = 1 ; */
+						/* name = Device cc07 */
+						pci@02040100 {
+							compatible =  "pci104a,cc07.0",
+								"pci104a,cc07",
+								"pciclass070000",
+								"pciclass0700" ;
+							reg = < 0x02040100    0x00000000    0xd2000000    0x00000000    0x00400000
+								 0x02040100    0x00000000    0xd1c00000    0x00000000    0x00400000  >;
+							device_type =  "pci" ;
+
+						};
+						/* pci device, bus = 4, dev = 0, function = 2 ; */
+						/* name = Device cc07 */
+						pci@02040200 {
+							compatible =  "pci104a,cc07.0",
+								"pci104a,cc07",
+								"pciclass070000",
+								"pciclass0700" ;
+							reg = < 0x02040200    0x00000000    0xd1800000    0x00000000    0x00400000
+								 0x02040200    0x00000000    0xd1400000    0x00000000    0x00400000  >;
+							device_type =  "pci" ;
+
+						};
+						/* pci device, bus = 4, dev = 0, function = 3 ; */
+						/* name = Device cc07 */
+						pci@02040300 {
+							compatible =  "pci104a,cc07.0",
+								"pci104a,cc07",
+								"pciclass070000",
+								"pciclass0700" ;
+							reg = < 0x02040300    0x00000000    0xd1000000    0x00000000    0x00400000
+								 0x02040300    0x00000000    0xd0c00000    0x00000000    0x00400000  >;
+							device_type =  "pci" ;
+
+						};
+						/* pci device, bus = 4, dev = 0, function = 4 ; */
+						/* name = Device cc07 */
+						pci@02040400 {
+							compatible =  "pci104a,cc07.0",
+								"pci104a,cc07",
+								"pciclass070000",
+								"pciclass0700" ;
+							reg = < 0x02040400    0x00000000    0xd0800000    0x00000000    0x00400000
+								 0x02040400    0x00000000    0xd0400000    0x00000000    0x00400000  >;
+							device_type =  "pci" ;
+
+						};
+						/* pci device, bus = 4, dev = 0, function = 5 ; */
+						/* name = Device cc04 */
+						pci@02040500 {
+							compatible =  "pci104a,cc04.0",
+								"pci104a,cc04",
+								"pciclass070000",
+								"pciclass0700" ;
+							reg = < 0x02040500    0x00000000    0xd0000000    0x00000000    0x00400000
+								 0x02040500    0x00000000    0xcfc00000    0x00000000    0x00400000  >;
+							device_type =  "pci" ;
+
+						};
+						/* pci device, bus = 4, dev = 0, function = 6 ; */
+						/* name = Device cc14 */
+						pci@02040600 {
+							compatible =  "pci104a,cc14.0",
+								"pci104a,cc14",
+								"pciclass088000",
+								"pciclass0880" ;
+							reg = < 0x02040600    0x00000000    0xcf800000    0x00000000    0x00400000
+								 0x02040600    0x00000000    0xcf400000    0x00000000    0x00400000  >;
+							device_type =  "pci" ;
+
+						};
+						/* pci device, bus = 4, dev = 0, function = 7 ; */
+						/* name = Device cc12 */
+						pci@02040700 {
+							compatible =  "pci104a,cc12.0",
+								"pci104a,cc12",
+								"pciclass070000",
+								"pciclass0700" ;
+							reg = < 0x02040700    0x00000000    0xcf000000    0x00000000    0x00400000
+								 0x02040700    0x00000000    0xcec00000    0x00000000    0x00400000  >;
+							device_type =  "pci" ;
+
+						};
+						amba@00020800 {
+							compatible =  "arm,amba-bus" ;
+							#address-cells = < 1 >;
+							#size-cells = < 1 >;
+							#interrupt-cells = < 1 >;
+							interrupt-map = < 0x5c003000    0x0000001e    &msi    0xfee03000    0x00000000  >;
+							ranges = < 0x5c003000    0x02040500    0x00000000    0xd0000000    0x00001000  >;
+							uart3_0: serial@5c003000 {
+								compatible =  "stericsson,pl011",
+									"arm,primecell" ;
+								arm,primecell-periphid = < 0x00380802  >;
+								reg = < 0x5c003000    0x00001000  >;
+								interrupts = < 0x0000001e  >;
+
+							};
+
+						};
+
+					};
+					/* pci-pci bridge, bus = 2, dev = 2, function = 0 ; */
+					/* name = Device cc18 */
+					pci@00021000 {
+						compatible =  "pci104a,cc18.0",
+							"pci104a,cc18",
+							"pciclass060400",
+							"pciclass0604" ;
+						reg = < 0x00021000    0x00000000    0x00000000    0x00000000    0x00000100  >;
+						device_type =  "pci" ;
+						#address-cells = < 3 >;
+						#size-cells = < 2 >;
+						bus-range = < 0x00000005    0x00000005  >;
+						ranges = < 0x02021000    0x00000000    0xc6400000    0x02010000    0x00000000    0xc6400000    0x00000000    0x04000000  >;
+						/* pci device, bus = 5, dev = 0, function = 0 ; */
+						/* name = Device cc16 */
+						pci@02050000 {
+							compatible =  "pci104a,cc16.0",
+								"pci104a,cc16",
+								"pciclass088000",
+								"pciclass0880" ;
+							reg = < 0x02050000    0x00000000    0xca000000    0x00000000    0x00400000
+								 0x02050000    0x00000000    0xc9c00000    0x00000000    0x00400000  >;
+							device_type =  "pci" ;
+
+						};
+						/* pci device, bus = 5, dev = 0, function = 1 ; */
+						/* name = Device cc0a */
+						pci@02050100 {
+							compatible =  "pci104a,cc0a.0",
+								"pci104a,cc0a",
+								"pciclass088000",
+								"pciclass0880" ;
+							reg = < 0x02050100    0x00000000    0xc9800000    0x00000000    0x00400000
+								 0x02050100    0x00000000    0xc9400000    0x00000000    0x00400000  >;
+							device_type =  "pci" ;
+
+						};
+						/* pci device, bus = 5, dev = 0, function = 2 ; */
+						/* name = Device cc0b */
+						pci@02050200 {
+							compatible =  "pci104a,cc0b.0",
+								"pci104a,cc0b",
+								"pciclass088000",
+								"pciclass0880" ;
+							reg = < 0x02050200    0x00000000    0xc9000000    0x00000000    0x00400000
+								 0x02050200    0x00000000    0xc8c00000    0x00000000    0x00400000  >;
+							device_type =  "pci" ;
+
+						};
+						/* pci device, bus = 5, dev = 0, function = 3 ; */
+						/* name = Device cc0b */
+						pci@02050300 {
+							compatible =  "pci104a,cc0b.0",
+								"pci104a,cc0b",
+								"pciclass088000",
+								"pciclass0880" ;
+							reg = < 0x02050300    0x00000000    0xc8800000    0x00000000    0x00400000
+								 0x02050300    0x00000000    0xc8400000    0x00000000    0x00400000  >;
+							device_type =  "pci" ;
+
+						};
+						/* pci device, bus = 5, dev = 0, function = 4 ; */
+						/* name = Device cc0b */
+						pci@02050400 {
+							compatible =  "pci104a,cc0b.0",
+								"pci104a,cc0b",
+								"pciclass088000",
+								"pciclass0880" ;
+							reg = < 0x02050400    0x00000000    0xc8000000    0x00000000    0x00400000
+								 0x02050400    0x00000000    0xc7c00000    0x00000000    0x00400000  >;
+							device_type =  "pci" ;
+
+						};
+						/* pci device, bus = 5, dev = 0, function = 5 ; */
+						/* name = Device cc15 */
+						pci@02050500 {
+							compatible =  "pci104a,cc15.0",
+								"pci104a,cc15",
+								"pciclass088000",
+								"pciclass0880" ;
+							reg = < 0x02050500    0x00000000    0xc7800000    0x00000000    0x00400000
+								 0x02050500    0x00000000    0xc7400000    0x00000000    0x00400000  >;
+							device_type =  "pci" ;
+
+						};
+						/* pci device, bus = 5, dev = 0, function = 6 ; */
+						/* name = Device cc09 */
+						pci@02050600 {
+							compatible =  "pci104a,cc09.0",
+								"pci104a,cc09",
+								"pciclass020000",
+								"pciclass0200" ;
+							reg = < 0x02050600    0x00000000    0xc7000000    0x00000000    0x00400000
+								 0x02050600    0x00000000    0xc6c00000    0x00000000    0x00400000  >;
+							device_type =  "pci" ;
+
+						};
+						/* pci device, bus = 5, dev = 0, function = 7 ; */
+						/* name = Device cc11 */
+						pci@02050700 {
+							compatible =  "pci104a,cc11.0",
+								"pci104a,cc11",
+								"pciclass070000",
+								"pciclass0700" ;
+							reg = < 0x02050700    0x00000000    0xc6800000    0x00000000    0x00400000
+								 0x02050700    0x00000000    0xc6400000    0x00000000    0x00400000  >;
+							device_type =  "pci" ;
+
+						};
+						amba@00021000 {
+							compatible =  "arm,amba-bus" ;
+							#address-cells = < 1 >;
+							#size-cells = < 1 >;
+							#interrupt-cells = < 1 >;
+							interrupt-map = < 0x5800b000    0xffffffff    &msi    0xfee03000    0x00000000
+								 0x54001000    0x00000010    &msi    0xfee03000    0x00000000
+								 0x54000000    0x00000011    &msi    0xfee03000    0x00000000
+								 0x58004000    0x00000012    &msi    0xfee03000    0x00000000
+								 0x5c004000    0x00000013    &msi    0xfee03000    0x00000000
+								 0x80000000    0xffffffff    &msi    0xfee03000    0x00000000  >;
+							ranges = < 0x5800b000    0x02050000    0x00000000    0xc9c00000    0x00001000
+								 0x54001000    0x02050100    0x00000000    0xc9800000    0x00001000
+								 0x54000000    0x02050200    0x00000000    0xc9000000    0x00001000
+								 0x58004000    0x02050300    0x00000000    0xc8800000    0x00001000
+								 0x5c004000    0x02050400    0x00000000    0xc8000000    0x00001000
+								 0x80000000    0x02050500    0x00000000	   0xc7800000    0x00010000 >;
+							sdio1_0: mmc@54000000 {
+								compatible =  "stericsson, pl180-ux500v2",
+									"arm,primecell" ;
+								arm,primecell-periphid = < 0x10480180  >;
+								reg = < 0x54000000    0x00001000  >;
+								interrupts = < 0x00000011  >;
+								bus-width=<4>;
+								/* Test at 2MHz */
+								max-frequency=<2000000>;
+								/* CD -> GPIO 124 -> GPIO3 PIN 28 */
+								cd-gpios = <&gpio3_0 28 0x1>;
+								cd-inverted;
+								/* WP -> GPIO 123 -> GPIO3 PIN 27 */
+								wp-gpios = <&gpio3_0 27 0>;
+								wp-inverted;
+								pinctrl-names = "default";
+								pinctrl-0 = <&sdio1_default_mux>, <&sdio1_default_mode>;
+							};
+							sdio0_0: mmc@54001000 {
+								compatible =  "stericsson, pl180-ux500v2",
+									"arm,primecell" ;
+								arm,primecell-periphid = < 0x10480180  >;
+								reg = < 0x54001000    0x00001000  >;
+								interrupts = < 0x00000010  >;
+
+							};
+							sdio2_0: mmc@58004000 {
+								compatible =  "stericsson, pl180-ux500v2",
+									"arm,primecell" ;
+								arm,primecell-periphid = < 0x10480180  >;
+								reg = < 0x58004000    0x00001000  >;
+								interrupts = < 0x00000012  >;
+
+							};
+							apb_soc_regs_0: apb-soc-regs@5800b000 {
+								compatible =  "st,sta2x11-apb-soc-regs" ;
+								reg = < 0x5800b000    0x00001000  >;
+
+							};
+							sdio3_0: mmc@5c004000 {
+								compatible =  "stericsson, pl180-ux500v2",
+									"arm,primecell" ;
+								arm,primecell-periphid = < 0x10480180  >;
+								reg = < 0x5c004000    0x00001000  >;
+								interrupts = < 0x00000013  >;
+
+							};
+							esram_0: esram@80000000 {
+								compatible =  "mmio-sram" ;
+								reg = < 0x80000000    0x00010000  >;
+
+							};
+
+						};
+
+					};
+					/* pci-pci bridge, bus = 2, dev = 3, function = 0 ; */
+					/* name = Device cc18 */
+					pci@00021800 {
+						compatible =  "pci104a,cc18.0",
+							"pci104a,cc18",
+							"pciclass060400",
+							"pciclass0604" ;
+						reg = < 0x00021800    0x00000000    0x00000000    0x00000000    0x00000100  >;
+						device_type =  "pci" ;
+						#address-cells = < 3 >;
+						#size-cells = < 2 >;
+						bus-range = < 0x00000006    0x00000006  >;
+						ranges = < 0x02021800    0x00000000    0xc0000000    0x02010000    0x00000000    0xc0000000    0x00000000    0x06000000  >;
+						/* pci device, bus = 6, dev = 0, function = 0 ; */
+						/* name = Device cc0d */
+						pci@02060000 {
+							compatible =  "pci104a,cc0d.0",
+								"pci104a,cc0d",
+								"pciclass040000",
+								"pciclass0400" ;
+							reg = < 0x02060000    0x00000000    0xc5c00000    0x00000000    0x00400000
+								 0x02060000    0x00000000    0xc5800000    0x00000000    0x00400000  >;
+							device_type =  "pci" ;
+
+						};
+						/* pci device, bus = 6, dev = 0, function = 1 ; */
+						/* name = Device cc13 */
+						pci@02060100 {
+							compatible =  "pci104a,cc13.0",
+								"pci104a,cc13",
+								"pciclass038000",
+								"pciclass0380" ;
+							reg = < 0x02060100    0x00000000    0xc5400000    0x00000000    0x00400000
+								 0x02060100    0x00000000    0xc5000000    0x00000000    0x00400000  >;
+							device_type =  "pci" ;
+
+						};
+						/* pci device, bus = 6, dev = 0, function = 2 ; */
+						/* name = Device cc08 */
+						pci@02060200 {
+							compatible =  "pci104a,cc08.0",
+								"pci104a,cc08",
+								"pciclass070000",
+								"pciclass0700" ;
+							reg = < 0x02060200    0x00000000    0xc4c00000    0x00000000    0x00400000
+								 0x02060200    0x00000000    0xc4800000    0x00000000    0x00400000  >;
+							device_type =  "pci" ;
+
+						};
+						/* pci device, bus = 6, dev = 0, function = 3 ; */
+						/* name = Device cc08 */
+						pci@02060300 {
+							compatible =  "pci104a,cc08.0",
+								"pci104a,cc08",
+								"pciclass070000",
+								"pciclass0700" ;
+							reg = < 0x02060300    0x00000000    0xc4400000    0x00000000    0x00400000
+								 0x02060300    0x00000000    0xc4000000    0x00000000    0x00400000  >;
+							device_type =  "pci" ;
+
+						};
+						/* pci device, bus = 6, dev = 0, function = 4 ; */
+						/* name = Device cc08 */
+						pci@02060400 {
+							compatible =  "pci104a,cc08.0",
+								"pci104a,cc08",
+								"pciclass070000",
+								"pciclass0700" ;
+							reg = < 0x02060400    0x00000000    0xc3c00000    0x00000000    0x00400000
+								 0x02060400    0x00000000    0xc3800000    0x00000000    0x00400000  >;
+							device_type =  "pci" ;
+
+						};
+						/* pci device, bus = 6, dev = 0, function = 5 ; */
+						/* name = Device cc0e */
+						pci@02060500 {
+							compatible =  "pci104a,cc0e.0",
+								"pci104a,cc0e",
+								"pciclass080100",
+								"pciclass0801" ;
+							reg = < 0x02060500    0x00000000    0xc3400000    0x00000000    0x00400000
+								 0x02060500    0x00000000    0xc3000000    0x00000000    0x00400000  >;
+							device_type =  "pci" ;
+
+						};
+						/* pci device, bus = 6, dev = 0, function = 6 ; */
+						/* name = Device cc0f */
+						pci@02060600 {
+							compatible =  "pci104a,cc0f.0",
+								"pci104a,cc0f",
+								"pciclass040100",
+								"pciclass0401" ;
+							reg = < 0x02060600    0x00000000    0xc2c00000    0x00000000    0x00400000
+								 0x02060600    0x00000000    0xc2800000    0x00000000    0x00400000
+								 0x02060600    0x00000000    0xc2400000    0x00000000    0x00400000
+								 0x02060600    0x00000000    0xc2000000    0x00000000    0x00400000
+								 0x02060600    0x00000000    0xc1c00000    0x00000000    0x00400000
+								 0x02060600    0x00000000    0xc1800000    0x00000000    0x00400000  >;
+							device_type =  "pci" ;
+
+						};
+						/* pci device, bus = 6, dev = 0, function = 7 ; */
+						/* name = Device cc10 */
+						pci@02060700 {
+							compatible =  "pci104a,cc10.0",
+								"pci104a,cc10",
+								"pciclass040100",
+								"pciclass0401" ;
+							reg = < 0x02060700    0x00000000    0xc1400000    0x00000000    0x00400000
+								 0x02060700    0x00000000    0xc1000000    0x00000000    0x00400000
+								 0x02060700    0x00000000    0xc0c00000    0x00000000    0x00400000
+								 0x02060700    0x00000000    0xc0800000    0x00000000    0x00400000
+								 0x02060700    0x00000000    0xc0400000    0x00000000    0x00400000
+								 0x02060700    0x00000000    0xc0000000    0x00000000    0x00400000  >;
+							device_type =  "pci" ;
+
+						};
+						amba@00021800 {
+							compatible =  "arm,amba-bus" ;
+							#address-cells = < 1 >;
+							#size-cells = < 1 >;
+							#interrupt-cells = < 1 >;
+							interrupt-map = < 0x54002000    0x0000000e    &msi    0xfee03000    0x00000000
+								 0x54003000    0x0000000f    &msi    0xfee03000    0x00000000
+								 0x54004000    0x00000010    &msi    0xfee03000    0x00000000
+								 0x30000000    0x00000011    &msi    0xfee03000    0x00000000  >;
+							ranges = < 0x54002000    0x02060200    0x00000000    0xc4c00000    0x00001000
+								 0x54003000    0x02060300    0x00000000    0xc4400000    0x00001000
+								 0x54004000    0x02060400    0x00000000    0xc3c00000    0x00001000
+								 0x30000000    0x02060500    0x00000000    0xc3400000    0x00001000  >;
+							audio_dma_0: dma-controller@30000000 {
+								compatible =  "stericsson,pl080-nomadik",
+									"arm,primecell" ;
+								arm,primecell-periphid = < 0x00280080  >;
+								reg = < 0x30000000    0x00001000  >;
+								interrupts = < 0x00000007  >;
+
+							};
+							spi0_0: ssp@54002000 {
+								compatible =  "stericsson,pl023",
+									"arm,primecell" ;
+								arm,primecell-periphid = < 0x00080023  >;
+								reg = < 0x54002000    0x00001000  >;
+								interrupts = < 0x0000000e  >;
+
+							};
+							spi1_0: ssp@54003000 {
+								compatible =  "stericsson,pl023",
+									"arm,primecell" ;
+								arm,primecell-periphid = < 0x00080023  >;
+								reg = < 0x54003000    0x00001000  >;
+								interrupts = < 0x0000000f  >;
+
+							};
+							spi2_0: ssp@54004000 {
+								compatible =  "stericsson,pl023",
+									"arm,primecell" ;
+								arm,primecell-periphid = < 0x00080023  >;
+								reg = < 0x54004000    0x00001000  >;
+								interrupts = < 0x00000010  >;
+
+							};
+
+						};
+
+					};
+
+				};
+
+			};
+			/* pci-pci bridge, bus = 0, dev = 24, function = 0 ; */
+			/* name = Atom Processor E6xx PCI Express Port 2 */
+			pci@0000c000 {
+				compatible =  "pci8086,8185.2",
+					"pci8086,8185",
+					"pciclass060400",
+					"pciclass0604" ;
+				reg = < 0x0000c000    0x00000000    0x00000000    0x00000000    0x00000100  >;
+				device_type =  "pci" ;
+				#address-cells = < 3 >;
+				#size-cells = < 2 >;
+				bus-range = < 0x00000007    0x00000007  >;
+				ranges = < 0x0200c000    0x00000000    0x40800000    0x02000000    0x00000000    0x40800000    0x00000000    0x00200000  >;
+
+			};
+			/* pci-pci bridge, bus = 0, dev = 25, function = 0 ; */
+			/* name = Atom Processor E6xx PCI Express Port 3 */
+			pci@0000c800 {
+				compatible =  "pci8086,8180.2",
+					"pci8086,8180",
+					"pciclass060400",
+					"pciclass0604" ;
+				reg = < 0x0000c800    0x00000000    0x00000000    0x00000000    0x00000100  >;
+				device_type =  "pci" ;
+				#address-cells = < 3 >;
+				#size-cells = < 2 >;
+				bus-range = < 0x00000008    0x00000008  >;
+				ranges = < 0x0200c800    0x00000000    0x40400000    0x02000000    0x00000000    0x40400000    0x00000000    0x00200000  >;
+
+			};
+			/* pci-pci bridge, bus = 0, dev = 26, function = 0 ; */
+			/* name = Atom Processor E6xx PCI Express Port 4 */
+			pci@0000d000 {
+				compatible =  "pci8086,8181.2",
+					"pci8086,8181",
+					"pciclass060400",
+					"pciclass0604" ;
+				reg = < 0x0000d000    0x00000000    0x00000000    0x00000000    0x00000100  >;
+				device_type =  "pci" ;
+				#address-cells = < 3 >;
+				#size-cells = < 2 >;
+				bus-range = < 0x00000009    0x00000009  >;
+				ranges = < 0x0200d000    0x00000000    0x40000000    0x02000000    0x00000000    0x40000000    0x00000000    0x00200000  >;
+
+			};
+			/* pci device, bus = 0, dev = 27, function = 0 ; */
+			/* name = System Controller Hub (SCH Poulsbo) HD Audio Controller */
+			pci@0200d800 {
+				compatible =  "pci8086,811b.2",
+					"pci8086,811b",
+					"pciclass040300",
+					"pciclass0403" ;
+				reg = < 0x0200d800    0x00000000    0xd2c00000    0x00000000    0x00004000  >;
+				device_type =  "pci" ;
+
+			};
+			/* pci device, bus = 0, dev = 31, function = 0 ; */
+			/* name = Atom Processor E6xx LPC Bridge */
+			pci@0000f800 {
+				compatible =  "pci8086,8186.2",
+					"pci8086,8186",
+					"pciclass060100",
+					"pciclass0601" ;
+				reg = < 0x0000f800    0x00000000    0x00000000    0x00000000    0x00000100  >;
+				device_type =  "pci" ;
+
+			};
+
+		};
+		interrupt-controller@0xfec00000 {
+			compatible =  "intel,e6600-ioapic",
+				"intel,ioapic" ;
+			reg = < 0xfec00000    0x00000040  >;
+			interrupt-controller;
+
+		};
+		timer@0xfed00000 {
+			compatible =  "intel,e6600-hpet",
+				"intel,hpet" ;
+			reg = < 0xfed00000    0x00000400  >;
+
+		};
+		interrupt-controller@0xfee00000 {
+			compatible =  "intel,e6600-lapic",
+				"intel,lapic" ;
+			reg = < 0xfee00000    0x00001000  >;
+
+		};
+		msi: interrupt-controller@0xfee03000 {
+			compatible =  "intel,msi-irqs" ;
+			interrupt-controller;
+			#interrupt-cells = < 1 >;
+			#address-cells = < 1 >;
+			reg = < 0xfee03000    0x00001000  >;
+
+		};
+
+	};
+
+};
Signature · 1 line
1.7.7.2
#26 lore raw

PATCH 25/26 drivers/clk: sta2x11 common clock framework implementation

In reply to Alessandro Rubini

This patch was submitted as RFC on June 20th 2012 (see
https://lkml.org/lkml/2012/6/20/779 for more details) and resubmitted on March 8th 2013 (see
https://lkml.org/lkml/2013/3/8/245 for more details).

This is a new version which:

* Gets rid of the platform bus notifier replacing it with a platform driver for the "virtual" sta2x11-clock-regs" device, which is created when three of the sta2x11 basic platform devices (sta2x11-sctl, sta2x11-apbreg and sta2x11-apb-soc-regs) have been probed.

* Adds some more clocks (gpios, sdio/mmc, spi, i2c, dma). Clocks still have to be improved because not all the details have been modeled (for instance mmc clocks are actually muxed clocks, not fixed factor).

---
 arch/x86/Kconfig                    |    1 +
 drivers/clk/Makefile                |    1 +
 drivers/clk/sta2x11/Makefile        |    1 +
 drivers/clk/sta2x11/clk-audio-pll.c |  149 ++++++
 drivers/clk/sta2x11/clk-soc-pll.c   |   95 ++++
 drivers/clk/sta2x11/clk.c           |  865 +++++++++++++++++++++++++++++++++++
 drivers/clk/sta2x11/clk.h           |   88 ++++
 7 files changed, 1200 insertions(+), 0 deletions(-)
 create mode 100644 drivers/clk/sta2x11/Makefile
 create mode 100644 drivers/clk/sta2x11/clk-audio-pll.c
 create mode 100644 drivers/clk/sta2x11/clk-soc-pll.c
 create mode 100644 drivers/clk/sta2x11/clk.c
 create mode 100644 drivers/clk/sta2x11/clk.h
arch/x86/Kconfig +1 -0
index ae05df92..fed3507 100644
@@ -551,6 +551,7 @@ config STA2X11
 	depends on X86_32_NON_STANDARD && PCI
 	select X86_DEV_DMA_OPS
 	select X86_DMA_REMAP
+	select COMMON_CLK
 	select SWIOTLB
 	select MFD_STA2X11
 	select ARCH_REQUIRE_GPIOLIB
drivers/clk/Makefile +1 -0
index 4038c2b..d2b7693 100644
@@ -34,6 +34,7 @@ obj-$(CONFIG_ARCH_TEGRA)	+= tegra/
 obj-$(CONFIG_PLAT_SAMSUNG)	+= samsung/
 
 obj-$(CONFIG_X86)		+= x86/
+obj-$(CONFIG_STA2X11)		+= sta2x11/
 
 # Chip specific
 obj-$(CONFIG_COMMON_CLK_AXI_CLKGEN) += clk-axi-clkgen.o
drivers/clk/sta2x11/Makefile new file +1 -0
new file mode 100644
index 0000000..60c319a
@@ -0,0 +1 @@
+obj-$(CONFIG_STA2X11) += clk.o clk-soc-pll.o clk-audio-pll.o
drivers/clk/sta2x11/clk-audio-pll.c new file +149 -0

149 lines not on this page · raw message

drivers/clk/sta2x11/clk-soc-pll.c new file +95 -0

95 lines not on this page · raw message

drivers/clk/sta2x11/clk.c new file +865 -0

865 lines not on this page · raw message

drivers/clk/sta2x11/clk.h new file +88 -0

88 lines not on this page · raw message

Signature · 1 line
1.7.7.2
#27 lore raw

PATCH 26/26 pinctrl: add support for sta2x11 (via pinctrl-nomadik)

In reply to Alessandro Rubini
---
 .../devicetree/bindings/pinctrl/ste,nomadik.txt    |    2 +-
 drivers/pinctrl/Kconfig                            |    6 +-
 drivers/pinctrl/Makefile                           |    1 +
 drivers/pinctrl/pinctrl-nomadik-sta2x11.c          |  578 ++++++++++++++++++++
 drivers/pinctrl/pinctrl-nomadik.c                  |    7 +
 drivers/pinctrl/pinctrl-nomadik.h                  |   14 +
 6 files changed, 606 insertions(+), 2 deletions(-)
 create mode 100644 drivers/pinctrl/pinctrl-nomadik-sta2x11.c
Documentation/devicetree/bindings/pinctrl/ste,nomadik.txt +1 -1
index 9a2f3f4..3361894 100644
@@ -2,7 +2,7 @@ ST Ericsson Nomadik pinmux controller
 
 Required properties:
 - compatible: "stericsson,nmk-pinctrl", "stericsson,nmk-pinctrl-db8540",
-              "stericsson,nmk-pinctrl-stn8815"
+              "stericsson,nmk-pinctrl-stn8815", "stericsson,nmk-pinctrl-sta2x11"
 - reg: Should contain the register physical address and length of the PRCMU.
 
 Please refer to pinctrl-bindings.txt in this directory for details of the
drivers/pinctrl/Kconfig +5 -1
index bc830af..be2977f 100644
@@ -154,7 +154,7 @@ config PINCTRL_IMX28
 
 config PINCTRL_NOMADIK
 	bool "Nomadik pin controller driver"
-	depends on ARCH_U8500 || ARCH_NOMADIK
+	depends on ARCH_U8500 || ARCH_NOMADIK || STA2X11
 	select PINMUX
 	select PINCONF
 
@@ -176,6 +176,10 @@ config PINCTRL_ROCKCHIP
 	select GENERIC_PINCONF
 	select GENERIC_IRQ_CHIP
 
+config PINCTRL_STA2X11
+       bool "STA2X11 pin controller driver"
+       depends on PINCTRL_NOMADIK && STA2X11
+
 config PINCTRL_SINGLE
 	tristate "One-register-per-pin type device tree based pinctrl driver"
 	depends on OF
drivers/pinctrl/Makefile +1 -0
index d64563bf..24efd71 100644
@@ -32,6 +32,7 @@ obj-$(CONFIG_PINCTRL_NOMADIK)	+= pinctrl-nomadik.o
 obj-$(CONFIG_PINCTRL_STN8815)	+= pinctrl-nomadik-stn8815.o
 obj-$(CONFIG_PINCTRL_DB8500)	+= pinctrl-nomadik-db8500.o
 obj-$(CONFIG_PINCTRL_DB8540)	+= pinctrl-nomadik-db8540.o
+obj-$(CONFIG_PINCTRL_STA2X11)	+= pinctrl-nomadik-sta2x11.o
 obj-$(CONFIG_PINCTRL_ROCKCHIP)	+= pinctrl-rockchip.o
 obj-$(CONFIG_PINCTRL_SINGLE)	+= pinctrl-single.o
 obj-$(CONFIG_PINCTRL_SIRF)	+= sirf/
drivers/pinctrl/pinctrl-nomadik-sta2x11.c new file +578 -0

578 lines not on this page · raw message

drivers/pinctrl/pinctrl-nomadik.c +7 -0
index 97fb020..d7d4b592 100644
@@ -2131,6 +2131,10 @@ static const struct of_device_id nmk_pinctrl_match[] = {
 		.compatible = "stericsson,db8540-pinctrl",
 		.data = (void *)PINCTRL_NMK_DB8540,
 	},
+	{
+		.compatible = "stericsson,nmk-pinctrl-sta2x11",
+		.data = (void *)PINCTRL_NMK_STA2X11,
+	},
 	{},
 };
 
@@ -2188,6 +2192,8 @@ static int nmk_pinctrl_probe(struct platform_device *pdev)
 		nmk_pinctrl_db8500_init(&npct->soc);
 	if (version == PINCTRL_NMK_DB8540)
 		nmk_pinctrl_db8540_init(&npct->soc);
+	if (version == PINCTRL_NMK_STA2X11)
+		nmk_pinctrl_sta2x11_init(&npct->soc);
 
 	if (np) {
 		prcm_np = of_parse_phandle(np, "prcm", 0);
@@ -2262,6 +2268,7 @@ static const struct platform_device_id nmk_pinctrl_id[] = {
 	{ "pinctrl-stn8815", PINCTRL_NMK_STN8815 },
 	{ "pinctrl-db8500", PINCTRL_NMK_DB8500 },
 	{ "pinctrl-db8540", PINCTRL_NMK_DB8540 },
+	{ "pinctrl-sta2x11", PINCTRL_NMK_STA2X11 },
 	{ }
 };
 
drivers/pinctrl/pinctrl-nomadik.h +14 -0
index bcd4191..8b072f8 100644
@@ -7,6 +7,7 @@
 #define PINCTRL_NMK_STN8815	0
 #define PINCTRL_NMK_DB8500	1
 #define PINCTRL_NMK_DB8540	2
+#define PINCTRL_NMK_STA2X11	3
 
 #define PRCM_GPIOCR_ALTCX(pin_num,\
 	altc1_used, altc1_ri, altc1_cb,\
@@ -179,4 +180,17 @@ nmk_pinctrl_db8540_init(const struct nmk_pinctrl_soc_data **soc)
 
 #endif
 
+#ifdef CONFIG_PINCTRL_STA2X11
+
+void nmk_pinctrl_sta2x11_init(const struct nmk_pinctrl_soc_data **soc);
+
+#else
+
+static inline void
+nmk_pinctrl_sta2x11_init(const struct nmk_pinctrl_soc_data **soc)
+{
+}
+
+#endif
+
 #endif /* PINCTRL_PINCTRL_NOMADIK_H */
Signature · 1 line
1.7.7.2
Acked-by on v1 26/26
#28 lore raw

Re: [PATCH 26/26] pinctrl: add support for sta2x11 (via pinctrl-nomadik)

Quoted 2 lines · Davide Ciminaghi

Maybe you could add a commit message?

Apart from that it looks like a straight-forward plug-in to the Nomadik pin controller, so I'd happily apply it, but I guess it will go in through the x86 tree?

Yours,
Linus Walleij

#29 lore raw

Re: [PATCH 26/26] pinctrl: add support for sta2x11 (via pinctrl-nomadik)

Quoted 1 line

Maybe you could add a commit message?

Ack (Davide is holidays, I grant that for him).

Quoted 3 lines

Apart from that it looks like a straight-forward plug-in to the Nomadik pin controller, so I'd happily apply it, but I guess it will go in through the x86 tree?

It's part of a bigger series, that adds devicetree support first. Yes, it's expected to go through a different path, if the whole series is ok.

Quoted 1 line

Thanks for this and the gpio acked-by -- yes, I didn't notice it's a nomadik logic block; it's Davide who tried to match the registers.

/alessandro

#30 lore raw
In reply to Alessandro Rubini
Quoted 26 lines · Alessandro Rubini

Some of the problems he found are:

* Passing a dtb to the kernel: we use a modified kexec at present because x86 boot loaders can't pass the DT blob, to our knowledge.

* Passing correct irq numbers to the AMBA drivers, because PCI MSI irq numbers are dynamically allocated (we solved this by using of_update_property() at runtime). We also had to register a new irq domain for msi irqs, otherwise of_irq_map_one() would complain about irqs lacking a corresponding domain.

* Switching to a new gpio driver with devicetree support (we took the Nomadik gpio/pinctrl because our device apparently has more or less the same gpio cell as the Nomadik chip). This requires implementation of writel_relaxed() and IRQF_VALID on x86: we hacked them internally but the patches are not part of this set. We're willing to solve these incompatibilities first, if there's interest.

* Writing a suitable dts: at present, a dts only exists for one of the STA2X11 based boards (Intel Northville). This includes a copy of all the physical addresses for the devices, as dts requires that, even if such addresses are automatically assigned by PCI. Clearly, with this approach we kill PCI autodetect: if you plug to a different slot you need a different dts.

Quoted 6 lines

This got us a more or less working kernel on the Northville board (where the device is soldered on the motherboard and acts as main chipset). The plug-in PCIe board cannot be supported by device tree, as far as we know, which in our opinion is a strong downside of device tree in favor of the platform data "shit".

OK, so we have a real corner case here... which is a plugin board beyond which sits a bus normally used by fixed devices. You are definitely correct that this is something that stresses current means of description to the breaking point.

*Note there are some questions below that I would perfectly understand if you can't talk about publicly, if so, please contact me privately at my corporate address.*

However, the plugin board is very different from it being the main chipset, in no small part because you can boot without it. I think this is the first time I have ever heard of a chip which can act both as a system chipset and a plugin card.

The mainboard case is relatively straightforward -- we should use ACPI 5 (preferred for x86) or device tree to describe it. My understanding from what you describe so far is that the only existing case is the Northville which is a mainboard.

For the plugin case, my thinking is that we probably do need a driver of some kind which at least contains the description of the board, as I assume one is not present in any kind of firmware on the board itself (*do any such boards or plans for them actually exist at this point?*) Ideally that driver should be (primarily?) a data object (an ACPI 5 SSDT or a DTB file) rather than open coded C.

I believe ACPI 5 unlike device tree should be able to specify the dynamic properties that you are rightfully concerned with.

Sorry if this feels like a wild goose chase to you. Some of this problem domain is not very well handled by the current code, but we really have to draw a hard line to make sure it doesn't descend into unmaintainable chaos.

We have similar issues with MinnowBoard and are trying to use that as a platform to figure out how a lot of these things need to be handled.

-hpa

#31 lore raw

[stripped list of issues from my original message follows]

Quoted 8 lines
Quoted 7 lines

Some of the problems he found are:

* Passing a dtb to the kernel: we use a modified kexec at present
* Passing correct irq numbers to the AMBA drivers
* Switching to a new gpio driver with devicetree support
* Writing a suitable dts: at present, a dts only exists for one of the STA2X11 based boards (Intel Northville).

Quoted 4 lines

OK, so we have a real corner case here... which is a plugin board beyond which sits a bus normally used by fixed devices. You are definitely correct that this is something that stresses current means of description to the breaking point.

Basically, it's an ARM chip with a PCI interface. So it offers USB, SATA, Eth, i2c, spi, gpio, can etc to the x86 CPU.

Quoted 3 lines

*Note there are some questions below that I would perfectly understand if you can't talk about publicly, if so, please contact me privately at my corporate address.*

Thanks. I'm not aware of any such issues at this point, though.

Quoted 4 lines

However, the plugin board is very different from it being the main chipset, in no small part because you can boot without it. I think this is the first time I have ever heard of a chip which can act both as a system chipset and a plugin card.

The main CPU in the Northville is an Atom, which IIUC has its own memory controller -- and definitely a PCIe controller. The Sta2x11 chip is connected to the PCIe bus, as both a slave and a master. It's a busmaster for SATA, USB and something else, and equipped with a PrimeCell PL080 as DMA engine for UART, I2C, SPI, MMC.

I'm aware it might be the first time this happens, but I also suspect it will be common pretty soon: the industrial world wants I2C, UART, SPI and GPIO, and bridging overt PCI to an external SoC is the right approach, in my opinion.

Quoted 4 lines

The mainboard case is relatively straightforward -- we should use ACPI 5 (preferred for x86) or device tree to describe it. My understanding from what you describe so far is that the only existing case is the Northville which is a mainboard.

There are a pair of such mainboards around, but what we developers only have the Northville at this time.

And the evaluation board, which is a PCIe card. With the previous platform_data-based approach I could plug two of them and access all devices (2 * 4 UART, 2 * 3 I2C etc).

Quoted 4 lines

For the plugin case, my thinking is that we probably do need a driver of some kind which at least contains the description of the board, as I assume one is not present in any kind of firmware on the board itself (*do any such boards or plans for them actually exist at this point?*)

The board exists as an evaluation board. But I see nothing against an industrial-grade commercial offering, to give SPI, CAN and all the rest to PC users that need them, as a single do-it-all cheap board.

Quoted 2 lines

Ideally that driver should be (primarily?) a data object (an ACPI 5 SSDT or a DTB file) rather than open coded C.

Mostly so. It used to be platform data, to register devices for drivers that already exist. Like we did for Ether and CAN: just add the vendor/device pair and PCI support where missing.

Quoted 2 lines

I believe ACPI 5 unlike device tree should be able to specify the dynamic properties that you are rightfully concerned with.

We'll try to get acquainted with that, but my wild guess is that platform data is still simpler. I'm aware of the issues, and I'm not insisting, though.

Quoted 4 lines

Sorry if this feels like a wild goose chase to you. Some of this problem domain is not very well handled by the current code, but we really have to draw a hard line to make sure it doesn't descend into unmaintainable chaos.

I understand. My impression of devicetree is exactly like that, I must say. What we have here is a very clean PCI enumeration of it all: we only need to specify the mapping of GPIO pins (i.e. card-detect for mmc) and DMA channels, as all the rest works by itself.

Quoted 2 lines

We have similar issues with MinnowBoard and are trying to use that as a platform to figure out how a lot of these things need to be handled.

Interesting. I'll take a look. We were looking for a simple PC today and found that very thing as a viable option.

Thank you for your feedback. May I ask three more questions (this is the 1st)?

Is the patch-set a viable approach for mainline, modulo serious evaluation of the hairy IRQ details and the other bits?

Would it make sense to work on devicetree support in x86 bootloaders (especially yours, let's ignore grub)?

thank you again
/alessandro

#32 lore raw
Quoted 4 lines · Alessandro Rubini

Would it make sense to work on devicetree support in x86 bootloaders (especially yours, let's ignore grub)?

No, it's already there. ;)

-hpa

#33 lore raw
In reply to Alessandro Rubini
Quoted 6 lines · Alessandro Rubini

I understand. My impression of devicetree is exactly like that, I must say. What we have here is a very clean PCI enumeration of it all: we only need to specify the mapping of GPIO pins (i.e. card-detect for mmc) and DMA channels, as all the rest works by itself.

Could you elucidate this a bit more? Specifically, from the PCI host's perspective, how do you know what you are dealing with (presumably PCI VID:DID:SVID:SID?) How exactly does the mapping of PCI BARs and INT/MSI/MSI-X channels to the slave device play in?

I think it is safe to say that the device models we have today simply don't account for this kind of usage, which, as you say, is a genuine problem, and I think we need to understand the problem space better in order to properly architect the solution, as I don't think we have one right now.

-hpa

#34 lore raw
In reply to Alessandro Rubini
Quoted 7 lines · Alessandro Rubini

Thank you for your feedback. May I ask three more questions (this is the 1st)?

Is the patch-set a viable approach for mainline, modulo serious evaluation of the hairy IRQ details and the other bits?

Serious evaluation is definitely called for. I think that is all I can say at this point.

When you say that on Northville this acts as "the main chipset". The typical definition of that is the firmware resides there. Is that the case in this platform as well (I am guessing no)? It may sound like splitting hairs but I'm trying to wrap my brain around this platform; it sounds like I might have received a very wrong understanding.

-hpa