*
* Based on work Copyright (C) 2002-2003 Intel Corporation
*
- * This file is licensed under the terms of the GNU General Public
+ * This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#include <asm/mach-types.h>
#include <asm/irq.h>
#include <asm/system.h>
+#include <asm/hardware.h>
#include <asm/tlbflush.h>
#include <asm/pgtable.h>
+#include <asm/mach-types.h>
#include <asm/mach/map.h>
#include <asm/mach/time.h>
static unsigned ticks_per_jiffy;
static unsigned ticks_per_usec;
-unsigned long ixp2000_gettimeoffset (void)
+static unsigned long ixp2000_gettimeoffset (void)
{
unsigned long elapsed;
static int ixp2000_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
- write_seqlock(&xtime_lock);
-
/* clear timer 1 */
ixp2000_reg_write(IXP2000_T1_CLR, 1);
timer_tick(regs);
- write_sequnlock(&xtime_lock);
-
return IRQ_HANDLED;
}
void __init ixp2000_init_time(unsigned long tick_rate)
{
+ gettimeoffset = ixp2000_gettimeoffset;
+
ixp2000_reg_write(IXP2000_T1_CLR, 0);
ixp2000_reg_write(IXP2000_T2_CLR, 0);
.unmask = ixp2000_pci_irq_unmask
};
+/*
+ * Error interrupts. These are used extensively by the microengine drivers
+ */
+static void ixp2000_err_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
+{
+ int i;
+ unsigned long status = *IXP2000_IRQ_ERR_STATUS;
+
+
+ for (i = 0; i <= 12; i++) {
+ if (status & (1 << i)) {
+ desc = irq_desc + IRQ_IXP2000_DRAM0_MIN_ERR + i;
+ desc->handle(IRQ_IXP2000_DRAM0_MIN_ERR + i, desc, regs);
+ }
+ }
+}
+
+static void ixp2000_err_irq_mask(unsigned int irq)
+{
+ ixp2000_reg_write(IXP2000_IRQ_ERR_ENABLE_CLR,
+ (1 << (irq - IRQ_IXP2000_DRAM0_MIN_ERR)));
+}
+
+static void ixp2000_err_irq_unmask(unsigned int irq)
+{
+ ixp2000_reg_write(IXP2000_IRQ_ERR_ENABLE_SET,
+ (1 << (irq - IRQ_IXP2000_DRAM0_MIN_ERR)));
+}
+
+static struct irqchip ixp2000_err_irq_chip = {
+ .ack = ixp2000_err_irq_mask,
+ .mask = ixp2000_err_irq_mask,
+ .unmask = ixp2000_err_irq_unmask
+};
+
static void ixp2000_irq_mask(unsigned int irq)
{
ixp2000_reg_write(IXP2000_IRQ_ENABLE_CLR, (1 << irq));
* we mark the reserved IRQs as invalid. This makes
* our mask/unmask code much simpler.
*/
- for (irq = IRQ_IXP2000_SOFT_INT; irq <= IRQ_IXP2000_THDB3; irq++) {
+ for (irq = IRQ_IXP2000_SWI; irq <= IRQ_IXP2000_THDB3; irq++) {
if((1 << irq) & IXP2000_VALID_IRQ_MASK) {
set_irq_chip(irq, &ixp2000_irq_chip);
set_irq_handler(irq, do_level_IRQ);
/*
* Enable PCI irq
*/
- ixp2000_reg_write(IXP2000_IRQ_ENABLE_SET, (1 << IRQ_IXP2000_PCI));
+ *(IXP2000_IRQ_ENABLE_SET) = (1 << IRQ_IXP2000_PCI);
for (irq = IRQ_IXP2000_PCIA; irq <= IRQ_IXP2000_PCIB; irq++) {
set_irq_chip(irq, &ixp2000_pci_irq_chip);
set_irq_handler(irq, do_level_IRQ);
set_irq_flags(irq, IRQF_VALID);
}
+
+ for (irq = IRQ_IXP2000_DRAM0_MIN_ERR; irq <= IRQ_IXP2000_SP_INT; irq++) {
+ set_irq_chip(irq, &ixp2000_err_irq_chip);
+ set_irq_handler(irq, do_level_IRQ);
+ set_irq_flags(irq, IRQF_VALID);
+ }
+ set_irq_chained_handler(IRQ_IXP2000_ERRSUM, ixp2000_err_irq_handler);
}