static int __devinit serial_card_probe(struct expansion_card *ec, const struct ecard_id *id) { struct serial_card_info *info; struct serial_card_type *type = id->data; unsigned long bus_addr; unsigned char *virt_addr; unsigned int port; info = kmalloc(sizeof(struct serial_card_info), GFP_KERNEL); if (!info) return -ENOMEM; memset(info, 0, sizeof(struct serial_card_info)); info->num_ports = type->num_ports; ecard_set_drvdata(ec, info); bus_addr = ec->resource[type->type].start; virt_addr = ioremap(bus_addr, ec->resource[type->type].end - bus_addr + 1); if (!virt_addr) { kfree(info); return -ENOMEM; } for (port = 0; port < info->num_ports; port ++) { unsigned long baddr = bus_addr + type->offset[port]; unsigned char *vaddr = virt_addr + type->offset[port]; info->ports[port] = serial_register_onedev(baddr, vaddr, ec->irq, type->baud_base); } return 0; }
static int __init serial_card_init(void) { int card = 0; ecard_startfind (); do { struct expansion_card *ec; unsigned long cardaddr; int port; ec = ecard_find (0, serial_cids); if (!ec) break; cardaddr = MY_BASE_ADDRESS(ec); for (port = 0; port < MY_NUMPORTS; port ++) { unsigned long address; int line; address = MY_PORT_ADDRESS(port, cardaddr); line = serial_register_onedev (address, ec->irq); if (line < 0) break; serial_ports[serial_pcount] = line; serial_addr[serial_pcount] = address; serial_pcount += 1; } if (port) { ecard_claim (ec); expcard[card] = ec; } else break; } while (++card < MAX_ECARDS); return card ? 0 : -ENODEV; }