From 9999e48639b3cecb08ffb37358bcba3b48161b29 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Fri, 10 May 2024 08:50:17 +0000
Subject: [PATCH] add ax88772_rst
---
kernel/drivers/regulator/of_regulator.c | 219 ++++++++++++++++++++++++++++++++++--------------------
1 files changed, 137 insertions(+), 82 deletions(-)
diff --git a/kernel/drivers/regulator/of_regulator.c b/kernel/drivers/regulator/of_regulator.c
index b255590..b11a434 100644
--- a/kernel/drivers/regulator/of_regulator.c
+++ b/kernel/drivers/regulator/of_regulator.c
@@ -1,13 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* OF helpers for regulator framework
*
* Copyright (C) 2011 Texas Instruments, Inc.
* Rajendra Nayak <rnayak@ti.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
*/
#include <linux/module.h>
@@ -20,11 +16,13 @@
#include "internal.h"
static const char *const regulator_states[PM_SUSPEND_MAX + 1] = {
+ [PM_SUSPEND_STANDBY] = "regulator-state-standby",
[PM_SUSPEND_MEM] = "regulator-state-mem",
[PM_SUSPEND_MAX] = "regulator-state-disk",
};
-static void of_get_regulation_constraints(struct device_node *np,
+static int of_get_regulation_constraints(struct device *dev,
+ struct device_node *np,
struct regulator_init_data **init_data,
const struct regulator_desc *desc)
{
@@ -33,7 +31,12 @@
struct device_node *suspend_np;
unsigned int mode;
int ret, i, len;
+ int n_phandles;
u32 pval;
+
+ n_phandles = of_count_phandle_with_args(np, "regulator-coupled-with",
+ NULL);
+ n_phandles = max(n_phandles, 0);
constraints->name = of_get_property(np, "regulator-name", NULL);
@@ -95,8 +98,8 @@
if (!ret)
constraints->settling_time_up = pval;
if (constraints->settling_time_up && constraints->settling_time) {
- pr_warn("%s: ambiguous configuration for settling time, ignoring 'regulator-settling-time-up-us'\n",
- np->name);
+ pr_warn("%pOFn: ambiguous configuration for settling time, ignoring 'regulator-settling-time-up-us'\n",
+ np);
constraints->settling_time_up = 0;
}
@@ -105,8 +108,8 @@
if (!ret)
constraints->settling_time_down = pval;
if (constraints->settling_time_down && constraints->settling_time) {
- pr_warn("%s: ambiguous configuration for settling time, ignoring 'regulator-settling-time-down-us'\n",
- np->name);
+ pr_warn("%pOFn: ambiguous configuration for settling time, ignoring 'regulator-settling-time-down-us'\n",
+ np);
constraints->settling_time_down = 0;
}
@@ -127,12 +130,12 @@
if (desc && desc->of_map_mode) {
mode = desc->of_map_mode(pval);
if (mode == REGULATOR_MODE_INVALID)
- pr_err("%s: invalid mode %u\n", np->name, pval);
+ pr_err("%pOFn: invalid mode %u\n", np, pval);
else
constraints->initial_mode = mode;
} else {
- pr_warn("%s: mapping for mode %d not defined\n",
- np->name, pval);
+ pr_warn("%pOFn: mapping for mode %d not defined\n",
+ np, pval);
}
}
@@ -144,14 +147,14 @@
ret = of_property_read_u32_index(np,
"regulator-allowed-modes", i, &pval);
if (ret) {
- pr_err("%s: couldn't read allowed modes index %d, ret=%d\n",
- np->name, i, ret);
+ pr_err("%pOFn: couldn't read allowed modes index %d, ret=%d\n",
+ np, i, ret);
break;
}
mode = desc->of_map_mode(pval);
if (mode == REGULATOR_MODE_INVALID)
- pr_err("%s: invalid regulator-allowed-modes element %u\n",
- np->name, pval);
+ pr_err("%pOFn: invalid regulator-allowed-modes element %u\n",
+ np, pval);
else
constraints->valid_modes_mask |= mode;
}
@@ -159,16 +162,28 @@
constraints->valid_ops_mask
|= REGULATOR_CHANGE_MODE;
} else {
- pr_warn("%s: mode mapping not defined\n", np->name);
+ pr_warn("%pOFn: mode mapping not defined\n", np);
}
}
if (!of_property_read_u32(np, "regulator-system-load", &pval))
constraints->system_load = pval;
- if (!of_property_read_u32(np, "regulator-coupled-max-spread",
+ if (n_phandles) {
+ constraints->max_spread = devm_kzalloc(dev,
+ sizeof(*constraints->max_spread) * n_phandles,
+ GFP_KERNEL);
+
+ if (!constraints->max_spread)
+ return -ENOMEM;
+
+ of_property_read_u32_array(np, "regulator-coupled-max-spread",
+ constraints->max_spread, n_phandles);
+ }
+
+ if (!of_property_read_u32(np, "regulator-max-step-microvolt",
&pval))
- constraints->max_spread = pval;
+ constraints->max_uV_step = pval;
constraints->over_current_protection = of_property_read_bool(np,
"regulator-over-current-protection");
@@ -181,29 +196,35 @@
case PM_SUSPEND_MAX:
suspend_state = &constraints->state_disk;
break;
+ case PM_SUSPEND_STANDBY:
+ suspend_state = &constraints->state_standby;
+ break;
case PM_SUSPEND_ON:
case PM_SUSPEND_TO_IDLE:
- case PM_SUSPEND_STANDBY:
default:
continue;
}
suspend_np = of_get_child_by_name(np, regulator_states[i]);
- if (!suspend_np || !suspend_state)
+ if (!suspend_np)
continue;
+ if (!suspend_state) {
+ of_node_put(suspend_np);
+ continue;
+ }
if (!of_property_read_u32(suspend_np, "regulator-mode",
&pval)) {
if (desc && desc->of_map_mode) {
mode = desc->of_map_mode(pval);
if (mode == REGULATOR_MODE_INVALID)
- pr_err("%s: invalid mode %u\n",
- np->name, pval);
+ pr_err("%pOFn: invalid mode %u\n",
+ np, pval);
else
suspend_state->mode = mode;
} else {
- pr_warn("%s: mapping for mode %d not defined\n",
- np->name, pval);
+ pr_warn("%pOFn: mapping for mode %d not defined\n",
+ np, pval);
}
}
@@ -239,6 +260,8 @@
suspend_state = NULL;
suspend_np = NULL;
}
+
+ return 0;
}
/**
@@ -248,7 +271,7 @@
* @desc: regulator description
*
* Populates regulator_init_data structure by extracting data from device
- * tree node, returns a pointer to the populated struture or NULL if memory
+ * tree node, returns a pointer to the populated structure or NULL if memory
* alloc fails.
*/
struct regulator_init_data *of_get_regulator_init_data(struct device *dev,
@@ -264,7 +287,9 @@
if (!init_data)
return NULL; /* Out of memory? */
- of_get_regulation_constraints(node, &init_data, desc);
+ if (of_get_regulation_constraints(dev, node, &init_data, desc))
+ return NULL;
+
return init_data;
}
EXPORT_SYMBOL_GPL(of_get_regulator_init_data);
@@ -349,8 +374,8 @@
match->desc);
if (!match->init_data) {
dev_err(dev,
- "failed to parse DT for regulator %s\n",
- child->name);
+ "failed to parse DT for regulator %pOFn\n",
+ child);
of_node_put(child);
return -EINVAL;
}
@@ -364,23 +389,25 @@
}
EXPORT_SYMBOL_GPL(of_regulator_match);
-struct regulator_init_data *regulator_of_get_init_data(struct device *dev,
- const struct regulator_desc *desc,
- struct regulator_config *config,
- struct device_node **node)
+static struct
+device_node *regulator_of_get_init_node(struct device *dev,
+ const struct regulator_desc *desc)
{
struct device_node *search, *child;
- struct regulator_init_data *init_data = NULL;
const char *name;
if (!dev->of_node || !desc->of_match)
return NULL;
- if (desc->regulators_node)
+ if (desc->regulators_node) {
search = of_get_child_by_name(dev->of_node,
desc->regulators_node);
- else
+ } else {
search = of_node_get(dev->of_node);
+
+ if (!strcmp(desc->of_match, search->name))
+ return search;
+ }
if (!search) {
dev_dbg(dev, "Failed to find regulator container node '%s'\n",
@@ -390,50 +417,73 @@
for_each_available_child_of_node(search, child) {
name = of_get_property(child, "regulator-compatible", NULL);
- if (!name)
- name = child->name;
-
- if (strcmp(desc->of_match, name))
- continue;
-
- init_data = of_get_regulator_init_data(dev, child, desc);
- if (!init_data) {
- dev_err(dev,
- "failed to parse DT for regulator %s\n",
- child->name);
- break;
+ if (!name) {
+ if (!desc->of_match_full_name)
+ name = child->name;
+ else
+ name = child->full_name;
}
- if (desc->of_parse_cb) {
- if (desc->of_parse_cb(child, desc, config)) {
- dev_err(dev,
- "driver callback failed to parse DT for regulator %s\n",
- child->name);
- init_data = NULL;
- break;
- }
+ if (!strcmp(desc->of_match, name)) {
+ of_node_put(search);
+ return of_node_get(child);
}
-
- of_node_get(child);
- *node = child;
- break;
}
of_node_put(search);
- return init_data;
+ return NULL;
}
-static int of_node_match(struct device *dev, const void *data)
+struct regulator_init_data *regulator_of_get_init_data(struct device *dev,
+ const struct regulator_desc *desc,
+ struct regulator_config *config,
+ struct device_node **node)
{
- return dev->of_node == data;
+ struct device_node *child;
+ struct regulator_init_data *init_data = NULL;
+
+ child = regulator_of_get_init_node(dev, desc);
+ if (!child)
+ return NULL;
+
+ init_data = of_get_regulator_init_data(dev, child, desc);
+ if (!init_data) {
+ dev_err(dev, "failed to parse DT for regulator %pOFn\n", child);
+ goto error;
+ }
+
+ if (desc->of_parse_cb) {
+ int ret;
+
+ ret = desc->of_parse_cb(child, desc, config);
+ if (ret) {
+ if (ret == -EPROBE_DEFER) {
+ of_node_put(child);
+ return ERR_PTR(-EPROBE_DEFER);
+ }
+ dev_err(dev,
+ "driver callback failed to parse DT for regulator %pOFn\n",
+ child);
+ goto error;
+ }
+ }
+
+ *node = child;
+
+ return init_data;
+
+error:
+ of_node_put(child);
+
+ return NULL;
}
struct regulator_dev *of_find_regulator_by_node(struct device_node *np)
{
struct device *dev;
- dev = class_find_device(®ulator_class, NULL, np, of_node_match);
+ dev = class_find_device_by_of_node(®ulator_class, np);
return dev ? dev_to_rdev(dev) : NULL;
}
@@ -455,7 +505,8 @@
/* Looks for "to_find" device_node in src's "regulator-coupled-with" property */
static bool of_coupling_find_node(struct device_node *src,
- struct device_node *to_find)
+ struct device_node *to_find,
+ int *index)
{
int n_phandles, i;
bool found = false;
@@ -477,8 +528,10 @@
of_node_put(tmp);
- if (found)
+ if (found) {
+ *index = i;
break;
+ }
}
return found;
@@ -487,7 +540,7 @@
/**
* of_check_coupling_data - Parse rdev's coupling properties and check data
* consistency
- * @rdev - pointer to regulator_dev whose data is checked
+ * @rdev: pointer to regulator_dev whose data is checked
*
* Function checks if all the following conditions are met:
* - rdev's max_spread is greater than 0
@@ -499,21 +552,22 @@
*/
bool of_check_coupling_data(struct regulator_dev *rdev)
{
- int max_spread = rdev->constraints->max_spread;
struct device_node *node = rdev->dev.of_node;
int n_phandles = of_get_n_coupled(rdev);
struct device_node *c_node;
+ int index;
int i;
bool ret = true;
- if (max_spread <= 0) {
- dev_err(&rdev->dev, "max_spread value invalid\n");
- return false;
- }
-
/* iterate over rdev's phandles */
for (i = 0; i < n_phandles; i++) {
+ int max_spread = rdev->constraints->max_spread[i];
int c_max_spread, c_n_phandles;
+
+ if (max_spread <= 0) {
+ dev_err(&rdev->dev, "max_spread value invalid\n");
+ return false;
+ }
c_node = of_parse_phandle(node,
"regulator-coupled-with", i);
@@ -526,13 +580,19 @@
NULL);
if (c_n_phandles != n_phandles) {
- dev_err(&rdev->dev, "number of couped reg phandles mismatch\n");
+ dev_err(&rdev->dev, "number of coupled reg phandles mismatch\n");
ret = false;
goto clean;
}
- if (of_property_read_u32(c_node, "regulator-coupled-max-spread",
- &c_max_spread)) {
+ if (!of_coupling_find_node(c_node, node, &index)) {
+ dev_err(&rdev->dev, "missing 2-way linking for coupled regulators\n");
+ ret = false;
+ goto clean;
+ }
+
+ if (of_property_read_u32_index(c_node, "regulator-coupled-max-spread",
+ index, &c_max_spread)) {
ret = false;
goto clean;
}
@@ -542,11 +602,6 @@
"coupled regulators max_spread mismatch\n");
ret = false;
goto clean;
- }
-
- if (!of_coupling_find_node(c_node, node)) {
- dev_err(&rdev->dev, "missing 2-way linking for coupled regulators\n");
- ret = false;
}
clean:
--
Gitblit v1.6.2