All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/4] PCI: add DT bindings for Cortina Gemini PCI Host Bridge
@ 2017-01-28 20:48 ` Linus Walleij
  0 siblings, 0 replies; 64+ messages in thread
From: Linus Walleij @ 2017-01-28 20:48 UTC (permalink / raw)
  To: Hans Ulli Kroll, Florian Fainelli, Bjorn Helgaas
  Cc: openwrt-devel, devicetree, Paulius Zaleckas, linux-pci,
	Janos Laube, linux-arm-kernel

This adds device tree bindings for the Cortina Systems Gemini PCI
Host Bridge.

Cc: Janos Laube <janos.dev@gmail.com>
Cc: Paulius Zaleckas <paulius.zaleckas@gmail.com>
Cc: Hans Ulli Kroll <ulli.kroll@googlemail.com>
Cc: Florian Fainelli <f.fainelli@gmail.com>
Cc: devicetree@vger.kernel.org
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
This can be merged to the PCI tree whenever it is considered
fine for inclusion.
---
 .../devicetree/bindings/pci/cortina,gemini-pci.txt | 64 ++++++++++++++++++++++
 1 file changed, 64 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pci/cortina,gemini-pci.txt

diff --git a/Documentation/devicetree/bindings/pci/cortina,gemini-pci.txt b/Documentation/devicetree/bindings/pci/cortina,gemini-pci.txt
new file mode 100644
index 000000000000..e3090d995e1e
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/cortina,gemini-pci.txt
@@ -0,0 +1,64 @@
+* Cortina Systems Gemini PCI Host Bridge
+
+Mandatory properties:
+
+- compatible: should be "cortina,gemini-pci"
+- reg: memory base and size for the host bridge
+- interrupts: the four PCI interrupts
+- #address-cells: set to <3>
+- #size-cells: set to <2>
+- #interrupt-cells: set to <1>
+- bus-range: set to <0x00 0x00> (only root bus)
+- device_type, set to "pci"
+- ranges: see pci.txt
+- interrupt-map-mask: see pci.txt
+- interrupt-map: see pci.txt
+
+Mandatory subnodes:
+- One node reprenting the interrupt-controller inside the host bridge
+  with the following mandatory properties:
+  - interrupt-controller: see interrupt-controller/interrupts.txt
+  - #address-cells: set to <0>
+  - #interrupt-cells: set to <1>
+
+Example:
+
+pci@50000000 {
+	compatible = "cortina,gemini-pci";
+	reg = <0x50000000 0x100>;
+	interrupts = <8 IRQ_TYPE_LEVEL_HIGH>, /* PCI A */
+			<26 IRQ_TYPE_LEVEL_HIGH>, /* PCI B */
+			<27 IRQ_TYPE_LEVEL_HIGH>, /* PCI C */
+			<28 IRQ_TYPE_LEVEL_HIGH>; /* PCI D */
+	#address-cells = <3>;
+	#size-cells = <2>;
+	#interrupt-cells = <1>;
+
+	bus-range = <0x00 0x00>; /* Only root bus */
+	ranges = /* 1MiB I/O space 0x50000000-0x500fffff */
+		 <0x01000000 0 0          0x50000000 0 0x00100000>,
+		 /* 128MiB non-prefetchable memory 0x58000000-0x5fffffff */
+		 <0x02000000 0 0x58000000 0x58000000 0 0x08000000>;
+	interrupt-map-mask = <0xff00 0 0 7>;
+	interrupt-map = <0x4800 0 0 1 &pci_intc 0>, /* Slot 9 */
+			<0x4900 0 0 2 &pci_intc 1>,
+			<0x4a00 0 0 3 &pci_intc 2>,
+			<0x4b00 0 0 4 &pci_intc 3>,
+			<0x5000 0 0 1 &pci_intc 0>, /* Slot 10 */
+			<0x5100 0 0 2 &pci_intc 1>,
+			<0x5200 0 0 3 &pci_intc 2>,
+			<0x5300 0 0 4 &pci_intc 3>,
+			<0x5800 0 0 1 &pci_intc 0>, /* Slot 11 */
+			<0x5900 0 0 2 &pci_intc 1>,
+			<0x5a00 0 0 3 &pci_intc 2>,
+			<0x5b00 0 0 4 &pci_intc 3>,
+			<0x6000 0 0 1 &pci_intc 0>, /* Slot 12 */
+			<0x6100 0 0 2 &pci_intc 1>,
+			<0x6200 0 0 3 &pci_intc 2>,
+			<0x6300 0 0 4 &pci_intc 3>;
+	pci_intc: interrupt-controller {
+		interrupt-controller;
+		#address-cells = <0>;
+		#interrupt-cells = <1>;
+	};
+};
-- 
2.9.3
_______________________________________________
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel

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

* [PATCH 1/4] PCI: add DT bindings for Cortina Gemini PCI Host Bridge
@ 2017-01-28 20:48 ` Linus Walleij
  0 siblings, 0 replies; 64+ messages in thread
From: Linus Walleij @ 2017-01-28 20:48 UTC (permalink / raw)
  To: Hans Ulli Kroll, Florian Fainelli, Bjorn Helgaas
  Cc: Janos Laube, Paulius Zaleckas, openwrt-devel, linux-arm-kernel,
	linux-pci, Linus Walleij, devicetree

This adds device tree bindings for the Cortina Systems Gemini PCI
Host Bridge.

Cc: Janos Laube <janos.dev@gmail.com>
Cc: Paulius Zaleckas <paulius.zaleckas@gmail.com>
Cc: Hans Ulli Kroll <ulli.kroll@googlemail.com>
Cc: Florian Fainelli <f.fainelli@gmail.com>
Cc: devicetree@vger.kernel.org
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
This can be merged to the PCI tree whenever it is considered
fine for inclusion.
---
 .../devicetree/bindings/pci/cortina,gemini-pci.txt | 64 ++++++++++++++++++++++
 1 file changed, 64 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pci/cortina,gemini-pci.txt

diff --git a/Documentation/devicetree/bindings/pci/cortina,gemini-pci.txt b/Documentation/devicetree/bindings/pci/cortina,gemini-pci.txt
new file mode 100644
index 000000000000..e3090d995e1e
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/cortina,gemini-pci.txt
@@ -0,0 +1,64 @@
+* Cortina Systems Gemini PCI Host Bridge
+
+Mandatory properties:
+
+- compatible: should be "cortina,gemini-pci"
+- reg: memory base and size for the host bridge
+- interrupts: the four PCI interrupts
+- #address-cells: set to <3>
+- #size-cells: set to <2>
+- #interrupt-cells: set to <1>
+- bus-range: set to <0x00 0x00> (only root bus)
+- device_type, set to "pci"
+- ranges: see pci.txt
+- interrupt-map-mask: see pci.txt
+- interrupt-map: see pci.txt
+
+Mandatory subnodes:
+- One node reprenting the interrupt-controller inside the host bridge
+  with the following mandatory properties:
+  - interrupt-controller: see interrupt-controller/interrupts.txt
+  - #address-cells: set to <0>
+  - #interrupt-cells: set to <1>
+
+Example:
+
+pci@50000000 {
+	compatible = "cortina,gemini-pci";
+	reg = <0x50000000 0x100>;
+	interrupts = <8 IRQ_TYPE_LEVEL_HIGH>, /* PCI A */
+			<26 IRQ_TYPE_LEVEL_HIGH>, /* PCI B */
+			<27 IRQ_TYPE_LEVEL_HIGH>, /* PCI C */
+			<28 IRQ_TYPE_LEVEL_HIGH>; /* PCI D */
+	#address-cells = <3>;
+	#size-cells = <2>;
+	#interrupt-cells = <1>;
+
+	bus-range = <0x00 0x00>; /* Only root bus */
+	ranges = /* 1MiB I/O space 0x50000000-0x500fffff */
+		 <0x01000000 0 0          0x50000000 0 0x00100000>,
+		 /* 128MiB non-prefetchable memory 0x58000000-0x5fffffff */
+		 <0x02000000 0 0x58000000 0x58000000 0 0x08000000>;
+	interrupt-map-mask = <0xff00 0 0 7>;
+	interrupt-map = <0x4800 0 0 1 &pci_intc 0>, /* Slot 9 */
+			<0x4900 0 0 2 &pci_intc 1>,
+			<0x4a00 0 0 3 &pci_intc 2>,
+			<0x4b00 0 0 4 &pci_intc 3>,
+			<0x5000 0 0 1 &pci_intc 0>, /* Slot 10 */
+			<0x5100 0 0 2 &pci_intc 1>,
+			<0x5200 0 0 3 &pci_intc 2>,
+			<0x5300 0 0 4 &pci_intc 3>,
+			<0x5800 0 0 1 &pci_intc 0>, /* Slot 11 */
+			<0x5900 0 0 2 &pci_intc 1>,
+			<0x5a00 0 0 3 &pci_intc 2>,
+			<0x5b00 0 0 4 &pci_intc 3>,
+			<0x6000 0 0 1 &pci_intc 0>, /* Slot 12 */
+			<0x6100 0 0 2 &pci_intc 1>,
+			<0x6200 0 0 3 &pci_intc 2>,
+			<0x6300 0 0 4 &pci_intc 3>;
+	pci_intc: interrupt-controller {
+		interrupt-controller;
+		#address-cells = <0>;
+		#interrupt-cells = <1>;
+	};
+};
-- 
2.9.3


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

* [PATCH 1/4] PCI: add DT bindings for Cortina Gemini PCI Host Bridge
@ 2017-01-28 20:48 ` Linus Walleij
  0 siblings, 0 replies; 64+ messages in thread
From: Linus Walleij @ 2017-01-28 20:48 UTC (permalink / raw)
  To: linux-arm-kernel

This adds device tree bindings for the Cortina Systems Gemini PCI
Host Bridge.

Cc: Janos Laube <janos.dev@gmail.com>
Cc: Paulius Zaleckas <paulius.zaleckas@gmail.com>
Cc: Hans Ulli Kroll <ulli.kroll@googlemail.com>
Cc: Florian Fainelli <f.fainelli@gmail.com>
Cc: devicetree at vger.kernel.org
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
This can be merged to the PCI tree whenever it is considered
fine for inclusion.
---
 .../devicetree/bindings/pci/cortina,gemini-pci.txt | 64 ++++++++++++++++++++++
 1 file changed, 64 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pci/cortina,gemini-pci.txt

diff --git a/Documentation/devicetree/bindings/pci/cortina,gemini-pci.txt b/Documentation/devicetree/bindings/pci/cortina,gemini-pci.txt
new file mode 100644
index 000000000000..e3090d995e1e
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/cortina,gemini-pci.txt
@@ -0,0 +1,64 @@
+* Cortina Systems Gemini PCI Host Bridge
+
+Mandatory properties:
+
+- compatible: should be "cortina,gemini-pci"
+- reg: memory base and size for the host bridge
+- interrupts: the four PCI interrupts
+- #address-cells: set to <3>
+- #size-cells: set to <2>
+- #interrupt-cells: set to <1>
+- bus-range: set to <0x00 0x00> (only root bus)
+- device_type, set to "pci"
+- ranges: see pci.txt
+- interrupt-map-mask: see pci.txt
+- interrupt-map: see pci.txt
+
+Mandatory subnodes:
+- One node reprenting the interrupt-controller inside the host bridge
+  with the following mandatory properties:
+  - interrupt-controller: see interrupt-controller/interrupts.txt
+  - #address-cells: set to <0>
+  - #interrupt-cells: set to <1>
+
+Example:
+
+pci at 50000000 {
+	compatible = "cortina,gemini-pci";
+	reg = <0x50000000 0x100>;
+	interrupts = <8 IRQ_TYPE_LEVEL_HIGH>, /* PCI A */
+			<26 IRQ_TYPE_LEVEL_HIGH>, /* PCI B */
+			<27 IRQ_TYPE_LEVEL_HIGH>, /* PCI C */
+			<28 IRQ_TYPE_LEVEL_HIGH>; /* PCI D */
+	#address-cells = <3>;
+	#size-cells = <2>;
+	#interrupt-cells = <1>;
+
+	bus-range = <0x00 0x00>; /* Only root bus */
+	ranges = /* 1MiB I/O space 0x50000000-0x500fffff */
+		 <0x01000000 0 0          0x50000000 0 0x00100000>,
+		 /* 128MiB non-prefetchable memory 0x58000000-0x5fffffff */
+		 <0x02000000 0 0x58000000 0x58000000 0 0x08000000>;
+	interrupt-map-mask = <0xff00 0 0 7>;
+	interrupt-map = <0x4800 0 0 1 &pci_intc 0>, /* Slot 9 */
+			<0x4900 0 0 2 &pci_intc 1>,
+			<0x4a00 0 0 3 &pci_intc 2>,
+			<0x4b00 0 0 4 &pci_intc 3>,
+			<0x5000 0 0 1 &pci_intc 0>, /* Slot 10 */
+			<0x5100 0 0 2 &pci_intc 1>,
+			<0x5200 0 0 3 &pci_intc 2>,
+			<0x5300 0 0 4 &pci_intc 3>,
+			<0x5800 0 0 1 &pci_intc 0>, /* Slot 11 */
+			<0x5900 0 0 2 &pci_intc 1>,
+			<0x5a00 0 0 3 &pci_intc 2>,
+			<0x5b00 0 0 4 &pci_intc 3>,
+			<0x6000 0 0 1 &pci_intc 0>, /* Slot 12 */
+			<0x6100 0 0 2 &pci_intc 1>,
+			<0x6200 0 0 3 &pci_intc 2>,
+			<0x6300 0 0 4 &pci_intc 3>;
+	pci_intc: interrupt-controller {
+		interrupt-controller;
+		#address-cells = <0>;
+		#interrupt-cells = <1>;
+	};
+};
-- 
2.9.3

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

* [PATCH 2/4] PCI: add driver for Cortina Gemini Host Bridge
  2017-01-28 20:48 ` Linus Walleij
@ 2017-01-28 20:48   ` Linus Walleij
  -1 siblings, 0 replies; 64+ messages in thread
From: Linus Walleij @ 2017-01-28 20:48 UTC (permalink / raw)
  To: Hans Ulli Kroll, Florian Fainelli, Bjorn Helgaas
  Cc: Janos Laube, Paulius Zaleckas, openwrt-devel, linux-arm-kernel,
	linux-pci, Linus Walleij

This adds a host bridge driver for the Cortina Systems Gemini
SoC (SL3516) PCI Host Bridge.

This code is inspired by the out-of-tree OpenWRT patch and
then extensively rewritten for device tree and using the modern
helpers to cut down and modernize the code to all new PCI
frameworks.

Tested on the ITian Square One SQ201 NAS with the following
result in the boot log (trimmed to relevant parts):

OF: PCI: host bridge /pci@50000000 ranges:
OF: PCI:    IO 0x50000000..0x500fffff -> 0x00000000
OF: PCI:   MEM 0x58000000..0x5fffffff -> 0x58000000
gemini-pci 50000000.pci: PCI host bridge to bus 0000:00
pci_bus 0000:00: root bus resource [bus 00]
pci_bus 0000:00: root bus resource [io  0x0000-0xfffff]
pci_bus 0000:00: root bus resource [mem 0x58000000-0x5fffffff]
pci 0000:00:00.0: [159b:4321] type 00 class 0x060000
pci 0000:00:09.0: [1106:3038] type 00 class 0x0c0300
pci 0000:00:09.0: reg 0x20: [io  0xfce0-0xfcff]
pci 0000:00:09.0: supports D1 D2
pci 0000:00:09.0: PME# supported from D0 D1 D2 D3hot D3cold
pci 0000:00:09.1: [1106:3038] type 00 class 0x0c0300
pci 0000:00:09.1: reg 0x20: [io  0xfce0-0xfcff]
pci 0000:00:09.1: supports D1 D2
pci 0000:00:09.1: PME# supported from D0 D1 D2 D3hot D3cold
pci 0000:00:09.2: [1106:3104] type 00 class 0x0c0320
pci 0000:00:09.2: reg 0x10: [mem 0x00000000-0x000000ff]
pci 0000:00:09.2: supports D1 D2
pci 0000:00:09.2: PME# supported from D0 D1 D2 D3hot D3cold
pci 0000:00:0c.0: [1814:0301] type 00 class 0x028000
pci 0000:00:0c.0: reg 0x10: [mem 0x58000000-0x58007fff]
PCI: bus0: Fast back to back transfers disabled
gemini-pci 50000000.pci: clear all IRQs
gemini-pci 50000000.pci: setting up PCI DMA
pci 0000:00:00.0: of_irq_parse_pci() failed with rc=-22
pci 0000:00:0c.0: BAR 0: assigned [mem 0x58000000-0x58007fff]
pci 0000:00:09.2: BAR 0: assigned [mem 0x58008000-0x580080ff]
pci 0000:00:09.0: BAR 4: assigned [io  0x0400-0x041f]
pci 0000:00:09.1: BAR 4: assigned [io  0x0420-0x043f]
pci 0000:00:09.0: enabling device (0140 -> 0141)
pci 0000:00:09.0: HCRESET not completed yet!
pci 0000:00:09.1: enabling device (0140 -> 0141)
pci 0000:00:09.1: HCRESET not completed yet!
pci 0000:00:09.2: enabling device (0140 -> 0142)
ieee80211 phy0: rt2x00_set_chip: Info - Chipset detected - rt: 2561, rf: 0003, rev: 000c
ieee80211 phy0: Selected rate control algorithm 'minstrel_ht'
ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
ehci-pci: EHCI PCI platform driver
ehci-pci 0000:00:09.2: EHCI Host Controller
ehci-pci 0000:00:09.2: new USB bus registered, assigned bus number 1
ehci-pci 0000:00:09.2: irq 146, io mem 0x58008000
ehci-pci 0000:00:09.2: USB 2.0 started, EHCI 1.00
hub 1-0:1.0: USB hub found
hub 1-0:1.0: 4 ports detected
uhci_hcd: USB Universal Host Controller Interface driver
uhci_hcd 0000:00:09.0: UHCI Host Controller
uhci_hcd 0000:00:09.0: new USB bus registered, assigned bus number 2
uhci_hcd 0000:00:09.0: HCRESET not completed yet!
uhci_hcd 0000:00:09.0: irq 144, io base 0x00000400
hub 2-0:1.0: USB hub found
hub 2-0:1.0: config failed, hub doesn't have any ports! (err -19)
uhci_hcd 0000:00:09.1: UHCI Host Controller
uhci_hcd 0000:00:09.1: new USB bus registered, assigned bus number 3
uhci_hcd 0000:00:09.1: HCRESET not completed yet!
uhci_hcd 0000:00:09.1: irq 145, io base 0x00000420
hub 3-0:1.0: USB hub found
hub 3-0:1.0: config failed, hub doesn't have any ports! (err -19)
usb 1-1: new high-speed USB device number 2 using ehci-pci
usb-storage 1-1:1.0: USB Mass Storage device detected
scsi host0: usb-storage 1-1:1.0
scsi 0:0:0:0: Direct-Access     USB      Flash Disk       1.00 PQ: 0 ANSI: 2
sd 0:0:0:0: [sda] 7900336 512-byte logical blocks: (4.04 GB/3.77 GiB)
sd 0:0:0:0: [sda] Write Protect is off
sd 0:0:0:0: [sda] Mode Sense: 0b 00 00 08
sd 0:0:0:0: [sda] No Caching mode page found
sd 0:0:0:0: [sda] Assuming drive cache: write through
 sda: sda1 sda2 sda3
sd 0:0:0:0: [sda] Attached SCSI removable disk

$ lspci
00:00.0 Class 0600: 159b:4321
00:09.2 Class 0c03: 1106:3104
00:09.0 Class 0c03: 1106:3038
00:09.1 Class 0c03: 1106:3038
00:0c.0 Class 0280: 1814:0301

cat /proc/interrupts
           CPU0
 19:          0    GEMINI   3 Level     watchdog bark
 30:       4943    GEMINI  14 Edge      Gemini Timer Tick
 33:          0    GEMINI  17 Level     45000000.rtc
 34:        651    GEMINI  18 Level     serial
 66:          0      GPIO  18 Edge      factory reset
144:          0       PCI   0 Edge      uhci_hcd:usb2
145:          0       PCI   1 Edge      uhci_hcd:usb3
146:        160       PCI   2 Edge      ehci_hcd:usb1

Well the EHCI USB hub works fine, I can mount and manage
files and the IRQs just keep ticking up.

Cc: Janos Laube <janos.dev@gmail.com>
Cc: Paulius Zaleckas <paulius.zaleckas@gmail.com>
Cc: Hans Ulli Kroll <ulli.kroll@googlemail.com>
Cc: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
This can be merged to the PCI tree whenever it is considered
fine for inclusion.
---
 drivers/pci/host/Kconfig      |   7 +
 drivers/pci/host/Makefile     |   1 +
 drivers/pci/host/pci-gemini.c | 375 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 383 insertions(+)
 create mode 100644 drivers/pci/host/pci-gemini.c

diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index 898d2c48239c..e29c2caf3492 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -60,6 +60,13 @@ config PCI_EXYNOS
 	select PCIEPORTBUS
 	select PCIE_DW
 
+config PCI_GEMINI
+	bool "Cortina Gemini SL351x PCI roller"
+	depends on ARCH_GEMINI
+	depends on ARM
+	depends on OF
+	default ARCH_GEMINI
+
 config PCI_IMX6
 	bool "Freescale i.MX6 PCIe controller"
 	depends on SOC_IMX6Q
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index bfe3179ae74c..8f007fe7a19d 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -2,6 +2,7 @@ obj-$(CONFIG_PCIE_DW) += pcie-designware.o
 obj-$(CONFIG_PCIE_DW_PLAT) += pcie-designware-plat.o
 obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
 obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
+obj-$(CONFIG_PCI_GEMINI) += pci-gemini.o
 obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
 obj-$(CONFIG_PCI_HYPERV) += pci-hyperv.o
 obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o
diff --git a/drivers/pci/host/pci-gemini.c b/drivers/pci/host/pci-gemini.c
new file mode 100644
index 000000000000..7051dd992114
--- /dev/null
+++ b/drivers/pci/host/pci-gemini.c
@@ -0,0 +1,375 @@
+/*
+ * Support for Gemini PCI Controller
+ *
+ * Copyright (C) 2017 Linus Walleij <linus.walleij@linaro.org>
+ *
+ * Based on the out-of-tree OpenWRT patch:
+ * Copyright (C) 2009 Janos Laube <janos.dev@gmail.com>
+ * Copyright (C) 2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ * Based on SL2312 PCI controller code
+ * Storlink (C) 2003
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/of_address.h>
+#include <linux/of_pci.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/irqdomain.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/bitops.h>
+#include <linux/irq.h>
+#include <linux/spinlock.h>
+
+#define GEMINI_PCI_IOSIZE_1M		0x0000
+
+#define GEMINI_PCI_PMC			0x40
+#define GEMINI_PCI_PMCSR		0x44
+#define GEMINI_PCI_CTRL1		0x48
+#define GEMINI_PCI_CTRL2		0x4C
+#define GEMINI_PCI_MEM1_BASE_SIZE	0x50
+#define GEMINI_PCI_MEM2_BASE_SIZE	0x54
+#define GEMINI_PCI_MEM3_BASE_SIZE	0x58
+
+#define PCI_CTRL2_INTSTS_SHIFT		28
+#define PCI_CTRL2_INTMASK_SHIFT		22
+
+#define GEMINI_PCI_DMA_MASK		0xFFF00000
+#define GEMINI_PCI_DMA_MEM1_BASE	0x00000000
+#define GEMINI_PCI_DMA_MEM2_BASE	0x00000000
+#define GEMINI_PCI_DMA_MEM3_BASE	0x00000000
+#define GEMINI_PCI_DMA_MEM1_SIZE	7
+#define GEMINI_PCI_DMA_MEM2_SIZE	6
+#define GEMINI_PCI_DMA_MEM3_SIZE	6
+
+#define PCI_CONF_ENABLE		BIT(31)
+#define PCI_CONF_WHERE(r)	((r) & 0xFC)
+#define PCI_CONF_BUS(b)		(((b) & 0xFF) << 16)
+#define PCI_CONF_DEVICE(d)	(((d) & 0x1F) << 11)
+#define PCI_CONF_FUNCTION(f)	(((f) & 0x07) << 8)
+
+#define PCI_IOSIZE	0x00
+#define PCI_PROT	0x04
+#define PCI_CTRL	0x08
+#define PCI_SOFTRST	0x10
+#define PCI_CONFIG	0x28
+#define PCI_DATA	0x2C
+
+struct gemini_pci {
+	struct device *dev;
+	void __iomem *base;
+	struct irq_domain *irqdomain;
+	spinlock_t lock;
+	struct pci_bus *bus;
+};
+
+static int gemini_pci_read_config(struct pci_bus *bus, unsigned int fn,
+				  int config, int size, u32 *value)
+{
+	struct gemini_pci *p = bus->sysdata;
+	unsigned long irq_flags;
+
+	spin_lock_irqsave(&p->lock, irq_flags);
+
+	writel(PCI_CONF_BUS(bus->number) |
+			PCI_CONF_DEVICE(PCI_SLOT(fn)) |
+			PCI_CONF_FUNCTION(PCI_FUNC(fn)) |
+			PCI_CONF_WHERE(config) |
+			PCI_CONF_ENABLE,
+			p->base + PCI_CONFIG);
+
+	*value = readl(p->base + PCI_DATA);
+
+	if (size == 1)
+		*value = (*value >> (8 * (config & 3))) & 0xFF;
+	else if (size == 2)
+		*value = (*value >> (8 * (config & 3))) & 0xFFFF;
+
+	spin_unlock_irqrestore(&p->lock, irq_flags);
+
+	dev_dbg(&bus->dev,
+		"[read]  slt: %.2d, fnc: %d, cnf: 0x%.2X, val (%d bytes): 0x%.8X\n",
+		PCI_SLOT(fn), PCI_FUNC(fn), config, size, *value);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int gemini_pci_write_config(struct pci_bus *bus, unsigned int fn,
+				   int config, int size, u32 value)
+{
+	struct gemini_pci *p = bus->sysdata;
+	unsigned long irq_flags = 0;
+	int ret = PCIBIOS_SUCCESSFUL;
+
+	dev_dbg(&bus->dev,
+		"[write] slt: %.2d, fnc: %d, cnf: 0x%.2X, val (%d bytes): 0x%.8X\n",
+		PCI_SLOT(fn), PCI_FUNC(fn), config, size, value);
+
+	spin_lock_irqsave(&p->lock, irq_flags);
+
+	writel(PCI_CONF_BUS(bus->number) |
+			PCI_CONF_DEVICE(PCI_SLOT(fn)) |
+			PCI_CONF_FUNCTION(PCI_FUNC(fn)) |
+			PCI_CONF_WHERE(config) |
+			PCI_CONF_ENABLE,
+			p->base + PCI_CONFIG);
+
+	switch (size) {
+	case 4:
+		writel(value, p->base + PCI_DATA);
+		break;
+	case 2:
+		writew(value, p->base + PCI_DATA + (config & 3));
+		break;
+	case 1:
+		writeb(value, p->base + PCI_DATA + (config & 3));
+		break;
+	default:
+		ret = PCIBIOS_BAD_REGISTER_NUMBER;
+	}
+
+	spin_unlock_irqrestore(&p->lock, irq_flags);
+
+	return ret;
+}
+
+static struct pci_ops gemini_pci_ops = {
+	.read	= gemini_pci_read_config,
+	.write	= gemini_pci_write_config,
+};
+
+static void gemini_pci_ack_irq(struct irq_data *d)
+{
+	struct gemini_pci *p = irq_data_get_irq_chip_data(d);
+	unsigned int reg;
+
+	gemini_pci_read_config(p->bus, 0, GEMINI_PCI_CTRL2, 4, &reg);
+	reg &= ~(0xF << PCI_CTRL2_INTSTS_SHIFT);
+	reg |= BIT(irqd_to_hwirq(d) + PCI_CTRL2_INTSTS_SHIFT);
+	gemini_pci_write_config(p->bus, 0, GEMINI_PCI_CTRL2, 4, reg);
+}
+
+static void gemini_pci_mask_irq(struct irq_data *d)
+{
+	struct gemini_pci *p = irq_data_get_irq_chip_data(d);
+	unsigned int reg;
+
+	gemini_pci_read_config(p->bus, 0, GEMINI_PCI_CTRL2, 4, &reg);
+	reg &= ~((0xF << PCI_CTRL2_INTSTS_SHIFT)
+		 | BIT(irqd_to_hwirq(d) + PCI_CTRL2_INTMASK_SHIFT));
+	gemini_pci_write_config(p->bus, 0, GEMINI_PCI_CTRL2, 4, reg);
+}
+
+static void gemini_pci_unmask_irq(struct irq_data *d)
+{
+	struct gemini_pci *p = irq_data_get_irq_chip_data(d);
+	unsigned int reg;
+
+	gemini_pci_read_config(p->bus, 0, GEMINI_PCI_CTRL2, 4, &reg);
+	reg &= ~(0xF << PCI_CTRL2_INTSTS_SHIFT);
+	reg |= BIT(irqd_to_hwirq(d) + PCI_CTRL2_INTMASK_SHIFT);
+	gemini_pci_write_config(p->bus, 0, GEMINI_PCI_CTRL2, 4, reg);
+}
+
+static void gemini_pci_irq_handler(struct irq_desc *desc)
+{
+	struct gemini_pci *p = irq_desc_get_handler_data(desc);
+	struct irq_chip *irqchip = irq_desc_get_chip(desc);
+	unsigned int irq_stat, reg, i;
+
+	gemini_pci_read_config(p->bus, 0, GEMINI_PCI_CTRL2, 4, &reg);
+	irq_stat = reg >> PCI_CTRL2_INTSTS_SHIFT;
+
+	chained_irq_enter(irqchip, desc);
+
+	for (i = 0; i < 4; i++) {
+		if ((irq_stat & BIT(i)) == 0)
+			continue;
+		generic_handle_irq(irq_find_mapping(p->irqdomain, i));
+	}
+
+	chained_irq_exit(irqchip, desc);
+}
+
+static struct irq_chip gemini_pci_irq_chip = {
+	.name = "PCI",
+	.irq_ack = gemini_pci_ack_irq,
+	.irq_mask = gemini_pci_mask_irq,
+	.irq_unmask = gemini_pci_unmask_irq,
+};
+
+static int gemini_pci_irq_map(struct irq_domain *domain, unsigned int irq,
+			      irq_hw_number_t hwirq)
+{
+	irq_set_chip_and_handler(irq, &gemini_pci_irq_chip, handle_level_irq);
+	irq_set_chip_data(irq, domain->host_data);
+
+	return 0;
+}
+
+static const struct irq_domain_ops gemini_pci_irqdomain_ops = {
+	.map = gemini_pci_irq_map,
+};
+
+static int gemini_pci_setup_irq(struct gemini_pci *p, int irq)
+{
+	struct device_node *intc = of_get_next_child(p->dev->of_node, NULL);
+	int i;
+
+	if (!intc) {
+		dev_err(p->dev, "missing child interrupt-controller node\n");
+		return -EINVAL;
+	}
+
+	p->irqdomain = irq_domain_add_linear(intc, 4,
+					     &gemini_pci_irqdomain_ops,
+					     p);
+	if (!p->irqdomain) {
+		dev_err(p->dev, "failed to create Gemini PCI IRQ domain\n");
+		return -EINVAL;
+	}
+
+	irq_set_chained_handler_and_data(irq, gemini_pci_irq_handler, p);
+
+	for (i = 0; i < 4; i++)
+		irq_create_mapping(p->irqdomain, i);
+
+	return 0;
+}
+
+static int gemini_pci_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct resource *regs;
+	resource_size_t io_base;
+	struct resource_entry *win;
+	struct gemini_pci *p;
+	struct resource *mem;
+	struct resource *io;
+	struct pci_bus *bus;
+	int irq;
+	int ret;
+	u32 val;
+	LIST_HEAD(res);
+
+	p = devm_kzalloc(dev, sizeof(*p), GFP_KERNEL);
+	if (!p)
+		return -ENOMEM;
+
+	p->dev = dev;
+	spin_lock_init(&p->lock);
+
+	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	p->base = devm_ioremap_resource(dev, regs);
+	if (IS_ERR(p->base))
+		return PTR_ERR(p->base);
+
+	ret = of_pci_get_host_bridge_resources(dev->of_node, 0, 0xff,
+					       &res, &io_base);
+	if (ret)
+		return ret;
+
+	ret = devm_request_pci_bus_resources(dev, &res);
+	if (ret)
+		return ret;
+
+	/* No clue what these do */
+	pcibios_min_io = 0x100;
+	pcibios_min_mem = 0;
+
+	/* setup I/O space to 1MB size */
+	writel(GEMINI_PCI_IOSIZE_1M, p->base + PCI_IOSIZE);
+
+	/* setup hostbridge */
+	val = readl(p->base + PCI_CTRL);
+	val |= PCI_COMMAND_IO;
+	val |= PCI_COMMAND_MEMORY;
+	val |= PCI_COMMAND_MASTER;
+	writel(val, p->base + PCI_CTRL);
+
+	/* Get the I/O and memory ranges from DT */
+	resource_list_for_each_entry(win, &res) {
+		switch (resource_type(win->res)) {
+		case IORESOURCE_IO:
+			io = win->res;
+			io->name = "Gemini PCI I/O";
+			ret = pci_remap_iospace(io, io_base);
+			if (ret) {
+				dev_warn(dev, "error %d: failed to map resource %pR\n",
+					 ret, io);
+				continue;
+			}
+			break;
+		case IORESOURCE_MEM:
+			mem = win->res;
+			mem->name = "Gemini PCI MEM";
+			break;
+		case IORESOURCE_BUS:
+			break;
+		default:
+			break;
+		}
+	}
+
+	bus = pci_scan_root_bus(&pdev->dev, 0, &gemini_pci_ops, p, &res);
+	if (!bus)
+		return -ENOMEM;
+	p->bus = bus;
+
+	dev_info(dev, "clear all IRQs\n");
+
+	/* Mask and clear all interrupts */
+	gemini_pci_write_config(bus, 0, GEMINI_PCI_CTRL2 + 2, 2, 0xF000);
+
+	/* IRQ - all PCI IRQs cascade off this one */
+	irq = platform_get_irq(pdev, 0);
+	if (!irq) {
+		dev_err(dev, "failed to get IRQ\n");
+		return -EINVAL;
+	}
+
+	ret = gemini_pci_setup_irq(p, irq);
+	if (ret) {
+		dev_err(dev, "failed to setup IRQ\n");
+		return ret;
+	}
+
+	dev_info(dev, "setting up PCI DMA\n");
+	val = (GEMINI_PCI_DMA_MEM1_BASE & GEMINI_PCI_DMA_MASK)
+		| (GEMINI_PCI_DMA_MEM1_SIZE << 16);
+	gemini_pci_write_config(bus, 0, GEMINI_PCI_MEM1_BASE_SIZE, 4, val);
+	val = (GEMINI_PCI_DMA_MEM2_BASE & GEMINI_PCI_DMA_MASK)
+		| (GEMINI_PCI_DMA_MEM2_SIZE << 16);
+	gemini_pci_write_config(bus, 0, GEMINI_PCI_MEM2_BASE_SIZE, 4, val);
+	val = (GEMINI_PCI_DMA_MEM3_BASE & GEMINI_PCI_DMA_MASK)
+		| (GEMINI_PCI_DMA_MEM3_SIZE << 16);
+	gemini_pci_write_config(bus, 0, GEMINI_PCI_MEM3_BASE_SIZE, 4, val);
+
+	pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
+	pci_bus_assign_resources(bus);
+	pci_assign_unassigned_bus_resources(bus);
+	pci_bus_add_devices(bus);
+	pci_free_resource_list(&res);
+
+	return 0;
+}
+
+static const struct of_device_id gemini_pci_of_match[] = {
+	{
+		.compatible = "cortina,gemini-pci",
+	},
+	{},
+};
+
+static struct platform_driver gemini_pci_driver = {
+	.driver = {
+		.name = "gemini-pci",
+		.of_match_table = of_match_ptr(gemini_pci_of_match),
+	},
+	.probe  = gemini_pci_probe,
+};
+builtin_platform_driver(gemini_pci_driver);
-- 
2.9.3


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

* [PATCH 2/4] PCI: add driver for Cortina Gemini Host Bridge
@ 2017-01-28 20:48   ` Linus Walleij
  0 siblings, 0 replies; 64+ messages in thread
From: Linus Walleij @ 2017-01-28 20:48 UTC (permalink / raw)
  To: linux-arm-kernel

This adds a host bridge driver for the Cortina Systems Gemini
SoC (SL3516) PCI Host Bridge.

This code is inspired by the out-of-tree OpenWRT patch and
then extensively rewritten for device tree and using the modern
helpers to cut down and modernize the code to all new PCI
frameworks.

Tested on the ITian Square One SQ201 NAS with the following
result in the boot log (trimmed to relevant parts):

OF: PCI: host bridge /pci at 50000000 ranges:
OF: PCI:    IO 0x50000000..0x500fffff -> 0x00000000
OF: PCI:   MEM 0x58000000..0x5fffffff -> 0x58000000
gemini-pci 50000000.pci: PCI host bridge to bus 0000:00
pci_bus 0000:00: root bus resource [bus 00]
pci_bus 0000:00: root bus resource [io  0x0000-0xfffff]
pci_bus 0000:00: root bus resource [mem 0x58000000-0x5fffffff]
pci 0000:00:00.0: [159b:4321] type 00 class 0x060000
pci 0000:00:09.0: [1106:3038] type 00 class 0x0c0300
pci 0000:00:09.0: reg 0x20: [io  0xfce0-0xfcff]
pci 0000:00:09.0: supports D1 D2
pci 0000:00:09.0: PME# supported from D0 D1 D2 D3hot D3cold
pci 0000:00:09.1: [1106:3038] type 00 class 0x0c0300
pci 0000:00:09.1: reg 0x20: [io  0xfce0-0xfcff]
pci 0000:00:09.1: supports D1 D2
pci 0000:00:09.1: PME# supported from D0 D1 D2 D3hot D3cold
pci 0000:00:09.2: [1106:3104] type 00 class 0x0c0320
pci 0000:00:09.2: reg 0x10: [mem 0x00000000-0x000000ff]
pci 0000:00:09.2: supports D1 D2
pci 0000:00:09.2: PME# supported from D0 D1 D2 D3hot D3cold
pci 0000:00:0c.0: [1814:0301] type 00 class 0x028000
pci 0000:00:0c.0: reg 0x10: [mem 0x58000000-0x58007fff]
PCI: bus0: Fast back to back transfers disabled
gemini-pci 50000000.pci: clear all IRQs
gemini-pci 50000000.pci: setting up PCI DMA
pci 0000:00:00.0: of_irq_parse_pci() failed with rc=-22
pci 0000:00:0c.0: BAR 0: assigned [mem 0x58000000-0x58007fff]
pci 0000:00:09.2: BAR 0: assigned [mem 0x58008000-0x580080ff]
pci 0000:00:09.0: BAR 4: assigned [io  0x0400-0x041f]
pci 0000:00:09.1: BAR 4: assigned [io  0x0420-0x043f]
pci 0000:00:09.0: enabling device (0140 -> 0141)
pci 0000:00:09.0: HCRESET not completed yet!
pci 0000:00:09.1: enabling device (0140 -> 0141)
pci 0000:00:09.1: HCRESET not completed yet!
pci 0000:00:09.2: enabling device (0140 -> 0142)
ieee80211 phy0: rt2x00_set_chip: Info - Chipset detected - rt: 2561, rf: 0003, rev: 000c
ieee80211 phy0: Selected rate control algorithm 'minstrel_ht'
ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
ehci-pci: EHCI PCI platform driver
ehci-pci 0000:00:09.2: EHCI Host Controller
ehci-pci 0000:00:09.2: new USB bus registered, assigned bus number 1
ehci-pci 0000:00:09.2: irq 146, io mem 0x58008000
ehci-pci 0000:00:09.2: USB 2.0 started, EHCI 1.00
hub 1-0:1.0: USB hub found
hub 1-0:1.0: 4 ports detected
uhci_hcd: USB Universal Host Controller Interface driver
uhci_hcd 0000:00:09.0: UHCI Host Controller
uhci_hcd 0000:00:09.0: new USB bus registered, assigned bus number 2
uhci_hcd 0000:00:09.0: HCRESET not completed yet!
uhci_hcd 0000:00:09.0: irq 144, io base 0x00000400
hub 2-0:1.0: USB hub found
hub 2-0:1.0: config failed, hub doesn't have any ports! (err -19)
uhci_hcd 0000:00:09.1: UHCI Host Controller
uhci_hcd 0000:00:09.1: new USB bus registered, assigned bus number 3
uhci_hcd 0000:00:09.1: HCRESET not completed yet!
uhci_hcd 0000:00:09.1: irq 145, io base 0x00000420
hub 3-0:1.0: USB hub found
hub 3-0:1.0: config failed, hub doesn't have any ports! (err -19)
usb 1-1: new high-speed USB device number 2 using ehci-pci
usb-storage 1-1:1.0: USB Mass Storage device detected
scsi host0: usb-storage 1-1:1.0
scsi 0:0:0:0: Direct-Access     USB      Flash Disk       1.00 PQ: 0 ANSI: 2
sd 0:0:0:0: [sda] 7900336 512-byte logical blocks: (4.04 GB/3.77 GiB)
sd 0:0:0:0: [sda] Write Protect is off
sd 0:0:0:0: [sda] Mode Sense: 0b 00 00 08
sd 0:0:0:0: [sda] No Caching mode page found
sd 0:0:0:0: [sda] Assuming drive cache: write through
 sda: sda1 sda2 sda3
sd 0:0:0:0: [sda] Attached SCSI removable disk

$ lspci
00:00.0 Class 0600: 159b:4321
00:09.2 Class 0c03: 1106:3104
00:09.0 Class 0c03: 1106:3038
00:09.1 Class 0c03: 1106:3038
00:0c.0 Class 0280: 1814:0301

cat /proc/interrupts
           CPU0
 19:          0    GEMINI   3 Level     watchdog bark
 30:       4943    GEMINI  14 Edge      Gemini Timer Tick
 33:          0    GEMINI  17 Level     45000000.rtc
 34:        651    GEMINI  18 Level     serial
 66:          0      GPIO  18 Edge      factory reset
144:          0       PCI   0 Edge      uhci_hcd:usb2
145:          0       PCI   1 Edge      uhci_hcd:usb3
146:        160       PCI   2 Edge      ehci_hcd:usb1

Well the EHCI USB hub works fine, I can mount and manage
files and the IRQs just keep ticking up.

Cc: Janos Laube <janos.dev@gmail.com>
Cc: Paulius Zaleckas <paulius.zaleckas@gmail.com>
Cc: Hans Ulli Kroll <ulli.kroll@googlemail.com>
Cc: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
This can be merged to the PCI tree whenever it is considered
fine for inclusion.
---
 drivers/pci/host/Kconfig      |   7 +
 drivers/pci/host/Makefile     |   1 +
 drivers/pci/host/pci-gemini.c | 375 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 383 insertions(+)
 create mode 100644 drivers/pci/host/pci-gemini.c

diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index 898d2c48239c..e29c2caf3492 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -60,6 +60,13 @@ config PCI_EXYNOS
 	select PCIEPORTBUS
 	select PCIE_DW
 
+config PCI_GEMINI
+	bool "Cortina Gemini SL351x PCI roller"
+	depends on ARCH_GEMINI
+	depends on ARM
+	depends on OF
+	default ARCH_GEMINI
+
 config PCI_IMX6
 	bool "Freescale i.MX6 PCIe controller"
 	depends on SOC_IMX6Q
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index bfe3179ae74c..8f007fe7a19d 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -2,6 +2,7 @@ obj-$(CONFIG_PCIE_DW) += pcie-designware.o
 obj-$(CONFIG_PCIE_DW_PLAT) += pcie-designware-plat.o
 obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
 obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
+obj-$(CONFIG_PCI_GEMINI) += pci-gemini.o
 obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
 obj-$(CONFIG_PCI_HYPERV) += pci-hyperv.o
 obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o
diff --git a/drivers/pci/host/pci-gemini.c b/drivers/pci/host/pci-gemini.c
new file mode 100644
index 000000000000..7051dd992114
--- /dev/null
+++ b/drivers/pci/host/pci-gemini.c
@@ -0,0 +1,375 @@
+/*
+ * Support for Gemini PCI Controller
+ *
+ * Copyright (C) 2017 Linus Walleij <linus.walleij@linaro.org>
+ *
+ * Based on the out-of-tree OpenWRT patch:
+ * Copyright (C) 2009 Janos Laube <janos.dev@gmail.com>
+ * Copyright (C) 2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ * Based on SL2312 PCI controller code
+ * Storlink (C) 2003
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/of_address.h>
+#include <linux/of_pci.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/irqdomain.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/bitops.h>
+#include <linux/irq.h>
+#include <linux/spinlock.h>
+
+#define GEMINI_PCI_IOSIZE_1M		0x0000
+
+#define GEMINI_PCI_PMC			0x40
+#define GEMINI_PCI_PMCSR		0x44
+#define GEMINI_PCI_CTRL1		0x48
+#define GEMINI_PCI_CTRL2		0x4C
+#define GEMINI_PCI_MEM1_BASE_SIZE	0x50
+#define GEMINI_PCI_MEM2_BASE_SIZE	0x54
+#define GEMINI_PCI_MEM3_BASE_SIZE	0x58
+
+#define PCI_CTRL2_INTSTS_SHIFT		28
+#define PCI_CTRL2_INTMASK_SHIFT		22
+
+#define GEMINI_PCI_DMA_MASK		0xFFF00000
+#define GEMINI_PCI_DMA_MEM1_BASE	0x00000000
+#define GEMINI_PCI_DMA_MEM2_BASE	0x00000000
+#define GEMINI_PCI_DMA_MEM3_BASE	0x00000000
+#define GEMINI_PCI_DMA_MEM1_SIZE	7
+#define GEMINI_PCI_DMA_MEM2_SIZE	6
+#define GEMINI_PCI_DMA_MEM3_SIZE	6
+
+#define PCI_CONF_ENABLE		BIT(31)
+#define PCI_CONF_WHERE(r)	((r) & 0xFC)
+#define PCI_CONF_BUS(b)		(((b) & 0xFF) << 16)
+#define PCI_CONF_DEVICE(d)	(((d) & 0x1F) << 11)
+#define PCI_CONF_FUNCTION(f)	(((f) & 0x07) << 8)
+
+#define PCI_IOSIZE	0x00
+#define PCI_PROT	0x04
+#define PCI_CTRL	0x08
+#define PCI_SOFTRST	0x10
+#define PCI_CONFIG	0x28
+#define PCI_DATA	0x2C
+
+struct gemini_pci {
+	struct device *dev;
+	void __iomem *base;
+	struct irq_domain *irqdomain;
+	spinlock_t lock;
+	struct pci_bus *bus;
+};
+
+static int gemini_pci_read_config(struct pci_bus *bus, unsigned int fn,
+				  int config, int size, u32 *value)
+{
+	struct gemini_pci *p = bus->sysdata;
+	unsigned long irq_flags;
+
+	spin_lock_irqsave(&p->lock, irq_flags);
+
+	writel(PCI_CONF_BUS(bus->number) |
+			PCI_CONF_DEVICE(PCI_SLOT(fn)) |
+			PCI_CONF_FUNCTION(PCI_FUNC(fn)) |
+			PCI_CONF_WHERE(config) |
+			PCI_CONF_ENABLE,
+			p->base + PCI_CONFIG);
+
+	*value = readl(p->base + PCI_DATA);
+
+	if (size == 1)
+		*value = (*value >> (8 * (config & 3))) & 0xFF;
+	else if (size == 2)
+		*value = (*value >> (8 * (config & 3))) & 0xFFFF;
+
+	spin_unlock_irqrestore(&p->lock, irq_flags);
+
+	dev_dbg(&bus->dev,
+		"[read]  slt: %.2d, fnc: %d, cnf: 0x%.2X, val (%d bytes): 0x%.8X\n",
+		PCI_SLOT(fn), PCI_FUNC(fn), config, size, *value);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int gemini_pci_write_config(struct pci_bus *bus, unsigned int fn,
+				   int config, int size, u32 value)
+{
+	struct gemini_pci *p = bus->sysdata;
+	unsigned long irq_flags = 0;
+	int ret = PCIBIOS_SUCCESSFUL;
+
+	dev_dbg(&bus->dev,
+		"[write] slt: %.2d, fnc: %d, cnf: 0x%.2X, val (%d bytes): 0x%.8X\n",
+		PCI_SLOT(fn), PCI_FUNC(fn), config, size, value);
+
+	spin_lock_irqsave(&p->lock, irq_flags);
+
+	writel(PCI_CONF_BUS(bus->number) |
+			PCI_CONF_DEVICE(PCI_SLOT(fn)) |
+			PCI_CONF_FUNCTION(PCI_FUNC(fn)) |
+			PCI_CONF_WHERE(config) |
+			PCI_CONF_ENABLE,
+			p->base + PCI_CONFIG);
+
+	switch (size) {
+	case 4:
+		writel(value, p->base + PCI_DATA);
+		break;
+	case 2:
+		writew(value, p->base + PCI_DATA + (config & 3));
+		break;
+	case 1:
+		writeb(value, p->base + PCI_DATA + (config & 3));
+		break;
+	default:
+		ret = PCIBIOS_BAD_REGISTER_NUMBER;
+	}
+
+	spin_unlock_irqrestore(&p->lock, irq_flags);
+
+	return ret;
+}
+
+static struct pci_ops gemini_pci_ops = {
+	.read	= gemini_pci_read_config,
+	.write	= gemini_pci_write_config,
+};
+
+static void gemini_pci_ack_irq(struct irq_data *d)
+{
+	struct gemini_pci *p = irq_data_get_irq_chip_data(d);
+	unsigned int reg;
+
+	gemini_pci_read_config(p->bus, 0, GEMINI_PCI_CTRL2, 4, &reg);
+	reg &= ~(0xF << PCI_CTRL2_INTSTS_SHIFT);
+	reg |= BIT(irqd_to_hwirq(d) + PCI_CTRL2_INTSTS_SHIFT);
+	gemini_pci_write_config(p->bus, 0, GEMINI_PCI_CTRL2, 4, reg);
+}
+
+static void gemini_pci_mask_irq(struct irq_data *d)
+{
+	struct gemini_pci *p = irq_data_get_irq_chip_data(d);
+	unsigned int reg;
+
+	gemini_pci_read_config(p->bus, 0, GEMINI_PCI_CTRL2, 4, &reg);
+	reg &= ~((0xF << PCI_CTRL2_INTSTS_SHIFT)
+		 | BIT(irqd_to_hwirq(d) + PCI_CTRL2_INTMASK_SHIFT));
+	gemini_pci_write_config(p->bus, 0, GEMINI_PCI_CTRL2, 4, reg);
+}
+
+static void gemini_pci_unmask_irq(struct irq_data *d)
+{
+	struct gemini_pci *p = irq_data_get_irq_chip_data(d);
+	unsigned int reg;
+
+	gemini_pci_read_config(p->bus, 0, GEMINI_PCI_CTRL2, 4, &reg);
+	reg &= ~(0xF << PCI_CTRL2_INTSTS_SHIFT);
+	reg |= BIT(irqd_to_hwirq(d) + PCI_CTRL2_INTMASK_SHIFT);
+	gemini_pci_write_config(p->bus, 0, GEMINI_PCI_CTRL2, 4, reg);
+}
+
+static void gemini_pci_irq_handler(struct irq_desc *desc)
+{
+	struct gemini_pci *p = irq_desc_get_handler_data(desc);
+	struct irq_chip *irqchip = irq_desc_get_chip(desc);
+	unsigned int irq_stat, reg, i;
+
+	gemini_pci_read_config(p->bus, 0, GEMINI_PCI_CTRL2, 4, &reg);
+	irq_stat = reg >> PCI_CTRL2_INTSTS_SHIFT;
+
+	chained_irq_enter(irqchip, desc);
+
+	for (i = 0; i < 4; i++) {
+		if ((irq_stat & BIT(i)) == 0)
+			continue;
+		generic_handle_irq(irq_find_mapping(p->irqdomain, i));
+	}
+
+	chained_irq_exit(irqchip, desc);
+}
+
+static struct irq_chip gemini_pci_irq_chip = {
+	.name = "PCI",
+	.irq_ack = gemini_pci_ack_irq,
+	.irq_mask = gemini_pci_mask_irq,
+	.irq_unmask = gemini_pci_unmask_irq,
+};
+
+static int gemini_pci_irq_map(struct irq_domain *domain, unsigned int irq,
+			      irq_hw_number_t hwirq)
+{
+	irq_set_chip_and_handler(irq, &gemini_pci_irq_chip, handle_level_irq);
+	irq_set_chip_data(irq, domain->host_data);
+
+	return 0;
+}
+
+static const struct irq_domain_ops gemini_pci_irqdomain_ops = {
+	.map = gemini_pci_irq_map,
+};
+
+static int gemini_pci_setup_irq(struct gemini_pci *p, int irq)
+{
+	struct device_node *intc = of_get_next_child(p->dev->of_node, NULL);
+	int i;
+
+	if (!intc) {
+		dev_err(p->dev, "missing child interrupt-controller node\n");
+		return -EINVAL;
+	}
+
+	p->irqdomain = irq_domain_add_linear(intc, 4,
+					     &gemini_pci_irqdomain_ops,
+					     p);
+	if (!p->irqdomain) {
+		dev_err(p->dev, "failed to create Gemini PCI IRQ domain\n");
+		return -EINVAL;
+	}
+
+	irq_set_chained_handler_and_data(irq, gemini_pci_irq_handler, p);
+
+	for (i = 0; i < 4; i++)
+		irq_create_mapping(p->irqdomain, i);
+
+	return 0;
+}
+
+static int gemini_pci_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct resource *regs;
+	resource_size_t io_base;
+	struct resource_entry *win;
+	struct gemini_pci *p;
+	struct resource *mem;
+	struct resource *io;
+	struct pci_bus *bus;
+	int irq;
+	int ret;
+	u32 val;
+	LIST_HEAD(res);
+
+	p = devm_kzalloc(dev, sizeof(*p), GFP_KERNEL);
+	if (!p)
+		return -ENOMEM;
+
+	p->dev = dev;
+	spin_lock_init(&p->lock);
+
+	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	p->base = devm_ioremap_resource(dev, regs);
+	if (IS_ERR(p->base))
+		return PTR_ERR(p->base);
+
+	ret = of_pci_get_host_bridge_resources(dev->of_node, 0, 0xff,
+					       &res, &io_base);
+	if (ret)
+		return ret;
+
+	ret = devm_request_pci_bus_resources(dev, &res);
+	if (ret)
+		return ret;
+
+	/* No clue what these do */
+	pcibios_min_io = 0x100;
+	pcibios_min_mem = 0;
+
+	/* setup I/O space to 1MB size */
+	writel(GEMINI_PCI_IOSIZE_1M, p->base + PCI_IOSIZE);
+
+	/* setup hostbridge */
+	val = readl(p->base + PCI_CTRL);
+	val |= PCI_COMMAND_IO;
+	val |= PCI_COMMAND_MEMORY;
+	val |= PCI_COMMAND_MASTER;
+	writel(val, p->base + PCI_CTRL);
+
+	/* Get the I/O and memory ranges from DT */
+	resource_list_for_each_entry(win, &res) {
+		switch (resource_type(win->res)) {
+		case IORESOURCE_IO:
+			io = win->res;
+			io->name = "Gemini PCI I/O";
+			ret = pci_remap_iospace(io, io_base);
+			if (ret) {
+				dev_warn(dev, "error %d: failed to map resource %pR\n",
+					 ret, io);
+				continue;
+			}
+			break;
+		case IORESOURCE_MEM:
+			mem = win->res;
+			mem->name = "Gemini PCI MEM";
+			break;
+		case IORESOURCE_BUS:
+			break;
+		default:
+			break;
+		}
+	}
+
+	bus = pci_scan_root_bus(&pdev->dev, 0, &gemini_pci_ops, p, &res);
+	if (!bus)
+		return -ENOMEM;
+	p->bus = bus;
+
+	dev_info(dev, "clear all IRQs\n");
+
+	/* Mask and clear all interrupts */
+	gemini_pci_write_config(bus, 0, GEMINI_PCI_CTRL2 + 2, 2, 0xF000);
+
+	/* IRQ - all PCI IRQs cascade off this one */
+	irq = platform_get_irq(pdev, 0);
+	if (!irq) {
+		dev_err(dev, "failed to get IRQ\n");
+		return -EINVAL;
+	}
+
+	ret = gemini_pci_setup_irq(p, irq);
+	if (ret) {
+		dev_err(dev, "failed to setup IRQ\n");
+		return ret;
+	}
+
+	dev_info(dev, "setting up PCI DMA\n");
+	val = (GEMINI_PCI_DMA_MEM1_BASE & GEMINI_PCI_DMA_MASK)
+		| (GEMINI_PCI_DMA_MEM1_SIZE << 16);
+	gemini_pci_write_config(bus, 0, GEMINI_PCI_MEM1_BASE_SIZE, 4, val);
+	val = (GEMINI_PCI_DMA_MEM2_BASE & GEMINI_PCI_DMA_MASK)
+		| (GEMINI_PCI_DMA_MEM2_SIZE << 16);
+	gemini_pci_write_config(bus, 0, GEMINI_PCI_MEM2_BASE_SIZE, 4, val);
+	val = (GEMINI_PCI_DMA_MEM3_BASE & GEMINI_PCI_DMA_MASK)
+		| (GEMINI_PCI_DMA_MEM3_SIZE << 16);
+	gemini_pci_write_config(bus, 0, GEMINI_PCI_MEM3_BASE_SIZE, 4, val);
+
+	pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
+	pci_bus_assign_resources(bus);
+	pci_assign_unassigned_bus_resources(bus);
+	pci_bus_add_devices(bus);
+	pci_free_resource_list(&res);
+
+	return 0;
+}
+
+static const struct of_device_id gemini_pci_of_match[] = {
+	{
+		.compatible = "cortina,gemini-pci",
+	},
+	{},
+};
+
+static struct platform_driver gemini_pci_driver = {
+	.driver = {
+		.name = "gemini-pci",
+		.of_match_table = of_match_ptr(gemini_pci_of_match),
+	},
+	.probe  = gemini_pci_probe,
+};
+builtin_platform_driver(gemini_pci_driver);
-- 
2.9.3

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

* [PATCH 3/4] ARM: gemini: select MIGHT_HAVE_PCI
  2017-01-28 20:48 ` Linus Walleij
@ 2017-01-28 20:48   ` Linus Walleij
  -1 siblings, 0 replies; 64+ messages in thread
From: Linus Walleij @ 2017-01-28 20:48 UTC (permalink / raw)
  To: Hans Ulli Kroll, Florian Fainelli, Bjorn Helgaas
  Cc: Janos Laube, Paulius Zaleckas, openwrt-devel, linux-arm-kernel,
	linux-pci, Linus Walleij

As we have a PCI driver for the Gemini, we should select
MIGHT_HAVE_PCI.

Cc: Janos Laube <janos.dev@gmail.com>
Cc: Paulius Zaleckas <paulius.zaleckas@gmail.com>
Cc: Hans Ulli Kroll <ulli.kroll@googlemail.com>
Cc: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
PCI maintainers: this is FYI only, I will funnel this to the ARM
SoC tree once we are done with the PCI driver.
---
 arch/arm/mach-gemini/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/mach-gemini/Kconfig b/arch/arm/mach-gemini/Kconfig
index 798abb16bb88..91ea52ccf13c 100644
--- a/arch/arm/mach-gemini/Kconfig
+++ b/arch/arm/mach-gemini/Kconfig
@@ -5,6 +5,7 @@ menuconfig ARCH_GEMINI
 	select GEMINI_TIMER
 	select GPIO_GEMINI
 	select GPIOLIB
+	select MIGHT_HAVE_PCI
 	select POWER_RESET
 	select POWER_RESET_SYSCON
 	select SERIAL_OF_PLATFORM
-- 
2.9.3


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

* [PATCH 3/4] ARM: gemini: select MIGHT_HAVE_PCI
@ 2017-01-28 20:48   ` Linus Walleij
  0 siblings, 0 replies; 64+ messages in thread
From: Linus Walleij @ 2017-01-28 20:48 UTC (permalink / raw)
  To: linux-arm-kernel

As we have a PCI driver for the Gemini, we should select
MIGHT_HAVE_PCI.

Cc: Janos Laube <janos.dev@gmail.com>
Cc: Paulius Zaleckas <paulius.zaleckas@gmail.com>
Cc: Hans Ulli Kroll <ulli.kroll@googlemail.com>
Cc: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
PCI maintainers: this is FYI only, I will funnel this to the ARM
SoC tree once we are done with the PCI driver.
---
 arch/arm/mach-gemini/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/mach-gemini/Kconfig b/arch/arm/mach-gemini/Kconfig
index 798abb16bb88..91ea52ccf13c 100644
--- a/arch/arm/mach-gemini/Kconfig
+++ b/arch/arm/mach-gemini/Kconfig
@@ -5,6 +5,7 @@ menuconfig ARCH_GEMINI
 	select GEMINI_TIMER
 	select GPIO_GEMINI
 	select GPIOLIB
+	select MIGHT_HAVE_PCI
 	select POWER_RESET
 	select POWER_RESET_SYSCON
 	select SERIAL_OF_PLATFORM
-- 
2.9.3

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

* [PATCH 4/4] ARM: dts: add PCI to the Gemini DTSI
  2017-01-28 20:48 ` Linus Walleij
@ 2017-01-28 20:48   ` Linus Walleij
  -1 siblings, 0 replies; 64+ messages in thread
From: Linus Walleij @ 2017-01-28 20:48 UTC (permalink / raw)
  To: Hans Ulli Kroll, Florian Fainelli, Bjorn Helgaas
  Cc: Janos Laube, Paulius Zaleckas, openwrt-devel, linux-arm-kernel,
	linux-pci, Linus Walleij

The Cortina Gemini has an internal PCI root bus, add this to
the device tree.

Cc: Janos Laube <janos.dev@gmail.com>
Cc: Paulius Zaleckas <paulius.zaleckas@gmail.com>
Cc: Hans Ulli Kroll <ulli.kroll@googlemail.com>
Cc: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
PCI maintainers: this is FYI only, I will funnel this to the ARM
SoC tree once we are done with the PCI driver.
---
 arch/arm/boot/dts/gemini.dtsi | 45 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/arch/arm/boot/dts/gemini.dtsi b/arch/arm/boot/dts/gemini.dtsi
index 405d6cedf409..df5630958038 100644
--- a/arch/arm/boot/dts/gemini.dtsi
+++ b/arch/arm/boot/dts/gemini.dtsi
@@ -99,4 +99,49 @@
 		interrupt-controller;
 		#interrupt-cells = <2>;
 	};
+
+	pci@50000000 {
+		compatible = "cortina,gemini-pci";
+		reg = <0x50000000 0x100>;
+		interrupts = <8 IRQ_TYPE_LEVEL_HIGH>, /* PCI A */
+				<26 IRQ_TYPE_LEVEL_HIGH>, /* PCI B */
+				<27 IRQ_TYPE_LEVEL_HIGH>, /* PCI C */
+				<28 IRQ_TYPE_LEVEL_HIGH>; /* PCI D */
+		#address-cells = <3>;
+		#size-cells = <2>;
+		#interrupt-cells = <1>;
+
+		bus-range = <0x00 0x00>; /* Only root bus */
+		/* PCI ranges mappings */
+		ranges = /* 1MiB I/O space 0x50000000-0x500fffff */
+			 <0x01000000 0 0          0x50000000 0 0x00100000>,
+			 /* 128MiB non-prefetchable memory 0x58000000-0x5fffffff */
+			 <0x02000000 0 0x58000000 0x58000000 0 0x08000000>;
+
+		interrupt-map-mask = <0xff00 0 0 7>;
+		/*
+		 * The interrupt map is done by sub-device and per-slot.
+		 */
+		interrupt-map = <0x4800 0 0 1 &pci_intc 0>, /* Slot 9 */
+				<0x4900 0 0 2 &pci_intc 1>,
+				<0x4a00 0 0 3 &pci_intc 2>,
+				<0x4b00 0 0 4 &pci_intc 3>,
+				<0x5000 0 0 1 &pci_intc 0>, /* Slot 10 */
+				<0x5100 0 0 2 &pci_intc 1>,
+				<0x5200 0 0 3 &pci_intc 2>,
+				<0x5300 0 0 4 &pci_intc 3>,
+				<0x5800 0 0 1 &pci_intc 0>, /* Slot 11 */
+				<0x5900 0 0 2 &pci_intc 1>,
+				<0x5a00 0 0 3 &pci_intc 2>,
+				<0x5b00 0 0 4 &pci_intc 3>,
+				<0x6000 0 0 1 &pci_intc 0>, /* Slot 12 */
+				<0x6100 0 0 2 &pci_intc 1>,
+				<0x6200 0 0 3 &pci_intc 2>,
+				<0x6300 0 0 4 &pci_intc 3>;
+		pci_intc: interrupt-controller {
+			interrupt-controller;
+			#address-cells = <0>;
+			#interrupt-cells = <1>;
+		};
+	};
 };
-- 
2.9.3


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

* [PATCH 4/4] ARM: dts: add PCI to the Gemini DTSI
@ 2017-01-28 20:48   ` Linus Walleij
  0 siblings, 0 replies; 64+ messages in thread
From: Linus Walleij @ 2017-01-28 20:48 UTC (permalink / raw)
  To: linux-arm-kernel

The Cortina Gemini has an internal PCI root bus, add this to
the device tree.

Cc: Janos Laube <janos.dev@gmail.com>
Cc: Paulius Zaleckas <paulius.zaleckas@gmail.com>
Cc: Hans Ulli Kroll <ulli.kroll@googlemail.com>
Cc: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
PCI maintainers: this is FYI only, I will funnel this to the ARM
SoC tree once we are done with the PCI driver.
---
 arch/arm/boot/dts/gemini.dtsi | 45 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/arch/arm/boot/dts/gemini.dtsi b/arch/arm/boot/dts/gemini.dtsi
index 405d6cedf409..df5630958038 100644
--- a/arch/arm/boot/dts/gemini.dtsi
+++ b/arch/arm/boot/dts/gemini.dtsi
@@ -99,4 +99,49 @@
 		interrupt-controller;
 		#interrupt-cells = <2>;
 	};
+
+	pci at 50000000 {
+		compatible = "cortina,gemini-pci";
+		reg = <0x50000000 0x100>;
+		interrupts = <8 IRQ_TYPE_LEVEL_HIGH>, /* PCI A */
+				<26 IRQ_TYPE_LEVEL_HIGH>, /* PCI B */
+				<27 IRQ_TYPE_LEVEL_HIGH>, /* PCI C */
+				<28 IRQ_TYPE_LEVEL_HIGH>; /* PCI D */
+		#address-cells = <3>;
+		#size-cells = <2>;
+		#interrupt-cells = <1>;
+
+		bus-range = <0x00 0x00>; /* Only root bus */
+		/* PCI ranges mappings */
+		ranges = /* 1MiB I/O space 0x50000000-0x500fffff */
+			 <0x01000000 0 0          0x50000000 0 0x00100000>,
+			 /* 128MiB non-prefetchable memory 0x58000000-0x5fffffff */
+			 <0x02000000 0 0x58000000 0x58000000 0 0x08000000>;
+
+		interrupt-map-mask = <0xff00 0 0 7>;
+		/*
+		 * The interrupt map is done by sub-device and per-slot.
+		 */
+		interrupt-map = <0x4800 0 0 1 &pci_intc 0>, /* Slot 9 */
+				<0x4900 0 0 2 &pci_intc 1>,
+				<0x4a00 0 0 3 &pci_intc 2>,
+				<0x4b00 0 0 4 &pci_intc 3>,
+				<0x5000 0 0 1 &pci_intc 0>, /* Slot 10 */
+				<0x5100 0 0 2 &pci_intc 1>,
+				<0x5200 0 0 3 &pci_intc 2>,
+				<0x5300 0 0 4 &pci_intc 3>,
+				<0x5800 0 0 1 &pci_intc 0>, /* Slot 11 */
+				<0x5900 0 0 2 &pci_intc 1>,
+				<0x5a00 0 0 3 &pci_intc 2>,
+				<0x5b00 0 0 4 &pci_intc 3>,
+				<0x6000 0 0 1 &pci_intc 0>, /* Slot 12 */
+				<0x6100 0 0 2 &pci_intc 1>,
+				<0x6200 0 0 3 &pci_intc 2>,
+				<0x6300 0 0 4 &pci_intc 3>;
+		pci_intc: interrupt-controller {
+			interrupt-controller;
+			#address-cells = <0>;
+			#interrupt-cells = <1>;
+		};
+	};
 };
-- 
2.9.3

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

* Re: [PATCH 1/4] PCI: add DT bindings for Cortina Gemini PCI Host Bridge
  2017-01-28 20:48 ` Linus Walleij
  (?)
@ 2017-01-31  0:31   ` Bjorn Helgaas
  -1 siblings, 0 replies; 64+ messages in thread
From: Bjorn Helgaas @ 2017-01-31  0:31 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Hans Ulli Kroll, Florian Fainelli, Bjorn Helgaas, Janos Laube,
	Paulius Zaleckas, openwrt-devel, linux-arm-kernel, linux-pci,
	devicetree

Hi Linus,

On Sat, Jan 28, 2017 at 09:48:36PM +0100, Linus Walleij wrote:
> This adds device tree bindings for the Cortina Systems Gemini PCI
> Host Bridge.
> 
> Cc: Janos Laube <janos.dev@gmail.com>
> Cc: Paulius Zaleckas <paulius.zaleckas@gmail.com>
> Cc: Hans Ulli Kroll <ulli.kroll@googlemail.com>
> Cc: Florian Fainelli <f.fainelli@gmail.com>
> Cc: devicetree@vger.kernel.org
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

I'm hoping one of the DT folks will take a quick look at this.

> ---
> This can be merged to the PCI tree whenever it is considered
> fine for inclusion.
> ---
>  .../devicetree/bindings/pci/cortina,gemini-pci.txt | 64 ++++++++++++++++++++++
>  1 file changed, 64 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/pci/cortina,gemini-pci.txt
> 
> diff --git a/Documentation/devicetree/bindings/pci/cortina,gemini-pci.txt b/Documentation/devicetree/bindings/pci/cortina,gemini-pci.txt
> new file mode 100644
> index 000000000000..e3090d995e1e
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pci/cortina,gemini-pci.txt
> @@ -0,0 +1,64 @@
> +* Cortina Systems Gemini PCI Host Bridge
> +
> +Mandatory properties:
> +
> +- compatible: should be "cortina,gemini-pci"
> +- reg: memory base and size for the host bridge
> +- interrupts: the four PCI interrupts
> +- #address-cells: set to <3>
> +- #size-cells: set to <2>
> +- #interrupt-cells: set to <1>
> +- bus-range: set to <0x00 0x00> (only root bus)

Why is this limited to bus 0?  Is everything completely soldered down
with no possibility of adding or replacing PCI devices?  The interrupt-map
below suggests slots, though.  If there's a slot, we could plug in a card
with a bridge, which would mean more than just bus 0.

> +- device_type, set to "pci"
> +- ranges: see pci.txt
> +- interrupt-map-mask: see pci.txt
> +- interrupt-map: see pci.txt
> +
> +Mandatory subnodes:
> +- One node reprenting the interrupt-controller inside the host bridge

s/reprenting/representing/

> +  with the following mandatory properties:
> +  - interrupt-controller: see interrupt-controller/interrupts.txt
> +  - #address-cells: set to <0>
> +  - #interrupt-cells: set to <1>
> +
> +Example:
> +
> +pci@50000000 {
> +	compatible = "cortina,gemini-pci";
> +	reg = <0x50000000 0x100>;
> +	interrupts = <8 IRQ_TYPE_LEVEL_HIGH>, /* PCI A */
> +			<26 IRQ_TYPE_LEVEL_HIGH>, /* PCI B */
> +			<27 IRQ_TYPE_LEVEL_HIGH>, /* PCI C */
> +			<28 IRQ_TYPE_LEVEL_HIGH>; /* PCI D */
> +	#address-cells = <3>;
> +	#size-cells = <2>;
> +	#interrupt-cells = <1>;
> +
> +	bus-range = <0x00 0x00>; /* Only root bus */
> +	ranges = /* 1MiB I/O space 0x50000000-0x500fffff */
> +		 <0x01000000 0 0          0x50000000 0 0x00100000>,
> +		 /* 128MiB non-prefetchable memory 0x58000000-0x5fffffff */
> +		 <0x02000000 0 0x58000000 0x58000000 0 0x08000000>;
> +	interrupt-map-mask = <0xff00 0 0 7>;
> +	interrupt-map = <0x4800 0 0 1 &pci_intc 0>, /* Slot 9 */
> +			<0x4900 0 0 2 &pci_intc 1>,
> +			<0x4a00 0 0 3 &pci_intc 2>,
> +			<0x4b00 0 0 4 &pci_intc 3>,
> +			<0x5000 0 0 1 &pci_intc 0>, /* Slot 10 */
> +			<0x5100 0 0 2 &pci_intc 1>,
> +			<0x5200 0 0 3 &pci_intc 2>,
> +			<0x5300 0 0 4 &pci_intc 3>,
> +			<0x5800 0 0 1 &pci_intc 0>, /* Slot 11 */
> +			<0x5900 0 0 2 &pci_intc 1>,
> +			<0x5a00 0 0 3 &pci_intc 2>,
> +			<0x5b00 0 0 4 &pci_intc 3>,
> +			<0x6000 0 0 1 &pci_intc 0>, /* Slot 12 */
> +			<0x6100 0 0 2 &pci_intc 1>,
> +			<0x6200 0 0 3 &pci_intc 2>,
> +			<0x6300 0 0 4 &pci_intc 3>;
> +	pci_intc: interrupt-controller {
> +		interrupt-controller;
> +		#address-cells = <0>;
> +		#interrupt-cells = <1>;
> +	};
> +};
> -- 
> 2.9.3
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 1/4] PCI: add DT bindings for Cortina Gemini PCI Host Bridge
@ 2017-01-31  0:31   ` Bjorn Helgaas
  0 siblings, 0 replies; 64+ messages in thread
From: Bjorn Helgaas @ 2017-01-31  0:31 UTC (permalink / raw)
  To: Linus Walleij
  Cc: openwrt-devel, devicetree, Florian Fainelli, Paulius Zaleckas,
	linux-pci, Hans Ulli Kroll, Bjorn Helgaas, Janos Laube,
	linux-arm-kernel

Hi Linus,

On Sat, Jan 28, 2017 at 09:48:36PM +0100, Linus Walleij wrote:
> This adds device tree bindings for the Cortina Systems Gemini PCI
> Host Bridge.
> 
> Cc: Janos Laube <janos.dev@gmail.com>
> Cc: Paulius Zaleckas <paulius.zaleckas@gmail.com>
> Cc: Hans Ulli Kroll <ulli.kroll@googlemail.com>
> Cc: Florian Fainelli <f.fainelli@gmail.com>
> Cc: devicetree@vger.kernel.org
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

I'm hoping one of the DT folks will take a quick look at this.

> ---
> This can be merged to the PCI tree whenever it is considered
> fine for inclusion.
> ---
>  .../devicetree/bindings/pci/cortina,gemini-pci.txt | 64 ++++++++++++++++++++++
>  1 file changed, 64 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/pci/cortina,gemini-pci.txt
> 
> diff --git a/Documentation/devicetree/bindings/pci/cortina,gemini-pci.txt b/Documentation/devicetree/bindings/pci/cortina,gemini-pci.txt
> new file mode 100644
> index 000000000000..e3090d995e1e
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pci/cortina,gemini-pci.txt
> @@ -0,0 +1,64 @@
> +* Cortina Systems Gemini PCI Host Bridge
> +
> +Mandatory properties:
> +
> +- compatible: should be "cortina,gemini-pci"
> +- reg: memory base and size for the host bridge
> +- interrupts: the four PCI interrupts
> +- #address-cells: set to <3>
> +- #size-cells: set to <2>
> +- #interrupt-cells: set to <1>
> +- bus-range: set to <0x00 0x00> (only root bus)

Why is this limited to bus 0?  Is everything completely soldered down
with no possibility of adding or replacing PCI devices?  The interrupt-map
below suggests slots, though.  If there's a slot, we could plug in a card
with a bridge, which would mean more than just bus 0.

> +- device_type, set to "pci"
> +- ranges: see pci.txt
> +- interrupt-map-mask: see pci.txt
> +- interrupt-map: see pci.txt
> +
> +Mandatory subnodes:
> +- One node reprenting the interrupt-controller inside the host bridge

s/reprenting/representing/

> +  with the following mandatory properties:
> +  - interrupt-controller: see interrupt-controller/interrupts.txt
> +  - #address-cells: set to <0>
> +  - #interrupt-cells: set to <1>
> +
> +Example:
> +
> +pci@50000000 {
> +	compatible = "cortina,gemini-pci";
> +	reg = <0x50000000 0x100>;
> +	interrupts = <8 IRQ_TYPE_LEVEL_HIGH>, /* PCI A */
> +			<26 IRQ_TYPE_LEVEL_HIGH>, /* PCI B */
> +			<27 IRQ_TYPE_LEVEL_HIGH>, /* PCI C */
> +			<28 IRQ_TYPE_LEVEL_HIGH>; /* PCI D */
> +	#address-cells = <3>;
> +	#size-cells = <2>;
> +	#interrupt-cells = <1>;
> +
> +	bus-range = <0x00 0x00>; /* Only root bus */
> +	ranges = /* 1MiB I/O space 0x50000000-0x500fffff */
> +		 <0x01000000 0 0          0x50000000 0 0x00100000>,
> +		 /* 128MiB non-prefetchable memory 0x58000000-0x5fffffff */
> +		 <0x02000000 0 0x58000000 0x58000000 0 0x08000000>;
> +	interrupt-map-mask = <0xff00 0 0 7>;
> +	interrupt-map = <0x4800 0 0 1 &pci_intc 0>, /* Slot 9 */
> +			<0x4900 0 0 2 &pci_intc 1>,
> +			<0x4a00 0 0 3 &pci_intc 2>,
> +			<0x4b00 0 0 4 &pci_intc 3>,
> +			<0x5000 0 0 1 &pci_intc 0>, /* Slot 10 */
> +			<0x5100 0 0 2 &pci_intc 1>,
> +			<0x5200 0 0 3 &pci_intc 2>,
> +			<0x5300 0 0 4 &pci_intc 3>,
> +			<0x5800 0 0 1 &pci_intc 0>, /* Slot 11 */
> +			<0x5900 0 0 2 &pci_intc 1>,
> +			<0x5a00 0 0 3 &pci_intc 2>,
> +			<0x5b00 0 0 4 &pci_intc 3>,
> +			<0x6000 0 0 1 &pci_intc 0>, /* Slot 12 */
> +			<0x6100 0 0 2 &pci_intc 1>,
> +			<0x6200 0 0 3 &pci_intc 2>,
> +			<0x6300 0 0 4 &pci_intc 3>;
> +	pci_intc: interrupt-controller {
> +		interrupt-controller;
> +		#address-cells = <0>;
> +		#interrupt-cells = <1>;
> +	};
> +};
> -- 
> 2.9.3
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 1/4] PCI: add DT bindings for Cortina Gemini PCI Host Bridge
@ 2017-01-31  0:31   ` Bjorn Helgaas
  0 siblings, 0 replies; 64+ messages in thread
From: Bjorn Helgaas @ 2017-01-31  0:31 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Linus,

On Sat, Jan 28, 2017 at 09:48:36PM +0100, Linus Walleij wrote:
> This adds device tree bindings for the Cortina Systems Gemini PCI
> Host Bridge.
> 
> Cc: Janos Laube <janos.dev@gmail.com>
> Cc: Paulius Zaleckas <paulius.zaleckas@gmail.com>
> Cc: Hans Ulli Kroll <ulli.kroll@googlemail.com>
> Cc: Florian Fainelli <f.fainelli@gmail.com>
> Cc: devicetree at vger.kernel.org
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

I'm hoping one of the DT folks will take a quick look at this.

> ---
> This can be merged to the PCI tree whenever it is considered
> fine for inclusion.
> ---
>  .../devicetree/bindings/pci/cortina,gemini-pci.txt | 64 ++++++++++++++++++++++
>  1 file changed, 64 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/pci/cortina,gemini-pci.txt
> 
> diff --git a/Documentation/devicetree/bindings/pci/cortina,gemini-pci.txt b/Documentation/devicetree/bindings/pci/cortina,gemini-pci.txt
> new file mode 100644
> index 000000000000..e3090d995e1e
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pci/cortina,gemini-pci.txt
> @@ -0,0 +1,64 @@
> +* Cortina Systems Gemini PCI Host Bridge
> +
> +Mandatory properties:
> +
> +- compatible: should be "cortina,gemini-pci"
> +- reg: memory base and size for the host bridge
> +- interrupts: the four PCI interrupts
> +- #address-cells: set to <3>
> +- #size-cells: set to <2>
> +- #interrupt-cells: set to <1>
> +- bus-range: set to <0x00 0x00> (only root bus)

Why is this limited to bus 0?  Is everything completely soldered down
with no possibility of adding or replacing PCI devices?  The interrupt-map
below suggests slots, though.  If there's a slot, we could plug in a card
with a bridge, which would mean more than just bus 0.

> +- device_type, set to "pci"
> +- ranges: see pci.txt
> +- interrupt-map-mask: see pci.txt
> +- interrupt-map: see pci.txt
> +
> +Mandatory subnodes:
> +- One node reprenting the interrupt-controller inside the host bridge

s/reprenting/representing/

> +  with the following mandatory properties:
> +  - interrupt-controller: see interrupt-controller/interrupts.txt
> +  - #address-cells: set to <0>
> +  - #interrupt-cells: set to <1>
> +
> +Example:
> +
> +pci at 50000000 {
> +	compatible = "cortina,gemini-pci";
> +	reg = <0x50000000 0x100>;
> +	interrupts = <8 IRQ_TYPE_LEVEL_HIGH>, /* PCI A */
> +			<26 IRQ_TYPE_LEVEL_HIGH>, /* PCI B */
> +			<27 IRQ_TYPE_LEVEL_HIGH>, /* PCI C */
> +			<28 IRQ_TYPE_LEVEL_HIGH>; /* PCI D */
> +	#address-cells = <3>;
> +	#size-cells = <2>;
> +	#interrupt-cells = <1>;
> +
> +	bus-range = <0x00 0x00>; /* Only root bus */
> +	ranges = /* 1MiB I/O space 0x50000000-0x500fffff */
> +		 <0x01000000 0 0          0x50000000 0 0x00100000>,
> +		 /* 128MiB non-prefetchable memory 0x58000000-0x5fffffff */
> +		 <0x02000000 0 0x58000000 0x58000000 0 0x08000000>;
> +	interrupt-map-mask = <0xff00 0 0 7>;
> +	interrupt-map = <0x4800 0 0 1 &pci_intc 0>, /* Slot 9 */
> +			<0x4900 0 0 2 &pci_intc 1>,
> +			<0x4a00 0 0 3 &pci_intc 2>,
> +			<0x4b00 0 0 4 &pci_intc 3>,
> +			<0x5000 0 0 1 &pci_intc 0>, /* Slot 10 */
> +			<0x5100 0 0 2 &pci_intc 1>,
> +			<0x5200 0 0 3 &pci_intc 2>,
> +			<0x5300 0 0 4 &pci_intc 3>,
> +			<0x5800 0 0 1 &pci_intc 0>, /* Slot 11 */
> +			<0x5900 0 0 2 &pci_intc 1>,
> +			<0x5a00 0 0 3 &pci_intc 2>,
> +			<0x5b00 0 0 4 &pci_intc 3>,
> +			<0x6000 0 0 1 &pci_intc 0>, /* Slot 12 */
> +			<0x6100 0 0 2 &pci_intc 1>,
> +			<0x6200 0 0 3 &pci_intc 2>,
> +			<0x6300 0 0 4 &pci_intc 3>;
> +	pci_intc: interrupt-controller {
> +		interrupt-controller;
> +		#address-cells = <0>;
> +		#interrupt-cells = <1>;
> +	};
> +};
> -- 
> 2.9.3
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 2/4] PCI: add driver for Cortina Gemini Host Bridge
  2017-01-28 20:48   ` Linus Walleij
@ 2017-01-31  0:37     ` Bjorn Helgaas
  -1 siblings, 0 replies; 64+ messages in thread
From: Bjorn Helgaas @ 2017-01-31  0:37 UTC (permalink / raw)
  To: Linus Walleij
  Cc: openwrt-devel, Florian Fainelli, Paulius Zaleckas, linux-pci,
	Hans Ulli Kroll, Bjorn Helgaas, Janos Laube, linux-arm-kernel

Hi Linus,

Looks nice; a couple unused definitions below.  It looks like /proc/iomem
should make sense, too, since you used devm_request_pci_bus_resources().

On Sat, Jan 28, 2017 at 09:48:37PM +0100, Linus Walleij wrote:
> This adds a host bridge driver for the Cortina Systems Gemini
> SoC (SL3516) PCI Host Bridge.
> 
> This code is inspired by the out-of-tree OpenWRT patch and
> then extensively rewritten for device tree and using the modern
> helpers to cut down and modernize the code to all new PCI
> frameworks.
> 
> Tested on the ITian Square One SQ201 NAS with the following
> result in the boot log (trimmed to relevant parts):
> 
> OF: PCI: host bridge /pci@50000000 ranges:
> OF: PCI:    IO 0x50000000..0x500fffff -> 0x00000000
> OF: PCI:   MEM 0x58000000..0x5fffffff -> 0x58000000
> gemini-pci 50000000.pci: PCI host bridge to bus 0000:00
> pci_bus 0000:00: root bus resource [bus 00]
> pci_bus 0000:00: root bus resource [io  0x0000-0xfffff]
> pci_bus 0000:00: root bus resource [mem 0x58000000-0x5fffffff]
> pci 0000:00:00.0: [159b:4321] type 00 class 0x060000
> pci 0000:00:09.0: [1106:3038] type 00 class 0x0c0300
> pci 0000:00:09.0: reg 0x20: [io  0xfce0-0xfcff]
> pci 0000:00:09.0: supports D1 D2
> pci 0000:00:09.0: PME# supported from D0 D1 D2 D3hot D3cold
> pci 0000:00:09.1: [1106:3038] type 00 class 0x0c0300
> pci 0000:00:09.1: reg 0x20: [io  0xfce0-0xfcff]
> pci 0000:00:09.1: supports D1 D2
> pci 0000:00:09.1: PME# supported from D0 D1 D2 D3hot D3cold
> pci 0000:00:09.2: [1106:3104] type 00 class 0x0c0320
> pci 0000:00:09.2: reg 0x10: [mem 0x00000000-0x000000ff]
> pci 0000:00:09.2: supports D1 D2
> pci 0000:00:09.2: PME# supported from D0 D1 D2 D3hot D3cold
> pci 0000:00:0c.0: [1814:0301] type 00 class 0x028000
> pci 0000:00:0c.0: reg 0x10: [mem 0x58000000-0x58007fff]
> PCI: bus0: Fast back to back transfers disabled
> gemini-pci 50000000.pci: clear all IRQs
> gemini-pci 50000000.pci: setting up PCI DMA
> pci 0000:00:00.0: of_irq_parse_pci() failed with rc=-22
> pci 0000:00:0c.0: BAR 0: assigned [mem 0x58000000-0x58007fff]
> pci 0000:00:09.2: BAR 0: assigned [mem 0x58008000-0x580080ff]
> pci 0000:00:09.0: BAR 4: assigned [io  0x0400-0x041f]
> pci 0000:00:09.1: BAR 4: assigned [io  0x0420-0x043f]
> pci 0000:00:09.0: enabling device (0140 -> 0141)
> pci 0000:00:09.0: HCRESET not completed yet!
> pci 0000:00:09.1: enabling device (0140 -> 0141)
> pci 0000:00:09.1: HCRESET not completed yet!
> pci 0000:00:09.2: enabling device (0140 -> 0142)
> ieee80211 phy0: rt2x00_set_chip: Info - Chipset detected - rt: 2561, rf: 0003, rev: 000c
> ieee80211 phy0: Selected rate control algorithm 'minstrel_ht'
> ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
> ehci-pci: EHCI PCI platform driver
> ehci-pci 0000:00:09.2: EHCI Host Controller
> ehci-pci 0000:00:09.2: new USB bus registered, assigned bus number 1
> ehci-pci 0000:00:09.2: irq 146, io mem 0x58008000
> ehci-pci 0000:00:09.2: USB 2.0 started, EHCI 1.00
> hub 1-0:1.0: USB hub found
> hub 1-0:1.0: 4 ports detected
> uhci_hcd: USB Universal Host Controller Interface driver
> uhci_hcd 0000:00:09.0: UHCI Host Controller
> uhci_hcd 0000:00:09.0: new USB bus registered, assigned bus number 2
> uhci_hcd 0000:00:09.0: HCRESET not completed yet!
> uhci_hcd 0000:00:09.0: irq 144, io base 0x00000400
> hub 2-0:1.0: USB hub found
> hub 2-0:1.0: config failed, hub doesn't have any ports! (err -19)
> uhci_hcd 0000:00:09.1: UHCI Host Controller
> uhci_hcd 0000:00:09.1: new USB bus registered, assigned bus number 3
> uhci_hcd 0000:00:09.1: HCRESET not completed yet!
> uhci_hcd 0000:00:09.1: irq 145, io base 0x00000420
> hub 3-0:1.0: USB hub found
> hub 3-0:1.0: config failed, hub doesn't have any ports! (err -19)
> usb 1-1: new high-speed USB device number 2 using ehci-pci
> usb-storage 1-1:1.0: USB Mass Storage device detected
> scsi host0: usb-storage 1-1:1.0
> scsi 0:0:0:0: Direct-Access     USB      Flash Disk       1.00 PQ: 0 ANSI: 2
> sd 0:0:0:0: [sda] 7900336 512-byte logical blocks: (4.04 GB/3.77 GiB)
> sd 0:0:0:0: [sda] Write Protect is off
> sd 0:0:0:0: [sda] Mode Sense: 0b 00 00 08
> sd 0:0:0:0: [sda] No Caching mode page found
> sd 0:0:0:0: [sda] Assuming drive cache: write through
>  sda: sda1 sda2 sda3
> sd 0:0:0:0: [sda] Attached SCSI removable disk
> 
> $ lspci
> 00:00.0 Class 0600: 159b:4321
> 00:09.2 Class 0c03: 1106:3104
> 00:09.0 Class 0c03: 1106:3038
> 00:09.1 Class 0c03: 1106:3038
> 00:0c.0 Class 0280: 1814:0301
> 
> cat /proc/interrupts
>            CPU0
>  19:          0    GEMINI   3 Level     watchdog bark
>  30:       4943    GEMINI  14 Edge      Gemini Timer Tick
>  33:          0    GEMINI  17 Level     45000000.rtc
>  34:        651    GEMINI  18 Level     serial
>  66:          0      GPIO  18 Edge      factory reset
> 144:          0       PCI   0 Edge      uhci_hcd:usb2
> 145:          0       PCI   1 Edge      uhci_hcd:usb3
> 146:        160       PCI   2 Edge      ehci_hcd:usb1
> 
> Well the EHCI USB hub works fine, I can mount and manage
> files and the IRQs just keep ticking up.
> 
> Cc: Janos Laube <janos.dev@gmail.com>
> Cc: Paulius Zaleckas <paulius.zaleckas@gmail.com>
> Cc: Hans Ulli Kroll <ulli.kroll@googlemail.com>
> Cc: Florian Fainelli <f.fainelli@gmail.com>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
> This can be merged to the PCI tree whenever it is considered
> fine for inclusion.
> ---
>  drivers/pci/host/Kconfig      |   7 +
>  drivers/pci/host/Makefile     |   1 +
>  drivers/pci/host/pci-gemini.c | 375 ++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 383 insertions(+)
>  create mode 100644 drivers/pci/host/pci-gemini.c
> 
> diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
> index 898d2c48239c..e29c2caf3492 100644
> --- a/drivers/pci/host/Kconfig
> +++ b/drivers/pci/host/Kconfig
> @@ -60,6 +60,13 @@ config PCI_EXYNOS
>  	select PCIEPORTBUS
>  	select PCIE_DW
>  
> +config PCI_GEMINI
> +	bool "Cortina Gemini SL351x PCI roller"
> +	depends on ARCH_GEMINI
> +	depends on ARM
> +	depends on OF
> +	default ARCH_GEMINI
> +
>  config PCI_IMX6
>  	bool "Freescale i.MX6 PCIe controller"
>  	depends on SOC_IMX6Q
> diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
> index bfe3179ae74c..8f007fe7a19d 100644
> --- a/drivers/pci/host/Makefile
> +++ b/drivers/pci/host/Makefile
> @@ -2,6 +2,7 @@ obj-$(CONFIG_PCIE_DW) += pcie-designware.o
>  obj-$(CONFIG_PCIE_DW_PLAT) += pcie-designware-plat.o
>  obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
>  obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
> +obj-$(CONFIG_PCI_GEMINI) += pci-gemini.o
>  obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
>  obj-$(CONFIG_PCI_HYPERV) += pci-hyperv.o
>  obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o
> diff --git a/drivers/pci/host/pci-gemini.c b/drivers/pci/host/pci-gemini.c
> new file mode 100644
> index 000000000000..7051dd992114
> --- /dev/null
> +++ b/drivers/pci/host/pci-gemini.c
> @@ -0,0 +1,375 @@
> +/*
> + * Support for Gemini PCI Controller
> + *
> + * Copyright (C) 2017 Linus Walleij <linus.walleij@linaro.org>
> + *
> + * Based on the out-of-tree OpenWRT patch:
> + * Copyright (C) 2009 Janos Laube <janos.dev@gmail.com>
> + * Copyright (C) 2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
> + * Based on SL2312 PCI controller code
> + * Storlink (C) 2003
> + */
> +
> +#include <linux/init.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/of_address.h>
> +#include <linux/of_pci.h>
> +#include <linux/pci.h>
> +#include <linux/platform_device.h>
> +#include <linux/slab.h>
> +#include <linux/irqdomain.h>
> +#include <linux/irqchip/chained_irq.h>
> +#include <linux/bitops.h>
> +#include <linux/irq.h>
> +#include <linux/spinlock.h>
> +
> +#define GEMINI_PCI_IOSIZE_1M		0x0000
> +
> +#define GEMINI_PCI_PMC			0x40
> +#define GEMINI_PCI_PMCSR		0x44
> +#define GEMINI_PCI_CTRL1		0x48

Above three definitions unused.

> +#define GEMINI_PCI_CTRL2		0x4C
> +#define GEMINI_PCI_MEM1_BASE_SIZE	0x50
> +#define GEMINI_PCI_MEM2_BASE_SIZE	0x54
> +#define GEMINI_PCI_MEM3_BASE_SIZE	0x58
> +
> +#define PCI_CTRL2_INTSTS_SHIFT		28
> +#define PCI_CTRL2_INTMASK_SHIFT		22
> +
> +#define GEMINI_PCI_DMA_MASK		0xFFF00000
> +#define GEMINI_PCI_DMA_MEM1_BASE	0x00000000
> +#define GEMINI_PCI_DMA_MEM2_BASE	0x00000000
> +#define GEMINI_PCI_DMA_MEM3_BASE	0x00000000
> +#define GEMINI_PCI_DMA_MEM1_SIZE	7
> +#define GEMINI_PCI_DMA_MEM2_SIZE	6
> +#define GEMINI_PCI_DMA_MEM3_SIZE	6
> +
> +#define PCI_CONF_ENABLE		BIT(31)
> +#define PCI_CONF_WHERE(r)	((r) & 0xFC)
> +#define PCI_CONF_BUS(b)		(((b) & 0xFF) << 16)
> +#define PCI_CONF_DEVICE(d)	(((d) & 0x1F) << 11)
> +#define PCI_CONF_FUNCTION(f)	(((f) & 0x07) << 8)
> +
> +#define PCI_IOSIZE	0x00
> +#define PCI_PROT	0x04

Unused.

> +#define PCI_CTRL	0x08
> +#define PCI_SOFTRST	0x10

Unused.

> +#define PCI_CONFIG	0x28
> +#define PCI_DATA	0x2C
> +
> +struct gemini_pci {
> +	struct device *dev;
> +	void __iomem *base;
> +	struct irq_domain *irqdomain;
> +	spinlock_t lock;
> +	struct pci_bus *bus;
> +};
> +
> +static int gemini_pci_read_config(struct pci_bus *bus, unsigned int fn,
> +				  int config, int size, u32 *value)
> +{
> +	struct gemini_pci *p = bus->sysdata;
> +	unsigned long irq_flags;
> +
> +	spin_lock_irqsave(&p->lock, irq_flags);
> +
> +	writel(PCI_CONF_BUS(bus->number) |
> +			PCI_CONF_DEVICE(PCI_SLOT(fn)) |
> +			PCI_CONF_FUNCTION(PCI_FUNC(fn)) |
> +			PCI_CONF_WHERE(config) |
> +			PCI_CONF_ENABLE,
> +			p->base + PCI_CONFIG);
> +
> +	*value = readl(p->base + PCI_DATA);
> +
> +	if (size == 1)
> +		*value = (*value >> (8 * (config & 3))) & 0xFF;
> +	else if (size == 2)
> +		*value = (*value >> (8 * (config & 3))) & 0xFFFF;
> +
> +	spin_unlock_irqrestore(&p->lock, irq_flags);
> +
> +	dev_dbg(&bus->dev,
> +		"[read]  slt: %.2d, fnc: %d, cnf: 0x%.2X, val (%d bytes): 0x%.8X\n",
> +		PCI_SLOT(fn), PCI_FUNC(fn), config, size, *value);
> +
> +	return PCIBIOS_SUCCESSFUL;
> +}
> +
> +static int gemini_pci_write_config(struct pci_bus *bus, unsigned int fn,
> +				   int config, int size, u32 value)
> +{
> +	struct gemini_pci *p = bus->sysdata;
> +	unsigned long irq_flags = 0;
> +	int ret = PCIBIOS_SUCCESSFUL;
> +
> +	dev_dbg(&bus->dev,
> +		"[write] slt: %.2d, fnc: %d, cnf: 0x%.2X, val (%d bytes): 0x%.8X\n",
> +		PCI_SLOT(fn), PCI_FUNC(fn), config, size, value);
> +
> +	spin_lock_irqsave(&p->lock, irq_flags);
> +
> +	writel(PCI_CONF_BUS(bus->number) |
> +			PCI_CONF_DEVICE(PCI_SLOT(fn)) |
> +			PCI_CONF_FUNCTION(PCI_FUNC(fn)) |
> +			PCI_CONF_WHERE(config) |
> +			PCI_CONF_ENABLE,
> +			p->base + PCI_CONFIG);
> +
> +	switch (size) {
> +	case 4:
> +		writel(value, p->base + PCI_DATA);
> +		break;
> +	case 2:
> +		writew(value, p->base + PCI_DATA + (config & 3));
> +		break;
> +	case 1:
> +		writeb(value, p->base + PCI_DATA + (config & 3));
> +		break;
> +	default:
> +		ret = PCIBIOS_BAD_REGISTER_NUMBER;
> +	}
> +
> +	spin_unlock_irqrestore(&p->lock, irq_flags);
> +
> +	return ret;
> +}
> +
> +static struct pci_ops gemini_pci_ops = {
> +	.read	= gemini_pci_read_config,
> +	.write	= gemini_pci_write_config,
> +};
> +
> +static void gemini_pci_ack_irq(struct irq_data *d)
> +{
> +	struct gemini_pci *p = irq_data_get_irq_chip_data(d);
> +	unsigned int reg;
> +
> +	gemini_pci_read_config(p->bus, 0, GEMINI_PCI_CTRL2, 4, &reg);
> +	reg &= ~(0xF << PCI_CTRL2_INTSTS_SHIFT);
> +	reg |= BIT(irqd_to_hwirq(d) + PCI_CTRL2_INTSTS_SHIFT);
> +	gemini_pci_write_config(p->bus, 0, GEMINI_PCI_CTRL2, 4, reg);
> +}
> +
> +static void gemini_pci_mask_irq(struct irq_data *d)
> +{
> +	struct gemini_pci *p = irq_data_get_irq_chip_data(d);
> +	unsigned int reg;
> +
> +	gemini_pci_read_config(p->bus, 0, GEMINI_PCI_CTRL2, 4, &reg);
> +	reg &= ~((0xF << PCI_CTRL2_INTSTS_SHIFT)
> +		 | BIT(irqd_to_hwirq(d) + PCI_CTRL2_INTMASK_SHIFT));
> +	gemini_pci_write_config(p->bus, 0, GEMINI_PCI_CTRL2, 4, reg);
> +}
> +
> +static void gemini_pci_unmask_irq(struct irq_data *d)
> +{
> +	struct gemini_pci *p = irq_data_get_irq_chip_data(d);
> +	unsigned int reg;
> +
> +	gemini_pci_read_config(p->bus, 0, GEMINI_PCI_CTRL2, 4, &reg);
> +	reg &= ~(0xF << PCI_CTRL2_INTSTS_SHIFT);
> +	reg |= BIT(irqd_to_hwirq(d) + PCI_CTRL2_INTMASK_SHIFT);
> +	gemini_pci_write_config(p->bus, 0, GEMINI_PCI_CTRL2, 4, reg);
> +}
> +
> +static void gemini_pci_irq_handler(struct irq_desc *desc)
> +{
> +	struct gemini_pci *p = irq_desc_get_handler_data(desc);
> +	struct irq_chip *irqchip = irq_desc_get_chip(desc);
> +	unsigned int irq_stat, reg, i;
> +
> +	gemini_pci_read_config(p->bus, 0, GEMINI_PCI_CTRL2, 4, &reg);
> +	irq_stat = reg >> PCI_CTRL2_INTSTS_SHIFT;
> +
> +	chained_irq_enter(irqchip, desc);
> +
> +	for (i = 0; i < 4; i++) {
> +		if ((irq_stat & BIT(i)) == 0)
> +			continue;
> +		generic_handle_irq(irq_find_mapping(p->irqdomain, i));
> +	}
> +
> +	chained_irq_exit(irqchip, desc);
> +}
> +
> +static struct irq_chip gemini_pci_irq_chip = {
> +	.name = "PCI",
> +	.irq_ack = gemini_pci_ack_irq,
> +	.irq_mask = gemini_pci_mask_irq,
> +	.irq_unmask = gemini_pci_unmask_irq,
> +};
> +
> +static int gemini_pci_irq_map(struct irq_domain *domain, unsigned int irq,
> +			      irq_hw_number_t hwirq)
> +{
> +	irq_set_chip_and_handler(irq, &gemini_pci_irq_chip, handle_level_irq);
> +	irq_set_chip_data(irq, domain->host_data);
> +
> +	return 0;
> +}
> +
> +static const struct irq_domain_ops gemini_pci_irqdomain_ops = {
> +	.map = gemini_pci_irq_map,
> +};
> +
> +static int gemini_pci_setup_irq(struct gemini_pci *p, int irq)
> +{
> +	struct device_node *intc = of_get_next_child(p->dev->of_node, NULL);
> +	int i;
> +
> +	if (!intc) {
> +		dev_err(p->dev, "missing child interrupt-controller node\n");
> +		return -EINVAL;
> +	}
> +
> +	p->irqdomain = irq_domain_add_linear(intc, 4,
> +					     &gemini_pci_irqdomain_ops,
> +					     p);
> +	if (!p->irqdomain) {
> +		dev_err(p->dev, "failed to create Gemini PCI IRQ domain\n");
> +		return -EINVAL;
> +	}
> +
> +	irq_set_chained_handler_and_data(irq, gemini_pci_irq_handler, p);
> +
> +	for (i = 0; i < 4; i++)
> +		irq_create_mapping(p->irqdomain, i);
> +
> +	return 0;
> +}
> +
> +static int gemini_pci_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct resource *regs;
> +	resource_size_t io_base;
> +	struct resource_entry *win;
> +	struct gemini_pci *p;
> +	struct resource *mem;
> +	struct resource *io;
> +	struct pci_bus *bus;
> +	int irq;
> +	int ret;
> +	u32 val;
> +	LIST_HEAD(res);
> +
> +	p = devm_kzalloc(dev, sizeof(*p), GFP_KERNEL);
> +	if (!p)
> +		return -ENOMEM;
> +
> +	p->dev = dev;
> +	spin_lock_init(&p->lock);
> +
> +	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	p->base = devm_ioremap_resource(dev, regs);
> +	if (IS_ERR(p->base))
> +		return PTR_ERR(p->base);
> +
> +	ret = of_pci_get_host_bridge_resources(dev->of_node, 0, 0xff,
> +					       &res, &io_base);
> +	if (ret)
> +		return ret;
> +
> +	ret = devm_request_pci_bus_resources(dev, &res);
> +	if (ret)
> +		return ret;
> +
> +	/* No clue what these do */
> +	pcibios_min_io = 0x100;
> +	pcibios_min_mem = 0;
> +
> +	/* setup I/O space to 1MB size */
> +	writel(GEMINI_PCI_IOSIZE_1M, p->base + PCI_IOSIZE);
> +
> +	/* setup hostbridge */
> +	val = readl(p->base + PCI_CTRL);
> +	val |= PCI_COMMAND_IO;
> +	val |= PCI_COMMAND_MEMORY;
> +	val |= PCI_COMMAND_MASTER;
> +	writel(val, p->base + PCI_CTRL);
> +
> +	/* Get the I/O and memory ranges from DT */
> +	resource_list_for_each_entry(win, &res) {
> +		switch (resource_type(win->res)) {
> +		case IORESOURCE_IO:
> +			io = win->res;
> +			io->name = "Gemini PCI I/O";
> +			ret = pci_remap_iospace(io, io_base);
> +			if (ret) {
> +				dev_warn(dev, "error %d: failed to map resource %pR\n",
> +					 ret, io);
> +				continue;
> +			}
> +			break;
> +		case IORESOURCE_MEM:
> +			mem = win->res;
> +			mem->name = "Gemini PCI MEM";
> +			break;
> +		case IORESOURCE_BUS:
> +			break;
> +		default:
> +			break;
> +		}
> +	}
> +
> +	bus = pci_scan_root_bus(&pdev->dev, 0, &gemini_pci_ops, p, &res);
> +	if (!bus)
> +		return -ENOMEM;
> +	p->bus = bus;
> +
> +	dev_info(dev, "clear all IRQs\n");
> +
> +	/* Mask and clear all interrupts */
> +	gemini_pci_write_config(bus, 0, GEMINI_PCI_CTRL2 + 2, 2, 0xF000);
> +
> +	/* IRQ - all PCI IRQs cascade off this one */
> +	irq = platform_get_irq(pdev, 0);
> +	if (!irq) {
> +		dev_err(dev, "failed to get IRQ\n");
> +		return -EINVAL;
> +	}
> +
> +	ret = gemini_pci_setup_irq(p, irq);
> +	if (ret) {
> +		dev_err(dev, "failed to setup IRQ\n");
> +		return ret;
> +	}
> +
> +	dev_info(dev, "setting up PCI DMA\n");
> +	val = (GEMINI_PCI_DMA_MEM1_BASE & GEMINI_PCI_DMA_MASK)
> +		| (GEMINI_PCI_DMA_MEM1_SIZE << 16);
> +	gemini_pci_write_config(bus, 0, GEMINI_PCI_MEM1_BASE_SIZE, 4, val);
> +	val = (GEMINI_PCI_DMA_MEM2_BASE & GEMINI_PCI_DMA_MASK)
> +		| (GEMINI_PCI_DMA_MEM2_SIZE << 16);
> +	gemini_pci_write_config(bus, 0, GEMINI_PCI_MEM2_BASE_SIZE, 4, val);
> +	val = (GEMINI_PCI_DMA_MEM3_BASE & GEMINI_PCI_DMA_MASK)
> +		| (GEMINI_PCI_DMA_MEM3_SIZE << 16);
> +	gemini_pci_write_config(bus, 0, GEMINI_PCI_MEM3_BASE_SIZE, 4, val);
> +
> +	pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
> +	pci_bus_assign_resources(bus);
> +	pci_assign_unassigned_bus_resources(bus);
> +	pci_bus_add_devices(bus);
> +	pci_free_resource_list(&res);
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id gemini_pci_of_match[] = {
> +	{
> +		.compatible = "cortina,gemini-pci",
> +	},
> +	{},
> +};
> +
> +static struct platform_driver gemini_pci_driver = {
> +	.driver = {
> +		.name = "gemini-pci",
> +		.of_match_table = of_match_ptr(gemini_pci_of_match),
> +	},
> +	.probe  = gemini_pci_probe,
> +};
> +builtin_platform_driver(gemini_pci_driver);
> -- 
> 2.9.3
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 2/4] PCI: add driver for Cortina Gemini Host Bridge
@ 2017-01-31  0:37     ` Bjorn Helgaas
  0 siblings, 0 replies; 64+ messages in thread
From: Bjorn Helgaas @ 2017-01-31  0:37 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Linus,

Looks nice; a couple unused definitions below.  It looks like /proc/iomem
should make sense, too, since you used devm_request_pci_bus_resources().

On Sat, Jan 28, 2017 at 09:48:37PM +0100, Linus Walleij wrote:
> This adds a host bridge driver for the Cortina Systems Gemini
> SoC (SL3516) PCI Host Bridge.
> 
> This code is inspired by the out-of-tree OpenWRT patch and
> then extensively rewritten for device tree and using the modern
> helpers to cut down and modernize the code to all new PCI
> frameworks.
> 
> Tested on the ITian Square One SQ201 NAS with the following
> result in the boot log (trimmed to relevant parts):
> 
> OF: PCI: host bridge /pci at 50000000 ranges:
> OF: PCI:    IO 0x50000000..0x500fffff -> 0x00000000
> OF: PCI:   MEM 0x58000000..0x5fffffff -> 0x58000000
> gemini-pci 50000000.pci: PCI host bridge to bus 0000:00
> pci_bus 0000:00: root bus resource [bus 00]
> pci_bus 0000:00: root bus resource [io  0x0000-0xfffff]
> pci_bus 0000:00: root bus resource [mem 0x58000000-0x5fffffff]
> pci 0000:00:00.0: [159b:4321] type 00 class 0x060000
> pci 0000:00:09.0: [1106:3038] type 00 class 0x0c0300
> pci 0000:00:09.0: reg 0x20: [io  0xfce0-0xfcff]
> pci 0000:00:09.0: supports D1 D2
> pci 0000:00:09.0: PME# supported from D0 D1 D2 D3hot D3cold
> pci 0000:00:09.1: [1106:3038] type 00 class 0x0c0300
> pci 0000:00:09.1: reg 0x20: [io  0xfce0-0xfcff]
> pci 0000:00:09.1: supports D1 D2
> pci 0000:00:09.1: PME# supported from D0 D1 D2 D3hot D3cold
> pci 0000:00:09.2: [1106:3104] type 00 class 0x0c0320
> pci 0000:00:09.2: reg 0x10: [mem 0x00000000-0x000000ff]
> pci 0000:00:09.2: supports D1 D2
> pci 0000:00:09.2: PME# supported from D0 D1 D2 D3hot D3cold
> pci 0000:00:0c.0: [1814:0301] type 00 class 0x028000
> pci 0000:00:0c.0: reg 0x10: [mem 0x58000000-0x58007fff]
> PCI: bus0: Fast back to back transfers disabled
> gemini-pci 50000000.pci: clear all IRQs
> gemini-pci 50000000.pci: setting up PCI DMA
> pci 0000:00:00.0: of_irq_parse_pci() failed with rc=-22
> pci 0000:00:0c.0: BAR 0: assigned [mem 0x58000000-0x58007fff]
> pci 0000:00:09.2: BAR 0: assigned [mem 0x58008000-0x580080ff]
> pci 0000:00:09.0: BAR 4: assigned [io  0x0400-0x041f]
> pci 0000:00:09.1: BAR 4: assigned [io  0x0420-0x043f]
> pci 0000:00:09.0: enabling device (0140 -> 0141)
> pci 0000:00:09.0: HCRESET not completed yet!
> pci 0000:00:09.1: enabling device (0140 -> 0141)
> pci 0000:00:09.1: HCRESET not completed yet!
> pci 0000:00:09.2: enabling device (0140 -> 0142)
> ieee80211 phy0: rt2x00_set_chip: Info - Chipset detected - rt: 2561, rf: 0003, rev: 000c
> ieee80211 phy0: Selected rate control algorithm 'minstrel_ht'
> ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
> ehci-pci: EHCI PCI platform driver
> ehci-pci 0000:00:09.2: EHCI Host Controller
> ehci-pci 0000:00:09.2: new USB bus registered, assigned bus number 1
> ehci-pci 0000:00:09.2: irq 146, io mem 0x58008000
> ehci-pci 0000:00:09.2: USB 2.0 started, EHCI 1.00
> hub 1-0:1.0: USB hub found
> hub 1-0:1.0: 4 ports detected
> uhci_hcd: USB Universal Host Controller Interface driver
> uhci_hcd 0000:00:09.0: UHCI Host Controller
> uhci_hcd 0000:00:09.0: new USB bus registered, assigned bus number 2
> uhci_hcd 0000:00:09.0: HCRESET not completed yet!
> uhci_hcd 0000:00:09.0: irq 144, io base 0x00000400
> hub 2-0:1.0: USB hub found
> hub 2-0:1.0: config failed, hub doesn't have any ports! (err -19)
> uhci_hcd 0000:00:09.1: UHCI Host Controller
> uhci_hcd 0000:00:09.1: new USB bus registered, assigned bus number 3
> uhci_hcd 0000:00:09.1: HCRESET not completed yet!
> uhci_hcd 0000:00:09.1: irq 145, io base 0x00000420
> hub 3-0:1.0: USB hub found
> hub 3-0:1.0: config failed, hub doesn't have any ports! (err -19)
> usb 1-1: new high-speed USB device number 2 using ehci-pci
> usb-storage 1-1:1.0: USB Mass Storage device detected
> scsi host0: usb-storage 1-1:1.0
> scsi 0:0:0:0: Direct-Access     USB      Flash Disk       1.00 PQ: 0 ANSI: 2
> sd 0:0:0:0: [sda] 7900336 512-byte logical blocks: (4.04 GB/3.77 GiB)
> sd 0:0:0:0: [sda] Write Protect is off
> sd 0:0:0:0: [sda] Mode Sense: 0b 00 00 08
> sd 0:0:0:0: [sda] No Caching mode page found
> sd 0:0:0:0: [sda] Assuming drive cache: write through
>  sda: sda1 sda2 sda3
> sd 0:0:0:0: [sda] Attached SCSI removable disk
> 
> $ lspci
> 00:00.0 Class 0600: 159b:4321
> 00:09.2 Class 0c03: 1106:3104
> 00:09.0 Class 0c03: 1106:3038
> 00:09.1 Class 0c03: 1106:3038
> 00:0c.0 Class 0280: 1814:0301
> 
> cat /proc/interrupts
>            CPU0
>  19:          0    GEMINI   3 Level     watchdog bark
>  30:       4943    GEMINI  14 Edge      Gemini Timer Tick
>  33:          0    GEMINI  17 Level     45000000.rtc
>  34:        651    GEMINI  18 Level     serial
>  66:          0      GPIO  18 Edge      factory reset
> 144:          0       PCI   0 Edge      uhci_hcd:usb2
> 145:          0       PCI   1 Edge      uhci_hcd:usb3
> 146:        160       PCI   2 Edge      ehci_hcd:usb1
> 
> Well the EHCI USB hub works fine, I can mount and manage
> files and the IRQs just keep ticking up.
> 
> Cc: Janos Laube <janos.dev@gmail.com>
> Cc: Paulius Zaleckas <paulius.zaleckas@gmail.com>
> Cc: Hans Ulli Kroll <ulli.kroll@googlemail.com>
> Cc: Florian Fainelli <f.fainelli@gmail.com>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
> This can be merged to the PCI tree whenever it is considered
> fine for inclusion.
> ---
>  drivers/pci/host/Kconfig      |   7 +
>  drivers/pci/host/Makefile     |   1 +
>  drivers/pci/host/pci-gemini.c | 375 ++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 383 insertions(+)
>  create mode 100644 drivers/pci/host/pci-gemini.c
> 
> diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
> index 898d2c48239c..e29c2caf3492 100644
> --- a/drivers/pci/host/Kconfig
> +++ b/drivers/pci/host/Kconfig
> @@ -60,6 +60,13 @@ config PCI_EXYNOS
>  	select PCIEPORTBUS
>  	select PCIE_DW
>  
> +config PCI_GEMINI
> +	bool "Cortina Gemini SL351x PCI roller"
> +	depends on ARCH_GEMINI
> +	depends on ARM
> +	depends on OF
> +	default ARCH_GEMINI
> +
>  config PCI_IMX6
>  	bool "Freescale i.MX6 PCIe controller"
>  	depends on SOC_IMX6Q
> diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
> index bfe3179ae74c..8f007fe7a19d 100644
> --- a/drivers/pci/host/Makefile
> +++ b/drivers/pci/host/Makefile
> @@ -2,6 +2,7 @@ obj-$(CONFIG_PCIE_DW) += pcie-designware.o
>  obj-$(CONFIG_PCIE_DW_PLAT) += pcie-designware-plat.o
>  obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
>  obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
> +obj-$(CONFIG_PCI_GEMINI) += pci-gemini.o
>  obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
>  obj-$(CONFIG_PCI_HYPERV) += pci-hyperv.o
>  obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o
> diff --git a/drivers/pci/host/pci-gemini.c b/drivers/pci/host/pci-gemini.c
> new file mode 100644
> index 000000000000..7051dd992114
> --- /dev/null
> +++ b/drivers/pci/host/pci-gemini.c
> @@ -0,0 +1,375 @@
> +/*
> + * Support for Gemini PCI Controller
> + *
> + * Copyright (C) 2017 Linus Walleij <linus.walleij@linaro.org>
> + *
> + * Based on the out-of-tree OpenWRT patch:
> + * Copyright (C) 2009 Janos Laube <janos.dev@gmail.com>
> + * Copyright (C) 2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
> + * Based on SL2312 PCI controller code
> + * Storlink (C) 2003
> + */
> +
> +#include <linux/init.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/of_address.h>
> +#include <linux/of_pci.h>
> +#include <linux/pci.h>
> +#include <linux/platform_device.h>
> +#include <linux/slab.h>
> +#include <linux/irqdomain.h>
> +#include <linux/irqchip/chained_irq.h>
> +#include <linux/bitops.h>
> +#include <linux/irq.h>
> +#include <linux/spinlock.h>
> +
> +#define GEMINI_PCI_IOSIZE_1M		0x0000
> +
> +#define GEMINI_PCI_PMC			0x40
> +#define GEMINI_PCI_PMCSR		0x44
> +#define GEMINI_PCI_CTRL1		0x48

Above three definitions unused.

> +#define GEMINI_PCI_CTRL2		0x4C
> +#define GEMINI_PCI_MEM1_BASE_SIZE	0x50
> +#define GEMINI_PCI_MEM2_BASE_SIZE	0x54
> +#define GEMINI_PCI_MEM3_BASE_SIZE	0x58
> +
> +#define PCI_CTRL2_INTSTS_SHIFT		28
> +#define PCI_CTRL2_INTMASK_SHIFT		22
> +
> +#define GEMINI_PCI_DMA_MASK		0xFFF00000
> +#define GEMINI_PCI_DMA_MEM1_BASE	0x00000000
> +#define GEMINI_PCI_DMA_MEM2_BASE	0x00000000
> +#define GEMINI_PCI_DMA_MEM3_BASE	0x00000000
> +#define GEMINI_PCI_DMA_MEM1_SIZE	7
> +#define GEMINI_PCI_DMA_MEM2_SIZE	6
> +#define GEMINI_PCI_DMA_MEM3_SIZE	6
> +
> +#define PCI_CONF_ENABLE		BIT(31)
> +#define PCI_CONF_WHERE(r)	((r) & 0xFC)
> +#define PCI_CONF_BUS(b)		(((b) & 0xFF) << 16)
> +#define PCI_CONF_DEVICE(d)	(((d) & 0x1F) << 11)
> +#define PCI_CONF_FUNCTION(f)	(((f) & 0x07) << 8)
> +
> +#define PCI_IOSIZE	0x00
> +#define PCI_PROT	0x04

Unused.

> +#define PCI_CTRL	0x08
> +#define PCI_SOFTRST	0x10

Unused.

> +#define PCI_CONFIG	0x28
> +#define PCI_DATA	0x2C
> +
> +struct gemini_pci {
> +	struct device *dev;
> +	void __iomem *base;
> +	struct irq_domain *irqdomain;
> +	spinlock_t lock;
> +	struct pci_bus *bus;
> +};
> +
> +static int gemini_pci_read_config(struct pci_bus *bus, unsigned int fn,
> +				  int config, int size, u32 *value)
> +{
> +	struct gemini_pci *p = bus->sysdata;
> +	unsigned long irq_flags;
> +
> +	spin_lock_irqsave(&p->lock, irq_flags);
> +
> +	writel(PCI_CONF_BUS(bus->number) |
> +			PCI_CONF_DEVICE(PCI_SLOT(fn)) |
> +			PCI_CONF_FUNCTION(PCI_FUNC(fn)) |
> +			PCI_CONF_WHERE(config) |
> +			PCI_CONF_ENABLE,
> +			p->base + PCI_CONFIG);
> +
> +	*value = readl(p->base + PCI_DATA);
> +
> +	if (size == 1)
> +		*value = (*value >> (8 * (config & 3))) & 0xFF;
> +	else if (size == 2)
> +		*value = (*value >> (8 * (config & 3))) & 0xFFFF;
> +
> +	spin_unlock_irqrestore(&p->lock, irq_flags);
> +
> +	dev_dbg(&bus->dev,
> +		"[read]  slt: %.2d, fnc: %d, cnf: 0x%.2X, val (%d bytes): 0x%.8X\n",
> +		PCI_SLOT(fn), PCI_FUNC(fn), config, size, *value);
> +
> +	return PCIBIOS_SUCCESSFUL;
> +}
> +
> +static int gemini_pci_write_config(struct pci_bus *bus, unsigned int fn,
> +				   int config, int size, u32 value)
> +{
> +	struct gemini_pci *p = bus->sysdata;
> +	unsigned long irq_flags = 0;
> +	int ret = PCIBIOS_SUCCESSFUL;
> +
> +	dev_dbg(&bus->dev,
> +		"[write] slt: %.2d, fnc: %d, cnf: 0x%.2X, val (%d bytes): 0x%.8X\n",
> +		PCI_SLOT(fn), PCI_FUNC(fn), config, size, value);
> +
> +	spin_lock_irqsave(&p->lock, irq_flags);
> +
> +	writel(PCI_CONF_BUS(bus->number) |
> +			PCI_CONF_DEVICE(PCI_SLOT(fn)) |
> +			PCI_CONF_FUNCTION(PCI_FUNC(fn)) |
> +			PCI_CONF_WHERE(config) |
> +			PCI_CONF_ENABLE,
> +			p->base + PCI_CONFIG);
> +
> +	switch (size) {
> +	case 4:
> +		writel(value, p->base + PCI_DATA);
> +		break;
> +	case 2:
> +		writew(value, p->base + PCI_DATA + (config & 3));
> +		break;
> +	case 1:
> +		writeb(value, p->base + PCI_DATA + (config & 3));
> +		break;
> +	default:
> +		ret = PCIBIOS_BAD_REGISTER_NUMBER;
> +	}
> +
> +	spin_unlock_irqrestore(&p->lock, irq_flags);
> +
> +	return ret;
> +}
> +
> +static struct pci_ops gemini_pci_ops = {
> +	.read	= gemini_pci_read_config,
> +	.write	= gemini_pci_write_config,
> +};
> +
> +static void gemini_pci_ack_irq(struct irq_data *d)
> +{
> +	struct gemini_pci *p = irq_data_get_irq_chip_data(d);
> +	unsigned int reg;
> +
> +	gemini_pci_read_config(p->bus, 0, GEMINI_PCI_CTRL2, 4, &reg);
> +	reg &= ~(0xF << PCI_CTRL2_INTSTS_SHIFT);
> +	reg |= BIT(irqd_to_hwirq(d) + PCI_CTRL2_INTSTS_SHIFT);
> +	gemini_pci_write_config(p->bus, 0, GEMINI_PCI_CTRL2, 4, reg);
> +}
> +
> +static void gemini_pci_mask_irq(struct irq_data *d)
> +{
> +	struct gemini_pci *p = irq_data_get_irq_chip_data(d);
> +	unsigned int reg;
> +
> +	gemini_pci_read_config(p->bus, 0, GEMINI_PCI_CTRL2, 4, &reg);
> +	reg &= ~((0xF << PCI_CTRL2_INTSTS_SHIFT)
> +		 | BIT(irqd_to_hwirq(d) + PCI_CTRL2_INTMASK_SHIFT));
> +	gemini_pci_write_config(p->bus, 0, GEMINI_PCI_CTRL2, 4, reg);
> +}
> +
> +static void gemini_pci_unmask_irq(struct irq_data *d)
> +{
> +	struct gemini_pci *p = irq_data_get_irq_chip_data(d);
> +	unsigned int reg;
> +
> +	gemini_pci_read_config(p->bus, 0, GEMINI_PCI_CTRL2, 4, &reg);
> +	reg &= ~(0xF << PCI_CTRL2_INTSTS_SHIFT);
> +	reg |= BIT(irqd_to_hwirq(d) + PCI_CTRL2_INTMASK_SHIFT);
> +	gemini_pci_write_config(p->bus, 0, GEMINI_PCI_CTRL2, 4, reg);
> +}
> +
> +static void gemini_pci_irq_handler(struct irq_desc *desc)
> +{
> +	struct gemini_pci *p = irq_desc_get_handler_data(desc);
> +	struct irq_chip *irqchip = irq_desc_get_chip(desc);
> +	unsigned int irq_stat, reg, i;
> +
> +	gemini_pci_read_config(p->bus, 0, GEMINI_PCI_CTRL2, 4, &reg);
> +	irq_stat = reg >> PCI_CTRL2_INTSTS_SHIFT;
> +
> +	chained_irq_enter(irqchip, desc);
> +
> +	for (i = 0; i < 4; i++) {
> +		if ((irq_stat & BIT(i)) == 0)
> +			continue;
> +		generic_handle_irq(irq_find_mapping(p->irqdomain, i));
> +	}
> +
> +	chained_irq_exit(irqchip, desc);
> +}
> +
> +static struct irq_chip gemini_pci_irq_chip = {
> +	.name = "PCI",
> +	.irq_ack = gemini_pci_ack_irq,
> +	.irq_mask = gemini_pci_mask_irq,
> +	.irq_unmask = gemini_pci_unmask_irq,
> +};
> +
> +static int gemini_pci_irq_map(struct irq_domain *domain, unsigned int irq,
> +			      irq_hw_number_t hwirq)
> +{
> +	irq_set_chip_and_handler(irq, &gemini_pci_irq_chip, handle_level_irq);
> +	irq_set_chip_data(irq, domain->host_data);
> +
> +	return 0;
> +}
> +
> +static const struct irq_domain_ops gemini_pci_irqdomain_ops = {
> +	.map = gemini_pci_irq_map,
> +};
> +
> +static int gemini_pci_setup_irq(struct gemini_pci *p, int irq)
> +{
> +	struct device_node *intc = of_get_next_child(p->dev->of_node, NULL);
> +	int i;
> +
> +	if (!intc) {
> +		dev_err(p->dev, "missing child interrupt-controller node\n");
> +		return -EINVAL;
> +	}
> +
> +	p->irqdomain = irq_domain_add_linear(intc, 4,
> +					     &gemini_pci_irqdomain_ops,
> +					     p);
> +	if (!p->irqdomain) {
> +		dev_err(p->dev, "failed to create Gemini PCI IRQ domain\n");
> +		return -EINVAL;
> +	}
> +
> +	irq_set_chained_handler_and_data(irq, gemini_pci_irq_handler, p);
> +
> +	for (i = 0; i < 4; i++)
> +		irq_create_mapping(p->irqdomain, i);
> +
> +	return 0;
> +}
> +
> +static int gemini_pci_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct resource *regs;
> +	resource_size_t io_base;
> +	struct resource_entry *win;
> +	struct gemini_pci *p;
> +	struct resource *mem;
> +	struct resource *io;
> +	struct pci_bus *bus;
> +	int irq;
> +	int ret;
> +	u32 val;
> +	LIST_HEAD(res);
> +
> +	p = devm_kzalloc(dev, sizeof(*p), GFP_KERNEL);
> +	if (!p)
> +		return -ENOMEM;
> +
> +	p->dev = dev;
> +	spin_lock_init(&p->lock);
> +
> +	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	p->base = devm_ioremap_resource(dev, regs);
> +	if (IS_ERR(p->base))
> +		return PTR_ERR(p->base);
> +
> +	ret = of_pci_get_host_bridge_resources(dev->of_node, 0, 0xff,
> +					       &res, &io_base);
> +	if (ret)
> +		return ret;
> +
> +	ret = devm_request_pci_bus_resources(dev, &res);
> +	if (ret)
> +		return ret;
> +
> +	/* No clue what these do */
> +	pcibios_min_io = 0x100;
> +	pcibios_min_mem = 0;
> +
> +	/* setup I/O space to 1MB size */
> +	writel(GEMINI_PCI_IOSIZE_1M, p->base + PCI_IOSIZE);
> +
> +	/* setup hostbridge */
> +	val = readl(p->base + PCI_CTRL);
> +	val |= PCI_COMMAND_IO;
> +	val |= PCI_COMMAND_MEMORY;
> +	val |= PCI_COMMAND_MASTER;
> +	writel(val, p->base + PCI_CTRL);
> +
> +	/* Get the I/O and memory ranges from DT */
> +	resource_list_for_each_entry(win, &res) {
> +		switch (resource_type(win->res)) {
> +		case IORESOURCE_IO:
> +			io = win->res;
> +			io->name = "Gemini PCI I/O";
> +			ret = pci_remap_iospace(io, io_base);
> +			if (ret) {
> +				dev_warn(dev, "error %d: failed to map resource %pR\n",
> +					 ret, io);
> +				continue;
> +			}
> +			break;
> +		case IORESOURCE_MEM:
> +			mem = win->res;
> +			mem->name = "Gemini PCI MEM";
> +			break;
> +		case IORESOURCE_BUS:
> +			break;
> +		default:
> +			break;
> +		}
> +	}
> +
> +	bus = pci_scan_root_bus(&pdev->dev, 0, &gemini_pci_ops, p, &res);
> +	if (!bus)
> +		return -ENOMEM;
> +	p->bus = bus;
> +
> +	dev_info(dev, "clear all IRQs\n");
> +
> +	/* Mask and clear all interrupts */
> +	gemini_pci_write_config(bus, 0, GEMINI_PCI_CTRL2 + 2, 2, 0xF000);
> +
> +	/* IRQ - all PCI IRQs cascade off this one */
> +	irq = platform_get_irq(pdev, 0);
> +	if (!irq) {
> +		dev_err(dev, "failed to get IRQ\n");
> +		return -EINVAL;
> +	}
> +
> +	ret = gemini_pci_setup_irq(p, irq);
> +	if (ret) {
> +		dev_err(dev, "failed to setup IRQ\n");
> +		return ret;
> +	}
> +
> +	dev_info(dev, "setting up PCI DMA\n");
> +	val = (GEMINI_PCI_DMA_MEM1_BASE & GEMINI_PCI_DMA_MASK)
> +		| (GEMINI_PCI_DMA_MEM1_SIZE << 16);
> +	gemini_pci_write_config(bus, 0, GEMINI_PCI_MEM1_BASE_SIZE, 4, val);
> +	val = (GEMINI_PCI_DMA_MEM2_BASE & GEMINI_PCI_DMA_MASK)
> +		| (GEMINI_PCI_DMA_MEM2_SIZE << 16);
> +	gemini_pci_write_config(bus, 0, GEMINI_PCI_MEM2_BASE_SIZE, 4, val);
> +	val = (GEMINI_PCI_DMA_MEM3_BASE & GEMINI_PCI_DMA_MASK)
> +		| (GEMINI_PCI_DMA_MEM3_SIZE << 16);
> +	gemini_pci_write_config(bus, 0, GEMINI_PCI_MEM3_BASE_SIZE, 4, val);
> +
> +	pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
> +	pci_bus_assign_resources(bus);
> +	pci_assign_unassigned_bus_resources(bus);
> +	pci_bus_add_devices(bus);
> +	pci_free_resource_list(&res);
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id gemini_pci_of_match[] = {
> +	{
> +		.compatible = "cortina,gemini-pci",
> +	},
> +	{},
> +};
> +
> +static struct platform_driver gemini_pci_driver = {
> +	.driver = {
> +		.name = "gemini-pci",
> +		.of_match_table = of_match_ptr(gemini_pci_of_match),
> +	},
> +	.probe  = gemini_pci_probe,
> +};
> +builtin_platform_driver(gemini_pci_driver);
> -- 
> 2.9.3
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 1/4] PCI: add DT bindings for Cortina Gemini PCI Host Bridge
  2017-01-28 20:48 ` Linus Walleij
  (?)
@ 2017-02-01 11:09     ` Arnd Bergmann
  -1 siblings, 0 replies; 64+ messages in thread
From: Arnd Bergmann @ 2017-02-01 11:09 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Hans Ulli Kroll, Florian Fainelli, Bjorn Helgaas, Janos Laube,
	Paulius Zaleckas, openwrt-devel-p3rKhJxN3npAfugRpC6u6w,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-pci-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA

On Saturday, January 28, 2017 9:48:36 PM CET Linus Walleij wrote:
> +       pci_intc: interrupt-controller {
> +               interrupt-controller;
> +               #address-cells = <0>;
> +               #interrupt-cells = <1>;
> +       };
> 


I think this one needs at least an interrupt-parent property, otherwise
you would recursively translate the numbers back through the interrupt-map
property of its parent.

	Arnd
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 1/4] PCI: add DT bindings for Cortina Gemini PCI Host Bridge
@ 2017-02-01 11:09     ` Arnd Bergmann
  0 siblings, 0 replies; 64+ messages in thread
From: Arnd Bergmann @ 2017-02-01 11:09 UTC (permalink / raw)
  To: Linus Walleij
  Cc: openwrt-devel, devicetree, Florian Fainelli, Paulius Zaleckas,
	linux-pci, Hans Ulli Kroll, Bjorn Helgaas, Janos Laube,
	linux-arm-kernel

On Saturday, January 28, 2017 9:48:36 PM CET Linus Walleij wrote:
> +       pci_intc: interrupt-controller {
> +               interrupt-controller;
> +               #address-cells = <0>;
> +               #interrupt-cells = <1>;
> +       };
> 


I think this one needs at least an interrupt-parent property, otherwise
you would recursively translate the numbers back through the interrupt-map
property of its parent.

	Arnd

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 1/4] PCI: add DT bindings for Cortina Gemini PCI Host Bridge
@ 2017-02-01 11:09     ` Arnd Bergmann
  0 siblings, 0 replies; 64+ messages in thread
From: Arnd Bergmann @ 2017-02-01 11:09 UTC (permalink / raw)
  To: linux-arm-kernel

On Saturday, January 28, 2017 9:48:36 PM CET Linus Walleij wrote:
> +       pci_intc: interrupt-controller {
> +               interrupt-controller;
> +               #address-cells = <0>;
> +               #interrupt-cells = <1>;
> +       };
> 


I think this one needs at least an interrupt-parent property, otherwise
you would recursively translate the numbers back through the interrupt-map
property of its parent.

	Arnd

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

* Re: [PATCH 2/4] PCI: add driver for Cortina Gemini Host Bridge
  2017-01-28 20:48   ` Linus Walleij
@ 2017-02-01 11:11     ` Arnd Bergmann
  -1 siblings, 0 replies; 64+ messages in thread
From: Arnd Bergmann @ 2017-02-01 11:11 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: openwrt-devel, Florian Fainelli, Paulius Zaleckas, linux-pci,
	Linus Walleij, Bjorn Helgaas, Janos Laube, Hans Ulli Kroll

On Saturday, January 28, 2017 9:48:37 PM CET Linus Walleij wrote:
> +static int gemini_pci_read_config(struct pci_bus *bus, unsigned int fn,
> +				  int config, int size, u32 *value)
> +{
> +	struct gemini_pci *p = bus->sysdata;
> +	unsigned long irq_flags;
> +
> +	spin_lock_irqsave(&p->lock, irq_flags);
> +
> +	writel(PCI_CONF_BUS(bus->number) |
> +			PCI_CONF_DEVICE(PCI_SLOT(fn)) |
> +			PCI_CONF_FUNCTION(PCI_FUNC(fn)) |
> +			PCI_CONF_WHERE(config) |
> +			PCI_CONF_ENABLE,
> +			p->base + PCI_CONFIG);
> +
> +	*value = readl(p->base + PCI_DATA);
> +
> +	if (size == 1)
> +		*value = (*value >> (8 * (config & 3))) & 0xFF;
> +	else if (size == 2)
> +		*value = (*value >> (8 * (config & 3))) & 0xFFFF;
> +
> +	spin_unlock_irqrestore(&p->lock, irq_flags);

The read_config/write_config functions are called under a spinlock,
no need for another one.

> +	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	p->base = devm_ioremap_resource(dev, regs);
> +	if (IS_ERR(p->base))
> +		return PTR_ERR(p->base);
> +
> +	ret = of_pci_get_host_bridge_resources(dev->of_node, 0, 0xff,
> +					       &res, &io_base);
> +	if (ret)
> +		return ret;
> +
> +	ret = devm_request_pci_bus_resources(dev, &res);
> +	if (ret)
> +		return ret;
> +
> +	/* No clue what these do */
> +	pcibios_min_io = 0x100;
> +	pcibios_min_mem = 0;

Don't touch these

> +	/* setup I/O space to 1MB size */
> +	writel(GEMINI_PCI_IOSIZE_1M, p->base + PCI_IOSIZE);

Maybe get the size from the resource instead? Note that pci_remap_iospace
only registers 64K of I/O space, so you could also use that.

> +	/* setup hostbridge */
> +	val = readl(p->base + PCI_CTRL);
> +	val |= PCI_COMMAND_IO;
> +	val |= PCI_COMMAND_MEMORY;
> +	val |= PCI_COMMAND_MASTER;
> +	writel(val, p->base + PCI_CTRL);
> +
> +	/* Get the I/O and memory ranges from DT */
> +	resource_list_for_each_entry(win, &res) {
> +		switch (resource_type(win->res)) {
> +		case IORESOURCE_IO:
> +			io = win->res;
> +			io->name = "Gemini PCI I/O";
> +			ret = pci_remap_iospace(io, io_base);
> +			if (ret) {
> +				dev_warn(dev, "error %d: failed to map resource %pR\n",
> +					 ret, io);
> +				continue;
> +			}
> +			break;
> +		case IORESOURCE_MEM:
> +			mem = win->res;
> +			mem->name = "Gemini PCI MEM";
> +			break;
> +		case IORESOURCE_BUS:
> +			break;
> +		default:
> +			break;
> +		}
> +	}
> +
> +	bus = pci_scan_root_bus(&pdev->dev, 0, &gemini_pci_ops, p, &res);

Can you try using the new pci_register_host_bridge() API?

	Arnd

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 2/4] PCI: add driver for Cortina Gemini Host Bridge
@ 2017-02-01 11:11     ` Arnd Bergmann
  0 siblings, 0 replies; 64+ messages in thread
From: Arnd Bergmann @ 2017-02-01 11:11 UTC (permalink / raw)
  To: linux-arm-kernel

On Saturday, January 28, 2017 9:48:37 PM CET Linus Walleij wrote:
> +static int gemini_pci_read_config(struct pci_bus *bus, unsigned int fn,
> +				  int config, int size, u32 *value)
> +{
> +	struct gemini_pci *p = bus->sysdata;
> +	unsigned long irq_flags;
> +
> +	spin_lock_irqsave(&p->lock, irq_flags);
> +
> +	writel(PCI_CONF_BUS(bus->number) |
> +			PCI_CONF_DEVICE(PCI_SLOT(fn)) |
> +			PCI_CONF_FUNCTION(PCI_FUNC(fn)) |
> +			PCI_CONF_WHERE(config) |
> +			PCI_CONF_ENABLE,
> +			p->base + PCI_CONFIG);
> +
> +	*value = readl(p->base + PCI_DATA);
> +
> +	if (size == 1)
> +		*value = (*value >> (8 * (config & 3))) & 0xFF;
> +	else if (size == 2)
> +		*value = (*value >> (8 * (config & 3))) & 0xFFFF;
> +
> +	spin_unlock_irqrestore(&p->lock, irq_flags);

The read_config/write_config functions are called under a spinlock,
no need for another one.

> +	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	p->base = devm_ioremap_resource(dev, regs);
> +	if (IS_ERR(p->base))
> +		return PTR_ERR(p->base);
> +
> +	ret = of_pci_get_host_bridge_resources(dev->of_node, 0, 0xff,
> +					       &res, &io_base);
> +	if (ret)
> +		return ret;
> +
> +	ret = devm_request_pci_bus_resources(dev, &res);
> +	if (ret)
> +		return ret;
> +
> +	/* No clue what these do */
> +	pcibios_min_io = 0x100;
> +	pcibios_min_mem = 0;

Don't touch these

> +	/* setup I/O space to 1MB size */
> +	writel(GEMINI_PCI_IOSIZE_1M, p->base + PCI_IOSIZE);

Maybe get the size from the resource instead? Note that pci_remap_iospace
only registers 64K of I/O space, so you could also use that.

> +	/* setup hostbridge */
> +	val = readl(p->base + PCI_CTRL);
> +	val |= PCI_COMMAND_IO;
> +	val |= PCI_COMMAND_MEMORY;
> +	val |= PCI_COMMAND_MASTER;
> +	writel(val, p->base + PCI_CTRL);
> +
> +	/* Get the I/O and memory ranges from DT */
> +	resource_list_for_each_entry(win, &res) {
> +		switch (resource_type(win->res)) {
> +		case IORESOURCE_IO:
> +			io = win->res;
> +			io->name = "Gemini PCI I/O";
> +			ret = pci_remap_iospace(io, io_base);
> +			if (ret) {
> +				dev_warn(dev, "error %d: failed to map resource %pR\n",
> +					 ret, io);
> +				continue;
> +			}
> +			break;
> +		case IORESOURCE_MEM:
> +			mem = win->res;
> +			mem->name = "Gemini PCI MEM";
> +			break;
> +		case IORESOURCE_BUS:
> +			break;
> +		default:
> +			break;
> +		}
> +	}
> +
> +	bus = pci_scan_root_bus(&pdev->dev, 0, &gemini_pci_ops, p, &res);

Can you try using the new pci_register_host_bridge() API?

	Arnd

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

* Re: [PATCH 1/4] PCI: add DT bindings for Cortina Gemini PCI Host Bridge
  2017-01-28 20:48 ` Linus Walleij
  (?)
@ 2017-02-01 11:19   ` Arnd Bergmann
  -1 siblings, 0 replies; 64+ messages in thread
From: Arnd Bergmann @ 2017-02-01 11:19 UTC (permalink / raw)
  To: Linus Walleij
  Cc: openwrt-devel, devicetree, Florian Fainelli, Paulius Zaleckas,
	linux-pci, Hans Ulli Kroll, Bjorn Helgaas, Janos Laube,
	linux-arm-kernel

On Saturday, January 28, 2017 9:48:36 PM CET Linus Walleij wrote:
> +       interrupt-map-mask = <0xff00 0 0 7>;
> +       interrupt-map = <0x4800 0 0 1 &pci_intc 0>, /* Slot 9 */
> +                       <0x4900 0 0 2 &pci_intc 1>,
> +                       <0x4a00 0 0 3 &pci_intc 2>,
> +                       <0x4b00 0 0 4 &pci_intc 3>,
> +                       <0x5000 0 0 1 &pci_intc 0>, /* Slot 10 */
> +                       <0x5100 0 0 2 &pci_intc 1>,
> +                       <0x5200 0 0 3 &pci_intc 2>,
> +                       <0x5300 0 0 4 &pci_intc 3>,
> +                       <0x5800 0 0 1 &pci_intc 0>, /* Slot 11 */
> +                       <0x5900 0 0 2 &pci_intc 1>,
> +                       <0x5a00 0 0 3 &pci_intc 2>,
> +                       <0x5b00 0 0 4 &pci_intc 3>,
> +                       <0x6000 0 0 1 &pci_intc 0>, /* Slot 12 */
> +                       <0x6100 0 0 2 &pci_intc 1>,
> +                       <0x6200 0 0 3 &pci_intc 2>,
> +                       <0x6300 0 0 4 &pci_intc 3>;
> 

The mapping looks wrong here, we normally don't list interrupts per function
so the mask should be 0xf800.

Note that the interrupt map is board specific, so this should probably
go in the board.dts file rather than platform.dtsi.

For this particular board, the interrupt lines appear to have been badly
configured so all slots use the same interrupt 0 for IntA. IIRC This also
means you can probably use <0 0 0 7> as the mask and just specify each of
the four interrupts once. A properly wired board would swizzle the
interrupts so that each slot has a different IRQ for its IntA line.

	Arnd

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

* Re: [PATCH 1/4] PCI: add DT bindings for Cortina Gemini PCI Host Bridge
@ 2017-02-01 11:19   ` Arnd Bergmann
  0 siblings, 0 replies; 64+ messages in thread
From: Arnd Bergmann @ 2017-02-01 11:19 UTC (permalink / raw)
  To: Linus Walleij
  Cc: openwrt-devel, devicetree, Florian Fainelli, Paulius Zaleckas,
	linux-pci, Hans Ulli Kroll, Bjorn Helgaas, Janos Laube,
	linux-arm-kernel

On Saturday, January 28, 2017 9:48:36 PM CET Linus Walleij wrote:
> +       interrupt-map-mask = <0xff00 0 0 7>;
> +       interrupt-map = <0x4800 0 0 1 &pci_intc 0>, /* Slot 9 */
> +                       <0x4900 0 0 2 &pci_intc 1>,
> +                       <0x4a00 0 0 3 &pci_intc 2>,
> +                       <0x4b00 0 0 4 &pci_intc 3>,
> +                       <0x5000 0 0 1 &pci_intc 0>, /* Slot 10 */
> +                       <0x5100 0 0 2 &pci_intc 1>,
> +                       <0x5200 0 0 3 &pci_intc 2>,
> +                       <0x5300 0 0 4 &pci_intc 3>,
> +                       <0x5800 0 0 1 &pci_intc 0>, /* Slot 11 */
> +                       <0x5900 0 0 2 &pci_intc 1>,
> +                       <0x5a00 0 0 3 &pci_intc 2>,
> +                       <0x5b00 0 0 4 &pci_intc 3>,
> +                       <0x6000 0 0 1 &pci_intc 0>, /* Slot 12 */
> +                       <0x6100 0 0 2 &pci_intc 1>,
> +                       <0x6200 0 0 3 &pci_intc 2>,
> +                       <0x6300 0 0 4 &pci_intc 3>;
> 

The mapping looks wrong here, we normally don't list interrupts per function
so the mask should be 0xf800.

Note that the interrupt map is board specific, so this should probably
go in the board.dts file rather than platform.dtsi.

For this particular board, the interrupt lines appear to have been badly
configured so all slots use the same interrupt 0 for IntA. IIRC This also
means you can probably use <0 0 0 7> as the mask and just specify each of
the four interrupts once. A properly wired board would swizzle the
interrupts so that each slot has a different IRQ for its IntA line.

	Arnd

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 1/4] PCI: add DT bindings for Cortina Gemini PCI Host Bridge
@ 2017-02-01 11:19   ` Arnd Bergmann
  0 siblings, 0 replies; 64+ messages in thread
From: Arnd Bergmann @ 2017-02-01 11:19 UTC (permalink / raw)
  To: linux-arm-kernel

On Saturday, January 28, 2017 9:48:36 PM CET Linus Walleij wrote:
> +       interrupt-map-mask = <0xff00 0 0 7>;
> +       interrupt-map = <0x4800 0 0 1 &pci_intc 0>, /* Slot 9 */
> +                       <0x4900 0 0 2 &pci_intc 1>,
> +                       <0x4a00 0 0 3 &pci_intc 2>,
> +                       <0x4b00 0 0 4 &pci_intc 3>,
> +                       <0x5000 0 0 1 &pci_intc 0>, /* Slot 10 */
> +                       <0x5100 0 0 2 &pci_intc 1>,
> +                       <0x5200 0 0 3 &pci_intc 2>,
> +                       <0x5300 0 0 4 &pci_intc 3>,
> +                       <0x5800 0 0 1 &pci_intc 0>, /* Slot 11 */
> +                       <0x5900 0 0 2 &pci_intc 1>,
> +                       <0x5a00 0 0 3 &pci_intc 2>,
> +                       <0x5b00 0 0 4 &pci_intc 3>,
> +                       <0x6000 0 0 1 &pci_intc 0>, /* Slot 12 */
> +                       <0x6100 0 0 2 &pci_intc 1>,
> +                       <0x6200 0 0 3 &pci_intc 2>,
> +                       <0x6300 0 0 4 &pci_intc 3>;
> 

The mapping looks wrong here, we normally don't list interrupts per function
so the mask should be 0xf800.

Note that the interrupt map is board specific, so this should probably
go in the board.dts file rather than platform.dtsi.

For this particular board, the interrupt lines appear to have been badly
configured so all slots use the same interrupt 0 for IntA. IIRC This also
means you can probably use <0 0 0 7> as the mask and just specify each of
the four interrupts once. A properly wired board would swizzle the
interrupts so that each slot has a different IRQ for its IntA line.

	Arnd

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

* Re: [PATCH 1/4] PCI: add DT bindings for Cortina Gemini PCI Host Bridge
  2017-01-28 20:48 ` Linus Walleij
  (?)
@ 2017-02-01 16:02   ` Rob Herring
  -1 siblings, 0 replies; 64+ messages in thread
From: Rob Herring @ 2017-02-01 16:02 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Hans Ulli Kroll, Florian Fainelli, Bjorn Helgaas, Janos Laube,
	Paulius Zaleckas, openwrt-devel, linux-arm-kernel, linux-pci,
	devicetree

On Sat, Jan 28, 2017 at 09:48:36PM +0100, Linus Walleij wrote:
> This adds device tree bindings for the Cortina Systems Gemini PCI
> Host Bridge.
> 
> Cc: Janos Laube <janos.dev@gmail.com>
> Cc: Paulius Zaleckas <paulius.zaleckas@gmail.com>
> Cc: Hans Ulli Kroll <ulli.kroll@googlemail.com>
> Cc: Florian Fainelli <f.fainelli@gmail.com>
> Cc: devicetree@vger.kernel.org
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
> This can be merged to the PCI tree whenever it is considered
> fine for inclusion.
> ---
>  .../devicetree/bindings/pci/cortina,gemini-pci.txt | 64 ++++++++++++++++++++++
>  1 file changed, 64 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/pci/cortina,gemini-pci.txt
> 
> diff --git a/Documentation/devicetree/bindings/pci/cortina,gemini-pci.txt b/Documentation/devicetree/bindings/pci/cortina,gemini-pci.txt
> new file mode 100644
> index 000000000000..e3090d995e1e
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pci/cortina,gemini-pci.txt
> @@ -0,0 +1,64 @@
> +* Cortina Systems Gemini PCI Host Bridge
> +
> +Mandatory properties:
> +
> +- compatible: should be "cortina,gemini-pci"
> +- reg: memory base and size for the host bridge
> +- interrupts: the four PCI interrupts
> +- #address-cells: set to <3>
> +- #size-cells: set to <2>
> +- #interrupt-cells: set to <1>
> +- bus-range: set to <0x00 0x00> (only root bus)
> +- device_type, set to "pci"
> +- ranges: see pci.txt

You need to specify what ranges should have for this bridge.

> +- interrupt-map-mask: see pci.txt
> +- interrupt-map: see pci.txt
> +
> +Mandatory subnodes:
> +- One node reprenting the interrupt-controller inside the host bridge
> +  with the following mandatory properties:
> +  - interrupt-controller: see interrupt-controller/interrupts.txt
> +  - #address-cells: set to <0>
> +  - #interrupt-cells: set to <1>
> +
> +Example:
> +
> +pci@50000000 {
> +	compatible = "cortina,gemini-pci";
> +	reg = <0x50000000 0x100>;

Config space is indirectly accessed?

> +	interrupts = <8 IRQ_TYPE_LEVEL_HIGH>, /* PCI A */
> +			<26 IRQ_TYPE_LEVEL_HIGH>, /* PCI B */
> +			<27 IRQ_TYPE_LEVEL_HIGH>, /* PCI C */
> +			<28 IRQ_TYPE_LEVEL_HIGH>; /* PCI D */
> +	#address-cells = <3>;
> +	#size-cells = <2>;
> +	#interrupt-cells = <1>;
> +
> +	bus-range = <0x00 0x00>; /* Only root bus */
> +	ranges = /* 1MiB I/O space 0x50000000-0x500fffff */
> +		 <0x01000000 0 0          0x50000000 0 0x00100000>,
> +		 /* 128MiB non-prefetchable memory 0x58000000-0x5fffffff */
> +		 <0x02000000 0 0x58000000 0x58000000 0 0x08000000>;
> +	interrupt-map-mask = <0xff00 0 0 7>;
> +	interrupt-map = <0x4800 0 0 1 &pci_intc 0>, /* Slot 9 */
> +			<0x4900 0 0 2 &pci_intc 1>,
> +			<0x4a00 0 0 3 &pci_intc 2>,
> +			<0x4b00 0 0 4 &pci_intc 3>,
> +			<0x5000 0 0 1 &pci_intc 0>, /* Slot 10 */
> +			<0x5100 0 0 2 &pci_intc 1>,
> +			<0x5200 0 0 3 &pci_intc 2>,
> +			<0x5300 0 0 4 &pci_intc 3>,
> +			<0x5800 0 0 1 &pci_intc 0>, /* Slot 11 */
> +			<0x5900 0 0 2 &pci_intc 1>,
> +			<0x5a00 0 0 3 &pci_intc 2>,
> +			<0x5b00 0 0 4 &pci_intc 3>,
> +			<0x6000 0 0 1 &pci_intc 0>, /* Slot 12 */
> +			<0x6100 0 0 2 &pci_intc 1>,
> +			<0x6200 0 0 3 &pci_intc 2>,
> +			<0x6300 0 0 4 &pci_intc 3>;
> +	pci_intc: interrupt-controller {
> +		interrupt-controller;
> +		#address-cells = <0>;
> +		#interrupt-cells = <1>;
> +	};
> +};
> -- 
> 2.9.3
> 
> --
> To unsubscribe from this list: send the line "unsubscribe devicetree" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 1/4] PCI: add DT bindings for Cortina Gemini PCI Host Bridge
@ 2017-02-01 16:02   ` Rob Herring
  0 siblings, 0 replies; 64+ messages in thread
From: Rob Herring @ 2017-02-01 16:02 UTC (permalink / raw)
  To: Linus Walleij
  Cc: openwrt-devel, devicetree, Florian Fainelli, Paulius Zaleckas,
	linux-pci, Hans Ulli Kroll, Bjorn Helgaas, Janos Laube,
	linux-arm-kernel

On Sat, Jan 28, 2017 at 09:48:36PM +0100, Linus Walleij wrote:
> This adds device tree bindings for the Cortina Systems Gemini PCI
> Host Bridge.
> 
> Cc: Janos Laube <janos.dev@gmail.com>
> Cc: Paulius Zaleckas <paulius.zaleckas@gmail.com>
> Cc: Hans Ulli Kroll <ulli.kroll@googlemail.com>
> Cc: Florian Fainelli <f.fainelli@gmail.com>
> Cc: devicetree@vger.kernel.org
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
> This can be merged to the PCI tree whenever it is considered
> fine for inclusion.
> ---
>  .../devicetree/bindings/pci/cortina,gemini-pci.txt | 64 ++++++++++++++++++++++
>  1 file changed, 64 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/pci/cortina,gemini-pci.txt
> 
> diff --git a/Documentation/devicetree/bindings/pci/cortina,gemini-pci.txt b/Documentation/devicetree/bindings/pci/cortina,gemini-pci.txt
> new file mode 100644
> index 000000000000..e3090d995e1e
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pci/cortina,gemini-pci.txt
> @@ -0,0 +1,64 @@
> +* Cortina Systems Gemini PCI Host Bridge
> +
> +Mandatory properties:
> +
> +- compatible: should be "cortina,gemini-pci"
> +- reg: memory base and size for the host bridge
> +- interrupts: the four PCI interrupts
> +- #address-cells: set to <3>
> +- #size-cells: set to <2>
> +- #interrupt-cells: set to <1>
> +- bus-range: set to <0x00 0x00> (only root bus)
> +- device_type, set to "pci"
> +- ranges: see pci.txt

You need to specify what ranges should have for this bridge.

> +- interrupt-map-mask: see pci.txt
> +- interrupt-map: see pci.txt
> +
> +Mandatory subnodes:
> +- One node reprenting the interrupt-controller inside the host bridge
> +  with the following mandatory properties:
> +  - interrupt-controller: see interrupt-controller/interrupts.txt
> +  - #address-cells: set to <0>
> +  - #interrupt-cells: set to <1>
> +
> +Example:
> +
> +pci@50000000 {
> +	compatible = "cortina,gemini-pci";
> +	reg = <0x50000000 0x100>;

Config space is indirectly accessed?

> +	interrupts = <8 IRQ_TYPE_LEVEL_HIGH>, /* PCI A */
> +			<26 IRQ_TYPE_LEVEL_HIGH>, /* PCI B */
> +			<27 IRQ_TYPE_LEVEL_HIGH>, /* PCI C */
> +			<28 IRQ_TYPE_LEVEL_HIGH>; /* PCI D */
> +	#address-cells = <3>;
> +	#size-cells = <2>;
> +	#interrupt-cells = <1>;
> +
> +	bus-range = <0x00 0x00>; /* Only root bus */
> +	ranges = /* 1MiB I/O space 0x50000000-0x500fffff */
> +		 <0x01000000 0 0          0x50000000 0 0x00100000>,
> +		 /* 128MiB non-prefetchable memory 0x58000000-0x5fffffff */
> +		 <0x02000000 0 0x58000000 0x58000000 0 0x08000000>;
> +	interrupt-map-mask = <0xff00 0 0 7>;
> +	interrupt-map = <0x4800 0 0 1 &pci_intc 0>, /* Slot 9 */
> +			<0x4900 0 0 2 &pci_intc 1>,
> +			<0x4a00 0 0 3 &pci_intc 2>,
> +			<0x4b00 0 0 4 &pci_intc 3>,
> +			<0x5000 0 0 1 &pci_intc 0>, /* Slot 10 */
> +			<0x5100 0 0 2 &pci_intc 1>,
> +			<0x5200 0 0 3 &pci_intc 2>,
> +			<0x5300 0 0 4 &pci_intc 3>,
> +			<0x5800 0 0 1 &pci_intc 0>, /* Slot 11 */
> +			<0x5900 0 0 2 &pci_intc 1>,
> +			<0x5a00 0 0 3 &pci_intc 2>,
> +			<0x5b00 0 0 4 &pci_intc 3>,
> +			<0x6000 0 0 1 &pci_intc 0>, /* Slot 12 */
> +			<0x6100 0 0 2 &pci_intc 1>,
> +			<0x6200 0 0 3 &pci_intc 2>,
> +			<0x6300 0 0 4 &pci_intc 3>;
> +	pci_intc: interrupt-controller {
> +		interrupt-controller;
> +		#address-cells = <0>;
> +		#interrupt-cells = <1>;
> +	};
> +};
> -- 
> 2.9.3
> 
> --
> To unsubscribe from this list: send the line "unsubscribe devicetree" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 1/4] PCI: add DT bindings for Cortina Gemini PCI Host Bridge
@ 2017-02-01 16:02   ` Rob Herring
  0 siblings, 0 replies; 64+ messages in thread
From: Rob Herring @ 2017-02-01 16:02 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Jan 28, 2017 at 09:48:36PM +0100, Linus Walleij wrote:
> This adds device tree bindings for the Cortina Systems Gemini PCI
> Host Bridge.
> 
> Cc: Janos Laube <janos.dev@gmail.com>
> Cc: Paulius Zaleckas <paulius.zaleckas@gmail.com>
> Cc: Hans Ulli Kroll <ulli.kroll@googlemail.com>
> Cc: Florian Fainelli <f.fainelli@gmail.com>
> Cc: devicetree at vger.kernel.org
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
> This can be merged to the PCI tree whenever it is considered
> fine for inclusion.
> ---
>  .../devicetree/bindings/pci/cortina,gemini-pci.txt | 64 ++++++++++++++++++++++
>  1 file changed, 64 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/pci/cortina,gemini-pci.txt
> 
> diff --git a/Documentation/devicetree/bindings/pci/cortina,gemini-pci.txt b/Documentation/devicetree/bindings/pci/cortina,gemini-pci.txt
> new file mode 100644
> index 000000000000..e3090d995e1e
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pci/cortina,gemini-pci.txt
> @@ -0,0 +1,64 @@
> +* Cortina Systems Gemini PCI Host Bridge
> +
> +Mandatory properties:
> +
> +- compatible: should be "cortina,gemini-pci"
> +- reg: memory base and size for the host bridge
> +- interrupts: the four PCI interrupts
> +- #address-cells: set to <3>
> +- #size-cells: set to <2>
> +- #interrupt-cells: set to <1>
> +- bus-range: set to <0x00 0x00> (only root bus)
> +- device_type, set to "pci"
> +- ranges: see pci.txt

You need to specify what ranges should have for this bridge.

> +- interrupt-map-mask: see pci.txt
> +- interrupt-map: see pci.txt
> +
> +Mandatory subnodes:
> +- One node reprenting the interrupt-controller inside the host bridge
> +  with the following mandatory properties:
> +  - interrupt-controller: see interrupt-controller/interrupts.txt
> +  - #address-cells: set to <0>
> +  - #interrupt-cells: set to <1>
> +
> +Example:
> +
> +pci at 50000000 {
> +	compatible = "cortina,gemini-pci";
> +	reg = <0x50000000 0x100>;

Config space is indirectly accessed?

> +	interrupts = <8 IRQ_TYPE_LEVEL_HIGH>, /* PCI A */
> +			<26 IRQ_TYPE_LEVEL_HIGH>, /* PCI B */
> +			<27 IRQ_TYPE_LEVEL_HIGH>, /* PCI C */
> +			<28 IRQ_TYPE_LEVEL_HIGH>; /* PCI D */
> +	#address-cells = <3>;
> +	#size-cells = <2>;
> +	#interrupt-cells = <1>;
> +
> +	bus-range = <0x00 0x00>; /* Only root bus */
> +	ranges = /* 1MiB I/O space 0x50000000-0x500fffff */
> +		 <0x01000000 0 0          0x50000000 0 0x00100000>,
> +		 /* 128MiB non-prefetchable memory 0x58000000-0x5fffffff */
> +		 <0x02000000 0 0x58000000 0x58000000 0 0x08000000>;
> +	interrupt-map-mask = <0xff00 0 0 7>;
> +	interrupt-map = <0x4800 0 0 1 &pci_intc 0>, /* Slot 9 */
> +			<0x4900 0 0 2 &pci_intc 1>,
> +			<0x4a00 0 0 3 &pci_intc 2>,
> +			<0x4b00 0 0 4 &pci_intc 3>,
> +			<0x5000 0 0 1 &pci_intc 0>, /* Slot 10 */
> +			<0x5100 0 0 2 &pci_intc 1>,
> +			<0x5200 0 0 3 &pci_intc 2>,
> +			<0x5300 0 0 4 &pci_intc 3>,
> +			<0x5800 0 0 1 &pci_intc 0>, /* Slot 11 */
> +			<0x5900 0 0 2 &pci_intc 1>,
> +			<0x5a00 0 0 3 &pci_intc 2>,
> +			<0x5b00 0 0 4 &pci_intc 3>,
> +			<0x6000 0 0 1 &pci_intc 0>, /* Slot 12 */
> +			<0x6100 0 0 2 &pci_intc 1>,
> +			<0x6200 0 0 3 &pci_intc 2>,
> +			<0x6300 0 0 4 &pci_intc 3>;
> +	pci_intc: interrupt-controller {
> +		interrupt-controller;
> +		#address-cells = <0>;
> +		#interrupt-cells = <1>;
> +	};
> +};
> -- 
> 2.9.3
> 
> --
> To unsubscribe from this list: send the line "unsubscribe devicetree" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 1/4] PCI: add DT bindings for Cortina Gemini PCI Host Bridge
  2017-01-31  0:31   ` Bjorn Helgaas
  (?)
@ 2017-02-01 20:00       ` Linus Walleij
  -1 siblings, 0 replies; 64+ messages in thread
From: Linus Walleij @ 2017-02-01 20:00 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Hans Ulli Kroll, Florian Fainelli, Bjorn Helgaas, Janos Laube,
	Paulius Zaleckas, openwrt-devel-p3rKhJxN3npAfugRpC6u6w,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, linux-pci,
	devicetree-u79uwXL29TY76Z2rM5mHXA

On Tue, Jan 31, 2017 at 1:31 AM, Bjorn Helgaas <helgaas-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:

>> +- bus-range: set to <0x00 0x00> (only root bus)
>
> Why is this limited to bus 0?  Is everything completely soldered down
> with no possibility of adding or replacing PCI devices? The interrupt-map
> below suggests slots, though.  If there's a slot, we could plug in a card
> with a bridge, which would mean more than just bus 0.

I thought so because it's a NAS box (the typical usecase) but when I
dismantled it and turned it over, wow, there is indeed a MiniPCI
slot!

OK I will augment this to 0x00 0xff.

Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 1/4] PCI: add DT bindings for Cortina Gemini PCI Host Bridge
@ 2017-02-01 20:00       ` Linus Walleij
  0 siblings, 0 replies; 64+ messages in thread
From: Linus Walleij @ 2017-02-01 20:00 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Hans Ulli Kroll, Florian Fainelli, Bjorn Helgaas, Janos Laube,
	Paulius Zaleckas, openwrt-devel, linux-arm-kernel, linux-pci,
	devicetree

On Tue, Jan 31, 2017 at 1:31 AM, Bjorn Helgaas <helgaas@kernel.org> wrote:

>> +- bus-range: set to <0x00 0x00> (only root bus)
>
> Why is this limited to bus 0?  Is everything completely soldered down
> with no possibility of adding or replacing PCI devices? The interrupt-map
> below suggests slots, though.  If there's a slot, we could plug in a card
> with a bridge, which would mean more than just bus 0.

I thought so because it's a NAS box (the typical usecase) but when I
dismantled it and turned it over, wow, there is indeed a MiniPCI
slot!

OK I will augment this to 0x00 0xff.

Yours,
Linus Walleij

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

* [PATCH 1/4] PCI: add DT bindings for Cortina Gemini PCI Host Bridge
@ 2017-02-01 20:00       ` Linus Walleij
  0 siblings, 0 replies; 64+ messages in thread
From: Linus Walleij @ 2017-02-01 20:00 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jan 31, 2017 at 1:31 AM, Bjorn Helgaas <helgaas@kernel.org> wrote:

>> +- bus-range: set to <0x00 0x00> (only root bus)
>
> Why is this limited to bus 0?  Is everything completely soldered down
> with no possibility of adding or replacing PCI devices? The interrupt-map
> below suggests slots, though.  If there's a slot, we could plug in a card
> with a bridge, which would mean more than just bus 0.

I thought so because it's a NAS box (the typical usecase) but when I
dismantled it and turned it over, wow, there is indeed a MiniPCI
slot!

OK I will augment this to 0x00 0xff.

Yours,
Linus Walleij

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

* Re: [PATCH 1/4] PCI: add DT bindings for Cortina Gemini PCI Host Bridge
  2017-02-01 16:02   ` Rob Herring
  (?)
@ 2017-02-01 20:04     ` Linus Walleij
  -1 siblings, 0 replies; 64+ messages in thread
From: Linus Walleij @ 2017-02-01 20:04 UTC (permalink / raw)
  To: Rob Herring
  Cc: Hans Ulli Kroll, Florian Fainelli, Bjorn Helgaas, Janos Laube,
	Paulius Zaleckas, openwrt-devel-p3rKhJxN3npAfugRpC6u6w,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, linux-pci,
	devicetree-u79uwXL29TY76Z2rM5mHXA

On Wed, Feb 1, 2017 at 5:02 PM, Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
> On Sat, Jan 28, 2017 at 09:48:36PM +0100, Linus Walleij wrote:

>> +Example:
>> +
>> +pci@50000000 {
>> +     compatible = "cortina,gemini-pci";
>> +     reg = <0x50000000 0x100>;
>
> Config space is indirectly accessed?

Yes it is a really annoying construction. The first device, the Faraday
roob hub is at that address, the init code uses that to set up the bus.

As soon as the bus is up, we use bus accessors to talk to the root
hub on slot 0 (this manages interrupts etc).

I guess I could even unmap this reg range at that point ...

I guess I could also get the address directly from the IO range
and start poking around. I don't know if that is any better.

Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 1/4] PCI: add DT bindings for Cortina Gemini PCI Host Bridge
@ 2017-02-01 20:04     ` Linus Walleij
  0 siblings, 0 replies; 64+ messages in thread
From: Linus Walleij @ 2017-02-01 20:04 UTC (permalink / raw)
  To: Rob Herring
  Cc: openwrt-devel, devicetree, Florian Fainelli, Paulius Zaleckas,
	linux-pci, Hans Ulli Kroll, Bjorn Helgaas, Janos Laube,
	linux-arm-kernel

On Wed, Feb 1, 2017 at 5:02 PM, Rob Herring <robh@kernel.org> wrote:
> On Sat, Jan 28, 2017 at 09:48:36PM +0100, Linus Walleij wrote:

>> +Example:
>> +
>> +pci@50000000 {
>> +     compatible = "cortina,gemini-pci";
>> +     reg = <0x50000000 0x100>;
>
> Config space is indirectly accessed?

Yes it is a really annoying construction. The first device, the Faraday
roob hub is at that address, the init code uses that to set up the bus.

As soon as the bus is up, we use bus accessors to talk to the root
hub on slot 0 (this manages interrupts etc).

I guess I could even unmap this reg range at that point ...

I guess I could also get the address directly from the IO range
and start poking around. I don't know if that is any better.

Yours,
Linus Walleij

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 1/4] PCI: add DT bindings for Cortina Gemini PCI Host Bridge
@ 2017-02-01 20:04     ` Linus Walleij
  0 siblings, 0 replies; 64+ messages in thread
From: Linus Walleij @ 2017-02-01 20:04 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Feb 1, 2017 at 5:02 PM, Rob Herring <robh@kernel.org> wrote:
> On Sat, Jan 28, 2017 at 09:48:36PM +0100, Linus Walleij wrote:

>> +Example:
>> +
>> +pci at 50000000 {
>> +     compatible = "cortina,gemini-pci";
>> +     reg = <0x50000000 0x100>;
>
> Config space is indirectly accessed?

Yes it is a really annoying construction. The first device, the Faraday
roob hub is at that address, the init code uses that to set up the bus.

As soon as the bus is up, we use bus accessors to talk to the root
hub on slot 0 (this manages interrupts etc).

I guess I could even unmap this reg range at that point ...

I guess I could also get the address directly from the IO range
and start poking around. I don't know if that is any better.

Yours,
Linus Walleij

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

* Re: [PATCH 2/4] PCI: add driver for Cortina Gemini Host Bridge
  2017-02-01 11:11     ` Arnd Bergmann
@ 2017-02-04 18:43       ` Linus Walleij
  -1 siblings, 0 replies; 64+ messages in thread
From: Linus Walleij @ 2017-02-04 18:43 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: openwrt-devel, Florian Fainelli, Paulius Zaleckas, linux-pci,
	Hans Ulli Kroll, Bjorn Helgaas, Janos Laube, linux-arm-kernel

On Wed, Feb 1, 2017 at 12:11 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Saturday, January 28, 2017 9:48:37 PM CET Linus Walleij wrote:

>> +     /* No clue what these do */
>> +     pcibios_min_io = 0x100;
>> +     pcibios_min_mem = 0;
>
> Don't touch these

OK I have a clue why this is there now, atleast the first one.

The first 0x100 in the IOspace is actually configuration registers
for the bridge. That is why we have this:

reg = <0x50000000 0x100>;
(...)
/* PCI ranges mappings */
                        ranges = /* 1MiB I/O space 0x50000000-0x500fffff */
                         <0x01000000 0 0          0x50000000 0 0x00100000>,

This is in all the vendor code I have located too.

So the pcibios_min_io is manipulated to avoid touching that
sensitive area. But I also see that arch/arm/mm/iomap.c
sets it to 0x1000, according to the commit because you said
it's the only valid value :D

I tried setting the IO range to <0x50000100 0x000FFF00>
instead of <0x50000000 0x00100000>
but predictably that doesn't work. Maybe it should, I don't
know really.

Yours,
Linus Walleij

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 2/4] PCI: add driver for Cortina Gemini Host Bridge
@ 2017-02-04 18:43       ` Linus Walleij
  0 siblings, 0 replies; 64+ messages in thread
From: Linus Walleij @ 2017-02-04 18:43 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Feb 1, 2017 at 12:11 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Saturday, January 28, 2017 9:48:37 PM CET Linus Walleij wrote:

>> +     /* No clue what these do */
>> +     pcibios_min_io = 0x100;
>> +     pcibios_min_mem = 0;
>
> Don't touch these

OK I have a clue why this is there now, atleast the first one.

The first 0x100 in the IOspace is actually configuration registers
for the bridge. That is why we have this:

reg = <0x50000000 0x100>;
(...)
/* PCI ranges mappings */
                        ranges = /* 1MiB I/O space 0x50000000-0x500fffff */
                         <0x01000000 0 0          0x50000000 0 0x00100000>,

This is in all the vendor code I have located too.

So the pcibios_min_io is manipulated to avoid touching that
sensitive area. But I also see that arch/arm/mm/iomap.c
sets it to 0x1000, according to the commit because you said
it's the only valid value :D

I tried setting the IO range to <0x50000100 0x000FFF00>
instead of <0x50000000 0x00100000>
but predictably that doesn't work. Maybe it should, I don't
know really.

Yours,
Linus Walleij

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

* Re: [PATCH 2/4] PCI: add driver for Cortina Gemini Host Bridge
  2017-01-28 20:48   ` Linus Walleij
@ 2017-02-05 10:00     ` Hans Ulli Kroll
  -1 siblings, 0 replies; 64+ messages in thread
From: Hans Ulli Kroll @ 2017-02-05 10:00 UTC (permalink / raw)
  To: Linus Walleij
  Cc: openwrt-devel, Florian Fainelli, Paulius Zaleckas, linux-pci,
	Hans Ulli Kroll, Bjorn Helgaas, Janos Laube, linux-arm-kernel

Hi Linus

while debugging my boot issues on my NAS 4220, I saw this warning

irq: type mismatch, failed to map hwirq-26 for /soc/interrupt-controller@48000000!

We need to use the use the use the PCI IRQ from gemini as root for the irq 
domain, not the next one in DT.

diff --git a/drivers/pci/host/pci-gemini.c b/drivers/pci/host/pci-gemini.c
index 7051dd992114..bb564a8e6379 100644
--- a/drivers/pci/host/pci-gemini.c
+++ b/drivers/pci/host/pci-gemini.c
@@ -217,7 +217,6 @@ static const struct irq_domain_ops gemini_pci_irqdomain_ops = {
 
 static int gemini_pci_setup_irq(struct gemini_pci *p, int irq)
 {
-	struct device_node *intc = of_get_next_child(p->dev->of_node, NULL);
 	int i;
 
 	if (!intc) {
@@ -225,7 +224,7 @@ static int gemini_pci_setup_irq(struct gemini_pci *p, int irq)
 		return -EINVAL;
 	}
 
-	p->irqdomain = irq_domain_add_linear(intc, 4,
+	p->irqdomain = irq_domain_add_linear(p->dev->of_node, 4,
 					     &gemini_pci_irqdomain_ops,
 					     p);
 	if (!p->irqdomain) {
-- 
2.11.0



_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 2/4] PCI: add driver for Cortina Gemini Host Bridge
@ 2017-02-05 10:00     ` Hans Ulli Kroll
  0 siblings, 0 replies; 64+ messages in thread
From: Hans Ulli Kroll @ 2017-02-05 10:00 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Linus

while debugging my boot issues on my NAS 4220, I saw this warning

irq: type mismatch, failed to map hwirq-26 for /soc/interrupt-controller at 48000000!

We need to use the use the use the PCI IRQ from gemini as root for the irq 
domain, not the next one in DT.

diff --git a/drivers/pci/host/pci-gemini.c b/drivers/pci/host/pci-gemini.c
index 7051dd992114..bb564a8e6379 100644
--- a/drivers/pci/host/pci-gemini.c
+++ b/drivers/pci/host/pci-gemini.c
@@ -217,7 +217,6 @@ static const struct irq_domain_ops gemini_pci_irqdomain_ops = {
 
 static int gemini_pci_setup_irq(struct gemini_pci *p, int irq)
 {
-	struct device_node *intc = of_get_next_child(p->dev->of_node, NULL);
 	int i;
 
 	if (!intc) {
@@ -225,7 +224,7 @@ static int gemini_pci_setup_irq(struct gemini_pci *p, int irq)
 		return -EINVAL;
 	}
 
-	p->irqdomain = irq_domain_add_linear(intc, 4,
+	p->irqdomain = irq_domain_add_linear(p->dev->of_node, 4,
 					     &gemini_pci_irqdomain_ops,
 					     p);
 	if (!p->irqdomain) {
-- 
2.11.0

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

* Re: [PATCH 4/4] ARM: dts: add PCI to the Gemini DTSI
  2017-01-28 20:48   ` Linus Walleij
@ 2017-02-05 10:03     ` Hans Ulli Kroll
  -1 siblings, 0 replies; 64+ messages in thread
From: Hans Ulli Kroll @ 2017-02-05 10:03 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Hans Ulli Kroll, Florian Fainelli, Bjorn Helgaas, Janos Laube,
	Paulius Zaleckas, openwrt-devel, linux-arm-kernel, linux-pci

Hi Linus

We need to the remove hwirq 26-28 from DT.
First one will print this warning while boot.

irq: type mismatch, failed to map hwirq-26 for /soc/interrupt-controller@48000000!

 arch/arm/boot/dts/gemini.dtsi | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/arch/arm/boot/dts/gemini.dtsi b/arch/arm/boot/dts/gemini.dtsi
index 11441e577058..0e2c021cd8c5 100644
--- a/arch/arm/boot/dts/gemini.dtsi
+++ b/arch/arm/boot/dts/gemini.dtsi
@@ -114,10 +114,7 @@
 		pci@50000000 {
 			compatible = "cortina,gemini-pci";
 			reg = <0x50000000 0x100>;
-			interrupts = <8 IRQ_TYPE_LEVEL_HIGH>, /* PCI A */
-				   	<26 IRQ_TYPE_LEVEL_HIGH>, /* PCI B */
-					<27 IRQ_TYPE_LEVEL_HIGH>, /* PCI C */
-					<28 IRQ_TYPE_LEVEL_HIGH>; /* PCI D */
+			interrupts = <8 IRQ_TYPE_LEVEL_HIGH>; /* chained irq PCI A-D */
 			#address-cells = <3>;
 			#size-cells = <2>;
 			#interrupt-cells = <1>;
-- 
2.11.0

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

* [PATCH 4/4] ARM: dts: add PCI to the Gemini DTSI
@ 2017-02-05 10:03     ` Hans Ulli Kroll
  0 siblings, 0 replies; 64+ messages in thread
From: Hans Ulli Kroll @ 2017-02-05 10:03 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Linus

We need to the remove hwirq 26-28 from DT.
First one will print this warning while boot.

irq: type mismatch, failed to map hwirq-26 for /soc/interrupt-controller at 48000000!

 arch/arm/boot/dts/gemini.dtsi | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/arch/arm/boot/dts/gemini.dtsi b/arch/arm/boot/dts/gemini.dtsi
index 11441e577058..0e2c021cd8c5 100644
--- a/arch/arm/boot/dts/gemini.dtsi
+++ b/arch/arm/boot/dts/gemini.dtsi
@@ -114,10 +114,7 @@
 		pci at 50000000 {
 			compatible = "cortina,gemini-pci";
 			reg = <0x50000000 0x100>;
-			interrupts = <8 IRQ_TYPE_LEVEL_HIGH>, /* PCI A */
-				   	<26 IRQ_TYPE_LEVEL_HIGH>, /* PCI B */
-					<27 IRQ_TYPE_LEVEL_HIGH>, /* PCI C */
-					<28 IRQ_TYPE_LEVEL_HIGH>; /* PCI D */
+			interrupts = <8 IRQ_TYPE_LEVEL_HIGH>; /* chained irq PCI A-D */
 			#address-cells = <3>;
 			#size-cells = <2>;
 			#interrupt-cells = <1>;
-- 
2.11.0

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

* Re: [PATCH 2/4] PCI: add driver for Cortina Gemini Host Bridge
  2017-02-05 10:00     ` Hans Ulli Kroll
@ 2017-02-05 14:36       ` Linus Walleij
  -1 siblings, 0 replies; 64+ messages in thread
From: Linus Walleij @ 2017-02-05 14:36 UTC (permalink / raw)
  To: Hans Ulli Kroll
  Cc: openwrt-devel, Florian Fainelli, Paulius Zaleckas, linux-pci,
	Bjorn Helgaas, Janos Laube, linux-arm-kernel

On Sun, Feb 5, 2017 at 11:00 AM, Hans Ulli Kroll
<ulli.kroll@googlemail.com> wrote:

> irq: type mismatch, failed to map hwirq-26 for /soc/interrupt-controller@48000000!
>
> We need to use the use the use the PCI IRQ from gemini as root for the irq
> domain, not the next one in DT.

Hm I wonder if that is because I need to set the parent for the intcon
in the device tree as Arnd pointed out in the bindings patch?

Yours,
Linus Walleij

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 2/4] PCI: add driver for Cortina Gemini Host Bridge
@ 2017-02-05 14:36       ` Linus Walleij
  0 siblings, 0 replies; 64+ messages in thread
From: Linus Walleij @ 2017-02-05 14:36 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Feb 5, 2017 at 11:00 AM, Hans Ulli Kroll
<ulli.kroll@googlemail.com> wrote:

> irq: type mismatch, failed to map hwirq-26 for /soc/interrupt-controller at 48000000!
>
> We need to use the use the use the PCI IRQ from gemini as root for the irq
> domain, not the next one in DT.

Hm I wonder if that is because I need to set the parent for the intcon
in the device tree as Arnd pointed out in the bindings patch?

Yours,
Linus Walleij

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

* Re: [PATCH 1/4] PCI: add DT bindings for Cortina Gemini PCI Host Bridge
  2017-02-01 11:09     ` Arnd Bergmann
  (?)
@ 2017-02-05 14:44       ` Linus Walleij
  -1 siblings, 0 replies; 64+ messages in thread
From: Linus Walleij @ 2017-02-05 14:44 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Hans Ulli Kroll, Florian Fainelli, Bjorn Helgaas, Janos Laube,
	Paulius Zaleckas, openwrt-devel, linux-arm-kernel, linux-pci,
	devicetree

On Wed, Feb 1, 2017 at 12:09 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Saturday, January 28, 2017 9:48:36 PM CET Linus Walleij wrote:
>> +       pci_intc: interrupt-controller {
>> +               interrupt-controller;
>> +               #address-cells = <0>;
>> +               #interrupt-cells = <1>;
>> +       };
>
> I think this one needs at least an interrupt-parent property, otherwise
> you would recursively translate the numbers back through the interrupt-map
> property of its parent.

OK I added this, I think it was the cause of the error Hand Uli Kroll
was seeing. I guess I didn't run into it because I was only testing the
device in slot 9 so everything was defaulting to zero.

Yours,
Linus Walleij

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

* Re: [PATCH 1/4] PCI: add DT bindings for Cortina Gemini PCI Host Bridge
@ 2017-02-05 14:44       ` Linus Walleij
  0 siblings, 0 replies; 64+ messages in thread
From: Linus Walleij @ 2017-02-05 14:44 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: openwrt-devel, devicetree, Florian Fainelli, Paulius Zaleckas,
	linux-pci, Hans Ulli Kroll, Bjorn Helgaas, Janos Laube,
	linux-arm-kernel

On Wed, Feb 1, 2017 at 12:09 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Saturday, January 28, 2017 9:48:36 PM CET Linus Walleij wrote:
>> +       pci_intc: interrupt-controller {
>> +               interrupt-controller;
>> +               #address-cells = <0>;
>> +               #interrupt-cells = <1>;
>> +       };
>
> I think this one needs at least an interrupt-parent property, otherwise
> you would recursively translate the numbers back through the interrupt-map
> property of its parent.

OK I added this, I think it was the cause of the error Hand Uli Kroll
was seeing. I guess I didn't run into it because I was only testing the
device in slot 9 so everything was defaulting to zero.

Yours,
Linus Walleij

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 1/4] PCI: add DT bindings for Cortina Gemini PCI Host Bridge
@ 2017-02-05 14:44       ` Linus Walleij
  0 siblings, 0 replies; 64+ messages in thread
From: Linus Walleij @ 2017-02-05 14:44 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Feb 1, 2017 at 12:09 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Saturday, January 28, 2017 9:48:36 PM CET Linus Walleij wrote:
>> +       pci_intc: interrupt-controller {
>> +               interrupt-controller;
>> +               #address-cells = <0>;
>> +               #interrupt-cells = <1>;
>> +       };
>
> I think this one needs at least an interrupt-parent property, otherwise
> you would recursively translate the numbers back through the interrupt-map
> property of its parent.

OK I added this, I think it was the cause of the error Hand Uli Kroll
was seeing. I guess I didn't run into it because I was only testing the
device in slot 9 so everything was defaulting to zero.

Yours,
Linus Walleij

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

* Re: [PATCH 1/4] PCI: add DT bindings for Cortina Gemini PCI Host Bridge
  2017-02-01 11:19   ` Arnd Bergmann
  (?)
@ 2017-02-05 14:56     ` Linus Walleij
  -1 siblings, 0 replies; 64+ messages in thread
From: Linus Walleij @ 2017-02-05 14:56 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Hans Ulli Kroll, Florian Fainelli, Bjorn Helgaas, Janos Laube,
	Paulius Zaleckas, openwrt-devel-p3rKhJxN3npAfugRpC6u6w,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, linux-pci,
	devicetree-u79uwXL29TY76Z2rM5mHXA

On Wed, Feb 1, 2017 at 12:19 PM, Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org> wrote:
> On Saturday, January 28, 2017 9:48:36 PM CET Linus Walleij wrote:
>> +       interrupt-map-mask = <0xff00 0 0 7>;
>> +       interrupt-map = <0x4800 0 0 1 &pci_intc 0>, /* Slot 9 */
>> +                       <0x4900 0 0 2 &pci_intc 1>,
>> +                       <0x4a00 0 0 3 &pci_intc 2>,
>> +                       <0x4b00 0 0 4 &pci_intc 3>,
>> +                       <0x5000 0 0 1 &pci_intc 0>, /* Slot 10 */
>> +                       <0x5100 0 0 2 &pci_intc 1>,
>> +                       <0x5200 0 0 3 &pci_intc 2>,
>> +                       <0x5300 0 0 4 &pci_intc 3>,
>> +                       <0x5800 0 0 1 &pci_intc 0>, /* Slot 11 */
>> +                       <0x5900 0 0 2 &pci_intc 1>,
>> +                       <0x5a00 0 0 3 &pci_intc 2>,
>> +                       <0x5b00 0 0 4 &pci_intc 3>,
>> +                       <0x6000 0 0 1 &pci_intc 0>, /* Slot 12 */
>> +                       <0x6100 0 0 2 &pci_intc 1>,
>> +                       <0x6200 0 0 3 &pci_intc 2>,
>> +                       <0x6300 0 0 4 &pci_intc 3>;
>>
>
> The mapping looks wrong here, we normally don't list interrupts per function
> so the mask should be 0xf800.

Yup it works that way too, and indeed the USB hub on function
2 was requesting the right pin and everything.

> Note that the interrupt map is board specific, so this should probably
> go in the board.dts file rather than platform.dtsi.

OK moving it down there.

> For this particular board, the interrupt lines appear to have been badly
> configured so all slots use the same interrupt 0 for IntA. IIRC This also
> means you can probably use <0 0 0 7> as the mask and just specify each of
> the four interrupts once. A properly wired board would swizzle the
> interrupts so that each slot has a different IRQ for its IntA line.

They are swizzled, I just have very bad hardware docs. (Only
code.) It turns out when I'm browsing through old board support
code that there is a comment followed by a piece of code like this:

/*
 *      No swizzle on SL2312
 */
static u8 __init sl2312_pci_swizzle(struct pci_dev *dev, u8 *pinp)
{
        return PCI_SLOT(dev->devfn);
}

/*
 * map the specified device/slot/pin to an IRQ.  This works out such
 * that slot 9 pin 1 is INT0, pin 2 is INT1, and slot 10 pin 1 is INT1.
 */
static int __init sl2312_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
        int intnr = ((slot  + (pin - 1)) & 3) + 4;  /* the IRQ number
of PCI bridge */

        printk("%s : slot = %d  pin = %d \n",__func__,slot,pin);
    switch (slot)
    {
        case 12:
                if (pin==1)
                {
                        intnr = 3;
                    }
                    else
                    {
                        intnr = 0;
                    }
#ifdef CONFIG_DUAL_PCI
                    return IRQ_PCI_INTD;
#endif
            break;
        case 11:
                    intnr = (2 + (pin - 1)) & 3;
#ifdef CONFIG_DUAL_PCI
                    return IRQ_PCI_INTC;
#endif
            break;
        case 10:
                    intnr = (1 + (pin - 1)) & 3;
#ifdef CONFIG_DUAL_PCI
                    return IRQ_PCI_INTB;
#endif
            break;
        case  9:
                    intnr = (pin - 1) & 3;
            break;
    }
//      if (slot == 10)
//              intnr = (1 + (pin - 1)) & 3;
//      else if (slot == 9)
//              intnr = (pin - 1) & 3;
        return (IRQ_PCI_INTA + intnr);
}

If I understand correctly they say that the IRQs are not swizzled
on the PCI bridge side but on the IRQ handler side.

So if I put it in the device tree like so:

+                         interrupt-map =
+                               <0x4800 0 0 1 &pci_intc 0>, /* Slot 9 */
+                               <0x4800 0 0 2 &pci_intc 1>,
+                               <0x4800 0 0 3 &pci_intc 2>,
+                               <0x4800 0 0 4 &pci_intc 3>,
+                               <0x5000 0 0 1 &pci_intc 1>, /* Slot 10 */
+                               <0x5000 0 0 2 &pci_intc 2>,
+                               <0x5000 0 0 3 &pci_intc 3>,
+                               <0x5000 0 0 4 &pci_intc 0>,
+                               <0x5800 0 0 1 &pci_intc 2>, /* Slot 11 */
+                               <0x5800 0 0 2 &pci_intc 3>,
+                               <0x5800 0 0 3 &pci_intc 0>,
+                               <0x5800 0 0 4 &pci_intc 1>,
+                               <0x6000 0 0 1 &pci_intc 3>, /* Slot 12 */
+                               <0x6000 0 0 2 &pci_intc 0>,
+                               <0x6000 0 0 3 &pci_intc 1>,
+                               <0x6000 0 0 4 &pci_intc 2>;

So the IRQs on the right side are swizzled instead
of the pins being swizzled.

...but that looks a bit insane.

Isn't that exactly the same thing just exposed in some
inverse way?

I'll try to get the RALink MiniPCI I have ín the slot going and
see if it works the same with just good old vanilla
swizzling.

Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 1/4] PCI: add DT bindings for Cortina Gemini PCI Host Bridge
@ 2017-02-05 14:56     ` Linus Walleij
  0 siblings, 0 replies; 64+ messages in thread
From: Linus Walleij @ 2017-02-05 14:56 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Hans Ulli Kroll, Florian Fainelli, Bjorn Helgaas, Janos Laube,
	Paulius Zaleckas, openwrt-devel, linux-arm-kernel, linux-pci,
	devicetree

On Wed, Feb 1, 2017 at 12:19 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Saturday, January 28, 2017 9:48:36 PM CET Linus Walleij wrote:
>> +       interrupt-map-mask =3D <0xff00 0 0 7>;
>> +       interrupt-map =3D <0x4800 0 0 1 &pci_intc 0>, /* Slot 9 */
>> +                       <0x4900 0 0 2 &pci_intc 1>,
>> +                       <0x4a00 0 0 3 &pci_intc 2>,
>> +                       <0x4b00 0 0 4 &pci_intc 3>,
>> +                       <0x5000 0 0 1 &pci_intc 0>, /* Slot 10 */
>> +                       <0x5100 0 0 2 &pci_intc 1>,
>> +                       <0x5200 0 0 3 &pci_intc 2>,
>> +                       <0x5300 0 0 4 &pci_intc 3>,
>> +                       <0x5800 0 0 1 &pci_intc 0>, /* Slot 11 */
>> +                       <0x5900 0 0 2 &pci_intc 1>,
>> +                       <0x5a00 0 0 3 &pci_intc 2>,
>> +                       <0x5b00 0 0 4 &pci_intc 3>,
>> +                       <0x6000 0 0 1 &pci_intc 0>, /* Slot 12 */
>> +                       <0x6100 0 0 2 &pci_intc 1>,
>> +                       <0x6200 0 0 3 &pci_intc 2>,
>> +                       <0x6300 0 0 4 &pci_intc 3>;
>>
>
> The mapping looks wrong here, we normally don't list interrupts per funct=
ion
> so the mask should be 0xf800.

Yup it works that way too, and indeed the USB hub on function
2 was requesting the right pin and everything.

> Note that the interrupt map is board specific, so this should probably
> go in the board.dts file rather than platform.dtsi.

OK moving it down there.

> For this particular board, the interrupt lines appear to have been badly
> configured so all slots use the same interrupt 0 for IntA. IIRC This also
> means you can probably use <0 0 0 7> as the mask and just specify each of
> the four interrupts once. A properly wired board would swizzle the
> interrupts so that each slot has a different IRQ for its IntA line.

They are swizzled, I just have very bad hardware docs. (Only
code.) It turns out when I'm browsing through old board support
code that there is a comment followed by a piece of code like this:

/*
 *      No swizzle on SL2312
 */
static u8 __init sl2312_pci_swizzle(struct pci_dev *dev, u8 *pinp)
{
        return PCI_SLOT(dev->devfn);
}

/*
 * map the specified device/slot/pin to an IRQ.  This works out such
 * that slot 9 pin 1 is INT0, pin 2 is INT1, and slot 10 pin 1 is INT1.
 */
static int __init sl2312_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
        int intnr =3D ((slot  + (pin - 1)) & 3) + 4;  /* the IRQ number
of PCI bridge */

        printk("%s : slot =3D %d  pin =3D %d \n",__func__,slot,pin);
    switch (slot)
    {
        case 12:
                if (pin=3D=3D1)
                {
                        intnr =3D 3;
                    }
                    else
                    {
                        intnr =3D 0;
                    }
#ifdef CONFIG_DUAL_PCI
                    return IRQ_PCI_INTD;
#endif
            break;
        case 11:
                    intnr =3D (2 + (pin - 1)) & 3;
#ifdef CONFIG_DUAL_PCI
                    return IRQ_PCI_INTC;
#endif
            break;
        case 10:
                    intnr =3D (1 + (pin - 1)) & 3;
#ifdef CONFIG_DUAL_PCI
                    return IRQ_PCI_INTB;
#endif
            break;
        case  9:
                    intnr =3D (pin - 1) & 3;
            break;
    }
//      if (slot =3D=3D 10)
//              intnr =3D (1 + (pin - 1)) & 3;
//      else if (slot =3D=3D 9)
//              intnr =3D (pin - 1) & 3;
        return (IRQ_PCI_INTA + intnr);
}

If I understand correctly they say that the IRQs are not swizzled
on the PCI bridge side but on the IRQ handler side.

So if I put it in the device tree like so:

+                         interrupt-map =3D
+                               <0x4800 0 0 1 &pci_intc 0>, /* Slot 9 */
+                               <0x4800 0 0 2 &pci_intc 1>,
+                               <0x4800 0 0 3 &pci_intc 2>,
+                               <0x4800 0 0 4 &pci_intc 3>,
+                               <0x5000 0 0 1 &pci_intc 1>, /* Slot 10 */
+                               <0x5000 0 0 2 &pci_intc 2>,
+                               <0x5000 0 0 3 &pci_intc 3>,
+                               <0x5000 0 0 4 &pci_intc 0>,
+                               <0x5800 0 0 1 &pci_intc 2>, /* Slot 11 */
+                               <0x5800 0 0 2 &pci_intc 3>,
+                               <0x5800 0 0 3 &pci_intc 0>,
+                               <0x5800 0 0 4 &pci_intc 1>,
+                               <0x6000 0 0 1 &pci_intc 3>, /* Slot 12 */
+                               <0x6000 0 0 2 &pci_intc 0>,
+                               <0x6000 0 0 3 &pci_intc 1>,
+                               <0x6000 0 0 4 &pci_intc 2>;

So the IRQs on the right side are swizzled instead
of the pins being swizzled.

...but that looks a bit insane.

Isn't that exactly the same thing just exposed in some
inverse way?

I'll try to get the RALink MiniPCI I have =C3=ADn the slot going and
see if it works the same with just good old vanilla
swizzling.

Yours,
Linus Walleij

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

* [PATCH 1/4] PCI: add DT bindings for Cortina Gemini PCI Host Bridge
@ 2017-02-05 14:56     ` Linus Walleij
  0 siblings, 0 replies; 64+ messages in thread
From: Linus Walleij @ 2017-02-05 14:56 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Feb 1, 2017 at 12:19 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Saturday, January 28, 2017 9:48:36 PM CET Linus Walleij wrote:
>> +       interrupt-map-mask = <0xff00 0 0 7>;
>> +       interrupt-map = <0x4800 0 0 1 &pci_intc 0>, /* Slot 9 */
>> +                       <0x4900 0 0 2 &pci_intc 1>,
>> +                       <0x4a00 0 0 3 &pci_intc 2>,
>> +                       <0x4b00 0 0 4 &pci_intc 3>,
>> +                       <0x5000 0 0 1 &pci_intc 0>, /* Slot 10 */
>> +                       <0x5100 0 0 2 &pci_intc 1>,
>> +                       <0x5200 0 0 3 &pci_intc 2>,
>> +                       <0x5300 0 0 4 &pci_intc 3>,
>> +                       <0x5800 0 0 1 &pci_intc 0>, /* Slot 11 */
>> +                       <0x5900 0 0 2 &pci_intc 1>,
>> +                       <0x5a00 0 0 3 &pci_intc 2>,
>> +                       <0x5b00 0 0 4 &pci_intc 3>,
>> +                       <0x6000 0 0 1 &pci_intc 0>, /* Slot 12 */
>> +                       <0x6100 0 0 2 &pci_intc 1>,
>> +                       <0x6200 0 0 3 &pci_intc 2>,
>> +                       <0x6300 0 0 4 &pci_intc 3>;
>>
>
> The mapping looks wrong here, we normally don't list interrupts per function
> so the mask should be 0xf800.

Yup it works that way too, and indeed the USB hub on function
2 was requesting the right pin and everything.

> Note that the interrupt map is board specific, so this should probably
> go in the board.dts file rather than platform.dtsi.

OK moving it down there.

> For this particular board, the interrupt lines appear to have been badly
> configured so all slots use the same interrupt 0 for IntA. IIRC This also
> means you can probably use <0 0 0 7> as the mask and just specify each of
> the four interrupts once. A properly wired board would swizzle the
> interrupts so that each slot has a different IRQ for its IntA line.

They are swizzled, I just have very bad hardware docs. (Only
code.) It turns out when I'm browsing through old board support
code that there is a comment followed by a piece of code like this:

/*
 *      No swizzle on SL2312
 */
static u8 __init sl2312_pci_swizzle(struct pci_dev *dev, u8 *pinp)
{
        return PCI_SLOT(dev->devfn);
}

/*
 * map the specified device/slot/pin to an IRQ.  This works out such
 * that slot 9 pin 1 is INT0, pin 2 is INT1, and slot 10 pin 1 is INT1.
 */
static int __init sl2312_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
        int intnr = ((slot  + (pin - 1)) & 3) + 4;  /* the IRQ number
of PCI bridge */

        printk("%s : slot = %d  pin = %d \n",__func__,slot,pin);
    switch (slot)
    {
        case 12:
                if (pin==1)
                {
                        intnr = 3;
                    }
                    else
                    {
                        intnr = 0;
                    }
#ifdef CONFIG_DUAL_PCI
                    return IRQ_PCI_INTD;
#endif
            break;
        case 11:
                    intnr = (2 + (pin - 1)) & 3;
#ifdef CONFIG_DUAL_PCI
                    return IRQ_PCI_INTC;
#endif
            break;
        case 10:
                    intnr = (1 + (pin - 1)) & 3;
#ifdef CONFIG_DUAL_PCI
                    return IRQ_PCI_INTB;
#endif
            break;
        case  9:
                    intnr = (pin - 1) & 3;
            break;
    }
//      if (slot == 10)
//              intnr = (1 + (pin - 1)) & 3;
//      else if (slot == 9)
//              intnr = (pin - 1) & 3;
        return (IRQ_PCI_INTA + intnr);
}

If I understand correctly they say that the IRQs are not swizzled
on the PCI bridge side but on the IRQ handler side.

So if I put it in the device tree like so:

+                         interrupt-map =
+                               <0x4800 0 0 1 &pci_intc 0>, /* Slot 9 */
+                               <0x4800 0 0 2 &pci_intc 1>,
+                               <0x4800 0 0 3 &pci_intc 2>,
+                               <0x4800 0 0 4 &pci_intc 3>,
+                               <0x5000 0 0 1 &pci_intc 1>, /* Slot 10 */
+                               <0x5000 0 0 2 &pci_intc 2>,
+                               <0x5000 0 0 3 &pci_intc 3>,
+                               <0x5000 0 0 4 &pci_intc 0>,
+                               <0x5800 0 0 1 &pci_intc 2>, /* Slot 11 */
+                               <0x5800 0 0 2 &pci_intc 3>,
+                               <0x5800 0 0 3 &pci_intc 0>,
+                               <0x5800 0 0 4 &pci_intc 1>,
+                               <0x6000 0 0 1 &pci_intc 3>, /* Slot 12 */
+                               <0x6000 0 0 2 &pci_intc 0>,
+                               <0x6000 0 0 3 &pci_intc 1>,
+                               <0x6000 0 0 4 &pci_intc 2>;

So the IRQs on the right side are swizzled instead
of the pins being swizzled.

...but that looks a bit insane.

Isn't that exactly the same thing just exposed in some
inverse way?

I'll try to get the RALink MiniPCI I have ?n the slot going and
see if it works the same with just good old vanilla
swizzling.

Yours,
Linus Walleij

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

* Re: [PATCH 4/4] ARM: dts: add PCI to the Gemini DTSI
  2017-02-05 10:03     ` Hans Ulli Kroll
@ 2017-02-05 15:00       ` Linus Walleij
  -1 siblings, 0 replies; 64+ messages in thread
From: Linus Walleij @ 2017-02-05 15:00 UTC (permalink / raw)
  To: Hans Ulli Kroll
  Cc: openwrt-devel, Florian Fainelli, Paulius Zaleckas, linux-pci,
	Bjorn Helgaas, Janos Laube, linux-arm-kernel

On Sun, Feb 5, 2017 at 11:03 AM, Hans Ulli Kroll
<ulli.kroll@googlemail.com> wrote:

> We need to the remove hwirq 26-28 from DT.
> First one will print this warning while boot.
>
> irq: type mismatch, failed to map hwirq-26 for /soc/interrupt-controller@48000000!
(...)
> -                       interrupts = <8 IRQ_TYPE_LEVEL_HIGH>, /* PCI A */
> -                                       <26 IRQ_TYPE_LEVEL_HIGH>, /* PCI B */
> -                                       <27 IRQ_TYPE_LEVEL_HIGH>, /* PCI C */
> -                                       <28 IRQ_TYPE_LEVEL_HIGH>; /* PCI D */
> +                       interrupts = <8 IRQ_TYPE_LEVEL_HIGH>; /* chained irq PCI A-D */

Sure I can remove them ... just found them in the irqs.h file and thought it
made sense to add them. I'll just cut them.

Since there is actually an internal IRQ controller in the host controller
cascading the four PCI child IRQs that we model as an irqchip, I don't
really see why they have these "PCI B-D" IRQs... anyone has a guess?

Yours,
Linus Walleij

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 4/4] ARM: dts: add PCI to the Gemini DTSI
@ 2017-02-05 15:00       ` Linus Walleij
  0 siblings, 0 replies; 64+ messages in thread
From: Linus Walleij @ 2017-02-05 15:00 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Feb 5, 2017 at 11:03 AM, Hans Ulli Kroll
<ulli.kroll@googlemail.com> wrote:

> We need to the remove hwirq 26-28 from DT.
> First one will print this warning while boot.
>
> irq: type mismatch, failed to map hwirq-26 for /soc/interrupt-controller at 48000000!
(...)
> -                       interrupts = <8 IRQ_TYPE_LEVEL_HIGH>, /* PCI A */
> -                                       <26 IRQ_TYPE_LEVEL_HIGH>, /* PCI B */
> -                                       <27 IRQ_TYPE_LEVEL_HIGH>, /* PCI C */
> -                                       <28 IRQ_TYPE_LEVEL_HIGH>; /* PCI D */
> +                       interrupts = <8 IRQ_TYPE_LEVEL_HIGH>; /* chained irq PCI A-D */

Sure I can remove them ... just found them in the irqs.h file and thought it
made sense to add them. I'll just cut them.

Since there is actually an internal IRQ controller in the host controller
cascading the four PCI child IRQs that we model as an irqchip, I don't
really see why they have these "PCI B-D" IRQs... anyone has a guess?

Yours,
Linus Walleij

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

* Re: [PATCH 4/4] ARM: dts: add PCI to the Gemini DTSI
  2017-02-05 15:00       ` Linus Walleij
@ 2017-02-06  9:55         ` Hans Ulli Kroll
  -1 siblings, 0 replies; 64+ messages in thread
From: Hans Ulli Kroll @ 2017-02-06  9:55 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Hans Ulli Kroll, Florian Fainelli, Bjorn Helgaas, Janos Laube,
	Paulius Zaleckas, openwrt-devel, linux-arm-kernel, linux-pci

Hi Linus,

On Sun, 5 Feb 2017, Linus Walleij wrote:

> On Sun, Feb 5, 2017 at 11:03 AM, Hans Ulli Kroll
> <ulli.kroll@googlemail.com> wrote:
> 
> > We need to the remove hwirq 26-28 from DT.
> > First one will print this warning while boot.
> >
> > irq: type mismatch, failed to map hwirq-26 for /soc/interrupt-controller@48000000!
> (...)
> > -                       interrupts = <8 IRQ_TYPE_LEVEL_HIGH>, /* PCI A */
> > -                                       <26 IRQ_TYPE_LEVEL_HIGH>, /* PCI B */
> > -                                       <27 IRQ_TYPE_LEVEL_HIGH>, /* PCI C */
> > -                                       <28 IRQ_TYPE_LEVEL_HIGH>; /* PCI D */
> > +                       interrupts = <8 IRQ_TYPE_LEVEL_HIGH>; /* chained irq PCI A-D */
> 
> Sure I can remove them ... just found them in the irqs.h file and thought it
> made sense to add them. I'll just cut them.
> 
> Since there is actually an internal IRQ controller in the host controller
> cascading the four PCI child IRQs that we model as an irqchip, I don't
> really see why they have these "PCI B-D" IRQs... anyone has a guess?

I think they used some other IP vendor.

from my IB 4220 sources.

#define IRQ_PCI_INTA				       PCI_IRQ_OFFSET + 0
#ifndef CONFIG_DUAL_PCI
#define IRQ_PCI_INTB				       PCI_IRQ_OFFSET + 1
#define IRQ_PCI_INTC				       PCI_IRQ_OFFSET + 2
#define IRQ_PCI_INTD				       PCI_IRQ_OFFSET + 3
#else
#define IRQ_PCI_INTB				       27
#define IRQ_PCI_INTC				       28
#define IRQ_PCI_INTD				       29
#endif

CONFIG_DUAL_PCI is never used
IRQ_PCIB - IRQ_PCID or IRQ_PCI_INTB - IRQ_PCI_INTD are also never used.

You can download my original NAS 4220 here
http://ulli-kroll.de/gemini/kernel.tgz

Greetings
Hans Ulli Kroll

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

* [PATCH 4/4] ARM: dts: add PCI to the Gemini DTSI
@ 2017-02-06  9:55         ` Hans Ulli Kroll
  0 siblings, 0 replies; 64+ messages in thread
From: Hans Ulli Kroll @ 2017-02-06  9:55 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Linus,

On Sun, 5 Feb 2017, Linus Walleij wrote:

> On Sun, Feb 5, 2017 at 11:03 AM, Hans Ulli Kroll
> <ulli.kroll@googlemail.com> wrote:
> 
> > We need to the remove hwirq 26-28 from DT.
> > First one will print this warning while boot.
> >
> > irq: type mismatch, failed to map hwirq-26 for /soc/interrupt-controller at 48000000!
> (...)
> > -                       interrupts = <8 IRQ_TYPE_LEVEL_HIGH>, /* PCI A */
> > -                                       <26 IRQ_TYPE_LEVEL_HIGH>, /* PCI B */
> > -                                       <27 IRQ_TYPE_LEVEL_HIGH>, /* PCI C */
> > -                                       <28 IRQ_TYPE_LEVEL_HIGH>; /* PCI D */
> > +                       interrupts = <8 IRQ_TYPE_LEVEL_HIGH>; /* chained irq PCI A-D */
> 
> Sure I can remove them ... just found them in the irqs.h file and thought it
> made sense to add them. I'll just cut them.
> 
> Since there is actually an internal IRQ controller in the host controller
> cascading the four PCI child IRQs that we model as an irqchip, I don't
> really see why they have these "PCI B-D" IRQs... anyone has a guess?

I think they used some other IP vendor.

from my IB 4220 sources.

#define IRQ_PCI_INTA				       PCI_IRQ_OFFSET + 0
#ifndef CONFIG_DUAL_PCI
#define IRQ_PCI_INTB				       PCI_IRQ_OFFSET + 1
#define IRQ_PCI_INTC				       PCI_IRQ_OFFSET + 2
#define IRQ_PCI_INTD				       PCI_IRQ_OFFSET + 3
#else
#define IRQ_PCI_INTB				       27
#define IRQ_PCI_INTC				       28
#define IRQ_PCI_INTD				       29
#endif

CONFIG_DUAL_PCI is never used
IRQ_PCIB - IRQ_PCID or IRQ_PCI_INTB - IRQ_PCI_INTD are also never used.

You can download my original NAS 4220 here
http://ulli-kroll.de/gemini/kernel.tgz

Greetings
Hans Ulli Kroll

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

* Re: [PATCH 1/4] PCI: add DT bindings for Cortina Gemini PCI Host Bridge
  2017-02-05 14:56     ` Linus Walleij
  (?)
@ 2017-02-06 16:05         ` Arnd Bergmann
  -1 siblings, 0 replies; 64+ messages in thread
From: Arnd Bergmann @ 2017-02-06 16:05 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Hans Ulli Kroll, Florian Fainelli, Bjorn Helgaas, Janos Laube,
	Paulius Zaleckas, openwrt-devel-p3rKhJxN3npAfugRpC6u6w,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, linux-pci,
	devicetree-u79uwXL29TY76Z2rM5mHXA

On Sun, Feb 5, 2017 at 3:56 PM, Linus Walleij <linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org> wrote:
> On Wed, Feb 1, 2017 at 12:19 PM, Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org> wrote:
>> On Saturday, January 28, 2017 9:48:36 PM CET Linus Walleij wrote:
>>> +       interrupt-map-mask = <0xff00 0 0 7>;
>>> +       interrupt-map = <0x4800 0 0 1 &pci_intc 0>, /* Slot 9 */
>>> +                       <0x4900 0 0 2 &pci_intc 1>,
>>> +                       <0x4a00 0 0 3 &pci_intc 2>,
>>> +                       <0x4b00 0 0 4 &pci_intc 3>,
>>> +                       <0x5000 0 0 1 &pci_intc 0>, /* Slot 10 */
>>> +                       <0x5100 0 0 2 &pci_intc 1>,
>>> +                       <0x5200 0 0 3 &pci_intc 2>,
>>> +                       <0x5300 0 0 4 &pci_intc 3>,
>>> +                       <0x5800 0 0 1 &pci_intc 0>, /* Slot 11 */
>>> +                       <0x5900 0 0 2 &pci_intc 1>,
>>> +                       <0x5a00 0 0 3 &pci_intc 2>,
>>> +                       <0x5b00 0 0 4 &pci_intc 3>,
>>> +                       <0x6000 0 0 1 &pci_intc 0>, /* Slot 12 */
>>> +                       <0x6100 0 0 2 &pci_intc 1>,
>>> +                       <0x6200 0 0 3 &pci_intc 2>,
>>> +                       <0x6300 0 0 4 &pci_intc 3>;
>>>
>>

>> For this particular board, the interrupt lines appear to have been badly
>> configured so all slots use the same interrupt 0 for IntA. IIRC This also
>> means you can probably use <0 0 0 7> as the mask and just specify each of
>> the four interrupts once. A properly wired board would swizzle the
>> interrupts so that each slot has a different IRQ for its IntA line.
>
> They are swizzled, I just have very bad hardware docs. (Only
> code.) It turns out when I'm browsing through old board support
> code that there is a comment followed by a piece of code like this:
>
> /*
>  *      No swizzle on SL2312
>  */
> static u8 __init sl2312_pci_swizzle(struct pci_dev *dev, u8 *pinp)
> {
>         return PCI_SLOT(dev->devfn);
> }
>
> /*
>  * map the specified device/slot/pin to an IRQ.  This works out such
>  * that slot 9 pin 1 is INT0, pin 2 is INT1, and slot 10 pin 1 is INT1.
>  */
> static int __init sl2312_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
> {
>         int intnr = ((slot  + (pin - 1)) & 3) + 4;  /* the IRQ number
> of PCI bridge */
>
>         printk("%s : slot = %d  pin = %d \n",__func__,slot,pin);
>     switch (slot)
>     {
>         case 12:
>                 if (pin==1)
>                 {
>                         intnr = 3;
>                     }
>                     else
>                     {
>                         intnr = 0;
>                     }
> #ifdef CONFIG_DUAL_PCI
>                     return IRQ_PCI_INTD;
> #endif
>             break;
>         case 11:
>                     intnr = (2 + (pin - 1)) & 3;
> #ifdef CONFIG_DUAL_PCI
>                     return IRQ_PCI_INTC;
> #endif
>             break;
>         case 10:
>                     intnr = (1 + (pin - 1)) & 3;
> #ifdef CONFIG_DUAL_PCI
>                     return IRQ_PCI_INTB;
> #endif
>             break;
>         case  9:
>                     intnr = (pin - 1) & 3;
>             break;
>     }
> //      if (slot == 10)
> //              intnr = (1 + (pin - 1)) & 3;
> //      else if (slot == 9)
> //              intnr = (pin - 1) & 3;
>         return (IRQ_PCI_INTA + intnr);
> }
>
> If I understand correctly they say that the IRQs are not swizzled
> on the PCI bridge side but on the IRQ handler side.

That depends on whether CONFIG_DUAL_PCI is set or not:

It seems that slot 12 is hardwired to have hwirq 3 on IntA and
hwirq 0 on all others by default, but have hwirq on IntA through
IntD on boards that use CONFIG_DUAL_PCI.

Slot 10/11 use the default swizzling without CONFIG_DUAL_PCI but
uses hwirq 1 or 2 for all four pins with CONFIG_DUAL_PCI.

Slot 9 seems to always use the default swizzling, so it has all
four IRQ pins connected to the four hwirqs of the SoC.

This is still an awful wiring, but not unthinkable, as board
designers may have had a specific usage for the four interrupts
in mind, to spread the devices that are actually present across
the available hwirqs.

> So if I put it in the device tree like so:
>
> +                         interrupt-map =
> +                               <0x4800 0 0 1 &pci_intc 0>, /* Slot 9 */
> +                               <0x4800 0 0 2 &pci_intc 1>,
> +                               <0x4800 0 0 3 &pci_intc 2>,
> +                               <0x4800 0 0 4 &pci_intc 3>,
> +                               <0x5000 0 0 1 &pci_intc 1>, /* Slot 10 */
> +                               <0x5000 0 0 2 &pci_intc 2>,
> +                               <0x5000 0 0 3 &pci_intc 3>,
> +                               <0x5000 0 0 4 &pci_intc 0>,
> +                               <0x5800 0 0 1 &pci_intc 2>, /* Slot 11 */
> +                               <0x5800 0 0 2 &pci_intc 3>,
> +                               <0x5800 0 0 3 &pci_intc 0>,
> +                               <0x5800 0 0 4 &pci_intc 1>,

For boards that require CONFIG_DUAL_PCI, this would be

                               <0x5000 0 0 1 &pci_intc 1>, /* Slot 10 */
                               <0x5000 0 0 2 &pci_intc 1>,
                               <0x5000 0 0 3 &pci_intc 1>,
                               <0x5000 0 0 4 &pci_intc 1>,
                               <0x5800 0 0 1 &pci_intc 2>, /* Slot 11 */
                               <0x5800 0 0 2 &pci_intc 2>,
                               <0x5800 0 0 3 &pci_intc 2>,
                               <0x5800 0 0 4 &pci_intc 2>,

It probably works either way if you put just one device in there,
as almost everything uses just IntA, but you'd notice the difference
if there is ever a PCI bridge behind that slot.

> +                               <0x6000 0 0 1 &pci_intc 3>, /* Slot 12 */
> +                               <0x6000 0 0 2 &pci_intc 0>,
> +                               <0x6000 0 0 3 &pci_intc 1>,
> +                               <0x6000 0 0 4 &pci_intc 2>;

The last two have to be

                               <0x6000 0 0 3 &pci_intc 0>, /* [sic] */
                               <0x6000 0 0 4 &pci_intc 0>; /* [sic] */

> So the IRQs on the right side are swizzled instead
> of the pins being swizzled.
>
> ...but that looks a bit insane.
>
> Isn't that exactly the same thing just exposed in some
> inverse way?

I don't understand your question. The mapping that you list
is the default swizzling, right? I think if you have a board with
sane wiring, you could write that as

                      interrupt-map-mask = <0x0 0x0 0x0 0x7>;
                      interrupt-map =
                              <0x0 0x0 0x0 0x1 &pci_intc 0>, /* int A */
                              <0x0 0x0 0x0 0x2 &pci_intc 1>, /* int B */
                              <0x0 0x0 0x0 0x3 &pci_intc 2>, /* int C */
                              <0x0 0x0 0x0 0x4 &pci_intc 3>; /* int D */

meaning that the IRQs are wired correctly to the root bus, and
all slots are connected one would normally do with the standard
swizzling.

    Arnd
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 1/4] PCI: add DT bindings for Cortina Gemini PCI Host Bridge
@ 2017-02-06 16:05         ` Arnd Bergmann
  0 siblings, 0 replies; 64+ messages in thread
From: Arnd Bergmann @ 2017-02-06 16:05 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Hans Ulli Kroll, Florian Fainelli, Bjorn Helgaas, Janos Laube,
	Paulius Zaleckas, openwrt-devel, linux-arm-kernel, linux-pci,
	devicetree

On Sun, Feb 5, 2017 at 3:56 PM, Linus Walleij <linus.walleij@linaro.org> wrote:
> On Wed, Feb 1, 2017 at 12:19 PM, Arnd Bergmann <arnd@arndb.de> wrote:
>> On Saturday, January 28, 2017 9:48:36 PM CET Linus Walleij wrote:
>>> +       interrupt-map-mask = <0xff00 0 0 7>;
>>> +       interrupt-map = <0x4800 0 0 1 &pci_intc 0>, /* Slot 9 */
>>> +                       <0x4900 0 0 2 &pci_intc 1>,
>>> +                       <0x4a00 0 0 3 &pci_intc 2>,
>>> +                       <0x4b00 0 0 4 &pci_intc 3>,
>>> +                       <0x5000 0 0 1 &pci_intc 0>, /* Slot 10 */
>>> +                       <0x5100 0 0 2 &pci_intc 1>,
>>> +                       <0x5200 0 0 3 &pci_intc 2>,
>>> +                       <0x5300 0 0 4 &pci_intc 3>,
>>> +                       <0x5800 0 0 1 &pci_intc 0>, /* Slot 11 */
>>> +                       <0x5900 0 0 2 &pci_intc 1>,
>>> +                       <0x5a00 0 0 3 &pci_intc 2>,
>>> +                       <0x5b00 0 0 4 &pci_intc 3>,
>>> +                       <0x6000 0 0 1 &pci_intc 0>, /* Slot 12 */
>>> +                       <0x6100 0 0 2 &pci_intc 1>,
>>> +                       <0x6200 0 0 3 &pci_intc 2>,
>>> +                       <0x6300 0 0 4 &pci_intc 3>;
>>>
>>

>> For this particular board, the interrupt lines appear to have been badly
>> configured so all slots use the same interrupt 0 for IntA. IIRC This also
>> means you can probably use <0 0 0 7> as the mask and just specify each of
>> the four interrupts once. A properly wired board would swizzle the
>> interrupts so that each slot has a different IRQ for its IntA line.
>
> They are swizzled, I just have very bad hardware docs. (Only
> code.) It turns out when I'm browsing through old board support
> code that there is a comment followed by a piece of code like this:
>
> /*
>  *      No swizzle on SL2312
>  */
> static u8 __init sl2312_pci_swizzle(struct pci_dev *dev, u8 *pinp)
> {
>         return PCI_SLOT(dev->devfn);
> }
>
> /*
>  * map the specified device/slot/pin to an IRQ.  This works out such
>  * that slot 9 pin 1 is INT0, pin 2 is INT1, and slot 10 pin 1 is INT1.
>  */
> static int __init sl2312_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
> {
>         int intnr = ((slot  + (pin - 1)) & 3) + 4;  /* the IRQ number
> of PCI bridge */
>
>         printk("%s : slot = %d  pin = %d \n",__func__,slot,pin);
>     switch (slot)
>     {
>         case 12:
>                 if (pin==1)
>                 {
>                         intnr = 3;
>                     }
>                     else
>                     {
>                         intnr = 0;
>                     }
> #ifdef CONFIG_DUAL_PCI
>                     return IRQ_PCI_INTD;
> #endif
>             break;
>         case 11:
>                     intnr = (2 + (pin - 1)) & 3;
> #ifdef CONFIG_DUAL_PCI
>                     return IRQ_PCI_INTC;
> #endif
>             break;
>         case 10:
>                     intnr = (1 + (pin - 1)) & 3;
> #ifdef CONFIG_DUAL_PCI
>                     return IRQ_PCI_INTB;
> #endif
>             break;
>         case  9:
>                     intnr = (pin - 1) & 3;
>             break;
>     }
> //      if (slot == 10)
> //              intnr = (1 + (pin - 1)) & 3;
> //      else if (slot == 9)
> //              intnr = (pin - 1) & 3;
>         return (IRQ_PCI_INTA + intnr);
> }
>
> If I understand correctly they say that the IRQs are not swizzled
> on the PCI bridge side but on the IRQ handler side.

That depends on whether CONFIG_DUAL_PCI is set or not:

It seems that slot 12 is hardwired to have hwirq 3 on IntA and
hwirq 0 on all others by default, but have hwirq on IntA through
IntD on boards that use CONFIG_DUAL_PCI.

Slot 10/11 use the default swizzling without CONFIG_DUAL_PCI but
uses hwirq 1 or 2 for all four pins with CONFIG_DUAL_PCI.

Slot 9 seems to always use the default swizzling, so it has all
four IRQ pins connected to the four hwirqs of the SoC.

This is still an awful wiring, but not unthinkable, as board
designers may have had a specific usage for the four interrupts
in mind, to spread the devices that are actually present across
the available hwirqs.

> So if I put it in the device tree like so:
>
> +                         interrupt-map =
> +                               <0x4800 0 0 1 &pci_intc 0>, /* Slot 9 */
> +                               <0x4800 0 0 2 &pci_intc 1>,
> +                               <0x4800 0 0 3 &pci_intc 2>,
> +                               <0x4800 0 0 4 &pci_intc 3>,
> +                               <0x5000 0 0 1 &pci_intc 1>, /* Slot 10 */
> +                               <0x5000 0 0 2 &pci_intc 2>,
> +                               <0x5000 0 0 3 &pci_intc 3>,
> +                               <0x5000 0 0 4 &pci_intc 0>,
> +                               <0x5800 0 0 1 &pci_intc 2>, /* Slot 11 */
> +                               <0x5800 0 0 2 &pci_intc 3>,
> +                               <0x5800 0 0 3 &pci_intc 0>,
> +                               <0x5800 0 0 4 &pci_intc 1>,

For boards that require CONFIG_DUAL_PCI, this would be

                               <0x5000 0 0 1 &pci_intc 1>, /* Slot 10 */
                               <0x5000 0 0 2 &pci_intc 1>,
                               <0x5000 0 0 3 &pci_intc 1>,
                               <0x5000 0 0 4 &pci_intc 1>,
                               <0x5800 0 0 1 &pci_intc 2>, /* Slot 11 */
                               <0x5800 0 0 2 &pci_intc 2>,
                               <0x5800 0 0 3 &pci_intc 2>,
                               <0x5800 0 0 4 &pci_intc 2>,

It probably works either way if you put just one device in there,
as almost everything uses just IntA, but you'd notice the difference
if there is ever a PCI bridge behind that slot.

> +                               <0x6000 0 0 1 &pci_intc 3>, /* Slot 12 */
> +                               <0x6000 0 0 2 &pci_intc 0>,
> +                               <0x6000 0 0 3 &pci_intc 1>,
> +                               <0x6000 0 0 4 &pci_intc 2>;

The last two have to be

                               <0x6000 0 0 3 &pci_intc 0>, /* [sic] */
                               <0x6000 0 0 4 &pci_intc 0>; /* [sic] */

> So the IRQs on the right side are swizzled instead
> of the pins being swizzled.
>
> ...but that looks a bit insane.
>
> Isn't that exactly the same thing just exposed in some
> inverse way?

I don't understand your question. The mapping that you list
is the default swizzling, right? I think if you have a board with
sane wiring, you could write that as

                      interrupt-map-mask = <0x0 0x0 0x0 0x7>;
                      interrupt-map =
                              <0x0 0x0 0x0 0x1 &pci_intc 0>, /* int A */
                              <0x0 0x0 0x0 0x2 &pci_intc 1>, /* int B */
                              <0x0 0x0 0x0 0x3 &pci_intc 2>, /* int C */
                              <0x0 0x0 0x0 0x4 &pci_intc 3>; /* int D */

meaning that the IRQs are wired correctly to the root bus, and
all slots are connected one would normally do with the standard
swizzling.

    Arnd

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

* [PATCH 1/4] PCI: add DT bindings for Cortina Gemini PCI Host Bridge
@ 2017-02-06 16:05         ` Arnd Bergmann
  0 siblings, 0 replies; 64+ messages in thread
From: Arnd Bergmann @ 2017-02-06 16:05 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Feb 5, 2017 at 3:56 PM, Linus Walleij <linus.walleij@linaro.org> wrote:
> On Wed, Feb 1, 2017 at 12:19 PM, Arnd Bergmann <arnd@arndb.de> wrote:
>> On Saturday, January 28, 2017 9:48:36 PM CET Linus Walleij wrote:
>>> +       interrupt-map-mask = <0xff00 0 0 7>;
>>> +       interrupt-map = <0x4800 0 0 1 &pci_intc 0>, /* Slot 9 */
>>> +                       <0x4900 0 0 2 &pci_intc 1>,
>>> +                       <0x4a00 0 0 3 &pci_intc 2>,
>>> +                       <0x4b00 0 0 4 &pci_intc 3>,
>>> +                       <0x5000 0 0 1 &pci_intc 0>, /* Slot 10 */
>>> +                       <0x5100 0 0 2 &pci_intc 1>,
>>> +                       <0x5200 0 0 3 &pci_intc 2>,
>>> +                       <0x5300 0 0 4 &pci_intc 3>,
>>> +                       <0x5800 0 0 1 &pci_intc 0>, /* Slot 11 */
>>> +                       <0x5900 0 0 2 &pci_intc 1>,
>>> +                       <0x5a00 0 0 3 &pci_intc 2>,
>>> +                       <0x5b00 0 0 4 &pci_intc 3>,
>>> +                       <0x6000 0 0 1 &pci_intc 0>, /* Slot 12 */
>>> +                       <0x6100 0 0 2 &pci_intc 1>,
>>> +                       <0x6200 0 0 3 &pci_intc 2>,
>>> +                       <0x6300 0 0 4 &pci_intc 3>;
>>>
>>

>> For this particular board, the interrupt lines appear to have been badly
>> configured so all slots use the same interrupt 0 for IntA. IIRC This also
>> means you can probably use <0 0 0 7> as the mask and just specify each of
>> the four interrupts once. A properly wired board would swizzle the
>> interrupts so that each slot has a different IRQ for its IntA line.
>
> They are swizzled, I just have very bad hardware docs. (Only
> code.) It turns out when I'm browsing through old board support
> code that there is a comment followed by a piece of code like this:
>
> /*
>  *      No swizzle on SL2312
>  */
> static u8 __init sl2312_pci_swizzle(struct pci_dev *dev, u8 *pinp)
> {
>         return PCI_SLOT(dev->devfn);
> }
>
> /*
>  * map the specified device/slot/pin to an IRQ.  This works out such
>  * that slot 9 pin 1 is INT0, pin 2 is INT1, and slot 10 pin 1 is INT1.
>  */
> static int __init sl2312_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
> {
>         int intnr = ((slot  + (pin - 1)) & 3) + 4;  /* the IRQ number
> of PCI bridge */
>
>         printk("%s : slot = %d  pin = %d \n",__func__,slot,pin);
>     switch (slot)
>     {
>         case 12:
>                 if (pin==1)
>                 {
>                         intnr = 3;
>                     }
>                     else
>                     {
>                         intnr = 0;
>                     }
> #ifdef CONFIG_DUAL_PCI
>                     return IRQ_PCI_INTD;
> #endif
>             break;
>         case 11:
>                     intnr = (2 + (pin - 1)) & 3;
> #ifdef CONFIG_DUAL_PCI
>                     return IRQ_PCI_INTC;
> #endif
>             break;
>         case 10:
>                     intnr = (1 + (pin - 1)) & 3;
> #ifdef CONFIG_DUAL_PCI
>                     return IRQ_PCI_INTB;
> #endif
>             break;
>         case  9:
>                     intnr = (pin - 1) & 3;
>             break;
>     }
> //      if (slot == 10)
> //              intnr = (1 + (pin - 1)) & 3;
> //      else if (slot == 9)
> //              intnr = (pin - 1) & 3;
>         return (IRQ_PCI_INTA + intnr);
> }
>
> If I understand correctly they say that the IRQs are not swizzled
> on the PCI bridge side but on the IRQ handler side.

That depends on whether CONFIG_DUAL_PCI is set or not:

It seems that slot 12 is hardwired to have hwirq 3 on IntA and
hwirq 0 on all others by default, but have hwirq on IntA through
IntD on boards that use CONFIG_DUAL_PCI.

Slot 10/11 use the default swizzling without CONFIG_DUAL_PCI but
uses hwirq 1 or 2 for all four pins with CONFIG_DUAL_PCI.

Slot 9 seems to always use the default swizzling, so it has all
four IRQ pins connected to the four hwirqs of the SoC.

This is still an awful wiring, but not unthinkable, as board
designers may have had a specific usage for the four interrupts
in mind, to spread the devices that are actually present across
the available hwirqs.

> So if I put it in the device tree like so:
>
> +                         interrupt-map =
> +                               <0x4800 0 0 1 &pci_intc 0>, /* Slot 9 */
> +                               <0x4800 0 0 2 &pci_intc 1>,
> +                               <0x4800 0 0 3 &pci_intc 2>,
> +                               <0x4800 0 0 4 &pci_intc 3>,
> +                               <0x5000 0 0 1 &pci_intc 1>, /* Slot 10 */
> +                               <0x5000 0 0 2 &pci_intc 2>,
> +                               <0x5000 0 0 3 &pci_intc 3>,
> +                               <0x5000 0 0 4 &pci_intc 0>,
> +                               <0x5800 0 0 1 &pci_intc 2>, /* Slot 11 */
> +                               <0x5800 0 0 2 &pci_intc 3>,
> +                               <0x5800 0 0 3 &pci_intc 0>,
> +                               <0x5800 0 0 4 &pci_intc 1>,

For boards that require CONFIG_DUAL_PCI, this would be

                               <0x5000 0 0 1 &pci_intc 1>, /* Slot 10 */
                               <0x5000 0 0 2 &pci_intc 1>,
                               <0x5000 0 0 3 &pci_intc 1>,
                               <0x5000 0 0 4 &pci_intc 1>,
                               <0x5800 0 0 1 &pci_intc 2>, /* Slot 11 */
                               <0x5800 0 0 2 &pci_intc 2>,
                               <0x5800 0 0 3 &pci_intc 2>,
                               <0x5800 0 0 4 &pci_intc 2>,

It probably works either way if you put just one device in there,
as almost everything uses just IntA, but you'd notice the difference
if there is ever a PCI bridge behind that slot.

> +                               <0x6000 0 0 1 &pci_intc 3>, /* Slot 12 */
> +                               <0x6000 0 0 2 &pci_intc 0>,
> +                               <0x6000 0 0 3 &pci_intc 1>,
> +                               <0x6000 0 0 4 &pci_intc 2>;

The last two have to be

                               <0x6000 0 0 3 &pci_intc 0>, /* [sic] */
                               <0x6000 0 0 4 &pci_intc 0>; /* [sic] */

> So the IRQs on the right side are swizzled instead
> of the pins being swizzled.
>
> ...but that looks a bit insane.
>
> Isn't that exactly the same thing just exposed in some
> inverse way?

I don't understand your question. The mapping that you list
is the default swizzling, right? I think if you have a board with
sane wiring, you could write that as

                      interrupt-map-mask = <0x0 0x0 0x0 0x7>;
                      interrupt-map =
                              <0x0 0x0 0x0 0x1 &pci_intc 0>, /* int A */
                              <0x0 0x0 0x0 0x2 &pci_intc 1>, /* int B */
                              <0x0 0x0 0x0 0x3 &pci_intc 2>, /* int C */
                              <0x0 0x0 0x0 0x4 &pci_intc 3>; /* int D */

meaning that the IRQs are wired correctly to the root bus, and
all slots are connected one would normally do with the standard
swizzling.

    Arnd

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

* Re: [PATCH 4/4] ARM: dts: add PCI to the Gemini DTSI
  2017-02-06  9:55         ` Hans Ulli Kroll
@ 2017-02-10 15:40           ` Arnd Bergmann
  -1 siblings, 0 replies; 64+ messages in thread
From: Arnd Bergmann @ 2017-02-10 15:40 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: openwrt-devel, Florian Fainelli, Paulius Zaleckas, linux-pci,
	Hans Ulli Kroll, Bjorn Helgaas, Janos Laube, Linus Walleij

On Monday, February 6, 2017 10:55:03 AM CET Hans Ulli Kroll wrote:
> 
> from my IB 4220 sources.
> 
> #define IRQ_PCI_INTA                                   PCI_IRQ_OFFSET + 0
> #ifndef CONFIG_DUAL_PCI
> #define IRQ_PCI_INTB                                   PCI_IRQ_OFFSET + 1
> #define IRQ_PCI_INTC                                   PCI_IRQ_OFFSET + 2
> #define IRQ_PCI_INTD                                   PCI_IRQ_OFFSET + 3
> #else
> #define IRQ_PCI_INTB                                   27
> #define IRQ_PCI_INTC                                   28
> #define IRQ_PCI_INTD                                   29
> #endif
> 
> CONFIG_DUAL_PCI is never used
> IRQ_PCIB - IRQ_PCID or IRQ_PCI_INTB - IRQ_PCI_INTD are also never used.
> 
> 

The source code that Linus quoted earlier had references to 
'IRQ_PCI_INTA +n' though, which is basically the same thing.

	Arnd

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 4/4] ARM: dts: add PCI to the Gemini DTSI
@ 2017-02-10 15:40           ` Arnd Bergmann
  0 siblings, 0 replies; 64+ messages in thread
From: Arnd Bergmann @ 2017-02-10 15:40 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday, February 6, 2017 10:55:03 AM CET Hans Ulli Kroll wrote:
> 
> from my IB 4220 sources.
> 
> #define IRQ_PCI_INTA                                   PCI_IRQ_OFFSET + 0
> #ifndef CONFIG_DUAL_PCI
> #define IRQ_PCI_INTB                                   PCI_IRQ_OFFSET + 1
> #define IRQ_PCI_INTC                                   PCI_IRQ_OFFSET + 2
> #define IRQ_PCI_INTD                                   PCI_IRQ_OFFSET + 3
> #else
> #define IRQ_PCI_INTB                                   27
> #define IRQ_PCI_INTC                                   28
> #define IRQ_PCI_INTD                                   29
> #endif
> 
> CONFIG_DUAL_PCI is never used
> IRQ_PCIB - IRQ_PCID or IRQ_PCI_INTB - IRQ_PCI_INTD are also never used.
> 
> 

The source code that Linus quoted earlier had references to 
'IRQ_PCI_INTA +n' though, which is basically the same thing.

	Arnd

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

* Re: [PATCH 4/4] ARM: dts: add PCI to the Gemini DTSI
  2017-02-10 15:40           ` Arnd Bergmann
@ 2017-02-11 11:17             ` Linus Walleij
  -1 siblings, 0 replies; 64+ messages in thread
From: Linus Walleij @ 2017-02-11 11:17 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: openwrt-devel, Florian Fainelli, Paulius Zaleckas, linux-pci,
	Hans Ulli Kroll, Bjorn Helgaas, Janos Laube, linux-arm-kernel

On Fri, Feb 10, 2017 at 4:40 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Monday, February 6, 2017 10:55:03 AM CET Hans Ulli Kroll wrote:
>>
>> from my IB 4220 sources.
>>
>> #define IRQ_PCI_INTA                                   PCI_IRQ_OFFSET + 0
>> #ifndef CONFIG_DUAL_PCI
>> #define IRQ_PCI_INTB                                   PCI_IRQ_OFFSET + 1
>> #define IRQ_PCI_INTC                                   PCI_IRQ_OFFSET + 2
>> #define IRQ_PCI_INTD                                   PCI_IRQ_OFFSET + 3
>> #else
>> #define IRQ_PCI_INTB                                   27
>> #define IRQ_PCI_INTC                                   28
>> #define IRQ_PCI_INTD                                   29
>> #endif
>>
>> CONFIG_DUAL_PCI is never used
>> IRQ_PCIB - IRQ_PCID or IRQ_PCI_INTB - IRQ_PCI_INTD are also never used.
>
> The source code that Linus quoted earlier had references to
> 'IRQ_PCI_INTA +n' though, which is basically the same thing.

There is essentially two versions of the IP block, one which has
a cascaded interrupt controller in the PCI host bridge, and one
named "dual PCI" that has dedicated IRQs for PCIA, B, C, D on
the primary interrupt controller.

I'll try to codify it into the driver so it's clear how this works on the
two variants.

I'm also pretty sure this is a faraday IP block and not something
from Storlink/Storm/Cortina, so I will rename the compatible strings
etc reflecting that.

Yours,
Linus Walleij

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 4/4] ARM: dts: add PCI to the Gemini DTSI
@ 2017-02-11 11:17             ` Linus Walleij
  0 siblings, 0 replies; 64+ messages in thread
From: Linus Walleij @ 2017-02-11 11:17 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Feb 10, 2017 at 4:40 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Monday, February 6, 2017 10:55:03 AM CET Hans Ulli Kroll wrote:
>>
>> from my IB 4220 sources.
>>
>> #define IRQ_PCI_INTA                                   PCI_IRQ_OFFSET + 0
>> #ifndef CONFIG_DUAL_PCI
>> #define IRQ_PCI_INTB                                   PCI_IRQ_OFFSET + 1
>> #define IRQ_PCI_INTC                                   PCI_IRQ_OFFSET + 2
>> #define IRQ_PCI_INTD                                   PCI_IRQ_OFFSET + 3
>> #else
>> #define IRQ_PCI_INTB                                   27
>> #define IRQ_PCI_INTC                                   28
>> #define IRQ_PCI_INTD                                   29
>> #endif
>>
>> CONFIG_DUAL_PCI is never used
>> IRQ_PCIB - IRQ_PCID or IRQ_PCI_INTB - IRQ_PCI_INTD are also never used.
>
> The source code that Linus quoted earlier had references to
> 'IRQ_PCI_INTA +n' though, which is basically the same thing.

There is essentially two versions of the IP block, one which has
a cascaded interrupt controller in the PCI host bridge, and one
named "dual PCI" that has dedicated IRQs for PCIA, B, C, D on
the primary interrupt controller.

I'll try to codify it into the driver so it's clear how this works on the
two variants.

I'm also pretty sure this is a faraday IP block and not something
from Storlink/Storm/Cortina, so I will rename the compatible strings
etc reflecting that.

Yours,
Linus Walleij

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

* Re: [PATCH 2/4] PCI: add driver for Cortina Gemini Host Bridge
  2017-02-04 18:43       ` Linus Walleij
@ 2017-02-16 14:08         ` Arnd Bergmann
  -1 siblings, 0 replies; 64+ messages in thread
From: Arnd Bergmann @ 2017-02-16 14:08 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: openwrt-devel, Florian Fainelli, Paulius Zaleckas, linux-pci,
	Linus Walleij, Bjorn Helgaas, Janos Laube, Hans Ulli Kroll

On Saturday, February 4, 2017 7:43:15 PM CET Linus Walleij wrote:
> On Wed, Feb 1, 2017 at 12:11 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> > On Saturday, January 28, 2017 9:48:37 PM CET Linus Walleij wrote:
> 
> >> +     /* No clue what these do */
> >> +     pcibios_min_io = 0x100;
> >> +     pcibios_min_mem = 0;
> >
> > Don't touch these
> 
> OK I have a clue why this is there now, atleast the first one.
> 
> The first 0x100 in the IOspace is actually configuration registers
> for the bridge. That is why we have this:

I see. It's normal to have the PCI config space done through
ports 0cf8-0cff, but apparently this one uses other ports in
the same range.

> reg = <0x50000000 0x100>;
> (...)
> /* PCI ranges mappings */
>                         ranges = /* 1MiB I/O space 0x50000000-0x500fffff */
>                          <0x01000000 0 0          0x50000000 0 0x00100000>,
> 
> This is in all the vendor code I have located too.
> 
> So the pcibios_min_io is manipulated to avoid touching that
> sensitive area. But I also see that arch/arm/mm/iomap.c
> sets it to 0x1000, according to the commit because you said
> it's the only valid value :D
> 
> I tried setting the IO range to <0x50000100 0x000FFF00>
> instead of <0x50000000 0x00100000>
> but predictably that doesn't work. Maybe it should, I don't
> know really.

It should work in theory, but then you'd have to update
io_offset accordingly, and it would be a bit confusing.

Did you notice my other comment below (quoting from my own
message)?

> > +
> > +     bus = pci_scan_root_bus(&pdev->dev, 0, &gemini_pci_ops, p, &res);
> 
> Can you try using the new pci_register_host_bridge() API?

	Arnd

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 2/4] PCI: add driver for Cortina Gemini Host Bridge
@ 2017-02-16 14:08         ` Arnd Bergmann
  0 siblings, 0 replies; 64+ messages in thread
From: Arnd Bergmann @ 2017-02-16 14:08 UTC (permalink / raw)
  To: linux-arm-kernel

On Saturday, February 4, 2017 7:43:15 PM CET Linus Walleij wrote:
> On Wed, Feb 1, 2017 at 12:11 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> > On Saturday, January 28, 2017 9:48:37 PM CET Linus Walleij wrote:
> 
> >> +     /* No clue what these do */
> >> +     pcibios_min_io = 0x100;
> >> +     pcibios_min_mem = 0;
> >
> > Don't touch these
> 
> OK I have a clue why this is there now, atleast the first one.
> 
> The first 0x100 in the IOspace is actually configuration registers
> for the bridge. That is why we have this:

I see. It's normal to have the PCI config space done through
ports 0cf8-0cff, but apparently this one uses other ports in
the same range.

> reg = <0x50000000 0x100>;
> (...)
> /* PCI ranges mappings */
>                         ranges = /* 1MiB I/O space 0x50000000-0x500fffff */
>                          <0x01000000 0 0          0x50000000 0 0x00100000>,
> 
> This is in all the vendor code I have located too.
> 
> So the pcibios_min_io is manipulated to avoid touching that
> sensitive area. But I also see that arch/arm/mm/iomap.c
> sets it to 0x1000, according to the commit because you said
> it's the only valid value :D
> 
> I tried setting the IO range to <0x50000100 0x000FFF00>
> instead of <0x50000000 0x00100000>
> but predictably that doesn't work. Maybe it should, I don't
> know really.

It should work in theory, but then you'd have to update
io_offset accordingly, and it would be a bit confusing.

Did you notice my other comment below (quoting from my own
message)?

> > +
> > +     bus = pci_scan_root_bus(&pdev->dev, 0, &gemini_pci_ops, p, &res);
> 
> Can you try using the new pci_register_host_bridge() API?

	Arnd

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

* Re: [PATCH 2/4] PCI: add driver for Cortina Gemini Host Bridge
  2017-02-16 14:08         ` Arnd Bergmann
@ 2017-02-18 14:05           ` Linus Walleij
  -1 siblings, 0 replies; 64+ messages in thread
From: Linus Walleij @ 2017-02-18 14:05 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: openwrt-devel, Florian Fainelli, Paulius Zaleckas, linux-pci,
	Hans Ulli Kroll, Bjorn Helgaas, Janos Laube, linux-arm-kernel

On Thu, Feb 16, 2017 at 3:08 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Saturday, February 4, 2017 7:43:15 PM CET Linus Walleij wrote:

> Did you notice my other comment below (quoting from my own
> message)?
>
>> > +
>> > +     bus = pci_scan_root_bus(&pdev->dev, 0, &gemini_pci_ops, p, &res);
>>
>> Can you try using the new pci_register_host_bridge() API?

Yes. It crashes badly when I try it so I'm still trying to figure this out...
If I do I will send an iteration.

Yours,
Linus Walleij

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 2/4] PCI: add driver for Cortina Gemini Host Bridge
@ 2017-02-18 14:05           ` Linus Walleij
  0 siblings, 0 replies; 64+ messages in thread
From: Linus Walleij @ 2017-02-18 14:05 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Feb 16, 2017 at 3:08 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Saturday, February 4, 2017 7:43:15 PM CET Linus Walleij wrote:

> Did you notice my other comment below (quoting from my own
> message)?
>
>> > +
>> > +     bus = pci_scan_root_bus(&pdev->dev, 0, &gemini_pci_ops, p, &res);
>>
>> Can you try using the new pci_register_host_bridge() API?

Yes. It crashes badly when I try it so I'm still trying to figure this out...
If I do I will send an iteration.

Yours,
Linus Walleij

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

* Re: [PATCH 2/4] PCI: add driver for Cortina Gemini Host Bridge
  2017-01-31  0:37     ` Bjorn Helgaas
@ 2017-02-26 19:42       ` Linus Walleij
  -1 siblings, 0 replies; 64+ messages in thread
From: Linus Walleij @ 2017-02-26 19:42 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Hans Ulli Kroll, Florian Fainelli, Bjorn Helgaas, Janos Laube,
	Paulius Zaleckas, openwrt-devel, linux-arm-kernel, linux-pci

On Tue, Jan 31, 2017 at 1:37 AM, Bjorn Helgaas <helgaas@kernel.org> wrote:

> Looks nice; a couple unused definitions below.

Just so I do things right:  what is your policy on unused defines?
I'm asking because the defines in this case is pretty much the
documentation... there is no datasheet for this IP core. I usually
like to keep the defines around so people can have them as a
hint if they want to tinker and hack the driver.

Would you be OK with keeping them if I comment them out?

I'll repost the driver soon, including all things asked to be
fixed up by you & Arnd.

Yours,
Linus Walleij

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

* [PATCH 2/4] PCI: add driver for Cortina Gemini Host Bridge
@ 2017-02-26 19:42       ` Linus Walleij
  0 siblings, 0 replies; 64+ messages in thread
From: Linus Walleij @ 2017-02-26 19:42 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jan 31, 2017 at 1:37 AM, Bjorn Helgaas <helgaas@kernel.org> wrote:

> Looks nice; a couple unused definitions below.

Just so I do things right:  what is your policy on unused defines?
I'm asking because the defines in this case is pretty much the
documentation... there is no datasheet for this IP core. I usually
like to keep the defines around so people can have them as a
hint if they want to tinker and hack the driver.

Would you be OK with keeping them if I comment them out?

I'll repost the driver soon, including all things asked to be
fixed up by you & Arnd.

Yours,
Linus Walleij

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

* Re: [PATCH 2/4] PCI: add driver for Cortina Gemini Host Bridge
  2017-02-26 19:42       ` Linus Walleij
@ 2017-02-27 16:49         ` Bjorn Helgaas
  -1 siblings, 0 replies; 64+ messages in thread
From: Bjorn Helgaas @ 2017-02-27 16:49 UTC (permalink / raw)
  To: Linus Walleij
  Cc: openwrt-devel, Florian Fainelli, Paulius Zaleckas, linux-pci,
	Hans Ulli Kroll, Bjorn Helgaas, Janos Laube, linux-arm-kernel

On Sun, Feb 26, 2017 at 08:42:51PM +0100, Linus Walleij wrote:
> On Tue, Jan 31, 2017 at 1:37 AM, Bjorn Helgaas <helgaas@kernel.org> wrote:
> 
> > Looks nice; a couple unused definitions below.
> 
> Just so I do things right:  what is your policy on unused defines?
> I'm asking because the defines in this case is pretty much the
> documentation... there is no datasheet for this IP core. I usually
> like to keep the defines around so people can have them as a
> hint if they want to tinker and hack the driver.
> 
> Would you be OK with keeping them if I comment them out?

It's fine if you keep them; don't even bother commenting them out.

If there's a datasheet, especially a public one like the PCI specs (I
know even those aren't completely free), I have been removing unused
defines simply because they can't be tested and there may be
transcription errors.  But I'm starting to think that might be too
aggressive.

Bjorn

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 2/4] PCI: add driver for Cortina Gemini Host Bridge
@ 2017-02-27 16:49         ` Bjorn Helgaas
  0 siblings, 0 replies; 64+ messages in thread
From: Bjorn Helgaas @ 2017-02-27 16:49 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Feb 26, 2017 at 08:42:51PM +0100, Linus Walleij wrote:
> On Tue, Jan 31, 2017 at 1:37 AM, Bjorn Helgaas <helgaas@kernel.org> wrote:
> 
> > Looks nice; a couple unused definitions below.
> 
> Just so I do things right:  what is your policy on unused defines?
> I'm asking because the defines in this case is pretty much the
> documentation... there is no datasheet for this IP core. I usually
> like to keep the defines around so people can have them as a
> hint if they want to tinker and hack the driver.
> 
> Would you be OK with keeping them if I comment them out?

It's fine if you keep them; don't even bother commenting them out.

If there's a datasheet, especially a public one like the PCI specs (I
know even those aren't completely free), I have been removing unused
defines simply because they can't be tested and there may be
transcription errors.  But I'm starting to think that might be too
aggressive.

Bjorn

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

end of thread, other threads:[~2017-02-27 16:49 UTC | newest]

Thread overview: 64+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-01-28 20:48 [PATCH 1/4] PCI: add DT bindings for Cortina Gemini PCI Host Bridge Linus Walleij
2017-01-28 20:48 ` Linus Walleij
2017-01-28 20:48 ` Linus Walleij
2017-01-28 20:48 ` [PATCH 2/4] PCI: add driver for Cortina Gemini " Linus Walleij
2017-01-28 20:48   ` Linus Walleij
2017-01-31  0:37   ` Bjorn Helgaas
2017-01-31  0:37     ` Bjorn Helgaas
2017-02-26 19:42     ` Linus Walleij
2017-02-26 19:42       ` Linus Walleij
2017-02-27 16:49       ` Bjorn Helgaas
2017-02-27 16:49         ` Bjorn Helgaas
2017-02-01 11:11   ` Arnd Bergmann
2017-02-01 11:11     ` Arnd Bergmann
2017-02-04 18:43     ` Linus Walleij
2017-02-04 18:43       ` Linus Walleij
2017-02-16 14:08       ` Arnd Bergmann
2017-02-16 14:08         ` Arnd Bergmann
2017-02-18 14:05         ` Linus Walleij
2017-02-18 14:05           ` Linus Walleij
2017-02-05 10:00   ` Hans Ulli Kroll
2017-02-05 10:00     ` Hans Ulli Kroll
2017-02-05 14:36     ` Linus Walleij
2017-02-05 14:36       ` Linus Walleij
2017-01-28 20:48 ` [PATCH 3/4] ARM: gemini: select MIGHT_HAVE_PCI Linus Walleij
2017-01-28 20:48   ` Linus Walleij
2017-01-28 20:48 ` [PATCH 4/4] ARM: dts: add PCI to the Gemini DTSI Linus Walleij
2017-01-28 20:48   ` Linus Walleij
2017-02-05 10:03   ` Hans Ulli Kroll
2017-02-05 10:03     ` Hans Ulli Kroll
2017-02-05 15:00     ` Linus Walleij
2017-02-05 15:00       ` Linus Walleij
2017-02-06  9:55       ` Hans Ulli Kroll
2017-02-06  9:55         ` Hans Ulli Kroll
2017-02-10 15:40         ` Arnd Bergmann
2017-02-10 15:40           ` Arnd Bergmann
2017-02-11 11:17           ` Linus Walleij
2017-02-11 11:17             ` Linus Walleij
2017-01-31  0:31 ` [PATCH 1/4] PCI: add DT bindings for Cortina Gemini PCI Host Bridge Bjorn Helgaas
2017-01-31  0:31   ` Bjorn Helgaas
2017-01-31  0:31   ` Bjorn Helgaas
     [not found]   ` <20170131003137.GE20550-1RhO1Y9PlrlHTL0Zs8A6p5iNqAH0jzoTYJqu5kTmcBRl57MIdRCFDg@public.gmane.org>
2017-02-01 20:00     ` Linus Walleij
2017-02-01 20:00       ` Linus Walleij
2017-02-01 20:00       ` Linus Walleij
     [not found] ` <20170128204839.18330-1-linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2017-02-01 11:09   ` Arnd Bergmann
2017-02-01 11:09     ` Arnd Bergmann
2017-02-01 11:09     ` Arnd Bergmann
2017-02-05 14:44     ` Linus Walleij
2017-02-05 14:44       ` Linus Walleij
2017-02-05 14:44       ` Linus Walleij
2017-02-01 11:19 ` Arnd Bergmann
2017-02-01 11:19   ` Arnd Bergmann
2017-02-01 11:19   ` Arnd Bergmann
2017-02-05 14:56   ` Linus Walleij
2017-02-05 14:56     ` Linus Walleij
2017-02-05 14:56     ` Linus Walleij
     [not found]     ` <CACRpkdYpBYaeTo2SJ55=cwKcZ5Y7A1k-wy1N3UuR6u3L3RdNoA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-02-06 16:05       ` Arnd Bergmann
2017-02-06 16:05         ` Arnd Bergmann
2017-02-06 16:05         ` Arnd Bergmann
2017-02-01 16:02 ` Rob Herring
2017-02-01 16:02   ` Rob Herring
2017-02-01 16:02   ` Rob Herring
2017-02-01 20:04   ` Linus Walleij
2017-02-01 20:04     ` Linus Walleij
2017-02-01 20:04     ` Linus Walleij

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