[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <Pine.LNX.4.64.0812300016030.8962@axis700.grange>
Date: Tue, 30 Dec 2008 00:54:51 +0100 (CET)
From: Guennadi Liakhovetski <lg@...x.de>
To: Andrew Morton <akpm@...ux-foundation.org>
cc: ben-linux@...ff.org, linux-kernel@...r.kernel.org,
rpurdie@...ys.net
Subject: Re: [PATCH v2] leds: add a dac124s085 SPI LED driver
On Mon, 29 Dec 2008, Andrew Morton wrote:
> On Thu, 18 Dec 2008 13:51:06 +0100 (CET)
> Guennadi Liakhovetski <lg@...x.de> wrote:
>
> > +static void dac124s085_led_work(struct work_struct *work)
> > +{
> > + struct dac124s085_led *led = container_of(work, struct dac124s085_led,
> > + work);
> > + u16 word;
> > +
> > + mutex_lock(&led->mutex);
> > + word = cpu_to_le16(((led->id) << 14) | REG_WRITE_UPDATE |
> > + (led->brightness & 0xfff));
> > + spi_write(led->spi, (const u8 *)&word, sizeof(word));
>
> This looks like it might have endianness issues?
Actually this was an attempt to fix the endianness issue pointed out in an
earlier review by Ben Dooks, have I done it wrong?
> > + mutex_unlock(&led->mutex);
> > +}
> > +
> > +static void dac124s085_set_brightness(struct led_classdev *ldev,
> > + enum led_brightness brightness)
> > +{
> > + struct dac124s085_led *led = container_of(ldev, struct dac124s085_led,
> > + ldev);
> > +
> > + spin_lock(&led->lock);
> > + led->brightness = brightness;
> > + schedule_work(&led->work);
> > + spin_unlock(&led->lock);
> > +}
>
> So.. why do we need to defer this to a workqueue rather than just
> performing the operation synchronously?
Here's why (from include/linux/leds.h):
/* Set LED brightness level */
/* Must not sleep, use a workqueue if needed */
void (*brightness_set)(struct led_classdev *led_cdev,
enum led_brightness brightness);
> What happens if there are two calls to set_brightness() in quick
> succession, and the second occurs before the first has completed? I
> think the schedule_work() fails and the second write gets lost?
This seems to be a common "feature" of multiple leds drivers. In fact, if
the two calls are successive, then the queue will take care of the
execution order. If they are "simultaneous," i.e., the callers didn't
synchronise, how do we know who is the first and who is the second? Isn't
the one that _completes_ first actually the first? Or am I missing
something?
Thanks for the review!
Guennadi
---
Guennadi Liakhovetski, Ph.D.
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: office@...x.de
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists