Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v6.19-rc8 307 lines 7.2 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright (c) 2018-2025 Raspberry Pi Ltd. 4 * 5 * All rights reserved. 6 */ 7 8#include <linux/err.h> 9#include <linux/interrupt.h> 10#include <linux/irq.h> 11#include <linux/irqchip/chained_irq.h> 12#include <linux/irqdomain.h> 13#include <linux/module.h> 14#include <linux/msi.h> 15#include <linux/of_platform.h> 16#include <linux/pci.h> 17#include <linux/platform_device.h> 18 19#define RP1_HW_IRQ_MASK GENMASK(5, 0) 20 21#define REG_SET 0x800 22#define REG_CLR 0xc00 23 24/* MSI-X CFG registers start at 0x8 */ 25#define MSIX_CFG(x) (0x8 + (4 * (x))) 26 27#define MSIX_CFG_IACK_EN BIT(3) 28#define MSIX_CFG_IACK BIT(2) 29#define MSIX_CFG_ENABLE BIT(0) 30 31/* Address map */ 32#define RP1_PCIE_APBS_BASE 0x108000 33 34/* Interrupts */ 35#define RP1_INT_END 61 36 37struct rp1_dev { 38 struct pci_dev *pdev; 39 struct irq_domain *domain; 40 struct irq_data *pcie_irqds[64]; 41 void __iomem *bar1; 42 bool level_triggered_irq[RP1_INT_END]; 43}; 44 45static void msix_cfg_set(struct rp1_dev *rp1, unsigned int hwirq, u32 value) 46{ 47 iowrite32(value, rp1->bar1 + RP1_PCIE_APBS_BASE + REG_SET + MSIX_CFG(hwirq)); 48} 49 50static void msix_cfg_clr(struct rp1_dev *rp1, unsigned int hwirq, u32 value) 51{ 52 iowrite32(value, rp1->bar1 + RP1_PCIE_APBS_BASE + REG_CLR + MSIX_CFG(hwirq)); 53} 54 55static void rp1_mask_irq(struct irq_data *irqd) 56{ 57 struct rp1_dev *rp1 = irqd->domain->host_data; 58 struct irq_data *pcie_irqd = rp1->pcie_irqds[irqd->hwirq]; 59 60 pci_msi_mask_irq(pcie_irqd); 61} 62 63static void rp1_unmask_irq(struct irq_data *irqd) 64{ 65 struct rp1_dev *rp1 = irqd->domain->host_data; 66 struct irq_data *pcie_irqd = rp1->pcie_irqds[irqd->hwirq]; 67 68 pci_msi_unmask_irq(pcie_irqd); 69} 70 71static int rp1_irq_set_type(struct irq_data *irqd, unsigned int type) 72{ 73 struct rp1_dev *rp1 = irqd->domain->host_data; 74 unsigned int hwirq = (unsigned int)irqd->hwirq; 75 76 switch (type) { 77 case IRQ_TYPE_LEVEL_HIGH: 78 dev_dbg(&rp1->pdev->dev, "MSIX IACK EN for IRQ %u\n", hwirq); 79 msix_cfg_set(rp1, hwirq, MSIX_CFG_IACK_EN); 80 rp1->level_triggered_irq[hwirq] = true; 81 break; 82 case IRQ_TYPE_EDGE_RISING: 83 msix_cfg_clr(rp1, hwirq, MSIX_CFG_IACK_EN); 84 rp1->level_triggered_irq[hwirq] = false; 85 break; 86 default: 87 return -EINVAL; 88 } 89 90 return 0; 91} 92 93static struct irq_chip rp1_irq_chip = { 94 .name = "rp1_irq_chip", 95 .irq_mask = rp1_mask_irq, 96 .irq_unmask = rp1_unmask_irq, 97 .irq_set_type = rp1_irq_set_type, 98}; 99 100static void rp1_chained_handle_irq(struct irq_desc *desc) 101{ 102 unsigned int hwirq = desc->irq_data.hwirq & RP1_HW_IRQ_MASK; 103 struct rp1_dev *rp1 = irq_desc_get_handler_data(desc); 104 struct irq_chip *chip = irq_desc_get_chip(desc); 105 unsigned int virq; 106 107 chained_irq_enter(chip, desc); 108 109 virq = irq_find_mapping(rp1->domain, hwirq); 110 generic_handle_irq(virq); 111 if (rp1->level_triggered_irq[hwirq]) 112 msix_cfg_set(rp1, hwirq, MSIX_CFG_IACK); 113 114 chained_irq_exit(chip, desc); 115} 116 117static int rp1_irq_xlate(struct irq_domain *d, struct device_node *node, 118 const u32 *intspec, unsigned int intsize, 119 unsigned long *out_hwirq, unsigned int *out_type) 120{ 121 struct rp1_dev *rp1 = d->host_data; 122 struct irq_data *pcie_irqd; 123 unsigned long hwirq; 124 int pcie_irq; 125 int ret; 126 127 ret = irq_domain_xlate_twocell(d, node, intspec, intsize, 128 &hwirq, out_type); 129 if (ret) 130 return ret; 131 132 pcie_irq = pci_irq_vector(rp1->pdev, hwirq); 133 pcie_irqd = irq_get_irq_data(pcie_irq); 134 rp1->pcie_irqds[hwirq] = pcie_irqd; 135 *out_hwirq = hwirq; 136 137 return 0; 138} 139 140static int rp1_irq_activate(struct irq_domain *d, struct irq_data *irqd, 141 bool reserve) 142{ 143 struct rp1_dev *rp1 = d->host_data; 144 145 msix_cfg_set(rp1, (unsigned int)irqd->hwirq, MSIX_CFG_ENABLE); 146 147 return 0; 148} 149 150static void rp1_irq_deactivate(struct irq_domain *d, struct irq_data *irqd) 151{ 152 struct rp1_dev *rp1 = d->host_data; 153 154 msix_cfg_clr(rp1, (unsigned int)irqd->hwirq, MSIX_CFG_ENABLE); 155} 156 157static const struct irq_domain_ops rp1_domain_ops = { 158 .xlate = rp1_irq_xlate, 159 .activate = rp1_irq_activate, 160 .deactivate = rp1_irq_deactivate, 161}; 162 163static void rp1_unregister_interrupts(struct pci_dev *pdev) 164{ 165 struct rp1_dev *rp1 = pci_get_drvdata(pdev); 166 int irq, i; 167 168 if (rp1->domain) { 169 for (i = 0; i < RP1_INT_END; i++) { 170 irq = irq_find_mapping(rp1->domain, i); 171 irq_dispose_mapping(irq); 172 } 173 174 irq_domain_remove(rp1->domain); 175 } 176 177 pci_free_irq_vectors(pdev); 178} 179 180static int rp1_probe(struct pci_dev *pdev, const struct pci_device_id *id) 181{ 182 struct device *dev = &pdev->dev; 183 struct device_node *rp1_node; 184 struct rp1_dev *rp1; 185 int err = 0; 186 int i; 187 188 rp1_node = dev_of_node(dev); 189 190 if (!rp1_node) { 191 dev_err(dev, "Missing of_node for device\n"); 192 err = -EINVAL; 193 goto err_put_node; 194 } 195 196 rp1 = devm_kzalloc(&pdev->dev, sizeof(*rp1), GFP_KERNEL); 197 if (!rp1) { 198 err = -ENOMEM; 199 goto err_put_node; 200 } 201 202 rp1->pdev = pdev; 203 204 if (pci_resource_len(pdev, 1) <= 0x10000) { 205 dev_err(&pdev->dev, 206 "Not initialized - is the firmware running?\n"); 207 err = -EINVAL; 208 goto err_put_node; 209 } 210 211 err = pcim_enable_device(pdev); 212 if (err < 0) { 213 err = dev_err_probe(&pdev->dev, err, 214 "Enabling PCI device has failed"); 215 goto err_put_node; 216 } 217 218 rp1->bar1 = pcim_iomap(pdev, 1, 0); 219 if (!rp1->bar1) { 220 dev_err(&pdev->dev, "Cannot map PCI BAR\n"); 221 err = -EIO; 222 goto err_put_node; 223 } 224 225 pci_set_master(pdev); 226 227 err = pci_alloc_irq_vectors(pdev, RP1_INT_END, RP1_INT_END, 228 PCI_IRQ_MSIX); 229 if (err < 0) { 230 err = dev_err_probe(&pdev->dev, err, 231 "Failed to allocate MSI-X vectors\n"); 232 goto err_put_node; 233 } else if (err != RP1_INT_END) { 234 dev_err(&pdev->dev, "Cannot allocate enough interrupts\n"); 235 err = -EINVAL; 236 goto err_put_node; 237 } 238 239 pci_set_drvdata(pdev, rp1); 240 rp1->domain = irq_domain_add_linear(rp1_node, RP1_INT_END, 241 &rp1_domain_ops, rp1); 242 if (!rp1->domain) { 243 dev_err(&pdev->dev, "Error creating IRQ domain\n"); 244 err = -ENOMEM; 245 goto err_unregister_interrupts; 246 } 247 248 for (i = 0; i < RP1_INT_END; i++) { 249 unsigned int irq = irq_create_mapping(rp1->domain, i); 250 251 if (!irq) { 252 dev_err(&pdev->dev, "Failed to create IRQ mapping\n"); 253 err = -EINVAL; 254 goto err_unregister_interrupts; 255 } 256 257 irq_set_chip_and_handler(irq, &rp1_irq_chip, handle_level_irq); 258 irq_set_probe(irq); 259 irq_set_chained_handler_and_data(pci_irq_vector(pdev, i), 260 rp1_chained_handle_irq, rp1); 261 } 262 263 err = of_platform_default_populate(rp1_node, NULL, dev); 264 if (err) { 265 dev_err_probe(&pdev->dev, err, "Error populating devicetree\n"); 266 goto err_unregister_interrupts; 267 } 268 269 of_node_put(rp1_node); 270 271 return 0; 272 273err_unregister_interrupts: 274 rp1_unregister_interrupts(pdev); 275err_put_node: 276 of_node_put(rp1_node); 277 278 return err; 279} 280 281static void rp1_remove(struct pci_dev *pdev) 282{ 283 struct device *dev = &pdev->dev; 284 285 of_platform_depopulate(dev); 286 rp1_unregister_interrupts(pdev); 287} 288 289static const struct pci_device_id dev_id_table[] = { 290 { PCI_DEVICE(PCI_VENDOR_ID_RPI, PCI_DEVICE_ID_RPI_RP1_C0), }, 291 { } 292}; 293MODULE_DEVICE_TABLE(pci, dev_id_table); 294 295static struct pci_driver rp1_driver = { 296 .name = KBUILD_MODNAME, 297 .id_table = dev_id_table, 298 .probe = rp1_probe, 299 .remove = rp1_remove, 300}; 301 302module_pci_driver(rp1_driver); 303 304MODULE_AUTHOR("Phil Elwell <phil@raspberrypi.com>"); 305MODULE_AUTHOR("Andrea della Porta <andrea.porta@suse.com>"); 306MODULE_DESCRIPTION("RaspberryPi RP1 misc device"); 307MODULE_LICENSE("GPL");