File Index
Files and directories
Sign in
FILE

vchiq_bus.c

File preview with syntax highlighting.

linux-6.19.14/drivers/platform/raspberrypi/vchiq-interface/vchiq_bus.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * vchiq_device.c - VCHIQ generic device and bus-type
  4 *
  5 * Copyright (c) 2023 Ideas On Board Oy
  6 */
  7
  8#include <linux/device/bus.h>
  9#include <linux/dma-mapping.h>
 10#include <linux/of_device.h>
 11#include <linux/slab.h>
 12#include <linux/string.h>
 13
 14#include <linux/raspberrypi/vchiq_arm.h>
 15#include <linux/raspberrypi/vchiq_bus.h>
 16
 17static int vchiq_bus_type_match(struct device *dev, const struct device_driver *drv)
 18{
 19	if (dev->bus == &vchiq_bus_type &&
 20	    strcmp(dev_name(dev), drv->name) == 0)
 21		return true;
 22
 23	return false;
 24}
 25
 26static int vchiq_bus_uevent(const struct device *dev, struct kobj_uevent_env *env)
 27{
 28	const struct vchiq_device *device = container_of_const(dev, struct vchiq_device, dev);
 29
 30	return add_uevent_var(env, "MODALIAS=vchiq:%s", dev_name(&device->dev));
 31}
 32
 33static int vchiq_bus_probe(struct device *dev)
 34{
 35	struct vchiq_device *device = to_vchiq_device(dev);
 36	struct vchiq_driver *driver = to_vchiq_driver(dev->driver);
 37
 38	return driver->probe(device);
 39}
 40
 41static void vchiq_bus_remove(struct device *dev)
 42{
 43	struct vchiq_device *device = to_vchiq_device(dev);
 44	struct vchiq_driver *driver = to_vchiq_driver(dev->driver);
 45
 46	if (driver->remove)
 47		driver->remove(device);
 48}
 49
 50const struct bus_type vchiq_bus_type = {
 51	.name   = "vchiq-bus",
 52	.match  = vchiq_bus_type_match,
 53	.uevent = vchiq_bus_uevent,
 54	.probe  = vchiq_bus_probe,
 55	.remove = vchiq_bus_remove,
 56};
 57
 58static void vchiq_device_release(struct device *dev)
 59{
 60	struct vchiq_device *device = to_vchiq_device(dev);
 61
 62	kfree(device);
 63}
 64
 65struct vchiq_device *
 66vchiq_device_register(struct device *parent, const char *name)
 67{
 68	struct vchiq_device *device;
 69	int ret;
 70
 71	device = kzalloc(sizeof(*device), GFP_KERNEL);
 72	if (!device)
 73		return NULL;
 74
 75	device->dev.init_name = name;
 76	device->dev.parent = parent;
 77	device->dev.bus = &vchiq_bus_type;
 78	device->dev.dma_mask = &device->dev.coherent_dma_mask;
 79	device->dev.release = vchiq_device_release;
 80
 81	device->drv_mgmt = dev_get_drvdata(parent);
 82
 83	of_dma_configure(&device->dev, parent->of_node, true);
 84
 85	ret = device_register(&device->dev);
 86	if (ret) {
 87		dev_err(parent, "Cannot register %s: %d\n", name, ret);
 88		put_device(&device->dev);
 89		return NULL;
 90	}
 91
 92	return device;
 93}
 94
 95void vchiq_device_unregister(struct vchiq_device *vchiq_dev)
 96{
 97	device_unregister(&vchiq_dev->dev);
 98}
 99
100int vchiq_driver_register(struct vchiq_driver *vchiq_drv)
101{
102	vchiq_drv->driver.bus = &vchiq_bus_type;
103
104	return driver_register(&vchiq_drv->driver);
105}
106EXPORT_SYMBOL_GPL(vchiq_driver_register);
107
108void vchiq_driver_unregister(struct vchiq_driver *vchiq_drv)
109{
110	driver_unregister(&vchiq_drv->driver);
111}
112EXPORT_SYMBOL_GPL(vchiq_driver_unregister);
~/ Read-only file preview.