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