From: Stephen Boyd <sboyd@codeaurora.org>
To: Timur Tabi <timur@codeaurora.org>
Cc: linux-arm-msm@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, linux-gpio@vger.kernel.org,
Linus Walleij <linus.walleij@linaro.org>,
Andy Shevchenko <andriy.shevchenko@linux.intel.com>,
Mika Westerberg <mika.westerberg@linux.intel.com>,
thierry.reding@gmail.com, david.brown@linaro.org,
andy.gross@linaro.org,
Bjorn Andersson <bjorn.andersson@linaro.org>,
Varadarajan Narayanan <varada@codeaurora.org>,
Archit Taneja <architt@codeaurora.org>
Subject: Re: [PATCH 3/3] [v6] pinctrl: qcom: qdf2xxx: add support for new ACPI HID QCOM8002
Date: Wed, 20 Dec 2017 00:15:56 -0800 [thread overview]
Message-ID: <20171220081556.GA30524@codeaurora.org> (raw)
In-Reply-To: <d511f096-bad4-c7b3-d7d4-11b1fa3b1cce@codeaurora.org>
On 12/19, Timur Tabi wrote:
> Frankly, I thought I had everything resolved already, and it sounds
> like you want me to start over from scratch anyway.
>
Here's the patch. I get a hang when dumping debugfs, but at least
sysfs expose fails when trying to request blocked gpios. I need
to check if we need to say "yes" to pins that are above the gpio
max for pinctrl. I'll do that tomorrow.
---
drivers/gpio/gpiolib.c | 4 +-
drivers/pinctrl/qcom/pinctrl-msm.c | 98 ++++++++++++++++++++++++++++++++++++--
include/linux/gpio/driver.h | 3 ++
3 files changed, 99 insertions(+), 6 deletions(-)
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 8db2680bf872..5f118f044caa 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -1475,8 +1475,8 @@ static void gpiochip_irqchip_free_valid_mask(struct gpio_chip *gpiochip)
gpiochip->irq_valid_mask = NULL;
}
-static bool gpiochip_irqchip_irq_valid(const struct gpio_chip *gpiochip,
- unsigned int offset)
+bool gpiochip_irqchip_irq_valid(const struct gpio_chip *gpiochip,
+ unsigned int offset)
{
/* No mask means all valid */
if (likely(!gpiochip->irq_valid_mask))
diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c
index 273badd92561..4c2ce1f7d449 100644
--- a/drivers/pinctrl/qcom/pinctrl-msm.c
+++ b/drivers/pinctrl/qcom/pinctrl-msm.c
@@ -105,6 +105,17 @@ static const struct pinctrl_ops msm_pinctrl_ops = {
.dt_free_map = pinctrl_utils_free_map,
};
+static int msm_pinmux_request(struct pinctrl_dev *pctldev, unsigned offset)
+{
+ struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+ struct gpio_chip *chip = &pctrl->chip;
+
+ if (gpiochip_irqchip_irq_valid(chip, offset))
+ return 0;
+
+ return -EINVAL;
+}
+
static int msm_get_functions_count(struct pinctrl_dev *pctldev)
{
struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
@@ -166,6 +177,7 @@ static int msm_pinmux_set_mux(struct pinctrl_dev *pctldev,
}
static const struct pinmux_ops msm_pinmux_ops = {
+ .request = msm_pinmux_request,
.get_functions_count = msm_get_functions_count,
.get_function_name = msm_get_function_name,
.get_function_groups = msm_get_function_groups,
@@ -493,6 +505,9 @@ static void msm_gpio_dbg_show_one(struct seq_file *s,
"pull up"
};
+ if (!gpiochip_irqchip_irq_valid(chip, offset))
+ return;
+
g = &pctrl->soc->groups[offset];
ctl_reg = readl(pctrl->regs + g->ctl_reg);
@@ -503,7 +518,7 @@ static void msm_gpio_dbg_show_one(struct seq_file *s,
seq_printf(s, " %-8s: %-3s %d", g->name, is_out ? "out" : "in", func);
seq_printf(s, " %dmA", msm_regval_to_drive(drive));
- seq_printf(s, " %s", pulls[pull]);
+ seq_printf(s, " %s\n", pulls[pull]);
}
static void msm_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
@@ -511,10 +526,8 @@ static void msm_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
unsigned gpio = chip->base;
unsigned i;
- for (i = 0; i < chip->ngpio; i++, gpio++) {
+ for (i = 0; i < chip->ngpio; i++, gpio++)
msm_gpio_dbg_show_one(s, NULL, chip, i, gpio);
- seq_puts(s, "\n");
- }
}
#else
@@ -795,6 +808,76 @@ static void msm_gpio_irq_handler(struct irq_desc *desc)
chained_irq_exit(chip, desc);
}
+static int msm_gpio_init_irq_valid_mask(struct gpio_chip *chip,
+ struct msm_pinctrl *pctrl)
+{
+ int ret;
+ unsigned int len, i;
+ unsigned int max_gpios = pctrl->soc->ngpios;
+ struct device_node *np = pctrl->dev->of_node;
+
+ /* The number of GPIOs in the ACPI tables */
+ ret = device_property_read_u16_array(pctrl->dev, "gpios", NULL, 0);
+ if (ret > 0 && ret < max_gpios) {
+ u16 *tmp;
+
+ len = ret;
+ tmp = kmalloc_array(len, sizeof(tmp[0]), GFP_KERNEL);
+ if (!tmp)
+ return -ENOMEM;
+
+ ret = device_property_read_u16_array(pctrl->dev, "gpios", tmp,
+ len);
+ if (ret < 0) {
+ dev_err(pctrl->dev, "could not read list of GPIOs\n");
+ kfree(tmp);
+ return ret;
+ }
+
+ bitmap_zero(chip->irq_valid_mask, max_gpios);
+ for (i = 0; i < len; i++)
+ set_bit(tmp[i], chip->irq_valid_mask);
+
+ return 0;
+ }
+
+ /* If there's a DT ngpios-ranges property then add those ranges */
+ ret = of_property_count_u32_elems(np, "ngpios-ranges");
+ if (ret > 0 && ret % 2 == 0 && ret / 2 < max_gpios) {
+ u32 start;
+ u32 count;
+
+ len = ret / 2;
+ bitmap_zero(chip->irq_valid_mask, max_gpios);
+
+ for (i = 0; i < len; i++) {
+ of_property_read_u32_index(np, "ngpios-ranges",
+ i * 2, &start);
+ of_property_read_u32_index(np, "ngpios-ranges",
+ i * 2 + 1, &count);
+ bitmap_set(chip->irq_valid_mask, start, count);
+ }
+ }
+
+ return 0;
+}
+
+static bool msm_gpio_needs_irq_valid_mask(struct msm_pinctrl *pctrl)
+{
+ int ret;
+ struct device_node *np = pctrl->dev->of_node;
+
+ ret = device_property_read_u16_array(pctrl->dev, "gpios", NULL, 0);
+ if (ret > 0)
+ return true;
+
+ ret = of_property_count_u32_elems(np, "ngpios-ranges");
+ if (ret > 0 && ret % 2 == 0)
+ return true;
+
+ return false;
+}
+
static int msm_gpio_init(struct msm_pinctrl *pctrl)
{
struct gpio_chip *chip;
@@ -811,6 +894,7 @@ static int msm_gpio_init(struct msm_pinctrl *pctrl)
chip->parent = pctrl->dev;
chip->owner = THIS_MODULE;
chip->of_node = pctrl->dev->of_node;
+ chip->irq_need_valid_mask = msm_gpio_needs_irq_valid_mask(pctrl);
ret = gpiochip_add_data(&pctrl->chip, pctrl);
if (ret) {
@@ -818,6 +902,12 @@ static int msm_gpio_init(struct msm_pinctrl *pctrl)
return ret;
}
+ ret = msm_gpio_init_irq_valid_mask(chip, pctrl);
+ if (ret) {
+ dev_err(pctrl->dev, "Failed to setup irq valid bits\n");
+ return ret;
+ }
+
ret = gpiochip_add_pin_range(&pctrl->chip, dev_name(pctrl->dev), 0, 0, chip->ngpio);
if (ret) {
dev_err(pctrl->dev, "Failed to add pin range\n");
diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h
index af20369ec8e7..be977c1c7498 100644
--- a/include/linux/gpio/driver.h
+++ b/include/linux/gpio/driver.h
@@ -262,6 +262,9 @@ int gpiochip_irqchip_add_key(struct gpio_chip *gpiochip,
bool nested,
struct lock_class_key *lock_key);
+bool gpiochip_irqchip_irq_valid(const struct gpio_chip *gpiochip,
+ unsigned int offset);
+
#ifdef CONFIG_LOCKDEP
/*
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
next prev parent reply other threads:[~2017-12-20 8:15 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-12-13 18:30 [PATCH 0/3] [v10] pinctrl: qcom: add support for sparse GPIOs Timur Tabi
2017-12-13 18:30 ` [PATCH 1/3] [v2] Revert "gpio: set up initial state from .get_direction()" Timur Tabi
2017-12-13 22:37 ` Stephen Boyd
2017-12-13 18:30 ` [PATCH 2/3] [v8] pinctrl: qcom: disable GPIO groups with no pins Timur Tabi
2017-12-13 22:37 ` Stephen Boyd
2017-12-13 18:30 ` [PATCH 3/3] [v6] pinctrl: qcom: qdf2xxx: add support for new ACPI HID QCOM8002 Timur Tabi
2017-12-13 23:01 ` Stephen Boyd
2017-12-13 23:09 ` Timur Tabi
2017-12-19 1:18 ` Timur Tabi
2017-12-19 2:39 ` Stephen Boyd
2017-12-19 4:47 ` Timur Tabi
2017-12-19 19:10 ` Stephen Boyd
2017-12-19 19:27 ` Timur Tabi
2017-12-19 20:30 ` Stephen Boyd
2017-12-19 20:32 ` Timur Tabi
2017-12-19 22:56 ` Timur Tabi
2017-12-20 2:26 ` Stephen Boyd
2017-12-20 4:05 ` Timur Tabi
2017-12-20 8:15 ` Stephen Boyd [this message]
2017-12-20 17:46 ` Timur Tabi
2017-12-21 0:39 ` Stephen Boyd
2017-12-21 1:06 ` Timur Tabi
2017-12-22 1:46 ` Stephen Boyd
2018-01-04 15:46 ` Timur Tabi
2018-01-04 16:04 ` Andy Shevchenko
2018-01-09 13:46 ` Linus Walleij
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=20171220081556.GA30524@codeaurora.org \
--to=sboyd@codeaurora.org \
--cc=andriy.shevchenko@linux.intel.com \
--cc=andy.gross@linaro.org \
--cc=architt@codeaurora.org \
--cc=bjorn.andersson@linaro.org \
--cc=david.brown@linaro.org \
--cc=linus.walleij@linaro.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-gpio@vger.kernel.org \
--cc=mika.westerberg@linux.intel.com \
--cc=thierry.reding@gmail.com \
--cc=timur@codeaurora.org \
--cc=varada@codeaurora.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;
as well as URLs for NNTP newsgroup(s).