add support arm-pmu for exynos4 and exynos5250
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQIcBAABAgAGBQJRYvh4AAoJEA0Cl+kVi2xqaH8P/2Rx1D7YqZZpDgPrmelQZCa5 eO4HMgNeA5sqNhTz9LXm4SVTDzBmXdhnHAw0vRSgIVdMjgi6ND2QezE3Xhgv1gZE Znr8aXg9B2hEapUWUTWFyVYRx+KoT/2QKh3ZsIDTxTchIyxU+zj6/cesdnsgbK0E WlauEP74iSdWswlnF9ylxnrifjBbnsblhBNXbchSyBtfu+VvWAKuLCmPJoBrMrfK dZhWzVXKUTwR2JyHNb6xTV12JXJrwjs57n3AUTGu+Qr9oryTK3rZBcUa7kQSqQ4Z UQKrd8S2v6JghNhAjkHmP686PDFqiDxIvmcq/QvR3GBzRM44PDRUlDizF8W2EffA M3/aiPw3pZ1RqDCmbCSovAItEad4Ct93SU+8sA9MPCMX6T8D4zOmeE3Mjq0FunCl 2acAvskoUOtY2Z4H7tQOO+2ie6lB/rAE9RwO03bRwAUddNaWh0hlUx18Q87bNmaD oA/x6OLgc0YRzhZQQlBB7HcKx0DQY3PZ0nsnC4PTOKkDBtY7I2h3jsga8FP38SBG tPUM5TjYMnPXbu7fFDfVb47B5y8jIzAXI6Iai8EtMKw/OvOcMBzuzqDymD46/KFN dVzZNDC+ZsmwglAGMuhLKIbnMOf9L5kCbjLAss9Vcs9V0KPnXM9unOWSW5IgRr/y ehZHofn5Dp3K/v3JoWd8 =V6w+ -----END PGP SIGNATURE----- Merge tag 'pmu-exynos-for-v3.10' of git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung into next/drivers From Kukjin Kim <kgene.kim@samsung.com>: add support arm-pmu for exynos4 and exynos5250 * tag 'pmu-exynos-for-v3.10' of git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung: ARM: EXYNOS: Add arm-pmu DT binding for exynos421x ARM: EXYNOS: Add arm-pmu DT binding for exynos5250 ARM: EXYNOS: Enable PMUs for exynos4 irqchip: exynos-combiner: Correct combined IRQs for exynos4 irqchip: exynos-combiner: Add set_irq_affinity function for combiner_irq Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
commit
0b8467ee39
|
@ -77,6 +77,12 @@
|
|||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
pmu {
|
||||
compatible = "arm,cortex-a9-pmu";
|
||||
interrupt-parent = <&combiner>;
|
||||
interrupts = <2 2>, <3 2>;
|
||||
};
|
||||
|
||||
pinctrl_0: pinctrl@11400000 {
|
||||
compatible = "samsung,exynos4210-pinctrl";
|
||||
reg = <0x11400000 0x1000>;
|
||||
|
|
|
@ -109,6 +109,12 @@
|
|||
};
|
||||
};
|
||||
|
||||
pmu {
|
||||
compatible = "arm,cortex-a15-pmu";
|
||||
interrupt-parent = <&combiner>;
|
||||
interrupts = <1 2>, <22 4>;
|
||||
};
|
||||
|
||||
watchdog {
|
||||
compatible = "samsung,s3c2410-wdt";
|
||||
reg = <0x101D0000 0x100>;
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include <mach/regs-irq.h>
|
||||
#include <mach/regs-pmu.h>
|
||||
#include <mach/regs-gpio.h>
|
||||
#include <mach/irqs.h>
|
||||
|
||||
#include <plat/cpu.h>
|
||||
#include <plat/devs.h>
|
||||
|
@ -851,3 +852,30 @@ static int __init exynos_init_irq_eint(void)
|
|||
return 0;
|
||||
}
|
||||
arch_initcall(exynos_init_irq_eint);
|
||||
|
||||
static struct resource exynos4_pmu_resource[] = {
|
||||
DEFINE_RES_IRQ(EXYNOS4_IRQ_PMU),
|
||||
DEFINE_RES_IRQ(EXYNOS4_IRQ_PMU_CPU1),
|
||||
#if defined(CONFIG_SOC_EXYNOS4412)
|
||||
DEFINE_RES_IRQ(EXYNOS4_IRQ_PMU_CPU2),
|
||||
DEFINE_RES_IRQ(EXYNOS4_IRQ_PMU_CPU3),
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct platform_device exynos4_device_pmu = {
|
||||
.name = "arm-pmu",
|
||||
.num_resources = ARRAY_SIZE(exynos4_pmu_resource),
|
||||
.resource = exynos4_pmu_resource,
|
||||
};
|
||||
|
||||
static int __init exynos_armpmu_init(void)
|
||||
{
|
||||
if (!of_have_populated_dt()) {
|
||||
if (soc_is_exynos4210() || soc_is_exynos4212())
|
||||
exynos4_device_pmu.num_resources = 2;
|
||||
platform_device_register(&exynos4_device_pmu);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
arch_initcall(exynos_armpmu_init);
|
||||
|
|
|
@ -126,7 +126,7 @@
|
|||
#define EXYNOS4_IRQ_ADC1 IRQ_SPI(107)
|
||||
#define EXYNOS4_IRQ_PEN1 IRQ_SPI(108)
|
||||
#define EXYNOS4_IRQ_KEYPAD IRQ_SPI(109)
|
||||
#define EXYNOS4_IRQ_PMU IRQ_SPI(110)
|
||||
#define EXYNOS4_IRQ_POWER_PMU IRQ_SPI(110)
|
||||
#define EXYNOS4_IRQ_GPS IRQ_SPI(111)
|
||||
#define EXYNOS4_IRQ_INTFEEDCTRL_SSS IRQ_SPI(112)
|
||||
#define EXYNOS4_IRQ_SLIMBUS IRQ_SPI(113)
|
||||
|
@ -134,6 +134,11 @@
|
|||
#define EXYNOS4_IRQ_TSI IRQ_SPI(115)
|
||||
#define EXYNOS4_IRQ_SATA IRQ_SPI(116)
|
||||
|
||||
#define EXYNOS4_IRQ_PMU COMBINER_IRQ(2, 2)
|
||||
#define EXYNOS4_IRQ_PMU_CPU1 COMBINER_IRQ(3, 2)
|
||||
#define EXYNOS4_IRQ_PMU_CPU2 COMBINER_IRQ(18, 2)
|
||||
#define EXYNOS4_IRQ_PMU_CPU3 COMBINER_IRQ(19, 2)
|
||||
|
||||
#define EXYNOS4_IRQ_TMU_TRIG0 COMBINER_IRQ(2, 4)
|
||||
#define EXYNOS4_IRQ_TMU_TRIG1 COMBINER_IRQ(3, 4)
|
||||
|
||||
|
@ -166,7 +171,10 @@
|
|||
#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 EXYNOS4210_MAX_COMBINER_NR 16
|
||||
#define EXYNOS4212_MAX_COMBINER_NR 18
|
||||
#define EXYNOS4412_MAX_COMBINER_NR 20
|
||||
#define EXYNOS4_MAX_COMBINER_NR EXYNOS4412_MAX_COMBINER_NR
|
||||
|
||||
#define EXYNOS4_IRQ_GPIO1_NR_GROUPS 16
|
||||
#define EXYNOS4_IRQ_GPIO2_NR_GROUPS 9
|
||||
|
@ -231,7 +239,6 @@
|
|||
#define IRQ_TC EXYNOS4_IRQ_PEN0
|
||||
|
||||
#define IRQ_KEYPAD EXYNOS4_IRQ_KEYPAD
|
||||
#define IRQ_PMU EXYNOS4_IRQ_PMU
|
||||
|
||||
#define IRQ_FIMD0_FIFO EXYNOS4_IRQ_FIMD0_FIFO
|
||||
#define IRQ_FIMD0_VSYNC EXYNOS4_IRQ_FIMD0_VSYNC
|
||||
|
|
|
@ -1113,7 +1113,7 @@ struct platform_device s5p_device_onenand = {
|
|||
|
||||
/* PMU */
|
||||
|
||||
#ifdef CONFIG_PLAT_S5P
|
||||
#if defined(CONFIG_PLAT_S5P) && !defined(CONFIG_ARCH_EXYNOS)
|
||||
static struct resource s5p_pmu_resource[] = {
|
||||
DEFINE_RES_IRQ(IRQ_PMU)
|
||||
};
|
||||
|
|
|
@ -31,6 +31,7 @@ struct combiner_chip_data {
|
|||
unsigned int irq_offset;
|
||||
unsigned int irq_mask;
|
||||
void __iomem *base;
|
||||
unsigned int parent_irq;
|
||||
};
|
||||
|
||||
static struct irq_domain *combiner_irq_domain;
|
||||
|
@ -87,22 +88,46 @@ static void combiner_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
|
|||
chained_irq_exit(chip, desc);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
static int combiner_set_affinity(struct irq_data *d,
|
||||
const struct cpumask *mask_val, bool force)
|
||||
{
|
||||
struct combiner_chip_data *chip_data = irq_data_get_irq_chip_data(d);
|
||||
struct irq_chip *chip = irq_get_chip(chip_data->parent_irq);
|
||||
struct irq_data *data = irq_get_irq_data(chip_data->parent_irq);
|
||||
|
||||
if (chip && chip->irq_set_affinity)
|
||||
return chip->irq_set_affinity(data, mask_val, force);
|
||||
else
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct irq_chip combiner_chip = {
|
||||
.name = "COMBINER",
|
||||
.irq_mask = combiner_mask_irq,
|
||||
.irq_unmask = combiner_unmask_irq,
|
||||
.name = "COMBINER",
|
||||
.irq_mask = combiner_mask_irq,
|
||||
.irq_unmask = combiner_unmask_irq,
|
||||
#ifdef CONFIG_SMP
|
||||
.irq_set_affinity = combiner_set_affinity,
|
||||
#endif
|
||||
};
|
||||
|
||||
static void __init combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq)
|
||||
static unsigned int max_combiner_nr(void)
|
||||
{
|
||||
unsigned int max_nr;
|
||||
|
||||
if (soc_is_exynos5250())
|
||||
max_nr = EXYNOS5_MAX_COMBINER_NR;
|
||||
return EXYNOS5_MAX_COMBINER_NR;
|
||||
else if (soc_is_exynos4412())
|
||||
return EXYNOS4412_MAX_COMBINER_NR;
|
||||
else if (soc_is_exynos4212())
|
||||
return EXYNOS4212_MAX_COMBINER_NR;
|
||||
else
|
||||
max_nr = EXYNOS4_MAX_COMBINER_NR;
|
||||
return EXYNOS4210_MAX_COMBINER_NR;
|
||||
}
|
||||
|
||||
if (combiner_nr >= max_nr)
|
||||
static void __init combiner_cascade_irq(unsigned int combiner_nr,
|
||||
unsigned int irq)
|
||||
{
|
||||
if (combiner_nr >= max_combiner_nr())
|
||||
BUG();
|
||||
if (irq_set_handler_data(irq, &combiner_data[combiner_nr]) != 0)
|
||||
BUG();
|
||||
|
@ -110,12 +135,13 @@ static void __init combiner_cascade_irq(unsigned int combiner_nr, unsigned int i
|
|||
}
|
||||
|
||||
static void __init combiner_init_one(unsigned int combiner_nr,
|
||||
void __iomem *base)
|
||||
void __iomem *base, unsigned int irq)
|
||||
{
|
||||
combiner_data[combiner_nr].base = base;
|
||||
combiner_data[combiner_nr].irq_offset = irq_find_mapping(
|
||||
combiner_irq_domain, combiner_nr * MAX_IRQ_IN_COMBINER);
|
||||
combiner_data[combiner_nr].irq_mask = 0xff << ((combiner_nr % 4) << 3);
|
||||
combiner_data[combiner_nr].parent_irq = irq;
|
||||
|
||||
/* Disable all interrupts */
|
||||
__raw_writel(combiner_data[combiner_nr].irq_mask,
|
||||
|
@ -166,23 +192,38 @@ static struct irq_domain_ops combiner_irq_domain_ops = {
|
|||
.map = combiner_irq_domain_map,
|
||||
};
|
||||
|
||||
static unsigned int exynos4x12_combiner_extra_irq(int group)
|
||||
{
|
||||
switch (group) {
|
||||
case 16:
|
||||
return IRQ_SPI(107);
|
||||
case 17:
|
||||
return IRQ_SPI(108);
|
||||
case 18:
|
||||
return IRQ_SPI(48);
|
||||
case 19:
|
||||
return IRQ_SPI(42);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void __init combiner_init(void __iomem *combiner_base,
|
||||
struct device_node *np)
|
||||
{
|
||||
int i, irq, irq_base;
|
||||
unsigned int max_nr, nr_irq;
|
||||
|
||||
max_nr = max_combiner_nr();
|
||||
|
||||
if (np) {
|
||||
if (of_property_read_u32(np, "samsung,combiner-nr", &max_nr)) {
|
||||
pr_warning("%s: number of combiners not specified, "
|
||||
pr_info("%s: number of combiners not specified, "
|
||||
"setting default as %d.\n",
|
||||
__func__, EXYNOS4_MAX_COMBINER_NR);
|
||||
max_nr = EXYNOS4_MAX_COMBINER_NR;
|
||||
__func__, max_nr);
|
||||
}
|
||||
} else {
|
||||
max_nr = soc_is_exynos5250() ? EXYNOS5_MAX_COMBINER_NR :
|
||||
EXYNOS4_MAX_COMBINER_NR;
|
||||
}
|
||||
|
||||
nr_irq = max_nr * MAX_IRQ_IN_COMBINER;
|
||||
|
||||
irq_base = irq_alloc_descs(COMBINER_IRQ(0, 0), 1, nr_irq, 0);
|
||||
|
@ -199,12 +240,15 @@ void __init combiner_init(void __iomem *combiner_base,
|
|||
}
|
||||
|
||||
for (i = 0; i < max_nr; i++) {
|
||||
combiner_init_one(i, combiner_base + (i >> 2) * 0x10);
|
||||
irq = IRQ_SPI(i);
|
||||
if (i < EXYNOS4210_MAX_COMBINER_NR || soc_is_exynos5250())
|
||||
irq = IRQ_SPI(i);
|
||||
else
|
||||
irq = exynos4x12_combiner_extra_irq(i);
|
||||
#ifdef CONFIG_OF
|
||||
if (np)
|
||||
irq = irq_of_parse_and_map(np, i);
|
||||
#endif
|
||||
combiner_init_one(i, combiner_base + (i >> 2) * 0x10, irq);
|
||||
combiner_cascade_irq(i, irq);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue