xref: /linux/drivers/uio/uio_dfl.c (revision cdd5b5a9761fd66d17586e4f4ba6588c70e640ea)
1bbfb54e7SXu Yilun // SPDX-License-Identifier: GPL-2.0
2bbfb54e7SXu Yilun /*
3bbfb54e7SXu Yilun  * Generic DFL driver for Userspace I/O devicess
4bbfb54e7SXu Yilun  *
5bbfb54e7SXu Yilun  * Copyright (C) 2021 Intel Corporation, Inc.
6bbfb54e7SXu Yilun  */
7bbfb54e7SXu Yilun #include <linux/dfl.h>
8bbfb54e7SXu Yilun #include <linux/errno.h>
9bbfb54e7SXu Yilun #include <linux/module.h>
10bbfb54e7SXu Yilun #include <linux/uio_driver.h>
11bbfb54e7SXu Yilun 
12bbfb54e7SXu Yilun #define DRIVER_NAME "uio_dfl"
13bbfb54e7SXu Yilun 
uio_dfl_probe(struct dfl_device * ddev)14bbfb54e7SXu Yilun static int uio_dfl_probe(struct dfl_device *ddev)
15bbfb54e7SXu Yilun {
16bbfb54e7SXu Yilun 	struct resource *r = &ddev->mmio_res;
17bbfb54e7SXu Yilun 	struct device *dev = &ddev->dev;
18bbfb54e7SXu Yilun 	struct uio_info *uioinfo;
19bbfb54e7SXu Yilun 	struct uio_mem *uiomem;
20bbfb54e7SXu Yilun 	int ret;
21bbfb54e7SXu Yilun 
22bbfb54e7SXu Yilun 	uioinfo = devm_kzalloc(dev, sizeof(struct uio_info), GFP_KERNEL);
23bbfb54e7SXu Yilun 	if (!uioinfo)
24bbfb54e7SXu Yilun 		return -ENOMEM;
25bbfb54e7SXu Yilun 
26bbfb54e7SXu Yilun 	uioinfo->name = DRIVER_NAME;
27bbfb54e7SXu Yilun 	uioinfo->version = "0";
28bbfb54e7SXu Yilun 
29bbfb54e7SXu Yilun 	uiomem = &uioinfo->mem[0];
30bbfb54e7SXu Yilun 	uiomem->memtype = UIO_MEM_PHYS;
31bbfb54e7SXu Yilun 	uiomem->addr = r->start & PAGE_MASK;
32bbfb54e7SXu Yilun 	uiomem->offs = r->start & ~PAGE_MASK;
33bbfb54e7SXu Yilun 	uiomem->size = (uiomem->offs + resource_size(r)
34bbfb54e7SXu Yilun 			+ PAGE_SIZE - 1) & PAGE_MASK;
35bbfb54e7SXu Yilun 	uiomem->name = r->name;
36bbfb54e7SXu Yilun 
37bbfb54e7SXu Yilun 	/* Irq is yet to be supported */
38bbfb54e7SXu Yilun 	uioinfo->irq = UIO_IRQ_NONE;
39bbfb54e7SXu Yilun 
40bbfb54e7SXu Yilun 	ret = devm_uio_register_device(dev, uioinfo);
41bbfb54e7SXu Yilun 	if (ret)
42bbfb54e7SXu Yilun 		dev_err(dev, "unable to register uio device\n");
43bbfb54e7SXu Yilun 
44bbfb54e7SXu Yilun 	return ret;
45bbfb54e7SXu Yilun }
46bbfb54e7SXu Yilun 
47bbfb54e7SXu Yilun #define FME_FEATURE_ID_ETH_GROUP	0x10
4883b716d1SMatthew Gerlach #define FME_FEATURE_ID_HSSI_SUBSYS	0x15
49*c9d9d11bSPeter Colberg #define FME_FEATURE_ID_VENDOR_SPECIFIC	0x23
50d82a7aedSPeter Colberg #define PORT_FEATURE_ID_IOPLL_USRCLK	0x14
51bbfb54e7SXu Yilun 
52bbfb54e7SXu Yilun static const struct dfl_device_id uio_dfl_ids[] = {
53bbfb54e7SXu Yilun 	{ FME_ID, FME_FEATURE_ID_ETH_GROUP },
5483b716d1SMatthew Gerlach 	{ FME_ID, FME_FEATURE_ID_HSSI_SUBSYS },
55*c9d9d11bSPeter Colberg 	{ FME_ID, FME_FEATURE_ID_VENDOR_SPECIFIC },
56d82a7aedSPeter Colberg 	{ PORT_ID, PORT_FEATURE_ID_IOPLL_USRCLK },
57bbfb54e7SXu Yilun 	{ }
58bbfb54e7SXu Yilun };
59bbfb54e7SXu Yilun MODULE_DEVICE_TABLE(dfl, uio_dfl_ids);
60bbfb54e7SXu Yilun 
61bbfb54e7SXu Yilun static struct dfl_driver uio_dfl_driver = {
62bbfb54e7SXu Yilun 	.drv = {
63bbfb54e7SXu Yilun 		.name = DRIVER_NAME,
64bbfb54e7SXu Yilun 	},
65bbfb54e7SXu Yilun 	.id_table	= uio_dfl_ids,
66bbfb54e7SXu Yilun 	.probe		= uio_dfl_probe,
67bbfb54e7SXu Yilun };
68bbfb54e7SXu Yilun module_dfl_driver(uio_dfl_driver);
69bbfb54e7SXu Yilun 
70bbfb54e7SXu Yilun MODULE_DESCRIPTION("Generic DFL driver for Userspace I/O devices");
71bbfb54e7SXu Yilun MODULE_AUTHOR("Intel Corporation");
72bbfb54e7SXu Yilun MODULE_LICENSE("GPL v2");
73