User avatar
eamaral
Posts: 6
Joined: Sun Jul 24, 2016 5:39 pm

request_mem_region fails

Sun Aug 07, 2016 5:59 am

The call to request_mem_region is failing (returns null). I would say that the memory region I'm trying to access (GPIO starting at 0x3f20000) is being used.

I removed (rmmod) the module bcm28795_gpio but the request is still failing. The modules I have loaded are (lsmod):

Code: Select all

Module                  Size  Used by
cfg80211              427817  0 
rfkill                 16018  1 cfg80211
snd_bcm2835            20511  0 
snd_pcm                75890  1 snd_bcm2835
snd_timer              19160  1 snd_pcm
snd                    51908  3 snd_bcm2835,snd_timer,snd_pcm
bcm2835_wdt             3225  0 
uio_pdrv_genirq         3164  0 
uio                     8000  1 uio_pdrv_genirq
i2c_dev                 5859  0 
ipv6                  347473  30
cat /proc/iomem is returning the following:

Code: Select all

00000000-3affffff : System RAM
  00008000-007e7483 : Kernel code
  00860000-0098e1ab : Kernel data
3f006000-3f006fff : dwc_otg
3f007000-3f007eff : /soc/dma@7e007000
3f00b840-3f00b84e : /soc/vchiq
3f00b880-3f00b8bf : /soc/mailbox@7e00b800
3f200000-3f2000b3 : /soc/gpio@7e200000
3f201000-3f201fff : /soc/uart@7e201000
  3f201000-3f201fff : /soc/uart@7e201000
3f202000-3f2020ff : /soc/sdhost@7e202000
3f980000-3f98ffff : dwc_otg
Output from dmesg:

Code: Select all

[ 1745.126636] tsgpio: init
[ 1745.130025] tsgpio: probe of 3f200000.gpiomem failed with error 16
I think this issue is related to the Device Tree, but I'm not sure what do next.

Platform: Raspberry Pi 2
Kernel release: 4.4.16-v7+

The driver code:

Code: Select all

#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/miscdevice.h>
#include <linux/of.h>
#include <linux/of_address.h>

#define DRIVER_NAME "tsgpio"

struct tsgpio_dev {
    struct resource res;
    void __iomem *virtbase;
} dev;

static const struct file_operations tsgpio_fops = {
    .owner = THIS_MODULE,
};

static struct miscdevice tsgpio_misc_device = {
    .minor = MISC_DYNAMIC_MINOR,
    .name = DRIVER_NAME,
    .fops = &tsgpio_fops,
};

static const struct of_device_id tsgpio_of_match[] = {
    { .compatible = "brcm,bcm2835-gpiomem" },
    {},
};

MODULE_DEVICE_TABLE(of, tsgpio_of_match);

int __init tsgpio_probe(struct platform_device *pdev)
{
    int ret;

    ret = misc_register(&tsgpio_misc_device);
    if (ret)
        return ENODEV;

    // Find address range in device tree
    ret = of_address_to_resource(pdev->dev.of_node, 0, &dev.res);

    if (ret) {
        ret = ENOENT;
        goto out_deregister;
    }

    // Request access to memory
    if (request_mem_region(dev.res.start, resource_size(&dev.res),
                                                    DRIVER_NAME) == NULL) {
        ret = EBUSY;
        goto out_deregister;
    }

    /* Arrange access to our registers (calls ioremap) */
    dev.virtbase = of_iomap(pdev->dev.of_node, 0);

    if (dev.virtbase == NULL) {
        ret = ENOMEM;
        goto out_release_mem_region;
        }

    return 0;

out_release_mem_region:
    release_mem_region(dev.res.start, resource_size(&dev.res));

out_deregister:
    misc_deregister(&tsgpio_misc_device);
    return ret;
}

int tsgpio_remove(struct platform_device *pdev)
{
    iounmap(dev.virtbase);
    release_mem_region(dev.res.start, resource_size(&dev.res));
    misc_deregister(&tsgpio_misc_device);
    return 0;
}

static struct platform_driver tsgpio_driver = {
    .driver = {
        .name = DRIVER_NAME,
        .owner = THIS_MODULE,
        .of_match_table = of_match_ptr(tsgpio_of_match),
    },
    .remove = __exit_p(tsgpio_remove),
};

static int __init tsgpio_init(void)
{
    return platform_driver_probe(&tsgpio_driver, tsgpio_probe);
}

static void __exit tsgpio_exit(void)
{
    platform_driver_unregister(&tsgpio_driver);
}

module_init(tsgpio_init);
module_exit(tsgpio_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Emanuel Oliveira");

User avatar
joan
Posts: 14960
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: request_mem_region fails

Sun Aug 07, 2016 8:11 am

Why not just use ioremap (or whatever it is called)? request_mem_region doesn't map any memory.

Return to “Troubleshooting”