对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
谢谢!