diff options
Diffstat (limited to 'drivers/irqchip/irq-stm32-exti.c')
| -rw-r--r-- | drivers/irqchip/irq-stm32-exti.c | 250 | 
1 files changed, 124 insertions, 126 deletions
diff --git a/drivers/irqchip/irq-stm32-exti.c b/drivers/irqchip/irq-stm32-exti.c index 9d18f47040eb..a73763d475f0 100644 --- a/drivers/irqchip/irq-stm32-exti.c +++ b/drivers/irqchip/irq-stm32-exti.c @@ -34,21 +34,15 @@ struct stm32_exti_bank {  	u32 swier_ofst;  	u32 rpr_ofst;  	u32 fpr_ofst; +	u32 trg_ofst;  };  #define UNDEF_REG ~0 -struct stm32_desc_irq { -	u32 exti; -	u32 irq_parent; -	struct irq_chip *chip; -}; -  struct stm32_exti_drv_data {  	const struct stm32_exti_bank **exti_banks; -	const struct stm32_desc_irq *desc_irqs; +	const u8 *desc_irqs;  	u32 bank_nr; -	u32 irq_nr;  };  struct stm32_exti_chip_data { @@ -78,6 +72,7 @@ static const struct stm32_exti_bank stm32f4xx_exti_b1 = {  	.swier_ofst	= 0x10,  	.rpr_ofst	= 0x14,  	.fpr_ofst	= UNDEF_REG, +	.trg_ofst	= UNDEF_REG,  };  static const struct stm32_exti_bank *stm32f4xx_exti_banks[] = { @@ -97,6 +92,7 @@ static const struct stm32_exti_bank stm32h7xx_exti_b1 = {  	.swier_ofst	= 0x08,  	.rpr_ofst	= 0x88,  	.fpr_ofst	= UNDEF_REG, +	.trg_ofst	= UNDEF_REG,  };  static const struct stm32_exti_bank stm32h7xx_exti_b2 = { @@ -107,6 +103,7 @@ static const struct stm32_exti_bank stm32h7xx_exti_b2 = {  	.swier_ofst	= 0x28,  	.rpr_ofst	= 0x98,  	.fpr_ofst	= UNDEF_REG, +	.trg_ofst	= UNDEF_REG,  };  static const struct stm32_exti_bank stm32h7xx_exti_b3 = { @@ -117,6 +114,7 @@ static const struct stm32_exti_bank stm32h7xx_exti_b3 = {  	.swier_ofst	= 0x48,  	.rpr_ofst	= 0xA8,  	.fpr_ofst	= UNDEF_REG, +	.trg_ofst	= UNDEF_REG,  };  static const struct stm32_exti_bank *stm32h7xx_exti_banks[] = { @@ -132,32 +130,35 @@ static const struct stm32_exti_drv_data stm32h7xx_drv_data = {  static const struct stm32_exti_bank stm32mp1_exti_b1 = {  	.imr_ofst	= 0x80, -	.emr_ofst	= 0x84, +	.emr_ofst	= UNDEF_REG,  	.rtsr_ofst	= 0x00,  	.ftsr_ofst	= 0x04,  	.swier_ofst	= 0x08,  	.rpr_ofst	= 0x0C,  	.fpr_ofst	= 0x10, +	.trg_ofst	= 0x3EC,  };  static const struct stm32_exti_bank stm32mp1_exti_b2 = {  	.imr_ofst	= 0x90, -	.emr_ofst	= 0x94, +	.emr_ofst	= UNDEF_REG,  	.rtsr_ofst	= 0x20,  	.ftsr_ofst	= 0x24,  	.swier_ofst	= 0x28,  	.rpr_ofst	= 0x2C,  	.fpr_ofst	= 0x30, +	.trg_ofst	= 0x3E8,  };  static const struct stm32_exti_bank stm32mp1_exti_b3 = {  	.imr_ofst	= 0xA0, -	.emr_ofst	= 0xA4, +	.emr_ofst	= UNDEF_REG,  	.rtsr_ofst	= 0x40,  	.ftsr_ofst	= 0x44,  	.swier_ofst	= 0x48,  	.rpr_ofst	= 0x4C,  	.fpr_ofst	= 0x50, +	.trg_ofst	= 0x3E4,  };  static const struct stm32_exti_bank *stm32mp1_exti_banks[] = { @@ -169,126 +170,114 @@ static const struct stm32_exti_bank *stm32mp1_exti_banks[] = {  static struct irq_chip stm32_exti_h_chip;  static struct irq_chip stm32_exti_h_chip_direct; -static const struct stm32_desc_irq stm32mp1_desc_irq[] = { -	{ .exti = 0, .irq_parent = 6, .chip = &stm32_exti_h_chip }, -	{ .exti = 1, .irq_parent = 7, .chip = &stm32_exti_h_chip }, -	{ .exti = 2, .irq_parent = 8, .chip = &stm32_exti_h_chip }, -	{ .exti = 3, .irq_parent = 9, .chip = &stm32_exti_h_chip }, -	{ .exti = 4, .irq_parent = 10, .chip = &stm32_exti_h_chip }, -	{ .exti = 5, .irq_parent = 23, .chip = &stm32_exti_h_chip }, -	{ .exti = 6, .irq_parent = 64, .chip = &stm32_exti_h_chip }, -	{ .exti = 7, .irq_parent = 65, .chip = &stm32_exti_h_chip }, -	{ .exti = 8, .irq_parent = 66, .chip = &stm32_exti_h_chip }, -	{ .exti = 9, .irq_parent = 67, .chip = &stm32_exti_h_chip }, -	{ .exti = 10, .irq_parent = 40, .chip = &stm32_exti_h_chip }, -	{ .exti = 11, .irq_parent = 42, .chip = &stm32_exti_h_chip }, -	{ .exti = 12, .irq_parent = 76, .chip = &stm32_exti_h_chip }, -	{ .exti = 13, .irq_parent = 77, .chip = &stm32_exti_h_chip }, -	{ .exti = 14, .irq_parent = 121, .chip = &stm32_exti_h_chip }, -	{ .exti = 15, .irq_parent = 127, .chip = &stm32_exti_h_chip }, -	{ .exti = 16, .irq_parent = 1, .chip = &stm32_exti_h_chip }, -	{ .exti = 19, .irq_parent = 3, .chip = &stm32_exti_h_chip_direct }, -	{ .exti = 21, .irq_parent = 31, .chip = &stm32_exti_h_chip_direct }, -	{ .exti = 22, .irq_parent = 33, .chip = &stm32_exti_h_chip_direct }, -	{ .exti = 23, .irq_parent = 72, .chip = &stm32_exti_h_chip_direct }, -	{ .exti = 24, .irq_parent = 95, .chip = &stm32_exti_h_chip_direct }, -	{ .exti = 25, .irq_parent = 107, .chip = &stm32_exti_h_chip_direct }, -	{ .exti = 26, .irq_parent = 37, .chip = &stm32_exti_h_chip_direct }, -	{ .exti = 27, .irq_parent = 38, .chip = &stm32_exti_h_chip_direct }, -	{ .exti = 28, .irq_parent = 39, .chip = &stm32_exti_h_chip_direct }, -	{ .exti = 29, .irq_parent = 71, .chip = &stm32_exti_h_chip_direct }, -	{ .exti = 30, .irq_parent = 52, .chip = &stm32_exti_h_chip_direct }, -	{ .exti = 31, .irq_parent = 53, .chip = &stm32_exti_h_chip_direct }, -	{ .exti = 32, .irq_parent = 82, .chip = &stm32_exti_h_chip_direct }, -	{ .exti = 33, .irq_parent = 83, .chip = &stm32_exti_h_chip_direct }, -	{ .exti = 47, .irq_parent = 93, .chip = &stm32_exti_h_chip_direct }, -	{ .exti = 48, .irq_parent = 138, .chip = &stm32_exti_h_chip_direct }, -	{ .exti = 50, .irq_parent = 139, .chip = &stm32_exti_h_chip_direct }, -	{ .exti = 52, .irq_parent = 140, .chip = &stm32_exti_h_chip_direct }, -	{ .exti = 53, .irq_parent = 141, .chip = &stm32_exti_h_chip_direct }, -	{ .exti = 54, .irq_parent = 135, .chip = &stm32_exti_h_chip_direct }, -	{ .exti = 61, .irq_parent = 100, .chip = &stm32_exti_h_chip_direct }, -	{ .exti = 65, .irq_parent = 144, .chip = &stm32_exti_h_chip }, -	{ .exti = 68, .irq_parent = 143, .chip = &stm32_exti_h_chip }, -	{ .exti = 70, .irq_parent = 62, .chip = &stm32_exti_h_chip_direct }, -	{ .exti = 73, .irq_parent = 129, .chip = &stm32_exti_h_chip }, +#define EXTI_INVALID_IRQ       U8_MAX +#define STM32MP1_DESC_IRQ_SIZE (ARRAY_SIZE(stm32mp1_exti_banks) * IRQS_PER_BANK) + +static const u8 stm32mp1_desc_irq[] = { +	/* default value */ +	[0 ... (STM32MP1_DESC_IRQ_SIZE - 1)] = EXTI_INVALID_IRQ, + +	[0] = 6, +	[1] = 7, +	[2] = 8, +	[3] = 9, +	[4] = 10, +	[5] = 23, +	[6] = 64, +	[7] = 65, +	[8] = 66, +	[9] = 67, +	[10] = 40, +	[11] = 42, +	[12] = 76, +	[13] = 77, +	[14] = 121, +	[15] = 127, +	[16] = 1, +	[19] = 3, +	[21] = 31, +	[22] = 33, +	[23] = 72, +	[24] = 95, +	[25] = 107, +	[26] = 37, +	[27] = 38, +	[28] = 39, +	[29] = 71, +	[30] = 52, +	[31] = 53, +	[32] = 82, +	[33] = 83, +	[47] = 93, +	[48] = 138, +	[50] = 139, +	[52] = 140, +	[53] = 141, +	[54] = 135, +	[61] = 100, +	[65] = 144, +	[68] = 143, +	[70] = 62, +	[73] = 129,  }; -static const struct stm32_desc_irq stm32mp13_desc_irq[] = { -	{ .exti = 0, .irq_parent = 6, .chip = &stm32_exti_h_chip }, -	{ .exti = 1, .irq_parent = 7, .chip = &stm32_exti_h_chip }, -	{ .exti = 2, .irq_parent = 8, .chip = &stm32_exti_h_chip }, -	{ .exti = 3, .irq_parent = 9, .chip = &stm32_exti_h_chip }, -	{ .exti = 4, .irq_parent = 10, .chip = &stm32_exti_h_chip }, -	{ .exti = 5, .irq_parent = 24, .chip = &stm32_exti_h_chip }, -	{ .exti = 6, .irq_parent = 65, .chip = &stm32_exti_h_chip }, -	{ .exti = 7, .irq_parent = 66, .chip = &stm32_exti_h_chip }, -	{ .exti = 8, .irq_parent = 67, .chip = &stm32_exti_h_chip }, -	{ .exti = 9, .irq_parent = 68, .chip = &stm32_exti_h_chip }, -	{ .exti = 10, .irq_parent = 41, .chip = &stm32_exti_h_chip }, -	{ .exti = 11, .irq_parent = 43, .chip = &stm32_exti_h_chip }, -	{ .exti = 12, .irq_parent = 77, .chip = &stm32_exti_h_chip }, -	{ .exti = 13, .irq_parent = 78, .chip = &stm32_exti_h_chip }, -	{ .exti = 14, .irq_parent = 106, .chip = &stm32_exti_h_chip }, -	{ .exti = 15, .irq_parent = 109, .chip = &stm32_exti_h_chip }, -	{ .exti = 16, .irq_parent = 1, .chip = &stm32_exti_h_chip }, -	{ .exti = 19, .irq_parent = 3, .chip = &stm32_exti_h_chip_direct }, -	{ .exti = 21, .irq_parent = 32, .chip = &stm32_exti_h_chip_direct }, -	{ .exti = 22, .irq_parent = 34, .chip = &stm32_exti_h_chip_direct }, -	{ .exti = 23, .irq_parent = 73, .chip = &stm32_exti_h_chip_direct }, -	{ .exti = 24, .irq_parent = 93, .chip = &stm32_exti_h_chip_direct }, -	{ .exti = 25, .irq_parent = 114, .chip = &stm32_exti_h_chip_direct }, -	{ .exti = 26, .irq_parent = 38, .chip = &stm32_exti_h_chip_direct }, -	{ .exti = 27, .irq_parent = 39, .chip = &stm32_exti_h_chip_direct }, -	{ .exti = 28, .irq_parent = 40, .chip = &stm32_exti_h_chip_direct }, -	{ .exti = 29, .irq_parent = 72, .chip = &stm32_exti_h_chip_direct }, -	{ .exti = 30, .irq_parent = 53, .chip = &stm32_exti_h_chip_direct }, -	{ .exti = 31, .irq_parent = 54, .chip = &stm32_exti_h_chip_direct }, -	{ .exti = 32, .irq_parent = 83, .chip = &stm32_exti_h_chip_direct }, -	{ .exti = 33, .irq_parent = 84, .chip = &stm32_exti_h_chip_direct }, -	{ .exti = 44, .irq_parent = 96, .chip = &stm32_exti_h_chip_direct }, -	{ .exti = 47, .irq_parent = 92, .chip = &stm32_exti_h_chip_direct }, -	{ .exti = 48, .irq_parent = 116, .chip = &stm32_exti_h_chip_direct }, -	{ .exti = 50, .irq_parent = 117, .chip = &stm32_exti_h_chip_direct }, -	{ .exti = 52, .irq_parent = 118, .chip = &stm32_exti_h_chip_direct }, -	{ .exti = 53, .irq_parent = 119, .chip = &stm32_exti_h_chip_direct }, -	{ .exti = 68, .irq_parent = 63, .chip = &stm32_exti_h_chip_direct }, -	{ .exti = 70, .irq_parent = 98, .chip = &stm32_exti_h_chip_direct }, +static const u8 stm32mp13_desc_irq[] = { +	/* default value */ +	[0 ... (STM32MP1_DESC_IRQ_SIZE - 1)] = EXTI_INVALID_IRQ, + +	[0] = 6, +	[1] = 7, +	[2] = 8, +	[3] = 9, +	[4] = 10, +	[5] = 24, +	[6] = 65, +	[7] = 66, +	[8] = 67, +	[9] = 68, +	[10] = 41, +	[11] = 43, +	[12] = 77, +	[13] = 78, +	[14] = 106, +	[15] = 109, +	[16] = 1, +	[19] = 3, +	[21] = 32, +	[22] = 34, +	[23] = 73, +	[24] = 93, +	[25] = 114, +	[26] = 38, +	[27] = 39, +	[28] = 40, +	[29] = 72, +	[30] = 53, +	[31] = 54, +	[32] = 83, +	[33] = 84, +	[44] = 96, +	[47] = 92, +	[48] = 116, +	[50] = 117, +	[52] = 118, +	[53] = 119, +	[68] = 63, +	[70] = 98,  };  static const struct stm32_exti_drv_data stm32mp1_drv_data = {  	.exti_banks = stm32mp1_exti_banks,  	.bank_nr = ARRAY_SIZE(stm32mp1_exti_banks),  	.desc_irqs = stm32mp1_desc_irq, -	.irq_nr = ARRAY_SIZE(stm32mp1_desc_irq),  };  static const struct stm32_exti_drv_data stm32mp13_drv_data = {  	.exti_banks = stm32mp1_exti_banks,  	.bank_nr = ARRAY_SIZE(stm32mp1_exti_banks),  	.desc_irqs = stm32mp13_desc_irq, -	.irq_nr = ARRAY_SIZE(stm32mp13_desc_irq),  }; -static const struct -stm32_desc_irq *stm32_exti_get_desc(const struct stm32_exti_drv_data *drv_data, -				    irq_hw_number_t hwirq) -{ -	const struct stm32_desc_irq *desc = NULL; -	int i; - -	if (!drv_data->desc_irqs) -		return NULL; - -	for (i = 0; i < drv_data->irq_nr; i++) { -		desc = &drv_data->desc_irqs[i]; -		if (desc->exti == hwirq) -			break; -	} - -	return desc; -} -  static unsigned long stm32_exti_pending(struct irq_chip_generic *gc)  {  	struct stm32_exti_chip_data *chip_data = gc->private; @@ -614,7 +603,7 @@ static int stm32_exti_h_set_affinity(struct irq_data *d,  	if (d->parent_data->chip)  		return irq_chip_set_affinity_parent(d, dest, force); -	return -EINVAL; +	return IRQ_SET_MASK_OK_DONE;  }  static int __maybe_unused stm32_exti_h_suspend(void) @@ -691,8 +680,8 @@ static struct irq_chip stm32_exti_h_chip_direct = {  	.name			= "stm32-exti-h-direct",  	.irq_eoi		= irq_chip_eoi_parent,  	.irq_ack		= irq_chip_ack_parent, -	.irq_mask		= irq_chip_mask_parent, -	.irq_unmask		= irq_chip_unmask_parent, +	.irq_mask		= stm32_exti_h_mask, +	.irq_unmask		= stm32_exti_h_unmask,  	.irq_retrigger		= irq_chip_retrigger_hierarchy,  	.irq_set_type		= irq_chip_set_type_parent,  	.irq_set_wake		= stm32_exti_h_set_wake, @@ -706,28 +695,36 @@ static int stm32_exti_h_domain_alloc(struct irq_domain *dm,  {  	struct stm32_exti_host_data *host_data = dm->host_data;  	struct stm32_exti_chip_data *chip_data; -	const struct stm32_desc_irq *desc; +	u8 desc_irq;  	struct irq_fwspec *fwspec = data;  	struct irq_fwspec p_fwspec;  	irq_hw_number_t hwirq;  	int bank; +	u32 event_trg; +	struct irq_chip *chip;  	hwirq = fwspec->param[0]; +	if (hwirq >= host_data->drv_data->bank_nr * IRQS_PER_BANK) +		return -EINVAL; +  	bank  = hwirq / IRQS_PER_BANK;  	chip_data = &host_data->chips_data[bank]; +	event_trg = readl_relaxed(host_data->base + chip_data->reg_bank->trg_ofst); +	chip = (event_trg & BIT(hwirq % IRQS_PER_BANK)) ? +	       &stm32_exti_h_chip : &stm32_exti_h_chip_direct; + +	irq_domain_set_hwirq_and_chip(dm, virq, hwirq, chip, chip_data); -	desc = stm32_exti_get_desc(host_data->drv_data, hwirq); -	if (!desc) +	if (!host_data->drv_data || !host_data->drv_data->desc_irqs)  		return -EINVAL; -	irq_domain_set_hwirq_and_chip(dm, virq, hwirq, desc->chip, -				      chip_data); -	if (desc->irq_parent) { +	desc_irq = host_data->drv_data->desc_irqs[hwirq]; +	if (desc_irq != EXTI_INVALID_IRQ) {  		p_fwspec.fwnode = dm->parent->fwnode;  		p_fwspec.param_count = 3;  		p_fwspec.param[0] = GIC_SPI; -		p_fwspec.param[1] = desc->irq_parent; +		p_fwspec.param[1] = desc_irq;  		p_fwspec.param[2] = IRQ_TYPE_LEVEL_HIGH;  		return irq_domain_alloc_irqs_parent(dm, virq, 1, &p_fwspec); @@ -792,7 +789,8 @@ stm32_exti_chip_data *stm32_exti_chip_init(struct stm32_exti_host_data *h_data,  	 * clear registers to avoid residue  	 */  	writel_relaxed(0, base + stm32_bank->imr_ofst); -	writel_relaxed(0, base + stm32_bank->emr_ofst); +	if (stm32_bank->emr_ofst != UNDEF_REG) +		writel_relaxed(0, base + stm32_bank->emr_ofst);  	pr_info("%pOF: bank%d\n", node, bank_idx);  |