Commit 89eb35e8 authored by Xu Yilun's avatar Xu Yilun Committed by Moritz Fischer

fpga: dfl: map feature mmio resources in their own feature drivers

This patch makes preparation for modularization of DFL sub feature
drivers.

DFL based FPGA devices may contain some IP blocks which are already
supported by kernel, most of them are supported by platform device
drivers. We could create platform devices for these IP blocks and get them
supported by these drivers.

An important issue is that platform device drivers usually requests mmio
resources on probe. But now DFL mmio is mapped in DFL bus driver (e.g.
dfl-pci) as a whole region. Then platform device drivers for sub features
can't request their own mmio resources again. This is what the patch
trying to resolve.

This patch changes the DFL enumeration. DFL bus driver will unmap mmio
resources after first step enumeration and pass enumeration info to DFL
framework. Then DFL framework will map the mmio resources again, do 2nd
step enumeration, and also unmap the mmio resources. In this way, sub
feature drivers could then request their own mmio resources as needed.

An exception is that mmio resource of FIU headers are still mapped in DFL
bus driver. The FIU headers have some fundamental functions (sriov set,
port enable/disable) needed for DFL bus devices and other sub features.
They should not be unmapped as long as DFL bus device is alive.
Signed-off-by: default avatarXu Yilun <yilun.xu@intel.com>
Signed-off-by: default avatarWu Hao <hao.wu@intel.com>
Signed-off-by: default avatarMatthew Gerlach <matthew.gerlach@linux.intel.com>
Signed-off-by: default avatarRuss Weight <russell.h.weight@intel.com>
Reviewed-by: default avatarTom Rix <trix@redhat.com>
Acked-by: default avatarWu Hao <hao.wu@intel.com>
Signed-off-by: default avatarMoritz Fischer <mdf@kernel.org>
parent 4e772ab8
......@@ -31,12 +31,12 @@ struct cci_drvdata {
struct dfl_fpga_cdev *cdev; /* container device */
};
static void __iomem *cci_pci_ioremap_bar(struct pci_dev *pcidev, int bar)
static void __iomem *cci_pci_ioremap_bar0(struct pci_dev *pcidev)
{
if (pcim_iomap_regions(pcidev, BIT(bar), DRV_NAME))
if (pcim_iomap_regions(pcidev, BIT(0), DRV_NAME))
return NULL;
return pcim_iomap_table(pcidev)[bar];
return pcim_iomap_table(pcidev)[0];
}
static int cci_pci_alloc_irq(struct pci_dev *pcidev)
......@@ -156,8 +156,8 @@ static int cci_enumerate_feature_devs(struct pci_dev *pcidev)
goto irq_free_exit;
}
/* start to find Device Feature List from Bar 0 */
base = cci_pci_ioremap_bar(pcidev, 0);
/* start to find Device Feature List in Bar 0 */
base = cci_pci_ioremap_bar0(pcidev);
if (!base) {
ret = -ENOMEM;
goto irq_free_exit;
......@@ -172,7 +172,7 @@ static int cci_enumerate_feature_devs(struct pci_dev *pcidev)
start = pci_resource_start(pcidev, 0);
len = pci_resource_len(pcidev, 0);
dfl_fpga_enum_info_add_dfl(info, start, len, base);
dfl_fpga_enum_info_add_dfl(info, start, len);
/*
* find more Device Feature Lists (e.g. Ports) per information
......@@ -196,26 +196,24 @@ static int cci_enumerate_feature_devs(struct pci_dev *pcidev)
*/
bar = FIELD_GET(FME_PORT_OFST_BAR_ID, v);
offset = FIELD_GET(FME_PORT_OFST_DFH_OFST, v);
base = cci_pci_ioremap_bar(pcidev, bar);
if (!base)
continue;
start = pci_resource_start(pcidev, bar) + offset;
len = pci_resource_len(pcidev, bar) - offset;
dfl_fpga_enum_info_add_dfl(info, start, len,
base + offset);
dfl_fpga_enum_info_add_dfl(info, start, len);
}
} else if (dfl_feature_is_port(base)) {
start = pci_resource_start(pcidev, 0);
len = pci_resource_len(pcidev, 0);
dfl_fpga_enum_info_add_dfl(info, start, len, base);
dfl_fpga_enum_info_add_dfl(info, start, len);
} else {
ret = -ENODEV;
goto irq_free_exit;
}
/* release I/O mappings for next step enumeration */
pcim_iounmap_regions(pcidev, BIT(0));
/* start enumeration with prepared enumeration information */
cdev = dfl_fpga_feature_devs_enumerate(info);
if (IS_ERR(cdev)) {
......
This diff is collapsed.
......@@ -441,22 +441,17 @@ struct dfl_fpga_enum_info {
*
* @start: base address of this device feature list.
* @len: size of this device feature list.
* @ioaddr: mapped base address of this device feature list.
* @node: node in list of device feature lists.
*/
struct dfl_fpga_enum_dfl {
resource_size_t start;
resource_size_t len;
void __iomem *ioaddr;
struct list_head node;
};
struct dfl_fpga_enum_info *dfl_fpga_enum_info_alloc(struct device *dev);
int dfl_fpga_enum_info_add_dfl(struct dfl_fpga_enum_info *info,
resource_size_t start, resource_size_t len,
void __iomem *ioaddr);
resource_size_t start, resource_size_t len);
int dfl_fpga_enum_info_add_irq(struct dfl_fpga_enum_info *info,
unsigned int nr_irqs, int *irq_table);
void dfl_fpga_enum_info_free(struct dfl_fpga_enum_info *info);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment