#include <asm/ptrace.h>
#include <asm/machdep.h>
#include <asm/udbg.h>
-#ifdef CONFIG_PPC_ISERIES
+#ifdef CONFIG_PPC64
#include <asm/paca.h>
+#include <asm/firmware.h>
#endif
int __irq_offset_value;
EXPORT_SYMBOL(irq_desc);
int distribute_irqs = 1;
+
+void local_irq_restore(unsigned long en)
+{
+ get_paca()->soft_enabled = en;
+ if (!en)
+ return;
+
+ if (firmware_has_feature(FW_FEATURE_ISERIES)) {
+ if (get_paca()->lppaca_ptr->int_dword.any_int)
+ iseries_handle_interrupts();
+ return;
+ }
+
+ if (get_paca()->hard_enabled)
+ return;
+ /* need to hard-enable interrupts here */
+ get_paca()->hard_enabled = en;
+ if ((int)mfspr(SPRN_DEC) < 0)
+ mtspr(SPRN_DEC, 1);
+ hard_irq_enable();
+}
#endif /* CONFIG_PPC64 */
int show_interrupts(struct seq_file *p, void *v)
void do_IRQ(struct pt_regs *regs)
{
+ struct pt_regs *old_regs = set_irq_regs(regs);
unsigned int irq;
#ifdef CONFIG_IRQSTACKS
struct thread_info *curtp, *irqtp;
* The value -2 is for buggy hardware and means that this IRQ
* has already been handled. -- Tom
*/
- irq = ppc_md.get_irq(regs);
+ irq = ppc_md.get_irq();
if (irq != NO_IRQ && irq != NO_IRQ_IGNORE) {
#ifdef CONFIG_IRQSTACKS
handler = &__do_IRQ;
irqtp->task = curtp->task;
irqtp->flags = 0;
- call_handle_irq(irq, desc, regs, irqtp, handler);
+ call_handle_irq(irq, desc, irqtp, handler);
irqtp->task = NULL;
if (irqtp->flags)
set_bits(irqtp->flags, &curtp->flags);
} else
#endif
- generic_handle_irq(irq, regs);
+ generic_handle_irq(irq);
} else if (irq != NO_IRQ_IGNORE)
/* That's not SMP safe ... but who cares ? */
ppc_spurious_interrupts++;
irq_exit();
+ set_irq_regs(old_regs);
#ifdef CONFIG_PPC_ISERIES
if (get_lppaca()->int_dword.fields.decr_int) {
}
EXPORT_SYMBOL_GPL(irq_create_mapping);
-extern unsigned int irq_create_of_mapping(struct device_node *controller,
- u32 *intspec, unsigned int intsize)
+unsigned int irq_create_of_mapping(struct device_node *controller,
+ u32 *intspec, unsigned int intsize)
{
struct irq_host *host;
irq_hw_number_t hwirq;
{
unsigned long flags;
unsigned int i, j, found = NO_IRQ;
- unsigned int limit = irq_virq_count - count;
if (count == 0 || count > (irq_virq_count - NUM_ISA_INTERRUPTS))
return NO_IRQ;
/* Look for count consecutive numbers in the allocatable
* (non-legacy) space
*/
- for (i = NUM_ISA_INTERRUPTS; i <= limit; ) {
- for (j = i; j < (i + count); j++)
- if (irq_map[j].host != NULL) {
- i = j + 1;
- continue;
- }
- found = i;
- break;
+ for (i = NUM_ISA_INTERRUPTS, j = 0; i < irq_virq_count; i++) {
+ if (irq_map[i].host != NULL)
+ j = 0;
+ else
+ j++;
+
+ if (j == count) {
+ found = i - count + 1;
+ break;
+ }
}
if (found == NO_IRQ) {
spin_unlock_irqrestore(&irq_big_lock, flags);