From: <he...@us...> - 2005-03-15 23:39:17
|
Update of /cvsroot/gc-linux/linux/drivers/exi In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv515 Modified Files: exi-driver.c exi-hw.c exi-hw.h Log Message: Added some more comments to code. Do not initialize again channels while initializing devices. Rename cmd_lock to select_lock, so it becomes more intuitive. Fix possible race while invoking handlers. Do not touch TCINT related stuff while enabling or disabling TC events. Index: exi-driver.c =================================================================== RCS file: /cvsroot/gc-linux/linux/drivers/exi/exi-driver.c,v retrieving revision 1.7 retrieving revision 1.8 diff -u -d -r1.7 -r1.8 --- exi-driver.c 13 Mar 2005 21:49:16 -0000 1.7 +++ exi-driver.c 15 Mar 2005 23:39:00 -0000 1.8 @@ -351,13 +351,12 @@ if (!test_and_set_bit(1, &exi_running)) { retval = exi_hw_init(); if (retval) - goto err_irq_init; + goto err_hw_init; } - /* initialize channels and devices */ + /* initialize devices */ for (channel = 0; channel < EXI_MAX_CHANNELS; ++channel) { exi_channel = to_exi_channel(channel); - exi_channel_init(exi_channel, channel); for (device = 0; device < EXI_DEVICES_PER_CHANNEL; ++device) { exi_device = &exi_devices[channel][device]; exi_device_init(exi_device, channel, device); @@ -387,7 +386,7 @@ device_unregister(&exi_bus_devices[channel]); } exi_hw_exit(); -err_irq_init: +err_hw_init: return retval; } Index: exi-hw.c =================================================================== RCS file: /cvsroot/gc-linux/linux/drivers/exi/exi-hw.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- exi-hw.c 14 Mar 2005 19:54:54 -0000 1.5 +++ exi-hw.c 15 Mar 2005 23:39:01 -0000 1.6 @@ -89,27 +89,27 @@ [0] = { .channel = 0, .lock = SPIN_LOCK_UNLOCKED, - .cmd_lock = SPIN_LOCK_UNLOCKED, .io_lock = SPIN_LOCK_UNLOCKED, .io_base = EXI_IO_BASE(0), + .select_lock = SPIN_LOCK_UNLOCKED, .wait_queue = __WAIT_QUEUE_HEAD_INITIALIZER( exi_channels[0].wait_queue), }, [1] = { .channel = 1, .lock = SPIN_LOCK_UNLOCKED, - .cmd_lock = SPIN_LOCK_UNLOCKED, .io_lock = SPIN_LOCK_UNLOCKED, .io_base = EXI_IO_BASE(1), + .select_lock = SPIN_LOCK_UNLOCKED, .wait_queue = __WAIT_QUEUE_HEAD_INITIALIZER( exi_channels[1].wait_queue), }, [2] = { .channel = 2, .lock = SPIN_LOCK_UNLOCKED, - .cmd_lock = SPIN_LOCK_UNLOCKED, .io_lock = SPIN_LOCK_UNLOCKED, .io_base = EXI_IO_BASE(2), + .select_lock = SPIN_LOCK_UNLOCKED, .wait_queue = __WAIT_QUEUE_HEAD_INITIALIZER( exi_channels[2].wait_queue), }, @@ -160,7 +160,7 @@ exi_channel->channel = channel; spin_lock_init(&exi_channel->lock); - spin_lock_init(&exi_channel->cmd_lock); + spin_lock_init(&exi_channel->select_lock); spin_lock_init(&exi_channel->io_lock); exi_channel->io_base = EXI_IO_BASE(channel); init_waitqueue_head(&exi_channel->wait_queue); @@ -406,16 +406,14 @@ { struct exi_channel *exi_channel = cmd->exi_channel; struct exi_device *exi_device; - //struct exi_driver *exi_driver; BUG_ON(cmd->data == NULL); BUG_ON(exi_is_selected(exi_channel)); - spin_lock(&exi_channel->cmd_lock); + spin_lock(&exi_channel->select_lock); /* cmd->data contains the device to select */ exi_device = cmd->data; - //exi_driver = to_exi_driver(exi_device->dev.driver); exi_channel->device_selected = exi_device; exi_channel->flags |= EXI_SELECTED; @@ -443,7 +441,7 @@ exi_channel->flags &= ~EXI_SELECTED; exi_channel->device_selected = NULL; - spin_unlock(&exi_channel->cmd_lock); + spin_unlock(&exi_channel->select_lock); } /* @@ -507,13 +505,14 @@ /* * |_______________|______...______|_______________| DMA alignment - * <----------------- len -----------------> + * <--pre_len--><---- len -----><-post_len-> * +-----------+------...------+-----------+ * | pre_data | data | post_data | * | non-DMA | DMA | non-DMA | * +-----------+------...------+-----------+ * < 32 bytes N*32 bytes < 32 bytes * |<--------->|<-----...----->|<--------->| + * <-------------- cmd->len ---------------> */ pre_data = data; @@ -816,13 +815,14 @@ static inline int exi_trigger_event(struct exi_channel *exi_channel, unsigned int event_id) { - struct exi_event_handler *event; + exi_event_handler_t handler; + int retval = 0; - event = &exi_channel->events[event_id]; - if (event->handler) { - return event->handler(exi_channel, event_id, event->data); + handler = exi_channel->events[event_id].handler; + if (handler) { + retval = handler(exi_channel, event_id, event->data); } - return 0; + return retval; } /* @@ -941,7 +941,7 @@ writel(csr | (EXI_CSR_EXTIN | EXI_CSR_EXTINMASK), csr_reg); break; case EXI_EVENT_TC: - writel(csr | (EXI_CSR_TCINT | EXI_CSR_TCINTMASK), csr_reg); + //writel(csr | (EXI_CSR_TCINT | EXI_CSR_TCINTMASK), csr_reg); break; case EXI_EVENT_IRQ: writel(csr | (EXI_CSR_EXIINT | EXI_CSR_EXIINTMASK), csr_reg); @@ -970,7 +970,7 @@ writel((csr | EXI_CSR_EXTIN) & ~EXI_CSR_EXTINMASK, csr_reg); break; case EXI_EVENT_TC: - writel((csr | EXI_CSR_TCINT) & ~EXI_CSR_TCINTMASK, csr_reg); + //writel((csr | EXI_CSR_TCINT) & ~EXI_CSR_TCINTMASK, csr_reg); break; case EXI_EVENT_IRQ: writel((csr | EXI_CSR_EXIINT) & ~EXI_CSR_EXIINTMASK, csr_reg); @@ -1070,7 +1070,7 @@ } /* - * Pseudo-Internal. Initialize + * Pseudo-Internal. Initialize basic channel structures and hardware. */ int exi_hw_init(void) { @@ -1085,6 +1085,7 @@ exi_channel_init(exi_channel, channel); } + /* calm down the hardware and allow external insertions */ exi_quiesce_all_channels(EXI_CSR_EXTINMASK); /* register the exi interrupt handler */ @@ -1097,7 +1098,7 @@ } /* - * Pseudo-Internal. + * Pseudo-Internal. */ void exi_hw_exit(void) { Index: exi-hw.h =================================================================== RCS file: /cvsroot/gc-linux/linux/drivers/exi/exi-hw.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- exi-hw.h 14 Mar 2005 19:47:10 -0000 1.2 +++ exi-hw.h 15 Mar 2005 23:39:01 -0000 1.3 @@ -88,28 +88,27 @@ struct exi_event_handler { exi_event_handler_t handler; void *data; - unsigned int channel_mask; /* channels used by the handler */ + unsigned int channel_mask; /* channels used by handler */ }; /* * This structure represents an exi channel. */ struct exi_channel { - spinlock_t lock; + spinlock_t lock; /* misc channel lock */ int channel; unsigned long flags; #define EXI_SELECTED (1<<0) #define EXI_DMABUSY (1<<1) - spinlock_t io_lock; + spinlock_t io_lock; /* serializes access to CSR */ void __iomem *io_base; + spinlock_t select_lock; /* held while using channel */ struct exi_device *device_selected; wait_queue_head_t wait_queue; - spinlock_t cmd_lock; - struct exi_command *dma_cmd; struct exi_command post_cmd; |