Can only read 0 from ioremap() memory

2.6k views Asked by At

I am developing a simple driver for linux that will talk to a device over SPI. After i use request_mem_region and ioremap all i can read from the returned address is 0 even after i write a value to it. The address at offset 0 should be the control register for the SPI controller (it is a Xilinx Zynq SoC). The control register is set with a initial value during the the boot process.

Code:

int device_init() {
    int ret;
    ret = register_chrdev(device_major, DEVICE_NAME, &fops);
    if(ret < 0) {
        printk(KERN_ALERT "spi: cannot obtain major number %d.\n", device_major);
        return ret;
    }

    if(request_mem_region (SPI_ADDR, SPI_SIZE, "SPI Driver") == NULL)
    {
        printk("Failed to request memory region!\n");
        device_exit();
        return 1;
    }
    spi = ioremap(SPI_ADDR, SPI_SIZE);
    if(spi == NULL)
    {
        printk("I/O remap failed\n");
        device_exit();
        return 1;
    }

    printk("Driver init complete. Mapped to address 0x%X\n", spi);
    iowrite32be(0x20000, spi);
    printk("%X\n", ioread32be(spi));
    return 0;
}

The output when i insert the module is:
Driver init complete. Mapped to address 0xE08C2000
0

Thanks in advance for any help.

1

There are 1 answers

2
Benjamin Leinweber On

I think this may be it so I'm putting it in an answer. I'm familiar with Xilinx in general but not with the SPI core specifically. I just had a look at the Xilinx SPI core data sheet. The Table 4 on page 8 has a summary of the registers. There are no registers at the base address. I'm not sure why the core responds to the base address at all, but maybe it's hard coded to 0.

Anyways, after the ioremap() try this:

void *ipier;

ipier = spi + 0x28;
printk("Driver init complete. Mapped to address 0x%X\n", spi);
iowrite32be(0x20000, ipier);
printk("%X\n", ioread32be(ipier));

This is of course assuming that the IPIER register isn't removed from the IP core due to some sort of setting, of course.


Edit: Per the Op's comment below, the Op is not using the SPI IP Core, so this is not the answer to the question.