This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Linux: Kernel error while reading GPIO OE register



Tool/software: Linux

Hi

I am facing a problem with setting the UART3_RTS Pin (G18, ZCZ) to low. No matter what i do (changing device tree, using the exposed export feature) I could manage to set it to zero. (Maybe the internal pullup?)

I was about to write a kernel module to read the OE register and to set the register manually.

Here problematic kernel module snippets:

The function below is called while installing the kernel module.

Here the Linux output on the AM335X when installing the module:

define GPIO2_START_ADDR 0x481AC000
#define GPIO2_END_ADDR 0x481ACFFF
//#define GPIO2_SIZE (GPIO2_END_ADDR - GPIO2_START_ADDR)
#define GPIO2_SIZE 0xFFF

#define UART3_RTS    (1 << 31)

#define GPIO_OE                0x134
#define GPIO_SETDATAOUT        0x194
#define GPIO_CLEARDATAOUT    0x190

#define CU_MAJOR    42
#define CU_GPIO    "cubasic gpio"

volatile void *gpio_addr = NULL;
volatile unsigned int *gpio_setdataout_addr = NULL;
volatile unsigned int *gpio_cleardataout_addr = NULL;
volatile unsigned int *gpio_oe_addr = NULL;


void set_output(void)
{
    //unsigned int reg;
    
    gpio_oe_addr = gpio_addr + GPIO_OE;
    gpio_setdataout_addr = gpio_addr + GPIO_SETDATAOUT;
    gpio_cleardataout_addr = gpio_addr + GPIO_CLEARDATAOUT;
    
    //reg = *gpio_oe_addr;

    pr_info("OE_Register: %x\n",*gpio_oe_addr);
    
}

static int gpio_init(void)
{    
    int rv;
    
    gpio_addr = ioremap((unsigned long) GPIO2_START_ADDR, GPIO2_SIZE);
    
    printk(KERN_INFO "virtual addr = 0x%x\n", (unsigned int) gpio_addr);
    set_output();
    pr_info("init done\n");
    rv = register_chrdev(CU_MAJOR, CU_GPIO, &fops);
        
    return (rv);
}

root@LTG-db8:/opt# insmod gpio_config.ko
[   49.850289] gpio_config: loading out-of-tree module taints kernel.
[   49.859549] virtual addr = 0xfa1ac000
[   49.865297] Unhandled fault: external abort on non-linefetch (0x1028) at 0xfa1ac134
[   49.865305] pgd = dd5ac000
[   49.865315] [fa1ac134] *pgd=48011452(bad)
[   49.865331] Internal error: : 1028 [#1] PREEMPT ARM
[   49.865371] Modules linked in: gpio_config(O+) spidev ti_am335x_adc pwm_tiehrpwm omap_rng rng_core spi_omap2_mcspi evdev ti_am335x_tscadc uio_pdrv_genirq uio cpufreq_dt
[   49.865388] CPU: 0 PID: 2153 Comm: insmod Tainted: G           O    4.8.6-rt5 #2
[   49.865392] Hardware name: Generic AM33XX (Flattened Device Tree)
[   49.865398] task: dc068b00 task.stack: dd664000
[   49.865429] PC is at set_output+0x24/0x4c [gpio_config]
[   49.865433] LR is at 0xfa1ac134
[   49.865442] pc : [<bf04a05c>]    lr : [<fa1ac134>]    psr: 60070013
[   49.865442] sp : dd665d78  ip : dd665d88  fp : dd665d84
[   49.865447] r10: bf04a400  r9 : dd645a08  r8 : bf04a448
[   49.865453] r7 : 00000000  r6 : c0d02088  r5 : bf04a1b4  r4 : ffffe000
[   49.865458] r3 : fa1ac000  r2 : bf04a600  r1 : 00000000  r0 : bf04a2ac
[   49.865466] Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment none
[   49.865473] Control: 10c5387d  Table: 9d5ac019  DAC: 00000051
[   49.865478] Process insmod (pid: 2153, stack limit = 0xdd664210)
[   49.865485] Stack: (0xdd665d78 to 0xdd666000)
[   49.865494] 5d60:                                                       dd665d9c dd665d88
[   49.865508] 5d80: bf04a1f4 bf04a044 bf04a1b4 c0d02088 dd665e1c dd665da0 c01018e0 bf04a1c0
[   49.865522] 5da0: dd665dfc dd665db0 c0206bfc c078ec8c dd665de4 dd665dc0 00000000 ffffe000
[   49.865536] 5dc0: dd645480 c021e7ec 00000001 462e8bcd dd645480 c023c508 dd645340 c01fcafc
[   49.865550] 5de0: dd645340 00000000 00000001 00000002 dd645340 462e8bcd bf04a400 dd665f38
[   49.865564] 5e00: dd645340 00000001 bf04a448 dd645a08 dd665e44 dd665e20 c01fcb38 c0101894
[   49.865577] 5e20: dd645a00 00000001 dd665e44 00000001 dd665f38 dd645a00 dd665f14 dd665e48
[   49.865591] 5e40: c01b0788 c01fcad8 bf04a40c 00007fff bf04a400 c01adff8 c080883c 00000000
[   49.865605] 5e60: bf04a40c bf04a5c0 e091b5b4 00000000 c0808858 dd665f38 00001604 c0ae8bd0
[   49.865619] 5e80: dd665ea4 462e8bcd dd61c840 dd665f2c 00000000 00000000 00000000 00000000
[   49.865631] 5ea0: 00000000 00000000 6e72656b 00006c65 00000000 00000000 00000000 00000000
[   49.865644] 5ec0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[   49.865658] 5ee0: 00000000 462e8bcd 7fffffff c0d02088 00000000 00000003 7f621e80 7fffffff
[   49.865671] 5f00: 00000000 00000000 dd665fa4 dd665f18 c01b0ffc c01ae7f4 7fffffff 00000000
[   49.865685] 5f20: 00000003 c078d6f0 dd665f74 e091a000 00001604 00000000 e091a000 00001604
[   49.865699] 5f40: e091b2e4 e091b220 e091ae44 00000610 00000800 00000000 00000000 00000000
[   49.865712] 5f60: 00000664 00000012 00000013 0000000b 00000008 00000004 00000000 462e8bcd
[   49.865726] 5f80: 9d966d00 7f61dcdc b6efff10 0000017b c0109368 dd664000 00000000 dd665fa8
[   49.865739] 5fa0: c0109160 c01b0f28 9d966d00 7f61dcdc 00000003 7f621e80 00000000 00000002
[   49.865753] 5fc0: 9d966d00 7f61dcdc b6efff10 0000017b 00000000 7f61dcdc 7f634000 00000000
[   49.865767] 5fe0: bedb5c40 bedb5c30 7f6186c3 b6e7aa42 80070030 00000003 00000000 00000000
[   49.865772] Backtrace:
[   49.865800] [<bf04a038>] (set_output [gpio_config]) from [<bf04a1f4>] (cubasic_gpio_init+0x40/0x88 [gpio_config])
[   49.865828] [<bf04a1b4>] (cubasic_gpio_init [gpio_config]) from [<c01018e0>] (do_one_initcall+0x58/0x1a8)
[   49.865851] [<c0101888>] (do_one_initcall) from [<c01fcb38>] (do_init_module+0x6c/0x3bc)
[   49.865868]  r9:dd645a08 r8:bf04a448 r7:00000001 r6:dd645340 r5:dd665f38 r4:bf04a400
[   49.865882] [<c01fcacc>] (do_init_module) from [<c01b0788>] (load_module+0x1fa0/0x2568)
[   49.865892]  r6:dd645a00 r5:dd665f38 r4:00000001
[   49.865903] [<c01ae7e8>] (load_module) from [<c01b0ffc>] (SyS_finit_module+0xe0/0x11c)
[   49.865919]  r10:00000000 r9:00000000 r8:7fffffff r7:7f621e80 r6:00000003 r5:00000000
[   49.865924]  r4:c0d02088
[   49.865941] [<c01b0f1c>] (SyS_finit_module) from [<c0109160>] (ret_fast_syscall+0x0/0x44)
[   49.865958]  r9:dd664000 r8:c0109368 r7:0000017b r6:b6efff10 r5:7f61dcdc r4:9d966d00
[   49.865971] Code: e59f2028 e59f0028 e5923000 e283ef4d (e5931134)
Segmentation fault

  • Hi,

    Which kernel is this, and which driver are you modifying? Also from the name of the package ZCZ, I guess you use am335x, right?
    Can you please share the dts file, to check the pinmux settings of the gpio?

    Best Regards,
    Yordan
  • Hi Yordan

    Thanks for the answer.

    Kernel: 4.8.5-rt5

    Driver: Is is actually just a loaded kernel module where I wanted to modify GPIOs. But the code is working with i.e. GPIO1 port (tested with pin 1_27)

    I am using the am335x wit hthe ZCZ package.

    The uart3_select (gpio2_31) is not appearing in the device tree since i have an rs485 interface and i want to set it manually to low or high (actually wondering if there is an implemented rs485 driver?)

    But is also tried it so set it with pinctrl-single,pins = <0x104 0x2f> or <0x104 0xf> to the gpio mode.

    I read some hints in the internet that the clock might not be initialized on the GPIO2 port?

    Thanks a lot in advance

    Device Tree:

    Included default headers:

    #include "am33xx.dtsi"
    #include "am335x-bone-common.dtsi"

    /*
     * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
     *
     * This program is free software; you can redistribute it and/or modify
     * it under the terms of the GNU General Public License version 2 as
     * published by the Free Software Foundation.
     */
    /dts-v1/;

    #include "am33xx.dtsi"
    #include "am335x-bone-common.dtsi"
    /* #include "am335x-bone-common.dtsi" */
    #include "am33xx-overlay-edma-fix.dtsi"
    /* #include "am335x-bone-jtag.dtsi" */

    / {
        model = "TI AM335x Fox Board";
        compatible = "ti,am335x-foxboard", "ti,am335x-bone", "ti,am33xx";
    };

    &ldo3_reg {
        regulator-min-microvolt = <1800000>;
        regulator-max-microvolt = <1800000>;
        regulator-always-on;
    };

    &mmc1 {
        vmmc-supply = <&vmmcsd_fixed>;
        status = "disabled";
    };

    &mmc2 {
        vmmc-supply = <&vmmcsd_fixed>;
        pinctrl-names = "default";
        pinctrl-0 = <&emmc_pins>;
        bus-width = <8>;
        status = "okay";
    };

    &am33xx_pinmux {
        pinctrl-names = "default";
        uart1_pins: uart1_pins {
            pinctrl-single,pins = <
            0x180 0x20 /* uart1_rx */
            0x184 0x08 /* uart1_tx */
            >;
        };
        
        uart3_pins: uart3_pins {
        pinctrl-single,pins = <
            0x160 0x21 /* uart3_rx */
            0x164 0x09 /* uart3_tx */
        >;
        };
        
        uart4_pins: uart4_pins {
        pinctrl-single,pins = <
            0x70 0xe /* uart4_rx */
            0x74 0x36 /* uart4_tx */
        >;
        };
        
        i2c1_pins: i2c1_pins {
        pinctrl-single,pins = <
            0x16C 0x33 /* SCL */
            0x168 0x33 /* SDA */
        >;
        };
    };


    &uart1 {
        pinctrl-names = "default";
        pinctrl-0 = <&uart1_pins>;

        status = "okay";
    };

    &uart3 {
        pinctrl-names = "default";
        pinctrl-0 = <&uart3_pins>;

        status = "okay";
    };

    &uart4 {
        pinctrl-names = "default";
        pinctrl-0 = <&uart4_pins>;

        status = "okay";
    };

    &i2c1{
        pinctrl-names = "default";
        pinctrl-0 = <&i2c1_pins>;

        status = "okay";
        clock-frequency = <100000>;
    };

    /* end of file */

  • Hi,

    actually wondering if there is an implemented rs485 driver?

    Have a look at the links provided in the following thread:
    e2e.ti.com/.../571538

    It provides full configuration examples for RS485

    Best Regards,
    Yordan
  • As for the clock settings, you can write 0x1 in CM_WKUPAON_GPIO1_CLKCTRL[1:0]MODULEMODE (physical address 0x4AE07838), using the devmem2 tool.

    Best Regards,
    Yordan