From 023381a1ddb66cd5ba5b720f1df3ca006b39e2c3 Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Sat, 4 Feb 2023 16:37:55 +0200 Subject: [PATCH] input: touchscreen: touchscreen_mmi: move power supply logic into work [ 9.687403] rcu_note_context_switch+0x33c/0x50c [ 9.687424] __schedule+0xbc/0x714 [ 9.687445] schedule+0xa0/0xe8 [ 9.687468] schedule_timeout+0x94/0x128 [ 9.687489] wait_for_common+0xa4/0x134 [ 9.687510] wait_for_completion_timeout+0x18/0x28 [ 9.687551] battery_chg_write+0x78/0xbc [qti_battery_charger] [ 9.687587] usb_psy_get_prop+0xc4/0x154 [qti_battery_charger] [ 9.687608] power_supply_get_property+0x28/0x50 [ 9.687658] ts_mmi_charger_cb+0x8c/0x168 [touchscreen_mmi] [ 9.687680] atomic_notifier_call_chain+0x54/0x94 [ 9.687700] power_supply_changed_work+0x80/0xcc [ 9.687721] process_one_work+0x1a4/0x3a0 [ 9.687739] worker_thread+0x274/0x4d8 [ 9.687761] kthread+0x13c/0x344 [ 9.687782] ret_from_fork+0x10/0x3 usb_psy_get_prop uses wait_for_completion_timeout which cannot be done from the power supply notifier. Move it to the worker. Change-Id: I3298c605670e963393e2f446cc3dfd99514c3864 --- .../touchscreen_mmi/touchscreen_mmi_notif.c | 63 +++++++++---------- include/linux/touchscreen_mmi.h | 1 + 2 files changed, 30 insertions(+), 34 deletions(-) diff --git a/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_notif.c b/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_notif.c index c1cd005a9f28..5caa363a95bc 100644 --- a/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_notif.c +++ b/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_notif.c @@ -370,6 +370,8 @@ static void ts_mmi_queued_resume(struct ts_mmi_dev *touch_cdev) dev_info(DEV_MMI, "%s: done\n", __func__); } +static inline int ts_mmi_ps_get_state(struct power_supply *psy, bool *present); + static void ts_mmi_worker_func(struct work_struct *w) { struct delayed_work *dw = @@ -399,9 +401,31 @@ static void ts_mmi_worker_func(struct work_struct *w) ts_mmi_queued_power_off(touch_cdev); break; - case TS_MMI_DO_PS: + case TS_MMI_DO_PS: { + struct power_supply *psy; + bool present; + + psy = power_supply_get_by_name("usb"); + if (!psy) + break; + + ret = ts_mmi_ps_get_state(psy, &present); + + power_supply_put(psy); + + if (ret) + break; + + if (touch_cdev->ps_is_present_set && + touch_cdev->ps_is_present == present) + break; + + touch_cdev->ps_is_present = present; + touch_cdev->ps_is_present_set = true; + TRY_TO_CALL(charger_mode, (int)touch_cdev->ps_is_present); break; + } case TS_MMI_DO_REFRESH_RATE: TRY_TO_CALL(refresh_rate, (int)touch_cdev->refresh_rate); @@ -513,31 +537,14 @@ static int ts_mmi_charger_cb(struct notifier_block *self, struct ts_mmi_dev *touch_cdev = container_of( self, struct ts_mmi_dev, ps_notif); struct power_supply *psy = ptr; - int ret; - bool present; if (!((event == PSY_EVENT_PROP_CHANGED) && psy && psy->desc->get_property && psy->desc->name && !strncmp(psy->desc->name, "usb", sizeof("usb")))) return 0; - ret = ts_mmi_ps_get_state(psy, &present); - if (ret) { - dev_err(DEV_MMI, "%s: failed to get usb status: %d\n", - __func__, ret); - return ret; - } - - dev_dbg(DEV_MMI, "%s: event=%lu, usb status: cur=%d, prev=%d\n", - __func__, event, present, touch_cdev->ps_is_present); - - if (touch_cdev->ps_is_present != present) { - touch_cdev->ps_is_present = present; - if (is_touch_active) { - kfifo_put(&touch_cdev->cmd_pipe, TS_MMI_DO_PS); - schedule_delayed_work(&touch_cdev->work, 0); - } - } + kfifo_put(&touch_cdev->cmd_pipe, TS_MMI_DO_PS); + schedule_delayed_work(&touch_cdev->work, 0); return 0; } @@ -648,25 +655,13 @@ int ts_mmi_notifiers_register(struct ts_mmi_dev *touch_cdev) goto FIFO_ALLOC_FAILED; if (touch_cdev->pdata.usb_detection) { - struct power_supply *psy = NULL; - bool present; touch_cdev->ps_notif.notifier_call = ts_mmi_charger_cb; ret = power_supply_reg_notifier(&touch_cdev->ps_notif); if (ret) goto PS_NOTIF_REGISTER_FAILED; - psy = power_supply_get_by_name("usb"); - if (psy) { - ret = ts_mmi_ps_get_state(psy, &present); - if (!ret) { - touch_cdev->ps_is_present = present; - kfifo_put(&touch_cdev->cmd_pipe, TS_MMI_DO_PS); - schedule_delayed_work(&touch_cdev->work, 0); - } - power_supply_put(psy); - dev_info(DEV_MMI, "%s: USB initial status=%d\n", - __func__, touch_cdev->ps_is_present); - } + kfifo_put(&touch_cdev->cmd_pipe, TS_MMI_DO_PS); + schedule_delayed_work(&touch_cdev->work, 0); } /* diff --git a/include/linux/touchscreen_mmi.h b/include/linux/touchscreen_mmi.h index 10089a995905..48ff3f67aabd 100644 --- a/include/linux/touchscreen_mmi.h +++ b/include/linux/touchscreen_mmi.h @@ -519,6 +519,7 @@ struct ts_mmi_dev { struct work_struct ps_notify_work; struct notifier_block ps_notif; + bool ps_is_present_set; bool ps_is_present; struct notifier_block fps_notif;