ramips: Power down phy on disabled switch ports
[openwrt/svn-archive/archive.git] / target / linux / ar71xx / patches-3.3 / 149-MIPS-pci-ar724x-use-dynamically-allocated-PCI-contro.patch
1 From 242aedf3246dc5085271aca56134ac455bfb64b5 Mon Sep 17 00:00:00 2001
2 From: Gabor Juhos <juhosg@openwrt.org>
3 Date: Sun, 24 Jun 2012 11:51:34 +0200
4 Subject: [PATCH 10/34] MIPS: pci-ar724x: use dynamically allocated PCI controller structure
5
6 Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
7 ---
8 arch/mips/pci/pci-ar724x.c | 129 ++++++++++++++++++++++++++++----------------
9 1 files changed, 82 insertions(+), 47 deletions(-)
10
11 --- a/arch/mips/pci/pci-ar724x.c
12 +++ b/arch/mips/pci/pci-ar724x.c
13 @@ -9,6 +9,7 @@
14 * by the Free Software Foundation.
15 */
16
17 +#include <linux/spinlock.h>
18 #include <linux/irq.h>
19 #include <linux/pci.h>
20 #include <linux/module.h>
21 @@ -28,38 +29,56 @@
22
23 #define AR7240_BAR0_WAR_VALUE 0xffff
24
25 -static DEFINE_SPINLOCK(ar724x_pci_lock);
26 -static void __iomem *ar724x_pci_devcfg_base;
27 -static void __iomem *ar724x_pci_ctrl_base;
28 -
29 -static u32 ar724x_pci_bar0_value;
30 -static bool ar724x_pci_bar0_is_cached;
31 -static bool ar724x_pci_link_up;
32 +struct ar724x_pci_controller {
33 + void __iomem *devcfg_base;
34 + void __iomem *ctrl_base;
35
36 -static inline bool ar724x_pci_check_link(void)
37 + int irq;
38 +
39 + bool link_up;
40 + bool bar0_is_cached;
41 + u32 bar0_value;
42 +
43 + spinlock_t lock;
44 +
45 + struct pci_controller pci_controller;
46 +};
47 +
48 +static inline bool ar724x_pci_check_link(struct ar724x_pci_controller *apc)
49 {
50 u32 reset;
51
52 - reset = __raw_readl(ar724x_pci_ctrl_base + AR724X_PCI_REG_RESET);
53 + reset = __raw_readl(apc->ctrl_base + AR724X_PCI_REG_RESET);
54 return reset & AR724X_PCI_RESET_LINK_UP;
55 }
56
57 +static inline struct ar724x_pci_controller *
58 +pci_bus_to_ar724x_controller(struct pci_bus *bus)
59 +{
60 + struct pci_controller *hose;
61 +
62 + hose = (struct pci_controller *) bus->sysdata;
63 + return container_of(hose, struct ar724x_pci_controller, pci_controller);
64 +}
65 +
66 static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
67 int size, uint32_t *value)
68 {
69 + struct ar724x_pci_controller *apc;
70 unsigned long flags;
71 void __iomem *base;
72 u32 data;
73
74 - if (!ar724x_pci_link_up)
75 + apc = pci_bus_to_ar724x_controller(bus);
76 + if (!apc->link_up)
77 return PCIBIOS_DEVICE_NOT_FOUND;
78
79 if (devfn)
80 return PCIBIOS_DEVICE_NOT_FOUND;
81
82 - base = ar724x_pci_devcfg_base;
83 + base = apc->devcfg_base;
84
85 - spin_lock_irqsave(&ar724x_pci_lock, flags);
86 + spin_lock_irqsave(&apc->lock, flags);
87 data = __raw_readl(base + (where & ~3));
88
89 switch (size) {
90 @@ -78,17 +97,17 @@ static int ar724x_pci_read(struct pci_bu
91 case 4:
92 break;
93 default:
94 - spin_unlock_irqrestore(&ar724x_pci_lock, flags);
95 + spin_unlock_irqrestore(&apc->lock, flags);
96
97 return PCIBIOS_BAD_REGISTER_NUMBER;
98 }
99
100 - spin_unlock_irqrestore(&ar724x_pci_lock, flags);
101 + spin_unlock_irqrestore(&apc->lock, flags);
102
103 if (where == PCI_BASE_ADDRESS_0 && size == 4 &&
104 - ar724x_pci_bar0_is_cached) {
105 + apc->bar0_is_cached) {
106 /* use the cached value */
107 - *value = ar724x_pci_bar0_value;
108 + *value = apc->bar0_value;
109 } else {
110 *value = data;
111 }
112 @@ -99,12 +118,14 @@ static int ar724x_pci_read(struct pci_bu
113 static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
114 int size, uint32_t value)
115 {
116 + struct ar724x_pci_controller *apc;
117 unsigned long flags;
118 void __iomem *base;
119 u32 data;
120 int s;
121
122 - if (!ar724x_pci_link_up)
123 + apc = pci_bus_to_ar724x_controller(bus);
124 + if (!apc->link_up)
125 return PCIBIOS_DEVICE_NOT_FOUND;
126
127 if (devfn)
128 @@ -122,18 +143,18 @@ static int ar724x_pci_write(struct pci_b
129 * BAR0 register in order to make the device memory
130 * accessible.
131 */
132 - ar724x_pci_bar0_is_cached = true;
133 - ar724x_pci_bar0_value = value;
134 + apc->bar0_is_cached = true;
135 + apc->bar0_value = value;
136
137 value = AR7240_BAR0_WAR_VALUE;
138 } else {
139 - ar724x_pci_bar0_is_cached = false;
140 + apc->bar0_is_cached = false;
141 }
142 }
143
144 - base = ar724x_pci_devcfg_base;
145 + base = apc->devcfg_base;
146
147 - spin_lock_irqsave(&ar724x_pci_lock, flags);
148 + spin_lock_irqsave(&apc->lock, flags);
149 data = __raw_readl(base + (where & ~3));
150
151 switch (size) {
152 @@ -151,7 +172,7 @@ static int ar724x_pci_write(struct pci_b
153 data = value;
154 break;
155 default:
156 - spin_unlock_irqrestore(&ar724x_pci_lock, flags);
157 + spin_unlock_irqrestore(&apc->lock, flags);
158
159 return PCIBIOS_BAD_REGISTER_NUMBER;
160 }
161 @@ -159,7 +180,7 @@ static int ar724x_pci_write(struct pci_b
162 __raw_writel(data, base + (where & ~3));
163 /* flush write */
164 __raw_readl(base + (where & ~3));
165 - spin_unlock_irqrestore(&ar724x_pci_lock, flags);
166 + spin_unlock_irqrestore(&apc->lock, flags);
167
168 return PCIBIOS_SUCCESSFUL;
169 }
170 @@ -183,18 +204,14 @@ static struct resource ar724x_mem_resour
171 .flags = IORESOURCE_MEM,
172 };
173
174 -static struct pci_controller ar724x_pci_controller = {
175 - .pci_ops = &ar724x_pci_ops,
176 - .io_resource = &ar724x_io_resource,
177 - .mem_resource = &ar724x_mem_resource,
178 -};
179 -
180 static void ar724x_pci_irq_handler(unsigned int irq, struct irq_desc *desc)
181 {
182 + struct ar724x_pci_controller *apc;
183 void __iomem *base;
184 u32 pending;
185
186 - base = ar724x_pci_ctrl_base;
187 + apc = irq_get_handler_data(irq);
188 + base = apc->ctrl_base;
189
190 pending = __raw_readl(base + AR724X_PCI_REG_INT_STATUS) &
191 __raw_readl(base + AR724X_PCI_REG_INT_MASK);
192 @@ -208,10 +225,12 @@ static void ar724x_pci_irq_handler(unsig
193
194 static void ar724x_pci_irq_unmask(struct irq_data *d)
195 {
196 + struct ar724x_pci_controller *apc;
197 void __iomem *base;
198 u32 t;
199
200 - base = ar724x_pci_ctrl_base;
201 + apc = irq_data_get_irq_chip_data(d);
202 + base = apc->ctrl_base;
203
204 switch (d->irq) {
205 case ATH79_PCI_IRQ(0):
206 @@ -225,10 +244,12 @@ static void ar724x_pci_irq_unmask(struct
207
208 static void ar724x_pci_irq_mask(struct irq_data *d)
209 {
210 + struct ar724x_pci_controller *apc;
211 void __iomem *base;
212 u32 t;
213
214 - base = ar724x_pci_ctrl_base;
215 + apc = irq_data_get_irq_chip_data(d);
216 + base = apc->ctrl_base;
217
218 switch (d->irq) {
219 case ATH79_PCI_IRQ(0):
220 @@ -255,12 +276,12 @@ static struct irq_chip ar724x_pci_irq_ch
221 .irq_mask_ack = ar724x_pci_irq_mask,
222 };
223
224 -static void __devinit ar724x_pci_irq_init(int irq)
225 +static void __devinit ar724x_pci_irq_init(struct ar724x_pci_controller *apc)
226 {
227 void __iomem *base;
228 int i;
229
230 - base = ar724x_pci_ctrl_base;
231 + base = apc->ctrl_base;
232
233 __raw_writel(0, base + AR724X_PCI_REG_INT_MASK);
234 __raw_writel(0, base + AR724X_PCI_REG_INT_STATUS);
235 @@ -268,45 +289,59 @@ static void __devinit ar724x_pci_irq_ini
236 BUILD_BUG_ON(ATH79_PCI_IRQ_COUNT < AR724X_PCI_IRQ_COUNT);
237
238 for (i = ATH79_PCI_IRQ_BASE;
239 - i < ATH79_PCI_IRQ_BASE + AR724X_PCI_IRQ_COUNT; i++)
240 + i < ATH79_PCI_IRQ_BASE + AR724X_PCI_IRQ_COUNT; i++) {
241 irq_set_chip_and_handler(i, &ar724x_pci_irq_chip,
242 handle_level_irq);
243 + irq_set_chip_data(i, apc);
244 + }
245
246 - irq_set_chained_handler(irq, ar724x_pci_irq_handler);
247 + irq_set_handler_data(apc->irq, apc);
248 + irq_set_chained_handler(apc->irq, ar724x_pci_irq_handler);
249 }
250
251 static int __devinit ar724x_pci_probe(struct platform_device *pdev)
252 {
253 + struct ar724x_pci_controller *apc;
254 struct resource *res;
255 - int irq;
256 +
257 + apc = devm_kzalloc(&pdev->dev, sizeof(struct ar724x_pci_controller),
258 + GFP_KERNEL);
259 + if (!apc)
260 + return -ENOMEM;
261
262 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ctrl_base");
263 if (!res)
264 return -EINVAL;
265
266 - ar724x_pci_ctrl_base = devm_request_and_ioremap(&pdev->dev, res);
267 - if (ar724x_pci_ctrl_base == NULL)
268 + apc->ctrl_base = devm_request_and_ioremap(&pdev->dev, res);
269 + if (apc->ctrl_base == NULL)
270 return -EBUSY;
271
272 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg_base");
273 if (!res)
274 return -EINVAL;
275
276 - ar724x_pci_devcfg_base = devm_request_and_ioremap(&pdev->dev, res);
277 - if (!ar724x_pci_devcfg_base)
278 + apc->devcfg_base = devm_request_and_ioremap(&pdev->dev, res);
279 + if (!apc->devcfg_base)
280 return -EBUSY;
281
282 - irq = platform_get_irq(pdev, 0);
283 - if (irq < 0)
284 + apc->irq = platform_get_irq(pdev, 0);
285 + if (apc->irq < 0)
286 return -EINVAL;
287
288 - ar724x_pci_link_up = ar724x_pci_check_link();
289 - if (!ar724x_pci_link_up)
290 + spin_lock_init(&apc->lock);
291 +
292 + apc->pci_controller.pci_ops = &ar724x_pci_ops;
293 + apc->pci_controller.io_resource = &ar724x_io_resource;
294 + apc->pci_controller.mem_resource = &ar724x_mem_resource;
295 +
296 + apc->link_up = ar724x_pci_check_link(apc);
297 + if (!apc->link_up)
298 dev_warn(&pdev->dev, "PCIe link is down\n");
299
300 - ar724x_pci_irq_init(irq);
301 + ar724x_pci_irq_init(apc);
302
303 - register_pci_controller(&ar724x_pci_controller);
304 + register_pci_controller(&apc->pci_controller);
305
306 return 0;
307 }