Staging: vme: Use dev_err rather than printk
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / staging / vme / bridges / vme_tsi148.c
CommitLineData
d22b8ed9
MW
1/*
2 * Support for the Tundra TSI148 VME-PCI Bridge Chip
3 *
66bd8db5
MW
4 * Author: Martyn Welch <martyn.welch@ge.com>
5 * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc.
d22b8ed9
MW
6 *
7 * Based on work by Tom Armistead and Ajit Prem
8 * Copyright 2004 Motorola Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 */
15
d22b8ed9
MW
16#include <linux/module.h>
17#include <linux/moduleparam.h>
18#include <linux/mm.h>
19#include <linux/types.h>
20#include <linux/errno.h>
21#include <linux/proc_fs.h>
22#include <linux/pci.h>
23#include <linux/poll.h>
24#include <linux/dma-mapping.h>
25#include <linux/interrupt.h>
26#include <linux/spinlock.h>
6af783c8 27#include <linux/sched.h>
5a0e3ad6 28#include <linux/slab.h>
d22b8ed9
MW
29#include <asm/time.h>
30#include <asm/io.h>
31#include <asm/uaccess.h>
32
33#include "../vme.h"
34#include "../vme_bridge.h"
35#include "vme_tsi148.h"
36
37static int __init tsi148_init(void);
38static int tsi148_probe(struct pci_dev *, const struct pci_device_id *);
39static void tsi148_remove(struct pci_dev *);
40static void __exit tsi148_exit(void);
41
42
43int tsi148_slave_set(struct vme_slave_resource *, int, unsigned long long,
44 unsigned long long, dma_addr_t, vme_address_t, vme_cycle_t);
45int tsi148_slave_get(struct vme_slave_resource *, int *, unsigned long long *,
46 unsigned long long *, dma_addr_t *, vme_address_t *, vme_cycle_t *);
47
48int tsi148_master_get(struct vme_master_resource *, int *, unsigned long long *,
49 unsigned long long *, vme_address_t *, vme_cycle_t *, vme_width_t *);
50int tsi148_master_set(struct vme_master_resource *, int, unsigned long long,
51 unsigned long long, vme_address_t, vme_cycle_t, vme_width_t);
52ssize_t tsi148_master_read(struct vme_master_resource *, void *, size_t,
53 loff_t);
54ssize_t tsi148_master_write(struct vme_master_resource *, void *, size_t,
55 loff_t);
56unsigned int tsi148_master_rmw(struct vme_master_resource *, unsigned int,
57 unsigned int, unsigned int, loff_t);
58int tsi148_dma_list_add (struct vme_dma_list *, struct vme_dma_attr *,
59 struct vme_dma_attr *, size_t);
60int tsi148_dma_list_exec(struct vme_dma_list *);
61int tsi148_dma_list_empty(struct vme_dma_list *);
62int tsi148_generate_irq(int, int);
d22b8ed9 63
29848ac9 64/* Module parameter */
42d4eff7 65static int err_chk;
638f199d 66static int geoid;
d22b8ed9 67
d22b8ed9
MW
68static char driver_name[] = "vme_tsi148";
69
13ac58da 70static const struct pci_device_id tsi148_ids[] = {
d22b8ed9
MW
71 { PCI_DEVICE(PCI_VENDOR_ID_TUNDRA, PCI_DEVICE_ID_TUNDRA_TSI148) },
72 { },
73};
74
75static struct pci_driver tsi148_driver = {
76 .name = driver_name,
77 .id_table = tsi148_ids,
78 .probe = tsi148_probe,
79 .remove = tsi148_remove,
80};
81
82static void reg_join(unsigned int high, unsigned int low,
83 unsigned long long *variable)
84{
85 *variable = (unsigned long long)high << 32;
86 *variable |= (unsigned long long)low;
87}
88
89static void reg_split(unsigned long long variable, unsigned int *high,
90 unsigned int *low)
91{
92 *low = (unsigned int)variable & 0xFFFFFFFF;
93 *high = (unsigned int)(variable >> 32);
94}
95
96/*
97 * Wakes up DMA queue.
98 */
29848ac9
MW
99static u32 tsi148_DMA_irqhandler(struct tsi148_driver *bridge,
100 int channel_mask)
d22b8ed9
MW
101{
102 u32 serviced = 0;
103
104 if (channel_mask & TSI148_LCSR_INTS_DMA0S) {
29848ac9 105 wake_up(&(bridge->dma_queue[0]));
d22b8ed9
MW
106 serviced |= TSI148_LCSR_INTC_DMA0C;
107 }
108 if (channel_mask & TSI148_LCSR_INTS_DMA1S) {
29848ac9 109 wake_up(&(bridge->dma_queue[1]));
d22b8ed9
MW
110 serviced |= TSI148_LCSR_INTC_DMA1C;
111 }
112
113 return serviced;
114}
115
116/*
117 * Wake up location monitor queue
118 */
29848ac9 119static u32 tsi148_LM_irqhandler(struct tsi148_driver *bridge, u32 stat)
d22b8ed9
MW
120{
121 int i;
122 u32 serviced = 0;
123
124 for (i = 0; i < 4; i++) {
125 if(stat & TSI148_LCSR_INTS_LMS[i]) {
126 /* We only enable interrupts if the callback is set */
29848ac9 127 bridge->lm_callback[i](i);
d22b8ed9
MW
128 serviced |= TSI148_LCSR_INTC_LMC[i];
129 }
130 }
131
132 return serviced;
133}
134
135/*
136 * Wake up mail box queue.
137 *
138 * XXX This functionality is not exposed up though API.
139 */
48d9356e 140static u32 tsi148_MB_irqhandler(struct vme_bridge *tsi148_bridge, u32 stat)
d22b8ed9
MW
141{
142 int i;
143 u32 val;
144 u32 serviced = 0;
48d9356e
MW
145 struct tsi148_driver *bridge;
146
147 bridge = tsi148_bridge->driver_priv;
d22b8ed9
MW
148
149 for (i = 0; i < 4; i++) {
150 if(stat & TSI148_LCSR_INTS_MBS[i]) {
29848ac9 151 val = ioread32be(bridge->base + TSI148_GCSR_MBOX[i]);
48d9356e
MW
152 dev_err(tsi148_bridge->parent, "VME Mailbox %d received"
153 ": 0x%x\n", i, val);
d22b8ed9
MW
154 serviced |= TSI148_LCSR_INTC_MBC[i];
155 }
156 }
157
158 return serviced;
159}
160
161/*
162 * Display error & status message when PERR (PCI) exception interrupt occurs.
163 */
48d9356e 164static u32 tsi148_PERR_irqhandler(struct vme_bridge *tsi148_bridge)
d22b8ed9 165{
48d9356e
MW
166 struct tsi148_driver *bridge;
167
168 bridge = tsi148_bridge->driver_priv;
169
170 dev_err(tsi148_bridge->parent, "PCI Exception at address: 0x%08x:%08x, "
171 "attributes: %08x\n",
29848ac9
MW
172 ioread32be(bridge->base + TSI148_LCSR_EDPAU),
173 ioread32be(bridge->base + TSI148_LCSR_EDPAL),
48d9356e
MW
174 ioread32be(bridge->base + TSI148_LCSR_EDPAT));
175
176 dev_err(tsi148_bridge->parent, "PCI-X attribute reg: %08x, PCI-X split "
177 "completion reg: %08x\n",
29848ac9 178 ioread32be(bridge->base + TSI148_LCSR_EDPXA),
48d9356e 179 ioread32be(bridge->base + TSI148_LCSR_EDPXS));
d22b8ed9 180
29848ac9 181 iowrite32be(TSI148_LCSR_EDPAT_EDPCL, bridge->base + TSI148_LCSR_EDPAT);
d22b8ed9
MW
182
183 return TSI148_LCSR_INTC_PERRC;
184}
185
186/*
187 * Save address and status when VME error interrupt occurs.
188 */
29848ac9 189static u32 tsi148_VERR_irqhandler(struct vme_bridge *tsi148_bridge)
d22b8ed9
MW
190{
191 unsigned int error_addr_high, error_addr_low;
192 unsigned long long error_addr;
193 u32 error_attrib;
194 struct vme_bus_error *error;
29848ac9
MW
195 struct tsi148_driver *bridge;
196
197 bridge = tsi148_bridge->driver_priv;
d22b8ed9 198
29848ac9
MW
199 error_addr_high = ioread32be(bridge->base + TSI148_LCSR_VEAU);
200 error_addr_low = ioread32be(bridge->base + TSI148_LCSR_VEAL);
201 error_attrib = ioread32be(bridge->base + TSI148_LCSR_VEAT);
d22b8ed9
MW
202
203 reg_join(error_addr_high, error_addr_low, &error_addr);
204
205 /* Check for exception register overflow (we have lost error data) */
206 if(error_attrib & TSI148_LCSR_VEAT_VEOF) {
48d9356e
MW
207 dev_err(tsi148_bridge->parent, "VME Bus Exception Overflow "
208 "Occurred\n");
d22b8ed9
MW
209 }
210
211 error = (struct vme_bus_error *)kmalloc(sizeof (struct vme_bus_error),
212 GFP_ATOMIC);
213 if (error) {
214 error->address = error_addr;
215 error->attributes = error_attrib;
216 list_add_tail(&(error->list), &(tsi148_bridge->vme_errors));
217 } else {
48d9356e
MW
218 dev_err(tsi148_bridge->parent, "Unable to alloc memory for "
219 "VMEbus Error reporting\n");
220 dev_err(tsi148_bridge->parent, "VME Bus Error at address: "
221 "0x%llx, attributes: %08x\n", error_addr, error_attrib);
d22b8ed9
MW
222 }
223
224 /* Clear Status */
29848ac9 225 iowrite32be(TSI148_LCSR_VEAT_VESCL, bridge->base + TSI148_LCSR_VEAT);
d22b8ed9
MW
226
227 return TSI148_LCSR_INTC_VERRC;
228}
229
230/*
231 * Wake up IACK queue.
232 */
29848ac9 233static u32 tsi148_IACK_irqhandler(struct tsi148_driver *bridge)
d22b8ed9 234{
29848ac9 235 wake_up(&(bridge->iack_queue));
d22b8ed9
MW
236
237 return TSI148_LCSR_INTC_IACKC;
238}
239
240/*
241 * Calling VME bus interrupt callback if provided.
242 */
29848ac9
MW
243static u32 tsi148_VIRQ_irqhandler(struct vme_bridge *tsi148_bridge,
244 u32 stat)
d22b8ed9
MW
245{
246 int vec, i, serviced = 0;
29848ac9
MW
247 struct tsi148_driver *bridge;
248
249 bridge = tsi148_bridge->driver_priv;
d22b8ed9
MW
250
251 for (i = 7; i > 0; i--) {
252 if (stat & (1 << i)) {
253 /*
254 * Note: Even though the registers are defined
255 * as 32-bits in the spec, we only want to issue
256 * 8-bit IACK cycles on the bus, read from offset
257 * 3.
258 */
29848ac9 259 vec = ioread8(bridge->base + TSI148_LCSR_VIACK[i] + 3);
d22b8ed9 260
c813f592 261 vme_irq_handler(tsi148_bridge, i, vec);
d22b8ed9
MW
262
263 serviced |= (1 << i);
264 }
265 }
266
267 return serviced;
268}
269
270/*
271 * Top level interrupt handler. Clears appropriate interrupt status bits and
272 * then calls appropriate sub handler(s).
273 */
29848ac9 274static irqreturn_t tsi148_irqhandler(int irq, void *ptr)
d22b8ed9
MW
275{
276 u32 stat, enable, serviced = 0;
29848ac9
MW
277 struct vme_bridge *tsi148_bridge;
278 struct tsi148_driver *bridge;
279
280 tsi148_bridge = ptr;
281
282 bridge = tsi148_bridge->driver_priv;
d22b8ed9
MW
283
284 /* Determine which interrupts are unmasked and set */
29848ac9
MW
285 enable = ioread32be(bridge->base + TSI148_LCSR_INTEO);
286 stat = ioread32be(bridge->base + TSI148_LCSR_INTS);
d22b8ed9
MW
287
288 /* Only look at unmasked interrupts */
289 stat &= enable;
290
291 if (unlikely(!stat)) {
292 return IRQ_NONE;
293 }
294
295 /* Call subhandlers as appropriate */
296 /* DMA irqs */
297 if (stat & (TSI148_LCSR_INTS_DMA1S | TSI148_LCSR_INTS_DMA0S))
29848ac9 298 serviced |= tsi148_DMA_irqhandler(bridge, stat);
d22b8ed9
MW
299
300 /* Location monitor irqs */
301 if (stat & (TSI148_LCSR_INTS_LM3S | TSI148_LCSR_INTS_LM2S |
302 TSI148_LCSR_INTS_LM1S | TSI148_LCSR_INTS_LM0S))
29848ac9 303 serviced |= tsi148_LM_irqhandler(bridge, stat);
d22b8ed9
MW
304
305 /* Mail box irqs */
306 if (stat & (TSI148_LCSR_INTS_MB3S | TSI148_LCSR_INTS_MB2S |
307 TSI148_LCSR_INTS_MB1S | TSI148_LCSR_INTS_MB0S))
48d9356e 308 serviced |= tsi148_MB_irqhandler(tsi148_bridge, stat);
d22b8ed9
MW
309
310 /* PCI bus error */
311 if (stat & TSI148_LCSR_INTS_PERRS)
48d9356e 312 serviced |= tsi148_PERR_irqhandler(tsi148_bridge);
d22b8ed9
MW
313
314 /* VME bus error */
315 if (stat & TSI148_LCSR_INTS_VERRS)
29848ac9 316 serviced |= tsi148_VERR_irqhandler(tsi148_bridge);
d22b8ed9
MW
317
318 /* IACK irq */
319 if (stat & TSI148_LCSR_INTS_IACKS)
29848ac9 320 serviced |= tsi148_IACK_irqhandler(bridge);
d22b8ed9
MW
321
322 /* VME bus irqs */
323 if (stat & (TSI148_LCSR_INTS_IRQ7S | TSI148_LCSR_INTS_IRQ6S |
324 TSI148_LCSR_INTS_IRQ5S | TSI148_LCSR_INTS_IRQ4S |
325 TSI148_LCSR_INTS_IRQ3S | TSI148_LCSR_INTS_IRQ2S |
326 TSI148_LCSR_INTS_IRQ1S))
29848ac9 327 serviced |= tsi148_VIRQ_irqhandler(tsi148_bridge, stat);
d22b8ed9
MW
328
329 /* Clear serviced interrupts */
29848ac9 330 iowrite32be(serviced, bridge->base + TSI148_LCSR_INTC);
d22b8ed9
MW
331
332 return IRQ_HANDLED;
333}
334
29848ac9 335static int tsi148_irq_init(struct vme_bridge *tsi148_bridge)
d22b8ed9
MW
336{
337 int result;
338 unsigned int tmp;
339 struct pci_dev *pdev;
29848ac9
MW
340 struct tsi148_driver *bridge;
341
342 pdev = container_of(tsi148_bridge->parent, struct pci_dev, dev);
d22b8ed9 343
29848ac9 344 bridge = tsi148_bridge->driver_priv;
d22b8ed9
MW
345
346 /* Initialise list for VME bus errors */
29848ac9 347 INIT_LIST_HEAD(&(tsi148_bridge->vme_errors));
d22b8ed9 348
29848ac9 349 mutex_init(&(tsi148_bridge->irq_mtx));
c813f592 350
d22b8ed9
MW
351 result = request_irq(pdev->irq,
352 tsi148_irqhandler,
353 IRQF_SHARED,
29848ac9 354 driver_name, tsi148_bridge);
d22b8ed9 355 if (result) {
48d9356e
MW
356 dev_err(tsi148_bridge->parent, "Can't get assigned pci irq "
357 "vector %02X\n", pdev->irq);
d22b8ed9
MW
358 return result;
359 }
360
361 /* Enable and unmask interrupts */
362 tmp = TSI148_LCSR_INTEO_DMA1EO | TSI148_LCSR_INTEO_DMA0EO |
363 TSI148_LCSR_INTEO_MB3EO | TSI148_LCSR_INTEO_MB2EO |
364 TSI148_LCSR_INTEO_MB1EO | TSI148_LCSR_INTEO_MB0EO |
365 TSI148_LCSR_INTEO_PERREO | TSI148_LCSR_INTEO_VERREO |
366 TSI148_LCSR_INTEO_IACKEO;
367
29848ac9 368 /* This leaves the following interrupts masked.
d22b8ed9
MW
369 * TSI148_LCSR_INTEO_VIEEO
370 * TSI148_LCSR_INTEO_SYSFLEO
371 * TSI148_LCSR_INTEO_ACFLEO
372 */
373
374 /* Don't enable Location Monitor interrupts here - they will be
375 * enabled when the location monitors are properly configured and
376 * a callback has been attached.
377 * TSI148_LCSR_INTEO_LM0EO
378 * TSI148_LCSR_INTEO_LM1EO
379 * TSI148_LCSR_INTEO_LM2EO
380 * TSI148_LCSR_INTEO_LM3EO
381 */
382
383 /* Don't enable VME interrupts until we add a handler, else the board
384 * will respond to it and we don't want that unless it knows how to
385 * properly deal with it.
386 * TSI148_LCSR_INTEO_IRQ7EO
387 * TSI148_LCSR_INTEO_IRQ6EO
388 * TSI148_LCSR_INTEO_IRQ5EO
389 * TSI148_LCSR_INTEO_IRQ4EO
390 * TSI148_LCSR_INTEO_IRQ3EO
391 * TSI148_LCSR_INTEO_IRQ2EO
392 * TSI148_LCSR_INTEO_IRQ1EO
393 */
394
395 iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEO);
396 iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEN);
397
398 return 0;
399}
400
29848ac9 401static void tsi148_irq_exit(struct tsi148_driver *bridge, struct pci_dev *pdev)
d22b8ed9
MW
402{
403 /* Turn off interrupts */
29848ac9
MW
404 iowrite32be(0x0, bridge->base + TSI148_LCSR_INTEO);
405 iowrite32be(0x0, bridge->base + TSI148_LCSR_INTEN);
d22b8ed9
MW
406
407 /* Clear all interrupts */
29848ac9 408 iowrite32be(0xFFFFFFFF, bridge->base + TSI148_LCSR_INTC);
d22b8ed9
MW
409
410 /* Detach interrupt handler */
411 free_irq(pdev->irq, pdev);
412}
413
414/*
415 * Check to see if an IACk has been received, return true (1) or false (0).
416 */
29848ac9 417int tsi148_iack_received(struct tsi148_driver *bridge)
d22b8ed9
MW
418{
419 u32 tmp;
420
29848ac9 421 tmp = ioread32be(bridge->base + TSI148_LCSR_VICR);
d22b8ed9
MW
422
423 if (tmp & TSI148_LCSR_VICR_IRQS)
424 return 0;
425 else
426 return 1;
427}
428
429/*
c813f592 430 * Configure VME interrupt
d22b8ed9 431 */
29848ac9
MW
432void tsi148_irq_set(struct vme_bridge *tsi148_bridge, int level,
433 int state, int sync)
d22b8ed9 434{
75155020 435 struct pci_dev *pdev;
c813f592 436 u32 tmp;
29848ac9
MW
437 struct tsi148_driver *bridge;
438
439 bridge = tsi148_bridge->driver_priv;
d22b8ed9 440
c813f592
MW
441 /* We need to do the ordering differently for enabling and disabling */
442 if (state == 0) {
29848ac9 443 tmp = ioread32be(bridge->base + TSI148_LCSR_INTEN);
d22b8ed9 444 tmp &= ~TSI148_LCSR_INTEN_IRQEN[level - 1];
29848ac9 445 iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEN);
df455175 446
29848ac9 447 tmp = ioread32be(bridge->base + TSI148_LCSR_INTEO);
df455175 448 tmp &= ~TSI148_LCSR_INTEO_IRQEO[level - 1];
29848ac9 449 iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEO);
75155020 450
c813f592
MW
451 if (sync != 0) {
452 pdev = container_of(tsi148_bridge->parent,
453 struct pci_dev, dev);
75155020 454
c813f592
MW
455 synchronize_irq(pdev->irq);
456 }
457 } else {
29848ac9 458 tmp = ioread32be(bridge->base + TSI148_LCSR_INTEO);
c813f592 459 tmp |= TSI148_LCSR_INTEO_IRQEO[level - 1];
29848ac9 460 iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEO);
df455175 461
29848ac9 462 tmp = ioread32be(bridge->base + TSI148_LCSR_INTEN);
c813f592 463 tmp |= TSI148_LCSR_INTEN_IRQEN[level - 1];
29848ac9 464 iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEN);
c813f592 465 }
d22b8ed9
MW
466}
467
468/*
469 * Generate a VME bus interrupt at the requested level & vector. Wait for
470 * interrupt to be acked.
d22b8ed9 471 */
29848ac9 472int tsi148_irq_generate(struct vme_bridge *tsi148_bridge, int level, int statid)
d22b8ed9
MW
473{
474 u32 tmp;
29848ac9
MW
475 struct tsi148_driver *bridge;
476
477 bridge = tsi148_bridge->driver_priv;
d22b8ed9 478
29848ac9 479 mutex_lock(&(bridge->vme_int));
d22b8ed9
MW
480
481 /* Read VICR register */
29848ac9 482 tmp = ioread32be(bridge->base + TSI148_LCSR_VICR);
d22b8ed9
MW
483
484 /* Set Status/ID */
485 tmp = (tmp & ~TSI148_LCSR_VICR_STID_M) |
486 (statid & TSI148_LCSR_VICR_STID_M);
29848ac9 487 iowrite32be(tmp, bridge->base + TSI148_LCSR_VICR);
d22b8ed9
MW
488
489 /* Assert VMEbus IRQ */
490 tmp = tmp | TSI148_LCSR_VICR_IRQL[level];
29848ac9 491 iowrite32be(tmp, bridge->base + TSI148_LCSR_VICR);
d22b8ed9
MW
492
493 /* XXX Consider implementing a timeout? */
29848ac9
MW
494 wait_event_interruptible(bridge->iack_queue,
495 tsi148_iack_received(bridge));
d22b8ed9 496
29848ac9 497 mutex_unlock(&(bridge->vme_int));
d22b8ed9
MW
498
499 return 0;
500}
501
502/*
503 * Find the first error in this address range
504 */
29848ac9
MW
505static struct vme_bus_error *tsi148_find_error(struct vme_bridge *tsi148_bridge,
506 vme_address_t aspace, unsigned long long address, size_t count)
d22b8ed9
MW
507{
508 struct list_head *err_pos;
509 struct vme_bus_error *vme_err, *valid = NULL;
510 unsigned long long bound;
511
512 bound = address + count;
513
514 /*
515 * XXX We are currently not looking at the address space when parsing
516 * for errors. This is because parsing the Address Modifier Codes
517 * is going to be quite resource intensive to do properly. We
518 * should be OK just looking at the addresses and this is certainly
519 * much better than what we had before.
520 */
521 err_pos = NULL;
522 /* Iterate through errors */
523 list_for_each(err_pos, &(tsi148_bridge->vme_errors)) {
524 vme_err = list_entry(err_pos, struct vme_bus_error, list);
525 if((vme_err->address >= address) && (vme_err->address < bound)){
526 valid = vme_err;
527 break;
528 }
529 }
530
531 return valid;
532}
533
534/*
535 * Clear errors in the provided address range.
536 */
29848ac9
MW
537static void tsi148_clear_errors(struct vme_bridge *tsi148_bridge,
538 vme_address_t aspace, unsigned long long address, size_t count)
d22b8ed9
MW
539{
540 struct list_head *err_pos, *temp;
541 struct vme_bus_error *vme_err;
542 unsigned long long bound;
543
544 bound = address + count;
545
546 /*
547 * XXX We are currently not looking at the address space when parsing
548 * for errors. This is because parsing the Address Modifier Codes
549 * is going to be quite resource intensive to do properly. We
550 * should be OK just looking at the addresses and this is certainly
551 * much better than what we had before.
552 */
553 err_pos = NULL;
554 /* Iterate through errors */
555 list_for_each_safe(err_pos, temp, &(tsi148_bridge->vme_errors)) {
556 vme_err = list_entry(err_pos, struct vme_bus_error, list);
557
558 if((vme_err->address >= address) && (vme_err->address < bound)){
559 list_del(err_pos);
560 kfree(vme_err);
561 }
562 }
563}
564
565/*
566 * Initialize a slave window with the requested attributes.
567 */
568int tsi148_slave_set(struct vme_slave_resource *image, int enabled,
569 unsigned long long vme_base, unsigned long long size,
570 dma_addr_t pci_base, vme_address_t aspace, vme_cycle_t cycle)
571{
572 unsigned int i, addr = 0, granularity = 0;
573 unsigned int temp_ctl = 0;
574 unsigned int vme_base_low, vme_base_high;
575 unsigned int vme_bound_low, vme_bound_high;
576 unsigned int pci_offset_low, pci_offset_high;
577 unsigned long long vme_bound, pci_offset;
48d9356e 578 struct vme_bridge *tsi148_bridge;
29848ac9
MW
579 struct tsi148_driver *bridge;
580
48d9356e
MW
581 tsi148_bridge = image->parent;
582 bridge = tsi148_bridge->driver_priv;
d22b8ed9 583
d22b8ed9
MW
584 i = image->number;
585
586 switch (aspace) {
587 case VME_A16:
588 granularity = 0x10;
589 addr |= TSI148_LCSR_ITAT_AS_A16;
590 break;
591 case VME_A24:
592 granularity = 0x1000;
593 addr |= TSI148_LCSR_ITAT_AS_A24;
594 break;
595 case VME_A32:
596 granularity = 0x10000;
597 addr |= TSI148_LCSR_ITAT_AS_A32;
598 break;
599 case VME_A64:
600 granularity = 0x10000;
601 addr |= TSI148_LCSR_ITAT_AS_A64;
602 break;
603 case VME_CRCSR:
604 case VME_USER1:
605 case VME_USER2:
606 case VME_USER3:
607 case VME_USER4:
608 default:
48d9356e 609 dev_err(tsi148_bridge->parent, "Invalid address space\n");
d22b8ed9
MW
610 return -EINVAL;
611 break;
612 }
613
614 /* Convert 64-bit variables to 2x 32-bit variables */
615 reg_split(vme_base, &vme_base_high, &vme_base_low);
616
617 /*
618 * Bound address is a valid address for the window, adjust
619 * accordingly
620 */
621 vme_bound = vme_base + size - granularity;
622 reg_split(vme_bound, &vme_bound_high, &vme_bound_low);
623 pci_offset = (unsigned long long)pci_base - vme_base;
624 reg_split(pci_offset, &pci_offset_high, &pci_offset_low);
625
626 if (vme_base_low & (granularity - 1)) {
48d9356e 627 dev_err(tsi148_bridge->parent, "Invalid VME base alignment\n");
d22b8ed9
MW
628 return -EINVAL;
629 }
630 if (vme_bound_low & (granularity - 1)) {
48d9356e 631 dev_err(tsi148_bridge->parent, "Invalid VME bound alignment\n");
d22b8ed9
MW
632 return -EINVAL;
633 }
634 if (pci_offset_low & (granularity - 1)) {
48d9356e
MW
635 dev_err(tsi148_bridge->parent, "Invalid PCI Offset "
636 "alignment\n");
d22b8ed9
MW
637 return -EINVAL;
638 }
639
d22b8ed9 640 /* Disable while we are mucking around */
29848ac9 641 temp_ctl = ioread32be(bridge->base + TSI148_LCSR_IT[i] +
d22b8ed9
MW
642 TSI148_LCSR_OFFSET_ITAT);
643 temp_ctl &= ~TSI148_LCSR_ITAT_EN;
29848ac9 644 iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_IT[i] +
d22b8ed9
MW
645 TSI148_LCSR_OFFSET_ITAT);
646
647 /* Setup mapping */
29848ac9 648 iowrite32be(vme_base_high, bridge->base + TSI148_LCSR_IT[i] +
d22b8ed9 649 TSI148_LCSR_OFFSET_ITSAU);
29848ac9 650 iowrite32be(vme_base_low, bridge->base + TSI148_LCSR_IT[i] +
d22b8ed9 651 TSI148_LCSR_OFFSET_ITSAL);
29848ac9 652 iowrite32be(vme_bound_high, bridge->base + TSI148_LCSR_IT[i] +
d22b8ed9 653 TSI148_LCSR_OFFSET_ITEAU);
29848ac9 654 iowrite32be(vme_bound_low, bridge->base + TSI148_LCSR_IT[i] +
d22b8ed9 655 TSI148_LCSR_OFFSET_ITEAL);
29848ac9 656 iowrite32be(pci_offset_high, bridge->base + TSI148_LCSR_IT[i] +
d22b8ed9 657 TSI148_LCSR_OFFSET_ITOFU);
29848ac9 658 iowrite32be(pci_offset_low, bridge->base + TSI148_LCSR_IT[i] +
d22b8ed9
MW
659 TSI148_LCSR_OFFSET_ITOFL);
660
d22b8ed9
MW
661 /* Setup 2eSST speeds */
662 temp_ctl &= ~TSI148_LCSR_ITAT_2eSSTM_M;
663 switch (cycle & (VME_2eSST160 | VME_2eSST267 | VME_2eSST320)) {
664 case VME_2eSST160:
665 temp_ctl |= TSI148_LCSR_ITAT_2eSSTM_160;
666 break;
667 case VME_2eSST267:
668 temp_ctl |= TSI148_LCSR_ITAT_2eSSTM_267;
669 break;
670 case VME_2eSST320:
671 temp_ctl |= TSI148_LCSR_ITAT_2eSSTM_320;
672 break;
673 }
674
675 /* Setup cycle types */
676 temp_ctl &= ~(0x1F << 7);
677 if (cycle & VME_BLT)
678 temp_ctl |= TSI148_LCSR_ITAT_BLT;
679 if (cycle & VME_MBLT)
680 temp_ctl |= TSI148_LCSR_ITAT_MBLT;
681 if (cycle & VME_2eVME)
682 temp_ctl |= TSI148_LCSR_ITAT_2eVME;
683 if (cycle & VME_2eSST)
684 temp_ctl |= TSI148_LCSR_ITAT_2eSST;
685 if (cycle & VME_2eSSTB)
686 temp_ctl |= TSI148_LCSR_ITAT_2eSSTB;
687
688 /* Setup address space */
689 temp_ctl &= ~TSI148_LCSR_ITAT_AS_M;
690 temp_ctl |= addr;
691
692 temp_ctl &= ~0xF;
693 if (cycle & VME_SUPER)
694 temp_ctl |= TSI148_LCSR_ITAT_SUPR ;
695 if (cycle & VME_USER)
696 temp_ctl |= TSI148_LCSR_ITAT_NPRIV;
697 if (cycle & VME_PROG)
698 temp_ctl |= TSI148_LCSR_ITAT_PGM;
699 if (cycle & VME_DATA)
700 temp_ctl |= TSI148_LCSR_ITAT_DATA;
701
702 /* Write ctl reg without enable */
29848ac9 703 iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_IT[i] +
d22b8ed9
MW
704 TSI148_LCSR_OFFSET_ITAT);
705
706 if (enabled)
707 temp_ctl |= TSI148_LCSR_ITAT_EN;
708
29848ac9 709 iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_IT[i] +
d22b8ed9
MW
710 TSI148_LCSR_OFFSET_ITAT);
711
712 return 0;
713}
714
715/*
716 * Get slave window configuration.
d22b8ed9
MW
717 */
718int tsi148_slave_get(struct vme_slave_resource *image, int *enabled,
719 unsigned long long *vme_base, unsigned long long *size,
720 dma_addr_t *pci_base, vme_address_t *aspace, vme_cycle_t *cycle)
721{
722 unsigned int i, granularity = 0, ctl = 0;
723 unsigned int vme_base_low, vme_base_high;
724 unsigned int vme_bound_low, vme_bound_high;
725 unsigned int pci_offset_low, pci_offset_high;
726 unsigned long long vme_bound, pci_offset;
29848ac9 727 struct tsi148_driver *bridge;
d22b8ed9 728
29848ac9 729 bridge = image->parent->driver_priv;
d22b8ed9
MW
730
731 i = image->number;
732
733 /* Read registers */
29848ac9 734 ctl = ioread32be(bridge->base + TSI148_LCSR_IT[i] +
d22b8ed9
MW
735 TSI148_LCSR_OFFSET_ITAT);
736
29848ac9 737 vme_base_high = ioread32be(bridge->base + TSI148_LCSR_IT[i] +
d22b8ed9 738 TSI148_LCSR_OFFSET_ITSAU);
29848ac9 739 vme_base_low = ioread32be(bridge->base + TSI148_LCSR_IT[i] +
d22b8ed9 740 TSI148_LCSR_OFFSET_ITSAL);
29848ac9 741 vme_bound_high = ioread32be(bridge->base + TSI148_LCSR_IT[i] +
d22b8ed9 742 TSI148_LCSR_OFFSET_ITEAU);
29848ac9 743 vme_bound_low = ioread32be(bridge->base + TSI148_LCSR_IT[i] +
d22b8ed9 744 TSI148_LCSR_OFFSET_ITEAL);
29848ac9 745 pci_offset_high = ioread32be(bridge->base + TSI148_LCSR_IT[i] +
d22b8ed9 746 TSI148_LCSR_OFFSET_ITOFU);
29848ac9 747 pci_offset_low = ioread32be(bridge->base + TSI148_LCSR_IT[i] +
d22b8ed9
MW
748 TSI148_LCSR_OFFSET_ITOFL);
749
750 /* Convert 64-bit variables to 2x 32-bit variables */
751 reg_join(vme_base_high, vme_base_low, vme_base);
752 reg_join(vme_bound_high, vme_bound_low, &vme_bound);
753 reg_join(pci_offset_high, pci_offset_low, &pci_offset);
754
755 *pci_base = (dma_addr_t)vme_base + pci_offset;
756
757 *enabled = 0;
758 *aspace = 0;
759 *cycle = 0;
760
761 if (ctl & TSI148_LCSR_ITAT_EN)
762 *enabled = 1;
763
764 if ((ctl & TSI148_LCSR_ITAT_AS_M) == TSI148_LCSR_ITAT_AS_A16) {
765 granularity = 0x10;
766 *aspace |= VME_A16;
767 }
768 if ((ctl & TSI148_LCSR_ITAT_AS_M) == TSI148_LCSR_ITAT_AS_A24) {
769 granularity = 0x1000;
770 *aspace |= VME_A24;
771 }
772 if ((ctl & TSI148_LCSR_ITAT_AS_M) == TSI148_LCSR_ITAT_AS_A32) {
773 granularity = 0x10000;
774 *aspace |= VME_A32;
775 }
776 if ((ctl & TSI148_LCSR_ITAT_AS_M) == TSI148_LCSR_ITAT_AS_A64) {
777 granularity = 0x10000;
778 *aspace |= VME_A64;
779 }
780
781 /* Need granularity before we set the size */
782 *size = (unsigned long long)((vme_bound - *vme_base) + granularity);
783
784
785 if ((ctl & TSI148_LCSR_ITAT_2eSSTM_M) == TSI148_LCSR_ITAT_2eSSTM_160)
786 *cycle |= VME_2eSST160;
787 if ((ctl & TSI148_LCSR_ITAT_2eSSTM_M) == TSI148_LCSR_ITAT_2eSSTM_267)
788 *cycle |= VME_2eSST267;
789 if ((ctl & TSI148_LCSR_ITAT_2eSSTM_M) == TSI148_LCSR_ITAT_2eSSTM_320)
790 *cycle |= VME_2eSST320;
791
792 if (ctl & TSI148_LCSR_ITAT_BLT)
793 *cycle |= VME_BLT;
794 if (ctl & TSI148_LCSR_ITAT_MBLT)
795 *cycle |= VME_MBLT;
796 if (ctl & TSI148_LCSR_ITAT_2eVME)
797 *cycle |= VME_2eVME;
798 if (ctl & TSI148_LCSR_ITAT_2eSST)
799 *cycle |= VME_2eSST;
800 if (ctl & TSI148_LCSR_ITAT_2eSSTB)
801 *cycle |= VME_2eSSTB;
802
803 if (ctl & TSI148_LCSR_ITAT_SUPR)
804 *cycle |= VME_SUPER;
805 if (ctl & TSI148_LCSR_ITAT_NPRIV)
806 *cycle |= VME_USER;
807 if (ctl & TSI148_LCSR_ITAT_PGM)
808 *cycle |= VME_PROG;
809 if (ctl & TSI148_LCSR_ITAT_DATA)
810 *cycle |= VME_DATA;
811
812 return 0;
813}
814
815/*
816 * Allocate and map PCI Resource
817 */
818static int tsi148_alloc_resource(struct vme_master_resource *image,
819 unsigned long long size)
820{
821 unsigned long long existing_size;
822 int retval = 0;
823 struct pci_dev *pdev;
29848ac9
MW
824 struct vme_bridge *tsi148_bridge;
825
826 tsi148_bridge = image->parent;
d22b8ed9 827
48d9356e 828 pdev = container_of(tsi148_bridge->parent, struct pci_dev, dev);
d22b8ed9 829
8fafb476
MW
830 existing_size = (unsigned long long)(image->bus_resource.end -
831 image->bus_resource.start);
d22b8ed9
MW
832
833 /* If the existing size is OK, return */
59c22904 834 if ((size != 0) && (existing_size == (size - 1)))
d22b8ed9
MW
835 return 0;
836
837 if (existing_size != 0) {
838 iounmap(image->kern_base);
839 image->kern_base = NULL;
8fafb476
MW
840 if (image->bus_resource.name != NULL)
841 kfree(image->bus_resource.name);
842 release_resource(&(image->bus_resource));
843 memset(&(image->bus_resource), 0, sizeof(struct resource));
d22b8ed9
MW
844 }
845
59c22904
MW
846 /* Exit here if size is zero */
847 if (size == 0) {
848 return 0;
849 }
850
8fafb476
MW
851 if (image->bus_resource.name == NULL) {
852 image->bus_resource.name = kmalloc(VMENAMSIZ+3, GFP_KERNEL);
853 if (image->bus_resource.name == NULL) {
48d9356e
MW
854 dev_err(tsi148_bridge->parent, "Unable to allocate "
855 "memory for resource name\n");
d22b8ed9
MW
856 retval = -ENOMEM;
857 goto err_name;
858 }
859 }
860
8fafb476 861 sprintf((char *)image->bus_resource.name, "%s.%d", tsi148_bridge->name,
d22b8ed9
MW
862 image->number);
863
8fafb476
MW
864 image->bus_resource.start = 0;
865 image->bus_resource.end = (unsigned long)size;
866 image->bus_resource.flags = IORESOURCE_MEM;
d22b8ed9
MW
867
868 retval = pci_bus_alloc_resource(pdev->bus,
8fafb476 869 &(image->bus_resource), size, size, PCIBIOS_MIN_MEM,
d22b8ed9
MW
870 0, NULL, NULL);
871 if (retval) {
48d9356e
MW
872 dev_err(tsi148_bridge->parent, "Failed to allocate mem "
873 "resource for window %d size 0x%lx start 0x%lx\n",
d22b8ed9 874 image->number, (unsigned long)size,
8fafb476 875 (unsigned long)image->bus_resource.start);
d22b8ed9
MW
876 goto err_resource;
877 }
878
879 image->kern_base = ioremap_nocache(
8fafb476 880 image->bus_resource.start, size);
d22b8ed9 881 if (image->kern_base == NULL) {
48d9356e 882 dev_err(tsi148_bridge->parent, "Failed to remap resource\n");
d22b8ed9
MW
883 retval = -ENOMEM;
884 goto err_remap;
885 }
886
887 return 0;
888
889 iounmap(image->kern_base);
890 image->kern_base = NULL;
891err_remap:
8fafb476 892 release_resource(&(image->bus_resource));
d22b8ed9 893err_resource:
8fafb476
MW
894 kfree(image->bus_resource.name);
895 memset(&(image->bus_resource), 0, sizeof(struct resource));
d22b8ed9
MW
896err_name:
897 return retval;
898}
899
900/*
901 * Free and unmap PCI Resource
902 */
903static void tsi148_free_resource(struct vme_master_resource *image)
904{
905 iounmap(image->kern_base);
906 image->kern_base = NULL;
8fafb476
MW
907 release_resource(&(image->bus_resource));
908 kfree(image->bus_resource.name);
909 memset(&(image->bus_resource), 0, sizeof(struct resource));
d22b8ed9
MW
910}
911
912/*
913 * Set the attributes of an outbound window.
914 */
915int tsi148_master_set( struct vme_master_resource *image, int enabled,
916 unsigned long long vme_base, unsigned long long size,
917 vme_address_t aspace, vme_cycle_t cycle, vme_width_t dwidth)
918{
919 int retval = 0;
920 unsigned int i;
921 unsigned int temp_ctl = 0;
922 unsigned int pci_base_low, pci_base_high;
923 unsigned int pci_bound_low, pci_bound_high;
924 unsigned int vme_offset_low, vme_offset_high;
925 unsigned long long pci_bound, vme_offset, pci_base;
48d9356e 926 struct vme_bridge *tsi148_bridge;
29848ac9
MW
927 struct tsi148_driver *bridge;
928
48d9356e
MW
929 tsi148_bridge = image->parent;
930
931 bridge = tsi148_bridge->driver_priv;
d22b8ed9
MW
932
933 /* Verify input data */
934 if (vme_base & 0xFFFF) {
48d9356e
MW
935 dev_err(tsi148_bridge->parent, "Invalid VME Window "
936 "alignment\n");
d22b8ed9
MW
937 retval = -EINVAL;
938 goto err_window;
939 }
59c22904
MW
940
941 if ((size == 0) && (enabled != 0)) {
48d9356e
MW
942 dev_err(tsi148_bridge->parent, "Size must be non-zero for "
943 "enabled windows\n");
d22b8ed9
MW
944 retval = -EINVAL;
945 goto err_window;
946 }
947
948 spin_lock(&(image->lock));
949
950 /* Let's allocate the resource here rather than further up the stack as
59c22904
MW
951 * it avoids pushing loads of bus dependant stuff up the stack. If size
952 * is zero, any existing resource will be freed.
d22b8ed9
MW
953 */
954 retval = tsi148_alloc_resource(image, size);
955 if (retval) {
956 spin_unlock(&(image->lock));
48d9356e 957 dev_err(tsi148_bridge->parent, "Unable to allocate memory for "
59c22904 958 "resource\n");
d22b8ed9
MW
959 goto err_res;
960 }
961
59c22904
MW
962 if (size == 0) {
963 pci_base = 0;
964 pci_bound = 0;
965 vme_offset = 0;
966 } else {
8fafb476 967 pci_base = (unsigned long long)image->bus_resource.start;
59c22904
MW
968
969 /*
970 * Bound address is a valid address for the window, adjust
971 * according to window granularity.
972 */
973 pci_bound = pci_base + (size - 0x10000);
974 vme_offset = vme_base - pci_base;
975 }
d22b8ed9
MW
976
977 /* Convert 64-bit variables to 2x 32-bit variables */
978 reg_split(pci_base, &pci_base_high, &pci_base_low);
979 reg_split(pci_bound, &pci_bound_high, &pci_bound_low);
980 reg_split(vme_offset, &vme_offset_high, &vme_offset_low);
981
982 if (pci_base_low & 0xFFFF) {
983 spin_unlock(&(image->lock));
48d9356e 984 dev_err(tsi148_bridge->parent, "Invalid PCI base alignment\n");
d22b8ed9
MW
985 retval = -EINVAL;
986 goto err_gran;
987 }
988 if (pci_bound_low & 0xFFFF) {
989 spin_unlock(&(image->lock));
48d9356e 990 dev_err(tsi148_bridge->parent, "Invalid PCI bound alignment\n");
d22b8ed9
MW
991 retval = -EINVAL;
992 goto err_gran;
993 }
994 if (vme_offset_low & 0xFFFF) {
995 spin_unlock(&(image->lock));
48d9356e
MW
996 dev_err(tsi148_bridge->parent, "Invalid VME Offset "
997 "alignment\n");
d22b8ed9
MW
998 retval = -EINVAL;
999 goto err_gran;
1000 }
1001
1002 i = image->number;
1003
1004 /* Disable while we are mucking around */
29848ac9 1005 temp_ctl = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
d22b8ed9
MW
1006 TSI148_LCSR_OFFSET_OTAT);
1007 temp_ctl &= ~TSI148_LCSR_OTAT_EN;
29848ac9 1008 iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_OT[i] +
d22b8ed9
MW
1009 TSI148_LCSR_OFFSET_OTAT);
1010
d22b8ed9
MW
1011 /* Setup 2eSST speeds */
1012 temp_ctl &= ~TSI148_LCSR_OTAT_2eSSTM_M;
1013 switch (cycle & (VME_2eSST160 | VME_2eSST267 | VME_2eSST320)) {
1014 case VME_2eSST160:
1015 temp_ctl |= TSI148_LCSR_OTAT_2eSSTM_160;
1016 break;
1017 case VME_2eSST267:
1018 temp_ctl |= TSI148_LCSR_OTAT_2eSSTM_267;
1019 break;
1020 case VME_2eSST320:
1021 temp_ctl |= TSI148_LCSR_OTAT_2eSSTM_320;
1022 break;
1023 }
1024
1025 /* Setup cycle types */
1026 if (cycle & VME_BLT) {
1027 temp_ctl &= ~TSI148_LCSR_OTAT_TM_M;
1028 temp_ctl |= TSI148_LCSR_OTAT_TM_BLT;
1029 }
1030 if (cycle & VME_MBLT) {
1031 temp_ctl &= ~TSI148_LCSR_OTAT_TM_M;
1032 temp_ctl |= TSI148_LCSR_OTAT_TM_MBLT;
1033 }
1034 if (cycle & VME_2eVME) {
1035 temp_ctl &= ~TSI148_LCSR_OTAT_TM_M;
1036 temp_ctl |= TSI148_LCSR_OTAT_TM_2eVME;
1037 }
1038 if (cycle & VME_2eSST) {
1039 temp_ctl &= ~TSI148_LCSR_OTAT_TM_M;
1040 temp_ctl |= TSI148_LCSR_OTAT_TM_2eSST;
1041 }
1042 if (cycle & VME_2eSSTB) {
48d9356e
MW
1043 dev_warn(tsi148_bridge->parent, "Currently not setting "
1044 "Broadcast Select Registers\n");
d22b8ed9
MW
1045 temp_ctl &= ~TSI148_LCSR_OTAT_TM_M;
1046 temp_ctl |= TSI148_LCSR_OTAT_TM_2eSSTB;
1047 }
1048
1049 /* Setup data width */
1050 temp_ctl &= ~TSI148_LCSR_OTAT_DBW_M;
1051 switch (dwidth) {
1052 case VME_D16:
1053 temp_ctl |= TSI148_LCSR_OTAT_DBW_16;
1054 break;
1055 case VME_D32:
1056 temp_ctl |= TSI148_LCSR_OTAT_DBW_32;
1057 break;
1058 default:
1059 spin_unlock(&(image->lock));
48d9356e 1060 dev_err(tsi148_bridge->parent, "Invalid data width\n");
d22b8ed9
MW
1061 retval = -EINVAL;
1062 goto err_dwidth;
1063 }
1064
1065 /* Setup address space */
1066 temp_ctl &= ~TSI148_LCSR_OTAT_AMODE_M;
1067 switch (aspace) {
1068 case VME_A16:
1069 temp_ctl |= TSI148_LCSR_OTAT_AMODE_A16;
1070 break;
1071 case VME_A24:
1072 temp_ctl |= TSI148_LCSR_OTAT_AMODE_A24;
1073 break;
1074 case VME_A32:
1075 temp_ctl |= TSI148_LCSR_OTAT_AMODE_A32;
1076 break;
1077 case VME_A64:
1078 temp_ctl |= TSI148_LCSR_OTAT_AMODE_A64;
1079 break;
1080 case VME_CRCSR:
1081 temp_ctl |= TSI148_LCSR_OTAT_AMODE_CRCSR;
1082 break;
1083 case VME_USER1:
1084 temp_ctl |= TSI148_LCSR_OTAT_AMODE_USER1;
1085 break;
1086 case VME_USER2:
1087 temp_ctl |= TSI148_LCSR_OTAT_AMODE_USER2;
1088 break;
1089 case VME_USER3:
1090 temp_ctl |= TSI148_LCSR_OTAT_AMODE_USER3;
1091 break;
1092 case VME_USER4:
1093 temp_ctl |= TSI148_LCSR_OTAT_AMODE_USER4;
1094 break;
1095 default:
1096 spin_unlock(&(image->lock));
48d9356e 1097 dev_err(tsi148_bridge->parent, "Invalid address space\n");
d22b8ed9
MW
1098 retval = -EINVAL;
1099 goto err_aspace;
1100 break;
1101 }
1102
1103 temp_ctl &= ~(3<<4);
1104 if (cycle & VME_SUPER)
1105 temp_ctl |= TSI148_LCSR_OTAT_SUP;
1106 if (cycle & VME_PROG)
1107 temp_ctl |= TSI148_LCSR_OTAT_PGM;
1108
1109 /* Setup mapping */
29848ac9 1110 iowrite32be(pci_base_high, bridge->base + TSI148_LCSR_OT[i] +
d22b8ed9 1111 TSI148_LCSR_OFFSET_OTSAU);
29848ac9 1112 iowrite32be(pci_base_low, bridge->base + TSI148_LCSR_OT[i] +
d22b8ed9 1113 TSI148_LCSR_OFFSET_OTSAL);
29848ac9 1114 iowrite32be(pci_bound_high, bridge->base + TSI148_LCSR_OT[i] +
d22b8ed9 1115 TSI148_LCSR_OFFSET_OTEAU);
29848ac9 1116 iowrite32be(pci_bound_low, bridge->base + TSI148_LCSR_OT[i] +
d22b8ed9 1117 TSI148_LCSR_OFFSET_OTEAL);
29848ac9 1118 iowrite32be(vme_offset_high, bridge->base + TSI148_LCSR_OT[i] +
d22b8ed9 1119 TSI148_LCSR_OFFSET_OTOFU);
29848ac9 1120 iowrite32be(vme_offset_low, bridge->base + TSI148_LCSR_OT[i] +
d22b8ed9
MW
1121 TSI148_LCSR_OFFSET_OTOFL);
1122
d22b8ed9 1123 /* Write ctl reg without enable */
29848ac9 1124 iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_OT[i] +
d22b8ed9
MW
1125 TSI148_LCSR_OFFSET_OTAT);
1126
1127 if (enabled)
1128 temp_ctl |= TSI148_LCSR_OTAT_EN;
1129
29848ac9 1130 iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_OT[i] +
d22b8ed9
MW
1131 TSI148_LCSR_OFFSET_OTAT);
1132
1133 spin_unlock(&(image->lock));
1134 return 0;
1135
1136err_aspace:
1137err_dwidth:
1138err_gran:
1139 tsi148_free_resource(image);
1140err_res:
1141err_window:
1142 return retval;
1143
1144}
1145
1146/*
1147 * Set the attributes of an outbound window.
1148 *
1149 * XXX Not parsing prefetch information.
1150 */
1151int __tsi148_master_get( struct vme_master_resource *image, int *enabled,
1152 unsigned long long *vme_base, unsigned long long *size,
1153 vme_address_t *aspace, vme_cycle_t *cycle, vme_width_t *dwidth)
1154{
1155 unsigned int i, ctl;
1156 unsigned int pci_base_low, pci_base_high;
1157 unsigned int pci_bound_low, pci_bound_high;
1158 unsigned int vme_offset_low, vme_offset_high;
1159
1160 unsigned long long pci_base, pci_bound, vme_offset;
29848ac9
MW
1161 struct tsi148_driver *bridge;
1162
1163 bridge = image->parent->driver_priv;
d22b8ed9
MW
1164
1165 i = image->number;
1166
29848ac9 1167 ctl = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
d22b8ed9
MW
1168 TSI148_LCSR_OFFSET_OTAT);
1169
29848ac9 1170 pci_base_high = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
d22b8ed9 1171 TSI148_LCSR_OFFSET_OTSAU);
29848ac9 1172 pci_base_low = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
d22b8ed9 1173 TSI148_LCSR_OFFSET_OTSAL);
29848ac9 1174 pci_bound_high = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
d22b8ed9 1175 TSI148_LCSR_OFFSET_OTEAU);
29848ac9 1176 pci_bound_low = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
d22b8ed9 1177 TSI148_LCSR_OFFSET_OTEAL);
29848ac9 1178 vme_offset_high = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
d22b8ed9 1179 TSI148_LCSR_OFFSET_OTOFU);
29848ac9 1180 vme_offset_low = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
d22b8ed9
MW
1181 TSI148_LCSR_OFFSET_OTOFL);
1182
1183 /* Convert 64-bit variables to 2x 32-bit variables */
1184 reg_join(pci_base_high, pci_base_low, &pci_base);
1185 reg_join(pci_bound_high, pci_bound_low, &pci_bound);
1186 reg_join(vme_offset_high, vme_offset_low, &vme_offset);
1187
1188 *vme_base = pci_base + vme_offset;
1189 *size = (unsigned long long)(pci_bound - pci_base) + 0x10000;
1190
1191 *enabled = 0;
1192 *aspace = 0;
1193 *cycle = 0;
1194 *dwidth = 0;
1195
1196 if (ctl & TSI148_LCSR_OTAT_EN)
1197 *enabled = 1;
1198
1199 /* Setup address space */
1200 if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_A16)
1201 *aspace |= VME_A16;
1202 if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_A24)
1203 *aspace |= VME_A24;
1204 if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_A32)
1205 *aspace |= VME_A32;
1206 if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_A64)
1207 *aspace |= VME_A64;
1208 if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_CRCSR)
1209 *aspace |= VME_CRCSR;
1210 if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_USER1)
1211 *aspace |= VME_USER1;
1212 if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_USER2)
1213 *aspace |= VME_USER2;
1214 if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_USER3)
1215 *aspace |= VME_USER3;
1216 if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_USER4)
1217 *aspace |= VME_USER4;
1218
1219 /* Setup 2eSST speeds */
1220 if ((ctl & TSI148_LCSR_OTAT_2eSSTM_M) == TSI148_LCSR_OTAT_2eSSTM_160)
1221 *cycle |= VME_2eSST160;
1222 if ((ctl & TSI148_LCSR_OTAT_2eSSTM_M) == TSI148_LCSR_OTAT_2eSSTM_267)
1223 *cycle |= VME_2eSST267;
1224 if ((ctl & TSI148_LCSR_OTAT_2eSSTM_M) == TSI148_LCSR_OTAT_2eSSTM_320)
1225 *cycle |= VME_2eSST320;
1226
1227 /* Setup cycle types */
1228 if ((ctl & TSI148_LCSR_OTAT_TM_M ) == TSI148_LCSR_OTAT_TM_SCT)
1229 *cycle |= VME_SCT;
1230 if ((ctl & TSI148_LCSR_OTAT_TM_M ) == TSI148_LCSR_OTAT_TM_BLT)
1231 *cycle |= VME_BLT;
1232 if ((ctl & TSI148_LCSR_OTAT_TM_M ) == TSI148_LCSR_OTAT_TM_MBLT)
1233 *cycle |= VME_MBLT;
1234 if ((ctl & TSI148_LCSR_OTAT_TM_M ) == TSI148_LCSR_OTAT_TM_2eVME)
1235 *cycle |= VME_2eVME;
1236 if ((ctl & TSI148_LCSR_OTAT_TM_M ) == TSI148_LCSR_OTAT_TM_2eSST)
1237 *cycle |= VME_2eSST;
1238 if ((ctl & TSI148_LCSR_OTAT_TM_M ) == TSI148_LCSR_OTAT_TM_2eSSTB)
1239 *cycle |= VME_2eSSTB;
1240
1241 if (ctl & TSI148_LCSR_OTAT_SUP)
1242 *cycle |= VME_SUPER;
1243 else
1244 *cycle |= VME_USER;
1245
1246 if (ctl & TSI148_LCSR_OTAT_PGM)
1247 *cycle |= VME_PROG;
1248 else
1249 *cycle |= VME_DATA;
1250
1251 /* Setup data width */
1252 if ((ctl & TSI148_LCSR_OTAT_DBW_M) == TSI148_LCSR_OTAT_DBW_16)
1253 *dwidth = VME_D16;
1254 if ((ctl & TSI148_LCSR_OTAT_DBW_M) == TSI148_LCSR_OTAT_DBW_32)
1255 *dwidth = VME_D32;
1256
1257 return 0;
1258}
1259
1260
1261int tsi148_master_get( struct vme_master_resource *image, int *enabled,
1262 unsigned long long *vme_base, unsigned long long *size,
1263 vme_address_t *aspace, vme_cycle_t *cycle, vme_width_t *dwidth)
1264{
1265 int retval;
1266
1267 spin_lock(&(image->lock));
1268
1269 retval = __tsi148_master_get(image, enabled, vme_base, size, aspace,
1270 cycle, dwidth);
1271
1272 spin_unlock(&(image->lock));
1273
1274 return retval;
1275}
1276
1277ssize_t tsi148_master_read(struct vme_master_resource *image, void *buf,
1278 size_t count, loff_t offset)
1279{
1280 int retval, enabled;
1281 unsigned long long vme_base, size;
1282 vme_address_t aspace;
1283 vme_cycle_t cycle;
1284 vme_width_t dwidth;
1285 struct vme_bus_error *vme_err = NULL;
29848ac9
MW
1286 struct vme_bridge *tsi148_bridge;
1287
1288 tsi148_bridge = image->parent;
d22b8ed9
MW
1289
1290 spin_lock(&(image->lock));
1291
1292 memcpy_fromio(buf, image->kern_base + offset, (unsigned int)count);
1293 retval = count;
1294
1295 if (!err_chk)
1296 goto skip_chk;
1297
1298 __tsi148_master_get(image, &enabled, &vme_base, &size, &aspace, &cycle,
1299 &dwidth);
1300
29848ac9
MW
1301 vme_err = tsi148_find_error(tsi148_bridge, aspace, vme_base + offset,
1302 count);
d22b8ed9
MW
1303 if(vme_err != NULL) {
1304 dev_err(image->parent->parent, "First VME read error detected "
1305 "an at address 0x%llx\n", vme_err->address);
1306 retval = vme_err->address - (vme_base + offset);
1307 /* Clear down save errors in this address range */
29848ac9
MW
1308 tsi148_clear_errors(tsi148_bridge, aspace, vme_base + offset,
1309 count);
d22b8ed9
MW
1310 }
1311
1312skip_chk:
1313 spin_unlock(&(image->lock));
1314
1315 return retval;
1316}
1317
1318
d22b8ed9
MW
1319ssize_t tsi148_master_write(struct vme_master_resource *image, void *buf,
1320 size_t count, loff_t offset)
1321{
1322 int retval = 0, enabled;
1323 unsigned long long vme_base, size;
1324 vme_address_t aspace;
1325 vme_cycle_t cycle;
1326 vme_width_t dwidth;
1327
1328 struct vme_bus_error *vme_err = NULL;
29848ac9
MW
1329 struct vme_bridge *tsi148_bridge;
1330 struct tsi148_driver *bridge;
1331
1332 tsi148_bridge = image->parent;
1333
1334 bridge = tsi148_bridge->driver_priv;
d22b8ed9
MW
1335
1336 spin_lock(&(image->lock));
1337
1338 memcpy_toio(image->kern_base + offset, buf, (unsigned int)count);
1339 retval = count;
1340
1341 /*
1342 * Writes are posted. We need to do a read on the VME bus to flush out
1343 * all of the writes before we check for errors. We can't guarentee
1344 * that reading the data we have just written is safe. It is believed
1345 * that there isn't any read, write re-ordering, so we can read any
1346 * location in VME space, so lets read the Device ID from the tsi148's
1347 * own registers as mapped into CR/CSR space.
1348 *
1349 * We check for saved errors in the written address range/space.
1350 */
1351
1352 if (!err_chk)
1353 goto skip_chk;
1354
1355 /*
1356 * Get window info first, to maximise the time that the buffers may
1357 * fluch on their own
1358 */
1359 __tsi148_master_get(image, &enabled, &vme_base, &size, &aspace, &cycle,
1360 &dwidth);
1361
29848ac9 1362 ioread16(bridge->flush_image->kern_base + 0x7F000);
d22b8ed9 1363
29848ac9
MW
1364 vme_err = tsi148_find_error(tsi148_bridge, aspace, vme_base + offset,
1365 count);
d22b8ed9 1366 if(vme_err != NULL) {
48d9356e
MW
1367 dev_warn(tsi148_bridge->parent, "First VME write error detected"
1368 " an at address 0x%llx\n", vme_err->address);
d22b8ed9
MW
1369 retval = vme_err->address - (vme_base + offset);
1370 /* Clear down save errors in this address range */
29848ac9
MW
1371 tsi148_clear_errors(tsi148_bridge, aspace, vme_base + offset,
1372 count);
d22b8ed9
MW
1373 }
1374
1375skip_chk:
1376 spin_unlock(&(image->lock));
1377
1378 return retval;
1379}
1380
1381/*
1382 * Perform an RMW cycle on the VME bus.
1383 *
1384 * Requires a previously configured master window, returns final value.
1385 */
1386unsigned int tsi148_master_rmw(struct vme_master_resource *image,
1387 unsigned int mask, unsigned int compare, unsigned int swap,
1388 loff_t offset)
1389{
1390 unsigned long long pci_addr;
1391 unsigned int pci_addr_high, pci_addr_low;
1392 u32 tmp, result;
1393 int i;
29848ac9 1394 struct tsi148_driver *bridge;
d22b8ed9 1395
29848ac9 1396 bridge = image->parent->driver_priv;
d22b8ed9
MW
1397
1398 /* Find the PCI address that maps to the desired VME address */
1399 i = image->number;
1400
1401 /* Locking as we can only do one of these at a time */
29848ac9 1402 mutex_lock(&(bridge->vme_rmw));
d22b8ed9
MW
1403
1404 /* Lock image */
1405 spin_lock(&(image->lock));
1406
29848ac9 1407 pci_addr_high = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
d22b8ed9 1408 TSI148_LCSR_OFFSET_OTSAU);
29848ac9 1409 pci_addr_low = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
d22b8ed9
MW
1410 TSI148_LCSR_OFFSET_OTSAL);
1411
1412 reg_join(pci_addr_high, pci_addr_low, &pci_addr);
1413 reg_split(pci_addr + offset, &pci_addr_high, &pci_addr_low);
1414
1415 /* Configure registers */
29848ac9
MW
1416 iowrite32be(mask, bridge->base + TSI148_LCSR_RMWEN);
1417 iowrite32be(compare, bridge->base + TSI148_LCSR_RMWC);
1418 iowrite32be(swap, bridge->base + TSI148_LCSR_RMWS);
1419 iowrite32be(pci_addr_high, bridge->base + TSI148_LCSR_RMWAU);
1420 iowrite32be(pci_addr_low, bridge->base + TSI148_LCSR_RMWAL);
d22b8ed9
MW
1421
1422 /* Enable RMW */
29848ac9 1423 tmp = ioread32be(bridge->base + TSI148_LCSR_VMCTRL);
d22b8ed9 1424 tmp |= TSI148_LCSR_VMCTRL_RMWEN;
29848ac9 1425 iowrite32be(tmp, bridge->base + TSI148_LCSR_VMCTRL);
d22b8ed9
MW
1426
1427 /* Kick process off with a read to the required address. */
1428 result = ioread32be(image->kern_base + offset);
1429
1430 /* Disable RMW */
29848ac9 1431 tmp = ioread32be(bridge->base + TSI148_LCSR_VMCTRL);
d22b8ed9 1432 tmp &= ~TSI148_LCSR_VMCTRL_RMWEN;
29848ac9 1433 iowrite32be(tmp, bridge->base + TSI148_LCSR_VMCTRL);
d22b8ed9
MW
1434
1435 spin_unlock(&(image->lock));
1436
29848ac9 1437 mutex_unlock(&(bridge->vme_rmw));
d22b8ed9
MW
1438
1439 return result;
1440}
1441
48d9356e
MW
1442static int tsi148_dma_set_vme_src_attributes(struct device *dev, u32 *attr,
1443 vme_address_t aspace, vme_cycle_t cycle, vme_width_t dwidth)
d22b8ed9
MW
1444{
1445 /* Setup 2eSST speeds */
1446 switch (cycle & (VME_2eSST160 | VME_2eSST267 | VME_2eSST320)) {
1447 case VME_2eSST160:
1448 *attr |= TSI148_LCSR_DSAT_2eSSTM_160;
1449 break;
1450 case VME_2eSST267:
1451 *attr |= TSI148_LCSR_DSAT_2eSSTM_267;
1452 break;
1453 case VME_2eSST320:
1454 *attr |= TSI148_LCSR_DSAT_2eSSTM_320;
1455 break;
1456 }
1457
1458 /* Setup cycle types */
1459 if (cycle & VME_SCT) {
1460 *attr |= TSI148_LCSR_DSAT_TM_SCT;
1461 }
1462 if (cycle & VME_BLT) {
1463 *attr |= TSI148_LCSR_DSAT_TM_BLT;
1464 }
1465 if (cycle & VME_MBLT) {
1466 *attr |= TSI148_LCSR_DSAT_TM_MBLT;
1467 }
1468 if (cycle & VME_2eVME) {
1469 *attr |= TSI148_LCSR_DSAT_TM_2eVME;
1470 }
1471 if (cycle & VME_2eSST) {
1472 *attr |= TSI148_LCSR_DSAT_TM_2eSST;
1473 }
1474 if (cycle & VME_2eSSTB) {
48d9356e
MW
1475 dev_err(dev, "Currently not setting Broadcast Select "
1476 "Registers\n");
d22b8ed9
MW
1477 *attr |= TSI148_LCSR_DSAT_TM_2eSSTB;
1478 }
1479
1480 /* Setup data width */
1481 switch (dwidth) {
1482 case VME_D16:
1483 *attr |= TSI148_LCSR_DSAT_DBW_16;
1484 break;
1485 case VME_D32:
1486 *attr |= TSI148_LCSR_DSAT_DBW_32;
1487 break;
1488 default:
48d9356e 1489 dev_err(dev, "Invalid data width\n");
d22b8ed9
MW
1490 return -EINVAL;
1491 }
1492
1493 /* Setup address space */
1494 switch (aspace) {
1495 case VME_A16:
1496 *attr |= TSI148_LCSR_DSAT_AMODE_A16;
1497 break;
1498 case VME_A24:
1499 *attr |= TSI148_LCSR_DSAT_AMODE_A24;
1500 break;
1501 case VME_A32:
1502 *attr |= TSI148_LCSR_DSAT_AMODE_A32;
1503 break;
1504 case VME_A64:
1505 *attr |= TSI148_LCSR_DSAT_AMODE_A64;
1506 break;
1507 case VME_CRCSR:
1508 *attr |= TSI148_LCSR_DSAT_AMODE_CRCSR;
1509 break;
1510 case VME_USER1:
1511 *attr |= TSI148_LCSR_DSAT_AMODE_USER1;
1512 break;
1513 case VME_USER2:
1514 *attr |= TSI148_LCSR_DSAT_AMODE_USER2;
1515 break;
1516 case VME_USER3:
1517 *attr |= TSI148_LCSR_DSAT_AMODE_USER3;
1518 break;
1519 case VME_USER4:
1520 *attr |= TSI148_LCSR_DSAT_AMODE_USER4;
1521 break;
1522 default:
48d9356e 1523 dev_err(dev, "Invalid address space\n");
d22b8ed9
MW
1524 return -EINVAL;
1525 break;
1526 }
1527
1528 if (cycle & VME_SUPER)
1529 *attr |= TSI148_LCSR_DSAT_SUP;
1530 if (cycle & VME_PROG)
1531 *attr |= TSI148_LCSR_DSAT_PGM;
1532
1533 return 0;
1534}
1535
48d9356e
MW
1536static int tsi148_dma_set_vme_dest_attributes(struct device *dev, u32 *attr,
1537 vme_address_t aspace, vme_cycle_t cycle, vme_width_t dwidth)
d22b8ed9
MW
1538{
1539 /* Setup 2eSST speeds */
1540 switch (cycle & (VME_2eSST160 | VME_2eSST267 | VME_2eSST320)) {
1541 case VME_2eSST160:
1542 *attr |= TSI148_LCSR_DDAT_2eSSTM_160;
1543 break;
1544 case VME_2eSST267:
1545 *attr |= TSI148_LCSR_DDAT_2eSSTM_267;
1546 break;
1547 case VME_2eSST320:
1548 *attr |= TSI148_LCSR_DDAT_2eSSTM_320;
1549 break;
1550 }
1551
1552 /* Setup cycle types */
1553 if (cycle & VME_SCT) {
1554 *attr |= TSI148_LCSR_DDAT_TM_SCT;
1555 }
1556 if (cycle & VME_BLT) {
1557 *attr |= TSI148_LCSR_DDAT_TM_BLT;
1558 }
1559 if (cycle & VME_MBLT) {
1560 *attr |= TSI148_LCSR_DDAT_TM_MBLT;
1561 }
1562 if (cycle & VME_2eVME) {
1563 *attr |= TSI148_LCSR_DDAT_TM_2eVME;
1564 }
1565 if (cycle & VME_2eSST) {
1566 *attr |= TSI148_LCSR_DDAT_TM_2eSST;
1567 }
1568 if (cycle & VME_2eSSTB) {
48d9356e
MW
1569 dev_err(dev, "Currently not setting Broadcast Select "
1570 "Registers\n");
d22b8ed9
MW
1571 *attr |= TSI148_LCSR_DDAT_TM_2eSSTB;
1572 }
1573
1574 /* Setup data width */
1575 switch (dwidth) {
1576 case VME_D16:
1577 *attr |= TSI148_LCSR_DDAT_DBW_16;
1578 break;
1579 case VME_D32:
1580 *attr |= TSI148_LCSR_DDAT_DBW_32;
1581 break;
1582 default:
48d9356e 1583 dev_err(dev, "Invalid data width\n");
d22b8ed9
MW
1584 return -EINVAL;
1585 }
1586
1587 /* Setup address space */
1588 switch (aspace) {
1589 case VME_A16:
1590 *attr |= TSI148_LCSR_DDAT_AMODE_A16;
1591 break;
1592 case VME_A24:
1593 *attr |= TSI148_LCSR_DDAT_AMODE_A24;
1594 break;
1595 case VME_A32:
1596 *attr |= TSI148_LCSR_DDAT_AMODE_A32;
1597 break;
1598 case VME_A64:
1599 *attr |= TSI148_LCSR_DDAT_AMODE_A64;
1600 break;
1601 case VME_CRCSR:
1602 *attr |= TSI148_LCSR_DDAT_AMODE_CRCSR;
1603 break;
1604 case VME_USER1:
1605 *attr |= TSI148_LCSR_DDAT_AMODE_USER1;
1606 break;
1607 case VME_USER2:
1608 *attr |= TSI148_LCSR_DDAT_AMODE_USER2;
1609 break;
1610 case VME_USER3:
1611 *attr |= TSI148_LCSR_DDAT_AMODE_USER3;
1612 break;
1613 case VME_USER4:
1614 *attr |= TSI148_LCSR_DDAT_AMODE_USER4;
1615 break;
1616 default:
48d9356e 1617 dev_err(dev, "Invalid address space\n");
d22b8ed9
MW
1618 return -EINVAL;
1619 break;
1620 }
1621
1622 if (cycle & VME_SUPER)
1623 *attr |= TSI148_LCSR_DDAT_SUP;
1624 if (cycle & VME_PROG)
1625 *attr |= TSI148_LCSR_DDAT_PGM;
1626
1627 return 0;
1628}
1629
1630/*
1631 * Add a link list descriptor to the list
d22b8ed9
MW
1632 */
1633int tsi148_dma_list_add (struct vme_dma_list *list, struct vme_dma_attr *src,
1634 struct vme_dma_attr *dest, size_t count)
1635{
1636 struct tsi148_dma_entry *entry, *prev;
1637 u32 address_high, address_low;
1638 struct vme_dma_pattern *pattern_attr;
1639 struct vme_dma_pci *pci_attr;
1640 struct vme_dma_vme *vme_attr;
1641 dma_addr_t desc_ptr;
1642 int retval = 0;
48d9356e
MW
1643 struct vme_bridge *tsi148_bridge;
1644
1645 tsi148_bridge = list->parent->parent;
d22b8ed9 1646
bb9ea89e 1647 /* Descriptor must be aligned on 64-bit boundaries */
d22b8ed9
MW
1648 entry = (struct tsi148_dma_entry *)kmalloc(
1649 sizeof(struct tsi148_dma_entry), GFP_KERNEL);
1650 if (entry == NULL) {
48d9356e
MW
1651 dev_err(tsi148_bridge->parent, "Failed to allocate memory for "
1652 "dma resource structure\n");
d22b8ed9
MW
1653 retval = -ENOMEM;
1654 goto err_mem;
1655 }
1656
1657 /* Test descriptor alignment */
1658 if ((unsigned long)&(entry->descriptor) & 0x7) {
48d9356e
MW
1659 dev_err(tsi148_bridge->parent, "Descriptor not aligned to 8 "
1660 "byte boundary as required: %p\n",
1661 &(entry->descriptor));
d22b8ed9
MW
1662 retval = -EINVAL;
1663 goto err_align;
1664 }
1665
1666 /* Given we are going to fill out the structure, we probably don't
1667 * need to zero it, but better safe than sorry for now.
1668 */
1669 memset(&(entry->descriptor), 0, sizeof(struct tsi148_dma_descriptor));
1670
1671 /* Fill out source part */
1672 switch (src->type) {
1673 case VME_DMA_PATTERN:
1674 pattern_attr = (struct vme_dma_pattern *)src->private;
1675
1676 entry->descriptor.dsal = pattern_attr->pattern;
1677 entry->descriptor.dsat = TSI148_LCSR_DSAT_TYP_PAT;
1678 /* Default behaviour is 32 bit pattern */
1679 if (pattern_attr->type & VME_DMA_PATTERN_BYTE) {
1680 entry->descriptor.dsat |= TSI148_LCSR_DSAT_PSZ;
1681 }
1682 /* It seems that the default behaviour is to increment */
1683 if ((pattern_attr->type & VME_DMA_PATTERN_INCREMENT) == 0) {
1684 entry->descriptor.dsat |= TSI148_LCSR_DSAT_NIN;
1685 }
1686 break;
1687 case VME_DMA_PCI:
1688 pci_attr = (struct vme_dma_pci *)src->private;
1689
1690 reg_split((unsigned long long)pci_attr->address, &address_high,
1691 &address_low);
1692 entry->descriptor.dsau = address_high;
1693 entry->descriptor.dsal = address_low;
1694 entry->descriptor.dsat = TSI148_LCSR_DSAT_TYP_PCI;
1695 break;
1696 case VME_DMA_VME:
1697 vme_attr = (struct vme_dma_vme *)src->private;
1698
1699 reg_split((unsigned long long)vme_attr->address, &address_high,
1700 &address_low);
1701 entry->descriptor.dsau = address_high;
1702 entry->descriptor.dsal = address_low;
1703 entry->descriptor.dsat = TSI148_LCSR_DSAT_TYP_VME;
1704
1705 retval = tsi148_dma_set_vme_src_attributes(
48d9356e
MW
1706 tsi148_bridge->parent, &(entry->descriptor.dsat),
1707 vme_attr->aspace, vme_attr->cycle, vme_attr->dwidth);
d22b8ed9
MW
1708 if(retval < 0 )
1709 goto err_source;
1710 break;
1711 default:
48d9356e 1712 dev_err(tsi148_bridge->parent, "Invalid source type\n");
d22b8ed9
MW
1713 retval = -EINVAL;
1714 goto err_source;
1715 break;
1716 }
1717
1718 /* Assume last link - this will be over-written by adding another */
1719 entry->descriptor.dnlau = 0;
1720 entry->descriptor.dnlal = TSI148_LCSR_DNLAL_LLA;
1721
1722
1723 /* Fill out destination part */
1724 switch (dest->type) {
1725 case VME_DMA_PCI:
1726 pci_attr = (struct vme_dma_pci *)dest->private;
1727
1728 reg_split((unsigned long long)pci_attr->address, &address_high,
1729 &address_low);
1730 entry->descriptor.ddau = address_high;
1731 entry->descriptor.ddal = address_low;
1732 entry->descriptor.ddat = TSI148_LCSR_DDAT_TYP_PCI;
1733 break;
1734 case VME_DMA_VME:
1735 vme_attr = (struct vme_dma_vme *)dest->private;
1736
1737 reg_split((unsigned long long)vme_attr->address, &address_high,
1738 &address_low);
1739 entry->descriptor.ddau = address_high;
1740 entry->descriptor.ddal = address_low;
1741 entry->descriptor.ddat = TSI148_LCSR_DDAT_TYP_VME;
1742
1743 retval = tsi148_dma_set_vme_dest_attributes(
48d9356e
MW
1744 tsi148_bridge->parent, &(entry->descriptor.ddat),
1745 vme_attr->aspace, vme_attr->cycle, vme_attr->dwidth);
d22b8ed9
MW
1746 if(retval < 0 )
1747 goto err_dest;
1748 break;
1749 default:
48d9356e 1750 dev_err(tsi148_bridge->parent, "Invalid destination type\n");
d22b8ed9
MW
1751 retval = -EINVAL;
1752 goto err_dest;
1753 break;
1754 }
1755
1756 /* Fill out count */
1757 entry->descriptor.dcnt = (u32)count;
1758
1759 /* Add to list */
1760 list_add_tail(&(entry->list), &(list->entries));
1761
1762 /* Fill out previous descriptors "Next Address" */
1763 if(entry->list.prev != &(list->entries)){
1764 prev = list_entry(entry->list.prev, struct tsi148_dma_entry,
1765 list);
1766 /* We need the bus address for the pointer */
1767 desc_ptr = virt_to_bus(&(entry->descriptor));
1768 reg_split(desc_ptr, &(prev->descriptor.dnlau),
1769 &(prev->descriptor.dnlal));
1770 }
1771
1772 return 0;
1773
1774err_dest:
1775err_source:
1776err_align:
1777 kfree(entry);
1778err_mem:
1779 return retval;
1780}
1781
1782/*
1783 * Check to see if the provided DMA channel is busy.
1784 */
29848ac9 1785static int tsi148_dma_busy(struct vme_bridge *tsi148_bridge, int channel)
d22b8ed9
MW
1786{
1787 u32 tmp;
29848ac9
MW
1788 struct tsi148_driver *bridge;
1789
1790 bridge = tsi148_bridge->driver_priv;
d22b8ed9 1791
29848ac9 1792 tmp = ioread32be(bridge->base + TSI148_LCSR_DMA[channel] +
d22b8ed9
MW
1793 TSI148_LCSR_OFFSET_DSTA);
1794
1795 if (tmp & TSI148_LCSR_DSTA_BSY)
1796 return 0;
1797 else
1798 return 1;
1799
1800}
1801
1802/*
1803 * Execute a previously generated link list
1804 *
1805 * XXX Need to provide control register configuration.
1806 */
1807int tsi148_dma_list_exec(struct vme_dma_list *list)
1808{
1809 struct vme_dma_resource *ctrlr;
1810 int channel, retval = 0;
1811 struct tsi148_dma_entry *entry;
1812 dma_addr_t bus_addr;
1813 u32 bus_addr_high, bus_addr_low;
1814 u32 val, dctlreg = 0;
48d9356e 1815 struct vme_bridge *tsi148_bridge;
29848ac9 1816 struct tsi148_driver *bridge;
d22b8ed9
MW
1817
1818 ctrlr = list->parent;
1819
48d9356e
MW
1820 tsi148_bridge = ctrlr->parent;
1821
1822 bridge = tsi148_bridge->driver_priv;
29848ac9 1823
400822fe 1824 mutex_lock(&(ctrlr->mtx));
d22b8ed9
MW
1825
1826 channel = ctrlr->number;
1827
1828 if (! list_empty(&(ctrlr->running))) {
1829 /*
1830 * XXX We have an active DMA transfer and currently haven't
1831 * sorted out the mechanism for "pending" DMA transfers.
1832 * Return busy.
1833 */
1834 /* Need to add to pending here */
400822fe 1835 mutex_unlock(&(ctrlr->mtx));
d22b8ed9
MW
1836 return -EBUSY;
1837 } else {
1838 list_add(&(list->list), &(ctrlr->running));
1839 }
d22b8ed9
MW
1840
1841 /* Get first bus address and write into registers */
1842 entry = list_first_entry(&(list->entries), struct tsi148_dma_entry,
1843 list);
1844
1845 bus_addr = virt_to_bus(&(entry->descriptor));
1846
400822fe 1847 mutex_unlock(&(ctrlr->mtx));
d22b8ed9
MW
1848
1849 reg_split(bus_addr, &bus_addr_high, &bus_addr_low);
1850
29848ac9 1851 iowrite32be(bus_addr_high, bridge->base +
d22b8ed9 1852 TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DNLAU);
29848ac9 1853 iowrite32be(bus_addr_low, bridge->base +
d22b8ed9
MW
1854 TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DNLAL);
1855
1856 /* Start the operation */
29848ac9 1857 iowrite32be(dctlreg | TSI148_LCSR_DCTL_DGO, bridge->base +
d22b8ed9
MW
1858 TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DCTL);
1859
29848ac9
MW
1860 wait_event_interruptible(bridge->dma_queue[channel],
1861 tsi148_dma_busy(ctrlr->parent, channel));
d22b8ed9
MW
1862 /*
1863 * Read status register, this register is valid until we kick off a
1864 * new transfer.
1865 */
29848ac9 1866 val = ioread32be(bridge->base + TSI148_LCSR_DMA[channel] +
d22b8ed9
MW
1867 TSI148_LCSR_OFFSET_DSTA);
1868
1869 if (val & TSI148_LCSR_DSTA_VBE) {
48d9356e 1870 dev_err(tsi148_bridge->parent, "DMA Error. DSTA=%08X\n", val);
d22b8ed9
MW
1871 retval = -EIO;
1872 }
1873
1874 /* Remove list from running list */
400822fe 1875 mutex_lock(&(ctrlr->mtx));
d22b8ed9 1876 list_del(&(list->list));
400822fe 1877 mutex_unlock(&(ctrlr->mtx));
d22b8ed9
MW
1878
1879 return retval;
1880}
1881
1882/*
1883 * Clean up a previously generated link list
1884 *
1885 * We have a separate function, don't assume that the chain can't be reused.
1886 */
1887int tsi148_dma_list_empty(struct vme_dma_list *list)
1888{
1889 struct list_head *pos, *temp;
1890 struct tsi148_dma_entry *entry;
1891
1892 /* detach and free each entry */
1893 list_for_each_safe(pos, temp, &(list->entries)) {
1894 list_del(pos);
1895 entry = list_entry(pos, struct tsi148_dma_entry, list);
1896 kfree(entry);
1897 }
1898
1899 return (0);
1900}
1901
1902/*
1903 * All 4 location monitors reside at the same base - this is therefore a
1904 * system wide configuration.
1905 *
1906 * This does not enable the LM monitor - that should be done when the first
1907 * callback is attached and disabled when the last callback is removed.
1908 */
42fb5031
MW
1909int tsi148_lm_set(struct vme_lm_resource *lm, unsigned long long lm_base,
1910 vme_address_t aspace, vme_cycle_t cycle)
d22b8ed9
MW
1911{
1912 u32 lm_base_high, lm_base_low, lm_ctl = 0;
1913 int i;
48d9356e 1914 struct vme_bridge *tsi148_bridge;
29848ac9
MW
1915 struct tsi148_driver *bridge;
1916
48d9356e
MW
1917 tsi148_bridge = lm->parent;
1918
1919 bridge = tsi148_bridge->driver_priv;
d22b8ed9 1920
42fb5031 1921 mutex_lock(&(lm->mtx));
d22b8ed9
MW
1922
1923 /* If we already have a callback attached, we can't move it! */
42fb5031 1924 for (i = 0; i < lm->monitors; i++) {
29848ac9 1925 if (bridge->lm_callback[i] != NULL) {
42fb5031 1926 mutex_unlock(&(lm->mtx));
48d9356e
MW
1927 dev_err(tsi148_bridge->parent, "Location monitor "
1928 "callback attached, can't reset\n");
d22b8ed9
MW
1929 return -EBUSY;
1930 }
1931 }
1932
1933 switch (aspace) {
1934 case VME_A16:
1935 lm_ctl |= TSI148_LCSR_LMAT_AS_A16;
1936 break;
1937 case VME_A24:
1938 lm_ctl |= TSI148_LCSR_LMAT_AS_A24;
1939 break;
1940 case VME_A32:
1941 lm_ctl |= TSI148_LCSR_LMAT_AS_A32;
1942 break;
1943 case VME_A64:
1944 lm_ctl |= TSI148_LCSR_LMAT_AS_A64;
1945 break;
1946 default:
42fb5031 1947 mutex_unlock(&(lm->mtx));
48d9356e 1948 dev_err(tsi148_bridge->parent, "Invalid address space\n");
d22b8ed9
MW
1949 return -EINVAL;
1950 break;
1951 }
1952
1953 if (cycle & VME_SUPER)
1954 lm_ctl |= TSI148_LCSR_LMAT_SUPR ;
1955 if (cycle & VME_USER)
1956 lm_ctl |= TSI148_LCSR_LMAT_NPRIV;
1957 if (cycle & VME_PROG)
1958 lm_ctl |= TSI148_LCSR_LMAT_PGM;
1959 if (cycle & VME_DATA)
1960 lm_ctl |= TSI148_LCSR_LMAT_DATA;
1961
1962 reg_split(lm_base, &lm_base_high, &lm_base_low);
1963
29848ac9
MW
1964 iowrite32be(lm_base_high, bridge->base + TSI148_LCSR_LMBAU);
1965 iowrite32be(lm_base_low, bridge->base + TSI148_LCSR_LMBAL);
1966 iowrite32be(lm_ctl, bridge->base + TSI148_LCSR_LMAT);
d22b8ed9 1967
42fb5031 1968 mutex_unlock(&(lm->mtx));
d22b8ed9
MW
1969
1970 return 0;
1971}
1972
1973/* Get configuration of the callback monitor and return whether it is enabled
1974 * or disabled.
1975 */
42fb5031
MW
1976int tsi148_lm_get(struct vme_lm_resource *lm, unsigned long long *lm_base,
1977 vme_address_t *aspace, vme_cycle_t *cycle)
d22b8ed9
MW
1978{
1979 u32 lm_base_high, lm_base_low, lm_ctl, enabled = 0;
29848ac9
MW
1980 struct tsi148_driver *bridge;
1981
1982 bridge = lm->parent->driver_priv;
d22b8ed9 1983
42fb5031 1984 mutex_lock(&(lm->mtx));
d22b8ed9 1985
29848ac9
MW
1986 lm_base_high = ioread32be(bridge->base + TSI148_LCSR_LMBAU);
1987 lm_base_low = ioread32be(bridge->base + TSI148_LCSR_LMBAL);
1988 lm_ctl = ioread32be(bridge->base + TSI148_LCSR_LMAT);
d22b8ed9
MW
1989
1990 reg_join(lm_base_high, lm_base_low, lm_base);
1991
1992 if (lm_ctl & TSI148_LCSR_LMAT_EN)
1993 enabled = 1;
1994
1995 if ((lm_ctl & TSI148_LCSR_LMAT_AS_M) == TSI148_LCSR_LMAT_AS_A16) {
1996 *aspace |= VME_A16;
1997 }
1998 if ((lm_ctl & TSI148_LCSR_LMAT_AS_M) == TSI148_LCSR_LMAT_AS_A24) {
1999 *aspace |= VME_A24;
2000 }
2001 if ((lm_ctl & TSI148_LCSR_LMAT_AS_M) == TSI148_LCSR_LMAT_AS_A32) {
2002 *aspace |= VME_A32;
2003 }
2004 if ((lm_ctl & TSI148_LCSR_LMAT_AS_M) == TSI148_LCSR_LMAT_AS_A64) {
2005 *aspace |= VME_A64;
2006 }
2007
2008 if (lm_ctl & TSI148_LCSR_LMAT_SUPR)
2009 *cycle |= VME_SUPER;
2010 if (lm_ctl & TSI148_LCSR_LMAT_NPRIV)
2011 *cycle |= VME_USER;
2012 if (lm_ctl & TSI148_LCSR_LMAT_PGM)
2013 *cycle |= VME_PROG;
2014 if (lm_ctl & TSI148_LCSR_LMAT_DATA)
2015 *cycle |= VME_DATA;
2016
42fb5031 2017 mutex_unlock(&(lm->mtx));
d22b8ed9
MW
2018
2019 return enabled;
2020}
2021
2022/*
2023 * Attach a callback to a specific location monitor.
2024 *
2025 * Callback will be passed the monitor triggered.
2026 */
42fb5031
MW
2027int tsi148_lm_attach(struct vme_lm_resource *lm, int monitor,
2028 void (*callback)(int))
d22b8ed9
MW
2029{
2030 u32 lm_ctl, tmp;
48d9356e 2031 struct vme_bridge *tsi148_bridge;
29848ac9
MW
2032 struct tsi148_driver *bridge;
2033
48d9356e
MW
2034 tsi148_bridge = lm->parent;
2035
2036 bridge = tsi148_bridge->driver_priv;
d22b8ed9 2037
42fb5031 2038 mutex_lock(&(lm->mtx));
d22b8ed9
MW
2039
2040 /* Ensure that the location monitor is configured - need PGM or DATA */
29848ac9 2041 lm_ctl = ioread32be(bridge->base + TSI148_LCSR_LMAT);
d22b8ed9 2042 if ((lm_ctl & (TSI148_LCSR_LMAT_PGM | TSI148_LCSR_LMAT_DATA)) == 0) {
42fb5031 2043 mutex_unlock(&(lm->mtx));
48d9356e
MW
2044 dev_err(tsi148_bridge->parent, "Location monitor not properly "
2045 "configured\n");
d22b8ed9
MW
2046 return -EINVAL;
2047 }
2048
2049 /* Check that a callback isn't already attached */
29848ac9 2050 if (bridge->lm_callback[monitor] != NULL) {
42fb5031 2051 mutex_unlock(&(lm->mtx));
48d9356e 2052 dev_err(tsi148_bridge->parent, "Existing callback attached\n");
d22b8ed9
MW
2053 return -EBUSY;
2054 }
2055
2056 /* Attach callback */
29848ac9 2057 bridge->lm_callback[monitor] = callback;
d22b8ed9
MW
2058
2059 /* Enable Location Monitor interrupt */
29848ac9 2060 tmp = ioread32be(bridge->base + TSI148_LCSR_INTEN);
d22b8ed9 2061 tmp |= TSI148_LCSR_INTEN_LMEN[monitor];
29848ac9 2062 iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEN);
d22b8ed9 2063
29848ac9 2064 tmp = ioread32be(bridge->base + TSI148_LCSR_INTEO);
d22b8ed9 2065 tmp |= TSI148_LCSR_INTEO_LMEO[monitor];
29848ac9 2066 iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEO);
d22b8ed9
MW
2067
2068 /* Ensure that global Location Monitor Enable set */
2069 if ((lm_ctl & TSI148_LCSR_LMAT_EN) == 0) {
2070 lm_ctl |= TSI148_LCSR_LMAT_EN;
29848ac9 2071 iowrite32be(lm_ctl, bridge->base + TSI148_LCSR_LMAT);
d22b8ed9
MW
2072 }
2073
42fb5031 2074 mutex_unlock(&(lm->mtx));
d22b8ed9
MW
2075
2076 return 0;
2077}
2078
2079/*
2080 * Detach a callback function forn a specific location monitor.
2081 */
42fb5031 2082int tsi148_lm_detach(struct vme_lm_resource *lm, int monitor)
d22b8ed9
MW
2083{
2084 u32 lm_en, tmp;
29848ac9
MW
2085 struct tsi148_driver *bridge;
2086
2087 bridge = lm->parent->driver_priv;
d22b8ed9 2088
42fb5031 2089 mutex_lock(&(lm->mtx));
d22b8ed9
MW
2090
2091 /* Disable Location Monitor and ensure previous interrupts are clear */
29848ac9 2092 lm_en = ioread32be(bridge->base + TSI148_LCSR_INTEN);
d22b8ed9 2093 lm_en &= ~TSI148_LCSR_INTEN_LMEN[monitor];
29848ac9 2094 iowrite32be(lm_en, bridge->base + TSI148_LCSR_INTEN);
d22b8ed9 2095
29848ac9 2096 tmp = ioread32be(bridge->base + TSI148_LCSR_INTEO);
d22b8ed9 2097 tmp &= ~TSI148_LCSR_INTEO_LMEO[monitor];
29848ac9 2098 iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEO);
d22b8ed9
MW
2099
2100 iowrite32be(TSI148_LCSR_INTC_LMC[monitor],
29848ac9 2101 bridge->base + TSI148_LCSR_INTC);
d22b8ed9
MW
2102
2103 /* Detach callback */
29848ac9 2104 bridge->lm_callback[monitor] = NULL;
d22b8ed9
MW
2105
2106 /* If all location monitors disabled, disable global Location Monitor */
2107 if ((lm_en & (TSI148_LCSR_INTS_LM0S | TSI148_LCSR_INTS_LM1S |
2108 TSI148_LCSR_INTS_LM2S | TSI148_LCSR_INTS_LM3S)) == 0) {
29848ac9 2109 tmp = ioread32be(bridge->base + TSI148_LCSR_LMAT);
d22b8ed9 2110 tmp &= ~TSI148_LCSR_LMAT_EN;
29848ac9 2111 iowrite32be(tmp, bridge->base + TSI148_LCSR_LMAT);
d22b8ed9
MW
2112 }
2113
42fb5031 2114 mutex_unlock(&(lm->mtx));
d22b8ed9
MW
2115
2116 return 0;
2117}
2118
2119/*
2120 * Determine Geographical Addressing
2121 */
29848ac9 2122int tsi148_slot_get(struct vme_bridge *tsi148_bridge)
d22b8ed9
MW
2123{
2124 u32 slot = 0;
29848ac9
MW
2125 struct tsi148_driver *bridge;
2126
2127 bridge = tsi148_bridge->driver_priv;
d22b8ed9 2128
638f199d 2129 if (!geoid) {
29848ac9 2130 slot = ioread32be(bridge->base + TSI148_LCSR_VSTAT);
638f199d
MW
2131 slot = slot & TSI148_LCSR_VSTAT_GA_M;
2132 } else
2133 slot = geoid;
2134
d22b8ed9
MW
2135 return (int)slot;
2136}
2137
2138static int __init tsi148_init(void)
2139{
2140 return pci_register_driver(&tsi148_driver);
2141}
2142
2143/*
2144 * Configure CR/CSR space
2145 *
2146 * Access to the CR/CSR can be configured at power-up. The location of the
2147 * CR/CSR registers in the CR/CSR address space is determined by the boards
2148 * Auto-ID or Geographic address. This function ensures that the window is
2149 * enabled at an offset consistent with the boards geopgraphic address.
2150 *
2151 * Each board has a 512kB window, with the highest 4kB being used for the
2152 * boards registers, this means there is a fix length 508kB window which must
2153 * be mapped onto PCI memory.
2154 */
29848ac9
MW
2155static int tsi148_crcsr_init(struct vme_bridge *tsi148_bridge,
2156 struct pci_dev *pdev)
d22b8ed9
MW
2157{
2158 u32 cbar, crat, vstat;
2159 u32 crcsr_bus_high, crcsr_bus_low;
2160 int retval;
29848ac9
MW
2161 struct tsi148_driver *bridge;
2162
2163 bridge = tsi148_bridge->driver_priv;
d22b8ed9
MW
2164
2165 /* Allocate mem for CR/CSR image */
29848ac9
MW
2166 bridge->crcsr_kernel = pci_alloc_consistent(pdev, VME_CRCSR_BUF_SIZE,
2167 &(bridge->crcsr_bus));
2168 if (bridge->crcsr_kernel == NULL) {
48d9356e
MW
2169 dev_err(tsi148_bridge->parent, "Failed to allocate memory for "
2170 "CR/CSR image\n");
d22b8ed9
MW
2171 return -ENOMEM;
2172 }
2173
29848ac9 2174 memset(bridge->crcsr_kernel, 0, VME_CRCSR_BUF_SIZE);
d22b8ed9 2175
29848ac9 2176 reg_split(bridge->crcsr_bus, &crcsr_bus_high, &crcsr_bus_low);
d22b8ed9 2177
29848ac9
MW
2178 iowrite32be(crcsr_bus_high, bridge->base + TSI148_LCSR_CROU);
2179 iowrite32be(crcsr_bus_low, bridge->base + TSI148_LCSR_CROL);
d22b8ed9
MW
2180
2181 /* Ensure that the CR/CSR is configured at the correct offset */
29848ac9 2182 cbar = ioread32be(bridge->base + TSI148_CBAR);
d22b8ed9
MW
2183 cbar = (cbar & TSI148_CRCSR_CBAR_M)>>3;
2184
29848ac9 2185 vstat = tsi148_slot_get(tsi148_bridge);
d22b8ed9
MW
2186
2187 if (cbar != vstat) {
638f199d 2188 cbar = vstat;
48d9356e 2189 dev_info(tsi148_bridge->parent, "Setting CR/CSR offset\n");
29848ac9 2190 iowrite32be(cbar<<3, bridge->base + TSI148_CBAR);
d22b8ed9 2191 }
48d9356e 2192 dev_info(tsi148_bridge->parent, "CR/CSR Offset: %d\n", cbar);
d22b8ed9 2193
29848ac9 2194 crat = ioread32be(bridge->base + TSI148_LCSR_CRAT);
d22b8ed9 2195 if (crat & TSI148_LCSR_CRAT_EN) {
48d9356e 2196 dev_info(tsi148_bridge->parent, "Enabling CR/CSR space\n");
d22b8ed9 2197 iowrite32be(crat | TSI148_LCSR_CRAT_EN,
29848ac9 2198 bridge->base + TSI148_LCSR_CRAT);
d22b8ed9 2199 } else
48d9356e 2200 dev_info(tsi148_bridge->parent, "CR/CSR already enabled\n");
d22b8ed9
MW
2201
2202 /* If we want flushed, error-checked writes, set up a window
2203 * over the CR/CSR registers. We read from here to safely flush
2204 * through VME writes.
2205 */
2206 if(err_chk) {
29848ac9
MW
2207 retval = tsi148_master_set(bridge->flush_image, 1,
2208 (vstat * 0x80000), 0x80000, VME_CRCSR, VME_SCT,
2209 VME_D16);
d22b8ed9 2210 if (retval)
48d9356e
MW
2211 dev_err(tsi148_bridge->parent, "Configuring flush image"
2212 " failed\n");
d22b8ed9
MW
2213 }
2214
2215 return 0;
2216
2217}
2218
29848ac9
MW
2219static void tsi148_crcsr_exit(struct vme_bridge *tsi148_bridge,
2220 struct pci_dev *pdev)
d22b8ed9
MW
2221{
2222 u32 crat;
29848ac9
MW
2223 struct tsi148_driver *bridge;
2224
2225 bridge = tsi148_bridge->driver_priv;
d22b8ed9
MW
2226
2227 /* Turn off CR/CSR space */
29848ac9 2228 crat = ioread32be(bridge->base + TSI148_LCSR_CRAT);
d22b8ed9 2229 iowrite32be(crat & ~TSI148_LCSR_CRAT_EN,
29848ac9 2230 bridge->base + TSI148_LCSR_CRAT);
d22b8ed9
MW
2231
2232 /* Free image */
29848ac9
MW
2233 iowrite32be(0, bridge->base + TSI148_LCSR_CROU);
2234 iowrite32be(0, bridge->base + TSI148_LCSR_CROL);
d22b8ed9 2235
29848ac9
MW
2236 pci_free_consistent(pdev, VME_CRCSR_BUF_SIZE, bridge->crcsr_kernel,
2237 bridge->crcsr_bus);
d22b8ed9
MW
2238}
2239
2240static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id)
2241{
2242 int retval, i, master_num;
2243 u32 data;
2244 struct list_head *pos = NULL;
29848ac9
MW
2245 struct vme_bridge *tsi148_bridge;
2246 struct tsi148_driver *tsi148_device;
d22b8ed9
MW
2247 struct vme_master_resource *master_image;
2248 struct vme_slave_resource *slave_image;
2249 struct vme_dma_resource *dma_ctrlr;
42fb5031 2250 struct vme_lm_resource *lm;
d22b8ed9
MW
2251
2252 /* If we want to support more than one of each bridge, we need to
2253 * dynamically generate this so we get one per device
2254 */
2255 tsi148_bridge = (struct vme_bridge *)kmalloc(sizeof(struct vme_bridge),
2256 GFP_KERNEL);
2257 if (tsi148_bridge == NULL) {
2258 dev_err(&pdev->dev, "Failed to allocate memory for device "
2259 "structure\n");
2260 retval = -ENOMEM;
2261 goto err_struct;
2262 }
2263
2264 memset(tsi148_bridge, 0, sizeof(struct vme_bridge));
2265
29848ac9
MW
2266 tsi148_device = kmalloc(sizeof(struct tsi148_driver), GFP_KERNEL);
2267 if (tsi148_device == NULL) {
2268 dev_err(&pdev->dev, "Failed to allocate memory for device "
2269 "structure\n");
2270 retval = -ENOMEM;
2271 goto err_driver;
2272 }
2273
2274 memset(tsi148_device, 0, sizeof(struct tsi148_driver));
2275
2276 tsi148_bridge->driver_priv = tsi148_device;
2277
d22b8ed9
MW
2278 /* Enable the device */
2279 retval = pci_enable_device(pdev);
2280 if (retval) {
2281 dev_err(&pdev->dev, "Unable to enable device\n");
2282 goto err_enable;
2283 }
2284
2285 /* Map Registers */
2286 retval = pci_request_regions(pdev, driver_name);
2287 if (retval) {
2288 dev_err(&pdev->dev, "Unable to reserve resources\n");
2289 goto err_resource;
2290 }
2291
2292 /* map registers in BAR 0 */
29848ac9
MW
2293 tsi148_device->base = ioremap_nocache(pci_resource_start(pdev, 0),
2294 4096);
2295 if (!tsi148_device->base) {
d22b8ed9
MW
2296 dev_err(&pdev->dev, "Unable to remap CRG region\n");
2297 retval = -EIO;
2298 goto err_remap;
2299 }
2300
2301 /* Check to see if the mapping worked out */
29848ac9 2302 data = ioread32(tsi148_device->base + TSI148_PCFS_ID) & 0x0000FFFF;
d22b8ed9
MW
2303 if (data != PCI_VENDOR_ID_TUNDRA) {
2304 dev_err(&pdev->dev, "CRG region check failed\n");
2305 retval = -EIO;
2306 goto err_test;
2307 }
2308
2309 /* Initialize wait queues & mutual exclusion flags */
29848ac9
MW
2310 init_waitqueue_head(&(tsi148_device->dma_queue[0]));
2311 init_waitqueue_head(&(tsi148_device->dma_queue[1]));
2312 init_waitqueue_head(&(tsi148_device->iack_queue));
2313 mutex_init(&(tsi148_device->vme_int));
2314 mutex_init(&(tsi148_device->vme_rmw));
d22b8ed9
MW
2315
2316 tsi148_bridge->parent = &(pdev->dev);
2317 strcpy(tsi148_bridge->name, driver_name);
2318
2319 /* Setup IRQ */
2320 retval = tsi148_irq_init(tsi148_bridge);
2321 if (retval != 0) {
2322 dev_err(&pdev->dev, "Chip Initialization failed.\n");
2323 goto err_irq;
2324 }
2325
2326 /* If we are going to flush writes, we need to read from the VME bus.
2327 * We need to do this safely, thus we read the devices own CR/CSR
2328 * register. To do this we must set up a window in CR/CSR space and
2329 * hence have one less master window resource available.
2330 */
2331 master_num = TSI148_MAX_MASTER;
2332 if(err_chk){
2333 master_num--;
29848ac9
MW
2334
2335 tsi148_device->flush_image = (struct vme_master_resource *)
2336 kmalloc(sizeof(struct vme_master_resource), GFP_KERNEL);
2337 if (tsi148_device->flush_image == NULL) {
d22b8ed9
MW
2338 dev_err(&pdev->dev, "Failed to allocate memory for "
2339 "flush resource structure\n");
2340 retval = -ENOMEM;
2341 goto err_master;
2342 }
29848ac9
MW
2343 tsi148_device->flush_image->parent = tsi148_bridge;
2344 spin_lock_init(&(tsi148_device->flush_image->lock));
2345 tsi148_device->flush_image->locked = 1;
2346 tsi148_device->flush_image->number = master_num;
2347 tsi148_device->flush_image->address_attr = VME_A16 | VME_A24 |
2348 VME_A32 | VME_A64;
2349 tsi148_device->flush_image->cycle_attr = VME_SCT | VME_BLT |
2350 VME_MBLT | VME_2eVME | VME_2eSST | VME_2eSSTB |
2351 VME_2eSST160 | VME_2eSST267 | VME_2eSST320 | VME_SUPER |
2352 VME_USER | VME_PROG | VME_DATA;
2353 tsi148_device->flush_image->width_attr = VME_D16 | VME_D32;
8fafb476 2354 memset(&(tsi148_device->flush_image->bus_resource), 0,
d22b8ed9 2355 sizeof(struct resource));
29848ac9 2356 tsi148_device->flush_image->kern_base = NULL;
d22b8ed9
MW
2357 }
2358
2359 /* Add master windows to list */
2360 INIT_LIST_HEAD(&(tsi148_bridge->master_resources));
2361 for (i = 0; i < master_num; i++) {
2362 master_image = (struct vme_master_resource *)kmalloc(
2363 sizeof(struct vme_master_resource), GFP_KERNEL);
2364 if (master_image == NULL) {
2365 dev_err(&pdev->dev, "Failed to allocate memory for "
2366 "master resource structure\n");
2367 retval = -ENOMEM;
2368 goto err_master;
2369 }
2370 master_image->parent = tsi148_bridge;
2371 spin_lock_init(&(master_image->lock));
2372 master_image->locked = 0;
2373 master_image->number = i;
2374 master_image->address_attr = VME_A16 | VME_A24 | VME_A32 |
2375 VME_A64;
2376 master_image->cycle_attr = VME_SCT | VME_BLT | VME_MBLT |
2377 VME_2eVME | VME_2eSST | VME_2eSSTB | VME_2eSST160 |
2378 VME_2eSST267 | VME_2eSST320 | VME_SUPER | VME_USER |
2379 VME_PROG | VME_DATA;
2380 master_image->width_attr = VME_D16 | VME_D32;
8fafb476 2381 memset(&(master_image->bus_resource), 0,
d22b8ed9
MW
2382 sizeof(struct resource));
2383 master_image->kern_base = NULL;
2384 list_add_tail(&(master_image->list),
2385 &(tsi148_bridge->master_resources));
2386 }
2387
2388 /* Add slave windows to list */
2389 INIT_LIST_HEAD(&(tsi148_bridge->slave_resources));
2390 for (i = 0; i < TSI148_MAX_SLAVE; i++) {
2391 slave_image = (struct vme_slave_resource *)kmalloc(
2392 sizeof(struct vme_slave_resource), GFP_KERNEL);
2393 if (slave_image == NULL) {
2394 dev_err(&pdev->dev, "Failed to allocate memory for "
2395 "slave resource structure\n");
2396 retval = -ENOMEM;
2397 goto err_slave;
2398 }
2399 slave_image->parent = tsi148_bridge;
400822fe 2400 mutex_init(&(slave_image->mtx));
d22b8ed9
MW
2401 slave_image->locked = 0;
2402 slave_image->number = i;
2403 slave_image->address_attr = VME_A16 | VME_A24 | VME_A32 |
2404 VME_A64 | VME_CRCSR | VME_USER1 | VME_USER2 |
2405 VME_USER3 | VME_USER4;
2406 slave_image->cycle_attr = VME_SCT | VME_BLT | VME_MBLT |
2407 VME_2eVME | VME_2eSST | VME_2eSSTB | VME_2eSST160 |
2408 VME_2eSST267 | VME_2eSST320 | VME_SUPER | VME_USER |
2409 VME_PROG | VME_DATA;
2410 list_add_tail(&(slave_image->list),
2411 &(tsi148_bridge->slave_resources));
2412 }
2413
2414 /* Add dma engines to list */
2415 INIT_LIST_HEAD(&(tsi148_bridge->dma_resources));
2416 for (i = 0; i < TSI148_MAX_DMA; i++) {
2417 dma_ctrlr = (struct vme_dma_resource *)kmalloc(
2418 sizeof(struct vme_dma_resource), GFP_KERNEL);
2419 if (dma_ctrlr == NULL) {
2420 dev_err(&pdev->dev, "Failed to allocate memory for "
2421 "dma resource structure\n");
2422 retval = -ENOMEM;
2423 goto err_dma;
2424 }
2425 dma_ctrlr->parent = tsi148_bridge;
400822fe 2426 mutex_init(&(dma_ctrlr->mtx));
d22b8ed9
MW
2427 dma_ctrlr->locked = 0;
2428 dma_ctrlr->number = i;
4f723df4
MW
2429 dma_ctrlr->route_attr = VME_DMA_VME_TO_MEM |
2430 VME_DMA_MEM_TO_VME | VME_DMA_VME_TO_VME |
2431 VME_DMA_MEM_TO_MEM | VME_DMA_PATTERN_TO_VME |
2432 VME_DMA_PATTERN_TO_MEM;
d22b8ed9
MW
2433 INIT_LIST_HEAD(&(dma_ctrlr->pending));
2434 INIT_LIST_HEAD(&(dma_ctrlr->running));
2435 list_add_tail(&(dma_ctrlr->list),
2436 &(tsi148_bridge->dma_resources));
2437 }
2438
42fb5031
MW
2439 /* Add location monitor to list */
2440 INIT_LIST_HEAD(&(tsi148_bridge->lm_resources));
2441 lm = kmalloc(sizeof(struct vme_lm_resource), GFP_KERNEL);
2442 if (lm == NULL) {
2443 dev_err(&pdev->dev, "Failed to allocate memory for "
2444 "location monitor resource structure\n");
2445 retval = -ENOMEM;
2446 goto err_lm;
2447 }
2448 lm->parent = tsi148_bridge;
2449 mutex_init(&(lm->mtx));
2450 lm->locked = 0;
2451 lm->number = 1;
2452 lm->monitors = 4;
2453 list_add_tail(&(lm->list), &(tsi148_bridge->lm_resources));
2454
d22b8ed9
MW
2455 tsi148_bridge->slave_get = tsi148_slave_get;
2456 tsi148_bridge->slave_set = tsi148_slave_set;
2457 tsi148_bridge->master_get = tsi148_master_get;
2458 tsi148_bridge->master_set = tsi148_master_set;
2459 tsi148_bridge->master_read = tsi148_master_read;
2460 tsi148_bridge->master_write = tsi148_master_write;
2461 tsi148_bridge->master_rmw = tsi148_master_rmw;
2462 tsi148_bridge->dma_list_add = tsi148_dma_list_add;
2463 tsi148_bridge->dma_list_exec = tsi148_dma_list_exec;
2464 tsi148_bridge->dma_list_empty = tsi148_dma_list_empty;
c813f592
MW
2465 tsi148_bridge->irq_set = tsi148_irq_set;
2466 tsi148_bridge->irq_generate = tsi148_irq_generate;
d22b8ed9
MW
2467 tsi148_bridge->lm_set = tsi148_lm_set;
2468 tsi148_bridge->lm_get = tsi148_lm_get;
2469 tsi148_bridge->lm_attach = tsi148_lm_attach;
2470 tsi148_bridge->lm_detach = tsi148_lm_detach;
2471 tsi148_bridge->slot_get = tsi148_slot_get;
2472
29848ac9 2473 data = ioread32be(tsi148_device->base + TSI148_LCSR_VSTAT);
d22b8ed9
MW
2474 dev_info(&pdev->dev, "Board is%s the VME system controller\n",
2475 (data & TSI148_LCSR_VSTAT_SCONS)? "" : " not");
29848ac9 2476 if (!geoid)
638f199d
MW
2477 dev_info(&pdev->dev, "VME geographical address is %d\n",
2478 data & TSI148_LCSR_VSTAT_GA_M);
29848ac9 2479 else
638f199d
MW
2480 dev_info(&pdev->dev, "VME geographical address is set to %d\n",
2481 geoid);
29848ac9 2482
d22b8ed9
MW
2483 dev_info(&pdev->dev, "VME Write and flush and error check is %s\n",
2484 err_chk ? "enabled" : "disabled");
2485
29848ac9 2486 if (tsi148_crcsr_init(tsi148_bridge, pdev))
d22b8ed9
MW
2487 dev_err(&pdev->dev, "CR/CSR configuration failed.\n");
2488 goto err_crcsr;
2489
d22b8ed9
MW
2490 retval = vme_register_bridge(tsi148_bridge);
2491 if (retval != 0) {
2492 dev_err(&pdev->dev, "Chip Registration failed.\n");
2493 goto err_reg;
2494 }
2495
29848ac9
MW
2496 pci_set_drvdata(pdev, tsi148_bridge);
2497
d22b8ed9 2498 /* Clear VME bus "board fail", and "power-up reset" lines */
29848ac9 2499 data = ioread32be(tsi148_device->base + TSI148_LCSR_VSTAT);
d22b8ed9
MW
2500 data &= ~TSI148_LCSR_VSTAT_BRDFL;
2501 data |= TSI148_LCSR_VSTAT_CPURST;
29848ac9 2502 iowrite32be(data, tsi148_device->base + TSI148_LCSR_VSTAT);
d22b8ed9
MW
2503
2504 return 0;
2505
2506 vme_unregister_bridge(tsi148_bridge);
2507err_reg:
29848ac9 2508 tsi148_crcsr_exit(tsi148_bridge, pdev);
d22b8ed9 2509err_crcsr:
42fb5031
MW
2510err_lm:
2511 /* resources are stored in link list */
2512 list_for_each(pos, &(tsi148_bridge->lm_resources)) {
2513 lm = list_entry(pos, struct vme_lm_resource, list);
2514 list_del(pos);
2515 kfree(lm);
2516 }
d22b8ed9
MW
2517err_dma:
2518 /* resources are stored in link list */
2519 list_for_each(pos, &(tsi148_bridge->dma_resources)) {
2520 dma_ctrlr = list_entry(pos, struct vme_dma_resource, list);
2521 list_del(pos);
2522 kfree(dma_ctrlr);
2523 }
2524err_slave:
2525 /* resources are stored in link list */
2526 list_for_each(pos, &(tsi148_bridge->slave_resources)) {
2527 slave_image = list_entry(pos, struct vme_slave_resource, list);
2528 list_del(pos);
2529 kfree(slave_image);
2530 }
2531err_master:
2532 /* resources are stored in link list */
2533 list_for_each(pos, &(tsi148_bridge->master_resources)) {
2534 master_image = list_entry(pos, struct vme_master_resource, list);
2535 list_del(pos);
2536 kfree(master_image);
2537 }
2538
29848ac9 2539 tsi148_irq_exit(tsi148_device, pdev);
d22b8ed9
MW
2540err_irq:
2541err_test:
29848ac9 2542 iounmap(tsi148_device->base);
d22b8ed9
MW
2543err_remap:
2544 pci_release_regions(pdev);
2545err_resource:
2546 pci_disable_device(pdev);
2547err_enable:
29848ac9
MW
2548 kfree(tsi148_device);
2549err_driver:
d22b8ed9
MW
2550 kfree(tsi148_bridge);
2551err_struct:
2552 return retval;
2553
2554}
2555
2556static void tsi148_remove(struct pci_dev *pdev)
2557{
2558 struct list_head *pos = NULL;
2559 struct vme_master_resource *master_image;
2560 struct vme_slave_resource *slave_image;
2561 struct vme_dma_resource *dma_ctrlr;
2562 int i;
29848ac9
MW
2563 struct tsi148_driver *bridge;
2564 struct vme_bridge *tsi148_bridge = pci_get_drvdata(pdev);
2565
2566 bridge = tsi148_bridge->driver_priv;
d22b8ed9 2567
d22b8ed9 2568
29848ac9 2569 dev_dbg(&pdev->dev, "Driver is being unloaded.\n");
d22b8ed9
MW
2570
2571 /*
2572 * Shutdown all inbound and outbound windows.
2573 */
2574 for (i = 0; i < 8; i++) {
29848ac9 2575 iowrite32be(0, bridge->base + TSI148_LCSR_IT[i] +
d22b8ed9 2576 TSI148_LCSR_OFFSET_ITAT);
29848ac9 2577 iowrite32be(0, bridge->base + TSI148_LCSR_OT[i] +
d22b8ed9
MW
2578 TSI148_LCSR_OFFSET_OTAT);
2579 }
2580
2581 /*
2582 * Shutdown Location monitor.
2583 */
29848ac9 2584 iowrite32be(0, bridge->base + TSI148_LCSR_LMAT);
d22b8ed9
MW
2585
2586 /*
2587 * Shutdown CRG map.
2588 */
29848ac9 2589 iowrite32be(0, bridge->base + TSI148_LCSR_CSRAT);
d22b8ed9
MW
2590
2591 /*
2592 * Clear error status.
2593 */
29848ac9
MW
2594 iowrite32be(0xFFFFFFFF, bridge->base + TSI148_LCSR_EDPAT);
2595 iowrite32be(0xFFFFFFFF, bridge->base + TSI148_LCSR_VEAT);
2596 iowrite32be(0x07000700, bridge->base + TSI148_LCSR_PSTAT);
d22b8ed9
MW
2597
2598 /*
2599 * Remove VIRQ interrupt (if any)
2600 */
29848ac9
MW
2601 if (ioread32be(bridge->base + TSI148_LCSR_VICR) & 0x800)
2602 iowrite32be(0x8000, bridge->base + TSI148_LCSR_VICR);
d22b8ed9 2603
d22b8ed9
MW
2604 /*
2605 * Map all Interrupts to PCI INTA
2606 */
29848ac9
MW
2607 iowrite32be(0x0, bridge->base + TSI148_LCSR_INTM1);
2608 iowrite32be(0x0, bridge->base + TSI148_LCSR_INTM2);
d22b8ed9 2609
29848ac9 2610 tsi148_irq_exit(bridge, pdev);
d22b8ed9
MW
2611
2612 vme_unregister_bridge(tsi148_bridge);
2613
29848ac9 2614 tsi148_crcsr_exit(tsi148_bridge, pdev);
d22b8ed9
MW
2615
2616 /* resources are stored in link list */
2617 list_for_each(pos, &(tsi148_bridge->dma_resources)) {
2618 dma_ctrlr = list_entry(pos, struct vme_dma_resource, list);
2619 list_del(pos);
2620 kfree(dma_ctrlr);
2621 }
2622
2623 /* resources are stored in link list */
2624 list_for_each(pos, &(tsi148_bridge->slave_resources)) {
2625 slave_image = list_entry(pos, struct vme_slave_resource, list);
2626 list_del(pos);
2627 kfree(slave_image);
2628 }
2629
2630 /* resources are stored in link list */
2631 list_for_each(pos, &(tsi148_bridge->master_resources)) {
638f199d
MW
2632 master_image = list_entry(pos, struct vme_master_resource,
2633 list);
d22b8ed9
MW
2634 list_del(pos);
2635 kfree(master_image);
2636 }
2637
29848ac9 2638 tsi148_irq_exit(bridge, pdev);
d22b8ed9 2639
29848ac9 2640 iounmap(bridge->base);
d22b8ed9
MW
2641
2642 pci_release_regions(pdev);
2643
2644 pci_disable_device(pdev);
2645
29848ac9
MW
2646 kfree(tsi148_bridge->driver_priv);
2647
d22b8ed9
MW
2648 kfree(tsi148_bridge);
2649}
2650
2651static void __exit tsi148_exit(void)
2652{
2653 pci_unregister_driver(&tsi148_driver);
d22b8ed9
MW
2654}
2655
2656MODULE_PARM_DESC(err_chk, "Check for VME errors on reads and writes");
2657module_param(err_chk, bool, 0);
2658
638f199d
MW
2659MODULE_PARM_DESC(geoid, "Override geographical addressing");
2660module_param(geoid, int, 0);
2661
d22b8ed9
MW
2662MODULE_DESCRIPTION("VME driver for the Tundra Tempe VME bridge");
2663MODULE_LICENSE("GPL");
2664
2665module_init(tsi148_init);
2666module_exit(tsi148_exit);