Skip to content

Commit a7fa33c

Browse files
committed
Merge pull request #3 from sjoerd-ccu/endless
Fix PMU for perf
2 parents 5ae16a2 + 31a4465 commit a7fa33c

File tree

3 files changed

+96
-18
lines changed

3 files changed

+96
-18
lines changed

arch/arm/mach-exynos/common.c

Lines changed: 84 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include <mach/regs-pmu.h>
3838
#include <mach/regs-gpio.h>
3939
#include <mach/pmu.h>
40+
#include <mach/irqs.h>
4041

4142
#include <plat/cpu.h>
4243
#include <plat/clock.h>
@@ -496,6 +497,7 @@ struct combiner_chip_data {
496497
unsigned int irq_offset;
497498
unsigned int irq_mask;
498499
void __iomem *base;
500+
unsigned int parent_irq;
499501
};
500502

501503
static struct irq_domain *combiner_irq_domain;
@@ -552,35 +554,59 @@ static void combiner_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
552554
chained_irq_exit(chip, desc);
553555
}
554556

557+
#ifdef CONFIG_SMP
558+
static int combiner_set_affinity(struct irq_data *d,
559+
const struct cpumask *mask_val, bool force)
560+
{
561+
struct combiner_chip_data *chip_data = irq_data_get_irq_chip_data(d);
562+
struct irq_chip *chip = irq_get_chip(chip_data->parent_irq);
563+
struct irq_data *data = irq_get_irq_data(chip_data->parent_irq);
564+
565+
if (chip && chip->irq_set_affinity)
566+
return chip->irq_set_affinity(data, mask_val, force);
567+
else
568+
return -EINVAL;
569+
}
570+
#endif
571+
555572
static struct irq_chip combiner_chip = {
556573
.name = "COMBINER",
557574
.irq_mask = combiner_mask_irq,
558575
.irq_unmask = combiner_unmask_irq,
576+
#ifdef CONFIG_SMP
577+
.irq_set_affinity = combiner_set_affinity,
578+
#endif
559579
};
560580

561-
static void __init combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq)
581+
static unsigned int max_combiner_nr(void)
562582
{
563-
unsigned int max_nr;
564-
565583
if (soc_is_exynos5250())
566-
max_nr = EXYNOS5_MAX_COMBINER_NR;
584+
return EXYNOS5_MAX_COMBINER_NR;
585+
else if (soc_is_exynos4412())
586+
return EXYNOS4412_MAX_COMBINER_NR;
587+
else if (soc_is_exynos4212())
588+
return EXYNOS4212_MAX_COMBINER_NR;
567589
else
568-
max_nr = EXYNOS4_MAX_COMBINER_NR;
590+
return EXYNOS4210_MAX_COMBINER_NR;
591+
}
569592

570-
if (combiner_nr >= max_nr)
593+
static void __init combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq)
594+
{
595+
if (combiner_nr >= max_combiner_nr())
571596
BUG();
572597
if (irq_set_handler_data(irq, &combiner_data[combiner_nr]) != 0)
573598
BUG();
574599
irq_set_chained_handler(irq, combiner_handle_cascade_irq);
575600
}
576601

577602
static void __init combiner_init_one(unsigned int combiner_nr,
578-
void __iomem *base)
603+
void __iomem *base, unsigned int irq)
579604
{
580605
combiner_data[combiner_nr].base = base;
581606
combiner_data[combiner_nr].irq_offset = irq_find_mapping(
582607
combiner_irq_domain, combiner_nr * MAX_IRQ_IN_COMBINER);
583608
combiner_data[combiner_nr].irq_mask = 0xff << ((combiner_nr % 4) << 3);
609+
combiner_data[combiner_nr].parent_irq = irq;
584610

585611
/* Disable all interrupts */
586612
__raw_writel(combiner_data[combiner_nr].irq_mask,
@@ -631,22 +657,36 @@ static struct irq_domain_ops combiner_irq_domain_ops = {
631657
.map = combiner_irq_domain_map,
632658
};
633659

660+
static unsigned int exynos4x12_combiner_extra_irq(int group)
661+
{
662+
switch (group) {
663+
case 16:
664+
return IRQ_SPI(107);
665+
case 17:
666+
return IRQ_SPI(108);
667+
case 18:
668+
return IRQ_SPI(48);
669+
case 19:
670+
return IRQ_SPI(42);
671+
default:
672+
return 0;
673+
}
674+
}
675+
634676
static void __init combiner_init(void __iomem *combiner_base,
635677
struct device_node *np)
636678
{
637679
int i, irq, irq_base;
638680
unsigned int max_nr, nr_irq;
639681

682+
max_nr = max_combiner_nr();
683+
640684
if (np) {
641685
if (of_property_read_u32(np, "samsung,combiner-nr", &max_nr)) {
642686
pr_warning("%s: number of combiners not specified, "
643687
"setting default as %d.\n",
644-
__func__, EXYNOS4_MAX_COMBINER_NR);
645-
max_nr = EXYNOS4_MAX_COMBINER_NR;
688+
__func__, max_nr);
646689
}
647-
} else {
648-
max_nr = soc_is_exynos5250() ? EXYNOS5_MAX_COMBINER_NR :
649-
EXYNOS4_MAX_COMBINER_NR;
650690
}
651691
nr_irq = max_nr * MAX_IRQ_IN_COMBINER;
652692

@@ -664,13 +704,16 @@ static void __init combiner_init(void __iomem *combiner_base,
664704
}
665705

666706
for (i = 0; i < max_nr; i++) {
667-
combiner_init_one(i, combiner_base + (i >> 2) * 0x10);
668-
irq = IRQ_SPI(i);
707+
if (i < EXYNOS4210_MAX_COMBINER_NR || soc_is_exynos5250())
708+
irq = IRQ_SPI(i);
709+
else
710+
irq = exynos4x12_combiner_extra_irq(i);
669711
#ifdef CONFIG_OF
670712
if (np)
671713
irq = irq_of_parse_and_map(np, i);
672714
#endif
673715
combiner_cascade_irq(i, irq);
716+
combiner_init_one(i, combiner_base + (i >> 2) * 0x10, irq);
674717
}
675718
}
676719

@@ -1143,3 +1186,30 @@ static int __init exynos_init_irq_eint(void)
11431186
return 0;
11441187
}
11451188
arch_initcall(exynos_init_irq_eint);
1189+
1190+
static struct resource exynos4_pmu_resource[] = {
1191+
DEFINE_RES_IRQ(EXYNOS4_IRQ_PMU),
1192+
DEFINE_RES_IRQ(EXYNOS4_IRQ_PMU_CPU1),
1193+
#if defined(CONFIG_SOC_EXYNOS4412)
1194+
DEFINE_RES_IRQ(EXYNOS4_IRQ_PMU_CPU2),
1195+
DEFINE_RES_IRQ(EXYNOS4_IRQ_PMU_CPU3),
1196+
#endif
1197+
};
1198+
1199+
static struct platform_device exynos4_device_pmu = {
1200+
.name = "arm-pmu",
1201+
.num_resources = ARRAY_SIZE(exynos4_pmu_resource),
1202+
.resource = exynos4_pmu_resource,
1203+
};
1204+
1205+
static int __init exynos_armpmu_init(void)
1206+
{
1207+
if (!of_have_populated_dt()) {
1208+
if (soc_is_exynos4210() || soc_is_exynos4212())
1209+
exynos4_device_pmu.num_resources = 2;
1210+
platform_device_register(&exynos4_device_pmu);
1211+
}
1212+
1213+
return 0;
1214+
}
1215+
arch_initcall(exynos_armpmu_init);

arch/arm/mach-exynos/include/mach/irqs.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@
128128
#define EXYNOS4_IRQ_ADC1 IRQ_SPI(107)
129129
#define EXYNOS4_IRQ_PEN1 IRQ_SPI(108)
130130
#define EXYNOS4_IRQ_KEYPAD IRQ_SPI(109)
131-
#define EXYNOS4_IRQ_PMU IRQ_SPI(110)
131+
#define EXYNOS4_IRQ_POWER_PMU IRQ_SPI(110)
132132
#define EXYNOS4_IRQ_GPS IRQ_SPI(111)
133133
#define EXYNOS4_IRQ_INTFEEDCTRL_SSS IRQ_SPI(112)
134134
#define EXYNOS4_IRQ_SLIMBUS IRQ_SPI(113)
@@ -137,6 +137,11 @@
137137
#define EXYNOS4_IRQ_TSI IRQ_SPI(115)
138138
#define EXYNOS4_IRQ_SATA IRQ_SPI(116)
139139

140+
#define EXYNOS4_IRQ_PMU COMBINER_IRQ(2, 2)
141+
#define EXYNOS4_IRQ_PMU_CPU1 COMBINER_IRQ(3, 2)
142+
#define EXYNOS4_IRQ_PMU_CPU2 COMBINER_IRQ(18, 2)
143+
#define EXYNOS4_IRQ_PMU_CPU3 COMBINER_IRQ(19, 2)
144+
140145
#define EXYNOS4_IRQ_TMU_TRIG0 COMBINER_IRQ(2, 4)
141146
#define EXYNOS4_IRQ_TMU_TRIG1 COMBINER_IRQ(3, 4)
142147

@@ -169,7 +174,11 @@
169174
#define EXYNOS4_IRQ_FIMD0_VSYNC COMBINER_IRQ(11, 1)
170175
#define EXYNOS4_IRQ_FIMD0_SYSTEM COMBINER_IRQ(11, 2)
171176

172-
#define EXYNOS4_MAX_COMBINER_NR 16
177+
#define EXYNOS4210_MAX_COMBINER_NR 16
178+
#define EXYNOS4212_MAX_COMBINER_NR 18
179+
#define EXYNOS4412_MAX_COMBINER_NR 20
180+
#define EXYNOS4_MAX_COMBINER_NR EXYNOS4412_MAX_COMBINER_NR
181+
173182

174183
#define EXYNOS4_IRQ_GPIO1_NR_GROUPS 16
175184
#define EXYNOS4_IRQ_GPIO2_NR_GROUPS 9
@@ -235,7 +244,6 @@
235244
#define IRQ_TC EXYNOS4_IRQ_PEN0
236245

237246
#define IRQ_KEYPAD EXYNOS4_IRQ_KEYPAD
238-
#define IRQ_PMU EXYNOS4_IRQ_PMU
239247

240248
#define IRQ_CEC EXYNOS4_IRQ_CEC
241249

arch/arm/plat-samsung/devs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1151,7 +1151,7 @@ struct platform_device s5p_device_onenand = {
11511151

11521152
/* PMU */
11531153

1154-
#ifdef CONFIG_PLAT_S5P
1154+
#if defined(CONFIG_PLAT_S5P) && !defined(CONFIG_ARCH_EXYNOS)
11551155
static struct resource s5p_pmu_resource[] = {
11561156
DEFINE_RES_IRQ(IRQ_PMU)
11571157
};

0 commit comments

Comments
 (0)