synaptics_tcm_reflash.c 51 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193
  1. /*
  2. * Synaptics TCM touchscreen driver
  3. *
  4. * Copyright (C) 2017-2019 Synaptics Incorporated. All rights reserved.
  5. *
  6. * Copyright (C) 2017-2019 Scott Lin <[email protected]>
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
  19. * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
  20. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
  21. * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
  22. * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  23. * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
  24. * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
  25. * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  26. * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
  27. * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION DOES
  28. * NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES, SYNAPTICS'
  29. * TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT EXCEED ONE HUNDRED U.S.
  30. * DOLLARS.
  31. */
  32. #include <linux/crc32.h>
  33. #include <linux/firmware.h>
  34. #include "synaptics_tcm_core.h"
  35. #define STARTUP_REFLASH
  36. #define FORCE_REFLASH false
  37. #define ENABLE_SYSFS_INTERFACE true
  38. #define SYSFS_DIR_NAME "reflash"
  39. #define CUSTOM_DIR_NAME "custom"
  40. #define FW_IMAGE_NAME "synaptics_firmware.img"
  41. #define BOOT_CONFIG_ID "BOOT_CONFIG"
  42. #define APP_CODE_ID "APP_CODE"
  43. #define PROD_TEST_ID "APP_PROD_TEST"
  44. #define APP_CONFIG_ID "APP_CONFIG"
  45. #define DISP_CONFIG_ID "DISPLAY"
  46. #define FB_READY_COUNT 2
  47. #define FB_READY_WAIT_MS 100
  48. #define FB_READY_TIMEOUT_S 80
  49. #define IMAGE_FILE_MAGIC_VALUE 0x4818472b
  50. #define FLASH_AREA_MAGIC_VALUE 0x7c05e516
  51. #define BOOT_CONFIG_SIZE 8
  52. #define BOOT_CONFIG_SLOTS 16
  53. #define IMAGE_BUF_SIZE (512 * 1024)
  54. #define ERASE_FLASH_DELAY_MS 500
  55. #define WRITE_FLASH_DELAY_MS 20
  56. #define REFLASH (1 << 0)
  57. #define FORCE_UPDATE (1 << 1)
  58. #define APP_CFG_UPDATE (1 << 2)
  59. #define DISP_CFG_UPDATE (1 << 3)
  60. #define BOOT_CFG_UPDATE (1 << 4)
  61. #define BOOT_CFG_LOCKDOWN (1 << 5)
  62. #define reflash_write(p_name) \
  63. static int reflash_write_##p_name(void) \
  64. { \
  65. int retval; \
  66. unsigned int size; \
  67. unsigned int flash_addr; \
  68. struct syna_tcm_hcd *tcm_hcd = reflash_hcd->tcm_hcd; \
  69. const unsigned char *data; \
  70. \
  71. data = reflash_hcd->image_info.p_name.data; \
  72. size = reflash_hcd->image_info.p_name.size; \
  73. flash_addr = reflash_hcd->image_info.p_name.flash_addr; \
  74. \
  75. retval = reflash_write_flash(flash_addr, data, size); \
  76. if (retval < 0) { \
  77. LOGE(tcm_hcd->pdev->dev.parent, \
  78. "Failed to write to flash\n"); \
  79. return retval; \
  80. } \
  81. \
  82. return 0; \
  83. }
  84. #define reflash_erase(p_name) \
  85. static int reflash_erase_##p_name(void) \
  86. { \
  87. int retval; \
  88. unsigned int size; \
  89. unsigned int flash_addr; \
  90. unsigned int page_start; \
  91. unsigned int page_count; \
  92. struct syna_tcm_hcd *tcm_hcd = reflash_hcd->tcm_hcd; \
  93. \
  94. flash_addr = reflash_hcd->image_info.p_name.flash_addr; \
  95. \
  96. page_start = flash_addr / reflash_hcd->page_size; \
  97. \
  98. size = reflash_hcd->image_info.p_name.size; \
  99. page_count = ceil_div(size, reflash_hcd->page_size); \
  100. \
  101. LOGD(tcm_hcd->pdev->dev.parent, \
  102. "Page start = %d\n", \
  103. page_start); \
  104. \
  105. LOGD(tcm_hcd->pdev->dev.parent, \
  106. "Page count = %d\n", \
  107. page_count); \
  108. \
  109. retval = reflash_erase_flash(page_start, page_count); \
  110. if (retval < 0) { \
  111. LOGE(tcm_hcd->pdev->dev.parent, \
  112. "Failed to erase flash pages\n"); \
  113. return retval; \
  114. } \
  115. \
  116. return 0; \
  117. }
  118. #define reflash_update(p_name) \
  119. static int reflash_update_##p_name(bool reset) \
  120. { \
  121. int retval; \
  122. struct syna_tcm_hcd *tcm_hcd = reflash_hcd->tcm_hcd; \
  123. \
  124. retval = reflash_set_up_flash_access(); \
  125. if (retval < 0) { \
  126. LOGE(tcm_hcd->pdev->dev.parent, \
  127. "Failed to set up flash access\n"); \
  128. return retval; \
  129. } \
  130. \
  131. tcm_hcd->update_watchdog(tcm_hcd, false); \
  132. \
  133. retval = reflash_check_##p_name(); \
  134. if (retval < 0) { \
  135. LOGE(tcm_hcd->pdev->dev.parent, \
  136. "Failed "#p_name" partition check\n"); \
  137. reset = true; \
  138. goto reset; \
  139. } \
  140. \
  141. retval = reflash_erase_##p_name(); \
  142. if (retval < 0) { \
  143. LOGE(tcm_hcd->pdev->dev.parent, \
  144. "Failed to erase "#p_name" partition\n"); \
  145. reset = true; \
  146. goto reset; \
  147. } \
  148. \
  149. LOGN(tcm_hcd->pdev->dev.parent, \
  150. "Partition erased ("#p_name")\n"); \
  151. \
  152. retval = reflash_write_##p_name(); \
  153. if (retval < 0) { \
  154. LOGE(tcm_hcd->pdev->dev.parent, \
  155. "Failed to write "#p_name" partition\n"); \
  156. reset = true; \
  157. goto reset; \
  158. } \
  159. \
  160. LOGN(tcm_hcd->pdev->dev.parent, \
  161. "Partition written ("#p_name")\n"); \
  162. \
  163. retval = 0; \
  164. \
  165. reset: \
  166. if (!reset) \
  167. goto exit; \
  168. \
  169. if (tcm_hcd->reset(tcm_hcd, false, true) < 0) { \
  170. LOGE(tcm_hcd->pdev->dev.parent, \
  171. "Failed to do reset\n"); \
  172. } \
  173. \
  174. exit: \
  175. tcm_hcd->update_watchdog(tcm_hcd, true); \
  176. \
  177. return retval; \
  178. }
  179. #define reflash_show_data() \
  180. { \
  181. LOCK_BUFFER(reflash_hcd->read); \
  182. \
  183. readlen = MIN(count, reflash_hcd->read.data_length - pos); \
  184. \
  185. retval = secure_memcpy(buf, \
  186. count, \
  187. &reflash_hcd->read.buf[pos], \
  188. reflash_hcd->read.buf_size - pos, \
  189. readlen); \
  190. if (retval < 0) { \
  191. LOGE(tcm_hcd->pdev->dev.parent, \
  192. "Failed to copy read data\n"); \
  193. } else { \
  194. retval = readlen; \
  195. } \
  196. \
  197. UNLOCK_BUFFER(reflash_hcd->read); \
  198. }
  199. enum update_area {
  200. NONE = 0,
  201. FIRMWARE_CONFIG,
  202. CONFIG_ONLY,
  203. };
  204. struct app_config_header {
  205. unsigned short magic_value[4];
  206. unsigned char checksum[4];
  207. unsigned char length[2];
  208. unsigned char build_id[4];
  209. unsigned char customer_config_id[16];
  210. };
  211. struct area_descriptor {
  212. unsigned char magic_value[4];
  213. unsigned char id_string[16];
  214. unsigned char flags[4];
  215. unsigned char flash_addr_words[4];
  216. unsigned char length[4];
  217. unsigned char checksum[4];
  218. };
  219. struct block_data {
  220. const unsigned char *data;
  221. unsigned int size;
  222. unsigned int flash_addr;
  223. };
  224. struct image_info {
  225. struct block_data boot_config;
  226. struct block_data app_firmware;
  227. struct block_data prod_test_firmware;
  228. struct block_data app_config;
  229. struct block_data disp_config;
  230. };
  231. struct image_header {
  232. unsigned char magic_value[4];
  233. unsigned char num_of_areas[4];
  234. };
  235. struct boot_config {
  236. union {
  237. unsigned char i2c_address;
  238. struct {
  239. unsigned char cpha:1;
  240. unsigned char cpol:1;
  241. unsigned char word0_b2__7:6;
  242. } __packed;
  243. };
  244. unsigned char attn_polarity:1;
  245. unsigned char attn_drive:2;
  246. unsigned char attn_pullup:1;
  247. unsigned char word0_b12__14:3;
  248. unsigned char used:1;
  249. unsigned short customer_part_id;
  250. unsigned short boot_timeout;
  251. unsigned short continue_on_reset:1;
  252. unsigned short word3_b1__15:15;
  253. } __packed;
  254. struct reflash_hcd {
  255. bool force_update;
  256. bool disp_cfg_update;
  257. const unsigned char *image;
  258. unsigned char *image_buf;
  259. unsigned int image_size;
  260. unsigned int page_size;
  261. unsigned int write_block_size;
  262. unsigned int max_write_payload_size;
  263. const struct firmware *fw_entry;
  264. struct mutex reflash_mutex;
  265. struct kobject *sysfs_dir;
  266. struct kobject *custom_dir;
  267. struct work_struct work;
  268. struct workqueue_struct *workqueue;
  269. struct image_info image_info;
  270. struct syna_tcm_buffer out;
  271. struct syna_tcm_buffer resp;
  272. struct syna_tcm_buffer read;
  273. struct syna_tcm_hcd *tcm_hcd;
  274. };
  275. DECLARE_COMPLETION(reflash_remove_complete);
  276. static struct reflash_hcd *reflash_hcd;
  277. static int reflash_get_fw_image(void);
  278. static int reflash_read_data(enum flash_area area, bool run_app_firmware,
  279. struct syna_tcm_buffer *output);
  280. static int reflash_update_custom_otp(const unsigned char *data,
  281. unsigned int offset, unsigned int datalen);
  282. static int reflash_update_custom_lcm(const unsigned char *data,
  283. unsigned int offset, unsigned int datalen);
  284. static int reflash_update_custom_oem(const unsigned char *data,
  285. unsigned int offset, unsigned int datalen);
  286. static int reflash_update_boot_config(bool lock);
  287. static int reflash_update_app_config(bool reset);
  288. static int reflash_update_disp_config(bool reset);
  289. static int reflash_do_reflash(void);
  290. STORE_PROTOTYPE(reflash, reflash);
  291. static struct device_attribute *attrs[] = {
  292. ATTRIFY(reflash),
  293. };
  294. static ssize_t reflash_sysfs_image_store(struct file *data_file,
  295. struct kobject *kobj, struct bin_attribute *attributes,
  296. char *buf, loff_t pos, size_t count);
  297. static ssize_t reflash_sysfs_lockdown_show(struct file *data_file,
  298. struct kobject *kobj, struct bin_attribute *attributes,
  299. char *buf, loff_t pos, size_t count);
  300. static ssize_t reflash_sysfs_lockdown_store(struct file *data_file,
  301. struct kobject *kobj, struct bin_attribute *attributes,
  302. char *buf, loff_t pos, size_t count);
  303. static ssize_t reflash_sysfs_lcm_show(struct file *data_file,
  304. struct kobject *kobj, struct bin_attribute *attributes,
  305. char *buf, loff_t pos, size_t count);
  306. static ssize_t reflash_sysfs_lcm_store(struct file *data_file,
  307. struct kobject *kobj, struct bin_attribute *attributes,
  308. char *buf, loff_t pos, size_t count);
  309. static ssize_t reflash_sysfs_oem_show(struct file *data_file,
  310. struct kobject *kobj, struct bin_attribute *attributes,
  311. char *buf, loff_t pos, size_t count);
  312. static ssize_t reflash_sysfs_oem_store(struct file *data_file,
  313. struct kobject *kobj, struct bin_attribute *attributes,
  314. char *buf, loff_t pos, size_t count);
  315. static struct bin_attribute bin_attrs[] = {
  316. {
  317. .attr = {
  318. .name = "image",
  319. .mode = 0220,
  320. },
  321. .size = 0,
  322. .write = reflash_sysfs_image_store,
  323. },
  324. {
  325. .attr = {
  326. .name = "lockdown",
  327. .mode = 0664,
  328. },
  329. .size = 0,
  330. .read = reflash_sysfs_lockdown_show,
  331. .write = reflash_sysfs_lockdown_store,
  332. },
  333. {
  334. .attr = {
  335. .name = "lcm",
  336. .mode = 0664,
  337. },
  338. .size = 0,
  339. .read = reflash_sysfs_lcm_show,
  340. .write = reflash_sysfs_lcm_store,
  341. },
  342. {
  343. .attr = {
  344. .name = "oem",
  345. .mode = 0664,
  346. },
  347. .size = 0,
  348. .read = reflash_sysfs_oem_show,
  349. .write = reflash_sysfs_oem_store,
  350. },
  351. };
  352. static ssize_t reflash_sysfs_reflash_store(struct device *dev,
  353. struct device_attribute *attr, const char *buf, size_t count)
  354. {
  355. int retval;
  356. unsigned int input;
  357. struct syna_tcm_hcd *tcm_hcd = reflash_hcd->tcm_hcd;
  358. if (kstrtouint(buf, 10, &input))
  359. return -EINVAL;
  360. mutex_lock(&tcm_hcd->extif_mutex);
  361. pm_stay_awake(&tcm_hcd->pdev->dev);
  362. mutex_lock(&reflash_hcd->reflash_mutex);
  363. if (reflash_hcd->image_size != 0)
  364. reflash_hcd->image = reflash_hcd->image_buf;
  365. reflash_hcd->force_update = input & FORCE_UPDATE ? true : false;
  366. if (input & REFLASH || input & FORCE_UPDATE) {
  367. retval = reflash_do_reflash();
  368. if (retval < 0) {
  369. LOGE(tcm_hcd->pdev->dev.parent,
  370. "Failed to do reflash\n");
  371. goto exit;
  372. }
  373. }
  374. if ((input & ~(REFLASH | FORCE_UPDATE)) == 0) {
  375. retval = count;
  376. goto exit;
  377. }
  378. retval = reflash_get_fw_image();
  379. if (retval < 0) {
  380. LOGD(tcm_hcd->pdev->dev.parent,
  381. "Failed to get firmware image\n");
  382. goto exit;
  383. }
  384. if (input & BOOT_CFG_LOCKDOWN) {
  385. retval = reflash_update_boot_config(true);
  386. if (retval < 0) {
  387. LOGE(tcm_hcd->pdev->dev.parent,
  388. "Failed to lockdown boot config\n");
  389. goto exit;
  390. }
  391. } else if (input & BOOT_CFG_UPDATE) {
  392. retval = reflash_update_boot_config(false);
  393. if (retval < 0) {
  394. LOGE(tcm_hcd->pdev->dev.parent,
  395. "Failed to update boot config\n");
  396. goto exit;
  397. }
  398. }
  399. if (input & REFLASH || input & FORCE_UPDATE) {
  400. retval = count;
  401. goto exit;
  402. }
  403. if (input & DISP_CFG_UPDATE) {
  404. if (input & APP_CFG_UPDATE)
  405. retval = reflash_update_disp_config(false);
  406. else
  407. retval = reflash_update_disp_config(true);
  408. if (retval < 0) {
  409. LOGE(tcm_hcd->pdev->dev.parent,
  410. "Failed to reflash display config\n");
  411. goto exit;
  412. }
  413. }
  414. if (input & APP_CFG_UPDATE) {
  415. retval = reflash_update_app_config(true);
  416. if (retval < 0) {
  417. LOGE(tcm_hcd->pdev->dev.parent,
  418. "Failed to reflash application config\n");
  419. goto exit;
  420. }
  421. }
  422. retval = count;
  423. exit:
  424. if (reflash_hcd->fw_entry) {
  425. release_firmware(reflash_hcd->fw_entry);
  426. reflash_hcd->fw_entry = NULL;
  427. }
  428. reflash_hcd->image = NULL;
  429. reflash_hcd->image_size = 0;
  430. reflash_hcd->force_update = FORCE_REFLASH;
  431. mutex_unlock(&reflash_hcd->reflash_mutex);
  432. pm_relax(&tcm_hcd->pdev->dev);
  433. mutex_unlock(&tcm_hcd->extif_mutex);
  434. return retval;
  435. }
  436. static ssize_t reflash_sysfs_image_store(struct file *data_file,
  437. struct kobject *kobj, struct bin_attribute *attributes,
  438. char *buf, loff_t pos, size_t count)
  439. {
  440. int retval;
  441. struct syna_tcm_hcd *tcm_hcd = reflash_hcd->tcm_hcd;
  442. mutex_lock(&tcm_hcd->extif_mutex);
  443. retval = secure_memcpy(&reflash_hcd->image_buf[pos],
  444. IMAGE_BUF_SIZE - pos,
  445. buf,
  446. count,
  447. count);
  448. if (retval < 0) {
  449. LOGE(tcm_hcd->pdev->dev.parent,
  450. "Failed to copy firmware image data\n");
  451. reflash_hcd->image_size = 0;
  452. goto exit;
  453. }
  454. reflash_hcd->image_size = pos + count;
  455. retval = count;
  456. exit:
  457. mutex_unlock(&tcm_hcd->extif_mutex);
  458. return retval;
  459. }
  460. static ssize_t reflash_sysfs_lockdown_show(struct file *data_file,
  461. struct kobject *kobj, struct bin_attribute *attributes,
  462. char *buf, loff_t pos, size_t count)
  463. {
  464. int retval;
  465. unsigned int readlen;
  466. struct syna_tcm_hcd *tcm_hcd = reflash_hcd->tcm_hcd;
  467. mutex_lock(&tcm_hcd->extif_mutex);
  468. mutex_lock(&reflash_hcd->reflash_mutex);
  469. retval = reflash_read_data(CUSTOM_OTP, true, NULL);
  470. if (retval < 0) {
  471. LOGE(tcm_hcd->pdev->dev.parent,
  472. "Failed to read lockdown data\n");
  473. goto exit;
  474. }
  475. reflash_show_data();
  476. exit:
  477. mutex_unlock(&reflash_hcd->reflash_mutex);
  478. mutex_unlock(&tcm_hcd->extif_mutex);
  479. return retval;
  480. }
  481. static ssize_t reflash_sysfs_lockdown_store(struct file *data_file,
  482. struct kobject *kobj, struct bin_attribute *attributes,
  483. char *buf, loff_t pos, size_t count)
  484. {
  485. int retval;
  486. struct syna_tcm_hcd *tcm_hcd = reflash_hcd->tcm_hcd;
  487. mutex_lock(&tcm_hcd->extif_mutex);
  488. pm_stay_awake(&tcm_hcd->pdev->dev);
  489. mutex_lock(&reflash_hcd->reflash_mutex);
  490. retval = reflash_update_custom_otp(buf, pos, count);
  491. if (retval < 0) {
  492. LOGE(tcm_hcd->pdev->dev.parent,
  493. "Failed to update custom OTP data\n");
  494. goto exit;
  495. }
  496. retval = count;
  497. exit:
  498. mutex_unlock(&reflash_hcd->reflash_mutex);
  499. pm_relax(&tcm_hcd->pdev->dev);
  500. mutex_unlock(&tcm_hcd->extif_mutex);
  501. return retval;
  502. }
  503. static ssize_t reflash_sysfs_lcm_show(struct file *data_file,
  504. struct kobject *kobj, struct bin_attribute *attributes,
  505. char *buf, loff_t pos, size_t count)
  506. {
  507. int retval;
  508. unsigned int readlen;
  509. struct syna_tcm_hcd *tcm_hcd = reflash_hcd->tcm_hcd;
  510. mutex_lock(&tcm_hcd->extif_mutex);
  511. mutex_lock(&reflash_hcd->reflash_mutex);
  512. retval = reflash_read_data(CUSTOM_LCM, true, NULL);
  513. if (retval < 0) {
  514. LOGE(tcm_hcd->pdev->dev.parent,
  515. "Failed to read LCM data\n");
  516. goto exit;
  517. }
  518. reflash_show_data();
  519. exit:
  520. mutex_unlock(&reflash_hcd->reflash_mutex);
  521. mutex_unlock(&tcm_hcd->extif_mutex);
  522. return retval;
  523. }
  524. static ssize_t reflash_sysfs_lcm_store(struct file *data_file,
  525. struct kobject *kobj, struct bin_attribute *attributes,
  526. char *buf, loff_t pos, size_t count)
  527. {
  528. int retval;
  529. struct syna_tcm_hcd *tcm_hcd = reflash_hcd->tcm_hcd;
  530. mutex_lock(&tcm_hcd->extif_mutex);
  531. pm_stay_awake(&tcm_hcd->pdev->dev);
  532. mutex_lock(&reflash_hcd->reflash_mutex);
  533. retval = reflash_update_custom_lcm(buf, pos, count);
  534. if (retval < 0) {
  535. LOGE(tcm_hcd->pdev->dev.parent,
  536. "Failed to update custom LCM data\n");
  537. goto exit;
  538. }
  539. retval = count;
  540. exit:
  541. mutex_unlock(&reflash_hcd->reflash_mutex);
  542. pm_relax(&tcm_hcd->pdev->dev);
  543. mutex_unlock(&tcm_hcd->extif_mutex);
  544. return retval;
  545. }
  546. static ssize_t reflash_sysfs_oem_show(struct file *data_file,
  547. struct kobject *kobj, struct bin_attribute *attributes,
  548. char *buf, loff_t pos, size_t count)
  549. {
  550. int retval;
  551. unsigned int readlen;
  552. struct syna_tcm_hcd *tcm_hcd = reflash_hcd->tcm_hcd;
  553. mutex_lock(&tcm_hcd->extif_mutex);
  554. mutex_lock(&reflash_hcd->reflash_mutex);
  555. retval = reflash_read_data(CUSTOM_OEM, true, NULL);
  556. if (retval < 0) {
  557. LOGE(tcm_hcd->pdev->dev.parent,
  558. "Failed to read OEM data\n");
  559. goto exit;
  560. }
  561. reflash_show_data();
  562. exit:
  563. mutex_unlock(&reflash_hcd->reflash_mutex);
  564. mutex_unlock(&tcm_hcd->extif_mutex);
  565. return retval;
  566. }
  567. static ssize_t reflash_sysfs_oem_store(struct file *data_file,
  568. struct kobject *kobj, struct bin_attribute *attributes,
  569. char *buf, loff_t pos, size_t count)
  570. {
  571. int retval;
  572. struct syna_tcm_hcd *tcm_hcd = reflash_hcd->tcm_hcd;
  573. mutex_lock(&tcm_hcd->extif_mutex);
  574. pm_stay_awake(&tcm_hcd->pdev->dev);
  575. mutex_lock(&reflash_hcd->reflash_mutex);
  576. retval = reflash_update_custom_oem(buf, pos, count);
  577. if (retval < 0) {
  578. LOGE(tcm_hcd->pdev->dev.parent,
  579. "Failed to update custom OEM data\n");
  580. goto exit;
  581. }
  582. retval = count;
  583. exit:
  584. mutex_unlock(&reflash_hcd->reflash_mutex);
  585. pm_relax(&tcm_hcd->pdev->dev);
  586. mutex_unlock(&tcm_hcd->extif_mutex);
  587. return retval;
  588. }
  589. static int reflash_set_up_flash_access(void)
  590. {
  591. int retval;
  592. unsigned int temp;
  593. struct syna_tcm_hcd *tcm_hcd = reflash_hcd->tcm_hcd;
  594. retval = tcm_hcd->identify(tcm_hcd, true);
  595. if (retval < 0) {
  596. LOGE(tcm_hcd->pdev->dev.parent,
  597. "Failed to do identification\n");
  598. return retval;
  599. }
  600. if (tcm_hcd->id_info.mode == MODE_APPLICATION) {
  601. retval = tcm_hcd->switch_mode(tcm_hcd, FW_MODE_BOOTLOADER);
  602. if (retval < 0) {
  603. LOGE(tcm_hcd->pdev->dev.parent,
  604. "Failed to enter bootloader mode\n");
  605. return retval;
  606. }
  607. }
  608. temp = tcm_hcd->boot_info.write_block_size_words;
  609. reflash_hcd->write_block_size = temp * 2;
  610. temp = le2_to_uint(tcm_hcd->boot_info.erase_page_size_words);
  611. reflash_hcd->page_size = temp * 2;
  612. temp = le2_to_uint(tcm_hcd->boot_info.max_write_payload_size);
  613. reflash_hcd->max_write_payload_size = temp;
  614. LOGD(tcm_hcd->pdev->dev.parent,
  615. "Write block size = %d\n",
  616. reflash_hcd->write_block_size);
  617. LOGD(tcm_hcd->pdev->dev.parent,
  618. "Page size = %d\n",
  619. reflash_hcd->page_size);
  620. LOGD(tcm_hcd->pdev->dev.parent,
  621. "Max write payload size = %d\n",
  622. reflash_hcd->max_write_payload_size);
  623. if (reflash_hcd->write_block_size > (tcm_hcd->wr_chunk_size - 5)) {
  624. LOGE(tcm_hcd->pdev->dev.parent,
  625. "Write size greater than available chunk space\n");
  626. return -EINVAL;
  627. }
  628. return 0;
  629. }
  630. static int reflash_parse_fw_image(void)
  631. {
  632. unsigned int idx;
  633. unsigned int addr;
  634. unsigned int offset;
  635. unsigned int length;
  636. unsigned int checksum;
  637. unsigned int flash_addr;
  638. unsigned int magic_value;
  639. unsigned int num_of_areas;
  640. struct image_header *header;
  641. struct image_info *image_info;
  642. struct area_descriptor *descriptor;
  643. struct syna_tcm_hcd *tcm_hcd = reflash_hcd->tcm_hcd;
  644. const unsigned char *image;
  645. const unsigned char *content;
  646. image = reflash_hcd->image;
  647. image_info = &reflash_hcd->image_info;
  648. header = (struct image_header *)image;
  649. reflash_hcd->disp_cfg_update = false;
  650. magic_value = le4_to_uint(header->magic_value);
  651. if (magic_value != IMAGE_FILE_MAGIC_VALUE) {
  652. LOGE(tcm_hcd->pdev->dev.parent,
  653. "Invalid image file magic value\n");
  654. return -EINVAL;
  655. }
  656. memset(image_info, 0x00, sizeof(*image_info));
  657. offset = sizeof(*header);
  658. num_of_areas = le4_to_uint(header->num_of_areas);
  659. for (idx = 0; idx < num_of_areas; idx++) {
  660. addr = le4_to_uint(image + offset);
  661. descriptor = (struct area_descriptor *)(image + addr);
  662. offset += 4;
  663. magic_value = le4_to_uint(descriptor->magic_value);
  664. if (magic_value != FLASH_AREA_MAGIC_VALUE)
  665. continue;
  666. length = le4_to_uint(descriptor->length);
  667. content = (unsigned char *)descriptor + sizeof(*descriptor);
  668. flash_addr = le4_to_uint(descriptor->flash_addr_words) * 2;
  669. checksum = le4_to_uint(descriptor->checksum);
  670. if (!memcmp((char *)descriptor->id_string,
  671. BOOT_CONFIG_ID,
  672. strlen(BOOT_CONFIG_ID))) {
  673. if (checksum != (crc32(~0, content, length) ^ ~0)) {
  674. LOGE(tcm_hcd->pdev->dev.parent,
  675. "Boot config checksum error\n");
  676. return -EINVAL;
  677. }
  678. image_info->boot_config.size = length;
  679. image_info->boot_config.data = content;
  680. image_info->boot_config.flash_addr = flash_addr;
  681. LOGD(tcm_hcd->pdev->dev.parent,
  682. "Boot config size = %d\n",
  683. length);
  684. LOGD(tcm_hcd->pdev->dev.parent,
  685. "Boot config flash address = 0x%08x\n",
  686. flash_addr);
  687. } else if (!memcmp((char *)descriptor->id_string,
  688. APP_CODE_ID,
  689. strlen(APP_CODE_ID))) {
  690. if (checksum != (crc32(~0, content, length) ^ ~0)) {
  691. LOGE(tcm_hcd->pdev->dev.parent,
  692. "APP firmware checksum error\n");
  693. return -EINVAL;
  694. }
  695. image_info->app_firmware.size = length;
  696. image_info->app_firmware.data = content;
  697. image_info->app_firmware.flash_addr = flash_addr;
  698. LOGD(tcm_hcd->pdev->dev.parent,
  699. "Application firmware size = %d\n",
  700. length);
  701. LOGD(tcm_hcd->pdev->dev.parent,
  702. "Application firmware flash address = 0x%08x\n",
  703. flash_addr);
  704. } else if (!memcmp((char *)descriptor->id_string,
  705. PROD_TEST_ID,
  706. strlen(PROD_TEST_ID))) {
  707. if (checksum != (crc32(~0, content, length) ^ ~0)) {
  708. LOGE(tcm_hcd->pdev->dev.parent,
  709. "Production test checksum error\n");
  710. return -EINVAL;
  711. }
  712. image_info->prod_test_firmware.size = length;
  713. image_info->prod_test_firmware.data = content;
  714. image_info->prod_test_firmware.flash_addr = flash_addr;
  715. LOGD(tcm_hcd->pdev->dev.parent,
  716. "Production test firmware size = %d\n",
  717. length);
  718. LOGD(tcm_hcd->pdev->dev.parent,
  719. "Production test flash address = 0x%08x\n",
  720. flash_addr);
  721. } else if (!memcmp((char *)descriptor->id_string,
  722. APP_CONFIG_ID,
  723. strlen(APP_CONFIG_ID))) {
  724. if (checksum != (crc32(~0, content, length) ^ ~0)) {
  725. LOGE(tcm_hcd->pdev->dev.parent,
  726. "Application config checksum error\n");
  727. return -EINVAL;
  728. }
  729. image_info->app_config.size = length;
  730. image_info->app_config.data = content;
  731. image_info->app_config.flash_addr = flash_addr;
  732. LOGD(tcm_hcd->pdev->dev.parent,
  733. "Application config size = %d\n",
  734. length);
  735. LOGD(tcm_hcd->pdev->dev.parent,
  736. "Application config flash address = 0x%08x\n",
  737. flash_addr);
  738. } else if (!memcmp((char *)descriptor->id_string,
  739. DISP_CONFIG_ID,
  740. strlen(DISP_CONFIG_ID))) {
  741. if (checksum != (crc32(~0, content, length) ^ ~0)) {
  742. LOGE(tcm_hcd->pdev->dev.parent,
  743. "Display config checksum error\n");
  744. return -EINVAL;
  745. }
  746. reflash_hcd->disp_cfg_update = true;
  747. image_info->disp_config.size = length;
  748. image_info->disp_config.data = content;
  749. image_info->disp_config.flash_addr = flash_addr;
  750. LOGD(tcm_hcd->pdev->dev.parent,
  751. "Display config size = %d\n",
  752. length);
  753. LOGD(tcm_hcd->pdev->dev.parent,
  754. "Display config flash address = 0x%08x\n",
  755. flash_addr);
  756. }
  757. }
  758. return 0;
  759. }
  760. static int reflash_get_fw_image(void)
  761. {
  762. int retval;
  763. const char *fw_name;
  764. struct syna_tcm_hcd *tcm_hcd = reflash_hcd->tcm_hcd;
  765. const struct syna_tcm_board_data *bdata = tcm_hcd->hw_if->bdata;
  766. if (bdata->fw_name)
  767. fw_name = bdata->fw_name;
  768. else
  769. fw_name = FW_IMAGE_NAME;
  770. if (reflash_hcd->image == NULL) {
  771. retval = request_firmware(&reflash_hcd->fw_entry, fw_name,
  772. tcm_hcd->pdev->dev.parent);
  773. if (retval < 0) {
  774. LOGD(tcm_hcd->pdev->dev.parent,
  775. "Failed to request %s\n",
  776. fw_name);
  777. return retval;
  778. }
  779. LOGD(tcm_hcd->pdev->dev.parent,
  780. "Firmware image size = %d\n",
  781. (unsigned int)reflash_hcd->fw_entry->size);
  782. reflash_hcd->image = reflash_hcd->fw_entry->data;
  783. reflash_hcd->image_size = reflash_hcd->fw_entry->size;
  784. }
  785. retval = reflash_parse_fw_image();
  786. if (retval < 0) {
  787. LOGE(tcm_hcd->pdev->dev.parent,
  788. "Failed to parse firmware image\n");
  789. return retval;
  790. }
  791. return 0;
  792. }
  793. static enum update_area reflash_compare_id_info(void)
  794. {
  795. enum update_area update_area;
  796. unsigned int idx;
  797. unsigned int image_fw_id;
  798. unsigned int device_fw_id;
  799. unsigned char *image_config_id;
  800. unsigned char *device_config_id;
  801. struct app_config_header *header;
  802. struct syna_tcm_hcd *tcm_hcd = reflash_hcd->tcm_hcd;
  803. const unsigned char *app_config_data;
  804. update_area = NONE;
  805. if (reflash_hcd->image_info.app_config.size < sizeof(*header)) {
  806. LOGE(tcm_hcd->pdev->dev.parent,
  807. "Invalid application config in image file\n");
  808. goto exit;
  809. }
  810. app_config_data = reflash_hcd->image_info.app_config.data;
  811. header = (struct app_config_header *)app_config_data;
  812. if (reflash_hcd->force_update) {
  813. update_area = FIRMWARE_CONFIG;
  814. goto exit;
  815. }
  816. if (tcm_hcd->id_info.mode != MODE_APPLICATION) {
  817. update_area = FIRMWARE_CONFIG;
  818. goto exit;
  819. }
  820. image_fw_id = le4_to_uint(header->build_id);
  821. device_fw_id = tcm_hcd->packrat_number;
  822. if (image_fw_id > device_fw_id) {
  823. LOGN(tcm_hcd->pdev->dev.parent,
  824. "Image firmware ID newer than device firmware ID\n");
  825. update_area = FIRMWARE_CONFIG;
  826. goto exit;
  827. } else if (image_fw_id < device_fw_id) {
  828. LOGN(tcm_hcd->pdev->dev.parent,
  829. "Image firmware ID older than device firmware ID\n");
  830. update_area = NONE;
  831. goto exit;
  832. }
  833. image_config_id = header->customer_config_id;
  834. device_config_id = tcm_hcd->app_info.customer_config_id;
  835. for (idx = 0; idx < 16; idx++) {
  836. if (image_config_id[idx] > device_config_id[idx]) {
  837. LOGN(tcm_hcd->pdev->dev.parent,
  838. "Image config ID newer than device's ID\n");
  839. update_area = CONFIG_ONLY;
  840. goto exit;
  841. } else if (image_config_id[idx] < device_config_id[idx]) {
  842. LOGN(tcm_hcd->pdev->dev.parent,
  843. "Image config ID older than device's ID\n");
  844. update_area = NONE;
  845. goto exit;
  846. }
  847. }
  848. update_area = NONE;
  849. exit:
  850. if (update_area == NONE)
  851. LOGD(tcm_hcd->pdev->dev.parent, "No need to do reflash\n");
  852. else
  853. LOGD(tcm_hcd->pdev->dev.parent,
  854. "Updating %s\n",
  855. update_area == FIRMWARE_CONFIG ?
  856. "firmware and config" :
  857. "config only");
  858. return update_area;
  859. }
  860. static int reflash_read_flash(unsigned int address, unsigned char *data,
  861. unsigned int datalen)
  862. {
  863. int retval;
  864. unsigned int length_words;
  865. unsigned int flash_addr_words;
  866. struct syna_tcm_hcd *tcm_hcd = reflash_hcd->tcm_hcd;
  867. LOCK_BUFFER(reflash_hcd->out);
  868. retval = syna_tcm_alloc_mem(tcm_hcd,
  869. &reflash_hcd->out,
  870. 6);
  871. if (retval < 0) {
  872. LOGE(tcm_hcd->pdev->dev.parent,
  873. "Failed to allocate memory for reflash_hcd->out.buf\n");
  874. UNLOCK_BUFFER(reflash_hcd->out);
  875. return retval;
  876. }
  877. length_words = datalen / 2;
  878. flash_addr_words = address / 2;
  879. reflash_hcd->out.buf[0] = (unsigned char)flash_addr_words;
  880. reflash_hcd->out.buf[1] = (unsigned char)(flash_addr_words >> 8);
  881. reflash_hcd->out.buf[2] = (unsigned char)(flash_addr_words >> 16);
  882. reflash_hcd->out.buf[3] = (unsigned char)(flash_addr_words >> 24);
  883. reflash_hcd->out.buf[4] = (unsigned char)length_words;
  884. reflash_hcd->out.buf[5] = (unsigned char)(length_words >> 8);
  885. LOCK_BUFFER(reflash_hcd->resp);
  886. retval = tcm_hcd->write_message(tcm_hcd,
  887. CMD_READ_FLASH,
  888. reflash_hcd->out.buf,
  889. 6,
  890. &reflash_hcd->resp.buf,
  891. &reflash_hcd->resp.buf_size,
  892. &reflash_hcd->resp.data_length,
  893. NULL,
  894. 0);
  895. if (retval < 0) {
  896. LOGE(tcm_hcd->pdev->dev.parent,
  897. "Failed to write command %s\n",
  898. STR(CMD_READ_FLASH));
  899. UNLOCK_BUFFER(reflash_hcd->resp);
  900. UNLOCK_BUFFER(reflash_hcd->out);
  901. return retval;
  902. }
  903. UNLOCK_BUFFER(reflash_hcd->out);
  904. if (reflash_hcd->resp.data_length != datalen) {
  905. LOGE(tcm_hcd->pdev->dev.parent,
  906. "Failed to read requested length\n");
  907. UNLOCK_BUFFER(reflash_hcd->resp);
  908. return -EIO;
  909. }
  910. retval = secure_memcpy(data,
  911. datalen,
  912. reflash_hcd->resp.buf,
  913. reflash_hcd->resp.buf_size,
  914. datalen);
  915. if (retval < 0) {
  916. LOGE(tcm_hcd->pdev->dev.parent,
  917. "Failed to copy read data\n");
  918. UNLOCK_BUFFER(reflash_hcd->resp);
  919. return retval;
  920. }
  921. UNLOCK_BUFFER(reflash_hcd->resp);
  922. return 0;
  923. }
  924. static int reflash_read_data(enum flash_area area, bool run_app_firmware,
  925. struct syna_tcm_buffer *output)
  926. {
  927. int retval;
  928. unsigned int temp;
  929. unsigned int addr;
  930. unsigned int length;
  931. struct syna_tcm_app_info *app_info;
  932. struct syna_tcm_boot_info *boot_info;
  933. struct syna_tcm_hcd *tcm_hcd = reflash_hcd->tcm_hcd;
  934. switch (area) {
  935. case CUSTOM_LCM:
  936. case CUSTOM_OEM:
  937. case PPDT:
  938. retval = tcm_hcd->get_data_location(tcm_hcd,
  939. area,
  940. &addr,
  941. &length);
  942. if (retval < 0) {
  943. LOGE(tcm_hcd->pdev->dev.parent,
  944. "Failed to get data location\n");
  945. return retval;
  946. }
  947. break;
  948. default:
  949. break;
  950. }
  951. retval = reflash_set_up_flash_access();
  952. if (retval < 0) {
  953. LOGE(tcm_hcd->pdev->dev.parent,
  954. "Failed to set up flash access\n");
  955. return retval;
  956. }
  957. app_info = &tcm_hcd->app_info;
  958. boot_info = &tcm_hcd->boot_info;
  959. switch (area) {
  960. case BOOT_CONFIG:
  961. temp = le2_to_uint(boot_info->boot_config_start_block);
  962. addr = temp * reflash_hcd->write_block_size;
  963. length = BOOT_CONFIG_SIZE * BOOT_CONFIG_SLOTS;
  964. break;
  965. case APP_CONFIG:
  966. temp = le2_to_uint(app_info->app_config_start_write_block);
  967. addr = temp * reflash_hcd->write_block_size;
  968. length = le2_to_uint(app_info->app_config_size);
  969. break;
  970. case DISP_CONFIG:
  971. temp = le4_to_uint(boot_info->display_config_start_block);
  972. addr = temp * reflash_hcd->write_block_size;
  973. temp = le2_to_uint(boot_info->display_config_length_blocks);
  974. length = temp * reflash_hcd->write_block_size;
  975. break;
  976. case CUSTOM_OTP:
  977. temp = le2_to_uint(boot_info->custom_otp_start_block);
  978. addr = temp * reflash_hcd->write_block_size;
  979. temp = le2_to_uint(boot_info->custom_otp_length_blocks);
  980. length = temp * reflash_hcd->write_block_size;
  981. break;
  982. case CUSTOM_LCM:
  983. case CUSTOM_OEM:
  984. case PPDT:
  985. addr *= reflash_hcd->write_block_size;
  986. length *= reflash_hcd->write_block_size;
  987. break;
  988. default:
  989. LOGE(tcm_hcd->pdev->dev.parent,
  990. "Invalid data area\n");
  991. retval = -EINVAL;
  992. goto run_app_firmware;
  993. }
  994. if (addr == 0 || length == 0) {
  995. LOGE(tcm_hcd->pdev->dev.parent,
  996. "Data area unavailable\n");
  997. retval = -EINVAL;
  998. goto run_app_firmware;
  999. }
  1000. LOCK_BUFFER(reflash_hcd->read);
  1001. retval = syna_tcm_alloc_mem(tcm_hcd,
  1002. &reflash_hcd->read,
  1003. length);
  1004. if (retval < 0) {
  1005. LOGE(tcm_hcd->pdev->dev.parent,
  1006. "Failed to allocate memory for read.buf\n");
  1007. UNLOCK_BUFFER(reflash_hcd->read);
  1008. goto run_app_firmware;
  1009. }
  1010. retval = reflash_read_flash(addr, reflash_hcd->read.buf, length);
  1011. if (retval < 0) {
  1012. LOGE(tcm_hcd->pdev->dev.parent,
  1013. "Failed to read from flash\n");
  1014. UNLOCK_BUFFER(reflash_hcd->read);
  1015. goto run_app_firmware;
  1016. }
  1017. reflash_hcd->read.data_length = length;
  1018. if (output != NULL) {
  1019. retval = syna_tcm_alloc_mem(tcm_hcd,
  1020. output,
  1021. length);
  1022. if (retval < 0) {
  1023. LOGE(tcm_hcd->pdev->dev.parent,
  1024. "Failed to allocate memory for output->buf\n");
  1025. UNLOCK_BUFFER(reflash_hcd->read);
  1026. goto run_app_firmware;
  1027. }
  1028. retval = secure_memcpy(output->buf,
  1029. output->buf_size,
  1030. reflash_hcd->read.buf,
  1031. reflash_hcd->read.buf_size,
  1032. length);
  1033. if (retval < 0) {
  1034. LOGE(tcm_hcd->pdev->dev.parent,
  1035. "Failed to copy read data\n");
  1036. UNLOCK_BUFFER(reflash_hcd->read);
  1037. goto run_app_firmware;
  1038. }
  1039. output->data_length = length;
  1040. }
  1041. UNLOCK_BUFFER(reflash_hcd->read);
  1042. retval = 0;
  1043. run_app_firmware:
  1044. if (!run_app_firmware)
  1045. goto exit;
  1046. if (tcm_hcd->switch_mode(tcm_hcd, FW_MODE_APPLICATION) < 0) {
  1047. LOGE(tcm_hcd->pdev->dev.parent,
  1048. "Failed to run application firmware\n");
  1049. }
  1050. exit:
  1051. return retval;
  1052. }
  1053. static int reflash_check_boot_config(void)
  1054. {
  1055. unsigned int temp;
  1056. unsigned int image_addr;
  1057. unsigned int device_addr;
  1058. struct syna_tcm_hcd *tcm_hcd = reflash_hcd->tcm_hcd;
  1059. if (reflash_hcd->image_info.boot_config.size < BOOT_CONFIG_SIZE) {
  1060. LOGE(tcm_hcd->pdev->dev.parent,
  1061. "No valid boot config in image file\n");
  1062. return -EINVAL;
  1063. }
  1064. image_addr = reflash_hcd->image_info.boot_config.flash_addr;
  1065. temp = le2_to_uint(tcm_hcd->boot_info.boot_config_start_block);
  1066. device_addr = temp * reflash_hcd->write_block_size;
  1067. if (image_addr != device_addr) {
  1068. LOGE(tcm_hcd->pdev->dev.parent,
  1069. "Flash address mismatch\n");
  1070. return -EINVAL;
  1071. }
  1072. return 0;
  1073. }
  1074. static int reflash_check_app_config(void)
  1075. {
  1076. unsigned int temp;
  1077. unsigned int image_addr;
  1078. unsigned int image_size;
  1079. unsigned int device_addr;
  1080. unsigned int device_size;
  1081. struct syna_tcm_hcd *tcm_hcd = reflash_hcd->tcm_hcd;
  1082. if (reflash_hcd->image_info.app_config.size == 0) {
  1083. LOGE(tcm_hcd->pdev->dev.parent,
  1084. "No application config in image file\n");
  1085. return -EINVAL;
  1086. }
  1087. image_addr = reflash_hcd->image_info.app_config.flash_addr;
  1088. image_size = reflash_hcd->image_info.app_config.size;
  1089. temp = le2_to_uint(tcm_hcd->app_info.app_config_start_write_block);
  1090. device_addr = temp * reflash_hcd->write_block_size;
  1091. device_size = le2_to_uint(tcm_hcd->app_info.app_config_size);
  1092. if (device_addr == 0 && device_size == 0)
  1093. return 0;
  1094. if (image_addr != device_addr) {
  1095. LOGE(tcm_hcd->pdev->dev.parent,
  1096. "Flash address mismatch\n");
  1097. return -EINVAL;
  1098. }
  1099. if (image_size != device_size) {
  1100. LOGE(tcm_hcd->pdev->dev.parent,
  1101. "Config size mismatch\n");
  1102. return -EINVAL;
  1103. }
  1104. return 0;
  1105. }
  1106. static int reflash_check_disp_config(void)
  1107. {
  1108. unsigned int temp;
  1109. unsigned int image_addr;
  1110. unsigned int image_size;
  1111. unsigned int device_addr;
  1112. unsigned int device_size;
  1113. struct syna_tcm_hcd *tcm_hcd = reflash_hcd->tcm_hcd;
  1114. if (reflash_hcd->image_info.disp_config.size == 0) {
  1115. LOGE(tcm_hcd->pdev->dev.parent,
  1116. "No display config in image file\n");
  1117. return -EINVAL;
  1118. }
  1119. image_addr = reflash_hcd->image_info.disp_config.flash_addr;
  1120. image_size = reflash_hcd->image_info.disp_config.size;
  1121. temp = le4_to_uint(tcm_hcd->boot_info.display_config_start_block);
  1122. device_addr = temp * reflash_hcd->write_block_size;
  1123. temp = le2_to_uint(tcm_hcd->boot_info.display_config_length_blocks);
  1124. device_size = temp * reflash_hcd->write_block_size;
  1125. if (image_addr != device_addr) {
  1126. LOGE(tcm_hcd->pdev->dev.parent,
  1127. "Flash address mismatch\n");
  1128. return -EINVAL;
  1129. }
  1130. if (image_size != device_size) {
  1131. LOGE(tcm_hcd->pdev->dev.parent,
  1132. "Config size mismatch\n");
  1133. return -EINVAL;
  1134. }
  1135. return 0;
  1136. }
  1137. static int reflash_check_prod_test_firmware(void)
  1138. {
  1139. struct syna_tcm_hcd *tcm_hcd = reflash_hcd->tcm_hcd;
  1140. if (reflash_hcd->image_info.prod_test_firmware.size == 0) {
  1141. LOGE(tcm_hcd->pdev->dev.parent,
  1142. "No production test firmware in image file\n");
  1143. return -EINVAL;
  1144. }
  1145. return 0;
  1146. }
  1147. static int reflash_check_app_firmware(void)
  1148. {
  1149. struct syna_tcm_hcd *tcm_hcd = reflash_hcd->tcm_hcd;
  1150. if (reflash_hcd->image_info.app_firmware.size == 0) {
  1151. LOGE(tcm_hcd->pdev->dev.parent,
  1152. "No application firmware in image file\n");
  1153. return -EINVAL;
  1154. }
  1155. return 0;
  1156. }
  1157. static int reflash_write_flash(unsigned int address, const unsigned char *data,
  1158. unsigned int datalen)
  1159. {
  1160. int retval;
  1161. unsigned int offset;
  1162. unsigned int w_length;
  1163. unsigned int xfer_length;
  1164. unsigned int remaining_length;
  1165. unsigned int flash_address;
  1166. unsigned int block_address;
  1167. struct syna_tcm_hcd *tcm_hcd = reflash_hcd->tcm_hcd;
  1168. w_length = tcm_hcd->wr_chunk_size - 5;
  1169. w_length = w_length - (w_length % reflash_hcd->write_block_size);
  1170. w_length = MIN(w_length, reflash_hcd->max_write_payload_size);
  1171. offset = 0;
  1172. remaining_length = datalen;
  1173. LOCK_BUFFER(reflash_hcd->out);
  1174. LOCK_BUFFER(reflash_hcd->resp);
  1175. while (remaining_length) {
  1176. if (remaining_length > w_length)
  1177. xfer_length = w_length;
  1178. else
  1179. xfer_length = remaining_length;
  1180. retval = syna_tcm_alloc_mem(tcm_hcd,
  1181. &reflash_hcd->out,
  1182. xfer_length + 2);
  1183. if (retval < 0) {
  1184. LOGE(tcm_hcd->pdev->dev.parent,
  1185. "Failed to allocate memory for out.buf\n");
  1186. UNLOCK_BUFFER(reflash_hcd->resp);
  1187. UNLOCK_BUFFER(reflash_hcd->out);
  1188. return retval;
  1189. }
  1190. flash_address = address + offset;
  1191. block_address = flash_address / reflash_hcd->write_block_size;
  1192. reflash_hcd->out.buf[0] = (unsigned char)block_address;
  1193. reflash_hcd->out.buf[1] = (unsigned char)(block_address >> 8);
  1194. retval = secure_memcpy(&reflash_hcd->out.buf[2],
  1195. reflash_hcd->out.buf_size - 2,
  1196. &data[offset],
  1197. datalen - offset,
  1198. xfer_length);
  1199. if (retval < 0) {
  1200. LOGE(tcm_hcd->pdev->dev.parent,
  1201. "Failed to copy write data\n");
  1202. UNLOCK_BUFFER(reflash_hcd->resp);
  1203. UNLOCK_BUFFER(reflash_hcd->out);
  1204. return retval;
  1205. }
  1206. retval = tcm_hcd->write_message(tcm_hcd,
  1207. CMD_WRITE_FLASH,
  1208. reflash_hcd->out.buf,
  1209. xfer_length + 2,
  1210. &reflash_hcd->resp.buf,
  1211. &reflash_hcd->resp.buf_size,
  1212. &reflash_hcd->resp.data_length,
  1213. NULL,
  1214. WRITE_FLASH_DELAY_MS);
  1215. if (retval < 0) {
  1216. LOGE(tcm_hcd->pdev->dev.parent,
  1217. "Failed to write command %s\n",
  1218. STR(CMD_WRITE_FLASH));
  1219. LOGE(tcm_hcd->pdev->dev.parent,
  1220. "Flash address = 0x%08x\n",
  1221. flash_address);
  1222. LOGE(tcm_hcd->pdev->dev.parent,
  1223. "Data length = %d\n",
  1224. xfer_length);
  1225. UNLOCK_BUFFER(reflash_hcd->resp);
  1226. UNLOCK_BUFFER(reflash_hcd->out);
  1227. return retval;
  1228. }
  1229. offset += xfer_length;
  1230. remaining_length -= xfer_length;
  1231. }
  1232. UNLOCK_BUFFER(reflash_hcd->resp);
  1233. UNLOCK_BUFFER(reflash_hcd->out);
  1234. return 0;
  1235. }
  1236. reflash_write(app_config)
  1237. reflash_write(disp_config)
  1238. reflash_write(prod_test_firmware)
  1239. reflash_write(app_firmware)
  1240. static int reflash_erase_flash(unsigned int page_start, unsigned int page_count)
  1241. {
  1242. int retval;
  1243. unsigned char out_buf[2];
  1244. struct syna_tcm_hcd *tcm_hcd = reflash_hcd->tcm_hcd;
  1245. out_buf[0] = (unsigned char)page_start;
  1246. out_buf[1] = (unsigned char)page_count;
  1247. LOCK_BUFFER(reflash_hcd->resp);
  1248. retval = tcm_hcd->write_message(tcm_hcd,
  1249. CMD_ERASE_FLASH,
  1250. out_buf,
  1251. sizeof(out_buf),
  1252. &reflash_hcd->resp.buf,
  1253. &reflash_hcd->resp.buf_size,
  1254. &reflash_hcd->resp.data_length,
  1255. NULL,
  1256. ERASE_FLASH_DELAY_MS);
  1257. if (retval < 0) {
  1258. LOGE(tcm_hcd->pdev->dev.parent,
  1259. "Failed to write command %s\n",
  1260. STR(CMD_ERASE_FLASH));
  1261. UNLOCK_BUFFER(reflash_hcd->resp);
  1262. return retval;
  1263. }
  1264. UNLOCK_BUFFER(reflash_hcd->resp);
  1265. return 0;
  1266. }
  1267. reflash_erase(app_config)
  1268. reflash_erase(disp_config)
  1269. reflash_erase(prod_test_firmware)
  1270. reflash_erase(app_firmware)
  1271. static int reflash_update_custom_otp(const unsigned char *data,
  1272. unsigned int offset, unsigned int datalen)
  1273. {
  1274. int retval;
  1275. unsigned int temp;
  1276. unsigned int addr;
  1277. unsigned int length;
  1278. struct syna_tcm_hcd *tcm_hcd = reflash_hcd->tcm_hcd;
  1279. retval = reflash_set_up_flash_access();
  1280. if (retval < 0) {
  1281. LOGE(tcm_hcd->pdev->dev.parent,
  1282. "Failed to set up flash access\n");
  1283. return retval;
  1284. }
  1285. tcm_hcd->update_watchdog(tcm_hcd, false);
  1286. temp = le2_to_uint(tcm_hcd->boot_info.custom_otp_start_block);
  1287. addr = temp * reflash_hcd->write_block_size;
  1288. temp = le2_to_uint(tcm_hcd->boot_info.custom_otp_length_blocks);
  1289. length = temp * reflash_hcd->write_block_size;
  1290. if (addr == 0 || length == 0) {
  1291. LOGE(tcm_hcd->pdev->dev.parent,
  1292. "Data area unavailable\n");
  1293. retval = -EINVAL;
  1294. goto run_app_firmware;
  1295. }
  1296. if (datalen + offset > length) {
  1297. LOGE(tcm_hcd->pdev->dev.parent,
  1298. "Invalid data length\n");
  1299. retval = -EINVAL;
  1300. goto run_app_firmware;
  1301. }
  1302. retval = reflash_write_flash(addr + offset,
  1303. data,
  1304. datalen);
  1305. if (retval < 0) {
  1306. LOGE(tcm_hcd->pdev->dev.parent,
  1307. "Failed to write to flash\n");
  1308. goto run_app_firmware;
  1309. }
  1310. retval = 0;
  1311. run_app_firmware:
  1312. if (tcm_hcd->switch_mode(tcm_hcd, FW_MODE_APPLICATION) < 0) {
  1313. LOGE(tcm_hcd->pdev->dev.parent,
  1314. "Failed to run application firmware\n");
  1315. }
  1316. tcm_hcd->update_watchdog(tcm_hcd, true);
  1317. return retval;
  1318. }
  1319. static int reflash_update_custom_lcm(const unsigned char *data,
  1320. unsigned int offset, unsigned int datalen)
  1321. {
  1322. int retval;
  1323. unsigned int addr;
  1324. unsigned int length;
  1325. unsigned int page_start;
  1326. unsigned int page_count;
  1327. struct syna_tcm_hcd *tcm_hcd = reflash_hcd->tcm_hcd;
  1328. retval = tcm_hcd->get_data_location(tcm_hcd,
  1329. CUSTOM_LCM,
  1330. &addr,
  1331. &length);
  1332. if (retval < 0) {
  1333. LOGE(tcm_hcd->pdev->dev.parent,
  1334. "Failed to get data location\n");
  1335. return retval;
  1336. }
  1337. retval = reflash_set_up_flash_access();
  1338. if (retval < 0) {
  1339. LOGE(tcm_hcd->pdev->dev.parent,
  1340. "Failed to set up flash access\n");
  1341. return retval;
  1342. }
  1343. tcm_hcd->update_watchdog(tcm_hcd, false);
  1344. addr *= reflash_hcd->write_block_size;
  1345. length *= reflash_hcd->write_block_size;
  1346. if (addr == 0 || length == 0) {
  1347. LOGE(tcm_hcd->pdev->dev.parent,
  1348. "Data area unavailable\n");
  1349. retval = -EINVAL;
  1350. goto run_app_firmware;
  1351. }
  1352. if (datalen + offset > length) {
  1353. LOGE(tcm_hcd->pdev->dev.parent,
  1354. "Invalid data length\n");
  1355. retval = -EINVAL;
  1356. goto run_app_firmware;
  1357. }
  1358. if (offset == 0) {
  1359. page_start = addr / reflash_hcd->page_size;
  1360. page_count = ceil_div(length, reflash_hcd->page_size);
  1361. retval = reflash_erase_flash(page_start, page_count);
  1362. if (retval < 0) {
  1363. LOGE(tcm_hcd->pdev->dev.parent,
  1364. "Failed to erase flash pages\n");
  1365. goto run_app_firmware;
  1366. }
  1367. }
  1368. retval = reflash_write_flash(addr + offset,
  1369. data,
  1370. datalen);
  1371. if (retval < 0) {
  1372. LOGE(tcm_hcd->pdev->dev.parent,
  1373. "Failed to write to flash\n");
  1374. goto run_app_firmware;
  1375. }
  1376. retval = 0;
  1377. run_app_firmware:
  1378. if (tcm_hcd->switch_mode(tcm_hcd, FW_MODE_APPLICATION) < 0) {
  1379. LOGE(tcm_hcd->pdev->dev.parent,
  1380. "Failed to run application firmware\n");
  1381. }
  1382. tcm_hcd->update_watchdog(tcm_hcd, true);
  1383. return retval;
  1384. }
  1385. static int reflash_update_custom_oem(const unsigned char *data,
  1386. unsigned int offset, unsigned int datalen)
  1387. {
  1388. int retval;
  1389. unsigned int addr;
  1390. unsigned int length;
  1391. unsigned int page_start;
  1392. unsigned int page_count;
  1393. struct syna_tcm_hcd *tcm_hcd = reflash_hcd->tcm_hcd;
  1394. retval = tcm_hcd->get_data_location(tcm_hcd,
  1395. CUSTOM_OEM,
  1396. &addr,
  1397. &length);
  1398. if (retval < 0) {
  1399. LOGE(tcm_hcd->pdev->dev.parent,
  1400. "Failed to get data location\n");
  1401. return retval;
  1402. }
  1403. retval = reflash_set_up_flash_access();
  1404. if (retval < 0) {
  1405. LOGE(tcm_hcd->pdev->dev.parent,
  1406. "Failed to set up flash access\n");
  1407. return retval;
  1408. }
  1409. tcm_hcd->update_watchdog(tcm_hcd, false);
  1410. addr *= reflash_hcd->write_block_size;
  1411. length *= reflash_hcd->write_block_size;
  1412. if (addr == 0 || length == 0) {
  1413. LOGE(tcm_hcd->pdev->dev.parent,
  1414. "Data area unavailable\n");
  1415. retval = -EINVAL;
  1416. goto run_app_firmware;
  1417. }
  1418. if (datalen + offset > length) {
  1419. LOGE(tcm_hcd->pdev->dev.parent,
  1420. "Invalid data length\n");
  1421. retval = -EINVAL;
  1422. goto run_app_firmware;
  1423. }
  1424. if (offset == 0) {
  1425. page_start = addr / reflash_hcd->page_size;
  1426. page_count = ceil_div(length, reflash_hcd->page_size);
  1427. retval = reflash_erase_flash(page_start, page_count);
  1428. if (retval < 0) {
  1429. LOGE(tcm_hcd->pdev->dev.parent,
  1430. "Failed to erase flash pages\n");
  1431. goto run_app_firmware;
  1432. }
  1433. }
  1434. retval = reflash_write_flash(addr + offset,
  1435. data,
  1436. datalen);
  1437. if (retval < 0) {
  1438. LOGE(tcm_hcd->pdev->dev.parent,
  1439. "Failed to write to flash\n");
  1440. goto run_app_firmware;
  1441. }
  1442. retval = 0;
  1443. run_app_firmware:
  1444. if (tcm_hcd->switch_mode(tcm_hcd, FW_MODE_APPLICATION) < 0) {
  1445. LOGE(tcm_hcd->pdev->dev.parent,
  1446. "Failed to run application firmware\n");
  1447. }
  1448. tcm_hcd->update_watchdog(tcm_hcd, true);
  1449. return retval;
  1450. }
  1451. static int reflash_update_boot_config(bool lock)
  1452. {
  1453. int retval;
  1454. unsigned char slot_used;
  1455. unsigned int idx;
  1456. unsigned int addr = 0;
  1457. struct boot_config *data;
  1458. struct boot_config *last_slot;
  1459. struct syna_tcm_hcd *tcm_hcd = reflash_hcd->tcm_hcd;
  1460. retval = reflash_set_up_flash_access();
  1461. if (retval < 0) {
  1462. LOGE(tcm_hcd->pdev->dev.parent,
  1463. "Failed to set up flash access\n");
  1464. return retval;
  1465. }
  1466. tcm_hcd->update_watchdog(tcm_hcd, false);
  1467. retval = reflash_check_boot_config();
  1468. if (retval < 0) {
  1469. LOGE(tcm_hcd->pdev->dev.parent,
  1470. "Failed boot_config partition check\n");
  1471. goto reset;
  1472. }
  1473. retval = reflash_read_data(BOOT_CONFIG, false, NULL);
  1474. if (retval < 0) {
  1475. LOGE(tcm_hcd->pdev->dev.parent,
  1476. "Failed to read boot config\n");
  1477. goto reset;
  1478. }
  1479. LOCK_BUFFER(reflash_hcd->read);
  1480. data = (struct boot_config *)reflash_hcd->read.buf;
  1481. last_slot = data + (BOOT_CONFIG_SLOTS - 1);
  1482. slot_used = tcm_hcd->id_info.mode == MODE_TDDI_BOOTLOADER ? 0 : 1;
  1483. if (last_slot->used == slot_used) {
  1484. LOGE(tcm_hcd->pdev->dev.parent,
  1485. "Boot config already locked down\n");
  1486. UNLOCK_BUFFER(reflash_hcd->read);
  1487. goto reset;
  1488. }
  1489. if (lock) {
  1490. idx = BOOT_CONFIG_SLOTS - 1;
  1491. } else {
  1492. for (idx = 0; idx < BOOT_CONFIG_SLOTS; idx++) {
  1493. if (data->used == slot_used) {
  1494. data++;
  1495. continue;
  1496. } else {
  1497. break;
  1498. }
  1499. }
  1500. }
  1501. UNLOCK_BUFFER(reflash_hcd->read);
  1502. if (idx == BOOT_CONFIG_SLOTS) {
  1503. LOGE(tcm_hcd->pdev->dev.parent,
  1504. "No free boot config slot available\n");
  1505. goto reset;
  1506. }
  1507. addr += idx * BOOT_CONFIG_SIZE;
  1508. retval = reflash_write_flash(addr,
  1509. reflash_hcd->image_info.boot_config.data,
  1510. BOOT_CONFIG_SIZE);
  1511. if (retval < 0) {
  1512. LOGE(tcm_hcd->pdev->dev.parent,
  1513. "Failed to write to flash\n");
  1514. goto reset;
  1515. }
  1516. LOGN(tcm_hcd->pdev->dev.parent,
  1517. "Slot %d updated with new boot config\n",
  1518. idx);
  1519. retval = 0;
  1520. reset:
  1521. if (tcm_hcd->reset(tcm_hcd, false, true) < 0) {
  1522. LOGE(tcm_hcd->pdev->dev.parent,
  1523. "Failed to do reset\n");
  1524. }
  1525. tcm_hcd->update_watchdog(tcm_hcd, true);
  1526. return retval;
  1527. }
  1528. reflash_update(app_config)
  1529. reflash_update(disp_config)
  1530. reflash_update(prod_test_firmware)
  1531. reflash_update(app_firmware)
  1532. static int reflash_do_reflash(void)
  1533. {
  1534. int retval;
  1535. enum update_area update_area;
  1536. struct syna_tcm_hcd *tcm_hcd = reflash_hcd->tcm_hcd;
  1537. retval = reflash_get_fw_image();
  1538. if (retval < 0) {
  1539. LOGD(tcm_hcd->pdev->dev.parent,
  1540. "Failed to get firmware image\n");
  1541. goto exit;
  1542. }
  1543. LOGD(tcm_hcd->pdev->dev.parent,
  1544. "Start of reflash\n");
  1545. atomic_set(&tcm_hcd->firmware_flashing, 1);
  1546. update_area = reflash_compare_id_info();
  1547. switch (update_area) {
  1548. case FIRMWARE_CONFIG:
  1549. retval = reflash_update_app_firmware(false);
  1550. if (retval < 0) {
  1551. LOGE(tcm_hcd->pdev->dev.parent,
  1552. "Failed to reflash application firmware\n");
  1553. goto exit;
  1554. }
  1555. memset(&tcm_hcd->app_info, 0x00, sizeof(tcm_hcd->app_info));
  1556. if (tcm_hcd->features.dual_firmware) {
  1557. retval = reflash_update_prod_test_firmware(false);
  1558. if (retval < 0) {
  1559. LOGE(tcm_hcd->pdev->dev.parent,
  1560. "Failed to reflash production test\n");
  1561. goto exit;
  1562. }
  1563. }
  1564. case CONFIG_ONLY:
  1565. if (reflash_hcd->disp_cfg_update) {
  1566. retval = reflash_update_disp_config(false);
  1567. if (retval < 0) {
  1568. LOGE(tcm_hcd->pdev->dev.parent,
  1569. "Failed to reflash display config\n");
  1570. goto exit;
  1571. }
  1572. }
  1573. retval = reflash_update_app_config(true);
  1574. if (retval < 0) {
  1575. LOGE(tcm_hcd->pdev->dev.parent,
  1576. "Failed to reflash application config\n");
  1577. goto exit;
  1578. }
  1579. break;
  1580. case NONE:
  1581. default:
  1582. break;
  1583. }
  1584. LOGD(tcm_hcd->pdev->dev.parent,
  1585. "End of reflash\n");
  1586. retval = 0;
  1587. exit:
  1588. if (reflash_hcd->fw_entry) {
  1589. release_firmware(reflash_hcd->fw_entry);
  1590. reflash_hcd->fw_entry = NULL;
  1591. reflash_hcd->image = NULL;
  1592. reflash_hcd->image_size = 0;
  1593. }
  1594. atomic_set(&tcm_hcd->firmware_flashing, 0);
  1595. wake_up_interruptible(&tcm_hcd->reflash_wq);
  1596. return retval;
  1597. }
  1598. #ifdef STARTUP_REFLASH
  1599. static void reflash_startup_work(struct work_struct *work)
  1600. {
  1601. int retval;
  1602. #if defined(CONFIG_DRM) || defined(CONFIG_FB)
  1603. unsigned int timeout;
  1604. #endif
  1605. struct syna_tcm_hcd *tcm_hcd = reflash_hcd->tcm_hcd;
  1606. #if defined(CONFIG_DRM) || defined(CONFIG_FB)
  1607. timeout = FB_READY_TIMEOUT_S * 1000 / FB_READY_WAIT_MS;
  1608. while (tcm_hcd->fb_ready != FB_READY_COUNT - 1) {
  1609. if (timeout == 0) {
  1610. LOGE(tcm_hcd->pdev->dev.parent,
  1611. "Timed out waiting for FB ready\n");
  1612. return;
  1613. }
  1614. msleep(FB_READY_WAIT_MS);
  1615. timeout--;
  1616. }
  1617. #endif
  1618. pm_stay_awake(&tcm_hcd->pdev->dev);
  1619. mutex_lock(&reflash_hcd->reflash_mutex);
  1620. retval = reflash_do_reflash();
  1621. if (retval < 0) {
  1622. LOGE(tcm_hcd->pdev->dev.parent,
  1623. "Failed to do reflash\n");
  1624. }
  1625. mutex_unlock(&reflash_hcd->reflash_mutex);
  1626. pm_relax(&tcm_hcd->pdev->dev);
  1627. }
  1628. #endif
  1629. static int reflash_init(struct syna_tcm_hcd *tcm_hcd)
  1630. {
  1631. int retval = 0;
  1632. int idx;
  1633. reflash_hcd = kzalloc(sizeof(*reflash_hcd), GFP_KERNEL);
  1634. if (!reflash_hcd) {
  1635. LOGE(tcm_hcd->pdev->dev.parent,
  1636. "Failed to allocate memory for reflash_hcd\n");
  1637. return -ENOMEM;
  1638. }
  1639. reflash_hcd->image_buf = kzalloc(IMAGE_BUF_SIZE, GFP_KERNEL);
  1640. if (!reflash_hcd->image_buf) {
  1641. LOGE(tcm_hcd->pdev->dev.parent,
  1642. "Failed to allocate memory for image_buf\n");
  1643. goto err_allocate_memory;
  1644. }
  1645. reflash_hcd->tcm_hcd = tcm_hcd;
  1646. reflash_hcd->force_update = FORCE_REFLASH;
  1647. mutex_init(&reflash_hcd->reflash_mutex);
  1648. INIT_BUFFER(reflash_hcd->out, false);
  1649. INIT_BUFFER(reflash_hcd->resp, false);
  1650. INIT_BUFFER(reflash_hcd->read, false);
  1651. #ifdef STARTUP_REFLASH
  1652. reflash_hcd->workqueue =
  1653. create_singlethread_workqueue("syna_tcm_reflash");
  1654. INIT_WORK(&reflash_hcd->work, reflash_startup_work);
  1655. queue_work(reflash_hcd->workqueue, &reflash_hcd->work);
  1656. #endif
  1657. if (!ENABLE_SYSFS_INTERFACE)
  1658. return 0;
  1659. reflash_hcd->sysfs_dir = kobject_create_and_add(SYSFS_DIR_NAME,
  1660. tcm_hcd->sysfs_dir);
  1661. if (!reflash_hcd->sysfs_dir) {
  1662. LOGE(tcm_hcd->pdev->dev.parent,
  1663. "Failed to create sysfs directory\n");
  1664. retval = -EINVAL;
  1665. goto err_sysfs_create_dir;
  1666. }
  1667. for (idx = 0; idx < ARRAY_SIZE(attrs); idx++) {
  1668. retval = sysfs_create_file(reflash_hcd->sysfs_dir,
  1669. &(*attrs[idx]).attr);
  1670. if (retval < 0) {
  1671. LOGE(tcm_hcd->pdev->dev.parent,
  1672. "Failed to create sysfs file\n");
  1673. goto err_sysfs_create_file;
  1674. }
  1675. }
  1676. retval = sysfs_create_bin_file(reflash_hcd->sysfs_dir, &bin_attrs[0]);
  1677. if (retval < 0) {
  1678. LOGE(tcm_hcd->pdev->dev.parent,
  1679. "Failed to create sysfs bin file\n");
  1680. goto err_sysfs_create_bin_file;
  1681. }
  1682. reflash_hcd->custom_dir = kobject_create_and_add(CUSTOM_DIR_NAME,
  1683. reflash_hcd->sysfs_dir);
  1684. if (!reflash_hcd->custom_dir) {
  1685. LOGE(tcm_hcd->pdev->dev.parent,
  1686. "Failed to create custom sysfs directory\n");
  1687. retval = -EINVAL;
  1688. goto err_custom_sysfs_create_dir;
  1689. }
  1690. for (idx = 1; idx < ARRAY_SIZE(bin_attrs); idx++) {
  1691. retval = sysfs_create_bin_file(reflash_hcd->custom_dir,
  1692. &bin_attrs[idx]);
  1693. if (retval < 0) {
  1694. LOGE(tcm_hcd->pdev->dev.parent,
  1695. "Failed to create sysfs bin file\n");
  1696. goto err_custom_sysfs_create_bin_file;
  1697. }
  1698. }
  1699. tcm_hcd->read_flash_data = reflash_read_data;
  1700. return 0;
  1701. err_custom_sysfs_create_bin_file:
  1702. for (idx--; idx > 0; idx--)
  1703. sysfs_remove_bin_file(reflash_hcd->custom_dir, &bin_attrs[idx]);
  1704. kobject_put(reflash_hcd->custom_dir);
  1705. idx = ARRAY_SIZE(attrs);
  1706. err_custom_sysfs_create_dir:
  1707. sysfs_remove_bin_file(reflash_hcd->sysfs_dir, &bin_attrs[0]);
  1708. err_sysfs_create_bin_file:
  1709. err_sysfs_create_file:
  1710. for (idx--; idx >= 0; idx--)
  1711. sysfs_remove_file(reflash_hcd->sysfs_dir, &(*attrs[idx]).attr);
  1712. kobject_put(reflash_hcd->sysfs_dir);
  1713. err_sysfs_create_dir:
  1714. err_allocate_memory:
  1715. kfree(reflash_hcd->image_buf);
  1716. RELEASE_BUFFER(reflash_hcd->read);
  1717. RELEASE_BUFFER(reflash_hcd->resp);
  1718. RELEASE_BUFFER(reflash_hcd->out);
  1719. kfree(reflash_hcd);
  1720. reflash_hcd = NULL;
  1721. return retval;
  1722. }
  1723. static int reflash_remove(struct syna_tcm_hcd *tcm_hcd)
  1724. {
  1725. int idx;
  1726. if (!reflash_hcd)
  1727. goto exit;
  1728. tcm_hcd->read_flash_data = NULL;
  1729. if (ENABLE_SYSFS_INTERFACE) {
  1730. for (idx = 1; idx < ARRAY_SIZE(bin_attrs); idx++) {
  1731. sysfs_remove_bin_file(reflash_hcd->custom_dir,
  1732. &bin_attrs[idx]);
  1733. }
  1734. kobject_put(reflash_hcd->custom_dir);
  1735. sysfs_remove_bin_file(reflash_hcd->sysfs_dir, &bin_attrs[0]);
  1736. for (idx = 0; idx < ARRAY_SIZE(attrs); idx++) {
  1737. sysfs_remove_file(reflash_hcd->sysfs_dir,
  1738. &(*attrs[idx]).attr);
  1739. }
  1740. kobject_put(reflash_hcd->sysfs_dir);
  1741. }
  1742. #ifdef STARTUP_REFLASH
  1743. cancel_work_sync(&reflash_hcd->work);
  1744. flush_workqueue(reflash_hcd->workqueue);
  1745. destroy_workqueue(reflash_hcd->workqueue);
  1746. #endif
  1747. kfree(reflash_hcd->image_buf);
  1748. RELEASE_BUFFER(reflash_hcd->read);
  1749. RELEASE_BUFFER(reflash_hcd->resp);
  1750. RELEASE_BUFFER(reflash_hcd->out);
  1751. kfree(reflash_hcd);
  1752. reflash_hcd = NULL;
  1753. exit:
  1754. complete(&reflash_remove_complete);
  1755. return 0;
  1756. }
  1757. static int reflash_reset(struct syna_tcm_hcd *tcm_hcd)
  1758. {
  1759. int retval;
  1760. if (!reflash_hcd) {
  1761. retval = reflash_init(tcm_hcd);
  1762. return retval;
  1763. }
  1764. return 0;
  1765. }
  1766. static struct syna_tcm_module_cb reflash_module = {
  1767. .type = TCM_REFLASH,
  1768. .init = reflash_init,
  1769. .remove = reflash_remove,
  1770. .syncbox = NULL,
  1771. .asyncbox = NULL,
  1772. .reset = reflash_reset,
  1773. .suspend = NULL,
  1774. .resume = NULL,
  1775. .early_suspend = NULL,
  1776. };
  1777. static int __init reflash_module_init(void)
  1778. {
  1779. return syna_tcm_add_module(&reflash_module, true);
  1780. }
  1781. static void __exit reflash_module_exit(void)
  1782. {
  1783. syna_tcm_add_module(&reflash_module, false);
  1784. wait_for_completion(&reflash_remove_complete);
  1785. }
  1786. module_init(reflash_module_init);
  1787. module_exit(reflash_module_exit);
  1788. MODULE_AUTHOR("Synaptics, Inc.");
  1789. MODULE_DESCRIPTION("Synaptics TCM Reflash Module");
  1790. MODULE_LICENSE("GPL v2");