1*b8ca4380SGeorge Abraham P // SPDX-License-Identifier: GPL-2.0-only 2*b8ca4380SGeorge Abraham P /* Copyright(c) 2023 Intel Corporation */ 3*b8ca4380SGeorge Abraham P 4*b8ca4380SGeorge Abraham P #include <linux/container_of.h> 5*b8ca4380SGeorge Abraham P #include <linux/dev_printk.h> 6*b8ca4380SGeorge Abraham P #include <linux/export.h> 7*b8ca4380SGeorge Abraham P #include <linux/jiffies.h> 8*b8ca4380SGeorge Abraham P #include <linux/ktime.h> 9*b8ca4380SGeorge Abraham P #include <linux/slab.h> 10*b8ca4380SGeorge Abraham P #include <linux/workqueue.h> 11*b8ca4380SGeorge Abraham P 12*b8ca4380SGeorge Abraham P #include "adf_admin.h" 13*b8ca4380SGeorge Abraham P #include "adf_accel_devices.h" 14*b8ca4380SGeorge Abraham P #include "adf_common_drv.h" 15*b8ca4380SGeorge Abraham P #include "adf_timer.h" 16*b8ca4380SGeorge Abraham P 17*b8ca4380SGeorge Abraham P #define ADF_DEFAULT_TIMER_PERIOD_MS 200 18*b8ca4380SGeorge Abraham P 19*b8ca4380SGeorge Abraham P /* This periodic update is used to trigger HB, RL & TL fw events */ 20*b8ca4380SGeorge Abraham P static void work_handler(struct work_struct *work) 21*b8ca4380SGeorge Abraham P { 22*b8ca4380SGeorge Abraham P struct adf_accel_dev *accel_dev; 23*b8ca4380SGeorge Abraham P struct adf_timer *timer_ctx; 24*b8ca4380SGeorge Abraham P u32 time_periods; 25*b8ca4380SGeorge Abraham P 26*b8ca4380SGeorge Abraham P timer_ctx = container_of(to_delayed_work(work), struct adf_timer, work_ctx); 27*b8ca4380SGeorge Abraham P accel_dev = timer_ctx->accel_dev; 28*b8ca4380SGeorge Abraham P 29*b8ca4380SGeorge Abraham P adf_misc_wq_queue_delayed_work(&timer_ctx->work_ctx, 30*b8ca4380SGeorge Abraham P msecs_to_jiffies(ADF_DEFAULT_TIMER_PERIOD_MS)); 31*b8ca4380SGeorge Abraham P 32*b8ca4380SGeorge Abraham P time_periods = div_u64(ktime_ms_delta(ktime_get_real(), timer_ctx->initial_ktime), 33*b8ca4380SGeorge Abraham P ADF_DEFAULT_TIMER_PERIOD_MS); 34*b8ca4380SGeorge Abraham P 35*b8ca4380SGeorge Abraham P if (adf_send_admin_tim_sync(accel_dev, time_periods)) 36*b8ca4380SGeorge Abraham P dev_err(&GET_DEV(accel_dev), "Failed to synchronize qat timer\n"); 37*b8ca4380SGeorge Abraham P } 38*b8ca4380SGeorge Abraham P 39*b8ca4380SGeorge Abraham P int adf_timer_start(struct adf_accel_dev *accel_dev) 40*b8ca4380SGeorge Abraham P { 41*b8ca4380SGeorge Abraham P struct adf_timer *timer_ctx; 42*b8ca4380SGeorge Abraham P 43*b8ca4380SGeorge Abraham P timer_ctx = kzalloc(sizeof(*timer_ctx), GFP_KERNEL); 44*b8ca4380SGeorge Abraham P if (!timer_ctx) 45*b8ca4380SGeorge Abraham P return -ENOMEM; 46*b8ca4380SGeorge Abraham P 47*b8ca4380SGeorge Abraham P timer_ctx->accel_dev = accel_dev; 48*b8ca4380SGeorge Abraham P accel_dev->timer = timer_ctx; 49*b8ca4380SGeorge Abraham P timer_ctx->initial_ktime = ktime_get_real(); 50*b8ca4380SGeorge Abraham P 51*b8ca4380SGeorge Abraham P INIT_DELAYED_WORK(&timer_ctx->work_ctx, work_handler); 52*b8ca4380SGeorge Abraham P adf_misc_wq_queue_delayed_work(&timer_ctx->work_ctx, 53*b8ca4380SGeorge Abraham P msecs_to_jiffies(ADF_DEFAULT_TIMER_PERIOD_MS)); 54*b8ca4380SGeorge Abraham P 55*b8ca4380SGeorge Abraham P return 0; 56*b8ca4380SGeorge Abraham P } 57*b8ca4380SGeorge Abraham P EXPORT_SYMBOL_GPL(adf_timer_start); 58*b8ca4380SGeorge Abraham P 59*b8ca4380SGeorge Abraham P void adf_timer_stop(struct adf_accel_dev *accel_dev) 60*b8ca4380SGeorge Abraham P { 61*b8ca4380SGeorge Abraham P struct adf_timer *timer_ctx = accel_dev->timer; 62*b8ca4380SGeorge Abraham P 63*b8ca4380SGeorge Abraham P if (!timer_ctx) 64*b8ca4380SGeorge Abraham P return; 65*b8ca4380SGeorge Abraham P 66*b8ca4380SGeorge Abraham P cancel_delayed_work_sync(&timer_ctx->work_ctx); 67*b8ca4380SGeorge Abraham P 68*b8ca4380SGeorge Abraham P kfree(timer_ctx); 69*b8ca4380SGeorge Abraham P accel_dev->timer = NULL; 70*b8ca4380SGeorge Abraham P } 71*b8ca4380SGeorge Abraham P EXPORT_SYMBOL_GPL(adf_timer_stop); 72