Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751780AbdFASse (ORCPT ); Thu, 1 Jun 2017 14:48:34 -0400 Received: from mx1.redhat.com ([209.132.183.28]:59060 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751310AbdFASrB (ORCPT ); Thu, 1 Jun 2017 14:47:01 -0400 DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 9251B80474 Authentication-Results: ext-mx04.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx04.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=benjamin.tissoires@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 9251B80474 From: Benjamin Tissoires To: Lv Zheng , "Rafael J . Wysocki" , "Rafael J . Wysocki" , Len Brown , Lv Zheng , Peter Hutterer Cc: linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org, systemd-devel@lists.freedesktop.org, linux-input@vger.kernel.org, Benjamin Tissoires Subject: [WIP PATCH 1/4] ACPI: button: extract input creation/destruction helpers Date: Thu, 1 Jun 2017 20:46:29 +0200 Message-Id: <20170601184632.2980-2-benjamin.tissoires@redhat.com> In-Reply-To: <20170601184632.2980-1-benjamin.tissoires@redhat.com> References: <20170601184632.2980-1-benjamin.tissoires@redhat.com> X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Thu, 01 Jun 2017 18:46:55 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3950 Lines: 155 When the LID switch ACPI implementation is unreliable, we might want to remove the device when we are not sure about the state. This should prevent any suspend/resume loops given that in that case, there will be no more LID switch input node. This patch prepares the dynamic creation/destruction of the input node. Signed-off-by: Benjamin Tissoires --- drivers/acpi/button.c | 90 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 57 insertions(+), 33 deletions(-) diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index 9ad8cdb..48bcdca 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c @@ -448,10 +448,61 @@ static int acpi_button_resume(struct device *dev) } #endif +static void acpi_button_remove_input(struct acpi_device *device) +{ + struct acpi_button *button = acpi_driver_data(device); + + input_unregister_device(button->input); + button->input = NULL; +} + +static int acpi_button_add_input(struct acpi_device *device) +{ + struct acpi_button *button = acpi_driver_data(device); + struct input_dev *input; + int error; + + button->input = input = input_allocate_device(); + if (!input) { + error = -ENOMEM; + goto err; + } + + input->name = acpi_device_name(device); + input->phys = button->phys; + input->id.bustype = BUS_HOST; + input->id.product = button->type; + input->dev.parent = &device->dev; + + switch (button->type) { + case ACPI_BUTTON_TYPE_POWER: + input_set_capability(input, EV_KEY, KEY_POWER); + break; + + case ACPI_BUTTON_TYPE_SLEEP: + input_set_capability(input, EV_KEY, KEY_SLEEP); + break; + + case ACPI_BUTTON_TYPE_LID: + input_set_capability(input, EV_SW, SW_LID); + break; + } + + error = input_register_device(input); + if (error) + goto err; + + return 0; + + err: + input_free_device(input); + button->input = NULL; + return error; +} + static int acpi_button_add(struct acpi_device *device) { struct acpi_button *button; - struct input_dev *input; const char *hid = acpi_device_hid(device); char *name, *class; int error; @@ -462,12 +513,6 @@ static int acpi_button_add(struct acpi_device *device) device->driver_data = button; - button->input = input = input_allocate_device(); - if (!input) { - error = -ENOMEM; - goto err_free_button; - } - name = acpi_device_name(device); class = acpi_device_class(device); @@ -493,38 +538,19 @@ static int acpi_button_add(struct acpi_device *device) } else { printk(KERN_ERR PREFIX "Unsupported hid [%s]\n", hid); error = -ENODEV; - goto err_free_input; + goto err_free_button; } error = acpi_button_add_fs(device); if (error) - goto err_free_input; + goto err_free_button; snprintf(button->phys, sizeof(button->phys), "%s/button/input0", hid); - input->name = name; - input->phys = button->phys; - input->id.bustype = BUS_HOST; - input->id.product = button->type; - input->dev.parent = &device->dev; - - switch (button->type) { - case ACPI_BUTTON_TYPE_POWER: - input_set_capability(input, EV_KEY, KEY_POWER); - break; - - case ACPI_BUTTON_TYPE_SLEEP: - input_set_capability(input, EV_KEY, KEY_SLEEP); - break; - - case ACPI_BUTTON_TYPE_LID: - input_set_capability(input, EV_SW, SW_LID); - break; - } - - error = input_register_device(input); + error = acpi_button_add_input(device); if (error) goto err_remove_fs; + if (button->type == ACPI_BUTTON_TYPE_LID) { acpi_lid_initialize_state(device); /* @@ -540,8 +566,6 @@ static int acpi_button_add(struct acpi_device *device) err_remove_fs: acpi_button_remove_fs(device); - err_free_input: - input_free_device(input); err_free_button: kfree(button); return error; @@ -552,7 +576,7 @@ static int acpi_button_remove(struct acpi_device *device) struct acpi_button *button = acpi_driver_data(device); acpi_button_remove_fs(device); - input_unregister_device(button->input); + acpi_button_remove_input(device); kfree(button); return 0; } -- 2.9.4