CPM1: implement GPIO LIB API
Subsystems (2)
---arch/powerpc/platforms/8xx/Kconfig | 2 +arch/powerpc/sysdev/commproc.c | 162 +++++++++++++++++++++++++++++++++++-
2 files changed, 163 insertions(+), 1 deletions(-)
arch/powerpc/platforms/8xx/Kconfig +0 -0
@@ -4,6 +4,8 @@ config FADS
config CPM1
bool
select CPM
+ select GENERIC_GPIO
+ select GPIO_LIB
choice
prompt "8xx Machine Type"
arch/powerpc/sysdev/commproc.c +0 -0
@@ -36,6 +36,7 @@
#include <asm/8xx_immap.h>
#include <asm/commproc.h>
#include <asm/io.h>
+#include <asm/gpio.h>
#include <asm/tlbflush.h>
#include <asm/rheap.h>
#include <asm/prom.h>
@@ -441,7 +442,7 @@ struct cpm_ioport16 {
};
struct cpm_ioport32 {
- __be32 dir, par, sor;
+ __be32 dir, par, sor, dat;
};
static void cpm1_set_pin32(int port, int pin, int flags)
@@ -648,3 +649,162 @@ int cpm1_clk_setup(enum cpm_clk_target target, int clock, int mode)
return 0; }
+
+/*
+ * GPIO LIB API implementation
+ */
+
+static int cpm1_gpio_get16(struct gpio_chip *gc, unsigned int gpio) +{
+ struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
+ struct cpm_ioport16 __iomem *iop = mm_gc->regs;
+ u16 pin_mask;
+
+ pin_mask = 1 << (15 - gpio);
+
+ return !!(in_be16(&iop->dat) & pin_mask);
+}
+
+static void cpm1_gpio_set16(struct gpio_chip *gc, unsigned int gpio, int value) +{
+ struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
+ struct cpm_ioport16 __iomem *iop = mm_gc->regs;
+ u16 pin_mask;
+
+ pin_mask = 1 << (15 - gpio);
+
+ if (value)
+ setbits16(&iop->dat, pin_mask);
+ else
+ clrbits16(&iop->dat, pin_mask);
+}
+
+static int cpm1_gpio_dir_out16(struct gpio_chip *gc, unsigned int gpio, int val) +{
+ struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
+ struct cpm_ioport16 __iomem *iop = mm_gc->regs;
+ u16 pin_mask;
+
+ pin_mask = 1 << (15 - gpio);
+
+ setbits16(&iop->dir, pin_mask);
+
+ cpm1_gpio_set16(gc, gpio, val);
+
+ return 0;
+}
+
+static int cpm1_gpio_dir_in16(struct gpio_chip *gc, unsigned int gpio) +{
+ struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
+ struct cpm_ioport16 __iomem *iop = mm_gc->regs;
+ u16 pin_mask;
+
+ pin_mask = 1 << (15 - gpio);
+
+ clrbits16(&iop->dir, pin_mask);
+
+ return 0;
+}
+
+static struct of_gpio_chip cpm1_gc16 = {
+ .gpio_cells = 1,
+ .xlate = of_gpio_simple_xlate,
+
+ .gc = {
+ .ngpio = 16,
+ .direction_input = cpm1_gpio_dir_in16,
+ .direction_output = cpm1_gpio_dir_out16,
+ .get = cpm1_gpio_get16,
+ .set = cpm1_gpio_set16,
+ },
+};
+
+int cpm1_gpiochip_add16(struct device_node *np)
+{
+ return of_mm_gpiochip_add(np, &cpm1_gc16);
+}
+
+static int cpm1_gpio_get32(struct gpio_chip *gc, unsigned int gpio) +{
+ struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
+ struct cpm_ioport32 __iomem *iop = mm_gc->regs;
+ u32 pin_mask;
+
+ pin_mask = 1 << (31 - gpio);
+
+ return !!(in_be32(&iop->dat) & pin_mask);
+}
+
+static void cpm1_gpio_set32(struct gpio_chip *gc, unsigned int gpio, int value) +{
+ struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
+ struct cpm_ioport32 __iomem *iop = mm_gc->regs;
+ u32 pin_mask;
+
+ pin_mask = 1 << (31 - gpio);
+
+ if (value)
+ setbits32(&iop->dat, pin_mask);
+ else
+ clrbits32(&iop->dat, pin_mask);
+}
+
+static int cpm1_gpio_dir_out32(struct gpio_chip *gc, unsigned int gpio, int val) +{
+ struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
+ struct cpm_ioport32 __iomem *iop = mm_gc->regs;
+ u32 pin_mask;
+
+ pin_mask = 1 << (31 - gpio);
+
+ setbits32(&iop->dir, pin_mask);
+
+ cpm1_gpio_set32(gc, gpio, val);
+
+ return 0;
+}
+
+static int cpm1_gpio_dir_in32(struct gpio_chip *gc, unsigned int gpio) +{
+ struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
+ struct cpm_ioport32 __iomem *iop = mm_gc->regs;
+ u32 pin_mask;
+
+ pin_mask = 1 << (31 - gpio);
+
+ clrbits32(&iop->dir, pin_mask);
+
+ return 0;
+}
+
+static struct of_gpio_chip cpm1_gc32 = {
+ .gpio_cells = 1,
+ .xlate = of_gpio_simple_xlate,
+
+ .gc = {
+ .ngpio = 32,
+ .direction_input = cpm1_gpio_dir_in32,
+ .direction_output = cpm1_gpio_dir_out32,
+ .get = cpm1_gpio_get32,
+ .set = cpm1_gpio_set32,
+ },
+};
+
+int cpm1_gpiochip_add32(struct device_node *np)
+{
+ return of_mm_gpiochip_add(np, &cpm1_gc32);
+}
+
+static int cpm_init_par_io(void)
+{
+ struct device_node *np;
+
+ for_each_compatible_node(np, NULL, "fsl,cpm1-pario-bank16")
+ cpm1_gpiochip_add16(np);
+
+ for_each_compatible_node(np, NULL, "fsl,cpm1-pario-bank32")
+ cpm1_gpiochip_add32(np);
+ return 0;
+}
+arch_initcall(cpm_init_par_io);
Signature · 1 line
1.5.3.8
Hi Jochen,
Thanks for the patch.
Quoted 6 lines · Jochen Friedrich
Signed-off-by Jochen Friedrich <[email protected]>---
arch/powerpc/platforms/8xx/Kconfig| 2 +arch/powerpc/sysdev/commproc.c| 162
+++++++++++++++++++++++++++++++++++-2 files changed, 163 insertions(+), 1 deletions(-)
Something happened wrt long lines, your editor seem to wrap them. :-(
Quoted 5 lines
arch/powerpc/platforms/8xx/Kconfig +0
-0
[...]
Quoted 4 lines
arch/powerpc/sysdev/commproc.c +0
-0
[...]
arch/powerpc/sysdev/commproc.c
Quoted 4 lines
arch/powerpc/sysdev/commproc.c +4
-0+int cpm1_gpiochip_add16 (struct device_node *np) +{ +return of_mm_gpiochip_add (np, &cpm1_gc16); +}
(1)
arch/powerpc/sysdev/commproc.c
Quoted 4 lines
arch/powerpc/sysdev/commproc.c +4
-0+int cpm1_gpiochip_add32 (struct device_node *np) +{ +return of_mm_gpiochip_add (np, &cpm1_gc32); +}
(2)
arch/powerpc/sysdev/commproc.c
Quoted 12 lines
arch/powerpc/sysdev/commproc.c +12
-0+static int cpm_init_par_io (void ) +{ +struct device_node *np; + +for_each_compatible_node (np,NULL ,"fsl,cpm1-pario-bank16" ) +cpm1_gpiochip_add16 (np); + +for_each_compatible_node (np,NULL ,"fsl,cpm1-pario-bank32" ) +cpm1_gpiochip_add32 (np); +return 0 ; +} +arch_initcall (cpm_init_par_io);
I was unable to use arch_initcall() because lack of kmalloc() that early (needed for of_mm_gpiochip_add() and GPIO LIB in general). So, does it really work here?
Though, I tried arch_initcall() in the board file, and well... link order matters a lot, so arch_initcall could indeed work in the arch/powerpc/sysdev/. I should try that for QE. :-)
If it works, you'd better make (1) and (2) static, or just remove them completely, since there are no users outside of this file.
Thanks!
Signature · 4 lines
Anton Vorontsov email: [email protected] backup email: [email protected] irc://irc.freenode.net/bd2
Hi Jochen,
comments below.
Quoted 2 lines · Jochen Friedrich
Signed-off-by Jochen Friedrich <[email protected]>---
Need a more detailed change description.
Quoted 2 lines
arch/powerpc/platforms/8xx/Kconfig | 2 + arch/powerpc/sysdev/commproc.c | 162 +++++++++++++++++++++++++++++++++++-
Is this 8xx only? Can it live in arch/powerpc/platforms/8xx?
Quoted 14 lines
2 files changed, 163 insertions(+), 1 deletions(-)(quoted diff) +12
-0+static struct of_gpio_chip cpm1_gc16 = { + .gpio_cells = 1, + .xlate = of_gpio_simple_xlate, + + .gc = { + .ngpio = 16, + .direction_input = cpm1_gpio_dir_in16, + .direction_output = cpm1_gpio_dir_out16, + .get = cpm1_gpio_get16, + .set = cpm1_gpio_set16, + }, +};
<snip>
Review
Quoted 12 lines
(quoted diff) +12
-0+static struct of_gpio_chip cpm1_gc32 = { + .gpio_cells = 1, + .xlate = of_gpio_simple_xlate, + + .gc = { + .ngpio = 32, + .direction_input = cpm1_gpio_dir_in32, + .direction_output = cpm1_gpio_dir_out32, + .get = cpm1_gpio_get32, + .set = cpm1_gpio_set32, + }, +};
Nit: Your naming convention seems a little backwards. It took me a moment to figure out what your hooks lined up with. Can you make the '16' and '32' part of the prefix instead of appended on the end?
ie. use 'cpm1_gpio16_dir_in' instead of 'cpm1_gpio_dir_in16'
Review
Quoted 4 lines
(quoted diff) +4
-0+int cpm1_gpiochip_add32(struct device_node *np) +{ + return of_mm_gpiochip_add(np, &cpm1_gc32); +}
Can you just drop this function and roll it into cpm_init_par_io?
Review
Quoted 13 lines
(quoted diff) +13
-0+ +static int cpm_init_par_io(void) +{ + struct device_node *np; + + for_each_compatible_node(np, NULL, "fsl,cpm1-pario-bank16") + cpm1_gpiochip_add16(np); + + for_each_compatible_node(np, NULL, "fsl,cpm1-pario-bank32") + cpm1_gpiochip_add32(np); + return 0; +} +arch_initcall(cpm_init_par_io);
Cheers,
g.
Signature · 2 lines
Grant Likely, B.Sc., P.Eng. Secret Lab Technologies Ltd.
Hi Grant,
Quoted 4 lines
Quoted 2 lines
arch/powerpc/platforms/8xx/Kconfig | 2 + arch/powerpc/sysdev/commproc.c | 162 +++++++++++++++++++++++++++++++++++-Is this 8xx only? Can it live in
arch/powerpc/platforms/8xx?
According to the freescale docs, the GPIO ports are part of the CPM1. So I've put the support into commproc.c (which maybe should be renamed to cpm1_common.c to match cpm2_common.c).
AFAIK, CPM1 is specific to 8xx.
Thanks,
Jochen
Quoted 11 lines · Jochen Friedrich
Hi Grant,
Quoted 4 lines
Quoted 2 lines
arch/powerpc/platforms/8xx/Kconfig | 2 + arch/powerpc/sysdev/commproc.c | 162 +++++++++++++++++++++++++++++++++++-Is this 8xx only? Can it live in
arch/powerpc/platforms/8xx?According to the freescale docs, the GPIO ports are part of the CPM1. So I've put the support into
commproc.c(which maybe should be renamed tocpm1_common.cto matchcpm2_common.c).AFAIK, CPM1 is specific to 8xx.
If we're going to rename, I'd change commproc.c to cpm1.c, and cpm2_common.c to cpm2.c.
-Scott