On Fri, Mar 19, 2010 at 2:39 AM, Christian Pellegrin <[email protected]> wrote:
> The driver was reworked to use threaded interrupts instead of workqueus.
> This is a major boost in performance because the former are scheduled as
> SCHED_FIFO processes. As a side effect suspend/resume code was greatly
> simplified.
>
> Signed-off-by: Christian Pellegrin <[email protected]>
On a quick parse, it seems mostly okay. I haven't dug into the driver
execution flow though. A few minor comments below.
> ---
> drivers/serial/max3100.c | 102 ++++++++++++++-------------------------------
> 1 files changed, 32 insertions(+), 70 deletions(-)
>
> diff --git a/drivers/serial/max3100.c b/drivers/serial/max3100.c
> index 3c30c56..0c972c6 100644
> --- a/drivers/serial/max3100.c
> +++ b/drivers/serial/max3100.c
> @@ -45,7 +45,9 @@
> #include <linux/serial_core.h>
> #include <linux/serial.h>
> #include <linux/spi/spi.h>
> -#include <linux/freezer.h>
> +#include <linux/kthread.h>
> +#include <linux/interrupt.h>
> +#include <linux/bitops.h>
>
> #include <linux/serial_max3100.h>
>
> @@ -113,18 +115,15 @@ struct max3100_port {
>
> int irq; /* irq assigned to the max3100 */
>
> + /* the workqueue is needed because we cannot schedule
> + a threaded interrupt during PM
> + */
> + struct work_struct resume_work;
> +
> int minor; /* minor number */
> int crystal; /* 1 if 3.6864Mhz crystal 0 for 1.8432 */
> int loopback; /* 1 if we are in loopback mode */
>
> - /* for handling irqs: need workqueue since we do spi_sync */
> - struct workqueue_struct *workqueue;
> - struct work_struct work;
> - /* set to 1 to make the workhandler exit as soon as possible */
> - int force_end_work;
> - /* need to know we are suspending to avoid deadlock on workqueue */
> - int suspending;
> -
> /* hook for suspending MAX3100 via dedicated pin */
> void (*max3100_hw_suspend) (int suspend);
>
> @@ -171,13 +170,12 @@ static void max3100_calc_parity(struct max3100_port *s,
> u16 *c)
> *c |= max3100_do_parity(s, *c) << 8;
> }
>
> -static void max3100_work(struct work_struct *w);
> -
> -static void max3100_dowork(struct max3100_port *s)
> +static void max3100_resume_work(struct work_struct *w)
> {
> - if (!s->force_end_work && !work_pending(&s->work) &&
> - !freezing(current) && !s->suspending)
> - queue_work(s->workqueue, &s->work);
> + struct max3100_port *s = container_of(w, struct max3100_port,
> + resume_work);
container_of is used a lot. Maybe consider a follow-on patch to
create a to_max3100_port() static inline.
> +
> + raise_threaded_irq(s->irq);
> }
>
> static void max3100_timeout(unsigned long data)
> @@ -185,7 +183,7 @@ static void max3100_timeout(unsigned long data)
> struct max3100_port *s = (struct max3100_port *)data;
>
> if (s->port.state) {
> - max3100_dowork(s);
> + raise_threaded_irq(s->irq);
> mod_timer(&s->timer, jiffies + s->poll_time);
> }
> }
> @@ -255,9 +253,9 @@ static int max3100_handlerx(struct max3100_port *s, u16
> rx)
> return ret;
> }
>
> -static void max3100_work(struct work_struct *w)
> +static irqreturn_t max3100_ist(int irq, void *dev_id)
'ist'?
g.
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
------------------------------------------------------------------------------
Download Intel® Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
spi-devel-general mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/spi-devel-general