From: Albert H. <he...@us...> - 2005-11-07 21:34:29
|
Update of /cvsroot/gc-linux/linux/include/linux In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15252/include/linux Modified Files: exi.h Log Message: Another exi layer update. Now channel allocation is independent of channel selection. Channels are allocated by "take" and deallocated by "give". "select", "deselect" and "transfer" operations are available _after_ channel allocation. Transfers can now be done with channel deselected (required for SD cards). exi drivers can now be simplified a lot more. ksoftirqd will need to run at lower prio to get good performance (try "renice -1 -p 2"). Index: exi.h =================================================================== RCS file: /cvsroot/gc-linux/linux/include/linux/exi.h,v retrieving revision 1.13 retrieving revision 1.14 diff -u -d -r1.13 -r1.14 --- exi.h 25 Sep 2005 19:55:50 -0000 1.13 +++ exi.h 7 Nov 2005 21:34:16 -0000 1.14 @@ -135,6 +135,7 @@ extern int exi_event_register(struct exi_channel *exi_channel, unsigned int event_id, + struct exi_device *exi_device, exi_event_handler_t handler, void *data, unsigned int channel_mask); extern int exi_event_unregister(struct exi_channel *exi_channel, @@ -152,13 +153,17 @@ #define EXI_OP_WRITE (0x01<<2) /* same as in EXIxCR */ #define EXI_OP_READWRITE (0x02<<2) /* same as in EXIxCR */ -#define EXI_OP_SELECT 0x0100 -#define EXI_OP_DESELECT 0x0200 +#define EXI_OP_TAKE 0x0100 +#define EXI_OP_GIVE 0x0200 +#define EXI_OP_SELECT 0x0400 +#define EXI_OP_DESELECT 0x0800 + #define EXI_OP_NOP -1 unsigned long flags; -#define EXI_CMD_NODMA (1<<0) -#define EXI_CMD_IDI (1<<1) +#define EXI_CMD_NOWAIT (1<<0) +#define EXI_CMD_NODMA (1<<1) +#define EXI_CMD_IDI (1<<2) void *data; size_t len; @@ -171,13 +176,17 @@ void (*done)(struct exi_command *cmd); struct exi_channel *exi_channel; + struct exi_device *exi_device; }; +#include "../drivers/exi/exi-hw.h" + static inline void exi_op_basic(struct exi_command *cmd, struct exi_channel *exi_channel) { memset(cmd, 0, sizeof(*cmd)); cmd->exi_channel = exi_channel; + cmd->exi_device = exi_channel_owner(exi_channel); } static inline void exi_op_nop(struct exi_command *cmd, @@ -187,12 +196,27 @@ cmd->opcode = EXI_OP_NOP; } +static inline void exi_op_take(struct exi_command *cmd, + struct exi_device *exi_device) +{ + exi_op_basic(cmd, exi_device->exi_channel); + cmd->opcode = EXI_OP_TAKE; + cmd->exi_device = exi_device; +} + +static inline void exi_op_give(struct exi_command *cmd, + struct exi_channel *exi_channel) +{ + exi_op_basic(cmd, exi_channel); + cmd->opcode = EXI_OP_GIVE; +} + static inline void exi_op_select(struct exi_command *cmd, struct exi_device *exi_device) { exi_op_basic(cmd, exi_device->exi_channel); cmd->opcode = EXI_OP_SELECT; - cmd->data = exi_device; + cmd->exi_device = exi_device; } static inline void exi_op_deselect(struct exi_command *cmd, @@ -217,7 +241,6 @@ * EXpansion Interface interfaces. * */ -#include "../drivers/exi/exi-hw.h" /* * Raw. @@ -239,14 +262,31 @@ * Standard. */ -int exi_select(struct exi_device *exi_device); +int exi_take(struct exi_device *exi_device, int wait); +int exi_give(struct exi_device *exi_device); +void exi_select(struct exi_device *exi_device); void exi_deselect(struct exi_channel *exi_channel); void exi_transfer(struct exi_channel *exi_channel, void *data, size_t len, int opcode, unsigned long flags); -static inline int exi_dev_select(struct exi_device *exi_device) +static inline int exi_dev_take(struct exi_device *exi_device) { - return exi_select(exi_device); + return exi_take(exi_device, 1); +} + +static inline int exi_dev_try_take(struct exi_device *exi_device) +{ + return exi_take(exi_device, 0); +} + +static inline int exi_dev_give(struct exi_device *exi_device) +{ + return exi_give(exi_device); +} + +static inline void exi_dev_select(struct exi_device *exi_device) +{ + exi_select(exi_device); } static inline void exi_dev_deselect(struct exi_device *exi_device) @@ -279,76 +319,5 @@ return freq; } - - - -/* - * Compatibility layer with old EXI_LITE. - */ - -#ifdef CONFIG_EXI_LITE2_COMPAT - -#ifndef EXI_LITE -#define EXI_LITE 2 - -extern unsigned long exi_running; - -static inline int exi_lite_init(void) -{ - int retval = 0; - - if (!test_and_set_bit(1, &exi_running)) { - retval = exi_hw_init("exi-lite"); - } - return retval; -} - -static inline void exi_lite_exit(void) -{ - exi_hw_exit(); -} - -static inline int exi_lite_select(int channel, int device, int freq) -{ - struct exi_channel *exi_channel = to_exi_channel(channel); - struct exi_device *exi_device = exi_get_exi_device(exi_channel, device); - return exi_select(exi_device); -} - -static inline void exi_lite_deselect(int channel) -{ - struct exi_channel *exi_channel = to_exi_channel(channel); - exi_deselect(exi_channel); -} - -static inline void exi_lite_read(int channel, void *data, size_t len) -{ - exi_transfer(to_exi_channel(channel), data, len, EXI_OP_READ, 0); -} - -static inline void exi_lite_write(int channel, void *data, size_t len) -{ - exi_transfer(to_exi_channel(channel), data, len, EXI_OP_WRITE, 0); -} - -static inline int exi_lite_register_event(int channel, int event_id, - exi_event_handler_t handler, - void *dev, unsigned int channel_mask) -{ - return exi_event_register(to_exi_channel(channel), - (unsigned int)event_id, - handler, dev, channel_mask); -} - -static inline int exi_lite_unregister_event(int channel, int event_id) -{ - return exi_event_unregister(to_exi_channel(channel), - (unsigned int)event_id); -} - -#endif /* EXI_LITE */ - -#endif /* CONFIG_EXI_LITE2_COMPAT */ - #endif /* __EXI_H */ |