8devices / carambola

Carambola - RT305x/SoC based PCB
http://openwrt.org/
GNU General Public License v2.0
26 stars 12 forks source link

Carambola kernel board code - incorrect GPIO initialization #11

Open Lukse opened 12 years ago

Lukse commented 12 years ago

Due to formatting and long description I am submitting link to problem.

http://www.8devices.com/community/viewtopic.php?f=6&t=202

Please review.

assarbad commented 9 years ago

Quoting from the forum link above.

Hi,

I've been playing with the GPIOs on Carambola and observed that whenever I try to initialize a GPIO pin for the first time I'm getting a kernel warning like this:

[ 3012.360000] ------------[ cut here ]------------
[ 3012.360000] WARNING: at drivers/gpio/gpiolib.c:101 0x80116e94()
[ 3012.360000] autorequest GPIO-11
[ 3012.360000] Modules linked in: usb_storage i2c_gpio i2c_algo_bit dwc_otg i2c_dev i2c_core nf_nat_irc nf_conntrack_irc nf_nat_ftp nf_conntrack_ftp ipt_MASQUERADE iptable_nat nf_nat pppoe xt_conntrack xt_CT xt_NOTRACK iptable_raw xt_state nf_conntrack_ipv4 nf_defrag_ipv4 nf_conntrack sd_mod pppox ipt_REJECT xt_TCPMSS ipt_LOG xt_comment xt_multiport xt_mac xt_limit iptable_mangle iptable_filter ip_tables xt_tcpudp x_tables gpio_dev ppp_async ppp_generic slhc rt2800usb(O) rt2800pci(O) rt2800lib(O) rt2500usb(O) rt2x00usb(O) rt2x00soc(O) rt2x00pci(O) rt2x00lib(O) mac80211(O) lib80211_crypt_tkip(O) lib80211_crypt_ccmp(O) lib80211_crypt_wep(O) lib80211(O) usbcore usb_common scsi_mod nls_base crc_itu_t crc_ccitt eeprom_93cx6 cfg80211(O) compat(O) arc4 aes_generic crypto_algapi leds_gpio
[ 3012.360000] Call Trace:[<801df038>] 0x801df038
[ 3012.360000] [<801df038>] 0x801df038
[ 3012.360000] [<80116e94>] 0x80116e94
[ 3012.360000] [<80010664>] 0x80010664
[ 3012.360000] [<80116e94>] 0x80116e94
[ 3012.360000] [<80010718>] 0x80010718
[ 3012.360000] [<80116e94>] 0x80116e94
[ 3012.360000] [<801170b0>] 0x801170b0
[ 3012.360000] [<800865ec>] 0x800865ec
[ 3012.360000] [<80031a44>] 0x80031a44
[ 3012.360000] [<800872cc>] 0x800872cc
[ 3012.360000] [<80031b40>] 0x80031b40
[ 3012.360000] [<8008f2c0>] 0x8008f2c0
[ 3012.360000] [<800343a0>] 0x800343a0
[ 3012.360000] [<80033b40>] 0x80033b40
[ 3012.360000] [<80047814>] 0x80047814
[ 3012.360000] [<80087370>] 0x80087370
[ 3012.360000] [<80008d30>] 0x80008d30
[ 3012.360000] 
[ 3012.360000] ---[ end trace b875ca21dcbec7a4 ]---

Looking into the kernel sources, I found out that this warning is issued when the board setup code > didn't call gpio_request() for that specific pin. In the board setup code, the function that should initialize the GPIO pins is rt305x_gpio_init(u32 mode):

void __init rt305x_gpio_init(u32 mode)
{
        u32 t;

        rt305x_sysc_wr(mode, SYSC_REG_GPIO_MODE);

        ramips_gpio_init(&rt305x_gpio_data);
        if ((mode & RT305X_GPIO_MODE_I2C) == 0)
                rt305x_gpio_reserve(RT305X_GPIO_I2C_SD, RT305X_GPIO_I2C_SCLK);

        if ((mode & RT305X_GPIO_MODE_SPI) == 0)
                rt305x_gpio_reserve(RT305X_GPIO_SPI_EN, RT305X_GPIO_SPI_DIN);

        t = mode >> RT305X_GPIO_MODE_UART0_SHIFT;
        t &= RT305X_GPIO_MODE_UART0_MASK;
        switch (t) {
        case RT305X_GPIO_MODE_UARTF:
        case RT305X_GPIO_MODE_PCM_UARTF:
        case RT305X_GPIO_MODE_PCM_I2S:
        case RT305X_GPIO_MODE_I2S_UARTF:
                rt305x_gpio_reserve(RT305X_GPIO_7, RT305X_GPIO_14);
                break;
        case RT305X_GPIO_MODE_PCM_GPIO:
                rt305x_gpio_reserve(RT305X_GPIO_10, RT305X_GPIO_14);
                break;
        case RT305X_GPIO_MODE_GPIO_UARTF:
        case RT305X_GPIO_MODE_GPIO_I2S:
                rt305x_gpio_reserve(RT305X_GPIO_7, RT305X_GPIO_10);
                break;
        }
...

Reading the code more carefully I observed that this function is not correct. What I mean is that for the UARTF, PCM_UARTF, PCM_I2S and I2S_UARTF modes the code shouldn't request any GPIO, while for PCM_GPIO it should request GPIOs 7, 8, 9, for GPIO_UARTF and GPIO_I2S it should request GPIOs 11, 12, 13, 14 and for RT305X_GPIO_MODE_GPIO (which is the default) it should request all GPIOs from 7 to 14.

I think the same observation applies to all the other tests (I2C, SPI, UART1, JTAG ...) where the conditions seem to be reversed too.