~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to arch/sparc/kernel/sun4m_irq.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*  sun4m_irq.c
2
 
 *  arch/sparc/kernel/sun4m_irq.c:
 
1
/*
 
2
 * sun4m irq support
3
3
 *
4
4
 *  djhr: Hacked out of irq.c into a CPU dependent version.
5
5
 *
9
9
 *  Copyright (C) 1996 Dave Redman (djhr@tadpole.co.uk)
10
10
 */
11
11
 
12
 
#include <linux/errno.h>
13
 
#include <linux/linkage.h>
14
 
#include <linux/kernel_stat.h>
15
 
#include <linux/signal.h>
16
 
#include <linux/sched.h>
17
 
#include <linux/ptrace.h>
18
 
#include <linux/smp.h>
19
 
#include <linux/interrupt.h>
20
 
#include <linux/init.h>
21
 
#include <linux/ioport.h>
22
 
#include <linux/of.h>
23
 
#include <linux/of_device.h>
24
 
 
25
 
#include <asm/ptrace.h>
26
 
#include <asm/processor.h>
27
 
#include <asm/system.h>
28
 
#include <asm/psr.h>
29
 
#include <asm/vaddrs.h>
30
12
#include <asm/timer.h>
31
 
#include <asm/openprom.h>
32
 
#include <asm/oplib.h>
33
13
#include <asm/traps.h>
34
14
#include <asm/pgalloc.h>
35
15
#include <asm/pgtable.h>
36
 
#include <asm/smp.h>
37
16
#include <asm/irq.h>
38
17
#include <asm/io.h>
39
18
#include <asm/cacheflush.h>
40
19
 
41
20
#include "irq.h"
42
 
 
43
 
struct sun4m_irq_percpu {
44
 
        u32             pending;
45
 
        u32             clear;
46
 
        u32             set;
47
 
};
48
 
 
49
 
struct sun4m_irq_global {
50
 
        u32             pending;
51
 
        u32             mask;
52
 
        u32             mask_clear;
53
 
        u32             mask_set;
54
 
        u32             interrupt_target;
55
 
};
56
 
 
57
 
/* Code in entry.S needs to get at these register mappings.  */
58
 
struct sun4m_irq_percpu __iomem *sun4m_irq_percpu[SUN4M_NCPUS];
59
 
struct sun4m_irq_global __iomem *sun4m_irq_global;
60
 
 
61
 
/* Dave Redman (djhr@tadpole.co.uk)
62
 
 * The sun4m interrupt registers.
63
 
 */
64
 
#define SUN4M_INT_ENABLE        0x80000000
65
 
#define SUN4M_INT_E14           0x00000080
66
 
#define SUN4M_INT_E10           0x00080000
67
 
 
68
 
#define SUN4M_HARD_INT(x)       (0x000000001 << (x))
69
 
#define SUN4M_SOFT_INT(x)       (0x000010000 << (x))
70
 
 
71
 
#define SUN4M_INT_MASKALL       0x80000000        /* mask all interrupts */
72
 
#define SUN4M_INT_MODULE_ERR    0x40000000        /* module error */
73
 
#define SUN4M_INT_M2S_WRITE_ERR 0x20000000        /* write buffer error */
74
 
#define SUN4M_INT_ECC_ERR       0x10000000        /* ecc memory error */
75
 
#define SUN4M_INT_VME_ERR       0x08000000        /* vme async error */
76
 
#define SUN4M_INT_FLOPPY        0x00400000        /* floppy disk */
77
 
#define SUN4M_INT_MODULE        0x00200000        /* module interrupt */
78
 
#define SUN4M_INT_VIDEO         0x00100000        /* onboard video */
79
 
#define SUN4M_INT_REALTIME      0x00080000        /* system timer */
80
 
#define SUN4M_INT_SCSI          0x00040000        /* onboard scsi */
81
 
#define SUN4M_INT_AUDIO         0x00020000        /* audio/isdn */
82
 
#define SUN4M_INT_ETHERNET      0x00010000        /* onboard ethernet */
83
 
#define SUN4M_INT_SERIAL        0x00008000        /* serial ports */
84
 
#define SUN4M_INT_KBDMS         0x00004000        /* keyboard/mouse */
85
 
#define SUN4M_INT_SBUSBITS      0x00003F80        /* sbus int bits */
86
 
#define SUN4M_INT_VMEBITS       0x0000007F        /* vme int bits */
87
 
 
88
 
#define SUN4M_INT_ERROR         (SUN4M_INT_MODULE_ERR |    \
89
 
                                 SUN4M_INT_M2S_WRITE_ERR | \
90
 
                                 SUN4M_INT_ECC_ERR |       \
91
 
                                 SUN4M_INT_VME_ERR)
92
 
 
93
 
#define SUN4M_INT_SBUS(x)       (1 << (x+7))
94
 
#define SUN4M_INT_VME(x)        (1 << (x))
95
 
 
96
 
/* Interrupt levels used by OBP */
97
 
#define OBP_INT_LEVEL_SOFT      0x10
98
 
#define OBP_INT_LEVEL_ONBOARD   0x20
99
 
#define OBP_INT_LEVEL_SBUS      0x30
100
 
#define OBP_INT_LEVEL_VME       0x40
101
 
 
102
 
/* Interrupt level assignment on sun4m:
 
21
#include "kernel.h"
 
22
 
 
23
/* Sample sun4m IRQ layout:
 
24
 *
 
25
 * 0x22 - Power
 
26
 * 0x24 - ESP SCSI
 
27
 * 0x26 - Lance ethernet
 
28
 * 0x2b - Floppy
 
29
 * 0x2c - Zilog uart
 
30
 * 0x32 - SBUS level 0
 
31
 * 0x33 - Parallel port, SBUS level 1
 
32
 * 0x35 - SBUS level 2
 
33
 * 0x37 - SBUS level 3
 
34
 * 0x39 - Audio, Graphics card, SBUS level 4
 
35
 * 0x3b - SBUS level 5
 
36
 * 0x3d - SBUS level 6
 
37
 *
 
38
 * Each interrupt source has a mask bit in the interrupt registers.
 
39
 * When the mask bit is set, this blocks interrupt deliver.  So you
 
40
 * clear the bit to enable the interrupt.
 
41
 *
 
42
 * Interrupts numbered less than 0x10 are software triggered interrupts
 
43
 * and unused by Linux.
 
44
 *
 
45
 * Interrupt level assignment on sun4m:
103
46
 *
104
47
 *      level           source
105
48
 * ------------------------------------------------------------
106
 
 *        1             softint-1
 
49
 *        1             softint-1
107
50
 *        2             softint-2, VME/SBUS level 1
108
51
 *        3             softint-3, VME/SBUS level 2
109
52
 *        4             softint-4, onboard SCSI
138
81
 * 'intr' property IRQ priority values from ss4, ss5, ss10, ss20, and
139
82
 * Tadpole S3 GX systems.
140
83
 *
141
 
 * esp:         0x24    onboard ESP SCSI
142
 
 * le:          0x26    onboard Lance ETHERNET
 
84
 * esp:         0x24    onboard ESP SCSI
 
85
 * le:          0x26    onboard Lance ETHERNET
143
86
 * p9100:       0x32    SBUS level 1 P9100 video
144
 
 * bpp:         0x33    SBUS level 2 BPP parallel port device
 
87
 * bpp:         0x33    SBUS level 2 BPP parallel port device
145
88
 * DBRI:        0x39    SBUS level 5 DBRI ISDN audio
146
89
 * SUNW,leo:    0x39    SBUS level 5 LEO video
147
90
 * pcmcia:      0x3b    SBUS level 6 PCMCIA controller
152
95
 * power:       0x22    onboard power device (XXX unknown mask bit XXX)
153
96
 */
154
97
 
155
 
static unsigned long irq_mask[0x50] = {
156
 
        /* SMP */
157
 
        0,  SUN4M_SOFT_INT(1),
158
 
        SUN4M_SOFT_INT(2),  SUN4M_SOFT_INT(3),
159
 
        SUN4M_SOFT_INT(4),  SUN4M_SOFT_INT(5),
160
 
        SUN4M_SOFT_INT(6),  SUN4M_SOFT_INT(7),
161
 
        SUN4M_SOFT_INT(8),  SUN4M_SOFT_INT(9),
162
 
        SUN4M_SOFT_INT(10), SUN4M_SOFT_INT(11),
163
 
        SUN4M_SOFT_INT(12), SUN4M_SOFT_INT(13),
164
 
        SUN4M_SOFT_INT(14), SUN4M_SOFT_INT(15),
165
 
        /* soft */
166
 
        0,  SUN4M_SOFT_INT(1),
167
 
        SUN4M_SOFT_INT(2),  SUN4M_SOFT_INT(3),
168
 
        SUN4M_SOFT_INT(4),  SUN4M_SOFT_INT(5),
169
 
        SUN4M_SOFT_INT(6),  SUN4M_SOFT_INT(7),
170
 
        SUN4M_SOFT_INT(8),  SUN4M_SOFT_INT(9),
171
 
        SUN4M_SOFT_INT(10), SUN4M_SOFT_INT(11),
172
 
        SUN4M_SOFT_INT(12), SUN4M_SOFT_INT(13),
173
 
        SUN4M_SOFT_INT(14), SUN4M_SOFT_INT(15),
174
 
        /* onboard */
 
98
 
 
99
/* Code in entry.S needs to get at these register mappings.  */
 
100
struct sun4m_irq_percpu __iomem *sun4m_irq_percpu[SUN4M_NCPUS];
 
101
struct sun4m_irq_global __iomem *sun4m_irq_global;
 
102
 
 
103
struct sun4m_handler_data {
 
104
        bool    percpu;
 
105
        long    mask;
 
106
};
 
107
 
 
108
/* Dave Redman (djhr@tadpole.co.uk)
 
109
 * The sun4m interrupt registers.
 
110
 */
 
111
#define SUN4M_INT_ENABLE        0x80000000
 
112
#define SUN4M_INT_E14           0x00000080
 
113
#define SUN4M_INT_E10           0x00080000
 
114
 
 
115
#define SUN4M_HARD_INT(x)       (0x000000001 << (x))
 
116
#define SUN4M_SOFT_INT(x)       (0x000010000 << (x))
 
117
 
 
118
#define SUN4M_INT_MASKALL       0x80000000        /* mask all interrupts */
 
119
#define SUN4M_INT_MODULE_ERR    0x40000000        /* module error */
 
120
#define SUN4M_INT_M2S_WRITE_ERR 0x20000000        /* write buffer error */
 
121
#define SUN4M_INT_ECC_ERR       0x10000000        /* ecc memory error */
 
122
#define SUN4M_INT_VME_ERR       0x08000000        /* vme async error */
 
123
#define SUN4M_INT_FLOPPY        0x00400000        /* floppy disk */
 
124
#define SUN4M_INT_MODULE        0x00200000        /* module interrupt */
 
125
#define SUN4M_INT_VIDEO         0x00100000        /* onboard video */
 
126
#define SUN4M_INT_REALTIME      0x00080000        /* system timer */
 
127
#define SUN4M_INT_SCSI          0x00040000        /* onboard scsi */
 
128
#define SUN4M_INT_AUDIO         0x00020000        /* audio/isdn */
 
129
#define SUN4M_INT_ETHERNET      0x00010000        /* onboard ethernet */
 
130
#define SUN4M_INT_SERIAL        0x00008000        /* serial ports */
 
131
#define SUN4M_INT_KBDMS         0x00004000        /* keyboard/mouse */
 
132
#define SUN4M_INT_SBUSBITS      0x00003F80        /* sbus int bits */
 
133
#define SUN4M_INT_VMEBITS       0x0000007F        /* vme int bits */
 
134
 
 
135
#define SUN4M_INT_ERROR         (SUN4M_INT_MODULE_ERR |    \
 
136
                                 SUN4M_INT_M2S_WRITE_ERR | \
 
137
                                 SUN4M_INT_ECC_ERR |       \
 
138
                                 SUN4M_INT_VME_ERR)
 
139
 
 
140
#define SUN4M_INT_SBUS(x)       (1 << (x+7))
 
141
#define SUN4M_INT_VME(x)        (1 << (x))
 
142
 
 
143
/* Interrupt levels used by OBP */
 
144
#define OBP_INT_LEVEL_SOFT      0x10
 
145
#define OBP_INT_LEVEL_ONBOARD   0x20
 
146
#define OBP_INT_LEVEL_SBUS      0x30
 
147
#define OBP_INT_LEVEL_VME       0x40
 
148
 
 
149
#define SUN4M_TIMER_IRQ         (OBP_INT_LEVEL_ONBOARD | 10)
 
150
#define SUN4M_PROFILE_IRQ       (OBP_INT_LEVEL_ONBOARD | 14)
 
151
 
 
152
static unsigned long sun4m_imask[0x50] = {
 
153
        /* 0x00 - SMP */
 
154
        0,  SUN4M_SOFT_INT(1),
 
155
        SUN4M_SOFT_INT(2),  SUN4M_SOFT_INT(3),
 
156
        SUN4M_SOFT_INT(4),  SUN4M_SOFT_INT(5),
 
157
        SUN4M_SOFT_INT(6),  SUN4M_SOFT_INT(7),
 
158
        SUN4M_SOFT_INT(8),  SUN4M_SOFT_INT(9),
 
159
        SUN4M_SOFT_INT(10), SUN4M_SOFT_INT(11),
 
160
        SUN4M_SOFT_INT(12), SUN4M_SOFT_INT(13),
 
161
        SUN4M_SOFT_INT(14), SUN4M_SOFT_INT(15),
 
162
        /* 0x10 - soft */
 
163
        0,  SUN4M_SOFT_INT(1),
 
164
        SUN4M_SOFT_INT(2),  SUN4M_SOFT_INT(3),
 
165
        SUN4M_SOFT_INT(4),  SUN4M_SOFT_INT(5),
 
166
        SUN4M_SOFT_INT(6),  SUN4M_SOFT_INT(7),
 
167
        SUN4M_SOFT_INT(8),  SUN4M_SOFT_INT(9),
 
168
        SUN4M_SOFT_INT(10), SUN4M_SOFT_INT(11),
 
169
        SUN4M_SOFT_INT(12), SUN4M_SOFT_INT(13),
 
170
        SUN4M_SOFT_INT(14), SUN4M_SOFT_INT(15),
 
171
        /* 0x20 - onboard */
175
172
        0, 0, 0, 0,
176
173
        SUN4M_INT_SCSI,  0, SUN4M_INT_ETHERNET, 0,
177
174
        SUN4M_INT_VIDEO, SUN4M_INT_MODULE,
178
175
        SUN4M_INT_REALTIME, SUN4M_INT_FLOPPY,
179
176
        (SUN4M_INT_SERIAL | SUN4M_INT_KBDMS),
180
 
        SUN4M_INT_AUDIO, 0, SUN4M_INT_MODULE_ERR,
181
 
        /* sbus */
 
177
        SUN4M_INT_AUDIO, SUN4M_INT_E14, SUN4M_INT_MODULE_ERR,
 
178
        /* 0x30 - sbus */
182
179
        0, 0, SUN4M_INT_SBUS(0), SUN4M_INT_SBUS(1),
183
180
        0, SUN4M_INT_SBUS(2), 0, SUN4M_INT_SBUS(3),
184
181
        0, SUN4M_INT_SBUS(4), 0, SUN4M_INT_SBUS(5),
185
182
        0, SUN4M_INT_SBUS(6), 0, 0,
186
 
        /* vme */
 
183
        /* 0x40 - vme */
187
184
        0, 0, SUN4M_INT_VME(0), SUN4M_INT_VME(1),
188
185
        0, SUN4M_INT_VME(2), 0, SUN4M_INT_VME(3),
189
186
        0, SUN4M_INT_VME(4), 0, SUN4M_INT_VME(5),
190
187
        0, SUN4M_INT_VME(6), 0, 0
191
188
};
192
189
 
193
 
static unsigned long sun4m_get_irqmask(unsigned int irq)
194
 
{
195
 
        unsigned long mask;
196
 
    
197
 
        if (irq < 0x50)
198
 
                mask = irq_mask[irq];
199
 
        else
200
 
                mask = 0;
201
 
 
202
 
        if (!mask)
203
 
                printk(KERN_ERR "sun4m_get_irqmask: IRQ%d has no valid mask!\n",
204
 
                       irq);
205
 
 
206
 
        return mask;
207
 
}
208
 
 
209
 
static void sun4m_disable_irq(unsigned int irq_nr)
210
 
{
211
 
        unsigned long mask, flags;
212
 
        int cpu = smp_processor_id();
213
 
 
214
 
        mask = sun4m_get_irqmask(irq_nr);
215
 
        local_irq_save(flags);
216
 
        if (irq_nr > 15)
217
 
                sbus_writel(mask, &sun4m_irq_global->mask_set);
218
 
        else
219
 
                sbus_writel(mask, &sun4m_irq_percpu[cpu]->set);
220
 
        local_irq_restore(flags);    
221
 
}
222
 
 
223
 
static void sun4m_enable_irq(unsigned int irq_nr)
224
 
{
225
 
        unsigned long mask, flags;
226
 
        int cpu = smp_processor_id();
227
 
 
228
 
        /* Dreadful floppy hack. When we use 0x2b instead of
229
 
         * 0x0b the system blows (it starts to whistle!).
230
 
         * So we continue to use 0x0b. Fixme ASAP. --P3
231
 
         */
232
 
        if (irq_nr != 0x0b) {
233
 
                mask = sun4m_get_irqmask(irq_nr);
234
 
                local_irq_save(flags);
235
 
                if (irq_nr > 15)
236
 
                        sbus_writel(mask, &sun4m_irq_global->mask_clear);
237
 
                else
238
 
                        sbus_writel(mask, &sun4m_irq_percpu[cpu]->clear);
239
 
                local_irq_restore(flags);    
240
 
        } else {
241
 
                local_irq_save(flags);
242
 
                sbus_writel(SUN4M_INT_FLOPPY, &sun4m_irq_global->mask_clear);
243
 
                local_irq_restore(flags);
244
 
        }
245
 
}
246
 
 
247
 
static unsigned long cpu_pil_to_imask[16] = {
248
 
/*0*/   0x00000000,
249
 
/*1*/   0x00000000,
250
 
/*2*/   SUN4M_INT_SBUS(0) | SUN4M_INT_VME(0),
251
 
/*3*/   SUN4M_INT_SBUS(1) | SUN4M_INT_VME(1),
252
 
/*4*/   SUN4M_INT_SCSI,
253
 
/*5*/   SUN4M_INT_SBUS(2) | SUN4M_INT_VME(2),
254
 
/*6*/   SUN4M_INT_ETHERNET,
255
 
/*7*/   SUN4M_INT_SBUS(3) | SUN4M_INT_VME(3),
256
 
/*8*/   SUN4M_INT_VIDEO,
257
 
/*9*/   SUN4M_INT_SBUS(4) | SUN4M_INT_VME(4) | SUN4M_INT_MODULE_ERR,
258
 
/*10*/  SUN4M_INT_REALTIME,
259
 
/*11*/  SUN4M_INT_SBUS(5) | SUN4M_INT_VME(5) | SUN4M_INT_FLOPPY,
260
 
/*12*/  SUN4M_INT_SERIAL  | SUN4M_INT_KBDMS,
261
 
/*13*/  SUN4M_INT_SBUS(6) | SUN4M_INT_VME(6) | SUN4M_INT_AUDIO,
262
 
/*14*/  SUN4M_INT_E14,
263
 
/*15*/  SUN4M_INT_ERROR
 
190
static void sun4m_mask_irq(struct irq_data *data)
 
191
{
 
192
        struct sun4m_handler_data *handler_data = data->handler_data;
 
193
        int cpu = smp_processor_id();
 
194
 
 
195
        if (handler_data->mask) {
 
196
                unsigned long flags;
 
197
 
 
198
                local_irq_save(flags);
 
199
                if (handler_data->percpu) {
 
200
                        sbus_writel(handler_data->mask, &sun4m_irq_percpu[cpu]->set);
 
201
                } else {
 
202
                        sbus_writel(handler_data->mask, &sun4m_irq_global->mask_set);
 
203
                }
 
204
                local_irq_restore(flags);
 
205
        }
 
206
}
 
207
 
 
208
static void sun4m_unmask_irq(struct irq_data *data)
 
209
{
 
210
        struct sun4m_handler_data *handler_data = data->handler_data;
 
211
        int cpu = smp_processor_id();
 
212
 
 
213
        if (handler_data->mask) {
 
214
                unsigned long flags;
 
215
 
 
216
                local_irq_save(flags);
 
217
                if (handler_data->percpu) {
 
218
                        sbus_writel(handler_data->mask, &sun4m_irq_percpu[cpu]->clear);
 
219
                } else {
 
220
                        sbus_writel(handler_data->mask, &sun4m_irq_global->mask_clear);
 
221
                }
 
222
                local_irq_restore(flags);
 
223
        }
 
224
}
 
225
 
 
226
static unsigned int sun4m_startup_irq(struct irq_data *data)
 
227
{
 
228
        irq_link(data->irq);
 
229
        sun4m_unmask_irq(data);
 
230
        return 0;
 
231
}
 
232
 
 
233
static void sun4m_shutdown_irq(struct irq_data *data)
 
234
{
 
235
        sun4m_mask_irq(data);
 
236
        irq_unlink(data->irq);
 
237
}
 
238
 
 
239
static struct irq_chip sun4m_irq = {
 
240
        .name           = "sun4m",
 
241
        .irq_startup    = sun4m_startup_irq,
 
242
        .irq_shutdown   = sun4m_shutdown_irq,
 
243
        .irq_mask       = sun4m_mask_irq,
 
244
        .irq_unmask     = sun4m_unmask_irq,
264
245
};
265
246
 
266
 
/* We assume the caller has disabled local interrupts when these are called,
267
 
 * or else very bizarre behavior will result.
268
 
 */
269
 
static void sun4m_disable_pil_irq(unsigned int pil)
270
 
{
271
 
        sbus_writel(cpu_pil_to_imask[pil], &sun4m_irq_global->mask_set);
272
 
}
273
 
 
274
 
static void sun4m_enable_pil_irq(unsigned int pil)
275
 
{
276
 
        sbus_writel(cpu_pil_to_imask[pil], &sun4m_irq_global->mask_clear);
 
247
 
 
248
static unsigned int sun4m_build_device_irq(struct platform_device *op,
 
249
                                           unsigned int real_irq)
 
250
{
 
251
        struct sun4m_handler_data *handler_data;
 
252
        unsigned int irq;
 
253
        unsigned int pil;
 
254
 
 
255
        if (real_irq >= OBP_INT_LEVEL_VME) {
 
256
                prom_printf("Bogus sun4m IRQ %u\n", real_irq);
 
257
                prom_halt();
 
258
        }
 
259
        pil = (real_irq & 0xf);
 
260
        irq = irq_alloc(real_irq, pil);
 
261
 
 
262
        if (irq == 0)
 
263
                goto out;
 
264
 
 
265
        handler_data = irq_get_handler_data(irq);
 
266
        if (unlikely(handler_data))
 
267
                goto out;
 
268
 
 
269
        handler_data = kzalloc(sizeof(struct sun4m_handler_data), GFP_ATOMIC);
 
270
        if (unlikely(!handler_data)) {
 
271
                prom_printf("IRQ: kzalloc(sun4m_handler_data) failed.\n");
 
272
                prom_halt();
 
273
        }
 
274
 
 
275
        handler_data->mask = sun4m_imask[real_irq];
 
276
        handler_data->percpu = real_irq < OBP_INT_LEVEL_ONBOARD;
 
277
        irq_set_chip_and_handler_name(irq, &sun4m_irq,
 
278
                                      handle_level_irq, "level");
 
279
        irq_set_handler_data(irq, handler_data);
 
280
 
 
281
out:
 
282
        return irq;
277
283
}
278
284
 
279
285
#ifdef CONFIG_SMP
280
286
static void sun4m_send_ipi(int cpu, int level)
281
287
{
282
 
        unsigned long mask = sun4m_get_irqmask(level);
283
 
        sbus_writel(mask, &sun4m_irq_percpu[cpu]->set);
 
288
        sbus_writel(SUN4M_SOFT_INT(level), &sun4m_irq_percpu[cpu]->set);
284
289
}
285
290
 
286
291
static void sun4m_clear_ipi(int cpu, int level)
287
292
{
288
 
        unsigned long mask = sun4m_get_irqmask(level);
289
 
        sbus_writel(mask, &sun4m_irq_percpu[cpu]->clear);
 
293
        sbus_writel(SUN4M_SOFT_INT(level), &sun4m_irq_percpu[cpu]->clear);
290
294
}
291
295
 
292
296
static void sun4m_set_udt(int cpu)
314
318
 
315
319
static struct sun4m_timer_global __iomem *timers_global;
316
320
 
317
 
#define TIMER_IRQ       (OBP_INT_LEVEL_ONBOARD | 10)
318
321
 
319
322
unsigned int lvl14_resolution = (((1000000/HZ) + 1) << 10);
320
323
 
350
353
        prom_halt();
351
354
}
352
355
 
353
 
/* Exported for sun4m_smp.c */
 
356
void sun4m_unmask_profile_irq(void)
 
357
{
 
358
        unsigned long flags;
 
359
 
 
360
        local_irq_save(flags);
 
361
        sbus_writel(sun4m_imask[SUN4M_PROFILE_IRQ], &sun4m_irq_global->mask_clear);
 
362
        local_irq_restore(flags);
 
363
}
 
364
 
354
365
void sun4m_clear_profile_irq(int cpu)
355
366
{
356
367
        sbus_readl(&timers_percpu[cpu]->l14_limit);
365
376
{
366
377
        struct device_node *dp = of_find_node_by_name(NULL, "counter");
367
378
        int i, err, len, num_cpu_timers;
 
379
        unsigned int irq;
368
380
        const u32 *addr;
369
381
 
370
382
        if (!dp) {
391
403
 
392
404
        master_l10_counter = &timers_global->l10_count;
393
405
 
394
 
        err = request_irq(TIMER_IRQ, counter_fn,
395
 
                          (IRQF_DISABLED | SA_STATIC_ALLOC), "timer", NULL);
 
406
        irq = sun4m_build_device_irq(NULL, SUN4M_TIMER_IRQ);
 
407
 
 
408
        err = request_irq(irq, counter_fn, IRQF_TIMER, "timer", NULL);
396
409
        if (err) {
397
410
                printk(KERN_ERR "sun4m_init_timers: Register IRQ error %d.\n",
398
411
                        err);
407
420
#ifdef CONFIG_SMP
408
421
        {
409
422
                unsigned long flags;
410
 
                extern unsigned long lvl14_save[4];
411
423
                struct tt_entry *trap_table = &sparc_ttable[SP_TRAP_IRQ1 + (14 - 1)];
412
424
 
413
425
                /* For SMP we use the level 14 ticker, however the bootup code
460
472
        if (num_cpu_iregs == 4)
461
473
                sbus_writel(0, &sun4m_irq_global->interrupt_target);
462
474
 
463
 
        BTFIXUPSET_CALL(enable_irq, sun4m_enable_irq, BTFIXUPCALL_NORM);
464
 
        BTFIXUPSET_CALL(disable_irq, sun4m_disable_irq, BTFIXUPCALL_NORM);
465
 
        BTFIXUPSET_CALL(enable_pil_irq, sun4m_enable_pil_irq, BTFIXUPCALL_NORM);
466
 
        BTFIXUPSET_CALL(disable_pil_irq, sun4m_disable_pil_irq, BTFIXUPCALL_NORM);
467
475
        BTFIXUPSET_CALL(clear_clock_irq, sun4m_clear_clock_irq, BTFIXUPCALL_NORM);
468
476
        BTFIXUPSET_CALL(load_profile_irq, sun4m_load_profile_irq, BTFIXUPCALL_NORM);
469
 
        sparc_init_timers = sun4m_init_timers;
 
477
 
 
478
        sparc_irq_config.init_timers = sun4m_init_timers;
 
479
        sparc_irq_config.build_device_irq = sun4m_build_device_irq;
 
480
 
470
481
#ifdef CONFIG_SMP
471
482
        BTFIXUPSET_CALL(set_cpu_int, sun4m_send_ipi, BTFIXUPCALL_NORM);
472
483
        BTFIXUPSET_CALL(clear_cpu_int, sun4m_clear_ipi, BTFIXUPCALL_NORM);