Esempio n. 1
0
/*
  *The TMIO core has a RDYREQ interrupt on the posedge of #SMRB.
  *This interrupt is normally disabled, but for long operations like
  *erase and write, we enable it to wake us up.  The irq handler
  *disables the interrupt.
 */
static int
tmio_nand_wait(struct mtd_info *mtd, struct nand_chip *nand_chip)
{
	struct tmio_nand *tmio = mtd_to_tmio(mtd);
	long timeout;

	/* enable RDYREQ interrupt */
	tmio_iowrite8(0x0f, tmio->fcr + FCR_ISR);
	tmio_iowrite8(0x81, tmio->fcr + FCR_IMR);

	timeout = wait_event_timeout(nand_chip->controller->wq,
		tmio_nand_dev_ready(mtd),
		msecs_to_jiffies(nand_chip->state == FL_ERASING ? 400 : 20));

	if (unlikely(!tmio_nand_dev_ready(mtd))) {
		tmio_iowrite8(0x00, tmio->fcr + FCR_IMR);
		dev_warn(&tmio->dev->dev, "still busy with %s after %d ms\n",
			nand_chip->state == FL_ERASING ? "erase" : "program",
			nand_chip->state == FL_ERASING ? 400 : 20);

	} else if (unlikely(!timeout)) {
		tmio_iowrite8(0x00, tmio->fcr + FCR_IMR);
		dev_warn(&tmio->dev->dev, "timeout waiting for interrupt\n");
	}

	nand_chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
	return nand_chip->read_byte(mtd);
}
Esempio n. 2
0
static void tmio_nand_hwcontrol(struct mtd_info *mtd, int cmd,
				   unsigned int ctrl)
{
	struct tmio_nand *tmio = mtd_to_tmio(mtd);
	struct nand_chip *chip = mtd->priv;

	if (ctrl & NAND_CTRL_CHANGE) {
		u8 mode;

		if (ctrl & NAND_NCE) {
			mode = FCR_MODE_DATA;

			if (ctrl & NAND_CLE)
				mode |=  FCR_MODE_CLE;
			else
				mode &= ~FCR_MODE_CLE;

			if (ctrl & NAND_ALE)
				mode |=  FCR_MODE_ALE;
			else
				mode &= ~FCR_MODE_ALE;
		} else {
			mode = FCR_MODE_STANDBY;
		}

		tmio_iowrite8(mode, tmio->fcr + FCR_MODE);
		tmio->read_good = 0;
	}

	if (cmd != NAND_CMD_NONE)
		tmio_iowrite8(cmd, chip->IO_ADDR_W);
}
Esempio n. 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);
}
Esempio n. 4
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);
}
Esempio n. 5
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;
}
Esempio n. 6
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;
}
Esempio n. 7
0
static void tmio_hw_stop(struct platform_device *dev, struct tmio_nand *tmio)
{
	struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data;

	tmio_iowrite8(FCR_MODE_POWER_OFF, tmio->fcr + FCR_MODE);
	if (cell->disable)
		cell->disable(dev);
}
Esempio n. 8
0
static void tmio_hw_stop(struct platform_device *dev, struct tmio_nand *tmio)
{
	const struct mfd_cell *cell = mfd_get_cell(dev);

	tmio_iowrite8(FCR_MODE_POWER_OFF, tmio->fcr + FCR_MODE);
	if (cell->disable)
		cell->disable(dev);
}
Esempio n. 9
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);
}
Esempio n. 10
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);
}
Esempio n. 11
0
static int tmio_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
							u_char *ecc_code)
{
	struct tmio_nand *tmio = mtd_to_tmio(mtd);
	unsigned int ecc;

	tmio_iowrite8(FCR_MODE_HWECC_RESULT, tmio->fcr + FCR_MODE);

	ecc = tmio_ioread16(tmio->fcr + FCR_DATA);
	ecc_code[1] = ecc;	/* 000-255 LP7-0 */
	ecc_code[0] = ecc >> 8;	/* 000-255 LP15-8 */
	ecc = tmio_ioread16(tmio->fcr + FCR_DATA);
	ecc_code[2] = ecc;	/* 000-255 CP5-0,11b */
	ecc_code[4] = ecc >> 8;	/* 256-511 LP7-0 */
	ecc = tmio_ioread16(tmio->fcr + FCR_DATA);
	ecc_code[3] = ecc;	/* 256-511 LP15-8 */
	ecc_code[5] = ecc >> 8;	/* 256-511 CP5-0,11b */

	tmio_iowrite8(FCR_MODE_DATA, tmio->fcr + FCR_MODE);
	return 0;
}
Esempio n. 12
0
static int tmio_hw_init(struct platform_device *dev, struct tmio_nand *tmio)
{
	struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data;
	int ret;

	if (cell->enable) {
		ret = cell->enable(dev);
		if (ret)
			return ret;
	}

	
	tmio_iowrite8(0x81, tmio->ccr + CCR_ICC);

	
	tmio_iowrite16(tmio->fcr_base, tmio->ccr + CCR_BASE);
	tmio_iowrite16(tmio->fcr_base >> 16, tmio->ccr + CCR_BASE + 2);

	
	tmio_iowrite8(0x02, tmio->ccr + CCR_COMMAND);

	
	
	tmio_iowrite8(0x02, tmio->ccr + CCR_NFPSC);

	
	tmio_iowrite8(0x02, tmio->ccr + CCR_NFDC);

	
	tmio_iowrite8(0x0f, tmio->fcr + FCR_ISR);

	
	tmio_iowrite8(FCR_MODE_POWER_ON, tmio->fcr + FCR_MODE);
	tmio_iowrite8(FCR_MODE_COMMAND, tmio->fcr + FCR_MODE);
	tmio_iowrite8(NAND_CMD_RESET, tmio->fcr + FCR_DATA);

	
	tmio_iowrite8(FCR_MODE_STANDBY, tmio->fcr + FCR_MODE);

	mdelay(5);

	return 0;
}
Esempio n. 13
0
static int tmio_hw_init(struct platform_device *dev, struct tmio_nand *tmio)
{
	const struct mfd_cell *cell = mfd_get_cell(dev);
	int ret;

	if (cell->enable) {
		ret = cell->enable(dev);
		if (ret)
			return ret;
	}

	/* (4Ch) CLKRUN Enable    1st spcrunc */
	tmio_iowrite8(0x81, tmio->ccr + CCR_ICC);

	/* (10h)BaseAddress    0x1000 spba.spba2 */
	tmio_iowrite16(tmio->fcr_base, tmio->ccr + CCR_BASE);
	tmio_iowrite16(tmio->fcr_base >> 16, tmio->ccr + CCR_BASE + 2);

	/* (04h)Command Register I/O spcmd */
	tmio_iowrite8(0x02, tmio->ccr + CCR_COMMAND);

	/* (62h) Power Supply Control ssmpwc */
	/* HardPowerOFF - SuspendOFF - PowerSupplyWait_4MS */
	tmio_iowrite8(0x02, tmio->ccr + CCR_NFPSC);

	/* (63h) Detect Control ssmdtc */
	tmio_iowrite8(0x02, tmio->ccr + CCR_NFDC);

	/* Interrupt status register clear sintst */
	tmio_iowrite8(0x0f, tmio->fcr + FCR_ISR);

	/* After power supply, Media are reset smode */
	tmio_iowrite8(FCR_MODE_POWER_ON, tmio->fcr + FCR_MODE);
	tmio_iowrite8(FCR_MODE_COMMAND, tmio->fcr + FCR_MODE);
	tmio_iowrite8(NAND_CMD_RESET, tmio->fcr + FCR_DATA);

	/* Standby Mode smode */
	tmio_iowrite8(FCR_MODE_STANDBY, tmio->fcr + FCR_MODE);

	mdelay(5);

	return 0;
}
Esempio n. 14
0
static irqreturn_t tmio_irq(int irq, void *__tmio)
{
	struct tmio_nand *tmio = __tmio;
	struct nand_chip *nand_chip = &tmio->chip;

	/* disable RDYREQ interrupt */
	tmio_iowrite8(0x00, tmio->fcr + FCR_IMR);

	if (unlikely(!waitqueue_active(&nand_chip->controller->wq)))
		dev_warn(&tmio->dev->dev, "spurious interrupt\n");

	wake_up(&nand_chip->controller->wq);
	return IRQ_HANDLED;
}
Esempio n. 15
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));
}
Esempio n. 16
0
static void tmio_stop_hc(struct platform_device *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);
    u16 pm;

    pm = CCR_PM_GKEN | CCR_PM_CKRNEN;
    switch (ohci->num_ports) {
    default:
        dev_err(&dev->dev, "Unsupported amount of ports: %d\n", ohci->num_ports);
    case 3:
        pm |= CCR_PM_USBPW3;
    case 2:
        pm |= CCR_PM_USBPW2;
    case 1:
        pm |= CCR_PM_USBPW1;
    }
    tmio_iowrite8(0, tmio->ccr + CCR_INTC);
    tmio_iowrite8(0, tmio->ccr + CCR_ILME);
    tmio_iowrite16(0, tmio->ccr + CCR_BASE);
    tmio_iowrite16(0, tmio->ccr + CCR_BASE + 2);
    tmio_iowrite16(pm, tmio->ccr + CCR_PM);
}
Esempio n. 17
0
static int tc6393xb_nand_enable(struct platform_device *nand)
{
	struct platform_device *dev = to_platform_device(nand->dev.parent);
	struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
	unsigned long flags;

	spin_lock_irqsave(&tc6393xb->lock, flags);

	/* SMD buffer on */
	dev_dbg(&dev->dev, "SMD buffer on\n");
	tmio_iowrite8(0xff, tc6393xb->scr + SCR_GPI_BCR(1));

	spin_unlock_irqrestore(&tc6393xb->lock, flags);

	return 0;
}
Esempio n. 18
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;
}
Esempio n. 19
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;
}
Esempio n. 20
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;
}
Esempio n. 21
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;
}
Esempio n. 22
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;
}