#define PFC_MASK GENMASK_ULL(5, 0)
#define PFC_PIN_MASK(pin) (PFC_MASK << ((pin) * 8))
+#define PFC_FUNC_INTERRUPT 0
/*
* Use 16 lower bits [15:0] for pin identifier
struct rzt2h_pinctrl *pctrl = gpiochip_get_data(chip);
u8 port = RZT2H_PIN_ID_TO_PORT(offset);
u8 bit = RZT2H_PIN_ID_TO_PIN(offset);
+ u64 reg64;
u16 reg;
int ret;
if (ret)
return ret;
- if (rzt2h_pinctrl_readb(pctrl, port, PMC(port)) & BIT(bit))
+ guard(spinlock_irqsave)(&pctrl->lock);
+
+ if (rzt2h_pinctrl_readb(pctrl, port, PMC(port)) & BIT(bit)) {
+ /*
+ * When a GPIO is being requested as an IRQ, the pinctrl
+ * framework expects to be able to read the GPIO's direction.
+ * IRQ function is separate from GPIO, and enabling it takes the
+ * pin out of GPIO mode.
+ * At this point, .child_to_parent_hwirq() has already been
+ * called to enable the IRQ function.
+ * Default to input direction for IRQ function.
+ */
+ reg64 = rzt2h_pinctrl_readq(pctrl, port, PFC(port));
+ reg64 = (reg64 >> (bit * 8)) & PFC_MASK;
+ if (reg64 == PFC_FUNC_INTERRUPT)
+ return GPIO_LINE_DIRECTION_IN;
+
return -EINVAL;
+ }
reg = rzt2h_pinctrl_readw(pctrl, port, PM(port));
reg = (reg >> (bit * 2)) & PM_MASK;