#include #include #include #include struct vain_plat_info { void __iomem *base; struct platform_device *pdev; spinlock_t lock; }; static int __devinit vain_plat_probe(struct platform_device *pdev) { struct vain_plat_info *info; struct resource *res, *mem; int err; info = kzalloc(sizeof(struct vain_plat_info), GFP_KERNEL); if (unlikely(!info)) { dev_err(&pdev->dev, "Could not allocate memory\n"); err = -ENOMEM; goto out; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (unlikely(!res)) { dev_err(&pdev->dev, "I/O address already in use\n"); err = -ENOENT; goto err_free; } mem = request_mem_region(res->start, resource_size(res), pdev->name); if (!mem) { err = -EBUSY; goto err_free; } info->base = ioremap(res->start, resource_size(res)); if (!info->base) { dev_err(&pdev->dev, "Unable to map card MMIO\n"); err = -ENODEV; goto err_ioremap; } platform_set_drvdata(pdev, info); return 0; err_ioremap: release_mem_region(res->start, resource_size(res)); err_free: kfree(info); out: return err; } static int __devexit vain_plat_remove(struct platform_device *pdev) { struct vain_plat_info *info = platform_get_drvdata(pdev); struct resource *res; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); iounmap(info->base); release_mem_region(res->start, resource_size(res)); platform_set_drvdata(pdev, NULL); kfree (info); return 0; } static struct platform_driver vain_plat_driver = { .driver = { .name = "vain_plat", .owner = THIS_MODULE, }, .probe = vain_plat_probe, .remove = __devexit_p(vain_plat_remove), }; static int __init vain_plat_init(void) { int err; err = platform_driver_register(&vain_plat_driver); if (!err) printk(KERN_INFO "vain_plat_init: done\n"); return err; } static void __exit vain_plat_exit(void) { platform_driver_unregister(&vain_plat_driver); printk(KERN_INFO "vain_plat_exit: done\n"); } module_init(vain_plat_init); module_exit(vain_plat_exit); MODULE_AUTHOR("Benedikt Spranger "); MODULE_DESCRIPTION("a more or less useless platform module"); MODULE_LICENSE("GPL v2"); MODULE_VERSION("0815");