Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v6.19-rc3 112 lines 2.7 kB view raw
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);