Created
December 18, 2012 05:44
-
-
Save anonymous/4325369 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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