coresight-stm.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930
  1. /* Copyright (c) 2012-2013, 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/kernel.h>
  13. #include <linux/module.h>
  14. #include <linux/init.h>
  15. #include <linux/types.h>
  16. #include <linux/device.h>
  17. #include <linux/platform_device.h>
  18. #include <linux/io.h>
  19. #include <linux/err.h>
  20. #include <linux/fs.h>
  21. #include <linux/miscdevice.h>
  22. #include <linux/uaccess.h>
  23. #include <linux/slab.h>
  24. #include <linux/delay.h>
  25. #include <linux/clk.h>
  26. #include <linux/bitmap.h>
  27. #include <linux/of.h>
  28. #include <linux/of_coresight.h>
  29. #include <linux/coresight.h>
  30. #include <linux/coresight-stm.h>
  31. #include <asm/unaligned.h>
  32. #include "coresight-priv.h"
  33. #define stm_writel(drvdata, val, off) __raw_writel((val), drvdata->base + off)
  34. #define stm_readl(drvdata, off) __raw_readl(drvdata->base + off)
  35. #define stm_data_writeb(val, addr) __raw_writeb_no_log(val, addr)
  36. #define stm_data_writew(val, addr) __raw_writew_no_log(val, addr)
  37. #define stm_data_writel(val, addr) __raw_writel_no_log(val, addr)
  38. #define STM_LOCK(drvdata) \
  39. do { \
  40. mb(); \
  41. stm_writel(drvdata, 0x0, CORESIGHT_LAR); \
  42. } while (0)
  43. #define STM_UNLOCK(drvdata) \
  44. do { \
  45. stm_writel(drvdata, CORESIGHT_UNLOCK, CORESIGHT_LAR); \
  46. mb(); \
  47. } while (0)
  48. #define STMDMASTARTR (0xC04)
  49. #define STMDMASTOPR (0xC08)
  50. #define STMDMASTATR (0xC0C)
  51. #define STMDMACTLR (0xC10)
  52. #define STMDMAIDR (0xCFC)
  53. #define STMHEER (0xD00)
  54. #define STMHETER (0xD20)
  55. #define STMHEMCR (0xD64)
  56. #define STMHEMASTR (0xDF4)
  57. #define STMHEFEAT1R (0xDF8)
  58. #define STMHEIDR (0xDFC)
  59. #define STMSPER (0xE00)
  60. #define STMSPTER (0xE20)
  61. #define STMSPSCR (0xE60)
  62. #define STMSPMSCR (0xE64)
  63. #define STMSPOVERRIDER (0xE68)
  64. #define STMSPMOVERRIDER (0xE6C)
  65. #define STMSPTRIGCSR (0xE70)
  66. #define STMTCSR (0xE80)
  67. #define STMTSSTIMR (0xE84)
  68. #define STMTSFREQR (0xE8C)
  69. #define STMSYNCR (0xE90)
  70. #define STMAUXCR (0xE94)
  71. #define STMSPFEAT1R (0xEA0)
  72. #define STMSPFEAT2R (0xEA4)
  73. #define STMSPFEAT3R (0xEA8)
  74. #define STMITTRIGGER (0xEE8)
  75. #define STMITATBDATA0 (0xEEC)
  76. #define STMITATBCTR2 (0xEF0)
  77. #define STMITATBID (0xEF4)
  78. #define STMITATBCTR0 (0xEF8)
  79. #define NR_STM_CHANNEL (32)
  80. #define BYTES_PER_CHANNEL (256)
  81. #define STM_TRACE_BUF_SIZE (4096)
  82. #define STM_USERSPACE_HEADER_SIZE (8)
  83. #define STM_USERSPACE_MAGIC1_VAL (0xf0)
  84. #define STM_USERSPACE_MAGIC2_VAL (0xf1)
  85. #define OST_TOKEN_STARTSIMPLE (0x10)
  86. #define OST_TOKEN_STARTBASE (0x30)
  87. #define OST_VERSION_PROP (1)
  88. #define OST_VERSION_MIPI1 (16)
  89. enum stm_pkt_type {
  90. STM_PKT_TYPE_DATA = 0x98,
  91. STM_PKT_TYPE_FLAG = 0xE8,
  92. STM_PKT_TYPE_TRIG = 0xF8,
  93. };
  94. enum {
  95. STM_OPTION_MARKED = 0x10,
  96. };
  97. #define stm_channel_addr(drvdata, ch) (drvdata->chs.base + \
  98. (ch * BYTES_PER_CHANNEL))
  99. #define stm_channel_off(type, opts) (type & ~opts)
  100. #ifdef CONFIG_CORESIGHT_STM_DEFAULT_ENABLE
  101. static int boot_enable = 1;
  102. #else
  103. static int boot_enable;
  104. #endif
  105. module_param_named(
  106. boot_enable, boot_enable, int, S_IRUGO
  107. );
  108. static int boot_nr_channel;
  109. module_param_named(
  110. boot_nr_channel, boot_nr_channel, int, S_IRUGO
  111. );
  112. struct channel_space {
  113. void __iomem *base;
  114. unsigned long *bitmap;
  115. };
  116. struct stm_drvdata {
  117. void __iomem *base;
  118. struct device *dev;
  119. struct coresight_device *csdev;
  120. struct miscdevice miscdev;
  121. struct clk *clk;
  122. spinlock_t spinlock;
  123. struct channel_space chs;
  124. bool enable;
  125. DECLARE_BITMAP(entities, OST_ENTITY_MAX);
  126. bool write_64bit;
  127. };
  128. static struct stm_drvdata *stmdrvdata;
  129. static int stm_hwevent_isenable(struct stm_drvdata *drvdata)
  130. {
  131. int ret = 0;
  132. spin_lock(&drvdata->spinlock);
  133. if (drvdata->enable)
  134. if (BVAL(stm_readl(drvdata, STMHEMCR), 0))
  135. ret = stm_readl(drvdata, STMHEER) == 0 ? 0 : 1;
  136. spin_unlock(&drvdata->spinlock);
  137. return ret;
  138. }
  139. static void __stm_hwevent_enable(struct stm_drvdata *drvdata)
  140. {
  141. STM_UNLOCK(drvdata);
  142. /* Program STMHETER to ensure TRIGOUTHETE (fed to CTI) is asserted
  143. for HW events.
  144. */
  145. stm_writel(drvdata, 0xFFFFFFFF, STMHETER);
  146. stm_writel(drvdata, 0xFFFFFFFF, STMHEER);
  147. stm_writel(drvdata, 0x5, STMHEMCR);
  148. STM_LOCK(drvdata);
  149. }
  150. static int stm_hwevent_enable(struct stm_drvdata *drvdata)
  151. {
  152. int ret = 0;
  153. spin_lock(&drvdata->spinlock);
  154. if (drvdata->enable)
  155. __stm_hwevent_enable(drvdata);
  156. else
  157. ret = -EINVAL;
  158. spin_unlock(&drvdata->spinlock);
  159. return ret;
  160. }
  161. static int stm_port_isenable(struct stm_drvdata *drvdata)
  162. {
  163. int ret = 0;
  164. spin_lock(&drvdata->spinlock);
  165. if (drvdata->enable)
  166. ret = stm_readl(drvdata, STMSPER) == 0 ? 0 : 1;
  167. spin_unlock(&drvdata->spinlock);
  168. return ret;
  169. }
  170. static void __stm_port_enable(struct stm_drvdata *drvdata)
  171. {
  172. STM_UNLOCK(drvdata);
  173. stm_writel(drvdata, 0x10, STMSPTRIGCSR);
  174. stm_writel(drvdata, 0xFFFFFFFF, STMSPER);
  175. STM_LOCK(drvdata);
  176. }
  177. static int stm_port_enable(struct stm_drvdata *drvdata)
  178. {
  179. int ret = 0;
  180. spin_lock(&drvdata->spinlock);
  181. if (drvdata->enable)
  182. __stm_port_enable(drvdata);
  183. else
  184. ret = -EINVAL;
  185. spin_unlock(&drvdata->spinlock);
  186. return ret;
  187. }
  188. static void __stm_enable(struct stm_drvdata *drvdata)
  189. {
  190. __stm_hwevent_enable(drvdata);
  191. __stm_port_enable(drvdata);
  192. STM_UNLOCK(drvdata);
  193. stm_writel(drvdata, 0xFFF, STMSYNCR);
  194. /* SYNCEN is read-only and HWTEN is not implemented */
  195. stm_writel(drvdata, 0x100003, STMTCSR);
  196. STM_LOCK(drvdata);
  197. }
  198. static int stm_enable(struct coresight_device *csdev)
  199. {
  200. struct stm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
  201. int ret;
  202. ret = clk_prepare_enable(drvdata->clk);
  203. if (ret)
  204. return ret;
  205. spin_lock(&drvdata->spinlock);
  206. __stm_enable(drvdata);
  207. drvdata->enable = true;
  208. spin_unlock(&drvdata->spinlock);
  209. dev_info(drvdata->dev, "STM tracing enabled\n");
  210. return 0;
  211. }
  212. static void __stm_hwevent_disable(struct stm_drvdata *drvdata)
  213. {
  214. STM_UNLOCK(drvdata);
  215. stm_writel(drvdata, 0x0, STMHEMCR);
  216. stm_writel(drvdata, 0x0, STMHEER);
  217. stm_writel(drvdata, 0x0, STMHETER);
  218. STM_LOCK(drvdata);
  219. }
  220. static void stm_hwevent_disable(struct stm_drvdata *drvdata)
  221. {
  222. spin_lock(&drvdata->spinlock);
  223. if (drvdata->enable)
  224. __stm_hwevent_disable(drvdata);
  225. spin_unlock(&drvdata->spinlock);
  226. }
  227. static void __stm_port_disable(struct stm_drvdata *drvdata)
  228. {
  229. STM_UNLOCK(drvdata);
  230. stm_writel(drvdata, 0x0, STMSPER);
  231. stm_writel(drvdata, 0x0, STMSPTRIGCSR);
  232. STM_LOCK(drvdata);
  233. }
  234. static void stm_port_disable(struct stm_drvdata *drvdata)
  235. {
  236. spin_lock(&drvdata->spinlock);
  237. if (drvdata->enable)
  238. __stm_port_disable(drvdata);
  239. spin_unlock(&drvdata->spinlock);
  240. }
  241. static void __stm_disable(struct stm_drvdata *drvdata)
  242. {
  243. STM_UNLOCK(drvdata);
  244. stm_writel(drvdata, 0x100000, STMTCSR);
  245. STM_LOCK(drvdata);
  246. __stm_hwevent_disable(drvdata);
  247. __stm_port_disable(drvdata);
  248. }
  249. static void stm_disable(struct coresight_device *csdev)
  250. {
  251. struct stm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
  252. spin_lock(&drvdata->spinlock);
  253. __stm_disable(drvdata);
  254. drvdata->enable = false;
  255. spin_unlock(&drvdata->spinlock);
  256. /* Wait for 100ms so that pending data has been written to HW */
  257. msleep(100);
  258. clk_disable_unprepare(drvdata->clk);
  259. dev_info(drvdata->dev, "STM tracing disabled\n");
  260. }
  261. static const struct coresight_ops_source stm_source_ops = {
  262. .enable = stm_enable,
  263. .disable = stm_disable,
  264. };
  265. static const struct coresight_ops stm_cs_ops = {
  266. .source_ops = &stm_source_ops,
  267. };
  268. static uint32_t stm_channel_alloc(uint32_t off)
  269. {
  270. struct stm_drvdata *drvdata = stmdrvdata;
  271. uint32_t ch;
  272. do {
  273. ch = find_next_zero_bit(drvdata->chs.bitmap,
  274. NR_STM_CHANNEL, off);
  275. } while ((ch < NR_STM_CHANNEL) &&
  276. test_and_set_bit(ch, drvdata->chs.bitmap));
  277. return ch;
  278. }
  279. static void stm_channel_free(uint32_t ch)
  280. {
  281. struct stm_drvdata *drvdata = stmdrvdata;
  282. clear_bit(ch, drvdata->chs.bitmap);
  283. }
  284. static int stm_send_64bit(void *addr, const void *data, uint32_t size)
  285. {
  286. uint64_t prepad = 0;
  287. uint64_t postpad = 0;
  288. char *pad;
  289. uint8_t off, endoff;
  290. uint32_t len = size;
  291. /* only 64bit writes are supported, we rely on the compiler to
  292. * generate STRD instruction for the casted 64bit assignments
  293. */
  294. off = (unsigned long)data & 0x7;
  295. if (off) {
  296. endoff = 8 - off;
  297. pad = (char *)&prepad;
  298. pad += off;
  299. while (endoff && size) {
  300. *pad++ = *(char *)data++;
  301. endoff--;
  302. size--;
  303. }
  304. *(volatile uint64_t __force *)addr = prepad;
  305. }
  306. /* now we are 64bit aligned */
  307. while (size >= 8) {
  308. *(volatile uint64_t __force *)addr = *(uint64_t *)data;
  309. data += 8;
  310. size -= 8;
  311. }
  312. endoff = 0;
  313. if (size) {
  314. endoff = 8 - (uint8_t)size;
  315. pad = (char *)&postpad;
  316. while (size) {
  317. *pad++ = *(char *)data++;
  318. size--;
  319. }
  320. *(volatile uint64_t __force *)addr = postpad;
  321. }
  322. return len + off + endoff;
  323. }
  324. static int stm_trace_ost_header_64bit(unsigned long ch_addr, uint32_t options,
  325. uint8_t entity_id, uint8_t proto_id,
  326. const void *payload_data,
  327. uint32_t payload_size)
  328. {
  329. void *addr;
  330. uint8_t prepad_size;
  331. uint64_t header;
  332. char *hdr;
  333. hdr = (char *)&header;
  334. hdr[0] = OST_TOKEN_STARTBASE;
  335. hdr[1] = OST_VERSION_PROP;
  336. hdr[2] = entity_id;
  337. hdr[3] = proto_id;
  338. prepad_size = (unsigned long)payload_data & 0x7;
  339. *(uint32_t *)(hdr + 4) = (prepad_size << 24) | payload_size;
  340. /* for 64bit writes, header is expected to be D32M, D32M type */
  341. options |= STM_OPTION_MARKED;
  342. options &= ~STM_OPTION_TIMESTAMPED;
  343. addr = (void *)(ch_addr | stm_channel_off(STM_PKT_TYPE_DATA, options));
  344. return stm_send_64bit(addr, &header, sizeof(header));
  345. }
  346. static int stm_trace_data_64bit(unsigned long ch_addr, uint32_t options,
  347. const void *data, uint32_t size)
  348. {
  349. void *addr;
  350. options &= ~STM_OPTION_TIMESTAMPED;
  351. addr = (void *)(ch_addr | stm_channel_off(STM_PKT_TYPE_DATA, options));
  352. return stm_send_64bit(addr, data, size);
  353. }
  354. static int stm_trace_ost_tail_64bit(unsigned long ch_addr, uint32_t options)
  355. {
  356. void *addr;
  357. uint64_t tail = 0x0;
  358. addr = (void *)(ch_addr | stm_channel_off(STM_PKT_TYPE_FLAG, options));
  359. return stm_send_64bit(addr, &tail, sizeof(tail));
  360. }
  361. static int stm_send(void *addr, const void *data, uint32_t size)
  362. {
  363. uint32_t len = size;
  364. if (((unsigned long)data & 0x1) && (size >= 1)) {
  365. stm_data_writeb(*(uint8_t *)data, addr);
  366. data++;
  367. size--;
  368. }
  369. if (((unsigned long)data & 0x2) && (size >= 2)) {
  370. stm_data_writew(*(uint16_t *)data, addr);
  371. data += 2;
  372. size -= 2;
  373. }
  374. /* now we are 32bit aligned */
  375. while (size >= 4) {
  376. stm_data_writel(*(uint32_t *)data, addr);
  377. data += 4;
  378. size -= 4;
  379. }
  380. if (size >= 2) {
  381. stm_data_writew(*(uint16_t *)data, addr);
  382. data += 2;
  383. size -= 2;
  384. }
  385. if (size >= 1) {
  386. stm_data_writeb(*(uint8_t *)data, addr);
  387. data++;
  388. size--;
  389. }
  390. return len;
  391. }
  392. static int stm_trace_ost_header(unsigned long ch_addr, uint32_t options,
  393. uint8_t entity_id, uint8_t proto_id,
  394. const void *payload_data, uint32_t payload_size)
  395. {
  396. void *addr;
  397. uint32_t header;
  398. char *hdr;
  399. hdr = (char *)&header;
  400. hdr[0] = OST_TOKEN_STARTSIMPLE;
  401. hdr[1] = OST_VERSION_MIPI1;
  402. hdr[2] = entity_id;
  403. hdr[3] = proto_id;
  404. /* header is expected to be D32M type */
  405. options |= STM_OPTION_MARKED;
  406. options &= ~STM_OPTION_TIMESTAMPED;
  407. addr = (void *)(ch_addr | stm_channel_off(STM_PKT_TYPE_DATA, options));
  408. return stm_send(addr, &header, sizeof(header));
  409. }
  410. static int stm_trace_data(unsigned long ch_addr, uint32_t options,
  411. const void *data, uint32_t size)
  412. {
  413. void *addr;
  414. options &= ~STM_OPTION_TIMESTAMPED;
  415. addr = (void *)(ch_addr | stm_channel_off(STM_PKT_TYPE_DATA, options));
  416. return stm_send(addr, data, size);
  417. }
  418. static int stm_trace_ost_tail(unsigned long ch_addr, uint32_t options)
  419. {
  420. void *addr;
  421. uint32_t tail = 0x0;
  422. addr = (void *)(ch_addr | stm_channel_off(STM_PKT_TYPE_FLAG, options));
  423. return stm_send(addr, &tail, sizeof(tail));
  424. }
  425. static inline int __stm_trace(uint32_t options, uint8_t entity_id,
  426. uint8_t proto_id, const void *data, uint32_t size)
  427. {
  428. struct stm_drvdata *drvdata = stmdrvdata;
  429. int len = 0;
  430. uint32_t ch;
  431. unsigned long ch_addr;
  432. /* allocate channel and get the channel address */
  433. ch = stm_channel_alloc(0);
  434. ch_addr = (unsigned long)stm_channel_addr(drvdata, ch);
  435. if (drvdata->write_64bit) {
  436. /* send the ost header */
  437. len += stm_trace_ost_header_64bit(ch_addr, options, entity_id,
  438. proto_id, data, size);
  439. /* send the payload data */
  440. len += stm_trace_data_64bit(ch_addr, options, data, size);
  441. /* send the ost tail */
  442. len += stm_trace_ost_tail_64bit(ch_addr, options);
  443. } else {
  444. /* send the ost header */
  445. len += stm_trace_ost_header(ch_addr, options, entity_id,
  446. proto_id, data, size);
  447. /* send the payload data */
  448. len += stm_trace_data(ch_addr, options, data, size);
  449. /* send the ost tail */
  450. len += stm_trace_ost_tail(ch_addr, options);
  451. }
  452. /* we are done, free the channel */
  453. stm_channel_free(ch);
  454. return len;
  455. }
  456. /**
  457. * stm_trace - trace the binary or string data through STM
  458. * @options: tracing options - guaranteed, timestamped, etc
  459. * @entity_id: entity representing the trace data
  460. * @proto_id: protocol id to distinguish between different binary formats
  461. * @data: pointer to binary or string data buffer
  462. * @size: size of data to send
  463. *
  464. * Packetizes the data as the payload to an OST packet and sends it over STM
  465. *
  466. * CONTEXT:
  467. * Can be called from any context.
  468. *
  469. * RETURNS:
  470. * number of bytes transfered over STM
  471. */
  472. int stm_trace(uint32_t options, uint8_t entity_id, uint8_t proto_id,
  473. const void *data, uint32_t size)
  474. {
  475. struct stm_drvdata *drvdata = stmdrvdata;
  476. /* we don't support sizes more than 24bits (0 to 23) */
  477. if (!(drvdata && drvdata->enable &&
  478. test_bit(entity_id, drvdata->entities) && size &&
  479. (size < 0x1000000)))
  480. return 0;
  481. return __stm_trace(options, entity_id, proto_id, data, size);
  482. }
  483. EXPORT_SYMBOL(stm_trace);
  484. static ssize_t stm_write(struct file *file, const char __user *data,
  485. size_t size, loff_t *ppos)
  486. {
  487. struct stm_drvdata *drvdata = container_of(file->private_data,
  488. struct stm_drvdata, miscdev);
  489. char *buf;
  490. uint8_t entity_id, proto_id;
  491. uint32_t options;
  492. if (!drvdata->enable || !size)
  493. return -EINVAL;
  494. if (size > STM_TRACE_BUF_SIZE)
  495. size = STM_TRACE_BUF_SIZE;
  496. buf = kmalloc(size, GFP_KERNEL);
  497. if (!buf)
  498. return -ENOMEM;
  499. if (copy_from_user(buf, data, size)) {
  500. kfree(buf);
  501. dev_dbg(drvdata->dev, "%s: copy_from_user failed\n", __func__);
  502. return -EFAULT;
  503. }
  504. if (size >= STM_USERSPACE_HEADER_SIZE &&
  505. buf[0] == STM_USERSPACE_MAGIC1_VAL &&
  506. buf[1] == STM_USERSPACE_MAGIC2_VAL) {
  507. entity_id = buf[2];
  508. proto_id = buf[3];
  509. options = *(uint32_t *)(buf + 4);
  510. if (!test_bit(entity_id, drvdata->entities) ||
  511. !(size - STM_USERSPACE_HEADER_SIZE)) {
  512. kfree(buf);
  513. return size;
  514. }
  515. __stm_trace(options, entity_id, proto_id,
  516. buf + STM_USERSPACE_HEADER_SIZE,
  517. size - STM_USERSPACE_HEADER_SIZE);
  518. } else {
  519. if (!test_bit(OST_ENTITY_DEV_NODE, drvdata->entities)) {
  520. kfree(buf);
  521. return size;
  522. }
  523. __stm_trace(STM_OPTION_TIMESTAMPED, OST_ENTITY_DEV_NODE, 0,
  524. buf, size);
  525. }
  526. kfree(buf);
  527. return size;
  528. }
  529. static const struct file_operations stm_fops = {
  530. .owner = THIS_MODULE,
  531. .open = nonseekable_open,
  532. .write = stm_write,
  533. .llseek = no_llseek,
  534. };
  535. static ssize_t stm_show_hwevent_enable(struct device *dev,
  536. struct device_attribute *attr, char *buf)
  537. {
  538. struct stm_drvdata *drvdata = dev_get_drvdata(dev->parent);
  539. unsigned long val = stm_hwevent_isenable(drvdata);
  540. return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
  541. }
  542. static ssize_t stm_store_hwevent_enable(struct device *dev,
  543. struct device_attribute *attr,
  544. const char *buf, size_t size)
  545. {
  546. struct stm_drvdata *drvdata = dev_get_drvdata(dev->parent);
  547. unsigned long val;
  548. int ret = 0;
  549. if (sscanf(buf, "%lx", &val) != 1)
  550. return -EINVAL;
  551. if (val)
  552. ret = stm_hwevent_enable(drvdata);
  553. else
  554. stm_hwevent_disable(drvdata);
  555. if (ret)
  556. return ret;
  557. return size;
  558. }
  559. static DEVICE_ATTR(hwevent_enable, S_IRUGO | S_IWUSR, stm_show_hwevent_enable,
  560. stm_store_hwevent_enable);
  561. static ssize_t stm_show_port_enable(struct device *dev,
  562. struct device_attribute *attr, char *buf)
  563. {
  564. struct stm_drvdata *drvdata = dev_get_drvdata(dev->parent);
  565. unsigned long val = stm_port_isenable(drvdata);
  566. return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
  567. }
  568. static ssize_t stm_store_port_enable(struct device *dev,
  569. struct device_attribute *attr,
  570. const char *buf, size_t size)
  571. {
  572. struct stm_drvdata *drvdata = dev_get_drvdata(dev->parent);
  573. unsigned long val;
  574. int ret = 0;
  575. if (sscanf(buf, "%lx", &val) != 1)
  576. return -EINVAL;
  577. if (val)
  578. ret = stm_port_enable(drvdata);
  579. else
  580. stm_port_disable(drvdata);
  581. if (ret)
  582. return ret;
  583. return size;
  584. }
  585. static DEVICE_ATTR(port_enable, S_IRUGO | S_IWUSR, stm_show_port_enable,
  586. stm_store_port_enable);
  587. static ssize_t stm_show_entities(struct device *dev,
  588. struct device_attribute *attr, char *buf)
  589. {
  590. struct stm_drvdata *drvdata = dev_get_drvdata(dev->parent);
  591. ssize_t len;
  592. len = bitmap_scnprintf(buf, PAGE_SIZE, drvdata->entities,
  593. OST_ENTITY_MAX);
  594. if (PAGE_SIZE - len < 2)
  595. len = -EINVAL;
  596. else
  597. len += scnprintf(buf + len, 2, "\n");
  598. return len;
  599. }
  600. static ssize_t stm_store_entities(struct device *dev,
  601. struct device_attribute *attr,
  602. const char *buf, size_t size)
  603. {
  604. struct stm_drvdata *drvdata = dev_get_drvdata(dev->parent);
  605. unsigned long val1, val2;
  606. if (sscanf(buf, "%lx %lx", &val1, &val2) != 2)
  607. return -EINVAL;
  608. if (val1 >= OST_ENTITY_MAX)
  609. return -EINVAL;
  610. if (val2)
  611. __set_bit(val1, drvdata->entities);
  612. else
  613. __clear_bit(val1, drvdata->entities);
  614. return size;
  615. }
  616. static DEVICE_ATTR(entities, S_IRUGO | S_IWUSR, stm_show_entities,
  617. stm_store_entities);
  618. static struct attribute *stm_attrs[] = {
  619. &dev_attr_hwevent_enable.attr,
  620. &dev_attr_port_enable.attr,
  621. &dev_attr_entities.attr,
  622. NULL,
  623. };
  624. static struct attribute_group stm_attr_grp = {
  625. .attrs = stm_attrs,
  626. };
  627. static const struct attribute_group *stm_attr_grps[] = {
  628. &stm_attr_grp,
  629. NULL,
  630. };
  631. static int __devinit stm_probe(struct platform_device *pdev)
  632. {
  633. int ret;
  634. struct device *dev = &pdev->dev;
  635. struct coresight_platform_data *pdata;
  636. struct stm_drvdata *drvdata;
  637. struct resource *res;
  638. size_t res_size, bitmap_size;
  639. struct coresight_desc *desc;
  640. if (coresight_fuse_access_disabled())
  641. return -EPERM;
  642. if (pdev->dev.of_node) {
  643. pdata = of_get_coresight_platform_data(dev, pdev->dev.of_node);
  644. if (IS_ERR(pdata))
  645. return PTR_ERR(pdata);
  646. pdev->dev.platform_data = pdata;
  647. }
  648. drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
  649. if (!drvdata)
  650. return -ENOMEM;
  651. /* Store the driver data pointer for use in exported functions */
  652. stmdrvdata = drvdata;
  653. drvdata->dev = &pdev->dev;
  654. platform_set_drvdata(pdev, drvdata);
  655. res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "stm-base");
  656. if (!res)
  657. return -ENODEV;
  658. drvdata->base = devm_ioremap(dev, res->start, resource_size(res));
  659. if (!drvdata->base)
  660. return -ENOMEM;
  661. res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
  662. "stm-data-base");
  663. if (!res)
  664. return -ENODEV;
  665. if (boot_nr_channel) {
  666. res_size = min((resource_size_t)(boot_nr_channel *
  667. BYTES_PER_CHANNEL), resource_size(res));
  668. bitmap_size = boot_nr_channel * sizeof(long);
  669. } else {
  670. res_size = min((resource_size_t)(NR_STM_CHANNEL *
  671. BYTES_PER_CHANNEL), resource_size(res));
  672. bitmap_size = NR_STM_CHANNEL * sizeof(long);
  673. }
  674. drvdata->chs.base = devm_ioremap(dev, res->start, res_size);
  675. if (!drvdata->chs.base)
  676. return -ENOMEM;
  677. drvdata->chs.bitmap = devm_kzalloc(dev, bitmap_size, GFP_KERNEL);
  678. if (!drvdata->chs.bitmap)
  679. return -ENOMEM;
  680. spin_lock_init(&drvdata->spinlock);
  681. drvdata->clk = devm_clk_get(dev, "core_clk");
  682. if (IS_ERR(drvdata->clk))
  683. return PTR_ERR(drvdata->clk);
  684. ret = clk_set_rate(drvdata->clk, CORESIGHT_CLK_RATE_TRACE);
  685. if (ret)
  686. return ret;
  687. bitmap_fill(drvdata->entities, OST_ENTITY_MAX);
  688. if (pdev->dev.of_node)
  689. drvdata->write_64bit = of_property_read_bool(pdev->dev.of_node,
  690. "qcom,write-64bit");
  691. desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
  692. if (!desc)
  693. return -ENOMEM;
  694. desc->type = CORESIGHT_DEV_TYPE_SOURCE;
  695. desc->subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE;
  696. desc->ops = &stm_cs_ops;
  697. desc->pdata = pdev->dev.platform_data;
  698. desc->dev = &pdev->dev;
  699. desc->groups = stm_attr_grps;
  700. desc->owner = THIS_MODULE;
  701. drvdata->csdev = coresight_register(desc);
  702. if (IS_ERR(drvdata->csdev))
  703. return PTR_ERR(drvdata->csdev);
  704. drvdata->miscdev.name = ((struct coresight_platform_data *)
  705. (pdev->dev.platform_data))->name;
  706. drvdata->miscdev.minor = MISC_DYNAMIC_MINOR;
  707. drvdata->miscdev.fops = &stm_fops;
  708. ret = misc_register(&drvdata->miscdev);
  709. if (ret)
  710. goto err;
  711. dev_info(drvdata->dev, "STM initialized\n");
  712. if (boot_enable)
  713. coresight_enable(drvdata->csdev);
  714. return 0;
  715. err:
  716. coresight_unregister(drvdata->csdev);
  717. return ret;
  718. }
  719. static int __devexit stm_remove(struct platform_device *pdev)
  720. {
  721. struct stm_drvdata *drvdata = platform_get_drvdata(pdev);
  722. misc_deregister(&drvdata->miscdev);
  723. coresight_unregister(drvdata->csdev);
  724. return 0;
  725. }
  726. static struct of_device_id stm_match[] = {
  727. {.compatible = "arm,coresight-stm"},
  728. {}
  729. };
  730. static struct platform_driver stm_driver = {
  731. .probe = stm_probe,
  732. .remove = __devexit_p(stm_remove),
  733. .driver = {
  734. .name = "coresight-stm",
  735. .owner = THIS_MODULE,
  736. .of_match_table = stm_match,
  737. },
  738. };
  739. static int __init stm_init(void)
  740. {
  741. return platform_driver_register(&stm_driver);
  742. }
  743. module_init(stm_init);
  744. static void __exit stm_exit(void)
  745. {
  746. platform_driver_unregister(&stm_driver);
  747. }
  748. module_exit(stm_exit);
  749. MODULE_LICENSE("GPL v2");
  750. MODULE_DESCRIPTION("CoreSight System Trace Macrocell driver");