[PATCH] [POWERPC] CPM1: implement GPIO LIB API - Kernel

This is a discussion on [PATCH] [POWERPC] CPM1: implement GPIO LIB API - Kernel ; Implement GPIO LIB API on CPM1 Freescale SoC. Signed-off-by: Jochen Friedrich --- This is based on the series starting at http://patchwork.ozlabs.org/linuxppc/patch?id=17299 arch/powerpc/platforms/8xx/Kconfig | 2 + arch/powerpc/sysdev/cpm1.c | 240 +++++++++++++++++++++++++++++++++++- 2 files changed, 241 insertions(+), 1 deletions(-) diff --git a/arch/powerpc/platforms/8xx/Kconfig b/arch/powerpc/platforms/8xx/Kconfig ...

+ Reply to Thread
Results 1 to 6 of 6

Thread: [PATCH] [POWERPC] CPM1: implement GPIO LIB API

  1. [PATCH] [POWERPC] CPM1: implement GPIO LIB API

    Implement GPIO LIB API on CPM1 Freescale SoC.

    Signed-off-by: Jochen Friedrich
    ---

    This is based on the series starting at http://patchwork.ozlabs.org/linuxppc/patch?id=17299

    arch/powerpc/platforms/8xx/Kconfig | 2 +
    arch/powerpc/sysdev/cpm1.c | 240 +++++++++++++++++++++++++++++++++++-
    2 files changed, 241 insertions(+), 1 deletions(-)

    diff --git a/arch/powerpc/platforms/8xx/Kconfig b/arch/powerpc/platforms/8xx/Kconfig
    index 7fd224c..e12cbf0 100644
    --- a/arch/powerpc/platforms/8xx/Kconfig
    +++ b/arch/powerpc/platforms/8xx/Kconfig
    @@ -4,6 +4,8 @@ config FADS
    config CPM1
    bool
    select CPM
    + select GENERIC_GPIO
    + select GPIO_LIB

    choice
    prompt "8xx Machine Type"
    diff --git a/arch/powerpc/sysdev/cpm1.c b/arch/powerpc/sysdev/cpm1.c
    index df8bd2b..c3d5df8 100644
    --- a/arch/powerpc/sysdev/cpm1.c
    +++ b/arch/powerpc/sysdev/cpm1.c
    @@ -30,11 +30,14 @@
    #include
    #include
    #include
    +#include
    +#include
    #include
    #include
    #include
    #include
    #include
    +#include
    #include
    #include
    #include
    @@ -403,7 +406,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)
    @@ -610,3 +613,238 @@ int cpm1_clk_setup(enum cpm_clk_target target, int clock, int mode)

    return 0;
    }
    +
    +/*
    + * GPIO LIB API implementation
    + */
    +
    +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_ioport32 __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_ioport32 __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_ioport32 __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_ioport32 __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_ioport32 __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-bank32")
    + cpm1_gpiochip_add32(np);
    + return 0;
    +}
    +arch_initcall(cpm_init_par_io);
    --
    1.5.4.4

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  2. Re: [PATCH] [POWERPC] CPM1: implement GPIO LIB API

    Jochen Friedrich wrote:
    > diff --git a/arch/powerpc/platforms/8xx/Kconfig b/arch/powerpc/platforms/8xx/Kconfig
    > index 7fd224c..e12cbf0 100644
    > --- a/arch/powerpc/platforms/8xx/Kconfig
    > +++ b/arch/powerpc/platforms/8xx/Kconfig
    > @@ -4,6 +4,8 @@ config FADS
    > config CPM1
    > bool
    > select CPM
    > + select GENERIC_GPIO
    > + select GPIO_LIB


    Shouldn't this depend on the user enabling GPIO support? Some 8xx
    boards are very memory-constrained, so we don't want to be making the
    kernel even bigger than it already is unless it's actually needed.

    -Scott
    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  3. Re: [PATCH] [POWERPC] CPM1: implement GPIO LIB API

    Hi Scott,

    >> diff --git a/arch/powerpc/platforms/8xx/Kconfig b/arch/powerpc/platforms/8xx/Kconfig
    >> index 7fd224c..e12cbf0 100644
    >> --- a/arch/powerpc/platforms/8xx/Kconfig
    >> +++ b/arch/powerpc/platforms/8xx/Kconfig
    >> @@ -4,6 +4,8 @@ config FADS
    >> config CPM1
    >> bool
    >> select CPM
    >> + select GENERIC_GPIO
    >> + select GPIO_LIB

    >
    > Shouldn't this depend on the user enabling GPIO support? Some 8xx
    > boards are very memory-constrained, so we don't want to be making the
    > kernel even bigger than it already is unless it's actually needed.


    Are you more comfortable with this?

    Implement GPIO LIB API on CPM1 Freescale SoC.

    Signed-off-by: Jochen Friedrich
    ---
    arch/powerpc/platforms/8xx/Kconfig | 10 ++
    arch/powerpc/sysdev/cpm1.c | 246 +++++++++++++++++++++++++++++++++++-
    2 files changed, 255 insertions(+), 1 deletions(-)

    diff --git a/arch/powerpc/platforms/8xx/Kconfig b/arch/powerpc/platforms/8xx/Kconfig
    index 7fd224c..9d17425 100644
    --- a/arch/powerpc/platforms/8xx/Kconfig
    +++ b/arch/powerpc/platforms/8xx/Kconfig
    @@ -109,6 +109,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 df8bd2b..6c97f3f 100644
    --- a/arch/powerpc/sysdev/cpm1.c
    +++ b/arch/powerpc/sysdev/cpm1.c
    @@ -30,6 +30,7 @@
    #include
    #include
    #include
    +#include
    #include
    #include
    #include
    @@ -42,6 +43,11 @@

    #include

    +#ifdef CONFIG_8xx_GPIO
    +#include
    +#include
    +#endif
    +
    #define CPM_MAP_SIZE (0x4000)

    #ifndef CONFIG_PPC_CPM_NEW_BINDING
    @@ -403,7 +409,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)
    @@ -610,3 +616,241 @@ 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_ioport32 __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_ioport32 __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_ioport32 __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_ioport32 __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_ioport32 __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-bank32")
    + cpm1_gpiochip_add32(np);
    + return 0;
    +}
    +arch_initcall(cpm_init_par_io);
    +
    +#endif /* CONFIG_8xx_GPIO */
    --
    1.5.4.4


    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  4. Re: [PATCH] [POWERPC] CPM1: implement GPIO LIB API

    Jochen Friedrich wrote:
    > Hi Scott,
    >
    >>> diff --git a/arch/powerpc/platforms/8xx/Kconfig b/arch/powerpc/platforms/8xx/Kconfig
    >>> index 7fd224c..e12cbf0 100644
    >>> --- a/arch/powerpc/platforms/8xx/Kconfig
    >>> +++ b/arch/powerpc/platforms/8xx/Kconfig
    >>> @@ -4,6 +4,8 @@ config FADS
    >>> config CPM1
    >>> bool
    >>> select CPM
    >>> + select GENERIC_GPIO
    >>> + select GPIO_LIB

    >> Shouldn't this depend on the user enabling GPIO support? Some 8xx
    >> boards are very memory-constrained, so we don't want to be making the
    >> kernel even bigger than it already is unless it's actually needed.

    >
    > Are you more comfortable with this?


    Sure.

    -Scott
    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  5. Re: [PATCH] [POWERPC] CPM1: implement GPIO LIB API

    Hi Jochen,

    On Tuesday 25 March 2008 17:56, Jochen Friedrich wrote:
    > Implement GPIO LIB API on CPM1 Freescale SoC.
    >
    > Signed-off-by: Jochen Friedrich
    > ---
    >
    > This is based on the series starting at

    http://patchwork.ozlabs.org/linuxppc/patch?id=17299
    >
    > arch/powerpc/platforms/8xx/Kconfig | 2 +
    > arch/powerpc/sysdev/cpm1.c | 240

    +++++++++++++++++++++++++++++++++++-
    > 2 files changed, 241 insertions(+), 1 deletions(-)
    >


    [snip]

    > diff --git a/arch/powerpc/sysdev/cpm1.c b/arch/powerpc/sysdev/cpm1.c
    > index df8bd2b..c3d5df8 100644
    > --- a/arch/powerpc/sysdev/cpm1.c
    > +++ b/arch/powerpc/sysdev/cpm1.c
    > @@ -30,11 +30,14 @@
    > #include
    > #include
    > #include
    > +#include
    > +#include
    > #include
    > #include
    > #include
    > #include
    > #include
    > +#include
    > #include
    > #include
    > #include
    > @@ -403,7 +406,7 @@ struct cpm_ioport16 {
    > };
    >
    > struct cpm_ioport32 {
    > - __be32 dir, par, sor;
    > + __be32 dir, par, sor, dat;
    > };


    I haven't checked all CPM1-based parts, but for the MPC855 family this doesn't
    look right. The MPC855 has two 32-bit ports, port B and port E. Registers for
    port B are dir, par, odr and dat, and registers for port E are dir, par, sor,
    odr and dat.

    Are you working on a similar patch for the CPM2 ? CPM2 I/O ports are 32 bit
    wide and their registers are layed out like for port E on the MPC855. It
    should thus be possible to share code between CPM1 and CPM2.

    Best regards,

    --
    Laurent Pinchart
    CSE Semaphore Belgium

    Chaussée de Bruxelles, 732A
    B-1410 Waterloo
    Belgium

    T +32 (2) 387 42 59
    F +32 (2) 387 42 75

    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.4.5 (GNU/Linux)

    iD8DBQBH9L0w8y9gWxC9vpcRAvhoAKCCygKu7qNMmsr8/NaDlngfBfaJ5gCgwKxT
    QOWOIRNAhV9ZBuHI8l33Shw=
    =mcgX
    -----END PGP SIGNATURE-----


  6. Re: [PATCH] [POWERPC] CPM1: implement GPIO LIB API

    Hi Laurent,

    > I haven't checked all CPM1-based parts, but for the MPC855 family this doesn't
    > look right. The MPC855 has two 32-bit ports, port B and port E. Registers for
    > port B are dir, par, odr and dat, and registers for port E are dir, par, sor,
    > odr and dat.


    You probably mean MPC885. Thanks for catching this, the 32bit registers really
    are a mess on CPM1 platforms.

    > Are you working on a similar patch for the CPM2 ? CPM2 I/O ports are 32 bit
    > wide and their registers are layed out like for port E on the MPC855. It
    > should thus be possible to share code between CPM1 and CPM2.


    Yes, some common port setup code could probably be moved to cpm.c.

    Thanks,
    Jochen
    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

+ Reply to Thread