mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-06 10:00:17 +00:00
irqchip: irq-bcm2835: Add 2836 FIQ support
Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
This commit is contained in:
committed by
popcornmix
parent
17e9967782
commit
bb72f2ca3e
@@ -50,6 +50,8 @@
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/irqchip.h>
|
||||
#include <linux/irqdomain.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#include <asm/exception.h>
|
||||
#include <asm/mach/irq.h>
|
||||
@@ -70,6 +72,9 @@
|
||||
#define BANK0_VALID_MASK (BANK0_HWIRQ_MASK | BANK1_HWIRQ | BANK2_HWIRQ \
|
||||
| SHORTCUT1_MASK | SHORTCUT2_MASK)
|
||||
|
||||
#undef ARM_LOCAL_GPU_INT_ROUTING
|
||||
#define ARM_LOCAL_GPU_INT_ROUTING 0x0c
|
||||
|
||||
#define REG_FIQ_CONTROL 0x0c
|
||||
#define REG_FIQ_ENABLE 0x80
|
||||
#define REG_FIQ_DISABLE 0
|
||||
@@ -95,6 +100,7 @@ struct armctrl_ic {
|
||||
void __iomem *enable[NR_BANKS];
|
||||
void __iomem *disable[NR_BANKS];
|
||||
struct irq_domain *domain;
|
||||
struct regmap *local_regmap;
|
||||
};
|
||||
|
||||
static struct armctrl_ic intc __read_mostly;
|
||||
@@ -128,12 +134,35 @@ static void armctrl_mask_irq(struct irq_data *d)
|
||||
|
||||
static void armctrl_unmask_irq(struct irq_data *d)
|
||||
{
|
||||
if (d->hwirq >= NUMBER_IRQS)
|
||||
if (d->hwirq >= NUMBER_IRQS) {
|
||||
if (num_online_cpus() > 1) {
|
||||
unsigned int data;
|
||||
int ret;
|
||||
|
||||
if (!intc.local_regmap) {
|
||||
pr_err("FIQ is disabled due to missing regmap\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ret = regmap_read(intc.local_regmap,
|
||||
ARM_LOCAL_GPU_INT_ROUTING, &data);
|
||||
if (ret) {
|
||||
pr_err("Failed to read int routing %d\n", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
data &= ~0xc;
|
||||
data |= (1 << 2);
|
||||
regmap_write(intc.local_regmap,
|
||||
ARM_LOCAL_GPU_INT_ROUTING, data);
|
||||
}
|
||||
|
||||
writel_relaxed(REG_FIQ_ENABLE | hwirq_to_fiq(d->hwirq),
|
||||
intc.base + REG_FIQ_CONTROL);
|
||||
else
|
||||
} else {
|
||||
writel_relaxed(HWIRQ_BIT(d->hwirq),
|
||||
intc.enable[HWIRQ_BANK(d->hwirq)]);
|
||||
}
|
||||
}
|
||||
|
||||
static struct irq_chip armctrl_chip = {
|
||||
@@ -211,6 +240,15 @@ static int __init armctrl_of_init(struct device_node *node,
|
||||
set_handle_irq(bcm2835_handle_irq);
|
||||
}
|
||||
|
||||
if (is_2836) {
|
||||
intc.local_regmap =
|
||||
syscon_regmap_lookup_by_compatible("brcm,bcm2836-arm-local");
|
||||
if (IS_ERR(intc.local_regmap)) {
|
||||
pr_err("Failed to get local register map. FIQ is disabled for cpus > 1\n");
|
||||
intc.local_regmap = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Make a duplicate irq range which is used to enable FIQ */
|
||||
for (b = 0; b < NR_BANKS; b++) {
|
||||
for (i = 0; i < bank_irqs[b]; i++) {
|
||||
|
||||
Reference in New Issue
Block a user