Why is membase adress different each time kernel module is loaded?

0

I've been building a RTDM UART driver by using the Linux version as an example. The UART base address is supposed to be 0x80070000, and when using the linux driver there is no problem as dmesg show:

80070000.serial: ttyAPP3 at MMIO 0x80070000 (irq = 234, base_baud = 1500000) is a 80070000.serial
mxs-auart 80070000.serial: Found APPUART 3.1.0

However, when I'm using the driver I'm builing I get a different adress each time I'm loading the module (such as 0xc8df6000) and none of them are correct.

Here's the probe function I'm using:

static int rt_mxs_auart_probe(struct platform_device *pdev)

{
    const struct of_device_id *of_id =

            of_match_device(mxs_auart_dt_ids, &pdev->dev);

    int ret;
    struct resource *r;

    struct rtdm_device *dev;

    struct rt_mxs_auart_port *s;

    //allocate managed kernel memory

    s = devm_kzalloc(&pdev->dev, sizeof(*s), GFP_KERNEL);
    if (!s)
        return -ENOMEM;

    ret = rt_serial_mxs_probe_dt(s, pdev);

    if (ret < 0){
        return ret;
        }

    if (of_id) {

        pdev->id_entry = of_id->data;
        s->devtype = pdev->id_entry->driver_data;
    }

    r = platform_get_resource(pdev, IORESOURCE_MEM, 0);

    if (!r)
        return -ENXIO;

    //get irq line
    s->irq = platform_get_irq(pdev, 0);
    if (s->irq < 0)
        return -ENODEV;

    //base memory
    s->membase = ioremap(r->start, resource_size(r));

    if (IS_ERR(s->membase))
        return PTR_ERR(s->membase);


    /*define the rtdm_device*/
    dev = &s->rtdm_dev;
    dev->driver = &ida_driver;
    dev->label = "xeno_ida";
    dev->device_data = s;

    ret = mxs_get_clks(s, pdev); //activate clocks
    if (ret)
        return ret;

    s->uartclk = clk_get_rate(s->clk);
    s->fifosize = MXS_AUART_FIFO_SIZE;

    mxs_init_regs(s);

    ret = rtdm_dev_register(dev); //register driver in RTDM space

    if (ret)
        return ret;

    platform_set_drvdata(pdev, s); //add device-related data to device struct


    pr_info("Probe: Successful\n");
    pr_info("%s on IMX UART%d: membase=0x%p irq=%d uartclk=%d\n",
           dev->name, pdev->id, s->membase, s->irq, s->uartclk);

    return 0;
}

which is based on mxs-auart.c and rt_imx_uart.c.

For membase I'm using the same code as mxs-auart.c which is why I don't understand why I'm having this issue. My driver also freezes after some time when I try to rmmod it so I wonder if it is caused by this.

Would appreciate any help!

c
linux-kernel
linux-device-driver
kernel-module
asked on Stack Overflow Apr 16, 2020 by Mamask Gold

1 Answer

1

The return value of ioremap is a virtual address, not a physical one. It could be anywhere in the virtual address space.

The physical address is stored in r->start (the input of ioremap).

answered on Stack Overflow Apr 18, 2020 by n. 'pronouns' m.

User contributions licensed under CC BY-SA 3.0