1 /* 2 * Special GIC quirks for the ARM RealView 3 * Copyright (C) 2015 Linus Walleij 4 */ 5 #include <linux/of.h> 6 #include <linux/regmap.h> 7 #include <linux/mfd/syscon.h> 8 #include <linux/bitops.h> 9 #include <linux/irqchip.h> 10 #include <linux/irqchip/arm-gic.h> 11 12 #define REALVIEW_SYS_LOCK_OFFSET 0x20 13 #define REALVIEW_SYS_PLD_CTRL1 0x74 14 #define REALVIEW_EB_REVB_SYS_PLD_CTRL1 0xD8 15 #define VERSATILE_LOCK_VAL 0xA05F 16 #define PLD_INTMODE_MASK BIT(22)|BIT(23)|BIT(24) 17 #define PLD_INTMODE_LEGACY 0x0 18 #define PLD_INTMODE_NEW_DCC BIT(22) 19 #define PLD_INTMODE_NEW_NO_DCC BIT(23) 20 #define PLD_INTMODE_FIQ_ENABLE BIT(24) 21 22 /* For some reason RealView EB Rev B moved this register */ 23 static const struct of_device_id syscon_pldset_of_match[] = { 24 { 25 .compatible = "arm,realview-eb11mp-revb-syscon", 26 .data = (void *)REALVIEW_EB_REVB_SYS_PLD_CTRL1, 27 }, 28 { 29 .compatible = "arm,realview-eb11mp-revc-syscon", 30 .data = (void *)REALVIEW_SYS_PLD_CTRL1, 31 }, 32 { 33 .compatible = "arm,realview-eb-syscon", 34 .data = (void *)REALVIEW_SYS_PLD_CTRL1, 35 }, 36 { 37 .compatible = "arm,realview-pb11mp-syscon", 38 .data = (void *)REALVIEW_SYS_PLD_CTRL1, 39 }, 40 {}, 41 }; 42 43 static int __init 44 realview_gic_of_init(struct device_node *node, struct device_node *parent) 45 { 46 static struct regmap *map; 47 struct device_node *np; 48 const struct of_device_id *gic_id; 49 u32 pld1_ctrl; 50 51 np = of_find_matching_node_and_match(NULL, syscon_pldset_of_match, 52 &gic_id); 53 if (!np) 54 return -ENODEV; 55 pld1_ctrl = (u32)gic_id->data; 56 57 /* The PB11MPCore GIC needs to be configured in the syscon */ 58 map = syscon_node_to_regmap(np); 59 if (!IS_ERR(map)) { 60 /* new irq mode with no DCC */ 61 regmap_write(map, REALVIEW_SYS_LOCK_OFFSET, 62 VERSATILE_LOCK_VAL); 63 regmap_update_bits(map, pld1_ctrl, 64 PLD_INTMODE_NEW_NO_DCC, 65 PLD_INTMODE_MASK); 66 regmap_write(map, REALVIEW_SYS_LOCK_OFFSET, 0x0000); 67 pr_info("RealView GIC: set up interrupt controller to NEW mode, no DCC\n"); 68 } else { 69 pr_err("RealView GIC setup: could not find syscon\n"); 70 return -ENODEV; 71 } 72 return gic_of_init(node, parent); 73 } 74 IRQCHIP_DECLARE(armtc11mp_gic, "arm,tc11mp-gic", realview_gic_of_init); 75 IRQCHIP_DECLARE(armeb11mp_gic, "arm,eb11mp-gic", realview_gic_of_init); 76