PowerPC: implement support for GPIO LIB API
Subsystems (2)
cover PowerPC: implement support for GPIO LIB API
Hi all,
Thanks for the previous review and ideas. Here is the RFC for the GPIO LIB support.
I'm using it like this:
qe_pio_a: gpio-controller@1400 {
#gpio-cells = <1>;
compatible = "fsl,qe-pario-bank";
reg = <0x1400 0x18>;
gpio-controller;
};
qe_pio_e: gpio-controller@1460 {
#gpio-cells = <1>;
compatible = "fsl,qe-pario-bank";
reg = <0x1460 0x18>;
gpio-controller;
};
nand-flash@1,0 {
compatible = "stmicro,NAND512W3A2BN6E", "fsl,upm-nand";
reg = <1 0 1>;
width = <1>;
upm = "A";
upm-addr-offset = <16>;
upm-cmd-offset = <8>;
gpios = <&qe_pio_e 18 &qe_pio_a 9>;
wait-pattern;
wait-write;
};As you can see I've split single "par_io" node into banks, thus the benefits:
- we can handle banks of different width (Jochen Friedrich asked for this, IIRC. Or I've misunderstood ;-).
- we can handle banks with different paddings (no more #ifdef PPC85xx).
Also, it's possible to specify different gpio-controllers in the gpios = <> property. gpio-specifier is controller specific.
The remaining question is about gpio.c placement. prom_parse.c doesn't feel as the appropriate place anymore. I think of:
- drivers/gpio/of_gpio.c (driver/gpio/ is in -mm tree);
- drivers/of/gpio.c
- keep it in arch/powerpc/kernel/ (though, there is nothing much PowerPC specific).
So, to try these patches you'll need apply these from the -mm tree:
generic-gpio-gpio_chip-support.patch generic-gpio-gpio_chip-support-fix.patch generic-gpio-gpio_chip-support-gpiolib-locking-simplified.patch
Or just issue this in your working tree:
git pull git://git.infradead.org/users/cbou/powerpc-gpio.git gpiolib
powerpc-gpio.git's gpiolib branch is galak/powerpc.git master branch + -mm patches + these patches.
Support for CPM2 is pending.
Thanks!
Signature · 4 lines
Anton Vorontsov email: [email protected] backup email: [email protected] irc://irc.freenode.net/bd2
PATCH 1/3 Implement support for the GPIO LIB API
This patch implements support for the GPIO LIB API. Two calls unimplemented though: irq_to_gpio and gpio_to_irq.
Various OF helpers provided to ease life and reduce code duplication.
--- Documentation/powerpc/booting-without-of.txt | 58 ++++++++ arch/powerpc/Kconfig | 5 + arch/powerpc/kernel/Makefile | 1 + arch/powerpc/kernel/gpio.c | 186 ++++++++++++++++++++++++++ include/asm-powerpc/gpio.h | 126 +++++++++++++++++ 5 files changed, 376 insertions(+), 0 deletions(-) create mode 100644 arch/powerpc/kernel/gpio.c create mode 100644 include/asm-powerpc/gpio.h
Documentation/powerpc/booting-without-of.txt +58 -0
@@ -60,6 +60,10 @@ Table of Contents 3) OpenPIC Interrupt Controllers 4) ISA Interrupt Controllers + VIII - Specifying GPIO information for devices + 1) gpios property + 2) gpio-controller nodes + Appendix A - Sample SOC node for MPC8540
@@ -2618,6 +2622,60 @@ encodings listed below: 2 = high to low edge sensitive type enabled 3 = low to high edge sensitive type enabled +VIII - Specifying GPIO information for devices +============================================== + +1) gpios property +----------------- + +Nodes that makes use of GPIOs should define them using `gpios' property, +format of which is: <&gpio-controller1-phandle gpio1-specifier + &gpio-controller2-phandle gpio2-specifier + ...>; + +Note that gpio-specifier length is controller dependent. + +gpio-specifier may encode: bank, pin position inside the bank, +whether pin is open-drain and whether pin is active-low. + +Example of the node using GPIOs: + + nand-flash@1,0 { + compatible = "stmicro,NAND512W3A2BN6E", "fsl,upm-nand"; + reg = <1 0 1>; + width = <1>; + upm = "A"; + upm-addr-offset = <16>; + upm-cmd-offset = <8>; + gpios = <&qe_pio_e 18>; + wait-pattern; + wait-write; + }; + +In that example gpio-specifier is "18" and encodes GPIO pin number only, +as accepted by the "qe_pio_e" gpio-controller. + +2) gpio-controller nodes +------------------------ + +Every GPIO controller node must have #gpio-cells property defined, +this information will be used to translate gpio-specifiers. + +Example of two SOC GPIO banks defined as gpio-controller nodes: + + qe_pio_a: gpio-controller@1400 { + #gpio-cells = <1>; + compatible = "fsl,qe-pario-bank"; + reg = <0x1400 0x18>; + gpio-controller; + }; + + qe_pio_e: gpio-controller@1460 { + #gpio-cells = <1>; + compatible = "fsl,qe-pario-bank"; + reg = <0x1460 0x18>; + gpio-controller; + }; Appendix A - Sample SOC node for MPC8540 ========================================
arch/powerpc/Kconfig +5 -0
@@ -73,6 +73,11 @@ config GENERIC_FIND_NEXT_BIT bool default y +config GENERIC_GPIO + bool + help + Generic GPIO API support + config ARCH_NO_VIRT_TO_BUS def_bool PPC64
arch/powerpc/kernel/Makefile +1 -0
@@ -65,6 +65,7 @@ obj-$(CONFIG_BOOTX_TEXT) += btext.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_KPROBES) += kprobes.o obj-$(CONFIG_PPC_UDBG_16550) += legacy_serial.o udbg_16550.o +obj-$(CONFIG_GPIO_LIB) += gpio.o pci64-$(CONFIG_PPC64) += pci_dn.o isa-bridge.o obj-$(CONFIG_PCI) += pci_$(CONFIG_WORD_SIZE).o $(pci64-y) \
arch/powerpc/kernel/gpio.c new file +186 -0
186 lines not on this page · raw message
include/asm-powerpc/gpio.h new file +126 -0
126 lines not on this page · raw message
Signature · 1 line
1.5.2.2
Re: [PATCH 1/3] [POWERPC] Implement support for the GPIO LIB API
Quoted 15 lines · On Tue, 8 Jan 2008 21:45:18 +0300 Anton Vorontsov <[email protected]>…
arch/powerpc/kernel/gpio.c new file +14
-0+int of_mm_gpiochip_add (struct device_node *np, +const struct of_gpio_chip *of_gc) +{ +int ret = -ENOMEM ; +struct of_mm_gpio_chip *mm_gc; + + mm_gc =kzalloc (sizeof (*mm_gc),GFP_KERNEL ); +if (!mm_gc) + goto err0; + + mm_gc->of_gc = *of_gc; + + mm_gc->of_gc.gc.label =kstrdup (np->full_name,GFP_KERNEL ); +if (!mm_gc->of_gc.gc.label)
arch/powerpc/kernel/gpio.c line 160
Quoted 10 lines
arch/powerpc/kernel/gpio.c new file +10
-0+ goto err1; + + ret =of_get_gpiochip_base (np); +if (ret <0 ) + goto err2; + + mm_gc->regs =of_iomap (np,0 ); +if (!mm_gc->regs) { + ret = -ENOMEM ; + goto err1;
Should this be err2?
arch/powerpc/kernel/gpio.c line 171
Quoted 11 lines
arch/powerpc/kernel/gpio.c new file +11
-0+ } + + mm_gc->of_gc.gc.base = ret; + + np->data = &mm_gc->of_gc; + + ret =gpiochip_add (&mm_gc->of_gc.gc); +if (ret) + goto err2; + +of_node_get (np);
Why do you this of_node_get(np) when you do not keep a reference to np in this routine?
Signature · 3 lines
Cheers, Stephen Rothwell [email protected] http://www.canb.auug.org.au/~sfr/
PATCH 2/3 QE: split par_io_config_pin()
In reply to Anton VorontsovThis patch splits par_io_config_pin so we can use it with GPIO LIB API.
Also add a comment regarding #ifdef CONFIG_PPC_85xx being legacy.
--- arch/powerpc/sysdev/qe_lib/qe_io.c | 60 +++++++++++++++++++++++------------ 1 files changed, 39 insertions(+), 21 deletions(-)
arch/powerpc/sysdev/qe_lib/qe_io.c +39 -21
@@ -37,6 +37,10 @@ struct port_regs {__be32 cppar1;/* Pin assignment register */ __be32 cppar2;/* Pin assignment register */ #ifdef CONFIG_PPC_85xx +/* +* This is needed for legacy support only, should go away, +* because we started using per-bank gpio chips. +*/ u8 pad[8 ];#endif };
@@ -63,28 +67,29 @@ int par_io_init(struct device_node *np)return 0 ; } -int par_io_config_pin (u8 port,u8 pin,int dir,int open_drain, -int assignment,int has_irq) +static void __par_io_config_pin (struct port_regs __iomem *par_io, +u8 pin,int dir,int open_drain, +int assignment,int has_irq) { -u32 pin_mask1bit, pin_mask2bits, new_mask2bits, tmp_val; - -if (!par_io) -return -1 ; +u32 pin_mask1bit; +u32 pin_mask2bits; +u32 new_mask2bits; +u32 tmp_val;/* calculate pin location for single and 2 bits information */ pin_mask1bit = (u32) (1 << (NUM_OF_PINS - (pin +1 )));/* Set open drain, if required */ - tmp_val =in_be32 (&par_io[port].cpodr); + tmp_val =in_be32 (&par_io->cpodr);if (open_drain) -out_be32 (&par_io[port].cpodr, pin_mask1bit | tmp_val); +out_be32 (&par_io->cpodr, pin_mask1bit | tmp_val);else -out_be32 (&par_io[port].cpodr, ~pin_mask1bit & tmp_val); +out_be32 (&par_io->cpodr, ~pin_mask1bit & tmp_val);/* define direction */ tmp_val = (pin > (NUM_OF_PINS /2 ) -1 ) ? -in_be32 (&par_io[port].cpdir2) : -in_be32 (&par_io[port].cpdir1); +in_be32 (&par_io->cpdir2) : +in_be32 (&par_io->cpdir1);/* get all bits mask for 2 bit per port */ pin_mask2bits = (u32) (0x3 << (NUM_OF_PINS -
@@ -96,36 +101,49 @@ int par_io_config_pin(u8 port, u8 pin, int dir, int open_drain,/* clear and set 2 bits mask */ if (pin > (NUM_OF_PINS /2 ) -1 ) { -out_be32 (&par_io[port].cpdir2, +out_be32 (&par_io->cpdir2, ~pin_mask2bits & tmp_val); tmp_val &= ~pin_mask2bits; -out_be32 (&par_io[port].cpdir2, new_mask2bits | tmp_val); +out_be32 (&par_io->cpdir2, new_mask2bits | tmp_val); }else { -out_be32 (&par_io[port].cpdir1, +out_be32 (&par_io->cpdir1, ~pin_mask2bits & tmp_val); tmp_val &= ~pin_mask2bits; -out_be32 (&par_io[port].cpdir1, new_mask2bits | tmp_val); +out_be32 (&par_io->cpdir1, new_mask2bits | tmp_val); }/* define pin assignment */ tmp_val = (pin > (NUM_OF_PINS /2 ) -1 ) ? -in_be32 (&par_io[port].cppar2) : -in_be32 (&par_io[port].cppar1); +in_be32 (&par_io->cppar2) : +in_be32 (&par_io->cppar1); new_mask2bits = (u32) (assignment << (NUM_OF_PINS - (pin % (NUM_OF_PINS /2 ) +1 ) *2 ));/* clear and set 2 bits mask */ if (pin > (NUM_OF_PINS /2 ) -1 ) { -out_be32 (&par_io[port].cppar2, +out_be32 (&par_io->cppar2, ~pin_mask2bits & tmp_val); tmp_val &= ~pin_mask2bits; -out_be32 (&par_io[port].cppar2, new_mask2bits | tmp_val); +out_be32 (&par_io->cppar2, new_mask2bits | tmp_val); }else { -out_be32 (&par_io[port].cppar1, +out_be32 (&par_io->cppar1, ~pin_mask2bits & tmp_val); tmp_val &= ~pin_mask2bits; -out_be32 (&par_io[port].cppar1, new_mask2bits | tmp_val); +out_be32 (&par_io->cppar1, new_mask2bits | tmp_val); } +} + +/* +* This is "legacy" function that takes port number as an argument +* instead of pointer to the appropriate bank. +*/ +int par_io_config_pin (u8 port,u8 pin,int dir,int open_drain, +int assignment,int has_irq) +{ +if (!par_io || port >= num_par_io_ports) +return -EINVAL ; +__par_io_config_pin (&par_io[port], pin, dir, open_drain, assignment, + has_irq);return 0 ; }EXPORT_SYMBOL (par_io_config_pin);
Signature · 1 line
1.5.2.2
PATCH 3/3 QE: implement GPIO LIB API
In reply to Anton Vorontsov--- Documentation/powerpc/booting-without-of.txt | 32 +++++++---- arch/powerpc/platforms/Kconfig | 2 + arch/powerpc/sysdev/qe_lib/qe_io.c | 73 ++++++++++++++++++++++++++ include/asm-powerpc/qe.h | 1 + 4 files changed, 96 insertions(+), 12 deletions(-)
Documentation/powerpc/booting-without-of.txt +20 -12
@@ -1696,24 +1696,32 @@ platforms are moved over to use the flattened-device-tree model. information. Required properties: - - device_type : should be "par_io". + - #gpio-cells : should be "1". + - compatible : should be "fsl,qe-pario-bank" - reg : offset to the register set and its length. - - num-ports : number of Parallel I/O ports + - gpio-controller : node to identify gpio controllers. - Example: - par_io@1400 { - reg = <1400 100>; - #address-cells = <1>; - #size-cells = <0>; - device_type = "par_io"; - num-ports = <7>; - ucc_pin@01 { - ...... - }; + For example, two QE Par I/O banks: + qe_pio_a: gpio-controller@1400 { + #gpio-cells = <1>; + compatible = "fsl,qe-pario-bank"; + reg = <0x1400 0x18>; + gpio-controller; + }; + qe_pio_e: gpio-controller@1460 { + #gpio-cells = <1>; + compatible = "fsl,qe-pario-bank"; + reg = <0x1460 0x18>; + gpio-controller; + }; vi) Pin configuration nodes + NOTE: pin configuration nodes are obsolete. Usually, their existance + is an evidence of the firmware shortcomings. Such fixups are + better handled by the Linux board file, not the device tree. + Required properties: - linux,phandle : phandle of this node; likely referenced by a QE device.
arch/powerpc/platforms/Kconfig +2 -0
@@ -265,6 +265,8 @@ config TAU_AVERAGE config QUICC_ENGINE bool select PPC_LIB_RHEAP + select GENERIC_GPIO + select GPIO_LIB help The QUICC Engine (QE) is a new generation of communications coprocessors on Freescale embedded CPUs (akin to CPM in older chips).
arch/powerpc/sysdev/qe_lib/qe_io.c +73 -0
85 lines not on this page · raw message
include/asm-powerpc/qe.h +1 -0
@@ -77,6 +77,7 @@ enum qe_clock {/* Export QE common operations */ extern void qe_reset (void );extern int par_io_init (struct device_node *np); +extern int qe_gpiochip_add (struct device_node *np);extern int par_io_of_config (struct device_node *np);extern int par_io_config_pin (u8 port,u8 pin,int dir,int open_drain,int assignment,int has_irq);
Signature · 1 line
1.5.2.2
Re: [PATCH 3/3] [POWERPC] QE: implement GPIO LIB API
Hi Anton,
Quoted 7 lines
arch/powerpc/sysdev/qe_lib/qe_io.c +7
-0+static void qe_gpio_set (struct gpio_chip *gc,unsigned int gpio,int val) +{ +struct of_mm_gpio_chip *mm_gc =to_of_mm_gpio_chip (gc); +struct port_regs *regs = mm_gc->regs; +u32 pin_mask; +u32 tmp_val; +
arch/powerpc/sysdev/qe_lib/qe_io.c int par_io_of_config(struct device_node *np) · line 249
Quoted 10 lines
arch/powerpc/sysdev/qe_lib/qe_io.c +10
-0+/* calculate pin location */ + pin_mask = (u32) (1 << (NUM_OF_PINS -1 - gpio)); + + tmp_val =in_be32 (®s->cpdata); + +if (val ==0 ) +out_be32 (®s->cpdata, ~pin_mask & tmp_val); +else +out_be32 (®s->cpdata, pin_mask | tmp_val); +}
I see a possible problem with this (and in the corresponding call in CPM1, as well):
if there is a pin configured as open drain, you might accidently switch this pin to 0 while switching a different pin, if an external device is pulling the pin to 0.
i2c-gpio.c and w1-gpio.c (in -mm) are examples of drivers which use open drain pins and which would fail if another pin on the same port would be set during a transfer.
Thanks,
Jochen
Re: [PATCH 3/3] [POWERPC] QE: implement GPIO LIB API
Quoted 22 lines · Jochen Friedrich
Hi Anton,
Quoted 7 lines
arch/powerpc/sysdev/qe_lib/qe_io.c +7
-0+static void qe_gpio_set (struct gpio_chip *gc,unsigned int gpio,int val) +{ +struct of_mm_gpio_chip *mm_gc =to_of_mm_gpio_chip (gc); +struct port_regs *regs = mm_gc->regs; +u32 pin_mask; +u32 tmp_val; +arch/powerpc/sysdev/qe_lib/qe_io.c int par_io_of_config(struct device_node *np) · line 249
Quoted 10 lines
arch/powerpc/sysdev/qe_lib/qe_io.c +10
-0+/* calculate pin location */ + pin_mask = (u32) (1 << (NUM_OF_PINS -1 - gpio)); + + tmp_val =in_be32 (®s->cpdata); + +if (val ==0 ) +out_be32 (®s->cpdata, ~pin_mask & tmp_val); +else +out_be32 (®s->cpdata, pin_mask | tmp_val); +}I see a possible problem with this (and in the corresponding call in CPM1, as well):
Quoted 2 lines
if there is a pin configured as open drain, you might accidently switch this pin to 0 while switching a different pin, if an external device is pulling the pin to 0.
Unfortunately I can't think out any workaround for this, except implementing generic gpio_bank_{,un}lock(gpio_pin_on_the_bank), and start using it in the drivers that might care about this issue. Though, looking into i2c-gpio.c I don't clearly see were we can insert these locks, there should be "start/end transaction" handlers or something, but it seems that it's in the bitbanging code, not in the i2c-gpio driver..
Actually, I see this as a hardware limitation. For example, on ARMs PXA2xx, there are separate, per bank, read/set/clear GPIO registers, not all-in-one data register.
Signature · 4 lines
Anton Vorontsov email: [email protected] backup email: [email protected] irc://irc.freenode.net/bd2
Re: [PATCH 3/3] [POWERPC] QE: implement GPIO LIB API
Quoted 34 lines · Anton Vorontsov
Quoted 22 lines · Jochen Friedrich
Hi Anton,
Quoted 7 lines
arch/powerpc/sysdev/qe_lib/qe_io.c +7
-0+static void qe_gpio_set (struct gpio_chip *gc,unsigned int gpio,int val) +{ +struct of_mm_gpio_chip *mm_gc =to_of_mm_gpio_chip (gc); +struct port_regs *regs = mm_gc->regs; +u32 pin_mask; +u32 tmp_val; +arch/powerpc/sysdev/qe_lib/qe_io.c int par_io_of_config(struct device_node *np) · line 249
Quoted 10 lines
arch/powerpc/sysdev/qe_lib/qe_io.c +10
-0+/* calculate pin location */ + pin_mask = (u32) (1 << (NUM_OF_PINS -1 - gpio)); + + tmp_val =in_be32 (®s->cpdata); + +if (val ==0 ) +out_be32 (®s->cpdata, ~pin_mask & tmp_val); +else +out_be32 (®s->cpdata, pin_mask | tmp_val); +}I see a possible problem with this (and in the corresponding call in CPM1, as well):
Quoted 2 lines
if there is a pin configured as open drain, you might accidently switch this pin to 0 while switching a different pin, if an external device is pulling the pin to 0.
Unfortunately I can't think out any workaround for this, except implementing generic gpio_bank_{,un}lock(gpio_pin_on_the_bank), and start using it in the drivers that might care about this issue. Though, looking into
i2c-gpio.cI don't clearly see were we can insert these locks, there should be "start/end transaction" handlers or something, but it seems that it's in the bitbanging code, not in the i2c-gpio driver..
Quoted 3 lines
Actually, I see this as a hardware limitation. For example, on ARMs PXA2xx, there are separate, per bank, read/set/clear GPIO registers, not all-in-one data register.
I've run into this exact issue on other GPIO hardware too. It's not uncommon behaviour in GPIO hardware.
The solution is to not depend on the hardware to remember what the output pin values should be. Add a shadow register in the driver private data. Set the pin state for each output pin in the shadow register and then write that value to the hardware. That way input state doesn't interfere with the output values.
Also, you do still need spinlocks around the manipulation of the shared registers; otherwise you'll have very hard to debug race conditions. Probably one spin lock per bank.
Here's what I did for a Xilinx GPIO block driver (but ignore the fact that I'm not using driver private data so only one GPIO block can be supported; that will be fixed before I post this driver)
+void gpio_set_value(unsigned gpio, int value)
+{
+ unsigned long flags;
+
+ if (!gpio_regs)
+ return;
+
+ spin_lock_irqsave(&gpio_spinlock, flags);
+ if (value)
+ gpio_output_state |= 1<<gpio;
+ else
+ gpio_output_state &= ~(1<<gpio);
+ out_be32(gpio_regs, gpio_output_state);
+ spin_unlock_irqrestore(&gpio_spinlock, flags);
+}
+EXPORT_SYMBOL_GPL(gpio_set_value);
Cheers,
g.
Quoted 11 lines
--
Anton Vorontsov
email: [email protected]
backup email: [email protected]
irc://irc.freenode.net/bd2
_______________________________________________
Linuxppc-dev mailing list
[email protected]
https://ozlabs.org/mailman/listinfo/linuxppc-dev
Signature · 2 lines
Grant Likely, B.Sc., P.Eng. Secret Lab Technologies Ltd.
Re: [PATCH 3/3] [POWERPC] QE: implement GPIO LIB API
Quoted 38 lines · Anton Vorontsov
Quoted 34 lines · Jochen Friedrich
Quoted 22 lines
Hi Anton,
Quoted 7 lines
arch/powerpc/sysdev/qe_lib/qe_io.c +7
-0+static void qe_gpio_set (struct gpio_chip *gc,unsigned int gpio,int val) +{ +struct of_mm_gpio_chip *mm_gc =to_of_mm_gpio_chip (gc); +struct port_regs *regs = mm_gc->regs; +u32 pin_mask; +u32 tmp_val; +arch/powerpc/sysdev/qe_lib/qe_io.c int par_io_of_config(struct device_node *np) · line 249
Quoted 10 lines
arch/powerpc/sysdev/qe_lib/qe_io.c +10
-0+/* calculate pin location */ + pin_mask = (u32) (1 << (NUM_OF_PINS -1 - gpio)); + + tmp_val =in_be32 (®s->cpdata); + +if (val ==0 ) +out_be32 (®s->cpdata, ~pin_mask & tmp_val); +else +out_be32 (®s->cpdata, pin_mask | tmp_val); +}I see a possible problem with this (and in the corresponding call in CPM1, as well):
Quoted 2 lines
if there is a pin configured as open drain, you might accidently switch this pin to 0 while switching a different pin, if an external device is pulling the pin to 0.
Unfortunately I can't think out any workaround for this, except implementing generic gpio_bank_{,un}lock(gpio_pin_on_the_bank), and start using it in the drivers that might care about this issue. Though, looking into
i2c-gpio.cI don't clearly see were we can insert these locks, there should be "start/end transaction" handlers or something, but it seems that it's in the bitbanging code, not in the i2c-gpio driver..Quoted 3 lines
Actually, I see this as a hardware limitation. For example, on ARMs PXA2xx, there are separate, per bank, read/set/clear GPIO registers, not all-in-one data register.
Quoted 8 lines
I've run into this exact issue on other GPIO hardware too. It's not uncommon behaviour in GPIO hardware.
The solution is to not depend on the hardware to remember what the output pin values should be. Add a shadow register in the driver private data. Set the pin state for each output pin in the shadow register and then write that value to the hardware. That way input state doesn't interfere with the output values.
Great idea, much thanks. Would be easy to implement also.
Quoted 3 lines
Also, you do still need spinlocks around the manipulation of the shared registers; otherwise you'll have very hard to debug race conditions. Probably one spin lock per bank.
With GPIO LIB we already have per bank spinlock, so it isn't a problem.
Thanks,
Signature · 4 lines
Anton Vorontsov email: [email protected] backup email: [email protected] irc://irc.freenode.net/bd2
Quoted 4 lines · Anton Vorontsov
Hi all,
Thanks for the previous review and ideas. Here is the RFC for the GPIO LIB support.
I like this layout for gpios. It's concise and compact. It will work well for my gpio driver also.
Quoted 6 lines
I'm using it like this:
qe_pio_a: gpio-controller@1400 { #gpio-cells = <1>; compatible = "fsl,qe-pario-bank";
Here's my only comment: Compatible should have "fsl,<chip>-pario-bank" first. Be specific for the first value of the compatible property. You can add generic names after the specific one if you like, but it's hard to come up with a generic name when you don't know what a manufacture is going to do with it's marketing names in the future.
Quoted 66 lines
reg = <0x1400 0x18>; gpio-controller; }; qe_pio_e: gpio-controller@1460 { #gpio-cells = <1>; compatible = "fsl,qe-pario-bank"; reg = <0x1460 0x18>; gpio-controller; }; nand-flash@1,0 { compatible = "stmicro,NAND512W3A2BN6E", "fsl,upm-nand"; reg = <1 0 1>; width = <1>; upm = "A"; upm-addr-offset = <16>; upm-cmd-offset = <8>; gpios = <&qe_pio_e 18 &qe_pio_a 9>; wait-pattern; wait-write; };As you can see I've split single "
par_io" node into banks, thus the benefits:
- we can handle banks of different width (Jochen Friedrich asked for this, IIRC. Or I've misunderstood ;-).
- we can handle banks with different paddings (no more #ifdef PPC85xx).Also, it's possible to specify different gpio-controllers in the gpios = <> property. gpio-specifier is controller specific.
The remaining question is about
gpio.cplacement.prom_parse.cdoesn't feel as the appropriate place anymore. I think of:-
drivers/gpio/of_gpio.c(driver/gpio/ is in -mm tree);
-drivers/of/gpio.c
- keep it inarch/powerpc/kernel/(though, there is nothing much PowerPC specific).So, to try these patches you'll need apply these from the -mm tree:
generic-gpio-gpio_chip-support.patch generic-gpio-gpio_chip-support-fix.patch generic-gpio-gpio_chip-support-gpiolib-locking-simplified.patchOr just issue this in your working tree:
git pull
git://git.infradead.org/users/cbou/powerpc-gpio.gitgpiolibpowerpc-gpio.git's gpiolib branch is galak/powerpc.git master branch + -mm patches + these patches.
Support for CPM2 is pending.
Thanks!
--
Anton Vorontsov
email: [email protected]
backup email: [email protected]
irc://irc.freenode.net/bd2
Signature · 2 lines
Grant Likely, B.Sc., P.Eng. Secret Lab Technologies Ltd.