From patchwork Wed Jan 25 15:34:19 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 719713 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3v7pz400lwz9s9Y for ; Thu, 26 Jan 2017 02:35:28 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=baylibre-com.20150623.gappssmtp.com header.i=@baylibre-com.20150623.gappssmtp.com header.b="efnz+1b/"; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751808AbdAYPej (ORCPT ); Wed, 25 Jan 2017 10:34:39 -0500 Received: from mail-wm0-f52.google.com ([74.125.82.52]:37955 "EHLO mail-wm0-f52.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751785AbdAYPef (ORCPT ); Wed, 25 Jan 2017 10:34:35 -0500 Received: by mail-wm0-f52.google.com with SMTP id r144so37008940wme.1 for ; Wed, 25 Jan 2017 07:34:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=rIjwNTxW+s7KKYycVPktAAsYkQyntBU15JAHBLnK6VM=; b=efnz+1b/LhsP86Lr5VY73TcyaSjOhdbU/vKuqWIQjrAIVOQhzQ+6eQ6/SjObC2bGP+ Z01YMREjuOUE0ORL+icwEr9e89cU46Vu0FDhuve9Ss6aHGvIqV5MH/ZXELxcgv/E5/6F ffZPRLlhlav7sRaY3kwhFRRMZ+3GxH8H0b9T4nMwQXF96hNUWV2y/l/LsLeEdY5Z5hHl FyY82A9dpE0kS1ArZIAKBPrTvflgcQOhMOsB9azCVum32YF8YCSIogIqbTGE9ZbXubAd tq6BYCIJgGH2dskfopkeDUQLbLdukyNVJ5pZZeFz6TVeZjZvdXrOTZ2tEzv0CvsMA+nr ZyLw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=rIjwNTxW+s7KKYycVPktAAsYkQyntBU15JAHBLnK6VM=; b=h79RXMIyrHmg87IxeVTKiVfQbnkebT4gJkJFPoDun/rbafkz5dDTCVf50HHdCh7f54 FzFMNgRyux2ybZCVdSklUsECjInurQcKf5JE20p4ZyFGOjbRGOFa88sGo9GshDgxIoDk 2ZeZXZvTYaNfNaiwCq8dgxsN60rB+gZ7LAjOUguOkRLQQMFATNnycERnASLflAq4cUaU RD66HCQfWfzOXbZfANOLiOYQnqdjfxQ241ChU76MzidK3Nsabg8TxSqfwzvR7lO0UdSk Csq111tkzJXhKo9nb79Xh8sZ/iG+NQZiIpEsRUiT8hsV0c8SfmeRg5gqsZDIVg1sUxbU TX3Q== X-Gm-Message-State: AIkVDXJqX23uOXAiAHNbd36u/hfBDJh9KFw31etF0yHsvR7HSklm1FV+IE48sbPi7jVkvnKI X-Received: by 10.223.174.183 with SMTP id y52mr37617820wrc.112.1485358473854; Wed, 25 Jan 2017 07:34:33 -0800 (PST) Received: from localhost.localdomain ([90.63.244.31]) by smtp.gmail.com with ESMTPSA id 33sm2462760wrd.34.2017.01.25.07.34.32 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 25 Jan 2017 07:34:33 -0800 (PST) From: Bartosz Golaszewski To: Linus Walleij , Alexandre Courbot , Bamvor Jian Zhang Cc: linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org, Bartosz Golaszewski Subject: [PATCH 5/7] gpio: mockup: implement injecting events over debugfs Date: Wed, 25 Jan 2017 16:34:19 +0100 Message-Id: <1485358461-24070-6-git-send-email-bgolaszewski@baylibre.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1485358461-24070-1-git-send-email-bgolaszewski@baylibre.com> References: <1485358461-24070-1-git-send-email-bgolaszewski@baylibre.com> Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org When probing gpio-mockup, create a debugfs directory structure that allows the user to inject line events by writing either 0 (falling-edge) or 1 (rising-edge) to debugfs files. The gpio-mockup-event directory has one sub-directory per chip and a single event file per line. Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpio-mockup.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/drivers/gpio/gpio-mockup.c b/drivers/gpio/gpio-mockup.c index cf8b1b2..c5eb530 100644 --- a/drivers/gpio/gpio-mockup.c +++ b/drivers/gpio/gpio-mockup.c @@ -15,6 +15,10 @@ #include #include #include +#include +#include + +#include "gpiolib.h" #define GPIO_NAME "gpio-mockup" #define MAX_GC 10 @@ -37,6 +41,7 @@ struct gpio_pin_status { struct mockup_gpio_controller { struct gpio_chip gc; struct gpio_pin_status *stats; + struct dentry *dbg_dir; }; static int gpio_mockup_ranges[MAX_GC << 1]; @@ -44,6 +49,7 @@ static int gpio_mockup_params_nr; module_param_array(gpio_mockup_ranges, int, &gpio_mockup_params_nr, 0400); static const char pins_name_start = 'A'; +static struct dentry *dbg_dir; static int mockup_gpio_get(struct gpio_chip *gc, unsigned int offset) { @@ -85,6 +91,80 @@ static int mockup_gpio_get_direction(struct gpio_chip *gc, unsigned int offset) return cntr->stats[offset].dir; } +static ssize_t mockup_gpio_event_write(struct file *file, + const char __user *usr_buf, + size_t size, loff_t *ppos) +{ + struct gpio_desc *desc; + struct seq_file *sfile; + int status, val; + char buf; + + sfile = file->private_data; + desc = sfile->private; + + status = copy_from_user(&buf, usr_buf, 1); + if (status) + return status; + + if (buf == '0') + val = 0; + else if (buf == '1') + val = 1; + else + return -EINVAL; + + gpiod_set_value_cansleep(desc, val); + gpiod_inject_event(desc); + + return size; +} + +static int mockup_gpio_event_open(struct inode *inode, struct file *file) +{ + return single_open(file, NULL, inode->i_private); +} + +static const struct file_operations mockup_gpio_event_ops = { + .owner = THIS_MODULE, + .open = mockup_gpio_event_open, + .write = mockup_gpio_event_write, + .llseek = no_llseek, +}; + +static void mockup_gpio_debugfs_setup(struct mockup_gpio_controller *cntr) +{ + struct dentry *evfile; + struct gpio_chip *gc; + struct device *dev; + char *name; + int i; + + gc = &cntr->gc; + dev = &gc->gpiodev->dev; + + cntr->dbg_dir = debugfs_create_dir(gc->label, dbg_dir); + if (!cntr->dbg_dir) + goto err; + + for (i = 0; i < gc->ngpio; i++) { + name = devm_kasprintf(dev, GFP_KERNEL, "%d", i); + if (!name) + goto err; + + evfile = debugfs_create_file(name, 0200, cntr->dbg_dir, + &gc->gpiodev->descs[i], + &mockup_gpio_event_ops); + if (!evfile) + goto err; + } + + return; + +err: + dev_err(dev, "error creating debugfs directory\n"); +} + static int mockup_gpio_add(struct device *dev, struct mockup_gpio_controller *cntr, const char *name, int base, int ngpio) @@ -112,6 +192,9 @@ static int mockup_gpio_add(struct device *dev, if (ret) goto err; + if (dbg_dir) + mockup_gpio_debugfs_setup(cntr); + dev_info(dev, "gpio<%d..%d> add successful!", base, base + ngpio); return 0; err: @@ -182,6 +265,10 @@ static int __init mock_device_init(void) { int err; + dbg_dir = debugfs_create_dir("gpio-mockup-event", NULL); + if (!dbg_dir) + pr_err("%s: error creating debugfs directory\n", GPIO_NAME); + pdev = platform_device_alloc(GPIO_NAME, -1); if (!pdev) return -ENOMEM; @@ -203,6 +290,7 @@ static int __init mock_device_init(void) static void __exit mock_device_exit(void) { + debugfs_remove_recursive(dbg_dir); platform_driver_unregister(&mockup_gpio_driver); platform_device_unregister(pdev); }