aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/cpu/sh4a/setup-sh7786.c
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2010-04-15 00:13:52 -0400
committerPaul Mundt <lethal@linux-sh.org>2010-04-15 00:13:52 -0400
commitdc825b17904a06bbd2f79d720b23156e4c01a22f (patch)
tree8f1e13b850a06264530f1f1bb680a541e73cef34 /arch/sh/kernel/cpu/sh4a/setup-sh7786.c
parentfecf066c2d2fbc7e6a7e7e3a5af772a165bdd7b0 (diff)
sh: intc: IRQ auto-distribution support.
This implements support for hardware-managed IRQ balancing as implemented by SH-X3 cores (presently only hooked up for SH7786, but can probably be carried over to other SH-X3 cores, too). CPUs need to specify their distribution register along with the mask definitions, as these follow the same format. Peripheral IRQs that don't opt out of balancing will be automatically distributed at the whim of the hardware block, while each CPU needs to verify whether it is handling the IRQ or not, especially before clearing the mask. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/kernel/cpu/sh4a/setup-sh7786.c')
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7786.c36
1 files changed, 30 insertions, 6 deletions
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c
index 235edf8065df..d7336036d04d 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c
@@ -573,7 +573,6 @@ static struct platform_device *sh7786_devices[] __initdata = {
573 &usb_ohci_device, 573 &usb_ohci_device,
574}; 574};
575 575
576
577/* 576/*
578 * Please call this function if your platform board 577 * Please call this function if your platform board
579 * use external clock for USB 578 * use external clock for USB
@@ -581,6 +580,7 @@ static struct platform_device *sh7786_devices[] __initdata = {
581#define USBCTL0 0xffe70858 580#define USBCTL0 0xffe70858
582#define CLOCK_MODE_MASK 0xffffff7f 581#define CLOCK_MODE_MASK 0xffffff7f
583#define EXT_CLOCK_MODE 0x00000080 582#define EXT_CLOCK_MODE 0x00000080
583
584void __init sh7786_usb_use_exclock(void) 584void __init sh7786_usb_use_exclock(void)
585{ 585{
586 u32 val = __raw_readl(USBCTL0) & CLOCK_MODE_MASK; 586 u32 val = __raw_readl(USBCTL0) & CLOCK_MODE_MASK;
@@ -598,6 +598,7 @@ void __init sh7786_usb_use_exclock(void)
598#define PLL_ENB 0x00000002 598#define PLL_ENB 0x00000002
599#define PHY_RST 0x00000004 599#define PHY_RST 0x00000004
600#define ACT_PLL_STATUS 0xc0000000 600#define ACT_PLL_STATUS 0xc0000000
601
601static void __init sh7786_usb_setup(void) 602static void __init sh7786_usb_setup(void)
602{ 603{
603 int i = 1000000; 604 int i = 1000000;
@@ -753,9 +754,19 @@ static struct intc_vect vectors[] __initdata = {
753#define INTMSK2 0xfe410068 754#define INTMSK2 0xfe410068
754#define INTMSKCLR2 0xfe41006c 755#define INTMSKCLR2 0xfe41006c
755 756
757#define INTDISTCR0 0xfe4100b0
758#define INTDISTCR1 0xfe4100b4
759#define INTACK 0xfe4100b8
760#define INTACKCLR 0xfe4100bc
761#define INT2DISTCR0 0xfe410900
762#define INT2DISTCR1 0xfe410904
763#define INT2DISTCR2 0xfe410908
764#define INT2DISTCR3 0xfe41090c
765
756static struct intc_mask_reg mask_registers[] __initdata = { 766static struct intc_mask_reg mask_registers[] __initdata = {
757 { CnINTMSK0, CnINTMSKCLR0, 32, 767 { CnINTMSK0, CnINTMSKCLR0, 32,
758 { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, 768 { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 },
769 INTC_SMP_BALANCING(INTDISTCR0) },
759 { INTMSK2, INTMSKCLR2, 32, 770 { INTMSK2, INTMSKCLR2, 32,
760 { IRL0_LLLL, IRL0_LLLH, IRL0_LLHL, IRL0_LLHH, 771 { IRL0_LLLL, IRL0_LLLH, IRL0_LLHL, IRL0_LLHH,
761 IRL0_LHLL, IRL0_LHLH, IRL0_LHHL, IRL0_LHHH, 772 IRL0_LHLL, IRL0_LHLH, IRL0_LHHL, IRL0_LHHH,
@@ -767,7 +778,8 @@ static struct intc_mask_reg mask_registers[] __initdata = {
767 IRL4_HHLL, IRL4_HHLH, IRL4_HHHL, 0, } }, 778 IRL4_HHLL, IRL4_HHLH, IRL4_HHHL, 0, } },
768 { CnINT2MSKR0, CnINT2MSKCR0 , 32, 779 { CnINT2MSKR0, CnINT2MSKCR0 , 32,
769 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 780 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
770 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, WDT } }, 781 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, WDT },
782 INTC_SMP_BALANCING(INT2DISTCR0) },
771 { CnINT2MSKR1, CnINT2MSKCR1, 32, 783 { CnINT2MSKR1, CnINT2MSKCR1, 32,
772 { TMU0_0, TMU0_1, TMU0_2, TMU0_3, TMU1_0, TMU1_1, TMU1_2, 0, 784 { TMU0_0, TMU0_1, TMU0_2, TMU0_3, TMU1_0, TMU1_1, TMU1_2, 0,
773 DMAC0_0, DMAC0_1, DMAC0_2, DMAC0_3, DMAC0_4, DMAC0_5, DMAC0_6, 785 DMAC0_0, DMAC0_1, DMAC0_2, DMAC0_3, DMAC0_4, DMAC0_5, DMAC0_6,
@@ -776,14 +788,14 @@ static struct intc_mask_reg mask_registers[] __initdata = {
776 HPB_0, HPB_1, HPB_2, 788 HPB_0, HPB_1, HPB_2,
777 SCIF0_0, SCIF0_1, SCIF0_2, SCIF0_3, 789 SCIF0_0, SCIF0_1, SCIF0_2, SCIF0_3,
778 SCIF1, 790 SCIF1,
779 TMU2, TMU3, 0, } }, 791 TMU2, TMU3, 0, }, INTC_SMP_BALANCING(INT2DISTCR1) },
780 { CnINT2MSKR2, CnINT2MSKCR2, 32, 792 { CnINT2MSKR2, CnINT2MSKCR2, 32,
781 { 0, 0, SCIF2, SCIF3, SCIF4, SCIF5, 793 { 0, 0, SCIF2, SCIF3, SCIF4, SCIF5,
782 Eth_0, Eth_1, 794 Eth_0, Eth_1,
783 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 795 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
784 PCIeC0_0, PCIeC0_1, PCIeC0_2, 796 PCIeC0_0, PCIeC0_1, PCIeC0_2,
785 PCIeC1_0, PCIeC1_1, PCIeC1_2, 797 PCIeC1_0, PCIeC1_1, PCIeC1_2,
786 USB, 0, 0 } }, 798 USB, 0, 0 }, INTC_SMP_BALANCING(INT2DISTCR2) },
787 { CnINT2MSKR3, CnINT2MSKCR3, 32, 799 { CnINT2MSKR3, CnINT2MSKCR3, 32,
788 { 0, 0, 0, 0, 0, 0, 800 { 0, 0, 0, 0, 0, 0,
789 I2C0, I2C1, 801 I2C0, I2C1,
@@ -792,7 +804,7 @@ static struct intc_mask_reg mask_registers[] __initdata = {
792 HAC0, HAC1, 804 HAC0, HAC1,
793 FLCTL, 0, 805 FLCTL, 0,
794 HSPI, GPIO0, GPIO1, Thermal, 806 HSPI, GPIO0, GPIO1, Thermal,
795 0, 0, 0, 0, 0, 0, 0, 0 } }, 807 0, 0, 0, 0, 0, 0, 0, 0 }, INTC_SMP_BALANCING(INT2DISTCR3) },
796}; 808};
797 809
798static struct intc_prio_reg prio_registers[] __initdata = { 810static struct intc_prio_reg prio_registers[] __initdata = {
@@ -910,6 +922,18 @@ static DECLARE_INTC_DESC(intc_desc_irl4567, "sh7786-irl4567", vectors_irl4567,
910#define INTC_INTMSKCLR2 INTMSKCLR2 922#define INTC_INTMSKCLR2 INTMSKCLR2
911#define INTC_USERIMASK 0xfe411000 923#define INTC_USERIMASK 0xfe411000
912 924
925#ifdef CONFIG_INTC_BALANCING
926unsigned int irq_lookup(unsigned int irq)
927{
928 return __raw_readl(INTACK) & 1 ? irq : NO_IRQ_IGNORE;
929}
930
931void irq_finish(unsigned int irq)
932{
933 __raw_writel(irq2evt(irq), INTACKCLR);
934}
935#endif
936
913void __init plat_irq_setup(void) 937void __init plat_irq_setup(void)
914{ 938{
915 /* disable IRQ3-0 + IRQ7-4 */ 939 /* disable IRQ3-0 + IRQ7-4 */