static int d7s_probe(struct platform_device *op) { struct device_node *opts; int err = -EINVAL; struct d7s *p; u8 regs; if (d7s_device) goto out; p = kzalloc(sizeof(*p), GFP_KERNEL); err = -ENOMEM; if (!p) goto out; p->regs = of_ioremap(&op->resource[0], 0, sizeof(u8), "d7s"); if (!p->regs) { printk(KERN_ERR PFX "Cannot map chip registers\n"); goto out_free; } err = misc_register(&d7s_miscdev); if (err) { printk(KERN_ERR PFX "Unable to acquire miscdevice minor %i\n", D7S_MINOR); goto out_iounmap; } /* OBP option "d7s-flipped?" is honored as default for the * device, and reset default when detached */ regs = readb(p->regs); opts = of_find_node_by_path("/options"); if (opts && of_get_property(opts, "d7s-flipped?", NULL)) p->flipped = true; if (p->flipped) regs |= D7S_FLIP; else regs &= ~D7S_FLIP; writeb(regs, p->regs); printk(KERN_INFO PFX "7-Segment Display%s at [%s:0x%llx] %s\n", op->dev.of_node->full_name, (regs & D7S_FLIP) ? " (FLIPPED)" : "", op->resource[0].start, sol_compat ? "in sol_compat mode" : ""); dev_set_drvdata(&op->dev, p); d7s_device = p; err = 0; out: return err; out_iounmap: of_iounmap(&op->resource[0], p->regs, sizeof(u8)); out_free: kfree(p); goto out; }
static int cg14_probe(struct platform_device *op) { struct device_node *dp = op->dev.of_node; struct fb_info *info; struct cg14_par *par; int is_8mb, linebytes, i, err; info = framebuffer_alloc(sizeof(struct cg14_par), &op->dev); err = -ENOMEM; if (!info) goto out_err; par = info->par; spin_lock_init(&par->lock); sbusfb_fill_var(&info->var, dp, 8); info->var.red.length = 8; info->var.green.length = 8; info->var.blue.length = 8; linebytes = of_getintprop_default(dp, "linebytes", info->var.xres); info->fix.smem_len = PAGE_ALIGN(linebytes * info->var.yres); if (!strcmp(dp->parent->name, "sbus") || !strcmp(dp->parent->name, "sbi")) { info->fix.smem_start = op->resource[0].start; par->iospace = op->resource[0].flags & IORESOURCE_BITS; } else { info->fix.smem_start = op->resource[1].start; par->iospace = op->resource[0].flags & IORESOURCE_BITS; } par->regs = of_ioremap(&op->resource[0], 0, sizeof(struct cg14_regs), "cg14 regs"); par->clut = of_ioremap(&op->resource[0], CG14_CLUT1, sizeof(struct cg14_clut), "cg14 clut"); par->cursor = of_ioremap(&op->resource[0], CG14_CURSORREGS, sizeof(struct cg14_cursor), "cg14 cursor"); info->screen_base = of_ioremap(&op->resource[1], 0, info->fix.smem_len, "cg14 ram"); if (!par->regs || !par->clut || !par->cursor || !info->screen_base) goto out_unmap_regs; is_8mb = (((op->resource[1].end - op->resource[1].start) + 1) == (8 * 1024 * 1024)); BUILD_BUG_ON(sizeof(par->mmap_map) != sizeof(__cg14_mmap_map)); memcpy(&par->mmap_map, &__cg14_mmap_map, sizeof(par->mmap_map)); for (i = 0; i < CG14_MMAP_ENTRIES; i++) { struct sbus_mmap_map *map = &par->mmap_map[i]; if (!map->size) break; if (map->poff & 0x80000000) map->poff = (map->poff & 0x7fffffff) + (op->resource[0].start - op->resource[1].start); if (is_8mb && map->size >= 0x100000 && map->size <= 0x400000) map->size *= 2; } par->mode = MDI_8_PIX; par->ramsize = (is_8mb ? 0x800000 : 0x400000); info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; info->fbops = &cg14_ops; __cg14_reset(par); if (fb_alloc_cmap(&info->cmap, 256, 0)) goto out_unmap_regs; fb_set_cmap(&info->cmap, info); cg14_init_fix(info, linebytes, dp); err = register_framebuffer(info); if (err < 0) goto out_dealloc_cmap; dev_set_drvdata(&op->dev, info); printk(KERN_INFO "%s: cgfourteen at %lx:%lx, %dMB\n", dp->full_name, par->iospace, info->fix.smem_start, par->ramsize >> 20); return 0; out_dealloc_cmap: fb_dealloc_cmap(&info->cmap); out_unmap_regs: cg14_unmap_regs(op, info, par); framebuffer_release(info); out_err: return err; }
static int __devinit bw2_probe(struct of_device *op, const struct of_device_id *match) { struct device_node *dp = op->dev.of_node; struct fb_info *info; struct bw2_par *par; int linebytes, err; info = framebuffer_alloc(sizeof(struct bw2_par), &op->dev); err = -ENOMEM; if (!info) goto out_err; par = info->par; spin_lock_init(&par->lock); info->fix.smem_start = op->resource[0].start; par->which_io = op->resource[0].flags & IORESOURCE_BITS; sbusfb_fill_var(&info->var, dp, 1); linebytes = of_getintprop_default(dp, "linebytes", info->var.xres); info->var.red.length = info->var.green.length = info->var.blue.length = info->var.bits_per_pixel; info->var.red.offset = info->var.green.offset = info->var.blue.offset = 0; par->regs = of_ioremap(&op->resource[0], BWTWO_REGISTER_OFFSET, sizeof(struct bw2_regs), "bw2 regs"); if (!par->regs) goto out_release_fb; if (!of_find_property(dp, "width", NULL)) { err = bw2_do_default_mode(par, info, &linebytes); if (err) goto out_unmap_regs; } info->fix.smem_len = PAGE_ALIGN(linebytes * info->var.yres); info->flags = FBINFO_DEFAULT; info->fbops = &bw2_ops; info->screen_base = of_ioremap(&op->resource[0], 0, info->fix.smem_len, "bw2 ram"); if (!info->screen_base) goto out_unmap_regs; bw2_blank(FB_BLANK_UNBLANK, info); bw2_init_fix(info, linebytes); err = register_framebuffer(info); if (err < 0) goto out_unmap_screen; dev_set_drvdata(&op->dev, info); printk(KERN_INFO "%s: bwtwo at %lx:%lx\n", dp->full_name, par->which_io, info->fix.smem_start); return 0; out_unmap_screen: of_iounmap(&op->resource[0], info->screen_base, info->fix.smem_len); out_unmap_regs: of_iounmap(&op->resource[0], par->regs, sizeof(struct bw2_regs)); out_release_fb: framebuffer_release(info); out_err: return err; }
static struct bbc_i2c_bus * __init attach_one_i2c(struct platform_device *op, int index) { struct bbc_i2c_bus *bp; struct device_node *dp; int entry; bp = kzalloc(sizeof(*bp), GFP_KERNEL); if (!bp) return NULL; INIT_LIST_HEAD(&bp->temps); INIT_LIST_HEAD(&bp->fans); bp->i2c_control_regs = of_ioremap(&op->resource[0], 0, 0x2, "bbc_i2c_regs"); if (!bp->i2c_control_regs) goto fail; if (op->num_resources == 2) { bp->i2c_bussel_reg = of_ioremap(&op->resource[1], 0, 0x1, "bbc_i2c_bussel"); if (!bp->i2c_bussel_reg) goto fail; } bp->waiting = 0; init_waitqueue_head(&bp->wq); if (request_irq(op->archdata.irqs[0], bbc_i2c_interrupt, IRQF_SHARED, "bbc_i2c", bp)) goto fail; bp->index = index; bp->op = op; spin_lock_init(&bp->lock); entry = 0; for (dp = op->dev.of_node->child; dp && entry < 8; dp = dp->sibling, entry++) { struct platform_device *child_op; child_op = of_find_device_by_node(dp); bp->devs[entry].device = child_op; bp->devs[entry].client_claimed = 0; } writeb(I2C_PCF_PIN, bp->i2c_control_regs + 0x0); bp->own = readb(bp->i2c_control_regs + 0x01); writeb(I2C_PCF_PIN | I2C_PCF_ES1, bp->i2c_control_regs + 0x0); bp->clock = readb(bp->i2c_control_regs + 0x01); printk(KERN_INFO "i2c-%d: Regs at %p, %d devices, own %02x, clock %02x.\n", bp->index, bp->i2c_control_regs, entry, bp->own, bp->clock); reset_one_i2c(bp); return bp; fail: if (bp->i2c_bussel_reg) of_iounmap(&op->resource[1], bp->i2c_bussel_reg, 1); if (bp->i2c_control_regs) of_iounmap(&op->resource[0], bp->i2c_control_regs, 2); kfree(bp); return NULL; }
static int __devinit tcx_probe(struct of_device *op, const struct of_device_id *match) { struct device_node *dp = op->node; struct fb_info *info; struct tcx_par *par; int linebytes, i, err; info = framebuffer_alloc(sizeof(struct tcx_par), &op->dev); err = -ENOMEM; if (!info) goto out_err; par = info->par; spin_lock_init(&par->lock); par->lowdepth = (of_find_property(dp, "tcx-8-bit", NULL) != NULL); sbusfb_fill_var(&info->var, dp, 8); info->var.red.length = 8; info->var.green.length = 8; info->var.blue.length = 8; linebytes = of_getintprop_default(dp, "linebytes", info->var.xres); info->fix.smem_len = PAGE_ALIGN(linebytes * info->var.yres); par->tec = of_ioremap(&op->resource[7], 0, sizeof(struct tcx_tec), "tcx tec"); par->thc = of_ioremap(&op->resource[9], 0, sizeof(struct tcx_thc), "tcx thc"); par->bt = of_ioremap(&op->resource[8], 0, sizeof(struct bt_regs), "tcx dac"); info->screen_base = of_ioremap(&op->resource[0], 0, info->fix.smem_len, "tcx ram"); if (!par->tec || !par->thc || !par->bt || !info->screen_base) goto out_unmap_regs; memcpy(&par->mmap_map, &__tcx_mmap_map, sizeof(par->mmap_map)); if (!par->lowdepth) { par->cplane = of_ioremap(&op->resource[4], 0, info->fix.smem_len * sizeof(u32), "tcx cplane"); if (!par->cplane) goto out_unmap_regs; } else { par->mmap_map[1].size = SBUS_MMAP_EMPTY; par->mmap_map[4].size = SBUS_MMAP_EMPTY; par->mmap_map[5].size = SBUS_MMAP_EMPTY; par->mmap_map[6].size = SBUS_MMAP_EMPTY; } info->fix.smem_start = op->resource[0].start; par->which_io = op->resource[0].flags & IORESOURCE_BITS; for (i = 0; i < TCX_MMAP_ENTRIES; i++) { int j; switch (i) { case 10: j = 12; break; case 11: case 12: j = i - 1; break; default: j = i; break; }; par->mmap_map[i].poff = op->resource[j].start; } info->flags = FBINFO_DEFAULT; info->fbops = &tcx_ops; /* Initialize brooktree DAC. */ sbus_writel(0x04 << 24, &par->bt->addr); /* color planes */ sbus_writel(0xff << 24, &par->bt->control); sbus_writel(0x05 << 24, &par->bt->addr); sbus_writel(0x00 << 24, &par->bt->control); sbus_writel(0x06 << 24, &par->bt->addr); /* overlay plane */ sbus_writel(0x73 << 24, &par->bt->control); sbus_writel(0x07 << 24, &par->bt->addr); sbus_writel(0x00 << 24, &par->bt->control); tcx_reset(info); tcx_blank(FB_BLANK_UNBLANK, info); if (fb_alloc_cmap(&info->cmap, 256, 0)) goto out_unmap_regs; fb_set_cmap(&info->cmap, info); tcx_init_fix(info, linebytes); err = register_framebuffer(info); if (err < 0) goto out_dealloc_cmap; dev_set_drvdata(&op->dev, info); printk(KERN_INFO "%s: TCX at %lx:%lx, %s\n", dp->full_name, par->which_io, info->fix.smem_start, par->lowdepth ? "8-bit only" : "24-bit depth"); return 0; out_dealloc_cmap: fb_dealloc_cmap(&info->cmap); out_unmap_regs: tcx_unmap_regs(op, info, par); out_err: return err; }
static int __devinit bpp_probe(struct platform_device *op) { struct parport_operations *ops; struct bpp_regs __iomem *regs; int irq, dma, err = 0, size; unsigned char value_tcr; void __iomem *base; struct parport *p; irq = op->archdata.irqs[0]; base = of_ioremap(&op->resource[0], 0, resource_size(&op->resource[0]), "sunbpp"); if (!base) return -ENODEV; size = resource_size(&op->resource[0]); dma = PARPORT_DMA_NONE; ops = kmalloc(sizeof(struct parport_operations), GFP_KERNEL); if (!ops) goto out_unmap; memcpy (ops, &parport_sunbpp_ops, sizeof(struct parport_operations)); dprintk(("register_port\n")); if (!(p = parport_register_port((unsigned long)base, irq, dma, ops))) goto out_free_ops; p->size = size; p->dev = &op->dev; if ((err = request_irq(p->irq, parport_irq_handler, IRQF_SHARED, p->name, p)) != 0) { goto out_put_port; } parport_sunbpp_enable_irq(p); regs = (struct bpp_regs __iomem *)p->base; value_tcr = sbus_readb(®s->p_tcr); value_tcr &= ~P_TCR_DIR; sbus_writeb(value_tcr, ®s->p_tcr); printk(KERN_INFO "%s: sunbpp at 0x%lx\n", p->name, p->base); dev_set_drvdata(&op->dev, p); parport_announce_port(p); return 0; out_put_port: parport_put_port(p); out_free_ops: kfree(ops); out_unmap: of_iounmap(&op->resource[0], base, size); return err; }
static int __devinit myri_sbus_probe(struct of_device *op, const struct of_device_id *match) { struct device_node *dp = op->node; static unsigned version_printed; struct net_device *dev; DECLARE_MAC_BUF(mac); struct myri_eth *mp; const void *prop; static int num; int i, len; DET(("myri_ether_init(%p,%d):\n", op, num)); dev = alloc_etherdev(sizeof(struct myri_eth)); if (!dev) return -ENOMEM; if (version_printed++ == 0) printk(version); SET_NETDEV_DEV(dev, &op->dev); mp = netdev_priv(dev); spin_lock_init(&mp->irq_lock); mp->myri_op = op; /* Clean out skb arrays. */ for (i = 0; i < (RX_RING_SIZE + 1); i++) mp->rx_skbs[i] = NULL; for (i = 0; i < TX_RING_SIZE; i++) mp->tx_skbs[i] = NULL; /* First check for EEPROM information. */ prop = of_get_property(dp, "myrinet-eeprom-info", &len); if (prop) memcpy(&mp->eeprom, prop, sizeof(struct myri_eeprom)); if (!prop) { /* No eeprom property, must cook up the values ourselves. */ DET(("No EEPROM: ")); mp->eeprom.bus_type = BUS_TYPE_SBUS; mp->eeprom.cpuvers = of_getintprop_default(dp, "cpu_version", 0); mp->eeprom.cval = of_getintprop_default(dp, "clock_value", 0); mp->eeprom.ramsz = of_getintprop_default(dp, "sram_size", 0); if (!mp->eeprom.cpuvers) mp->eeprom.cpuvers = CPUVERS_2_3; if (mp->eeprom.cpuvers < CPUVERS_3_0) mp->eeprom.cval = 0; if (!mp->eeprom.ramsz) mp->eeprom.ramsz = (128 * 1024); prop = of_get_property(dp, "myrinet-board-id", &len); if (prop) memcpy(&mp->eeprom.id[0], prop, 6); else set_boardid_from_idprom(mp, num); prop = of_get_property(dp, "fpga_version", &len); if (prop) memcpy(&mp->eeprom.fvers[0], prop, 32); else memset(&mp->eeprom.fvers[0], 0, 32); if (mp->eeprom.cpuvers == CPUVERS_4_1) { if (mp->eeprom.ramsz == (128 * 1024)) mp->eeprom.ramsz = (256 * 1024); if ((mp->eeprom.cval == 0x40414041) || (mp->eeprom.cval == 0x90449044)) mp->eeprom.cval = 0x50e450e4; } } #ifdef DEBUG_DETECT dump_eeprom(mp); #endif for (i = 0; i < 6; i++) dev->dev_addr[i] = mp->eeprom.id[i]; determine_reg_space_size(mp); /* Map in the MyriCOM register/localram set. */ if (mp->eeprom.cpuvers < CPUVERS_4_0) { /* XXX Makes no sense, if control reg is non-existant this * XXX driver cannot function at all... maybe pre-4.0 is * XXX only a valid version for PCI cards? Ask feldy... */ DET(("Mapping regs for cpuvers < CPUVERS_4_0\n")); mp->regs = of_ioremap(&op->resource[0], 0, mp->reg_size, "MyriCOM Regs"); if (!mp->regs) { printk("MyriCOM: Cannot map MyriCOM registers.\n"); goto err; } mp->lanai = mp->regs + (256 * 1024); mp->lregs = mp->lanai + (0x10000 * 2); } else { DET(("Mapping regs for cpuvers >= CPUVERS_4_0\n")); mp->cregs = of_ioremap(&op->resource[0], 0, PAGE_SIZE, "MyriCOM Control Regs"); mp->lregs = of_ioremap(&op->resource[0], (256 * 1024), PAGE_SIZE, "MyriCOM LANAI Regs"); mp->lanai = of_ioremap(&op->resource[0], (512 * 1024), mp->eeprom.ramsz, "MyriCOM SRAM"); } DET(("Registers mapped: cregs[%p] lregs[%p] lanai[%p]\n", mp->cregs, mp->lregs, mp->lanai)); if (mp->eeprom.cpuvers >= CPUVERS_4_0) mp->shmem_base = 0xf000; else mp->shmem_base = 0x8000; DET(("Shared memory base is %04x, ", mp->shmem_base)); mp->shmem = (struct myri_shmem __iomem *) (mp->lanai + (mp->shmem_base * 2)); DET(("shmem mapped at %p\n", mp->shmem)); mp->rqack = &mp->shmem->channel.recvqa; mp->rq = &mp->shmem->channel.recvq; mp->sq = &mp->shmem->channel.sendq; /* Reset the board. */ DET(("Resetting LANAI\n")); myri_reset_off(mp->lregs, mp->cregs); myri_reset_on(mp->cregs); /* Turn IRQ's off. */ myri_disable_irq(mp->lregs, mp->cregs); /* Reset once more. */ myri_reset_on(mp->cregs); /* Get the supported DVMA burst sizes from our SBUS. */ mp->myri_bursts = of_getintprop_default(dp->parent, "burst-sizes", 0x00); if (!sbus_can_burst64()) mp->myri_bursts &= ~(DMA_BURST64); DET(("MYRI bursts %02x\n", mp->myri_bursts)); /* Encode SBUS interrupt level in second control register. */ i = of_getintprop_default(dp, "interrupts", 0); if (i == 0) i = 4; DET(("prom_getint(interrupts)==%d, irqlvl set to %04x\n", i, (1 << i))); sbus_writel((1 << i), mp->cregs + MYRICTRL_IRQLVL); mp->dev = dev; dev->open = &myri_open; dev->stop = &myri_close; dev->hard_start_xmit = &myri_start_xmit; dev->tx_timeout = &myri_tx_timeout; dev->watchdog_timeo = 5*HZ; dev->set_multicast_list = &myri_set_multicast; dev->irq = op->irqs[0]; /* Register interrupt handler now. */ DET(("Requesting MYRIcom IRQ line.\n")); if (request_irq(dev->irq, &myri_interrupt, IRQF_SHARED, "MyriCOM Ethernet", (void *) dev)) { printk("MyriCOM: Cannot register interrupt handler.\n"); goto err; } dev->mtu = MYRINET_MTU; dev->change_mtu = myri_change_mtu; dev->header_ops = &myri_header_ops; dev->hard_header_len = (ETH_HLEN + MYRI_PAD_LEN); /* Load code onto the LANai. */ DET(("Loading LANAI firmware\n")); myri_load_lanai(mp); if (register_netdev(dev)) { printk("MyriCOM: Cannot register device.\n"); goto err_free_irq; } dev_set_drvdata(&op->dev, mp); num++; printk("%s: MyriCOM MyriNET Ethernet %s\n", dev->name, print_mac(mac, dev->dev_addr)); return 0; err_free_irq: free_irq(dev->irq, dev); err: /* This will also free the co-allocated 'dev->priv' */ free_netdev(dev); return -ENODEV; }
static int __devinit envctrl_probe(struct of_device *op, const struct of_device_id *match) { struct device_node *dp; int index, err; if (i2c) return -EINVAL; i2c = of_ioremap(&op->resource[0], 0, 0x2, DRIVER_NAME); if (!i2c) return -ENOMEM; index = 0; dp = op->node->child; while (dp) { if (!strcmp(dp->name, "gpio")) { i2c_childlist[index].i2ctype = I2C_GPIO; envctrl_init_i2c_child(dp, &(i2c_childlist[index++])); } else if (!strcmp(dp->name, "adc")) { i2c_childlist[index].i2ctype = I2C_ADC; envctrl_init_i2c_child(dp, &(i2c_childlist[index++])); } dp = dp->sibling; } /* Set device address. */ writeb(CONTROL_PIN, i2c + PCF8584_CSR); writeb(PCF8584_ADDRESS, i2c + PCF8584_DATA); /* Set system clock and SCL frequencies. */ writeb(CONTROL_PIN | CONTROL_ES1, i2c + PCF8584_CSR); writeb(CLK_4_43 | BUS_CLK_90, i2c + PCF8584_DATA); /* Enable serial interface. */ writeb(CONTROL_PIN | CONTROL_ES0 | CONTROL_ACK, i2c + PCF8584_CSR); udelay(200); /* Register the device as a minor miscellaneous device. */ err = misc_register(&envctrl_dev); if (err) { printk(KERN_ERR PFX "Unable to get misc minor %d\n", envctrl_dev.minor); goto out_iounmap; } /* Note above traversal routine post-incremented 'i' to accommodate * a next child device, so we decrement before reverse-traversal of * child devices. */ printk(KERN_INFO PFX "Initialized "); for (--index; index >= 0; --index) { printk("[%s 0x%lx]%s", (I2C_ADC == i2c_childlist[index].i2ctype) ? "adc" : ((I2C_GPIO == i2c_childlist[index].i2ctype) ? "gpio" : "unknown"), i2c_childlist[index].addr, (0 == index) ? "\n" : " "); } kenvctrld_task = kthread_run(kenvctrld, NULL, "kenvctrld"); if (IS_ERR(kenvctrld_task)) { err = PTR_ERR(kenvctrld_task); goto out_deregister; } return 0; out_deregister: misc_deregister(&envctrl_dev); out_iounmap: of_iounmap(&op->resource[0], i2c, 0x2); for (index = 0; index < ENVCTRL_MAX_CPU * 2; index++) kfree(i2c_childlist[index].tables); return err; }
static int __devinit leo_probe(struct platform_device *op) { struct device_node *dp = op->dev.of_node; struct fb_info *info; struct leo_par *par; int linebytes, err; info = framebuffer_alloc(sizeof(struct leo_par), &op->dev); err = -ENOMEM; if (!info) goto out_err; par = info->par; spin_lock_init(&par->lock); info->fix.smem_start = op->resource[0].start; par->which_io = op->resource[0].flags & IORESOURCE_BITS; sbusfb_fill_var(&info->var, dp, 32); leo_fixup_var_rgb(&info->var); linebytes = of_getintprop_default(dp, "linebytes", info->var.xres); info->fix.smem_len = PAGE_ALIGN(linebytes * info->var.yres); par->lc_ss0_usr = of_ioremap(&op->resource[0], LEO_OFF_LC_SS0_USR, 0x1000, "leolc ss0usr"); par->ld_ss0 = of_ioremap(&op->resource[0], LEO_OFF_LD_SS0, 0x1000, "leold ss0"); par->ld_ss1 = of_ioremap(&op->resource[0], LEO_OFF_LD_SS1, 0x1000, "leold ss1"); par->lx_krn = of_ioremap(&op->resource[0], LEO_OFF_LX_KRN, 0x1000, "leolx krn"); par->cursor = of_ioremap(&op->resource[0], LEO_OFF_LX_CURSOR, sizeof(struct leo_cursor), "leolx cursor"); info->screen_base = of_ioremap(&op->resource[0], LEO_OFF_SS0, 0x800000, "leo ram"); if (!par->lc_ss0_usr || !par->ld_ss0 || !par->ld_ss1 || !par->lx_krn || !par->cursor || !info->screen_base) goto out_unmap_regs; info->flags = FBINFO_DEFAULT; info->fbops = &leo_ops; info->pseudo_palette = par->clut_data; leo_init_wids(info); leo_init_hw(info); leo_blank(FB_BLANK_UNBLANK, info); if (fb_alloc_cmap(&info->cmap, 256, 0)) goto out_unmap_regs; leo_init_fix(info, dp); err = register_framebuffer(info); if (err < 0) goto out_dealloc_cmap; dev_set_drvdata(&op->dev, info); printk(KERN_INFO "%s: leo at %lx:%lx\n", dp->full_name, par->which_io, info->fix.smem_start); return 0; out_dealloc_cmap: fb_dealloc_cmap(&info->cmap); out_unmap_regs: leo_unmap_regs(op, info, par); framebuffer_release(info); out_err: return err; }
static int __devinit cg14_init_one(struct of_device *op) { struct device_node *dp = op->node; struct all_info *all; int is_8mb, linebytes, i, err; all = kzalloc(sizeof(*all), GFP_KERNEL); if (!all) return -ENOMEM; spin_lock_init(&all->par.lock); sbusfb_fill_var(&all->info.var, dp->node, 8); all->info.var.red.length = 8; all->info.var.green.length = 8; all->info.var.blue.length = 8; linebytes = of_getintprop_default(dp, "linebytes", all->info.var.xres); all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres); if (!strcmp(dp->parent->name, "sbus") || !strcmp(dp->parent->name, "sbi")) { all->par.physbase = op->resource[0].start; all->par.iospace = op->resource[0].flags & IORESOURCE_BITS; } else { all->par.physbase = op->resource[1].start; all->par.iospace = op->resource[0].flags & IORESOURCE_BITS; } all->par.regs = of_ioremap(&op->resource[0], 0, sizeof(struct cg14_regs), "cg14 regs"); all->par.clut = of_ioremap(&op->resource[0], CG14_CLUT1, sizeof(struct cg14_clut), "cg14 clut"); all->par.cursor = of_ioremap(&op->resource[0], CG14_CURSORREGS, sizeof(struct cg14_cursor), "cg14 cursor"); all->info.screen_base = of_ioremap(&op->resource[1], 0, all->par.fbsize, "cg14 ram"); if (!all->par.regs || !all->par.clut || !all->par.cursor || !all->info.screen_base) cg14_unmap_regs(all); is_8mb = (((op->resource[1].end - op->resource[1].start) + 1) == (8 * 1024 * 1024)); BUILD_BUG_ON(sizeof(all->par.mmap_map) != sizeof(__cg14_mmap_map)); memcpy(&all->par.mmap_map, &__cg14_mmap_map, sizeof(all->par.mmap_map)); for (i = 0; i < CG14_MMAP_ENTRIES; i++) { struct sbus_mmap_map *map = &all->par.mmap_map[i]; if (!map->size) break; if (map->poff & 0x80000000) map->poff = (map->poff & 0x7fffffff) + (op->resource[0].start - op->resource[1].start); if (is_8mb && map->size >= 0x100000 && map->size <= 0x400000) map->size *= 2; } all->par.mode = MDI_8_PIX; all->par.ramsize = (is_8mb ? 0x800000 : 0x400000); all->info.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; all->info.fbops = &cg14_ops; all->info.par = &all->par; __cg14_reset(&all->par); if (fb_alloc_cmap(&all->info.cmap, 256, 0)) { cg14_unmap_regs(all); kfree(all); return -ENOMEM; } fb_set_cmap(&all->info.cmap, &all->info); cg14_init_fix(&all->info, linebytes, dp); err = register_framebuffer(&all->info); if (err < 0) { fb_dealloc_cmap(&all->info.cmap); cg14_unmap_regs(all); kfree(all); return err; } dev_set_drvdata(&op->dev, all); printk("%s: cgfourteen at %lx:%lx, %dMB\n", dp->full_name, all->par.iospace, all->par.physbase, all->par.ramsize >> 20); return 0; }