linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Johan Hovold <jhovold@gmail.com>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: Richard Purdie <rpurdie@rpsys.net>, Rob Landley <rob@landley.net>,
	Samuel Ortiz <sameo@linux.intel.com>,
	Jonathan Cameron <jic23@cam.ac.uk>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Florian Tobias Schandinat <FlorianSchandinat@gmx.de>,
	Arnd Bergmann <arnd@arndb.de>,
	Mark Brown <broonie@opensource.wolfsonmicro.com>,
	linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
	Bryan Wu <bryan.wu@canonical.com>
Subject: Re: [PATCH v3] leds: add LM3533 LED driver
Date: Fri, 11 May 2012 11:54:11 +0200	[thread overview]
Message-ID: <20120511095411.GC29437@localhost> (raw)
In-Reply-To: <20120510114817.28b24168.akpm@linux-foundation.org>

On Thu, May 10, 2012 at 11:48:17AM -0700, Andrew Morton wrote:
> On Thu, 10 May 2012 20:27:05 +0200
> Johan Hovold <jhovold@gmail.com> wrote:
> 
> > Add sub-driver for the LEDs on National Semiconductor / TI LM3533
> > lighting power chips.
> > 
> > The chip provides 256 brightness levels, hardware accelerated blinking
> > as well as ambient-light-sensor and pwm input control.
> > 
> > ...
> >
> > +#define to_lm3533_led(_cdev) \
> > +	container_of(_cdev, struct lm3533_led, cdev)
> 
> Minor thing: container_of() is not fully type-safe: it can be passed
> the address of any struct which contains a field called cdev and will
> return a struct lm3533_led* (or something like that - it has holes...).
> 
> A way to fix that is to wrap container_of() in a real C function, not a
> macro:
> 
> static inline struct lm3533_led *to_lm3533_led(struct struct led_classdev *cdev)
> {
> 	return container_of(_cdev, struct lm3533_led, cdev);
> }
> 
> This has been another episode in the ongoing series "macros are always
> wrong" :)

Fair enough. :) Seems like the vast majority of drivers still use
convenience macros such as the this one for this kind of use (where the
functions are either passed the class device or it is retrieved through
device driver data).

Do you want me to replace the other three instances of container_of
convenience macros in the iio-subdriver and core (already added to the
mfd tree) as well?

> > ...
> >
> > +static int time_to_val(long *t, long t_min, long t_max, long t_step,
> > +							int v_min, int v_max)
> > +{
> > +	int val;
> > +
> > +	*t += t_step / 2;
> > +	val = (*t - t_min) / t_step + v_min;
> > +	val = clamp(val, v_min, v_max);
> > +	*t = t_step * (val - v_min) + t_min;
> > +
> > +	return val;
> > +}
> 
> Oh wow, what does all this do.  Please, take pity upon the poor reader
> and add a comment documenting this function's intent?

Mapping a time in SI-units (us) to device-specific discrete time
and returning the actual time that will be used (multiple of t_step +
offset).

I'll try to make it more clear and add some comments.

> > +static int lm3533_led_get_delay(long *delay)
> > +{
> > +	int val;
> > +
> > +	*delay *= 1000;
> > +
> > +	if (*delay >= LM3533_LED_DELAY_GROUP3_MIN -
> > +					LM3533_LED_DELAY_GROUP3_STEP / 2) {
> > +		val = time_to_val(delay, LM3533_LED_DELAY_GROUP3_MIN,
> > +					LM3533_LED_DELAY_GROUP3_MAX,
> > +					LM3533_LED_DELAY_GROUP3_STEP,
> > +					LM3533_LED_DELAY_GROUP3_BASE,
> > +					0xff);
> > +	} else if (*delay >= LM3533_LED_DELAY_GROUP2_MIN -
> > +					LM3533_LED_DELAY_GROUP2_STEP / 2) {
> > +		val = time_to_val(delay, LM3533_LED_DELAY_GROUP2_MIN,
> > +					LM3533_LED_DELAY_GROUP2_MAX,
> > +					LM3533_LED_DELAY_GROUP2_STEP,
> > +					LM3533_LED_DELAY_GROUP2_BASE,
> > +					LM3533_LED_DELAY_GROUP3_BASE - 1);
> > +	} else {
> > +		val = time_to_val(delay, LM3533_LED_DELAY_GROUP1_MIN,
> > +					LM3533_LED_DELAY_GROUP1_MAX,
> > +					LM3533_LED_DELAY_GROUP1_STEP,
> > +					LM3533_LED_DELAY_GROUP1_BASE,
> > +					LM3533_LED_DELAY_GROUP2_BASE - 1);
> > +	}
> > +
> > +	*delay /= 1000;
> > +
> > +	return val;
> > +}
> 
> And this one, please.

Will do. [ The device has three ranges of supported hardware-accelerated
blink times with different step sizes. ]

> > +static int lm3533_led_delay_set(struct lm3533_led *led, u8 base,
> > +							unsigned long *delay)
> > +{
> > +	u8 val;
> > +	u8 reg;
> > +	long t;
> > +	int ret;
> > +
> > +	t = *delay;
> > +	val = lm3533_led_get_delay(&t);
> > +
> > +	dev_dbg(led->cdev.dev, "%s - %lu: %ld (0x%02x)\n", __func__,
> > +							*delay, t, val);
> > +	reg = lm3533_led_get_pattern_reg(led, base);
> > +	ret = lm3533_write(led->lm3533, reg, val);
> > +	if (ret)
> > +		dev_err(led->cdev.dev, "failed to set delay (%02x)\n", reg);
> > +
> > +	*delay = t;
> > +
> > +	return ret;
> > +}
> 
> Should `t' have unsigned long type?  I think so.  The above functions
> confuddle longs with unsigned longs.  As a negative delay is an
> absurdity, perhaps everything should use unsigned long consistently?

Indeed. 

> > +static int lm3533_led_delay_on_set(struct lm3533_led *led, unsigned long *t)
> > +{
> > +	*t = min_t(long, *t, LM3533_LED_DELAY_GROUP2_MAX / 1000);
> 
> The use of min_t is often a sign that the types are mucked up.  How to
> fix this?
> 
> Are the LM3533_LED_DELAY_* constants logically to be considered to have
> unsigned long type?  If so, put a "L" after their values and everything
> should work out nicely.

Will do.

> > +	return lm3533_led_delay_set(led, LM3533_REG_PATTERN_HIGH_TIME_BASE, t);
> > +}
> > +
> >
> > ...
> >
> > +static ssize_t store_als(struct device *dev,
> > +					struct device_attribute *attr,
> > +					const char *buf, size_t len)
> > +{
> > +	struct led_classdev *led_cdev = dev_get_drvdata(dev);
> > +	struct lm3533_led *led = to_lm3533_led(led_cdev);
> > +	u8 als;
> > +	u8 reg;
> > +	u8 mask;
> > +	int ret;
> > +
> > +	if (kstrtou8(buf, 0, &als))
> > +		return -EINVAL;
> > +
> > +	if (als != 0 && (als < LM3533_ALS_LV_MIN || als > LM3533_ALS_LV_MAX))
> > +		return -EINVAL;
> 
> The `als != 0' test doesn't do anything, and looks odd.  Is there some
> magical reason why als==0 would be illegal even if LM3533_ALS_LV_MIN
> was negative?  If so, it should be documented.

The non-zero-test is not redundant as 0 is the only valid input outside
of [LV_MIN,LV_MAX] (in fact, the only three valid values are 0,2 and 3).

Would you prefer

	if ((als < LM3533_ALS_LV_MIN && als != 0) || als > LM3533_ALS_LV_MAX)
		return -EINVAL;

or nested conditionals? Or should I simply add a comment?

Thanks,
Johan

  reply	other threads:[~2012-05-11  9:54 UTC|newest]

Thread overview: 83+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-04-20 15:30 [PATCH 0/4] mfd: add LM3533 lighting-power chip driver Johan Hovold
2012-04-20 15:30 ` [PATCH 1/4] mfd: add LM3533 lighting-power core driver Johan Hovold
2012-04-26 12:41   ` Mark Brown
2012-05-03 10:15     ` Johan Hovold
2012-05-03 10:22     ` Johan Hovold
2012-04-20 15:30 ` [PATCH 2/4] misc: add LM3533 ambient light sensor driver Johan Hovold
2012-04-20 15:57   ` Greg Kroah-Hartman
2012-04-20 17:28     ` Johan Hovold
2012-04-20 17:37       ` Greg Kroah-Hartman
2012-04-26 11:52         ` Johan Hovold
2012-04-20 15:30 ` [PATCH 3/4] leds: add LM3533 LED driver Johan Hovold
2012-04-20 16:10   ` Arnd Bergmann
2012-04-20 16:45     ` Johan Hovold
2012-04-20 15:30 ` [PATCH 4/4] backlight: add LM3533 backlight driver Johan Hovold
2012-05-03 10:26 ` [PATCH v2 0/4] mfd: add LM3533 lighting-power chip driver Johan Hovold
2012-05-03 10:26   ` [PATCH v2 1/4] mfd: add LM3533 lighting-power core driver Johan Hovold
2012-05-03 10:38     ` Mark Brown
2012-05-03 11:28       ` Johan Hovold
2012-05-03 11:38         ` Mark Brown
2012-05-03 15:00           ` Johan Hovold
2012-05-03 15:24             ` Mark Brown
2012-05-03 16:54               ` Johan Hovold
2012-05-03 16:57                 ` Mark Brown
2012-05-03 17:14                   ` Johan Hovold
2012-05-03 17:23                     ` Mark Brown
2012-05-03 17:31                       ` Johan Hovold
2012-05-09 14:42     ` Samuel Ortiz
2012-05-10 12:07       ` Johan Hovold
2012-05-10 12:11         ` [PATCH 1/2] mfd: lm3533: add boost frequency and ovp to platform data Johan Hovold
2012-05-10 12:11           ` [PATCH 2/2] mfd: lm3533: remove boost attributes Johan Hovold
2012-05-10 17:18         ` [PATCH 0/2] mfd: lm3533: update max-current interface Johan Hovold
2012-05-10 17:18           ` [PATCH 1/2] mfd: lm3533: remove unused max-current function Johan Hovold
2012-05-10 17:18           ` [PATCH 2/2] mfd: lm3533: use SI-units for max-current interface Johan Hovold
2012-05-11 13:32         ` [PATCH v2 1/4] mfd: add LM3533 lighting-power core driver Samuel Ortiz
2012-05-03 10:26   ` [PATCH v2 2/4] iio: add LM3533 ambient light sensor driver Johan Hovold
2012-05-03 11:40     ` Jonathan Cameron
2012-05-03 16:36       ` Johan Hovold
2012-05-08 13:47         ` Jonathan Cameron
2012-05-15 16:44           ` Johan Hovold
2012-05-15 20:00             ` Jonathan Cameron
2012-05-16 13:05               ` Johan Hovold
2012-05-16 14:21                 ` Jonathan Cameron
2012-05-18 12:27                   ` Johan Hovold
2012-05-18 17:34                     ` Jonathan Cameron
2012-05-18 17:57                       ` Johan Hovold
2012-05-19  8:04                         ` Jonathan Cameron
2012-05-15 16:46     ` [PATCH v3] iio: add LM3533 ambient-light-sensor driver Johan Hovold
2012-05-15 19:27       ` Andrew Morton
2012-05-15 20:00         ` Johan Hovold
2012-05-15 20:16           ` Jonathan Cameron
2012-05-18 13:07       ` [PATCH v4] " Johan Hovold
2012-05-19  8:48         ` Jonathan Cameron
2012-05-19 16:30           ` Johan Hovold
2012-05-19 13:26             ` Jonathan Cameron
2012-05-21  9:50           ` Johan Hovold
2012-05-21 16:37             ` Jonathan Cameron
2012-05-21 22:07               ` Johan Hovold
2012-05-22  7:13                 ` Jonathan Cameron
2012-05-22  9:09                   ` Johan Hovold
2012-05-22  9:15                     ` Jonathan Cameron
2012-05-22  7:45               ` Michael Hennerich
2012-05-22  7:49                 ` Jonathan Cameron
2012-05-22  8:11                   ` Michael Hennerich
2012-05-22  8:20                     ` Jonathan Cameron
2012-05-21 12:18         ` [PATCH v5] " Johan Hovold
2012-05-22  9:19           ` Jonathan Cameron
2012-05-22  9:40             ` Johan Hovold
2012-05-22 13:55               ` Greg Kroah-Hartman
2012-06-05  4:11               ` Greg Kroah-Hartman
2012-05-03 10:26   ` [PATCH v2 3/4] leds: add LM3533 LED driver Johan Hovold
2012-05-03 10:43     ` Mark Brown
2012-05-03 11:50       ` Johan Hovold
2012-05-03 14:51         ` Mark Brown
2012-05-03 16:46           ` Johan Hovold
2012-05-10 18:27     ` [PATCH v3] " Johan Hovold
2012-05-10 18:48       ` Andrew Morton
2012-05-11  9:54         ` Johan Hovold [this message]
2012-05-11 22:24           ` Andrew Morton
2012-05-14 10:25             ` Johan Hovold
2012-05-14 10:31       ` [PATCH v4] " Johan Hovold
2012-05-03 10:26   ` [PATCH v2 4/4] backlight: add LM3533 backlight driver Johan Hovold
2012-05-10 18:29     ` [PATCH v3] " Johan Hovold
2012-05-15 19:13       ` [PATCH v4] " Johan Hovold

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20120511095411.GC29437@localhost \
    --to=jhovold@gmail.com \
    --cc=FlorianSchandinat@gmx.de \
    --cc=akpm@linux-foundation.org \
    --cc=arnd@arndb.de \
    --cc=broonie@opensource.wolfsonmicro.com \
    --cc=bryan.wu@canonical.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=jic23@cam.ac.uk \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=rob@landley.net \
    --cc=rpurdie@rpsys.net \
    --cc=sameo@linux.intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).