Re: [PATCH v4 1/2] gpio: gpio-mlxbf3: Add gpio driver support

From: Andy Shevchenko
Date: Fri Feb 17 2023 - 18:08:03 EST


On Fri, Feb 17, 2023 at 11:27 PM Asmaa Mnebhi <asmaa@xxxxxxxxxx> wrote:
>
> Add support for the BlueField-3 SoC GPIO driver.
> This driver configures and handles GPIO interrupts. It also enables a user
> to manipulate certain GPIO pins via libgpiod tools or other kernel drivers.
> The usables pins are defined via the gpio-reserved-ranges property.

Probably

"gpio-reserved-ranges"

(in double quotes).

...

> + depends on (MELLANOX_PLATFORM && ARM64 && ACPI) || (64BIT && COMPILE_TEST)

But do you really need the ACPI dependency? I don't see a single bit
of it in the driver.
(Yes, I know about IDs.)

Also, how 64BIT is needed for testing?

...

> +#include <linux/version.h>

I believe it's included automatically. Please, double check the header
inclusions to make sure you don't have some spurious ones in the list.

> +struct mlxbf3_gpio_context {
> + struct gpio_chip gc;
> +
> + /* YU GPIO block address */
> + void __iomem *gpio_io;
> +
> + /* YU GPIO cause block address */
> + void __iomem *gpio_cause_io;
> +};

...

> + int offset = irqd_to_hwirq(irqd);

It returns irq_hw_number_t IIRC. It's an unsigned type. Otherwise you
may have interesting effects.

...

> + int offset = irqd_to_hwirq(irqd);

Ditto.

...

> + raw_spin_lock_irqsave(&gs->gc.bgpio_lock, flags);
> +
> + switch (type & IRQ_TYPE_SENSE_MASK) {
> + case IRQ_TYPE_EDGE_BOTH:
> + val = readl(gs->gpio_io + MLXBF_GPIO_CAUSE_FALL_EN);
> + val |= BIT(offset);
> + writel(val, gs->gpio_io + MLXBF_GPIO_CAUSE_FALL_EN);
> + val = readl(gs->gpio_io + MLXBF_GPIO_CAUSE_RISE_EN);
> + val |= BIT(offset);
> + writel(val, gs->gpio_io + MLXBF_GPIO_CAUSE_RISE_EN);
> + break;
> + case IRQ_TYPE_EDGE_RISING:
> + val = readl(gs->gpio_io + MLXBF_GPIO_CAUSE_RISE_EN);
> + val |= BIT(offset);
> + writel(val, gs->gpio_io + MLXBF_GPIO_CAUSE_RISE_EN);
> + break;
> + case IRQ_TYPE_EDGE_FALLING:
> + val = readl(gs->gpio_io + MLXBF_GPIO_CAUSE_FALL_EN);
> + val |= BIT(offset);
> + writel(val, gs->gpio_io + MLXBF_GPIO_CAUSE_FALL_EN);
> + break;
> + default:

Dead lock starts here.

> + return -EINVAL;
> + }
> +
> + raw_spin_unlock_irqrestore(&gs->gc.bgpio_lock, flags);

...

> + irq_set_handler_locked(irqd, handle_simple_irq);

Why not using propert handler type (edge)?

...

> +static const struct irq_chip gpio_mlxbf3_irqchip = {
> + .name = "MLNXBF33",
> + .irq_set_type = mlxbf3_gpio_irq_set_type,
> + .irq_enable = mlxbf3_gpio_irq_enable,
> + .irq_disable = mlxbf3_gpio_irq_disable,
> +};

Seems missing two things (dunno if bgpio_init() helps with that):
- IMMUTABLE flag
- actual calls to enable and disable IRQs for internal GPIO library usage

See other drivers how it's done. There are even plenty of patches to
enable this thing separately.

...

> +static int
> +mlxbf3_gpio_probe(struct platform_device *pdev)

Doesn't it perfectly fit one line?

...

> + npins = MLXBF3_GPIO_MAX_PINS_PER_BLOCK;
> + device_property_read_u32(dev, "npins", &npins);

I don't see DT bindings for this property (being added in this
series). Is it already established one?

...

> + girq->default_type = IRQ_TYPE_NONE;

Assigning handle_bad_irq() is missing.

--
With Best Regards,
Andy Shevchenko