162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * MDEV driver 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. 662306a36Sopenharmony_ci * Author: Neo Jia <cjia@nvidia.com> 762306a36Sopenharmony_ci * Kirti Wankhede <kwankhede@nvidia.com> 862306a36Sopenharmony_ci */ 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include <linux/iommu.h> 1162306a36Sopenharmony_ci#include <linux/mdev.h> 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci#include "mdev_private.h" 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_cistatic int mdev_probe(struct device *dev) 1662306a36Sopenharmony_ci{ 1762306a36Sopenharmony_ci struct mdev_driver *drv = 1862306a36Sopenharmony_ci container_of(dev->driver, struct mdev_driver, driver); 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ci if (!drv->probe) 2162306a36Sopenharmony_ci return 0; 2262306a36Sopenharmony_ci return drv->probe(to_mdev_device(dev)); 2362306a36Sopenharmony_ci} 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_cistatic void mdev_remove(struct device *dev) 2662306a36Sopenharmony_ci{ 2762306a36Sopenharmony_ci struct mdev_driver *drv = 2862306a36Sopenharmony_ci container_of(dev->driver, struct mdev_driver, driver); 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci if (drv->remove) 3162306a36Sopenharmony_ci drv->remove(to_mdev_device(dev)); 3262306a36Sopenharmony_ci} 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_cistatic int mdev_match(struct device *dev, struct device_driver *drv) 3562306a36Sopenharmony_ci{ 3662306a36Sopenharmony_ci /* 3762306a36Sopenharmony_ci * No drivers automatically match. Drivers are only bound by explicit 3862306a36Sopenharmony_ci * device_driver_attach() 3962306a36Sopenharmony_ci */ 4062306a36Sopenharmony_ci return 0; 4162306a36Sopenharmony_ci} 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_cistruct bus_type mdev_bus_type = { 4462306a36Sopenharmony_ci .name = "mdev", 4562306a36Sopenharmony_ci .probe = mdev_probe, 4662306a36Sopenharmony_ci .remove = mdev_remove, 4762306a36Sopenharmony_ci .match = mdev_match, 4862306a36Sopenharmony_ci}; 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci/** 5162306a36Sopenharmony_ci * mdev_register_driver - register a new MDEV driver 5262306a36Sopenharmony_ci * @drv: the driver to register 5362306a36Sopenharmony_ci * 5462306a36Sopenharmony_ci * Returns a negative value on error, otherwise 0. 5562306a36Sopenharmony_ci **/ 5662306a36Sopenharmony_ciint mdev_register_driver(struct mdev_driver *drv) 5762306a36Sopenharmony_ci{ 5862306a36Sopenharmony_ci if (!drv->device_api) 5962306a36Sopenharmony_ci return -EINVAL; 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci /* initialize common driver fields */ 6262306a36Sopenharmony_ci drv->driver.bus = &mdev_bus_type; 6362306a36Sopenharmony_ci return driver_register(&drv->driver); 6462306a36Sopenharmony_ci} 6562306a36Sopenharmony_ciEXPORT_SYMBOL(mdev_register_driver); 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci/* 6862306a36Sopenharmony_ci * mdev_unregister_driver - unregister MDEV driver 6962306a36Sopenharmony_ci * @drv: the driver to unregister 7062306a36Sopenharmony_ci */ 7162306a36Sopenharmony_civoid mdev_unregister_driver(struct mdev_driver *drv) 7262306a36Sopenharmony_ci{ 7362306a36Sopenharmony_ci driver_unregister(&drv->driver); 7462306a36Sopenharmony_ci} 7562306a36Sopenharmony_ciEXPORT_SYMBOL(mdev_unregister_driver); 76