From patchwork Sun Aug 26 11:03:21 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 145133 Delivered-To: patch@linaro.org Received: by 2002:a2e:1648:0:0:0:0:0 with SMTP id 8-v6csp3078722ljw; Sun, 26 Aug 2018 04:03:28 -0700 (PDT) X-Google-Smtp-Source: ANB0VdbrShphOEeCewQeVQFzQb0JoX0zQdXaWgM+wQU76xdW40u1hCgkjJNm0mOC2ojbAfVUzfBR X-Received: by 2002:a63:27c1:: with SMTP id n184-v6mr8351774pgn.298.1535281408855; Sun, 26 Aug 2018 04:03:28 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1535281408; cv=none; d=google.com; s=arc-20160816; b=mSCElyWSE5YP8M5V4Em3IwiqexnnA9l7AhpH7CQhZUf5WPFx/Rh3Wt58qSUs2/qcJX cnSY7rI6L6ElhwAfzdls12dknHETi/PDwevdvC9ohIlNBiCru1+xkSscs1ZCbkECaf8A FCEJYlqNH1u2vI70is4WQoiQmixvJoa4SnE75MAslgDQn+Vjcq2kIq1ovD/haGUzrbAt Z96vH/r5GjszJwtCxNOHcZG15U7U3I3lwESUqjdZuqX/1+9iPCM5Xz0GUN2Bf1ONosh7 cOyV0gBEeULmxr3GvaxT9YRFcljEPIHwkK7RYHMZqUWIj151Cq9SohjT4zbuQ6grjtVG G1Zg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from :dkim-signature:arc-authentication-results; bh=RcaDJZHuKC7hQyyzJAF9KSPDE91a7AsBZMk3LftP7OE=; b=sjTngCY3EETMQsvDMV7NMkryShtM3gann5TGX4qKxOcQCTl6mH/81j8LEwjY7nWACX 2puD+iFtoptait42gOEzs58AUzWF7TQETNx8gO5vRfZW2lXGrGihj0YuWt5W9CQ8zMFn OTYwi5qhOWsXTY1A5mOah/mKItigxkmV0wuLYqOLwuV137oSZf7vUBFK8u+f5iXILgZN exY5mCFDzx0MLd+5ZDvH1HpR4w6o0sF7zami1WiXQx9dipcIH7gOuQY6yJi4KmJAVNpH FFXVSq7mCu42Rf/GxHqUHLwfeqLM0CyJ/w9eCPsfmpbmJmDHzq7nSfe6MbHhcGuNOx06 CIkQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=IHIPzDRj; spf=pass (google.com: best guess record for domain of linux-gpio-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-gpio-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id m14-v6si11956143pgc.368.2018.08.26.04.03.28; Sun, 26 Aug 2018 04:03:28 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-gpio-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=IHIPzDRj; spf=pass (google.com: best guess record for domain of linux-gpio-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-gpio-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726503AbeHZOpl (ORCPT + 5 others); Sun, 26 Aug 2018 10:45:41 -0400 Received: from mail-lj1-f195.google.com ([209.85.208.195]:34964 "EHLO mail-lj1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726415AbeHZOpl (ORCPT ); Sun, 26 Aug 2018 10:45:41 -0400 Received: by mail-lj1-f195.google.com with SMTP id p10-v6so10065121ljg.2 for ; Sun, 26 Aug 2018 04:03:26 -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=RcaDJZHuKC7hQyyzJAF9KSPDE91a7AsBZMk3LftP7OE=; b=IHIPzDRjjgRcOzgl59og5nZOBIHWLZ1CovAEjIbnECc3UnEEEdPxutssX3oqdEcLLv vTXEW48jOvFnKt6Ngpqg15Mr95IhsMNi3SU1C+W4kRd9K7YCwVgs0g+4lVFedVvsWQYw sRtJt6Hd5g+9KaK42yS4EawfdjpIzLQXOFDYI= 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=RcaDJZHuKC7hQyyzJAF9KSPDE91a7AsBZMk3LftP7OE=; b=D9uZ/kmx2s0xeUaZBOe/WVJ5Q3qzos0+W5D29cuHyg8mDUzVanNRK4VrgYxyShx764 R3riqq+W3crxE6EoJPgtz/j//GwFwvjFEwt1Z1mcFQgW2KMBGev9NUoifb9wnFzGUsiS MLPl+nm0a1Mzjg8MxXgLPly1Pq0ZXawdEIcANtHZzalz/tUDi6F6IhF7BGfepFEI8/y3 92FFRTrEXOGStwpsSrFjbz2ary66uwsxvn0KfcVYUAv6QNQeAfKPpaMgdmsvR4jOoi5T Bo6x9RoWDc7m/l3qQSxiU+5fRzoKStpFpgg1WJr+PlXm1cs18WtFumO7+912WkQWUrS3 ewuA== X-Gm-Message-State: APzg51AJIPHS78wYEdZqqC6+/ucCyqiitCfYtV53tbt555lh4iMlaP2P sV4OmShL9ENL6GVlJ84XcCyCVA== X-Received: by 2002:a2e:7014:: with SMTP id l20-v6mr6040516ljc.141.1535281405454; Sun, 26 Aug 2018 04:03:25 -0700 (PDT) Received: from localhost.bredbandsbolaget (c-ae7b71d5.014-348-6c756e10.bbcust.telenor.se. [213.113.123.174]) by smtp.gmail.com with ESMTPSA id y2-v6sm1478146ljc.52.2018.08.26.04.03.23 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sun, 26 Aug 2018 04:03:24 -0700 (PDT) From: Linus Walleij To: Hans Ulli Kroll , Florian Fainelli , Jonas Jensen Cc: linux-arm-kernel@lists.infradead.org, linux-gpio@vger.kernel.org, Linus Walleij Subject: [PATCH 1/2] gpio: ftgpio: Support optional silicon clock Date: Sun, 26 Aug 2018 13:03:21 +0200 Message-Id: <20180826110321.17723-1-linus.walleij@linaro.org> X-Mailer: git-send-email 2.17.1 Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org The GPIO silicon is clocked with a PCLK (peripheral clock) on all systems, however not all platforms model it and include it in e.g. the device tree, so add clock handling but make it optional so we bail out safely if it is e.g. always on. Signed-off-by: Linus Walleij --- drivers/gpio/gpio-ftgpio010.c | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) -- 2.17.1 diff --git a/drivers/gpio/gpio-ftgpio010.c b/drivers/gpio/gpio-ftgpio010.c index 868bf8501560..c26feab143a3 100644 --- a/drivers/gpio/gpio-ftgpio010.c +++ b/drivers/gpio/gpio-ftgpio010.c @@ -15,6 +15,7 @@ #include #include #include +#include /* GPIO registers definition */ #define GPIO_DATA_OUT 0x00 @@ -40,11 +41,14 @@ * struct ftgpio_gpio - Gemini GPIO state container * @dev: containing device for this instance * @gc: gpiochip for this instance + * @base: remapped I/O-memory base + * @clk: silicon clock */ struct ftgpio_gpio { struct device *dev; struct gpio_chip gc; void __iomem *base; + struct clk *clk; }; static void ftgpio_gpio_ack_irq(struct irq_data *d) @@ -180,6 +184,13 @@ static int ftgpio_gpio_probe(struct platform_device *pdev) if (irq <= 0) return irq ? irq : -EINVAL; + g->clk = devm_clk_get(dev, NULL); + if (!IS_ERR(g->clk)) { + ret = clk_prepare_enable(g->clk); + if (ret) + return ret; + } + ret = bgpio_init(&g->gc, dev, 4, g->base + GPIO_DATA_IN, g->base + GPIO_DATA_SET, @@ -189,7 +200,7 @@ static int ftgpio_gpio_probe(struct platform_device *pdev) 0); if (ret) { dev_err(dev, "unable to init generic GPIO\n"); - return ret; + goto dis_clk; } g->gc.label = "FTGPIO010"; g->gc.base = -1; @@ -199,7 +210,7 @@ static int ftgpio_gpio_probe(struct platform_device *pdev) ret = devm_gpiochip_add_data(dev, &g->gc, g); if (ret) - return ret; + goto dis_clk; /* Disable, unmask and clear all interrupts */ writel(0x0, g->base + GPIO_INT_EN); @@ -211,14 +222,29 @@ static int ftgpio_gpio_probe(struct platform_device *pdev) IRQ_TYPE_NONE); if (ret) { dev_info(dev, "could not add irqchip\n"); - return ret; + goto dis_clk; } gpiochip_set_chained_irqchip(&g->gc, &ftgpio_gpio_irqchip, irq, ftgpio_gpio_irq_handler); + platform_set_drvdata(pdev, g); dev_info(dev, "FTGPIO010 @%p registered\n", g->base); return 0; + +dis_clk: + if (!IS_ERR(g->clk)) + clk_disable_unprepare(g->clk); + return ret; +} + +static int ftgpio_gpio_remove(struct platform_device *pdev) +{ + struct ftgpio_gpio *g = platform_get_drvdata(pdev); + + if (!IS_ERR(g->clk)) + clk_disable_unprepare(g->clk); + return 0; } static const struct of_device_id ftgpio_gpio_of_match[] = { @@ -239,6 +265,7 @@ static struct platform_driver ftgpio_gpio_driver = { .name = "ftgpio010-gpio", .of_match_table = of_match_ptr(ftgpio_gpio_of_match), }, - .probe = ftgpio_gpio_probe, + .probe = ftgpio_gpio_probe, + .remove = ftgpio_gpio_remove, }; builtin_platform_driver(ftgpio_gpio_driver); From patchwork Sun Aug 26 11:03:29 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 145134 Delivered-To: patch@linaro.org Received: by 2002:a2e:1648:0:0:0:0:0 with SMTP id 8-v6csp3078820ljw; Sun, 26 Aug 2018 04:03:36 -0700 (PDT) X-Google-Smtp-Source: ANB0VdaTFFjLJw7ehnpzy41FjNvDm0M88l5C4vYmEwktoh+4vJqvKTgqMZBWPzpmhYkh0pNuDYKd X-Received: by 2002:a63:1866:: with SMTP id 38-v6mr8305599pgy.313.1535281416384; Sun, 26 Aug 2018 04:03:36 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1535281416; cv=none; d=google.com; s=arc-20160816; b=Lcu8Kv7izRJBpbw8zaSnwA66VRd3tmDP+Sv4WgGt8Qf3QGU7Amp4BC9ihx4jw7Dg/M yaOI2TlKMxBUt+Baqm/Mn1hMR9lTWdmWSfJTL6XE+7hxpuQT+WqZ/l4T1CytF/upVOx+ yTN0ooQZOsfJWD/MMVGDZw8yeSeoztCnC47jOf4w2E1/xSn8a2zlAmA5NP57Gun3Xyci Dn9vTD1+HI6WqeTcMYzr9cHiclPmSBT6g8DhtcdyuvB2CNRP5Yv/iqRG/lv+vxgyLA3n eS+Umxs7XnUeLUbnEaRHWEo04gwmmie83MtIQ02CuyUtKHdbaG/ZpQP6jkpTHK55YEmP 0eYg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from :dkim-signature:arc-authentication-results; bh=sPfeoUA2/PuDJTk+m7dzAZUmI6BlXQyU2SBh15Y+Ewk=; b=S0YFEOANPn1brWVQY5DVnFVkRWCDhtl+17bNcAovx+/6nLv149IPSv0PCkgh0th1BQ tofOz2FwxziXF/xUjA/rErjPjKFoz1PAirBS/dNTzghsCvmBrqZljdnQMjbaiitCC1sR REcSn7sg7xTRDYPaSFdlc9IC0i/FjmK9ixlEoGyquj+9K2UZQ+bEniFSUCL1o9stsa+g BO9uRlGImpDHCcmx+VxU/DOLPGkKPBTjUa/gQpVMoZFcWVDklqh1rnqGCdMhHSAaDx/w 6AvZZyugD9IhEV7npLDS3JTVTYvLF6/AikkQ6hKZ16uI8Srucx7LJ05uKvwZtQAPiL1/ h/6g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=jWxp9WSx; spf=pass (google.com: best guess record for domain of linux-gpio-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-gpio-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id e39-v6si11916259plg.386.2018.08.26.04.03.36; Sun, 26 Aug 2018 04:03:36 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-gpio-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=jWxp9WSx; spf=pass (google.com: best guess record for domain of linux-gpio-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-gpio-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726542AbeHZOpt (ORCPT + 5 others); Sun, 26 Aug 2018 10:45:49 -0400 Received: from mail-lf1-f65.google.com ([209.85.167.65]:44412 "EHLO mail-lf1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726415AbeHZOpt (ORCPT ); Sun, 26 Aug 2018 10:45:49 -0400 Received: by mail-lf1-f65.google.com with SMTP id g6-v6so9756068lfb.11 for ; Sun, 26 Aug 2018 04:03:34 -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=sPfeoUA2/PuDJTk+m7dzAZUmI6BlXQyU2SBh15Y+Ewk=; b=jWxp9WSxaqoXzyX6//ZT8m3ihJexCwsIw59IGALEz8It6QIXC6b6XQKrKCBMmLU4vC jNUi+P9ngqk0xo0oiDD6gb3wDKFvttNNf5V4b4eqvfpyFS4n82PXrrEelftLizLkqgzP ahugTQuSHa4hWTLJMa4QJXLyRRtjB9h8ZgLLI= 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=sPfeoUA2/PuDJTk+m7dzAZUmI6BlXQyU2SBh15Y+Ewk=; b=G2x0h0RnHx15Q1gmDMEAcg9IY1NWRqa8nRFhRdk+Rj8V6Qu6fayuj4gvt02NMFwVMi Qq1hC0QwYdZx2vDqUANl4XgT1lm0alPTYL0p8rbXq99U00e71ipTq3Xup2oJhqupFktB 3CFrBJ2Vc2HNDHV40uA2sLkGDFSPLKxvY2Etnv8St28Q7TsdcbmEOxt/u22RA8UV7hrc HmHsS1XpZM1wi+JSGxqfuTRMQdls0kbuO2y+FfJWvsQqjcvMUgjPDIw/VY4m1GsV2Mv2 /eencTTO0BuEOZUp/PNPAMe0R5FH8aPmFNygbkFNRrxQZqpdvpxMV79RNIcZP7pc/boW p1tg== X-Gm-Message-State: APzg51A1Qx6o1kKRtOUJuLWtF7Obq4NS2EJL8LPQkK6u++mGw3kmh9s7 nzKvIc581pNxKbwQdtW7hlDsow== X-Received: by 2002:a19:d095:: with SMTP id h143-v6mr5687916lfg.16.1535281413183; Sun, 26 Aug 2018 04:03:33 -0700 (PDT) Received: from localhost.bredbandsbolaget (c-ae7b71d5.014-348-6c756e10.bbcust.telenor.se. [213.113.123.174]) by smtp.gmail.com with ESMTPSA id g16-v6sm2157289lje.1.2018.08.26.04.03.31 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sun, 26 Aug 2018 04:03:32 -0700 (PDT) From: Linus Walleij To: Hans Ulli Kroll , Florian Fainelli , Jonas Jensen Cc: linux-arm-kernel@lists.infradead.org, linux-gpio@vger.kernel.org, Linus Walleij Subject: [PATCH 2/2] gpio: ftgpio: Support debounce timer Date: Sun, 26 Aug 2018 13:03:29 +0200 Message-Id: <20180826110329.17778-1-linus.walleij@linaro.org> X-Mailer: git-send-email 2.17.1 Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org The FTGPIO010 has a debounce timer or rather prescaler that will affect interrupts fireing off the block. We can support this to get proper debounce on e.g. keypresses. Since the same prescaler is used across all GPIO lines of the silicon block, we need to bail out if the prescaler is already set and in use by another line. If the prescaler is already set to what we need, fine, we reuse it. This happens more often than not when the same debounce time is set for several GPIO keys, so we support that usecase easily with this code. Signed-off-by: Linus Walleij --- drivers/gpio/gpio-ftgpio010.c | 74 +++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) -- 2.17.1 diff --git a/drivers/gpio/gpio-ftgpio010.c b/drivers/gpio/gpio-ftgpio010.c index c26feab143a3..3645607440b5 100644 --- a/drivers/gpio/gpio-ftgpio010.c +++ b/drivers/gpio/gpio-ftgpio010.c @@ -161,6 +161,73 @@ static void ftgpio_gpio_irq_handler(struct irq_desc *desc) chained_irq_exit(irqchip, desc); } +static int ftgpio_gpio_set_config(struct gpio_chip *gc, unsigned int offset, + unsigned long config) +{ + enum pin_config_param param = pinconf_to_config_param(config); + u32 arg = pinconf_to_config_argument(config); + struct ftgpio_gpio *g = gpiochip_get_data(gc); + unsigned long pclk_freq; + u32 deb_div; + u32 val; + + if (param != PIN_CONFIG_INPUT_DEBOUNCE) + return -ENOTSUPP; + + /* + * Debounce only works if interrupts are enabled. The manual + * states that if PCLK is 66 MHz, and this is set to 0x7D0, then + * PCLK is divided down to 33 kHz for the debounce timer. 0x7D0 is + * 2000 decimal, so what they mean is simply that the PCLK is + * divided by this value. + * + * As we get a debounce setting in microseconds, we calculate the + * desired period time and see if we can get a suitable debounce + * time. + */ + pclk_freq = clk_get_rate(g->clk); + deb_div = DIV_ROUND_CLOSEST(pclk_freq, arg); + + /* This register is only 24 bits wide */ + if (deb_div > (1 << 24)) + return -ENOTSUPP; + + dev_dbg(g->dev, "prescale divisor: %08x, resulting frequency %lu Hz\n", + deb_div, (pclk_freq/deb_div)); + + val = readl(g->base + GPIO_DEBOUNCE_PRESCALE); + if (val == deb_div) { + /* + * The debounce timer happens to already be set to the + * desireable value, what a coincidence! We can just enable + * debounce on this GPIO line and return. This happens more + * often than you think, for example when all GPIO keys + * on a system are requesting the same debounce interval. + */ + val = readl(g->base + GPIO_DEBOUNCE_EN); + val |= BIT(offset); + writel(val, g->base + GPIO_DEBOUNCE_EN); + return 0; + } + + val = readl(g->base + GPIO_DEBOUNCE_EN); + if (val) { + /* + * Oh no! Someone is already using the debounce with + * another setting than what we need. Bummer. + */ + return -ENOTSUPP; + } + + /* First come, first serve */ + writel(deb_div, g->base + GPIO_DEBOUNCE_PRESCALE); + /* Enable debounce */ + val |= BIT(offset); + writel(val, g->base + GPIO_DEBOUNCE_EN); + + return 0; +} + static int ftgpio_gpio_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -208,6 +275,10 @@ static int ftgpio_gpio_probe(struct platform_device *pdev) g->gc.owner = THIS_MODULE; /* ngpio is set by bgpio_init() */ + /* We need a silicon clock to do debounce */ + if (!IS_ERR(g->clk)) + g->gc.set_config = ftgpio_gpio_set_config; + ret = devm_gpiochip_add_data(dev, &g->gc, g); if (ret) goto dis_clk; @@ -217,6 +288,9 @@ static int ftgpio_gpio_probe(struct platform_device *pdev) writel(0x0, g->base + GPIO_INT_MASK); writel(~0x0, g->base + GPIO_INT_CLR); + /* Clear any use of debounce */ + writel(val, g->base + GPIO_DEBOUNCE_EN); + ret = gpiochip_irqchip_add(&g->gc, &ftgpio_gpio_irqchip, 0, handle_bad_irq, IRQ_TYPE_NONE);