aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Cox <alan@lxorguk.ukuu.org.uk>2006-05-16 16:16:44 +0100
committerDominik Brodowski <linux@dominikbrodowski.net>2006-06-30 22:09:10 +0200
commitc533120b8da215dc02310c535fa87c5c480d0f14 (patch)
tree5142cad1107953e1655c7153ef10b7cc0719f068
parentd29693bf10f376870d9bfd34bde80dd061cc4575 (diff)
[PATCH] pcmcia: warn if driver requests exclusive, but gets a shared IRQ
The patch below cleans up the pcmcia code a bit on the IRQ side (I did this while debugging the problem just so I could read wtf it was doing), and also adds a warning and passes back the correct information when a device asks for exclusive but gets given shared. This at least means the dmesg dump of a problem triggered by this will have a signature to find. Signed-off-by: Alan Cox <alan@redhat.com> Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
-rw-r--r--drivers/pcmcia/pcmcia_resource.c27
1 files changed, 18 insertions, 9 deletions
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c
index 3131bb0a009..3281e519e71 100644
--- a/drivers/pcmcia/pcmcia_resource.c
+++ b/drivers/pcmcia/pcmcia_resource.c
@@ -788,6 +788,7 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
struct pcmcia_socket *s = p_dev->socket;
config_t *c;
int ret = CS_IN_USE, irq = 0;
+ int type;
if (!(s->state & SOCKET_PRESENT))
return CS_NO_CARD;
@@ -797,6 +798,13 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
if (c->state & CONFIG_IRQ_REQ)
return CS_IN_USE;
+ /* Decide what type of interrupt we are registering */
+ type = 0;
+ if (s->functions > 1) /* All of this ought to be handled higher up */
+ type = SA_SHIRQ;
+ if (req->Attributes & IRQ_TYPE_DYNAMIC_SHARING)
+ type = SA_SHIRQ;
+
#ifdef CONFIG_PCMCIA_PROBE
if (s->irq.AssignedIRQ != 0) {
/* If the interrupt is already assigned, it must be the same */
@@ -822,9 +830,7 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
* marked as used by the kernel resource management core */
ret = request_irq(irq,
(req->Attributes & IRQ_HANDLE_PRESENT) ? req->Handler : test_action,
- ((req->Attributes & IRQ_TYPE_DYNAMIC_SHARING) ||
- (s->functions > 1) ||
- (irq == s->pci_irq)) ? SA_SHIRQ : 0,
+ type,
p_dev->devname,
(req->Attributes & IRQ_HANDLE_PRESENT) ? req->Instance : data);
if (!ret) {
@@ -839,18 +845,21 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
if (ret && !s->irq.AssignedIRQ) {
if (!s->pci_irq)
return ret;
+ type = SA_SHIRQ;
irq = s->pci_irq;
}
- if (ret && req->Attributes & IRQ_HANDLE_PRESENT) {
- if (request_irq(irq, req->Handler,
- ((req->Attributes & IRQ_TYPE_DYNAMIC_SHARING) ||
- (s->functions > 1) ||
- (irq == s->pci_irq)) ? SA_SHIRQ : 0,
- p_dev->devname, req->Instance))
+ if (ret && (req->Attributes & IRQ_HANDLE_PRESENT)) {
+ if (request_irq(irq, req->Handler, type, p_dev->devname, req->Instance))
return CS_IN_USE;
}
+ /* Make sure the fact the request type was overridden is passed back */
+ if (type == SA_SHIRQ && !(req->Attributes & IRQ_TYPE_DYNAMIC_SHARING)) {
+ req->Attributes |= IRQ_TYPE_DYNAMIC_SHARING;
+ printk(KERN_WARNING "pcmcia: request for exclusive IRQ could not be fulfilled.\n");
+ printk(KERN_WARNING "pcmcia: the driver needs updating to supported shared IRQ lines.\n");
+ }
c->irq.Attributes = req->Attributes;
s->irq.AssignedIRQ = req->AssignedIRQ = irq;
s->irq.Config++;