drivers/hwtracing/coresight/coresight-cpu-debug.c

Source file repositories/reference/linux-study-clean/drivers/hwtracing/coresight/coresight-cpu-debug.c

File Facts

System
Linux kernel
Corpus path
drivers/hwtracing/coresight/coresight-cpu-debug.c
Extension
.c
Size
18642 bytes
Lines
773
Domain
Driver Families
Bucket
drivers/hwtracing
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

static const struct file_operations debug_func_knob_fops = {
	.open	= simple_open,
	.read	= debug_func_knob_read,
	.write	= debug_func_knob_write,
};

static int debug_func_init(void)
{
	int ret;

	/* Create debugfs node */
	debug_debugfs_dir = debugfs_create_dir("coresight_cpu_debug", NULL);
	debugfs_create_file("enable", 0644, debug_debugfs_dir, NULL,
			    &debug_func_knob_fops);

	/* Register function to be called for panic */
	ret = atomic_notifier_chain_register(&panic_notifier_list,
					     &debug_notifier);
	if (ret) {
		pr_err("%s: unable to register notifier: %d\n",
		       __func__, ret);
		goto err;
	}

	return 0;

err:
	debugfs_remove_recursive(debug_debugfs_dir);
	return ret;
}

static void debug_func_exit(void)
{
	atomic_notifier_chain_unregister(&panic_notifier_list,
					 &debug_notifier);
	debugfs_remove_recursive(debug_debugfs_dir);
}

static int __debug_probe(struct device *dev, struct resource *res)
{
	struct debug_drvdata *drvdata;
	void __iomem *base;
	int ret;

	drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
	if (!drvdata)
		return -ENOMEM;

	dev_set_drvdata(dev, drvdata);

	ret = coresight_get_enable_clocks(dev, &drvdata->pclk, NULL);
	if (ret)
		return ret;

	drvdata->cpu = coresight_get_cpu(dev);
	if (drvdata->cpu < 0)
		return drvdata->cpu;

	if (per_cpu(debug_drvdata, drvdata->cpu)) {
		dev_err(dev, "CPU%d drvdata has already been initialized\n",
			drvdata->cpu);
		return -EBUSY;
	}

	drvdata->dev = dev;
	base = devm_ioremap_resource(dev, res);
	if (IS_ERR(base))
		return PTR_ERR(base);

	drvdata->base = base;

	cpus_read_lock();
	per_cpu(debug_drvdata, drvdata->cpu) = drvdata;
	ret = smp_call_function_single(drvdata->cpu, debug_init_arch_data,
				       drvdata, 1);
	cpus_read_unlock();

	if (ret) {
		dev_err(dev, "CPU%d debug arch init failed\n", drvdata->cpu);
		goto err;
	}

	if (!drvdata->edpcsr_present) {
		dev_err(dev, "CPU%d sample-based profiling isn't implemented\n",
			drvdata->cpu);
		ret = -ENXIO;
		goto err;
	}

	if (!debug_count++) {

Annotation

Implementation Notes