1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Fake VME bridge support.
5 * This drive provides a fake VME bridge chip, this enables debugging of the
6 * VME framework in the absence of a VME system.
8 * This driver has to do a number of things in software that would be driven
9 * by hardware if it was available, it will also result in extra overhead at
10 * times when compared with driving actual hardware.
12 * Author: Martyn Welch <martyn@welches.me.uk>
13 * Copyright (c) 2014 Martyn Welch
15 * Based on vme_tsi148.c:
17 * Author: Martyn Welch <martyn.welch@ge.com>
18 * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc.
20 * Based on work by Tom Armistead and Ajit Prem
21 * Copyright 2004 Motorola Inc.
24 #include <linux/device.h>
25 #include <linux/errno.h>
26 #include <linux/interrupt.h>
27 #include <linux/module.h>
28 #include <linux/moduleparam.h>
29 #include <linux/slab.h>
30 #include <linux/spinlock.h>
31 #include <linux/types.h>
32 #include <linux/vme.h>
34 #include "../vme_bridge.h"
37 * Define the number of each that the fake driver supports.
39 #define FAKE_MAX_MASTER 8 /* Max Master Windows */
40 #define FAKE_MAX_SLAVE 8 /* Max Slave Windows */
42 /* Structures to hold information normally held in device registers */
43 struct fake_slave_window
{
45 unsigned long long vme_base
;
46 unsigned long long size
;
52 struct fake_master_window
{
54 unsigned long long vme_base
;
55 unsigned long long size
;
61 /* Structure used to hold driver specific information */
63 struct vme_bridge
*parent
;
64 struct fake_slave_window slaves
[FAKE_MAX_SLAVE
];
65 struct fake_master_window masters
[FAKE_MAX_MASTER
];
67 unsigned long long lm_base
;
70 void (*lm_callback
[4])(void *);
72 struct tasklet_struct int_tasklet
;
77 /* Only one VME interrupt can be generated at a time, provide locking */
81 /* Module parameter */
84 static const char driver_name
[] = "vme_fake";
86 static struct vme_bridge
*exit_pointer
;
88 static struct device
*vme_root
;
91 * Calling VME bus interrupt callback if provided.
93 static void fake_VIRQ_tasklet(unsigned long data
)
95 struct vme_bridge
*fake_bridge
;
96 struct fake_driver
*bridge
;
98 fake_bridge
= (struct vme_bridge
*) data
;
99 bridge
= fake_bridge
->driver_priv
;
101 vme_irq_handler(fake_bridge
, bridge
->int_level
, bridge
->int_statid
);
105 * Configure VME interrupt
107 static void fake_irq_set(struct vme_bridge
*fake_bridge
, int level
,
113 static void *fake_pci_to_ptr(dma_addr_t addr
)
115 return (void *)(uintptr_t)addr
;
118 static dma_addr_t
fake_ptr_to_pci(void *addr
)
120 return (dma_addr_t
)(uintptr_t)addr
;
124 * Generate a VME bus interrupt at the requested level & vector. Wait for
125 * interrupt to be acked.
127 static int fake_irq_generate(struct vme_bridge
*fake_bridge
, int level
,
130 struct fake_driver
*bridge
;
132 bridge
= fake_bridge
->driver_priv
;
134 mutex_lock(&bridge
->vme_int
);
136 bridge
->int_level
= level
;
138 bridge
->int_statid
= statid
;
141 * Schedule tasklet to run VME handler to emulate normal VME interrupt
144 tasklet_schedule(&bridge
->int_tasklet
);
146 mutex_unlock(&bridge
->vme_int
);
152 * Initialize a slave window with the requested attributes.
154 static int fake_slave_set(struct vme_slave_resource
*image
, int enabled
,
155 unsigned long long vme_base
, unsigned long long size
,
156 dma_addr_t buf_base
, u32 aspace
, u32 cycle
)
158 unsigned int i
, granularity
= 0;
159 unsigned long long vme_bound
;
160 struct vme_bridge
*fake_bridge
;
161 struct fake_driver
*bridge
;
163 fake_bridge
= image
->parent
;
164 bridge
= fake_bridge
->driver_priv
;
173 granularity
= 0x1000;
176 granularity
= 0x10000;
179 granularity
= 0x10000;
187 pr_err("Invalid address space\n");
192 * Bound address is a valid address for the window, adjust
195 vme_bound
= vme_base
+ size
- granularity
;
197 if (vme_base
& (granularity
- 1)) {
198 pr_err("Invalid VME base alignment\n");
201 if (vme_bound
& (granularity
- 1)) {
202 pr_err("Invalid VME bound alignment\n");
206 mutex_lock(&image
->mtx
);
208 bridge
->slaves
[i
].enabled
= enabled
;
209 bridge
->slaves
[i
].vme_base
= vme_base
;
210 bridge
->slaves
[i
].size
= size
;
211 bridge
->slaves
[i
].buf_base
= fake_pci_to_ptr(buf_base
);
212 bridge
->slaves
[i
].aspace
= aspace
;
213 bridge
->slaves
[i
].cycle
= cycle
;
215 mutex_unlock(&image
->mtx
);
221 * Get slave window configuration.
223 static int fake_slave_get(struct vme_slave_resource
*image
, int *enabled
,
224 unsigned long long *vme_base
, unsigned long long *size
,
225 dma_addr_t
*buf_base
, u32
*aspace
, u32
*cycle
)
228 struct fake_driver
*bridge
;
230 bridge
= image
->parent
->driver_priv
;
234 mutex_lock(&image
->mtx
);
236 *enabled
= bridge
->slaves
[i
].enabled
;
237 *vme_base
= bridge
->slaves
[i
].vme_base
;
238 *size
= bridge
->slaves
[i
].size
;
239 *buf_base
= fake_ptr_to_pci(bridge
->slaves
[i
].buf_base
);
240 *aspace
= bridge
->slaves
[i
].aspace
;
241 *cycle
= bridge
->slaves
[i
].cycle
;
243 mutex_unlock(&image
->mtx
);
249 * Set the attributes of an outbound window.
251 static int fake_master_set(struct vme_master_resource
*image
, int enabled
,
252 unsigned long long vme_base
, unsigned long long size
,
253 u32 aspace
, u32 cycle
, u32 dwidth
)
257 struct vme_bridge
*fake_bridge
;
258 struct fake_driver
*bridge
;
260 fake_bridge
= image
->parent
;
262 bridge
= fake_bridge
->driver_priv
;
264 /* Verify input data */
265 if (vme_base
& 0xFFFF) {
266 pr_err("Invalid VME Window alignment\n");
272 pr_err("Invalid size alignment\n");
277 if ((size
== 0) && (enabled
!= 0)) {
278 pr_err("Size must be non-zero for enabled windows\n");
283 /* Setup data width */
290 pr_err("Invalid data width\n");
295 /* Setup address space */
308 pr_err("Invalid address space\n");
313 spin_lock(&image
->lock
);
317 bridge
->masters
[i
].enabled
= enabled
;
318 bridge
->masters
[i
].vme_base
= vme_base
;
319 bridge
->masters
[i
].size
= size
;
320 bridge
->masters
[i
].aspace
= aspace
;
321 bridge
->masters
[i
].cycle
= cycle
;
322 bridge
->masters
[i
].dwidth
= dwidth
;
324 spin_unlock(&image
->lock
);
336 * Set the attributes of an outbound window.
338 static int __fake_master_get(struct vme_master_resource
*image
, int *enabled
,
339 unsigned long long *vme_base
, unsigned long long *size
,
340 u32
*aspace
, u32
*cycle
, u32
*dwidth
)
343 struct fake_driver
*bridge
;
345 bridge
= image
->parent
->driver_priv
;
349 *enabled
= bridge
->masters
[i
].enabled
;
350 *vme_base
= bridge
->masters
[i
].vme_base
;
351 *size
= bridge
->masters
[i
].size
;
352 *aspace
= bridge
->masters
[i
].aspace
;
353 *cycle
= bridge
->masters
[i
].cycle
;
354 *dwidth
= bridge
->masters
[i
].dwidth
;
360 static int fake_master_get(struct vme_master_resource
*image
, int *enabled
,
361 unsigned long long *vme_base
, unsigned long long *size
,
362 u32
*aspace
, u32
*cycle
, u32
*dwidth
)
366 spin_lock(&image
->lock
);
368 retval
= __fake_master_get(image
, enabled
, vme_base
, size
, aspace
,
371 spin_unlock(&image
->lock
);
377 static void fake_lm_check(struct fake_driver
*bridge
, unsigned long long addr
,
378 u32 aspace
, u32 cycle
)
380 struct vme_bridge
*fake_bridge
;
381 unsigned long long lm_base
;
382 u32 lm_aspace
, lm_cycle
;
384 struct vme_lm_resource
*lm
;
385 struct list_head
*pos
= NULL
, *n
;
388 fake_bridge
= bridge
->parent
;
390 /* Loop through each location monitor resource */
391 list_for_each_safe(pos
, n
, &fake_bridge
->lm_resources
) {
392 lm
= list_entry(pos
, struct vme_lm_resource
, list
);
394 /* If disabled, we're done */
395 if (bridge
->lm_enabled
== 0)
398 lm_base
= bridge
->lm_base
;
399 lm_aspace
= bridge
->lm_aspace
;
400 lm_cycle
= bridge
->lm_cycle
;
402 /* First make sure that the cycle and address space match */
403 if ((lm_aspace
== aspace
) && (lm_cycle
== cycle
)) {
404 for (i
= 0; i
< lm
->monitors
; i
++) {
405 /* Each location monitor covers 8 bytes */
406 if (((lm_base
+ (8 * i
)) <= addr
) &&
407 ((lm_base
+ (8 * i
) + 8) > addr
)) {
408 if (bridge
->lm_callback
[i
])
409 bridge
->lm_callback
[i
](
417 static noinline_for_stack u8
fake_vmeread8(struct fake_driver
*bridge
,
418 unsigned long long addr
,
419 u32 aspace
, u32 cycle
)
423 unsigned long long start
, end
, offset
;
426 for (i
= 0; i
< FAKE_MAX_SLAVE
; i
++) {
427 start
= bridge
->slaves
[i
].vme_base
;
428 end
= bridge
->slaves
[i
].vme_base
+ bridge
->slaves
[i
].size
;
430 if (aspace
!= bridge
->slaves
[i
].aspace
)
433 if (cycle
!= bridge
->slaves
[i
].cycle
)
436 if ((addr
>= start
) && (addr
< end
)) {
437 offset
= addr
- bridge
->slaves
[i
].vme_base
;
438 loc
= (u8
*)(bridge
->slaves
[i
].buf_base
+ offset
);
445 fake_lm_check(bridge
, addr
, aspace
, cycle
);
450 static noinline_for_stack u16
fake_vmeread16(struct fake_driver
*bridge
,
451 unsigned long long addr
,
452 u32 aspace
, u32 cycle
)
456 unsigned long long start
, end
, offset
;
459 for (i
= 0; i
< FAKE_MAX_SLAVE
; i
++) {
460 if (aspace
!= bridge
->slaves
[i
].aspace
)
463 if (cycle
!= bridge
->slaves
[i
].cycle
)
466 start
= bridge
->slaves
[i
].vme_base
;
467 end
= bridge
->slaves
[i
].vme_base
+ bridge
->slaves
[i
].size
;
469 if ((addr
>= start
) && ((addr
+ 1) < end
)) {
470 offset
= addr
- bridge
->slaves
[i
].vme_base
;
471 loc
= (u16
*)(bridge
->slaves
[i
].buf_base
+ offset
);
478 fake_lm_check(bridge
, addr
, aspace
, cycle
);
483 static noinline_for_stack u32
fake_vmeread32(struct fake_driver
*bridge
,
484 unsigned long long addr
,
485 u32 aspace
, u32 cycle
)
487 u32 retval
= 0xffffffff;
489 unsigned long long start
, end
, offset
;
492 for (i
= 0; i
< FAKE_MAX_SLAVE
; i
++) {
493 if (aspace
!= bridge
->slaves
[i
].aspace
)
496 if (cycle
!= bridge
->slaves
[i
].cycle
)
499 start
= bridge
->slaves
[i
].vme_base
;
500 end
= bridge
->slaves
[i
].vme_base
+ bridge
->slaves
[i
].size
;
502 if ((addr
>= start
) && ((addr
+ 3) < end
)) {
503 offset
= addr
- bridge
->slaves
[i
].vme_base
;
504 loc
= (u32
*)(bridge
->slaves
[i
].buf_base
+ offset
);
511 fake_lm_check(bridge
, addr
, aspace
, cycle
);
516 static ssize_t
fake_master_read(struct vme_master_resource
*image
, void *buf
,
517 size_t count
, loff_t offset
)
520 u32 aspace
, cycle
, dwidth
;
521 struct vme_bridge
*fake_bridge
;
522 struct fake_driver
*priv
;
524 unsigned long long addr
;
525 unsigned int done
= 0;
526 unsigned int count32
;
528 fake_bridge
= image
->parent
;
530 priv
= fake_bridge
->driver_priv
;
534 addr
= (unsigned long long)priv
->masters
[i
].vme_base
+ offset
;
535 aspace
= priv
->masters
[i
].aspace
;
536 cycle
= priv
->masters
[i
].cycle
;
537 dwidth
= priv
->masters
[i
].dwidth
;
539 spin_lock(&image
->lock
);
541 /* The following code handles VME address alignment. We cannot use
542 * memcpy_xxx here because it may cut data transfers in to 8-bit
543 * cycles when D16 or D32 cycles are required on the VME bus.
544 * On the other hand, the bridge itself assures that the maximum data
545 * cycle configured for the transfer is used and splits it
546 * automatically for non-aligned addresses, so we don't want the
547 * overhead of needlessly forcing small transfers for the entire cycle.
550 *(u8
*)buf
= fake_vmeread8(priv
, addr
, aspace
, cycle
);
555 if ((dwidth
== VME_D16
) || (dwidth
== VME_D32
)) {
556 if ((addr
+ done
) & 0x2) {
557 if ((count
- done
) < 2) {
558 *(u8
*)(buf
+ done
) = fake_vmeread8(priv
,
559 addr
+ done
, aspace
, cycle
);
563 *(u16
*)(buf
+ done
) = fake_vmeread16(priv
,
564 addr
+ done
, aspace
, cycle
);
570 if (dwidth
== VME_D32
) {
571 count32
= (count
- done
) & ~0x3;
572 while (done
< count32
) {
573 *(u32
*)(buf
+ done
) = fake_vmeread32(priv
, addr
+ done
,
577 } else if (dwidth
== VME_D16
) {
578 count32
= (count
- done
) & ~0x3;
579 while (done
< count32
) {
580 *(u16
*)(buf
+ done
) = fake_vmeread16(priv
, addr
+ done
,
584 } else if (dwidth
== VME_D8
) {
585 count32
= (count
- done
);
586 while (done
< count32
) {
587 *(u8
*)(buf
+ done
) = fake_vmeread8(priv
, addr
+ done
,
594 if ((dwidth
== VME_D16
) || (dwidth
== VME_D32
)) {
595 if ((count
- done
) & 0x2) {
596 *(u16
*)(buf
+ done
) = fake_vmeread16(priv
, addr
+ done
,
601 if ((count
- done
) & 0x1) {
602 *(u8
*)(buf
+ done
) = fake_vmeread8(priv
, addr
+ done
, aspace
,
610 spin_unlock(&image
->lock
);
615 static noinline_for_stack
void fake_vmewrite8(struct fake_driver
*bridge
,
616 u8
*buf
, unsigned long long addr
,
617 u32 aspace
, u32 cycle
)
620 unsigned long long start
, end
, offset
;
623 for (i
= 0; i
< FAKE_MAX_SLAVE
; i
++) {
624 if (aspace
!= bridge
->slaves
[i
].aspace
)
627 if (cycle
!= bridge
->slaves
[i
].cycle
)
630 start
= bridge
->slaves
[i
].vme_base
;
631 end
= bridge
->slaves
[i
].vme_base
+ bridge
->slaves
[i
].size
;
633 if ((addr
>= start
) && (addr
< end
)) {
634 offset
= addr
- bridge
->slaves
[i
].vme_base
;
635 loc
= (u8
*)((void *)bridge
->slaves
[i
].buf_base
+ offset
);
642 fake_lm_check(bridge
, addr
, aspace
, cycle
);
646 static noinline_for_stack
void fake_vmewrite16(struct fake_driver
*bridge
,
647 u16
*buf
, unsigned long long addr
,
648 u32 aspace
, u32 cycle
)
651 unsigned long long start
, end
, offset
;
654 for (i
= 0; i
< FAKE_MAX_SLAVE
; i
++) {
655 if (aspace
!= bridge
->slaves
[i
].aspace
)
658 if (cycle
!= bridge
->slaves
[i
].cycle
)
661 start
= bridge
->slaves
[i
].vme_base
;
662 end
= bridge
->slaves
[i
].vme_base
+ bridge
->slaves
[i
].size
;
664 if ((addr
>= start
) && ((addr
+ 1) < end
)) {
665 offset
= addr
- bridge
->slaves
[i
].vme_base
;
666 loc
= (u16
*)((void *)bridge
->slaves
[i
].buf_base
+ offset
);
673 fake_lm_check(bridge
, addr
, aspace
, cycle
);
677 static noinline_for_stack
void fake_vmewrite32(struct fake_driver
*bridge
,
678 u32
*buf
, unsigned long long addr
,
679 u32 aspace
, u32 cycle
)
682 unsigned long long start
, end
, offset
;
685 for (i
= 0; i
< FAKE_MAX_SLAVE
; i
++) {
686 if (aspace
!= bridge
->slaves
[i
].aspace
)
689 if (cycle
!= bridge
->slaves
[i
].cycle
)
692 start
= bridge
->slaves
[i
].vme_base
;
693 end
= bridge
->slaves
[i
].vme_base
+ bridge
->slaves
[i
].size
;
695 if ((addr
>= start
) && ((addr
+ 3) < end
)) {
696 offset
= addr
- bridge
->slaves
[i
].vme_base
;
697 loc
= (u32
*)((void *)bridge
->slaves
[i
].buf_base
+ offset
);
704 fake_lm_check(bridge
, addr
, aspace
, cycle
);
708 static ssize_t
fake_master_write(struct vme_master_resource
*image
, void *buf
,
709 size_t count
, loff_t offset
)
712 u32 aspace
, cycle
, dwidth
;
713 unsigned long long addr
;
715 unsigned int done
= 0;
716 unsigned int count32
;
718 struct vme_bridge
*fake_bridge
;
719 struct fake_driver
*bridge
;
721 fake_bridge
= image
->parent
;
723 bridge
= fake_bridge
->driver_priv
;
727 addr
= bridge
->masters
[i
].vme_base
+ offset
;
728 aspace
= bridge
->masters
[i
].aspace
;
729 cycle
= bridge
->masters
[i
].cycle
;
730 dwidth
= bridge
->masters
[i
].dwidth
;
732 spin_lock(&image
->lock
);
734 /* Here we apply for the same strategy we do in master_read
735 * function in order to assure the correct cycles.
738 fake_vmewrite8(bridge
, (u8
*)buf
, addr
, aspace
, cycle
);
744 if ((dwidth
== VME_D16
) || (dwidth
== VME_D32
)) {
745 if ((addr
+ done
) & 0x2) {
746 if ((count
- done
) < 2) {
747 fake_vmewrite8(bridge
, (u8
*)(buf
+ done
),
748 addr
+ done
, aspace
, cycle
);
752 fake_vmewrite16(bridge
, (u16
*)(buf
+ done
),
753 addr
+ done
, aspace
, cycle
);
759 if (dwidth
== VME_D32
) {
760 count32
= (count
- done
) & ~0x3;
761 while (done
< count32
) {
762 fake_vmewrite32(bridge
, (u32
*)(buf
+ done
),
763 addr
+ done
, aspace
, cycle
);
766 } else if (dwidth
== VME_D16
) {
767 count32
= (count
- done
) & ~0x3;
768 while (done
< count32
) {
769 fake_vmewrite16(bridge
, (u16
*)(buf
+ done
),
770 addr
+ done
, aspace
, cycle
);
773 } else if (dwidth
== VME_D8
) {
774 count32
= (count
- done
);
775 while (done
< count32
) {
776 fake_vmewrite8(bridge
, (u8
*)(buf
+ done
), addr
+ done
,
783 if ((dwidth
== VME_D16
) || (dwidth
== VME_D32
)) {
784 if ((count
- done
) & 0x2) {
785 fake_vmewrite16(bridge
, (u16
*)(buf
+ done
),
786 addr
+ done
, aspace
, cycle
);
791 if ((count
- done
) & 0x1) {
792 fake_vmewrite8(bridge
, (u8
*)(buf
+ done
), addr
+ done
, aspace
,
800 spin_unlock(&image
->lock
);
806 * Perform an RMW cycle on the VME bus.
808 * Requires a previously configured master window, returns final value.
810 static unsigned int fake_master_rmw(struct vme_master_resource
*image
,
811 unsigned int mask
, unsigned int compare
, unsigned int swap
,
817 struct fake_driver
*bridge
;
819 bridge
= image
->parent
->driver_priv
;
821 /* Find the PCI address that maps to the desired VME address */
824 base
= bridge
->masters
[i
].vme_base
;
825 aspace
= bridge
->masters
[i
].aspace
;
826 cycle
= bridge
->masters
[i
].cycle
;
829 spin_lock(&image
->lock
);
831 /* Read existing value */
832 tmp
= fake_vmeread32(bridge
, base
+ offset
, aspace
, cycle
);
835 if ((tmp
&& mask
) == (compare
&& mask
)) {
836 tmp
= tmp
| (mask
| swap
);
837 tmp
= tmp
& (~mask
| swap
);
840 fake_vmewrite32(bridge
, &tmp
, base
+ offset
, aspace
, cycle
);
844 spin_unlock(&image
->lock
);
850 * All 4 location monitors reside at the same base - this is therefore a
851 * system wide configuration.
853 * This does not enable the LM monitor - that should be done when the first
854 * callback is attached and disabled when the last callback is removed.
856 static int fake_lm_set(struct vme_lm_resource
*lm
, unsigned long long lm_base
,
857 u32 aspace
, u32 cycle
)
860 struct vme_bridge
*fake_bridge
;
861 struct fake_driver
*bridge
;
863 fake_bridge
= lm
->parent
;
865 bridge
= fake_bridge
->driver_priv
;
867 mutex_lock(&lm
->mtx
);
869 /* If we already have a callback attached, we can't move it! */
870 for (i
= 0; i
< lm
->monitors
; i
++) {
871 if (bridge
->lm_callback
[i
]) {
872 mutex_unlock(&lm
->mtx
);
873 pr_err("Location monitor callback attached, can't reset\n");
885 mutex_unlock(&lm
->mtx
);
886 pr_err("Invalid address space\n");
890 bridge
->lm_base
= lm_base
;
891 bridge
->lm_aspace
= aspace
;
892 bridge
->lm_cycle
= cycle
;
894 mutex_unlock(&lm
->mtx
);
899 /* Get configuration of the callback monitor and return whether it is enabled
902 static int fake_lm_get(struct vme_lm_resource
*lm
,
903 unsigned long long *lm_base
, u32
*aspace
, u32
*cycle
)
905 struct fake_driver
*bridge
;
907 bridge
= lm
->parent
->driver_priv
;
909 mutex_lock(&lm
->mtx
);
911 *lm_base
= bridge
->lm_base
;
912 *aspace
= bridge
->lm_aspace
;
913 *cycle
= bridge
->lm_cycle
;
915 mutex_unlock(&lm
->mtx
);
917 return bridge
->lm_enabled
;
921 * Attach a callback to a specific location monitor.
923 * Callback will be passed the monitor triggered.
925 static int fake_lm_attach(struct vme_lm_resource
*lm
, int monitor
,
926 void (*callback
)(void *), void *data
)
928 struct vme_bridge
*fake_bridge
;
929 struct fake_driver
*bridge
;
931 fake_bridge
= lm
->parent
;
933 bridge
= fake_bridge
->driver_priv
;
935 mutex_lock(&lm
->mtx
);
937 /* Ensure that the location monitor is configured - need PGM or DATA */
938 if (bridge
->lm_cycle
== 0) {
939 mutex_unlock(&lm
->mtx
);
940 pr_err("Location monitor not properly configured\n");
944 /* Check that a callback isn't already attached */
945 if (bridge
->lm_callback
[monitor
]) {
946 mutex_unlock(&lm
->mtx
);
947 pr_err("Existing callback attached\n");
951 /* Attach callback */
952 bridge
->lm_callback
[monitor
] = callback
;
953 bridge
->lm_data
[monitor
] = data
;
955 /* Ensure that global Location Monitor Enable set */
956 bridge
->lm_enabled
= 1;
958 mutex_unlock(&lm
->mtx
);
964 * Detach a callback function forn a specific location monitor.
966 static int fake_lm_detach(struct vme_lm_resource
*lm
, int monitor
)
970 struct fake_driver
*bridge
;
972 bridge
= lm
->parent
->driver_priv
;
974 mutex_lock(&lm
->mtx
);
976 /* Detach callback */
977 bridge
->lm_callback
[monitor
] = NULL
;
978 bridge
->lm_data
[monitor
] = NULL
;
980 /* If all location monitors disabled, disable global Location Monitor */
982 for (i
= 0; i
< lm
->monitors
; i
++) {
983 if (bridge
->lm_callback
[i
])
988 bridge
->lm_enabled
= 0;
990 mutex_unlock(&lm
->mtx
);
996 * Determine Geographical Addressing
998 static int fake_slot_get(struct vme_bridge
*fake_bridge
)
1003 static void *fake_alloc_consistent(struct device
*parent
, size_t size
,
1006 void *alloc
= kmalloc(size
, GFP_KERNEL
);
1009 *dma
= fake_ptr_to_pci(alloc
);
1014 static void fake_free_consistent(struct device
*parent
, size_t size
,
1015 void *vaddr
, dma_addr_t dma
)
1019 dma_free_coherent(parent, size, vaddr, dma);
1024 * Configure CR/CSR space
1026 * Access to the CR/CSR can be configured at power-up. The location of the
1027 * CR/CSR registers in the CR/CSR address space is determined by the boards
1028 * Geographic address.
1030 * Each board has a 512kB window, with the highest 4kB being used for the
1031 * boards registers, this means there is a fix length 508kB window which must
1032 * be mapped onto PCI memory.
1034 static int fake_crcsr_init(struct vme_bridge
*fake_bridge
)
1037 struct fake_driver
*bridge
;
1039 bridge
= fake_bridge
->driver_priv
;
1041 /* Allocate mem for CR/CSR image */
1042 bridge
->crcsr_kernel
= kzalloc(VME_CRCSR_BUF_SIZE
, GFP_KERNEL
);
1043 bridge
->crcsr_bus
= fake_ptr_to_pci(bridge
->crcsr_kernel
);
1044 if (!bridge
->crcsr_kernel
)
1047 vstat
= fake_slot_get(fake_bridge
);
1049 pr_info("CR/CSR Offset: %d\n", vstat
);
1054 static void fake_crcsr_exit(struct vme_bridge
*fake_bridge
)
1056 struct fake_driver
*bridge
;
1058 bridge
= fake_bridge
->driver_priv
;
1060 kfree(bridge
->crcsr_kernel
);
1064 static int __init
fake_init(void)
1067 struct list_head
*pos
= NULL
, *n
;
1068 struct vme_bridge
*fake_bridge
;
1069 struct fake_driver
*fake_device
;
1070 struct vme_master_resource
*master_image
;
1071 struct vme_slave_resource
*slave_image
;
1072 struct vme_lm_resource
*lm
;
1074 /* We need a fake parent device */
1075 vme_root
= __root_device_register("vme", THIS_MODULE
);
1077 /* If we want to support more than one bridge at some point, we need to
1078 * dynamically allocate this so we get one per device.
1080 fake_bridge
= kzalloc(sizeof(*fake_bridge
), GFP_KERNEL
);
1086 fake_device
= kzalloc(sizeof(*fake_device
), GFP_KERNEL
);
1092 fake_bridge
->driver_priv
= fake_device
;
1094 fake_bridge
->parent
= vme_root
;
1096 fake_device
->parent
= fake_bridge
;
1098 /* Initialize wait queues & mutual exclusion flags */
1099 mutex_init(&fake_device
->vme_int
);
1100 mutex_init(&fake_bridge
->irq_mtx
);
1101 tasklet_init(&fake_device
->int_tasklet
, fake_VIRQ_tasklet
,
1102 (unsigned long) fake_bridge
);
1104 strcpy(fake_bridge
->name
, driver_name
);
1106 /* Add master windows to list */
1107 INIT_LIST_HEAD(&fake_bridge
->master_resources
);
1108 for (i
= 0; i
< FAKE_MAX_MASTER
; i
++) {
1109 master_image
= kmalloc(sizeof(*master_image
), GFP_KERNEL
);
1110 if (!master_image
) {
1114 master_image
->parent
= fake_bridge
;
1115 spin_lock_init(&master_image
->lock
);
1116 master_image
->locked
= 0;
1117 master_image
->number
= i
;
1118 master_image
->address_attr
= VME_A16
| VME_A24
| VME_A32
|
1120 master_image
->cycle_attr
= VME_SCT
| VME_BLT
| VME_MBLT
|
1121 VME_2eVME
| VME_2eSST
| VME_2eSSTB
| VME_2eSST160
|
1122 VME_2eSST267
| VME_2eSST320
| VME_SUPER
| VME_USER
|
1123 VME_PROG
| VME_DATA
;
1124 master_image
->width_attr
= VME_D16
| VME_D32
;
1125 memset(&master_image
->bus_resource
, 0,
1126 sizeof(struct resource
));
1127 master_image
->kern_base
= NULL
;
1128 list_add_tail(&master_image
->list
,
1129 &fake_bridge
->master_resources
);
1132 /* Add slave windows to list */
1133 INIT_LIST_HEAD(&fake_bridge
->slave_resources
);
1134 for (i
= 0; i
< FAKE_MAX_SLAVE
; i
++) {
1135 slave_image
= kmalloc(sizeof(*slave_image
), GFP_KERNEL
);
1140 slave_image
->parent
= fake_bridge
;
1141 mutex_init(&slave_image
->mtx
);
1142 slave_image
->locked
= 0;
1143 slave_image
->number
= i
;
1144 slave_image
->address_attr
= VME_A16
| VME_A24
| VME_A32
|
1145 VME_A64
| VME_CRCSR
| VME_USER1
| VME_USER2
|
1146 VME_USER3
| VME_USER4
;
1147 slave_image
->cycle_attr
= VME_SCT
| VME_BLT
| VME_MBLT
|
1148 VME_2eVME
| VME_2eSST
| VME_2eSSTB
| VME_2eSST160
|
1149 VME_2eSST267
| VME_2eSST320
| VME_SUPER
| VME_USER
|
1150 VME_PROG
| VME_DATA
;
1151 list_add_tail(&slave_image
->list
,
1152 &fake_bridge
->slave_resources
);
1155 /* Add location monitor to list */
1156 INIT_LIST_HEAD(&fake_bridge
->lm_resources
);
1157 lm
= kmalloc(sizeof(*lm
), GFP_KERNEL
);
1162 lm
->parent
= fake_bridge
;
1163 mutex_init(&lm
->mtx
);
1167 list_add_tail(&lm
->list
, &fake_bridge
->lm_resources
);
1169 fake_bridge
->slave_get
= fake_slave_get
;
1170 fake_bridge
->slave_set
= fake_slave_set
;
1171 fake_bridge
->master_get
= fake_master_get
;
1172 fake_bridge
->master_set
= fake_master_set
;
1173 fake_bridge
->master_read
= fake_master_read
;
1174 fake_bridge
->master_write
= fake_master_write
;
1175 fake_bridge
->master_rmw
= fake_master_rmw
;
1176 fake_bridge
->irq_set
= fake_irq_set
;
1177 fake_bridge
->irq_generate
= fake_irq_generate
;
1178 fake_bridge
->lm_set
= fake_lm_set
;
1179 fake_bridge
->lm_get
= fake_lm_get
;
1180 fake_bridge
->lm_attach
= fake_lm_attach
;
1181 fake_bridge
->lm_detach
= fake_lm_detach
;
1182 fake_bridge
->slot_get
= fake_slot_get
;
1183 fake_bridge
->alloc_consistent
= fake_alloc_consistent
;
1184 fake_bridge
->free_consistent
= fake_free_consistent
;
1186 pr_info("Board is%s the VME system controller\n",
1187 (geoid
== 1) ? "" : " not");
1189 pr_info("VME geographical address is set to %d\n", geoid
);
1191 retval
= fake_crcsr_init(fake_bridge
);
1193 pr_err("CR/CSR configuration failed.\n");
1197 retval
= vme_register_bridge(fake_bridge
);
1199 pr_err("Chip Registration failed.\n");
1203 exit_pointer
= fake_bridge
;
1208 fake_crcsr_exit(fake_bridge
);
1211 /* resources are stored in link list */
1212 list_for_each_safe(pos
, n
, &fake_bridge
->lm_resources
) {
1213 lm
= list_entry(pos
, struct vme_lm_resource
, list
);
1218 /* resources are stored in link list */
1219 list_for_each_safe(pos
, n
, &fake_bridge
->slave_resources
) {
1220 slave_image
= list_entry(pos
, struct vme_slave_resource
, list
);
1225 /* resources are stored in link list */
1226 list_for_each_safe(pos
, n
, &fake_bridge
->master_resources
) {
1227 master_image
= list_entry(pos
, struct vme_master_resource
,
1230 kfree(master_image
);
1242 static void __exit
fake_exit(void)
1244 struct list_head
*pos
= NULL
;
1245 struct list_head
*tmplist
;
1246 struct vme_master_resource
*master_image
;
1247 struct vme_slave_resource
*slave_image
;
1249 struct vme_bridge
*fake_bridge
;
1250 struct fake_driver
*bridge
;
1252 fake_bridge
= exit_pointer
;
1254 bridge
= fake_bridge
->driver_priv
;
1256 pr_debug("Driver is being unloaded.\n");
1259 * Shutdown all inbound and outbound windows.
1261 for (i
= 0; i
< FAKE_MAX_MASTER
; i
++)
1262 bridge
->masters
[i
].enabled
= 0;
1264 for (i
= 0; i
< FAKE_MAX_SLAVE
; i
++)
1265 bridge
->slaves
[i
].enabled
= 0;
1268 * Shutdown Location monitor.
1270 bridge
->lm_enabled
= 0;
1272 vme_unregister_bridge(fake_bridge
);
1274 fake_crcsr_exit(fake_bridge
);
1275 /* resources are stored in link list */
1276 list_for_each_safe(pos
, tmplist
, &fake_bridge
->slave_resources
) {
1277 slave_image
= list_entry(pos
, struct vme_slave_resource
, list
);
1282 /* resources are stored in link list */
1283 list_for_each_safe(pos
, tmplist
, &fake_bridge
->master_resources
) {
1284 master_image
= list_entry(pos
, struct vme_master_resource
,
1287 kfree(master_image
);
1290 kfree(fake_bridge
->driver_priv
);
1294 root_device_unregister(vme_root
);
1298 MODULE_PARM_DESC(geoid
, "Set geographical addressing");
1299 module_param(geoid
, int, 0);
1301 MODULE_DESCRIPTION("Fake VME bridge driver");
1302 MODULE_LICENSE("GPL");
1304 module_init(fake_init
);
1305 module_exit(fake_exit
);