--- zzzz-none-000/linux-3.10.107/drivers/regulator/da9055-regulator.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/drivers/regulator/da9055-regulator.c 2021-02-04 17:41:59.000000000 +0000 @@ -19,6 +19,8 @@ #include #include #include +#include +#include #include #include @@ -446,6 +448,9 @@ struct da9055_regulator_info *info = regulator->info; int ret = 0; + if (!pdata) + return 0; + if (pdata->gpio_ren && pdata->gpio_ren[id]) { char name[18]; int gpio_mux = pdata->gpio_ren[id]; @@ -530,17 +535,67 @@ return NULL; } +#ifdef CONFIG_OF +static struct of_regulator_match da9055_reg_matches[] = { + { .name = "BUCK1", }, + { .name = "BUCK2", }, + { .name = "LDO1", }, + { .name = "LDO2", }, + { .name = "LDO3", }, + { .name = "LDO4", }, + { .name = "LDO5", }, + { .name = "LDO6", }, +}; + +static int da9055_regulator_dt_init(struct platform_device *pdev, + struct da9055_regulator *regulator, + struct regulator_config *config, + int regid) +{ + struct device_node *nproot, *np; + int ret; + + nproot = of_node_get(pdev->dev.parent->of_node); + if (!nproot) + return -ENODEV; + + np = of_get_child_by_name(nproot, "regulators"); + if (!np) + return -ENODEV; + + ret = of_regulator_match(&pdev->dev, np, &da9055_reg_matches[regid], 1); + of_node_put(nproot); + if (ret < 0) { + dev_err(&pdev->dev, "Error matching regulator: %d\n", ret); + return ret; + } + + config->init_data = da9055_reg_matches[regid].init_data; + config->of_node = da9055_reg_matches[regid].of_node; + + if (!config->of_node) + return -ENODEV; + + return 0; +} +#else +static inline int da9055_regulator_dt_init(struct platform_device *pdev, + struct da9055_regulator *regulator, + struct regulator_config *config, + int regid) +{ + return -ENODEV; +} +#endif /* CONFIG_OF */ + static int da9055_regulator_probe(struct platform_device *pdev) { struct regulator_config config = { }; struct da9055_regulator *regulator; struct da9055 *da9055 = dev_get_drvdata(pdev->dev.parent); - struct da9055_pdata *pdata = da9055->dev->platform_data; + struct da9055_pdata *pdata = dev_get_platdata(da9055->dev); int ret, irq; - if (pdata == NULL || pdata->regulators[pdev->id] == NULL) - return -ENODEV; - regulator = devm_kzalloc(&pdev->dev, sizeof(struct da9055_regulator), GFP_KERNEL); if (!regulator) @@ -557,26 +612,34 @@ config.driver_data = regulator; config.regmap = da9055->regmap; - if (pdata && pdata->regulators) + if (pdata && pdata->regulators) { config.init_data = pdata->regulators[pdev->id]; + } else { + ret = da9055_regulator_dt_init(pdev, regulator, &config, + pdev->id); + if (ret < 0) + return ret; + } ret = da9055_gpio_init(regulator, &config, pdata, pdev->id); if (ret < 0) return ret; - regulator->rdev = regulator_register(®ulator->info->reg_desc, - &config); + regulator->rdev = devm_regulator_register(&pdev->dev, + ®ulator->info->reg_desc, + &config); if (IS_ERR(regulator->rdev)) { dev_err(&pdev->dev, "Failed to register regulator %s\n", regulator->info->reg_desc.name); - ret = PTR_ERR(regulator->rdev); - return ret; + return PTR_ERR(regulator->rdev); } /* Only LDO 5 and 6 has got the over current interrupt */ if (pdev->id == DA9055_ID_LDO5 || pdev->id == DA9055_ID_LDO6) { irq = platform_get_irq_byname(pdev, "REGULATOR"); - irq = regmap_irq_get_virq(da9055->irq_data, irq); + if (irq < 0) + return irq; + ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, da9055_ldo5_6_oc_irq, IRQF_TRIGGER_HIGH | @@ -588,7 +651,7 @@ dev_err(&pdev->dev, "Failed to request Regulator IRQ %d: %d\n", irq, ret); - goto err_regulator; + return ret; } } } @@ -596,27 +659,12 @@ platform_set_drvdata(pdev, regulator); return 0; - -err_regulator: - regulator_unregister(regulator->rdev); - return ret; -} - -static int da9055_regulator_remove(struct platform_device *pdev) -{ - struct da9055_regulator *regulator = platform_get_drvdata(pdev); - - regulator_unregister(regulator->rdev); - - return 0; } static struct platform_driver da9055_regulator_driver = { .probe = da9055_regulator_probe, - .remove = da9055_regulator_remove, .driver = { .name = "da9055-regulator", - .owner = THIS_MODULE, }, };