linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3] gpio: aspeed: Add banks Y, Z, AA, AB and AC
@ 2017-01-27  4:24 Andrew Jeffery
  2017-01-27  5:53 ` Joel Stanley
  2017-01-31 14:50 ` Linus Walleij
  0 siblings, 2 replies; 6+ messages in thread
From: Andrew Jeffery @ 2017-01-27  4:24 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Andrew Jeffery, Joel Stanley, linux-gpio, linux-kernel, openbmc

This is less straight-forward than one would hope, as some banks only
have 4 pins rather than 8, others are output only, yet more (W and
X, already supported) are input-only, and in the case of the g4 SoC bank
AC doesn't exist.

Add some structs to describe the varying properties of different banks
and integrate mechanisms to deny requests for unsupported
configurations.

Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
---

Since v2:

Drop linux/gpio.h include and change away from using GPIOF_* macros

Since v1:

Fix types for for_each_clear_bit() iteration

 drivers/gpio/gpio-aspeed.c | 173 +++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 159 insertions(+), 14 deletions(-)

diff --git a/drivers/gpio/gpio-aspeed.c b/drivers/gpio/gpio-aspeed.c
index 20f6f8ae4671..fb16cc771c0d 100644
--- a/drivers/gpio/gpio-aspeed.c
+++ b/drivers/gpio/gpio-aspeed.c
@@ -18,11 +18,23 @@
 #include <linux/gpio/driver.h>
 #include <linux/pinctrl/consumer.h>
 
+struct aspeed_bank_props {
+	unsigned int bank;
+	u32 input;
+	u32 output;
+};
+
+struct aspeed_gpio_config {
+	unsigned int nr_gpios;
+	const struct aspeed_bank_props *props;
+};
+
 struct aspeed_gpio {
 	struct gpio_chip chip;
 	spinlock_t lock;
 	void __iomem *base;
 	int irq;
+	const struct aspeed_gpio_config *config;
 };
 
 struct aspeed_gpio_bank {
@@ -62,11 +74,16 @@ static const struct aspeed_gpio_bank aspeed_gpio_banks[] = {
 		.irq_regs = 0x0148,
 		.names = { "U", "V", "W", "X" },
 	},
-	/*
-	 * A bank exists for { 'Y', 'Z', "AA", "AB" }, but is not implemented.
-	 * Only half of GPIOs Y support interrupt configuration, and none of Z,
-	 * AA or AB do as they are output only.
-	 */
+	{
+		.val_regs = 0x01E0,
+		.irq_regs = 0x0178,
+		.names = { "Y", "Z", "AA", "AB" },
+	},
+	{
+		.val_regs = 0x01E8,
+		.irq_regs = 0x01A8,
+		.names = { "AC", "", "", "" },
+	},
 };
 
 #define GPIO_BANK(x)	((x) >> 5)
@@ -90,6 +107,51 @@ static const struct aspeed_gpio_bank *to_bank(unsigned int offset)
 	return &aspeed_gpio_banks[bank];
 }
 
+static inline bool is_bank_props_sentinel(const struct aspeed_bank_props *props)
+{
+	return !(props->input || props->output);
+}
+
+static inline const struct aspeed_bank_props *find_bank_props(
+		struct aspeed_gpio *gpio, unsigned int offset)
+{
+	const struct aspeed_bank_props *props = gpio->config->props;
+
+	while (!is_bank_props_sentinel(props)) {
+		if (props->bank == GPIO_BANK(offset))
+			return props;
+		props++;
+	}
+
+	return NULL;
+}
+
+static inline bool have_gpio(struct aspeed_gpio *gpio, unsigned int offset)
+{
+	const struct aspeed_bank_props *props = find_bank_props(gpio, offset);
+	const struct aspeed_gpio_bank *bank = to_bank(offset);
+	unsigned int group = GPIO_OFFSET(offset) / 8;
+
+	return bank->names[group][0] != '\0' &&
+		(!props || ((props->input | props->output) & GPIO_BIT(offset)));
+}
+
+static inline bool have_input(struct aspeed_gpio *gpio, unsigned int offset)
+{
+	const struct aspeed_bank_props *props = find_bank_props(gpio, offset);
+
+	return !props || (props->input & GPIO_BIT(offset));
+}
+
+#define have_irq(g, o) have_input((g), (o))
+
+static inline bool have_output(struct aspeed_gpio *gpio, unsigned int offset)
+{
+	const struct aspeed_bank_props *props = find_bank_props(gpio, offset);
+
+	return !props || (props->output & GPIO_BIT(offset));
+}
+
 static void __iomem *bank_val_reg(struct aspeed_gpio *gpio,
 		const struct aspeed_gpio_bank *bank,
 		unsigned int reg)
@@ -152,6 +214,9 @@ static int aspeed_gpio_dir_in(struct gpio_chip *gc, unsigned int offset)
 	unsigned long flags;
 	u32 reg;
 
+	if (!have_input(gpio, offset))
+		return -ENOTSUPP;
+
 	spin_lock_irqsave(&gpio->lock, flags);
 
 	reg = ioread32(bank_val_reg(gpio, bank, GPIO_DIR));
@@ -170,6 +235,9 @@ static int aspeed_gpio_dir_out(struct gpio_chip *gc,
 	unsigned long flags;
 	u32 reg;
 
+	if (!have_output(gpio, offset))
+		return -ENOTSUPP;
+
 	spin_lock_irqsave(&gpio->lock, flags);
 
 	reg = ioread32(bank_val_reg(gpio, bank, GPIO_DIR));
@@ -189,6 +257,12 @@ static int aspeed_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
 	unsigned long flags;
 	u32 val;
 
+	if (!have_input(gpio, offset))
+		return 0;
+
+	if (!have_output(gpio, offset))
+		return 1;
+
 	spin_lock_irqsave(&gpio->lock, flags);
 
 	val = ioread32(bank_val_reg(gpio, bank, GPIO_DIR)) & GPIO_BIT(offset);
@@ -205,10 +279,17 @@ static inline int irqd_to_aspeed_gpio_data(struct irq_data *d,
 		u32 *bit)
 {
 	int offset;
+	struct aspeed_gpio *internal;
 
 	offset = irqd_to_hwirq(d);
 
-	*gpio = irq_data_get_irq_chip_data(d);
+	internal = irq_data_get_irq_chip_data(d);
+
+	/* This might be a bit of a questionable place to check */
+	if (!have_irq(internal, offset))
+		return -ENOTSUPP;
+
+	*gpio = internal;
 	*bank = to_bank(offset);
 	*bit = GPIO_BIT(offset);
 
@@ -364,6 +445,28 @@ static struct irq_chip aspeed_gpio_irqchip = {
 	.irq_set_type	= aspeed_gpio_set_type,
 };
 
+static void set_irq_valid_mask(struct aspeed_gpio *gpio)
+{
+	const struct aspeed_bank_props *props = gpio->config->props;
+
+	while (!is_bank_props_sentinel(props)) {
+		unsigned int offset;
+		const unsigned long int input = props->input;
+
+		/* Pretty crummy approach, but similar to GPIO core */
+		for_each_clear_bit(offset, &input, 32) {
+			unsigned int i = props->bank * 32 + offset;
+
+			if (i >= gpio->config->nr_gpios)
+				break;
+
+			clear_bit(i, gpio->chip.irq_valid_mask);
+		}
+
+		props++;
+	}
+}
+
 static int aspeed_gpio_setup_irqs(struct aspeed_gpio *gpio,
 		struct platform_device *pdev)
 {
@@ -375,6 +478,8 @@ static int aspeed_gpio_setup_irqs(struct aspeed_gpio *gpio,
 
 	gpio->irq = rc;
 
+	set_irq_valid_mask(gpio);
+
 	rc = gpiochip_irqchip_add(&gpio->chip, &aspeed_gpio_irqchip,
 			0, handle_bad_irq, IRQ_TYPE_NONE);
 	if (rc) {
@@ -390,6 +495,9 @@ static int aspeed_gpio_setup_irqs(struct aspeed_gpio *gpio,
 
 static int aspeed_gpio_request(struct gpio_chip *chip, unsigned int offset)
 {
+	if (!have_gpio(gpiochip_get_data(chip), offset))
+		return -ENODEV;
+
 	return pinctrl_request_gpio(chip->base + offset);
 }
 
@@ -398,8 +506,46 @@ static void aspeed_gpio_free(struct gpio_chip *chip, unsigned int offset)
 	pinctrl_free_gpio(chip->base + offset);
 }
 
+/*
+ * Any banks not specified in a struct aspeed_bank_props array are assumed to
+ * have the properties:
+ *
+ *     { .input = 0xffffffff, .output = 0xffffffff }
+ */
+
+static const struct aspeed_bank_props ast2400_bank_props[] = {
+	/*     input	  output   */
+	{ 5, 0xffffffff, 0x0000ffff }, /* U/V/W/X */
+	{ 6, 0x0000000f, 0x0fffff0f }, /* Y/Z/AA/AB, two 4-GPIO holes */
+	{ },
+};
+
+static const struct aspeed_gpio_config ast2400_config =
+	/* 220 for simplicity, really 216 with two 4-GPIO holes, four at end */
+	{ .nr_gpios = 220, .props = ast2400_bank_props, };
+
+static const struct aspeed_bank_props ast2500_bank_props[] = {
+	/*     input	  output   */
+	{ 5, 0xffffffff, 0x0000ffff }, /* U/V/W/X */
+	{ 6, 0x0fffffff, 0x0fffffff }, /* Y/Z/AA/AB, 4-GPIO hole */
+	{ 7, 0x000000ff, 0x000000ff }, /* AC */
+	{ },
+};
+
+static const struct aspeed_gpio_config ast2500_config =
+	/* 232 for simplicity, actual number is 228 (4-GPIO hole in GPIOAB) */
+	{ .nr_gpios = 232, .props = ast2500_bank_props, };
+
+static const struct of_device_id aspeed_gpio_of_table[] = {
+	{ .compatible = "aspeed,ast2400-gpio", .data = &ast2400_config, },
+	{ .compatible = "aspeed,ast2500-gpio", .data = &ast2500_config, },
+	{}
+};
+MODULE_DEVICE_TABLE(of, aspeed_gpio_of_table);
+
 static int __init aspeed_gpio_probe(struct platform_device *pdev)
 {
+	const struct of_device_id *gpio_id;
 	struct aspeed_gpio *gpio;
 	struct resource *res;
 	int rc;
@@ -415,8 +561,13 @@ static int __init aspeed_gpio_probe(struct platform_device *pdev)
 
 	spin_lock_init(&gpio->lock);
 
-	gpio->chip.ngpio = ARRAY_SIZE(aspeed_gpio_banks) * 32;
+	gpio_id = of_match_node(aspeed_gpio_of_table, pdev->dev.of_node);
+	if (!gpio_id)
+		return -EINVAL;
 
+	gpio->config = gpio_id->data;
+
+	gpio->chip.ngpio = gpio->config->nr_gpios;
 	gpio->chip.parent = &pdev->dev;
 	gpio->chip.direction_input = aspeed_gpio_dir_in;
 	gpio->chip.direction_output = aspeed_gpio_dir_out;
@@ -427,6 +578,7 @@ static int __init aspeed_gpio_probe(struct platform_device *pdev)
 	gpio->chip.set = aspeed_gpio_set;
 	gpio->chip.label = dev_name(&pdev->dev);
 	gpio->chip.base = -1;
+	gpio->chip.irq_need_valid_mask = true;
 
 	rc = devm_gpiochip_add_data(&pdev->dev, &gpio->chip, gpio);
 	if (rc < 0)
@@ -435,13 +587,6 @@ static int __init aspeed_gpio_probe(struct platform_device *pdev)
 	return aspeed_gpio_setup_irqs(gpio, pdev);
 }
 
-static const struct of_device_id aspeed_gpio_of_table[] = {
-	{ .compatible = "aspeed,ast2400-gpio" },
-	{ .compatible = "aspeed,ast2500-gpio" },
-	{}
-};
-MODULE_DEVICE_TABLE(of, aspeed_gpio_of_table);
-
 static struct platform_driver aspeed_gpio_driver = {
 	.driver = {
 		.name = KBUILD_MODNAME,
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH v3] gpio: aspeed: Add banks Y, Z, AA, AB and AC
  2017-01-27  4:24 [PATCH v3] gpio: aspeed: Add banks Y, Z, AA, AB and AC Andrew Jeffery
@ 2017-01-27  5:53 ` Joel Stanley
  2017-01-31 14:50 ` Linus Walleij
  1 sibling, 0 replies; 6+ messages in thread
From: Joel Stanley @ 2017-01-27  5:53 UTC (permalink / raw)
  To: Andrew Jeffery; +Cc: Linus Walleij, linux-gpio, linux-kernel, OpenBMC Maillist

On Fri, Jan 27, 2017 at 3:24 PM, Andrew Jeffery <andrew@aj.id.au> wrote:
> This is less straight-forward than one would hope, as some banks only
> have 4 pins rather than 8, others are output only, yet more (W and
> X, already supported) are input-only, and in the case of the g4 SoC bank
> AC doesn't exist.
>
> Add some structs to describe the varying properties of different banks
> and integrate mechanisms to deny requests for unsupported
> configurations.
>
> Signed-off-by: Andrew Jeffery <andrew@aj.id.au>

Acked-by: Joel Stanley <joel@jms.id.au>

Cheers,

Joel

> ---
>
> Since v2:
>
> Drop linux/gpio.h include and change away from using GPIOF_* macros
>
> Since v1:
>
> Fix types for for_each_clear_bit() iteration
>
>  drivers/gpio/gpio-aspeed.c | 173 +++++++++++++++++++++++++++++++++++++++++----
>  1 file changed, 159 insertions(+), 14 deletions(-)

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v3] gpio: aspeed: Add banks Y, Z, AA, AB and AC
  2017-01-27  4:24 [PATCH v3] gpio: aspeed: Add banks Y, Z, AA, AB and AC Andrew Jeffery
  2017-01-27  5:53 ` Joel Stanley
@ 2017-01-31 14:50 ` Linus Walleij
  2017-02-01  0:52   ` Andrew Jeffery
  1 sibling, 1 reply; 6+ messages in thread
From: Linus Walleij @ 2017-01-31 14:50 UTC (permalink / raw)
  To: Andrew Jeffery; +Cc: Joel Stanley, linux-gpio, linux-kernel, OpenBMC Maillist

On Fri, Jan 27, 2017 at 5:24 AM, Andrew Jeffery <andrew@aj.id.au> wrote:

> This is less straight-forward than one would hope, as some banks only
> have 4 pins rather than 8, others are output only, yet more (W and
> X, already supported) are input-only, and in the case of the g4 SoC bank
> AC doesn't exist.
>
> Add some structs to describe the varying properties of different banks
> and integrate mechanisms to deny requests for unsupported
> configurations.
>
> Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
> ---
>
> Since v2:

Patch applied with some patch -p1 < fuzz
please check the result.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v3] gpio: aspeed: Add banks Y, Z, AA, AB and AC
  2017-01-31 14:50 ` Linus Walleij
@ 2017-02-01  0:52   ` Andrew Jeffery
  2017-02-01  1:20     ` Andrew Jeffery
  0 siblings, 1 reply; 6+ messages in thread
From: Andrew Jeffery @ 2017-02-01  0:52 UTC (permalink / raw)
  To: Linus Walleij; +Cc: Joel Stanley, linux-gpio, linux-kernel, OpenBMC Maillist

[-- Attachment #1: Type: text/plain, Size: 1650 bytes --]

On Tue, 2017-01-31 at 15:50 +0100, Linus Walleij wrote:
> > On Fri, Jan 27, 2017 at 5:24 AM, Andrew Jeffery <andrew@aj.id.au> wrote:
> 
> > This is less straight-forward than one would hope, as some banks only
> > have 4 pins rather than 8, others are output only, yet more (W and
> > X, already supported) are input-only, and in the case of the g4 SoC bank
> > AC doesn't exist.
> > 
> > Add some structs to describe the varying properties of different banks
> > and integrate mechanisms to deny requests for unsupported
> > configurations.
> > 
> > > > Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
> > ---
> > 
> > Since v2:
> 
> Patch applied with some patch -p1 < fuzz
> please check the result.

Have you pushed the tree with the fuzzy patch applied? I can't find it.
I fetched the gpio (and pinctrl) trees just now, but all I'm seeing is:

    $ git log --all --author "Andrew Jeffery" --committer "Linus Walleij" --grep "AA, AB" --oneline
    1736f75d35e4 gpio: aspeed: Add banks Y, Z, AA, AB and AC
    8ccb6dc6e999 pinctrl: aspeed: g4: Fix mux configuration for GPIOs AA[4-7], AB[0-7]

and 

    $ git show --stat --pretty=fuller 1736f75d35e4
    commit 1736f75d35e47409ad776273133d0f558a4c8253
    Author:     Andrew Jeffery <    andrew@aj.id.au    >
    AuthorDate: Tue Jan 24 16:46:46 2017 +1030
    Commit:     Linus Walleij <    linus.walleij@linaro.org    >
    CommitDate: Thu Jan 26 14:45:43 2017 +0100

v3 wasn't sent until Friday the 27th, and the diff of 1736f75d35e4
still drags in <linux/gpio.h> which v3 removes.

Regardless, I'll try to recreate it myself and inspect the fuzz damage.

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v3] gpio: aspeed: Add banks Y, Z, AA, AB and AC
  2017-02-01  0:52   ` Andrew Jeffery
@ 2017-02-01  1:20     ` Andrew Jeffery
  2017-02-01 14:58       ` Linus Walleij
  0 siblings, 1 reply; 6+ messages in thread
From: Andrew Jeffery @ 2017-02-01  1:20 UTC (permalink / raw)
  To: Linus Walleij; +Cc: linux-gpio, OpenBMC Maillist, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1927 bytes --]

On Wed, 2017-02-01 at 11:22 +1030, Andrew Jeffery wrote:
> On Tue, 2017-01-31 at 15:50 +0100, Linus Walleij wrote:
> > > > > > On Fri, Jan 27, 2017 at 5:24 AM, Andrew Jeffery <andrew@aj.id.au> wrote:
> > > This is less straight-forward than one would hope, as some banks only
> > > have 4 pins rather than 8, others are output only, yet more (W and
> > > X, already supported) are input-only, and in the case of the g4 SoC bank
> > > AC doesn't exist.
> > > 
> > > Add some structs to describe the varying properties of different banks
> > > and integrate mechanisms to deny requests for unsupported
> > > configurations.
> > > 
> > > > > Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
> > > 
> > > ---
> > > 
> > > Since v2:
> > 
> > Patch applied with some patch -p1 < fuzz
> > please check the result.
> 

*snip*

> Regardless, I'll try to recreate it myself and inspect the fuzz damage.

Ah, I think I see what's happened. I didn't send "gpio: aspeed: Make
bank names strings" again because you claimed you had applied v1 in the
v2 thread[1]. This patch doesn't fuzz when "gpio: aspeed: Make bank
names strings" has been applied, so is it possible that you tried
applying it to a tree missing "gpio: aspeed: Make bank names strings"?

    $ git reset --hard gpio/for-next
    HEAD is now at f334eae9c4e9 Merge branch 'devel' into for-next
    $ git am "/home/andrew/patches/[PATCH_v2_1_2]_gpio:_aspeed:_Make_bank_names_strings.mbox"
    Applying: gpio: aspeed: Make bank names strings
    $ git am "/home/andrew/patches/[PATCH_v3]_gpio:_aspeed:_Add_banks_Y,_Z,_AA,_AB_and_AC.mbox"
    Applying: gpio: aspeed: Add banks Y, Z, AA, AB and AC
    $

    Sorry for the confusion. What should I be doing when sending an updated
    series where some of the patches have been applied? Send the whole
    series regardless?

    Andrew

    [1]     https://lkml.org/lkml/2017/1/26/334

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v3] gpio: aspeed: Add banks Y, Z, AA, AB and AC
  2017-02-01  1:20     ` Andrew Jeffery
@ 2017-02-01 14:58       ` Linus Walleij
  0 siblings, 0 replies; 6+ messages in thread
From: Linus Walleij @ 2017-02-01 14:58 UTC (permalink / raw)
  To: Andrew Jeffery; +Cc: linux-gpio, OpenBMC Maillist, linux-kernel

On Wed, Feb 1, 2017 at 2:20 AM, Andrew Jeffery <andrew@aj.id.au> wrote:
> On Wed, 2017-02-01 at 11:22 +1030, Andrew Jeffery wrote:
>> On Tue, 2017-01-31 at 15:50 +0100, Linus Walleij wrote:
>> > > > > > On Fri, Jan 27, 2017 at 5:24 AM, Andrew Jeffery <andrew@aj.id.au> wrote:
>> > > This is less straight-forward than one would hope, as some banks only
>> > > have 4 pins rather than 8, others are output only, yet more (W and
>> > > X, already supported) are input-only, and in the case of the g4 SoC bank
>> > > AC doesn't exist.
>> > >
>> > > Add some structs to describe the varying properties of different banks
>> > > and integrate mechanisms to deny requests for unsupported
>> > > configurations.
>> > >
>> > > > > Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
>> > >
>> > > ---
>> > >
>> > > Since v2:
>> >
>> > Patch applied with some patch -p1 < fuzz
>> > please check the result.
>>
>
> *snip*
>
>> Regardless, I'll try to recreate it myself and inspect the fuzz damage.
>
> Ah, I think I see what's happened. I didn't send "gpio: aspeed: Make
> bank names strings" again because you claimed you had applied v1 in the
> v2 thread[1]. This patch doesn't fuzz when "gpio: aspeed: Make bank
> names strings" has been applied, so is it possible that you tried
> applying it to a tree missing "gpio: aspeed: Make bank names strings"?

I mistakedly applied *both* patches to the pinctrl tree, devel branch.

I blame stress.

Oh well I guess I have to keep them there and remove this copy
from the gpio tree.

If the version I applied in the pinctrl tree is the wrong one (which
is possible) then please send an incremental patch on top fixing
the difference, so I can apply that to the pinctrl tree too....

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2017-02-01 14:58 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-01-27  4:24 [PATCH v3] gpio: aspeed: Add banks Y, Z, AA, AB and AC Andrew Jeffery
2017-01-27  5:53 ` Joel Stanley
2017-01-31 14:50 ` Linus Walleij
2017-02-01  0:52   ` Andrew Jeffery
2017-02-01  1:20     ` Andrew Jeffery
2017-02-01 14:58       ` Linus Walleij

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).