.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Regulator driver for tps65090 power management chip. |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. |
---|
5 | 6 | |
---|
6 | | - * This program is free software; you can redistribute it and/or modify it |
---|
7 | | - * under the terms and conditions of the GNU General Public License, |
---|
8 | | - * version 2, as published by the Free Software Foundation. |
---|
9 | | - |
---|
10 | | - * This program is distributed in the hope it will be useful, but WITHOUT |
---|
11 | | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
---|
12 | | - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
---|
13 | | - * more details. |
---|
14 | | - |
---|
15 | | - * You should have received a copy of the GNU General Public License |
---|
16 | | - * along with this program. If not, see <http://www.gnu.org/licenses/> |
---|
17 | 7 | */ |
---|
18 | 8 | |
---|
19 | 9 | #include <linux/module.h> |
---|
.. | .. |
---|
57 | 47 | int overcurrent_wait; |
---|
58 | 48 | }; |
---|
59 | 49 | |
---|
60 | | -static struct regulator_ops tps65090_ext_control_ops = { |
---|
| 50 | +static const struct regulator_ops tps65090_ext_control_ops = { |
---|
61 | 51 | }; |
---|
62 | 52 | |
---|
63 | 53 | /** |
---|
.. | .. |
---|
177 | 167 | return ret; |
---|
178 | 168 | } |
---|
179 | 169 | |
---|
180 | | -static struct regulator_ops tps65090_reg_control_ops = { |
---|
| 170 | +static const struct regulator_ops tps65090_reg_control_ops = { |
---|
181 | 171 | .enable = regulator_enable_regmap, |
---|
182 | 172 | .disable = regulator_disable_regmap, |
---|
183 | 173 | .is_enabled = regulator_is_enabled_regmap, |
---|
184 | 174 | }; |
---|
185 | 175 | |
---|
186 | | -static struct regulator_ops tps65090_fet_control_ops = { |
---|
| 176 | +static const struct regulator_ops tps65090_fet_control_ops = { |
---|
187 | 177 | .enable = tps65090_fet_enable, |
---|
188 | 178 | .disable = regulator_disable_regmap, |
---|
189 | 179 | .is_enabled = regulator_is_enabled_regmap, |
---|
190 | 180 | }; |
---|
191 | 181 | |
---|
192 | | -static struct regulator_ops tps65090_ldo_ops = { |
---|
| 182 | +static const struct regulator_ops tps65090_ldo_ops = { |
---|
193 | 183 | }; |
---|
194 | 184 | |
---|
195 | 185 | #define tps65090_REG_DESC(_id, _sname, _en_reg, _en_bits, _nvolt, _volt, _ops) \ |
---|
.. | .. |
---|
356 | 346 | for (idx = 0; idx < ARRAY_SIZE(tps65090_matches); idx++) { |
---|
357 | 347 | struct regulator_init_data *ri_data; |
---|
358 | 348 | struct tps65090_regulator_plat_data *rpdata; |
---|
| 349 | + struct device_node *np; |
---|
359 | 350 | |
---|
360 | 351 | rpdata = ®_pdata[idx]; |
---|
361 | 352 | ri_data = tps65090_matches[idx].init_data; |
---|
362 | | - if (!ri_data || !tps65090_matches[idx].of_node) |
---|
| 353 | + if (!ri_data) |
---|
| 354 | + continue; |
---|
| 355 | + |
---|
| 356 | + np = tps65090_matches[idx].of_node; |
---|
| 357 | + if (!np) |
---|
363 | 358 | continue; |
---|
364 | 359 | |
---|
365 | 360 | rpdata->reg_init_data = ri_data; |
---|
366 | | - rpdata->enable_ext_control = of_property_read_bool( |
---|
367 | | - tps65090_matches[idx].of_node, |
---|
368 | | - "ti,enable-ext-control"); |
---|
| 361 | + rpdata->enable_ext_control = of_property_read_bool(np, |
---|
| 362 | + "ti,enable-ext-control"); |
---|
369 | 363 | if (rpdata->enable_ext_control) { |
---|
370 | 364 | enum gpiod_flags gflags; |
---|
371 | 365 | |
---|
.. | .. |
---|
374 | 368 | gflags = GPIOD_OUT_HIGH; |
---|
375 | 369 | else |
---|
376 | 370 | gflags = GPIOD_OUT_LOW; |
---|
| 371 | + gflags |= GPIOD_FLAGS_BIT_NONEXCLUSIVE; |
---|
377 | 372 | |
---|
378 | | - rpdata->gpiod = devm_gpiod_get_from_of_node(&pdev->dev, |
---|
379 | | - tps65090_matches[idx].of_node, |
---|
380 | | - "dcdc-ext-control-gpios", 0, |
---|
381 | | - gflags, |
---|
382 | | - "tps65090"); |
---|
383 | | - if (IS_ERR(rpdata->gpiod)) |
---|
384 | | - return ERR_CAST(rpdata->gpiod); |
---|
385 | | - if (!rpdata->gpiod) |
---|
| 373 | + rpdata->gpiod = devm_fwnode_gpiod_get( |
---|
| 374 | + &pdev->dev, |
---|
| 375 | + of_fwnode_handle(np), |
---|
| 376 | + "dcdc-ext-control", |
---|
| 377 | + gflags, |
---|
| 378 | + "tps65090"); |
---|
| 379 | + if (PTR_ERR(rpdata->gpiod) == -ENOENT) { |
---|
386 | 380 | dev_err(&pdev->dev, |
---|
387 | 381 | "could not find DCDC external control GPIO\n"); |
---|
| 382 | + rpdata->gpiod = NULL; |
---|
| 383 | + } else if (IS_ERR(rpdata->gpiod)) |
---|
| 384 | + return ERR_CAST(rpdata->gpiod); |
---|
388 | 385 | } |
---|
389 | 386 | |
---|
390 | | - if (of_property_read_u32(tps65090_matches[idx].of_node, |
---|
391 | | - "ti,overcurrent-wait", |
---|
| 387 | + if (of_property_read_u32(np, "ti,overcurrent-wait", |
---|
392 | 388 | &rpdata->overcurrent_wait) == 0) |
---|
393 | 389 | rpdata->overcurrent_wait_valid = true; |
---|
394 | 390 | |
---|
.. | .. |
---|
479 | 475 | else |
---|
480 | 476 | config.of_node = NULL; |
---|
481 | 477 | |
---|
| 478 | + /* |
---|
| 479 | + * Hand the GPIO descriptor management over to the regulator |
---|
| 480 | + * core, remove it from devres management. |
---|
| 481 | + */ |
---|
| 482 | + if (config.ena_gpiod) |
---|
| 483 | + devm_gpiod_unhinge(&pdev->dev, config.ena_gpiod); |
---|
482 | 484 | rdev = devm_regulator_register(&pdev->dev, ri->desc, &config); |
---|
483 | 485 | if (IS_ERR(rdev)) { |
---|
484 | 486 | dev_err(&pdev->dev, "failed to register regulator %s\n", |
---|