Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mfd: intel_soc_pmic_bxtwc: Chain power button IRQs as well

Power button IRQ actually has a second level of interrupts to
distinguish between UI and POWER buttons. Moreover, current
implementation looks awkward in approach to handle second level IRQs by
first level related IRQ chip.

To address above issues, split power button IRQ to be chained as well.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>

authored by

Andy Shevchenko and committed by
Lee Jones
9f8ddee1 8bd2d03e

+32 -10
+31 -10
drivers/mfd/intel_soc_pmic_bxtwc.c
··· 31 31 32 32 /* Interrupt Status Registers */ 33 33 #define BXTWC_IRQLVL1 0x4E02 34 - #define BXTWC_PWRBTNIRQ 0x4E03 35 34 35 + #define BXTWC_PWRBTNIRQ 0x4E03 36 36 #define BXTWC_THRM0IRQ 0x4E04 37 37 #define BXTWC_THRM1IRQ 0x4E05 38 38 #define BXTWC_THRM2IRQ 0x4E06 ··· 47 47 48 48 /* Interrupt MASK Registers */ 49 49 #define BXTWC_MIRQLVL1 0x4E0E 50 - #define BXTWC_MPWRTNIRQ 0x4E0F 51 - 52 50 #define BXTWC_MIRQLVL1_MCHGR BIT(5) 53 51 52 + #define BXTWC_MPWRBTNIRQ 0x4E0F 54 53 #define BXTWC_MTHRM0IRQ 0x4E12 55 54 #define BXTWC_MTHRM1IRQ 0x4E13 56 55 #define BXTWC_MTHRM2IRQ 0x4E14 ··· 65 66 /* Whiskey Cove PMIC share same ACPI ID between different platforms */ 66 67 #define BROXTON_PMIC_WC_HRV 4 67 68 68 - /* Manage in two IRQ chips since mask registers are not consecutive */ 69 69 enum bxtwc_irqs { 70 - /* Level 1 */ 71 70 BXTWC_PWRBTN_LVL1_IRQ = 0, 72 71 BXTWC_TMU_LVL1_IRQ, 73 72 BXTWC_THRM_LVL1_IRQ, ··· 74 77 BXTWC_CHGR_LVL1_IRQ, 75 78 BXTWC_GPIO_LVL1_IRQ, 76 79 BXTWC_CRIT_LVL1_IRQ, 80 + }; 77 81 78 - /* Level 2 */ 79 - BXTWC_PWRBTN_IRQ, 82 + enum bxtwc_irqs_pwrbtn { 83 + BXTWC_PWRBTN_IRQ = 0, 84 + BXTWC_UIBTN_IRQ, 80 85 }; 81 86 82 87 enum bxtwc_irqs_bcu { ··· 112 113 REGMAP_IRQ_REG(BXTWC_CHGR_LVL1_IRQ, 0, BIT(5)), 113 114 REGMAP_IRQ_REG(BXTWC_GPIO_LVL1_IRQ, 0, BIT(6)), 114 115 REGMAP_IRQ_REG(BXTWC_CRIT_LVL1_IRQ, 0, BIT(7)), 115 - REGMAP_IRQ_REG(BXTWC_PWRBTN_IRQ, 1, 0x03), 116 + }; 117 + 118 + static const struct regmap_irq bxtwc_regmap_irqs_pwrbtn[] = { 119 + REGMAP_IRQ_REG(BXTWC_PWRBTN_IRQ, 0, 0x01), 116 120 }; 117 121 118 122 static const struct regmap_irq bxtwc_regmap_irqs_bcu[] = { ··· 127 125 }; 128 126 129 127 static const struct regmap_irq bxtwc_regmap_irqs_chgr[] = { 130 - REGMAP_IRQ_REG(BXTWC_USBC_IRQ, 0, BIT(5)), 128 + REGMAP_IRQ_REG(BXTWC_USBC_IRQ, 0, 0x20), 131 129 REGMAP_IRQ_REG(BXTWC_CHGR0_IRQ, 0, 0x1f), 132 130 REGMAP_IRQ_REG(BXTWC_CHGR1_IRQ, 1, 0x1f), 133 131 }; ··· 146 144 .mask_base = BXTWC_MIRQLVL1, 147 145 .irqs = bxtwc_regmap_irqs, 148 146 .num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs), 149 - .num_regs = 2, 147 + .num_regs = 1, 148 + }; 149 + 150 + static struct regmap_irq_chip bxtwc_regmap_irq_chip_pwrbtn = { 151 + .name = "bxtwc_irq_chip_pwrbtn", 152 + .status_base = BXTWC_PWRBTNIRQ, 153 + .mask_base = BXTWC_MPWRBTNIRQ, 154 + .irqs = bxtwc_regmap_irqs_pwrbtn, 155 + .num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_pwrbtn), 156 + .num_regs = 1, 150 157 }; 151 158 152 159 static struct regmap_irq_chip bxtwc_regmap_irq_chip_tmu = { ··· 480 469 &pmic->irq_chip_data); 481 470 if (ret) { 482 471 dev_err(&pdev->dev, "Failed to add IRQ chip\n"); 472 + return ret; 473 + } 474 + 475 + ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data, 476 + BXTWC_PWRBTN_LVL1_IRQ, 477 + IRQF_ONESHOT, 478 + &bxtwc_regmap_irq_chip_pwrbtn, 479 + &pmic->irq_chip_data_pwrbtn); 480 + if (ret) { 481 + dev_err(&pdev->dev, "Failed to add PWRBTN IRQ chip\n"); 483 482 return ret; 484 483 } 485 484
+1
include/linux/mfd/intel_soc_pmic.h
··· 25 25 int irq; 26 26 struct regmap *regmap; 27 27 struct regmap_irq_chip_data *irq_chip_data; 28 + struct regmap_irq_chip_data *irq_chip_data_pwrbtn; 28 29 struct regmap_irq_chip_data *irq_chip_data_tmu; 29 30 struct regmap_irq_chip_data *irq_chip_data_bcu; 30 31 struct regmap_irq_chip_data *irq_chip_data_adc;