Commit 364ca8a8 authored by Yoichi Yuasa's avatar Yoichi Yuasa Committed by Ralf Baechle

[MIPS] Vr41xx: Fix after GENERIC_HARDIRQS_NO__DO_IRQ change

Signed-off-by: default avatarYoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent ac8be955
/* /*
* Interrupt handing routines for NEC VR4100 series. * Interrupt handing routines for NEC VR4100 series.
* *
* Copyright (C) 2005 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> * Copyright (C) 2005-2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
...@@ -73,13 +73,19 @@ static void irq_dispatch(unsigned int irq) ...@@ -73,13 +73,19 @@ static void irq_dispatch(unsigned int irq)
if (cascade->get_irq != NULL) { if (cascade->get_irq != NULL) {
unsigned int source_irq = irq; unsigned int source_irq = irq;
desc = irq_desc + source_irq; desc = irq_desc + source_irq;
desc->chip->ack(source_irq); if (desc->chip->mask_ack)
desc->chip->mask_ack(source_irq);
else {
desc->chip->mask(source_irq);
desc->chip->ack(source_irq);
}
irq = cascade->get_irq(irq); irq = cascade->get_irq(irq);
if (irq < 0) if (irq < 0)
atomic_inc(&irq_err_count); atomic_inc(&irq_err_count);
else else
irq_dispatch(irq); irq_dispatch(irq);
desc->chip->end(source_irq); if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask)
desc->chip->unmask(source_irq);
} else } else
do_IRQ(irq); do_IRQ(irq);
} }
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* *
* Copyright (C) 2002 MontaVista Software Inc. * Copyright (C) 2002 MontaVista Software Inc.
* Author: Yoichi Yuasa <yyuasa@mvista.com or source@mvista.com> * Author: Yoichi Yuasa <yyuasa@mvista.com or source@mvista.com>
* Copyright (C) 2003-2005 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> * Copyright (C) 2003-2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
...@@ -125,30 +125,17 @@ static inline uint16_t giu_clear(uint16_t offset, uint16_t clear) ...@@ -125,30 +125,17 @@ static inline uint16_t giu_clear(uint16_t offset, uint16_t clear)
return data; return data;
} }
static unsigned int startup_giuint_low_irq(unsigned int irq) static void ack_giuint_low(unsigned int irq)
{ {
unsigned int pin; giu_write(GIUINTSTATL, 1 << GPIO_PIN_OF_IRQ(irq));
pin = GPIO_PIN_OF_IRQ(irq);
giu_write(GIUINTSTATL, 1 << pin);
giu_set(GIUINTENL, 1 << pin);
return 0;
} }
static void shutdown_giuint_low_irq(unsigned int irq) static void mask_giuint_low(unsigned int irq)
{ {
giu_clear(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq)); giu_clear(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq));
} }
static void enable_giuint_low_irq(unsigned int irq) static void mask_ack_giuint_low(unsigned int irq)
{
giu_set(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq));
}
#define disable_giuint_low_irq shutdown_giuint_low_irq
static void ack_giuint_low_irq(unsigned int irq)
{ {
unsigned int pin; unsigned int pin;
...@@ -157,46 +144,30 @@ static void ack_giuint_low_irq(unsigned int irq) ...@@ -157,46 +144,30 @@ static void ack_giuint_low_irq(unsigned int irq)
giu_write(GIUINTSTATL, 1 << pin); giu_write(GIUINTSTATL, 1 << pin);
} }
static void end_giuint_low_irq(unsigned int irq) static void unmask_giuint_low(unsigned int irq)
{ {
if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) giu_set(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq));
giu_set(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq));
} }
static struct hw_interrupt_type giuint_low_irq_type = { static struct irq_chip giuint_low_irq_chip = {
.typename = "GIUINTL", .name = "GIUINTL",
.startup = startup_giuint_low_irq, .ack = ack_giuint_low,
.shutdown = shutdown_giuint_low_irq, .mask = mask_giuint_low,
.enable = enable_giuint_low_irq, .mask_ack = mask_ack_giuint_low,
.disable = disable_giuint_low_irq, .unmask = unmask_giuint_low,
.ack = ack_giuint_low_irq,
.end = end_giuint_low_irq,
}; };
static unsigned int startup_giuint_high_irq(unsigned int irq) static void ack_giuint_high(unsigned int irq)
{ {
unsigned int pin; giu_write(GIUINTSTATH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET));
pin = GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET;
giu_write(GIUINTSTATH, 1 << pin);
giu_set(GIUINTENH, 1 << pin);
return 0;
} }
static void shutdown_giuint_high_irq(unsigned int irq) static void mask_giuint_high(unsigned int irq)
{ {
giu_clear(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET)); giu_clear(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET));
} }
static void enable_giuint_high_irq(unsigned int irq) static void mask_ack_giuint_high(unsigned int irq)
{
giu_set(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET));
}
#define disable_giuint_high_irq shutdown_giuint_high_irq
static void ack_giuint_high_irq(unsigned int irq)
{ {
unsigned int pin; unsigned int pin;
...@@ -205,20 +176,17 @@ static void ack_giuint_high_irq(unsigned int irq) ...@@ -205,20 +176,17 @@ static void ack_giuint_high_irq(unsigned int irq)
giu_write(GIUINTSTATH, 1 << pin); giu_write(GIUINTSTATH, 1 << pin);
} }
static void end_giuint_high_irq(unsigned int irq) static void unmask_giuint_high(unsigned int irq)
{ {
if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) giu_set(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET));
giu_set(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET));
} }
static struct hw_interrupt_type giuint_high_irq_type = { static struct irq_chip giuint_high_irq_chip = {
.typename = "GIUINTH", .name = "GIUINTH",
.startup = startup_giuint_high_irq, .ack = ack_giuint_high,
.shutdown = shutdown_giuint_high_irq, .mask = mask_giuint_high,
.enable = enable_giuint_high_irq, .mask_ack = mask_ack_giuint_high,
.disable = disable_giuint_high_irq, .unmask = unmask_giuint_high,
.ack = ack_giuint_high_irq,
.end = end_giuint_high_irq,
}; };
static int giu_get_irq(unsigned int irq) static int giu_get_irq(unsigned int irq)
...@@ -282,9 +250,15 @@ void vr41xx_set_irq_trigger(unsigned int pin, irq_trigger_t trigger, irq_signal_ ...@@ -282,9 +250,15 @@ void vr41xx_set_irq_trigger(unsigned int pin, irq_trigger_t trigger, irq_signal_
break; break;
} }
} }
set_irq_chip_and_handler(GIU_IRQ(pin),
&giuint_low_irq_chip,
handle_edge_irq);
} else { } else {
giu_clear(GIUINTTYPL, mask); giu_clear(GIUINTTYPL, mask);
giu_clear(GIUINTHTSELL, mask); giu_clear(GIUINTHTSELL, mask);
set_irq_chip_and_handler(GIU_IRQ(pin),
&giuint_low_irq_chip,
handle_level_irq);
} }
giu_write(GIUINTSTATL, mask); giu_write(GIUINTSTATL, mask);
} else if (pin < GIUINT_HIGH_MAX) { } else if (pin < GIUINT_HIGH_MAX) {
...@@ -311,9 +285,15 @@ void vr41xx_set_irq_trigger(unsigned int pin, irq_trigger_t trigger, irq_signal_ ...@@ -311,9 +285,15 @@ void vr41xx_set_irq_trigger(unsigned int pin, irq_trigger_t trigger, irq_signal_
break; break;
} }
} }
set_irq_chip_and_handler(GIU_IRQ(pin),
&giuint_high_irq_chip,
handle_edge_irq);
} else { } else {
giu_clear(GIUINTTYPH, mask); giu_clear(GIUINTTYPH, mask);
giu_clear(GIUINTHTSELH, mask); giu_clear(GIUINTHTSELH, mask);
set_irq_chip_and_handler(GIU_IRQ(pin),
&giuint_high_irq_chip,
handle_level_irq);
} }
giu_write(GIUINTSTATH, mask); giu_write(GIUINTSTATH, mask);
} }
...@@ -617,10 +597,11 @@ static const struct file_operations gpio_fops = { ...@@ -617,10 +597,11 @@ static const struct file_operations gpio_fops = {
static int __devinit giu_probe(struct platform_device *dev) static int __devinit giu_probe(struct platform_device *dev)
{ {
unsigned long start, size, flags = 0; unsigned long start, size, flags = 0;
unsigned int nr_pins = 0; unsigned int nr_pins = 0, trigger, i, pin;
struct resource *res1, *res2 = NULL; struct resource *res1, *res2 = NULL;
void *base; void *base;
int retval, i; struct irq_chip *chip;
int retval;
switch (current_cpu_data.cputype) { switch (current_cpu_data.cputype) {
case CPU_VR4111: case CPU_VR4111:
...@@ -688,11 +669,20 @@ static int __devinit giu_probe(struct platform_device *dev) ...@@ -688,11 +669,20 @@ static int __devinit giu_probe(struct platform_device *dev)
giu_write(GIUINTENL, 0); giu_write(GIUINTENL, 0);
giu_write(GIUINTENH, 0); giu_write(GIUINTENH, 0);
trigger = giu_read(GIUINTTYPH) << 16;
trigger |= giu_read(GIUINTTYPL);
for (i = GIU_IRQ_BASE; i <= GIU_IRQ_LAST; i++) { for (i = GIU_IRQ_BASE; i <= GIU_IRQ_LAST; i++) {
if (i < GIU_IRQ(GIUINT_HIGH_OFFSET)) pin = GPIO_PIN_OF_IRQ(i);
irq_desc[i].chip = &giuint_low_irq_type; if (pin < GIUINT_HIGH_OFFSET)
chip = &giuint_low_irq_chip;
else else
irq_desc[i].chip = &giuint_high_irq_type; chip = &giuint_high_irq_chip;
if (trigger & (1 << pin))
set_irq_chip_and_handler(i, chip, handle_edge_irq);
else
set_irq_chip_and_handler(i, chip, handle_level_irq);
} }
return cascade_irq(GIUINT_IRQ, giu_get_irq); return cascade_irq(GIUINT_IRQ, giu_get_irq);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment