162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * cxd2880_integ.c
462306a36Sopenharmony_ci * Sony CXD2880 DVB-T2/T tuner + demodulator driver
562306a36Sopenharmony_ci * integration layer common functions
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation
862306a36Sopenharmony_ci */
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#include <linux/ktime.h>
1162306a36Sopenharmony_ci#include <linux/errno.h>
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci#include "cxd2880_tnrdmd.h"
1462306a36Sopenharmony_ci#include "cxd2880_tnrdmd_mon.h"
1562306a36Sopenharmony_ci#include "cxd2880_integ.h"
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ciint cxd2880_integ_init(struct cxd2880_tnrdmd *tnr_dmd)
1862306a36Sopenharmony_ci{
1962306a36Sopenharmony_ci	int ret;
2062306a36Sopenharmony_ci	ktime_t start;
2162306a36Sopenharmony_ci	u8 cpu_task_completed = 0;
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci	if (!tnr_dmd)
2462306a36Sopenharmony_ci		return -EINVAL;
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci	ret = cxd2880_tnrdmd_init1(tnr_dmd);
2762306a36Sopenharmony_ci	if (ret)
2862306a36Sopenharmony_ci		return ret;
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ci	start = ktime_get();
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci	while (1) {
3362306a36Sopenharmony_ci		ret =
3462306a36Sopenharmony_ci		    cxd2880_tnrdmd_check_internal_cpu_status(tnr_dmd,
3562306a36Sopenharmony_ci						     &cpu_task_completed);
3662306a36Sopenharmony_ci		if (ret)
3762306a36Sopenharmony_ci			return ret;
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci		if (cpu_task_completed)
4062306a36Sopenharmony_ci			break;
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci		if (ktime_to_ms(ktime_sub(ktime_get(), start)) >
4362306a36Sopenharmony_ci					CXD2880_TNRDMD_WAIT_INIT_TIMEOUT)
4462306a36Sopenharmony_ci			return -ETIMEDOUT;
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci		usleep_range(CXD2880_TNRDMD_WAIT_INIT_INTVL,
4762306a36Sopenharmony_ci			     CXD2880_TNRDMD_WAIT_INIT_INTVL + 1000);
4862306a36Sopenharmony_ci	}
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci	return cxd2880_tnrdmd_init2(tnr_dmd);
5162306a36Sopenharmony_ci}
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ciint cxd2880_integ_cancel(struct cxd2880_tnrdmd *tnr_dmd)
5462306a36Sopenharmony_ci{
5562306a36Sopenharmony_ci	if (!tnr_dmd)
5662306a36Sopenharmony_ci		return -EINVAL;
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ci	atomic_set(&tnr_dmd->cancel, 1);
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ci	return 0;
6162306a36Sopenharmony_ci}
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ciint cxd2880_integ_check_cancellation(struct cxd2880_tnrdmd *tnr_dmd)
6462306a36Sopenharmony_ci{
6562306a36Sopenharmony_ci	if (!tnr_dmd)
6662306a36Sopenharmony_ci		return -EINVAL;
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci	if (atomic_read(&tnr_dmd->cancel) != 0)
6962306a36Sopenharmony_ci		return -ECANCELED;
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci	return 0;
7262306a36Sopenharmony_ci}
73