aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2005-06-27 20:04:45 -0400
committerDavid S. Miller <davem@davemloft.net>2005-06-27 20:04:45 -0400
commit63b614522cba5a015923c0e8f284be6e01c13f1a (patch)
tree4f3724d90f52ef8b98f7c0b9716730b7adbd8566 /arch
parentb445e26cbf784cdba10f2b6c3e2cd3ee7bab360a (diff)
[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: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch')
-rw-r--r--arch/sparc64/kernel/auxio.c2
-rw-r--r--arch/sparc64/kernel/entry.S110
-rw-r--r--arch/sparc64/kernel/irq.c171
-rw-r--r--arch/sparc64/kernel/sparc64_ksyms.c1
4 files changed, 51 insertions, 233 deletions
diff --git a/arch/sparc64/kernel/auxio.c b/arch/sparc64/kernel/auxio.c
index a0716ccc2f4a..8852c20c8d99 100644
--- a/arch/sparc64/kernel/auxio.c
+++ b/arch/sparc64/kernel/auxio.c
@@ -16,7 +16,7 @@
16#include <asm/ebus.h> 16#include <asm/ebus.h>
17#include <asm/auxio.h> 17#include <asm/auxio.h>
18 18
19/* This cannot be static, as it is referenced in entry.S */ 19/* This cannot be static, as it is referenced in irq.c */
20void __iomem *auxio_register = NULL; 20void __iomem *auxio_register = NULL;
21 21
22enum auxio_type { 22enum auxio_type {
diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S
index ffe717ab7f83..eee516a71c14 100644
--- a/arch/sparc64/kernel/entry.S
+++ b/arch/sparc64/kernel/entry.S
@@ -701,116 +701,6 @@ utrap_ill:
701 ba,pt %xcc, rtrap 701 ba,pt %xcc, rtrap
702 clr %l6 702 clr %l6
703 703
704#ifdef CONFIG_BLK_DEV_FD
705 .globl floppy_hardint
706floppy_hardint:
707 wr %g0, (1 << 11), %clear_softint
708 sethi %hi(doing_pdma), %g1
709 ld [%g1 + %lo(doing_pdma)], %g2
710 brz,pn %g2, floppy_dosoftint
711 sethi %hi(fdc_status), %g3
712 ldx [%g3 + %lo(fdc_status)], %g3
713 sethi %hi(pdma_vaddr), %g5
714 ldx [%g5 + %lo(pdma_vaddr)], %g4
715 sethi %hi(pdma_size), %g5
716 ldx [%g5 + %lo(pdma_size)], %g5
717
718next_byte:
719 lduba [%g3] ASI_PHYS_BYPASS_EC_E, %g7
720 andcc %g7, 0x80, %g0
721 be,pn %icc, floppy_fifo_emptied
722 andcc %g7, 0x20, %g0
723 be,pn %icc, floppy_overrun
724 andcc %g7, 0x40, %g0
725 be,pn %icc, floppy_write
726 sub %g5, 1, %g5
727
728 inc %g3
729 lduba [%g3] ASI_PHYS_BYPASS_EC_E, %g7
730 dec %g3
731 orcc %g0, %g5, %g0
732 stb %g7, [%g4]
733 bne,pn %xcc, next_byte
734 add %g4, 1, %g4
735
736 b,pt %xcc, floppy_tdone
737 nop
738
739floppy_write:
740 ldub [%g4], %g7
741 orcc %g0, %g5, %g0
742 inc %g3
743 stba %g7, [%g3] ASI_PHYS_BYPASS_EC_E
744 dec %g3
745 bne,pn %xcc, next_byte
746 add %g4, 1, %g4
747
748floppy_tdone:
749 sethi %hi(pdma_vaddr), %g1
750 stx %g4, [%g1 + %lo(pdma_vaddr)]
751 sethi %hi(pdma_size), %g1
752 stx %g5, [%g1 + %lo(pdma_size)]
753 sethi %hi(auxio_register), %g1
754 ldx [%g1 + %lo(auxio_register)], %g7
755 lduba [%g7] ASI_PHYS_BYPASS_EC_E, %g5
756 or %g5, AUXIO_AUX1_FTCNT, %g5
757/* andn %g5, AUXIO_AUX1_MASK, %g5 */
758 stba %g5, [%g7] ASI_PHYS_BYPASS_EC_E
759 andn %g5, AUXIO_AUX1_FTCNT, %g5
760/* andn %g5, AUXIO_AUX1_MASK, %g5 */
761
762 nop; nop; nop; nop; nop; nop;
763 nop; nop; nop; nop; nop; nop;
764
765 stba %g5, [%g7] ASI_PHYS_BYPASS_EC_E
766 sethi %hi(doing_pdma), %g1
767 b,pt %xcc, floppy_dosoftint
768 st %g0, [%g1 + %lo(doing_pdma)]
769
770floppy_fifo_emptied:
771 sethi %hi(pdma_vaddr), %g1
772 stx %g4, [%g1 + %lo(pdma_vaddr)]
773 sethi %hi(pdma_size), %g1
774 stx %g5, [%g1 + %lo(pdma_size)]
775 sethi %hi(irq_action), %g1
776 or %g1, %lo(irq_action), %g1
777 ldx [%g1 + (11 << 3)], %g3 ! irqaction[floppy_irq]
778 ldx [%g3 + 0x08], %g4 ! action->flags>>48==ino
779 sethi %hi(ivector_table), %g3
780 srlx %g4, 48, %g4
781 or %g3, %lo(ivector_table), %g3
782 sllx %g4, 5, %g4
783 ldx [%g3 + %g4], %g4 ! &ivector_table[ino]
784 ldx [%g4 + 0x10], %g4 ! bucket->iclr
785 stwa %g0, [%g4] ASI_PHYS_BYPASS_EC_E ! ICLR_IDLE
786 membar #Sync ! probably not needed...
787 retry
788
789floppy_overrun:
790 sethi %hi(pdma_vaddr), %g1
791 stx %g4, [%g1 + %lo(pdma_vaddr)]
792 sethi %hi(pdma_size), %g1
793 stx %g5, [%g1 + %lo(pdma_size)]
794 sethi %hi(doing_pdma), %g1
795 st %g0, [%g1 + %lo(doing_pdma)]
796
797floppy_dosoftint:
798 rdpr %pil, %g2
799 wrpr %g0, 15, %pil
800 sethi %hi(109f), %g7
801 b,pt %xcc, etrap_irq
802109: or %g7, %lo(109b), %g7
803
804 mov 11, %o0
805 mov 0, %o1
806 call sparc_floppy_irq
807 add %sp, PTREGS_OFF, %o2
808
809 b,pt %xcc, rtrap_irq
810 nop
811
812#endif /* CONFIG_BLK_DEV_FD */
813
814 /* XXX Here is stuff we still need to write... -DaveM XXX */ 704 /* XXX Here is stuff we still need to write... -DaveM XXX */
815 .globl netbsd_syscall 705 .globl netbsd_syscall
816netbsd_syscall: 706netbsd_syscall:
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c
index 4dcb8af94090..424712577307 100644
--- a/arch/sparc64/kernel/irq.c
+++ b/arch/sparc64/kernel/irq.c
@@ -37,6 +37,7 @@
37#include <asm/uaccess.h> 37#include <asm/uaccess.h>
38#include <asm/cache.h> 38#include <asm/cache.h>
39#include <asm/cpudata.h> 39#include <asm/cpudata.h>
40#include <asm/auxio.h>
40 41
41#ifdef CONFIG_SMP 42#ifdef CONFIG_SMP
42static void distribute_irqs(void); 43static void distribute_irqs(void);
@@ -834,137 +835,65 @@ void handler_irq(int irq, struct pt_regs *regs)
834} 835}
835 836
836#ifdef CONFIG_BLK_DEV_FD 837#ifdef CONFIG_BLK_DEV_FD
837extern void floppy_interrupt(int irq, void *dev_cookie, struct pt_regs *regs); 838extern irqreturn_t floppy_interrupt(int, void *, struct pt_regs *);;
838 839
839void sparc_floppy_irq(int irq, void *dev_cookie, struct pt_regs *regs) 840/* XXX No easy way to include asm/floppy.h XXX */
840{ 841extern unsigned char *pdma_vaddr;
841 struct irqaction *action = *(irq + irq_action); 842extern unsigned long pdma_size;
842 struct ino_bucket *bucket; 843extern volatile int doing_pdma;
843 int cpu = smp_processor_id(); 844extern unsigned long fdc_status;
844
845 irq_enter();
846 kstat_this_cpu.irqs[irq]++;
847
848 *(irq_work(cpu, irq)) = 0;
849 bucket = get_ino_in_irqaction(action) + ivector_table;
850
851 bucket->flags |= IBF_INPROGRESS;
852
853 floppy_interrupt(irq, dev_cookie, regs);
854 upa_writel(ICLR_IDLE, bucket->iclr);
855
856 bucket->flags &= ~IBF_INPROGRESS;
857
858 irq_exit();
859}
860#endif
861
862/* The following assumes that the branch lies before the place we
863 * are branching to. This is the case for a trap vector...
864 * You have been warned.
865 */
866#define SPARC_BRANCH(dest_addr, inst_addr) \
867 (0x10800000 | ((((dest_addr)-(inst_addr))>>2)&0x3fffff))
868
869#define SPARC_NOP (0x01000000)
870 845
871static void install_fast_irq(unsigned int cpu_irq, 846irqreturn_t sparc_floppy_irq(int irq, void *dev_cookie, struct pt_regs *regs)
872 irqreturn_t (*handler)(int, void *, struct pt_regs *))
873{ 847{
874 extern unsigned long sparc64_ttable_tl0; 848 if (likely(doing_pdma)) {
875 unsigned long ttent = (unsigned long) &sparc64_ttable_tl0; 849 void __iomem *stat = (void __iomem *) fdc_status;
876 unsigned int *insns; 850 unsigned char *vaddr = pdma_vaddr;
877 851 unsigned long size = pdma_size;
878 ttent += 0x820; 852 u8 val;
879 ttent += (cpu_irq - 1) << 5; 853
880 insns = (unsigned int *) ttent; 854 while (size) {
881 insns[0] = SPARC_BRANCH(((unsigned long) handler), 855 val = readb(stat);
882 ((unsigned long)&insns[0])); 856 if (unlikely(!(val & 0x80))) {
883 insns[1] = SPARC_NOP; 857 pdma_vaddr = vaddr;
884 __asm__ __volatile__("membar #StoreStore; flush %0" : : "r" (ttent)); 858 pdma_size = size;
885} 859 return IRQ_HANDLED;
886 860 }
887int request_fast_irq(unsigned int irq, 861 if (unlikely(!(val & 0x20))) {
888 irqreturn_t (*handler)(int, void *, struct pt_regs *), 862 pdma_vaddr = vaddr;
889 unsigned long irqflags, const char *name, void *dev_id) 863 pdma_size = size;
890{ 864 doing_pdma = 0;
891 struct irqaction *action; 865 goto main_interrupt;
892 struct ino_bucket *bucket = __bucket(irq); 866 }
893 unsigned long flags; 867 if (val & 0x40) {
894 868 /* read */
895 /* No pil0 dummy buckets allowed here. */ 869 *vaddr++ = readb(stat + 1);
896 if (bucket < &ivector_table[0] || 870 } else {
897 bucket >= &ivector_table[NUM_IVECS]) { 871 unsigned char data = *vaddr++;
898 unsigned int *caller;
899
900 __asm__ __volatile__("mov %%i7, %0" : "=r" (caller));
901 printk(KERN_CRIT "request_fast_irq: Old style IRQ registry attempt "
902 "from %p, irq %08x.\n", caller, irq);
903 return -EINVAL;
904 }
905
906 if (!handler)
907 return -EINVAL;
908 872
909 if ((bucket->pil == 0) || (bucket->pil == 14)) { 873 /* write */
910 printk("request_fast_irq: Trying to register shared IRQ 0 or 14.\n"); 874 writeb(data, stat + 1);
911 return -EBUSY; 875 }
912 } 876 size--;
877 }
913 878
914 spin_lock_irqsave(&irq_action_lock, flags); 879 pdma_vaddr = vaddr;
880 pdma_size = size;
915 881
916 action = *(bucket->pil + irq_action); 882 /* Send Terminal Count pulse to floppy controller. */
917 if (action) { 883 val = readb(auxio_register);
918 if (action->flags & SA_SHIRQ) 884 val |= AUXIO_AUX1_FTCNT;
919 panic("Trying to register fast irq when already shared.\n"); 885 writeb(val, auxio_register);
920 if (irqflags & SA_SHIRQ) 886 val &= AUXIO_AUX1_FTCNT;
921 panic("Trying to register fast irq as shared.\n"); 887 writeb(val, auxio_register);
922 printk("request_fast_irq: Trying to register yet already owned.\n");
923 spin_unlock_irqrestore(&irq_action_lock, flags);
924 return -EBUSY;
925 }
926 888
927 /* 889 doing_pdma = 0;
928 * We do not check for SA_SAMPLE_RANDOM in this path. Neither do we
929 * support smp intr affinity in this path.
930 */
931 if (irqflags & SA_STATIC_ALLOC) {
932 if (static_irq_count < MAX_STATIC_ALLOC)
933 action = &static_irqaction[static_irq_count++];
934 else
935 printk("Request for IRQ%d (%s) SA_STATIC_ALLOC failed "
936 "using kmalloc\n", bucket->pil, name);
937 }
938 if (action == NULL)
939 action = (struct irqaction *)kmalloc(sizeof(struct irqaction),
940 GFP_ATOMIC);
941 if (!action) {
942 spin_unlock_irqrestore(&irq_action_lock, flags);
943 return -ENOMEM;
944 } 890 }
945 install_fast_irq(bucket->pil, handler);
946 891
947 bucket->irq_info = action; 892main_interrupt:
948 bucket->flags |= IBF_ACTIVE; 893 return floppy_interrupt(irq, dev_cookie, regs);
949
950 action->handler = handler;
951 action->flags = irqflags;
952 action->dev_id = NULL;
953 action->name = name;
954 action->next = NULL;
955 put_ino_in_irqaction(action, irq);
956 put_smpaff_in_irqaction(action, CPU_MASK_NONE);
957
958 *(bucket->pil + irq_action) = action;
959 enable_irq(irq);
960
961 spin_unlock_irqrestore(&irq_action_lock, flags);
962
963#ifdef CONFIG_SMP
964 distribute_irqs();
965#endif
966 return 0;
967} 894}
895EXPORT_SYMBOL(sparc_floppy_irq);
896#endif
968 897
969/* We really don't need these at all on the Sparc. We only have 898/* We really don't need these at all on the Sparc. We only have
970 * stubs here because they are exported to modules. 899 * stubs here because they are exported to modules.
diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c
index e78cc53594fa..56cd96f4a5cd 100644
--- a/arch/sparc64/kernel/sparc64_ksyms.c
+++ b/arch/sparc64/kernel/sparc64_ksyms.c
@@ -227,7 +227,6 @@ EXPORT_SYMBOL(__flush_dcache_range);
227 227
228EXPORT_SYMBOL(mostek_lock); 228EXPORT_SYMBOL(mostek_lock);
229EXPORT_SYMBOL(mstk48t02_regs); 229EXPORT_SYMBOL(mstk48t02_regs);
230EXPORT_SYMBOL(request_fast_irq);
231#ifdef CONFIG_SUN_AUXIO 230#ifdef CONFIG_SUN_AUXIO
232EXPORT_SYMBOL(auxio_set_led); 231EXPORT_SYMBOL(auxio_set_led);
233EXPORT_SYMBOL(auxio_set_lte); 232EXPORT_SYMBOL(auxio_set_lte);