Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Endless #3

Merged
merged 2 commits into from
Apr 22, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 84 additions & 14 deletions arch/arm/mach-exynos/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include <mach/regs-pmu.h>
#include <mach/regs-gpio.h>
#include <mach/pmu.h>
#include <mach/irqs.h>

#include <plat/cpu.h>
#include <plat/clock.h>
Expand Down Expand Up @@ -496,6 +497,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;
Expand Down Expand Up @@ -552,35 +554,59 @@ 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,
#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();
irq_set_chained_handler(irq, combiner_handle_cascade_irq);
}

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,
Expand Down Expand Up @@ -631,22 +657,36 @@ 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;
}
}

static 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, "
"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;

Expand All @@ -664,13 +704,16 @@ static 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_cascade_irq(i, irq);
combiner_init_one(i, combiner_base + (i >> 2) * 0x10, irq);
}
}

Expand Down Expand Up @@ -1143,3 +1186,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);
14 changes: 11 additions & 3 deletions arch/arm/mach-exynos/include/mach/irqs.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,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)
Expand All @@ -137,6 +137,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)

Expand Down Expand Up @@ -169,7 +174,11 @@
#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
Expand Down Expand Up @@ -235,7 +244,6 @@
#define IRQ_TC EXYNOS4_IRQ_PEN0

#define IRQ_KEYPAD EXYNOS4_IRQ_KEYPAD
#define IRQ_PMU EXYNOS4_IRQ_PMU

#define IRQ_CEC EXYNOS4_IRQ_CEC

Expand Down
2 changes: 1 addition & 1 deletion arch/arm/plat-samsung/devs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1151,7 +1151,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)
};
Expand Down