linux-spi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* spi_async and heavy CPU occupation by ksoftirqd
@ 2007-08-08  8:21 llandre
       [not found] ` <46B97D01.5000208-4VKA1VU3ct/j+vYz1yj4TQ@public.gmane.org>
  0 siblings, 1 reply; 10+ messages in thread
From: llandre @ 2007-08-08  8:21 UTC (permalink / raw)
  To: spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

I'm facing the following problem.
I have to poll a SPI device periodically (around ten times a second). 
Both command and response are 1 byte. To do the job I created a work 
that looks like this:

work(...)
{
	sets debug_pin
	poll the device
	err = queue_delayed_work(wq, work, (HZ / 10));
	clears debug_pin
}

The actual SPI transaction is perfomed by invoking spi_async. SPI 
transactions work fine but the kernel daemon ksoftirqd eats about 18% of 
CPU time. With the help of debug pin, I measured the execution time of 
function work that is around 70us. Then I commented out the call of 
spi_async and the ksoftirqd CPU occupation drops to 0%. Am I doing 
something wrong?

I'm working with kernel 2.6.21.3 on iMXL ARM9 processor.

TIA,
llandre

DAVE Electronics System House - R&D Department
web:   http://www.dave-tech.it
email: r&d2-4VKA1VU3ct/j+vYz1yj4TQ@public.gmane.org

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: spi_async and heavy CPU occupation by ksoftirqd
       [not found] ` <46B97D01.5000208-4VKA1VU3ct/j+vYz1yj4TQ@public.gmane.org>
@ 2007-08-08 16:27   ` David Brownell
       [not found]     ` <200708080927.36737.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
  0 siblings, 1 reply; 10+ messages in thread
From: David Brownell @ 2007-08-08 16:27 UTC (permalink / raw)
  To: spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

On Wednesday 08 August 2007, llandre wrote:
> The actual SPI transaction is perfomed by invoking spi_async. SPI 
> transactions work fine but the kernel daemon ksoftirqd eats about 18% of 
> CPU time.

That's excessive.


> With the help of debug pin, I measured the execution time of  
> function work that is around 70us. Then I commented out the call of 
> spi_async and the ksoftirqd CPU occupation drops to 0%. Am I doing 
> something wrong?

Are your transfers large enough to kick in DMA, or is it doing PIO?

At a first glance, I wonder if you're not spending too much time
in the spi_imx "pump_transfers" tasklet.  I have no idea how well
tuned that driver is...

I'd expect that using spi_sync() wouldn't save much, but it might
be worth verifying that.

- Dave

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: spi_async and heavy CPU occupation by ksoftirqd
       [not found]     ` <200708080927.36737.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
@ 2007-08-09 14:05       ` llandre
       [not found]         ` <46BB1F10.3030608-4VKA1VU3ct/j+vYz1yj4TQ@public.gmane.org>
  0 siblings, 1 reply; 10+ messages in thread
From: llandre @ 2007-08-09 14:05 UTC (permalink / raw)
  To: David Brownell; +Cc: spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

>> With the help of debug pin, I measured the execution time of  
>> function work that is around 70us. Then I commented out the call of 
>> spi_async and the ksoftirqd CPU occupation drops to 0%. Am I doing 
>> something wrong?
> 
> Are your transfers large enough to kick in DMA, or is it doing PIO?
I transfer just 1 byte every time the work is executed (HZ/10). I tried
to turn on and off DMA by setting/clearing enable_dma field but nothing 
changed:

/* SPI Controller configuration */
static struct spi_imx_master spi_imx1_master_info = {
	.num_chipselect = SPI_NUM_CHIPSELECT,
	.enable_dma = 0
};


> At a first glance, I wonder if you're not spending too much time
> in the spi_imx "pump_transfers" tasklet.  I have no idea how well
> tuned that driver is...
Hmmm ... how do you suggest me to investigate around this tasklet? Do I 
need to use the toggling pin technique or does the kernel provides some 
tools to do that? Could oprofile come to help?


> I'd expect that using spi_sync() wouldn't save much, but it might
> be worth verifying that.
Initially my driver used spi_sync. When I realized the huge CPU 
occupation I modified it in order to use spi_async instead but, again, 
nothing changed.




-- 
llandre

DAVE Electronics System House - R&D Department
web:   http://www.dave-tech.it
email: r&d2-4VKA1VU3ct/j+vYz1yj4TQ@public.gmane.org

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: spi_async and heavy CPU occupation by ksoftirqd
       [not found]         ` <46BB1F10.3030608-4VKA1VU3ct/j+vYz1yj4TQ@public.gmane.org>
@ 2007-08-09 15:23           ` David Brownell
       [not found]             ` <200708090823.29708.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
  0 siblings, 1 reply; 10+ messages in thread
From: David Brownell @ 2007-08-09 15:23 UTC (permalink / raw)
  To: llandre; +Cc: spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

On Thursday 09 August 2007, llandre wrote:
> > At a first glance, I wonder if you're not spending too much time
> > in the spi_imx "pump_transfers" tasklet.  I have no idea how well
> > tuned that driver is...
> 
> Hmmm ... how do you suggest me to investigate around this tasklet? Do I 
> need to use the toggling pin technique

That seems to be the most precise tool you have, unless you
have access to the JTAG-style hardware tools giving access
to the on-chip instruction trace buffers found in many ARMs.


> or does the kernel provides some  
> tools to do that? Could oprofile come to help?

Statistical profiling probably wouldn't help.  I'm not sure that
anything like gprof is working in the kernel.  Folk that I know
have done that level analysis tend to rely on hardware trace tools.


> > I'd expect that using spi_sync() wouldn't save much, but it might
> > be worth verifying that.
>
> Initially my driver used spi_sync. When I realized the huge CPU 
> occupation I modified it in order to use spi_async instead but, again, 
> nothing changed.

And that should have been a HUGE clue that the way you were calling
it wasn't a factor at all.  

- Dave

 



-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: spi_async and heavy CPU occupation by ksoftirqd
       [not found]             ` <200708090823.29708.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
@ 2007-08-10  8:52               ` llandre
       [not found]                 ` <46BC2732.5070504-4VKA1VU3ct/j+vYz1yj4TQ@public.gmane.org>
  0 siblings, 1 reply; 10+ messages in thread
From: llandre @ 2007-08-10  8:52 UTC (permalink / raw)
  To: David Brownell
  Cc: spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f, Andrea Paterniani

> That seems to be the most precise tool you have, unless you
> have access to the JTAG-style hardware tools giving access
> to the on-chip instruction trace buffers found in many ARMs.
Unfortunatley trace port is not available so I have to use the old 
fashioned debug pin technique.

>> or does the kernel provides some  
>> tools to do that? Could oprofile come to help?
> 
> Statistical profiling probably wouldn't help.  I'm not sure that
> anything like gprof is working in the kernel.  Folk that I know
> have done that level analysis tend to rely on hardware trace tools.
I see.

>>> I'd expect that using spi_sync() wouldn't save much, but it might
>>> be worth verifying that.
>> Initially my driver used spi_sync. When I realized the huge CPU 
>> occupation I modified it in order to use spi_async instead but, again, 
>> nothing changed.
> 
> And that should have been a HUGE clue that the way you were calling
> it wasn't a factor at all.  
I moved the set/clear pin functions inside the iMXL master driver and I 
found the problem is at line 804 inside the interrupt handler:

	qt510_debug_pin(1);
	while ((read(drv_data) == 0) && limit--);
	qt510_debug_pin(0);

Usually the high pulse lasts about 10ms. Occasionally (about 1 time out 
of 3) it lasts about 300 ms ! That would explain the ksoftirqd abnormal 
CPU occupation.
I hope Andrea can come to help.



-- 
llandre

DAVE Electronics System House - R&D Department
web:   http://www.dave-tech.it
email: r&d2-4VKA1VU3ct/j+vYz1yj4TQ@public.gmane.org

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: spi_async and heavy CPU occupation by ksoftirqd
       [not found]                 ` <46BC2732.5070504-4VKA1VU3ct/j+vYz1yj4TQ@public.gmane.org>
@ 2007-08-10 10:29                   ` Andrea Paterniani
       [not found]                     ` <FLEPLOLKEPNLMHOILNHPMEKGDKAA.a.paterniani-03BXCEkGbFHYGGNLXY5/rw@public.gmane.org>
  0 siblings, 1 reply; 10+ messages in thread
From: Andrea Paterniani @ 2007-08-10 10:29 UTC (permalink / raw)
  To: llandre, David Brownell
  Cc: spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

Is there any logged error message?
May be that limit reaches 0 but in this case an error is logged (trailing bytes read failed).

- Andrea





> -----Messaggio originale-----
> Da: llandre [mailto:r&d2-4VKA1VU3ct/j+vYz1yj4TQ@public.gmane.org]
> Inviato: venerdì 10 agosto 2007 10.52
> A: David Brownell
> Cc: spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org; Andrea Paterniani
> Oggetto: Re: [spi-devel-general] spi_async and heavy CPU occupation by
> ksoftirqd
>
>
> > That seems to be the most precise tool you have, unless you
> > have access to the JTAG-style hardware tools giving access
> > to the on-chip instruction trace buffers found in many ARMs.
> Unfortunatley trace port is not available so I have to use the old
> fashioned debug pin technique.
>
> >> or does the kernel provides some
> >> tools to do that? Could oprofile come to help?
> >
> > Statistical profiling probably wouldn't help.  I'm not sure that
> > anything like gprof is working in the kernel.  Folk that I know
> > have done that level analysis tend to rely on hardware trace tools.
> I see.
>
> >>> I'd expect that using spi_sync() wouldn't save much, but it might
> >>> be worth verifying that.
> >> Initially my driver used spi_sync. When I realized the huge CPU
> >> occupation I modified it in order to use spi_async instead but, again,
> >> nothing changed.
> >
> > And that should have been a HUGE clue that the way you were calling
> > it wasn't a factor at all.
> I moved the set/clear pin functions inside the iMXL master driver and I
> found the problem is at line 804 inside the interrupt handler:
>
> 	qt510_debug_pin(1);
> 	while ((read(drv_data) == 0) && limit--);
> 	qt510_debug_pin(0);
>
> Usually the high pulse lasts about 10ms. Occasionally (about 1 time out
> of 3) it lasts about 300 ms ! That would explain the ksoftirqd abnormal
> CPU occupation.
> I hope Andrea can come to help.
>
>
>
> --
> llandre
>
> DAVE Electronics System House - R&D Department
> web:   http://www.dave-tech.it
> email: r&d2-4VKA1VU3ct/j+vYz1yj4TQ@public.gmane.org


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: spi_async and heavy CPU occupation by ksoftirqd
       [not found]                     ` <FLEPLOLKEPNLMHOILNHPMEKGDKAA.a.paterniani-03BXCEkGbFHYGGNLXY5/rw@public.gmane.org>
@ 2007-08-10 11:32                       ` llandre
       [not found]                         ` <46BC4CD3.5090304-4VKA1VU3ct/j+vYz1yj4TQ@public.gmane.org>
  0 siblings, 1 reply; 10+ messages in thread
From: llandre @ 2007-08-10 11:32 UTC (permalink / raw)
  To: Andrea Paterniani
  Cc: David Brownell, spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

I think I found the cause.
Since I needed to enable the RDY control (SPI_CONTROL_DRCTL_2) as 
required by the SPI slave (Quantum QT510), the actual SPI transactions 
may occur after the driver wrote the TX FIFO (if (write(drv_data))).
Thus

while ((read(drv_data) == 0) && limit--);

waits until the actual transaction have been completed, that happens 
when the slave is ready to accept data.
So I'm afraid I need modify the MXL driver in order to support this case.

-- 
llandre

DAVE Electronics System House - R&D Department
web:   http://www.dave-tech.it
email: r&d2-4VKA1VU3ct/j+vYz1yj4TQ@public.gmane.org


> Is there any logged error message?
> May be that limit reaches 0 but in this case an error is logged (trailing bytes read failed).
> 
> - Andrea
> 
> 
> 
> 
> 
>> -----Messaggio originale-----
>> Da: llandre [mailto:r&d2-4VKA1VU3ct/j+vYz1yj4TQ@public.gmane.org]
>> Inviato: venerdì 10 agosto 2007 10.52
>> A: David Brownell
>> Cc: spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org; Andrea Paterniani
>> Oggetto: Re: [spi-devel-general] spi_async and heavy CPU occupation by
>> ksoftirqd
>>
>>
>>> That seems to be the most precise tool you have, unless you
>>> have access to the JTAG-style hardware tools giving access
>>> to the on-chip instruction trace buffers found in many ARMs.
>> Unfortunatley trace port is not available so I have to use the old
>> fashioned debug pin technique.
>>
>>>> or does the kernel provides some
>>>> tools to do that? Could oprofile come to help?
>>> Statistical profiling probably wouldn't help.  I'm not sure that
>>> anything like gprof is working in the kernel.  Folk that I know
>>> have done that level analysis tend to rely on hardware trace tools.
>> I see.
>>
>>>>> I'd expect that using spi_sync() wouldn't save much, but it might
>>>>> be worth verifying that.
>>>> Initially my driver used spi_sync. When I realized the huge CPU
>>>> occupation I modified it in order to use spi_async instead but, again,
>>>> nothing changed.
>>> And that should have been a HUGE clue that the way you were calling
>>> it wasn't a factor at all.
>> I moved the set/clear pin functions inside the iMXL master driver and I
>> found the problem is at line 804 inside the interrupt handler:
>>
>> 	qt510_debug_pin(1);
>> 	while ((read(drv_data) == 0) && limit--);
>> 	qt510_debug_pin(0);
>>
>> Usually the high pulse lasts about 10ms. Occasionally (about 1 time out
>> of 3) it lasts about 300 ms ! That would explain the ksoftirqd abnormal
>> CPU occupation.
>> I hope Andrea can come to help.
>>
>>
>>
>> --
>> llandre
>>
>> DAVE Electronics System House - R&D Department
>> web:   http://www.dave-tech.it
>> email: r&d2-4VKA1VU3ct/j+vYz1yj4TQ@public.gmane.org
> 
> 
> 



-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/

^ permalink raw reply	[flat|nested] 10+ messages in thread

* R: spi_async and heavy CPU occupation by ksoftirqd
       [not found]                         ` <46BC4CD3.5090304-4VKA1VU3ct/j+vYz1yj4TQ@public.gmane.org>
@ 2007-08-10 12:27                           ` Andrea Paterniani
       [not found]                             ` <FLEPLOLKEPNLMHOILNHPIEKIDKAA.a.paterniani-03BXCEkGbFHYGGNLXY5/rw@public.gmane.org>
  0 siblings, 1 reply; 10+ messages in thread
From: Andrea Paterniani @ 2007-08-10 12:27 UTC (permalink / raw)
  To: llandre
  Cc: David Brownell, spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

You're right the current version of the driver doesn't support RDY control.
Infact SPI_DEFAULT_CONTROL is defined with SPI_CONTROL_DRCTL_0.
Also setup function doesn't managed DRCTL changes.

Then you probably changes SPI_DEFAULT_CONTROL to use SPI_CONTROL_DRCTL_2.

Please do your suggestions for driver modification in order to release a driver patch.

- Andrea



> -----Messaggio originale-----
> Da: llandre [mailto:r&d2-4VKA1VU3ct/j+vYz1yj4TQ@public.gmane.org]
> Inviato: venerdì 10 agosto 2007 13.33
> A: Andrea Paterniani
> Cc: David Brownell; spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
> Oggetto: Re: [spi-devel-general] spi_async and heavy CPU occupation by
> ksoftirqd
>
>
> I think I found the cause.
> Since I needed to enable the RDY control (SPI_CONTROL_DRCTL_2) as
> required by the SPI slave (Quantum QT510), the actual SPI transactions
> may occur after the driver wrote the TX FIFO (if (write(drv_data))).
> Thus
>
> while ((read(drv_data) == 0) && limit--);
>
> waits until the actual transaction have been completed, that happens
> when the slave is ready to accept data.
> So I'm afraid I need modify the MXL driver in order to support this case.
>
> --
> llandre
>
> DAVE Electronics System House - R&D Department
> web:   http://www.dave-tech.it
> email: r&d2-4VKA1VU3ct/j+vYz1yj4TQ@public.gmane.org
>
>
> > Is there any logged error message?
> > May be that limit reaches 0 but in this case an error is logged (trailing bytes read failed).
> >
> > - Andrea
> >
> >
> >
> >
> >
> >> -----Messaggio originale-----
> >> Da: llandre [mailto:r&d2-4VKA1VU3ct/j+vYz1yj4TQ@public.gmane.org]
> >> Inviato: venerdì 10 agosto 2007 10.52
> >> A: David Brownell
> >> Cc: spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org; Andrea Paterniani
> >> Oggetto: Re: [spi-devel-general] spi_async and heavy CPU occupation by
> >> ksoftirqd
> >>
> >>
> >>> That seems to be the most precise tool you have, unless you
> >>> have access to the JTAG-style hardware tools giving access
> >>> to the on-chip instruction trace buffers found in many ARMs.
> >> Unfortunatley trace port is not available so I have to use the old
> >> fashioned debug pin technique.
> >>
> >>>> or does the kernel provides some
> >>>> tools to do that? Could oprofile come to help?
> >>> Statistical profiling probably wouldn't help.  I'm not sure that
> >>> anything like gprof is working in the kernel.  Folk that I know
> >>> have done that level analysis tend to rely on hardware trace tools.
> >> I see.
> >>
> >>>>> I'd expect that using spi_sync() wouldn't save much, but it might
> >>>>> be worth verifying that.
> >>>> Initially my driver used spi_sync. When I realized the huge CPU
> >>>> occupation I modified it in order to use spi_async instead but, again,
> >>>> nothing changed.
> >>> And that should have been a HUGE clue that the way you were calling
> >>> it wasn't a factor at all.
> >> I moved the set/clear pin functions inside the iMXL master driver and I
> >> found the problem is at line 804 inside the interrupt handler:
> >>
> >> 	qt510_debug_pin(1);
> >> 	while ((read(drv_data) == 0) && limit--);
> >> 	qt510_debug_pin(0);
> >>
> >> Usually the high pulse lasts about 10ms. Occasionally (about 1 time out
> >> of 3) it lasts about 300 ms ! That would explain the ksoftirqd abnormal
> >> CPU occupation.
> >> I hope Andrea can come to help.
> >>
> >>
> >>
> >> --
> >> llandre
> >>
> >> DAVE Electronics System House - R&D Department
> >> web:   http://www.dave-tech.it
> >> email: r&d2-4VKA1VU3ct/j+vYz1yj4TQ@public.gmane.org
> >
> >
> >
>
>


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: R: spi_async and heavy CPU occupation by ksoftirqd
       [not found]                             ` <FLEPLOLKEPNLMHOILNHPIEKIDKAA.a.paterniani-03BXCEkGbFHYGGNLXY5/rw@public.gmane.org>
@ 2007-08-14  8:29                               ` llandre
       [not found]                                 ` <46C167F0.4040100-4VKA1VU3ct/j+vYz1yj4TQ@public.gmane.org>
  0 siblings, 1 reply; 10+ messages in thread
From: llandre @ 2007-08-14  8:29 UTC (permalink / raw)
  To: Andrea Paterniani
  Cc: David Brownell, spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

AFAIK introducing support for RDY in the driver is not a trivial matter.
Since
a) I just need to perform 1-byte transactions to communicate with 
Quantum QT510
b) I don't have much time to spend on this issue (customer needs to 
assemble a demo quickly)
I'm afraid I'll have to write a dirty patch just to make my specific 
configuration work.

I'll keep you informed anyway.

Regards,
llandre

DAVE Electronics System House - R&D Department
web:   http://www.dave-tech.it
email: r&d2-4VKA1VU3ct/j+vYz1yj4TQ@public.gmane.org



> You're right the current version of the driver doesn't support RDY control.
> Infact SPI_DEFAULT_CONTROL is defined with SPI_CONTROL_DRCTL_0.
> Also setup function doesn't managed DRCTL changes.
> 
> Then you probably changes SPI_DEFAULT_CONTROL to use SPI_CONTROL_DRCTL_2.
> 
> Please do your suggestions for driver modification in order to release a driver patch.
> 
> - Andrea


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: R: spi_async and heavy CPU occupation by ksoftirqd
       [not found]                                 ` <46C167F0.4040100-4VKA1VU3ct/j+vYz1yj4TQ@public.gmane.org>
@ 2007-08-14  9:43                                   ` llandre
  0 siblings, 0 replies; 10+ messages in thread
From: llandre @ 2007-08-14  9:43 UTC (permalink / raw)
  To: Andrea Paterniani
  Cc: David Brownell, spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

[-- Attachment #1: Type: text/plain, Size: 1893 bytes --]

Atatched is a dirty ugly patch that seems to work for 1-byte transfers I 
use with QT510.
In case RDY control is enabled, transfer is completed by

interrupt_data_ready (new irq handler)
pump_transfers (tasklet)

in this order.


Regards,
llandre

DAVE Electronics System House - R&D Department
web:   http://www.dave-tech.it
email: r&d2-4VKA1VU3ct/j+vYz1yj4TQ@public.gmane.org


> AFAIK introducing support for RDY in the driver is not a trivial matter.
> Since
> a) I just need to perform 1-byte transactions to communicate with 
> Quantum QT510
> b) I don't have much time to spend on this issue (customer needs to 
> assemble a demo quickly)
> I'm afraid I'll have to write a dirty patch just to make my specific 
> configuration work.
> 
> I'll keep you informed anyway.
> 
> Regards,
> llandre
> 
> DAVE Electronics System House - R&D Department
> web:   http://www.dave-tech.it
> email: r&d2-4VKA1VU3ct/j+vYz1yj4TQ@public.gmane.org
> 
> 
> 
>> You're right the current version of the driver doesn't support RDY control.
>> Infact SPI_DEFAULT_CONTROL is defined with SPI_CONTROL_DRCTL_0.
>> Also setup function doesn't managed DRCTL changes.
>>
>> Then you probably changes SPI_DEFAULT_CONTROL to use SPI_CONTROL_DRCTL_2.
>>
>> Please do your suggestions for driver modification in order to release a driver patch.
>>
>> - Andrea
> 
> 
> -------------------------------------------------------------------------
> This SF.net email is sponsored by: Splunk Inc.
> Still grepping through log files to find problems?  Stop.
> Now Search log events and configuration files using AJAX and a browser.
> Download your FREE copy of Splunk now >>  http://get.splunk.com/
> _______________________________________________
> spi-devel-general mailing list
> spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
> https://lists.sourceforge.net/lists/listinfo/spi-devel-general
> 
> 


[-- Attachment #2: spi-imx-rdy.patch --]
[-- Type: text/plain, Size: 4151 bytes --]

diff --git a/drivers/spi/spi_imx.c b/drivers/spi/spi_imx.c
index 25c22ff..2b9ab9c 100644
--- a/drivers/spi/spi_imx.c
+++ b/drivers/spi/spi_imx.c
@@ -148,6 +148,7 @@
 #define SPI_DEFAULT_ENABLE_LOOPBACK	(0)
 #define SPI_DEFAULT_ENABLE_DMA		(0)
 #define SPI_DEFAULT_PERIOD_WAIT		(8)
+#define SPI_IS_RDY_ENABLED			((SPI_DEFAULT_CONTROL & SPI_CONTROL_DRCTL_2) ? 1 : 0)
 /*-------------------------------------------------------------------------*/
 
 
@@ -281,7 +282,7 @@ static int flush(struct driver_data *drv_data)
 		while (readl(regs + SPI_INT_STATUS) & SPI_STATUS_RR)
 			d = readl(regs + SPI_RXDATA);
 	} while ((readl(regs + SPI_CONTROL) & SPI_CONTROL_XCH) && limit--);
-
+	
 	return limit;
 }
 
@@ -754,6 +755,20 @@ static irqreturn_t interrupt_wronly_transfer(struct driver_data *drv_data)
 	return handled;
 }
 
+static irqreturn_t interrupt_data_ready(struct driver_data *drv_data){
+	void __iomem *regs = drv_data->regs;
+
+	/* Read rx data */
+	read(drv_data);
+	/* Disable irq */
+	writel(readl(regs + SPI_INT_STATUS) & ~SPI_INTEN,
+		regs + SPI_INT_STATUS);
+	/* Schedule transfer tasklet */
+	tasklet_schedule(&drv_data->pump_transfers);
+	
+	return IRQ_HANDLED;
+}
+
 static irqreturn_t interrupt_transfer(struct driver_data *drv_data)
 {
 	struct spi_message *msg = drv_data->cur_msg;
@@ -763,7 +778,7 @@ static irqreturn_t interrupt_transfer(struct driver_data *drv_data)
 	unsigned long limit;
 
 	status = readl(regs + SPI_INT_STATUS);
-
+	
 	while (status & (SPI_STATUS_TH | SPI_STATUS_RO)) {
 		dev_dbg(&drv_data->pdev->dev,
 			"interrupt_transfer - status = 0x%08X\n", status);
@@ -785,23 +800,30 @@ static irqreturn_t interrupt_transfer(struct driver_data *drv_data)
 
 			msg->state = ERROR_STATE;
 			tasklet_schedule(&drv_data->pump_transfers);
-
+			
 			return IRQ_HANDLED;
 		}
 
 		/* Pump data */
 		read(drv_data);
 		if (write(drv_data)) {
-			writel(readl(regs + SPI_INT_STATUS) & ~SPI_INTEN,
-				regs + SPI_INT_STATUS);
+			if (SPI_IS_RDY_ENABLED) {
+				/* RX IRQ handler will complete the transfer */
+				drv_data->transfer_handler = interrupt_data_ready;
+				writel((readl(regs + SPI_INT_STATUS) & ~SPI_INTEN) | SPI_INTEN_RE,
+					regs + SPI_INT_STATUS);
+				goto skip_rx_poll;
+			} else {
+				writel(readl(regs + SPI_INT_STATUS) & ~SPI_INTEN,
+					regs + SPI_INT_STATUS);
+			}
 
 			dev_dbg(&drv_data->pdev->dev,
 				"interrupt_transfer - end of tx\n");
-
+			
 			/* Read trailing bytes */
 			limit = loops_per_jiffy << 1;
 			while ((read(drv_data) == 0) && limit--);
-
 			if (limit == 0)
 				dev_err(&drv_data->pdev->dev,
 					"interrupt_transfer - "
@@ -810,6 +832,7 @@ static irqreturn_t interrupt_transfer(struct driver_data *drv_data)
 				dev_dbg(&drv_data->pdev->dev,
 					"interrupt_transfer - end of rx\n");
 
+skip_rx_poll:
 			/* End of transfer, update total byte transfered */
 			msg->actual_length += drv_data->len;
 
@@ -821,9 +844,11 @@ static irqreturn_t interrupt_transfer(struct driver_data *drv_data)
 			/* Move to next transfer */
 			msg->state = next_transfer(drv_data);
 
-			/* Schedule transfer tasklet */
-			tasklet_schedule(&drv_data->pump_transfers);
-
+			if (!SPI_IS_RDY_ENABLED) {
+				/* Schedule transfer tasklet */
+				tasklet_schedule(&drv_data->pump_transfers);
+			}
+			
 			return IRQ_HANDLED;
 		}
 
@@ -832,7 +857,7 @@ static irqreturn_t interrupt_transfer(struct driver_data *drv_data)
 		/* We did something */
 		handled = IRQ_HANDLED;
 	}
-
+	
 	return handled;
 }
 
@@ -949,7 +974,7 @@ static void pump_transfers(unsigned long data)
 
 	/* Assert device chip-select */
 	drv_data->cs_control(SPI_CS_ASSERT);
-
+	
 	/* DMA cannot read/write SPI FIFOs other than 16 bits at a time; hence
 	   if bits_per_word is less or equal 8 PIO transfers are performed.
 	   Moreover DMA is convinient for transfer length bigger than FIFOs
@@ -1089,7 +1114,7 @@ static void pump_messages(struct work_struct *work)
 	/* Setup the SPI using the per chip configuration */
 	drv_data->cur_chip = spi_get_ctldata(drv_data->cur_msg->spi);
 	restore_state(drv_data);
-
+	
 	/* Mark as busy and launch transfers */
 	tasklet_schedule(&drv_data->pump_transfers);
 }

[-- Attachment #3: Type: text/plain, Size: 315 bytes --]

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/

[-- Attachment #4: Type: text/plain, Size: 210 bytes --]

_______________________________________________
spi-devel-general mailing list
spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
https://lists.sourceforge.net/lists/listinfo/spi-devel-general

^ permalink raw reply related	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2007-08-14  9:43 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-08-08  8:21 spi_async and heavy CPU occupation by ksoftirqd llandre
     [not found] ` <46B97D01.5000208-4VKA1VU3ct/j+vYz1yj4TQ@public.gmane.org>
2007-08-08 16:27   ` David Brownell
     [not found]     ` <200708080927.36737.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
2007-08-09 14:05       ` llandre
     [not found]         ` <46BB1F10.3030608-4VKA1VU3ct/j+vYz1yj4TQ@public.gmane.org>
2007-08-09 15:23           ` David Brownell
     [not found]             ` <200708090823.29708.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
2007-08-10  8:52               ` llandre
     [not found]                 ` <46BC2732.5070504-4VKA1VU3ct/j+vYz1yj4TQ@public.gmane.org>
2007-08-10 10:29                   ` Andrea Paterniani
     [not found]                     ` <FLEPLOLKEPNLMHOILNHPMEKGDKAA.a.paterniani-03BXCEkGbFHYGGNLXY5/rw@public.gmane.org>
2007-08-10 11:32                       ` llandre
     [not found]                         ` <46BC4CD3.5090304-4VKA1VU3ct/j+vYz1yj4TQ@public.gmane.org>
2007-08-10 12:27                           ` R: " Andrea Paterniani
     [not found]                             ` <FLEPLOLKEPNLMHOILNHPIEKIDKAA.a.paterniani-03BXCEkGbFHYGGNLXY5/rw@public.gmane.org>
2007-08-14  8:29                               ` llandre
     [not found]                                 ` <46C167F0.4040100-4VKA1VU3ct/j+vYz1yj4TQ@public.gmane.org>
2007-08-14  9:43                                   ` llandre

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).