From patchwork Fri Nov 27 22:02:38 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heiner Kallweit X-Patchwork-Id: 7715591 Return-Path: X-Original-To: patchwork-linux-media@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 66BC99F39B for ; Fri, 27 Nov 2015 22:03:12 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 777062067A for ; Fri, 27 Nov 2015 22:03:11 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 70E2820680 for ; Fri, 27 Nov 2015 22:03:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755296AbbK0WDI (ORCPT ); Fri, 27 Nov 2015 17:03:08 -0500 Received: from mail-wm0-f41.google.com ([74.125.82.41]:37101 "EHLO mail-wm0-f41.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755271AbbK0WDG (ORCPT ); Fri, 27 Nov 2015 17:03:06 -0500 Received: by wmww144 with SMTP id w144so71907287wmw.0 for ; Fri, 27 Nov 2015 14:03:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:subject:to:cc:message-id:date:user-agent:mime-version :content-type:content-transfer-encoding; bh=TNIvGo89s4zksXNbKE+LX6HIAHqkErx3kDZOsgdnaKs=; b=ihbyPzEe/OVleLDkgH4adCI8+fC5BR8UzC/7RQ59ybSrYbKviwgZ4SkQ0rpBt5dNYg rkNsZqM+SQjR01e+ljI1Hj8jIzcDhomr0clOfPrLHF/ZNLxqVj4jzuubqvmC4zFoXWGR Mr/1GGqFi5HQe9fvuF7+vRcrJVFbAuiRgt8ZouAC+RGqcznaLfC3CLPDxdgyXZ2tUVof 4Ee6UNdbTNPz15lmWfqBEakxTJHQvOwXwu1XUTCmNdXEqUQhEUky+lsIBjKorpg2gGUU wayxTRgnNIfXj37MfWy21e3qa7AK0thLPljUULjuzxtq4RthHTGDXUeH38497yIHF/la NQOA== X-Received: by 10.194.189.68 with SMTP id gg4mr66681918wjc.146.1448661785444; Fri, 27 Nov 2015 14:03:05 -0800 (PST) Received: from ?IPv6:2003:62:5f55:ba00:b5bb:17e1:e888:2713? (p200300625F55BA00B5BB17E1E8882713.dip0.t-ipconnect.de. [2003:62:5f55:ba00:b5bb:17e1:e888:2713]) by smtp.googlemail.com with ESMTPSA id bg10sm34567626wjb.46.2015.11.27.14.03.04 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 27 Nov 2015 14:03:04 -0800 (PST) From: Heiner Kallweit Subject: [PATCH] media: rc: raw: improve FIFO handling To: Mauro Carvalho Chehab Cc: linux-media@vger.kernel.org, =?UTF-8?Q?David_H=c3=a4rdeman?= Message-ID: <5658D2FE.2000603@gmail.com> Date: Fri, 27 Nov 2015 23:02:38 +0100 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Thunderbird/38.3.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-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, T_DKIM_INVALID, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The FIFO is used for ir_raw_event records, however for some historic reason the FIFO is used on a per byte basis. IMHO this adds unneeded complexity. Therefore set up the FIFO for ir_raw_event records. This also allows to define the FIFO statically as part of ir_raw_event_ctrl instead of having to allocate the FIFO dynamically. In addition: - When writing into the FIFO and it's full return ENOSPC instead of ENOMEM thus making it easier to tell between "FIFO full" and "Dynamic memory allocation failed" when the error is propagated to a higher level. Also add an error message. - When reading from the FIFO check whether it's empty. This is not strictly needed here but kfifo_out is annotated "must check" anyway. Successfully tested it with the nuvoton-cir driver. Signed-off-by: Heiner Kallweit --- drivers/media/rc/rc-core-priv.h | 6 +++++- drivers/media/rc/rc-ir-raw.c | 23 ++++++++--------------- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h index 7359f3d..585d5e5 100644 --- a/drivers/media/rc/rc-core-priv.h +++ b/drivers/media/rc/rc-core-priv.h @@ -16,6 +16,9 @@ #ifndef _RC_CORE_PRIV #define _RC_CORE_PRIV +/* Define the max number of pulse/space transitions to buffer */ +#define MAX_IR_EVENT_SIZE 512 + #include #include #include @@ -35,7 +38,8 @@ struct ir_raw_event_ctrl { struct list_head list; /* to keep track of raw clients */ struct task_struct *thread; spinlock_t lock; - struct kfifo_rec_ptr_1 kfifo; /* fifo for the pulse/space durations */ + /* fifo for the pulse/space durations */ + DECLARE_KFIFO(kfifo, struct ir_raw_event, MAX_IR_EVENT_SIZE); ktime_t last_event; /* when last event occurred */ enum raw_event_type last_type; /* last event type */ struct rc_dev *dev; /* pointer to the parent rc_dev */ diff --git a/drivers/media/rc/rc-ir-raw.c b/drivers/media/rc/rc-ir-raw.c index c69807f..144304c 100644 --- a/drivers/media/rc/rc-ir-raw.c +++ b/drivers/media/rc/rc-ir-raw.c @@ -20,9 +20,6 @@ #include #include "rc-core-priv.h" -/* Define the max number of pulse/space transitions to buffer */ -#define MAX_IR_EVENT_SIZE 512 - /* Used to keep track of IR raw clients, protected by ir_raw_handler_lock */ static LIST_HEAD(ir_raw_client_list); @@ -36,14 +33,12 @@ static int ir_raw_event_thread(void *data) struct ir_raw_event ev; struct ir_raw_handler *handler; struct ir_raw_event_ctrl *raw = (struct ir_raw_event_ctrl *)data; - int retval; while (!kthread_should_stop()) { spin_lock_irq(&raw->lock); - retval = kfifo_len(&raw->kfifo); - if (retval < sizeof(ev)) { + if (!kfifo_len(&raw->kfifo)) { set_current_state(TASK_INTERRUPTIBLE); if (kthread_should_stop()) @@ -54,7 +49,8 @@ static int ir_raw_event_thread(void *data) continue; } - retval = kfifo_out(&raw->kfifo, &ev, sizeof(ev)); + if(!kfifo_out(&raw->kfifo, &ev, 1)) + dev_err(&raw->dev->dev, "IR event FIFO is empty!\n"); spin_unlock_irq(&raw->lock); mutex_lock(&ir_raw_handler_lock); @@ -87,8 +83,10 @@ int ir_raw_event_store(struct rc_dev *dev, struct ir_raw_event *ev) IR_dprintk(2, "sample: (%05dus %s)\n", TO_US(ev->duration), TO_STR(ev->pulse)); - if (kfifo_in(&dev->raw->kfifo, ev, sizeof(*ev)) != sizeof(*ev)) - return -ENOMEM; + if (!kfifo_put(&dev->raw->kfifo, *ev)) { + dev_err(&dev->dev, "IR event FIFO is full!\n"); + return -ENOSPC; + } return 0; } @@ -273,11 +271,7 @@ int ir_raw_event_register(struct rc_dev *dev) dev->raw->dev = dev; dev->change_protocol = change_protocol; - rc = kfifo_alloc(&dev->raw->kfifo, - sizeof(struct ir_raw_event) * MAX_IR_EVENT_SIZE, - GFP_KERNEL); - if (rc < 0) - goto out; + INIT_KFIFO(dev->raw->kfifo); spin_lock_init(&dev->raw->lock); dev->raw->thread = kthread_run(ir_raw_event_thread, dev->raw, @@ -319,7 +313,6 @@ void ir_raw_event_unregister(struct rc_dev *dev) handler->raw_unregister(dev); mutex_unlock(&ir_raw_handler_lock); - kfifo_free(&dev->raw->kfifo); kfree(dev->raw); dev->raw = NULL; }