File Index
Files and directories
Sign in
FILE

coresight-catu.c

File preview with syntax highlighting.

linux-6.19.14/drivers/hwtracing/coresight/coresight-catu.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * Copyright (C) 2018 Arm Limited. All rights reserved.
  4 *
  5 * Coresight Address Translation Unit support
  6 *
  7 * Author: Suzuki K Poulose <suzuki.poulose@arm.com>
  8 */
  9
 10#include <linux/acpi.h>
 11#include <linux/amba/bus.h>
 12#include <linux/device.h>
 13#include <linux/dma-mapping.h>
 14#include <linux/io.h>
 15#include <linux/kernel.h>
 16#include <linux/platform_device.h>
 17#include <linux/slab.h>
 18
 19#include "coresight-catu.h"
 20#include "coresight-priv.h"
 21#include "coresight-tmc.h"
 22
 23#define csdev_to_catu_drvdata(csdev)	\
 24	dev_get_drvdata(csdev->dev.parent)
 25
 26/* Verbose output for CATU table contents */
 27#ifdef CATU_DEBUG
 28#define catu_dbg(x, ...) dev_dbg(x, __VA_ARGS__)
 29#else
 30#define catu_dbg(x, ...) do {} while (0)
 31#endif
 32
 33DEFINE_CORESIGHT_DEVLIST(catu_devs, "catu");
 34
 35struct catu_etr_buf {
 36	struct tmc_sg_table *catu_table;
 37	dma_addr_t sladdr;
 38};
 39
 40/*
 41 * CATU uses a page size of 4KB for page tables as well as data pages.
 42 * Each 64bit entry in the table has the following format.
 43 *
 44 *	63			12	1  0
 45 *	------------------------------------
 46 *	|	 Address [63-12] | SBZ	| V|
 47 *	------------------------------------
 48 *
 49 * Where bit[0] V indicates if the address is valid or not.
 50 * Each 4K table pages have upto 256 data page pointers, taking upto 2K
 51 * size. There are two Link pointers, pointing to the previous and next
 52 * table pages respectively at the end of the 4K page. (i.e, entry 510
 53 * and 511).
 54 *  E.g, a table of two pages could look like :
 55 *
 56 *                 Table Page 0               Table Page 1
 57 * SLADDR ===> x------------------x  x--> x-----------------x
 58 * INADDR    ->|  Page 0      | V |  |    | Page 256    | V | <- INADDR+1M
 59 *             |------------------|  |    |-----------------|
 60 * INADDR+4K ->|  Page 1      | V |  |    |                 |
 61 *             |------------------|  |    |-----------------|
 62 *             |  Page 2      | V |  |    |                 |
 63 *             |------------------|  |    |-----------------|
 64 *             |   ...        | V |  |    |    ...          |
 65 *             |------------------|  |    |-----------------|
 66 * INADDR+1020K|  Page 255    | V |  |    |   Page 511  | V |
 67 * SLADDR+2K==>|------------------|  |    |-----------------|
 68 *             |  UNUSED      |   |  |    |                 |
 69 *             |------------------|  |    |                 |
 70 *             |  UNUSED      |   |  |    |                 |
 71 *             |------------------|  |    |                 |
 72 *             |    ...       |   |  |    |                 |
 73 *             |------------------|  |    |-----------------|
 74 *             |   IGNORED    | 0 |  |    | Table Page 0| 1 |
 75 *             |------------------|  |    |-----------------|
 76 *             |  Table Page 1| 1 |--x    | IGNORED     | 0 |
 77 *             x------------------x       x-----------------x
 78 * SLADDR+4K==>
 79 *
 80 * The base input address (used by the ETR, programmed in INADDR_{LO,HI})
 81 * must be aligned to 1MB (the size addressable by a single page table).
 82 * The CATU maps INADDR{LO:HI} to the first page in the table pointed
 83 * to by SLADDR{LO:HI} and so on.
 84 *
 85 */
 86typedef u64 cate_t;
 87
 88#define CATU_PAGE_SHIFT		12
 89#define CATU_PAGE_SIZE		(1UL << CATU_PAGE_SHIFT)
 90#define CATU_PAGES_PER_SYSPAGE	(PAGE_SIZE / CATU_PAGE_SIZE)
 91
 92/* Page pointers are only allocated in the first 2K half */
 93#define CATU_PTRS_PER_PAGE	((CATU_PAGE_SIZE >> 1) / sizeof(cate_t))
 94#define CATU_PTRS_PER_SYSPAGE	(CATU_PAGES_PER_SYSPAGE * CATU_PTRS_PER_PAGE)
 95#define CATU_LINK_PREV		((CATU_PAGE_SIZE / sizeof(cate_t)) - 2)
 96#define CATU_LINK_NEXT		((CATU_PAGE_SIZE / sizeof(cate_t)) - 1)
 97
 98#define CATU_ADDR_SHIFT		12
 99#define CATU_ADDR_MASK		~(((cate_t)1 << CATU_ADDR_SHIFT) - 1)
100#define CATU_ENTRY_VALID	((cate_t)0x1)
101#define CATU_VALID_ENTRY(addr) \
102	(((cate_t)(addr) & CATU_ADDR_MASK) | CATU_ENTRY_VALID)
103#define CATU_ENTRY_ADDR(entry)	((cate_t)(entry) & ~((cate_t)CATU_ENTRY_VALID))
104
105/* CATU expects the INADDR to be aligned to 1M. */
106#define CATU_DEFAULT_INADDR	(1ULL << 20)
107
108/*
109 * catu_get_table : Retrieve the table pointers for the given @offset
110 * within the buffer. The buffer is wrapped around to a valid offset.
111 *
112 * Returns : The CPU virtual address for the beginning of the table
113 * containing the data page pointer for @offset. If @daddrp is not NULL,
114 * @daddrp points the DMA address of the beginning of the table.
115 */
116static cate_t *catu_get_table(struct tmc_sg_table *catu_table, unsigned long offset,
117			      dma_addr_t *daddrp)
118{
119	unsigned long buf_size = tmc_sg_table_buf_size(catu_table);
120	unsigned int table_nr, pg_idx, pg_offset;
121	struct tmc_pages *table_pages = &catu_table->table_pages;
122	void *ptr;
123
124	/* Make sure offset is within the range */
125	offset %= buf_size;
126
127	/*
128	 * Each table can address 1MB and a single kernel page can
129	 * contain "CATU_PAGES_PER_SYSPAGE" CATU tables.
130	 */
131	table_nr = offset >> 20;
132	/* Find the table page where the table_nr lies in */
133	pg_idx = table_nr / CATU_PAGES_PER_SYSPAGE;
134	pg_offset = (table_nr % CATU_PAGES_PER_SYSPAGE) * CATU_PAGE_SIZE;
135	if (daddrp)
136		*daddrp = table_pages->daddrs[pg_idx] + pg_offset;
137	ptr = page_address(table_pages->pages[pg_idx]);
138	return (cate_t *)((unsigned long)ptr + pg_offset);
139}
140
141#ifdef CATU_DEBUG
142static void catu_dump_table(struct tmc_sg_table *catu_table)
143{
144	int i;
145	cate_t *table;
146	unsigned long table_end, buf_size, offset = 0;
147
148	buf_size = tmc_sg_table_buf_size(catu_table);
149	dev_dbg(catu_table->dev,
150		"Dump table %p, tdaddr: %llx\n",
151		catu_table, catu_table->table_daddr);
152
153	while (offset < buf_size) {
154		table_end = offset + SZ_1M < buf_size ?
155			    offset + SZ_1M : buf_size;
156		table = catu_get_table(catu_table, offset, NULL);
157		for (i = 0; offset < table_end; i++, offset += CATU_PAGE_SIZE)
158			dev_dbg(catu_table->dev, "%d: %llx\n", i, table[i]);
159		dev_dbg(catu_table->dev, "Prev : %llx, Next: %llx\n",
160			table[CATU_LINK_PREV], table[CATU_LINK_NEXT]);
161		dev_dbg(catu_table->dev, "== End of sub-table ===");
162	}
163	dev_dbg(catu_table->dev, "== End of Table ===");
164}
165
166#else
167static void catu_dump_table(struct tmc_sg_table *catu_table)
168{
169}
170#endif
171
172static cate_t catu_make_entry(dma_addr_t addr)
173{
174	return addr ? CATU_VALID_ENTRY(addr) : 0;
175}
176
177/*
178 * catu_populate_table : Populate the given CATU table.
179 * The table is always populated as a circular table.
180 * i.e, the "prev" link of the "first" table points to the "last"
181 * table and the "next" link of the "last" table points to the
182 * "first" table. The buffer should be made linear by calling
183 * catu_set_table().
184 */
185static void
186catu_populate_table(struct tmc_sg_table *catu_table)
187{
188	int i;
189	int sys_pidx;	/* Index to current system data page */
190	int catu_pidx;	/* Index of CATU page within the system data page */
191	unsigned long offset, buf_size, table_end;
192	dma_addr_t data_daddr;
193	dma_addr_t prev_taddr, next_taddr, cur_taddr;
194	cate_t *table_ptr, *next_table;
195
196	buf_size = tmc_sg_table_buf_size(catu_table);
197	sys_pidx = catu_pidx = 0;
198	offset = 0;
199
200	table_ptr = catu_get_table(catu_table, 0, &cur_taddr);
201	prev_taddr = 0;	/* Prev link for the first table */
202
203	while (offset < buf_size) {
204		/*
205		 * The @offset is always 1M aligned here and we have an
206		 * empty table @table_ptr to fill. Each table can address
207		 * upto 1MB data buffer. The last table may have fewer
208		 * entries if the buffer size is not aligned.
209		 */
210		table_end = (offset + SZ_1M) < buf_size ?
211			    (offset + SZ_1M) : buf_size;
212		for (i = 0; offset < table_end;
213		     i++, offset += CATU_PAGE_SIZE) {
214
215			data_daddr = catu_table->data_pages.daddrs[sys_pidx] +
216				     catu_pidx * CATU_PAGE_SIZE;
217			catu_dbg(catu_table->dev,
218				"[table %5ld:%03d] 0x%llx\n",
219				(offset >> 20), i, data_daddr);
220			table_ptr[i] = catu_make_entry(data_daddr);
221			/* Move the pointers for data pages */
222			catu_pidx = (catu_pidx + 1) % CATU_PAGES_PER_SYSPAGE;
223			if (catu_pidx == 0)
224				sys_pidx++;
225		}
226
227		/*
228		 * If we have finished all the valid entries, fill the rest of
229		 * the table (i.e, last table page) with invalid entries,
230		 * to fail the lookups.
231		 */
232		if (offset == buf_size) {
233			memset(&table_ptr[i], 0,
234			       sizeof(cate_t) * (CATU_PTRS_PER_PAGE - i));
235			next_taddr = 0;
236		} else {
237			next_table = catu_get_table(catu_table,
238						    offset, &next_taddr);
239		}
240
241		table_ptr[CATU_LINK_PREV] = catu_make_entry(prev_taddr);
242		table_ptr[CATU_LINK_NEXT] = catu_make_entry(next_taddr);
243
244		catu_dbg(catu_table->dev,
245			"[table%5ld]: Cur: 0x%llx Prev: 0x%llx, Next: 0x%llx\n",
246			(offset >> 20) - 1,  cur_taddr, prev_taddr, next_taddr);
247
248		/* Update the prev/next addresses */
249		if (next_taddr) {
250			prev_taddr = cur_taddr;
251			cur_taddr = next_taddr;
252			table_ptr = next_table;
253		}
254	}
255
256	/* Sync the table for device */
257	tmc_sg_table_sync_table(catu_table);
258}
259
260static struct tmc_sg_table *
261catu_init_sg_table(struct device *catu_dev, int node,
262		   ssize_t size, void **pages)
263{
264	int nr_tpages;
265	struct tmc_sg_table *catu_table;
266
267	/*
268	 * Each table can address upto 1MB and we can have
269	 * CATU_PAGES_PER_SYSPAGE tables in a system page.
270	 */
271	nr_tpages = DIV_ROUND_UP(size, CATU_PAGES_PER_SYSPAGE * SZ_1M);
272	catu_table = tmc_alloc_sg_table(catu_dev, node, nr_tpages,
273					size >> PAGE_SHIFT, pages);
274	if (IS_ERR(catu_table))
275		return catu_table;
276
277	catu_populate_table(catu_table);
278	dev_dbg(catu_dev,
279		"Setup table %p, size %ldKB, %d table pages\n",
280		catu_table, (unsigned long)size >> 10,  nr_tpages);
281	catu_dump_table(catu_table);
282	return catu_table;
283}
284
285static void catu_free_etr_buf(struct etr_buf *etr_buf)
286{
287	struct catu_etr_buf *catu_buf;
288
289	if (!etr_buf || etr_buf->mode != ETR_MODE_CATU || !etr_buf->private)
290		return;
291
292	catu_buf = etr_buf->private;
293	tmc_free_sg_table(catu_buf->catu_table);
294	kfree(catu_buf);
295}
296
297static ssize_t catu_get_data_etr_buf(struct etr_buf *etr_buf, u64 offset,
298				     size_t len, char **bufpp)
299{
300	struct catu_etr_buf *catu_buf = etr_buf->private;
301
302	return tmc_sg_table_get_data(catu_buf->catu_table, offset, len, bufpp);
303}
304
305static void catu_sync_etr_buf(struct etr_buf *etr_buf, u64 rrp, u64 rwp)
306{
307	struct catu_etr_buf *catu_buf = etr_buf->private;
308	struct tmc_sg_table *catu_table = catu_buf->catu_table;
309	u64 r_offset, w_offset;
310
311	/*
312	 * ETR started off at etr_buf->hwaddr. Convert the RRP/RWP to
313	 * offsets within the trace buffer.
314	 */
315	r_offset = rrp - etr_buf->hwaddr;
316	w_offset = rwp - etr_buf->hwaddr;
317
318	if (!etr_buf->full) {
319		etr_buf->len = w_offset - r_offset;
320		if (w_offset < r_offset)
321			etr_buf->len += etr_buf->size;
322	} else {
323		etr_buf->len = etr_buf->size;
324	}
325
326	etr_buf->offset = r_offset;
327	tmc_sg_table_sync_data_range(catu_table, r_offset, etr_buf->len);
328}
329
330static int catu_alloc_etr_buf(struct tmc_drvdata *tmc_drvdata,
331			      struct etr_buf *etr_buf, int node, void **pages)
332{
333	struct coresight_device *csdev;
334	struct tmc_sg_table *catu_table;
335	struct catu_etr_buf *catu_buf;
336
337	csdev = tmc_etr_get_catu_device(tmc_drvdata);
338	if (!csdev)
339		return -ENODEV;
340	catu_buf = kzalloc(sizeof(*catu_buf), GFP_KERNEL);
341	if (!catu_buf)
342		return -ENOMEM;
343
344	catu_table = catu_init_sg_table(&csdev->dev, node,
345					etr_buf->size, pages);
346	if (IS_ERR(catu_table)) {
347		kfree(catu_buf);
348		return PTR_ERR(catu_table);
349	}
350
351	etr_buf->mode = ETR_MODE_CATU;
352	etr_buf->private = catu_buf;
353	etr_buf->hwaddr = CATU_DEFAULT_INADDR;
354
355	catu_buf->catu_table = catu_table;
356	/* Get the table base address */
357	catu_buf->sladdr = catu_table->table_daddr;
358
359	return 0;
360}
361
362static const struct etr_buf_operations etr_catu_buf_ops = {
363	.alloc = catu_alloc_etr_buf,
364	.free = catu_free_etr_buf,
365	.sync = catu_sync_etr_buf,
366	.get_data = catu_get_data_etr_buf,
367};
368
369static struct attribute *catu_mgmt_attrs[] = {
370	coresight_simple_reg32(devid, CORESIGHT_DEVID),
371	coresight_simple_reg32(control, CATU_CONTROL),
372	coresight_simple_reg32(status, CATU_STATUS),
373	coresight_simple_reg32(mode, CATU_MODE),
374	coresight_simple_reg32(axictrl, CATU_AXICTRL),
375	coresight_simple_reg32(irqen, CATU_IRQEN),
376	coresight_simple_reg64(sladdr, CATU_SLADDRLO, CATU_SLADDRHI),
377	coresight_simple_reg64(inaddr, CATU_INADDRLO, CATU_INADDRHI),
378	NULL,
379};
380
381static const struct attribute_group catu_mgmt_group = {
382	.attrs = catu_mgmt_attrs,
383	.name = "mgmt",
384};
385
386static const struct attribute_group *catu_groups[] = {
387	&catu_mgmt_group,
388	NULL,
389};
390
391
392static int catu_wait_for_ready(struct catu_drvdata *drvdata)
393{
394	struct csdev_access *csa = &drvdata->csdev->access;
395
396	return coresight_timeout(csa, CATU_STATUS, CATU_STATUS_READY, 1);
397}
398
399static int catu_enable_hw(struct catu_drvdata *drvdata, enum cs_mode cs_mode,
400			  struct coresight_path *path)
401{
402	int rc;
403	u32 control, mode;
404	struct etr_buf *etr_buf = NULL;
405	struct device *dev = &drvdata->csdev->dev;
406	struct coresight_device *csdev = drvdata->csdev;
407	struct coresight_device *etrdev;
408	union coresight_dev_subtype etr_subtype = {
409		.sink_subtype = CORESIGHT_DEV_SUBTYPE_SINK_SYSMEM
410	};
411
412	if (catu_wait_for_ready(drvdata))
413		dev_warn(dev, "Timeout while waiting for READY\n");
414
415	control = catu_read_control(drvdata);
416	if (control & BIT(CATU_CONTROL_ENABLE)) {
417		dev_warn(dev, "CATU is already enabled\n");
418		return -EBUSY;
419	}
420
421	rc = coresight_claim_device_unlocked(csdev);
422	if (rc)
423		return rc;
424
425	etrdev = coresight_find_input_type(
426		csdev->pdata, CORESIGHT_DEV_TYPE_SINK, etr_subtype);
427	if (etrdev) {
428		etr_buf = tmc_etr_get_buffer(etrdev, cs_mode, path);
429		if (IS_ERR(etr_buf))
430			return PTR_ERR(etr_buf);
431	}
432	control |= BIT(CATU_CONTROL_ENABLE);
433
434	if (etr_buf && etr_buf->mode == ETR_MODE_CATU) {
435		struct catu_etr_buf *catu_buf = etr_buf->private;
436
437		mode = CATU_MODE_TRANSLATE;
438		catu_write_axictrl(drvdata, CATU_OS_AXICTRL);
439		catu_write_sladdr(drvdata, catu_buf->sladdr);
440		catu_write_inaddr(drvdata, CATU_DEFAULT_INADDR);
441	} else {
442		mode = CATU_MODE_PASS_THROUGH;
443		catu_write_sladdr(drvdata, 0);
444		catu_write_inaddr(drvdata, 0);
445	}
446
447	catu_write_irqen(drvdata, 0);
448	catu_write_mode(drvdata, mode);
449	catu_write_control(drvdata, control);
450	dev_dbg(dev, "Enabled in %s mode\n",
451		(mode == CATU_MODE_PASS_THROUGH) ?
452		"Pass through" :
453		"Translate");
454	return 0;
455}
456
457static int catu_enable(struct coresight_device *csdev, enum cs_mode mode,
458		       struct coresight_path *path)
459{
460	int rc = 0;
461	struct catu_drvdata *catu_drvdata = csdev_to_catu_drvdata(csdev);
462
463	guard(raw_spinlock_irqsave)(&catu_drvdata->spinlock);
464	if (csdev->refcnt == 0) {
465		CS_UNLOCK(catu_drvdata->base);
466		rc = catu_enable_hw(catu_drvdata, mode, path);
467		CS_LOCK(catu_drvdata->base);
468	}
469	if (!rc)
470		csdev->refcnt++;
471	return rc;
472}
473
474static int catu_disable_hw(struct catu_drvdata *drvdata)
475{
476	int rc = 0;
477	struct device *dev = &drvdata->csdev->dev;
478	struct coresight_device *csdev = drvdata->csdev;
479
480	catu_write_control(drvdata, 0);
481	coresight_disclaim_device_unlocked(csdev);
482	if (catu_wait_for_ready(drvdata)) {
483		dev_info(dev, "Timeout while waiting for READY\n");
484		rc = -EAGAIN;
485	}
486
487	dev_dbg(dev, "Disabled\n");
488	return rc;
489}
490
491static int catu_disable(struct coresight_device *csdev, struct coresight_path *path)
492{
493	int rc = 0;
494	struct catu_drvdata *catu_drvdata = csdev_to_catu_drvdata(csdev);
495
496	guard(raw_spinlock_irqsave)(&catu_drvdata->spinlock);
497	if (--csdev->refcnt == 0) {
498		CS_UNLOCK(catu_drvdata->base);
499		rc = catu_disable_hw(catu_drvdata);
500		CS_LOCK(catu_drvdata->base);
501	}
502	return rc;
503}
504
505static const struct coresight_ops_helper catu_helper_ops = {
506	.enable = catu_enable,
507	.disable = catu_disable,
508};
509
510static const struct coresight_ops catu_ops = {
511	.helper_ops = &catu_helper_ops,
512};
513
514static int __catu_probe(struct device *dev, struct resource *res)
515{
516	int ret = 0;
517	u32 dma_mask;
518	struct catu_drvdata *drvdata;
519	struct coresight_desc catu_desc;
520	struct coresight_platform_data *pdata = NULL;
521	void __iomem *base;
522
523	drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
524	if (!drvdata)
525		return -ENOMEM;
526
527	dev_set_drvdata(dev, drvdata);
528
529	ret = coresight_get_enable_clocks(dev, &drvdata->pclk, &drvdata->atclk);
530	if (ret)
531		return ret;
532
533	catu_desc.name = coresight_alloc_device_name(&catu_devs, dev);
534	if (!catu_desc.name)
535		return -ENOMEM;
536
537	base = devm_ioremap_resource(dev, res);
538	if (IS_ERR(base)) {
539		ret = PTR_ERR(base);
540		goto out;
541	}
542
543	/* Setup dma mask for the device */
544	dma_mask = readl_relaxed(base + CORESIGHT_DEVID) & 0x3f;
545	switch (dma_mask) {
546	case 32:
547	case 40:
548	case 44:
549	case 48:
550	case 52:
551	case 56:
552	case 64:
553		break;
554	default:
555		/* Default to the 40bits as supported by TMC-ETR */
556		dma_mask = 40;
557	}
558	ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(dma_mask));
559	if (ret)
560		goto out;
561
562	pdata = coresight_get_platform_data(dev);
563	if (IS_ERR(pdata)) {
564		ret = PTR_ERR(pdata);
565		goto out;
566	}
567	dev->platform_data = pdata;
568
569	drvdata->base = base;
570	raw_spin_lock_init(&drvdata->spinlock);
571	catu_desc.access = CSDEV_ACCESS_IOMEM(base);
572	catu_desc.pdata = pdata;
573	catu_desc.dev = dev;
574	catu_desc.groups = catu_groups;
575	catu_desc.type = CORESIGHT_DEV_TYPE_HELPER;
576	catu_desc.subtype.helper_subtype = CORESIGHT_DEV_SUBTYPE_HELPER_CATU;
577	catu_desc.ops = &catu_ops;
578
579	coresight_clear_self_claim_tag(&catu_desc.access);
580	drvdata->csdev = coresight_register(&catu_desc);
581	if (IS_ERR(drvdata->csdev))
582		ret = PTR_ERR(drvdata->csdev);
583out:
584	return ret;
585}
586
587static int catu_probe(struct amba_device *adev, const struct amba_id *id)
588{
589	int ret;
590
591	ret = __catu_probe(&adev->dev, &adev->res);
592	if (!ret)
593		pm_runtime_put(&adev->dev);
594
595	return ret;
596}
597
598static void __catu_remove(struct device *dev)
599{
600	struct catu_drvdata *drvdata = dev_get_drvdata(dev);
601
602	coresight_unregister(drvdata->csdev);
603}
604
605static void catu_remove(struct amba_device *adev)
606{
607	__catu_remove(&adev->dev);
608}
609
610static const struct amba_id catu_ids[] = {
611	CS_AMBA_ID(0x000bb9ee),
612	{},
613};
614
615MODULE_DEVICE_TABLE(amba, catu_ids);
616
617static struct amba_driver catu_driver = {
618	.drv = {
619		.name			= "coresight-catu",
620		.suppress_bind_attrs	= true,
621	},
622	.probe				= catu_probe,
623	.remove				= catu_remove,
624	.id_table			= catu_ids,
625};
626
627static int catu_platform_probe(struct platform_device *pdev)
628{
629	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
630	int ret = 0;
631
632	pm_runtime_get_noresume(&pdev->dev);
633	pm_runtime_set_active(&pdev->dev);
634	pm_runtime_enable(&pdev->dev);
635
636	ret = __catu_probe(&pdev->dev, res);
637	pm_runtime_put(&pdev->dev);
638	if (ret)
639		pm_runtime_disable(&pdev->dev);
640
641	return ret;
642}
643
644static void catu_platform_remove(struct platform_device *pdev)
645{
646	struct catu_drvdata *drvdata = dev_get_drvdata(&pdev->dev);
647
648	if (WARN_ON(!drvdata))
649		return;
650
651	__catu_remove(&pdev->dev);
652	pm_runtime_disable(&pdev->dev);
653}
654
655#ifdef CONFIG_PM
656static int catu_runtime_suspend(struct device *dev)
657{
658	struct catu_drvdata *drvdata = dev_get_drvdata(dev);
659
660	clk_disable_unprepare(drvdata->atclk);
661	clk_disable_unprepare(drvdata->pclk);
662
663	return 0;
664}
665
666static int catu_runtime_resume(struct device *dev)
667{
668	struct catu_drvdata *drvdata = dev_get_drvdata(dev);
669	int ret;
670
671	ret = clk_prepare_enable(drvdata->pclk);
672	if (ret)
673		return ret;
674
675	ret = clk_prepare_enable(drvdata->atclk);
676	if (ret)
677		clk_disable_unprepare(drvdata->pclk);
678
679	return ret;
680}
681#endif
682
683static const struct dev_pm_ops catu_dev_pm_ops = {
684	SET_RUNTIME_PM_OPS(catu_runtime_suspend, catu_runtime_resume, NULL)
685};
686
687#ifdef CONFIG_ACPI
688static const struct acpi_device_id catu_acpi_ids[] = {
689	{"ARMHC9CA", 0, 0, 0}, /* ARM CoreSight CATU */
690	{},
691};
692
693MODULE_DEVICE_TABLE(acpi, catu_acpi_ids);
694#endif
695
696static struct platform_driver catu_platform_driver = {
697	.probe	= catu_platform_probe,
698	.remove = catu_platform_remove,
699	.driver	= {
700		.name			= "coresight-catu-platform",
701		.acpi_match_table	= ACPI_PTR(catu_acpi_ids),
702		.suppress_bind_attrs	= true,
703		.pm			= &catu_dev_pm_ops,
704	},
705};
706
707static int __init catu_init(void)
708{
709	int ret;
710
711	ret = coresight_init_driver("catu", &catu_driver, &catu_platform_driver, THIS_MODULE);
712	tmc_etr_set_catu_ops(&etr_catu_buf_ops);
713	return ret;
714}
715
716static void __exit catu_exit(void)
717{
718	tmc_etr_remove_catu_ops();
719	coresight_remove_driver(&catu_driver, &catu_platform_driver);
720}
721
722module_init(catu_init);
723module_exit(catu_exit);
724
725MODULE_AUTHOR("Suzuki K Poulose <suzuki.poulose@arm.com>");
726MODULE_DESCRIPTION("Arm CoreSight Address Translation Unit (CATU) Driver");
727MODULE_LICENSE("GPL v2");
~/ Read-only file preview.