]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
power: twl4030_charger: find associated phy by more reliable means.
authorNeilBrown <neilb@suse.de>
Sun, 22 Mar 2015 22:52:48 +0000 (09:52 +1100)
committerFelipe Balbi <balbi@ti.com>
Tue, 26 May 2015 15:44:06 +0000 (10:44 -0500)
twl4030_charger currently finds the associated phy
using usb_get_phy() which will return the first USB2 phy.
If your platform has multiple such phys (as mine does),
this is not reliable (and reliably fails on the GTA04).

Change to use devm_usb_get_phy_by_node(), having found the
node by looking for an appropriately named sibling in
device-tree.

This makes usb-charging dependent on correct device-tree
configuration.

Acked-By: Sebastian Reichel <sre@kernel.org>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: NeilBrown <neilb@suse.de>
Signed-off-by: Felipe Balbi <balbi@ti.com>
Documentation/devicetree/bindings/power/twl-charger.txt
Documentation/devicetree/bindings/usb/twlxxxx-usb.txt
drivers/power/twl4030_charger.c

index d5c706216df55ddf9f07343c5c534618e6c036e5..3b4ea1b73b38293619c11c5483ef583229317611 100644 (file)
@@ -1,5 +1,15 @@
 TWL BCI (Battery Charger Interface)
 
+The battery charger needs to interact with the USB phy in order
+to know when charging is permissible, and when there is a connection
+or disconnection.
+
+The choice of phy cannot be configured at a hardware level, so there
+is no value in explicit configuration in device-tree.  Rather
+if there is a sibling of the BCI node which is compatible with
+"ti,twl4030-usb", then that is used to determine when and how
+use USB power for charging.
+
 Required properties:
 - compatible:
   - "ti,twl4030-bci"
index 0aee0ad3f035b8fcb80c78a976e10c503e87943a..17327a296110a49814cc7b725a0fb111a2ae55da 100644 (file)
@@ -30,6 +30,9 @@ TWL4030 USB PHY AND COMPARATOR
  - usb_mode : The mode used by the phy to connect to the controller. "1"
    specifies "ULPI" mode and "2" specifies "CEA2011_3PIN" mode.
 
+If a sibling node is compatible "ti,twl4030-bci", then it will find
+this device and query it for USB power status.
+
 twl4030-usb {
        compatible = "ti,twl4030-usb";
        interrupts = < 10 4 >;
index 02a522cb775377177760b06f5bc40bed6506b5bf..022b8910e443510fdf1320891af7566e1db24b6f 100644 (file)
@@ -638,10 +638,15 @@ static int __init twl4030_bci_probe(struct platform_device *pdev)
 
        INIT_WORK(&bci->work, twl4030_bci_usb_work);
 
-       bci->transceiver = usb_get_phy(USB_PHY_TYPE_USB2);
-       if (!IS_ERR_OR_NULL(bci->transceiver)) {
-               bci->usb_nb.notifier_call = twl4030_bci_usb_ncb;
-               usb_register_notifier(bci->transceiver, &bci->usb_nb);
+       bci->usb_nb.notifier_call = twl4030_bci_usb_ncb;
+       if (bci->dev->of_node) {
+               struct device_node *phynode;
+
+               phynode = of_find_compatible_node(bci->dev->of_node->parent,
+                                                 NULL, "ti,twl4030-usb");
+               if (phynode)
+                       bci->transceiver = devm_usb_get_phy_by_node(
+                               bci->dev, phynode, &bci->usb_nb);
        }
 
        /* Enable interrupts now. */
@@ -671,10 +676,6 @@ static int __init twl4030_bci_probe(struct platform_device *pdev)
        return 0;
 
 fail_unmask_interrupts:
-       if (!IS_ERR_OR_NULL(bci->transceiver)) {
-               usb_unregister_notifier(bci->transceiver, &bci->usb_nb);
-               usb_put_phy(bci->transceiver);
-       }
        free_irq(bci->irq_bci, bci);
 fail_bci_irq:
        free_irq(bci->irq_chg, bci);
@@ -703,10 +704,6 @@ static int __exit twl4030_bci_remove(struct platform_device *pdev)
        twl_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff,
                         TWL4030_INTERRUPTS_BCIIMR2A);
 
-       if (!IS_ERR_OR_NULL(bci->transceiver)) {
-               usb_unregister_notifier(bci->transceiver, &bci->usb_nb);
-               usb_put_phy(bci->transceiver);
-       }
        free_irq(bci->irq_bci, bci);
        free_irq(bci->irq_chg, bci);
        power_supply_unregister(bci->usb);