* Re: [PATCH] Revert "spi: gpio: Don't request CS GPIO in DT use-case"
From: Linus Walleij @ 2019-07-02 19:41 UTC (permalink / raw)
To: Mark Brown; +Cc: linux-spi, open list:GPIO SUBSYSTEM, Andrey Smirnov
In-Reply-To: <CACRpkdbng1M=5BnzFuiubRaqM1Bu4eLxqKvb3fCQuqyKsVcBjg@mail.gmail.com>
On Tue, Jul 2, 2019 at 3:08 PM Linus Walleij <linus.walleij@linaro.org> wrote:
> I am trying to rootcause it, I suspect I was just the first to try this
> on real hardware actually.
Ha! I found it. Only affects active high CS GPIO users.
A nasty one. Sent a patch.
Yours,
Linus Walleij
^ permalink raw reply
* [PATCH] gpio/spi: Fix spi-gpio regression on active high CS
From: Linus Walleij @ 2019-07-02 19:39 UTC (permalink / raw)
To: Mark Brown, linux-spi; +Cc: linux-gpio, Linus Walleij, Andrey Smirnov
I ran into an intriguing bug caused by
commit ""spi: gpio: Don't request CS GPIO in DT use-case"
affecting all SPI GPIO devices with an active high
chip select line.
The commit switches the CS gpio handling over to the GPIO
core, which will parse and handle "cs-gpios" from the OF
node without even calling down to the driver to get the
job done.
However the GPIO core handles the standard bindings in
Documentation/devicetree/bindings/spi/spi-controller.yaml
that specifies that active high CS needs to be specified
using "spi-cs-high" in the DT node.
The code in drivers/spi/spi-gpio.c never respected this
and never tried to inspect subnodes to see if they contained
"spi-cs-high" like the gpiolib OF quirks does. Instead the
only way to get an active high CS was to tag it in the
device tree using the flags cell such as
cs-gpios = <&gpio 4 GPIO_ACTIVE_HIGH>;
This alters the quirks to not inspect the subnodes of SPI
masters on "spi-gpio" for the standard attribute "spi-cs-high",
making old device trees work as expected.
This semantic is a bit ambigous, but just allowing the
flags on the GPIO descriptor to modify polarity is what
the kernel at large mostly uses so let's encourage that.
Fixes: 249e2632dcd0 ("spi: gpio: Don't request CS GPIO in DT use-case")
Cc: Andrey Smirnov <andrew.smirnov@gmail.com>
Cc: linux-gpio@vger.kernel.org
Cc: linux-spi@vger.kernel.org
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
Mark: I will apply this to the GPIO tree, so I think it is
safe for you to drop my revert of Andrey's patch once this
hits mainline. I will try to expediate it, I feel a bit
responsible.
---
drivers/gpio/gpiolib-of.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
index aec7bd86ae7e..9c9b965d7d6d 100644
--- a/drivers/gpio/gpiolib-of.c
+++ b/drivers/gpio/gpiolib-of.c
@@ -118,8 +118,15 @@ static void of_gpio_flags_quirks(struct device_node *np,
* Legacy handling of SPI active high chip select. If we have a
* property named "cs-gpios" we need to inspect the child node
* to determine if the flags should have inverted semantics.
+ *
+ * This does not apply to an SPI device named "spi-gpio", because
+ * these have traditionally obtained their own GPIOs by parsing
+ * the device tree directly and did not respect any "spi-cs-high"
+ * property on the SPI bus children.
*/
- if (IS_ENABLED(CONFIG_SPI_MASTER) && !strcmp(propname, "cs-gpios") &&
+ if (IS_ENABLED(CONFIG_SPI_MASTER) &&
+ !strcmp(propname, "cs-gpios") &&
+ !of_device_is_compatible(np, "spi-gpio") &&
of_property_read_bool(np, "cs-gpios")) {
struct device_node *child;
u32 cs;
--
2.21.0
^ permalink raw reply related
* Re: [PATCH] Revert "spi: gpio: Don't request CS GPIO in DT use-case"
From: Linus Walleij @ 2019-07-02 13:08 UTC (permalink / raw)
To: Mark Brown; +Cc: linux-spi, open list:GPIO SUBSYSTEM, Andrey Smirnov
In-Reply-To: <20190702113914.GH2793@sirena.org.uk>
On Tue, Jul 2, 2019 at 1:39 PM Mark Brown <broonie@kernel.org> wrote:
> On Mon, Jul 01, 2019 at 07:25:17PM +0200, Linus Walleij wrote:
> > This reverts commit 249e2632dcd0509b8f8f296f5aabf4d48dfd6da8.
> >
> > After this commit drivers/net/dsa/vitesse-vsc73xx.c stopped
> > working. Apparently CS is not working because the reads
> > from the device is just returning just 1:s or just 0:s at
> > all bisection points, so it is a complete regression and
> > I think spi-gpio CS is essentially broken.
>
> Also I'm a bit concerned that nobody else noticed this - do we
> have any understanding of what the actual problem is?
I am trying to rootcause it, I suspect I was just the first to try this
on real hardware actually.
The users in the device trees in the kernel
mostly point to consumers like LEDs, displays and switches
that wouldn't cause boot regressions
instead you must observe more elaborate aspects of the system
so that is why the automatic test farms cannot see it.
Yours,
Linus Walleij
^ permalink raw reply
* Applied "Revert "spi: gpio: Don't request CS GPIO in DT use-case"" to the spi tree
From: Mark Brown @ 2019-07-02 13:04 UTC (permalink / raw)
To: Linus Walleij; +Cc: Andrey Smirnov, linux-gpio, linux-spi, Mark Brown
In-Reply-To: <20190701172517.31641-1-linus.walleij@linaro.org>
The patch
Revert "spi: gpio: Don't request CS GPIO in DT use-case"
has been applied to the spi tree at
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-5.3
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
From 0540ac3729da9c7d664197151fb7f432a1e11e3a Mon Sep 17 00:00:00 2001
From: Linus Walleij <linus.walleij@linaro.org>
Date: Mon, 1 Jul 2019 19:25:17 +0200
Subject: [PATCH] Revert "spi: gpio: Don't request CS GPIO in DT use-case"
This reverts commit 249e2632dcd0509b8f8f296f5aabf4d48dfd6da8.
After this commit drivers/net/dsa/vitesse-vsc73xx.c stopped
working. Apparently CS is not working because the reads
from the device is just returning just 1:s or just 0:s at
all bisection points, so it is a complete regression and
I think spi-gpio CS is essentially broken.
The revert had to be hand-crafted to preserve all the other
cleanup and changes to this driver, but now it works.
I'm sad to revert the change because it is a nice cleanup
but with the short time before v5.2 is released this is
probably the best idea, so we can figure out the right way
to do this in the next kernel cycle.
Fixes: 249e2632dcd0 ("spi: gpio: Don't request CS GPIO in DT use-case")
Cc: Andrey Smirnov <andrew.smirnov@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
drivers/spi/spi-gpio.c | 137 +++++++++++++++++++++++------------------
1 file changed, 78 insertions(+), 59 deletions(-)
diff --git a/drivers/spi/spi-gpio.c b/drivers/spi/spi-gpio.c
index eca9d52ecf65..7cf800efef93 100644
--- a/drivers/spi/spi-gpio.c
+++ b/drivers/spi/spi-gpio.c
@@ -36,6 +36,7 @@ struct spi_gpio {
struct gpio_desc *miso;
struct gpio_desc *mosi;
struct gpio_desc **cs_gpios;
+ bool has_cs;
};
/*----------------------------------------------------------------------*/
@@ -205,7 +206,7 @@ static void spi_gpio_chipselect(struct spi_device *spi, int is_active)
gpiod_set_value_cansleep(spi_gpio->sck, spi->mode & SPI_CPOL);
/* Drive chip select line, if we have one */
- if (spi_gpio->cs_gpios) {
+ if (spi_gpio->has_cs) {
struct gpio_desc *cs = spi_gpio->cs_gpios[spi->chip_select];
/* SPI chip selects are normally active-low */
@@ -223,12 +224,10 @@ static int spi_gpio_setup(struct spi_device *spi)
* The CS GPIOs have already been
* initialized from the descriptor lookup.
*/
- if (spi_gpio->cs_gpios) {
- cs = spi_gpio->cs_gpios[spi->chip_select];
- if (!spi->controller_state && cs)
- status = gpiod_direction_output(cs,
- !(spi->mode & SPI_CS_HIGH));
- }
+ cs = spi_gpio->cs_gpios[spi->chip_select];
+ if (!spi->controller_state && cs)
+ status = gpiod_direction_output(cs,
+ !(spi->mode & SPI_CS_HIGH));
if (!status)
status = spi_bitbang_setup(spi);
@@ -279,8 +278,12 @@ static void spi_gpio_cleanup(struct spi_device *spi)
* floating signals. (A weak pulldown would save power too, but many
* drivers expect to see all-ones data as the no slave "response".)
*/
-static int spi_gpio_request(struct device *dev, struct spi_gpio *spi_gpio)
+static int spi_gpio_request(struct device *dev,
+ struct spi_gpio *spi_gpio,
+ unsigned int num_chipselects)
{
+ int i;
+
spi_gpio->mosi = devm_gpiod_get_optional(dev, "mosi", GPIOD_OUT_LOW);
if (IS_ERR(spi_gpio->mosi))
return PTR_ERR(spi_gpio->mosi);
@@ -293,6 +296,13 @@ static int spi_gpio_request(struct device *dev, struct spi_gpio *spi_gpio)
if (IS_ERR(spi_gpio->sck))
return PTR_ERR(spi_gpio->sck);
+ for (i = 0; i < num_chipselects; i++) {
+ spi_gpio->cs_gpios[i] = devm_gpiod_get_index(dev, "cs",
+ i, GPIOD_OUT_HIGH);
+ if (IS_ERR(spi_gpio->cs_gpios[i]))
+ return PTR_ERR(spi_gpio->cs_gpios[i]);
+ }
+
return 0;
}
@@ -303,55 +313,44 @@ static const struct of_device_id spi_gpio_dt_ids[] = {
};
MODULE_DEVICE_TABLE(of, spi_gpio_dt_ids);
-static int spi_gpio_probe_dt(struct platform_device *pdev,
- struct spi_master *master)
+static int spi_gpio_probe_dt(struct platform_device *pdev)
{
- master->dev.of_node = pdev->dev.of_node;
- master->use_gpio_descriptors = true;
-
- return 0;
-}
-#else
-static inline int spi_gpio_probe_dt(struct platform_device *pdev,
- struct spi_master *master)
-{
- return 0;
-}
-#endif
-
-static int spi_gpio_probe_pdata(struct platform_device *pdev,
- struct spi_master *master)
-{
- struct device *dev = &pdev->dev;
- struct spi_gpio_platform_data *pdata = dev_get_platdata(dev);
- struct spi_gpio *spi_gpio = spi_master_get_devdata(master);
- int i;
+ int ret;
+ u32 tmp;
+ struct spi_gpio_platform_data *pdata;
+ struct device_node *np = pdev->dev.of_node;
+ const struct of_device_id *of_id =
+ of_match_device(spi_gpio_dt_ids, &pdev->dev);
-#ifdef GENERIC_BITBANG
- if (!pdata || !pdata->num_chipselect)
- return -ENODEV;
-#endif
- /*
- * The master needs to think there is a chipselect even if not
- * connected
- */
- master->num_chipselect = pdata->num_chipselect ?: 1;
+ if (!of_id)
+ return 0;
- spi_gpio->cs_gpios = devm_kcalloc(dev, master->num_chipselect,
- sizeof(*spi_gpio->cs_gpios),
- GFP_KERNEL);
- if (!spi_gpio->cs_gpios)
+ pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata)
return -ENOMEM;
- for (i = 0; i < master->num_chipselect; i++) {
- spi_gpio->cs_gpios[i] = devm_gpiod_get_index(dev, "cs", i,
- GPIOD_OUT_HIGH);
- if (IS_ERR(spi_gpio->cs_gpios[i]))
- return PTR_ERR(spi_gpio->cs_gpios[i]);
+
+ ret = of_property_read_u32(np, "num-chipselects", &tmp);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "num-chipselects property not found\n");
+ goto error_free;
}
+ pdata->num_chipselect = tmp;
+ pdev->dev.platform_data = pdata;
+
+ return 1;
+
+error_free:
+ devm_kfree(&pdev->dev, pdata);
+ return ret;
+}
+#else
+static inline int spi_gpio_probe_dt(struct platform_device *pdev)
+{
return 0;
}
+#endif
static void spi_gpio_put(void *data)
{
@@ -363,11 +362,22 @@ static int spi_gpio_probe(struct platform_device *pdev)
int status;
struct spi_master *master;
struct spi_gpio *spi_gpio;
+ struct spi_gpio_platform_data *pdata;
struct device *dev = &pdev->dev;
struct spi_bitbang *bb;
- const struct of_device_id *of_id;
+ bool use_of = 0;
- of_id = of_match_device(spi_gpio_dt_ids, &pdev->dev);
+ status = spi_gpio_probe_dt(pdev);
+ if (status < 0)
+ return status;
+ if (status > 0)
+ use_of = 1;
+
+ pdata = dev_get_platdata(dev);
+#ifdef GENERIC_BITBANG
+ if (!pdata || (!use_of && !pdata->num_chipselect))
+ return -ENODEV;
+#endif
master = spi_alloc_master(dev, sizeof(*spi_gpio));
if (!master)
@@ -377,17 +387,22 @@ static int spi_gpio_probe(struct platform_device *pdev)
if (status)
return status;
- if (of_id)
- status = spi_gpio_probe_dt(pdev, master);
- else
- status = spi_gpio_probe_pdata(pdev, master);
+ spi_gpio = spi_master_get_devdata(master);
- if (status)
- return status;
+ spi_gpio->cs_gpios = devm_kcalloc(dev,
+ pdata->num_chipselect,
+ sizeof(*spi_gpio->cs_gpios),
+ GFP_KERNEL);
+ if (!spi_gpio->cs_gpios)
+ return -ENOMEM;
- spi_gpio = spi_master_get_devdata(master);
+ platform_set_drvdata(pdev, spi_gpio);
+
+ /* Determine if we have chip selects connected */
+ spi_gpio->has_cs = !!pdata->num_chipselect;
- status = spi_gpio_request(dev, spi_gpio);
+ status = spi_gpio_request(dev, spi_gpio,
+ pdata->num_chipselect);
if (status)
return status;
@@ -405,9 +420,13 @@ static int spi_gpio_probe(struct platform_device *pdev)
}
master->bus_num = pdev->id;
+ /* The master needs to think there is a chipselect even if not connected */
+ master->num_chipselect = spi_gpio->has_cs ? pdata->num_chipselect : 1;
master->setup = spi_gpio_setup;
master->cleanup = spi_gpio_cleanup;
-
+#ifdef CONFIG_OF
+ master->dev.of_node = dev->of_node;
+#endif
bb = &spi_gpio->bitbang;
bb->master = master;
bb->chipselect = spi_gpio_chipselect;
--
2.20.1
^ permalink raw reply related
* Applied "spi: gpio: Fix handling of CS GPIO for DT systems" to the spi tree
From: Mark Brown @ 2019-07-02 13:04 UTC (permalink / raw)
To: Linus Walleij; +Cc: Andrey Smirnov, linux-gpio, linux-spi, Mark Brown
In-Reply-To: <20190701172517.31641-1-linus.walleij@linaro.org>
The patch
spi: gpio: Fix handling of CS GPIO for DT systems
has been applied to the spi tree at
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-5.2
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
From 83ce8ad482f64159155b605add18eb130b6a03fc Mon Sep 17 00:00:00 2001
From: Linus Walleij <linus.walleij@linaro.org>
Date: Mon, 1 Jul 2019 19:25:17 +0200
Subject: [PATCH] spi: gpio: Fix handling of CS GPIO for DT systems
This reverts commit 249e2632dcd0509b8f8f296f5aabf4d48dfd6da8.
After this commit drivers/net/dsa/vitesse-vsc73xx.c stopped
working. Apparently CS is not working because the reads
from the device is just returning just 1:s or just 0:s at
all bisection points, so it is a complete regression and
I think spi-gpio CS is essentially broken. [No other reports?
A bit concerning... --- broonie]
The revert had to be hand-crafted to preserve all the other
cleanup and changes to this driver, but now it works.
I'm sad to revert the change because it is a nice cleanup
but with the short time before v5.2 is released this is
probably the best idea, so we can figure out the right way
to do this in the next kernel cycle.
Fixes: 249e2632dcd0 ("spi: gpio: Don't request CS GPIO in DT use-case")
Cc: Andrey Smirnov <andrew.smirnov@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
drivers/spi/spi-gpio.c | 137 +++++++++++++++++++++++------------------
1 file changed, 78 insertions(+), 59 deletions(-)
diff --git a/drivers/spi/spi-gpio.c b/drivers/spi/spi-gpio.c
index 487ee55d26f7..45f3c196cc60 100644
--- a/drivers/spi/spi-gpio.c
+++ b/drivers/spi/spi-gpio.c
@@ -45,6 +45,7 @@ struct spi_gpio {
struct gpio_desc *miso;
struct gpio_desc *mosi;
struct gpio_desc **cs_gpios;
+ bool has_cs;
};
/*----------------------------------------------------------------------*/
@@ -214,7 +215,7 @@ static void spi_gpio_chipselect(struct spi_device *spi, int is_active)
gpiod_set_value_cansleep(spi_gpio->sck, spi->mode & SPI_CPOL);
/* Drive chip select line, if we have one */
- if (spi_gpio->cs_gpios) {
+ if (spi_gpio->has_cs) {
struct gpio_desc *cs = spi_gpio->cs_gpios[spi->chip_select];
/* SPI chip selects are normally active-low */
@@ -232,12 +233,10 @@ static int spi_gpio_setup(struct spi_device *spi)
* The CS GPIOs have already been
* initialized from the descriptor lookup.
*/
- if (spi_gpio->cs_gpios) {
- cs = spi_gpio->cs_gpios[spi->chip_select];
- if (!spi->controller_state && cs)
- status = gpiod_direction_output(cs,
- !(spi->mode & SPI_CS_HIGH));
- }
+ cs = spi_gpio->cs_gpios[spi->chip_select];
+ if (!spi->controller_state && cs)
+ status = gpiod_direction_output(cs,
+ !(spi->mode & SPI_CS_HIGH));
if (!status)
status = spi_bitbang_setup(spi);
@@ -288,8 +287,12 @@ static void spi_gpio_cleanup(struct spi_device *spi)
* floating signals. (A weak pulldown would save power too, but many
* drivers expect to see all-ones data as the no slave "response".)
*/
-static int spi_gpio_request(struct device *dev, struct spi_gpio *spi_gpio)
+static int spi_gpio_request(struct device *dev,
+ struct spi_gpio *spi_gpio,
+ unsigned int num_chipselects)
{
+ int i;
+
spi_gpio->mosi = devm_gpiod_get_optional(dev, "mosi", GPIOD_OUT_LOW);
if (IS_ERR(spi_gpio->mosi))
return PTR_ERR(spi_gpio->mosi);
@@ -302,6 +305,13 @@ static int spi_gpio_request(struct device *dev, struct spi_gpio *spi_gpio)
if (IS_ERR(spi_gpio->sck))
return PTR_ERR(spi_gpio->sck);
+ for (i = 0; i < num_chipselects; i++) {
+ spi_gpio->cs_gpios[i] = devm_gpiod_get_index(dev, "cs",
+ i, GPIOD_OUT_HIGH);
+ if (IS_ERR(spi_gpio->cs_gpios[i]))
+ return PTR_ERR(spi_gpio->cs_gpios[i]);
+ }
+
return 0;
}
@@ -312,55 +322,44 @@ static const struct of_device_id spi_gpio_dt_ids[] = {
};
MODULE_DEVICE_TABLE(of, spi_gpio_dt_ids);
-static int spi_gpio_probe_dt(struct platform_device *pdev,
- struct spi_master *master)
+static int spi_gpio_probe_dt(struct platform_device *pdev)
{
- master->dev.of_node = pdev->dev.of_node;
- master->use_gpio_descriptors = true;
-
- return 0;
-}
-#else
-static inline int spi_gpio_probe_dt(struct platform_device *pdev,
- struct spi_master *master)
-{
- return 0;
-}
-#endif
-
-static int spi_gpio_probe_pdata(struct platform_device *pdev,
- struct spi_master *master)
-{
- struct device *dev = &pdev->dev;
- struct spi_gpio_platform_data *pdata = dev_get_platdata(dev);
- struct spi_gpio *spi_gpio = spi_master_get_devdata(master);
- int i;
+ int ret;
+ u32 tmp;
+ struct spi_gpio_platform_data *pdata;
+ struct device_node *np = pdev->dev.of_node;
+ const struct of_device_id *of_id =
+ of_match_device(spi_gpio_dt_ids, &pdev->dev);
-#ifdef GENERIC_BITBANG
- if (!pdata || !pdata->num_chipselect)
- return -ENODEV;
-#endif
- /*
- * The master needs to think there is a chipselect even if not
- * connected
- */
- master->num_chipselect = pdata->num_chipselect ?: 1;
+ if (!of_id)
+ return 0;
- spi_gpio->cs_gpios = devm_kcalloc(dev, master->num_chipselect,
- sizeof(*spi_gpio->cs_gpios),
- GFP_KERNEL);
- if (!spi_gpio->cs_gpios)
+ pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata)
return -ENOMEM;
- for (i = 0; i < master->num_chipselect; i++) {
- spi_gpio->cs_gpios[i] = devm_gpiod_get_index(dev, "cs", i,
- GPIOD_OUT_HIGH);
- if (IS_ERR(spi_gpio->cs_gpios[i]))
- return PTR_ERR(spi_gpio->cs_gpios[i]);
+
+ ret = of_property_read_u32(np, "num-chipselects", &tmp);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "num-chipselects property not found\n");
+ goto error_free;
}
+ pdata->num_chipselect = tmp;
+ pdev->dev.platform_data = pdata;
+
+ return 1;
+
+error_free:
+ devm_kfree(&pdev->dev, pdata);
+ return ret;
+}
+#else
+static inline int spi_gpio_probe_dt(struct platform_device *pdev)
+{
return 0;
}
+#endif
static void spi_gpio_put(void *data)
{
@@ -372,11 +371,22 @@ static int spi_gpio_probe(struct platform_device *pdev)
int status;
struct spi_master *master;
struct spi_gpio *spi_gpio;
+ struct spi_gpio_platform_data *pdata;
struct device *dev = &pdev->dev;
struct spi_bitbang *bb;
- const struct of_device_id *of_id;
+ bool use_of = 0;
- of_id = of_match_device(spi_gpio_dt_ids, &pdev->dev);
+ status = spi_gpio_probe_dt(pdev);
+ if (status < 0)
+ return status;
+ if (status > 0)
+ use_of = 1;
+
+ pdata = dev_get_platdata(dev);
+#ifdef GENERIC_BITBANG
+ if (!pdata || (!use_of && !pdata->num_chipselect))
+ return -ENODEV;
+#endif
master = spi_alloc_master(dev, sizeof(*spi_gpio));
if (!master)
@@ -386,17 +396,22 @@ static int spi_gpio_probe(struct platform_device *pdev)
if (status)
return status;
- if (of_id)
- status = spi_gpio_probe_dt(pdev, master);
- else
- status = spi_gpio_probe_pdata(pdev, master);
+ spi_gpio = spi_master_get_devdata(master);
- if (status)
- return status;
+ spi_gpio->cs_gpios = devm_kcalloc(dev,
+ pdata->num_chipselect,
+ sizeof(*spi_gpio->cs_gpios),
+ GFP_KERNEL);
+ if (!spi_gpio->cs_gpios)
+ return -ENOMEM;
- spi_gpio = spi_master_get_devdata(master);
+ platform_set_drvdata(pdev, spi_gpio);
+
+ /* Determine if we have chip selects connected */
+ spi_gpio->has_cs = !!pdata->num_chipselect;
- status = spi_gpio_request(dev, spi_gpio);
+ status = spi_gpio_request(dev, spi_gpio,
+ pdata->num_chipselect);
if (status)
return status;
@@ -414,9 +429,13 @@ static int spi_gpio_probe(struct platform_device *pdev)
}
master->bus_num = pdev->id;
+ /* The master needs to think there is a chipselect even if not connected */
+ master->num_chipselect = spi_gpio->has_cs ? pdata->num_chipselect : 1;
master->setup = spi_gpio_setup;
master->cleanup = spi_gpio_cleanup;
-
+#ifdef CONFIG_OF
+ master->dev.of_node = dev->of_node;
+#endif
bb = &spi_gpio->bitbang;
bb->master = master;
bb->chipselect = spi_gpio_chipselect;
--
2.20.1
^ permalink raw reply related
* [gpio:devel-gpio-driver-isolation 65/66] include/asm-generic/gpio.h:60:9: error: implicit declaration of function 'gpiod_to_chip'; did you mean 'gpio_to_chip'?
From: kbuild test robot @ 2019-07-02 12:21 UTC (permalink / raw)
To: Linus Walleij; +Cc: kbuild-all, linux-gpio
[-- Attachment #1: Type: text/plain, Size: 23110 bytes --]
tree: https://kernel.googlesource.com/pub/scm/linux/kernel/git/linusw/linux-gpio.git devel-gpio-driver-isolation
head: 6c5bf689e0dca2a882193a202a96222dcba184e9
commit: f8a386f66ebfc32891f2af31b7474e31cdabd90d [65/66] gpio: Drop driver header from legacy header include
config: sparc64-allmodconfig (attached as .config)
compiler: sparc64-linux-gcc (GCC) 7.4.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
git checkout f8a386f66ebfc32891f2af31b7474e31cdabd90d
# save the attached .config to linux build tree
GCC_VERSION=7.4.0 make.cross ARCH=sparc64
If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>
All error/warnings (new ones prefixed by >>):
In file included from include/linux/gpio.h:62:0,
from drivers//usb/typec/tcpm/fusb302.c:12:
include/asm-generic/gpio.h: In function 'gpio_to_chip':
>> include/asm-generic/gpio.h:60:9: error: implicit declaration of function 'gpiod_to_chip'; did you mean 'gpio_to_chip'? [-Werror=implicit-function-declaration]
return gpiod_to_chip(gpio_to_desc(gpio));
^~~~~~~~~~~~~
gpio_to_chip
>> include/asm-generic/gpio.h:60:9: warning: return makes pointer from integer without a cast [-Wint-conversion]
return gpiod_to_chip(gpio_to_desc(gpio));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from drivers//usb/typec/tcpm/fusb302.c:19:0:
include/linux/of_gpio.h: At top level:
>> include/linux/of_gpio.h:41:19: error: field 'gc' has incomplete type
struct gpio_chip gc;
^~
In file included from include/linux/kernel.h:11:0,
from include/linux/list.h:9,
from include/linux/wait.h:7,
from include/linux/wait_bit.h:8,
from include/linux/fs.h:6,
from include/linux/debugfs.h:15,
from drivers//usb/typec/tcpm/fusb302.c:8:
include/linux/of_gpio.h: In function 'to_of_mm_gpio_chip':
>> include/linux/kernel.h:970:32: error: dereferencing pointer to incomplete type 'struct gpio_chip'
BUILD_BUG_ON_MSG(!__same_type(*(ptr), ((type *)0)->member) && \
^~~~~~
include/linux/compiler.h:325:9: note: in definition of macro '__compiletime_assert'
if (!(condition)) \
^~~~~~~~~
include/linux/compiler.h:345:2: note: in expansion of macro '_compiletime_assert'
_compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
^~~~~~~~~~~~~~~~~~~
include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert'
#define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
^~~~~~~~~~~~~~~~~~
include/linux/kernel.h:970:2: note: in expansion of macro 'BUILD_BUG_ON_MSG'
BUILD_BUG_ON_MSG(!__same_type(*(ptr), ((type *)0)->member) && \
^~~~~~~~~~~~~~~~
include/linux/kernel.h:970:20: note: in expansion of macro '__same_type'
BUILD_BUG_ON_MSG(!__same_type(*(ptr), ((type *)0)->member) && \
^~~~~~~~~~~
>> include/linux/of_gpio.h:48:9: note: in expansion of macro 'container_of'
return container_of(gc, struct of_mm_gpio_chip, gc);
^~~~~~~~~~~~
cc1: some warnings being treated as errors
--
In file included from include/linux/gpio.h:62:0,
from drivers//media/platform/sti/c8sectpfe/c8sectpfe-common.h:15,
from drivers//media/platform/sti/c8sectpfe/c8sectpfe-common.c:30:
include/asm-generic/gpio.h: In function 'gpio_to_chip':
>> include/asm-generic/gpio.h:60:9: error: implicit declaration of function 'gpiod_to_chip'; did you mean 'gpio_to_chip'? [-Werror=implicit-function-declaration]
return gpiod_to_chip(gpio_to_desc(gpio));
^~~~~~~~~~~~~
gpio_to_chip
>> include/asm-generic/gpio.h:60:9: warning: return makes pointer from integer without a cast [-Wint-conversion]
return gpiod_to_chip(gpio_to_desc(gpio));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cc1: some warnings being treated as errors
--
In file included from include/linux/gpio.h:62:0,
from include/linux/bcma/bcma_driver_chipcommon.h:6,
from include/linux/bcma/bcma.h:9,
from drivers//net/ethernet/broadcom/bgmac-bcma.c:11:
include/asm-generic/gpio.h: In function 'gpio_to_chip':
>> include/asm-generic/gpio.h:60:9: error: implicit declaration of function 'gpiod_to_chip'; did you mean 'gpio_to_chip'? [-Werror=implicit-function-declaration]
return gpiod_to_chip(gpio_to_desc(gpio));
^~~~~~~~~~~~~
gpio_to_chip
>> include/asm-generic/gpio.h:60:9: warning: return makes pointer from integer without a cast [-Wint-conversion]
return gpiod_to_chip(gpio_to_desc(gpio));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from include/linux/bcma/bcma.h:9:0,
from drivers//net/ethernet/broadcom/bgmac-bcma.c:11:
include/linux/bcma/bcma_driver_chipcommon.h: At top level:
>> include/linux/bcma/bcma_driver_chipcommon.h:647:19: error: field 'gpio' has incomplete type
struct gpio_chip gpio;
^~~~
In file included from include/linux/bcma/bcma.h:14:0,
from drivers//net/ethernet/broadcom/bgmac-bcma.c:11:
>> include/linux/ssb/ssb.h:496:19: error: field 'gpio' has incomplete type
struct gpio_chip gpio;
^~~~
cc1: some warnings being treated as errors
--
In file included from include/linux/gpio.h:62:0,
from include/linux/ssb/ssb.h:10,
from drivers//net/ethernet/broadcom/b44.c:31:
include/asm-generic/gpio.h: In function 'gpio_to_chip':
>> include/asm-generic/gpio.h:60:9: error: implicit declaration of function 'gpiod_to_chip'; did you mean 'gpio_to_chip'? [-Werror=implicit-function-declaration]
return gpiod_to_chip(gpio_to_desc(gpio));
^~~~~~~~~~~~~
gpio_to_chip
>> include/asm-generic/gpio.h:60:9: warning: return makes pointer from integer without a cast [-Wint-conversion]
return gpiod_to_chip(gpio_to_desc(gpio));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from drivers//net/ethernet/broadcom/b44.c:31:0:
include/linux/ssb/ssb.h: At top level:
>> include/linux/ssb/ssb.h:496:19: error: field 'gpio' has incomplete type
struct gpio_chip gpio;
^~~~
cc1: some warnings being treated as errors
--
In file included from include/linux/gpio.h:62:0,
from drivers/media/dvb-frontends/cxd2820r_priv.h:16,
from drivers/media/dvb-frontends/cxd2820r_c.c:9:
include/asm-generic/gpio.h: In function 'gpio_to_chip':
>> include/asm-generic/gpio.h:60:9: error: implicit declaration of function 'gpiod_to_chip'; did you mean 'gpio_to_chip'? [-Werror=implicit-function-declaration]
return gpiod_to_chip(gpio_to_desc(gpio));
^~~~~~~~~~~~~
gpio_to_chip
>> include/asm-generic/gpio.h:60:9: warning: return makes pointer from integer without a cast [-Wint-conversion]
return gpiod_to_chip(gpio_to_desc(gpio));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from drivers/media/dvb-frontends/cxd2820r_c.c:9:0:
drivers/media/dvb-frontends/cxd2820r_priv.h: At top level:
>> drivers/media/dvb-frontends/cxd2820r_priv.h:46:19: error: field 'gpio_chip' has incomplete type
struct gpio_chip gpio_chip;
^~~~~~~~~
cc1: some warnings being treated as errors
--
In file included from include/linux/gpio.h:62:0,
from drivers/media/dvb-frontends/cxd2820r_priv.h:16,
from drivers/media/dvb-frontends/cxd2820r_core.c:9:
include/asm-generic/gpio.h: In function 'gpio_to_chip':
>> include/asm-generic/gpio.h:60:9: error: implicit declaration of function 'gpiod_to_chip'; did you mean 'gpio_to_chip'? [-Werror=implicit-function-declaration]
return gpiod_to_chip(gpio_to_desc(gpio));
^~~~~~~~~~~~~
gpio_to_chip
>> include/asm-generic/gpio.h:60:9: warning: return makes pointer from integer without a cast [-Wint-conversion]
return gpiod_to_chip(gpio_to_desc(gpio));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from drivers/media/dvb-frontends/cxd2820r_core.c:9:0:
drivers/media/dvb-frontends/cxd2820r_priv.h: At top level:
>> drivers/media/dvb-frontends/cxd2820r_priv.h:46:19: error: field 'gpio_chip' has incomplete type
struct gpio_chip gpio_chip;
^~~~~~~~~
drivers/media/dvb-frontends/cxd2820r_core.c: In function 'cxd2820r_gpio_direction_output':
>> drivers/media/dvb-frontends/cxd2820r_core.c:424:31: error: implicit declaration of function 'gpiochip_get_data'; did you mean 'gpio_get_value'? [-Werror=implicit-function-declaration]
struct cxd2820r_priv *priv = gpiochip_get_data(chip);
^~~~~~~~~~~~~~~~~
gpio_get_value
>> drivers/media/dvb-frontends/cxd2820r_core.c:424:31: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
drivers/media/dvb-frontends/cxd2820r_core.c: In function 'cxd2820r_gpio_set':
drivers/media/dvb-frontends/cxd2820r_core.c:438:31: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
struct cxd2820r_priv *priv = gpiochip_get_data(chip);
^~~~~~~~~~~~~~~~~
drivers/media/dvb-frontends/cxd2820r_core.c: In function 'cxd2820r_gpio_get':
drivers/media/dvb-frontends/cxd2820r_core.c:454:31: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
struct cxd2820r_priv *priv = gpiochip_get_data(chip);
^~~~~~~~~~~~~~~~~
drivers/media/dvb-frontends/cxd2820r_core.c: In function 'cxd2820r_probe':
>> drivers/media/dvb-frontends/cxd2820r_core.c:661:9: error: implicit declaration of function 'gpiochip_add_data'; did you mean 'proc_create_data'? [-Werror=implicit-function-declaration]
ret = gpiochip_add_data(&priv->gpio_chip, priv);
^~~~~~~~~~~~~~~~~
proc_create_data
drivers/media/dvb-frontends/cxd2820r_core.c: In function 'cxd2820r_remove':
>> drivers/media/dvb-frontends/cxd2820r_core.c:717:3: error: implicit declaration of function 'gpiochip_remove'; did you mean 'proc_remove'? [-Werror=implicit-function-declaration]
gpiochip_remove(&priv->gpio_chip);
^~~~~~~~~~~~~~~
proc_remove
cc1: some warnings being treated as errors
--
In file included from include/linux/gpio.h:62:0,
from drivers//media/dvb-frontends/cxd2820r_priv.h:16,
from drivers//media/dvb-frontends/cxd2820r_t.c:9:
include/asm-generic/gpio.h: In function 'gpio_to_chip':
>> include/asm-generic/gpio.h:60:9: error: implicit declaration of function 'gpiod_to_chip'; did you mean 'gpio_to_chip'? [-Werror=implicit-function-declaration]
return gpiod_to_chip(gpio_to_desc(gpio));
^~~~~~~~~~~~~
gpio_to_chip
>> include/asm-generic/gpio.h:60:9: warning: return makes pointer from integer without a cast [-Wint-conversion]
return gpiod_to_chip(gpio_to_desc(gpio));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from drivers//media/dvb-frontends/cxd2820r_t.c:9:0:
drivers//media/dvb-frontends/cxd2820r_priv.h: At top level:
drivers//media/dvb-frontends/cxd2820r_priv.h:46:19: error: field 'gpio_chip' has incomplete type
struct gpio_chip gpio_chip;
^~~~~~~~~
cc1: some warnings being treated as errors
--
In file included from include/linux/gpio.h:62:0,
from drivers//media/dvb-frontends/cxd2820r_priv.h:16,
from drivers//media/dvb-frontends/cxd2820r_core.c:9:
include/asm-generic/gpio.h: In function 'gpio_to_chip':
>> include/asm-generic/gpio.h:60:9: error: implicit declaration of function 'gpiod_to_chip'; did you mean 'gpio_to_chip'? [-Werror=implicit-function-declaration]
return gpiod_to_chip(gpio_to_desc(gpio));
^~~~~~~~~~~~~
gpio_to_chip
>> include/asm-generic/gpio.h:60:9: warning: return makes pointer from integer without a cast [-Wint-conversion]
return gpiod_to_chip(gpio_to_desc(gpio));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from drivers//media/dvb-frontends/cxd2820r_core.c:9:0:
drivers//media/dvb-frontends/cxd2820r_priv.h: At top level:
drivers//media/dvb-frontends/cxd2820r_priv.h:46:19: error: field 'gpio_chip' has incomplete type
struct gpio_chip gpio_chip;
^~~~~~~~~
drivers//media/dvb-frontends/cxd2820r_core.c: In function 'cxd2820r_gpio_direction_output':
drivers//media/dvb-frontends/cxd2820r_core.c:424:31: error: implicit declaration of function 'gpiochip_get_data'; did you mean 'gpio_get_value'? [-Werror=implicit-function-declaration]
struct cxd2820r_priv *priv = gpiochip_get_data(chip);
^~~~~~~~~~~~~~~~~
gpio_get_value
drivers//media/dvb-frontends/cxd2820r_core.c:424:31: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
drivers//media/dvb-frontends/cxd2820r_core.c: In function 'cxd2820r_gpio_set':
drivers//media/dvb-frontends/cxd2820r_core.c:438:31: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
struct cxd2820r_priv *priv = gpiochip_get_data(chip);
^~~~~~~~~~~~~~~~~
drivers//media/dvb-frontends/cxd2820r_core.c: In function 'cxd2820r_gpio_get':
drivers//media/dvb-frontends/cxd2820r_core.c:454:31: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
struct cxd2820r_priv *priv = gpiochip_get_data(chip);
^~~~~~~~~~~~~~~~~
drivers//media/dvb-frontends/cxd2820r_core.c: In function 'cxd2820r_probe':
drivers//media/dvb-frontends/cxd2820r_core.c:661:9: error: implicit declaration of function 'gpiochip_add_data'; did you mean 'proc_create_data'? [-Werror=implicit-function-declaration]
ret = gpiochip_add_data(&priv->gpio_chip, priv);
^~~~~~~~~~~~~~~~~
proc_create_data
drivers//media/dvb-frontends/cxd2820r_core.c: In function 'cxd2820r_remove':
drivers//media/dvb-frontends/cxd2820r_core.c:717:3: error: implicit declaration of function 'gpiochip_remove'; did you mean 'proc_remove'? [-Werror=implicit-function-declaration]
gpiochip_remove(&priv->gpio_chip);
^~~~~~~~~~~~~~~
proc_remove
cc1: some warnings being treated as errors
--
In file included from include/linux/gpio.h:62:0,
from drivers/leds/leds-pca9532.c:23:
include/asm-generic/gpio.h: In function 'gpio_to_chip':
>> include/asm-generic/gpio.h:60:9: error: implicit declaration of function 'gpiod_to_chip'; did you mean 'gpio_to_chip'? [-Werror=implicit-function-declaration]
return gpiod_to_chip(gpio_to_desc(gpio));
^~~~~~~~~~~~~
gpio_to_chip
>> include/asm-generic/gpio.h:60:9: warning: return makes pointer from integer without a cast [-Wint-conversion]
return gpiod_to_chip(gpio_to_desc(gpio));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/leds/leds-pca9532.c: At top level:
>> drivers/leds/leds-pca9532.c:48:19: error: field 'gpio' has incomplete type
struct gpio_chip gpio;
^~~~
drivers/leds/leds-pca9532.c: In function 'pca9532_gpio_request_pin':
>> drivers/leds/leds-pca9532.c:275:30: error: implicit declaration of function 'gpiochip_get_data'; did you mean 'gpio_get_value'? [-Werror=implicit-function-declaration]
struct pca9532_data *data = gpiochip_get_data(gc);
^~~~~~~~~~~~~~~~~
gpio_get_value
>> drivers/leds/leds-pca9532.c:275:30: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
drivers/leds/leds-pca9532.c: In function 'pca9532_gpio_set_value':
drivers/leds/leds-pca9532.c:286:30: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
struct pca9532_data *data = gpiochip_get_data(gc);
^~~~~~~~~~~~~~~~~
drivers/leds/leds-pca9532.c: In function 'pca9532_gpio_get_value':
drivers/leds/leds-pca9532.c:299:30: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
struct pca9532_data *data = gpiochip_get_data(gc);
^~~~~~~~~~~~~~~~~
drivers/leds/leds-pca9532.c: In function 'pca9532_destroy_devices':
>> drivers/leds/leds-pca9532.c:349:3: error: implicit declaration of function 'gpiochip_remove'; did you mean 'proc_remove'? [-Werror=implicit-function-declaration]
gpiochip_remove(&data->gpio);
^~~~~~~~~~~~~~~
proc_remove
drivers/leds/leds-pca9532.c: In function 'pca9532_configure':
>> drivers/leds/leds-pca9532.c:449:9: error: implicit declaration of function 'gpiochip_add_data'; did you mean 'proc_create_data'? [-Werror=implicit-function-declaration]
err = gpiochip_add_data(&data->gpio, data);
^~~~~~~~~~~~~~~~~
proc_create_data
cc1: some warnings being treated as errors
--
In file included from include/linux/gpio.h:62:0,
from drivers/leds/leds-tca6507.c:96:
include/asm-generic/gpio.h: In function 'gpio_to_chip':
>> include/asm-generic/gpio.h:60:9: error: implicit declaration of function 'gpiod_to_chip'; did you mean 'gpio_to_chip'? [-Werror=implicit-function-declaration]
return gpiod_to_chip(gpio_to_desc(gpio));
^~~~~~~~~~~~~
gpio_to_chip
>> include/asm-generic/gpio.h:60:9: warning: return makes pointer from integer without a cast [-Wint-conversion]
return gpiod_to_chip(gpio_to_desc(gpio));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/leds/leds-tca6507.c: At top level:
>> drivers/leds/leds-tca6507.c:191:20: error: field 'gpio' has incomplete type
struct gpio_chip gpio;
^~~~
drivers/leds/leds-tca6507.c: In function 'tca6507_gpio_set_value':
>> drivers/leds/leds-tca6507.c:609:29: error: implicit declaration of function 'gpiochip_get_data'; did you mean 'gpio_get_value'? [-Werror=implicit-function-declaration]
struct tca6507_chip *tca = gpiochip_get_data(gc);
^~~~~~~~~~~~~~~~~
gpio_get_value
>> drivers/leds/leds-tca6507.c:609:29: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
drivers/leds/leds-tca6507.c: In function 'tca6507_probe_gpios':
>> drivers/leds/leds-tca6507.c:661:8: error: implicit declaration of function 'gpiochip_add_data'; did you mean 'proc_create_data'? [-Werror=implicit-function-declaration]
err = gpiochip_add_data(&tca->gpio, tca);
^~~~~~~~~~~~~~~~~
proc_create_data
drivers/leds/leds-tca6507.c: In function 'tca6507_remove_gpio':
>> drivers/leds/leds-tca6507.c:674:3: error: implicit declaration of function 'gpiochip_remove'; did you mean 'proc_remove'? [-Werror=implicit-function-declaration]
gpiochip_remove(&tca->gpio);
^~~~~~~~~~~~~~~
proc_remove
cc1: some warnings being treated as errors
--
In file included from include/linux/gpio.h:62:0,
from drivers/leds/leds-pca955x.c:46:
include/asm-generic/gpio.h: In function 'gpio_to_chip':
>> include/asm-generic/gpio.h:60:9: error: implicit declaration of function 'gpiod_to_chip'; did you mean 'gpio_to_chip'? [-Werror=implicit-function-declaration]
return gpiod_to_chip(gpio_to_desc(gpio));
^~~~~~~~~~~~~
gpio_to_chip
>> include/asm-generic/gpio.h:60:9: warning: return makes pointer from integer without a cast [-Wint-conversion]
return gpiod_to_chip(gpio_to_desc(gpio));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/leds/leds-pca955x.c: At top level:
>> drivers/leds/leds-pca955x.c:118:19: error: field 'gpio' has incomplete type
struct gpio_chip gpio;
^~~~
drivers/leds/leds-pca955x.c: In function 'pca955x_gpio_request_pin':
>> drivers/leds/leds-pca955x.c:310:28: error: implicit declaration of function 'gpiochip_get_data'; did you mean 'gpio_get_value'? [-Werror=implicit-function-declaration]
struct pca955x *pca955x = gpiochip_get_data(gc);
^~~~~~~~~~~~~~~~~
gpio_get_value
>> drivers/leds/leds-pca955x.c:310:28: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
drivers/leds/leds-pca955x.c: In function 'pca955x_set_value':
drivers/leds/leds-pca955x.c:322:28: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
struct pca955x *pca955x = gpiochip_get_data(gc);
^~~~~~~~~~~~~~~~~
drivers/leds/leds-pca955x.c: In function 'pca955x_gpio_get_value':
drivers/leds/leds-pca955x.c:339:28: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
struct pca955x *pca955x = gpiochip_get_data(gc);
^~~~~~~~~~~~~~~~~
drivers/leds/leds-pca955x.c: In function 'pca955x_gpio_direction_input':
drivers/leds/leds-pca955x.c:352:28: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
struct pca955x *pca955x = gpiochip_get_data(gc);
^~~~~~~~~~~~~~~~~
drivers/leds/leds-pca955x.c: In function 'pca955x_probe':
>> drivers/leds/leds-pca955x.c:557:9: error: implicit declaration of function 'devm_gpiochip_add_data'; did you mean 'devm_gpiod_put'? [-Werror=implicit-function-declaration]
err = devm_gpiochip_add_data(&client->dev, &pca955x->gpio,
^~~~~~~~~~~~~~~~~~~~~~
devm_gpiod_put
cc1: some warnings being treated as errors
..
vim +60 include/asm-generic/gpio.h
d2876d08 David Brownell 2008-02-04 56
79a9becd Alexandre Courbot 2013-10-17 57 /* caller holds gpio_lock *OR* gpio is marked as requested */
79a9becd Alexandre Courbot 2013-10-17 58 static inline struct gpio_chip *gpio_to_chip(unsigned gpio)
79a9becd Alexandre Courbot 2013-10-17 59 {
79a9becd Alexandre Courbot 2013-10-17 @60 return gpiod_to_chip(gpio_to_desc(gpio));
79a9becd Alexandre Courbot 2013-10-17 61 }
d2876d08 David Brownell 2008-02-04 62
:::::: The code at line 60 was first introduced by commit
:::::: 79a9becda8940deb2274b5aa4577c86d52ee7ecb gpiolib: export descriptor-based GPIO interface
:::::: TO: Alexandre Courbot <acourbot@nvidia.com>
:::::: CC: Linus Walleij <linus.walleij@linaro.org>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 58292 bytes --]
^ permalink raw reply
* [gpio:devel-gpio-driver-isolation 65/66] drivers/leds/leds-pca9532.c:349:3: error: implicit declaration of function 'gpiochip_remove'; did you mean 'pca9532_remove'?
From: kbuild test robot @ 2019-07-02 12:03 UTC (permalink / raw)
To: Linus Walleij; +Cc: kbuild-all, linux-gpio
[-- Attachment #1: Type: text/plain, Size: 36485 bytes --]
tree: https://kernel.googlesource.com/pub/scm/linux/kernel/git/linusw/linux-gpio.git devel-gpio-driver-isolation
head: 6c5bf689e0dca2a882193a202a96222dcba184e9
commit: f8a386f66ebfc32891f2af31b7474e31cdabd90d [65/66] gpio: Drop driver header from legacy header include
config: i386-allmodconfig (attached as .config)
compiler: gcc-7 (Debian 7.4.0-9) 7.4.0
reproduce:
git checkout f8a386f66ebfc32891f2af31b7474e31cdabd90d
# save the attached .config to linux build tree
make ARCH=i386
If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>
All error/warnings (new ones prefixed by >>):
In file included from include/linux/gpio.h:62:0,
from drivers/leds/leds-pca9532.c:23:
include/asm-generic/gpio.h: In function 'gpio_to_chip':
include/asm-generic/gpio.h:60:9: error: implicit declaration of function 'gpiod_to_chip'; did you mean 'gpio_to_chip'? [-Werror=implicit-function-declaration]
return gpiod_to_chip(gpio_to_desc(gpio));
^~~~~~~~~~~~~
gpio_to_chip
include/asm-generic/gpio.h:60:9: warning: return makes pointer from integer without a cast [-Wint-conversion]
return gpiod_to_chip(gpio_to_desc(gpio));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/leds/leds-pca9532.c: At top level:
drivers/leds/leds-pca9532.c:48:19: error: field 'gpio' has incomplete type
struct gpio_chip gpio;
^~~~
drivers/leds/leds-pca9532.c: In function 'pca9532_gpio_request_pin':
drivers/leds/leds-pca9532.c:275:30: error: implicit declaration of function 'gpiochip_get_data'; did you mean 'gpio_get_value'? [-Werror=implicit-function-declaration]
struct pca9532_data *data = gpiochip_get_data(gc);
^~~~~~~~~~~~~~~~~
gpio_get_value
drivers/leds/leds-pca9532.c:275:30: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
drivers/leds/leds-pca9532.c: In function 'pca9532_gpio_set_value':
drivers/leds/leds-pca9532.c:286:30: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
struct pca9532_data *data = gpiochip_get_data(gc);
^~~~~~~~~~~~~~~~~
drivers/leds/leds-pca9532.c: In function 'pca9532_gpio_get_value':
drivers/leds/leds-pca9532.c:299:30: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
struct pca9532_data *data = gpiochip_get_data(gc);
^~~~~~~~~~~~~~~~~
drivers/leds/leds-pca9532.c: In function 'pca9532_destroy_devices':
>> drivers/leds/leds-pca9532.c:349:3: error: implicit declaration of function 'gpiochip_remove'; did you mean 'pca9532_remove'? [-Werror=implicit-function-declaration]
gpiochip_remove(&data->gpio);
^~~~~~~~~~~~~~~
pca9532_remove
drivers/leds/leds-pca9532.c: In function 'pca9532_configure':
>> drivers/leds/leds-pca9532.c:449:9: error: implicit declaration of function 'gpiochip_add_data' [-Werror=implicit-function-declaration]
err = gpiochip_add_data(&data->gpio, data);
^~~~~~~~~~~~~~~~~
cc1: some warnings being treated as errors
--
In file included from include/linux/gpio.h:62:0,
from drivers/leds/leds-tca6507.c:96:
include/asm-generic/gpio.h: In function 'gpio_to_chip':
include/asm-generic/gpio.h:60:9: error: implicit declaration of function 'gpiod_to_chip'; did you mean 'gpio_to_chip'? [-Werror=implicit-function-declaration]
return gpiod_to_chip(gpio_to_desc(gpio));
^~~~~~~~~~~~~
gpio_to_chip
include/asm-generic/gpio.h:60:9: warning: return makes pointer from integer without a cast [-Wint-conversion]
return gpiod_to_chip(gpio_to_desc(gpio));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/leds/leds-tca6507.c: At top level:
drivers/leds/leds-tca6507.c:191:20: error: field 'gpio' has incomplete type
struct gpio_chip gpio;
^~~~
drivers/leds/leds-tca6507.c: In function 'tca6507_gpio_set_value':
drivers/leds/leds-tca6507.c:609:29: error: implicit declaration of function 'gpiochip_get_data'; did you mean 'gpio_get_value'? [-Werror=implicit-function-declaration]
struct tca6507_chip *tca = gpiochip_get_data(gc);
^~~~~~~~~~~~~~~~~
gpio_get_value
drivers/leds/leds-tca6507.c:609:29: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
drivers/leds/leds-tca6507.c: In function 'tca6507_probe_gpios':
>> drivers/leds/leds-tca6507.c:661:8: error: implicit declaration of function 'gpiochip_add_data' [-Werror=implicit-function-declaration]
err = gpiochip_add_data(&tca->gpio, tca);
^~~~~~~~~~~~~~~~~
drivers/leds/leds-tca6507.c: In function 'tca6507_remove_gpio':
>> drivers/leds/leds-tca6507.c:674:3: error: implicit declaration of function 'gpiochip_remove'; did you mean 'klist_remove'? [-Werror=implicit-function-declaration]
gpiochip_remove(&tca->gpio);
^~~~~~~~~~~~~~~
klist_remove
cc1: some warnings being treated as errors
--
In file included from include/linux/gpio.h:62:0,
from drivers/pinctrl/sh-pfc/gpio.c:10:
include/asm-generic/gpio.h: In function 'gpio_to_chip':
include/asm-generic/gpio.h:60:9: error: implicit declaration of function 'gpiod_to_chip'; did you mean 'gpio_to_chip'? [-Werror=implicit-function-declaration]
return gpiod_to_chip(gpio_to_desc(gpio));
^~~~~~~~~~~~~
gpio_to_chip
include/asm-generic/gpio.h:60:9: warning: return makes pointer from integer without a cast [-Wint-conversion]
return gpiod_to_chip(gpio_to_desc(gpio));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/pinctrl/sh-pfc/gpio.c: At top level:
drivers/pinctrl/sh-pfc/gpio.c:31:20: error: field 'gpio_chip' has incomplete type
struct gpio_chip gpio_chip;
^~~~~~~~~
drivers/pinctrl/sh-pfc/gpio.c: In function 'gpio_to_pfc':
drivers/pinctrl/sh-pfc/gpio.c:40:29: error: implicit declaration of function 'gpiochip_get_data'; did you mean 'gpio_get_value'? [-Werror=implicit-function-declaration]
struct sh_pfc_chip *chip = gpiochip_get_data(gc);
^~~~~~~~~~~~~~~~~
gpio_get_value
drivers/pinctrl/sh-pfc/gpio.c:40:29: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
drivers/pinctrl/sh-pfc/gpio.c: In function 'gpio_pin_direction_output':
drivers/pinctrl/sh-pfc/gpio.c:174:21: warning: passing argument 1 of 'gpio_pin_set_value' makes pointer from integer without a cast [-Wint-conversion]
gpio_pin_set_value(gpiochip_get_data(gc), offset, value);
^~~~~~~~~~~~~~~~~
drivers/pinctrl/sh-pfc/gpio.c:147:13: note: expected 'struct sh_pfc_chip *' but argument is of type 'int'
static void gpio_pin_set_value(struct sh_pfc_chip *chip, unsigned offset,
^~~~~~~~~~~~~~~~~~
drivers/pinctrl/sh-pfc/gpio.c: In function 'gpio_pin_get':
drivers/pinctrl/sh-pfc/gpio.c:181:29: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
struct sh_pfc_chip *chip = gpiochip_get_data(gc);
^~~~~~~~~~~~~~~~~
drivers/pinctrl/sh-pfc/gpio.c: In function 'gpio_pin_set':
drivers/pinctrl/sh-pfc/gpio.c:195:21: warning: passing argument 1 of 'gpio_pin_set_value' makes pointer from integer without a cast [-Wint-conversion]
gpio_pin_set_value(gpiochip_get_data(gc), offset, value);
^~~~~~~~~~~~~~~~~
drivers/pinctrl/sh-pfc/gpio.c:147:13: note: expected 'struct sh_pfc_chip *' but argument is of type 'int'
static void gpio_pin_set_value(struct sh_pfc_chip *chip, unsigned offset,
^~~~~~~~~~~~~~~~~~
drivers/pinctrl/sh-pfc/gpio.c: In function 'gpio_pin_setup':
drivers/pinctrl/sh-pfc/gpio.c:234:4: error: dereferencing pointer to incomplete type 'struct gpio_chip'
gc->request = gpio_pin_request;
^~
drivers/pinctrl/sh-pfc/gpio.c: In function 'sh_pfc_add_gpiochip':
drivers/pinctrl/sh-pfc/gpio.c:319:8: error: implicit declaration of function 'devm_gpiochip_add_data'; did you mean 'devm_gpiod_put'? [-Werror=implicit-function-declaration]
ret = devm_gpiochip_add_data(pfc->dev, &chip->gpio_chip, chip);
^~~~~~~~~~~~~~~~~~~~~~
devm_gpiod_put
drivers/pinctrl/sh-pfc/gpio.c: In function 'sh_pfc_register_gpiochip':
>> drivers/pinctrl/sh-pfc/gpio.c:386:9: error: implicit declaration of function 'gpiochip_add_pin_range'; did you mean 'pci_iomap_range'? [-Werror=implicit-function-declaration]
ret = gpiochip_add_pin_range(&chip->gpio_chip,
^~~~~~~~~~~~~~~~~~~~~~
pci_iomap_range
cc1: some warnings being treated as errors
--
In file included from include/linux/gpio.h:62:0,
from drivers/media/dvb-frontends/cxd2820r_priv.h:16,
from drivers/media/dvb-frontends/cxd2820r_core.c:9:
include/asm-generic/gpio.h: In function 'gpio_to_chip':
include/asm-generic/gpio.h:60:9: error: implicit declaration of function 'gpiod_to_chip'; did you mean 'gpio_to_chip'? [-Werror=implicit-function-declaration]
return gpiod_to_chip(gpio_to_desc(gpio));
^~~~~~~~~~~~~
gpio_to_chip
include/asm-generic/gpio.h:60:9: warning: return makes pointer from integer without a cast [-Wint-conversion]
return gpiod_to_chip(gpio_to_desc(gpio));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from drivers/media/dvb-frontends/cxd2820r_core.c:9:0:
drivers/media/dvb-frontends/cxd2820r_priv.h: At top level:
drivers/media/dvb-frontends/cxd2820r_priv.h:46:19: error: field 'gpio_chip' has incomplete type
struct gpio_chip gpio_chip;
^~~~~~~~~
drivers/media/dvb-frontends/cxd2820r_core.c: In function 'cxd2820r_gpio_direction_output':
drivers/media/dvb-frontends/cxd2820r_core.c:424:31: error: implicit declaration of function 'gpiochip_get_data'; did you mean 'gpio_get_value'? [-Werror=implicit-function-declaration]
struct cxd2820r_priv *priv = gpiochip_get_data(chip);
^~~~~~~~~~~~~~~~~
gpio_get_value
drivers/media/dvb-frontends/cxd2820r_core.c:424:31: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
drivers/media/dvb-frontends/cxd2820r_core.c: In function 'cxd2820r_gpio_set':
drivers/media/dvb-frontends/cxd2820r_core.c:438:31: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
struct cxd2820r_priv *priv = gpiochip_get_data(chip);
^~~~~~~~~~~~~~~~~
drivers/media/dvb-frontends/cxd2820r_core.c: In function 'cxd2820r_gpio_get':
drivers/media/dvb-frontends/cxd2820r_core.c:454:31: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
struct cxd2820r_priv *priv = gpiochip_get_data(chip);
^~~~~~~~~~~~~~~~~
drivers/media/dvb-frontends/cxd2820r_core.c: In function 'cxd2820r_probe':
>> drivers/media/dvb-frontends/cxd2820r_core.c:661:9: error: implicit declaration of function 'gpiochip_add_data' [-Werror=implicit-function-declaration]
ret = gpiochip_add_data(&priv->gpio_chip, priv);
^~~~~~~~~~~~~~~~~
drivers/media/dvb-frontends/cxd2820r_core.c: In function 'cxd2820r_remove':
>> drivers/media/dvb-frontends/cxd2820r_core.c:717:3: error: implicit declaration of function 'gpiochip_remove'; did you mean 'klist_remove'? [-Werror=implicit-function-declaration]
gpiochip_remove(&priv->gpio_chip);
^~~~~~~~~~~~~~~
klist_remove
cc1: some warnings being treated as errors
--
In file included from include/linux/gpio.h:62:0,
from drivers/mfd/htc-i2cpld.c:23:
include/asm-generic/gpio.h: In function 'gpio_to_chip':
include/asm-generic/gpio.h:60:9: error: implicit declaration of function 'gpiod_to_chip'; did you mean 'gpio_to_chip'? [-Werror=implicit-function-declaration]
return gpiod_to_chip(gpio_to_desc(gpio));
^~~~~~~~~~~~~
gpio_to_chip
include/asm-generic/gpio.h:60:9: warning: return makes pointer from integer without a cast [-Wint-conversion]
return gpiod_to_chip(gpio_to_desc(gpio));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/mfd/htc-i2cpld.c: At top level:
>> drivers/mfd/htc-i2cpld.c:37:26: error: field 'chip_out' has incomplete type
struct gpio_chip chip_out;
^~~~~~~~
>> drivers/mfd/htc-i2cpld.c:41:26: error: field 'chip_in' has incomplete type
struct gpio_chip chip_in;
^~~~~~~
drivers/mfd/htc-i2cpld.c: In function 'htcpld_chip_set':
>> drivers/mfd/htc-i2cpld.c:216:34: error: implicit declaration of function 'gpiochip_get_data'; did you mean 'gpio_get_value'? [-Werror=implicit-function-declaration]
struct htcpld_chip *chip_data = gpiochip_get_data(chip);
^~~~~~~~~~~~~~~~~
gpio_get_value
>> drivers/mfd/htc-i2cpld.c:216:34: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
drivers/mfd/htc-i2cpld.c: In function 'htcpld_chip_get':
drivers/mfd/htc-i2cpld.c:245:34: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
struct htcpld_chip *chip_data = gpiochip_get_data(chip);
^~~~~~~~~~~~~~~~~
>> drivers/mfd/htc-i2cpld.c:248:19: error: dereferencing pointer to incomplete type 'struct gpio_chip'
if (!strncmp(chip->label, "htcpld-out", 10)) {
^~
drivers/mfd/htc-i2cpld.c: In function 'htcpld_chip_to_irq':
drivers/mfd/htc-i2cpld.c:277:34: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
struct htcpld_chip *chip_data = gpiochip_get_data(chip);
^~~~~~~~~~~~~~~~~
drivers/mfd/htc-i2cpld.c: In function 'htcpld_register_chip_gpio':
>> drivers/mfd/htc-i2cpld.c:435:8: error: implicit declaration of function 'gpiochip_add_data' [-Werror=implicit-function-declaration]
ret = gpiochip_add_data(&(chip->chip_out), chip);
^~~~~~~~~~~~~~~~~
>> drivers/mfd/htc-i2cpld.c:446:3: error: implicit declaration of function 'gpiochip_remove'; did you mean 'klist_remove'? [-Werror=implicit-function-declaration]
gpiochip_remove(&(chip->chip_out));
^~~~~~~~~~~~~~~
klist_remove
cc1: some warnings being treated as errors
--
In file included from include/linux/gpio.h:62:0,
from drivers/mfd/sm501.c:40:
include/asm-generic/gpio.h: In function 'gpio_to_chip':
include/asm-generic/gpio.h:60:9: error: implicit declaration of function 'gpiod_to_chip'; did you mean 'gpio_to_chip'? [-Werror=implicit-function-declaration]
return gpiod_to_chip(gpio_to_desc(gpio));
^~~~~~~~~~~~~
gpio_to_chip
include/asm-generic/gpio.h:60:9: warning: return makes pointer from integer without a cast [-Wint-conversion]
return gpiod_to_chip(gpio_to_desc(gpio));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/mfd/sm501.c: At top level:
drivers/mfd/sm501.c:43:19: error: field 'gpio' has incomplete type
struct gpio_chip gpio;
^~~~
drivers/mfd/sm501.c: In function 'sm501_gpio_get':
drivers/mfd/sm501.c:892:35: error: implicit declaration of function 'gpiochip_get_data'; did you mean 'gpio_get_value'? [-Werror=implicit-function-declaration]
struct sm501_gpio_chip *smgpio = gpiochip_get_data(chip);
^~~~~~~~~~~~~~~~~
gpio_get_value
drivers/mfd/sm501.c:892:35: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
drivers/mfd/sm501.c: In function 'sm501_gpio_set':
drivers/mfd/sm501.c:923:35: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
struct sm501_gpio_chip *smchip = gpiochip_get_data(chip);
^~~~~~~~~~~~~~~~~
drivers/mfd/sm501.c: In function 'sm501_gpio_input':
drivers/mfd/sm501.c:948:35: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
struct sm501_gpio_chip *smchip = gpiochip_get_data(chip);
^~~~~~~~~~~~~~~~~
drivers/mfd/sm501.c: In function 'sm501_gpio_output':
drivers/mfd/sm501.c:974:35: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
struct sm501_gpio_chip *smchip = gpiochip_get_data(chip);
^~~~~~~~~~~~~~~~~
drivers/mfd/sm501.c: At top level:
drivers/mfd/sm501.c:1006:21: error: variable 'gpio_chip_template' has initializer but incomplete type
static const struct gpio_chip gpio_chip_template = {
^~~~~~~~~
drivers/mfd/sm501.c:1007:3: error: 'const struct gpio_chip' has no member named 'ngpio'
.ngpio = 32,
^~~~~
drivers/mfd/sm501.c:1007:13: warning: excess elements in struct initializer
.ngpio = 32,
^~
drivers/mfd/sm501.c:1007:13: note: (near initialization for 'gpio_chip_template')
drivers/mfd/sm501.c:1008:3: error: 'const struct gpio_chip' has no member named 'direction_input'
.direction_input = sm501_gpio_input,
^~~~~~~~~~~~~~~
drivers/mfd/sm501.c:1008:21: warning: excess elements in struct initializer
.direction_input = sm501_gpio_input,
^~~~~~~~~~~~~~~~
drivers/mfd/sm501.c:1008:21: note: (near initialization for 'gpio_chip_template')
drivers/mfd/sm501.c:1009:3: error: 'const struct gpio_chip' has no member named 'direction_output'
.direction_output = sm501_gpio_output,
^~~~~~~~~~~~~~~~
drivers/mfd/sm501.c:1009:22: warning: excess elements in struct initializer
.direction_output = sm501_gpio_output,
^~~~~~~~~~~~~~~~~
drivers/mfd/sm501.c:1009:22: note: (near initialization for 'gpio_chip_template')
drivers/mfd/sm501.c:1010:3: error: 'const struct gpio_chip' has no member named 'set'
.set = sm501_gpio_set,
^~~
drivers/mfd/sm501.c:1010:11: warning: excess elements in struct initializer
.set = sm501_gpio_set,
^~~~~~~~~~~~~~
drivers/mfd/sm501.c:1010:11: note: (near initialization for 'gpio_chip_template')
drivers/mfd/sm501.c:1011:3: error: 'const struct gpio_chip' has no member named 'get'
.get = sm501_gpio_get,
^~~
drivers/mfd/sm501.c:1011:11: warning: excess elements in struct initializer
.get = sm501_gpio_get,
^~~~~~~~~~~~~~
drivers/mfd/sm501.c:1011:11: note: (near initialization for 'gpio_chip_template')
drivers/mfd/sm501.c: In function 'sm501_gpio_register_chip':
drivers/mfd/sm501.c:1029:8: error: dereferencing pointer to incomplete type 'struct gpio_chip'
gchip->label = "SM501-HIGH";
^~
drivers/mfd/sm501.c:1039:9: error: implicit declaration of function 'gpiochip_add_data'; did you mean 'tty_audit_add_data'? [-Werror=implicit-function-declaration]
return gpiochip_add_data(gchip, chip);
^~~~~~~~~~~~~~~~~
tty_audit_add_data
drivers/mfd/sm501.c: In function 'sm501_register_gpio':
>> drivers/mfd/sm501.c:1085:2: error: implicit declaration of function 'gpiochip_remove'; did you mean 'klist_remove'? [-Werror=implicit-function-declaration]
gpiochip_remove(&gpio->low.gpio);
^~~~~~~~~~~~~~~
klist_remove
drivers/mfd/sm501.c: At top level:
drivers/mfd/sm501.c:1006:31: error: storage size of 'gpio_chip_template' isn't known
static const struct gpio_chip gpio_chip_template = {
^~~~~~~~~~~~~~~~~~
cc1: some warnings being treated as errors
--
In file included from include/linux/gpio.h:62:0,
from drivers/input/keyboard/adp5588-keys.c:20:
include/asm-generic/gpio.h: In function 'gpio_to_chip':
include/asm-generic/gpio.h:60:9: error: implicit declaration of function 'gpiod_to_chip'; did you mean 'gpio_to_chip'? [-Werror=implicit-function-declaration]
return gpiod_to_chip(gpio_to_desc(gpio));
^~~~~~~~~~~~~
gpio_to_chip
include/asm-generic/gpio.h:60:9: warning: return makes pointer from integer without a cast [-Wint-conversion]
return gpiod_to_chip(gpio_to_desc(gpio));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/input/keyboard/adp5588-keys.c: At top level:
drivers/input/keyboard/adp5588-keys.c:51:19: error: field 'gc' has incomplete type
struct gpio_chip gc;
^~
drivers/input/keyboard/adp5588-keys.c: In function 'adp5588_gpio_get_value':
drivers/input/keyboard/adp5588-keys.c:76:30: error: implicit declaration of function 'gpiochip_get_data'; did you mean 'gpio_get_value'? [-Werror=implicit-function-declaration]
struct adp5588_kpad *kpad = gpiochip_get_data(chip);
^~~~~~~~~~~~~~~~~
gpio_get_value
drivers/input/keyboard/adp5588-keys.c:76:30: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
drivers/input/keyboard/adp5588-keys.c: In function 'adp5588_gpio_set_value':
drivers/input/keyboard/adp5588-keys.c:96:30: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
struct adp5588_kpad *kpad = gpiochip_get_data(chip);
^~~~~~~~~~~~~~~~~
drivers/input/keyboard/adp5588-keys.c: In function 'adp5588_gpio_direction_input':
drivers/input/keyboard/adp5588-keys.c:115:30: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
struct adp5588_kpad *kpad = gpiochip_get_data(chip);
^~~~~~~~~~~~~~~~~
drivers/input/keyboard/adp5588-keys.c: In function 'adp5588_gpio_direction_output':
drivers/input/keyboard/adp5588-keys.c:133:30: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
struct adp5588_kpad *kpad = gpiochip_get_data(chip);
^~~~~~~~~~~~~~~~~
drivers/input/keyboard/adp5588-keys.c: In function 'adp5588_gpio_add':
>> drivers/input/keyboard/adp5588-keys.c:213:10: error: implicit declaration of function 'gpiochip_add_data' [-Werror=implicit-function-declaration]
error = gpiochip_add_data(&kpad->gc, kpad);
^~~~~~~~~~~~~~~~~
drivers/input/keyboard/adp5588-keys.c: In function 'adp5588_gpio_remove':
>> drivers/input/keyboard/adp5588-keys.c:254:2: error: implicit declaration of function 'gpiochip_remove'; did you mean 'klist_remove'? [-Werror=implicit-function-declaration]
gpiochip_remove(&kpad->gc);
^~~~~~~~~~~~~~~
klist_remove
cc1: some warnings being treated as errors
..
vim +349 drivers/leds/leds-pca9532.c
3c1ab50d0 Joachim Eastwood 2011-05-24 283
3c1ab50d0 Joachim Eastwood 2011-05-24 284 static void pca9532_gpio_set_value(struct gpio_chip *gc, unsigned offset, int val)
3c1ab50d0 Joachim Eastwood 2011-05-24 285 {
dced14675 Linus Walleij 2015-12-08 @286 struct pca9532_data *data = gpiochip_get_data(gc);
3c1ab50d0 Joachim Eastwood 2011-05-24 287 struct pca9532_led *led = &data->leds[offset];
3c1ab50d0 Joachim Eastwood 2011-05-24 288
3c1ab50d0 Joachim Eastwood 2011-05-24 289 if (val)
3c1ab50d0 Joachim Eastwood 2011-05-24 290 led->state = PCA9532_ON;
3c1ab50d0 Joachim Eastwood 2011-05-24 291 else
3c1ab50d0 Joachim Eastwood 2011-05-24 292 led->state = PCA9532_OFF;
3c1ab50d0 Joachim Eastwood 2011-05-24 293
3c1ab50d0 Joachim Eastwood 2011-05-24 294 pca9532_setled(led);
3c1ab50d0 Joachim Eastwood 2011-05-24 295 }
3c1ab50d0 Joachim Eastwood 2011-05-24 296
3c1ab50d0 Joachim Eastwood 2011-05-24 297 static int pca9532_gpio_get_value(struct gpio_chip *gc, unsigned offset)
3c1ab50d0 Joachim Eastwood 2011-05-24 298 {
dced14675 Linus Walleij 2015-12-08 @299 struct pca9532_data *data = gpiochip_get_data(gc);
3c1ab50d0 Joachim Eastwood 2011-05-24 300 unsigned char reg;
3c1ab50d0 Joachim Eastwood 2011-05-24 301
3c1ab50d0 Joachim Eastwood 2011-05-24 302 reg = i2c_smbus_read_byte_data(data->client, PCA9532_REG_INPUT(offset));
3c1ab50d0 Joachim Eastwood 2011-05-24 303
3c1ab50d0 Joachim Eastwood 2011-05-24 304 return !!(reg & (1 << (offset % 8)));
3c1ab50d0 Joachim Eastwood 2011-05-24 305 }
3c1ab50d0 Joachim Eastwood 2011-05-24 306
3c1ab50d0 Joachim Eastwood 2011-05-24 307 static int pca9532_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
3c1ab50d0 Joachim Eastwood 2011-05-24 308 {
3c1ab50d0 Joachim Eastwood 2011-05-24 309 /* To use as input ensure pin is not driven */
3c1ab50d0 Joachim Eastwood 2011-05-24 310 pca9532_gpio_set_value(gc, offset, 0);
3c1ab50d0 Joachim Eastwood 2011-05-24 311
3c1ab50d0 Joachim Eastwood 2011-05-24 312 return 0;
3c1ab50d0 Joachim Eastwood 2011-05-24 313 }
3c1ab50d0 Joachim Eastwood 2011-05-24 314
3c1ab50d0 Joachim Eastwood 2011-05-24 315 static int pca9532_gpio_direction_output(struct gpio_chip *gc, unsigned offset, int val)
3c1ab50d0 Joachim Eastwood 2011-05-24 316 {
3c1ab50d0 Joachim Eastwood 2011-05-24 317 pca9532_gpio_set_value(gc, offset, val);
3c1ab50d0 Joachim Eastwood 2011-05-24 318
3c1ab50d0 Joachim Eastwood 2011-05-24 319 return 0;
3c1ab50d0 Joachim Eastwood 2011-05-24 320 }
3c1ab50d0 Joachim Eastwood 2011-05-24 321 #endif /* CONFIG_LEDS_PCA9532_GPIO */
3c1ab50d0 Joachim Eastwood 2011-05-24 322
3c1ab50d0 Joachim Eastwood 2011-05-24 323 static int pca9532_destroy_devices(struct pca9532_data *data, int n_devs)
125c71352 Axel Lin 2011-01-12 324 {
125c71352 Axel Lin 2011-01-12 325 int i = n_devs;
125c71352 Axel Lin 2011-01-12 326
125c71352 Axel Lin 2011-01-12 327 if (!data)
3c1ab50d0 Joachim Eastwood 2011-05-24 328 return -EINVAL;
125c71352 Axel Lin 2011-01-12 329
125c71352 Axel Lin 2011-01-12 330 while (--i >= 0) {
125c71352 Axel Lin 2011-01-12 331 switch (data->leds[i].type) {
125c71352 Axel Lin 2011-01-12 332 case PCA9532_TYPE_NONE:
3c1ab50d0 Joachim Eastwood 2011-05-24 333 case PCA9532_TYPE_GPIO:
125c71352 Axel Lin 2011-01-12 334 break;
125c71352 Axel Lin 2011-01-12 335 case PCA9532_TYPE_LED:
125c71352 Axel Lin 2011-01-12 336 led_classdev_unregister(&data->leds[i].ldev);
125c71352 Axel Lin 2011-01-12 337 break;
125c71352 Axel Lin 2011-01-12 338 case PCA9532_TYPE_N2100_BEEP:
125c71352 Axel Lin 2011-01-12 339 if (data->idev != NULL) {
125c71352 Axel Lin 2011-01-12 340 cancel_work_sync(&data->work);
125c71352 Axel Lin 2011-01-12 341 data->idev = NULL;
125c71352 Axel Lin 2011-01-12 342 }
125c71352 Axel Lin 2011-01-12 343 break;
125c71352 Axel Lin 2011-01-12 344 }
125c71352 Axel Lin 2011-01-12 345 }
3c1ab50d0 Joachim Eastwood 2011-05-24 346
3c1ab50d0 Joachim Eastwood 2011-05-24 347 #ifdef CONFIG_LEDS_PCA9532_GPIO
58383c784 Linus Walleij 2015-11-04 348 if (data->gpio.parent)
88d5e520a abdoulaye berthe 2014-07-12 @349 gpiochip_remove(&data->gpio);
3c1ab50d0 Joachim Eastwood 2011-05-24 350 #endif
3c1ab50d0 Joachim Eastwood 2011-05-24 351
3c1ab50d0 Joachim Eastwood 2011-05-24 352 return 0;
125c71352 Axel Lin 2011-01-12 353 }
125c71352 Axel Lin 2011-01-12 354
e14fa8243 Riku Voipio 2008-05-31 355 static int pca9532_configure(struct i2c_client *client,
e14fa8243 Riku Voipio 2008-05-31 356 struct pca9532_data *data, struct pca9532_platform_data *pdata)
e14fa8243 Riku Voipio 2008-05-31 357 {
e14fa8243 Riku Voipio 2008-05-31 358 int i, err = 0;
3c1ab50d0 Joachim Eastwood 2011-05-24 359 int gpios = 0;
3dbf622c1 Jan Weitzel 2011-05-24 360 u8 maxleds = data->chip_info->num_leds;
e14fa8243 Riku Voipio 2008-05-31 361
e14fa8243 Riku Voipio 2008-05-31 362 for (i = 0; i < 2; i++) {
e14fa8243 Riku Voipio 2008-05-31 363 data->pwm[i] = pdata->pwm[i];
e14fa8243 Riku Voipio 2008-05-31 364 data->psc[i] = pdata->psc[i];
3dbf622c1 Jan Weitzel 2011-05-24 365 i2c_smbus_write_byte_data(client, PCA9532_REG_PWM(maxleds, i),
e14fa8243 Riku Voipio 2008-05-31 366 data->pwm[i]);
3dbf622c1 Jan Weitzel 2011-05-24 367 i2c_smbus_write_byte_data(client, PCA9532_REG_PSC(maxleds, i),
e14fa8243 Riku Voipio 2008-05-31 368 data->psc[i]);
e14fa8243 Riku Voipio 2008-05-31 369 }
e14fa8243 Riku Voipio 2008-05-31 370
3dbf622c1 Jan Weitzel 2011-05-24 371 for (i = 0; i < data->chip_info->num_leds; i++) {
e14fa8243 Riku Voipio 2008-05-31 372 struct pca9532_led *led = &data->leds[i];
e14fa8243 Riku Voipio 2008-05-31 373 struct pca9532_led *pled = &pdata->leds[i];
e14fa8243 Riku Voipio 2008-05-31 374 led->client = client;
e14fa8243 Riku Voipio 2008-05-31 375 led->id = i;
e14fa8243 Riku Voipio 2008-05-31 376 led->type = pled->type;
e14fa8243 Riku Voipio 2008-05-31 377 switch (led->type) {
e14fa8243 Riku Voipio 2008-05-31 378 case PCA9532_TYPE_NONE:
e14fa8243 Riku Voipio 2008-05-31 379 break;
3c1ab50d0 Joachim Eastwood 2011-05-24 380 case PCA9532_TYPE_GPIO:
3c1ab50d0 Joachim Eastwood 2011-05-24 381 gpios++;
3c1ab50d0 Joachim Eastwood 2011-05-24 382 break;
e14fa8243 Riku Voipio 2008-05-31 383 case PCA9532_TYPE_LED:
28c5fe990 Felix Brack 2017-04-13 384 if (pled->state == PCA9532_KEEP)
28c5fe990 Felix Brack 2017-04-13 385 led->state = pca9532_getled(led);
28c5fe990 Felix Brack 2017-04-13 386 else
e14fa8243 Riku Voipio 2008-05-31 387 led->state = pled->state;
e14fa8243 Riku Voipio 2008-05-31 388 led->name = pled->name;
e14fa8243 Riku Voipio 2008-05-31 389 led->ldev.name = led->name;
90a5537bd Felix Brack 2016-10-26 390 led->ldev.default_trigger = pled->default_trigger;
e14fa8243 Riku Voipio 2008-05-31 391 led->ldev.brightness = LED_OFF;
00a88a19d Andrew Lunn 2015-08-20 392 led->ldev.brightness_set_blocking =
00a88a19d Andrew Lunn 2015-08-20 393 pca9532_set_brightness;
e14fa8243 Riku Voipio 2008-05-31 394 led->ldev.blink_set = pca9532_set_blink;
f785d022a Sven Wegener 2008-12-03 395 err = led_classdev_register(&client->dev, &led->ldev);
f785d022a Sven Wegener 2008-12-03 396 if (err < 0) {
e14fa8243 Riku Voipio 2008-05-31 397 dev_err(&client->dev,
e14fa8243 Riku Voipio 2008-05-31 398 "couldn't register LED %s\n",
e14fa8243 Riku Voipio 2008-05-31 399 led->name);
e14fa8243 Riku Voipio 2008-05-31 400 goto exit;
e14fa8243 Riku Voipio 2008-05-31 401 }
e14fa8243 Riku Voipio 2008-05-31 402 pca9532_setled(led);
e14fa8243 Riku Voipio 2008-05-31 403 break;
e14fa8243 Riku Voipio 2008-05-31 404 case PCA9532_TYPE_N2100_BEEP:
e14fa8243 Riku Voipio 2008-05-31 405 BUG_ON(data->idev);
e14fa8243 Riku Voipio 2008-05-31 406 led->state = PCA9532_PWM1;
e14fa8243 Riku Voipio 2008-05-31 407 pca9532_setled(led);
8614fb466 Axel Lin 2012-12-25 408 data->idev = devm_input_allocate_device(&client->dev);
e14fa8243 Riku Voipio 2008-05-31 409 if (data->idev == NULL) {
e14fa8243 Riku Voipio 2008-05-31 410 err = -ENOMEM;
e14fa8243 Riku Voipio 2008-05-31 411 goto exit;
e14fa8243 Riku Voipio 2008-05-31 412 }
e14fa8243 Riku Voipio 2008-05-31 413 data->idev->name = pled->name;
e14fa8243 Riku Voipio 2008-05-31 414 data->idev->phys = "i2c/pca9532";
e14fa8243 Riku Voipio 2008-05-31 415 data->idev->id.bustype = BUS_HOST;
e14fa8243 Riku Voipio 2008-05-31 416 data->idev->id.vendor = 0x001f;
e14fa8243 Riku Voipio 2008-05-31 417 data->idev->id.product = 0x0001;
e14fa8243 Riku Voipio 2008-05-31 418 data->idev->id.version = 0x0100;
e14fa8243 Riku Voipio 2008-05-31 419 data->idev->evbit[0] = BIT_MASK(EV_SND);
e14fa8243 Riku Voipio 2008-05-31 420 data->idev->sndbit[0] = BIT_MASK(SND_BELL) |
e14fa8243 Riku Voipio 2008-05-31 421 BIT_MASK(SND_TONE);
e14fa8243 Riku Voipio 2008-05-31 422 data->idev->event = pca9532_event;
e14fa8243 Riku Voipio 2008-05-31 423 input_set_drvdata(data->idev, data);
934cd3f97 Riku Voipio 2008-12-03 424 INIT_WORK(&data->work, pca9532_input_work);
e14fa8243 Riku Voipio 2008-05-31 425 err = input_register_device(data->idev);
e14fa8243 Riku Voipio 2008-05-31 426 if (err) {
934cd3f97 Riku Voipio 2008-12-03 427 cancel_work_sync(&data->work);
e14fa8243 Riku Voipio 2008-05-31 428 data->idev = NULL;
e14fa8243 Riku Voipio 2008-05-31 429 goto exit;
e14fa8243 Riku Voipio 2008-05-31 430 }
e14fa8243 Riku Voipio 2008-05-31 431 break;
e14fa8243 Riku Voipio 2008-05-31 432 }
e14fa8243 Riku Voipio 2008-05-31 433 }
3c1ab50d0 Joachim Eastwood 2011-05-24 434
3c1ab50d0 Joachim Eastwood 2011-05-24 435 #ifdef CONFIG_LEDS_PCA9532_GPIO
3c1ab50d0 Joachim Eastwood 2011-05-24 436 if (gpios) {
3c1ab50d0 Joachim Eastwood 2011-05-24 437 data->gpio.label = "gpio-pca9532";
3c1ab50d0 Joachim Eastwood 2011-05-24 438 data->gpio.direction_input = pca9532_gpio_direction_input;
3c1ab50d0 Joachim Eastwood 2011-05-24 439 data->gpio.direction_output = pca9532_gpio_direction_output;
3c1ab50d0 Joachim Eastwood 2011-05-24 440 data->gpio.set = pca9532_gpio_set_value;
3c1ab50d0 Joachim Eastwood 2011-05-24 441 data->gpio.get = pca9532_gpio_get_value;
3c1ab50d0 Joachim Eastwood 2011-05-24 442 data->gpio.request = pca9532_gpio_request_pin;
3c1ab50d0 Joachim Eastwood 2011-05-24 443 data->gpio.can_sleep = 1;
3c1ab50d0 Joachim Eastwood 2011-05-24 444 data->gpio.base = pdata->gpio_base;
3dbf622c1 Jan Weitzel 2011-05-24 445 data->gpio.ngpio = data->chip_info->num_leds;
58383c784 Linus Walleij 2015-11-04 446 data->gpio.parent = &client->dev;
3c1ab50d0 Joachim Eastwood 2011-05-24 447 data->gpio.owner = THIS_MODULE;
3c1ab50d0 Joachim Eastwood 2011-05-24 448
dced14675 Linus Walleij 2015-12-08 @449 err = gpiochip_add_data(&data->gpio, data);
3c1ab50d0 Joachim Eastwood 2011-05-24 450 if (err) {
3c1ab50d0 Joachim Eastwood 2011-05-24 451 /* Use data->gpio.dev as a flag for freeing gpiochip */
58383c784 Linus Walleij 2015-11-04 452 data->gpio.parent = NULL;
3c1ab50d0 Joachim Eastwood 2011-05-24 453 dev_warn(&client->dev, "could not add gpiochip\n");
3c1ab50d0 Joachim Eastwood 2011-05-24 454 } else {
3c1ab50d0 Joachim Eastwood 2011-05-24 455 dev_info(&client->dev, "gpios %i...%i\n",
3c1ab50d0 Joachim Eastwood 2011-05-24 456 data->gpio.base, data->gpio.base +
3c1ab50d0 Joachim Eastwood 2011-05-24 457 data->gpio.ngpio - 1);
3c1ab50d0 Joachim Eastwood 2011-05-24 458 }
3c1ab50d0 Joachim Eastwood 2011-05-24 459 }
3c1ab50d0 Joachim Eastwood 2011-05-24 460 #endif
3c1ab50d0 Joachim Eastwood 2011-05-24 461
e14fa8243 Riku Voipio 2008-05-31 462 return 0;
e14fa8243 Riku Voipio 2008-05-31 463
e14fa8243 Riku Voipio 2008-05-31 464 exit:
125c71352 Axel Lin 2011-01-12 465 pca9532_destroy_devices(data, i);
e14fa8243 Riku Voipio 2008-05-31 466 return err;
e14fa8243 Riku Voipio 2008-05-31 467 }
e14fa8243 Riku Voipio 2008-05-31 468
:::::: The code at line 349 was first introduced by commit
:::::: 88d5e520aa9701eb3e4f46165e02097cc03d363a driver:gpio remove all usage of gpio_remove retval in driver
:::::: TO: abdoulaye berthe <berthe.ab@gmail.com>
:::::: CC: Linus Walleij <linus.walleij@linaro.org>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 68832 bytes --]
^ permalink raw reply
* Re: [PATCH] Revert "spi: gpio: Don't request CS GPIO in DT use-case"
From: Mark Brown @ 2019-07-02 11:39 UTC (permalink / raw)
To: Linus Walleij; +Cc: linux-spi, linux-gpio, Andrey Smirnov
In-Reply-To: <20190701172517.31641-1-linus.walleij@linaro.org>
[-- Attachment #1: Type: text/plain, Size: 544 bytes --]
On Mon, Jul 01, 2019 at 07:25:17PM +0200, Linus Walleij wrote:
> This reverts commit 249e2632dcd0509b8f8f296f5aabf4d48dfd6da8.
>
> After this commit drivers/net/dsa/vitesse-vsc73xx.c stopped
> working. Apparently CS is not working because the reads
> from the device is just returning just 1:s or just 0:s at
> all bisection points, so it is a complete regression and
> I think spi-gpio CS is essentially broken.
Also I'm a bit concerned that nobody else noticed this - do we
have any understanding of what the actual problem is?
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* Re: [PATCH] Revert "spi: gpio: Don't request CS GPIO in DT use-case"
From: Mark Brown @ 2019-07-02 11:35 UTC (permalink / raw)
To: Linus Walleij; +Cc: linux-spi, linux-gpio, Andrey Smirnov
In-Reply-To: <20190701172517.31641-1-linus.walleij@linaro.org>
[-- Attachment #1: Type: text/plain, Size: 326 bytes --]
On Mon, Jul 01, 2019 at 07:25:17PM +0200, Linus Walleij wrote:
> This reverts commit 249e2632dcd0509b8f8f296f5aabf4d48dfd6da8.
>
> After this commit drivers/net/dsa/vitesse-vsc73xx.c stopped
Please use subject lines matching the style for the subsystem. This
makes it easier for people to identify relevant patches.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* [PATCH v2 3/3] pinctrl: qcom: Add SM8150 pinctrl driver
From: Vinod Koul @ 2019-07-02 10:50 UTC (permalink / raw)
To: Linus Walleij
Cc: linux-arm-msm, Bjorn Andersson, Prasad Sodagudi, Andy Gross,
Rob Herring, Mark Rutland, linux-gpio, devicetree, linux-kernel,
Isaac J . Manjarres, Vinod Koul
In-Reply-To: <20190702105045.27646-1-vkoul@kernel.org>
From: Prasad Sodagudi <psodagud@codeaurora.org>
Add initial pinctrl driver to support pin configuration with
pinctrl framework for SM8150
Signed-off-by: Prasad Sodagudi <psodagud@codeaurora.org>
Signed-off-by: Isaac J. Manjarres <isaacm@codeaurora.org>
[vkoul: modify to use upstream tile support
use upstream code style
order the functions and squash functions]
Signed-off-by: Vinod Koul <vkoul@kernel.org>
---
drivers/pinctrl/qcom/Kconfig | 9 +
drivers/pinctrl/qcom/Makefile | 1 +
drivers/pinctrl/qcom/pinctrl-sm8150.c | 1548 +++++++++++++++++++++++++
3 files changed, 1558 insertions(+)
create mode 100644 drivers/pinctrl/qcom/pinctrl-sm8150.c
diff --git a/drivers/pinctrl/qcom/Kconfig b/drivers/pinctrl/qcom/Kconfig
index 2e66ab72c10b..47be1622dcf6 100644
--- a/drivers/pinctrl/qcom/Kconfig
+++ b/drivers/pinctrl/qcom/Kconfig
@@ -175,4 +175,13 @@ config PINCTRL_SDM845
Qualcomm Technologies Inc TLMM block found on the Qualcomm
Technologies Inc SDM845 platform.
+config PINCTRL_SM8150
+ tristate "Qualcomm Technologies Inc SM8150 pin controller driver"
+ depends on GPIOLIB && OF
+ select PINCTRL_MSM
+ help
+ This is the pinctrl, pinmux, pinconf and gpiolib driver for the
+ Qualcomm Technologies Inc TLMM block found on the Qualcomm
+ Technologies Inc SM8150 platform.
+
endif
diff --git a/drivers/pinctrl/qcom/Makefile b/drivers/pinctrl/qcom/Makefile
index 344b4c6a6c6e..ebe906872272 100644
--- a/drivers/pinctrl/qcom/Makefile
+++ b/drivers/pinctrl/qcom/Makefile
@@ -22,3 +22,4 @@ obj-$(CONFIG_PINCTRL_QCOM_SSBI_PMIC) += pinctrl-ssbi-gpio.o
obj-$(CONFIG_PINCTRL_QCOM_SSBI_PMIC) += pinctrl-ssbi-mpp.o
obj-$(CONFIG_PINCTRL_SDM660) += pinctrl-sdm660.o
obj-$(CONFIG_PINCTRL_SDM845) += pinctrl-sdm845.o
+obj-$(CONFIG_PINCTRL_SM8150) += pinctrl-sm8150.o
diff --git a/drivers/pinctrl/qcom/pinctrl-sm8150.c b/drivers/pinctrl/qcom/pinctrl-sm8150.c
new file mode 100644
index 000000000000..7359bae68c69
--- /dev/null
+++ b/drivers/pinctrl/qcom/pinctrl-sm8150.c
@@ -0,0 +1,1548 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pinctrl/pinctrl.h>
+
+#include "pinctrl-msm.h"
+
+static const char * const sm8150_tiles[] = {
+ "north",
+ "south",
+ "east",
+ "west"
+};
+
+enum {
+ NORTH,
+ SOUTH,
+ EAST,
+ WEST
+};
+
+#define FUNCTION(fname) \
+ [msm_mux_##fname] = { \
+ .name = #fname, \
+ .groups = fname##_groups, \
+ .ngroups = ARRAY_SIZE(fname##_groups), \
+ }
+
+#define PINGROUP(id, _tile, f1, f2, f3, f4, f5, f6, f7, f8, f9) \
+ { \
+ .name = "gpio" #id, \
+ .pins = gpio##id##_pins, \
+ .npins = (unsigned int)ARRAY_SIZE(gpio##id##_pins), \
+ .funcs = (int[]){ \
+ msm_mux_gpio, /* gpio mode */ \
+ msm_mux_##f1, \
+ msm_mux_##f2, \
+ msm_mux_##f3, \
+ msm_mux_##f4, \
+ msm_mux_##f5, \
+ msm_mux_##f6, \
+ msm_mux_##f7, \
+ msm_mux_##f8, \
+ msm_mux_##f9 \
+ }, \
+ .nfuncs = 10, \
+ .ctl_reg = 0x1000 * id, \
+ .io_reg = 0x1000 * id + 0x4, \
+ .intr_cfg_reg = 0x1000 * id + 0x8, \
+ .intr_status_reg = 0x1000 * id + 0xc, \
+ .intr_target_reg = 0x1000 * id + 0x8, \
+ .tile = _tile, \
+ .mux_bit = 2, \
+ .pull_bit = 0, \
+ .drv_bit = 6, \
+ .oe_bit = 9, \
+ .in_bit = 0, \
+ .out_bit = 1, \
+ .intr_enable_bit = 0, \
+ .intr_status_bit = 0, \
+ .intr_target_bit = 5, \
+ .intr_target_kpss_val = 3, \
+ .intr_raw_status_bit = 4, \
+ .intr_polarity_bit = 1, \
+ .intr_detection_bit = 2, \
+ .intr_detection_width = 2, \
+ }
+
+#define SDC_QDSD_PINGROUP(pg_name, ctl, pull, drv) \
+ { \
+ .name = #pg_name, \
+ .pins = pg_name##_pins, \
+ .npins = (unsigned int)ARRAY_SIZE(pg_name##_pins), \
+ .ctl_reg = ctl, \
+ .io_reg = 0, \
+ .intr_cfg_reg = 0, \
+ .intr_status_reg = 0, \
+ .intr_target_reg = 0, \
+ .tile = NORTH, \
+ .mux_bit = -1, \
+ .pull_bit = pull, \
+ .drv_bit = drv, \
+ .oe_bit = -1, \
+ .in_bit = -1, \
+ .out_bit = -1, \
+ .intr_enable_bit = -1, \
+ .intr_status_bit = -1, \
+ .intr_target_bit = -1, \
+ .intr_raw_status_bit = -1, \
+ .intr_polarity_bit = -1, \
+ .intr_detection_bit = -1, \
+ .intr_detection_width = -1, \
+ }
+
+#define UFS_RESET(pg_name, offset) \
+ { \
+ .name = #pg_name, \
+ .pins = pg_name##_pins, \
+ .npins = (unsigned int)ARRAY_SIZE(pg_name##_pins), \
+ .ctl_reg = offset, \
+ .io_reg = offset + 0x4, \
+ .intr_cfg_reg = 0, \
+ .intr_status_reg = 0, \
+ .intr_target_reg = 0, \
+ .tile = SOUTH, \
+ .mux_bit = -1, \
+ .pull_bit = 3, \
+ .drv_bit = 0, \
+ .oe_bit = -1, \
+ .in_bit = -1, \
+ .out_bit = 0, \
+ .intr_enable_bit = -1, \
+ .intr_status_bit = -1, \
+ .intr_target_bit = -1, \
+ .intr_raw_status_bit = -1, \
+ .intr_polarity_bit = -1, \
+ .intr_detection_bit = -1, \
+ .intr_detection_width = -1, \
+ }
+
+static const struct pinctrl_pin_desc sm8150_pins[] = {
+ PINCTRL_PIN(0, "GPIO_0"),
+ PINCTRL_PIN(1, "GPIO_1"),
+ PINCTRL_PIN(2, "GPIO_2"),
+ PINCTRL_PIN(3, "GPIO_3"),
+ PINCTRL_PIN(4, "GPIO_4"),
+ PINCTRL_PIN(5, "GPIO_5"),
+ PINCTRL_PIN(6, "GPIO_6"),
+ PINCTRL_PIN(7, "GPIO_7"),
+ PINCTRL_PIN(8, "GPIO_8"),
+ PINCTRL_PIN(9, "GPIO_9"),
+ PINCTRL_PIN(10, "GPIO_10"),
+ PINCTRL_PIN(11, "GPIO_11"),
+ PINCTRL_PIN(12, "GPIO_12"),
+ PINCTRL_PIN(13, "GPIO_13"),
+ PINCTRL_PIN(14, "GPIO_14"),
+ PINCTRL_PIN(15, "GPIO_15"),
+ PINCTRL_PIN(16, "GPIO_16"),
+ PINCTRL_PIN(17, "GPIO_17"),
+ PINCTRL_PIN(18, "GPIO_18"),
+ PINCTRL_PIN(19, "GPIO_19"),
+ PINCTRL_PIN(20, "GPIO_20"),
+ PINCTRL_PIN(21, "GPIO_21"),
+ PINCTRL_PIN(22, "GPIO_22"),
+ PINCTRL_PIN(23, "GPIO_23"),
+ PINCTRL_PIN(24, "GPIO_24"),
+ PINCTRL_PIN(25, "GPIO_25"),
+ PINCTRL_PIN(26, "GPIO_26"),
+ PINCTRL_PIN(27, "GPIO_27"),
+ PINCTRL_PIN(28, "GPIO_28"),
+ PINCTRL_PIN(29, "GPIO_29"),
+ PINCTRL_PIN(30, "GPIO_30"),
+ PINCTRL_PIN(31, "GPIO_31"),
+ PINCTRL_PIN(32, "GPIO_32"),
+ PINCTRL_PIN(33, "GPIO_33"),
+ PINCTRL_PIN(34, "GPIO_34"),
+ PINCTRL_PIN(35, "GPIO_35"),
+ PINCTRL_PIN(36, "GPIO_36"),
+ PINCTRL_PIN(37, "GPIO_37"),
+ PINCTRL_PIN(38, "GPIO_38"),
+ PINCTRL_PIN(39, "GPIO_39"),
+ PINCTRL_PIN(40, "GPIO_40"),
+ PINCTRL_PIN(41, "GPIO_41"),
+ PINCTRL_PIN(42, "GPIO_42"),
+ PINCTRL_PIN(43, "GPIO_43"),
+ PINCTRL_PIN(44, "GPIO_44"),
+ PINCTRL_PIN(45, "GPIO_45"),
+ PINCTRL_PIN(46, "GPIO_46"),
+ PINCTRL_PIN(47, "GPIO_47"),
+ PINCTRL_PIN(48, "GPIO_48"),
+ PINCTRL_PIN(49, "GPIO_49"),
+ PINCTRL_PIN(50, "GPIO_50"),
+ PINCTRL_PIN(51, "GPIO_51"),
+ PINCTRL_PIN(52, "GPIO_52"),
+ PINCTRL_PIN(53, "GPIO_53"),
+ PINCTRL_PIN(54, "GPIO_54"),
+ PINCTRL_PIN(55, "GPIO_55"),
+ PINCTRL_PIN(56, "GPIO_56"),
+ PINCTRL_PIN(57, "GPIO_57"),
+ PINCTRL_PIN(58, "GPIO_58"),
+ PINCTRL_PIN(59, "GPIO_59"),
+ PINCTRL_PIN(60, "GPIO_60"),
+ PINCTRL_PIN(61, "GPIO_61"),
+ PINCTRL_PIN(62, "GPIO_62"),
+ PINCTRL_PIN(63, "GPIO_63"),
+ PINCTRL_PIN(64, "GPIO_64"),
+ PINCTRL_PIN(65, "GPIO_65"),
+ PINCTRL_PIN(66, "GPIO_66"),
+ PINCTRL_PIN(67, "GPIO_67"),
+ PINCTRL_PIN(68, "GPIO_68"),
+ PINCTRL_PIN(69, "GPIO_69"),
+ PINCTRL_PIN(70, "GPIO_70"),
+ PINCTRL_PIN(71, "GPIO_71"),
+ PINCTRL_PIN(72, "GPIO_72"),
+ PINCTRL_PIN(73, "GPIO_73"),
+ PINCTRL_PIN(74, "GPIO_74"),
+ PINCTRL_PIN(75, "GPIO_75"),
+ PINCTRL_PIN(76, "GPIO_76"),
+ PINCTRL_PIN(77, "GPIO_77"),
+ PINCTRL_PIN(78, "GPIO_78"),
+ PINCTRL_PIN(79, "GPIO_79"),
+ PINCTRL_PIN(80, "GPIO_80"),
+ PINCTRL_PIN(81, "GPIO_81"),
+ PINCTRL_PIN(82, "GPIO_82"),
+ PINCTRL_PIN(83, "GPIO_83"),
+ PINCTRL_PIN(84, "GPIO_84"),
+ PINCTRL_PIN(85, "GPIO_85"),
+ PINCTRL_PIN(86, "GPIO_86"),
+ PINCTRL_PIN(87, "GPIO_87"),
+ PINCTRL_PIN(88, "GPIO_88"),
+ PINCTRL_PIN(89, "GPIO_89"),
+ PINCTRL_PIN(90, "GPIO_90"),
+ PINCTRL_PIN(91, "GPIO_91"),
+ PINCTRL_PIN(92, "GPIO_92"),
+ PINCTRL_PIN(93, "GPIO_93"),
+ PINCTRL_PIN(94, "GPIO_94"),
+ PINCTRL_PIN(95, "GPIO_95"),
+ PINCTRL_PIN(96, "GPIO_96"),
+ PINCTRL_PIN(97, "GPIO_97"),
+ PINCTRL_PIN(98, "GPIO_98"),
+ PINCTRL_PIN(99, "GPIO_99"),
+ PINCTRL_PIN(100, "GPIO_100"),
+ PINCTRL_PIN(101, "GPIO_101"),
+ PINCTRL_PIN(102, "GPIO_102"),
+ PINCTRL_PIN(103, "GPIO_103"),
+ PINCTRL_PIN(104, "GPIO_104"),
+ PINCTRL_PIN(105, "GPIO_105"),
+ PINCTRL_PIN(106, "GPIO_106"),
+ PINCTRL_PIN(107, "GPIO_107"),
+ PINCTRL_PIN(108, "GPIO_108"),
+ PINCTRL_PIN(109, "GPIO_109"),
+ PINCTRL_PIN(110, "GPIO_110"),
+ PINCTRL_PIN(111, "GPIO_111"),
+ PINCTRL_PIN(112, "GPIO_112"),
+ PINCTRL_PIN(113, "GPIO_113"),
+ PINCTRL_PIN(114, "GPIO_114"),
+ PINCTRL_PIN(115, "GPIO_115"),
+ PINCTRL_PIN(116, "GPIO_116"),
+ PINCTRL_PIN(117, "GPIO_117"),
+ PINCTRL_PIN(118, "GPIO_118"),
+ PINCTRL_PIN(119, "GPIO_119"),
+ PINCTRL_PIN(120, "GPIO_120"),
+ PINCTRL_PIN(121, "GPIO_121"),
+ PINCTRL_PIN(122, "GPIO_122"),
+ PINCTRL_PIN(123, "GPIO_123"),
+ PINCTRL_PIN(124, "GPIO_124"),
+ PINCTRL_PIN(125, "GPIO_125"),
+ PINCTRL_PIN(126, "GPIO_126"),
+ PINCTRL_PIN(127, "GPIO_127"),
+ PINCTRL_PIN(128, "GPIO_128"),
+ PINCTRL_PIN(129, "GPIO_129"),
+ PINCTRL_PIN(130, "GPIO_130"),
+ PINCTRL_PIN(131, "GPIO_131"),
+ PINCTRL_PIN(132, "GPIO_132"),
+ PINCTRL_PIN(133, "GPIO_133"),
+ PINCTRL_PIN(134, "GPIO_134"),
+ PINCTRL_PIN(135, "GPIO_135"),
+ PINCTRL_PIN(136, "GPIO_136"),
+ PINCTRL_PIN(137, "GPIO_137"),
+ PINCTRL_PIN(138, "GPIO_138"),
+ PINCTRL_PIN(139, "GPIO_139"),
+ PINCTRL_PIN(140, "GPIO_140"),
+ PINCTRL_PIN(141, "GPIO_141"),
+ PINCTRL_PIN(142, "GPIO_142"),
+ PINCTRL_PIN(143, "GPIO_143"),
+ PINCTRL_PIN(144, "GPIO_144"),
+ PINCTRL_PIN(145, "GPIO_145"),
+ PINCTRL_PIN(146, "GPIO_146"),
+ PINCTRL_PIN(147, "GPIO_147"),
+ PINCTRL_PIN(148, "GPIO_148"),
+ PINCTRL_PIN(149, "GPIO_149"),
+ PINCTRL_PIN(150, "GPIO_150"),
+ PINCTRL_PIN(151, "GPIO_151"),
+ PINCTRL_PIN(152, "GPIO_152"),
+ PINCTRL_PIN(153, "GPIO_153"),
+ PINCTRL_PIN(154, "GPIO_154"),
+ PINCTRL_PIN(155, "GPIO_155"),
+ PINCTRL_PIN(156, "GPIO_156"),
+ PINCTRL_PIN(157, "GPIO_157"),
+ PINCTRL_PIN(158, "GPIO_158"),
+ PINCTRL_PIN(159, "GPIO_159"),
+ PINCTRL_PIN(160, "GPIO_160"),
+ PINCTRL_PIN(161, "GPIO_161"),
+ PINCTRL_PIN(162, "GPIO_162"),
+ PINCTRL_PIN(163, "GPIO_163"),
+ PINCTRL_PIN(164, "GPIO_164"),
+ PINCTRL_PIN(165, "GPIO_165"),
+ PINCTRL_PIN(166, "GPIO_166"),
+ PINCTRL_PIN(167, "GPIO_167"),
+ PINCTRL_PIN(168, "GPIO_168"),
+ PINCTRL_PIN(169, "GPIO_169"),
+ PINCTRL_PIN(170, "GPIO_170"),
+ PINCTRL_PIN(171, "GPIO_171"),
+ PINCTRL_PIN(172, "GPIO_172"),
+ PINCTRL_PIN(173, "GPIO_173"),
+ PINCTRL_PIN(174, "GPIO_174"),
+ PINCTRL_PIN(175, "UFS_RESET"),
+ PINCTRL_PIN(176, "SDC2_CLK"),
+ PINCTRL_PIN(177, "SDC2_CMD"),
+ PINCTRL_PIN(178, "SDC2_DATA"),
+};
+
+#define DECLARE_MSM_GPIO_PINS(pin) \
+ static const unsigned int gpio##pin##_pins[] = { pin }
+DECLARE_MSM_GPIO_PINS(0);
+DECLARE_MSM_GPIO_PINS(1);
+DECLARE_MSM_GPIO_PINS(2);
+DECLARE_MSM_GPIO_PINS(3);
+DECLARE_MSM_GPIO_PINS(4);
+DECLARE_MSM_GPIO_PINS(5);
+DECLARE_MSM_GPIO_PINS(6);
+DECLARE_MSM_GPIO_PINS(7);
+DECLARE_MSM_GPIO_PINS(8);
+DECLARE_MSM_GPIO_PINS(9);
+DECLARE_MSM_GPIO_PINS(10);
+DECLARE_MSM_GPIO_PINS(11);
+DECLARE_MSM_GPIO_PINS(12);
+DECLARE_MSM_GPIO_PINS(13);
+DECLARE_MSM_GPIO_PINS(14);
+DECLARE_MSM_GPIO_PINS(15);
+DECLARE_MSM_GPIO_PINS(16);
+DECLARE_MSM_GPIO_PINS(17);
+DECLARE_MSM_GPIO_PINS(18);
+DECLARE_MSM_GPIO_PINS(19);
+DECLARE_MSM_GPIO_PINS(20);
+DECLARE_MSM_GPIO_PINS(21);
+DECLARE_MSM_GPIO_PINS(22);
+DECLARE_MSM_GPIO_PINS(23);
+DECLARE_MSM_GPIO_PINS(24);
+DECLARE_MSM_GPIO_PINS(25);
+DECLARE_MSM_GPIO_PINS(26);
+DECLARE_MSM_GPIO_PINS(27);
+DECLARE_MSM_GPIO_PINS(28);
+DECLARE_MSM_GPIO_PINS(29);
+DECLARE_MSM_GPIO_PINS(30);
+DECLARE_MSM_GPIO_PINS(31);
+DECLARE_MSM_GPIO_PINS(32);
+DECLARE_MSM_GPIO_PINS(33);
+DECLARE_MSM_GPIO_PINS(34);
+DECLARE_MSM_GPIO_PINS(35);
+DECLARE_MSM_GPIO_PINS(36);
+DECLARE_MSM_GPIO_PINS(37);
+DECLARE_MSM_GPIO_PINS(38);
+DECLARE_MSM_GPIO_PINS(39);
+DECLARE_MSM_GPIO_PINS(40);
+DECLARE_MSM_GPIO_PINS(41);
+DECLARE_MSM_GPIO_PINS(42);
+DECLARE_MSM_GPIO_PINS(43);
+DECLARE_MSM_GPIO_PINS(44);
+DECLARE_MSM_GPIO_PINS(45);
+DECLARE_MSM_GPIO_PINS(46);
+DECLARE_MSM_GPIO_PINS(47);
+DECLARE_MSM_GPIO_PINS(48);
+DECLARE_MSM_GPIO_PINS(49);
+DECLARE_MSM_GPIO_PINS(50);
+DECLARE_MSM_GPIO_PINS(51);
+DECLARE_MSM_GPIO_PINS(52);
+DECLARE_MSM_GPIO_PINS(53);
+DECLARE_MSM_GPIO_PINS(54);
+DECLARE_MSM_GPIO_PINS(55);
+DECLARE_MSM_GPIO_PINS(56);
+DECLARE_MSM_GPIO_PINS(57);
+DECLARE_MSM_GPIO_PINS(58);
+DECLARE_MSM_GPIO_PINS(59);
+DECLARE_MSM_GPIO_PINS(60);
+DECLARE_MSM_GPIO_PINS(61);
+DECLARE_MSM_GPIO_PINS(62);
+DECLARE_MSM_GPIO_PINS(63);
+DECLARE_MSM_GPIO_PINS(64);
+DECLARE_MSM_GPIO_PINS(65);
+DECLARE_MSM_GPIO_PINS(66);
+DECLARE_MSM_GPIO_PINS(67);
+DECLARE_MSM_GPIO_PINS(68);
+DECLARE_MSM_GPIO_PINS(69);
+DECLARE_MSM_GPIO_PINS(70);
+DECLARE_MSM_GPIO_PINS(71);
+DECLARE_MSM_GPIO_PINS(72);
+DECLARE_MSM_GPIO_PINS(73);
+DECLARE_MSM_GPIO_PINS(74);
+DECLARE_MSM_GPIO_PINS(75);
+DECLARE_MSM_GPIO_PINS(76);
+DECLARE_MSM_GPIO_PINS(77);
+DECLARE_MSM_GPIO_PINS(78);
+DECLARE_MSM_GPIO_PINS(79);
+DECLARE_MSM_GPIO_PINS(80);
+DECLARE_MSM_GPIO_PINS(81);
+DECLARE_MSM_GPIO_PINS(82);
+DECLARE_MSM_GPIO_PINS(83);
+DECLARE_MSM_GPIO_PINS(84);
+DECLARE_MSM_GPIO_PINS(85);
+DECLARE_MSM_GPIO_PINS(86);
+DECLARE_MSM_GPIO_PINS(87);
+DECLARE_MSM_GPIO_PINS(88);
+DECLARE_MSM_GPIO_PINS(89);
+DECLARE_MSM_GPIO_PINS(90);
+DECLARE_MSM_GPIO_PINS(91);
+DECLARE_MSM_GPIO_PINS(92);
+DECLARE_MSM_GPIO_PINS(93);
+DECLARE_MSM_GPIO_PINS(94);
+DECLARE_MSM_GPIO_PINS(95);
+DECLARE_MSM_GPIO_PINS(96);
+DECLARE_MSM_GPIO_PINS(97);
+DECLARE_MSM_GPIO_PINS(98);
+DECLARE_MSM_GPIO_PINS(99);
+DECLARE_MSM_GPIO_PINS(100);
+DECLARE_MSM_GPIO_PINS(101);
+DECLARE_MSM_GPIO_PINS(102);
+DECLARE_MSM_GPIO_PINS(103);
+DECLARE_MSM_GPIO_PINS(104);
+DECLARE_MSM_GPIO_PINS(105);
+DECLARE_MSM_GPIO_PINS(106);
+DECLARE_MSM_GPIO_PINS(107);
+DECLARE_MSM_GPIO_PINS(108);
+DECLARE_MSM_GPIO_PINS(109);
+DECLARE_MSM_GPIO_PINS(110);
+DECLARE_MSM_GPIO_PINS(111);
+DECLARE_MSM_GPIO_PINS(112);
+DECLARE_MSM_GPIO_PINS(113);
+DECLARE_MSM_GPIO_PINS(114);
+DECLARE_MSM_GPIO_PINS(115);
+DECLARE_MSM_GPIO_PINS(116);
+DECLARE_MSM_GPIO_PINS(117);
+DECLARE_MSM_GPIO_PINS(118);
+DECLARE_MSM_GPIO_PINS(119);
+DECLARE_MSM_GPIO_PINS(120);
+DECLARE_MSM_GPIO_PINS(121);
+DECLARE_MSM_GPIO_PINS(122);
+DECLARE_MSM_GPIO_PINS(123);
+DECLARE_MSM_GPIO_PINS(124);
+DECLARE_MSM_GPIO_PINS(125);
+DECLARE_MSM_GPIO_PINS(126);
+DECLARE_MSM_GPIO_PINS(127);
+DECLARE_MSM_GPIO_PINS(128);
+DECLARE_MSM_GPIO_PINS(129);
+DECLARE_MSM_GPIO_PINS(130);
+DECLARE_MSM_GPIO_PINS(131);
+DECLARE_MSM_GPIO_PINS(132);
+DECLARE_MSM_GPIO_PINS(133);
+DECLARE_MSM_GPIO_PINS(134);
+DECLARE_MSM_GPIO_PINS(135);
+DECLARE_MSM_GPIO_PINS(136);
+DECLARE_MSM_GPIO_PINS(137);
+DECLARE_MSM_GPIO_PINS(138);
+DECLARE_MSM_GPIO_PINS(139);
+DECLARE_MSM_GPIO_PINS(140);
+DECLARE_MSM_GPIO_PINS(141);
+DECLARE_MSM_GPIO_PINS(142);
+DECLARE_MSM_GPIO_PINS(143);
+DECLARE_MSM_GPIO_PINS(144);
+DECLARE_MSM_GPIO_PINS(145);
+DECLARE_MSM_GPIO_PINS(146);
+DECLARE_MSM_GPIO_PINS(147);
+DECLARE_MSM_GPIO_PINS(148);
+DECLARE_MSM_GPIO_PINS(149);
+DECLARE_MSM_GPIO_PINS(150);
+DECLARE_MSM_GPIO_PINS(151);
+DECLARE_MSM_GPIO_PINS(152);
+DECLARE_MSM_GPIO_PINS(153);
+DECLARE_MSM_GPIO_PINS(154);
+DECLARE_MSM_GPIO_PINS(155);
+DECLARE_MSM_GPIO_PINS(156);
+DECLARE_MSM_GPIO_PINS(157);
+DECLARE_MSM_GPIO_PINS(158);
+DECLARE_MSM_GPIO_PINS(159);
+DECLARE_MSM_GPIO_PINS(160);
+DECLARE_MSM_GPIO_PINS(161);
+DECLARE_MSM_GPIO_PINS(162);
+DECLARE_MSM_GPIO_PINS(163);
+DECLARE_MSM_GPIO_PINS(164);
+DECLARE_MSM_GPIO_PINS(165);
+DECLARE_MSM_GPIO_PINS(166);
+DECLARE_MSM_GPIO_PINS(167);
+DECLARE_MSM_GPIO_PINS(168);
+DECLARE_MSM_GPIO_PINS(169);
+DECLARE_MSM_GPIO_PINS(170);
+DECLARE_MSM_GPIO_PINS(171);
+DECLARE_MSM_GPIO_PINS(172);
+DECLARE_MSM_GPIO_PINS(173);
+DECLARE_MSM_GPIO_PINS(174);
+
+static const unsigned int ufs_reset_pins[] = { 175 };
+static const unsigned int sdc2_clk_pins[] = { 176 };
+static const unsigned int sdc2_cmd_pins[] = { 177 };
+static const unsigned int sdc2_data_pins[] = { 178 };
+
+enum sm8150_functions {
+ msm_mux_adsp_ext,
+ msm_mux_agera_pll,
+ msm_mux_aoss_cti,
+ msm_mux_atest_char,
+ msm_mux_atest_char0,
+ msm_mux_atest_char1,
+ msm_mux_atest_char2,
+ msm_mux_atest_char3,
+ msm_mux_atest_usb1,
+ msm_mux_atest_usb2,
+ msm_mux_atest_usb10,
+ msm_mux_atest_usb11,
+ msm_mux_atest_usb12,
+ msm_mux_atest_usb13,
+ msm_mux_atest_usb20,
+ msm_mux_atest_usb21,
+ msm_mux_atest_usb22,
+ msm_mux_atest_usb23,
+ msm_mux_audio_ref,
+ msm_mux_btfm_slimbus,
+ msm_mux_cam_mclk,
+ msm_mux_cci_async,
+ msm_mux_cci_i2c,
+ msm_mux_cci_timer0,
+ msm_mux_cci_timer1,
+ msm_mux_cci_timer2,
+ msm_mux_cci_timer3,
+ msm_mux_cci_timer4,
+ msm_mux_cri_trng,
+ msm_mux_cri_trng0,
+ msm_mux_cri_trng1,
+ msm_mux_dbg_out,
+ msm_mux_ddr_bist,
+ msm_mux_ddr_pxi0,
+ msm_mux_ddr_pxi1,
+ msm_mux_ddr_pxi2,
+ msm_mux_ddr_pxi3,
+ msm_mux_edp_hot,
+ msm_mux_edp_lcd,
+ msm_mux_emac_phy,
+ msm_mux_emac_pps,
+ msm_mux_gcc_gp1,
+ msm_mux_gcc_gp2,
+ msm_mux_gcc_gp3,
+ msm_mux_gpio,
+ msm_mux_jitter_bist,
+ msm_mux_hs1_mi2s,
+ msm_mux_hs2_mi2s,
+ msm_mux_hs3_mi2s,
+ msm_mux_lpass_slimbus,
+ msm_mux_mdp_vsync,
+ msm_mux_mdp_vsync0,
+ msm_mux_mdp_vsync1,
+ msm_mux_mdp_vsync2,
+ msm_mux_mdp_vsync3,
+ msm_mux_mss_lte,
+ msm_mux_m_voc,
+ msm_mux_nav_pps,
+ msm_mux_pa_indicator,
+ msm_mux_pci_e0,
+ msm_mux_pci_e1,
+ msm_mux_phase_flag,
+ msm_mux_pll_bist,
+ msm_mux_pll_bypassnl,
+ msm_mux_pll_reset,
+ msm_mux_pri_mi2s,
+ msm_mux_pri_mi2s_ws,
+ msm_mux_prng_rosc,
+ msm_mux_qdss,
+ msm_mux_qdss_cti,
+ msm_mux_qlink_enable,
+ msm_mux_qlink_request,
+ msm_mux_qspi0,
+ msm_mux_qspi1,
+ msm_mux_qspi2,
+ msm_mux_qspi3,
+ msm_mux_qspi_clk,
+ msm_mux_qspi_cs,
+ msm_mux_qua_mi2s,
+ msm_mux_qup0,
+ msm_mux_qup1,
+ msm_mux_qup2,
+ msm_mux_qup3,
+ msm_mux_qup4,
+ msm_mux_qup5,
+ msm_mux_qup6,
+ msm_mux_qup7,
+ msm_mux_qup8,
+ msm_mux_qup9,
+ msm_mux_qup10,
+ msm_mux_qup11,
+ msm_mux_qup12,
+ msm_mux_qup13,
+ msm_mux_qup14,
+ msm_mux_qup15,
+ msm_mux_qup16,
+ msm_mux_qup17,
+ msm_mux_qup18,
+ msm_mux_qup19,
+ msm_mux_qup_l4,
+ msm_mux_qup_l5,
+ msm_mux_qup_l6,
+ msm_mux_rgmii,
+ msm_mux_sdc4,
+ msm_mux_sd_write,
+ msm_mux_sec_mi2s,
+ msm_mux_spkr_i2s,
+ msm_mux_sp_cmu,
+ msm_mux_ter_mi2s,
+ msm_mux_tgu_ch0,
+ msm_mux_tgu_ch2,
+ msm_mux_tgu_ch1,
+ msm_mux_tgu_ch3,
+ msm_mux_tsense_pwm1,
+ msm_mux_tsense_pwm2,
+ msm_mux_tsif1,
+ msm_mux_tsif2,
+ msm_mux_uim1,
+ msm_mux_uim2,
+ msm_mux_uim_batt,
+ msm_mux_usb2phy_ac,
+ msm_mux_usb_phy,
+ msm_mux_vfr_1,
+ msm_mux_vsense_trigger,
+ msm_mux_wlan1_adc1,
+ msm_mux_wlan1_adc0,
+ msm_mux_wlan2_adc1,
+ msm_mux_wlan2_adc0,
+ msm_mux_wmss_reset,
+ msm_mux__,
+};
+
+static const char * const phase_flag_groups[] = {
+ "gpio18", "gpio19", "gpio20", "gpio55", "gpio56",
+ "gpio57", "gpio59", "gpio64", "gpio68", "gpio76",
+ "gpio79", "gpio80", "gpio90", "gpio91", "gpio92",
+ "gpio93", "gpio94", "gpio96", "gpio114", "gpio115",
+ "gpio116", "gpio117", "gpio118", "gpio119", "gpio120",
+ "gpio121", "gpio122", "gpio126", "gpio127", "gpio128",
+ "gpio144", "gpio145",
+};
+
+static const char * const emac_pps_groups[] = {
+ "gpio81",
+};
+
+static const char * const qup12_groups[] = {
+ "gpio83", "gpio84", "gpio85", "gpio86",
+};
+
+static const char * const qup16_groups[] = {
+ "gpio83", "gpio84", "gpio85", "gpio86",
+};
+
+static const char * const tsif1_groups[] = {
+ "gpio88", "gpio89", "gpio90", "gpio91", "gpio97",
+};
+
+static const char * const qup8_groups[] = {
+ "gpio88", "gpio89", "gpio90", "gpio91",
+};
+
+static const char * const qspi_cs_groups[] = {
+ "gpio88", "gpio94",
+};
+
+static const char * const tgu_ch3_groups[] = {
+ "gpio88",
+};
+
+static const char * const qspi0_groups[] = {
+ "gpio89",
+};
+
+static const char * const mdp_vsync0_groups[] = {
+ "gpio89",
+};
+
+static const char * const mdp_vsync1_groups[] = {
+ "gpio89",
+};
+
+static const char * const mdp_vsync2_groups[] = {
+ "gpio89",
+};
+
+static const char * const mdp_vsync3_groups[] = {
+ "gpio89",
+};
+
+static const char * const tgu_ch0_groups[] = {
+ "gpio89",
+};
+
+static const char * const qspi1_groups[] = {
+ "gpio90",
+};
+
+static const char * const sdc4_groups[] = {
+ "gpio90", "gpio91", "gpio92", "gpio93", "gpio94", "gpio95",
+};
+
+static const char * const tgu_ch1_groups[] = {
+ "gpio90",
+};
+
+static const char * const wlan1_adc1_groups[] = {
+ "gpio90",
+};
+
+static const char * const qspi2_groups[] = {
+ "gpio91",
+};
+
+static const char * const vfr_1_groups[] = {
+ "gpio91",
+};
+
+static const char * const tgu_ch2_groups[] = {
+ "gpio91",
+};
+
+static const char * const wlan1_adc0_groups[] = {
+ "gpio91",
+};
+
+static const char * const tsif2_groups[] = {
+ "gpio92", "gpio93", "gpio94", "gpio95", "gpio96",
+};
+
+static const char * const qup11_groups[] = {
+ "gpio92", "gpio93", "gpio94", "gpio95",
+};
+
+static const char * const qspi_clk_groups[] = {
+ "gpio92",
+};
+
+static const char * const wlan2_adc1_groups[] = {
+ "gpio92",
+};
+
+static const char * const qspi3_groups[] = {
+ "gpio93",
+};
+
+static const char * const wlan2_adc0_groups[] = {
+ "gpio93",
+};
+
+static const char * const sd_write_groups[] = {
+ "gpio97",
+};
+
+static const char * const qup7_groups[] = {
+ "gpio98", "gpio99", "gpio100", "gpio101",
+};
+
+static const char * const ddr_bist_groups[] = {
+ "gpio98", "gpio99", "gpio145", "gpio146",
+};
+
+static const char * const ddr_pxi3_groups[] = {
+ "gpio98", "gpio101",
+};
+
+static const char * const atest_usb13_groups[] = {
+ "gpio99",
+};
+
+static const char * const ddr_pxi1_groups[] = {
+ "gpio99", "gpio100",
+};
+
+static const char * const pll_bypassnl_groups[] = {
+ "gpio100",
+};
+
+static const char * const atest_usb12_groups[] = {
+ "gpio100",
+};
+
+static const char * const pll_reset_groups[] = {
+ "gpio101",
+};
+
+static const char * const pci_e1_groups[] = {
+ "gpio102", "gpio103",
+};
+
+static const char * const uim2_groups[] = {
+ "gpio105", "gpio106", "gpio107", "gpio108",
+};
+
+static const char * const uim1_groups[] = {
+ "gpio109", "gpio110", "gpio111", "gpio112",
+};
+
+static const char * const uim_batt_groups[] = {
+ "gpio113",
+};
+
+static const char * const usb2phy_ac_groups[] = {
+ "gpio113", "gpio123",
+};
+
+static const char * const aoss_cti_groups[] = {
+ "gpio113",
+};
+
+static const char * const qup1_groups[] = {
+ "gpio114", "gpio115", "gpio116", "gpio117",
+};
+
+static const char * const rgmii_groups[] = {
+ "gpio4", "gpio5", "gpio6", "gpio7", "gpio59",
+ "gpio114", "gpio115", "gpio116", "gpio117",
+ "gpio118", "gpio119", "gpio120", "gpio121", "gpio122",
+};
+
+static const char * const adsp_ext_groups[] = {
+ "gpio115",
+};
+
+static const char * const qup5_groups[] = {
+ "gpio119", "gpio120", "gpio121", "gpio122",
+};
+
+static const char * const atest_usb22_groups[] = {
+ "gpio123",
+};
+
+static const char * const emac_phy_groups[] = {
+ "gpio124",
+};
+
+static const char * const hs3_mi2s_groups[] = {
+ "gpio125", "gpio165", "gpio166", "gpio167", "gpio168",
+};
+
+static const char * const sec_mi2s_groups[] = {
+ "gpio126", "gpio127", "gpio128", "gpio129", "gpio130",
+};
+
+static const char * const qup2_groups[] = {
+ "gpio126", "gpio127", "gpio128", "gpio129",
+};
+
+static const char * const jitter_bist_groups[] = {
+ "gpio129",
+};
+
+static const char * const atest_usb21_groups[] = {
+ "gpio129",
+};
+
+static const char * const pll_bist_groups[] = {
+ "gpio130",
+};
+
+static const char * const atest_usb20_groups[] = {
+ "gpio130",
+};
+
+static const char * const atest_char0_groups[] = {
+ "gpio130",
+};
+
+static const char * const ter_mi2s_groups[] = {
+ "gpio131", "gpio132", "gpio133", "gpio134", "gpio135",
+};
+
+static const char * const gcc_gp1_groups[] = {
+ "gpio131", "gpio136",
+};
+
+static const char * const atest_char1_groups[] = {
+ "gpio133",
+};
+
+static const char * const atest_char2_groups[] = {
+ "gpio134",
+};
+
+static const char * const atest_char3_groups[] = {
+ "gpio135",
+};
+
+static const char * const qua_mi2s_groups[] = {
+ "gpio136", "gpio137", "gpio138", "gpio139", "gpio140", "gpio141",
+ "gpio142",
+};
+
+static const char * const pri_mi2s_groups[] = {
+ "gpio143", "gpio144", "gpio146", "gpio147",
+};
+
+static const char * const qup3_groups[] = {
+ "gpio144", "gpio145", "gpio146", "gpio147",
+};
+
+static const char * const ddr_pxi0_groups[] = {
+ "gpio144", "gpio145",
+};
+
+static const char * const pri_mi2s_ws_groups[] = {
+ "gpio145",
+};
+
+static const char * const vsense_trigger_groups[] = {
+ "gpio145",
+};
+
+static const char * const atest_usb1_groups[] = {
+ "gpio145",
+};
+
+static const char * const atest_usb11_groups[] = {
+ "gpio146",
+};
+
+static const char * const ddr_pxi2_groups[] = {
+ "gpio146", "gpio147",
+};
+
+static const char * const dbg_out_groups[] = {
+ "gpio147",
+};
+
+static const char * const atest_usb10_groups[] = {
+ "gpio147",
+};
+
+static const char * const spkr_i2s_groups[] = {
+ "gpio148", "gpio149", "gpio150", "gpio151", "gpio152",
+};
+
+static const char * const audio_ref_groups[] = {
+ "gpio148",
+};
+
+static const char * const lpass_slimbus_groups[] = {
+ "gpio149", "gpio150", "gpio151", "gpio152",
+};
+
+static const char * const tsense_pwm1_groups[] = {
+ "gpio150",
+};
+
+static const char * const tsense_pwm2_groups[] = {
+ "gpio150",
+};
+
+static const char * const btfm_slimbus_groups[] = {
+ "gpio153", "gpio154",
+};
+
+static const char * const hs1_mi2s_groups[] = {
+ "gpio155", "gpio156", "gpio157", "gpio158", "gpio159",
+};
+
+static const char * const cri_trng0_groups[] = {
+ "gpio159",
+};
+
+static const char * const hs2_mi2s_groups[] = {
+ "gpio160", "gpio161", "gpio162", "gpio163", "gpio164",
+};
+
+static const char * const cri_trng1_groups[] = {
+ "gpio160",
+};
+
+static const char * const cri_trng_groups[] = {
+ "gpio161",
+};
+
+static const char * const sp_cmu_groups[] = {
+ "gpio162",
+};
+
+static const char * const prng_rosc_groups[] = {
+ "gpio163",
+};
+
+static const char * const qup0_groups[] = {
+ "gpio0", "gpio1", "gpio2", "gpio3",
+};
+
+static const char * const gpio_groups[] = {
+ "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7",
+ "gpio8", "gpio9", "gpio10", "gpio11", "gpio12", "gpio13", "gpio14",
+ "gpio15", "gpio16", "gpio17", "gpio18", "gpio19", "gpio20", "gpio21",
+ "gpio22", "gpio23", "gpio24", "gpio25", "gpio26", "gpio27", "gpio28",
+ "gpio29", "gpio30", "gpio31", "gpio32", "gpio33", "gpio34", "gpio35",
+ "gpio36", "gpio37", "gpio38", "gpio39", "gpio40", "gpio41", "gpio42",
+ "gpio43", "gpio44", "gpio45", "gpio46", "gpio47", "gpio48", "gpio49",
+ "gpio50", "gpio51", "gpio52", "gpio53", "gpio54", "gpio55", "gpio56",
+ "gpio57", "gpio58", "gpio59", "gpio60", "gpio61", "gpio62", "gpio63",
+ "gpio64", "gpio65", "gpio66", "gpio67", "gpio68", "gpio69", "gpio70",
+ "gpio71", "gpio72", "gpio73", "gpio74", "gpio75", "gpio76", "gpio77",
+ "gpio78", "gpio79", "gpio80", "gpio81", "gpio82", "gpio83", "gpio84",
+ "gpio85", "gpio86", "gpio87", "gpio88", "gpio89", "gpio90", "gpio91",
+ "gpio92", "gpio93", "gpio94", "gpio95", "gpio96", "gpio97", "gpio98",
+ "gpio99", "gpio100", "gpio101", "gpio102", "gpio103", "gpio104",
+ "gpio105", "gpio106", "gpio107", "gpio108", "gpio109", "gpio110",
+ "gpio111", "gpio112", "gpio113", "gpio114", "gpio115", "gpio116",
+ "gpio117", "gpio118", "gpio119", "gpio120", "gpio121", "gpio122",
+ "gpio123", "gpio124", "gpio125", "gpio126", "gpio127", "gpio128",
+ "gpio129", "gpio130", "gpio131", "gpio132", "gpio133", "gpio134",
+ "gpio135", "gpio136", "gpio137", "gpio138", "gpio139", "gpio140",
+ "gpio141", "gpio142", "gpio143", "gpio144", "gpio145", "gpio146",
+ "gpio147", "gpio148", "gpio149", "gpio150", "gpio151", "gpio152",
+ "gpio153", "gpio154", "gpio155", "gpio156", "gpio157", "gpio158",
+ "gpio159", "gpio160", "gpio161", "gpio162", "gpio163", "gpio164",
+ "gpio165", "gpio166", "gpio167", "gpio168", "gpio169", "gpio170",
+ "gpio171", "gpio172", "gpio173", "gpio174",
+};
+
+static const char * const qup6_groups[] = {
+ "gpio4", "gpio5", "gpio6", "gpio7",
+};
+
+static const char * const qup_l6_groups[] = {
+ "gpio6", "gpio34", "gpio97", "gpio123",
+};
+
+static const char * const qup_l5_groups[] = {
+ "gpio7", "gpio33", "gpio82", "gpio96",
+};
+
+static const char * const mdp_vsync_groups[] = {
+ "gpio8", "gpio9", "gpio10", "gpio81", "gpio82",
+};
+
+static const char * const edp_lcd_groups[] = {
+ "gpio9",
+};
+
+static const char * const qup10_groups[] = {
+ "gpio9", "gpio10", "gpio11", "gpio12",
+};
+
+static const char * const m_voc_groups[] = {
+ "gpio10",
+};
+
+static const char * const edp_hot_groups[] = {
+ "gpio10",
+};
+
+static const char * const cam_mclk_groups[] = {
+ "gpio13", "gpio14", "gpio15", "gpio16",
+};
+
+static const char * const qdss_groups[] = {
+ "gpio13", "gpio14", "gpio15", "gpio16", "gpio17",
+ "gpio18", "gpio19", "gpio20", "gpio21", "gpio22",
+ "gpio23", "gpio24", "gpio25", "gpio26", "gpio27",
+ "gpio28", "gpio29", "gpio30", "gpio31", "gpio32",
+ "gpio33", "gpio39", "gpio40", "gpio41", "gpio42",
+ "gpio47", "gpio48", "gpio83", "gpio117", "gpio118",
+ "gpio119", "gpio120", "gpio121", "gpio132",
+ "gpio133", "gpio134",
+};
+
+static const char * const cci_i2c_groups[] = {
+ "gpio17", "gpio18", "gpio19", "gpio20", "gpio31", "gpio32", "gpio33",
+ "gpio34",
+};
+
+static const char * const cci_timer0_groups[] = {
+ "gpio21",
+};
+
+static const char * const gcc_gp2_groups[] = {
+ "gpio21", "gpio137",
+};
+
+static const char * const cci_timer1_groups[] = {
+ "gpio22",
+};
+
+static const char * const gcc_gp3_groups[] = {
+ "gpio22", "gpio138",
+};
+
+static const char * const cci_timer2_groups[] = {
+ "gpio23",
+};
+
+static const char * const qup18_groups[] = {
+ "gpio23", "gpio24", "gpio25", "gpio26",
+};
+
+static const char * const cci_timer3_groups[] = {
+ "gpio24",
+};
+
+static const char * const cci_async_groups[] = {
+ "gpio24", "gpio25", "gpio26",
+};
+
+static const char * const cci_timer4_groups[] = {
+ "gpio25",
+};
+
+static const char * const qup15_groups[] = {
+ "gpio27", "gpio28", "gpio29", "gpio30",
+};
+
+static const char * const pci_e0_groups[] = {
+ "gpio35", "gpio36",
+};
+
+static const char * const qup_l4_groups[] = {
+ "gpio37", "gpio59", "gpio81", "gpio95",
+};
+
+static const char * const agera_pll_groups[] = {
+ "gpio37",
+};
+
+static const char * const usb_phy_groups[] = {
+ "gpio38",
+};
+
+static const char * const qup9_groups[] = {
+ "gpio39", "gpio40", "gpio41", "gpio42",
+};
+
+static const char * const qup13_groups[] = {
+ "gpio43", "gpio44", "gpio45", "gpio46",
+};
+
+static const char * const qdss_cti_groups[] = {
+ "gpio45", "gpio46", "gpio49", "gpio50", "gpio56", "gpio57", "gpio58",
+ "gpio58",
+};
+
+static const char * const qup14_groups[] = {
+ "gpio47", "gpio48", "gpio49", "gpio50",
+};
+
+static const char * const qup4_groups[] = {
+ "gpio51", "gpio52", "gpio53", "gpio54",
+};
+
+static const char * const qup17_groups[] = {
+ "gpio55", "gpio56", "gpio57", "gpio58",
+};
+
+static const char * const qup19_groups[] = {
+ "gpio55", "gpio56", "gpio57", "gpio58",
+};
+
+static const char * const atest_char_groups[] = {
+ "gpio59",
+};
+
+static const char * const nav_pps_groups[] = {
+ "gpio60", "gpio60", "gpio76", "gpio76", "gpio77", "gpio77", "gpio81",
+ "gpio81", "gpio82", "gpio82",
+};
+
+static const char * const atest_usb2_groups[] = {
+ "gpio60",
+};
+
+static const char * const qlink_request_groups[] = {
+ "gpio61",
+};
+
+static const char * const qlink_enable_groups[] = {
+ "gpio62",
+};
+
+static const char * const wmss_reset_groups[] = {
+ "gpio63",
+};
+
+static const char * const atest_usb23_groups[] = {
+ "gpio63",
+};
+
+static const char * const pa_indicator_groups[] = {
+ "gpio68",
+};
+
+static const char * const mss_lte_groups[] = {
+ "gpio69", "gpio70",
+};
+
+static const struct msm_function sm8150_functions[] = {
+ FUNCTION(adsp_ext),
+ FUNCTION(agera_pll),
+ FUNCTION(aoss_cti),
+ FUNCTION(ddr_pxi2),
+ FUNCTION(atest_char),
+ FUNCTION(atest_char0),
+ FUNCTION(atest_char1),
+ FUNCTION(atest_char2),
+ FUNCTION(atest_char3),
+ FUNCTION(audio_ref),
+ FUNCTION(atest_usb1),
+ FUNCTION(atest_usb2),
+ FUNCTION(atest_usb10),
+ FUNCTION(atest_usb11),
+ FUNCTION(atest_usb12),
+ FUNCTION(atest_usb13),
+ FUNCTION(atest_usb20),
+ FUNCTION(atest_usb21),
+ FUNCTION(atest_usb22),
+ FUNCTION(atest_usb23),
+ FUNCTION(btfm_slimbus),
+ FUNCTION(cam_mclk),
+ FUNCTION(cci_async),
+ FUNCTION(cci_i2c),
+ FUNCTION(cci_timer0),
+ FUNCTION(cci_timer1),
+ FUNCTION(cci_timer2),
+ FUNCTION(cci_timer3),
+ FUNCTION(cci_timer4),
+ FUNCTION(cri_trng),
+ FUNCTION(cri_trng0),
+ FUNCTION(cri_trng1),
+ FUNCTION(dbg_out),
+ FUNCTION(ddr_bist),
+ FUNCTION(ddr_pxi0),
+ FUNCTION(ddr_pxi1),
+ FUNCTION(ddr_pxi3),
+ FUNCTION(edp_hot),
+ FUNCTION(edp_lcd),
+ FUNCTION(emac_phy),
+ FUNCTION(emac_pps),
+ FUNCTION(gcc_gp1),
+ FUNCTION(gcc_gp2),
+ FUNCTION(gcc_gp3),
+ FUNCTION(gpio),
+ FUNCTION(hs1_mi2s),
+ FUNCTION(hs2_mi2s),
+ FUNCTION(hs3_mi2s),
+ FUNCTION(jitter_bist),
+ FUNCTION(lpass_slimbus),
+ FUNCTION(mdp_vsync),
+ FUNCTION(mdp_vsync0),
+ FUNCTION(mdp_vsync1),
+ FUNCTION(mdp_vsync2),
+ FUNCTION(mdp_vsync3),
+ FUNCTION(mss_lte),
+ FUNCTION(m_voc),
+ FUNCTION(nav_pps),
+ FUNCTION(pa_indicator),
+ FUNCTION(pci_e0),
+ FUNCTION(phase_flag),
+ FUNCTION(pll_bypassnl),
+ FUNCTION(pll_bist),
+ FUNCTION(pci_e1),
+ FUNCTION(pll_reset),
+ FUNCTION(pri_mi2s),
+ FUNCTION(pri_mi2s_ws),
+ FUNCTION(prng_rosc),
+ FUNCTION(qdss),
+ FUNCTION(qdss_cti),
+ FUNCTION(qlink_request),
+ FUNCTION(qlink_enable),
+ FUNCTION(qspi0),
+ FUNCTION(qspi1),
+ FUNCTION(qspi2),
+ FUNCTION(qspi3),
+ FUNCTION(qspi_clk),
+ FUNCTION(qspi_cs),
+ FUNCTION(qua_mi2s),
+ FUNCTION(qup0),
+ FUNCTION(qup1),
+ FUNCTION(qup2),
+ FUNCTION(qup3),
+ FUNCTION(qup4),
+ FUNCTION(qup5),
+ FUNCTION(qup6),
+ FUNCTION(qup7),
+ FUNCTION(qup8),
+ FUNCTION(qup9),
+ FUNCTION(qup10),
+ FUNCTION(qup11),
+ FUNCTION(qup12),
+ FUNCTION(qup13),
+ FUNCTION(qup14),
+ FUNCTION(qup15),
+ FUNCTION(qup16),
+ FUNCTION(qup17),
+ FUNCTION(qup18),
+ FUNCTION(qup19),
+ FUNCTION(qup_l4),
+ FUNCTION(qup_l5),
+ FUNCTION(qup_l6),
+ FUNCTION(rgmii),
+ FUNCTION(sdc4),
+ FUNCTION(sd_write),
+ FUNCTION(sec_mi2s),
+ FUNCTION(spkr_i2s),
+ FUNCTION(sp_cmu),
+ FUNCTION(ter_mi2s),
+ FUNCTION(tgu_ch0),
+ FUNCTION(tgu_ch1),
+ FUNCTION(tgu_ch2),
+ FUNCTION(tgu_ch3),
+ FUNCTION(tsense_pwm1),
+ FUNCTION(tsense_pwm2),
+ FUNCTION(tsif1),
+ FUNCTION(tsif2),
+ FUNCTION(uim1),
+ FUNCTION(uim2),
+ FUNCTION(uim_batt),
+ FUNCTION(usb2phy_ac),
+ FUNCTION(usb_phy),
+ FUNCTION(vfr_1),
+ FUNCTION(vsense_trigger),
+ FUNCTION(wlan1_adc0),
+ FUNCTION(wlan1_adc1),
+ FUNCTION(wlan2_adc0),
+ FUNCTION(wlan2_adc1),
+ FUNCTION(wmss_reset),
+};
+
+/*
+ * Every pin is maintained as a single group, and missing or non-existing pin
+ * would be maintained as dummy group to synchronize pin group index with
+ * pin descriptor registered with pinctrl core.
+ * Clients would not be able to request these dummy pin groups.
+ */
+static const struct msm_pingroup sm8150_groups[] = {
+ [0] = PINGROUP(0, SOUTH, qup0, _, _, _, _, _, _, _, _),
+ [1] = PINGROUP(1, SOUTH, qup0, _, _, _, _, _, _, _, _),
+ [2] = PINGROUP(2, SOUTH, qup0, _, _, _, _, _, _, _, _),
+ [3] = PINGROUP(3, SOUTH, qup0, _, _, _, _, _, _, _, _),
+ [4] = PINGROUP(4, SOUTH, qup6, rgmii, _, _, _, _, _, _, _),
+ [5] = PINGROUP(5, SOUTH, qup6, rgmii, _, _, _, _, _, _, _),
+ [6] = PINGROUP(6, SOUTH, qup6, rgmii, qup_l6, _, _, _, _, _, _),
+ [7] = PINGROUP(7, SOUTH, qup6, rgmii, qup_l5, _, _, _, _, _, _),
+ [8] = PINGROUP(8, NORTH, mdp_vsync, _, _, _, _, _, _, _, _),
+ [9] = PINGROUP(9, NORTH, mdp_vsync, edp_lcd, qup10, _, _, _, _, _, _),
+ [10] = PINGROUP(10, NORTH, mdp_vsync, m_voc, edp_hot, qup10, _, _, _, _, _),
+ [11] = PINGROUP(11, NORTH, qup10, _, _, _, _, _, _, _, _),
+ [12] = PINGROUP(12, NORTH, qup10, _, _, _, _, _, _, _, _),
+ [13] = PINGROUP(13, NORTH, cam_mclk, qdss, _, _, _, _, _, _, _),
+ [14] = PINGROUP(14, NORTH, cam_mclk, qdss, _, _, _, _, _, _, _),
+ [15] = PINGROUP(15, NORTH, cam_mclk, qdss, _, _, _, _, _, _, _),
+ [16] = PINGROUP(16, NORTH, cam_mclk, qdss, _, _, _, _, _, _, _),
+ [17] = PINGROUP(17, NORTH, cci_i2c, qdss, _, _, _, _, _, _, _),
+ [18] = PINGROUP(18, NORTH, cci_i2c, phase_flag, _, qdss, _, _, _, _, _),
+ [19] = PINGROUP(19, NORTH, cci_i2c, phase_flag, _, qdss, _, _, _, _, _),
+ [20] = PINGROUP(20, NORTH, cci_i2c, phase_flag, _, qdss, _, _, _, _, _),
+ [21] = PINGROUP(21, EAST, cci_timer0, gcc_gp2, qdss, _, _, _, _, _, _),
+ [22] = PINGROUP(22, EAST, cci_timer1, gcc_gp3, qdss, _, _, _, _, _, _),
+ [23] = PINGROUP(23, EAST, cci_timer2, qup18, qdss, _, _, _, _, _, _),
+ [24] = PINGROUP(24, EAST, cci_timer3, cci_async, qup18, qdss, _, _, _, _, _),
+ [25] = PINGROUP(25, EAST, cci_timer4, cci_async, qup18, qdss, _, _, _, _, _),
+ [26] = PINGROUP(26, EAST, cci_async, qup18, qdss, _, _, _, _, _, _),
+ [27] = PINGROUP(27, EAST, qup15, _, qdss, _, _, _, _, _, _),
+ [28] = PINGROUP(28, EAST, qup15, qdss, _, _, _, _, _, _, _),
+ [29] = PINGROUP(29, EAST, qup15, qdss, _, _, _, _, _, _, _),
+ [30] = PINGROUP(30, EAST, qup15, qdss, _, _, _, _, _, _, _),
+ [31] = PINGROUP(31, NORTH, cci_i2c, qdss, _, _, _, _, _, _, _),
+ [32] = PINGROUP(32, NORTH, cci_i2c, qdss, _, _, _, _, _, _, _),
+ [33] = PINGROUP(33, NORTH, cci_i2c, qup_l5, qdss, _, _, _, _, _, _),
+ [34] = PINGROUP(34, NORTH, cci_i2c, qup_l6, _, _, _, _, _, _, _),
+ [35] = PINGROUP(35, NORTH, pci_e0, _, _, _, _, _, _, _, _),
+ [36] = PINGROUP(36, NORTH, pci_e0, _, _, _, _, _, _, _, _),
+ [37] = PINGROUP(37, NORTH, qup_l4, agera_pll, _, _, _, _, _, _, _),
+ [38] = PINGROUP(38, SOUTH, usb_phy, _, _, _, _, _, _, _, _),
+ [39] = PINGROUP(39, NORTH, qup9, qdss, _, _, _, _, _, _, _),
+ [40] = PINGROUP(40, NORTH, qup9, qdss, _, _, _, _, _, _, _),
+ [41] = PINGROUP(41, NORTH, qup9, qdss, _, _, _, _, _, _, _),
+ [42] = PINGROUP(42, NORTH, qup9, qdss, _, _, _, _, _, _, _),
+ [43] = PINGROUP(43, EAST, qup13, _, _, _, _, _, _, _, _),
+ [44] = PINGROUP(44, EAST, qup13, _, _, _, _, _, _, _, _),
+ [45] = PINGROUP(45, EAST, qup13, qdss_cti, _, _, _, _, _, _, _),
+ [46] = PINGROUP(46, EAST, qup13, qdss_cti, _, _, _, _, _, _, _),
+ [47] = PINGROUP(47, EAST, qup14, qdss, _, _, _, _, _, _, _),
+ [48] = PINGROUP(48, EAST, qup14, qdss, _, _, _, _, _, _, _),
+ [49] = PINGROUP(49, EAST, qup14, _, qdss_cti, _, _, _, _, _, _),
+ [50] = PINGROUP(50, EAST, qup14, qdss_cti, _, _, _, _, _, _, _),
+ [51] = PINGROUP(51, SOUTH, qup4, _, _, _, _, _, _, _, _),
+ [52] = PINGROUP(52, SOUTH, qup4, _, _, _, _, _, _, _, _),
+ [53] = PINGROUP(53, SOUTH, qup4, _, _, _, _, _, _, _, _),
+ [54] = PINGROUP(54, SOUTH, qup4, _, _, _, _, _, _, _, _),
+ [55] = PINGROUP(55, SOUTH, qup17, qup19, phase_flag, _, _, _, _, _, _),
+ [56] = PINGROUP(56, SOUTH, qup17, qup19, qdss_cti, phase_flag, _, _, _, _, _),
+ [57] = PINGROUP(57, SOUTH, qup17, qup19, qdss_cti, phase_flag, _, _, _, _, _),
+ [58] = PINGROUP(58, SOUTH, qup17, qup19, qdss_cti, phase_flag, _, _, _, _, _),
+ [59] = PINGROUP(59, SOUTH, rgmii, qup_l4, phase_flag, _, atest_char, _, _, _, _),
+ [60] = PINGROUP(60, SOUTH, _, nav_pps, nav_pps, atest_usb2, _, _, _, _, _),
+ [61] = PINGROUP(61, SOUTH, qlink_request, _, _, _, _, _, _, _, _),
+ [62] = PINGROUP(62, SOUTH, qlink_enable, _, _, _, _, _, _, _, _),
+ [63] = PINGROUP(63, SOUTH, wmss_reset, atest_usb23, _, _, _, _, _, _, _),
+ [64] = PINGROUP(64, SOUTH, _, phase_flag, _, _, _, _, _, _, _),
+ [65] = PINGROUP(65, SOUTH, _, _, _, _, _, _, _, _, _),
+ [66] = PINGROUP(66, SOUTH, _, _, _, _, _, _, _, _, _),
+ [67] = PINGROUP(67, SOUTH, _, _, _, _, _, _, _, _, _),
+ [68] = PINGROUP(68, SOUTH, _, pa_indicator, phase_flag, _, _, _, _, _, _),
+ [69] = PINGROUP(69, SOUTH, mss_lte, _, _, _, _, _, _, _, _),
+ [70] = PINGROUP(70, SOUTH, mss_lte, _, _, _, _, _, _, _, _),
+ [71] = PINGROUP(71, SOUTH, _, _, _, _, _, _, _, _, _),
+ [72] = PINGROUP(72, SOUTH, _, _, _, _, _, _, _, _, _),
+ [73] = PINGROUP(73, SOUTH, _, _, _, _, _, _, _, _, _),
+ [74] = PINGROUP(74, SOUTH, _, _, _, _, _, _, _, _, _),
+ [75] = PINGROUP(75, SOUTH, _, _, _, _, _, _, _, _, _),
+ [76] = PINGROUP(76, SOUTH, _, _, _, nav_pps, nav_pps, phase_flag, _, _, _),
+ [77] = PINGROUP(77, SOUTH, _, _, _, nav_pps, nav_pps, _, _, _, _),
+ [78] = PINGROUP(78, SOUTH, _, _, _, _, _, _, _, _, _),
+ [79] = PINGROUP(79, SOUTH, _, _, phase_flag, _, _, _, _, _, _),
+ [80] = PINGROUP(80, SOUTH, _, _, phase_flag, _, _, _, _, _, _),
+ [81] = PINGROUP(81, SOUTH, _, _, _, nav_pps, nav_pps, qup_l4, mdp_vsync, emac_pps, _),
+ [82] = PINGROUP(82, SOUTH, _, _, _, nav_pps, nav_pps, qup_l5, mdp_vsync, _, _),
+ [83] = PINGROUP(83, NORTH, qup12, qup16, _, qdss, _, _, _, _, _),
+ [84] = PINGROUP(84, NORTH, qup12, qup16, _, _, _, _, _, _, _),
+ [85] = PINGROUP(85, NORTH, qup12, qup16, _, _, _, _, _, _, _),
+ [86] = PINGROUP(86, NORTH, qup12, qup16, _, _, _, _, _, _, _),
+ [87] = PINGROUP(87, EAST, _, _, _, _, _, _, _, _, _),
+ [88] = PINGROUP(88, NORTH, tsif1, qup8, qspi_cs, tgu_ch3, _, _, _, _, _),
+ [89] = PINGROUP(89, NORTH, tsif1, qup8, qspi0, mdp_vsync0, mdp_vsync1, mdp_vsync2, mdp_vsync3, tgu_ch0, _),
+ [90] = PINGROUP(90, NORTH, tsif1, qup8, qspi1, sdc4, phase_flag, tgu_ch1, _, _, wlan1_adc1),
+ [91] = PINGROUP(91, NORTH, tsif1, qup8, qspi2, sdc4, vfr_1, phase_flag, tgu_ch2, _, _),
+ [92] = PINGROUP(92, NORTH, tsif2, qup11, qspi_clk, sdc4, phase_flag, _, wlan2_adc1, _, _),
+ [93] = PINGROUP(93, NORTH, tsif2, qup11, qspi3, sdc4, phase_flag, _, wlan2_adc0, _, _),
+ [94] = PINGROUP(94, NORTH, tsif2, qup11, qspi_cs, sdc4, phase_flag, _, _, _, _),
+ [95] = PINGROUP(95, NORTH, tsif2, qup11, sdc4, qup_l4, _, _, _, _, _),
+ [96] = PINGROUP(96, NORTH, tsif2, qup_l5, phase_flag, _, _, _, _, _, _),
+ [97] = PINGROUP(97, NORTH, sd_write, tsif1, qup_l6, _, _, _, _, _, _),
+ [98] = PINGROUP(98, SOUTH, qup7, ddr_bist, ddr_pxi3, _, _, _, _, _, _),
+ [99] = PINGROUP(99, SOUTH, qup7, ddr_bist, atest_usb13, ddr_pxi1, _, _, _, _, _),
+ [100] = PINGROUP(100, SOUTH, qup7, pll_bypassnl, atest_usb12, ddr_pxi1, _, _, _, _, _),
+ [101] = PINGROUP(101, SOUTH, qup7, pll_reset, ddr_pxi3, _, _, _, _, _, _),
+ [102] = PINGROUP(102, NORTH, pci_e1, _, _, _, _, _, _, _, _),
+ [103] = PINGROUP(103, NORTH, pci_e1, _, _, _, _, _, _, _, _),
+ [104] = PINGROUP(104, NORTH, _, _, _, _, _, _, _, _, _),
+ [105] = PINGROUP(105, WEST, uim2, _, _, _, _, _, _, _, _),
+ [106] = PINGROUP(106, WEST, uim2, _, _, _, _, _, _, _, _),
+ [107] = PINGROUP(107, WEST, uim2, _, _, _, _, _, _, _, _),
+ [108] = PINGROUP(108, WEST, uim2, _, _, _, _, _, _, _, _),
+ [109] = PINGROUP(109, WEST, uim1, _, _, _, _, _, _, _, _),
+ [110] = PINGROUP(110, WEST, uim1, _, _, _, _, _, _, _, _),
+ [111] = PINGROUP(111, WEST, uim1, _, _, _, _, _, _, _, _),
+ [112] = PINGROUP(112, WEST, uim1, _, _, _, _, _, _, _, _),
+ [113] = PINGROUP(113, WEST, uim_batt, usb2phy_ac, aoss_cti, _, _, _, _, _, _),
+ [114] = PINGROUP(114, SOUTH, qup1, rgmii, phase_flag, _, _, _, _, _, _),
+ [115] = PINGROUP(115, SOUTH, qup1, rgmii, phase_flag, adsp_ext, _, _, _, _, _),
+ [116] = PINGROUP(116, SOUTH, qup1, rgmii, phase_flag, _, _, _, _, _, _),
+ [117] = PINGROUP(117, SOUTH, qup1, rgmii, phase_flag, _, qdss, _, _, _, _),
+ [118] = PINGROUP(118, SOUTH, rgmii, phase_flag, _, qdss, _, _, _, _, _),
+ [119] = PINGROUP(119, SOUTH, qup5, rgmii, phase_flag, _, qdss, _, _, _, _),
+ [120] = PINGROUP(120, SOUTH, qup5, rgmii, phase_flag, _, qdss, _, _, _, _),
+ [121] = PINGROUP(121, SOUTH, qup5, rgmii, phase_flag, _, qdss, _, _, _, _),
+ [122] = PINGROUP(122, SOUTH, qup5, rgmii, phase_flag, _, _, _, _, _, _),
+ [123] = PINGROUP(123, SOUTH, usb2phy_ac, qup_l6, atest_usb22, _, _, _, _, _, _),
+ [124] = PINGROUP(124, SOUTH, emac_phy, _, _, _, _, _, _, _, _),
+ [125] = PINGROUP(125, WEST, hs3_mi2s, _, _, _, _, _, _, _, _),
+ [126] = PINGROUP(126, SOUTH, sec_mi2s, qup2, phase_flag, _, _, _, _, _, _),
+ [127] = PINGROUP(127, SOUTH, sec_mi2s, qup2, phase_flag, _, _, _, _, _, _),
+ [128] = PINGROUP(128, SOUTH, sec_mi2s, qup2, phase_flag, _, _, _, _, _, _),
+ [129] = PINGROUP(129, SOUTH, sec_mi2s, qup2, jitter_bist, atest_usb21, _, _, _, _, _),
+ [130] = PINGROUP(130, SOUTH, sec_mi2s, pll_bist, atest_usb20, atest_char0, _, _, _, _, _),
+ [131] = PINGROUP(131, SOUTH, ter_mi2s, gcc_gp1, _, _, _, _, _, _, _),
+ [132] = PINGROUP(132, SOUTH, ter_mi2s, _, qdss, _, _, _, _, _, _),
+ [133] = PINGROUP(133, SOUTH, ter_mi2s, qdss, atest_char1, _, _, _, _, _, _),
+ [134] = PINGROUP(134, SOUTH, ter_mi2s, qdss, atest_char2, _, _, _, _, _, _),
+ [135] = PINGROUP(135, SOUTH, ter_mi2s, atest_char3, _, _, _, _, _, _, _),
+ [136] = PINGROUP(136, SOUTH, qua_mi2s, gcc_gp1, _, _, _, _, _, _, _),
+ [137] = PINGROUP(137, SOUTH, qua_mi2s, gcc_gp2, _, _, _, _, _, _, _),
+ [138] = PINGROUP(138, SOUTH, qua_mi2s, gcc_gp3, _, _, _, _, _, _, _),
+ [139] = PINGROUP(139, SOUTH, qua_mi2s, _, _, _, _, _, _, _, _),
+ [140] = PINGROUP(140, SOUTH, qua_mi2s, _, _, _, _, _, _, _, _),
+ [141] = PINGROUP(141, SOUTH, qua_mi2s, _, _, _, _, _, _, _, _),
+ [142] = PINGROUP(142, SOUTH, qua_mi2s, _, _, _, _, _, _, _, _),
+ [143] = PINGROUP(143, SOUTH, pri_mi2s, _, _, _, _, _, _, _, _),
+ [144] = PINGROUP(144, SOUTH, pri_mi2s, qup3, phase_flag, _, ddr_pxi0, _, _, _, _),
+ [145] = PINGROUP(145, SOUTH, pri_mi2s_ws, qup3, phase_flag, ddr_bist, _, vsense_trigger, atest_usb1, ddr_pxi0, _),
+ [146] = PINGROUP(146, SOUTH, pri_mi2s, qup3, ddr_bist, atest_usb11, ddr_pxi2, _, _, _, _),
+ [147] = PINGROUP(147, SOUTH, pri_mi2s, qup3, dbg_out, atest_usb10, ddr_pxi2, _, _, _, _),
+ [148] = PINGROUP(148, SOUTH, spkr_i2s, audio_ref, _, _, _, _, _, _, _),
+ [149] = PINGROUP(149, SOUTH, lpass_slimbus, spkr_i2s, _, _, _, _, _, _, _),
+ [150] = PINGROUP(150, SOUTH, lpass_slimbus, spkr_i2s, tsense_pwm1, tsense_pwm2, _, _, _, _, _),
+ [151] = PINGROUP(151, SOUTH, lpass_slimbus, spkr_i2s, _, _, _, _, _, _, _),
+ [152] = PINGROUP(152, SOUTH, lpass_slimbus, spkr_i2s, _, _, _, _, _, _, _),
+ [153] = PINGROUP(153, SOUTH, btfm_slimbus, _, _, _, _, _, _, _, _),
+ [154] = PINGROUP(154, SOUTH, btfm_slimbus, _, _, _, _, _, _, _, _),
+ [155] = PINGROUP(155, WEST, hs1_mi2s, _, _, _, _, _, _, _, _),
+ [156] = PINGROUP(156, WEST, hs1_mi2s, _, _, _, _, _, _, _, _),
+ [157] = PINGROUP(157, WEST, hs1_mi2s, _, _, _, _, _, _, _, _),
+ [158] = PINGROUP(158, WEST, hs1_mi2s, _, _, _, _, _, _, _, _),
+ [159] = PINGROUP(159, WEST, hs1_mi2s, cri_trng0, _, _, _, _, _, _, _),
+ [160] = PINGROUP(160, WEST, hs2_mi2s, cri_trng1, _, _, _, _, _, _, _),
+ [161] = PINGROUP(161, WEST, hs2_mi2s, cri_trng, _, _, _, _, _, _, _),
+ [162] = PINGROUP(162, WEST, hs2_mi2s, sp_cmu, _, _, _, _, _, _, _),
+ [163] = PINGROUP(163, WEST, hs2_mi2s, prng_rosc, _, _, _, _, _, _, _),
+ [164] = PINGROUP(164, WEST, hs2_mi2s, _, _, _, _, _, _, _, _),
+ [165] = PINGROUP(165, WEST, hs3_mi2s, _, _, _, _, _, _, _, _),
+ [166] = PINGROUP(166, WEST, hs3_mi2s, _, _, _, _, _, _, _, _),
+ [167] = PINGROUP(167, WEST, hs3_mi2s, _, _, _, _, _, _, _, _),
+ [168] = PINGROUP(168, WEST, hs3_mi2s, _, _, _, _, _, _, _, _),
+ [169] = PINGROUP(169, NORTH, _, _, _, _, _, _, _, _, _),
+ [170] = PINGROUP(170, NORTH, _, _, _, _, _, _, _, _, _),
+ [171] = PINGROUP(171, NORTH, _, _, _, _, _, _, _, _, _),
+ [172] = PINGROUP(172, NORTH, _, _, _, _, _, _, _, _, _),
+ [173] = PINGROUP(173, NORTH, _, _, _, _, _, _, _, _, _),
+ [174] = PINGROUP(174, NORTH, _, _, _, _, _, _, _, _, _),
+ [175] = UFS_RESET(ufs_reset, 0xB6000),
+ [176] = SDC_QDSD_PINGROUP(sdc2_clk, 0xB2000, 14, 6),
+ [177] = SDC_QDSD_PINGROUP(sdc2_cmd, 0xB2000, 11, 3),
+ [178] = SDC_QDSD_PINGROUP(sdc2_data, 0xB2000, 9, 0),
+};
+
+static const struct msm_pinctrl_soc_data sm8150_pinctrl = {
+ .pins = sm8150_pins,
+ .npins = ARRAY_SIZE(sm8150_pins),
+ .functions = sm8150_functions,
+ .nfunctions = ARRAY_SIZE(sm8150_functions),
+ .groups = sm8150_groups,
+ .ngroups = ARRAY_SIZE(sm8150_groups),
+ .ngpios = 176,
+ .tiles = sm8150_tiles,
+ .ntiles = ARRAY_SIZE(sm8150_tiles),
+};
+
+static int sm8150_pinctrl_probe(struct platform_device *pdev)
+{
+ return msm_pinctrl_probe(pdev, &sm8150_pinctrl);
+}
+
+static const struct of_device_id sm8150_pinctrl_of_match[] = {
+ { .compatible = "qcom,sm8150-pinctrl", },
+ { },
+};
+
+static struct platform_driver sm8150_pinctrl_driver = {
+ .driver = {
+ .name = "sm8150-pinctrl",
+ .of_match_table = sm8150_pinctrl_of_match,
+ },
+ .probe = sm8150_pinctrl_probe,
+ .remove = msm_pinctrl_remove,
+};
+
+static int __init sm8150_pinctrl_init(void)
+{
+ return platform_driver_register(&sm8150_pinctrl_driver);
+}
+arch_initcall(sm8150_pinctrl_init);
+
+static void __exit sm8150_pinctrl_exit(void)
+{
+ platform_driver_unregister(&sm8150_pinctrl_driver);
+}
+module_exit(sm8150_pinctrl_exit);
+
+MODULE_DESCRIPTION("QTI sm8150 pinctrl driver");
+MODULE_LICENSE("GPL v2");
+MODULE_DEVICE_TABLE(of, sm8150_pinctrl_of_match);
--
2.20.1
^ permalink raw reply related
* [PATCH v2 2/3] dt-bindings: pinctrl: qcom: Add SM8150 pinctrl binding
From: Vinod Koul @ 2019-07-02 10:50 UTC (permalink / raw)
To: Linus Walleij
Cc: linux-arm-msm, Bjorn Andersson, Prasad Sodagudi, Andy Gross,
Rob Herring, Mark Rutland, linux-gpio, devicetree, linux-kernel,
Isaac J . Manjarres, Vinod Koul
In-Reply-To: <20190702105045.27646-1-vkoul@kernel.org>
From: Prasad Sodagudi <psodagud@codeaurora.org>
Add the binding for the TLMM pinctrl block found in the SM8150 platform.
Signed-off-by: Prasad Sodagudi <psodagud@codeaurora.org>
Signed-off-by: Isaac J. Manjarres <isaacm@codeaurora.org>
[vkoul: add missing nodes of gpio range and reserved
rewrote function names and order them]
Signed-off-by: Vinod Koul <vkoul@kernel.org>
---
.../bindings/pinctrl/qcom,sm8150-pinctrl.txt | 190 ++++++++++++++++++
1 file changed, 190 insertions(+)
create mode 100644 Documentation/devicetree/bindings/pinctrl/qcom,sm8150-pinctrl.txt
diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sm8150-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/qcom,sm8150-pinctrl.txt
new file mode 100644
index 000000000000..fa37733e5102
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/qcom,sm8150-pinctrl.txt
@@ -0,0 +1,190 @@
+Qualcomm SM8150 TLMM block
+
+This binding describes the Top Level Mode Multiplexer block found in the
+QCS404 platform.
+
+- compatible:
+ Usage: required
+ Value type: <string>
+ Definition: must be "qcom,sm8150-pinctrl"
+
+- reg:
+ Usage: required
+ Value type: <prop-encoded-array>
+ Definition: the base address and size of the north, south, west
+ and east TLMM tiles.
+
+- reg-names:
+ Usage: required
+ Value type: <prop-encoded-array>
+ Defintiion: names for the cells of reg, must contain "north", "south"
+ "west" and "east".
+
+- interrupts:
+ Usage: required
+ Value type: <prop-encoded-array>
+ Definition: should specify the TLMM summary IRQ.
+
+- interrupt-controller:
+ Usage: required
+ Value type: <none>
+ Definition: identifies this node as an interrupt controller
+
+- #interrupt-cells:
+ Usage: required
+ Value type: <u32>
+ Definition: must be 2. Specifying the pin number and flags, as defined
+ in <dt-bindings/interrupt-controller/irq.h>
+
+- gpio-controller:
+ Usage: required
+ Value type: <none>
+ Definition: identifies this node as a gpio controller
+
+- #gpio-cells:
+ Usage: required
+ Value type: <u32>
+ Definition: must be 2. Specifying the pin number and flags, as defined
+ in <dt-bindings/gpio/gpio.h>
+
+- gpio-ranges:
+ Usage: required
+ Value type: <prop-encoded-array>
+ Definition: see ../gpio/gpio.txt
+
+- gpio-reserved-ranges:
+ Usage: optional
+ Value type: <prop-encoded-array>
+ Definition: see ../gpio/gpio.txt
+
+Please refer to ../gpio/gpio.txt and ../interrupt-controller/interrupts.txt for
+a general description of GPIO and interrupt bindings.
+
+Please refer to pinctrl-bindings.txt in this directory for details of the
+common pinctrl bindings used by client devices, including the meaning of the
+phrase "pin configuration node".
+
+The pin configuration nodes act as a container for an arbitrary number of
+subnodes. Each of these subnodes represents some desired configuration for a
+pin, a group, or a list of pins or groups. This configuration can include the
+mux function to select on those pin(s)/group(s), and various pin configuration
+parameters, such as pull-up, drive strength, etc.
+
+
+PIN CONFIGURATION NODES:
+
+The name of each subnode is not important; all subnodes should be enumerated
+and processed purely based on their content.
+
+Each subnode only affects those parameters that are explicitly listed. In
+other words, a subnode that lists a mux function but no pin configuration
+parameters implies no information about any pin configuration parameters.
+Similarly, a pin subnode that describes a pullup parameter implies no
+information about e.g. the mux function.
+
+
+The following generic properties as defined in pinctrl-bindings.txt are valid
+to specify in a pin configuration subnode:
+
+- pins:
+ Usage: required
+ Value type: <string-array>
+ Definition: List of gpio pins affected by the properties specified in
+ this subnode.
+
+ Valid pins are:
+ gpio0-gpio149
+ Supports mux, bias and drive-strength
+
+ sdc1_clk, sdc1_cmd, sdc1_data sdc2_clk, sdc2_cmd,
+ sdc2_data sdc1_rclk
+ Supports bias and drive-strength
+
+ ufs_reset
+ Supports bias and drive-strength
+
+- function:
+ Usage: required
+ Value type: <string>
+ Definition: Specify the alternative function to be configured for the
+ specified pins. Functions are only valid for gpio pins.
+ Valid values are:
+
+ adsp_ext, agera_pll, aoss_cti, ddr_pxi2, atest_char,
+ atest_char0, atest_char1, atest_char2, atest_char3,
+ audio_ref, atest_usb1, atest_usb2, atest_usb10,
+ atest_usb11, atest_usb12, atest_usb13, atest_usb20,
+ atest_usb21, atest_usb22, atest_usb2, atest_usb23,
+ btfm_slimbus, cam_mclk, cci_async, cci_i2c, cci_timer0,
+ cci_timer1, cci_timer2, cci_timer3, cci_timer4,
+ cri_trng, cri_trng0, cri_trng1, dbg_out, ddr_bist,
+ ddr_pxi0, ddr_pxi1, ddr_pxi3, edp_hot, edp_lcd,
+ emac_phy, emac_pps, gcc_gp1, gcc_gp2, gcc_gp3, gpio,
+ hs1_mi2s, hs2_mi2s, hs3_mi2s, jitter_bist,
+ lpass_slimbus, mdp_vsync, mdp_vsync0, mdp_vsync1,
+ mdp_vsync2, mdp_vsync3, mss_lte, m_voc, nav_pps,
+ pa_indicator, pci_e0, phase_flag, pll_bypassnl,
+ pll_bist, pci_e1, pll_reset, pri_mi2s, pri_mi2s_ws,
+ prng_rosc, qdss, qdss_cti, qlink_request, qlink_enable,
+ qspi0, qspi1, qspi2, qspi3, qspi_clk, qspi_cs, qua_mi2s,
+ qup0, qup1, qup2, qup3, qup4, qup5, qup6, qup7, qup8,
+ qup9, qup10, qup11, qup12, qup13, qup14, qup15, qup16,
+ qup17, qup18, qup19, qup_l4, qup_l5, qup_l6, rgmii,
+ sdc4, sd_write, sec_mi2s, spkr_i2s, sp_cmu, ter_mi2s,
+ tgu_ch0, tgu_ch1, tgu_ch2, tgu_ch3, tsense_pwm1,
+ tsense_pwm2, tsif1, tsif2, uim1, uim2, uim_batt,
+ usb2phy_ac, usb_phy, vfr_1, vsense_trigger, wlan1_adc0,
+ wlan1_adc1, wlan2_adc0, wlan2_adc1, wmss_reset
+
+- bias-disable:
+ Usage: optional
+ Value type: <none>
+ Definition: The specified pins should be configued as no pull.
+
+- bias-pull-down:
+ Usage: optional
+ Value type: <none>
+ Definition: The specified pins should be configued as pull down.
+
+- bias-pull-up:
+ Usage: optional
+ Value type: <none>
+ Definition: The specified pins should be configued as pull up.
+
+- output-high:
+ Usage: optional
+ Value type: <none>
+ Definition: The specified pins are configured in output mode, driven
+ high.
+ Not valid for sdc pins.
+
+- output-low:
+ Usage: optional
+ Value type: <none>
+ Definition: The specified pins are configured in output mode, driven
+ low.
+ Not valid for sdc pins.
+
+- drive-strength:
+ Usage: optional
+ Value type: <u32>
+ Definition: Selects the drive strength for the specified pins, in mA.
+ Valid values are: 2, 4, 6, 8, 10, 12, 14 and 16
+
+Example:
+
+ tlmm: pinctrl@3000000 {
+ compatible = "qcom,sm8150-pinctrl";
+ reg = <0x03100000 0x300000>,
+ <0x03500000 0x300000>,
+ <0x03900000 0x300000>,
+ <0x03D00000 0x300000>;
+ reg-names = "west", "east", "north", "south";
+ interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&tlmm 0 0 175>;
+ gpio-reserved-ranges = <0 4>, <126 4>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
--
2.20.1
^ permalink raw reply related
* [PATCH v2 1/3] dt-bindings: pinctrl: qcom: Document missing gpio nodes
From: Vinod Koul @ 2019-07-02 10:50 UTC (permalink / raw)
To: Linus Walleij
Cc: linux-arm-msm, Bjorn Andersson, Vinod Koul, Andy Gross,
Rob Herring, Mark Rutland, linux-gpio, devicetree, linux-kernel
In-Reply-To: <20190702105045.27646-1-vkoul@kernel.org>
The bindings for msm8998-pinctrl was missing gpio-ranges and
gpio-reserved-ranges, so document them as well
Signed-off-by: Vinod Koul <vkoul@kernel.org>
---
.../bindings/pinctrl/qcom,msm8998-pinctrl.txt | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,msm8998-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/qcom,msm8998-pinctrl.txt
index e70c79bbbc5b..280af41eb86e 100644
--- a/Documentation/devicetree/bindings/pinctrl/qcom,msm8998-pinctrl.txt
+++ b/Documentation/devicetree/bindings/pinctrl/qcom,msm8998-pinctrl.txt
@@ -40,6 +40,14 @@ MSM8998 platform.
Definition: must be 2. Specifying the pin number and flags, as defined
in <dt-bindings/gpio/gpio.h>
+- gpio-ranges:
+ Usage: required
+ Definition: see ../gpio/gpio.txt
+
+- gpio-reserved-ranges:
+ Usage: optional
+ Definition: see ../gpio/gpio.txt
+
Please refer to ../gpio/gpio.txt and ../interrupt-controller/interrupts.txt for
a general description of GPIO and interrupt bindings.
@@ -175,6 +183,8 @@ Example:
interrupts = <0 208 0>;
gpio-controller;
#gpio-cells = <2>;
+ gpio-ranges = <&tlmm 0 0 175>;
+ gpio-reserved-ranges = <0 4>, <81 4>;
interrupt-controller;
#interrupt-cells = <2>;
--
2.20.1
^ permalink raw reply related
* [PATCH v2 0/3] ipinctrl: qcom: Add support for SM8150
From: Vinod Koul @ 2019-07-02 10:50 UTC (permalink / raw)
To: Linus Walleij
Cc: linux-arm-msm, Bjorn Andersson, Vinod Koul, Andy Gross,
Rob Herring, Mark Rutland, linux-gpio, devicetree, linux-kernel
This series adds binding and driver for SM8150 pinctrl block. Also fixes one
binding missing gpio node for msm8998.
Changes since v2:
- Order the function names and squash functions
- document gpio-ranges and gpio-reserved-ranges
- change ufs reset to be after gpios
- fix pin58 having qdss_cti twice
- remove .owner
- Add one patch for missing gpio nodes
Prasad Sodagudi (2):
dt-bindings: pinctrl: qcom: Add SM8150 pinctrl binding
pinctrl: qcom: Add SM8150 pinctrl driver
Vinod Koul (1):
dt-bindings: pinctrl: qcom: Document missing gpio nodes
.../bindings/pinctrl/qcom,msm8998-pinctrl.txt | 10 +
.../bindings/pinctrl/qcom,sm8150-pinctrl.txt | 190 ++
drivers/pinctrl/qcom/Kconfig | 9 +
drivers/pinctrl/qcom/Makefile | 1 +
drivers/pinctrl/qcom/pinctrl-sm8150.c | 1548 +++++++++++++++++
5 files changed, 1758 insertions(+)
create mode 100644 Documentation/devicetree/bindings/pinctrl/qcom,sm8150-pinctrl.txt
create mode 100644 drivers/pinctrl/qcom/pinctrl-sm8150.c
--
2.20.1
^ permalink raw reply
* [PATCH] Revert "spi: gpio: Don't request CS GPIO in DT use-case"
From: Linus Walleij @ 2019-07-01 17:25 UTC (permalink / raw)
To: Mark Brown, linux-spi; +Cc: linux-gpio, Linus Walleij, Andrey Smirnov
This reverts commit 249e2632dcd0509b8f8f296f5aabf4d48dfd6da8.
After this commit drivers/net/dsa/vitesse-vsc73xx.c stopped
working. Apparently CS is not working because the reads
from the device is just returning just 1:s or just 0:s at
all bisection points, so it is a complete regression and
I think spi-gpio CS is essentially broken.
The revert had to be hand-crafted to preserve all the other
cleanup and changes to this driver, but now it works.
I'm sad to revert the change because it is a nice cleanup
but with the short time before v5.2 is released this is
probably the best idea, so we can figure out the right way
to do this in the next kernel cycle.
Fixes: 249e2632dcd0 ("spi: gpio: Don't request CS GPIO in DT use-case")
Cc: Andrey Smirnov <andrew.smirnov@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
drivers/spi/spi-gpio.c | 137 +++++++++++++++++++++++------------------
1 file changed, 78 insertions(+), 59 deletions(-)
diff --git a/drivers/spi/spi-gpio.c b/drivers/spi/spi-gpio.c
index eca9d52ecf65..7cf800efef93 100644
--- a/drivers/spi/spi-gpio.c
+++ b/drivers/spi/spi-gpio.c
@@ -36,6 +36,7 @@ struct spi_gpio {
struct gpio_desc *miso;
struct gpio_desc *mosi;
struct gpio_desc **cs_gpios;
+ bool has_cs;
};
/*----------------------------------------------------------------------*/
@@ -205,7 +206,7 @@ static void spi_gpio_chipselect(struct spi_device *spi, int is_active)
gpiod_set_value_cansleep(spi_gpio->sck, spi->mode & SPI_CPOL);
/* Drive chip select line, if we have one */
- if (spi_gpio->cs_gpios) {
+ if (spi_gpio->has_cs) {
struct gpio_desc *cs = spi_gpio->cs_gpios[spi->chip_select];
/* SPI chip selects are normally active-low */
@@ -223,12 +224,10 @@ static int spi_gpio_setup(struct spi_device *spi)
* The CS GPIOs have already been
* initialized from the descriptor lookup.
*/
- if (spi_gpio->cs_gpios) {
- cs = spi_gpio->cs_gpios[spi->chip_select];
- if (!spi->controller_state && cs)
- status = gpiod_direction_output(cs,
- !(spi->mode & SPI_CS_HIGH));
- }
+ cs = spi_gpio->cs_gpios[spi->chip_select];
+ if (!spi->controller_state && cs)
+ status = gpiod_direction_output(cs,
+ !(spi->mode & SPI_CS_HIGH));
if (!status)
status = spi_bitbang_setup(spi);
@@ -279,8 +278,12 @@ static void spi_gpio_cleanup(struct spi_device *spi)
* floating signals. (A weak pulldown would save power too, but many
* drivers expect to see all-ones data as the no slave "response".)
*/
-static int spi_gpio_request(struct device *dev, struct spi_gpio *spi_gpio)
+static int spi_gpio_request(struct device *dev,
+ struct spi_gpio *spi_gpio,
+ unsigned int num_chipselects)
{
+ int i;
+
spi_gpio->mosi = devm_gpiod_get_optional(dev, "mosi", GPIOD_OUT_LOW);
if (IS_ERR(spi_gpio->mosi))
return PTR_ERR(spi_gpio->mosi);
@@ -293,6 +296,13 @@ static int spi_gpio_request(struct device *dev, struct spi_gpio *spi_gpio)
if (IS_ERR(spi_gpio->sck))
return PTR_ERR(spi_gpio->sck);
+ for (i = 0; i < num_chipselects; i++) {
+ spi_gpio->cs_gpios[i] = devm_gpiod_get_index(dev, "cs",
+ i, GPIOD_OUT_HIGH);
+ if (IS_ERR(spi_gpio->cs_gpios[i]))
+ return PTR_ERR(spi_gpio->cs_gpios[i]);
+ }
+
return 0;
}
@@ -303,55 +313,44 @@ static const struct of_device_id spi_gpio_dt_ids[] = {
};
MODULE_DEVICE_TABLE(of, spi_gpio_dt_ids);
-static int spi_gpio_probe_dt(struct platform_device *pdev,
- struct spi_master *master)
+static int spi_gpio_probe_dt(struct platform_device *pdev)
{
- master->dev.of_node = pdev->dev.of_node;
- master->use_gpio_descriptors = true;
-
- return 0;
-}
-#else
-static inline int spi_gpio_probe_dt(struct platform_device *pdev,
- struct spi_master *master)
-{
- return 0;
-}
-#endif
-
-static int spi_gpio_probe_pdata(struct platform_device *pdev,
- struct spi_master *master)
-{
- struct device *dev = &pdev->dev;
- struct spi_gpio_platform_data *pdata = dev_get_platdata(dev);
- struct spi_gpio *spi_gpio = spi_master_get_devdata(master);
- int i;
+ int ret;
+ u32 tmp;
+ struct spi_gpio_platform_data *pdata;
+ struct device_node *np = pdev->dev.of_node;
+ const struct of_device_id *of_id =
+ of_match_device(spi_gpio_dt_ids, &pdev->dev);
-#ifdef GENERIC_BITBANG
- if (!pdata || !pdata->num_chipselect)
- return -ENODEV;
-#endif
- /*
- * The master needs to think there is a chipselect even if not
- * connected
- */
- master->num_chipselect = pdata->num_chipselect ?: 1;
+ if (!of_id)
+ return 0;
- spi_gpio->cs_gpios = devm_kcalloc(dev, master->num_chipselect,
- sizeof(*spi_gpio->cs_gpios),
- GFP_KERNEL);
- if (!spi_gpio->cs_gpios)
+ pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata)
return -ENOMEM;
- for (i = 0; i < master->num_chipselect; i++) {
- spi_gpio->cs_gpios[i] = devm_gpiod_get_index(dev, "cs", i,
- GPIOD_OUT_HIGH);
- if (IS_ERR(spi_gpio->cs_gpios[i]))
- return PTR_ERR(spi_gpio->cs_gpios[i]);
+
+ ret = of_property_read_u32(np, "num-chipselects", &tmp);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "num-chipselects property not found\n");
+ goto error_free;
}
+ pdata->num_chipselect = tmp;
+ pdev->dev.platform_data = pdata;
+
+ return 1;
+
+error_free:
+ devm_kfree(&pdev->dev, pdata);
+ return ret;
+}
+#else
+static inline int spi_gpio_probe_dt(struct platform_device *pdev)
+{
return 0;
}
+#endif
static void spi_gpio_put(void *data)
{
@@ -363,11 +362,22 @@ static int spi_gpio_probe(struct platform_device *pdev)
int status;
struct spi_master *master;
struct spi_gpio *spi_gpio;
+ struct spi_gpio_platform_data *pdata;
struct device *dev = &pdev->dev;
struct spi_bitbang *bb;
- const struct of_device_id *of_id;
+ bool use_of = 0;
- of_id = of_match_device(spi_gpio_dt_ids, &pdev->dev);
+ status = spi_gpio_probe_dt(pdev);
+ if (status < 0)
+ return status;
+ if (status > 0)
+ use_of = 1;
+
+ pdata = dev_get_platdata(dev);
+#ifdef GENERIC_BITBANG
+ if (!pdata || (!use_of && !pdata->num_chipselect))
+ return -ENODEV;
+#endif
master = spi_alloc_master(dev, sizeof(*spi_gpio));
if (!master)
@@ -377,17 +387,22 @@ static int spi_gpio_probe(struct platform_device *pdev)
if (status)
return status;
- if (of_id)
- status = spi_gpio_probe_dt(pdev, master);
- else
- status = spi_gpio_probe_pdata(pdev, master);
+ spi_gpio = spi_master_get_devdata(master);
- if (status)
- return status;
+ spi_gpio->cs_gpios = devm_kcalloc(dev,
+ pdata->num_chipselect,
+ sizeof(*spi_gpio->cs_gpios),
+ GFP_KERNEL);
+ if (!spi_gpio->cs_gpios)
+ return -ENOMEM;
- spi_gpio = spi_master_get_devdata(master);
+ platform_set_drvdata(pdev, spi_gpio);
+
+ /* Determine if we have chip selects connected */
+ spi_gpio->has_cs = !!pdata->num_chipselect;
- status = spi_gpio_request(dev, spi_gpio);
+ status = spi_gpio_request(dev, spi_gpio,
+ pdata->num_chipselect);
if (status)
return status;
@@ -405,9 +420,13 @@ static int spi_gpio_probe(struct platform_device *pdev)
}
master->bus_num = pdev->id;
+ /* The master needs to think there is a chipselect even if not connected */
+ master->num_chipselect = spi_gpio->has_cs ? pdata->num_chipselect : 1;
master->setup = spi_gpio_setup;
master->cleanup = spi_gpio_cleanup;
-
+#ifdef CONFIG_OF
+ master->dev.of_node = dev->of_node;
+#endif
bb = &spi_gpio->bitbang;
bb->master = master;
bb->chipselect = spi_gpio_chipselect;
--
2.21.0
^ permalink raw reply related
* [PATCH] gpiolib: Clarify use of non-sleeping functions
From: Geert Uytterhoeven @ 2019-07-01 14:28 UTC (permalink / raw)
To: Linus Walleij, Bartosz Golaszewski
Cc: linux-gpio, linux-kernel, Geert Uytterhoeven
Obviously functions that are safe to be called from atomic contexts, can
be called from non-atomic contexts, too.
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
Do I need more coffee?
---
drivers/gpio/gpiolib.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index a3fb9302e94eb310..906c9763b08511d8 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -3031,7 +3031,7 @@ int gpiod_get_array_value_complex(bool raw, bool can_sleep,
* Return the GPIO's raw value, i.e. the value of the physical line disregarding
* its ACTIVE_LOW status, or negative errno on failure.
*
- * This function should be called from contexts where we cannot sleep, and will
+ * This function can be called from contexts where we cannot sleep, and will
* complain if the GPIO chip functions potentially sleep.
*/
int gpiod_get_raw_value(const struct gpio_desc *desc)
@@ -3050,7 +3050,7 @@ EXPORT_SYMBOL_GPL(gpiod_get_raw_value);
* Return the GPIO's logical value, i.e. taking the ACTIVE_LOW status into
* account, or negative errno on failure.
*
- * This function should be called from contexts where we cannot sleep, and will
+ * This function can be called from contexts where we cannot sleep, and will
* complain if the GPIO chip functions potentially sleep.
*/
int gpiod_get_value(const struct gpio_desc *desc)
@@ -3083,7 +3083,7 @@ EXPORT_SYMBOL_GPL(gpiod_get_value);
* without regard for their ACTIVE_LOW status. Return 0 in case of success,
* else an error code.
*
- * This function should be called from contexts where we cannot sleep,
+ * This function can be called from contexts where we cannot sleep,
* and it will complain if the GPIO chip functions potentially sleep.
*/
int gpiod_get_raw_array_value(unsigned int array_size,
@@ -3109,7 +3109,7 @@ EXPORT_SYMBOL_GPL(gpiod_get_raw_array_value);
* Read the logical values of the GPIOs, i.e. taking their ACTIVE_LOW status
* into account. Return 0 in case of success, else an error code.
*
- * This function should be called from contexts where we cannot sleep,
+ * This function can be called from contexts where we cannot sleep,
* and it will complain if the GPIO chip functions potentially sleep.
*/
int gpiod_get_array_value(unsigned int array_size,
@@ -3323,7 +3323,7 @@ int gpiod_set_array_value_complex(bool raw, bool can_sleep,
* Set the raw value of the GPIO, i.e. the value of its physical line without
* regard for its ACTIVE_LOW status.
*
- * This function should be called from contexts where we cannot sleep, and will
+ * This function can be called from contexts where we cannot sleep, and will
* complain if the GPIO chip functions potentially sleep.
*/
void gpiod_set_raw_value(struct gpio_desc *desc, int value)
@@ -3364,7 +3364,7 @@ static void gpiod_set_value_nocheck(struct gpio_desc *desc, int value)
* Set the logical value of the GPIO, i.e. taking its ACTIVE_LOW,
* OPEN_DRAIN and OPEN_SOURCE flags into account.
*
- * This function should be called from contexts where we cannot sleep, and will
+ * This function can be called from contexts where we cannot sleep, and will
* complain if the GPIO chip functions potentially sleep.
*/
void gpiod_set_value(struct gpio_desc *desc, int value)
@@ -3386,7 +3386,7 @@ EXPORT_SYMBOL_GPL(gpiod_set_value);
* Set the raw values of the GPIOs, i.e. the values of the physical lines
* without regard for their ACTIVE_LOW status.
*
- * This function should be called from contexts where we cannot sleep, and will
+ * This function can be called from contexts where we cannot sleep, and will
* complain if the GPIO chip functions potentially sleep.
*/
int gpiod_set_raw_array_value(unsigned int array_size,
@@ -3411,7 +3411,7 @@ EXPORT_SYMBOL_GPL(gpiod_set_raw_array_value);
* Set the logical values of the GPIOs, i.e. taking their ACTIVE_LOW status
* into account.
*
- * This function should be called from contexts where we cannot sleep, and will
+ * This function can be called from contexts where we cannot sleep, and will
* complain if the GPIO chip functions potentially sleep.
*/
int gpiod_set_array_value(unsigned int array_size,
--
2.17.1
^ permalink raw reply related
* [PATCH] gpiolib: Fix references to gpiod_[gs]et_*value_cansleep() variants
From: Geert Uytterhoeven @ 2019-07-01 14:27 UTC (permalink / raw)
To: Linus Walleij, Bartosz Golaszewski
Cc: linux-gpio, linux-kernel, Geert Uytterhoeven
Commit 372e722ea4dd4ca1 ("gpiolib: use descriptors internally") renamed
the functions to use a "gpiod" prefix, and commit 79a9becda8940deb
("gpiolib: export descriptor-based GPIO interface") introduced the "raw"
variants, but both changes forgot to update the comments.
Readd a similar reference to gpiod_set_value(), which was accidentally
removed by commit 1e77fc82110ac36f ("gpio: Add missing open drain/source
handling to gpiod_set_value_cansleep()").
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
drivers/gpio/gpiolib.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 71cd685ed6c462b4..a3fb9302e94eb310 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -3037,7 +3037,7 @@ int gpiod_get_array_value_complex(bool raw, bool can_sleep,
int gpiod_get_raw_value(const struct gpio_desc *desc)
{
VALIDATE_DESC(desc);
- /* Should be using gpio_get_value_cansleep() */
+ /* Should be using gpiod_get_raw_value_cansleep() */
WARN_ON(desc->gdev->chip->can_sleep);
return gpiod_get_raw_value_commit(desc);
}
@@ -3058,7 +3058,7 @@ int gpiod_get_value(const struct gpio_desc *desc)
int value;
VALIDATE_DESC(desc);
- /* Should be using gpio_get_value_cansleep() */
+ /* Should be using gpiod_get_value_cansleep() */
WARN_ON(desc->gdev->chip->can_sleep);
value = gpiod_get_raw_value_commit(desc);
@@ -3329,7 +3329,7 @@ int gpiod_set_array_value_complex(bool raw, bool can_sleep,
void gpiod_set_raw_value(struct gpio_desc *desc, int value)
{
VALIDATE_DESC_VOID(desc);
- /* Should be using gpiod_set_value_cansleep() */
+ /* Should be using gpiod_set_raw_value_cansleep() */
WARN_ON(desc->gdev->chip->can_sleep);
gpiod_set_raw_value_commit(desc, value);
}
@@ -3370,6 +3370,7 @@ static void gpiod_set_value_nocheck(struct gpio_desc *desc, int value)
void gpiod_set_value(struct gpio_desc *desc, int value)
{
VALIDATE_DESC_VOID(desc);
+ /* Should be using gpiod_set_value_cansleep() */
WARN_ON(desc->gdev->chip->can_sleep);
gpiod_set_value_nocheck(desc, value);
}
--
2.17.1
^ permalink raw reply related
* [PATCH] gpiolib: Document new gpio_chip.init_valid_mask field
From: Geert Uytterhoeven @ 2019-07-01 14:26 UTC (permalink / raw)
To: Linus Walleij, Bartosz Golaszewski
Cc: Ricardo Ribalda Delgado, linux-gpio, linux-kernel,
Geert Uytterhoeven
A new field init_valid_mask was added to struct gpio_chip, but it was
not documented.
Fixes: f8ec92a9f63b3b11 ("gpiolib: Add init_valid_mask exported function")
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
include/linux/gpio/driver.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h
index 02698c0f34eaef16..269a4433f70cf6d8 100644
--- a/include/linux/gpio/driver.h
+++ b/include/linux/gpio/driver.h
@@ -194,6 +194,8 @@ struct gpio_irq_chip {
* @dbg_show: optional routine to show contents in debugfs; default code
* will be used when this is omitted, but custom code can show extra
* state (such as pullup/pulldown configuration).
+ * @init_valid_mask: optional routine to initialize @valid_mask, to be used if
+ * not all GPIOs are valid.
* @base: identifies the first GPIO number handled by this chip;
* or, if negative during registration, requests dynamic ID allocation.
* DEPRECATION: providing anything non-negative and nailing the base
--
2.17.1
^ permalink raw reply related
* [PATCH] Documentation: gpio: Fix reference to gpiod_get_array()
From: Geert Uytterhoeven @ 2019-07-01 14:10 UTC (permalink / raw)
To: Linus Walleij, Bartosz Golaszewski, Jonathan Corbet
Cc: Janusz Krzysztofik, linux-gpio, linux-doc, linux-kernel,
Geert Uytterhoeven
The function is called gpiod_get_array(), not gpiod_array_get().
Fixes: 77588c14ac868cae ("gpiolib: Pass array info to get/set array functions")
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
Documentation/driver-api/gpio/consumer.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Documentation/driver-api/gpio/consumer.rst b/Documentation/driver-api/gpio/consumer.rst
index 23d68c321c5c7c7d..9559aa3cbcef25a2 100644
--- a/Documentation/driver-api/gpio/consumer.rst
+++ b/Documentation/driver-api/gpio/consumer.rst
@@ -364,7 +364,7 @@ accessed sequentially.
The functions take three arguments:
* array_size - the number of array elements
* desc_array - an array of GPIO descriptors
- * array_info - optional information obtained from gpiod_array_get()
+ * array_info - optional information obtained from gpiod_get_array()
* value_bitmap - a bitmap to store the GPIOs' values (get) or
a bitmap of values to assign to the GPIOs (set)
--
2.17.1
^ permalink raw reply related
* [RFC/RFT v3 01/14] pinctrl: meson-g12a: add pwm_a on GPIOE_2 pinmux
From: Neil Armstrong @ 2019-07-01 9:12 UTC (permalink / raw)
To: jbrunet, khilman
Cc: linux-arm-kernel, linux-amlogic, linux-kernel, linux-clk,
martin.blumenstingl, linux-gpio, Neil Armstrong
In-Reply-To: <20190701091258.3870-1-narmstrong@baylibre.com>
Add the missing pinmux for the pwm_a function on the GPIOE_2 pin.
Reviewed-by: Kevin Hilman <khilman@baylibre.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
drivers/pinctrl/meson/pinctrl-meson-g12a.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/pinctrl/meson/pinctrl-meson-g12a.c b/drivers/pinctrl/meson/pinctrl-meson-g12a.c
index d494492e98e9..f69af4fa7cf8 100644
--- a/drivers/pinctrl/meson/pinctrl-meson-g12a.c
+++ b/drivers/pinctrl/meson/pinctrl-meson-g12a.c
@@ -801,6 +801,9 @@ static const unsigned int remote_ao_input_pins[] = { GPIOAO_5 };
/* ir_out */
static const unsigned int remote_ao_out_pins[] = { GPIOAO_4 };
+/* pwm_a_e */
+static const unsigned int pwm_a_e_pins[] = { GPIOE_2 };
+
/* pwm_ao_a */
static const unsigned int pwm_ao_a_pins[] = { GPIOAO_11 };
static const unsigned int pwm_ao_a_hiz_pins[] = { GPIOAO_11 };
@@ -888,6 +891,7 @@ static struct meson_pmx_group meson_g12a_aobus_groups[] = {
GROUP(i2c_ao_slave_sda, 3),
GROUP(remote_ao_input, 1),
GROUP(remote_ao_out, 1),
+ GROUP(pwm_a_e, 3),
GROUP(pwm_ao_a, 3),
GROUP(pwm_ao_a_hiz, 2),
GROUP(pwm_ao_b, 3),
@@ -1192,6 +1196,10 @@ static const char * const remote_ao_out_groups[] = {
"remote_ao_out",
};
+static const char * const pwm_a_e_groups[] = {
+ "pwm_a_e",
+};
+
static const char * const pwm_ao_a_groups[] = {
"pwm_ao_a", "pwm_ao_a_hiz",
};
@@ -1290,6 +1298,7 @@ static struct meson_pmx_func meson_g12a_aobus_functions[] = {
FUNCTION(i2c_ao_slave),
FUNCTION(remote_ao_input),
FUNCTION(remote_ao_out),
+ FUNCTION(pwm_a_e),
FUNCTION(pwm_ao_a),
FUNCTION(pwm_ao_b),
FUNCTION(pwm_ao_c),
--
2.21.0
^ permalink raw reply related
* [RFC/RFT v3 02/14] clk: core: introduce clk_hw_set_parent()
From: Neil Armstrong @ 2019-07-01 9:12 UTC (permalink / raw)
To: jbrunet, khilman
Cc: linux-arm-kernel, linux-amlogic, linux-kernel, linux-clk,
martin.blumenstingl, linux-gpio, Neil Armstrong
In-Reply-To: <20190701091258.3870-1-narmstrong@baylibre.com>
Introduce the clk_hw_set_parent() provider call to change parent of
a clock by using the clk_hw pointers.
This eases the clock reparenting from clock rate notifiers and
implementing DVFS with simpler code avoiding the boilerplates
functions as __clk_lookup(clk_hw_get_name()) then clk_set_parent().
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
drivers/clk/clk.c | 6 ++++++
include/linux/clk-provider.h | 1 +
2 files changed, 7 insertions(+)
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index aa51756fd4d6..06e1abe3391c 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -2490,6 +2490,12 @@ static int clk_core_set_parent_nolock(struct clk_core *core,
return ret;
}
+int clk_hw_set_parent(struct clk_hw *hw, struct clk_hw *parent)
+{
+ return clk_core_set_parent_nolock(hw->core, parent->core);
+}
+EXPORT_SYMBOL_GPL(clk_hw_set_parent);
+
/**
* clk_set_parent - switch the parent of a mux clk
* @clk: the mux clk whose input we are switching
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index bb6118f79784..8a453380f9a4 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -812,6 +812,7 @@ unsigned int clk_hw_get_num_parents(const struct clk_hw *hw);
struct clk_hw *clk_hw_get_parent(const struct clk_hw *hw);
struct clk_hw *clk_hw_get_parent_by_index(const struct clk_hw *hw,
unsigned int index);
+int clk_hw_set_parent(struct clk_hw *hw, struct clk_hw *new_parent);
unsigned int __clk_get_enable_count(struct clk *clk);
unsigned long clk_hw_get_rate(const struct clk_hw *hw);
unsigned long __clk_get_flags(struct clk *clk);
--
2.21.0
^ permalink raw reply related
* [RFC/RFT v3 04/14] clk: meson: eeclk: add setup callback
From: Neil Armstrong @ 2019-07-01 9:12 UTC (permalink / raw)
To: jbrunet, khilman
Cc: linux-arm-kernel, linux-amlogic, linux-kernel, linux-clk,
martin.blumenstingl, linux-gpio, Neil Armstrong
In-Reply-To: <20190701091258.3870-1-narmstrong@baylibre.com>
Add a setup() callback in the eeclk structure, to call an optional
call() function at end of eeclk probe to setup clocks.
It's used for the G12A clock controller to setup the CPU clock notifiers.
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
drivers/clk/meson/meson-eeclk.c | 6 ++++++
drivers/clk/meson/meson-eeclk.h | 1 +
2 files changed, 7 insertions(+)
diff --git a/drivers/clk/meson/meson-eeclk.c b/drivers/clk/meson/meson-eeclk.c
index 6ba2094be257..81fd2abcd173 100644
--- a/drivers/clk/meson/meson-eeclk.c
+++ b/drivers/clk/meson/meson-eeclk.c
@@ -61,6 +61,12 @@ int meson_eeclkc_probe(struct platform_device *pdev)
}
}
+ if (data->setup) {
+ ret = data->setup(pdev);
+ if (ret)
+ return ret;
+ }
+
return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
data->hw_onecell_data);
}
diff --git a/drivers/clk/meson/meson-eeclk.h b/drivers/clk/meson/meson-eeclk.h
index 9ab5d6fa7ccb..7fdf424f71a6 100644
--- a/drivers/clk/meson/meson-eeclk.h
+++ b/drivers/clk/meson/meson-eeclk.h
@@ -20,6 +20,7 @@ struct meson_eeclkc_data {
const struct reg_sequence *init_regs;
unsigned int init_count;
struct clk_hw_onecell_data *hw_onecell_data;
+ int (*setup)(struct platform_device *pdev);
};
int meson_eeclkc_probe(struct platform_device *pdev);
--
2.21.0
^ permalink raw reply related
* [RFC/RFT v3 05/14] soc: amlogic: meson-clk-measure: protect measure with a mutex
From: Neil Armstrong @ 2019-07-01 9:12 UTC (permalink / raw)
To: jbrunet, khilman
Cc: linux-arm-kernel, linux-amlogic, linux-kernel, linux-clk,
martin.blumenstingl, linux-gpio, Neil Armstrong
In-Reply-To: <20190701091258.3870-1-narmstrong@baylibre.com>
In order to protect clock measuring when multiple process asks for
a measure, protect the main measure function with mutexes.
Reviewed-by: Kevin Hilman <khilman@baylibre.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
drivers/soc/amlogic/meson-clk-measure.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/drivers/soc/amlogic/meson-clk-measure.c b/drivers/soc/amlogic/meson-clk-measure.c
index 19d4cbc93a17..c470e24f1dfa 100644
--- a/drivers/soc/amlogic/meson-clk-measure.c
+++ b/drivers/soc/amlogic/meson-clk-measure.c
@@ -11,6 +11,8 @@
#include <linux/debugfs.h>
#include <linux/regmap.h>
+static DEFINE_MUTEX(measure_lock);
+
#define MSR_CLK_DUTY 0x0
#define MSR_CLK_REG0 0x4
#define MSR_CLK_REG1 0x8
@@ -360,6 +362,10 @@ static int meson_measure_id(struct meson_msr_id *clk_msr_id,
unsigned int val;
int ret;
+ ret = mutex_lock_interruptible(&measure_lock);
+ if (ret)
+ return ret;
+
regmap_write(priv->regmap, MSR_CLK_REG0, 0);
/* Set measurement duration */
@@ -377,8 +383,10 @@ static int meson_measure_id(struct meson_msr_id *clk_msr_id,
ret = regmap_read_poll_timeout(priv->regmap, MSR_CLK_REG0,
val, !(val & MSR_BUSY), 10, 10000);
- if (ret)
+ if (ret) {
+ mutex_unlock(&measure_lock);
return ret;
+ }
/* Disable */
regmap_update_bits(priv->regmap, MSR_CLK_REG0, MSR_ENABLE, 0);
@@ -386,6 +394,8 @@ static int meson_measure_id(struct meson_msr_id *clk_msr_id,
/* Get the value in multiple of gate time counts */
regmap_read(priv->regmap, MSR_CLK_REG2, &val);
+ mutex_unlock(&measure_lock);
+
if (val >= MSR_VAL_MASK)
return -EINVAL;
--
2.21.0
^ permalink raw reply related
* [RFC/RFT v3 07/14] clk: meson: g12a: add notifiers to handle cpu clock change
From: Neil Armstrong @ 2019-07-01 9:12 UTC (permalink / raw)
To: jbrunet, khilman
Cc: linux-arm-kernel, linux-amlogic, linux-kernel, linux-clk,
martin.blumenstingl, linux-gpio, Neil Armstrong
In-Reply-To: <20190701091258.3870-1-narmstrong@baylibre.com>
In order to implement clock switching for the CLKID_CPU_CLK and
CLKID_CPUB_CLK, notifiers are added on specific points of the
clock tree :
cpu_clk / cpub_clk
| \- cpu_clk_dyn
| | \- cpu_clk_premux0
| | |- cpu_clk_postmux0
| | | |- cpu_clk_dyn0_div
| | | \- xtal/fclk_div2/fclk_div3
| | \- xtal/fclk_div2/fclk_div3
| \- cpu_clk_premux1
| |- cpu_clk_postmux1
| | |- cpu_clk_dyn1_div
| | \- xtal/fclk_div2/fclk_div3
| \- xtal/fclk_div2/fclk_div3
\ sys_pll / sys1_pll
This for each cluster, a single one for G12A, two for G12B.
Each cpu_clk_premux1 tree is marked as read-only and CLK_SET_RATE_NO_REPARENT,
to be used as "parking" clock in a safe clock frequency.
A notifier is added on each cpu_clk_premux0 to detech when CCF want to
change the frequency of the cpu_clk_dyn tree.
In this notifier, the cpu_clk_premux1 tree is configured to use the xtal
clock and then the cpu_clk_dyn is switch to cpu_clk_premux1 while CCF
updates the cpu_clk_premux0 tree.
A notifier is added on each sys_pll/sys1_pll to detect when CCF wants to
change the PLL clock source of the cpu_clk.
In this notifier, the cpu_clk is switched to cpu_clk_dyn while CCF
updates the sys_pll/sys1_pll frequency.
A third small notifier is added on each cpu_clk / cpub_clk and cpu_clk_dyn,
add a small delay at PRE_RATE_CHANGE/POST_RATE_CHANGE to let the other
notofiers change propagate before changing the cpu_clk_premux0 and sys_pll
clock trees.
This notifier set permits switching the cpu_clk / cpub_clk without any
glitches and using a safe parking clock while switching between sub-GHz
clocks using the cpu_clk_dyn tree.
This setup has been tested and validated on the Amlogic G12A and G12B
SoCs running the arm64 cpuburn at [1] and cycling between all the possible
cpufreq translations of each cluster and checking the final frequency using
the clock-measurer, script at [2].
[1] https://github.com/ssvb/cpuburn-arm/blob/master/cpuburn-a53.S
[2] https://gist.github.com/superna9999/d4de964dbc0f84b7d527e1df2ddea25f
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
drivers/clk/meson/g12a.c | 500 ++++++++++++++++++++++++++++++++++++---
1 file changed, 468 insertions(+), 32 deletions(-)
diff --git a/drivers/clk/meson/g12a.c b/drivers/clk/meson/g12a.c
index db1c4ed9d54e..3d2c2ac9a46d 100644
--- a/drivers/clk/meson/g12a.c
+++ b/drivers/clk/meson/g12a.c
@@ -14,6 +14,7 @@
#include <linux/init.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
+#include <linux/clk.h>
#include "clk-input.h"
#include "clk-mpll.h"
@@ -85,16 +86,9 @@ static struct clk_regmap g12a_fixed_pll = {
},
};
-/*
- * Internal sys pll emulation configuration parameters
- */
-static const struct reg_sequence g12a_sys_init_regs[] = {
- { .reg = HHI_SYS_PLL_CNTL1, .def = 0x00000000 },
- { .reg = HHI_SYS_PLL_CNTL2, .def = 0x00000000 },
- { .reg = HHI_SYS_PLL_CNTL3, .def = 0x48681c00 },
- { .reg = HHI_SYS_PLL_CNTL4, .def = 0x88770290 },
- { .reg = HHI_SYS_PLL_CNTL5, .def = 0x39272000 },
- { .reg = HHI_SYS_PLL_CNTL6, .def = 0x56540000 },
+static const struct pll_mult_range g12a_sys_pll_mult_range = {
+ .min = 128,
+ .max = 250,
};
static struct clk_regmap g12a_sys_pll_dco = {
@@ -124,14 +118,15 @@ static struct clk_regmap g12a_sys_pll_dco = {
.shift = 29,
.width = 1,
},
- .init_regs = g12a_sys_init_regs,
- .init_count = ARRAY_SIZE(g12a_sys_init_regs),
+ .range = &g12a_sys_pll_mult_range,
},
.hw.init = &(struct clk_init_data){
.name = "sys_pll_dco",
- .ops = &meson_clk_pll_ro_ops,
+ .ops = &meson_clk_pll_ops,
.parent_names = (const char *[]){ IN_PREFIX "xtal" },
.num_parents = 1,
+ /* This clock feeds the CPU, avoid disabling it */
+ .flags = CLK_IS_CRITICAL,
},
};
@@ -144,9 +139,10 @@ static struct clk_regmap g12a_sys_pll = {
},
.hw.init = &(struct clk_init_data){
.name = "sys_pll",
- .ops = &clk_regmap_divider_ro_ops,
+ .ops = &clk_regmap_divider_ops,
.parent_names = (const char *[]){ "sys_pll_dco" },
.num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
},
};
@@ -177,12 +173,15 @@ static struct clk_regmap g12b_sys1_pll_dco = {
.shift = 29,
.width = 1,
},
+ .range = &g12a_sys_pll_mult_range,
},
.hw.init = &(struct clk_init_data){
.name = "sys1_pll_dco",
- .ops = &meson_clk_pll_ro_ops,
+ .ops = &meson_clk_pll_ops,
.parent_names = (const char *[]){ IN_PREFIX "xtal" },
.num_parents = 1,
+ /* This clock feeds the CPU, avoid disabling it */
+ .flags = CLK_IS_CRITICAL,
},
};
@@ -195,9 +194,10 @@ static struct clk_regmap g12b_sys1_pll = {
},
.hw.init = &(struct clk_init_data){
.name = "sys1_pll",
- .ops = &clk_regmap_divider_ro_ops,
+ .ops = &clk_regmap_divider_ops,
.parent_names = (const char *[]){ "sys1_pll_dco" },
.num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
},
};
@@ -266,7 +266,7 @@ static struct clk_regmap g12a_cpu_clk_premux0 = {
},
.hw.init = &(struct clk_init_data){
.name = "cpu_clk_dyn0_sel",
- .ops = &clk_regmap_mux_ro_ops,
+ .ops = &clk_regmap_mux_ops,
.parent_names = (const char *[]){ IN_PREFIX "xtal",
"fclk_div2",
"fclk_div3" },
@@ -275,6 +275,38 @@ static struct clk_regmap g12a_cpu_clk_premux0 = {
};
/* Datasheet names this field as "mux0_divn_tcnt" */
+#define SYS_CPU_DYN_ENABLE BIT(26)
+
+/* This divider uses bit 26 to take change in account */
+static int g12a_cpu_clk_mux0_div_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_regmap *clk = to_clk_regmap(hw);
+ struct clk_regmap_div_data *div = clk_get_regmap_div_data(clk);
+ unsigned int val;
+ int ret;
+
+ ret = divider_get_val(rate, parent_rate, div->table, div->width,
+ div->flags);
+ if (ret < 0)
+ return ret;
+
+ val = (unsigned int)ret << div->shift;
+
+ regmap_update_bits(clk->map, HHI_SYS_CPU_CLK_CNTL0,
+ SYS_CPU_DYN_ENABLE, SYS_CPU_DYN_ENABLE);
+
+ return regmap_update_bits(clk->map, div->offset,
+ clk_div_mask(div->width) << div->shift |
+ SYS_CPU_DYN_ENABLE, val);
+};
+
+const struct clk_ops g12a_cpu_clk_mux0_div_ops = {
+ .recalc_rate = clk_regmap_div_recalc_rate,
+ .round_rate = clk_regmap_div_round_rate,
+ .set_rate = g12a_cpu_clk_mux0_div_set_rate,
+};
+
static struct clk_regmap g12a_cpu_clk_mux0_div = {
.data = &(struct clk_regmap_div_data){
.offset = HHI_SYS_CPU_CLK_CNTL0,
@@ -283,9 +315,10 @@ static struct clk_regmap g12a_cpu_clk_mux0_div = {
},
.hw.init = &(struct clk_init_data){
.name = "cpu_clk_dyn0_div",
- .ops = &clk_regmap_divider_ro_ops,
+ .ops = &g12a_cpu_clk_mux0_div_ops,
.parent_names = (const char *[]){ "cpu_clk_dyn0_sel" },
.num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
},
};
@@ -298,10 +331,11 @@ static struct clk_regmap g12a_cpu_clk_postmux0 = {
},
.hw.init = &(struct clk_init_data){
.name = "cpu_clk_dyn0",
- .ops = &clk_regmap_mux_ro_ops,
+ .ops = &clk_regmap_mux_ops,
.parent_names = (const char *[]){ "cpu_clk_dyn0_sel",
"cpu_clk_dyn0_div" },
.num_parents = 2,
+ .flags = CLK_SET_RATE_PARENT,
},
};
@@ -314,11 +348,13 @@ static struct clk_regmap g12a_cpu_clk_premux1 = {
},
.hw.init = &(struct clk_init_data){
.name = "cpu_clk_dyn1_sel",
- .ops = &clk_regmap_mux_ro_ops,
+ .ops = &clk_regmap_mux_ops,
.parent_names = (const char *[]){ IN_PREFIX "xtal",
"fclk_div2",
"fclk_div3" },
.num_parents = 3,
+ /* This sub-tree is used a parking clock */
+ .flags = CLK_SET_RATE_NO_REPARENT,
},
};
@@ -346,10 +382,12 @@ static struct clk_regmap g12a_cpu_clk_postmux1 = {
},
.hw.init = &(struct clk_init_data){
.name = "cpu_clk_dyn1",
- .ops = &clk_regmap_mux_ro_ops,
+ .ops = &clk_regmap_mux_ops,
.parent_names = (const char *[]){ "cpu_clk_dyn1_sel",
"cpu_clk_dyn1_div" },
.num_parents = 2,
+ /* This sub-tree is used a parking clock */
+ .flags = CLK_SET_RATE_NO_REPARENT,
},
};
@@ -362,10 +400,11 @@ static struct clk_regmap g12a_cpu_clk_dyn = {
},
.hw.init = &(struct clk_init_data){
.name = "cpu_clk_dyn",
- .ops = &clk_regmap_mux_ro_ops,
+ .ops = &clk_regmap_mux_ops,
.parent_names = (const char *[]){ "cpu_clk_dyn0",
"cpu_clk_dyn1" },
.num_parents = 2,
+ .flags = CLK_SET_RATE_PARENT,
},
};
@@ -378,10 +417,11 @@ static struct clk_regmap g12a_cpu_clk = {
},
.hw.init = &(struct clk_init_data){
.name = "cpu_clk",
- .ops = &clk_regmap_mux_ro_ops,
+ .ops = &clk_regmap_mux_ops,
.parent_names = (const char *[]){ "cpu_clk_dyn",
"sys_pll" },
.num_parents = 2,
+ .flags = CLK_SET_RATE_PARENT,
},
};
@@ -394,10 +434,11 @@ static struct clk_regmap g12b_cpu_clk = {
},
.hw.init = &(struct clk_init_data){
.name = "cpu_clk",
- .ops = &clk_regmap_mux_ro_ops,
+ .ops = &clk_regmap_mux_ops,
.parent_names = (const char *[]){ "cpu_clk_dyn",
"sys1_pll" },
.num_parents = 2,
+ .flags = CLK_SET_RATE_PARENT,
},
};
@@ -410,7 +451,7 @@ static struct clk_regmap g12b_cpub_clk_premux0 = {
},
.hw.init = &(struct clk_init_data){
.name = "cpub_clk_dyn0_sel",
- .ops = &clk_regmap_mux_ro_ops,
+ .ops = &clk_regmap_mux_ops,
.parent_names = (const char *[]){ IN_PREFIX "xtal",
"fclk_div2",
"fclk_div3" },
@@ -418,6 +459,37 @@ static struct clk_regmap g12b_cpub_clk_premux0 = {
},
};
+/* This divider uses bit 26 to take change in account */
+static int g12b_cpub_clk_mux0_div_set_rate(struct clk_hw *hw,
+ unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_regmap *clk = to_clk_regmap(hw);
+ struct clk_regmap_div_data *div = clk_get_regmap_div_data(clk);
+ unsigned int val;
+ int ret;
+
+ ret = divider_get_val(rate, parent_rate, div->table, div->width,
+ div->flags);
+ if (ret < 0)
+ return ret;
+
+ val = (unsigned int)ret << div->shift;
+
+ regmap_update_bits(clk->map, HHI_SYS_CPUB_CLK_CNTL,
+ SYS_CPU_DYN_ENABLE, SYS_CPU_DYN_ENABLE);
+
+ return regmap_update_bits(clk->map, div->offset,
+ clk_div_mask(div->width) << div->shift |
+ SYS_CPU_DYN_ENABLE, val);
+};
+
+static const struct clk_ops g12b_cpub_clk_mux0_div_ops = {
+ .recalc_rate = clk_regmap_div_recalc_rate,
+ .round_rate = clk_regmap_div_round_rate,
+ .set_rate = g12b_cpub_clk_mux0_div_set_rate,
+};
+
/* Datasheet names this field as "mux0_divn_tcnt" */
static struct clk_regmap g12b_cpub_clk_mux0_div = {
.data = &(struct clk_regmap_div_data){
@@ -427,9 +499,10 @@ static struct clk_regmap g12b_cpub_clk_mux0_div = {
},
.hw.init = &(struct clk_init_data){
.name = "cpub_clk_dyn0_div",
- .ops = &clk_regmap_divider_ro_ops,
+ .ops = &g12b_cpub_clk_mux0_div_ops,
.parent_names = (const char *[]){ "cpub_clk_dyn0_sel" },
.num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
},
};
@@ -442,10 +515,11 @@ static struct clk_regmap g12b_cpub_clk_postmux0 = {
},
.hw.init = &(struct clk_init_data){
.name = "cpub_clk_dyn0",
- .ops = &clk_regmap_mux_ro_ops,
+ .ops = &clk_regmap_mux_ops,
.parent_names = (const char *[]){ "cpub_clk_dyn0_sel",
"cpub_clk_dyn0_div" },
.num_parents = 2,
+ .flags = CLK_SET_RATE_PARENT,
},
};
@@ -458,11 +532,13 @@ static struct clk_regmap g12b_cpub_clk_premux1 = {
},
.hw.init = &(struct clk_init_data){
.name = "cpub_clk_dyn1_sel",
- .ops = &clk_regmap_mux_ro_ops,
+ .ops = &clk_regmap_mux_ops,
.parent_names = (const char *[]){ IN_PREFIX "xtal",
"fclk_div2",
"fclk_div3" },
.num_parents = 3,
+ /* This sub-tree is used a parking clock */
+ .flags = CLK_SET_RATE_NO_REPARENT,
},
};
@@ -490,10 +566,12 @@ static struct clk_regmap g12b_cpub_clk_postmux1 = {
},
.hw.init = &(struct clk_init_data){
.name = "cpub_clk_dyn1",
- .ops = &clk_regmap_mux_ro_ops,
+ .ops = &clk_regmap_mux_ops,
.parent_names = (const char *[]){ "cpub_clk_dyn1_sel",
"cpub_clk_dyn1_div" },
.num_parents = 2,
+ /* This sub-tree is used a parking clock */
+ .flags = CLK_SET_RATE_NO_REPARENT,
},
};
@@ -506,10 +584,11 @@ static struct clk_regmap g12b_cpub_clk_dyn = {
},
.hw.init = &(struct clk_init_data){
.name = "cpub_clk_dyn",
- .ops = &clk_regmap_mux_ro_ops,
+ .ops = &clk_regmap_mux_ops,
.parent_names = (const char *[]){ "cpub_clk_dyn0",
"cpub_clk_dyn1" },
.num_parents = 2,
+ .flags = CLK_SET_RATE_PARENT,
},
};
@@ -522,13 +601,225 @@ static struct clk_regmap g12b_cpub_clk = {
},
.hw.init = &(struct clk_init_data){
.name = "cpub_clk",
- .ops = &clk_regmap_mux_ro_ops,
+ .ops = &clk_regmap_mux_ops,
.parent_names = (const char *[]){ "cpub_clk_dyn",
"sys_pll" },
.num_parents = 2,
+ .flags = CLK_SET_RATE_PARENT,
},
};
+static int g12a_cpu_clk_mux_notifier_cb(struct notifier_block *nb,
+ unsigned long event, void *data)
+{
+ if (event == POST_RATE_CHANGE || event == PRE_RATE_CHANGE) {
+ /* Wait for clock propagation before/after changing the mux */
+ udelay(100);
+ return NOTIFY_OK;
+ }
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block g12a_cpu_clk_mux_nb = {
+ .notifier_call = g12a_cpu_clk_mux_notifier_cb,
+};
+
+struct g12a_cpu_clk_postmux_nb_data {
+ struct notifier_block nb;
+ struct clk_hw *xtal;
+ struct clk_hw *cpu_clk_dyn;
+ struct clk_hw *cpu_clk_postmux0;
+ struct clk_hw *cpu_clk_postmux1;
+ struct clk_hw *cpu_clk_premux1;
+};
+
+static int g12a_cpu_clk_postmux_notifier_cb(struct notifier_block *nb,
+ unsigned long event, void *data)
+{
+ struct g12a_cpu_clk_postmux_nb_data *nb_data =
+ container_of(nb, struct g12a_cpu_clk_postmux_nb_data, nb);
+
+ switch (event) {
+ case PRE_RATE_CHANGE:
+ /*
+ * This notifier means cpu_clk_postmux0 clock will be changed
+ * to feed cpu_clk, this is the current path :
+ * cpu_clk
+ * \- cpu_clk_dyn
+ * \- cpu_clk_postmux0
+ * \- cpu_clk_muxX_div
+ * \- cpu_clk_premux0
+ * \- fclk_div3 or fclk_div2
+ * OR
+ * \- cpu_clk_premux0
+ * \- fclk_div3 or fclk_div2
+ */
+
+ /* Setup cpu_clk_premux1 to xtal */
+ clk_hw_set_parent(nb_data->cpu_clk_premux1,
+ nb_data->xtal);
+
+ /* Setup cpu_clk_postmux1 to bypass divider */
+ clk_hw_set_parent(nb_data->cpu_clk_postmux1,
+ nb_data->cpu_clk_premux1);
+
+ /* Switch to parking clk on cpu_clk_postmux1 */
+ clk_hw_set_parent(nb_data->cpu_clk_dyn,
+ nb_data->cpu_clk_postmux1);
+
+ /*
+ * Now, cpu_clk is 24MHz in the current path :
+ * cpu_clk
+ * \- cpu_clk_dyn
+ * \- cpu_clk_postmux1
+ * \- cpu_clk_premux1
+ * \- xtal
+ */
+
+ udelay(100);
+
+ return NOTIFY_OK;
+
+ case POST_RATE_CHANGE:
+ /*
+ * The cpu_clk_postmux0 has ben updated, now switch back
+ * cpu_clk_dyn to cpu_clk_postmux0 and take the changes
+ * in account.
+ */
+
+ /* Configure cpu_clk_dyn back to cpu_clk_postmux0 */
+ clk_hw_set_parent(nb_data->cpu_clk_dyn,
+ nb_data->cpu_clk_postmux0);
+
+ /*
+ * new path :
+ * cpu_clk
+ * \- cpu_clk_dyn
+ * \- cpu_clk_postmux0
+ * \- cpu_clk_muxX_div
+ * \- cpu_clk_premux0
+ * \- fclk_div3 or fclk_div2
+ * OR
+ * \- cpu_clk_premux0
+ * \- fclk_div3 or fclk_div2
+ */
+
+ udelay(100);
+
+ return NOTIFY_OK;
+
+ default:
+ return NOTIFY_DONE;
+ }
+}
+
+static struct g12a_cpu_clk_postmux_nb_data g12a_cpu_clk_postmux0_nb_data = {
+ .cpu_clk_dyn = &g12a_cpu_clk_dyn.hw,
+ .cpu_clk_postmux0 = &g12a_cpu_clk_postmux0.hw,
+ .cpu_clk_postmux1 = &g12a_cpu_clk_postmux1.hw,
+ .cpu_clk_premux1 = &g12a_cpu_clk_premux1.hw,
+ .nb.notifier_call = g12a_cpu_clk_postmux_notifier_cb,
+};
+
+static struct g12a_cpu_clk_postmux_nb_data g12b_cpub_clk_postmux0_nb_data = {
+ .cpu_clk_dyn = &g12b_cpub_clk_dyn.hw,
+ .cpu_clk_postmux0 = &g12b_cpub_clk_postmux0.hw,
+ .cpu_clk_postmux1 = &g12b_cpub_clk_postmux1.hw,
+ .cpu_clk_premux1 = &g12b_cpub_clk_premux1.hw,
+ .nb.notifier_call = g12a_cpu_clk_postmux_notifier_cb,
+};
+
+struct g12a_sys_pll_nb_data {
+ struct notifier_block nb;
+ struct clk_hw *sys_pll;
+ struct clk_hw *cpu_clk;
+ struct clk_hw *cpu_clk_dyn;
+};
+
+static int g12a_sys_pll_notifier_cb(struct notifier_block *nb,
+ unsigned long event, void *data)
+{
+ struct g12a_sys_pll_nb_data *nb_data =
+ container_of(nb, struct g12a_sys_pll_nb_data, nb);
+
+ switch (event) {
+ case PRE_RATE_CHANGE:
+ /*
+ * This notifier means sys_pll clock will be changed
+ * to feed cpu_clk, this the current path :
+ * cpu_clk
+ * \- sys_pll
+ * \- sys_pll_dco
+ */
+
+ /* Configure cpu_clk to use cpu_clk_dyn */
+ clk_hw_set_parent(nb_data->cpu_clk,
+ nb_data->cpu_clk_dyn);
+
+ /*
+ * Now, cpu_clk uses the dyn path
+ * cpu_clk
+ * \- cpu_clk_dyn
+ * \- cpu_clk_dynX
+ * \- cpu_clk_dynX_sel
+ * \- cpu_clk_dynX_div
+ * \- xtal/fclk_div2/fclk_div3
+ * \- xtal/fclk_div2/fclk_div3
+ */
+
+ udelay(100);
+
+ return NOTIFY_OK;
+
+ case POST_RATE_CHANGE:
+ /*
+ * The sys_pll has ben updated, now switch back cpu_clk to
+ * sys_pll
+ */
+
+ /* Configure cpu_clk to use sys_pll */
+ clk_hw_set_parent(nb_data->cpu_clk,
+ nb_data->sys_pll);
+
+ udelay(100);
+
+ /* new path :
+ * cpu_clk
+ * \- sys_pll
+ * \- sys_pll_dco
+ */
+
+ return NOTIFY_OK;
+
+ default:
+ return NOTIFY_DONE;
+ }
+}
+
+static struct g12a_sys_pll_nb_data g12a_sys_pll_nb_data = {
+ .sys_pll = &g12a_sys_pll.hw,
+ .cpu_clk = &g12a_cpu_clk.hw,
+ .cpu_clk_dyn = &g12a_cpu_clk_dyn.hw,
+ .nb.notifier_call = g12a_sys_pll_notifier_cb,
+};
+
+/* G12B first CPU cluster uses sys1_pll */
+static struct g12a_sys_pll_nb_data g12b_cpu_clk_sys1_pll_nb_data = {
+ .sys_pll = &g12b_sys1_pll.hw,
+ .cpu_clk = &g12b_cpu_clk.hw,
+ .cpu_clk_dyn = &g12a_cpu_clk_dyn.hw,
+ .nb.notifier_call = g12a_sys_pll_notifier_cb,
+};
+
+/* G12B second CPU cluster uses sys_pll */
+static struct g12a_sys_pll_nb_data g12b_cpub_clk_sys_pll_nb_data = {
+ .sys_pll = &g12a_sys_pll.hw,
+ .cpu_clk = &g12b_cpub_clk.hw,
+ .cpu_clk_dyn = &g12b_cpub_clk_dyn.hw,
+ .nb.notifier_call = g12a_sys_pll_notifier_cb,
+};
+
static struct clk_regmap g12a_cpu_clk_div16_en = {
.data = &(struct clk_regmap_gate_data){
.offset = HHI_SYS_CPU_CLK_CNTL1,
@@ -3792,18 +4083,163 @@ static const struct reg_sequence g12a_init_regs[] = {
{ .reg = HHI_MPLL_CNTL0, .def = 0x00000543 },
};
+static int meson_g12a_dvfs_setup_common(struct platform_device *pdev,
+ struct clk_hw **hws)
+{
+ const char *notifier_clk_name;
+ struct clk *notifier_clk;
+ struct clk_hw *xtal;
+ int ret;
+
+ xtal = clk_hw_get_parent_by_index(hws[CLKID_CPU_CLK_DYN1_SEL], 0);
+
+ /* Setup clock notifier for cpu_clk_postmux0 */
+ g12a_cpu_clk_postmux0_nb_data.xtal = xtal;
+ notifier_clk_name = clk_hw_get_name(&g12a_cpu_clk_postmux0.hw);
+ notifier_clk = __clk_lookup(notifier_clk_name);
+ ret = clk_notifier_register(notifier_clk,
+ &g12a_cpu_clk_postmux0_nb_data.nb);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register the cpu_clk_postmux0 notifier\n");
+ return ret;
+ }
+
+ /* Setup clock notifier for cpu_clk_dyn mux */
+ notifier_clk_name = clk_hw_get_name(&g12a_cpu_clk_dyn.hw);
+ notifier_clk = __clk_lookup(notifier_clk_name);
+ ret = clk_notifier_register(notifier_clk, &g12a_cpu_clk_mux_nb);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register the cpu_clk_dyn notifier\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int meson_g12b_dvfs_setup(struct platform_device *pdev)
+{
+ struct clk_hw **hws = g12b_hw_onecell_data.hws;
+ const char *notifier_clk_name;
+ struct clk *notifier_clk;
+ struct clk_hw *xtal;
+ int ret;
+
+ ret = meson_g12a_dvfs_setup_common(pdev, hws);
+ if (ret)
+ return ret;
+
+ xtal = clk_hw_get_parent_by_index(hws[CLKID_CPU_CLK_DYN1_SEL], 0);
+
+ /* Setup clock notifier for cpu_clk mux */
+ notifier_clk_name = clk_hw_get_name(&g12b_cpu_clk.hw);
+ notifier_clk = __clk_lookup(notifier_clk_name);
+ ret = clk_notifier_register(notifier_clk, &g12a_cpu_clk_mux_nb);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register the cpu_clk notifier\n");
+ return ret;
+ }
+
+ /* Setup clock notifier for sys1_pll */
+ notifier_clk_name = clk_hw_get_name(&g12b_sys1_pll.hw);
+ notifier_clk = __clk_lookup(notifier_clk_name);
+ ret = clk_notifier_register(notifier_clk,
+ &g12b_cpu_clk_sys1_pll_nb_data.nb);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register the sys1_pll notifier\n");
+ return ret;
+ }
+
+ /* Add notifiers for the second CPU cluster */
+
+ /* Setup clock notifier for cpub_clk_postmux0 */
+ g12b_cpub_clk_postmux0_nb_data.xtal = xtal;
+ notifier_clk_name = clk_hw_get_name(&g12b_cpub_clk_postmux0.hw);
+ notifier_clk = __clk_lookup(notifier_clk_name);
+ ret = clk_notifier_register(notifier_clk,
+ &g12b_cpub_clk_postmux0_nb_data.nb);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register the cpub_clk_postmux0 notifier\n");
+ return ret;
+ }
+
+ /* Setup clock notifier for cpub_clk_dyn mux */
+ notifier_clk_name = clk_hw_get_name(&g12b_cpub_clk_dyn.hw);
+ notifier_clk = __clk_lookup(notifier_clk_name);
+ ret = clk_notifier_register(notifier_clk, &g12a_cpu_clk_mux_nb);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register the cpub_clk_dyn notifier\n");
+ return ret;
+ }
+
+ /* Setup clock notifier for cpub_clk mux */
+ notifier_clk_name = clk_hw_get_name(&g12b_cpub_clk.hw);
+ notifier_clk = __clk_lookup(notifier_clk_name);
+ ret = clk_notifier_register(notifier_clk, &g12a_cpu_clk_mux_nb);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register the cpub_clk notifier\n");
+ return ret;
+ }
+
+ /* Setup clock notifier for sys_pll */
+ notifier_clk_name = clk_hw_get_name(&g12a_sys_pll.hw);
+ notifier_clk = __clk_lookup(notifier_clk_name);
+ ret = clk_notifier_register(notifier_clk,
+ &g12b_cpub_clk_sys_pll_nb_data.nb);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register the sys_pll notifier\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+
+static int meson_g12a_dvfs_setup(struct platform_device *pdev)
+{
+ struct clk_hw **hws = g12a_hw_onecell_data.hws;
+ const char *notifier_clk_name;
+ struct clk *notifier_clk;
+ int ret;
+
+ ret = meson_g12a_dvfs_setup_common(pdev, hws);
+ if (ret)
+ return ret;
+
+ /* Setup clock notifier for cpu_clk mux */
+ notifier_clk_name = clk_hw_get_name(&g12a_cpu_clk.hw);
+ notifier_clk = __clk_lookup(notifier_clk_name);
+ ret = clk_notifier_register(notifier_clk, &g12a_cpu_clk_mux_nb);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register the cpu_clk notifier\n");
+ return ret;
+ }
+
+ /* Setup clock notifier for sys_pll */
+ notifier_clk_name = clk_hw_get_name(&g12a_sys_pll.hw);
+ notifier_clk = __clk_lookup(notifier_clk_name);
+ ret = clk_notifier_register(notifier_clk, &g12a_sys_pll_nb_data.nb);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register the sys_pll notifier\n");
+ return ret;
+ }
+
+ return 0;
+}
+
static const struct meson_eeclkc_data g12a_clkc_data = {
.regmap_clks = g12a_clk_regmaps,
.regmap_clk_num = ARRAY_SIZE(g12a_clk_regmaps),
.hw_onecell_data = &g12a_hw_onecell_data,
.init_regs = g12a_init_regs,
.init_count = ARRAY_SIZE(g12a_init_regs),
+ .setup = meson_g12a_dvfs_setup,
};
static const struct meson_eeclkc_data g12b_clkc_data = {
.regmap_clks = g12a_clk_regmaps,
.regmap_clk_num = ARRAY_SIZE(g12a_clk_regmaps),
- .hw_onecell_data = &g12b_hw_onecell_data
+ .hw_onecell_data = &g12b_hw_onecell_data,
+ .setup = meson_g12b_dvfs_setup,
};
static const struct of_device_id clkc_match_table[] = {
--
2.21.0
^ permalink raw reply related
* [RFC/RFT v3 12/14] arm64: dts: meson-g12a: enable DVFS on G12A boards
From: Neil Armstrong @ 2019-07-01 9:12 UTC (permalink / raw)
To: jbrunet, khilman
Cc: linux-arm-kernel, linux-amlogic, linux-kernel, linux-clk,
martin.blumenstingl, linux-gpio, Neil Armstrong
In-Reply-To: <20190701091258.3870-1-narmstrong@baylibre.com>
Enable DVFS for the U200, SEI520 and X96-Max Amlogic G12A based board
by setting the clock, OPP and supply for each CPU cores.
The CPU cluster power supply can achieve 0.73V to 1.01V using a PWM
output clocked at 800KHz with an inverse duty-cycle.
DVFS has been tested by running the arm64 cpuburn at [1] and cycling
between all the possible cpufreq translations and checking the final
frequency using the clock-measurer, script at [2].
[1] https://github.com/ssvb/cpuburn-arm/blob/master/cpuburn-a53.S
[2] https://gist.github.com/superna9999/d4de964dbc0f84b7d527e1df2ddea25f
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
.../boot/dts/amlogic/meson-g12a-sei510.dts | 55 +++++++++++++++++++
.../boot/dts/amlogic/meson-g12a-u200.dts | 54 ++++++++++++++++++
.../boot/dts/amlogic/meson-g12a-x96-max.dts | 52 ++++++++++++++++++
3 files changed, 161 insertions(+)
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts b/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts
index c7a87368850b..979449968a5f 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts
@@ -129,6 +129,25 @@
enable-active-high;
};
+ vddcpu: regulator-vddcpu {
+ /*
+ * SY8120B1ABC DC/DC Regulator.
+ */
+ compatible = "pwm-regulator";
+
+ regulator-name = "VDDCPU";
+ regulator-min-microvolt = <721000>;
+ regulator-max-microvolt = <1022000>;
+
+ vin-supply = <&dc_in>;
+
+ pwms = <&pwm_AO_cd 1 1250 0>;
+ pwm-dutycycle-range = <100 0>;
+
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
vddio_ao1v8: regulator-vddio_ao1v8 {
compatible = "regulator-fixed";
regulator-name = "VDDIO_AO1V8";
@@ -297,6 +316,34 @@
status = "okay";
};
+&cpu0 {
+ cpu-supply = <&vddcpu>;
+ operating-points-v2 = <&cpu_opp_table>;
+ clocks = <&clkc CLKID_CPU_CLK>;
+ clock-latency = <50000>;
+};
+
+&cpu1 {
+ cpu-supply = <&vddcpu>;
+ operating-points-v2 = <&cpu_opp_table>;
+ clocks = <&clkc CLKID_CPU_CLK>;
+ clock-latency = <50000>;
+};
+
+&cpu2 {
+ cpu-supply = <&vddcpu>;
+ operating-points-v2 = <&cpu_opp_table>;
+ clocks = <&clkc CLKID_CPU_CLK>;
+ clock-latency = <50000>;
+};
+
+&cpu3 {
+ cpu-supply = <&vddcpu>;
+ operating-points-v2 = <&cpu_opp_table>;
+ clocks = <&clkc CLKID_CPU_CLK>;
+ clock-latency = <50000>;
+};
+
&cvbs_vdac_port {
cvbs_vdac_out: endpoint {
remote-endpoint = <&cvbs_connector_in>;
@@ -339,6 +386,14 @@
pinctrl-names = "default";
};
+&pwm_AO_cd {
+ pinctrl-0 = <&pwm_ao_d_e_pins>;
+ pinctrl-names = "default";
+ clocks = <&xtal>;
+ clock-names = "clkin1";
+ status = "okay";
+};
+
&pwm_ef {
status = "okay";
pinctrl-0 = <&pwm_e_pins>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts b/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts
index 8551fbd4a488..2a324f0136e3 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts
@@ -129,6 +129,24 @@
regulator-always-on;
};
+ vddcpu: regulator-vddcpu {
+ /*
+ * MP8756GD Regulator.
+ */
+ compatible = "pwm-regulator";
+
+ regulator-name = "VDDCPU";
+ regulator-min-microvolt = <721000>;
+ regulator-max-microvolt = <1022000>;
+
+ vin-supply = <&main_12v>;
+
+ pwms = <&pwm_AO_cd 1 1250 0>;
+ pwm-dutycycle-range = <100 0>;
+
+ regulator-boot-on;
+ regulator-always-on;
+ };
};
&cec_AO {
@@ -145,6 +163,34 @@
hdmi-phandle = <&hdmi_tx>;
};
+&cpu0 {
+ cpu-supply = <&vddcpu>;
+ operating-points-v2 = <&cpu_opp_table>;
+ clocks = <&clkc CLKID_CPU_CLK>;
+ clock-latency = <50000>;
+};
+
+&cpu1 {
+ cpu-supply = <&vddcpu>;
+ operating-points-v2 = <&cpu_opp_table>;
+ clocks = <&clkc CLKID_CPU_CLK>;
+ clock-latency = <50000>;
+};
+
+&cpu2 {
+ cpu-supply = <&vddcpu>;
+ operating-points-v2 = <&cpu_opp_table>;
+ clocks = <&clkc CLKID_CPU_CLK>;
+ clock-latency = <50000>;
+};
+
+&cpu3 {
+ cpu-supply = <&vddcpu>;
+ operating-points-v2 = <&cpu_opp_table>;
+ clocks = <&clkc CLKID_CPU_CLK>;
+ clock-latency = <50000>;
+};
+
&cvbs_vdac_port {
cvbs_vdac_out: endpoint {
remote-endpoint = <&cvbs_connector_in>;
@@ -197,6 +243,14 @@
pinctrl-names = "default";
};
+&pwm_AO_cd {
+ pinctrl-0 = <&pwm_ao_d_e_pins>;
+ pinctrl-names = "default";
+ clocks = <&xtal>;
+ clock-names = "clkin1";
+ status = "okay";
+};
+
/* SD card */
&sd_emmc_b {
status = "okay";
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts b/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts
index fe4013cca876..c1e58a69d434 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts
@@ -132,6 +132,22 @@
regulator-always-on;
};
+ vddcpu: regulator-vddcpu {
+ compatible = "pwm-regulator";
+
+ regulator-name = "VDDCPU";
+ regulator-min-microvolt = <721000>;
+ regulator-max-microvolt = <1022000>;
+
+ vin-supply = <&dc_in>;
+
+ pwms = <&pwm_AO_cd 1 1250 0>;
+ pwm-dutycycle-range = <100 0>;
+
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
sound {
compatible = "amlogic,axg-sound-card";
model = "G12A-X96-MAX";
@@ -242,6 +258,34 @@
status = "okay";
};
+&cpu0 {
+ cpu-supply = <&vddcpu>;
+ operating-points-v2 = <&cpu_opp_table>;
+ clocks = <&clkc CLKID_CPU_CLK>;
+ clock-latency = <50000>;
+};
+
+&cpu1 {
+ cpu-supply = <&vddcpu>;
+ operating-points-v2 = <&cpu_opp_table>;
+ clocks = <&clkc CLKID_CPU_CLK>;
+ clock-latency = <50000>;
+};
+
+&cpu2 {
+ cpu-supply = <&vddcpu>;
+ operating-points-v2 = <&cpu_opp_table>;
+ clocks = <&clkc CLKID_CPU_CLK>;
+ clock-latency = <50000>;
+};
+
+&cpu3 {
+ cpu-supply = <&vddcpu>;
+ operating-points-v2 = <&cpu_opp_table>;
+ clocks = <&clkc CLKID_CPU_CLK>;
+ clock-latency = <50000>;
+};
+
&cvbs_vdac_port {
cvbs_vdac_out: endpoint {
remote-endpoint = <&cvbs_connector_in>;
@@ -279,6 +323,14 @@
pinctrl-names = "default";
};
+&pwm_AO_cd {
+ pinctrl-0 = <&pwm_ao_d_e_pins>;
+ pinctrl-names = "default";
+ clocks = <&xtal>;
+ clock-names = "clkin1";
+ status = "okay";
+};
+
&ext_mdio {
external_phy: ethernet-phy@0 {
/* Realtek RTL8211F (0x001cc916) */
--
2.21.0
^ permalink raw reply related
* [RFC/RFT v3 11/14] arm64: dts: meson-g12a: add cpus OPP table
From: Neil Armstrong @ 2019-07-01 9:12 UTC (permalink / raw)
To: jbrunet, khilman
Cc: linux-arm-kernel, linux-amlogic, linux-kernel, linux-clk,
martin.blumenstingl, linux-gpio, Neil Armstrong
In-Reply-To: <20190701091258.3870-1-narmstrong@baylibre.com>
Add the OPP table taken from the vendor u200 and u211 DTS.
The Amlogic G12A SoC seems to available in 3 types :
- low-speed: up to 1,8GHz
- mid-speed: up to 1,908GHz
- high-speed: up to 2.1GHz
And the S905X2 opp voltages are slightly higher than the S905D2
OPP voltages for the low-speed table.
This adds the conservative OPP table with the S905X2 higher voltages
and the maximum low-speed OPP frequency.
The values were tested to be stable on an Amlogic U200 Reference Board,
SeiRobotics SEI510 and X96 Max Set-Top-Boxes running the arm64 cpuburn
at [1] and cycling between all the possible cpufreq translations and
checking the final frequency using the clock-measurer, script at [2].
[1] https://github.com/ssvb/cpuburn-arm/blob/master/cpuburn-a53.S
[2] https://gist.github.com/superna9999/d4de964dbc0f84b7d527e1df2ddea25f
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
arch/arm64/boot/dts/amlogic/meson-g12a.dtsi | 60 +++++++++++++++++++++
1 file changed, 60 insertions(+)
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi
index ac15967bb7fa..733a9d46fc4b 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi
@@ -48,6 +48,66 @@
compatible = "cache";
};
};
+
+ cpu_opp_table: opp-table {
+ compatible = "operating-points-v2";
+ opp-shared;
+
+ opp-100000000 {
+ opp-hz = /bits/ 64 <100000000>;
+ opp-microvolt = <731000>;
+ };
+
+ opp-250000000 {
+ opp-hz = /bits/ 64 <250000000>;
+ opp-microvolt = <731000>;
+ };
+
+ opp-500000000 {
+ opp-hz = /bits/ 64 <500000000>;
+ opp-microvolt = <731000>;
+ };
+
+ opp-667000000 {
+ opp-hz = /bits/ 64 <666666666>;
+ opp-microvolt = <731000>;
+ };
+
+ opp-1000000000 {
+ opp-hz = /bits/ 64 <1000000000>;
+ opp-microvolt = <731000>;
+ };
+
+ opp-1200000000 {
+ opp-hz = /bits/ 64 <1200000000>;
+ opp-microvolt = <731000>;
+ };
+
+ opp-1398000000 {
+ opp-hz = /bits/ 64 <1398000000>;
+ opp-microvolt = <761000>;
+ };
+
+ opp-1512000000 {
+ opp-hz = /bits/ 64 <1512000000>;
+ opp-microvolt = <791000>;
+ };
+
+ opp-1608000000 {
+ opp-hz = /bits/ 64 <1608000000>;
+ opp-microvolt = <831000>;
+ };
+
+ opp-1704000000 {
+ opp-hz = /bits/ 64 <1704000000>;
+ opp-microvolt = <861000>;
+ };
+
+ opp-1800000000 {
+ opp-hz = /bits/ 64 <1800000000>;
+ opp-microvolt = <981000>;
+ };
+ };
};
&sd_emmc_a {
--
2.21.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox