1/* 2 * linux/arch/sh/boards/renesas/systemh/irq.c 3 * 4 * Copyright (C) 2000 Kazumoto Kojima 5 * 6 * Hitachi SystemH Support. 7 * 8 * Modified for 7751 SystemH by 9 * Jonathan Short. 10 */ 11 12#include <linux/init.h> 13#include <linux/irq.h> 14 15#include <linux/hdreg.h> 16#include <linux/ide.h> 17#include <asm/io.h> 18#include <asm/systemh7751.h> 19#include <asm/smc37c93x.h> 20 21static unsigned long *systemh_irq_mask_register = (unsigned long *)0xB3F10004; 22static unsigned long *systemh_irq_request_register = (unsigned long *)0xB3F10000; 23 24/* forward declaration */ 25static unsigned int startup_systemh_irq(unsigned int irq); 26static void shutdown_systemh_irq(unsigned int irq); 27static void enable_systemh_irq(unsigned int irq); 28static void disable_systemh_irq(unsigned int irq); 29static void mask_and_ack_systemh(unsigned int); 30static void end_systemh_irq(unsigned int irq); 31 32/* hw_interrupt_type */ 33static struct hw_interrupt_type systemh_irq_type = { 34 .typename = " SystemH Register", 35 .startup = startup_systemh_irq, 36 .shutdown = shutdown_systemh_irq, 37 .enable = enable_systemh_irq, 38 .disable = disable_systemh_irq, 39 .ack = mask_and_ack_systemh, 40 .end = end_systemh_irq 41}; 42 43static unsigned int startup_systemh_irq(unsigned int irq) 44{ 45 enable_systemh_irq(irq); 46 return 0; /* never anything pending */ 47} 48 49static void shutdown_systemh_irq(unsigned int irq) 50{ 51 disable_systemh_irq(irq); 52} 53 54static void disable_systemh_irq(unsigned int irq) 55{ 56 if (systemh_irq_mask_register) { 57 unsigned long val, mask = 0x01 << 1; 58 59 /* Clear the "irq"th bit in the mask and set it in the request */ 60 val = ctrl_inl((unsigned long)systemh_irq_mask_register); 61 val &= ~mask; 62 ctrl_outl(val, (unsigned long)systemh_irq_mask_register); 63 64 val = ctrl_inl((unsigned long)systemh_irq_request_register); 65 val |= mask; 66 ctrl_outl(val, (unsigned long)systemh_irq_request_register); 67 } 68} 69 70static void enable_systemh_irq(unsigned int irq) 71{ 72 if (systemh_irq_mask_register) { 73 unsigned long val, mask = 0x01 << 1; 74 75 /* Set "irq"th bit in the mask register */ 76 val = ctrl_inl((unsigned long)systemh_irq_mask_register); 77 val |= mask; 78 ctrl_outl(val, (unsigned long)systemh_irq_mask_register); 79 } 80} 81 82static void mask_and_ack_systemh(unsigned int irq) 83{ 84 disable_systemh_irq(irq); 85} 86 87static void end_systemh_irq(unsigned int irq) 88{ 89 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) 90 enable_systemh_irq(irq); 91} 92 93void make_systemh_irq(unsigned int irq) 94{ 95 disable_irq_nosync(irq); 96 irq_desc[irq].chip = &systemh_irq_type; 97 disable_systemh_irq(irq); 98} 99