drivers/input/rmi4/rmi_bus.c

Source file repositories/reference/linux-study-clean/drivers/input/rmi4/rmi_bus.c

File Facts

System
Linux kernel
Corpus path
drivers/input/rmi4/rmi_bus.c
Extension
.c
Size
11012 bytes
Lines
486
Domain
Driver Families
Bucket
drivers/input
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 int rmi_function_match(struct device *dev, const struct device_driver *drv)
{
	const struct rmi_function_handler *handler = to_rmi_function_handler(drv);
	struct rmi_function *fn = to_rmi_function(dev);

	return fn->fd.function_number == handler->func;
}

#ifdef CONFIG_OF
static void rmi_function_of_probe(struct rmi_function *fn)
{
	char of_name[9];
	struct device_node *node = fn->rmi_dev->xport->dev->of_node;

	snprintf(of_name, sizeof(of_name), "rmi4-f%02x",
		fn->fd.function_number);
	fn->dev.of_node = of_get_child_by_name(node, of_name);
}
#else
static inline void rmi_function_of_probe(struct rmi_function *fn)
{}
#endif

static struct irq_chip rmi_irq_chip = {
	.name = "rmi4",
};

static int rmi_create_function_irq(struct rmi_function *fn,
				   struct rmi_function_handler *handler)
{
	struct rmi_driver_data *drvdata = dev_get_drvdata(&fn->rmi_dev->dev);
	int i, error;

	for (i = 0; i < fn->num_of_irqs; i++) {
		set_bit(fn->irq_pos + i, fn->irq_mask);

		fn->irq[i] = irq_create_mapping(drvdata->irqdomain,
						fn->irq_pos + i);

		irq_set_chip_data(fn->irq[i], fn);
		irq_set_chip_and_handler(fn->irq[i], &rmi_irq_chip,
					 handle_simple_irq);
		irq_set_nested_thread(fn->irq[i], 1);

		error = devm_request_threaded_irq(&fn->dev, fn->irq[i], NULL,
					handler->attention, IRQF_ONESHOT,
					dev_name(&fn->dev), fn);
		if (error) {
			dev_err(&fn->dev, "Error %d registering IRQ\n", error);
			return error;
		}
	}

	return 0;
}

static int rmi_function_probe(struct device *dev)
{
	struct rmi_function *fn = to_rmi_function(dev);
	struct rmi_function_handler *handler =
					to_rmi_function_handler(dev->driver);
	int error;

	rmi_function_of_probe(fn);

	if (handler->probe) {
		error = handler->probe(fn);
		if (error)
			return error;
	}

	if (fn->num_of_irqs && handler->attention) {
		error = rmi_create_function_irq(fn, handler);
		if (error)
			return error;
	}

	return 0;
}

static int rmi_function_remove(struct device *dev)
{
	struct rmi_function *fn = to_rmi_function(dev);
	struct rmi_function_handler *handler =
					to_rmi_function_handler(dev->driver);

	if (handler->remove)
		handler->remove(fn);

	return 0;

Annotation

Implementation Notes