Skip to content

Commit

Permalink
media: smipcie: fix interrupt handling and IR timeout
Browse files Browse the repository at this point in the history
commit 6532923 upstream.

After the first IR message, interrupts are no longer received. In addition,
the code generates a timeout IR message of 10ms but sets the timeout value
to 100ms, so no timeout was ever generated.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=204317

Fixes: a49a7a4 ("media: smipcie: add universal ir capability")
Tested-by: Laz Lev <lazlev@web.de>
Cc: stable@vger.kernel.org # v5.1+
Signed-off-by: Sean Young <sean@mess.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
seanyoung authored and gregkh committed Mar 4, 2021
1 parent 3932cb2 commit b0de414
Showing 1 changed file with 26 additions and 20 deletions.
46 changes: 26 additions & 20 deletions drivers/media/pci/smipcie/smipcie-ir.c
Expand Up @@ -60,38 +60,44 @@ static void smi_ir_decode(struct smi_rc *ir)
{
struct smi_dev *dev = ir->dev;
struct rc_dev *rc_dev = ir->rc_dev;
u32 dwIRControl, dwIRData;
u8 index, ucIRCount, readLoop;
u32 control, data;
u8 index, ir_count, read_loop;

dwIRControl = smi_read(IR_Init_Reg);
control = smi_read(IR_Init_Reg);

if (dwIRControl & rbIRVld) {
ucIRCount = (u8) smi_read(IR_Data_Cnt);
dev_dbg(&rc_dev->dev, "ircontrol: 0x%08x\n", control);

readLoop = ucIRCount/4;
if (ucIRCount % 4)
readLoop += 1;
for (index = 0; index < readLoop; index++) {
dwIRData = smi_read(IR_DATA_BUFFER_BASE + (index * 4));
if (control & rbIRVld) {
ir_count = (u8)smi_read(IR_Data_Cnt);

ir->irData[index*4 + 0] = (u8)(dwIRData);
ir->irData[index*4 + 1] = (u8)(dwIRData >> 8);
ir->irData[index*4 + 2] = (u8)(dwIRData >> 16);
ir->irData[index*4 + 3] = (u8)(dwIRData >> 24);
dev_dbg(&rc_dev->dev, "ircount %d\n", ir_count);

read_loop = ir_count / 4;
if (ir_count % 4)
read_loop += 1;
for (index = 0; index < read_loop; index++) {
data = smi_read(IR_DATA_BUFFER_BASE + (index * 4));
dev_dbg(&rc_dev->dev, "IRData 0x%08x\n", data);

ir->irData[index * 4 + 0] = (u8)(data);
ir->irData[index * 4 + 1] = (u8)(data >> 8);
ir->irData[index * 4 + 2] = (u8)(data >> 16);
ir->irData[index * 4 + 3] = (u8)(data >> 24);
}
smi_raw_process(rc_dev, ir->irData, ucIRCount);
smi_set(IR_Init_Reg, rbIRVld);
smi_raw_process(rc_dev, ir->irData, ir_count);
}

if (dwIRControl & rbIRhighidle) {
if (control & rbIRhighidle) {
struct ir_raw_event rawir = {};

dev_dbg(&rc_dev->dev, "high idle\n");

rawir.pulse = 0;
rawir.duration = SMI_SAMPLE_PERIOD * SMI_SAMPLE_IDLEMIN;
ir_raw_event_store_with_filter(rc_dev, &rawir);
smi_set(IR_Init_Reg, rbIRhighidle);
}

smi_set(IR_Init_Reg, rbIRVld);
ir_raw_event_handle(rc_dev);
}

Expand Down Expand Up @@ -150,7 +156,7 @@ int smi_ir_init(struct smi_dev *dev)
rc_dev->dev.parent = &dev->pci_dev->dev;

rc_dev->map_name = dev->info->rc_map;
rc_dev->timeout = MS_TO_US(100);
rc_dev->timeout = SMI_SAMPLE_PERIOD * SMI_SAMPLE_IDLEMIN;
rc_dev->rx_resolution = SMI_SAMPLE_PERIOD;

ir->rc_dev = rc_dev;
Expand All @@ -173,7 +179,7 @@ void smi_ir_exit(struct smi_dev *dev)
struct smi_rc *ir = &dev->ir;
struct rc_dev *rc_dev = ir->rc_dev;

smi_ir_stop(ir);
rc_unregister_device(rc_dev);
smi_ir_stop(ir);
ir->rc_dev = NULL;
}

0 comments on commit b0de414

Please sign in to comment.