示例#1
0
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;
}
示例#2
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;
}
示例#3
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);
}
示例#4
0
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);
}
示例#5
0
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);
}
示例#6
0
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);
}
示例#7
0
/* 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);
}
示例#8
0
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));
}
示例#9
0
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);
}
示例#10
0
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);
		}
}
示例#11
0
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;
}
示例#12
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;
}
示例#13
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;
}
示例#14
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;
}
示例#15
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;
}
示例#16
0
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);
}
示例#17
0
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;
}