Re: [PATCH] ACPI: Platform driver to support App Hot Startup (PNP0C32)

Shaohua Li
2008-03-27T02:31:39Z

On Thu, 2008-03-27 at 01:51 +0800, Ângelo Miguel Arrifano wrote:
> PATCH
> - -----------------------------------------------------------------
> diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
> index f688c21..fb096ee 100644
> - --- a/drivers/acpi/Kconfig
> +++ b/drivers/acpi/Kconfig
> @@ -196,6 +196,14 @@ config ACPI_THERMAL
> recommended that this option be enabled, as your
> processor(s)
> may be damaged without it.
>
> +config ACPI_QUICKSTART
> + tristate "Quickstart"
> + default y
default m?

> +
> +static struct quickstart_driver_data {
> + struct quickstart_btn *btn_lst;
> + struct quickstart_btn *pressed;
> +} quickstart_data = {
> + .btn_lst = NULL,
> + .pressed = NULL,
> +};
They are NULL, you don't need initialize them.

> + * Platform driver structs
> + */
> +static ssize_t buttons_show(struct device *dev,
> + struct device_attribute *attr,
> + char *buf);
> +static ssize_t pressed_button_show(struct device *dev,
> + struct device_attribute *attr,
> + char *buf);
> +static ssize_t pressed_button_store(struct device *dev,
> + struct device_attribute *attr,
> + const char *buf,
> + size_t count);
> +static DEVICE_ATTR(pressed_button, 0666, pressed_button_show,
> + pressed_button_store);
this file can be changed by non-root?

> +static ssize_t buttons_show(struct device *dev,
> + struct device_attribute
> *attr,
> + char *buf)
> +{
> + int count = 0;
> + char tmpbuf[QUICKSTART_MAX_BTN_NAME_LEN + 2];
> + struct quickstart_btn *ptr = quickstart_data.btn_lst;
> +
> + if (!ptr)
> + return snprintf(buf, PAGE_SIZE, "none");
> +
> + while (ptr && (count < PAGE_SIZE)) {
> + if (ptr->name) {
> + strncpy(tmpbuf, ptr->name,
> QUICKSTART_MAX_BTN_NAME_LEN);
> + strcat(tmpbuf, "\n");
> + count += snprintf(buf + count,
> + PAGE_SIZE - count,
> + tmpbuf);
we could simplify:
snprintf(buf + count, PAGE_SIZE -count, "%s\n", ptr->name);
> + }
> + ptr = ptr->next;
> + }
> +
> + return count;
> +}

> +

> +
> +/* ACPI Driver functions */
> +static void quickstart_acpi_notify(acpi_handle handle, u32 event,
> void *data)
> +{
> + struct quickstart_acpi *quickstart = data;
> +
> + if (!quickstart)
> + return;
> +
> + if (event == QUICKSTART_EVENT_WAKE) {
> + quickstart_data.pressed = quickstart->btn;
> + printk(KERN_ERR "quickstart: Quickbutton %s
> pressed.\n",
> +
> acpi_device_bid(quickstart->device));
> + } else if (event == QUICKSTART_EVENT_RUNTIME) {
> + printk(KERN_ERR "quickstart: Runtime button %s
> pressed.\n\t"
> + "please report on linux-acpi@vger.kernel.org",
> +
> acpi_device_bid(quickstart->device));
> + }
Please remove above printks. they are misleading, which isn't an error.
please send an ACPI event to userspace in the notify, we need it for
runtime.

> + return;
> +}
> +
> +static void quickstart_acpi_raise_notify(struct quickstart_acpi
> *quickstart)
> +{
> + acpi_status status;
> + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
> +
> + if (!quickstart)
> + return;
> +
> + /* This returns a buffer telling the button usage ID
> (useless),
> + * we dont care about it now. The important is to trigger
> + * pending notify events (The ones before booting). */
> + status = acpi_evaluate_object(quickstart->device->handle,
> + "GHID", NULL, &buffer);
> + if (ACPI_FAILURE(status) || !buffer.pointer) {
> + printk(KERN_ERR "quickstart: %s GHID method
> failed.\n",
> + quickstart->btn->name);
> + return;
> + }
I'd suggest the GHID info should be exported to sysfs too. It's hard to
judge what a button is just per its name. You know it but an
inexperienced user doesn't.

> + kfree(buffer.pointer);
> + return;
> +}
> +

> +
> +static int quickstart_acpi_add(struct acpi_device *device)
> +{
> + int ret = 0;
> + acpi_status status = AE_OK;
> + struct quickstart_acpi *quickstart = NULL;
> +
> + if (!device)
> + return -EINVAL;
> +
> + quickstart = kzalloc(sizeof(struct quickstart_acpi),
> GFP_KERNEL);
> + if (!quickstart)
> + return -ENOMEM;
> +
> + quickstart->device = device;
> + strcpy(acpi_device_name(device), QUICKSTART_ACPI_DEVICE_NAME);
> + strcpy(acpi_device_class(device), QUICKSTART_ACPI_CLASS);
> + acpi_driver_data(device) = quickstart;
> +
> + /* Add button to list and initialize some stuff */
> + ret = quickstart_acpi_config(quickstart,
> acpi_device_bid(device));
> + if (ret)
> + goto fail_config;
> +
> + status = acpi_install_notify_handler(device->handle,
> + ACPI_ALL_NOTIFY,
> +
> quickstart_acpi_notify,
> + quickstart);
> + if (ACPI_FAILURE(status)) {
> + printk(KERN_ERR "quickstart: Notify handler install
> error\n");
> + ret = -ENODEV;
> + goto fail_installnotify;
memory is freed but it's still in the list.

Thanks,
Shaohua