aboutsummaryrefslogtreecommitdiff
path: root/arch/arm/plat-s3c24xx/include/plat/irq.h
blob: 11a866466d803e13afbc4ee71da39a9493f34785 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/* linux/include/asm-arm/plat-s3c24xx/irq.h
 *
 * Copyright (c) 2004-2005 Simtec Electronics
 *	Ben Dooks <ben@simtec.co.uk>
 *
 * Header file for S3C24XX CPU IRQ support
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
*/

#include <linux/io.h>

#include <mach/irqs.h>
#include <mach/hardware.h>
#include <mach/regs-irq.h>
#include <mach/regs-gpio.h>

#define irqdbf(x...)
#define irqdbf2(x...)

#define EXTINT_OFF (IRQ_EINT4 - 4)

/* these are exported for arch/arm/mach-* usage */
extern struct irq_chip s3c_irq_level_chip;
extern struct irq_chip s3c_irq_chip;

static inline void
s3c_irqsub_mask(unsigned int irqno, unsigned int parentbit,
		int subcheck)
{
	unsigned long mask;
	unsigned long submask;
#ifdef CONFIG_S3C2440_C_FIQ
	unsigned long flags;
#endif

	submask = __raw_readl(S3C2410_INTSUBMSK);
#ifdef CONFIG_S3C2440_C_FIQ
	local_save_flags(flags);
	local_fiq_disable();
#endif
	mask = __raw_readl(S3C2410_INTMSK);

	submask |= (1UL << (irqno - IRQ_S3CUART_RX0));

	/* check to see if we need to mask the parent IRQ */

	if ((submask  & subcheck) == subcheck) {
		__raw_writel(mask | parentbit, S3C2410_INTMSK);
	}

	/* write back masks */
	__raw_writel(submask, S3C2410_INTSUBMSK);
#ifdef CONFIG_S3C2440_C_FIQ
	local_irq_restore(flags);
#endif

}

static inline void
s3c_irqsub_unmask(unsigned int irqno, unsigned int parentbit)
{
	unsigned long mask;
	unsigned long submask;
#ifdef CONFIG_S3C2440_C_FIQ
	unsigned long flags;
#endif

	submask = __raw_readl(S3C2410_INTSUBMSK);
#ifdef CONFIG_S3C2440_C_FIQ
	local_save_flags(flags);
	local_fiq_disable();
#endif
	mask = __raw_readl(S3C2410_INTMSK);

	submask &= ~(1UL << (irqno - IRQ_S3CUART_RX0));
	mask &= ~parentbit;

	/* write back masks */
	__raw_writel(submask, S3C2410_INTSUBMSK);
	__raw_writel(mask, S3C2410_INTMSK);
#ifdef CONFIG_S3C2440_C_FIQ
	local_irq_restore(flags);
#endif
}


static inline void
s3c_irqsub_maskack(unsigned int irqno, unsigned int parentmask, unsigned int group)
{
	unsigned int bit = 1UL << (irqno - IRQ_S3CUART_RX0);

	s3c_irqsub_mask(irqno, parentmask, group);

	__raw_writel(bit, S3C2410_SUBSRCPND);

	/* only ack parent if we've got all the irqs (seems we must
	 * ack, all and hope that the irq system retriggers ok when
	 * the interrupt goes off again)
	 */

	if (1) {
		__raw_writel(parentmask, S3C2410_SRCPND);
		__raw_writel(parentmask, S3C2410_INTPND);
	}
}

static inline void
s3c_irqsub_ack(unsigned int irqno, unsigned int parentmask, unsigned int group)
{
	unsigned int bit = 1UL << (irqno - IRQ_S3CUART_RX0);

	__raw_writel(bit, S3C2410_SUBSRCPND);

	/* only ack parent if we've got all the irqs (seems we must
	 * ack, all and hope that the irq system retriggers ok when
	 * the interrupt goes off again)
	 */

	if (1) {
		__raw_writel(parentmask, S3C2410_SRCPND);
		__raw_writel(parentmask, S3C2410_INTPND);
	}
}

/* exported for use in arch/arm/mach-s3c2410 */

#ifdef CONFIG_PM
extern int s3c_irq_wake(unsigned int irqno, unsigned int state);
#else
#define s3c_irq_wake NULL
#endif

extern int s3c_irqext_type(unsigned int irq, unsigned int type);