From 556445101b940d81b7d5b4026a183ac7f4091684 Mon Sep 17 00:00:00 2001 From: Basheer Ahmed Muddebihal Date: Mon, 2 Oct 2023 13:21:18 -0700 Subject: [PATCH 01/12] uuid: Add helper functions to parse and compare GUID/UUID Added the helper functions to parse the passed character string to GUID/UUID and compare with passed GUID. Signed-off-by: Basheer Ahmed Muddebihal --- include/linux/uuid.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 include/linux/uuid.h diff --git a/include/linux/uuid.h b/include/linux/uuid.h new file mode 100644 index 00000000..5a533c20 --- /dev/null +++ b/include/linux/uuid.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef __BACKPORT_UUID_H +#define __BACKPORT_UUID_H + +#include +#include_next + +static inline +bool guid_parse_and_compare(const char *string, const guid_t *guid) +{ + guid_t guid_input; + if (guid_parse(string, &guid_input)) + return false; + return guid_equal(&guid_input, guid); +} + +static inline +bool uuid_parse_and_compare(const char *string, const uuid_t *uuid) +{ + uuid_t uuid_input; + if (uuid_parse(string, &uuid_input)) + return false; + return uuid_equal(&uuid_input, uuid); +} + +#endif From c0ebd835505167a274f719f90d45e66220c0ad32 Mon Sep 17 00:00:00 2001 From: Basheer Ahmed Muddebihal Date: Tue, 19 Jul 2022 13:53:03 -0700 Subject: [PATCH 02/12] fpga: dfl: Add GUID support in mod device table In the modalias table, dfl devices use the type id and feature id to create the dfl device string entry "dfl:t0000f0009*". This patch adds support for the use of a GUID for dfl devices. Device drivers may match on type id and feature id, on the GUID, or on a combination of the type id, feature id and GUID. If the feature id and GUID are both non-zero, then the modalias string is: "dfl:t0000f0009g{03020100-0504-0706-0809-0A0B0C0D0E0F}*" If the feature id is zero and the GUID is non-zero, then the string is: "dfl:t*f*g{03020100-0504-0706-0809-0A0B0C0D0E0F}*" If the feature id is non-zero and the GUID is zero, then the string is "dfl:t0000f0009*" Followed the concept of the wmi device ID to define the GUID in string format and reuse the existing GUID infrastructure. Signed-off-by: Basheer Ahmed Muddebihal --- include/linux/mod_devicetable.h | 3 ++- scripts/mod/devicetable-offsets.c | 2 +- scripts/mod/file2alias.c | 27 ++++++++++++++------------- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index af5a9710..cc44214f 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -28,13 +28,14 @@ * @type: DFL FIU type of the device. See enum dfl_id_type. * @feature_id: feature identifier local to its DFL FIU type. * @driver_data: driver specific data. + * @guid_string: 36 char string of the form 03020100-0504-0706-0809-0A0B0C0D0E0F */ #define dfl_device_id BACKPORT_dfl_device_id struct BACKPORT_dfl_device_id { __u16 type; __u16 feature_id; - guid_t guid; kernel_ulong_t driver_data; + const char guid_string[UUID_STRING_LEN + 1]; }; #endif /* BACKPORT_LINUX_MOD_DEVICETABLE_H */ diff --git a/scripts/mod/devicetable-offsets.c b/scripts/mod/devicetable-offsets.c index 993394b2..eaf79aec 100644 --- a/scripts/mod/devicetable-offsets.c +++ b/scripts/mod/devicetable-offsets.c @@ -246,7 +246,7 @@ int main(void) DEVID(dfl_device_id); DEVID_FIELD(dfl_device_id, type); DEVID_FIELD(dfl_device_id, feature_id); - DEVID_FIELD(dfl_device_id, guid); + DEVID_FIELD(dfl_device_id, guid_string); return 0; } diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 0d0df135..4389b3a0 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -1379,32 +1379,33 @@ static int do_mhi_entry(const char *filename, void *symval, char *alias) return 1; } -/* Looks like: dfl:tNfNg{guid} */ +/* Looks like: dfl:tNfNg{GUID} */ static int do_dfl_entry(const char *filename, void *symval, char *alias) { - int guid_cmp_val; - guid_t null_guid = {0}; + bool with_guid = true; + int len; DEF_FIELD(symval, dfl_device_id, type); DEF_FIELD(symval, dfl_device_id, feature_id); - DEF_FIELD(symval, dfl_device_id, guid); + DEF_FIELD_ADDR(symval, dfl_device_id, guid_string); - guid_cmp_val = memcmp(&null_guid, &guid, sizeof(guid_t)); + if (__uuid_is_valid(*guid_string) < 0) + with_guid = false; - if (feature_id == 0 && guid_cmp_val == 0) { - warn("Invalid dfl Device ID for in '%s'\n", filename); + if (feature_id == 0 && !with_guid) { + warn("Invalid dfl Device ID in '%s'\n", filename); return 0; } if (feature_id == 0) - strcpy(alias, "dfl:t*f*"); + len = snprintf(alias, ALIAS_SIZE, "dfl:t*f*"); else - snprintf(alias, ALIAS_SIZE, "dfl:t%04Xf%04X", type, feature_id); + len = snprintf(alias, ALIAS_SIZE, "dfl:t%04Xf%04X", type, feature_id); - if (guid_cmp_val) { - strcat(alias + strlen(alias), "g{"); - add_guid(alias, guid); - strcat(alias + strlen(alias), "}"); + if(with_guid) { + __uuid_uppercase((char *)guid_string); + snprintf(alias + len, ALIAS_SIZE - len, "g{%s}", *guid_string); } + add_wildcard(alias); return 1; } From 352c2d1ae7210ae53ba9239bebe476053a3a0b31 Mon Sep 17 00:00:00 2001 From: Basheer Ahmed Muddebihal Date: Mon, 28 Nov 2022 15:03:35 -0800 Subject: [PATCH 03/12] fpga: dfl: Add feature device driver match by GUID This patch introduces changes to enhance the identification and matching of features in the Device Feature List (DFL) using GUID (Globally Unique Identifier). The use of GUID allows for an infinite pool of feature IDs, and decentralized allocation, and enables the matching of DFL devices with their respective drivers based on GUID. This mechanism allows customers to match their custom IP with the desired or required driver. Changes made in this patch: 1. Modified the UEVENT string to reflect GUID matching, ensuring compatibility with the updated identification method. 2. Added system entries to display the GUID in Little Endian format, facilitating the interpretation of the GUID value. 3. Included wrapper functions for GUID matching and Feature ID matching, enabling the comparison and matching of GUIDs and feature. Signed-off-by: Basheer Ahmed Muddebihal --- Documentation/ABI/testing/sysfs-bus-dfl | 9 +++++ drivers/fpga/dfl.c | 53 ++++++++++++++----------- drivers/fpga/dfl.h | 46 ++++++++++----------- include/linux/dfl.h | 3 +- 4 files changed, 62 insertions(+), 49 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-bus-dfl b/Documentation/ABI/testing/sysfs-bus-dfl index b0265ab1..4d09774f 100644 --- a/Documentation/ABI/testing/sysfs-bus-dfl +++ b/Documentation/ABI/testing/sysfs-bus-dfl @@ -15,3 +15,12 @@ Description: Read-only. It returns feature identifier local to its DFL FIU type. Format: 0x%x + +What: /sys/bus/dfl/devices/dfl_dev.X/guid +Date: Nov 2023 +KernelVersion: 6.6 +Contact: Basheer Ahmed Muddebihal +Description: Read-only. It returns DFL feature identifier in the form GUID + (8-4-4-4-12) if the feature header version is 1(DFHv1). + + Format: 03020100-0504-0706-0809-0A0B0C0D0E0F (Little Endian) diff --git a/drivers/fpga/dfl.c b/drivers/fpga/dfl.c index 036a397d..36bdbdec 100644 --- a/drivers/fpga/dfl.c +++ b/drivers/fpga/dfl.c @@ -244,11 +244,23 @@ EXPORT_SYMBOL_GPL(dfl_fpga_check_port_id); static DEFINE_IDA(dfl_device_ida); +static bool dfl_feature_id_is_match(const struct dfl_device_id *id, struct dfl_device *ddev) +{ + return id->type == ddev->type && id->feature_id == ddev->feature_id; +} + +static bool dfl_guid_is_match(const char *guid_str, const guid_t *guid_dev) +{ + return dfl_guid_is_valid(guid_dev) && guid_parse_and_compare(guid_str, guid_dev); +} + static const struct dfl_device_id * dfl_match_one_device(const struct dfl_device_id *id, struct dfl_device *ddev) { - if ((dfl_guid_is_valid(&ddev->guid) && guid_equal(&id->guid, &ddev->guid)) || - (id->type == ddev->type && id->feature_id == ddev->feature_id)) + if (dfl_guid_is_match(id->guid_string, &ddev->guid)) + return id; + + if (dfl_feature_id_is_match(id, ddev)) return id; return NULL; @@ -262,7 +274,7 @@ static int dfl_bus_match(struct device *dev, struct device_driver *drv) id_entry = ddrv->id_table; if (id_entry) { - while (id_entry->feature_id || dfl_guid_is_valid(&id_entry->guid)) { + while (id_entry->feature_id || *id_entry->guid_string) { if (dfl_match_one_device(id_entry, ddev)) { ddev->id_entry = id_entry; return 1; @@ -312,12 +324,14 @@ static int dfl_bus_uevent(const struct device *dev, struct kobj_uevent_env *env) #else const struct dfl_device *ddev = to_dfl_dev(dev); #endif - char alias[DFL_ALIAS_BUF_LEN]; - - scnprintf(alias, DFL_ALIAS_BUF_LEN, "dfl:t%04Xf%04X", ddev->type, ddev->feature_id); + char alias[sizeof("dfl:tXXXXfXXXXg{}") + UUID_STRING_LEN]; - if (!guid_is_null(&ddev->guid)) - scnprintf(alias + strlen(alias), DFL_ALIAS_BUF_LEN, "g{%pUL}", &ddev->guid); + if (guid_is_null(&ddev->guid)) + snprintf(alias, sizeof("dfl:tXXXXfXXXX"), "dfl:t%04Xf%04X", + ddev->type, ddev->feature_id); + else + snprintf(alias,sizeof("dfl:tXXXXfXXXXg{}") + UUID_STRING_LEN, + "dfl:t%04Xf%04Xg{%pUL}", ddev->type, ddev->feature_id, &ddev->guid); return add_uevent_var(env, "MODALIAS=%s", alias); } @@ -427,6 +441,9 @@ dfl_dev_add(struct dfl_feature_dev_data *fdata, ddev->param_size = feature->param_size; } + if (ddev->dfh_version == 1) + guid_copy(&ddev->guid, &feature->guid); + if (ddev->dfh_version == 1) guid_copy(&ddev->guid, &feature->guid); @@ -771,7 +788,7 @@ struct build_feature_devs_info { * @fid: id of this sub feature. * @revision: revision of this sub feature * @dfh_version: device feature header version. - * @guid: guid of this sub feature. + * @guid: GUID of this sub feature. * @mmio_res: mmio resource of this sub feature. * @ioaddr: mapped base address of mmio resource. * @node: node in sub_features linked list. @@ -1341,22 +1358,10 @@ create_feature_instance(struct build_feature_devs_info *binfo, guid_l = readq(binfo->ioaddr + ofst + GUID_L); guid_h = readq(binfo->ioaddr + ofst + GUID_H); + finfo->guid = dfl_guid_init(guid_h, guid_l); + dev_dbg(binfo->dev, "dfl: GUID_H = 0x%llx , GUID_L = 0x%llx\n GUID = %pUL\n", + guid_h, guid_l, &finfo->guid); - if (guid_l || guid_h) { - dev_dbg(binfo->dev, "dfl: GUID_H = 0x%llx , GUID_L = 0x%llx\n", - guid_h, guid_l); - finfo->guid = GUID_INIT(FIELD_GET(DFL_GUID_H_A, guid_h), - FIELD_GET(DFL_GUID_H_B, guid_h), - FIELD_GET(DFL_GUID_H_C, guid_h), - FIELD_GET(DFL_GUID_L_D0, guid_l), - FIELD_GET(DFL_GUID_L_D1, guid_l), - FIELD_GET(DFL_GUID_L_D2, guid_l), - FIELD_GET(DFL_GUID_L_D3, guid_l), - FIELD_GET(DFL_GUID_L_D4, guid_l), - FIELD_GET(DFL_GUID_L_D5, guid_l), - FIELD_GET(DFL_GUID_L_D6, guid_l), - FIELD_GET(DFL_GUID_L_D7, guid_l)); - } } else { start = binfo->start + ofst; end = start + size - 1; diff --git a/drivers/fpga/dfl.h b/drivers/fpga/dfl.h index 32fb9c19..1e8c6aa0 100644 --- a/drivers/fpga/dfl.h +++ b/drivers/fpga/dfl.h @@ -239,7 +239,7 @@ int dfl_fpga_check_port_id(struct dfl_feature_dev_data *fdata, void *pport_id); * struct dfl_feature_id - dfl private feature id * * @id: unique dfl private feature id. - * @guid: unique dfl private guid. + * @guid: unique dfl private GUID. */ struct dfl_feature_id { u16 id; @@ -285,6 +285,7 @@ struct dfl_feature_irq_ctx { * @ops: ops of this sub feature. * @ddev: ptr to the dfl device of this sub feature. * @priv: priv data of this feature. + * @guid: sub feature GUID. * @dfh_version: version of the DFH * @param_size: size of dfh parameters * @params: point to memory copy of dfh parameters @@ -301,10 +302,10 @@ struct dfl_feature { const struct dfl_feature_ops *ops; struct dfl_device *ddev; void *priv; + guid_t guid; u8 dfh_version; unsigned int param_size; void *params; - guid_t guid; }; #define FEATURE_DEV_ID_UNUSED (-1) @@ -508,34 +509,31 @@ static inline u8 dfl_feature_revision(void __iomem *base) return (u8)FIELD_GET(DFH_REVISION, readq(base + DFH)); } -#define DFL_GUID_INVALID \ - GUID_INIT(0xffffffff, 0xffff, 0xffff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff) +#define DFL_GUID_INVALID \ + GUID_INIT(0xffffffff, 0xffff, 0xffff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff) static inline bool dfl_guid_is_valid(const guid_t *guid) { - bool ret = true; - guid_t *guid_invalid = &DFL_GUID_INVALID; + guid_t *guid_invalid = &DFL_GUID_INVALID; - if (guid_is_null(guid) || guid_equal(guid, guid_invalid)) - ret = false; - return ret; + return !guid_is_null(guid) && !guid_equal(guid, guid_invalid); } -/* - * Bit definitions masks extract from GUID_H and GUID_L - * GUID_INIT(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) - */ -#define DFL_GUID_H_A GENMASK_ULL(63, 32) -#define DFL_GUID_H_B GENMASK_ULL(31, 16) -#define DFL_GUID_H_C GENMASK_ULL(15, 0) -#define DFL_GUID_L_D0 GENMASK_ULL(63, 56) -#define DFL_GUID_L_D1 GENMASK_ULL(55, 48) -#define DFL_GUID_L_D2 GENMASK_ULL(47, 40) -#define DFL_GUID_L_D3 GENMASK_ULL(39, 32) -#define DFL_GUID_L_D4 GENMASK_ULL(31, 24) -#define DFL_GUID_L_D5 GENMASK_ULL(23, 16) -#define DFL_GUID_L_D6 GENMASK_ULL(15, 8) -#define DFL_GUID_L_D7 GENMASK_ULL(7, 0) +static inline guid_t dfl_guid_init(u64 guid_h, u64 guid_l) +{ + return GUID_INIT(FIELD_GET(GENMASK_ULL(63, 32), guid_h), + FIELD_GET(GENMASK_ULL(31, 16), guid_h), + FIELD_GET(GENMASK_ULL(15, 0), guid_h), + FIELD_GET(GENMASK_ULL(63, 56), guid_l), + FIELD_GET(GENMASK_ULL(55, 48), guid_l), + FIELD_GET(GENMASK_ULL(47, 40), guid_l), + FIELD_GET(GENMASK_ULL(39, 32), guid_l), + FIELD_GET(GENMASK_ULL(31, 24), guid_l), + FIELD_GET(GENMASK_ULL(23, 16), guid_l), + FIELD_GET(GENMASK_ULL(15, 8), guid_l), + FIELD_GET(GENMASK_ULL(7, 0), guid_l)); +} /** * struct dfl_fpga_enum_info - DFL FPGA enumeration information diff --git a/include/linux/dfl.h b/include/linux/dfl.h index 6d66aa4a..226b30d0 100644 --- a/include/linux/dfl.h +++ b/include/linux/dfl.h @@ -34,6 +34,7 @@ enum dfl_id_type { * @num_irqs: number of IRQs supported by this dfl device. * @cdev: pointer to DFL FPGA container device this dfl device belongs to. * @id_entry: matched id entry in dfl driver's id table. + * @guid: feature GUID of the dfl device. * @dfh_version: version of DFH for the device * @param_size: size of the block parameters in bytes * @params: pointer to block of parameters copied memory @@ -50,10 +51,10 @@ struct dfl_device { unsigned int num_irqs; struct dfl_fpga_cdev *cdev; const struct dfl_device_id *id_entry; + guid_t guid; u8 dfh_version; unsigned int param_size; void *params; - guid_t guid; }; /** From fac9b34bc0b9cc532332fb4ed65023228314f864 Mon Sep 17 00:00:00 2001 From: Basheer Ahmed Muddebihal Date: Thu, 3 Nov 2022 22:56:09 -0700 Subject: [PATCH 04/12] tty: serial: 8250: Add the GUID definition for UART Moving forward GUID match is the preferred match, UART is the first feature device that supports GUID, It provides a way to demonstrate and test the GUID match functionality. Signed-off-by: Basheer Ahmed Muddebihal --- drivers/tty/serial/8250/8250_dfl.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/tty/serial/8250/8250_dfl.c b/drivers/tty/serial/8250/8250_dfl.c index e04c9284..bb3cf1f1 100644 --- a/drivers/tty/serial/8250/8250_dfl.c +++ b/drivers/tty/serial/8250/8250_dfl.c @@ -150,12 +150,10 @@ static void dfl_uart_remove(struct dfl_device *dfl_dev) #define FME_FEATURE_ID_UART 0x24 -#define FME_GUID_UART \ - GUID_INIT(0x9e6641a6, 0xca26, 0xcc04, 0xe1, 0xdf, \ - 0x0d, 0x4a, 0xce, 0x8e, 0x48, 0x6c) +#define DFL_GUID_UART "9E6641A6-CA26-CC04-E1DF-0D4ACE8E486C" static const struct dfl_device_id dfl_uart_ids[] = { - { FME_ID, FME_FEATURE_ID_UART, .guid = FME_GUID_UART }, + { FME_ID, FME_FEATURE_ID_UART, .guid_string = DFL_GUID_UART }, { } }; MODULE_DEVICE_TABLE(dfl, dfl_uart_ids); From 793a817f8980c7dd655acf24f2b2ba6729e088b8 Mon Sep 17 00:00:00 2001 From: Russ Weight Date: Wed, 9 Nov 2022 14:08:33 -0800 Subject: [PATCH 05/12] fpga: dfl: Prefer GUID match when binding dfl drivers With the introduction of GUIDs as DFL device identifiers, a DFL driver may be selected based on a GUID match or based on a type/feature ID match. A driver that matches based on GUID is written specifically for that device. A driver that matches based on type/feature ID is likely to be a more generalized driver that will support the device but may not enable all functionality. This change will prevent a DFL device from binding to a driver based on type/feature ID if a driver for the GUID is present in the system. Signed-off-by: Russ Weight Signed-off-by: Basheer Ahmed Muddebihal --- drivers/fpga/dfl.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/drivers/fpga/dfl.c b/drivers/fpga/dfl.c index 36bdbdec..3d35bd60 100644 --- a/drivers/fpga/dfl.c +++ b/drivers/fpga/dfl.c @@ -254,13 +254,39 @@ static bool dfl_guid_is_match(const char *guid_str, const guid_t *guid_dev) return dfl_guid_is_valid(guid_dev) && guid_parse_and_compare(guid_str, guid_dev); } +static int dfl_match_one_guid(struct device_driver *drv, void *data) +{ + struct dfl_driver *ddrv = to_dfl_drv(drv); + const struct dfl_device_id *id_entry; + struct dfl_device *ddev = data; + + id_entry = ddrv->id_table; + if (!id_entry) + return 0; + + while (*id_entry->guid_string) { + if (dfl_guid_is_match(id_entry->guid_string, &ddev->guid)) + return 1; + id_entry++; + } + return 0; +} + +static struct bus_type dfl_bus_type; + +static bool can_match_guid(struct dfl_device *ddev) +{ + return bus_for_each_drv(&dfl_bus_type, NULL, ddev, dfl_match_one_guid) > 0; +} + static const struct dfl_device_id * dfl_match_one_device(const struct dfl_device_id *id, struct dfl_device *ddev) { if (dfl_guid_is_match(id->guid_string, &ddev->guid)) return id; - if (dfl_feature_id_is_match(id, ddev)) + if (dfl_feature_id_is_match(id, ddev) && + !(dfl_guid_is_valid(&ddev->guid) && can_match_guid(ddev))) return id; return NULL; From 2b2ec7a8ee6496acd56e38d238427b255446ba10 Mon Sep 17 00:00:00 2001 From: Basheer Ahmed Muddebihal Date: Fri, 14 Apr 2023 00:22:52 -0700 Subject: [PATCH 06/12] fpga: dfl: Add a dfl driver DFL branch feature This patch adds the DFL feature driver for the branch device feature which will bind using GUID, and processes the branch parameter to extract the address of the branch DFL, and branch DFL size to enumerate the devices present in the branch DFL. Signed-off-by: Basheer Ahmed Muddebihal --- Makefile | 2 + drivers/fpga/Kconfig | 11 +++ drivers/fpga/Makefile | 1 + drivers/fpga/dfl-branch.c | 169 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 183 insertions(+) create mode 100644 drivers/fpga/dfl-branch.c diff --git a/Makefile b/Makefile index bf342cd2..16d35890 100644 --- a/Makefile +++ b/Makefile @@ -61,6 +61,7 @@ obj-m += dfl-fme-mgr.o obj-m += dfl-fme-region.o obj-m += dfl-fme-br.o obj-m += dfl-priv-feat.o +obj-m += dfl-branch.o obj-m += dfl-hssi.o obj-m += dfl-n3000-nios.o obj-m += dfl-emif.o @@ -107,6 +108,7 @@ dfl-fme-y += drivers/fpga/dfl-fme-perf.o dfl-fme-y += drivers/fpga/dfl-fme-error.o dfl-priv-feat-y += drivers/fpga/dfl-priv-feat-main.o +dfl-branch-y += drivers/fpga/dfl-branch.o dfl-fme-br-y := drivers/fpga/dfl-fme-br.o dfl-fme-mgr-y := drivers/fpga/dfl-fme-mgr.o diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig index a41037f7..11defb68 100644 --- a/drivers/fpga/Kconfig +++ b/drivers/fpga/Kconfig @@ -202,6 +202,17 @@ config FPGA_DFL_PRIV_FEAT To compile this driver as a module, choose M here: the module will be called dfl_priv_feat. +config FPGA_DFL_BRANCH + tristate "FPGA DFL Branch Driver" + depends on FPGA_DFL + help + This is the feature driver for Branch DFL (Device Feature List), + which binds the DFL driver for the branch DFL feature using GUID, + and processes branch parameters and enumerates DFL devices in + the branch list. + + To compile this as a module, choose M here. + config FPGA_DFL_NIOS_INTEL_PAC_N3000 tristate "FPGA DFL NIOS Driver for Intel PAC N3000" depends on FPGA_DFL diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile index 027c651c..41e74da2 100644 --- a/drivers/fpga/Makefile +++ b/drivers/fpga/Makefile @@ -39,6 +39,7 @@ obj-$(CONFIG_OF_FPGA_REGION) += of-fpga-region.o # FPGA Device Feature List Support obj-$(CONFIG_FPGA_DFL) += dfl.o +obj-$(CONFIG_FPGA_DFL_BRANCH) += dfl-branch.o obj-$(CONFIG_FPGA_DFL_FME) += dfl-fme.o obj-$(CONFIG_FPGA_DFL_PRIV_FEAT) += dfl-priv-feat.o obj-$(CONFIG_FPGA_DFL_FME_MGR) += dfl-fme-mgr.o diff --git a/drivers/fpga/dfl-branch.c b/drivers/fpga/dfl-branch.c new file mode 100644 index 00000000..44ec2447 --- /dev/null +++ b/drivers/fpga/dfl-branch.c @@ -0,0 +1,169 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Driver for FPGA BRANCH DFL + * + * Copyright (C) 2023 Intel Corporation. + * + * Authors: + * Basheer Ahmed Muddebihal + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "dfl.h" + +#define DRV_NAME "dfl-branch" + +#define DFHv1_PARAM_ID_BRANCH_DFL 0xF00C +#define DFL_BRANCH_SIZE 0x2000 /*default DFL ROM Size*/ +#define DFL_BRANCH_PARAM_DATA_LEN 16 /*two 8-byte words*/ + +/* + * REL_N, 1'b0 = relative (offset from feature DFH start), + * 1'b1 = absolute (ARM or other non-PCIe use) + */ +#define DFHv1_BRANCH_DFL_ADDR_REL_N BIT_ULL(0) +#define DFHv1_BRANCH_DFL_ADDR GENMASK_ULL(63, 3) /* 63:3 of DFL address */ +#define DFHv1_BRANCH_DFL_SIZE GENMASK_ULL(63, 32) /* 63:32 size of DFL */ + +static int dfh_branch_get_param_vals(struct dfl_device *dfl_dev, int param_id, + u64 *bdfl_addr, size_t *bdfl_size, bool *rel_addr) +{ + struct device *dev = &dfl_dev->dev; + u64 addr_val, size_val; + size_t psize; + u64 *p; + + p = dfh_find_param(dfl_dev, param_id, &psize); + if (IS_ERR(p)) + return PTR_ERR(p); + + if (psize == DFL_BRANCH_PARAM_DATA_LEN) { + addr_val = *p; + size_val = *(p + 1); + dev_info(dev, "addr_val = %pa, size_val=%pa\n", &addr_val, &size_val); + } else { + dev_err(dev, "Branch parameters data is missing\n"); + return -EINVAL; + } + + if (FIELD_GET(DFHv1_BRANCH_DFL_ADDR_REL_N, addr_val)) + *rel_addr = false; + else + *rel_addr = true; + + *bdfl_addr = FIELD_GET(DFHv1_BRANCH_DFL_ADDR, addr_val) << 3; + *bdfl_size = FIELD_GET(DFHv1_BRANCH_DFL_SIZE, size_val); + + return 0; +} + +static int dfl_branch_process_dfl(struct dfl_device *dfl_dev) +{ + struct device *dev = &dfl_dev->dev; + struct dfl_fpga_enum_info *info; + struct dfl_fpga_cdev *cdev; + resource_size_t start, len; + resource_size_t feat_base; + bool rel_addr = true; + u64 *pstart, *pend; + size_t bdfl_size; + u64 bdfl_addr; + u64 next, v; + int ret; + + /* allocate enumeration info */ + info = dfl_fpga_enum_info_alloc(dev); + if (!info) + return -ENOMEM; + + pstart = dfl_dev->params; + pend = dfl_dev->params + dfl_dev->param_size / sizeof(u64); + + feat_base = dfl_dev->mmio_res.start; + + while (pstart < pend) { + v = *pstart; + + ret = dfh_branch_get_param_vals(dfl_dev, DFHv1_PARAM_ID_BRANCH_DFL, + &bdfl_addr, &bdfl_size, &rel_addr); + + if (!ret) { + if (rel_addr) { + start = feat_base + bdfl_addr; + dev_info(dev, "Start=%pa\n", &start); + } else { + start = bdfl_addr; + } + + len = bdfl_size ? bdfl_size : DFL_BRANCH_SIZE; + dfl_fpga_enum_info_add_dfl(info, start, len); + } + next = FIELD_GET(DFHv1_PARAM_HDR_NEXT_OFFSET, v); + pstart += next; + } + + /* start enumeration with prepared enumeration information */ + cdev = dfl_fpga_feature_devs_enumerate(info); + if (IS_ERR(cdev)) { + dev_err(&dfl_dev->dev, "Enumeration failure\n"); + ret = PTR_ERR(cdev); + goto info_free_exit; + } + + dfl_dev->cdev = cdev; + +info_free_exit: + dfl_fpga_enum_info_free(info); + + return ret; +} + +static int dfl_branch_probe(struct dfl_device *dfl_dev) +{ + struct device *dev = &dfl_dev->dev; + int ret; + + ret = dfl_branch_process_dfl(dfl_dev); + if (ret < 0) + return dev_err_probe(dev, ret, "Failed to find the branch dfl\n"); + + return 0; +} + +static void dfl_branch_remove(struct dfl_device *dfl_dev) +{ + dfl_fpga_feature_devs_remove(dfl_dev->cdev); +} + +/* + * GUID for Branch DFL {30c45aea-68f6-42e6-aefb-15b4b5e28284} + */ + +#define DFL_BRANCH_GUID "30c45aEa-68f6-42e6-aefb-15b4b5e28284" + +static const struct dfl_device_id dfl_branch_ids[] = { + { .guid_string = DFL_BRANCH_GUID }, + { } +}; +MODULE_DEVICE_TABLE(dfl, dfl_branch_ids); + +static struct dfl_driver dfl_branch_driver = { + .drv = { + .name = "dfl-branch", + }, + .id_table = dfl_branch_ids, + .probe = dfl_branch_probe, + .remove = dfl_branch_remove, +}; +module_dfl_driver(dfl_branch_driver); + +MODULE_DESCRIPTION("DFL Intel Branch DFL driver"); +MODULE_AUTHOR("Intel Corporation"); +MODULE_LICENSE("GPL"); From 1ebb6254a9a1ee3ad4a365d3c6e8d6b291312b90 Mon Sep 17 00:00:00 2001 From: Basheer Ahmed Muddebihal Date: Thu, 21 Dec 2023 02:57:02 -0800 Subject: [PATCH 07/12] fpga: dfl: Add sysfs entries for Group and Instance ID Added sysfs entries for Group Id and Instance ID Signed-off-by: Basheer Ahmed Muddebihal --- drivers/fpga/dfl-priv-feat-main.c | 19 ++++++++++++++----- drivers/fpga/dfl.c | 11 ++++++++--- drivers/fpga/dfl.h | 15 ++++++++++++++- include/linux/dfl.h | 7 +++++-- 4 files changed, 41 insertions(+), 11 deletions(-) diff --git a/drivers/fpga/dfl-priv-feat-main.c b/drivers/fpga/dfl-priv-feat-main.c index 8d469a7d..2f4594ed 100644 --- a/drivers/fpga/dfl-priv-feat-main.c +++ b/drivers/fpga/dfl-priv-feat-main.c @@ -14,20 +14,29 @@ #include "dfl.h" #include "dfl-priv-feat.h" -static ssize_t -guid_show(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t group_id_show(struct device *dev, struct device_attribute *attr, char *buf) { struct dfl_device *ddev = to_dfl_dev(dev); + if (!ddev->dfh_version) + return -ENOENT; + + return sysfs_emit(buf, "0x%X\n", ddev->group_id); +} +static DEVICE_ATTR_RO(group_id); +static ssize_t inst_id_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct dfl_device *ddev = to_dfl_dev(dev); if (!ddev->dfh_version) return -ENOENT; - return sysfs_emit(buf, "%pUL\n", &ddev->guid); + return sysfs_emit(buf, "0x%X\n", ddev->inst_id); } -static DEVICE_ATTR_RO(guid); +static DEVICE_ATTR_RO(inst_id); static struct attribute *dfl_priv_feat_attrs[] = { - &dev_attr_guid.attr, + &dev_attr_group_id.attr, + &dev_attr_inst_id.attr, NULL, }; diff --git a/drivers/fpga/dfl.c b/drivers/fpga/dfl.c index 3d35bd60..a0dedecc 100644 --- a/drivers/fpga/dfl.c +++ b/drivers/fpga/dfl.c @@ -457,6 +457,8 @@ dfl_dev_add(struct dfl_feature_dev_data *fdata, ddev->feature_id = feature->id; ddev->revision = feature->revision; ddev->dfh_version = feature->dfh_version; + ddev->group_id = feature->group_id; + ddev->inst_id = feature->inst_id; ddev->cdev = fdata->dfl_cdev; if (feature->param_size) { ddev->params = kmemdup(feature->params, feature->param_size, GFP_KERNEL); @@ -467,9 +469,6 @@ dfl_dev_add(struct dfl_feature_dev_data *fdata, ddev->param_size = feature->param_size; } - if (ddev->dfh_version == 1) - guid_copy(&ddev->guid, &feature->guid); - if (ddev->dfh_version == 1) guid_copy(&ddev->guid, &feature->guid); @@ -815,6 +814,8 @@ struct build_feature_devs_info { * @revision: revision of this sub feature * @dfh_version: device feature header version. * @guid: GUID of this sub feature. + * @group_id: specify the group id of the feature. + * @inst_id: Instance id of the feature. * @mmio_res: mmio resource of this sub feature. * @ioaddr: mapped base address of mmio resource. * @node: node in sub_features linked list. @@ -828,6 +829,8 @@ struct dfl_feature_info { u8 revision; u8 dfh_version; guid_t guid; + u16 group_id; + u16 inst_id; struct resource mmio_res; void __iomem *ioaddr; struct list_head node; @@ -1353,6 +1356,8 @@ create_feature_instance(struct build_feature_devs_info *binfo, finfo->fid = fid; finfo->revision = revision; finfo->dfh_version = dfh_ver; + finfo->group_id = dfl_feature_group_id(binfo->ioaddr + ofst); + finfo->inst_id = dfl_feature_inst_id(binfo->ioaddr + ofst); if (dfh_ver == 1) { v = readq(binfo->ioaddr + ofst + DFHv1_CSR_ADDR); addr_off = FIELD_GET(DFHv1_CSR_ADDR_MASK, v) << 1; diff --git a/drivers/fpga/dfl.h b/drivers/fpga/dfl.h index 1e8c6aa0..bd2e3ca9 100644 --- a/drivers/fpga/dfl.h +++ b/drivers/fpga/dfl.h @@ -287,9 +287,10 @@ struct dfl_feature_irq_ctx { * @priv: priv data of this feature. * @guid: sub feature GUID. * @dfh_version: version of the DFH + * @group_id: specify the group id of the feature. + * @inst_id: Instance id of the feature. * @param_size: size of dfh parameters * @params: point to memory copy of dfh parameters - * @guid: unique dfl private guid. */ struct dfl_feature { struct platform_device *dev; @@ -304,6 +305,8 @@ struct dfl_feature { void *priv; guid_t guid; u8 dfh_version; + u16 group_id; + u16 inst_id; unsigned int param_size; void *params; }; @@ -509,6 +512,16 @@ static inline u8 dfl_feature_revision(void __iomem *base) return (u8)FIELD_GET(DFH_REVISION, readq(base + DFH)); } +static inline u16 dfl_feature_inst_id(void __iomem *base) +{ + return (u16)FIELD_GET(DFHv1_CSR_SIZE_GRP_INSTANCE_ID, readq(base + DFHv1_CSR_SIZE_GRP)); +} + +static inline u16 dfl_feature_group_id(void __iomem *base) +{ + return (u16)FIELD_GET(DFHv1_CSR_SIZE_GRP_GROUPING_ID, readq(base + DFHv1_CSR_SIZE_GRP)); +} + #define DFL_GUID_INVALID \ GUID_INIT(0xffffffff, 0xffff, 0xffff, \ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff) diff --git a/include/linux/dfl.h b/include/linux/dfl.h index 226b30d0..2a2370a3 100644 --- a/include/linux/dfl.h +++ b/include/linux/dfl.h @@ -35,10 +35,11 @@ enum dfl_id_type { * @cdev: pointer to DFL FPGA container device this dfl device belongs to. * @id_entry: matched id entry in dfl driver's id table. * @guid: feature GUID of the dfl device. - * @dfh_version: version of DFH for the device + * @dfh_version: version of DFH for the device. + * @group_id: specify the group id of the feature. + * @inst_id: Instance id of the feature. * @param_size: size of the block parameters in bytes * @params: pointer to block of parameters copied memory - * @guid: feature GUID of the dfl device. */ struct dfl_device { struct device dev; @@ -53,6 +54,8 @@ struct dfl_device { const struct dfl_device_id *id_entry; guid_t guid; u8 dfh_version; + u16 group_id; + u16 inst_id; unsigned int param_size; void *params; }; From de1ee2b8a57cec6560293e8a3143cc48c75f2fe5 Mon Sep 17 00:00:00 2001 From: Basheer Ahmed Muddebihal Date: Fri, 3 Nov 2023 01:36:41 -0700 Subject: [PATCH 08/12] dt-bindings: fpga: Add Device Feature List(DFL) The Device Feature List (DFL) defines a linked list of feature headers within the device MMIO space, offering an extensible method for adding features. Signed-off-by: Basheer Ahmed Muddebihal --- .../bindings/soc/intel/intel,dfl-mmio.yaml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Documentation/devicetree/bindings/soc/intel/intel,dfl-mmio.yaml b/Documentation/devicetree/bindings/soc/intel/intel,dfl-mmio.yaml index 16f181d9..5d1f5e32 100644 --- a/Documentation/devicetree/bindings/soc/intel/intel,dfl-mmio.yaml +++ b/Documentation/devicetree/bindings/soc/intel/intel,dfl-mmio.yaml @@ -31,19 +31,19 @@ properties: This property establishes a reference to the Interrupt Controller Node, which manages interrupts for the device. - interrupt-user-start: + intel,user-interrupt-start: maxItems: 1 description: This property defines the initial user interrupts available on the specified controller. GIC are reserved for local purposes - fpga-interrupt-start: + intel,fpga-interrupt-start: maxItems: 1 descritpion: This property indicates the starting interrupt number within the GIC where FPGA-specific interrupts are mapped. - fpga-interrupt-lines: + intel,fpga-interrupt-lines: maxItems: 1 descritpions: This property specifies the total count of Interrupt Requests (IRQs) @@ -61,7 +61,7 @@ examples: compatible = "intel,dfl-mmio"; reg = <0xF9000000 0x00002000>; interrupt-parent = <&intc>; - interrupt-user-start = <32>; - fpga-interrupt-start = <49>; - fpga-interrupt-lines = <64>; + intel,user-interrupt-start = <32>; + intel,fpga-interrupt-start = <49>; + intel,fpga-interrupt-lines = <64>; }; From 4873a9508a0cdc81a582800665c34250893adb6f Mon Sep 17 00:00:00 2001 From: Basheer Ahmed Muddebihal Date: Thu, 4 Jan 2024 00:18:37 -0800 Subject: [PATCH 09/12] fpga: dfl: Process the Device Tree interrupt properties Processes the device tree interrupt entires and stores the two properties gic_arm_ref and fpga_intr_lines in to DFL dev strucure, these proerties are used to process the feature interrupt param block to register ISR. Signed-off-by: Basheer Ahmed Muddebihal --- drivers/fpga/dfl-platform.c | 39 +++++++++++++++++++++++++++++++++++-- drivers/fpga/dfl.c | 16 ++++++++++++++- drivers/fpga/dfl.h | 4 ++++ include/linux/dfl.h | 2 ++ 4 files changed, 58 insertions(+), 3 deletions(-) diff --git a/drivers/fpga/dfl-platform.c b/drivers/fpga/dfl-platform.c index 28b4f25b..f07e18a0 100644 --- a/drivers/fpga/dfl-platform.c +++ b/drivers/fpga/dfl-platform.c @@ -20,6 +20,10 @@ #define DRV_NAME "dfl-platform" +#define USER_INTERRUPT_START 32 +#define FPGA_INTERRUPT_START 49 +#define FPGA_INTERRUPT_LINES 64 + struct dfl_platform_drvdata { struct dfl_fpga_cdev *cdev; /* container device */ }; @@ -37,6 +41,34 @@ static int dfl_platform_init_drvdata(struct platform_device *pdev) return 0; } +static void dfl_platform_process_intr_params(struct platform_device *pdev, + struct dfl_fpga_enum_info *info) +{ + struct device_node *node = pdev->dev.of_node; + int user_intr_start = USER_INTERRUPT_START; + int fpga_intr_start = FPGA_INTERRUPT_START; + int fpga_intr_lines = FPGA_INTERRUPT_LINES; + int reg; + + if (of_property_read_u32(node, "intel,user-interrupt-start", ®)) + dev_warn(&pdev->dev, "intel,user-interrupt-start value not set in device tree\n"); + else + user_intr_start = reg; + + if (of_property_read_u32(node, "intel,fpga-interrupt-start", ®)) + dev_warn(&pdev->dev, "intel,fpga-interrupt-start not set in device tree\n"); + else + fpga_intr_start = reg; + + if (of_property_read_u32(node, "intel,fpga-interrupt-lines", ®)) + dev_warn(&pdev->dev, "intel,interrupt-user-offset value not set in device tree\n"); + else + fpga_intr_lines = reg; + + info->gic_arm_ref = fpga_intr_start - user_intr_start; + info->fpga_intr_lines = fpga_intr_lines; +} + static void dfl_platform_remove_feature_devs(struct platform_device *pdev) { struct dfl_platform_drvdata *drvdata = platform_get_drvdata(pdev); @@ -68,6 +100,8 @@ static int dfl_platform_process_dfl_node(struct platform_device *pdev, goto err_map; } + dfl_platform_process_intr_params(pdev, info); + dfl_fpga_enum_info_add_dfl(info, start, len); /* release I/O mappings for next step enumeration */ @@ -113,6 +147,7 @@ static int dfl_platform_enumerate_feature_devs(struct platform_device *pdev, return ret; } + static int dfl_platform_probe(struct platform_device *pdev) { struct resource dfl_location; @@ -163,13 +198,13 @@ static int dfl_platform_remove(struct platform_device *pdev) static const struct of_device_id dfl_platform_match[] = { { .compatible = "intel,dfl-mmio", }, - {}, + {} }; MODULE_DEVICE_TABLE(of, dfl_platform_match); static const struct platform_device_id dfl_platform_ids[] = { { DRV_NAME, 0 }, - { } + {} }; MODULE_DEVICE_TABLE(platform, dfl_platform_ids); diff --git a/drivers/fpga/dfl.c b/drivers/fpga/dfl.c index a0dedecc..a6b5d6ad 100644 --- a/drivers/fpga/dfl.c +++ b/drivers/fpga/dfl.c @@ -460,6 +460,9 @@ dfl_dev_add(struct dfl_feature_dev_data *fdata, ddev->group_id = feature->group_id; ddev->inst_id = feature->inst_id; ddev->cdev = fdata->dfl_cdev; + ddev->gic_arm_ref = feature->gic_arm_ref; + ddev->fpga_intr_lines = feature->fpga_intr_lines; + if (feature->param_size) { ddev->params = kmemdup(feature->params, feature->param_size, GFP_KERNEL); if (!ddev->params) { @@ -798,13 +801,14 @@ struct build_feature_devs_info { struct dfl_fpga_cdev *cdev; unsigned int nr_irqs; int *irq_table; - enum dfl_id_type type; void __iomem *ioaddr; resource_size_t start; resource_size_t len; struct list_head sub_features; int feature_num; + int gic_arm_ref; + int fpga_intr_lines; }; /** @@ -836,6 +840,8 @@ struct dfl_feature_info { struct list_head node; unsigned int irq_base; unsigned int nr_irqs; + int gic_arm_ref; + int fpga_intr_lines; unsigned int param_size; u64 params[]; }; @@ -892,6 +898,7 @@ binfo_create_feature_dev_data(struct build_feature_devs_info *binfo) fdata->num = binfo->feature_num; fdata->dfl_cdev = binfo->cdev; fdata->id = FEATURE_DEV_ID_UNUSED; + mutex_init(&fdata->lock); lockdep_set_class_and_name(&fdata->lock, &dfl_pdata_keys[type], dfl_pdata_key_strings[type]); @@ -914,6 +921,8 @@ binfo_create_feature_dev_data(struct build_feature_devs_info *binfo) feature->id = finfo->fid; feature->revision = finfo->revision; feature->dfh_version = finfo->dfh_version; + feature->gic_arm_ref = finfo->gic_arm_ref; + feature->fpga_intr_lines = finfo->fpga_intr_lines; if (finfo->param_size) { feature->params = devm_kmemdup(binfo->dev, @@ -1358,6 +1367,9 @@ create_feature_instance(struct build_feature_devs_info *binfo, finfo->dfh_version = dfh_ver; finfo->group_id = dfl_feature_group_id(binfo->ioaddr + ofst); finfo->inst_id = dfl_feature_inst_id(binfo->ioaddr + ofst); + finfo->gic_arm_ref = binfo->gic_arm_ref; + finfo->fpga_intr_lines = binfo->fpga_intr_lines; + if (dfh_ver == 1) { v = readq(binfo->ioaddr + ofst + DFHv1_CSR_ADDR); addr_off = FIELD_GET(DFHv1_CSR_ADDR_MASK, v) << 1; @@ -1799,6 +1811,8 @@ dfl_fpga_feature_devs_enumerate(struct dfl_fpga_enum_info *info) binfo->cdev = cdev; INIT_LIST_HEAD(&binfo->sub_features); + binfo->gic_arm_ref = info->gic_arm_ref; + binfo->fpga_intr_lines = info->fpga_intr_lines; binfo->nr_irqs = info->nr_irqs; if (info->nr_irqs) binfo->irq_table = info->irq_table; diff --git a/drivers/fpga/dfl.h b/drivers/fpga/dfl.h index bd2e3ca9..30af97da 100644 --- a/drivers/fpga/dfl.h +++ b/drivers/fpga/dfl.h @@ -307,6 +307,8 @@ struct dfl_feature { u8 dfh_version; u16 group_id; u16 inst_id; + int gic_arm_ref; + int fpga_intr_lines; unsigned int param_size; void *params; }; @@ -561,6 +563,8 @@ struct dfl_fpga_enum_info { struct list_head dfls; unsigned int nr_irqs; int *irq_table; + int gic_arm_ref; + int fpga_intr_lines; }; /** diff --git a/include/linux/dfl.h b/include/linux/dfl.h index 2a2370a3..d22a5c0f 100644 --- a/include/linux/dfl.h +++ b/include/linux/dfl.h @@ -56,6 +56,8 @@ struct dfl_device { u8 dfh_version; u16 group_id; u16 inst_id; + int gic_arm_ref; + int fpga_intr_lines; unsigned int param_size; void *params; }; From 073175c852ef19e572d3b36af0afed7a4a7bbcbd Mon Sep 17 00:00:00 2001 From: Peter Colberg Date: Tue, 19 Mar 2024 18:57:13 -0400 Subject: [PATCH 10/12] fixup! fpga: dfl: Add a dfl driver DFL branch feature --- drivers/fpga/dfl-branch.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/fpga/dfl-branch.c b/drivers/fpga/dfl-branch.c index 44ec2447..f2a9168d 100644 --- a/drivers/fpga/dfl-branch.c +++ b/drivers/fpga/dfl-branch.c @@ -142,11 +142,7 @@ static void dfl_branch_remove(struct dfl_device *dfl_dev) dfl_fpga_feature_devs_remove(dfl_dev->cdev); } -/* - * GUID for Branch DFL {30c45aea-68f6-42e6-aefb-15b4b5e28284} - */ - -#define DFL_BRANCH_GUID "30c45aEa-68f6-42e6-aefb-15b4b5e28284" +#define DFL_BRANCH_GUID "30C45AEA-68F6-42E6-AEFB-15B4B5E28284" static const struct dfl_device_id dfl_branch_ids[] = { { .guid_string = DFL_BRANCH_GUID }, @@ -164,6 +160,7 @@ static struct dfl_driver dfl_branch_driver = { }; module_dfl_driver(dfl_branch_driver); +MODULE_ALIAS("dfl:t*f*g{" DFL_BRANCH_GUID "}"); MODULE_DESCRIPTION("DFL Intel Branch DFL driver"); MODULE_AUTHOR("Intel Corporation"); MODULE_LICENSE("GPL"); From ee1398d826b2f3b09b8b0a0d997629ed2e90cade Mon Sep 17 00:00:00 2001 From: Peter Colberg Date: Wed, 20 Mar 2024 15:00:05 -0400 Subject: [PATCH 11/12] fixup! dfl: fpga: Introduce new FIU for enhanced initiation flexibility --- drivers/fpga/dfl-priv-feat-main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/fpga/dfl-priv-feat-main.c b/drivers/fpga/dfl-priv-feat-main.c index 2f4594ed..b2cc621e 100644 --- a/drivers/fpga/dfl-priv-feat-main.c +++ b/drivers/fpga/dfl-priv-feat-main.c @@ -138,3 +138,4 @@ module_platform_driver(dfl_priv_feat_driver); MODULE_DESCRIPTION("FPGA Privare Feature driver"); MODULE_AUTHOR("Intel Corporation"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:dfl-priv-feat"); From 79058cfbbae8569d744bc26ee559580059468836 Mon Sep 17 00:00:00 2001 From: Peter Colberg Date: Wed, 20 Mar 2024 15:42:06 -0400 Subject: [PATCH 12/12] Makefile: support builtin fpga-{mgr,bridge,region} modules The Intel SoCFPGA GSRD (Golden Software Reference Design) Yocto image is by default built with CONFIG_FPGA=y (but CONFIG_FPGA_BRIDGE=m and CONFIG_FPGA_REGION=m), which causes an unresolvable symbol conflict between the kernel image and the fpga-mgr backport module. Assuming that the kernel version is recent enough not to require any updates to fpga-{mgr,bridge,region}, do not build these modules when CONFIG_FPGA=y. Do not consider CONFIG_FPGA_BRIDGE and CONFIG_FPGA_REGION to avoid a version mix between kernel-provided and backport modules. This is not a complete solution and may result in unknown failures when the builtin kernel modules are too old, but it does happen to work with Intel SoCFPGA GSRD which is currently based on Linux 6.1.55 (LTS). Link: https://github.com/altera-opensource/gsrd-socfpga Link: https://github.com/altera-opensource/linux-socfpga Signed-off-by: Peter Colberg --- Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile b/Makefile index 16d35890..2af3a173 100644 --- a/Makefile +++ b/Makefile @@ -48,9 +48,11 @@ endif # The module order matters; it determines the module order for # both the insmod and rmmod targets. The module order is also # leveraged for install packages by the dkms.conf file. +ifneq ($(CONFIG_FPGA),y) obj-m += fpga-mgr.o obj-m += fpga-bridge.o obj-m += fpga-region.o +endif ifndef CONFIG_FW_UPLOAD obj-m += fpga-image-load.o endif