Example #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;
}
Example #2
0
int mfd_clone_cell(const char *cell, const char **clones, size_t n_clones)
{
	struct mfd_cell cell_entry;
	struct device *dev;
	struct platform_device *pdev;
	int i;

	/* fetch the parent cell's device (should already be registered!) */
	dev = bus_find_device_by_name(&platform_bus_type, NULL, cell);
	if (!dev) {
		printk(KERN_ERR "failed to find device for cell %s\n", cell);
		return -ENODEV;
	}
	pdev = to_platform_device(dev);
	memcpy(&cell_entry, mfd_get_cell(pdev), sizeof(cell_entry));

	WARN_ON(!cell_entry.enable);

	for (i = 0; i < n_clones; i++) {
		cell_entry.name = clones[i];
		/* don't give up if a single call fails; just report error */
		if (mfd_add_device(pdev->dev.parent, -1, &cell_entry, NULL, 0))
			dev_err(dev, "failed to create platform device '%s'\n",
					clones[i]);
	}

	return 0;
}
Example #3
0
int mfd_clone_cell(const char *cell, const char **clones, size_t n_clones)
{
	struct mfd_cell cell_entry;
	struct device *dev;
	struct platform_device *pdev;
	int i;

	
	dev = bus_find_device_by_name(&platform_bus_type, NULL, cell);
	if (!dev) {
		printk(KERN_ERR "failed to find device for cell %s\n", cell);
		return -ENODEV;
	}
	pdev = to_platform_device(dev);
	memcpy(&cell_entry, mfd_get_cell(pdev), sizeof(cell_entry));

	WARN_ON(!cell_entry.enable);

	for (i = 0; i < n_clones; i++) {
		cell_entry.name = clones[i];
		
		if (mfd_add_device(pdev->dev.parent, -1, &cell_entry, NULL, 0))
			dev_err(dev, "failed to create platform device '%s'\n",
					clones[i]);
	}

	return 0;
}
Example #4
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;
}
Example #5
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);
}
Example #6
0
static int tmio_suspend(struct platform_device *dev, pm_message_t state)
{
	const struct mfd_cell *cell = mfd_get_cell(dev);

	if (cell->suspend)
		cell->suspend(dev);

	tmio_hw_stop(dev, platform_get_drvdata(dev));
	return 0;
}
Example #7
0
static int asic3_led_resume(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	const struct mfd_cell *cell = mfd_get_cell(pdev);
	int ret;

	ret = 0;
	if (cell->resume)
		ret = (*cell->resume)(pdev);

	return ret;
}
Example #8
0
static int mfd_remove_devices_fn(struct device *dev, void *c)
{
	struct platform_device *pdev = to_platform_device(dev);
	const struct mfd_cell *cell = mfd_get_cell(pdev);
	atomic_t **usage_count = c;

	/* find the base address of usage_count pointers (for freeing) */
	if (!*usage_count || (cell->usage_count < *usage_count))
		*usage_count = cell->usage_count;

	platform_device_unregister(pdev);
	return 0;
}
static int tmio_mmc_suspend(struct platform_device *dev, pm_message_t state)
{
	const struct mfd_cell *cell = mfd_get_cell(dev);
	int ret;

	ret = tmio_mmc_host_suspend(&dev->dev);

	/*                                     */
	if (!ret && cell->disable)
		cell->disable(dev);

	return ret;
}
Example #10
0
static int tmio_resume(struct platform_device *dev)
{
	const struct mfd_cell *cell = mfd_get_cell(dev);

	/* FIXME - is this required or merely another attack of the broken
	 * SHARP platform? Looks suspicious.
	 */
	tmio_hw_init(dev, platform_get_drvdata(dev));

	if (cell->resume)
		cell->resume(dev);

	return 0;
}
Example #11
0
static int tmio_mmc_resume(struct platform_device *dev)
{
	const struct mfd_cell *cell = mfd_get_cell(dev);
	int ret = 0;

	/* Tell the MFD core we are ready to be enabled */
	if (cell->resume)
		ret = cell->resume(dev);

	if (!ret)
		ret = tmio_mmc_host_resume(&dev->dev);

	return ret;
}
static int tmio_mmc_resume(struct platform_device *dev)
{
	const struct mfd_cell *cell = mfd_get_cell(dev);
	int ret = 0;

	/*                                              */
	if (cell->resume)
		ret = cell->resume(dev);

	if (!ret)
		ret = tmio_mmc_host_resume(&dev->dev);

	return ret;
}
Example #13
0
static int tmio_mmc_suspend(struct platform_device *dev, pm_message_t state)
{
	const struct mfd_cell *cell = mfd_get_cell(dev);
	struct mmc_host *mmc = platform_get_drvdata(dev);
	int ret;

	ret = mmc_suspend_host(mmc);

	/* Tell MFD core it can disable us now.*/
	if (!ret && cell->disable)
		cell->disable(dev);

	return ret;
}
static int __devinit tmio_mmc_probe(struct platform_device *pdev)
{
	const struct mfd_cell *cell = mfd_get_cell(pdev);
	struct tmio_mmc_data *pdata;
	struct tmio_mmc_host *host;
	int ret = -EINVAL, irq;

	if (pdev->num_resources != 2)
		goto out;

	pdata = pdev->dev.platform_data;
	if (!pdata || !pdata->hclk)
		goto out;

	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		ret = irq;
		goto out;
	}

	/*                                              */
	if (cell->enable) {
		ret = cell->enable(pdev);
		if (ret)
			goto out;
	}

	ret = tmio_mmc_host_probe(&host, pdev, pdata);
	if (ret)
		goto cell_disable;

	ret = request_irq(irq, tmio_mmc_irq, IRQF_TRIGGER_FALLING,
				dev_name(&pdev->dev), host);
	if (ret)
		goto host_remove;

	pr_info("%s at 0x%08lx irq %d\n", mmc_hostname(host->mmc),
		(unsigned long)host->ctl, irq);

	return 0;

host_remove:
	tmio_mmc_host_remove(host);
cell_disable:
	if (cell->disable)
		cell->disable(pdev);
out:
	return ret;
}
Example #15
0
int mfd_cell_enable(struct platform_device *pdev)
{
	const struct mfd_cell *cell = mfd_get_cell(pdev);
	int err = 0;

	/* only call enable hook if the cell wasn't previously enabled */
	if (atomic_inc_return(cell->usage_count) == 1)
		err = cell->enable(pdev);

	/* if the enable hook failed, decrement counter to allow retries */
	if (err)
		atomic_dec(cell->usage_count);

	return err;
}
Example #16
0
static int tmio_mmc_remove(struct platform_device *pdev)
{
	const struct mfd_cell *cell = mfd_get_cell(pdev);
	struct mmc_host *mmc = platform_get_drvdata(pdev);

	if (mmc) {
		struct tmio_mmc_host *host = mmc_priv(mmc);
		free_irq(platform_get_irq(pdev, 0), host);
		tmio_mmc_host_remove(host);
		if (cell->disable)
			cell->disable(pdev);
	}

	return 0;
}
Example #17
0
int mfd_cell_enable(struct platform_device *pdev)
{
	const struct mfd_cell *cell = mfd_get_cell(pdev);
	int err = 0;

	
	if (atomic_inc_return(cell->usage_count) == 1)
		err = cell->enable(pdev);

	
	if (err)
		atomic_dec(cell->usage_count);

	return err;
}
Example #18
0
static int __devexit tmio_mmc_remove(struct platform_device *pdev)
{
	const struct mfd_cell *cell = mfd_get_cell(pdev);
	struct mmc_host *mmc = platform_get_drvdata(pdev);

	platform_set_drvdata(pdev, NULL);

	if (mmc) {
		tmio_mmc_host_remove(mmc_priv(mmc));
		if (cell->disable)
			cell->disable(pdev);
	}

	return 0;
}
Example #19
0
static int ohci_hcd_tmio_drv_remove(struct platform_device *dev)
{
	struct usb_hcd *hcd = platform_get_drvdata(dev);
	struct tmio_hcd *tmio = hcd_to_tmio(hcd);
	const struct mfd_cell *cell = mfd_get_cell(dev);

	usb_remove_hcd(hcd);
	tmio_stop_hc(dev);
	if (cell->disable)
		cell->disable(dev);
	dma_release_declared_memory(&dev->dev);
	iounmap(hcd->regs);
	iounmap(tmio->ccr);
	usb_put_hcd(hcd);

	return 0;
}
Example #20
0
static void brightness_set(struct led_classdev *cdev,
	enum led_brightness value)
{
	struct platform_device *pdev = to_platform_device(cdev->dev->parent);
	const struct mfd_cell *cell = mfd_get_cell(pdev);
	struct asic3 *asic = dev_get_drvdata(pdev->dev.parent);
	u32 timebase;
	unsigned int base;

	timebase = (value == LED_OFF) ? 0 : (LED_EN|0x4);

	base = led_n_base[cell->id];
	asic3_write_register(asic, (base + ASIC3_LED_PeriodTime), 32);
	asic3_write_register(asic, (base + ASIC3_LED_DutyTime), 32);
	asic3_write_register(asic, (base + ASIC3_LED_AutoStopCount), 0);
	asic3_write_register(asic, (base + ASIC3_LED_TimeBase), timebase);
}
Example #21
0
static int mfd_remove_devices_fn(struct device *dev, void *c)
{
	struct platform_device *pdev;
	const struct mfd_cell *cell;
	atomic_t **usage_count = c;

	if (dev->type != &mfd_dev_type)
		return 0;

	pdev = to_platform_device(dev);
	cell = mfd_get_cell(pdev);

	if (!*usage_count || (cell->usage_count < *usage_count))
		*usage_count = cell->usage_count;

	platform_device_unregister(pdev);
	return 0;
}
Example #22
0
static int tmio_mmc_resume(struct platform_device *dev)
{
	const struct mfd_cell *cell = mfd_get_cell(dev);
	struct mmc_host *mmc = platform_get_drvdata(dev);
	int ret = 0;

	/* Tell the MFD core we are ready to be enabled */
	if (cell->resume) {
		ret = cell->resume(dev);
		if (ret)
			goto out;
	}

	mmc_resume_host(mmc);

out:
	return ret;
}
Example #23
0
int mfd_cell_disable(struct platform_device *pdev)
{
	const struct mfd_cell *cell = mfd_get_cell(pdev);
	int err = 0;

	
	if (atomic_dec_return(cell->usage_count) == 0)
		err = cell->disable(pdev);

	
	if (err)
		atomic_inc(cell->usage_count);

	
	WARN_ON(atomic_read(cell->usage_count) < 0);

	return err;
}
Example #24
0
int mfd_cell_disable(struct platform_device *pdev)
{
	const struct mfd_cell *cell = mfd_get_cell(pdev);
	int err = 0;

	/* only disable if no other clients are using it */
	if (atomic_dec_return(cell->usage_count) == 0)
		err = cell->disable(pdev);

	/* if the disable hook failed, increment to allow retries */
	if (err)
		atomic_inc(cell->usage_count);

	/* sanity check; did someone call disable too many times? */
	WARN_ON(atomic_read(cell->usage_count) < 0);

	return err;
}
Example #25
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;
}
Example #26
0
static int blink_set(struct led_classdev *cdev,
	unsigned long *delay_on,
	unsigned long *delay_off)
{
	struct platform_device *pdev = to_platform_device(cdev->dev->parent);
	const struct mfd_cell *cell = mfd_get_cell(pdev);
	struct asic3 *asic = dev_get_drvdata(pdev->dev.parent);
	u32 on;
	u32 off;
	unsigned int base;

	if (*delay_on > MAX_MS || *delay_off > MAX_MS)
		return -EINVAL;

	if (*delay_on == 0 && *delay_off == 0) {
		/* If both are zero then a sensible default should be chosen */
		on = MS_TO_CLK(500);
		off = MS_TO_CLK(500);
	} else {
		on = MS_TO_CLK(*delay_on);
		off = MS_TO_CLK(*delay_off);
		if ((on + off) > MAX_CLK)
			return -EINVAL;
	}

	base = led_n_base[cell->id];
	asic3_write_register(asic, (base + ASIC3_LED_PeriodTime), (on + off));
	asic3_write_register(asic, (base + ASIC3_LED_DutyTime), on);
	asic3_write_register(asic, (base + ASIC3_LED_AutoStopCount), 0);
	asic3_write_register(asic, (base + ASIC3_LED_TimeBase), (LED_EN|0x4));

	*delay_on = CLK_TO_MS(on);
	*delay_off = CLK_TO_MS(off);

	return 0;
}
Example #27
0
static int __devinit tmio_mmc_probe(struct platform_device *pdev)
{
	const struct mfd_cell *cell = mfd_get_cell(pdev);
	struct tmio_mmc_data *pdata;
	struct tmio_mmc_host *host;
	int ret = -EINVAL;

	if (pdev->num_resources != 2)
		goto out;

	pdata = mfd_get_data(pdev);
	if (!pdata || !pdata->hclk)
		goto out;

	/* Tell the MFD core we are ready to be enabled */
	if (cell->enable) {
		ret = cell->enable(pdev);
		if (ret)
			goto out;
	}

	ret = tmio_mmc_host_probe(&host, pdev, pdata);
	if (ret)
		goto cell_disable;

	pr_info("%s at 0x%08lx irq %d\n", mmc_hostname(host->mmc),
		(unsigned long)host->ctl, host->irq);

	return 0;

cell_disable:
	if (cell->disable)
		cell->disable(pdev);
out:
	return ret;
}
Example #28
0
static int __devinit ohci_hcd_tmio_drv_probe(struct platform_device *dev)
{
    const struct mfd_cell *cell = mfd_get_cell(dev);
    struct resource *regs = platform_get_resource(dev, IORESOURCE_MEM, 0);
    struct resource *config = platform_get_resource(dev, IORESOURCE_MEM, 1);
    struct resource *sram = platform_get_resource(dev, IORESOURCE_MEM, 2);
    int irq = platform_get_irq(dev, 0);
    struct tmio_hcd *tmio;
    struct ohci_hcd *ohci;
    struct usb_hcd *hcd;
    int ret;

    if (usb_disabled())
        return -ENODEV;

    if (!cell)
        return -EINVAL;

    hcd = usb_create_hcd(&ohci_tmio_hc_driver, &dev->dev, dev_name(&dev->dev));
    if (!hcd) {
        ret = -ENOMEM;
        goto err_usb_create_hcd;
    }

    hcd->rsrc_start = regs->start;
    hcd->rsrc_len = resource_size(regs);

    tmio = hcd_to_tmio(hcd);

    spin_lock_init(&tmio->lock);

    tmio->ccr = ioremap(config->start, resource_size(config));
    if (!tmio->ccr) {
        ret = -ENOMEM;
        goto err_ioremap_ccr;
    }

    hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
    if (!hcd->regs) {
        ret = -ENOMEM;
        goto err_ioremap_regs;
    }

    if (!dma_declare_coherent_memory(&dev->dev, sram->start,
                                     sram->start,
                                     resource_size(sram),
                                     DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE)) {
        ret = -EBUSY;
        goto err_dma_declare;
    }

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

    tmio_start_hc(dev);
    ohci = hcd_to_ohci(hcd);
    ohci_hcd_init(ohci);

    ret = usb_add_hcd(hcd, irq, 0);
    if (ret)
        goto err_add_hcd;

    if (ret == 0)
        return ret;

    usb_remove_hcd(hcd);

err_add_hcd:
    tmio_stop_hc(dev);
    if (cell->disable)
        cell->disable(dev);
err_enable:
    dma_release_declared_memory(&dev->dev);
err_dma_declare:
    iounmap(hcd->regs);
err_ioremap_regs:
    iounmap(tmio->ccr);
err_ioremap_ccr:
    usb_put_hcd(hcd);
err_usb_create_hcd:

    return ret;
}