From patchwork Sun Aug 17 06:04:18 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mika Westerberg X-Patchwork-Id: 4730701 Return-Path: X-Original-To: patchwork-linux-acpi@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 89830C0338 for ; Sun, 17 Aug 2014 06:06:24 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 89CE4201BC for ; Sun, 17 Aug 2014 06:06:23 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 65E5B2015D for ; Sun, 17 Aug 2014 06:06:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751771AbaHQGFA (ORCPT ); Sun, 17 Aug 2014 02:05:00 -0400 Received: from mga02.intel.com ([134.134.136.20]:54308 "EHLO mga02.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751745AbaHQGE5 (ORCPT ); Sun, 17 Aug 2014 02:04:57 -0400 Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga101.jf.intel.com with ESMTP; 16 Aug 2014 23:04:56 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.01,878,1400050800"; d="scan'208";a="559589170" Received: from blue.fi.intel.com ([10.237.72.156]) by orsmga001.jf.intel.com with ESMTP; 16 Aug 2014 23:04:53 -0700 Received: by blue.fi.intel.com (Postfix, from userid 1004) id 93D82E00AA; Sun, 17 Aug 2014 09:04:19 +0300 (EEST) From: Mika Westerberg To: Darren Hart , "Rafael J. Wysocki" Cc: Aaron Lu , Max Eliaser , Mika Westerberg , linux-acpi@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [RFC PATCH 8/9] Input: gpio_keys_polled - Make use of device property API Date: Sun, 17 Aug 2014 09:04:18 +0300 Message-Id: <1408255459-17625-9-git-send-email-mika.westerberg@linux.intel.com> X-Mailer: git-send-email 2.1.0.rc1 In-Reply-To: <1408255459-17625-1-git-send-email-mika.westerberg@linux.intel.com> References: <1408255459-17625-1-git-send-email-mika.westerberg@linux.intel.com> Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Spam-Status: No, score=-7.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Aaron Lu Make use of device property API in this driver so that both OF based system and ACPI based system can use this driver. The driver isn't converted to descriptor based gpio API due to there are a lot of existing users of struct gpio_keys_button that expects the gpio integer field. Though this can be solved by adding a new field of type struct gpio_desc but then there is another problem: the devm_gpiod_get needs to operate on the button device instead of its parent device that has the driver binded, so when the driver is unloaded, the resources for the gpio will not get freed automatically. Alternatively, we can introduce a new API, something like gpiod_find_index that does almost the same thing as gpiod_get_index but doesn't do the gpiod_request call and use it during finding button resources in gpio_keys_polled_get_button function. But then this may seem too complicated and not desirable. So in the end, a simple dev_get_gpiod_flags which is introduced in the last patch gets used and the gpio field of the struct gpio_keys_button can be got from the desc_to_gpio. Signed-off-by: Aaron Lu Signed-off-by: Max Eliaser Reviewed-by: Darren Hart Signed-off-by: Mika Westerberg --- drivers/input/keyboard/gpio_keys_polled.c | 139 ++++++++++++++++++------------ 1 file changed, 84 insertions(+), 55 deletions(-) diff --git a/drivers/input/keyboard/gpio_keys_polled.c b/drivers/input/keyboard/gpio_keys_polled.c index 432d36395f35..49895d75aaff 100644 --- a/drivers/input/keyboard/gpio_keys_polled.c +++ b/drivers/input/keyboard/gpio_keys_polled.c @@ -27,6 +27,7 @@ #include #include #include +#include #define DRV_NAME "gpio-keys-polled" @@ -102,78 +103,95 @@ static void gpio_keys_polled_close(struct input_polled_dev *dev) pdata->disable(bdev->dev); } -#ifdef CONFIG_OF -static struct gpio_keys_platform_data *gpio_keys_polled_get_devtree_pdata(struct device *dev) -{ - struct device_node *node, *pp; +#if defined(CONFIG_OF) || defined(CONFIG_ACPI) + +struct button_proc_context { struct gpio_keys_platform_data *pdata; - struct gpio_keys_button *button; - int error; - int nbuttons; int i; +}; - node = dev->of_node; - if (!node) - return NULL; +static int gpio_keys_polled_get_button(struct device *dev, void *data) +{ + struct button_proc_context *c = data; + struct gpio_keys_platform_data *pdata = c->pdata; + struct gpio_keys_button *button = &pdata->buttons[c->i]; + struct gpio_desc *desc; + enum gpio_lookup_flags flags; + void *val; + + if (device_property_get(dev, "gpios", NULL)) { + pdata->nbuttons--; + dev_warn(dev, "Found button without gpios\n"); + return 0; + } - nbuttons = of_get_child_count(node); - if (nbuttons == 0) - return NULL; + desc = dev_get_gpiod_flags(dev, 0, &flags); + if (IS_ERR(desc)) { + int error = PTR_ERR(desc); - pdata = devm_kzalloc(dev, sizeof(*pdata) + nbuttons * sizeof(*button), - GFP_KERNEL); - if (!pdata) - return ERR_PTR(-ENOMEM); + if (error != -EPROBE_DEFER) + dev_err(dev, "Failed to get gpio flags, error: %d\n", + error); + return error; + } - pdata->buttons = (struct gpio_keys_button *)(pdata + 1); - pdata->nbuttons = nbuttons; + button->gpio = desc_to_gpio(desc); + button->active_low = flags & GPIO_ACTIVE_LOW; - pdata->rep = !!of_get_property(node, "autorepeat", NULL); - of_property_read_u32(node, "poll-interval", &pdata->poll_interval); + if (device_property_read(dev, "linux,code", DEV_PROP_U32, + &button->code)) { + dev_err(dev, "Button without keycode: 0x%x\n", + button->gpio); + return -EINVAL; + } - i = 0; - for_each_child_of_node(node, pp) { - int gpio; - enum of_gpio_flags flags; + if (!device_property_get(dev, "label", &val)) + button->desc = val; - if (!of_find_property(pp, "gpios", NULL)) { - pdata->nbuttons--; - dev_warn(dev, "Found button without gpios\n"); - continue; - } + if (device_property_read(dev, "linux,input-type", DEV_PROP_U32, + &button->type)) + button->type = EV_KEY; - gpio = of_get_gpio_flags(pp, 0, &flags); - if (gpio < 0) { - error = gpio; - if (error != -EPROBE_DEFER) - dev_err(dev, - "Failed to get gpio flags, error: %d\n", - error); - return ERR_PTR(error); - } + button->wakeup = !device_property_get(dev, "gpio-key,wakeup", NULL); - button = &pdata->buttons[i++]; + if (device_property_read(dev, "debounce-interval", DEV_PROP_U32, + &button->debounce_interval)) + button->debounce_interval = 5; - button->gpio = gpio; - button->active_low = flags & OF_GPIO_ACTIVE_LOW; + c->i++; + return 0; +} - if (of_property_read_u32(pp, "linux,code", &button->code)) { - dev_err(dev, "Button without keycode: 0x%x\n", - button->gpio); - return ERR_PTR(-EINVAL); - } +static struct gpio_keys_platform_data * +gpio_keys_polled_get_devtree_pdata(struct device *dev) +{ + struct gpio_keys_platform_data *pdata; + int size; + struct button_proc_context c; + int error; + int nbuttons; - button->desc = of_get_property(pp, "label", NULL); + nbuttons = device_property_child_count(dev); + if (nbuttons <= 0) + return NULL; - if (of_property_read_u32(pp, "linux,input-type", &button->type)) - button->type = EV_KEY; + size = sizeof(*pdata) + nbuttons * sizeof(struct gpio_keys_button); + pdata = devm_kzalloc(dev, size, GFP_KERNEL); + if (!pdata) + return ERR_PTR(-ENOMEM); - button->wakeup = !!of_get_property(pp, "gpio-key,wakeup", NULL); + pdata->buttons = (struct gpio_keys_button *)(pdata + 1); + pdata->nbuttons = nbuttons; - if (of_property_read_u32(pp, "debounce-interval", - &button->debounce_interval)) - button->debounce_interval = 5; - } + pdata->rep = !device_property_get(dev, "autorepeat", NULL); + device_property_read(dev, "poll-interval", DEV_PROP_U32, + &pdata->poll_interval); + + c.pdata = pdata; + c.i = 0; + error = device_for_each_child(dev, &c, gpio_keys_polled_get_button); + if (error) + return ERR_PTR(error); if (pdata->nbuttons == 0) return ERR_PTR(-EINVAL); @@ -181,11 +199,21 @@ static struct gpio_keys_platform_data *gpio_keys_polled_get_devtree_pdata(struct return pdata; } +#ifdef CONFIG_OF static const struct of_device_id gpio_keys_polled_of_match[] = { { .compatible = "gpio-keys-polled", }, { }, }; MODULE_DEVICE_TABLE(of, gpio_keys_polled_of_match); +#endif + +#ifdef CONFIG_ACPI +static struct acpi_device_id gpio_keys_polled_acpi_match[] = { + { "MNW0002" }, + { }, +}; +MODULE_DEVICE_TABLE(acpi, gpio_keys_polled_acpi_match); +#endif #else @@ -309,6 +337,7 @@ static struct platform_driver gpio_keys_polled_driver = { .name = DRV_NAME, .owner = THIS_MODULE, .of_match_table = of_match_ptr(gpio_keys_polled_of_match), + .acpi_match_table = ACPI_PTR(gpio_keys_polled_acpi_match), }, }; module_platform_driver(gpio_keys_polled_driver);