/* This is the function that scans the DIO space and works out what * hardware is actually present. */ static int __init dio_init(void) { int scode; struct dioboard *b, *bprev = NULL; printk("Scanning for DIO devices...\n"); for (scode = 0; scode < DIO_SCMAX; ++scode) { u_char prid, secid = 0; /* primary, secondary ID bytes */ u_char *va; if (DIO_SCINHOLE(scode)) continue; va = dio_scodetoviraddr(scode); if (!va || !hwreg_present(va + DIO_IDOFF)) continue; /* no board present at that select code */ /* Found a board, allocate it an entry in the list */ b = kmalloc(sizeof(struct dioboard), GFP_KERNEL); /* read the ID byte(s) and encode if necessary. Note workaround * for broken internal HPIB devices... */ if (!DIO_ISIHPIB(scode)) prid = DIO_ID(va); else prid = DIO_ID_IHPIB; if (DIO_NEEDSSECID(prid)) { secid = DIO_SECID(va); b->id = DIO_ENCODE_ID(prid, secid); } else b->id = prid; b->configured = 0; b->scode = scode; b->ipl = DIO_IPL(va); b->name = dio_getname(b->id); printk("select code %3d: ipl %d: ID %02X", scode, b->ipl, prid); if (DIO_NEEDSSECID(b->id)) printk(":%02X", secid); printk(": %s\n", b->name); b->next = NULL; if (bprev) bprev->next = b; else blist = b; bprev = b; } return 0; }
int __init dio_find(int deviceid) { /* Called to find a DIO device before the full bus scan has run. * Only used by the console driver. */ int scode, id; u_char prid, secid, i; mm_segment_t fs; for (scode = 0; scode < DIO_SCMAX; scode++) { void *va; unsigned long pa; if (DIO_SCINHOLE(scode)) continue; pa = dio_scodetophysaddr(scode); if (!pa) continue; if (scode < DIOII_SCBASE) va = (void *)(pa + DIO_VIRADDRBASE); else va = ioremap(pa, PAGE_SIZE); fs = get_fs(); set_fs(KERNEL_DS); if (get_user(i, (unsigned char *)va + DIO_IDOFF)) { set_fs(fs); if (scode >= DIOII_SCBASE) iounmap(va); continue; /* no board present at that select code */ } set_fs(fs); prid = DIO_ID(va); if (DIO_NEEDSSECID(prid)) { secid = DIO_SECID(va); id = DIO_ENCODE_ID(prid, secid); } else id = prid; if (id == deviceid) { if (scode >= DIOII_SCBASE) iounmap(va); return scode; } } return -1; }
int __init dio_find(int deviceid) { int scode, id; u_char prid, secid, i; mm_segment_t fs; for (scode = 0; scode < DIO_SCMAX; scode++) { void *va; unsigned long pa; if (DIO_SCINHOLE(scode)) continue; pa = dio_scodetophysaddr(scode); if (!pa) continue; if (scode < DIOII_SCBASE) va = (void *)(pa + DIO_VIRADDRBASE); else va = ioremap(pa, PAGE_SIZE); fs = get_fs(); set_fs(KERNEL_DS); if (get_user(i, (unsigned char *)va + DIO_IDOFF)) { set_fs(fs); if (scode >= DIOII_SCBASE) iounmap(va); continue; } set_fs(fs); prid = DIO_ID(va); if (DIO_NEEDSSECID(prid)) { secid = DIO_SECID(va); id = DIO_ENCODE_ID(prid, secid); } else id = prid; if (id == deviceid) { if (scode >= DIOII_SCBASE) iounmap(va); return scode; } } return -1; }
iounmap((void *)vaddr); return -ENOMEM; } return 0; } static void __devexit hpfb_remove_one(struct dio_dev *d) { unregister_framebuffer(&fb_info); if (d->scode >= DIOII_SCBASE) iounmap((void *)fb_regs); release_mem_region(d->resource.start, resource_size(&d->resource)); } static struct dio_device_id hpfb_dio_tbl[] = { { DIO_ENCODE_ID(DIO_ID_FBUFFER, DIO_ID2_LRCATSEYE) }, { DIO_ENCODE_ID(DIO_ID_FBUFFER, DIO_ID2_HRCCATSEYE) }, { DIO_ENCODE_ID(DIO_ID_FBUFFER, DIO_ID2_HRMCATSEYE) }, { DIO_ENCODE_ID(DIO_ID_FBUFFER, DIO_ID2_TOPCAT) }, { 0 } }; static struct dio_driver hpfb_driver = { .name = "hpfb", .id_table = hpfb_dio_tbl, .probe = hpfb_dio_probe, .remove = __devexit_p(hpfb_remove_one), }; int __init hpfb_init(void) {
/* This is the function that scans the DIO space and works out what * hardware is actually present. */ static int __init dio_init(void) { int scode; mm_segment_t fs; int i; struct dio_dev *dev; int error; if (!MACH_IS_HP300) return 0; printk(KERN_INFO "Scanning for DIO devices...\n"); /* Initialize the DIO bus */ INIT_LIST_HEAD(&dio_bus.devices); dev_set_name(&dio_bus.dev, "dio"); error = device_register(&dio_bus.dev); if (error) { pr_err("DIO: Error registering dio_bus\n"); return error; } /* Request all resources */ dio_bus.num_resources = (hp300_model == HP_320 ? 1 : 2); for (i = 0; i < dio_bus.num_resources; i++) request_resource(&iomem_resource, &dio_bus.resources[i]); /* Register all devices */ for (scode = 0; scode < DIO_SCMAX; ++scode) { u_char prid, secid = 0; /* primary, secondary ID bytes */ u_char *va; unsigned long pa; if (DIO_SCINHOLE(scode)) continue; pa = dio_scodetophysaddr(scode); if (!pa) continue; if (scode < DIOII_SCBASE) va = (void *)(pa + DIO_VIRADDRBASE); else va = ioremap(pa, PAGE_SIZE); fs = get_fs(); set_fs(KERNEL_DS); if (get_user(i, (unsigned char *)va + DIO_IDOFF)) { set_fs(fs); if (scode >= DIOII_SCBASE) iounmap(va); continue; /* no board present at that select code */ } set_fs(fs); /* Found a board, allocate it an entry in the list */ dev = kzalloc(sizeof(struct dio_dev), GFP_KERNEL); if (!dev) return 0; dev->bus = &dio_bus; dev->dev.parent = &dio_bus.dev; dev->dev.bus = &dio_bus_type; dev->scode = scode; dev->resource.start = pa; dev->resource.end = pa + DIO_SIZE(scode, va); dev_set_name(&dev->dev, "%02x", scode); /* read the ID byte(s) and encode if necessary. */ prid = DIO_ID(va); if (DIO_NEEDSSECID(prid)) { secid = DIO_SECID(va); dev->id = DIO_ENCODE_ID(prid, secid); } else dev->id = prid; dev->ipl = DIO_IPL(va); strcpy(dev->name,dio_getname(dev->id)); printk(KERN_INFO "select code %3d: ipl %d: ID %02X", dev->scode, dev->ipl, prid); if (DIO_NEEDSSECID(prid)) printk(":%02X", secid); printk(": %s\n", dev->name); if (scode >= DIOII_SCBASE) iounmap(va); error = device_register(&dev->dev); if (error) { pr_err("DIO: Error registering device %s\n", dev->name); continue; } error = dio_create_sysfs_dev_files(dev); if (error) dev_err(&dev->dev, "Error creating sysfs files\n"); } return 0; }