irq.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:18k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * linux/arch/alpha/kernel/irq.c
  3.  *
  4.  * Copyright (C) 1995 Linus Torvalds
  5.  *
  6.  * This file contains the code used by various IRQ handling routines:
  7.  * asking for different IRQ's should be done through these routines
  8.  * instead of just grabbing them. Thus setups with different IRQ numbers
  9.  * shouldn't result in any weird surprises, and installing new handlers
  10.  * should be easier.
  11.  */
  12. #include <linux/config.h>
  13. #include <linux/kernel.h>
  14. #include <linux/ptrace.h>
  15. #include <linux/errno.h>
  16. #include <linux/kernel_stat.h>
  17. #include <linux/signal.h>
  18. #include <linux/sched.h>
  19. #include <linux/interrupt.h>
  20. #include <linux/slab.h>
  21. #include <linux/random.h>
  22. #include <linux/init.h>
  23. #include <linux/irq.h>
  24. #include <linux/proc_fs.h>
  25. #include <asm/system.h>
  26. #include <asm/io.h>
  27. #include <asm/bitops.h>
  28. #include <asm/uaccess.h>
  29. /*
  30.  * Controller mappings for all interrupt sources:
  31.  */
  32. irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned = {
  33. [0 ... NR_IRQS-1] = { 0, &no_irq_type, NULL, 0, SPIN_LOCK_UNLOCKED}
  34. };
  35. static void register_irq_proc(unsigned int irq);
  36. volatile unsigned long irq_err_count;
  37. /*
  38.  * Special irq handlers.
  39.  */
  40. void no_action(int cpl, void *dev_id, struct pt_regs *regs) { }
  41. /*
  42.  * Generic no controller code
  43.  */
  44. static void no_irq_enable_disable(unsigned int irq) { }
  45. static unsigned int no_irq_startup(unsigned int irq) { return 0; }
  46. static void
  47. no_irq_ack(unsigned int irq)
  48. {
  49. irq_err_count++;
  50. printk(KERN_CRIT "Unexpected IRQ trap at vector %un", irq);
  51. }
  52. struct hw_interrupt_type no_irq_type = {
  53. typename: "none",
  54. startup: no_irq_startup,
  55. shutdown: no_irq_enable_disable,
  56. enable: no_irq_enable_disable,
  57. disable: no_irq_enable_disable,
  58. ack: no_irq_ack,
  59. end: no_irq_enable_disable,
  60. };
  61. int
  62. handle_IRQ_event(unsigned int irq, struct pt_regs *regs,
  63.  struct irqaction *action)
  64. {
  65. int status;
  66. int cpu = smp_processor_id();
  67. kstat.irqs[cpu][irq]++;
  68. irq_enter(cpu, irq);
  69. status = 1; /* Force the "do bottom halves" bit */
  70. do {
  71. if (!(action->flags & SA_INTERRUPT))
  72. __sti();
  73. else
  74. __cli();
  75. status |= action->flags;
  76. action->handler(irq, action->dev_id, regs);
  77. action = action->next;
  78. } while (action);
  79. if (status & SA_SAMPLE_RANDOM)
  80. add_interrupt_randomness(irq);
  81. __cli();
  82. irq_exit(cpu, irq);
  83. return status;
  84. }
  85. /*
  86.  * Generic enable/disable code: this just calls
  87.  * down into the PIC-specific version for the actual
  88.  * hardware disable after having gotten the irq
  89.  * controller lock. 
  90.  */
  91. void inline
  92. disable_irq_nosync(unsigned int irq)
  93. {
  94. irq_desc_t *desc = irq_desc + irq;
  95. unsigned long flags;
  96. spin_lock_irqsave(&desc->lock, flags);
  97. if (!desc->depth++) {
  98. desc->status |= IRQ_DISABLED;
  99. desc->handler->disable(irq);
  100. }
  101. spin_unlock_irqrestore(&desc->lock, flags);
  102. }
  103. /*
  104.  * Synchronous version of the above, making sure the IRQ is
  105.  * no longer running on any other IRQ..
  106.  */
  107. void
  108. disable_irq(unsigned int irq)
  109. {
  110. disable_irq_nosync(irq);
  111. if (!local_irq_count(smp_processor_id())) {
  112. do {
  113. barrier();
  114. } while (irq_desc[irq].status & IRQ_INPROGRESS);
  115. }
  116. }
  117. void
  118. enable_irq(unsigned int irq)
  119. {
  120. irq_desc_t *desc = irq_desc + irq;
  121. unsigned long flags;
  122. spin_lock_irqsave(&desc->lock, flags);
  123. switch (desc->depth) {
  124. case 1: {
  125. unsigned int status = desc->status & ~IRQ_DISABLED;
  126. desc->status = status;
  127. if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
  128. desc->status = status | IRQ_REPLAY;
  129. hw_resend_irq(desc->handler,irq);
  130. }
  131. desc->handler->enable(irq);
  132. /* fall-through */
  133. }
  134. default:
  135. desc->depth--;
  136. break;
  137. case 0:
  138. printk(KERN_ERR "enable_irq() unbalanced from %pn",
  139.        __builtin_return_address(0));
  140. }
  141. spin_unlock_irqrestore(&desc->lock, flags);
  142. }
  143. int
  144. setup_irq(unsigned int irq, struct irqaction * new)
  145. {
  146. int shared = 0;
  147. struct irqaction *old, **p;
  148. unsigned long flags;
  149. irq_desc_t *desc = irq_desc + irq;
  150. /*
  151.  * Some drivers like serial.c use request_irq() heavily,
  152.  * so we have to be careful not to interfere with a
  153.  * running system.
  154.  */
  155. if (new->flags & SA_SAMPLE_RANDOM) {
  156. /*
  157.  * This function might sleep, we want to call it first,
  158.  * outside of the atomic block.
  159.  * Yes, this might clear the entropy pool if the wrong
  160.  * driver is attempted to be loaded, without actually
  161.  * installing a new handler, but is this really a problem,
  162.  * only the sysadmin is able to do this.
  163.  */
  164. rand_initialize_irq(irq);
  165. }
  166. /*
  167.  * The following block of code has to be executed atomically
  168.  */
  169. spin_lock_irqsave(&desc->lock,flags);
  170. p = &desc->action;
  171. if ((old = *p) != NULL) {
  172. /* Can't share interrupts unless both agree to */
  173. if (!(old->flags & new->flags & SA_SHIRQ)) {
  174. spin_unlock_irqrestore(&desc->lock,flags);
  175. return -EBUSY;
  176. }
  177. /* add new interrupt at end of irq queue */
  178. do {
  179. p = &old->next;
  180. old = *p;
  181. } while (old);
  182. shared = 1;
  183. }
  184. *p = new;
  185. if (!shared) {
  186. desc->depth = 0;
  187. desc->status &= ~IRQ_DISABLED;
  188. desc->handler->startup(irq);
  189. }
  190. spin_unlock_irqrestore(&desc->lock,flags);
  191. return 0;
  192. }
  193. static struct proc_dir_entry * root_irq_dir;
  194. static struct proc_dir_entry * irq_dir[NR_IRQS];
  195. #ifdef CONFIG_SMP
  196. static struct proc_dir_entry * smp_affinity_entry[NR_IRQS];
  197. static char irq_user_affinity[NR_IRQS];
  198. static unsigned long irq_affinity[NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL };
  199. static void
  200. select_smp_affinity(int irq)
  201. {
  202. static int last_cpu;
  203. int cpu = last_cpu + 1;
  204. if (! irq_desc[irq].handler->set_affinity || irq_user_affinity[irq])
  205. return;
  206. while (((cpu_present_mask >> cpu) & 1) == 0)
  207. cpu = (cpu < (NR_CPUS-1) ? cpu + 1 : 0);
  208. last_cpu = cpu;
  209. irq_affinity[irq] = 1UL << cpu;
  210. irq_desc[irq].handler->set_affinity(irq, 1UL << cpu);
  211. }
  212. #define HEX_DIGITS 16
  213. static int
  214. irq_affinity_read_proc (char *page, char **start, off_t off,
  215. int count, int *eof, void *data)
  216. {
  217. if (count < HEX_DIGITS+1)
  218. return -EINVAL;
  219. return sprintf (page, "%016lxn", irq_affinity[(long)data]);
  220. }
  221. static unsigned int
  222. parse_hex_value (const char *buffer,
  223.  unsigned long count, unsigned long *ret)
  224. {
  225. unsigned char hexnum [HEX_DIGITS];
  226. unsigned long value;
  227. int i;
  228. if (!count)
  229. return -EINVAL;
  230. if (count > HEX_DIGITS)
  231. count = HEX_DIGITS;
  232. if (copy_from_user(hexnum, buffer, count))
  233. return -EFAULT;
  234. /*
  235.  * Parse the first 8 characters as a hex string, any non-hex char
  236.  * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same.
  237.  */
  238. value = 0;
  239. for (i = 0; i < count; i++) {
  240. unsigned int c = hexnum[i];
  241. switch (c) {
  242. case '0' ... '9': c -= '0'; break;
  243. case 'a' ... 'f': c -= 'a'-10; break;
  244. case 'A' ... 'F': c -= 'A'-10; break;
  245. default:
  246. goto out;
  247. }
  248. value = (value << 4) | c;
  249. }
  250. out:
  251. *ret = value;
  252. return 0;
  253. }
  254. static int
  255. irq_affinity_write_proc(struct file *file, const char *buffer,
  256. unsigned long count, void *data)
  257. {
  258. int irq = (long) data, full_count = count, err;
  259. unsigned long new_value;
  260. if (!irq_desc[irq].handler->set_affinity)
  261. return -EIO;
  262. err = parse_hex_value(buffer, count, &new_value);
  263. /* The special value 0 means release control of the
  264.    affinity to kernel.  */
  265. if (new_value == 0) {
  266. irq_user_affinity[irq] = 0;
  267. select_smp_affinity(irq);
  268. }
  269. /* Do not allow disabling IRQs completely - it's a too easy
  270.    way to make the system unusable accidentally :-) At least
  271.    one online CPU still has to be targeted.  */
  272. else if (!(new_value & cpu_present_mask))
  273. return -EINVAL;
  274. else {
  275. irq_affinity[irq] = new_value;
  276. irq_user_affinity[irq] = 1;
  277. irq_desc[irq].handler->set_affinity(irq, new_value);
  278. }
  279. return full_count;
  280. }
  281. static int
  282. prof_cpu_mask_read_proc(char *page, char **start, off_t off,
  283. int count, int *eof, void *data)
  284. {
  285. unsigned long *mask = (unsigned long *) data;
  286. if (count < HEX_DIGITS+1)
  287. return -EINVAL;
  288. return sprintf (page, "%016lxn", *mask);
  289. }
  290. static int
  291. prof_cpu_mask_write_proc(struct file *file, const char *buffer,
  292.  unsigned long count, void *data)
  293. {
  294. unsigned long *mask = (unsigned long *) data, full_count = count, err;
  295. unsigned long new_value;
  296. err = parse_hex_value(buffer, count, &new_value);
  297. if (err)
  298. return err;
  299. *mask = new_value;
  300. return full_count;
  301. }
  302. #endif /* CONFIG_SMP */
  303. #define MAX_NAMELEN 10
  304. static void
  305. register_irq_proc (unsigned int irq)
  306. {
  307. #ifdef CONFIG_SMP
  308. struct proc_dir_entry *entry;
  309. #endif
  310. char name [MAX_NAMELEN];
  311. if (!root_irq_dir || (irq_desc[irq].handler == &no_irq_type))
  312. return;
  313. memset(name, 0, MAX_NAMELEN);
  314. sprintf(name, "%d", irq);
  315. /* create /proc/irq/1234 */
  316. irq_dir[irq] = proc_mkdir(name, root_irq_dir);
  317. #ifdef CONFIG_SMP
  318. /* create /proc/irq/1234/smp_affinity */
  319. entry = create_proc_entry("smp_affinity", 0600, irq_dir[irq]);
  320. entry->nlink = 1;
  321. entry->data = (void *)(long)irq;
  322. entry->read_proc = irq_affinity_read_proc;
  323. entry->write_proc = irq_affinity_write_proc;
  324. smp_affinity_entry[irq] = entry;
  325. #endif
  326. }
  327. unsigned long prof_cpu_mask = ~0UL;
  328. void
  329. init_irq_proc (void)
  330. {
  331. #ifdef CONFIG_SMP
  332. struct proc_dir_entry *entry;
  333. #endif
  334. int i;
  335. /* create /proc/irq */
  336. root_irq_dir = proc_mkdir("irq", 0);
  337. #ifdef CONFIG_SMP
  338. /* create /proc/irq/prof_cpu_mask */
  339. entry = create_proc_entry("prof_cpu_mask", 0600, root_irq_dir);
  340. entry->nlink = 1;
  341. entry->data = (void *)&prof_cpu_mask;
  342. entry->read_proc = prof_cpu_mask_read_proc;
  343. entry->write_proc = prof_cpu_mask_write_proc;
  344. #endif
  345. /*
  346.  * Create entries for all existing IRQs.
  347.  */
  348. for (i = 0; i < NR_IRQS; i++) {
  349. if (irq_desc[i].handler == &no_irq_type)
  350. continue;
  351. register_irq_proc(i);
  352. }
  353. }
  354. int
  355. request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
  356.     unsigned long irqflags, const char * devname, void *dev_id)
  357. {
  358. int retval;
  359. struct irqaction * action;
  360. if (irq >= ACTUAL_NR_IRQS)
  361. return -EINVAL;
  362. if (!handler)
  363. return -EINVAL;
  364. #if 1
  365. /*
  366.  * Sanity-check: shared interrupts should REALLY pass in
  367.  * a real dev-ID, otherwise we'll have trouble later trying
  368.  * to figure out which interrupt is which (messes up the
  369.  * interrupt freeing logic etc).
  370.  */
  371. if ((irqflags & SA_SHIRQ) && !dev_id) {
  372. printk(KERN_ERR
  373.        "Bad boy: %s (at %p) called us without a dev_id!n",
  374.        devname, __builtin_return_address(0));
  375. }
  376. #endif
  377. action = (struct irqaction *)
  378. kmalloc(sizeof(struct irqaction), GFP_KERNEL);
  379. if (!action)
  380. return -ENOMEM;
  381. action->handler = handler;
  382. action->flags = irqflags;
  383. action->mask = 0;
  384. action->name = devname;
  385. action->next = NULL;
  386. action->dev_id = dev_id;
  387. #ifdef CONFIG_SMP
  388. select_smp_affinity(irq);
  389. #endif
  390. retval = setup_irq(irq, action);
  391. if (retval)
  392. kfree(action);
  393. return retval;
  394. }
  395. void
  396. free_irq(unsigned int irq, void *dev_id)
  397. {
  398. irq_desc_t *desc;
  399. struct irqaction **p;
  400. unsigned long flags;
  401. if (irq >= ACTUAL_NR_IRQS) {
  402. printk(KERN_CRIT "Trying to free IRQ%dn", irq);
  403. return;
  404. }
  405. desc = irq_desc + irq;
  406. spin_lock_irqsave(&desc->lock,flags);
  407. p = &desc->action;
  408. for (;;) {
  409. struct irqaction * action = *p;
  410. if (action) {
  411. struct irqaction **pp = p;
  412. p = &action->next;
  413. if (action->dev_id != dev_id)
  414. continue;
  415. /* Found - now remove it from the list of entries.  */
  416. *pp = action->next;
  417. if (!desc->action) {
  418. desc->status |= IRQ_DISABLED;
  419. desc->handler->shutdown(irq);
  420. }
  421. spin_unlock_irqrestore(&desc->lock,flags);
  422. #ifdef CONFIG_SMP
  423. /* Wait to make sure it's not being used on
  424.    another CPU.  */
  425. while (desc->status & IRQ_INPROGRESS)
  426. barrier();
  427. #endif
  428. kfree(action);
  429. return;
  430. }
  431. printk(KERN_ERR "Trying to free free IRQ%dn",irq);
  432. spin_unlock_irqrestore(&desc->lock,flags);
  433. return;
  434. }
  435. }
  436. int
  437. get_irq_list(char *buf)
  438. {
  439. #ifdef CONFIG_SMP
  440. int j;
  441. #endif
  442. int i;
  443. struct irqaction * action;
  444. char *p = buf;
  445. #ifdef CONFIG_SMP
  446. p += sprintf(p, "           ");
  447. for (i = 0; i < smp_num_cpus; i++)
  448. p += sprintf(p, "CPU%d       ", i);
  449. #ifdef DO_BROADCAST_INTS
  450. for (i = 0; i < smp_num_cpus; i++)
  451. p += sprintf(p, "TRY%d       ", i);
  452. #endif
  453. *p++ = 'n';
  454. #endif
  455. for (i = 0; i < NR_IRQS; i++) {
  456. action = irq_desc[i].action;
  457. if (!action) 
  458. continue;
  459. p += sprintf(p, "%3d: ",i);
  460. #ifndef CONFIG_SMP
  461. p += sprintf(p, "%10u ", kstat_irqs(i));
  462. #else
  463. for (j = 0; j < smp_num_cpus; j++)
  464. p += sprintf(p, "%10u ",
  465.      kstat.irqs[cpu_logical_map(j)][i]);
  466. #ifdef DO_BROADCAST_INTS
  467. for (j = 0; j < smp_num_cpus; j++)
  468. p += sprintf(p, "%10lu ",
  469.      irq_attempt(cpu_logical_map(j), i));
  470. #endif
  471. #endif
  472. p += sprintf(p, " %14s", irq_desc[i].handler->typename);
  473. p += sprintf(p, "  %c%s",
  474.      (action->flags & SA_INTERRUPT)?'+':' ',
  475.      action->name);
  476. for (action=action->next; action; action = action->next) {
  477. p += sprintf(p, ", %c%s",
  478.      (action->flags & SA_INTERRUPT)?'+':' ',
  479.      action->name);
  480. }
  481. *p++ = 'n';
  482. }
  483. #if CONFIG_SMP
  484. p += sprintf(p, "IPI: ");
  485. for (j = 0; j < smp_num_cpus; j++)
  486. p += sprintf(p, "%10lu ",
  487.      cpu_data[cpu_logical_map(j)].ipi_count);
  488. p += sprintf(p, "n");
  489. #endif
  490. p += sprintf(p, "ERR: %10lun", irq_err_count);
  491. return p - buf;
  492. }
  493. /*
  494.  * handle_irq handles all normal device IRQ's (the special
  495.  * SMP cross-CPU interrupts have their own specific
  496.  * handlers).
  497.  */
  498. #define MAX_ILLEGAL_IRQS 16
  499. void
  500. handle_irq(int irq, struct pt_regs * regs)
  501. {
  502. /* 
  503.  * We ack quickly, we don't want the irq controller
  504.  * thinking we're snobs just because some other CPU has
  505.  * disabled global interrupts (we have already done the
  506.  * INT_ACK cycles, it's too late to try to pretend to the
  507.  * controller that we aren't taking the interrupt).
  508.  *
  509.  * 0 return value means that this irq is already being
  510.  * handled by some other CPU. (or is disabled)
  511.  */
  512. int cpu = smp_processor_id();
  513. irq_desc_t *desc = irq_desc + irq;
  514. struct irqaction * action;
  515. unsigned int status;
  516. static unsigned int illegal_count=0;
  517. if ((unsigned) irq > ACTUAL_NR_IRQS && illegal_count < MAX_ILLEGAL_IRQS ) {
  518. irq_err_count++;
  519. illegal_count++;
  520. printk(KERN_CRIT "device_interrupt: illegal interrupt %dn",
  521.        irq);
  522. return;
  523. }
  524. irq_attempt(cpu, irq)++;
  525. spin_lock_irq(&desc->lock); /* mask also the higher prio events */
  526. desc->handler->ack(irq);
  527. /*
  528.  * REPLAY is when Linux resends an IRQ that was dropped earlier.
  529.  * WAITING is used by probe to mark irqs that are being tested.
  530.  */
  531. status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
  532. status |= IRQ_PENDING; /* we _want_ to handle it */
  533. /*
  534.  * If the IRQ is disabled for whatever reason, we cannot
  535.  * use the action we have.
  536.  */
  537. action = NULL;
  538. if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
  539. action = desc->action;
  540. status &= ~IRQ_PENDING; /* we commit to handling */
  541. status |= IRQ_INPROGRESS; /* we are handling it */
  542. }
  543. desc->status = status;
  544. /*
  545.  * If there is no IRQ handler or it was disabled, exit early.
  546.  * Since we set PENDING, if another processor is handling
  547.  * a different instance of this same irq, the other processor
  548.  * will take care of it.
  549.  */
  550. if (!action)
  551. goto out;
  552. /*
  553.  * Edge triggered interrupts need to remember pending events.
  554.  * This applies to any hw interrupts that allow a second
  555.  * instance of the same irq to arrive while we are in handle_irq
  556.  * or in the handler. But the code here only handles the _second_
  557.  * instance of the irq, not the third or fourth. So it is mostly
  558.  * useful for irq hardware that does not mask cleanly in an
  559.  * SMP environment.
  560.  */
  561. for (;;) {
  562. spin_unlock(&desc->lock);
  563. handle_IRQ_event(irq, regs, action);
  564. spin_lock(&desc->lock);
  565. if (!(desc->status & IRQ_PENDING)
  566.     || (desc->status & IRQ_LEVEL))
  567. break;
  568. desc->status &= ~IRQ_PENDING;
  569. }
  570. desc->status &= ~IRQ_INPROGRESS;
  571. out:
  572. /*
  573.  * The ->end() handler has to deal with interrupts which got
  574.  * disabled while the handler was running.
  575.  */
  576. desc->handler->end(irq);
  577. spin_unlock(&desc->lock);
  578. if (softirq_pending(cpu))
  579. do_softirq();
  580. }
  581. /*
  582.  * IRQ autodetection code..
  583.  *
  584.  * This depends on the fact that any interrupt that
  585.  * comes in on to an unassigned handler will get stuck
  586.  * with "IRQ_WAITING" cleared and the interrupt
  587.  * disabled.
  588.  */
  589. unsigned long
  590. probe_irq_on(void)
  591. {
  592. int i;
  593. irq_desc_t *desc;
  594. unsigned long delay;
  595. unsigned long val;
  596. /* Something may have generated an irq long ago and we want to
  597.    flush such a longstanding irq before considering it as spurious. */
  598. for (i = NR_IRQS-1; i >= 0; i--) {
  599. desc = irq_desc + i;
  600. spin_lock_irq(&desc->lock);
  601. if (!irq_desc[i].action) 
  602. irq_desc[i].handler->startup(i);
  603. spin_unlock_irq(&desc->lock);
  604. }
  605. /* Wait for longstanding interrupts to trigger. */
  606. for (delay = jiffies + HZ/50; time_after(delay, jiffies); )
  607. /* about 20ms delay */ synchronize_irq();
  608. /* enable any unassigned irqs (we must startup again here because
  609.    if a longstanding irq happened in the previous stage, it may have
  610.    masked itself) first, enable any unassigned irqs. */
  611. for (i = NR_IRQS-1; i >= 0; i--) {
  612. desc = irq_desc + i;
  613. spin_lock_irq(&desc->lock);
  614. if (!desc->action) {
  615. desc->status |= IRQ_AUTODETECT | IRQ_WAITING;
  616. if (desc->handler->startup(i))
  617. desc->status |= IRQ_PENDING;
  618. }
  619. spin_unlock_irq(&desc->lock);
  620. }
  621. /*
  622.  * Wait for spurious interrupts to trigger
  623.  */
  624. for (delay = jiffies + HZ/10; time_after(delay, jiffies); )
  625. /* about 100ms delay */ synchronize_irq();
  626. /*
  627.  * Now filter out any obviously spurious interrupts
  628.  */
  629. val = 0;
  630. for (i=0; i<NR_IRQS; i++) {
  631. irq_desc_t *desc = irq_desc + i;
  632. unsigned int status;
  633. spin_lock_irq(&desc->lock);
  634. status = desc->status;
  635. if (status & IRQ_AUTODETECT) {
  636. /* It triggered already - consider it spurious. */
  637. if (!(status & IRQ_WAITING)) {
  638. desc->status = status & ~IRQ_AUTODETECT;
  639. desc->handler->shutdown(i);
  640. } else
  641. if (i < 32)
  642. val |= 1 << i;
  643. }
  644. spin_unlock_irq(&desc->lock);
  645. }
  646. return val;
  647. }
  648. /*
  649.  * Return a mask of triggered interrupts (this
  650.  * can handle only legacy ISA interrupts).
  651.  */
  652. unsigned int
  653. probe_irq_mask(unsigned long val)
  654. {
  655. int i;
  656. unsigned int mask;
  657. mask = 0;
  658. for (i = 0; i < NR_IRQS; i++) {
  659. irq_desc_t *desc = irq_desc + i;
  660. unsigned int status;
  661. spin_lock_irq(&desc->lock);
  662. status = desc->status;
  663. if (status & IRQ_AUTODETECT) {
  664. /* We only react to ISA interrupts */
  665. if (!(status & IRQ_WAITING)) {
  666. if (i < 16)
  667. mask |= 1 << i;
  668. }
  669. desc->status = status & ~IRQ_AUTODETECT;
  670. desc->handler->shutdown(i);
  671. }
  672. spin_unlock_irq(&desc->lock);
  673. }
  674. return mask & val;
  675. }
  676. /*
  677.  * Get the result of the IRQ probe.. A negative result means that
  678.  * we have several candidates (but we return the lowest-numbered
  679.  * one).
  680.  */
  681. int
  682. probe_irq_off(unsigned long val)
  683. {
  684. int i, irq_found, nr_irqs;
  685. nr_irqs = 0;
  686. irq_found = 0;
  687. for (i=0; i<NR_IRQS; i++) {
  688. irq_desc_t *desc = irq_desc + i;
  689. unsigned int status;
  690. spin_lock_irq(&desc->lock);
  691. status = desc->status;
  692. if (status & IRQ_AUTODETECT) {
  693. if (!(status & IRQ_WAITING)) {
  694. if (!nr_irqs)
  695. irq_found = i;
  696. nr_irqs++;
  697. }
  698. desc->status = status & ~IRQ_AUTODETECT;
  699. desc->handler->shutdown(i);
  700. }
  701. spin_unlock_irq(&desc->lock);
  702. }
  703. if (nr_irqs > 1)
  704. irq_found = -irq_found;
  705. return irq_found;
  706. }