1

I have a register which needs to be accessed from more then one driver. It is a global read-only register resides in FPGA space The register address is exported via device tree. The first call to "request_mem_region" is ok, but any consecutive call fails.

Is there a way to share a register between drivers ?

Linux Kernel release is 4.14 , using petalinux

Thanks, Ran

user3087632
  • 143
  • 2
  • 9
  • 2
    E.g. make the "parent" driver, which calls `request_mem_region` and provides a function, which expose resulted address of that call. Then make your drivers use this function. – Tsyvarev Nov 25 '18 at 18:30
  • Use object oriented programming, i.e. data encapsulation. Have one driver that maps the register, and then create a single function that reads this register. – sawdust Nov 26 '18 at 01:15
  • Thanks , so using export I can access the function for set\get global registers. The only issue i have is how to obtain the device driver context which is allocated in probe function. @Tsyvarev - what do you mean "parent" driver ? maybe this is the key – user3087632 Nov 26 '18 at 13:05
  • By "parent" driver I mean some other driver, which is required for your drivers. (That is, the "parent" driver should be loaded before your ones.) In that parent drivers you may define as many functions as you need. E.g., the function which returns device driver context can be one of the functions, exported by the "parent" driver. Note, that you may export even *variables* (Well, it is not the approach which is recomended, but it may simplify things a lot.) – Tsyvarev Nov 26 '18 at 13:16
  • If it’s read-only register, you may remap its address as many times as you want without requesting a region. But with caution: this is rather hack. – 0andriy Dec 01 '18 at 09:40

1 Answers1

0

You need to remap the memory region with something like ioremap() after you have requested it.

Then, as Tsyvarev and others mentioned, create and export a function in your "parent" driver that returns the mapped memory.

Here is some rough code:

void * mapped_mem;

void * map_addr(unsigned int phy_addr, char * name) {

    struct resource * resource;
    void * mapped_mem;

    resource = request_mem_region(phy_addr, page_size * 4, name);
    // check for errors

    mapped_mem= ioremap_nocache(phy_addr, page_size * 4);
    // check for errors
    return mappedMem;

    //handle errors
}


void * get_mapped_addr(void) {
    return mapped_mem
}

EXPORT_SYMBOL( get_mapped_addr);

Now, mapped_mem should actually be tracked as part of your devices private info, but I figure thats beyond the scope of the question. Also, make sure to check for all possible errors. Make sure that request_mem_region() returns something >0 and not Null.

charlesw
  • 572
  • 6
  • 25