acxpci.h: include struct acx_device but \#if 0 it
[acx-mac80211.git] / irq.c
blobb33f8385006b65e35addb2f26f39f3a3d162bedb
1 /*
2 * IRQ handling: top half, bottom half (halves?) and utilities.
4 * This file is mainly modeled on the b43 way of doing things.
6 * Copyright (c) 2008, Francis Galiegue <fgaliegue@gmail.com> for the ACX100
7 * driver project.
9 * This file is licensed under GPLv2.
11 #include <linux/irq.h>
12 #include <linux/spinlock.h>
14 #include "acx_config.h"
15 #include "acx_log.h"
16 #include "acx_struct.h"
17 #include "acx_irq.h"
20 * acx_enable_irqs() and acx_disable_irqs():
23 /**
24 * acx_enable_irqs(): set the interrupt mask on the card. Should be called with
25 * a mask saved by the acx_disable_irqs() function.
26 * @adev: the device on which to enable the IRQs.
27 * @mask: the mask to apply to this device.
29 //void acx_enable_irqs(acx_device_t *adev, u16 mask)
30 //{
31 // write_reg16(adev, ACX_IO_IRQ_MASK, mask);
32 // write_reg16(adev, ACX_IO_FEMR, 0x0);
33 // smp_wmb();
34 //}
36 /**
37 * acx_disable_irqs(): set an interrupt mask on the card, and return the mask
38 * that was present on the card.
39 * @adev: the device on which to disable the IRQs.
40 * @mask: the mask to set.
42 * FIXME: I couldn't actually find an example of reading the current interrupt
43 * mask, but it would make sense that you read it from the same location that
44 * you write to...
46 //u16 acx_disable_irqs(acx_device_t *adev, u16 mask)
47 //{
48 // u16 saved_mask = read_reg16(adev, ACX_IO_IRQ_MASK);
49 // write_reg16(adev, ACX_IO_IRQ_MASK, mask);
50 // write_reg16(adev, ACX_IO_FEMR, 0x0);
51 // smp_wmb();
52 // return saved_mask;
53 //}
56 /**
57 * acx_interrupt_tophalf(): the IRQ top half routine, called when an interrupt
58 * is raised.
59 * @irq: the IRQ line number.
60 * @dev_id: the current device addressed by this interrupt (or not, since our
61 * IRQ line can be shared).
63 * Theory of operation:
64 * - spin_lock the device's irqlock;
65 * - acknowledge the IRQ on the card;
66 * - schedule the bottom half;
67 * - disable ALL interrupts on the card they will be re-enabled by the
68 * bottom half;
69 * - spin_unlock the device's irqlock;
70 * - tell the kernel that we are done.
73 //irqreturn_t acx_interrupt_tophalf(int irq, void *dev_id)
74 //{
75 // irqreturn_t ret = IRQ_NONE;
76 // acx_device_t *adev = dev_id;
77 // u16 saved_mask, reason;
78 //
79 // if (!adev)
80 // return IRQ_NONE;
82 // spin_lock(&adev->irqlock);
83 //
84 // /* Check whether the device is started. If not, out! */
85 // if (!adev->initialized)
86 // goto out;
88 // reason = read_reg16(adev, ACX_IO_IRQ_REASON);
89 // if (reason == ACX_IRQ_ALL) {
90 // /*
91 // * Original code says this is because of missing hardware?
92 // *
93 // * Anyway, other drivers hint at this meaning: shared interrupt
94 // * and it's not ours. I like that description better.
95 // */
96 // goto out;
97 // }
99 // ret = IRQ_HANDLED;
100 // /*
101 // * If it's not an interrupt the card is currently handling, out
102 // */
103 // reason &= read_reg16(adev, ACX_IO_IRQ_MASK);
104 // if (!reason)
105 // goto out;
107 // /*
108 // * Tell the card that we got it.
109 // *
110 // * FIXME: the original code writes ACX_IRQ_ALL?? Other drivers write
111 // * only the real reason, I choose to do it that way.
112 // */
113 // write_reg16(adev, ACX_IO_IRQ_ACK, reason);
114 // /*
115 // * FIXME: the current code leaves some interrupts in the clear, let's
116 // * try not to here
117 // */
118 // adev->irq_saved_mask = acx_disable_irqs(adev, ACX_IRQ_ALL);
119 // /*
120 // * Save the IRQ reason for our bottom half to read
121 // */
122 // adev->irq_reason = reason;
124 // /*
125 // * TODO!!
126 // *
127 // * tasklet_schedule(&adev->some_field);
128 // */
131 //out:
132 // //mmiowb(); Necessary?
133 // spin_unlock(&adev->irqlock);
134 // return ret;
138 * acx_interrupt_bottomhalf(): the interrupt bottom half, as its name says.
139 * @adev: the device on behalf of which this bottom half is called.
141 * Theory of operation:
142 * - enter with all card interrupts DISABLED!
143 * - spin_lock_irqsave() the device's irq_lock;
144 * - handle the interrupt (reason is stored in ->irq_reason);
145 * - re-enable on-card interrupts (saved in ->irq_saved_mask);
146 * - spin_unlock_irqrestore() the device's irq_lock.
149 //void acx_interrupt_bottomhalf(acx_device_t *adev)
151 // u16 reason;
152 // unsigned long flags;
154 // spin_lock_irqsave(&adev->irqlock, flags);
156 // reason = adev->irq_reason;
157 // //TODO: fill these!
161 // acx_enable_irqs(adev, adev->irq_saved_mask);
162 // spin_unlock_irqrestore(&adev->irqlock, flags);