This post is used to describe how Linux creates device files under /dev, illustrated with devices attached to TCC8935's DISPLAY bus.
First of all, the "create device file" procedures are device-type specific:
1. Char device. Example: VIQE //drivers/video/tcc/viqe/tcc_vioc_viqe.c
When the driver (module) is loaded in:
static int __init tcc_viqe_init(void)
{
int res;
res = register_chrdev(VIQE_DEV_MAJOR, VIQE_DEV_NAME, &tcc_viqe_fops);
if (res < 0)
return res;
viqe_class = class_create(THIS_MODULE, VIQE_DEV_NAME);
device_create(viqe_class, NULL, MKDEV(VIQE_DEV_MAJOR, VIQE_DEV_MINOR), NULL, VIQE_DEV_NAME);
printk(KERN_INFO "%s\n", __FUNCTION__);
return 0;
}
The routine device_create() creates a node under /dev according to MAJOR / MINOR / NAME parameters, /dev/viqe.
BTW, routine class_create() creates a class "viqe" under /sys/class.
Similar examples include WMIXER / SCALER. //drivers/char/tcc_wmixer.c, tcc_scaler.c
2. Platform device.
According to other blogs, Linux creates device node for platform devices when the DEVICE is registered, rather than the driver is registered.
For example:
platform_device_register(&tcc_lcd_device); (the struct tcc_lcd_device's NAME is "tccfb", which is identical with it's driver's name.
CALLS platform_device_add(dev) -> CALLS device_add()
routine device_add() calls device_create_file() to create files under /sys
and
calls devtmpfs_create_node() to create device node under /dev.
NOTE: see blow blogs for details: http://jieohsong.blog.163.com/blog/static/110530884201343054853424/ and
I'm not sure if it's correct but i do cannot find a "tccfb" node under /dev.
Well, my understanding is totally different. The driver creates device node within PROBE phase, and, the approach is device specific.
Example 1: tccfb //drivers/video/tcc/tcc_vioc_fb.c
This is a PLATFORM device since the driver is registered via platform_driver_register().
In routine probe(), calls register_framebuffer() -> do_register_framebuffer() , in do_register_framebuffer(),
fb_info->dev = device_create(fb_class, fb_info->device,
MKDEV(FB_MAJOR, i), NULL, "fb%d", i);
The fb_class is "graphics", FB_MAJOR is 29.
Here, we see device_create() again, exact the same as a char device above. And, there is a node under /dev/graphics, fb0, major number is 29.
Example 2: overlay //drivers/video/tcc/tcc_overlay.c
This is a PLATFORM device.
static struct platform_device tcc_overlay_device = {
.name = "tcc_overlay",
.dev = {
.release = NULL,
},
.id = 0,
};
But also a MISC device.
static struct miscdevice overlay_misc_device =
{
DEV_MINOR,
DEVICE_NAME,
&tcc_overlay_fops,
};
At the end of probe(), within misc_register(&overlay_misc_device), calls
misc->this_device = device_create(misc_class, misc->parent, dev,
misc, "%s", misc->name);
Familiar? That it! It creates /dev/overlay.