diff options
author | Suzuki K Poulose <suzuki.poulose@arm.com> | 2018-07-11 15:40:34 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-07-15 07:52:59 -0400 |
commit | 434d611cddef1ceed32bf416a363992b01a3ff9a (patch) | |
tree | a3257f7cec20386097ca1e79fded50777ea55d76 /drivers | |
parent | 8ed536b1e2838dad4f495347f0917b1cb6e3604f (diff) |
coresight: catu: Plug in CATU as a backend for ETR buffer
Now that we can use a CATU with a scatter gather table, add support
for the TMC ETR to make use of the connected CATU in translate mode.
This is done by adding CATU as new buffer mode.
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/hwtracing/coresight/coresight-catu.c | 122 | ||||
-rw-r--r-- | drivers/hwtracing/coresight/coresight-catu.h | 35 | ||||
-rw-r--r-- | drivers/hwtracing/coresight/coresight-tmc-etr.c | 25 | ||||
-rw-r--r-- | drivers/hwtracing/coresight/coresight-tmc.h | 3 |
4 files changed, 174 insertions, 11 deletions
diff --git a/drivers/hwtracing/coresight/coresight-catu.c b/drivers/hwtracing/coresight/coresight-catu.c index 559d45b6bc39..ff94e58845b7 100644 --- a/drivers/hwtracing/coresight/coresight-catu.c +++ b/drivers/hwtracing/coresight/coresight-catu.c | |||
@@ -28,6 +28,11 @@ | |||
28 | #define catu_dbg(x, ...) do {} while (0) | 28 | #define catu_dbg(x, ...) do {} while (0) |
29 | #endif | 29 | #endif |
30 | 30 | ||
31 | struct catu_etr_buf { | ||
32 | struct tmc_sg_table *catu_table; | ||
33 | dma_addr_t sladdr; | ||
34 | }; | ||
35 | |||
31 | /* | 36 | /* |
32 | * CATU uses a page size of 4KB for page tables as well as data pages. | 37 | * CATU uses a page size of 4KB for page tables as well as data pages. |
33 | * Each 64bit entry in the table has the following format. | 38 | * Each 64bit entry in the table has the following format. |
@@ -93,6 +98,9 @@ typedef u64 cate_t; | |||
93 | (((cate_t)(addr) & CATU_ADDR_MASK) | CATU_ENTRY_VALID) | 98 | (((cate_t)(addr) & CATU_ADDR_MASK) | CATU_ENTRY_VALID) |
94 | #define CATU_ENTRY_ADDR(entry) ((cate_t)(entry) & ~((cate_t)CATU_ENTRY_VALID)) | 99 | #define CATU_ENTRY_ADDR(entry) ((cate_t)(entry) & ~((cate_t)CATU_ENTRY_VALID)) |
95 | 100 | ||
101 | /* CATU expects the INADDR to be aligned to 1M. */ | ||
102 | #define CATU_DEFAULT_INADDR (1ULL << 20) | ||
103 | |||
96 | /* | 104 | /* |
97 | * catu_get_table : Retrieve the table pointers for the given @offset | 105 | * catu_get_table : Retrieve the table pointers for the given @offset |
98 | * within the buffer. The buffer is wrapped around to a valid offset. | 106 | * within the buffer. The buffer is wrapped around to a valid offset. |
@@ -246,7 +254,7 @@ catu_populate_table(struct tmc_sg_table *catu_table) | |||
246 | tmc_sg_table_sync_table(catu_table); | 254 | tmc_sg_table_sync_table(catu_table); |
247 | } | 255 | } |
248 | 256 | ||
249 | static struct tmc_sg_table __maybe_unused * | 257 | static struct tmc_sg_table * |
250 | catu_init_sg_table(struct device *catu_dev, int node, | 258 | catu_init_sg_table(struct device *catu_dev, int node, |
251 | ssize_t size, void **pages) | 259 | ssize_t size, void **pages) |
252 | { | 260 | { |
@@ -271,6 +279,91 @@ catu_init_sg_table(struct device *catu_dev, int node, | |||
271 | return catu_table; | 279 | return catu_table; |
272 | } | 280 | } |
273 | 281 | ||
282 | static void catu_free_etr_buf(struct etr_buf *etr_buf) | ||
283 | { | ||
284 | struct catu_etr_buf *catu_buf; | ||
285 | |||
286 | if (!etr_buf || etr_buf->mode != ETR_MODE_CATU || !etr_buf->private) | ||
287 | return; | ||
288 | |||
289 | catu_buf = etr_buf->private; | ||
290 | tmc_free_sg_table(catu_buf->catu_table); | ||
291 | kfree(catu_buf); | ||
292 | } | ||
293 | |||
294 | static ssize_t catu_get_data_etr_buf(struct etr_buf *etr_buf, u64 offset, | ||
295 | size_t len, char **bufpp) | ||
296 | { | ||
297 | struct catu_etr_buf *catu_buf = etr_buf->private; | ||
298 | |||
299 | return tmc_sg_table_get_data(catu_buf->catu_table, offset, len, bufpp); | ||
300 | } | ||
301 | |||
302 | static void catu_sync_etr_buf(struct etr_buf *etr_buf, u64 rrp, u64 rwp) | ||
303 | { | ||
304 | struct catu_etr_buf *catu_buf = etr_buf->private; | ||
305 | struct tmc_sg_table *catu_table = catu_buf->catu_table; | ||
306 | u64 r_offset, w_offset; | ||
307 | |||
308 | /* | ||
309 | * ETR started off at etr_buf->hwaddr. Convert the RRP/RWP to | ||
310 | * offsets within the trace buffer. | ||
311 | */ | ||
312 | r_offset = rrp - etr_buf->hwaddr; | ||
313 | w_offset = rwp - etr_buf->hwaddr; | ||
314 | |||
315 | if (!etr_buf->full) { | ||
316 | etr_buf->len = w_offset - r_offset; | ||
317 | if (w_offset < r_offset) | ||
318 | etr_buf->len += etr_buf->size; | ||
319 | } else { | ||
320 | etr_buf->len = etr_buf->size; | ||
321 | } | ||
322 | |||
323 | etr_buf->offset = r_offset; | ||
324 | tmc_sg_table_sync_data_range(catu_table, r_offset, etr_buf->len); | ||
325 | } | ||
326 | |||
327 | static int catu_alloc_etr_buf(struct tmc_drvdata *tmc_drvdata, | ||
328 | struct etr_buf *etr_buf, int node, void **pages) | ||
329 | { | ||
330 | struct coresight_device *csdev; | ||
331 | struct device *catu_dev; | ||
332 | struct tmc_sg_table *catu_table; | ||
333 | struct catu_etr_buf *catu_buf; | ||
334 | |||
335 | csdev = tmc_etr_get_catu_device(tmc_drvdata); | ||
336 | if (!csdev) | ||
337 | return -ENODEV; | ||
338 | catu_dev = csdev->dev.parent; | ||
339 | catu_buf = kzalloc(sizeof(*catu_buf), GFP_KERNEL); | ||
340 | if (!catu_buf) | ||
341 | return -ENOMEM; | ||
342 | |||
343 | catu_table = catu_init_sg_table(catu_dev, node, etr_buf->size, pages); | ||
344 | if (IS_ERR(catu_table)) { | ||
345 | kfree(catu_buf); | ||
346 | return PTR_ERR(catu_table); | ||
347 | } | ||
348 | |||
349 | etr_buf->mode = ETR_MODE_CATU; | ||
350 | etr_buf->private = catu_buf; | ||
351 | etr_buf->hwaddr = CATU_DEFAULT_INADDR; | ||
352 | |||
353 | catu_buf->catu_table = catu_table; | ||
354 | /* Get the table base address */ | ||
355 | catu_buf->sladdr = catu_table->table_daddr; | ||
356 | |||
357 | return 0; | ||
358 | } | ||
359 | |||
360 | const struct etr_buf_operations etr_catu_buf_ops = { | ||
361 | .alloc = catu_alloc_etr_buf, | ||
362 | .free = catu_free_etr_buf, | ||
363 | .sync = catu_sync_etr_buf, | ||
364 | .get_data = catu_get_data_etr_buf, | ||
365 | }; | ||
366 | |||
274 | coresight_simple_reg32(struct catu_drvdata, devid, CORESIGHT_DEVID); | 367 | coresight_simple_reg32(struct catu_drvdata, devid, CORESIGHT_DEVID); |
275 | coresight_simple_reg32(struct catu_drvdata, control, CATU_CONTROL); | 368 | coresight_simple_reg32(struct catu_drvdata, control, CATU_CONTROL); |
276 | coresight_simple_reg32(struct catu_drvdata, status, CATU_STATUS); | 369 | coresight_simple_reg32(struct catu_drvdata, status, CATU_STATUS); |
@@ -311,9 +404,10 @@ static inline int catu_wait_for_ready(struct catu_drvdata *drvdata) | |||
311 | CATU_STATUS, CATU_STATUS_READY, 1); | 404 | CATU_STATUS, CATU_STATUS_READY, 1); |
312 | } | 405 | } |
313 | 406 | ||
314 | static int catu_enable_hw(struct catu_drvdata *drvdata, void *__unused) | 407 | static int catu_enable_hw(struct catu_drvdata *drvdata, void *data) |
315 | { | 408 | { |
316 | u32 control; | 409 | u32 control, mode; |
410 | struct etr_buf *etr_buf = data; | ||
317 | 411 | ||
318 | if (catu_wait_for_ready(drvdata)) | 412 | if (catu_wait_for_ready(drvdata)) |
319 | dev_warn(drvdata->dev, "Timeout while waiting for READY\n"); | 413 | dev_warn(drvdata->dev, "Timeout while waiting for READY\n"); |
@@ -325,9 +419,27 @@ static int catu_enable_hw(struct catu_drvdata *drvdata, void *__unused) | |||
325 | } | 419 | } |
326 | 420 | ||
327 | control |= BIT(CATU_CONTROL_ENABLE); | 421 | control |= BIT(CATU_CONTROL_ENABLE); |
328 | catu_write_mode(drvdata, CATU_MODE_PASS_THROUGH); | 422 | |
423 | if (etr_buf && etr_buf->mode == ETR_MODE_CATU) { | ||
424 | struct catu_etr_buf *catu_buf = etr_buf->private; | ||
425 | |||
426 | mode = CATU_MODE_TRANSLATE; | ||
427 | catu_write_axictrl(drvdata, CATU_OS_AXICTRL); | ||
428 | catu_write_sladdr(drvdata, catu_buf->sladdr); | ||
429 | catu_write_inaddr(drvdata, CATU_DEFAULT_INADDR); | ||
430 | } else { | ||
431 | mode = CATU_MODE_PASS_THROUGH; | ||
432 | catu_write_sladdr(drvdata, 0); | ||
433 | catu_write_inaddr(drvdata, 0); | ||
434 | } | ||
435 | |||
436 | catu_write_irqen(drvdata, 0); | ||
437 | catu_write_mode(drvdata, mode); | ||
329 | catu_write_control(drvdata, control); | 438 | catu_write_control(drvdata, control); |
330 | dev_dbg(drvdata->dev, "Enabled in Pass through mode\n"); | 439 | dev_dbg(drvdata->dev, "Enabled in %s mode\n", |
440 | (mode == CATU_MODE_PASS_THROUGH) ? | ||
441 | "Pass through" : | ||
442 | "Translate"); | ||
331 | return 0; | 443 | return 0; |
332 | } | 444 | } |
333 | 445 | ||
diff --git a/drivers/hwtracing/coresight/coresight-catu.h b/drivers/hwtracing/coresight/coresight-catu.h index 4f221fccffca..1b281f0dcccc 100644 --- a/drivers/hwtracing/coresight/coresight-catu.h +++ b/drivers/hwtracing/coresight/coresight-catu.h | |||
@@ -27,6 +27,32 @@ | |||
27 | #define CATU_MODE_PASS_THROUGH 0U | 27 | #define CATU_MODE_PASS_THROUGH 0U |
28 | #define CATU_MODE_TRANSLATE 1U | 28 | #define CATU_MODE_TRANSLATE 1U |
29 | 29 | ||
30 | #define CATU_AXICTRL_ARCACHE_SHIFT 4 | ||
31 | #define CATU_AXICTRL_ARCACHE_MASK 0xf | ||
32 | #define CATU_AXICTRL_ARPROT_MASK 0x3 | ||
33 | #define CATU_AXICTRL_ARCACHE(arcache) \ | ||
34 | (((arcache) & CATU_AXICTRL_ARCACHE_MASK) << CATU_AXICTRL_ARCACHE_SHIFT) | ||
35 | |||
36 | #define CATU_AXICTRL_VAL(arcache, arprot) \ | ||
37 | (CATU_AXICTRL_ARCACHE(arcache) | ((arprot) & CATU_AXICTRL_ARPROT_MASK)) | ||
38 | |||
39 | #define AXI3_AxCACHE_WB_READ_ALLOC 0x7 | ||
40 | /* | ||
41 | * AXI - ARPROT bits: | ||
42 | * See AMBA AXI & ACE Protocol specification (ARM IHI 0022E) | ||
43 | * sectionA4.7 Access Permissions. | ||
44 | * | ||
45 | * Bit 0: 0 - Unprivileged access, 1 - Privileged access | ||
46 | * Bit 1: 0 - Secure access, 1 - Non-secure access. | ||
47 | * Bit 2: 0 - Data access, 1 - instruction access. | ||
48 | * | ||
49 | * CATU AXICTRL:ARPROT[2] is res0 as we always access data. | ||
50 | */ | ||
51 | #define CATU_OS_ARPROT 0x2 | ||
52 | |||
53 | #define CATU_OS_AXICTRL \ | ||
54 | CATU_AXICTRL_VAL(AXI3_AxCACHE_WB_READ_ALLOC, CATU_OS_ARPROT) | ||
55 | |||
30 | #define CATU_STATUS_READY 8 | 56 | #define CATU_STATUS_READY 8 |
31 | #define CATU_STATUS_ADRERR 0 | 57 | #define CATU_STATUS_ADRERR 0 |
32 | #define CATU_STATUS_AXIERR 4 | 58 | #define CATU_STATUS_AXIERR 4 |
@@ -67,6 +93,8 @@ catu_write_##name(struct catu_drvdata *drvdata, u64 val) \ | |||
67 | 93 | ||
68 | CATU_REG32(control, CATU_CONTROL); | 94 | CATU_REG32(control, CATU_CONTROL); |
69 | CATU_REG32(mode, CATU_MODE); | 95 | CATU_REG32(mode, CATU_MODE); |
96 | CATU_REG32(irqen, CATU_IRQEN); | ||
97 | CATU_REG32(axictrl, CATU_AXICTRL); | ||
70 | CATU_REG_PAIR(sladdr, CATU_SLADDRLO, CATU_SLADDRHI) | 98 | CATU_REG_PAIR(sladdr, CATU_SLADDRLO, CATU_SLADDRHI) |
71 | CATU_REG_PAIR(inaddr, CATU_INADDRLO, CATU_INADDRHI) | 99 | CATU_REG_PAIR(inaddr, CATU_INADDRLO, CATU_INADDRHI) |
72 | 100 | ||
@@ -81,4 +109,11 @@ static inline bool coresight_is_catu_device(struct coresight_device *csdev) | |||
81 | return true; | 109 | return true; |
82 | } | 110 | } |
83 | 111 | ||
112 | #ifdef CONFIG_CORESIGHT_CATU | ||
113 | extern const struct etr_buf_operations etr_catu_buf_ops; | ||
114 | #else | ||
115 | /* Dummy declaration for the CATU ops */ | ||
116 | static const struct etr_buf_operations etr_catu_buf_ops; | ||
117 | #endif | ||
118 | |||
84 | #endif | 119 | #endif |
diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c index e37923acb725..2eda5de304c2 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c | |||
@@ -710,7 +710,7 @@ static const struct etr_buf_operations etr_sg_buf_ops = { | |||
710 | * Returns : coresight_device ptr for the CATU device if a CATU is found. | 710 | * Returns : coresight_device ptr for the CATU device if a CATU is found. |
711 | * : NULL otherwise. | 711 | * : NULL otherwise. |
712 | */ | 712 | */ |
713 | static inline struct coresight_device * | 713 | struct coresight_device * |
714 | tmc_etr_get_catu_device(struct tmc_drvdata *drvdata) | 714 | tmc_etr_get_catu_device(struct tmc_drvdata *drvdata) |
715 | { | 715 | { |
716 | int i; | 716 | int i; |
@@ -733,7 +733,7 @@ static inline void tmc_etr_enable_catu(struct tmc_drvdata *drvdata) | |||
733 | struct coresight_device *catu = tmc_etr_get_catu_device(drvdata); | 733 | struct coresight_device *catu = tmc_etr_get_catu_device(drvdata); |
734 | 734 | ||
735 | if (catu && helper_ops(catu)->enable) | 735 | if (catu && helper_ops(catu)->enable) |
736 | helper_ops(catu)->enable(catu, NULL); | 736 | helper_ops(catu)->enable(catu, drvdata->etr_buf); |
737 | } | 737 | } |
738 | 738 | ||
739 | static inline void tmc_etr_disable_catu(struct tmc_drvdata *drvdata) | 739 | static inline void tmc_etr_disable_catu(struct tmc_drvdata *drvdata) |
@@ -741,12 +741,13 @@ static inline void tmc_etr_disable_catu(struct tmc_drvdata *drvdata) | |||
741 | struct coresight_device *catu = tmc_etr_get_catu_device(drvdata); | 741 | struct coresight_device *catu = tmc_etr_get_catu_device(drvdata); |
742 | 742 | ||
743 | if (catu && helper_ops(catu)->disable) | 743 | if (catu && helper_ops(catu)->disable) |
744 | helper_ops(catu)->disable(catu, NULL); | 744 | helper_ops(catu)->disable(catu, drvdata->etr_buf); |
745 | } | 745 | } |
746 | 746 | ||
747 | static const struct etr_buf_operations *etr_buf_ops[] = { | 747 | static const struct etr_buf_operations *etr_buf_ops[] = { |
748 | [ETR_MODE_FLAT] = &etr_flat_buf_ops, | 748 | [ETR_MODE_FLAT] = &etr_flat_buf_ops, |
749 | [ETR_MODE_ETR_SG] = &etr_sg_buf_ops, | 749 | [ETR_MODE_ETR_SG] = &etr_sg_buf_ops, |
750 | [ETR_MODE_CATU] = &etr_catu_buf_ops, | ||
750 | }; | 751 | }; |
751 | 752 | ||
752 | static inline int tmc_etr_mode_alloc_buf(int mode, | 753 | static inline int tmc_etr_mode_alloc_buf(int mode, |
@@ -754,12 +755,15 @@ static inline int tmc_etr_mode_alloc_buf(int mode, | |||
754 | struct etr_buf *etr_buf, int node, | 755 | struct etr_buf *etr_buf, int node, |
755 | void **pages) | 756 | void **pages) |
756 | { | 757 | { |
757 | int rc; | 758 | int rc = -EINVAL; |
758 | 759 | ||
759 | switch (mode) { | 760 | switch (mode) { |
760 | case ETR_MODE_FLAT: | 761 | case ETR_MODE_FLAT: |
761 | case ETR_MODE_ETR_SG: | 762 | case ETR_MODE_ETR_SG: |
762 | rc = etr_buf_ops[mode]->alloc(drvdata, etr_buf, node, pages); | 763 | case ETR_MODE_CATU: |
764 | if (etr_buf_ops[mode]->alloc) | ||
765 | rc = etr_buf_ops[mode]->alloc(drvdata, etr_buf, | ||
766 | node, pages); | ||
763 | if (!rc) | 767 | if (!rc) |
764 | etr_buf->ops = etr_buf_ops[mode]; | 768 | etr_buf->ops = etr_buf_ops[mode]; |
765 | return rc; | 769 | return rc; |
@@ -782,10 +786,14 @@ static struct etr_buf *tmc_alloc_etr_buf(struct tmc_drvdata *drvdata, | |||
782 | { | 786 | { |
783 | int rc = -ENOMEM; | 787 | int rc = -ENOMEM; |
784 | bool has_etr_sg, has_iommu; | 788 | bool has_etr_sg, has_iommu; |
789 | bool has_sg, has_catu; | ||
785 | struct etr_buf *etr_buf; | 790 | struct etr_buf *etr_buf; |
786 | 791 | ||
787 | has_etr_sg = tmc_etr_has_cap(drvdata, TMC_ETR_SG); | 792 | has_etr_sg = tmc_etr_has_cap(drvdata, TMC_ETR_SG); |
788 | has_iommu = iommu_get_domain_for_dev(drvdata->dev); | 793 | has_iommu = iommu_get_domain_for_dev(drvdata->dev); |
794 | has_catu = !!tmc_etr_get_catu_device(drvdata); | ||
795 | |||
796 | has_sg = has_catu || has_etr_sg; | ||
789 | 797 | ||
790 | etr_buf = kzalloc(sizeof(*etr_buf), GFP_KERNEL); | 798 | etr_buf = kzalloc(sizeof(*etr_buf), GFP_KERNEL); |
791 | if (!etr_buf) | 799 | if (!etr_buf) |
@@ -806,17 +814,22 @@ static struct etr_buf *tmc_alloc_etr_buf(struct tmc_drvdata *drvdata, | |||
806 | * | 814 | * |
807 | */ | 815 | */ |
808 | if (!pages && | 816 | if (!pages && |
809 | (!has_etr_sg || has_iommu || size < SZ_1M)) | 817 | (!has_sg || has_iommu || size < SZ_1M)) |
810 | rc = tmc_etr_mode_alloc_buf(ETR_MODE_FLAT, drvdata, | 818 | rc = tmc_etr_mode_alloc_buf(ETR_MODE_FLAT, drvdata, |
811 | etr_buf, node, pages); | 819 | etr_buf, node, pages); |
812 | if (rc && has_etr_sg) | 820 | if (rc && has_etr_sg) |
813 | rc = tmc_etr_mode_alloc_buf(ETR_MODE_ETR_SG, drvdata, | 821 | rc = tmc_etr_mode_alloc_buf(ETR_MODE_ETR_SG, drvdata, |
814 | etr_buf, node, pages); | 822 | etr_buf, node, pages); |
823 | if (rc && has_catu) | ||
824 | rc = tmc_etr_mode_alloc_buf(ETR_MODE_CATU, drvdata, | ||
825 | etr_buf, node, pages); | ||
815 | if (rc) { | 826 | if (rc) { |
816 | kfree(etr_buf); | 827 | kfree(etr_buf); |
817 | return ERR_PTR(rc); | 828 | return ERR_PTR(rc); |
818 | } | 829 | } |
819 | 830 | ||
831 | dev_dbg(drvdata->dev, "allocated buffer of size %ldKB in mode %d\n", | ||
832 | (unsigned long)size >> 10, etr_buf->mode); | ||
820 | return etr_buf; | 833 | return etr_buf; |
821 | } | 834 | } |
822 | 835 | ||
diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h index e7456575bfc1..7027bd60c4cc 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.h +++ b/drivers/hwtracing/coresight/coresight-tmc.h | |||
@@ -126,6 +126,7 @@ enum tmc_mem_intf_width { | |||
126 | enum etr_mode { | 126 | enum etr_mode { |
127 | ETR_MODE_FLAT, /* Uses contiguous flat buffer */ | 127 | ETR_MODE_FLAT, /* Uses contiguous flat buffer */ |
128 | ETR_MODE_ETR_SG, /* Uses in-built TMC ETR SG mechanism */ | 128 | ETR_MODE_ETR_SG, /* Uses in-built TMC ETR SG mechanism */ |
129 | ETR_MODE_CATU, /* Use SG mechanism in CATU */ | ||
129 | }; | 130 | }; |
130 | 131 | ||
131 | struct etr_buf_operations; | 132 | struct etr_buf_operations; |
@@ -303,4 +304,6 @@ tmc_sg_table_buf_size(struct tmc_sg_table *sg_table) | |||
303 | return sg_table->data_pages.nr_pages << PAGE_SHIFT; | 304 | return sg_table->data_pages.nr_pages << PAGE_SHIFT; |
304 | } | 305 | } |
305 | 306 | ||
307 | struct coresight_device *tmc_etr_get_catu_device(struct tmc_drvdata *drvdata); | ||
308 | |||
306 | #endif | 309 | #endif |