media: vivid: use ktime_t for timestamp calculation

timespec is generally deprecated because of the y2038 overflow.
In vivid, the usage is fine, since we are dealing with monotonic
timestamps, but we can also simplify the code by going to ktime_t.

Using ktime_divns() should be roughly as efficient as the old code,
since the constant 64-bit division gets turned into a multiplication
on modern platforms, and we save multiple 32-bit divisions that can be
expensive e.g. on ARMv7.

Tested-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
This commit is contained in:
Arnd Bergmann 2017-11-27 10:25:56 -05:00 committed by Mauro Carvalho Chehab
parent 1d88f4bccf
commit aad2fa4c8b
5 changed files with 11 additions and 13 deletions

View file

@ -995,7 +995,7 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
dev->edid_max_blocks = dev->edid_blocks = 2;
memcpy(dev->edid, vivid_hdmi_edid, sizeof(vivid_hdmi_edid));
ktime_get_ts(&dev->radio_rds_init_ts);
dev->radio_rds_init_time = ktime_get();
/* create all controls */
ret = vivid_create_controls(dev, ccs_cap == -1, ccs_out == -1, no_error_inj,

View file

@ -510,7 +510,7 @@ struct vivid_dev {
/* Shared between radio receiver and transmitter */
bool radio_rds_loop;
struct timespec radio_rds_init_ts;
ktime_t radio_rds_init_time;
/* CEC */
struct cec_adapter *cec_rx_adap;

View file

@ -38,9 +38,9 @@ ssize_t vivid_radio_rx_read(struct file *file, char __user *buf,
size_t size, loff_t *offset)
{
struct vivid_dev *dev = video_drvdata(file);
struct timespec ts;
struct v4l2_rds_data *data = dev->rds_gen.data;
bool use_alternates;
ktime_t timestamp;
unsigned blk;
int perc;
int i;
@ -64,17 +64,16 @@ ssize_t vivid_radio_rx_read(struct file *file, char __user *buf,
}
retry:
ktime_get_ts(&ts);
use_alternates = ts.tv_sec % 10 >= 5;
timestamp = ktime_sub(ktime_get(), dev->radio_rds_init_time);
blk = ktime_divns(timestamp, VIVID_RDS_NSEC_PER_BLK);
use_alternates = (blk % VIVID_RDS_GEN_BLOCKS) & 1;
if (dev->radio_rx_rds_last_block == 0 ||
dev->radio_rx_rds_use_alternates != use_alternates) {
dev->radio_rx_rds_use_alternates = use_alternates;
/* Re-init the RDS generator */
vivid_radio_rds_init(dev);
}
ts = timespec_sub(ts, dev->radio_rds_init_ts);
blk = ts.tv_sec * 100 + ts.tv_nsec / 10000000;
blk = (blk * VIVID_RDS_GEN_BLOCKS) / 500;
if (blk >= dev->radio_rx_rds_last_block + VIVID_RDS_GEN_BLOCKS)
dev->radio_rx_rds_last_block = blk - VIVID_RDS_GEN_BLOCKS + 1;

View file

@ -37,7 +37,7 @@ ssize_t vivid_radio_tx_write(struct file *file, const char __user *buf,
{
struct vivid_dev *dev = video_drvdata(file);
struct v4l2_rds_data *data = dev->rds_gen.data;
struct timespec ts;
ktime_t timestamp;
unsigned blk;
int i;
@ -58,10 +58,8 @@ ssize_t vivid_radio_tx_write(struct file *file, const char __user *buf,
dev->radio_tx_rds_owner = file->private_data;
retry:
ktime_get_ts(&ts);
ts = timespec_sub(ts, dev->radio_rds_init_ts);
blk = ts.tv_sec * 100 + ts.tv_nsec / 10000000;
blk = (blk * VIVID_RDS_GEN_BLOCKS) / 500;
timestamp = ktime_sub(ktime_get(), dev->radio_rds_init_time);
blk = ktime_divns(timestamp, VIVID_RDS_NSEC_PER_BLK);
if (blk - VIVID_RDS_GEN_BLOCKS >= dev->radio_tx_rds_last_block)
dev->radio_tx_rds_last_block = blk - VIVID_RDS_GEN_BLOCKS + 1;

View file

@ -29,6 +29,7 @@
#define VIVID_RDS_GEN_GROUPS 57
#define VIVID_RDS_GEN_BLKS_PER_GRP 4
#define VIVID_RDS_GEN_BLOCKS (VIVID_RDS_GEN_BLKS_PER_GRP * VIVID_RDS_GEN_GROUPS)
#define VIVID_RDS_NSEC_PER_BLK (u32)(5ull * NSEC_PER_SEC / VIVID_RDS_GEN_BLOCKS)
struct vivid_rds_gen {
struct v4l2_rds_data data[VIVID_RDS_GEN_BLOCKS];