Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1097d7ce authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/brodo/pcmcia-2.6:
  PCMCIA: resource, fix lock imbalance
  pcmcia: add important if statement
  pcmcia: re-route Cardbus IRQ to ISA on ti1130 bridges if necessary
  pcmcia: allow for cb_irq to differ from pci_dev's irq in yenta_socket
  pcmcia: honor saved flags in yenta_socket's I365_CSCINT register
  pcmcia: revert "irq probe can be done without risking an IRQ storm"
  pcmcia: pd6729, i82092: use parent (PCI) resources
  pcmcia/vrc4171: use local spinlock for device local lock.
parents 57b552ba 4e06e240
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -133,6 +133,7 @@ static int __devinit i82092aa_pci_probe(struct pci_dev *dev, const struct pci_de
		sockets[i].socket.map_size = 0x1000;
		sockets[i].socket.irq_mask = 0;
		sockets[i].socket.pci_irq  = dev->irq;
		sockets[i].socket.cb_dev  = dev;
		sockets[i].socket.owner = THIS_MODULE;

		sockets[i].number = i;
+1 −0
Original line number Diff line number Diff line
@@ -95,6 +95,7 @@
#define I365_CSC_DETECT	0x08
#define I365_CSC_ANY	0x0F
#define I365_CSC_GPI	0x10
#define I365_CSC_IRQ_MASK	0xF0

/* Flags for I365_ADDRWIN */
#define I365_ENA_IO(map)	(0x40 << (map))
+16 −20
Original line number Diff line number Diff line
@@ -256,6 +256,7 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
{
	struct pcmcia_socket *s;
	config_t *c;
	int ret;

	s = p_dev->socket;

@@ -264,13 +265,13 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,

	if (!(s->state & SOCKET_PRESENT)) {
		dev_dbg(&s->dev, "No card present\n");
		mutex_unlock(&s->ops_mutex);
		return -ENODEV;
		ret = -ENODEV;
		goto unlock;
	}
	if (!(c->state & CONFIG_LOCKED)) {
		dev_dbg(&s->dev, "Configuration isnt't locked\n");
		mutex_unlock(&s->ops_mutex);
		return -EACCES;
		ret = -EACCES;
		goto unlock;
	}

	if (mod->Attributes & CONF_IRQ_CHANGE_VALID) {
@@ -286,7 +287,8 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,

	if (mod->Attributes & CONF_VCC_CHANGE_VALID) {
		dev_dbg(&s->dev, "changing Vcc is not allowed at this time\n");
		return -EINVAL;
		ret = -EINVAL;
		goto unlock;
	}

	/* We only allow changing Vpp1 and Vpp2 to the same value */
@@ -294,21 +296,21 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
	    (mod->Attributes & CONF_VPP2_CHANGE_VALID)) {
		if (mod->Vpp1 != mod->Vpp2) {
			dev_dbg(&s->dev, "Vpp1 and Vpp2 must be the same\n");
			mutex_unlock(&s->ops_mutex);
			return -EINVAL;
			ret = -EINVAL;
			goto unlock;
		}
		s->socket.Vpp = mod->Vpp1;
		if (s->ops->set_socket(s, &s->socket)) {
			mutex_unlock(&s->ops_mutex);
			dev_printk(KERN_WARNING, &s->dev,
				   "Unable to set VPP\n");
			return -EIO;
			ret = -EIO;
			goto unlock;
		}
	} else if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) ||
		   (mod->Attributes & CONF_VPP2_CHANGE_VALID)) {
		dev_dbg(&s->dev, "changing Vcc is not allowed at this time\n");
		mutex_unlock(&s->ops_mutex);
		return -EINVAL;
		ret = -EINVAL;
		goto unlock;
	}

	if (mod->Attributes & CONF_IO_CHANGE_WIDTH) {
@@ -332,9 +334,11 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
			s->ops->set_io_map(s, &io_on);
		}
	}
	ret = 0;
unlock:
	mutex_unlock(&s->ops_mutex);

	return 0;
	return ret;
} /* modify_configuration */
EXPORT_SYMBOL(pcmcia_modify_configuration);

@@ -752,14 +756,6 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)

#ifdef CONFIG_PCMCIA_PROBE

#ifdef IRQ_NOAUTOEN
	/* if the underlying IRQ infrastructure allows for it, only allocate
	 * the IRQ, but do not enable it
	 */
	if (!(req->Handler))
		type |= IRQ_NOAUTOEN;
#endif /* IRQ_NOAUTOEN */

	if (s->irq.AssignedIRQ != 0) {
		/* If the interrupt is already assigned, it must be the same */
		irq = s->irq.AssignedIRQ;
+1 −0
Original line number Diff line number Diff line
@@ -671,6 +671,7 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev,
		socket[i].socket.map_size = 0x1000;
		socket[i].socket.irq_mask = mask;
		socket[i].socket.pci_irq  = dev->irq;
		socket[i].socket.cb_dev = dev;
		socket[i].socket.owner = THIS_MODULE;

		socket[i].number = i;
+35 −2
Original line number Diff line number Diff line
@@ -296,7 +296,7 @@ static int ti_init(struct yenta_socket *socket)
	u8 new, reg = exca_readb(socket, I365_INTCTL);

	new = reg & ~I365_INTR_ENA;
	if (socket->cb_irq)
	if (socket->dev->irq)
		new |= I365_INTR_ENA;
	if (new != reg)
		exca_writeb(socket, I365_INTCTL, new);
@@ -316,14 +316,47 @@ static int ti_override(struct yenta_socket *socket)
	return 0;
}

static void ti113x_use_isa_irq(struct yenta_socket *socket)
{
	int isa_irq = -1;
	u8 intctl;
	u32 isa_irq_mask = 0;

	if (!isa_probe)
		return;

	/* get a free isa int */
	isa_irq_mask = yenta_probe_irq(socket, isa_interrupts);
	if (!isa_irq_mask)
		return; /* no useable isa irq found */

	/* choose highest available */
	for (; isa_irq_mask; isa_irq++)
		isa_irq_mask >>= 1;
	socket->cb_irq = isa_irq;

	exca_writeb(socket, I365_CSCINT, (isa_irq << 4));

	intctl = exca_readb(socket, I365_INTCTL);
	intctl &= ~(I365_INTR_ENA | I365_IRQ_MASK);     /* CSC Enable */
	exca_writeb(socket, I365_INTCTL, intctl);

	dev_info(&socket->dev->dev,
		"Yenta TI113x: using isa irq %d for CardBus\n", isa_irq);
}


static int ti113x_override(struct yenta_socket *socket)
{
	u8 cardctl;

	cardctl = config_readb(socket, TI113X_CARD_CONTROL);
	cardctl &= ~(TI113X_CCR_PCI_IRQ_ENA | TI113X_CCR_PCI_IREQ | TI113X_CCR_PCI_CSC);
	if (socket->cb_irq)
	if (socket->dev->irq)
		cardctl |= TI113X_CCR_PCI_IRQ_ENA | TI113X_CCR_PCI_CSC | TI113X_CCR_PCI_IREQ;
	else
		ti113x_use_isa_irq(socket);

	config_writeb(socket, TI113X_CARD_CONTROL, cardctl);

	return ti_override(socket);
Loading