From patchwork Thu Oct 18 22:32:57 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Sean Young X-Patchwork-Id: 10648335 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B654D14E2 for ; Thu, 18 Oct 2018 22:33:00 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 99D6D28BA1 for ; Thu, 18 Oct 2018 22:33:00 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 878C828BB3; Thu, 18 Oct 2018 22:33:00 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 090C428BA1 for ; Thu, 18 Oct 2018 22:33:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725906AbeJSGgF (ORCPT ); Fri, 19 Oct 2018 02:36:05 -0400 Received: from gofer.mess.org ([88.97.38.141]:38963 "EHLO gofer.mess.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725751AbeJSGgF (ORCPT ); Fri, 19 Oct 2018 02:36:05 -0400 Received: by gofer.mess.org (Postfix, from userid 1000) id 48F8B6012B; Thu, 18 Oct 2018 23:32:57 +0100 (BST) From: Sean Young To: linux-media@vger.kernel.org Subject: [PATCH] media: rc: imon_raw: use fls rather than loop per bit Date: Thu, 18 Oct 2018 23:32:57 +0100 Message-Id: <20181018223257.15528-1-sean@mess.org> X-Mailer: git-send-email 2.11.0 MIME-Version: 1.0 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Previously, the code would loop for each of the 40 bits. Now it will branch for each edge in the IR, which will be much less. Signed-off-by: Sean Young --- drivers/media/rc/imon_raw.c | 47 ++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/drivers/media/rc/imon_raw.c b/drivers/media/rc/imon_raw.c index 7796098d9c30..25e56c5b13c0 100644 --- a/drivers/media/rc/imon_raw.c +++ b/drivers/media/rc/imon_raw.c @@ -14,51 +14,50 @@ struct imon { struct device *dev; struct urb *ir_urb; struct rc_dev *rcdev; - u8 ir_buf[8]; + u8 ir_buf[8] __aligned(__alignof__(u64)); char phys[64]; }; /* - * ffs/find_next_bit() searches in the wrong direction, so open-code our own. + * The first 5 bytes of data represent IR pulse or space. Each bit, starting + * from highest bit in the first byte, represents 250µs of data. It is 1 + * for space and 0 for pulse. + * + * The station sends 10 packets, and the 7th byte will be number 1 to 10, so + * when we receive 10 we assume all the data has arrived. */ -static inline int is_bit_set(const u8 *buf, int bit) -{ - return buf[bit / 8] & (0x80 >> (bit & 7)); -} - static void imon_ir_data(struct imon *imon) { struct ir_raw_event rawir = {}; - int offset = 0, size = 5 * 8; + u64 d = be64_to_cpup((__be64 *)imon->ir_buf) >> 24; + int offset = 40; int bit; dev_dbg(imon->dev, "data: %*ph", 8, imon->ir_buf); - while (offset < size) { - bit = offset; - while (!is_bit_set(imon->ir_buf, bit) && bit < size) - bit++; - dev_dbg(imon->dev, "pulse: %d bits", bit - offset); - if (bit > offset) { + do { + bit = fls64(d & (BIT_ULL(offset) - 1)); + if (bit < offset) { + dev_dbg(imon->dev, "pulse: %d bits", offset - bit); rawir.pulse = true; - rawir.duration = (bit - offset) * BIT_DURATION; + rawir.duration = (offset - bit) * BIT_DURATION; ir_raw_event_store_with_filter(imon->rcdev, &rawir); - } - if (bit >= size) - break; + if (bit == 0) + break; - offset = bit; - while (is_bit_set(imon->ir_buf, bit) && bit < size) - bit++; - dev_dbg(imon->dev, "space: %d bits", bit - offset); + offset = bit; + } + + bit = fls64(~d & (BIT_ULL(offset) - 1)); + dev_dbg(imon->dev, "space: %d bits", offset - bit); rawir.pulse = false; - rawir.duration = (bit - offset) * BIT_DURATION; + rawir.duration = (offset - bit) * BIT_DURATION; ir_raw_event_store_with_filter(imon->rcdev, &rawir); offset = bit; - } + } while (offset > 0); if (imon->ir_buf[7] == 0x0a) { ir_raw_event_set_idle(imon->rcdev, true);