Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 63b61452 authored by David S. Miller's avatar David S. Miller
Browse files

[SPARC64]: Get rid of fast IRQ feature.



The only real user was the assembler floppy interrupt
handler, which does not need to be in assembly.

This makes it so that there are less pieces of code which
know about the internal layout of ivector_table[] and
friends.

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent b445e26c
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -16,7 +16,7 @@
#include <asm/ebus.h>
#include <asm/auxio.h>

/* This cannot be static, as it is referenced in entry.S */
/* This cannot be static, as it is referenced in irq.c */
void __iomem *auxio_register = NULL;

enum auxio_type {
+0 −110
Original line number Diff line number Diff line
@@ -701,116 +701,6 @@ utrap_ill:
	ba,pt		%xcc, rtrap
	 clr		%l6

#ifdef CONFIG_BLK_DEV_FD
	.globl		floppy_hardint
floppy_hardint:
	wr		%g0, (1 << 11), %clear_softint
	sethi		%hi(doing_pdma), %g1
	ld		[%g1 + %lo(doing_pdma)], %g2
	brz,pn		%g2, floppy_dosoftint
	 sethi		%hi(fdc_status), %g3
	ldx		[%g3 + %lo(fdc_status)], %g3
	sethi		%hi(pdma_vaddr), %g5
	ldx		[%g5 + %lo(pdma_vaddr)], %g4
	sethi		%hi(pdma_size), %g5
	ldx		[%g5 + %lo(pdma_size)], %g5

next_byte:
	lduba		[%g3] ASI_PHYS_BYPASS_EC_E, %g7
	andcc		%g7, 0x80, %g0
	be,pn		%icc, floppy_fifo_emptied
	 andcc		%g7, 0x20, %g0
	be,pn		%icc, floppy_overrun
	 andcc		%g7, 0x40, %g0
	be,pn		%icc, floppy_write
	 sub		%g5, 1, %g5

	inc		%g3
	lduba		[%g3] ASI_PHYS_BYPASS_EC_E, %g7
	dec		%g3
	orcc		%g0, %g5, %g0
	stb		%g7, [%g4]
	bne,pn		%xcc, next_byte
	 add		%g4, 1, %g4

	b,pt		%xcc, floppy_tdone
	 nop

floppy_write:
	ldub		[%g4], %g7
	orcc		%g0, %g5, %g0
	inc		%g3
	stba		%g7, [%g3] ASI_PHYS_BYPASS_EC_E
	dec		%g3
	bne,pn		%xcc, next_byte
	 add		%g4, 1, %g4

floppy_tdone:
	sethi		%hi(pdma_vaddr), %g1
	stx		%g4, [%g1 + %lo(pdma_vaddr)]
	sethi		%hi(pdma_size), %g1
	stx		%g5, [%g1 + %lo(pdma_size)]
	sethi		%hi(auxio_register), %g1
	ldx		[%g1 + %lo(auxio_register)], %g7
	lduba		[%g7] ASI_PHYS_BYPASS_EC_E, %g5
	or		%g5, AUXIO_AUX1_FTCNT, %g5
/*	andn		%g5, AUXIO_AUX1_MASK, %g5 */
	stba		%g5, [%g7] ASI_PHYS_BYPASS_EC_E
	andn		%g5, AUXIO_AUX1_FTCNT, %g5
/*	andn		%g5, AUXIO_AUX1_MASK, %g5 */

	nop; nop;  nop; nop;  nop; nop;
	nop; nop;  nop; nop;  nop; nop;

	stba		%g5, [%g7] ASI_PHYS_BYPASS_EC_E
	sethi		%hi(doing_pdma), %g1
	b,pt		%xcc, floppy_dosoftint
	 st		%g0, [%g1 + %lo(doing_pdma)]

floppy_fifo_emptied:
	sethi		%hi(pdma_vaddr), %g1
	stx		%g4, [%g1 + %lo(pdma_vaddr)]
	sethi		%hi(pdma_size), %g1
	stx		%g5, [%g1 + %lo(pdma_size)]
	sethi		%hi(irq_action), %g1
	or		%g1, %lo(irq_action), %g1
	ldx		[%g1 + (11 << 3)], %g3		! irqaction[floppy_irq]
	ldx		[%g3 + 0x08], %g4		! action->flags>>48==ino
	sethi		%hi(ivector_table), %g3
	srlx		%g4, 48, %g4
	or		%g3, %lo(ivector_table), %g3
	sllx		%g4, 5, %g4
	ldx		[%g3 + %g4], %g4		! &ivector_table[ino]
	ldx		[%g4 + 0x10], %g4		! bucket->iclr
	stwa		%g0, [%g4] ASI_PHYS_BYPASS_EC_E	! ICLR_IDLE
	membar		#Sync				! probably not needed...
	retry

floppy_overrun:
	sethi		%hi(pdma_vaddr), %g1
	stx		%g4, [%g1 + %lo(pdma_vaddr)]
	sethi		%hi(pdma_size), %g1
	stx		%g5, [%g1 + %lo(pdma_size)]
	sethi		%hi(doing_pdma), %g1
	st		%g0, [%g1 + %lo(doing_pdma)]

floppy_dosoftint:
	rdpr		%pil, %g2
	wrpr		%g0, 15, %pil
	sethi		%hi(109f), %g7
	b,pt		%xcc, etrap_irq
109:	 or		%g7, %lo(109b), %g7

	mov		11, %o0
	mov		0, %o1
	call		sparc_floppy_irq
	 add		%sp, PTREGS_OFF, %o2

	b,pt		%xcc, rtrap_irq
	 nop

#endif /* CONFIG_BLK_DEV_FD */

	/* XXX Here is stuff we still need to write... -DaveM XXX */
	.globl		netbsd_syscall
netbsd_syscall:
+50 −121
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@
#include <asm/uaccess.h>
#include <asm/cache.h>
#include <asm/cpudata.h>
#include <asm/auxio.h>

#ifdef CONFIG_SMP
static void distribute_irqs(void);
@@ -834,137 +835,65 @@ void handler_irq(int irq, struct pt_regs *regs)
}

#ifdef CONFIG_BLK_DEV_FD
extern void floppy_interrupt(int irq, void *dev_cookie, struct pt_regs *regs);
extern irqreturn_t floppy_interrupt(int, void *, struct pt_regs *);;

void sparc_floppy_irq(int irq, void *dev_cookie, struct pt_regs *regs)
{
	struct irqaction *action = *(irq + irq_action);
	struct ino_bucket *bucket;
	int cpu = smp_processor_id();

	irq_enter();
	kstat_this_cpu.irqs[irq]++;

	*(irq_work(cpu, irq)) = 0;
	bucket = get_ino_in_irqaction(action) + ivector_table;

	bucket->flags |= IBF_INPROGRESS;

	floppy_interrupt(irq, dev_cookie, regs);
	upa_writel(ICLR_IDLE, bucket->iclr);

	bucket->flags &= ~IBF_INPROGRESS;
/* XXX No easy way to include asm/floppy.h XXX */
extern unsigned char *pdma_vaddr;
extern unsigned long pdma_size;
extern volatile int doing_pdma;
extern unsigned long fdc_status;

	irq_exit();
}
#endif

/* The following assumes that the branch lies before the place we
 * are branching to.  This is the case for a trap vector...
 * You have been warned.
 */
#define SPARC_BRANCH(dest_addr, inst_addr) \
          (0x10800000 | ((((dest_addr)-(inst_addr))>>2)&0x3fffff))

#define SPARC_NOP (0x01000000)

static void install_fast_irq(unsigned int cpu_irq,
			     irqreturn_t (*handler)(int, void *, struct pt_regs *))
irqreturn_t sparc_floppy_irq(int irq, void *dev_cookie, struct pt_regs *regs)
{
	extern unsigned long sparc64_ttable_tl0;
	unsigned long ttent = (unsigned long) &sparc64_ttable_tl0;
	unsigned int *insns;
	if (likely(doing_pdma)) {
		void __iomem *stat = (void __iomem *) fdc_status;
		unsigned char *vaddr = pdma_vaddr;
		unsigned long size = pdma_size;
		u8 val;

		while (size) {
			val = readb(stat);
			if (unlikely(!(val & 0x80))) {
				pdma_vaddr = vaddr;
				pdma_size = size;
				return IRQ_HANDLED;
			}
			if (unlikely(!(val & 0x20))) {
				pdma_vaddr = vaddr;
				pdma_size = size;
				doing_pdma = 0;
				goto main_interrupt;
			}
			if (val & 0x40) {
				/* read */
				*vaddr++ = readb(stat + 1);
			} else {
				unsigned char data = *vaddr++;

	ttent += 0x820;
	ttent += (cpu_irq - 1) << 5;
	insns = (unsigned int *) ttent;
	insns[0] = SPARC_BRANCH(((unsigned long) handler),
				((unsigned long)&insns[0]));
	insns[1] = SPARC_NOP;
	__asm__ __volatile__("membar #StoreStore; flush %0" : : "r" (ttent));
				/* write */
				writeb(data, stat + 1);
			}

int request_fast_irq(unsigned int irq,
		     irqreturn_t (*handler)(int, void *, struct pt_regs *),
		     unsigned long irqflags, const char *name, void *dev_id)
{
	struct irqaction *action;
	struct ino_bucket *bucket = __bucket(irq);
	unsigned long flags;

	/* No pil0 dummy buckets allowed here. */
	if (bucket < &ivector_table[0] ||
	    bucket >= &ivector_table[NUM_IVECS]) {
		unsigned int *caller;

		__asm__ __volatile__("mov %%i7, %0" : "=r" (caller));
		printk(KERN_CRIT "request_fast_irq: Old style IRQ registry attempt "
		       "from %p, irq %08x.\n", caller, irq);
		return -EINVAL;
			size--;
		}

	if (!handler)
		return -EINVAL;
		pdma_vaddr = vaddr;
		pdma_size = size;

	if ((bucket->pil == 0) || (bucket->pil == 14)) {
		printk("request_fast_irq: Trying to register shared IRQ 0 or 14.\n");
		return -EBUSY;
	}

	spin_lock_irqsave(&irq_action_lock, flags);
		/* Send Terminal Count pulse to floppy controller. */
		val = readb(auxio_register);
		val |= AUXIO_AUX1_FTCNT;
		writeb(val, auxio_register);
		val &= AUXIO_AUX1_FTCNT;
		writeb(val, auxio_register);

	action = *(bucket->pil + irq_action);
	if (action) {
		if (action->flags & SA_SHIRQ)
			panic("Trying to register fast irq when already shared.\n");
		if (irqflags & SA_SHIRQ)
			panic("Trying to register fast irq as shared.\n");
		printk("request_fast_irq: Trying to register yet already owned.\n");
		spin_unlock_irqrestore(&irq_action_lock, flags);
		return -EBUSY;
		doing_pdma = 0;
	}

	/*
	 * We do not check for SA_SAMPLE_RANDOM in this path. Neither do we
	 * support smp intr affinity in this path.
	 */
	if (irqflags & SA_STATIC_ALLOC) {
		if (static_irq_count < MAX_STATIC_ALLOC)
			action = &static_irqaction[static_irq_count++];
		else
			printk("Request for IRQ%d (%s) SA_STATIC_ALLOC failed "
			       "using kmalloc\n", bucket->pil, name);
main_interrupt:
	return floppy_interrupt(irq, dev_cookie, regs);
}
	if (action == NULL)
		action = (struct irqaction *)kmalloc(sizeof(struct irqaction),
						     GFP_ATOMIC);
	if (!action) {
		spin_unlock_irqrestore(&irq_action_lock, flags);
		return -ENOMEM;
	}
	install_fast_irq(bucket->pil, handler);

	bucket->irq_info = action;
	bucket->flags |= IBF_ACTIVE;

	action->handler = handler;
	action->flags = irqflags;
	action->dev_id = NULL;
	action->name = name;
	action->next = NULL;
	put_ino_in_irqaction(action, irq);
	put_smpaff_in_irqaction(action, CPU_MASK_NONE);

	*(bucket->pil + irq_action) = action;
	enable_irq(irq);

	spin_unlock_irqrestore(&irq_action_lock, flags);

#ifdef CONFIG_SMP
	distribute_irqs();
EXPORT_SYMBOL(sparc_floppy_irq);
#endif
	return 0;
}

/* We really don't need these at all on the Sparc.  We only have
 * stubs here because they are exported to modules.
+0 −1
Original line number Diff line number Diff line
@@ -227,7 +227,6 @@ EXPORT_SYMBOL(__flush_dcache_range);

EXPORT_SYMBOL(mostek_lock);
EXPORT_SYMBOL(mstk48t02_regs);
EXPORT_SYMBOL(request_fast_irq);
#ifdef CONFIG_SUN_AUXIO
EXPORT_SYMBOL(auxio_set_led);
EXPORT_SYMBOL(auxio_set_lte);
+2 −0
Original line number Diff line number Diff line
@@ -75,6 +75,8 @@

#ifndef __ASSEMBLY__

extern void __iomem *auxio_register;

#define AUXIO_LTE_ON	1
#define AUXIO_LTE_OFF	0

Loading