Ejemplo n.º 1
0
Archivo: core.c Proyecto: Addision/LVS
static int __init mmc_init(void)
{
	int ret;

	workqueue = create_freezeable_workqueue("kmmcd");
	if (!workqueue)
		return -ENOMEM;

	ret = mmc_register_bus();
	if (ret)
		goto destroy_workqueue;

	ret = mmc_register_host_class();
	if (ret)
		goto unregister_bus;

	ret = sdio_register_bus();
	if (ret)
		goto unregister_host_class;

	return 0;

unregister_host_class:
	mmc_unregister_host_class();
unregister_bus:
	mmc_unregister_bus();
destroy_workqueue:
	destroy_workqueue(workqueue);

	return ret;
}
Ejemplo n.º 2
0
//end
static int __init mmc_init(void)
{
	int ret;

	wake_lock_init(&mmc_delayed_work_wake_lock, WAKE_LOCK_SUSPEND, "mmc_delayed_work");

	workqueue = create_freezeable_workqueue("kmmcd");
	if (!workqueue)
		return -ENOMEM;

	ret = mmc_register_bus();
	if (ret)
		goto destroy_workqueue;

	ret = mmc_register_host_class();
	if (ret)
		goto unregister_bus;

	ret = sdio_register_bus();
	if (ret)
		goto unregister_host_class;

	return 0;

unregister_host_class:
	mmc_unregister_host_class();
unregister_bus:
	mmc_unregister_bus();
destroy_workqueue:
	destroy_workqueue(workqueue);

	return ret;
}
Ejemplo n.º 3
0
static int __devinit smb328a_probe(struct i2c_client *client,
			 const struct i2c_device_id *id)
{
	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
	struct smb328a_platform_data *pdata = client->dev.platform_data;
	int ret;

	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
		return -EIO;

	printk("+++++++++++++++ %s +++++++++++++++\n", __func__);

	smb328a_i2c_client = client;

	pdata->start_charging = smb328a_start_charging;
	pdata->stop_charging = smb328a_stop_charging;
	pdata->get_vbus_status = smb328a_get_vbus_status;

	INIT_WORK(&chg_work, _smb328a_chg_work);
	setup_timer(&chg_work_timer, _smb328a_chg_work_timer_func, (unsigned long)pdata);
	chg_wqueue = create_freezeable_workqueue("smb328a_wqueue");

	ret = request_threaded_irq(client->irq, NULL, _smb328a_isr,
				   IRQF_TRIGGER_RISING,
				   "smb328a-isr", pdata);

	_smb328a_print_register();
	return 0;
}
Ejemplo n.º 4
0
static int ksuspend_usb_init(void)
{
	
	ksuspend_usb_wq = create_freezeable_workqueue("ksuspend_usbd");
	if (!ksuspend_usb_wq)
		return -ENOMEM;
	return 0;
}
static int bu92747_irda_startup(struct uart_port *port)
{
	struct bu92747_port *s = container_of(port,
						  struct bu92747_port,
						  port);
	char b[32];
	struct rev_frame_length *f = &(s->rev_frames);

	BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__);
	dev_dbg(s->dev, "%s\n", __func__);

	s->baud = 9600;
	s->rx_enabled = 1;
	
	spin_lock(&s->data_lock);
	frame_length_buf_clear(f);
	s->cur_frame_length = 0;
	spin_unlock(&s->data_lock);

	if (s->suspending)
		return 0;

	s->tx_empty = 1;
	s->force_end_work = 0;

	sprintf(b, "bu92747_irda-%d", s->minor);
	s->workqueue = create_freezeable_workqueue(b);
	if (!s->workqueue) {
		dev_warn(s->dev, "cannot create workqueue\n");
		return -EBUSY;
	}
	INIT_WORK(&s->work, bu92747_irda_work);

	//atomic_set(&(s->data_ready), 0);

	if (request_irq(s->irq, bu92747_irda_irq,
			IRQ_TYPE_LEVEL_LOW, "bu92747_irda", s) < 0) {
		dev_warn(s->dev, "cannot allocate irq %d\n", s->irq);
		s->irq = 0;
		destroy_workqueue(s->workqueue);
		s->workqueue = NULL;
		return -EBUSY;
	}

	disable_irq(s->irq);

	if (s->pdata->irda_pwr_ctl)
		s->pdata->irda_pwr_ctl(1);

	irda_hw_startup();
	irda_hw_set_moderx();

	enable_irq(s->irq);

	return 0;
}
Ejemplo n.º 6
0
static int ksuspend_usb_init(void)
{
	/* This workqueue is supposed to be both freezable and
	 * singlethreaded.  Its job doesn't justify running on more
	 * than one CPU.
	 */
	ksuspend_usb_wq = create_freezeable_workqueue("ksuspend_usbd");
	if (!ksuspend_usb_wq)
		return -ENOMEM;
	return 0;
}
Ejemplo n.º 7
0
static int sc16is7x2_startup(struct uart_port *port)
{
	struct sc16is7x2_channel *chan = to_sc16is7x2_channel(port);
	struct sc16is7x2_chip *ts = chan->chip;
	unsigned ch = (&ts->channel[1] == chan) ? 1 : 0;
	unsigned long flags;

	dev_dbg(&ts->spi->dev, "\n%s (%d)\n", __func__, port->line);

	/* Clear the interrupt registers. */
	sc16is7x2_write(ts, UART_IER, ch, 0);
	sc16is7x2_read_status(ts, ch);

	/* Initialize work queue */
	chan->workqueue = create_freezeable_workqueue("sc16is7x2");
	if (!chan->workqueue) {
		dev_err(&ts->spi->dev, "Workqueue creation failed\n");
		return -EBUSY;
	}
	INIT_WORK(&chan->work, sc16is7x2_handle_channel);

	/* Setup IRQ. Actually we have a low active IRQ, but we want
	 * one shot behaviour */
	if (request_irq(ts->spi->irq, sc16is7x2_irq,
			IRQF_TRIGGER_FALLING | IRQF_SHARED,
			"sc16is7x2", chan)) {
		dev_err(&ts->spi->dev, "IRQ request failed\n");
		destroy_workqueue(chan->workqueue);
		chan->workqueue = NULL;
		return -EBUSY;
	}


	spin_lock_irqsave(&chan->uart.lock, flags);
	chan->lcr = UART_LCR_WLEN8;
	chan->mcr = 0;
	chan->fcr = 0;
	chan->ier = UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI;
	spin_unlock_irqrestore(&chan->uart.lock, flags);

	sc16is7x2_write(ts, UART_FCR, ch, UART_FCR_ENABLE_FIFO |
		       UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
	sc16is7x2_write(ts, UART_FCR, ch, chan->fcr);
	/* Now, initialize the UART */
	sc16is7x2_write(ts, UART_LCR, ch, chan->lcr);
	sc16is7x2_write(ts, UART_MCR, ch, chan->mcr);
	sc16is7x2_write(ts, UART_IER, ch, chan->ier);

	return 0;
}
Ejemplo n.º 8
0
static int __init mmc_init(void)
{
	int ret;

	wake_lock_init(&mmc_delayed_work_wake_lock, WAKE_LOCK_SUSPEND, "mmc_delayed_work");

    /* FIH, BillHJChang, 2009/11/20 { */
	/* [FXX_CR], issue of card detect fail in suspend mode */
	#ifdef CONFIG_FIH_FXX
	wake_lock_init(&sdcard_idle_wake_lock, WAKE_LOCK_IDLE, "sd_suspend_work");	
	#endif
	/* } FIH, BillHJChang, 2009/11/20 */

    /* FIH, SimonSSChang, 2010/08/25 { */
    /* avoid WIFI firmware reload fail when to do kernel resume */
    #ifdef CONFIG_FIH_FXX
	workqueue = create_singlethread_workqueue("kmmcd");
    #else
	workqueue = create_freezeable_workqueue("kmmcd");    
    #endif
    /* } FIH, SimonSSChang, 2010/08/25 */
	if (!workqueue)
		return -ENOMEM;

	ret = mmc_register_bus();
	if (ret)
		goto destroy_workqueue;

	ret = mmc_register_host_class();
	if (ret)
		goto unregister_bus;

	ret = sdio_register_bus();
	if (ret)
		goto unregister_host_class;

	return 0;

unregister_host_class:
	mmc_unregister_host_class();
unregister_bus:
	mmc_unregister_bus();
destroy_workqueue:
	destroy_workqueue(workqueue);

	return ret;
}
Ejemplo n.º 9
0
static int __devinit fan5403_probe(struct i2c_client *client,
			 const struct i2c_device_id *id)
{
	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
	struct fan5403_platform_data *pdata = client->dev.platform_data;
	int ret;

	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
		return -EIO;

	pr_info("+++++++++++++++ %s +++++++++++++++\n", __func__);

	fan5403_i2c_client = client;

	/* Init Rx functions from host */
	pdata->start_charging = fan5403_start_charging;
	pdata->stop_charging = fan5403_stop_charging;
	pdata->get_vbus_status = fan5403_get_vbus_status;
	pdata->set_host_status = fan5403_set_host_status;
	pdata->get_monitor_bits = fan5403_get_monitor_bits;

	INIT_WORK(&chg_work, _fan5403_chg_work);
	setup_timer(&chg_work_timer, _fan5403_chg_work_timer_func, (unsigned long)pdata);
	chg_wqueue = create_freezeable_workqueue("fan5403_wqueue");

	if (HWREV == 0x1) {	/* REV0.5 */
		ret = request_threaded_irq(client->irq, NULL, _fan5403_handle_stat,
					   (IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING),
					   "fan5403-stat", pdata);
	}

	_fan5403_customize_register_settings();
	_fan5403_print_register();

	return 0;
}
Ejemplo n.º 10
0
static int __init pm_start_workqueue(void)
{
	pm_wq = create_freezeable_workqueue("pm");

	return pm_wq ? 0 : -ENOMEM;
}
Ejemplo n.º 11
0
static int __devinit omapl_pru_can_probe(struct platform_device *pdev)
{
	struct net_device *ndev = NULL;
	struct omapl_pru_can_priv *priv = NULL;
	struct ti_pru_can_platform_data *pdata;
	struct resource *res_mem, *trx_irq;
	pru_can_firmware_structure fw_pru;
	u32 err, retries = 0;

	pdata = pdev->dev.platform_data;
	if (!pdata) {
		dev_err(&pdev->dev, "no platform data provided for pru!\n");
		return -ENODEV;
	}

	res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res_mem) {
		dev_err(&pdev->dev, "unable to get pru memory resources!\n");
		err = -ENODEV;
		goto probe_exit;
	}

	trx_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!trx_irq) {
		dev_err(&pdev->dev, "unable to get pru interrupt resources!\n");
		err = -ENODEV;
		goto probe_exit;
	}

	if (!request_mem_region(res_mem->start, resource_size(res_mem),
				dev_name(&pdev->dev))) {
		dev_err(&pdev->dev, "pru memory region already claimed!\n");
		err = -EBUSY;
		goto probe_exit;
	}

	ndev = alloc_candev(sizeof(struct omapl_pru_can_priv), MB_MAX + 1);
	if (!ndev) {
		dev_err(&pdev->dev, "alloc_candev failed\n");
		err = -ENOMEM;
		goto probe_exit_free_region;
	}
	priv = netdev_priv(ndev);

	priv->pru_arm_iomap.pru_io_addr =
	    ioremap(res_mem->start, resource_size(res_mem));
	if (!priv->pru_arm_iomap.pru_io_addr) {
		dev_err(&pdev->dev, "ioremap failed\n");
		err = -ENOMEM;
		goto probe_exit_free_region;
	}

	priv->pru_arm_iomap.psc0_io_addr = IO_ADDRESS(DA8XX_PSC0_BASE);
	if (!priv->pru_arm_iomap.psc0_io_addr) {
		dev_err(&pdev->dev, "ioremap failed\n");
		err = -ENOMEM;
		goto probe_exit_iounmap;
	}

	priv->pru_arm_iomap.psc1_io_addr = IO_ADDRESS(DA8XX_PSC1_BASE);
	if (!priv->pru_arm_iomap.psc1_io_addr) {
		dev_err(&pdev->dev, "ioremap failed\n");
		err = -ENOMEM;
		goto probe_exit_iounmap;
	}

	priv->pru_arm_iomap.syscfg_io_addr = IO_ADDRESS(DA8XX_SYSCFG0_BASE);
	if (!priv->pru_arm_iomap.syscfg_io_addr) {
		dev_err(&pdev->dev, "ioremap failed\n");
		err = -ENOMEM;
		goto probe_exit_iounmap;
	}

	priv->ndev = ndev;
	priv->trx_irq = trx_irq->start;

	priv->can.bittiming_const = NULL;
	priv->can.do_set_bittiming = omapl_pru_can_set_bittiming;
	priv->can.do_set_mode = omapl_pru_can_set_mode;
	priv->can.do_get_state = omapl_pru_can_get_state;
	priv->can_tx_hndl.u8prunumber = CAN_TX_PRU_1;
	priv->can_rx_hndl.u8prunumber = CAN_RX_PRU_0;

	ndev->flags |= (IFF_ECHO | IFF_NOARP);	/* we support local echo, no arp */
	platform_set_drvdata(pdev, ndev);
	SET_NETDEV_DEV(ndev, &pdev->dev);
	ndev->netdev_ops = &omapl_pru_can_netdev_ops;

	priv->clk = clk_get(&pdev->dev, "pru_ck");
	if (IS_ERR(priv->clk)) {
		dev_err(&pdev->dev, "no clock available\n");
		err = PTR_ERR(priv->clk);
		priv->clk = NULL;
		goto probe_exit_candev;
	}
	priv->can.clock.freq = clk_get_rate(priv->clk);

	priv->clk_timer = clk_get(&pdev->dev, "pll1_sysclk2");
	if (IS_ERR(priv->clk_timer)) {
		dev_err(&pdev->dev, "no timer clock available\n");
		err = PTR_ERR(priv->clk_timer);
		priv->clk_timer = NULL;
		goto probe_exit_candev;
	}
	priv->timer_freq = clk_get_rate(priv->clk_timer);

	err = register_candev(ndev);
	if (err) {
		dev_err(&pdev->dev, "register_candev() failed\n");
		err = -ENODEV;
		goto probe_exit_clk;
	}

	err = request_firmware(&priv->fw_tx, "PRU_CAN_Emulation_Tx.bin",
			       &pdev->dev);
	if (err) {
		dev_err(&pdev->dev, "can't load firmware\n");
		err = -ENODEV;
		goto probe_exit_clk;
	}

	dev_info(&pdev->dev, "fw_tx size %d. downloading...\n",
		 priv->fw_tx->size);

	err = request_firmware(&priv->fw_rx, "PRU_CAN_Emulation_Rx.bin",
			       &pdev->dev);
	if (err) {
		dev_err(&pdev->dev, "can't load firmware\n");
		err = -ENODEV;
		goto probe_release_fw;
	}
	dev_info(&pdev->dev, "fw_rx size %d. downloading...\n",
		 priv->fw_rx->size);

	fw_pru.ptr_pru1 = kmalloc(priv->fw_tx->size, GFP_KERNEL);
	memcpy((void *)fw_pru.ptr_pru1, (const void *)priv->fw_tx->data,
	       priv->fw_tx->size);
	fw_pru.u32_pru1_code_size = priv->fw_tx->size;
	fw_pru.ptr_pru0 = kmalloc(priv->fw_rx->size, GFP_KERNEL);
	memcpy((void *)fw_pru.ptr_pru0, (const void *)priv->fw_rx->data,
	       priv->fw_rx->size);
	fw_pru.u32_pru0_code_size = priv->fw_rx->size;

	/* init the pru */
	pru_can_emulation_init(&priv->pru_arm_iomap, priv->can.clock.freq);

	while ((pru_can_check_init_status()) && (retries++ < MAX_INIT_RETRIES))
		udelay(retries);

	if (MAX_INIT_RETRIES <= retries) {
		dev_err(&pdev->dev, "failed to initialize the pru\n");
		err = -ENODEV;
		goto probe_release_fw_1;
	}

	pru_can_enable();
	/* download firmware into pru */
	err = pru_can_download_firmware(&fw_pru, 0);
	if (err) {
		dev_err(&pdev->dev, "firmware download error\n");
		err = -ENODEV;
		goto probe_release_fw_1;
	}
	err = pru_can_download_firmware(&fw_pru, 1);
	if (err) {
		dev_err(&pdev->dev, "firmware download error\n");
		err = -ENODEV;
		goto probe_release_fw_1;
	}

	if (pru_can_calculatetiming (DFLT_PRU_FREQ, DFLT_PRU_BITRATE) != 0) {
        return -EINVAL;
    }

	pru_can_run(0);
	pru_can_run(1);
	kfree((const void *)fw_pru.ptr_pru0);
	kfree((const void *)fw_pru.ptr_pru1);

	/*Create The Work Queue */
	if ((priv->pru_can_wQ =
	     create_freezeable_workqueue("omapl_pru_wQ")) == NULL)
		dev_err(&pdev->dev, "failed to create work queue\n");

	INIT_WORK(&priv->rx_work, omapl_pru_can_rx_wQ);
	dev_info(&pdev->dev,
		 "%s device registered"
		 "(&reg_base=0x%p, trx_irq = %d,  clk = %d)\n",
		 DRV_NAME, priv->pru_arm_iomap.pru_io_addr, priv->trx_irq,
		 priv->can.clock.freq);
	return 0;

probe_release_fw_1:
	kfree((const void *)fw_pru.ptr_pru0);
	kfree((const void *)fw_pru.ptr_pru1);
	release_firmware(priv->fw_rx);
probe_release_fw:
	release_firmware(priv->fw_tx);
probe_exit_clk:
	clk_put(priv->clk);
probe_exit_candev:
	if (NULL != ndev)
		free_candev(ndev);
probe_exit_iounmap:
	iounmap(priv->pru_arm_iomap.pru_io_addr);
probe_exit_free_region:
	release_mem_region(res_mem->start, resource_size(res_mem));
probe_exit:
	return err;
}
Ejemplo n.º 12
0
static int __devinit max17040_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
    struct input_dev *input_data = NULL;	
	int ret;
#if 0	
	int aflag=0;
#endif
	sleep_dbg("[MAX17040] max17040_probe [IN]\n");	
	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
		return -EIO;

	max17040_data.client = client;
	i2c_set_clientdata(client, &max17040_data);
	//sys file system are registered
	max17040_data.battery.name		= "batterys";
	max17040_data.battery.type		= POWER_SUPPLY_TYPE_BATTERY;
	max17040_data.battery.get_property	= max17040_get_property;
	max17040_data.battery.properties	= max17040_battery_props;
	max17040_data.battery.external_power_changed = max17040_bat_external_power_changed;
	max17040_data.battery.num_properties	= ARRAY_SIZE(max17040_battery_props);
	ret = power_supply_register(&client->dev, &max17040_data.battery);
	if (ret) {
		sleep_dbg("[MAX17040] failed: power supply register [ERROR]\n");			
		i2c_set_clientdata(client, NULL);
		return ret;
	}
	//The code used in the test mode [TEST MODE]	
	ret = sysfs_create_group(&client->dev.kobj, &max17040_attr_group);	
	if (ret) {
		sleep_dbg("[MAX17040] failed: sysfs_create_group  [ERROR]\n");					
	}	
	//mutex is init
	mutex_init(&max17040_data.data_mutex);
	mutex_init(&max17040_data.i2c_mutex);	
	mutex_init(&max17040_data.quick_mutex);		
	//rcomp is set
	max17040_set_rcomp();
	//Version of reading
	max17040_get_version();
	//read vell and soc 
	max17040_quick_get_vcell();
	max17040_quick_get_soc();

#if 0	
	//check quick start
	aflag=max17040_check_restart(max17040_data.quick_data.quick_vcell,max17040_data.quick_data.quick_soc);
	if(aflag)
	{
	max17040_restart();	
	msleep(300); //quick start update time
	}
#endif

	//The code used in the test mode [TEST MODE]
	atomic_set(&max17040_data.set_test, 0);		
    input_data = input_allocate_device();
  if (!input_data) {
        sleep_dbg("MAX17040: Unable to input_allocate_device \n");  	
		return -1;
    }
	
    set_bit(EV_REL,input_data->evbit);
    input_set_capability(input_data, EV_REL, REL_RX);	
    input_set_capability(input_data, EV_REL, REL_RY); /* wake */	
    input_set_capability(input_data, EV_REL, REL_RZ); /* wake */
	input_data->name="max17040";
    ret =input_register_device(input_data);
    if (ret) {
        sleep_dbg("MAX17040: Unable to register input_data device\n");
		return -1;
    }
    input_set_drvdata(input_data, &max17040_data);	
	max17040_data.max17040_input_data=input_data;
	//initialize workqueue and alarm setting
	wake_lock_init(&max17040_data.work_wake_lock, WAKE_LOCK_SUSPEND,
			"max17040-battery");


#ifdef MAX17040_ALARM_RTC_ENABLE
	max17040_data.last_poll=alarm_get_elapsed_realtime();	
	INIT_WORK(&max17040_data.monitor_work, max17040_work);
	max17040_data.monitor_wqueue = create_freezeable_workqueue("max17040");
	/* init to something sane */
	if (!max17040_data.monitor_wqueue) {
		sleep_dbg("fail_workqueue Error [PROBE FUNCTION]");
		return -1;
	}
	alarm_init(&max17040_data.alarm, ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP,
			max_battery_alarm_callback);
	//prevent suspend
	max17040_prevent_suspend();
#ifdef CONFIG_HAS_EARLYSUSPEND
	max17040_data.early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN;
	max17040_data.early_suspend.suspend = max17040_batt_early_suspend;
	max17040_data.early_suspend.resume = max17040_batt_late_resume;
	dbg("set max17040 EARLY_SUSPEND\n");	
	register_early_suspend(&max17040_data.early_suspend);
#endif	//CONFIG_HAS_EARLYSUSPEND
	queue_work(max17040_data.monitor_wqueue, &max17040_data.monitor_work);
	
#else
	INIT_DELAYED_WORK_DEFERRABLE(&max17040_data.work, max17040_work);
	schedule_delayed_work(&max17040_data.work, 0);
#endif //MAX17040_ALARM_RTC_ENABLE
	sleep_dbg("[MAX17040] max17040_probe [OUT]\n");	
	return 0;
}
Ejemplo n.º 13
0
static __devinit int max8998_charger_probe(struct platform_device *pdev)
{
	struct max8998_dev *iodev = dev_get_drvdata(pdev->dev.parent);
	struct max8998_platform_data *pdata = dev_get_platdata(iodev->dev);
	struct chg_data *chg;
        struct i2c_client *i2c = iodev->i2c;
	int ret = 0;

	bat_info("%s : MAX8998 Charger Driver Loading\n", __func__);

	chg = kzalloc(sizeof(*chg), GFP_KERNEL);
	if (!chg)
		return -ENOMEM;

	chg->iodev = iodev;
	chg->pdata = pdata->charger;

	if (!chg->pdata || !chg->pdata->adc_table) {
		pr_err("%s : No platform data & adc_table supplied\n", __func__);
		ret = -EINVAL;
		goto err_bat_table;
	}

	chg->psy_bat.name = "battery";
	chg->psy_bat.type = POWER_SUPPLY_TYPE_BATTERY;
	chg->psy_bat.properties = max8998_battery_props;
	chg->psy_bat.num_properties = ARRAY_SIZE(max8998_battery_props);
	chg->psy_bat.get_property = s3c_bat_get_property;

	chg->psy_usb.name = "usb";
	chg->psy_usb.type = POWER_SUPPLY_TYPE_USB;
	chg->psy_usb.supplied_to = supply_list;
	chg->psy_usb.num_supplicants = ARRAY_SIZE(supply_list);
	chg->psy_usb.properties = s3c_power_properties;
	chg->psy_usb.num_properties = ARRAY_SIZE(s3c_power_properties);
	chg->psy_usb.get_property = s3c_usb_get_property;

	chg->psy_ac.name = "ac";
	chg->psy_ac.type = POWER_SUPPLY_TYPE_MAINS;
	chg->psy_ac.supplied_to = supply_list;
	chg->psy_ac.num_supplicants = ARRAY_SIZE(supply_list);
	chg->psy_ac.properties = s3c_power_properties;
	chg->psy_ac.num_properties = ARRAY_SIZE(s3c_power_properties);
	chg->psy_ac.get_property = s3c_ac_get_property;

	chg->present = 1;
	chg->bat_info.batt_health = POWER_SUPPLY_HEALTH_GOOD;
	chg->bat_info.batt_is_full = false;
	chg->set_batt_full = false;
	chg->set_charge_timeout = false;

	chg->cable_status = CABLE_TYPE_NONE;
	chg->esafe = MAX8998_USB_VBUS_AP_ON;

	mutex_init(&chg->mutex);

	platform_set_drvdata(pdev, chg);

	ret = max8998_write_reg(i2c, MAX8998_REG_IRQM1,
		~(MAX8998_IRQ_DCINR_MASK | MAX8998_IRQ_DCINF_MASK));
	if (ret < 0)
		goto err_kfree;

	ret = max8998_write_reg(i2c, MAX8998_REG_IRQM2, 0xFF);
	if (ret < 0)
		goto err_kfree;

#ifdef TOPOFF_CURRENT_CHECK
	ret = max8998_write_reg(i2c, MAX8998_REG_IRQM3, 0xFF);
#else
	ret = max8998_write_reg(i2c, MAX8998_REG_IRQM3, ~MAX8998_IRQ_TOPOFFR_MASK);
#endif
	if (ret < 0)
		goto err_kfree;

	ret = max8998_write_reg(i2c, MAX8998_REG_IRQM4,
		~(MAX8998_IRQ_LOBAT2_MASK | MAX8998_IRQ_LOBAT1_MASK));
	if (ret < 0)
		goto err_kfree;

	ret = max8998_update_reg(i2c, MAX8998_REG_ONOFF3,
		(1 << MAX8998_SHIFT_ENBATTMON), MAX8998_MASK_ENBATTMON);
	if (ret < 0)
		goto err_kfree;

	ret = max8998_update_reg(i2c, MAX8998_REG_LBCNFG1, 0x7, 0x37); //3.57V
	if (ret < 0)
		goto err_kfree;

	ret = max8998_update_reg(i2c, MAX8998_REG_LBCNFG2, 0x5, 0x37); //3.4V
	if (ret < 0)
		goto err_kfree;

	max8998_lowbat_config(chg, 0);

	wake_lock_init(&chg->vbus_wake_lock, WAKE_LOCK_SUSPEND, "vbus_present");
	wake_lock_init(&chg->work_wake_lock, WAKE_LOCK_SUSPEND, "max8998-charger");
	wake_lock_init(&chg->lowbat_wake_lock, WAKE_LOCK_SUSPEND, "max8998-lowbat");

	INIT_WORK(&chg->bat_work, s3c_bat_work);
	setup_timer(&chg->bat_work_timer, s3c_bat_work_timer_func, (unsigned long)chg);

	chg->monitor_wqueue = create_freezeable_workqueue(dev_name(&pdev->dev));
	if (!chg->monitor_wqueue) {
		pr_err("%s : Failed to create freezeable workqueue\n", __func__);
		ret = -ENOMEM;
		goto err_wake_lock;
	}

	check_lpm_charging_mode(chg);

	/* init power supplier framework */
	ret = power_supply_register(&pdev->dev, &chg->psy_bat);
	if (ret) {
		pr_err("%s : Failed to register power supply psy_bat\n", __func__);
		goto err_wqueue;
	}

	ret = power_supply_register(&pdev->dev, &chg->psy_usb);
	if (ret) {
		pr_err("%s : Failed to register power supply psy_usb\n", __func__);
		goto err_supply_unreg_bat;
	}

	ret = power_supply_register(&pdev->dev, &chg->psy_ac);
	if (ret) {
		pr_err("%s : Failed to register power supply psy_ac\n", __func__);
		goto err_supply_unreg_usb;
	}

	ret = request_threaded_irq(iodev->i2c->irq, NULL, max8998_int_work_func,
				   IRQF_TRIGGER_FALLING, "max8998-charger", chg);
	if (ret) {
		pr_err("%s : Failed to request pmic irq\n", __func__);
		goto err_supply_unreg_ac;
	}

	ret = enable_irq_wake(iodev->i2c->irq);
	if (ret) {
		pr_err("%s : Failed to enable pmic irq wake\n", __func__);
		goto err_irq;
	}

	ret = s3c_bat_create_attrs(chg->psy_bat.dev);
	if (ret) {
		pr_err("%s : Failed to create_attrs\n", __func__);
		goto err_irq;
	}

	chg->callbacks.set_cable = max8998_set_cable;
	chg->callbacks.set_esafe = max8998_set_esafe;
	chg->callbacks.get_vdcin = max8998_get_vdcin;
	if (chg->pdata->register_callbacks)
		chg->pdata->register_callbacks(&chg->callbacks);

	wake_lock(&chg->work_wake_lock);
	queue_work(chg->monitor_wqueue, &chg->bat_work);

	return 0;

err_irq:
	free_irq(iodev->i2c->irq, NULL);
err_supply_unreg_ac:
	power_supply_unregister(&chg->psy_ac);
err_supply_unreg_usb:
	power_supply_unregister(&chg->psy_usb);
err_supply_unreg_bat:
	power_supply_unregister(&chg->psy_bat);
err_wqueue:
	destroy_workqueue(chg->monitor_wqueue);
	cancel_work_sync(&chg->bat_work);
err_wake_lock:
	wake_lock_destroy(&chg->work_wake_lock);
	wake_lock_destroy(&chg->vbus_wake_lock);
	wake_lock_destroy(&chg->lowbat_wake_lock);
err_kfree:
	mutex_destroy(&chg->mutex);
err_bat_table:
	kfree(chg);
	return ret;
}
Ejemplo n.º 14
0
static __devinit int max8998_charger_probe(struct platform_device *pdev)
{
	struct max8998_dev *iodev = dev_get_drvdata(pdev->dev.parent);
	struct max8998_platform_data *pdata = dev_get_platdata(iodev->dev);
	struct chg_data *chg;
	int ret = 0;

	pr_info("%s : MAX8998 Charger Driver Loading\n", __func__);

	chg = kzalloc(sizeof(*chg), GFP_KERNEL);
	if (!chg)
		return -ENOMEM;

	chg->iodev = iodev;
	chg->pdata = pdata->charger;

	if (!chg->pdata || !chg->pdata->adc_table) {
		pr_err("%s : No platform data & adc_table supplied\n", __func__);
		ret = -EINVAL;
		goto err_bat_table;
	}

	chg->psy_bat.name = "battery",
	chg->psy_bat.type = POWER_SUPPLY_TYPE_BATTERY,
	chg->psy_bat.properties = max8998_battery_props,
	chg->psy_bat.num_properties = ARRAY_SIZE(max8998_battery_props),
	chg->psy_bat.get_property = s3c_bat_get_property,

	chg->psy_usb.name = "usb",
	chg->psy_usb.type = POWER_SUPPLY_TYPE_USB,
	chg->psy_usb.supplied_to = supply_list,
	chg->psy_usb.num_supplicants = ARRAY_SIZE(supply_list),
	chg->psy_usb.properties = s3c_power_properties,
	chg->psy_usb.num_properties = ARRAY_SIZE(s3c_power_properties),
	chg->psy_usb.get_property = s3c_usb_get_property,

	chg->psy_ac.name = "ac",
	chg->psy_ac.type = POWER_SUPPLY_TYPE_MAINS,
	chg->psy_ac.supplied_to = supply_list,
	chg->psy_ac.num_supplicants = ARRAY_SIZE(supply_list),
	chg->psy_ac.properties = s3c_power_properties,
	chg->psy_ac.num_properties = ARRAY_SIZE(s3c_power_properties),
	chg->psy_ac.get_property = s3c_ac_get_property,

	chg->present = 1;
	chg->polling_interval = POLLING_INTERVAL;
	chg->bat_info.batt_health = POWER_SUPPLY_HEALTH_GOOD;
	chg->bat_info.batt_is_full = false;
	chg->bat_info.batt_max_soc = 0;
	chg->set_charge_timeout = false;

	chg->cable_status = CABLE_TYPE_NONE;

	mutex_init(&chg->mutex);

	platform_set_drvdata(pdev, chg);

	ret = max8998_update_reg(iodev, MAX8998_REG_CHGR1, /* disable */
		(0x3 << MAX8998_SHIFT_RSTR), MAX8998_MASK_RSTR);
	if (ret < 0)
		goto err_kfree;

	ret = max8998_update_reg(iodev, MAX8998_REG_CHGR2, /* 6 Hr */
		(0x2 << MAX8998_SHIFT_FT), MAX8998_MASK_FT);
	if (ret < 0)
		goto err_kfree;

	ret = max8998_update_reg(iodev, MAX8998_REG_CHGR2, /* 4.2V */
		(0x0 << MAX8998_SHIFT_BATTSL), MAX8998_MASK_BATTSL);
	if (ret < 0)
		goto err_kfree;

	ret = max8998_update_reg(iodev, MAX8998_REG_CHGR2, /* 105c */
		(0x0 << MAX8998_SHIFT_TMP), MAX8998_MASK_TMP);
	if (ret < 0)
		goto err_kfree;

	pr_info("%s : pmic interrupt registered\n", __func__);
	ret = max8998_write_reg(iodev, MAX8998_REG_IRQM1,
		~(MAX8998_MASK_DCINR | MAX8998_MASK_DCINF));
	if (ret < 0)
		goto err_kfree;

	ret = max8998_write_reg(iodev, MAX8998_REG_IRQM2, 0xFF);
	if (ret < 0)
		goto err_kfree;

	ret = max8998_write_reg(iodev, MAX8998_REG_IRQM3, ~0x4);
	if (ret < 0)
		goto err_kfree;

	ret = max8998_write_reg(iodev, MAX8998_REG_IRQM4, 0xFF);
	if (ret < 0)
		goto err_kfree;

	wake_lock_init(&chg->vbus_wake_lock, WAKE_LOCK_SUSPEND,
		"vbus_present");
	wake_lock_init(&chg->work_wake_lock, WAKE_LOCK_SUSPEND,
		"max8998-charger");

	INIT_WORK(&chg->bat_work, s3c_bat_work);

	chg->monitor_wqueue =
		create_freezeable_workqueue(dev_name(&pdev->dev));
	if (!chg->monitor_wqueue) {
		pr_err("Failed to create freezeable workqueue\n");
		ret = -ENOMEM;
		goto err_wake_lock;
	}

	chg->last_poll = alarm_get_elapsed_realtime();
	alarm_init(&chg->alarm, ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP,
		s3c_battery_alarm);

	check_lpm_charging_mode(chg);

	/* init power supplier framework */
	ret = power_supply_register(&pdev->dev, &chg->psy_bat);
	if (ret) {
		pr_err("Failed to register power supply psy_bat\n");
		goto err_wqueue;
	}

	ret = power_supply_register(&pdev->dev, &chg->psy_usb);
	if (ret) {
		pr_err("Failed to register power supply psy_usb\n");
		goto err_supply_unreg_bat;
	}

	ret = power_supply_register(&pdev->dev, &chg->psy_ac);
	if (ret) {
		pr_err("Failed to register power supply psy_ac\n");
		goto err_supply_unreg_usb;
	}

	ret = request_threaded_irq(iodev->i2c_client->irq, NULL,
			max8998_int_work_func,
			IRQF_TRIGGER_FALLING, "max8998-charger", chg);
	if (ret) {
		pr_err("%s : Failed to request pmic irq\n", __func__);
		goto err_supply_unreg_ac;
	}

	ret = enable_irq_wake(iodev->i2c_client->irq);
	if (ret) {
		pr_err("Failed to enable pmic irq wake\n");
		goto err_irq;
	}

	ret = s3c_bat_create_attrs(chg->psy_bat.dev);
	if (ret) {
		pr_err("%s : Failed to create_attrs\n", __func__);
		goto err_irq;
	}

	chg->callbacks.set_cable = max8998_set_cable;
	if (chg->pdata->register_callbacks)
		chg->pdata->register_callbacks(&chg->callbacks);

	wake_lock(&chg->work_wake_lock);
	queue_work(chg->monitor_wqueue, &chg->bat_work);

	return 0;

err_irq:
	free_irq(iodev->i2c_client->irq, NULL);
err_supply_unreg_ac:
	power_supply_unregister(&chg->psy_ac);
err_supply_unreg_usb:
	power_supply_unregister(&chg->psy_usb);
err_supply_unreg_bat:
	power_supply_unregister(&chg->psy_bat);
err_wqueue:
	destroy_workqueue(chg->monitor_wqueue);
	cancel_work_sync(&chg->bat_work);
	alarm_cancel(&chg->alarm);
err_wake_lock:
	wake_lock_destroy(&chg->work_wake_lock);
	wake_lock_destroy(&chg->vbus_wake_lock);
err_kfree:
	mutex_destroy(&chg->mutex);
err_bat_table:
	kfree(chg);
	return ret;
}
Ejemplo n.º 15
0
static int capella_cm3602_setup(struct capella_cm3602_data *ip)
{
	int rc = -EIO;
	struct capella_cm3602_platform_data *pdata = ip->pdata;
	//int irq = gpio_to_irq(pdata->p_out);
	char b[20];

	D("%s\n", __func__);

	rc = gpio_request(pdata->pwd_out_pin, "cm3602 out");
	if (rc) {
		pr_err("%s: request gpio %d failed \n",	__func__, pdata->pwd_out_pin);
		return rc;
	}
	rc = gpio_request(pdata->ps_shutdown_pin, "shut down pin");
	if (rc) {
		gpio_free(pdata->pwd_out_pin);
		pr_err("%s: request gpio %d failed \n",	__func__, pdata->ps_shutdown_pin);
		return rc;
	}
	/*
	gpio_direction_output(pdata->pwd_out_pin, SPI_GPIO_OUT);
	gpio_set_value(pdata->pwd_out_pin, SPI_GPIO_LOW);		//CM3605_PWD output
	gpio_direction_output(pdata->ps_shutdown_pin, SPI_GPIO_OUT);
	gpio_set_value(pdata->ps_shutdown_pin, SPI_GPIO_LOW);		//CM3605_PS_SHUTDOWN
	*/
	rc = gpio_request(pdata->irq_pin, "cm3602 irq");
	if (rc) {
		gpio_free(pdata->pwd_out_pin);
		gpio_free(pdata->ps_shutdown_pin);
		pr_err("%s: request gpio %d failed \n",	__func__, pdata->irq_pin);
		return rc;
	}
	//rc = gpio_direction_input(pdata->irq_pin);
	rc = request_irq(gpio_to_irq(pdata->irq_pin),capella_cm3602_irq_handler,SPI_GPIO_EDGE_FALLING,NULL, ip);
	if (rc < 0) {
		pr_err("%s: request_irq failed for gpio %d (%d)\n",
			__func__, 
			pdata->p_out, rc);
		goto fail_free_p_out;
	}

	sprintf(b,"cm3602_workqueue");
	ip->cm3602_workqueue = create_freezeable_workqueue(b);
	if(!ip->cm3602_workqueue)
	{
		printk("cannot create cm3602 workqueue\n");
		return -EBUSY;
	}
	INIT_WORK(&ip->cm3602_work, cm3602_work_handler);
	setup_timer(&ip->cm3602_timer,cm3602_timer,(unsigned long)ip);
	ip->cm3602_timer.expires = jiffies + HZ;
	add_timer(&ip->cm3602_timer);

	//chenli:psensor off by default
	ip->pdata->power(0);
/*
	rc = set_irq_wake(irq, 1);
	if (rc < 0) {
		pr_err("%s: failed to set irq %d as a wake interrupt\n",
			__func__, irq);
		goto fail_free_irq;

	}
*/
	goto done;
/*
fail_free_irq:
	free_irq(irq, 0);*/
fail_free_p_out:
	gpio_free(pdata->irq_pin);
done:
	return rc;
}
Ejemplo n.º 16
0
/** 
 * \fn     wlanDrvIf_Create
 * \brief  Create the driver instance
 * 
 * Allocate driver object.
 * Initialize driver OS resources (IRQ, workqueue, events socket)
 * Setup driver network interface.
 * Create and link all driver modules.
 *
 * \note   
 * \param  void
 * \return 0 - OK, else - failure
 * \sa     wlanDrvIf_Destroy
 */ 
static int wlanDrvIf_Create (void)
{
	TWlanDrvIfObj *drv; /* Dm: Failure is not cleaned properly !!! */
	int rc;

	/* Allocate driver's structure */
	drv = kmalloc (sizeof(TWlanDrvIfObj), GFP_KERNEL);
    if (!drv)
    {
		return -ENOMEM;
	}
#ifdef TI_DBG
	tb_init(TB_OPTION_NONE);
#endif
	pDrvStaticHandle = drv;  /* save for module destroy */
#ifdef TI_MEM_ALLOC_TRACE        
	os_printf ("MTT:%s:%d ::kmalloc(%lu, %x) : %lu\n", __FUNCTION__, __LINE__, sizeof(TWlanDrvIfObj), GFP_KERNEL, sizeof(TWlanDrvIfObj));
#endif
	memset (drv, 0, sizeof(TWlanDrvIfObj));

	/* Dm:    drv->irq = TNETW_IRQ; */
	drv->tCommon.eDriverState = DRV_STATE_IDLE;

	drv->tiwlan_wq = create_freezeable_workqueue(DRIVERWQ_NAME);
	if (!drv->tiwlan_wq) {
		ti_dprintf (TIWLAN_LOG_ERROR, "wlanDrvIf_Create(): Failed to create workQ!\n");
		rc = -EINVAL;
		goto drv_create_end_1;
	}
	drv->wl_packet = 0;
	drv->wl_count = 0;
#ifdef CONFIG_HAS_WAKELOCK
	wake_lock_init(&drv->wl_wifi, WAKE_LOCK_SUSPEND, "wifi_wake");
	wake_lock_init(&drv->wl_rxwake, WAKE_LOCK_SUSPEND, "wifi_rx_wake");
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
	INIT_WORK(&drv->tWork, wlanDrvIf_DriverTask, (void *)drv);
#else
	INIT_WORK(&drv->tWork, wlanDrvIf_DriverTask);
#endif
	spin_lock_init (&drv->lock);

	/* Setup driver network interface. */
	rc = wlanDrvIf_SetupNetif (drv);
	if (rc)	{
		goto drv_create_end_2;
	}

	/* Create the events socket interface */
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
	drv->wl_sock = netlink_kernel_create( NETLINK_USERSOCK, 0, NULL, THIS_MODULE );
#else
	drv->wl_sock = netlink_kernel_create(&init_net, NETLINK_USERSOCK, 0, NULL, NULL, THIS_MODULE );
#endif
	if (drv->wl_sock == NULL) {
	        ti_dprintf (TIWLAN_LOG_ERROR, "netlink_kernel_create() failed !\n");
		rc = -EINVAL;
		goto drv_create_end_3;
	}

	/* Create all driver modules and link their handles */
	rc = drvMain_Create (drv,
			&drv->tCommon.hDrvMain,
			&drv->tCommon.hCmdHndlr,
			&drv->tCommon.hContext,
			&drv->tCommon.hTxDataQ,
			&drv->tCommon.hTxMgmtQ,
			&drv->tCommon.hTxCtrl,
			&drv->tCommon.hTWD,
					&drv->tCommon.hEvHandler,
                    &drv->tCommon.hCmdDispatch,
		&drv->tCommon.hReport);
	if (rc != TI_OK) {
		ti_dprintf (TIWLAN_LOG_ERROR, "%s: Failed to dvrMain_Create!\n", __func__);
		rc = -EINVAL;
		goto drv_create_end_4;
	}
	/*
	 *  Initialize interrupts (or polling mode for debug):
	 */
#ifdef PRIODIC_INTERRUPT
	/* Debug mode: Polling (the timer is started by HwInit process) */
	drv->hPollTimer = os_timerCreate ((TI_HANDLE)drv, wlanDrvIf_PollIrqHandler, (TI_HANDLE)drv);
#else 
	/* Normal mode: Interrupts (the default mode) */
	rc = hPlatform_initInterrupt (drv, (void*)wlanDrvIf_HandleInterrupt);
#if 1 //wait to debug
	if (rc)	{
		ti_dprintf (TIWLAN_LOG_ERROR, "wlanDrvIf_Create(): Failed to register interrupt handler!\n");
		goto drv_create_end_5;
	}
#endif
#endif  /* PRIODIC_INTERRUPT */
	return 0;
#if 1 //wait to debug
drv_create_end_5:
	/* Destroy all driver modules */
	if (drv->tCommon.hDrvMain) {
		drvMain_Destroy (drv->tCommon.hDrvMain);
	}
#endif
drv_create_end_4:
	if (drv->wl_sock) {
		sock_release (drv->wl_sock->sk_socket);
	}

drv_create_end_3:
	/* Release the driver network interface */
	if (drv->netdev) {
		unregister_netdev (drv->netdev);
		free_netdev (drv->netdev);
	}

drv_create_end_2:
#ifdef CONFIG_HAS_WAKELOCK
	wake_lock_destroy(&drv->wl_wifi);
	wake_lock_destroy(&drv->wl_rxwake);
#endif
	if (drv->tiwlan_wq)
		destroy_workqueue(drv->tiwlan_wq);

drv_create_end_1:
	kfree(drv);
	printk("%s: Fail\n", __func__);
	return rc;
}
Ejemplo n.º 17
0
static __devinit int sec_battery_probe(struct platform_device *pdev)
{
    struct sec_battery_platform_data *pdata = pdev->dev.platform_data;
    struct chg_data *chg;
    int ret = 0;

    pr_info("%s : Samsung Battery Driver Loading\n", __func__);

    chg = kzalloc(sizeof(*chg), GFP_KERNEL);
    if (!chg)
        return -ENOMEM;

    chg->pdata = pdata;

    if (!chg->pdata || !chg->pdata->adc_table) {
        pr_err("%s : No platform data & adc_table supplied\n", __func__);
        ret = -EINVAL;
        goto err_bat_table;
    }

    chg->psy_bat.name = "battery",
                 chg->psy_bat.type = POWER_SUPPLY_TYPE_BATTERY,
                              chg->psy_bat.properties = sec_battery_props,
                                           chg->psy_bat.num_properties = ARRAY_SIZE(sec_battery_props),
                                                        chg->psy_bat.get_property = sec_bat_get_property,

                                                                     chg->psy_usb.name = "usb",
                                                                                  chg->psy_usb.type = POWER_SUPPLY_TYPE_USB,
                                                                                               chg->psy_usb.supplied_to = supply_list,
                                                                                                            chg->psy_usb.num_supplicants = ARRAY_SIZE(supply_list),
                                                                                                                         chg->psy_usb.properties = sec_power_properties,
                                                                                                                                      chg->psy_usb.num_properties = ARRAY_SIZE(sec_power_properties),
                                                                                                                                                   chg->psy_usb.get_property = sec_usb_get_property,

                                                                                                                                                                chg->psy_ac.name = "ac",
                                                                                                                                                                            chg->psy_ac.type = POWER_SUPPLY_TYPE_MAINS,
                                                                                                                                                                                        chg->psy_ac.supplied_to = supply_list,
                                                                                                                                                                                                    chg->psy_ac.num_supplicants = ARRAY_SIZE(supply_list),
                                                                                                                                                                                                                chg->psy_ac.properties = sec_power_properties,
                                                                                                                                                                                                                            chg->psy_ac.num_properties = ARRAY_SIZE(sec_power_properties),
                                                                                                                                                                                                                                        chg->psy_ac.get_property = sec_ac_get_property,

                                                                                                                                                                                                                                                    chg->present = 1;
    chg->polling_interval = POLLING_INTERVAL;
    chg->bat_info.batt_health = POWER_SUPPLY_HEALTH_GOOD;
    chg->bat_info.batt_is_full = false;
    chg->set_charge_timeout = false;
    chg->bat_info.batt_improper_ta = false;
    chg->is_recharging = false;
#ifdef CONFIG_BATTERY_MAX17042
    // Get battery type from fuelgauge driver.
    if(chg->pdata && chg->pdata->fuelgauge_cb)
        chg->battery_type = (battery_type_t)chg->pdata->fuelgauge_cb(
                                REQ_TEST_MODE_INTERFACE, TEST_MODE_BATTERY_TYPE_CHECK, 0);

    // Check UV charging case.
    if(chg->pdata && chg->pdata->pmic_charger &&
            chg->pdata->pmic_charger->get_connection_status) {
        if(chg->pdata->pmic_charger->get_connection_status() &&
                check_UV_charging_case(chg))
            chg->low_batt_boot_flag = true;
    }
    else
        chg->low_batt_boot_flag = false;

    // init delayed work
    INIT_DELAYED_WORK(&chg->full_chg_work, full_comp_work_handler);

    // Init low batt check threshold values.
    if(chg->battery_type == SDI_BATTERY_TYPE)
        chg->check_start_vol = 3550;  // Under 3.55V
    else if(chg->battery_type == ATL_BATTERY_TYPE)
        chg->check_start_vol = 3450;  // Under 3.45V
#endif

    chg->cable_status = CABLE_TYPE_NONE;
    chg->charging_status = CHARGING_STATUS_NONE;

    mutex_init(&chg->mutex);

    platform_set_drvdata(pdev, chg);

    wake_lock_init(&chg->vbus_wake_lock, WAKE_LOCK_SUSPEND,
                   "vbus_present");
    wake_lock_init(&chg->work_wake_lock, WAKE_LOCK_SUSPEND,
                   "sec_battery_work");

    INIT_WORK(&chg->bat_work, sec_bat_work);

    chg->monitor_wqueue =
        create_freezeable_workqueue(dev_name(&pdev->dev));
    if (!chg->monitor_wqueue) {
        pr_err("Failed to create freezeable workqueue\n");
        ret = -ENOMEM;
        goto err_wake_lock;
    }

    chg->last_poll = alarm_get_elapsed_realtime();
    alarm_init(&chg->alarm, ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP,
               sec_battery_alarm);

    /* init power supplier framework */
    ret = power_supply_register(&pdev->dev, &chg->psy_bat);
    if (ret) {
        pr_err("Failed to register power supply psy_bat\n");
        goto err_wqueue;
    }

    ret = power_supply_register(&pdev->dev, &chg->psy_usb);
    if (ret) {
        pr_err("Failed to register power supply psy_usb\n");
        goto err_supply_unreg_bat;
    }

    ret = power_supply_register(&pdev->dev, &chg->psy_ac);
    if (ret) {
        pr_err("Failed to register power supply psy_ac\n");
        goto err_supply_unreg_usb;
    }

    sec_bat_create_attrs(chg->psy_bat.dev);

    chg->callbacks.set_cable = sec_bat_set_cable;
    chg->callbacks.set_status = sec_bat_set_status;
    chg->callbacks.force_update = sec_bat_force_update;
    if (chg->pdata->register_callbacks)
        chg->pdata->register_callbacks(&chg->callbacks);

    wake_lock(&chg->work_wake_lock);
    queue_work(chg->monitor_wqueue, &chg->bat_work);

    p1_lpm_mode_check(chg);

    return 0;

err_supply_unreg_ac:
    power_supply_unregister(&chg->psy_ac);
err_supply_unreg_usb:
    power_supply_unregister(&chg->psy_usb);
err_supply_unreg_bat:
    power_supply_unregister(&chg->psy_bat);
err_wqueue:
    destroy_workqueue(chg->monitor_wqueue);
    cancel_work_sync(&chg->bat_work);
    alarm_cancel(&chg->alarm);
err_wake_lock:
    wake_lock_destroy(&chg->work_wake_lock);
    wake_lock_destroy(&chg->vbus_wake_lock);
    mutex_destroy(&chg->mutex);
err_bat_table:
    kfree(chg);
    return ret;
}