1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Intel Elkhart Lake Programmable Service Engine (PSE) I/O 4 * 5 * Copyright (c) 2025 Intel Corporation. 6 * 7 * Author: Raag Jadav <raag.jadav@intel.com> 8 */ 9 10 #include <linux/auxiliary_bus.h> 11 #include <linux/device/devres.h> 12 #include <linux/errno.h> 13 #include <linux/gfp_types.h> 14 #include <linux/ioport.h> 15 #include <linux/mod_devicetable.h> 16 #include <linux/module.h> 17 #include <linux/pci.h> 18 #include <linux/sizes.h> 19 #include <linux/types.h> 20 21 #include <linux/ehl_pse_io_aux.h> 22 23 #define EHL_PSE_IO_DEV_SIZE SZ_4K 24 25 static int ehl_pse_io_dev_create(struct pci_dev *pci, const char *name, int idx) 26 { 27 struct device *dev = &pci->dev; 28 struct auxiliary_device *adev; 29 struct ehl_pse_io_data *data; 30 resource_size_t start, offset; 31 u32 id; 32 33 data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); 34 if (!data) 35 return -ENOMEM; 36 37 id = (pci_domain_nr(pci->bus) << 16) | pci_dev_id(pci); 38 start = pci_resource_start(pci, 0); 39 offset = EHL_PSE_IO_DEV_SIZE * idx; 40 41 data->mem = DEFINE_RES_MEM(start + offset, EHL_PSE_IO_DEV_SIZE); 42 data->irq = pci_irq_vector(pci, idx); 43 44 adev = __devm_auxiliary_device_create(dev, EHL_PSE_IO_NAME, name, data, id); 45 46 return adev ? 0 : -ENODEV; 47 } 48 49 static int ehl_pse_io_probe(struct pci_dev *pci, const struct pci_device_id *id) 50 { 51 int ret; 52 53 ret = pcim_enable_device(pci); 54 if (ret) 55 return ret; 56 57 pci_set_master(pci); 58 59 ret = pci_alloc_irq_vectors(pci, 2, 2, PCI_IRQ_MSI); 60 if (ret < 0) 61 return ret; 62 63 ret = ehl_pse_io_dev_create(pci, EHL_PSE_GPIO_NAME, 0); 64 if (ret) 65 return ret; 66 67 return ehl_pse_io_dev_create(pci, EHL_PSE_TIO_NAME, 1); 68 } 69 70 static const struct pci_device_id ehl_pse_io_ids[] = { 71 { PCI_VDEVICE(INTEL, 0x4b88) }, 72 { PCI_VDEVICE(INTEL, 0x4b89) }, 73 { } 74 }; 75 MODULE_DEVICE_TABLE(pci, ehl_pse_io_ids); 76 77 static struct pci_driver ehl_pse_io_driver = { 78 .name = EHL_PSE_IO_NAME, 79 .id_table = ehl_pse_io_ids, 80 .probe = ehl_pse_io_probe, 81 }; 82 module_pci_driver(ehl_pse_io_driver); 83 84 MODULE_AUTHOR("Raag Jadav <raag.jadav@intel.com>"); 85 MODULE_DESCRIPTION("Intel Elkhart Lake PSE I/O driver"); 86 MODULE_LICENSE("GPL"); 87