linux-input.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Andrew Morton <akpm@linux-foundation.org>
Cc: linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org,
	linux-input@vger.kernel.org, jbarnes@virtuousgeek.org,
	david@hardeman.nu
Subject: Re: [PATCH 2/2] Add a driver for the Winbond WPCD376I IR functionality.
Date: Tue, 30 Jun 2009 14:23:45 -0700	[thread overview]
Message-ID: <20090630142345.58e97b50.akpm@linux-foundation.org> (raw)
In-Reply-To: <1246079912-17619-3-git-send-email-david@hardeman.nu>

On Sat, 27 Jun 2009 07:18:32 +0200
David H__rdeman <david@hardeman.nu> wrote:

> This patch adds a driver for the the Consumer IR (CIR) functionality
> of the Winbond WPCD376I chipset (found on e.g. Intel DG45FC
> motherboards).
> 
> Changes since the driver was last posted to the list:
> o Homebrew dprintk -> dev_dbg
> o Some magic values changed to defines
> o Fixed a bug where the wake-ir-command mask/value would not be
>   written properly
> o Fixed the use of the invert parameter both for wake and normal
>   IR reception.
> 
>
> ...
>
> +static void
> +wbcir_set_bits(unsigned long addr, u8 bits, u8 mask)
> +{
> +	u8 val;
> +
> +	val = inb(addr);
> +	val = ((val & ~mask) | (bits & mask));
> +	outb(val, addr);
> +}

What locking prevents the races which could occur here?

Whatever it is, it would be good to document that here in a code
comment.

>
> ...
>
> +static u8
> +wbcir_revbyte(u8 byte)
> +{
> +	byte = ((byte >> 1) & 0x55) | ((byte << 1) & 0xAA);
> +	byte = ((byte >> 2) & 0x33) | ((byte << 2) & 0xCC);
> +	return (byte >> 4) | (byte<<4);
> +}

Can this use the facilities in include/linux/bitrev.h?

> +static u8
> +wbcir_to_rc6cells(u8 val)
> +{
> +	u8 coded = 0x00;
> +	int i;
> +
> +	val &= 0x0F;
> +	for (i = 0; i < 4; i++) {
> +		if (val & 0x01)
> +			coded |= 0x02 << (i * 2);
> +		else
> +			coded |= 0x01 << (i * 2);
> +		val >>= 1;
> +	}
> +
> +	return coded;
> +}

geeze, what does that do?

Code needs comments..

>
> ...
>
> +static int
> +wbcir_getkeycode(struct input_dev *dev, int sscancode, int *keycode)
> +{
> +	unsigned int scancode = (unsigned int)sscancode;

unneeded cast.

> +	struct wbcir_data *data = input_get_drvdata(dev);
> +
> +	if (scancode < 0 || scancode > 0xFFFFFFFF)

Neither of the comparisons in this expression can ever be true.

> +		return -EINVAL;
> +
> +	*keycode = (int)wbcir_do_getkeycode(data, (u32)scancode);

uneeded casts.

Something has gone wrong with the types here.  Where does the fault lie
- this driver, or input core?

> +	return 0;
> +}
> +
> +static int
> +wbcir_setkeycode(struct input_dev *dev, int sscancode, int keycode)
> +{
> +	struct wbcir_data *data = input_get_drvdata(dev);
> +	struct wbcir_keyentry *keyentry;
> +	struct wbcir_keyentry *new_keyentry;
> +	unsigned long flags;
> +	unsigned int old_keycode = KEY_RESERVED;
> +	unsigned int scancode = (unsigned int)sscancode;
> +
> +	if (scancode < 0 || scancode > 0xFFFFFFFF)

various dittoes.

> +		return -EINVAL;
> +
> +	if (keycode < 0 || keycode > KEY_MAX)
> +		return -EINVAL;
> +
> +	new_keyentry = kmalloc(sizeof(*new_keyentry), GFP_KERNEL);
> +	if (!new_keyentry)
> +		return -ENOMEM;
> +
> +	write_lock_irqsave(&keytable_lock, flags);
> +
> +	list_for_each_entry(keyentry, &data->keytable, list) {
> +		if (keyentry->key.scancode != scancode)
> +			continue;
> +
> +		old_keycode = keyentry->key.keycode;
> +		keyentry->key.keycode = keycode;
> +
> +		if (keyentry->key.keycode == KEY_RESERVED) {
> +			list_del(&keyentry->list);
> +			kfree(keyentry);
> +		}
> +
> +		break;
> +	}
> +
> +	set_bit(keycode, dev->keybit);
> +
> +	if (old_keycode == KEY_RESERVED) {
> +		new_keyentry->key.scancode = (u32)scancode;
> +		new_keyentry->key.keycode = (unsigned int)keycode;
> +		list_add(&new_keyentry->list, &data->keytable);
> +	} else {
> +		kfree(new_keyentry);
> +		clear_bit(old_keycode, dev->keybit);
> +		list_for_each_entry(keyentry, &data->keytable, list) {
> +			if (keyentry->key.keycode == old_keycode) {
> +				set_bit(old_keycode, dev->keybit);
> +				break;
> +			}
> +		}
> +	}
> +
> +	write_unlock_irqrestore(&keytable_lock, flags);
> +	return 0;
> +}
> +
> +static void
> +wbcir_keyup(unsigned long cookie)

It would be useful to add a comment telling the reader that this is a
timer-handler function.

> +{
> +	struct wbcir_data *data = (struct wbcir_data *)cookie;
> +	unsigned long flags;
> +
> +	/*
> +	 * data->keyup_jiffies is used to prevent a race condition if a
> +	 * hardware interrupt occurs at this point and the keyup timer
> +	 * event is moved further into the future as a result.
> +	 */

hm.  I don't see what the race is, nor how the comparison fixes it.  If
I _did_ understand this, perhaps I could suggest alternative fixes. 
But I don't so I can't.  Oh well.

> +	spin_lock_irqsave(&wbcir_lock, flags);
> +
> +	if (time_is_after_eq_jiffies(data->keyup_jiffies) && data->keypressed) {
> +		data->keypressed = 0;
> +		led_trigger_event(data->rxtrigger, LED_OFF);
> +		input_report_key(data->input_dev, data->last_keycode, 0);
> +		input_sync(data->input_dev);
> +	}
> +
> +	spin_unlock_irqrestore(&wbcir_lock, flags);
> +}
> +
>
> ...
>
> +static void
> +add_irdata_bit(struct wbcir_data *data, int set)
> +{
> +	if (set)
> +		data->irdata[data->irdata_count / 8] |=
> +			0x01 << (data->irdata_count % 8);

Can/should this use generic___set_le_bit() or similar, rather than
open-coding it?

> +	data->irdata_count++;
> +}
> +
> +/* Gets count bits of irdata */
> +static u16
> +get_bits(struct wbcir_data *data, int count)
> +{
> +	u16 val = 0x0;
> +
> +	if (data->irdata_count - data->irdata_off < count) {
> +		data->irdata_error = 1;
> +		return 0x0;
> +	}
> +
> +	while (count > 0) {
> +		val <<= 1;
> +		if (data->irdata[data->irdata_off / 8] &
> +		    (0x01 << (data->irdata_off % 8)))
> +			val |= 0x1;

ditto

> +		count--;
> +		data->irdata_off++;
> +	}
> +
> +	return val;
> +}
> +
>
> ...
>


  reply	other threads:[~2009-06-30 21:23 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-06-27  5:18 [PATCH 0/2] Winbond IR driver David Härdeman
2009-06-27  5:18 ` [PATCH 1/2] ACPI: reintroduce acpi_device_ops .shutdown method David Härdeman
2009-06-30 21:10   ` Andrew Morton
2009-06-30 23:11     ` Bjorn Helgaas
2009-07-01  8:20       ` David Härdeman
2009-07-08 16:52         ` Bjorn Helgaas
2009-07-09 21:38           ` [PATCH 0/2] Winbond driver as PNP Bjorn Helgaas
2009-07-09 21:39             ` [PATCH 1/2] PNP: add .shutdown method Bjorn Helgaas
2009-07-09 21:40             ` [PATCH 2/2] Winbond: convert from ACPI to PNP driver Bjorn Helgaas
2009-07-10  7:55             ` [PATCH 0/2] Winbond driver as PNP David Härdeman
2009-07-10 16:01               ` Bjorn Helgaas
2009-06-27  5:18 ` [PATCH 2/2] Add a driver for the Winbond WPCD376I IR functionality David Härdeman
2009-06-30 21:23   ` Andrew Morton [this message]
2009-07-01  7:47     ` David Härdeman
2009-07-01 18:06       ` Andrew Morton
2009-07-01 21:45         ` David Härdeman
2009-07-01 21:47     ` David Härdeman
2009-07-01 21:53       ` Jesse Barnes

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=20090630142345.58e97b50.akpm@linux-foundation.org \
    --to=akpm@linux-foundation.org \
    --cc=david@hardeman.nu \
    --cc=jbarnes@virtuousgeek.org \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-input@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    /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).