...
+/**
+ * xgpio_irq_ack - Acknowledge a child GPIO interrupt.
+ * This currently does nothing, but irq_ack is unconditionally called by
+ * handle_edge_irq and therefore must be defined.
This should go after parameter description(s).
+ * @irq_data: per irq and chip data passed down to chip functions
+ */
...
/**
+ * xgpio_irq_mask - Write the specified signal of the GPIO device.
+ * @irq_data: per irq and chip data passed down to chip functions
In all comments irq -> IRQ.
+ */
+static void xgpio_irq_mask(struct irq_data *irq_data)
+{
+ unsigned long flags;
+ struct xgpio_instance *chip = irq_data_get_irq_chip_data(irq_data);
+ int irq_offset = irqd_to_hwirq(irq_data);
+ int index = xgpio_index(chip, irq_offset);
+ int offset = xgpio_offset(chip, irq_offset);
+
+ spin_lock_irqsave(&chip->gpio_lock, flags);
+
+ chip->irq_enable[index] &= ~BIT(offset);
If you convert your data structure to use bitmaps (and respective API) like
#define XILINX_NGPIOS 64
...
DECLARE_BITMAP(irq_enable, XILINX_NGPIOS);
...
it will make code better to read and understand. For example, here it
will be just
__clear_bit(offset, chip->irq_enable);
+ dev_dbg(chip->gc.parent, "Disable %d irq, irq_enable_mask 0x%x\n",
+ irq_offset, chip->irq_enable[index]);
Under spin lock?! Hmm...
+ if (!chip->irq_enable[index]) {
+ /* Disable per channel interrupt */
+ u32 temp = xgpio_readreg(chip->regs + XGPIO_IPIER_OFFSET);
+
+ temp &= ~BIT(index);
+ xgpio_writereg(chip->regs + XGPIO_IPIER_OFFSET, temp);
+ }
+ spin_unlock_irqrestore(&chip->gpio_lock, flags);
+}
...
+ for (index = 0; index < num_channels; index++) {
+ if ((status & BIT(index))) {
If gpio_width is the same among banks, you can use for_each_set_bit()
here as well.
...
+ for_each_set_bit(bit, &all_events, 32) {
+ generic_handle_irq(irq_find_mapping
+ (chip->gc.irq.domain, offset + bit));
Strange indentation. Maybe a temporary variable helps?
...
+ chip->irq = platform_get_irq_optional(pdev, 0);
+ if (chip->irq <= 0) {
+ dev_info(&pdev->dev, "GPIO IRQ not set\n");
Why do you need an optional variant if you print an error anyway?
+ } else {
...
+ chip->gc.irq.parents = (unsigned int *)&chip->irq;
+ chip->gc.irq.num_parents = 1;
Current pattern is to use devm_kcalloc() for it (Linus has plans to
simplify this in the future and this will help him to find what
patterns are being used)