1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Microchip LAN966x PCI driver 4 * 5 * Copyright (c) 2024 Microchip Technology Inc. and its subsidiaries. 6 * 7 * Authors: 8 * Clément Léger <clement.leger@bootlin.com> 9 * Hervé Codina <herve.codina@bootlin.com> 10 */ 11 12 #include <linux/device.h> 13 #include <linux/irq.h> 14 #include <linux/irqdomain.h> 15 #include <linux/module.h> 16 #include <linux/of_platform.h> 17 #include <linux/pci.h> 18 #include <linux/pci_ids.h> 19 #include <linux/slab.h> 20 21 /* Embedded dtbo symbols created by cmd_wrap_S_dtb in scripts/Makefile.lib */ 22 extern char __dtbo_lan966x_pci_begin[]; 23 extern char __dtbo_lan966x_pci_end[]; 24 25 struct pci_dev_intr_ctrl { 26 struct pci_dev *pci_dev; 27 struct irq_domain *irq_domain; 28 int irq; 29 }; 30 31 static int pci_dev_irq_domain_map(struct irq_domain *d, unsigned int virq, irq_hw_number_t hw) 32 { 33 irq_set_chip_and_handler(virq, &dummy_irq_chip, handle_simple_irq); 34 return 0; 35 } 36 37 static const struct irq_domain_ops pci_dev_irq_domain_ops = { 38 .map = pci_dev_irq_domain_map, 39 .xlate = irq_domain_xlate_onecell, 40 }; 41 42 static irqreturn_t pci_dev_irq_handler(int irq, void *data) 43 { 44 struct pci_dev_intr_ctrl *intr_ctrl = data; 45 int ret; 46 47 ret = generic_handle_domain_irq(intr_ctrl->irq_domain, 0); 48 return ret ? IRQ_NONE : IRQ_HANDLED; 49 } 50 51 static struct pci_dev_intr_ctrl *pci_dev_create_intr_ctrl(struct pci_dev *pdev) 52 { 53 struct pci_dev_intr_ctrl *intr_ctrl __free(kfree) = NULL; 54 struct fwnode_handle *fwnode; 55 int ret; 56 57 fwnode = dev_fwnode(&pdev->dev); 58 if (!fwnode) 59 return ERR_PTR(-ENODEV); 60 61 intr_ctrl = kmalloc(sizeof(*intr_ctrl), GFP_KERNEL); 62 if (!intr_ctrl) 63 return ERR_PTR(-ENOMEM); 64 65 intr_ctrl->pci_dev = pdev; 66 67 intr_ctrl->irq_domain = irq_domain_create_linear(fwnode, 1, &pci_dev_irq_domain_ops, 68 intr_ctrl); 69 if (!intr_ctrl->irq_domain) { 70 pci_err(pdev, "Failed to create irqdomain\n"); 71 return ERR_PTR(-ENOMEM); 72 } 73 74 ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_INTX); 75 if (ret < 0) { 76 pci_err(pdev, "Unable alloc irq vector (%d)\n", ret); 77 goto err_remove_domain; 78 } 79 intr_ctrl->irq = pci_irq_vector(pdev, 0); 80 ret = request_irq(intr_ctrl->irq, pci_dev_irq_handler, IRQF_SHARED, 81 pci_name(pdev), intr_ctrl); 82 if (ret) { 83 pci_err(pdev, "Unable to request irq %d (%d)\n", intr_ctrl->irq, ret); 84 goto err_free_irq_vector; 85 } 86 87 return_ptr(intr_ctrl); 88 89 err_free_irq_vector: 90 pci_free_irq_vectors(pdev); 91 err_remove_domain: 92 irq_domain_remove(intr_ctrl->irq_domain); 93 return ERR_PTR(ret); 94 } 95 96 static void pci_dev_remove_intr_ctrl(struct pci_dev_intr_ctrl *intr_ctrl) 97 { 98 free_irq(intr_ctrl->irq, intr_ctrl); 99 pci_free_irq_vectors(intr_ctrl->pci_dev); 100 irq_dispose_mapping(irq_find_mapping(intr_ctrl->irq_domain, 0)); 101 irq_domain_remove(intr_ctrl->irq_domain); 102 kfree(intr_ctrl); 103 } 104 105 static void devm_pci_dev_remove_intr_ctrl(void *intr_ctrl) 106 { 107 pci_dev_remove_intr_ctrl(intr_ctrl); 108 } 109 110 static int devm_pci_dev_create_intr_ctrl(struct pci_dev *pdev) 111 { 112 struct pci_dev_intr_ctrl *intr_ctrl; 113 114 intr_ctrl = pci_dev_create_intr_ctrl(pdev); 115 if (IS_ERR(intr_ctrl)) 116 return PTR_ERR(intr_ctrl); 117 118 return devm_add_action_or_reset(&pdev->dev, devm_pci_dev_remove_intr_ctrl, intr_ctrl); 119 } 120 121 struct lan966x_pci { 122 struct device *dev; 123 int ovcs_id; 124 }; 125 126 static int lan966x_pci_load_overlay(struct lan966x_pci *data) 127 { 128 u32 dtbo_size = __dtbo_lan966x_pci_end - __dtbo_lan966x_pci_begin; 129 void *dtbo_start = __dtbo_lan966x_pci_begin; 130 131 return of_overlay_fdt_apply(dtbo_start, dtbo_size, &data->ovcs_id, dev_of_node(data->dev)); 132 } 133 134 static void lan966x_pci_unload_overlay(struct lan966x_pci *data) 135 { 136 of_overlay_remove(&data->ovcs_id); 137 } 138 139 static int lan966x_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) 140 { 141 struct device *dev = &pdev->dev; 142 struct lan966x_pci *data; 143 int ret; 144 145 /* 146 * On ACPI system, fwnode can point to the ACPI node. 147 * This driver needs an of_node to be used as the device-tree overlay 148 * target. This of_node should be set by the PCI core if it succeeds in 149 * creating it (CONFIG_PCI_DYNAMIC_OF_NODES feature). 150 * Check here for the validity of this of_node. 151 */ 152 if (!dev_of_node(dev)) 153 return dev_err_probe(dev, -EINVAL, "Missing of_node for device\n"); 154 155 /* Need to be done before devm_pci_dev_create_intr_ctrl. 156 * It allocates an IRQ and so pdev->irq is updated. 157 */ 158 ret = pcim_enable_device(pdev); 159 if (ret) 160 return ret; 161 162 ret = devm_pci_dev_create_intr_ctrl(pdev); 163 if (ret) 164 return ret; 165 166 data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); 167 if (!data) 168 return -ENOMEM; 169 170 pci_set_drvdata(pdev, data); 171 data->dev = dev; 172 173 ret = lan966x_pci_load_overlay(data); 174 if (ret) 175 return ret; 176 177 pci_set_master(pdev); 178 179 ret = of_platform_default_populate(dev_of_node(dev), NULL, dev); 180 if (ret) 181 goto err_unload_overlay; 182 183 return 0; 184 185 err_unload_overlay: 186 lan966x_pci_unload_overlay(data); 187 return ret; 188 } 189 190 static void lan966x_pci_remove(struct pci_dev *pdev) 191 { 192 struct lan966x_pci *data = pci_get_drvdata(pdev); 193 194 of_platform_depopulate(data->dev); 195 196 lan966x_pci_unload_overlay(data); 197 } 198 199 static struct pci_device_id lan966x_pci_ids[] = { 200 { PCI_DEVICE(PCI_VENDOR_ID_EFAR, 0x9660) }, 201 { } 202 }; 203 MODULE_DEVICE_TABLE(pci, lan966x_pci_ids); 204 205 static struct pci_driver lan966x_pci_driver = { 206 .name = "mchp_lan966x_pci", 207 .id_table = lan966x_pci_ids, 208 .probe = lan966x_pci_probe, 209 .remove = lan966x_pci_remove, 210 }; 211 module_pci_driver(lan966x_pci_driver); 212 213 MODULE_AUTHOR("Herve Codina <herve.codina@bootlin.com>"); 214 MODULE_DESCRIPTION("Microchip LAN966x PCI driver"); 215 MODULE_LICENSE("GPL"); 216