]> git.pld-linux.org Git - packages/kernel.git/blob - 2.2.21-ppc_openpic_fix.patch
- obsolete
[packages/kernel.git] / 2.2.21-ppc_openpic_fix.patch
1 diff -urN linux.orig/arch/ppc/kernel/chrp_setup.c linux/arch/ppc/kernel/chrp_setup.c
2 --- linux.orig/arch/ppc/kernel/chrp_setup.c     Sun Mar 25 18:31:49 2001
3 +++ linux/arch/ppc/kernel/chrp_setup.c  Tue Aug 27 15:46:50 2002
4 @@ -4,6 +4,7 @@
5   *  Copyright (C) 1995  Linus Torvalds
6   *  Adapted from 'alpha' version by Gary Thomas
7   *  Modified by Cort Dougan (cort@cs.nmt.edu)
8 + *  Fixed IRQ time out problem by Krzysztof Taraszka (dzimi@pld.org.pl)
9   */
10  
11  /*
12 @@ -359,6 +360,81 @@
13         }
14  }
15  
16 +void
17 +chrp_do_IRQ(struct pt_regs *regs,
18 +           int            cpu,
19 +            int            isfake)
20 +{
21 +        int irq;
22 +        unsigned long bits = 0;
23 +        int openpic_eoi_done = 0;
24 +
25 +#ifdef __SMP__
26 +        {
27 +                unsigned int loops = 1000000;
28 +                while (test_bit(0, &global_irq_lock)) {
29 +                        if (smp_processor_id() == global_irq_holder) {
30 +                                printk("uh oh, interrupt while we hold global irq lock!\n");
31 +#ifdef CONFIG_XMON
32 +                                xmon(0);
33 +#endif
34 +                                break;
35 +                        }
36 +                        if (loops-- == 0) {
37 +                                printk("do_IRQ waiting for irq lock (holder=%d)\n", global_irq_holder);
38 +#ifdef CONFIG_XMON
39 +                                xmon(0);
40 +#endif
41 +                        }
42 +                }
43 +        }
44 +#endif /* __SMP__ */
45 +       
46 +        irq = openpic_irq(smp_processor_id());
47 +        if (irq == IRQ_8259_CASCADE)
48 +        {
49 +                /*
50 +                 * This magic address generates a PCI IACK cycle.
51 +                 *
52 +                 * This should go in the above mask/ack code soon. -- Cort
53 +                 */
54 +               if ( chrp_int_ack_special )
55 +                       irq = *chrp_int_ack_special;
56 +               else
57 +                       irq = i8259_irq(0);
58 +                /*
59 +                 * Acknowledge as soon as possible to allow i8259
60 +                 * interrupt nesting                         */
61 +                openpic_eoi(smp_processor_id());
62 +                openpic_eoi_done = 1;
63 +        }
64 +        if (irq == OPENPIC_VEC_SPURIOUS)
65 +        {
66 +                /*
67 +                 * Spurious interrupts should never be
68 +                 * acknowledged
69 +                 */
70 +                ppc_spurious_interrupts++;
71 +                openpic_eoi_done = 1;
72 +               goto out;
73 +        }
74 +        bits = 1UL << irq;
75 +
76 +        if (irq < 0)
77 +        {
78 +                printk(KERN_DEBUG "Bogus interrupt %d from PC = %lx\n",
79 +                       irq, regs->nip);
80 +                ppc_spurious_interrupts++;
81 +        }
82 +       else
83 +        {
84 +               ppc_irq_dispatch_handler( regs, irq );
85 +       }
86 +out:
87 +        if (!openpic_eoi_done)
88 +                openpic_eoi(smp_processor_id());
89 +}
90 +
91  __initfunc(void
92            chrp_init_IRQ(void))
93  {
94 @@ -570,7 +646,7 @@
95         ppc_md.get_cpuinfo    = chrp_get_cpuinfo;
96         ppc_md.irq_cannonicalize = chrp_irq_cannonicalize;
97         ppc_md.init_IRQ       = chrp_init_IRQ;
98 -       ppc_md.do_IRQ         = open_pic_do_IRQ;
99 +       ppc_md.do_IRQ         = chrp_do_IRQ;
100                 
101         ppc_md.init           = chrp_init2;
102  
103 diff -urN linux.orig/arch/ppc/kernel/open_pic.c linux/arch/ppc/kernel/open_pic.c
104 --- linux.orig/arch/ppc/kernel/open_pic.c       Sun Mar 25 18:31:49 2001
105 +++ linux/arch/ppc/kernel/open_pic.c    Tue Aug 27 15:46:50 2002
106 @@ -11,116 +11,45 @@
107  #include <linux/signal.h>
108  #include <linux/openpic.h>
109  #include <asm/irq.h>
110 -#include <asm/processor.h>
111  #include "open_pic.h"
112  #include "i8259.h"
113  
114 -extern volatile unsigned char *chrp_int_ack_special;
115 -
116 -void open_pic_do_IRQ(struct pt_regs *regs, int cpu, int isfake)
117 -{
118 -       int irq;
119 -        int openpic_eoi_done = 0;
120 -
121  #ifdef __SMP__
122 -        {
123 -                unsigned int loops = 1000000;
124 -                while (test_bit(0, &global_irq_lock)) {
125 -                        if (smp_processor_id() == global_irq_holder) {
126 -                                printk("uh oh, interrupt while we hold global irq lock!\n");
127 -#ifdef CONFIG_XMON
128 -                                xmon(0);
129 -#endif
130 -                                break;
131 -                        }
132 -                        if (loops-- == 0) {
133 -                                printk("do_IRQ waiting for irq lock (holder=%d)\n", global_irq_holder);
134 -#ifdef CONFIG_XMON
135 -                                xmon(0);
136 -#endif
137 -                        }
138 -                }
139 -        }
140 +void openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs)
141 +{
142 +       smp_message_recv(cpl-OPENPIC_VEC_IPI);
143 +}
144  #endif /* __SMP__ */
145 -       
146 -        irq = openpic_irq(smp_processor_id());
147 -       /* make sure open_pic.irq_offset is set to something!
148 -        * do we really need the _MACH_Pmac test??
149 -        */
150 -        if (!(_machine == _MACH_Pmac) && (irq == open_pic.irq_offset))
151 -        {
152 -                /*
153 -                 * This magic address generates a PCI IACK cycle.
154 -                 *
155 -                 * This should go in the above mask/ack code soon. -- Cort
156 -                 */
157 -               if ( chrp_int_ack_special )
158 -                       irq = *chrp_int_ack_special;
159 -#ifndef CONFIG_PMAC
160 -               else
161 -                       irq = i8259_irq(0);
162 -#endif
163 -                /*
164 -                 * Acknowledge as soon as possible to allow i8259
165 -                 * interrupt nesting                         */
166 -                openpic_eoi(smp_processor_id());
167 -                openpic_eoi_done = 1;
168 -        }
169 -        if (irq == OPENPIC_VEC_SPURIOUS)
170 -        {
171 -                /*
172 -                 * Spurious interrupts should never be
173 -                 * acknowledged
174 -                 */
175 -                ppc_spurious_interrupts++;
176 -                openpic_eoi_done = 1;
177 -               goto out;
178 -        }
179  
180 -        if (irq < 0)
181 -        {
182 -                printk(KERN_DEBUG "Bogus interrupt %d from PC = %lx\n",
183 -                       irq, regs->nip);
184 -                ppc_spurious_interrupts++;
185 -        }
186 -       else
187 -        {
188 -               ppc_irq_dispatch_handler( regs, irq );
189 -       }
190 -out:
191 -        if (!openpic_eoi_done)
192 -                openpic_eoi(smp_processor_id());
193 +void chrp_mask_and_ack_irq(unsigned int irq_nr)
194 +{
195 +       if ((_machine != _MACH_gemini) && is_8259_irq(irq_nr))
196 +               i8259_pic.mask_and_ack(irq_nr);
197  }
198  
199 -#ifdef __SMP__
200 -void openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs)
201 +static void chrp_mask_irq(unsigned int irq_nr)
202  {
203 -       smp_message_recv(cpl-OPENPIC_VEC_IPI);
204 +       if ((_machine != _MACH_gemini) && is_8259_irq(irq_nr))
205 +               i8259_pic.disable(irq_nr);
206 +       else
207 +               openpic_disable_irq(irq_nr-open_pic.irq_offset);
208  }
209 -#endif /* __SMP__ */
210  
211 +static void chrp_unmask_irq(unsigned int irq_nr)
212 +{
213 +       if ((_machine != _MACH_gemini) && is_8259_irq(irq_nr))
214 +               i8259_pic.enable(irq_nr);
215 +       else
216 +               openpic_enable_irq(irq_nr-open_pic.irq_offset);
217 +}
218  
219  struct hw_interrupt_type open_pic = {
220         " OpenPIC  ",
221         NULL,
222         NULL,
223         NULL,
224 -       openpic_enable_irq,
225 -       openpic_disable_irq,
226 -       /* Theorically, the mask&ack should be NULL for OpenPIC. However, doing
227 -        * so shows tons of bogus interrupts coming in.
228 -        * This problem is apparently due to the common code always calling
229 -        * unmask(). I apparently (need more test) fixed it in the 2.4 new IRQ
230 -        * management by cleanly implementing the handler's end() function, so
231 -        * neither mask nor unmask are needed. In the meantime, the fix below will
232 -        * work for 2.2 -Benh
233 -        *
234 -        * Hopefully this will fix my bogus interrups on MTX
235 -        * I merged everthing together so we don't have the same code in three
236 -        * places. This might cause stability problems, but I'd rather
237 -        * get it right once than three different times because someone forgot
238 -        * to make the same change to PReP or something --Troy
239 -        */
240 -       openpic_disable_irq,
241 +       chrp_unmask_irq,
242 +       chrp_mask_irq,
243 +       chrp_mask_and_ack_irq,
244         0
245  };
246 diff -urN linux.orig/arch/ppc/kernel/open_pic.h linux/arch/ppc/kernel/open_pic.h
247 --- linux.orig/arch/ppc/kernel/open_pic.h       Sun Mar 25 18:31:49 2001
248 +++ linux/arch/ppc/kernel/open_pic.h    Tue Aug 27 15:46:50 2002
249 @@ -6,7 +6,6 @@
250  
251  extern struct hw_interrupt_type open_pic;
252  
253 -void open_pic_do_IRQ(struct pt_regs *regs, int cpu, int isfake);
254  void openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs);
255  void openpic_enable_IPI(u_int ipi);
256  void do_openpic_setup_cpu(void);
257 diff -urN linux.orig/arch/ppc/kernel/openpic.c linux/arch/ppc/kernel/openpic.c
258 --- linux.orig/arch/ppc/kernel/openpic.c        Fri Nov  2 17:39:05 2001
259 +++ linux/arch/ppc/kernel/openpic.c     Tue Aug 27 15:46:50 2002
260 @@ -10,6 +10,9 @@
261   *  to avoid bogus interrupts and to make sure the disable function exits with
262   *  the interrupt actually masked. --BenH
263   *  Todo: map interrupts to all available CPUs after the ack round
264 + *
265 + *  Fixed IRQ time out problem by 
266 + *    Krzysztof Taraszka (dzimi@pld.org.pl)
267   * 
268   *  This file is subject to the terms and conditions of the GNU General Public
269   *  License.  See the file COPYING in the main directory of this archive
270 @@ -33,6 +36,8 @@
271  #define REGISTER_DEBUG
272  #undef REGISTER_DEBUG
273  
274 +#define OPENPIC_SENSE_POLARITY                 0x00800000      /* Undoc'd */
275 +
276  #ifdef __powerpc__
277  extern int use_of_interrupt_tree;
278  #endif
279 @@ -173,7 +178,6 @@
280   * other ones are just masked out.
281   * Note: We might want to adjust priorities too.
282   */
283 -
284  /* Not an init func, called on pbook wakeup --BenH */
285  void
286  __init
287 @@ -229,7 +233,7 @@
288             
289                 /* Initialize IPI interrupts */
290                 for (i = 0; i < OPENPIC_NUM_IPI; i++) {
291 -                       openpic_initipi(i, 10+i, OPENPIC_VEC_IPI+i);
292 +                       openpic_initipi(i, 0/*10*/, OPENPIC_VEC_IPI+i);
293                 }
294             
295                 if (_machine != _MACH_Pmac) {
296 @@ -266,7 +270,7 @@
297                                         openpic_initirq(        np->intrs[j].line,
298                                                                 pri,
299                                                                 np->intrs[j].line,
300 -                                                               0,
301 +                                                               np->intrs[j].sense,
302                                                                 np->intrs[j].sense);
303                                         irq_desc[np->intrs[j].line].level = np->intrs[j].sense;
304                                     }
305 @@ -276,8 +280,8 @@
306                                 /* Fixme: read level value from controller */
307                                 printk("openpic: WARNING, openpic running without interrupt tree\n");
308                         }
309 -               }
310 -
311 +       }
312 +    
313                 /* Initialize the spurious interrupt */
314                 openpic_set_spurious(OPENPIC_VEC_SPURIOUS);
315  
316 @@ -311,10 +315,6 @@
317  {
318         openpic_setfield(&OpenPIC->Global.Global_Configuration0,
319                          OPENPIC_CONFIG_RESET);
320 -       /* Wait for reset to complete */
321 -       while(openpic_readfield(&OpenPIC->Global.Global_Configuration0,
322 -                       OPENPIC_CONFIG_RESET))
323 -               ;
324  }
325  
326  
327 @@ -465,12 +465,12 @@
328         
329         for ( i = 0; i < OPENPIC_NUM_IPI ; i++ )
330                   openpic_enable_IPI(i);
331 -
332 +#if 0  
333         /* let the openpic know we want intrs */
334         for ( i = 0; i < NumSources ; i++ )
335                 openpic_mapirq(i, openpic_read(&OpenPIC->Source[i].Destination)
336                                | (1<<smp_processor_id()) );
337 -
338 +#endif 
339         openpic_set_priority(smp_processor_id(), 0);
340  }    
341  
342 @@ -506,11 +506,7 @@
343   */
344  void openpic_enable_irq(u_int irq)
345  {
346 -       /* on SMP, we get IPI vector numbers here, we should handle them
347 -        * or at least ignore them.
348 -        */
349 -       if (irq < 0 || irq >= NumSources)
350 -               return;
351 +       check_arg_irq(irq);
352         openpic_clearfield(&OpenPIC->Source[irq].Vector_Priority, OPENPIC_MASK);
353         /* make sure mask gets to controller before we return to user */
354         do {
355 @@ -519,30 +515,15 @@
356                         OPENPIC_MASK));
357  }
358  
359 -u_int openpic_get_enable(u_int irq)
360 -{
361 -       if (irq < 0 || irq >= NumSources)
362 -               return 0;
363 -       return !openpic_readfield(&OpenPIC->Source[irq].Vector_Priority,
364 -                       OPENPIC_MASK);
365 -}
366 -
367  void openpic_disable_irq(u_int irq)
368  {
369 -       u32 vp;
370 -       
371 -       /* on SMP, we get IPI vector numbers here, we should handle them
372 -        * or at least ignore them.
373 -        */
374 -       if (irq < 0 || irq >= NumSources)
375 -               return;
376 +       check_arg_irq(irq);
377         openpic_setfield(&OpenPIC->Source[irq].Vector_Priority, OPENPIC_MASK);
378         /* make sure mask gets to controller before we return to user */
379         do {
380 -               mb();  /* sync is probably useless here */
381 -               vp = openpic_readfield(&OpenPIC->Source[irq].Vector_Priority,
382 -                       OPENPIC_MASK | OPENPIC_ACTIVITY);
383 -       } while((vp & OPENPIC_ACTIVITY) && !(vp & OPENPIC_MASK));
384 +               mb();
385 +       } while(!openpic_readfield(&OpenPIC->Source[irq].Vector_Priority,
386 +                       OPENPIC_MASK));
387  }
388  
389  /*
390 @@ -561,11 +542,10 @@
391         check_arg_vec(vec);
392         openpic_safe_writefield(&OpenPIC->Source[irq].Vector_Priority,
393                                 OPENPIC_PRIORITY_MASK | OPENPIC_VECTOR_MASK |
394 -                               OPENPIC_POLARITY_MASK | OPENPIC_SENSE_MASK,
395 +                               OPENPIC_SENSE_POLARITY | OPENPIC_SENSE_LEVEL,
396                                 (pri << OPENPIC_PRIORITY_SHIFT) | vec |
397 -                               (pol ? OPENPIC_POLARITY_POSITIVE :
398 -                                       OPENPIC_POLARITY_NEGATIVE) |
399 -                               (sense ? OPENPIC_SENSE_LEVEL : OPENPIC_SENSE_EDGE));
400 +                               (pol ? OPENPIC_SENSE_POLARITY : 0) |
401 +                               (sense ? OPENPIC_SENSE_LEVEL : 0));
402  }
403  
404  /*
405 @@ -608,7 +588,7 @@
406                 save_irq_src_vp[i] = openpic_read(&OpenPIC->Source[i].Vector_Priority);
407                 save_irq_src_dest[i] = openpic_read(&OpenPIC->Source[i].Destination);
408         }
409 -       for (i=0; i<NumProcessors; i++) {
410 +for (i=0; i<NumProcessors; i++) {
411                 save_cpu_task_pri[i] = openpic_read(&OpenPIC->Processor[i].Current_Task_Priority);
412                 openpic_set_priority(i, 0xf);
413         }
414 @@ -626,7 +606,7 @@
415         }
416         for (i=0; i<OPENPIC_NUM_IPI; i++)
417                 openpic_write(&OpenPIC->Global.IPI_Vector_Priority(i), save_ipi_vp[i]);
418 -       for (i=0; i<NumSources; i++) {
419 +for (i=0; i<NumSources; i++) {
420                 openpic_write(&OpenPIC->Source[i].Vector_Priority, save_irq_src_vp[i]);
421                 openpic_write(&OpenPIC->Source[i].Destination, save_irq_src_dest[i]);
422         }
423 diff -urN linux.orig/arch/ppc/kernel/pmac_pic.c linux/arch/ppc/kernel/pmac_pic.c
424 --- linux.orig/arch/ppc/kernel/pmac_pic.c       Sun Mar 25 18:31:49 2001
425 +++ linux/arch/ppc/kernel/pmac_pic.c    Tue Aug 27 15:47:42 2002
426 @@ -32,6 +32,8 @@
427  
428  extern u_int openpic_read(volatile u_int *addr);
429  
430 +extern void chrp_do_IRQ(struct pt_regs *,int , int);
431 +
432  #define MAXCOUNT 10000000
433  
434  #define GATWICK_IRQ_POOL_SIZE        10
435 @@ -385,7 +387,7 @@
436                     irq_desc[i].ctl = &open_pic;
437                     irq_desc[i].level = 0;
438                 }
439 -               ppc_md.do_IRQ = open_pic_do_IRQ;
440 +               ppc_md.do_IRQ = chrp_do_IRQ;
441                 open_pic.irq_offset = 0;
442                 openpic_init(1);
443  #ifdef CONFIG_XMON
444 diff -urN linux.orig/arch/ppc/kernel/prep_pci.c linux/arch/ppc/kernel/prep_pci.c
445 --- linux.orig/arch/ppc/kernel/prep_pci.c       Sun Mar 25 18:31:49 2001
446 +++ linux/arch/ppc/kernel/prep_pci.c    Tue Aug 27 15:46:50 2002
447 @@ -5,6 +5,9 @@
448   * rewritten and updated by Cort Dougan (cort@cs.nmt.edu)
449   *
450   * The motherboard routes/maps will disappear shortly. -- Cort
451 + *
452 + * Add chrp_do_IRQ into ppc_md.do_IRQ -- Krzysztof Taraszka (dzimi@pld.org.pl)
453 + *
454   */
455  
456  #include <linux/types.h>
457 @@ -43,6 +46,8 @@
458  /* Used for Motorola to store system config register */
459  static unsigned long   *ProcInfo;
460  
461 +extern void chrp_do_IRQ(struct pt_regs *,int , int);
462 +
463  /* Tables for known hardware */   
464  
465  /* Motorola PowerStackII - Utah */
466 @@ -783,7 +788,7 @@
467         OpenPIC_InitSenses = mvme2600_openpic_initsenses;
468         OpenPIC_NumInitSenses = sizeof(mvme2600_openpic_initsenses);
469  
470 -       ppc_md.do_IRQ = open_pic_do_IRQ;
471 +       ppc_md.do_IRQ = chrp_do_IRQ;
472         
473         /* If raven is present on Motorola store the system config register
474          * for later use.
This page took 0.062877 seconds and 3 git commands to generate.