diff options
Diffstat (limited to 'drivers/staging/vme/bridges/vme_ca91cx42.c')
-rw-r--r-- | drivers/staging/vme/bridges/vme_ca91cx42.c | 78 |
1 files changed, 15 insertions, 63 deletions
diff --git a/drivers/staging/vme/bridges/vme_ca91cx42.c b/drivers/staging/vme/bridges/vme_ca91cx42.c index 2810d80fa0e..74d54bb3f8e 100644 --- a/drivers/staging/vme/bridges/vme_ca91cx42.c +++ b/drivers/staging/vme/bridges/vme_ca91cx42.c @@ -53,9 +53,6 @@ struct mutex vme_int; /* * Only one VME interrupt can be * generated at a time, provide locking */ -struct mutex vme_irq; /* Locking for VME irq callback configuration */ - - static char driver_name[] = "vme_ca91cx42"; @@ -157,23 +154,13 @@ static u32 ca91cx42_LERR_irqhandler(void) static u32 ca91cx42_VIRQ_irqhandler(int stat) { int vec, i, serviced = 0; - void (*call)(int, int, void *); - void *priv_data; for (i = 7; i > 0; i--) { if (stat & (1 << i)) { vec = ioread32(ca91cx42_bridge->base + CA91CX42_V_STATID[i]) & 0xff; - call = ca91cx42_bridge->irq[i - 1].callback[vec].func; - priv_data = - ca91cx42_bridge->irq[i - 1].callback[vec].priv_data; - - if (call != NULL) - call(i, vec, priv_data); - else - printk("Spurilous VME interrupt, level:%x, " - "vector:%x\n", i, vec); + vme_irq_handler(ca91cx42_bridge, i, vec); serviced |= (1 << i); } @@ -234,6 +221,8 @@ static int ca91cx42_irq_init(struct vme_bridge *bridge) /* Initialise list for VME bus errors */ INIT_LIST_HEAD(&(bridge->vme_errors)); + mutex_init(&(bridge->irq_mtx)); + /* Disable interrupts from PCI to VME */ iowrite32(0, bridge->base + VINT_EN); @@ -281,66 +270,31 @@ static void ca91cx42_irq_exit(struct pci_dev *pdev) /* * Set up an VME interrupt */ -int ca91cx42_request_irq(int level, int statid, - void (*callback)(int level, int vector, void *priv_data), - void *priv_data) +void ca91cx42_irq_set(int level, int state, int sync) + { + struct pci_dev *pdev; u32 tmp; - mutex_lock(&(vme_irq)); - - if (ca91cx42_bridge->irq[level - 1].callback[statid].func) { - mutex_unlock(&(vme_irq)); - printk("VME Interrupt already taken\n"); - return -EBUSY; - } - - - ca91cx42_bridge->irq[level - 1].count++; - ca91cx42_bridge->irq[level - 1].callback[statid].priv_data = priv_data; - ca91cx42_bridge->irq[level - 1].callback[statid].func = callback; - /* Enable IRQ level */ tmp = ioread32(ca91cx42_bridge->base + LINT_EN); - tmp |= CA91CX42_LINT_VIRQ[level]; - iowrite32(tmp, ca91cx42_bridge->base + LINT_EN); - mutex_unlock(&(vme_irq)); - - return 0; -} - -/* - * Free VME interrupt - */ -void ca91cx42_free_irq(int level, int statid) -{ - u32 tmp; - struct pci_dev *pdev; - - mutex_lock(&(vme_irq)); - - ca91cx42_bridge->irq[level - 1].count--; - - /* Disable IRQ level if no more interrupts attached at this level*/ - if (ca91cx42_bridge->irq[level - 1].count == 0) { - tmp = ioread32(ca91cx42_bridge->base + LINT_EN); + if (state == 0) tmp &= ~CA91CX42_LINT_VIRQ[level]; - iowrite32(tmp, ca91cx42_bridge->base + LINT_EN); + else + tmp |= CA91CX42_LINT_VIRQ[level]; + iowrite32(tmp, ca91cx42_bridge->base + LINT_EN); + + if ((state == 0) && (sync != 0)) { pdev = container_of(ca91cx42_bridge->parent, struct pci_dev, dev); synchronize_irq(pdev->irq); } - - ca91cx42_bridge->irq[level - 1].callback[statid].func = NULL; - ca91cx42_bridge->irq[level - 1].callback[statid].priv_data = NULL; - - mutex_unlock(&(vme_irq)); } -int ca91cx42_generate_irq(int level, int statid) +int ca91cx42_irq_generate(int level, int statid) { u32 tmp; @@ -1064,7 +1018,6 @@ static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id) init_waitqueue_head(&dma_queue); init_waitqueue_head(&iack_queue); mutex_init(&(vme_int)); - mutex_init(&(vme_irq)); mutex_init(&(vme_rmw)); ca91cx42_bridge->parent = &(pdev->dev); @@ -1181,9 +1134,8 @@ static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id) ca91cx42_bridge->dma_list_exec = ca91cx42_dma_list_exec; ca91cx42_bridge->dma_list_empty = ca91cx42_dma_list_empty; #endif - ca91cx42_bridge->request_irq = ca91cx42_request_irq; - ca91cx42_bridge->free_irq = ca91cx42_free_irq; - ca91cx42_bridge->generate_irq = ca91cx42_generate_irq; + ca91cx42_bridge->irq_set = ca91cx42_irq_set; + ca91cx42_bridge->irq_generate = ca91cx42_irq_generate; #if 0 ca91cx42_bridge->lm_set = ca91cx42_lm_set; ca91cx42_bridge->lm_get = ca91cx42_lm_get; |