[SPAM] 出口贸易业务
你好: 我司可优惠代办贸促会证明书,品质证,健康证等各类CIQ证书,CO产地证.普惠证(FA,FE, FF,亚太,中巴)等各类清关证书。提供大小核销单(出口报关单).厂家可合作 退税单‘贴息单 代理商检 , 深圳进出口报关等业务 如有业务需要可来电咨询:张先生(业务经理) 传真:0755--25401451 联系电话:0755--25420177手机:13686868548 QQ:122062143 邮箱:szyongdongjia...@163.com -- ___ spi-devel-general mailing list spi-devel-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/spi-devel-general
Re: [spi-devel-general] [PATCH v4 1/2] spi: implemented driver for Cirrus EP93xx SPI controller
On Tue, Apr 20, 2010 at 05:16:10PM -0500, H Hartley Sweeten wrote: On Tuesday, April 20, 2010 8:12 AM, Mika Westerberg wrote: This patch adds an SPI master driver for the Cirrus EP93xx SPI controller found in EP93xx chips (EP9301, EP9302, EP9307, EP9312 and EP9315). Signed-off-by: Mika Westerberg mika.westerb...@iki.fi Mika, I discovered one gotcha with this driver. Bear with me through this... 1. ep93xx_spi_process_message is called by the workqueue worker function to handle a spi_message queued in by the ep93xx_spi_transfer function. Before starting the actual transfer the chip select to the device is asserted. 2. ep93xx_spi_process_transfer processes each transfer in the spi_message, one at a time, and does a wait_for_completion on each transfer. 3. When the entire spi_message has been transferred the chip select to the device is deasserted. Yes. There is possibility that last transfer -cs_change is set which can be used by SPI controller drivers to keep the chip selected in case next message is going to the same device. However, I haven't implemented that as it is optional (but trivial to add afterwards). The problem is if a hardware design uses the SFRM1 pin as part of the chip select logic. The EP93xx User's Guide states that the SFRMOUT signal behaves as a slave Select in Motorola SPI mode. This signal behaves differently depending on the SPI_MODE_* used. Modes 0 and 2: SFRMOUT is forced HIGH during idle periods. Start of transmission, SFRMOUT is driven LOW. Single word transmission, SFRMOUT is returned to its idle HIGH state one SCLKOUT period after the last bit has been captured. Back-to-back transmissions, SFRMOUT signal is pulsed HIGH between each data word transfer. On completion the SFRMOUT pin returns to its idle HIGH state one SCLKOUT period after the last bit has been captured. Modes 1 and 3: SFRMOUT is forced HIGH during idle periods. Start of transmission, SFRMOUT is driven LOW. Single word transmission, SFRMOUT is returned to its idle HIGH state one SCLKOUT period after the last bit has been captured. Back-to-back transmissions, SFRMOUT signal is held LOW between each data word transfer. On completion the SFRMOUT pin returns to its idle HIGH state one SCLKOUT period after the last bit has been captured. So, since each transfer does a wait_for_completion, all the data is transmitted which causes the SFRMOUT pin to go HIGH between each transfer in the message. Yes, unfortunately. SFRMOUT cannot be software controlled so it is not suitable for general purpose chipselect. This was the sole purpose of using GPIO lines for chipselects. For devices like the sst25lf040a SPI Flash on the EDB93xx boards this causes a problem. To read data from that device you need to send a two part message. The first part is a write transfer with the one byte command and three byte address. This is then followed by a read transfer to get the data. But since the SFRMOUT pin goes high this ends the command. The driver Ryan and I worked on actually does work with the sst25lf040a on the EDB93xx boards. But now that I know what the issue is, it was actually a race condition. Sometimes it worked and sometimes it didn't... I would think the Sim.One board (Martin?) would have the same issue with the mmc card since that design uses the SFRMOUT pin directly for the chip select. Is there anyway to keep the transfers going in a muiltipart message? I'm not exactly sure but polling mode sounds something that could work around that. It just need to be sure that it transmits continuously to keep the SFRMOUT asserted. You could try v3 of the driver with: # modprobe ep93xx-spi transfer_method=0 and see if it works there. An alternative would be that interrupt handler schedules tasklet which then takes next transfer immediately once current transfer is finished. Thanks, MW -- ___ spi-devel-general mailing list spi-devel-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/spi-devel-general
Re: [spi-devel-general] [PATCH v4 1/2] spi: implemented driver for Cirrus EP93xx SPI controller
On Tue, Apr 20, 2010 at 08:52:26PM -0500, H Hartley Sweeten wrote: On Tuesday, April 20, 2010 6:10 PM, Martin Guy wrote: I have noticed on card insertion, the last line of: mmc0: problem reading switch capabilities, performance might suffer. mmc0: host does not support reading read-only switch. assuming write-enable. mmc0: new SD card on SPI mmcblk0: mmc0: SD952 MiB mmcblk0: p1 p2 p4 mmcblk0: retrying using single block read That message might be related to the SFRM1 line being deasserted. This message comes, depending on the card you are using. It is easily reproduced with following command: # fdisk -l Problem there seems to be that fdisk (and also part of block layer that reads partition table) seeks to the end of the disk and reads last block. I remember reading some mail thread about the matter and it could be that some cards do read-ahead which causes the response message to return failure (address error as a response to STOP message which is completely bogus). You can enable MMC debugging and see if this is the case with your card also. I actually debugged this further some time ago and after failure if card status register is read, there is no failure at all (card is in correct state). You could try cutting the trace going to pin 1 (CS pin) of the mmc socket and jumpering it to one of the EGPIO pins on JP15 (the LCD header) or JP16 (the keypad header). You will of course need to modify your platform init to use the new chip select line. and the SDHC cards I have don't work at all, spewing tons of: mmcblk0: error -38 sending status comand mmcblk0: error -38 sending read/write command, response 0x4, card status 0xff04 end_request: I/O error, dev mmcblk0, sector 7744509 I haven't seen those error messages before. Of course I don't have any SDHC cards... ;-) With my TS-7260 board, SDHC cards work (but it uses GPIO lines). MW -- ___ spi-devel-general mailing list spi-devel-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/spi-devel-general
Re: [spi-devel-general] [PATCH v4 1/2] spi: implemented driver for Cirrus EP93xx SPI controller
On Tue, Apr 20, 2010 at 12:24:26PM -0500, H Hartley Sweeten wrote: On Tuesday, April 20, 2010 8:12 AM, Mika Westerberg wrote: This patch adds an SPI master driver for the Cirrus EP93xx SPI controller found in EP93xx chips (EP9301, EP9302, EP9307, EP9312 and EP9315). Signed-off-by: Mika Westerberg mika.westerb...@iki.fi Mika, I'm still looking this over but I have one quick comment. +/** + * ep93xx_spi_select_device() - select given SPI device + * @espi: ep93xx SPI controller struct + * @spi: SPI device to select + * + * Function asserts chipselect line as specified in @spi-chip_select in board + * specific manner. + * + * Note that this function is called from a thread context and can sleep. + */ +static inline void ep93xx_spi_select_device(const struct ep93xx_spi *espi, + struct spi_device *spi) +{ + if (espi-cs_control) + espi-cs_control(spi, !!(spi-mode SPI_CS_HIGH)); +} + +/** + * ep93xx_spi_deselect_device() - deselects given SPI device + * @espi: ep93xx SPI controller struct + * @spi: SPI device to deselect + * + * Function deasserts chipselect line as specified in @spi-chip_select in board + * specific manner. + * + * Note that this function is called from a thread context and can sleep. + */ +static inline void ep93xx_spi_deselect_device(const struct ep93xx_spi *espi, + struct spi_device *spi) +{ + if (espi-cs_control) + espi-cs_control(spi, !(spi-mode SPI_CS_HIGH)); +} These two functions can be combined. /** * ep93xx_spi_chip_select() - select/deselect a given SPI device * @espi: ep93xx SPI controller struct * @spi: SPI device to select * @assert: flag to assert the chip select line * * Note that this function is called from a thread context and can sleep. */ static void ep93xx_spi_chip_select(const struct ep93xx_spi *espi, struct spi_device *spi, int assert) { int value = (spi-mode SPI_CS_HIGH) ? !!assert : !assert; if (espi-cs_control) espi-cs_control(spi, value); } Then just do: ep93xx_spi_select_device(espi, msg-spi, 1); /* assert the spi chip select */ ep93xx_spi_select_device(espi, msg-spi, 0); /* deassert the spi chip select */ I think it is more readable to do: ep93xx_spi_select_device(espi, msg-spi); and ep93xx_spi_deselect_device(espi, msg-spi); It can be seen from the function names what we are doing. Thanks, MW -- ___ spi-devel-general mailing list spi-devel-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/spi-devel-general
Re: [spi-devel-general] [PATCH v4 1/2] spi: implemented driver for Cirrus EP93xx SPI controller
On Tue, Apr 20, 2010 at 08:52:26PM -0500, H Hartley Sweeten wrote: On Tuesday, April 20, 2010 6:10 PM, Martin Guy wrote: Not easily, but it seems a likely cause. To prevent card deselection mid-message I think we would need to handle multi-transfer messages by making the start of transfers 2..N continuous with the end of transfers 1..N-1 instead of draining the reply from each one before starting the next. Am I on the right track? Yes. I'm just not sure how to implement this. I made a hack that allows transfer handler to continue to the next transfer directly if there is no special per transfer settings in the message. Could you try that out and report whether SFRMOUT works better with it? Note that this is just to make sure that we are on the right track. Patch is against v4 of the driver. Thanks, MW diff --git a/drivers/spi/ep93xx_spi.c b/drivers/spi/ep93xx_spi.c index 310032d..11dcdd1 100644 --- a/drivers/spi/ep93xx_spi.c +++ b/drivers/spi/ep93xx_spi.c @@ -106,6 +106,8 @@ struct ep93xx_spi { unsigned long min_rate; unsigned long max_rate; boolrunning; + boolcan_continue; + struct spi_transfer *last_transfer; struct workqueue_struct *wq; struct work_struct msg_work; struct completion wait; @@ -380,6 +382,7 @@ static int ep93xx_spi_transfer(struct spi_device *spi, struct spi_message *msg) struct ep93xx_spi *espi = spi_master_get_devdata(spi-master); struct spi_transfer *t; unsigned long flags; + bool can_continue = true; if (!msg || !msg-complete) return -EINVAL; @@ -387,11 +390,21 @@ static int ep93xx_spi_transfer(struct spi_device *spi, struct spi_message *msg) /* first validate each transfer */ list_for_each_entry(t, msg-transfers, transfer_list) { if (t-bits_per_word) { + can_continue = false; if (t-bits_per_word 4 || t-bits_per_word 16) return -EINVAL; } - if (t-speed_hz t-speed_hz espi-min_rate) + if (t-speed_hz) { + can_continue = false; + if (t-speed_hz espi-min_rate) return -EINVAL; + } + if (t-cs_change + !list_is_last(t-transfer_list, msg-transfers)) { + can_continue = false; + } + if (t-delay_usecs) + can_continue = false; } /* @@ -400,7 +413,7 @@ static int ep93xx_spi_transfer(struct spi_device *spi, struct spi_message *msg) * error in transfer and @msg-state is used to hold pointer to the * current transfer (or %NULL if no active current transfer). */ - msg-state = NULL; + msg-state = (void *)can_continue; msg-status = 0; msg-actual_length = 0; @@ -606,10 +619,33 @@ static void ep93xx_spi_process_message(struct ep93xx_spi *espi, ep93xx_spi_chip_setup(espi, spi_get_ctldata(msg-spi)); ep93xx_spi_select_device(espi, msg-spi); - list_for_each_entry(t, msg-transfers, transfer_list) { - ep93xx_spi_process_transfer(espi, msg, t); - if (msg-status) - break; + if (msg-state) { + espi-can_continue = true; + espi-last_transfer = list_entry(msg-transfers.prev, struct spi_transfer, +transfer_list); + } else { + espi-can_continue = false; + espi-last_transfer = NULL; + } + + /* +* In case there is no transfer specific settings in this message we +* can transfer the whole message with interrupts. Otherwise we need +* to perform transfer specific stuff in thread context. +*/ + if (espi-can_continue) { + msg-state = list_first_entry(msg-transfers, struct spi_transfer, + transfer_list); + espi-rx = 0; + espi-tx = 0; + ep93xx_spi_enable_interrupts(espi); + wait_for_completion(espi-wait); + } else { + list_for_each_entry(t, msg-transfers, transfer_list) { + ep93xx_spi_process_transfer(espi, msg, t); + if (msg-status) + break; + } } /* @@ -792,6 +828,24 @@ static irqreturn_t ep93xx_spi_interrupt(int irq, void *dev_id) * interrupt then. */ return IRQ_HANDLED; + } else { + /* +* If we can continue
Re: [spi-devel-general] [PATCH v4 1/2] spi: implemented driver for Cirrus EP93xx SPI controller
On Wed, Apr 21, 2010 at 11:47:13AM -0500, H Hartley Sweeten wrote: On Wednesday, April 21, 2010 12:16 AM, Mika Westerberg wrote: I think it is more readable to do: ep93xx_spi_select_device(espi, msg-spi); and ep93xx_spi_deselect_device(espi, msg-spi); It can be seen from the function names what we are doing. So rename the combined function to ep93xx_spi_cs_control and pass the control parameter as a bool; true = selected, false = deselected. Having the two almost identical functions is a bit redundant. It also gives you two places to have to maintain basically the same operation. I think this is what Grant was referring to with his previous comment. Agreed. Will do. Thanks, MW -- ___ spi-devel-general mailing list spi-devel-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/spi-devel-general
Re: [spi-devel-general] [PATCH v4 1/2] spi: implemented driver for Cirrus EP93xx SPI controller
On Tuesday, April 20, 2010 11:37 PM, Mika Westerberg wrote: On Tue, Apr 20, 2010 at 05:16:10PM -0500, H Hartley Sweeten wrote: On Tuesday, April 20, 2010 8:12 AM, Mika Westerberg wrote: This patch adds an SPI master driver for the Cirrus EP93xx SPI controller found in EP93xx chips (EP9301, EP9302, EP9307, EP9312 and EP9315). Signed-off-by: Mika Westerberg mika.westerb...@iki.fi Mika, I discovered one gotcha with this driver. Bear with me through this... 1. ep93xx_spi_process_message is called by the workqueue worker function to handle a spi_message queued in by the ep93xx_spi_transfer function. Before starting the actual transfer the chip select to the device is asserted. 2. ep93xx_spi_process_transfer processes each transfer in the spi_message, one at a time, and does a wait_for_completion on each transfer. 3. When the entire spi_message has been transferred the chip select to the device is deasserted. Yes. There is possibility that last transfer -cs_change is set which can be used by SPI controller drivers to keep the chip selected in case next message is going to the same device. However, I haven't implemented that as it is optional (but trivial to add afterwards). It should be implemented. The mmc_spi driver basically requires this. Refer to this comment in the mmc_spi driver: * - We tell the controller to keep the chipselect active from the * beginning of an mmc_host_ops.request until the end. So beware * of SPI controller drivers that mis-handle the cs_change flag! * * However, many cards seem OK with chipselect flapping up/down * during that time ... at least on unshared bus segments. The problem is if a hardware design uses the SFRM1 pin as part of the chip select logic. The EP93xx User's Guide states that the SFRMOUT signal behaves as a slave Select in Motorola SPI mode. This signal behaves differently depending on the SPI_MODE_* used. Modes 0 and 2: SFRMOUT is forced HIGH during idle periods. Start of transmission, SFRMOUT is driven LOW. Single word transmission, SFRMOUT is returned to its idle HIGH state one SCLKOUT period after the last bit has been captured. Back-to-back transmissions, SFRMOUT signal is pulsed HIGH between each data word transfer. On completion the SFRMOUT pin returns to its idle HIGH state one SCLKOUT period after the last bit has been captured. Modes 1 and 3: SFRMOUT is forced HIGH during idle periods. Start of transmission, SFRMOUT is driven LOW. Single word transmission, SFRMOUT is returned to its idle HIGH state one SCLKOUT period after the last bit has been captured. Back-to-back transmissions, SFRMOUT signal is held LOW between each data word transfer. On completion the SFRMOUT pin returns to its idle HIGH state one SCLKOUT period after the last bit has been captured. So, since each transfer does a wait_for_completion, all the data is transmitted which causes the SFRMOUT pin to go HIGH between each transfer in the message. Yes, unfortunately. SFRMOUT cannot be software controlled so it is not suitable for general purpose chipselect. This was the sole purpose of using GPIO lines for chipselects. I agree. But existing ep93xx designs, the EDB93xx boards and Sim.One for instance, use the SFRMOUT either directly for the chip select or as part of the logic generating the chip select. If possible it would be nice to handle this. For devices like the sst25lf040a SPI Flash on the EDB93xx boards this causes a problem. To read data from that device you need to send a two part message. The first part is a write transfer with the one byte command and three byte address. This is then followed by a read transfer to get the data. But since the SFRMOUT pin goes high this ends the command. The driver Ryan and I worked on actually does work with the sst25lf040a on the EDB93xx boards. But now that I know what the issue is, it was actually a race condition. Sometimes it worked and sometimes it didn't... I would think the Sim.One board (Martin?) would have the same issue with the mmc card since that design uses the SFRMOUT pin directly for the chip select. Is there anyway to keep the transfers going in a muiltipart message? I'm not exactly sure but polling mode sounds something that could work around that. It just need to be sure that it transmits continuously to keep the SFRMOUT asserted. You could try v3 of the driver with: # modprobe ep93xx-spi transfer_method=0 and see if it works there. I'll try to test this later. The driver Ryan and I had used polling and it worked but I think there was a race condition in it which occasionally broke the transfer. An alternative would be that interrupt handler schedules tasklet which then takes next transfer immediately once current transfer is finished. I think you would need to: 1. detect when all the transmit data in a
Re: [spi-devel-general] [PATCH v4 1/2] spi: implemented driver for Cirrus EP93xx SPI controller
On Wednesday, April 21, 2010 3:47 AM, Mika Westerberg wrote: On Tue, Apr 20, 2010 at 08:52:26PM -0500, H Hartley Sweeten wrote: On Tuesday, April 20, 2010 6:10 PM, Martin Guy wrote: Not easily, but it seems a likely cause. To prevent card deselection mid-message I think we would need to handle multi-transfer messages by making the start of transfers 2..N continuous with the end of transfers 1..N-1 instead of draining the reply from each one before starting the next. Am I on the right track? Yes. I'm just not sure how to implement this. I made a hack that allows transfer handler to continue to the next transfer directly if there is no special per transfer settings in the message. Could you try that out and report whether SFRMOUT works better with it? Note that this is just to make sure that we are on the right track. Patch is against v4 of the driver. Thanks, MW diff --git a/drivers/spi/ep93xx_spi.c b/drivers/spi/ep93xx_spi.c index 310032d..11dcdd1 100644 --- a/drivers/spi/ep93xx_spi.c +++ b/drivers/spi/ep93xx_spi.c @@ -106,6 +106,8 @@ struct ep93xx_spi { unsigned long min_rate; unsigned long max_rate; boolrunning; + boolcan_continue; + struct spi_transfer *last_transfer; struct workqueue_struct *wq; struct work_struct msg_work; struct completion wait; @@ -380,6 +382,7 @@ static int ep93xx_spi_transfer(struct spi_device *spi, struct spi_message *msg) struct ep93xx_spi *espi = spi_master_get_devdata(spi-master); struct spi_transfer *t; unsigned long flags; + bool can_continue = true; if (!msg || !msg-complete) return -EINVAL; @@ -387,11 +390,21 @@ static int ep93xx_spi_transfer(struct spi_device *spi, struct spi_message *msg) /* first validate each transfer */ list_for_each_entry(t, msg-transfers, transfer_list) { if (t-bits_per_word) { + can_continue = false; if (t-bits_per_word 4 || t-bits_per_word 16) return -EINVAL; } - if (t-speed_hz t-speed_hz espi-min_rate) + if (t-speed_hz) { + can_continue = false; + if (t-speed_hz espi-min_rate) return -EINVAL; + } + if (t-cs_change + !list_is_last(t-transfer_list, msg-transfers)) { + can_continue = false; + } + if (t-delay_usecs) + can_continue = false; } /* @@ -400,7 +413,7 @@ static int ep93xx_spi_transfer(struct spi_device *spi, struct spi_message *msg) * error in transfer and @msg-state is used to hold pointer to the * current transfer (or %NULL if no active current transfer). */ - msg-state = NULL; + msg-state = (void *)can_continue; msg-status = 0; msg-actual_length = 0; @@ -606,10 +619,33 @@ static void ep93xx_spi_process_message(struct ep93xx_spi *espi, ep93xx_spi_chip_setup(espi, spi_get_ctldata(msg-spi)); ep93xx_spi_select_device(espi, msg-spi); - list_for_each_entry(t, msg-transfers, transfer_list) { - ep93xx_spi_process_transfer(espi, msg, t); - if (msg-status) - break; + if (msg-state) { + espi-can_continue = true; + espi-last_transfer = list_entry(msg-transfers.prev, struct spi_transfer, + transfer_list); + } else { + espi-can_continue = false; + espi-last_transfer = NULL; + } + + /* + * In case there is no transfer specific settings in this message we + * can transfer the whole message with interrupts. Otherwise we need + * to perform transfer specific stuff in thread context. + */ + if (espi-can_continue) { + msg-state = list_first_entry(msg-transfers, struct spi_transfer, + transfer_list); + espi-rx = 0; + espi-tx = 0; + ep93xx_spi_enable_interrupts(espi); + wait_for_completion(espi-wait); + } else { + list_for_each_entry(t, msg-transfers, transfer_list) { + ep93xx_spi_process_transfer(espi, msg, t); + if (msg-status) + break; + } } /* @@ -792,6 +828,24 @@ static irqreturn_t ep93xx_spi_interrupt(int irq, void *dev_id) * interrupt then. */ return IRQ_HANDLED; + } else { + /* + * If we can continue
Re: [spi-devel-general] [PATCH v4 1/2] spi: implemented driver for Cirrus EP93xx SPI controller
Mika, I have added some debug messages to the driver trying to figure out how to chain the transfers in a message together in order to keep the SFRM signal asserted for the entire message. I still haven't worked out a good solution but I did notice something else. First, every spi transaction, including a single byte transfer, is going to generate at least two interrupts. One when the interrupts are first enabled because the TX FIFO is empty. And a second when that byte has been transferred and the TX FIFO is again empty. The first interrupt can be prevented by priming the TX FIFO before enabling the interrupts. All you need to do is call ep93xx_spi_read_write right before ep93xx_spi_enable_interrupts. Second, at high clock rates the RX FIFO will actually start to fill as you are putting data into the TX FIFO. If you add an inner reader loop to the writer loop in ep93xx_spi_read_write you can take advantage of this and reduce the number of interrupts generated for large transfers. For instance the mmc_spi driver regularly does 3 transfer messages where the last transfer is a 512 byte read. With your current v4 driver this message averages 69 interrupts to complete. By adding the inner reader it reduces the number of interrupts to an average of 40. Regards, Hartley -- ___ spi-devel-general mailing list spi-devel-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/spi-devel-general
Re: [spi-devel-general] [PATCH v4 1/2] spi: implemented driver for Cirrus EP93xx SPI controller
On Wed, Apr 21, 2010 at 01:00:56PM -0500, H Hartley Sweeten wrote: Same results are your v4 driver. But, I think your on the right track. Thanks for testing. I think the problem is in the ep93xx_spi_read_write routine. That function returns 0 as long as there is still data left in the current transfer. The only time it doesn't return 0, which will cause the can_continue, is when: if (espi-rx == t-len) { msg-actual_length += t-len; return t-len; } At this point the tx and rx fifos will both be empty, which causes the SSP peripheral to raise the SFRM signal. True. A picture is worth a thousand words... Attached is a logic analyzer capture of the Read-ID command and response from the SPI Flash. EGPIO7 is my chip select to the flash. The first 4 SPI MOSI (Tx) blocks are the 0x90, 0x00, 0x00, 0x00 command to the flash. You will notice that the SFRM line is asserted for those bytes. A bit later are the 2 SPI MISO (Rx) responses from the flash with the ManID/DevID, again with the SFRM line asserted. Yeah, it clearly shows that SFRMOUT is deasserted between transfers :( I will try to work out some sort of hack which will keep the FIFOs from emptying. MW -- ___ spi-devel-general mailing list spi-devel-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/spi-devel-general
Re: [spi-devel-general] [PATCH v4 1/2] spi: implemented driver for Cirrus EP93xx SPI controller
On Wed, Apr 21, 2010 at 09:47:14PM -0500, H Hartley Sweeten wrote: [...] First, every spi transaction, including a single byte transfer, is going to generate at least two interrupts. One when the interrupts are first enabled because the TX FIFO is empty. And a second when that byte has been transferred and the TX FIFO is again empty. The first interrupt can be prevented by priming the TX FIFO before enabling the interrupts. All you need to do is call ep93xx_spi_read_write right before ep93xx_spi_enable_interrupts. OK thanks. Second, at high clock rates the RX FIFO will actually start to fill as you are putting data into the TX FIFO. If you add an inner reader loop to the writer loop in ep93xx_spi_read_write you can take advantage of this and reduce the number of interrupts generated for large transfers. I originally had inner read loop in the first version of the driver but it wasn't functioning as it should (this was pointed out by Martin). But now when we have explicit FIFO size handling, I think that it can be added there again. Thanks, MW -- ___ spi-devel-general mailing list spi-devel-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/spi-devel-general