From: Paul Kocialkowski <paulk@sys-base.io>
To: linux-arm-kernel@lists.infradead.org,
linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org
Cc: "Uwe Kleine-König" <ukleinek@kernel.org>,
"Chen-Yu Tsai" <wens@csie.org>,
"Jernej Skrabec" <jernej.skrabec@gmail.com>,
"Samuel Holland" <samuel@sholland.org>,
"Linus Walleij" <linus.walleij@linaro.org>,
"Maxime Ripard" <mripard@kernel.org>,
"Paul Kocialkowski" <contact@paulk.fr>
Subject: [PATCH] pinctrl: sunxi: Use minimal debouncing period as default
Date: Tue, 19 Nov 2024 15:08:05 +0100 [thread overview]
Message-ID: <20241119140805.3345412-1-paulk@sys-base.io> (raw)
From: Paul Kocialkowski <contact@paulk.fr>
The sunxi external interrupts (available from GPIO pins) come with a
built-in debouncing mechanism that cannot be disabled. It can be
configured to use either the low-frequency oscillator (32 KHz) or the
high-frequency oscillator (24 MHz), with a pre-scaler.
The pinctrl code supports an input-debounce device-tree property to set
a specific debouncing period and choose which clock source is most
relevant. However the property is specified in microseconds, which is
longer than the minimal period achievable from the high-frequency
oscillator without a pre-scaler.
When the property is missing, the reset configuration is kept, which
selects the low-frequency oscillator without pre-scaling. This severely
limits the possible interrupt periods that can be detected.
Instead of keeping this default, use the minimal debouncing period from
the high-frequency oscillator without a pre-scaler to allow the largest
possible range of interrupt periods.
This issue was encountered with a peripheral that generates active-low
interrupts for 1 us. No interrupt was detected with the default setup,
while it is now correctly detected with this change.
Signed-off-by: Paul Kocialkowski <contact@paulk.fr>
---
drivers/pinctrl/sunxi/pinctrl-sunxi.c | 49 ++++++++++++++++-----------
1 file changed, 29 insertions(+), 20 deletions(-)
diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
index 73bcf806af0e..06c650d97645 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
+++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
@@ -1416,6 +1416,7 @@ static int sunxi_pinctrl_setup_debounce(struct sunxi_pinctrl *pctl,
unsigned int hosc_diff, losc_diff;
unsigned int hosc_div, losc_div;
struct clk *hosc, *losc;
+ bool debounce_minimal = false;
u8 div, src;
int i, ret;
@@ -1423,9 +1424,9 @@ static int sunxi_pinctrl_setup_debounce(struct sunxi_pinctrl *pctl,
if (of_clk_get_parent_count(node) != 3)
return 0;
- /* If we don't have any setup, bail out */
+ /* If we don't have any setup, use minimal debouncing. */
if (!of_property_present(node, "input-debounce"))
- return 0;
+ debounce_minimal = true;
losc = devm_clk_get(pctl->dev, "losc");
if (IS_ERR(losc))
@@ -1439,29 +1440,37 @@ static int sunxi_pinctrl_setup_debounce(struct sunxi_pinctrl *pctl,
unsigned long debounce_freq;
u32 debounce;
- ret = of_property_read_u32_index(node, "input-debounce",
- i, &debounce);
- if (ret)
- return ret;
+ if (!debounce_minimal) {
+ ret = of_property_read_u32_index(node, "input-debounce",
+ i, &debounce);
+ if (ret)
+ return ret;
- if (!debounce)
- continue;
+ if (!debounce)
+ continue;
- debounce_freq = DIV_ROUND_CLOSEST(USEC_PER_SEC, debounce);
- losc_div = sunxi_pinctrl_get_debounce_div(losc,
- debounce_freq,
- &losc_diff);
+ debounce_freq = DIV_ROUND_CLOSEST(USEC_PER_SEC,
+ debounce);
- hosc_div = sunxi_pinctrl_get_debounce_div(hosc,
- debounce_freq,
- &hosc_diff);
+ losc_div = sunxi_pinctrl_get_debounce_div(losc,
+ debounce_freq,
+ &losc_diff);
- if (hosc_diff < losc_diff) {
- div = hosc_div;
- src = 1;
+ hosc_div = sunxi_pinctrl_get_debounce_div(hosc,
+ debounce_freq,
+ &hosc_diff);
+
+ if (hosc_diff < losc_diff) {
+ div = hosc_div;
+ src = 1;
+ } else {
+ div = losc_div;
+ src = 0;
+ }
} else {
- div = losc_div;
- src = 0;
+ /* Achieve minimal debouncing using undivided hosc. */
+ div = 0;
+ src = 1;
}
writel(src | div << 4,
--
2.47.0
next reply other threads:[~2024-11-19 14:29 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-11-19 14:08 Paul Kocialkowski [this message]
2024-11-19 14:43 ` [PATCH] pinctrl: sunxi: Use minimal debouncing period as default Maxime Ripard
2024-11-19 15:00 ` Paul Kocialkowski
2024-11-19 15:43 ` Maxime Ripard
2024-11-19 18:47 ` Paul Kocialkowski
2024-11-20 8:01 ` Maxime Ripard
2024-11-20 10:05 ` Paul Kocialkowski
2024-11-29 15:37 ` Maxime Ripard
2024-11-30 10:34 ` Paul Kocialkowski
2024-12-02 11:03 ` Maxime Ripard
2024-12-03 10:58 ` Paul Kocialkowski
2024-12-17 13:39 ` Linus Walleij
2025-01-07 11:53 ` Paul Kocialkowski
2024-12-17 13:41 ` Linus Walleij
2024-12-17 13:58 ` Maxime Ripard
2025-01-07 11:55 ` Paul Kocialkowski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20241119140805.3345412-1-paulk@sys-base.io \
--to=paulk@sys-base.io \
--cc=contact@paulk.fr \
--cc=jernej.skrabec@gmail.com \
--cc=linus.walleij@linaro.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-sunxi@lists.linux.dev \
--cc=mripard@kernel.org \
--cc=samuel@sholland.org \
--cc=ukleinek@kernel.org \
--cc=wens@csie.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox