Skip to content

Instantly share code, notes, and snippets.

Created December 18, 2012 05:44
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/4325369 to your computer and use it in GitHub Desktop.
Save anonymous/4325369 to your computer and use it in GitHub Desktop.
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index ab243b8..cb1d8e8 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -20,7 +20,7 @@
#include <linux/platform_device.h>
#include <linux/spinlock.h>
#include <linux/uaccess.h>
-
+#include <linux/irq.h>
#include <asm/cputype.h>
#include <asm/irq.h>
#include <asm/irq_regs.h>
@@ -413,17 +413,26 @@ armpmu_reserve_hardware(struct arm_pmu *armpmu)
}
for (i = 0; i < irqs; ++i) {
+ struct irq_data *irq_data;
+ struct irq_chip *chip;
+
err = 0;
irq = platform_get_irq(pmu_device, i);
if (irq < 0)
continue;
+ irq_data = irq_get_irq_data(irq);
+ chip = irq_get_chip(irq);
+
/*
* If we have a single PMU interrupt that we can't shift,
* assume that we're running on a uniprocessor machine and
* continue. Otherwise, continue without this interrupt.
*/
- if (irq_set_affinity(irq, cpumask_of(i)) && irqs > 1) {
+ if (chip && chip->irq_set_affinity &&
+ chip->irq_set_affinity(irq_data, cpumask_of(i), 1) && irqs > 1)
+ {
+ /* WARN: chained irq must set affinity of the parent chip */
pr_warning("unable to set irq affinity (irq=%d, cpu=%u)\n",
irq, i);
continue;
diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c
index 6ed9369..ee9777b 100644
--- a/arch/arm/mach-exynos/common.c
+++ b/arch/arm/mach-exynos/common.c
@@ -587,6 +587,29 @@ static void __init combiner_init(void __iomem *combiner_base,
return;
}
+ /**
+ * Special handling for enabling group 16-19
+ *
+ * G(19) - IRQ_SPI(42)
+ * G(18) - IRQ_SPI(48)
+ * G(16) - IRQ_SPI(107)
+ * G(17) - IRQ_SPI(108)
+ *
+ * Ref: Exynos4412 User Manul. Table 6-2
+ *
+ */
+ if (soc_is_exynos4412()) {
+ combiner_init_one(19, combiner_base + (19 >> 2) * 0x10);
+ combiner_cascade_irq(19, IRQ_SPI(42));
+ combiner_init_one(18, combiner_base + (18 >> 2) * 0x10);
+ combiner_cascade_irq(18, IRQ_SPI(48));
+ combiner_init_one(16, combiner_base + (16 >> 2) * 0x10);
+ combiner_cascade_irq(16, IRQ_SPI(107));
+ combiner_init_one(17, combiner_base + (17 >> 2) * 0x10);
+ combiner_cascade_irq(17, IRQ_SPI(108));
+ max_nr -= 4;
+ }
+
for (i = 0; i < max_nr; i++) {
combiner_init_one(i, combiner_base + (i >> 2) * 0x10);
irq = IRQ_SPI(i);
@@ -732,6 +755,21 @@ static int __init exynos_init(void)
{
printk(KERN_INFO "EXYNOS: Initializing architecture\n");
+ if (soc_is_exynos4412()) {
+ int pmu_intrs[] = {34, 35, 80, 74};
+ int pmu_cpus [] = { 0, 1, 2, 3};
+ int i, err;
+ struct irq_chip *gic_chip = irq_get_chip(IRQ_SPI(0));
+ for (i = 0; i < 4; i++) {
+ int irq = pmu_intrs[i];
+ int cpu = pmu_cpus [i];
+ struct irq_data *irq_data = irq_get_irq_data(irq);
+ err = gic_chip->irq_set_affinity(irq_data, cpumask_of(cpu), 1);
+ if (err)
+ pr_warning("unable to set affinity (irq=%d, cpu=%u)\n",
+ irq, cpu);
+ }
+ }
return device_register(&exynos4_dev);
}
diff --git a/arch/arm/mach-exynos/include/mach/irqs.h b/arch/arm/mach-exynos/include/mac\
h/irqs.h
index 35bced6..2967f56 100644
--- a/arch/arm/mach-exynos/include/mach/irqs.h
+++ b/arch/arm/mach-exynos/include/mach/irqs.h
@@ -136,6 +136,12 @@
#define EXYNOS4_IRQ_TSI IRQ_SPI(115)
#define EXYNOS4_IRQ_SATA IRQ_SPI(116)
+/* Per-cpu performance counter interrupt. */
+#define EXYNOS4_IRQ_PMUIRQ_0 COMBINER_IRQ(2,2)
+#define EXYNOS4_IRQ_PMUIRQ_1 COMBINER_IRQ(3,2)
+#define EXYNOS4_IRQ_PMUIRQ_2 COMBINER_IRQ(18,2)
+#define EXYNOS4_IRQ_PMUIRQ_3 COMBINER_IRQ(19,2)
+
#define EXYNOS4_IRQ_SYSMMU_MDMA0_0 COMBINER_IRQ(4, 0)
#define EXYNOS4_IRQ_SYSMMU_SSS_0 COMBINER_IRQ(4, 1)
#define EXYNOS4_IRQ_SYSMMU_FIMC0_0 COMBINER_IRQ(4, 2)
@@ -165,7 +171,7 @@
#define EXYNOS4_IRQ_FIMD0_VSYNC COMBINER_IRQ(11, 1)
#define EXYNOS4_IRQ_FIMD0_SYSTEM COMBINER_IRQ(11, 2)
-#define EXYNOS4_MAX_COMBINER_NR 16
+#define EXYNOS4_MAX_COMBINER_NR 20
#define EXYNOS4_IRQ_GPIO1_NR_GROUPS 16
#define EXYNOS4_IRQ_GPIO2_NR_GROUPS 9
diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c
index 6185dcf..4384719 100644
--- a/arch/arm/plat-samsung/devs.c
+++ b/arch/arm/plat-samsung/devs.c
@@ -1129,7 +1129,10 @@ struct platform_device s5p_device_onenand = {
#ifdef CONFIG_PLAT_S5P
static struct resource s5p_pmu_resource[] = {
- DEFINE_RES_IRQ(IRQ_PMU)
+ [0] = DEFINE_RES_IRQ(EXYNOS4_IRQ_PMUIRQ_0),
+ [1] = DEFINE_RES_IRQ(EXYNOS4_IRQ_PMUIRQ_1),
+ [2] = DEFINE_RES_IRQ(EXYNOS4_IRQ_PMUIRQ_2),
+ [3] = DEFINE_RES_IRQ(EXYNOS4_IRQ_PMUIRQ_3),
};
static struct platform_device s5p_device_pmu = {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment