counter.c 38 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Generic Counter interface
  4. * Copyright (C) 2018 William Breathitt Gray
  5. */
  6. #include <linux/counter.h>
  7. #include <linux/device.h>
  8. #include <linux/err.h>
  9. #include <linux/export.h>
  10. #include <linux/fs.h>
  11. #include <linux/gfp.h>
  12. #include <linux/idr.h>
  13. #include <linux/init.h>
  14. #include <linux/kernel.h>
  15. #include <linux/list.h>
  16. #include <linux/module.h>
  17. #include <linux/printk.h>
  18. #include <linux/slab.h>
  19. #include <linux/string.h>
  20. #include <linux/sysfs.h>
  21. #include <linux/types.h>
  22. const char *const counter_count_direction_str[2] = {
  23. [COUNTER_COUNT_DIRECTION_FORWARD] = "forward",
  24. [COUNTER_COUNT_DIRECTION_BACKWARD] = "backward"
  25. };
  26. EXPORT_SYMBOL_GPL(counter_count_direction_str);
  27. const char *const counter_count_mode_str[4] = {
  28. [COUNTER_COUNT_MODE_NORMAL] = "normal",
  29. [COUNTER_COUNT_MODE_RANGE_LIMIT] = "range limit",
  30. [COUNTER_COUNT_MODE_NON_RECYCLE] = "non-recycle",
  31. [COUNTER_COUNT_MODE_MODULO_N] = "modulo-n"
  32. };
  33. EXPORT_SYMBOL_GPL(counter_count_mode_str);
  34. ssize_t counter_signal_enum_read(struct counter_device *counter,
  35. struct counter_signal *signal, void *priv,
  36. char *buf)
  37. {
  38. const struct counter_signal_enum_ext *const e = priv;
  39. int err;
  40. size_t index;
  41. if (!e->get)
  42. return -EINVAL;
  43. err = e->get(counter, signal, &index);
  44. if (err)
  45. return err;
  46. if (index >= e->num_items)
  47. return -EINVAL;
  48. return sprintf(buf, "%s\n", e->items[index]);
  49. }
  50. EXPORT_SYMBOL_GPL(counter_signal_enum_read);
  51. ssize_t counter_signal_enum_write(struct counter_device *counter,
  52. struct counter_signal *signal, void *priv,
  53. const char *buf, size_t len)
  54. {
  55. const struct counter_signal_enum_ext *const e = priv;
  56. ssize_t index;
  57. int err;
  58. if (!e->set)
  59. return -EINVAL;
  60. index = __sysfs_match_string(e->items, e->num_items, buf);
  61. if (index < 0)
  62. return index;
  63. err = e->set(counter, signal, index);
  64. if (err)
  65. return err;
  66. return len;
  67. }
  68. EXPORT_SYMBOL_GPL(counter_signal_enum_write);
  69. ssize_t counter_signal_enum_available_read(struct counter_device *counter,
  70. struct counter_signal *signal,
  71. void *priv, char *buf)
  72. {
  73. const struct counter_signal_enum_ext *const e = priv;
  74. size_t i;
  75. size_t len = 0;
  76. if (!e->num_items)
  77. return 0;
  78. for (i = 0; i < e->num_items; i++)
  79. len += sprintf(buf + len, "%s\n", e->items[i]);
  80. return len;
  81. }
  82. EXPORT_SYMBOL_GPL(counter_signal_enum_available_read);
  83. ssize_t counter_count_enum_read(struct counter_device *counter,
  84. struct counter_count *count, void *priv,
  85. char *buf)
  86. {
  87. const struct counter_count_enum_ext *const e = priv;
  88. int err;
  89. size_t index;
  90. if (!e->get)
  91. return -EINVAL;
  92. err = e->get(counter, count, &index);
  93. if (err)
  94. return err;
  95. if (index >= e->num_items)
  96. return -EINVAL;
  97. return sprintf(buf, "%s\n", e->items[index]);
  98. }
  99. EXPORT_SYMBOL_GPL(counter_count_enum_read);
  100. ssize_t counter_count_enum_write(struct counter_device *counter,
  101. struct counter_count *count, void *priv,
  102. const char *buf, size_t len)
  103. {
  104. const struct counter_count_enum_ext *const e = priv;
  105. ssize_t index;
  106. int err;
  107. if (!e->set)
  108. return -EINVAL;
  109. index = __sysfs_match_string(e->items, e->num_items, buf);
  110. if (index < 0)
  111. return index;
  112. err = e->set(counter, count, index);
  113. if (err)
  114. return err;
  115. return len;
  116. }
  117. EXPORT_SYMBOL_GPL(counter_count_enum_write);
  118. ssize_t counter_count_enum_available_read(struct counter_device *counter,
  119. struct counter_count *count,
  120. void *priv, char *buf)
  121. {
  122. const struct counter_count_enum_ext *const e = priv;
  123. size_t i;
  124. size_t len = 0;
  125. if (!e->num_items)
  126. return 0;
  127. for (i = 0; i < e->num_items; i++)
  128. len += sprintf(buf + len, "%s\n", e->items[i]);
  129. return len;
  130. }
  131. EXPORT_SYMBOL_GPL(counter_count_enum_available_read);
  132. ssize_t counter_device_enum_read(struct counter_device *counter, void *priv,
  133. char *buf)
  134. {
  135. const struct counter_device_enum_ext *const e = priv;
  136. int err;
  137. size_t index;
  138. if (!e->get)
  139. return -EINVAL;
  140. err = e->get(counter, &index);
  141. if (err)
  142. return err;
  143. if (index >= e->num_items)
  144. return -EINVAL;
  145. return sprintf(buf, "%s\n", e->items[index]);
  146. }
  147. EXPORT_SYMBOL_GPL(counter_device_enum_read);
  148. ssize_t counter_device_enum_write(struct counter_device *counter, void *priv,
  149. const char *buf, size_t len)
  150. {
  151. const struct counter_device_enum_ext *const e = priv;
  152. ssize_t index;
  153. int err;
  154. if (!e->set)
  155. return -EINVAL;
  156. index = __sysfs_match_string(e->items, e->num_items, buf);
  157. if (index < 0)
  158. return index;
  159. err = e->set(counter, index);
  160. if (err)
  161. return err;
  162. return len;
  163. }
  164. EXPORT_SYMBOL_GPL(counter_device_enum_write);
  165. ssize_t counter_device_enum_available_read(struct counter_device *counter,
  166. void *priv, char *buf)
  167. {
  168. const struct counter_device_enum_ext *const e = priv;
  169. size_t i;
  170. size_t len = 0;
  171. if (!e->num_items)
  172. return 0;
  173. for (i = 0; i < e->num_items; i++)
  174. len += sprintf(buf + len, "%s\n", e->items[i]);
  175. return len;
  176. }
  177. EXPORT_SYMBOL_GPL(counter_device_enum_available_read);
  178. struct counter_attr_parm {
  179. struct counter_device_attr_group *group;
  180. const char *prefix;
  181. const char *name;
  182. ssize_t (*show)(struct device *dev, struct device_attribute *attr,
  183. char *buf);
  184. ssize_t (*store)(struct device *dev, struct device_attribute *attr,
  185. const char *buf, size_t len);
  186. void *component;
  187. };
  188. struct counter_device_attr {
  189. struct device_attribute dev_attr;
  190. struct list_head l;
  191. void *component;
  192. };
  193. static int counter_attribute_create(const struct counter_attr_parm *const parm)
  194. {
  195. struct counter_device_attr *counter_attr;
  196. struct device_attribute *dev_attr;
  197. int err;
  198. struct list_head *const attr_list = &parm->group->attr_list;
  199. /* Allocate a Counter device attribute */
  200. counter_attr = kzalloc(sizeof(*counter_attr), GFP_KERNEL);
  201. if (!counter_attr)
  202. return -ENOMEM;
  203. dev_attr = &counter_attr->dev_attr;
  204. sysfs_attr_init(&dev_attr->attr);
  205. /* Configure device attribute */
  206. dev_attr->attr.name = kasprintf(GFP_KERNEL, "%s%s", parm->prefix,
  207. parm->name);
  208. if (!dev_attr->attr.name) {
  209. err = -ENOMEM;
  210. goto err_free_counter_attr;
  211. }
  212. if (parm->show) {
  213. dev_attr->attr.mode |= 0444;
  214. dev_attr->show = parm->show;
  215. }
  216. if (parm->store) {
  217. dev_attr->attr.mode |= 0200;
  218. dev_attr->store = parm->store;
  219. }
  220. /* Store associated Counter component with attribute */
  221. counter_attr->component = parm->component;
  222. /* Keep track of the attribute for later cleanup */
  223. list_add(&counter_attr->l, attr_list);
  224. parm->group->num_attr++;
  225. return 0;
  226. err_free_counter_attr:
  227. kfree(counter_attr);
  228. return err;
  229. }
  230. #define to_counter_attr(_dev_attr) \
  231. container_of(_dev_attr, struct counter_device_attr, dev_attr)
  232. struct counter_signal_unit {
  233. struct counter_signal *signal;
  234. };
  235. static const char *const counter_signal_value_str[] = {
  236. [COUNTER_SIGNAL_LOW] = "low",
  237. [COUNTER_SIGNAL_HIGH] = "high"
  238. };
  239. static ssize_t counter_signal_show(struct device *dev,
  240. struct device_attribute *attr, char *buf)
  241. {
  242. struct counter_device *const counter = dev_get_drvdata(dev);
  243. const struct counter_device_attr *const devattr = to_counter_attr(attr);
  244. const struct counter_signal_unit *const component = devattr->component;
  245. struct counter_signal *const signal = component->signal;
  246. int err;
  247. enum counter_signal_value val;
  248. err = counter->ops->signal_read(counter, signal, &val);
  249. if (err)
  250. return err;
  251. return sprintf(buf, "%s\n", counter_signal_value_str[val]);
  252. }
  253. struct counter_name_unit {
  254. const char *name;
  255. };
  256. static ssize_t counter_device_attr_name_show(struct device *dev,
  257. struct device_attribute *attr,
  258. char *buf)
  259. {
  260. const struct counter_name_unit *const comp = to_counter_attr(attr)->component;
  261. return sprintf(buf, "%s\n", comp->name);
  262. }
  263. static int counter_name_attribute_create(
  264. struct counter_device_attr_group *const group,
  265. const char *const name)
  266. {
  267. struct counter_name_unit *name_comp;
  268. struct counter_attr_parm parm;
  269. int err;
  270. /* Skip if no name */
  271. if (!name)
  272. return 0;
  273. /* Allocate name attribute component */
  274. name_comp = kmalloc(sizeof(*name_comp), GFP_KERNEL);
  275. if (!name_comp)
  276. return -ENOMEM;
  277. name_comp->name = name;
  278. /* Allocate Signal name attribute */
  279. parm.group = group;
  280. parm.prefix = "";
  281. parm.name = "name";
  282. parm.show = counter_device_attr_name_show;
  283. parm.store = NULL;
  284. parm.component = name_comp;
  285. err = counter_attribute_create(&parm);
  286. if (err)
  287. goto err_free_name_comp;
  288. return 0;
  289. err_free_name_comp:
  290. kfree(name_comp);
  291. return err;
  292. }
  293. struct counter_signal_ext_unit {
  294. struct counter_signal *signal;
  295. const struct counter_signal_ext *ext;
  296. };
  297. static ssize_t counter_signal_ext_show(struct device *dev,
  298. struct device_attribute *attr, char *buf)
  299. {
  300. const struct counter_device_attr *const devattr = to_counter_attr(attr);
  301. const struct counter_signal_ext_unit *const comp = devattr->component;
  302. const struct counter_signal_ext *const ext = comp->ext;
  303. return ext->read(dev_get_drvdata(dev), comp->signal, ext->priv, buf);
  304. }
  305. static ssize_t counter_signal_ext_store(struct device *dev,
  306. struct device_attribute *attr,
  307. const char *buf, size_t len)
  308. {
  309. const struct counter_device_attr *const devattr = to_counter_attr(attr);
  310. const struct counter_signal_ext_unit *const comp = devattr->component;
  311. const struct counter_signal_ext *const ext = comp->ext;
  312. return ext->write(dev_get_drvdata(dev), comp->signal, ext->priv, buf,
  313. len);
  314. }
  315. static void counter_device_attr_list_free(struct list_head *attr_list)
  316. {
  317. struct counter_device_attr *p, *n;
  318. list_for_each_entry_safe(p, n, attr_list, l) {
  319. /* free attribute name and associated component memory */
  320. kfree(p->dev_attr.attr.name);
  321. kfree(p->component);
  322. list_del(&p->l);
  323. kfree(p);
  324. }
  325. }
  326. static int counter_signal_ext_register(
  327. struct counter_device_attr_group *const group,
  328. struct counter_signal *const signal)
  329. {
  330. const size_t num_ext = signal->num_ext;
  331. size_t i;
  332. const struct counter_signal_ext *ext;
  333. struct counter_signal_ext_unit *signal_ext_comp;
  334. struct counter_attr_parm parm;
  335. int err;
  336. /* Create an attribute for each extension */
  337. for (i = 0 ; i < num_ext; i++) {
  338. ext = signal->ext + i;
  339. /* Allocate signal_ext attribute component */
  340. signal_ext_comp = kmalloc(sizeof(*signal_ext_comp), GFP_KERNEL);
  341. if (!signal_ext_comp) {
  342. err = -ENOMEM;
  343. goto err_free_attr_list;
  344. }
  345. signal_ext_comp->signal = signal;
  346. signal_ext_comp->ext = ext;
  347. /* Allocate a Counter device attribute */
  348. parm.group = group;
  349. parm.prefix = "";
  350. parm.name = ext->name;
  351. parm.show = (ext->read) ? counter_signal_ext_show : NULL;
  352. parm.store = (ext->write) ? counter_signal_ext_store : NULL;
  353. parm.component = signal_ext_comp;
  354. err = counter_attribute_create(&parm);
  355. if (err) {
  356. kfree(signal_ext_comp);
  357. goto err_free_attr_list;
  358. }
  359. }
  360. return 0;
  361. err_free_attr_list:
  362. counter_device_attr_list_free(&group->attr_list);
  363. return err;
  364. }
  365. static int counter_signal_attributes_create(
  366. struct counter_device_attr_group *const group,
  367. const struct counter_device *const counter,
  368. struct counter_signal *const signal)
  369. {
  370. struct counter_signal_unit *signal_comp;
  371. struct counter_attr_parm parm;
  372. int err;
  373. /* Allocate Signal attribute component */
  374. signal_comp = kmalloc(sizeof(*signal_comp), GFP_KERNEL);
  375. if (!signal_comp)
  376. return -ENOMEM;
  377. signal_comp->signal = signal;
  378. /* Create main Signal attribute */
  379. parm.group = group;
  380. parm.prefix = "";
  381. parm.name = "signal";
  382. parm.show = (counter->ops->signal_read) ? counter_signal_show : NULL;
  383. parm.store = NULL;
  384. parm.component = signal_comp;
  385. err = counter_attribute_create(&parm);
  386. if (err) {
  387. kfree(signal_comp);
  388. return err;
  389. }
  390. /* Create Signal name attribute */
  391. err = counter_name_attribute_create(group, signal->name);
  392. if (err)
  393. goto err_free_attr_list;
  394. /* Register Signal extension attributes */
  395. err = counter_signal_ext_register(group, signal);
  396. if (err)
  397. goto err_free_attr_list;
  398. return 0;
  399. err_free_attr_list:
  400. counter_device_attr_list_free(&group->attr_list);
  401. return err;
  402. }
  403. static int counter_signals_register(
  404. struct counter_device_attr_group *const groups_list,
  405. const struct counter_device *const counter)
  406. {
  407. const size_t num_signals = counter->num_signals;
  408. size_t i;
  409. struct counter_signal *signal;
  410. const char *name;
  411. int err;
  412. /* Register each Signal */
  413. for (i = 0; i < num_signals; i++) {
  414. signal = counter->signals + i;
  415. /* Generate Signal attribute directory name */
  416. name = kasprintf(GFP_KERNEL, "signal%d", signal->id);
  417. if (!name) {
  418. err = -ENOMEM;
  419. goto err_free_attr_groups;
  420. }
  421. groups_list[i].attr_group.name = name;
  422. /* Create all attributes associated with Signal */
  423. err = counter_signal_attributes_create(groups_list + i, counter,
  424. signal);
  425. if (err)
  426. goto err_free_attr_groups;
  427. }
  428. return 0;
  429. err_free_attr_groups:
  430. do {
  431. kfree(groups_list[i].attr_group.name);
  432. counter_device_attr_list_free(&groups_list[i].attr_list);
  433. } while (i--);
  434. return err;
  435. }
  436. static const char *const counter_synapse_action_str[] = {
  437. [COUNTER_SYNAPSE_ACTION_NONE] = "none",
  438. [COUNTER_SYNAPSE_ACTION_RISING_EDGE] = "rising edge",
  439. [COUNTER_SYNAPSE_ACTION_FALLING_EDGE] = "falling edge",
  440. [COUNTER_SYNAPSE_ACTION_BOTH_EDGES] = "both edges"
  441. };
  442. struct counter_action_unit {
  443. struct counter_synapse *synapse;
  444. struct counter_count *count;
  445. };
  446. static ssize_t counter_action_show(struct device *dev,
  447. struct device_attribute *attr, char *buf)
  448. {
  449. const struct counter_device_attr *const devattr = to_counter_attr(attr);
  450. int err;
  451. struct counter_device *const counter = dev_get_drvdata(dev);
  452. const struct counter_action_unit *const component = devattr->component;
  453. struct counter_count *const count = component->count;
  454. struct counter_synapse *const synapse = component->synapse;
  455. size_t action_index;
  456. enum counter_synapse_action action;
  457. err = counter->ops->action_get(counter, count, synapse, &action_index);
  458. if (err)
  459. return err;
  460. synapse->action = action_index;
  461. action = synapse->actions_list[action_index];
  462. return sprintf(buf, "%s\n", counter_synapse_action_str[action]);
  463. }
  464. static ssize_t counter_action_store(struct device *dev,
  465. struct device_attribute *attr,
  466. const char *buf, size_t len)
  467. {
  468. const struct counter_device_attr *const devattr = to_counter_attr(attr);
  469. const struct counter_action_unit *const component = devattr->component;
  470. struct counter_synapse *const synapse = component->synapse;
  471. size_t action_index;
  472. const size_t num_actions = synapse->num_actions;
  473. enum counter_synapse_action action;
  474. int err;
  475. struct counter_device *const counter = dev_get_drvdata(dev);
  476. struct counter_count *const count = component->count;
  477. /* Find requested action mode */
  478. for (action_index = 0; action_index < num_actions; action_index++) {
  479. action = synapse->actions_list[action_index];
  480. if (sysfs_streq(buf, counter_synapse_action_str[action]))
  481. break;
  482. }
  483. /* If requested action mode not found */
  484. if (action_index >= num_actions)
  485. return -EINVAL;
  486. err = counter->ops->action_set(counter, count, synapse, action_index);
  487. if (err)
  488. return err;
  489. synapse->action = action_index;
  490. return len;
  491. }
  492. struct counter_action_avail_unit {
  493. const enum counter_synapse_action *actions_list;
  494. size_t num_actions;
  495. };
  496. static ssize_t counter_synapse_action_available_show(struct device *dev,
  497. struct device_attribute *attr, char *buf)
  498. {
  499. const struct counter_device_attr *const devattr = to_counter_attr(attr);
  500. const struct counter_action_avail_unit *const component = devattr->component;
  501. size_t i;
  502. enum counter_synapse_action action;
  503. ssize_t len = 0;
  504. for (i = 0; i < component->num_actions; i++) {
  505. action = component->actions_list[i];
  506. len += sprintf(buf + len, "%s\n",
  507. counter_synapse_action_str[action]);
  508. }
  509. return len;
  510. }
  511. static int counter_synapses_register(
  512. struct counter_device_attr_group *const group,
  513. const struct counter_device *const counter,
  514. struct counter_count *const count, const char *const count_attr_name)
  515. {
  516. size_t i;
  517. struct counter_synapse *synapse;
  518. const char *prefix;
  519. struct counter_action_unit *action_comp;
  520. struct counter_attr_parm parm;
  521. int err;
  522. struct counter_action_avail_unit *avail_comp;
  523. /* Register each Synapse */
  524. for (i = 0; i < count->num_synapses; i++) {
  525. synapse = count->synapses + i;
  526. /* Generate attribute prefix */
  527. prefix = kasprintf(GFP_KERNEL, "signal%d_",
  528. synapse->signal->id);
  529. if (!prefix) {
  530. err = -ENOMEM;
  531. goto err_free_attr_list;
  532. }
  533. /* Allocate action attribute component */
  534. action_comp = kmalloc(sizeof(*action_comp), GFP_KERNEL);
  535. if (!action_comp) {
  536. err = -ENOMEM;
  537. goto err_free_prefix;
  538. }
  539. action_comp->synapse = synapse;
  540. action_comp->count = count;
  541. /* Create action attribute */
  542. parm.group = group;
  543. parm.prefix = prefix;
  544. parm.name = "action";
  545. parm.show = (counter->ops->action_get) ? counter_action_show : NULL;
  546. parm.store = (counter->ops->action_set) ? counter_action_store : NULL;
  547. parm.component = action_comp;
  548. err = counter_attribute_create(&parm);
  549. if (err) {
  550. kfree(action_comp);
  551. goto err_free_prefix;
  552. }
  553. /* Allocate action available attribute component */
  554. avail_comp = kmalloc(sizeof(*avail_comp), GFP_KERNEL);
  555. if (!avail_comp) {
  556. err = -ENOMEM;
  557. goto err_free_prefix;
  558. }
  559. avail_comp->actions_list = synapse->actions_list;
  560. avail_comp->num_actions = synapse->num_actions;
  561. /* Create action_available attribute */
  562. parm.group = group;
  563. parm.prefix = prefix;
  564. parm.name = "action_available";
  565. parm.show = counter_synapse_action_available_show;
  566. parm.store = NULL;
  567. parm.component = avail_comp;
  568. err = counter_attribute_create(&parm);
  569. if (err) {
  570. kfree(avail_comp);
  571. goto err_free_prefix;
  572. }
  573. kfree(prefix);
  574. }
  575. return 0;
  576. err_free_prefix:
  577. kfree(prefix);
  578. err_free_attr_list:
  579. counter_device_attr_list_free(&group->attr_list);
  580. return err;
  581. }
  582. struct counter_count_unit {
  583. struct counter_count *count;
  584. };
  585. static ssize_t counter_count_show(struct device *dev,
  586. struct device_attribute *attr,
  587. char *buf)
  588. {
  589. struct counter_device *const counter = dev_get_drvdata(dev);
  590. const struct counter_device_attr *const devattr = to_counter_attr(attr);
  591. const struct counter_count_unit *const component = devattr->component;
  592. struct counter_count *const count = component->count;
  593. int err;
  594. unsigned long val;
  595. err = counter->ops->count_read(counter, count, &val);
  596. if (err)
  597. return err;
  598. return sprintf(buf, "%lu\n", val);
  599. }
  600. static ssize_t counter_count_store(struct device *dev,
  601. struct device_attribute *attr,
  602. const char *buf, size_t len)
  603. {
  604. struct counter_device *const counter = dev_get_drvdata(dev);
  605. const struct counter_device_attr *const devattr = to_counter_attr(attr);
  606. const struct counter_count_unit *const component = devattr->component;
  607. struct counter_count *const count = component->count;
  608. int err;
  609. unsigned long val;
  610. err = kstrtoul(buf, 0, &val);
  611. if (err)
  612. return err;
  613. err = counter->ops->count_write(counter, count, val);
  614. if (err)
  615. return err;
  616. return len;
  617. }
  618. static const char *const counter_count_function_str[] = {
  619. [COUNTER_COUNT_FUNCTION_INCREASE] = "increase",
  620. [COUNTER_COUNT_FUNCTION_DECREASE] = "decrease",
  621. [COUNTER_COUNT_FUNCTION_PULSE_DIRECTION] = "pulse-direction",
  622. [COUNTER_COUNT_FUNCTION_QUADRATURE_X1_A] = "quadrature x1 a",
  623. [COUNTER_COUNT_FUNCTION_QUADRATURE_X1_B] = "quadrature x1 b",
  624. [COUNTER_COUNT_FUNCTION_QUADRATURE_X2_A] = "quadrature x2 a",
  625. [COUNTER_COUNT_FUNCTION_QUADRATURE_X2_B] = "quadrature x2 b",
  626. [COUNTER_COUNT_FUNCTION_QUADRATURE_X4] = "quadrature x4"
  627. };
  628. static ssize_t counter_function_show(struct device *dev,
  629. struct device_attribute *attr, char *buf)
  630. {
  631. int err;
  632. struct counter_device *const counter = dev_get_drvdata(dev);
  633. const struct counter_device_attr *const devattr = to_counter_attr(attr);
  634. const struct counter_count_unit *const component = devattr->component;
  635. struct counter_count *const count = component->count;
  636. size_t func_index;
  637. enum counter_count_function function;
  638. err = counter->ops->function_get(counter, count, &func_index);
  639. if (err)
  640. return err;
  641. count->function = func_index;
  642. function = count->functions_list[func_index];
  643. return sprintf(buf, "%s\n", counter_count_function_str[function]);
  644. }
  645. static ssize_t counter_function_store(struct device *dev,
  646. struct device_attribute *attr,
  647. const char *buf, size_t len)
  648. {
  649. const struct counter_device_attr *const devattr = to_counter_attr(attr);
  650. const struct counter_count_unit *const component = devattr->component;
  651. struct counter_count *const count = component->count;
  652. const size_t num_functions = count->num_functions;
  653. size_t func_index;
  654. enum counter_count_function function;
  655. int err;
  656. struct counter_device *const counter = dev_get_drvdata(dev);
  657. /* Find requested Count function mode */
  658. for (func_index = 0; func_index < num_functions; func_index++) {
  659. function = count->functions_list[func_index];
  660. if (sysfs_streq(buf, counter_count_function_str[function]))
  661. break;
  662. }
  663. /* Return error if requested Count function mode not found */
  664. if (func_index >= num_functions)
  665. return -EINVAL;
  666. err = counter->ops->function_set(counter, count, func_index);
  667. if (err)
  668. return err;
  669. count->function = func_index;
  670. return len;
  671. }
  672. struct counter_count_ext_unit {
  673. struct counter_count *count;
  674. const struct counter_count_ext *ext;
  675. };
  676. static ssize_t counter_count_ext_show(struct device *dev,
  677. struct device_attribute *attr, char *buf)
  678. {
  679. const struct counter_device_attr *const devattr = to_counter_attr(attr);
  680. const struct counter_count_ext_unit *const comp = devattr->component;
  681. const struct counter_count_ext *const ext = comp->ext;
  682. return ext->read(dev_get_drvdata(dev), comp->count, ext->priv, buf);
  683. }
  684. static ssize_t counter_count_ext_store(struct device *dev,
  685. struct device_attribute *attr,
  686. const char *buf, size_t len)
  687. {
  688. const struct counter_device_attr *const devattr = to_counter_attr(attr);
  689. const struct counter_count_ext_unit *const comp = devattr->component;
  690. const struct counter_count_ext *const ext = comp->ext;
  691. return ext->write(dev_get_drvdata(dev), comp->count, ext->priv, buf,
  692. len);
  693. }
  694. static int counter_count_ext_register(
  695. struct counter_device_attr_group *const group,
  696. struct counter_count *const count)
  697. {
  698. size_t i;
  699. const struct counter_count_ext *ext;
  700. struct counter_count_ext_unit *count_ext_comp;
  701. struct counter_attr_parm parm;
  702. int err;
  703. /* Create an attribute for each extension */
  704. for (i = 0 ; i < count->num_ext; i++) {
  705. ext = count->ext + i;
  706. /* Allocate count_ext attribute component */
  707. count_ext_comp = kmalloc(sizeof(*count_ext_comp), GFP_KERNEL);
  708. if (!count_ext_comp) {
  709. err = -ENOMEM;
  710. goto err_free_attr_list;
  711. }
  712. count_ext_comp->count = count;
  713. count_ext_comp->ext = ext;
  714. /* Allocate count_ext attribute */
  715. parm.group = group;
  716. parm.prefix = "";
  717. parm.name = ext->name;
  718. parm.show = (ext->read) ? counter_count_ext_show : NULL;
  719. parm.store = (ext->write) ? counter_count_ext_store : NULL;
  720. parm.component = count_ext_comp;
  721. err = counter_attribute_create(&parm);
  722. if (err) {
  723. kfree(count_ext_comp);
  724. goto err_free_attr_list;
  725. }
  726. }
  727. return 0;
  728. err_free_attr_list:
  729. counter_device_attr_list_free(&group->attr_list);
  730. return err;
  731. }
  732. struct counter_func_avail_unit {
  733. const enum counter_count_function *functions_list;
  734. size_t num_functions;
  735. };
  736. static ssize_t counter_count_function_available_show(struct device *dev,
  737. struct device_attribute *attr, char *buf)
  738. {
  739. const struct counter_device_attr *const devattr = to_counter_attr(attr);
  740. const struct counter_func_avail_unit *const component = devattr->component;
  741. const enum counter_count_function *const func_list = component->functions_list;
  742. const size_t num_functions = component->num_functions;
  743. size_t i;
  744. enum counter_count_function function;
  745. ssize_t len = 0;
  746. for (i = 0; i < num_functions; i++) {
  747. function = func_list[i];
  748. len += sprintf(buf + len, "%s\n",
  749. counter_count_function_str[function]);
  750. }
  751. return len;
  752. }
  753. static int counter_count_attributes_create(
  754. struct counter_device_attr_group *const group,
  755. const struct counter_device *const counter,
  756. struct counter_count *const count)
  757. {
  758. struct counter_count_unit *count_comp;
  759. struct counter_attr_parm parm;
  760. int err;
  761. struct counter_count_unit *func_comp;
  762. struct counter_func_avail_unit *avail_comp;
  763. /* Allocate count attribute component */
  764. count_comp = kmalloc(sizeof(*count_comp), GFP_KERNEL);
  765. if (!count_comp)
  766. return -ENOMEM;
  767. count_comp->count = count;
  768. /* Create main Count attribute */
  769. parm.group = group;
  770. parm.prefix = "";
  771. parm.name = "count";
  772. parm.show = (counter->ops->count_read) ? counter_count_show : NULL;
  773. parm.store = (counter->ops->count_write) ? counter_count_store : NULL;
  774. parm.component = count_comp;
  775. err = counter_attribute_create(&parm);
  776. if (err) {
  777. kfree(count_comp);
  778. return err;
  779. }
  780. /* Allocate function attribute component */
  781. func_comp = kmalloc(sizeof(*func_comp), GFP_KERNEL);
  782. if (!func_comp) {
  783. err = -ENOMEM;
  784. goto err_free_attr_list;
  785. }
  786. func_comp->count = count;
  787. /* Create Count function attribute */
  788. parm.group = group;
  789. parm.prefix = "";
  790. parm.name = "function";
  791. parm.show = (counter->ops->function_get) ? counter_function_show : NULL;
  792. parm.store = (counter->ops->function_set) ? counter_function_store : NULL;
  793. parm.component = func_comp;
  794. err = counter_attribute_create(&parm);
  795. if (err) {
  796. kfree(func_comp);
  797. goto err_free_attr_list;
  798. }
  799. /* Allocate function available attribute component */
  800. avail_comp = kmalloc(sizeof(*avail_comp), GFP_KERNEL);
  801. if (!avail_comp) {
  802. err = -ENOMEM;
  803. goto err_free_attr_list;
  804. }
  805. avail_comp->functions_list = count->functions_list;
  806. avail_comp->num_functions = count->num_functions;
  807. /* Create Count function_available attribute */
  808. parm.group = group;
  809. parm.prefix = "";
  810. parm.name = "function_available";
  811. parm.show = counter_count_function_available_show;
  812. parm.store = NULL;
  813. parm.component = avail_comp;
  814. err = counter_attribute_create(&parm);
  815. if (err) {
  816. kfree(avail_comp);
  817. goto err_free_attr_list;
  818. }
  819. /* Create Count name attribute */
  820. err = counter_name_attribute_create(group, count->name);
  821. if (err)
  822. goto err_free_attr_list;
  823. /* Register Count extension attributes */
  824. err = counter_count_ext_register(group, count);
  825. if (err)
  826. goto err_free_attr_list;
  827. return 0;
  828. err_free_attr_list:
  829. counter_device_attr_list_free(&group->attr_list);
  830. return err;
  831. }
  832. static int counter_counts_register(
  833. struct counter_device_attr_group *const groups_list,
  834. const struct counter_device *const counter)
  835. {
  836. size_t i;
  837. struct counter_count *count;
  838. const char *name;
  839. int err;
  840. /* Register each Count */
  841. for (i = 0; i < counter->num_counts; i++) {
  842. count = counter->counts + i;
  843. /* Generate Count attribute directory name */
  844. name = kasprintf(GFP_KERNEL, "count%d", count->id);
  845. if (!name) {
  846. err = -ENOMEM;
  847. goto err_free_attr_groups;
  848. }
  849. groups_list[i].attr_group.name = name;
  850. /* Register the Synapses associated with each Count */
  851. err = counter_synapses_register(groups_list + i, counter, count,
  852. name);
  853. if (err)
  854. goto err_free_attr_groups;
  855. /* Create all attributes associated with Count */
  856. err = counter_count_attributes_create(groups_list + i, counter,
  857. count);
  858. if (err)
  859. goto err_free_attr_groups;
  860. }
  861. return 0;
  862. err_free_attr_groups:
  863. do {
  864. kfree(groups_list[i].attr_group.name);
  865. counter_device_attr_list_free(&groups_list[i].attr_list);
  866. } while (i--);
  867. return err;
  868. }
  869. struct counter_size_unit {
  870. size_t size;
  871. };
  872. static ssize_t counter_device_attr_size_show(struct device *dev,
  873. struct device_attribute *attr,
  874. char *buf)
  875. {
  876. const struct counter_size_unit *const comp = to_counter_attr(attr)->component;
  877. return sprintf(buf, "%zu\n", comp->size);
  878. }
  879. static int counter_size_attribute_create(
  880. struct counter_device_attr_group *const group,
  881. const size_t size, const char *const name)
  882. {
  883. struct counter_size_unit *size_comp;
  884. struct counter_attr_parm parm;
  885. int err;
  886. /* Allocate size attribute component */
  887. size_comp = kmalloc(sizeof(*size_comp), GFP_KERNEL);
  888. if (!size_comp)
  889. return -ENOMEM;
  890. size_comp->size = size;
  891. parm.group = group;
  892. parm.prefix = "";
  893. parm.name = name;
  894. parm.show = counter_device_attr_size_show;
  895. parm.store = NULL;
  896. parm.component = size_comp;
  897. err = counter_attribute_create(&parm);
  898. if (err)
  899. goto err_free_size_comp;
  900. return 0;
  901. err_free_size_comp:
  902. kfree(size_comp);
  903. return err;
  904. }
  905. struct counter_ext_unit {
  906. const struct counter_device_ext *ext;
  907. };
  908. static ssize_t counter_device_ext_show(struct device *dev,
  909. struct device_attribute *attr, char *buf)
  910. {
  911. const struct counter_device_attr *const devattr = to_counter_attr(attr);
  912. const struct counter_ext_unit *const component = devattr->component;
  913. const struct counter_device_ext *const ext = component->ext;
  914. return ext->read(dev_get_drvdata(dev), ext->priv, buf);
  915. }
  916. static ssize_t counter_device_ext_store(struct device *dev,
  917. struct device_attribute *attr,
  918. const char *buf, size_t len)
  919. {
  920. const struct counter_device_attr *const devattr = to_counter_attr(attr);
  921. const struct counter_ext_unit *const component = devattr->component;
  922. const struct counter_device_ext *const ext = component->ext;
  923. return ext->write(dev_get_drvdata(dev), ext->priv, buf, len);
  924. }
  925. static int counter_device_ext_register(
  926. struct counter_device_attr_group *const group,
  927. struct counter_device *const counter)
  928. {
  929. size_t i;
  930. struct counter_ext_unit *ext_comp;
  931. struct counter_attr_parm parm;
  932. int err;
  933. /* Create an attribute for each extension */
  934. for (i = 0 ; i < counter->num_ext; i++) {
  935. /* Allocate extension attribute component */
  936. ext_comp = kmalloc(sizeof(*ext_comp), GFP_KERNEL);
  937. if (!ext_comp) {
  938. err = -ENOMEM;
  939. goto err_free_attr_list;
  940. }
  941. ext_comp->ext = counter->ext + i;
  942. /* Allocate extension attribute */
  943. parm.group = group;
  944. parm.prefix = "";
  945. parm.name = counter->ext[i].name;
  946. parm.show = (counter->ext[i].read) ? counter_device_ext_show : NULL;
  947. parm.store = (counter->ext[i].write) ? counter_device_ext_store : NULL;
  948. parm.component = ext_comp;
  949. err = counter_attribute_create(&parm);
  950. if (err) {
  951. kfree(ext_comp);
  952. goto err_free_attr_list;
  953. }
  954. }
  955. return 0;
  956. err_free_attr_list:
  957. counter_device_attr_list_free(&group->attr_list);
  958. return err;
  959. }
  960. static int counter_global_attr_register(
  961. struct counter_device_attr_group *const group,
  962. struct counter_device *const counter)
  963. {
  964. int err;
  965. /* Create name attribute */
  966. err = counter_name_attribute_create(group, counter->name);
  967. if (err)
  968. return err;
  969. /* Create num_counts attribute */
  970. err = counter_size_attribute_create(group, counter->num_counts,
  971. "num_counts");
  972. if (err)
  973. goto err_free_attr_list;
  974. /* Create num_signals attribute */
  975. err = counter_size_attribute_create(group, counter->num_signals,
  976. "num_signals");
  977. if (err)
  978. goto err_free_attr_list;
  979. /* Register Counter device extension attributes */
  980. err = counter_device_ext_register(group, counter);
  981. if (err)
  982. goto err_free_attr_list;
  983. return 0;
  984. err_free_attr_list:
  985. counter_device_attr_list_free(&group->attr_list);
  986. return err;
  987. }
  988. static void counter_device_groups_list_free(
  989. struct counter_device_attr_group *const groups_list,
  990. const size_t num_groups)
  991. {
  992. struct counter_device_attr_group *group;
  993. size_t i;
  994. /* loop through all attribute groups (signals, counts, global, etc.) */
  995. for (i = 0; i < num_groups; i++) {
  996. group = groups_list + i;
  997. /* free all attribute group and associated attributes memory */
  998. kfree(group->attr_group.name);
  999. kfree(group->attr_group.attrs);
  1000. counter_device_attr_list_free(&group->attr_list);
  1001. }
  1002. kfree(groups_list);
  1003. }
  1004. static int counter_device_groups_list_prepare(
  1005. struct counter_device *const counter)
  1006. {
  1007. const size_t total_num_groups =
  1008. counter->num_signals + counter->num_counts + 1;
  1009. struct counter_device_attr_group *groups_list;
  1010. size_t i;
  1011. int err;
  1012. size_t num_groups = 0;
  1013. /* Allocate space for attribute groups (signals, counts, and ext) */
  1014. groups_list = kcalloc(total_num_groups, sizeof(*groups_list),
  1015. GFP_KERNEL);
  1016. if (!groups_list)
  1017. return -ENOMEM;
  1018. /* Initialize attribute lists */
  1019. for (i = 0; i < total_num_groups; i++)
  1020. INIT_LIST_HEAD(&groups_list[i].attr_list);
  1021. /* Register Signals */
  1022. err = counter_signals_register(groups_list, counter);
  1023. if (err)
  1024. goto err_free_groups_list;
  1025. num_groups += counter->num_signals;
  1026. /* Register Counts and respective Synapses */
  1027. err = counter_counts_register(groups_list + num_groups, counter);
  1028. if (err)
  1029. goto err_free_groups_list;
  1030. num_groups += counter->num_counts;
  1031. /* Register Counter global attributes */
  1032. err = counter_global_attr_register(groups_list + num_groups, counter);
  1033. if (err)
  1034. goto err_free_groups_list;
  1035. num_groups++;
  1036. /* Store groups_list in device_state */
  1037. counter->device_state->groups_list = groups_list;
  1038. counter->device_state->num_groups = num_groups;
  1039. return 0;
  1040. err_free_groups_list:
  1041. counter_device_groups_list_free(groups_list, num_groups);
  1042. return err;
  1043. }
  1044. static int counter_device_groups_prepare(
  1045. struct counter_device_state *const device_state)
  1046. {
  1047. size_t i, j;
  1048. struct counter_device_attr_group *group;
  1049. int err;
  1050. struct counter_device_attr *p;
  1051. /* Allocate attribute groups for association with device */
  1052. device_state->groups = kcalloc(device_state->num_groups + 1,
  1053. sizeof(*device_state->groups),
  1054. GFP_KERNEL);
  1055. if (!device_state->groups)
  1056. return -ENOMEM;
  1057. /* Prepare each group of attributes for association */
  1058. for (i = 0; i < device_state->num_groups; i++) {
  1059. group = device_state->groups_list + i;
  1060. /* Allocate space for attribute pointers in attribute group */
  1061. group->attr_group.attrs = kcalloc(group->num_attr + 1,
  1062. sizeof(*group->attr_group.attrs), GFP_KERNEL);
  1063. if (!group->attr_group.attrs) {
  1064. err = -ENOMEM;
  1065. goto err_free_groups;
  1066. }
  1067. /* Add attribute pointers to attribute group */
  1068. j = 0;
  1069. list_for_each_entry(p, &group->attr_list, l)
  1070. group->attr_group.attrs[j++] = &p->dev_attr.attr;
  1071. /* Group attributes in attribute group */
  1072. device_state->groups[i] = &group->attr_group;
  1073. }
  1074. /* Associate attributes with device */
  1075. device_state->dev.groups = device_state->groups;
  1076. return 0;
  1077. err_free_groups:
  1078. do {
  1079. group = device_state->groups_list + i;
  1080. kfree(group->attr_group.attrs);
  1081. group->attr_group.attrs = NULL;
  1082. } while (i--);
  1083. kfree(device_state->groups);
  1084. return err;
  1085. }
  1086. /* Provides a unique ID for each counter device */
  1087. static DEFINE_IDA(counter_ida);
  1088. static void counter_device_release(struct device *dev)
  1089. {
  1090. struct counter_device *const counter = dev_get_drvdata(dev);
  1091. struct counter_device_state *const device_state = counter->device_state;
  1092. kfree(device_state->groups);
  1093. counter_device_groups_list_free(device_state->groups_list,
  1094. device_state->num_groups);
  1095. ida_simple_remove(&counter_ida, device_state->id);
  1096. kfree(device_state);
  1097. }
  1098. static struct device_type counter_device_type = {
  1099. .name = "counter_device",
  1100. .release = counter_device_release
  1101. };
  1102. static struct bus_type counter_bus_type = {
  1103. .name = "counter"
  1104. };
  1105. /**
  1106. * counter_register - register Counter to the system
  1107. * @counter: pointer to Counter to register
  1108. *
  1109. * This function registers a Counter to the system. A sysfs "counter" directory
  1110. * will be created and populated with sysfs attributes correlating with the
  1111. * Counter Signals, Synapses, and Counts respectively.
  1112. */
  1113. int counter_register(struct counter_device *const counter)
  1114. {
  1115. struct counter_device_state *device_state;
  1116. int err;
  1117. /* Allocate internal state container for Counter device */
  1118. device_state = kzalloc(sizeof(*device_state), GFP_KERNEL);
  1119. if (!device_state)
  1120. return -ENOMEM;
  1121. counter->device_state = device_state;
  1122. /* Acquire unique ID */
  1123. device_state->id = ida_simple_get(&counter_ida, 0, 0, GFP_KERNEL);
  1124. if (device_state->id < 0) {
  1125. err = device_state->id;
  1126. goto err_free_device_state;
  1127. }
  1128. /* Configure device structure for Counter */
  1129. device_state->dev.type = &counter_device_type;
  1130. device_state->dev.bus = &counter_bus_type;
  1131. if (counter->parent) {
  1132. device_state->dev.parent = counter->parent;
  1133. device_state->dev.of_node = counter->parent->of_node;
  1134. }
  1135. dev_set_name(&device_state->dev, "counter%d", device_state->id);
  1136. device_initialize(&device_state->dev);
  1137. dev_set_drvdata(&device_state->dev, counter);
  1138. /* Prepare device attributes */
  1139. err = counter_device_groups_list_prepare(counter);
  1140. if (err)
  1141. goto err_free_id;
  1142. /* Organize device attributes to groups and match to device */
  1143. err = counter_device_groups_prepare(device_state);
  1144. if (err)
  1145. goto err_free_groups_list;
  1146. /* Add device to system */
  1147. err = device_add(&device_state->dev);
  1148. if (err)
  1149. goto err_free_groups;
  1150. return 0;
  1151. err_free_groups:
  1152. kfree(device_state->groups);
  1153. err_free_groups_list:
  1154. counter_device_groups_list_free(device_state->groups_list,
  1155. device_state->num_groups);
  1156. err_free_id:
  1157. ida_simple_remove(&counter_ida, device_state->id);
  1158. err_free_device_state:
  1159. kfree(device_state);
  1160. return err;
  1161. }
  1162. EXPORT_SYMBOL_GPL(counter_register);
  1163. /**
  1164. * counter_unregister - unregister Counter from the system
  1165. * @counter: pointer to Counter to unregister
  1166. *
  1167. * The Counter is unregistered from the system; all allocated memory is freed.
  1168. */
  1169. void counter_unregister(struct counter_device *const counter)
  1170. {
  1171. if (counter)
  1172. device_del(&counter->device_state->dev);
  1173. }
  1174. EXPORT_SYMBOL_GPL(counter_unregister);
  1175. static void devm_counter_unreg(struct device *dev, void *res)
  1176. {
  1177. counter_unregister(*(struct counter_device **)res);
  1178. }
  1179. /**
  1180. * devm_counter_register - Resource-managed counter_register
  1181. * @dev: device to allocate counter_device for
  1182. * @counter: pointer to Counter to register
  1183. *
  1184. * Managed counter_register. The Counter registered with this function is
  1185. * automatically unregistered on driver detach. This function calls
  1186. * counter_register internally. Refer to that function for more information.
  1187. *
  1188. * If an Counter registered with this function needs to be unregistered
  1189. * separately, devm_counter_unregister must be used.
  1190. *
  1191. * RETURNS:
  1192. * 0 on success, negative error number on failure.
  1193. */
  1194. int devm_counter_register(struct device *dev,
  1195. struct counter_device *const counter)
  1196. {
  1197. struct counter_device **ptr;
  1198. int ret;
  1199. ptr = devres_alloc(devm_counter_unreg, sizeof(*ptr), GFP_KERNEL);
  1200. if (!ptr)
  1201. return -ENOMEM;
  1202. ret = counter_register(counter);
  1203. if (!ret) {
  1204. *ptr = counter;
  1205. devres_add(dev, ptr);
  1206. } else {
  1207. devres_free(ptr);
  1208. }
  1209. return ret;
  1210. }
  1211. EXPORT_SYMBOL_GPL(devm_counter_register);
  1212. static int devm_counter_match(struct device *dev, void *res, void *data)
  1213. {
  1214. struct counter_device **r = res;
  1215. if (!r || !*r) {
  1216. WARN_ON(!r || !*r);
  1217. return 0;
  1218. }
  1219. return *r == data;
  1220. }
  1221. /**
  1222. * devm_counter_unregister - Resource-managed counter_unregister
  1223. * @dev: device this counter_device belongs to
  1224. * @counter: pointer to Counter associated with the device
  1225. *
  1226. * Unregister Counter registered with devm_counter_register.
  1227. */
  1228. void devm_counter_unregister(struct device *dev,
  1229. struct counter_device *const counter)
  1230. {
  1231. int rc;
  1232. rc = devres_release(dev, devm_counter_unreg, devm_counter_match,
  1233. counter);
  1234. WARN_ON(rc);
  1235. }
  1236. EXPORT_SYMBOL_GPL(devm_counter_unregister);
  1237. static int __init counter_init(void)
  1238. {
  1239. return bus_register(&counter_bus_type);
  1240. }
  1241. static void __exit counter_exit(void)
  1242. {
  1243. bus_unregister(&counter_bus_type);
  1244. }
  1245. subsys_initcall(counter_init);
  1246. module_exit(counter_exit);
  1247. MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
  1248. MODULE_DESCRIPTION("Generic Counter interface");
  1249. MODULE_LICENSE("GPL v2");