aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/cell/axon_msi.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms/cell/axon_msi.c')
-rw-r--r--arch/powerpc/platforms/cell/axon_msi.c76
1 files changed, 66 insertions, 10 deletions
diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c
index c39f5c225f2e..896548ba1ca1 100644
--- a/arch/powerpc/platforms/cell/axon_msi.c
+++ b/arch/powerpc/platforms/cell/axon_msi.c
@@ -14,6 +14,7 @@
14#include <linux/pci.h> 14#include <linux/pci.h>
15#include <linux/msi.h> 15#include <linux/msi.h>
16#include <linux/of_platform.h> 16#include <linux/of_platform.h>
17#include <linux/debugfs.h>
17 18
18#include <asm/dcr.h> 19#include <asm/dcr.h>
19#include <asm/machdep.h> 20#include <asm/machdep.h>
@@ -69,8 +70,19 @@ struct axon_msic {
69 dma_addr_t fifo_phys; 70 dma_addr_t fifo_phys;
70 dcr_host_t dcr_host; 71 dcr_host_t dcr_host;
71 u32 read_offset; 72 u32 read_offset;
73#ifdef DEBUG
74 u32 __iomem *trigger;
75#endif
72}; 76};
73 77
78#ifdef DEBUG
79void axon_msi_debug_setup(struct device_node *dn, struct axon_msic *msic);
80#else
81static inline void axon_msi_debug_setup(struct device_node *dn,
82 struct axon_msic *msic) { }
83#endif
84
85
74static void msic_dcr_write(struct axon_msic *msic, unsigned int dcr_n, u32 val) 86static void msic_dcr_write(struct axon_msic *msic, unsigned int dcr_n, u32 val)
75{ 87{
76 pr_debug("axon_msi: dcr_write(0x%x, 0x%x)\n", val, dcr_n); 88 pr_debug("axon_msi: dcr_write(0x%x, 0x%x)\n", val, dcr_n);
@@ -346,7 +358,14 @@ static int axon_msi_probe(struct of_device *device,
346 goto out_free_msic; 358 goto out_free_msic;
347 } 359 }
348 360
349 msic->irq_host = irq_alloc_host(of_node_get(dn), IRQ_HOST_MAP_NOMAP, 361 virq = irq_of_parse_and_map(dn, 0);
362 if (virq == NO_IRQ) {
363 printk(KERN_ERR "axon_msi: irq parse and map failed for %s\n",
364 dn->full_name);
365 goto out_free_fifo;
366 }
367
368 msic->irq_host = irq_alloc_host(dn, IRQ_HOST_MAP_NOMAP,
350 NR_IRQS, &msic_host_ops, 0); 369 NR_IRQS, &msic_host_ops, 0);
351 if (!msic->irq_host) { 370 if (!msic->irq_host) {
352 printk(KERN_ERR "axon_msi: couldn't allocate irq_host for %s\n", 371 printk(KERN_ERR "axon_msi: couldn't allocate irq_host for %s\n",
@@ -356,13 +375,6 @@ static int axon_msi_probe(struct of_device *device,
356 375
357 msic->irq_host->host_data = msic; 376 msic->irq_host->host_data = msic;
358 377
359 virq = irq_of_parse_and_map(dn, 0);
360 if (virq == NO_IRQ) {
361 printk(KERN_ERR "axon_msi: irq parse and map failed for %s\n",
362 dn->full_name);
363 goto out_free_host;
364 }
365
366 set_irq_data(virq, msic); 378 set_irq_data(virq, msic);
367 set_irq_chained_handler(virq, axon_msi_cascade); 379 set_irq_chained_handler(virq, axon_msi_cascade);
368 pr_debug("axon_msi: irq 0x%x setup for axon_msi\n", virq); 380 pr_debug("axon_msi: irq 0x%x setup for axon_msi\n", virq);
@@ -381,12 +393,12 @@ static int axon_msi_probe(struct of_device *device,
381 ppc_md.teardown_msi_irqs = axon_msi_teardown_msi_irqs; 393 ppc_md.teardown_msi_irqs = axon_msi_teardown_msi_irqs;
382 ppc_md.msi_check_device = axon_msi_check_device; 394 ppc_md.msi_check_device = axon_msi_check_device;
383 395
396 axon_msi_debug_setup(dn, msic);
397
384 printk(KERN_DEBUG "axon_msi: setup MSIC on %s\n", dn->full_name); 398 printk(KERN_DEBUG "axon_msi: setup MSIC on %s\n", dn->full_name);
385 399
386 return 0; 400 return 0;
387 401
388out_free_host:
389 kfree(msic->irq_host);
390out_free_fifo: 402out_free_fifo:
391 dma_free_coherent(&device->dev, MSIC_FIFO_SIZE_BYTES, msic->fifo_virt, 403 dma_free_coherent(&device->dev, MSIC_FIFO_SIZE_BYTES, msic->fifo_virt,
392 msic->fifo_phys); 404 msic->fifo_phys);
@@ -418,3 +430,47 @@ static int __init axon_msi_init(void)
418 return of_register_platform_driver(&axon_msi_driver); 430 return of_register_platform_driver(&axon_msi_driver);
419} 431}
420subsys_initcall(axon_msi_init); 432subsys_initcall(axon_msi_init);
433
434
435#ifdef DEBUG
436static int msic_set(void *data, u64 val)
437{
438 struct axon_msic *msic = data;
439 out_le32(msic->trigger, val);
440 return 0;
441}
442
443static int msic_get(void *data, u64 *val)
444{
445 *val = 0;
446 return 0;
447}
448
449DEFINE_SIMPLE_ATTRIBUTE(fops_msic, msic_get, msic_set, "%llu\n");
450
451void axon_msi_debug_setup(struct device_node *dn, struct axon_msic *msic)
452{
453 char name[8];
454 u64 addr;
455
456 addr = of_translate_address(dn, of_get_property(dn, "reg", NULL));
457 if (addr == OF_BAD_ADDR) {
458 pr_debug("axon_msi: couldn't translate reg property\n");
459 return;
460 }
461
462 msic->trigger = ioremap(addr, 0x4);
463 if (!msic->trigger) {
464 pr_debug("axon_msi: ioremap failed\n");
465 return;
466 }
467
468 snprintf(name, sizeof(name), "msic_%d", of_node_to_nid(dn));
469
470 if (!debugfs_create_file(name, 0600, powerpc_debugfs_root,
471 msic, &fops_msic)) {
472 pr_debug("axon_msi: debugfs_create_file failed!\n");
473 return;
474 }
475}
476#endif /* DEBUG */