linux kernel - Device Specific Data Structure with Platform Driver and Character Device Interface -
i'm struggling understanding linkup between platform device driver character device interface , storing data in device specific data structure.
i created struct keeping track of data related device, , add devices struct @ probe function:
dev_set_drvdata(dev, data_struct); i keep global copy of data_struct.
i register misc device can mmap() , access device through ioctl() commands. if want access device's data_struct, , access through global copy. there way through inode or file pointers access data stored in devices struct?
i allow 1 instance of device, want make sure implement correctly future implementations there might multiple devices using same driver.
when miscdevice being open first time, miscdevice framework set file->private_data struct miscdevice (see misc_open() function , comment misc_register() function). can rely on , use file->private_data in file operations obtain custom structure, using container_of() macro. of course, custom structure must contain struct miscdevice that. neat , commonly used way create helper function called to_*(), figure out , return custom struct file pointer provided. if called custom struct my_struct, should call helper function to_my_struct().
also, if writing platform driver, can use platform_set_drvdata() instead of dev_set_drvdata(). needed can obtain custom structure in remove() function of platform driver.
here example explained above:
struct my_struct { struct platform_device *pdev; struct miscdevice mdev; }; static inline struct my_struct *to_my_struct(struct file *file) { struct miscdevice *miscdev = file->private_data; return container_of(miscdev, struct my_struct, mdev); } static ssize_t my_read(struct file *file, char __user *buf, size_t count, loff_t *pos) { struct my_struct *my = to_my_struct(file); return simple_read_from_buffer(buf, count, pos, "my text", 7); } static const struct file_operations my_fops = { .owner = this_module, .read = my_read, }; static int my_probe(struct platform_device *pdev) { struct my_struct *my; int ret; = devm_kzalloc(&pdev->dev, sizeof(*my), gfp_kernel); if (!my) return -enomem; platform_set_drvdata(pdev, my); my->pdev = pdev; my->mdev.minor = misc_dynamic_minor; my->mdev.name = "my"; my->mdev.fops = &my_fops; my->mdev.parent = null; ret = misc_register(&my->mdev); if (ret) { dev_err(&pdev->dev, "failed register miscdev\n"); return ret; } dev_info(&pdev->dev, "registered\n"); return 0; } static int my_remove(struct platform_device *pdev) { struct my_struct *my = platform_get_drvdata(pdev); misc_deregister(&my->mdev); dev_info(&pdev->dev, "unregistered\n"); return 0; } by way, can examples in kernel code, using keywords, this:
$ git grep -l --all-match -e 'misc_register(' -e 'platform_device' -e 'file->private_data' -- drivers/
Comments
Post a Comment