From patchwork Thu Oct 22 08:32:28 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 55415 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-wi0-f200.google.com (mail-wi0-f200.google.com [209.85.212.200]) by patches.linaro.org (Postfix) with ESMTPS id C376F23024 for ; Thu, 22 Oct 2015 08:33:07 +0000 (UTC) Received: by wikv3 with SMTP id v3sf30332696wik.1 for ; Thu, 22 Oct 2015 01:33:07 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:sender:precedence:list-id :x-original-sender:x-original-authentication-results:mailing-list :list-post:list-help:list-archive:list-unsubscribe; bh=574m+1GCl5uz99lMRHhaMwby0fJMVWuJ41/Xr1nvlj8=; b=Z2fnF+MlvBQE/XfTkbynaUtPdXZkWdrM4ftAubFxTjONf11tXJVLCbQ4q6n5vxCuc2 HRnR8hO0vA+eCWKsiG6ioKYXtXYY2UMGBIsh6JYDwzdMGGR2rhbxADhMBkrWPWYde0Y2 fMurzvLdj6WOcPesbHxG4n81NIGATzo5qUdoCmsuq0dgUGaMSHlqbRN3x/GgtRPfrbXV fHOIQt8D+8wiQNGp1U7mY6sBvFM72YsfnwckgvFccs31vfiD4y9NmbtIoe5E0UT22dcT gNHOqUEWwfimVFoy6KWJi5OvkgcDnAkjOINZ6usNvTUV4ds7K9lmClM0m3dv2dTRd5ij OPZQ== X-Gm-Message-State: ALoCoQkOnLBkR/qd4bH19zyX7HfMeKFy0G7OGJoNQEJRbzjfVXJoSf3/RgH68oE0V05rxlmJkr5D X-Received: by 10.180.89.41 with SMTP id bl9mr3427320wib.1.1445502787114; Thu, 22 Oct 2015 01:33:07 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.25.170.72 with SMTP id t69ls276704lfe.56.gmail; Thu, 22 Oct 2015 01:33:07 -0700 (PDT) X-Received: by 10.112.156.193 with SMTP id wg1mr7605365lbb.24.1445502786997; Thu, 22 Oct 2015 01:33:06 -0700 (PDT) Received: from mail-lf0-f44.google.com (mail-lf0-f44.google.com. [209.85.215.44]) by mx.google.com with ESMTPS id aw10si8903617lbc.112.2015.10.22.01.33.06 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 22 Oct 2015 01:33:06 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.44 as permitted sender) client-ip=209.85.215.44; Received: by lfbn126 with SMTP id n126so5106801lfb.2 for ; Thu, 22 Oct 2015 01:33:06 -0700 (PDT) X-Received: by 10.112.202.35 with SMTP id kf3mr7851128lbc.19.1445502786843; Thu, 22 Oct 2015 01:33:06 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.59.35 with SMTP id w3csp448223lbq; Thu, 22 Oct 2015 01:33:05 -0700 (PDT) X-Received: by 10.66.120.80 with SMTP id la16mr16115771pab.1.1445502785490; Thu, 22 Oct 2015 01:33:05 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id ep1si19422198pbd.256.2015.10.22.01.33.05; Thu, 22 Oct 2015 01:33:05 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-gpio-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756766AbbJVIdE (ORCPT + 3 others); Thu, 22 Oct 2015 04:33:04 -0400 Received: from mail-lf0-f49.google.com ([209.85.215.49]:33526 "EHLO mail-lf0-f49.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756737AbbJVIdC (ORCPT ); Thu, 22 Oct 2015 04:33:02 -0400 Received: by lffv3 with SMTP id v3so39293211lff.0 for ; Thu, 22 Oct 2015 01:33:00 -0700 (PDT) X-Received: by 10.25.143.72 with SMTP id r69mr4987629lfd.65.1445502780756; Thu, 22 Oct 2015 01:33:00 -0700 (PDT) Received: from localhost.localdomain ([85.235.10.227]) by smtp.gmail.com with ESMTPSA id um10sm2148562lbc.15.2015.10.22.01.32.59 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 22 Oct 2015 01:33:00 -0700 (PDT) From: Linus Walleij To: linux-gpio@vger.kernel.org, Johan Hovold , Alexandre Courbot , Arnd Bergmann , Michael Welling , Markus Pargmann Cc: Mark Brown , Amit Kucheria , Linus Walleij Subject: [PATCH 4/6] tools/gpio: create GPIO tools Date: Thu, 22 Oct 2015 10:32:28 +0200 Message-Id: <1445502750-22672-5-git-send-email-linus.walleij@linaro.org> X-Mailer: git-send-email 2.4.3 In-Reply-To: <1445502750-22672-1-git-send-email-linus.walleij@linaro.org> References: <1445502750-22672-1-git-send-email-linus.walleij@linaro.org> Sender: linux-gpio-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-gpio@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: linus.walleij@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.44 as permitted sender) smtp.mailfrom=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , This creates GPIO tools under tools/gpio/* and adds a single example program to list the GPIOs on a system. When proper devices are created it provides this minimal output: Cc: Johan Hovold Cc: Michael Welling Cc: Markus Pargmann Signed-off-by: Linus Walleij --- MAINTAINERS | 1 + tools/Makefile | 7 +-- tools/gpio/Makefile | 12 +++++ tools/gpio/gpio-utils.c | 11 +++++ tools/gpio/gpio-utils.h | 25 ++++++++++ tools/gpio/lsgpio.c | 128 ++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 181 insertions(+), 3 deletions(-) create mode 100644 tools/gpio/Makefile create mode 100644 tools/gpio/gpio-utils.c create mode 100644 tools/gpio/gpio-utils.h create mode 100644 tools/gpio/lsgpio.c diff --git a/MAINTAINERS b/MAINTAINERS index 4a12cd019511..3bb1f52d54e0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4647,6 +4647,7 @@ F: include/linux/gpio/ F: include/linux/gpio.h F: include/asm-generic/gpio.h F: include/uapi/linux/gpio.h +F: tools/gpio/ GRE DEMULTIPLEXER DRIVER M: Dmitry Kozlov diff --git a/tools/Makefile b/tools/Makefile index d6f307dfb1a3..8912759247b5 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -12,6 +12,7 @@ help: @echo ' cgroup - cgroup tools' @echo ' cpupower - a tool for all things x86 CPU power' @echo ' firewire - the userspace part of nosy, an IEEE-1394 traffic sniffer' + @echo ' gpio - GPIO tools' @echo ' hv - tools used when in Hyper-V clients' @echo ' iio - IIO tools' @echo ' lguest - a minimal 32-bit x86 hypervisor' @@ -48,7 +49,7 @@ acpi: FORCE cpupower: FORCE $(call descend,power/$@) -cgroup firewire hv guest usb virtio vm net iio: FORCE +cgroup firewire hv guest usb virtio vm net iio gpio: FORCE $(call descend,$@) liblockdep: FORCE @@ -109,7 +110,7 @@ acpi_clean: cpupower_clean: $(call descend,power/cpupower,clean) -cgroup_clean hv_clean firewire_clean lguest_clean usb_clean virtio_clean vm_clean net_clean iio_clean: +cgroup_clean hv_clean firewire_clean lguest_clean usb_clean virtio_clean vm_clean net_clean iio_clean gpio_clean: $(call descend,$(@:_clean=),clean) liblockdep_clean: @@ -136,6 +137,6 @@ freefall_clean: clean: acpi_clean cgroup_clean cpupower_clean hv_clean firewire_clean lguest_clean \ perf_clean selftests_clean turbostat_clean usb_clean virtio_clean \ vm_clean net_clean iio_clean x86_energy_perf_policy_clean tmon_clean \ - freefall_clean + freefall_clean gpio_clean .PHONY: FORCE diff --git a/tools/gpio/Makefile b/tools/gpio/Makefile new file mode 100644 index 000000000000..4d198d5c4203 --- /dev/null +++ b/tools/gpio/Makefile @@ -0,0 +1,12 @@ +CC = $(CROSS_COMPILE)gcc +CFLAGS += -Wall -g -D_GNU_SOURCE + +all: lsgpio + +lsgpio: lsgpio.o gpio-utils.o + +%.o: %.c gpio-utils.h + +.PHONY: clean +clean: + rm -f *.o lsgpio diff --git a/tools/gpio/gpio-utils.c b/tools/gpio/gpio-utils.c new file mode 100644 index 000000000000..8208718f2c99 --- /dev/null +++ b/tools/gpio/gpio-utils.c @@ -0,0 +1,11 @@ +/* + * GPIO tools - helpers library for the GPIO tools + * + * Copyright (C) 2015 Linus Walleij + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ + +#include "gpio-utils.h" diff --git a/tools/gpio/gpio-utils.h b/tools/gpio/gpio-utils.h new file mode 100644 index 000000000000..b18209a45ad3 --- /dev/null +++ b/tools/gpio/gpio-utils.h @@ -0,0 +1,25 @@ +/* + * GPIO tools - utility helpers library for the GPIO tools + * + * Copyright (C) 2015 Linus Walleij + * + * Portions copied from iio_utils and lssio: + * Copyright (c) 2010 Manuel Stahl + * Copyright (c) 2008 Jonathan Cameron + * * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ +#ifndef _GPIO_UTILS_H_ +#define _GPIO_UTILS_H_ + +#include + +static inline int check_prefix(const char *str, const char *prefix) +{ + return strlen(str) > strlen(prefix) && + strncmp(str, prefix, strlen(prefix)) == 0; +} + +#endif /* _GPIO_UTILS_H_ */ diff --git a/tools/gpio/lsgpio.c b/tools/gpio/lsgpio.c new file mode 100644 index 000000000000..4cfe29da279b --- /dev/null +++ b/tools/gpio/lsgpio.c @@ -0,0 +1,128 @@ +/* + * lsgpio - example on how to list the GPIO lines on a system + * + * Copyright (C) 2015 Linus Walleij + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * Usage: + * lsgpio <-n device-name> + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gpio-utils.h" + +int list_device(const char *device_name) +{ + struct gpiochip_info cinfo; + char *chrdev_name; + int fd; + int ret; + + ret = asprintf(&chrdev_name, "/dev/%s", device_name); + if (ret < 0) + return -ENOMEM; + + fd = open(chrdev_name, 0); + if (fd == -1) { + ret = -errno; + fprintf(stderr, "Failed to open %s\n", chrdev_name); + goto free_chrdev_name; + } + + /* Inspect this GPIO chip */ + ret = ioctl(fd, GPIO_GET_CHIPINFO_IOCTL, &cinfo); + if (ret == -1) { + ret = -errno; + fprintf(stderr, "Failed to retrieve GPIO fd\n"); + if (close(fd) == -1) + perror("Failed to close GPIO character device file"); + + goto free_chrdev_name; + } + fprintf(stdout, "GPIO chip: %s, %u GPIO lines\n", + cinfo.name, cinfo.lines); + + if (close(fd) == -1) { + ret = -errno; + goto free_chrdev_name; + } + +free_chrdev_name: + free(chrdev_name); + + return ret; + +} + +void print_usage(void) +{ + fprintf(stderr, "Usage: lsgpio [options]...\n" + "List GPIO chips, lines and states\n" + " -n List GPIOs on a named device\n" + " -? This helptext\n" + ); +} + +int main(int argc, char **argv) +{ + const char *device_name; + int ret; + int c; + + while ((c = getopt(argc, argv, "n:")) != -1) { + switch (c) { + case 'n': + device_name = optarg; + break; + case '?': + print_usage(); + return -1; + } + } + + if (device_name) + ret = list_device(device_name); + else { + const struct dirent *ent; + DIR *dp; + + /* List all GPIO devices one at a time */ + dp = opendir("/dev"); + if (!dp) { + ret = -errno; + goto error_out; + } + + ret = -ENOENT; + while (ent = readdir(dp), ent) { + if (check_prefix(ent->d_name, "gpiochip")) { + ret = list_device(ent->d_name); + if (ret) + break; + } + } + + ret = 0; + if (closedir(dp) == -1) { + perror("scanning devices: Failed to close directory"); + ret = -errno; + } + } +error_out: + return ret; +}