总的来说有两个地方会调用到:一个是设备注销时,一个是驱动注销时。
platform_driver_unregister(struct platform_driver *drv)
0>driver_unregister(&drv->driver);
void driver_unregister(struct device_driver *drv)
一> bus_remove_driver(drv);
bus_remove_driver(struct device_driver *drv)
二> driver_detach(drv);
driver_detach(struct device_driver *drv)
三>__device_release_driver(dev);
__device_release_driver(struct device *dev)
{
struct device_driver *drv;
drv = dev->driver;
drv->remove(dev);
}
其中:
25 void driver_detach(struct device_driver *drv)
526 {
527 struct device_private *dev_prv;
528 struct device *dev;
536 dev_prv = list_entry(drv->p->klist_devices.k_list.prev,
537 struct device_private,
538 knode_driver.n_node);
539 dev = dev_prv->device;
547 __device_release_driver(dev);
553 }
==================================
489 int platform_driver_register(struct platform_driver *drv)
494 if (drv->remove)
495 drv->driver.remove = platform_drv_remove;
这边就是 platform_driver.remove = __devexit_p(xxx_remove),
platform_driver->driver.remove = platform_drv_remove;
当 platform_drv_remove(struct device *_dev)
463 {
464 struct platform_driver *drv = to_platform_driver(_dev->driver);
468 ret = drv->remove(dev);
473 }
499 return driver_register(&drv->driver);
一> int driver_register(struct device_driver *drv)
184 ret = bus_add_driver(drv);
二>
710 priv->driver = drv;
711 drv->p = priv;
719 error = driver_attach(drv);
三>
421 static int __driver_attach(struct device *dev, void *data)
442 driver_probe_device(drv, dev);
四>
252 static int really_probe(struct device *dev, struct device_driver *drv)
261 dev->driver = drv;
273 ret = drv->probe(dev);
500 }
========================================
platform_device_unregister
platform_device_del 或者 device_unregister都能往下调
device_del(struct device *dev)
bus_remove_device(struct device *dev)
__device_release_driver(dev);
{
struct device_driver *drv;
drv = dev->driver;
drv->remove(dev); 这个就是platform_drv_remove,
通过platform_drv_remove调到 platform_driver.remove
}
================================================
驱动被注销时:
199 #define module_platform_driver(__platform_driver) \
200 module_driver(__platform_driver, platform_driver_register, \
201 platform_driver_unregister)
1032 #define module_driver(__driver, __register, __unregister, ...) \
1033 static int __init __driver##_init(void) \
1034 { \
1035 return __register(&(__driver) , ##__VA_ARGS__); \
1036 } \
1037 module_init(__driver##_init); \
1038 static void __exit __driver##_exit(void) \
1039 { \
1040 __unregister(&(__driver) , ##__VA_ARGS__); \
1041 } \
1042 module_exit(__driver##_exit);
所以在rmmod时候,platform_driver_unregister 被调用,接着:
driver_unregister
bus_remove_driver(drv);
diver_detach(drv);
__device_release_driver(struct device *dev)
{
471 struct device_driver *drv;
472
473 drv = dev->driver;
...
473 drv = dev->driver;
474 if (drv) {
...
488 else if (drv->remove)
489 drv->remove(dev); 这个就是platform_drv_remove,据此调到 platform_driver.remove
....
491 dev->driver = NULL;
...... }
非常可笑,在我们的 platform_driver.remove 函数里调用了device_unregister(), 我本以为这个device_unregister()又会再此调用到这边。。。
突然间发现 dev->driver 被置为 NULL , 前面有个 if (drv) 判断,所以这里不会再进来了。
}
=======================================
#define DWC3_DEVICE_NAME "dwc3-device"
在刚才的驱动里:
621 static struct platform_driver dwc3_driver = {
623 .remove = __devexit_p(dwc3_remove),
624 .driver = {
625 .name = "dwc3-device",
626 .pm = &dwc3_pm_ops
627 },
628 };
dwc_gadget = platform_device_alloc(DWC3_DEVICE_NAME,...)
2267 static struct pci_driver dwc_otg_pci_driver = {
2271 .remove = dwc_otg_remove,
2278 };
2279
1826 static int dwc_otg_probe(struct pci_dev *pdev,
1827 const struct pci_device_id *id)
......
1981 if ( platform_device_add(dwc_gadget)) { // 该函数相当于 platform_device_resigter......
1991 if (platform_device_add(dwc_host)) {
2063 }
2290 static void __exit dwc_otg_exit(void)
2291 {
2292 pci_unregister_driver(&dwc_otg_pci_driver);
2294 }
================================================================================
别人的例子:
rmmod gprs_uart.ko→gprs_exit_module()→uart_unregister_driver()→gprs_uart_remove()→uart_remove_one_port()→gprs_uart_release_port()→release_mem_region()
static struct platform_driver gprs_plat_driver = {
.probe = gprs_uart_probe,/* Probe method */
.remove = __exit_p(gprs_uart_remove),/* Detach method */
};
static int __init gprs_init_module(void)
{
retval = platform_driver_register(&gprs_plat_driver);
}
static void __exit gprs_exit_module(void)
{
platform_driver_unregister(&gprs_plat_driver);
uart_unregister_driver(&gprs_uart_driver);
}
insmod gprs_uart.ko→gprs_init_module()→uart_register_driver()→gprs_uart_probe()→ uart_add_one_port()→gprs_uart_config_port()→gprs_uart_request_port()→request_mem_region()
open /dev/gprs_uart→gprs_uart_startup()→request_irq()
close /dev/gprs_uart→gprs_uart_shutdown()→free_irq()
http://blog.chinaunix.net/uid-20776117-id-3154782.html