aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/irq.c
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/sparc64/kernel/irq.c
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/sparc64/kernel/irq.c')
-rw-r--r--arch/sparc64/kernel/irq.c171
1 files changed, 50 insertions, 121 deletions
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.