mt_sd_misc.c 30 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169
  1. #include <generated/autoconf.h>
  2. #include <linux/module.h>
  3. #include <linux/moduleparam.h>
  4. #include <linux/init.h>
  5. #include <linux/spinlock.h>
  6. #include <linux/timer.h>
  7. #include <linux/ioport.h>
  8. #include <linux/device.h>
  9. #include <linux/miscdevice.h>
  10. #include <linux/platform_device.h>
  11. #include <linux/interrupt.h>
  12. #include <linux/delay.h>
  13. #include <linux/blkdev.h>
  14. #include <linux/mmc/host.h>
  15. #include <linux/mmc/card.h>
  16. #include <linux/mmc/core.h>
  17. #include <linux/mmc/mmc.h>
  18. #include <linux/mmc/sd.h>
  19. #include <linux/mmc/sdio.h>
  20. #include <linux/dma-mapping.h>
  21. #include <queue.h>
  22. #include "mt_sd.h"
  23. #include <mt-plat/sd_misc.h>
  24. #ifndef FPGA_PLATFORM
  25. #ifdef CONFIG_MTK_CLKMGR
  26. #include <mach/mt_clkmgr.h>
  27. #endif
  28. #endif
  29. #include <linux/proc_fs.h>
  30. #include <linux/fs.h>
  31. #include <asm/uaccess.h>
  32. #define PARTITION_NAME_LENGTH (64)
  33. #define DRV_NAME_MISC "misc-sd"
  34. #define DEBUG_MMC_IOCTL 0
  35. #define DEBUG_MSDC_SSC 1
  36. /*
  37. * For simple_sd_ioctl
  38. */
  39. #define FORCE_IN_DMA (0x11)
  40. #define FORCE_IN_PIO (0x10)
  41. #define FORCE_NOTHING (0x0)
  42. static int dma_force[HOST_MAX_NUM] = /* used for sd ioctrol */
  43. {
  44. FORCE_NOTHING,
  45. FORCE_NOTHING,
  46. FORCE_NOTHING,
  47. FORCE_NOTHING,
  48. };
  49. #define dma_is_forced(host_id) (dma_force[host_id] & 0x10)
  50. #define get_forced_transfer_mode(host_id) (dma_force[host_id] & 0x01)
  51. static u32 *sg_msdc_multi_buffer;
  52. static int simple_sd_open(struct inode *inode, struct file *file)
  53. {
  54. return 0;
  55. }
  56. static int sd_ioctl_reinit(struct msdc_ioctl *msdc_ctl)
  57. {
  58. struct msdc_host *host = msdc_get_host(MSDC_SD, 0, 0);
  59. if (NULL != host)
  60. return msdc_reinit(host);
  61. else
  62. return -EINVAL;
  63. }
  64. static int sd_ioctl_cd_pin_en(struct msdc_ioctl *msdc_ctl)
  65. {
  66. struct msdc_host *host = msdc_get_host(MSDC_SD, 0, 0);
  67. if (NULL != host) {
  68. if (host->hw->host_function == MSDC_SD)
  69. return ((host->hw->flags & MSDC_CD_PIN_EN) == MSDC_CD_PIN_EN);
  70. else
  71. return -EINVAL;
  72. } else
  73. return -EINVAL;
  74. }
  75. static void simple_sd_get_driving(struct msdc_host *host,
  76. struct msdc_ioctl *msdc_ctl)
  77. {
  78. switch (host->id) {
  79. case 0:
  80. sdr_get_field(MSDC0_GPIO_DRV0_G5_ADDR,
  81. MSDC0_DRV_CMD_MASK, msdc_ctl->cmd_pu_driving);
  82. sdr_get_field(MSDC0_GPIO_DRV0_G5_ADDR,
  83. MSDC0_DRV_DSL_MASK, msdc_ctl->ds_pu_driving);
  84. sdr_get_field(MSDC0_GPIO_DRV0_G5_ADDR,
  85. MSDC0_DRV_CLK_MASK, msdc_ctl->clk_pu_driving);
  86. sdr_get_field(MSDC0_GPIO_DRV0_G5_ADDR,
  87. MSDC0_DRV_DAT_MASK, msdc_ctl->dat_pu_driving);
  88. sdr_get_field(MSDC0_GPIO_DRV0_G5_ADDR,
  89. MSDC0_DRV_RSTB_MASK, msdc_ctl->rst_pu_driving);
  90. break;
  91. case 1:
  92. sdr_get_field(MSDC1_GPIO_DRV0_G4_ADDR,
  93. MSDC1_DRV_CMD_MASK, msdc_ctl->cmd_pu_driving);
  94. sdr_get_field(MSDC1_GPIO_DRV0_G4_ADDR,
  95. MSDC1_DRV_CLK_MASK, msdc_ctl->clk_pu_driving);
  96. sdr_get_field(MSDC1_GPIO_DRV0_G4_ADDR,
  97. MSDC1_DRV_DAT_MASK, msdc_ctl->dat_pu_driving);
  98. msdc_ctl->rst_pu_driving = 0;
  99. msdc_ctl->ds_pu_driving = 0;
  100. break;
  101. #ifdef CFG_DEV_MSDC2 /* FIXME: For 6630 */
  102. case 2:
  103. sdr_get_field(MSDC2_GPIO_DRV0_G0_ADDR,
  104. MSDC2_DRV_CMD_MASK, msdc_ctl->cmd_pu_driving);
  105. sdr_get_field(MSDC2_GPIO_DRV0_G0_ADDR,
  106. MSDC2_DRV_CLK_MASK, msdc_ctl->clk_pu_driving);
  107. sdr_get_field(MSDC2_GPIO_DRV0_G0_ADDR,
  108. MSDC2_DRV_DAT_MASK, msdc_ctl->dat_pu_driving);
  109. msdc_ctl->rst_pu_driving = 0;
  110. msdc_ctl->ds_pu_driving = 0;
  111. break;
  112. #endif
  113. default:
  114. pr_err("error...[%s] host->id out of range!!!\n", __func__);
  115. break;
  116. }
  117. }
  118. static int simple_sd_ioctl_multi_rw(struct msdc_ioctl *msdc_ctl)
  119. {
  120. char l_buf[512];
  121. struct scatterlist msdc_sg;
  122. struct mmc_data msdc_data;
  123. struct mmc_command msdc_cmd;
  124. struct mmc_command msdc_stop;
  125. int ret = 0;
  126. #ifdef MTK_MSDC_USE_CMD23
  127. struct mmc_command msdc_sbc;
  128. #endif
  129. struct mmc_request msdc_mrq;
  130. struct msdc_host *host_ctl;
  131. if (!msdc_ctl)
  132. return -EINVAL;
  133. if (msdc_ctl->total_size <= 0)
  134. return -EINVAL;
  135. host_ctl = mtk_msdc_host[msdc_ctl->host_num];
  136. if (IS_ERR_OR_NULL(host_ctl))
  137. return -EINVAL;
  138. if (IS_ERR_OR_NULL(host_ctl->mmc))
  139. return -EINVAL;
  140. if (IS_ERR_OR_NULL(host_ctl->mmc->card))
  141. return -EINVAL;
  142. msdc_ctl->result = 0;
  143. /*
  144. * workaround here, if sd.c has remove baisc DMA 64KB limit
  145. * sg_msdc_multi_buffer should alloc size :max_reg_size,not 64KB
  146. * at simple_sd_init function.
  147. */
  148. if (msdc_ctl->total_size > (64 * 1024)) {
  149. pr_err("%s [%d]: read or write size excced 64KB\n", __func__, __LINE__);
  150. msdc_ctl->result = -1;
  151. goto multi_end_without_release;
  152. }
  153. if (msdc_ctl->iswrite) {
  154. if (MSDC_CARD_DUNM_FUNC != msdc_ctl->opcode) {
  155. if (copy_from_user(sg_msdc_multi_buffer, msdc_ctl->buffer,
  156. msdc_ctl->total_size)) {
  157. dma_force[host_ctl->id] = FORCE_NOTHING;
  158. ret = -EFAULT;
  159. goto multi_end_without_release;
  160. }
  161. } else {
  162. /* called from other kernel module */
  163. memcpy(sg_msdc_multi_buffer, msdc_ctl->buffer, msdc_ctl->total_size);
  164. }
  165. }
  166. mmc_claim_host(host_ctl->mmc);
  167. #if DEBUG_MMC_IOCTL
  168. pr_debug("user want access %d partition\n", msdc_ctl->partition);
  169. #endif
  170. ret = mmc_send_ext_csd(host_ctl->mmc->card, l_buf);
  171. if (ret) {
  172. pr_debug("mmc_send_ext_csd error, multi rw\n");
  173. goto multi_end;
  174. }
  175. #ifdef CONFIG_MTK_EMMC_SUPPORT
  176. switch (msdc_ctl->partition) {
  177. case EMMC_PART_BOOT1:
  178. if (0x1 != (l_buf[179] & 0x7)) {
  179. /* change to access boot partition 1 */
  180. l_buf[179] &= ~0x7;
  181. l_buf[179] |= 0x1;
  182. mmc_switch(host_ctl->mmc->card, EXT_CSD_CMD_SET_NORMAL,
  183. 179, l_buf[179], 1000);
  184. }
  185. break;
  186. case EMMC_PART_BOOT2:
  187. if (0x2 != (l_buf[179] & 0x7)) {
  188. /* change to access boot partition 2 */
  189. l_buf[179] &= ~0x7;
  190. l_buf[179] |= 0x2;
  191. mmc_switch(host_ctl->mmc->card, EXT_CSD_CMD_SET_NORMAL,
  192. 179, l_buf[179], 1000);
  193. }
  194. break;
  195. default:
  196. /* make sure access partition is user data area */
  197. if (0 != (l_buf[179] & 0x7)) {
  198. /* set back to access user area */
  199. l_buf[179] &= ~0x7;
  200. l_buf[179] |= 0x0;
  201. mmc_switch(host_ctl->mmc->card, EXT_CSD_CMD_SET_NORMAL,
  202. 179, l_buf[179], 1000);
  203. }
  204. break;
  205. }
  206. #endif
  207. memset(&msdc_data, 0, sizeof(struct mmc_data));
  208. memset(&msdc_mrq, 0, sizeof(struct mmc_request));
  209. memset(&msdc_cmd, 0, sizeof(struct mmc_command));
  210. memset(&msdc_stop, 0, sizeof(struct mmc_command));
  211. #ifdef MTK_MSDC_USE_CMD23
  212. memset(&msdc_sbc, 0, sizeof(struct mmc_command));
  213. #endif
  214. msdc_mrq.cmd = &msdc_cmd;
  215. msdc_mrq.data = &msdc_data;
  216. if (msdc_ctl->trans_type)
  217. dma_force[host_ctl->id] = FORCE_IN_DMA;
  218. else
  219. dma_force[host_ctl->id] = FORCE_IN_PIO;
  220. if (msdc_ctl->iswrite) {
  221. msdc_data.flags = MMC_DATA_WRITE;
  222. msdc_cmd.opcode = MMC_WRITE_MULTIPLE_BLOCK;
  223. msdc_data.blocks = msdc_ctl->total_size / 512;
  224. } else {
  225. msdc_data.flags = MMC_DATA_READ;
  226. msdc_cmd.opcode = MMC_READ_MULTIPLE_BLOCK;
  227. msdc_data.blocks = msdc_ctl->total_size / 512;
  228. memset(sg_msdc_multi_buffer, 0, msdc_ctl->total_size);
  229. }
  230. #ifdef MTK_MSDC_USE_CMD23
  231. if ((mmc_card_mmc(host_ctl->mmc->card)
  232. || (mmc_card_sd(host_ctl->mmc->card)
  233. && host_ctl->mmc->card->scr.cmds & SD_SCR_CMD23_SUPPORT))
  234. && !(host_ctl->mmc->card->quirks & MMC_QUIRK_BLK_NO_CMD23)) {
  235. msdc_mrq.sbc = &msdc_sbc;
  236. msdc_mrq.sbc->opcode = MMC_SET_BLOCK_COUNT;
  237. #ifdef MTK_MSDC_USE_CACHE
  238. /* if ioctl access cacheable partition data, there is on flush mechanism in msdc driver
  239. * so do reliable write .*/
  240. if (mmc_card_mmc(host_ctl->mmc->card)
  241. && (host_ctl->mmc->card->ext_csd.cache_ctrl & 0x1)
  242. && (msdc_cmd.opcode == MMC_WRITE_MULTIPLE_BLOCK))
  243. msdc_mrq.sbc->arg = msdc_data.blocks | (1 << 31);
  244. else
  245. msdc_mrq.sbc->arg = msdc_data.blocks;
  246. #else
  247. msdc_mrq.sbc->arg = msdc_data.blocks;
  248. #endif
  249. msdc_mrq.sbc->flags = MMC_RSP_R1 | MMC_CMD_AC;
  250. }
  251. #endif
  252. msdc_cmd.arg = msdc_ctl->address;
  253. if (!mmc_card_blockaddr(host_ctl->mmc->card)) {
  254. pr_debug("this device use byte address!!\n");
  255. msdc_cmd.arg <<= 9;
  256. }
  257. msdc_cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
  258. msdc_stop.opcode = MMC_STOP_TRANSMISSION;
  259. msdc_stop.arg = 0;
  260. msdc_stop.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC;
  261. msdc_data.stop = &msdc_stop;
  262. msdc_data.blksz = 512;
  263. msdc_data.sg = &msdc_sg;
  264. msdc_data.sg_len = 1;
  265. #if DEBUG_MMC_IOCTL
  266. pr_debug("total size is %d\n", msdc_ctl->total_size);
  267. #endif
  268. sg_init_one(&msdc_sg, sg_msdc_multi_buffer, msdc_ctl->total_size);
  269. mmc_set_data_timeout(&msdc_data, host_ctl->mmc->card);
  270. mmc_wait_for_req(host_ctl->mmc, &msdc_mrq);
  271. if (msdc_ctl->partition) {
  272. ret = mmc_send_ext_csd(host_ctl->mmc->card, l_buf);
  273. if (ret) {
  274. pr_debug("mmc_send_ext_csd error, multi rw2\n");
  275. goto multi_end;
  276. }
  277. if (l_buf[179] & 0x7) {
  278. /* set back to access user area */
  279. l_buf[179] &= ~0x7;
  280. l_buf[179] |= 0x0;
  281. mmc_switch(host_ctl->mmc->card, EXT_CSD_CMD_SET_NORMAL,
  282. 179, l_buf[179], 1000);
  283. }
  284. }
  285. mmc_release_host(host_ctl->mmc);
  286. if (!msdc_ctl->iswrite) {
  287. if (MSDC_CARD_DUNM_FUNC != msdc_ctl->opcode) {
  288. if (copy_to_user(msdc_ctl->buffer, sg_msdc_multi_buffer,
  289. msdc_ctl->total_size)) {
  290. dma_force[host_ctl->id] = FORCE_NOTHING;
  291. ret = -EFAULT;
  292. goto multi_end_without_release;
  293. }
  294. } else {
  295. /* called from other kernel module */
  296. memcpy(msdc_ctl->buffer, sg_msdc_multi_buffer, msdc_ctl->total_size);
  297. }
  298. }
  299. /* clear the global buffer of R/W IOCTL */
  300. memset(sg_msdc_multi_buffer, 0 , msdc_ctl->total_size);
  301. goto multi_end_without_release;
  302. multi_end:
  303. mmc_release_host(host_ctl->mmc);
  304. multi_end_without_release:
  305. if (ret)
  306. msdc_ctl->result = ret;
  307. if (msdc_cmd.error)
  308. msdc_ctl->result = msdc_cmd.error;
  309. if (msdc_data.error)
  310. msdc_ctl->result = msdc_data.error;
  311. dma_force[host_ctl->id] = FORCE_NOTHING;
  312. return msdc_ctl->result;
  313. }
  314. static int simple_sd_ioctl_single_rw(struct msdc_ioctl *msdc_ctl)
  315. {
  316. char l_buf[512];
  317. struct scatterlist msdc_sg;
  318. struct mmc_data msdc_data;
  319. struct mmc_command msdc_cmd;
  320. struct mmc_request msdc_mrq;
  321. struct msdc_host *host_ctl;
  322. int ret = 0;
  323. if (!msdc_ctl)
  324. return -EINVAL;
  325. if (msdc_ctl->total_size <= 0)
  326. return -EINVAL;
  327. host_ctl = mtk_msdc_host[msdc_ctl->host_num];
  328. if (IS_ERR_OR_NULL(host_ctl))
  329. return -EINVAL;
  330. if (IS_ERR_OR_NULL(host_ctl->mmc))
  331. return -EINVAL;
  332. if (IS_ERR_OR_NULL(host_ctl->mmc->card))
  333. return -EINVAL;
  334. msdc_ctl->result = 0;
  335. #ifdef MTK_MSDC_USE_CACHE
  336. if (msdc_ctl->iswrite && mmc_card_mmc(host_ctl->mmc->card)
  337. && (host_ctl->mmc->card->ext_csd.cache_ctrl & 0x1))
  338. return simple_sd_ioctl_multi_rw(msdc_ctl);
  339. #endif
  340. if (msdc_ctl->iswrite) {
  341. if (MSDC_CARD_DUNM_FUNC != msdc_ctl->opcode) {
  342. if (copy_from_user(sg_msdc_multi_buffer, msdc_ctl->buffer, 512)) {
  343. dma_force[host_ctl->id] = FORCE_NOTHING;
  344. ret = -EFAULT;
  345. goto single_end_without_release;
  346. }
  347. } else {
  348. /* called from other kernel module */
  349. memcpy(sg_msdc_multi_buffer, msdc_ctl->buffer, 512);
  350. }
  351. } else {
  352. memset(sg_msdc_multi_buffer, 0 , 512);
  353. }
  354. if (msdc_ctl->total_size > 512) {
  355. msdc_ctl->result = -1;
  356. goto single_end_without_release;
  357. }
  358. mmc_claim_host(host_ctl->mmc);
  359. #if DEBUG_MMC_IOCTL
  360. pr_debug("user want access %d partition\n", msdc_ctl->partition);
  361. #endif
  362. ret = mmc_send_ext_csd(host_ctl->mmc->card, l_buf);
  363. if (ret) {
  364. pr_debug("mmc_send_ext_csd error, single rw\n");
  365. goto single_end;
  366. }
  367. #ifdef CONFIG_MTK_EMMC_SUPPORT
  368. switch (msdc_ctl->partition) {
  369. case EMMC_PART_BOOT1:
  370. if (0x1 != (l_buf[179] & 0x7)) {
  371. /* change to access boot partition 1 */
  372. l_buf[179] &= ~0x7;
  373. l_buf[179] |= 0x1;
  374. mmc_switch(host_ctl->mmc->card, EXT_CSD_CMD_SET_NORMAL,
  375. 179, l_buf[179], 1000);
  376. }
  377. break;
  378. case EMMC_PART_BOOT2:
  379. if (0x2 != (l_buf[179] & 0x7)) {
  380. /* change to access boot partition 2 */
  381. l_buf[179] &= ~0x7;
  382. l_buf[179] |= 0x2;
  383. mmc_switch(host_ctl->mmc->card, EXT_CSD_CMD_SET_NORMAL,
  384. 179, l_buf[179], 1000);
  385. }
  386. break;
  387. default:
  388. /* make sure access partition is user data area */
  389. if (0 != (l_buf[179] & 0x7)) {
  390. /* set back to access user area */
  391. l_buf[179] &= ~0x7;
  392. l_buf[179] |= 0x0;
  393. mmc_switch(host_ctl->mmc->card, EXT_CSD_CMD_SET_NORMAL,
  394. 179, l_buf[179], 1000);
  395. }
  396. break;
  397. }
  398. #endif
  399. #if DEBUG_MMC_IOCTL
  400. pr_debug("start MSDC_SINGLE_READ_WRITE !!\n");
  401. #endif
  402. memset(&msdc_data, 0, sizeof(struct mmc_data));
  403. memset(&msdc_mrq, 0, sizeof(struct mmc_request));
  404. memset(&msdc_cmd, 0, sizeof(struct mmc_command));
  405. msdc_mrq.cmd = &msdc_cmd;
  406. msdc_mrq.data = &msdc_data;
  407. if (msdc_ctl->trans_type)
  408. dma_force[host_ctl->id] = FORCE_IN_DMA;
  409. else
  410. dma_force[host_ctl->id] = FORCE_IN_PIO;
  411. if (msdc_ctl->iswrite) {
  412. msdc_data.flags = MMC_DATA_WRITE;
  413. msdc_cmd.opcode = MMC_WRITE_BLOCK;
  414. msdc_data.blocks = msdc_ctl->total_size / 512;
  415. } else {
  416. msdc_data.flags = MMC_DATA_READ;
  417. msdc_cmd.opcode = MMC_READ_SINGLE_BLOCK;
  418. msdc_data.blocks = msdc_ctl->total_size / 512;
  419. memset(sg_msdc_multi_buffer, 0, 512);
  420. }
  421. msdc_cmd.arg = msdc_ctl->address;
  422. if (!mmc_card_blockaddr(host_ctl->mmc->card)) {
  423. pr_debug("the device is used byte address!\n");
  424. msdc_cmd.arg <<= 9;
  425. }
  426. msdc_cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
  427. msdc_data.stop = NULL;
  428. msdc_data.blksz = 512;
  429. msdc_data.sg = &msdc_sg;
  430. msdc_data.sg_len = 1;
  431. #if DEBUG_MMC_IOCTL
  432. pr_debug("single block: ueser buf address is 0x%p!\n", msdc_ctl->buffer);
  433. #endif
  434. sg_init_one(&msdc_sg, sg_msdc_multi_buffer, msdc_ctl->total_size);
  435. mmc_set_data_timeout(&msdc_data, host_ctl->mmc->card);
  436. mmc_wait_for_req(host_ctl->mmc, &msdc_mrq);
  437. if (msdc_ctl->partition) {
  438. ret = mmc_send_ext_csd(host_ctl->mmc->card, l_buf);
  439. if (ret) {
  440. pr_debug("mmc_send_ext_csd error, single rw2\n");
  441. goto single_end;
  442. }
  443. if (l_buf[179] & 0x7) {
  444. /* set back to access user area */
  445. l_buf[179] &= ~0x7;
  446. l_buf[179] |= 0x0;
  447. mmc_switch(host_ctl->mmc->card, EXT_CSD_CMD_SET_NORMAL,
  448. 179, l_buf[179], 1000);
  449. }
  450. }
  451. mmc_release_host(host_ctl->mmc);
  452. if (!msdc_ctl->iswrite) {
  453. if (MSDC_CARD_DUNM_FUNC != msdc_ctl->opcode) {
  454. if (copy_to_user(msdc_ctl->buffer, sg_msdc_multi_buffer, 512)) {
  455. dma_force[host_ctl->id] = FORCE_NOTHING;
  456. ret = -EFAULT;
  457. goto single_end_without_release;
  458. }
  459. } else {
  460. /* called from other kernel module */
  461. memcpy(msdc_ctl->buffer, sg_msdc_multi_buffer, 512);
  462. }
  463. }
  464. /* clear the global buffer of R/W IOCTL */
  465. memset(sg_msdc_multi_buffer, 0, 512);
  466. goto single_end_without_release;
  467. single_end:
  468. mmc_release_host(host_ctl->mmc);
  469. single_end_without_release:
  470. if (ret)
  471. msdc_ctl->result = ret;
  472. if (msdc_cmd.error)
  473. msdc_ctl->result = msdc_cmd.error;
  474. if (msdc_data.error)
  475. msdc_ctl->result = msdc_data.error;
  476. dma_force[host_ctl->id] = FORCE_NOTHING;
  477. return msdc_ctl->result;
  478. }
  479. int simple_sd_ioctl_rw(struct msdc_ioctl *msdc_ctl)
  480. {
  481. if ((msdc_ctl->total_size > 512) && (msdc_ctl->total_size <= MAX_REQ_SZ))
  482. return simple_sd_ioctl_multi_rw(msdc_ctl);
  483. else
  484. return simple_sd_ioctl_single_rw(msdc_ctl);
  485. }
  486. static int simple_sd_ioctl_get_cid(struct msdc_ioctl *msdc_ctl)
  487. {
  488. struct msdc_host *host_ctl;
  489. if (!msdc_ctl)
  490. return -EINVAL;
  491. host_ctl = mtk_msdc_host[msdc_ctl->host_num];
  492. if (IS_ERR_OR_NULL(host_ctl))
  493. return -EINVAL;
  494. if (IS_ERR_OR_NULL(host_ctl->mmc))
  495. return -EINVAL;
  496. if (IS_ERR_OR_NULL(host_ctl->mmc->card))
  497. return -EINVAL;
  498. #if DEBUG_MMC_IOCTL
  499. pr_debug("user want the cid in msdc slot%d\n", msdc_ctl->host_num);
  500. #endif
  501. if (copy_to_user(msdc_ctl->buffer, &host_ctl->mmc->card->raw_cid, 16))
  502. return -EFAULT;
  503. #if DEBUG_MMC_IOCTL
  504. pr_debug("cid:0x%x,0x%x,0x%x,0x%x\n",
  505. host_ctl->mmc->card->raw_cid[0], host_ctl->mmc->card->raw_cid[1],
  506. host_ctl->mmc->card->raw_cid[2], host_ctl->mmc->card->raw_cid[3]);
  507. #endif
  508. return 0;
  509. }
  510. static int simple_sd_ioctl_get_csd(struct msdc_ioctl *msdc_ctl)
  511. {
  512. struct msdc_host *host_ctl;
  513. if (!msdc_ctl)
  514. return -EINVAL;
  515. host_ctl = mtk_msdc_host[msdc_ctl->host_num];
  516. if (IS_ERR_OR_NULL(host_ctl))
  517. return -EINVAL;
  518. if (IS_ERR_OR_NULL(host_ctl->mmc))
  519. return -EINVAL;
  520. if (IS_ERR_OR_NULL(host_ctl->mmc->card))
  521. return -EINVAL;
  522. #if DEBUG_MMC_IOCTL
  523. pr_debug("user want the csd in msdc slot%d\n", msdc_ctl->host_num);
  524. #endif
  525. if (copy_to_user(msdc_ctl->buffer, &host_ctl->mmc->card->raw_csd, 16))
  526. return -EFAULT;
  527. #if DEBUG_MMC_IOCTL
  528. pr_debug("csd:0x%x,0x%x,0x%x,0x%x\n",
  529. host_ctl->mmc->card->raw_csd[0], host_ctl->mmc->card->raw_csd[1],
  530. host_ctl->mmc->card->raw_csd[2], host_ctl->mmc->card->raw_csd[3]);
  531. #endif
  532. return 0;
  533. }
  534. static int simple_sd_ioctl_get_excsd(struct msdc_ioctl *msdc_ctl)
  535. {
  536. char l_buf[512];
  537. struct msdc_host *host_ctl;
  538. int ret = 0;
  539. #if DEBUG_MMC_IOCTL
  540. int i;
  541. #endif
  542. if (!msdc_ctl)
  543. goto out;
  544. host_ctl = mtk_msdc_host[msdc_ctl->host_num];
  545. if (IS_ERR_OR_NULL(host_ctl))
  546. goto out;
  547. if (IS_ERR_OR_NULL(host_ctl->mmc))
  548. goto out;
  549. if (IS_ERR_OR_NULL(host_ctl->mmc->card))
  550. goto out;
  551. #if DEBUG_MMC_IOCTL
  552. pr_debug("user want the extend csd in msdc slot%d\n", msdc_ctl->host_num);
  553. #endif
  554. mmc_claim_host(host_ctl->mmc);
  555. ret = mmc_send_ext_csd(host_ctl->mmc->card, l_buf);
  556. mmc_release_host(host_ctl->mmc);
  557. if (ret)
  558. goto out;
  559. if (copy_to_user(msdc_ctl->buffer, l_buf, 512))
  560. goto out;
  561. #if DEBUG_MMC_IOCTL
  562. for (i = 0; i < 512; i++) {
  563. pr_debug("%x", l_buf[i]);
  564. if (0 == ((i + 1) % 16))
  565. pr_debug("\n");
  566. }
  567. #endif
  568. return 0;
  569. out:
  570. return -EINVAL;
  571. }
  572. static int simple_sd_ioctl_set_driving(struct msdc_ioctl *msdc_ctl)
  573. {
  574. void __iomem *base;
  575. struct msdc_host *host;
  576. #if DEBUG_MMC_IOCTL
  577. unsigned int l_value;
  578. #endif
  579. if (!msdc_ctl)
  580. return -EINVAL;
  581. if ((msdc_ctl->host_num < 0) || (msdc_ctl->host_num >= HOST_MAX_NUM)) {
  582. pr_err("invalid host num: %d\n", msdc_ctl->host_num);
  583. return -EINVAL;
  584. }
  585. if (mtk_msdc_host[msdc_ctl->host_num])
  586. host = mtk_msdc_host[msdc_ctl->host_num];
  587. else {
  588. pr_err("host%d is not config\n", msdc_ctl->host_num);
  589. return -EINVAL;
  590. }
  591. base = host->base;
  592. #ifndef FPGA_PLATFORM
  593. #ifdef CONFIG_MTK_CLKMGR
  594. enable_clock(MT_CG_PERI_MSDC30_0 + host->id, "SD");
  595. #else
  596. clk_enable(host->clock_control);
  597. #endif
  598. #if DEBUG_MMC_IOCTL
  599. pr_debug("set: clk driving is 0x%x\n", msdc_ctl->clk_pu_driving);
  600. pr_debug("set: cmd driving is 0x%x\n", msdc_ctl->cmd_pu_driving);
  601. pr_debug("set: dat driving is 0x%x\n", msdc_ctl->dat_pu_driving);
  602. pr_debug("set: rst driving is 0x%x\n", msdc_ctl->rst_pu_driving);
  603. pr_debug("set: ds driving is 0x%x\n", msdc_ctl->ds_pu_driving);
  604. #endif
  605. host->hw->clk_drv = msdc_ctl->clk_pu_driving;
  606. host->hw->cmd_drv = msdc_ctl->cmd_pu_driving;
  607. host->hw->dat_drv = msdc_ctl->dat_pu_driving;
  608. host->hw->rst_drv = msdc_ctl->rst_pu_driving;
  609. host->hw->ds_drv = msdc_ctl->ds_pu_driving;
  610. host->hw->clk_drv_sd_18 = msdc_ctl->clk_pu_driving;
  611. host->hw->cmd_drv_sd_18 = msdc_ctl->cmd_pu_driving;
  612. host->hw->dat_drv_sd_18 = msdc_ctl->dat_pu_driving;
  613. msdc_set_driving(host, host->hw, 0);
  614. #if DEBUG_MMC_IOCTL
  615. #if 0
  616. msdc_dump_padctl(host);
  617. #endif
  618. #endif
  619. #endif
  620. return 0;
  621. }
  622. static int simple_sd_ioctl_get_driving(struct msdc_ioctl *msdc_ctl)
  623. {
  624. void __iomem *base;
  625. /* unsigned int l_value; */
  626. struct msdc_host *host;
  627. if (!msdc_ctl)
  628. return -EINVAL;
  629. if ((msdc_ctl->host_num < 0) || (msdc_ctl->host_num >= HOST_MAX_NUM)) {
  630. pr_err("invalid host num: %d\n", msdc_ctl->host_num);
  631. return -EINVAL;
  632. }
  633. if (mtk_msdc_host[msdc_ctl->host_num])
  634. host = mtk_msdc_host[msdc_ctl->host_num];
  635. else {
  636. pr_err("host%d is not config\n", msdc_ctl->host_num);
  637. return -EINVAL;
  638. }
  639. base = host->base;
  640. #ifndef FPGA_PLATFORM
  641. #ifdef CONFIG_MTK_CLKMGR
  642. enable_clock(MT_CG_PERI_MSDC30_0 + host->id, "SD");
  643. #else
  644. clk_enable(host->clock_control);
  645. #endif
  646. simple_sd_get_driving(mtk_msdc_host[msdc_ctl->host_num], msdc_ctl);
  647. #if DEBUG_MMC_IOCTL
  648. pr_debug("read: clk driving is 0x%x\n", msdc_ctl->clk_pu_driving);
  649. pr_debug("read: cmd driving is 0x%x\n", msdc_ctl->cmd_pu_driving);
  650. pr_debug("read: dat driving is 0x%x\n", msdc_ctl->dat_pu_driving);
  651. pr_debug("read: rst driving is 0x%x\n", msdc_ctl->rst_pu_driving);
  652. pr_debug("read: ds driving is 0x%x\n", msdc_ctl->ds_pu_driving);
  653. #endif
  654. #endif
  655. return 0;
  656. }
  657. static int simple_sd_ioctl_sd30_mode_switch(struct msdc_ioctl *msdc_ctl)
  658. {
  659. /* u32 base; */
  660. /* struct msdc_hw hw; */
  661. int id;
  662. #if DEBUG_MMC_IOCTL
  663. unsigned int l_value;
  664. #endif
  665. if (!msdc_ctl)
  666. return -EINVAL;
  667. id = msdc_ctl->host_num;
  668. if ((msdc_ctl->host_num < 0) || (msdc_ctl->host_num >= HOST_MAX_NUM)) {
  669. pr_err("invalid host num: %d\n", msdc_ctl->host_num);
  670. return -EINVAL;
  671. }
  672. if (!mtk_msdc_host[msdc_ctl->host_num]) {
  673. pr_err("host%d is not config\n", msdc_ctl->host_num);
  674. return -EINVAL;
  675. }
  676. switch (msdc_ctl->sd30_mode) {
  677. case SDHC_HIGHSPEED:
  678. msdc_host_mode[id] |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED;
  679. msdc_host_mode[id] &= (~MMC_CAP_UHS_SDR12) & (~MMC_CAP_UHS_SDR25) &
  680. (~MMC_CAP_UHS_SDR50) & (~MMC_CAP_UHS_DDR50) &
  681. (~MMC_CAP_1_8V_DDR) & (~MMC_CAP_UHS_SDR104);
  682. msdc_host_mode2[id] &= (~MMC_CAP2_HS200_1_8V_SDR) & (~MMC_CAP2_HS400_1_8V);
  683. pr_debug("[****SD_Debug****]host will support Highspeed\n");
  684. break;
  685. case UHS_SDR12:
  686. msdc_host_mode[id] |= MMC_CAP_UHS_SDR12;
  687. msdc_host_mode[id] &= (~MMC_CAP_UHS_SDR25) & (~MMC_CAP_UHS_SDR50) &
  688. (~MMC_CAP_UHS_DDR50) & (~MMC_CAP_1_8V_DDR) & (~MMC_CAP_UHS_SDR104);
  689. msdc_host_mode2[id] &= (~MMC_CAP2_HS200_1_8V_SDR) & (~MMC_CAP2_HS400_1_8V);
  690. pr_debug("[****SD_Debug****]host will support UHS-SDR12\n");
  691. break;
  692. case UHS_SDR25:
  693. msdc_host_mode[id] |= MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25;
  694. msdc_host_mode[id] &= (~MMC_CAP_UHS_SDR50) & (~MMC_CAP_UHS_DDR50) &
  695. (~MMC_CAP_1_8V_DDR) & (~MMC_CAP_UHS_SDR104);
  696. msdc_host_mode2[id] &= (~MMC_CAP2_HS200_1_8V_SDR) & (~MMC_CAP2_HS400_1_8V);
  697. pr_debug("[****SD_Debug****]host will support UHS-SDR25\n");
  698. break;
  699. case UHS_SDR50:
  700. msdc_host_mode[id] |= MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 | MMC_CAP_UHS_SDR50;
  701. msdc_host_mode[id] &= (~MMC_CAP_UHS_DDR50) & (~MMC_CAP_1_8V_DDR) &
  702. (~MMC_CAP_UHS_SDR104);
  703. msdc_host_mode2[id] &= (~MMC_CAP2_HS200_1_8V_SDR) & (~MMC_CAP2_HS400_1_8V);
  704. pr_debug("[****SD_Debug****]host will support UHS-SDR50\n");
  705. break;
  706. case UHS_SDR104:
  707. msdc_host_mode[id] |= MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
  708. MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_DDR50 | MMC_CAP_1_8V_DDR | MMC_CAP_UHS_SDR104;
  709. msdc_host_mode2[id] |= MMC_CAP2_HS200_1_8V_SDR;
  710. msdc_host_mode2[id] &= (~MMC_CAP2_HS400_1_8V);
  711. pr_debug("[****SD_Debug****]host will support UHS-SDR104\n");
  712. break;
  713. case UHS_DDR50:
  714. msdc_host_mode[id] |= MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
  715. MMC_CAP_UHS_DDR50 | MMC_CAP_1_8V_DDR;
  716. msdc_host_mode[id] &= (~MMC_CAP_UHS_SDR50) & (~MMC_CAP_UHS_SDR104);
  717. msdc_host_mode2[id] &= (~MMC_CAP2_HS200_1_8V_SDR) & (~MMC_CAP2_HS400_1_8V);
  718. pr_debug("[****SD_Debug****]host will support UHS-DDR50\n");
  719. break;
  720. case 6: /* EMMC_HS400: */
  721. msdc_host_mode[id] |= MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
  722. MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_DDR50 | MMC_CAP_1_8V_DDR | MMC_CAP_UHS_SDR104;
  723. msdc_host_mode2[id] |= MMC_CAP2_HS200_1_8V_SDR | MMC_CAP2_HS400_1_8V;
  724. pr_debug("[****SD_Debug****]host will support EMMC_HS400\n");
  725. break;
  726. default:
  727. pr_debug("[****SD_Debug****]invalid sd30_mode:%d\n", msdc_ctl->sd30_mode);
  728. break;
  729. }
  730. pr_debug("\n [%s]: msdc%d, line:%d, msdc_host_mode2=%d\n",
  731. __func__, id, __LINE__, msdc_host_mode2[id]);
  732. #ifdef CONFIG_MTK_EMMC_SUPPORT
  733. /* just for emmc slot */
  734. if (msdc_ctl->host_num == 0)
  735. g_emmc_mode_switch = 1;
  736. else
  737. g_emmc_mode_switch = 0;
  738. #endif
  739. return 0;
  740. }
  741. /* to ensure format operate is clean the emmc device fully(partition erase) */
  742. typedef struct mbr_part_info {
  743. unsigned int start_sector;
  744. unsigned int nr_sects;
  745. unsigned int part_no;
  746. unsigned char *part_name;
  747. } MBR_PART_INFO_T;
  748. #define MBR_PART_NUM 6
  749. #define __MMC_ERASE_ARG 0x00000000
  750. #define __MMC_TRIM_ARG 0x00000001
  751. #define __MMC_DISCARD_ARG 0x00000003
  752. struct __mmc_blk_data {
  753. spinlock_t lock;
  754. struct gendisk *disk;
  755. struct mmc_queue queue;
  756. unsigned int usage;
  757. unsigned int read_only;
  758. };
  759. #ifdef CONFIG_MTK_EMMC_SUPPORT
  760. static int simple_mmc_get_disk_info(struct mbr_part_info *mpi, unsigned char *name)
  761. {
  762. struct disk_part_iter piter;
  763. struct hd_struct *part;
  764. struct msdc_host *host;
  765. struct gendisk *disk;
  766. struct __mmc_blk_data *md;
  767. /* emmc always in slot0 */
  768. host = msdc_get_host(MSDC_EMMC, MSDC_BOOT_EN, 0);
  769. if (IS_ERR_OR_NULL(host))
  770. return -EINVAL;
  771. if (IS_ERR_OR_NULL(host->mmc))
  772. return -EINVAL;
  773. if (IS_ERR_OR_NULL(host->mmc->card))
  774. return -EINVAL;
  775. md = mmc_get_drvdata(host->mmc->card);
  776. BUG_ON(!md);
  777. BUG_ON(!md->disk);
  778. disk = md->disk;
  779. /* use this way to find partition info is to avoid handle addr transfer in scatter file
  780. * and 64bit address calculate */
  781. disk_part_iter_init(&piter, disk, 0);
  782. while ((part = disk_part_iter_next(&piter))) {
  783. #if DEBUG_MMC_IOCTL
  784. pr_debug("part_name = %s name = %s\n", part->info->volname, name);
  785. #endif
  786. if (!strncmp(part->info->volname, name, PARTITION_NAME_LENGTH)) {
  787. mpi->start_sector = part->start_sect;
  788. mpi->nr_sects = part->nr_sects;
  789. mpi->part_no = part->partno;
  790. mpi->part_name = part->info->volname;
  791. disk_part_iter_exit(&piter);
  792. return 0;
  793. }
  794. }
  795. disk_part_iter_exit(&piter);
  796. return 1;
  797. }
  798. /* call mmc block layer interface for userspace to do erase operate */
  799. static int simple_mmc_erase_func(unsigned int start, unsigned int size)
  800. {
  801. struct msdc_host *host;
  802. unsigned int arg, ret = 0;
  803. /* emmc always in slot0 */
  804. host = msdc_get_host(MSDC_EMMC, MSDC_BOOT_EN, 0);
  805. if (IS_ERR_OR_NULL(host))
  806. return -EINVAL;
  807. if (IS_ERR_OR_NULL(host->mmc))
  808. return -EINVAL;
  809. if (IS_ERR_OR_NULL(host->mmc->card))
  810. return -EINVAL;
  811. if (mmc_can_discard(host->mmc->card)) {
  812. arg = __MMC_DISCARD_ARG;
  813. } else if (mmc_can_trim(host->mmc->card)) {
  814. arg = __MMC_TRIM_ARG;
  815. } else if (mmc_can_erase(host->mmc->card)) {
  816. /* mmc_erase() will remove the erase group un-aligned part,
  817. * msdc_command_start() will do trim for old combo erase un-aligned issue
  818. */
  819. arg = __MMC_ERASE_ARG;
  820. } else {
  821. pr_err("[%s]: emmc card can't support trim / discard / erase\n", __func__);
  822. goto out;
  823. }
  824. pr_debug
  825. ("[%s]: start=0x%x, size=%d, arg=0x%x, can_trim=(0x%x),EXT_CSD_SEC_GB_CL_EN=0x%lx\n",
  826. __func__, start, size, arg, host->mmc->card->ext_csd.sec_feature_support,
  827. EXT_CSD_SEC_GB_CL_EN);
  828. mmc_claim_host(host->mmc);
  829. ret = mmc_erase(host->mmc->card, start, size, arg);
  830. mmc_release_host(host->mmc);
  831. #if DEBUG_MMC_IOCTL
  832. pr_debug("[%s]: erase done....arg=0x%x\n", __func__, arg);
  833. #endif
  834. return ret;
  835. out:
  836. return -EINVAL;
  837. }
  838. #endif
  839. static int simple_mmc_erase_partition(unsigned char *name)
  840. {
  841. #ifdef CONFIG_MTK_EMMC_SUPPORT
  842. struct mbr_part_info mbr_part;
  843. int l_ret = -1;
  844. if (!name)
  845. return -EINVAL;
  846. /* just support erase cache & data partition now */
  847. if (('u' == *name && 's' == *(name + 1) && 'r' == *(name + 2) && 'd' == *(name + 3) &&
  848. 'a' == *(name + 4) && 't' == *(name + 5) && 'a' == *(name + 6)) ||
  849. ('c' == *name && 'a' == *(name + 1) && 'c' == *(name + 2) && 'h' == *(name + 3)
  850. && 'e' == *(name + 4))) {
  851. /* find erase start address and erase size, just support high capacity emmc card now */
  852. l_ret = simple_mmc_get_disk_info(&mbr_part, name);
  853. if (l_ret == 0) {
  854. /* do erase */
  855. pr_debug("erase %s start sector: 0x%x size: 0x%x\n", mbr_part.part_name,
  856. mbr_part.start_sector, mbr_part.nr_sects);
  857. simple_mmc_erase_func(mbr_part.start_sector, mbr_part.nr_sects);
  858. }
  859. }
  860. return 0;
  861. #else
  862. return 0;
  863. #endif
  864. }
  865. static int simple_mmc_erase_partition_wrap(struct msdc_ioctl *msdc_ctl)
  866. {
  867. unsigned char name[PARTITION_NAME_LENGTH];
  868. if (!msdc_ctl)
  869. return -EINVAL;
  870. if (msdc_ctl->total_size > PARTITION_NAME_LENGTH)
  871. return -EFAULT;
  872. if (copy_from_user(name, (unsigned char *)msdc_ctl->buffer, msdc_ctl->total_size))
  873. return -EFAULT;
  874. return simple_mmc_erase_partition(name);
  875. }
  876. static long simple_sd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
  877. {
  878. struct msdc_ioctl msdc_ctl;
  879. int ret;
  880. if ((struct msdc_ioctl *)arg == NULL) {
  881. switch (cmd) {
  882. case MSDC_REINIT_SDCARD:
  883. ret = sd_ioctl_reinit((struct msdc_ioctl *)arg);
  884. break;
  885. case MSDC_CD_PIN_EN_SDCARD:
  886. ret = sd_ioctl_cd_pin_en((struct msdc_ioctl *)arg);
  887. break;
  888. default:
  889. pr_err("mt_sd_ioctl:this opcode value is illegal!!\n");
  890. return -EINVAL;
  891. }
  892. } else {
  893. if (copy_from_user(&msdc_ctl, (struct msdc_ioctl *)arg, sizeof(struct msdc_ioctl)))
  894. return -EFAULT;
  895. if (msdc_ctl.host_num >= HOST_MAX_NUM || msdc_ctl.host_num < 0) {
  896. pr_err("msdc:host id=%d is not available.\n", msdc_ctl.host_num);
  897. return -EINVAL;
  898. }
  899. switch (msdc_ctl.opcode) {
  900. case MSDC_SINGLE_READ_WRITE:
  901. msdc_ctl.result = simple_sd_ioctl_single_rw(&msdc_ctl);
  902. break;
  903. case MSDC_MULTIPLE_READ_WRITE:
  904. msdc_ctl.result = simple_sd_ioctl_multi_rw(&msdc_ctl);
  905. break;
  906. case MSDC_GET_CID:
  907. msdc_ctl.result = simple_sd_ioctl_get_cid(&msdc_ctl);
  908. break;
  909. case MSDC_GET_CSD:
  910. msdc_ctl.result = simple_sd_ioctl_get_csd(&msdc_ctl);
  911. break;
  912. case MSDC_GET_EXCSD:
  913. msdc_ctl.result = simple_sd_ioctl_get_excsd(&msdc_ctl);
  914. break;
  915. case MSDC_DRIVING_SETTING:
  916. pr_debug("in ioctl to change driving\n");
  917. if (msdc_ctl.iswrite)
  918. msdc_ctl.result = simple_sd_ioctl_set_driving(&msdc_ctl);
  919. else
  920. msdc_ctl.result = simple_sd_ioctl_get_driving(&msdc_ctl);
  921. break;
  922. case MSDC_ERASE_PARTITION:
  923. msdc_ctl.result = simple_mmc_erase_partition_wrap(&msdc_ctl);
  924. break;
  925. case MSDC_SD30_MODE_SWITCH:
  926. msdc_ctl.result = simple_sd_ioctl_sd30_mode_switch(&msdc_ctl);
  927. break;
  928. default:
  929. pr_err("simple_sd_ioctl:this opcode value is illegal!!\n");
  930. return -EINVAL;
  931. }
  932. if (copy_to_user((struct msdc_ioctl *)arg, &msdc_ctl, sizeof(struct msdc_ioctl)))
  933. return -EFAULT;
  934. return msdc_ctl.result;
  935. }
  936. return 0;
  937. }
  938. static const struct file_operations simple_msdc_em_fops = {
  939. .owner = THIS_MODULE,
  940. .unlocked_ioctl = simple_sd_ioctl,
  941. .open = simple_sd_open,
  942. };
  943. static struct miscdevice simple_msdc_em_dev[] = {
  944. {
  945. .minor = MISC_DYNAMIC_MINOR,
  946. .name = "misc-sd",
  947. .fops = &simple_msdc_em_fops,
  948. }
  949. };
  950. static int simple_sd_probe(struct platform_device *pdev)
  951. {
  952. int ret = 0;
  953. pr_debug("in misc_sd_probe function\n");
  954. return ret;
  955. }
  956. static int simple_sd_remove(struct platform_device *pdev)
  957. {
  958. return 0;
  959. }
  960. static struct platform_driver simple_sd_driver = {
  961. .probe = simple_sd_probe,
  962. .remove = simple_sd_remove,
  963. .driver = {
  964. .name = DRV_NAME_MISC,
  965. .owner = THIS_MODULE,
  966. },
  967. };
  968. static int __init simple_sd_init(void)
  969. {
  970. int ret;
  971. sg_msdc_multi_buffer = kmalloc(64 * 1024, GFP_KERNEL);
  972. if (sg_msdc_multi_buffer == NULL)
  973. return 0;
  974. ret = platform_driver_register(&simple_sd_driver);
  975. if (ret) {
  976. pr_err(DRV_NAME_MISC ": Can't register driver\n");
  977. return ret;
  978. }
  979. pr_debug(DRV_NAME_MISC ": MediaTek simple SD/MMC Card Driver\n");
  980. /*msdc0 is for emmc only, just for emmc */
  981. /* ret = misc_register(&simple_msdc_em_dev[host->id]); */
  982. ret = misc_register(&simple_msdc_em_dev[0]);
  983. if (ret) {
  984. pr_err("register MSDC Slot[0] misc driver failed (%d)\n", ret);
  985. return ret;
  986. }
  987. return 0;
  988. }
  989. static void __exit simple_sd_exit(void)
  990. {
  991. if (sg_msdc_multi_buffer != NULL) {
  992. kfree(sg_msdc_multi_buffer);
  993. sg_msdc_multi_buffer = NULL;
  994. }
  995. misc_deregister(&simple_msdc_em_dev[0]);
  996. platform_driver_unregister(&simple_sd_driver);
  997. }
  998. module_init(simple_sd_init);
  999. module_exit(simple_sd_exit);
  1000. MODULE_LICENSE("GPL");
  1001. MODULE_DESCRIPTION("simple MediaTek SD/MMC Card Driver");
  1002. MODULE_AUTHOR("feifei.wang <feifei.wang@mediatek.com>");