OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [kernel/] [irq/] [manage.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 * linux/kernel/irq/manage.c
3
 *
4
 * Copyright (C) 1992, 1998-2006 Linus Torvalds, Ingo Molnar
5
 * Copyright (C) 2005-2006 Thomas Gleixner
6
 *
7
 * This file contains driver APIs to the irq subsystem.
8
 */
9
 
10
#include <linux/irq.h>
11
#include <linux/module.h>
12
#include <linux/random.h>
13
#include <linux/interrupt.h>
14
 
15
#include "internals.h"
16
 
17
#ifdef CONFIG_SMP
18
 
19
/**
20
 *      synchronize_irq - wait for pending IRQ handlers (on other CPUs)
21
 *      @irq: interrupt number to wait for
22
 *
23
 *      This function waits for any pending IRQ handlers for this interrupt
24
 *      to complete before returning. If you use this function while
25
 *      holding a resource the IRQ handler may need you will deadlock.
26
 *
27
 *      This function may be called - with care - from IRQ context.
28
 */
29
void synchronize_irq(unsigned int irq)
30
{
31
        struct irq_desc *desc = irq_desc + irq;
32
        unsigned int status;
33
 
34
        if (irq >= NR_IRQS)
35
                return;
36
 
37
        do {
38
                unsigned long flags;
39
 
40
                /*
41
                 * Wait until we're out of the critical section.  This might
42
                 * give the wrong answer due to the lack of memory barriers.
43
                 */
44
                while (desc->status & IRQ_INPROGRESS)
45
                        cpu_relax();
46
 
47
                /* Ok, that indicated we're done: double-check carefully. */
48
                spin_lock_irqsave(&desc->lock, flags);
49
                status = desc->status;
50
                spin_unlock_irqrestore(&desc->lock, flags);
51
 
52
                /* Oops, that failed? */
53
        } while (status & IRQ_INPROGRESS);
54
}
55
EXPORT_SYMBOL(synchronize_irq);
56
 
57
/**
58
 *      irq_can_set_affinity - Check if the affinity of a given irq can be set
59
 *      @irq:           Interrupt to check
60
 *
61
 */
62
int irq_can_set_affinity(unsigned int irq)
63
{
64
        struct irq_desc *desc = irq_desc + irq;
65
 
66
        if (CHECK_IRQ_PER_CPU(desc->status) || !desc->chip ||
67
            !desc->chip->set_affinity)
68
                return 0;
69
 
70
        return 1;
71
}
72
 
73
/**
74
 *      irq_set_affinity - Set the irq affinity of a given irq
75
 *      @irq:           Interrupt to set affinity
76
 *      @cpumask:       cpumask
77
 *
78
 */
79
int irq_set_affinity(unsigned int irq, cpumask_t cpumask)
80
{
81
        struct irq_desc *desc = irq_desc + irq;
82
 
83
        if (!desc->chip->set_affinity)
84
                return -EINVAL;
85
 
86
        set_balance_irq_affinity(irq, cpumask);
87
 
88
#ifdef CONFIG_GENERIC_PENDING_IRQ
89
        set_pending_irq(irq, cpumask);
90
#else
91
        desc->affinity = cpumask;
92
        desc->chip->set_affinity(irq, cpumask);
93
#endif
94
        return 0;
95
}
96
 
97
#endif
98
 
99
/**
100
 *      disable_irq_nosync - disable an irq without waiting
101
 *      @irq: Interrupt to disable
102
 *
103
 *      Disable the selected interrupt line.  Disables and Enables are
104
 *      nested.
105
 *      Unlike disable_irq(), this function does not ensure existing
106
 *      instances of the IRQ handler have completed before returning.
107
 *
108
 *      This function may be called from IRQ context.
109
 */
110
void disable_irq_nosync(unsigned int irq)
111
{
112
        struct irq_desc *desc = irq_desc + irq;
113
        unsigned long flags;
114
 
115
        if (irq >= NR_IRQS)
116
                return;
117
 
118
        spin_lock_irqsave(&desc->lock, flags);
119
        if (!desc->depth++) {
120
                desc->status |= IRQ_DISABLED;
121
                desc->chip->disable(irq);
122
        }
123
        spin_unlock_irqrestore(&desc->lock, flags);
124
}
125
EXPORT_SYMBOL(disable_irq_nosync);
126
 
127
/**
128
 *      disable_irq - disable an irq and wait for completion
129
 *      @irq: Interrupt to disable
130
 *
131
 *      Disable the selected interrupt line.  Enables and Disables are
132
 *      nested.
133
 *      This function waits for any pending IRQ handlers for this interrupt
134
 *      to complete before returning. If you use this function while
135
 *      holding a resource the IRQ handler may need you will deadlock.
136
 *
137
 *      This function may be called - with care - from IRQ context.
138
 */
139
void disable_irq(unsigned int irq)
140
{
141
        struct irq_desc *desc = irq_desc + irq;
142
 
143
        if (irq >= NR_IRQS)
144
                return;
145
 
146
        disable_irq_nosync(irq);
147
        if (desc->action)
148
                synchronize_irq(irq);
149
}
150
EXPORT_SYMBOL(disable_irq);
151
 
152
/**
153
 *      enable_irq - enable handling of an irq
154
 *      @irq: Interrupt to enable
155
 *
156
 *      Undoes the effect of one call to disable_irq().  If this
157
 *      matches the last disable, processing of interrupts on this
158
 *      IRQ line is re-enabled.
159
 *
160
 *      This function may be called from IRQ context.
161
 */
162
void enable_irq(unsigned int irq)
163
{
164
        struct irq_desc *desc = irq_desc + irq;
165
        unsigned long flags;
166
 
167
        if (irq >= NR_IRQS)
168
                return;
169
 
170
        spin_lock_irqsave(&desc->lock, flags);
171
        switch (desc->depth) {
172
        case 0:
173
                printk(KERN_WARNING "Unbalanced enable for IRQ %d\n", irq);
174
                WARN_ON(1);
175
                break;
176
        case 1: {
177
                unsigned int status = desc->status & ~IRQ_DISABLED;
178
 
179
                /* Prevent probing on this irq: */
180
                desc->status = status | IRQ_NOPROBE;
181
                check_irq_resend(desc, irq);
182
                /* fall-through */
183
        }
184
        default:
185
                desc->depth--;
186
        }
187
        spin_unlock_irqrestore(&desc->lock, flags);
188
}
189
EXPORT_SYMBOL(enable_irq);
190
 
191
/**
192
 *      set_irq_wake - control irq power management wakeup
193
 *      @irq:   interrupt to control
194
 *      @on:    enable/disable power management wakeup
195
 *
196
 *      Enable/disable power management wakeup mode, which is
197
 *      disabled by default.  Enables and disables must match,
198
 *      just as they match for non-wakeup mode support.
199
 *
200
 *      Wakeup mode lets this IRQ wake the system from sleep
201
 *      states like "suspend to RAM".
202
 */
203
int set_irq_wake(unsigned int irq, unsigned int on)
204
{
205
        struct irq_desc *desc = irq_desc + irq;
206
        unsigned long flags;
207
        int ret = -ENXIO;
208
        int (*set_wake)(unsigned, unsigned) = desc->chip->set_wake;
209
 
210
        /* wakeup-capable irqs can be shared between drivers that
211
         * don't need to have the same sleep mode behaviors.
212
         */
213
        spin_lock_irqsave(&desc->lock, flags);
214
        if (on) {
215
                if (desc->wake_depth++ == 0)
216
                        desc->status |= IRQ_WAKEUP;
217
                else
218
                        set_wake = NULL;
219
        } else {
220
                if (desc->wake_depth == 0) {
221
                        printk(KERN_WARNING "Unbalanced IRQ %d "
222
                                        "wake disable\n", irq);
223
                        WARN_ON(1);
224
                } else if (--desc->wake_depth == 0)
225
                        desc->status &= ~IRQ_WAKEUP;
226
                else
227
                        set_wake = NULL;
228
        }
229
        if (set_wake)
230
                ret = desc->chip->set_wake(irq, on);
231
        spin_unlock_irqrestore(&desc->lock, flags);
232
        return ret;
233
}
234
EXPORT_SYMBOL(set_irq_wake);
235
 
236
/*
237
 * Internal function that tells the architecture code whether a
238
 * particular irq has been exclusively allocated or is available
239
 * for driver use.
240
 */
241
int can_request_irq(unsigned int irq, unsigned long irqflags)
242
{
243
        struct irqaction *action;
244
 
245
        if (irq >= NR_IRQS || irq_desc[irq].status & IRQ_NOREQUEST)
246
                return 0;
247
 
248
        action = irq_desc[irq].action;
249
        if (action)
250
                if (irqflags & action->flags & IRQF_SHARED)
251
                        action = NULL;
252
 
253
        return !action;
254
}
255
 
256
void compat_irq_chip_set_default_handler(struct irq_desc *desc)
257
{
258
        /*
259
         * If the architecture still has not overriden
260
         * the flow handler then zap the default. This
261
         * should catch incorrect flow-type setting.
262
         */
263
        if (desc->handle_irq == &handle_bad_irq)
264
                desc->handle_irq = NULL;
265
}
266
 
267
/*
268
 * Internal function to register an irqaction - typically used to
269
 * allocate special interrupts that are part of the architecture.
270
 */
271
int setup_irq(unsigned int irq, struct irqaction *new)
272
{
273
        struct irq_desc *desc = irq_desc + irq;
274
        struct irqaction *old, **p;
275
        const char *old_name = NULL;
276
        unsigned long flags;
277
        int shared = 0;
278
 
279
        if (irq >= NR_IRQS)
280
                return -EINVAL;
281
 
282
        if (desc->chip == &no_irq_chip)
283
                return -ENOSYS;
284
        /*
285
         * Some drivers like serial.c use request_irq() heavily,
286
         * so we have to be careful not to interfere with a
287
         * running system.
288
         */
289
        if (new->flags & IRQF_SAMPLE_RANDOM) {
290
                /*
291
                 * This function might sleep, we want to call it first,
292
                 * outside of the atomic block.
293
                 * Yes, this might clear the entropy pool if the wrong
294
                 * driver is attempted to be loaded, without actually
295
                 * installing a new handler, but is this really a problem,
296
                 * only the sysadmin is able to do this.
297
                 */
298
                rand_initialize_irq(irq);
299
        }
300
 
301
        /*
302
         * The following block of code has to be executed atomically
303
         */
304
        spin_lock_irqsave(&desc->lock, flags);
305
        p = &desc->action;
306
        old = *p;
307
        if (old) {
308
                /*
309
                 * Can't share interrupts unless both agree to and are
310
                 * the same type (level, edge, polarity). So both flag
311
                 * fields must have IRQF_SHARED set and the bits which
312
                 * set the trigger type must match.
313
                 */
314
                if (!((old->flags & new->flags) & IRQF_SHARED) ||
315
                    ((old->flags ^ new->flags) & IRQF_TRIGGER_MASK)) {
316
                        old_name = old->name;
317
                        goto mismatch;
318
                }
319
 
320
#if defined(CONFIG_IRQ_PER_CPU)
321
                /* All handlers must agree on per-cpuness */
322
                if ((old->flags & IRQF_PERCPU) !=
323
                    (new->flags & IRQF_PERCPU))
324
                        goto mismatch;
325
#endif
326
 
327
                /* add new interrupt at end of irq queue */
328
                do {
329
                        p = &old->next;
330
                        old = *p;
331
                } while (old);
332
                shared = 1;
333
        }
334
 
335
        *p = new;
336
 
337
        /* Exclude IRQ from balancing */
338
        if (new->flags & IRQF_NOBALANCING)
339
                desc->status |= IRQ_NO_BALANCING;
340
 
341
        if (!shared) {
342
                irq_chip_set_defaults(desc->chip);
343
 
344
#if defined(CONFIG_IRQ_PER_CPU)
345
                if (new->flags & IRQF_PERCPU)
346
                        desc->status |= IRQ_PER_CPU;
347
#endif
348
 
349
                /* Setup the type (level, edge polarity) if configured: */
350
                if (new->flags & IRQF_TRIGGER_MASK) {
351
                        if (desc->chip && desc->chip->set_type)
352
                                desc->chip->set_type(irq,
353
                                                new->flags & IRQF_TRIGGER_MASK);
354
                        else
355
                                /*
356
                                 * IRQF_TRIGGER_* but the PIC does not support
357
                                 * multiple flow-types?
358
                                 */
359
                                printk(KERN_WARNING "No IRQF_TRIGGER set_type "
360
                                       "function for IRQ %d (%s)\n", irq,
361
                                       desc->chip ? desc->chip->name :
362
                                       "unknown");
363
                } else
364
                        compat_irq_chip_set_default_handler(desc);
365
 
366
                desc->status &= ~(IRQ_AUTODETECT | IRQ_WAITING |
367
                                  IRQ_INPROGRESS);
368
 
369
                if (!(desc->status & IRQ_NOAUTOEN)) {
370
                        desc->depth = 0;
371
                        desc->status &= ~IRQ_DISABLED;
372
                        if (desc->chip->startup)
373
                                desc->chip->startup(irq);
374
                        else
375
                                desc->chip->enable(irq);
376
                } else
377
                        /* Undo nested disables: */
378
                        desc->depth = 1;
379
        }
380
        /* Reset broken irq detection when installing new handler */
381
        desc->irq_count = 0;
382
        desc->irqs_unhandled = 0;
383
        spin_unlock_irqrestore(&desc->lock, flags);
384
 
385
        new->irq = irq;
386
        register_irq_proc(irq);
387
        new->dir = NULL;
388
        register_handler_proc(irq, new);
389
 
390
        return 0;
391
 
392
mismatch:
393
#ifdef CONFIG_DEBUG_SHIRQ
394
        if (!(new->flags & IRQF_PROBE_SHARED)) {
395
                printk(KERN_ERR "IRQ handler type mismatch for IRQ %d\n", irq);
396
                if (old_name)
397
                        printk(KERN_ERR "current handler: %s\n", old_name);
398
                dump_stack();
399
        }
400
#endif
401
        spin_unlock_irqrestore(&desc->lock, flags);
402
        return -EBUSY;
403
}
404
 
405
/**
406
 *      free_irq - free an interrupt
407
 *      @irq: Interrupt line to free
408
 *      @dev_id: Device identity to free
409
 *
410
 *      Remove an interrupt handler. The handler is removed and if the
411
 *      interrupt line is no longer in use by any driver it is disabled.
412
 *      On a shared IRQ the caller must ensure the interrupt is disabled
413
 *      on the card it drives before calling this function. The function
414
 *      does not return until any executing interrupts for this IRQ
415
 *      have completed.
416
 *
417
 *      This function must not be called from interrupt context.
418
 */
419
void free_irq(unsigned int irq, void *dev_id)
420
{
421
        struct irq_desc *desc;
422
        struct irqaction **p;
423
        unsigned long flags;
424
 
425
        WARN_ON(in_interrupt());
426
        if (irq >= NR_IRQS)
427
                return;
428
 
429
        desc = irq_desc + irq;
430
        spin_lock_irqsave(&desc->lock, flags);
431
        p = &desc->action;
432
        for (;;) {
433
                struct irqaction *action = *p;
434
 
435
                if (action) {
436
                        struct irqaction **pp = p;
437
 
438
                        p = &action->next;
439
                        if (action->dev_id != dev_id)
440
                                continue;
441
 
442
                        /* Found it - now remove it from the list of entries */
443
                        *pp = action->next;
444
 
445
                        /* Currently used only by UML, might disappear one day.*/
446
#ifdef CONFIG_IRQ_RELEASE_METHOD
447
                        if (desc->chip->release)
448
                                desc->chip->release(irq, dev_id);
449
#endif
450
 
451
                        if (!desc->action) {
452
                                desc->status |= IRQ_DISABLED;
453
                                if (desc->chip->shutdown)
454
                                        desc->chip->shutdown(irq);
455
                                else
456
                                        desc->chip->disable(irq);
457
                        }
458
                        spin_unlock_irqrestore(&desc->lock, flags);
459
                        unregister_handler_proc(irq, action);
460
 
461
                        /* Make sure it's not being used on another CPU */
462
                        synchronize_irq(irq);
463
#ifdef CONFIG_DEBUG_SHIRQ
464
                        /*
465
                         * It's a shared IRQ -- the driver ought to be
466
                         * prepared for it to happen even now it's
467
                         * being freed, so let's make sure....  We do
468
                         * this after actually deregistering it, to
469
                         * make sure that a 'real' IRQ doesn't run in
470
                         * parallel with our fake
471
                         */
472
                        if (action->flags & IRQF_SHARED) {
473
                                local_irq_save(flags);
474
                                action->handler(irq, dev_id);
475
                                local_irq_restore(flags);
476
                        }
477
#endif
478
                        kfree(action);
479
                        return;
480
                }
481
                printk(KERN_ERR "Trying to free already-free IRQ %d\n", irq);
482
                spin_unlock_irqrestore(&desc->lock, flags);
483
                return;
484
        }
485
}
486
EXPORT_SYMBOL(free_irq);
487
 
488
/**
489
 *      request_irq - allocate an interrupt line
490
 *      @irq: Interrupt line to allocate
491
 *      @handler: Function to be called when the IRQ occurs
492
 *      @irqflags: Interrupt type flags
493
 *      @devname: An ascii name for the claiming device
494
 *      @dev_id: A cookie passed back to the handler function
495
 *
496
 *      This call allocates interrupt resources and enables the
497
 *      interrupt line and IRQ handling. From the point this
498
 *      call is made your handler function may be invoked. Since
499
 *      your handler function must clear any interrupt the board
500
 *      raises, you must take care both to initialise your hardware
501
 *      and to set up the interrupt handler in the right order.
502
 *
503
 *      Dev_id must be globally unique. Normally the address of the
504
 *      device data structure is used as the cookie. Since the handler
505
 *      receives this value it makes sense to use it.
506
 *
507
 *      If your interrupt is shared you must pass a non NULL dev_id
508
 *      as this is required when freeing the interrupt.
509
 *
510
 *      Flags:
511
 *
512
 *      IRQF_SHARED             Interrupt is shared
513
 *      IRQF_DISABLED   Disable local interrupts while processing
514
 *      IRQF_SAMPLE_RANDOM      The interrupt can be used for entropy
515
 *
516
 */
517
int request_irq(unsigned int irq, irq_handler_t handler,
518
                unsigned long irqflags, const char *devname, void *dev_id)
519
{
520
        struct irqaction *action;
521
        int retval;
522
 
523
#ifdef CONFIG_LOCKDEP
524
        /*
525
         * Lockdep wants atomic interrupt handlers:
526
         */
527
        irqflags |= IRQF_DISABLED;
528
#endif
529
        /*
530
         * Sanity-check: shared interrupts must pass in a real dev-ID,
531
         * otherwise we'll have trouble later trying to figure out
532
         * which interrupt is which (messes up the interrupt freeing
533
         * logic etc).
534
         */
535
        if ((irqflags & IRQF_SHARED) && !dev_id)
536
                return -EINVAL;
537
        if (irq >= NR_IRQS)
538
                return -EINVAL;
539
        if (irq_desc[irq].status & IRQ_NOREQUEST)
540
                return -EINVAL;
541
        if (!handler)
542
                return -EINVAL;
543
 
544
        action = kmalloc(sizeof(struct irqaction), GFP_ATOMIC);
545
        if (!action)
546
                return -ENOMEM;
547
 
548
        action->handler = handler;
549
        action->flags = irqflags;
550
        cpus_clear(action->mask);
551
        action->name = devname;
552
        action->next = NULL;
553
        action->dev_id = dev_id;
554
 
555
        select_smp_affinity(irq);
556
 
557
#ifdef CONFIG_DEBUG_SHIRQ
558
        if (irqflags & IRQF_SHARED) {
559
                /*
560
                 * It's a shared IRQ -- the driver ought to be prepared for it
561
                 * to happen immediately, so let's make sure....
562
                 * We do this before actually registering it, to make sure that
563
                 * a 'real' IRQ doesn't run in parallel with our fake
564
                 */
565
                unsigned long flags;
566
 
567
                local_irq_save(flags);
568
                handler(irq, dev_id);
569
                local_irq_restore(flags);
570
        }
571
#endif
572
 
573
        retval = setup_irq(irq, action);
574
        if (retval)
575
                kfree(action);
576
 
577
        return retval;
578
}
579
EXPORT_SYMBOL(request_irq);

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.