Re: [PATCH] Input: wm831x-ts - Fix races with IRQ management

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sat, Mar 12, 2011 at 10:14:10PM -0800, Dmitry Torokhov wrote:

> Hmm, this is quite ugly. The race that you mentioned should be dealt
> with by rearranging the order in which you disable IRQ and enable the
> conversions. I.e. in wm831x_ts_pen_down_irq() you should do:

> 	disable_irq_nosync(wm831x_ts->pd_irq);
> 	wm831x_ts->pendown = true;
> 
> 	...
> 	enable_irq(wm831x_ts->data_irq);

Sadly there's also some sensitivities in the hardware with regard to the
interaction between the interrupt controller and the touchscreen
controller which complicate things somewhat.

> What is needed I guess is wm831x_ts->open flag that
> wm831x_ts_input_open() would set and wm831x_ts_input_close() would reset
> and the interrupt handlers would check before touching the registers
> or enabling their counterparts. wm831x_ts_input_close() would reset the
> flag first and then disable first pd_irq and then data_irq, before
> writing to the control register. The only issue is to keep track of irq
> disble counters.

IIRC I did implement a version of this approach but it causes problems
as if the interrupts fire you really do need to handle them to have
things restart correctly when you reenable.  Possibly we can do
something that fiddles with the workqueue scheduling only.  Also...

> The issue is that wm831x_ts_input_close() is racy; it simply writes into
> WM831X_TOUCH_CONTROL_1 and hopes that it will stick...    

The register I/O operations are locked so they can't race with each
other and the only bit that's really important here is TCH_ENA which is
only updated by open and close - it will stop any of the other bits
taking effect later on.  We ought to explicitly disable the X, Y and Z
conversions in open and have an explicit synchronise_irq() after turning
off the controller, though.  We can also just flush the workqueues
unconditionally and clean up the interrupts once we've done that.

> The issue with enable_irq() not working in the irq handler thread should
> be dealt at the controller level (i.e. fix it so that it works).

This is a genirq restriction which doesn't seem entirely unreasonable to
me, the enable operation needs to take the bus lock which can't be done
within IRQ context as the whole point is to deal with things that can't
run there.  You'd have to check that you were running in the context of
an operation which held the bus lock and then skip the bus locking in
that case only which doesn't seem tasteful and won't work at all if
we're using two different locking IRQ controllers for the two interrupts
(which is entirely possible here).  Scheduling out of IRQ context to
avoid these issues seems much more tasteful.
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media Devel]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Linux Wireless Networking]     [Linux Omap]

  Powered by Linux