diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2020-12-19 11:58:46 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2020-12-19 11:58:46 -0800 |
| commit | 11c336526e2504d34c70fcf11a3642ae333a5085 (patch) | |
| tree | 26f7183a83d17ebb57dcb9b350f8a1718ea0e1dd | |
| parent | c2703b66172fff39122012e42986b44c9c6ad5f1 (diff) | |
| parent | c2362519a04a7307e386e43bc567780d0d7631c7 (diff) | |
| download | linux-11c336526e2504d34c70fcf11a3642ae333a5085.tar.gz linux-11c336526e2504d34c70fcf11a3642ae333a5085.tar.bz2 linux-11c336526e2504d34c70fcf11a3642ae333a5085.zip | |
Merge tag 'for-v5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply
Pull power supply and reset updates from Sebastian Reichel:
"Battery/charger driver changes:
- collie_battery, generic-adc-battery, s3c-adc-battery: convert to
GPIO descriptors (incl ARM board files)
- misc cleanup and fixes
Reset drivers:
- new poweroff driver for force disabling a regulator
- use printk format symbol resolver
- ocelot: add support for Luton and Jaguar2"
* tag 'for-v5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply: (31 commits)
power: supply: Fix a typo in warning message
Documentation: DT: binding documentation for regulator-poweroff
power: reset: new driver regulator-poweroff
power: supply: ab8500: Use dev_err_probe() for IIO channels
power: supply: ab8500_fg: Request all IRQs as threaded
power: supply: ab8500_charger: Oneshot threaded IRQs
power: supply: ab8500: Convert to dev_pm_ops
power: supply: ab8500: Use local helper
power: supply: wm831x_power: remove unneeded break
power: supply: bq24735: Drop unused include
power: supply: bq24190_charger: Drop unused include
power: supply: generic-adc-battery: Use GPIO descriptors
power: supply: collie_battery: Convert to GPIO descriptors
power: supply: bq24190_charger: fix reference leak
power: supply: s3c-adc-battery: Convert to GPIO descriptors
power: reset: Use printk format symbol resolver
power: supply: axp20x_usb_power: Use power efficient workqueue for debounce
power: supply: axp20x_usb_power: fix typo
power: supply: max8997-charger: Improve getting charger status
power: supply: max8997-charger: Fix platform data retrieval
...
30 files changed, 562 insertions, 355 deletions
diff --git a/Documentation/devicetree/bindings/power/reset/ocelot-reset.txt b/Documentation/devicetree/bindings/power/reset/ocelot-reset.txt index 4d530d815484..c5de7b555feb 100644 --- a/Documentation/devicetree/bindings/power/reset/ocelot-reset.txt +++ b/Documentation/devicetree/bindings/power/reset/ocelot-reset.txt @@ -7,7 +7,9 @@ The reset registers are both present in the MSCC vcoreiii MIPS and microchip Sparx5 armv8 SoC's. Required Properties: - - compatible: "mscc,ocelot-chip-reset" or "microchip,sparx5-chip-reset" + + - compatible: "mscc,ocelot-chip-reset", "mscc,luton-chip-reset", + "mscc,jaguar2-chip-reset" or "microchip,sparx5-chip-reset" Example: reset@1070008 { diff --git a/Documentation/devicetree/bindings/power/reset/regulator-poweroff.yaml b/Documentation/devicetree/bindings/power/reset/regulator-poweroff.yaml new file mode 100644 index 000000000000..03bd1fa5a623 --- /dev/null +++ b/Documentation/devicetree/bindings/power/reset/regulator-poweroff.yaml @@ -0,0 +1,37 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/power/reset/regulator-poweroff.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Force-disable power regulator to turn the power off. + +maintainers: + - Michael Klein <michael@fossekall.de> + +description: | + When the power-off handler is called, a power regulator is disabled by + calling regulator_force_disable(). If the power is still on and the + CPU still running after a 3000ms delay, a warning is emitted. + +properties: + compatible: + const: "regulator-poweroff" + + cpu-supply: + description: + regulator to disable on power-down + +required: + - compatible + - cpu-supply + +additionalProperties: false + +examples: + - | + regulator-poweroff { + compatible = "regulator-poweroff"; + cpu-supply = <®_vcc1v2>; + }; +... diff --git a/arch/arm/mach-s3c/mach-h1940.c b/arch/arm/mach-s3c/mach-h1940.c index 53d51aa83200..8a43ed1c4c4d 100644 --- a/arch/arm/mach-s3c/mach-h1940.c +++ b/arch/arm/mach-s3c/mach-h1940.c @@ -297,6 +297,15 @@ static const struct s3c_adc_bat_thresh bat_lut_acin[] = { { .volt = 3841, .cur = 0, .level = 0}, }; +static struct gpiod_lookup_table h1940_bat_gpio_table = { + .dev_id = "s3c-adc-battery", + .table = { + /* Charge status S3C2410_GPF(3) */ + GPIO_LOOKUP("GPIOF", 3, "charge-status", GPIO_ACTIVE_LOW), + { }, + }, +}; + static int h1940_bat_init(void) { int ret; @@ -330,8 +339,6 @@ static struct s3c_adc_bat_pdata h1940_bat_cfg = { .exit = h1940_bat_exit, .enable_charger = h1940_enable_charger, .disable_charger = h1940_disable_charger, - .gpio_charge_finished = S3C2410_GPF(3), - .gpio_inverted = 1, .lut_noac = bat_lut_noac, .lut_noac_cnt = ARRAY_SIZE(bat_lut_noac), .lut_acin = bat_lut_acin, @@ -720,6 +727,7 @@ static void __init h1940_init(void) s3c24xx_fb_set_platdata(&h1940_fb_info); gpiod_add_lookup_table(&h1940_mmc_gpio_table); gpiod_add_lookup_table(&h1940_audio_gpio_table); + gpiod_add_lookup_table(&h1940_bat_gpio_table); /* Configure the I2S pins (GPE0...GPE4) in correct mode */ s3c_gpio_cfgall_range(S3C2410_GPE(0), 5, S3C_GPIO_SFN(2), S3C_GPIO_PULL_NONE); diff --git a/arch/arm/mach-s3c/mach-rx1950.c b/arch/arm/mach-s3c/mach-rx1950.c index b9758f0a9a14..6e19add158a9 100644 --- a/arch/arm/mach-s3c/mach-rx1950.c +++ b/arch/arm/mach-s3c/mach-rx1950.c @@ -206,6 +206,15 @@ static const struct s3c_adc_bat_thresh bat_lut_acin[] = { { .volt = 3820, .cur = 0, .level = 0}, }; +static struct gpiod_lookup_table rx1950_bat_gpio_table = { + .dev_id = "s3c-adc-battery", + .table = { + /* Charge status S3C2410_GPF(3) */ + GPIO_LOOKUP("GPIOF", 3, "charge-status", GPIO_ACTIVE_HIGH), + { }, + }, +}; + static int rx1950_bat_init(void) { int ret; @@ -331,7 +340,6 @@ static struct s3c_adc_bat_pdata rx1950_bat_cfg = { .exit = rx1950_bat_exit, .enable_charger = rx1950_enable_charger, .disable_charger = rx1950_disable_charger, - .gpio_charge_finished = S3C2410_GPF(3), .lut_noac = bat_lut_noac, .lut_noac_cnt = ARRAY_SIZE(bat_lut_noac), .lut_acin = bat_lut_acin, @@ -840,6 +848,7 @@ static void __init rx1950_init_machine(void) pwm_add_table(rx1950_pwm_lookup, ARRAY_SIZE(rx1950_pwm_lookup)); gpiod_add_lookup_table(&rx1950_audio_gpio_table); + gpiod_add_lookup_table(&rx1950_bat_gpio_table); /* Configure the I2S pins (GPE0...GPE4) in correct mode */ s3c_gpio_cfgall_range(S3C2410_GPE(0), 5, S3C_GPIO_SFN(2), S3C_GPIO_PULL_NONE); diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c index bd3a52fd09ce..d4e89a02c8c8 100644 --- a/arch/arm/mach-sa1100/collie.c +++ b/arch/arm/mach-sa1100/collie.c @@ -98,6 +98,26 @@ static struct mcp_plat_data collie_mcp_data = { .codec_pdata = &collie_ucb1x00_data, }; +/* Battery management GPIOs */ +static struct gpiod_lookup_table collie_battery_gpiod_table = { + /* the MCP codec mcp0 has the ucb1x00 as attached device */ + .dev_id = "ucb1x00", + .table = { + /* This is found on the main GPIO on the SA1100 */ + GPIO_LOOKUP("gpio", COLLIE_GPIO_CO, + "main battery full", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("gpio", COLLIE_GPIO_MAIN_BAT_LOW, + "main battery low", GPIO_ACTIVE_HIGH), + /* + * This is GPIO 0 on the Scoop expander, which is registered + * from common/scoop.c with this gpio chip label. + */ + GPIO_LOOKUP("sharp-scoop", 0, + "main charge on", GPIO_ACTIVE_HIGH), + { }, + }, +}; + static int collie_ir_startup(struct device *dev) { int rc = gpio_request(COLLIE_GPIO_IR_ON, "IrDA"); @@ -395,6 +415,7 @@ static void __init collie_init(void) platform_scoop_config = &collie_pcmcia_config; gpiod_add_lookup_table(&collie_power_gpiod_table); + gpiod_add_lookup_table(&collie_battery_gpiod_table); ret = platform_add_devices(devices, ARRAY_SIZE(devices)); if (ret) { diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig index d55b3727e00e..b22c4fdb2561 100644 --- a/drivers/power/reset/Kconfig +++ b/drivers/power/reset/Kconfig @@ -177,6 +177,13 @@ config POWER_RESET_QNAP Say Y if you have a QNAP NAS. +config POWER_RESET_REGULATOR + bool "Regulator subsystem power-off driver" + depends on OF && REGULATOR + help + This driver supports turning off your board by disabling a + power regulator defined in the devicetree. + config POWER_RESET_RESTART bool "Restart power-off driver" help diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile index c51eceba9ea3..9dc49d3a57ff 100644 --- a/drivers/power/reset/Makefile +++ b/drivers/power/reset/Makefile @@ -19,6 +19,7 @@ obj-$(CONFIG_POWER_RESET_OCELOT_RESET) += ocelot-reset.o obj-$(CONFIG_POWER_RESET_PIIX4_POWEROFF) += piix4-poweroff.o obj-$(CONFIG_POWER_RESET_LTC2952) += ltc2952-poweroff.o obj-$(CONFIG_POWER_RESET_QNAP) += qnap-poweroff.o +obj-$(CONFIG_POWER_RESET_REGULATOR) += regulator-poweroff.o obj-$(CONFIG_POWER_RESET_RESTART) += restart-poweroff.o obj-$(CONFIG_POWER_RESET_ST) += st-poweroff.o obj-$(CONFIG_POWER_RESET_VERSATILE) += arm-versatile-reboot.o diff --git a/drivers/power/reset/ocelot-reset.c b/drivers/power/reset/ocelot-reset.c index f74e1dbb4ba3..8caa90cb58fc 100644 --- a/drivers/power/reset/ocelot-reset.c +++ b/drivers/power/reset/ocelot-reset.c @@ -29,6 +29,8 @@ struct ocelot_reset_context { struct notifier_block restart_handler; }; +#define BIT_OFF_INVALID 32 + #define SOFT_CHIP_RST BIT(0) #define ICPU_CFG_CPU_SYSTEM_CTRL_GENERAL_CTRL 0x24 @@ -50,9 +52,11 @@ static int ocelot_restart_handle(struct notifier_block *this, ctx->props->vcore_protect, 0); /* Make the SI back to boot mode */ - regmap_update_bits(ctx->cpu_ctrl, ICPU_CFG_CPU_SYSTEM_CTRL_GENERAL_CTRL, - IF_SI_OWNER_MASK << if_si_owner_bit, - IF_SI_OWNER_SIBM << if_si_owner_bit); + if (if_si_owner_bit != BIT_OFF_INVALID) + regmap_update_bits(ctx->cpu_ctrl, + ICPU_CFG_CPU_SYSTEM_CTRL_GENERAL_CTRL, + IF_SI_OWNER_MASK << if_si_owner_bit, + IF_SI_OWNER_SIBM << if_si_owner_bit); pr_emerg("Resetting SoC\n"); @@ -96,6 +100,20 @@ static int ocelot_reset_probe(struct platform_device *pdev) return err; } +static const struct reset_props reset_props_jaguar2 = { + .syscon = "mscc,ocelot-cpu-syscon", + .protect_reg = 0x20, + .vcore_protect = BIT(2), + .if_si_owner_bit = 6, +}; + +static const struct reset_props reset_props_luton = { + .syscon = "mscc,ocelot-cpu-syscon", + .protect_reg = 0x20, + .vcore_protect = BIT(2), + .if_si_owner_bit = BIT_OFF_INVALID, /* n/a */ +}; + static const struct reset_props reset_props_ocelot = { .syscon = "mscc,ocelot-cpu-syscon", .protect_reg = 0x20, @@ -112,6 +130,12 @@ static const struct reset_props reset_props_sparx5 = { static const struct of_device_id ocelot_reset_of_match[] = { { + .compatible = "mscc,jaguar2-chip-reset", + .data = &reset_props_jaguar2 + }, { + .compatible = "mscc,luton-chip-reset", + .data = &reset_props_luton + }, { .compatible = "mscc,ocelot-chip-reset", .data = &reset_props_ocelot }, { diff --git a/drivers/power/reset/qnap-poweroff.c b/drivers/power/reset/qnap-poweroff.c index 52b7dc61d870..0ddf7f25f7b8 100644 --- a/drivers/power/reset/qnap-poweroff.c +++ b/drivers/power/reset/qnap-poweroff.c @@ -14,7 +14,6 @@ #include <linux/module.h> #include <linux/platform_device.h> #include <linux/serial_reg.h> -#include <linux/kallsyms.h> #include <linux/of.h> #include <linux/io.h> #include <linux/clk.h> @@ -75,7 +74,6 @@ static int qnap_power_off_probe(struct platform_device *pdev) struct device_node *np = pdev->dev.of_node; struct resource *res; struct clk *clk; - char symname[KSYM_NAME_LEN]; const struct of_device_id *match = of_match_node(qnap_power_off_of_match_table, np); @@ -104,10 +102,8 @@ static int qnap_power_off_probe(struct platform_device *pdev) /* Check that nothing else has already setup a handler */ if (pm_power_off) { - lookup_symbol_name((ulong)pm_power_off, symname); - dev_err(&pdev->dev, - "pm_power_off already claimed %p %s", - pm_power_off, symname); + dev_err(&pdev->dev, "pm_power_off already claimed for %ps", + pm_power_off); return -EBUSY; } pm_power_off = qnap_power_off; diff --git a/drivers/power/reset/regulator-poweroff.c b/drivers/power/reset/regulator-poweroff.c new file mode 100644 index 000000000000..f697088e0ad1 --- /dev/null +++ b/drivers/power/reset/regulator-poweroff.c @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Force-disables a regulator to power down a device + * + * Michael Klein <michael@fossekall.de> + * + * Copyright (C) 2020 Michael Klein + * + * Based on the gpio-poweroff driver. + */ +#include <linux/delay.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/pm.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) +{ + if (cpu_regulator && regulator_is_enabled(cpu_regulator)) + regulator_force_disable(cpu_regulator); + + /* give it some time */ + mdelay(TIMEOUT_MS); + + WARN_ON(1); +} + +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; + } + + 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 int regulator_poweroff_remove(__maybe_unused struct platform_device *pdev) +{ + if (pm_power_off == ®ulator_poweroff_do_poweroff) + pm_power_off = NULL; + + return 0; +} + +static const struct of_device_id of_regulator_poweroff_match[] = { + { .compatible = "regulator-poweroff", }, + {}, +}; + +static struct platform_driver regulator_poweroff_driver = { + .probe = regulator_poweroff_probe, + .remove = regulator_poweroff_remove, + .driver = { + .name = "poweroff-regulator", + .of_match_table = of_regulator_poweroff_match, + }, +}; + +module_platform_driver(regulator_poweroff_driver); + +MODULE_AUTHOR("Michael Klein <michael@fossekall.de>"); +MODULE_DESCRIPTION("Regulator poweroff driver"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:poweroff-regulator"); diff --git a/drivers/power/reset/syscon-poweroff.c b/drivers/power/reset/syscon-poweroff.c index 4d6923b102b6..ed58bdf41e27 100644 --- a/drivers/power/reset/syscon-poweroff.c +++ b/drivers/power/reset/syscon-poweroff.c @@ -6,7 +6,6 @@ * Author: Moritz Fischer <moritz.fischer@ettus.com> */ -#include <linux/kallsyms.h> #include <linux/delay.h> #include <linux/io.h> #include <linux/notifier.h> @@ -34,7 +33,6 @@ static void syscon_poweroff(void) static int syscon_poweroff_probe(struct platform_device *pdev) { - char symname[KSYM_NAME_LEN]; int mask_err, value_err; map = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, "regmap"); @@ -65,10 +63,8 @@ static int syscon_poweroff_probe(struct platform_device *pdev) } if (pm_power_off) { - lookup_symbol_name((ulong)pm_power_off, symname); - dev_err(&pdev->dev, - "pm_power_off already claimed %p %s", - pm_power_off, symname); + dev_err(&pdev->dev, "pm_power_off already claimed for %ps", + pm_power_off); return -EBUSY; } diff --git a/drivers/power/supply/ab8500_btemp.c b/drivers/power/supply/ab8500_btemp.c index 909f0242bacb..d20345386b1e 100644 --- a/drivers/power/supply/ab8500_btemp.c +++ b/drivers/power/supply/ab8500_btemp.c @@ -936,29 +936,23 @@ static struct ab8500_btemp_interrupts ab8500_btemp_irq[] = { {"BTEMP_MEDIUM_HIGH", ab8500_btemp_medhigh_handler}, }; -#if defined(CONFIG_PM) -static int ab8500_btemp_resume(struct platform_device *pdev) +static int __maybe_unused ab8500_btemp_resume(struct device *dev) { - struct ab8500_btemp *di = platform_get_drvdata(pdev); + struct ab8500_btemp *di = dev_get_drvdata(dev); ab8500_btemp_periodic(di, true); return 0; } -static int ab8500_btemp_suspend(struct platform_device *pdev, - pm_message_t state) +static int __maybe_unused ab8500_btemp_suspend(struct device *dev) { - struct ab8500_btemp *di = platform_get_drvdata(pdev); + struct ab8500_btemp *di = dev_get_drvdata(dev); ab8500_btemp_periodic(di, false); return 0; } -#else -#define ab8500_btemp_suspend NULL -#define ab8500_btemp_resume NULL -#endif static int ab8500_btemp_remove(struct platform_device *pdev) { @@ -999,48 +993,45 @@ static int ab8500_btemp_probe(struct platform_device *pdev) struct device_node *np = pdev->dev.of_node; struct abx500_bm_data *plat = pdev->dev.platform_data; struct power_supply_config psy_cfg = {}; + struct device *dev = &pdev->dev; struct ab8500_btemp *di; int irq, i, ret = 0; u8 val; - di = devm_kzalloc(&pdev->dev, sizeof(*di), GFP_KERNEL); - if (!di) { - dev_err(&pdev->dev, "%s no mem for ab8500_btemp\n", __func__); + di = devm_kzalloc(dev, sizeof(*di), GFP_KERNEL); + if (!di) return -ENOMEM; - } if (!plat) { - dev_err(&pdev->dev, "no battery management data supplied\n"); + dev_err(dev, "no battery management data supplied\n"); return -EINVAL; } di->bm = plat; if (np) { - ret = ab8500_bm_of_probe(&pdev->dev, np, di->bm); + ret = ab8500_bm_of_probe(dev, np, di->bm); if (ret) { - dev_err(&pdev->dev, "failed to get battery information\n"); + dev_err(dev, "failed to get battery information\n"); return ret; } } /* get parent data */ - di->dev = &pdev->dev; + di->dev = dev; di->parent = dev_get_drvdata(pdev->dev.parent); /* Get ADC channels */ - di->btemp_ball = devm_iio_channel_get(&pdev->dev, "btemp_ball"); + di->btemp_ball = devm_iio_channel_get(dev, "btemp_ball"); if (IS_ERR(di->btemp_ball)) { - if (PTR_ERR(di->btemp_ball) == -ENODEV) - return -EPROBE_DEFER; - dev_err(&pdev->dev, "failed to get BTEMP BALL ADC channel\n"); - return PTR_ERR(di->btemp_ball); + ret = dev_err_probe(dev, PTR_ERR(di->btemp_ball), + "failed to get BTEMP BALL ADC channel\n"); + return ret; } - di->bat_ctrl = devm_iio_channel_get(&pdev->dev, "bat_ctrl"); + di->bat_ctrl = devm_iio_channel_get(dev, "bat_ctrl"); if (IS_ERR(di->bat_ctrl)) { - if (PTR_ERR(di->bat_ctrl) == -ENODEV) - return -EPROBE_DEFER; - dev_err(&pdev->dev, "failed to get BAT CTRL ADC channel\n"); - return PTR_ERR(di->bat_ctrl); + ret = dev_err_probe(dev, PTR_ERR(di->bat_ctrl), + "failed to get BAT CTRL ADC channel\n"); + return ret; } di->initialized = false; @@ -1053,7 +1044,7 @@ static int ab8500_btemp_probe(struct platform_device *pdev) di->btemp_wq = alloc_workqueue("ab8500_btemp_wq", WQ_MEM_RECLAIM, 0); if (di->btemp_wq == NULL) { - dev_err(di->dev, "failed to create work queue\n"); + dev_err(dev, "failed to create work queue\n"); return -ENOMEM; } @@ -1065,10 +1056,10 @@ static int ab8500_btemp_probe(struct platform_device *pdev) di->btemp_ranges.btemp_low_limit = BTEMP_THERMAL_LOW_LIMIT; di->btemp_ranges.btemp_med_limit = BTEMP_THERMAL_MED_LIMIT; - ret = abx500_get_register_interruptible(di->dev, AB8500_CHARGER, + ret = abx500_get_register_interruptible(dev, AB8500_CHARGER, AB8500_BTEMP_HIGH_TH, &val); if (ret < 0) { - dev_err(di->dev, "%s ab8500 read failed\n", __func__); + dev_err(dev, "%s ab8500 read failed\n", __func__); goto free_btemp_wq; } switch (val) { @@ -1088,10 +1079,10 @@ static int ab8500_btemp_probe(struct platform_device *pdev) } /* Register BTEMP power supply class */ - di->btemp_psy = power_supply_register(di->dev, &ab8500_btemp_desc, + di->btemp_psy = power_supply_register(dev, &ab8500_btemp_desc, &psy_cfg); if (IS_ERR(di->btemp_psy)) { - dev_err(di->dev, "failed to register BTEMP psy\n"); + dev_err(dev, "failed to register BTEMP psy\n"); ret = PTR_ERR(di->btemp_psy); goto free_btemp_wq; } @@ -1105,15 +1096,15 @@ static int ab8500_btemp_probe(struct platform_device *pdev) } ret = request_threaded_irq(irq, NULL, ab8500_btemp_irq[i].isr, - IRQF_SHARED | IRQF_NO_SUSPEND, + IRQF_SHARED | IRQF_NO_SUSPEND | IRQF_ONESHOT, ab8500_btemp_irq[i].name, di); if (ret) { - dev_err(di->dev, "failed to request %s IRQ %d: %d\n" + dev_err(dev, "failed to request %s IRQ %d: %d\n" , ab8500_btemp_irq[i].name, irq, ret); goto free_irq; } - dev_dbg(di->dev, "Requested %s IRQ %d: %d\n", + dev_dbg(dev, "Requested %s IRQ %d: %d\n", ab8500_btemp_irq[i].name, irq, ret); } @@ -1138,6 +1129,8 @@ free_btemp_wq: return ret; } +static SIMPLE_DEV_PM_OPS(ab8500_btemp_pm_ops, ab8500_btemp_suspend, ab8500_btemp_resume); + static const struct of_device_id ab8500_btemp_match[] = { { .compatible = "stericsson,ab8500-btemp", }, { }, @@ -1146,11 +1139,10 @@ static const struct of_device_id ab8500_btemp_match[] = { static struct platform_driver ab8500_btemp_driver = { .probe = ab8500_btemp_probe, .remove = ab8500_btemp_remove, - .suspend = ab8500_btemp_suspend, - .resume = ab8500_btemp_resume, .driver = { .name = "ab8500-btemp", .of_match_table = ab8500_btemp_match, + .pm = &ab8500_btemp_pm_ops, }, }; diff --git a/drivers/power/supply/ab8500_charger.c b/drivers/power/supply/ab8500_charger.c index db65be026920..ac77c8882d17 100644 --- a/drivers/power/supply/ab8500_charger.c +++ b/drivers/power/supply/ab8500_charger.c @@ -3209,11 +3209,10 @@ static int ab8500_charger_usb_notifier_call(struct notifier_block *nb, return NOTIFY_OK; } -#if defined(CONFIG_PM) -static int ab8500_charger_resume(struct platform_device *pdev) +static int __maybe_unused ab8500_charger_resume(struct device *dev) { int ret; - struct ab8500_charger *di = platform_get_drvdata(pdev); + struct ab8500_charger *di = dev_get_drvdata(dev); /* * For ABB revision 1.0 and 1.1 there is a bug in the watchdog @@ -3247,10 +3246,9 @@ static int ab8500_charger_resume(struct platform_device *pdev) return 0; } -static int ab8500_charger_suspend(struct platform_device *pdev, - pm_message_t state) +static int __maybe_unused ab8500_charger_suspend(struct device *dev) { - struct ab8500_charger *di = platform_get_drvdata(pdev); + struct ab8500_charger *di = dev_get_drvdata(dev); /* Cancel any pending jobs */ cancel_delayed_work(&di->check_hw_failure_work); @@ -3272,10 +3270,6 @@ static int ab8500_charger_suspend(struct platform_device *pdev, return 0; } -#else -#define ab8500_charger_suspend NULL -#define ab8500_charger_resume NULL -#endif static struct notifier_block charger_nb = { .notifier_call = ab8500_external_charger_prepare, @@ -3354,23 +3348,22 @@ static int ab8500_charger_probe(struct platform_device *pdev) struct power_supply_config ac_psy_cfg = {}, usb_psy_cfg = {}; struct ab8500_charger *di; int irq, i, charger_status, ret = 0, ch_stat; + struct device *dev = &pdev->dev; - di = devm_kzalloc(&pdev->dev, sizeof(*di), GFP_KERNEL); - if (!di) { - dev_err(&pdev->dev, "%s no mem for ab8500_charger\n", __func__); + di = devm_kzalloc(dev, sizeof(*di), GFP_KERNEL); + if (!di) return -ENOMEM; - } if (!plat) { - dev_err(&pdev->dev, "no battery management data supplied\n"); + dev_err(dev, "no battery management data supplied\n"); return -EINVAL; } di->bm = plat; if (np) { - ret = ab8500_bm_of_probe(&pdev->dev, np, di->bm); + ret = ab8500_bm_of_probe(dev, np, di->bm); if (ret) { - dev_err(&pdev->dev, "failed to get battery information\n"); + dev_err(dev, "failed to get battery information\n"); return ret; } di->autopower_cfg = of_property_read_bool(np, "autopower_cfg"); @@ -3378,40 +3371,33 @@ static int ab8500_charger_probe(struct platform_device *pdev) di->autopower_cfg = false; /* get parent data */ - di->dev = &pdev->dev; + di->dev = dev; di->parent = dev_get_drvdata(pdev->dev.parent); /* Get ADC channels */ - di->adc_main_charger_v = devm_iio_channel_get(&pdev->dev, - "main_charger_v"); + di->adc_main_charger_v = devm_iio_channel_get(dev, "main_charger_v"); if (IS_ERR(di->adc_main_charger_v)) { - if (PTR_ERR(di->adc_main_charger_v) == -ENODEV) - return -EPROBE_DEFER; - dev_err(&pdev->dev, "failed to get ADC main charger voltage\n"); - return PTR_ERR(di->adc_main_charger_v); + ret = dev_err_probe(dev, PTR_ERR(di->adc_main_charger_v), + "failed to get ADC main charger voltage\n"); + return ret; } - di->adc_main_charger_c = devm_iio_channel_get(&pdev->dev, - "main_charger_c"); + di->adc_main_charger_c = devm_iio_channel_get(dev, "main_charger_c"); if (IS_ERR(di->adc_main_charger_c)) { - if (PTR_ERR(di->adc_main_charger_c) == -ENODEV) - return -EPROBE_DEFER; - dev_err(&pdev->dev, "failed to get ADC main charger current\n"); - return PTR_ERR(di->adc_main_charger_c); + ret = dev_err_probe(dev, PTR_ERR(di->adc_main_charger_c), + "failed to get ADC main charger current\n"); + return ret; } - di->adc_vbus_v = devm_iio_channel_get(&pdev->dev, "vbus_v"); + di->adc_vbus_v = devm_iio_channel_get(dev, "vbus_v"); if (IS_ERR(di->adc_vbus_v)) { - if (PTR_ERR(di->adc_vbus_v) == -ENODEV) - return -EPROBE_DEFER; - dev_err(&pdev->dev, "failed to get ADC USB charger voltage\n"); - return PTR_ERR(di->adc_vbus_v); + ret = dev_err_probe(dev, PTR_ERR(di->adc_vbus_v), + "failed to get ADC USB charger voltage\n"); + return ret; } - di->adc_usb_charger_c = devm_iio_channel_get(&pdev->dev, - "usb_charger_c"); + di->adc_usb_charger_c = devm_iio_channel_get(dev, "usb_charger_c"); if (IS_ERR(di->adc_usb_charger_c)) { - if (PTR_ERR(di->adc_usb_charger_c) == -ENODEV) - return -EPROBE_DEFER; - dev_err(&pdev->dev, "failed to get ADC USB charger current\n"); - return PTR_ERR(di->adc_usb_charger_c); + ret = dev_err_probe(dev, PTR_ERR(di->adc_usb_charger_c), + "failed to get ADC USB charger current\n"); + return ret; } /* initialize lock */ @@ - |
