aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd
diff options
context:
space:
mode:
authorLee Jones <lee.jones@linaro.org>2012-09-24 04:11:46 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2012-09-24 17:04:53 -0400
commitf3f1f0a1eac6fd1529d552b8e2a0e1ac07293c62 (patch)
tree74e4f13bcc3f46d81a135dfabda6dddfdc940e8b /drivers/mfd
parent0f471916d4d03503cf6fb696f7c8baf12fec30b9 (diff)
mfd: Provide the PRCMU with its own IRQ domain
The PRCMU has its own USB, Thermal, GPIO, Modem, HSI and RTC drivers, amongst other things. This patch allows those subordinate devices to use it as an interrupt controller as and when they are DT enabled. Signed-off-by: Lee Jones <lee.jones@linaro.org> Acked-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/db8500-prcmu.c47
1 files changed, 35 insertions, 12 deletions
diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c
index 6fb11b76071e..bac4876d090f 100644
--- a/drivers/mfd/db8500-prcmu.c
+++ b/drivers/mfd/db8500-prcmu.c
@@ -270,6 +270,8 @@ static struct {
270 struct prcmu_fw_version version; 270 struct prcmu_fw_version version;
271} fw_info; 271} fw_info;
272 272
273static struct irq_domain *db8500_irq_domain;
274
273/* 275/*
274 * This vector maps irq numbers to the bits in the bit field used in 276 * This vector maps irq numbers to the bits in the bit field used in
275 * communication with the PRCMU firmware. 277 * communication with the PRCMU firmware.
@@ -2623,7 +2625,7 @@ static void prcmu_irq_mask(struct irq_data *d)
2623 2625
2624 spin_lock_irqsave(&mb0_transfer.dbb_irqs_lock, flags); 2626 spin_lock_irqsave(&mb0_transfer.dbb_irqs_lock, flags);
2625 2627
2626 mb0_transfer.req.dbb_irqs &= ~prcmu_irq_bit[d->irq - IRQ_PRCMU_BASE]; 2628 mb0_transfer.req.dbb_irqs &= ~prcmu_irq_bit[d->hwirq];
2627 2629
2628 spin_unlock_irqrestore(&mb0_transfer.dbb_irqs_lock, flags); 2630 spin_unlock_irqrestore(&mb0_transfer.dbb_irqs_lock, flags);
2629 2631
@@ -2637,7 +2639,7 @@ static void prcmu_irq_unmask(struct irq_data *d)
2637 2639
2638 spin_lock_irqsave(&mb0_transfer.dbb_irqs_lock, flags); 2640 spin_lock_irqsave(&mb0_transfer.dbb_irqs_lock, flags);
2639 2641
2640 mb0_transfer.req.dbb_irqs |= prcmu_irq_bit[d->irq - IRQ_PRCMU_BASE]; 2642 mb0_transfer.req.dbb_irqs |= prcmu_irq_bit[d->hwirq];
2641 2643
2642 spin_unlock_irqrestore(&mb0_transfer.dbb_irqs_lock, flags); 2644 spin_unlock_irqrestore(&mb0_transfer.dbb_irqs_lock, flags);
2643 2645
@@ -2677,9 +2679,37 @@ static char *fw_project_name(u8 project)
2677 } 2679 }
2678} 2680}
2679 2681
2682static int db8500_irq_map(struct irq_domain *d, unsigned int virq,
2683 irq_hw_number_t hwirq)
2684{
2685 irq_set_chip_and_handler(virq, &prcmu_irq_chip,
2686 handle_simple_irq);
2687 set_irq_flags(virq, IRQF_VALID);
2688
2689 return 0;
2690}
2691
2692static struct irq_domain_ops db8500_irq_ops = {
2693 .map = db8500_irq_map,
2694 .xlate = irq_domain_xlate_twocell,
2695};
2696
2697static int db8500_irq_init(struct device_node *np)
2698{
2699 db8500_irq_domain = irq_domain_add_legacy(
2700 np, NUM_PRCMU_WAKEUPS, IRQ_PRCMU_BASE,
2701 0, &db8500_irq_ops, NULL);
2702
2703 if (!db8500_irq_domain) {
2704 pr_err("Failed to create irqdomain\n");
2705 return -ENOSYS;
2706 }
2707
2708 return 0;
2709}
2710
2680void __init db8500_prcmu_early_init(void) 2711void __init db8500_prcmu_early_init(void)
2681{ 2712{
2682 unsigned int i;
2683 if (cpu_is_u8500v2()) { 2713 if (cpu_is_u8500v2()) {
2684 void *tcpm_base = ioremap_nocache(U8500_PRCMU_TCPM_BASE, SZ_4K); 2714 void *tcpm_base = ioremap_nocache(U8500_PRCMU_TCPM_BASE, SZ_4K);
2685 2715
@@ -2724,15 +2754,6 @@ void __init db8500_prcmu_early_init(void)
2724 2754
2725 INIT_WORK(&mb0_transfer.mask_work, prcmu_mask_work); 2755 INIT_WORK(&mb0_transfer.mask_work, prcmu_mask_work);
2726 2756
2727 /* Initalize irqs. */
2728 for (i = 0; i < NUM_PRCMU_WAKEUPS; i++) {
2729 unsigned int irq;
2730
2731 irq = IRQ_PRCMU_BASE + i;
2732 irq_set_chip_and_handler(irq, &prcmu_irq_chip,
2733 handle_simple_irq);
2734 set_irq_flags(irq, IRQF_VALID);
2735 }
2736 compute_armss_rate(); 2757 compute_armss_rate();
2737} 2758}
2738 2759
@@ -3040,6 +3061,8 @@ static int __devinit db8500_prcmu_probe(struct platform_device *pdev)
3040 goto no_irq_return; 3061 goto no_irq_return;
3041 } 3062 }
3042 3063
3064 db8500_irq_init(np);
3065
3043 for (i = 0; i < ARRAY_SIZE(db8500_prcmu_devs); i++) { 3066 for (i = 0; i < ARRAY_SIZE(db8500_prcmu_devs); i++) {
3044 if (!strcmp(db8500_prcmu_devs[i].name, "ab8500-core")) { 3067 if (!strcmp(db8500_prcmu_devs[i].name, "ab8500-core")) {
3045 db8500_prcmu_devs[i].platform_data = ab8500_platdata; 3068 db8500_prcmu_devs[i].platform_data = ab8500_platdata;