drvmain.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889
  1. #include <linux/version.h>
  2. #include <linux/init.h>
  3. #include <linux/kernel.h> // printk()
  4. #include <linux/module.h> // THIS_MODULE
  5. #include <linux/kobject.h> // struct kobject
  6. #include <linux/timer.h>
  7. #include <linux/errno.h> // error codes
  8. #include <linux/sysfs.h>
  9. #include <linux/syscalls.h>
  10. #include <linux/workqueue.h>
  11. #include <asm/ioctls.h>
  12. #include <linux/spi/spidev.h>
  13. #include "defines.h"
  14. #include "kfile.h"
  15. #include "kspi.h"
  16. #include "ktiva.h"
  17. #include "sfsattrib.h"
  18. #include "kfirmware.h"
  19. #include "ksync.h"
  20. /////////////////////////////////////////////////////////////////////////////
  21. MODULE_LICENSE("Dual BSD/GPL");
  22. MODULE_AUTHOR("GfA");
  23. #define _SLEEP_DELAY_JIFFIES 5
  24. #define _IS_REVIVE_STATE(ret) ((ret) != -ECOMM)
  25. /////////////////////////////////////////////////////////////////////////////
  26. // sys fs
  27. static struct kobject *g_pKoGfa = NULL, *g_pKoTiva = NULL, *g_pKoBacklight = NULL, *g_pKoADC = NULL, *g_pKoFirmware = NULL;
  28. static bool g_bHasFwVersion = false;
  29. static atomic_t g_flgSysFsRunning;
  30. /////////////////////////////////////////////////////////////////////////////
  31. // worker threads
  32. static void _SysFsWorkProc(struct work_struct *work);
  33. static void _FwUploadWorkProc(struct work_struct *work);
  34. static void _BacklightWorkProc(struct work_struct *work);
  35. static struct workqueue_struct *g_pwq = NULL;
  36. static DECLARE_WORK(g_sysFsWorkObj, _SysFsWorkProc);
  37. static DECLARE_WORK(g_fwUploadWorkObj, _FwUploadWorkProc);
  38. static DECLARE_WORK(g_backLightWorkObj, _BacklightWorkProc);
  39. /////////////////////////////////////////////////////////////////////////////
  40. // timer
  41. static atomic_t g_flgTimerRunning;
  42. static struct timer_list g_timer_list;
  43. /////////////////////////////////////////////////////////////////////////////
  44. typedef enum _WorkerState
  45. {
  46. WS_SysFs,
  47. WS_FwUpload,
  48. WS_Backlight,
  49. WS_Idle
  50. }WorkerState;
  51. /////////////////////////////////////////////////////////////////////////////
  52. static bool _GetSysFsRunning(void)
  53. {
  54. return !!atomic_read(&g_flgSysFsRunning);
  55. }
  56. /////////////////////////////////////////////////////////////////////////////
  57. static void _SetSysFsRunning(bool bRunning)
  58. {
  59. atomic_set(&g_flgSysFsRunning, bRunning ? 1 : 0);
  60. }
  61. /////////////////////////////////////////////////////////////////////////////
  62. static bool _GetTimerRunning(void)
  63. {
  64. return !!atomic_read(&g_flgTimerRunning);
  65. }
  66. /////////////////////////////////////////////////////////////////////////////
  67. static void _SetTimerRunning(bool bRunning)
  68. {
  69. atomic_set(&g_flgTimerRunning, bRunning ? 1 : 0);
  70. }
  71. /////////////////////////////////////////////////////////////////////////////
  72. static void _WorkScheduler(unsigned long ptr)
  73. {
  74. static unsigned int nPass = 0;
  75. static WorkerState ws = WS_SysFs;
  76. // KALERT("%s: %d, %p\n", __FUNCTION__, _GetTimerRunning() ? 1 : 0, g_pwq);
  77. if(_GetTimerRunning())
  78. {
  79. if(KfwUploadInfoReady())
  80. ws = WS_FwUpload;
  81. else if(SfAttBacklightChanged())
  82. ws = WS_Backlight;
  83. else if(!_GetSysFsRunning())
  84. ws = WS_Idle;
  85. switch(ws)
  86. {
  87. case WS_SysFs:
  88. if(++nPass == 3)
  89. {
  90. if(!queue_work(g_pwq, &g_sysFsWorkObj))
  91. {
  92. KALERT("%s: queue_work failed\n", __FUNCTION__);
  93. }
  94. nPass = 0;
  95. }
  96. else
  97. {
  98. mod_timer(&g_timer_list, _TIMER_INTERVAL);
  99. }
  100. break;
  101. case WS_FwUpload:
  102. if(!queue_work(g_pwq, &g_fwUploadWorkObj))
  103. {
  104. KALERT("%s: queue_work failed\n", __FUNCTION__);
  105. }
  106. ws = WS_SysFs;
  107. nPass = 2;
  108. break;
  109. case WS_Backlight:
  110. if(!queue_work(g_pwq, &g_backLightWorkObj))
  111. {
  112. KALERT("%s: queue_work failed\n", __FUNCTION__);
  113. }
  114. ws = WS_SysFs;
  115. nPass = 2;
  116. break;
  117. case WS_Idle:
  118. mod_timer(&g_timer_list, _TIMER_INTERVAL);
  119. break;
  120. }
  121. }
  122. }
  123. /////////////////////////////////////////////////////////////////////////////
  124. // work queue
  125. // sysfs_notify
  126. // https://stackoverflow.com/questions/16367623/using-the-linux-sysfs-notify-call
  127. //
  128. static void _BacklightWorkProc(struct work_struct *work)
  129. {
  130. struct file *pfSpiDev = NULL;
  131. int ret;
  132. if((pfSpiDev = kf_open(_SPI_DEVICE, O_RDWR, 0)))
  133. {
  134. do
  135. {
  136. unsigned int nFrequency = SfAttGetBacklightFrequency();
  137. unsigned int nBrightness = SfAttGetBacklightBrightness();
  138. /////////////////////////////////////////////////////////////////
  139. if(!KSpiInit(pfSpiDev))
  140. {
  141. break;
  142. }
  143. /////////////////////////////////////////////////////////////////
  144. KALERT("%s: Set backlight frequency to %u Hz, brightness to %u %%\n", __FUNCTION__, nFrequency, nBrightness);
  145. if((ret = TivaCmdSetBacklight(pfSpiDev, nFrequency, nBrightness)) != 0)
  146. {
  147. KALERT("%s: TivaCmdSetBacklight failed: %d!\n", __FUNCTION__, ret);
  148. break;
  149. }
  150. }
  151. while(0);
  152. kf_close(pfSpiDev);
  153. }
  154. else
  155. {
  156. KALERT("%s: kf_open failed\n", __FUNCTION__);
  157. }
  158. if(_GetTimerRunning())
  159. {
  160. ksync_lock();
  161. mod_timer(&g_timer_list, _TIMER_INTERVAL);
  162. ksync_unlock();
  163. }
  164. }
  165. /////////////////////////////////////////////////////////////////////////////
  166. static void _FwUploadWorkProc(struct work_struct *work)
  167. {
  168. int nRet, i;
  169. bool bSuccess = false, bReset = true;
  170. unsigned long start = jiffies;
  171. struct file *pfSpiDev = NULL;
  172. TIVA_UPLOAD_INFO tui;
  173. if(!KfwQueryUploadInfo(&tui))
  174. {
  175. KALERT("%s: Upload info not ready!!\n", __FUNCTION__);
  176. return;
  177. }
  178. if((pfSpiDev = kf_open(_SPI_DEVICE, O_RDWR, 0)))
  179. {
  180. do
  181. {
  182. unsigned char stat = 0xFF;
  183. size_t nCntBlocks, nCbToSend, nCbBlock, nCntFlashPages;
  184. const unsigned char *pbToSend;
  185. if(!KSpiInit(pfSpiDev))
  186. {
  187. break;
  188. }
  189. /////////////////////////////////////////////////////////////////
  190. if(g_sw >= KFW_MIN_HAS_MATERIAL_NR_VERSION)
  191. {
  192. }
  193. if((nRet = TivaCmdStartBootloader(pfSpiDev)) < 0)
  194. {
  195. KALERT("%s: TivaCmdStartBootloader failed!\n", __FUNCTION__);
  196. break;
  197. }
  198. ksync_lock();
  199. g_hw = -1;
  200. g_sw = -1;
  201. g_bHasFwVersion = false;
  202. ksync_unlock();
  203. sysfs_notify(g_pKoFirmware, NULL, "version");
  204. KALERT("%s: Started bootloader!\n", __FUNCTION__);
  205. ksync_sleep_jiffies(_SLEEP_DELAY_JIFFIES);
  206. if((nRet = TivaCmdGetBootloaderStatus(pfSpiDev, &stat)) < 0)
  207. {
  208. KALERT("%s: TivaCmdGetBootloaderStatus failed!\n", __FUNCTION__);
  209. break;
  210. }
  211. KALERT("%s: Bootloader Status: 0x%02hhX\n", __FUNCTION__, stat);
  212. ksync_sleep_jiffies(_SLEEP_DELAY_JIFFIES);
  213. if((nRet = TivaCmdPing(pfSpiDev)) < 0)
  214. {
  215. KALERT("%s: TivaCmdPing failed!\n", __FUNCTION__);
  216. break;
  217. }
  218. KALERT("%s: Bootloader Ping success!\n", __FUNCTION__);
  219. ksync_sleep_jiffies(_SLEEP_DELAY_JIFFIES);
  220. if((nRet = TivaCmdGetBootloaderStatus(pfSpiDev, &stat)) < 0)
  221. {
  222. KALERT("%s: TivaCmdGetBootloaderStatus failed!\n", __FUNCTION__);
  223. break;
  224. }
  225. KALERT("%s: Bootloader Status: 0x%02hhX\n", __FUNCTION__, stat);
  226. ksync_sleep_jiffies(_SLEEP_DELAY_JIFFIES);
  227. /////////////////////////////////////////////////////////////////
  228. nCbToSend = (tui.nCbData + (KFW_MIN_UPLOAD_BLOCKSIZE - 1) / KFW_MIN_UPLOAD_BLOCKSIZE * KFW_MIN_UPLOAD_BLOCKSIZE);
  229. pbToSend = (const unsigned char*)tui.pData;
  230. nCntBlocks = (nCbToSend + KFW_DEFAULT_UPLOAD_BLOCKSIZE - 1) / KFW_DEFAULT_UPLOAD_BLOCKSIZE;
  231. nCntFlashPages = (nCntBlocks * KFW_DEFAULT_UPLOAD_BLOCKSIZE + KFW_FLASH_PAGE_SIZE - 1) / KFW_FLASH_PAGE_SIZE;
  232. KALERT("%s: Start Download of %zu Bytes (%zu Blocks) at Address 0x%08X\n", __FUNCTION__, nCbToSend, nCntBlocks, KFW_DEFAULT_BASE_ADDRESS);
  233. if((nRet = TivaCmdStartDownload(pfSpiDev, KFW_DEFAULT_BASE_ADDRESS, nCbToSend)) != 0)
  234. {
  235. KALERT("%s: TivaCmdStartDownload failed: %d!\n", __FUNCTION__, nRet);
  236. break;
  237. }
  238. ksync_sleep_jiffies((long)(nCntFlashPages * KFW_DEFAULT_PAGE_ERASE_TIME));
  239. if((nRet = TivaCmdGetBootloaderStatus(pfSpiDev, &stat)) < 0)
  240. {
  241. KALERT("%s: TivaCmdGetBootloaderStatus failed!\n", __FUNCTION__);
  242. break;
  243. }
  244. if(stat != COMMAND_RET_SUCCESS)
  245. {
  246. KALERT("%s: TivaCmdGetBootloaderStatus returned 0x%02hhX!\n", __FUNCTION__, stat);
  247. break;
  248. }
  249. KALERT("%s: Bootloader Status: 0x%02hhX\n", __FUNCTION__, stat);
  250. KALERT("%s: Sending data ...\n", __FUNCTION__);
  251. ksync_sleep_jiffies(_SLEEP_DELAY_JIFFIES);
  252. for(i = 0; i < nCntBlocks; ++i)
  253. {
  254. nCbBlock = _min(KFW_DEFAULT_UPLOAD_BLOCKSIZE, nCbToSend);
  255. if((nRet = TivaCmdSendDataBlock(pfSpiDev, pbToSend, nCbBlock)) != 0)
  256. {
  257. bReset = false;
  258. KALERT("%s: TivaCmdSendDataBlock failed!\n", __FUNCTION__);
  259. break;
  260. }
  261. pbToSend += nCbBlock;
  262. nCbToSend -= nCbBlock;
  263. if(i && !(i % 64))
  264. {
  265. KALERT("%s: %zu Blocks sent.\n", __FUNCTION__, i);
  266. }
  267. // ksync_sleep_jiffies(1);
  268. if((nRet = TivaCmdGetBootloaderStatus(pfSpiDev, &stat)) < 0)
  269. {
  270. bReset = false;
  271. KALERT("%s: TivaCmdGetBootloaderStatus failed!\n", __FUNCTION__);
  272. break;
  273. }
  274. if(stat != COMMAND_RET_SUCCESS)
  275. {
  276. bReset = false;
  277. KALERT("%s: TivaCmdGetBootloaderStatus returned 0x%02hhX!\n", __FUNCTION__, stat);
  278. break;
  279. }
  280. // ksync_sleep_jiffies(1);
  281. }
  282. KALERT("%s: %zu Blocks sent.\n", __FUNCTION__, i);
  283. ksync_sleep_jiffies(_SLEEP_DELAY_JIFFIES);
  284. /////////////////////////////////////////////////////////////////
  285. if(bReset)
  286. {
  287. if((nRet = TivaCmdReset(pfSpiDev)) < 0)
  288. {
  289. KALERT("%s: TivaCmdReset failed!\n", __FUNCTION__);
  290. break;
  291. }
  292. KALERT("%s: Started firmware!\n", __FUNCTION__);
  293. ksync_sleep_jiffies(_SLEEP_DELAY_JIFFIES);
  294. if((nRet = TivaCmdGetStatus(pfSpiDev, &stat)) < 0)
  295. {
  296. KALERT("%s: TivaCmdGetStatus failed!\n", __FUNCTION__);
  297. break;
  298. }
  299. KALERT("%s: FW Status: 0x%02hhX\n", __FUNCTION__, stat);
  300. bSuccess = true;
  301. }
  302. // KALERT("%s: data: 0x%p, cb: %zu, mat: %s, bld: %s\n", __FUNCTION__, tui.pData, tui.nCbData, tui.pszMat, tui.pszBld);
  303. }
  304. while(0);
  305. kf_close(pfSpiDev);
  306. SfAttLockFirmware(false);
  307. }
  308. else
  309. {
  310. KALERT("%s: kf_open failed\n", __FUNCTION__);
  311. }
  312. if(!bSuccess)
  313. {
  314. KALERT("%s: Firmware-Upload failed! Stopping all activities!\n", __FUNCTION__);
  315. }
  316. _SetSysFsRunning(bSuccess);
  317. if(_GetTimerRunning())
  318. {
  319. ksync_lock();
  320. mod_timer(&g_timer_list, _TIMER_INTERVAL);
  321. ksync_unlock();
  322. }
  323. KALERT("%s: jiffies: %lu\n", __FUNCTION__, _JIFFY_DIFF(jiffies, start));
  324. }
  325. /////////////////////////////////////////////////////////////////////////////
  326. static void _SysFsWorkProc(struct work_struct *work)
  327. {
  328. TIVA_ADC tadc;
  329. unsigned char stat;
  330. int hw, sw, ret;
  331. unsigned long long nUpTime;
  332. struct file *pfSpiDev = NULL;
  333. if((pfSpiDev = kf_open(_SPI_DEVICE, O_RDWR, 0)))
  334. {
  335. do
  336. {
  337. if(!KSpiInit(pfSpiDev))
  338. {
  339. break;
  340. }
  341. /////////////////////////////////////////////////////////////////
  342. #if !_SITARA_EGGELSBERG
  343. if( (ret = TivaCmdPing(pfSpiDev)) < 0 &&
  344. _IS_REVIVE_STATE(ret))
  345. {
  346. KALERT("%s: TivaCmdPing failed: %d - call TivaRevive\n", __FUNCTION__, ret);
  347. TivaRevive(pfSpiDev);
  348. }
  349. ksync_sleep_jiffies(_SLEEP_DELAY_JIFFIES);
  350. /////////////////////////////////////////////////////////////////
  351. // firmware
  352. if(!g_bHasFwVersion)
  353. {
  354. if((ret = TivaCmdGetFirmwareVersion(pfSpiDev, &hw, &sw)) == 0)
  355. {
  356. if((g_hw != hw) || (g_sw != sw))
  357. {
  358. ksync_lock();
  359. g_hw = hw;
  360. g_sw = sw;
  361. ksync_unlock();
  362. sysfs_notify(g_pKoFirmware, NULL, "version");
  363. KALERT("%s: TivaCmdGetFirmwareVersion: HW %d, SW: %d\n", __FUNCTION__, g_hw, g_sw);
  364. }
  365. g_bHasFwVersion = true;
  366. }
  367. else
  368. {
  369. if(_IS_REVIVE_STATE(ret))
  370. {
  371. KALERT("%s: TivaCmdGetFirmwareVersion failed: %d - call TivaRevive\n", __FUNCTION__, ret);
  372. TivaRevive(pfSpiDev);
  373. }
  374. break;
  375. }
  376. ksync_sleep_jiffies(_SLEEP_DELAY_JIFFIES);
  377. }
  378. /////////////////////////////////////////////////////////////////
  379. // ADC
  380. if((ret = TivaCmdGetADC(pfSpiDev, &tadc)) == 0)
  381. {
  382. bool bModified = false;
  383. if(g_tadc.UVers != tadc.UVers)
  384. {
  385. ksync_lock();
  386. g_tadc.UVers = tadc.UVers;
  387. ksync_unlock();
  388. bModified = true;
  389. sysfs_notify(g_pKoADC, NULL, "UVers");
  390. }
  391. if(g_tadc.UBatV3 != tadc.UBatV3)
  392. {
  393. ksync_lock();
  394. g_tadc.UBatV3 = tadc.UBatV3;
  395. ksync_unlock();
  396. bModified = true;
  397. sysfs_notify(g_pKoADC, NULL, "UBatV3");
  398. }
  399. if(g_tadc.Temp != tadc.Temp)
  400. {
  401. ksync_lock();
  402. g_tadc.Temp = tadc.Temp;
  403. ksync_unlock();
  404. bModified = true;
  405. sysfs_notify(g_pKoADC, NULL, "TempBoard");
  406. }
  407. if(g_tadc.UV5Vsys != tadc.UV5Vsys)
  408. {
  409. ksync_lock();
  410. g_tadc.UV5Vsys = tadc.UV5Vsys;
  411. ksync_unlock();
  412. bModified = true;
  413. sysfs_notify(g_pKoADC, NULL, "UV5Vsys");
  414. }
  415. if(g_tadc.UV3V6Bat != tadc.UV3V6Bat)
  416. {
  417. ksync_lock();
  418. g_tadc.UV3V6Bat = tadc.UV3V6Bat;
  419. ksync_unlock();
  420. bModified = true;
  421. sysfs_notify(g_pKoADC, NULL, "UV3V6Bat");
  422. }
  423. if(g_tadc.TempTIVA != tadc.TempTIVA)
  424. {
  425. ksync_lock();
  426. g_tadc.TempTIVA = tadc.TempTIVA;
  427. ksync_unlock();
  428. bModified = true;
  429. sysfs_notify(g_pKoADC, NULL, "TempTIVA");
  430. }
  431. if(bModified) // if any of the ADC values have changed, signal the binary file
  432. {
  433. sysfs_notify(g_pKoADC, NULL, "AdcBin");
  434. }
  435. }
  436. else if(_IS_REVIVE_STATE(ret))
  437. {
  438. KALERT("%s: TivaCmdGetADC failed: %d - call TivaRevive\n", __FUNCTION__, ret);
  439. TivaRevive(pfSpiDev);
  440. }
  441. ksync_sleep_jiffies(_SLEEP_DELAY_JIFFIES);
  442. /////////////////////////////////////////////////////////////////
  443. if((ret = TivaCmdGetUptime(pfSpiDev, &nUpTime)) == 0)
  444. {
  445. if(g_nUpTime != nUpTime)
  446. {
  447. ksync_lock();
  448. g_nUpTime = nUpTime;
  449. ksync_unlock();
  450. sysfs_notify(g_pKoTiva, NULL, "uptime");
  451. }
  452. }
  453. else if(_IS_REVIVE_STATE(ret))
  454. {
  455. KALERT("%s: TivaCmdGetUptime failed: %d - call TivaRevive\n", __FUNCTION__, ret);
  456. TivaRevive(pfSpiDev);
  457. }
  458. ksync_sleep_jiffies(_SLEEP_DELAY_JIFFIES);
  459. /////////////////////////////////////////////////////////////////
  460. #endif // _SITARA_EGGELSBERG
  461. if((ret = TivaCmdGetStatus(pfSpiDev, &stat)) == 0)
  462. {
  463. }
  464. else if(_IS_REVIVE_STATE(ret))
  465. {
  466. #if !_SITARA_EGGELSBERG
  467. KALERT("%s: TivaCmdGetStatus failed: %d - call TivaRevive\n", __FUNCTION__, ret);
  468. TivaRevive(pfSpiDev);
  469. #endif // _SITARA_EGGELSBERG
  470. }
  471. /////////////////////////////////////////////////////////////////
  472. // KALERT("Worker pass - jiffies: %ld - status: 0x%02hhX\n", _JIFFY_DIFF(jiffies, start), stat);
  473. }
  474. while(0);
  475. kf_close(pfSpiDev);
  476. }
  477. else
  478. {
  479. KALERT("%s: kf_open failed\n", __FUNCTION__);
  480. }
  481. if(_GetTimerRunning())
  482. {
  483. ksync_lock();
  484. mod_timer(&g_timer_list, _TIMER_INTERVAL);
  485. ksync_unlock();
  486. }
  487. }
  488. /////////////////////////////////////////////////////////////////////////////
  489. static int drv_init(void)
  490. {
  491. /////////////////////////////////////////////////////////////////////////
  492. do
  493. {
  494. if(!(g_pKoGfa = kobject_create_and_add("gfa", NULL)))
  495. {
  496. KALERT("kobject_create_and_add failed\n");
  497. break;
  498. }
  499. if(!(g_pKoTiva = kobject_create_and_add("tiva", g_pKoGfa)))
  500. {
  501. KALERT("kobject_create_and_add failed\n");
  502. break;
  503. }
  504. if(!(g_pKoBacklight = kobject_create_and_add("backlight", g_pKoTiva)))
  505. {
  506. KALERT("kobject_create_and_add failed\n");
  507. break;
  508. }
  509. if(!(g_pKoADC = kobject_create_and_add("adc", g_pKoTiva)))
  510. {
  511. KALERT("kobject_create_and_add failed\n");
  512. break;
  513. }
  514. if(!(g_pKoFirmware = kobject_create_and_add("firmware", g_pKoTiva)))
  515. {
  516. KALERT("kobject_create_and_add failed\n");
  517. break;
  518. }
  519. /////////////////////////////////////////////////////////////////////
  520. // generic
  521. if(sysfs_create_file(g_pKoTiva, &g_tivaUptimeAtt.attr))
  522. {
  523. KALERT("sysfs_create_file failed\n");
  524. break;
  525. }
  526. /////////////////////////////////////////////////////////////////////
  527. // firmware
  528. if(sysfs_create_file(g_pKoFirmware, &g_tivaVersionAtt.attr))
  529. {
  530. KALERT("sysfs_create_file failed\n");
  531. break;
  532. }
  533. if(SfAttInit())
  534. {
  535. if(sysfs_create_bin_file(g_pKoFirmware, &g_tivaFwImageAtt))
  536. {
  537. KALERT("sysfs_create_file failed\n");
  538. break;
  539. }
  540. }
  541. /////////////////////////////////////////////////////////////////////
  542. // backlight
  543. if(sysfs_create_file(g_pKoBacklight, &g_tivaBrightnessAtt.attr))
  544. {
  545. KALERT("sysfs_create_file failed\n");
  546. break;
  547. }
  548. if(sysfs_create_file(g_pKoBacklight, &g_tivaFrequencyAtt.attr))
  549. {
  550. KALERT("sysfs_create_file failed\n");
  551. break;
  552. }
  553. /////////////////////////////////////////////////////////////////////
  554. // ADC
  555. if(sysfs_create_file(g_pKoADC, &g_tivaUVersAtt.attr))
  556. {
  557. KALERT("sysfs_create_file failed\n");
  558. break;
  559. }
  560. if(sysfs_create_file(g_pKoADC, &g_tivaUBatV3Att.attr))
  561. {
  562. KALERT("sysfs_create_file failed\n");
  563. break;
  564. }
  565. if(sysfs_create_file(g_pKoADC, &g_tivaTempAtt.attr))
  566. {
  567. KALERT("sysfs_create_file failed\n");
  568. break;
  569. }
  570. if(sysfs_create_file(g_pKoADC, &g_tivaUV5VsysAtt.attr))
  571. {
  572. KALERT("sysfs_create_file failed\n");
  573. break;
  574. }
  575. if(sysfs_create_file(g_pKoADC, &g_tivaUV3V6BatAtt.attr))
  576. {
  577. KALERT("sysfs_create_file failed\n");
  578. break;
  579. }
  580. if(sysfs_create_file(g_pKoADC, &g_tivaTempTIVAAtt.attr))
  581. {
  582. KALERT("sysfs_create_file failed\n");
  583. break;
  584. }
  585. if(sysfs_create_bin_file(g_pKoADC, &g_tivaAdcBinAtt))
  586. {
  587. KALERT("sysfs_create_file failed\n");
  588. break;
  589. }
  590. /////////////////////////////////////////////////////////////////////
  591. if(!(g_pwq = create_workqueue("GfaWrk")))
  592. {
  593. KALERT("create_workqueue failed!\n");
  594. break;
  595. }
  596. /////////////////////////////////////////////////////////////////////
  597. init_timer(&g_timer_list);
  598. g_timer_list.function = _WorkScheduler;
  599. g_timer_list.data = 0;
  600. g_timer_list.expires = _TIMER_INTERVAL;
  601. add_timer(&g_timer_list);
  602. _SetTimerRunning(true);
  603. /////////////////////////////////////////////////////////////////////
  604. _SetSysFsRunning(true);
  605. if(!queue_work(g_pwq, &g_sysFsWorkObj))
  606. {
  607. KALERT("%s: queue_work failed\n", __FUNCTION__);
  608. break;
  609. }
  610. /////////////////////////////////////////////////////////////////////
  611. KALERT("%s, Ctx: \"%s\"-(%d), HZ: %d\n", __FUNCTION__, current->comm, current->pid, HZ);
  612. return 0;
  613. }
  614. while(0);
  615. /////////////////////////////////////////////////////////////////////////
  616. _SetSysFsRunning(false);
  617. if(_GetTimerRunning())
  618. {
  619. _SetTimerRunning(false);
  620. del_timer_sync(&g_timer_list);
  621. }
  622. if(g_pwq)
  623. {
  624. destroy_workqueue(g_pwq);
  625. g_pwq = NULL;
  626. }
  627. SfAttExit();
  628. if(g_pKoFirmware)
  629. {
  630. sysfs_remove_bin_file(g_pKoFirmware, &g_tivaFwImageAtt);
  631. sysfs_remove_file(g_pKoFirmware, &g_tivaVersionAtt.attr);
  632. kobject_put(g_pKoFirmware);
  633. g_pKoFirmware = NULL;
  634. }
  635. if(g_pKoADC)
  636. {
  637. sysfs_remove_file(g_pKoADC, &g_tivaUVersAtt.attr);
  638. sysfs_remove_file(g_pKoADC, &g_tivaUBatV3Att.attr);
  639. sysfs_remove_file(g_pKoADC, &g_tivaTempAtt.attr);
  640. sysfs_remove_file(g_pKoADC, &g_tivaUV5VsysAtt.attr);
  641. sysfs_remove_file(g_pKoADC, &g_tivaUV3V6BatAtt.attr);
  642. sysfs_remove_file(g_pKoADC, &g_tivaTempTIVAAtt.attr);
  643. sysfs_remove_bin_file(g_pKoADC, &g_tivaAdcBinAtt);
  644. kobject_put(g_pKoADC);
  645. g_pKoADC = NULL;
  646. }
  647. if(g_pKoBacklight)
  648. {
  649. sysfs_remove_file(g_pKoBacklight, &g_tivaBrightnessAtt.attr);
  650. sysfs_remove_file(g_pKoBacklight, &g_tivaFrequencyAtt.attr);
  651. kobject_put(g_pKoBacklight);
  652. g_pKoBacklight = NULL;
  653. }
  654. if(g_pKoTiva)
  655. {
  656. sysfs_remove_file(g_pKoTiva, &g_tivaUptimeAtt.attr);
  657. kobject_put(g_pKoTiva);
  658. g_pKoTiva = NULL;
  659. }
  660. if(g_pKoGfa)
  661. {
  662. kobject_put(g_pKoGfa);
  663. g_pKoGfa = NULL;
  664. }
  665. return -ENOMEM;
  666. }
  667. /////////////////////////////////////////////////////////////////////////////
  668. static void drv_exit(void)
  669. {
  670. _SetSysFsRunning(false);
  671. if(_GetTimerRunning())
  672. {
  673. _SetTimerRunning(false);
  674. del_timer_sync(&g_timer_list);
  675. }
  676. if(g_pwq)
  677. {
  678. destroy_workqueue(g_pwq);
  679. g_pwq = NULL;
  680. }
  681. SfAttExit();
  682. if(g_pKoFirmware)
  683. {
  684. sysfs_remove_bin_file(g_pKoFirmware, &g_tivaFwImageAtt);
  685. sysfs_remove_file(g_pKoFirmware, &g_tivaVersionAtt.attr);
  686. kobject_put(g_pKoFirmware);
  687. g_pKoFirmware = NULL;
  688. }
  689. if(g_pKoADC)
  690. {
  691. sysfs_remove_file(g_pKoADC, &g_tivaUVersAtt.attr);
  692. sysfs_remove_file(g_pKoADC, &g_tivaUBatV3Att.attr);
  693. sysfs_remove_file(g_pKoADC, &g_tivaTempAtt.attr);
  694. sysfs_remove_file(g_pKoADC, &g_tivaUV5VsysAtt.attr);
  695. sysfs_remove_file(g_pKoADC, &g_tivaUV3V6BatAtt.attr);
  696. sysfs_remove_file(g_pKoADC, &g_tivaTempTIVAAtt.attr);
  697. sysfs_remove_bin_file(g_pKoADC, &g_tivaAdcBinAtt);
  698. kobject_put(g_pKoADC);
  699. g_pKoADC = NULL;
  700. }
  701. if(g_pKoBacklight)
  702. {
  703. sysfs_remove_file(g_pKoBacklight, &g_tivaBrightnessAtt.attr);
  704. sysfs_remove_file(g_pKoBacklight, &g_tivaFrequencyAtt.attr);
  705. kobject_put(g_pKoBacklight);
  706. g_pKoBacklight = NULL;
  707. }
  708. if(g_pKoTiva)
  709. {
  710. sysfs_remove_file(g_pKoTiva, &g_tivaUptimeAtt.attr);
  711. kobject_put(g_pKoTiva);
  712. }
  713. if(g_pKoGfa)
  714. kobject_put(g_pKoGfa);
  715. KALERT("%s, Ctx: \"%s\"-(%d)\n", __FUNCTION__, current->comm, current->pid);
  716. }
  717. /////////////////////////////////////////////////////////////////////////////
  718. module_init(drv_init);
  719. module_exit(drv_exit);