~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to arch/powerpc/sysdev/cpm2_pic.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
78
78
        24, 25, 26, 27, 28, 29, 30, 31,
79
79
};
80
80
 
81
 
static void cpm2_mask_irq(unsigned int virq)
 
81
static void cpm2_mask_irq(struct irq_data *d)
82
82
{
83
83
        int     bit, word;
84
 
        unsigned int irq_nr = virq_to_hw(virq);
 
84
        unsigned int irq_nr = irqd_to_hwirq(d);
85
85
 
86
86
        bit = irq_to_siubit[irq_nr];
87
87
        word = irq_to_siureg[irq_nr];
90
90
        out_be32(&cpm2_intctl->ic_simrh + word, ppc_cached_irq_mask[word]);
91
91
}
92
92
 
93
 
static void cpm2_unmask_irq(unsigned int virq)
 
93
static void cpm2_unmask_irq(struct irq_data *d)
94
94
{
95
95
        int     bit, word;
96
 
        unsigned int irq_nr = virq_to_hw(virq);
 
96
        unsigned int irq_nr = irqd_to_hwirq(d);
97
97
 
98
98
        bit = irq_to_siubit[irq_nr];
99
99
        word = irq_to_siureg[irq_nr];
102
102
        out_be32(&cpm2_intctl->ic_simrh + word, ppc_cached_irq_mask[word]);
103
103
}
104
104
 
105
 
static void cpm2_ack(unsigned int virq)
 
105
static void cpm2_ack(struct irq_data *d)
106
106
{
107
107
        int     bit, word;
108
 
        unsigned int irq_nr = virq_to_hw(virq);
 
108
        unsigned int irq_nr = irqd_to_hwirq(d);
109
109
 
110
110
        bit = irq_to_siubit[irq_nr];
111
111
        word = irq_to_siureg[irq_nr];
113
113
        out_be32(&cpm2_intctl->ic_sipnrh + word, 1 << bit);
114
114
}
115
115
 
116
 
static void cpm2_end_irq(unsigned int virq)
 
116
static void cpm2_end_irq(struct irq_data *d)
117
117
{
118
 
        struct irq_desc *desc;
119
118
        int     bit, word;
120
 
        unsigned int irq_nr = virq_to_hw(virq);
121
 
 
122
 
        desc = irq_to_desc(irq_nr);
123
 
        if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS))
124
 
                        && desc->action) {
125
 
 
126
 
                bit = irq_to_siubit[irq_nr];
127
 
                word = irq_to_siureg[irq_nr];
128
 
 
129
 
                ppc_cached_irq_mask[word] |= 1 << bit;
130
 
                out_be32(&cpm2_intctl->ic_simrh + word, ppc_cached_irq_mask[word]);
131
 
 
132
 
                /*
133
 
                 * Work around large numbers of spurious IRQs on PowerPC 82xx
134
 
                 * systems.
135
 
                 */
136
 
                mb();
137
 
        }
 
119
        unsigned int irq_nr = irqd_to_hwirq(d);
 
120
 
 
121
        bit = irq_to_siubit[irq_nr];
 
122
        word = irq_to_siureg[irq_nr];
 
123
 
 
124
        ppc_cached_irq_mask[word] |= 1 << bit;
 
125
        out_be32(&cpm2_intctl->ic_simrh + word, ppc_cached_irq_mask[word]);
 
126
 
 
127
        /*
 
128
         * Work around large numbers of spurious IRQs on PowerPC 82xx
 
129
         * systems.
 
130
         */
 
131
        mb();
138
132
}
139
133
 
140
 
static int cpm2_set_irq_type(unsigned int virq, unsigned int flow_type)
 
134
static int cpm2_set_irq_type(struct irq_data *d, unsigned int flow_type)
141
135
{
142
 
        unsigned int src = virq_to_hw(virq);
143
 
        struct irq_desc *desc = irq_to_desc(virq);
 
136
        unsigned int src = irqd_to_hwirq(d);
144
137
        unsigned int vold, vnew, edibit;
145
138
 
146
139
        /* Port C interrupts are either IRQ_TYPE_EDGE_FALLING or
162
155
                        goto err_sense;
163
156
        }
164
157
 
165
 
        desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
166
 
        desc->status |= flow_type & IRQ_TYPE_SENSE_MASK;
167
 
        if (flow_type & IRQ_TYPE_LEVEL_LOW)  {
168
 
                desc->status |= IRQ_LEVEL;
169
 
                desc->handle_irq = handle_level_irq;
170
 
        } else
171
 
                desc->handle_irq = handle_edge_irq;
 
158
        irqd_set_trigger_type(d, flow_type);
 
159
        if (flow_type & IRQ_TYPE_LEVEL_LOW)
 
160
                __irq_set_handler_locked(d->irq, handle_level_irq);
 
161
        else
 
162
                __irq_set_handler_locked(d->irq, handle_edge_irq);
172
163
 
173
164
        /* internal IRQ senses are LEVEL_LOW
174
165
         * EXT IRQ and Port C IRQ senses are programmable
179
170
                if (src >= CPM2_IRQ_PORTC15 && src <= CPM2_IRQ_PORTC0)
180
171
                        edibit = (31 - (CPM2_IRQ_PORTC0 - src));
181
172
                else
182
 
                        return (flow_type & IRQ_TYPE_LEVEL_LOW) ? 0 : -EINVAL;
 
173
                        return (flow_type & IRQ_TYPE_LEVEL_LOW) ?
 
174
                                IRQ_SET_MASK_OK_NOCOPY : -EINVAL;
183
175
 
184
176
        vold = in_be32(&cpm2_intctl->ic_siexr);
185
177
 
190
182
 
191
183
        if (vold != vnew)
192
184
                out_be32(&cpm2_intctl->ic_siexr, vnew);
193
 
        return 0;
 
185
        return IRQ_SET_MASK_OK_NOCOPY;
194
186
 
195
187
err_sense:
196
188
        pr_err("CPM2 PIC: sense type 0x%x not supported\n", flow_type);
199
191
 
200
192
static struct irq_chip cpm2_pic = {
201
193
        .name = "CPM2 SIU",
202
 
        .mask = cpm2_mask_irq,
203
 
        .unmask = cpm2_unmask_irq,
204
 
        .ack = cpm2_ack,
205
 
        .eoi = cpm2_end_irq,
206
 
        .set_type = cpm2_set_irq_type,
 
194
        .irq_mask = cpm2_mask_irq,
 
195
        .irq_unmask = cpm2_unmask_irq,
 
196
        .irq_ack = cpm2_ack,
 
197
        .irq_eoi = cpm2_end_irq,
 
198
        .irq_set_type = cpm2_set_irq_type,
 
199
        .flags = IRQCHIP_EOI_IF_HANDLED,
207
200
};
208
201
 
209
202
unsigned int cpm2_get_irq(void)
226
219
{
227
220
        pr_debug("cpm2_pic_host_map(%d, 0x%lx)\n", virq, hw);
228
221
 
229
 
        irq_to_desc(virq)->status |= IRQ_LEVEL;
230
 
        set_irq_chip_and_handler(virq, &cpm2_pic, handle_level_irq);
 
222
        irq_set_status_flags(virq, IRQ_LEVEL);
 
223
        irq_set_chip_and_handler(virq, &cpm2_pic, handle_level_irq);
231
224
        return 0;
232
225
}
233
226