Root/target/linux/ar71xx/patches-3.2/017-MIPS-Initial-PCI-support-for-Atheros-724x-SoCs.patch

1From 958e444a5a7750c407ed0c90af28f74295478e99 Mon Sep 17 00:00:00 2001
2From: Rene Bolldorf <xsecute@googlemail.com>
3Date: Thu, 17 Nov 2011 14:25:09 +0000
4Subject: [PATCH 17/27] MIPS: Initial PCI support for Atheros 724x SoCs.
5
6[ralf@linux-mips.org: Fixed the odd formatting of all break statements.]
7
8Signed-off-by: Rene Bolldorf <xsecute@googlemail.com>
9Cc: linux-mips@linux-mips.org
10Cc: linux-kernel@vger.kernel.org
11Patchwork: https://patchwork.linux-mips.org/patch/3019/
12Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
13---
14 arch/mips/include/asm/mach-ath79/pci-ath724x.h | 21 +++
15 arch/mips/pci/Makefile | 1 +
16 arch/mips/pci/pci-ath724x.c | 174 ++++++++++++++++++++++++
17 3 files changed, 196 insertions(+), 0 deletions(-)
18 create mode 100644 arch/mips/include/asm/mach-ath79/pci-ath724x.h
19 create mode 100644 arch/mips/pci/pci-ath724x.c
20
21--- /dev/null
22+++ b/arch/mips/include/asm/mach-ath79/pci-ath724x.h
23@@ -0,0 +1,21 @@
24+/*
25+ * Atheros 724x PCI support
26+ *
27+ * Copyright (C) 2011 René Bolldorf <xsecute@googlemail.com>
28+ *
29+ * This program is free software; you can redistribute it and/or modify it
30+ * under the terms of the GNU General Public License version 2 as published
31+ * by the Free Software Foundation.
32+ */
33+
34+#ifndef __ASM_MACH_ATH79_PCI_ATH724X_H
35+#define __ASM_MACH_ATH79_PCI_ATH724X_H
36+
37+struct ath724x_pci_data {
38+ int irq;
39+ void *pdata;
40+};
41+
42+void ath724x_pci_add_data(struct ath724x_pci_data *data, int size);
43+
44+#endif /* __ASM_MACH_ATH79_PCI_ATH724X_H */
45--- a/arch/mips/pci/Makefile
46+++ b/arch/mips/pci/Makefile
47@@ -19,6 +19,7 @@ obj-$(CONFIG_BCM47XX) += pci-bcm47xx.o
48 obj-$(CONFIG_BCM63XX) += pci-bcm63xx.o fixup-bcm63xx.o \
49                     ops-bcm63xx.o
50 obj-$(CONFIG_MIPS_ALCHEMY) += pci-alchemy.o
51+obj-$(CONFIG_SOC_AR724X) += pci-ath724x.o
52 
53 #
54 # These are still pretty much in the old state, watch, go blind.
55--- /dev/null
56+++ b/arch/mips/pci/pci-ath724x.c
57@@ -0,0 +1,174 @@
58+/*
59+ * Atheros 724x PCI support
60+ *
61+ * Copyright (C) 2011 René Bolldorf <xsecute@googlemail.com>
62+ *
63+ * This program is free software; you can redistribute it and/or modify it
64+ * under the terms of the GNU General Public License version 2 as published
65+ * by the Free Software Foundation.
66+ */
67+
68+#include <linux/pci.h>
69+#include <asm/mach-ath79/pci-ath724x.h>
70+
71+#define reg_read(_phys) (*(unsigned int *) KSEG1ADDR(_phys))
72+#define reg_write(_phys, _val) ((*(unsigned int *) KSEG1ADDR(_phys)) = (_val))
73+
74+#define ATH724X_PCI_DEV_BASE 0x14000000
75+#define ATH724X_PCI_MEM_BASE 0x10000000
76+#define ATH724X_PCI_MEM_SIZE 0x08000000
77+
78+static DEFINE_SPINLOCK(ath724x_pci_lock);
79+static struct ath724x_pci_data *pci_data;
80+static int pci_data_size;
81+
82+static int ath724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
83+ int size, uint32_t *value)
84+{
85+ unsigned long flags, addr, tval, mask;
86+
87+ if (devfn)
88+ return PCIBIOS_DEVICE_NOT_FOUND;
89+
90+ if (where & (size - 1))
91+ return PCIBIOS_BAD_REGISTER_NUMBER;
92+
93+ spin_lock_irqsave(&ath724x_pci_lock, flags);
94+
95+ switch (size) {
96+ case 1:
97+ addr = where & ~3;
98+ mask = 0xff000000 >> ((where % 4) * 8);
99+ tval = reg_read(ATH724X_PCI_DEV_BASE + addr);
100+ tval = tval & ~mask;
101+ *value = (tval >> ((4 - (where % 4))*8));
102+ break;
103+ case 2:
104+ addr = where & ~3;
105+ mask = 0xffff0000 >> ((where % 4)*8);
106+ tval = reg_read(ATH724X_PCI_DEV_BASE + addr);
107+ tval = tval & ~mask;
108+ *value = (tval >> ((4 - (where % 4))*8));
109+ break;
110+ case 4:
111+ *value = reg_read(ATH724X_PCI_DEV_BASE + where);
112+ break;
113+ default:
114+ spin_unlock_irqrestore(&ath724x_pci_lock, flags);
115+
116+ return PCIBIOS_BAD_REGISTER_NUMBER;
117+ }
118+
119+ spin_unlock_irqrestore(&ath724x_pci_lock, flags);
120+
121+ return PCIBIOS_SUCCESSFUL;
122+}
123+
124+static int ath724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
125+ int size, uint32_t value)
126+{
127+ unsigned long flags, tval, addr, mask;
128+
129+ if (devfn)
130+ return PCIBIOS_DEVICE_NOT_FOUND;
131+
132+ if (where & (size - 1))
133+ return PCIBIOS_BAD_REGISTER_NUMBER;
134+
135+ spin_lock_irqsave(&ath724x_pci_lock, flags);
136+
137+ switch (size) {
138+ case 1:
139+ addr = (ATH724X_PCI_DEV_BASE + where) & ~3;
140+ mask = 0xff000000 >> ((where % 4)*8);
141+ tval = reg_read(addr);
142+ tval = tval & ~mask;
143+ tval |= (value << ((4 - (where % 4))*8)) & mask;
144+ reg_write(addr, tval);
145+ break;
146+ case 2:
147+ addr = (ATH724X_PCI_DEV_BASE + where) & ~3;
148+ mask = 0xffff0000 >> ((where % 4)*8);
149+ tval = reg_read(addr);
150+ tval = tval & ~mask;
151+ tval |= (value << ((4 - (where % 4))*8)) & mask;
152+ reg_write(addr, tval);
153+ break;
154+ case 4:
155+ reg_write((ATH724X_PCI_DEV_BASE + where), value);
156+ break;
157+ default:
158+ spin_unlock_irqrestore(&ath724x_pci_lock, flags);
159+
160+ return PCIBIOS_BAD_REGISTER_NUMBER;
161+ }
162+
163+ spin_unlock_irqrestore(&ath724x_pci_lock, flags);
164+
165+ return PCIBIOS_SUCCESSFUL;
166+}
167+
168+static struct pci_ops ath724x_pci_ops = {
169+ .read = ath724x_pci_read,
170+ .write = ath724x_pci_write,
171+};
172+
173+static struct resource ath724x_io_resource = {
174+ .name = "PCI IO space",
175+ .start = 0,
176+ .end = 0,
177+ .flags = IORESOURCE_IO,
178+};
179+
180+static struct resource ath724x_mem_resource = {
181+ .name = "PCI memory space",
182+ .start = ATH724X_PCI_MEM_BASE,
183+ .end = ATH724X_PCI_MEM_BASE + ATH724X_PCI_MEM_SIZE - 1,
184+ .flags = IORESOURCE_MEM,
185+};
186+
187+static struct pci_controller ath724x_pci_controller = {
188+ .pci_ops = &ath724x_pci_ops,
189+ .io_resource = &ath724x_io_resource,
190+ .mem_resource = &ath724x_mem_resource,
191+};
192+
193+void ath724x_pci_add_data(struct ath724x_pci_data *data, int size)
194+{
195+ pci_data = data;
196+ pci_data_size = size;
197+}
198+
199+int __init pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin)
200+{
201+ unsigned int devfn = dev->devfn;
202+ int irq = -1;
203+
204+ if (devfn > pci_data_size - 1)
205+ return irq;
206+
207+ irq = pci_data[devfn].irq;
208+
209+ return irq;
210+}
211+
212+int pcibios_plat_dev_init(struct pci_dev *dev)
213+{
214+ unsigned int devfn = dev->devfn;
215+
216+ if (devfn > pci_data_size - 1)
217+ return PCIBIOS_DEVICE_NOT_FOUND;
218+
219+ dev->dev.platform_data = pci_data[devfn].pdata;
220+
221+ return PCIBIOS_SUCCESSFUL;
222+}
223+
224+static int __init ath724x_pcibios_init(void)
225+{
226+ register_pci_controller(&ath724x_pci_controller);
227+
228+ return PCIBIOS_SUCCESSFUL;
229+}
230+
231+arch_initcall(ath724x_pcibios_init);
232

Archive Download this file



interactive