| kogiidena | 94c0fa5 | 2006-09-27 14:53:35 +0900 | [diff] [blame] | 1 | /* | 
 | 2 |  * arch/sh/boards/landisk/irq.c | 
 | 3 |  * | 
 | 4 |  * Copyright (C) 2001  Ian da Silva, Jeremy Siegel | 
 | 5 |  * Based largely on io_se.c. | 
 | 6 |  * | 
 | 7 |  * I/O routine for I-O Data Device, Inc. LANDISK. | 
 | 8 |  * | 
 | 9 |  * Initial version only to support LAN access; some | 
 | 10 |  * placeholder code from io_landisk.c left in with the | 
 | 11 |  * expectation of later SuperIO and PCMCIA access. | 
 | 12 |  */ | 
 | 13 | /* | 
 | 14 |  * modified by kogiidena | 
 | 15 |  * 2005.03.03 | 
 | 16 |  */ | 
| kogiidena | 94c0fa5 | 2006-09-27 14:53:35 +0900 | [diff] [blame] | 17 | #include <linux/init.h> | 
 | 18 | #include <linux/irq.h> | 
| Paul Mundt | b6250e3 | 2006-12-07 17:27:18 +0900 | [diff] [blame] | 19 | #include <linux/interrupt.h> | 
 | 20 | #include <linux/io.h> | 
| kogiidena | 94c0fa5 | 2006-09-27 14:53:35 +0900 | [diff] [blame] | 21 | #include <asm/landisk/iodata_landisk.h> | 
 | 22 |  | 
 | 23 | static void enable_landisk_irq(unsigned int irq); | 
 | 24 | static void disable_landisk_irq(unsigned int irq); | 
 | 25 |  | 
 | 26 | /* shutdown is same as "disable" */ | 
 | 27 | #define shutdown_landisk_irq disable_landisk_irq | 
 | 28 |  | 
 | 29 | static void ack_landisk_irq(unsigned int irq); | 
 | 30 | static void end_landisk_irq(unsigned int irq); | 
 | 31 |  | 
 | 32 | static unsigned int startup_landisk_irq(unsigned int irq) | 
 | 33 | { | 
 | 34 | 	enable_landisk_irq(irq); | 
 | 35 | 	return 0;		/* never anything pending */ | 
 | 36 | } | 
 | 37 |  | 
 | 38 | static void disable_landisk_irq(unsigned int irq) | 
 | 39 | { | 
| kogiidena | 94c0fa5 | 2006-09-27 14:53:35 +0900 | [diff] [blame] | 40 | 	unsigned char val; | 
 | 41 | 	unsigned char mask = 0xff ^ (0x01 << (irq - 5)); | 
 | 42 |  | 
 | 43 | 	/* Set the priority in IPR to 0 */ | 
| kogiidena | 94c0fa5 | 2006-09-27 14:53:35 +0900 | [diff] [blame] | 44 | 	val = ctrl_inb(PA_IMASK); | 
 | 45 | 	val &= mask; | 
 | 46 | 	ctrl_outb(val, PA_IMASK); | 
| kogiidena | 94c0fa5 | 2006-09-27 14:53:35 +0900 | [diff] [blame] | 47 | } | 
 | 48 |  | 
 | 49 | static void enable_landisk_irq(unsigned int irq) | 
 | 50 | { | 
| kogiidena | 94c0fa5 | 2006-09-27 14:53:35 +0900 | [diff] [blame] | 51 | 	unsigned char val; | 
 | 52 | 	unsigned char value = (0x01 << (irq - 5)); | 
 | 53 |  | 
 | 54 | 	/* Set priority in IPR back to original value */ | 
| kogiidena | 94c0fa5 | 2006-09-27 14:53:35 +0900 | [diff] [blame] | 55 | 	val = ctrl_inb(PA_IMASK); | 
 | 56 | 	val |= value; | 
 | 57 | 	ctrl_outb(val, PA_IMASK); | 
| kogiidena | 94c0fa5 | 2006-09-27 14:53:35 +0900 | [diff] [blame] | 58 | } | 
 | 59 |  | 
 | 60 | static void ack_landisk_irq(unsigned int irq) | 
 | 61 | { | 
 | 62 | 	disable_landisk_irq(irq); | 
 | 63 | } | 
 | 64 |  | 
 | 65 | static void end_landisk_irq(unsigned int irq) | 
 | 66 | { | 
 | 67 | 	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) | 
 | 68 | 		enable_landisk_irq(irq); | 
 | 69 | } | 
 | 70 |  | 
 | 71 | static struct hw_interrupt_type landisk_irq_type = { | 
 | 72 | 	.typename = "LANDISK IRQ", | 
 | 73 | 	.startup = startup_landisk_irq, | 
 | 74 | 	.shutdown = shutdown_landisk_irq, | 
 | 75 | 	.enable = enable_landisk_irq, | 
 | 76 | 	.disable = disable_landisk_irq, | 
 | 77 | 	.ack = ack_landisk_irq, | 
 | 78 | 	.end = end_landisk_irq | 
 | 79 | }; | 
 | 80 |  | 
 | 81 | static void make_landisk_irq(unsigned int irq) | 
 | 82 | { | 
 | 83 | 	disable_irq_nosync(irq); | 
| Paul Mundt | 711fa80 | 2006-10-03 13:14:04 +0900 | [diff] [blame] | 84 | 	irq_desc[irq].chip = &landisk_irq_type; | 
| kogiidena | 94c0fa5 | 2006-09-27 14:53:35 +0900 | [diff] [blame] | 85 | 	disable_landisk_irq(irq); | 
 | 86 | } | 
 | 87 |  | 
 | 88 | /* | 
 | 89 |  * Initialize IRQ setting | 
 | 90 |  */ | 
 | 91 | void __init init_landisk_IRQ(void) | 
 | 92 | { | 
 | 93 | 	int i; | 
 | 94 |  | 
 | 95 | 	for (i = 5; i < 14; i++) | 
 | 96 | 		make_landisk_irq(i); | 
 | 97 | } |