PageRenderTime 19ms CodeModel.GetById 2ms app.highlight 13ms RepoModel.GetById 1ms app.codeStats 0ms

/arch/sh/boards/harp/irq.c

https://bitbucket.org/evzijst/gittest
C | 148 lines | 102 code | 30 blank | 16 comment | 9 complexity | a6b4ca81f1abbfdd73835a1cf18ab368 MD5 | raw file
  1/* 
  2 * Copyright (C) 2000 David J. Mckay (david.mckay@st.com)
  3 *
  4 * May be copied or modified under the terms of the GNU General Public
  5 * License.  See linux/COPYING for more information.                            
  6 *
  7 * Looks after interrupts on the HARP board.
  8 *
  9 * Bases on the IPR irq system
 10 */
 11
 12#include <linux/config.h>
 13#include <linux/init.h>
 14#include <linux/irq.h>
 15
 16#include <asm/system.h>
 17#include <asm/io.h>
 18#include <asm/harp/harp.h>
 19
 20
 21#define NUM_EXTERNAL_IRQS 16
 22
 23// Early versions of the STB1 Overdrive required this nasty frig
 24//#define INVERT_INTMASK_WRITES
 25
 26static void enable_harp_irq(unsigned int irq);
 27static void disable_harp_irq(unsigned int irq);
 28
 29/* shutdown is same as "disable" */
 30#define shutdown_harp_irq disable_harp_irq
 31
 32static void mask_and_ack_harp(unsigned int);
 33static void end_harp_irq(unsigned int irq);
 34
 35static unsigned int startup_harp_irq(unsigned int irq)
 36{
 37	enable_harp_irq(irq);
 38	return 0;		/* never anything pending */
 39}
 40
 41static struct hw_interrupt_type harp_irq_type = {
 42	"Harp-IRQ",
 43	startup_harp_irq,
 44	shutdown_harp_irq,
 45	enable_harp_irq,
 46	disable_harp_irq,
 47	mask_and_ack_harp,
 48	end_harp_irq
 49};
 50
 51static void disable_harp_irq(unsigned int irq)
 52{
 53	unsigned val, flags;
 54	unsigned maskReg;
 55	unsigned mask;
 56	int pri;
 57
 58	if (irq < 0 || irq >= NUM_EXTERNAL_IRQS)
 59		return;
 60
 61	pri = 15 - irq;
 62
 63	if (pri < 8) {
 64		maskReg = EPLD_INTMASK0;
 65	} else {
 66		maskReg = EPLD_INTMASK1;
 67		pri -= 8;
 68	}
 69
 70	local_irq_save(flags);
 71	mask = ctrl_inl(maskReg);
 72	mask &= (~(1 << pri));
 73#if defined(INVERT_INTMASK_WRITES)
 74	mask ^= 0xff;
 75#endif
 76	ctrl_outl(mask, maskReg);
 77	local_irq_restore(flags);
 78}
 79
 80static void enable_harp_irq(unsigned int irq)
 81{
 82	unsigned flags;
 83	unsigned maskReg;
 84	unsigned mask;
 85	int pri;
 86
 87	if (irq < 0 || irq >= NUM_EXTERNAL_IRQS)
 88		return;
 89
 90	pri = 15 - irq;
 91
 92	if (pri < 8) {
 93		maskReg = EPLD_INTMASK0;
 94	} else {
 95		maskReg = EPLD_INTMASK1;
 96		pri -= 8;
 97	}
 98
 99	local_irq_save(flags);
100	mask = ctrl_inl(maskReg);
101
102
103	mask |= (1 << pri);
104
105#if defined(INVERT_INTMASK_WRITES)
106	mask ^= 0xff;
107#endif
108	ctrl_outl(mask, maskReg);
109
110	local_irq_restore(flags);
111}
112
113/* This functions sets the desired irq handler to be an overdrive type */
114static void __init make_harp_irq(unsigned int irq)
115{
116	disable_irq_nosync(irq);
117	irq_desc[irq].handler = &harp_irq_type;
118	disable_harp_irq(irq);
119}
120
121static void mask_and_ack_harp(unsigned int irq)
122{
123	disable_harp_irq(irq);
124}
125
126static void end_harp_irq(unsigned int irq)
127{
128	enable_harp_irq(irq);
129}
130
131void __init init_harp_irq(void)
132{
133	int i;
134
135#if !defined(INVERT_INTMASK_WRITES)
136	// On the harp these are set to enable an interrupt
137	ctrl_outl(0x00, EPLD_INTMASK0);
138	ctrl_outl(0x00, EPLD_INTMASK1);
139#else
140	// On the Overdrive the data is inverted before being stored in the reg
141	ctrl_outl(0xff, EPLD_INTMASK0);
142	ctrl_outl(0xff, EPLD_INTMASK1);
143#endif
144
145	for (i = 0; i < NUM_EXTERNAL_IRQS; i++) {
146		make_harp_irq(i);
147	}
148}