18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * cxd2880_integ.c
48c2ecf20Sopenharmony_ci * Sony CXD2880 DVB-T2/T tuner + demodulator driver
58c2ecf20Sopenharmony_ci * integration layer common functions
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation
88c2ecf20Sopenharmony_ci */
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#include <linux/ktime.h>
118c2ecf20Sopenharmony_ci#include <linux/errno.h>
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ci#include "cxd2880_tnrdmd.h"
148c2ecf20Sopenharmony_ci#include "cxd2880_tnrdmd_mon.h"
158c2ecf20Sopenharmony_ci#include "cxd2880_integ.h"
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ciint cxd2880_integ_init(struct cxd2880_tnrdmd *tnr_dmd)
188c2ecf20Sopenharmony_ci{
198c2ecf20Sopenharmony_ci	int ret;
208c2ecf20Sopenharmony_ci	ktime_t start;
218c2ecf20Sopenharmony_ci	u8 cpu_task_completed = 0;
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ci	if (!tnr_dmd)
248c2ecf20Sopenharmony_ci		return -EINVAL;
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_ci	ret = cxd2880_tnrdmd_init1(tnr_dmd);
278c2ecf20Sopenharmony_ci	if (ret)
288c2ecf20Sopenharmony_ci		return ret;
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ci	start = ktime_get();
318c2ecf20Sopenharmony_ci
328c2ecf20Sopenharmony_ci	while (1) {
338c2ecf20Sopenharmony_ci		ret =
348c2ecf20Sopenharmony_ci		    cxd2880_tnrdmd_check_internal_cpu_status(tnr_dmd,
358c2ecf20Sopenharmony_ci						     &cpu_task_completed);
368c2ecf20Sopenharmony_ci		if (ret)
378c2ecf20Sopenharmony_ci			return ret;
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci		if (cpu_task_completed)
408c2ecf20Sopenharmony_ci			break;
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci		if (ktime_to_ms(ktime_sub(ktime_get(), start)) >
438c2ecf20Sopenharmony_ci					CXD2880_TNRDMD_WAIT_INIT_TIMEOUT)
448c2ecf20Sopenharmony_ci			return -ETIMEDOUT;
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci		usleep_range(CXD2880_TNRDMD_WAIT_INIT_INTVL,
478c2ecf20Sopenharmony_ci			     CXD2880_TNRDMD_WAIT_INIT_INTVL + 1000);
488c2ecf20Sopenharmony_ci	}
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_ci	return cxd2880_tnrdmd_init2(tnr_dmd);
518c2ecf20Sopenharmony_ci}
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_ciint cxd2880_integ_cancel(struct cxd2880_tnrdmd *tnr_dmd)
548c2ecf20Sopenharmony_ci{
558c2ecf20Sopenharmony_ci	if (!tnr_dmd)
568c2ecf20Sopenharmony_ci		return -EINVAL;
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_ci	atomic_set(&tnr_dmd->cancel, 1);
598c2ecf20Sopenharmony_ci
608c2ecf20Sopenharmony_ci	return 0;
618c2ecf20Sopenharmony_ci}
628c2ecf20Sopenharmony_ci
638c2ecf20Sopenharmony_ciint cxd2880_integ_check_cancellation(struct cxd2880_tnrdmd *tnr_dmd)
648c2ecf20Sopenharmony_ci{
658c2ecf20Sopenharmony_ci	if (!tnr_dmd)
668c2ecf20Sopenharmony_ci		return -EINVAL;
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_ci	if (atomic_read(&tnr_dmd->cancel) != 0)
698c2ecf20Sopenharmony_ci		return -ECANCELED;
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_ci	return 0;
728c2ecf20Sopenharmony_ci}
73