Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge remote-tracking branch 'regulator/topic/tps65090' into regulator-next

+101 -5
+101 -5
drivers/regulator/tps65090-regulator.c
··· 19 19 #include <linux/module.h> 20 20 #include <linux/init.h> 21 21 #include <linux/gpio.h> 22 + #include <linux/of_gpio.h> 22 23 #include <linux/slab.h> 23 24 #include <linux/err.h> 24 25 #include <linux/platform_device.h> 25 26 #include <linux/regulator/driver.h> 26 27 #include <linux/regulator/machine.h> 28 + #include <linux/regulator/of_regulator.h> 27 29 #include <linux/mfd/tps65090.h> 28 30 29 31 struct tps65090_regulator { ··· 69 67 tps65090_REG_DESC(FET5, "infet5", 0x13, tps65090_reg_contol_ops), 70 68 tps65090_REG_DESC(FET6, "infet6", 0x14, tps65090_reg_contol_ops), 71 69 tps65090_REG_DESC(FET7, "infet7", 0x15, tps65090_reg_contol_ops), 72 - tps65090_REG_DESC(LDO1, "vsys_l1", 0, tps65090_ldo_ops), 73 - tps65090_REG_DESC(LDO2, "vsys_l2", 0, tps65090_ldo_ops), 70 + tps65090_REG_DESC(LDO1, "vsys-l1", 0, tps65090_ldo_ops), 71 + tps65090_REG_DESC(LDO2, "vsys-l2", 0, tps65090_ldo_ops), 74 72 }; 75 73 76 74 static inline bool is_dcdc(int id) ··· 140 138 } 141 139 } 142 140 141 + #ifdef CONFIG_OF 142 + static struct of_regulator_match tps65090_matches[] = { 143 + { .name = "dcdc1", }, 144 + { .name = "dcdc2", }, 145 + { .name = "dcdc3", }, 146 + { .name = "fet1", }, 147 + { .name = "fet2", }, 148 + { .name = "fet3", }, 149 + { .name = "fet4", }, 150 + { .name = "fet5", }, 151 + { .name = "fet6", }, 152 + { .name = "fet7", }, 153 + { .name = "ldo1", }, 154 + { .name = "ldo2", }, 155 + }; 156 + 157 + static struct tps65090_platform_data *tps65090_parse_dt_reg_data( 158 + struct platform_device *pdev, 159 + struct of_regulator_match **tps65090_reg_matches) 160 + { 161 + struct tps65090_platform_data *tps65090_pdata; 162 + struct device_node *np = pdev->dev.parent->of_node; 163 + struct device_node *regulators; 164 + int idx = 0, ret; 165 + struct tps65090_regulator_plat_data *reg_pdata; 166 + 167 + tps65090_pdata = devm_kzalloc(&pdev->dev, sizeof(*tps65090_pdata), 168 + GFP_KERNEL); 169 + if (!tps65090_pdata) { 170 + dev_err(&pdev->dev, "Memory alloc for tps65090_pdata failed\n"); 171 + return ERR_PTR(-ENOMEM); 172 + } 173 + 174 + reg_pdata = devm_kzalloc(&pdev->dev, TPS65090_REGULATOR_MAX * 175 + sizeof(*reg_pdata), GFP_KERNEL); 176 + if (!reg_pdata) { 177 + dev_err(&pdev->dev, "Memory alloc for reg_pdata failed\n"); 178 + return ERR_PTR(-ENOMEM); 179 + } 180 + 181 + regulators = of_find_node_by_name(np, "regulators"); 182 + if (!regulators) { 183 + dev_err(&pdev->dev, "regulator node not found\n"); 184 + return ERR_PTR(-ENODEV); 185 + } 186 + 187 + ret = of_regulator_match(&pdev->dev, regulators, tps65090_matches, 188 + ARRAY_SIZE(tps65090_matches)); 189 + if (ret < 0) { 190 + dev_err(&pdev->dev, 191 + "Error parsing regulator init data: %d\n", ret); 192 + return ERR_PTR(ret); 193 + } 194 + 195 + *tps65090_reg_matches = tps65090_matches; 196 + for (idx = 0; idx < ARRAY_SIZE(tps65090_matches); idx++) { 197 + struct regulator_init_data *ri_data; 198 + struct tps65090_regulator_plat_data *rpdata; 199 + 200 + rpdata = &reg_pdata[idx]; 201 + ri_data = tps65090_matches[idx].init_data; 202 + if (!ri_data || !tps65090_matches[idx].of_node) 203 + continue; 204 + 205 + rpdata->reg_init_data = ri_data; 206 + rpdata->enable_ext_control = of_property_read_bool( 207 + tps65090_matches[idx].of_node, 208 + "ti,enable-ext-control"); 209 + if (rpdata->enable_ext_control) 210 + rpdata->gpio = of_get_named_gpio(np, 211 + "dcdc-ext-control-gpios", 0); 212 + 213 + tps65090_pdata->reg_pdata[idx] = rpdata; 214 + } 215 + return tps65090_pdata; 216 + } 217 + #else 218 + static inline struct tps65090_platform_data *tps65090_parse_dt_reg_data( 219 + struct platform_device *pdev, 220 + struct of_regulator_match **tps65090_reg_matches) 221 + { 222 + *tps65090_reg_matches = NULL; 223 + return NULL; 224 + } 225 + #endif 226 + 143 227 static int tps65090_regulator_probe(struct platform_device *pdev) 144 228 { 145 229 struct tps65090 *tps65090_mfd = dev_get_drvdata(pdev->dev.parent); ··· 235 147 struct tps65090_regulator_plat_data *tps_pdata; 236 148 struct tps65090_regulator *pmic; 237 149 struct tps65090_platform_data *tps65090_pdata; 150 + struct of_regulator_match *tps65090_reg_matches = NULL; 238 151 int num; 239 152 int ret; 240 153 241 154 dev_dbg(&pdev->dev, "Probing regulator\n"); 242 155 243 156 tps65090_pdata = dev_get_platdata(pdev->dev.parent); 244 - if (!tps65090_pdata) { 157 + if (!tps65090_pdata && tps65090_mfd->dev->of_node) 158 + tps65090_pdata = tps65090_parse_dt_reg_data(pdev, 159 + &tps65090_reg_matches); 160 + if (IS_ERR_OR_NULL(tps65090_pdata)) { 245 161 dev_err(&pdev->dev, "Platform data missing\n"); 246 - return -EINVAL; 162 + return tps65090_pdata ? PTR_ERR(tps65090_pdata) : -EINVAL; 247 163 } 248 164 249 165 pmic = devm_kzalloc(&pdev->dev, TPS65090_REGULATOR_MAX * sizeof(*pmic), ··· 284 192 } 285 193 } 286 194 287 - config.dev = &pdev->dev; 195 + config.dev = pdev->dev.parent; 288 196 config.driver_data = ri; 289 197 config.regmap = tps65090_mfd->rmap; 290 198 if (tps_pdata) 291 199 config.init_data = tps_pdata->reg_init_data; 292 200 else 293 201 config.init_data = NULL; 202 + if (tps65090_reg_matches) 203 + config.of_node = tps65090_reg_matches[num].of_node; 204 + else 205 + config.of_node = NULL; 294 206 295 207 rdev = regulator_register(ri->desc, &config); 296 208 if (IS_ERR(rdev)) {