wcnss_wlan.c 78 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013
  1. /* Copyright (c) 2011-2015, 2017 The Linux Foundation. All rights reserved.
  2. *
  3. * This program is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License version 2 and
  5. * only version 2 as published by the Free Software Foundation.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. */
  12. #include <linux/module.h>
  13. #include <linux/firmware.h>
  14. #include <linux/slab.h>
  15. #include <linux/err.h>
  16. #include <linux/platform_device.h>
  17. #include <linux/miscdevice.h>
  18. #include <linux/fs.h>
  19. #include <linux/wcnss_wlan.h>
  20. #include <linux/platform_data/qcom_wcnss_device.h>
  21. #include <linux/workqueue.h>
  22. #include <linux/jiffies.h>
  23. #include <linux/gpio.h>
  24. #include <linux/wakelock.h>
  25. #include <linux/delay.h>
  26. #include <linux/of.h>
  27. #include <linux/of_gpio.h>
  28. #include <linux/clk.h>
  29. #include <linux/ratelimit.h>
  30. #include <linux/kthread.h>
  31. #include <linux/wait.h>
  32. #include <linux/uaccess.h>
  33. #include <linux/suspend.h>
  34. #include <linux/rwsem.h>
  35. #include <linux/mfd/pm8xxx/misc.h>
  36. #include <linux/qpnp/qpnp-adc.h>
  37. #include <linux/pm_qos.h>
  38. #include <mach/board.h>
  39. #include <mach/msm_smd.h>
  40. #include <mach/msm_iomap.h>
  41. #include <mach/subsystem_restart.h>
  42. #include <mach/subsystem_notif.h>
  43. #ifdef CONFIG_WCNSS_MEM_PRE_ALLOC
  44. #include "wcnss_prealloc.h"
  45. #endif
  46. #define DEVICE "wcnss_wlan"
  47. #define CTRL_DEVICE "wcnss_ctrl"
  48. #define VERSION "1.01"
  49. #define WCNSS_PIL_DEVICE "wcnss"
  50. #define WCNSS_DISABLE_PC_LATENCY 100
  51. #define WCNSS_ENABLE_PC_LATENCY PM_QOS_DEFAULT_VALUE
  52. #define WCNSS_PM_QOS_TIMEOUT 15000
  53. #define WAIT_FOR_CBC_IND 2
  54. /* module params */
  55. #define WCNSS_CONFIG_UNSPECIFIED (-1)
  56. #define UINT32_MAX (0xFFFFFFFFU)
  57. static int has_48mhz_xo = WCNSS_CONFIG_UNSPECIFIED;
  58. module_param(has_48mhz_xo, int, S_IWUSR | S_IRUGO);
  59. MODULE_PARM_DESC(has_48mhz_xo, "Is an external 48 MHz XO present");
  60. static int has_calibrated_data = WCNSS_CONFIG_UNSPECIFIED;
  61. module_param(has_calibrated_data, int, S_IWUSR | S_IRUGO);
  62. MODULE_PARM_DESC(has_calibrated_data, "whether calibrated data file available");
  63. static int has_autodetect_xo = WCNSS_CONFIG_UNSPECIFIED;
  64. module_param(has_autodetect_xo, int, S_IWUSR | S_IRUGO);
  65. MODULE_PARM_DESC(has_autodetect_xo, "Perform auto detect to configure IRIS XO");
  66. static int do_not_cancel_vote = WCNSS_CONFIG_UNSPECIFIED;
  67. module_param(do_not_cancel_vote, int, S_IWUSR | S_IRUGO);
  68. MODULE_PARM_DESC(do_not_cancel_vote, "Do not cancel votes for wcnss");
  69. static DEFINE_SPINLOCK(reg_spinlock);
  70. #define MSM_RIVA_PHYS 0x03204000
  71. #define MSM_PRONTO_PHYS 0xfb21b000
  72. #define RIVA_SPARE_OFFSET 0x0b4
  73. #define RIVA_SUSPEND_BIT BIT(24)
  74. #define MSM_RIVA_CCU_BASE 0x03200800
  75. #define CCU_RIVA_INVALID_ADDR_OFFSET 0x100
  76. #define CCU_RIVA_LAST_ADDR0_OFFSET 0x104
  77. #define CCU_RIVA_LAST_ADDR1_OFFSET 0x108
  78. #define CCU_RIVA_LAST_ADDR2_OFFSET 0x10c
  79. #define PRONTO_PMU_SPARE_OFFSET 0x1088
  80. #define PRONTO_PMU_COM_GDSCR_OFFSET 0x0024
  81. #define PRONTO_PMU_COM_GDSCR_SW_COLLAPSE BIT(0)
  82. #define PRONTO_PMU_COM_GDSCR_HW_CTRL BIT(1)
  83. #define PRONTO_PMU_WLAN_BCR_OFFSET 0x0050
  84. #define PRONTO_PMU_WLAN_BCR_BLK_ARES BIT(0)
  85. #define PRONTO_PMU_WLAN_GDSCR_OFFSET 0x0054
  86. #define PRONTO_PMU_WLAN_GDSCR_SW_COLLAPSE BIT(0)
  87. #define PRONTO_PMU_CBCR_OFFSET 0x0008
  88. #define PRONTO_PMU_CBCR_CLK_EN BIT(0)
  89. #define PRONTO_PMU_COM_CPU_CBCR_OFFSET 0x0030
  90. #define PRONTO_PMU_COM_AHB_CBCR_OFFSET 0x0034
  91. #define PRONTO_PMU_WLAN_AHB_CBCR_OFFSET 0x0074
  92. #define PRONTO_PMU_WLAN_AHB_CBCR_CLK_EN BIT(0)
  93. #define PRONTO_PMU_WLAN_AHB_CBCR_CLK_OFF BIT(31)
  94. #define PRONTO_PMU_CPU_AHB_CMD_RCGR_OFFSET 0x0120
  95. #define PRONTO_PMU_CPU_AHB_CMD_RCGR_ROOT_EN BIT(1)
  96. #define PRONTO_PMU_CFG_OFFSET 0x1004
  97. #define PRONTO_PMU_COM_CSR_OFFSET 0x1040
  98. #define PRONTO_PMU_SOFT_RESET_OFFSET 0x104C
  99. #define MSM_PRONTO_A2XB_BASE 0xfb100400
  100. #define A2XB_CFG_OFFSET 0x00
  101. #define A2XB_INT_SRC_OFFSET 0x0c
  102. #define A2XB_TSTBUS_CTRL_OFFSET 0x14
  103. #define A2XB_TSTBUS_OFFSET 0x18
  104. #define A2XB_ERR_INFO_OFFSET 0x1c
  105. #define A2XB_FIFO_FILL_OFFSET 0x07
  106. #define A2XB_READ_FIFO_FILL_MASK 0x3F
  107. #define A2XB_CMD_FIFO_FILL_MASK 0x0F
  108. #define A2XB_WRITE_FIFO_FILL_MASK 0x1F
  109. #define A2XB_FIFO_EMPTY 0x2
  110. #define A2XB_FIFO_COUNTER 0xA
  111. #define WCNSS_TSTBUS_CTRL_EN BIT(0)
  112. #define WCNSS_TSTBUS_CTRL_AXIM (0x02 << 1)
  113. #define WCNSS_TSTBUS_CTRL_CMDFIFO (0x03 << 1)
  114. #define WCNSS_TSTBUS_CTRL_WRFIFO (0x04 << 1)
  115. #define WCNSS_TSTBUS_CTRL_RDFIFO (0x05 << 1)
  116. #define WCNSS_TSTBUS_CTRL_CTRL (0x07 << 1)
  117. #define WCNSS_TSTBUS_CTRL_AXIM_CFG0 (0x00 << 8)
  118. #define WCNSS_TSTBUS_CTRL_AXIM_CFG1 (0x01 << 8)
  119. #define WCNSS_TSTBUS_CTRL_CTRL_CFG0 (0x00 << 28)
  120. #define WCNSS_TSTBUS_CTRL_CTRL_CFG1 (0x01 << 28)
  121. #define MSM_PRONTO_CCPU_BASE 0xfb205050
  122. #define CCU_PRONTO_INVALID_ADDR_OFFSET 0x08
  123. #define CCU_PRONTO_LAST_ADDR0_OFFSET 0x0c
  124. #define CCU_PRONTO_LAST_ADDR1_OFFSET 0x10
  125. #define CCU_PRONTO_LAST_ADDR2_OFFSET 0x14
  126. #define MSM_PRONTO_SAW2_BASE 0xfb219000
  127. #define PRONTO_SAW2_SPM_STS_OFFSET 0x0c
  128. #define MSM_PRONTO_PLL_BASE 0xfb21b1c0
  129. #define PRONTO_PLL_STATUS_OFFSET 0x1c
  130. #define MSM_PRONTO_MCU_BASE 0xfb080c00
  131. #define MCU_APB2PHY_STATUS_OFFSET 0xec
  132. #define MCU_CBR_CCAHB_ERR_OFFSET 0x380
  133. #define MCU_CBR_CAHB_ERR_OFFSET 0x384
  134. #define MCU_CBR_CCAHB_TIMEOUT_OFFSET 0x388
  135. #define MCU_CBR_CAHB_TIMEOUT_OFFSET 0x38c
  136. #define MCU_DBR_CDAHB_ERR_OFFSET 0x390
  137. #define MCU_DBR_DAHB_ERR_OFFSET 0x394
  138. #define MCU_DBR_CDAHB_TIMEOUT_OFFSET 0x398
  139. #define MCU_DBR_DAHB_TIMEOUT_OFFSET 0x39c
  140. #define MCU_FDBR_CDAHB_ERR_OFFSET 0x3a0
  141. #define MCU_FDBR_FDAHB_ERR_OFFSET 0x3a4
  142. #define MCU_FDBR_CDAHB_TIMEOUT_OFFSET 0x3a8
  143. #define MCU_FDBR_FDAHB_TIMEOUT_OFFSET 0x3ac
  144. #define MSM_PRONTO_TXP_STATUS 0xfb08040c
  145. #define MSM_PRONTO_TXP_PHY_ABORT 0xfb080488
  146. #define MSM_PRONTO_BRDG_ERR_SRC 0xfb080fb0
  147. #define MSM_PRONTO_ALARMS_TXCTL 0xfb0120a8
  148. #define MSM_PRONTO_ALARMS_TACTL 0xfb012448
  149. #define WCNSS_DEF_WLAN_RX_BUFF_COUNT 1024
  150. #define WCNSS_VBATT_THRESHOLD 3500000
  151. #define WCNSS_VBATT_GUARD 20000
  152. #define WCNSS_VBATT_HIGH 3700000
  153. #define WCNSS_VBATT_LOW 3300000
  154. #define WCNSS_CTRL_CHANNEL "WCNSS_CTRL"
  155. #define WCNSS_MAX_FRAME_SIZE (4*1024)
  156. #define WCNSS_VERSION_LEN 30
  157. #define WCNSS_MAX_BUILD_VER_LEN 256
  158. #define WCNSS_MAX_CMD_LEN (128)
  159. #define WCNSS_MIN_CMD_LEN (3)
  160. #define WCNSS_MIN_SERIAL_LEN (6)
  161. /* control messages from userspace */
  162. #define WCNSS_USR_CTRL_MSG_START 0x00000000
  163. #define WCNSS_USR_SERIAL_NUM (WCNSS_USR_CTRL_MSG_START + 1)
  164. #define WCNSS_USR_HAS_CAL_DATA (WCNSS_USR_CTRL_MSG_START + 2)
  165. #define WCNSS_USR_WLAN_MAC_ADDR (WCNSS_USR_CTRL_MSG_START + 3)
  166. #define MAC_ADDRESS_STR "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx"
  167. /* message types */
  168. #define WCNSS_CTRL_MSG_START 0x01000000
  169. #define WCNSS_VERSION_REQ (WCNSS_CTRL_MSG_START + 0)
  170. #define WCNSS_VERSION_RSP (WCNSS_CTRL_MSG_START + 1)
  171. #define WCNSS_NVBIN_DNLD_REQ (WCNSS_CTRL_MSG_START + 2)
  172. #define WCNSS_NVBIN_DNLD_RSP (WCNSS_CTRL_MSG_START + 3)
  173. #define WCNSS_CALDATA_UPLD_REQ (WCNSS_CTRL_MSG_START + 4)
  174. #define WCNSS_CALDATA_UPLD_RSP (WCNSS_CTRL_MSG_START + 5)
  175. #define WCNSS_CALDATA_DNLD_REQ (WCNSS_CTRL_MSG_START + 6)
  176. #define WCNSS_CALDATA_DNLD_RSP (WCNSS_CTRL_MSG_START + 7)
  177. #define WCNSS_VBATT_LEVEL_IND (WCNSS_CTRL_MSG_START + 8)
  178. #define WCNSS_BUILD_VER_REQ (WCNSS_CTRL_MSG_START + 9)
  179. #define WCNSS_BUILD_VER_RSP (WCNSS_CTRL_MSG_START + 10)
  180. #define WCNSS_PM_CONFIG_REQ (WCNSS_CTRL_MSG_START + 11)
  181. #define WCNSS_CBC_COMPLETE_IND (WCNSS_CTRL_MSG_START + 12)
  182. /* max 20mhz channel count */
  183. #define WCNSS_MAX_CH_NUM 45
  184. #define WCNSS_MAX_PIL_RETRY 2
  185. #define VALID_VERSION(version) \
  186. ((strncmp(version, "INVALID", WCNSS_VERSION_LEN)) ? 1 : 0)
  187. #define FW_CALDATA_CAPABLE() \
  188. ((penv->fw_major >= 1) && (penv->fw_minor >= 5) ? 1 : 0)
  189. struct smd_msg_hdr {
  190. unsigned int msg_type;
  191. unsigned int msg_len;
  192. };
  193. struct wcnss_version {
  194. struct smd_msg_hdr hdr;
  195. unsigned char major;
  196. unsigned char minor;
  197. unsigned char version;
  198. unsigned char revision;
  199. };
  200. struct wcnss_pmic_dump {
  201. char reg_name[10];
  202. u16 reg_addr;
  203. };
  204. static struct wcnss_pmic_dump wcnss_pmic_reg_dump[] = {
  205. {"S2", 0x1D8},
  206. {"L4", 0xB4},
  207. {"L10", 0xC0},
  208. {"LVS2", 0x62},
  209. {"S4", 0x1E8},
  210. {"LVS7", 0x06C},
  211. {"LVS1", 0x060},
  212. };
  213. static int wcnss_notif_cb(struct notifier_block *this, unsigned long code,
  214. void *ss_handle);
  215. static struct notifier_block wnb = {
  216. .notifier_call = wcnss_notif_cb,
  217. };
  218. #define NVBIN_FILE "wlan/prima/WCNSS_qcom_wlan_nv.bin"
  219. /*
  220. * On SMD channel 4K of maximum data can be transferred, including message
  221. * header, so NV fragment size as next multiple of 1Kb is 3Kb.
  222. */
  223. #define NV_FRAGMENT_SIZE 3072
  224. #define MAX_CALIBRATED_DATA_SIZE (64*1024)
  225. #define LAST_FRAGMENT (1 << 0)
  226. #define MESSAGE_TO_FOLLOW (1 << 1)
  227. #define CAN_RECEIVE_CALDATA (1 << 15)
  228. #define WCNSS_RESP_SUCCESS 1
  229. #define WCNSS_RESP_FAIL 0
  230. /* Macro to find the total number fragments of the NV bin Image */
  231. #define TOTALFRAGMENTS(x) (((x % NV_FRAGMENT_SIZE) == 0) ? \
  232. (x / NV_FRAGMENT_SIZE) : ((x / NV_FRAGMENT_SIZE) + 1))
  233. struct nvbin_dnld_req_params {
  234. /*
  235. * Fragment sequence number of the NV bin Image. NV Bin Image
  236. * might not fit into one message due to size limitation of
  237. * the SMD channel FIFO so entire NV blob is chopped into
  238. * multiple fragments starting with seqeunce number 0. The
  239. * last fragment is indicated by marking is_last_fragment field
  240. * to 1. At receiving side, NV blobs would be concatenated
  241. * together without any padding bytes in between.
  242. */
  243. unsigned short frag_number;
  244. /*
  245. * bit 0: When set to 1 it indicates that no more fragments will
  246. * be sent.
  247. * bit 1: When set, a new message will be followed by this message
  248. * bit 2- bit 14: Reserved
  249. * bit 15: when set, it indicates that the sender is capable of
  250. * receiving Calibrated data.
  251. */
  252. unsigned short msg_flags;
  253. /* NV Image size (number of bytes) */
  254. unsigned int nvbin_buffer_size;
  255. /*
  256. * Following the 'nvbin_buffer_size', there should be
  257. * nvbin_buffer_size bytes of NV bin Image i.e.
  258. * uint8[nvbin_buffer_size].
  259. */
  260. };
  261. struct nvbin_dnld_req_msg {
  262. /*
  263. * Note: The length specified in nvbin_dnld_req_msg messages
  264. * should be hdr.msg_len = sizeof(nvbin_dnld_req_msg) +
  265. * nvbin_buffer_size.
  266. */
  267. struct smd_msg_hdr hdr;
  268. struct nvbin_dnld_req_params dnld_req_params;
  269. };
  270. struct cal_data_params {
  271. /* The total size of the calibrated data, including all the
  272. * fragments.
  273. */
  274. unsigned int total_size;
  275. unsigned short frag_number;
  276. /*
  277. * bit 0: When set to 1 it indicates that no more fragments will
  278. * be sent.
  279. * bit 1: When set, a new message will be followed by this message
  280. * bit 2- bit 15: Reserved
  281. */
  282. unsigned short msg_flags;
  283. /*
  284. * fragment size
  285. */
  286. unsigned int frag_size;
  287. /*
  288. * Following the frag_size, frag_size of fragmented
  289. * data will be followed.
  290. */
  291. };
  292. struct cal_data_msg {
  293. /*
  294. * The length specified in cal_data_msg should be
  295. * hdr.msg_len = sizeof(cal_data_msg) + frag_size
  296. */
  297. struct smd_msg_hdr hdr;
  298. struct cal_data_params cal_params;
  299. };
  300. struct vbatt_level {
  301. u32 curr_volt;
  302. u32 threshold;
  303. };
  304. struct vbatt_message {
  305. struct smd_msg_hdr hdr;
  306. struct vbatt_level vbatt;
  307. };
  308. static struct {
  309. struct platform_device *pdev;
  310. void *pil;
  311. struct resource *mmio_res;
  312. struct resource *tx_irq_res;
  313. struct resource *rx_irq_res;
  314. struct resource *gpios_5wire;
  315. const struct dev_pm_ops *pm_ops;
  316. int triggered;
  317. int smd_channel_ready;
  318. u32 wlan_rx_buff_count;
  319. smd_channel_t *smd_ch;
  320. unsigned char wcnss_version[WCNSS_VERSION_LEN];
  321. unsigned char fw_major;
  322. unsigned char fw_minor;
  323. unsigned int serial_number;
  324. int thermal_mitigation;
  325. enum wcnss_hw_type wcnss_hw_type;
  326. void (*tm_notify)(struct device *, int);
  327. struct wcnss_wlan_config wlan_config;
  328. struct delayed_work wcnss_work;
  329. struct delayed_work vbatt_work;
  330. struct work_struct wcnssctrl_version_work;
  331. struct work_struct wcnss_pm_config_work;
  332. struct work_struct wcnssctrl_nvbin_dnld_work;
  333. struct work_struct wcnssctrl_rx_work;
  334. struct wake_lock wcnss_wake_lock;
  335. void __iomem *msm_wcnss_base;
  336. void __iomem *riva_ccu_base;
  337. void __iomem *pronto_a2xb_base;
  338. void __iomem *pronto_ccpu_base;
  339. void __iomem *pronto_saw2_base;
  340. void __iomem *pronto_pll_base;
  341. void __iomem *pronto_mcu_base;
  342. void __iomem *wlan_tx_status;
  343. void __iomem *wlan_tx_phy_aborts;
  344. void __iomem *wlan_brdg_err_source;
  345. void __iomem *alarms_txctl;
  346. void __iomem *alarms_tactl;
  347. void __iomem *fiq_reg;
  348. int nv_downloaded;
  349. int is_cbc_done;
  350. unsigned char *fw_cal_data;
  351. unsigned char *user_cal_data;
  352. int fw_cal_rcvd;
  353. int fw_cal_exp_frag;
  354. int fw_cal_available;
  355. int user_cal_read;
  356. int user_cal_available;
  357. u32 user_cal_rcvd;
  358. u32 user_cal_exp_size;
  359. int iris_xo_mode_set;
  360. int fw_vbatt_state;
  361. int ctrl_device_opened;
  362. char wlan_nv_macAddr[WLAN_MAC_ADDR_SIZE];
  363. struct mutex dev_lock;
  364. struct mutex ctrl_lock;
  365. wait_queue_head_t read_wait;
  366. struct qpnp_adc_tm_btm_param vbat_monitor_params;
  367. struct qpnp_adc_tm_chip *adc_tm_dev;
  368. struct mutex vbat_monitor_mutex;
  369. u16 unsafe_ch_count;
  370. u16 unsafe_ch_list[WCNSS_MAX_CH_NUM];
  371. void *wcnss_notif_hdle;
  372. u8 is_shutdown;
  373. struct pm_qos_request wcnss_pm_qos_request;
  374. int pc_disabled;
  375. struct delayed_work wcnss_pm_qos_del_req;
  376. struct mutex pm_qos_mutex;
  377. } *penv = NULL;
  378. static ssize_t wcnss_wlan_macaddr_store(struct device *dev,
  379. struct device_attribute *attr, const char *buf, size_t count)
  380. {
  381. char macAddr[WLAN_MAC_ADDR_SIZE];
  382. if (!penv)
  383. return -ENODEV;
  384. pr_debug("%s: Receive MAC Addr From user space: %s\n", __func__, buf);
  385. if (WLAN_MAC_ADDR_SIZE != sscanf(buf, MAC_ADDRESS_STR,
  386. &macAddr[0], &macAddr[1],
  387. &macAddr[2], &macAddr[3],
  388. &macAddr[4], &macAddr[5])) {
  389. pr_err("%s: Failed to Copy MAC\n", __func__);
  390. return -EINVAL;
  391. }
  392. memcpy(penv->wlan_nv_macAddr, macAddr, sizeof(penv->wlan_nv_macAddr));
  393. pr_info("%s: Write MAC Addr:" MAC_ADDRESS_STR "\n", __func__,
  394. penv->wlan_nv_macAddr[0], penv->wlan_nv_macAddr[1],
  395. penv->wlan_nv_macAddr[2], penv->wlan_nv_macAddr[3],
  396. penv->wlan_nv_macAddr[4], penv->wlan_nv_macAddr[5]);
  397. return count;
  398. }
  399. static ssize_t wcnss_wlan_macaddr_show(struct device *dev,
  400. struct device_attribute *attr, char *buf)
  401. {
  402. if (!penv)
  403. return -ENODEV;
  404. return scnprintf(buf, PAGE_SIZE, MAC_ADDRESS_STR,
  405. penv->wlan_nv_macAddr[0], penv->wlan_nv_macAddr[1],
  406. penv->wlan_nv_macAddr[2], penv->wlan_nv_macAddr[3],
  407. penv->wlan_nv_macAddr[4], penv->wlan_nv_macAddr[5]);
  408. }
  409. static DEVICE_ATTR(wcnss_mac_addr, S_IRUSR | S_IWUSR,
  410. wcnss_wlan_macaddr_show, wcnss_wlan_macaddr_store);
  411. static ssize_t wcnss_serial_number_show(struct device *dev,
  412. struct device_attribute *attr, char *buf)
  413. {
  414. if (!penv)
  415. return -ENODEV;
  416. return scnprintf(buf, PAGE_SIZE, "%08X\n", penv->serial_number);
  417. }
  418. static ssize_t wcnss_serial_number_store(struct device *dev,
  419. struct device_attribute *attr, const char *buf, size_t count)
  420. {
  421. unsigned int value;
  422. if (!penv)
  423. return -ENODEV;
  424. if (sscanf(buf, "%08X", &value) != 1)
  425. return -EINVAL;
  426. penv->serial_number = value;
  427. return count;
  428. }
  429. static DEVICE_ATTR(serial_number, S_IRUSR | S_IWUSR,
  430. wcnss_serial_number_show, wcnss_serial_number_store);
  431. static ssize_t wcnss_thermal_mitigation_show(struct device *dev,
  432. struct device_attribute *attr, char *buf)
  433. {
  434. if (!penv)
  435. return -ENODEV;
  436. return scnprintf(buf, PAGE_SIZE, "%u\n", penv->thermal_mitigation);
  437. }
  438. static ssize_t wcnss_thermal_mitigation_store(struct device *dev,
  439. struct device_attribute *attr, const char *buf, size_t count)
  440. {
  441. int value;
  442. if (!penv)
  443. return -ENODEV;
  444. if (sscanf(buf, "%d", &value) != 1)
  445. return -EINVAL;
  446. penv->thermal_mitigation = value;
  447. if (penv->tm_notify)
  448. (penv->tm_notify)(dev, value);
  449. return count;
  450. }
  451. static DEVICE_ATTR(thermal_mitigation, S_IRUSR | S_IWUSR,
  452. wcnss_thermal_mitigation_show, wcnss_thermal_mitigation_store);
  453. static ssize_t wcnss_version_show(struct device *dev,
  454. struct device_attribute *attr, char *buf)
  455. {
  456. if (!penv)
  457. return -ENODEV;
  458. return scnprintf(buf, PAGE_SIZE, "%s", penv->wcnss_version);
  459. }
  460. static DEVICE_ATTR(wcnss_version, S_IRUSR,
  461. wcnss_version_show, NULL);
  462. void wcnss_riva_dump_pmic_regs(void)
  463. {
  464. int i, rc;
  465. u8 val;
  466. for (i = 0; i < ARRAY_SIZE(wcnss_pmic_reg_dump); i++) {
  467. val = 0;
  468. rc = pm8xxx_read_register(wcnss_pmic_reg_dump[i].reg_addr,
  469. &val);
  470. if (rc)
  471. pr_err("PMIC READ: Failed to read addr = %d\n",
  472. wcnss_pmic_reg_dump[i].reg_addr);
  473. else
  474. pr_info_ratelimited("PMIC READ: %s addr = %x, value = %x\n",
  475. wcnss_pmic_reg_dump[i].reg_name,
  476. wcnss_pmic_reg_dump[i].reg_addr, val);
  477. }
  478. }
  479. /* wcnss_reset_intr() is invoked when host drivers fails to
  480. * communicate with WCNSS over SMD; so logging these registers
  481. * helps to know WCNSS failure reason
  482. */
  483. void wcnss_riva_log_debug_regs(void)
  484. {
  485. void __iomem *ccu_reg;
  486. u32 reg = 0;
  487. ccu_reg = penv->riva_ccu_base + CCU_RIVA_INVALID_ADDR_OFFSET;
  488. reg = readl_relaxed(ccu_reg);
  489. pr_info_ratelimited("%s: CCU_CCPU_INVALID_ADDR %08x\n", __func__, reg);
  490. ccu_reg = penv->riva_ccu_base + CCU_RIVA_LAST_ADDR0_OFFSET;
  491. reg = readl_relaxed(ccu_reg);
  492. pr_info_ratelimited("%s: CCU_CCPU_LAST_ADDR0 %08x\n", __func__, reg);
  493. ccu_reg = penv->riva_ccu_base + CCU_RIVA_LAST_ADDR1_OFFSET;
  494. reg = readl_relaxed(ccu_reg);
  495. pr_info_ratelimited("%s: CCU_CCPU_LAST_ADDR1 %08x\n", __func__, reg);
  496. ccu_reg = penv->riva_ccu_base + CCU_RIVA_LAST_ADDR2_OFFSET;
  497. reg = readl_relaxed(ccu_reg);
  498. pr_info_ratelimited("%s: CCU_CCPU_LAST_ADDR2 %08x\n", __func__, reg);
  499. wcnss_riva_dump_pmic_regs();
  500. }
  501. EXPORT_SYMBOL(wcnss_riva_log_debug_regs);
  502. void wcnss_pronto_is_a2xb_bus_stall(void *tst_addr, u32 fifo_mask, char *type)
  503. {
  504. u32 iter = 0, reg = 0;
  505. u32 axi_fifo_count = 0, axi_fifo_count_last = 0;
  506. reg = readl_relaxed(tst_addr);
  507. axi_fifo_count = (reg >> A2XB_FIFO_FILL_OFFSET) & fifo_mask;
  508. while ((++iter < A2XB_FIFO_COUNTER) && axi_fifo_count) {
  509. axi_fifo_count_last = axi_fifo_count;
  510. reg = readl_relaxed(tst_addr);
  511. axi_fifo_count = (reg >> A2XB_FIFO_FILL_OFFSET) & fifo_mask;
  512. if (axi_fifo_count < axi_fifo_count_last)
  513. break;
  514. }
  515. if (iter == A2XB_FIFO_COUNTER) {
  516. pr_err("%s data FIFO testbus possibly stalled reg%08x\n",
  517. type, reg);
  518. } else {
  519. pr_err("%s data FIFO tstbus not stalled reg%08x\n",
  520. type, reg);
  521. }
  522. }
  523. /* Log pronto debug registers before sending reset interrupt */
  524. void wcnss_pronto_log_debug_regs(void)
  525. {
  526. void __iomem *reg_addr, *tst_addr, *tst_ctrl_addr;
  527. u32 reg = 0, reg2 = 0, reg3 = 0, reg4 = 0;
  528. reg_addr = penv->msm_wcnss_base + PRONTO_PMU_SPARE_OFFSET;
  529. reg = readl_relaxed(reg_addr);
  530. pr_err("PRONTO_PMU_SPARE %08x\n", reg);
  531. reg_addr = penv->msm_wcnss_base + PRONTO_PMU_COM_CPU_CBCR_OFFSET;
  532. reg = readl_relaxed(reg_addr);
  533. pr_err("PRONTO_PMU_COM_CPU_CBCR %08x\n", reg);
  534. reg_addr = penv->msm_wcnss_base + PRONTO_PMU_COM_AHB_CBCR_OFFSET;
  535. reg = readl_relaxed(reg_addr);
  536. pr_err("PRONTO_PMU_COM_AHB_CBCR %08x\n", reg);
  537. reg_addr = penv->msm_wcnss_base + PRONTO_PMU_CFG_OFFSET;
  538. reg = readl_relaxed(reg_addr);
  539. pr_err("PRONTO_PMU_CFG %08x\n", reg);
  540. reg_addr = penv->msm_wcnss_base + PRONTO_PMU_COM_CSR_OFFSET;
  541. reg = readl_relaxed(reg_addr);
  542. pr_err("PRONTO_PMU_COM_CSR %08x\n", reg);
  543. reg_addr = penv->msm_wcnss_base + PRONTO_PMU_SOFT_RESET_OFFSET;
  544. reg = readl_relaxed(reg_addr);
  545. pr_err("PRONTO_PMU_SOFT_RESET %08x\n", reg);
  546. reg_addr = penv->pronto_saw2_base + PRONTO_SAW2_SPM_STS_OFFSET;
  547. reg = readl_relaxed(reg_addr);
  548. pr_err("PRONTO_SAW2_SPM_STS %08x\n", reg);
  549. reg_addr = penv->pronto_pll_base + PRONTO_PLL_STATUS_OFFSET;
  550. reg = readl_relaxed(reg_addr);
  551. pr_err("PRONTO_PLL_STATUS %08x\n", reg);
  552. reg_addr = penv->msm_wcnss_base + PRONTO_PMU_CPU_AHB_CMD_RCGR_OFFSET;
  553. reg4 = readl_relaxed(reg_addr);
  554. pr_err("PMU_CPU_CMD_RCGR %08x\n", reg4);
  555. reg_addr = penv->msm_wcnss_base + PRONTO_PMU_COM_GDSCR_OFFSET;
  556. reg = readl_relaxed(reg_addr);
  557. pr_err("PRONTO_PMU_COM_GDSCR %08x\n", reg);
  558. reg >>= 31;
  559. if (!reg) {
  560. pr_err("Cannot log, Pronto common SS is power collapsed\n");
  561. return;
  562. }
  563. reg &= ~(PRONTO_PMU_COM_GDSCR_SW_COLLAPSE
  564. | PRONTO_PMU_COM_GDSCR_HW_CTRL);
  565. writel_relaxed(reg, reg_addr);
  566. reg_addr = penv->msm_wcnss_base + PRONTO_PMU_CBCR_OFFSET;
  567. reg = readl_relaxed(reg_addr);
  568. reg |= PRONTO_PMU_CBCR_CLK_EN;
  569. writel_relaxed(reg, reg_addr);
  570. reg_addr = penv->pronto_a2xb_base + A2XB_CFG_OFFSET;
  571. reg = readl_relaxed(reg_addr);
  572. pr_err("A2XB_CFG_OFFSET %08x\n", reg);
  573. reg_addr = penv->pronto_a2xb_base + A2XB_INT_SRC_OFFSET;
  574. reg = readl_relaxed(reg_addr);
  575. pr_err("A2XB_INT_SRC_OFFSET %08x\n", reg);
  576. reg_addr = penv->pronto_a2xb_base + A2XB_ERR_INFO_OFFSET;
  577. reg = readl_relaxed(reg_addr);
  578. pr_err("A2XB_ERR_INFO_OFFSET %08x\n", reg);
  579. reg_addr = penv->pronto_ccpu_base + CCU_PRONTO_INVALID_ADDR_OFFSET;
  580. reg = readl_relaxed(reg_addr);
  581. pr_err("CCU_CCPU_INVALID_ADDR %08x\n", reg);
  582. reg_addr = penv->pronto_ccpu_base + CCU_PRONTO_LAST_ADDR0_OFFSET;
  583. reg = readl_relaxed(reg_addr);
  584. pr_err("CCU_CCPU_LAST_ADDR0 %08x\n", reg);
  585. reg_addr = penv->pronto_ccpu_base + CCU_PRONTO_LAST_ADDR1_OFFSET;
  586. reg = readl_relaxed(reg_addr);
  587. pr_err("CCU_CCPU_LAST_ADDR1 %08x\n", reg);
  588. reg_addr = penv->pronto_ccpu_base + CCU_PRONTO_LAST_ADDR2_OFFSET;
  589. reg = readl_relaxed(reg_addr);
  590. pr_err("CCU_CCPU_LAST_ADDR2 %08x\n", reg);
  591. tst_addr = penv->pronto_a2xb_base + A2XB_TSTBUS_OFFSET;
  592. tst_ctrl_addr = penv->pronto_a2xb_base + A2XB_TSTBUS_CTRL_OFFSET;
  593. /* read data FIFO */
  594. reg = 0;
  595. reg = reg | WCNSS_TSTBUS_CTRL_EN | WCNSS_TSTBUS_CTRL_RDFIFO;
  596. writel_relaxed(reg, tst_ctrl_addr);
  597. reg = readl_relaxed(tst_addr);
  598. if (!(reg & A2XB_FIFO_EMPTY)) {
  599. wcnss_pronto_is_a2xb_bus_stall(tst_addr,
  600. A2XB_READ_FIFO_FILL_MASK, "Read");
  601. } else {
  602. pr_err("Read data FIFO testbus %08x\n", reg);
  603. }
  604. /* command FIFO */
  605. reg = 0;
  606. reg = reg | WCNSS_TSTBUS_CTRL_EN | WCNSS_TSTBUS_CTRL_CMDFIFO;
  607. writel_relaxed(reg, tst_ctrl_addr);
  608. reg = readl_relaxed(tst_addr);
  609. if (!(reg & A2XB_FIFO_EMPTY)) {
  610. wcnss_pronto_is_a2xb_bus_stall(tst_addr,
  611. A2XB_CMD_FIFO_FILL_MASK, "Cmd");
  612. } else {
  613. pr_err("Command FIFO testbus %08x\n", reg);
  614. }
  615. /* write data FIFO */
  616. reg = 0;
  617. reg = reg | WCNSS_TSTBUS_CTRL_EN | WCNSS_TSTBUS_CTRL_WRFIFO;
  618. writel_relaxed(reg, tst_ctrl_addr);
  619. reg = readl_relaxed(tst_addr);
  620. if (!(reg & A2XB_FIFO_EMPTY)) {
  621. wcnss_pronto_is_a2xb_bus_stall(tst_addr,
  622. A2XB_WRITE_FIFO_FILL_MASK, "Write");
  623. } else {
  624. pr_err("Write data FIFO testbus %08x\n", reg);
  625. }
  626. /* AXIM SEL CFG0 */
  627. reg = 0;
  628. reg = reg | WCNSS_TSTBUS_CTRL_EN | WCNSS_TSTBUS_CTRL_AXIM |
  629. WCNSS_TSTBUS_CTRL_AXIM_CFG0;
  630. writel_relaxed(reg, tst_ctrl_addr);
  631. reg = readl_relaxed(tst_addr);
  632. pr_err("AXIM SEL CFG0 testbus %08x\n", reg);
  633. /* AXIM SEL CFG1 */
  634. reg = 0;
  635. reg = reg | WCNSS_TSTBUS_CTRL_EN | WCNSS_TSTBUS_CTRL_AXIM |
  636. WCNSS_TSTBUS_CTRL_AXIM_CFG1;
  637. writel_relaxed(reg, tst_ctrl_addr);
  638. reg = readl_relaxed(tst_addr);
  639. pr_err("AXIM SEL CFG1 testbus %08x\n", reg);
  640. /* CTRL SEL CFG0 */
  641. reg = 0;
  642. reg = reg | WCNSS_TSTBUS_CTRL_EN | WCNSS_TSTBUS_CTRL_CTRL |
  643. WCNSS_TSTBUS_CTRL_CTRL_CFG0;
  644. writel_relaxed(reg, tst_ctrl_addr);
  645. reg = readl_relaxed(tst_addr);
  646. pr_err("CTRL SEL CFG0 testbus %08x\n", reg);
  647. /* CTRL SEL CFG1 */
  648. reg = 0;
  649. reg = reg | WCNSS_TSTBUS_CTRL_EN | WCNSS_TSTBUS_CTRL_CTRL |
  650. WCNSS_TSTBUS_CTRL_CTRL_CFG1;
  651. writel_relaxed(reg, tst_ctrl_addr);
  652. reg = readl_relaxed(tst_addr);
  653. pr_err("CTRL SEL CFG1 testbus %08x\n", reg);
  654. reg_addr = penv->msm_wcnss_base + PRONTO_PMU_WLAN_BCR_OFFSET;
  655. reg = readl_relaxed(reg_addr);
  656. reg_addr = penv->msm_wcnss_base + PRONTO_PMU_WLAN_GDSCR_OFFSET;
  657. reg2 = readl_relaxed(reg_addr);
  658. reg_addr = penv->msm_wcnss_base + PRONTO_PMU_WLAN_AHB_CBCR_OFFSET;
  659. reg3 = readl_relaxed(reg_addr);
  660. pr_err("PMU_WLAN_AHB_CBCR %08x\n", reg3);
  661. if ((reg & PRONTO_PMU_WLAN_BCR_BLK_ARES) ||
  662. (reg2 & PRONTO_PMU_WLAN_GDSCR_SW_COLLAPSE) ||
  663. (!(reg4 & PRONTO_PMU_CPU_AHB_CMD_RCGR_ROOT_EN)) ||
  664. (reg3 & PRONTO_PMU_WLAN_AHB_CBCR_CLK_OFF) ||
  665. (!(reg3 & PRONTO_PMU_WLAN_AHB_CBCR_CLK_EN))) {
  666. pr_err("Cannot log, wlan domain is power collapsed\n");
  667. return;
  668. }
  669. msleep(50);
  670. reg = readl_relaxed(penv->wlan_tx_phy_aborts);
  671. pr_err("WLAN_TX_PHY_ABORTS %08x\n", reg);
  672. reg_addr = penv->pronto_mcu_base + MCU_APB2PHY_STATUS_OFFSET;
  673. reg = readl_relaxed(reg_addr);
  674. pr_err("MCU_APB2PHY_STATUS %08x\n", reg);
  675. reg_addr = penv->pronto_mcu_base + MCU_CBR_CCAHB_ERR_OFFSET;
  676. reg = readl_relaxed(reg_addr);
  677. pr_err("MCU_CBR_CCAHB_ERR %08x\n", reg);
  678. reg_addr = penv->pronto_mcu_base + MCU_CBR_CAHB_ERR_OFFSET;
  679. reg = readl_relaxed(reg_addr);
  680. pr_err("MCU_CBR_CAHB_ERR %08x\n", reg);
  681. reg_addr = penv->pronto_mcu_base + MCU_CBR_CCAHB_TIMEOUT_OFFSET;
  682. reg = readl_relaxed(reg_addr);
  683. pr_err("MCU_CBR_CCAHB_TIMEOUT %08x\n", reg);
  684. reg_addr = penv->pronto_mcu_base + MCU_CBR_CAHB_TIMEOUT_OFFSET;
  685. reg = readl_relaxed(reg_addr);
  686. pr_err("MCU_CBR_CAHB_TIMEOUT %08x\n", reg);
  687. reg_addr = penv->pronto_mcu_base + MCU_DBR_CDAHB_ERR_OFFSET;
  688. reg = readl_relaxed(reg_addr);
  689. pr_err("MCU_DBR_CDAHB_ERR %08x\n", reg);
  690. reg_addr = penv->pronto_mcu_base + MCU_DBR_DAHB_ERR_OFFSET;
  691. reg = readl_relaxed(reg_addr);
  692. pr_err("MCU_DBR_DAHB_ERR %08x\n", reg);
  693. reg_addr = penv->pronto_mcu_base + MCU_DBR_CDAHB_TIMEOUT_OFFSET;
  694. reg = readl_relaxed(reg_addr);
  695. pr_err("MCU_DBR_CDAHB_TIMEOUT %08x\n", reg);
  696. reg_addr = penv->pronto_mcu_base + MCU_DBR_DAHB_TIMEOUT_OFFSET;
  697. reg = readl_relaxed(reg_addr);
  698. pr_err("MCU_DBR_DAHB_TIMEOUT %08x\n", reg);
  699. reg_addr = penv->pronto_mcu_base + MCU_FDBR_CDAHB_ERR_OFFSET;
  700. reg = readl_relaxed(reg_addr);
  701. pr_err("MCU_FDBR_CDAHB_ERR %08x\n", reg);
  702. reg_addr = penv->pronto_mcu_base + MCU_FDBR_FDAHB_ERR_OFFSET;
  703. reg = readl_relaxed(reg_addr);
  704. pr_err("MCU_FDBR_FDAHB_ERR %08x\n", reg);
  705. reg_addr = penv->pronto_mcu_base + MCU_FDBR_CDAHB_TIMEOUT_OFFSET;
  706. reg = readl_relaxed(reg_addr);
  707. pr_err("MCU_FDBR_CDAHB_TIMEOUT %08x\n", reg);
  708. reg_addr = penv->pronto_mcu_base + MCU_FDBR_FDAHB_TIMEOUT_OFFSET;
  709. reg = readl_relaxed(reg_addr);
  710. pr_err("MCU_FDBR_FDAHB_TIMEOUT %08x\n", reg);
  711. reg = readl_relaxed(penv->wlan_brdg_err_source);
  712. pr_err("WLAN_BRDG_ERR_SOURCE %08x\n", reg);
  713. reg = readl_relaxed(penv->wlan_tx_status);
  714. pr_err("WLAN_TXP_STATUS %08x\n", reg);
  715. reg = readl_relaxed(penv->alarms_txctl);
  716. pr_err("ALARMS_TXCTL %08x\n", reg);
  717. reg = readl_relaxed(penv->alarms_tactl);
  718. pr_err("ALARMS_TACTL %08x\n", reg);
  719. }
  720. EXPORT_SYMBOL(wcnss_pronto_log_debug_regs);
  721. #ifdef CONFIG_WCNSS_REGISTER_DUMP_ON_BITE
  722. static void wcnss_log_iris_regs(void)
  723. {
  724. int i;
  725. u32 reg_val;
  726. u32 regs_array[] = {
  727. 0x04, 0x05, 0x11, 0x1e, 0x40, 0x48,
  728. 0x49, 0x4b, 0x00, 0x01, 0x4d};
  729. pr_info("IRIS Registers [address] : value\n");
  730. for (i = 0; i < ARRAY_SIZE(regs_array); i++) {
  731. reg_val = wcnss_rf_read_reg(regs_array[i]);
  732. pr_info("[0x%08x] : 0x%08x\n", regs_array[i], reg_val);
  733. }
  734. }
  735. int wcnss_get_mux_control(void)
  736. {
  737. void __iomem *pmu_conf_reg;
  738. u32 reg = 0;
  739. if (NULL == penv)
  740. return 0;
  741. pmu_conf_reg = penv->msm_wcnss_base + PRONTO_PMU_OFFSET;
  742. reg = readl_relaxed(pmu_conf_reg);
  743. reg |= WCNSS_PMU_CFG_GC_BUS_MUX_SEL_TOP;
  744. writel_relaxed(reg, pmu_conf_reg);
  745. return 1;
  746. }
  747. void wcnss_log_debug_regs_on_bite(void)
  748. {
  749. struct platform_device *pdev = wcnss_get_platform_device();
  750. struct clk *measure;
  751. struct clk *wcnss_debug_mux;
  752. unsigned long clk_rate;
  753. if (wcnss_hardware_type() != WCNSS_PRONTO_HW)
  754. return;
  755. measure = clk_get(&pdev->dev, "measure");
  756. wcnss_debug_mux = clk_get(&pdev->dev, "wcnss_debug");
  757. if (!IS_ERR(measure) && !IS_ERR(wcnss_debug_mux)) {
  758. if (clk_set_parent(measure, wcnss_debug_mux))
  759. return;
  760. clk_rate = clk_get_rate(measure);
  761. pr_debug("wcnss: clock frequency is: %luHz\n", clk_rate);
  762. if (clk_rate) {
  763. wcnss_pronto_log_debug_regs();
  764. if (wcnss_get_mux_control())
  765. wcnss_log_iris_regs();
  766. } else {
  767. pr_err("clock frequency is zero, cannot access PMU or other registers\n");
  768. wcnss_log_iris_regs();
  769. }
  770. }
  771. }
  772. #endif
  773. /* interface to reset wcnss by sending the reset interrupt */
  774. void wcnss_reset_intr(void)
  775. {
  776. if (wcnss_hardware_type() == WCNSS_PRONTO_HW) {
  777. wcnss_pronto_log_debug_regs();
  778. if (wcnss_get_mux_control())
  779. wcnss_log_iris_regs();
  780. wmb();
  781. __raw_writel(1 << 16, penv->fiq_reg);
  782. } else {
  783. wcnss_riva_log_debug_regs();
  784. wmb();
  785. __raw_writel(1 << 24, MSM_APCS_GCC_BASE + 0x8);
  786. }
  787. }
  788. EXPORT_SYMBOL(wcnss_reset_intr);
  789. void wcnss_reset_fiq(bool clk_chk_en)
  790. {
  791. if (wcnss_hardware_type() == WCNSS_PRONTO_HW) {
  792. if (clk_chk_en) {
  793. wcnss_log_debug_regs_on_bite();
  794. } else {
  795. wcnss_pronto_log_debug_regs();
  796. if (wcnss_get_mux_control())
  797. wcnss_log_iris_regs();
  798. }
  799. /* Insert memory barrier before writing fiq register */
  800. wmb();
  801. __raw_writel(1 << 16, penv->fiq_reg);
  802. } else {
  803. wcnss_riva_log_debug_regs();
  804. }
  805. }
  806. EXPORT_SYMBOL(wcnss_reset_fiq);
  807. static int wcnss_create_sysfs(struct device *dev)
  808. {
  809. int ret;
  810. if (!dev)
  811. return -ENODEV;
  812. ret = device_create_file(dev, &dev_attr_serial_number);
  813. if (ret)
  814. return ret;
  815. ret = device_create_file(dev, &dev_attr_thermal_mitigation);
  816. if (ret)
  817. goto remove_serial;
  818. ret = device_create_file(dev, &dev_attr_wcnss_version);
  819. if (ret)
  820. goto remove_thermal;
  821. ret = device_create_file(dev, &dev_attr_wcnss_mac_addr);
  822. if (ret)
  823. goto remove_version;
  824. return 0;
  825. remove_version:
  826. device_remove_file(dev, &dev_attr_wcnss_version);
  827. remove_thermal:
  828. device_remove_file(dev, &dev_attr_thermal_mitigation);
  829. remove_serial:
  830. device_remove_file(dev, &dev_attr_serial_number);
  831. return ret;
  832. }
  833. static void wcnss_remove_sysfs(struct device *dev)
  834. {
  835. if (dev) {
  836. device_remove_file(dev, &dev_attr_serial_number);
  837. device_remove_file(dev, &dev_attr_thermal_mitigation);
  838. device_remove_file(dev, &dev_attr_wcnss_version);
  839. device_remove_file(dev, &dev_attr_wcnss_mac_addr);
  840. }
  841. }
  842. static void wcnss_pm_qos_add_request(void)
  843. {
  844. pr_info("%s: add request\n", __func__);
  845. pm_qos_add_request(&penv->wcnss_pm_qos_request, PM_QOS_CPU_DMA_LATENCY,
  846. PM_QOS_DEFAULT_VALUE);
  847. }
  848. static void wcnss_pm_qos_remove_request(void)
  849. {
  850. pr_info("%s: remove request\n", __func__);
  851. pm_qos_remove_request(&penv->wcnss_pm_qos_request);
  852. }
  853. void wcnss_pm_qos_update_request(int val)
  854. {
  855. pr_info("%s: update request %d\n", __func__, val);
  856. pm_qos_update_request(&penv->wcnss_pm_qos_request, val);
  857. }
  858. void wcnss_disable_pc_remove_req(void)
  859. {
  860. mutex_lock(&penv->pm_qos_mutex);
  861. if (penv->pc_disabled) {
  862. penv->pc_disabled = 0;
  863. wcnss_pm_qos_update_request(WCNSS_ENABLE_PC_LATENCY);
  864. wcnss_pm_qos_remove_request();
  865. wcnss_allow_suspend();
  866. }
  867. mutex_unlock(&penv->pm_qos_mutex);
  868. }
  869. void wcnss_disable_pc_add_req(void)
  870. {
  871. mutex_lock(&penv->pm_qos_mutex);
  872. if (!penv->pc_disabled) {
  873. wcnss_pm_qos_add_request();
  874. wcnss_prevent_suspend();
  875. wcnss_pm_qos_update_request(WCNSS_DISABLE_PC_LATENCY);
  876. penv->pc_disabled = 1;
  877. }
  878. mutex_unlock(&penv->pm_qos_mutex);
  879. }
  880. static void wcnss_smd_notify_event(void *data, unsigned int event)
  881. {
  882. int len = 0;
  883. if (penv != data) {
  884. pr_err("wcnss: invalid env pointer in smd callback\n");
  885. return;
  886. }
  887. switch (event) {
  888. case SMD_EVENT_DATA:
  889. len = smd_read_avail(penv->smd_ch);
  890. if (len < 0) {
  891. pr_err("wcnss: failed to read from smd %d\n", len);
  892. return;
  893. }
  894. schedule_work(&penv->wcnssctrl_rx_work);
  895. break;
  896. case SMD_EVENT_OPEN:
  897. pr_debug("wcnss: opening WCNSS SMD channel :%s",
  898. WCNSS_CTRL_CHANNEL);
  899. schedule_work(&penv->wcnssctrl_version_work);
  900. schedule_work(&penv->wcnss_pm_config_work);
  901. __cancel_delayed_work(&penv->wcnss_pm_qos_del_req);
  902. schedule_delayed_work(&penv->wcnss_pm_qos_del_req, 0);
  903. break;
  904. case SMD_EVENT_CLOSE:
  905. pr_debug("wcnss: closing WCNSS SMD channel :%s",
  906. WCNSS_CTRL_CHANNEL);
  907. penv->nv_downloaded = 0;
  908. penv->is_cbc_done = 0;
  909. break;
  910. default:
  911. break;
  912. }
  913. }
  914. static void wcnss_post_bootup(struct work_struct *work)
  915. {
  916. if (do_not_cancel_vote == 1) {
  917. pr_info("%s: Keeping APPS vote for Iris & WCNSS\n", __func__);
  918. return;
  919. }
  920. pr_info("%s: Cancel APPS vote for Iris & WCNSS\n", __func__);
  921. /* Since WCNSS is up, cancel any APPS vote for Iris & WCNSS VREGs */
  922. wcnss_wlan_power(&penv->pdev->dev, &penv->wlan_config,
  923. WCNSS_WLAN_SWITCH_OFF, NULL);
  924. }
  925. static int
  926. wcnss_pronto_gpios_config(struct device *dev, bool enable)
  927. {
  928. int rc = 0;
  929. int i, j;
  930. int WCNSS_WLAN_NUM_GPIOS = 5;
  931. for (i = 0; i < WCNSS_WLAN_NUM_GPIOS; i++) {
  932. int gpio = of_get_gpio(dev->of_node, i);
  933. if (enable) {
  934. rc = gpio_request(gpio, "wcnss_wlan");
  935. if (rc) {
  936. pr_err("WCNSS gpio_request %d err %d\n",
  937. gpio, rc);
  938. goto fail;
  939. }
  940. } else
  941. gpio_free(gpio);
  942. }
  943. return rc;
  944. fail:
  945. for (j = WCNSS_WLAN_NUM_GPIOS-1; j >= 0; j--) {
  946. int gpio = of_get_gpio(dev->of_node, i);
  947. gpio_free(gpio);
  948. }
  949. return rc;
  950. }
  951. static int
  952. wcnss_gpios_config(struct resource *gpios_5wire, bool enable)
  953. {
  954. int i, j;
  955. int rc = 0;
  956. for (i = gpios_5wire->start; i <= gpios_5wire->end; i++) {
  957. if (enable) {
  958. rc = gpio_request(i, gpios_5wire->name);
  959. if (rc) {
  960. pr_err("WCNSS gpio_request %d err %d\n", i, rc);
  961. goto fail;
  962. }
  963. } else
  964. gpio_free(i);
  965. }
  966. return rc;
  967. fail:
  968. for (j = i-1; j >= gpios_5wire->start; j--)
  969. gpio_free(j);
  970. return rc;
  971. }
  972. static int __devinit
  973. wcnss_wlan_ctrl_probe(struct platform_device *pdev)
  974. {
  975. if (!penv || !penv->triggered)
  976. return -ENODEV;
  977. penv->smd_channel_ready = 1;
  978. pr_info("%s: SMD ctrl channel up\n", __func__);
  979. /* Schedule a work to do any post boot up activity */
  980. INIT_DELAYED_WORK(&penv->wcnss_work, wcnss_post_bootup);
  981. schedule_delayed_work(&penv->wcnss_work, msecs_to_jiffies(10000));
  982. return 0;
  983. }
  984. void wcnss_flush_delayed_boot_votes()
  985. {
  986. flush_delayed_work(&penv->wcnss_work);
  987. }
  988. EXPORT_SYMBOL(wcnss_flush_delayed_boot_votes);
  989. static int __devexit
  990. wcnss_wlan_ctrl_remove(struct platform_device *pdev)
  991. {
  992. if (penv)
  993. penv->smd_channel_ready = 0;
  994. pr_info("%s: SMD ctrl channel down\n", __func__);
  995. return 0;
  996. }
  997. static struct platform_driver wcnss_wlan_ctrl_driver = {
  998. .driver = {
  999. .name = "WLAN_CTRL",
  1000. .owner = THIS_MODULE,
  1001. },
  1002. .probe = wcnss_wlan_ctrl_probe,
  1003. .remove = __devexit_p(wcnss_wlan_ctrl_remove),
  1004. };
  1005. static int __devexit
  1006. wcnss_ctrl_remove(struct platform_device *pdev)
  1007. {
  1008. if (penv && penv->smd_ch)
  1009. smd_close(penv->smd_ch);
  1010. return 0;
  1011. }
  1012. static int __devinit
  1013. wcnss_ctrl_probe(struct platform_device *pdev)
  1014. {
  1015. int ret = 0;
  1016. if (!penv || !penv->triggered)
  1017. return -ENODEV;
  1018. ret = smd_named_open_on_edge(WCNSS_CTRL_CHANNEL, SMD_APPS_WCNSS,
  1019. &penv->smd_ch, penv, wcnss_smd_notify_event);
  1020. if (ret < 0) {
  1021. pr_err("wcnss: cannot open the smd command channel %s: %d\n",
  1022. WCNSS_CTRL_CHANNEL, ret);
  1023. return -ENODEV;
  1024. }
  1025. smd_disable_read_intr(penv->smd_ch);
  1026. return 0;
  1027. }
  1028. /* platform device for WCNSS_CTRL SMD channel */
  1029. static struct platform_driver wcnss_ctrl_driver = {
  1030. .driver = {
  1031. .name = "WCNSS_CTRL",
  1032. .owner = THIS_MODULE,
  1033. },
  1034. .probe = wcnss_ctrl_probe,
  1035. .remove = __devexit_p(wcnss_ctrl_remove),
  1036. };
  1037. void wcnss_get_monotonic_boottime(struct timespec *ts)
  1038. {
  1039. get_monotonic_boottime(ts);
  1040. }
  1041. EXPORT_SYMBOL(wcnss_get_monotonic_boottime);
  1042. struct device *wcnss_wlan_get_device(void)
  1043. {
  1044. if (penv && penv->pdev && penv->smd_channel_ready)
  1045. return &penv->pdev->dev;
  1046. return NULL;
  1047. }
  1048. EXPORT_SYMBOL(wcnss_wlan_get_device);
  1049. struct platform_device *wcnss_get_platform_device(void)
  1050. {
  1051. if (penv && penv->pdev)
  1052. return penv->pdev;
  1053. return NULL;
  1054. }
  1055. EXPORT_SYMBOL(wcnss_get_platform_device);
  1056. struct wcnss_wlan_config *wcnss_get_wlan_config(void)
  1057. {
  1058. if (penv && penv->pdev)
  1059. return &penv->wlan_config;
  1060. return NULL;
  1061. }
  1062. EXPORT_SYMBOL(wcnss_get_wlan_config);
  1063. int wcnss_is_hw_pronto_ver3(void)
  1064. {
  1065. if (penv && penv->pdev)
  1066. return penv->wlan_config.is_pronto_v3;
  1067. return 0;
  1068. }
  1069. EXPORT_SYMBOL(wcnss_is_hw_pronto_ver3);
  1070. int wcnss_device_ready(void)
  1071. {
  1072. if (penv && penv->pdev && penv->nv_downloaded &&
  1073. !wcnss_device_is_shutdown())
  1074. return 1;
  1075. return 0;
  1076. }
  1077. EXPORT_SYMBOL(wcnss_device_ready);
  1078. bool wcnss_cbc_complete(void)
  1079. {
  1080. if (penv && penv->pdev && penv->is_cbc_done &&
  1081. !wcnss_device_is_shutdown())
  1082. return true;
  1083. return false;
  1084. }
  1085. EXPORT_SYMBOL(wcnss_cbc_complete);
  1086. int wcnss_device_is_shutdown(void)
  1087. {
  1088. if (penv && penv->is_shutdown)
  1089. return 1;
  1090. return 0;
  1091. }
  1092. EXPORT_SYMBOL(wcnss_device_is_shutdown);
  1093. struct resource *wcnss_wlan_get_memory_map(struct device *dev)
  1094. {
  1095. if (penv && dev && (dev == &penv->pdev->dev) && penv->smd_channel_ready)
  1096. return penv->mmio_res;
  1097. return NULL;
  1098. }
  1099. EXPORT_SYMBOL(wcnss_wlan_get_memory_map);
  1100. int wcnss_wlan_get_dxe_tx_irq(struct device *dev)
  1101. {
  1102. if (penv && dev && (dev == &penv->pdev->dev) &&
  1103. penv->tx_irq_res && penv->smd_channel_ready)
  1104. return penv->tx_irq_res->start;
  1105. return WCNSS_WLAN_IRQ_INVALID;
  1106. }
  1107. EXPORT_SYMBOL(wcnss_wlan_get_dxe_tx_irq);
  1108. int wcnss_wlan_get_dxe_rx_irq(struct device *dev)
  1109. {
  1110. if (penv && dev && (dev == &penv->pdev->dev) &&
  1111. penv->rx_irq_res && penv->smd_channel_ready)
  1112. return penv->rx_irq_res->start;
  1113. return WCNSS_WLAN_IRQ_INVALID;
  1114. }
  1115. EXPORT_SYMBOL(wcnss_wlan_get_dxe_rx_irq);
  1116. void wcnss_wlan_register_pm_ops(struct device *dev,
  1117. const struct dev_pm_ops *pm_ops)
  1118. {
  1119. if (penv && dev && (dev == &penv->pdev->dev) && pm_ops)
  1120. penv->pm_ops = pm_ops;
  1121. }
  1122. EXPORT_SYMBOL(wcnss_wlan_register_pm_ops);
  1123. void wcnss_wlan_unregister_pm_ops(struct device *dev,
  1124. const struct dev_pm_ops *pm_ops)
  1125. {
  1126. if (penv && dev && (dev == &penv->pdev->dev) && pm_ops) {
  1127. if (penv->pm_ops == NULL) {
  1128. pr_err("%s: pm_ops is already unregistered.\n",
  1129. __func__);
  1130. return;
  1131. }
  1132. if (pm_ops->suspend != penv->pm_ops->suspend ||
  1133. pm_ops->resume != penv->pm_ops->resume)
  1134. pr_err("PM APIs dont match with registered APIs\n");
  1135. penv->pm_ops = NULL;
  1136. }
  1137. }
  1138. EXPORT_SYMBOL(wcnss_wlan_unregister_pm_ops);
  1139. void wcnss_register_thermal_mitigation(struct device *dev,
  1140. void (*tm_notify)(struct device *, int))
  1141. {
  1142. if (penv && dev && tm_notify)
  1143. penv->tm_notify = tm_notify;
  1144. }
  1145. EXPORT_SYMBOL(wcnss_register_thermal_mitigation);
  1146. void wcnss_unregister_thermal_mitigation(
  1147. void (*tm_notify)(struct device *, int))
  1148. {
  1149. if (penv && tm_notify) {
  1150. if (tm_notify != penv->tm_notify)
  1151. pr_err("tm_notify doesn't match registered\n");
  1152. penv->tm_notify = NULL;
  1153. }
  1154. }
  1155. EXPORT_SYMBOL(wcnss_unregister_thermal_mitigation);
  1156. unsigned int wcnss_get_serial_number(void)
  1157. {
  1158. if (penv)
  1159. return penv->serial_number;
  1160. return 0;
  1161. }
  1162. EXPORT_SYMBOL(wcnss_get_serial_number);
  1163. int wcnss_get_wlan_mac_address(char mac_addr[WLAN_MAC_ADDR_SIZE])
  1164. {
  1165. if (!penv)
  1166. return -ENODEV;
  1167. memcpy(mac_addr, penv->wlan_nv_macAddr, WLAN_MAC_ADDR_SIZE);
  1168. pr_debug("%s: Get MAC Addr:" MAC_ADDRESS_STR "\n", __func__,
  1169. penv->wlan_nv_macAddr[0], penv->wlan_nv_macAddr[1],
  1170. penv->wlan_nv_macAddr[2], penv->wlan_nv_macAddr[3],
  1171. penv->wlan_nv_macAddr[4], penv->wlan_nv_macAddr[5]);
  1172. return 0;
  1173. }
  1174. EXPORT_SYMBOL(wcnss_get_wlan_mac_address);
  1175. static int enable_wcnss_suspend_notify;
  1176. static int enable_wcnss_suspend_notify_set(const char *val,
  1177. struct kernel_param *kp)
  1178. {
  1179. int ret;
  1180. ret = param_set_int(val, kp);
  1181. if (ret)
  1182. return ret;
  1183. if (enable_wcnss_suspend_notify)
  1184. pr_debug("Suspend notification activated for wcnss\n");
  1185. return 0;
  1186. }
  1187. module_param_call(enable_wcnss_suspend_notify, enable_wcnss_suspend_notify_set,
  1188. param_get_int, &enable_wcnss_suspend_notify, S_IRUGO | S_IWUSR);
  1189. int wcnss_xo_auto_detect_enabled(void)
  1190. {
  1191. return (has_autodetect_xo == 1 ? 1 : 0);
  1192. }
  1193. int wcnss_wlan_iris_xo_mode(void)
  1194. {
  1195. if (penv && penv->pdev && penv->smd_channel_ready)
  1196. return penv->iris_xo_mode_set;
  1197. return -ENODEV;
  1198. }
  1199. EXPORT_SYMBOL(wcnss_wlan_iris_xo_mode);
  1200. void wcnss_suspend_notify(void)
  1201. {
  1202. void __iomem *pmu_spare_reg;
  1203. u32 reg = 0;
  1204. unsigned long flags;
  1205. if (!enable_wcnss_suspend_notify)
  1206. return;
  1207. if (wcnss_hardware_type() == WCNSS_PRONTO_HW)
  1208. return;
  1209. /* For Riva */
  1210. pmu_spare_reg = penv->msm_wcnss_base + RIVA_SPARE_OFFSET;
  1211. spin_lock_irqsave(&reg_spinlock, flags);
  1212. reg = readl_relaxed(pmu_spare_reg);
  1213. reg |= RIVA_SUSPEND_BIT;
  1214. writel_relaxed(reg, pmu_spare_reg);
  1215. spin_unlock_irqrestore(&reg_spinlock, flags);
  1216. }
  1217. EXPORT_SYMBOL(wcnss_suspend_notify);
  1218. void wcnss_resume_notify(void)
  1219. {
  1220. void __iomem *pmu_spare_reg;
  1221. u32 reg = 0;
  1222. unsigned long flags;
  1223. if (!enable_wcnss_suspend_notify)
  1224. return;
  1225. if (wcnss_hardware_type() == WCNSS_PRONTO_HW)
  1226. return;
  1227. /* For Riva */
  1228. pmu_spare_reg = penv->msm_wcnss_base + RIVA_SPARE_OFFSET;
  1229. spin_lock_irqsave(&reg_spinlock, flags);
  1230. reg = readl_relaxed(pmu_spare_reg);
  1231. reg &= ~RIVA_SUSPEND_BIT;
  1232. writel_relaxed(reg, pmu_spare_reg);
  1233. spin_unlock_irqrestore(&reg_spinlock, flags);
  1234. }
  1235. EXPORT_SYMBOL(wcnss_resume_notify);
  1236. static int wcnss_wlan_suspend(struct device *dev)
  1237. {
  1238. if (penv && dev && (dev == &penv->pdev->dev) &&
  1239. penv->smd_channel_ready &&
  1240. penv->pm_ops && penv->pm_ops->suspend)
  1241. return penv->pm_ops->suspend(dev);
  1242. return 0;
  1243. }
  1244. static int wcnss_wlan_resume(struct device *dev)
  1245. {
  1246. if (penv && dev && (dev == &penv->pdev->dev) &&
  1247. penv->smd_channel_ready &&
  1248. penv->pm_ops && penv->pm_ops->resume)
  1249. return penv->pm_ops->resume(dev);
  1250. return 0;
  1251. }
  1252. void wcnss_prevent_suspend()
  1253. {
  1254. if (penv)
  1255. wake_lock(&penv->wcnss_wake_lock);
  1256. }
  1257. EXPORT_SYMBOL(wcnss_prevent_suspend);
  1258. void wcnss_allow_suspend()
  1259. {
  1260. if (penv)
  1261. wake_unlock(&penv->wcnss_wake_lock);
  1262. }
  1263. EXPORT_SYMBOL(wcnss_allow_suspend);
  1264. int wcnss_hardware_type(void)
  1265. {
  1266. if (penv)
  1267. return penv->wcnss_hw_type;
  1268. else
  1269. return -ENODEV;
  1270. }
  1271. EXPORT_SYMBOL(wcnss_hardware_type);
  1272. int fw_cal_data_available(void)
  1273. {
  1274. if (penv)
  1275. return penv->fw_cal_available;
  1276. else
  1277. return -ENODEV;
  1278. }
  1279. u32 wcnss_get_wlan_rx_buff_count(void)
  1280. {
  1281. if (penv)
  1282. return penv->wlan_rx_buff_count;
  1283. else
  1284. return WCNSS_DEF_WLAN_RX_BUFF_COUNT;
  1285. }
  1286. EXPORT_SYMBOL(wcnss_get_wlan_rx_buff_count);
  1287. int wcnss_set_wlan_unsafe_channel(u16 *unsafe_ch_list, u16 ch_count)
  1288. {
  1289. if (penv && unsafe_ch_list &&
  1290. (ch_count <= WCNSS_MAX_CH_NUM)) {
  1291. memcpy((char *)penv->unsafe_ch_list,
  1292. (char *)unsafe_ch_list, ch_count * sizeof(u16));
  1293. penv->unsafe_ch_count = ch_count;
  1294. return 0;
  1295. } else
  1296. return -ENODEV;
  1297. }
  1298. EXPORT_SYMBOL(wcnss_set_wlan_unsafe_channel);
  1299. int wcnss_get_wlan_unsafe_channel(u16 *unsafe_ch_list, u16 buffer_size,
  1300. u16 *ch_count)
  1301. {
  1302. if (penv) {
  1303. if (buffer_size < penv->unsafe_ch_count * sizeof(u16))
  1304. return -ENODEV;
  1305. memcpy((char *)unsafe_ch_list,
  1306. (char *)penv->unsafe_ch_list,
  1307. penv->unsafe_ch_count * sizeof(u16));
  1308. *ch_count = penv->unsafe_ch_count;
  1309. return 0;
  1310. } else
  1311. return -ENODEV;
  1312. }
  1313. EXPORT_SYMBOL(wcnss_get_wlan_unsafe_channel);
  1314. static int wcnss_smd_tx(void *data, int len)
  1315. {
  1316. int ret = 0;
  1317. ret = smd_write_avail(penv->smd_ch);
  1318. if (ret < len) {
  1319. pr_err("wcnss: no space available for smd frame\n");
  1320. return -ENOSPC;
  1321. }
  1322. ret = smd_write(penv->smd_ch, data, len);
  1323. if (ret < len) {
  1324. pr_err("wcnss: failed to write Command %d", len);
  1325. ret = -ENODEV;
  1326. }
  1327. return ret;
  1328. }
  1329. static void wcnss_notify_vbat(enum qpnp_tm_state state, void *ctx)
  1330. {
  1331. mutex_lock(&penv->vbat_monitor_mutex);
  1332. cancel_delayed_work_sync(&penv->vbatt_work);
  1333. if (state == ADC_TM_LOW_STATE) {
  1334. pr_debug("wcnss: low voltage notification triggered\n");
  1335. penv->vbat_monitor_params.state_request =
  1336. ADC_TM_HIGH_THR_ENABLE;
  1337. penv->vbat_monitor_params.high_thr = WCNSS_VBATT_THRESHOLD +
  1338. WCNSS_VBATT_GUARD;
  1339. penv->vbat_monitor_params.low_thr = 0;
  1340. } else if (state == ADC_TM_HIGH_STATE) {
  1341. penv->vbat_monitor_params.state_request =
  1342. ADC_TM_LOW_THR_ENABLE;
  1343. penv->vbat_monitor_params.low_thr = WCNSS_VBATT_THRESHOLD -
  1344. WCNSS_VBATT_GUARD;
  1345. penv->vbat_monitor_params.high_thr = 0;
  1346. pr_debug("wcnss: high voltage notification triggered\n");
  1347. } else {
  1348. pr_debug("wcnss: unknown voltage notification state: %d\n",
  1349. state);
  1350. mutex_unlock(&penv->vbat_monitor_mutex);
  1351. return;
  1352. }
  1353. pr_debug("wcnss: set low thr to %d and high to %d\n",
  1354. penv->vbat_monitor_params.low_thr,
  1355. penv->vbat_monitor_params.high_thr);
  1356. qpnp_adc_tm_channel_measure(penv->adc_tm_dev,
  1357. &penv->vbat_monitor_params);
  1358. schedule_delayed_work(&penv->vbatt_work, msecs_to_jiffies(2000));
  1359. mutex_unlock(&penv->vbat_monitor_mutex);
  1360. }
  1361. static int wcnss_setup_vbat_monitoring(void)
  1362. {
  1363. int rc = -1;
  1364. if (!penv->adc_tm_dev) {
  1365. pr_err("wcnss: not setting up vbatt\n");
  1366. return rc;
  1367. }
  1368. penv->vbat_monitor_params.low_thr = WCNSS_VBATT_THRESHOLD;
  1369. penv->vbat_monitor_params.high_thr = WCNSS_VBATT_THRESHOLD;
  1370. penv->vbat_monitor_params.state_request = ADC_TM_HIGH_LOW_THR_ENABLE;
  1371. penv->vbat_monitor_params.channel = VBAT_SNS;
  1372. penv->vbat_monitor_params.btm_ctx = (void *)penv;
  1373. penv->vbat_monitor_params.timer_interval = ADC_MEAS1_INTERVAL_1S;
  1374. penv->vbat_monitor_params.threshold_notification = &wcnss_notify_vbat;
  1375. pr_debug("wcnss: set low thr to %d and high to %d\n",
  1376. penv->vbat_monitor_params.low_thr,
  1377. penv->vbat_monitor_params.high_thr);
  1378. rc = qpnp_adc_tm_channel_measure(penv->adc_tm_dev,
  1379. &penv->vbat_monitor_params);
  1380. if (rc)
  1381. pr_err("wcnss: tm setup failed: %d\n", rc);
  1382. return rc;
  1383. }
  1384. static void wcnss_update_vbatt(struct work_struct *work)
  1385. {
  1386. struct vbatt_message vbatt_msg;
  1387. int ret = 0;
  1388. vbatt_msg.hdr.msg_type = WCNSS_VBATT_LEVEL_IND;
  1389. vbatt_msg.hdr.msg_len = sizeof(struct vbatt_message);
  1390. vbatt_msg.vbatt.threshold = WCNSS_VBATT_THRESHOLD;
  1391. mutex_lock(&penv->vbat_monitor_mutex);
  1392. if (penv->vbat_monitor_params.low_thr &&
  1393. (penv->fw_vbatt_state == WCNSS_VBATT_LOW ||
  1394. penv->fw_vbatt_state == WCNSS_CONFIG_UNSPECIFIED)) {
  1395. vbatt_msg.vbatt.curr_volt = WCNSS_VBATT_HIGH;
  1396. penv->fw_vbatt_state = WCNSS_VBATT_HIGH;
  1397. pr_debug("wcnss: send HIGH BATT to FW\n");
  1398. } else if (!penv->vbat_monitor_params.low_thr &&
  1399. (penv->fw_vbatt_state == WCNSS_VBATT_HIGH ||
  1400. penv->fw_vbatt_state == WCNSS_CONFIG_UNSPECIFIED)){
  1401. vbatt_msg.vbatt.curr_volt = WCNSS_VBATT_LOW;
  1402. penv->fw_vbatt_state = WCNSS_VBATT_LOW;
  1403. pr_debug("wcnss: send LOW BATT to FW\n");
  1404. } else {
  1405. mutex_unlock(&penv->vbat_monitor_mutex);
  1406. return;
  1407. }
  1408. mutex_unlock(&penv->vbat_monitor_mutex);
  1409. ret = wcnss_smd_tx(&vbatt_msg, vbatt_msg.hdr.msg_len);
  1410. if (ret < 0)
  1411. pr_err("wcnss: smd tx failed\n");
  1412. return;
  1413. }
  1414. static unsigned char wcnss_fw_status(void)
  1415. {
  1416. int len = 0;
  1417. int rc = 0;
  1418. unsigned char fw_status = 0xFF;
  1419. len = smd_read_avail(penv->smd_ch);
  1420. if (len < 1) {
  1421. pr_err("%s: invalid firmware status", __func__);
  1422. return fw_status;
  1423. }
  1424. rc = smd_read(penv->smd_ch, &fw_status, 1);
  1425. if (rc < 0) {
  1426. pr_err("%s: incomplete data read from smd\n", __func__);
  1427. return fw_status;
  1428. }
  1429. return fw_status;
  1430. }
  1431. static void wcnss_send_cal_rsp(unsigned char fw_status)
  1432. {
  1433. struct smd_msg_hdr *rsphdr;
  1434. unsigned char *msg = NULL;
  1435. int rc;
  1436. msg = kmalloc((sizeof(struct smd_msg_hdr) + 1), GFP_KERNEL);
  1437. if (NULL == msg) {
  1438. pr_err("wcnss: %s: failed to get memory\n", __func__);
  1439. return;
  1440. }
  1441. rsphdr = (struct smd_msg_hdr *)msg;
  1442. rsphdr->msg_type = WCNSS_CALDATA_UPLD_RSP;
  1443. rsphdr->msg_len = sizeof(struct smd_msg_hdr) + 1;
  1444. memcpy(msg+sizeof(struct smd_msg_hdr), &fw_status, 1);
  1445. rc = wcnss_smd_tx(msg, rsphdr->msg_len);
  1446. if (rc < 0)
  1447. pr_err("wcnss: smd tx failed\n");
  1448. kfree(msg);
  1449. }
  1450. /* Collect calibrated data from WCNSS */
  1451. void extract_cal_data(int len)
  1452. {
  1453. int rc;
  1454. struct cal_data_params calhdr;
  1455. unsigned char fw_status = WCNSS_RESP_FAIL;
  1456. if (len < sizeof(struct cal_data_params)) {
  1457. pr_err("wcnss: incomplete cal header length\n");
  1458. return;
  1459. }
  1460. rc = smd_read(penv->smd_ch, (unsigned char *)&calhdr,
  1461. sizeof(struct cal_data_params));
  1462. if (rc < sizeof(struct cal_data_params)) {
  1463. pr_err("wcnss: incomplete cal header read from smd\n");
  1464. return;
  1465. }
  1466. if (penv->fw_cal_exp_frag != calhdr.frag_number) {
  1467. pr_err("wcnss: Invalid frgament");
  1468. goto exit;
  1469. }
  1470. if (calhdr.frag_size > WCNSS_MAX_FRAME_SIZE) {
  1471. pr_err("wcnss: Invalid fragment size");
  1472. goto exit;
  1473. }
  1474. if (penv->fw_cal_available) {
  1475. /* ignore cal upload from SSR */
  1476. smd_read(penv->smd_ch, NULL, calhdr.frag_size);
  1477. penv->fw_cal_exp_frag++;
  1478. if (calhdr.msg_flags & LAST_FRAGMENT) {
  1479. penv->fw_cal_exp_frag = 0;
  1480. goto exit;
  1481. }
  1482. return;
  1483. }
  1484. if (0 == calhdr.frag_number) {
  1485. if (calhdr.total_size > MAX_CALIBRATED_DATA_SIZE) {
  1486. pr_err("wcnss: Invalid cal data size %d",
  1487. calhdr.total_size);
  1488. goto exit;
  1489. }
  1490. kfree(penv->fw_cal_data);
  1491. penv->fw_cal_rcvd = 0;
  1492. penv->fw_cal_data = kmalloc(calhdr.total_size,
  1493. GFP_KERNEL);
  1494. if (penv->fw_cal_data == NULL) {
  1495. smd_read(penv->smd_ch, NULL, calhdr.frag_size);
  1496. goto exit;
  1497. }
  1498. }
  1499. mutex_lock(&penv->dev_lock);
  1500. if (penv->fw_cal_rcvd + calhdr.frag_size >
  1501. MAX_CALIBRATED_DATA_SIZE) {
  1502. pr_err("calibrated data size is more than expected %d",
  1503. penv->fw_cal_rcvd + calhdr.frag_size);
  1504. penv->fw_cal_exp_frag = 0;
  1505. penv->fw_cal_rcvd = 0;
  1506. smd_read(penv->smd_ch, NULL, calhdr.frag_size);
  1507. goto unlock_exit;
  1508. }
  1509. rc = smd_read(penv->smd_ch, penv->fw_cal_data + penv->fw_cal_rcvd,
  1510. calhdr.frag_size);
  1511. if (rc < calhdr.frag_size)
  1512. goto unlock_exit;
  1513. penv->fw_cal_exp_frag++;
  1514. penv->fw_cal_rcvd += calhdr.frag_size;
  1515. if (calhdr.msg_flags & LAST_FRAGMENT) {
  1516. penv->fw_cal_exp_frag = 0;
  1517. penv->fw_cal_available = true;
  1518. pr_info("wcnss: cal data collection completed\n");
  1519. }
  1520. mutex_unlock(&penv->dev_lock);
  1521. wake_up(&penv->read_wait);
  1522. if (penv->fw_cal_available) {
  1523. fw_status = WCNSS_RESP_SUCCESS;
  1524. wcnss_send_cal_rsp(fw_status);
  1525. }
  1526. return;
  1527. unlock_exit:
  1528. mutex_unlock(&penv->dev_lock);
  1529. exit:
  1530. wcnss_send_cal_rsp(fw_status);
  1531. return;
  1532. }
  1533. static void wcnssctrl_rx_handler(struct work_struct *worker)
  1534. {
  1535. int len = 0;
  1536. int rc = 0;
  1537. unsigned char buf[sizeof(struct wcnss_version)];
  1538. unsigned char build[WCNSS_MAX_BUILD_VER_LEN+1];
  1539. struct smd_msg_hdr *phdr;
  1540. struct smd_msg_hdr smd_msg;
  1541. struct wcnss_version *pversion;
  1542. int hw_type;
  1543. unsigned char fw_status = 0;
  1544. len = smd_read_avail(penv->smd_ch);
  1545. if (len > WCNSS_MAX_FRAME_SIZE) {
  1546. pr_err("wcnss: frame larger than the allowed size\n");
  1547. smd_read(penv->smd_ch, NULL, len);
  1548. return;
  1549. }
  1550. if (len < sizeof(struct smd_msg_hdr)) {
  1551. pr_err("wcnss: incomplete header available len = %d\n", len);
  1552. return;
  1553. }
  1554. rc = smd_read(penv->smd_ch, buf, sizeof(struct smd_msg_hdr));
  1555. if (rc < sizeof(struct smd_msg_hdr)) {
  1556. pr_err("wcnss: incomplete header read from smd\n");
  1557. return;
  1558. }
  1559. len -= sizeof(struct smd_msg_hdr);
  1560. phdr = (struct smd_msg_hdr *)buf;
  1561. switch (phdr->msg_type) {
  1562. case WCNSS_VERSION_RSP:
  1563. if (len != sizeof(struct wcnss_version)
  1564. - sizeof(struct smd_msg_hdr)) {
  1565. pr_err("wcnss: invalid version data from wcnss %d\n",
  1566. len);
  1567. return;
  1568. }
  1569. rc = smd_read(penv->smd_ch, buf+sizeof(struct smd_msg_hdr),
  1570. len);
  1571. if (rc < len) {
  1572. pr_err("wcnss: incomplete data read from smd\n");
  1573. return;
  1574. }
  1575. pversion = (struct wcnss_version *)buf;
  1576. penv->fw_major = pversion->major;
  1577. penv->fw_minor = pversion->minor;
  1578. snprintf(penv->wcnss_version, WCNSS_VERSION_LEN,
  1579. "%02x%02x%02x%02x", pversion->major, pversion->minor,
  1580. pversion->version, pversion->revision);
  1581. pr_info("wcnss: version %s\n", penv->wcnss_version);
  1582. /* schedule work to download nvbin to ccpu */
  1583. hw_type = wcnss_hardware_type();
  1584. switch (hw_type) {
  1585. case WCNSS_RIVA_HW:
  1586. /* supported only if riva major >= 1 and minor >= 4 */
  1587. if ((pversion->major >= 1) && (pversion->minor >= 4)) {
  1588. pr_info("wcnss: schedule dnld work for riva\n");
  1589. schedule_work(&penv->wcnssctrl_nvbin_dnld_work);
  1590. }
  1591. break;
  1592. case WCNSS_PRONTO_HW:
  1593. smd_msg.msg_type = WCNSS_BUILD_VER_REQ;
  1594. smd_msg.msg_len = sizeof(smd_msg);
  1595. rc = wcnss_smd_tx(&smd_msg, smd_msg.msg_len);
  1596. if (rc < 0)
  1597. pr_err("wcnss: smd tx failed: %s\n", __func__);
  1598. /* supported only if pronto major >= 1 and minor >= 4 */
  1599. if ((pversion->major >= 1) && (pversion->minor >= 4)) {
  1600. pr_info("wcnss: schedule dnld work for pronto\n");
  1601. schedule_work(&penv->wcnssctrl_nvbin_dnld_work);
  1602. }
  1603. break;
  1604. default:
  1605. pr_info("wcnss: unknown hw type (%d), will not schedule dnld work\n",
  1606. hw_type);
  1607. break;
  1608. }
  1609. break;
  1610. case WCNSS_BUILD_VER_RSP:
  1611. if (len > WCNSS_MAX_BUILD_VER_LEN) {
  1612. pr_err("wcnss: invalid build version data from wcnss %d\n",
  1613. len);
  1614. return;
  1615. }
  1616. rc = smd_read(penv->smd_ch, build, len);
  1617. if (rc < len) {
  1618. pr_err("wcnss: incomplete data read from smd\n");
  1619. return;
  1620. }
  1621. build[len] = 0;
  1622. pr_info("wcnss: build version %s\n", build);
  1623. break;
  1624. case WCNSS_NVBIN_DNLD_RSP:
  1625. penv->nv_downloaded = true;
  1626. fw_status = wcnss_fw_status();
  1627. pr_debug("wcnss: received WCNSS_NVBIN_DNLD_RSP from ccpu %u\n",
  1628. fw_status);
  1629. if (fw_status != WAIT_FOR_CBC_IND)
  1630. penv->is_cbc_done = 1;
  1631. wcnss_setup_vbat_monitoring();
  1632. break;
  1633. case WCNSS_CALDATA_DNLD_RSP:
  1634. penv->nv_downloaded = true;
  1635. fw_status = wcnss_fw_status();
  1636. pr_debug("wcnss: received WCNSS_CALDATA_DNLD_RSP from ccpu %u\n",
  1637. fw_status);
  1638. break;
  1639. case WCNSS_CBC_COMPLETE_IND:
  1640. penv->is_cbc_done = 1;
  1641. pr_debug("wcnss: received WCNSS_CBC_COMPLETE_IND from FW\n");
  1642. break;
  1643. case WCNSS_CBC_COMPLETE_IND:
  1644. penv->is_cbc_done = 1;
  1645. pr_debug("wcnss: received WCNSS_CBC_COMPLETE_IND from FW\n");
  1646. break;
  1647. case WCNSS_CALDATA_UPLD_REQ:
  1648. extract_cal_data(len);
  1649. break;
  1650. default:
  1651. pr_err("wcnss: invalid message type %d\n", phdr->msg_type);
  1652. }
  1653. return;
  1654. }
  1655. static void wcnss_send_version_req(struct work_struct *worker)
  1656. {
  1657. struct smd_msg_hdr smd_msg;
  1658. int ret = 0;
  1659. smd_msg.msg_type = WCNSS_VERSION_REQ;
  1660. smd_msg.msg_len = sizeof(smd_msg);
  1661. ret = wcnss_smd_tx(&smd_msg, smd_msg.msg_len);
  1662. if (ret < 0)
  1663. pr_err("wcnss: smd tx failed\n");
  1664. return;
  1665. }
  1666. static void wcnss_send_pm_config(struct work_struct *worker)
  1667. {
  1668. struct smd_msg_hdr *hdr;
  1669. unsigned char *msg = NULL;
  1670. int rc, prop_len;
  1671. u32 *payload;
  1672. if (!of_find_property(penv->pdev->dev.of_node,
  1673. "qcom,wcnss-pm", &prop_len))
  1674. return;
  1675. msg = kmalloc((sizeof(struct smd_msg_hdr) + prop_len), GFP_KERNEL);
  1676. if (NULL == msg) {
  1677. pr_err("wcnss: %s: failed to allocate memory\n", __func__);
  1678. return;
  1679. }
  1680. payload = (u32 *)(msg + sizeof(struct smd_msg_hdr));
  1681. prop_len /= sizeof(int);
  1682. rc = of_property_read_u32_array(penv->pdev->dev.of_node,
  1683. "qcom,wcnss-pm", payload, prop_len);
  1684. if (rc < 0) {
  1685. pr_err("wcnss: property read failed\n");
  1686. kfree(msg);
  1687. return;
  1688. }
  1689. pr_debug("%s:size=%d: <%d, %d, %d, %d, %d %d>\n", __func__,
  1690. prop_len, *payload, *(payload+1), *(payload+2),
  1691. *(payload+3), *(payload+4), *(payload+5));
  1692. hdr = (struct smd_msg_hdr *)msg;
  1693. hdr->msg_type = WCNSS_PM_CONFIG_REQ;
  1694. hdr->msg_len = sizeof(struct smd_msg_hdr) + (prop_len * sizeof(int));
  1695. rc = wcnss_smd_tx(msg, hdr->msg_len);
  1696. if (rc < 0)
  1697. pr_err("wcnss: smd tx failed\n");
  1698. kfree(msg);
  1699. return;
  1700. }
  1701. static DECLARE_RWSEM(wcnss_pm_sem);
  1702. static void wcnss_nvbin_dnld(void)
  1703. {
  1704. int ret = 0;
  1705. struct nvbin_dnld_req_msg *dnld_req_msg;
  1706. unsigned short total_fragments = 0;
  1707. unsigned short count = 0;
  1708. unsigned short retry_count = 0;
  1709. unsigned short cur_frag_size = 0;
  1710. unsigned char *outbuffer = NULL;
  1711. const void *nv_blob_addr = NULL;
  1712. unsigned int nv_blob_size = 0;
  1713. const struct firmware *nv = NULL;
  1714. struct device *dev = &penv->pdev->dev;
  1715. down_read(&wcnss_pm_sem);
  1716. ret = request_firmware(&nv, NVBIN_FILE, dev);
  1717. if (ret || !nv || !nv->data || !nv->size) {
  1718. pr_err("wcnss: %s: request_firmware failed for %s(ret = %d)\n",
  1719. __func__, NVBIN_FILE, ret);
  1720. goto out;
  1721. }
  1722. /*
  1723. * First 4 bytes in nv blob is validity bitmap.
  1724. * We cannot validate nv, so skip those 4 bytes.
  1725. */
  1726. nv_blob_addr = nv->data + 4;
  1727. nv_blob_size = nv->size - 4;
  1728. total_fragments = TOTALFRAGMENTS(nv_blob_size);
  1729. pr_info("wcnss: NV bin size: %d, total_fragments: %d\n",
  1730. nv_blob_size, total_fragments);
  1731. /* get buffer for nv bin dnld req message */
  1732. outbuffer = kmalloc((sizeof(struct nvbin_dnld_req_msg) +
  1733. NV_FRAGMENT_SIZE), GFP_KERNEL);
  1734. if (NULL == outbuffer) {
  1735. pr_err("wcnss: %s: failed to get buffer\n", __func__);
  1736. goto err_free_nv;
  1737. }
  1738. dnld_req_msg = (struct nvbin_dnld_req_msg *)outbuffer;
  1739. dnld_req_msg->hdr.msg_type = WCNSS_NVBIN_DNLD_REQ;
  1740. dnld_req_msg->dnld_req_params.msg_flags = 0;
  1741. for (count = 0; count < total_fragments; count++) {
  1742. dnld_req_msg->dnld_req_params.frag_number = count;
  1743. if (count == (total_fragments - 1)) {
  1744. /* last fragment, take care of boundry condition */
  1745. cur_frag_size = nv_blob_size % NV_FRAGMENT_SIZE;
  1746. if (!cur_frag_size)
  1747. cur_frag_size = NV_FRAGMENT_SIZE;
  1748. dnld_req_msg->dnld_req_params.msg_flags |=
  1749. LAST_FRAGMENT;
  1750. dnld_req_msg->dnld_req_params.msg_flags |=
  1751. CAN_RECEIVE_CALDATA;
  1752. } else {
  1753. cur_frag_size = NV_FRAGMENT_SIZE;
  1754. dnld_req_msg->dnld_req_params.msg_flags &=
  1755. ~LAST_FRAGMENT;
  1756. }
  1757. dnld_req_msg->dnld_req_params.nvbin_buffer_size =
  1758. cur_frag_size;
  1759. dnld_req_msg->hdr.msg_len =
  1760. sizeof(struct nvbin_dnld_req_msg) + cur_frag_size;
  1761. /* copy NV fragment */
  1762. memcpy((outbuffer + sizeof(struct nvbin_dnld_req_msg)),
  1763. (nv_blob_addr + count * NV_FRAGMENT_SIZE),
  1764. cur_frag_size);
  1765. ret = wcnss_smd_tx(outbuffer, dnld_req_msg->hdr.msg_len);
  1766. retry_count = 0;
  1767. while ((ret == -ENOSPC) && (retry_count <= 3)) {
  1768. pr_debug("wcnss: %s: smd tx failed, ENOSPC\n",
  1769. __func__);
  1770. pr_debug("fragment: %d, len: %d, TotFragments: %d, retry_count: %d\n",
  1771. count, dnld_req_msg->hdr.msg_len,
  1772. total_fragments, retry_count);
  1773. /* wait and try again */
  1774. msleep(20);
  1775. retry_count++;
  1776. ret = wcnss_smd_tx(outbuffer,
  1777. dnld_req_msg->hdr.msg_len);
  1778. }
  1779. if (ret < 0) {
  1780. pr_err("wcnss: %s: smd tx failed\n", __func__);
  1781. pr_err("fragment %d, len: %d, TotFragments: %d, retry_count: %d\n",
  1782. count, dnld_req_msg->hdr.msg_len,
  1783. total_fragments, retry_count);
  1784. goto err_dnld;
  1785. }
  1786. }
  1787. err_dnld:
  1788. /* free buffer */
  1789. kfree(outbuffer);
  1790. err_free_nv:
  1791. /* release firmware */
  1792. release_firmware(nv);
  1793. out:
  1794. up_read(&wcnss_pm_sem);
  1795. return;
  1796. }
  1797. static void wcnss_pm_qos_enable_pc(struct work_struct *worker)
  1798. {
  1799. wcnss_disable_pc_remove_req();
  1800. return;
  1801. }
  1802. static void wcnss_caldata_dnld(const void *cal_data,
  1803. unsigned int cal_data_size, bool msg_to_follow)
  1804. {
  1805. int ret = 0;
  1806. struct cal_data_msg *cal_msg;
  1807. unsigned short total_fragments = 0;
  1808. unsigned short count = 0;
  1809. unsigned short retry_count = 0;
  1810. unsigned short cur_frag_size = 0;
  1811. unsigned char *outbuffer = NULL;
  1812. total_fragments = TOTALFRAGMENTS(cal_data_size);
  1813. outbuffer = kmalloc((sizeof(struct cal_data_msg) +
  1814. NV_FRAGMENT_SIZE), GFP_KERNEL);
  1815. if (NULL == outbuffer) {
  1816. pr_err("wcnss: %s: failed to get buffer\n", __func__);
  1817. return;
  1818. }
  1819. cal_msg = (struct cal_data_msg *)outbuffer;
  1820. cal_msg->hdr.msg_type = WCNSS_CALDATA_DNLD_REQ;
  1821. cal_msg->cal_params.msg_flags = 0;
  1822. for (count = 0; count < total_fragments; count++) {
  1823. cal_msg->cal_params.frag_number = count;
  1824. if (count == (total_fragments - 1)) {
  1825. cur_frag_size = cal_data_size % NV_FRAGMENT_SIZE;
  1826. if (!cur_frag_size)
  1827. cur_frag_size = NV_FRAGMENT_SIZE;
  1828. cal_msg->cal_params.msg_flags
  1829. |= LAST_FRAGMENT;
  1830. if (msg_to_follow)
  1831. cal_msg->cal_params.msg_flags |=
  1832. MESSAGE_TO_FOLLOW;
  1833. } else {
  1834. cur_frag_size = NV_FRAGMENT_SIZE;
  1835. cal_msg->cal_params.msg_flags &=
  1836. ~LAST_FRAGMENT;
  1837. }
  1838. cal_msg->cal_params.total_size = cal_data_size;
  1839. cal_msg->cal_params.frag_size =
  1840. cur_frag_size;
  1841. cal_msg->hdr.msg_len =
  1842. sizeof(struct cal_data_msg) + cur_frag_size;
  1843. memcpy((outbuffer + sizeof(struct cal_data_msg)),
  1844. (cal_data + count * NV_FRAGMENT_SIZE),
  1845. cur_frag_size);
  1846. ret = wcnss_smd_tx(outbuffer, cal_msg->hdr.msg_len);
  1847. retry_count = 0;
  1848. while ((ret == -ENOSPC) && (retry_count <= 3)) {
  1849. pr_debug("wcnss: %s: smd tx failed, ENOSPC\n",
  1850. __func__);
  1851. pr_debug("fragment: %d, len: %d, TotFragments: %d, retry_count: %d\n",
  1852. count, cal_msg->hdr.msg_len,
  1853. total_fragments, retry_count);
  1854. /* wait and try again */
  1855. msleep(20);
  1856. retry_count++;
  1857. ret = wcnss_smd_tx(outbuffer,
  1858. cal_msg->hdr.msg_len);
  1859. }
  1860. if (ret < 0) {
  1861. pr_err("wcnss: %s: smd tx failed\n", __func__);
  1862. pr_err("fragment %d, len: %d, TotFragments: %d, retry_count: %d\n",
  1863. count, cal_msg->hdr.msg_len,
  1864. total_fragments, retry_count);
  1865. goto err_dnld;
  1866. }
  1867. }
  1868. err_dnld:
  1869. /* free buffer */
  1870. kfree(outbuffer);
  1871. return;
  1872. }
  1873. static void wcnss_nvbin_dnld_main(struct work_struct *worker)
  1874. {
  1875. int retry = 0;
  1876. if (!FW_CALDATA_CAPABLE())
  1877. goto nv_download;
  1878. if (!penv->fw_cal_available && WCNSS_CONFIG_UNSPECIFIED
  1879. != has_calibrated_data && !penv->user_cal_available) {
  1880. while (!penv->user_cal_available && retry++ < 5)
  1881. msleep(500);
  1882. }
  1883. if (penv->fw_cal_available) {
  1884. pr_info_ratelimited("wcnss: cal download, using fw cal");
  1885. wcnss_caldata_dnld(penv->fw_cal_data, penv->fw_cal_rcvd, true);
  1886. } else if (penv->user_cal_available) {
  1887. pr_info_ratelimited("wcnss: cal download, using user cal");
  1888. wcnss_caldata_dnld(penv->user_cal_data,
  1889. penv->user_cal_rcvd, true);
  1890. }
  1891. nv_download:
  1892. pr_info_ratelimited("wcnss: NV download");
  1893. wcnss_nvbin_dnld();
  1894. return;
  1895. }
  1896. static int wcnss_pm_notify(struct notifier_block *b,
  1897. unsigned long event, void *p)
  1898. {
  1899. switch (event) {
  1900. case PM_SUSPEND_PREPARE:
  1901. down_write(&wcnss_pm_sem);
  1902. break;
  1903. case PM_POST_SUSPEND:
  1904. up_write(&wcnss_pm_sem);
  1905. break;
  1906. }
  1907. return NOTIFY_DONE;
  1908. }
  1909. static struct notifier_block wcnss_pm_notifier = {
  1910. .notifier_call = wcnss_pm_notify,
  1911. };
  1912. static int wcnss_ctrl_open(struct inode *inode, struct file *file)
  1913. {
  1914. int rc = 0;
  1915. if (!penv || penv->ctrl_device_opened)
  1916. return -EFAULT;
  1917. penv->ctrl_device_opened = 1;
  1918. return rc;
  1919. }
  1920. void process_usr_ctrl_cmd(u8 *buf, size_t len)
  1921. {
  1922. u16 cmd = buf[0] << 8 | buf[1];
  1923. switch (cmd) {
  1924. case WCNSS_USR_SERIAL_NUM:
  1925. if (WCNSS_MIN_SERIAL_LEN > len) {
  1926. pr_err("%s: Invalid serial number\n", __func__);
  1927. return;
  1928. }
  1929. penv->serial_number = buf[2] << 24 | buf[3] << 16
  1930. | buf[4] << 8 | buf[5];
  1931. break;
  1932. case WCNSS_USR_HAS_CAL_DATA:
  1933. if (1 < buf[2])
  1934. pr_err("%s: Invalid data for cal %d\n", __func__,
  1935. buf[2]);
  1936. has_calibrated_data = buf[2];
  1937. break;
  1938. case WCNSS_USR_WLAN_MAC_ADDR:
  1939. memcpy(&penv->wlan_nv_macAddr, &buf[2],
  1940. sizeof(penv->wlan_nv_macAddr));
  1941. pr_debug("%s: MAC Addr:" MAC_ADDRESS_STR "\n", __func__,
  1942. penv->wlan_nv_macAddr[0], penv->wlan_nv_macAddr[1],
  1943. penv->wlan_nv_macAddr[2], penv->wlan_nv_macAddr[3],
  1944. penv->wlan_nv_macAddr[4], penv->wlan_nv_macAddr[5]);
  1945. break;
  1946. default:
  1947. pr_err("%s: Invalid command %d\n", __func__, cmd);
  1948. break;
  1949. }
  1950. }
  1951. static ssize_t wcnss_ctrl_write(struct file *fp, const char __user
  1952. *user_buffer, size_t count, loff_t *position)
  1953. {
  1954. int rc = 0;
  1955. u8 buf[WCNSS_MAX_CMD_LEN];
  1956. if (!penv || !penv->ctrl_device_opened || WCNSS_MAX_CMD_LEN < count
  1957. || WCNSS_MIN_CMD_LEN > count)
  1958. return -EFAULT;
  1959. mutex_lock(&penv->ctrl_lock);
  1960. rc = copy_from_user(buf, user_buffer, count);
  1961. if (0 == rc)
  1962. process_usr_ctrl_cmd(buf, count);
  1963. mutex_unlock(&penv->ctrl_lock);
  1964. return rc;
  1965. }
  1966. static const struct file_operations wcnss_ctrl_fops = {
  1967. .owner = THIS_MODULE,
  1968. .open = wcnss_ctrl_open,
  1969. .write = wcnss_ctrl_write,
  1970. };
  1971. static struct miscdevice wcnss_usr_ctrl = {
  1972. .minor = MISC_DYNAMIC_MINOR,
  1973. .name = CTRL_DEVICE,
  1974. .fops = &wcnss_ctrl_fops,
  1975. };
  1976. static int
  1977. wcnss_trigger_config(struct platform_device *pdev)
  1978. {
  1979. int ret;
  1980. struct qcom_wcnss_opts *pdata;
  1981. unsigned long wcnss_phys_addr;
  1982. int size = 0;
  1983. struct resource *res;
  1984. int is_pronto_v3;
  1985. int pil_retry = 0;
  1986. int has_pronto_hw = of_property_read_bool(pdev->dev.of_node,
  1987. "qcom,has-pronto-hw");
  1988. is_pronto_v3 = of_property_read_bool(pdev->dev.of_node,
  1989. "qcom,is-pronto-v3");
  1990. if (of_property_read_u32(pdev->dev.of_node,
  1991. "qcom,wlan-rx-buff-count", &penv->wlan_rx_buff_count)) {
  1992. penv->wlan_rx_buff_count = WCNSS_DEF_WLAN_RX_BUFF_COUNT;
  1993. }
  1994. /* make sure we are only triggered once */
  1995. if (penv->triggered)
  1996. return 0;
  1997. penv->triggered = 1;
  1998. /* initialize the WCNSS device configuration */
  1999. pdata = pdev->dev.platform_data;
  2000. if (WCNSS_CONFIG_UNSPECIFIED == has_48mhz_xo) {
  2001. if (has_pronto_hw) {
  2002. has_48mhz_xo = of_property_read_bool(pdev->dev.of_node,
  2003. "qcom,has-48mhz-xo");
  2004. } else {
  2005. has_48mhz_xo = pdata->has_48mhz_xo;
  2006. }
  2007. }
  2008. penv->wcnss_hw_type = (has_pronto_hw) ? WCNSS_PRONTO_HW : WCNSS_RIVA_HW;
  2009. penv->wlan_config.use_48mhz_xo = has_48mhz_xo;
  2010. penv->wlan_config.is_pronto_v3 = is_pronto_v3;
  2011. if (WCNSS_CONFIG_UNSPECIFIED == has_autodetect_xo && has_pronto_hw) {
  2012. has_autodetect_xo = of_property_read_bool(pdev->dev.of_node,
  2013. "qcom,has-autodetect-xo");
  2014. }
  2015. penv->thermal_mitigation = 0;
  2016. strlcpy(penv->wcnss_version, "INVALID", WCNSS_VERSION_LEN);
  2017. /* Configure 5 wire GPIOs */
  2018. if (!has_pronto_hw) {
  2019. penv->gpios_5wire = platform_get_resource_byname(pdev,
  2020. IORESOURCE_IO, "wcnss_gpios_5wire");
  2021. /* allocate 5-wire GPIO resources */
  2022. if (!penv->gpios_5wire) {
  2023. dev_err(&pdev->dev, "insufficient IO resources\n");
  2024. ret = -ENOENT;
  2025. goto fail_gpio_res;
  2026. }
  2027. ret = wcnss_gpios_config(penv->gpios_5wire, true);
  2028. } else
  2029. ret = wcnss_pronto_gpios_config(&pdev->dev, true);
  2030. if (ret) {
  2031. dev_err(&pdev->dev, "WCNSS gpios config failed.\n");
  2032. goto fail_gpio_res;
  2033. }
  2034. /* power up the WCNSS */
  2035. ret = wcnss_wlan_power(&pdev->dev, &penv->wlan_config,
  2036. WCNSS_WLAN_SWITCH_ON,
  2037. &penv->iris_xo_mode_set);
  2038. if (ret) {
  2039. dev_err(&pdev->dev, "WCNSS Power-up failed.\n");
  2040. goto fail_power;
  2041. }
  2042. /* allocate resources */
  2043. penv->mmio_res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
  2044. "wcnss_mmio");
  2045. penv->tx_irq_res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
  2046. "wcnss_wlantx_irq");
  2047. penv->rx_irq_res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
  2048. "wcnss_wlanrx_irq");
  2049. if (!(penv->mmio_res && penv->tx_irq_res && penv->rx_irq_res)) {
  2050. dev_err(&pdev->dev, "insufficient resources\n");
  2051. ret = -ENOENT;
  2052. goto fail_res;
  2053. }
  2054. INIT_WORK(&penv->wcnssctrl_rx_work, wcnssctrl_rx_handler);
  2055. INIT_WORK(&penv->wcnssctrl_version_work, wcnss_send_version_req);
  2056. INIT_WORK(&penv->wcnss_pm_config_work, wcnss_send_pm_config);
  2057. INIT_WORK(&penv->wcnssctrl_nvbin_dnld_work, wcnss_nvbin_dnld_main);
  2058. INIT_DELAYED_WORK(&penv->wcnss_pm_qos_del_req, wcnss_pm_qos_enable_pc);
  2059. wake_lock_init(&penv->wcnss_wake_lock, WAKE_LOCK_SUSPEND, "wcnss");
  2060. /* Add pm_qos request to disable power collapse for DDR */
  2061. wcnss_disable_pc_add_req();
  2062. if (wcnss_hardware_type() == WCNSS_PRONTO_HW) {
  2063. size = 0x3000;
  2064. wcnss_phys_addr = MSM_PRONTO_PHYS;
  2065. } else {
  2066. wcnss_phys_addr = MSM_RIVA_PHYS;
  2067. size = SZ_256;
  2068. }
  2069. penv->msm_wcnss_base = ioremap(wcnss_phys_addr, size);
  2070. if (!penv->msm_wcnss_base) {
  2071. ret = -ENOMEM;
  2072. pr_err("%s: ioremap wcnss physical failed\n", __func__);
  2073. goto fail_ioremap;
  2074. }
  2075. if (wcnss_hardware_type() == WCNSS_RIVA_HW) {
  2076. penv->riva_ccu_base = ioremap(MSM_RIVA_CCU_BASE, SZ_512);
  2077. if (!penv->riva_ccu_base) {
  2078. ret = -ENOMEM;
  2079. pr_err("%s: ioremap wcnss physical failed\n", __func__);
  2080. goto fail_ioremap2;
  2081. }
  2082. } else {
  2083. penv->pronto_a2xb_base = ioremap(MSM_PRONTO_A2XB_BASE, SZ_512);
  2084. if (!penv->pronto_a2xb_base) {
  2085. ret = -ENOMEM;
  2086. pr_err("%s: ioremap wcnss physical failed\n", __func__);
  2087. goto fail_ioremap2;
  2088. }
  2089. penv->pronto_ccpu_base = ioremap(MSM_PRONTO_CCPU_BASE, SZ_512);
  2090. if (!penv->pronto_ccpu_base) {
  2091. ret = -ENOMEM;
  2092. pr_err("%s: ioremap wcnss physical failed\n", __func__);
  2093. goto fail_ioremap3;
  2094. }
  2095. /* for reset FIQ */
  2096. res = platform_get_resource_byname(penv->pdev,
  2097. IORESOURCE_MEM, "wcnss_fiq");
  2098. if (!res) {
  2099. dev_err(&pdev->dev, "insufficient irq mem resources\n");
  2100. ret = -ENOENT;
  2101. goto fail_ioremap4;
  2102. }
  2103. penv->fiq_reg = ioremap_nocache(res->start, resource_size(res));
  2104. if (!penv->fiq_reg) {
  2105. pr_err("wcnss: %s: ioremap_nocache() failed fiq_reg addr:%pr\n",
  2106. __func__, &res->start);
  2107. ret = -ENOMEM;
  2108. goto fail_ioremap4;
  2109. }
  2110. penv->pronto_saw2_base = ioremap_nocache(MSM_PRONTO_SAW2_BASE,
  2111. SZ_32);
  2112. if (!penv->pronto_saw2_base) {
  2113. pr_err("%s: ioremap wcnss physical(saw2) failed\n",
  2114. __func__);
  2115. ret = -ENOMEM;
  2116. goto fail_ioremap5;
  2117. }
  2118. penv->pronto_pll_base = ioremap_nocache(MSM_PRONTO_PLL_BASE,
  2119. SZ_64);
  2120. if (!penv->pronto_pll_base) {
  2121. pr_err("%s: ioremap wcnss physical(pll) failed\n",
  2122. __func__);
  2123. ret = -ENOMEM;
  2124. goto fail_ioremap6;
  2125. }
  2126. penv->wlan_tx_phy_aborts = ioremap(MSM_PRONTO_TXP_PHY_ABORT,
  2127. SZ_8);
  2128. if (!penv->wlan_tx_phy_aborts) {
  2129. ret = -ENOMEM;
  2130. pr_err("%s: ioremap wlan TX PHY failed\n", __func__);
  2131. goto fail_ioremap7;
  2132. }
  2133. penv->wlan_brdg_err_source = ioremap(MSM_PRONTO_BRDG_ERR_SRC,
  2134. SZ_8);
  2135. if (!penv->wlan_brdg_err_source) {
  2136. ret = -ENOMEM;
  2137. pr_err("%s: ioremap wlan BRDG ERR failed\n", __func__);
  2138. goto fail_ioremap8;
  2139. }
  2140. penv->wlan_tx_status = ioremap(MSM_PRONTO_TXP_STATUS, SZ_8);
  2141. if (!penv->wlan_tx_status) {
  2142. ret = -ENOMEM;
  2143. pr_err("%s: ioremap wlan TX STATUS failed\n", __func__);
  2144. goto fail_ioremap9;
  2145. }
  2146. penv->alarms_txctl = ioremap(MSM_PRONTO_ALARMS_TXCTL, SZ_8);
  2147. if (!penv->alarms_txctl) {
  2148. ret = -ENOMEM;
  2149. pr_err("%s: ioremap alarms TXCTL failed\n", __func__);
  2150. goto fail_ioremap10;
  2151. }
  2152. penv->alarms_tactl = ioremap(MSM_PRONTO_ALARMS_TACTL, SZ_8);
  2153. if (!penv->alarms_tactl) {
  2154. ret = -ENOMEM;
  2155. pr_err("%s: ioremap alarms TACTL failed\n", __func__);
  2156. goto fail_ioremap11;
  2157. }
  2158. penv->pronto_mcu_base = ioremap(MSM_PRONTO_MCU_BASE, SZ_1K);
  2159. if (!penv->pronto_mcu_base) {
  2160. ret = -ENOMEM;
  2161. pr_err("%s: ioremap wcnss physical(mcu) failed\n",
  2162. __func__);
  2163. goto fail_ioremap12;
  2164. }
  2165. }
  2166. penv->adc_tm_dev = qpnp_get_adc_tm(&penv->pdev->dev, "wcnss");
  2167. if (IS_ERR(penv->adc_tm_dev)) {
  2168. pr_err("%s: adc get failed\n", __func__);
  2169. penv->adc_tm_dev = NULL;
  2170. } else {
  2171. INIT_DELAYED_WORK(&penv->vbatt_work, wcnss_update_vbatt);
  2172. penv->fw_vbatt_state = WCNSS_CONFIG_UNSPECIFIED;
  2173. }
  2174. do {
  2175. /* trigger initialization of the WCNSS */
  2176. penv->pil = subsystem_get(WCNSS_PIL_DEVICE);
  2177. if (IS_ERR(penv->pil)) {
  2178. dev_err(&pdev->dev, "Peripheral Loader failed on WCNSS.\n");
  2179. ret = PTR_ERR(penv->pil);
  2180. wcnss_disable_pc_add_req();
  2181. wcnss_pronto_log_debug_regs();
  2182. }
  2183. } while (pil_retry++ < WCNSS_MAX_PIL_RETRY && IS_ERR(penv->pil));
  2184. if (IS_ERR(penv->pil)) {
  2185. wcnss_reset_intr();
  2186. if (penv->wcnss_notif_hdle)
  2187. subsys_notif_unregister_notifier(penv->wcnss_notif_hdle,
  2188. &wnb);
  2189. penv->pil = NULL;
  2190. goto fail_pil;
  2191. }
  2192. /* Remove pm_qos request */
  2193. wcnss_disable_pc_remove_req();
  2194. return 0;
  2195. fail_pil:
  2196. if (penv->riva_ccu_base)
  2197. iounmap(penv->riva_ccu_base);
  2198. if (penv->pronto_mcu_base)
  2199. iounmap(penv->pronto_mcu_base);
  2200. fail_ioremap12:
  2201. if (penv->alarms_tactl)
  2202. iounmap(penv->alarms_tactl);
  2203. fail_ioremap11:
  2204. if (penv->alarms_txctl)
  2205. iounmap(penv->alarms_txctl);
  2206. fail_ioremap10:
  2207. if (penv->wlan_tx_status)
  2208. iounmap(penv->wlan_tx_status);
  2209. fail_ioremap9:
  2210. if (penv->wlan_brdg_err_source)
  2211. iounmap(penv->wlan_brdg_err_source);
  2212. fail_ioremap8:
  2213. if (penv->wlan_tx_phy_aborts)
  2214. iounmap(penv->wlan_tx_phy_aborts);
  2215. fail_ioremap7:
  2216. if (penv->pronto_pll_base)
  2217. iounmap(penv->pronto_pll_base);
  2218. fail_ioremap6:
  2219. if (penv->pronto_saw2_base)
  2220. iounmap(penv->pronto_saw2_base);
  2221. fail_ioremap5:
  2222. if (penv->fiq_reg)
  2223. iounmap(penv->fiq_reg);
  2224. fail_ioremap4:
  2225. if (penv->pronto_ccpu_base)
  2226. iounmap(penv->pronto_ccpu_base);
  2227. fail_ioremap3:
  2228. if (penv->pronto_a2xb_base)
  2229. iounmap(penv->pronto_a2xb_base);
  2230. fail_ioremap2:
  2231. if (penv->msm_wcnss_base)
  2232. iounmap(penv->msm_wcnss_base);
  2233. fail_ioremap:
  2234. wake_lock_destroy(&penv->wcnss_wake_lock);
  2235. fail_res:
  2236. wcnss_wlan_power(&pdev->dev, &penv->wlan_config,
  2237. WCNSS_WLAN_SWITCH_OFF, NULL);
  2238. fail_power:
  2239. if (has_pronto_hw)
  2240. wcnss_pronto_gpios_config(&pdev->dev, false);
  2241. else
  2242. wcnss_gpios_config(penv->gpios_5wire, false);
  2243. fail_gpio_res:
  2244. wcnss_disable_pc_remove_req();
  2245. penv = NULL;
  2246. return ret;
  2247. }
  2248. /* wlan prop driver cannot invoke cancel_work_sync
  2249. * function directly, so to invoke this function it
  2250. * call wcnss_flush_work function
  2251. */
  2252. void wcnss_flush_work(struct work_struct *work)
  2253. {
  2254. struct work_struct *cnss_work = work;
  2255. if (cnss_work != NULL)
  2256. cancel_work_sync(cnss_work);
  2257. }
  2258. EXPORT_SYMBOL(wcnss_flush_work);
  2259. /* wlan prop driver cannot invoke show_stack
  2260. * function directly, so to invoke this function it
  2261. * call wcnss_dump_stack function
  2262. */
  2263. void wcnss_dump_stack(struct task_struct *task)
  2264. {
  2265. show_stack(task, NULL);
  2266. }
  2267. EXPORT_SYMBOL(wcnss_dump_stack);
  2268. /* wlan prop driver cannot invoke cancel_delayed_work_sync
  2269. * function directly, so to invoke this function it call
  2270. * wcnss_flush_delayed_work function
  2271. */
  2272. void wcnss_flush_delayed_work(struct delayed_work *dwork)
  2273. {
  2274. struct delayed_work *cnss_dwork = dwork;
  2275. if (cnss_dwork != NULL)
  2276. cancel_delayed_work_sync(cnss_dwork);
  2277. }
  2278. EXPORT_SYMBOL(wcnss_flush_delayed_work);
  2279. static int wcnss_node_open(struct inode *inode, struct file *file)
  2280. {
  2281. struct platform_device *pdev;
  2282. int rc = 0;
  2283. if (!penv)
  2284. return -EFAULT;
  2285. if (!penv->triggered) {
  2286. pr_info(DEVICE " triggered by userspace\n");
  2287. pdev = penv->pdev;
  2288. rc = wcnss_trigger_config(pdev);
  2289. if (rc)
  2290. return -EFAULT;
  2291. }
  2292. return rc;
  2293. }
  2294. static ssize_t wcnss_wlan_read(struct file *fp, char __user
  2295. *buffer, size_t count, loff_t *position)
  2296. {
  2297. int rc = 0;
  2298. if (!penv)
  2299. return -EFAULT;
  2300. rc = wait_event_interruptible(penv->read_wait, penv->fw_cal_rcvd
  2301. > penv->user_cal_read || penv->fw_cal_available);
  2302. if (rc < 0)
  2303. return rc;
  2304. mutex_lock(&penv->dev_lock);
  2305. if (penv->fw_cal_available && penv->fw_cal_rcvd
  2306. == penv->user_cal_read) {
  2307. rc = 0;
  2308. goto exit;
  2309. }
  2310. if (count > penv->fw_cal_rcvd - penv->user_cal_read)
  2311. count = penv->fw_cal_rcvd - penv->user_cal_read;
  2312. rc = copy_to_user(buffer, penv->fw_cal_data +
  2313. penv->user_cal_read, count);
  2314. if (rc == 0) {
  2315. penv->user_cal_read += count;
  2316. rc = count;
  2317. }
  2318. exit:
  2319. mutex_unlock(&penv->dev_lock);
  2320. return rc;
  2321. }
  2322. /* first (valid) write to this device should be 4 bytes cal file size */
  2323. static ssize_t wcnss_wlan_write(struct file *fp, const char __user
  2324. *user_buffer, size_t count, loff_t *position)
  2325. {
  2326. int rc = 0;
  2327. char *cal_data = NULL;
  2328. if (!penv || penv->user_cal_available)
  2329. return -EFAULT;
  2330. if (!penv->user_cal_rcvd && count >= 4 && !penv->user_cal_exp_size) {
  2331. mutex_lock(&penv->dev_lock);
  2332. rc = copy_from_user((void *)&penv->user_cal_exp_size,
  2333. user_buffer, 4);
  2334. if (!penv->user_cal_exp_size ||
  2335. penv->user_cal_exp_size > MAX_CALIBRATED_DATA_SIZE) {
  2336. pr_err(DEVICE " invalid size to write %d\n",
  2337. penv->user_cal_exp_size);
  2338. penv->user_cal_exp_size = 0;
  2339. mutex_unlock(&penv->dev_lock);
  2340. return -EFAULT;
  2341. }
  2342. mutex_unlock(&penv->dev_lock);
  2343. return count;
  2344. } else if (!penv->user_cal_rcvd && count < 4) {
  2345. return -EFAULT;
  2346. }
  2347. mutex_lock(&penv->dev_lock);
  2348. if ((UINT32_MAX - count < penv->user_cal_rcvd) ||
  2349. (penv->user_cal_exp_size < count + penv->user_cal_rcvd)) {
  2350. pr_err(DEVICE " invalid size to write %zu\n", count +
  2351. penv->user_cal_rcvd);
  2352. mutex_unlock(&penv->dev_lock);
  2353. return -ENOMEM;
  2354. }
  2355. cal_data = kmalloc(count, GFP_KERNEL);
  2356. if (!cal_data) {
  2357. mutex_unlock(&penv->dev_lock);
  2358. return -ENOMEM;
  2359. }
  2360. rc = copy_from_user(cal_data, user_buffer, count);
  2361. if (!rc) {
  2362. memcpy(penv->user_cal_data + penv->user_cal_rcvd,
  2363. cal_data, count);
  2364. penv->user_cal_rcvd += count;
  2365. rc += count;
  2366. }
  2367. kfree(cal_data);
  2368. if (penv->user_cal_rcvd == penv->user_cal_exp_size) {
  2369. penv->user_cal_available = true;
  2370. pr_info_ratelimited("wcnss: user cal written");
  2371. }
  2372. mutex_unlock(&penv->dev_lock);
  2373. return rc;
  2374. }
  2375. static int wcnss_node_release(struct inode *inode, struct file *file)
  2376. {
  2377. return 0;
  2378. }
  2379. static int wcnss_notif_cb(struct notifier_block *this, unsigned long code,
  2380. void *ss_handle)
  2381. {
  2382. pr_info("%s: wcnss notification event: %lu\n", __func__, code);
  2383. if (code == SUBSYS_BEFORE_SHUTDOWN) {
  2384. penv->is_shutdown = 1;
  2385. wcnss_disable_pc_add_req();
  2386. schedule_delayed_work(&penv->wcnss_pm_qos_del_req,
  2387. msecs_to_jiffies(WCNSS_PM_QOS_TIMEOUT));
  2388. } else if (code == SUBSYS_POWERUP_FAILURE) {
  2389. wcnss_pronto_log_debug_regs();
  2390. wcnss_disable_pc_remove_req();
  2391. } else if (SUBSYS_AFTER_POWERUP == code)
  2392. penv->is_shutdown = 0;
  2393. return NOTIFY_DONE;
  2394. }
  2395. static const struct file_operations wcnss_node_fops = {
  2396. .owner = THIS_MODULE,
  2397. .open = wcnss_node_open,
  2398. .read = wcnss_wlan_read,
  2399. .write = wcnss_wlan_write,
  2400. .release = wcnss_node_release,
  2401. };
  2402. static struct miscdevice wcnss_misc = {
  2403. .minor = MISC_DYNAMIC_MINOR,
  2404. .name = DEVICE,
  2405. .fops = &wcnss_node_fops,
  2406. };
  2407. static int __devinit
  2408. wcnss_wlan_probe(struct platform_device *pdev)
  2409. {
  2410. int ret = 0;
  2411. /* verify we haven't been called more than once */
  2412. if (penv) {
  2413. dev_err(&pdev->dev, "cannot handle multiple devices.\n");
  2414. return -ENODEV;
  2415. }
  2416. /* create an environment to track the device */
  2417. penv = devm_kzalloc(&pdev->dev, sizeof(*penv), GFP_KERNEL);
  2418. if (!penv) {
  2419. dev_err(&pdev->dev, "cannot allocate device memory.\n");
  2420. return -ENOMEM;
  2421. }
  2422. penv->pdev = pdev;
  2423. penv->user_cal_data =
  2424. devm_kzalloc(&pdev->dev, MAX_CALIBRATED_DATA_SIZE, GFP_KERNEL);
  2425. if (!penv->user_cal_data) {
  2426. dev_err(&pdev->dev, "Failed to alloc memory for cal data.\n");
  2427. return -ENOMEM;
  2428. }
  2429. /* register sysfs entries */
  2430. ret = wcnss_create_sysfs(&pdev->dev);
  2431. if (ret) {
  2432. penv = NULL;
  2433. return -ENOENT;
  2434. }
  2435. /* register wcnss event notification */
  2436. penv->wcnss_notif_hdle = subsys_notif_register_notifier("wcnss", &wnb);
  2437. if (IS_ERR(penv->wcnss_notif_hdle)) {
  2438. pr_err("wcnss: register event notification failed!\n");
  2439. return PTR_ERR(penv->wcnss_notif_hdle);
  2440. }
  2441. mutex_init(&penv->dev_lock);
  2442. mutex_init(&penv->ctrl_lock);
  2443. mutex_init(&penv->vbat_monitor_mutex);
  2444. mutex_init(&penv->pm_qos_mutex);
  2445. init_waitqueue_head(&penv->read_wait);
  2446. penv->user_cal_rcvd = 0;
  2447. penv->user_cal_read = 0;
  2448. penv->user_cal_exp_size = 0;
  2449. penv->user_cal_available = false;
  2450. /* Since we were built into the kernel we'll be called as part
  2451. * of kernel initialization. We don't know if userspace
  2452. * applications are available to service PIL at this time
  2453. * (they probably are not), so we simply create a device node
  2454. * here. When userspace is available it should touch the
  2455. * device so that we know that WCNSS configuration can take
  2456. * place
  2457. */
  2458. pr_info(DEVICE " probed in built-in mode\n");
  2459. misc_register(&wcnss_usr_ctrl);
  2460. return misc_register(&wcnss_misc);
  2461. }
  2462. static int __devexit
  2463. wcnss_wlan_remove(struct platform_device *pdev)
  2464. {
  2465. if (penv->wcnss_notif_hdle)
  2466. subsys_notif_unregister_notifier(penv->wcnss_notif_hdle, &wnb);
  2467. wcnss_remove_sysfs(&pdev->dev);
  2468. penv = NULL;
  2469. return 0;
  2470. }
  2471. static const struct dev_pm_ops wcnss_wlan_pm_ops = {
  2472. .suspend = wcnss_wlan_suspend,
  2473. .resume = wcnss_wlan_resume,
  2474. };
  2475. #ifdef CONFIG_WCNSS_CORE_PRONTO
  2476. static struct of_device_id msm_wcnss_pronto_match[] = {
  2477. {.compatible = "qcom,wcnss_wlan"},
  2478. {}
  2479. };
  2480. #endif
  2481. static struct platform_driver wcnss_wlan_driver = {
  2482. .driver = {
  2483. .name = DEVICE,
  2484. .owner = THIS_MODULE,
  2485. .pm = &wcnss_wlan_pm_ops,
  2486. #ifdef CONFIG_WCNSS_CORE_PRONTO
  2487. .of_match_table = msm_wcnss_pronto_match,
  2488. #endif
  2489. },
  2490. .probe = wcnss_wlan_probe,
  2491. .remove = __devexit_p(wcnss_wlan_remove),
  2492. };
  2493. static int __init wcnss_wlan_init(void)
  2494. {
  2495. int ret = 0;
  2496. platform_driver_register(&wcnss_wlan_driver);
  2497. platform_driver_register(&wcnss_wlan_ctrl_driver);
  2498. platform_driver_register(&wcnss_ctrl_driver);
  2499. register_pm_notifier(&wcnss_pm_notifier);
  2500. #ifdef CONFIG_WCNSS_MEM_PRE_ALLOC
  2501. ret = wcnss_prealloc_init();
  2502. if (ret < 0)
  2503. pr_err("wcnss: pre-allocation failed\n");
  2504. #endif
  2505. return ret;
  2506. }
  2507. static void __exit wcnss_wlan_exit(void)
  2508. {
  2509. if (penv) {
  2510. if (penv->pil)
  2511. subsystem_put(penv->pil);
  2512. penv = NULL;
  2513. }
  2514. #ifdef CONFIG_WCNSS_MEM_PRE_ALLOC
  2515. wcnss_prealloc_deinit();
  2516. #endif
  2517. unregister_pm_notifier(&wcnss_pm_notifier);
  2518. platform_driver_unregister(&wcnss_ctrl_driver);
  2519. platform_driver_unregister(&wcnss_wlan_ctrl_driver);
  2520. platform_driver_unregister(&wcnss_wlan_driver);
  2521. }
  2522. module_init(wcnss_wlan_init);
  2523. module_exit(wcnss_wlan_exit);
  2524. MODULE_LICENSE("GPL v2");
  2525. MODULE_VERSION(VERSION);
  2526. MODULE_DESCRIPTION(DEVICE "Driver");