* [PATCH2/2] [POWERPC] CPM1: implement GPIO LIB API on CPM1 Freescale SoC.
@ 2008-04-18 17:10 Jochen Friedrich
2008-04-21 14:30 ` Grant Likely
0 siblings, 1 reply; 4+ messages in thread
From: Jochen Friedrich @ 2008-04-18 17:10 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev list, Scott Wood
This patch implement GPIO LIB support for the CPM1 GPIOs.
Signed-off-by: Jochen Friedrich <jochen@scram.de>
---
arch/powerpc/platforms/8xx/Kconfig | 10 ++
arch/powerpc/sysdev/cpm1.c | 261 +++++++++++++++++++++++++++++++++++-
2 files changed, 266 insertions(+), 5 deletions(-)
diff --git a/arch/powerpc/platforms/8xx/Kconfig b/arch/powerpc/platforms/8xx/Kconfig
index 6fc849e..3488bb7 100644
--- a/arch/powerpc/platforms/8xx/Kconfig
+++ b/arch/powerpc/platforms/8xx/Kconfig
@@ -105,6 +105,16 @@ config 8xx_COPYBACK
If in doubt, say Y here.
+config 8xx_GPIO
+ bool "GPIO API Support"
+ select GENERIC_GPIO
+ select HAVE_GPIO_LIB
+ help
+ Saying Y here will cause the ports on an MPC8xx processor to be used
+ with the GPIO API. If you say N here, the kernel needs less memory.
+
+ If in doubt, say Y here.
+
config 8xx_CPU6
bool "CPU6 Silicon Errata (860 Pre Rev. C)"
help
diff --git a/arch/powerpc/sysdev/cpm1.c b/arch/powerpc/sysdev/cpm1.c
index 58292a0..01ae3ae 100644
--- a/arch/powerpc/sysdev/cpm1.c
+++ b/arch/powerpc/sysdev/cpm1.c
@@ -30,6 +30,7 @@
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/module.h>
+#include <linux/spinlock.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/8xx_immap.h>
@@ -42,6 +43,10 @@
#include <asm/fs_pd.h>
+#ifdef CONFIG_8xx_GPIO
+#include <linux/of_gpio.h>
+#endif
+
#define CPM_MAP_SIZE (0x4000)
cpm8xx_t __iomem *cpmp; /* Pointer to comm processor space */
@@ -290,20 +295,24 @@ struct cpm_ioport16 {
__be16 res[3];
};
-struct cpm_ioport32 {
- __be32 dir, par, sor;
+struct cpm_ioport32b {
+ __be32 dir, par, odr, dat;
+};
+
+struct cpm_ioport32e {
+ __be32 dir, par, sor, odr, dat;
};
static void cpm1_set_pin32(int port, int pin, int flags)
{
- struct cpm_ioport32 __iomem *iop;
+ struct cpm_ioport32e __iomem *iop;
pin = 1 << (31 - pin);
if (port == CPM_PORTB)
- iop = (struct cpm_ioport32 __iomem *)
+ iop = (struct cpm_ioport32e __iomem *)
&mpc8xx_immr->im_cpm.cp_pbdir;
else
- iop = (struct cpm_ioport32 __iomem *)
+ iop = (struct cpm_ioport32e __iomem *)
&mpc8xx_immr->im_cpm.cp_pedir;
if (flags & CPM_PIN_OUTPUT)
@@ -498,3 +507,245 @@ int cpm1_clk_setup(enum cpm_clk_target target, int clock, int mode)
return 0;
}
+
+/*
+ * GPIO LIB API implementation
+ */
+#ifdef CONFIG_8xx_GPIO
+
+struct cpm1_gpio16_chip {
+ struct of_mm_gpio_chip mm_gc;
+ spinlock_t lock;
+
+ /* shadowed data register to clear/set bits safely */
+ u16 cpdata;
+};
+
+static inline struct cpm1_gpio16_chip *
+to_cpm1_gpio16_chip(struct of_mm_gpio_chip *mm_gc)
+{
+ return container_of(mm_gc, struct cpm1_gpio16_chip, mm_gc);
+}
+
+static void cpm1_gpio16_save_regs(struct of_mm_gpio_chip *mm_gc)
+{
+ struct cpm1_gpio16_chip *cpm1_gc = to_cpm1_gpio16_chip(mm_gc);
+ struct cpm_ioport16 __iomem *iop = mm_gc->regs;
+
+ cpm1_gc->cpdata = in_be16(&iop->dat);
+}
+
+static int cpm1_gpio16_get(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_gpio16_set(struct gpio_chip *gc, unsigned int gpio, int value)
+{
+ struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
+ struct cpm1_gpio16_chip *cpm1_gc = to_cpm1_gpio16_chip(mm_gc);
+ struct cpm_ioport16 __iomem *iop = mm_gc->regs;
+ unsigned long flags;
+ u16 pin_mask = 1 << (15 - gpio);
+
+ spin_lock_irqsave(&cpm1_gc->lock, flags);
+
+ if (value)
+ cpm1_gc->cpdata |= pin_mask;
+ else
+ cpm1_gc->cpdata &= ~pin_mask;
+
+ out_be16(&iop->dat, cpm1_gc->cpdata);
+
+ spin_unlock_irqrestore(&cpm1_gc->lock, flags);
+}
+
+static int cpm1_gpio16_dir_out(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_gpio16_set(gc, gpio, val);
+
+ return 0;
+}
+
+static int cpm1_gpio16_dir_in(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;
+}
+
+int cpm1_gpiochip_add16(struct device_node *np)
+{
+ struct cpm1_gpio16_chip *cpm1_gc;
+ struct of_mm_gpio_chip *mm_gc;
+ struct of_gpio_chip *of_gc;
+ struct gpio_chip *gc;
+
+ cpm1_gc = kzalloc(sizeof(*cpm1_gc), GFP_KERNEL);
+ if (!cpm1_gc)
+ return -ENOMEM;
+
+ spin_lock_init(&cpm1_gc->lock);
+
+ mm_gc = &cpm1_gc->mm_gc;
+ of_gc = &mm_gc->of_gc;
+ gc = &of_gc->gc;
+
+ mm_gc->save_regs = cpm1_gpio16_save_regs;
+ of_gc->gpio_cells = 1;
+ gc->ngpio = 16;
+ gc->direction_input = cpm1_gpio16_dir_in;
+ gc->direction_output = cpm1_gpio16_dir_out;
+ gc->get = cpm1_gpio16_get;
+ gc->set = cpm1_gpio16_set;
+
+ return of_mm_gpiochip_add(np, mm_gc);
+}
+
+struct cpm1_gpio32_chip {
+ struct of_mm_gpio_chip mm_gc;
+ spinlock_t lock;
+
+ /* shadowed data register to clear/set bits safely */
+ u32 cpdata;
+};
+
+static inline struct cpm1_gpio32_chip *
+to_cpm1_gpio32_chip(struct of_mm_gpio_chip *mm_gc)
+{
+ return container_of(mm_gc, struct cpm1_gpio32_chip, mm_gc);
+}
+
+static void cpm1_gpio32_save_regs(struct of_mm_gpio_chip *mm_gc)
+{
+ struct cpm1_gpio32_chip *cpm1_gc = to_cpm1_gpio32_chip(mm_gc);
+ struct cpm_ioport32b __iomem *iop = mm_gc->regs;
+
+ cpm1_gc->cpdata = in_be32(&iop->dat);
+}
+
+static int cpm1_gpio32_get(struct gpio_chip *gc, unsigned int gpio)
+{
+ struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
+ struct cpm_ioport32b __iomem *iop = mm_gc->regs;
+ u32 pin_mask;
+
+ pin_mask = 1 << (31 - gpio);
+
+ return !!(in_be32(&iop->dat) & pin_mask);
+}
+
+static void cpm1_gpio32_set(struct gpio_chip *gc, unsigned int gpio, int value)
+{
+ struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
+ struct cpm1_gpio32_chip *cpm1_gc = to_cpm1_gpio32_chip(mm_gc);
+ struct cpm_ioport32b __iomem *iop = mm_gc->regs;
+ unsigned long flags;
+ u32 pin_mask = 1 << (31 - gpio);
+
+ spin_lock_irqsave(&cpm1_gc->lock, flags);
+
+ if (value)
+ cpm1_gc->cpdata |= pin_mask;
+ else
+ cpm1_gc->cpdata &= ~pin_mask;
+
+ out_be32(&iop->dat, cpm1_gc->cpdata);
+
+ spin_unlock_irqrestore(&cpm1_gc->lock, flags);
+}
+
+static int cpm1_gpio32_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
+{
+ struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
+ struct cpm_ioport32b __iomem *iop = mm_gc->regs;
+ u32 pin_mask;
+
+ pin_mask = 1 << (31 - gpio);
+
+ setbits32(&iop->dir, pin_mask);
+
+ cpm1_gpio32_set(gc, gpio, val);
+
+ return 0;
+}
+
+static int cpm1_gpio32_dir_in(struct gpio_chip *gc, unsigned int gpio)
+{
+ struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
+ struct cpm_ioport32b __iomem *iop = mm_gc->regs;
+ u32 pin_mask;
+
+ pin_mask = 1 << (31 - gpio);
+
+ clrbits32(&iop->dir, pin_mask);
+
+ return 0;
+}
+
+int cpm1_gpiochip_add32(struct device_node *np)
+{
+ struct cpm1_gpio32_chip *cpm1_gc;
+ struct of_mm_gpio_chip *mm_gc;
+ struct of_gpio_chip *of_gc;
+ struct gpio_chip *gc;
+
+ cpm1_gc = kzalloc(sizeof(*cpm1_gc), GFP_KERNEL);
+ if (!cpm1_gc)
+ return -ENOMEM;
+
+ spin_lock_init(&cpm1_gc->lock);
+
+ mm_gc = &cpm1_gc->mm_gc;
+ of_gc = &mm_gc->of_gc;
+ gc = &of_gc->gc;
+
+ mm_gc->save_regs = cpm1_gpio32_save_regs;
+ of_gc->gpio_cells = 1;
+ gc->ngpio = 32;
+ gc->direction_input = cpm1_gpio32_dir_in;
+ gc->direction_output = cpm1_gpio32_dir_out;
+ gc->get = cpm1_gpio32_get;
+ gc->set = cpm1_gpio32_set;
+
+ return of_mm_gpiochip_add(np, mm_gc);
+}
+
+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-bank32b")
+ cpm1_gpiochip_add32(np);
+
+ /* Port E uses CPM2 layout */
+ for_each_compatible_node(np, NULL, "fsl,cpm1-pario-bank32e")
+ cpm2_gpiochip_add32(np);
+ return 0;
+}
+arch_initcall(cpm_init_par_io);
+
+#endif /* CONFIG_8xx_GPIO */
--
1.5.5
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH2/2] [POWERPC] CPM1: implement GPIO LIB API on CPM1 Freescale SoC.
2008-04-18 17:10 [PATCH2/2] [POWERPC] CPM1: implement GPIO LIB API on CPM1 Freescale SoC Jochen Friedrich
@ 2008-04-21 14:30 ` Grant Likely
2008-07-01 15:40 ` Jochen Friedrich
0 siblings, 1 reply; 4+ messages in thread
From: Grant Likely @ 2008-04-21 14:30 UTC (permalink / raw)
To: Jochen Friedrich; +Cc: Scott Wood, linuxppc-dev list
On Fri, Apr 18, 2008 at 11:10 AM, Jochen Friedrich <jochen@scram.de> wrote:
> This patch implement GPIO LIB support for the CPM1 GPIOs.
>
> Signed-off-by: Jochen Friedrich <jochen@scram.de>
> ---
> arch/powerpc/platforms/8xx/Kconfig | 10 ++
> arch/powerpc/sysdev/cpm1.c | 261 +++++++++++++++++++++++++++++++++++-
> 2 files changed, 266 insertions(+), 5 deletions(-)
2 quick comments:
1. You need to include binding documentation to booting without of
2. You need to specifiy exact chip names in your compatible string.
"fsl,cpm1-pario-<bank>" is a made up thing.
Cheers,
g.
>
> diff --git a/arch/powerpc/platforms/8xx/Kconfig b/arch/powerpc/platforms/8xx/Kconfig
> index 6fc849e..3488bb7 100644
> --- a/arch/powerpc/platforms/8xx/Kconfig
> +++ b/arch/powerpc/platforms/8xx/Kconfig
> @@ -105,6 +105,16 @@ config 8xx_COPYBACK
>
> If in doubt, say Y here.
>
> +config 8xx_GPIO
> + bool "GPIO API Support"
> + select GENERIC_GPIO
> + select HAVE_GPIO_LIB
> + help
> + Saying Y here will cause the ports on an MPC8xx processor to be used
> + with the GPIO API. If you say N here, the kernel needs less memory.
> +
> + If in doubt, say Y here.
> +
> config 8xx_CPU6
> bool "CPU6 Silicon Errata (860 Pre Rev. C)"
> help
> diff --git a/arch/powerpc/sysdev/cpm1.c b/arch/powerpc/sysdev/cpm1.c
> index 58292a0..01ae3ae 100644
> --- a/arch/powerpc/sysdev/cpm1.c
> +++ b/arch/powerpc/sysdev/cpm1.c
> @@ -30,6 +30,7 @@
> #include <linux/interrupt.h>
> #include <linux/irq.h>
> #include <linux/module.h>
> +#include <linux/spinlock.h>
> #include <asm/page.h>
> #include <asm/pgtable.h>
> #include <asm/8xx_immap.h>
> @@ -42,6 +43,10 @@
>
> #include <asm/fs_pd.h>
>
> +#ifdef CONFIG_8xx_GPIO
> +#include <linux/of_gpio.h>
> +#endif
> +
> #define CPM_MAP_SIZE (0x4000)
>
> cpm8xx_t __iomem *cpmp; /* Pointer to comm processor space */
> @@ -290,20 +295,24 @@ struct cpm_ioport16 {
> __be16 res[3];
> };
>
> -struct cpm_ioport32 {
> - __be32 dir, par, sor;
> +struct cpm_ioport32b {
> + __be32 dir, par, odr, dat;
> +};
> +
> +struct cpm_ioport32e {
> + __be32 dir, par, sor, odr, dat;
> };
>
> static void cpm1_set_pin32(int port, int pin, int flags)
> {
> - struct cpm_ioport32 __iomem *iop;
> + struct cpm_ioport32e __iomem *iop;
> pin = 1 << (31 - pin);
>
> if (port == CPM_PORTB)
> - iop = (struct cpm_ioport32 __iomem *)
> + iop = (struct cpm_ioport32e __iomem *)
> &mpc8xx_immr->im_cpm.cp_pbdir;
> else
> - iop = (struct cpm_ioport32 __iomem *)
> + iop = (struct cpm_ioport32e __iomem *)
> &mpc8xx_immr->im_cpm.cp_pedir;
>
> if (flags & CPM_PIN_OUTPUT)
> @@ -498,3 +507,245 @@ int cpm1_clk_setup(enum cpm_clk_target target, int clock, int mode)
>
> return 0;
> }
> +
> +/*
> + * GPIO LIB API implementation
> + */
> +#ifdef CONFIG_8xx_GPIO
> +
> +struct cpm1_gpio16_chip {
> + struct of_mm_gpio_chip mm_gc;
> + spinlock_t lock;
> +
> + /* shadowed data register to clear/set bits safely */
> + u16 cpdata;
> +};
> +
> +static inline struct cpm1_gpio16_chip *
> +to_cpm1_gpio16_chip(struct of_mm_gpio_chip *mm_gc)
> +{
> + return container_of(mm_gc, struct cpm1_gpio16_chip, mm_gc);
> +}
> +
> +static void cpm1_gpio16_save_regs(struct of_mm_gpio_chip *mm_gc)
> +{
> + struct cpm1_gpio16_chip *cpm1_gc = to_cpm1_gpio16_chip(mm_gc);
> + struct cpm_ioport16 __iomem *iop = mm_gc->regs;
> +
> + cpm1_gc->cpdata = in_be16(&iop->dat);
> +}
> +
> +static int cpm1_gpio16_get(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_gpio16_set(struct gpio_chip *gc, unsigned int gpio, int value)
> +{
> + struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
> + struct cpm1_gpio16_chip *cpm1_gc = to_cpm1_gpio16_chip(mm_gc);
> + struct cpm_ioport16 __iomem *iop = mm_gc->regs;
> + unsigned long flags;
> + u16 pin_mask = 1 << (15 - gpio);
> +
> + spin_lock_irqsave(&cpm1_gc->lock, flags);
> +
> + if (value)
> + cpm1_gc->cpdata |= pin_mask;
> + else
> + cpm1_gc->cpdata &= ~pin_mask;
> +
> + out_be16(&iop->dat, cpm1_gc->cpdata);
> +
> + spin_unlock_irqrestore(&cpm1_gc->lock, flags);
> +}
> +
> +static int cpm1_gpio16_dir_out(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_gpio16_set(gc, gpio, val);
> +
> + return 0;
> +}
> +
> +static int cpm1_gpio16_dir_in(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;
> +}
> +
> +int cpm1_gpiochip_add16(struct device_node *np)
> +{
> + struct cpm1_gpio16_chip *cpm1_gc;
> + struct of_mm_gpio_chip *mm_gc;
> + struct of_gpio_chip *of_gc;
> + struct gpio_chip *gc;
> +
> + cpm1_gc = kzalloc(sizeof(*cpm1_gc), GFP_KERNEL);
> + if (!cpm1_gc)
> + return -ENOMEM;
> +
> + spin_lock_init(&cpm1_gc->lock);
> +
> + mm_gc = &cpm1_gc->mm_gc;
> + of_gc = &mm_gc->of_gc;
> + gc = &of_gc->gc;
> +
> + mm_gc->save_regs = cpm1_gpio16_save_regs;
> + of_gc->gpio_cells = 1;
> + gc->ngpio = 16;
> + gc->direction_input = cpm1_gpio16_dir_in;
> + gc->direction_output = cpm1_gpio16_dir_out;
> + gc->get = cpm1_gpio16_get;
> + gc->set = cpm1_gpio16_set;
> +
> + return of_mm_gpiochip_add(np, mm_gc);
> +}
> +
> +struct cpm1_gpio32_chip {
> + struct of_mm_gpio_chip mm_gc;
> + spinlock_t lock;
> +
> + /* shadowed data register to clear/set bits safely */
> + u32 cpdata;
> +};
> +
> +static inline struct cpm1_gpio32_chip *
> +to_cpm1_gpio32_chip(struct of_mm_gpio_chip *mm_gc)
> +{
> + return container_of(mm_gc, struct cpm1_gpio32_chip, mm_gc);
> +}
> +
> +static void cpm1_gpio32_save_regs(struct of_mm_gpio_chip *mm_gc)
> +{
> + struct cpm1_gpio32_chip *cpm1_gc = to_cpm1_gpio32_chip(mm_gc);
> + struct cpm_ioport32b __iomem *iop = mm_gc->regs;
> +
> + cpm1_gc->cpdata = in_be32(&iop->dat);
> +}
> +
> +static int cpm1_gpio32_get(struct gpio_chip *gc, unsigned int gpio)
> +{
> + struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
> + struct cpm_ioport32b __iomem *iop = mm_gc->regs;
> + u32 pin_mask;
> +
> + pin_mask = 1 << (31 - gpio);
> +
> + return !!(in_be32(&iop->dat) & pin_mask);
> +}
> +
> +static void cpm1_gpio32_set(struct gpio_chip *gc, unsigned int gpio, int value)
> +{
> + struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
> + struct cpm1_gpio32_chip *cpm1_gc = to_cpm1_gpio32_chip(mm_gc);
> + struct cpm_ioport32b __iomem *iop = mm_gc->regs;
> + unsigned long flags;
> + u32 pin_mask = 1 << (31 - gpio);
> +
> + spin_lock_irqsave(&cpm1_gc->lock, flags);
> +
> + if (value)
> + cpm1_gc->cpdata |= pin_mask;
> + else
> + cpm1_gc->cpdata &= ~pin_mask;
> +
> + out_be32(&iop->dat, cpm1_gc->cpdata);
> +
> + spin_unlock_irqrestore(&cpm1_gc->lock, flags);
> +}
> +
> +static int cpm1_gpio32_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
> +{
> + struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
> + struct cpm_ioport32b __iomem *iop = mm_gc->regs;
> + u32 pin_mask;
> +
> + pin_mask = 1 << (31 - gpio);
> +
> + setbits32(&iop->dir, pin_mask);
> +
> + cpm1_gpio32_set(gc, gpio, val);
> +
> + return 0;
> +}
> +
> +static int cpm1_gpio32_dir_in(struct gpio_chip *gc, unsigned int gpio)
> +{
> + struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
> + struct cpm_ioport32b __iomem *iop = mm_gc->regs;
> + u32 pin_mask;
> +
> + pin_mask = 1 << (31 - gpio);
> +
> + clrbits32(&iop->dir, pin_mask);
> +
> + return 0;
> +}
> +
> +int cpm1_gpiochip_add32(struct device_node *np)
> +{
> + struct cpm1_gpio32_chip *cpm1_gc;
> + struct of_mm_gpio_chip *mm_gc;
> + struct of_gpio_chip *of_gc;
> + struct gpio_chip *gc;
> +
> + cpm1_gc = kzalloc(sizeof(*cpm1_gc), GFP_KERNEL);
> + if (!cpm1_gc)
> + return -ENOMEM;
> +
> + spin_lock_init(&cpm1_gc->lock);
> +
> + mm_gc = &cpm1_gc->mm_gc;
> + of_gc = &mm_gc->of_gc;
> + gc = &of_gc->gc;
> +
> + mm_gc->save_regs = cpm1_gpio32_save_regs;
> + of_gc->gpio_cells = 1;
> + gc->ngpio = 32;
> + gc->direction_input = cpm1_gpio32_dir_in;
> + gc->direction_output = cpm1_gpio32_dir_out;
> + gc->get = cpm1_gpio32_get;
> + gc->set = cpm1_gpio32_set;
> +
> + return of_mm_gpiochip_add(np, mm_gc);
> +}
> +
> +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-bank32b")
> + cpm1_gpiochip_add32(np);
> +
> + /* Port E uses CPM2 layout */
> + for_each_compatible_node(np, NULL, "fsl,cpm1-pario-bank32e")
> + cpm2_gpiochip_add32(np);
> + return 0;
> +}
> +arch_initcall(cpm_init_par_io);
> +
> +#endif /* CONFIG_8xx_GPIO */
> --
> 1.5.5
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev
>
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH2/2] [POWERPC] CPM1: implement GPIO LIB API on CPM1 Freescale SoC.
2008-04-21 14:30 ` Grant Likely
@ 2008-07-01 15:40 ` Jochen Friedrich
2008-07-01 16:36 ` Grant Likely
0 siblings, 1 reply; 4+ messages in thread
From: Jochen Friedrich @ 2008-07-01 15:40 UTC (permalink / raw)
To: Grant Likely; +Cc: Scott Wood, linuxppc-dev list
Hi Grant,
sorry for the late response on this one.
> 2. You need to specifiy exact chip names in your compatible string.
> "fsl,cpm1-pario-<bank>" is a made up thing.
>> + for_each_compatible_node(np, NULL, "fsl,cpm1-pario-bank16")
>> + cpm1_gpiochip_add16(np);
>> +
>> + for_each_compatible_node(np, NULL, "fsl,cpm1-pario-bank32b")
>> + cpm1_gpiochip_add32(np);
>> +
>> + /* Port E uses CPM2 layout */
>> + for_each_compatible_node(np, NULL, "fsl,cpm1-pario-bank32e")
>> + cpm2_gpiochip_add32(np);
What do you suggest here?
All GPIO ports of CPM1/CPM2 are on the SoC, so the chip name is in fact the CPU itself
(like fsl,mpc866-pario-bank16).
Thanks,
Jochen
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH2/2] [POWERPC] CPM1: implement GPIO LIB API on CPM1 Freescale SoC.
2008-07-01 15:40 ` Jochen Friedrich
@ 2008-07-01 16:36 ` Grant Likely
0 siblings, 0 replies; 4+ messages in thread
From: Grant Likely @ 2008-07-01 16:36 UTC (permalink / raw)
To: Jochen Friedrich; +Cc: Scott Wood, linuxppc-dev list
On Tue, Jul 01, 2008 at 05:40:46PM +0200, Jochen Friedrich wrote:
> Hi Grant,
>
> sorry for the late response on this one.
>
> > 2. You need to specifiy exact chip names in your compatible string.
> > "fsl,cpm1-pario-<bank>" is a made up thing.
>
> >> + for_each_compatible_node(np, NULL, "fsl,cpm1-pario-bank16")
> >> + cpm1_gpiochip_add16(np);
> >> +
> >> + for_each_compatible_node(np, NULL, "fsl,cpm1-pario-bank32b")
> >> + cpm1_gpiochip_add32(np);
> >> +
> >> + /* Port E uses CPM2 layout */
> >> + for_each_compatible_node(np, NULL, "fsl,cpm1-pario-bank32e")
> >> + cpm2_gpiochip_add32(np);
>
> What do you suggest here?
>
> All GPIO ports of CPM1/CPM2 are on the SoC, so the chip name is in fact the CPU itself
> (like fsl,mpc866-pario-bank16).
Right; so that is what I think you should call them. 'fsl,mpc866-*' instead
of 'fsl,cpm1-*'. If multiple mpc8xx parts have the cpm1 core, then
choose one of the parts for all the others to claim compatibility with.
Now, there is a possible exception here... *IF* 'fsl,cpm1' is a very
well defined ASIC logic block that is known to be identical or versioned
between the various 8xx parts, *THEN* it is probably okay to call it
fsl,cpm1 and my previous comment does not apply. But, I think it must
be documented in the device tree binding as to what it is and where to
get documentation for it. And you should still have the first
compatible value to be something like "fsl,mpc866-pario-bank16",
followed by the cpm ones.
This was recently discussed between Kim and Segher.
g.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2008-07-01 16:36 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-04-18 17:10 [PATCH2/2] [POWERPC] CPM1: implement GPIO LIB API on CPM1 Freescale SoC Jochen Friedrich
2008-04-21 14:30 ` Grant Likely
2008-07-01 15:40 ` Jochen Friedrich
2008-07-01 16:36 ` Grant Likely
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).