€•6|Œsphinx.addnodes”Œdocument”“”)”}”(Œ rawsource”Œ”Œchildren”]”(Œ translations”Œ LanguagesNode”“”)”}”(hhh]”(hŒ pending_xref”“”)”}”(hhh]”Œdocutils.nodes”ŒText”“”ŒChinese (Simplified)”…””}”Œparent”hsbaŒ attributes”}”(Œids”]”Œclasses”]”Œnames”]”Œdupnames”]”Œbackrefs”]”Œ refdomain”Œstd”Œreftype”Œdoc”Œ reftarget”Œ:/translations/zh_CN/watchdog/convert_drivers_to_kernel_api”Œmodname”NŒ classname”NŒ refexplicit”ˆuŒtagname”hhh ubh)”}”(hhh]”hŒChinese (Traditional)”…””}”hh2sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ:/translations/zh_TW/watchdog/convert_drivers_to_kernel_api”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒItalian”…””}”hhFsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ:/translations/it_IT/watchdog/convert_drivers_to_kernel_api”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒJapanese”…””}”hhZsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ:/translations/ja_JP/watchdog/convert_drivers_to_kernel_api”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒKorean”…””}”hhnsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ:/translations/ko_KR/watchdog/convert_drivers_to_kernel_api”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒPortuguese (Brazilian)”…””}”hh‚sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ:/translations/pt_BR/watchdog/convert_drivers_to_kernel_api”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒSpanish”…””}”hh–sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ:/translations/sp_SP/watchdog/convert_drivers_to_kernel_api”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubeh}”(h]”h ]”h"]”h$]”h&]”Œcurrent_language”ŒEnglish”uh1h hhŒ _document”hŒsource”NŒline”NubhŒsection”“”)”}”(hhh]”(hŒtitle”“”)”}”(hŒ9Converting old watchdog drivers to the watchdog framework”h]”hŒ9Converting old watchdog drivers to the watchdog framework”…””}”(hh¼h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhh·h²hh³ŒT/var/lib/git/docbuild/linux/Documentation/watchdog/convert_drivers_to_kernel_api.rst”h´KubhŒ paragraph”“”)”}”(hŒ by Wolfram Sang ”h]”(hŒby Wolfram Sang <”…””}”(hhÍh²hh³Nh´NubhŒ reference”“”)”}”(hŒwsa@kernel.org”h]”hŒwsa@kernel.org”…””}”(hh×h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œrefuri”Œmailto:wsa@kernel.org”uh1hÕhhÍubhŒ>”…””}”(hhÍh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Khh·h²hubhÌ)”}”(hXSBefore the watchdog framework came into the kernel, every driver had to implement the API on its own. Now, as the framework factored out the common components, those drivers can be lightened making it a user of the framework. This document shall guide you for this task. The necessary steps are described as well as things to look out for.”h]”hXSBefore the watchdog framework came into the kernel, every driver had to implement the API on its own. Now, as the framework factored out the common components, those drivers can be lightened making it a user of the framework. This document shall guide you for this task. The necessary steps are described as well as things to look out for.”…””}”(hhñh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Khh·h²hubh¶)”}”(hhh]”(h»)”}”(hŒ!Remove the file_operations struct”h]”hŒ!Remove the file_operations struct”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhhÿh²hh³hÊh´KubhÌ)”}”(hXzOld drivers define their own file_operations for actions like open(), write(), etc... These are now handled by the framework and just call the driver when needed. So, in general, the 'file_operations' struct and assorted functions can go. Only very few driver-specific details have to be moved to other functions. Here is a overview of the functions and probably needed actions:”h]”hX~Old drivers define their own file_operations for actions like open(), write(), etc... These are now handled by the framework and just call the driver when needed. So, in general, the ‘file_operations’ struct and assorted functions can go. Only very few driver-specific details have to be moved to other functions. Here is a overview of the functions and probably needed actions:”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Khhÿh²hubhŒ bullet_list”“”)”}”(hhh]”(hŒ list_item”“”)”}”(hXˆopen: Everything dealing with resource management (file-open checks, magic close preparations) can simply go. Device specific stuff needs to go to the driver specific start-function. Note that for some drivers, the start-function also serves as the ping-function. If that is the case and you need start/stop to be balanced (clocks!), you are better off refactoring a separate start-function. ”h]”hÌ)”}”(hX‡open: Everything dealing with resource management (file-open checks, magic close preparations) can simply go. Device specific stuff needs to go to the driver specific start-function. Note that for some drivers, the start-function also serves as the ping-function. If that is the case and you need start/stop to be balanced (clocks!), you are better off refactoring a separate start-function.”h]”hX‡open: Everything dealing with resource management (file-open checks, magic close preparations) can simply go. Device specific stuff needs to go to the driver specific start-function. Note that for some drivers, the start-function also serves as the ping-function. If that is the case and you need start/stop to be balanced (clocks!), you are better off refactoring a separate start-function.”…””}”(hj)h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Khj%ubah}”(h]”h ]”h"]”h$]”h&]”uh1j#hj h²hh³hÊh´Nubj$)”}”(hŒ%close: Same hints as for open apply. ”h]”hÌ)”}”(hŒ$close: Same hints as for open apply.”h]”hŒ$close: Same hints as for open apply.”…””}”(hjAh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Khj=ubah}”(h]”h ]”h"]”h$]”h&]”uh1j#hj h²hh³hÊh´Nubj$)”}”(hŒwrite: Can simply go, all defined behaviour is taken care of by the framework, i.e. ping on write and magic char ('V') handling. ”h]”hÌ)”}”(hŒ€write: Can simply go, all defined behaviour is taken care of by the framework, i.e. ping on write and magic char ('V') handling.”h]”hŒ„write: Can simply go, all defined behaviour is taken care of by the framework, i.e. ping on write and magic char (‘V’) handling.”…””}”(hjYh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KhjUubah}”(h]”h ]”h"]”h$]”h&]”uh1j#hj h²hh³hÊh´Nubj$)”}”(hXioctl: While the driver is allowed to have extensions to the IOCTL interface, the most common ones are handled by the framework, supported by some assistance from the driver: WDIOC_GETSUPPORT: Returns the mandatory watchdog_info struct from the driver WDIOC_GETSTATUS: Needs the status-callback defined, otherwise returns 0 WDIOC_GETBOOTSTATUS: Needs the bootstatus member properly set. Make sure it is 0 if you don't have further support! WDIOC_SETOPTIONS: No preparations needed WDIOC_KEEPALIVE: If wanted, options in watchdog_info need to have WDIOF_KEEPALIVEPING set WDIOC_SETTIMEOUT: Options in watchdog_info need to have WDIOF_SETTIMEOUT set and a set_timeout-callback has to be defined. The core will also do limit-checking, if min_timeout and max_timeout in the watchdog device are set. All is optional. WDIOC_GETTIMEOUT: No preparations needed WDIOC_GETTIMELEFT: It needs get_timeleft() callback to be defined. Otherwise it will return EOPNOTSUPP Other IOCTLs can be served using the ioctl-callback. Note that this is mainly intended for porting old drivers; new drivers should not invent private IOCTLs. Private IOCTLs are processed first. When the callback returns with -ENOIOCTLCMD, the IOCTLs of the framework will be tried, too. Any other error is directly given to the user. ”h]”(hÌ)”}”(hŒ®ioctl: While the driver is allowed to have extensions to the IOCTL interface, the most common ones are handled by the framework, supported by some assistance from the driver:”h]”hŒ®ioctl: While the driver is allowed to have extensions to the IOCTL interface, the most common ones are handled by the framework, supported by some assistance from the driver:”…””}”(hjqh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K"hjmubhŒ block_quote”“”)”}”(hX„WDIOC_GETSUPPORT: Returns the mandatory watchdog_info struct from the driver WDIOC_GETSTATUS: Needs the status-callback defined, otherwise returns 0 WDIOC_GETBOOTSTATUS: Needs the bootstatus member properly set. Make sure it is 0 if you don't have further support! WDIOC_SETOPTIONS: No preparations needed WDIOC_KEEPALIVE: If wanted, options in watchdog_info need to have WDIOF_KEEPALIVEPING set WDIOC_SETTIMEOUT: Options in watchdog_info need to have WDIOF_SETTIMEOUT set and a set_timeout-callback has to be defined. The core will also do limit-checking, if min_timeout and max_timeout in the watchdog device are set. All is optional. WDIOC_GETTIMEOUT: No preparations needed WDIOC_GETTIMELEFT: It needs get_timeleft() callback to be defined. Otherwise it will return EOPNOTSUPP ”h]”hŒdefinition_list”“”)”}”(hhh]”(hŒdefinition_list_item”“”)”}”(hŒMWDIOC_GETSUPPORT: Returns the mandatory watchdog_info struct from the driver ”h]”(hŒterm”“”)”}”(hŒWDIOC_GETSUPPORT:”h]”hŒWDIOC_GETSUPPORT:”…””}”(hj’h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´K'hjŒubhŒ definition”“”)”}”(hhh]”hÌ)”}”(hŒ:Returns the mandatory watchdog_info struct from the driver”h]”hŒ:Returns the mandatory watchdog_info struct from the driver”…””}”(hj¥h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K'hj¢ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjŒubeh}”(h]”h ]”h"]”h$]”h&]”uh1jŠh³hÊh´K'hj‡ubj‹)”}”(hŒHWDIOC_GETSTATUS: Needs the status-callback defined, otherwise returns 0 ”h]”(j‘)”}”(hŒWDIOC_GETSTATUS:”h]”hŒWDIOC_GETSTATUS:”…””}”(hjÃh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´K*hj¿ubj¡)”}”(hhh]”hÌ)”}”(hŒ6Needs the status-callback defined, otherwise returns 0”h]”hŒ6Needs the status-callback defined, otherwise returns 0”…””}”(hjÔh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K*hjÑubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj¿ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jŠh³hÊh´K*hj‡ubj‹)”}”(hŒtWDIOC_GETBOOTSTATUS: Needs the bootstatus member properly set. Make sure it is 0 if you don't have further support! ”h]”(j‘)”}”(hŒWDIOC_GETBOOTSTATUS:”h]”hŒWDIOC_GETBOOTSTATUS:”…””}”(hjòh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´K.hjîubj¡)”}”(hhh]”hÌ)”}”(hŒ^Needs the bootstatus member properly set. Make sure it is 0 if you don't have further support!”h]”hŒ`Needs the bootstatus member properly set. Make sure it is 0 if you don’t have further support!”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K-hjubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjîubeh}”(h]”h ]”h"]”h$]”h&]”uh1jŠh³hÊh´K.hj‡ubj‹)”}”(hŒ)WDIOC_SETOPTIONS: No preparations needed ”h]”(j‘)”}”(hŒWDIOC_SETOPTIONS:”h]”hŒWDIOC_SETOPTIONS:”…””}”(hj!h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´K1hjubj¡)”}”(hhh]”hÌ)”}”(hŒNo preparations needed”h]”hŒNo preparations needed”…””}”(hj2h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K1hj/ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjubeh}”(h]”h ]”h"]”h$]”h&]”uh1jŠh³hÊh´K1hj‡ubj‹)”}”(hŒZWDIOC_KEEPALIVE: If wanted, options in watchdog_info need to have WDIOF_KEEPALIVEPING set ”h]”(j‘)”}”(hŒWDIOC_KEEPALIVE:”h]”hŒWDIOC_KEEPALIVE:”…””}”(hjPh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´K5hjLubj¡)”}”(hhh]”hÌ)”}”(hŒHIf wanted, options in watchdog_info need to have WDIOF_KEEPALIVEPING set”h]”hŒHIf wanted, options in watchdog_info need to have WDIOF_KEEPALIVEPING set”…””}”(hjah²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K4hj^ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjLubeh}”(h]”h ]”h"]”h$]”h&]”uh1jŠh³hÊh´K5hj‡ubj‹)”}”(hŒñWDIOC_SETTIMEOUT: Options in watchdog_info need to have WDIOF_SETTIMEOUT set and a set_timeout-callback has to be defined. The core will also do limit-checking, if min_timeout and max_timeout in the watchdog device are set. All is optional. ”h]”(j‘)”}”(hŒWDIOC_SETTIMEOUT:”h]”hŒWDIOC_SETTIMEOUT:”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´K;hj{ubj¡)”}”(hhh]”hÌ)”}”(hŒÞOptions in watchdog_info need to have WDIOF_SETTIMEOUT set and a set_timeout-callback has to be defined. The core will also do limit-checking, if min_timeout and max_timeout in the watchdog device are set. All is optional.”h]”hŒÞOptions in watchdog_info need to have WDIOF_SETTIMEOUT set and a set_timeout-callback has to be defined. The core will also do limit-checking, if min_timeout and max_timeout in the watchdog device are set. All is optional.”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K8hjubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj{ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jŠh³hÊh´K;hj‡ubj‹)”}”(hŒ)WDIOC_GETTIMEOUT: No preparations needed ”h]”(j‘)”}”(hŒWDIOC_GETTIMEOUT:”h]”hŒWDIOC_GETTIMEOUT:”…””}”(hj®h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´K>hjªubj¡)”}”(hhh]”hÌ)”}”(hŒNo preparations needed”h]”hŒNo preparations needed”…””}”(hj¿h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K>hj¼ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjªubeh}”(h]”h ]”h"]”h$]”h&]”uh1jŠh³hÊh´K>hj‡ubj‹)”}”(hŒgWDIOC_GETTIMELEFT: It needs get_timeleft() callback to be defined. Otherwise it will return EOPNOTSUPP ”h]”(j‘)”}”(hŒWDIOC_GETTIMELEFT:”h]”hŒWDIOC_GETTIMELEFT:”…””}”(hjÝh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´KBhjÙubj¡)”}”(hhh]”hÌ)”}”(hŒSIt needs get_timeleft() callback to be defined. Otherwise it will return EOPNOTSUPP”h]”hŒSIt needs get_timeleft() callback to be defined. Otherwise it will return EOPNOTSUPP”…””}”(hjîh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KAhjëubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjÙubeh}”(h]”h ]”h"]”h$]”h&]”uh1jŠh³hÊh´KBhj‡ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j…hjubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´K&hjmubhÌ)”}”(hXMOther IOCTLs can be served using the ioctl-callback. Note that this is mainly intended for porting old drivers; new drivers should not invent private IOCTLs. Private IOCTLs are processed first. When the callback returns with -ENOIOCTLCMD, the IOCTLs of the framework will be tried, too. Any other error is directly given to the user.”h]”hXMOther IOCTLs can be served using the ioctl-callback. Note that this is mainly intended for porting old drivers; new drivers should not invent private IOCTLs. Private IOCTLs are processed first. When the callback returns with -ENOIOCTLCMD, the IOCTLs of the framework will be tried, too. Any other error is directly given to the user.”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KDhjmubeh}”(h]”h ]”h"]”h$]”h&]”uh1j#hj h²hh³hÊh´Nubeh}”(h]”h ]”h"]”h$]”h&]”Œbullet”Œ-”uh1jh³hÊh´Khhÿh²hubhÌ)”}”(hŒExample conversion::”h]”hŒExample conversion:”…””}”(hj0h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KJhhÿh²hubhŒ literal_block”“”)”}”(hX-static const struct file_operations s3c2410wdt_fops = { - .owner = THIS_MODULE, - .write = s3c2410wdt_write, - .unlocked_ioctl = s3c2410wdt_ioctl, - .open = s3c2410wdt_open, - .release = s3c2410wdt_release, -};”h]”hX-static const struct file_operations s3c2410wdt_fops = { - .owner = THIS_MODULE, - .write = s3c2410wdt_write, - .unlocked_ioctl = s3c2410wdt_ioctl, - .open = s3c2410wdt_open, - .release = s3c2410wdt_release, -};”…””}”hj@sbah}”(h]”h ]”h"]”h$]”h&]”Œ xml:space”Œpreserve”uh1j>h³hÊh´KLhhÿh²hubhÌ)”}”(hŒaCheck the functions for device-specific stuff and keep it for later refactoring. The rest can go.”h]”hŒaCheck the functions for device-specific stuff and keep it for later refactoring. The rest can go.”…””}”(hjPh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KThhÿh²hubeh}”(h]”Œ!remove-the-file-operations-struct”ah ]”h"]”Œ!remove the file_operations struct”ah$]”h&]”uh1hµhh·h²hh³hÊh´Kubh¶)”}”(hhh]”(h»)”}”(hŒRemove the miscdevice”h]”hŒRemove the miscdevice”…””}”(hjih²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjfh²hh³hÊh´KYubhÌ)”}”(hŒ³Since the file_operations are gone now, you can also remove the 'struct miscdevice'. The framework will create it on watchdog_dev_register() called by watchdog_register_device()::”h]”hŒ¶Since the file_operations are gone now, you can also remove the ‘struct miscdevice’. The framework will create it on watchdog_dev_register() called by watchdog_register_device():”…””}”(hjwh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K[hjfh²hubj?)”}”(hŒ°-static struct miscdevice s3c2410wdt_miscdev = { - .minor = WATCHDOG_MINOR, - .name = "watchdog", - .fops = &s3c2410wdt_fops, -};”h]”hŒ°-static struct miscdevice s3c2410wdt_miscdev = { - .minor = WATCHDOG_MINOR, - .name = "watchdog", - .fops = &s3c2410wdt_fops, -};”…””}”hj…sbah}”(h]”h ]”h"]”h$]”h&]”jNjOuh1j>h³hÊh´K_hjfh²hubeh}”(h]”Œremove-the-miscdevice”ah ]”h"]”Œremove the miscdevice”ah$]”h&]”uh1hµhh·h²hh³hÊh´KYubh¶)”}”(hhh]”(h»)”}”(hŒ$Remove obsolete includes and defines”h]”hŒ$Remove obsolete includes and defines”…””}”(hjžh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhj›h²hh³hÊh´KgubhÌ)”}”(hŒBecause of the simplifications, a few defines are probably unused now. Remove them. Includes can be removed, too. For example::”h]”hŒ~Because of the simplifications, a few defines are probably unused now. Remove them. Includes can be removed, too. For example:”…””}”(hj¬h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Kihj›h²hubj?)”}”(hŒ™- #include - #include (if MODULE_ALIAS_MISCDEV is not used) - #include (if no custom IOCTLs are used)”h]”hŒ™- #include - #include (if MODULE_ALIAS_MISCDEV is not used) - #include (if no custom IOCTLs are used)”…””}”hjºsbah}”(h]”h ]”h"]”h$]”h&]”jNjOuh1j>h³hÊh´Klhj›h²hubeh}”(h]”Œ$remove-obsolete-includes-and-defines”ah ]”h"]”Œ$remove obsolete includes and defines”ah$]”h&]”uh1hµhh·h²hh³hÊh´Kgubh¶)”}”(hhh]”(h»)”}”(hŒAdd the watchdog operations”h]”hŒAdd the watchdog operations”…””}”(hjÓh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjÐh²hh³hÊh´KrubhÌ)”}”(hX[All possible callbacks are defined in 'struct watchdog_ops'. You can find it explained in 'watchdog-kernel-api.txt' in this directory. start() and owner must be set, the rest are optional. You will easily find corresponding functions in the old driver. Note that you will now get a pointer to the watchdog_device as a parameter to these functions, so you probably have to change the function header. Other changes are most likely not needed, because here simply happens the direct hardware access. If you have device-specific code left from the above steps, it should be refactored into these callbacks.”h]”hXcAll possible callbacks are defined in ‘struct watchdog_ops’. You can find it explained in ‘watchdog-kernel-api.txt’ in this directory. start() and owner must be set, the rest are optional. You will easily find corresponding functions in the old driver. Note that you will now get a pointer to the watchdog_device as a parameter to these functions, so you probably have to change the function header. Other changes are most likely not needed, because here simply happens the direct hardware access. If you have device-specific code left from the above steps, it should be refactored into these callbacks.”…””}”(hjáh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KthjÐh²hubhÌ)”}”(hŒHere is a simple example::”h]”hŒHere is a simple example:”…””}”(hjïh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K}hjÐh²hubj?)”}”(hŒë+static struct watchdog_ops s3c2410wdt_ops = { + .owner = THIS_MODULE, + .start = s3c2410wdt_start, + .stop = s3c2410wdt_stop, + .ping = s3c2410wdt_keepalive, + .set_timeout = s3c2410wdt_set_heartbeat, +};”h]”hŒë+static struct watchdog_ops s3c2410wdt_ops = { + .owner = THIS_MODULE, + .start = s3c2410wdt_start, + .stop = s3c2410wdt_stop, + .ping = s3c2410wdt_keepalive, + .set_timeout = s3c2410wdt_set_heartbeat, +};”…””}”hjýsbah}”(h]”h ]”h"]”h$]”h&]”jNjOuh1j>h³hÊh´KhjÐh²hubhÌ)”}”(hŒ-A typical function-header change looks like::”h]”hŒ,A typical function-header change looks like:”…””}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K‡hjÐh²hubj?)”}”(hŒÕ-static void s3c2410wdt_keepalive(void) +static int s3c2410wdt_keepalive(struct watchdog_device *wdd) { ... + + return 0; } ... - s3c2410wdt_keepalive(); + s3c2410wdt_keepalive(&s3c2410_wdd);”h]”hŒÕ-static void s3c2410wdt_keepalive(void) +static int s3c2410wdt_keepalive(struct watchdog_device *wdd) { ... + + return 0; } ... - s3c2410wdt_keepalive(); + s3c2410wdt_keepalive(&s3c2410_wdd);”…””}”hjsbah}”(h]”h ]”h"]”h$]”h&]”jNjOuh1j>h³hÊh´K‰hjÐh²hubeh}”(h]”Œadd-the-watchdog-operations”ah ]”h"]”Œadd the watchdog operations”ah$]”h&]”uh1hµhh·h²hh³hÊh´Krubh¶)”}”(hhh]”(h»)”}”(hŒAdd the watchdog device”h]”hŒAdd the watchdog device”…””}”(hj2h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhj/h²hh³hÊh´K˜ubhÌ)”}”(hX;Now we need to create a 'struct watchdog_device' and populate it with the necessary information for the framework. The struct is also explained in detail in 'watchdog-kernel-api.txt' in this directory. We pass it the mandatory watchdog_info struct and the newly created watchdog_ops. Often, old drivers have their own record-keeping for things like bootstatus and timeout using static variables. Those have to be converted to use the members in watchdog_device. Note that the timeout values are unsigned int. Some drivers use signed int, so this has to be converted, too.”h]”hXCNow we need to create a ‘struct watchdog_device’ and populate it with the necessary information for the framework. The struct is also explained in detail in ‘watchdog-kernel-api.txt’ in this directory. We pass it the mandatory watchdog_info struct and the newly created watchdog_ops. Often, old drivers have their own record-keeping for things like bootstatus and timeout using static variables. Those have to be converted to use the members in watchdog_device. Note that the timeout values are unsigned int. Some drivers use signed int, so this has to be converted, too.”…””}”(hj@h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Kšhj/h²hubhÌ)”}”(hŒ0Here is a simple example for a watchdog device::”h]”hŒ/Here is a simple example for a watchdog device:”…””}”(hjNh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K£hj/h²hubj?)”}”(hŒv+static struct watchdog_device s3c2410_wdd = { + .info = &s3c2410_wdt_ident, + .ops = &s3c2410wdt_ops, +};”h]”hŒv+static struct watchdog_device s3c2410_wdd = { + .info = &s3c2410_wdt_ident, + .ops = &s3c2410wdt_ops, +};”…””}”hj\sbah}”(h]”h ]”h"]”h$]”h&]”jNjOuh1j>h³hÊh´K¥hj/h²hubeh}”(h]”Œadd-the-watchdog-device”ah ]”h"]”Œadd the watchdog device”ah$]”h&]”uh1hµhh·h²hh³hÊh´K˜ubh¶)”}”(hhh]”(h»)”}”(hŒHandle the 'nowayout' feature”h]”hŒ!Handle the ‘nowayout’ feature”…””}”(hjuh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjrh²hh³hÊh´K¬ubhÌ)”}”(hXA few drivers use nowayout statically, i.e. there is no module parameter for it and only CONFIG_WATCHDOG_NOWAYOUT determines if the feature is going to be used. This needs to be converted by initializing the status variable of the watchdog_device like this::”h]”hXA few drivers use nowayout statically, i.e. there is no module parameter for it and only CONFIG_WATCHDOG_NOWAYOUT determines if the feature is going to be used. This needs to be converted by initializing the status variable of the watchdog_device like this:”…””}”(hjƒh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K®hjrh²hubj?)”}”(hŒ(.status = WATCHDOG_NOWAYOUT_INIT_STATUS,”h]”hŒ(.status = WATCHDOG_NOWAYOUT_INIT_STATUS,”…””}”hj‘sbah}”(h]”h ]”h"]”h$]”h&]”jNjOuh1j>h³hÊh´K³hjrh²hubhÌ)”}”(hŒœMost drivers, however, also allow runtime configuration of nowayout, usually by adding a module parameter. The conversion for this would be something like::”h]”hŒ›Most drivers, however, also allow runtime configuration of nowayout, usually by adding a module parameter. The conversion for this would be something like:”…””}”(hjŸh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Kµhjrh²hubj?)”}”(hŒ.watchdog_set_nowayout(&s3c2410_wdd, nowayout);”h]”hŒ.watchdog_set_nowayout(&s3c2410_wdd, nowayout);”…””}”hj­sbah}”(h]”h ]”h"]”h$]”h&]”jNjOuh1j>h³hÊh´K¸hjrh²hubhÌ)”}”(hŒ›The module parameter itself needs to stay, everything else related to nowayout can go, though. This will likely be some code in open(), close() or write().”h]”hŒ›The module parameter itself needs to stay, everything else related to nowayout can go, though. This will likely be some code in open(), close() or write().”…””}”(hj»h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Kºhjrh²hubeh}”(h]”Œhandle-the-nowayout-feature”ah ]”h"]”Œhandle the 'nowayout' feature”ah$]”h&]”uh1hµhh·h²hh³hÊh´K¬ubh¶)”}”(hhh]”(h»)”}”(hŒRegister the watchdog device”h]”hŒRegister the watchdog device”…””}”(hjÔh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjÑh²hh³hÊh´K¿ubhÌ)”}”(hŒÇReplace misc_register(&miscdev) with watchdog_register_device(&watchdog_dev). Make sure the return value gets checked and the error message, if present, still fits. Also convert the unregister case::”h]”hŒÆReplace misc_register(&miscdev) with watchdog_register_device(&watchdog_dev). Make sure the return value gets checked and the error message, if present, still fits. Also convert the unregister case:”…””}”(hjâh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KÁhjÑh²hubj?)”}”(hŒÍ- ret = misc_register(&s3c2410wdt_miscdev); + ret = watchdog_register_device(&s3c2410_wdd); ... - misc_deregister(&s3c2410wdt_miscdev); + watchdog_unregister_device(&s3c2410_wdd);”h]”hŒÍ- ret = misc_register(&s3c2410wdt_miscdev); + ret = watchdog_register_device(&s3c2410_wdd); ... - misc_deregister(&s3c2410wdt_miscdev); + watchdog_unregister_device(&s3c2410_wdd);”…””}”hjðsbah}”(h]”h ]”h"]”h$]”h&]”jNjOuh1j>h³hÊh´KÅhjÑh²hubeh}”(h]”Œregister-the-watchdog-device”ah ]”h"]”Œregister the watchdog device”ah$]”h&]”uh1hµhh·h²hh³hÊh´K¿ubh¶)”}”(hhh]”(h»)”}”(hŒUpdate the Kconfig-entry”h]”hŒUpdate the Kconfig-entry”…””}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjh²hh³hÊh´KÏubhÌ)”}”(hŒ;The entry for the driver now needs to select WATCHDOG_CORE:”h]”hŒ;The entry for the driver now needs to select WATCHDOG_CORE:”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KÑhjh²hubj€)”}”(hŒ+ select WATCHDOG_CORE ”h]”j)”}”(hhh]”j$)”}”(hŒselect WATCHDOG_CORE ”h]”hÌ)”}”(hŒselect WATCHDOG_CORE”h]”hŒselect WATCHDOG_CORE”…””}”(hj0h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KÓhj,ubah}”(h]”h ]”h"]”h$]”h&]”uh1j#hj)ubah}”(h]”h ]”h"]”h$]”h&]”j.Œ+”uh1jh³hÊh´KÓhj%ubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´KÓhjh²hubeh}”(h]”Œupdate-the-kconfig-entry”ah ]”h"]”Œupdate the kconfig-entry”ah$]”h&]”uh1hµhh·h²hh³hÊh´KÏubh¶)”}”(hhh]”(h»)”}”(hŒ&Create a patch and send it to upstream”h]”hŒ&Create a patch and send it to upstream”…””}”(hj\h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjYh²hh³hÊh´K×ubhÌ)”}”(hŒœMake sure you understood Documentation/process/submitting-patches.rst and send your patch to linux-watchdog@vger.kernel.org. We are looking forward to it :)”h]”(hŒ]Make sure you understood Documentation/process/submitting-patches.rst and send your patch to ”…””}”(hjjh²hh³Nh´NubhÖ)”}”(hŒlinux-watchdog@vger.kernel.org”h]”hŒlinux-watchdog@vger.kernel.org”…””}”(hjrh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œrefuri”Œ%mailto:linux-watchdog@vger.kernel.org”uh1hÕhjjubhŒ!. We are looking forward to it :)”…””}”(hjjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KÙhjYh²hubeh}”(h]”Œ&create-a-patch-and-send-it-to-upstream”ah ]”h"]”Œ&create a patch and send it to upstream”ah$]”h&]”uh1hµhh·h²hh³hÊh´K×ubeh}”(h]”Œ9converting-old-watchdog-drivers-to-the-watchdog-framework”ah ]”h"]”Œ9converting old watchdog drivers to the watchdog framework”ah$]”h&]”uh1hµhhh²hh³hÊh´Kubeh}”(h]”h ]”h"]”h$]”h&]”Œsource”hÊuh1hŒcurrent_source”NŒ current_line”NŒsettings”Œdocutils.frontend”ŒValues”“”)”}”(hºNŒ generator”NŒ datestamp”NŒ source_link”NŒ source_url”NŒ toc_backlinks”Œentry”Œfootnote_backlinks”KŒ sectnum_xform”KŒstrip_comments”NŒstrip_elements_with_classes”NŒ strip_classes”NŒ report_level”KŒ halt_level”KŒexit_status_level”KŒdebug”NŒwarning_stream”NŒ traceback”ˆŒinput_encoding”Œ utf-8-sig”Œinput_encoding_error_handler”Œstrict”Œoutput_encoding”Œutf-8”Œoutput_encoding_error_handler”j¿Œerror_encoding”Œutf-8”Œerror_encoding_error_handler”Œbackslashreplace”Œ language_code”Œen”Œrecord_dependencies”NŒconfig”NŒ id_prefix”hŒauto_id_prefix”Œid”Œ dump_settings”NŒdump_internals”NŒdump_transforms”NŒdump_pseudo_xml”NŒexpose_internals”NŒstrict_visitor”NŒ_disable_config”NŒ_source”hÊŒ _destination”NŒ _config_files”]”Œ7/var/lib/git/docbuild/linux/Documentation/docutils.conf”aŒfile_insertion_enabled”ˆŒ raw_enabled”KŒline_length_limit”M'Œpep_references”NŒ pep_base_url”Œhttps://peps.python.org/”Œpep_file_url_template”Œpep-%04d”Œrfc_references”NŒ rfc_base_url”Œ&https://datatracker.ietf.org/doc/html/”Œ tab_width”KŒtrim_footnote_reference_space”‰Œsyntax_highlight”Œlong”Œ smart_quotes”ˆŒsmartquotes_locales”]”Œcharacter_level_inline_markup”‰Œdoctitle_xform”‰Œ docinfo_xform”KŒsectsubtitle_xform”‰Œ image_loading”Œlink”Œembed_stylesheet”‰Œcloak_email_addresses”ˆŒsection_self_link”‰Œenv”NubŒreporter”NŒindirect_targets”]”Œsubstitution_defs”}”Œsubstitution_names”}”Œrefnames”}”Œrefids”}”Œnameids”}”(j™j–jcj`j˜j•jÍjÊj,j)jojljÎjËjjjVjSj‘jŽuŒ nametypes”}”(j™‰jc‰j˜‰j͉j,‰jo‰jΉj‰jV‰j‘‰uh}”(j–h·j`hÿj•jfjÊj›j)jÐjlj/jËjrjjÑjSjjŽjYuŒ footnote_refs”}”Œ citation_refs”}”Œ autofootnotes”]”Œautofootnote_refs”]”Œsymbol_footnotes”]”Œsymbol_footnote_refs”]”Œ footnotes”]”Œ citations”]”Œautofootnote_start”KŒsymbol_footnote_start”KŒ id_counter”Œ collections”ŒCounter”“”}”…”R”Œparse_messages”]”Œtransform_messages”]”Œ transformer”NŒ include_log”]”Œ decoration”Nh²hub.