Re: Mips IRQ support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




On Tue, 22 Jan 2002, Jun Sun wrote:

> The best way is to provide hw_irq_controller structure for the extended CPU
> IRQ feature.  See arch/mips/kernel/irq_cpu.c file and its related config
> option.

Attached is such a file.

Jason

/* Copyright 2002 Jason Gunthorpe <jgg@debian.org>   
   Modified from arch/mips/kernel/irq_cpu.S:   
   Copyright 2001 MontaVista Software Inc.
   Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
  
   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 the
   Free Software Foundation;  either version 2 of the  License, or (at your
   option) any later version.

   This is an addendum to irq_cpu to support the additional RM7000 
   interrupt sources. irq_cpu handles the lower 8 interrupts, this does 
   the remaining 6.
 */

#include <linux/irq.h>
#include <linux/types.h>
#include <linux/kernel.h>

#include <asm/mipsregs.h>

/* Move me to asm-mips/mipsregs.h */
#define __BUILD_SET_CP0_SET1(name,register)                     \
extern __inline__ unsigned int                                  \
set_cp0_##name(unsigned int set)				\
{                                                               \
	unsigned int res;                                       \
                                                                \
	res = read_32bit_cp0_set1_register(register);           \
	res |= set;						\
	write_32bit_cp0_set1_register(register, res);        	\
                                                                \
	return res;                                             \
}								\
								\
extern __inline__ unsigned int                                  \
clear_cp0_##name(unsigned int clear)				\
{                                                               \
	unsigned int res;                                       \
                                                                \
	res = read_32bit_cp0_set1_register(register);           \
	res &= ~clear;						\
	write_32bit_cp0_set1_register(register, res);		\
                                                                \
	return res;                                             \
}								\
								\
extern __inline__ unsigned int                                  \
change_cp0_##name(unsigned int change, unsigned int new)	\
{                                                               \
	unsigned int res;                                       \
                                                                \
	res = read_32bit_cp0_set1_register(register);           \
	res &= ~change;                                         \
	res |= (new & change);                                  \
	if(change)                                              \
		write_32bit_cp0_set1_register(register, res);   \
                                                                \
	return res;                                             \
}

__BUILD_SET_CP0_SET1(s1_intcontrol,CP0_S1_INTCONTROL)
   
static int mips_rm7kcpu_irq_base;
   
static void 
mips_rm7kcpu_irq_enable(unsigned int irq)
{
	set_cp0_s1_intcontrol(1 << (irq - mips_rm7kcpu_irq_base + 8));
}

static void 
mips_rm7kcpu_irq_disable(unsigned int irq)
{
	clear_cp0_s1_intcontrol(1 << (irq - mips_rm7kcpu_irq_base + 8));
}

static unsigned int mips_rm7kcpu_irq_startup(unsigned int irq)
{
	mips_rm7kcpu_irq_enable(irq);
	return 0;
}

#define	mips_rm7kcpu_irq_shutdown	mips_rm7kcpu_irq_disable

static void
mips_rm7kcpu_irq_ack(unsigned int irq)
{
	/* disable this interrupt - so that we safe proceed to the handler */
	mips_rm7kcpu_irq_disable(irq);
}

static void
mips_rm7kcpu_irq_end(unsigned int irq)
{
	mips_rm7kcpu_irq_enable(irq);
}

static hw_irq_controller mips_rm7kcpu_irq_controller = {
	"RM7KCPU_irq",
	mips_rm7kcpu_irq_startup,
	mips_rm7kcpu_irq_shutdown,
	mips_rm7kcpu_irq_enable,
	mips_rm7kcpu_irq_disable,
	mips_rm7kcpu_irq_ack,
	mips_rm7kcpu_irq_end,
	NULL			/* no affinity stuff for UP */
};


void 
mips_rm7kcpu_irq_init(u32 irq_base)
{
	extern irq_desc_t irq_desc[];
	u32 i;

	for (i= irq_base; i< irq_base+6; i++) {
		irq_desc[i].status = IRQ_DISABLED;
		irq_desc[i].action = NULL;
		irq_desc[i].depth = 1;
		irq_desc[i].handler = &mips_rm7kcpu_irq_controller;
	}
        mips_rm7kcpu_irq_base = irq_base;
   
        // Enable TE, the dedicated timer IRQ. It shows up as irq_base + 4
	set_cp0_s1_intcontrol(1 << 7);
}



[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux