Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
0ed4513c
Commit
0ed4513c
authored
Jul 04, 2019
by
Mark Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'regulator/topic/coupled' into regulator-next
parents
65244e5b
d22b85a1
Changes
5
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
287 additions
and
75 deletions
+287
-75
drivers/regulator/core.c
drivers/regulator/core.c
+143
-51
drivers/regulator/of_regulator.c
drivers/regulator/of_regulator.c
+43
-20
include/linux/regulator/coupler.h
include/linux/regulator/coupler.h
+97
-0
include/linux/regulator/driver.h
include/linux/regulator/driver.h
+3
-3
include/linux/regulator/machine.h
include/linux/regulator/machine.h
+1
-1
No files found.
drivers/regulator/core.c
View file @
0ed4513c
This diff is collapsed.
Click to expand it.
drivers/regulator/of_regulator.c
View file @
0ed4513c
...
...
@@ -21,7 +21,8 @@ static const char *const regulator_states[PM_SUSPEND_MAX + 1] = {
[
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
)
{
...
...
@@ -30,8 +31,13 @@ static void of_get_regulation_constraints(struct device_node *np,
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
);
if
(
!
of_property_read_u32
(
np
,
"regulator-min-microvolt"
,
&
pval
))
...
...
@@ -163,9 +169,17 @@ static void of_get_regulation_constraints(struct device_node *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"
,
&
pval
))
constraints
->
max_spread
=
pval
;
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
))
...
...
@@ -242,6 +256,8 @@ static void of_get_regulation_constraints(struct device_node *np,
suspend_state
=
NULL
;
suspend_np
=
NULL
;
}
return
0
;
}
/**
...
...
@@ -267,7 +283,9 @@ struct regulator_init_data *of_get_regulator_init_data(struct device *dev,
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
);
...
...
@@ -473,7 +491,8 @@ int of_get_n_coupled(struct regulator_dev *rdev)
/* 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
;
...
...
@@ -495,8 +514,10 @@ static bool of_coupling_find_node(struct device_node *src,
of_node_put
(
tmp
);
if
(
found
)
if
(
found
)
{
*
index
=
i
;
break
;
}
}
return
found
;
...
...
@@ -517,22 +538,23 @@ static bool of_coupling_find_node(struct device_node *src,
*/
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
);
...
...
@@ -549,22 +571,23 @@ bool of_check_coupling_data(struct regulator_dev *rdev)
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
(
c_max_spread
!=
max_spread
)
{
dev_err
(
&
rdev
->
dev
,
"coupled regulators max_spread mismatch
\n
"
);
if
(
of_property_read_u32_index
(
c_node
,
"regulator-coupled-max-spread"
,
index
,
&
c_max_spread
))
{
ret
=
false
;
goto
clean
;
}
if
(
!
of_coupling_find_node
(
c_node
,
node
))
{
dev_err
(
&
rdev
->
dev
,
"missing 2-way linking for coupled regulators
\n
"
);
if
(
c_max_spread
!=
max_spread
)
{
dev_err
(
&
rdev
->
dev
,
"coupled regulators max_spread mismatch
\n
"
);
ret
=
false
;
goto
clean
;
}
clean:
...
...
include/linux/regulator/coupler.h
0 → 100644
View file @
0ed4513c
/* SPDX-License-Identifier: GPL-2.0 */
/*
* coupler.h -- SoC Regulator support, coupler API.
*
* Regulator Coupler Interface.
*/
#ifndef __LINUX_REGULATOR_COUPLER_H_
#define __LINUX_REGULATOR_COUPLER_H_
#include <linux/kernel.h>
#include <linux/suspend.h>
struct
regulator_coupler
;
struct
regulator_dev
;
/**
* struct regulator_coupler - customized regulator's coupler
*
* Regulator's coupler allows to customize coupling algorithm.
*
* @list: couplers list entry
* @attach_regulator: Callback invoked on creation of a coupled regulator,
* couples are unresolved at this point. The callee should
* check that it could handle the regulator and return 0 on
* success, -errno on failure and 1 if given regulator is
* not suitable for this coupler (case of having multiple
* regulators in a system). Callback shall be implemented.
* @detach_regulator: Callback invoked on destruction of a coupled regulator.
* This callback is optional and could be NULL.
* @balance_voltage: Callback invoked when voltage of a coupled regulator is
* changing. Called with all of the coupled rdev's being held
* under "consumer lock". The callee should perform voltage
* balancing, changing voltage of the coupled regulators as
* needed. It's up to the coupler to verify the voltage
* before changing it in hardware, i.e. coupler should
* check consumer's min/max and etc. This callback is
* optional and could be NULL, in which case a generic
* voltage balancer will be used.
*/
struct
regulator_coupler
{
struct
list_head
list
;
int
(
*
attach_regulator
)(
struct
regulator_coupler
*
coupler
,
struct
regulator_dev
*
rdev
);
int
(
*
detach_regulator
)(
struct
regulator_coupler
*
coupler
,
struct
regulator_dev
*
rdev
);
int
(
*
balance_voltage
)(
struct
regulator_coupler
*
coupler
,
struct
regulator_dev
*
rdev
,
suspend_state_t
state
);
};
#ifdef CONFIG_REGULATOR
int
regulator_coupler_register
(
struct
regulator_coupler
*
coupler
);
const
char
*
rdev_get_name
(
struct
regulator_dev
*
rdev
);
int
regulator_check_consumers
(
struct
regulator_dev
*
rdev
,
int
*
min_uV
,
int
*
max_uV
,
suspend_state_t
state
);
int
regulator_check_voltage
(
struct
regulator_dev
*
rdev
,
int
*
min_uV
,
int
*
max_uV
);
int
regulator_get_voltage_rdev
(
struct
regulator_dev
*
rdev
);
int
regulator_set_voltage_rdev
(
struct
regulator_dev
*
rdev
,
int
min_uV
,
int
max_uV
,
suspend_state_t
state
);
#else
static
inline
int
regulator_coupler_register
(
struct
regulator_coupler
*
coupler
)
{
return
0
;
}
static
inline
const
char
*
rdev_get_name
(
struct
regulator_dev
*
rdev
)
{
return
NULL
;
}
static
inline
int
regulator_check_consumers
(
struct
regulator_dev
*
rdev
,
int
*
min_uV
,
int
*
max_uV
,
suspend_state_t
state
)
{
return
-
EINVAL
;
}
static
inline
int
regulator_check_voltage
(
struct
regulator_dev
*
rdev
,
int
*
min_uV
,
int
*
max_uV
)
{
return
-
EINVAL
;
}
static
inline
int
regulator_get_voltage_rdev
(
struct
regulator_dev
*
rdev
)
{
return
-
EINVAL
;
}
static
inline
int
regulator_set_voltage_rdev
(
struct
regulator_dev
*
rdev
,
int
min_uV
,
int
max_uV
,
suspend_state_t
state
)
{
return
-
EINVAL
;
}
#endif
#endif
include/linux/regulator/driver.h
View file @
0ed4513c
...
...
@@ -12,8 +12,6 @@
#ifndef __LINUX_REGULATOR_DRIVER_H_
#define __LINUX_REGULATOR_DRIVER_H_
#define MAX_COUPLED 2
#include <linux/device.h>
#include <linux/notifier.h>
#include <linux/regulator/consumer.h>
...
...
@@ -429,7 +427,8 @@ struct regulator_config {
* incremented.
*/
struct
coupling_desc
{
struct
regulator_dev
*
coupled_rdevs
[
MAX_COUPLED
];
struct
regulator_dev
**
coupled_rdevs
;
struct
regulator_coupler
*
coupler
;
int
n_resolved
;
int
n_coupled
;
};
...
...
@@ -555,4 +554,5 @@ void regulator_unlock(struct regulator_dev *rdev);
*/
int
regulator_desc_list_voltage_linear_range
(
const
struct
regulator_desc
*
desc
,
unsigned
int
selector
);
#endif
include/linux/regulator/machine.h
View file @
0ed4513c
...
...
@@ -153,7 +153,7 @@ struct regulation_constraints {
int
system_load
;
/* used for coupled regulators */
int
max_spread
;
u32
*
max_spread
;
/* used for changing voltage in steps */
int
max_uV_step
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment