Lines Matching +full:msi +full:- +full:x
1 // SPDX-License-Identifier: GPL-2.0-or-later
11 #include <linux/msi.h>
52 * To configure the FIFO size as (1 << n) bytes, we write (n - 15) into bits
53 * 8-9 of the MSIC control reg.
55 #define MSIC_CTRL_FIFO_SIZE (((MSIC_FIFO_SIZE_SHIFT - 15) << 8) & 0x300)
59 * the bounds of the FIFO. Also they should always be 16-byte aligned.
61 #define MSIC_FIFO_SIZE_MASK ((MSIC_FIFO_SIZE_BYTES - 1) & ~0xFu)
88 pr_devel("axon_msi: dcr_write(0x%x, 0x%x)\n", val, dcr_n); in msic_dcr_write()
90 dcr_write(msic->dcr_host, dcr_n, val); in msic_dcr_write()
97 u32 write_offset, msi; in axon_msi_cascade() local
101 write_offset = dcr_read(msic->dcr_host, MSIC_WRITE_OFFSET_REG); in axon_msi_cascade()
102 pr_devel("axon_msi: original write_offset 0x%x\n", write_offset); in axon_msi_cascade()
107 while (msic->read_offset != write_offset && retry < 100) { in axon_msi_cascade()
108 idx = msic->read_offset / sizeof(__le32); in axon_msi_cascade()
109 msi = le32_to_cpu(msic->fifo_virt[idx]); in axon_msi_cascade()
110 msi &= 0xFFFF; in axon_msi_cascade()
112 pr_devel("axon_msi: woff %x roff %x msi %x\n", in axon_msi_cascade()
113 write_offset, msic->read_offset, msi); in axon_msi_cascade()
115 if (msi < nr_irqs && irq_get_chip_data(msi) == msic) { in axon_msi_cascade()
116 generic_handle_irq(msi); in axon_msi_cascade()
117 msic->fifo_virt[idx] = cpu_to_le32(0xffffffff); in axon_msi_cascade()
127 pr_devel("axon_msi: invalid irq 0x%x!\n", msi); in axon_msi_cascade()
132 pr_devel("axon_msi: late irq 0x%x, retry %d\n", in axon_msi_cascade()
133 msi, retry); in axon_msi_cascade()
137 msic->read_offset += MSIC_FIFO_ENTRY_SIZE; in axon_msi_cascade()
138 msic->read_offset &= MSIC_FIFO_SIZE_MASK; in axon_msi_cascade()
144 msic->read_offset += MSIC_FIFO_ENTRY_SIZE; in axon_msi_cascade()
145 msic->read_offset &= MSIC_FIFO_SIZE_MASK; in axon_msi_cascade()
148 chip->irq_eoi(&desc->irq_data); in axon_msi_cascade()
160 dev_dbg(&dev->dev, "axon_msi: no pci_dn found\n"); in find_msi_translator()
165 ph = of_get_property(dn, "msi-translator", NULL); in find_msi_translator()
171 dev_dbg(&dev->dev, in find_msi_translator()
172 "axon_msi: no msi-translator property found\n"); in find_msi_translator()
180 dev_dbg(&dev->dev, in find_msi_translator()
181 "axon_msi: msi-translator doesn't point to a node\n"); in find_msi_translator()
187 dev_dbg(&dev->dev, "axon_msi: no irq_domain found for node %pOF\n", in find_msi_translator()
192 msic = irq_domain->host_data; in find_msi_translator()
208 dev_dbg(&dev->dev, "axon_msi: no pci_dn found\n"); in setup_msi_msg_address()
209 return -ENODEV; in setup_msi_msg_address()
213 if (!dev->no_64bit_msi) { in setup_msi_msg_address()
214 prop = of_get_property(dn, "msi-address-64", &len); in setup_msi_msg_address()
219 prop = of_get_property(dn, "msi-address-32", &len); in setup_msi_msg_address()
225 dev_dbg(&dev->dev, in setup_msi_msg_address()
226 "axon_msi: no msi-address-(32|64) properties found\n"); in setup_msi_msg_address()
228 return -ENOENT; in setup_msi_msg_address()
233 msg->address_hi = prop[0]; in setup_msi_msg_address()
234 msg->address_lo = prop[1]; in setup_msi_msg_address()
237 msg->address_hi = 0; in setup_msi_msg_address()
238 msg->address_lo = prop[0]; in setup_msi_msg_address()
241 dev_dbg(&dev->dev, in setup_msi_msg_address()
242 "axon_msi: malformed msi-address-(32|64) property\n"); in setup_msi_msg_address()
244 return -EINVAL; in setup_msi_msg_address()
261 return -ENODEV; in axon_msi_setup_msi_irqs()
267 msi_for_each_desc(entry, &dev->dev, MSI_DESC_NOTASSOCIATED) { in axon_msi_setup_msi_irqs()
268 virq = irq_create_direct_mapping(msic->irq_domain); in axon_msi_setup_msi_irqs()
270 dev_warn(&dev->dev, in axon_msi_setup_msi_irqs()
272 return -1; in axon_msi_setup_msi_irqs()
274 dev_dbg(&dev->dev, "axon_msi: allocated virq 0x%x\n", virq); in axon_msi_setup_msi_irqs()
288 dev_dbg(&dev->dev, "axon_msi: tearing down msi irqs\n"); in axon_msi_teardown_msi_irqs()
290 msi_for_each_desc(entry, &dev->dev, MSI_DESC_ASSOCIATED) { in axon_msi_teardown_msi_irqs()
291 irq_set_msi_desc(entry->irq, NULL); in axon_msi_teardown_msi_irqs()
292 irq_dispose_mapping(entry->irq); in axon_msi_teardown_msi_irqs()
293 entry->irq = 0; in axon_msi_teardown_msi_irqs()
301 .name = "AXON-MSI",
307 irq_set_chip_data(virq, h->host_data); in msic_host_map()
319 struct axon_msic *msic = dev_get_drvdata(&device->dev); in axon_msi_shutdown()
323 irq_domain_get_of_node(msic->irq_domain)); in axon_msi_shutdown()
324 tmp = dcr_read(msic->dcr_host, MSIC_CTRL_REG); in axon_msi_shutdown()
331 struct device_node *dn = device->dev.of_node; in axon_msi_probe()
355 msic->dcr_host = dcr_map(dn, dcr_base, dcr_len); in axon_msi_probe()
356 if (!DCR_MAP_OK(msic->dcr_host)) { in axon_msi_probe()
362 msic->fifo_virt = dma_alloc_coherent(&device->dev, MSIC_FIFO_SIZE_BYTES, in axon_msi_probe()
363 &msic->fifo_phys, GFP_KERNEL); in axon_msi_probe()
364 if (!msic->fifo_virt) { in axon_msi_probe()
376 memset(msic->fifo_virt, 0xff, MSIC_FIFO_SIZE_BYTES); in axon_msi_probe()
379 msic->irq_domain = irq_domain_add_nomap(dn, 65536, &msic_host_ops, msic); in axon_msi_probe()
380 if (!msic->irq_domain) { in axon_msi_probe()
388 pr_devel("axon_msi: irq 0x%x setup for axon_msi\n", virq); in axon_msi_probe()
391 msic_dcr_write(msic, MSIC_BASE_ADDR_HI_REG, msic->fifo_phys >> 32); in axon_msi_probe()
393 msic->fifo_phys & 0xFFFFFFFF); in axon_msi_probe()
398 msic->read_offset = dcr_read(msic->dcr_host, MSIC_WRITE_OFFSET_REG) in axon_msi_probe()
401 dev_set_drvdata(&device->dev, msic); in axon_msi_probe()
413 dma_free_coherent(&device->dev, MSIC_FIFO_SIZE_BYTES, msic->fifo_virt, in axon_msi_probe()
414 msic->fifo_phys); in axon_msi_probe()
419 return -1; in axon_msi_probe()
424 .compatible = "ibm,axon-msic"
433 .name = "axon-msi",
449 out_le32(msic->trigger, val); in msic_set()
471 msic->trigger = ioremap(res.start, 0x4); in axon_msi_debug_setup()
472 if (!msic->trigger) { in axon_msi_debug_setup()