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

« back to all changes in this revision

Viewing changes to arch/mips/bcm63xx/irq.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:
76
76
 * internal IRQs operations: only mask/unmask on PERF irq mask
77
77
 * register.
78
78
 */
79
 
static inline void bcm63xx_internal_irq_mask(unsigned int irq)
 
79
static inline void bcm63xx_internal_irq_mask(struct irq_data *d)
80
80
{
 
81
        unsigned int irq = d->irq - IRQ_INTERNAL_BASE;
81
82
        u32 mask;
82
83
 
83
 
        irq -= IRQ_INTERNAL_BASE;
84
84
        mask = bcm_perf_readl(PERF_IRQMASK_REG);
85
85
        mask &= ~(1 << irq);
86
86
        bcm_perf_writel(mask, PERF_IRQMASK_REG);
87
87
}
88
88
 
89
 
static void bcm63xx_internal_irq_unmask(unsigned int irq)
 
89
static void bcm63xx_internal_irq_unmask(struct irq_data *d)
90
90
{
 
91
        unsigned int irq = d->irq - IRQ_INTERNAL_BASE;
91
92
        u32 mask;
92
93
 
93
 
        irq -= IRQ_INTERNAL_BASE;
94
94
        mask = bcm_perf_readl(PERF_IRQMASK_REG);
95
95
        mask |= (1 << irq);
96
96
        bcm_perf_writel(mask, PERF_IRQMASK_REG);
97
97
}
98
98
 
99
 
static unsigned int bcm63xx_internal_irq_startup(unsigned int irq)
100
 
{
101
 
        bcm63xx_internal_irq_unmask(irq);
102
 
        return 0;
103
 
}
104
 
 
105
99
/*
106
100
 * external IRQs operations: mask/unmask and clear on PERF external
107
101
 * irq control register.
108
102
 */
109
 
static void bcm63xx_external_irq_mask(unsigned int irq)
 
103
static void bcm63xx_external_irq_mask(struct irq_data *d)
110
104
{
 
105
        unsigned int irq = d->irq - IRQ_EXT_BASE;
111
106
        u32 reg;
112
107
 
113
 
        irq -= IRQ_EXT_BASE;
114
108
        reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG);
115
109
        reg &= ~EXTIRQ_CFG_MASK(irq);
116
110
        bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG);
117
111
}
118
112
 
119
 
static void bcm63xx_external_irq_unmask(unsigned int irq)
 
113
static void bcm63xx_external_irq_unmask(struct irq_data *d)
120
114
{
 
115
        unsigned int irq = d->irq - IRQ_EXT_BASE;
121
116
        u32 reg;
122
117
 
123
 
        irq -= IRQ_EXT_BASE;
124
118
        reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG);
125
119
        reg |= EXTIRQ_CFG_MASK(irq);
126
120
        bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG);
127
121
}
128
122
 
129
 
static void bcm63xx_external_irq_clear(unsigned int irq)
 
123
static void bcm63xx_external_irq_clear(struct irq_data *d)
130
124
{
 
125
        unsigned int irq = d->irq - IRQ_EXT_BASE;
131
126
        u32 reg;
132
127
 
133
 
        irq -= IRQ_EXT_BASE;
134
128
        reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG);
135
129
        reg |= EXTIRQ_CFG_CLEAR(irq);
136
130
        bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG);
137
131
}
138
132
 
139
 
static unsigned int bcm63xx_external_irq_startup(unsigned int irq)
 
133
static unsigned int bcm63xx_external_irq_startup(struct irq_data *d)
140
134
{
141
 
        set_c0_status(0x100 << (irq - IRQ_MIPS_BASE));
 
135
        set_c0_status(0x100 << (d->irq - IRQ_MIPS_BASE));
142
136
        irq_enable_hazard();
143
 
        bcm63xx_external_irq_unmask(irq);
 
137
        bcm63xx_external_irq_unmask(d);
144
138
        return 0;
145
139
}
146
140
 
147
 
static void bcm63xx_external_irq_shutdown(unsigned int irq)
 
141
static void bcm63xx_external_irq_shutdown(struct irq_data *d)
148
142
{
149
 
        bcm63xx_external_irq_mask(irq);
150
 
        clear_c0_status(0x100 << (irq - IRQ_MIPS_BASE));
 
143
        bcm63xx_external_irq_mask(d);
 
144
        clear_c0_status(0x100 << (d->irq - IRQ_MIPS_BASE));
151
145
        irq_disable_hazard();
152
146
}
153
147
 
154
 
static int bcm63xx_external_irq_set_type(unsigned int irq,
 
148
static int bcm63xx_external_irq_set_type(struct irq_data *d,
155
149
                                         unsigned int flow_type)
156
150
{
 
151
        unsigned int irq = d->irq - IRQ_EXT_BASE;
157
152
        u32 reg;
158
 
        struct irq_desc *desc = irq_desc + irq;
159
 
 
160
 
        irq -= IRQ_EXT_BASE;
161
153
 
162
154
        flow_type &= IRQ_TYPE_SENSE_MASK;
163
155
 
199
191
        }
200
192
        bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG);
201
193
 
202
 
        if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))  {
203
 
                desc->status |= IRQ_LEVEL;
204
 
                desc->handle_irq = handle_level_irq;
205
 
        } else {
206
 
                desc->handle_irq = handle_edge_irq;
207
 
        }
 
194
        irqd_set_trigger_type(d, flow_type);
 
195
        if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
 
196
                __irq_set_handler_locked(d->irq, handle_level_irq);
 
197
        else
 
198
                __irq_set_handler_locked(d->irq, handle_edge_irq);
208
199
 
209
 
        return 0;
 
200
        return IRQ_SET_MASK_OK_NOCOPY;
210
201
}
211
202
 
212
203
static struct irq_chip bcm63xx_internal_irq_chip = {
213
204
        .name           = "bcm63xx_ipic",
214
 
        .startup        = bcm63xx_internal_irq_startup,
215
 
        .shutdown       = bcm63xx_internal_irq_mask,
216
 
 
217
 
        .mask           = bcm63xx_internal_irq_mask,
218
 
        .mask_ack       = bcm63xx_internal_irq_mask,
219
 
        .unmask         = bcm63xx_internal_irq_unmask,
 
205
        .irq_mask       = bcm63xx_internal_irq_mask,
 
206
        .irq_unmask     = bcm63xx_internal_irq_unmask,
220
207
};
221
208
 
222
209
static struct irq_chip bcm63xx_external_irq_chip = {
223
210
        .name           = "bcm63xx_epic",
224
 
        .startup        = bcm63xx_external_irq_startup,
225
 
        .shutdown       = bcm63xx_external_irq_shutdown,
226
 
 
227
 
        .ack            = bcm63xx_external_irq_clear,
228
 
 
229
 
        .mask           = bcm63xx_external_irq_mask,
230
 
        .unmask         = bcm63xx_external_irq_unmask,
231
 
 
232
 
        .set_type       = bcm63xx_external_irq_set_type,
 
211
        .irq_startup    = bcm63xx_external_irq_startup,
 
212
        .irq_shutdown   = bcm63xx_external_irq_shutdown,
 
213
 
 
214
        .irq_ack        = bcm63xx_external_irq_clear,
 
215
 
 
216
        .irq_mask       = bcm63xx_external_irq_mask,
 
217
        .irq_unmask     = bcm63xx_external_irq_unmask,
 
218
 
 
219
        .irq_set_type   = bcm63xx_external_irq_set_type,
233
220
};
234
221
 
235
222
static struct irqaction cpu_ip2_cascade_action = {
243
230
 
244
231
        mips_cpu_irq_init();
245
232
        for (i = IRQ_INTERNAL_BASE; i < NR_IRQS; ++i)
246
 
                set_irq_chip_and_handler(i, &bcm63xx_internal_irq_chip,
 
233
                irq_set_chip_and_handler(i, &bcm63xx_internal_irq_chip,
247
234
                                         handle_level_irq);
248
235
 
249
236
        for (i = IRQ_EXT_BASE; i < IRQ_EXT_BASE + 4; ++i)
250
 
                set_irq_chip_and_handler(i, &bcm63xx_external_irq_chip,
 
237
                irq_set_chip_and_handler(i, &bcm63xx_external_irq_chip,
251
238
                                         handle_edge_irq);
252
239
 
253
240
        setup_irq(IRQ_MIPS_BASE + 2, &cpu_ip2_cascade_action);