From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id A4C7AA0C47; Wed, 17 Nov 2021 01:23:48 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id EF20F411FB; Wed, 17 Nov 2021 01:23:04 +0100 (CET) Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) by mails.dpdk.org (Postfix) with ESMTP id C64AB411DD for ; Wed, 17 Nov 2021 01:23:02 +0100 (CET) Received: from pps.filterd (m0045851.ppops.net [127.0.0.1]) by mx0b-0016f401.pphosted.com (8.16.1.2/8.16.1.2) with ESMTP id 1AGMT3iI004129 for ; Tue, 16 Nov 2021 16:23:02 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=pfpt0220; bh=/yZJWE4fUu8hECEhP9r6p8hMwFuV7ct4FoWzxfnq2oo=; b=EkAyIlL16Wdw6c1Tq41qQIydJPfqFuxMZYWqGJJKCaOS+3JdLyHu1NLsgdPfxheeOYyZ 06Mqj5JGspnpn3nHapqhoik7E2NTL1f2gjeVz2Ehuf4J6ptRltGUaP1fKAbIVIciAFjr N1ndyzhQxVYnNJPC939cuwZd4xS38Z+tlZpkYwoGpv1rvLy0JhJ/kr4Qi1tp2/uHJeVx anCSVBWnP1x2PFQpmyK5PliX2tULlYKWFgV+WY0oXQqE/sSDHMlFc8cnaplQHw+CFMUi +wGiO1vI2oSWfFa8B/Ieg6n10rCFfMk2qMRr5hWzHKBskdE6X1EJNR7N5pRRYynhy0a5 yg== Received: from dc5-exch02.marvell.com ([199.233.59.182]) by mx0b-0016f401.pphosted.com (PPS) with ESMTPS id 3cc85xc9w0-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT) for ; Tue, 16 Nov 2021 16:23:02 -0800 Received: from DC5-EXCH01.marvell.com (10.69.176.38) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server (TLS) id 15.0.1497.18; Tue, 16 Nov 2021 16:23:00 -0800 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH01.marvell.com (10.69.176.38) with Microsoft SMTP Server id 15.0.1497.18 via Frontend Transport; Tue, 16 Nov 2021 16:22:59 -0800 Received: from localhost.localdomain (unknown [10.28.34.39]) by maili.marvell.com (Postfix) with ESMTP id E75093F705A; Tue, 16 Nov 2021 16:22:58 -0800 (PST) From: Tomasz Duszynski To: CC: , Tomasz Duszynski Subject: [PATCH 10/10] raw/cnxk_gpio: support selftest Date: Wed, 17 Nov 2021 01:21:55 +0100 Message-ID: <20211117002155.293267-11-tduszynski@marvell.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211117002155.293267-1-tduszynski@marvell.com> References: <20211117002155.293267-1-tduszynski@marvell.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-Proofpoint-GUID: wOzXH22PLmzTyhxPXgn86re6R3ds7Ccv X-Proofpoint-ORIG-GUID: wOzXH22PLmzTyhxPXgn86re6R3ds7Ccv X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.790,Hydra:6.0.425,FMLib:17.0.607.475 definitions=2021-11-16_07,2021-11-16_01,2020-04-07_01 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Add support for performing selftest. Signed-off-by: Tomasz Duszynski --- doc/guides/rawdevs/cnxk_gpio.rst | 11 + drivers/raw/cnxk_gpio/cnxk_gpio.c | 1 + drivers/raw/cnxk_gpio/cnxk_gpio.h | 2 + drivers/raw/cnxk_gpio/cnxk_gpio_selftest.c | 442 +++++++++++++++++++++ drivers/raw/cnxk_gpio/meson.build | 1 + 5 files changed, 457 insertions(+) create mode 100644 drivers/raw/cnxk_gpio/cnxk_gpio_selftest.c diff --git a/doc/guides/rawdevs/cnxk_gpio.rst b/doc/guides/rawdevs/cnxk_gpio.rst index ad93ec0d44..c03a5b937c 100644 --- a/doc/guides/rawdevs/cnxk_gpio.rst +++ b/doc/guides/rawdevs/cnxk_gpio.rst @@ -182,3 +182,14 @@ Message is used to remove installed interrupt handler. Message must have type set to ``CNXK_GPIO_MSG_TYPE_UNREGISTER_IRQ``. Consider using ``rte_pmd_gpio_unregister_gpio()`` wrapper. + +Self test +--------- + +On EAL initialization CNXK GPIO device will be probed and populated into +the list of raw devices on condition ``--vdev=cnxk_gpio,gpiochip=`` was +passed. ``rte_rawdev_get_dev_id("CNXK_GPIO")`` returns unique device id. Use +this identifier for further rawdev function calls. + +Selftest rawdev API can be used to verify the PMD functionality. Note it blindly +assumes that all GPIOs are controllable so some errors during test are expected. diff --git a/drivers/raw/cnxk_gpio/cnxk_gpio.c b/drivers/raw/cnxk_gpio/cnxk_gpio.c index d39d203245..fa81b45f89 100644 --- a/drivers/raw/cnxk_gpio/cnxk_gpio.c +++ b/drivers/raw/cnxk_gpio/cnxk_gpio.c @@ -514,6 +514,7 @@ static const struct rte_rawdev_ops cnxk_gpio_rawdev_ops = { .queue_count = cnxk_gpio_queue_count, .queue_setup = cnxk_gpio_queue_setup, .queue_release = cnxk_gpio_queue_release, + .dev_selftest = cnxk_gpio_selftest, }; static int diff --git a/drivers/raw/cnxk_gpio/cnxk_gpio.h b/drivers/raw/cnxk_gpio/cnxk_gpio.h index a2e44fefbe..dfbad47c51 100644 --- a/drivers/raw/cnxk_gpio/cnxk_gpio.h +++ b/drivers/raw/cnxk_gpio/cnxk_gpio.h @@ -21,6 +21,8 @@ struct cnxk_gpiochip { struct cnxk_gpio **gpios; }; +int cnxk_gpio_selftest(uint16_t dev_id); + int cnxk_gpio_irq_init(struct cnxk_gpiochip *gpiochip); void cnxk_gpio_irq_fini(void); int cnxk_gpio_irq_request(int gpio, int cpu); diff --git a/drivers/raw/cnxk_gpio/cnxk_gpio_selftest.c b/drivers/raw/cnxk_gpio/cnxk_gpio_selftest.c new file mode 100644 index 0000000000..3fbba4af81 --- /dev/null +++ b/drivers/raw/cnxk_gpio/cnxk_gpio_selftest.c @@ -0,0 +1,442 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(C) 2021 Marvell. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "cnxk_gpio.h" +#include "rte_pmd_cnxk_gpio.h" + +#define CNXK_GPIO_BUFSZ 128 + +static int +cnxk_gpio_attr_exists(const char *attr) +{ + struct stat st; + + return !stat(attr, &st); +} + +static int +cnxk_gpio_read_attr(char *attr, char *val) +{ + FILE *fp; + int ret; + + fp = fopen(attr, "r"); + if (!fp) + return -errno; + + ret = fscanf(fp, "%s", val); + if (ret < 0) + return -errno; + if (ret != 1) + return -EIO; + + ret = fclose(fp); + if (ret) + return -errno; + + return 0; +} + +#define CNXK_GPIO_ERR_STR(err, str, ...) do { \ + if (err) { \ + RTE_LOG(ERR, PMD, "%s:%d: " str " (%d)\n", __func__, __LINE__, \ + ##__VA_ARGS__, err); \ + goto out; \ + } \ +} while (0) + +static int +cnxk_gpio_validate_attr(char *attr, const char *expected) +{ + char buf[CNXK_GPIO_BUFSZ]; + int ret; + + ret = cnxk_gpio_read_attr(attr, buf); + if (ret) + return ret; + + if (strncmp(buf, expected, sizeof(buf))) + return -EIO; + + return 0; +} + +#define CNXK_GPIO_PATH_FMT "/sys/class/gpio/gpio%d" + +static int +cnxk_gpio_test_input(uint16_t dev_id, int base, int gpio) +{ + char buf[CNXK_GPIO_BUFSZ]; + int ret, n; + + n = snprintf(buf, sizeof(buf), CNXK_GPIO_PATH_FMT, base + gpio); + snprintf(buf + n, sizeof(buf) - n, "/direction"); + + ret = rte_pmd_gpio_set_pin_dir(dev_id, gpio, CNXK_GPIO_PIN_DIR_IN); + CNXK_GPIO_ERR_STR(ret, "failed to set dir to input"); + ret = cnxk_gpio_validate_attr(buf, "in"); + CNXK_GPIO_ERR_STR(ret, "failed to validate %s", buf); + + ret = rte_pmd_gpio_set_pin_value(dev_id, gpio, 1) | + rte_pmd_gpio_set_pin_value(dev_id, gpio, 0); + if (!ret) { + ret = -EIO; + CNXK_GPIO_ERR_STR(ret, "input pin overwritten"); + } + + snprintf(buf + n, sizeof(buf) - n, "/edge"); + + ret = rte_pmd_gpio_set_pin_edge(dev_id, gpio, + CNXK_GPIO_PIN_EDGE_FALLING); + CNXK_GPIO_ERR_STR(ret, "failed to set edge to falling"); + ret = cnxk_gpio_validate_attr(buf, "falling"); + CNXK_GPIO_ERR_STR(ret, "failed to validate %s", buf); + + ret = rte_pmd_gpio_set_pin_edge(dev_id, gpio, + CNXK_GPIO_PIN_EDGE_RISING); + CNXK_GPIO_ERR_STR(ret, "failed to change edge to rising"); + ret = cnxk_gpio_validate_attr(buf, "rising"); + CNXK_GPIO_ERR_STR(ret, "failed to validate %s", buf); + + ret = rte_pmd_gpio_set_pin_edge(dev_id, gpio, CNXK_GPIO_PIN_EDGE_BOTH); + CNXK_GPIO_ERR_STR(ret, "failed to change edge to both"); + ret = cnxk_gpio_validate_attr(buf, "both"); + CNXK_GPIO_ERR_STR(ret, "failed to validate %s", buf); + + ret = rte_pmd_gpio_set_pin_edge(dev_id, gpio, CNXK_GPIO_PIN_EDGE_NONE); + CNXK_GPIO_ERR_STR(ret, "failed to set edge to none"); + ret = cnxk_gpio_validate_attr(buf, "none"); + CNXK_GPIO_ERR_STR(ret, "failed to validate %s", buf); + + /* + * calling this makes sure kernel driver switches off inverted + * logic + */ + rte_pmd_gpio_set_pin_dir(dev_id, gpio, CNXK_GPIO_PIN_DIR_IN); + +out: + return ret; +} + +static int +cnxk_gpio_open_mem(void) +{ + int ret = 0, fd; + + fd = open("/dev/mem", O_RDWR | O_SYNC); + if (fd < 0) + ret = -errno; + + return ret; +} + +static void +cnxk_gpio_close_mem(int fd) +{ + if (fd >= 0) + close(fd); +} + +#define GPIO_INTRX(a) (803000000800ull + (a) * 0x8) + +static int +cnxk_gpio_map_gpio_intrx(int fd, int gpio, void **va) +{ + uint64_t mask; + long size; + + size = sysconf(_SC_PAGESIZE); + mask = (uint64_t)size - 1; + *va = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, + GPIO_INTRX(gpio) & ~mask); + if (*va == MAP_FAILED) + return -errno; + + *(char *)va += GPIO_INTRX(gpio) & mask; + + return 0; +} + +static void +cnxk_gpio_unmap_gpio_intrx(int gpio, void *va) +{ + uint64_t mask; + long size; + + if (!va) + return; + + size = sysconf(_SC_PAGESIZE); + mask = (uint64_t)size - 1; + munmap((char *)va - (GPIO_INTRX(gpio) & mask), size); +} + +static int +cnxk_gpio_trigger_irq(int gpio) +{ + void *va; + int ret, fd; + + fd = cnxk_gpio_open_mem(); + if (fd < 0) + return fd; + + ret = cnxk_gpio_map_gpio_intrx(fd, gpio, &va); + if (ret) { + cnxk_gpio_close_mem(fd); + return ret; + } + + /* set INTR_W1S bit */ + *(volatile uint64_t *)va = 2; + cnxk_gpio_unmap_gpio_intrx(gpio, va); + cnxk_gpio_close_mem(fd); + + return 0; +} + +static void +cnxk_gpio_irq_handler(int gpio, void *data) +{ + *(int *)data = gpio; +} + +static int +cnxk_gpio_test_irq(uint16_t dev_id, int gpio) +{ + int irq_data, ret; + + ret = rte_pmd_gpio_set_pin_dir(dev_id, gpio, CNXK_GPIO_PIN_DIR_IN); + CNXK_GPIO_ERR_STR(ret, "failed to set dir to input"); + + irq_data = 0; + ret = rte_pmd_gpio_register_irq(dev_id, gpio, rte_lcore_id(), + cnxk_gpio_irq_handler, &irq_data); + CNXK_GPIO_ERR_STR(ret, "failed to register irq handler"); + + ret = rte_pmd_gpio_enable_interrupt(dev_id, gpio, + CNXK_GPIO_PIN_EDGE_RISING); + CNXK_GPIO_ERR_STR(ret, "failed to enable interrupt"); + + ret = cnxk_gpio_trigger_irq(gpio); + CNXK_GPIO_ERR_STR(ret, "failed to trigger irq"); + rte_delay_ms(1); + ret = *(volatile int *)&irq_data == gpio ? 0 : -EIO; + CNXK_GPIO_ERR_STR(ret, "failed to test irq"); + + ret = rte_pmd_gpio_disable_interrupt(dev_id, gpio); + CNXK_GPIO_ERR_STR(ret, "failed to disable interrupt"); + + ret = rte_pmd_gpio_unregister_irq(dev_id, gpio); + CNXK_GPIO_ERR_STR(ret, "failed to unregister irq handler"); +out: + rte_pmd_gpio_disable_interrupt(dev_id, gpio); + rte_pmd_gpio_unregister_irq(dev_id, gpio); + + return ret; +} + +static int +cnxk_gpio_test_output(uint16_t dev_id, int base, int gpio) +{ + char buf[CNXK_GPIO_BUFSZ]; + int ret, val, n; + + n = snprintf(buf, sizeof(buf), CNXK_GPIO_PATH_FMT, base + gpio); + + snprintf(buf + n, sizeof(buf) - n, "/direction"); + ret = rte_pmd_gpio_set_pin_dir(dev_id, gpio, CNXK_GPIO_PIN_DIR_OUT); + CNXK_GPIO_ERR_STR(ret, "failed to set dir to out"); + ret = cnxk_gpio_validate_attr(buf, "out"); + CNXK_GPIO_ERR_STR(ret, "failed to validate %s", buf); + + snprintf(buf + n, sizeof(buf) - n, "/value"); + ret = rte_pmd_gpio_set_pin_value(dev_id, gpio, 0); + CNXK_GPIO_ERR_STR(ret, "failed to set value to 0"); + ret = cnxk_gpio_validate_attr(buf, "0"); + CNXK_GPIO_ERR_STR(ret, "failed to validate %s", buf); + ret = rte_pmd_gpio_get_pin_value(dev_id, gpio, &val); + CNXK_GPIO_ERR_STR(ret, "failed to read value"); + if (val) + ret = -EIO; + CNXK_GPIO_ERR_STR(ret, "read %d instead of 0", val); + + ret = rte_pmd_gpio_set_pin_value(dev_id, gpio, 1); + CNXK_GPIO_ERR_STR(ret, "failed to set value to 1"); + ret = cnxk_gpio_validate_attr(buf, "1"); + CNXK_GPIO_ERR_STR(ret, "failed to validate %s", buf); + ret = rte_pmd_gpio_get_pin_value(dev_id, gpio, &val); + CNXK_GPIO_ERR_STR(ret, "failed to read value"); + if (val != 1) + ret = -EIO; + CNXK_GPIO_ERR_STR(ret, "read %d instead of 1", val); + + snprintf(buf + n, sizeof(buf) - n, "/direction"); + ret = rte_pmd_gpio_set_pin_dir(dev_id, gpio, CNXK_GPIO_PIN_DIR_LOW); + CNXK_GPIO_ERR_STR(ret, "failed to set dir to low"); + ret = cnxk_gpio_validate_attr(buf, "out"); + CNXK_GPIO_ERR_STR(ret, "failed to validate %s", buf); + snprintf(buf + n, sizeof(buf) - n, "/value"); + ret = cnxk_gpio_validate_attr(buf, "0"); + CNXK_GPIO_ERR_STR(ret, "failed to validate %s", buf); + + snprintf(buf + n, sizeof(buf) - n, "/direction"); + ret = rte_pmd_gpio_set_pin_dir(dev_id, gpio, CNXK_GPIO_PIN_DIR_HIGH); + CNXK_GPIO_ERR_STR(ret, "failed to set dir to high"); + ret = cnxk_gpio_validate_attr(buf, "out"); + CNXK_GPIO_ERR_STR(ret, "failed to validate %s", buf); + snprintf(buf + n, sizeof(buf) - n, "/value"); + ret = cnxk_gpio_validate_attr(buf, "1"); + CNXK_GPIO_ERR_STR(ret, "failed to validate %s", buf); + + snprintf(buf + n, sizeof(buf) - n, "/edge"); + ret = rte_pmd_gpio_set_pin_edge(dev_id, gpio, + CNXK_GPIO_PIN_EDGE_FALLING); + ret = ret == 0 ? -EIO : 0; + CNXK_GPIO_ERR_STR(ret, "changed edge to falling"); + ret = cnxk_gpio_validate_attr(buf, "none"); + CNXK_GPIO_ERR_STR(ret, "failed to validate %s", buf); + + ret = rte_pmd_gpio_set_pin_edge(dev_id, gpio, + CNXK_GPIO_PIN_EDGE_RISING); + ret = ret == 0 ? -EIO : 0; + CNXK_GPIO_ERR_STR(ret, "changed edge to rising"); + ret = cnxk_gpio_validate_attr(buf, "none"); + CNXK_GPIO_ERR_STR(ret, "failed to validate %s", buf); + + ret = rte_pmd_gpio_set_pin_edge(dev_id, gpio, CNXK_GPIO_PIN_EDGE_BOTH); + ret = ret == 0 ? -EIO : 0; + CNXK_GPIO_ERR_STR(ret, "changed edge to both"); + ret = cnxk_gpio_validate_attr(buf, "none"); + CNXK_GPIO_ERR_STR(ret, "failed to validate %s", buf); + + /* this one should succeed */ + ret = rte_pmd_gpio_set_pin_edge(dev_id, gpio, CNXK_GPIO_PIN_EDGE_NONE); + CNXK_GPIO_ERR_STR(ret, "failed to change edge to none"); + ret = cnxk_gpio_validate_attr(buf, "none"); + CNXK_GPIO_ERR_STR(ret, "failed to validate %s", buf); + + snprintf(buf + n, sizeof(buf) - n, "/active_low"); + ret = rte_pmd_gpio_set_pin_active_low(dev_id, gpio, 1); + CNXK_GPIO_ERR_STR(ret, "failed to set active_low to 1"); + ret = cnxk_gpio_validate_attr(buf, "1"); + CNXK_GPIO_ERR_STR(ret, "failed to validate %s", buf); + + ret = rte_pmd_gpio_get_pin_active_low(dev_id, gpio, &val); + CNXK_GPIO_ERR_STR(ret, "failed to read active_low"); + if (val != 1) + ret = -EIO; + CNXK_GPIO_ERR_STR(ret, "read %d instead of 1", val); + + snprintf(buf + n, sizeof(buf) - n, "/value"); + ret = rte_pmd_gpio_set_pin_value(dev_id, gpio, 1); + CNXK_GPIO_ERR_STR(ret, "failed to set value to 1"); + ret = cnxk_gpio_validate_attr(buf, "1"); + CNXK_GPIO_ERR_STR(ret, "failed to validate %s", buf); + + ret = rte_pmd_gpio_set_pin_value(dev_id, gpio, 0); + CNXK_GPIO_ERR_STR(ret, "failed to set value to 0"); + ret = cnxk_gpio_validate_attr(buf, "0"); + CNXK_GPIO_ERR_STR(ret, "failed to validate %s", buf); + + snprintf(buf + n, sizeof(buf) - n, "/active_low"); + ret = rte_pmd_gpio_set_pin_active_low(dev_id, gpio, 0); + CNXK_GPIO_ERR_STR(ret, "failed to set active_low to 0"); + ret = cnxk_gpio_validate_attr(buf, "0"); + CNXK_GPIO_ERR_STR(ret, "failed to validate %s", buf); + +out: + return ret; +} + +int +cnxk_gpio_selftest(uint16_t dev_id) +{ + struct cnxk_gpiochip *gpiochip; + unsigned int queues, i, size; + char buf[CNXK_GPIO_BUFSZ]; + struct rte_rawdev *rawdev; + struct cnxk_gpio *gpio; + int ret; + + rawdev = rte_rawdev_pmd_get_named_dev("cnxk_gpio"); + gpiochip = rawdev->dev_private; + + queues = rte_rawdev_queue_count(dev_id); + if (queues == 0) + return -ENODEV; + + ret = rte_rawdev_start(dev_id); + if (ret) + return ret; + + for (i = 0; i < queues; i++) { + RTE_LOG(INFO, PMD, "testing queue %d (gpio%d)\n", i, + gpiochip->base + i); + + ret = rte_rawdev_queue_conf_get(dev_id, i, &size, sizeof(size)); + if (ret) { + RTE_LOG(ERR, PMD, + "failed to read queue configuration (%d)\n", + ret); + continue; + } + + if (size != 1) { + RTE_LOG(ERR, PMD, "wrong queue size received\n"); + continue; + } + + ret = rte_rawdev_queue_setup(dev_id, i, NULL, 0); + if (ret) { + RTE_LOG(ERR, PMD, "failed to setup queue (%d)\n", ret); + continue; + } + + gpio = gpiochip->gpios[i]; + snprintf(buf, sizeof(buf), CNXK_GPIO_PATH_FMT, gpio->num); + if (!cnxk_gpio_attr_exists(buf)) { + RTE_LOG(ERR, PMD, "%s does not exist\n", buf); + continue; + } + + ret = cnxk_gpio_test_input(dev_id, gpiochip->base, i); + if (ret) + goto release; + + ret = cnxk_gpio_test_irq(dev_id, i); + if (ret) + goto release; + + ret = cnxk_gpio_test_output(dev_id, gpiochip->base, i); + if (ret) + goto release; + +release: + ret = rte_rawdev_queue_release(dev_id, i); + if (ret) { + RTE_LOG(ERR, PMD, "failed to release queue (%d)\n", + ret); + continue; + } + + if (cnxk_gpio_attr_exists(buf)) { + RTE_LOG(ERR, PMD, "%s still exists\n", buf); + continue; + } + } + + return 0; +} diff --git a/drivers/raw/cnxk_gpio/meson.build b/drivers/raw/cnxk_gpio/meson.build index 9b55f029c7..a75a5b9084 100644 --- a/drivers/raw/cnxk_gpio/meson.build +++ b/drivers/raw/cnxk_gpio/meson.build @@ -6,5 +6,6 @@ deps += ['bus_vdev', 'common_cnxk', 'rawdev', 'kvargs'] sources = files( 'cnxk_gpio.c', 'cnxk_gpio_irq.c', + 'cnxk_gpio_selftest.c', ) headers = files('rte_pmd_cnxk_gpio.h') -- 2.25.1