~ubuntu-branches/debian/wheezy/linux-2.6/wheezy

« back to all changes in this revision

Viewing changes to arch/mips/pmc-sierra/msp71xx/msp_irq_per.c

  • Committer: Bazaar Package Importer
  • Author(s): Ben Hutchings, Ben Hutchings, Aurelien Jarno
  • Date: 2011-06-07 12:14:05 UTC
  • mfrom: (43.1.9 sid)
  • Revision ID: james.westby@ubuntu.com-20110607121405-i3h1rd7nrnd2b73h
Tags: 2.6.39-2
[ Ben Hutchings ]
* [x86] Enable BACKLIGHT_APPLE, replacing BACKLIGHT_MBP_NVIDIA
  (Closes: #627492)
* cgroups: Disable memory resource controller by default. Allow it
  to be enabled using kernel parameter 'cgroup_enable=memory'.
* rt2800usb: Enable support for more USB devices including
  Linksys WUSB600N (Closes: #596626) (this change was accidentally
  omitted from 2.6.39-1)
* [x86] Remove Celeron from list of processors supporting PAE. Most
  'Celeron M' models do not.
* Update debconf template translations:
  - Swedish (Martin Bagge) (Closes: #628932)
  - French (David Prévot) (Closes: #628191)
* aufs: Update for 2.6.39 (Closes: #627837)
* Add stable 2.6.39.1, including:
  - ext4: dont set PageUptodate in ext4_end_bio()
  - pata_cmd64x: fix boot crash on parisc (Closes: #622997, #622745)
  - ext3: Fix fs corruption when make_indexed_dir() fails
  - netfilter: nf_ct_sip: validate Content-Length in TCP SIP messages
  - sctp: fix race between sctp_bind_addr_free() and
    sctp_bind_addr_conflict()
  - sctp: fix memory leak of the ASCONF queue when free asoc
  - md/bitmap: fix saving of events_cleared and other state
  - cdc_acm: Fix oops when Droids MuIn LCD is connected
  - cx88: Fix conversion from BKL to fine-grained locks (Closes: #619827)
  - keys: Set cred->user_ns in key_replace_session_keyring (CVE-2011-2184)
  - tmpfs: fix race between truncate and writepage
  - nfs41: Correct offset for LAYOUTCOMMIT
  - xen/mmu: fix a race window causing leave_mm BUG()
  - ext4: fix possible use-after-free in ext4_remove_li_request()
  For the complete list of changes, see:
   http://www.kernel.org/pub/linux/kernel/v2.6/ChangeLog-2.6.39.1
* Bump ABI to 2
* netfilter: Enable IP_SET, IP_SET_BITMAP_IP, IP_SET_BITMAP_IPMAC,
  IP_SET_BITMAP_PORT, IP_SET_HASH_IP, IP_SET_HASH_IPPORT,
  IP_SET_HASH_IPPORTIP, IP_SET_HASH_IPPORTNET, IP_SET_HASH_NET,
  IP_SET_HASH_NETPORT, IP_SET_LIST_SET, NETFILTER_XT_SET as modules
  (Closes: #629401)

[ Aurelien Jarno ]
* [mipsel/loongson-2f] Disable_SCSI_LPFC to workaround GCC ICE.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright 2010 PMC-Sierra, Inc, derived from irq_cpu.c
 
3
 *
 
4
 * This file define the irq handler for MSP PER subsystem interrupts.
 
5
 *
 
6
 * This program is free software; you can redistribute  it and/or modify it
 
7
 * under  the terms of  the GNU General  Public License as published by the
 
8
 * Free Software Foundation;  either version 2 of the  License, or (at your
 
9
 * option) any later version.
 
10
 */
 
11
 
 
12
#include <linux/init.h>
 
13
#include <linux/interrupt.h>
 
14
#include <linux/kernel.h>
 
15
#include <linux/spinlock.h>
 
16
#include <linux/bitops.h>
 
17
 
 
18
#include <asm/mipsregs.h>
 
19
#include <asm/system.h>
 
20
 
 
21
#include <msp_cic_int.h>
 
22
#include <msp_regs.h>
 
23
 
 
24
 
 
25
/*
 
26
 * Convenience Macro.  Should be somewhere generic.
 
27
 */
 
28
#define get_current_vpe()       \
 
29
        ((read_c0_tcbind() >> TCBIND_CURVPE_SHIFT) & TCBIND_CURVPE)
 
30
 
 
31
#ifdef CONFIG_SMP
 
32
/*
 
33
 * The PER registers must be protected from concurrent access.
 
34
 */
 
35
 
 
36
static DEFINE_SPINLOCK(per_lock);
 
37
#endif
 
38
 
 
39
/* ensure writes to per are completed */
 
40
 
 
41
static inline void per_wmb(void)
 
42
{
 
43
        const volatile void __iomem *per_mem = PER_INT_MSK_REG;
 
44
        volatile u32 dummy_read;
 
45
 
 
46
        wmb();
 
47
        dummy_read = __raw_readl(per_mem);
 
48
        dummy_read++;
 
49
}
 
50
 
 
51
static inline void unmask_per_irq(struct irq_data *d)
 
52
{
 
53
#ifdef CONFIG_SMP
 
54
        unsigned long flags;
 
55
        spin_lock_irqsave(&per_lock, flags);
 
56
        *PER_INT_MSK_REG |= (1 << (d->irq - MSP_PER_INTBASE));
 
57
        spin_unlock_irqrestore(&per_lock, flags);
 
58
#else
 
59
        *PER_INT_MSK_REG |= (1 << (d->irq - MSP_PER_INTBASE));
 
60
#endif
 
61
        per_wmb();
 
62
}
 
63
 
 
64
static inline void mask_per_irq(struct irq_data *d)
 
65
{
 
66
#ifdef CONFIG_SMP
 
67
        unsigned long flags;
 
68
        spin_lock_irqsave(&per_lock, flags);
 
69
        *PER_INT_MSK_REG &= ~(1 << (d->irq - MSP_PER_INTBASE));
 
70
        spin_unlock_irqrestore(&per_lock, flags);
 
71
#else
 
72
        *PER_INT_MSK_REG &= ~(1 << (d->irq - MSP_PER_INTBASE));
 
73
#endif
 
74
        per_wmb();
 
75
}
 
76
 
 
77
static inline void msp_per_irq_ack(struct irq_data *d)
 
78
{
 
79
        mask_per_irq(d);
 
80
        /*
 
81
         * In the PER interrupt controller, only bits 11 and 10
 
82
         * are write-to-clear, (SPI TX complete, SPI RX complete).
 
83
         * It does nothing for any others.
 
84
         */
 
85
        *PER_INT_STS_REG = (1 << (d->irq - MSP_PER_INTBASE));
 
86
}
 
87
 
 
88
#ifdef CONFIG_SMP
 
89
static int msp_per_irq_set_affinity(struct irq_data *d,
 
90
                                    const struct cpumask *affinity, bool force)
 
91
{
 
92
        /* WTF is this doing ????? */
 
93
        unmask_per_irq(d);
 
94
        return 0;
 
95
}
 
96
#endif
 
97
 
 
98
static struct irq_chip msp_per_irq_controller = {
 
99
        .name = "MSP_PER",
 
100
        .irq_enable = unmask_per_irq,
 
101
        .irq_disable = mask_per_irq,
 
102
        .irq_ack = msp_per_irq_ack,
 
103
#ifdef CONFIG_SMP
 
104
        .irq_set_affinity = msp_per_irq_set_affinity,
 
105
#endif
 
106
};
 
107
 
 
108
void __init msp_per_irq_init(void)
 
109
{
 
110
        int i;
 
111
        /* Mask/clear interrupts. */
 
112
        *PER_INT_MSK_REG  = 0x00000000;
 
113
        *PER_INT_STS_REG  = 0xFFFFFFFF;
 
114
        /* initialize all the IRQ descriptors */
 
115
        for (i = MSP_PER_INTBASE; i < MSP_PER_INTBASE + 32; i++) {
 
116
                irq_set_chip(i, &msp_per_irq_controller);
 
117
#ifdef CONFIG_MIPS_MT_SMTC
 
118
                irq_hwmask[i] = C_IRQ4;
 
119
#endif
 
120
        }
 
121
}
 
122
 
 
123
void msp_per_irq_dispatch(void)
 
124
{
 
125
        u32     per_mask = *PER_INT_MSK_REG;
 
126
        u32     per_status = *PER_INT_STS_REG;
 
127
        u32     pending;
 
128
 
 
129
        pending = per_status & per_mask;
 
130
        if (pending) {
 
131
                do_IRQ(ffs(pending) + MSP_PER_INTBASE - 1);
 
132
        } else {
 
133
                spurious_interrupt();
 
134
        }
 
135
}