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

Commit 6baa9b20 authored by Sam Ravnborg's avatar Sam Ravnborg Committed by David S. Miller
Browse files

sparc32: genirq support



The conversion of sparc32 to genirq is based on original work done
by David S. Miller.
Daniel Hellstrom has helped in the conversion and implemented
the shutdowm functionality.
Marcel van Nies <morcles@gmail.com> has tested this on Sparc Station 20

Test status:
sun4c      - not tested
sun4m,pci  - not tested
sun4m,sbus - tested (Sparc Classic, Sparc Station 5, Sparc Station 20)
sun4d      - not tested
leon       - tested on various combinations of leon boards,
             including SMP variants

generic
   Introduce use of GENERIC_HARDIRQS and GENERIC_IRQ_SHOW
   Allocate 64 IRQs - which is enough even for SS2000
   Use a table of irq_bucket to maintain uses IRQs
      irq_bucket is also used to chain several irq's that
      must be called when the same intrrupt is asserted
   Use irq_link to link a interrupt source to the irq
   All plafforms must now supply their own build_device_irq method
   handler_irq rewriten to use generic irq support

floppy
   Read FLOPPY_IRQ from platform device
   Use generic request_irq to register the floppy interrupt
   Rewrote sparc_floppy_irq to use the generic irq support

pcic:
   Introduce irq_chip
   Store mask in chip_data for use in mask/unmask functions
   Add build_device_irq for pcic
   Use pcic_build_device_irq in pci_time_init
   allocate virtual irqs in pcic_fill_irq

sun4c:
   Introduce irq_chip
   Store mask in chip_data for use in mask/unmask functions
   Add build_device_irq for sun4c
   Use sun4c_build_device_irq in sun4c_init_timers

sun4m:
   Introduce irq_chip
   Introduce dedicated mask/unmask methods
   Introduce sun4m_handler_data that allow easy access to necessary
     data in the mask/unmask functions
   Add a helper method to enable profile_timer (used from smp)
   Added sun4m_build_device_irq
   Use sun4m_build_device_irq in sun4m_init_timers

   TODO:
      There is no replacement for smp_rotate that always scheduled
      next CPU as interrupt target upon an interrupt

sun4d:
   Introduce irq_chip
   Introduce dedicated mask/unmask methods
   Introduce sun4d_handler_data that allow easy access to
   necessary data in mask/unmask fuctions
   Rewrote sun4d_handler_irq to use generic irq support

   TODO:
      The original implmentation of enable/disable had:

          if (irq < NR_IRQS)
               return;

      The new implmentation does not distingush between SBUS and cpu
      interrupts.
      I am no sure what is right here. I assume we need to do
      something for the cpu interrupts.

      I have not succeeded booting my sun4d box (with or without this patch)
      and my understanding of this platfrom is limited.
      So I would be a bit suprised if this works.

leon:
   Introduce irq_chip
   Store mask in chip_data for use in mask/unmask functions
   Add build_device_irq for leon
   Use leon_build_device_irq in leon_init_timers

Signed-off-by: default avatarSam Ravnborg <sam@ravnborg.org>
Acked-by: default avatarDaniel Hellstrom <daniel@gaisler.com>
Tested-by: default avatarDaniel Hellstrom <daniel@gaisler.com>
Tested-by: default avatarMarcel van Nies <morcles@gmail.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 06010fb5
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -25,6 +25,10 @@ config SPARC
	select HAVE_DMA_ATTRS
	select HAVE_DMA_API_DEBUG
	select HAVE_ARCH_JUMP_LABEL
	select HAVE_GENERIC_HARDIRQS
	select GENERIC_HARDIRQS_NO_DEPRECATED
	select GENERIC_IRQ_SHOW


config SPARC32
	def_bool !64BIT
@@ -50,8 +54,6 @@ config SPARC64
	select RTC_DRV_STARFIRE
	select HAVE_PERF_EVENTS
	select PERF_USE_VMALLOC
	select HAVE_GENERIC_HARDIRQS
	select GENERIC_IRQ_SHOW
	select IRQ_PREFLOW_FASTEOI

config ARCH_DEFCONFIG
+29 −11
Original line number Diff line number Diff line
@@ -281,28 +281,27 @@ static inline void sun_fd_enable_dma(void)
	pdma_areasize = pdma_size;
}

/* Our low-level entry point in arch/sparc/kernel/entry.S */
extern int sparc_floppy_request_irq(int irq, unsigned long flags,
extern int sparc_floppy_request_irq(unsigned int irq,
                                    irq_handler_t irq_handler);

static int sun_fd_request_irq(void)
{
	static int once = 0;
	int error;

	if (!once) {
		once = 1;
		error = sparc_floppy_request_irq(FLOPPY_IRQ,
						 IRQF_DISABLED,
						 floppy_interrupt);
		return ((error == 0) ? 0 : -1);
	} else return 0;
		return sparc_floppy_request_irq(FLOPPY_IRQ, floppy_interrupt);
	} else {
		return 0;
	}
}

static struct linux_prom_registers fd_regs[2];

static int sun_floppy_init(void)
{
	struct platform_device *op;
	struct device_node *dp;
	char state[128];
	phandle tnode, fd_node;
	int num_regs;
@@ -310,7 +309,6 @@ static int sun_floppy_init(void)

	use_virtual_dma = 1;

	FLOPPY_IRQ = 11;
	/* Forget it if we aren't on a machine that could possibly
	 * ever have a floppy drive.
	 */
@@ -349,6 +347,26 @@ static int sun_floppy_init(void)
	sun_fdc = (struct sun_flpy_controller *)
	    of_ioremap(&r, 0, fd_regs[0].reg_size, "floppy");

	/* Look up irq in platform_device.
	 * We try "SUNW,fdtwo" and "fd"
	 */
	for_each_node_by_name(dp, "SUNW,fdtwo") {
		op = of_find_device_by_node(dp);
		if (op)
			break;
	}
	if (!op) {
		for_each_node_by_name(dp, "fd") {
			op = of_find_device_by_node(dp);
			if (op)
				break;
		}
	}
	if (!op)
		goto no_sun_fdc;

	FLOPPY_IRQ = op->archdata.irqs[0];

	/* Last minute sanity check... */
	if(sun_fdc->status_82072 == 0xff) {
		sun_fdc = NULL;
+5 −1
Original line number Diff line number Diff line
@@ -6,7 +6,11 @@
#ifndef _SPARC_IRQ_H
#define _SPARC_IRQ_H

#define NR_IRQS    16
/* Allocated number of logical irq numbers.
 * sun4d boxes (ss2000e) should be OK with ~32.
 * Be on the safe side and make room for 64
 */
#define NR_IRQS    64

#include <linux/interrupt.h>

+0 −5
Original line number Diff line number Diff line
@@ -15,11 +15,6 @@

#include <linux/irqflags.h>

static inline unsigned int probe_irq_mask(unsigned long val)
{
	return 0;
}

/*
 * Sparc (general) CPU types
 */
+0 −4
Original line number Diff line number Diff line
@@ -71,10 +71,6 @@ obj-$(CONFIG_SPARC64) += pcr.o
obj-$(CONFIG_SPARC64)	+= nmi.o
obj-$(CONFIG_SPARC64_SMP) += cpumap.o

# sparc32 do not use GENERIC_HARDIRQS but uses the generic devres implementation
obj-$(CONFIG_SPARC32)     += devres.o
devres-y                  := ../../../kernel/irq/devres.o

obj-y                     += dma.o

obj-$(CONFIG_SPARC32_PCI) += pcic.o
Loading