From: Len Brown <lenb-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
To: Henrique de Moraes Holschuh
<hmh-N3TV7GIv+o9fyO9Q7EP/yw@public.gmane.org>
Cc: ibm-acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org,
linux-acpi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Subject: Re: [PATCH 01/15] ACPI: thinkpad-acpi: refactor hotkey_get and hotkey_set
Date: Thu, 15 Nov 2007 13:14:12 -0500 [thread overview]
Message-ID: <200711151314.12935.lenb@kernel.org> (raw)
In-Reply-To: <1195097822-24738-2-git-send-email-hmh-N3TV7GIv+o9fyO9Q7EP/yw@public.gmane.org>
> This patch:
a nit to prove that I read this before dumping it into my test branch...
the "perfect patch" never refers to itself as a patch
in its check-in comments -- since by the time it is checked
in, it is sort of self-evident it is a patch:-)
http://www.zip.com.au/~akpm/linux/patches/stuff/tpp.txt
> 1. Splits hotkey_get/set into hotkey_status_get/set and hotkey_mask_get/set;
Split...
> 2. Caches the status of hot key mask for later driver use;
Cache...
> 3. Makes sure the cache of hot key mask is refreshed when needed;
Make...
> 4. logs a printk notice when the firmware doesn't set the hot key
> mask to exactly what we asked it to;
Log...
> 5. Do the proper locking on the data structures.
Fix broken locking.
cool, huh?
> Only (4) is user-noticeable, unless (5) fixes some corner-case races.
of course that means that they should ideally be different smaller patches.
but, Henrique, we're waxing about perfection here -- your
patch hygene is already some of the best on the list.
thanks,
-Len
> Signed-off-by: Henrique de Moraes Holschuh <hmh-N3TV7GIv+o9fyO9Q7EP/yw@public.gmane.org>
> ---
> drivers/misc/thinkpad_acpi.c | 184 +++++++++++++++++++++++++-----------------
> drivers/misc/thinkpad_acpi.h | 2 -
> 2 files changed, 109 insertions(+), 77 deletions(-)
>
> diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
> index 8c94307..87ba534 100644
> --- a/drivers/misc/thinkpad_acpi.c
> +++ b/drivers/misc/thinkpad_acpi.c
> @@ -777,6 +777,7 @@ static int hotkey_orig_status;
> static u32 hotkey_orig_mask;
> static u32 hotkey_all_mask;
> static u32 hotkey_reserved_mask;
> +static u32 hotkey_mask;
>
> static u16 *hotkey_keycode_map;
>
> @@ -789,15 +790,76 @@ static int hotkey_get_wlsw(int *status)
> return 0;
> }
>
> +/*
> + * Call with hotkey_mutex held
> + */
> +static int hotkey_mask_get(void)
> +{
> + if (tp_features.hotkey_mask) {
> + if (!acpi_evalf(hkey_handle, &hotkey_mask, "DHKN", "d"))
> + return -EIO;
> + }
> +
> + return 0;
> +}
> +
> +/*
> + * Call with hotkey_mutex held
> + */
> +static int hotkey_mask_set(u32 mask)
> +{
> + int i;
> + int rc = 0;
> +
> + if (tp_features.hotkey_mask) {
> + for (i = 0; i < 32; i++) {
> + u32 m = 1 << i;
> + if (!acpi_evalf(hkey_handle,
> + NULL, "MHKM", "vdd", i + 1,
> + !!(mask & m))) {
> + rc = -EIO;
> + break;
> + } else {
> + hotkey_mask = (hotkey_mask & ~m) | (mask & m);
> + }
> + }
> +
> + /* hotkey_mask_get must be called unconditionally below */
> + if (!hotkey_mask_get() && !rc && hotkey_mask != mask) {
> + printk(IBM_NOTICE
> + "requested hot key mask 0x%08x, but "
> + "firmware forced it to 0x%08x\n",
> + mask, hotkey_mask);
> + }
> + }
> +
> + return rc;
> +}
> +
> +static int hotkey_status_get(int *status)
> +{
> + if (!acpi_evalf(hkey_handle, status, "DHKC", "d"))
> + return -EIO;
> +
> + return 0;
> +}
> +
> +static int hotkey_status_set(int status)
> +{
> + if (!acpi_evalf(hkey_handle, NULL, "MHKC", "vd", status))
> + return -EIO;
> +
> + return 0;
> +}
> +
> /* sysfs hotkey enable ------------------------------------------------- */
> static ssize_t hotkey_enable_show(struct device *dev,
> struct device_attribute *attr,
> char *buf)
> {
> int res, status;
> - u32 mask;
>
> - res = hotkey_get(&status, &mask);
> + res = hotkey_status_get(&status);
> if (res)
> return res;
>
> @@ -809,15 +871,12 @@ static ssize_t hotkey_enable_store(struct device *dev,
> const char *buf, size_t count)
> {
> unsigned long t;
> - int res, status;
> - u32 mask;
> + int res;
>
> if (parse_strtoul(buf, 1, &t))
> return -EINVAL;
>
> - res = hotkey_get(&status, &mask);
> - if (!res)
> - res = hotkey_set(t, mask);
> + res = hotkey_status_set(t);
>
> return (res) ? res : count;
> }
> @@ -831,14 +890,15 @@ static ssize_t hotkey_mask_show(struct device *dev,
> struct device_attribute *attr,
> char *buf)
> {
> - int res, status;
> - u32 mask;
> + int res;
>
> - res = hotkey_get(&status, &mask);
> - if (res)
> - return res;
> + if (mutex_lock_interruptible(&hotkey_mutex))
> + return -ERESTARTSYS;
> + res = hotkey_mask_get();
> + mutex_unlock(&hotkey_mutex);
>
> - return snprintf(buf, PAGE_SIZE, "0x%08x\n", mask);
> + return (res)?
> + res : snprintf(buf, PAGE_SIZE, "0x%08x\n", hotkey_mask);
> }
>
> static ssize_t hotkey_mask_store(struct device *dev,
> @@ -846,15 +906,16 @@ static ssize_t hotkey_mask_store(struct device *dev,
> const char *buf, size_t count)
> {
> unsigned long t;
> - int res, status;
> - u32 mask;
> + int res;
>
> if (parse_strtoul(buf, 0xffffffffUL, &t))
> return -EINVAL;
>
> - res = hotkey_get(&status, &mask);
> - if (!res)
> - hotkey_set(status, t);
> + if (mutex_lock_interruptible(&hotkey_mutex))
> + return -ERESTARTSYS;
> +
> + res = hotkey_mask_set(t);
> + mutex_unlock(&hotkey_mutex);
>
> return (res) ? res : count;
> }
> @@ -1065,11 +1126,16 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
> }
> }
>
> - res = hotkey_get(&hotkey_orig_status, &hotkey_orig_mask);
> + res = hotkey_status_get(&hotkey_orig_status);
> if (!res && tp_features.hotkey_mask) {
> - res = add_many_to_attr_set(hotkey_dev_attributes,
> - hotkey_mask_attributes,
> - ARRAY_SIZE(hotkey_mask_attributes));
> + res = hotkey_mask_get();
> + hotkey_orig_mask = hotkey_mask;
> + if (!res) {
> + res = add_many_to_attr_set(
> + hotkey_dev_attributes,
> + hotkey_mask_attributes,
> + ARRAY_SIZE(hotkey_mask_attributes));
> + }
> }
>
> /* Not all thinkpads have a hardware radio switch */
> @@ -1133,7 +1199,10 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
>
> dbg_printk(TPACPI_DBG_INIT,
> "enabling hot key handling\n");
> - res = hotkey_set(1, (hotkey_all_mask & ~hotkey_reserved_mask)
> + res = hotkey_status_set(1);
> + if (res)
> + return res;
> + res = hotkey_mask_set((hotkey_all_mask & ~hotkey_reserved_mask)
> | hotkey_orig_mask);
> if (res)
> return res;
> @@ -1149,13 +1218,12 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
>
> static void hotkey_exit(void)
> {
> - int res;
> -
> if (tp_features.hotkey) {
> - dbg_printk(TPACPI_DBG_EXIT, "restoring original hotkey mask\n");
> - res = hotkey_set(hotkey_orig_status, hotkey_orig_mask);
> - if (res)
> - printk(IBM_ERR "failed to restore hotkey to BIOS defaults\n");
> + dbg_printk(TPACPI_DBG_EXIT, "restoring original hot key mask\n");
> + /* no short-circuit boolean operator below! */
> + if ((hotkey_mask_set(hotkey_orig_mask) |
> + hotkey_status_set(hotkey_orig_status)) != 0)
> + printk(IBM_ERR "failed to restore hot key mask to BIOS defaults\n");
> }
>
> if (hotkey_dev_attributes) {
> @@ -1291,50 +1359,15 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event)
>
> static void hotkey_resume(void)
> {
> + if (hotkey_mask_get())
> + printk(IBM_ERR "error while trying to read hot key mask from firmware\n");
> tpacpi_input_send_radiosw();
> }
>
> -/*
> - * Call with hotkey_mutex held
> - */
> -static int hotkey_get(int *status, u32 *mask)
> -{
> - if (!acpi_evalf(hkey_handle, status, "DHKC", "d"))
> - return -EIO;
> -
> - if (tp_features.hotkey_mask)
> - if (!acpi_evalf(hkey_handle, mask, "DHKN", "d"))
> - return -EIO;
> -
> - return 0;
> -}
> -
> -/*
> - * Call with hotkey_mutex held
> - */
> -static int hotkey_set(int status, u32 mask)
> -{
> - int i;
> -
> - if (!acpi_evalf(hkey_handle, NULL, "MHKC", "vd", status))
> - return -EIO;
> -
> - if (tp_features.hotkey_mask)
> - for (i = 0; i < 32; i++) {
> - int bit = ((1 << i) & mask) != 0;
> - if (!acpi_evalf(hkey_handle,
> - NULL, "MHKM", "vdd", i + 1, bit))
> - return -EIO;
> - }
> -
> - return 0;
> -}
> -
> /* procfs -------------------------------------------------------------- */
> static int hotkey_read(char *p)
> {
> int res, status;
> - u32 mask;
> int len = 0;
>
> if (!tp_features.hotkey) {
> @@ -1344,14 +1377,16 @@ static int hotkey_read(char *p)
>
> if (mutex_lock_interruptible(&hotkey_mutex))
> return -ERESTARTSYS;
> - res = hotkey_get(&status, &mask);
> + res = hotkey_status_get(&status);
> + if (!res)
> + res = hotkey_mask_get();
> mutex_unlock(&hotkey_mutex);
> if (res)
> return res;
>
> len += sprintf(p + len, "status:\t\t%s\n", enabled(status, 0));
> if (tp_features.hotkey_mask) {
> - len += sprintf(p + len, "mask:\t\t0x%08x\n", mask);
> + len += sprintf(p + len, "mask:\t\t0x%08x\n", hotkey_mask);
> len += sprintf(p + len,
> "commands:\tenable, disable, reset, <mask>\n");
> } else {
> @@ -1367,7 +1402,6 @@ static int hotkey_write(char *buf)
> int res, status;
> u32 mask;
> char *cmd;
> - int do_cmd = 0;
>
> if (!tp_features.hotkey)
> return -ENODEV;
> @@ -1375,9 +1409,8 @@ static int hotkey_write(char *buf)
> if (mutex_lock_interruptible(&hotkey_mutex))
> return -ERESTARTSYS;
>
> - res = hotkey_get(&status, &mask);
> - if (res)
> - goto errexit;
> + status = -1;
> + mask = hotkey_mask;
>
> res = 0;
> while ((cmd = next_cmd(&buf))) {
> @@ -1396,11 +1429,12 @@ static int hotkey_write(char *buf)
> res = -EINVAL;
> goto errexit;
> }
> - do_cmd = 1;
> }
> + if (status != -1)
> + res = hotkey_status_set(status);
>
> - if (do_cmd)
> - res = hotkey_set(status, mask);
> + if (!res && mask != hotkey_mask)
> + res = hotkey_mask_set(mask);
>
> errexit:
> mutex_unlock(&hotkey_mutex);
> diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h
> index 8fba2bb..3b03134 100644
> --- a/drivers/misc/thinkpad_acpi.h
> +++ b/drivers/misc/thinkpad_acpi.h
> @@ -461,8 +461,6 @@ static struct mutex hotkey_mutex;
>
> static int hotkey_init(struct ibm_init_struct *iibm);
> static void hotkey_exit(void);
> -static int hotkey_get(int *status, u32 *mask);
> -static int hotkey_set(int status, u32 mask);
> static void hotkey_notify(struct ibm_struct *ibm, u32 event);
> static int hotkey_read(char *p);
> static int hotkey_write(char *buf);
-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
next prev parent reply other threads:[~2007-11-15 18:14 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-11-15 3:36 [GIT PATCH] thinkpad-acpi patches for 2.6.25 (batch 1) Henrique de Moraes Holschuh
2007-11-15 3:36 ` [PATCH 01/15] ACPI: thinkpad-acpi: refactor hotkey_get and hotkey_set Henrique de Moraes Holschuh
[not found] ` <1195097822-24738-2-git-send-email-hmh-N3TV7GIv+o9fyO9Q7EP/yw@public.gmane.org>
2007-11-15 18:14 ` Len Brown [this message]
2007-11-17 20:15 ` Henrique de Moraes Holschuh
[not found] ` <20071117201501.GG30919-ZGHd14iZgfaRjzvQDGKj+xxZW9W5cXbT@public.gmane.org>
2007-11-19 21:20 ` Len Brown
[not found] ` <1195097822-24738-1-git-send-email-hmh-N3TV7GIv+o9fyO9Q7EP/yw@public.gmane.org>
2007-11-15 3:36 ` [PATCH 02/15] ACPI: thinkpad-acpi: prepare for NVRAM polling support Henrique de Moraes Holschuh
2007-11-15 3:36 ` [PATCH 03/15] ACPI: thinkpad-acpi: add CMOS NVRAM polling for hot keys (v6) Henrique de Moraes Holschuh
2007-11-15 3:36 ` [PATCH 04/15] ACPI: thinkpad-acpi: let threads be frozen Henrique de Moraes Holschuh
2007-11-15 3:36 ` [PATCH 05/15] ACPI: thinkpad-acpi: bump up version to 0.18 Henrique de Moraes Holschuh
2007-11-15 3:36 ` [PATCH 06/15] ACPI: thinkpad-acpi: spring cleanup part 1 Henrique de Moraes Holschuh
2007-11-15 3:36 ` [PATCH 07/15] ACPI: thinkpad-acpi: spring cleanup part 2 Henrique de Moraes Holschuh
2007-11-15 3:36 ` [PATCH 11/15] ACPI: thinkpad-acpi: rename IBM in defines Henrique de Moraes Holschuh
2007-11-15 3:36 ` [PATCH 12/15] ACPI: thinkpad-acpi: some checkpatch.pl fluff Henrique de Moraes Holschuh
2007-11-15 3:37 ` [PATCH 13/15] ACPI: thinkpad-acpi: add suspend handler Henrique de Moraes Holschuh
2007-11-15 3:37 ` [PATCH 15/15] ACPI: thinkpad-acpi: wakeup on hotunplug reporting Henrique de Moraes Holschuh
2007-11-15 3:36 ` [PATCH 08/15] ACPI: thinkpad-acpi: spring cleanup part 3 Henrique de Moraes Holschuh
2007-11-15 3:36 ` [PATCH 09/15] ACPI: thinkpad-acpi: spring cleanup part 4 Henrique de Moraes Holschuh
2007-11-15 3:36 ` [PATCH 10/15] ACPI: thinkpad-acpi: module glue cleanups Henrique de Moraes Holschuh
2007-11-15 3:37 ` [PATCH 14/15] ACPI: thinkpad-acpi: cleanup hotkey_notify and HKEY log messages Henrique de Moraes Holschuh
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=200711151314.12935.lenb@kernel.org \
--to=lenb-dgejt+ai2ygdnm+yrofe0a@public.gmane.org \
--cc=hmh-N3TV7GIv+o9fyO9Q7EP/yw@public.gmane.org \
--cc=ibm-acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org \
--cc=linux-acpi-u79uwXL29TY76Z2rM5mHXA@public.gmane.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