summaryrefslogtreecommitdiff
path: root/arch/sparc
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc')
-rw-r--r--arch/sparc/include/asm/pil.h1
-rw-r--r--arch/sparc/include/asm/socket.h3
-rw-r--r--arch/sparc/include/asm/tlb_64.h4
-rw-r--r--arch/sparc/kernel/irq_64.c31
-rw-r--r--arch/sparc/kernel/kgdb_64.c2
-rw-r--r--arch/sparc/kernel/pci_common.c2
-rw-r--r--arch/sparc/kernel/time_64.c2
-rw-r--r--arch/sparc/kernel/ttable.S7
-rw-r--r--arch/sparc/mm/ultra.S24
9 files changed, 37 insertions, 39 deletions
diff --git a/arch/sparc/include/asm/pil.h b/arch/sparc/include/asm/pil.h
index 32a7efe76d00..266937030546 100644
--- a/arch/sparc/include/asm/pil.h
+++ b/arch/sparc/include/asm/pil.h
@@ -24,6 +24,7 @@
#define PIL_DEVICE_IRQ 5
#define PIL_SMP_CALL_FUNC_SNGL 6
#define PIL_DEFERRED_PCR_WORK 7
+#define PIL_KGDB_CAPTURE 8
#define PIL_NORMAL_MAX 14
#define PIL_NMI 15
diff --git a/arch/sparc/include/asm/socket.h b/arch/sparc/include/asm/socket.h
index bf50d0c2d583..982a12f959f4 100644
--- a/arch/sparc/include/asm/socket.h
+++ b/arch/sparc/include/asm/socket.h
@@ -50,6 +50,9 @@
#define SO_MARK 0x0022
+#define SO_TIMESTAMPING 0x0023
+#define SCM_TIMESTAMPING SO_TIMESTAMPING
+
/* Security levels - as per NRL IPv6 - don't actually do anything */
#define SO_SECURITY_AUTHENTICATION 0x5001
#define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002
diff --git a/arch/sparc/include/asm/tlb_64.h b/arch/sparc/include/asm/tlb_64.h
index ec81cdedef2c..ee38e731bfa6 100644
--- a/arch/sparc/include/asm/tlb_64.h
+++ b/arch/sparc/include/asm/tlb_64.h
@@ -57,6 +57,8 @@ static inline struct mmu_gather *tlb_gather_mmu(struct mm_struct *mm, unsigned i
static inline void tlb_flush_mmu(struct mmu_gather *mp)
{
+ if (!mp->fullmm)
+ flush_tlb_pending();
if (mp->need_flush) {
free_pages_and_swap_cache(mp->pages, mp->pages_nr);
mp->pages_nr = 0;
@@ -78,8 +80,6 @@ static inline void tlb_finish_mmu(struct mmu_gather *mp, unsigned long start, un
if (mp->fullmm)
mp->fullmm = 0;
- else
- flush_tlb_pending();
/* keep the page table cache within bounds */
check_pgt_cache();
diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c
index 3d2c6baae96b..d0d6a515499a 100644
--- a/arch/sparc/kernel/irq_64.c
+++ b/arch/sparc/kernel/irq_64.c
@@ -185,7 +185,7 @@ int show_interrupts(struct seq_file *p, void *v)
seq_printf(p, "%10u ", kstat_irqs(i));
#else
for_each_online_cpu(j)
- seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+ seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
#endif
seq_printf(p, " %9s", irq_desc[i].chip->typename);
seq_printf(p, " %s", action->name);
@@ -324,17 +324,25 @@ static void sun4u_set_affinity(unsigned int virt_irq,
sun4u_irq_enable(virt_irq);
}
+/* Don't do anything. The desc->status check for IRQ_DISABLED in
+ * handler_irq() will skip the handler call and that will leave the
+ * interrupt in the sent state. The next ->enable() call will hit the
+ * ICLR register to reset the state machine.
+ *
+ * This scheme is necessary, instead of clearing the Valid bit in the
+ * IMAP register, to handle the case of IMAP registers being shared by
+ * multiple INOs (and thus ICLR registers). Since we use a different
+ * virtual IRQ for each shared IMAP instance, the generic code thinks
+ * there is only one user so it prematurely calls ->disable() on
+ * free_irq().
+ *
+ * We have to provide an explicit ->disable() method instead of using
+ * NULL to get the default. The reason is that if the generic code
+ * sees that, it also hooks up a default ->shutdown method which
+ * invokes ->mask() which we do not want. See irq_chip_set_defaults().
+ */
static void sun4u_irq_disable(unsigned int virt_irq)
{
- struct irq_handler_data *data = get_irq_chip_data(virt_irq);
-
- if (likely(data)) {
- unsigned long imap = data->imap;
- unsigned long tmp = upa_readq(imap);
-
- tmp &= ~IMAP_VALID;
- upa_writeq(tmp, imap);
- }
}
static void sun4u_irq_eoi(unsigned int virt_irq)
@@ -747,7 +755,8 @@ void handler_irq(int irq, struct pt_regs *regs)
desc = irq_desc + virt_irq;
- desc->handle_irq(virt_irq, desc);
+ if (!(desc->status & IRQ_DISABLED))
+ desc->handle_irq(virt_irq, desc);
bucket_pa = next_pa;
}
diff --git a/arch/sparc/kernel/kgdb_64.c b/arch/sparc/kernel/kgdb_64.c
index fefbe6dc51be..f5a0fd490b59 100644
--- a/arch/sparc/kernel/kgdb_64.c
+++ b/arch/sparc/kernel/kgdb_64.c
@@ -108,7 +108,7 @@ void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
}
#ifdef CONFIG_SMP
-void smp_kgdb_capture_client(struct pt_regs *regs)
+void smp_kgdb_capture_client(int irq, struct pt_regs *regs)
{
unsigned long flags;
diff --git a/arch/sparc/kernel/pci_common.c b/arch/sparc/kernel/pci_common.c
index 64e6edf17b9d..b775658a927d 100644
--- a/arch/sparc/kernel/pci_common.c
+++ b/arch/sparc/kernel/pci_common.c
@@ -368,7 +368,7 @@ static void pci_register_iommu_region(struct pci_pbm_info *pbm)
const u32 *vdma = of_get_property(pbm->op->node, "virtual-dma", NULL);
if (vdma) {
- struct resource *rp = kmalloc(sizeof(*rp), GFP_KERNEL);
+ struct resource *rp = kzalloc(sizeof(*rp), GFP_KERNEL);
if (!rp) {
prom_printf("Cannot allocate IOMMU resource.\n");
diff --git a/arch/sparc/kernel/time_64.c b/arch/sparc/kernel/time_64.c
index db310aa00183..f95066b6f805 100644
--- a/arch/sparc/kernel/time_64.c
+++ b/arch/sparc/kernel/time_64.c
@@ -36,10 +36,10 @@
#include <linux/clocksource.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
+#include <linux/irq.h>
#include <asm/oplib.h>
#include <asm/timer.h>
-#include <asm/irq.h>
#include <asm/io.h>
#include <asm/prom.h>
#include <asm/starfire.h>
diff --git a/arch/sparc/kernel/ttable.S b/arch/sparc/kernel/ttable.S
index d9bdfb9d5c18..76d837fc47d3 100644
--- a/arch/sparc/kernel/ttable.S
+++ b/arch/sparc/kernel/ttable.S
@@ -64,7 +64,12 @@ tl0_irq6: TRAP_IRQ(smp_call_function_single_client, 6)
tl0_irq6: BTRAP(0x46)
#endif
tl0_irq7: TRAP_IRQ(deferred_pcr_work_irq, 7)
-tl0_irq8: BTRAP(0x48) BTRAP(0x49)
+#ifdef CONFIG_KGDB
+tl0_irq8: TRAP_IRQ(smp_kgdb_capture_client, 8)
+#else
+tl0_irq8: BTRAP(0x48)
+#endif
+tl0_irq9: BTRAP(0x49)
tl0_irq10: BTRAP(0x4a) BTRAP(0x4b) BTRAP(0x4c) BTRAP(0x4d)
tl0_irq14: TRAP_IRQ(timer_interrupt, 14)
tl0_irq15: TRAP_NMI_IRQ(perfctr_irq, 15)
diff --git a/arch/sparc/mm/ultra.S b/arch/sparc/mm/ultra.S
index 80c788ec7c32..b57a5942ba64 100644
--- a/arch/sparc/mm/ultra.S
+++ b/arch/sparc/mm/ultra.S
@@ -679,28 +679,8 @@ xcall_new_mmu_context_version:
#ifdef CONFIG_KGDB
.globl xcall_kgdb_capture
xcall_kgdb_capture:
-661: rdpr %pstate, %g2
- wrpr %g2, PSTATE_IG | PSTATE_AG, %pstate
- .section .sun4v_2insn_patch, "ax"
- .word 661b
- nop
- nop
- .previous
-
- rdpr %pil, %g2
- wrpr %g0, PIL_NORMAL_MAX, %pil
- sethi %hi(109f), %g7
- ba,pt %xcc, etrap_irq
-109: or %g7, %lo(109b), %g7
-#ifdef CONFIG_TRACE_IRQFLAGS
- call trace_hardirqs_off
- nop
-#endif
- call smp_kgdb_capture_client
- add %sp, PTREGS_OFF, %o0
- /* Has to be a non-v9 branch due to the large distance. */
- ba rtrap_xcall
- ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1
+ wr %g0, (1 << PIL_KGDB_CAPTURE), %set_softint
+ retry
#endif
#endif /* CONFIG_SMP */