drivers/soc/qcom/apr.c

Source file repositories/reference/linux-study-clean/drivers/soc/qcom/apr.c

File Facts

System
Linux kernel
Corpus path
drivers/soc/qcom/apr.c
Extension
.c
Size
17337 bytes
Lines
734
Domain
Driver Families
Bucket
drivers/soc
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 apr_device_match(struct device *dev, const struct device_driver *drv)
{
	struct apr_device *adev = to_apr_device(dev);
	const struct apr_driver *adrv = to_apr_driver(drv);
	const struct apr_device_id *id = adrv->id_table;

	/* Attempt an OF style match first */
	if (of_driver_match_device(dev, drv))
		return 1;

	if (!id)
		return 0;

	while (id->domain_id != 0 || id->svc_id != 0) {
		if (id->domain_id == adev->domain_id &&
		    id->svc_id == adev->svc.id)
			return 1;
		id++;
	}

	return 0;
}

static int apr_device_probe(struct device *dev)
{
	struct apr_device *adev = to_apr_device(dev);
	struct apr_driver *adrv = to_apr_driver(dev->driver);
	int ret;

	ret = adrv->probe(adev);
	if (!ret)
		adev->svc.callback = adrv->gpr_callback;

	return ret;
}

static void apr_device_remove(struct device *dev)
{
	struct apr_device *adev = to_apr_device(dev);
	struct apr_driver *adrv = to_apr_driver(dev->driver);
	struct packet_router *apr = dev_get_drvdata(adev->dev.parent);

	if (adrv->remove)
		adrv->remove(adev);
	spin_lock(&apr->svcs_lock);
	idr_remove(&apr->svcs_idr, adev->svc.id);
	spin_unlock(&apr->svcs_lock);
}

static int apr_uevent(const struct device *dev, struct kobj_uevent_env *env)
{
	const struct apr_device *adev = to_apr_device(dev);
	int ret;

	ret = of_device_uevent_modalias(dev, env);
	if (ret != -ENODEV)
		return ret;

	return add_uevent_var(env, "MODALIAS=apr:%s", adev->name);
}

const struct bus_type aprbus = {
	.name		= "aprbus",
	.match		= apr_device_match,
	.probe		= apr_device_probe,
	.uevent		= apr_uevent,
	.remove		= apr_device_remove,
};
EXPORT_SYMBOL_GPL(aprbus);

static int apr_add_device(struct device *dev, struct device_node *np,
			  u32 svc_id, u32 domain_id)
{
	struct packet_router *apr = dev_get_drvdata(dev);
	struct apr_device *adev = NULL;
	struct pkt_router_svc *svc;
	int ret;

	adev = kzalloc_obj(*adev);
	if (!adev)
		return -ENOMEM;

	adev->svc_id = svc_id;
	svc = &adev->svc;

	svc->id = svc_id;
	svc->pr = apr;
	svc->priv = adev;
	svc->dev = dev;
	spin_lock_init(&svc->lock);

Annotation

Implementation Notes