brintos

brintos / linux-shallow public Read only

0
0
Text · 25.0 KiB · 07371cb Raw
971 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * CDX bus driver.4 *5 * Copyright (C) 2022-2023, Advanced Micro Devices, Inc.6 */7 8/*9 * Architecture Overview10 * =====================11 * CDX is a Hardware Architecture designed for AMD FPGA devices. It12 * consists of sophisticated mechanism for interaction between FPGA,13 * Firmware and the APUs (Application CPUs).14 *15 * Firmware resides on RPU (Realtime CPUs) which interacts with16 * the FPGA program manager and the APUs. The RPU provides memory-mapped17 * interface (RPU if) which is used to communicate with APUs.18 *19 * The diagram below shows an overview of the CDX architecture:20 *21 *          +--------------------------------------+22 *          |    Application CPUs (APU)            |23 *          |                                      |24 *          |                    CDX device drivers|25 *          |     Linux OS                |        |26 *          |                        CDX bus       |27 *          |                             |        |28 *          |                     CDX controller   |29 *          |                             |        |30 *          +-----------------------------|--------+31 *                                        | (discover, config,32 *                                        |  reset, rescan)33 *                                        |34 *          +------------------------| RPU if |----+35 *          |                             |        |36 *          |                             V        |37 *          |          Realtime CPUs (RPU)         |38 *          |                                      |39 *          +--------------------------------------+40 *                                |41 *          +---------------------|----------------+42 *          |  FPGA               |                |43 *          |      +-----------------------+       |44 *          |      |           |           |       |45 *          | +-------+    +-------+   +-------+   |46 *          | | dev 1 |    | dev 2 |   | dev 3 |   |47 *          | +-------+    +-------+   +-------+   |48 *          +--------------------------------------+49 *50 * The RPU firmware extracts the device information from the loaded FPGA51 * image and implements a mechanism that allows the APU drivers to52 * enumerate such devices (device personality and resource details) via53 * a dedicated communication channel. RPU mediates operations such as54 * discover, reset and rescan of the FPGA devices for the APU. This is55 * done using memory mapped interface provided by the RPU to APU.56 */57 58#include <linux/init.h>59#include <linux/irqdomain.h>60#include <linux/kernel.h>61#include <linux/of.h>62#include <linux/of_device.h>63#include <linux/of_platform.h>64#include <linux/platform_device.h>65#include <linux/slab.h>66#include <linux/mm.h>67#include <linux/idr.h>68#include <linux/cdx/cdx_bus.h>69#include <linux/iommu.h>70#include <linux/dma-map-ops.h>71#include <linux/debugfs.h>72#include "cdx.h"73 74/* Default DMA mask for devices on a CDX bus */75#define CDX_DEFAULT_DMA_MASK	(~0ULL)76#define MAX_CDX_CONTROLLERS 1677 78/* IDA for CDX controllers registered with the CDX bus */79static DEFINE_IDA(cdx_controller_ida);80/* Lock to protect controller ops */81static DEFINE_MUTEX(cdx_controller_lock);82/* Debugfs dir for cdx bus */83static struct dentry *cdx_debugfs_dir;84 85static char *compat_node_name = "xlnx,versal-net-cdx";86 87static void cdx_destroy_res_attr(struct cdx_device *cdx_dev, int num);88 89/**90 * cdx_dev_reset - Reset a CDX device91 * @dev: CDX device92 *93 * Return: -errno on failure, 0 on success.94 */95int cdx_dev_reset(struct device *dev)96{97	struct cdx_device *cdx_dev = to_cdx_device(dev);98	struct cdx_controller *cdx = cdx_dev->cdx;99	struct cdx_device_config dev_config = {0};100	struct cdx_driver *cdx_drv;101	int ret;102 103	cdx_drv = to_cdx_driver(dev->driver);104	/* Notify driver that device is being reset */105	if (cdx_drv && cdx_drv->reset_prepare)106		cdx_drv->reset_prepare(cdx_dev);107 108	dev_config.type = CDX_DEV_RESET_CONF;109	ret = cdx->ops->dev_configure(cdx, cdx_dev->bus_num,110				      cdx_dev->dev_num, &dev_config);111	if (ret)112		dev_err(dev, "cdx device reset failed\n");113 114	/* Notify driver that device reset is complete */115	if (cdx_drv && cdx_drv->reset_done)116		cdx_drv->reset_done(cdx_dev);117 118	return ret;119}120EXPORT_SYMBOL_GPL(cdx_dev_reset);121 122/**123 * reset_cdx_device - Reset a CDX device124 * @dev: CDX device125 * @data: This is always passed as NULL, and is not used in this API,126 *    but is required here as the device_for_each_child() API expects127 *    the passed function to have this as an argument.128 *129 * Return: -errno on failure, 0 on success.130 */131static int reset_cdx_device(struct device *dev, void *data)132{133	return cdx_dev_reset(dev);134}135 136/**137 * cdx_unregister_device - Unregister a CDX device138 * @dev: CDX device139 * @data: This is always passed as NULL, and is not used in this API,140 *	  but is required here as the bus_for_each_dev() API expects141 *	  the passed function (cdx_unregister_device) to have this142 *	  as an argument.143 *144 * Return: 0 on success.145 */146static int cdx_unregister_device(struct device *dev,147				 void *data)148{149	struct cdx_device *cdx_dev = to_cdx_device(dev);150	struct cdx_controller *cdx = cdx_dev->cdx;151 152	if (cdx_dev->is_bus) {153		device_for_each_child(dev, NULL, cdx_unregister_device);154		if (cdx_dev->enabled && cdx->ops->bus_disable)155			cdx->ops->bus_disable(cdx, cdx_dev->bus_num);156	} else {157		cdx_destroy_res_attr(cdx_dev, MAX_CDX_DEV_RESOURCES);158		debugfs_remove_recursive(cdx_dev->debugfs_dir);159		kfree(cdx_dev->driver_override);160		cdx_dev->driver_override = NULL;161	}162 163	/*164	 * Do not free cdx_dev here as it would be freed in165	 * cdx_device_release() called from within put_device().166	 */167	device_del(&cdx_dev->dev);168	put_device(&cdx_dev->dev);169 170	return 0;171}172 173static void cdx_unregister_devices(struct bus_type *bus)174{175	/* Reset all the devices attached to cdx bus */176	bus_for_each_dev(bus, NULL, NULL, cdx_unregister_device);177}178 179/**180 * cdx_match_one_device - Tell if a CDX device structure has a matching181 *			  CDX device id structure182 * @id: single CDX device id structure to match183 * @dev: the CDX device structure to match against184 *185 * Return: matching cdx_device_id structure or NULL if there is no match.186 */187static inline const struct cdx_device_id *188cdx_match_one_device(const struct cdx_device_id *id,189		     const struct cdx_device *dev)190{191	/* Use vendor ID and device ID for matching */192	if ((id->vendor == CDX_ANY_ID || id->vendor == dev->vendor) &&193	    (id->device == CDX_ANY_ID || id->device == dev->device) &&194	    (id->subvendor == CDX_ANY_ID || id->subvendor == dev->subsystem_vendor) &&195	    (id->subdevice == CDX_ANY_ID || id->subdevice == dev->subsystem_device) &&196	    !((id->class ^ dev->class) & id->class_mask))197		return id;198	return NULL;199}200 201/**202 * cdx_match_id - See if a CDX device matches a given cdx_id table203 * @ids: array of CDX device ID structures to search in204 * @dev: the CDX device structure to match against.205 *206 * Used by a driver to check whether a CDX device is in its list of207 * supported devices. Returns the matching cdx_device_id structure or208 * NULL if there is no match.209 *210 * Return: matching cdx_device_id structure or NULL if there is no match.211 */212static inline const struct cdx_device_id *213cdx_match_id(const struct cdx_device_id *ids, struct cdx_device *dev)214{215	if (ids) {216		while (ids->vendor || ids->device) {217			if (cdx_match_one_device(ids, dev))218				return ids;219			ids++;220		}221	}222	return NULL;223}224 225int cdx_set_master(struct cdx_device *cdx_dev)226{227	struct cdx_controller *cdx = cdx_dev->cdx;228	struct cdx_device_config dev_config;229	int ret = -EOPNOTSUPP;230 231	dev_config.type = CDX_DEV_BUS_MASTER_CONF;232	dev_config.bus_master_enable = true;233	if (cdx->ops->dev_configure)234		ret = cdx->ops->dev_configure(cdx, cdx_dev->bus_num,235					      cdx_dev->dev_num, &dev_config);236 237	return ret;238}239EXPORT_SYMBOL_GPL(cdx_set_master);240 241int cdx_clear_master(struct cdx_device *cdx_dev)242{243	struct cdx_controller *cdx = cdx_dev->cdx;244	struct cdx_device_config dev_config;245	int ret = -EOPNOTSUPP;246 247	dev_config.type = CDX_DEV_BUS_MASTER_CONF;248	dev_config.bus_master_enable = false;249	if (cdx->ops->dev_configure)250		ret = cdx->ops->dev_configure(cdx, cdx_dev->bus_num,251					      cdx_dev->dev_num, &dev_config);252 253	return ret;254}255EXPORT_SYMBOL_GPL(cdx_clear_master);256 257/**258 * cdx_bus_match - device to driver matching callback259 * @dev: the cdx device to match against260 * @drv: the device driver to search for matching cdx device261 * structures262 *263 * Return: true on success, false otherwise.264 */265static int cdx_bus_match(struct device *dev, const struct device_driver *drv)266{267	struct cdx_device *cdx_dev = to_cdx_device(dev);268	const struct cdx_driver *cdx_drv = to_cdx_driver(drv);269	const struct cdx_device_id *found_id = NULL;270	const struct cdx_device_id *ids;271 272	if (cdx_dev->is_bus)273		return false;274 275	ids = cdx_drv->match_id_table;276 277	/* When driver_override is set, only bind to the matching driver */278	if (cdx_dev->driver_override && strcmp(cdx_dev->driver_override, drv->name))279		return false;280 281	found_id = cdx_match_id(ids, cdx_dev);282	if (!found_id)283		return false;284 285	do {286		/*287		 * In case override_only was set, enforce driver_override288		 * matching.289		 */290		if (!found_id->override_only)291			return true;292		if (cdx_dev->driver_override)293			return true;294 295		ids = found_id + 1;296		found_id = cdx_match_id(ids, cdx_dev);297	} while (found_id);298 299	return false;300}301 302static int cdx_probe(struct device *dev)303{304	struct cdx_driver *cdx_drv = to_cdx_driver(dev->driver);305	struct cdx_device *cdx_dev = to_cdx_device(dev);306	struct cdx_controller *cdx = cdx_dev->cdx;307	int error;308 309	/*310	 * Setup MSI device data so that generic MSI alloc/free can311	 * be used by the device driver.312	 */313	if (cdx->msi_domain) {314		error = msi_setup_device_data(&cdx_dev->dev);315		if (error)316			return error;317	}318 319	error = cdx_drv->probe(cdx_dev);320	if (error) {321		dev_err_probe(dev, error, "%s failed\n", __func__);322		return error;323	}324 325	return 0;326}327 328static void cdx_remove(struct device *dev)329{330	struct cdx_driver *cdx_drv = to_cdx_driver(dev->driver);331	struct cdx_device *cdx_dev = to_cdx_device(dev);332 333	if (cdx_drv && cdx_drv->remove)334		cdx_drv->remove(cdx_dev);335}336 337static void cdx_shutdown(struct device *dev)338{339	struct cdx_driver *cdx_drv = to_cdx_driver(dev->driver);340	struct cdx_device *cdx_dev = to_cdx_device(dev);341 342	if (cdx_drv && cdx_drv->shutdown)343		cdx_drv->shutdown(cdx_dev);344}345 346static int cdx_dma_configure(struct device *dev)347{348	struct cdx_driver *cdx_drv = to_cdx_driver(dev->driver);349	struct cdx_device *cdx_dev = to_cdx_device(dev);350	struct cdx_controller *cdx = cdx_dev->cdx;351	u32 input_id = cdx_dev->req_id;352	int ret;353 354	ret = of_dma_configure_id(dev, cdx->dev->of_node, 0, &input_id);355	if (ret && ret != -EPROBE_DEFER) {356		dev_err(dev, "of_dma_configure_id() failed\n");357		return ret;358	}359 360	if (!ret && !cdx_drv->driver_managed_dma) {361		ret = iommu_device_use_default_domain(dev);362		if (ret)363			arch_teardown_dma_ops(dev);364	}365 366	return 0;367}368 369static void cdx_dma_cleanup(struct device *dev)370{371	struct cdx_driver *cdx_drv = to_cdx_driver(dev->driver);372 373	if (!cdx_drv->driver_managed_dma)374		iommu_device_unuse_default_domain(dev);375}376 377/* show configuration fields */378#define cdx_config_attr(field, format_string)	\379static ssize_t	\380field##_show(struct device *dev, struct device_attribute *attr, char *buf)	\381{	\382	struct cdx_device *cdx_dev = to_cdx_device(dev);	\383	return sysfs_emit(buf, format_string, cdx_dev->field);	\384}	\385static DEVICE_ATTR_RO(field)386 387cdx_config_attr(vendor, "0x%04x\n");388cdx_config_attr(device, "0x%04x\n");389cdx_config_attr(subsystem_vendor, "0x%04x\n");390cdx_config_attr(subsystem_device, "0x%04x\n");391cdx_config_attr(revision, "0x%02x\n");392cdx_config_attr(class, "0x%06x\n");393 394static ssize_t remove_store(struct device *dev,395			    struct device_attribute *attr,396			    const char *buf, size_t count)397{398	bool val;399 400	if (kstrtobool(buf, &val) < 0)401		return -EINVAL;402 403	if (!val)404		return -EINVAL;405 406	if (device_remove_file_self(dev, attr)) {407		int ret;408 409		ret = cdx_unregister_device(dev, NULL);410		if (ret)411			return ret;412	}413 414	return count;415}416static DEVICE_ATTR_WO(remove);417 418static ssize_t reset_store(struct device *dev, struct device_attribute *attr,419			   const char *buf, size_t count)420{421	struct cdx_device *cdx_dev = to_cdx_device(dev);422	bool val;423	int ret;424 425	if (kstrtobool(buf, &val) < 0)426		return -EINVAL;427 428	if (!val)429		return -EINVAL;430 431	if (cdx_dev->is_bus)432		/* Reset all the devices attached to cdx bus */433		ret = device_for_each_child(dev, NULL, reset_cdx_device);434	else435		ret = cdx_dev_reset(dev);436 437	return ret < 0 ? ret : count;438}439static DEVICE_ATTR_WO(reset);440 441static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,442			     char *buf)443{444	struct cdx_device *cdx_dev = to_cdx_device(dev);445 446	return sprintf(buf, "cdx:v%04Xd%04Xsv%04Xsd%04Xc%06X\n", cdx_dev->vendor,447			cdx_dev->device, cdx_dev->subsystem_vendor, cdx_dev->subsystem_device,448			cdx_dev->class);449}450static DEVICE_ATTR_RO(modalias);451 452static ssize_t driver_override_store(struct device *dev,453				     struct device_attribute *attr,454				     const char *buf, size_t count)455{456	struct cdx_device *cdx_dev = to_cdx_device(dev);457	int ret;458 459	if (WARN_ON(dev->bus != &cdx_bus_type))460		return -EINVAL;461 462	ret = driver_set_override(dev, &cdx_dev->driver_override, buf, count);463	if (ret)464		return ret;465 466	return count;467}468 469static ssize_t driver_override_show(struct device *dev,470				    struct device_attribute *attr, char *buf)471{472	struct cdx_device *cdx_dev = to_cdx_device(dev);473 474	return sysfs_emit(buf, "%s\n", cdx_dev->driver_override);475}476static DEVICE_ATTR_RW(driver_override);477 478static ssize_t enable_store(struct device *dev, struct device_attribute *attr,479			    const char *buf, size_t count)480{481	struct cdx_device *cdx_dev = to_cdx_device(dev);482	struct cdx_controller *cdx = cdx_dev->cdx;483	bool enable;484	int ret;485 486	if (kstrtobool(buf, &enable) < 0)487		return -EINVAL;488 489	if (enable == cdx_dev->enabled)490		return count;491 492	if (enable && cdx->ops->bus_enable)493		ret = cdx->ops->bus_enable(cdx, cdx_dev->bus_num);494	else if (!enable && cdx->ops->bus_disable)495		ret = cdx->ops->bus_disable(cdx, cdx_dev->bus_num);496	else497		ret = -EOPNOTSUPP;498 499	if (!ret)500		cdx_dev->enabled = enable;501 502	return ret < 0 ? ret : count;503}504 505static ssize_t enable_show(struct device *dev, struct device_attribute *attr, char *buf)506{507	struct cdx_device *cdx_dev = to_cdx_device(dev);508 509	return sysfs_emit(buf, "%u\n", cdx_dev->enabled);510}511static DEVICE_ATTR_RW(enable);512 513static umode_t cdx_dev_attrs_are_visible(struct kobject *kobj, struct attribute *a, int n)514{515	struct device *dev = kobj_to_dev(kobj);516	struct cdx_device *cdx_dev;517 518	cdx_dev = to_cdx_device(dev);519	if (!cdx_dev->is_bus)520		return a->mode;521 522	return 0;523}524 525static umode_t cdx_bus_attrs_are_visible(struct kobject *kobj, struct attribute *a, int n)526{527	struct device *dev = kobj_to_dev(kobj);528	struct cdx_device *cdx_dev;529 530	cdx_dev = to_cdx_device(dev);531	if (cdx_dev->is_bus)532		return a->mode;533 534	return 0;535}536 537static struct attribute *cdx_dev_attrs[] = {538	&dev_attr_remove.attr,539	&dev_attr_reset.attr,540	&dev_attr_vendor.attr,541	&dev_attr_device.attr,542	&dev_attr_subsystem_vendor.attr,543	&dev_attr_subsystem_device.attr,544	&dev_attr_class.attr,545	&dev_attr_revision.attr,546	&dev_attr_modalias.attr,547	&dev_attr_driver_override.attr,548	NULL,549};550 551static const struct attribute_group cdx_dev_group = {552	.attrs = cdx_dev_attrs,553	.is_visible = cdx_dev_attrs_are_visible,554};555 556static struct attribute *cdx_bus_dev_attrs[] = {557	&dev_attr_enable.attr,558	&dev_attr_reset.attr,559	NULL,560};561 562static const struct attribute_group cdx_bus_dev_group = {563	.attrs = cdx_bus_dev_attrs,564	.is_visible = cdx_bus_attrs_are_visible,565};566 567static const struct attribute_group *cdx_dev_groups[] = {568	&cdx_dev_group,569	&cdx_bus_dev_group,570	NULL,571};572 573static int cdx_debug_resource_show(struct seq_file *s, void *data)574{575	struct cdx_device *cdx_dev = s->private;576	int i;577 578	for (i = 0; i < MAX_CDX_DEV_RESOURCES; i++) {579		struct resource *res =  &cdx_dev->res[i];580 581		seq_printf(s, "%pr\n", res);582	}583 584	return 0;585}586DEFINE_SHOW_ATTRIBUTE(cdx_debug_resource);587 588static void cdx_device_debugfs_init(struct cdx_device *cdx_dev)589{590	cdx_dev->debugfs_dir = debugfs_create_dir(dev_name(&cdx_dev->dev), cdx_debugfs_dir);591	if (IS_ERR(cdx_dev->debugfs_dir))592		return;593 594	debugfs_create_file("resource", 0444, cdx_dev->debugfs_dir, cdx_dev,595			    &cdx_debug_resource_fops);596}597 598static ssize_t rescan_store(const struct bus_type *bus,599			    const char *buf, size_t count)600{601	struct cdx_controller *cdx;602	struct platform_device *pd;603	struct device_node *np;604	bool val;605 606	if (kstrtobool(buf, &val) < 0)607		return -EINVAL;608 609	if (!val)610		return -EINVAL;611 612	mutex_lock(&cdx_controller_lock);613 614	/* Unregister all the devices on the bus */615	cdx_unregister_devices(&cdx_bus_type);616 617	/* Rescan all the devices */618	for_each_compatible_node(np, NULL, compat_node_name) {619		pd = of_find_device_by_node(np);620		if (!pd) {621			of_node_put(np);622			count = -EINVAL;623			goto unlock;624		}625 626		cdx = platform_get_drvdata(pd);627		if (cdx && cdx->controller_registered && cdx->ops->scan)628			cdx->ops->scan(cdx);629 630		put_device(&pd->dev);631	}632 633unlock:634	mutex_unlock(&cdx_controller_lock);635 636	return count;637}638static BUS_ATTR_WO(rescan);639 640static struct attribute *cdx_bus_attrs[] = {641	&bus_attr_rescan.attr,642	NULL,643};644ATTRIBUTE_GROUPS(cdx_bus);645 646struct bus_type cdx_bus_type = {647	.name		= "cdx",648	.match		= cdx_bus_match,649	.probe		= cdx_probe,650	.remove		= cdx_remove,651	.shutdown	= cdx_shutdown,652	.dma_configure	= cdx_dma_configure,653	.dma_cleanup	= cdx_dma_cleanup,654	.bus_groups	= cdx_bus_groups,655	.dev_groups	= cdx_dev_groups,656};657EXPORT_SYMBOL_GPL(cdx_bus_type);658 659int __cdx_driver_register(struct cdx_driver *cdx_driver,660			  struct module *owner)661{662	int error;663 664	cdx_driver->driver.owner = owner;665	cdx_driver->driver.bus = &cdx_bus_type;666 667	error = driver_register(&cdx_driver->driver);668	if (error) {669		pr_err("driver_register() failed for %s: %d\n",670		       cdx_driver->driver.name, error);671		return error;672	}673 674	return 0;675}676EXPORT_SYMBOL_GPL(__cdx_driver_register);677 678void cdx_driver_unregister(struct cdx_driver *cdx_driver)679{680	driver_unregister(&cdx_driver->driver);681}682EXPORT_SYMBOL_GPL(cdx_driver_unregister);683 684static void cdx_device_release(struct device *dev)685{686	struct cdx_device *cdx_dev = to_cdx_device(dev);687 688	kfree(cdx_dev);689}690 691static const struct vm_operations_struct cdx_phys_vm_ops = {692#ifdef CONFIG_HAVE_IOREMAP_PROT693	.access = generic_access_phys,694#endif695};696 697/**698 * cdx_mmap_resource - map a CDX resource into user memory space699 * @fp: File pointer. Not used in this function, but required where700 *      this API is registered as a callback.701 * @kobj: kobject for mapping702 * @attr: struct bin_attribute for the file being mapped703 * @vma: struct vm_area_struct passed into the mmap704 *705 * Use the regular CDX mapping routines to map a CDX resource into userspace.706 *707 * Return: true on success, false otherwise.708 */709static int cdx_mmap_resource(struct file *fp, struct kobject *kobj,710			     struct bin_attribute *attr,711			     struct vm_area_struct *vma)712{713	struct cdx_device *cdx_dev = to_cdx_device(kobj_to_dev(kobj));714	int num = (unsigned long)attr->private;715	struct resource *res;716	unsigned long size;717 718	res = &cdx_dev->res[num];719	if (iomem_is_exclusive(res->start))720		return -EINVAL;721 722	/* Make sure the caller is mapping a valid resource for this device */723	size = ((cdx_resource_len(cdx_dev, num) - 1) >> PAGE_SHIFT) + 1;724	if (vma->vm_pgoff + vma_pages(vma) > size)725		return -EINVAL;726 727	/*728	 * Map memory region and vm->vm_pgoff is expected to be an729	 * offset within that region.730	 */731	vma->vm_page_prot = pgprot_device(vma->vm_page_prot);732	vma->vm_pgoff += (cdx_resource_start(cdx_dev, num) >> PAGE_SHIFT);733	vma->vm_ops = &cdx_phys_vm_ops;734	return io_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,735				  vma->vm_end - vma->vm_start,736				  vma->vm_page_prot);737}738 739static void cdx_destroy_res_attr(struct cdx_device *cdx_dev, int num)740{741	int i;742 743	/* removing the bin attributes */744	for (i = 0; i < num; i++) {745		struct bin_attribute *res_attr;746 747		res_attr = cdx_dev->res_attr[i];748		if (res_attr) {749			sysfs_remove_bin_file(&cdx_dev->dev.kobj, res_attr);750			kfree(res_attr);751		}752	}753}754 755#define CDX_RES_ATTR_NAME_LEN	10756static int cdx_create_res_attr(struct cdx_device *cdx_dev, int num)757{758	struct bin_attribute *res_attr;759	char *res_attr_name;760	int ret;761 762	res_attr = kzalloc(sizeof(*res_attr) + CDX_RES_ATTR_NAME_LEN, GFP_ATOMIC);763	if (!res_attr)764		return -ENOMEM;765 766	res_attr_name = (char *)(res_attr + 1);767 768	sysfs_bin_attr_init(res_attr);769 770	cdx_dev->res_attr[num] = res_attr;771	sprintf(res_attr_name, "resource%d", num);772 773	res_attr->mmap = cdx_mmap_resource;774	res_attr->attr.name = res_attr_name;775	res_attr->attr.mode = 0600;776	res_attr->size = cdx_resource_len(cdx_dev, num);777	res_attr->private = (void *)(unsigned long)num;778	ret = sysfs_create_bin_file(&cdx_dev->dev.kobj, res_attr);779	if (ret)780		kfree(res_attr);781 782	return ret;783}784 785int cdx_device_add(struct cdx_dev_params *dev_params)786{787	struct cdx_controller *cdx = dev_params->cdx;788	struct cdx_device *cdx_dev;789	int ret, i;790 791	cdx_dev = kzalloc(sizeof(*cdx_dev), GFP_KERNEL);792	if (!cdx_dev)793		return -ENOMEM;794 795	/* Populate resource */796	memcpy(cdx_dev->res, dev_params->res, sizeof(struct resource) *797		dev_params->res_count);798	cdx_dev->res_count = dev_params->res_count;799 800	/* Populate CDX dev params */801	cdx_dev->req_id = dev_params->req_id;802	cdx_dev->msi_dev_id = dev_params->msi_dev_id;803	cdx_dev->vendor = dev_params->vendor;804	cdx_dev->device = dev_params->device;805	cdx_dev->subsystem_vendor = dev_params->subsys_vendor;806	cdx_dev->subsystem_device = dev_params->subsys_device;807	cdx_dev->class = dev_params->class;808	cdx_dev->revision = dev_params->revision;809	cdx_dev->bus_num = dev_params->bus_num;810	cdx_dev->dev_num = dev_params->dev_num;811	cdx_dev->cdx = dev_params->cdx;812	cdx_dev->dma_mask = CDX_DEFAULT_DMA_MASK;813 814	/* Initialize generic device */815	device_initialize(&cdx_dev->dev);816	cdx_dev->dev.parent = dev_params->parent;817	cdx_dev->dev.bus = &cdx_bus_type;818	cdx_dev->dev.dma_mask = &cdx_dev->dma_mask;819	cdx_dev->dev.release = cdx_device_release;820	cdx_dev->msi_write_pending = false;821	mutex_init(&cdx_dev->irqchip_lock);822 823	/* Set Name */824	dev_set_name(&cdx_dev->dev, "cdx-%02x:%02x",825		     ((cdx->id << CDX_CONTROLLER_ID_SHIFT) | (cdx_dev->bus_num & CDX_BUS_NUM_MASK)),826		     cdx_dev->dev_num);827 828	if (cdx->msi_domain) {829		cdx_dev->num_msi = dev_params->num_msi;830		dev_set_msi_domain(&cdx_dev->dev, cdx->msi_domain);831	}832 833	ret = device_add(&cdx_dev->dev);834	if (ret) {835		dev_err(&cdx_dev->dev,836			"cdx device add failed: %d", ret);837		goto fail;838	}839 840	/* Create resource<N> attributes */841	for (i = 0; i < MAX_CDX_DEV_RESOURCES; i++) {842		if (cdx_resource_flags(cdx_dev, i) & IORESOURCE_MEM) {843			/* skip empty resources */844			if (!cdx_resource_len(cdx_dev, i))845				continue;846 847			ret = cdx_create_res_attr(cdx_dev, i);848			if (ret != 0) {849				dev_err(&cdx_dev->dev,850					"cdx device resource<%d> file creation failed: %d", i, ret);851				goto resource_create_fail;852			}853		}854	}855 856	cdx_device_debugfs_init(cdx_dev);857 858	return 0;859resource_create_fail:860	cdx_destroy_res_attr(cdx_dev, i);861	device_del(&cdx_dev->dev);862fail:863	/*864	 * Do not free cdx_dev here as it would be freed in865	 * cdx_device_release() called from put_device().866	 */867	put_device(&cdx_dev->dev);868 869	return ret;870}871EXPORT_SYMBOL_NS_GPL(cdx_device_add, CDX_BUS_CONTROLLER);872 873struct device *cdx_bus_add(struct cdx_controller *cdx, u8 bus_num)874{875	struct cdx_device *cdx_dev;876	int ret;877 878	cdx_dev = kzalloc(sizeof(*cdx_dev), GFP_KERNEL);879	if (!cdx_dev)880		return NULL;881 882	device_initialize(&cdx_dev->dev);883	cdx_dev->cdx = cdx;884 885	cdx_dev->dev.parent = cdx->dev;886	cdx_dev->dev.bus = &cdx_bus_type;887	cdx_dev->dev.release = cdx_device_release;888	cdx_dev->is_bus = true;889	cdx_dev->bus_num = bus_num;890 891	dev_set_name(&cdx_dev->dev, "cdx-%02x",892		     ((cdx->id << CDX_CONTROLLER_ID_SHIFT) | (bus_num & CDX_BUS_NUM_MASK)));893 894	ret = device_add(&cdx_dev->dev);895	if (ret) {896		dev_err(&cdx_dev->dev, "cdx bus device add failed: %d\n", ret);897		goto device_add_fail;898	}899 900	if (cdx->ops->bus_enable) {901		ret = cdx->ops->bus_enable(cdx, bus_num);902		if (ret && ret != -EALREADY) {903			dev_err(cdx->dev, "cdx bus enable failed: %d\n", ret);904			goto bus_enable_fail;905		}906	}907 908	cdx_dev->enabled = true;909	return &cdx_dev->dev;910 911bus_enable_fail:912	device_del(&cdx_dev->dev);913device_add_fail:914	put_device(&cdx_dev->dev);915 916	return NULL;917}918EXPORT_SYMBOL_NS_GPL(cdx_bus_add, CDX_BUS_CONTROLLER);919 920int cdx_register_controller(struct cdx_controller *cdx)921{922	int ret;923 924	ret = ida_alloc_range(&cdx_controller_ida, 0,  MAX_CDX_CONTROLLERS - 1, GFP_KERNEL);925	if (ret < 0) {926		dev_err(cdx->dev,927			"No free index available. Maximum controllers already registered\n");928		cdx->id = (u8)MAX_CDX_CONTROLLERS;929		return ret;930	}931 932	mutex_lock(&cdx_controller_lock);933	cdx->id = ret;934 935	/* Scan all the devices */936	if (cdx->ops->scan)937		cdx->ops->scan(cdx);938	cdx->controller_registered = true;939	mutex_unlock(&cdx_controller_lock);940 941	return 0;942}943EXPORT_SYMBOL_NS_GPL(cdx_register_controller, CDX_BUS_CONTROLLER);944 945void cdx_unregister_controller(struct cdx_controller *cdx)946{947	if (cdx->id >= MAX_CDX_CONTROLLERS)948		return;949 950	mutex_lock(&cdx_controller_lock);951 952	cdx->controller_registered = false;953	device_for_each_child(cdx->dev, NULL, cdx_unregister_device);954	ida_free(&cdx_controller_ida, cdx->id);955 956	mutex_unlock(&cdx_controller_lock);957}958EXPORT_SYMBOL_NS_GPL(cdx_unregister_controller, CDX_BUS_CONTROLLER);959 960static int __init cdx_bus_init(void)961{962	int ret;963 964	ret = bus_register(&cdx_bus_type);965	if (!ret)966		cdx_debugfs_dir = debugfs_create_dir(cdx_bus_type.name, NULL);967 968	return ret;969}970postcore_initcall(cdx_bus_init);971