ar71xx: merge machine patches
[openwrt.git] / target / linux / ar71xx / patches-3.6 / 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  }