From 92d5f8766221d70da003c562d454a8ae99a722d3 Mon Sep 17 00:00:00 2001 From: Midas Chien Date: Wed, 22 Apr 2020 16:29:32 +0800 Subject: [PATCH 1/4] techpack: drm/msm/sde: add sysfs node for trigger wake up early Add sysfs node on crtc to trigger sde wake up early. The command to trigger wake up early give in shell: echo 1 > /sys/class/drm/sde-crtc-*/early_wakeup Bug: 150196517 Test: trigger wake up and switch display power state Test: testInflatingEmojiListViewFling Test: testBrowseContentScroll Change-Id: I96e6ad73e83e8a9e3e5e65e064c92f8e6a6d63f8 Signed-off-by: Midas Chien --- techpack/display/msm/sde/sde_crtc.c | 79 ++++++++++++++++++++++++++ techpack/display/msm/sde/sde_crtc.h | 2 + techpack/display/msm/sde/sde_encoder.c | 24 ++++++++ techpack/display/msm/sde/sde_encoder.h | 6 ++ techpack/display/msm/sde/sde_kms.c | 23 ++++++++ techpack/display/msm/sde/sde_kms.h | 9 +++ 6 files changed, 143 insertions(+) diff --git a/techpack/display/msm/sde/sde_crtc.c b/techpack/display/msm/sde/sde_crtc.c index 602476ba8a4a..12f355e2f017 100644 --- a/techpack/display/msm/sde/sde_crtc.c +++ b/techpack/display/msm/sde/sde_crtc.c @@ -215,6 +215,47 @@ static int _sde_debugfs_fps_status(struct inode *inode, struct file *file) } #endif +static ssize_t early_wakeup_store(struct device *device, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct drm_crtc *crtc; + struct sde_crtc *sde_crtc; + struct msm_drm_private *priv; + u32 crtc_id; + bool trigger; + + if (!device || !buf || !count) { + SDE_ERROR("invalid input param(s)\n"); + return -EINVAL; + } + + if (kstrtobool(buf, &trigger) < 0) + return -EINVAL; + + if (!trigger) + return count; + + crtc = dev_get_drvdata(device); + if (!crtc || !crtc->dev || !crtc->dev->dev_private) { + SDE_ERROR("invalid crtc\n"); + return -EINVAL; + } + + sde_crtc = to_sde_crtc(crtc); + priv = crtc->dev->dev_private; + + crtc_id = drm_crtc_index(crtc); + if (crtc_id >= ARRAY_SIZE(priv->disp_thread)) { + SDE_ERROR("invalid crtc index[%d]\n", crtc_id); + return -EINVAL; + } + + kthread_queue_work(&priv->disp_thread[crtc_id].worker, + &sde_crtc->early_wakeup_work); + + return count; +} + static ssize_t fps_periodicity_ms_store(struct device *device, struct device_attribute *attr, const char *buf, size_t count) { @@ -402,12 +443,14 @@ static DEVICE_ATTR_RO(vsync_event); static DEVICE_ATTR_RO(measured_fps); static DEVICE_ATTR_RW(fps_periodicity_ms); static DEVICE_ATTR_RO(retire_frame_event); +static DEVICE_ATTR_WO(early_wakeup); static struct attribute *sde_crtc_dev_attrs[] = { &dev_attr_vsync_event.attr, &dev_attr_measured_fps.attr, &dev_attr_fps_periodicity_ms.attr, &dev_attr_retire_frame_event.attr, + &dev_attr_early_wakeup.attr, NULL }; @@ -6262,6 +6305,40 @@ static void __sde_crtc_idle_notify_work(struct kthread_work *work) } } +/* + * __sde_crtc_early_wakeup_work - trigger early wakeup from user space + */ +static void __sde_crtc_early_wakeup_work(struct kthread_work *work) +{ + struct sde_crtc *sde_crtc = container_of(work, struct sde_crtc, + early_wakeup_work); + struct drm_crtc *crtc; + struct drm_device *dev; + struct msm_drm_private *priv; + struct sde_kms *sde_kms; + + if (!sde_crtc) { + SDE_ERROR("invalid sde crtc\n"); + return; + } + + if (!sde_crtc->enabled) { + SDE_INFO("sde crtc is not enabled\n"); + return; + } + + crtc = &sde_crtc->base; + dev = crtc->dev; + if (!dev) { + SDE_ERROR("invalid drm device\n"); + return; + } + + priv = dev->dev_private; + sde_kms = to_sde_kms(priv->kms); + sde_kms_trigger_early_wakeup(sde_kms, crtc); +} + /* initialize crtc */ struct drm_crtc *sde_crtc_init(struct drm_device *dev, struct drm_plane *plane) { @@ -6353,6 +6430,8 @@ struct drm_crtc *sde_crtc_init(struct drm_device *dev, struct drm_plane *plane) kthread_init_delayed_work(&sde_crtc->idle_notify_work, __sde_crtc_idle_notify_work); + kthread_init_work(&sde_crtc->early_wakeup_work, + __sde_crtc_early_wakeup_work); SDE_DEBUG("crtc=%d new_llcc=%d, old_llcc=%d\n", crtc->base.id, diff --git a/techpack/display/msm/sde/sde_crtc.h b/techpack/display/msm/sde/sde_crtc.h index bd16cd3da6fe..9d0526888922 100644 --- a/techpack/display/msm/sde/sde_crtc.h +++ b/techpack/display/msm/sde/sde_crtc.h @@ -272,6 +272,7 @@ struct sde_crtc_misr_info { * @misr_frame_count : misr frame count provided by client * @misr_data : store misr data before turning off the clocks. * @idle_notify_work: delayed worker to notify idle timeout to user space + * @early_wakeup_work: work to trigger early wakeup * @power_event : registered power event handle * @cur_perf : current performance committed to clock/bandwidth driver * @plane_mask_old: keeps track of the planes used in the previous commit @@ -349,6 +350,7 @@ struct sde_crtc { bool misr_enable_debugfs; u32 misr_frame_count; struct kthread_delayed_work idle_notify_work; + struct kthread_work early_wakeup_work; struct sde_power_event *power_event; diff --git a/techpack/display/msm/sde/sde_encoder.c b/techpack/display/msm/sde/sde_encoder.c index cbb8b5b87bbc..c7b5cb0f6777 100644 --- a/techpack/display/msm/sde/sde_encoder.c +++ b/techpack/display/msm/sde/sde_encoder.c @@ -6320,3 +6320,27 @@ void sde_encoder_recovery_events_handler(struct drm_encoder *encoder, sde_enc = to_sde_encoder_virt(encoder); sde_enc->recovery_events_enabled = enabled; } + +void sde_encoder_trigger_early_wakeup(struct drm_encoder *drm_enc) +{ + struct sde_encoder_virt *sde_enc = NULL; + struct msm_drm_private *priv = NULL; + + priv = drm_enc->dev->dev_private; + sde_enc = to_sde_encoder_virt(drm_enc); + if (!sde_enc->crtc || (sde_enc->crtc->index + >= ARRAY_SIZE(priv->disp_thread))) { + SDE_DEBUG_ENC(sde_enc, + "invalid cached CRTC: %d or crtc index: %d\n", + sde_enc->crtc == NULL, + sde_enc->crtc ? sde_enc->crtc->index : -EINVAL); + return; + } + + if (sde_enc->rc_state == SDE_ENC_RC_STATE_IDLE) { + SDE_ATRACE_BEGIN("sde_encoder_resource_control"); + sde_encoder_resource_control(drm_enc, + SDE_ENC_RC_EVENT_EARLY_WAKEUP); + SDE_ATRACE_END("sde_encoder_resource_control"); + } +} diff --git a/techpack/display/msm/sde/sde_encoder.h b/techpack/display/msm/sde/sde_encoder.h index ebee140da628..b70cfd590956 100644 --- a/techpack/display/msm/sde/sde_encoder.h +++ b/techpack/display/msm/sde/sde_encoder.h @@ -399,4 +399,10 @@ static inline struct sde_kms *sde_encoder_get_kms(struct drm_encoder *drm_enc) return to_sde_kms(priv->kms); } +/** + * sde_encoder_trigger_early_wakeup - trigger early wake up + * @drm_enc: Pointer to drm encoder structure + */ +void sde_encoder_trigger_early_wakeup(struct drm_encoder *drm_enc); + #endif /* __SDE_ENCODER_H__ */ diff --git a/techpack/display/msm/sde/sde_kms.c b/techpack/display/msm/sde/sde_kms.c index ba5b2bc38fdb..46d94d30fff1 100644 --- a/techpack/display/msm/sde/sde_kms.c +++ b/techpack/display/msm/sde/sde_kms.c @@ -3933,3 +3933,26 @@ int sde_kms_handle_recovery(struct drm_encoder *encoder) SDE_EVT32(DRMID(encoder), MSM_ENC_ACTIVE_REGION); return sde_encoder_wait_for_event(encoder, MSM_ENC_ACTIVE_REGION); } + +void sde_kms_trigger_early_wakeup(struct sde_kms *sde_kms, + struct drm_crtc *crtc) +{ + struct msm_drm_private *priv; + struct drm_encoder *drm_enc; + + if (!sde_kms || !crtc) { + SDE_ERROR("invalid argument sde_kms %pK crtc %pK\n", + sde_kms, crtc); + return; + } + + priv = sde_kms->dev->dev_private; + + SDE_ATRACE_BEGIN("sde_kms_trigger_early_wakeup"); + drm_for_each_encoder_mask(drm_enc, crtc->dev, crtc->state->encoder_mask) + sde_encoder_trigger_early_wakeup(drm_enc); + + if (sde_kms->first_kickoff) + sde_power_scale_reg_bus(&priv->phandle, VOTE_INDEX_HIGH, false); + SDE_ATRACE_END("sde_kms_trigger_early_wakeup"); +} diff --git a/techpack/display/msm/sde/sde_kms.h b/techpack/display/msm/sde/sde_kms.h index 6882cdfdb00f..76a3dccd96b0 100644 --- a/techpack/display/msm/sde/sde_kms.h +++ b/techpack/display/msm/sde/sde_kms.h @@ -671,4 +671,13 @@ int sde_kms_handle_recovery(struct drm_encoder *encoder); */ void sde_kms_update_pm_qos_irq_request(struct sde_kms *sde_kms, bool enable, bool skip_lock); + +/** + * sde_kms_trigger_early_wakeup - trigger early wake up + * @sde_kms: pointer to sde_kms structure + * @crtc: pointer to drm_crtc structure + */ +void sde_kms_trigger_early_wakeup(struct sde_kms *sde_kms, + struct drm_crtc *crtc); + #endif /* __sde_kms_H__ */ From d12e9eb2dec43ed7d705aef545e92700271236b9 Mon Sep 17 00:00:00 2001 From: fadlyas07 Date: Sun, 10 May 2026 04:10:20 +0000 Subject: [PATCH 2/4] fixup! BACKPORT: kbuild: check the minimum assembler version in Kconfig Since minimum assembler version checking is not required in 5.10, it should not be required in 4.19 either. Change-Id: I333454a3dffb4798295adf9b3038ebc9acda948e --- scripts/as-version.sh | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/scripts/as-version.sh b/scripts/as-version.sh index 1a21495e9ff0..532270bd4b7e 100755 --- a/scripts/as-version.sh +++ b/scripts/as-version.sh @@ -51,12 +51,9 @@ set -- $(LC_ALL=C "$@" -Wa,--version -c -x assembler /dev/null -o /dev/null 2>/d IFS=' ' set -- $1 -min_tool_version=$(dirname $0)/min-tool-version.sh - if [ "$1" = GNU -a "$2" = assembler ]; then shift $(($# - 1)) version=$1 - min_version=$($min_tool_version binutils) name=GNU else echo "$orig_args: unknown assembler invoked" >&2 @@ -68,15 +65,5 @@ fi version=${version%-*} cversion=$(get_canonical_version $version) -min_cversion=$(get_canonical_version $min_version) - -if [ "$cversion" -lt "$min_cversion" ]; then - echo >&2 "***" - echo >&2 "*** Assembler is too old." - echo >&2 "*** Your $name assembler version: $version" - echo >&2 "*** Minimum $name assembler version: $min_version" - echo >&2 "***" - exit 1 -fi echo $name $cversion From 8785db2046a0b977608fab3c5bce152d850f254b Mon Sep 17 00:00:00 2001 From: Kamal Agrawal Date: Tue, 13 Apr 2021 22:44:05 +0530 Subject: [PATCH 3/4] msm: kgsl: Fix possible NULL pointer dereference Return value of alloc_workqueue is not checked and as a result, a possible NULL pointer dereference could occur. Change-Id: I608d12601227f125625a97c1d0da37e3386cf306 Signed-off-by: Kamal Agrawal --- drivers/gpu/msm/kgsl.c | 44 ++++++++++++++++++++++++++++++--- drivers/gpu/msm/kgsl_pwrscale.c | 17 ++++++++++--- 2 files changed, 54 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index 51803d98b175..1b46bb3504a9 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -5334,6 +5334,15 @@ int kgsl_device_platform_probe(struct kgsl_device *device) if (status) goto error; + device->events_wq = alloc_workqueue("kgsl-events", + WQ_UNBOUND | WQ_MEM_RECLAIM | WQ_SYSFS | WQ_HIGHPRI, 0); + + if (!device->events_wq) { + dev_err(device->dev, "Failed to allocate events workqueue\n"); + status = -ENOMEM; + goto error_pwrctrl_close; + } + if (!devm_request_mem_region(device->dev, device->reg_phys, device->reg_len, device->name)) { dev_err(device->dev, "request_mem_region failed\n"); @@ -5422,9 +5431,6 @@ int kgsl_device_platform_probe(struct kgsl_device *device) PM_QOS_DEFAULT_VALUE); } - device->events_wq = alloc_workqueue("kgsl-events", - WQ_UNBOUND | WQ_MEM_RECLAIM | WQ_SYSFS | WQ_HIGHPRI, 0); - /* Initialize the snapshot engine */ kgsl_device_snapshot_init(device); @@ -5436,6 +5442,11 @@ int kgsl_device_platform_probe(struct kgsl_device *device) error_close_mmu: kgsl_mmu_close(device); error_pwrctrl_close: + if (device->events_wq) { + destroy_workqueue(device->events_wq); + device->events_wq = NULL; + } + kgsl_pwrctrl_close(device); error: kgsl_device_debugfs_close(device); @@ -5446,7 +5457,10 @@ EXPORT_SYMBOL(kgsl_device_platform_probe); void kgsl_device_platform_remove(struct kgsl_device *device) { - destroy_workqueue(device->events_wq); + if (device->events_wq) { + destroy_workqueue(device->events_wq); + device->events_wq = NULL; + } kfree(device->dev->dma_parms); device->dev->dma_parms = NULL; @@ -5481,6 +5495,16 @@ _flush_mem_workqueue(struct work_struct *work) static void kgsl_core_exit(void) { + if (kgsl_driver.workqueue) { + destroy_workqueue(kgsl_driver.workqueue); + kgsl_driver.workqueue = NULL; + } + + if (kgsl_driver.mem_workqueue) { + destroy_workqueue(kgsl_driver.mem_workqueue); + kgsl_driver.mem_workqueue = NULL; + } + kgsl_events_exit(); kgsl_core_debugfs_close(); @@ -5579,9 +5603,21 @@ static int __init kgsl_core_init(void) kgsl_driver.workqueue = alloc_workqueue("kgsl-workqueue", WQ_UNBOUND | WQ_MEM_RECLAIM | WQ_SYSFS, 0); + if (!kgsl_driver.workqueue) { + pr_err("kgsl: Failed to allocate kgsl workqueue\n"); + result = -ENOMEM; + goto err; + } + kgsl_driver.mem_workqueue = alloc_workqueue("kgsl-mementry", WQ_UNBOUND | WQ_MEM_RECLAIM, 0); + if (!kgsl_driver.mem_workqueue) { + pr_err("kgsl: Failed to allocate mem workqueue\n"); + result = -ENOMEM; + goto err; + } + INIT_WORK(&kgsl_driver.mem_work, _flush_mem_workqueue); kthread_init_worker(&kgsl_driver.worker); diff --git a/drivers/gpu/msm/kgsl_pwrscale.c b/drivers/gpu/msm/kgsl_pwrscale.c index 892e9e69f1d0..3ea7d28f39c1 100644 --- a/drivers/gpu/msm/kgsl_pwrscale.c +++ b/drivers/gpu/msm/kgsl_pwrscale.c @@ -1028,6 +1028,13 @@ int kgsl_pwrscale_init(struct device *dev, const char *governor) } else data->bus.num = 0; + pwrscale->devfreq_wq = create_freezable_workqueue("kgsl_devfreq_wq"); + if (!pwrscale->devfreq_wq) { + dev_err(device->dev, "Failed to allocate kgsl devfreq workqueue\n"); + device->pwrscale.enabled = false; + return -ENOMEM; + } + devfreq = devfreq_add_device(dev, &pwrscale->gpu_profile.profile, governor, pwrscale->gpu_profile.private_data); if (IS_ERR(devfreq)) { @@ -1074,7 +1081,6 @@ int kgsl_pwrscale_init(struct device *dev, const char *governor) ret = sysfs_create_link(&device->dev->kobj, &devfreq->dev.kobj, "devfreq"); - pwrscale->devfreq_wq = create_freezable_workqueue("kgsl_devfreq_wq"); INIT_WORK(&pwrscale->devfreq_suspend_ws, do_devfreq_suspend); INIT_WORK(&pwrscale->devfreq_resume_ws, do_devfreq_resume); INIT_WORK(&pwrscale->devfreq_notify_ws, do_devfreq_notify); @@ -1125,8 +1131,13 @@ void kgsl_pwrscale_close(struct kgsl_device *device) devfreq_cooling_unregister(pwrscale->cooling_dev); kgsl_pwrscale_midframe_timer_cancel(device); - flush_workqueue(pwrscale->devfreq_wq); - destroy_workqueue(pwrscale->devfreq_wq); + + if (pwrscale->devfreq_wq) { + flush_workqueue(pwrscale->devfreq_wq); + destroy_workqueue(pwrscale->devfreq_wq); + pwrscale->devfreq_wq = NULL; + } + devfreq_remove_device(device->pwrscale.devfreqptr); kfree(kgsl_midframe); kgsl_midframe = NULL; From b25c4f30abff96848aed3ec4448cd7384c252a1f Mon Sep 17 00:00:00 2001 From: Pankaj Gupta Date: Fri, 6 Dec 2024 13:06:02 +0530 Subject: [PATCH 4/4] msm: kgsl: Use kthread instead of workqueue for event work Currently a workqueue is being used to process the event work. In certain scenarios like when most of CPU cores are busy, there can be a significant delay between the actual timestamp retire event and when the work is processed by the events workqueue as workqueues cannot have RT priority. Hence use kthread instead of workqueue for event work. Change-Id: Ib1ec7fa1ec3a133d03104c9a029dcc4c06180609 Signed-off-by: Puranam V G Tejaswi Signed-off-by: Pankaj Gupta --- drivers/gpu/msm/kgsl.c | 26 +++++++++++--------------- drivers/gpu/msm/kgsl.h | 4 ++-- drivers/gpu/msm/kgsl_device.h | 4 ++-- drivers/gpu/msm/kgsl_events.c | 15 ++++++++------- 4 files changed, 23 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index 1b46bb3504a9..6242852b3880 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -609,11 +609,11 @@ int kgsl_context_init(struct kgsl_device_private *dev_priv, if (id == -ENOSPC) { /* * Before declaring that there are no contexts left try - * flushing the event workqueue just in case there are + * flushing the event worker just in case there are * detached contexts waiting to finish */ - flush_workqueue(device->events_wq); + kthread_flush_worker(device->events_worker); id = _kgsl_get_context_id(device); } @@ -5334,15 +5334,16 @@ int kgsl_device_platform_probe(struct kgsl_device *device) if (status) goto error; - device->events_wq = alloc_workqueue("kgsl-events", - WQ_UNBOUND | WQ_MEM_RECLAIM | WQ_SYSFS | WQ_HIGHPRI, 0); + device->events_worker = kthread_create_worker(0, "kgsl-events"); - if (!device->events_wq) { - dev_err(device->dev, "Failed to allocate events workqueue\n"); - status = -ENOMEM; + if (IS_ERR(device->events_worker)) { + status = PTR_ERR(device->events_worker); + dev_err(device->dev, "Failed to create events worker ret=%d\n", status); goto error_pwrctrl_close; } + sched_set_fifo(device->events_worker->task); + if (!devm_request_mem_region(device->dev, device->reg_phys, device->reg_len, device->name)) { dev_err(device->dev, "request_mem_region failed\n"); @@ -5442,10 +5443,8 @@ int kgsl_device_platform_probe(struct kgsl_device *device) error_close_mmu: kgsl_mmu_close(device); error_pwrctrl_close: - if (device->events_wq) { - destroy_workqueue(device->events_wq); - device->events_wq = NULL; - } + if (!IS_ERR(device->events_worker)) + kthread_destroy_worker(device->events_worker); kgsl_pwrctrl_close(device); error: @@ -5457,10 +5456,7 @@ EXPORT_SYMBOL(kgsl_device_platform_probe); void kgsl_device_platform_remove(struct kgsl_device *device) { - if (device->events_wq) { - destroy_workqueue(device->events_wq); - device->events_wq = NULL; - } + kthread_destroy_worker(device->events_worker); kfree(device->dev->dma_parms); device->dev->dma_parms = NULL; diff --git a/drivers/gpu/msm/kgsl.h b/drivers/gpu/msm/kgsl.h index 0dc906aa3d9e..95703d31a659 100644 --- a/drivers/gpu/msm/kgsl.h +++ b/drivers/gpu/msm/kgsl.h @@ -316,7 +316,7 @@ typedef void (*kgsl_event_func)(struct kgsl_device *, struct kgsl_event_group *, * @priv: Private data passed to the callback function * @node: List node for the kgsl_event_group list * @created: Jiffies when the event was created - * @work: Work struct for dispatching the callback + * @work: kthread_work struct for dispatching the callback * @result: KGSL event result type to pass to the callback * group: The event group this event belongs to */ @@ -328,7 +328,7 @@ struct kgsl_event { void *priv; struct list_head node; unsigned int created; - struct work_struct work; + struct kthread_work work; int result; struct kgsl_event_group *group; }; diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h index 55008e288e72..9137fc6138ed 100644 --- a/drivers/gpu/msm/kgsl_device.h +++ b/drivers/gpu/msm/kgsl_device.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2002,2007-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef __KGSL_DEVICE_H #define __KGSL_DEVICE_H @@ -311,7 +311,7 @@ struct kgsl_device { struct kgsl_pwrscale pwrscale; int reset_counter; /* Track how many GPU core resets have occurred */ - struct workqueue_struct *events_wq; + struct kthread_worker *events_worker; struct device *busmondev; /* pseudo dev for GPU BW voting governor */ diff --git a/drivers/gpu/msm/kgsl_events.c b/drivers/gpu/msm/kgsl_events.c index b2c07c38e0d5..a6705d752299 100644 --- a/drivers/gpu/msm/kgsl_events.c +++ b/drivers/gpu/msm/kgsl_events.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2011-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2022, 2024 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -21,17 +22,17 @@ static inline void signal_event(struct kgsl_device *device, { list_del(&event->node); event->result = result; - queue_work(device->events_wq, &event->work); + kthread_queue_work(device->events_worker, &event->work); } /** * _kgsl_event_worker() - Work handler for processing GPU event callbacks - * @work: Pointer to the work_struct for the event + * @work: Pointer to the kthread_work for the event * - * Each event callback has its own work struct and is run on a event specific - * workqeuue. This is the worker that queues up the event callback function. + * Each event callback has its own kthread_work struct and is run on a event specific + * worker thread. This is the worker that queues up the event callback function. */ -static void _kgsl_event_worker(struct work_struct *work) +static void _kgsl_event_worker(struct kthread_work *work) { struct kgsl_event *event = container_of(work, struct kgsl_event, work); int id = KGSL_CONTEXT_ID(event->context); @@ -273,7 +274,7 @@ int kgsl_add_event(struct kgsl_device *device, struct kgsl_event_group *group, event->created = jiffies; event->group = group; - INIT_WORK(&event->work, _kgsl_event_worker); + kthread_init_work(&event->work, _kgsl_event_worker); trace_kgsl_register_event(KGSL_CONTEXT_ID(context), timestamp, func); @@ -288,7 +289,7 @@ int kgsl_add_event(struct kgsl_device *device, struct kgsl_event_group *group, if (timestamp_cmp(retired, timestamp) >= 0) { event->result = KGSL_EVENT_RETIRED; - queue_work(device->events_wq, &event->work); + kthread_queue_work(device->events_worker, &event->work); spin_unlock(&group->lock); return 0; }