regulator: Updates for v6.8
The main updates for this release are around monitoring of regulators, largely for error handling purposes. We allow the stream of regulator events to be seen by userspace as netlink events and allow system integrators to describe individual regulators as system critical with information on how long the system is expected to last on error. The system level error handling is very much about best effort problem mitigation rather than providing something fully robust, the initial drive was to provide a mechanism for trying to avoid initiating any new writes to flash once we notice the power going out. Otherwise it's very quiet, mainly several new Qualcomm devices. - Support for marking regulators as system critical and providing information on how long the system might last with those regulators in a failure state, hooked into the existing critical shutdown error handling. - Optional support for generating netlink events for events, there are use cases for system monitoring UIs and error handling. - A command line option to leave unused controllable regulators enabled, useful for debugging. We already only disable regulators we were explicitly given permission to control. - Support for Quacomm MP5496, PM8010 and PM8937. -----BEGIN PGP SIGNATURE----- iQEzBAABCgAdFiEEreZoqmdXGLWf4p/qJNaLcl1Uh9AFAmWbJAkACgkQJNaLcl1U h9AmPwf/SXOxx0sp8xfmt1iJU30dg0L/0MNETf76dPFmCR8Oy1G9PLUqyzNQkTRf bvDrLf9amRRhY4FDCT74VoEiGo7fcduHmjDfYbK/A8bwY1l1UDn0d7hLwgqoyydf p07JbJzCHXAc1PhhMMdgOfdcpYs1Tah91CXOIdbe36pwgGJ8jwodJFD55uhXTsUZ R4PcNs/M2A8rW8SaggopOEzDExdne/ZogpGwclTTWau0OIze2SuPVSsQfrOtAabY BIxaMYKU5tSRdAJOSBNaL9NssUYzyO4q4hXs3Cms1p8XQlzZOVfMZznefdNHoVnw VXlJyEvMREpg8ilwlz7KOyvyF7rshg== =DADk -----END PGP SIGNATURE----- Merge tag 'regulator-v6.8' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator Pull regulator updates from Mark Brown: "The main updates for this release are around monitoring of regulators, largely for error handling purposes. We allow the stream of regulator events to be seen by userspace as netlink events and allow system integrators to describe individual regulators as system critical with information on how long the system is expected to last on error. The system level error handling is very much about best effort problem mitigation rather than providing something fully robust, the initial drive was to provide a mechanism for trying to avoid initiating any new writes to flash once we notice the power going out. Otherwise it's very quiet, mainly several new Qualcomm devices. - Support for marking regulators as system critical and providing information on how long the system might last with those regulators in a failure state, hooked into the existing critical shutdown error handling. - Optional support for generating netlink events for events, there are use cases for system monitoring UIs and error handling. - A command line option to leave unused controllable regulators enabled, useful for debugging. We already only disable regulators we were explicitly given permission to control. - Support for Quacomm MP5496, PM8010 and PM8937" * tag 'regulator-v6.8' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: (31 commits) regulator: event: Ensure atomicity for sequence number uapi: regulator: Fix typo regulator: Reuse LINEAR_RANGE() in REGULATOR_LINEAR_RANGE() dt-bindings: regulator: qcom,usb-vbus-regulator: clean up example regulator: qcom_smd: Add LDO5 MP5496 regulator regulator: qcom-rpmh: add support for pm8010 regulators regulator: dt-bindings: qcom,rpmh: add compatible for pm8010 regulator: qcom-rpmh: extend to support multiple linear voltage ranges regulator: wm8350: Convert to platform remove callback returning void regulator: virtual: Convert to platform remove callback returning void regulator: userspace-consumer: Convert to platform remove callback returning void regulator: uniphier: Convert to platform remove callback returning void regulator: stm32-vrefbuf: Convert to platform remove callback returning void regulator: db8500-prcmu: Convert to platform remove callback returning void regulator: bd9571mwv: Convert to platform remove callback returning void regulator: arizona-ldo1: Convert to platform remove callback returning void regulator: event: Add regulator netlink event support regulator: event: Add regulator netlink event support regulator: stpmic1: Fix kernel-doc notation warnings regulator: palmas: remove redundant initialization of pointer pdata ...
This commit is contained in:
commit
da96801729
@ -5544,6 +5544,13 @@
|
||||
print every Nth verbose statement, where N is the value
|
||||
specified.
|
||||
|
||||
regulator_ignore_unused
|
||||
[REGULATOR]
|
||||
Prevents regulator framework from disabling regulators
|
||||
that are unused, due no driver claiming them. This may
|
||||
be useful for debug and development, but should not be
|
||||
needed on a platform with proper driver support.
|
||||
|
||||
relax_domain_level=
|
||||
[KNL, SMP] Set scheduler's default relax_domain_level.
|
||||
See Documentation/admin-guide/cgroup-v1/cpusets.rst.
|
||||
|
@ -105,6 +105,8 @@ properties:
|
||||
description:
|
||||
Interrupt signaling a critical under-voltage event.
|
||||
|
||||
system-critical-regulator: true
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- regulator-name
|
||||
|
@ -42,6 +42,7 @@ description: |
|
||||
For PM7325, smps1 - smps8, ldo1 - ldo19
|
||||
For PM8005, smps1 - smps4
|
||||
For PM8009, smps1 - smps2, ldo1 - ldo7
|
||||
For PM8010, ldo1 - ldo7
|
||||
For PM8150, smps1 - smps10, ldo1 - ldo18
|
||||
For PM8150L, smps1 - smps8, ldo1 - ldo11, bob, flash, rgb
|
||||
For PM8350, smps1 - smps12, ldo1 - ldo10
|
||||
@ -68,6 +69,7 @@ properties:
|
||||
- qcom,pm8005-rpmh-regulators
|
||||
- qcom,pm8009-rpmh-regulators
|
||||
- qcom,pm8009-1-rpmh-regulators
|
||||
- qcom,pm8010-rpmh-regulators
|
||||
- qcom,pm8150-rpmh-regulators
|
||||
- qcom,pm8150l-rpmh-regulators
|
||||
- qcom,pm8350-rpmh-regulators
|
||||
@ -238,6 +240,18 @@ allOf:
|
||||
"^vdd-l[1-47]-supply$": true
|
||||
"^vdd-s[1-2]-supply$": true
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,pm8010-rpmh-regulators
|
||||
then:
|
||||
properties:
|
||||
vdd-l1-l2-supply: true
|
||||
vdd-l3-l4-supply: true
|
||||
patternProperties:
|
||||
"^vdd-l[5-7]-supply$": true
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
|
@ -47,6 +47,9 @@ description:
|
||||
For pm8916, s1, s2, s3, s4, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11,
|
||||
l12, l13, l14, l15, l16, l17, l18
|
||||
|
||||
For pm8937, s1, s2, s3, s4, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10,
|
||||
l11, l12, l13, l14, l15, l16, l17, l18, l19, l20, l21, l22, l23
|
||||
|
||||
For pm8941, s1, s2, s3, s4, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11,
|
||||
l12, l13, l14, l15, l16, l17, l18, l19, l20, l21, l22, l23, l24, lvs1, lvs2,
|
||||
lvs3, 5vs1, 5vs2
|
||||
@ -92,6 +95,7 @@ properties:
|
||||
- qcom,rpm-pm8841-regulators
|
||||
- qcom,rpm-pm8909-regulators
|
||||
- qcom,rpm-pm8916-regulators
|
||||
- qcom,rpm-pm8937-regulators
|
||||
- qcom,rpm-pm8941-regulators
|
||||
- qcom,rpm-pm8950-regulators
|
||||
- qcom,rpm-pm8953-regulators
|
||||
|
@ -22,6 +22,7 @@ properties:
|
||||
- qcom,pm8841-regulators
|
||||
- qcom,pm8909-regulators
|
||||
- qcom,pm8916-regulators
|
||||
- qcom,pm8937-regulators
|
||||
- qcom,pm8941-regulators
|
||||
- qcom,pm8950-regulators
|
||||
- qcom,pm8994-regulators
|
||||
@ -291,6 +292,24 @@ allOf:
|
||||
patternProperties:
|
||||
"^vdd_s[1-3]-supply$": true
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,pm8937-regulators
|
||||
then:
|
||||
properties:
|
||||
vdd_l1_l19-supply: true
|
||||
vdd_l20_l21-supply: true
|
||||
vdd_l2_l23-supply: true
|
||||
vdd_l3-supply: true
|
||||
vdd_l4_l5_l6_l7_l16-supply: true
|
||||
vdd_l8_l11_l12_l17_l22-supply: true
|
||||
vdd_l9_l10_l13_l14_l15_l18-supply: true
|
||||
patternProperties:
|
||||
"^vdd_s[1-6]-supply$": true
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
|
@ -36,10 +36,11 @@ unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
pm8150b {
|
||||
pmic {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
pm8150b_vbus: usb-vbus-regulator@1100 {
|
||||
|
||||
usb-vbus-regulator@1100 {
|
||||
compatible = "qcom,pm8150b-vbus-reg";
|
||||
reg = <0x1100>;
|
||||
regulator-min-microamp = <500000>;
|
||||
|
@ -114,6 +114,11 @@ properties:
|
||||
description: Enable pull down resistor when the regulator is disabled.
|
||||
type: boolean
|
||||
|
||||
system-critical-regulator:
|
||||
description: Set if the regulator is critical to system stability or
|
||||
functionality.
|
||||
type: boolean
|
||||
|
||||
regulator-over-current-protection:
|
||||
description: Enable over current protection.
|
||||
type: boolean
|
||||
@ -181,6 +186,14 @@ properties:
|
||||
be enabled but limit setting can be omitted. Limit is given as microvolt
|
||||
offset from voltage set to regulator.
|
||||
|
||||
regulator-uv-less-critical-window-ms:
|
||||
description: Specifies the time window (in milliseconds) following a
|
||||
critical under-voltage event during which the system can continue to
|
||||
operate safely while performing less critical operations. This property
|
||||
provides a defined duration before a more severe reaction to the
|
||||
under-voltage event is needed, allowing for certain non-urgent actions to
|
||||
be carried out in preparation for potential power loss.
|
||||
|
||||
regulator-temp-protection-kelvin:
|
||||
description: Set over temperature protection limit. This is a limit where
|
||||
hardware performs emergency shutdown. Zero can be passed to disable
|
||||
|
@ -56,6 +56,16 @@ config REGULATOR_USERSPACE_CONSUMER
|
||||
|
||||
If unsure, say no.
|
||||
|
||||
config REGULATOR_NETLINK_EVENTS
|
||||
bool "Enable support for receiving regulator events via netlink"
|
||||
depends on NET
|
||||
help
|
||||
Enabling this option allows the kernel to broadcast regulator events using
|
||||
the netlink mechanism. User-space applications can subscribe to these events
|
||||
for real-time updates on various regulator events.
|
||||
|
||||
If unsure, say no.
|
||||
|
||||
config REGULATOR_88PG86X
|
||||
tristate "Marvell 88PG86X voltage regulators"
|
||||
depends on I2C
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
|
||||
obj-$(CONFIG_REGULATOR) += core.o dummy.o fixed-helper.o helpers.o devres.o irq_helpers.o
|
||||
obj-$(CONFIG_REGULATOR_NETLINK_EVENTS) += event.o
|
||||
obj-$(CONFIG_OF) += of_regulator.o
|
||||
obj-$(CONFIG_REGULATOR_FIXED_VOLTAGE) += fixed.o
|
||||
obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o
|
||||
|
@ -339,14 +339,12 @@ static int arizona_ldo1_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int arizona_ldo1_remove(struct platform_device *pdev)
|
||||
static void arizona_ldo1_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct arizona_ldo1 *ldo1 = platform_get_drvdata(pdev);
|
||||
|
||||
if (ldo1->ena_gpiod)
|
||||
gpiod_put(ldo1->ena_gpiod);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int madera_ldo1_probe(struct platform_device *pdev)
|
||||
@ -377,7 +375,7 @@ static int madera_ldo1_probe(struct platform_device *pdev)
|
||||
|
||||
static struct platform_driver arizona_ldo1_driver = {
|
||||
.probe = arizona_ldo1_probe,
|
||||
.remove = arizona_ldo1_remove,
|
||||
.remove_new = arizona_ldo1_remove,
|
||||
.driver = {
|
||||
.name = "arizona-ldo1",
|
||||
.probe_type = PROBE_FORCE_SYNCHRONOUS,
|
||||
@ -386,7 +384,7 @@ static struct platform_driver arizona_ldo1_driver = {
|
||||
|
||||
static struct platform_driver madera_ldo1_driver = {
|
||||
.probe = madera_ldo1_probe,
|
||||
.remove = arizona_ldo1_remove,
|
||||
.remove_new = arizona_ldo1_remove,
|
||||
.driver = {
|
||||
.name = "madera-ldo1",
|
||||
.probe_type = PROBE_FORCE_SYNCHRONOUS,
|
||||
|
@ -260,10 +260,9 @@ static const struct dev_pm_ops bd9571mwv_pm = {
|
||||
SET_SYSTEM_SLEEP_PM_OPS(bd9571mwv_suspend, bd9571mwv_resume)
|
||||
};
|
||||
|
||||
static int bd9571mwv_regulator_remove(struct platform_device *pdev)
|
||||
static void bd9571mwv_regulator_remove(struct platform_device *pdev)
|
||||
{
|
||||
device_remove_file(&pdev->dev, &dev_attr_backup_mode);
|
||||
return 0;
|
||||
}
|
||||
#define DEV_PM_OPS &bd9571mwv_pm
|
||||
#else
|
||||
@ -357,7 +356,7 @@ static struct platform_driver bd9571mwv_regulator_driver = {
|
||||
.pm = DEV_PM_OPS,
|
||||
},
|
||||
.probe = bd9571mwv_regulator_probe,
|
||||
.remove = bd9571mwv_regulator_remove,
|
||||
.remove_new = bd9571mwv_regulator_remove,
|
||||
.id_table = bd9571mwv_regulator_id_table,
|
||||
};
|
||||
module_platform_driver(bd9571mwv_regulator_driver);
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/regulator/of_regulator.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
@ -32,6 +33,7 @@
|
||||
|
||||
#include "dummy.h"
|
||||
#include "internal.h"
|
||||
#include "regnl.h"
|
||||
|
||||
static DEFINE_WW_CLASS(regulator_ww_class);
|
||||
static DEFINE_MUTEX(regulator_nesting_mutex);
|
||||
@ -2918,7 +2920,8 @@ static int _regulator_enable(struct regulator *regulator)
|
||||
/* Fallthrough on positive return values - already enabled */
|
||||
}
|
||||
|
||||
rdev->use_count++;
|
||||
if (regulator->enable_count == 1)
|
||||
rdev->use_count++;
|
||||
|
||||
return 0;
|
||||
|
||||
@ -2993,37 +2996,40 @@ static int _regulator_disable(struct regulator *regulator)
|
||||
|
||||
lockdep_assert_held_once(&rdev->mutex.base);
|
||||
|
||||
if (WARN(rdev->use_count <= 0,
|
||||
if (WARN(regulator->enable_count == 0,
|
||||
"unbalanced disables for %s\n", rdev_get_name(rdev)))
|
||||
return -EIO;
|
||||
|
||||
/* are we the last user and permitted to disable ? */
|
||||
if (rdev->use_count == 1 &&
|
||||
(rdev->constraints && !rdev->constraints->always_on)) {
|
||||
if (regulator->enable_count == 1) {
|
||||
/* disabling last enable_count from this regulator */
|
||||
/* are we the last user and permitted to disable ? */
|
||||
if (rdev->use_count == 1 &&
|
||||
(rdev->constraints && !rdev->constraints->always_on)) {
|
||||
|
||||
/* we are last user */
|
||||
if (regulator_ops_is_valid(rdev, REGULATOR_CHANGE_STATUS)) {
|
||||
ret = _notifier_call_chain(rdev,
|
||||
REGULATOR_EVENT_PRE_DISABLE,
|
||||
NULL);
|
||||
if (ret & NOTIFY_STOP_MASK)
|
||||
return -EINVAL;
|
||||
/* we are last user */
|
||||
if (regulator_ops_is_valid(rdev, REGULATOR_CHANGE_STATUS)) {
|
||||
ret = _notifier_call_chain(rdev,
|
||||
REGULATOR_EVENT_PRE_DISABLE,
|
||||
NULL);
|
||||
if (ret & NOTIFY_STOP_MASK)
|
||||
return -EINVAL;
|
||||
|
||||
ret = _regulator_do_disable(rdev);
|
||||
if (ret < 0) {
|
||||
rdev_err(rdev, "failed to disable: %pe\n", ERR_PTR(ret));
|
||||
_notifier_call_chain(rdev,
|
||||
REGULATOR_EVENT_ABORT_DISABLE,
|
||||
ret = _regulator_do_disable(rdev);
|
||||
if (ret < 0) {
|
||||
rdev_err(rdev, "failed to disable: %pe\n", ERR_PTR(ret));
|
||||
_notifier_call_chain(rdev,
|
||||
REGULATOR_EVENT_ABORT_DISABLE,
|
||||
NULL);
|
||||
return ret;
|
||||
}
|
||||
_notifier_call_chain(rdev, REGULATOR_EVENT_DISABLE,
|
||||
NULL);
|
||||
return ret;
|
||||
}
|
||||
_notifier_call_chain(rdev, REGULATOR_EVENT_DISABLE,
|
||||
NULL);
|
||||
}
|
||||
|
||||
rdev->use_count = 0;
|
||||
} else if (rdev->use_count > 1) {
|
||||
rdev->use_count--;
|
||||
rdev->use_count = 0;
|
||||
} else if (rdev->use_count > 1) {
|
||||
rdev->use_count--;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
@ -4849,7 +4855,23 @@ static int _notifier_call_chain(struct regulator_dev *rdev,
|
||||
unsigned long event, void *data)
|
||||
{
|
||||
/* call rdev chain first */
|
||||
return blocking_notifier_call_chain(&rdev->notifier, event, data);
|
||||
int ret = blocking_notifier_call_chain(&rdev->notifier, event, data);
|
||||
|
||||
if (IS_REACHABLE(CONFIG_REGULATOR_NETLINK_EVENTS)) {
|
||||
struct device *parent = rdev->dev.parent;
|
||||
const char *rname = rdev_get_name(rdev);
|
||||
char name[32];
|
||||
|
||||
/* Avoid duplicate debugfs directory names */
|
||||
if (parent && rname == rdev->desc->name) {
|
||||
snprintf(name, sizeof(name), "%s-%s", dev_name(parent),
|
||||
rname);
|
||||
rname = name;
|
||||
}
|
||||
reg_generate_netlink_event(rname, event);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int _regulator_bulk_get(struct device *dev, int num_consumers,
|
||||
@ -5061,6 +5083,41 @@ void regulator_bulk_free(int num_consumers,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(regulator_bulk_free);
|
||||
|
||||
/**
|
||||
* regulator_handle_critical - Handle events for system-critical regulators.
|
||||
* @rdev: The regulator device.
|
||||
* @event: The event being handled.
|
||||
*
|
||||
* This function handles critical events such as under-voltage, over-current,
|
||||
* and unknown errors for regulators deemed system-critical. On detecting such
|
||||
* events, it triggers a hardware protection shutdown with a defined timeout.
|
||||
*/
|
||||
static void regulator_handle_critical(struct regulator_dev *rdev,
|
||||
unsigned long event)
|
||||
{
|
||||
const char *reason = NULL;
|
||||
|
||||
if (!rdev->constraints->system_critical)
|
||||
return;
|
||||
|
||||
switch (event) {
|
||||
case REGULATOR_EVENT_UNDER_VOLTAGE:
|
||||
reason = "System critical regulator: voltage drop detected";
|
||||
break;
|
||||
case REGULATOR_EVENT_OVER_CURRENT:
|
||||
reason = "System critical regulator: over-current detected";
|
||||
break;
|
||||
case REGULATOR_EVENT_FAIL:
|
||||
reason = "System critical regulator: unknown error";
|
||||
}
|
||||
|
||||
if (!reason)
|
||||
return;
|
||||
|
||||
hw_protection_shutdown(reason,
|
||||
rdev->constraints->uv_less_critical_window_ms);
|
||||
}
|
||||
|
||||
/**
|
||||
* regulator_notifier_call_chain - call regulator event notifier
|
||||
* @rdev: regulator source
|
||||
@ -5073,6 +5130,8 @@ EXPORT_SYMBOL_GPL(regulator_bulk_free);
|
||||
int regulator_notifier_call_chain(struct regulator_dev *rdev,
|
||||
unsigned long event, void *data)
|
||||
{
|
||||
regulator_handle_critical(rdev, event);
|
||||
|
||||
_notifier_call_chain(rdev, event, data);
|
||||
return NOTIFY_DONE;
|
||||
|
||||
@ -6234,6 +6293,14 @@ unlock:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool regulator_ignore_unused;
|
||||
static int __init regulator_ignore_unused_setup(char *__unused)
|
||||
{
|
||||
regulator_ignore_unused = true;
|
||||
return 1;
|
||||
}
|
||||
__setup("regulator_ignore_unused", regulator_ignore_unused_setup);
|
||||
|
||||
static void regulator_init_complete_work_function(struct work_struct *work)
|
||||
{
|
||||
/*
|
||||
@ -6246,6 +6313,15 @@ static void regulator_init_complete_work_function(struct work_struct *work)
|
||||
class_for_each_device(®ulator_class, NULL, NULL,
|
||||
regulator_register_resolve_supply);
|
||||
|
||||
/*
|
||||
* For debugging purposes, it may be useful to prevent unused
|
||||
* regulators from being disabled.
|
||||
*/
|
||||
if (regulator_ignore_unused) {
|
||||
pr_warn("regulator: Not disabling unused regulators\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* If we have a full configuration then disable any regulators
|
||||
* we have permission to change the status for and which are
|
||||
* not in use or always_on. This is effectively the default
|
||||
|
@ -469,11 +469,9 @@ static int db8500_regulator_probe(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int db8500_regulator_remove(struct platform_device *pdev)
|
||||
static void db8500_regulator_remove(struct platform_device *pdev)
|
||||
{
|
||||
ux500_regulator_debug_exit();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver db8500_regulator_driver = {
|
||||
@ -482,7 +480,7 @@ static struct platform_driver db8500_regulator_driver = {
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
},
|
||||
.probe = db8500_regulator_probe,
|
||||
.remove = db8500_regulator_remove,
|
||||
.remove_new = db8500_regulator_remove,
|
||||
};
|
||||
|
||||
static int __init db8500_regulator_init(void)
|
||||
|
91
drivers/regulator/event.c
Normal file
91
drivers/regulator/event.c
Normal file
@ -0,0 +1,91 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Regulator event over netlink
|
||||
*
|
||||
* Author: Naresh Solanki <Naresh.Solanki@9elements.com>
|
||||
*/
|
||||
|
||||
#include <regulator/regulator.h>
|
||||
#include <net/netlink.h>
|
||||
#include <net/genetlink.h>
|
||||
#include <linux/atomic.h>
|
||||
|
||||
#include "regnl.h"
|
||||
|
||||
static atomic_t reg_event_seqnum = ATOMIC_INIT(0);
|
||||
|
||||
static const struct genl_multicast_group reg_event_mcgrps[] = {
|
||||
{ .name = REG_GENL_MCAST_GROUP_NAME, },
|
||||
};
|
||||
|
||||
static struct genl_family reg_event_genl_family __ro_after_init = {
|
||||
.module = THIS_MODULE,
|
||||
.name = REG_GENL_FAMILY_NAME,
|
||||
.version = REG_GENL_VERSION,
|
||||
.maxattr = REG_GENL_ATTR_MAX,
|
||||
.mcgrps = reg_event_mcgrps,
|
||||
.n_mcgrps = ARRAY_SIZE(reg_event_mcgrps),
|
||||
};
|
||||
|
||||
int reg_generate_netlink_event(const char *reg_name, u64 event)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
struct nlattr *attr;
|
||||
struct reg_genl_event *edata;
|
||||
void *msg_header;
|
||||
int size;
|
||||
|
||||
/* allocate memory */
|
||||
size = nla_total_size(sizeof(struct reg_genl_event)) +
|
||||
nla_total_size(0);
|
||||
|
||||
skb = genlmsg_new(size, GFP_ATOMIC);
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
/* add the genetlink message header */
|
||||
msg_header = genlmsg_put(skb, 0, atomic_inc_return(®_event_seqnum),
|
||||
®_event_genl_family, 0, REG_GENL_CMD_EVENT);
|
||||
if (!msg_header) {
|
||||
nlmsg_free(skb);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* fill the data */
|
||||
attr = nla_reserve(skb, REG_GENL_ATTR_EVENT, sizeof(struct reg_genl_event));
|
||||
if (!attr) {
|
||||
nlmsg_free(skb);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
edata = nla_data(attr);
|
||||
memset(edata, 0, sizeof(struct reg_genl_event));
|
||||
|
||||
strscpy(edata->reg_name, reg_name, sizeof(edata->reg_name));
|
||||
edata->event = event;
|
||||
|
||||
/* send multicast genetlink message */
|
||||
genlmsg_end(skb, msg_header);
|
||||
size = genlmsg_multicast(®_event_genl_family, skb, 0, 0, GFP_ATOMIC);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static int __init reg_event_genetlink_init(void)
|
||||
{
|
||||
return genl_register_family(®_event_genl_family);
|
||||
}
|
||||
|
||||
static int __init reg_event_init(void)
|
||||
{
|
||||
int error;
|
||||
|
||||
/* create genetlink for acpi event */
|
||||
error = reg_event_genetlink_init();
|
||||
if (error)
|
||||
pr_warn("Failed to create genetlink family for reg event\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
fs_initcall(reg_event_init);
|
@ -131,6 +131,8 @@ static int of_get_regulation_constraints(struct device *dev,
|
||||
constraints->valid_ops_mask |= REGULATOR_CHANGE_STATUS;
|
||||
|
||||
constraints->pull_down = of_property_read_bool(np, "regulator-pull-down");
|
||||
constraints->system_critical = of_property_read_bool(np,
|
||||
"system-critical-regulator");
|
||||
|
||||
if (of_property_read_bool(np, "regulator-allow-bypass"))
|
||||
constraints->valid_ops_mask |= REGULATOR_CHANGE_BYPASS;
|
||||
@ -173,6 +175,13 @@ static int of_get_regulation_constraints(struct device *dev,
|
||||
if (!ret)
|
||||
constraints->enable_time = pval;
|
||||
|
||||
ret = of_property_read_u32(np, "regulator-uv-survival-time-ms", &pval);
|
||||
if (!ret)
|
||||
constraints->uv_less_critical_window_ms = pval;
|
||||
else
|
||||
constraints->uv_less_critical_window_ms =
|
||||
REGULATOR_DEF_UV_LESS_CRITICAL_WINDOW_MS;
|
||||
|
||||
constraints->soft_start = of_property_read_bool(np,
|
||||
"regulator-soft-start");
|
||||
ret = of_property_read_u32(np, "regulator-active-discharge", &pval);
|
||||
|
@ -1594,7 +1594,7 @@ static const struct of_device_id of_palmas_match_tbl[] = {
|
||||
static int palmas_regulators_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct palmas *palmas = dev_get_drvdata(pdev->dev.parent);
|
||||
struct palmas_pmic_platform_data *pdata = dev_get_platdata(&pdev->dev);
|
||||
struct palmas_pmic_platform_data *pdata;
|
||||
struct device_node *node = pdev->dev.of_node;
|
||||
struct palmas_pmic_driver_data *driver_data;
|
||||
struct regulator_config config = { };
|
||||
|
@ -1,5 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
|
||||
// Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
|
||||
#define pr_fmt(fmt) "%s: " fmt, __func__
|
||||
|
||||
@ -68,10 +69,11 @@ enum rpmh_regulator_type {
|
||||
* @regulator_type: RPMh accelerator type used to manage this
|
||||
* regulator
|
||||
* @ops: Pointer to regulator ops callback structure
|
||||
* @voltage_range: The single range of voltages supported by this
|
||||
* PMIC regulator type
|
||||
* @voltage_ranges: The possible ranges of voltages supported by this
|
||||
* PMIC regulator type
|
||||
* @n_linear_ranges: Number of entries in voltage_ranges
|
||||
* @n_voltages: The number of unique voltage set points defined
|
||||
* by voltage_range
|
||||
* by voltage_ranges
|
||||
* @hpm_min_load_uA: Minimum load current in microamps that requires
|
||||
* high power mode (HPM) operation. This is used
|
||||
* for LDO hardware type regulators only.
|
||||
@ -85,7 +87,8 @@ enum rpmh_regulator_type {
|
||||
struct rpmh_vreg_hw_data {
|
||||
enum rpmh_regulator_type regulator_type;
|
||||
const struct regulator_ops *ops;
|
||||
const struct linear_range voltage_range;
|
||||
const struct linear_range *voltage_ranges;
|
||||
int n_linear_ranges;
|
||||
int n_voltages;
|
||||
int hpm_min_load_uA;
|
||||
const int *pmic_mode_map;
|
||||
@ -449,8 +452,8 @@ static int rpmh_regulator_init_vreg(struct rpmh_vreg *vreg, struct device *dev,
|
||||
vreg->mode = REGULATOR_MODE_INVALID;
|
||||
|
||||
if (rpmh_data->hw_data->n_voltages) {
|
||||
vreg->rdesc.linear_ranges = &rpmh_data->hw_data->voltage_range;
|
||||
vreg->rdesc.n_linear_ranges = 1;
|
||||
vreg->rdesc.linear_ranges = rpmh_data->hw_data->voltage_ranges;
|
||||
vreg->rdesc.n_linear_ranges = rpmh_data->hw_data->n_linear_ranges;
|
||||
vreg->rdesc.n_voltages = rpmh_data->hw_data->n_voltages;
|
||||
}
|
||||
|
||||
@ -508,6 +511,14 @@ static const int pmic_mode_map_pmic5_ldo[REGULATOR_MODE_STANDBY + 1] = {
|
||||
[REGULATOR_MODE_FAST] = -EINVAL,
|
||||
};
|
||||
|
||||
static const int pmic_mode_map_pmic5_ldo_hpm[REGULATOR_MODE_STANDBY + 1] = {
|
||||
[REGULATOR_MODE_INVALID] = -EINVAL,
|
||||
[REGULATOR_MODE_STANDBY] = -EINVAL,
|
||||
[REGULATOR_MODE_IDLE] = -EINVAL,
|
||||
[REGULATOR_MODE_NORMAL] = PMIC5_LDO_MODE_HPM,
|
||||
[REGULATOR_MODE_FAST] = -EINVAL,
|
||||
};
|
||||
|
||||
static unsigned int rpmh_regulator_pmic4_ldo_of_map_mode(unsigned int rpmh_mode)
|
||||
{
|
||||
unsigned int mode;
|
||||
@ -613,7 +624,10 @@ static unsigned int rpmh_regulator_pmic4_bob_of_map_mode(unsigned int rpmh_mode)
|
||||
static const struct rpmh_vreg_hw_data pmic4_pldo = {
|
||||
.regulator_type = VRM,
|
||||
.ops = &rpmh_regulator_vrm_drms_ops,
|
||||
.voltage_range = REGULATOR_LINEAR_RANGE(1664000, 0, 255, 8000),
|
||||
.voltage_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(1664000, 0, 255, 8000),
|
||||
},
|
||||
.n_linear_ranges = 1,
|
||||
.n_voltages = 256,
|
||||
.hpm_min_load_uA = 10000,
|
||||
.pmic_mode_map = pmic_mode_map_pmic4_ldo,
|
||||
@ -623,7 +637,10 @@ static const struct rpmh_vreg_hw_data pmic4_pldo = {
|
||||
static const struct rpmh_vreg_hw_data pmic4_pldo_lv = {
|
||||
.regulator_type = VRM,
|
||||
.ops = &rpmh_regulator_vrm_drms_ops,
|
||||
.voltage_range = REGULATOR_LINEAR_RANGE(1256000, 0, 127, 8000),
|
||||
.voltage_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(1256000, 0, 127, 8000),
|
||||
},
|
||||
.n_linear_ranges = 1,
|
||||
.n_voltages = 128,
|
||||
.hpm_min_load_uA = 10000,
|
||||
.pmic_mode_map = pmic_mode_map_pmic4_ldo,
|
||||
@ -633,7 +650,10 @@ static const struct rpmh_vreg_hw_data pmic4_pldo_lv = {
|
||||
static const struct rpmh_vreg_hw_data pmic4_nldo = {
|
||||
.regulator_type = VRM,
|
||||
.ops = &rpmh_regulator_vrm_drms_ops,
|
||||
.voltage_range = REGULATOR_LINEAR_RANGE(312000, 0, 127, 8000),
|
||||
.voltage_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(312000, 0, 127, 8000),
|
||||
},
|
||||
.n_linear_ranges = 1,
|
||||
.n_voltages = 128,
|
||||
.hpm_min_load_uA = 30000,
|
||||
.pmic_mode_map = pmic_mode_map_pmic4_ldo,
|
||||
@ -643,7 +663,10 @@ static const struct rpmh_vreg_hw_data pmic4_nldo = {
|
||||
static const struct rpmh_vreg_hw_data pmic4_hfsmps3 = {
|
||||
.regulator_type = VRM,
|
||||
.ops = &rpmh_regulator_vrm_ops,
|
||||
.voltage_range = REGULATOR_LINEAR_RANGE(320000, 0, 215, 8000),
|
||||
.voltage_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(320000, 0, 215, 8000),
|
||||
},
|
||||
.n_linear_ranges = 1,
|
||||
.n_voltages = 216,
|
||||
.pmic_mode_map = pmic_mode_map_pmic4_smps,
|
||||
.of_map_mode = rpmh_regulator_pmic4_smps_of_map_mode,
|
||||
@ -652,7 +675,10 @@ static const struct rpmh_vreg_hw_data pmic4_hfsmps3 = {
|
||||
static const struct rpmh_vreg_hw_data pmic4_ftsmps426 = {
|
||||
.regulator_type = VRM,
|
||||
.ops = &rpmh_regulator_vrm_ops,
|
||||
.voltage_range = REGULATOR_LINEAR_RANGE(320000, 0, 258, 4000),
|
||||
.voltage_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(320000, 0, 258, 4000),
|
||||
},
|
||||
.n_linear_ranges = 1,
|
||||
.n_voltages = 259,
|
||||
.pmic_mode_map = pmic_mode_map_pmic4_smps,
|
||||
.of_map_mode = rpmh_regulator_pmic4_smps_of_map_mode,
|
||||
@ -661,7 +687,10 @@ static const struct rpmh_vreg_hw_data pmic4_ftsmps426 = {
|
||||
static const struct rpmh_vreg_hw_data pmic4_bob = {
|
||||
.regulator_type = VRM,
|
||||
.ops = &rpmh_regulator_vrm_bypass_ops,
|
||||
.voltage_range = REGULATOR_LINEAR_RANGE(1824000, 0, 83, 32000),
|
||||
.voltage_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(1824000, 0, 83, 32000),
|
||||
},
|
||||
.n_linear_ranges = 1,
|
||||
.n_voltages = 84,
|
||||
.pmic_mode_map = pmic_mode_map_pmic4_bob,
|
||||
.of_map_mode = rpmh_regulator_pmic4_bob_of_map_mode,
|
||||
@ -676,7 +705,10 @@ static const struct rpmh_vreg_hw_data pmic4_lvs = {
|
||||
static const struct rpmh_vreg_hw_data pmic5_pldo = {
|
||||
.regulator_type = VRM,
|
||||
.ops = &rpmh_regulator_vrm_drms_ops,
|
||||
.voltage_range = REGULATOR_LINEAR_RANGE(1504000, 0, 255, 8000),
|
||||
.voltage_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(1504000, 0, 255, 8000),
|
||||
},
|
||||
.n_linear_ranges = 1,
|
||||
.n_voltages = 256,
|
||||
.hpm_min_load_uA = 10000,
|
||||
.pmic_mode_map = pmic_mode_map_pmic5_ldo,
|
||||
@ -686,7 +718,10 @@ static const struct rpmh_vreg_hw_data pmic5_pldo = {
|
||||
static const struct rpmh_vreg_hw_data pmic5_pldo_lv = {
|
||||
.regulator_type = VRM,
|
||||
.ops = &rpmh_regulator_vrm_drms_ops,
|
||||
.voltage_range = REGULATOR_LINEAR_RANGE(1504000, 0, 62, 8000),
|
||||
.voltage_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(1504000, 0, 62, 8000),
|
||||
},
|
||||
.n_linear_ranges = 1,
|
||||
.n_voltages = 63,
|
||||
.hpm_min_load_uA = 10000,
|
||||
.pmic_mode_map = pmic_mode_map_pmic5_ldo,
|
||||
@ -696,17 +731,50 @@ static const struct rpmh_vreg_hw_data pmic5_pldo_lv = {
|
||||
static const struct rpmh_vreg_hw_data pmic5_pldo515_mv = {
|
||||
.regulator_type = VRM,
|
||||
.ops = &rpmh_regulator_vrm_drms_ops,
|
||||
.voltage_range = REGULATOR_LINEAR_RANGE(1800000, 0, 187, 8000),
|
||||
.voltage_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(1800000, 0, 187, 8000),
|
||||
},
|
||||
.n_linear_ranges = 1,
|
||||
.n_voltages = 188,
|
||||
.hpm_min_load_uA = 10000,
|
||||
.pmic_mode_map = pmic_mode_map_pmic5_ldo,
|
||||
.of_map_mode = rpmh_regulator_pmic4_ldo_of_map_mode,
|
||||
};
|
||||
|
||||
static const struct rpmh_vreg_hw_data pmic5_pldo502 = {
|
||||
.regulator_type = VRM,
|
||||
.ops = &rpmh_regulator_vrm_ops,
|
||||
.voltage_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(1504000, 0, 255, 8000),
|
||||
},
|
||||
.n_linear_ranges = 1,
|
||||
.n_voltages = 256,
|
||||
.pmic_mode_map = pmic_mode_map_pmic5_ldo_hpm,
|
||||
.of_map_mode = rpmh_regulator_pmic4_ldo_of_map_mode,
|
||||
};
|
||||
|
||||
static const struct rpmh_vreg_hw_data pmic5_pldo502ln = {
|
||||
.regulator_type = VRM,
|
||||
.ops = &rpmh_regulator_vrm_ops,
|
||||
.voltage_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(1800000, 0, 2, 200000),
|
||||
REGULATOR_LINEAR_RANGE(2608000, 3, 28, 16000),
|
||||
REGULATOR_LINEAR_RANGE(3104000, 29, 30, 96000),
|
||||
REGULATOR_LINEAR_RANGE(3312000, 31, 31, 0),
|
||||
},
|
||||
.n_linear_ranges = 4,
|
||||
.n_voltages = 32,
|
||||
.pmic_mode_map = pmic_mode_map_pmic5_ldo_hpm,
|
||||
.of_map_mode = rpmh_regulator_pmic4_ldo_of_map_mode,
|
||||
};
|
||||
|
||||
static const struct rpmh_vreg_hw_data pmic5_nldo = {
|
||||
.regulator_type = VRM,
|
||||
.ops = &rpmh_regulator_vrm_drms_ops,
|
||||
.voltage_range = REGULATOR_LINEAR_RANGE(320000, 0, 123, 8000),
|
||||
.voltage_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(320000, 0, 123, 8000),
|
||||
},
|
||||
.n_linear_ranges = 1,
|
||||
.n_voltages = 124,
|
||||
.hpm_min_load_uA = 30000,
|
||||
.pmic_mode_map = pmic_mode_map_pmic5_ldo,
|
||||
@ -716,17 +784,36 @@ static const struct rpmh_vreg_hw_data pmic5_nldo = {
|
||||
static const struct rpmh_vreg_hw_data pmic5_nldo515 = {
|
||||
.regulator_type = VRM,
|
||||
.ops = &rpmh_regulator_vrm_drms_ops,
|
||||
.voltage_range = REGULATOR_LINEAR_RANGE(320000, 0, 210, 8000),
|
||||
.voltage_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(320000, 0, 210, 8000),
|
||||
},
|
||||
.n_linear_ranges = 1,
|
||||
.n_voltages = 211,
|
||||
.hpm_min_load_uA = 30000,
|
||||
.pmic_mode_map = pmic_mode_map_pmic5_ldo,
|
||||
.of_map_mode = rpmh_regulator_pmic4_ldo_of_map_mode,
|
||||
};
|
||||
|
||||
static const struct rpmh_vreg_hw_data pmic5_nldo502 = {
|
||||
.regulator_type = VRM,
|
||||
.ops = &rpmh_regulator_vrm_drms_ops,
|
||||
.voltage_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(528000, 0, 127, 8000),
|
||||
},
|
||||
.n_linear_ranges = 1,
|
||||
.n_voltages = 128,
|
||||
.hpm_min_load_uA = 30000,
|
||||
.pmic_mode_map = pmic_mode_map_pmic5_ldo,
|
||||
.of_map_mode = rpmh_regulator_pmic4_ldo_of_map_mode,
|
||||
};
|
||||
|
||||
static const struct rpmh_vreg_hw_data pmic5_hfsmps510 = {
|
||||
.regulator_type = VRM,
|
||||
.ops = &rpmh_regulator_vrm_ops,
|
||||
.voltage_range = REGULATOR_LINEAR_RANGE(320000, 0, 215, 8000),
|
||||
.voltage_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(320000, 0, 215, 8000),
|
||||
},
|
||||
.n_linear_ranges = 1,
|
||||
.n_voltages = 216,
|
||||
.pmic_mode_map = pmic_mode_map_pmic5_smps,
|
||||
.of_map_mode = rpmh_regulator_pmic4_smps_of_map_mode,
|
||||
@ -735,7 +822,10 @@ static const struct rpmh_vreg_hw_data pmic5_hfsmps510 = {
|
||||
static const struct rpmh_vreg_hw_data pmic5_ftsmps510 = {
|
||||
.regulator_type = VRM,
|
||||
.ops = &rpmh_regulator_vrm_ops,
|
||||
.voltage_range = REGULATOR_LINEAR_RANGE(300000, 0, 263, 4000),
|
||||
.voltage_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(300000, 0, 263, 4000),
|
||||
},
|
||||
.n_linear_ranges = 1,
|
||||
.n_voltages = 264,
|
||||
.pmic_mode_map = pmic_mode_map_pmic5_smps,
|
||||
.of_map_mode = rpmh_regulator_pmic4_smps_of_map_mode,
|
||||
@ -744,7 +834,10 @@ static const struct rpmh_vreg_hw_data pmic5_ftsmps510 = {
|
||||
static const struct rpmh_vreg_hw_data pmic5_ftsmps520 = {
|
||||
.regulator_type = VRM,
|
||||
.ops = &rpmh_regulator_vrm_ops,
|
||||
.voltage_range = REGULATOR_LINEAR_RANGE(300000, 0, 263, 4000),
|
||||
.voltage_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(300000, 0, 263, 4000),
|
||||
},
|
||||
.n_linear_ranges = 1,
|
||||
.n_voltages = 264,
|
||||
.pmic_mode_map = pmic_mode_map_pmic5_smps,
|
||||
.of_map_mode = rpmh_regulator_pmic4_smps_of_map_mode,
|
||||
@ -753,7 +846,10 @@ static const struct rpmh_vreg_hw_data pmic5_ftsmps520 = {
|
||||
static const struct rpmh_vreg_hw_data pmic5_ftsmps525_lv = {
|
||||
.regulator_type = VRM,
|
||||
.ops = &rpmh_regulator_vrm_ops,
|
||||
.voltage_range = REGULATOR_LINEAR_RANGE(300000, 0, 267, 4000),
|
||||
.voltage_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(300000, 0, 267, 4000),
|
||||
},
|
||||
.n_linear_ranges = 1,
|
||||
.n_voltages = 268,
|
||||
.pmic_mode_map = pmic_mode_map_pmic5_smps,
|
||||
.of_map_mode = rpmh_regulator_pmic4_smps_of_map_mode,
|
||||
@ -762,7 +858,10 @@ static const struct rpmh_vreg_hw_data pmic5_ftsmps525_lv = {
|
||||
static const struct rpmh_vreg_hw_data pmic5_ftsmps525_mv = {
|
||||
.regulator_type = VRM,
|
||||
.ops = &rpmh_regulator_vrm_ops,
|
||||
.voltage_range = REGULATOR_LINEAR_RANGE(600000, 0, 267, 8000),
|
||||
.voltage_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(600000, 0, 267, 8000),
|
||||
},
|
||||
.n_linear_ranges = 1,
|
||||
.n_voltages = 268,
|
||||
.pmic_mode_map = pmic_mode_map_pmic5_smps,
|
||||
.of_map_mode = rpmh_regulator_pmic4_smps_of_map_mode,
|
||||
@ -771,7 +870,10 @@ static const struct rpmh_vreg_hw_data pmic5_ftsmps525_mv = {
|
||||
static const struct rpmh_vreg_hw_data pmic5_ftsmps527 = {
|
||||
.regulator_type = VRM,
|
||||
.ops = &rpmh_regulator_vrm_ops,
|
||||
.voltage_range = REGULATOR_LINEAR_RANGE(320000, 0, 215, 8000),
|
||||
.voltage_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(320000, 0, 215, 8000),
|
||||
},
|
||||
.n_linear_ranges = 1,
|
||||
.n_voltages = 215,
|
||||
.pmic_mode_map = pmic_mode_map_pmic5_smps,
|
||||
.of_map_mode = rpmh_regulator_pmic4_smps_of_map_mode,
|
||||
@ -780,7 +882,10 @@ static const struct rpmh_vreg_hw_data pmic5_ftsmps527 = {
|
||||
static const struct rpmh_vreg_hw_data pmic5_hfsmps515 = {
|
||||
.regulator_type = VRM,
|
||||
.ops = &rpmh_regulator_vrm_ops,
|
||||
.voltage_range = REGULATOR_LINEAR_RANGE(320000, 0, 235, 16000),
|
||||
.voltage_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(320000, 0, 235, 16000),
|
||||
},
|
||||
.n_linear_ranges = 1,
|
||||
.n_voltages = 236,
|
||||
.pmic_mode_map = pmic_mode_map_pmic5_smps,
|
||||
.of_map_mode = rpmh_regulator_pmic4_smps_of_map_mode,
|
||||
@ -789,7 +894,10 @@ static const struct rpmh_vreg_hw_data pmic5_hfsmps515 = {
|
||||
static const struct rpmh_vreg_hw_data pmic5_hfsmps515_1 = {
|
||||
.regulator_type = VRM,
|
||||
.ops = &rpmh_regulator_vrm_ops,
|
||||
.voltage_range = REGULATOR_LINEAR_RANGE(900000, 0, 4, 16000),
|
||||
.voltage_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(900000, 0, 4, 16000),
|
||||
},
|
||||
.n_linear_ranges = 1,
|
||||
.n_voltages = 5,
|
||||
.pmic_mode_map = pmic_mode_map_pmic5_smps,
|
||||
.of_map_mode = rpmh_regulator_pmic4_smps_of_map_mode,
|
||||
@ -798,7 +906,10 @@ static const struct rpmh_vreg_hw_data pmic5_hfsmps515_1 = {
|
||||
static const struct rpmh_vreg_hw_data pmic5_bob = {
|
||||
.regulator_type = VRM,
|
||||
.ops = &rpmh_regulator_vrm_bypass_ops,
|
||||
.voltage_range = REGULATOR_LINEAR_RANGE(3000000, 0, 31, 32000),
|
||||
.voltage_ranges = (struct linear_range[]) {
|
||||
REGULATOR_LINEAR_RANGE(3000000, 0, 31, 32000),
|
||||
},
|
||||
.n_linear_ranges = 1,
|
||||
.n_voltages = 32,
|
||||
.pmic_mode_map = pmic_mode_map_pmic5_bob,
|
||||
.of_map_mode = rpmh_regulator_pmic4_bob_of_map_mode,
|
||||
@ -1147,6 +1258,16 @@ static const struct rpmh_vreg_init_data pm8009_1_vreg_data[] = {
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct rpmh_vreg_init_data pm8010_vreg_data[] = {
|
||||
RPMH_VREG("ldo1", "ldo%s1", &pmic5_nldo502, "vdd-l1-l2"),
|
||||
RPMH_VREG("ldo2", "ldo%s2", &pmic5_nldo502, "vdd-l1-l2"),
|
||||
RPMH_VREG("ldo3", "ldo%s3", &pmic5_pldo502ln, "vdd-l3-l4"),
|
||||
RPMH_VREG("ldo4", "ldo%s4", &pmic5_pldo502ln, "vdd-l3-l4"),
|
||||
RPMH_VREG("ldo5", "ldo%s5", &pmic5_pldo502, "vdd-l5"),
|
||||
RPMH_VREG("ldo6", "ldo%s6", &pmic5_pldo502ln, "vdd-l6"),
|
||||
RPMH_VREG("ldo7", "ldo%s7", &pmic5_pldo502, "vdd-l7"),
|
||||
};
|
||||
|
||||
static const struct rpmh_vreg_init_data pm6150_vreg_data[] = {
|
||||
RPMH_VREG("smps1", "smp%s1", &pmic5_ftsmps510, "vdd-s1"),
|
||||
RPMH_VREG("smps2", "smp%s2", &pmic5_ftsmps510, "vdd-s2"),
|
||||
@ -1462,6 +1583,10 @@ static const struct of_device_id __maybe_unused rpmh_regulator_match_table[] = {
|
||||
.compatible = "qcom,pm8009-1-rpmh-regulators",
|
||||
.data = pm8009_1_vreg_data,
|
||||
},
|
||||
{
|
||||
.compatible = "qcom,pm8010-rpmh-regulators",
|
||||
.data = pm8010_vreg_data,
|
||||
},
|
||||
{
|
||||
.compatible = "qcom,pm8150-rpmh-regulators",
|
||||
.data = pm8150_vreg_data,
|
||||
|
@ -796,6 +796,7 @@ static const struct rpm_regulator_data rpm_mp5496_regulators[] = {
|
||||
{ "s1", QCOM_SMD_RPM_SMPA, 1, &mp5496_smps, "s1" },
|
||||
{ "s2", QCOM_SMD_RPM_SMPA, 2, &mp5496_smps, "s2" },
|
||||
{ "l2", QCOM_SMD_RPM_LDOA, 2, &mp5496_ldoa2, "l2" },
|
||||
{ "l5", QCOM_SMD_RPM_LDOA, 5, &mp5496_ldoa2, "l5" },
|
||||
{}
|
||||
};
|
||||
|
||||
@ -1012,6 +1013,39 @@ static const struct rpm_regulator_data rpm_pm8916_regulators[] = {
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct rpm_regulator_data rpm_pm8937_regulators[] = {
|
||||
{ "s1", QCOM_SMD_RPM_SMPA, 1, &pm8994_hfsmps, "vdd_s1" },
|
||||
{ "s2", QCOM_SMD_RPM_SMPA, 2, &pm8994_hfsmps, "vdd_s2" },
|
||||
{ "s3", QCOM_SMD_RPM_SMPA, 3, &pm8994_hfsmps, "vdd_s3" },
|
||||
{ "s4", QCOM_SMD_RPM_SMPA, 4, &pm8994_hfsmps, "vdd_s4" },
|
||||
/* S5 - S6 are managed by SPMI */
|
||||
|
||||
{ "l1", QCOM_SMD_RPM_LDOA, 1, &pm8953_ult_nldo, "vdd_l1_l19" },
|
||||
{ "l2", QCOM_SMD_RPM_LDOA, 2, &pm8953_ult_nldo, "vdd_l2_l23" },
|
||||
{ "l3", QCOM_SMD_RPM_LDOA, 3, &pm8953_ult_nldo, "vdd_l3" },
|
||||
{ "l4", QCOM_SMD_RPM_LDOA, 4, &pm8950_ult_pldo, "vdd_l4_l5_l6_l7_l16" },
|
||||
{ "l5", QCOM_SMD_RPM_LDOA, 5, &pm8950_ult_pldo, "vdd_l4_l5_l6_l7_l16" },
|
||||
{ "l6", QCOM_SMD_RPM_LDOA, 6, &pm8950_ult_pldo, "vdd_l4_l5_l6_l7_l16" },
|
||||
{ "l7", QCOM_SMD_RPM_LDOA, 7, &pm8950_ult_pldo, "vdd_l4_l5_l6_l7_l16" },
|
||||
{ "l8", QCOM_SMD_RPM_LDOA, 8, &pm8950_ult_pldo, "vdd_l8_l11_l12_l17_l22" },
|
||||
{ "l9", QCOM_SMD_RPM_LDOA, 9, &pm8950_ult_pldo, "vdd_l9_l10_l13_l14_l15_l18" },
|
||||
{ "l10", QCOM_SMD_RPM_LDOA, 10, &pm8950_ult_pldo, "vdd_l9_l10_l13_l14_l15_l18"},
|
||||
{ "l11", QCOM_SMD_RPM_LDOA, 11, &pm8950_ult_pldo, "vdd_l8_l11_l12_l17_l22" },
|
||||
{ "l12", QCOM_SMD_RPM_LDOA, 12, &pm8950_ult_pldo, "vdd_l8_l11_l12_l17_l22" },
|
||||
{ "l13", QCOM_SMD_RPM_LDOA, 13, &pm8950_ult_pldo, "vdd_l9_l10_l13_l14_l15_l18" },
|
||||
{ "l14", QCOM_SMD_RPM_LDOA, 14, &pm8950_ult_pldo, "vdd_l9_l10_l13_l14_l15_l18" },
|
||||
{ "l15", QCOM_SMD_RPM_LDOA, 15, &pm8950_ult_pldo, "vdd_l9_l10_l13_l14_l15_l18" },
|
||||
{ "l16", QCOM_SMD_RPM_LDOA, 16, &pm8950_ult_pldo, "vdd_l4_l5_l6_l7_l16" },
|
||||
{ "l17", QCOM_SMD_RPM_LDOA, 17, &pm8950_ult_pldo, "vdd_l8_l11_l12_l17_l22" },
|
||||
{ "l18", QCOM_SMD_RPM_LDOA, 18, &pm8950_ult_pldo, "vdd_l9_l10_l13_l14_l15_l18" },
|
||||
{ "l19", QCOM_SMD_RPM_LDOA, 19, &pm8953_ult_nldo, "vdd_l1_l19" },
|
||||
{ "l20", QCOM_SMD_RPM_LDOA, 20, &pm8953_lnldo, "vdd_l20_l21" },
|
||||
{ "l21", QCOM_SMD_RPM_LDOA, 21, &pm8953_lnldo, "vdd_l20_l21" },
|
||||
{ "l22", QCOM_SMD_RPM_LDOA, 22, &pm8950_ult_pldo, "vdd_l8_l11_l12_l17_l22" },
|
||||
{ "l23", QCOM_SMD_RPM_LDOA, 23, &pm8994_nldo, "vdd_l2_l23" },
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct rpm_regulator_data rpm_pm8941_regulators[] = {
|
||||
{ "s1", QCOM_SMD_RPM_SMPA, 1, &pm8x41_hfsmps, "vdd_s1" },
|
||||
{ "s2", QCOM_SMD_RPM_SMPA, 2, &pm8x41_hfsmps, "vdd_s2" },
|
||||
@ -1329,6 +1363,7 @@ static const struct of_device_id rpm_of_match[] = {
|
||||
{ .compatible = "qcom,rpm-pm8841-regulators", .data = &rpm_pm8841_regulators },
|
||||
{ .compatible = "qcom,rpm-pm8909-regulators", .data = &rpm_pm8909_regulators },
|
||||
{ .compatible = "qcom,rpm-pm8916-regulators", .data = &rpm_pm8916_regulators },
|
||||
{ .compatible = "qcom,rpm-pm8937-regulators", .data = &rpm_pm8937_regulators },
|
||||
{ .compatible = "qcom,rpm-pm8941-regulators", .data = &rpm_pm8941_regulators },
|
||||
{ .compatible = "qcom,rpm-pm8950-regulators", .data = &rpm_pm8950_regulators },
|
||||
{ .compatible = "qcom,rpm-pm8953-regulators", .data = &rpm_pm8953_regulators },
|
||||
|
@ -2239,6 +2239,39 @@ static const struct spmi_regulator_data pm8916_regulators[] = {
|
||||
{ }
|
||||
};
|
||||
|
||||
static const struct spmi_regulator_data pm8937_regulators[] = {
|
||||
{ "s1", 0x1400, "vdd_s1", },
|
||||
{ "s2", 0x1700, "vdd_s2", },
|
||||
{ "s3", 0x1a00, "vdd_s3", },
|
||||
{ "s4", 0x1d00, "vdd_s4", },
|
||||
{ "s5", 0x2000, "vdd_s5", },
|
||||
{ "s6", 0x2300, "vdd_s6", },
|
||||
{ "l1", 0x4000, "vdd_l1_l19", },
|
||||
{ "l2", 0x4100, "vdd_l2_l23", },
|
||||
{ "l3", 0x4200, "vdd_l3", },
|
||||
{ "l4", 0x4300, "vdd_l4_l5_l6_l7_l16", },
|
||||
{ "l5", 0x4400, "vdd_l4_l5_l6_l7_l16", },
|
||||
{ "l6", 0x4500, "vdd_l4_l5_l6_l7_l16", },
|
||||
{ "l7", 0x4600, "vdd_l4_l5_l6_l7_l16", },
|
||||
{ "l8", 0x4700, "vdd_l8_l11_l12_l17_l22", },
|
||||
{ "l9", 0x4800, "vdd_l9_l10_l13_l14_l15_l18", },
|
||||
{ "l10", 0x4900, "vdd_l9_l10_l13_l14_l15_l18", },
|
||||
{ "l11", 0x4a00, "vdd_l8_l11_l12_l17_l22", },
|
||||
{ "l12", 0x4b00, "vdd_l8_l11_l12_l17_l22", },
|
||||
{ "l13", 0x4c00, "vdd_l9_l10_l13_l14_l15_l18", },
|
||||
{ "l14", 0x4d00, "vdd_l9_l10_l13_l14_l15_l18", },
|
||||
{ "l15", 0x4e00, "vdd_l9_l10_l13_l14_l15_l18", },
|
||||
{ "l16", 0x4f00, "vdd_l4_l5_l6_l7_l16", },
|
||||
{ "l17", 0x5000, "vdd_l8_l11_l12_l17_l22", },
|
||||
{ "l18", 0x5100, "vdd_l9_l10_l13_l14_l15_l18", },
|
||||
{ "l19", 0x5200, "vdd_l1_l19", },
|
||||
{ "l20", 0x5300, "vdd_l20_l21", },
|
||||
{ "l21", 0x5400, "vdd_l21_l21", },
|
||||
{ "l22", 0x5500, "vdd_l8_l11_l12_l17_l22", },
|
||||
{ "l23", 0x5600, "vdd_l2_l23", },
|
||||
{ }
|
||||
};
|
||||
|
||||
static const struct spmi_regulator_data pm8941_regulators[] = {
|
||||
{ "s1", 0x1400, "vdd_s1", },
|
||||
{ "s2", 0x1700, "vdd_s2", },
|
||||
@ -2453,6 +2486,7 @@ static const struct of_device_id qcom_spmi_regulator_match[] = {
|
||||
{ .compatible = "qcom,pm8841-regulators", .data = &pm8841_regulators },
|
||||
{ .compatible = "qcom,pm8909-regulators", .data = &pm8909_regulators },
|
||||
{ .compatible = "qcom,pm8916-regulators", .data = &pm8916_regulators },
|
||||
{ .compatible = "qcom,pm8937-regulators", .data = &pm8937_regulators },
|
||||
{ .compatible = "qcom,pm8941-regulators", .data = &pm8941_regulators },
|
||||
{ .compatible = "qcom,pm8950-regulators", .data = &pm8950_regulators },
|
||||
{ .compatible = "qcom,pm8994-regulators", .data = &pm8994_regulators },
|
||||
|
13
drivers/regulator/regnl.h
Normal file
13
drivers/regulator/regnl.h
Normal file
@ -0,0 +1,13 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Regulator event over netlink
|
||||
*
|
||||
* Author: Naresh Solanki <Naresh.Solanki@9elements.com>
|
||||
*/
|
||||
|
||||
#ifndef __REGULATOR_EVENT_H
|
||||
#define __REGULATOR_EVENT_H
|
||||
|
||||
int reg_generate_netlink_event(const char *reg_name, u64 event);
|
||||
|
||||
#endif
|
@ -233,7 +233,7 @@ err_pm_stop:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int stm32_vrefbuf_remove(struct platform_device *pdev)
|
||||
static void stm32_vrefbuf_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct regulator_dev *rdev = platform_get_drvdata(pdev);
|
||||
struct stm32_vrefbuf *priv = rdev_get_drvdata(rdev);
|
||||
@ -244,8 +244,6 @@ static int stm32_vrefbuf_remove(struct platform_device *pdev)
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
pm_runtime_set_suspended(&pdev->dev);
|
||||
pm_runtime_put_noidle(&pdev->dev);
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
static int __maybe_unused stm32_vrefbuf_runtime_suspend(struct device *dev)
|
||||
@ -282,7 +280,7 @@ MODULE_DEVICE_TABLE(of, stm32_vrefbuf_of_match);
|
||||
|
||||
static struct platform_driver stm32_vrefbuf_driver = {
|
||||
.probe = stm32_vrefbuf_probe,
|
||||
.remove = stm32_vrefbuf_remove,
|
||||
.remove_new = stm32_vrefbuf_remove,
|
||||
.driver = {
|
||||
.name = "stm32-vrefbuf",
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
|
@ -15,7 +15,7 @@
|
||||
#include <dt-bindings/mfd/st,stpmic1.h>
|
||||
|
||||
/**
|
||||
* struct stpmic1 regulator description: this structure is used as driver data
|
||||
* struct stpmic1_regulator_cfg - this structure is used as driver data
|
||||
* @desc: regulator framework description
|
||||
* @mask_reset_reg: mask reset register address
|
||||
* @mask_reset_mask: mask rank and mask reset register mask
|
||||
|
@ -115,7 +115,7 @@ out_rst_assert:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int uniphier_regulator_remove(struct platform_device *pdev)
|
||||
static void uniphier_regulator_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct uniphier_regulator_priv *priv = platform_get_drvdata(pdev);
|
||||
int i;
|
||||
@ -124,8 +124,6 @@ static int uniphier_regulator_remove(struct platform_device *pdev)
|
||||
reset_control_assert(priv->rst[i]);
|
||||
|
||||
clk_bulk_disable_unprepare(priv->data->nclks, priv->clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* USB3 controller data */
|
||||
@ -209,7 +207,7 @@ MODULE_DEVICE_TABLE(of, uniphier_regulator_match);
|
||||
|
||||
static struct platform_driver uniphier_regulator_driver = {
|
||||
.probe = uniphier_regulator_probe,
|
||||
.remove = uniphier_regulator_remove,
|
||||
.remove_new = uniphier_regulator_remove,
|
||||
.driver = {
|
||||
.name = "uniphier-regulator",
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
|
@ -194,7 +194,7 @@ err_enable:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int regulator_userspace_consumer_remove(struct platform_device *pdev)
|
||||
static void regulator_userspace_consumer_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct userspace_consumer_data *data = platform_get_drvdata(pdev);
|
||||
|
||||
@ -202,8 +202,6 @@ static int regulator_userspace_consumer_remove(struct platform_device *pdev)
|
||||
|
||||
if (data->enabled && !data->no_autoswitch)
|
||||
regulator_bulk_disable(data->num_supplies, data->supplies);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id regulator_userspace_consumer_of_match[] = {
|
||||
@ -213,7 +211,7 @@ static const struct of_device_id regulator_userspace_consumer_of_match[] = {
|
||||
|
||||
static struct platform_driver regulator_userspace_consumer_driver = {
|
||||
.probe = regulator_userspace_consumer_probe,
|
||||
.remove = regulator_userspace_consumer_remove,
|
||||
.remove_new = regulator_userspace_consumer_remove,
|
||||
.driver = {
|
||||
.name = "reg-userspace-consumer",
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
|
@ -345,7 +345,7 @@ static int regulator_virtual_probe(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int regulator_virtual_remove(struct platform_device *pdev)
|
||||
static void regulator_virtual_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct virtual_consumer_data *drvdata = platform_get_drvdata(pdev);
|
||||
|
||||
@ -353,13 +353,11 @@ static int regulator_virtual_remove(struct platform_device *pdev)
|
||||
|
||||
if (drvdata->enabled)
|
||||
regulator_disable(drvdata->regulator);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver regulator_virtual_consumer_driver = {
|
||||
.probe = regulator_virtual_probe,
|
||||
.remove = regulator_virtual_remove,
|
||||
.remove_new = regulator_virtual_remove,
|
||||
.driver = {
|
||||
.name = "reg-virt-consumer",
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
|
@ -1158,14 +1158,12 @@ static int wm8350_regulator_probe(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wm8350_regulator_remove(struct platform_device *pdev)
|
||||
static void wm8350_regulator_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct regulator_dev *rdev = platform_get_drvdata(pdev);
|
||||
struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
|
||||
|
||||
wm8350_free_irq(wm8350, wm8350_reg[pdev->id].irq, rdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wm8350_register_regulator(struct wm8350 *wm8350, int reg,
|
||||
@ -1306,7 +1304,7 @@ EXPORT_SYMBOL_GPL(wm8350_register_led);
|
||||
|
||||
static struct platform_driver wm8350_regulator_driver = {
|
||||
.probe = wm8350_regulator_probe,
|
||||
.remove = wm8350_regulator_remove,
|
||||
.remove_new = wm8350_regulator_remove,
|
||||
.driver = {
|
||||
.name = "wm8350-regulator",
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
|
@ -33,6 +33,7 @@
|
||||
|
||||
#include <linux/err.h>
|
||||
#include <linux/suspend.h>
|
||||
#include <regulator/regulator.h>
|
||||
|
||||
struct device;
|
||||
struct notifier_block;
|
||||
@ -84,52 +85,6 @@ struct regulator_dev;
|
||||
#define REGULATOR_MODE_IDLE 0x4
|
||||
#define REGULATOR_MODE_STANDBY 0x8
|
||||
|
||||
/*
|
||||
* Regulator notifier events.
|
||||
*
|
||||
* UNDER_VOLTAGE Regulator output is under voltage.
|
||||
* OVER_CURRENT Regulator output current is too high.
|
||||
* REGULATION_OUT Regulator output is out of regulation.
|
||||
* FAIL Regulator output has failed.
|
||||
* OVER_TEMP Regulator over temp.
|
||||
* FORCE_DISABLE Regulator forcibly shut down by software.
|
||||
* VOLTAGE_CHANGE Regulator voltage changed.
|
||||
* Data passed is old voltage cast to (void *).
|
||||
* DISABLE Regulator was disabled.
|
||||
* PRE_VOLTAGE_CHANGE Regulator is about to have voltage changed.
|
||||
* Data passed is "struct pre_voltage_change_data"
|
||||
* ABORT_VOLTAGE_CHANGE Regulator voltage change failed for some reason.
|
||||
* Data passed is old voltage cast to (void *).
|
||||
* PRE_DISABLE Regulator is about to be disabled
|
||||
* ABORT_DISABLE Regulator disable failed for some reason
|
||||
*
|
||||
* NOTE: These events can be OR'ed together when passed into handler.
|
||||
*/
|
||||
|
||||
#define REGULATOR_EVENT_UNDER_VOLTAGE 0x01
|
||||
#define REGULATOR_EVENT_OVER_CURRENT 0x02
|
||||
#define REGULATOR_EVENT_REGULATION_OUT 0x04
|
||||
#define REGULATOR_EVENT_FAIL 0x08
|
||||
#define REGULATOR_EVENT_OVER_TEMP 0x10
|
||||
#define REGULATOR_EVENT_FORCE_DISABLE 0x20
|
||||
#define REGULATOR_EVENT_VOLTAGE_CHANGE 0x40
|
||||
#define REGULATOR_EVENT_DISABLE 0x80
|
||||
#define REGULATOR_EVENT_PRE_VOLTAGE_CHANGE 0x100
|
||||
#define REGULATOR_EVENT_ABORT_VOLTAGE_CHANGE 0x200
|
||||
#define REGULATOR_EVENT_PRE_DISABLE 0x400
|
||||
#define REGULATOR_EVENT_ABORT_DISABLE 0x800
|
||||
#define REGULATOR_EVENT_ENABLE 0x1000
|
||||
/*
|
||||
* Following notifications should be emitted only if detected condition
|
||||
* is such that the HW is likely to still be working but consumers should
|
||||
* take a recovery action to prevent problems esacalating into errors.
|
||||
*/
|
||||
#define REGULATOR_EVENT_UNDER_VOLTAGE_WARN 0x2000
|
||||
#define REGULATOR_EVENT_OVER_CURRENT_WARN 0x4000
|
||||
#define REGULATOR_EVENT_OVER_VOLTAGE_WARN 0x8000
|
||||
#define REGULATOR_EVENT_OVER_TEMP_WARN 0x10000
|
||||
#define REGULATOR_EVENT_WARN_MASK 0x1E000
|
||||
|
||||
/*
|
||||
* Regulator errors that can be queried using regulator_get_error_flags
|
||||
*
|
||||
|
@ -51,12 +51,7 @@ enum regulator_detection_severity {
|
||||
|
||||
/* Initialize struct linear_range for regulators */
|
||||
#define REGULATOR_LINEAR_RANGE(_min_uV, _min_sel, _max_sel, _step_uV) \
|
||||
{ \
|
||||
.min = _min_uV, \
|
||||
.min_sel = _min_sel, \
|
||||
.max_sel = _max_sel, \
|
||||
.step = _step_uV, \
|
||||
}
|
||||
LINEAR_RANGE(_min_uV, _min_sel, _max_sel, _step_uV)
|
||||
|
||||
/**
|
||||
* struct regulator_ops - regulator operations.
|
||||
|
@ -49,6 +49,13 @@ struct regulator;
|
||||
#define DISABLE_IN_SUSPEND 1
|
||||
#define ENABLE_IN_SUSPEND 2
|
||||
|
||||
/*
|
||||
* Default time window (in milliseconds) following a critical under-voltage
|
||||
* event during which less critical actions can be safely carried out by the
|
||||
* system.
|
||||
*/
|
||||
#define REGULATOR_DEF_UV_LESS_CRITICAL_WINDOW_MS 10
|
||||
|
||||
/* Regulator active discharge flags */
|
||||
enum regulator_active_discharge {
|
||||
REGULATOR_ACTIVE_DISCHARGE_DEFAULT,
|
||||
@ -127,6 +134,8 @@ struct notification_limit {
|
||||
* @ramp_disable: Disable ramp delay when initialising or when setting voltage.
|
||||
* @soft_start: Enable soft start so that voltage ramps slowly.
|
||||
* @pull_down: Enable pull down when regulator is disabled.
|
||||
* @system_critical: Set if the regulator is critical to system stability or
|
||||
* functionality.
|
||||
* @over_current_protection: Auto disable on over current event.
|
||||
*
|
||||
* @over_current_detection: Configure over current limits.
|
||||
@ -153,6 +162,13 @@ struct notification_limit {
|
||||
* regulator_active_discharge values are used for
|
||||
* initialisation.
|
||||
* @enable_time: Turn-on time of the rails (unit: microseconds)
|
||||
* @uv_less_critical_window_ms: Specifies the time window (in milliseconds)
|
||||
* following a critical under-voltage (UV) event
|
||||
* during which less critical actions can be
|
||||
* safely carried out by the system (for example
|
||||
* logging). After this time window more critical
|
||||
* actions should be done (for example prevent
|
||||
* HW damage).
|
||||
*/
|
||||
struct regulation_constraints {
|
||||
|
||||
@ -204,6 +220,7 @@ struct regulation_constraints {
|
||||
unsigned int settling_time_up;
|
||||
unsigned int settling_time_down;
|
||||
unsigned int enable_time;
|
||||
unsigned int uv_less_critical_window_ms;
|
||||
|
||||
unsigned int active_discharge;
|
||||
|
||||
@ -214,6 +231,7 @@ struct regulation_constraints {
|
||||
unsigned ramp_disable:1; /* disable ramp delay */
|
||||
unsigned soft_start:1; /* ramp voltage slowly */
|
||||
unsigned pull_down:1; /* pull down resistor when regulator off */
|
||||
unsigned system_critical:1; /* critical to system stability */
|
||||
unsigned over_current_protection:1; /* auto disable on over current */
|
||||
unsigned over_current_detection:1; /* notify on over current */
|
||||
unsigned over_voltage_detection:1; /* notify on over voltage */
|
||||
|
90
include/uapi/regulator/regulator.h
Normal file
90
include/uapi/regulator/regulator.h
Normal file
@ -0,0 +1,90 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
* Regulator uapi header
|
||||
*
|
||||
* Author: Naresh Solanki <Naresh.Solanki@9elements.com>
|
||||
*/
|
||||
|
||||
#ifndef _UAPI_REGULATOR_H
|
||||
#define _UAPI_REGULATOR_H
|
||||
|
||||
#ifdef __KERNEL__
|
||||
#include <linux/types.h>
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Regulator notifier events.
|
||||
*
|
||||
* UNDER_VOLTAGE Regulator output is under voltage.
|
||||
* OVER_CURRENT Regulator output current is too high.
|
||||
* REGULATION_OUT Regulator output is out of regulation.
|
||||
* FAIL Regulator output has failed.
|
||||
* OVER_TEMP Regulator over temp.
|
||||
* FORCE_DISABLE Regulator forcibly shut down by software.
|
||||
* VOLTAGE_CHANGE Regulator voltage changed.
|
||||
* Data passed is old voltage cast to (void *).
|
||||
* DISABLE Regulator was disabled.
|
||||
* PRE_VOLTAGE_CHANGE Regulator is about to have voltage changed.
|
||||
* Data passed is "struct pre_voltage_change_data"
|
||||
* ABORT_VOLTAGE_CHANGE Regulator voltage change failed for some reason.
|
||||
* Data passed is old voltage cast to (void *).
|
||||
* PRE_DISABLE Regulator is about to be disabled
|
||||
* ABORT_DISABLE Regulator disable failed for some reason
|
||||
*
|
||||
* NOTE: These events can be OR'ed together when passed into handler.
|
||||
*/
|
||||
|
||||
#define REGULATOR_EVENT_UNDER_VOLTAGE 0x01
|
||||
#define REGULATOR_EVENT_OVER_CURRENT 0x02
|
||||
#define REGULATOR_EVENT_REGULATION_OUT 0x04
|
||||
#define REGULATOR_EVENT_FAIL 0x08
|
||||
#define REGULATOR_EVENT_OVER_TEMP 0x10
|
||||
#define REGULATOR_EVENT_FORCE_DISABLE 0x20
|
||||
#define REGULATOR_EVENT_VOLTAGE_CHANGE 0x40
|
||||
#define REGULATOR_EVENT_DISABLE 0x80
|
||||
#define REGULATOR_EVENT_PRE_VOLTAGE_CHANGE 0x100
|
||||
#define REGULATOR_EVENT_ABORT_VOLTAGE_CHANGE 0x200
|
||||
#define REGULATOR_EVENT_PRE_DISABLE 0x400
|
||||
#define REGULATOR_EVENT_ABORT_DISABLE 0x800
|
||||
#define REGULATOR_EVENT_ENABLE 0x1000
|
||||
/*
|
||||
* Following notifications should be emitted only if detected condition
|
||||
* is such that the HW is likely to still be working but consumers should
|
||||
* take a recovery action to prevent problems escalating into errors.
|
||||
*/
|
||||
#define REGULATOR_EVENT_UNDER_VOLTAGE_WARN 0x2000
|
||||
#define REGULATOR_EVENT_OVER_CURRENT_WARN 0x4000
|
||||
#define REGULATOR_EVENT_OVER_VOLTAGE_WARN 0x8000
|
||||
#define REGULATOR_EVENT_OVER_TEMP_WARN 0x10000
|
||||
#define REGULATOR_EVENT_WARN_MASK 0x1E000
|
||||
|
||||
struct reg_genl_event {
|
||||
char reg_name[32];
|
||||
uint64_t event;
|
||||
};
|
||||
|
||||
/* attributes of reg_genl_family */
|
||||
enum {
|
||||
REG_GENL_ATTR_UNSPEC,
|
||||
REG_GENL_ATTR_EVENT, /* reg event info needed by user space */
|
||||
__REG_GENL_ATTR_MAX,
|
||||
};
|
||||
|
||||
#define REG_GENL_ATTR_MAX (__REG_GENL_ATTR_MAX - 1)
|
||||
|
||||
/* commands supported by the reg_genl_family */
|
||||
enum {
|
||||
REG_GENL_CMD_UNSPEC,
|
||||
REG_GENL_CMD_EVENT, /* kernel->user notifications for reg events */
|
||||
__REG_GENL_CMD_MAX,
|
||||
};
|
||||
|
||||
#define REG_GENL_CMD_MAX (__REG_GENL_CMD_MAX - 1)
|
||||
|
||||
#define REG_GENL_FAMILY_NAME "reg_event"
|
||||
#define REG_GENL_VERSION 0x01
|
||||
#define REG_GENL_MCAST_GROUP_NAME "reg_mc_group"
|
||||
|
||||
#endif /* _UAPI_REGULATOR_H */
|
Loading…
x
Reference in New Issue
Block a user