Re: [RFC] Teach drivers/media/IR/ir-raw-event.c to use durations
On Tue, 2010-04-06 at 11:26 -0300, Mauro Carvalho Chehab wrote: Hi David, I won't comment every single bits of the change, since we're more interested on the conceptual aspects. -int ir_raw_event_store(struct input_dev *input_dev, enum raw_event_type type) Don't remove the raw_event_store. It is needed by the hardware that gets events from IRQ/polling. For sure another interface is needed, for the cases where the hardware pass their own time measure, like cx18 (http://linuxtv.org/hg/~awalls/cx23885-ir2/rev/2cfef53b95a2). For those, we need something like: int ir_raw_event_time_store(struct input_dev *input_dev, enum raw_event_type type, u32 nsecs) Where, instead of using ktime_get_ts(), it will use the timing provided by the hardware. Just to clarify what Conexant hardware, and my current driver for it, is capable of: 1. It provides raw pulse (and space) width measurements. 2. Those measurements can have very high resoltuion (~37 ns IIRC) or very low resolution (usec or msec IIRC) depending on how the hardware clock dividers are set up. 3. The hardware provides a timeout when the measurment timer overflows, meaning that no edge happened for a very long time. This generates a special overflow measurment value and a receiver timeout interrupt. 4. The hardware has an 8 measurement deep FIFO, which the driver starts to drain whenever it is half full (i.e. pulse measurement data is delayed). This happens in response to a hardware FIFO service request interrupt. 5. The hardware FIFO is drained by the driver whenever an interrupt is received and the available measruement data is placed into a kfifo(). This will then signal a work handler that it has work to do. 6. Measurements are scaled to standard time units (i.e. ns) by the driver when they are read out of the kfifo() by a work handler. (No sense in doing time conversions in an interrupt handler). 7. The work handler then begins passing whatever measurements it has, one at a time, over to a pulse stream decoder. 8. If the pulse stream decoder actually decodes something, it is passed over to the input subsystem. I suspect this device's behavior is much closer to what the MCE-USB device does, than the raw GPIO handlers, but I don't really know the MCE-USB. Regards, Andy -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC] Teach drivers/media/IR/ir-raw-event.c to use durations
On Tue, Apr 06, 2010 at 11:26:35AM -0300, Mauro Carvalho Chehab wrote: Hi David, Em Tue, 6 Apr 2010 12:48:11 +0200 David Härdeman da...@hardeman.nu escreveu: Content-Type: text/plain; charset=us-ascii Content-Disposition: inline; filename=use-pulse-space-timings-in-ir-raw Thunderbird 2 really don't like this. It considers the entire body as a file, and refuses to quote it. Never had people complain when I use quilt before but I'll see what I can do. drivers/media/IR/ir-raw-event.c is currently written with the assumption that all raw hardware will generate events only on state change (i.e. when a pulse or space starts). However, some hardware (like mceusb, probably the most popular IR receiver out there) only generates duration data (and that data is buffered so using any kind of timing on the data is futile). Am I understanding right and this hardware is not capable of indicating if the event is a pulse or a space? It seems hard to auto-detect what is pulse or space, but IMO such code should belong to mceusb driver and not to the decoders. No, the driver for mceusb sends a usb packet which contains a couple of pulse/space durations in the form of signed integers representing pulse (positive) and space (negative) durations in microseconds. It's a pretty common arrangement. winbond-cir also has a mode (which is the one I'm planning on using in the future) where pulse/space durations are accumulated in the UART buffer and an IRQ is generated once the buffer level reaches a threshold. Based on the code changes you did, I suspect that one of the things the hardware provides is a machine reset state, right? If you just need to add a code to reset the state machines, this could be done as easily as adding an event at kfifo with IR_STOP_EVENT. A three line addition at the decoders event handler would be enough to use it to reset the state machine: if (ev-type IR_STOP_EVENT) { data-state = STATE_INACTIVE; return; } This event were not added yet, since no hardware currently ported needs it. Eventually, we may rename it to IR_RESET_STATE, if you think it is clearer. Not a particular state per se, I just added a function which the hardware can use to reset the state machines when necessary (think hardware reset, suspend/resume, switching from RX to TX and back again, etc). I think this: /* Hardware has been reset, notify ir-core */ ir_raw_event_reset(input_dev); is a hell lot clearer than this (your current code): /* Hardware has been reset, notify ir-core */ rc = ir_raw_event_store(input_dev, IR_STOP_EVENT); if (rc) { /* Uh oh, what do we do now? */ ... } rc = ir_raw_event_handle(input_dev); if (rc) { /* Not again... */ ... } This patch (which is not tested since I haven't yet converted a driver for any of my hardware to ir-core yet, will do soon) is a RFC on my proposed interface change...once I get the green light on the interface change itself I'll make sure that the decoders actually work :) Yes, better to discuss before changing everything ;) The rc5 decoder has also gained rc5x support and the use of kfifo's for intermediate storage is gone (since there is no need for it). The RC-5X addition is welcome, but the better is to add it as a separate patch. Using durations (instead of a combination of struct timespec and enum raw_event_type) as the argument to the decoder necessitates rewriting most of the decoders, so it seemed like a good time to add it. RC5X or not will anyway only mean a couple of lines of difference but I can send it as a separate patch if that helps you. I won't comment every single bits of the change, since we're more interested on the conceptual aspects. -int ir_raw_event_store(struct input_dev *input_dev, enum raw_event_type type) Don't remove the raw_event_store. It is needed by the hardware that gets events from IRQ/polling. See the comments for kfifo below. For sure another interface is needed, for the cases where the hardware pass their own time measure, like cx18 (http://linuxtv.org/hg/~awalls/cx23885-ir2/rev/2cfef53b95a2). For those, we need something like: int ir_raw_event_time_store(struct input_dev *input_dev, enum raw_event_type type, u32 nsecs) Where, instead of using ktime_get_ts(), it will use the timing provided by the hardware. Um, this sounds exactly like ir_raw_event_duration() which was the main point of my patch. -int ir_raw_event_handle(struct input_dev *input_dev) +/** + * ir_raw_event_edge() - notify raw ir decoders of the start of a pulse/space + * @input_dev: the struct input_dev device descriptor + * @type: the type of the event that has occurred + * + * This routine is used to notify the raw ir
Re: [RFC] Teach drivers/media/IR/ir-raw-event.c to use durations
On Wed, Apr 07, 2010 at 06:20:07AM -0400, Andy Walls wrote: On Tue, 2010-04-06 at 11:26 -0300, Mauro Carvalho Chehab wrote: I won't comment every single bits of the change, since we're more interested on the conceptual aspects. -int ir_raw_event_store(struct input_dev *input_dev, enum raw_event_type type) Don't remove the raw_event_store. It is needed by the hardware that gets events from IRQ/polling. For sure another interface is needed, for the cases where the hardware pass their own time measure, like cx18 (http://linuxtv.org/hg/~awalls/cx23885-ir2/rev/2cfef53b95a2). For those, we need something like: int ir_raw_event_time_store(struct input_dev *input_dev, enum raw_event_type type, u32 nsecs) Where, instead of using ktime_get_ts(), it will use the timing provided by the hardware. Just to clarify what Conexant hardware, and my current driver for it, is capable of: 1. It provides raw pulse (and space) width measurements. 2. Those measurements can have very high resoltuion (~37 ns IIRC) or very low resolution (usec or msec IIRC) depending on how the hardware clock dividers are set up. 3. The hardware provides a timeout when the measurment timer overflows, meaning that no edge happened for a very long time. This generates a special overflow measurment value and a receiver timeout interrupt. 4. The hardware has an 8 measurement deep FIFO, which the driver starts to drain whenever it is half full (i.e. pulse measurement data is delayed). This happens in response to a hardware FIFO service request interrupt. 5. The hardware FIFO is drained by the driver whenever an interrupt is received and the available measruement data is placed into a kfifo(). This will then signal a work handler that it has work to do. 6. Measurements are scaled to standard time units (i.e. ns) by the driver when they are read out of the kfifo() by a work handler. (No sense in doing time conversions in an interrupt handler). 7. The work handler then begins passing whatever measurements it has, one at a time, over to a pulse stream decoder. 8. If the pulse stream decoder actually decodes something, it is passed over to the input subsystem. I suspect this device's behavior is much closer to what the MCE-USB device does, than the raw GPIO handlers, but I don't really know the MCE-USB. This sounds very similar to winbond-cir (the hardware parts that is, basically until and including item 5, line 1). The mceusb HW does something similar...it sends usb packets with a couple of pulse/space duration measurements (of 50us resolution IIRC)...and it automatically enters an inactive state after 1 us of silence. The ir_raw_event_duration() function of my patch is intended for exactly this kind of hardware (which I mentioned in my reply to Mauro which I just sent out). The question is though, is the kfifo and work handler really necessary? -- David Härdeman -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC] Teach drivers/media/IR/ir-raw-event.c to use durations
I had to rework this portion of code several times in the IR code I posted. I had the core provide input_ir_queue() which was legal to call from interrupt context. Calling from interrupt context was an important aspect I missed in the first versions. I made this a common routine so that the code didn't get copied into all of the drivers. This code should have used kfifo but I didn't know about kfifo. The question is though, is the kfifo and work handler really necessary? Yes, otherwise it will get duplicated into all of the drivers that run in interrupt context like this GPIO one. Put this common code into the core so that the individual drivers writers don't mess it up. void input_ir_queue(struct input_dev *dev, int sample) { unsigned int next; spin_lock(dev-ir-queue.lock); dev-ir-queue.samples[dev-ir-queue.head] = sample; next = dev-ir-queue.head + 1; dev-ir-queue.head = (next = MAX_SAMPLES ? 0 : next); spin_unlock(dev-ir-queue.lock); schedule_work(dev-ir-work); } My GPIO implementation simply call input_it_queue() with the timing data. I collapsed multiple long space interrupts into one very long space. If you are using protocol engines, there is no need to detect the long trailing space. The protocol engine will trigger on the last pulse of the signal. On the other hand, LIRC in user space needs the last long space to know when to flush the buffer from kernel space into user space. The timeout for this flush should be implemented in the LIRC compatibility driver, not ir-core. In this case my GPIO driver doesn't ever generate an event for the long space at the end of the message (because it doesn't end). Instead the LIRC compatibility layer should start a timer and flush when no data has been received for 200ms or whatever. static irqreturn_t dpeak_ir_irq(int irq, void *_ir) { struct ir_gpt *ir_gpt = _ir; int sample, count, delta, bit, wrap; sample = in_be32(ir_gpt-regs-status); out_be32(ir_gpt-regs-status, 0xF); count = sample 16; wrap = (sample 12) 7; bit = (sample 8) 1; delta = count - ir_gpt-previous; delta += wrap * 0x1; ir_gpt-previous = count; if (bit) delta = -delta; input_ir_queue(ir_gpt-input, delta); return IRQ_HANDLED; } For MSMCE I converted their format back into simple delays and fed it into input_ir_queue(). This was not done in interrupt context because of the way USB works. input_ir_queue() doesn't care - it works correctly when called from either context. if (ir-last.command == 0x80) { bit = ((ir-buf_in[i] MCE_PULSE_BIT) != 0); delta = (ir-buf_in[i] MCE_PULSE_MASK) * MCE_TIME_BASE; if ((ir-buf_in[i] MCE_PULSE_MASK) == 0x7f) { if (ir-last.bit == bit) ir-last.delta += delta; else { ir-last.delta = delta; ir-last.bit = bit; } continue; } delta += ir-last.delta; ir-last.delta = 0; ir-last.bit = bit; dev_dbg(ir-usbdev-dev, bit %d delta %d\n, bit, delta); if (bit) delta = -delta; input_ir_queue(ir-input, delta); } These delay messages are then fed into the protocol engines which process the pulses in parallel. Processing in parallel works, because that's how IR receivers work. When you shine a remote on an equipment rack, all of the equipment sees the command in parallel. The protocols are designed so that parallel decode works properly. -- Jon Smirl jonsm...@gmail.com -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC] Teach drivers/media/IR/ir-raw-event.c to use durations
David Härdeman wrote: On Tue, Apr 06, 2010 at 11:26:35AM -0300, Mauro Carvalho Chehab wrote: Hi David, Em Tue, 6 Apr 2010 12:48:11 +0200 David Härdeman da...@hardeman.nu escreveu: Content-Type: text/plain; charset=us-ascii Content-Disposition: inline; filename=use-pulse-space-timings-in-ir-raw Thunderbird 2 really don't like this. It considers the entire body as a file, and refuses to quote it. Never had people complain when I use quilt before but I'll see what I can do. Thanks. I'll also see if I can get some extension to thunderbird to fix it, or consider moving (again) to another emailer. drivers/media/IR/ir-raw-event.c is currently written with the assumption that all raw hardware will generate events only on state change (i.e. when a pulse or space starts). However, some hardware (like mceusb, probably the most popular IR receiver out there) only generates duration data (and that data is buffered so using any kind of timing on the data is futile). Am I understanding right and this hardware is not capable of indicating if the event is a pulse or a space? It seems hard to auto-detect what is pulse or space, but IMO such code should belong to mceusb driver and not to the decoders. No, the driver for mceusb sends a usb packet which contains a couple of pulse/space durations in the form of signed integers representing pulse (positive) and space (negative) durations in microseconds. It's a pretty common arrangement. winbond-cir also has a mode (which is the one I'm planning on using in the future) where pulse/space durations are accumulated in the UART buffer and an IRQ is generated once the buffer level reaches a threshold. Ok. Based on the code changes you did, I suspect that one of the things the hardware provides is a machine reset state, right? If you just need to add a code to reset the state machines, this could be done as easily as adding an event at kfifo with IR_STOP_EVENT. A three line addition at the decoders event handler would be enough to use it to reset the state machine: if (ev-type IR_STOP_EVENT) { data-state = STATE_INACTIVE; return; } This event were not added yet, since no hardware currently ported needs it. Eventually, we may rename it to IR_RESET_STATE, if you think it is clearer. Not a particular state per se, I just added a function which the hardware can use to reset the state machines when necessary (think hardware reset, suspend/resume, switching from RX to TX and back again, etc). I think this: /* Hardware has been reset, notify ir-core */ ir_raw_event_reset(input_dev); is a hell lot clearer than this (your current code): /* Hardware has been reset, notify ir-core */ rc = ir_raw_event_store(input_dev, IR_STOP_EVENT); if (rc) { /* Uh oh, what do we do now? */ ... Ok. What about: #define ir_raw_event_reset(input_dev) ir_raw_event_store(input_dev, IR_STOP_EVENT) This will save some code and avoid one more symbol to be exported. } rc = ir_raw_event_handle(input_dev); if (rc) { /* Not again... */ ... } This patch (which is not tested since I haven't yet converted a driver for any of my hardware to ir-core yet, will do soon) is a RFC on my proposed interface change...once I get the green light on the interface change itself I'll make sure that the decoders actually work :) Yes, better to discuss before changing everything ;) The rc5 decoder has also gained rc5x support and the use of kfifo's for intermediate storage is gone (since there is no need for it). The RC-5X addition is welcome, but the better is to add it as a separate patch. Using durations (instead of a combination of struct timespec and enum raw_event_type) as the argument to the decoder necessitates rewriting most of the decoders, so it seemed like a good time to add it. RC5X or not will anyway only mean a couple of lines of difference but I can send it as a separate patch if that helps you. Ok, thanks. I won't comment every single bits of the change, since we're more interested on the conceptual aspects. -int ir_raw_event_store(struct input_dev *input_dev, enum raw_event_type type) Don't remove the raw_event_store. It is needed by the hardware that gets events from IRQ/polling. See the comments for kfifo below. For sure another interface is needed, for the cases where the hardware pass their own time measure, like cx18 (http://linuxtv.org/hg/~awalls/cx23885-ir2/rev/2cfef53b95a2). For those, we need something like: int ir_raw_event_time_store(struct input_dev *input_dev, enum raw_event_type type, u32 nsecs) Where, instead of using ktime_get_ts(), it will use the timing provided by the hardware. Um, this sounds exactly like ir_raw_event_duration() which was the main point of my patch. The better
Re: [RFC] Teach drivers/media/IR/ir-raw-event.c to use durations
Jon Smirl wrote: I had to rework this portion of code several times in the IR code I posted. I had the core provide input_ir_queue() which was legal to call from interrupt context. Calling from interrupt context was an important aspect I missed in the first versions. I made this a common routine so that the code didn't get copied into all of the drivers. This code should have used kfifo but I didn't know about kfifo. The question is though, is the kfifo and work handler really necessary? Yes, otherwise it will get duplicated into all of the drivers that run in interrupt context like this GPIO one. Put this common code into the core so that the individual drivers writers don't mess it up. void input_ir_queue(struct input_dev *dev, int sample) { unsigned int next; spin_lock(dev-ir-queue.lock); dev-ir-queue.samples[dev-ir-queue.head] = sample; next = dev-ir-queue.head + 1; dev-ir-queue.head = (next = MAX_SAMPLES ? 0 : next); spin_unlock(dev-ir-queue.lock); schedule_work(dev-ir-work); } The big advantage of using kfifo is that you don't need to use a spinlock, if there's just one consumer of the event. On the implementation I did, just one code writes to the kfifo (the driver) and just one code reads from the kfifo, and multiplexing the data to the several decoders (and lirc_dev). So, no locks. My GPIO implementation simply call input_it_queue() with the timing data. I collapsed multiple long space interrupts into one very long space. If you are using protocol engines, there is no need to detect the long trailing space. The protocol engine will trigger on the last pulse of the signal. On the other hand, LIRC in user space needs the last long space to know when to flush the buffer from kernel space into user space. The timeout for this flush should be implemented in the LIRC compatibility driver, not ir-core. In this case my GPIO driver doesn't ever generate an event for the long space at the end of the message (because it doesn't end). Instead the LIRC compatibility layer should start a timer and flush when no data has been received for 200ms or whatever. Agreed. static irqreturn_t dpeak_ir_irq(int irq, void *_ir) { struct ir_gpt *ir_gpt = _ir; int sample, count, delta, bit, wrap; sample = in_be32(ir_gpt-regs-status); out_be32(ir_gpt-regs-status, 0xF); count = sample 16; wrap = (sample 12) 7; bit = (sample 8) 1; delta = count - ir_gpt-previous; delta += wrap * 0x1; ir_gpt-previous = count; if (bit) delta = -delta; input_ir_queue(ir_gpt-input, delta); return IRQ_HANDLED; } For MSMCE I converted their format back into simple delays and fed it into input_ir_queue(). This was not done in interrupt context because of the way USB works. input_ir_queue() doesn't care - it works correctly when called from either context. if (ir-last.command == 0x80) { bit = ((ir-buf_in[i] MCE_PULSE_BIT) != 0); delta = (ir-buf_in[i] MCE_PULSE_MASK) * MCE_TIME_BASE; if ((ir-buf_in[i] MCE_PULSE_MASK) == 0x7f) { if (ir-last.bit == bit) ir-last.delta += delta; else { ir-last.delta = delta; ir-last.bit = bit; } continue; } delta += ir-last.delta; ir-last.delta = 0; ir-last.bit = bit; dev_dbg(ir-usbdev-dev, bit %d delta %d\n, bit, delta); if (bit) delta = -delta; input_ir_queue(ir-input, delta); } These delay messages are then fed into the protocol engines which process the pulses in parallel. Processing in parallel works, because that's how IR receivers work. When you shine a remote on an equipment rack, all of the equipment sees the command in parallel. The protocols are designed so that parallel decode works properly. On the implementation I did, each event is passed to each decoder serialized (yet, as one keystroke is a series of events, it behaves as if they are processed in parallel). We might create separate kthreads for each decoder, and use a spinlock at kfifo, but I suspect that the end result will be very close and we'll have more
Re: [RFC] Teach drivers/media/IR/ir-raw-event.c to use durations
On Wed, Apr 7, 2010 at 9:29 AM, Mauro Carvalho Chehab mche...@infradead.org wrote: On the implementation I did, each event is passed to each decoder serialized (yet, as one keystroke is a series of events, it behaves as if they are processed in parallel). We might create separate kthreads for each decoder, and use a spinlock at kfifo, but I suspect that the end result will be very close and we'll have more threads interfering at the samples collect, especially on those (broken) hardware that don't have IRQ's to indicate a state transition, so the driver needs to poll the samples. Polling should be the driver's problem. They can set up a timer interrupt and do it that way. Do all of the protocols have a long enough lead one for a timer tick to catch them? If so, look for it in the timer event, then go into a polling loop. You'd be way better off buying new hardware since your video is going to stop while this pooling loop runs. Do modern serial ports interrupt on DTR or whatever those Iguana devices use? What is an example of a polled input device? I can't think of one, even IR diode on mic input is interrupt driven (that require a special ALSA driver to pass the data into RC core). No need to use different kthreads for each protocol decoder, but don't lock up the default kernel thread waiting for a user space response. What I meant by parallel was that pulses are fed one at a time into each of the decoders, don't wait for a long space and then feed the entire message into the decoders. -- Cheers, Mauro -- Jon Smirl jonsm...@gmail.com -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC] Teach drivers/media/IR/ir-raw-event.c to use durations
Hi David, Em Tue, 6 Apr 2010 12:48:11 +0200 David Härdeman da...@hardeman.nu escreveu: Content-Type: text/plain; charset=us-ascii Content-Disposition: inline; filename=use-pulse-space-timings-in-ir-raw Thunderbird 2 really don't like this. It considers the entire body as a file, and refuses to quote it. drivers/media/IR/ir-raw-event.c is currently written with the assumption that all raw hardware will generate events only on state change (i.e. when a pulse or space starts). However, some hardware (like mceusb, probably the most popular IR receiver out there) only generates duration data (and that data is buffered so using any kind of timing on the data is futile). Am I understanding right and this hardware is not capable of indicating if the event is a pulse or a space? It seems hard to auto-detect what is pulse or space, but IMO such code should belong to mceusb driver and not to the decoders. Based on the code changes you did, I suspect that one of the things the hardware provides is a machine reset state, right? If you just need to add a code to reset the state machines, this could be done as easily as adding an event at kfifo with IR_STOP_EVENT. A three line addition at the decoders event handler would be enough to use it to reset the state machine: if (ev-type IR_STOP_EVENT) { data-state = STATE_INACTIVE; return; } This event were not added yet, since no hardware currently ported needs it. Eventually, we may rename it to IR_RESET_STATE, if you think it is clearer. This patch (which is not tested since I haven't yet converted a driver for any of my hardware to ir-core yet, will do soon) is a RFC on my proposed interface change...once I get the green light on the interface change itself I'll make sure that the decoders actually work :) Yes, better to discuss before changing everything ;) The rc5 decoder has also gained rc5x support and the use of kfifo's for intermediate storage is gone (since there is no need for it). The RC-5X addition is welcome, but the better is to add it as a separate patch. I won't comment every single bits of the change, since we're more interested on the conceptual aspects. -int ir_raw_event_store(struct input_dev *input_dev, enum raw_event_type type) Don't remove the raw_event_store. It is needed by the hardware that gets events from IRQ/polling. For sure another interface is needed, for the cases where the hardware pass their own time measure, like cx18 (http://linuxtv.org/hg/~awalls/cx23885-ir2/rev/2cfef53b95a2). For those, we need something like: int ir_raw_event_time_store(struct input_dev *input_dev, enum raw_event_type type, u32 nsecs) Where, instead of using ktime_get_ts(), it will use the timing provided by the hardware. -int ir_raw_event_handle(struct input_dev *input_dev) +/** + * ir_raw_event_edge() - notify raw ir decoders of the start of a pulse/space + * @input_dev: the struct input_dev device descriptor + * @type:the type of the event that has occurred + * + * This routine is used to notify the raw ir decoders on the beginning of an + * ir pulse or space (or the start/end of ir reception). This is used by + * hardware which does not provide durations directly but only interrupts + * (or similar events) on state change. + */ +void ir_raw_event_edge(struct input_dev *input_dev, enum raw_event_type type) { - struct ir_input_dev *ir = input_get_drvdata(input_dev); - int rc; - struct ir_raw_event ev; - int len, i; - - /* - * Store the events into a temporary buffer. This allows calling more than - * one decoder to deal with the received data - */ - len = kfifo_len(ir-raw-kfifo) / sizeof(ev); - if (!len) - return 0; The removal of kfifo is not a good idea. On several drivers, the event is generated during IRQ time, or on a very expensive polling loop. So, buffering is needed to release the IRQ as soon as possible and not adding too much processing during polling. - - for (i = 0; i len; i++) { - rc = kfifo_out(ir-raw-kfifo, ev, sizeof(ev)); - if (rc != sizeof(ev)) { - IR_dprintk(1, overflow error: received %d instead of %zd\n, -rc, sizeof(ev)); - return -EINVAL; - } - IR_dprintk(2, event type %d, time before event: %07luus\n, - ev.type, (ev.delta.tv_nsec + 500) / 1000); - rc = RUN_DECODER(decode, input_dev, ev); - } + struct ir_input_dev *ir = input_get_drvdata(input_dev); + ktime_t now; + s64 delta; /* us */ + + if (!ir-raw) + return; - /* - * Call all ir decoders. This allows decoding the same event with - * more than one