~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/microblaze/kernel/irq.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /arch/microblaze/kernel/irq.c (Version linux-6.11-rc3) and /arch/ppc/kernel/irq.c (Version linux-2.6.0)


  1 /*                                                  1 /*
  2  * Copyright (C) 2007-2009 Michal Simek <monst !!   2  *  arch/ppc/kernel/irq.c
  3  * Copyright (C) 2007-2009 PetaLogix           !!   3  *
  4  * Copyright (C) 2006 Atmark Techno, Inc.      !!   4  *  Derived from arch/i386/kernel/irq.c
  5  *                                             !!   5  *    Copyright (C) 1992 Linus Torvalds
  6  * This file is subject to the terms and condi !!   6  *  Adapted from arch/i386 by Gary Thomas
  7  * License. See the file "COPYING" in the main !!   7  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
  8  * for more details.                           !!   8  *  Updated and modified by Cort Dougan <cort@fsmlabs.com>
                                                   >>   9  *    Copyright (C) 1996-2001 Cort Dougan
                                                   >>  10  *  Adapted for Power Macintosh by Paul Mackerras
                                                   >>  11  *    Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au)
                                                   >>  12  *  Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
                                                   >>  13  *
                                                   >>  14  * This file contains the code used by various IRQ handling routines:
                                                   >>  15  * asking for different IRQ's should be done through these routines
                                                   >>  16  * instead of just grabbing them. Thus setups with different IRQ numbers
                                                   >>  17  * shouldn't result in any weird surprises, and installing new handlers
                                                   >>  18  * should be easier.
                                                   >>  19  *
                                                   >>  20  * The MPC8xx has an interrupt mask in the SIU.  If a bit is set, the
                                                   >>  21  * interrupt is _enabled_.  As expected, IRQ0 is bit 0 in the 32-bit
                                                   >>  22  * mask register (of which only 16 are defined), hence the weird shifting
                                                   >>  23  * and complement of the cached_irq_mask.  I want to be able to stuff
                                                   >>  24  * this right into the SIU SMASK register.
                                                   >>  25  * Many of the prep/chrp functions are conditional compiled on CONFIG_8xx
                                                   >>  26  * to reduce code space and undefined function references.
  9  */                                                27  */
 10                                                    28 
 11 #include <linux/init.h>                        !!  29 #include <linux/errno.h>
 12 #include <linux/ftrace.h>                      !!  30 #include <linux/module.h>
 13 #include <linux/kernel.h>                      !!  31 #include <linux/threads.h>
 14 #include <linux/hardirq.h>                     << 
 15 #include <linux/interrupt.h>                   << 
 16 #include <linux/irqflags.h>                    << 
 17 #include <linux/seq_file.h>                    << 
 18 #include <linux/kernel_stat.h>                     32 #include <linux/kernel_stat.h>
                                                   >>  33 #include <linux/signal.h>
                                                   >>  34 #include <linux/sched.h>
                                                   >>  35 #include <linux/ptrace.h>
                                                   >>  36 #include <linux/ioport.h>
                                                   >>  37 #include <linux/interrupt.h>
                                                   >>  38 #include <linux/timex.h>
                                                   >>  39 #include <linux/config.h>
                                                   >>  40 #include <linux/init.h>
                                                   >>  41 #include <linux/slab.h>
                                                   >>  42 #include <linux/pci.h>
                                                   >>  43 #include <linux/delay.h>
 19 #include <linux/irq.h>                             44 #include <linux/irq.h>
 20 #include <linux/irqchip.h>                     !!  45 #include <linux/proc_fs.h>
 21 #include <linux/of_irq.h>                      !!  46 #include <linux/random.h>
                                                   >>  47 #include <linux/seq_file.h>
                                                   >>  48 #include <linux/cpumask.h>
                                                   >>  49 
                                                   >>  50 #include <asm/uaccess.h>
                                                   >>  51 #include <asm/bitops.h>
                                                   >>  52 #include <asm/system.h>
                                                   >>  53 #include <asm/io.h>
                                                   >>  54 #include <asm/pgtable.h>
                                                   >>  55 #include <asm/irq.h>
                                                   >>  56 #include <asm/cache.h>
                                                   >>  57 #include <asm/prom.h>
                                                   >>  58 #include <asm/ptrace.h>
                                                   >>  59 
                                                   >>  60 #define NR_MASK_WORDS   ((NR_IRQS + 31) / 32)
                                                   >>  61 
                                                   >>  62 extern atomic_t ipi_recv;
                                                   >>  63 extern atomic_t ipi_sent;
                                                   >>  64 void enable_irq(unsigned int irq_nr);
                                                   >>  65 void disable_irq(unsigned int irq_nr);
                                                   >>  66 
                                                   >>  67 static void register_irq_proc (unsigned int irq);
                                                   >>  68 
                                                   >>  69 #define MAXCOUNT 10000000
                                                   >>  70 
                                                   >>  71 irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned = {
                                                   >>  72         [0 ... NR_IRQS-1] = {
                                                   >>  73                 .lock = SPIN_LOCK_UNLOCKED
                                                   >>  74         }
                                                   >>  75 };
                                                   >>  76 
                                                   >>  77 int ppc_spurious_interrupts = 0;
                                                   >>  78 struct irqaction *ppc_irq_action[NR_IRQS];
                                                   >>  79 unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
                                                   >>  80 unsigned long ppc_lost_interrupts[NR_MASK_WORDS];
                                                   >>  81 atomic_t ppc_n_lost_interrupts;
                                                   >>  82 
                                                   >>  83 /* nasty hack for shared irq's since we need to do kmalloc calls but
                                                   >>  84  * can't very early in the boot when we need to do a request irq.
                                                   >>  85  * this needs to be removed.
                                                   >>  86  * -- Cort
                                                   >>  87  */
                                                   >>  88 #define IRQ_KMALLOC_ENTRIES 8
                                                   >>  89 static int cache_bitmask = 0;
                                                   >>  90 static struct irqaction malloc_cache[IRQ_KMALLOC_ENTRIES];
                                                   >>  91 extern int mem_init_done;
                                                   >>  92 
                                                   >>  93 #if defined(CONFIG_TAU_INT)
                                                   >>  94 extern int tau_interrupts(unsigned long cpu);
                                                   >>  95 extern int tau_initialized;
                                                   >>  96 #endif
                                                   >>  97 
                                                   >>  98 void *irq_kmalloc(size_t size, int pri)
                                                   >>  99 {
                                                   >> 100         unsigned int i;
                                                   >> 101         if ( mem_init_done )
                                                   >> 102                 return kmalloc(size,pri);
                                                   >> 103         for ( i = 0; i < IRQ_KMALLOC_ENTRIES ; i++ )
                                                   >> 104                 if ( ! ( cache_bitmask & (1<<i) ) )
                                                   >> 105                 {
                                                   >> 106                         cache_bitmask |= (1<<i);
                                                   >> 107                         return (void *)(&malloc_cache[i]);
                                                   >> 108                 }
                                                   >> 109         return 0;
                                                   >> 110 }
                                                   >> 111 
                                                   >> 112 void irq_kfree(void *ptr)
                                                   >> 113 {
                                                   >> 114         unsigned int i;
                                                   >> 115         for ( i = 0 ; i < IRQ_KMALLOC_ENTRIES ; i++ )
                                                   >> 116                 if ( ptr == &malloc_cache[i] )
                                                   >> 117                 {
                                                   >> 118                         cache_bitmask &= ~(1<<i);
                                                   >> 119                         return;
                                                   >> 120                 }
                                                   >> 121         kfree(ptr);
                                                   >> 122 }
                                                   >> 123 
                                                   >> 124 int
                                                   >> 125 setup_irq(unsigned int irq, struct irqaction * new)
                                                   >> 126 {
                                                   >> 127         int shared = 0;
                                                   >> 128         unsigned long flags;
                                                   >> 129         struct irqaction *old, **p;
                                                   >> 130         irq_desc_t *desc = irq_desc + irq;
                                                   >> 131 
                                                   >> 132         /*
                                                   >> 133          * Some drivers like serial.c use request_irq() heavily,
                                                   >> 134          * so we have to be careful not to interfere with a
                                                   >> 135          * running system.
                                                   >> 136          */
                                                   >> 137         if (new->flags & SA_SAMPLE_RANDOM) {
                                                   >> 138                 /*
                                                   >> 139                  * This function might sleep, we want to call it first,
                                                   >> 140                  * outside of the atomic block.
                                                   >> 141                  * Yes, this might clear the entropy pool if the wrong
                                                   >> 142                  * driver is attempted to be loaded, without actually
                                                   >> 143                  * installing a new handler, but is this really a problem,
                                                   >> 144                  * only the sysadmin is able to do this.
                                                   >> 145                  */
                                                   >> 146                 rand_initialize_irq(irq);
                                                   >> 147         }
                                                   >> 148 
                                                   >> 149         /*
                                                   >> 150          * The following block of code has to be executed atomically
                                                   >> 151          */
                                                   >> 152         spin_lock_irqsave(&desc->lock,flags);
                                                   >> 153         p = &desc->action;
                                                   >> 154         if ((old = *p) != NULL) {
                                                   >> 155                 /* Can't share interrupts unless both agree to */
                                                   >> 156                 if (!(old->flags & new->flags & SA_SHIRQ)) {
                                                   >> 157                         spin_unlock_irqrestore(&desc->lock,flags);
                                                   >> 158                         return -EBUSY;
                                                   >> 159                 }
                                                   >> 160 
                                                   >> 161                 /* add new interrupt at end of irq queue */
                                                   >> 162                 do {
                                                   >> 163                         p = &old->next;
                                                   >> 164                         old = *p;
                                                   >> 165                 } while (old);
                                                   >> 166                 shared = 1;
                                                   >> 167         }
                                                   >> 168 
                                                   >> 169         *p = new;
                                                   >> 170 
                                                   >> 171         if (!shared) {
                                                   >> 172                 desc->depth = 0;
                                                   >> 173                 desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING);
                                                   >> 174                 unmask_irq(irq);
                                                   >> 175         }
                                                   >> 176         spin_unlock_irqrestore(&desc->lock,flags);
                                                   >> 177 
                                                   >> 178         register_irq_proc(irq);
                                                   >> 179         return 0;
                                                   >> 180 }
                                                   >> 181 
                                                   >> 182 void free_irq(unsigned int irq, void* dev_id)
                                                   >> 183 {
                                                   >> 184         irq_desc_t *desc;
                                                   >> 185         struct irqaction **p;
                                                   >> 186         unsigned long flags;
                                                   >> 187 
                                                   >> 188         desc = irq_desc + irq;
                                                   >> 189         spin_lock_irqsave(&desc->lock,flags);
                                                   >> 190         p = &desc->action;
                                                   >> 191         for (;;) {
                                                   >> 192                 struct irqaction * action = *p;
                                                   >> 193                 if (action) {
                                                   >> 194                         struct irqaction **pp = p;
                                                   >> 195                         p = &action->next;
                                                   >> 196                         if (action->dev_id != dev_id)
                                                   >> 197                                 continue;
                                                   >> 198 
                                                   >> 199                         /* Found it - now remove it from the list of entries */
                                                   >> 200                         *pp = action->next;
                                                   >> 201                         if (!desc->action) {
                                                   >> 202                                 desc->status |= IRQ_DISABLED;
                                                   >> 203                                 mask_irq(irq);
                                                   >> 204                         }
                                                   >> 205                         spin_unlock_irqrestore(&desc->lock,flags);
                                                   >> 206 
                                                   >> 207                         synchronize_irq(irq);
                                                   >> 208                         irq_kfree(action);
                                                   >> 209                         return;
                                                   >> 210                 }
                                                   >> 211                 printk("Trying to free free IRQ%d\n",irq);
                                                   >> 212                 spin_unlock_irqrestore(&desc->lock,flags);
                                                   >> 213                 break;
                                                   >> 214         }
                                                   >> 215         return;
                                                   >> 216 }
                                                   >> 217 
                                                   >> 218 EXPORT_SYMBOL(free_irq);
                                                   >> 219 
                                                   >> 220 int request_irq(unsigned int irq,
                                                   >> 221         irqreturn_t (*handler)(int, void *, struct pt_regs *),
                                                   >> 222         unsigned long irqflags, const char * devname, void *dev_id)
                                                   >> 223 {
                                                   >> 224         struct irqaction *action;
                                                   >> 225         int retval;
                                                   >> 226 
                                                   >> 227         if (irq >= NR_IRQS)
                                                   >> 228                 return -EINVAL;
                                                   >> 229         if (!handler) {
                                                   >> 230                 printk(KERN_ERR "request_irq called with NULL handler!\n");
                                                   >> 231                 dump_stack();
                                                   >> 232                 return 0;
                                                   >> 233         }
                                                   >> 234 
                                                   >> 235         action = (struct irqaction *)
                                                   >> 236                 irq_kmalloc(sizeof(struct irqaction), GFP_KERNEL);
                                                   >> 237         if (!action) {
                                                   >> 238                 printk(KERN_ERR "irq_kmalloc() failed for irq %d !\n", irq);
                                                   >> 239                 return -ENOMEM;
                                                   >> 240         }
                                                   >> 241 
                                                   >> 242         action->handler = handler;
                                                   >> 243         action->flags = irqflags;                       
                                                   >> 244         action->mask = 0;
                                                   >> 245         action->name = devname;
                                                   >> 246         action->dev_id = dev_id;
                                                   >> 247         action->next = NULL;
                                                   >> 248 
                                                   >> 249         retval = setup_irq(irq, action);
                                                   >> 250         if (retval) {
                                                   >> 251                 kfree(action);
                                                   >> 252                 return retval;
                                                   >> 253         }
                                                   >> 254 
                                                   >> 255         return 0;
                                                   >> 256 }
                                                   >> 257 
                                                   >> 258 EXPORT_SYMBOL(request_irq);
                                                   >> 259 
                                                   >> 260 /*
                                                   >> 261  * Generic enable/disable code: this just calls
                                                   >> 262  * down into the PIC-specific version for the actual
                                                   >> 263  * hardware disable after having gotten the irq
                                                   >> 264  * controller lock.
                                                   >> 265  */
                                                   >> 266 
                                                   >> 267 /**
                                                   >> 268  *      disable_irq_nosync - disable an irq without waiting
                                                   >> 269  *      @irq: Interrupt to disable
                                                   >> 270  *
                                                   >> 271  *      Disable the selected interrupt line. Disables of an interrupt
                                                   >> 272  *      stack. Unlike disable_irq(), this function does not ensure existing
                                                   >> 273  *      instances of the IRQ handler have completed before returning.
                                                   >> 274  *
                                                   >> 275  *      This function may be called from IRQ context.
                                                   >> 276  */
                                                   >> 277 
                                                   >> 278 void disable_irq_nosync(unsigned int irq)
                                                   >> 279 {
                                                   >> 280         irq_desc_t *desc = irq_desc + irq;
                                                   >> 281         unsigned long flags;
                                                   >> 282 
                                                   >> 283         spin_lock_irqsave(&desc->lock, flags);
                                                   >> 284         if (!desc->depth++) {
                                                   >> 285                 if (!(desc->status & IRQ_PER_CPU))
                                                   >> 286                         desc->status |= IRQ_DISABLED;
                                                   >> 287                 mask_irq(irq);
                                                   >> 288         }
                                                   >> 289         spin_unlock_irqrestore(&desc->lock, flags);
                                                   >> 290 }
                                                   >> 291 
                                                   >> 292 /**
                                                   >> 293  *      disable_irq - disable an irq and wait for completion
                                                   >> 294  *      @irq: Interrupt to disable
                                                   >> 295  *
                                                   >> 296  *      Disable the selected interrupt line. Disables of an interrupt
                                                   >> 297  *      stack. That is for two disables you need two enables. This
                                                   >> 298  *      function waits for any pending IRQ handlers for this interrupt
                                                   >> 299  *      to complete before returning. If you use this function while
                                                   >> 300  *      holding a resource the IRQ handler may need you will deadlock.
                                                   >> 301  *
                                                   >> 302  *      This function may be called - with care - from IRQ context.
                                                   >> 303  */
                                                   >> 304 
                                                   >> 305 void disable_irq(unsigned int irq)
                                                   >> 306 {
                                                   >> 307         disable_irq_nosync(irq);
                                                   >> 308         synchronize_irq(irq);
                                                   >> 309 }
                                                   >> 310 
                                                   >> 311 /**
                                                   >> 312  *      enable_irq - enable interrupt handling on an irq
                                                   >> 313  *      @irq: Interrupt to enable
                                                   >> 314  *
                                                   >> 315  *      Re-enables the processing of interrupts on this IRQ line
                                                   >> 316  *      providing no disable_irq calls are now in effect.
                                                   >> 317  *
                                                   >> 318  *      This function may be called from IRQ context.
                                                   >> 319  */
                                                   >> 320 
                                                   >> 321 void enable_irq(unsigned int irq)
                                                   >> 322 {
                                                   >> 323         irq_desc_t *desc = irq_desc + irq;
                                                   >> 324         unsigned long flags;
                                                   >> 325 
                                                   >> 326         spin_lock_irqsave(&desc->lock, flags);
                                                   >> 327         switch (desc->depth) {
                                                   >> 328         case 1: {
                                                   >> 329                 unsigned int status = desc->status & ~IRQ_DISABLED;
                                                   >> 330                 desc->status = status;
                                                   >> 331                 if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
                                                   >> 332                         desc->status = status | IRQ_REPLAY;
                                                   >> 333                         hw_resend_irq(desc->handler,irq);
                                                   >> 334                 }
                                                   >> 335                 unmask_irq(irq);
                                                   >> 336                 /* fall-through */
                                                   >> 337         }
                                                   >> 338         default:
                                                   >> 339                 desc->depth--;
                                                   >> 340                 break;
                                                   >> 341         case 0:
                                                   >> 342                 printk("enable_irq(%u) unbalanced\n", irq);
                                                   >> 343         }
                                                   >> 344         spin_unlock_irqrestore(&desc->lock, flags);
                                                   >> 345 }
                                                   >> 346 
                                                   >> 347 int show_interrupts(struct seq_file *p, void *v)
                                                   >> 348 {
                                                   >> 349         int i, j;
                                                   >> 350         struct irqaction * action;
                                                   >> 351         unsigned long flags;
                                                   >> 352 
                                                   >> 353         seq_puts(p, "           ");
                                                   >> 354         for (j=0; j<NR_CPUS; j++)
                                                   >> 355                 if (cpu_online(j))
                                                   >> 356                         seq_printf(p, "CPU%d       ", j);
                                                   >> 357         seq_putc(p, '\n');
                                                   >> 358 
                                                   >> 359         for (i = 0 ; i < NR_IRQS ; i++) {
                                                   >> 360                 spin_lock_irqsave(&irq_desc[i].lock, flags);
                                                   >> 361                 action = irq_desc[i].action;
                                                   >> 362                 if ( !action || !action->handler )
                                                   >> 363                         goto skip;
                                                   >> 364                 seq_printf(p, "%3d: ", i);
                                                   >> 365 #ifdef CONFIG_SMP
                                                   >> 366                 for (j = 0; j < NR_CPUS; j++)
                                                   >> 367                         if (cpu_online(j))
                                                   >> 368                                 seq_printf(p, "%10u ",
                                                   >> 369                                            kstat_cpu(j).irqs[i]);
                                                   >> 370 #else
                                                   >> 371                 seq_printf(p, "%10u ", kstat_irqs(i));
                                                   >> 372 #endif /* CONFIG_SMP */
                                                   >> 373                 if (irq_desc[i].handler)
                                                   >> 374                         seq_printf(p, " %s ", irq_desc[i].handler->typename);
                                                   >> 375                 else
                                                   >> 376                         seq_puts(p, "  None      ");
                                                   >> 377                 seq_printf(p, "%s", (irq_desc[i].status & IRQ_LEVEL) ? "Level " : "Edge  ");
                                                   >> 378                 seq_printf(p, "    %s", action->name);
                                                   >> 379                 for (action = action->next; action; action = action->next)
                                                   >> 380                         seq_printf(p, ", %s", action->name);
                                                   >> 381                 seq_putc(p, '\n');
                                                   >> 382 skip:
                                                   >> 383                 spin_unlock_irqrestore(&irq_desc[i].lock, flags);
                                                   >> 384         }
                                                   >> 385 #ifdef CONFIG_TAU_INT
                                                   >> 386         if (tau_initialized){
                                                   >> 387                 seq_puts(p, "TAU: ");
                                                   >> 388                 for (j = 0; j < NR_CPUS; j++)
                                                   >> 389                         if (cpu_online(j))
                                                   >> 390                                 seq_printf(p, "%10u ", tau_interrupts(j));
                                                   >> 391                 seq_puts(p, "  PowerPC             Thermal Assist (cpu temp)\n");
                                                   >> 392         }
                                                   >> 393 #endif
                                                   >> 394 #ifdef CONFIG_SMP
                                                   >> 395         /* should this be per processor send/receive? */
                                                   >> 396         seq_printf(p, "IPI (recv/sent): %10u/%u\n",
                                                   >> 397                    atomic_read(&ipi_recv), atomic_read(&ipi_sent));
                                                   >> 398 #endif
                                                   >> 399         seq_printf(p, "BAD: %10u\n", ppc_spurious_interrupts);
                                                   >> 400         return 0;
                                                   >> 401 }
                                                   >> 402 
                                                   >> 403 static inline void
                                                   >> 404 handle_irq_event(int irq, struct pt_regs *regs, struct irqaction *action)
                                                   >> 405 {
                                                   >> 406         int status = 0;
                                                   >> 407 
                                                   >> 408         if (!(action->flags & SA_INTERRUPT))
                                                   >> 409                 local_irq_enable();
 22                                                   410 
 23 void __irq_entry do_IRQ(struct pt_regs *regs)  !! 411         do {
                                                   >> 412                 status |= action->flags;
                                                   >> 413                 action->handler(irq, action->dev_id, regs);
                                                   >> 414                 action = action->next;
                                                   >> 415         } while (action);
                                                   >> 416         if (status & SA_SAMPLE_RANDOM)
                                                   >> 417                 add_interrupt_randomness(irq);
                                                   >> 418         local_irq_disable();
                                                   >> 419 }
                                                   >> 420 
                                                   >> 421 /*
                                                   >> 422  * Eventually, this should take an array of interrupts and an array size
                                                   >> 423  * so it can dispatch multiple interrupts.
                                                   >> 424  */
                                                   >> 425 void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq)
                                                   >> 426 {
                                                   >> 427         int status;
                                                   >> 428         struct irqaction *action;
                                                   >> 429         irq_desc_t *desc = irq_desc + irq;
                                                   >> 430 
                                                   >> 431         kstat_this_cpu.irqs[irq]++;
                                                   >> 432         spin_lock(&desc->lock);
                                                   >> 433         ack_irq(irq);
                                                   >> 434         /*
                                                   >> 435            REPLAY is when Linux resends an IRQ that was dropped earlier
                                                   >> 436            WAITING is used by probe to mark irqs that are being tested
                                                   >> 437            */
                                                   >> 438         status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
                                                   >> 439         if (!(status & IRQ_PER_CPU))
                                                   >> 440                 status |= IRQ_PENDING; /* we _want_ to handle it */
                                                   >> 441 
                                                   >> 442         /*
                                                   >> 443          * If the IRQ is disabled for whatever reason, we cannot
                                                   >> 444          * use the action we have.
                                                   >> 445          */
                                                   >> 446         action = NULL;
                                                   >> 447         if (likely(!(status & (IRQ_DISABLED | IRQ_INPROGRESS)))) {
                                                   >> 448                 action = desc->action;
                                                   >> 449                 if (!action || !action->handler) {
                                                   >> 450                         ppc_spurious_interrupts++;
                                                   >> 451                         printk(KERN_DEBUG "Unhandled interrupt %x, disabled\n", irq);
                                                   >> 452                         /* We can't call disable_irq here, it would deadlock */
                                                   >> 453                         ++desc->depth;
                                                   >> 454                         desc->status |= IRQ_DISABLED;
                                                   >> 455                         mask_irq(irq);
                                                   >> 456                         /* This is a real interrupt, we have to eoi it,
                                                   >> 457                            so we jump to out */
                                                   >> 458                         goto out;
                                                   >> 459                 }
                                                   >> 460                 status &= ~IRQ_PENDING; /* we commit to handling */
                                                   >> 461                 if (!(status & IRQ_PER_CPU))
                                                   >> 462                         status |= IRQ_INPROGRESS; /* we are handling it */
                                                   >> 463         }
                                                   >> 464         desc->status = status;
                                                   >> 465 
                                                   >> 466         /*
                                                   >> 467          * If there is no IRQ handler or it was disabled, exit early.
                                                   >> 468            Since we set PENDING, if another processor is handling
                                                   >> 469            a different instance of this same irq, the other processor
                                                   >> 470            will take care of it.
                                                   >> 471          */
                                                   >> 472         if (unlikely(!action))
                                                   >> 473                 goto out;
                                                   >> 474 
                                                   >> 475 
                                                   >> 476         /*
                                                   >> 477          * Edge triggered interrupts need to remember
                                                   >> 478          * pending events.
                                                   >> 479          * This applies to any hw interrupts that allow a second
                                                   >> 480          * instance of the same irq to arrive while we are in do_IRQ
                                                   >> 481          * or in the handler. But the code here only handles the _second_
                                                   >> 482          * instance of the irq, not the third or fourth. So it is mostly
                                                   >> 483          * useful for irq hardware that does not mask cleanly in an
                                                   >> 484          * SMP environment.
                                                   >> 485          */
                                                   >> 486         for (;;) {
                                                   >> 487                 spin_unlock(&desc->lock);
                                                   >> 488                 handle_irq_event(irq, regs, action);
                                                   >> 489                 spin_lock(&desc->lock);
                                                   >> 490 
                                                   >> 491                 if (likely(!(desc->status & IRQ_PENDING)))
                                                   >> 492                         break;
                                                   >> 493                 desc->status &= ~IRQ_PENDING;
                                                   >> 494         }
                                                   >> 495 out:
                                                   >> 496         desc->status &= ~IRQ_INPROGRESS;
                                                   >> 497         /*
                                                   >> 498          * The ->end() handler has to deal with interrupts which got
                                                   >> 499          * disabled while the handler was running.
                                                   >> 500          */
                                                   >> 501         if (irq_desc[irq].handler) {
                                                   >> 502                 if (irq_desc[irq].handler->end)
                                                   >> 503                         irq_desc[irq].handler->end(irq);
                                                   >> 504                 else if (irq_desc[irq].handler->enable)
                                                   >> 505                         irq_desc[irq].handler->enable(irq);
                                                   >> 506         }
                                                   >> 507         spin_unlock(&desc->lock);
                                                   >> 508 }
                                                   >> 509 
                                                   >> 510 void do_IRQ(struct pt_regs *regs)
                                                   >> 511 {
                                                   >> 512         int irq, first = 1;
                                                   >> 513         irq_enter();
                                                   >> 514 
                                                   >> 515         /*
                                                   >> 516          * Every platform is required to implement ppc_md.get_irq.
                                                   >> 517          * This function will either return an irq number or -1 to
                                                   >> 518          * indicate there are no more pending.  But the first time
                                                   >> 519          * through the loop this means there wasn't and IRQ pending.
                                                   >> 520          * The value -2 is for buggy hardware and means that this IRQ
                                                   >> 521          * has already been handled. -- Tom
                                                   >> 522          */
                                                   >> 523         while ((irq = ppc_md.get_irq(regs)) >= 0) {
                                                   >> 524                 ppc_irq_dispatch_handler(regs, irq);
                                                   >> 525                 first = 0;
                                                   >> 526         }
                                                   >> 527         if (irq != -2 && first)
                                                   >> 528                 /* That's not SMP safe ... but who cares ? */
                                                   >> 529                 ppc_spurious_interrupts++;
                                                   >> 530         irq_exit();
                                                   >> 531 }
                                                   >> 532 
                                                   >> 533 unsigned long probe_irq_on (void)
                                                   >> 534 {
                                                   >> 535         return 0;
                                                   >> 536 }
                                                   >> 537 
                                                   >> 538 EXPORT_SYMBOL(probe_irq_on);
                                                   >> 539 
                                                   >> 540 int probe_irq_off (unsigned long irqs)
                                                   >> 541 {
                                                   >> 542         return 0;
                                                   >> 543 }
                                                   >> 544 
                                                   >> 545 EXPORT_SYMBOL(probe_irq_off);
                                                   >> 546 
                                                   >> 547 unsigned int probe_irq_mask(unsigned long irqs)
                                                   >> 548 {
                                                   >> 549         return 0;
                                                   >> 550 }
                                                   >> 551 
                                                   >> 552 #ifdef CONFIG_SMP
                                                   >> 553 void synchronize_irq(unsigned int irq)
 24 {                                                 554 {
 25         struct pt_regs *old_regs = set_irq_reg !! 555         while (irq_desc[irq].status & IRQ_INPROGRESS)
 26         trace_hardirqs_off();                  !! 556                 barrier();
                                                   >> 557 }
                                                   >> 558 #endif /* CONFIG_SMP */
                                                   >> 559 
                                                   >> 560 static struct proc_dir_entry *root_irq_dir;
                                                   >> 561 static struct proc_dir_entry *irq_dir[NR_IRQS];
                                                   >> 562 static struct proc_dir_entry *smp_affinity_entry[NR_IRQS];
                                                   >> 563 
                                                   >> 564 #ifdef CONFIG_IRQ_ALL_CPUS
                                                   >> 565 #define DEFAULT_CPU_AFFINITY CPU_MASK_ALL
                                                   >> 566 #else
                                                   >> 567 #define DEFAULT_CPU_AFFINITY cpumask_of_cpu(0)
                                                   >> 568 #endif
                                                   >> 569 
                                                   >> 570 cpumask_t irq_affinity [NR_IRQS];
                                                   >> 571 
                                                   >> 572 #define HEX_DIGITS (2*sizeof(cpumask_t))
                                                   >> 573 
                                                   >> 574 static int irq_affinity_read_proc (char *page, char **start, off_t off,
                                                   >> 575                         int count, int *eof, void *data)
                                                   >> 576 {
                                                   >> 577         cpumask_t tmp = irq_affinity[(long)data];
                                                   >> 578         int k, len = 0;
                                                   >> 579 
                                                   >> 580         if (count < HEX_DIGITS+1)
                                                   >> 581                 return -EINVAL;
                                                   >> 582 
                                                   >> 583         for (k = 0; k < sizeof(cpumask_t)/sizeof(u16); ++k) {
                                                   >> 584                 int j = sprintf(page, "%04hx", (u16)cpus_coerce(tmp));
                                                   >> 585                 len += j;
                                                   >> 586                 page += j;
                                                   >> 587                 cpus_shift_right(tmp, tmp, 16);
                                                   >> 588         }
                                                   >> 589 
                                                   >> 590         len += sprintf(page, "\n");
                                                   >> 591         return len;
                                                   >> 592 }
                                                   >> 593 
                                                   >> 594 static unsigned int parse_hex_value (const char __user *buffer,
                                                   >> 595                 unsigned long count, cpumask_t *ret)
                                                   >> 596 {
                                                   >> 597         unsigned char hexnum [HEX_DIGITS];
                                                   >> 598         cpumask_t value = CPU_MASK_NONE;
                                                   >> 599         int i;
                                                   >> 600 
                                                   >> 601         if (!count)
                                                   >> 602                 return -EINVAL;
                                                   >> 603         if (count > HEX_DIGITS)
                                                   >> 604                 count = HEX_DIGITS;
                                                   >> 605         if (copy_from_user(hexnum, buffer, count))
                                                   >> 606                 return -EFAULT;
                                                   >> 607 
                                                   >> 608         /*
                                                   >> 609          * Parse the first 8 characters as a hex string, any non-hex char
                                                   >> 610          * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same.
                                                   >> 611          */
                                                   >> 612         for (i = 0; i < count; i++) {
                                                   >> 613                 unsigned int c = hexnum[i];
                                                   >> 614                 int k;
 27                                                   615 
 28         irq_enter();                           !! 616                 switch (c) {
 29         handle_arch_irq(regs);                 !! 617                         case '' ... '9': c -= ''; break;
 30         irq_exit();                            !! 618                         case 'a' ... 'f': c -= 'a'-10; break;
 31         set_irq_regs(old_regs);                !! 619                         case 'A' ... 'F': c -= 'A'-10; break;
 32         trace_hardirqs_on();                   !! 620                 default:
                                                   >> 621                         goto out;
                                                   >> 622                 }
                                                   >> 623                 cpus_shift_left(value, value, 4);
                                                   >> 624                 for (k = 0; k < 4; ++k)
                                                   >> 625                         if (c & (1 << k))
                                                   >> 626                                 cpu_set(k, value);
                                                   >> 627         }
                                                   >> 628 out:
                                                   >> 629         *ret = value;
                                                   >> 630         return 0;
                                                   >> 631 }
                                                   >> 632 
                                                   >> 633 static int irq_affinity_write_proc (struct file *file, const char __user *buffer,
                                                   >> 634                                         unsigned long count, void *data)
                                                   >> 635 {
                                                   >> 636         int irq = (int) data, full_count = count, err;
                                                   >> 637         cpumask_t new_value, tmp;
                                                   >> 638 
                                                   >> 639         if (!irq_desc[irq].handler->set_affinity)
                                                   >> 640                 return -EIO;
                                                   >> 641 
                                                   >> 642         err = parse_hex_value(buffer, count, &new_value);
                                                   >> 643 
                                                   >> 644         /*
                                                   >> 645          * Do not allow disabling IRQs completely - it's a too easy
                                                   >> 646          * way to make the system unusable accidentally :-) At least
                                                   >> 647          * one online CPU still has to be targeted.
                                                   >> 648          *
                                                   >> 649          * We assume a 1-1 logical<->physical cpu mapping here.  If
                                                   >> 650          * we assume that the cpu indices in /proc/irq/../smp_affinity
                                                   >> 651          * are actually logical cpu #'s then we have no problem.
                                                   >> 652          *  -- Cort <cort@fsmlabs.com>
                                                   >> 653          */
                                                   >> 654         cpus_and(tmp, new_value, cpu_online_map);
                                                   >> 655         if (cpus_empty(tmp))
                                                   >> 656                 return -EINVAL;
                                                   >> 657 
                                                   >> 658         irq_affinity[irq] = new_value;
                                                   >> 659         irq_desc[irq].handler->set_affinity(irq, new_value);
                                                   >> 660 
                                                   >> 661         return full_count;
                                                   >> 662 }
                                                   >> 663 
                                                   >> 664 static int prof_cpu_mask_read_proc (char *page, char **start, off_t off,
                                                   >> 665                         int count, int *eof, void *data)
                                                   >> 666 {
                                                   >> 667         cpumask_t mask = *(cpumask_t *)data;
                                                   >> 668         int k, len = 0;
                                                   >> 669 
                                                   >> 670         if (count < HEX_DIGITS+1)
                                                   >> 671                 return -EINVAL;
                                                   >> 672 
                                                   >> 673         for (k = 0; k < sizeof(cpumask_t)/sizeof(u16); ++k) {
                                                   >> 674                 int j = sprintf(page, "%04hx", (u16)cpus_coerce(mask));
                                                   >> 675                 len += j;
                                                   >> 676                 page += j;
                                                   >> 677                 cpus_shift_right(mask, mask, 16);
                                                   >> 678         }
                                                   >> 679         len += sprintf(page, "\n");
                                                   >> 680         return len;
                                                   >> 681 }
                                                   >> 682 
                                                   >> 683 static int prof_cpu_mask_write_proc (struct file *file, const char __user *buffer,
                                                   >> 684                                         unsigned long count, void *data)
                                                   >> 685 {
                                                   >> 686         cpumask_t *mask = (cpumask_t *)data, full_count = count, err;
                                                   >> 687         cpumask_t new_value;
                                                   >> 688 
                                                   >> 689         err = parse_hex_value(buffer, count, &new_value);
                                                   >> 690         if (err)
                                                   >> 691                 return err;
                                                   >> 692 
                                                   >> 693         *mask = new_value;
                                                   >> 694         return full_count;
                                                   >> 695 }
                                                   >> 696 
                                                   >> 697 #define MAX_NAMELEN 10
                                                   >> 698 
                                                   >> 699 static void register_irq_proc (unsigned int irq)
                                                   >> 700 {
                                                   >> 701         struct proc_dir_entry *entry;
                                                   >> 702         char name [MAX_NAMELEN];
                                                   >> 703 
                                                   >> 704         if (!root_irq_dir || (irq_desc[irq].handler == NULL) || irq_dir[irq])
                                                   >> 705                 return;
                                                   >> 706 
                                                   >> 707         memset(name, 0, MAX_NAMELEN);
                                                   >> 708         sprintf(name, "%d", irq);
                                                   >> 709 
                                                   >> 710         /* create /proc/irq/1234 */
                                                   >> 711         irq_dir[irq] = proc_mkdir(name, root_irq_dir);
                                                   >> 712 
                                                   >> 713         /* create /proc/irq/1234/smp_affinity */
                                                   >> 714         entry = create_proc_entry("smp_affinity", 0600, irq_dir[irq]);
                                                   >> 715 
                                                   >> 716         entry->nlink = 1;
                                                   >> 717         entry->data = (void *)irq;
                                                   >> 718         entry->read_proc = irq_affinity_read_proc;
                                                   >> 719         entry->write_proc = irq_affinity_write_proc;
                                                   >> 720 
                                                   >> 721         smp_affinity_entry[irq] = entry;
                                                   >> 722 }
                                                   >> 723 
                                                   >> 724 unsigned long prof_cpu_mask = -1;
                                                   >> 725 
                                                   >> 726 void init_irq_proc (void)
                                                   >> 727 {
                                                   >> 728         struct proc_dir_entry *entry;
                                                   >> 729         int i;
                                                   >> 730 
                                                   >> 731         /* create /proc/irq */
                                                   >> 732         root_irq_dir = proc_mkdir("irq", 0);
                                                   >> 733 
                                                   >> 734         /* create /proc/irq/prof_cpu_mask */
                                                   >> 735         entry = create_proc_entry("prof_cpu_mask", 0600, root_irq_dir);
                                                   >> 736 
                                                   >> 737         entry->nlink = 1;
                                                   >> 738         entry->data = (void *)&prof_cpu_mask;
                                                   >> 739         entry->read_proc = prof_cpu_mask_read_proc;
                                                   >> 740         entry->write_proc = prof_cpu_mask_write_proc;
                                                   >> 741 
                                                   >> 742         /*
                                                   >> 743          * Create entries for all existing IRQs.
                                                   >> 744          */
                                                   >> 745         for (i = 0; i < NR_IRQS; i++) {
                                                   >> 746                 if (irq_desc[i].handler == NULL)
                                                   >> 747                         continue;
                                                   >> 748                 register_irq_proc(i);
                                                   >> 749         }
                                                   >> 750 }
                                                   >> 751 
                                                   >> 752 irqreturn_t no_action(int irq, void *dev, struct pt_regs *regs)
                                                   >> 753 {
                                                   >> 754         return IRQ_NONE;
 33 }                                                 755 }
 34                                                   756 
 35 void __init init_IRQ(void)                        757 void __init init_IRQ(void)
 36 {                                                 758 {
 37         /* process the entire interrupt tree i !! 759         int i;
 38         irqchip_init();                        !! 760 
                                                   >> 761         for (i = 0; i < NR_IRQS; ++i)
                                                   >> 762                 irq_affinity[i] = DEFAULT_CPU_AFFINITY;
                                                   >> 763 
                                                   >> 764         ppc_md.init_IRQ();
 39 }                                                 765 }
 40                                                   766 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php