Patch "pinctrl: sunxi: Fix A33 external interrupts not working" has been added to the 4.4-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
pinctrl: sunxi: Fix A33 external interrupts not working
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
pinctrl-sunxi-fix-a33-external-interrupts-not-working.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
5e7515ba78fff2f5407eaa2f97c1d5c07801ac3dMon Sep 17 00:00:00 2001
From: Hans de Goede <[email protected]>
Date: Sat, 12 Mar 2016 19:44:57 +0100
Subject: pinctrl: sunxi: Fix A33 external interrupts not working
From: Hans de Goede <[email protected]>
commit 5e7515ba78fff2f5407eaa2f97c1d5c07801ac3d upstream.
pinctrl-sun8i-a33.c (and the dts) declare only 2 interrupt banks, where as the closely related a23 has 3 banks. This matches with the datasheet for the A33 where only interrupt banks B and G are specified where as the A23 has banks A, B and G.
However the A33 being the A23 derative it is means that the interrupt configure/status io-addresses for the 2 banks it has are not changed from the A23, iow they have the same address as if bank A was still present. Where as the sunxi pinctrl currently tries to use the A23 bank A addresses for bank B, since the pinctrl code does not know about the removed bank A.
Add a irq_bank_base parameter and use this where appropriate to take the missing bank A into account.
This fixes external interrupts not working on the A33 (tested with an i2c touchscreen controller which uses an external interrupt).
--- drivers/pinctrl/sunxi/pinctrl-sun8i-a33.c | 1 + drivers/pinctrl/sunxi/pinctrl-sunxi.c | 17 ++++++++++------- drivers/pinctrl/sunxi/pinctrl-sunxi.h | 21 +++++++++++---------- 3 files changed, 22 insertions(+), 17 deletions(-)
drivers/pinctrl/sunxi/pinctrl-sun8i-a33.c +1 -0
@@ -485,6 +485,7 @@ static const struct sunxi_pinctrl_desc s .pins = sun8i_a33_pins, .npins = ARRAY_SIZE(sun8i_a33_pins), .irq_banks = 2, + .irq_bank_base = 1, };static int sun8i_a33_pinctrl_probe (struct platform_device *pdev)
drivers/pinctrl/sunxi/pinctrl-sunxi.c +10 -7
@@ -578,7 +578,7 @@ static void sunxi_pinctrl_irq_release_restatic int sunxi_pinctrl_irq_set_type (struct irq_data *d,unsigned int type) {struct sunxi_pinctrl *pctl =irq_data_get_irq_chip_data (d); -u32 reg =sunxi_irq_cfg_reg (d->hwirq); +u32 reg =sunxi_irq_cfg_reg (d->hwirq, pctl->desc->irq_bank_base);u8 index =sunxi_irq_cfg_offset (d->hwirq);unsigned long flags;u32 regval;
@@ -625,7 +625,8 @@ static int sunxi_pinctrl_irq_set_type(ststatic void sunxi_pinctrl_irq_ack (struct irq_data *d) {struct sunxi_pinctrl *pctl =irq_data_get_irq_chip_data (d); -u32 status_reg =sunxi_irq_status_reg (d->hwirq); +u32 status_reg =sunxi_irq_status_reg (d->hwirq, + pctl->desc->irq_bank_base);u8 status_idx =sunxi_irq_status_offset (d->hwirq);/* Clear the IRQ */
@@ -635,7 +636,7 @@ static void sunxi_pinctrl_irq_ack(structstatic void sunxi_pinctrl_irq_mask (struct irq_data *d) {struct sunxi_pinctrl *pctl =irq_data_get_irq_chip_data (d); -u32 reg =sunxi_irq_ctrl_reg (d->hwirq); +u32 reg =sunxi_irq_ctrl_reg (d->hwirq, pctl->desc->irq_bank_base);u8 idx =sunxi_irq_ctrl_offset (d->hwirq);unsigned long flags;u32 val;
@@ -652,7 +653,7 @@ static void sunxi_pinctrl_irq_mask(strucstatic void sunxi_pinctrl_irq_unmask (struct irq_data *d) {struct sunxi_pinctrl *pctl =irq_data_get_irq_chip_data (d); -u32 reg =sunxi_irq_ctrl_reg (d->hwirq); +u32 reg =sunxi_irq_ctrl_reg (d->hwirq, pctl->desc->irq_bank_base);u8 idx =sunxi_irq_ctrl_offset (d->hwirq);unsigned long flags;u32 val;
@@ -744,7 +745,7 @@ static void sunxi_pinctrl_irq_handler(stif (bank == pctl->desc->irq_banks)return ; - reg =sunxi_irq_status_reg_from_bank (bank); + reg =sunxi_irq_status_reg_from_bank (bank, pctl->desc->irq_bank_base); val =readl (pctl->membase + reg);if (val) {
@@ -1023,9 +1024,11 @@ int sunxi_pinctrl_init(struct platform_dfor (i =0 ; i < pctl->desc->irq_banks; i++) {/* Mask and clear all IRQs before registering a handler */ -writel (0 , pctl->membase +sunxi_irq_ctrl_reg_from_bank (i)); +writel (0 , pctl->membase +sunxi_irq_ctrl_reg_from_bank (i, + pctl->desc->irq_bank_base));writel (0xffffffff , - pctl->membase +sunxi_irq_status_reg_from_bank (i)); + pctl->membase +sunxi_irq_status_reg_from_bank (i, + pctl->desc->irq_bank_base)); irq_set_chained_handler_and_data(pctl->irq[i], sunxi_pinctrl_irq_handler,
drivers/pinctrl/sunxi/pinctrl-sunxi.h +11 -10
@@ -97,6 +97,7 @@ struct sunxi_pinctrl_desc {int npins;unsigned pin_base;unsigned irq_banks; +unsigned irq_bank_base;bool irq_read_needs_mux; };
@@ -233,12 +234,12 @@ static inline u32 sunxi_pull_offset(u16return pin_num *PULL_PINS_BITS ; } -static inline u32 sunxi_irq_cfg_reg (u16 irq) +static inline u32 sunxi_irq_cfg_reg (u16 irq,unsigned bank_base) {u8 bank = irq /IRQ_PER_BANK ;u8 reg = (irq %IRQ_PER_BANK ) /IRQ_CFG_IRQ_PER_REG *0x04 ; -return IRQ_CFG_REG + bank *IRQ_MEM_SIZE + reg; +return IRQ_CFG_REG + (bank_base + bank) *IRQ_MEM_SIZE + reg; }static inline u32 sunxi_irq_cfg_offset (u16 irq)
@@ -247,16 +248,16 @@ static inline u32 sunxi_irq_cfg_offset(ureturn irq_num *IRQ_CFG_IRQ_BITS ; } -static inline u32 sunxi_irq_ctrl_reg_from_bank (u8 bank) +static inline u32 sunxi_irq_ctrl_reg_from_bank (u8 bank,unsigned bank_base) { -return IRQ_CTRL_REG + bank *IRQ_MEM_SIZE ; +return IRQ_CTRL_REG + (bank_base + bank) *IRQ_MEM_SIZE ; } -static inline u32 sunxi_irq_ctrl_reg (u16 irq) +static inline u32 sunxi_irq_ctrl_reg (u16 irq,unsigned bank_base) {u8 bank = irq /IRQ_PER_BANK ; -return sunxi_irq_ctrl_reg_from_bank (bank); +return sunxi_irq_ctrl_reg_from_bank (bank, bank_base); }static inline u32 sunxi_irq_ctrl_offset (u16 irq)
@@ -265,16 +266,16 @@ static inline u32 sunxi_irq_ctrl_offset(return irq_num *IRQ_CTRL_IRQ_BITS ; } -static inline u32 sunxi_irq_status_reg_from_bank (u8 bank) +static inline u32 sunxi_irq_status_reg_from_bank (u8 bank,unsigned bank_base) { -return IRQ_STATUS_REG + bank *IRQ_MEM_SIZE ; +return IRQ_STATUS_REG + (bank_base + bank) *IRQ_MEM_SIZE ; } -static inline u32 sunxi_irq_status_reg (u16 irq) +static inline u32 sunxi_irq_status_reg (u16 irq,unsigned bank_base) {u8 bank = irq /IRQ_PER_BANK ; -return sunxi_irq_status_reg_from_bank (bank); +return sunxi_irq_status_reg_from_bank (bank, bank_base); }static inline u32 sunxi_irq_status_offset (u16 irq)
Patches currently in stable-queue which might be from [email protected] are
queue-4.4/usb-uas-limit-qdepth-at-the-scsi-host-level.patch queue-4.4/usb-uas-add-a-new-no_report_luns-quirk.patch queue-4.4/pinctrl-sunxi-fix-a33-external-interrupts-not-working.patch