aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/pci/pci-ar724x.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/pci/pci-ar724x.c')
-rw-r--r--arch/mips/pci/pci-ar724x.c129
1 files changed, 82 insertions, 47 deletions
diff --git a/arch/mips/pci/pci-ar724x.c b/arch/mips/pci/pci-ar724x.c
index 8f008d9a112c..93ab8778ce10 100644
--- a/arch/mips/pci/pci-ar724x.c
+++ b/arch/mips/pci/pci-ar724x.c
@@ -9,6 +9,7 @@
9 * by the Free Software Foundation. 9 * by the Free Software Foundation.
10 */ 10 */
11 11
12#include <linux/spinlock.h>
12#include <linux/irq.h> 13#include <linux/irq.h>
13#include <linux/pci.h> 14#include <linux/pci.h>
14#include <linux/module.h> 15#include <linux/module.h>
@@ -28,38 +29,56 @@
28 29
29#define AR7240_BAR0_WAR_VALUE 0xffff 30#define AR7240_BAR0_WAR_VALUE 0xffff
30 31
31static DEFINE_SPINLOCK(ar724x_pci_lock); 32struct ar724x_pci_controller {
32static void __iomem *ar724x_pci_devcfg_base; 33 void __iomem *devcfg_base;
33static void __iomem *ar724x_pci_ctrl_base; 34 void __iomem *ctrl_base;
34 35
35static u32 ar724x_pci_bar0_value; 36 int irq;
36static bool ar724x_pci_bar0_is_cached; 37
37static bool ar724x_pci_link_up; 38 bool link_up;
39 bool bar0_is_cached;
40 u32 bar0_value;
41
42 spinlock_t lock;
43
44 struct pci_controller pci_controller;
45};
38 46
39static inline bool ar724x_pci_check_link(void) 47static inline bool ar724x_pci_check_link(struct ar724x_pci_controller *apc)
40{ 48{
41 u32 reset; 49 u32 reset;
42 50
43 reset = __raw_readl(ar724x_pci_ctrl_base + AR724X_PCI_REG_RESET); 51 reset = __raw_readl(apc->ctrl_base + AR724X_PCI_REG_RESET);
44 return reset & AR724X_PCI_RESET_LINK_UP; 52 return reset & AR724X_PCI_RESET_LINK_UP;
45} 53}
46 54
55static inline struct ar724x_pci_controller *
56pci_bus_to_ar724x_controller(struct pci_bus *bus)
57{
58 struct pci_controller *hose;
59
60 hose = (struct pci_controller *) bus->sysdata;
61 return container_of(hose, struct ar724x_pci_controller, pci_controller);
62}
63
47static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where, 64static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
48 int size, uint32_t *value) 65 int size, uint32_t *value)
49{ 66{
67 struct ar724x_pci_controller *apc;
50 unsigned long flags; 68 unsigned long flags;
51 void __iomem *base; 69 void __iomem *base;
52 u32 data; 70 u32 data;
53 71
54 if (!ar724x_pci_link_up) 72 apc = pci_bus_to_ar724x_controller(bus);
73 if (!apc->link_up)
55 return PCIBIOS_DEVICE_NOT_FOUND; 74 return PCIBIOS_DEVICE_NOT_FOUND;
56 75
57 if (devfn) 76 if (devfn)
58 return PCIBIOS_DEVICE_NOT_FOUND; 77 return PCIBIOS_DEVICE_NOT_FOUND;
59 78
60 base = ar724x_pci_devcfg_base; 79 base = apc->devcfg_base;
61 80
62 spin_lock_irqsave(&ar724x_pci_lock, flags); 81 spin_lock_irqsave(&apc->lock, flags);
63 data = __raw_readl(base + (where & ~3)); 82 data = __raw_readl(base + (where & ~3));
64 83
65 switch (size) { 84 switch (size) {
@@ -78,17 +97,17 @@ static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
78 case 4: 97 case 4:
79 break; 98 break;
80 default: 99 default:
81 spin_unlock_irqrestore(&ar724x_pci_lock, flags); 100 spin_unlock_irqrestore(&apc->lock, flags);
82 101
83 return PCIBIOS_BAD_REGISTER_NUMBER; 102 return PCIBIOS_BAD_REGISTER_NUMBER;
84 } 103 }
85 104
86 spin_unlock_irqrestore(&ar724x_pci_lock, flags); 105 spin_unlock_irqrestore(&apc->lock, flags);
87 106
88 if (where == PCI_BASE_ADDRESS_0 && size == 4 && 107 if (where == PCI_BASE_ADDRESS_0 && size == 4 &&
89 ar724x_pci_bar0_is_cached) { 108 apc->bar0_is_cached) {
90 /* use the cached value */ 109 /* use the cached value */
91 *value = ar724x_pci_bar0_value; 110 *value = apc->bar0_value;
92 } else { 111 } else {
93 *value = data; 112 *value = data;
94 } 113 }
@@ -99,12 +118,14 @@ static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
99static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where, 118static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
100 int size, uint32_t value) 119 int size, uint32_t value)
101{ 120{
121 struct ar724x_pci_controller *apc;
102 unsigned long flags; 122 unsigned long flags;
103 void __iomem *base; 123 void __iomem *base;
104 u32 data; 124 u32 data;
105 int s; 125 int s;
106 126
107 if (!ar724x_pci_link_up) 127 apc = pci_bus_to_ar724x_controller(bus);
128 if (!apc->link_up)
108 return PCIBIOS_DEVICE_NOT_FOUND; 129 return PCIBIOS_DEVICE_NOT_FOUND;
109 130
110 if (devfn) 131 if (devfn)
@@ -122,18 +143,18 @@ static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
122 * BAR0 register in order to make the device memory 143 * BAR0 register in order to make the device memory
123 * accessible. 144 * accessible.
124 */ 145 */
125 ar724x_pci_bar0_is_cached = true; 146 apc->bar0_is_cached = true;
126 ar724x_pci_bar0_value = value; 147 apc->bar0_value = value;
127 148
128 value = AR7240_BAR0_WAR_VALUE; 149 value = AR7240_BAR0_WAR_VALUE;
129 } else { 150 } else {
130 ar724x_pci_bar0_is_cached = false; 151 apc->bar0_is_cached = false;
131 } 152 }
132 } 153 }
133 154
134 base = ar724x_pci_devcfg_base; 155 base = apc->devcfg_base;
135 156
136 spin_lock_irqsave(&ar724x_pci_lock, flags); 157 spin_lock_irqsave(&apc->lock, flags);
137 data = __raw_readl(base + (where & ~3)); 158 data = __raw_readl(base + (where & ~3));
138 159
139 switch (size) { 160 switch (size) {
@@ -151,7 +172,7 @@ static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
151 data = value; 172 data = value;
152 break; 173 break;
153 default: 174 default:
154 spin_unlock_irqrestore(&ar724x_pci_lock, flags); 175 spin_unlock_irqrestore(&apc->lock, flags);
155 176
156 return PCIBIOS_BAD_REGISTER_NUMBER; 177 return PCIBIOS_BAD_REGISTER_NUMBER;
157 } 178 }
@@ -159,7 +180,7 @@ static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
159 __raw_writel(data, base + (where & ~3)); 180 __raw_writel(data, base + (where & ~3));
160 /* flush write */ 181 /* flush write */
161 __raw_readl(base + (where & ~3)); 182 __raw_readl(base + (where & ~3));
162 spin_unlock_irqrestore(&ar724x_pci_lock, flags); 183 spin_unlock_irqrestore(&apc->lock, flags);
163 184
164 return PCIBIOS_SUCCESSFUL; 185 return PCIBIOS_SUCCESSFUL;
165} 186}
@@ -183,18 +204,14 @@ static struct resource ar724x_mem_resource = {
183 .flags = IORESOURCE_MEM, 204 .flags = IORESOURCE_MEM,
184}; 205};
185 206
186static struct pci_controller ar724x_pci_controller = {
187 .pci_ops = &ar724x_pci_ops,
188 .io_resource = &ar724x_io_resource,
189 .mem_resource = &ar724x_mem_resource,
190};
191
192static void ar724x_pci_irq_handler(unsigned int irq, struct irq_desc *desc) 207static void ar724x_pci_irq_handler(unsigned int irq, struct irq_desc *desc)
193{ 208{
209 struct ar724x_pci_controller *apc;
194 void __iomem *base; 210 void __iomem *base;
195 u32 pending; 211 u32 pending;
196 212
197 base = ar724x_pci_ctrl_base; 213 apc = irq_get_handler_data(irq);
214 base = apc->ctrl_base;
198 215
199 pending = __raw_readl(base + AR724X_PCI_REG_INT_STATUS) & 216 pending = __raw_readl(base + AR724X_PCI_REG_INT_STATUS) &
200 __raw_readl(base + AR724X_PCI_REG_INT_MASK); 217 __raw_readl(base + AR724X_PCI_REG_INT_MASK);
@@ -208,10 +225,12 @@ static void ar724x_pci_irq_handler(unsigned int irq, struct irq_desc *desc)
208 225
209static void ar724x_pci_irq_unmask(struct irq_data *d) 226static void ar724x_pci_irq_unmask(struct irq_data *d)
210{ 227{
228 struct ar724x_pci_controller *apc;
211 void __iomem *base; 229 void __iomem *base;
212 u32 t; 230 u32 t;
213 231
214 base = ar724x_pci_ctrl_base; 232 apc = irq_data_get_irq_chip_data(d);
233 base = apc->ctrl_base;
215 234
216 switch (d->irq) { 235 switch (d->irq) {
217 case ATH79_PCI_IRQ(0): 236 case ATH79_PCI_IRQ(0):
@@ -225,10 +244,12 @@ static void ar724x_pci_irq_unmask(struct irq_data *d)
225 244
226static void ar724x_pci_irq_mask(struct irq_data *d) 245static void ar724x_pci_irq_mask(struct irq_data *d)
227{ 246{
247 struct ar724x_pci_controller *apc;
228 void __iomem *base; 248 void __iomem *base;
229 u32 t; 249 u32 t;
230 250
231 base = ar724x_pci_ctrl_base; 251 apc = irq_data_get_irq_chip_data(d);
252 base = apc->ctrl_base;
232 253
233 switch (d->irq) { 254 switch (d->irq) {
234 case ATH79_PCI_IRQ(0): 255 case ATH79_PCI_IRQ(0):
@@ -255,12 +276,12 @@ static struct irq_chip ar724x_pci_irq_chip = {
255 .irq_mask_ack = ar724x_pci_irq_mask, 276 .irq_mask_ack = ar724x_pci_irq_mask,
256}; 277};
257 278
258static void ar724x_pci_irq_init(int irq) 279static void ar724x_pci_irq_init(struct ar724x_pci_controller *apc)
259{ 280{
260 void __iomem *base; 281 void __iomem *base;
261 int i; 282 int i;
262 283
263 base = ar724x_pci_ctrl_base; 284 base = apc->ctrl_base;
264 285
265 __raw_writel(0, base + AR724X_PCI_REG_INT_MASK); 286 __raw_writel(0, base + AR724X_PCI_REG_INT_MASK);
266 __raw_writel(0, base + AR724X_PCI_REG_INT_STATUS); 287 __raw_writel(0, base + AR724X_PCI_REG_INT_STATUS);
@@ -268,45 +289,59 @@ static void ar724x_pci_irq_init(int irq)
268 BUILD_BUG_ON(ATH79_PCI_IRQ_COUNT < AR724X_PCI_IRQ_COUNT); 289 BUILD_BUG_ON(ATH79_PCI_IRQ_COUNT < AR724X_PCI_IRQ_COUNT);
269 290
270 for (i = ATH79_PCI_IRQ_BASE; 291 for (i = ATH79_PCI_IRQ_BASE;
271 i < ATH79_PCI_IRQ_BASE + AR724X_PCI_IRQ_COUNT; i++) 292 i < ATH79_PCI_IRQ_BASE + AR724X_PCI_IRQ_COUNT; i++) {
272 irq_set_chip_and_handler(i, &ar724x_pci_irq_chip, 293 irq_set_chip_and_handler(i, &ar724x_pci_irq_chip,
273 handle_level_irq); 294 handle_level_irq);
295 irq_set_chip_data(i, apc);
296 }
274 297
275 irq_set_chained_handler(irq, ar724x_pci_irq_handler); 298 irq_set_handler_data(apc->irq, apc);
299 irq_set_chained_handler(apc->irq, ar724x_pci_irq_handler);
276} 300}
277 301
278static int ar724x_pci_probe(struct platform_device *pdev) 302static int ar724x_pci_probe(struct platform_device *pdev)
279{ 303{
304 struct ar724x_pci_controller *apc;
280 struct resource *res; 305 struct resource *res;
281 int irq; 306
307 apc = devm_kzalloc(&pdev->dev, sizeof(struct ar724x_pci_controller),
308 GFP_KERNEL);
309 if (!apc)
310 return -ENOMEM;
282 311
283 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ctrl_base"); 312 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ctrl_base");
284 if (!res) 313 if (!res)
285 return -EINVAL; 314 return -EINVAL;
286 315
287 ar724x_pci_ctrl_base = devm_request_and_ioremap(&pdev->dev, res); 316 apc->ctrl_base = devm_request_and_ioremap(&pdev->dev, res);
288 if (ar724x_pci_ctrl_base == NULL) 317 if (apc->ctrl_base == NULL)
289 return -EBUSY; 318 return -EBUSY;
290 319
291 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg_base"); 320 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg_base");
292 if (!res) 321 if (!res)
293 return -EINVAL; 322 return -EINVAL;
294 323
295 ar724x_pci_devcfg_base = devm_request_and_ioremap(&pdev->dev, res); 324 apc->devcfg_base = devm_request_and_ioremap(&pdev->dev, res);
296 if (!ar724x_pci_devcfg_base) 325 if (!apc->devcfg_base)
297 return -EBUSY; 326 return -EBUSY;
298 327
299 irq = platform_get_irq(pdev, 0); 328 apc->irq = platform_get_irq(pdev, 0);
300 if (irq < 0) 329 if (apc->irq < 0)
301 return -EINVAL; 330 return -EINVAL;
302 331
303 ar724x_pci_link_up = ar724x_pci_check_link(); 332 spin_lock_init(&apc->lock);
304 if (!ar724x_pci_link_up) 333
334 apc->pci_controller.pci_ops = &ar724x_pci_ops;
335 apc->pci_controller.io_resource = &ar724x_io_resource;
336 apc->pci_controller.mem_resource = &ar724x_mem_resource;
337
338 apc->link_up = ar724x_pci_check_link(apc);
339 if (!apc->link_up)
305 dev_warn(&pdev->dev, "PCIe link is down\n"); 340 dev_warn(&pdev->dev, "PCIe link is down\n");
306 341
307 ar724x_pci_irq_init(irq); 342 ar724x_pci_irq_init(apc);
308 343
309 register_pci_controller(&ar724x_pci_controller); 344 register_pci_controller(&apc->pci_controller);
310 345
311 return 0; 346 return 0;
312} 347}