summaryrefslogtreecommitdiff
path: root/arch/arm/plat-s5p
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-05-23 15:15:27 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2011-05-23 15:15:27 -0700
commit42cd71bf1e3a081b3150018bbf448cb6c8a844a5 (patch)
tree4a5d2eb0444255e4ad827a76dbd1417dd3876db6 /arch/arm/plat-s5p
parentf5039935ac685b3b9b8c13fbc33cac8643dee32e (diff)
parent9a55d9752d8abfc62f1ab05ccc790d22a0c8e7c0 (diff)
Merge branch 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm
* 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm: (137 commits) ARM: bcmring: convert to use sp804 clockevents ARM: bcmring: convert to sp804 clocksource ARM: 6912/1: bcmring: Add clkdev table in init_early clockevents: ARM sp804: obtain sp804 timer rate via clks clockevents: ARM sp804: allow clockevent name to be specified clocksource: ARM sp804: obtain sp804 timer rate via clks clocksource: ARM sp804: allow clocksource name to be specified clocksource: convert OMAP1 to 32-bit down counting clocksource clocksource: convert MXS timrotv2 to 32-bit down counting clocksource clocksource: convert SPEAr platforms 16-bit up counting clocksource clocksource: convert Integrator/AP 16-bit down counting clocksource clocksource: convert W90x900 24-bit down counting clocksource clocksource: convert ARM 32-bit down counting clocksources clocksource: convert ARM 32-bit up counting clocksources clocksource: add common mmio clocksource ARM: update sa1100 to reflect PXA updates ARM: omap1: convert to using readl/writel instead of volatile struct ARM: omap1: delete useless interrupt handler ARM: s5p: consolidate selection of timer register ARM: 6939/1: fix missing 'cpu_relax()' declaration ...
Diffstat (limited to 'arch/arm/plat-s5p')
-rw-r--r--arch/arm/plat-s5p/irq-gpioint.c116
-rw-r--r--arch/arm/plat-s5p/irq.c6
-rw-r--r--arch/arm/plat-s5p/s5p-time.c58
3 files changed, 45 insertions, 135 deletions
diff --git a/arch/arm/plat-s5p/irq-gpioint.c b/arch/arm/plat-s5p/irq-gpioint.c
index cd6d67c8382a..135abda31c9a 100644
--- a/arch/arm/plat-s5p/irq-gpioint.c
+++ b/arch/arm/plat-s5p/irq-gpioint.c
@@ -41,72 +41,11 @@ struct s5p_gpioint_bank {
LIST_HEAD(banks);
-static int s5p_gpioint_get_offset(struct irq_data *data)
+static int s5p_gpioint_set_type(struct irq_data *d, unsigned int type)
{
- struct s3c_gpio_chip *chip = irq_data_get_irq_handler_data(data);
- return data->irq - chip->irq_base;
-}
-
-static void s5p_gpioint_ack(struct irq_data *data)
-{
- struct s3c_gpio_chip *chip = irq_data_get_irq_handler_data(data);
- int group, offset, pend_offset;
- unsigned int value;
-
- group = chip->group;
- offset = s5p_gpioint_get_offset(data);
- pend_offset = REG_OFFSET(group);
-
- value = __raw_readl(GPIO_BASE(chip) + PEND_OFFSET + pend_offset);
- value |= BIT(offset);
- __raw_writel(value, GPIO_BASE(chip) + PEND_OFFSET + pend_offset);
-}
-
-static void s5p_gpioint_mask(struct irq_data *data)
-{
- struct s3c_gpio_chip *chip = irq_data_get_irq_handler_data(data);
- int group, offset, mask_offset;
- unsigned int value;
-
- group = chip->group;
- offset = s5p_gpioint_get_offset(data);
- mask_offset = REG_OFFSET(group);
-
- value = __raw_readl(GPIO_BASE(chip) + MASK_OFFSET + mask_offset);
- value |= BIT(offset);
- __raw_writel(value, GPIO_BASE(chip) + MASK_OFFSET + mask_offset);
-}
-
-static void s5p_gpioint_unmask(struct irq_data *data)
-{
- struct s3c_gpio_chip *chip = irq_data_get_irq_handler_data(data);
- int group, offset, mask_offset;
- unsigned int value;
-
- group = chip->group;
- offset = s5p_gpioint_get_offset(data);
- mask_offset = REG_OFFSET(group);
-
- value = __raw_readl(GPIO_BASE(chip) + MASK_OFFSET + mask_offset);
- value &= ~BIT(offset);
- __raw_writel(value, GPIO_BASE(chip) + MASK_OFFSET + mask_offset);
-}
-
-static void s5p_gpioint_mask_ack(struct irq_data *data)
-{
- s5p_gpioint_mask(data);
- s5p_gpioint_ack(data);
-}
-
-static int s5p_gpioint_set_type(struct irq_data *data, unsigned int type)
-{
- struct s3c_gpio_chip *chip = irq_data_get_irq_handler_data(data);
- int group, offset, con_offset;
- unsigned int value;
-
- group = chip->group;
- offset = s5p_gpioint_get_offset(data);
- con_offset = REG_OFFSET(group);
+ struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+ struct irq_chip_type *ct = gc->chip_types;
+ unsigned int shift = (d->irq - gc->irq_base) << 2;
switch (type) {
case IRQ_TYPE_EDGE_RISING:
@@ -130,23 +69,12 @@ static int s5p_gpioint_set_type(struct irq_data *data, unsigned int type)
return -EINVAL;
}
- value = __raw_readl(GPIO_BASE(chip) + CON_OFFSET + con_offset);
- value &= ~(0x7 << (offset * 0x4));
- value |= (type << (offset * 0x4));
- __raw_writel(value, GPIO_BASE(chip) + CON_OFFSET + con_offset);
-
+ gc->type_cache &= ~(0x7 << shift);
+ gc->type_cache |= type << shift;
+ writel(gc->type_cache, gc->reg_base + ct->regs.type);
return 0;
}
-static struct irq_chip s5p_gpioint = {
- .name = "s5p_gpioint",
- .irq_ack = s5p_gpioint_ack,
- .irq_mask = s5p_gpioint_mask,
- .irq_mask_ack = s5p_gpioint_mask_ack,
- .irq_unmask = s5p_gpioint_unmask,
- .irq_set_type = s5p_gpioint_set_type,
-};
-
static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc)
{
struct s5p_gpioint_bank *bank = irq_get_handler_data(irq);
@@ -179,9 +107,10 @@ static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc)
static __init int s5p_gpioint_add(struct s3c_gpio_chip *chip)
{
static int used_gpioint_groups = 0;
- int irq, group = chip->group;
- int i;
+ int group = chip->group;
struct s5p_gpioint_bank *bank = NULL;
+ struct irq_chip_generic *gc;
+ struct irq_chip_type *ct;
if (used_gpioint_groups >= S5P_GPIOINT_GROUP_COUNT)
return -ENOMEM;
@@ -211,19 +140,28 @@ static __init int s5p_gpioint_add(struct s3c_gpio_chip *chip)
* chained GPIO irq has been successfully registered, allocate new gpio
* int group and assign irq nubmers
*/
-
chip->irq_base = S5P_GPIOINT_BASE +
used_gpioint_groups * S5P_GPIOINT_GROUP_SIZE;
used_gpioint_groups++;
bank->chips[group - bank->start] = chip;
- for (i = 0; i < chip->chip.ngpio; i++) {
- irq = chip->irq_base + i;
- irq_set_chip(irq, &s5p_gpioint);
- irq_set_handler_data(irq, chip);
- irq_set_handler(irq, handle_level_irq);
- set_irq_flags(irq, IRQF_VALID);
- }
+
+ gc = irq_alloc_generic_chip("s5p_gpioint", 1, chip->irq_base,
+ (void __iomem *)GPIO_BASE(chip),
+ handle_level_irq);
+ if (!gc)
+ return -ENOMEM;
+ ct = gc->chip_types;
+ ct->chip.irq_ack = irq_gc_ack;
+ ct->chip.irq_mask = irq_gc_mask_set_bit;
+ ct->chip.irq_unmask = irq_gc_mask_clr_bit;
+ ct->chip.irq_set_type = s5p_gpioint_set_type,
+ ct->regs.ack = PEND_OFFSET + REG_OFFSET(chip->group);
+ ct->regs.mask = MASK_OFFSET + REG_OFFSET(chip->group);
+ ct->regs.type = CON_OFFSET + REG_OFFSET(chip->group);
+ irq_setup_generic_chip(gc, IRQ_MSK(chip->chip.ngpio),
+ IRQ_GC_INIT_MASK_CACHE,
+ IRQ_NOREQUEST | IRQ_NOPROBE, 0);
return 0;
}
diff --git a/arch/arm/plat-s5p/irq.c b/arch/arm/plat-s5p/irq.c
index 5560b12035d1..a97c08957f49 100644
--- a/arch/arm/plat-s5p/irq.c
+++ b/arch/arm/plat-s5p/irq.c
@@ -64,11 +64,7 @@ void __init s5p_init_irq(u32 *vic, u32 num_vic)
vic_init(VA_VIC(irq), VIC_BASE(irq), vic[irq], 0);
#endif
- s3c_init_vic_timer_irq(IRQ_TIMER0_VIC, IRQ_TIMER0);
- s3c_init_vic_timer_irq(IRQ_TIMER1_VIC, IRQ_TIMER1);
- s3c_init_vic_timer_irq(IRQ_TIMER2_VIC, IRQ_TIMER2);
- s3c_init_vic_timer_irq(IRQ_TIMER3_VIC, IRQ_TIMER3);
- s3c_init_vic_timer_irq(IRQ_TIMER4_VIC, IRQ_TIMER4);
+ s3c_init_vic_timer_irq(5, IRQ_TIMER0);
s3c_init_uart_irqs(uart_irqs, ARRAY_SIZE(uart_irqs));
}
diff --git a/arch/arm/plat-s5p/s5p-time.c b/arch/arm/plat-s5p/s5p-time.c
index 8090403eec0f..899a8cc011ff 100644
--- a/arch/arm/plat-s5p/s5p-time.c
+++ b/arch/arm/plat-s5p/s5p-time.c
@@ -290,7 +290,7 @@ static void __init s5p_clockevent_init(void)
setup_irq(irq_number, &s5p_clock_event_irq);
}
-static cycle_t s5p_timer_read(struct clocksource *cs)
+static void __iomem *s5p_timer_reg(void)
{
unsigned long offset = 0;
@@ -308,10 +308,17 @@ static cycle_t s5p_timer_read(struct clocksource *cs)
default:
printk(KERN_ERR "Invalid Timer %d\n", timer_source.source_id);
- return 0;
+ return NULL;
}
- return (cycle_t) ~__raw_readl(S3C_TIMERREG(offset));
+ return S3C_TIMERREG(offset);
+}
+
+static cycle_t s5p_timer_read(struct clocksource *cs)
+{
+ void __iomem *reg = s5p_timer_reg();
+
+ return (cycle_t) (reg ? ~__raw_readl(reg) : 0);
}
/*
@@ -325,53 +332,22 @@ static DEFINE_CLOCK_DATA(cd);
unsigned long long notrace sched_clock(void)
{
- u32 cyc;
- unsigned long offset = 0;
-
- switch (timer_source.source_id) {
- case S5P_PWM0:
- case S5P_PWM1:
- case S5P_PWM2:
- case S5P_PWM3:
- offset = (timer_source.source_id * 0x0c) + 0x14;
- break;
-
- case S5P_PWM4:
- offset = 0x40;
- break;
+ void __iomem *reg = s5p_timer_reg();
- default:
- printk(KERN_ERR "Invalid Timer %d\n", timer_source.source_id);
+ if (!reg)
return 0;
- }
- cyc = ~__raw_readl(S3C_TIMERREG(offset));
- return cyc_to_sched_clock(&cd, cyc, (u32)~0);
+ return cyc_to_sched_clock(&cd, ~__raw_readl(reg), (u32)~0);
}
static void notrace s5p_update_sched_clock(void)
{
- u32 cyc;
- unsigned long offset = 0;
+ void __iomem *reg = s5p_timer_reg();
- switch (timer_source.source_id) {
- case S5P_PWM0:
- case S5P_PWM1:
- case S5P_PWM2:
- case S5P_PWM3:
- offset = (timer_source.source_id * 0x0c) + 0x14;
- break;
-
- case S5P_PWM4:
- offset = 0x40;
- break;
-
- default:
- printk(KERN_ERR "Invalid Timer %d\n", timer_source.source_id);
- }
+ if (!reg)
+ return;
- cyc = ~__raw_readl(S3C_TIMERREG(offset));
- update_sched_clock(&cd, cyc, (u32)~0);
+ update_sched_clock(&cd, ~__raw_readl(reg), (u32)~0);
}
struct clocksource time_clocksource = {