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

Commit 0c326387 authored by David Daney's avatar David Daney Committed by Thomas Gleixner
Browse files

MIPS: Octeon: Rewrite interrupt handling code.



This includes conversion to new style irq_chip functions, and
correctly enabling/disabling per-CPU interrupts.

The hardware interrupt bit to irq number mapping is now done with a
flexible map, instead of by bit twiddling the irq number.

[ tglx: Adjusted to new irq_cpu_on/offline callbacks and
        __irq_set_affinity_lock ]

Signed-off-by: default avatarDavid Daney <ddaney@caviumnetworks.com>
Cc: linux-mips@linux-mips.org
Cc: ralf@linux-mips.org
LKML-Reference: <1301081931-11240-5-git-send-email-ddaney@caviumnetworks.com>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent a4584656
Loading
Loading
Loading
Loading
+815 −607

File changed.

Preview size limit exceeded, changes collapsed.

+0 −12
Original line number Diff line number Diff line
@@ -420,7 +420,6 @@ void octeon_user_io_init(void)
void __init prom_init(void)
{
	struct cvmx_sysinfo *sysinfo;
	const int coreid = cvmx_get_core_num();
	int i;
	int argc;
#ifdef CONFIG_CAVIUM_RESERVE32
@@ -537,17 +536,6 @@ void __init prom_init(void)

	octeon_uart = octeon_get_boot_uart();

	/*
	 * Disable All CIU Interrupts. The ones we need will be
	 * enabled later.  Read the SUM register so we know the write
	 * completed.
	 */
	cvmx_write_csr(CVMX_CIU_INTX_EN0((coreid * 2)), 0);
	cvmx_write_csr(CVMX_CIU_INTX_EN0((coreid * 2 + 1)), 0);
	cvmx_write_csr(CVMX_CIU_INTX_EN1((coreid * 2)), 0);
	cvmx_write_csr(CVMX_CIU_INTX_EN1((coreid * 2 + 1)), 0);
	cvmx_read_csr(CVMX_CIU_INTX_SUM0((coreid * 2)));

#ifdef CONFIG_SMP
	octeon_write_lcd("LinuxSMP");
#else
+13 −26
Original line number Diff line number Diff line
@@ -171,41 +171,19 @@ static void octeon_boot_secondary(int cpu, struct task_struct *idle)
 * After we've done initial boot, this function is called to allow the
 * board code to clean up state, if needed
 */
static void octeon_init_secondary(void)
static void __cpuinit octeon_init_secondary(void)
{
	const int coreid = cvmx_get_core_num();
	union cvmx_ciu_intx_sum0 interrupt_enable;
	unsigned int sr;

#ifdef CONFIG_HOTPLUG_CPU
	struct linux_app_boot_info *labi;

	labi = (struct linux_app_boot_info *)PHYS_TO_XKSEG_CACHED(LABI_ADDR_IN_BOOTLOADER);

	if (labi->labi_signature != LABI_SIGNATURE)
		panic("The bootloader version on this board is incorrect.");
#endif

	sr = set_c0_status(ST0_BEV);
	write_c0_ebase((u32)ebase);
	write_c0_status(sr);

	octeon_check_cpu_bist();
	octeon_init_cvmcount();
	/*
	pr_info("SMP: CPU%d (CoreId %lu) started\n", cpu, coreid);
	*/
	/* Enable Mailbox interrupts to this core. These are the only
	   interrupts allowed on line 3 */
	cvmx_write_csr(CVMX_CIU_MBOX_CLRX(coreid), 0xffffffff);
	interrupt_enable.u64 = 0;
	interrupt_enable.s.mbox = 0x3;
	cvmx_write_csr(CVMX_CIU_INTX_EN0((coreid * 2)), interrupt_enable.u64);
	cvmx_write_csr(CVMX_CIU_INTX_EN0((coreid * 2 + 1)), 0);
	cvmx_write_csr(CVMX_CIU_INTX_EN1((coreid * 2)), 0);
	cvmx_write_csr(CVMX_CIU_INTX_EN1((coreid * 2 + 1)), 0);
	/* Enable core interrupt processing for 2,3 and 7 */
	set_c0_status(0x8c01);

	octeon_irq_setup_secondary();
	raw_local_irq_enable();
}

/**
@@ -214,6 +192,15 @@ static void octeon_init_secondary(void)
 */
void octeon_prepare_cpus(unsigned int max_cpus)
{
#ifdef CONFIG_HOTPLUG_CPU
	struct linux_app_boot_info *labi;

	labi = (struct linux_app_boot_info *)PHYS_TO_XKSEG_CACHED(LABI_ADDR_IN_BOOTLOADER);

	if (labi->labi_signature != LABI_SIGNATURE)
		panic("The bootloader version on this board is incorrect.");
#endif

	cvmx_write_csr(CVMX_CIU_MBOX_CLRX(cvmx_get_core_num()), 0xffffffff);
	if (request_irq(OCTEON_IRQ_MBOX0, mailbox_interrupt, IRQF_DISABLED,
			"mailbox0", mailbox_interrupt)) {
+81 −162
Original line number Diff line number Diff line
@@ -11,172 +11,91 @@
#define NR_IRQS OCTEON_IRQ_LAST
#define MIPS_CPU_IRQ_BASE OCTEON_IRQ_SW0

/* 0 - 7 represent the i8259 master */
#define OCTEON_IRQ_I8259M0	0
#define OCTEON_IRQ_I8259M1	1
#define OCTEON_IRQ_I8259M2	2
#define OCTEON_IRQ_I8259M3	3
#define OCTEON_IRQ_I8259M4	4
#define OCTEON_IRQ_I8259M5	5
#define OCTEON_IRQ_I8259M6	6
#define OCTEON_IRQ_I8259M7	7
/* 8 - 15 represent the i8259 slave */
#define OCTEON_IRQ_I8259S0	8
#define OCTEON_IRQ_I8259S1	9
#define OCTEON_IRQ_I8259S2	10
#define OCTEON_IRQ_I8259S3	11
#define OCTEON_IRQ_I8259S4	12
#define OCTEON_IRQ_I8259S5	13
#define OCTEON_IRQ_I8259S6	14
#define OCTEON_IRQ_I8259S7	15
/* 16 - 23 represent the 8 MIPS standard interrupt sources */
#define OCTEON_IRQ_SW0		16
#define OCTEON_IRQ_SW1		17
#define OCTEON_IRQ_CIU0		18
#define OCTEON_IRQ_CIU1		19
#define OCTEON_IRQ_CIU4		20
#define OCTEON_IRQ_5		21
#define OCTEON_IRQ_PERF		22
#define OCTEON_IRQ_TIMER	23
/* 24 - 87 represent the sources in CIU_INTX_EN0 */
#define OCTEON_IRQ_WORKQ0	24
#define OCTEON_IRQ_WORKQ1	25
#define OCTEON_IRQ_WORKQ2	26
#define OCTEON_IRQ_WORKQ3	27
#define OCTEON_IRQ_WORKQ4	28
#define OCTEON_IRQ_WORKQ5	29
#define OCTEON_IRQ_WORKQ6	30
#define OCTEON_IRQ_WORKQ7	31
#define OCTEON_IRQ_WORKQ8	32
#define OCTEON_IRQ_WORKQ9	33
#define OCTEON_IRQ_WORKQ10	34
#define OCTEON_IRQ_WORKQ11	35
#define OCTEON_IRQ_WORKQ12	36
#define OCTEON_IRQ_WORKQ13	37
#define OCTEON_IRQ_WORKQ14	38
#define OCTEON_IRQ_WORKQ15	39
#define OCTEON_IRQ_GPIO0	40
#define OCTEON_IRQ_GPIO1	41
#define OCTEON_IRQ_GPIO2	42
#define OCTEON_IRQ_GPIO3	43
#define OCTEON_IRQ_GPIO4	44
#define OCTEON_IRQ_GPIO5	45
#define OCTEON_IRQ_GPIO6	46
#define OCTEON_IRQ_GPIO7	47
#define OCTEON_IRQ_GPIO8	48
#define OCTEON_IRQ_GPIO9	49
#define OCTEON_IRQ_GPIO10	50
#define OCTEON_IRQ_GPIO11	51
#define OCTEON_IRQ_GPIO12	52
#define OCTEON_IRQ_GPIO13	53
#define OCTEON_IRQ_GPIO14	54
#define OCTEON_IRQ_GPIO15	55
#define OCTEON_IRQ_MBOX0	56
#define OCTEON_IRQ_MBOX1	57
#define OCTEON_IRQ_UART0	58
#define OCTEON_IRQ_UART1	59
#define OCTEON_IRQ_PCI_INT0	60
#define OCTEON_IRQ_PCI_INT1	61
#define OCTEON_IRQ_PCI_INT2	62
#define OCTEON_IRQ_PCI_INT3	63
#define OCTEON_IRQ_PCI_MSI0	64
#define OCTEON_IRQ_PCI_MSI1	65
#define OCTEON_IRQ_PCI_MSI2	66
#define OCTEON_IRQ_PCI_MSI3	67
#define OCTEON_IRQ_RESERVED68	68	/* Summary of CIU_INT_SUM1 */
#define OCTEON_IRQ_TWSI		69
#define OCTEON_IRQ_RML		70
#define OCTEON_IRQ_TRACE	71
#define OCTEON_IRQ_GMX_DRP0	72
#define OCTEON_IRQ_GMX_DRP1	73
#define OCTEON_IRQ_IPD_DRP	74
#define OCTEON_IRQ_KEY_ZERO	75
#define OCTEON_IRQ_TIMER0	76
#define OCTEON_IRQ_TIMER1	77
#define OCTEON_IRQ_TIMER2	78
#define OCTEON_IRQ_TIMER3	79
#define OCTEON_IRQ_USB0		80
#define OCTEON_IRQ_PCM		81
#define OCTEON_IRQ_MPI		82
#define OCTEON_IRQ_TWSI2	83
#define OCTEON_IRQ_POWIQ	84
#define OCTEON_IRQ_IPDPPTHR	85
#define OCTEON_IRQ_MII0		86
#define OCTEON_IRQ_BOOTDMA	87
/* 88 - 151 represent the sources in CIU_INTX_EN1 */
#define OCTEON_IRQ_WDOG0	88
#define OCTEON_IRQ_WDOG1	89
#define OCTEON_IRQ_WDOG2	90
#define OCTEON_IRQ_WDOG3	91
#define OCTEON_IRQ_WDOG4	92
#define OCTEON_IRQ_WDOG5	93
#define OCTEON_IRQ_WDOG6	94
#define OCTEON_IRQ_WDOG7	95
#define OCTEON_IRQ_WDOG8	96
#define OCTEON_IRQ_WDOG9	97
#define OCTEON_IRQ_WDOG10	98
#define OCTEON_IRQ_WDOG11	99
#define OCTEON_IRQ_WDOG12	100
#define OCTEON_IRQ_WDOG13	101
#define OCTEON_IRQ_WDOG14	102
#define OCTEON_IRQ_WDOG15	103
#define OCTEON_IRQ_UART2	104
#define OCTEON_IRQ_USB1		105
#define OCTEON_IRQ_MII1		106
#define OCTEON_IRQ_RESERVED107	107
#define OCTEON_IRQ_RESERVED108	108
#define OCTEON_IRQ_RESERVED109	109
#define OCTEON_IRQ_RESERVED110	110
#define OCTEON_IRQ_RESERVED111	111
#define OCTEON_IRQ_RESERVED112	112
#define OCTEON_IRQ_RESERVED113	113
#define OCTEON_IRQ_RESERVED114	114
#define OCTEON_IRQ_RESERVED115	115
#define OCTEON_IRQ_RESERVED116	116
#define OCTEON_IRQ_RESERVED117	117
#define OCTEON_IRQ_RESERVED118	118
#define OCTEON_IRQ_RESERVED119	119
#define OCTEON_IRQ_RESERVED120	120
#define OCTEON_IRQ_RESERVED121	121
#define OCTEON_IRQ_RESERVED122	122
#define OCTEON_IRQ_RESERVED123	123
#define OCTEON_IRQ_RESERVED124	124
#define OCTEON_IRQ_RESERVED125	125
#define OCTEON_IRQ_RESERVED126	126
#define OCTEON_IRQ_RESERVED127	127
#define OCTEON_IRQ_RESERVED128	128
#define OCTEON_IRQ_RESERVED129	129
#define OCTEON_IRQ_RESERVED130	130
#define OCTEON_IRQ_RESERVED131	131
#define OCTEON_IRQ_RESERVED132	132
#define OCTEON_IRQ_RESERVED133	133
#define OCTEON_IRQ_RESERVED134	134
#define OCTEON_IRQ_RESERVED135	135
#define OCTEON_IRQ_RESERVED136	136
#define OCTEON_IRQ_RESERVED137	137
#define OCTEON_IRQ_RESERVED138	138
#define OCTEON_IRQ_RESERVED139	139
#define OCTEON_IRQ_RESERVED140	140
#define OCTEON_IRQ_RESERVED141	141
#define OCTEON_IRQ_RESERVED142	142
#define OCTEON_IRQ_RESERVED143	143
#define OCTEON_IRQ_RESERVED144	144
#define OCTEON_IRQ_RESERVED145	145
#define OCTEON_IRQ_RESERVED146	146
#define OCTEON_IRQ_RESERVED147	147
#define OCTEON_IRQ_RESERVED148	148
#define OCTEON_IRQ_RESERVED149	149
#define OCTEON_IRQ_RESERVED150	150
#define OCTEON_IRQ_RESERVED151	151
enum octeon_irq {
/* 1 - 8 represent the 8 MIPS standard interrupt sources */
	OCTEON_IRQ_SW0 = 1,
	OCTEON_IRQ_SW1,
/* CIU0, CUI2, CIU4 are 3, 4, 5 */
	OCTEON_IRQ_5 = 6,
	OCTEON_IRQ_PERF,
	OCTEON_IRQ_TIMER,
/* sources in CIU_INTX_EN0 */
	OCTEON_IRQ_WORKQ0,
	OCTEON_IRQ_GPIO0 = OCTEON_IRQ_WORKQ0 + 16,
	OCTEON_IRQ_WDOG0 = OCTEON_IRQ_GPIO0 + 16,
	OCTEON_IRQ_WDOG15 = OCTEON_IRQ_WDOG0 + 15,
	OCTEON_IRQ_MBOX0 = OCTEON_IRQ_WDOG0 + 16,
	OCTEON_IRQ_MBOX1,
	OCTEON_IRQ_UART0,
	OCTEON_IRQ_UART1,
	OCTEON_IRQ_UART2,
	OCTEON_IRQ_PCI_INT0,
	OCTEON_IRQ_PCI_INT1,
	OCTEON_IRQ_PCI_INT2,
	OCTEON_IRQ_PCI_INT3,
	OCTEON_IRQ_PCI_MSI0,
	OCTEON_IRQ_PCI_MSI1,
	OCTEON_IRQ_PCI_MSI2,
	OCTEON_IRQ_PCI_MSI3,

	OCTEON_IRQ_TWSI,
	OCTEON_IRQ_TWSI2,
	OCTEON_IRQ_RML,
	OCTEON_IRQ_TRACE0,
	OCTEON_IRQ_GMX_DRP0 = OCTEON_IRQ_TRACE0 + 4,
	OCTEON_IRQ_IPD_DRP = OCTEON_IRQ_GMX_DRP0 + 5,
	OCTEON_IRQ_KEY_ZERO,
	OCTEON_IRQ_TIMER0,
	OCTEON_IRQ_TIMER1,
	OCTEON_IRQ_TIMER2,
	OCTEON_IRQ_TIMER3,
	OCTEON_IRQ_USB0,
	OCTEON_IRQ_USB1,
	OCTEON_IRQ_PCM,
	OCTEON_IRQ_MPI,
	OCTEON_IRQ_POWIQ,
	OCTEON_IRQ_IPDPPTHR,
	OCTEON_IRQ_MII0,
	OCTEON_IRQ_MII1,
	OCTEON_IRQ_BOOTDMA,

	OCTEON_IRQ_NAND,
	OCTEON_IRQ_MIO,		/* Summary of MIO_BOOT_ERR */
	OCTEON_IRQ_IOB,		/* Summary of IOB_INT_SUM */
	OCTEON_IRQ_FPA,		/* Summary of FPA_INT_SUM */
	OCTEON_IRQ_POW,		/* Summary of POW_ECC_ERR */
	OCTEON_IRQ_L2C,		/* Summary of L2C_INT_STAT */
	OCTEON_IRQ_IPD,		/* Summary of IPD_INT_SUM */
	OCTEON_IRQ_PIP,		/* Summary of PIP_INT_REG */
	OCTEON_IRQ_PKO,		/* Summary of PKO_REG_ERROR */
	OCTEON_IRQ_ZIP,		/* Summary of ZIP_ERROR */
	OCTEON_IRQ_TIM,		/* Summary of TIM_REG_ERROR */
	OCTEON_IRQ_RAD,		/* Summary of RAD_REG_ERROR */
	OCTEON_IRQ_KEY,		/* Summary of KEY_INT_SUM */
	OCTEON_IRQ_DFA,		/* Summary of DFA */
	OCTEON_IRQ_USBCTL,	/* Summary of USBN0_INT_SUM */
	OCTEON_IRQ_SLI,		/* Summary of SLI_INT_SUM */
	OCTEON_IRQ_DPI,		/* Summary of DPI_INT_SUM */
	OCTEON_IRQ_AGX0,	/* Summary of GMX0*+PCS0_INT*_REG */
	OCTEON_IRQ_AGL  = OCTEON_IRQ_AGX0 + 5,
	OCTEON_IRQ_PTP,
	OCTEON_IRQ_PEM0,
	OCTEON_IRQ_PEM1,
	OCTEON_IRQ_SRIO0,
	OCTEON_IRQ_SRIO1,
	OCTEON_IRQ_LMC0,
	OCTEON_IRQ_DFM = OCTEON_IRQ_LMC0 + 4,		/* Summary of DFM */
	OCTEON_IRQ_RST,
};

#ifdef CONFIG_PCI_MSI
/* 152 - 215 represent the MSI interrupts 0-63 */
#define OCTEON_IRQ_MSI_BIT0	152
#define OCTEON_IRQ_MSI_LAST	(OCTEON_IRQ_MSI_BIT0 + 255)
/* 152 - 407 represent the MSI interrupts 0-255 */
#define OCTEON_IRQ_MSI_BIT0	(OCTEON_IRQ_RST + 1)

#define OCTEON_IRQ_MSI_LAST      (OCTEON_IRQ_MSI_BIT0 + 255)
#define OCTEON_IRQ_LAST          (OCTEON_IRQ_MSI_LAST + 1)
#else
#define OCTEON_IRQ_LAST         152
#define OCTEON_IRQ_LAST         (OCTEON_IRQ_RST + 1)
#endif

#endif
+2 −0
Original line number Diff line number Diff line
@@ -257,4 +257,6 @@ extern struct cvmx_bootinfo *octeon_bootinfo;

extern uint64_t octeon_bootloader_entry_addr;

extern void (*octeon_irq_setup_secondary)(void);

#endif /* __ASM_OCTEON_OCTEON_H */
Loading