|
23 | 23 | #include <linux/signal.h>
|
24 | 24 | #include <linux/device.h>
|
25 | 25 | #include <linux/spinlock.h>
|
| 26 | +#include <linux/platform_device.h> |
26 | 27 | #include <asm/irq.h>
|
27 | 28 | #include <asm/io.h>
|
28 | 29 | #include <soc/fsl/qe/qe.h>
|
@@ -53,8 +54,8 @@ struct qe_ic {
|
53 | 54 | struct irq_chip hc_irq;
|
54 | 55 |
|
55 | 56 | /* VIRQ numbers of QE high/low irqs */
|
56 |
| - unsigned int virq_high; |
57 |
| - unsigned int virq_low; |
| 57 | + int virq_high; |
| 58 | + int virq_low; |
58 | 59 | };
|
59 | 60 |
|
60 | 61 | /*
|
@@ -404,72 +405,83 @@ static void qe_ic_cascade_muxed_mpic(struct irq_desc *desc)
|
404 | 405 | chip->irq_eoi(&desc->irq_data);
|
405 | 406 | }
|
406 | 407 |
|
407 |
| -static void __init qe_ic_init(struct device_node *node) |
| 408 | +static int qe_ic_init(struct platform_device *pdev) |
408 | 409 | {
|
| 410 | + struct device *dev = &pdev->dev; |
409 | 411 | void (*low_handler)(struct irq_desc *desc);
|
410 | 412 | void (*high_handler)(struct irq_desc *desc);
|
411 | 413 | struct qe_ic *qe_ic;
|
412 |
| - struct resource res; |
413 |
| - u32 ret; |
| 414 | + struct resource *res; |
| 415 | + struct device_node *node = pdev->dev.of_node; |
414 | 416 |
|
415 |
| - ret = of_address_to_resource(node, 0, &res); |
416 |
| - if (ret) |
417 |
| - return; |
| 417 | + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 418 | + if (res == NULL) { |
| 419 | + dev_err(dev, "no memory resource defined\n"); |
| 420 | + return -ENODEV; |
| 421 | + } |
418 | 422 |
|
419 |
| - qe_ic = kzalloc(sizeof(*qe_ic), GFP_KERNEL); |
| 423 | + qe_ic = devm_kzalloc(dev, sizeof(*qe_ic), GFP_KERNEL); |
420 | 424 | if (qe_ic == NULL)
|
421 |
| - return; |
| 425 | + return -ENOMEM; |
422 | 426 |
|
423 |
| - qe_ic->irqhost = irq_domain_add_linear(node, NR_QE_IC_INTS, |
424 |
| - &qe_ic_host_ops, qe_ic); |
425 |
| - if (qe_ic->irqhost == NULL) { |
426 |
| - kfree(qe_ic); |
427 |
| - return; |
| 427 | + qe_ic->regs = devm_ioremap(dev, res->start, resource_size(res)); |
| 428 | + if (qe_ic->regs == NULL) { |
| 429 | + dev_err(dev, "failed to ioremap() registers\n"); |
| 430 | + return -ENODEV; |
428 | 431 | }
|
429 | 432 |
|
430 |
| - qe_ic->regs = ioremap(res.start, resource_size(&res)); |
431 |
| - |
432 | 433 | qe_ic->hc_irq = qe_ic_irq_chip;
|
433 | 434 |
|
434 |
| - qe_ic->virq_high = irq_of_parse_and_map(node, 0); |
435 |
| - qe_ic->virq_low = irq_of_parse_and_map(node, 1); |
| 435 | + qe_ic->virq_high = platform_get_irq(pdev, 0); |
| 436 | + qe_ic->virq_low = platform_get_irq(pdev, 1); |
436 | 437 |
|
437 |
| - if (!qe_ic->virq_low) { |
438 |
| - printk(KERN_ERR "Failed to map QE_IC low IRQ\n"); |
439 |
| - kfree(qe_ic); |
440 |
| - return; |
441 |
| - } |
442 |
| - if (qe_ic->virq_high != qe_ic->virq_low) { |
| 438 | + if (qe_ic->virq_low <= 0) |
| 439 | + return -ENODEV; |
| 440 | + |
| 441 | + if (qe_ic->virq_high > 0 && qe_ic->virq_high != qe_ic->virq_low) { |
443 | 442 | low_handler = qe_ic_cascade_low;
|
444 | 443 | high_handler = qe_ic_cascade_high;
|
445 | 444 | } else {
|
446 | 445 | low_handler = qe_ic_cascade_muxed_mpic;
|
447 | 446 | high_handler = NULL;
|
448 | 447 | }
|
449 | 448 |
|
| 449 | + qe_ic->irqhost = irq_domain_add_linear(node, NR_QE_IC_INTS, |
| 450 | + &qe_ic_host_ops, qe_ic); |
| 451 | + if (qe_ic->irqhost == NULL) { |
| 452 | + dev_err(dev, "failed to add irq domain\n"); |
| 453 | + return -ENODEV; |
| 454 | + } |
| 455 | + |
450 | 456 | qe_ic_write(qe_ic->regs, QEIC_CICR, 0);
|
451 | 457 |
|
452 | 458 | irq_set_handler_data(qe_ic->virq_low, qe_ic);
|
453 | 459 | irq_set_chained_handler(qe_ic->virq_low, low_handler);
|
454 | 460 |
|
455 |
| - if (qe_ic->virq_high && qe_ic->virq_high != qe_ic->virq_low) { |
| 461 | + if (high_handler) { |
456 | 462 | irq_set_handler_data(qe_ic->virq_high, qe_ic);
|
457 | 463 | irq_set_chained_handler(qe_ic->virq_high, high_handler);
|
458 | 464 | }
|
| 465 | + return 0; |
459 | 466 | }
|
| 467 | +static const struct of_device_id qe_ic_ids[] = { |
| 468 | + { .compatible = "fsl,qe-ic"}, |
| 469 | + { .type = "qeic"}, |
| 470 | + {}, |
| 471 | +}; |
460 | 472 |
|
461 |
| -static int __init qe_ic_of_init(void) |
| 473 | +static struct platform_driver qe_ic_driver = |
462 | 474 | {
|
463 |
| - struct device_node *np; |
| 475 | + .driver = { |
| 476 | + .name = "qe-ic", |
| 477 | + .of_match_table = qe_ic_ids, |
| 478 | + }, |
| 479 | + .probe = qe_ic_init, |
| 480 | +}; |
464 | 481 |
|
465 |
| - np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic"); |
466 |
| - if (!np) { |
467 |
| - np = of_find_node_by_type(NULL, "qeic"); |
468 |
| - if (!np) |
469 |
| - return -ENODEV; |
470 |
| - } |
471 |
| - qe_ic_init(np); |
472 |
| - of_node_put(np); |
| 482 | +static int __init qe_ic_of_init(void) |
| 483 | +{ |
| 484 | + platform_driver_register(&qe_ic_driver); |
473 | 485 | return 0;
|
474 | 486 | }
|
475 | 487 | subsys_initcall(qe_ic_of_init);
|
0 commit comments