* Re: [PATCH 2/3]: Remove perl from make headers_install
From: Sam Ravnborg @ 2009-01-02 9:09 UTC (permalink / raw)
To: Rob Landley
Cc: Embedded Linux mailing list, linux-kernel, Andrew Morton,
H. Peter Anvin
In-Reply-To: <200901020214.33123.rob@landley.net>
On Fri, Jan 02, 2009 at 02:14:32AM -0600, Rob Landley wrote:
> From: Rob Landley <rob@landley.net>
>
> Remove perl from make headers_install by replacing a perl script (doing
> a simple regex search and replace) with a smaller and faster shell script
> implementation. The new shell script is a single for loop calling sed and
> piping its output through unifdef to produce the target file.
OK
>
> Sam Ravnborg added this perl to 2.6.27.
Drop this part - this is just to make you happy and for no use for others.
>
> Signed-off-by: Rob Landley <rob@landley.net>
> ---
>
> scripts/Makefile.headersinst | 6 ++--
> scripts/headers_install.pl | 46 ---------------------------------
> scripts/headers_install.sh | 23 ++++++++++++++++
> 3 files changed, 26 insertions(+), 49 deletions(-)
>
> --- /dev/null 2008-11-21 04:46:41.000000000 -0600
> +++ b/scripts/headers_install.sh 2008-12-15 22:09:45.000000000 -0600
> @@ -0,0 +1,23 @@
> +#!/bin/bash
> +
> +# Grab arguments
> +
> +INDIR="$1"
> +shift
> +OUTDIR="$1"
> +shift
> +ARCH="$1"
> +shift
Please add a short explanation what this file is used for
and what it does.
You can take more or less a direct copy from headers_install.pl
> +
> +# Iterate through files listed on command line
> +
> +for i in "$@"
> +do
> + sed -r \
> + -e 's/([ \t(])(__user|__force|__iomem)[ \t]/\1/g' \
> + -e 's/__attribute_const__([ \t]|$)/\1/g' \
> + -e 's@^#include <linux/compiler.h>@@' "$INDIR/$i" |
> + scripts/unifdef -U__KERNEL__ - > "$OUTDIR/$i"
> +done
> +
> +exit 0
> diff -r d9b501c91442 scripts/Makefile.headersinst
> --- a/scripts/Makefile.headersinst Sun Dec 14 16:25:19 2008 -0800
> +++ b/scripts/Makefile.headersinst Mon Dec 15 23:30:15 2008 -0600
> @@ -44,8 +44,8 @@
> quiet_cmd_install = INSTALL $(printdir) ($(words $(all-files))\
> file$(if $(word 2, $(all-files)),s))
> cmd_install = \
> - $(PERL) $< $(srctree)/$(obj) $(install) $(SRCARCH) $(header-y); \
> - $(PERL) $< $(objtree)/$(obj) $(install) $(SRCARCH) $(objhdr-y); \
> + $(CONFIG_SHELL) $< $(srctree)/$(obj) $(install) $(SRCARCH) $(header-y); \
> + $(CONFIG_SHELL) $< $(objtree)/$(obj) $(install) $(SRCARCH) $(objhdr-y); \
Stick to the coding style i the file and do not add your own.
Makefile.headersinst uses tabs for commands and not for indent.
Sam
^ permalink raw reply
* Re: [PATCH 1/3]: Replace kernel/timeconst.pl with kernel/timeconst.sh
From: Sam Ravnborg @ 2009-01-02 9:04 UTC (permalink / raw)
To: Rob Landley
Cc: Embedded Linux mailing list, linux-kernel, Andrew Morton,
H. Peter Anvin
In-Reply-To: <200901020213.30658.rob@landley.net>
Hi Rob.
On Fri, Jan 02, 2009 at 02:13:30AM -0600, Rob Landley wrote:
> From: Rob Landley <rob@landley.net>
>
> Replace kernel/timeconst.pl with kernel/timeconst.sh. The new shell script
> is much simpler, about 1/4 the size, and runs on Red Hat 9 from 2003.
This part of the changelog is OK except that is fails to
address why we want to get away from perl.
Please drop the remining part of the changelog (but not the s-o-b).
> Peter Anvin added this perl to 2.6.25. Before that, the kernel had never
> required perl to build.
>
> Signed-off-by: Rob Landley <rob@landley.net>
> ---
>
> kernel/Makefile | 4
> kernel/timeconst.pl | 378 ------------------------------------------
> kernel/timeconst.sh | 91 ++++++++++
> 3 files changed, 93 insertions(+), 380 deletions(-)
>
> diff -r d0c7611dcfd6 kernel/Makefile
> --- a/kernel/Makefile Tue Dec 30 17:48:25 2008 -0800
> +++ b/kernel/Makefile Fri Jan 02 00:10:44 2009 -0600
> @@ -115,7 +115,7 @@
> $(obj)/time.o: $(obj)/timeconst.h
>
> quiet_cmd_timeconst = TIMEC $@
> - cmd_timeconst = $(PERL) $< $(CONFIG_HZ) > $@
> + cmd_timeconst = $(CONFIG_SHELL) $< $(CONFIG_HZ) > $@
> targets += timeconst.h
> -$(obj)/timeconst.h: $(src)/timeconst.pl FORCE
> +$(obj)/timeconst.h: $(src)/timeconst.sh FORCE
> $(call if_changed,timeconst)
OK
> --- /dev/null 1969-12-31 00:00:00.000000000 -0600
> +++ hg/kernel/timeconst.sh 2009-01-01 23:53:17.000000000 -0600
> @@ -0,0 +1,91 @@
> +#!/bin/bash
> +
> +if [ $# -ne 1 ]
> +then
> + echo "Usage: timeconst.sh HZ"
> + exit 1
> +fi
That usage is useless. Either extend it or spend a few lines
in the shell script explainign what the shell script is supposed to do.
> +
> +HZ=$1
> +
> +# Sanity test: even the shell in Red Hat 9 (circa 2003) supported 64 bit math.
> +
> +[ $((1<<32)) -lt 0 ] && exit 1
> +
If it fails then add an error message explaining why. So if we get reports that this
fails then we at least can see something like:
"timeconst noticed that the shell did not support 64 bit math - stop"
> +# Output start of header file
> +
> +cat << EOF
> +/* Automatically generated by kernel/timeconst.sh */
> +/* Conversion constants for HZ == $HZ */
> +
> +#ifndef KERNEL_TIMECONST_H
> +#define KERNEL_TIMECONST_H
Please use __KERNEL_TIMECONST_H. The two underscores are standard.
> +
> +#include <linux/param.h>
> +#include <linux/types.h>
> +
> +#if HZ != $HZ
> +#error "kernel/timeconst.h has the wrong HZ value!"
> +#endif
> +
> +EOF
> +
> +# For both Miliseconds and Microseconds
> +
> +for i in "MSEC 1000" "USEC 1000000"
> +do
> + NAME=$(echo $i | awk '{print $1}')
> + PERIOD=$(echo $i | awk '{print $2}')
> +
> + # Find greatest common denominator (using Euclid's algorithm)
> +
> + A=$HZ
> + B=$PERIOD
> +
> + while [ $B -ne 0 ]
> + do
> + C=$(($A%$B))
> + A=$B
> + B=$C
> + done
> +
> + GCD=$A
> +
> + # Do this for each direction (HZ_TO_PERIOD and PERIOD_TO_HZ)
> +
> + for DIRECTION in 0 1
> + do
> + if [ $DIRECTION -eq 0 ]
> + then
> + CONVERT="HZ_TO_${NAME}"
> + FROM=$HZ
> + TO=$PERIOD
> + else
> + CONVERT="${NAME}_TO_HZ"
> + FROM=$PERIOD
> + TO=$HZ
> + fi
> +
> + # How many shift bits give 32 bits of significant data?
> +
> + SHIFT=0
> + while [ $(( (($TO<<$SHIFT)+$FROM-1)/$FROM )) -lt $((1<<31)) ]
> + do
> + SHIFT=$(( $SHIFT+1 ))
> + done
> +
> + MUL32=$(( (($TO<<$SHIFT)+$FROM-1)/$FROM ))
> + MUL32=$(printf %x $MUL32)
> + echo "#define ${CONVERT}_MUL32 U64_C(0x$MUL32)"
> + ADJ32=$(($FROM/$GCD))
> + ADJ32=$(( (($ADJ32-1)<<$SHIFT)/$ADJ32 ))
> + ADJ32=$(printf %x $ADJ32)
> + echo "#define ${CONVERT}_ADJ32 U64_C(0x$ADJ32)"
> + echo "#define ${CONVERT}_SHR32 $SHIFT"
> + echo "#define ${CONVERT}_NUM U64_C($(($TO/$GCD)))"
> + echo "#define ${CONVERT}_DEN U64_C($(($FROM/$GCD)))"
> + done
> +done
Is it a shell limitation that all spaces around operators are missing?
Makes it hard to read..
You should use trap in your shell script so we do not end up with a
partially generated file.
Or you should change the rule in the Makefile to use
a temperary file and then rename it.
We have similar bugs in other places - but no need to add
in more places.
Sam
^ permalink raw reply
* [PATCH 3/3]: Convert mkcapflags.pl to mkcapflags.sh
From: Rob Landley @ 2009-01-02 8:15 UTC (permalink / raw)
To: Embedded Linux mailing list
Cc: linux-kernel, Andrew Morton, H. Peter Anvin, Sam Ravnborg
In-Reply-To: <200901020207.30359.rob@landley.net>
From: Rob Landley <rob@landley.net>
Convert kernel/cpu/mkcapflags.pl to kernel/cpu/mkcapflags.sh.
This script generates kernel/cpu/capflags.c from include/asm/cpufeature.h.
Peter Anvin added this perl to 2.6.28.
Signed-off-by: Rob Landley <rob@landley.net>
---
arch/x86/kernel/cpu/Makefile | 4 +--
arch/x86/kernel/cpu/mkcapflags.pl | 32 ----------------------------
arch/x86/kernel/cpu/mkcapflags.sh | 28 ++++++++++++++++++++++++
3 files changed, 30 insertions(+), 34 deletions(-)
diff -ruN alt-linux/arch/x86/kernel/cpu/Makefile alt-linux2/arch/x86/kernel/cpu/Makefile
--- alt-linux/arch/x86/kernel/cpu/Makefile 2008-12-24 17:26:37.000000000 -0600
+++ alt-linux2/arch/x86/kernel/cpu/Makefile 2008-12-28 18:10:51.000000000 -0600
@@ -23,10 +23,10 @@
obj-$(CONFIG_X86_LOCAL_APIC) += perfctr-watchdog.o
quiet_cmd_mkcapflags = MKCAP $@
- cmd_mkcapflags = $(PERL) $(srctree)/$(src)/mkcapflags.pl $< $@
+ cmd_mkcapflags = $(CONFIG_SHELL) $(srctree)/$(src)/mkcapflags.sh $< $@
cpufeature = $(src)/../../include/asm/cpufeature.h
targets += capflags.c
-$(obj)/capflags.c: $(cpufeature) $(src)/mkcapflags.pl FORCE
+$(obj)/capflags.c: $(cpufeature) $(src)/mkcapflags.sh FORCE
$(call if_changed,mkcapflags)
diff -ruN alt-linux/arch/x86/kernel/cpu/mkcapflags.pl alt-linux2/arch/x86/kernel/cpu/mkcapflags.pl
--- alt-linux/arch/x86/kernel/cpu/mkcapflags.pl 2008-12-24 17:26:37.000000000 -0600
+++ alt-linux2/arch/x86/kernel/cpu/mkcapflags.pl 1969-12-31 18:00:00.000000000 -0600
@@ -1,32 +0,0 @@
-#!/usr/bin/perl
-#
-# Generate the x86_cap_flags[] array from include/asm-x86/cpufeature.h
-#
-
-($in, $out) = @ARGV;
-
-open(IN, "< $in\0") or die "$0: cannot open: $in: $!\n";
-open(OUT, "> $out\0") or die "$0: cannot create: $out: $!\n";
-
-print OUT "#include <asm/cpufeature.h>\n\n";
-print OUT "const char * const x86_cap_flags[NCAPINTS*32] = {\n";
-
-while (defined($line = <IN>)) {
- if ($line =~ /^\s*\#\s*define\s+(X86_FEATURE_(\S+))\s+(.*)$/) {
- $macro = $1;
- $feature = $2;
- $tail = $3;
- if ($tail =~ /\/\*\s*\"([^"]*)\".*\*\//) {
- $feature = $1;
- }
-
- if ($feature ne '') {
- printf OUT "\t%-32s = \"%s\",\n",
- "[$macro]", "\L$feature";
- }
- }
-}
-print OUT "};\n";
-
-close(IN);
-close(OUT);
diff -ruN alt-linux/arch/x86/kernel/cpu/mkcapflags.sh alt-linux2/arch/x86/kernel/cpu/mkcapflags.sh
--- alt-linux/arch/x86/kernel/cpu/mkcapflags.sh 1969-12-31 18:00:00.000000000 -0600
+++ alt-linux2/arch/x86/kernel/cpu/mkcapflags.sh 2008-12-28 18:08:50.000000000 -0600
@@ -0,0 +1,28 @@
+#!/bin/bash
+#
+# Generate the x86_cap_flags[] array from include/asm/cpufeature.h
+#
+
+IN=$1
+OUT=$2
+
+(
+ echo "#include <asm/cpufeature.h>"
+ echo ""
+ echo "const char * const x86_cap_flags[NCAPINTS*32] = {"
+
+ # Iterate through any input lines starting with #define X86_FEATURE_
+ sed -n -e 's/\t/ /g' -e 's/^ *# *define *X86_FEATURE_//p' $IN |
+ while read i
+ do
+ # Name is everything up to the first whitespace
+ NAME="$(echo "$i" | sed 's/ .*//')"
+
+ # If the /* comment */ starts with a quote string, grab that.
+ VALUE="$(echo "$i" | sed -n 's@.*/\* *\("[^"]*"\).*\*/@\1@p')"
+ [ -z "$VALUE" ] && VALUE="\"$(echo "$NAME" | tr A-Z a-z)\""
+
+ [ "$VALUE" != '""' ] && echo " [X86_FEATURE_$NAME] = $VALUE,"
+ done
+ echo "};"
+) > $OUT
\0
^ permalink raw reply
* [PATCH 2/3]: Remove perl from make headers_install
From: Rob Landley @ 2009-01-02 8:14 UTC (permalink / raw)
To: Embedded Linux mailing list
Cc: linux-kernel, Andrew Morton, H. Peter Anvin, Sam Ravnborg
In-Reply-To: <200901020207.30359.rob@landley.net>
From: Rob Landley <rob@landley.net>
Remove perl from make headers_install by replacing a perl script (doing
a simple regex search and replace) with a smaller and faster shell script
implementation. The new shell script is a single for loop calling sed and
piping its output through unifdef to produce the target file.
Sam Ravnborg added this perl to 2.6.27.
Signed-off-by: Rob Landley <rob@landley.net>
---
scripts/Makefile.headersinst | 6 ++--
scripts/headers_install.pl | 46 ---------------------------------
scripts/headers_install.sh | 23 ++++++++++++++++
3 files changed, 26 insertions(+), 49 deletions(-)
--- /dev/null 2008-11-21 04:46:41.000000000 -0600
+++ b/scripts/headers_install.sh 2008-12-15 22:09:45.000000000 -0600
@@ -0,0 +1,23 @@
+#!/bin/bash
+
+# Grab arguments
+
+INDIR="$1"
+shift
+OUTDIR="$1"
+shift
+ARCH="$1"
+shift
+
+# Iterate through files listed on command line
+
+for i in "$@"
+do
+ sed -r \
+ -e 's/([ \t(])(__user|__force|__iomem)[ \t]/\1/g' \
+ -e 's/__attribute_const__([ \t]|$)/\1/g' \
+ -e 's@^#include <linux/compiler.h>@@' "$INDIR/$i" |
+ scripts/unifdef -U__KERNEL__ - > "$OUTDIR/$i"
+done
+
+exit 0
diff -r d9b501c91442 scripts/Makefile.headersinst
--- a/scripts/Makefile.headersinst Sun Dec 14 16:25:19 2008 -0800
+++ b/scripts/Makefile.headersinst Mon Dec 15 23:30:15 2008 -0600
@@ -44,8 +44,8 @@
quiet_cmd_install = INSTALL $(printdir) ($(words $(all-files))\
file$(if $(word 2, $(all-files)),s))
cmd_install = \
- $(PERL) $< $(srctree)/$(obj) $(install) $(SRCARCH) $(header-y); \
- $(PERL) $< $(objtree)/$(obj) $(install) $(SRCARCH) $(objhdr-y); \
+ $(CONFIG_SHELL) $< $(srctree)/$(obj) $(install) $(SRCARCH) $(header-y); \
+ $(CONFIG_SHELL) $< $(objtree)/$(obj) $(install) $(SRCARCH) $(objhdr-y); \
touch $@
quiet_cmd_remove = REMOVE $(unwanted)
@@ -64,7 +64,7 @@
@:
targets += $(install-file)
-$(install-file): scripts/headers_install.pl $(input-files) FORCE
+$(install-file): scripts/headers_install.sh $(input-files) FORCE
$(if $(unwanted),$(call cmd,remove),)
$(if $(wildcard $(dir $@)),,$(shell mkdir -p $(dir $@)))
$(call if_changed,install)
--- hg/scripts/headers_install.pl 2008-11-22 19:09:21.000000000 -0600
+++ /dev/null 1970-01-01 00:00:00 -0600
@@ -1,46 +0,0 @@
-#!/usr/bin/perl -w
-#
-# headers_install prepare the listed header files for use in
-# user space and copy the files to their destination.
-#
-# Usage: headers_install.pl readdir installdir arch [files...]
-# readdir: dir to open files
-# installdir: dir to install the files
-# arch: current architecture
-# arch is used to force a reinstallation when the arch
-# changes because kbuild then detect a command line change.
-# files: list of files to check
-#
-# Step in preparation for users space:
-# 1) Drop all use of compiler.h definitions
-# 2) Drop include of compiler.h
-# 3) Drop all sections defined out by __KERNEL__ (using unifdef)
-
-use strict;
-
-my ($readdir, $installdir, $arch, @files) = @ARGV;
-
-my $unifdef = "scripts/unifdef -U__KERNEL__";
-
-foreach my $file (@files) {
- local *INFILE;
- local *OUTFILE;
- my $tmpfile = "$installdir/$file.tmp";
- open(INFILE, "<$readdir/$file")
- or die "$readdir/$file: $!\n";
- open(OUTFILE, ">$tmpfile") or die "$tmpfile: $!\n";
- while (my $line = <INFILE>) {
- $line =~ s/([\s(])__user\s/$1/g;
- $line =~ s/([\s(])__force\s/$1/g;
- $line =~ s/([\s(])__iomem\s/$1/g;
- $line =~ s/\s__attribute_const__\s/ /g;
- $line =~ s/\s__attribute_const__$//g;
- $line =~ s/^#include <linux\/compiler.h>//;
- printf OUTFILE "%s", $line;
- }
- close OUTFILE;
- close INFILE;
- system $unifdef . " $tmpfile > $installdir/$file";
- unlink $tmpfile;
-}
-exit 0;
\0
^ permalink raw reply
* [PATCH 1/3]: Replace kernel/timeconst.pl with kernel/timeconst.sh
From: Rob Landley @ 2009-01-02 8:13 UTC (permalink / raw)
To: Embedded Linux mailing list
Cc: linux-kernel, Andrew Morton, H. Peter Anvin, Sam Ravnborg
In-Reply-To: <200901020207.30359.rob@landley.net>
From: Rob Landley <rob@landley.net>
Replace kernel/timeconst.pl with kernel/timeconst.sh. The new shell script
is much simpler, about 1/4 the size, and runs on Red Hat 9 from 2003.
Peter Anvin added this perl to 2.6.25. Before that, the kernel had never
required perl to build.
Signed-off-by: Rob Landley <rob@landley.net>
---
kernel/Makefile | 4
kernel/timeconst.pl | 378 ------------------------------------------
kernel/timeconst.sh | 91 ++++++++++
3 files changed, 93 insertions(+), 380 deletions(-)
diff -r d0c7611dcfd6 kernel/Makefile
--- a/kernel/Makefile Tue Dec 30 17:48:25 2008 -0800
+++ b/kernel/Makefile Fri Jan 02 00:10:44 2009 -0600
@@ -115,7 +115,7 @@
$(obj)/time.o: $(obj)/timeconst.h
quiet_cmd_timeconst = TIMEC $@
- cmd_timeconst = $(PERL) $< $(CONFIG_HZ) > $@
+ cmd_timeconst = $(CONFIG_SHELL) $< $(CONFIG_HZ) > $@
targets += timeconst.h
-$(obj)/timeconst.h: $(src)/timeconst.pl FORCE
+$(obj)/timeconst.h: $(src)/timeconst.sh FORCE
$(call if_changed,timeconst)
--- /dev/null 1969-12-31 00:00:00.000000000 -0600
+++ hg/kernel/timeconst.sh 2009-01-01 23:53:17.000000000 -0600
@@ -0,0 +1,91 @@
+#!/bin/bash
+
+if [ $# -ne 1 ]
+then
+ echo "Usage: timeconst.sh HZ"
+ exit 1
+fi
+
+HZ=$1
+
+# Sanity test: even the shell in Red Hat 9 (circa 2003) supported 64 bit math.
+
+[ $((1<<32)) -lt 0 ] && exit 1
+
+# Output start of header file
+
+cat << EOF
+/* Automatically generated by kernel/timeconst.sh */
+/* Conversion constants for HZ == $HZ */
+
+#ifndef KERNEL_TIMECONST_H
+#define KERNEL_TIMECONST_H
+
+#include <linux/param.h>
+#include <linux/types.h>
+
+#if HZ != $HZ
+#error "kernel/timeconst.h has the wrong HZ value!"
+#endif
+
+EOF
+
+# For both Miliseconds and Microseconds
+
+for i in "MSEC 1000" "USEC 1000000"
+do
+ NAME=$(echo $i | awk '{print $1}')
+ PERIOD=$(echo $i | awk '{print $2}')
+
+ # Find greatest common denominator (using Euclid's algorithm)
+
+ A=$HZ
+ B=$PERIOD
+
+ while [ $B -ne 0 ]
+ do
+ C=$(($A%$B))
+ A=$B
+ B=$C
+ done
+
+ GCD=$A
+
+ # Do this for each direction (HZ_TO_PERIOD and PERIOD_TO_HZ)
+
+ for DIRECTION in 0 1
+ do
+ if [ $DIRECTION -eq 0 ]
+ then
+ CONVERT="HZ_TO_${NAME}"
+ FROM=$HZ
+ TO=$PERIOD
+ else
+ CONVERT="${NAME}_TO_HZ"
+ FROM=$PERIOD
+ TO=$HZ
+ fi
+
+ # How many shift bits give 32 bits of significant data?
+
+ SHIFT=0
+ while [ $(( (($TO<<$SHIFT)+$FROM-1)/$FROM )) -lt $((1<<31)) ]
+ do
+ SHIFT=$(( $SHIFT+1 ))
+ done
+
+ MUL32=$(( (($TO<<$SHIFT)+$FROM-1)/$FROM ))
+ MUL32=$(printf %x $MUL32)
+ echo "#define ${CONVERT}_MUL32 U64_C(0x$MUL32)"
+ ADJ32=$(($FROM/$GCD))
+ ADJ32=$(( (($ADJ32-1)<<$SHIFT)/$ADJ32 ))
+ ADJ32=$(printf %x $ADJ32)
+ echo "#define ${CONVERT}_ADJ32 U64_C(0x$ADJ32)"
+ echo "#define ${CONVERT}_SHR32 $SHIFT"
+ echo "#define ${CONVERT}_NUM U64_C($(($TO/$GCD)))"
+ echo "#define ${CONVERT}_DEN U64_C($(($FROM/$GCD)))"
+ done
+done
+
+echo
+echo "#endif /* KERNEL_TIMECHONST_H */"
--- hg/kernel/timeconst.pl 2008-11-22 19:09:13.000000000 -0600
+++ /dev/null 1969-12-31 00:00:00.000000000 -0600
@@ -1,378 +0,0 @@
-#!/usr/bin/perl
-# -----------------------------------------------------------------------
-#
-# Copyright 2007-2008 rPath, Inc. - All Rights Reserved
-#
-# This file is part of the Linux kernel, and is made available under
-# the terms of the GNU General Public License version 2 or (at your
-# option) any later version; incorporated herein by reference.
-#
-# -----------------------------------------------------------------------
-#
-
-#
-# Usage: timeconst.pl HZ > timeconst.h
-#
-
-# Precomputed values for systems without Math::BigInt
-# Generated by:
-# timeconst.pl --can 24 32 48 64 100 122 128 200 250 256 300 512 1000 1024 1200
-%canned_values = (
- 24 => [
- '0xa6aaaaab','0x2aaaaaa',26,
- 125,3,
- '0xc49ba5e4','0x1fbe76c8b4',37,
- 3,125,
- '0xa2c2aaab','0xaaaa',16,
- 125000,3,
- '0xc9539b89','0x7fffbce4217d',47,
- 3,125000,
- ], 32 => [
- '0xfa000000','0x6000000',27,
- 125,4,
- '0x83126e98','0xfdf3b645a',36,
- 4,125,
- '0xf4240000','0x0',17,
- 31250,1,
- '0x8637bd06','0x3fff79c842fa',46,
- 1,31250,
- ], 48 => [
- '0xa6aaaaab','0x6aaaaaa',27,
- 125,6,
- '0xc49ba5e4','0xfdf3b645a',36,
- 6,125,
- '0xa2c2aaab','0x15555',17,
- 62500,3,
- '0xc9539b89','0x3fffbce4217d',46,
- 3,62500,
- ], 64 => [
- '0xfa000000','0xe000000',28,
- 125,8,
- '0x83126e98','0x7ef9db22d',35,
- 8,125,
- '0xf4240000','0x0',18,
- 15625,1,
- '0x8637bd06','0x1fff79c842fa',45,
- 1,15625,
- ], 100 => [
- '0xa0000000','0x0',28,
- 10,1,
- '0xcccccccd','0x733333333',35,
- 1,10,
- '0x9c400000','0x0',18,
- 10000,1,
- '0xd1b71759','0x1fff2e48e8a7',45,
- 1,10000,
- ], 122 => [
- '0x8325c53f','0xfbcda3a',28,
- 500,61,
- '0xf9db22d1','0x7fbe76c8b',35,
- 61,500,
- '0x8012e2a0','0x3ef36',18,
- 500000,61,
- '0xffda4053','0x1ffffbce4217',45,
- 61,500000,
- ], 128 => [
- '0xfa000000','0x1e000000',29,
- 125,16,
- '0x83126e98','0x3f7ced916',34,
- 16,125,
- '0xf4240000','0x40000',19,
- 15625,2,
- '0x8637bd06','0xfffbce4217d',44,
- 2,15625,
- ], 200 => [
- '0xa0000000','0x0',29,
- 5,1,
- '0xcccccccd','0x333333333',34,
- 1,5,
- '0x9c400000','0x0',19,
- 5000,1,
- '0xd1b71759','0xfff2e48e8a7',44,
- 1,5000,
- ], 250 => [
- '0x80000000','0x0',29,
- 4,1,
- '0x80000000','0x180000000',33,
- 1,4,
- '0xfa000000','0x0',20,
- 4000,1,
- '0x83126e98','0x7ff7ced9168',43,
- 1,4000,
- ], 256 => [
- '0xfa000000','0x3e000000',30,
- 125,32,
- '0x83126e98','0x1fbe76c8b',33,
- 32,125,
- '0xf4240000','0xc0000',20,
- 15625,4,
- '0x8637bd06','0x7ffde7210be',43,
- 4,15625,
- ], 300 => [
- '0xd5555556','0x2aaaaaaa',30,
- 10,3,
- '0x9999999a','0x1cccccccc',33,
- 3,10,
- '0xd0555556','0xaaaaa',20,
- 10000,3,
- '0x9d495183','0x7ffcb923a29',43,
- 3,10000,
- ], 512 => [
- '0xfa000000','0x7e000000',31,
- 125,64,
- '0x83126e98','0xfdf3b645',32,
- 64,125,
- '0xf4240000','0x1c0000',21,
- 15625,8,
- '0x8637bd06','0x3ffef39085f',42,
- 8,15625,
- ], 1000 => [
- '0x80000000','0x0',31,
- 1,1,
- '0x80000000','0x0',31,
- 1,1,
- '0xfa000000','0x0',22,
- 1000,1,
- '0x83126e98','0x1ff7ced9168',41,
- 1,1000,
- ], 1024 => [
- '0xfa000000','0xfe000000',32,
- 125,128,
- '0x83126e98','0x7ef9db22',31,
- 128,125,
- '0xf4240000','0x3c0000',22,
- 15625,16,
- '0x8637bd06','0x1fff79c842f',41,
- 16,15625,
- ], 1200 => [
- '0xd5555556','0xd5555555',32,
- 5,6,
- '0x9999999a','0x66666666',31,
- 6,5,
- '0xd0555556','0x2aaaaa',22,
- 2500,3,
- '0x9d495183','0x1ffcb923a29',41,
- 3,2500,
- ]
-);
-
-$has_bigint = eval 'use Math::BigInt qw(bgcd); 1;';
-
-sub bint($)
-{
- my($x) = @_;
- return Math::BigInt->new($x);
-}
-
-#
-# Constants for division by reciprocal multiplication.
-# (bits, numerator, denominator)
-#
-sub fmul($$$)
-{
- my ($b,$n,$d) = @_;
-
- $n = bint($n);
- $d = bint($d);
-
- return scalar (($n << $b)+$d-bint(1))/$d;
-}
-
-sub fadj($$$)
-{
- my($b,$n,$d) = @_;
-
- $n = bint($n);
- $d = bint($d);
-
- $d = $d/bgcd($n, $d);
- return scalar (($d-bint(1)) << $b)/$d;
-}
-
-sub fmuls($$$) {
- my($b,$n,$d) = @_;
- my($s,$m);
- my($thres) = bint(1) << ($b-1);
-
- $n = bint($n);
- $d = bint($d);
-
- for ($s = 0; 1; $s++) {
- $m = fmul($s,$n,$d);
- return $s if ($m >= $thres);
- }
- return 0;
-}
-
-# Generate a hex value if the result fits in 64 bits;
-# otherwise skip.
-sub bignum_hex($) {
- my($x) = @_;
- my $s = $x->as_hex();
-
- return (length($s) > 18) ? undef : $s;
-}
-
-# Provides mul, adj, and shr factors for a specific
-# (bit, time, hz) combination
-sub muladj($$$) {
- my($b, $t, $hz) = @_;
- my $s = fmuls($b, $t, $hz);
- my $m = fmul($s, $t, $hz);
- my $a = fadj($s, $t, $hz);
- return (bignum_hex($m), bignum_hex($a), $s);
-}
-
-# Provides numerator, denominator values
-sub numden($$) {
- my($n, $d) = @_;
- my $g = bgcd($n, $d);
- return ($n/$g, $d/$g);
-}
-
-# All values for a specific (time, hz) combo
-sub conversions($$) {
- my ($t, $hz) = @_;
- my @val = ();
-
- # HZ_TO_xx
- push(@val, muladj(32, $t, $hz));
- push(@val, numden($t, $hz));
-
- # xx_TO_HZ
- push(@val, muladj(32, $hz, $t));
- push(@val, numden($hz, $t));
-
- return @val;
-}
-
-sub compute_values($) {
- my($hz) = @_;
- my @val = ();
- my $s, $m, $a, $g;
-
- if (!$has_bigint) {
- die "$0: HZ == $hz not canned and ".
- "Math::BigInt not available\n";
- }
-
- # MSEC conversions
- push(@val, conversions(1000, $hz));
-
- # USEC conversions
- push(@val, conversions(1000000, $hz));
-
- return @val;
-}
-
-sub outputval($$)
-{
- my($name, $val) = @_;
- my $csuf;
-
- if (defined($val)) {
- if ($name !~ /SHR/) {
- $val = "U64_C($val)";
- }
- printf "#define %-23s %s\n", $name.$csuf, $val.$csuf;
- }
-}
-
-sub output($@)
-{
- my($hz, @val) = @_;
- my $pfx, $bit, $suf, $s, $m, $a;
-
- print "/* Automatically generated by kernel/timeconst.pl */\n";
- print "/* Conversion constants for HZ == $hz */\n";
- print "\n";
- print "#ifndef KERNEL_TIMECONST_H\n";
- print "#define KERNEL_TIMECONST_H\n";
- print "\n";
-
- print "#include <linux/param.h>\n";
- print "#include <linux/types.h>\n";
-
- print "\n";
- print "#if HZ != $hz\n";
- print "#error \"kernel/timeconst.h has the wrong HZ value!\"\n";
- print "#endif\n";
- print "\n";
-
- foreach $pfx ('HZ_TO_MSEC','MSEC_TO_HZ',
- 'HZ_TO_USEC','USEC_TO_HZ') {
- foreach $bit (32) {
- foreach $suf ('MUL', 'ADJ', 'SHR') {
- outputval("${pfx}_$suf$bit", shift(@val));
- }
- }
- foreach $suf ('NUM', 'DEN') {
- outputval("${pfx}_$suf", shift(@val));
- }
- }
-
- print "\n";
- print "#endif /* KERNEL_TIMECONST_H */\n";
-}
-
-# Pretty-print Perl values
-sub perlvals(@) {
- my $v;
- my @l = ();
-
- foreach $v (@_) {
- if (!defined($v)) {
- push(@l, 'undef');
- } elsif ($v =~ /^0x/) {
- push(@l, "\'".$v."\'");
- } else {
- push(@l, $v.'');
- }
- }
- return join(',', @l);
-}
-
-($hz) = @ARGV;
-
-# Use this to generate the %canned_values structure
-if ($hz eq '--can') {
- shift(@ARGV);
- @hzlist = sort {$a <=> $b} (@ARGV);
-
- print "# Precomputed values for systems without Math::BigInt\n";
- print "# Generated by:\n";
- print "# timeconst.pl --can ", join(' ', @hzlist), "\n";
- print "\%canned_values = (\n";
- my $pf = "\t";
- foreach $hz (@hzlist) {
- my @values = compute_values($hz);
- print "$pf$hz => [\n";
- while (scalar(@values)) {
- my $bit;
- foreach $bit (32) {
- my $m = shift(@values);
- my $a = shift(@values);
- my $s = shift(@values);
- print "\t\t", perlvals($m,$a,$s), ",\n";
- }
- my $n = shift(@values);
- my $d = shift(@values);
- print "\t\t", perlvals($n,$d), ",\n";
- }
- print "\t]";
- $pf = ', ';
- }
- print "\n);\n";
-} else {
- $hz += 0; # Force to number
- if ($hz < 1) {
- die "Usage: $0 HZ\n";
- }
-
- @val = @{$canned_values{$hz}};
- if (!defined(@val)) {
- @val = compute_values($hz);
- }
- output($hz, @val);
-}
-exit 0;
\0
^ permalink raw reply
* PATCH [0/3]: Simplify the kernel build by removing perl.
From: Rob Landley @ 2009-01-02 8:07 UTC (permalink / raw)
To: Embedded Linux mailing list
Cc: linux-kernel, Andrew Morton, H. Peter Anvin, Sam Ravnborg
Before 2.6.25 (specifically git bdc807871d58285737d50dc6163d0feb72cb0dc2 )
building a Linux kernel never required perl to be installed on the build
system. (Various development and debugging scripts were written in perl and
python and such, but they weren't involved in actually building a kernel.)
Building a kernel before 2.6.25 could be done with a minimal system built from
gcc, binutils, bash, make, busybox, uClibc, and the Linux kernel, and nothing
else. (Embedded developers creating clean cross compile environments that
won't leak bits of the host system into the target, or bootstrapping native
development environments to run on target hardware or under emulators, tend to
care about this sort of thing.)
The perl checkin for 2.6.25 was the camel's nose under the tent flap, and
since then two more instances of perl have shown up in the core kernel build.
This patch series removes the three required to build a basic kernel for qemu
for the targets I've tested (arm, mips, powerpc, sparc, m68k, sh4, and of
course x86 and x86-64), replacing them with shell scripts.
Historically the kernel has gone out of its way to minimize environmental
dependencies for the build. For example, the plethora of *_shipped files mean
we don't need lex and yacc to build the kernel. The kconfig infrastructure
once required curses to run "make oldconfig", but that requirement was
restricted to just menuconfig so the kernel could build on systems without
ncurses.
That was a very nice policy. Kernel development already requires an in-depth
knowledge of C, make, and shell, plus things like the kconfig language. A
similarly in-depth knowledge of perl is bigger than all that combined (even
Larry Wall probably doesn't know all of Perl anymore), and then what's the
excuse _not_ to add Python to the core build? And after that why not java, or
lua? Where does it end? What's the criteria to say "no" here?
This patch series saves time and says no now.
^ permalink raw reply
* Re: [RFC 2.6.27 1/1] gpiolib: add support for batch set of pins
From: Jaya Kumar @ 2008-12-31 18:05 UTC (permalink / raw)
To: Robin Getz
Cc: David Brownell, Eric Miao, Sam Ravnborg, Eric Miao,
Haavard Skinnemoen, Philipp Zabel, Russell King, Ben Gardner,
Greg KH, linux-arm-kernel, linux-fbdev-devel, linux-kernel,
linux-embedded
In-Reply-To: <200812311238.13810.rgetz@blackfin.uclinux.org>
On Thu, Jan 1, 2009 at 1:38 AM, Robin Getz <rgetz@blackfin.uclinux.org> wrote:
> On Tue 30 Dec 2008 23:58, Jaya Kumar pondered:
>> On Tue, Dec 30, 2008 at 11:55 PM, Robin Getz <rgetz@blackfin.uclinux.org> wrote:
>> > Yeah, I hadn't thought about spanning more than one gpio_chip. That's a good
>> > point.
>>
>> The currently posted code already supports spanning more than one gpio_chip.
>>
>
> But doesn't do all the other things that David suggested/requested.
>
Hi Robin,
Yes, you are right. My implementation does not support a driver that
needs to set/get more than 32-bits of gpio in a single call. I'm okay
with that restriction as I don't see a concrete use case for that. I
understand that you're saying that's not satisfactory. I guess we'll
have to agree to differ.
Thanks,
jaya
^ permalink raw reply
* Re: [RFC 2.6.27 1/1] gpiolib: add support for batch set of pins
From: Robin Getz @ 2008-12-31 17:38 UTC (permalink / raw)
To: Jaya Kumar
Cc: David Brownell, Eric Miao, Sam Ravnborg, Eric Miao,
Haavard Skinnemoen, Philipp Zabel, Russell King, Ben Gardner,
Greg KH, linux-arm-kernel, linux-fbdev-devel, linux-kernel,
linux-embedded
In-Reply-To: <45a44e480812302058k365eddcfxf902095657b78534@mail.gmail.com>
On Tue 30 Dec 2008 23:58, Jaya Kumar pondered:
> On Tue, Dec 30, 2008 at 11:55 PM, Robin Getz <rgetz@blackfin.uclinux.org> wrote:
> > Yeah, I hadn't thought about spanning more than one gpio_chip. That's a good
> > point.
>
> The currently posted code already supports spanning more than one gpio_chip.
>
But doesn't do all the other things that David suggested/requested.
^ permalink raw reply
* Re: [RFC 2.6.27 1/1] gpiolib: add support for batch set of pins
From: Jaya Kumar @ 2008-12-31 5:02 UTC (permalink / raw)
To: Robin Getz
Cc: David Brownell, Eric Miao, Sam Ravnborg, Eric Miao,
Haavard Skinnemoen, Philipp Zabel, Russell King, Ben Gardner,
Greg KH, linux-arm-kernel, linux-fbdev-devel, linux-kernel,
linux-embedded
In-Reply-To: <45a44e480812302058k365eddcfxf902095657b78534@mail.gmail.com>
On Tue, Dec 30, 2008 at 11:58 PM, Jaya Kumar <jayakumar.lkml@gmail.com> wrote:
> On Tue, Dec 30, 2008 at 11:55 PM, Robin Getz <rgetz@blackfin.uclinux.org> wrote:
>> Yeah, I hadn't thought about spanning more than one gpio_chip. That's a good
>> point.
>
> The currently posted code already supports spanning more than one gpio_chip.
and btw, that was because the use case needed to span 2, since it
started at 58 and was 16 bits long on a platform where ngpio == 32.
this was explained at the start of the thread.
>
> + do {
> + chip = gpio_to_chip(gpio + i);
> + WARN_ON(extra_checks && chip->can_sleep);
> +
> + if (!chip->set_bus) {
> + while (((gpio + i) < (chip->base + chip->ngpio))
> + && bitwidth) {
> + value = values & (1 << i);
> + chip->set(chip, gpio + i - chip->base, value);
> + i++;
> + bitwidth--;
> + }
> + } else {
> + value = values >> i; /* shift off the used stuff */
> + remwidth = ((chip->base + (int) chip->ngpio) -
> + ((int) gpio + i));
> + width = min(bitwidth, remwidth);
> +
> + chip->set_bus(chip, gpio + i - chip->base, value,
> + width);
> + i += width;
> + bitwidth -= width;
> + }
> + } while (bitwidth);
>
^ permalink raw reply
* Re: [RFC 2.6.27 1/1] gpiolib: add support for batch set of pins
From: Jaya Kumar @ 2008-12-31 4:58 UTC (permalink / raw)
To: Robin Getz
Cc: David Brownell, Eric Miao, Sam Ravnborg, Eric Miao,
Haavard Skinnemoen, Philipp Zabel, Russell King, Ben Gardner,
Greg KH, linux-arm-kernel, linux-fbdev-devel, linux-kernel,
linux-embedded
In-Reply-To: <200812302355.45193.rgetz@blackfin.uclinux.org>
On Tue, Dec 30, 2008 at 11:55 PM, Robin Getz <rgetz@blackfin.uclinux.org> wrote:
> Yeah, I hadn't thought about spanning more than one gpio_chip. That's a good
> point.
The currently posted code already supports spanning more than one gpio_chip.
+ do {
+ chip = gpio_to_chip(gpio + i);
+ WARN_ON(extra_checks && chip->can_sleep);
+
+ if (!chip->set_bus) {
+ while (((gpio + i) < (chip->base + chip->ngpio))
+ && bitwidth) {
+ value = values & (1 << i);
+ chip->set(chip, gpio + i - chip->base, value);
+ i++;
+ bitwidth--;
+ }
+ } else {
+ value = values >> i; /* shift off the used stuff */
+ remwidth = ((chip->base + (int) chip->ngpio) -
+ ((int) gpio + i));
+ width = min(bitwidth, remwidth);
+
+ chip->set_bus(chip, gpio + i - chip->base, value,
+ width);
+ i += width;
+ bitwidth -= width;
+ }
+ } while (bitwidth);
^ permalink raw reply
* Re: [RFC 2.6.27 1/1] gpiolib: add support for batch set of pins
From: Robin Getz @ 2008-12-31 4:55 UTC (permalink / raw)
To: David Brownell
Cc: Jaya Kumar, Eric Miao, Sam Ravnborg, Eric Miao,
Haavard Skinnemoen, Philipp Zabel, Russell King, Ben Gardner,
Greg KH, linux-arm-kernel, linux-fbdev-devel, linux-kernel,
linux-embedded
In-Reply-To: <200812291156.12230.david-b@pacbell.net>
On Mon 29 Dec 2008 14:56, David Brownell pondered:
> On Sunday 28 December 2008, Robin Getz wrote:
> > On Sat 27 Dec 2008 09:55, Jaya Kumar pondered:
> >
> > I think that I would prefer 'group' or 'collection' to use some of
> > the words that David described things as 'ganged' or 'bus' or 'bank'
> > or 'adjacent'. (but I think 'adjacent' or 'bank' really is an
> > implementation convention).
> >
> > I think I would also prefer to name things like gpio_bus_* as a
> > rather than gpio_*_bus - so the operation always is on the end...
>
> I'd avoid "bus"; the term has specific meanings, which aren't
> necessarily relevant in these contexts. Agreed about "adjacent" and
> "bank".
>
> If it weren't for its verb usage, I'd suggest "set". :)
So, any suggestions? how about "gang" or "group"? or as you said
below "multiple".
> > Shouldn't the write return an error code (if the data was not
> > written)?
>
> For these operations, I think reads/writes should have that possibility.
>
> The reason single-bit operations don't provide error paths is twofold.
> First, they started as wrappers for can't-fail register accessors.
> Second, it's extremely unrealisitic to expect much code to handle any
> kind of faults in the middle of bitbanging loops ... or even just in
> classic "set this bit and continue" configuration code.
>
> Those reasons don't apply well to these multi-bit cases.
I'm just trying to think of what the error case might be. The only think I can
really think of - is the case where you try to do a set/get on something that
has been freed.
Otherwise - it should be pretty much the same. (basic bitbanging loops, which
call multiple/basic can't-fail register accessors).
> > > While we are here, I was thinking about it, and its better if I give
> > > gpio_request/free/direction_batch a miss for now. Nothing prevents
> > > those features being added at a later point.
> >
> > I don't think that request/free are optional.
>
> Agreed. If there's any difficulty implementing them, that would
> suggest there's a significant conceptual problem to address ...
>
> > For example - in most SoC implementations - gpios are implemented
> > as banks of 16 or 32. (a 16 or 32 bit register).
> >
> > Are there facilities to span these registers?
> > - can you request 64 gpios as a 'bank'?
> > - can you request gpio_8 -> gpio_40 as a 'bank' on a 32-bit system?
> >
> > Are non-adjacent/non-contiguous gpios avaliable to be put into
> > a 'bank/batch/bus'? can you use gpio_8 -> 11 & 28 -> 31 as a
> > 8-bit 'bus'?
> >
> > How do you know what is avaliable to be talked to as a bank/bus/batch
> > without the request/free operation?
> >
> >
> > I have seen various hardware designs (both at the PCB and SoC level)
> > require all of these options, and would like to see common
> > infrastructure which handles this.
>
> Right. Get the interface right -- it should allow all those
> complexities! -- and maybe take shortcuts in the first versions
> of the implementation, by only talking to one gpio_chip at a
> time. I'd expect any shortcuts would be resolved quickly, to
> the extent they cause problems.
Yeah, I hadn't thought about spanning more than one gpio_chip. That's a good
point.
> > The issue is that on many SoC implementations - dedicated peripherals
> > can also be GPIOs - so it someone wants to use SPI (for example) GPIO's
> > 3->7 might be removed from the avaliable 'gpio' resources. This is
> > determined by the silicon designer - and even the PCB designer has
> > little to no flexibility on this. It gets worse as multiple SPI or I2C
> > are used on the PCB (which can have lots of small (less than 5)
> > dedicated pins in the middle of the larger gpio resources)....
>
> Such pin-muxing is a different issue though. Don't expect GPIO
> calls to resolve those problems.
I wasn't trying to make the point about pin muxing (I agree - different
problem) - just that it is unlikely that the gang of gpios will be
adjacent/contiguous in most cases.
> > I would think that a 'bank' / 'bus' (whatever) would be a collection
> > of random/multiple GPIOs (a struct of gpio_port_t) rather than a
> > start/length (as you described) - or better yet - the request function
> > takes a list (of individual GPIO's - defined in the platform data),
> > and creates the struct itself.
>
> That's why I pointed to <linux/bitmask.h> as one model: it allows
> an arbitrary set of bits (GPIOs) to be specified.
I can see that being useful.
> I'll NAK any "gpio_port_t" name based entirely on kernel coding
> conventions though. ;)
>
>
> > Something like the way gpio_keys are defined...
> >
> > static struct gpio_bus bfin_gpio_bus_table[] = {
> > {BIT_0, GPIO_PB8, 1, "gpio-bus: BIT0"},
> > {BIT_1, GPIO_PB9, 1, "gpio-bus: BIT1"},
> > {BIT_2, GPIO_PB10, 1, "gpio-bus: BIT2"},
> > {BIT_3, GPIO_PB11, 1, "gpio-bus: BIT3"},
> > };
> >
> > static struct gpio_bus_data bfin_gpio_bus_data = {
> > .bits = bfin_gpio_bus_table,
> > .width = ARRAY_SIZE(bfin_gpio_keys_table),
> > };
> >
> > static struct platform_device bfin_device_gpiobus = {
> > .name = "gpio-bus",
> > .dev = {
> > .platform_data = &bfin_gpio_bus_data,
> > },
> > };
> >
> > The request function builds up the bus/masks/shifts from that...
>
> That sort of thing might be made to work. Whatever this
> multiple-GPIO-set abstraction is, I suspect you're right
> about wanting the request function to be able to build
> up some data structures behind it. And that it would be
> simpler to require all the GPIOs to be listed up front,
> rather than support "add these to the set" requests.
Yeah, I would prefer the data structures to 16 calls to a request function to
build up a 16-bit wide group...
^ permalink raw reply
* Re: [RFC 2.6.27 1/1] gpiolib: add support for batch set of pins
From: Jaya Kumar @ 2008-12-30 15:45 UTC (permalink / raw)
To: David Brownell
Cc: Eric Miao, Sam Ravnborg, Eric Miao, Haavard Skinnemoen,
Philipp Zabel, Russell King, Ben Gardner, Greg KH,
linux-arm-kernel, linux-fbdev-devel, linux-kernel, linux-embedded
In-Reply-To: <200812291132.14806.david-b@pacbell.net>
Hi David,
On Mon, Dec 29, 2008 at 2:32 PM, David Brownell <david-b@pacbell.net> wrote:
>
> - passing bitmasks as {unsigned long *bits, int count} tuples
> - separate calls to:
> * zero a set of bits (loop: gpio_set_value to 0)
> * fill a set of bits (loop: gpio_set_value to 1)
> * copy a set of bits (loop: gpio_set_value to src[i])
> * read a set of bits (loop: dst[i] = gpio_get_value)
> * ... maybe more
I had read bitmasks.h as per your recommendation and my thought on
that was: How do I reconcile such a substantial API when the use case
is just setting/getting a bunch of gpio pins?
>
> Any restriction to 32 bit value seems shortsighted. It would
> make sense to wrap the GPIO bitmask descriptions in a struct,
> letting drivers work with smaller sets -- probably most would
> fit into a single "unsigned long".
>
Hmm. Well. Currently, there's only been 1 bit support and its been
that way for years, hasn't it? It was not shortsighted at that time to
have only 1 bit access. No one raised a need for more. There weren't
any complaints about the 1-bit gpio API until am300epd.c came along.
You had correctly pointed out "I happen not to have come across the
need for such ganged access from Linux" in the start of this thread. I
think that you raised a strong point there. If I understood you
correctly, it implies it is NOT likely that there'll be many users of
this ganged access API.
Which is precisely why I took your suggestion to heart and stuck to
the middle path. For better or worse, we currently have a grand total
of just one use case for this ganged API: am300epd.c which does a
16-bit write. No one has spoken up with another concrete use case. So
I say we stick to the simple 32-bit startpin/mask/length API. Lets see
if people start using it. If more than a few do and issues are raised
with it being limited to "just 32 bits", then we can rearchitecht as
needed. After all, as you requested, it's an optional in-kernel only
API so we're in no danger of shooting ourselves in the foot here.
Further more, we've gone from years of 1-bit access with no complaints
to 32-bit access. A factor of 32 improvement seems a reasonably good
bet for the next few years to me. :-)
If any of my assertions are mistaken, I'll need your help to
understand which specific part of the conversation I've misunderstood.
Thanks,
jaya
^ permalink raw reply
* Re: [RFC 2.6.27 1/1] gpiolib: add support for batch set of pins
From: David Brownell @ 2008-12-30 0:43 UTC (permalink / raw)
To: Jamie Lokier
Cc: Robin Getz, Jaya Kumar, Eric Miao, Sam Ravnborg, Eric Miao,
Haavard Skinnemoen, Philipp Zabel, Russell King, Ben Gardner,
Greg KH, linux-arm-kernel, linux-fbdev-devel, linux-kernel,
linux-embedded
In-Reply-To: <20081230002023.GA5309@shareable.org>
On Monday 29 December 2008, Jamie Lokier wrote:
> David Brownell wrote:
> > The reason single-bit operations don't provide error paths is twofold.
> > First, they started as wrappers for can't-fail register accessors.
> > Second, it's extremely unrealisitic to expect much code to handle any
> > kind of faults in the middle of bitbanging loops ... or even just in
> > classic "set this bit and continue" configuration code.
>
> That's interesting. I'm not sure it's a good idea not to return an
> error code. The caller can just ignore it if they don't care, and
> it's extremely cheap to "return 0" in GPIO drivers which can't error.
I'm not sure either; at this point I *might* consider doing
it differently -- but primarily for the case of external GPIO
chips, e.g. over I2C or SPI -- where errors are realistic. But
it's been this way for a few years now, and changing stuff
that hasn't been observed to be a problem isn't on my list.
But as I noted: patches for $SUBJECT don't seem to have any
reason not to report whatever faults they encounter.
Also worth remembering: when reading a GPIO value, it's not
so easy to "ignore" a tristate (0, 1, error) return value.
> If I were bit-banging on GPIOs reached via some peripheral chip (such
> a GPIO-fanout chip over I2C/SPI, where that chip is itself feeding a
> secondary I2C or similar bit-banging bus), I probably would like to
> check for errors and take emergency action if the peripheral chip
> isn't responding, or just report to userspace.
If I had to do that, I'd *certainly* want to bang the hardware
designer over the head with some sort of cluebat or cluebrick. :(
> This has actually happened on a board I worked with, where the primary
> I2C failed due to a plugged in peripheral loading it too much, and a
> secondary bit-banging bus was not then reachable.
It should now be realistic for I2C device drivers to have
fault recovery logic...
But for a long time, I2c only returned -EPERM so it was
completely hopeless trying to figure out how to "handle"
any problem beyond logging the problem and hoping someone
is watching syslog output. That's a big part of why most
current I2C drivers have such unfriendly fault handling.
- Dave
>
> -- Jamie
>
>
^ permalink raw reply
* Re: [RFC 2.6.27 1/1] gpiolib: add support for batch set of pins
From: Jamie Lokier @ 2008-12-30 0:20 UTC (permalink / raw)
To: David Brownell
Cc: Robin Getz, Jaya Kumar, Eric Miao, Sam Ravnborg, Eric Miao,
Haavard Skinnemoen, Philipp Zabel, Russell King, Ben Gardner,
Greg KH, linux-arm-kernel, linux-fbdev-devel, linux-kernel,
linux-embedded
In-Reply-To: <200812291156.12230.david-b@pacbell.net>
David Brownell wrote:
> The reason single-bit operations don't provide error paths is twofold.
> First, they started as wrappers for can't-fail register accessors.
> Second, it's extremely unrealisitic to expect much code to handle any
> kind of faults in the middle of bitbanging loops ... or even just in
> classic "set this bit and continue" configuration code.
That's interesting. I'm not sure it's a good idea not to return an
error code. The caller can just ignore it if they don't care, and
it's extremely cheap to "return 0" in GPIO drivers which can't error.
If I were bit-banging on GPIOs reached via some peripheral chip (such
a GPIO-fanout chip over I2C/SPI, where that chip is itself feeding a
secondary I2C or similar bit-banging bus), I probably would like to
check for errors and take emergency action if the peripheral chip
isn't responding, or just report to userspace.
This has actually happened on a board I worked with, where the primary
I2C failed due to a plugged in peripheral loading it too much, and a
secondary bit-banging bus was not then reachable.
-- Jamie
^ permalink raw reply
* Re: [RFC 2.6.27 1/1] gpiolib: add support for batch set of pins
From: David Brownell @ 2008-12-29 20:32 UTC (permalink / raw)
To: Jaya Kumar
Cc: Ben Nizette, Robin Getz, Eric Miao, Sam Ravnborg, Eric Miao,
Haavard Skinnemoen, Philipp Zabel, Russell King, Ben Gardner,
Greg KH, linux-arm-kernel, linux-fbdev-devel, linux-kernel,
linux-embedded
In-Reply-To: <45a44e480812281628j214a9efvd19e4647fe30582c@mail.gmail.com>
On Sunday 28 December 2008, Jaya Kumar wrote:
> I'd like to get the start/length approach out there and in-play to
> find out if other people want to use it and how they end up using it.
As an *implementation* constraint, I might agree ... so
long as it's easily changed later.
As an *interface* constraint, I don't ... interfaces are
rarely easy to change.
However, in terms of implementation, most gpio chips have
primitives that work in terms of bitmasks rather than any
kind of start/length primitive. Example:
- To set bits in "u32 mask":
iowrite32(mask, bank_base + SET_REG)
- To clear bits in "u32 mask"
iowrite32(mask, bank_base + CLR_REG)
- To read bits in "u32 mask",
return mask & ioread32(bank_base + VALUE_REG)
In short, start/length looks most like a policy, of the
"keep them out of interfaces!" flavor, than something
appropriate for an interface. As noted above, gpio_chip
interfaces would more naturally use masks.
- Dave
^ permalink raw reply
* Re: [RFC 2.6.27 1/1] gpiolib: add support for batch set of pins
From: David Brownell @ 2008-12-29 19:59 UTC (permalink / raw)
To: Ben Nizette
Cc: Robin Getz, Jaya Kumar, Eric Miao, Sam Ravnborg, Eric Miao,
Haavard Skinnemoen, Philipp Zabel, Russell King, Ben Gardner,
Greg KH, linux-arm-kernel, linux-fbdev-devel, linux-kernel,
linux-embedded
In-Reply-To: <1230501634.16910.57.camel@linux-51e8.site>
On Sunday 28 December 2008, Ben Nizette wrote:
> > > gpio_set_batch(DB0, value, 0xFFFF, 16)
> > >
> > > which has the nice performance benefit of skipping all the bit
> > > counting in the most common use case scenario.
> >
> > but has the requirement that the driver know exactly the board level
> > impmentation details (something that doesn't sound generic).
>
> The original use case for these batch operations was in a fastpath -
> setting data lines on a framebuffer.
And the rationale for generalizing them was to let such fastpaths
stop being board-specific hacks. :)
^ permalink raw reply
* Re: [RFC 2.6.27 1/1] gpiolib: add support for batch set of pins
From: David Brownell @ 2008-12-29 19:56 UTC (permalink / raw)
To: Robin Getz
Cc: Jaya Kumar, Eric Miao, Sam Ravnborg, Eric Miao,
Haavard Skinnemoen, Philipp Zabel, Russell King, Ben Gardner,
Greg KH, linux-arm-kernel, linux-fbdev-devel, linux-kernel,
linux-embedded
In-Reply-To: <200812281346.56703.rgetz@blackfin.uclinux.org>
On Sunday 28 December 2008, Robin Getz wrote:
> On Sat 27 Dec 2008 09:55, Jaya Kumar pondered:
>
> I think that I would prefer 'group' or 'collection' to use some of the words
> that David described things as 'ganged' or 'bus' or 'bank' or 'adjacent'.
> (but I think 'adjacent' or 'bank' really is an implementation convention).
>
> I think I would also prefer to name things like gpio_bus_* as a rather than
> gpio_*_bus - so the operation always is on the end...
I'd avoid "bus"; the term has specific meanings, which aren't necessarily
relevant in these contexts. Agreed about "adjacent" and "bank".
If it weren't for its verb usage, I'd suggest "set". :)
> Shouldn't the write return an error code (if the data was not written)?
For these operations, I think reads/writes should have that possibility.
The reason single-bit operations don't provide error paths is twofold.
First, they started as wrappers for can't-fail register accessors.
Second, it's extremely unrealisitic to expect much code to handle any
kind of faults in the middle of bitbanging loops ... or even just in
classic "set this bit and continue" configuration code.
Those reasons don't apply well to these multi-bit cases.
> > While we are here, I was thinking about it, and its better if I give
> > gpio_request/free/direction_batch a miss for now. Nothing prevents
> > those features being added at a later point.
>
> I don't think that request/free are optional.
Agreed. If there's any difficulty implementing them, that would
suggest there's a significant conceptual problem to address ...
> For example - in most SoC implementations - gpios are implemented as banks of
> 16 or 32. (a 16 or 32 bit register).
>
> Are there facilities to span these registers?
> - can you request 64 gpios as a 'bank'?
> - can you request gpio_8 -> gpio_40 as a 'bank' on a 32-bit system?
>
> Are non-adjacent/non-contiguous gpios avaliable to be put into
> a 'bank/batch/bus'? can you use gpio_8 -> 11 & 28 -> 31 as a 8-bit 'bus'?
>
> How do you know what is avaliable to be talked to as a bank/bus/batch without
> the request/free operation?
>
>
> I have seen various hardware designs (both at the PCB and SoC level) require
> all of these options, and would like to see common infrastructure which
> handles this.
Right. Get the interface right -- it should allow all those
complexities! -- and maybe take shortcuts in the first versions
of the implementation, by only talking to one gpio_chip at a
time. I'd expect any shortcuts would be resolved quickly, to
the extent they cause problems.
> The issue is that on many SoC implementations - dedicated peripherals can also
> be GPIOs - so it someone wants to use SPI (for example) GPIO's 3->7 might be
> removed from the avaliable 'gpio' resources. This is determined by the
> silicon designer - and even the PCB designer has little to no flexibility on
> this. It gets worse as multiple SPI or I2C are used on the PCB (which can
> have lots of small (less than 5) dedicated pins in the middle of the larger
> gpio resources)....
Such pin-muxing is a different issue though. Don't expect GPIO
calls to resolve those problems.
> I would think that a 'bank' / 'bus' (whatever) would be a collection of
> random/multiple GPIOs (a struct of gpio_port_t) rather than a start/length
> (as you described) - or better yet - the request function takes a list (of
> individual GPIO's - defined in the platform data), and creates the struct
> itself.
That's why I pointed to <linux/bitmask.h> as one model: it allows
an arbitrary set of bits (GPIOs) to be specified.
I'll NAK any "gpio_port_t" name based entirely on kernel coding
conventions though. ;)
> Something like the way gpio_keys are defined...
>
> static struct gpio_bus bfin_gpio_bus_table[] = {
> {BIT_0, GPIO_PB8, 1, "gpio-bus: BIT0"},
> {BIT_1, GPIO_PB9, 1, "gpio-bus: BIT1"},
> {BIT_2, GPIO_PB10, 1, "gpio-bus: BIT2"},
> {BIT_3, GPIO_PB11, 1, "gpio-bus: BIT3"},
> };
>
> static struct gpio_bus_data bfin_gpio_bus_data = {
> .bits = bfin_gpio_bus_table,
> .width = ARRAY_SIZE(bfin_gpio_keys_table),
> };
>
> static struct platform_device bfin_device_gpiobus = {
> .name = "gpio-bus",
> .dev = {
> .platform_data = &bfin_gpio_bus_data,
> },
> };
>
> The request function builds up the bus/masks/shifts from that...
That sort of thing might be made to work. Whatever this
multiple-GPIO-set abstraction is, I suspect you're right
about wanting the request function to be able to build
up some data structures behind it. And that it would be
simpler to require all the GPIOs to be listed up front,
rather than support "add these to the set" requests.
- Dave
^ permalink raw reply
* Re: [RFC 2.6.27 1/1] gpiolib: add support for batch set of pins
From: David Brownell @ 2008-12-29 19:32 UTC (permalink / raw)
To: Jaya Kumar
Cc: Eric Miao, Sam Ravnborg, Eric Miao, Haavard Skinnemoen,
Philipp Zabel, Russell King, Ben Gardner, Greg KH,
linux-arm-kernel, linux-fbdev-devel, linux-kernel, linux-embedded
In-Reply-To: <45a44e480812270655u10bde0d2mc7f429cf47ed7bc6@mail.gmail.com>
On Saturday 27 December 2008, Jaya Kumar wrote:
> Oh, gosh darn it, how time has flown. My email above was to make sure
> I have understood the feedback. I assume I should just get started on
> implementing. Just to double check, the plan is:
> - add bitmask support.
> - add get_batch support
> - improve naming. I think gpio_get_batch/gpio_set_batch sounds good.
I was expecting to get some agreement on interfaces first.
> I plan to have something like:
>
> void gpio_set_batch(unsigned gpio, u32 values, u32 bitmask, int bitwidth);
> u32 gpio_get_batch(unsigned gpio, u32 bitmask, int bitwidth);
I still don't like the word "batch" here. Did you look
at the <linux/bitmask.h> interfaces as I suggested? They
would suggest something rather different:
- passing bitmasks as {unsigned long *bits, int count} tuples
- separate calls to:
* zero a set of bits (loop: gpio_set_value to 0)
* fill a set of bits (loop: gpio_set_value to 1)
* copy a set of bits (loop: gpio_set_value to src[i])
* read a set of bits (loop: dst[i] = gpio_get_value)
* ... maybe more
Any restriction to 32 bit value seems shortsighted. It would
make sense to wrap the GPIO bitmask descriptions in a struct,
letting drivers work with smaller sets -- probably most would
fit into a single "unsigned long".
> I think I should explain the bitmask and bitwidth choice. The intended
> use case is:
> for (i=0; i < 800*600; i++) {
> gpio_set_batch(...)
> }
>
> bitwidth (needed to iterate and map to chip ngpios) could be
> calculated from bitmask, but that involves iteratively counting bits
> from the mask, so we would have to do 800*600 bit counts. Unless, we
> do ugly things like cache the previous bitwidth/mask and compare
> against the current caller arguments. Given that the bitwidth would
> typically be a fixed value, I believe it is more intuitive for the
> caller to provide it, eg:
>
> gpio_set_batch(DB0, value, 0xFFFF, 16)
>
> which has the nice performance benefit of skipping all the bit
> counting in the most common use case scenario.
That doesn't explain the bit mask and bitwidth parameters at all.
> While we are here, I was thinking about it, and its better if I give
> gpio_request/free/direction_batch a miss for now.
Let's not and say we didn't. Providing incomplete interfaces
isn't really much help.
> Nothing prevents
> those features being added at a later point. That way I can focus on
> getting gpio_set/get_batch implemented correctly and merged as the
> first step.
First step needs to be defining the interface extensions needed.
- Dave
^ permalink raw reply
* Re: [RFC 2.6.27 1/1] gpiolib: add support for batch set of pins
From: David Brownell @ 2008-12-29 19:06 UTC (permalink / raw)
To: Jaya Kumar
Cc: Eric Miao, Sam Ravnborg, Eric Miao, Haavard Skinnemoen,
Philipp Zabel, Russell King, Ben Gardner, Greg KH,
linux-arm-kernel, linux-fbdev-devel, linux-kernel, linux-embedded
In-Reply-To: <45a44e480811301710v78875425p75dedd850728cbec@mail.gmail.com>
On Sunday 30 November 2008, Jaya Kumar wrote:
> > The gpio_*() interfaces are how system glue code and drivers
> > access GPIOs, unless they roll their own chip-specific calls.
> >
> > Whereas gpiolib (and gpio_chip) are an *optional* framework
> > for implementing those calls. Platforms can (and do!) use
> > other frameworks ... maybe they don't want to pay its costs,
> > and don't need the various GPIO expander drivers.
> >
> > So to repeat: don't assume the interface is implemented in
> > one particular way (using gpiolib). It has to make sense
> > with other implementation strategies too. Standard split
> > between interface and implementation, that's all. (Some folk
> > have been heard to talk about "gpiolib" as the interface to
> > drivers ... it's not, it's a provider-only interface library.)
> >
>
> Okay, I read above several times and I read Documentation/gpio.txt.
> But... I'm not confident I've understood your meanings above in terms
> of how it should change the code. What I know so far is:
>
> a)
> arch/arm/mach-pxa/include/mach/gpio.h is where the pxa GPIO api
> interface is defined.
It's actually where the *implementation* is *declared*. The
API is defined primarily in Documentation/gpio.txt ... though
in this case the implementation mostly punts to gpiolib. And
as you note below, the implementation is *defined* elsewhere.
> So that's where I will put the
> gpio_get/set_values_batch functions. This will match the existing
> gpio_set/get_value code there.
Those functions just punt to gpiolib, unlesss they happen
to fit in the "constant parameters" case where they can
expend to two or three instructions inline, rather than a
more expensive function call.
In this case, I don't see any benefit to supporting that
"inline constant parameters" case.
> b)
> arch/arm/mach-pxa/gpio.c is where the implementation is.
> So I'll put the pxa_gpio_direction_input/output_batch and
> pxa_gpio_set/get_batch there.
This is where the PXA implementation is *defined*, yes.
> c)
> drivers/gpio/gpiolib_batch.c
>
> This is where I'd put the generic platform independent implementations
> of __gpio_set/get_values_batch
>
> Does this sound consistent with your recommendation? If not, I need
> more help to understand what changes you are recommending.
More or less, yes. I'd have to see actual code. :)
> > Doesn't necessarily need to be *you* doing that, but if it only
> > works on older gumstix boards it'd not be general enough. Which
> > is part of why I say to get the lowest level proposal out there
> > first. If done right, it'll be easy to support on other chips.
>
> Yes, I completely agree that it must work on a wide range of
> architectures. But I don't understand what you mean when you say get
> the lowest level proposal out there first.
Provide a patch/RFD with
(0) methods you want to add to "struct gpio_chip".
Nothing else. That should be the easiest part of this change.
Other patches should probably include:
(1) one with the proposed driver level interface ... needs
discussion, so beginning with a patch may not be best;
(2) one *implementing* that interface using current calls;
(3) another *optimizing* that interface to use the new low
level methods (0), on chips where they're available;
(4) gpio_chip implementations for those low level ops.
Plus at least one example of how to use the interfaces in (1),
by the time everything starts to become solid, and implementation
patches are worth while.
(I'm not keen on starting with code to implement interfaces, except
when the interfaces are trivial or obvious. Interfaces are hard to
change. It's best to spend some time up-front improving them, while
they're easy to change/fix.)
> I see the RFC code that I
> posted as being the lowest level proposal (albeit needing better name
> and bitmask support) and one that is sufficiently general that it can
> be implemented on other architectures.
To repeat: what you've sent so far is mixing layers. It doesn't split
out the programming interface from its implementation at all.
Yet the whole *point* of having gpiolib is to make that split easy.
Which is why I want to see patches that reflect that architectural
split, instead of a hard-to-review megapatch that crosses all the
existing boundaries and doesn't show how non-PXA hardware could
implement these patches (or benefit from them).
- Dave
^ permalink raw reply
* Re: [RFC 2.6.27 1/1] gpiolib: add support for batch set of pins
From: Jaya Kumar @ 2008-12-29 0:28 UTC (permalink / raw)
To: Ben Nizette
Cc: Robin Getz, David Brownell, Eric Miao, Sam Ravnborg, Eric Miao,
Haavard Skinnemoen, Philipp Zabel, Russell King, Ben Gardner,
Greg KH, linux-arm-kernel, linux-fbdev-devel, linux-kernel,
linux-embedded
In-Reply-To: <1230501634.16910.57.camel@linux-51e8.site>
On Mon, Dec 29, 2008 at 6:00 AM, Ben Nizette <bn@niasdigital.com> wrote:
> On Sun, 2008-12-28 at 13:46 -0500, Robin Getz wrote:
>> > gpio_set_batch(DB0, value, 0xFFFF, 16)
>> >
>> > which has the nice performance benefit of skipping all the bit
>> > counting in the most common use case scenario.
>>
>> but has the requirement that the driver know exactly the board level
>> impmentation details (something that doesn't sound generic).
>
> The original use case for these batch operations was in a fastpath -
> setting data lines on a framebuffer. Sure it's arguably not as generic
> as may be, but it optimises for speed and current usage patterns - I'm
> OK with that. Other usage patterns which don't have a speed requirement
> can be done using the individual pin operations and a loop.
Hi Ben, Yes, exactly! Thanks!
Hi Robin, I think the randomly or less ordered gpio case that you
raised should be solved using the existing gpio_set/get single bit
value API. I intended this startpin, mask and length based API is to
help drivers that would currently hit a performance limitation while
keeping it just sufficiently abstract that it can be accelerated on an
implementation specific basis without too much of a headache.
btw, about the term batch, I had looked it up originally and seen:
google define:batch
A collection of products or data which is treated as one entity with
respect to certain operations eg processing and production.
www.shipping.francoudi.com/main/main.asp
so I felt it was a sufficiently meaningful and matching term to use.
Also, I had used the term gpio_set_value_bus in the first patch to try
to be close to the existing gpio_set/get_value API. I switched to
gpio_set_batch because it was pointed out that _bus could be
misleading. All that said, I'm happy to change it to the term around
which consensus forms. :-)
>
>>
>> > While we are here, I was thinking about it, and its better if I give
>> > gpio_request/free/direction_batch a miss for now. Nothing prevents
>> > those features being added at a later point.
>>
>> I don't think that request/free are optional.
>>
>> For example - in most SoC implementations - gpios are implemented as banks of
>> 16 or 32. (a 16 or 32 bit register).
>>
>> Are there facilities to span these registers?
>> - can you request 64 gpios as a 'bank'?
>> - can you request gpio_8 -> gpio_40 as a 'bank' on a 32-bit system?
I think as discussed above, these cases would be better solved using
the single bit set/get API.
>>
>> Are non-adjacent/non-contiguous gpios avaliable to be put into
>> a 'bank/batch/bus'? can you use gpio_8 -> 11 & 28 -> 31 as a 8-bit 'bus'?
>>
>> How do you know what is avaliable to be talked to as a bank/bus/batch without
>> the request/free operation?
>
> I think the read/write operations should be able to fail if you give
> them invalid chunks of gpio, sure. Request/free are not really designed
I think we can do that for read/write but we'd need to break
consistency with the existing api. The existing gpio_set_value and
gpio_get_value don't offer an error return.
> for that operation - they just ensure exclusive access to a gpio if
> that's what the driver wants. In the batch case the
> request/free/direction operations can once again be performed by single
> pin operations and iteration.
Agreed.
>
>>
>>
>> I have seen various hardware designs (both at the PCB and SoC level) require
>> all of these options, and would like to see common infrastructure which
>> handles this.
>>
>> The issue is that on many SoC implementations - dedicated peripherals can also
>> be GPIOs - so it someone wants to use SPI (for example) GPIO's 3->7 might be
>> removed from the avaliable 'gpio' resources. This is determined by the
>> silicon designer - and even the PCB designer has little to no flexibility on
>> this. It gets worse as multiple SPI or I2C are used on the PCB (which can
>> have lots of small (less than 5) dedicated pins in the middle of the larger
>> gpio resources)....
>
> Yeah the request/free operation doesn't deal with muxing or any other
> platform-specific kinda gumph, that was an original design decision.
> They're really just a usage counter.
>
> An example which comes to mind is the avr32-specific userspace gpio
> interface. This takes a bitmask, loops over the set bits and fails if
> any of the gpio are previously requested or have been assigned to
> non-gpio peripherals. I don't really see a need to streamline this.
>
>>
>> I would think that a 'bank' / 'bus' (whatever) would be a collection of
>> random/multiple GPIOs (a struct of gpio_port_t) rather than a start/length
>> (as you described) - or better yet - the request function takes a list (of
>> individual GPIO's - defined in the platform data), and creates the struct
>> itself.
Robin, I agree with you that trying to achieve unstructured multiple
GPIO support is elegant. The start/length approach I've taken here is
definitely not as generic. But by giving up some pure abstraction,
we've gained in implementation simplicity for each platform. Also,
there's nothing in my patch that would in future prevent us from
adding the random capability via an API akin to what you've suggested.
I'd like to get the start/length approach out there and in-play to
find out if other people want to use it and how they end up using it.
Thanks,
jaya
^ permalink raw reply
* Re: [RFC 2.6.27 1/1] gpiolib: add support for batch set of pins
From: Ben Nizette @ 2008-12-28 22:00 UTC (permalink / raw)
To: Robin Getz
Cc: Jaya Kumar, David Brownell, Eric Miao, Sam Ravnborg, Eric Miao,
Haavard Skinnemoen, Philipp Zabel, Russell King, Ben Gardner,
Greg KH, linux-arm-kernel, linux-fbdev-devel, linux-kernel,
linux-embedded
In-Reply-To: <200812281346.56703.rgetz@blackfin.uclinux.org>
On Sun, 2008-12-28 at 13:46 -0500, Robin Getz wrote:
> > gpio_set_batch(DB0, value, 0xFFFF, 16)
> >
> > which has the nice performance benefit of skipping all the bit
> > counting in the most common use case scenario.
>
> but has the requirement that the driver know exactly the board level
> impmentation details (something that doesn't sound generic).
The original use case for these batch operations was in a fastpath -
setting data lines on a framebuffer. Sure it's arguably not as generic
as may be, but it optimises for speed and current usage patterns - I'm
OK with that. Other usage patterns which don't have a speed requirement
can be done using the individual pin operations and a loop.
>
> > While we are here, I was thinking about it, and its better if I give
> > gpio_request/free/direction_batch a miss for now. Nothing prevents
> > those features being added at a later point.
>
> I don't think that request/free are optional.
>
> For example - in most SoC implementations - gpios are implemented as banks of
> 16 or 32. (a 16 or 32 bit register).
>
> Are there facilities to span these registers?
> - can you request 64 gpios as a 'bank'?
> - can you request gpio_8 -> gpio_40 as a 'bank' on a 32-bit system?
>
> Are non-adjacent/non-contiguous gpios avaliable to be put into
> a 'bank/batch/bus'? can you use gpio_8 -> 11 & 28 -> 31 as a 8-bit 'bus'?
>
> How do you know what is avaliable to be talked to as a bank/bus/batch without
> the request/free operation?
I think the read/write operations should be able to fail if you give
them invalid chunks of gpio, sure. Request/free are not really designed
for that operation - they just ensure exclusive access to a gpio if
that's what the driver wants. In the batch case the
request/free/direction operations can once again be performed by single
pin operations and iteration.
>
>
> I have seen various hardware designs (both at the PCB and SoC level) require
> all of these options, and would like to see common infrastructure which
> handles this.
>
> The issue is that on many SoC implementations - dedicated peripherals can also
> be GPIOs - so it someone wants to use SPI (for example) GPIO's 3->7 might be
> removed from the avaliable 'gpio' resources. This is determined by the
> silicon designer - and even the PCB designer has little to no flexibility on
> this. It gets worse as multiple SPI or I2C are used on the PCB (which can
> have lots of small (less than 5) dedicated pins in the middle of the larger
> gpio resources)....
Yeah the request/free operation doesn't deal with muxing or any other
platform-specific kinda gumph, that was an original design decision.
They're really just a usage counter.
An example which comes to mind is the avr32-specific userspace gpio
interface. This takes a bitmask, loops over the set bits and fails if
any of the gpio are previously requested or have been assigned to
non-gpio peripherals. I don't really see a need to streamline this.
>
> I would think that a 'bank' / 'bus' (whatever) would be a collection of
> random/multiple GPIOs (a struct of gpio_port_t) rather than a start/length
> (as you described) - or better yet - the request function takes a list (of
> individual GPIO's - defined in the platform data), and creates the struct
> itself.
Hmm, this seems a little overengineered for the basic use-cases I can
think of. If this can be cranked up to the same speed as the current
proposition then OK maybe someone will like it but otherwise, once
again, I think most people will be happy with individual operations and
iteration.
--Ben.
^ permalink raw reply
* Re: [RFC 2.6.27 1/1] gpiolib: add support for batch set of pins
From: Robin Getz @ 2008-12-28 18:46 UTC (permalink / raw)
To: Jaya Kumar
Cc: David Brownell, Eric Miao, Sam Ravnborg, Eric Miao,
Haavard Skinnemoen, Philipp Zabel, Russell King, Ben Gardner,
Greg KH, linux-arm-kernel, linux-fbdev-devel, linux-kernel,
linux-embedded
In-Reply-To: <45a44e480812270655u10bde0d2mc7f429cf47ed7bc6@mail.gmail.com>
On Sat 27 Dec 2008 09:55, Jaya Kumar pondered:
> Oh, gosh darn it, how time has flown. My email above was to make sure
> I have understood the feedback. I assume I should just get started on
> implementing. Just to double check, the plan is:
> - add bitmask support.
> - add get_batch support
> - improve naming. I think gpio_get_batch/gpio_set_batch sounds good.
for what it is worth - I don't like 'batch'.
According to wikipedia[1] - in computer science, batch typically refers to:
* Batch (Unix), a command to queue jobs for later execution
* Batch file, in DOS, OS/2, and Microsoft Windows, a text file containing
a series of commands intended to be executed
* Batch processing, execution of a series of programs on a computer
without human interaction
* Batch renaming, the process of renaming multiple computer files
and folders in an automated fashion
None of these are really what you are talking about. Batch normally only
refers to a group when taking about baking - A batch of cookies - at least
where I grew up....
I think that I would prefer 'group' or 'collection' to use some of the words
that David described things as 'ganged' or 'bus' or 'bank' or 'adjacent'.
(but I think 'adjacent' or 'bank' really is an implementation convention).
I think I would also prefer to name things like gpio_bus_* as a rather than
gpio_*_bus - so the operation always is on the end...
> I
> plan to have something like:
>
> void gpio_set_batch(unsigned gpio, u32 values, u32 bitmask, int bitwidth);
Shouldn't the write return an error code (if the data was not written)?
> u32 gpio_get_batch(unsigned gpio, u32 bitmask, int bitwidth);
Both assume specific SoC and board level impmentation details (which I ask
below).
> I think I should explain the bitmask and bitwidth choice. The intended
> use case is:
> for (i=0; i < 800*600; i++) {
> gpio_set_batch(...)
> }
>
> bitwidth (needed to iterate and map to chip ngpios) could be
> calculated from bitmask, but that involves iteratively counting bits
> from the mask, so we would have to do 800*600 bit counts. Unless, we
> do ugly things like cache the previous bitwidth/mask and compare
> against the current caller arguments. Given that the bitwidth would
> typically be a fixed value, I believe it is more intuitive for the
> caller to provide it, eg:
>
> gpio_set_batch(DB0, value, 0xFFFF, 16)
>
> which has the nice performance benefit of skipping all the bit
> counting in the most common use case scenario.
but has the requirement that the driver know exactly the board level
impmentation details (something that doesn't sound generic).
> While we are here, I was thinking about it, and its better if I give
> gpio_request/free/direction_batch a miss for now. Nothing prevents
> those features being added at a later point.
I don't think that request/free are optional.
For example - in most SoC implementations - gpios are implemented as banks of
16 or 32. (a 16 or 32 bit register).
Are there facilities to span these registers?
- can you request 64 gpios as a 'bank'?
- can you request gpio_8 -> gpio_40 as a 'bank' on a 32-bit system?
Are non-adjacent/non-contiguous gpios avaliable to be put into
a 'bank/batch/bus'? can you use gpio_8 -> 11 & 28 -> 31 as a 8-bit 'bus'?
How do you know what is avaliable to be talked to as a bank/bus/batch without
the request/free operation?
I have seen various hardware designs (both at the PCB and SoC level) require
all of these options, and would like to see common infrastructure which
handles this.
The issue is that on many SoC implementations - dedicated peripherals can also
be GPIOs - so it someone wants to use SPI (for example) GPIO's 3->7 might be
removed from the avaliable 'gpio' resources. This is determined by the
silicon designer - and even the PCB designer has little to no flexibility on
this. It gets worse as multiple SPI or I2C are used on the PCB (which can
have lots of small (less than 5) dedicated pins in the middle of the larger
gpio resources)....
I would think that a 'bank' / 'bus' (whatever) would be a collection of
random/multiple GPIOs (a struct of gpio_port_t) rather than a start/length
(as you described) - or better yet - the request function takes a list (of
individual GPIO's - defined in the platform data), and creates the struct
itself.
Something like the way gpio_keys are defined...
static struct gpio_bus bfin_gpio_bus_table[] = {
{BIT_0, GPIO_PB8, 1, "gpio-bus: BIT0"},
{BIT_1, GPIO_PB9, 1, "gpio-bus: BIT1"},
{BIT_2, GPIO_PB10, 1, "gpio-bus: BIT2"},
{BIT_3, GPIO_PB11, 1, "gpio-bus: BIT3"},
};
static struct gpio_bus_data bfin_gpio_bus_data = {
.bits = bfin_gpio_bus_table,
.width = ARRAY_SIZE(bfin_gpio_keys_table),
};
static struct platform_device bfin_device_gpiobus = {
.name = "gpio-bus",
.dev = {
.platform_data = &bfin_gpio_bus_data,
},
};
The request function builds up the bus/masks/shifts from that...
-Robin
[1] http://en.wikipedia.org/wiki/Batch
^ permalink raw reply
* Re: [RFC 2.6.27 1/1] gpiolib: add support for batch set of pins
From: Jaya Kumar @ 2008-12-27 14:55 UTC (permalink / raw)
To: David Brownell
Cc: Eric Miao, Sam Ravnborg, Eric Miao, Haavard Skinnemoen,
Philipp Zabel, Russell King, Ben Gardner, Greg KH,
linux-arm-kernel, linux-fbdev-devel, linux-kernel, linux-embedded
In-Reply-To: <45a44e480811301710v78875425p75dedd850728cbec@mail.gmail.com>
On Mon, Dec 1, 2008 at 9:10 AM, Jaya Kumar <jayakumar.lkml@gmail.com> wrote:
> On Mon, Dec 1, 2008 at 1:55 AM, David Brownell <david-b@pacbell.net> wrote:
>>
>> They wouldn't want names so easily confused with the current set
>> of GPIO calls, no.
>>
>
> Okay, how does gpio_set/get_values_batch() sound?
>
>>
>>> >
>>> > Then separately two more things:
>>> >
>>> > - A gpio_* interface proposal for higher-level bitmask calls.
>>> > This is worth some discussion; the calls should clearly
>>> > be optional (not everything will implement them), and I
>>> > can't help but suspect <linux/bitmap.h> interfaces should
>>> > interoperate smoothly.
>>
>> ... including probably ganged request/free, and direction updates.
>> When bitbanging a multiplexed parallel databus, you'll often need
>> to change directions.
>
> Okay, so I'll also add gpio_direction_output/input_batch and request/free_batch.
>
>>
>>
>>> >
>>> > - A gpiolib based implementation, using those new gpio_chip
>>> > methods as accelerators if they're present. This should
>>> > probably also be optional, even at the Kconfig level; many
>>> > systems won't need to spend memory on these calls.
>>>
>>> Understood. I will make it optional. Does
>>> CONFIG_GPIOLIB_MULTIBIT_ACCESS sound okay?
>>
>> Kind of verbose for my taste, and it's already "multibit" (one
>> at a time, but still multiple) ... let's see some more mergeable
>> proposals and code first. Different C file too, I suspect.
>
> Ok, CONFIG_GPIOLIB_BATCH and I'll add this code in
> drivers/gpio/gpiolib_batch.c. I hope I have understood that suggestion
> correctly.
>
>>
>>
>>> > Don't assume gpiolib when defining the interface.
>>>
>>> Ok, I didn't understand this part. I think you mentioned a higher
>>> level interface before but I didn't fully understand, if not gpiolib,
>>> then at what level do you recommend?
>>
>> The gpio_*() interfaces are how system glue code and drivers
>> access GPIOs, unless they roll their own chip-specific calls.
>>
>> Whereas gpiolib (and gpio_chip) are an *optional* framework
>> for implementing those calls. Platforms can (and do!) use
>> other frameworks ... maybe they don't want to pay its costs,
>> and don't need the various GPIO expander drivers.
>>
>> So to repeat: don't assume the interface is implemented in
>> one particular way (using gpiolib). It has to make sense
>> with other implementation strategies too. Standard split
>> between interface and implementation, that's all. (Some folk
>> have been heard to talk about "gpiolib" as the interface to
>> drivers ... it's not, it's a provider-only interface library.)
>>
>
> Okay, I read above several times and I read Documentation/gpio.txt.
> But... I'm not confident I've understood your meanings above in terms
> of how it should change the code. What I know so far is:
>
> a)
> arch/arm/mach-pxa/include/mach/gpio.h is where the pxa GPIO api
> interface is defined. So that's where I will put the
> gpio_get/set_values_batch functions. This will match the existing
> gpio_set/get_value code there.
>
> b)
> arch/arm/mach-pxa/gpio.c is where the implementation is.
> So I'll put the pxa_gpio_direction_input/output_batch and
> pxa_gpio_set/get_batch there.
>
> c)
> drivers/gpio/gpiolib_batch.c
>
> This is where I'd put the generic platform independent implementations
> of __gpio_set/get_values_batch
>
> Does this sound consistent with your recommendation? If not, I need
> more help to understand what changes you are recommending.
>
>
>> Doesn't necessarily need to be *you* doing that, but if it only
>> works on older gumstix boards it'd not be general enough. Which
>> is part of why I say to get the lowest level proposal out there
>> first. If done right, it'll be easy to support on other chips.
>
> Yes, I completely agree that it must work on a wide range of
> architectures. But I don't understand what you mean when you say get
> the lowest level proposal out there first. I see the RFC code that I
> posted as being the lowest level proposal (albeit needing better name
> and bitmask support) and one that is sufficiently general that it can
> be implemented on other architectures. If it can't, can you help me
> understand by pointing to which portion would break on other archs?
>
Oh, gosh darn it, how time has flown. My email above was to make sure
I have understood the feedback. I assume I should just get started on
implementing. Just to double check, the plan is:
- add bitmask support.
- add get_batch support
- improve naming. I think gpio_get_batch/gpio_set_batch sounds good. I
plan to have something like:
void gpio_set_batch(unsigned gpio, u32 values, u32 bitmask, int bitwidth);
u32 gpio_get_batch(unsigned gpio, u32 bitmask, int bitwidth);
I think I should explain the bitmask and bitwidth choice. The intended
use case is:
for (i=0; i < 800*600; i++) {
gpio_set_batch(...)
}
bitwidth (needed to iterate and map to chip ngpios) could be
calculated from bitmask, but that involves iteratively counting bits
from the mask, so we would have to do 800*600 bit counts. Unless, we
do ugly things like cache the previous bitwidth/mask and compare
against the current caller arguments. Given that the bitwidth would
typically be a fixed value, I believe it is more intuitive for the
caller to provide it, eg:
gpio_set_batch(DB0, value, 0xFFFF, 16)
which has the nice performance benefit of skipping all the bit
counting in the most common use case scenario.
While we are here, I was thinking about it, and its better if I give
gpio_request/free/direction_batch a miss for now. Nothing prevents
those features being added at a later point. That way I can focus on
getting gpio_set/get_batch implemented correctly and merged as the
first step.
Thanks,
jaya
^ permalink raw reply
* Re: [Celinux-dev] animated graphics on embedded linux systems
From: Gustavo Sverzut Barbieri @ 2008-12-25 23:59 UTC (permalink / raw)
To: Oguz Yarimtepe; +Cc: celinux-dev, linux-embedded
In-Reply-To: <20831c740812250614w5525f248kffd6a6a5151afec1@mail.gmail.com>
2008/12/25 Oguz Yarimtepe <comp.ogz@gmail.com>:
> Hi,
>
> I am searching graphics libraries that enables animated graphics on
> embedded linux systems. Here are the requirements for the graphics
> library:
>
> * Should work or able to work with DirectFB
> * Lightweight
> * Doesn't consume memory and cpu power much
>
> So it can be thought that the library will be used for a media center
> type application. At that application i want to be able to write some
> animation effects for ex for the window part that shows video covers
> and passing from one to another will be with some animation or
> pressing a close button will be with some animation or will cause the
> current window closed with some animation...
>
> I Googled a little but i want to hear some experiences also, if any.
> There are some graphics libraries suggested for embedded environments
> like Qt Embedded or SDL. I am not sure whether they are suitable dor
> such applications or whether they are memory efficient.
I use and recommend Enlightenment Foundation Libraries (EFL,
http://enlightenment.org), specially Evas (canvas) and Edje (theme,
with animations and transitions). It is very lightweight and can use
hardware acceleration when possible, with optimized (sse, mmx,
altivec) C replacement.
I wrote DirectFB engine some time ago and Denis did a review of it.
Denis said to make fully use of hardware acceleration for blits we
need to change image allocation to hardware, then paint it with
pixels, not hard to do, but I'm not doing it now... patches are
welcome or you can consider hiring our company to do such work.
Compared to SDL, EFL offers much more primitives and thus can provide
many optimizations, like occlusion culling and dirty area/movement.
Compared to Qt 4.x, it provides a bit less canvas primitives (no
vectors, for instance), but it provides Edje, a very helpful piece of
EFL. Also, EFL is BSD with one piece in LGPL, while Qt is GPL or
commercial.
You can find lots of information about EFL on my blog
(http://blog.gustavobarbieri.com.br/) or company news
(http://profusion.mobi/taxonomy/term/2). If you want to hire
consulting, training or development, feel free to contact us.
Regards,
--
Gustavo Sverzut Barbieri
http://profusion.mobi embedded systems
--------------------------------------
MSN: barbieri@gmail.com
Skype: gsbarbieri
Mobile: +55 (19) 9225-2202
^ permalink raw reply
* animated graphics on embedded linux systems
From: Oguz Yarimtepe @ 2008-12-25 14:14 UTC (permalink / raw)
To: celinux-dev, linux-embedded
Hi,
I am searching graphics libraries that enables animated graphics on
embedded linux systems. Here are the requirements for the graphics
library:
* Should work or able to work with DirectFB
* Lightweight
* Doesn't consume memory and cpu power much
So it can be thought that the library will be used for a media center
type application. At that application i want to be able to write some
animation effects for ex for the window part that shows video covers
and passing from one to another will be with some animation or
pressing a close button will be with some animation or will cause the
current window closed with some animation...
I Googled a little but i want to hear some experiences also, if any.
There are some graphics libraries suggested for embedded environments
like Qt Embedded or SDL. I am not sure whether they are suitable dor
such applications or whether they are memory efficient.
I would like to hear some suggestions
Thanx.
--
Oðuz Yarýmtepe
www.loopbacking.info
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox