in xxs1500_ss.c [209:302]
static int xxs1500_pcmcia_probe(struct platform_device *pdev)
{
struct xxs1500_pcmcia_sock *sock;
struct resource *r;
int ret, irq;
sock = kzalloc(sizeof(struct xxs1500_pcmcia_sock), GFP_KERNEL);
if (!sock)
return -ENOMEM;
ret = -ENODEV;
/* 36bit PCMCIA Attribute area address */
r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pcmcia-attr");
if (!r) {
dev_err(&pdev->dev, "missing 'pcmcia-attr' resource!\n");
goto out0;
}
sock->phys_attr = r->start;
/* 36bit PCMCIA Memory area address */
r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pcmcia-mem");
if (!r) {
dev_err(&pdev->dev, "missing 'pcmcia-mem' resource!\n");
goto out0;
}
sock->phys_mem = r->start;
/* 36bit PCMCIA IO area address */
r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pcmcia-io");
if (!r) {
dev_err(&pdev->dev, "missing 'pcmcia-io' resource!\n");
goto out0;
}
sock->phys_io = r->start;
/*
* PCMCIA client drivers use the inb/outb macros to access
* the IO registers. Since mips_io_port_base is added
* to the access address of the mips implementation of
* inb/outb, we need to subtract it here because we want
* to access the I/O or MEM address directly, without
* going through this "mips_io_port_base" mechanism.
*/
sock->virt_io = (void *)(ioremap(sock->phys_io, IO_MAP_SIZE) -
mips_io_port_base);
if (!sock->virt_io) {
dev_err(&pdev->dev, "cannot remap IO area\n");
ret = -ENOMEM;
goto out0;
}
sock->socket.ops = &xxs1500_pcmcia_operations;
sock->socket.owner = THIS_MODULE;
sock->socket.pci_irq = gpio_to_irq(GPIO_CARDIRQ);
sock->socket.features = SS_CAP_STATIC_MAP | SS_CAP_PCCARD;
sock->socket.map_size = MEM_MAP_SIZE;
sock->socket.io_offset = (unsigned long)sock->virt_io;
sock->socket.dev.parent = &pdev->dev;
sock->socket.resource_ops = &pccard_static_ops;
platform_set_drvdata(pdev, sock);
/* setup carddetect irq: use one of the 2 GPIOs as an
* edge detector.
*/
irq = gpio_to_irq(GPIO_CDA);
irq_set_irq_type(irq, IRQ_TYPE_EDGE_BOTH);
ret = request_irq(irq, cdirq, 0, "pcmcia_carddetect", sock);
if (ret) {
dev_err(&pdev->dev, "cannot setup cd irq\n");
goto out1;
}
ret = pcmcia_register_socket(&sock->socket);
if (ret) {
dev_err(&pdev->dev, "failed to register\n");
goto out2;
}
printk(KERN_INFO "MyCable XXS1500 PCMCIA socket services\n");
return 0;
out2:
free_irq(gpio_to_irq(GPIO_CDA), sock);
out1:
iounmap((void *)(sock->virt_io + (u32)mips_io_port_base));
out0:
kfree(sock);
return ret;
}