OpenCores
URL https://opencores.org/ocsvn/or1k_soc_on_altera_embedded_dev_kit/or1k_soc_on_altera_embedded_dev_kit/trunk

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [arch/] [powerpc/] [sysdev/] [mpic_msi.c] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
/*
2
 * Copyright 2006-2007, Michael Ellerman, IBM Corporation.
3
 *
4
 * This program is free software; you can redistribute it and/or
5
 * modify it under the terms of the GNU General Public License
6
 * as published by the Free Software Foundation; version 2 of the
7
 * License.
8
 *
9
 */
10
 
11
#include <linux/irq.h>
12
#include <linux/bitmap.h>
13
#include <linux/msi.h>
14
#include <asm/mpic.h>
15
#include <asm/prom.h>
16
#include <asm/hw_irq.h>
17
#include <asm/ppc-pci.h>
18
 
19
 
20
static void __mpic_msi_reserve_hwirq(struct mpic *mpic, irq_hw_number_t hwirq)
21
{
22
        pr_debug("mpic: reserving hwirq 0x%lx\n", hwirq);
23
        bitmap_allocate_region(mpic->hwirq_bitmap, hwirq, 0);
24
}
25
 
26
void mpic_msi_reserve_hwirq(struct mpic *mpic, irq_hw_number_t hwirq)
27
{
28
        unsigned long flags;
29
 
30
        /* The mpic calls this even when there is no allocator setup */
31
        if (!mpic->hwirq_bitmap)
32
                return;
33
 
34
        spin_lock_irqsave(&mpic->bitmap_lock, flags);
35
        __mpic_msi_reserve_hwirq(mpic, hwirq);
36
        spin_unlock_irqrestore(&mpic->bitmap_lock, flags);
37
}
38
 
39
irq_hw_number_t mpic_msi_alloc_hwirqs(struct mpic *mpic, int num)
40
{
41
        unsigned long flags;
42
        int offset, order = get_count_order(num);
43
 
44
        spin_lock_irqsave(&mpic->bitmap_lock, flags);
45
        /*
46
         * This is fast, but stricter than we need. We might want to add
47
         * a fallback routine which does a linear search with no alignment.
48
         */
49
        offset = bitmap_find_free_region(mpic->hwirq_bitmap, mpic->irq_count,
50
                                         order);
51
        spin_unlock_irqrestore(&mpic->bitmap_lock, flags);
52
 
53
        pr_debug("mpic: allocated 0x%x (2^%d) at offset 0x%x\n",
54
                 num, order, offset);
55
 
56
        return offset;
57
}
58
 
59
void mpic_msi_free_hwirqs(struct mpic *mpic, int offset, int num)
60
{
61
        unsigned long flags;
62
        int order = get_count_order(num);
63
 
64
        pr_debug("mpic: freeing 0x%x (2^%d) at offset 0x%x\n",
65
                 num, order, offset);
66
 
67
        spin_lock_irqsave(&mpic->bitmap_lock, flags);
68
        bitmap_release_region(mpic->hwirq_bitmap, offset, order);
69
        spin_unlock_irqrestore(&mpic->bitmap_lock, flags);
70
}
71
 
72
#ifdef CONFIG_MPIC_U3_HT_IRQS
73
static int mpic_msi_reserve_u3_hwirqs(struct mpic *mpic)
74
{
75
        irq_hw_number_t hwirq;
76
        struct irq_host_ops *ops = mpic->irqhost->ops;
77
        struct device_node *np;
78
        int flags, index, i;
79
        struct of_irq oirq;
80
 
81
        pr_debug("mpic: found U3, guessing msi allocator setup\n");
82
 
83
        /* Reserve source numbers we know are reserved in the HW */
84
        for (i = 0;   i < 8;   i++)
85
                __mpic_msi_reserve_hwirq(mpic, i);
86
 
87
        for (i = 42;  i < 46;  i++)
88
                __mpic_msi_reserve_hwirq(mpic, i);
89
 
90
        for (i = 100; i < 105; i++)
91
                __mpic_msi_reserve_hwirq(mpic, i);
92
 
93
        np = NULL;
94
        while ((np = of_find_all_nodes(np))) {
95
                pr_debug("mpic: mapping hwirqs for %s\n", np->full_name);
96
 
97
                index = 0;
98
                while (of_irq_map_one(np, index++, &oirq) == 0) {
99
                        ops->xlate(mpic->irqhost, NULL, oirq.specifier,
100
                                                oirq.size, &hwirq, &flags);
101
                        __mpic_msi_reserve_hwirq(mpic, hwirq);
102
                }
103
        }
104
 
105
        return 0;
106
}
107
#else
108
static int mpic_msi_reserve_u3_hwirqs(struct mpic *mpic)
109
{
110
        return -1;
111
}
112
#endif
113
 
114
static int mpic_msi_reserve_dt_hwirqs(struct mpic *mpic)
115
{
116
        int i, len;
117
        const u32 *p;
118
 
119
        p = of_get_property(mpic->irqhost->of_node,
120
                            "msi-available-ranges", &len);
121
        if (!p) {
122
                pr_debug("mpic: no msi-available-ranges property found on %s\n",
123
                          mpic->irqhost->of_node->full_name);
124
                return -ENODEV;
125
        }
126
 
127
        if (len % 8 != 0) {
128
                printk(KERN_WARNING "mpic: Malformed msi-available-ranges "
129
                       "property on %s\n", mpic->irqhost->of_node->full_name);
130
                return -EINVAL;
131
        }
132
 
133
        bitmap_allocate_region(mpic->hwirq_bitmap, 0,
134
                               get_count_order(mpic->irq_count));
135
 
136
        /* Format is: (<u32 start> <u32 count>)+ */
137
        len /= sizeof(u32);
138
        for (i = 0; i < len / 2; i++, p += 2)
139
                mpic_msi_free_hwirqs(mpic, *p, *(p + 1));
140
 
141
        return 0;
142
}
143
 
144
int mpic_msi_init_allocator(struct mpic *mpic)
145
{
146
        int rc, size;
147
 
148
        BUG_ON(mpic->hwirq_bitmap);
149
        spin_lock_init(&mpic->bitmap_lock);
150
 
151
        size = BITS_TO_LONGS(mpic->irq_count) * sizeof(long);
152
        pr_debug("mpic: allocator bitmap size is 0x%x bytes\n", size);
153
 
154
        mpic->hwirq_bitmap = alloc_maybe_bootmem(size, GFP_KERNEL);
155
 
156
        if (!mpic->hwirq_bitmap) {
157
                pr_debug("mpic: ENOMEM allocating allocator bitmap!\n");
158
                return -ENOMEM;
159
        }
160
 
161
        memset(mpic->hwirq_bitmap, 0, size);
162
 
163
        rc = mpic_msi_reserve_dt_hwirqs(mpic);
164
        if (rc) {
165
                if (mpic->flags & MPIC_U3_HT_IRQS)
166
                        rc = mpic_msi_reserve_u3_hwirqs(mpic);
167
 
168
                if (rc)
169
                        goto out_free;
170
        }
171
 
172
        return 0;
173
 
174
 out_free:
175
        if (mem_init_done)
176
                kfree(mpic->hwirq_bitmap);
177
 
178
        mpic->hwirq_bitmap = NULL;
179
        return rc;
180
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.