request_mem_region在Raspberry Pi上失败

时间:2016-08-06 17:15:30

标签: linux-kernel raspberry-pi gpio device-tree

request_mem_region的调用失败(返回null)。 我会说我正在尝试访问的内存区域(从0x3f20000开始的GPIO)。

我删除了rmmod模块bcm28795_gpio,但请求仍然失败。 我加载的模块是(lsmod):

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正在返回以下内容:

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`

我认为这个问题与设备树有关,但我不确定接下来做什么。

驱动程序代码:

#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/errno.h>
#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");

dmesg的输出:

[ 1745.126636] tsgpio: init
[ 1745.130025] tsgpio: probe of 3f200000.gpiomem failed with error 16

谢谢!

0 个答案:

没有答案