From 246197632902c38202f4a3e8c86db9e6d7217ab9 Mon Sep 17 00:00:00 2001 From: Curtis Porter Date: Tue, 17 Jul 2018 09:36:02 -0500 Subject: [PATCH] drivers: mmi_muc_uart: Add Phone Power Supply Update to trigger usb driver on attach. This will add a new "phone" power supply so that the usb driver or any other driver can register against the "phone" power supply and get notified when it changes state. POWER_SUPPLY_PROP_PRESENT will be used to communicate the attach status. Change-Id: I150740f1be0ddc9ba44c6bc036f87796686ee9c5 Reviewed-on: https://gerrit.mot.com/1210669 SLTApproved: Slta Waiver SME-Granted: SME Approvals Granted Tested-by: Jira Key Reviewed-by: Ryan Lattrel Reviewed-by: Kenneth Kessler Submit-Approved: Jira Key --- drivers/mmi_muc_uart/muc_uart.c | 47 +++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/drivers/mmi_muc_uart/muc_uart.c b/drivers/mmi_muc_uart/muc_uart.c index 4f90ab180134..e8056951f52b 100644 --- a/drivers/mmi_muc_uart/muc_uart.c +++ b/drivers/mmi_muc_uart/muc_uart.c @@ -72,6 +72,8 @@ struct mod_muc_data_t { struct delayed_work idle_work; struct delayed_work attach_work; struct delayed_work write_work; + + struct power_supply *phone_psy; }; /* How long until we move on without an ack */ @@ -187,6 +189,10 @@ static void muc_uart_attach_work(struct work_struct *w) if (mm_data) { gpio_state = gpio_get_value(mm_data->mod_attached_gpio); + + if (atomic_read(&mm_data->mod_attached) == gpio_state) + return; + atomic_set(&mm_data->mod_attached, gpio_state); env = kzalloc(sizeof(*env), GFP_KERNEL); @@ -202,6 +208,9 @@ static void muc_uart_attach_work(struct work_struct *w) KOBJ_CHANGE, env->envp); kfree(env); + + /* also make sure to notify the drivers of the attach/detach */ + power_supply_changed(mm_data->phone_psy); } } @@ -807,16 +816,46 @@ f_end: return error; } +static enum power_supply_property muc_uart_ps_props[] = { + POWER_SUPPLY_PROP_PRESENT, +}; + +static int muc_uart_get_property(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + struct mod_muc_data_t *mm_data = power_supply_get_drvdata(psy); + + switch (psp) { + case POWER_SUPPLY_PROP_PRESENT: + val->intval = atomic_read(&mm_data->mod_attached); + break; + default: + return -EINVAL; + } + return 0; +} + +static const struct power_supply_desc phone_psy_desc = { + .name = "phone", + .type = POWER_SUPPLY_TYPE_USB, + .get_property = muc_uart_get_property, + .properties = muc_uart_ps_props, + .num_properties = ARRAY_SIZE(muc_uart_ps_props), +}; + static int muc_uart_probe(struct platform_device *pdev) { struct device_node *np = (&pdev->dev)->of_node; struct mod_muc_data_t *mm_data; + struct power_supply_config psy_cfg = {}; mm_data = devm_kzalloc(&pdev->dev, sizeof(*mm_data), GFP_KERNEL); if (!mm_data) return -ENOMEM; mm_data->pdev = pdev; platform_set_drvdata(pdev, mm_data); + psy_cfg.drv_data = mm_data; pr_info("muc_uart_probe: probe start\n"); @@ -900,6 +939,14 @@ static int muc_uart_probe(struct platform_device *pdev) pdev)) goto err3; + mm_data->phone_psy = devm_power_supply_register(&pdev->dev, + &phone_psy_desc, + &psy_cfg); + if (IS_ERR(mm_data->phone_psy)) { + dev_err(&pdev->dev, "failed: phone power supply register\n"); + goto err3; + } + kobject_uevent(&pdev->dev.kobj, KOBJ_ADD); schedule_delayed_work(&mm_data->attach_work, msecs_to_jiffies(0));