aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeert Uytterhoeven <geert+renesas@glider.be>2015-11-24 10:08:13 -0500
committerJason Cooper <jason@lakedaemon.net>2015-11-24 11:54:19 -0500
commit86e57ca735a72b44aab90a649157a678b7069a6d (patch)
treee38a3ad8ad6d7428167f6275925545fb52560f37
parent1affe5946f7293b3747bfe7ef25dc5cfe9869012 (diff)
irqchip/renesas-intc-irqpin: Improve clock error handling and reporting
If the Renesas External IRQ Pin driver cannot find a functional clock, it prints a warning, .e.g. renesas_intc_irqpin fe78001c.interrupt-controller: unable to get clock and continues, as the clock is optional, depending on the SoC type. This warning may confuse users. To fix this, add a flag to indicate that the clock is mandatory or optional, and add a few more compatible entries: - If the clock is mandatory (on R-Mobile A1 or SH-Mobile AG5), a missing clock is now treated as a fatal error, - If the clock is optional (on R-Car Gen1, or using the generic "renesas,intc-irqpin" compatible value), the warning is no longer printed. This requires making struct intc_irqpin_irlm_config more generic by renaming it to intc_irqpin_config, and adding a flag to indicate if IRLM is needed. The new clock flag is merged with the existing shared_irqs boolean into a bitfield to save space. Suggested-by: Magnus Damm <magnus.damm@gmail.com> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be> Link: https://lkml.kernel.org/r/1448377693-19597-1-git-send-email-geert+renesas@glider.be Signed-off-by: Jason Cooper <jason@lakedaemon.net>
-rw-r--r--drivers/irqchip/irq-renesas-intc-irqpin.c45
1 files changed, 33 insertions, 12 deletions
diff --git a/drivers/irqchip/irq-renesas-intc-irqpin.c b/drivers/irqchip/irq-renesas-intc-irqpin.c
index 7f6cf19aa6ac..713177d97c7a 100644
--- a/drivers/irqchip/irq-renesas-intc-irqpin.c
+++ b/drivers/irqchip/irq-renesas-intc-irqpin.c
@@ -79,12 +79,15 @@ struct intc_irqpin_priv {
79 struct irq_chip irq_chip; 79 struct irq_chip irq_chip;
80 struct irq_domain *irq_domain; 80 struct irq_domain *irq_domain;
81 struct clk *clk; 81 struct clk *clk;
82 bool shared_irqs; 82 unsigned shared_irqs:1;
83 unsigned needs_clk:1;
83 u8 shared_irq_mask; 84 u8 shared_irq_mask;
84}; 85};
85 86
86struct intc_irqpin_irlm_config { 87struct intc_irqpin_config {
87 unsigned int irlm_bit; 88 unsigned int irlm_bit;
89 unsigned needs_irlm:1;
90 unsigned needs_clk:1;
88}; 91};
89 92
90static unsigned long intc_irqpin_read32(void __iomem *iomem) 93static unsigned long intc_irqpin_read32(void __iomem *iomem)
@@ -359,8 +362,15 @@ static const struct irq_domain_ops intc_irqpin_irq_domain_ops = {
359 .xlate = irq_domain_xlate_twocell, 362 .xlate = irq_domain_xlate_twocell,
360}; 363};
361 364
362static const struct intc_irqpin_irlm_config intc_irqpin_irlm_r8a777x = { 365static const struct intc_irqpin_config intc_irqpin_irlm_r8a777x = {
363 .irlm_bit = 23, /* ICR0.IRLM0 */ 366 .irlm_bit = 23, /* ICR0.IRLM0 */
367 .needs_irlm = 1,
368 .needs_clk = 0,
369};
370
371static const struct intc_irqpin_config intc_irqpin_rmobile = {
372 .needs_irlm = 0,
373 .needs_clk = 1,
364}; 374};
365 375
366static const struct of_device_id intc_irqpin_dt_ids[] = { 376static const struct of_device_id intc_irqpin_dt_ids[] = {
@@ -369,12 +379,17 @@ static const struct of_device_id intc_irqpin_dt_ids[] = {
369 .data = &intc_irqpin_irlm_r8a777x }, 379 .data = &intc_irqpin_irlm_r8a777x },
370 { .compatible = "renesas,intc-irqpin-r8a7779", 380 { .compatible = "renesas,intc-irqpin-r8a7779",
371 .data = &intc_irqpin_irlm_r8a777x }, 381 .data = &intc_irqpin_irlm_r8a777x },
382 { .compatible = "renesas,intc-irqpin-r8a7740",
383 .data = &intc_irqpin_rmobile },
384 { .compatible = "renesas,intc-irqpin-sh73a0",
385 .data = &intc_irqpin_rmobile },
372 {}, 386 {},
373}; 387};
374MODULE_DEVICE_TABLE(of, intc_irqpin_dt_ids); 388MODULE_DEVICE_TABLE(of, intc_irqpin_dt_ids);
375 389
376static int intc_irqpin_probe(struct platform_device *pdev) 390static int intc_irqpin_probe(struct platform_device *pdev)
377{ 391{
392 const struct intc_irqpin_config *config = NULL;
378 struct device *dev = &pdev->dev; 393 struct device *dev = &pdev->dev;
379 const struct of_device_id *of_id; 394 const struct of_device_id *of_id;
380 struct intc_irqpin_priv *p; 395 struct intc_irqpin_priv *p;
@@ -407,9 +422,19 @@ static int intc_irqpin_probe(struct platform_device *pdev)
407 p->pdev = pdev; 422 p->pdev = pdev;
408 platform_set_drvdata(pdev, p); 423 platform_set_drvdata(pdev, p);
409 424
425 of_id = of_match_device(intc_irqpin_dt_ids, dev);
426 if (of_id && of_id->data) {
427 config = of_id->data;
428 p->needs_clk = config->needs_clk;
429 }
430
410 p->clk = devm_clk_get(dev, NULL); 431 p->clk = devm_clk_get(dev, NULL);
411 if (IS_ERR(p->clk)) { 432 if (IS_ERR(p->clk)) {
412 dev_warn(dev, "unable to get clock\n"); 433 if (p->needs_clk) {
434 dev_err(dev, "unable to get clock\n");
435 ret = PTR_ERR(p->clk);
436 goto err0;
437 }
413 p->clk = NULL; 438 p->clk = NULL;
414 } 439 }
415 440
@@ -479,14 +504,10 @@ static int intc_irqpin_probe(struct platform_device *pdev)
479 } 504 }
480 505
481 /* configure "individual IRQ mode" where needed */ 506 /* configure "individual IRQ mode" where needed */
482 of_id = of_match_device(intc_irqpin_dt_ids, dev); 507 if (config && config->needs_irlm) {
483 if (of_id && of_id->data) {
484 const struct intc_irqpin_irlm_config *irlm_config = of_id->data;
485
486 if (io[INTC_IRQPIN_REG_IRLM]) 508 if (io[INTC_IRQPIN_REG_IRLM])
487 intc_irqpin_read_modify_write(p, INTC_IRQPIN_REG_IRLM, 509 intc_irqpin_read_modify_write(p, INTC_IRQPIN_REG_IRLM,
488 irlm_config->irlm_bit, 510 config->irlm_bit, 1, 1);
489 1, 1);
490 else 511 else
491 dev_warn(dev, "unable to select IRLM mode\n"); 512 dev_warn(dev, "unable to select IRLM mode\n");
492 } 513 }
@@ -500,10 +521,10 @@ static int intc_irqpin_probe(struct platform_device *pdev)
500 521
501 /* scan for shared interrupt lines */ 522 /* scan for shared interrupt lines */
502 ref_irq = p->irq[0].requested_irq; 523 ref_irq = p->irq[0].requested_irq;
503 p->shared_irqs = true; 524 p->shared_irqs = 1;
504 for (k = 1; k < nirqs; k++) { 525 for (k = 1; k < nirqs; k++) {
505 if (ref_irq != p->irq[k].requested_irq) { 526 if (ref_irq != p->irq[k].requested_irq) {
506 p->shared_irqs = false; 527 p->shared_irqs = 0;
507 break; 528 break;
508 } 529 }
509 } 530 }