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

Popular posts from this blog

javascript - Thinglink image not visible until browser resize -

firebird - Error "invalid transaction handle (expecting explicit transaction start)" executing script from Delphi -

mongodb - How to keep track of users making Stripe Payments -