dpll_netlink.c 49 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Generic netlink for DPLL management framework
  4. *
  5. * Copyright (c) 2023 Meta Platforms, Inc. and affiliates
  6. * Copyright (c) 2023 Intel and affiliates
  7. *
  8. */
  9. #include <linux/module.h>
  10. #include <linux/kernel.h>
  11. #include <linux/netdevice.h>
  12. #include <net/genetlink.h>
  13. #include "dpll_core.h"
  14. #include "dpll_netlink.h"
  15. #include "dpll_nl.h"
  16. #include <uapi/linux/dpll.h>
  17. #define ASSERT_NOT_NULL(ptr) (WARN_ON(!ptr))
  18. #define xa_for_each_marked_start(xa, index, entry, filter, start) \
  19. for (index = start, entry = xa_find(xa, &index, ULONG_MAX, filter); \
  20. entry; entry = xa_find_after(xa, &index, ULONG_MAX, filter))
  21. struct dpll_dump_ctx {
  22. unsigned long idx;
  23. };
  24. static struct dpll_dump_ctx *dpll_dump_context(struct netlink_callback *cb)
  25. {
  26. return (struct dpll_dump_ctx *)cb->ctx;
  27. }
  28. static int
  29. dpll_msg_add_dev_handle(struct sk_buff *msg, struct dpll_device *dpll)
  30. {
  31. if (nla_put_u32(msg, DPLL_A_ID, dpll->id))
  32. return -EMSGSIZE;
  33. return 0;
  34. }
  35. static int
  36. dpll_msg_add_dev_parent_handle(struct sk_buff *msg, u32 id)
  37. {
  38. if (nla_put_u32(msg, DPLL_A_PIN_PARENT_ID, id))
  39. return -EMSGSIZE;
  40. return 0;
  41. }
  42. static bool dpll_pin_available(struct dpll_pin *pin)
  43. {
  44. struct dpll_pin_ref *par_ref;
  45. unsigned long i;
  46. if (!xa_get_mark(&dpll_pin_xa, pin->id, DPLL_REGISTERED))
  47. return false;
  48. xa_for_each(&pin->parent_refs, i, par_ref)
  49. if (xa_get_mark(&dpll_pin_xa, par_ref->pin->id,
  50. DPLL_REGISTERED))
  51. return true;
  52. xa_for_each(&pin->dpll_refs, i, par_ref)
  53. if (xa_get_mark(&dpll_device_xa, par_ref->dpll->id,
  54. DPLL_REGISTERED))
  55. return true;
  56. return false;
  57. }
  58. /**
  59. * dpll_msg_add_pin_handle - attach pin handle attribute to a given message
  60. * @msg: pointer to sk_buff message to attach a pin handle
  61. * @pin: pin pointer
  62. *
  63. * Return:
  64. * * 0 - success
  65. * * -EMSGSIZE - no space in message to attach pin handle
  66. */
  67. static int dpll_msg_add_pin_handle(struct sk_buff *msg, struct dpll_pin *pin)
  68. {
  69. if (!pin)
  70. return 0;
  71. if (nla_put_u32(msg, DPLL_A_PIN_ID, pin->id))
  72. return -EMSGSIZE;
  73. return 0;
  74. }
  75. static struct dpll_pin *dpll_netdev_pin(const struct net_device *dev)
  76. {
  77. return rcu_dereference_rtnl(dev->dpll_pin);
  78. }
  79. /**
  80. * dpll_netdev_pin_handle_size - get size of pin handle attribute of a netdev
  81. * @dev: netdev from which to get the pin
  82. *
  83. * Return: byte size of pin handle attribute, or 0 if @dev has no pin.
  84. */
  85. size_t dpll_netdev_pin_handle_size(const struct net_device *dev)
  86. {
  87. return dpll_netdev_pin(dev) ? nla_total_size(4) : 0; /* DPLL_A_PIN_ID */
  88. }
  89. int dpll_netdev_add_pin_handle(struct sk_buff *msg,
  90. const struct net_device *dev)
  91. {
  92. return dpll_msg_add_pin_handle(msg, dpll_netdev_pin(dev));
  93. }
  94. static int
  95. dpll_msg_add_mode(struct sk_buff *msg, struct dpll_device *dpll,
  96. struct netlink_ext_ack *extack)
  97. {
  98. const struct dpll_device_ops *ops = dpll_device_ops(dpll);
  99. enum dpll_mode mode;
  100. int ret;
  101. ret = ops->mode_get(dpll, dpll_priv(dpll), &mode, extack);
  102. if (ret)
  103. return ret;
  104. if (nla_put_u32(msg, DPLL_A_MODE, mode))
  105. return -EMSGSIZE;
  106. return 0;
  107. }
  108. static int
  109. dpll_msg_add_mode_supported(struct sk_buff *msg, struct dpll_device *dpll,
  110. struct netlink_ext_ack *extack)
  111. {
  112. const struct dpll_device_ops *ops = dpll_device_ops(dpll);
  113. DECLARE_BITMAP(modes, DPLL_MODE_MAX + 1) = { 0 };
  114. enum dpll_mode mode;
  115. int ret;
  116. if (ops->supported_modes_get) {
  117. ret = ops->supported_modes_get(dpll, dpll_priv(dpll), modes,
  118. extack);
  119. if (ret)
  120. return ret;
  121. } else {
  122. /* If the supported modes are not reported by the driver, the
  123. * only supported mode is the one obtained by mode_get().
  124. */
  125. ret = ops->mode_get(dpll, dpll_priv(dpll), &mode, extack);
  126. if (ret)
  127. return ret;
  128. __set_bit(mode, modes);
  129. }
  130. for_each_set_bit(mode, modes, DPLL_MODE_MAX + 1)
  131. if (nla_put_u32(msg, DPLL_A_MODE_SUPPORTED, mode))
  132. return -EMSGSIZE;
  133. return 0;
  134. }
  135. static int
  136. dpll_msg_add_phase_offset_monitor(struct sk_buff *msg, struct dpll_device *dpll,
  137. struct netlink_ext_ack *extack)
  138. {
  139. const struct dpll_device_ops *ops = dpll_device_ops(dpll);
  140. enum dpll_feature_state state;
  141. int ret;
  142. if (ops->phase_offset_monitor_set && ops->phase_offset_monitor_get) {
  143. ret = ops->phase_offset_monitor_get(dpll, dpll_priv(dpll),
  144. &state, extack);
  145. if (ret)
  146. return ret;
  147. if (nla_put_u32(msg, DPLL_A_PHASE_OFFSET_MONITOR, state))
  148. return -EMSGSIZE;
  149. }
  150. return 0;
  151. }
  152. static int
  153. dpll_msg_add_phase_offset_avg_factor(struct sk_buff *msg,
  154. struct dpll_device *dpll,
  155. struct netlink_ext_ack *extack)
  156. {
  157. const struct dpll_device_ops *ops = dpll_device_ops(dpll);
  158. u32 factor;
  159. int ret;
  160. if (ops->phase_offset_avg_factor_get) {
  161. ret = ops->phase_offset_avg_factor_get(dpll, dpll_priv(dpll),
  162. &factor, extack);
  163. if (ret)
  164. return ret;
  165. if (nla_put_u32(msg, DPLL_A_PHASE_OFFSET_AVG_FACTOR, factor))
  166. return -EMSGSIZE;
  167. }
  168. return 0;
  169. }
  170. static int
  171. dpll_msg_add_lock_status(struct sk_buff *msg, struct dpll_device *dpll,
  172. struct netlink_ext_ack *extack)
  173. {
  174. const struct dpll_device_ops *ops = dpll_device_ops(dpll);
  175. enum dpll_lock_status_error status_error = 0;
  176. enum dpll_lock_status status;
  177. int ret;
  178. ret = ops->lock_status_get(dpll, dpll_priv(dpll), &status,
  179. &status_error, extack);
  180. if (ret)
  181. return ret;
  182. if (nla_put_u32(msg, DPLL_A_LOCK_STATUS, status))
  183. return -EMSGSIZE;
  184. if (status_error &&
  185. (status == DPLL_LOCK_STATUS_UNLOCKED ||
  186. status == DPLL_LOCK_STATUS_HOLDOVER) &&
  187. nla_put_u32(msg, DPLL_A_LOCK_STATUS_ERROR, status_error))
  188. return -EMSGSIZE;
  189. return 0;
  190. }
  191. static int
  192. dpll_msg_add_temp(struct sk_buff *msg, struct dpll_device *dpll,
  193. struct netlink_ext_ack *extack)
  194. {
  195. const struct dpll_device_ops *ops = dpll_device_ops(dpll);
  196. s32 temp;
  197. int ret;
  198. if (!ops->temp_get)
  199. return 0;
  200. ret = ops->temp_get(dpll, dpll_priv(dpll), &temp, extack);
  201. if (ret)
  202. return ret;
  203. if (nla_put_s32(msg, DPLL_A_TEMP, temp))
  204. return -EMSGSIZE;
  205. return 0;
  206. }
  207. static int
  208. dpll_msg_add_clock_quality_level(struct sk_buff *msg, struct dpll_device *dpll,
  209. struct netlink_ext_ack *extack)
  210. {
  211. DECLARE_BITMAP(qls, DPLL_CLOCK_QUALITY_LEVEL_MAX + 1) = { 0 };
  212. const struct dpll_device_ops *ops = dpll_device_ops(dpll);
  213. enum dpll_clock_quality_level ql;
  214. int ret;
  215. if (!ops->clock_quality_level_get)
  216. return 0;
  217. ret = ops->clock_quality_level_get(dpll, dpll_priv(dpll), qls, extack);
  218. if (ret)
  219. return ret;
  220. for_each_set_bit(ql, qls, DPLL_CLOCK_QUALITY_LEVEL_MAX + 1)
  221. if (nla_put_u32(msg, DPLL_A_CLOCK_QUALITY_LEVEL, ql))
  222. return -EMSGSIZE;
  223. return 0;
  224. }
  225. static int
  226. dpll_msg_add_pin_prio(struct sk_buff *msg, struct dpll_pin *pin,
  227. struct dpll_pin_ref *ref,
  228. struct netlink_ext_ack *extack)
  229. {
  230. const struct dpll_pin_ops *ops = dpll_pin_ops(ref);
  231. struct dpll_device *dpll = ref->dpll;
  232. u32 prio;
  233. int ret;
  234. if (!ops->prio_get)
  235. return 0;
  236. ret = ops->prio_get(pin, dpll_pin_on_dpll_priv(dpll, pin), dpll,
  237. dpll_priv(dpll), &prio, extack);
  238. if (ret)
  239. return ret;
  240. if (nla_put_u32(msg, DPLL_A_PIN_PRIO, prio))
  241. return -EMSGSIZE;
  242. return 0;
  243. }
  244. static int
  245. dpll_msg_add_pin_on_dpll_state(struct sk_buff *msg, struct dpll_pin *pin,
  246. struct dpll_pin_ref *ref,
  247. struct netlink_ext_ack *extack)
  248. {
  249. const struct dpll_pin_ops *ops = dpll_pin_ops(ref);
  250. struct dpll_device *dpll = ref->dpll;
  251. enum dpll_pin_state state;
  252. int ret;
  253. if (!ops->state_on_dpll_get)
  254. return 0;
  255. ret = ops->state_on_dpll_get(pin, dpll_pin_on_dpll_priv(dpll, pin),
  256. dpll, dpll_priv(dpll), &state, extack);
  257. if (ret)
  258. return ret;
  259. if (nla_put_u32(msg, DPLL_A_PIN_STATE, state))
  260. return -EMSGSIZE;
  261. return 0;
  262. }
  263. static int
  264. dpll_msg_add_pin_direction(struct sk_buff *msg, struct dpll_pin *pin,
  265. struct dpll_pin_ref *ref,
  266. struct netlink_ext_ack *extack)
  267. {
  268. const struct dpll_pin_ops *ops = dpll_pin_ops(ref);
  269. struct dpll_device *dpll = ref->dpll;
  270. enum dpll_pin_direction direction;
  271. int ret;
  272. ret = ops->direction_get(pin, dpll_pin_on_dpll_priv(dpll, pin), dpll,
  273. dpll_priv(dpll), &direction, extack);
  274. if (ret)
  275. return ret;
  276. if (nla_put_u32(msg, DPLL_A_PIN_DIRECTION, direction))
  277. return -EMSGSIZE;
  278. return 0;
  279. }
  280. static int
  281. dpll_msg_add_pin_phase_adjust(struct sk_buff *msg, struct dpll_pin *pin,
  282. struct dpll_pin_ref *ref,
  283. struct netlink_ext_ack *extack)
  284. {
  285. const struct dpll_pin_ops *ops = dpll_pin_ops(ref);
  286. struct dpll_device *dpll = ref->dpll;
  287. s32 phase_adjust;
  288. int ret;
  289. if (!ops->phase_adjust_get)
  290. return 0;
  291. ret = ops->phase_adjust_get(pin, dpll_pin_on_dpll_priv(dpll, pin),
  292. dpll, dpll_priv(dpll),
  293. &phase_adjust, extack);
  294. if (ret)
  295. return ret;
  296. if (nla_put_s32(msg, DPLL_A_PIN_PHASE_ADJUST, phase_adjust))
  297. return -EMSGSIZE;
  298. return 0;
  299. }
  300. static int
  301. dpll_msg_add_phase_offset(struct sk_buff *msg, struct dpll_pin *pin,
  302. struct dpll_pin_ref *ref,
  303. struct netlink_ext_ack *extack)
  304. {
  305. const struct dpll_pin_ops *ops = dpll_pin_ops(ref);
  306. struct dpll_device *dpll = ref->dpll;
  307. s64 phase_offset;
  308. int ret;
  309. if (!ops->phase_offset_get)
  310. return 0;
  311. ret = ops->phase_offset_get(pin, dpll_pin_on_dpll_priv(dpll, pin),
  312. dpll, dpll_priv(dpll), &phase_offset,
  313. extack);
  314. if (ret)
  315. return ret;
  316. if (nla_put_64bit(msg, DPLL_A_PIN_PHASE_OFFSET, sizeof(phase_offset),
  317. &phase_offset, DPLL_A_PIN_PAD))
  318. return -EMSGSIZE;
  319. return 0;
  320. }
  321. static int dpll_msg_add_ffo(struct sk_buff *msg, struct dpll_pin *pin,
  322. struct dpll_pin_ref *ref,
  323. struct netlink_ext_ack *extack)
  324. {
  325. const struct dpll_pin_ops *ops = dpll_pin_ops(ref);
  326. struct dpll_device *dpll = ref->dpll;
  327. s64 ffo;
  328. int ret;
  329. if (!ops->ffo_get)
  330. return 0;
  331. ret = ops->ffo_get(pin, dpll_pin_on_dpll_priv(dpll, pin),
  332. dpll, dpll_priv(dpll), &ffo, extack);
  333. if (ret) {
  334. if (ret == -ENODATA)
  335. return 0;
  336. return ret;
  337. }
  338. /* Put the FFO value in PPM to preserve compatibility with older
  339. * programs.
  340. */
  341. ret = nla_put_sint(msg, DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET,
  342. div_s64(ffo, 1000000));
  343. if (ret)
  344. return -EMSGSIZE;
  345. return nla_put_sint(msg, DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET_PPT,
  346. ffo);
  347. }
  348. static int
  349. dpll_msg_add_pin_freq(struct sk_buff *msg, struct dpll_pin *pin,
  350. struct dpll_pin_ref *ref, struct netlink_ext_ack *extack)
  351. {
  352. const struct dpll_pin_ops *ops = dpll_pin_ops(ref);
  353. struct dpll_device *dpll = ref->dpll;
  354. struct nlattr *nest;
  355. int fs, ret;
  356. u64 freq;
  357. if (!ops->frequency_get)
  358. return 0;
  359. ret = ops->frequency_get(pin, dpll_pin_on_dpll_priv(dpll, pin), dpll,
  360. dpll_priv(dpll), &freq, extack);
  361. if (ret)
  362. return ret;
  363. if (nla_put_64bit(msg, DPLL_A_PIN_FREQUENCY, sizeof(freq), &freq,
  364. DPLL_A_PIN_PAD))
  365. return -EMSGSIZE;
  366. for (fs = 0; fs < pin->prop.freq_supported_num; fs++) {
  367. nest = nla_nest_start(msg, DPLL_A_PIN_FREQUENCY_SUPPORTED);
  368. if (!nest)
  369. return -EMSGSIZE;
  370. freq = pin->prop.freq_supported[fs].min;
  371. if (nla_put_64bit(msg, DPLL_A_PIN_FREQUENCY_MIN, sizeof(freq),
  372. &freq, DPLL_A_PIN_PAD)) {
  373. nla_nest_cancel(msg, nest);
  374. return -EMSGSIZE;
  375. }
  376. freq = pin->prop.freq_supported[fs].max;
  377. if (nla_put_64bit(msg, DPLL_A_PIN_FREQUENCY_MAX, sizeof(freq),
  378. &freq, DPLL_A_PIN_PAD)) {
  379. nla_nest_cancel(msg, nest);
  380. return -EMSGSIZE;
  381. }
  382. nla_nest_end(msg, nest);
  383. }
  384. return 0;
  385. }
  386. static int
  387. dpll_msg_add_pin_esync(struct sk_buff *msg, struct dpll_pin *pin,
  388. struct dpll_pin_ref *ref, struct netlink_ext_ack *extack)
  389. {
  390. const struct dpll_pin_ops *ops = dpll_pin_ops(ref);
  391. struct dpll_device *dpll = ref->dpll;
  392. struct dpll_pin_esync esync;
  393. struct nlattr *nest;
  394. int ret, i;
  395. if (!ops->esync_get)
  396. return 0;
  397. ret = ops->esync_get(pin, dpll_pin_on_dpll_priv(dpll, pin), dpll,
  398. dpll_priv(dpll), &esync, extack);
  399. if (ret == -EOPNOTSUPP)
  400. return 0;
  401. else if (ret)
  402. return ret;
  403. if (nla_put_64bit(msg, DPLL_A_PIN_ESYNC_FREQUENCY, sizeof(esync.freq),
  404. &esync.freq, DPLL_A_PIN_PAD))
  405. return -EMSGSIZE;
  406. if (nla_put_u32(msg, DPLL_A_PIN_ESYNC_PULSE, esync.pulse))
  407. return -EMSGSIZE;
  408. for (i = 0; i < esync.range_num; i++) {
  409. nest = nla_nest_start(msg,
  410. DPLL_A_PIN_ESYNC_FREQUENCY_SUPPORTED);
  411. if (!nest)
  412. return -EMSGSIZE;
  413. if (nla_put_64bit(msg, DPLL_A_PIN_FREQUENCY_MIN,
  414. sizeof(esync.range[i].min),
  415. &esync.range[i].min, DPLL_A_PIN_PAD))
  416. goto nest_cancel;
  417. if (nla_put_64bit(msg, DPLL_A_PIN_FREQUENCY_MAX,
  418. sizeof(esync.range[i].max),
  419. &esync.range[i].max, DPLL_A_PIN_PAD))
  420. goto nest_cancel;
  421. nla_nest_end(msg, nest);
  422. }
  423. return 0;
  424. nest_cancel:
  425. nla_nest_cancel(msg, nest);
  426. return -EMSGSIZE;
  427. }
  428. static int
  429. dpll_msg_add_pin_ref_sync(struct sk_buff *msg, struct dpll_pin *pin,
  430. struct dpll_pin_ref *ref,
  431. struct netlink_ext_ack *extack)
  432. {
  433. const struct dpll_pin_ops *ops = dpll_pin_ops(ref);
  434. struct dpll_device *dpll = ref->dpll;
  435. void *pin_priv, *ref_sync_pin_priv;
  436. struct dpll_pin *ref_sync_pin;
  437. enum dpll_pin_state state;
  438. struct nlattr *nest;
  439. unsigned long index;
  440. int ret;
  441. pin_priv = dpll_pin_on_dpll_priv(dpll, pin);
  442. xa_for_each(&pin->ref_sync_pins, index, ref_sync_pin) {
  443. if (!dpll_pin_available(ref_sync_pin))
  444. continue;
  445. ref_sync_pin_priv = dpll_pin_on_dpll_priv(dpll, ref_sync_pin);
  446. if (WARN_ON(!ops->ref_sync_get))
  447. return -EOPNOTSUPP;
  448. ret = ops->ref_sync_get(pin, pin_priv, ref_sync_pin,
  449. ref_sync_pin_priv, &state, extack);
  450. if (ret)
  451. return ret;
  452. nest = nla_nest_start(msg, DPLL_A_PIN_REFERENCE_SYNC);
  453. if (!nest)
  454. return -EMSGSIZE;
  455. if (nla_put_s32(msg, DPLL_A_PIN_ID, ref_sync_pin->id))
  456. goto nest_cancel;
  457. if (nla_put_s32(msg, DPLL_A_PIN_STATE, state))
  458. goto nest_cancel;
  459. nla_nest_end(msg, nest);
  460. }
  461. return 0;
  462. nest_cancel:
  463. nla_nest_cancel(msg, nest);
  464. return -EMSGSIZE;
  465. }
  466. static bool dpll_pin_is_freq_supported(struct dpll_pin *pin, u32 freq)
  467. {
  468. int fs;
  469. for (fs = 0; fs < pin->prop.freq_supported_num; fs++)
  470. if (freq >= pin->prop.freq_supported[fs].min &&
  471. freq <= pin->prop.freq_supported[fs].max)
  472. return true;
  473. return false;
  474. }
  475. static int
  476. dpll_msg_add_pin_parents(struct sk_buff *msg, struct dpll_pin *pin,
  477. struct dpll_pin_ref *dpll_ref,
  478. struct netlink_ext_ack *extack)
  479. {
  480. enum dpll_pin_state state;
  481. struct dpll_pin_ref *ref;
  482. struct dpll_pin *ppin;
  483. struct nlattr *nest;
  484. unsigned long index;
  485. int ret;
  486. xa_for_each(&pin->parent_refs, index, ref) {
  487. const struct dpll_pin_ops *ops = dpll_pin_ops(ref);
  488. void *parent_priv;
  489. ppin = ref->pin;
  490. parent_priv = dpll_pin_on_dpll_priv(dpll_ref->dpll, ppin);
  491. ret = ops->state_on_pin_get(pin,
  492. dpll_pin_on_pin_priv(ppin, pin),
  493. ppin, parent_priv, &state, extack);
  494. if (ret)
  495. return ret;
  496. nest = nla_nest_start(msg, DPLL_A_PIN_PARENT_PIN);
  497. if (!nest)
  498. return -EMSGSIZE;
  499. ret = dpll_msg_add_dev_parent_handle(msg, ppin->id);
  500. if (ret)
  501. goto nest_cancel;
  502. if (nla_put_u32(msg, DPLL_A_PIN_STATE, state)) {
  503. ret = -EMSGSIZE;
  504. goto nest_cancel;
  505. }
  506. nla_nest_end(msg, nest);
  507. }
  508. return 0;
  509. nest_cancel:
  510. nla_nest_cancel(msg, nest);
  511. return ret;
  512. }
  513. static int
  514. dpll_msg_add_pin_dplls(struct sk_buff *msg, struct dpll_pin *pin,
  515. struct netlink_ext_ack *extack)
  516. {
  517. struct dpll_pin_ref *ref;
  518. struct nlattr *attr;
  519. unsigned long index;
  520. int ret;
  521. xa_for_each(&pin->dpll_refs, index, ref) {
  522. attr = nla_nest_start(msg, DPLL_A_PIN_PARENT_DEVICE);
  523. if (!attr)
  524. return -EMSGSIZE;
  525. ret = dpll_msg_add_dev_parent_handle(msg, ref->dpll->id);
  526. if (ret)
  527. goto nest_cancel;
  528. ret = dpll_msg_add_pin_on_dpll_state(msg, pin, ref, extack);
  529. if (ret)
  530. goto nest_cancel;
  531. ret = dpll_msg_add_pin_prio(msg, pin, ref, extack);
  532. if (ret)
  533. goto nest_cancel;
  534. ret = dpll_msg_add_pin_direction(msg, pin, ref, extack);
  535. if (ret)
  536. goto nest_cancel;
  537. ret = dpll_msg_add_phase_offset(msg, pin, ref, extack);
  538. if (ret)
  539. goto nest_cancel;
  540. nla_nest_end(msg, attr);
  541. }
  542. return 0;
  543. nest_cancel:
  544. nla_nest_end(msg, attr);
  545. return ret;
  546. }
  547. static int
  548. dpll_cmd_pin_get_one(struct sk_buff *msg, struct dpll_pin *pin,
  549. struct netlink_ext_ack *extack)
  550. {
  551. const struct dpll_pin_properties *prop = &pin->prop;
  552. struct dpll_pin_ref *ref;
  553. int ret;
  554. ref = dpll_xa_ref_dpll_first(&pin->dpll_refs);
  555. ASSERT_NOT_NULL(ref);
  556. ret = dpll_msg_add_pin_handle(msg, pin);
  557. if (ret)
  558. return ret;
  559. if (nla_put_string(msg, DPLL_A_PIN_MODULE_NAME,
  560. module_name(pin->module)))
  561. return -EMSGSIZE;
  562. if (nla_put_64bit(msg, DPLL_A_PIN_CLOCK_ID, sizeof(pin->clock_id),
  563. &pin->clock_id, DPLL_A_PIN_PAD))
  564. return -EMSGSIZE;
  565. if (prop->board_label &&
  566. nla_put_string(msg, DPLL_A_PIN_BOARD_LABEL, prop->board_label))
  567. return -EMSGSIZE;
  568. if (prop->panel_label &&
  569. nla_put_string(msg, DPLL_A_PIN_PANEL_LABEL, prop->panel_label))
  570. return -EMSGSIZE;
  571. if (prop->package_label &&
  572. nla_put_string(msg, DPLL_A_PIN_PACKAGE_LABEL,
  573. prop->package_label))
  574. return -EMSGSIZE;
  575. if (nla_put_u32(msg, DPLL_A_PIN_TYPE, prop->type))
  576. return -EMSGSIZE;
  577. if (nla_put_u32(msg, DPLL_A_PIN_CAPABILITIES, prop->capabilities))
  578. return -EMSGSIZE;
  579. ret = dpll_msg_add_pin_freq(msg, pin, ref, extack);
  580. if (ret)
  581. return ret;
  582. if (prop->phase_gran &&
  583. nla_put_u32(msg, DPLL_A_PIN_PHASE_ADJUST_GRAN,
  584. prop->phase_gran))
  585. return -EMSGSIZE;
  586. if (nla_put_s32(msg, DPLL_A_PIN_PHASE_ADJUST_MIN,
  587. prop->phase_range.min))
  588. return -EMSGSIZE;
  589. if (nla_put_s32(msg, DPLL_A_PIN_PHASE_ADJUST_MAX,
  590. prop->phase_range.max))
  591. return -EMSGSIZE;
  592. ret = dpll_msg_add_pin_phase_adjust(msg, pin, ref, extack);
  593. if (ret)
  594. return ret;
  595. ret = dpll_msg_add_ffo(msg, pin, ref, extack);
  596. if (ret)
  597. return ret;
  598. ret = dpll_msg_add_pin_esync(msg, pin, ref, extack);
  599. if (ret)
  600. return ret;
  601. if (!xa_empty(&pin->ref_sync_pins))
  602. ret = dpll_msg_add_pin_ref_sync(msg, pin, ref, extack);
  603. if (ret)
  604. return ret;
  605. if (xa_empty(&pin->parent_refs))
  606. ret = dpll_msg_add_pin_dplls(msg, pin, extack);
  607. else
  608. ret = dpll_msg_add_pin_parents(msg, pin, ref, extack);
  609. return ret;
  610. }
  611. static int
  612. dpll_device_get_one(struct dpll_device *dpll, struct sk_buff *msg,
  613. struct netlink_ext_ack *extack)
  614. {
  615. int ret;
  616. ret = dpll_msg_add_dev_handle(msg, dpll);
  617. if (ret)
  618. return ret;
  619. if (nla_put_string(msg, DPLL_A_MODULE_NAME, module_name(dpll->module)))
  620. return -EMSGSIZE;
  621. if (nla_put_64bit(msg, DPLL_A_CLOCK_ID, sizeof(dpll->clock_id),
  622. &dpll->clock_id, DPLL_A_PAD))
  623. return -EMSGSIZE;
  624. ret = dpll_msg_add_temp(msg, dpll, extack);
  625. if (ret)
  626. return ret;
  627. ret = dpll_msg_add_lock_status(msg, dpll, extack);
  628. if (ret)
  629. return ret;
  630. ret = dpll_msg_add_clock_quality_level(msg, dpll, extack);
  631. if (ret)
  632. return ret;
  633. ret = dpll_msg_add_mode(msg, dpll, extack);
  634. if (ret)
  635. return ret;
  636. ret = dpll_msg_add_mode_supported(msg, dpll, extack);
  637. if (ret)
  638. return ret;
  639. if (nla_put_u32(msg, DPLL_A_TYPE, dpll->type))
  640. return -EMSGSIZE;
  641. ret = dpll_msg_add_phase_offset_monitor(msg, dpll, extack);
  642. if (ret)
  643. return ret;
  644. ret = dpll_msg_add_phase_offset_avg_factor(msg, dpll, extack);
  645. if (ret)
  646. return ret;
  647. return 0;
  648. }
  649. static int
  650. dpll_device_event_send(enum dpll_cmd event, struct dpll_device *dpll)
  651. {
  652. struct sk_buff *msg;
  653. int ret = -ENOMEM;
  654. void *hdr;
  655. if (WARN_ON(!xa_get_mark(&dpll_device_xa, dpll->id, DPLL_REGISTERED)))
  656. return -ENODEV;
  657. msg = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
  658. if (!msg)
  659. return -ENOMEM;
  660. hdr = genlmsg_put(msg, 0, 0, &dpll_nl_family, 0, event);
  661. if (!hdr)
  662. goto err_free_msg;
  663. ret = dpll_device_get_one(dpll, msg, NULL);
  664. if (ret)
  665. goto err_cancel_msg;
  666. genlmsg_end(msg, hdr);
  667. genlmsg_multicast(&dpll_nl_family, msg, 0, 0, GFP_KERNEL);
  668. return 0;
  669. err_cancel_msg:
  670. genlmsg_cancel(msg, hdr);
  671. err_free_msg:
  672. nlmsg_free(msg);
  673. return ret;
  674. }
  675. int dpll_device_create_ntf(struct dpll_device *dpll)
  676. {
  677. dpll_device_notify(dpll, DPLL_DEVICE_CREATED);
  678. return dpll_device_event_send(DPLL_CMD_DEVICE_CREATE_NTF, dpll);
  679. }
  680. int dpll_device_delete_ntf(struct dpll_device *dpll)
  681. {
  682. dpll_device_notify(dpll, DPLL_DEVICE_DELETED);
  683. return dpll_device_event_send(DPLL_CMD_DEVICE_DELETE_NTF, dpll);
  684. }
  685. static int
  686. __dpll_device_change_ntf(struct dpll_device *dpll)
  687. {
  688. dpll_device_notify(dpll, DPLL_DEVICE_CHANGED);
  689. return dpll_device_event_send(DPLL_CMD_DEVICE_CHANGE_NTF, dpll);
  690. }
  691. /**
  692. * dpll_device_change_ntf - notify that the dpll device has been changed
  693. * @dpll: registered dpll pointer
  694. *
  695. * Context: acquires and holds a dpll_lock.
  696. * Return: 0 if succeeds, error code otherwise.
  697. */
  698. int dpll_device_change_ntf(struct dpll_device *dpll)
  699. {
  700. int ret;
  701. mutex_lock(&dpll_lock);
  702. ret = __dpll_device_change_ntf(dpll);
  703. mutex_unlock(&dpll_lock);
  704. return ret;
  705. }
  706. EXPORT_SYMBOL_GPL(dpll_device_change_ntf);
  707. static int
  708. dpll_pin_event_send(enum dpll_cmd event, struct dpll_pin *pin)
  709. {
  710. struct sk_buff *msg;
  711. int ret = -ENOMEM;
  712. void *hdr;
  713. if (!dpll_pin_available(pin))
  714. return -ENODEV;
  715. msg = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
  716. if (!msg)
  717. return -ENOMEM;
  718. hdr = genlmsg_put(msg, 0, 0, &dpll_nl_family, 0, event);
  719. if (!hdr)
  720. goto err_free_msg;
  721. ret = dpll_cmd_pin_get_one(msg, pin, NULL);
  722. if (ret)
  723. goto err_cancel_msg;
  724. genlmsg_end(msg, hdr);
  725. genlmsg_multicast(&dpll_nl_family, msg, 0, 0, GFP_KERNEL);
  726. return 0;
  727. err_cancel_msg:
  728. genlmsg_cancel(msg, hdr);
  729. err_free_msg:
  730. nlmsg_free(msg);
  731. return ret;
  732. }
  733. int dpll_pin_create_ntf(struct dpll_pin *pin)
  734. {
  735. dpll_pin_notify(pin, DPLL_PIN_CREATED);
  736. return dpll_pin_event_send(DPLL_CMD_PIN_CREATE_NTF, pin);
  737. }
  738. int dpll_pin_delete_ntf(struct dpll_pin *pin)
  739. {
  740. dpll_pin_notify(pin, DPLL_PIN_DELETED);
  741. return dpll_pin_event_send(DPLL_CMD_PIN_DELETE_NTF, pin);
  742. }
  743. int __dpll_pin_change_ntf(struct dpll_pin *pin)
  744. {
  745. dpll_pin_notify(pin, DPLL_PIN_CHANGED);
  746. return dpll_pin_event_send(DPLL_CMD_PIN_CHANGE_NTF, pin);
  747. }
  748. /**
  749. * dpll_pin_change_ntf - notify that the pin has been changed
  750. * @pin: registered pin pointer
  751. *
  752. * Context: acquires and holds a dpll_lock.
  753. * Return: 0 if succeeds, error code otherwise.
  754. */
  755. int dpll_pin_change_ntf(struct dpll_pin *pin)
  756. {
  757. int ret;
  758. mutex_lock(&dpll_lock);
  759. ret = __dpll_pin_change_ntf(pin);
  760. mutex_unlock(&dpll_lock);
  761. return ret;
  762. }
  763. EXPORT_SYMBOL_GPL(dpll_pin_change_ntf);
  764. static int
  765. dpll_mode_set(struct dpll_device *dpll, struct nlattr *a,
  766. struct netlink_ext_ack *extack)
  767. {
  768. const struct dpll_device_ops *ops = dpll_device_ops(dpll);
  769. DECLARE_BITMAP(modes, DPLL_MODE_MAX + 1) = { 0 };
  770. enum dpll_mode mode = nla_get_u32(a), old_mode;
  771. int ret;
  772. if (!(ops->mode_set && ops->supported_modes_get)) {
  773. NL_SET_ERR_MSG_ATTR(extack, a,
  774. "dpll device does not support mode switch");
  775. return -EOPNOTSUPP;
  776. }
  777. ret = ops->mode_get(dpll, dpll_priv(dpll), &old_mode, extack);
  778. if (ret) {
  779. NL_SET_ERR_MSG(extack, "unable to get current mode");
  780. return ret;
  781. }
  782. if (mode == old_mode)
  783. return 0;
  784. ret = ops->supported_modes_get(dpll, dpll_priv(dpll), modes, extack);
  785. if (ret) {
  786. NL_SET_ERR_MSG(extack, "unable to get supported modes");
  787. return ret;
  788. }
  789. if (!test_bit(mode, modes)) {
  790. NL_SET_ERR_MSG(extack,
  791. "dpll device does not support requested mode");
  792. return -EINVAL;
  793. }
  794. return ops->mode_set(dpll, dpll_priv(dpll), mode, extack);
  795. }
  796. static int
  797. dpll_phase_offset_monitor_set(struct dpll_device *dpll, struct nlattr *a,
  798. struct netlink_ext_ack *extack)
  799. {
  800. const struct dpll_device_ops *ops = dpll_device_ops(dpll);
  801. enum dpll_feature_state state = nla_get_u32(a), old_state;
  802. int ret;
  803. if (!(ops->phase_offset_monitor_set && ops->phase_offset_monitor_get)) {
  804. NL_SET_ERR_MSG_ATTR(extack, a, "dpll device not capable of phase offset monitor");
  805. return -EOPNOTSUPP;
  806. }
  807. ret = ops->phase_offset_monitor_get(dpll, dpll_priv(dpll), &old_state,
  808. extack);
  809. if (ret) {
  810. NL_SET_ERR_MSG(extack, "unable to get current state of phase offset monitor");
  811. return ret;
  812. }
  813. if (state == old_state)
  814. return 0;
  815. return ops->phase_offset_monitor_set(dpll, dpll_priv(dpll), state,
  816. extack);
  817. }
  818. static int
  819. dpll_phase_offset_avg_factor_set(struct dpll_device *dpll, struct nlattr *a,
  820. struct netlink_ext_ack *extack)
  821. {
  822. const struct dpll_device_ops *ops = dpll_device_ops(dpll);
  823. u32 factor = nla_get_u32(a);
  824. if (!ops->phase_offset_avg_factor_set) {
  825. NL_SET_ERR_MSG_ATTR(extack, a,
  826. "device not capable of changing phase offset average factor");
  827. return -EOPNOTSUPP;
  828. }
  829. return ops->phase_offset_avg_factor_set(dpll, dpll_priv(dpll), factor,
  830. extack);
  831. }
  832. static int
  833. dpll_pin_freq_set(struct dpll_pin *pin, struct nlattr *a,
  834. struct netlink_ext_ack *extack)
  835. {
  836. u64 freq = nla_get_u64(a), old_freq;
  837. struct dpll_pin_ref *ref, *failed;
  838. const struct dpll_pin_ops *ops;
  839. struct dpll_device *dpll;
  840. unsigned long i;
  841. int ret;
  842. if (!dpll_pin_is_freq_supported(pin, freq)) {
  843. NL_SET_ERR_MSG_ATTR(extack, a, "frequency is not supported by the device");
  844. return -EINVAL;
  845. }
  846. xa_for_each(&pin->dpll_refs, i, ref) {
  847. ops = dpll_pin_ops(ref);
  848. if (!ops->frequency_set || !ops->frequency_get) {
  849. NL_SET_ERR_MSG(extack, "frequency set not supported by the device");
  850. return -EOPNOTSUPP;
  851. }
  852. }
  853. ref = dpll_xa_ref_dpll_first(&pin->dpll_refs);
  854. ops = dpll_pin_ops(ref);
  855. dpll = ref->dpll;
  856. ret = ops->frequency_get(pin, dpll_pin_on_dpll_priv(dpll, pin), dpll,
  857. dpll_priv(dpll), &old_freq, extack);
  858. if (ret) {
  859. NL_SET_ERR_MSG(extack, "unable to get old frequency value");
  860. return ret;
  861. }
  862. if (freq == old_freq)
  863. return 0;
  864. xa_for_each(&pin->dpll_refs, i, ref) {
  865. ops = dpll_pin_ops(ref);
  866. dpll = ref->dpll;
  867. ret = ops->frequency_set(pin, dpll_pin_on_dpll_priv(dpll, pin),
  868. dpll, dpll_priv(dpll), freq, extack);
  869. if (ret) {
  870. failed = ref;
  871. NL_SET_ERR_MSG_FMT(extack, "frequency set failed for dpll_id:%u",
  872. dpll->id);
  873. goto rollback;
  874. }
  875. }
  876. __dpll_pin_change_ntf(pin);
  877. return 0;
  878. rollback:
  879. xa_for_each(&pin->dpll_refs, i, ref) {
  880. if (ref == failed)
  881. break;
  882. ops = dpll_pin_ops(ref);
  883. dpll = ref->dpll;
  884. if (ops->frequency_set(pin, dpll_pin_on_dpll_priv(dpll, pin),
  885. dpll, dpll_priv(dpll), old_freq, extack))
  886. NL_SET_ERR_MSG(extack, "set frequency rollback failed");
  887. }
  888. return ret;
  889. }
  890. static int
  891. dpll_pin_esync_set(struct dpll_pin *pin, struct nlattr *a,
  892. struct netlink_ext_ack *extack)
  893. {
  894. struct dpll_pin_ref *ref, *failed;
  895. const struct dpll_pin_ops *ops;
  896. struct dpll_pin_esync esync;
  897. u64 freq = nla_get_u64(a);
  898. struct dpll_device *dpll;
  899. bool supported = false;
  900. unsigned long i;
  901. int ret;
  902. xa_for_each(&pin->dpll_refs, i, ref) {
  903. ops = dpll_pin_ops(ref);
  904. if (!ops->esync_set || !ops->esync_get) {
  905. NL_SET_ERR_MSG(extack,
  906. "embedded sync feature is not supported by this device");
  907. return -EOPNOTSUPP;
  908. }
  909. }
  910. ref = dpll_xa_ref_dpll_first(&pin->dpll_refs);
  911. ops = dpll_pin_ops(ref);
  912. dpll = ref->dpll;
  913. ret = ops->esync_get(pin, dpll_pin_on_dpll_priv(dpll, pin), dpll,
  914. dpll_priv(dpll), &esync, extack);
  915. if (ret) {
  916. NL_SET_ERR_MSG(extack, "unable to get current embedded sync frequency value");
  917. return ret;
  918. }
  919. if (freq == esync.freq)
  920. return 0;
  921. for (i = 0; i < esync.range_num; i++)
  922. if (freq <= esync.range[i].max && freq >= esync.range[i].min)
  923. supported = true;
  924. if (!supported) {
  925. NL_SET_ERR_MSG_ATTR(extack, a,
  926. "requested embedded sync frequency value is not supported by this device");
  927. return -EINVAL;
  928. }
  929. xa_for_each(&pin->dpll_refs, i, ref) {
  930. void *pin_dpll_priv;
  931. ops = dpll_pin_ops(ref);
  932. dpll = ref->dpll;
  933. pin_dpll_priv = dpll_pin_on_dpll_priv(dpll, pin);
  934. ret = ops->esync_set(pin, pin_dpll_priv, dpll, dpll_priv(dpll),
  935. freq, extack);
  936. if (ret) {
  937. failed = ref;
  938. NL_SET_ERR_MSG_FMT(extack,
  939. "embedded sync frequency set failed for dpll_id: %u",
  940. dpll->id);
  941. goto rollback;
  942. }
  943. }
  944. __dpll_pin_change_ntf(pin);
  945. return 0;
  946. rollback:
  947. xa_for_each(&pin->dpll_refs, i, ref) {
  948. void *pin_dpll_priv;
  949. if (ref == failed)
  950. break;
  951. ops = dpll_pin_ops(ref);
  952. dpll = ref->dpll;
  953. pin_dpll_priv = dpll_pin_on_dpll_priv(dpll, pin);
  954. if (ops->esync_set(pin, pin_dpll_priv, dpll, dpll_priv(dpll),
  955. esync.freq, extack))
  956. NL_SET_ERR_MSG(extack, "set embedded sync frequency rollback failed");
  957. }
  958. return ret;
  959. }
  960. static int
  961. dpll_pin_ref_sync_state_set(struct dpll_pin *pin,
  962. unsigned long ref_sync_pin_idx,
  963. const enum dpll_pin_state state,
  964. struct netlink_ext_ack *extack)
  965. {
  966. struct dpll_pin_ref *ref, *failed;
  967. const struct dpll_pin_ops *ops;
  968. enum dpll_pin_state old_state;
  969. struct dpll_pin *ref_sync_pin;
  970. struct dpll_device *dpll;
  971. unsigned long i;
  972. int ret;
  973. ref_sync_pin = xa_find(&pin->ref_sync_pins, &ref_sync_pin_idx,
  974. ULONG_MAX, XA_PRESENT);
  975. if (!ref_sync_pin) {
  976. NL_SET_ERR_MSG(extack, "reference sync pin not found");
  977. return -EINVAL;
  978. }
  979. if (!dpll_pin_available(ref_sync_pin)) {
  980. NL_SET_ERR_MSG(extack, "reference sync pin not available");
  981. return -EINVAL;
  982. }
  983. ref = dpll_xa_ref_dpll_first(&pin->dpll_refs);
  984. ASSERT_NOT_NULL(ref);
  985. ops = dpll_pin_ops(ref);
  986. if (!ops->ref_sync_set || !ops->ref_sync_get) {
  987. NL_SET_ERR_MSG(extack, "reference sync not supported by this pin");
  988. return -EOPNOTSUPP;
  989. }
  990. dpll = ref->dpll;
  991. ret = ops->ref_sync_get(pin, dpll_pin_on_dpll_priv(dpll, pin),
  992. ref_sync_pin,
  993. dpll_pin_on_dpll_priv(dpll, ref_sync_pin),
  994. &old_state, extack);
  995. if (ret) {
  996. NL_SET_ERR_MSG(extack, "unable to get old reference sync state");
  997. return ret;
  998. }
  999. if (state == old_state)
  1000. return 0;
  1001. xa_for_each(&pin->dpll_refs, i, ref) {
  1002. ops = dpll_pin_ops(ref);
  1003. dpll = ref->dpll;
  1004. ret = ops->ref_sync_set(pin, dpll_pin_on_dpll_priv(dpll, pin),
  1005. ref_sync_pin,
  1006. dpll_pin_on_dpll_priv(dpll,
  1007. ref_sync_pin),
  1008. state, extack);
  1009. if (ret) {
  1010. failed = ref;
  1011. NL_SET_ERR_MSG_FMT(extack, "reference sync set failed for dpll_id:%u",
  1012. dpll->id);
  1013. goto rollback;
  1014. }
  1015. }
  1016. __dpll_pin_change_ntf(pin);
  1017. return 0;
  1018. rollback:
  1019. xa_for_each(&pin->dpll_refs, i, ref) {
  1020. if (ref == failed)
  1021. break;
  1022. ops = dpll_pin_ops(ref);
  1023. dpll = ref->dpll;
  1024. if (ops->ref_sync_set(pin, dpll_pin_on_dpll_priv(dpll, pin),
  1025. ref_sync_pin,
  1026. dpll_pin_on_dpll_priv(dpll, ref_sync_pin),
  1027. old_state, extack))
  1028. NL_SET_ERR_MSG(extack, "set reference sync rollback failed");
  1029. }
  1030. return ret;
  1031. }
  1032. static int
  1033. dpll_pin_ref_sync_set(struct dpll_pin *pin, struct nlattr *nest,
  1034. struct netlink_ext_ack *extack)
  1035. {
  1036. struct nlattr *tb[DPLL_A_PIN_MAX + 1];
  1037. enum dpll_pin_state state;
  1038. u32 sync_pin_id;
  1039. nla_parse_nested(tb, DPLL_A_PIN_MAX, nest,
  1040. dpll_reference_sync_nl_policy, extack);
  1041. if (!tb[DPLL_A_PIN_ID]) {
  1042. NL_SET_ERR_MSG(extack, "sync pin id expected");
  1043. return -EINVAL;
  1044. }
  1045. sync_pin_id = nla_get_u32(tb[DPLL_A_PIN_ID]);
  1046. if (!tb[DPLL_A_PIN_STATE]) {
  1047. NL_SET_ERR_MSG(extack, "sync pin state expected");
  1048. return -EINVAL;
  1049. }
  1050. state = nla_get_u32(tb[DPLL_A_PIN_STATE]);
  1051. return dpll_pin_ref_sync_state_set(pin, sync_pin_id, state, extack);
  1052. }
  1053. static int
  1054. dpll_pin_on_pin_state_set(struct dpll_pin *pin, u32 parent_idx,
  1055. enum dpll_pin_state state,
  1056. struct netlink_ext_ack *extack)
  1057. {
  1058. struct dpll_pin_ref *parent_ref;
  1059. const struct dpll_pin_ops *ops;
  1060. struct dpll_pin_ref *dpll_ref;
  1061. void *pin_priv, *parent_priv;
  1062. struct dpll_pin *parent;
  1063. unsigned long i;
  1064. int ret;
  1065. if (!(DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE &
  1066. pin->prop.capabilities)) {
  1067. NL_SET_ERR_MSG(extack, "state changing is not allowed");
  1068. return -EOPNOTSUPP;
  1069. }
  1070. parent = xa_load(&dpll_pin_xa, parent_idx);
  1071. if (!parent)
  1072. return -EINVAL;
  1073. parent_ref = xa_load(&pin->parent_refs, parent->pin_idx);
  1074. if (!parent_ref)
  1075. return -EINVAL;
  1076. xa_for_each(&parent->dpll_refs, i, dpll_ref) {
  1077. ops = dpll_pin_ops(parent_ref);
  1078. if (!ops->state_on_pin_set)
  1079. return -EOPNOTSUPP;
  1080. pin_priv = dpll_pin_on_pin_priv(parent, pin);
  1081. parent_priv = dpll_pin_on_dpll_priv(dpll_ref->dpll, parent);
  1082. ret = ops->state_on_pin_set(pin, pin_priv, parent, parent_priv,
  1083. state, extack);
  1084. if (ret)
  1085. return ret;
  1086. }
  1087. __dpll_pin_change_ntf(pin);
  1088. return 0;
  1089. }
  1090. static int
  1091. dpll_pin_state_set(struct dpll_device *dpll, struct dpll_pin *pin,
  1092. enum dpll_pin_state state,
  1093. struct netlink_ext_ack *extack)
  1094. {
  1095. const struct dpll_pin_ops *ops;
  1096. struct dpll_pin_ref *ref;
  1097. int ret;
  1098. if (!(DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE &
  1099. pin->prop.capabilities)) {
  1100. NL_SET_ERR_MSG(extack, "state changing is not allowed");
  1101. return -EOPNOTSUPP;
  1102. }
  1103. ref = xa_load(&pin->dpll_refs, dpll->id);
  1104. ASSERT_NOT_NULL(ref);
  1105. ops = dpll_pin_ops(ref);
  1106. if (!ops->state_on_dpll_set)
  1107. return -EOPNOTSUPP;
  1108. ret = ops->state_on_dpll_set(pin, dpll_pin_on_dpll_priv(dpll, pin),
  1109. dpll, dpll_priv(dpll), state, extack);
  1110. if (ret)
  1111. return ret;
  1112. __dpll_pin_change_ntf(pin);
  1113. return 0;
  1114. }
  1115. static int
  1116. dpll_pin_prio_set(struct dpll_device *dpll, struct dpll_pin *pin,
  1117. u32 prio, struct netlink_ext_ack *extack)
  1118. {
  1119. const struct dpll_pin_ops *ops;
  1120. struct dpll_pin_ref *ref;
  1121. int ret;
  1122. if (!(DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE &
  1123. pin->prop.capabilities)) {
  1124. NL_SET_ERR_MSG(extack, "prio changing is not allowed");
  1125. return -EOPNOTSUPP;
  1126. }
  1127. ref = xa_load(&pin->dpll_refs, dpll->id);
  1128. ASSERT_NOT_NULL(ref);
  1129. ops = dpll_pin_ops(ref);
  1130. if (!ops->prio_set)
  1131. return -EOPNOTSUPP;
  1132. ret = ops->prio_set(pin, dpll_pin_on_dpll_priv(dpll, pin), dpll,
  1133. dpll_priv(dpll), prio, extack);
  1134. if (ret)
  1135. return ret;
  1136. __dpll_pin_change_ntf(pin);
  1137. return 0;
  1138. }
  1139. static int
  1140. dpll_pin_direction_set(struct dpll_pin *pin, struct dpll_device *dpll,
  1141. enum dpll_pin_direction direction,
  1142. struct netlink_ext_ack *extack)
  1143. {
  1144. const struct dpll_pin_ops *ops;
  1145. struct dpll_pin_ref *ref;
  1146. int ret;
  1147. if (!(DPLL_PIN_CAPABILITIES_DIRECTION_CAN_CHANGE &
  1148. pin->prop.capabilities)) {
  1149. NL_SET_ERR_MSG(extack, "direction changing is not allowed");
  1150. return -EOPNOTSUPP;
  1151. }
  1152. ref = xa_load(&pin->dpll_refs, dpll->id);
  1153. ASSERT_NOT_NULL(ref);
  1154. ops = dpll_pin_ops(ref);
  1155. if (!ops->direction_set)
  1156. return -EOPNOTSUPP;
  1157. ret = ops->direction_set(pin, dpll_pin_on_dpll_priv(dpll, pin),
  1158. dpll, dpll_priv(dpll), direction, extack);
  1159. if (ret)
  1160. return ret;
  1161. __dpll_pin_change_ntf(pin);
  1162. return 0;
  1163. }
  1164. static int
  1165. dpll_pin_phase_adj_set(struct dpll_pin *pin, struct nlattr *phase_adj_attr,
  1166. struct netlink_ext_ack *extack)
  1167. {
  1168. struct dpll_pin_ref *ref, *failed;
  1169. const struct dpll_pin_ops *ops;
  1170. s32 phase_adj, old_phase_adj;
  1171. struct dpll_device *dpll;
  1172. unsigned long i;
  1173. int ret;
  1174. phase_adj = nla_get_s32(phase_adj_attr);
  1175. if (phase_adj > pin->prop.phase_range.max ||
  1176. phase_adj < pin->prop.phase_range.min) {
  1177. NL_SET_ERR_MSG_ATTR(extack, phase_adj_attr,
  1178. "phase adjust value of out range");
  1179. return -EINVAL;
  1180. }
  1181. if (pin->prop.phase_gran && phase_adj % (s32)pin->prop.phase_gran) {
  1182. NL_SET_ERR_MSG_ATTR_FMT(extack, phase_adj_attr,
  1183. "phase adjust value not multiple of %u",
  1184. pin->prop.phase_gran);
  1185. return -EINVAL;
  1186. }
  1187. xa_for_each(&pin->dpll_refs, i, ref) {
  1188. ops = dpll_pin_ops(ref);
  1189. if (!ops->phase_adjust_set || !ops->phase_adjust_get) {
  1190. NL_SET_ERR_MSG(extack, "phase adjust not supported");
  1191. return -EOPNOTSUPP;
  1192. }
  1193. }
  1194. ref = dpll_xa_ref_dpll_first(&pin->dpll_refs);
  1195. ops = dpll_pin_ops(ref);
  1196. dpll = ref->dpll;
  1197. ret = ops->phase_adjust_get(pin, dpll_pin_on_dpll_priv(dpll, pin),
  1198. dpll, dpll_priv(dpll), &old_phase_adj,
  1199. extack);
  1200. if (ret) {
  1201. NL_SET_ERR_MSG(extack, "unable to get old phase adjust value");
  1202. return ret;
  1203. }
  1204. if (phase_adj == old_phase_adj)
  1205. return 0;
  1206. xa_for_each(&pin->dpll_refs, i, ref) {
  1207. ops = dpll_pin_ops(ref);
  1208. dpll = ref->dpll;
  1209. ret = ops->phase_adjust_set(pin,
  1210. dpll_pin_on_dpll_priv(dpll, pin),
  1211. dpll, dpll_priv(dpll), phase_adj,
  1212. extack);
  1213. if (ret) {
  1214. failed = ref;
  1215. NL_SET_ERR_MSG_FMT(extack,
  1216. "phase adjust set failed for dpll_id:%u",
  1217. dpll->id);
  1218. goto rollback;
  1219. }
  1220. }
  1221. __dpll_pin_change_ntf(pin);
  1222. return 0;
  1223. rollback:
  1224. xa_for_each(&pin->dpll_refs, i, ref) {
  1225. if (ref == failed)
  1226. break;
  1227. ops = dpll_pin_ops(ref);
  1228. dpll = ref->dpll;
  1229. if (ops->phase_adjust_set(pin, dpll_pin_on_dpll_priv(dpll, pin),
  1230. dpll, dpll_priv(dpll), old_phase_adj,
  1231. extack))
  1232. NL_SET_ERR_MSG(extack, "set phase adjust rollback failed");
  1233. }
  1234. return ret;
  1235. }
  1236. static int
  1237. dpll_pin_parent_device_set(struct dpll_pin *pin, struct nlattr *parent_nest,
  1238. struct netlink_ext_ack *extack)
  1239. {
  1240. struct nlattr *tb[DPLL_A_PIN_MAX + 1];
  1241. enum dpll_pin_direction direction;
  1242. enum dpll_pin_state state;
  1243. struct dpll_pin_ref *ref;
  1244. struct dpll_device *dpll;
  1245. u32 pdpll_idx, prio;
  1246. int ret;
  1247. nla_parse_nested(tb, DPLL_A_PIN_MAX, parent_nest,
  1248. dpll_pin_parent_device_nl_policy, extack);
  1249. if (!tb[DPLL_A_PIN_PARENT_ID]) {
  1250. NL_SET_ERR_MSG(extack, "device parent id expected");
  1251. return -EINVAL;
  1252. }
  1253. pdpll_idx = nla_get_u32(tb[DPLL_A_PIN_PARENT_ID]);
  1254. dpll = xa_load(&dpll_device_xa, pdpll_idx);
  1255. if (!dpll) {
  1256. NL_SET_ERR_MSG(extack, "parent device not found");
  1257. return -EINVAL;
  1258. }
  1259. ref = xa_load(&pin->dpll_refs, dpll->id);
  1260. if (!ref) {
  1261. NL_SET_ERR_MSG(extack, "pin not connected to given parent device");
  1262. return -EINVAL;
  1263. }
  1264. if (tb[DPLL_A_PIN_STATE]) {
  1265. state = nla_get_u32(tb[DPLL_A_PIN_STATE]);
  1266. ret = dpll_pin_state_set(dpll, pin, state, extack);
  1267. if (ret)
  1268. return ret;
  1269. }
  1270. if (tb[DPLL_A_PIN_PRIO]) {
  1271. prio = nla_get_u32(tb[DPLL_A_PIN_PRIO]);
  1272. ret = dpll_pin_prio_set(dpll, pin, prio, extack);
  1273. if (ret)
  1274. return ret;
  1275. }
  1276. if (tb[DPLL_A_PIN_DIRECTION]) {
  1277. direction = nla_get_u32(tb[DPLL_A_PIN_DIRECTION]);
  1278. ret = dpll_pin_direction_set(pin, dpll, direction, extack);
  1279. if (ret)
  1280. return ret;
  1281. }
  1282. return 0;
  1283. }
  1284. static int
  1285. dpll_pin_parent_pin_set(struct dpll_pin *pin, struct nlattr *parent_nest,
  1286. struct netlink_ext_ack *extack)
  1287. {
  1288. struct nlattr *tb[DPLL_A_PIN_MAX + 1];
  1289. u32 ppin_idx;
  1290. int ret;
  1291. nla_parse_nested(tb, DPLL_A_PIN_MAX, parent_nest,
  1292. dpll_pin_parent_pin_nl_policy, extack);
  1293. if (!tb[DPLL_A_PIN_PARENT_ID]) {
  1294. NL_SET_ERR_MSG(extack, "device parent id expected");
  1295. return -EINVAL;
  1296. }
  1297. ppin_idx = nla_get_u32(tb[DPLL_A_PIN_PARENT_ID]);
  1298. if (tb[DPLL_A_PIN_STATE]) {
  1299. enum dpll_pin_state state = nla_get_u32(tb[DPLL_A_PIN_STATE]);
  1300. ret = dpll_pin_on_pin_state_set(pin, ppin_idx, state, extack);
  1301. if (ret)
  1302. return ret;
  1303. }
  1304. return 0;
  1305. }
  1306. static int
  1307. dpll_pin_set_from_nlattr(struct dpll_pin *pin, struct genl_info *info)
  1308. {
  1309. struct nlattr *a;
  1310. int rem, ret;
  1311. nla_for_each_attr(a, genlmsg_data(info->genlhdr),
  1312. genlmsg_len(info->genlhdr), rem) {
  1313. switch (nla_type(a)) {
  1314. case DPLL_A_PIN_FREQUENCY:
  1315. ret = dpll_pin_freq_set(pin, a, info->extack);
  1316. if (ret)
  1317. return ret;
  1318. break;
  1319. case DPLL_A_PIN_PHASE_ADJUST:
  1320. ret = dpll_pin_phase_adj_set(pin, a, info->extack);
  1321. if (ret)
  1322. return ret;
  1323. break;
  1324. case DPLL_A_PIN_PARENT_DEVICE:
  1325. ret = dpll_pin_parent_device_set(pin, a, info->extack);
  1326. if (ret)
  1327. return ret;
  1328. break;
  1329. case DPLL_A_PIN_PARENT_PIN:
  1330. ret = dpll_pin_parent_pin_set(pin, a, info->extack);
  1331. if (ret)
  1332. return ret;
  1333. break;
  1334. case DPLL_A_PIN_ESYNC_FREQUENCY:
  1335. ret = dpll_pin_esync_set(pin, a, info->extack);
  1336. if (ret)
  1337. return ret;
  1338. break;
  1339. case DPLL_A_PIN_REFERENCE_SYNC:
  1340. ret = dpll_pin_ref_sync_set(pin, a, info->extack);
  1341. if (ret)
  1342. return ret;
  1343. break;
  1344. }
  1345. }
  1346. return 0;
  1347. }
  1348. static struct dpll_pin *
  1349. dpll_pin_find(u64 clock_id, struct nlattr *mod_name_attr,
  1350. enum dpll_pin_type type, struct nlattr *board_label,
  1351. struct nlattr *panel_label, struct nlattr *package_label,
  1352. struct netlink_ext_ack *extack)
  1353. {
  1354. bool board_match, panel_match, package_match;
  1355. struct dpll_pin *pin_match = NULL, *pin;
  1356. const struct dpll_pin_properties *prop;
  1357. bool cid_match, mod_match, type_match;
  1358. unsigned long i;
  1359. xa_for_each_marked(&dpll_pin_xa, i, pin, DPLL_REGISTERED) {
  1360. prop = &pin->prop;
  1361. cid_match = clock_id ? pin->clock_id == clock_id : true;
  1362. mod_match = mod_name_attr && module_name(pin->module) ?
  1363. !nla_strcmp(mod_name_attr,
  1364. module_name(pin->module)) : true;
  1365. type_match = type ? prop->type == type : true;
  1366. board_match = board_label ? (prop->board_label ?
  1367. !nla_strcmp(board_label, prop->board_label) : false) :
  1368. true;
  1369. panel_match = panel_label ? (prop->panel_label ?
  1370. !nla_strcmp(panel_label, prop->panel_label) : false) :
  1371. true;
  1372. package_match = package_label ? (prop->package_label ?
  1373. !nla_strcmp(package_label, prop->package_label) :
  1374. false) : true;
  1375. if (cid_match && mod_match && type_match && board_match &&
  1376. panel_match && package_match) {
  1377. if (pin_match) {
  1378. NL_SET_ERR_MSG(extack, "multiple matches");
  1379. return ERR_PTR(-EINVAL);
  1380. }
  1381. pin_match = pin;
  1382. }
  1383. }
  1384. if (!pin_match) {
  1385. NL_SET_ERR_MSG(extack, "not found");
  1386. return ERR_PTR(-ENODEV);
  1387. }
  1388. return pin_match;
  1389. }
  1390. static struct dpll_pin *dpll_pin_find_from_nlattr(struct genl_info *info)
  1391. {
  1392. struct nlattr *attr, *mod_name_attr = NULL, *board_label_attr = NULL,
  1393. *panel_label_attr = NULL, *package_label_attr = NULL;
  1394. enum dpll_pin_type type = 0;
  1395. u64 clock_id = 0;
  1396. int rem = 0;
  1397. nla_for_each_attr(attr, genlmsg_data(info->genlhdr),
  1398. genlmsg_len(info->genlhdr), rem) {
  1399. switch (nla_type(attr)) {
  1400. case DPLL_A_PIN_CLOCK_ID:
  1401. if (clock_id)
  1402. goto duplicated_attr;
  1403. clock_id = nla_get_u64(attr);
  1404. break;
  1405. case DPLL_A_PIN_MODULE_NAME:
  1406. if (mod_name_attr)
  1407. goto duplicated_attr;
  1408. mod_name_attr = attr;
  1409. break;
  1410. case DPLL_A_PIN_TYPE:
  1411. if (type)
  1412. goto duplicated_attr;
  1413. type = nla_get_u32(attr);
  1414. break;
  1415. case DPLL_A_PIN_BOARD_LABEL:
  1416. if (board_label_attr)
  1417. goto duplicated_attr;
  1418. board_label_attr = attr;
  1419. break;
  1420. case DPLL_A_PIN_PANEL_LABEL:
  1421. if (panel_label_attr)
  1422. goto duplicated_attr;
  1423. panel_label_attr = attr;
  1424. break;
  1425. case DPLL_A_PIN_PACKAGE_LABEL:
  1426. if (package_label_attr)
  1427. goto duplicated_attr;
  1428. package_label_attr = attr;
  1429. break;
  1430. default:
  1431. break;
  1432. }
  1433. }
  1434. if (!(clock_id || mod_name_attr || board_label_attr ||
  1435. panel_label_attr || package_label_attr)) {
  1436. NL_SET_ERR_MSG(info->extack, "missing attributes");
  1437. return ERR_PTR(-EINVAL);
  1438. }
  1439. return dpll_pin_find(clock_id, mod_name_attr, type, board_label_attr,
  1440. panel_label_attr, package_label_attr,
  1441. info->extack);
  1442. duplicated_attr:
  1443. NL_SET_ERR_MSG(info->extack, "duplicated attribute");
  1444. return ERR_PTR(-EINVAL);
  1445. }
  1446. int dpll_nl_pin_id_get_doit(struct sk_buff *skb, struct genl_info *info)
  1447. {
  1448. struct dpll_pin *pin;
  1449. struct sk_buff *msg;
  1450. struct nlattr *hdr;
  1451. int ret;
  1452. msg = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
  1453. if (!msg)
  1454. return -ENOMEM;
  1455. hdr = genlmsg_put_reply(msg, info, &dpll_nl_family, 0,
  1456. DPLL_CMD_PIN_ID_GET);
  1457. if (!hdr) {
  1458. nlmsg_free(msg);
  1459. return -EMSGSIZE;
  1460. }
  1461. pin = dpll_pin_find_from_nlattr(info);
  1462. if (IS_ERR(pin)) {
  1463. nlmsg_free(msg);
  1464. return PTR_ERR(pin);
  1465. }
  1466. if (!dpll_pin_available(pin)) {
  1467. nlmsg_free(msg);
  1468. return -ENODEV;
  1469. }
  1470. ret = dpll_msg_add_pin_handle(msg, pin);
  1471. if (ret) {
  1472. nlmsg_free(msg);
  1473. return ret;
  1474. }
  1475. genlmsg_end(msg, hdr);
  1476. return genlmsg_reply(msg, info);
  1477. }
  1478. int dpll_nl_pin_get_doit(struct sk_buff *skb, struct genl_info *info)
  1479. {
  1480. struct dpll_pin *pin = info->user_ptr[0];
  1481. struct sk_buff *msg;
  1482. struct nlattr *hdr;
  1483. int ret;
  1484. if (!pin)
  1485. return -ENODEV;
  1486. msg = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
  1487. if (!msg)
  1488. return -ENOMEM;
  1489. hdr = genlmsg_put_reply(msg, info, &dpll_nl_family, 0,
  1490. DPLL_CMD_PIN_GET);
  1491. if (!hdr) {
  1492. nlmsg_free(msg);
  1493. return -EMSGSIZE;
  1494. }
  1495. ret = dpll_cmd_pin_get_one(msg, pin, info->extack);
  1496. if (ret) {
  1497. nlmsg_free(msg);
  1498. return ret;
  1499. }
  1500. genlmsg_end(msg, hdr);
  1501. return genlmsg_reply(msg, info);
  1502. }
  1503. int dpll_nl_pin_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
  1504. {
  1505. struct dpll_dump_ctx *ctx = dpll_dump_context(cb);
  1506. struct dpll_pin *pin;
  1507. struct nlattr *hdr;
  1508. unsigned long i;
  1509. int ret = 0;
  1510. mutex_lock(&dpll_lock);
  1511. xa_for_each_marked_start(&dpll_pin_xa, i, pin, DPLL_REGISTERED,
  1512. ctx->idx) {
  1513. if (!dpll_pin_available(pin))
  1514. continue;
  1515. hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid,
  1516. cb->nlh->nlmsg_seq,
  1517. &dpll_nl_family, NLM_F_MULTI,
  1518. DPLL_CMD_PIN_GET);
  1519. if (!hdr) {
  1520. ret = -EMSGSIZE;
  1521. break;
  1522. }
  1523. ret = dpll_cmd_pin_get_one(skb, pin, cb->extack);
  1524. if (ret) {
  1525. genlmsg_cancel(skb, hdr);
  1526. break;
  1527. }
  1528. genlmsg_end(skb, hdr);
  1529. }
  1530. mutex_unlock(&dpll_lock);
  1531. if (ret == -EMSGSIZE) {
  1532. ctx->idx = i;
  1533. return skb->len;
  1534. }
  1535. return ret;
  1536. }
  1537. int dpll_nl_pin_set_doit(struct sk_buff *skb, struct genl_info *info)
  1538. {
  1539. struct dpll_pin *pin = info->user_ptr[0];
  1540. return dpll_pin_set_from_nlattr(pin, info);
  1541. }
  1542. static struct dpll_device *
  1543. dpll_device_find(u64 clock_id, struct nlattr *mod_name_attr,
  1544. enum dpll_type type, struct netlink_ext_ack *extack)
  1545. {
  1546. struct dpll_device *dpll_match = NULL, *dpll;
  1547. bool cid_match, mod_match, type_match;
  1548. unsigned long i;
  1549. xa_for_each_marked(&dpll_device_xa, i, dpll, DPLL_REGISTERED) {
  1550. cid_match = clock_id ? dpll->clock_id == clock_id : true;
  1551. mod_match = mod_name_attr ? (module_name(dpll->module) ?
  1552. !nla_strcmp(mod_name_attr,
  1553. module_name(dpll->module)) : false) : true;
  1554. type_match = type ? dpll->type == type : true;
  1555. if (cid_match && mod_match && type_match) {
  1556. if (dpll_match) {
  1557. NL_SET_ERR_MSG(extack, "multiple matches");
  1558. return ERR_PTR(-EINVAL);
  1559. }
  1560. dpll_match = dpll;
  1561. }
  1562. }
  1563. if (!dpll_match) {
  1564. NL_SET_ERR_MSG(extack, "not found");
  1565. return ERR_PTR(-ENODEV);
  1566. }
  1567. return dpll_match;
  1568. }
  1569. static struct dpll_device *
  1570. dpll_device_find_from_nlattr(struct genl_info *info)
  1571. {
  1572. struct nlattr *attr, *mod_name_attr = NULL;
  1573. enum dpll_type type = 0;
  1574. u64 clock_id = 0;
  1575. int rem = 0;
  1576. nla_for_each_attr(attr, genlmsg_data(info->genlhdr),
  1577. genlmsg_len(info->genlhdr), rem) {
  1578. switch (nla_type(attr)) {
  1579. case DPLL_A_CLOCK_ID:
  1580. if (clock_id)
  1581. goto duplicated_attr;
  1582. clock_id = nla_get_u64(attr);
  1583. break;
  1584. case DPLL_A_MODULE_NAME:
  1585. if (mod_name_attr)
  1586. goto duplicated_attr;
  1587. mod_name_attr = attr;
  1588. break;
  1589. case DPLL_A_TYPE:
  1590. if (type)
  1591. goto duplicated_attr;
  1592. type = nla_get_u32(attr);
  1593. break;
  1594. default:
  1595. break;
  1596. }
  1597. }
  1598. if (!clock_id && !mod_name_attr && !type) {
  1599. NL_SET_ERR_MSG(info->extack, "missing attributes");
  1600. return ERR_PTR(-EINVAL);
  1601. }
  1602. return dpll_device_find(clock_id, mod_name_attr, type, info->extack);
  1603. duplicated_attr:
  1604. NL_SET_ERR_MSG(info->extack, "duplicated attribute");
  1605. return ERR_PTR(-EINVAL);
  1606. }
  1607. int dpll_nl_device_id_get_doit(struct sk_buff *skb, struct genl_info *info)
  1608. {
  1609. struct dpll_device *dpll;
  1610. struct sk_buff *msg;
  1611. struct nlattr *hdr;
  1612. int ret;
  1613. msg = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
  1614. if (!msg)
  1615. return -ENOMEM;
  1616. hdr = genlmsg_put_reply(msg, info, &dpll_nl_family, 0,
  1617. DPLL_CMD_DEVICE_ID_GET);
  1618. if (!hdr) {
  1619. nlmsg_free(msg);
  1620. return -EMSGSIZE;
  1621. }
  1622. dpll = dpll_device_find_from_nlattr(info);
  1623. if (IS_ERR(dpll)) {
  1624. nlmsg_free(msg);
  1625. return PTR_ERR(dpll);
  1626. }
  1627. ret = dpll_msg_add_dev_handle(msg, dpll);
  1628. if (ret) {
  1629. nlmsg_free(msg);
  1630. return ret;
  1631. }
  1632. genlmsg_end(msg, hdr);
  1633. return genlmsg_reply(msg, info);
  1634. }
  1635. int dpll_nl_device_get_doit(struct sk_buff *skb, struct genl_info *info)
  1636. {
  1637. struct dpll_device *dpll = info->user_ptr[0];
  1638. struct sk_buff *msg;
  1639. struct nlattr *hdr;
  1640. int ret;
  1641. msg = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
  1642. if (!msg)
  1643. return -ENOMEM;
  1644. hdr = genlmsg_put_reply(msg, info, &dpll_nl_family, 0,
  1645. DPLL_CMD_DEVICE_GET);
  1646. if (!hdr) {
  1647. nlmsg_free(msg);
  1648. return -EMSGSIZE;
  1649. }
  1650. ret = dpll_device_get_one(dpll, msg, info->extack);
  1651. if (ret) {
  1652. nlmsg_free(msg);
  1653. return ret;
  1654. }
  1655. genlmsg_end(msg, hdr);
  1656. return genlmsg_reply(msg, info);
  1657. }
  1658. static int
  1659. dpll_set_from_nlattr(struct dpll_device *dpll, struct genl_info *info)
  1660. {
  1661. struct nlattr *a;
  1662. int rem, ret;
  1663. nla_for_each_attr(a, genlmsg_data(info->genlhdr),
  1664. genlmsg_len(info->genlhdr), rem) {
  1665. switch (nla_type(a)) {
  1666. case DPLL_A_MODE:
  1667. ret = dpll_mode_set(dpll, a, info->extack);
  1668. if (ret)
  1669. return ret;
  1670. break;
  1671. case DPLL_A_PHASE_OFFSET_MONITOR:
  1672. ret = dpll_phase_offset_monitor_set(dpll, a,
  1673. info->extack);
  1674. if (ret)
  1675. return ret;
  1676. break;
  1677. case DPLL_A_PHASE_OFFSET_AVG_FACTOR:
  1678. ret = dpll_phase_offset_avg_factor_set(dpll, a,
  1679. info->extack);
  1680. if (ret)
  1681. return ret;
  1682. break;
  1683. }
  1684. }
  1685. return 0;
  1686. }
  1687. int dpll_nl_device_set_doit(struct sk_buff *skb, struct genl_info *info)
  1688. {
  1689. struct dpll_device *dpll = info->user_ptr[0];
  1690. return dpll_set_from_nlattr(dpll, info);
  1691. }
  1692. int dpll_nl_device_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
  1693. {
  1694. struct dpll_dump_ctx *ctx = dpll_dump_context(cb);
  1695. struct dpll_device *dpll;
  1696. struct nlattr *hdr;
  1697. unsigned long i;
  1698. int ret = 0;
  1699. mutex_lock(&dpll_lock);
  1700. xa_for_each_marked_start(&dpll_device_xa, i, dpll, DPLL_REGISTERED,
  1701. ctx->idx) {
  1702. hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid,
  1703. cb->nlh->nlmsg_seq, &dpll_nl_family,
  1704. NLM_F_MULTI, DPLL_CMD_DEVICE_GET);
  1705. if (!hdr) {
  1706. ret = -EMSGSIZE;
  1707. break;
  1708. }
  1709. ret = dpll_device_get_one(dpll, skb, cb->extack);
  1710. if (ret) {
  1711. genlmsg_cancel(skb, hdr);
  1712. break;
  1713. }
  1714. genlmsg_end(skb, hdr);
  1715. }
  1716. mutex_unlock(&dpll_lock);
  1717. if (ret == -EMSGSIZE) {
  1718. ctx->idx = i;
  1719. return skb->len;
  1720. }
  1721. return ret;
  1722. }
  1723. int dpll_pre_doit(const struct genl_split_ops *ops, struct sk_buff *skb,
  1724. struct genl_info *info)
  1725. {
  1726. u32 id;
  1727. if (GENL_REQ_ATTR_CHECK(info, DPLL_A_ID))
  1728. return -EINVAL;
  1729. mutex_lock(&dpll_lock);
  1730. id = nla_get_u32(info->attrs[DPLL_A_ID]);
  1731. info->user_ptr[0] = dpll_device_get_by_id(id);
  1732. if (!info->user_ptr[0]) {
  1733. NL_SET_ERR_MSG(info->extack, "device not found");
  1734. goto unlock;
  1735. }
  1736. return 0;
  1737. unlock:
  1738. mutex_unlock(&dpll_lock);
  1739. return -ENODEV;
  1740. }
  1741. void dpll_post_doit(const struct genl_split_ops *ops, struct sk_buff *skb,
  1742. struct genl_info *info)
  1743. {
  1744. mutex_unlock(&dpll_lock);
  1745. }
  1746. int
  1747. dpll_lock_doit(const struct genl_split_ops *ops, struct sk_buff *skb,
  1748. struct genl_info *info)
  1749. {
  1750. mutex_lock(&dpll_lock);
  1751. return 0;
  1752. }
  1753. void
  1754. dpll_unlock_doit(const struct genl_split_ops *ops, struct sk_buff *skb,
  1755. struct genl_info *info)
  1756. {
  1757. mutex_unlock(&dpll_lock);
  1758. }
  1759. int dpll_pin_pre_doit(const struct genl_split_ops *ops, struct sk_buff *skb,
  1760. struct genl_info *info)
  1761. {
  1762. int ret;
  1763. mutex_lock(&dpll_lock);
  1764. if (GENL_REQ_ATTR_CHECK(info, DPLL_A_PIN_ID)) {
  1765. ret = -EINVAL;
  1766. goto unlock_dev;
  1767. }
  1768. info->user_ptr[0] = xa_load(&dpll_pin_xa,
  1769. nla_get_u32(info->attrs[DPLL_A_PIN_ID]));
  1770. if (!info->user_ptr[0] ||
  1771. !dpll_pin_available(info->user_ptr[0])) {
  1772. NL_SET_ERR_MSG(info->extack, "pin not found");
  1773. ret = -ENODEV;
  1774. goto unlock_dev;
  1775. }
  1776. return 0;
  1777. unlock_dev:
  1778. mutex_unlock(&dpll_lock);
  1779. return ret;
  1780. }
  1781. void dpll_pin_post_doit(const struct genl_split_ops *ops, struct sk_buff *skb,
  1782. struct genl_info *info)
  1783. {
  1784. mutex_unlock(&dpll_lock);
  1785. }