Wind River Support Network

HomeDefectsLIN6-4318
Not to be fixed

LIN6-4318 : mpc8572_gpio_get function can not get right value on p2020 board

Created: Mar 26, 2013    Updated: Apr 19, 2018
Resolved Date: Apr 17, 2018
Previous ID: LIN4-6989
Found In Version: 6.0
Severity: Standard
Applicable for: Wind River Linux 6
Component/s: BSP

Description

On p2020 board, customer connect one external device to CPU's GPIO pin, but when try to get GPIO pin's status with mpc8572_gpio_get function, it can not get right value.

After investigation, mpc8572_gpio_get function was added by a patch which is used to provide a workaourd about hardware errata, here list the patch info:

/*******************************************************/

diff --git a/arch/powerpc/sysdev/mpc8xxx_gpio.c b/arch/powerpc/sysdev/mpc8xxx_gpio.c
index 103eace..ee1c0e1 100644
--- a/arch/powerpc/sysdev/mpc8xxx_gpio.c
+++ b/arch/powerpc/sysdev/mpc8xxx_gpio.c

/*******************************************************/

This patch state that it was used for  MPC8572 and MPC8536, when dts show it use 8572-gpio, it will use mpc8572_gpio_get to get gpio data, because hardware bug.
/*******************************************************/
static void __init mpc8xxx_add_controller(struct device_node *np)
{
.......
    if (of_device_is_compatible(np, "fsl,mpc8572-gpio"))
        gc->get = mpc8572_gpio_get;
    else
        gc->get = mpc8xxx_gpio_get;
/*******************************************************/

Patch description also said the patch fix the bug when GPIO in output status, in customer's application environment, the GPIO dir was set to input, then they failed to get right value, 

here list the codes of this function:
/*****************************************************/
static int mpc8572_gpio_get(struct gpio_chip *gc, unsigned int gpio)
{
 u32 val;
 struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
 struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
 
 val = in_be32(mm->regs + GPIO_DAT) & ~in_be32(mm->regs + GPIO_DIR);
 
 return (val | mpc8xxx_gc->data) & mpc8xxx_gpio2mask(gpio);
}
/*****************************************************/

The val will only be used as a flag in this function(for hardware bug, when in output status, the value is wrong here), the real value will need to do `or` operation( return (val | mpc8xxx_gc->data)).
But customer use input status, the val is right after checking, but this function will do `or` operation with mpc8xxx_gc->data, then they get wrong value.

In p2020's dts, it show it use mpc8572-gpio.
/*********************************/
        gpio: gpio-controller@f000 {
            #gpio-cells = <2>;
            compatible = "fsl,mpc8572-gpio";
            reg = <0xf000 0x100>;
            interrupts = <47 0x2>;
            interrupt-parent = <&mpic>;
            gpio-controller;
        };
/*********************************/

So not sure if this patch have bug or dts have bug.

Workaround

there are two method as workaround:
1, modify dts, did not mpc8572-gpio, this will cause gpio driver use mpc8xxx_gpio_get instead, this function can give right value.

2, modify source codes directly(arch/powerpc/sysdev/mpc8xxx_gpio.c), did no use `or` operation when return value in mpc8572_gpio_get function 

Steps to Reproduce

1, build a p2020 project on wind river linux 4.3
2, boot it on target
3, connect a external device to GPIO's PIN
4, try to get GPIO's data(on p2020, it'll invoke mpc8572_gpio_get at last.)
Live chat
Online