From patchwork Sun Oct 8 23:14:32 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 9992079 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id B64A260231 for ; Sun, 8 Oct 2017 23:16:40 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9446E28634 for ; Sun, 8 Oct 2017 23:16:40 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8728F28640; Sun, 8 Oct 2017 23:16:40 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.3 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C303828634 for ; Sun, 8 Oct 2017 23:16:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751783AbdJHXQj (ORCPT ); Sun, 8 Oct 2017 19:16:39 -0400 Received: from mail-lf0-f46.google.com ([209.85.215.46]:53670 "EHLO mail-lf0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750820AbdJHXQj (ORCPT ); Sun, 8 Oct 2017 19:16:39 -0400 Received: by mail-lf0-f46.google.com with SMTP id l23so18613976lfk.10 for ; Sun, 08 Oct 2017 16:16:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=btEI2Uf/NPLukKLXk0rma/tEGs9ftJ/X5Vexi5lorig=; b=ixSBcfH2cGzPp5al5eAzF8auZt9vSG5ylBx/PkhGeJfEKxYMWxlsCfptty8Y9D4K41 6ImXQKA5DBmBdP/XRHVGfRGBYC5xBIhFZLPnbewHIm7Vsup8EGhwhspDDGo5DqHvISBl zgfjIOlh/dswCBWOEDvWvquCvFHKrnlaN92x0= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=btEI2Uf/NPLukKLXk0rma/tEGs9ftJ/X5Vexi5lorig=; b=uk2kRz0yoAcW0caI7UZ/pPBgOOMXVs8ZkOANPY7onxzgNx5yisbzL+hOTjiP7P7VhG A3PgtRpQAZ2++W2r9sl5JeZx0rcVnAlFg6IycKPyLQESxarmf5WUTis9+UfzY0IKt5bL C1B6qfTkFvMlPwbrRxtzjpsLa9fJ2MP68r6kZV4YNS0jQeBWVAHNhQXLaMsy1WmpuNrN 0D5qY3XVElc/rQR/RzPEzlUpTYu4eTBFPvE7vUVfP7yA24n1e+fT7f/68Ij2tVagWBJL wkamMh7mP9Az/+NbguE1+LtgeQ9NzDZmm5inuNWGl8II8OHeezT/ybTi0orNPtL6ck4Y V43w== X-Gm-Message-State: AMCzsaX9x0VtJfJqmdUTsMSy4zcskYLaJJOQX1sksFGycQOcfA19nZlq GfkDBM51IYNw3Epck0pf1F20CQ== X-Google-Smtp-Source: AOwi7QAGCYqOZSFnzQfVlFQqYou0wWSRQ6Clnvd5mRgJJ6qOjT3jcIxu8VazjbukdkI5vnxwtSNfrA== X-Received: by 10.46.75.2 with SMTP id y2mr3644609lja.91.1507504597387; Sun, 08 Oct 2017 16:16:37 -0700 (PDT) Received: from localhost.localdomain (c-367171d5.014-348-6c756e10.cust.bredbandsbolaget.se. [213.113.113.54]) by smtp.gmail.com with ESMTPSA id c71sm1099108lfg.17.2017.10.08.16.16.35 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sun, 08 Oct 2017 16:16:36 -0700 (PDT) From: Linus Walleij To: Jean Delvare , Guenter Roeck Cc: linux-hwmon@vger.kernel.org, Linus Walleij Subject: [PATCH 9/9 v2] hwmon: gpio-fan: Convert to use GPIO descriptors Date: Mon, 9 Oct 2017 01:14:32 +0200 Message-Id: <20171008231432.6585-1-linus.walleij@linaro.org> X-Mailer: git-send-email 2.13.5 Sender: linux-hwmon-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-hwmon@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This converts the GPIO fan driver to use GPIO descriptors. This way we avoid indirection since the gpiolib anyway just use descriptors inside, and we also get rid of explicit polarity handling: the descriptors internally knows if the line is active high or active low. Signed-off-by: Linus Walleij --- ChangeLog v1->v2: - Fix the polarity of the sysfs alarm file: it does not need to be inverted any more. - Check returned alarm IRQ for <= 0 as 0 is NO_IRQ and not a valid IRQ in Linux. --- drivers/hwmon/gpio-fan.c | 87 +++++++++++++++++------------------------------- 1 file changed, 31 insertions(+), 56 deletions(-) diff --git a/drivers/hwmon/gpio-fan.c b/drivers/hwmon/gpio-fan.c index 18b3c7c27d36..8b57119e841e 100644 --- a/drivers/hwmon/gpio-fan.c +++ b/drivers/hwmon/gpio-fan.c @@ -29,10 +29,9 @@ #include #include #include -#include +#include #include #include -#include #include struct gpio_fan_speed { @@ -47,7 +46,7 @@ struct gpio_fan_data { struct thermal_cooling_device *cdev; struct mutex lock; /* lock GPIOs operations. */ int num_gpios; - unsigned int *gpios; + struct gpio_desc **gpios; int num_speed; struct gpio_fan_speed *speed; int speed_index; @@ -55,8 +54,7 @@ struct gpio_fan_data { int resume_speed; #endif bool pwm_enable; - unsigned int alarm_gpio; - unsigned int alarm_gpio_active_low; + struct gpio_desc *alarm_gpio; struct work_struct alarm_work; }; @@ -86,43 +84,29 @@ static ssize_t fan1_alarm_show(struct device *dev, struct device_attribute *attr, char *buf) { struct gpio_fan_data *fan_data = dev_get_drvdata(dev); - int value = gpio_get_value_cansleep(fan_data->alarm_gpio); - if (fan_data->alarm_gpio_active_low) - value = !value; - - return sprintf(buf, "%d\n", value); + return sprintf(buf, "%d\n", gpiod_get_value_cansleep(fan_data->alarm_gpio)); } static DEVICE_ATTR_RO(fan1_alarm); static int fan_alarm_init(struct gpio_fan_data *fan_data) { - int err; int alarm_irq; struct device *dev = fan_data->dev; - err = devm_gpio_request(dev, fan_data->alarm_gpio, "GPIO fan alarm"); - if (err) - return err; - - err = gpio_direction_input(fan_data->alarm_gpio); - if (err) - return err; - /* * If the alarm GPIO don't support interrupts, just leave * without initializing the fail notification support. */ - alarm_irq = gpio_to_irq(fan_data->alarm_gpio); - if (alarm_irq < 0) + alarm_irq = gpiod_to_irq(fan_data->alarm_gpio); + if (alarm_irq <= 0) return 0; INIT_WORK(&fan_data->alarm_work, fan_alarm_notify); irq_set_irq_type(alarm_irq, IRQ_TYPE_EDGE_BOTH); - err = devm_request_irq(dev, alarm_irq, fan_alarm_irq_handler, - IRQF_SHARED, "GPIO fan alarm", fan_data); - return err; + return devm_request_irq(dev, alarm_irq, fan_alarm_irq_handler, + IRQF_SHARED, "GPIO fan alarm", fan_data); } /* @@ -135,8 +119,8 @@ static void __set_fan_ctrl(struct gpio_fan_data *fan_data, int ctrl_val) int i; for (i = 0; i < fan_data->num_gpios; i++) - gpio_set_value_cansleep(fan_data->gpios[i], - (ctrl_val >> i) & 1); + gpiod_set_value_cansleep(fan_data->gpios[i], + (ctrl_val >> i) & 1); } static int __get_fan_ctrl(struct gpio_fan_data *fan_data) @@ -147,7 +131,7 @@ static int __get_fan_ctrl(struct gpio_fan_data *fan_data) for (i = 0; i < fan_data->num_gpios; i++) { int value; - value = gpio_get_value_cansleep(fan_data->gpios[i]); + value = gpiod_get_value_cansleep(fan_data->gpios[i]); ctrl_val |= (value << i); } return ctrl_val; @@ -362,19 +346,19 @@ static const struct attribute_group *gpio_fan_groups[] = { static int fan_ctrl_init(struct gpio_fan_data *fan_data) { - struct device *dev = fan_data->dev; int num_gpios = fan_data->num_gpios; - unsigned int *gpios = fan_data->gpios; + struct gpio_desc **gpios = fan_data->gpios; int i, err; for (i = 0; i < num_gpios; i++) { - err = devm_gpio_request(dev, gpios[i], - "GPIO fan control"); - if (err) - return err; - - err = gpio_direction_output(gpios[i], - gpio_get_value_cansleep(gpios[i])); + /* + * The GPIO descriptors were retrieved with GPIOD_ASIS so here + * we set the GPIO into output mode, carefully preserving the + * current value by setting it to whatever it is already set + * (no surprise changes in default fan speed). + */ + err = gpiod_direction_output(gpios[i], + gpiod_get_value_cansleep(gpios[i])); if (err) return err; } @@ -437,43 +421,34 @@ static int gpio_fan_get_of_data(struct gpio_fan_data *fan_data) struct gpio_fan_speed *speed; struct device *dev = fan_data->dev; struct device_node *np = dev->of_node; - unsigned int *gpios; + struct gpio_desc **gpios; unsigned i; u32 u; struct property *prop; const __be32 *p; /* Alarm GPIO if one exists */ - if (of_gpio_named_count(np, "alarm-gpios") > 0) { - int val; - enum of_gpio_flags flags; - - val = of_get_named_gpio_flags(np, "alarm-gpios", 0, &flags); - if (val < 0) - return val; - fan_data->alarm_gpio = val; - fan_data->alarm_gpio_active_low = flags & OF_GPIO_ACTIVE_LOW; - } + fan_data->alarm_gpio = devm_gpiod_get_optional(dev, "alarm", GPIOD_IN); + if (IS_ERR(fan_data->alarm_gpio)) + return PTR_ERR(fan_data->alarm_gpio); /* Fill GPIO pin array */ - fan_data->num_gpios = of_gpio_count(np); + fan_data->num_gpios = gpiod_count(dev, NULL); if (fan_data->num_gpios <= 0) { if (fan_data->alarm_gpio) return 0; dev_err(dev, "DT properties empty / missing"); return -ENODEV; } - gpios = devm_kzalloc(dev, fan_data->num_gpios * sizeof(unsigned int), - GFP_KERNEL); + gpios = devm_kzalloc(dev, + fan_data->num_gpios * sizeof(struct gpio_desc *), + GFP_KERNEL); if (!gpios) return -ENOMEM; for (i = 0; i < fan_data->num_gpios; i++) { - int val; - - val = of_get_gpio(np, i); - if (val < 0) - return val; - gpios[i] = val; + gpios[i] = devm_gpiod_get_index(dev, NULL, i, GPIOD_ASIS); + if (IS_ERR(gpios[i])) + return PTR_ERR(gpios[i]); } fan_data->gpios = gpios;