162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Generic DFL driver for Userspace I/O devicess 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2021 Intel Corporation, Inc. 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci#include <linux/dfl.h> 862306a36Sopenharmony_ci#include <linux/errno.h> 962306a36Sopenharmony_ci#include <linux/module.h> 1062306a36Sopenharmony_ci#include <linux/uio_driver.h> 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#define DRIVER_NAME "uio_dfl" 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_cistatic int uio_dfl_probe(struct dfl_device *ddev) 1562306a36Sopenharmony_ci{ 1662306a36Sopenharmony_ci struct resource *r = &ddev->mmio_res; 1762306a36Sopenharmony_ci struct device *dev = &ddev->dev; 1862306a36Sopenharmony_ci struct uio_info *uioinfo; 1962306a36Sopenharmony_ci struct uio_mem *uiomem; 2062306a36Sopenharmony_ci int ret; 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci uioinfo = devm_kzalloc(dev, sizeof(struct uio_info), GFP_KERNEL); 2362306a36Sopenharmony_ci if (!uioinfo) 2462306a36Sopenharmony_ci return -ENOMEM; 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci uioinfo->name = DRIVER_NAME; 2762306a36Sopenharmony_ci uioinfo->version = "0"; 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci uiomem = &uioinfo->mem[0]; 3062306a36Sopenharmony_ci uiomem->memtype = UIO_MEM_PHYS; 3162306a36Sopenharmony_ci uiomem->addr = r->start & PAGE_MASK; 3262306a36Sopenharmony_ci uiomem->offs = r->start & ~PAGE_MASK; 3362306a36Sopenharmony_ci uiomem->size = (uiomem->offs + resource_size(r) 3462306a36Sopenharmony_ci + PAGE_SIZE - 1) & PAGE_MASK; 3562306a36Sopenharmony_ci uiomem->name = r->name; 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci /* Irq is yet to be supported */ 3862306a36Sopenharmony_ci uioinfo->irq = UIO_IRQ_NONE; 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci ret = devm_uio_register_device(dev, uioinfo); 4162306a36Sopenharmony_ci if (ret) 4262306a36Sopenharmony_ci dev_err(dev, "unable to register uio device\n"); 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci return ret; 4562306a36Sopenharmony_ci} 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci#define FME_FEATURE_ID_ETH_GROUP 0x10 4862306a36Sopenharmony_ci#define FME_FEATURE_ID_HSSI_SUBSYS 0x15 4962306a36Sopenharmony_ci#define FME_FEATURE_ID_VENDOR_SPECIFIC 0x23 5062306a36Sopenharmony_ci#define PORT_FEATURE_ID_IOPLL_USRCLK 0x14 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_cistatic const struct dfl_device_id uio_dfl_ids[] = { 5362306a36Sopenharmony_ci { FME_ID, FME_FEATURE_ID_ETH_GROUP }, 5462306a36Sopenharmony_ci { FME_ID, FME_FEATURE_ID_HSSI_SUBSYS }, 5562306a36Sopenharmony_ci { FME_ID, FME_FEATURE_ID_VENDOR_SPECIFIC }, 5662306a36Sopenharmony_ci { PORT_ID, PORT_FEATURE_ID_IOPLL_USRCLK }, 5762306a36Sopenharmony_ci { } 5862306a36Sopenharmony_ci}; 5962306a36Sopenharmony_ciMODULE_DEVICE_TABLE(dfl, uio_dfl_ids); 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_cistatic struct dfl_driver uio_dfl_driver = { 6262306a36Sopenharmony_ci .drv = { 6362306a36Sopenharmony_ci .name = DRIVER_NAME, 6462306a36Sopenharmony_ci }, 6562306a36Sopenharmony_ci .id_table = uio_dfl_ids, 6662306a36Sopenharmony_ci .probe = uio_dfl_probe, 6762306a36Sopenharmony_ci}; 6862306a36Sopenharmony_cimodule_dfl_driver(uio_dfl_driver); 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ciMODULE_DESCRIPTION("Generic DFL driver for Userspace I/O devices"); 7162306a36Sopenharmony_ciMODULE_AUTHOR("Intel Corporation"); 7262306a36Sopenharmony_ciMODULE_LICENSE("GPL v2"); 73