예제 #1
0
static int __platform_pm_runtime_resume(struct platform_device *pdev)
{
    struct device *d = &pdev->dev;
    struct pdev_archdata *ad = &pdev->archdata;
    int hwblk = ad->hwblk_id;
    int ret = -ENOSYS;

    dev_dbg(d, "__platform_pm_runtime_resume() [%d]\n", hwblk);

    if (d->driver) {
        hwblk_enable(hwblk_info, hwblk);
        ret = 0;

        if (test_bit(PDEV_ARCHDATA_FLAG_SUSP, &ad->flags)) {
            if (d->driver->pm && d->driver->pm->runtime_resume)
                ret = d->driver->pm->runtime_resume(d);

            if (!ret)
                clear_bit(PDEV_ARCHDATA_FLAG_SUSP, &ad->flags);
            else
                hwblk_disable(hwblk_info, hwblk);
        }
    }

    dev_dbg(d, "__platform_pm_runtime_resume() [%d] - returns %d\n",
            hwblk, ret);

    return ret;
}
예제 #2
0
static int __platform_pm_runtime_suspend(struct platform_device *pdev)
{
    struct device *d = &pdev->dev;
    struct pdev_archdata *ad = &pdev->archdata;
    int hwblk = ad->hwblk_id;
    int ret = -ENOSYS;

    dev_dbg(d, "__platform_pm_runtime_suspend() [%d]\n", hwblk);

    if (d->driver) {
        BUG_ON(!test_bit(PDEV_ARCHDATA_FLAG_IDLE, &ad->flags));
        ret = 0;

        if (d->driver->pm && d->driver->pm->runtime_suspend) {
            hwblk_enable(hwblk_info, hwblk);
            ret = d->driver->pm->runtime_suspend(d);
            hwblk_disable(hwblk_info, hwblk);
        }

        if (!ret) {
            set_bit(PDEV_ARCHDATA_FLAG_SUSP, &ad->flags);
            platform_pm_runtime_not_idle(pdev);
            hwblk_cnt_dec(hwblk_info, hwblk, HWBLK_CNT_IDLE);
        }
    }

    dev_dbg(d, "__platform_pm_runtime_suspend() [%d] - returns %d\n",
            hwblk, ret);

    return ret;
}
예제 #3
0
파일: hwblk.c 프로젝트: 08opt/linux
/* allow clocks to enable and disable hardware blocks */
static int sh_hwblk_clk_enable(struct clk *clk)
{
	if (!hwblk_info)
		return -ENOENT;

	hwblk_enable(hwblk_info, clk->arch_flags);
	return 0;
}
예제 #4
0
static int platform_bus_notify(struct notifier_block *nb,
                               unsigned long action, void *data)
{
    struct device *dev = data;
    struct platform_device *pdev = to_platform_device(dev);
    int hwblk = pdev->archdata.hwblk_id;

    /* ignore off-chip platform devices */
    if (!hwblk)
        return 0;

    switch (action) {
    case BUS_NOTIFY_ADD_DEVICE:
        INIT_LIST_HEAD(&pdev->archdata.entry);
        mutex_init(&pdev->archdata.mutex);
        /* platform devices without drivers should be disabled */
        hwblk_enable(hwblk_info, hwblk);
        hwblk_disable(hwblk_info, hwblk);
        /* make sure driver re-inits itself once */
        __set_bit(PDEV_ARCHDATA_FLAG_INIT, &pdev->archdata.flags);
        break;
    /* TODO: add BUS_NOTIFY_BIND_DRIVER and increase idle count */
    case BUS_NOTIFY_BOUND_DRIVER:
        /* keep track of number of devices in use per hwblk */
        hwblk_cnt_inc(hwblk_info, hwblk, HWBLK_CNT_DEVICES);
        break;
    case BUS_NOTIFY_UNBOUND_DRIVER:
        /* keep track of number of devices in use per hwblk */
        hwblk_cnt_dec(hwblk_info, hwblk, HWBLK_CNT_DEVICES);
        /* make sure driver re-inits itself once */
        __set_bit(PDEV_ARCHDATA_FLAG_INIT, &pdev->archdata.flags);
        break;
    case BUS_NOTIFY_DEL_DEVICE:
        break;
    }
    return 0;
}