static int ohci_hcd_tmio_drv_suspend(struct platform_device *dev, pm_message_t state) { const struct mfd_cell *cell = mfd_get_cell(dev); struct usb_hcd *hcd = platform_get_drvdata(dev); struct ohci_hcd *ohci = hcd_to_ohci(hcd); struct tmio_hcd *tmio = hcd_to_tmio(hcd); unsigned long flags; u8 misc; int ret; if (time_before(jiffies, ohci->next_statechange)) msleep(5); ohci->next_statechange = jiffies; spin_lock_irqsave(&tmio->lock, flags); misc = tmio_ioread8(tmio->ccr + CCR_MISC); misc |= 1 << 3; /* USSUSP */ tmio_iowrite8(misc, tmio->ccr + CCR_MISC); spin_unlock_irqrestore(&tmio->lock, flags); if (cell->suspend) { ret = cell->suspend(dev); if (ret) return ret; } return 0; }
static int ohci_hcd_tmio_drv_resume(struct platform_device *dev) { const struct mfd_cell *cell = mfd_get_cell(dev); struct usb_hcd *hcd = platform_get_drvdata(dev); struct ohci_hcd *ohci = hcd_to_ohci(hcd); struct tmio_hcd *tmio = hcd_to_tmio(hcd); unsigned long flags; u8 misc; int ret; if (time_before(jiffies, ohci->next_statechange)) msleep(5); ohci->next_statechange = jiffies; if (cell->resume) { ret = cell->resume(dev); if (ret) return ret; } tmio_start_hc(dev); spin_lock_irqsave(&tmio->lock, flags); misc = tmio_ioread8(tmio->ccr + CCR_MISC); misc &= ~(1 << 3); /* USSUSP */ tmio_iowrite8(misc, tmio->ccr + CCR_MISC); spin_unlock_irqrestore(&tmio->lock, flags); ohci_finish_controller_resume(hcd); return 0; }
static void tmio_nand_enable_hwecc(struct mtd_info *mtd, int mode) { struct tmio_nand *tmio = mtd_to_tmio(mtd); tmio_iowrite8(FCR_MODE_HWECC_RESET, tmio->fcr + FCR_MODE); tmio_ioread8(tmio->fcr + FCR_DATA); /* dummy read */ tmio_iowrite8(FCR_MODE_HWECC_CALC, tmio->fcr + FCR_MODE); }
static int tc6393xb_gpio_get(struct gpio_chip *chip, unsigned offset) { struct tc6393xb *tc6393xb = container_of(chip, struct tc6393xb, gpio); /* XXX: does dsr also represent inputs? */ return tmio_ioread8(tc6393xb->scr + SCR_GPO_DSR(offset / 8)) & TC_GPIO_BIT(offset); }
static void t7l66xb_irq_unmask(unsigned int irq) { struct t7l66xb *t7l66xb = get_irq_chip_data(irq); unsigned long flags; u8 imr; spin_lock_irqsave(&t7l66xb->lock, flags); imr = tmio_ioread8(t7l66xb->scr + SCR_IMR); imr &= ~(1 << (irq - t7l66xb->irq_base)); tmio_iowrite8(imr, t7l66xb->scr + SCR_IMR); spin_unlock_irqrestore(&t7l66xb->lock, flags); }
static void tc6393xb_irq_unmask(struct irq_data *data) { struct tc6393xb *tc6393xb = irq_data_get_irq_chip_data(data); unsigned long flags; u8 imr; spin_lock_irqsave(&tc6393xb->lock, flags); imr = tmio_ioread8(tc6393xb->scr + SCR_IMR); imr &= ~(1 << (data->irq - tc6393xb->irq_base)); tmio_iowrite8(imr, tc6393xb->scr + SCR_IMR); spin_unlock_irqrestore(&tc6393xb->lock, flags); }
/* Handle the T7L66XB interrupt mux */ static void t7l66xb_irq(unsigned int irq, struct irq_desc *desc) { struct t7l66xb *t7l66xb = get_irq_data(irq); unsigned int isr; unsigned int i, irq_base; irq_base = t7l66xb->irq_base; while ((isr = tmio_ioread8(t7l66xb->scr + SCR_ISR) & ~tmio_ioread8(t7l66xb->scr + SCR_IMR))) for (i = 0; i < T7L66XB_NR_IRQS; i++) if (isr & (1 << i)) generic_handle_irq(irq_base + i); }
static void __tc6393xb_gpio_set(struct gpio_chip *chip, unsigned offset, int value) { struct tc6393xb *tc6393xb = container_of(chip, struct tc6393xb, gpio); u8 dsr; dsr = tmio_ioread8(tc6393xb->scr + SCR_GPO_DSR(offset / 8)); if (value) dsr |= TC_GPIO_BIT(offset); else dsr &= ~TC_GPIO_BIT(offset); tmio_iowrite8(dsr, tc6393xb->scr + SCR_GPO_DSR(offset / 8)); }
static void tmio_start_hc(struct platform_device *dev) { struct usb_hcd *hcd = platform_get_drvdata(dev); struct tmio_hcd *tmio = hcd_to_tmio(hcd); unsigned long base = hcd->rsrc_start; tmio_write_pm(dev); tmio_iowrite16(base, tmio->ccr + CCR_BASE); tmio_iowrite16(base >> 16, tmio->ccr + CCR_BASE + 2); tmio_iowrite8(1, tmio->ccr + CCR_ILME); tmio_iowrite8(2, tmio->ccr + CCR_INTC); dev_info(&dev->dev, "revision %d @ 0x%08llx, irq %d\n", tmio_ioread8(tmio->ccr + CCR_REVID), hcd->rsrc_start, hcd->irq); }
static void tc6393xb_irq(unsigned int irq, struct irq_desc *desc) { struct tc6393xb *tc6393xb = irq_get_handler_data(irq); unsigned int isr; unsigned int i, irq_base; irq_base = tc6393xb->irq_base; while ((isr = tmio_ioread8(tc6393xb->scr + SCR_ISR) & ~tmio_ioread8(tc6393xb->scr + SCR_IMR))) for (i = 0; i < TC6393XB_NR_IRQS; i++) { if (isr & (1 << i)) generic_handle_irq(irq_base + i); } }
static int tc6393xb_gpio_direction_input(struct gpio_chip *chip, unsigned offset) { struct tc6393xb *tc6393xb = container_of(chip, struct tc6393xb, gpio); unsigned long flags; u8 doecr; spin_lock_irqsave(&tc6393xb->lock, flags); doecr = tmio_ioread8(tc6393xb->scr + SCR_GPO_DOECR(offset / 8)); doecr &= ~TC_GPIO_BIT(offset); tmio_iowrite8(doecr, tc6393xb->scr + SCR_GPO_DOECR(offset / 8)); spin_unlock_irqrestore(&tc6393xb->lock, flags); return 0; }
static int t7l66xb_mmc_disable(struct platform_device *mmc) { struct platform_device *dev = to_platform_device(mmc->dev.parent); struct t7l66xb *t7l66xb = platform_get_drvdata(dev); unsigned long flags; u8 dev_ctl; spin_lock_irqsave(&t7l66xb->lock, flags); dev_ctl = tmio_ioread8(t7l66xb->scr + SCR_DEV_CTL); dev_ctl &= ~SCR_DEV_CTL_MMC; tmio_iowrite8(dev_ctl, t7l66xb->scr + SCR_DEV_CTL); spin_unlock_irqrestore(&t7l66xb->lock, flags); clk_disable(t7l66xb->clk32k); return 0; }
static int tc6393xb_ohci_disable(struct platform_device *dev) { struct tc6393xb *tc6393xb = dev_get_drvdata(dev->dev.parent); unsigned long flags; u16 ccr; u8 fer; spin_lock_irqsave(&tc6393xb->lock, flags); fer = tmio_ioread8(tc6393xb->scr + SCR_FER); fer &= ~SCR_FER_USBEN; tmio_iowrite8(fer, tc6393xb->scr + SCR_FER); ccr = tmio_ioread16(tc6393xb->scr + SCR_CCR); ccr &= ~SCR_CCR_USBCK; tmio_iowrite16(ccr, tc6393xb->scr + SCR_CCR); spin_unlock_irqrestore(&tc6393xb->lock, flags); return 0; }
static int t7l66xb_mmc_enable(struct platform_device *mmc) { struct platform_device *dev = to_platform_device(mmc->dev.parent); struct t7l66xb *t7l66xb = platform_get_drvdata(dev); unsigned long flags; u8 dev_ctl; clk_enable(t7l66xb->clk32k); spin_lock_irqsave(&t7l66xb->lock, flags); dev_ctl = tmio_ioread8(t7l66xb->scr + SCR_DEV_CTL); dev_ctl |= SCR_DEV_CTL_MMC; tmio_iowrite8(dev_ctl, t7l66xb->scr + SCR_DEV_CTL); spin_unlock_irqrestore(&t7l66xb->lock, flags); tmio_core_mmc_enable(t7l66xb->scr + 0x200, 0, t7l66xb_mmc_resources[0].start & 0xfffe); return 0; }
static int t7l66xb_probe(struct platform_device *dev) { struct t7l66xb_platform_data *pdata = dev->dev.platform_data; struct t7l66xb *t7l66xb; struct resource *iomem, *rscr; int ret; iomem = platform_get_resource(dev, IORESOURCE_MEM, 0); if (!iomem) return -EINVAL; t7l66xb = kzalloc(sizeof *t7l66xb, GFP_KERNEL); if (!t7l66xb) return -ENOMEM; spin_lock_init(&t7l66xb->lock); platform_set_drvdata(dev, t7l66xb); ret = platform_get_irq(dev, 0); if (ret >= 0) t7l66xb->irq = ret; else goto err_noirq; t7l66xb->irq_base = pdata->irq_base; t7l66xb->clk32k = clk_get(&dev->dev, "CLK_CK32K"); if (IS_ERR(t7l66xb->clk32k)) { ret = PTR_ERR(t7l66xb->clk32k); goto err_clk32k_get; } t7l66xb->clk48m = clk_get(&dev->dev, "CLK_CK48M"); if (IS_ERR(t7l66xb->clk48m)) { ret = PTR_ERR(t7l66xb->clk48m); clk_put(t7l66xb->clk32k); goto err_clk48m_get; } rscr = &t7l66xb->rscr; rscr->name = "t7l66xb-core"; rscr->start = iomem->start; rscr->end = iomem->start + 0xff; rscr->flags = IORESOURCE_MEM; ret = request_resource(iomem, rscr); if (ret) goto err_request_scr; t7l66xb->scr = ioremap(rscr->start, rscr->end - rscr->start + 1); if (!t7l66xb->scr) { ret = -ENOMEM; goto err_ioremap; } clk_enable(t7l66xb->clk48m); if (pdata && pdata->enable) pdata->enable(dev); /* Mask all interrupts */ tmio_iowrite8(0xbf, t7l66xb->scr + SCR_IMR); printk(KERN_INFO "%s rev %d @ 0x%08lx, irq %d\n", dev->name, tmio_ioread8(t7l66xb->scr + SCR_REVID), (unsigned long)iomem->start, t7l66xb->irq); t7l66xb_attach_irq(dev); t7l66xb_cells[T7L66XB_CELL_NAND].driver_data = pdata->nand_data; t7l66xb_cells[T7L66XB_CELL_NAND].platform_data = &t7l66xb_cells[T7L66XB_CELL_NAND]; t7l66xb_cells[T7L66XB_CELL_NAND].data_size = sizeof(t7l66xb_cells[T7L66XB_CELL_NAND]); t7l66xb_cells[T7L66XB_CELL_MMC].platform_data = &t7l66xb_cells[T7L66XB_CELL_MMC]; t7l66xb_cells[T7L66XB_CELL_MMC].data_size = sizeof(t7l66xb_cells[T7L66XB_CELL_MMC]); ret = mfd_add_devices(&dev->dev, dev->id, t7l66xb_cells, ARRAY_SIZE(t7l66xb_cells), iomem, t7l66xb->irq_base); if (!ret) return 0; t7l66xb_detach_irq(dev); iounmap(t7l66xb->scr); err_ioremap: release_resource(&t7l66xb->rscr); err_request_scr: kfree(t7l66xb); clk_put(t7l66xb->clk48m); err_clk48m_get: clk_put(t7l66xb->clk32k); err_clk32k_get: err_noirq: return ret; }
static int tmio_nand_dev_ready(struct mtd_info *mtd) { struct tmio_nand *tmio = mtd_to_tmio(mtd); return !(tmio_ioread8(tmio->fcr + FCR_STATUS) & FCR_STATUS_BUSY); }
static int __devinit tc6393xb_probe(struct platform_device *dev) { struct tc6393xb_platform_data *tcpd = dev->dev.platform_data; struct tc6393xb *tc6393xb; struct resource *iomem, *rscr; int ret, temp; iomem = platform_get_resource(dev, IORESOURCE_MEM, 0); if (!iomem) return -EINVAL; tc6393xb = kzalloc(sizeof *tc6393xb, GFP_KERNEL); if (!tc6393xb) { ret = -ENOMEM; goto err_kzalloc; } spin_lock_init(&tc6393xb->lock); platform_set_drvdata(dev, tc6393xb); ret = platform_get_irq(dev, 0); if (ret >= 0) tc6393xb->irq = ret; else goto err_noirq; tc6393xb->iomem = iomem; tc6393xb->irq_base = tcpd->irq_base; tc6393xb->clk = clk_get(&dev->dev, "CLK_CK3P6MI"); if (IS_ERR(tc6393xb->clk)) { ret = PTR_ERR(tc6393xb->clk); goto err_clk_get; } rscr = &tc6393xb->rscr; rscr->name = "tc6393xb-core"; rscr->start = iomem->start; rscr->end = iomem->start + 0xff; rscr->flags = IORESOURCE_MEM; ret = request_resource(iomem, rscr); if (ret) goto err_request_scr; tc6393xb->scr = ioremap(rscr->start, resource_size(rscr)); if (!tc6393xb->scr) { ret = -ENOMEM; goto err_ioremap; } ret = clk_enable(tc6393xb->clk); if (ret) goto err_clk_enable; ret = tcpd->enable(dev); if (ret) goto err_enable; iowrite8(0, tc6393xb->scr + SCR_FER); iowrite16(tcpd->scr_pll2cr, tc6393xb->scr + SCR_PLL2CR); iowrite16(SCR_CCR_UNK1 | SCR_CCR_HCLK_48, tc6393xb->scr + SCR_CCR); iowrite16(SCR_MCR_RDY_OPENDRAIN | SCR_MCR_RDY_UNK | SCR_MCR_RDY_EN | SCR_MCR_INT_OPENDRAIN | SCR_MCR_INT_UNK | SCR_MCR_INT_EN | BIT(15), tc6393xb->scr + SCR_MCR); iowrite16(tcpd->scr_gper, tc6393xb->scr + SCR_GPER); iowrite8(0, tc6393xb->scr + SCR_IRR); iowrite8(0xbf, tc6393xb->scr + SCR_IMR); printk(KERN_INFO "Toshiba tc6393xb revision %d at 0x%08lx, irq %d\n", tmio_ioread8(tc6393xb->scr + SCR_REVID), (unsigned long) iomem->start, tc6393xb->irq); tc6393xb->gpio.base = -1; if (tcpd->gpio_base >= 0) { ret = tc6393xb_register_gpio(tc6393xb, tcpd->gpio_base); if (ret) goto err_gpio_add; } tc6393xb_attach_irq(dev); if (tcpd->setup) { ret = tcpd->setup(dev); if (ret) goto err_setup; } tc6393xb_cells[TC6393XB_CELL_NAND].platform_data = tcpd->nand_data; tc6393xb_cells[TC6393XB_CELL_NAND].pdata_size = sizeof(*tcpd->nand_data); tc6393xb_cells[TC6393XB_CELL_FB].platform_data = tcpd->fb_data; tc6393xb_cells[TC6393XB_CELL_FB].pdata_size = sizeof(*tcpd->fb_data); ret = mfd_add_devices(&dev->dev, dev->id, tc6393xb_cells, ARRAY_SIZE(tc6393xb_cells), iomem, tcpd->irq_base); if (!ret) return 0; if (tcpd->teardown) tcpd->teardown(dev); err_setup: tc6393xb_detach_irq(dev); err_gpio_add: if (tc6393xb->gpio.base != -1) temp = gpiochip_remove(&tc6393xb->gpio); tcpd->disable(dev); err_enable: clk_disable(tc6393xb->clk); err_clk_enable: iounmap(tc6393xb->scr); err_ioremap: release_resource(&tc6393xb->rscr); err_request_scr: clk_put(tc6393xb->clk); err_noirq: err_clk_get: kfree(tc6393xb); err_kzalloc: return ret; }