示例#1
0
static int sharpsl_pm_suspend(struct platform_device *pdev, pm_message_t state)
{
	sharpsl_pm.flags |= SHARPSL_SUSPENDED;
	flush_delayed_work_sync(&toggle_charger);
	flush_delayed_work_sync(&sharpsl_bat);

	if (sharpsl_pm.charge_mode == CHRG_ON)
		sharpsl_pm.flags |= SHARPSL_DO_OFFLINE_CHRG;
	else
		sharpsl_pm.flags &= ~SHARPSL_DO_OFFLINE_CHRG;

	return 0;
}
static int s5p_dp_set_power(struct lcd_device *lcd, int power)
{
	struct s5p_dp_device *dp = lcd_get_data(lcd);
	int retval;

#ifdef CONFIG_S5P_DP_PSR
	if (dp->user_disabled)
		return 0;
#endif

#ifdef CONFIG_S5P_DP_ESD_RECOVERY
	dp->set_power_state = power;
#endif

	if (power == FB_BLANK_UNBLANK) {
		retval = s5p_dp_enable(dp);
		if (retval < 0)
			return retval;
	} else {
#ifdef CONFIG_S5P_DP_ESD_RECOVERY
		if (dp->enabled)
			s5p_dp_disable_esd_interrupt(dp);
		flush_delayed_work_sync(&dp->esd_recovery);
#endif
		s5p_dp_disable(dp);
	}

	return 0;
}
static int vib_suspend(struct device *dev)
{
	hrtimer_cancel(&misc_data->timer);
	vib_set(0);
	flush_delayed_work_sync(&misc_data->power_work);

	return 0;
}
static int __devexit pil_riva_remove(struct platform_device *pdev)
{
    struct riva_data *drv = platform_get_drvdata(pdev);
    flush_delayed_work_sync(&drv->work);
    wake_lock_destroy(&drv->wlock);
    clk_put(drv->xo);
    regulator_put(drv->pll_supply);
    return 0;
}
示例#5
0
static int capacity_set(void *data, u64 val)
{
	struct depl_driver *drv = data;

	drv->capacity = clamp_t(int, val, 0, 100);
	flush_delayed_work_sync(&drv->work);

	return 0;
}
示例#6
0
void snd_ak4114_reinit(struct ak4114 *chip)
{
    chip->init = 1;
    mb();
    flush_delayed_work_sync(&chip->work);
    ak4114_init_regs(chip);
    /* bring up statistics / event queing */
    chip->init = 0;
    if (chip->kctls[0])
        schedule_delayed_work(&chip->work, HZ / 10);
}
/**
 * exynos_drd_switch_set_peripheral -  bind/unbind the peripheral controller driver.
 *
 * @otg: Pointer to the usb_otg structure.
 * @gadget: pointer to the usb_gadget structure.
 *
 * Returns 0 on success otherwise negative errno.
 */
static int exynos_drd_switch_set_peripheral(struct usb_otg *otg,
        struct usb_gadget *gadget)
{
    struct exynos_drd_switch *drd_switch = container_of(otg,
                                           struct exynos_drd_switch, otg);
    struct exynos_drd *drd = container_of(drd_switch->core,
                                          struct exynos_drd, core);
    struct device *dev = otg->phy->dev;
    bool activate = false;
    unsigned long flags;


    if (gadget) {
        dev_dbg(dev, "Binding gadget %s\n", gadget->name);

        spin_lock_irqsave(&drd_switch->lock, flags);
        otg->gadget = gadget;
        /*
         * Prevents unnecessary activation of the work function.
         * If both peripheral and host are set or if we want to force
         * peripheral to run then we ensure that work function will
         * enter to valid state.
         */
        if (otg->host || (drd->pdata->quirks & FORCE_RUN_PERIPHERAL &&
                          drd_switch->id_state == B_DEV))
            activate = true;
        spin_unlock_irqrestore(&drd_switch->lock, flags);
    } else {
        dev_dbg(dev, "Unbinding gadget\n");

        /* put state machine into reset state */
        atomic_inc(&drd_switch->sm_reset);
        exynos_drd_switch_schedule_work(&drd_switch->work);
        flush_delayed_work_sync(&drd_switch->work);
        if (otg->phy->state != OTG_STATE_UNDEFINED)
            dev_err(dev, "%s: SM reset failed\n", __func__);

        spin_lock_irqsave(&drd_switch->lock, flags);
        otg->gadget = NULL;
        activate = true;
        spin_unlock_irqrestore(&drd_switch->lock, flags);

        atomic_dec(&drd_switch->sm_reset);
    }

    if (activate)
        exynos_drd_switch_schedule_work(&drd_switch->work);

    return 0;
}
void msm_pil_unregister(struct pil_device *pil)
{
	if (IS_ERR_OR_NULL(pil))
		return;

	if (get_device(&pil->dev)) {
		mutex_lock(&pil->lock);
		WARN_ON(pil->count);
		flush_delayed_work_sync(&pil->proxy);
		msm_pil_debugfs_remove(pil);
		device_unregister(&pil->dev);
		mutex_unlock(&pil->lock);
		put_device(&pil->dev);
	}
}
static int vib_remove(struct platform_device *pdev)
{
	struct vib_data *data = platform_get_drvdata(pdev);

	if (data->pdata->exit)
		data->pdata->exit();

	hrtimer_cancel(&data->timer);
	vib_set(0);
	flush_delayed_work_sync(&data->power_work);
	twl6040_free_irq(data->twl6040, TWL6040_IRQ_VIB, data);
	timed_output_dev_unregister(&data->dev);
	kfree(data);

	return 0;
}
/**
 * exynos_drd_switch_set_host -  bind/unbind the host controller driver.
 *
 * @otg: Pointer to the usb_otg structure.
 * @host: Pointer to the usb_bus structure.
 *
 * Returns 0 on success otherwise negative errno.
 */
static int exynos_drd_switch_set_host(struct usb_otg *otg, struct usb_bus *host)
{
    struct exynos_drd_switch *drd_switch = container_of(otg,
                                           struct exynos_drd_switch, otg);
    struct device *dev = otg->phy->dev;
    bool activate = false;
    unsigned long flags;

    if (host) {
        dev_dbg(dev, "Binding host %s\n", host->bus_name);

        spin_lock_irqsave(&drd_switch->lock, flags);
        otg->host = host;
        /*
         * Prevents unnecessary activation of the work function.
         * If both peripheral and host are set or if ID pin is low
         * then we ensure that work function will enter to valid state.
         */
        if (otg->gadget || drd_switch->id_state == A_DEV)
            activate = true;
        spin_unlock_irqrestore(&drd_switch->lock, flags);
    } else {
        dev_dbg(dev, "Unbinding host\n");

        /* put state machine into reset state */
        atomic_inc(&drd_switch->sm_reset);
        exynos_drd_switch_schedule_work(&drd_switch->work);
        flush_delayed_work_sync(&drd_switch->work);
        if (otg->phy->state != OTG_STATE_UNDEFINED)
            dev_err(dev, "%s: SM reset failed\n", __func__);

        spin_lock_irqsave(&drd_switch->lock, flags);
        otg->host = NULL;
        activate = true;
        spin_unlock_irqrestore(&drd_switch->lock, flags);

        atomic_dec(&drd_switch->sm_reset);
    }

    if (activate)
        exynos_drd_switch_schedule_work(&drd_switch->work);

    return 0;
}
static int apds9130_suspend(struct i2c_client *client, pm_message_t mesg)
{
    struct apds9130_data *data = i2c_get_clientdata(client);

    printk("[ProximitySensor] %s [%x][%d]\n", __func__, data->enable, data->irq_wake);

    disable_irq(data->irq);
    if( !enable_irq_wake(data->irq) )
        data->irq_wake = 1;

    flush_delayed_work_sync(&data->dwork);

    if( data->enable & 0x20 ) {
        apds9130_set_enable(client, 0x25);
    } else {
        apds9130_set_enable(client, 0);
    }

	return 0;
}
static void gdlm_unmount(struct gfs2_sbd *sdp)
{
	struct lm_lockstruct *ls = &sdp->sd_lockstruct;

	if (test_bit(DFL_NO_DLM_OPS, &ls->ls_recover_flags))
		goto release;

	/* wait for gfs2_control_wq to be done with this mount */

	spin_lock(&ls->ls_recover_spin);
	set_bit(DFL_UNMOUNT, &ls->ls_recover_flags);
	spin_unlock(&ls->ls_recover_spin);
	flush_delayed_work_sync(&sdp->sd_control_work);

	/* mounted_lock and control_lock will be purged in dlm recovery */
release:
	if (ls->ls_dlm) {
		dlm_release_lockspace(ls->ls_dlm, 2);
		ls->ls_dlm = NULL;
	}

	free_recover_size(ls);
}
static void gdlm_unmount(struct gfs2_sbd *sdp)
{
	struct lm_lockstruct *ls = &sdp->sd_lockstruct;

	if (test_bit(DFL_NO_DLM_OPS, &ls->ls_recover_flags))
		goto release;

	

	spin_lock(&ls->ls_recover_spin);
	set_bit(DFL_UNMOUNT, &ls->ls_recover_flags);
	spin_unlock(&ls->ls_recover_spin);
	flush_delayed_work_sync(&sdp->sd_control_work);

	
release:
	if (ls->ls_dlm) {
		dlm_release_lockspace(ls->ls_dlm, 2);
		ls->ls_dlm = NULL;
	}

	free_recover_size(ls);
}
/**
 * exynos_drd_switch_set_host -  bind/unbind the host controller driver.
 *
 * @otg: Pointer to the usb_otg structure.
 * @host: Pointer to the usb_bus structure.
 *
 * Returns 0 on success otherwise negative errno.
 */
static int exynos_drd_switch_set_host(struct usb_otg *otg, struct usb_bus *host)
{
	struct exynos_drd_switch *drd_switch = container_of(otg,
					struct exynos_drd_switch, otg);
	struct device *dev = otg->phy->dev;
	bool activate = false;
	unsigned long flags;

	if (host) {
		dev_dbg(dev, "Binding host %s\n", host->bus_name);

		spin_lock_irqsave(&drd_switch->lock, flags);
		otg->host = host;
		spin_unlock_irqrestore(&drd_switch->lock, flags);
	} else {
		dev_dbg(dev, "Unbinding host\n");

		/* put state machine into reset state */
		atomic_inc(&drd_switch->sm_reset);
		exynos_drd_switch_schedule_work(&drd_switch->work);
		flush_delayed_work_sync(&drd_switch->work);
		if (otg->phy->state != OTG_STATE_UNDEFINED)
			dev_err(dev, "%s: SM reset failed\n", __func__);

		spin_lock_irqsave(&drd_switch->lock, flags);
		otg->host = NULL;
		activate = true;
		spin_unlock_irqrestore(&drd_switch->lock, flags);

		atomic_dec(&drd_switch->sm_reset);
	}

	if (activate)
		exynos_drd_switch_schedule_work(&drd_switch->work);

	return 0;
}
/**
 * exynos_drd_switch_set_peripheral -  bind/unbind the peripheral controller driver.
 *
 * @otg: Pointer to the usb_otg structure.
 * @gadget: pointer to the usb_gadget structure.
 *
 * Returns 0 on success otherwise negative errno.
 */
static int exynos_drd_switch_set_peripheral(struct usb_otg *otg,
				struct usb_gadget *gadget)
{
	struct exynos_drd_switch *drd_switch = container_of(otg,
					struct exynos_drd_switch, otg);
	struct device *dev = otg->phy->dev;
	unsigned long flags;


	if (gadget) {
		dev_dbg(dev, "Binding gadget %s\n", gadget->name);

		spin_lock_irqsave(&drd_switch->lock, flags);
		otg->gadget = gadget;
		spin_unlock_irqrestore(&drd_switch->lock, flags);
	} else {
		dev_dbg(dev, "Unbinding gadget\n");

		/* put state machine into reset state */
		atomic_inc(&drd_switch->sm_reset);
		exynos_drd_switch_schedule_work(&drd_switch->work);
		flush_delayed_work_sync(&drd_switch->work);
		if (otg->phy->state != OTG_STATE_UNDEFINED)
			dev_err(dev, "%s: SM reset failed\n", __func__);

		spin_lock_irqsave(&drd_switch->lock, flags);
		otg->gadget = NULL;
		spin_unlock_irqrestore(&drd_switch->lock, flags);

		atomic_dec(&drd_switch->sm_reset);
	}

	exynos_drd_switch_schedule_work(&drd_switch->work);

	return 0;
}
/* LGE_CHANGE_E : LCD ESD Protection*/ 
static int mipi_lg4573b_lcd_on(struct platform_device *pdev)
{
	struct msm_fb_data_type *mfd;
	struct mipi_panel_info *mipi;
	int result=0;
/* LGE_CHANGE_S : LCD ESD Protection 
 * 2012-01-30, [email protected]
 * LCD ESD Protection
 */
#ifdef CONFIG_LGE_LCD_ESD_DETECTION
	bool int_en_wq_ret;
	if ( (!local_pdev_for_pwm) && (pdev) )
	{
		local_pdev_for_pwm = pdev;
	} 
#endif
/* LGE_CHANGE_E : LCD ESD Protection*/ 

	mfd = platform_get_drvdata(pdev);
	mipi  = &mfd->panel_info.mipi;

	if (!mfd)
		return -ENODEV;
	if (mfd->key != MFD_KEY)
		return -EINVAL;

	printk( "mipi_lg4573b_lcd_on START\n");
	
#ifndef CONFIG_FB_MSM_MIPI_DSI_LG4573B_BOOT_LOGO
	if(!lglogo_firstboot)
#endif
	{	
	#if 1//LGE_CHANGE_S [changbum.lee] 20120128 
	//jangsu.lee
// LGE_S, [email protected], 12-11-28 without this U0 JB does not go 1.8mA
#if 1 //defined(CONFIG_MACH_MSM7X27A_U0)
	udelay(500);//mdelay(1);//1
	gpio_set_value(GPIO_U0_LCD_RESET, 1);	
	msleep(10);	//10	
#endif
// LGE_E, [email protected], 12-11-28 without this U0 JB does not go 1.8mA
    #endif//LGE_CHANGE_E [changbum.lee] 20120128 
/* LGE_CHANGE_S : LCD ESD Protection 
 * 2012-01-30, [email protected]
 * LCD ESD Protection
 */
#ifdef CONFIG_LGE_LCD_ESD_DETECTION
	/*If any work pending flush it & disable irq */	
	int_en_wq_ret = cancel_delayed_work_sync(&lcd_esd->esd_det_work);
	int_en_wq_ret = cancel_delayed_work_sync(&lcd_esd->esd_dsi_panel_on);
	int_en_wq_ret = flush_delayed_work_sync(&lcd_esd->esd_int_en_work);
	if( true == int_en_wq_ret)
	{
		printk("Pending INTR EN work Finished \n");
	}			
	if( 1 == atomic_read(&lcd_esd->esd_irq_state))
	{
		disable_irq(lcd_esd->esd_irq);
		printk("ESD irq Disabled \n");
		atomic_set(&lcd_esd->esd_irq_state,0);
	}
#endif
/* LGE_CHANGE_E : LCD ESD Protection*/ 

	mipi_set_tx_power_mode(1);

	result=mipi_dsi_cmds_tx(&lg4573b_tx_buf, lg4573b_init_on_cmds,
			ARRAY_SIZE(lg4573b_init_on_cmds));

	mdelay(10);
	
	result=mipi_dsi_cmds_tx(&lg4573b_tx_buf, lg4573b_sleep_out_cmds,
			ARRAY_SIZE(lg4573b_sleep_out_cmds));

/*LGE_CHANGE_S, [email protected], 12-12-28, for V7 reduce the display time*/
#if !defined(CONFIG_MACH_MSM8X25_V7)
	/*[LGSI_SP4_BSP_BEGIN] [[email protected]]: Sometimes display is blank or distorted during bootlogo*/
	if(lglogo_firstboot){
		mdelay(120);
	}
	/*[LGSI_SP4_BSP_END] [[email protected]]*/
#endif
/*LGE_CHANGE_E, [email protected], 12-12-28, for V7 reduce the display time*/
	
	result=mipi_dsi_cmds_tx(&lg4573b_tx_buf, lg4573b_disp_on_cmds,
			ARRAY_SIZE(lg4573b_disp_on_cmds));

	mipi_set_tx_power_mode(0);
#ifdef CONFIG_LGE_LCD_ESD_DETECTION
	is_esd_occured = false;
#endif
/* LGE_CHANGE_S : LCD ESD Protection 
 * 2012-01-30, [email protected]
 * LCD ESD Protection
 */	
#ifdef CONFIG_LGE_LCD_ESD_DETECTION
/*Make Panel power off state to ZERO. So that esd irq can be enabled in int wq handler*/
	if(1 == atomic_read(&lcd_esd->panel_poweroff))
	{
		atomic_set(&lcd_esd->panel_poweroff,0);
	}
	/*Schedule work after 1 sec to enable ESD interrupt*/
	schedule_delayed_work(&lcd_esd->esd_int_en_work,ESD_INT_EN_DELAY);
#endif
/* LGE_CHANGE_E : LCD ESD Protection*/ 

	printk( "mipi_lg4573b_lcd_on FINISH\n");
	}

	/*LGE_CHANGE_S, [email protected], 13-01-03, for V7 lcd backlight timing code*/
	#if defined(CONFIG_MACH_MSM8X25_V7)
	lcd_on_completed = 1;
	#endif
	/*LGE_CHANGE_E, [email protected], 13-01-03, for V7 lcd backlight timing code*/
	return 0;
}
static int mipi_lg4573b_lcd_off(struct platform_device *pdev)
{
	struct msm_fb_data_type *mfd;
/* LGE_CHANGE_S : LCD ESD Protection 
 * LCD ESD Protection
 */
#ifdef CONFIG_LGE_LCD_ESD_DETECTION	
	bool int_en_wq_ret;
	bool panel_power_on_wq_ret;

	if ( (!local_pdev_for_pwm) && (pdev) )
	{
		local_pdev_for_pwm = pdev;
	}
#endif
/* LGE_CHANGE_E : LCD ESD Protection*/ 

	mfd = platform_get_drvdata(pdev);

	if (!mfd)
		return -ENODEV;
	if (mfd->key != MFD_KEY)
		return -EINVAL;

	printk(KERN_INFO "mipi_lg4573b_chip_lcd_off START\n");
/* LGE_CHANGE_S : LCD ESD Protection 
 * LCD ESD Protection
 */
#ifdef CONFIG_LGE_LCD_ESD_DETECTION
/*Set panel power off state to TRUE & flush the INTR EN Work queue*/
/*Don't enable esd irq in wq handler as we are powering off panel */	
	if( 0 == atomic_read(&lcd_esd->panel_poweroff) ) 
	{
		atomic_set(&lcd_esd->panel_poweroff,1);
	}
	int_en_wq_ret = flush_delayed_work_sync(&lcd_esd->esd_int_en_work);
	if ( true == int_en_wq_ret )
		printk("Waited for intr work to finish \n");
	panel_power_on_wq_ret = flush_delayed_work_sync(&lcd_esd->esd_dsi_panel_on);
	if( true == panel_power_on_wq_ret )
		printk("Waited for Panel On work to finish \n");
/*Disable ESD interrupt while powering off*/
	if( 1 == atomic_read(&lcd_esd->esd_irq_state))
	{
		disable_irq(lcd_esd->esd_irq);
		printk("ESD irq Disabled \n");
		atomic_set(&lcd_esd->esd_irq_state,0);
	}
#endif
/* LGE_CHANGE_E : LCD ESD Protection*/ 


//LGE_CHANGE_S [Kiran] Change LCD sleep sequence
	//display off
#ifdef CONFIG_LGE_LCD_ESD_DETECTION
	if(false == is_esd_occured)
#endif
	{
		mipi_dsi_cmds_tx(mfd, &lg4573b_tx_buf, lg4573b_disp_off_cmds,
			ARRAY_SIZE(lg4573b_disp_off_cmds));

		msleep(40);
	}
//LGE_CHANGE_E [Kiran] Change LCD sleep sequence
/*LCD Reset After data pulled Down*/
#if 0
	mipi_ldp_lcd_panel_poweroff();
#endif
/*LGE_CHANGE_E LCD Reset After Data Pulled Down*/
#ifdef CONFIG_FB_MSM_MIPI_DSI_LG4573B_BOOT_LOGO
	lglogo_firstboot = FALSE;
#endif
/*LCD off end Log added 27-01-2012*/	
	printk("End %s \n",__func__);
	return 0;
}
/* LGE_CHANGE_E : LCD ESD Protection*/ 
static int mipi_lg4573b_lcd_on(struct platform_device *pdev)
{
	struct msm_fb_data_type *mfd;
	struct mipi_panel_info *mipi;
	int result=0;
/* LGE_CHANGE_S : LCD ESD Protection 
 * LCD ESD Protection
 */
#ifdef CONFIG_LGE_LCD_ESD_DETECTION
	bool int_en_wq_ret;
	if ( (!local_pdev_for_pwm) && (pdev) )
	{
		local_pdev_for_pwm = pdev;
	} 
#endif
/* LGE_CHANGE_E : LCD ESD Protection*/ 

	mfd = platform_get_drvdata(pdev);
	mipi  = &mfd->panel_info.mipi;

	if (!mfd)
		return -ENODEV;
	if (mfd->key != MFD_KEY)
		return -EINVAL;

#ifdef CONFIG_FB_MSM_MIPI_DSI_LG4573B_BOOT_LOGO
	if(!lglogo_firstboot)
#endif
	{
	
	printk( "mipi_lg4573b_lcd_on START\n");
	#if 1//LGE_CHANGE_S [changbum.lee] 20120128 
	//jangsu.lee
	udelay(500);//mdelay(1);//1
	gpio_set_value(GPIO_U0_LCD_RESET, 1);	
	msleep(10);	//10	
    #endif//LGE_CHANGE_E [changbum.lee] 20120128 
/* LGE_CHANGE_S : LCD ESD Protection 
 * LCD ESD Protection
 */
#ifdef CONFIG_LGE_LCD_ESD_DETECTION
	/*If any work pending flush it & disable irq */	
	int_en_wq_ret = flush_delayed_work_sync(&lcd_esd->esd_int_en_work);
	if( true == int_en_wq_ret)
	{
		printk("Pending INTR EN work Finished \n");
	}			
	if( 1 == atomic_read(&lcd_esd->esd_irq_state))
	{
		disable_irq(lcd_esd->esd_irq);
		printk("ESD irq Disabled \n");
		atomic_set(&lcd_esd->esd_irq_state,0);
	}
#endif
/* LGE_CHANGE_E : LCD ESD Protection*/ 

	mipi_set_tx_power_mode(1);

	result=mipi_dsi_cmds_tx(mfd, &lg4573b_tx_buf, lg4573b_init_on_cmds,
			ARRAY_SIZE(lg4573b_init_on_cmds));

	mdelay(10);
	
	result=mipi_dsi_cmds_tx(mfd, &lg4573b_tx_buf, lg4573b_sleep_out_cmds,
			ARRAY_SIZE(lg4573b_sleep_out_cmds));

	//LGE_CHANGE_S [jangsu.lee] 20120130 : remove delay
	//mdelay(120);
	
	result=mipi_dsi_cmds_tx(mfd, &lg4573b_tx_buf, lg4573b_disp_on_cmds,
			ARRAY_SIZE(lg4573b_disp_on_cmds));

	mipi_set_tx_power_mode(0);
#ifdef CONFIG_LGE_LCD_ESD_DETECTION
	is_esd_occured = false;
#endif
/* LGE_CHANGE_S : LCD ESD Protection 
 * LCD ESD Protection
 */	
#ifdef CONFIG_LGE_LCD_ESD_DETECTION
/*Make Panel power off state to ZERO. So that esd irq can be enabled in int wq handler*/
	if(1 == atomic_read(&lcd_esd->panel_poweroff))
	{
		atomic_set(&lcd_esd->panel_poweroff,0);
	}
	/*Schedule work after 1 sec to enable ESD interrupt*/
	schedule_delayed_work(&lcd_esd->esd_int_en_work,ESD_INT_EN_DELAY);
#endif
/* LGE_CHANGE_E : LCD ESD Protection*/ 

	printk( "mipi_lg4573b_lcd_on FINISH\n");
	}
	return 0;
}
示例#19
0
void wcnss_flush_delayed_boot_votes()
{
	flush_delayed_work_sync(&penv->wcnss_work);
}
示例#20
0
文件: dmt08.c 项目: josh64x2/apc-rock
static void device_i2c_shutdown(struct i2c_client *client)
{
	flush_delayed_work_sync(&work);
	cancel_delayed_work_sync(&work);
}
static ssize_t pm8941_set_mode(struct device *ldev,
	struct device_attribute *attr, const char *buf, size_t size)
{
	struct pm8941_flash_data *data = dev_get_drvdata(ldev);
	unsigned long mode;
	int rc = 0;

	if (kstrtoul(buf, 10, &mode))
		return -EINVAL;

	if (mode >= FLASH_MODE_MAX)
		return -EINVAL;

	mutex_lock(&data->lock);

	if (data->scheduled) {
		mutex_unlock(&data->lock);
		flush_delayed_work_sync(&data->dwork);
		mutex_lock(&data->lock);
	} else {
		rc = pm_reg_masked_write(data, STROBE_CONTROL,
			ENABLE_CURRENT_OUT, DISABLE_CURRENT_OUT);
		if (rc)
			goto error;

		rc = pm_reg_write(data, ENABLE_CONTROL,
			MODULE_DISABLE | CURR_MAX_200mA);
		if (rc)
			goto error;

		rc = pm8941_regulator_disable(&data->spmi_dev->dev,
			&data->boost_for_torch);
		rc = rc ? rc :
			pm8941_regulator_disable(&data->spmi_dev->dev,
			&data->boost_for_flash);
		if (rc)
			goto exit;
	}

	switch (mode) {
	case FLASH_MODE_FLASH:
		rc = rc ? rc :
			pm8941_regulator_enable(&data->spmi_dev->dev,
				&data->boost_for_flash);
		rc = rc ? rc :
			pm_reg_write(data, TMR_CONTROL, ENABLE_FLASH_TIMER);
		rc = rc ? rc :
			pm_reg_write(data, VREG_OK_FORCE, 0x40);
		rc = rc ? rc :
			pm_reg_write(data, FAULT_DETECT, ENABLE_SELF_CHECK);
		rc = rc ? rc :
			pm_reg_write(data, MAX_CURRENT, 0x4F);
		rc = rc ? rc :
			pm_reg_write(data, ENABLE_CONTROL,
			MODULE_ENABLE | CURR_MAX_1A);
		rc = rc ? rc :
			pm_reg_masked_write(data, STROBE_CONTROL,
			ENABLE_CURRENT_OUT, ENABLE_CURRENT_OUT);

		if (!is_hw_strobe(data)) {
			data->scheduled = true;
			INIT_DELAYED_WORK(&data->dwork, flash_turn_off_delayed);
			schedule_delayed_work(&data->dwork,
				msecs_to_jiffies(data->turn_off_delay_ms));
		}
		break;
	case FLASH_MODE_TORCH:
		rc = rc ? rc :
			pm_reg_masked_write(data, STROBE_CONTROL,
				STROBE_SELECT_HW, STROBE_SELECT_SW);
		rc = rc ? rc :
			pm8941_regulator_enable(&data->spmi_dev->dev,
				&data->boost_for_torch);
		rc = rc ? rc :
			pm_reg_write(data, MAX_CURRENT, 0xF);
		rc = rc ? rc :
			pm_reg_write(data, TMR_CONTROL, ENABLE_WATCHDOG_TIMER);
		rc = rc ? rc :
			pm_reg_write(data, ENABLE_CONTROL,
			MODULE_ENABLE | CURR_MAX_200mA);
		rc = rc ? rc :
			pm_reg_masked_write(data, STROBE_CONTROL,
			ENABLE_CURRENT_OUT, ENABLE_CURRENT_OUT);
		break;
	case FLASH_MODE_NONE:
	default:
		break;
	}
error:
	if (rc)
		pm8941_dev_err(data, "reg write failed(%d)\n", rc);
exit:
	mutex_unlock(&data->lock);

	return rc ? rc : size;
}
示例#22
0
static int sdhci_pltfm_suspend(struct platform_device *pdev, pm_message_t state)
{
	struct sdio_dev *dev = platform_get_drvdata(pdev);
	struct sdhci_host *host = dev->host;

	if (dev->devtype == SDIO_DEV_TYPE_WIFI) {
		host->mmc->pm_flags |= host->mmc->pm_caps;
		printk(KERN_DEBUG "%s: pm_flags=0x%08x\n",
			__FUNCTION__, host->mmc->pm_flags);
		sdhci_suspend_host(host, state);
	}
#if 0
	if (dev->devtype == SDIO_DEV_TYPE_SDMMC && dev->cd_gpio >= 0)
		free_irq(gpio_to_irq(dev->cd_gpio), dev);
#endif

	flush_work_sync(&host->wait_erase_work);
	/*
	 * If the device type is WIFI, and WiFi is enabled,
	 * turn off the clock since currently
	 * the WIFI driver does not support turning on/off the
	 * clock dynamicly.
	 */
	if (dev->devtype == SDIO_DEV_TYPE_WIFI && sdhci_test_sdio_enabled(dev))
		sdhci_pltfm_clk_enable(host, 0);
	
	/*
	 *   Move Dynamic Power Management State machine to OFF state to
	 *   ensure the SD card regulators are turned-off during suspend.
	 *
	 * State Machine:
	 *
	 *   ENABLED -> DISABLED ->  OFF
	 *     ^___________|          |
	 *     |______________________|
	 *
	 *  Delayed workqueue host->mmc->disable (mmc_host_deeper_disable) is
	 *  scheduled twice:
	 *  mmc_host_lazy_disable queues host->mmc->disable for 100ms delay
	 *  1st Entry(after 100ms):  work function(mmc_host_deeper_disable)
	 *  moves the DPM state: ENABLED -> DISABLED [lazy disable] and
	 *  and queues the workqueue host->mmc->disable again for 8s delay
	 *
	 * 2nd Entry(after 8s): work function(mmc_host_deeper_disable) moves
	 * the DPM state: DISABLED ->  OFF [deeper disable] this time to
	 * turn-off the SD card/IO regulators.
	 *
	 * We need to call flush_delayed_work_sync twice to ensure the SD card
	 * DPM is moved to OFF state.
	 *
	 */
	flush_delayed_work_sync(&host->mmc->disable);
	flush_delayed_work_sync(&host->mmc->disable);

	dev->suspended = 1;
	if(dev->devtype == SDIO_DEV_TYPE_SDMMC)
	{
		mdelay(STABLE_TIME_BEFORE_SUSPEND_MS);
	}

	return 0;
}
static int __devinit pil_riva_probe(struct platform_device *pdev)
{
    struct riva_data *drv;
    struct resource *res;
    struct pil_desc *desc;
    int ret;

    res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
    if (!res)
        return -EINVAL;

    drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL);
    if (!drv)
        return -ENOMEM;
    platform_set_drvdata(pdev, drv);

    drv->base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
    if (!drv->base)
        return -ENOMEM;

    desc = devm_kzalloc(&pdev->dev, sizeof(*desc), GFP_KERNEL);
    if (!desc)
        return -ENOMEM;

    drv->pll_supply = regulator_get(&pdev->dev, "pll_vdd");
    if (IS_ERR(drv->pll_supply)) {
        dev_err(&pdev->dev, "failed to get pll supply\n");
        return PTR_ERR(drv->pll_supply);
    }
    ret = regulator_set_voltage(drv->pll_supply, 1800000, 1800000);
    if (ret) {
        dev_err(&pdev->dev, "failed to set pll supply voltage\n");
        goto err;
    }

    ret = regulator_set_optimum_mode(drv->pll_supply, 100000);
    if (ret < 0) {
        dev_err(&pdev->dev, "failed to set pll supply optimum mode\n");
        goto err;
    }

    desc->name = "wcnss";
    desc->dev = &pdev->dev;

    if (pas_supported(PAS_RIVA) > 0) {
        desc->ops = &pil_riva_ops_trusted;
        dev_info(&pdev->dev, "using secure boot\n");
    } else {
        desc->ops = &pil_riva_ops;
        dev_info(&pdev->dev, "using non-secure boot\n");
    }

    drv->xo = clk_get(&pdev->dev, "cxo");
    if (IS_ERR(drv->xo)) {
        ret = PTR_ERR(drv->xo);
        goto err;
    }
    wake_lock_init(&drv->wlock, WAKE_LOCK_SUSPEND, "riva-wlock");
    INIT_DELAYED_WORK(&drv->work, pil_riva_remove_proxy_votes);

    ret = msm_pil_register(desc);
    if (ret)
        goto err_register;
    return 0;
err_register:
    flush_delayed_work_sync(&drv->work);
    wake_lock_destroy(&drv->wlock);
    clk_put(drv->xo);
err:
    regulator_put(drv->pll_supply);
    return ret;
}