日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

探究platform_driver中“多态”思想

發(fā)布時間:2025/1/21 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 探究platform_driver中“多态”思想 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

問題最初是下面的兩段代碼引出的:

static struct platform_driver sonypi_driver = {.driver = {.name = "sonypi",.owner = THIS_MODULE,},.probe = sonypi_probe,.remove = __devexit_p(sonypi_remove),.shutdown = sonypi_shutdown,.suspend = sonypi_suspend,.resume = sonypi_resume, }; static const struct dev_pm_ops aa5302_pm_ops = {.suspend = aa5302_suspend,.resume = aa5302_resume, }; #endifstatic struct platform_driver aa5302_driver = {.driver = {.name = "aa5302",.owner = THIS_MODULE, #ifdef CONFIG_PM.pm = &aa5302_pm_ops, #endif},.probe = aa5302_probe,.remove = __devexit_p(aa5302_remove),.shutdown = aa5302_shutdown, };

注意到這兩個驅動都是platform driver,但是對于電源管理的定義方式卻不同:前者直接賦值platform_driver中的suspend/resume字段,后者間接賦值driver.pm字段。一直以來,我接觸到的原廠驅動,大部分是后面的定義方式,一直覺得其定義方式很羅嗦,這次要好好研究一下。

這里http://lists.kernelnewbies.org/pipermail/kernelnewbies/2013-October/009074.html有人問了一個類似的問題,可惜的是沒有回復!

我們先看看kernel/include/linux/platform_device.h中的定義:

struct platform_driver {int (*probe)(struct platform_device *);int (*remove)(struct platform_device *);void (*shutdown)(struct platform_device *);int (*suspend)(struct platform_device *, pm_message_t state);int (*resume)(struct platform_device *);struct device_driver driver;const struct platform_device_id *id_table; };

再看看kernel/include/linux/device.h中的定義:

struct device_driver {const char *name;struct bus_type *bus;struct module *owner;const char *mod_name; /* used for built-in modules */bool suppress_bind_attrs; /* disables bind/unbind via sysfs */const struct of_device_id *of_match_table;int (*probe) (struct device *dev);int (*remove) (struct device *dev);void (*shutdown) (struct device *dev);int (*suspend) (struct device *dev, pm_message_t state);int (*resume) (struct device *dev);const struct attribute_group **groups;const struct dev_pm_ops *pm;struct driver_private *p; };

初看,它們都定義了probe, remove ... 等函數,但platform_driver里面包含了device_driver結構體,也就是說platform_driver中實際上有2套probe, remove ... 為什么會這樣的?我們再看看drivers/base/platform.c中關于platform_driver_register的定義:

int platform_driver_register(struct platform_driver *drv) {drv->driver.bus = &platform_bus_type;if (drv->probe)drv->driver.probe = platform_drv_probe;if (drv->remove)drv->driver.remove = platform_drv_remove;if (drv->shutdown)drv->driver.shutdown = platform_drv_shutdown;return driver_register(&drv->driver); }

至此,你可能會更納悶,這不是畫蛇添足嗎?把platform_driver中的probe, remove字段又賦值給了driver中的相應字段,最終效果是,這2套probe, remove...實際上指向的分別是相同的回調函數!其實,如果細看platform_driver和device_driver中的probe, remove指針的定義,你會發(fā)現,他們還是有差別的:

int (*probe)(struct platform_device *);
int (*probe) (struct device *dev);

那就是,參數類型不同哦!前者是platform_device,后者是device!如果你學習過C++語言,頭腦中有“繼承”和“多態(tài)”的概念,我相信你已經知道為什么要這么做了:)

這么說吧,device和device_driver分別是驅動中的基類,而platform_device和platform_driver分別是PLATFORM BUS體系中對應的派生類;device_driver中的probe是基類的虛函數,platform_driver中的probe是派生類中的重載函數。如果我們要寫的是platform設備驅動,那么應該按照platform_driver中的回調函數聲明格式來定義自己的回調函數。

因此sonypi驅動的shutdown函數是這樣定義的:

?

static void sonypi_shutdown(struct platform_device *dev) {sonypi_disable(); }

?

而不是:

static void sonypi_shutdown(struct device *dev) {sonypi_disable(); }

如果你非要用這個“基類的函數”,那也是有辦法的,在聲明platform_driver的時候,用下面的方式,純屬猜測,沒有驗證哈。

static struct platform_driver sonypi_driver = {.driver = {.name = "sonypi",.owner = THIS_MODULE,.shutdown = sonypi_shutdown,},.probe = sonypi_probe,.remove = __devexit_p(sonypi_remove),.suspend = sonypi_suspend,.resume = sonypi_resume, };

?

---------------------------------------------------------華麗的分割線-----------------------------------------------------------

?

下面再說說電源管理的問題,sonypi驅動使用了platform_driver.suspend/resume的方式來定義回調函數,而aa5302驅動使用platform_driver.driver.pm.suspend/resume的方式定義回調,這和上面說所講的“多態(tài)”似乎不完全契合。確實如此,這里涉及到另外一個legacy的問題,stackoverflow上的一篇解釋說的很明白:http://stackoverflow.com/questions/19462639/which-suspend-resume-pointer-is-the-right-one-to-use 我們看看platform_pm_suspend的實現,如果driver.pm字段不為空,則使用.pm提供的回調,否則使用platform_driver.suspend定義的lagacy方式的回調。

int platform_pm_suspend(struct device *dev) {struct device_driver *drv = dev->driver;int ret = 0;if (!drv)return 0;if (drv->pm) {if (drv->pm->suspend)ret = drv->pm->suspend(dev);} else {ret = platform_legacy_suspend(dev, PMSG_SUSPEND);}return ret; }

device_driver.suspend/resume是舊的方式,他們在dev_pm_ops誕生以前就存在了,我們新的驅動中應該使用dev_pm_ops來定義回調函數。stackoverflow中提到的i2c驅動,跟這里的2個platform_driver還不完全一樣,i2c_driver僅僅提供一組通信接口,其并不提供設備的控制邏輯,在音頻codec中體現的非常明顯,音頻codec本質上是一個I2C芯片,在probe函數中注冊了一個更加“高級”的控制設備:codec,控制邏輯由codec來完成。因此其i2c_driver中并沒有提供電源管理功能:

static struct i2c_driver wm8900_i2c_driver = {.driver = {.name = "WM8900",.owner = THIS_MODULE,},.probe = wm8900_i2c_probe,.remove = __devexit_p(wm8900_i2c_remove),.shutdown = wm8900_i2c_shutdown,.id_table = wm8900_i2c_id, };

而是轉移到了codec中:

static struct snd_soc_codec_driver soc_codec_dev_wm8900 = {.probe = wm8900_probe,.remove = wm8900_remove,.suspend = wm8900_suspend,.resume = wm8900_resume,.set_bias_level = wm8900_set_bias_level,.volatile_register = wm8900_volatile_register,.reg_cache_size = ARRAY_SIZE(wm8900_reg_defaults),.reg_word_size = sizeof(u16),.reg_cache_default = wm8900_reg_defaults, };

?

轉載于:https://www.cnblogs.com/swnuwangyun/p/4233821.html

總結

以上是生活随笔為你收集整理的探究platform_driver中“多态”思想的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 男生裸体视频网站 | 99热成人| 久久精品av | 欧美特黄 | 欧美日韩在线国产 | 99超碰在线观看 | 免费超碰在线观看 | 亚洲成人黄 | 亚洲精品乱码久久久久久蜜桃欧美 | 卡通动漫亚洲综合 | 国产免费无遮挡 | 在线观看成人动漫 | 手机免费在线观看av | 密臀av一区二区 | 亚洲瑟瑟 | 91黄版| 在线精品视频一区 | 一二级毛片 | 激情六月色 | 亚色视频在线 | 伊人久久大香线蕉综合网站 | 黄色激情视频在线观看 | 免费看黄色大片 | 91av在线视频播放 | 亚洲精品久久久久久久久 | 日本三区视频 | 9cao| 熟妇人妻精品一区二区三区视频 | 日韩人妻精品一区二区 | 91官网入口| 玩弄人妻少妇500系列视频 | 97视频播放 | 黄色国产片 | 高清日韩一区 | 国产精品久久国产愉拍 | 免费视频日韩 | 色妞综合网 | 日日操夜夜摸 | 久草黄色| 色屁屁一区二区三区视频 | 国产区视频在线观看 | 国产丝袜一区二区 | 日韩爱爱免费视频 | 蜜桃视频一区二区三区在线观看 | 国产精品亲子伦对白 | 国产免费内射又粗又爽密桃视频 | 亚洲av色一区二区三区精品 | www.色日本 | 日批免费在线观看 | av电影一区二区 | 亚洲妇女无套内射精 | 中文字幕第28页 | 欧美整片在线 | 天天草天天操 | 97欧美视频 | 丁香六月欧美 | 全国男人天堂网 | 国产精品jizz在线观看老狼 | 色在线免费视频 | 亚洲综合激情小说 | www.久热 | 粗口调教gay2022.com | 成人在线观看你懂的 | 久久精彩免费视频 | 日韩1区2区3区 | 国产精品一区二区在线观看 | 亚洲伦理视频 | 天天躁夜夜操 | 久久综合色视频 | 亚洲欧洲成人在线 | 国产免费的av | 亚洲午夜精品一区二区三区 | 五月激情小说网 | 欧洲成人午夜精品无码区久久 | 医生强烈淫药h调教小说视频 | www.午夜av| 三级黄色片免费观看 | 日韩中文在线播放 | 五十路六十路七十路熟婆 | 成人3d动漫在线观看 | 看一级黄色| 精品在线视频免费 | 少妇一级淫片免费放 | 青青草视频 | 大片视频免费观看视频 | 中文字幕精品一区二区三区视频 | 深夜在线 | 精品一区二区三区无码视频 | 在线草 | 男女黄网站 | 国产精选自拍 | www九九热 | 国产精品久久久久精 | 五月亚洲婷婷 | 国产按摩一区二区三区 | 熟女少妇一区二区 | 亚洲精品2 | 精品国产三级片在线观看 | 五月丁香久久婷婷 |