Merge tag 'for-v6.8-v2' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 19 Jan 2024 19:34:19 +0000 (11:34 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 19 Jan 2024 19:34:19 +0000 (11:34 -0800)
Pull power supply and reset updates from Sebastian Reichel:
 "New features:
   - bq24190: Add support for BQ24296 charger

  Cleanups:
   - all reset drivers: Stop using module_platform_driver_probe()
   - gpio-restart: use devm_register_sys_off_handler
   - pwr-mlxbf: support graceful reboot
   - cw2015: correct time_to_empty units
   - qcom-battmgr: Fix driver initialization sequence
   - bq27xxx: Start/Stop delayed work in suspend/resume
   - minor cleanups and fixes"

* tag 'for-v6.8-v2' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply: (33 commits)
  power: supply: bq24190_charger: Fix "initializer element is not constant" error
  power: supply: bq24190_charger: Add support for BQ24296
  dt-bindings: power: supply: bq24190: Add BQ24296 compatible
  dt-bindings: power: reset: xilinx: Rename node names in examples
  power: supply: qcom_battmgr: Register the power supplies after PDR is up
  dt-bindings: power: reset: qcom-pon: fix inconsistent example
  power: supply: Fix null pointer dereference in smb2_probe
  power: reset: at91: Drop '__init' from at91_wakeup_status()
  power: supply: Use multiple MODULE_AUTHOR statements
  power: supply: Fix indentation and some other warnings
  power: reset: gpio-restart: Use devm_register_sys_off_handler()
  power: supply: bq256xx: fix some problem in bq256xx_hw_init
  power: supply: cw2015: correct time_to_empty units in sysfs
  power: reset: at91-sama5d2_shdwc: Convert to platform remove callback returning void
  power: reset: at91-reset: Convert to platform remove callback returning void
  power: reset: tps65086-restart: Convert to platform remove callback returning void
  power: reset: syscon-poweroff: Convert to platform remove callback returning void
  power: reset: rmobile-reset: Convert to platform remove callback returning void
  power: reset: restart-poweroff: Convert to platform remove callback returning void
  power: reset: regulator-poweroff: Convert to platform remove callback returning void
  ...

29 files changed:
Documentation/devicetree/bindings/power/reset/nvmem-reboot-mode.yaml
Documentation/devicetree/bindings/power/reset/qcom,pon.yaml
Documentation/devicetree/bindings/power/reset/syscon-reboot-mode.yaml
Documentation/devicetree/bindings/power/reset/xlnx,zynqmp-power.yaml
Documentation/devicetree/bindings/power/supply/bq24190.yaml
drivers/power/reset/as3722-poweroff.c
drivers/power/reset/at91-poweroff.c
drivers/power/reset/at91-reset.c
drivers/power/reset/at91-sama5d2_shdwc.c
drivers/power/reset/atc260x-poweroff.c
drivers/power/reset/gpio-restart.c
drivers/power/reset/ltc2952-poweroff.c
drivers/power/reset/mt6323-poweroff.c
drivers/power/reset/pwr-mlxbf.c
drivers/power/reset/qnap-poweroff.c
drivers/power/reset/regulator-poweroff.c
drivers/power/reset/restart-poweroff.c
drivers/power/reset/rmobile-reset.c
drivers/power/reset/syscon-poweroff.c
drivers/power/reset/tps65086-restart.c
drivers/power/supply/bq24190_charger.c
drivers/power/supply/bq256xx_charger.c
drivers/power/supply/bq27xxx_battery.c
drivers/power/supply/bq27xxx_battery_i2c.c
drivers/power/supply/cw2015_battery.c
drivers/power/supply/power_supply_core.c
drivers/power/supply/qcom_battmgr.c
drivers/power/supply/qcom_pmi8998_charger.c
include/linux/power/bq27xxx_battery.h

index 14a262b..627f8a6 100644 (file)
@@ -28,17 +28,15 @@ properties:
     items:
       - const: reboot-mode
 
-patternProperties:
-  "^mode-.+":
-    $ref: /schemas/types.yaml#/definitions/uint32
-    description: Vendor-specific mode value written to the mode register
+allOf:
+  - $ref: reboot-mode.yaml#
 
 required:
   - compatible
   - nvmem-cells
   - nvmem-cell-names
 
-additionalProperties: false
+unevaluatedProperties: false
 
 examples:
   - |
index 5e46012..fc8105a 100644 (file)
@@ -111,21 +111,24 @@ examples:
    #include <dt-bindings/interrupt-controller/irq.h>
    #include <dt-bindings/input/linux-event-codes.h>
    #include <dt-bindings/spmi/spmi.h>
-   spmi_bus: spmi@c440000 {
+
+   spmi@c440000 {
      reg = <0x0c440000 0x1100>;
      #address-cells = <2>;
      #size-cells = <0>;
-     pmk8350: pmic@0 {
+
+     pmic@0 {
        reg = <0x0 SPMI_USID>;
        #address-cells = <1>;
        #size-cells = <0>;
-       pmk8350_pon: pon_hlos@1300 {
-         reg = <0x1300>;
+
+       pon@800 {
          compatible = "qcom,pm8998-pon";
+         reg = <0x800>;
 
          pwrkey {
             compatible = "qcom,pm8941-pwrkey";
-            interrupts = < 0x0 0x8 0 IRQ_TYPE_EDGE_BOTH >;
+            interrupts = <0x0 0x8 0 IRQ_TYPE_EDGE_BOTH>;
             debounce = <15625>;
             bias-pull-up;
             linux,code = <KEY_POWER>;
index 9b1ffce..b6acff1 100644 (file)
@@ -29,12 +29,10 @@ properties:
     $ref: /schemas/types.yaml#/definitions/uint32
     description: Offset in the register map for the mode register (in bytes)
 
-patternProperties:
-  "^mode-.+":
-    $ref: /schemas/types.yaml#/definitions/uint32
-    description: Vendor-specific mode value written to the mode register
+allOf:
+  - $ref: reboot-mode.yaml#
 
-additionalProperties: false
+unevaluatedProperties: false
 
 required:
   - compatible
index 45792e2..7998316 100644 (file)
@@ -57,7 +57,7 @@ examples:
 
     firmware {
       zynqmp-firmware {
-        zynqmp-power {
+        power-management {
           compatible = "xlnx,zynqmp-power";
           interrupts = <0 35 4>;
         };
@@ -70,7 +70,7 @@ examples:
 
     firmware {
       zynqmp-firmware {
-        zynqmp-power {
+        power-management {
           compatible = "xlnx,zynqmp-power";
           interrupt-parent = <&gic>;
           interrupts = <0 35 4>;
index d3ebc9d..131b7e5 100644 (file)
@@ -20,6 +20,7 @@ properties:
       - ti,bq24192
       - ti,bq24192i
       - ti,bq24196
+      - ti,bq24296
 
   reg:
     maxItems: 1
index 829e0db..ab3350c 100644 (file)
@@ -61,13 +61,11 @@ static int as3722_poweroff_probe(struct platform_device *pdev)
        return 0;
 }
 
-static int as3722_poweroff_remove(struct platform_device *pdev)
+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;
-
-       return 0;
 }
 
 static struct platform_driver as3722_poweroff_driver = {
@@ -75,7 +73,7 @@ static struct platform_driver as3722_poweroff_driver = {
                .name = "as3722-power-off",
        },
        .probe = as3722_poweroff_probe,
-       .remove = as3722_poweroff_remove,
+       .remove_new = as3722_poweroff_remove,
 };
 
 module_platform_driver(as3722_poweroff_driver);
index dd53997..93eece0 100644 (file)
@@ -57,7 +57,7 @@ static struct shdwc {
        void __iomem *mpddrc_base;
 } at91_shdwc;
 
-static void __init at91_wakeup_status(struct platform_device *pdev)
+static void at91_wakeup_status(struct platform_device *pdev)
 {
        const char *reason;
        u32 reg = readl(at91_shdwc.shdwc_base + AT91_SHDW_SR);
@@ -149,7 +149,7 @@ static void at91_poweroff_dt_set_wakeup_mode(struct platform_device *pdev)
        writel(wakeup_mode | mode, at91_shdwc.shdwc_base + AT91_SHDW_MR);
 }
 
-static int __init at91_poweroff_probe(struct platform_device *pdev)
+static int at91_poweroff_probe(struct platform_device *pdev)
 {
        struct device_node *np;
        u32 ddr_type;
@@ -202,7 +202,7 @@ clk_disable:
        return ret;
 }
 
-static int __exit at91_poweroff_remove(struct platform_device *pdev)
+static void at91_poweroff_remove(struct platform_device *pdev)
 {
        if (pm_power_off == at91_poweroff)
                pm_power_off = NULL;
@@ -211,8 +211,6 @@ static int __exit at91_poweroff_remove(struct platform_device *pdev)
                iounmap(at91_shdwc.mpddrc_base);
 
        clk_disable_unprepare(at91_shdwc.sclk);
-
-       return 0;
 }
 
 static const struct of_device_id at91_poweroff_of_match[] = {
@@ -224,13 +222,14 @@ static const struct of_device_id at91_poweroff_of_match[] = {
 MODULE_DEVICE_TABLE(of, at91_poweroff_of_match);
 
 static struct platform_driver at91_poweroff_driver = {
-       .remove = __exit_p(at91_poweroff_remove),
+       .probe = at91_poweroff_probe,
+       .remove_new = at91_poweroff_remove,
        .driver = {
                .name = "at91-poweroff",
                .of_match_table = at91_poweroff_of_match,
        },
 };
-module_platform_driver_probe(at91_poweroff_driver, at91_poweroff_probe);
+module_platform_driver(at91_poweroff_driver);
 
 MODULE_AUTHOR("Atmel Corporation");
 MODULE_DESCRIPTION("Shutdown driver for Atmel SoCs");
index aa9b012..1651265 100644 (file)
@@ -337,7 +337,7 @@ static int at91_rcdev_init(struct at91_reset *reset,
        return devm_reset_controller_register(&pdev->dev, &reset->rcdev);
 }
 
-static int __init at91_reset_probe(struct platform_device *pdev)
+static int at91_reset_probe(struct platform_device *pdev)
 {
        const struct of_device_id *match;
        struct at91_reset *reset;
@@ -417,24 +417,23 @@ disable_clk:
        return ret;
 }
 
-static int __exit at91_reset_remove(struct platform_device *pdev)
+static void at91_reset_remove(struct platform_device *pdev)
 {
        struct at91_reset *reset = platform_get_drvdata(pdev);
 
        unregister_restart_handler(&reset->nb);
        clk_disable_unprepare(reset->sclk);
-
-       return 0;
 }
 
 static struct platform_driver at91_reset_driver = {
-       .remove = __exit_p(at91_reset_remove),
+       .probe = at91_reset_probe,
+       .remove_new = at91_reset_remove,
        .driver = {
                .name = "at91-reset",
                .of_match_table = at91_reset_of_match,
        },
 };
-module_platform_driver_probe(at91_reset_driver, at91_reset_probe);
+module_platform_driver(at91_reset_driver);
 
 MODULE_AUTHOR("Atmel Corporation");
 MODULE_DESCRIPTION("Reset driver for Atmel SoCs");
index e76b102..959ce0d 100644 (file)
@@ -107,7 +107,7 @@ static const unsigned long long sdwc_dbc_period[] = {
        0, 3, 32, 512, 4096, 32768,
 };
 
-static void __init at91_wakeup_status(struct platform_device *pdev)
+static void at91_wakeup_status(struct platform_device *pdev)
 {
        struct shdwc *shdw = platform_get_drvdata(pdev);
        const struct reg_config *rcfg = shdw->rcfg;
@@ -329,7 +329,7 @@ static const struct of_device_id at91_pmc_ids[] = {
        { /* Sentinel. */ }
 };
 
-static int __init at91_shdwc_probe(struct platform_device *pdev)
+static int at91_shdwc_probe(struct platform_device *pdev)
 {
        const struct of_device_id *match;
        struct device_node *np;
@@ -421,7 +421,7 @@ clk_disable:
        return ret;
 }
 
-static int __exit at91_shdwc_remove(struct platform_device *pdev)
+static void at91_shdwc_remove(struct platform_device *pdev)
 {
        struct shdwc *shdw = platform_get_drvdata(pdev);
 
@@ -437,18 +437,17 @@ static int __exit at91_shdwc_remove(struct platform_device *pdev)
        iounmap(shdw->pmc_base);
 
        clk_disable_unprepare(shdw->sclk);
-
-       return 0;
 }
 
 static struct platform_driver at91_shdwc_driver = {
-       .remove = __exit_p(at91_shdwc_remove),
+       .probe = at91_shdwc_probe,
+       .remove_new = at91_shdwc_remove,
        .driver = {
                .name = "at91-shdwc",
                .of_match_table = at91_shdwc_of_match,
        },
 };
-module_platform_driver_probe(at91_shdwc_driver, at91_shdwc_probe);
+module_platform_driver(at91_shdwc_driver);
 
 MODULE_AUTHOR("Nicolas Ferre <nicolas.ferre@atmel.com>");
 MODULE_DESCRIPTION("Atmel shutdown controller driver");
index 98f2025..b4aa50e 100644 (file)
@@ -233,7 +233,7 @@ static int atc260x_pwrc_probe(struct platform_device *pdev)
        return ret;
 }
 
-static int atc260x_pwrc_remove(struct platform_device *pdev)
+static void atc260x_pwrc_remove(struct platform_device *pdev)
 {
        struct atc260x_pwrc *priv = platform_get_drvdata(pdev);
 
@@ -243,13 +243,11 @@ static int atc260x_pwrc_remove(struct platform_device *pdev)
        }
 
        unregister_restart_handler(&priv->restart_nb);
-
-       return 0;
 }
 
 static struct platform_driver atc260x_pwrc_driver = {
        .probe = atc260x_pwrc_probe,
-       .remove = atc260x_pwrc_remove,
+       .remove_new = atc260x_pwrc_remove,
        .driver = {
                .name = "atc260x-pwrc",
        },
index 3aa1976..d1e1771 100644 (file)
 
 struct gpio_restart {
        struct gpio_desc *reset_gpio;
-       struct notifier_block restart_handler;
        u32 active_delay_ms;
        u32 inactive_delay_ms;
        u32 wait_delay_ms;
 };
 
-static int gpio_restart_notify(struct notifier_block *this,
-                               unsigned long mode, void *cmd)
+static int gpio_restart_notify(struct sys_off_data *data)
 {
-       struct gpio_restart *gpio_restart =
-               container_of(this, struct gpio_restart, restart_handler);
+       struct gpio_restart *gpio_restart = data->cb_data;
 
        /* drive it active, also inactive->active edge */
        gpiod_direction_output(gpio_restart->reset_gpio, 1);
@@ -52,6 +49,7 @@ static int gpio_restart_probe(struct platform_device *pdev)
 {
        struct gpio_restart *gpio_restart;
        bool open_source = false;
+       int priority = 129;
        u32 property;
        int ret;
 
@@ -71,8 +69,6 @@ static int gpio_restart_probe(struct platform_device *pdev)
                return ret;
        }
 
-       gpio_restart->restart_handler.notifier_call = gpio_restart_notify;
-       gpio_restart->restart_handler.priority = 129;
        gpio_restart->active_delay_ms = 100;
        gpio_restart->inactive_delay_ms = 100;
        gpio_restart->wait_delay_ms = 3000;
@@ -83,7 +79,7 @@ static int gpio_restart_probe(struct platform_device *pdev)
                        dev_err(&pdev->dev, "Invalid priority property: %u\n",
                                        property);
                else
-                       gpio_restart->restart_handler.priority = property;
+                       priority = property;
        }
 
        of_property_read_u32(pdev->dev.of_node, "active-delay",
@@ -93,9 +89,11 @@ static int gpio_restart_probe(struct platform_device *pdev)
        of_property_read_u32(pdev->dev.of_node, "wait-delay",
                        &gpio_restart->wait_delay_ms);
 
-       platform_set_drvdata(pdev, gpio_restart);
-
-       ret = register_restart_handler(&gpio_restart->restart_handler);
+       ret = devm_register_sys_off_handler(&pdev->dev,
+                                           SYS_OFF_MODE_RESTART,
+                                           priority,
+                                           gpio_restart_notify,
+                                           gpio_restart);
        if (ret) {
                dev_err(&pdev->dev, "%s: cannot register restart handler, %d\n",
                                __func__, ret);
@@ -105,19 +103,6 @@ static int gpio_restart_probe(struct platform_device *pdev)
        return 0;
 }
 
-static void gpio_restart_remove(struct platform_device *pdev)
-{
-       struct gpio_restart *gpio_restart = platform_get_drvdata(pdev);
-       int ret;
-
-       ret = unregister_restart_handler(&gpio_restart->restart_handler);
-       if (ret) {
-               dev_err(&pdev->dev,
-                               "%s: cannot unregister restart handler, %d\n",
-                               __func__, ret);
-       }
-}
-
 static const struct of_device_id of_gpio_restart_match[] = {
        { .compatible = "gpio-restart", },
        {},
@@ -125,7 +110,6 @@ static const struct of_device_id of_gpio_restart_match[] = {
 
 static struct platform_driver gpio_restart_driver = {
        .probe = gpio_restart_probe,
-       .remove_new = gpio_restart_remove,
        .driver = {
                .name = "restart-gpio",
                .of_match_table = of_gpio_restart_match,
index eea0592..fa25fbd 100644 (file)
@@ -286,7 +286,7 @@ static int ltc2952_poweroff_probe(struct platform_device *pdev)
        return 0;
 }
 
-static int ltc2952_poweroff_remove(struct platform_device *pdev)
+static void ltc2952_poweroff_remove(struct platform_device *pdev)
 {
        struct ltc2952_poweroff *data = platform_get_drvdata(pdev);
 
@@ -295,7 +295,6 @@ static int ltc2952_poweroff_remove(struct platform_device *pdev)
        hrtimer_cancel(&data->timer_wde);
        atomic_notifier_chain_unregister(&panic_notifier_list,
                                         &data->panic_notifier);
-       return 0;
 }
 
 static const struct of_device_id of_ltc2952_poweroff_match[] = {
@@ -306,7 +305,7 @@ MODULE_DEVICE_TABLE(of, of_ltc2952_poweroff_match);
 
 static struct platform_driver ltc2952_poweroff_driver = {
        .probe = ltc2952_poweroff_probe,
-       .remove = ltc2952_poweroff_remove,
+       .remove_new = ltc2952_poweroff_remove,
        .driver = {
                .name = "ltc2952-poweroff",
                .of_match_table = of_ltc2952_poweroff_match,
index 108167f..57a63c0 100644 (file)
@@ -70,12 +70,10 @@ static int mt6323_pwrc_probe(struct platform_device *pdev)
        return 0;
 }
 
-static int mt6323_pwrc_remove(struct platform_device *pdev)
+static void mt6323_pwrc_remove(struct platform_device *pdev)
 {
        if (pm_power_off == &mt6323_do_pwroff)
                pm_power_off = NULL;
-
-       return 0;
 }
 
 static const struct of_device_id mt6323_pwrc_dt_match[] = {
@@ -86,7 +84,7 @@ MODULE_DEVICE_TABLE(of, mt6323_pwrc_dt_match);
 
 static struct platform_driver mt6323_pwrc_driver = {
        .probe          = mt6323_pwrc_probe,
-       .remove         = mt6323_pwrc_remove,
+       .remove_new     = mt6323_pwrc_remove,
        .driver         = {
                .name   = "mt6323-pwrc",
                .of_match_table = mt6323_pwrc_dt_match,
index de35d24..1775b31 100644 (file)
 #include <linux/types.h>
 
 struct pwr_mlxbf {
-       struct work_struct send_work;
+       struct work_struct reboot_work;
+       struct work_struct shutdown_work;
        const char *hid;
 };
 
-static void pwr_mlxbf_send_work(struct work_struct *work)
+static void pwr_mlxbf_reboot_work(struct work_struct *work)
+{
+       acpi_bus_generate_netlink_event("button/reboot.*", "Reboot Button", 0x80, 1);
+}
+
+static void pwr_mlxbf_shutdown_work(struct work_struct *work)
 {
        acpi_bus_generate_netlink_event("button/power.*", "Power Button", 0x80, 1);
 }
@@ -33,10 +39,10 @@ static irqreturn_t pwr_mlxbf_irq(int irq, void *ptr)
        struct pwr_mlxbf *priv = ptr;
 
        if (!strncmp(priv->hid, rst_pwr_hid, 8))
-               emergency_restart();
+               schedule_work(&priv->reboot_work);
 
        if (!strncmp(priv->hid, low_pwr_hid, 8))
-               schedule_work(&priv->send_work);
+               schedule_work(&priv->shutdown_work);
 
        return IRQ_HANDLED;
 }
@@ -64,7 +70,11 @@ static int pwr_mlxbf_probe(struct platform_device *pdev)
        if (irq < 0)
                return dev_err_probe(dev, irq, "Error getting %s irq.\n", priv->hid);
 
-       err = devm_work_autocancel(dev, &priv->send_work, pwr_mlxbf_send_work);
+       err = devm_work_autocancel(dev, &priv->shutdown_work, pwr_mlxbf_shutdown_work);
+       if (err)
+               return err;
+
+       err = devm_work_autocancel(dev, &priv->reboot_work, pwr_mlxbf_reboot_work);
        if (err)
                return err;
 
index 0ddf7f2..e0f2ff6 100644 (file)
@@ -111,15 +111,14 @@ static int qnap_power_off_probe(struct platform_device *pdev)
        return 0;
 }
 
-static int qnap_power_off_remove(struct platform_device *pdev)
+static void qnap_power_off_remove(struct platform_device *pdev)
 {
        pm_power_off = NULL;
-       return 0;
 }
 
 static struct platform_driver qnap_power_off_driver = {
        .probe  = qnap_power_off_probe,
-       .remove = qnap_power_off_remove,
+       .remove_new = qnap_power_off_remove,
        .driver = {
                .name   = "qnap_power_off",
                .of_match_table = of_match_ptr(qnap_power_off_of_match_table),
index 7f87fbb..1516080 100644 (file)
@@ -52,12 +52,10 @@ static int regulator_poweroff_probe(struct platform_device *pdev)
        return 0;
 }
 
-static int regulator_poweroff_remove(__maybe_unused struct platform_device *pdev)
+static void regulator_poweroff_remove(struct platform_device *pdev)
 {
        if (pm_power_off == &regulator_poweroff_do_poweroff)
                pm_power_off = NULL;
-
-       return 0;
 }
 
 static const struct of_device_id of_regulator_poweroff_match[] = {
@@ -68,7 +66,7 @@ MODULE_DEVICE_TABLE(of, of_regulator_poweroff_match);
 
 static struct platform_driver regulator_poweroff_driver = {
        .probe = regulator_poweroff_probe,
-       .remove = regulator_poweroff_remove,
+       .remove_new = regulator_poweroff_remove,
        .driver = {
                .name = "poweroff-regulator",
                .of_match_table = of_regulator_poweroff_match,
index 28f1822..f4d6004 100644 (file)
@@ -33,12 +33,10 @@ static int restart_poweroff_probe(struct platform_device *pdev)
        return 0;
 }
 
-static int restart_poweroff_remove(struct platform_device *pdev)
+static void restart_poweroff_remove(struct platform_device *pdev)
 {
        if (pm_power_off == &restart_poweroff_do_poweroff)
                pm_power_off = NULL;
-
-       return 0;
 }
 
 static const struct of_device_id of_restart_poweroff_match[] = {
@@ -49,7 +47,7 @@ MODULE_DEVICE_TABLE(of, of_restart_poweroff_match);
 
 static struct platform_driver restart_poweroff_driver = {
        .probe = restart_poweroff_probe,
-       .remove = restart_poweroff_remove,
+       .remove_new = restart_poweroff_remove,
        .driver = {
                .name = "poweroff-restart",
                .of_match_table = of_restart_poweroff_match,
index bd3b396..5df9b41 100644 (file)
@@ -59,11 +59,10 @@ fail_unmap:
        return error;
 }
 
-static int rmobile_reset_remove(struct platform_device *pdev)
+static void rmobile_reset_remove(struct platform_device *pdev)
 {
        unregister_restart_handler(&rmobile_reset_nb);
        iounmap(sysc_base2);
-       return 0;
 }
 
 static const struct of_device_id rmobile_reset_of_match[] = {
@@ -74,7 +73,7 @@ MODULE_DEVICE_TABLE(of, rmobile_reset_of_match);
 
 static struct platform_driver rmobile_reset_driver = {
        .probe = rmobile_reset_probe,
-       .remove = rmobile_reset_remove,
+       .remove_new = rmobile_reset_remove,
        .driver = {
                .name = "rmobile_reset",
                .of_match_table = rmobile_reset_of_match,
index c3aab7f..1b2ce77 100644 (file)
@@ -76,12 +76,10 @@ static int syscon_poweroff_probe(struct platform_device *pdev)
        return 0;
 }
 
-static int syscon_poweroff_remove(struct platform_device *pdev)
+static void syscon_poweroff_remove(struct platform_device *pdev)
 {
        if (pm_power_off == syscon_poweroff)
                pm_power_off = NULL;
-
-       return 0;
 }
 
 static const struct of_device_id syscon_poweroff_of_match[] = {
@@ -91,7 +89,7 @@ static const struct of_device_id syscon_poweroff_of_match[] = {
 
 static struct platform_driver syscon_poweroff_driver = {
        .probe = syscon_poweroff_probe,
-       .remove = syscon_poweroff_remove,
+       .remove_new = syscon_poweroff_remove,
        .driver = {
                .name = "syscon-poweroff",
                .of_match_table = syscon_poweroff_of_match,
index 5ec819e..ee8e9f4 100644 (file)
@@ -62,19 +62,21 @@ static int tps65086_restart_probe(struct platform_device *pdev)
        return 0;
 }
 
-static int tps65086_restart_remove(struct platform_device *pdev)
+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 -ENODEV;
        }
-
-       return 0;
 }
 
 static const struct platform_device_id tps65086_restart_id_table[] = {
@@ -88,7 +90,7 @@ static struct platform_driver tps65086_restart_driver = {
                .name = "tps65086-restart",
        },
        .probe = tps65086_restart_probe,
-       .remove = tps65086_restart_remove,
+       .remove_new = tps65086_restart_remove,
        .id_table = tps65086_restart_id_table,
 };
 module_platform_driver(tps65086_restart_driver);
index 1db290e..2b393eb 100644 (file)
 #define BQ24190_REG_POC_WDT_RESET_SHIFT                6
 #define BQ24190_REG_POC_CHG_CONFIG_MASK                (BIT(5) | BIT(4))
 #define BQ24190_REG_POC_CHG_CONFIG_SHIFT       4
-#define BQ24190_REG_POC_CHG_CONFIG_DISABLE             0x0
-#define BQ24190_REG_POC_CHG_CONFIG_CHARGE              0x1
-#define BQ24190_REG_POC_CHG_CONFIG_OTG                 0x2
-#define BQ24190_REG_POC_CHG_CONFIG_OTG_ALT             0x3
+#define BQ24190_REG_POC_CHG_CONFIG_DISABLE     0x0
+#define BQ24190_REG_POC_CHG_CONFIG_CHARGE      0x1
+#define BQ24190_REG_POC_CHG_CONFIG_OTG         0x2
+#define BQ24190_REG_POC_CHG_CONFIG_OTG_ALT     0x3
+#define BQ24296_REG_POC_OTG_CONFIG_MASK                BIT(5)
+#define BQ24296_REG_POC_OTG_CONFIG_SHIFT       5
+#define BQ24296_REG_POC_CHG_CONFIG_MASK                BIT(4)
+#define BQ24296_REG_POC_CHG_CONFIG_SHIFT       4
+#define BQ24296_REG_POC_OTG_CONFIG_DISABLE     0x0
+#define BQ24296_REG_POC_OTG_CONFIG_OTG         0x1
 #define BQ24190_REG_POC_SYS_MIN_MASK           (BIT(3) | BIT(2) | BIT(1))
 #define BQ24190_REG_POC_SYS_MIN_SHIFT          1
 #define BQ24190_REG_POC_SYS_MIN_MIN                    3000
 #define BQ24190_REG_F_BAT_FAULT_SHIFT          3
 #define BQ24190_REG_F_NTC_FAULT_MASK           (BIT(2) | BIT(1) | BIT(0))
 #define BQ24190_REG_F_NTC_FAULT_SHIFT          0
+#define BQ24296_REG_F_NTC_FAULT_MASK           (BIT(1) | BIT(0))
+#define BQ24296_REG_F_NTC_FAULT_SHIFT          0
 
 #define BQ24190_REG_VPRS       0x0A /* Vendor/Part/Revision Status */
 #define BQ24190_REG_VPRS_PN_MASK               (BIT(5) | BIT(4) | BIT(3))
 #define BQ24190_REG_VPRS_PN_SHIFT              3
-#define BQ24190_REG_VPRS_PN_24190                      0x4
-#define BQ24190_REG_VPRS_PN_24192                      0x5 /* Also 24193, 24196 */
-#define BQ24190_REG_VPRS_PN_24192I                     0x3
+#define BQ24190_REG_VPRS_PN_24190              0x4
+#define BQ24190_REG_VPRS_PN_24192              0x5 /* Also 24193, 24196 */
+#define BQ24190_REG_VPRS_PN_24192I             0x3
+#define BQ24296_REG_VPRS_PN_MASK               (BIT(7) | BIT(6) | BIT(5))
+#define BQ24296_REG_VPRS_PN_SHIFT              5
+#define BQ24296_REG_VPRS_PN_24296              0x1
 #define BQ24190_REG_VPRS_TS_PROFILE_MASK       BIT(2)
 #define BQ24190_REG_VPRS_TS_PROFILE_SHIFT      2
 #define BQ24190_REG_VPRS_DEV_REG_MASK          (BIT(1) | BIT(0))
 #define BQ24190_REG_VPRS_DEV_REG_SHIFT         0
 
-/*
- * The FAULT register is latched by the bq24190 (except for NTC_FAULT)
- * so the first read after a fault returns the latched value and subsequent
- * reads return the current value.  In order to return the fault status
- * to the user, have the interrupt handler save the reg's value and retrieve
- * it in the appropriate health/status routine.
- */
-struct bq24190_dev_info {
-       struct i2c_client               *client;
-       struct device                   *dev;
-       struct extcon_dev               *edev;
-       struct power_supply             *charger;
-       struct power_supply             *battery;
-       struct delayed_work             input_current_limit_work;
-       char                            model_name[I2C_NAME_SIZE];
-       bool                            initialized;
-       bool                            irq_event;
-       bool                            otg_vbus_enabled;
-       int                             charge_type;
-       u16                             sys_min;
-       u16                             iprechg;
-       u16                             iterm;
-       u32                             ichg;
-       u32                             ichg_max;
-       u32                             vreg;
-       u32                             vreg_max;
-       struct mutex                    f_reg_lock;
-       u8                              f_reg;
-       u8                              ss_reg;
-       u8                              watchdog;
-};
-
-static int bq24190_charger_set_charge_type(struct bq24190_dev_info *bdi,
-                                          const union power_supply_propval *val);
-
-static const unsigned int bq24190_usb_extcon_cable[] = {
-       EXTCON_USB,
-       EXTCON_NONE,
-};
-
 /*
  * The tables below provide a 2-way mapping for the value that goes in
  * the register field and the real-world value that it represents.
@@ -211,6 +182,9 @@ static const int bq24190_ccc_ichg_values[] = {
        4096000, 4160000, 4224000, 4288000, 4352000, 4416000, 4480000, 4544000
 };
 
+/* ICHG higher than 3008mA is not supported in BQ24296 */
+#define BQ24296_CCC_ICHG_VALUES_LEN    40
+
 /* REG04[7:2] (VREG) in uV */
 static const int bq24190_cvc_vreg_values[] = {
        3504000, 3520000, 3536000, 3552000, 3568000, 3584000, 3600000, 3616000,
@@ -228,6 +202,68 @@ static const int bq24190_ictrc_treg_values[] = {
        600, 800, 1000, 1200
 };
 
+enum bq24190_chip {
+       BQ24190,
+       BQ24192,
+       BQ24192i,
+       BQ24196,
+       BQ24296,
+};
+
+/*
+ * The FAULT register is latched by the bq24190 (except for NTC_FAULT)
+ * so the first read after a fault returns the latched value and subsequent
+ * reads return the current value.  In order to return the fault status
+ * to the user, have the interrupt handler save the reg's value and retrieve
+ * it in the appropriate health/status routine.
+ */
+struct bq24190_dev_info {
+       struct i2c_client               *client;
+       struct device                   *dev;
+       struct extcon_dev               *edev;
+       struct power_supply             *charger;
+       struct power_supply             *battery;
+       struct delayed_work             input_current_limit_work;
+       char                            model_name[I2C_NAME_SIZE];
+       bool                            initialized;
+       bool                            irq_event;
+       bool                            otg_vbus_enabled;
+       int                             charge_type;
+       u16                             sys_min;
+       u16                             iprechg;
+       u16                             iterm;
+       u32                             ichg;
+       u32                             ichg_max;
+       u32                             vreg;
+       u32                             vreg_max;
+       struct mutex                    f_reg_lock;
+       u8                              f_reg;
+       u8                              ss_reg;
+       u8                              watchdog;
+       const struct bq24190_chip_info  *info;
+};
+
+struct bq24190_chip_info {
+       int ichg_array_size;
+#ifdef CONFIG_REGULATOR
+       const struct regulator_desc *vbus_desc;
+#endif
+       int (*check_chip)(struct bq24190_dev_info *bdi);
+       int (*set_chg_config)(struct bq24190_dev_info *bdi, const u8 chg_config);
+       int (*set_otg_vbus)(struct bq24190_dev_info *bdi, bool enable);
+       u8 ntc_fault_mask;
+       int (*get_ntc_status)(const u8 value);
+};
+
+static int bq24190_charger_set_charge_type(struct bq24190_dev_info *bdi,
+                                          const union power_supply_propval *val);
+
+static const unsigned int bq24190_usb_extcon_cable[] = {
+       EXTCON_USB,
+       EXTCON_NONE,
+};
+
+
 /*
  * Return the index in 'tbl' of greatest value that is less than or equal to
  * 'val'.  The index range returned is 0 to 'tbl_size' - 1.  Assumes that
@@ -529,6 +565,43 @@ static int bq24190_set_otg_vbus(struct bq24190_dev_info *bdi, bool enable)
        return ret;
 }
 
+static int bq24296_set_otg_vbus(struct bq24190_dev_info *bdi, bool enable)
+{
+       int ret;
+
+       ret = pm_runtime_resume_and_get(bdi->dev);
+       if (ret < 0) {
+               dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", ret);
+               return ret;
+       }
+
+       bdi->otg_vbus_enabled = enable;
+       if (enable) {
+               ret = bq24190_write_mask(bdi, BQ24190_REG_POC,
+                                        BQ24296_REG_POC_CHG_CONFIG_MASK,
+                                        BQ24296_REG_POC_CHG_CONFIG_SHIFT,
+                                        BQ24190_REG_POC_CHG_CONFIG_DISABLE);
+
+               if (ret < 0)
+                       goto out;
+
+               ret = bq24190_write_mask(bdi, BQ24190_REG_POC,
+                                        BQ24296_REG_POC_OTG_CONFIG_MASK,
+                                        BQ24296_REG_POC_CHG_CONFIG_SHIFT,
+                                        BQ24296_REG_POC_OTG_CONFIG_OTG);
+       } else
+               ret = bq24190_write_mask(bdi, BQ24190_REG_POC,
+                                        BQ24296_REG_POC_OTG_CONFIG_MASK,
+                                        BQ24296_REG_POC_CHG_CONFIG_SHIFT,
+                                        BQ24296_REG_POC_OTG_CONFIG_DISABLE);
+
+out:
+       pm_runtime_mark_last_busy(bdi->dev);
+       pm_runtime_put_autosuspend(bdi->dev);
+
+       return ret;
+}
+
 #ifdef CONFIG_REGULATOR
 static int bq24190_vbus_enable(struct regulator_dev *dev)
 {
@@ -567,6 +640,43 @@ static int bq24190_vbus_is_enabled(struct regulator_dev *dev)
        return bdi->otg_vbus_enabled;
 }
 
+static int bq24296_vbus_enable(struct regulator_dev *dev)
+{
+       return bq24296_set_otg_vbus(rdev_get_drvdata(dev), true);
+}
+
+static int bq24296_vbus_disable(struct regulator_dev *dev)
+{
+       return bq24296_set_otg_vbus(rdev_get_drvdata(dev), false);
+}
+
+static int bq24296_vbus_is_enabled(struct regulator_dev *dev)
+{
+       struct bq24190_dev_info *bdi = rdev_get_drvdata(dev);
+       int ret;
+       u8 val;
+
+       ret = pm_runtime_resume_and_get(bdi->dev);
+       if (ret < 0) {
+               dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", ret);
+               return ret;
+       }
+
+       ret = bq24190_read_mask(bdi, BQ24190_REG_POC,
+                               BQ24296_REG_POC_OTG_CONFIG_MASK,
+                               BQ24296_REG_POC_OTG_CONFIG_SHIFT, &val);
+
+       pm_runtime_mark_last_busy(bdi->dev);
+       pm_runtime_put_autosuspend(bdi->dev);
+
+       if (ret)
+               return ret;
+
+       bdi->otg_vbus_enabled = (val == BQ24296_REG_POC_OTG_CONFIG_OTG);
+
+       return bdi->otg_vbus_enabled;
+}
+
 static const struct regulator_ops bq24190_vbus_ops = {
        .enable = bq24190_vbus_enable,
        .disable = bq24190_vbus_disable,
@@ -583,6 +693,22 @@ static const struct regulator_desc bq24190_vbus_desc = {
        .n_voltages = 1,
 };
 
+static const struct regulator_ops bq24296_vbus_ops = {
+       .enable = bq24296_vbus_enable,
+       .disable = bq24296_vbus_disable,
+       .is_enabled = bq24296_vbus_is_enabled,
+};
+
+static const struct regulator_desc bq24296_vbus_desc = {
+       .name = "usb_otg_vbus",
+       .of_match = "usb-otg-vbus",
+       .type = REGULATOR_VOLTAGE,
+       .owner = THIS_MODULE,
+       .ops = &bq24296_vbus_ops,
+       .fixed_uV = 5000000,
+       .n_voltages = 1,
+};
+
 static const struct regulator_init_data bq24190_vbus_init_data = {
        .constraints = {
                .valid_ops_mask = REGULATOR_CHANGE_STATUS,
@@ -602,7 +728,7 @@ static int bq24190_register_vbus_regulator(struct bq24190_dev_info *bdi)
        else
                cfg.init_data = &bq24190_vbus_init_data;
        cfg.driver_data = bdi;
-       reg = devm_regulator_register(bdi->dev, &bq24190_vbus_desc, &cfg);
+       reg = devm_regulator_register(bdi->dev, bdi->info->vbus_desc, &cfg);
        if (IS_ERR(reg)) {
                ret = PTR_ERR(reg);
                dev_err(bdi->dev, "Can't register regulator: %d\n", ret);
@@ -678,7 +804,7 @@ static int bq24190_set_config(struct bq24190_dev_info *bdi)
                                            BQ24190_REG_CCC_ICHG_MASK,
                                            BQ24190_REG_CCC_ICHG_SHIFT,
                                            bq24190_ccc_ichg_values,
-                                           ARRAY_SIZE(bq24190_ccc_ichg_values),
+                                           bdi->info->ichg_array_size,
                                            bdi->ichg);
                if (ret < 0)
                        return ret;
@@ -777,6 +903,24 @@ static int bq24190_charger_get_charge_type(struct bq24190_dev_info *bdi,
        return 0;
 }
 
+static int bq24190_battery_set_chg_config(struct bq24190_dev_info *bdi,
+               const u8 chg_config)
+{
+       return bq24190_write_mask(bdi, BQ24190_REG_POC,
+                       BQ24190_REG_POC_CHG_CONFIG_MASK,
+                       BQ24190_REG_POC_CHG_CONFIG_SHIFT,
+                       chg_config);
+}
+
+static int bq24296_battery_set_chg_config(struct bq24190_dev_info *bdi,
+               const u8 chg_config)
+{
+       return bq24190_write_mask(bdi, BQ24190_REG_POC,
+                       BQ24296_REG_POC_CHG_CONFIG_MASK,
+                       BQ24296_REG_POC_CHG_CONFIG_SHIFT,
+                       chg_config);
+}
+
 static int bq24190_charger_set_charge_type(struct bq24190_dev_info *bdi,
                const union power_supply_propval *val)
 {
@@ -835,9 +979,50 @@ static int bq24190_charger_set_charge_type(struct bq24190_dev_info *bdi,
                        return ret;
        }
 
-       return bq24190_write_mask(bdi, BQ24190_REG_POC,
-                       BQ24190_REG_POC_CHG_CONFIG_MASK,
-                       BQ24190_REG_POC_CHG_CONFIG_SHIFT, chg_config);
+       return bdi->info->set_chg_config(bdi, chg_config);
+}
+
+static int bq24190_charger_get_ntc_status(u8 value)
+{
+       int health;
+
+       switch (value >> BQ24190_REG_F_NTC_FAULT_SHIFT & 0x7) {
+       case 0x1: /* TS1  Cold */
+       case 0x3: /* TS2  Cold */
+       case 0x5: /* Both Cold */
+               health = POWER_SUPPLY_HEALTH_COLD;
+               break;
+       case 0x2: /* TS1  Hot */
+       case 0x4: /* TS2  Hot */
+       case 0x6: /* Both Hot */
+               health = POWER_SUPPLY_HEALTH_OVERHEAT;
+               break;
+       default:
+               health = POWER_SUPPLY_HEALTH_UNKNOWN;
+       }
+
+       return health;
+}
+
+static int bq24296_charger_get_ntc_status(u8 value)
+{
+       int health;
+
+       switch (value >> BQ24296_REG_F_NTC_FAULT_SHIFT & 0x3) {
+       case 0x0: /* Normal */
+               health = POWER_SUPPLY_HEALTH_GOOD;
+               break;
+       case 0x1: /* Hot */
+               health = POWER_SUPPLY_HEALTH_OVERHEAT;
+               break;
+       case 0x2: /* Cold */
+               health = POWER_SUPPLY_HEALTH_COLD;
+               break;
+       default:
+               health = POWER_SUPPLY_HEALTH_UNKNOWN;
+       }
+
+       return health;
 }
 
 static int bq24190_charger_get_health(struct bq24190_dev_info *bdi,
@@ -850,21 +1035,8 @@ static int bq24190_charger_get_health(struct bq24190_dev_info *bdi,
        v = bdi->f_reg;
        mutex_unlock(&bdi->f_reg_lock);
 
-       if (v & BQ24190_REG_F_NTC_FAULT_MASK) {
-               switch (v >> BQ24190_REG_F_NTC_FAULT_SHIFT & 0x7) {
-               case 0x1: /* TS1  Cold */
-               case 0x3: /* TS2  Cold */
-               case 0x5: /* Both Cold */
-                       health = POWER_SUPPLY_HEALTH_COLD;
-                       break;
-               case 0x2: /* TS1  Hot */
-               case 0x4: /* TS2  Hot */
-               case 0x6: /* Both Hot */
-                       health = POWER_SUPPLY_HEALTH_OVERHEAT;
-                       break;
-               default:
-                       health = POWER_SUPPLY_HEALTH_UNKNOWN;
-               }
+       if (v & bdi->info->ntc_fault_mask) {
+               health = bdi->info->get_ntc_status(v);
        } else if (v & BQ24190_REG_F_BAT_FAULT_MASK) {
                health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
        } else if (v & BQ24190_REG_F_CHRG_FAULT_MASK) {
@@ -1015,7 +1187,7 @@ static int bq24190_charger_get_current(struct bq24190_dev_info *bdi,
        ret = bq24190_get_field_val(bdi, BQ24190_REG_CCC,
                        BQ24190_REG_CCC_ICHG_MASK, BQ24190_REG_CCC_ICHG_SHIFT,
                        bq24190_ccc_ichg_values,
-                       ARRAY_SIZE(bq24190_ccc_ichg_values), &curr);
+                       bdi->info->ichg_array_size, &curr);
        if (ret < 0)
                return ret;
 
@@ -1055,7 +1227,7 @@ static int bq24190_charger_set_current(struct bq24190_dev_info *bdi,
        ret = bq24190_set_field_val(bdi, BQ24190_REG_CCC,
                        BQ24190_REG_CCC_ICHG_MASK, BQ24190_REG_CCC_ICHG_SHIFT,
                        bq24190_ccc_ichg_values,
-                       ARRAY_SIZE(bq24190_ccc_ichg_values), curr);
+                       bdi->info->ichg_array_size, curr);
        if (ret < 0)
                return ret;
 
@@ -1395,26 +1567,9 @@ static int bq24190_battery_get_health(struct bq24190_dev_info *bdi,
        if (v & BQ24190_REG_F_BAT_FAULT_MASK) {
                health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
        } else {
-               v &= BQ24190_REG_F_NTC_FAULT_MASK;
-               v >>= BQ24190_REG_F_NTC_FAULT_SHIFT;
+               v &= bdi->info->ntc_fault_mask;
 
-               switch (v) {
-               case 0x0: /* Normal */
-                       health = POWER_SUPPLY_HEALTH_GOOD;
-                       break;
-               case 0x1: /* TS1 Cold */
-               case 0x3: /* TS2 Cold */
-               case 0x5: /* Both Cold */
-                       health = POWER_SUPPLY_HEALTH_COLD;
-                       break;
-               case 0x2: /* TS1 Hot */
-               case 0x4: /* TS2 Hot */
-               case 0x6: /* Both Hot */
-                       health = POWER_SUPPLY_HEALTH_OVERHEAT;
-                       break;
-               default:
-                       health = POWER_SUPPLY_HEALTH_UNKNOWN;
-               }
+               health = v ? bdi->info->get_ntc_status(v) : POWER_SUPPLY_HEALTH_GOOD;
        }
 
        val->intval = health;
@@ -1601,12 +1756,13 @@ static int bq24190_configure_usb_otg(struct bq24190_dev_info *bdi, u8 ss_reg)
 static void bq24190_check_status(struct bq24190_dev_info *bdi)
 {
        const u8 battery_mask_ss = BQ24190_REG_SS_CHRG_STAT_MASK;
-       const u8 battery_mask_f = BQ24190_REG_F_BAT_FAULT_MASK
-                               | BQ24190_REG_F_NTC_FAULT_MASK;
+       u8 battery_mask_f = BQ24190_REG_F_BAT_FAULT_MASK;
        bool alert_charger = false, alert_battery = false;
        u8 ss_reg = 0, f_reg = 0;
        int i, ret;
 
+       battery_mask_f |= bdi->info->ntc_fault_mask;
+
        ret = bq24190_read(bdi, BQ24190_REG_SS, &ss_reg);
        if (ret < 0) {
                dev_err(bdi->dev, "Can't read SS reg: %d\n", ret);
@@ -1633,7 +1789,7 @@ static void bq24190_check_status(struct bq24190_dev_info *bdi)
                        !!(f_reg & BQ24190_REG_F_BOOST_FAULT_MASK),
                        !!(f_reg & BQ24190_REG_F_CHRG_FAULT_MASK),
                        !!(f_reg & BQ24190_REG_F_BAT_FAULT_MASK),
-                       !!(f_reg & BQ24190_REG_F_NTC_FAULT_MASK));
+                       !!(f_reg & bdi->info->ntc_fault_mask));
 
                mutex_lock(&bdi->f_reg_lock);
                if ((bdi->f_reg & battery_mask_f) != (f_reg & battery_mask_f))
@@ -1696,12 +1852,11 @@ static irqreturn_t bq24190_irq_handler_thread(int irq, void *data)
        return IRQ_HANDLED;
 }
 
-static int bq24190_hw_init(struct bq24190_dev_info *bdi)
+static int bq24190_check_chip(struct bq24190_dev_info *bdi)
 {
        u8 v;
        int ret;
 
-       /* First check that the device really is what its supposed to be */
        ret = bq24190_read_mask(bdi, BQ24190_REG_VPRS,
                        BQ24190_REG_VPRS_PN_MASK,
                        BQ24190_REG_VPRS_PN_SHIFT,
@@ -1719,6 +1874,40 @@ static int bq24190_hw_init(struct bq24190_dev_info *bdi)
                return -ENODEV;
        }
 
+       return 0;
+}
+
+static int bq24296_check_chip(struct bq24190_dev_info *bdi)
+{
+       u8 v;
+       int ret;
+
+       ret = bq24190_read_mask(bdi, BQ24190_REG_VPRS,
+                       BQ24296_REG_VPRS_PN_MASK,
+                       BQ24296_REG_VPRS_PN_SHIFT,
+                       &v);
+       if (ret < 0)
+               return ret;
+
+       switch (v) {
+       case BQ24296_REG_VPRS_PN_24296:
+               break;
+       default:
+               dev_err(bdi->dev, "Error unknown model: 0x%02x\n", v);
+               return -ENODEV;
+       }
+
+       return 0;
+}
+
+static int bq24190_hw_init(struct bq24190_dev_info *bdi)
+{
+       int ret;
+
+       ret = bdi->info->check_chip(bdi);
+       if (ret < 0)
+               return ret;
+
        ret = bq24190_register_reset(bdi);
        if (ret < 0)
                return ret;
@@ -1736,7 +1925,8 @@ static int bq24190_get_config(struct bq24190_dev_info *bdi)
        struct power_supply_battery_info *info;
        int v, idx;
 
-       idx = ARRAY_SIZE(bq24190_ccc_ichg_values) - 1;
+       idx = bdi->info->ichg_array_size - 1;
+
        bdi->ichg_max = bq24190_ccc_ichg_values[idx];
 
        idx = ARRAY_SIZE(bq24190_cvc_vreg_values) - 1;
@@ -1781,6 +1971,64 @@ static int bq24190_get_config(struct bq24190_dev_info *bdi)
        return 0;
 }
 
+static const struct bq24190_chip_info bq24190_chip_info_tbl[] = {
+       [BQ24190] = {
+               .ichg_array_size = ARRAY_SIZE(bq24190_ccc_ichg_values),
+#ifdef CONFIG_REGULATOR
+               .vbus_desc = &bq24190_vbus_desc,
+#endif
+               .check_chip = bq24190_check_chip,
+               .set_chg_config = bq24190_battery_set_chg_config,
+               .ntc_fault_mask = BQ24190_REG_F_NTC_FAULT_MASK,
+               .get_ntc_status = bq24190_charger_get_ntc_status,
+               .set_otg_vbus = bq24190_set_otg_vbus,
+       },
+       [BQ24192] = {
+               .ichg_array_size = ARRAY_SIZE(bq24190_ccc_ichg_values),
+#ifdef CONFIG_REGULATOR
+               .vbus_desc = &bq24190_vbus_desc,
+#endif
+               .check_chip = bq24190_check_chip,
+               .set_chg_config = bq24190_battery_set_chg_config,
+               .ntc_fault_mask = BQ24190_REG_F_NTC_FAULT_MASK,
+               .get_ntc_status = bq24190_charger_get_ntc_status,
+               .set_otg_vbus = bq24190_set_otg_vbus,
+       },
+       [BQ24192i] = {
+               .ichg_array_size = ARRAY_SIZE(bq24190_ccc_ichg_values),
+#ifdef CONFIG_REGULATOR
+               .vbus_desc = &bq24190_vbus_desc,
+#endif
+               .check_chip = bq24190_check_chip,
+               .set_chg_config = bq24190_battery_set_chg_config,
+               .ntc_fault_mask = BQ24190_REG_F_NTC_FAULT_MASK,
+               .get_ntc_status = bq24190_charger_get_ntc_status,
+               .set_otg_vbus = bq24190_set_otg_vbus,
+       },
+       [BQ24196] = {
+               .ichg_array_size = ARRAY_SIZE(bq24190_ccc_ichg_values),
+#ifdef CONFIG_REGULATOR
+               .vbus_desc = &bq24190_vbus_desc,
+#endif
+               .check_chip = bq24190_check_chip,
+               .set_chg_config = bq24190_battery_set_chg_config,
+               .ntc_fault_mask = BQ24190_REG_F_NTC_FAULT_MASK,
+               .get_ntc_status = bq24190_charger_get_ntc_status,
+               .set_otg_vbus = bq24190_set_otg_vbus,
+       },
+       [BQ24296] = {
+               .ichg_array_size = BQ24296_CCC_ICHG_VALUES_LEN,
+#ifdef CONFIG_REGULATOR
+               .vbus_desc = &bq24296_vbus_desc,
+#endif
+               .check_chip = bq24296_check_chip,
+               .set_chg_config = bq24296_battery_set_chg_config,
+               .ntc_fault_mask = BQ24296_REG_F_NTC_FAULT_MASK,
+               .get_ntc_status = bq24296_charger_get_ntc_status,
+               .set_otg_vbus = bq24296_set_otg_vbus,
+       },
+};
+
 static int bq24190_probe(struct i2c_client *client)
 {
        const struct i2c_device_id *id = i2c_client_get_device_id(client);
@@ -1804,6 +2052,7 @@ static int bq24190_probe(struct i2c_client *client)
        bdi->client = client;
        bdi->dev = dev;
        strscpy(bdi->model_name, id->name, sizeof(bdi->model_name));
+       bdi->info = i2c_get_match_data(client);
        mutex_init(&bdi->f_reg_lock);
        bdi->charge_type = POWER_SUPPLY_CHARGE_TYPE_FAST;
        bdi->f_reg = 0;
@@ -1940,7 +2189,7 @@ static void bq24190_shutdown(struct i2c_client *client)
        struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
 
        /* Turn off 5V boost regulator on shutdown */
-       bq24190_set_otg_vbus(bdi, false);
+       bdi->info->set_otg_vbus(bdi, false);
 }
 
 static __maybe_unused int bq24190_runtime_suspend(struct device *dev)
@@ -2029,19 +2278,21 @@ static const struct dev_pm_ops bq24190_pm_ops = {
 };
 
 static const struct i2c_device_id bq24190_i2c_ids[] = {
-       { "bq24190" },
-       { "bq24192" },
-       { "bq24192i" },
-       { "bq24196" },
+       { "bq24190", (kernel_ulong_t)&bq24190_chip_info_tbl[BQ24190] },
+       { "bq24192", (kernel_ulong_t)&bq24190_chip_info_tbl[BQ24192] },
+       { "bq24192i", (kernel_ulong_t)&bq24190_chip_info_tbl[BQ24192i] },
+       { "bq24196", (kernel_ulong_t)&bq24190_chip_info_tbl[BQ24196] },
+       { "bq24296", (kernel_ulong_t)&bq24190_chip_info_tbl[BQ24296] },
        { },
 };
 MODULE_DEVICE_TABLE(i2c, bq24190_i2c_ids);
 
 static const struct of_device_id bq24190_of_match[] = {
-       { .compatible = "ti,bq24190", },
-       { .compatible = "ti,bq24192", },
-       { .compatible = "ti,bq24192i", },
-       { .compatible = "ti,bq24196", },
+       { .compatible = "ti,bq24190", .data = &bq24190_chip_info_tbl[BQ24190] },
+       { .compatible = "ti,bq24192", .data = &bq24190_chip_info_tbl[BQ24192] },
+       { .compatible = "ti,bq24192i", .data = &bq24190_chip_info_tbl[BQ24192i] },
+       { .compatible = "ti,bq24196", .data = &bq24190_chip_info_tbl[BQ24196] },
+       { .compatible = "ti,bq24296", .data = &bq24190_chip_info_tbl[BQ24296] },
        { },
 };
 MODULE_DEVICE_TABLE(of, bq24190_of_match);
index 789a31b..1a935bc 100644 (file)
@@ -1574,13 +1574,16 @@ static int bq256xx_hw_init(struct bq256xx_device *bq)
                        wd_reg_val = i;
                        break;
                }
-               if (bq->watchdog_timer > bq256xx_watchdog_time[i] &&
+               if (i + 1 < BQ256XX_NUM_WD_VAL &&
+                   bq->watchdog_timer > bq256xx_watchdog_time[i] &&
                    bq->watchdog_timer < bq256xx_watchdog_time[i + 1])
                        wd_reg_val = i;
        }
        ret = regmap_update_bits(bq->regmap, BQ256XX_CHARGER_CONTROL_1,
                                 BQ256XX_WATCHDOG_MASK, wd_reg_val <<
                                                BQ256XX_WDT_BIT_SHIFT);
+       if (ret)
+               return ret;
 
        ret = power_supply_get_battery_info(bq->charger, &bat_info);
        if (ret == -ENOMEM)
index 4296600..1c4a9d1 100644 (file)
@@ -2162,6 +2162,28 @@ void bq27xxx_battery_teardown(struct bq27xxx_device_info *di)
 }
 EXPORT_SYMBOL_GPL(bq27xxx_battery_teardown);
 
+#ifdef CONFIG_PM_SLEEP
+static int bq27xxx_battery_suspend(struct device *dev)
+{
+       struct bq27xxx_device_info *di = dev_get_drvdata(dev);
+
+       cancel_delayed_work(&di->work);
+       return 0;
+}
+
+static int bq27xxx_battery_resume(struct device *dev)
+{
+       struct bq27xxx_device_info *di = dev_get_drvdata(dev);
+
+       schedule_delayed_work(&di->work, 0);
+       return 0;
+}
+#endif /* CONFIG_PM_SLEEP */
+
+SIMPLE_DEV_PM_OPS(bq27xxx_battery_battery_pm_ops,
+                 bq27xxx_battery_suspend, bq27xxx_battery_resume);
+EXPORT_SYMBOL_GPL(bq27xxx_battery_battery_pm_ops);
+
 MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
 MODULE_DESCRIPTION("BQ27xxx battery monitor driver");
 MODULE_LICENSE("GPL");
index 9b54755..3a1798b 100644 (file)
@@ -295,6 +295,7 @@ static struct i2c_driver bq27xxx_battery_i2c_driver = {
        .driver = {
                .name = "bq27xxx-battery",
                .of_match_table = of_match_ptr(bq27xxx_battery_i2c_of_match_table),
+               .pm = &bq27xxx_battery_battery_pm_ops,
        },
        .probe = bq27xxx_battery_i2c_probe,
        .remove = bq27xxx_battery_i2c_remove,
index bb29e9e..99f3ccd 100644 (file)
@@ -491,7 +491,7 @@ static int cw_battery_get_property(struct power_supply *psy,
 
        case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW:
                if (cw_battery_valid_time_to_empty(cw_bat))
-                       val->intval = cw_bat->time_to_empty;
+                       val->intval = cw_bat->time_to_empty * 60;
                else
                        val->intval = 0;
                break;
index 7326500..ecef35a 100644 (file)
@@ -861,44 +861,44 @@ const size_t power_supply_battery_info_properties_size = ARRAY_SIZE(power_supply
 EXPORT_SYMBOL_GPL(power_supply_battery_info_properties_size);
 
 bool power_supply_battery_info_has_prop(struct power_supply_battery_info *info,
-                                       enum power_supply_property psp)
+                                       enum power_supply_property psp)
 {
        if (!info)
                return false;
 
        switch (psp) {
-               case POWER_SUPPLY_PROP_TECHNOLOGY:
-                       return info->technology != POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
-               case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
-                       return info->energy_full_design_uwh >= 0;
-               case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
-                       return info->charge_full_design_uah >= 0;
-               case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
-                       return info->voltage_min_design_uv >= 0;
-               case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
-                       return info->voltage_max_design_uv >= 0;
-               case POWER_SUPPLY_PROP_PRECHARGE_CURRENT:
-                       return info->precharge_current_ua >= 0;
-               case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:
-                       return info->charge_term_current_ua >= 0;
-               case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
-                       return info->constant_charge_current_max_ua >= 0;
-               case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
-                       return info->constant_charge_voltage_max_uv >= 0;
-               case POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MIN:
-                       return info->temp_ambient_alert_min > INT_MIN;
-               case POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MAX:
-                       return info->temp_ambient_alert_max < INT_MAX;
-               case POWER_SUPPLY_PROP_TEMP_ALERT_MIN:
-                       return info->temp_alert_min > INT_MIN;
-               case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
-                       return info->temp_alert_max < INT_MAX;
-               case POWER_SUPPLY_PROP_TEMP_MIN:
-                       return info->temp_min > INT_MIN;
-               case POWER_SUPPLY_PROP_TEMP_MAX:
-                       return info->temp_max < INT_MAX;
-               default:
-                       return false;
+       case POWER_SUPPLY_PROP_TECHNOLOGY:
+               return info->technology != POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
+       case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
+               return info->energy_full_design_uwh >= 0;
+       case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
+               return info->charge_full_design_uah >= 0;
+       case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
+               return info->voltage_min_design_uv >= 0;
+       case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
+               return info->voltage_max_design_uv >= 0;
+       case POWER_SUPPLY_PROP_PRECHARGE_CURRENT:
+               return info->precharge_current_ua >= 0;
+       case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:
+               return info->charge_term_current_ua >= 0;
+       case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
+               return info->constant_charge_current_max_ua >= 0;
+       case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
+               return info->constant_charge_voltage_max_uv >= 0;
+       case POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MIN:
+               return info->temp_ambient_alert_min > INT_MIN;
+       case POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MAX:
+               return info->temp_ambient_alert_max < INT_MAX;
+       case POWER_SUPPLY_PROP_TEMP_ALERT_MIN:
+               return info->temp_alert_min > INT_MIN;
+       case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
+               return info->temp_alert_max < INT_MAX;
+       case POWER_SUPPLY_PROP_TEMP_MIN:
+               return info->temp_min > INT_MIN;
+       case POWER_SUPPLY_PROP_TEMP_MAX:
+               return info->temp_max < INT_MAX;
+       default:
+               return false;
        }
 }
 EXPORT_SYMBOL_GPL(power_supply_battery_info_has_prop);
@@ -914,53 +914,53 @@ int power_supply_battery_info_get_prop(struct power_supply_battery_info *info,
                return -EINVAL;
 
        switch (psp) {
-               case POWER_SUPPLY_PROP_TECHNOLOGY:
-                       val->intval = info->technology;
-                       return 0;
-               case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
-                       val->intval = info->energy_full_design_uwh;
-                       return 0;
-               case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
-                       val->intval = info->charge_full_design_uah;
-                       return 0;
-               case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
-                       val->intval = info->voltage_min_design_uv;
-                       return 0;
-               case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
-                       val->intval = info->voltage_max_design_uv;
-                       return 0;
-               case POWER_SUPPLY_PROP_PRECHARGE_CURRENT:
-                       val->intval = info->precharge_current_ua;
-                       return 0;
-               case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:
-                       val->intval = info->charge_term_current_ua;
-                       return 0;
-               case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
-                       val->intval = info->constant_charge_current_max_ua;
-                       return 0;
-               case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
-                       val->intval = info->constant_charge_voltage_max_uv;
-                       return 0;
-               case POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MIN:
-                       val->intval = info->temp_ambient_alert_min;
-                       return 0;
-               case POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MAX:
-                       val->intval = info->temp_ambient_alert_max;
-                       return 0;
-               case POWER_SUPPLY_PROP_TEMP_ALERT_MIN:
-                       val->intval = info->temp_alert_min;
-                       return 0;
-               case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
-                       val->intval = info->temp_alert_max;
-                       return 0;
-               case POWER_SUPPLY_PROP_TEMP_MIN:
-                       val->intval = info->temp_min;
-                       return 0;
-               case POWER_SUPPLY_PROP_TEMP_MAX:
-                       val->intval = info->temp_max;
-                       return 0;
-               default:
-                       return -EINVAL;
+       case POWER_SUPPLY_PROP_TECHNOLOGY:
+               val->intval = info->technology;
+               return 0;
+       case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
+               val->intval = info->energy_full_design_uwh;
+               return 0;
+       case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
+               val->intval = info->charge_full_design_uah;
+               return 0;
+       case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
+               val->intval = info->voltage_min_design_uv;
+               return 0;
+       case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
+               val->intval = info->voltage_max_design_uv;
+               return 0;
+       case POWER_SUPPLY_PROP_PRECHARGE_CURRENT:
+               val->intval = info->precharge_current_ua;
+               return 0;
+       case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:
+               val->intval = info->charge_term_current_ua;
+               return 0;
+       case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
+               val->intval = info->constant_charge_current_max_ua;
+               return 0;
+       case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
+               val->intval = info->constant_charge_voltage_max_uv;
+               return 0;
+       case POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MIN:
+               val->intval = info->temp_ambient_alert_min;
+               return 0;
+       case POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MAX:
+               val->intval = info->temp_ambient_alert_max;
+               return 0;
+       case POWER_SUPPLY_PROP_TEMP_ALERT_MIN:
+               val->intval = info->temp_alert_min;
+               return 0;
+       case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
+               val->intval = info->temp_alert_max;
+               return 0;
+       case POWER_SUPPLY_PROP_TEMP_MIN:
+               val->intval = info->temp_min;
+               return 0;
+       case POWER_SUPPLY_PROP_TEMP_MAX:
+               val->intval = info->temp_max;
+               return 0;
+       default:
+               return -EINVAL;
        }
 }
 EXPORT_SYMBOL_GPL(power_supply_battery_info_get_prop);
@@ -1255,6 +1255,7 @@ EXPORT_SYMBOL_GPL(power_supply_powers);
 static void power_supply_dev_release(struct device *dev)
 {
        struct power_supply *psy = to_power_supply(dev);
+
        dev_dbg(dev, "%s\n", __func__);
        kfree(psy);
 }
@@ -1636,6 +1637,6 @@ subsys_initcall(power_supply_class_init);
 module_exit(power_supply_class_exit);
 
 MODULE_DESCRIPTION("Universal power supply monitor class");
-MODULE_AUTHOR("Ian Molton <spyro@f2s.com>, "
-             "Szabolcs Gyurko, "
-             "Anton Vorontsov <cbou@mail.ru>");
+MODULE_AUTHOR("Ian Molton <spyro@f2s.com>");
+MODULE_AUTHOR("Szabolcs Gyurko");
+MODULE_AUTHOR("Anton Vorontsov <cbou@mail.ru>");
index ec163d1..a12e2a6 100644 (file)
@@ -282,6 +282,7 @@ struct qcom_battmgr_wireless {
 
 struct qcom_battmgr {
        struct device *dev;
+       struct auxiliary_device *adev;
        struct pmic_glink_client *client;
 
        enum qcom_battmgr_variant variant;
@@ -1293,11 +1294,69 @@ static void qcom_battmgr_enable_worker(struct work_struct *work)
                dev_err(battmgr->dev, "failed to request power notifications\n");
 }
 
+static char *qcom_battmgr_battery[] = { "battery" };
+
+static void qcom_battmgr_register_psy(struct qcom_battmgr *battmgr)
+{
+       struct power_supply_config psy_cfg_supply = {};
+       struct auxiliary_device *adev = battmgr->adev;
+       struct power_supply_config psy_cfg = {};
+       struct device *dev = &adev->dev;
+
+       psy_cfg.drv_data = battmgr;
+       psy_cfg.of_node = adev->dev.of_node;
+
+       psy_cfg_supply.drv_data = battmgr;
+       psy_cfg_supply.of_node = adev->dev.of_node;
+       psy_cfg_supply.supplied_to = qcom_battmgr_battery;
+       psy_cfg_supply.num_supplicants = 1;
+
+       if (battmgr->variant == QCOM_BATTMGR_SC8280XP) {
+               battmgr->bat_psy = devm_power_supply_register(dev, &sc8280xp_bat_psy_desc, &psy_cfg);
+               if (IS_ERR(battmgr->bat_psy))
+                       dev_err(dev, "failed to register battery power supply (%ld)\n",
+                               PTR_ERR(battmgr->bat_psy));
+
+               battmgr->ac_psy = devm_power_supply_register(dev, &sc8280xp_ac_psy_desc, &psy_cfg_supply);
+               if (IS_ERR(battmgr->ac_psy))
+                       dev_err(dev, "failed to register AC power supply (%ld)\n",
+                               PTR_ERR(battmgr->ac_psy));
+
+               battmgr->usb_psy = devm_power_supply_register(dev, &sc8280xp_usb_psy_desc, &psy_cfg_supply);
+               if (IS_ERR(battmgr->usb_psy))
+                       dev_err(dev, "failed to register USB power supply (%ld)\n",
+                               PTR_ERR(battmgr->usb_psy));
+
+               battmgr->wls_psy = devm_power_supply_register(dev, &sc8280xp_wls_psy_desc, &psy_cfg_supply);
+               if (IS_ERR(battmgr->wls_psy))
+                       dev_err(dev, "failed to register wireless charing power supply (%ld)\n",
+                               PTR_ERR(battmgr->wls_psy));
+       } else {
+               battmgr->bat_psy = devm_power_supply_register(dev, &sm8350_bat_psy_desc, &psy_cfg);
+               if (IS_ERR(battmgr->bat_psy))
+                       dev_err(dev, "failed to register battery power supply (%ld)\n",
+                               PTR_ERR(battmgr->bat_psy));
+
+               battmgr->usb_psy = devm_power_supply_register(dev, &sm8350_usb_psy_desc, &psy_cfg_supply);
+               if (IS_ERR(battmgr->usb_psy))
+                       dev_err(dev, "failed to register USB power supply (%ld)\n",
+                               PTR_ERR(battmgr->usb_psy));
+
+               battmgr->wls_psy = devm_power_supply_register(dev, &sm8350_wls_psy_desc, &psy_cfg_supply);
+               if (IS_ERR(battmgr->wls_psy))
+                       dev_err(dev, "failed to register wireless charing power supply (%ld)\n",
+                               PTR_ERR(battmgr->wls_psy));
+       }
+}
+
 static void qcom_battmgr_pdr_notify(void *priv, int state)
 {
        struct qcom_battmgr *battmgr = priv;
 
        if (state == SERVREG_SERVICE_STATE_UP) {
+               if (!battmgr->bat_psy)
+                       qcom_battmgr_register_psy(battmgr);
+
                battmgr->service_up = true;
                schedule_work(&battmgr->enable_work);
        } else {
@@ -1312,13 +1371,9 @@ static const struct of_device_id qcom_battmgr_of_variants[] = {
        {}
 };
 
-static char *qcom_battmgr_battery[] = { "battery" };
-
 static int qcom_battmgr_probe(struct auxiliary_device *adev,
                              const struct auxiliary_device_id *id)
 {
-       struct power_supply_config psy_cfg_supply = {};
-       struct power_supply_config psy_cfg = {};
        const struct of_device_id *match;
        struct qcom_battmgr *battmgr;
        struct device *dev = &adev->dev;
@@ -1328,14 +1383,7 @@ static int qcom_battmgr_probe(struct auxiliary_device *adev,
                return -ENOMEM;
 
        battmgr->dev = dev;
-
-       psy_cfg.drv_data = battmgr;
-       psy_cfg.of_node = adev->dev.of_node;
-
-       psy_cfg_supply.drv_data = battmgr;
-       psy_cfg_supply.of_node = adev->dev.of_node;
-       psy_cfg_supply.supplied_to = qcom_battmgr_battery;
-       psy_cfg_supply.num_supplicants = 1;
+       battmgr->adev = adev;
 
        INIT_WORK(&battmgr->enable_work, qcom_battmgr_enable_worker);
        mutex_init(&battmgr->lock);
@@ -1347,43 +1395,6 @@ static int qcom_battmgr_probe(struct auxiliary_device *adev,
        else
                battmgr->variant = QCOM_BATTMGR_SM8350;
 
-       if (battmgr->variant == QCOM_BATTMGR_SC8280XP) {
-               battmgr->bat_psy = devm_power_supply_register(dev, &sc8280xp_bat_psy_desc, &psy_cfg);
-               if (IS_ERR(battmgr->bat_psy))
-                       return dev_err_probe(dev, PTR_ERR(battmgr->bat_psy),
-                                            "failed to register battery power supply\n");
-
-               battmgr->ac_psy = devm_power_supply_register(dev, &sc8280xp_ac_psy_desc, &psy_cfg_supply);
-               if (IS_ERR(battmgr->ac_psy))
-                       return dev_err_probe(dev, PTR_ERR(battmgr->ac_psy),
-                                            "failed to register AC power supply\n");
-
-               battmgr->usb_psy = devm_power_supply_register(dev, &sc8280xp_usb_psy_desc, &psy_cfg_supply);
-               if (IS_ERR(battmgr->usb_psy))
-                       return dev_err_probe(dev, PTR_ERR(battmgr->usb_psy),
-                                            "failed to register USB power supply\n");
-
-               battmgr->wls_psy = devm_power_supply_register(dev, &sc8280xp_wls_psy_desc, &psy_cfg_supply);
-               if (IS_ERR(battmgr->wls_psy))
-                       return dev_err_probe(dev, PTR_ERR(battmgr->wls_psy),
-                                            "failed to register wireless charing power supply\n");
-       } else {
-               battmgr->bat_psy = devm_power_supply_register(dev, &sm8350_bat_psy_desc, &psy_cfg);
-               if (IS_ERR(battmgr->bat_psy))
-                       return dev_err_probe(dev, PTR_ERR(battmgr->bat_psy),
-                                            "failed to register battery power supply\n");
-
-               battmgr->usb_psy = devm_power_supply_register(dev, &sm8350_usb_psy_desc, &psy_cfg_supply);
-               if (IS_ERR(battmgr->usb_psy))
-                       return dev_err_probe(dev, PTR_ERR(battmgr->usb_psy),
-                                            "failed to register USB power supply\n");
-
-               battmgr->wls_psy = devm_power_supply_register(dev, &sm8350_wls_psy_desc, &psy_cfg_supply);
-               if (IS_ERR(battmgr->wls_psy))
-                       return dev_err_probe(dev, PTR_ERR(battmgr->wls_psy),
-                                            "failed to register wireless charing power supply\n");
-       }
-
        battmgr->client = devm_pmic_glink_register_client(dev,
                                                          PMIC_GLINK_OWNER_BATTMGR,
                                                          qcom_battmgr_callback,
index 8acf63e..9bb7774 100644 (file)
@@ -972,10 +972,14 @@ static int smb2_probe(struct platform_device *pdev)
        supply_config.of_node = pdev->dev.of_node;
 
        desc = devm_kzalloc(chip->dev, sizeof(smb2_psy_desc), GFP_KERNEL);
+       if (!desc)
+               return -ENOMEM;
        memcpy(desc, &smb2_psy_desc, sizeof(smb2_psy_desc));
        desc->name =
                devm_kasprintf(chip->dev, GFP_KERNEL, "%s-charger",
                               (const char *)device_get_match_data(chip->dev));
+       if (!desc->name)
+               return -ENOMEM;
 
        chip->chg_psy =
                devm_power_supply_register(chip->dev, desc, &supply_config);
index 7c8d654..7d8025f 100644 (file)
@@ -83,5 +83,6 @@ struct bq27xxx_device_info {
 void bq27xxx_battery_update(struct bq27xxx_device_info *di);
 int bq27xxx_battery_setup(struct bq27xxx_device_info *di);
 void bq27xxx_battery_teardown(struct bq27xxx_device_info *di);
+extern const struct dev_pm_ops bq27xxx_battery_battery_pm_ops;
 
 #endif