static int rt5025_gpio_probe(struct platform_device *pdev)
{
	struct rt5025_chip *chip = dev_get_drvdata(pdev->dev.parent);
	struct rt5025_platform_data *pdata = (pdev->dev.parent)->platform_data;
	struct rt5025_gpio_info *gi;
	bool use_dt = pdev->dev.of_node;
	int rc = 0;

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


	gi->i2c = chip->i2c;
	if (use_dt) {
		rt_parse_dt(gi, &pdev->dev);
	} else {
		if (!pdata) {
			rc = -EINVAL;
			goto out_dev;
		}
		pdev->dev.platform_data = pdata->gpio_pdata;
		rt_parse_pdata(gi, &pdev->dev);
	}

	gi->gpio_chip.direction_input  = rt5025_gpio_direction_input;
	gi->gpio_chip.direction_output = rt5025_gpio_direction_output;
	gi->gpio_chip.get = rt5025_gpio_get_value;
	gi->gpio_chip.set = rt5025_gpio_set_value;
	gi->gpio_chip.can_sleep = 0;

	gi->gpio_chip.base = -1;
	gi->gpio_chip.ngpio = gi->ngpio;
	gi->gpio_chip.label = pdev->name;
	gi->gpio_chip.dev = &pdev->dev;
	gi->gpio_chip.owner = THIS_MODULE;

	rc = gpiochip_add(&gi->gpio_chip);
	if (rc)
		goto out_dev;

	platform_set_drvdata(pdev, gi);
	dev_info(&pdev->dev, "driver successfully loaded\n");
	return rc;
out_dev:
	return rc;
}
static int rt5025_misc_probe(struct platform_device *pdev)
{
	struct rt5025_chip *chip = dev_get_drvdata(pdev->dev.parent);
	struct rt5025_platform_data *pdata = (pdev->dev.parent)->platform_data;
	struct rt5025_misc_info *mi;
	bool use_dt = pdev->dev.of_node;
	int ret = 0;

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

	mi->i2c = chip->i2c;
	mi->dev = &pdev->dev;
	if (use_dt) {
		rt_parse_dt(mi, &pdev->dev);
	} else {
		if (!pdata) {
			dev_err(&pdev->dev, "no initial platform data\n");
			ret = -EINVAL;
			goto err_init;
		}
		pdev->dev.platform_data = pdata->misc_pdata;
		rt_parse_pdata(mi, &pdev->dev);
	}
	/*for shutdown control*/
	g_shdn = chip->i2c;

	if (rt_pm_off && !pm_power_off)
		pm_power_off = rt5025_power_off;

	platform_set_drvdata(pdev, mi);
	chip->misc_info = mi;
	dev_info(&pdev->dev, "driver successfully loaded\n");
	return 0;
err_init:
	return ret;
}
static inline struct regulator_dev* rt5746_regulator_register(
	struct regulator_desc *regulator_desc, struct device *dev,
	struct regulator_init_data *init_data, void *driver_data)
{
#if (LINUX_VERSION_CODE>=KERNEL_VERSION(3,5,0))
    struct regulator_config config = {
        .dev = dev,
        .init_data = init_data,
        .driver_data = driver_data,
	.of_node = dev->of_node,
    };
    return regulator_register(&regulator_desc, &config);
#elif (LINUX_VERSION_CODE>=KERNEL_VERSION(3,0,0))
    return regulator_register(regulator_desc,dev,init_data,
		driver_data,dev->of_node);
#else
    return regulator_register(regulator_desc,dev,init_data,driver_data);
#endif /* LINUX_VERSION_CODE>=KERNEL_VERSION(3,5,0)) */
}

static irqreturn_t rt5746_irq_handler(int irqno, void *param)
{
	struct rt5746_regulator_info *ri = param;
	int regval;
	int i;

	if (ri->suspend)
	{
		schedule_delayed_work(&ri->irq_dwork, msecs_to_jiffies(50));
		goto fin_intr;
	}

	regval = rt5746_reg_read(ri->i2c, RT5746_REG_INTACK);
	if (regval<0)
		dev_err(ri->dev, "read irq event io fail\n");
	else {
		if (regval == 0)
			goto fin_intr;
		regval &= (~rt5746_init_regval[0]);
		for (i=0; i<RT5746_IRQ_MAX; i++) {
			if (regval&(1<<i)) {
				switch (i) {
				case RT5746_IRQ_PGOOD:
					dev_err(ri->dev, "pgood event occur\n");
					break;
				case RT5746_IRQ_IDCDC:
					dev_err(ri->dev, "dcdc over current\n");
					break;
				case RT5746_IRQ_UVLO:
					dev_err(ri->dev, "uvlo event occur\n");
					break;
				case RT5746_IRQ_TPREW:
					dev_info(ri->dev, "thermal pre-warning\n");
					break;
				case RT5746_IRQ_TWARN:
					dev_warn(ri->dev, "thermal warning\n");
					break;
				case RT5746_IRQ_TSD:
					dev_err(ri->dev, "thermal shutdown\n");
					break;
				default:
					dev_err(ri->dev, "unrecognized event\n");
					break;
				}
			}
		}
	}
fin_intr:
	return IRQ_HANDLED;
}

static void rt5746_irq_dwork_func(struct work_struct *work)
{
	struct rt5746_regulator_info *ri = container_of(work,
		struct rt5746_regulator_info, irq_dwork.work);
	rt5746_irq_handler(0, ri);
}

static void rt5746_interrupt_init(struct rt5746_regulator_info *ri)
{
	struct rt5746_platform_data *pdata = ri->dev->platform_data;
	int rc = (int)0, irq_no = (int)0;
	if (gpio_is_valid(pdata->irq_gpio)) {
		rc = gpio_request(pdata->irq_gpio, "rt5746_irq_gpio");
		if (rc<0) {
			dev_err(ri->dev, "gpio request failed\n");
			return;
		}
		gpio_direction_input(pdata->irq_gpio);
		irq_no = gpio_to_irq(pdata->irq_gpio);
		if (irq_no<0) {
			dev_err(ri->dev, "gpio to irq fail\n");
			gpio_free(pdata->irq_gpio);
			return;
		}
		if (devm_request_threaded_irq(ri->dev, irq_no, NULL,
			rt5746_irq_handler,
			IRQF_TRIGGER_FALLING|IRQF_NO_SUSPEND|IRQF_DISABLED,
			"rt5746_irq", ri)) {
			dev_err(ri->dev, "request irq fail\n");
			gpio_free(pdata->irq_gpio);
			return;
		}
		enable_irq_wake(irq_no);
		schedule_delayed_work(&ri->irq_dwork, msecs_to_jiffies(100));
	}
	else
		dev_info(ri->dev, "gpio is not valid\n");
}

static void rt_parse_dt(struct device *dev)
{
	#ifdef CONFIG_OF
	struct regulator_init_data *init_data = NULL;
	struct rt5746_platform_data *pdata = dev->platform_data;
	struct device_node *np = dev->of_node;
	int rc;
	u32 tmp;
	#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
	init_data = of_get_regulator_init_data(dev, dev->of_node);
	#else
	init_data = of_get_regulator_init_data(dev);
	#endif /* #if (LINUX_KERNEL_VERSION >= KERNEL_VERSION(3,3,0)) */

	pdata->regulator = init_data;
	rc = of_property_read_u32(np, "rt,standby_uV", &tmp);
	if (rc<0)
		dev_info(dev, "no standby voltage setting, use ic default\n");
	else
		pdata->standby_uV = tmp;

	rc = of_property_read_u32(np, "rt,rampup_sel", &tmp);
	if (rc)
		dev_info(dev, "no rampup_sel property, use ic default value\n");
	else
	{
		if (tmp>RT5746_RAMPUP_MAX)
			tmp = RT5746_RAMPUP_MAX;
		pdata->rampup_sel = tmp;
	}

	rc = of_property_read_u32(np, "rt,rampdn_sel", &tmp);
	if (rc)
		dev_info(dev, "no rampdn_sel property, use ic default value\n");
	else
	{
		if (tmp>RT5746_RAMPDN_MAX)
			tmp = RT5746_RAMPDN_MAX;
		pdata->rampdn_sel = tmp;
	}
	rc = of_property_read_u32(np, "rt,ipeak_sel", &tmp);
	if (rc)
		dev_info(dev, "no ipeak_sel property, use ic default value\n");
	else {
		if (tmp>RT5746_IPEAK_MAX)
			tmp = RT5746_IPEAK_MAX;
		pdata->ipeak_sel = tmp;
	}
	rc = of_property_read_u32(np, "rt,tpwth_sel", &tmp);
	if (rc)
		dev_info(dev, "no tpwth_sel property, use ic default value\n");
	else {
		if (tmp>RT5746_TPWTH_MAX)
			tmp = RT5746_TPWTH_MAX;
		pdata->tpwth_sel = tmp;
	}
	if (of_property_read_bool(np, "rt,rearm_en"))
		pdata->rearm_en = 1;
	if (of_property_read_bool(np, "rt,discharge_en"))
		pdata->discharge_en = 1;
	pdata->irq_gpio = of_get_named_gpio(np, "rt,irq_gpio", 0);
	#endif /* #ifdef CONFIG_OF */
}

static int rt5746_regulator_probe(struct i2c_client *i2c,
	const struct i2c_device_id *id)
{
	struct rt5746_regulator_info *ri;
	struct rt5746_platform_data *pdata = i2c->dev.platform_data;
	struct regulator_dev *rdev;
	struct regulator_init_data *init_data;
	bool use_dt = i2c->dev.of_node;
	int val = 0;
	int ret = 0;

	ri = &rt5746_regulator_info;
	if (use_dt) {
		pdata = devm_kzalloc(&i2c->dev, sizeof(*pdata), GFP_KERNEL);
		if (!pdata) {
			ret = -ENOMEM;
			goto err_init;
		}
		i2c->dev.platform_data = pdata;
		rt_parse_dt(&i2c->dev);
	}
	else {
		if (!pdata) {
			ret = -EINVAL;
			goto err_init;
		}
	}

	init_data = pdata->regulator;
	if (!init_data) {
		dev_err(&i2c->dev, "no initializing data\n");
		ret = -EINVAL;
		goto err_init;
	}

	mutex_init(&ri->io_lock);
	INIT_DELAYED_WORK(&ri->irq_dwork, rt5746_irq_dwork_func);
	ri->i2c = i2c;
	ri->dev = &i2c->dev;
	i2c_set_clientdata(i2c, ri);
	//check ic communication & ic vendor id
	val = rt5746_reg_read(i2c, RT5746_REG_VID);
	if (val<0) {
		ret = -EIO;
		goto err_init;
	}
	else {
		dev_info(&i2c->dev, "vendor id = %02x\n", val);
		if (val!=RT5746_VEN_ID) {
			ret = -EINVAL;
			goto err_init;
		}
	}
	rt5746_parse_initconfig(pdata);
	rt5746_register_init(i2c);

	//interrupt gpio init
	if (pdata->irq_gpio<0)
		dev_info(&i2c->dev, "no interrupt irq specified\n");
	else
		rt5746_interrupt_init(ri);

	rdev = rt5746_regulator_register(&ri->desc, &i2c->dev,
				  init_data, ri);
	if (IS_ERR(rdev)) {
		dev_err(&i2c->dev, "failed to register regulator %s\n",
				ri->desc.name);
		return PTR_ERR(rdev);
	}
	ri->rdev = rdev;
	//set suspend voltage
	if (pdata->standby_uV>0)
		rt5746_set_suspend_voltage(rdev, pdata->standby_uV);
	rt_dbg_create_attrs(&i2c->dev);
	dev_info(&i2c->dev, "regulator successfully registered\n");
err_init:
	return ret;
}

static int rt5746_regulator_remove(struct i2c_client *i2c)
{
	struct rt5746_regulator_info *ri = i2c_get_clientdata(i2c);
	regulator_unregister(ri->rdev);
	dev_info(&i2c->dev, "regulator driver removed\n");
	return 0;
}

static int rt5746_regulator_suspend(struct i2c_client *i2c, pm_message_t mesg)
{
	struct rt5746_regulator_info *ri = i2c_get_clientdata(i2c);
	ri->suspend = 1;
	return 0;
}

static int rt5746_regulator_resume(struct i2c_client *i2c)
{
	struct rt5746_regulator_info *ri = i2c_get_clientdata(i2c);
	ri->suspend = 0;
	return 0;
}

static const struct of_device_id rt_match_table[] = {
	{ .compatible = "richtek,rt5746",},
	{},
};