mirror of
https://github.com/Dasharo/linux.git
synced 2026-03-06 15:25:10 -08:00
Merge tag 'for-v6.9' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply
Pull power supply and reset updates from Sebastian Reichel: "New features: - axp20x_usb_power: report USB type Cleanups: - convert lots of drivers to use devm_power_supply_register() - convert lots of reset drivers to use devm_register_sys_off_handler() - constify device_type and power_supply_class - axp20x_usb_power: use correct property to report input current limit - mm8013: correct handling of "not charging" status register - core: fix charge_behaviour formatting - minor fixes cleanups" * tag 'for-v6.9' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply: (66 commits) power: supply: core: fix charge_behaviour formatting power: supply: core: ease special formatting implementations power: supply: mm8013: fix "not charging" detection power: supply: move power_supply_attr_groups definition back to sysfs power: supply: core: simplify power_supply_class_init power: supply: core: add power_supply_for_each_device() power: supply: core: make power_supply_class constant power: supply: bq2415x_charger: report online status power: supply: core: move power_supply_attr_group into #ifdef block power: supply: core: Fix power_supply_init_attrs() stub power: supply: bq27xxx: Report charge full state correctly power: reset: rmobile-reset: Make sysc_base2 local power: supply: core: constify the struct device_type usage power: supply: axp288_fuel_gauge: Deny ROCK Pi X power: reset: rmobile-reset: Map correct MMIO resource power: reset: xgene-reboot: Fix a NULL vs IS_ERR() test power: supply: axp288_fuel_gauge: Add STCK1A* Intel Compute Sticks to the deny-list power: reset: syscon-poweroff: Use devm_register_sys_off_handler(POWER_OFF) power: reset: syscon-poweroff: Move device data into a struct power: reset: restart-poweroff: Use devm_register_sys_off_handler(POWER_OFF) ...
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
struct as3722_poweroff {
|
||||
@@ -18,22 +19,18 @@ struct as3722_poweroff {
|
||||
struct as3722 *as3722;
|
||||
};
|
||||
|
||||
static struct as3722_poweroff *as3722_pm_poweroff;
|
||||
|
||||
static void as3722_pm_power_off(void)
|
||||
static int as3722_pm_power_off(struct sys_off_data *data)
|
||||
{
|
||||
struct as3722_poweroff *as3722_pm_poweroff = data->cb_data;
|
||||
int ret;
|
||||
|
||||
if (!as3722_pm_poweroff) {
|
||||
pr_err("AS3722 poweroff is not initialised\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ret = as3722_update_bits(as3722_pm_poweroff->as3722,
|
||||
AS3722_RESET_CONTROL_REG, AS3722_POWER_OFF, AS3722_POWER_OFF);
|
||||
if (ret < 0)
|
||||
dev_err(as3722_pm_poweroff->dev,
|
||||
"RESET_CONTROL_REG update failed, %d\n", ret);
|
||||
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
static int as3722_poweroff_probe(struct platform_device *pdev)
|
||||
@@ -54,26 +51,21 @@ static int as3722_poweroff_probe(struct platform_device *pdev)
|
||||
|
||||
as3722_poweroff->as3722 = dev_get_drvdata(pdev->dev.parent);
|
||||
as3722_poweroff->dev = &pdev->dev;
|
||||
as3722_pm_poweroff = as3722_poweroff;
|
||||
if (!pm_power_off)
|
||||
pm_power_off = as3722_pm_power_off;
|
||||
|
||||
return devm_register_sys_off_handler(as3722_poweroff->dev,
|
||||
SYS_OFF_MODE_POWER_OFF,
|
||||
SYS_OFF_PRIO_DEFAULT,
|
||||
as3722_pm_power_off,
|
||||
as3722_poweroff);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void as3722_poweroff_remove(struct platform_device *pdev)
|
||||
{
|
||||
if (pm_power_off == as3722_pm_power_off)
|
||||
pm_power_off = NULL;
|
||||
as3722_pm_poweroff = NULL;
|
||||
}
|
||||
|
||||
static struct platform_driver as3722_poweroff_driver = {
|
||||
.driver = {
|
||||
.name = "as3722-power-off",
|
||||
},
|
||||
.probe = as3722_poweroff_probe,
|
||||
.remove_new = as3722_poweroff_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(as3722_poweroff_driver);
|
||||
|
||||
@@ -16,13 +16,9 @@
|
||||
struct atc260x_pwrc {
|
||||
struct device *dev;
|
||||
struct regmap *regmap;
|
||||
struct notifier_block restart_nb;
|
||||
int (*do_poweroff)(const struct atc260x_pwrc *pwrc, bool restart);
|
||||
};
|
||||
|
||||
/* Global variable needed only for pm_power_off */
|
||||
static struct atc260x_pwrc *atc260x_pwrc_data;
|
||||
|
||||
static int atc2603c_do_poweroff(const struct atc260x_pwrc *pwrc, bool restart)
|
||||
{
|
||||
int ret, deep_sleep = 0;
|
||||
@@ -165,18 +161,20 @@ static int atc2609a_init(const struct atc260x_pwrc *pwrc)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void atc260x_pwrc_pm_handler(void)
|
||||
static int atc260x_pwrc_pm_handler(struct sys_off_data *data)
|
||||
{
|
||||
atc260x_pwrc_data->do_poweroff(atc260x_pwrc_data, false);
|
||||
struct atc260x_pwrc *pwrc = data->cb_data;
|
||||
|
||||
pwrc->do_poweroff(pwrc, false);
|
||||
|
||||
WARN_ONCE(1, "Unable to power off system\n");
|
||||
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
static int atc260x_pwrc_restart_handler(struct notifier_block *nb,
|
||||
unsigned long mode, void *cmd)
|
||||
static int atc260x_pwrc_restart_handler(struct sys_off_data *data)
|
||||
{
|
||||
struct atc260x_pwrc *pwrc = container_of(nb, struct atc260x_pwrc,
|
||||
restart_nb);
|
||||
struct atc260x_pwrc *pwrc = data->cb_data;
|
||||
pwrc->do_poweroff(pwrc, true);
|
||||
|
||||
return NOTIFY_DONE;
|
||||
@@ -194,8 +192,6 @@ static int atc260x_pwrc_probe(struct platform_device *pdev)
|
||||
|
||||
priv->dev = &pdev->dev;
|
||||
priv->regmap = atc260x->regmap;
|
||||
priv->restart_nb.notifier_call = atc260x_pwrc_restart_handler;
|
||||
priv->restart_nb.priority = 192;
|
||||
|
||||
switch (atc260x->ic_type) {
|
||||
case ATC2603C:
|
||||
@@ -216,16 +212,20 @@ static int atc260x_pwrc_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
platform_set_drvdata(pdev, priv);
|
||||
ret = devm_register_sys_off_handler(priv->dev,
|
||||
SYS_OFF_MODE_POWER_OFF,
|
||||
SYS_OFF_PRIO_DEFAULT,
|
||||
atc260x_pwrc_pm_handler,
|
||||
priv);
|
||||
if (ret)
|
||||
dev_err(priv->dev, "failed to register power-off handler: %d\n",
|
||||
ret);
|
||||
|
||||
if (!pm_power_off) {
|
||||
atc260x_pwrc_data = priv;
|
||||
pm_power_off = atc260x_pwrc_pm_handler;
|
||||
} else {
|
||||
dev_warn(priv->dev, "Poweroff callback already assigned\n");
|
||||
}
|
||||
|
||||
ret = register_restart_handler(&priv->restart_nb);
|
||||
ret = devm_register_sys_off_handler(priv->dev,
|
||||
SYS_OFF_MODE_RESTART,
|
||||
SYS_OFF_PRIO_HIGH,
|
||||
atc260x_pwrc_restart_handler,
|
||||
priv);
|
||||
if (ret)
|
||||
dev_err(priv->dev, "failed to register restart handler: %d\n",
|
||||
ret);
|
||||
@@ -233,21 +233,8 @@ static int atc260x_pwrc_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void atc260x_pwrc_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct atc260x_pwrc *priv = platform_get_drvdata(pdev);
|
||||
|
||||
if (atc260x_pwrc_data == priv) {
|
||||
pm_power_off = NULL;
|
||||
atc260x_pwrc_data = NULL;
|
||||
}
|
||||
|
||||
unregister_restart_handler(&priv->restart_nb);
|
||||
}
|
||||
|
||||
static struct platform_driver atc260x_pwrc_driver = {
|
||||
.probe = atc260x_pwrc_probe,
|
||||
.remove_new = atc260x_pwrc_remove,
|
||||
.driver = {
|
||||
.name = "atc260x-pwrc",
|
||||
},
|
||||
|
||||
@@ -26,11 +26,10 @@
|
||||
#define SC_EFUSE_INT_STATUS 0x180c
|
||||
#define EFUSE_READ_DONE (1<<31)
|
||||
|
||||
static struct regmap *syscon;
|
||||
|
||||
static int axxia_restart_handler(struct notifier_block *this,
|
||||
unsigned long mode, void *cmd)
|
||||
static int axxia_restart_handler(struct sys_off_data *data)
|
||||
{
|
||||
struct regmap *syscon = data->cb_data;
|
||||
|
||||
/* Access Key (0xab) */
|
||||
regmap_write(syscon, SC_CRIT_WRITE_KEY, 0xab);
|
||||
/* Select internal boot from 0xffff0000 */
|
||||
@@ -44,14 +43,10 @@ static int axxia_restart_handler(struct notifier_block *this,
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
static struct notifier_block axxia_restart_nb = {
|
||||
.notifier_call = axxia_restart_handler,
|
||||
.priority = 128,
|
||||
};
|
||||
|
||||
static int axxia_reset_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct regmap *syscon;
|
||||
int err;
|
||||
|
||||
syscon = syscon_regmap_lookup_by_phandle(dev->of_node, "syscon");
|
||||
@@ -60,7 +55,8 @@ static int axxia_reset_probe(struct platform_device *pdev)
|
||||
return PTR_ERR(syscon);
|
||||
}
|
||||
|
||||
err = register_restart_handler(&axxia_restart_nb);
|
||||
err = devm_register_sys_off_handler(&pdev->dev, SYS_OFF_MODE_RESTART,
|
||||
128, axxia_restart_handler, syscon);
|
||||
if (err)
|
||||
dev_err(dev, "cannot register restart handler (err=%d)\n", err);
|
||||
|
||||
|
||||
@@ -15,8 +15,7 @@
|
||||
|
||||
static void __iomem *kona_reset_base;
|
||||
|
||||
static int kona_reset_handler(struct notifier_block *this,
|
||||
unsigned long mode, void *cmd)
|
||||
static int kona_reset_handler(struct sys_off_data *data)
|
||||
{
|
||||
/*
|
||||
* A soft reset is triggered by writing a 0 to bit 0 of the soft reset
|
||||
@@ -31,18 +30,14 @@ static int kona_reset_handler(struct notifier_block *this,
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
static struct notifier_block kona_reset_nb = {
|
||||
.notifier_call = kona_reset_handler,
|
||||
.priority = 128,
|
||||
};
|
||||
|
||||
static int kona_reset_probe(struct platform_device *pdev)
|
||||
{
|
||||
kona_reset_base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(kona_reset_base))
|
||||
return PTR_ERR(kona_reset_base);
|
||||
|
||||
return register_restart_handler(&kona_reset_nb);
|
||||
return devm_register_sys_off_handler(&pdev->dev, SYS_OFF_MODE_RESTART,
|
||||
128, kona_reset_handler, NULL);
|
||||
}
|
||||
|
||||
static const struct of_device_id of_match[] = {
|
||||
|
||||
@@ -70,12 +70,9 @@ static irqreturn_t gemini_powerbutton_interrupt(int irq, void *data)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
/* This callback needs this static local as it has void as argument */
|
||||
static struct gemini_powercon *gpw_poweroff;
|
||||
|
||||
static void gemini_poweroff(void)
|
||||
static int gemini_poweroff(struct sys_off_data *data)
|
||||
{
|
||||
struct gemini_powercon *gpw = gpw_poweroff;
|
||||
struct gemini_powercon *gpw = data->cb_data;
|
||||
u32 val;
|
||||
|
||||
dev_crit(gpw->dev, "Gemini power off\n");
|
||||
@@ -86,6 +83,8 @@ static void gemini_poweroff(void)
|
||||
val &= ~GEMINI_CTRL_ENABLE;
|
||||
val |= GEMINI_CTRL_SHUTDOWN;
|
||||
writel(val, gpw->base + GEMINI_PWC_CTRLREG);
|
||||
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
static int gemini_poweroff_probe(struct platform_device *pdev)
|
||||
@@ -148,8 +147,11 @@ static int gemini_poweroff_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
pm_power_off = gemini_poweroff;
|
||||
gpw_poweroff = gpw;
|
||||
ret = devm_register_sys_off_handler(dev, SYS_OFF_MODE_POWER_OFF,
|
||||
SYS_OFF_PRIO_DEFAULT,
|
||||
gemini_poweroff, gpw);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
dev_info(dev, "Gemini poweroff driver registered\n");
|
||||
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
#include <linux/pm.h>
|
||||
|
||||
static void __iomem *msm_ps_hold;
|
||||
static int deassert_pshold(struct notifier_block *nb, unsigned long action,
|
||||
void *data)
|
||||
|
||||
static int do_msm_poweroff(struct sys_off_data *data)
|
||||
{
|
||||
writel(0, msm_ps_hold);
|
||||
mdelay(10000);
|
||||
@@ -23,25 +23,18 @@ static int deassert_pshold(struct notifier_block *nb, unsigned long action,
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
static struct notifier_block restart_nb = {
|
||||
.notifier_call = deassert_pshold,
|
||||
.priority = 128,
|
||||
};
|
||||
|
||||
static void do_msm_poweroff(void)
|
||||
{
|
||||
deassert_pshold(&restart_nb, 0, NULL);
|
||||
}
|
||||
|
||||
static int msm_restart_probe(struct platform_device *pdev)
|
||||
{
|
||||
msm_ps_hold = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(msm_ps_hold))
|
||||
return PTR_ERR(msm_ps_hold);
|
||||
|
||||
register_restart_handler(&restart_nb);
|
||||
devm_register_sys_off_handler(&pdev->dev, SYS_OFF_MODE_RESTART,
|
||||
128, do_msm_poweroff, NULL);
|
||||
|
||||
pm_power_off = do_msm_poweroff;
|
||||
devm_register_sys_off_handler(&pdev->dev, SYS_OFF_MODE_POWER_OFF,
|
||||
SYS_OFF_PRIO_DEFAULT, do_msm_poweroff,
|
||||
NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/mfd/mt6397/core.h>
|
||||
#include <linux/mfd/mt6397/rtc.h>
|
||||
#include <linux/reboot.h>
|
||||
|
||||
struct mt6323_pwrc {
|
||||
struct device *dev;
|
||||
@@ -21,11 +22,9 @@ struct mt6323_pwrc {
|
||||
u32 base;
|
||||
};
|
||||
|
||||
static struct mt6323_pwrc *mt_pwrc;
|
||||
|
||||
static void mt6323_do_pwroff(void)
|
||||
static int mt6323_do_pwroff(struct sys_off_data *data)
|
||||
{
|
||||
struct mt6323_pwrc *pwrc = mt_pwrc;
|
||||
struct mt6323_pwrc *pwrc = data->cb_data;
|
||||
unsigned int val;
|
||||
int ret;
|
||||
|
||||
@@ -44,6 +43,8 @@ static void mt6323_do_pwroff(void)
|
||||
mdelay(1000);
|
||||
|
||||
WARN_ONCE(1, "Unable to power off system\n");
|
||||
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
static int mt6323_pwrc_probe(struct platform_device *pdev)
|
||||
@@ -51,6 +52,7 @@ static int mt6323_pwrc_probe(struct platform_device *pdev)
|
||||
struct mt6397_chip *mt6397_chip = dev_get_drvdata(pdev->dev.parent);
|
||||
struct mt6323_pwrc *pwrc;
|
||||
struct resource *res;
|
||||
int ret;
|
||||
|
||||
pwrc = devm_kzalloc(&pdev->dev, sizeof(*pwrc), GFP_KERNEL);
|
||||
if (!pwrc)
|
||||
@@ -63,19 +65,18 @@ static int mt6323_pwrc_probe(struct platform_device *pdev)
|
||||
pwrc->base = res->start;
|
||||
pwrc->regmap = mt6397_chip->regmap;
|
||||
pwrc->dev = &pdev->dev;
|
||||
mt_pwrc = pwrc;
|
||||
|
||||
pm_power_off = &mt6323_do_pwroff;
|
||||
ret = devm_register_sys_off_handler(pwrc->dev,
|
||||
SYS_OFF_MODE_POWER_OFF,
|
||||
SYS_OFF_PRIO_DEFAULT,
|
||||
mt6323_do_pwroff,
|
||||
pwrc);
|
||||
if (ret)
|
||||
return dev_err_probe(pwrc->dev, ret, "failed to register power-off handler\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mt6323_pwrc_remove(struct platform_device *pdev)
|
||||
{
|
||||
if (pm_power_off == &mt6323_do_pwroff)
|
||||
pm_power_off = NULL;
|
||||
}
|
||||
|
||||
static const struct of_device_id mt6323_pwrc_dt_match[] = {
|
||||
{ .compatible = "mediatek,mt6323-pwrc" },
|
||||
{},
|
||||
@@ -84,7 +85,6 @@ MODULE_DEVICE_TABLE(of, mt6323_pwrc_dt_match);
|
||||
|
||||
static struct platform_driver mt6323_pwrc_driver = {
|
||||
.probe = mt6323_pwrc_probe,
|
||||
.remove_new = mt6323_pwrc_remove,
|
||||
.driver = {
|
||||
.name = "mt6323-pwrc",
|
||||
.of_match_table = mt6323_pwrc_dt_match,
|
||||
|
||||
@@ -13,18 +13,15 @@
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
||||
#define TIMEOUT_MS 3000
|
||||
|
||||
/*
|
||||
* Hold configuration here, cannot be more than one instance of the driver
|
||||
* since pm_power_off itself is global.
|
||||
*/
|
||||
static struct regulator *cpu_regulator;
|
||||
|
||||
static void regulator_poweroff_do_poweroff(void)
|
||||
static int regulator_poweroff_do_poweroff(struct sys_off_data *data)
|
||||
{
|
||||
struct regulator *cpu_regulator = data->cb_data;
|
||||
|
||||
if (cpu_regulator && regulator_is_enabled(cpu_regulator))
|
||||
regulator_force_disable(cpu_regulator);
|
||||
|
||||
@@ -32,30 +29,24 @@ static void regulator_poweroff_do_poweroff(void)
|
||||
mdelay(TIMEOUT_MS);
|
||||
|
||||
WARN_ON(1);
|
||||
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
static int regulator_poweroff_probe(struct platform_device *pdev)
|
||||
{
|
||||
/* If a pm_power_off function has already been added, leave it alone */
|
||||
if (pm_power_off != NULL) {
|
||||
dev_err(&pdev->dev,
|
||||
"%s: pm_power_off function already registered\n",
|
||||
__func__);
|
||||
return -EBUSY;
|
||||
}
|
||||
struct regulator *cpu_regulator;
|
||||
|
||||
cpu_regulator = devm_regulator_get(&pdev->dev, "cpu");
|
||||
if (IS_ERR(cpu_regulator))
|
||||
return PTR_ERR(cpu_regulator);
|
||||
|
||||
pm_power_off = ®ulator_poweroff_do_poweroff;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void regulator_poweroff_remove(struct platform_device *pdev)
|
||||
{
|
||||
if (pm_power_off == ®ulator_poweroff_do_poweroff)
|
||||
pm_power_off = NULL;
|
||||
/* Set this handler to low priority to not override an existing handler */
|
||||
return devm_register_sys_off_handler(&pdev->dev,
|
||||
SYS_OFF_MODE_POWER_OFF,
|
||||
SYS_OFF_PRIO_LOW,
|
||||
regulator_poweroff_do_poweroff,
|
||||
cpu_regulator);
|
||||
}
|
||||
|
||||
static const struct of_device_id of_regulator_poweroff_match[] = {
|
||||
@@ -66,7 +57,6 @@ MODULE_DEVICE_TABLE(of, of_regulator_poweroff_match);
|
||||
|
||||
static struct platform_driver regulator_poweroff_driver = {
|
||||
.probe = regulator_poweroff_probe,
|
||||
.remove_new = regulator_poweroff_remove,
|
||||
.driver = {
|
||||
.name = "poweroff-regulator",
|
||||
.of_match_table = of_regulator_poweroff_match,
|
||||
|
||||
@@ -14,29 +14,21 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/reboot.h>
|
||||
|
||||
static void restart_poweroff_do_poweroff(void)
|
||||
static int restart_poweroff_do_poweroff(struct sys_off_data *data)
|
||||
{
|
||||
reboot_mode = REBOOT_HARD;
|
||||
machine_restart(NULL);
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
static int restart_poweroff_probe(struct platform_device *pdev)
|
||||
{
|
||||
/* If a pm_power_off function has already been added, leave it alone */
|
||||
if (pm_power_off != NULL) {
|
||||
dev_err(&pdev->dev,
|
||||
"pm_power_off function already registered");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
pm_power_off = &restart_poweroff_do_poweroff;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void restart_poweroff_remove(struct platform_device *pdev)
|
||||
{
|
||||
if (pm_power_off == &restart_poweroff_do_poweroff)
|
||||
pm_power_off = NULL;
|
||||
/* Set this handler to low priority to not override an existing handler */
|
||||
return devm_register_sys_off_handler(&pdev->dev,
|
||||
SYS_OFF_MODE_POWER_OFF,
|
||||
SYS_OFF_PRIO_LOW,
|
||||
restart_poweroff_do_poweroff,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static const struct of_device_id of_restart_poweroff_match[] = {
|
||||
@@ -47,7 +39,6 @@ MODULE_DEVICE_TABLE(of, of_restart_poweroff_match);
|
||||
|
||||
static struct platform_driver restart_poweroff_driver = {
|
||||
.probe = restart_poweroff_probe,
|
||||
.remove_new = restart_poweroff_remove,
|
||||
.driver = {
|
||||
.name = "poweroff-restart",
|
||||
.of_match_table = of_restart_poweroff_match,
|
||||
|
||||
@@ -19,12 +19,9 @@
|
||||
/* Reset Control Register 2 */
|
||||
#define RESCNT2_PRES 0x80000000 /* Soft power-on reset */
|
||||
|
||||
static void __iomem *sysc_base2;
|
||||
|
||||
static int rmobile_reset_handler(struct notifier_block *this,
|
||||
unsigned long mode, void *cmd)
|
||||
static int rmobile_reset_handler(struct sys_off_data *data)
|
||||
{
|
||||
pr_debug("%s %lu\n", __func__, mode);
|
||||
void __iomem *sysc_base2 = (void __iomem *)data->cb_data;
|
||||
|
||||
/* Let's assume we have acquired the HPB semaphore */
|
||||
writel(RESCNT2_PRES, sysc_base2 + RESCNT2);
|
||||
@@ -32,37 +29,27 @@ static int rmobile_reset_handler(struct notifier_block *this,
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
static struct notifier_block rmobile_reset_nb = {
|
||||
.notifier_call = rmobile_reset_handler,
|
||||
.priority = 192,
|
||||
};
|
||||
|
||||
static int rmobile_reset_probe(struct platform_device *pdev)
|
||||
{
|
||||
void __iomem *sysc_base2;
|
||||
int error;
|
||||
|
||||
sysc_base2 = of_iomap(pdev->dev.of_node, 1);
|
||||
if (!sysc_base2)
|
||||
return -ENODEV;
|
||||
sysc_base2 = devm_platform_ioremap_resource(pdev, 1);
|
||||
if (IS_ERR(sysc_base2))
|
||||
return PTR_ERR(sysc_base2);
|
||||
|
||||
error = register_restart_handler(&rmobile_reset_nb);
|
||||
error = devm_register_sys_off_handler(&pdev->dev,
|
||||
SYS_OFF_MODE_RESTART,
|
||||
SYS_OFF_PRIO_HIGH,
|
||||
rmobile_reset_handler,
|
||||
(__force void *)sysc_base2);
|
||||
if (error) {
|
||||
dev_err(&pdev->dev,
|
||||
"cannot register restart handler (err=%d)\n", error);
|
||||
goto fail_unmap;
|
||||
return error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
fail_unmap:
|
||||
iounmap(sysc_base2);
|
||||
return error;
|
||||
}
|
||||
|
||||
static void rmobile_reset_remove(struct platform_device *pdev)
|
||||
{
|
||||
unregister_restart_handler(&rmobile_reset_nb);
|
||||
iounmap(sysc_base2);
|
||||
}
|
||||
|
||||
static const struct of_device_id rmobile_reset_of_match[] = {
|
||||
@@ -73,7 +60,6 @@ MODULE_DEVICE_TABLE(of, rmobile_reset_of_match);
|
||||
|
||||
static struct platform_driver rmobile_reset_driver = {
|
||||
.probe = rmobile_reset_probe,
|
||||
.remove_new = rmobile_reset_remove,
|
||||
.driver = {
|
||||
.name = "rmobile_reset",
|
||||
.of_match_table = rmobile_reset_of_match,
|
||||
|
||||
@@ -13,44 +13,56 @@
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
static struct regmap *map;
|
||||
static u32 offset;
|
||||
static u32 value;
|
||||
static u32 mask;
|
||||
struct syscon_poweroff_data {
|
||||
struct regmap *map;
|
||||
u32 offset;
|
||||
u32 value;
|
||||
u32 mask;
|
||||
};
|
||||
|
||||
static void syscon_poweroff(void)
|
||||
static int syscon_poweroff(struct sys_off_data *off_data)
|
||||
{
|
||||
struct syscon_poweroff_data *data = off_data->cb_data;
|
||||
|
||||
/* Issue the poweroff */
|
||||
regmap_update_bits(map, offset, mask, value);
|
||||
regmap_update_bits(data->map, data->offset, data->mask, data->value);
|
||||
|
||||
mdelay(1000);
|
||||
|
||||
pr_emerg("Unable to poweroff system\n");
|
||||
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
static int syscon_poweroff_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct syscon_poweroff_data *data;
|
||||
int mask_err, value_err;
|
||||
|
||||
map = syscon_regmap_lookup_by_phandle(dev->of_node, "regmap");
|
||||
if (IS_ERR(map)) {
|
||||
map = syscon_node_to_regmap(dev->parent->of_node);
|
||||
if (IS_ERR(map)) {
|
||||
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
data->map = syscon_regmap_lookup_by_phandle(dev->of_node, "regmap");
|
||||
if (IS_ERR(data->map)) {
|
||||
data->map = syscon_node_to_regmap(dev->parent->of_node);
|
||||
if (IS_ERR(data->map)) {
|
||||
dev_err(dev, "unable to get syscon");
|
||||
return PTR_ERR(map);
|
||||
return PTR_ERR(data->map);
|
||||
}
|
||||
}
|
||||
|
||||
if (of_property_read_u32(dev->of_node, "offset", &offset)) {
|
||||
if (of_property_read_u32(dev->of_node, "offset", &data->offset)) {
|
||||
dev_err(dev, "unable to read 'offset'");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
value_err = of_property_read_u32(dev->of_node, "value", &value);
|
||||
mask_err = of_property_read_u32(dev->of_node, "mask", &mask);
|
||||
value_err = of_property_read_u32(dev->of_node, "value", &data->value);
|
||||
mask_err = of_property_read_u32(dev->of_node, "mask", &data->mask);
|
||||
if (value_err && mask_err) {
|
||||
dev_err(dev, "unable to read 'value' and 'mask'");
|
||||
return -EINVAL;
|
||||
@@ -58,28 +70,17 @@ static int syscon_poweroff_probe(struct platform_device *pdev)
|
||||
|
||||
if (value_err) {
|
||||
/* support old binding */
|
||||
value = mask;
|
||||
mask = 0xFFFFFFFF;
|
||||
data->value = data->mask;
|
||||
data->mask = 0xFFFFFFFF;
|
||||
} else if (mask_err) {
|
||||
/* support value without mask*/
|
||||
mask = 0xFFFFFFFF;
|
||||
data->mask = 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
if (pm_power_off) {
|
||||
dev_err(dev, "pm_power_off already claimed for %ps",
|
||||
pm_power_off);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
pm_power_off = syscon_poweroff;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void syscon_poweroff_remove(struct platform_device *pdev)
|
||||
{
|
||||
if (pm_power_off == syscon_poweroff)
|
||||
pm_power_off = NULL;
|
||||
return devm_register_sys_off_handler(&pdev->dev,
|
||||
SYS_OFF_MODE_POWER_OFF,
|
||||
SYS_OFF_PRIO_DEFAULT,
|
||||
syscon_poweroff, data);
|
||||
}
|
||||
|
||||
static const struct of_device_id syscon_poweroff_of_match[] = {
|
||||
@@ -89,7 +90,6 @@ static const struct of_device_id syscon_poweroff_of_match[] = {
|
||||
|
||||
static struct platform_driver syscon_poweroff_driver = {
|
||||
.probe = syscon_poweroff_probe,
|
||||
.remove_new = syscon_poweroff_remove,
|
||||
.driver = {
|
||||
.name = "syscon-poweroff",
|
||||
.of_match_table = syscon_poweroff_of_match,
|
||||
|
||||
@@ -9,22 +9,14 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/reboot.h>
|
||||
|
||||
struct tps65086_restart {
|
||||
struct notifier_block handler;
|
||||
struct device *dev;
|
||||
};
|
||||
|
||||
static int tps65086_restart_notify(struct notifier_block *this,
|
||||
unsigned long mode, void *cmd)
|
||||
static int tps65086_restart_notify(struct sys_off_data *data)
|
||||
{
|
||||
struct tps65086_restart *tps65086_restart =
|
||||
container_of(this, struct tps65086_restart, handler);
|
||||
struct tps65086 *tps65086 = dev_get_drvdata(tps65086_restart->dev->parent);
|
||||
struct tps65086 *tps65086 = data->cb_data;
|
||||
int ret;
|
||||
|
||||
ret = regmap_write(tps65086->regmap, TPS65086_FORCESHUTDN, 1);
|
||||
if (ret) {
|
||||
dev_err(tps65086_restart->dev, "%s: error writing to tps65086 pmic: %d\n",
|
||||
dev_err(tps65086->dev, "%s: error writing to tps65086 pmic: %d\n",
|
||||
__func__, ret);
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
@@ -39,44 +31,13 @@ static int tps65086_restart_notify(struct notifier_block *this,
|
||||
|
||||
static int tps65086_restart_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct tps65086_restart *tps65086_restart;
|
||||
int ret;
|
||||
struct tps65086 *tps65086 = dev_get_drvdata(pdev->dev.parent);
|
||||
|
||||
tps65086_restart = devm_kzalloc(&pdev->dev, sizeof(*tps65086_restart), GFP_KERNEL);
|
||||
if (!tps65086_restart)
|
||||
return -ENOMEM;
|
||||
|
||||
platform_set_drvdata(pdev, tps65086_restart);
|
||||
|
||||
tps65086_restart->handler.notifier_call = tps65086_restart_notify;
|
||||
tps65086_restart->handler.priority = 192;
|
||||
tps65086_restart->dev = &pdev->dev;
|
||||
|
||||
ret = register_restart_handler(&tps65086_restart->handler);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "%s: cannot register restart handler: %d\n",
|
||||
__func__, ret);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void tps65086_restart_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct tps65086_restart *tps65086_restart = platform_get_drvdata(pdev);
|
||||
int ret;
|
||||
|
||||
ret = unregister_restart_handler(&tps65086_restart->handler);
|
||||
if (ret) {
|
||||
/*
|
||||
* tps65086_restart_probe() registered the restart handler. So
|
||||
* unregistering should work fine. Checking the error code
|
||||
* shouldn't be needed, still doing it for completeness.
|
||||
*/
|
||||
dev_err(&pdev->dev, "%s: cannot unregister restart handler: %d\n",
|
||||
__func__, ret);
|
||||
}
|
||||
return devm_register_sys_off_handler(&pdev->dev,
|
||||
SYS_OFF_MODE_RESTART,
|
||||
SYS_OFF_PRIO_HIGH,
|
||||
tps65086_restart_notify,
|
||||
tps65086);
|
||||
}
|
||||
|
||||
static const struct platform_device_id tps65086_restart_id_table[] = {
|
||||
@@ -90,7 +51,6 @@ static struct platform_driver tps65086_restart_driver = {
|
||||
.name = "tps65086-restart",
|
||||
},
|
||||
.probe = tps65086_restart_probe,
|
||||
.remove_new = tps65086_restart_remove,
|
||||
.id_table = tps65086_restart_id_table,
|
||||
};
|
||||
module_platform_driver(tps65086_restart_driver);
|
||||
|
||||
@@ -22,17 +22,13 @@
|
||||
|
||||
struct xgene_reboot_context {
|
||||
struct device *dev;
|
||||
void *csr;
|
||||
void __iomem *csr;
|
||||
u32 mask;
|
||||
struct notifier_block restart_handler;
|
||||
};
|
||||
|
||||
static int xgene_restart_handler(struct notifier_block *this,
|
||||
unsigned long mode, void *cmd)
|
||||
static int xgene_restart_handler(struct sys_off_data *data)
|
||||
{
|
||||
struct xgene_reboot_context *ctx =
|
||||
container_of(this, struct xgene_reboot_context,
|
||||
restart_handler);
|
||||
struct xgene_reboot_context *ctx = data->cb_data;
|
||||
|
||||
/* Issue the reboot */
|
||||
writel(ctx->mask, ctx->csr);
|
||||
@@ -54,23 +50,20 @@ static int xgene_reboot_probe(struct platform_device *pdev)
|
||||
if (!ctx)
|
||||
return -ENOMEM;
|
||||
|
||||
ctx->csr = of_iomap(dev->of_node, 0);
|
||||
if (!ctx->csr) {
|
||||
ctx->csr = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(ctx->csr)) {
|
||||
dev_err(dev, "can not map resource\n");
|
||||
return -ENODEV;
|
||||
return PTR_ERR(ctx->csr);
|
||||
}
|
||||
|
||||
if (of_property_read_u32(dev->of_node, "mask", &ctx->mask))
|
||||
ctx->mask = 0xFFFFFFFF;
|
||||
|
||||
ctx->dev = dev;
|
||||
ctx->restart_handler.notifier_call = xgene_restart_handler;
|
||||
ctx->restart_handler.priority = 128;
|
||||
err = register_restart_handler(&ctx->restart_handler);
|
||||
if (err) {
|
||||
iounmap(ctx->csr);
|
||||
err = devm_register_sys_off_handler(dev, SYS_OFF_MODE_RESTART, 128,
|
||||
xgene_restart_handler, ctx);
|
||||
if (err)
|
||||
dev_err(dev, "cannot register restart handler (err=%d)\n", err);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -617,8 +617,7 @@ static int ab8500_btemp_get_ext_psy_data(struct device *dev, void *data)
|
||||
*/
|
||||
static void ab8500_btemp_external_power_changed(struct power_supply *psy)
|
||||
{
|
||||
class_for_each_device(power_supply_class, NULL, psy,
|
||||
ab8500_btemp_get_ext_psy_data);
|
||||
power_supply_for_each_device(psy, ab8500_btemp_get_ext_psy_data);
|
||||
}
|
||||
|
||||
/* ab8500 btemp driver interrupts and their respective isr */
|
||||
|
||||
@@ -1231,8 +1231,7 @@ static void ab8500_chargalg_algorithm(struct ab8500_chargalg *di)
|
||||
int ret;
|
||||
|
||||
/* Collect data from all power_supply class devices */
|
||||
class_for_each_device(power_supply_class, NULL,
|
||||
di->chargalg_psy, ab8500_chargalg_get_ext_psy_data);
|
||||
power_supply_for_each_device(di->chargalg_psy, ab8500_chargalg_get_ext_psy_data);
|
||||
|
||||
ab8500_chargalg_end_of_charge(di);
|
||||
ab8500_chargalg_check_temp(di);
|
||||
|
||||
@@ -1949,8 +1949,7 @@ static void ab8500_charger_check_vbat_work(struct work_struct *work)
|
||||
struct ab8500_charger *di = container_of(work,
|
||||
struct ab8500_charger, check_vbat_work.work);
|
||||
|
||||
class_for_each_device(power_supply_class, NULL,
|
||||
&di->usb_chg, ab8500_charger_get_ext_psy_data);
|
||||
power_supply_for_each_device(&di->usb_chg, ab8500_charger_get_ext_psy_data);
|
||||
|
||||
/* First run old_vbat is 0. */
|
||||
if (di->old_vbat == 0)
|
||||
|
||||
@@ -2407,8 +2407,7 @@ out:
|
||||
*/
|
||||
static void ab8500_fg_external_power_changed(struct power_supply *psy)
|
||||
{
|
||||
class_for_each_device(power_supply_class, NULL, psy,
|
||||
ab8500_fg_get_ext_psy_data);
|
||||
power_supply_for_each_device(psy, ab8500_fg_get_ext_psy_data);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -79,8 +79,7 @@ static void find_main_battery(void)
|
||||
main_battery = NULL;
|
||||
bp.main = main_battery;
|
||||
|
||||
error = class_for_each_device(power_supply_class, NULL, &bp,
|
||||
__find_main_battery);
|
||||
error = power_supply_for_each_device(&bp, __find_main_battery);
|
||||
if (error) {
|
||||
main_battery = bp.main;
|
||||
return;
|
||||
|
||||
@@ -50,20 +50,24 @@ struct axp_data {
|
||||
const char * const *irq_names;
|
||||
unsigned int num_irq_names;
|
||||
const int *curr_lim_table;
|
||||
int curr_lim_table_size;
|
||||
struct reg_field curr_lim_fld;
|
||||
struct reg_field vbus_valid_bit;
|
||||
struct reg_field vbus_mon_bit;
|
||||
struct reg_field usb_bc_en_bit;
|
||||
struct reg_field usb_bc_det_fld;
|
||||
struct reg_field vbus_disable_bit;
|
||||
bool vbus_needs_polling: 1;
|
||||
};
|
||||
|
||||
struct axp20x_usb_power {
|
||||
struct device *dev;
|
||||
struct regmap *regmap;
|
||||
struct regmap_field *curr_lim_fld;
|
||||
struct regmap_field *vbus_valid_bit;
|
||||
struct regmap_field *vbus_mon_bit;
|
||||
struct regmap_field *usb_bc_en_bit;
|
||||
struct regmap_field *usb_bc_det_fld;
|
||||
struct regmap_field *vbus_disable_bit;
|
||||
struct power_supply *supply;
|
||||
const struct axp_data *axp_data;
|
||||
@@ -115,6 +119,15 @@ static void axp20x_usb_power_poll_vbus(struct work_struct *work)
|
||||
if (val != power->old_status)
|
||||
power_supply_changed(power->supply);
|
||||
|
||||
if (power->usb_bc_en_bit && (val & AXP20X_PWR_STATUS_VBUS_PRESENT) !=
|
||||
(power->old_status & AXP20X_PWR_STATUS_VBUS_PRESENT)) {
|
||||
dev_dbg(power->dev, "Cable status changed, re-enabling USB BC");
|
||||
ret = regmap_field_write(power->usb_bc_en_bit, 1);
|
||||
if (ret)
|
||||
dev_err(power->dev, "failed to enable USB BC: errno %d",
|
||||
ret);
|
||||
}
|
||||
|
||||
power->old_status = val;
|
||||
power->online = val & AXP20X_PWR_STATUS_VBUS_USED;
|
||||
|
||||
@@ -123,6 +136,37 @@ out:
|
||||
mod_delayed_work(system_power_efficient_wq, &power->vbus_detect, DEBOUNCE_TIME);
|
||||
}
|
||||
|
||||
static int axp20x_get_usb_type(struct axp20x_usb_power *power,
|
||||
union power_supply_propval *val)
|
||||
{
|
||||
unsigned int reg;
|
||||
int ret;
|
||||
|
||||
if (!power->usb_bc_det_fld)
|
||||
return -EINVAL;
|
||||
|
||||
ret = regmap_field_read(power->usb_bc_det_fld, ®);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
switch (reg) {
|
||||
case 1:
|
||||
val->intval = POWER_SUPPLY_USB_TYPE_SDP;
|
||||
break;
|
||||
case 2:
|
||||
val->intval = POWER_SUPPLY_USB_TYPE_CDP;
|
||||
break;
|
||||
case 3:
|
||||
val->intval = POWER_SUPPLY_USB_TYPE_DCP;
|
||||
break;
|
||||
default:
|
||||
val->intval = POWER_SUPPLY_USB_TYPE_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int axp20x_usb_power_get_property(struct power_supply *psy,
|
||||
enum power_supply_property psp, union power_supply_propval *val)
|
||||
{
|
||||
@@ -160,12 +204,16 @@ static int axp20x_usb_power_get_property(struct power_supply *psy,
|
||||
|
||||
val->intval = ret * 1700; /* 1 step = 1.7 mV */
|
||||
return 0;
|
||||
case POWER_SUPPLY_PROP_CURRENT_MAX:
|
||||
case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
|
||||
ret = regmap_field_read(power->curr_lim_fld, &v);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
val->intval = power->axp_data->curr_lim_table[v];
|
||||
if (v < power->axp_data->curr_lim_table_size)
|
||||
val->intval = power->axp_data->curr_lim_table[v];
|
||||
else
|
||||
val->intval = power->axp_data->curr_lim_table[
|
||||
power->axp_data->curr_lim_table_size - 1];
|
||||
return 0;
|
||||
case POWER_SUPPLY_PROP_CURRENT_NOW:
|
||||
if (IS_ENABLED(CONFIG_AXP20X_ADC)) {
|
||||
@@ -189,6 +237,9 @@ static int axp20x_usb_power_get_property(struct power_supply *psy,
|
||||
|
||||
val->intval = ret * 375; /* 1 step = 0.375 mA */
|
||||
return 0;
|
||||
|
||||
case POWER_SUPPLY_PROP_USB_TYPE:
|
||||
return axp20x_get_usb_type(power, val);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -256,19 +307,37 @@ static int axp20x_usb_power_set_voltage_min(struct axp20x_usb_power *power,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int axp20x_usb_power_set_current_max(struct axp20x_usb_power *power, int intval)
|
||||
static int axp20x_usb_power_set_input_current_limit(struct axp20x_usb_power *power,
|
||||
int intval)
|
||||
{
|
||||
const unsigned int max = GENMASK(power->axp_data->curr_lim_fld.msb,
|
||||
power->axp_data->curr_lim_fld.lsb);
|
||||
int ret;
|
||||
unsigned int reg;
|
||||
const unsigned int max = power->axp_data->curr_lim_table_size;
|
||||
|
||||
if (intval == -1)
|
||||
return -EINVAL;
|
||||
|
||||
for (unsigned int i = 0; i <= max; ++i)
|
||||
if (power->axp_data->curr_lim_table[i] == intval)
|
||||
return regmap_field_write(power->curr_lim_fld, i);
|
||||
/*
|
||||
* BC1.2 detection can cause a race condition if we try to set a current
|
||||
* limit while it's in progress. When it finishes it will overwrite the
|
||||
* current limit we just set.
|
||||
*/
|
||||
if (power->usb_bc_en_bit) {
|
||||
dev_dbg(power->dev,
|
||||
"disabling BC1.2 detection because current limit was set");
|
||||
ret = regmap_field_write(power->usb_bc_en_bit, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
for (reg = max - 1; reg > 0; reg--)
|
||||
if (power->axp_data->curr_lim_table[reg] <= intval)
|
||||
break;
|
||||
|
||||
dev_dbg(power->dev, "setting input current limit reg to %d (%d uA), requested %d uA",
|
||||
reg, power->axp_data->curr_lim_table[reg], intval);
|
||||
|
||||
return regmap_field_write(power->curr_lim_fld, reg);
|
||||
}
|
||||
|
||||
static int axp20x_usb_power_set_property(struct power_supply *psy,
|
||||
@@ -287,8 +356,8 @@ static int axp20x_usb_power_set_property(struct power_supply *psy,
|
||||
case POWER_SUPPLY_PROP_VOLTAGE_MIN:
|
||||
return axp20x_usb_power_set_voltage_min(power, val->intval);
|
||||
|
||||
case POWER_SUPPLY_PROP_CURRENT_MAX:
|
||||
return axp20x_usb_power_set_current_max(power, val->intval);
|
||||
case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
|
||||
return axp20x_usb_power_set_input_current_limit(power, val->intval);
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
@@ -313,7 +382,7 @@ static int axp20x_usb_power_prop_writeable(struct power_supply *psy,
|
||||
return power->vbus_disable_bit != NULL;
|
||||
|
||||
return psp == POWER_SUPPLY_PROP_VOLTAGE_MIN ||
|
||||
psp == POWER_SUPPLY_PROP_CURRENT_MAX;
|
||||
psp == POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT;
|
||||
}
|
||||
|
||||
static enum power_supply_property axp20x_usb_power_properties[] = {
|
||||
@@ -322,7 +391,7 @@ static enum power_supply_property axp20x_usb_power_properties[] = {
|
||||
POWER_SUPPLY_PROP_ONLINE,
|
||||
POWER_SUPPLY_PROP_VOLTAGE_MIN,
|
||||
POWER_SUPPLY_PROP_VOLTAGE_NOW,
|
||||
POWER_SUPPLY_PROP_CURRENT_MAX,
|
||||
POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
|
||||
POWER_SUPPLY_PROP_CURRENT_NOW,
|
||||
};
|
||||
|
||||
@@ -331,7 +400,23 @@ static enum power_supply_property axp22x_usb_power_properties[] = {
|
||||
POWER_SUPPLY_PROP_PRESENT,
|
||||
POWER_SUPPLY_PROP_ONLINE,
|
||||
POWER_SUPPLY_PROP_VOLTAGE_MIN,
|
||||
POWER_SUPPLY_PROP_CURRENT_MAX,
|
||||
POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
|
||||
};
|
||||
|
||||
static enum power_supply_property axp813_usb_power_properties[] = {
|
||||
POWER_SUPPLY_PROP_HEALTH,
|
||||
POWER_SUPPLY_PROP_PRESENT,
|
||||
POWER_SUPPLY_PROP_ONLINE,
|
||||
POWER_SUPPLY_PROP_VOLTAGE_MIN,
|
||||
POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
|
||||
POWER_SUPPLY_PROP_USB_TYPE,
|
||||
};
|
||||
|
||||
static enum power_supply_usb_type axp813_usb_types[] = {
|
||||
POWER_SUPPLY_USB_TYPE_SDP,
|
||||
POWER_SUPPLY_USB_TYPE_DCP,
|
||||
POWER_SUPPLY_USB_TYPE_CDP,
|
||||
POWER_SUPPLY_USB_TYPE_UNKNOWN,
|
||||
};
|
||||
|
||||
static const struct power_supply_desc axp20x_usb_power_desc = {
|
||||
@@ -354,6 +439,18 @@ static const struct power_supply_desc axp22x_usb_power_desc = {
|
||||
.set_property = axp20x_usb_power_set_property,
|
||||
};
|
||||
|
||||
static const struct power_supply_desc axp813_usb_power_desc = {
|
||||
.name = "axp20x-usb",
|
||||
.type = POWER_SUPPLY_TYPE_USB,
|
||||
.properties = axp813_usb_power_properties,
|
||||
.num_properties = ARRAY_SIZE(axp813_usb_power_properties),
|
||||
.property_is_writeable = axp20x_usb_power_prop_writeable,
|
||||
.get_property = axp20x_usb_power_get_property,
|
||||
.set_property = axp20x_usb_power_set_property,
|
||||
.usb_types = axp813_usb_types,
|
||||
.num_usb_types = ARRAY_SIZE(axp813_usb_types),
|
||||
};
|
||||
|
||||
static const char * const axp20x_irq_names[] = {
|
||||
"VBUS_PLUGIN",
|
||||
"VBUS_REMOVAL",
|
||||
@@ -388,10 +485,15 @@ static int axp221_usb_curr_lim_table[] = {
|
||||
};
|
||||
|
||||
static int axp813_usb_curr_lim_table[] = {
|
||||
100000,
|
||||
500000,
|
||||
900000,
|
||||
1500000,
|
||||
2000000,
|
||||
2500000,
|
||||
3000000,
|
||||
3500000,
|
||||
4000000,
|
||||
};
|
||||
|
||||
static const struct axp_data axp192_data = {
|
||||
@@ -399,6 +501,7 @@ static const struct axp_data axp192_data = {
|
||||
.irq_names = axp20x_irq_names,
|
||||
.num_irq_names = ARRAY_SIZE(axp20x_irq_names),
|
||||
.curr_lim_table = axp192_usb_curr_lim_table,
|
||||
.curr_lim_table_size = ARRAY_SIZE(axp192_usb_curr_lim_table),
|
||||
.curr_lim_fld = REG_FIELD(AXP20X_VBUS_IPSOUT_MGMT, 0, 1),
|
||||
.vbus_valid_bit = REG_FIELD(AXP192_USB_OTG_STATUS, 2, 2),
|
||||
.vbus_mon_bit = REG_FIELD(AXP20X_VBUS_MON, 3, 3),
|
||||
@@ -409,6 +512,7 @@ static const struct axp_data axp202_data = {
|
||||
.irq_names = axp20x_irq_names,
|
||||
.num_irq_names = ARRAY_SIZE(axp20x_irq_names),
|
||||
.curr_lim_table = axp20x_usb_curr_lim_table,
|
||||
.curr_lim_table_size = ARRAY_SIZE(axp20x_usb_curr_lim_table),
|
||||
.curr_lim_fld = REG_FIELD(AXP20X_VBUS_IPSOUT_MGMT, 0, 1),
|
||||
.vbus_valid_bit = REG_FIELD(AXP20X_USB_OTG_STATUS, 2, 2),
|
||||
.vbus_mon_bit = REG_FIELD(AXP20X_VBUS_MON, 3, 3),
|
||||
@@ -419,6 +523,7 @@ static const struct axp_data axp221_data = {
|
||||
.irq_names = axp22x_irq_names,
|
||||
.num_irq_names = ARRAY_SIZE(axp22x_irq_names),
|
||||
.curr_lim_table = axp221_usb_curr_lim_table,
|
||||
.curr_lim_table_size = ARRAY_SIZE(axp221_usb_curr_lim_table),
|
||||
.curr_lim_fld = REG_FIELD(AXP20X_VBUS_IPSOUT_MGMT, 0, 1),
|
||||
.vbus_needs_polling = true,
|
||||
};
|
||||
@@ -428,17 +533,20 @@ static const struct axp_data axp223_data = {
|
||||
.irq_names = axp22x_irq_names,
|
||||
.num_irq_names = ARRAY_SIZE(axp22x_irq_names),
|
||||
.curr_lim_table = axp20x_usb_curr_lim_table,
|
||||
.curr_lim_table_size = ARRAY_SIZE(axp20x_usb_curr_lim_table),
|
||||
.curr_lim_fld = REG_FIELD(AXP20X_VBUS_IPSOUT_MGMT, 0, 1),
|
||||
.vbus_needs_polling = true,
|
||||
};
|
||||
|
||||
static const struct axp_data axp813_data = {
|
||||
.power_desc = &axp22x_usb_power_desc,
|
||||
.power_desc = &axp813_usb_power_desc,
|
||||
.irq_names = axp22x_irq_names,
|
||||
.num_irq_names = ARRAY_SIZE(axp22x_irq_names),
|
||||
.curr_lim_table = axp813_usb_curr_lim_table,
|
||||
.curr_lim_fld = REG_FIELD(AXP20X_VBUS_IPSOUT_MGMT, 0, 1),
|
||||
.curr_lim_table_size = ARRAY_SIZE(axp813_usb_curr_lim_table),
|
||||
.curr_lim_fld = REG_FIELD(AXP22X_CHRG_CTRL3, 4, 7),
|
||||
.usb_bc_en_bit = REG_FIELD(AXP288_BC_GLOBAL, 0, 0),
|
||||
.usb_bc_det_fld = REG_FIELD(AXP288_BC_DET_STAT, 5, 7),
|
||||
.vbus_disable_bit = REG_FIELD(AXP20X_VBUS_IPSOUT_MGMT, 7, 7),
|
||||
.vbus_needs_polling = true,
|
||||
};
|
||||
@@ -558,6 +666,7 @@ static int axp20x_usb_power_probe(struct platform_device *pdev)
|
||||
|
||||
platform_set_drvdata(pdev, power);
|
||||
|
||||
power->dev = &pdev->dev;
|
||||
power->axp_data = axp_data;
|
||||
power->regmap = axp20x->regmap;
|
||||
power->num_irqs = axp_data->num_irq_names;
|
||||
@@ -585,6 +694,12 @@ static int axp20x_usb_power_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = axp20x_regmap_field_alloc_optional(&pdev->dev, power->regmap,
|
||||
axp_data->usb_bc_det_fld,
|
||||
&power->usb_bc_det_fld);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = axp20x_regmap_field_alloc_optional(&pdev->dev, power->regmap,
|
||||
axp_data->vbus_disable_bit,
|
||||
&power->vbus_disable_bit);
|
||||
|
||||
@@ -550,18 +550,20 @@ static const struct dmi_system_id axp288_quirks[] = {
|
||||
.driver_data = (void *)AXP288_QUIRK_NO_BATTERY,
|
||||
},
|
||||
{
|
||||
/* Intel Cherry Trail Compute Stick, Windows version */
|
||||
/* Intel Bay Trail Compute Stick */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Intel"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "STK1AW32SC"),
|
||||
/* Partial match for STCK1A32WFC STCK1A32FC, STCK1A8LFC variants */
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "STCK1A"),
|
||||
},
|
||||
.driver_data = (void *)AXP288_QUIRK_NO_BATTERY,
|
||||
},
|
||||
{
|
||||
/* Intel Cherry Trail Compute Stick, version without an OS */
|
||||
/* Intel Cherry Trail Compute Stick */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Intel"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "STK1A32SC"),
|
||||
/* Partial match for STK1AW32SC and STK1A32SC variants */
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "STK1A"),
|
||||
},
|
||||
.driver_data = (void *)AXP288_QUIRK_NO_BATTERY,
|
||||
},
|
||||
@@ -599,6 +601,14 @@ static const struct dmi_system_id axp288_quirks[] = {
|
||||
},
|
||||
.driver_data = NULL,
|
||||
},
|
||||
{
|
||||
/* Radxa ROCK Pi X Single Board Computer */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "ROCK Pi X"),
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "Radxa"),
|
||||
},
|
||||
.driver_data = (void *)AXP288_QUIRK_NO_BATTERY,
|
||||
},
|
||||
{
|
||||
/*
|
||||
* Various Ace PC/Meegopad/MinisForum/Wintel Mini-PCs/HDMI-sticks
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user