|
@@ -788,6 +788,7 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
|
|
struct pcmcia_socket *s = p_dev->socket;
|
|
struct pcmcia_socket *s = p_dev->socket;
|
|
config_t *c;
|
|
config_t *c;
|
|
int ret = CS_IN_USE, irq = 0;
|
|
int ret = CS_IN_USE, irq = 0;
|
|
|
|
+ int type;
|
|
|
|
|
|
if (!(s->state & SOCKET_PRESENT))
|
|
if (!(s->state & SOCKET_PRESENT))
|
|
return CS_NO_CARD;
|
|
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)
|
|
if (c->state & CONFIG_IRQ_REQ)
|
|
return CS_IN_USE;
|
|
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
|
|
#ifdef CONFIG_PCMCIA_PROBE
|
|
if (s->irq.AssignedIRQ != 0) {
|
|
if (s->irq.AssignedIRQ != 0) {
|
|
/* If the interrupt is already assigned, it must be the same */
|
|
/* 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 */
|
|
* marked as used by the kernel resource management core */
|
|
ret = request_irq(irq,
|
|
ret = request_irq(irq,
|
|
(req->Attributes & IRQ_HANDLE_PRESENT) ? req->Handler : test_action,
|
|
(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,
|
|
p_dev->devname,
|
|
(req->Attributes & IRQ_HANDLE_PRESENT) ? req->Instance : data);
|
|
(req->Attributes & IRQ_HANDLE_PRESENT) ? req->Instance : data);
|
|
if (!ret) {
|
|
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 (ret && !s->irq.AssignedIRQ) {
|
|
if (!s->pci_irq)
|
|
if (!s->pci_irq)
|
|
return ret;
|
|
return ret;
|
|
|
|
+ type = SA_SHIRQ;
|
|
irq = s->pci_irq;
|
|
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;
|
|
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;
|
|
c->irq.Attributes = req->Attributes;
|
|
s->irq.AssignedIRQ = req->AssignedIRQ = irq;
|
|
s->irq.AssignedIRQ = req->AssignedIRQ = irq;
|
|
s->irq.Config++;
|
|
s->irq.Config++;
|