Lines Matching +full:msi +full:- +full:cell
1 // SPDX-License-Identifier: GPL-2.0-or-later
11 #include <linux/msi.h>
21 #include "cell.h"
51 * To configure the FIFO size as (1 << n) bytes, we write (n - 15) into bits
52 * 8-9 of the MSIC control reg.
54 #define MSIC_CTRL_FIFO_SIZE (((MSIC_FIFO_SIZE_SHIFT - 15) << 8) & 0x300)
58 * the bounds of the FIFO. Also they should always be 16-byte aligned.
60 #define MSIC_FIFO_SIZE_MASK ((MSIC_FIFO_SIZE_BYTES - 1) & ~0xFu)
89 dcr_write(msic->dcr_host, dcr_n, val); in msic_dcr_write()
96 u32 write_offset, msi; in axon_msi_cascade() local
100 write_offset = dcr_read(msic->dcr_host, MSIC_WRITE_OFFSET_REG); in axon_msi_cascade()
106 while (msic->read_offset != write_offset && retry < 100) { in axon_msi_cascade()
107 idx = msic->read_offset / sizeof(__le32); in axon_msi_cascade()
108 msi = le32_to_cpu(msic->fifo_virt[idx]); in axon_msi_cascade()
109 msi &= 0xFFFF; in axon_msi_cascade()
111 pr_devel("axon_msi: woff %x roff %x msi %x\n", in axon_msi_cascade()
112 write_offset, msic->read_offset, msi); in axon_msi_cascade()
114 if (msi < nr_irqs && irq_get_chip_data(msi) == msic) { in axon_msi_cascade()
115 generic_handle_irq(msi); in axon_msi_cascade()
116 msic->fifo_virt[idx] = cpu_to_le32(0xffffffff); in axon_msi_cascade()
126 pr_devel("axon_msi: invalid irq 0x%x!\n", msi); in axon_msi_cascade()
132 msi, retry); in axon_msi_cascade()
136 msic->read_offset += MSIC_FIFO_ENTRY_SIZE; in axon_msi_cascade()
137 msic->read_offset &= MSIC_FIFO_SIZE_MASK; in axon_msi_cascade()
143 msic->read_offset += MSIC_FIFO_ENTRY_SIZE; in axon_msi_cascade()
144 msic->read_offset &= MSIC_FIFO_SIZE_MASK; in axon_msi_cascade()
147 chip->irq_eoi(&desc->irq_data); in axon_msi_cascade()
159 dev_dbg(&dev->dev, "axon_msi: no pci_dn found\n"); in find_msi_translator()
164 ph = of_get_property(dn, "msi-translator", NULL); in find_msi_translator()
170 dev_dbg(&dev->dev, in find_msi_translator()
171 "axon_msi: no msi-translator property found\n"); in find_msi_translator()
179 dev_dbg(&dev->dev, in find_msi_translator()
180 "axon_msi: msi-translator doesn't point to a node\n"); in find_msi_translator()
186 dev_dbg(&dev->dev, "axon_msi: no irq_domain found for node %pOF\n", in find_msi_translator()
191 msic = irq_domain->host_data; in find_msi_translator()
207 dev_dbg(&dev->dev, "axon_msi: no pci_dn found\n"); in setup_msi_msg_address()
208 return -ENODEV; in setup_msi_msg_address()
212 if (!dev->no_64bit_msi) { in setup_msi_msg_address()
213 prop = of_get_property(dn, "msi-address-64", &len); in setup_msi_msg_address()
218 prop = of_get_property(dn, "msi-address-32", &len); in setup_msi_msg_address()
224 dev_dbg(&dev->dev, in setup_msi_msg_address()
225 "axon_msi: no msi-address-(32|64) properties found\n"); in setup_msi_msg_address()
227 return -ENOENT; in setup_msi_msg_address()
232 msg->address_hi = prop[0]; in setup_msi_msg_address()
233 msg->address_lo = prop[1]; in setup_msi_msg_address()
236 msg->address_hi = 0; in setup_msi_msg_address()
237 msg->address_lo = prop[0]; in setup_msi_msg_address()
240 dev_dbg(&dev->dev, in setup_msi_msg_address()
241 "axon_msi: malformed msi-address-(32|64) property\n"); in setup_msi_msg_address()
243 return -EINVAL; in setup_msi_msg_address()
260 return -ENODEV; in axon_msi_setup_msi_irqs()
266 msi_for_each_desc(entry, &dev->dev, MSI_DESC_NOTASSOCIATED) { in axon_msi_setup_msi_irqs()
267 virq = irq_create_direct_mapping(msic->irq_domain); in axon_msi_setup_msi_irqs()
269 dev_warn(&dev->dev, in axon_msi_setup_msi_irqs()
271 return -1; in axon_msi_setup_msi_irqs()
273 dev_dbg(&dev->dev, "axon_msi: allocated virq 0x%x\n", virq); in axon_msi_setup_msi_irqs()
287 dev_dbg(&dev->dev, "axon_msi: tearing down msi irqs\n"); in axon_msi_teardown_msi_irqs()
289 msi_for_each_desc(entry, &dev->dev, MSI_DESC_ASSOCIATED) { in axon_msi_teardown_msi_irqs()
290 irq_set_msi_desc(entry->irq, NULL); in axon_msi_teardown_msi_irqs()
291 irq_dispose_mapping(entry->irq); in axon_msi_teardown_msi_irqs()
299 .name = "AXON-MSI",
305 irq_set_chip_data(virq, h->host_data); in msic_host_map()
317 struct axon_msic *msic = dev_get_drvdata(&device->dev); in axon_msi_shutdown()
321 irq_domain_get_of_node(msic->irq_domain)); in axon_msi_shutdown()
322 tmp = dcr_read(msic->dcr_host, MSIC_CTRL_REG); in axon_msi_shutdown()
329 struct device_node *dn = device->dev.of_node; in axon_msi_probe()
353 msic->dcr_host = dcr_map(dn, dcr_base, dcr_len); in axon_msi_probe()
354 if (!DCR_MAP_OK(msic->dcr_host)) { in axon_msi_probe()
360 msic->fifo_virt = dma_alloc_coherent(&device->dev, MSIC_FIFO_SIZE_BYTES, in axon_msi_probe()
361 &msic->fifo_phys, GFP_KERNEL); in axon_msi_probe()
362 if (!msic->fifo_virt) { in axon_msi_probe()
374 memset(msic->fifo_virt, 0xff, MSIC_FIFO_SIZE_BYTES); in axon_msi_probe()
377 msic->irq_domain = irq_domain_add_nomap(dn, 65536, &msic_host_ops, msic); in axon_msi_probe()
378 if (!msic->irq_domain) { in axon_msi_probe()
389 msic_dcr_write(msic, MSIC_BASE_ADDR_HI_REG, msic->fifo_phys >> 32); in axon_msi_probe()
391 msic->fifo_phys & 0xFFFFFFFF); in axon_msi_probe()
396 msic->read_offset = dcr_read(msic->dcr_host, MSIC_WRITE_OFFSET_REG) in axon_msi_probe()
399 dev_set_drvdata(&device->dev, msic); in axon_msi_probe()
411 dma_free_coherent(&device->dev, MSIC_FIFO_SIZE_BYTES, msic->fifo_virt, in axon_msi_probe()
412 msic->fifo_phys); in axon_msi_probe()
417 return -1; in axon_msi_probe()
422 .compatible = "ibm,axon-msic"
431 .name = "axon-msi",
447 out_le32(msic->trigger, val); in msic_set()
470 msic->trigger = ioremap(addr, 0x4); in axon_msi_debug_setup()
471 if (!msic->trigger) { in axon_msi_debug_setup()