Lines Matching +full:fpga +full:- +full:region
1 // SPDX-License-Identifier: GPL-2.0
3 * Driver for FPGA Device Feature List (DFL) Support
5 * Copyright (C) 2017-2018 Intel Corporation, Inc.
14 #include <linux/fpga-dfl.h>
44 "dfl-fme-pdata",
45 "dfl-port-pdata",
49 * struct dfl_dev_info - dfl feature device information.
71 * struct dfl_chardev_info - chardev information of dfl feature device
137 * in virtualization case of PCIe-based FPGA DFL device, when SRIOV is
139 * is hidden from system but it's still required to access port to finish FPGA
147 * dfl_fpga_port_ops_get - get matched port ops from the global list
163 if (!strcmp(fdata->pdev_name, ops->name)) {
164 if (!try_module_get(ops->owner))
178 * dfl_fpga_port_ops_put - put port ops
183 if (ops && ops->owner)
184 module_put(ops->owner);
189 * dfl_fpga_port_ops_add - add port_ops to global list
195 list_add_tail(&ops->node, &dfl_port_ops_list);
201 * dfl_fpga_port_ops_del - remove port_ops from global list
207 list_del(&ops->node);
213 * dfl_fpga_check_port_id - check the port id
223 if (fdata->id != FEATURE_DEV_ID_UNUSED)
224 return fdata->id == *(int *)pport_id;
227 if (!port_ops || !port_ops->get_id)
230 fdata->id = port_ops->get_id(fdata);
233 return fdata->id == *(int *)pport_id;
242 if (id->type == ddev->type && id->feature_id == ddev->feature_id)
254 id_entry = ddrv->id_table;
256 while (id_entry->feature_id) {
258 ddev->id_entry = id_entry;
270 struct dfl_driver *ddrv = to_dfl_drv(dev->driver);
273 return ddrv->probe(ddev);
278 struct dfl_driver *ddrv = to_dfl_drv(dev->driver);
281 if (ddrv->remove)
282 ddrv->remove(ddev);
290 ddev->type, ddev->feature_id);
298 return sprintf(buf, "0x%x\n", ddev->type);
307 return sprintf(buf, "0x%x\n", ddev->feature_id);
331 if (ddev->mmio_res.parent)
332 release_resource(&ddev->mmio_res);
334 kfree(ddev->params);
336 ida_free(&dfl_device_ida, ddev->id);
337 kfree(ddev->irqs);
345 struct platform_device *pdev = fdata->dev;
352 return ERR_PTR(-ENOMEM);
356 dev_err(&pdev->dev, "unable to get id\n");
362 device_initialize(&ddev->dev);
363 ddev->dev.parent = &pdev->dev;
364 ddev->dev.bus = &dfl_bus_type;
365 ddev->dev.release = release_dfl_dev;
366 ddev->id = id;
367 ret = dev_set_name(&ddev->dev, "dfl_dev.%d", id);
371 ddev->type = fdata->type;
372 ddev->feature_id = feature->id;
373 ddev->revision = feature->revision;
374 ddev->dfh_version = feature->dfh_version;
375 ddev->cdev = fdata->dfl_cdev;
376 if (feature->param_size) {
377 ddev->params = kmemdup(feature->params, feature->param_size, GFP_KERNEL);
378 if (!ddev->params) {
379 ret = -ENOMEM;
382 ddev->param_size = feature->param_size;
386 parent_res = &pdev->resource[feature->resource_index];
387 ddev->mmio_res.flags = IORESOURCE_MEM;
388 ddev->mmio_res.start = parent_res->start;
389 ddev->mmio_res.end = parent_res->end;
390 ddev->mmio_res.name = dev_name(&ddev->dev);
391 ret = insert_resource(parent_res, &ddev->mmio_res);
393 dev_err(&pdev->dev, "%s failed to claim resource: %pR\n",
394 dev_name(&ddev->dev), &ddev->mmio_res);
399 if (feature->nr_irqs) {
400 ddev->irqs = kcalloc(feature->nr_irqs,
401 sizeof(*ddev->irqs), GFP_KERNEL);
402 if (!ddev->irqs) {
403 ret = -ENOMEM;
407 for (i = 0; i < feature->nr_irqs; i++)
408 ddev->irqs[i] = feature->irq_ctx[i].irq;
410 ddev->num_irqs = feature->nr_irqs;
413 ret = device_add(&ddev->dev);
417 dev_dbg(&pdev->dev, "add dfl_dev: %s\n", dev_name(&ddev->dev));
422 put_device(&ddev->dev);
431 if (feature->ddev) {
432 device_unregister(&feature->ddev->dev);
433 feature->ddev = NULL;
445 if (feature->ioaddr)
448 if (feature->ddev) {
449 ret = -EEXIST;
459 feature->ddev = ddev;
471 if (!dfl_drv || !dfl_drv->probe || !dfl_drv->id_table)
472 return -EINVAL;
474 dfl_drv->drv.owner = owner;
475 dfl_drv->drv.bus = &dfl_bus_type;
477 return driver_register(&dfl_drv->drv);
483 driver_unregister(&dfl_drv->drv);
487 #define is_header_feature(feature) ((feature)->id == FEATURE_ID_FIU_HEADER)
490 * dfl_fpga_dev_feature_uinit - uinit for sub features of dfl feature device
495 struct dfl_feature_dev_data *fdata = to_dfl_feature_dev_data(&pdev->dev);
501 if (feature->ops) {
502 if (feature->ops->uinit)
503 feature->ops->uinit(pdev, feature);
504 feature->ops = NULL;
519 feature->resource_index);
521 dev_err(&pdev->dev,
523 feature->id);
527 feature->ioaddr = base;
530 if (drv->ops->init) {
531 ret = drv->ops->init(pdev, feature);
536 feature->ops = drv->ops;
544 const struct dfl_feature_id *ids = driver->id_table;
547 while (ids->id) {
548 if (ids->id == feature->id)
557 * dfl_fpga_dev_feature_init - init for sub features of dfl feature device
569 struct dfl_feature_dev_data *fdata = to_dfl_feature_dev_data(&pdev->dev);
574 while (drv->ops) {
635 * dfl_fpga_dev_ops_register - register cdev ops for feature dev
647 struct dfl_feature_platform_data *pdata = dev_get_platdata(&pdev->dev);
649 cdev_init(&pdata->cdev, fops);
650 pdata->cdev.owner = owner;
656 * file's life-cycle.
658 pdata->cdev.kobj.parent = &pdev->dev.kobj;
660 return cdev_add(&pdata->cdev, pdev->dev.devt, 1);
665 * dfl_fpga_dev_ops_unregister - unregister cdev ops for feature dev
670 struct dfl_feature_platform_data *pdata = dev_get_platdata(&pdev->dev);
672 cdev_del(&pdata->cdev);
677 * struct build_feature_devs_info - info collected during feature dev build.
685 * @ioaddr: header register region address of current FIU in enumeration.
706 * struct dfl_feature_info - sub feature info collected during feature dev build
735 mutex_lock(&cdev->lock);
736 list_add(&fdata->node, &cdev->port_dev_list);
737 mutex_unlock(&cdev->lock);
744 dfl_id_free(fdata->type, fdata->pdev_id);
750 enum dfl_id_type type = binfo->type;
756 return ERR_PTR(-EINVAL);
758 fdata = devm_kzalloc(binfo->dev, sizeof(*fdata), GFP_KERNEL);
760 return ERR_PTR(-ENOMEM);
762 fdata->features = devm_kcalloc(binfo->dev, binfo->feature_num,
763 sizeof(*fdata->features), GFP_KERNEL);
764 if (!fdata->features)
765 return ERR_PTR(-ENOMEM);
767 fdata->resources = devm_kcalloc(binfo->dev, binfo->feature_num,
768 sizeof(*fdata->resources), GFP_KERNEL);
769 if (!fdata->resources)
770 return ERR_PTR(-ENOMEM);
772 fdata->type = type;
774 fdata->pdev_id = dfl_id_alloc(type, binfo->dev);
775 if (fdata->pdev_id < 0)
776 return ERR_PTR(fdata->pdev_id);
778 ret = devm_add_action_or_reset(binfo->dev, dfl_id_free_action, fdata);
782 fdata->pdev_name = dfl_devs[type].name;
783 fdata->num = binfo->feature_num;
784 fdata->dfl_cdev = binfo->cdev;
785 fdata->id = FEATURE_DEV_ID_UNUSED;
786 mutex_init(&fdata->lock);
787 lockdep_set_class_and_name(&fdata->lock, &dfl_pdata_keys[type],
796 WARN_ON(fdata->disable_count);
799 list_for_each_entry_safe(finfo, p, &binfo->sub_features, node) {
800 struct dfl_feature *feature = &fdata->features[index++];
805 feature->id = finfo->fid;
806 feature->revision = finfo->revision;
807 feature->dfh_version = finfo->dfh_version;
809 if (finfo->param_size) {
810 feature->params = devm_kmemdup(binfo->dev,
811 finfo->params, finfo->param_size,
813 if (!feature->params)
814 return ERR_PTR(-ENOMEM);
816 feature->param_size = finfo->param_size;
823 * devices (dfl-fme/afu) again.
826 feature->resource_index = -1;
827 feature->ioaddr =
828 devm_ioremap_resource(binfo->dev,
829 &finfo->mmio_res);
830 if (IS_ERR(feature->ioaddr))
831 return ERR_CAST(feature->ioaddr);
833 feature->resource_index = res_idx;
834 fdata->resources[res_idx++] = finfo->mmio_res;
837 if (finfo->nr_irqs) {
838 ctx = devm_kcalloc(binfo->dev, finfo->nr_irqs,
841 return ERR_PTR(-ENOMEM);
843 for (i = 0; i < finfo->nr_irqs; i++)
845 binfo->irq_table[finfo->irq_base + i];
847 feature->irq_ctx = ctx;
848 feature->nr_irqs = finfo->nr_irqs;
851 list_del(&finfo->node);
855 fdata->resource_num = res_idx;
872 fdev = platform_device_alloc(fdata->pdev_name, fdata->pdev_id);
874 return -ENOMEM;
876 fdata->dev = fdev;
878 fdev->dev.parent = &fdata->dfl_cdev->region->dev;
879 fdev->dev.devt = dfl_get_devt(dfl_devs[fdata->type].devt_type, fdev->id);
882 feature->dev = fdev;
884 ret = platform_device_add_resources(fdev, fdata->resources,
885 fdata->resource_num);
903 fdata->dev = NULL;
906 feature->dev = NULL;
915 platform_device_unregister(fdata->dev);
917 fdata->dev = NULL;
920 feature->dev = NULL;
936 if (binfo->type == PORT_ID)
937 dfl_fpga_cdev_add_port_data(binfo->cdev, fdata);
939 binfo->cdev->fme_dev = get_device(&fdata->dev->dev);
942 binfo->type = DFL_ID_MAX;
951 list_for_each_entry_safe(finfo, p, &binfo->sub_features, node) {
952 list_del(&finfo->node);
956 devm_kfree(binfo->dev, binfo);
1003 * dfh_find_param() - find parameter block for the given parameter id
1012 u64 *phdr = find_param(dfl_dev->params, dfl_dev->param_size, param_id);
1015 return ERR_PTR(-ENOENT);
1018 *psize = (FIELD_GET(DFHv1_PARAM_HDR_NEXT_OFFSET, *phdr) - 1) * sizeof(u64);
1027 void __iomem *base = binfo->ioaddr + ofst;
1029 void *params = finfo->params;
1031 u16 fid = finfo->fid;
1036 switch (finfo->dfh_version) {
1044 type = binfo->type;
1074 p = find_param(params, finfo->param_size, DFHv1_PARAM_ID_MSI_X);
1084 dev_warn(binfo->dev, "unexpected DFH version %d\n", finfo->dfh_version);
1089 finfo->irq_base = 0;
1090 finfo->nr_irqs = 0;
1094 dev_dbg(binfo->dev, "feature: 0x%x, irq_base: %u, nr_irqs: %u\n",
1097 if (ibase + inr > binfo->nr_irqs) {
1098 dev_err(binfo->dev,
1100 return -EINVAL;
1104 virq = binfo->irq_table[ibase + i];
1106 dev_err(binfo->dev,
1109 return -EINVAL;
1113 finfo->irq_base = ibase;
1114 finfo->nr_irqs = inr;
1133 return -EINVAL;
1141 return -ENOENT;
1147 * register. For afu sub feature, its register region only contains user
1164 v = readq(binfo->ioaddr + ofst);
1171 dfh_psize = dfh_get_param_size(binfo->ioaddr + ofst, size);
1173 dev_err(binfo->dev,
1178 dev_dbg(binfo->dev, "dfhv1_psize %d\n", dfh_psize);
1182 if (binfo->len - ofst < size)
1183 return -EINVAL;
1187 return -ENOMEM;
1189 memcpy_fromio(finfo->params, binfo->ioaddr + ofst + DFHv1_PARAM_HDR, dfh_psize);
1190 finfo->param_size = dfh_psize;
1192 finfo->fid = fid;
1193 finfo->revision = revision;
1194 finfo->dfh_version = dfh_ver;
1196 v = readq(binfo->ioaddr + ofst + DFHv1_CSR_ADDR);
1201 start = binfo->start + ofst + addr_off;
1203 v = readq(binfo->ioaddr + ofst + DFHv1_CSR_SIZE_GRP);
1204 end = start + FIELD_GET(DFHv1_CSR_SIZE_GRP_SIZE, v) - 1;
1206 start = binfo->start + ofst;
1207 end = start + size - 1;
1209 finfo->mmio_res.flags = IORESOURCE_MEM;
1210 finfo->mmio_res.start = start;
1211 finfo->mmio_res.end = end;
1219 list_add_tail(&finfo->node, &binfo->sub_features);
1220 binfo->feature_num++;
1228 u64 v = readq(binfo->ioaddr + PORT_HDR_CAP);
1236 #define is_feature_dev_detected(binfo) ((binfo)->type != DFL_ID_MAX)
1242 dev_err(binfo->dev, "this AFU does not belong to any FIU.\n");
1243 return -EINVAL;
1246 switch (binfo->type) {
1250 dev_info(binfo->dev, "AFU belonging to FIU is not supported yet.\n");
1259 struct device *dev = binfo->dev;
1263 dev_err(dev, "request region fail, start:%pa, len:%pa\n",
1265 return -EBUSY;
1270 dev_err(dev, "ioremap region fail, start:%pa, len:%pa\n",
1272 return -ENOMEM;
1275 binfo->start = start;
1276 binfo->len = len;
1277 binfo->ioaddr = ioaddr;
1284 devm_iounmap(binfo->dev, binfo->ioaddr);
1285 devm_release_mem_region(binfo->dev, binfo->start, binfo->len);
1304 ret = build_info_prepare(binfo, binfo->start + ofst,
1305 binfo->len - ofst);
1310 v = readq(binfo->ioaddr + DFH);
1315 return -EINVAL;
1317 binfo->type = type;
1318 binfo->feature_num = 0;
1319 INIT_LIST_HEAD(&binfo->sub_features);
1328 v = readq(binfo->ioaddr + NEXT_AFU);
1334 dev_dbg(binfo->dev, "No AFUs detected on FIU %d\n", id);
1343 dev_err(binfo->dev, "the private feature 0x%x does not belong to any AFU.\n",
1344 feature_id(readq(binfo->ioaddr + ofst)));
1345 return -EINVAL;
1352 * parse_feature - parse a feature on given device feature list
1363 v = readq(binfo->ioaddr + ofst + DFH);
1374 dev_info(binfo->dev,
1395 if (end - start < DFH_SIZE) {
1396 dev_err(binfo->dev, "The region is too small to contain a feature.\n");
1397 return -EINVAL;
1400 ret = parse_feature(binfo, start - binfo->start);
1404 v = readq(binfo->ioaddr + start - binfo->start + DFH);
1433 info->dev = dev;
1434 INIT_LIST_HEAD(&info->dfls);
1448 dev = info->dev;
1451 list_for_each_entry_safe(dfl, tmp, &info->dfls, node) {
1452 list_del(&dfl->node);
1457 if (info->irq_table)
1458 devm_kfree(dev, info->irq_table);
1466 * dfl_fpga_enum_info_add_dfl - add info of a device feature list to enum info
1472 * One FPGA device may have one or more Device Feature Lists (DFLs), use this
1483 dfl = devm_kzalloc(info->dev, sizeof(*dfl), GFP_KERNEL);
1485 return -ENOMEM;
1487 dfl->start = start;
1488 dfl->len = len;
1490 list_add_tail(&dfl->node, &info->dfls);
1497 * dfl_fpga_enum_info_add_irq - add irq table to enum info
1500 * @nr_irqs: number of irqs of the DFL fpga device to be enumerated.
1504 * One FPGA device may have several interrupts. This function adds irq
1505 * information of the DFL fpga device to enum info for next step enumeration.
1519 return -EINVAL;
1521 if (info->irq_table)
1522 return -EEXIST;
1524 info->irq_table = devm_kmemdup(info->dev, irq_table,
1526 if (!info->irq_table)
1527 return -ENOMEM;
1529 info->nr_irqs = nr_irqs;
1546 device_for_each_child(&cdev->region->dev, NULL, remove_feature_dev);
1550 * dfl_fpga_feature_devs_enumerate - enumerate feature devices
1553 * This function creates a container device (base FPGA region), enumerates
1557 * Return: dfl_fpga_cdev struct on success, -errno on failure
1567 if (!info->dev)
1568 return ERR_PTR(-ENODEV);
1570 cdev = devm_kzalloc(info->dev, sizeof(*cdev), GFP_KERNEL);
1572 return ERR_PTR(-ENOMEM);
1574 cdev->parent = info->dev;
1575 mutex_init(&cdev->lock);
1576 INIT_LIST_HEAD(&cdev->port_dev_list);
1578 cdev->region = fpga_region_register(info->dev, NULL, NULL);
1579 if (IS_ERR(cdev->region)) {
1580 ret = PTR_ERR(cdev->region);
1585 binfo = devm_kzalloc(info->dev, sizeof(*binfo), GFP_KERNEL);
1587 ret = -ENOMEM;
1591 binfo->type = DFL_ID_MAX;
1592 binfo->dev = info->dev;
1593 binfo->cdev = cdev;
1595 binfo->nr_irqs = info->nr_irqs;
1596 if (info->nr_irqs)
1597 binfo->irq_table = info->irq_table;
1603 list_for_each_entry(dfl, &info->dfls, node) {
1604 ret = parse_feature_list(binfo, dfl->start, dfl->len);
1617 fpga_region_unregister(cdev->region);
1619 devm_kfree(info->dev, cdev);
1625 * dfl_fpga_feature_devs_remove - remove all feature devices
1626 * @cdev: fpga container device.
1633 mutex_lock(&cdev->lock);
1634 if (cdev->fme_dev)
1635 put_device(cdev->fme_dev);
1637 mutex_unlock(&cdev->lock);
1641 fpga_region_unregister(cdev->region);
1642 devm_kfree(cdev->parent, cdev);
1647 * __dfl_fpga_cdev_find_port_data - find a port under given container device
1666 list_for_each_entry(fdata, &cdev->port_dev_list, node) {
1695 * dfl_fpga_cdev_release_port - release a port platform device
1708 int ret = -ENODEV;
1710 mutex_lock(&cdev->lock);
1716 if (!fdata->dev) {
1717 ret = -EBUSY;
1721 mutex_lock(&fdata->lock);
1723 mutex_unlock(&fdata->lock);
1728 cdev->released_port_num++;
1730 mutex_unlock(&cdev->lock);
1736 * dfl_fpga_cdev_assign_port - assign a port platform device back
1749 int ret = -ENODEV;
1751 mutex_lock(&cdev->lock);
1757 if (fdata->dev) {
1758 ret = -EBUSY;
1766 mutex_lock(&fdata->lock);
1768 mutex_unlock(&fdata->lock);
1770 cdev->released_port_num--;
1772 mutex_unlock(&cdev->lock);
1799 * dfl_fpga_cdev_config_ports_pf - configure ports to PF access mode
1810 mutex_lock(&cdev->lock);
1811 list_for_each_entry(fdata, &cdev->port_dev_list, node) {
1812 if (fdata->dev)
1815 config_port_pf_mode(cdev->fme_dev, fdata->id);
1817 mutex_unlock(&cdev->lock);
1822 * dfl_fpga_cdev_config_ports_vf - configure ports to VF access mode
1837 mutex_lock(&cdev->lock);
1841 * then reject the request with -EINVAL error code.
1843 if (cdev->released_port_num != num_vfs) {
1844 ret = -EINVAL;
1848 list_for_each_entry(fdata, &cdev->port_dev_list, node) {
1849 if (fdata->dev)
1852 config_port_vf_mode(cdev->fme_dev, fdata->id);
1855 mutex_unlock(&cdev->lock);
1871 struct platform_device *pdev = feature->dev;
1875 irq = feature->irq_ctx[idx].irq;
1877 if (feature->irq_ctx[idx].trigger) {
1878 free_irq(irq, feature->irq_ctx[idx].trigger);
1879 kfree(feature->irq_ctx[idx].name);
1880 eventfd_ctx_put(feature->irq_ctx[idx].trigger);
1881 feature->irq_ctx[idx].trigger = NULL;
1887 feature->irq_ctx[idx].name =
1888 kasprintf(GFP_KERNEL, "fpga-irq[%u](%s-%x)", idx,
1889 dev_name(&pdev->dev), feature->id);
1890 if (!feature->irq_ctx[idx].name)
1891 return -ENOMEM;
1900 feature->irq_ctx[idx].name, trigger);
1902 feature->irq_ctx[idx].trigger = trigger;
1908 kfree(feature->irq_ctx[idx].name);
1914 * dfl_fpga_set_irq_triggers - set eventfd triggers for dfl feature interrupts
1936 return -EINVAL;
1939 if (start + count > feature->nr_irqs)
1940 return -EINVAL;
1943 int fd = fds ? fds[i] : -1;
1947 while (i--)
1948 do_set_irq_trigger(feature, start + i, -1);
1958 * dfl_feature_ioctl_get_num_irqs - dfl feature _GET_IRQ_NUM ioctl interface.
1969 return put_user(feature->nr_irqs, (__u32 __user *)arg);
1974 * dfl_feature_ioctl_set_irq - dfl feature _SET_IRQ ioctl interface.
1985 struct dfl_feature_dev_data *fdata = to_dfl_feature_dev_data(&pdev->dev);
1990 if (!feature->nr_irqs)
1991 return -ENOENT;
1994 return -EFAULT;
1996 if (!hdr.count || (hdr.start + hdr.count > feature->nr_irqs) ||
1998 return -EINVAL;
2005 mutex_lock(&fdata->lock);
2007 mutex_unlock(&fdata->lock);
2024 MODULE_DESCRIPTION("FPGA Device Feature List (DFL) Support");