P4080/eLBC: Make Freescale elbc interrupt common to elbc devices
[pandora-kernel.git] / arch / powerpc / sysdev / fsl_lbc.c
1 /*
2  * Freescale LBC and UPM routines.
3  *
4  * Copyright © 2007-2008  MontaVista Software, Inc.
5  * Copyright © 2010 Freescale Semiconductor
6  *
7  * Author: Anton Vorontsov <avorontsov@ru.mvista.com>
8  * Author: Jack Lan <Jack.Lan@freescale.com>
9  * Author: Roy Zang <tie-fei.zang@freescale.com>
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  */
16
17 #include <linux/init.h>
18 #include <linux/module.h>
19 #include <linux/kernel.h>
20 #include <linux/compiler.h>
21 #include <linux/spinlock.h>
22 #include <linux/types.h>
23 #include <linux/io.h>
24 #include <linux/of.h>
25 #include <linux/slab.h>
26 #include <linux/platform_device.h>
27 #include <linux/interrupt.h>
28 #include <linux/mod_devicetable.h>
29 #include <asm/prom.h>
30 #include <asm/fsl_lbc.h>
31
32 static spinlock_t fsl_lbc_lock = __SPIN_LOCK_UNLOCKED(fsl_lbc_lock);
33 struct fsl_lbc_ctrl *fsl_lbc_ctrl_dev;
34 EXPORT_SYMBOL(fsl_lbc_ctrl_dev);
35
36 /**
37  * fsl_lbc_find - find Localbus bank
38  * @addr_base:  base address of the memory bank
39  *
40  * This function walks LBC banks comparing "Base address" field of the BR
41  * registers with the supplied addr_base argument. When bases match this
42  * function returns bank number (starting with 0), otherwise it returns
43  * appropriate errno value.
44  */
45 int fsl_lbc_find(phys_addr_t addr_base)
46 {
47         int i;
48         struct fsl_lbc_regs __iomem *lbc;
49
50         if (!fsl_lbc_ctrl_dev || !fsl_lbc_ctrl_dev->regs)
51                 return -ENODEV;
52
53         lbc = fsl_lbc_ctrl_dev->regs;
54         for (i = 0; i < ARRAY_SIZE(lbc->bank); i++) {
55                 __be32 br = in_be32(&lbc->bank[i].br);
56                 __be32 or = in_be32(&lbc->bank[i].or);
57
58                 if (br & BR_V && (br & or & BR_BA) == addr_base)
59                         return i;
60         }
61
62         return -ENOENT;
63 }
64 EXPORT_SYMBOL(fsl_lbc_find);
65
66 /**
67  * fsl_upm_find - find pre-programmed UPM via base address
68  * @addr_base:  base address of the memory bank controlled by the UPM
69  * @upm:        pointer to the allocated fsl_upm structure
70  *
71  * This function fills fsl_upm structure so you can use it with the rest of
72  * UPM API. On success this function returns 0, otherwise it returns
73  * appropriate errno value.
74  */
75 int fsl_upm_find(phys_addr_t addr_base, struct fsl_upm *upm)
76 {
77         int bank;
78         __be32 br;
79         struct fsl_lbc_regs __iomem *lbc;
80
81         bank = fsl_lbc_find(addr_base);
82         if (bank < 0)
83                 return bank;
84
85         if (!fsl_lbc_ctrl_dev || !fsl_lbc_ctrl_dev->regs)
86                 return -ENODEV;
87
88         lbc = fsl_lbc_ctrl_dev->regs;
89         br = in_be32(&lbc->bank[bank].br);
90
91         switch (br & BR_MSEL) {
92         case BR_MS_UPMA:
93                 upm->mxmr = &lbc->mamr;
94                 break;
95         case BR_MS_UPMB:
96                 upm->mxmr = &lbc->mbmr;
97                 break;
98         case BR_MS_UPMC:
99                 upm->mxmr = &lbc->mcmr;
100                 break;
101         default:
102                 return -EINVAL;
103         }
104
105         switch (br & BR_PS) {
106         case BR_PS_8:
107                 upm->width = 8;
108                 break;
109         case BR_PS_16:
110                 upm->width = 16;
111                 break;
112         case BR_PS_32:
113                 upm->width = 32;
114                 break;
115         default:
116                 return -EINVAL;
117         }
118
119         return 0;
120 }
121 EXPORT_SYMBOL(fsl_upm_find);
122
123 /**
124  * fsl_upm_run_pattern - actually run an UPM pattern
125  * @upm:        pointer to the fsl_upm structure obtained via fsl_upm_find
126  * @io_base:    remapped pointer to where memory access should happen
127  * @mar:        MAR register content during pattern execution
128  *
129  * This function triggers dummy write to the memory specified by the io_base,
130  * thus UPM pattern actually executed. Note that mar usage depends on the
131  * pre-programmed AMX bits in the UPM RAM.
132  */
133 int fsl_upm_run_pattern(struct fsl_upm *upm, void __iomem *io_base, u32 mar)
134 {
135         int ret = 0;
136         unsigned long flags;
137
138         if (!fsl_lbc_ctrl_dev || !fsl_lbc_ctrl_dev->regs)
139                 return -ENODEV;
140
141         spin_lock_irqsave(&fsl_lbc_lock, flags);
142
143         out_be32(&fsl_lbc_ctrl_dev->regs->mar, mar);
144
145         switch (upm->width) {
146         case 8:
147                 out_8(io_base, 0x0);
148                 break;
149         case 16:
150                 out_be16(io_base, 0x0);
151                 break;
152         case 32:
153                 out_be32(io_base, 0x0);
154                 break;
155         default:
156                 ret = -EINVAL;
157                 break;
158         }
159
160         spin_unlock_irqrestore(&fsl_lbc_lock, flags);
161
162         return ret;
163 }
164 EXPORT_SYMBOL(fsl_upm_run_pattern);
165
166 static int __devinit fsl_lbc_ctrl_init(struct fsl_lbc_ctrl *ctrl)
167 {
168         struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
169
170         /* clear event registers */
171         setbits32(&lbc->ltesr, LTESR_CLEAR);
172         out_be32(&lbc->lteatr, 0);
173         out_be32(&lbc->ltear, 0);
174         out_be32(&lbc->lteccr, LTECCR_CLEAR);
175         out_be32(&lbc->ltedr, LTEDR_ENABLE);
176
177         /* Enable interrupts for any detected events */
178         out_be32(&lbc->lteir, LTEIR_ENABLE);
179
180         return 0;
181 }
182
183 /*
184  * NOTE: This interrupt is used to report localbus events of various kinds,
185  * such as transaction errors on the chipselects.
186  */
187
188 static irqreturn_t fsl_lbc_ctrl_irq(int irqno, void *data)
189 {
190         struct fsl_lbc_ctrl *ctrl = data;
191         struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
192         u32 status;
193
194         status = in_be32(&lbc->ltesr);
195         if (!status)
196                 return IRQ_NONE;
197
198         out_be32(&lbc->ltesr, LTESR_CLEAR);
199         out_be32(&lbc->lteatr, 0);
200         out_be32(&lbc->ltear, 0);
201         ctrl->irq_status = status;
202
203         if (status & LTESR_BM)
204                 dev_err(ctrl->dev, "Local bus monitor time-out: "
205                         "LTESR 0x%08X\n", status);
206         if (status & LTESR_WP)
207                 dev_err(ctrl->dev, "Write protect error: "
208                         "LTESR 0x%08X\n", status);
209         if (status & LTESR_ATMW)
210                 dev_err(ctrl->dev, "Atomic write error: "
211                         "LTESR 0x%08X\n", status);
212         if (status & LTESR_ATMR)
213                 dev_err(ctrl->dev, "Atomic read error: "
214                         "LTESR 0x%08X\n", status);
215         if (status & LTESR_CS)
216                 dev_err(ctrl->dev, "Chip select error: "
217                         "LTESR 0x%08X\n", status);
218         if (status & LTESR_UPM)
219                 ;
220         if (status & LTESR_FCT) {
221                 dev_err(ctrl->dev, "FCM command time-out: "
222                         "LTESR 0x%08X\n", status);
223                 smp_wmb();
224                 wake_up(&ctrl->irq_wait);
225         }
226         if (status & LTESR_PAR) {
227                 dev_err(ctrl->dev, "Parity or Uncorrectable ECC error: "
228                         "LTESR 0x%08X\n", status);
229                 smp_wmb();
230                 wake_up(&ctrl->irq_wait);
231         }
232         if (status & LTESR_CC) {
233                 smp_wmb();
234                 wake_up(&ctrl->irq_wait);
235         }
236         if (status & ~LTESR_MASK)
237                 dev_err(ctrl->dev, "Unknown error: "
238                         "LTESR 0x%08X\n", status);
239         return IRQ_HANDLED;
240 }
241
242 /*
243  * fsl_lbc_ctrl_probe
244  *
245  * called by device layer when it finds a device matching
246  * one our driver can handled. This code allocates all of
247  * the resources needed for the controller only.  The
248  * resources for the NAND banks themselves are allocated
249  * in the chip probe function.
250 */
251
252 static int __devinit fsl_lbc_ctrl_probe(struct platform_device *dev)
253 {
254         int ret;
255
256         if (!dev->dev.of_node) {
257                 dev_err(&dev->dev, "Device OF-Node is NULL");
258                 return -EFAULT;
259         }
260
261         fsl_lbc_ctrl_dev = kzalloc(sizeof(*fsl_lbc_ctrl_dev), GFP_KERNEL);
262         if (!fsl_lbc_ctrl_dev)
263                 return -ENOMEM;
264
265         dev_set_drvdata(&dev->dev, fsl_lbc_ctrl_dev);
266
267         spin_lock_init(&fsl_lbc_ctrl_dev->lock);
268         init_waitqueue_head(&fsl_lbc_ctrl_dev->irq_wait);
269
270         fsl_lbc_ctrl_dev->regs = of_iomap(dev->dev.of_node, 0);
271         if (!fsl_lbc_ctrl_dev->regs) {
272                 dev_err(&dev->dev, "failed to get memory region\n");
273                 ret = -ENODEV;
274                 goto err;
275         }
276
277         fsl_lbc_ctrl_dev->irq = irq_of_parse_and_map(dev->dev.of_node, 0);
278         if (fsl_lbc_ctrl_dev->irq == NO_IRQ) {
279                 dev_err(&dev->dev, "failed to get irq resource\n");
280                 ret = -ENODEV;
281                 goto err;
282         }
283
284         fsl_lbc_ctrl_dev->dev = &dev->dev;
285
286         ret = fsl_lbc_ctrl_init(fsl_lbc_ctrl_dev);
287         if (ret < 0)
288                 goto err;
289
290         ret = request_irq(fsl_lbc_ctrl_dev->irq, fsl_lbc_ctrl_irq, 0,
291                                 "fsl-lbc", fsl_lbc_ctrl_dev);
292         if (ret != 0) {
293                 dev_err(&dev->dev, "failed to install irq (%d)\n",
294                         fsl_lbc_ctrl_dev->irq);
295                 ret = fsl_lbc_ctrl_dev->irq;
296                 goto err;
297         }
298
299         return 0;
300
301 err:
302         iounmap(fsl_lbc_ctrl_dev->regs);
303         kfree(fsl_lbc_ctrl_dev);
304         return ret;
305 }
306
307 static const struct of_device_id fsl_lbc_match[] = {
308         { .compatible = "fsl,elbc", },
309         { .compatible = "fsl,pq3-localbus", },
310         { .compatible = "fsl,pq2-localbus", },
311         { .compatible = "fsl,pq2pro-localbus", },
312         {},
313 };
314
315 static struct platform_driver fsl_lbc_ctrl_driver = {
316         .driver = {
317                 .name = "fsl-lbc",
318                 .of_match_table = fsl_lbc_match,
319         },
320         .probe = fsl_lbc_ctrl_probe,
321 };
322
323 static int __init fsl_lbc_init(void)
324 {
325         return platform_driver_register(&fsl_lbc_ctrl_driver);
326 }
327 module_init(fsl_lbc_init);