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