/alps/pcitool

To get this branch, use:
bzr branch http://suren.me/webbzr/alps/pcitool

« back to all changes in this revision

Viewing changes to driver/int.c

  • Committer: Suren A. Chilingaryan
  • Date: 2016-03-02 18:37:30 UTC
  • Revision ID: csa@suren.me-20160302183730-nlrgi7h3yuizcizc
Restructure driver headers

Show diffs side-by-side

added added

removed removed

Lines of Context:
7
7
 *
8
8
 */
9
9
 
10
 
/*
11
 
 * Change History:
12
 
 *
13
 
 * $Log: not supported by cvs2svn $
14
 
 * Revision 1.7  2008-01-11 10:18:28  marcus
15
 
 * Modified interrupt mechanism. Added atomic functions and queues, to address race conditions. Removed unused interrupt code.
16
 
 *
17
 
 * Revision 1.6  2007-11-04 20:58:22  marcus
18
 
 * Added interrupt generator acknowledge.
19
 
 * Fixed wrong operator.
20
 
 *
21
 
 * Revision 1.5  2007-10-31 15:42:21  marcus
22
 
 * Added IG ack for testing, may be removed later.
23
 
 *
24
 
 * Revision 1.4  2007-07-17 13:15:56  marcus
25
 
 * Removed Tasklets.
26
 
 * Using newest map for the ABB interrupts.
27
 
 *
28
 
 * Revision 1.3  2007-07-05 15:30:30  marcus
29
 
 * Added support for both register maps of the ABB.
30
 
 *
31
 
 * Revision 1.2  2007-05-29 07:50:18  marcus
32
 
 * Split code into 2 files. May get merged in the future again....
33
 
 *
34
 
 * Revision 1.1  2007/03/01 16:57:43  marcus
35
 
 * Divided driver file to ease the interrupt hooks for the user of the driver.
36
 
 * Modified Makefile accordingly.
37
 
 *
38
 
 */
39
 
 
40
10
#include <linux/version.h>
41
11
#include <linux/string.h>
42
12
#include <linux/types.h>
48
18
#include <linux/sched.h>
49
19
#include <stdbool.h>
50
20
 
51
 
#include "config.h"
52
 
 
53
 
#include "compat.h"
54
 
 
55
 
#include "pciDriver.h"
56
 
 
57
 
#include "common.h"
58
 
 
59
 
#include "int.h"
60
 
 
61
 
/*
62
 
 * The ID between IRQ_SOURCE in irq_outstanding and the actual source is arbitrary.
63
 
 * Therefore, be careful when communicating with multiple implementations.
64
 
 */
65
 
 
66
 
/* IRQ_SOURCES */
67
 
#define ABB_IRQ_CH0             0
68
 
#define ABB_IRQ_CH1             1
69
 
#define ABB_IRQ_IG              2
70
 
 
71
 
/* See ABB user’s guide, register definitions (3.1) */
72
 
#define ABB_INT_ENABLE          (0x0010 >> 2)
73
 
#define ABB_INT_STAT            (0x0008 >> 2)
74
 
 
75
 
#define ABB_INT_CH1_TIMEOUT     (1 << 4)
76
 
#define ABB_INT_CH0_TIMEOUT     (1 << 5)
77
 
#define ABB_INT_IG              (1 << 2)
78
 
#define ABB_INT_CH0             (1 << 1) /* downstream */
79
 
#define ABB_INT_CH1             (1)     /* upstream */
80
 
 
81
 
#define ABB_CH0_CTRL            (108 >> 2)
82
 
#define ABB_CH1_CTRL            (72 >> 2)
83
 
#define ABB_CH_RESET            (0x0201000A)
84
 
#define ABB_IG_CTRL             (0x0080 >> 2)
85
 
#define ABB_IG_ACK              (0x00F0)
 
21
#include "base.h"
 
22
 
 
23
/**
 
24
 *
 
25
 * Acknowledges the receival of an interrupt to the card.
 
26
 *
 
27
 * @returns true if the card was acknowledget
 
28
 * @returns false if the interrupt was not for one of our cards
 
29
 *
 
30
 * @see check_acknowlegde_channel
 
31
 *
 
32
 */
 
33
static bool pcidriver_irq_acknowledge(pcidriver_privdata_t *privdata)
 
34
{
 
35
    int channel = 0;
 
36
 
 
37
    atomic_inc(&(privdata->irq_outstanding[channel]));
 
38
    wake_up_interruptible(&(privdata->irq_queues[channel]));
 
39
 
 
40
    return true;
 
41
}
 
42
 
 
43
/**
 
44
 *
 
45
 * Handles IRQs. At the moment, this acknowledges the card that this IRQ
 
46
 * was received and then increases the driver's IRQ counter.
 
47
 *
 
48
 * @see pcidriver_irq_acknowledge
 
49
 *
 
50
 */
 
51
static irqreturn_t pcidriver_irq_handler(int irq, void *dev_id)
 
52
{
 
53
    pcidriver_privdata_t *privdata = (pcidriver_privdata_t *)dev_id;
 
54
 
 
55
    if (!pcidriver_irq_acknowledge(privdata))
 
56
        return IRQ_NONE;
 
57
 
 
58
    privdata->irq_count++;
 
59
    return IRQ_HANDLED;
 
60
}
 
61
 
86
62
 
87
63
/**
88
64
 *
167
143
        privdata->msi_mode = 1;
168
144
 
169
145
    /* register interrupt handler */
170
 
    if ((err = request_irq(privdata->pdev->irq, pcidriver_irq_handler, MODNAME, privdata)) != 0) {
 
146
    if ((err = request_irq(privdata->pdev->irq, pcidriver_irq_handler, IRQF_SHARED, MODNAME, privdata)) != 0) {
171
147
        mod_info("Error registering the interrupt handler. Disabling interrupts for this device\n");
172
148
        return 0;
173
149
    }
215
191
    }
216
192
}
217
193
 
218
 
/**
219
 
 *
220
 
 * Acknowledges the receival of an interrupt to the card.
221
 
 *
222
 
 * @returns true if the card was acknowledget
223
 
 * @returns false if the interrupt was not for one of our cards
224
 
 *
225
 
 * @see check_acknowlegde_channel
226
 
 *
227
 
 */
228
 
static bool pcidriver_irq_acknowledge(pcidriver_privdata_t *privdata)
229
 
{
230
 
    int channel = 0;
231
 
//      volatile unsigned int *bar;
232
 
//      bar = privdata->bars_kmapped[0];
233
 
//      mod_info_dbg("interrupt registers. ISR: %x, IER: %x\n", bar[ABB_INT_STAT], bar[ABB_INT_ENABLE]);
234
 
 
235
 
    atomic_inc(&(privdata->irq_outstanding[channel]));
236
 
    wake_up_interruptible(&(privdata->irq_queues[channel]));
237
 
 
238
 
    return true;
239
 
}
240
 
 
241
 
/**
242
 
 *
243
 
 * Handles IRQs. At the moment, this acknowledges the card that this IRQ
244
 
 * was received and then increases the driver's IRQ counter.
245
 
 *
246
 
 * @see pcidriver_irq_acknowledge
247
 
 *
248
 
 */
249
 
IRQ_HANDLER_FUNC(pcidriver_irq_handler)
250
 
{
251
 
    pcidriver_privdata_t *privdata = (pcidriver_privdata_t *)dev_id;
252
 
 
253
 
    if (!pcidriver_irq_acknowledge(privdata))
254
 
        return IRQ_NONE;
255
 
 
256
 
    privdata->irq_count++;
257
 
    return IRQ_HANDLED;
258
 
}