diff options
-rw-r--r-- | Documentation/devicetree/bindings/power_supply/power_supply_extcon.txt | 11 | ||||
-rw-r--r-- | drivers/power/power_supply_extcon.c | 51 |
2 files changed, 57 insertions, 5 deletions
diff --git a/Documentation/devicetree/bindings/power_supply/power_supply_extcon.txt b/Documentation/devicetree/bindings/power_supply/power_supply_extcon.txt new file mode 100644 index 000000000000..fd4a1a476ce9 --- /dev/null +++ b/Documentation/devicetree/bindings/power_supply/power_supply_extcon.txt @@ -0,0 +1,11 @@ +power_supply_extcon +~~~~~~~~~~~~~~~~ +Required properties : + - compatible : Should contain "power-supply-extcon". + - power-supply,extcon-dev: Extcon device name. + +Example: + psy_extcon { + compatible = "power-supply-extcon"; + power-supply,extcon-dev = "udc-extcon"; + }; diff --git a/drivers/power/power_supply_extcon.c b/drivers/power/power_supply_extcon.c index 44e19d67df4a..1236738968b0 100644 --- a/drivers/power/power_supply_extcon.c +++ b/drivers/power/power_supply_extcon.c @@ -23,6 +23,8 @@ #include <linux/err.h> #include <linux/err.h> #include <linux/module.h> +#include <linux/of.h> +#include <linux/of_device.h> #include <linux/platform_device.h> #include <linux/power_supply.h> #include <linux/power/power_supply_extcon.h> @@ -185,6 +187,25 @@ static int psy_extcon_extcon_notifier(struct notifier_block *self, return NOTIFY_DONE; } +static struct power_supply_extcon_plat_data *psy_extcon_get_dt_pdata( + struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct power_supply_extcon_plat_data *pdata; + char const *pstr; + int ret; + + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return ERR_PTR(-ENOMEM); + + ret = of_property_read_string(np, "power-supply,extcon-dev", &pstr); + if (!ret) + pdata->extcon_name = pstr; + + return pdata; +} + static int psy_extcon_probe(struct platform_device *pdev) { int ret = 0; @@ -192,6 +213,14 @@ static int psy_extcon_probe(struct platform_device *pdev) struct power_supply_extcon *psy_extcon; struct power_supply_extcon_plat_data *pdata = pdev->dev.platform_data; + if (!pdata && pdev->dev.of_node) { + pdata = psy_extcon_get_dt_pdata(pdev); + if (IS_ERR(pdata)) { + ret = PTR_ERR(pdata); + pdata = NULL; + } + } + if (!pdata) { dev_err(&pdev->dev, "No platform data, exiting..\n"); return -ENODEV; @@ -206,6 +235,8 @@ static int psy_extcon_probe(struct platform_device *pdev) psy_extcon->dev = &pdev->dev; dev_set_drvdata(&pdev->dev, psy_extcon); + dev_info(psy_extcon->dev, "Extcon name %s\n", pdata->extcon_name); + psy_extcon->ac.name = "ac"; psy_extcon->ac.type = POWER_SUPPLY_TYPE_MAINS; psy_extcon->ac.get_property = power_supply_extcon_get_property; @@ -247,13 +278,17 @@ static int psy_extcon_probe(struct platform_device *pdev) pdata->extcon_name, cable->name, &cable->nb); if (ret < 0) - dev_err(psy_extcon->dev, "Cannot register for cable: %s\n", - cable->name); + dev_err(psy_extcon->dev, + "Cable %s registration failed: %d\n", + cable->name, ret); } psy_extcon->edev = extcon_get_extcon_dev(pdata->extcon_name); - if (!psy_extcon->edev) - goto econ_err; + if (!psy_extcon->edev) { + dev_err(psy_extcon->dev, "No extcon device with %s\n", + pdata->extcon_name); + goto econ_err; + } power_supply_extcon_attach_cable(psy_extcon, psy_extcon->edev); dev_info(&pdev->dev, "%s() get success\n", __func__); @@ -275,14 +310,20 @@ static int psy_extcon_remove(struct platform_device *pdev) return 0; } +static struct of_device_id power_supply_extcon_of_match[] = { + { .compatible = "power-supply-extcon", }, + {}, +}; +MODULE_DEVICE_TABLE(of, power_supply_extcon_of_match); + static struct platform_driver power_supply_extcon_driver = { .driver = { .name = "power-supply-extcon", .owner = THIS_MODULE, + .of_match_table = power_supply_extcon_of_match, }, .probe = psy_extcon_probe, .remove = psy_extcon_remove, - }; static int __init psy_extcon_init(void) |