-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Formerly implemented by ADX, we can use this generically, so move it over. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
- Loading branch information
Paul Mundt
committed
Sep 27, 2006
1 parent
5a4053b
commit ba46393
Showing
3 changed files
with
105 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
/* | ||
* Interrupt handling for Simple external interrupt mask register | ||
* | ||
* Copyright (C) 2001 A&D Co., Ltd. <http://www.aandd.co.jp> | ||
* | ||
* This is for the machine which have single 16 bit register | ||
* for masking external IRQ individually. | ||
* Each bit of the register is for masking each interrupt. | ||
* | ||
* This file may be copied or modified under the terms of the GNU | ||
* General Public License. See linux/COPYING for more information. | ||
*/ | ||
#include <linux/kernel.h> | ||
#include <linux/init.h> | ||
#include <linux/irq.h> | ||
#include <asm/system.h> | ||
#include <asm/io.h> | ||
|
||
/* address of external interrupt mask register */ | ||
unsigned long irq_mask_register; | ||
|
||
/* forward declaration */ | ||
static unsigned int startup_maskreg_irq(unsigned int irq); | ||
static void shutdown_maskreg_irq(unsigned int irq); | ||
static void enable_maskreg_irq(unsigned int irq); | ||
static void disable_maskreg_irq(unsigned int irq); | ||
static void mask_and_ack_maskreg(unsigned int); | ||
static void end_maskreg_irq(unsigned int irq); | ||
|
||
/* hw_interrupt_type */ | ||
static struct hw_interrupt_type maskreg_irq_type = { | ||
.typename = "Mask Register", | ||
.startup = startup_maskreg_irq, | ||
.shutdown = shutdown_maskreg_irq, | ||
.enable = enable_maskreg_irq, | ||
.disable = disable_maskreg_irq, | ||
.ack = mask_and_ack_maskreg, | ||
.end = end_maskreg_irq | ||
}; | ||
|
||
/* actual implementatin */ | ||
static unsigned int startup_maskreg_irq(unsigned int irq) | ||
{ | ||
enable_maskreg_irq(irq); | ||
return 0; /* never anything pending */ | ||
} | ||
|
||
static void shutdown_maskreg_irq(unsigned int irq) | ||
{ | ||
disable_maskreg_irq(irq); | ||
} | ||
|
||
static void disable_maskreg_irq(unsigned int irq) | ||
{ | ||
unsigned long flags; | ||
unsigned short val, mask = 0x01 << irq; | ||
|
||
BUG_ON(!irq_mask_register); | ||
|
||
/* Set "irq"th bit */ | ||
local_irq_save(flags); | ||
val = ctrl_inw(irq_mask_register); | ||
val |= mask; | ||
ctrl_outw(val, irq_mask_register); | ||
local_irq_restore(flags); | ||
} | ||
|
||
static void enable_maskreg_irq(unsigned int irq) | ||
{ | ||
unsigned long flags; | ||
unsigned short val, mask = ~(0x01 << irq); | ||
|
||
BUG_ON(!irq_mask_register); | ||
|
||
/* Clear "irq"th bit */ | ||
local_irq_save(flags); | ||
val = ctrl_inw(irq_mask_register); | ||
val &= mask; | ||
ctrl_outw(val, irq_mask_register); | ||
local_irq_restore(flags); | ||
} | ||
|
||
static void mask_and_ack_maskreg(unsigned int irq) | ||
{ | ||
disable_maskreg_irq(irq); | ||
} | ||
|
||
static void end_maskreg_irq(unsigned int irq) | ||
{ | ||
if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) | ||
enable_maskreg_irq(irq); | ||
} | ||
|
||
void make_maskreg_irq(unsigned int irq) | ||
{ | ||
disable_irq_nosync(irq); | ||
irq_desc[irq].handler = &maskreg_irq_type; | ||
disable_maskreg_irq(irq); | ||
} |