提交 29848ac9 编写于 作者: M Martyn Welch 提交者: Greg Kroah-Hartman

Staging: vme: Enable drivers to handle more than one bridge

At the moment the vme bridge drivers are written in a way that only
allows them to support one bridge at a time. Modify the drivers to
enable more than one bridge to be present per board.
Signed-off-by: NMartyn Welch <martyn.welch@ge.com>
Signed-off-by: NGreg Kroah-Hartman <gregkh@suse.de>
上级 4f723df4
...@@ -47,7 +47,6 @@ Bridge Support ...@@ -47,7 +47,6 @@ Bridge Support
Tempe (tsi148) Tempe (tsi148)
-------------- --------------
- Driver can currently only support a single bridge.
- 2eSST Broadcast mode. - 2eSST Broadcast mode.
- Mailboxes unsupported. - Mailboxes unsupported.
- Improve error detection. - Improve error detection.
...@@ -58,7 +57,6 @@ Tempe (tsi148) ...@@ -58,7 +57,6 @@ Tempe (tsi148)
Universe II (ca91c142) Universe II (ca91c142)
---------------------- ----------------------
- Driver can currently only support a single bridge.
- DMA unsupported. - DMA unsupported.
- RMW transactions unsupported. - RMW transactions unsupported.
- Location Monitors unsupported. - Location Monitors unsupported.
......
...@@ -37,6 +37,22 @@ ...@@ -37,6 +37,22 @@
#define CA91C142_MAX_DMA 1 /* Max DMA Controllers */ #define CA91C142_MAX_DMA 1 /* Max DMA Controllers */
#define CA91C142_MAX_MAILBOX 4 /* Max Mail Box registers */ #define CA91C142_MAX_MAILBOX 4 /* Max Mail Box registers */
/* Structure used to hold driver specific information */
struct ca91cx42_driver {
void *base; /* Base Address of device registers */
wait_queue_head_t dma_queue;
wait_queue_head_t iack_queue;
wait_queue_head_t mbox_queue;
void (*lm_callback[4])(int); /* Called in interrupt handler */
void *crcsr_kernel;
dma_addr_t crcsr_bus;
struct mutex vme_rmw; /* Only one RMW cycle at a time */
struct mutex vme_int; /*
* Only one VME interrupt can be
* generated at a time, provide locking
*/
};
/* See Page 2-77 in the Universe User Manual */ /* See Page 2-77 in the Universe User Manual */
struct ca91cx42_dma_descriptor { struct ca91cx42_dma_descriptor {
unsigned int dctl; /* DMA Control */ unsigned int dctl; /* DMA Control */
......
...@@ -33,6 +33,22 @@ ...@@ -33,6 +33,22 @@
#define TSI148_MAX_MAILBOX 4 /* Max Mail Box registers */ #define TSI148_MAX_MAILBOX 4 /* Max Mail Box registers */
#define TSI148_MAX_SEMAPHORE 8 /* Max Semaphores */ #define TSI148_MAX_SEMAPHORE 8 /* Max Semaphores */
/* Structure used to hold driver specific information */
struct tsi148_driver {
void *base; /* Base Address of device registers */
wait_queue_head_t dma_queue[2];
wait_queue_head_t iack_queue;
void (*lm_callback[4])(int); /* Called in interrupt handler */
void *crcsr_kernel;
dma_addr_t crcsr_bus;
struct vme_master_resource *flush_image;
struct mutex vme_rmw; /* Only one RMW cycle at a time */
struct mutex vme_int; /*
* Only one VME interrupt can be
* generated at a time, provide locking
*/
};
/* /*
* Layout of a DMAC Linked-List Descriptor * Layout of a DMAC Linked-List Descriptor
* *
......
...@@ -993,7 +993,7 @@ void vme_irq_handler(struct vme_bridge *bridge, int level, int statid) ...@@ -993,7 +993,7 @@ void vme_irq_handler(struct vme_bridge *bridge, int level, int statid)
EXPORT_SYMBOL(vme_irq_handler); EXPORT_SYMBOL(vme_irq_handler);
int vme_irq_request(struct device *dev, int level, int statid, int vme_irq_request(struct device *dev, int level, int statid,
void (*callback)(int level, int vector, void *priv_data), void (*callback)(int, int, void *),
void *priv_data) void *priv_data)
{ {
struct vme_bridge *bridge; struct vme_bridge *bridge;
...@@ -1027,7 +1027,7 @@ int vme_irq_request(struct device *dev, int level, int statid, ...@@ -1027,7 +1027,7 @@ int vme_irq_request(struct device *dev, int level, int statid,
bridge->irq[level - 1].callback[statid].func = callback; bridge->irq[level - 1].callback[statid].func = callback;
/* Enable IRQ level */ /* Enable IRQ level */
bridge->irq_set(level, 1, 1); bridge->irq_set(bridge, level, 1, 1);
mutex_unlock(&(bridge->irq_mtx)); mutex_unlock(&(bridge->irq_mtx));
...@@ -1061,7 +1061,7 @@ void vme_irq_free(struct device *dev, int level, int statid) ...@@ -1061,7 +1061,7 @@ void vme_irq_free(struct device *dev, int level, int statid)
/* Disable IRQ level if no more interrupts attached at this level*/ /* Disable IRQ level if no more interrupts attached at this level*/
if (bridge->irq[level - 1].count == 0) if (bridge->irq[level - 1].count == 0)
bridge->irq_set(level, 0, 1); bridge->irq_set(bridge, level, 0, 1);
bridge->irq[level - 1].callback[statid].func = NULL; bridge->irq[level - 1].callback[statid].func = NULL;
bridge->irq[level - 1].callback[statid].priv_data = NULL; bridge->irq[level - 1].callback[statid].priv_data = NULL;
...@@ -1090,7 +1090,7 @@ int vme_irq_generate(struct device *dev, int level, int statid) ...@@ -1090,7 +1090,7 @@ int vme_irq_generate(struct device *dev, int level, int statid)
return -EINVAL; return -EINVAL;
} }
return bridge->irq_generate(level, statid); return bridge->irq_generate(bridge, level, statid);
} }
EXPORT_SYMBOL(vme_irq_generate); EXPORT_SYMBOL(vme_irq_generate);
...@@ -1303,7 +1303,7 @@ int vme_slot_get(struct device *bus) ...@@ -1303,7 +1303,7 @@ int vme_slot_get(struct device *bus)
return -EINVAL; return -EINVAL;
} }
return bridge->slot_get(); return bridge->slot_get(bridge);
} }
EXPORT_SYMBOL(vme_slot_get); EXPORT_SYMBOL(vme_slot_get);
......
...@@ -113,7 +113,7 @@ struct vme_bridge { ...@@ -113,7 +113,7 @@ struct vme_bridge {
/* Bridge Info - XXX Move to private structure? */ /* Bridge Info - XXX Move to private structure? */
struct device *parent; /* Generic device struct (pdev->dev for PCI) */ struct device *parent; /* Generic device struct (pdev->dev for PCI) */
void *base; /* Base Address of device registers */ void *driver_priv; /* Private pointer for the bridge driver */
struct device dev[VME_SLOTS_MAX]; /* Device registered with struct device dev[VME_SLOTS_MAX]; /* Device registered with
* device model on VME bus * device model on VME bus
...@@ -152,8 +152,8 @@ struct vme_bridge { ...@@ -152,8 +152,8 @@ struct vme_bridge {
int (*dma_list_empty) (struct vme_dma_list *); int (*dma_list_empty) (struct vme_dma_list *);
/* Interrupt Functions */ /* Interrupt Functions */
void (*irq_set) (int, int, int); void (*irq_set) (struct vme_bridge *, int, int, int);
int (*irq_generate) (int, int); int (*irq_generate) (struct vme_bridge *, int, int);
/* Location monitor functions */ /* Location monitor functions */
int (*lm_set) (struct vme_lm_resource *, unsigned long long, int (*lm_set) (struct vme_lm_resource *, unsigned long long,
...@@ -164,7 +164,7 @@ struct vme_bridge { ...@@ -164,7 +164,7 @@ struct vme_bridge {
int (*lm_detach) (struct vme_lm_resource *, int); int (*lm_detach) (struct vme_lm_resource *, int);
/* CR/CSR space functions */ /* CR/CSR space functions */
int (*slot_get) (void); int (*slot_get) (struct vme_bridge *);
/* Use standard master read and write functions to access CR/CSR */ /* Use standard master read and write functions to access CR/CSR */
#if 0 #if 0
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册