static int ohci_hcd_sm501_drv_remove(struct platform_device *pdev) { struct usb_hcd *hcd = platform_get_drvdata(pdev); struct resource *mem; usb_remove_hcd(hcd); release_mem_region(hcd->rsrc_start, hcd->rsrc_len); usb_put_hcd(hcd); dma_release_declared_memory(&pdev->dev); mem = platform_get_resource(pdev, IORESOURCE_MEM, 1); if (mem) release_mem_region(mem->start, resource_size(mem)); /* mask interrupts and disable power */ sm501_modify_reg(pdev->dev.parent, SM501_IRQ_MASK, 0, 1 << 6); sm501_unit_power(pdev->dev.parent, SM501_GATE_USB_HOST, 0); return 0; }
static int ohci_hcd_sm501_drv_probe(struct platform_device *pdev) { const struct hc_driver *driver = &ohci_sm501_hc_driver; struct device *dev = &pdev->dev; struct resource *res, *mem; int retval, irq; struct usb_hcd *hcd = NULL; irq = retval = platform_get_irq(pdev, 0); if (retval < 0) goto err0; mem = platform_get_resource(pdev, IORESOURCE_MEM, 1); if (mem == NULL) { dev_err(dev, "no resource definition for memory\n"); retval = -ENOENT; goto err0; } if (!request_mem_region(mem->start, resource_size(mem), pdev->name)) { dev_err(dev, "request_mem_region failed\n"); retval = -EBUSY; goto err0; } /* The sm501 chip is equipped with local memory that may be used * by on-chip devices such as the video controller and the usb host. * This driver uses dma_declare_coherent_memory() to make sure * usb allocations with dma_alloc_coherent() allocate from * this local memory. The dma_handle returned by dma_alloc_coherent() * will be an offset starting from 0 for the first local memory byte. * * So as long as data is allocated using dma_alloc_coherent() all is * fine. This is however not always the case - buffers may be allocated * using kmalloc() - so the usb core needs to be told that it must copy * data into our local memory if the buffers happen to be placed in * regular memory. The HCD_LOCAL_MEM flag does just that. */ if (!dma_declare_coherent_memory(dev, mem->start, mem->start - mem->parent->start, resource_size(mem), DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE)) { dev_err(dev, "cannot declare coherent memory\n"); retval = -ENXIO; goto err1; } /* allocate, reserve and remap resources for registers */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) { dev_err(dev, "no resource definition for registers\n"); retval = -ENOENT; goto err2; } hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev)); if (!hcd) { retval = -ENOMEM; goto err2; } hcd->rsrc_start = res->start; hcd->rsrc_len = resource_size(res); if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, pdev->name)) { dev_err(dev, "request_mem_region failed\n"); retval = -EBUSY; goto err3; } hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); if (hcd->regs == NULL) { dev_err(dev, "cannot remap registers\n"); retval = -ENXIO; goto err4; } ohci_hcd_init(hcd_to_ohci(hcd)); retval = usb_add_hcd(hcd, irq, IRQF_SHARED); if (retval) goto err5; /* enable power and unmask interrupts */ sm501_unit_power(dev->parent, SM501_GATE_USB_HOST, 1); sm501_modify_reg(dev->parent, SM501_IRQ_MASK, 1 << 6, 0); return 0; err5: iounmap(hcd->regs); err4: release_mem_region(hcd->rsrc_start, hcd->rsrc_len); err3: usb_put_hcd(hcd); err2: dma_release_declared_memory(dev); err1: release_mem_region(mem->start, resource_size(mem)); err0: return retval; }
static int ohci_hcd_sm501_drv_probe(struct platform_device *pdev) { const struct hc_driver *driver = &ohci_sm501_hc_driver; struct device *dev = &pdev->dev; struct resource *res, *mem; int retval, irq; struct usb_hcd *hcd = NULL; irq = retval = platform_get_irq(pdev, 0); if (retval < 0) goto err0; mem = platform_get_resource(pdev, IORESOURCE_MEM, 1); if (mem == NULL) { dev_err(dev, "no resource definition for memory\n"); retval = -ENOENT; goto err0; } if (!request_mem_region(mem->start, mem->end - mem->start + 1, pdev->name)) { dev_err(dev, "request_mem_region failed\n"); retval = -EBUSY; goto err0; } if (!dma_declare_coherent_memory(dev, mem->start, mem->start - mem->parent->start, (mem->end - mem->start) + 1, DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE)) { dev_err(dev, "cannot declare coherent memory\n"); retval = -ENXIO; goto err1; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) { dev_err(dev, "no resource definition for registers\n"); retval = -ENOENT; goto err2; } hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev)); if (!hcd) { retval = -ENOMEM; goto err2; } hcd->rsrc_start = res->start; hcd->rsrc_len = res->end - res->start + 1; if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, pdev->name)) { dev_err(dev, "request_mem_region failed\n"); retval = -EBUSY; goto err3; } hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); if (hcd->regs == NULL) { dev_err(dev, "cannot remap registers\n"); retval = -ENXIO; goto err4; } ohci_hcd_init(hcd_to_ohci(hcd)); retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); if (retval) goto err4; sm501_unit_power(dev->parent, SM501_GATE_USB_HOST, 1); sm501_modify_reg(dev->parent, SM501_IRQ_MASK, 1 << 6, 0); return 0; err4: release_mem_region(hcd->rsrc_start, hcd->rsrc_len); err3: usb_put_hcd(hcd); err2: dma_release_declared_memory(dev); err1: release_mem_region(mem->start, mem->end - mem->start + 1); err0: return retval; }
static int sm501fb_set_par_pnl(struct fb_info *info) { struct sm501fb_par *par = info->par; struct sm501fb_info *fbi = par->info; struct fb_var_screeninfo *var = &info->var; unsigned long control; unsigned long reg; int ret; dev_dbg(fbi->dev, "%s(%p)\n", __func__, info); /* activate this new configuration */ ret = sm501fb_set_par_common(info, var); if (ret) return ret; sm501fb_pan_pnl(var, info); sm501fb_set_par_geometry(info, var); /* update control register */ control = readl(fbi->regs + SM501_DC_PANEL_CONTROL); control &= (SM501_DC_PANEL_CONTROL_GAMMA | SM501_DC_PANEL_CONTROL_VDD | SM501_DC_PANEL_CONTROL_DATA | SM501_DC_PANEL_CONTROL_BIAS | SM501_DC_PANEL_CONTROL_FPEN | SM501_DC_PANEL_CONTROL_CP | SM501_DC_PANEL_CONTROL_CK | SM501_DC_PANEL_CONTROL_HP | SM501_DC_PANEL_CONTROL_VP | SM501_DC_PANEL_CONTROL_HPD | SM501_DC_PANEL_CONTROL_VPD); control |= SM501_FIFO_3; /* fill if >3 free slots */ switch(var->bits_per_pixel) { case 8: control |= SM501_DC_PANEL_CONTROL_8BPP; break; case 16: control |= SM501_DC_PANEL_CONTROL_16BPP; sm501fb_setup_gamma(fbi, SM501_DC_PANEL_PALETTE); break; case 32: control |= SM501_DC_PANEL_CONTROL_32BPP; sm501fb_setup_gamma(fbi, SM501_DC_PANEL_PALETTE); break; default: BUG(); } writel(0x0, fbi->regs + SM501_DC_PANEL_PANNING_CONTROL); /* panel plane top left and bottom right location */ writel(0x00, fbi->regs + SM501_DC_PANEL_TL_LOC); reg = var->xres - 1; reg |= (var->yres - 1) << 16; writel(reg, fbi->regs + SM501_DC_PANEL_BR_LOC); /* program panel control register */ control |= SM501_DC_PANEL_CONTROL_TE; /* enable PANEL timing */ control |= SM501_DC_PANEL_CONTROL_EN; /* enable PANEL gfx plane */ if ((var->sync & FB_SYNC_HOR_HIGH_ACT) == 0) control |= SM501_DC_PANEL_CONTROL_HSP; if ((var->sync & FB_SYNC_VERT_HIGH_ACT) == 0) control |= SM501_DC_PANEL_CONTROL_VSP; writel(control, fbi->regs + SM501_DC_PANEL_CONTROL); sm501fb_sync_regs(fbi); /* ensure the panel interface is not tristated at this point */ sm501_modify_reg(fbi->dev->parent, SM501_SYSTEM_CONTROL, 0, SM501_SYSCTRL_PANEL_TRISTATE); /* power the panel up */ sm501fb_panel_power(fbi, 1); return 0; }