diff options
Diffstat (limited to 'arch/blackfin/mach-common')
-rw-r--r-- | arch/blackfin/mach-common/clocks-init.c | 139 | ||||
-rw-r--r-- | arch/blackfin/mach-common/cpufreq.c | 5 | ||||
-rw-r--r-- | arch/blackfin/mach-common/entry.S | 7 | ||||
-rw-r--r-- | arch/blackfin/mach-common/ints-priority.c | 331 | ||||
-rw-r--r-- | arch/blackfin/mach-common/pm.c | 8 |
5 files changed, 248 insertions, 242 deletions
diff --git a/arch/blackfin/mach-common/clocks-init.c b/arch/blackfin/mach-common/clocks-init.c index 7ad2407d157..2308ce52f84 100644 --- a/arch/blackfin/mach-common/clocks-init.c +++ b/arch/blackfin/mach-common/clocks-init.c @@ -16,23 +16,14 @@ #include <asm/dpmc.h> #ifdef CONFIG_BF60x -#define CSEL_P 0 -#define S0SEL_P 5 -#define SYSSEL_P 8 -#define S1SEL_P 13 -#define DSEL_P 16 -#define OSEL_P 22 -#define ALGN_P 29 -#define UPDT_P 30 -#define LOCK_P 31 #define CGU_CTL_VAL ((CONFIG_VCO_MULT << 8) | CLKIN_HALF) #define CGU_DIV_VAL \ - ((CONFIG_CCLK_DIV << CSEL_P) | \ - (CONFIG_SCLK_DIV << SYSSEL_P) | \ - (CONFIG_SCLK0_DIV << S0SEL_P) | \ - (CONFIG_SCLK1_DIV << S1SEL_P) | \ - (CONFIG_DCLK_DIV << DSEL_P)) + ((CONFIG_CCLK_DIV << CSEL_OFFSET) | \ + (CONFIG_SCLK_DIV << SYSSEL_OFFSET) | \ + (CONFIG_SCLK0_DIV << S0SEL_OFFSET) | \ + (CONFIG_SCLK1_DIV << S1SEL_OFFSET) | \ + (CONFIG_DCLK_DIV << DSEL_OFFSET)) #define CONFIG_BFIN_DCLK (((CONFIG_CLKIN_HZ * CONFIG_VCO_MULT) / CONFIG_DCLK_DIV) / 1000000) #if ((CONFIG_BFIN_DCLK != 125) && \ @@ -41,89 +32,7 @@ (CONFIG_BFIN_DCLK != 225) && (CONFIG_BFIN_DCLK != 250)) #error "DCLK must be in (125, 133, 150, 166, 200, 225, 250)MHz" #endif -struct ddr_config { - u32 ddr_clk; - u32 dmc_ddrctl; - u32 dmc_ddrcfg; - u32 dmc_ddrtr0; - u32 dmc_ddrtr1; - u32 dmc_ddrtr2; - u32 dmc_ddrmr; - u32 dmc_ddrmr1; -}; -struct ddr_config ddr_config_table[] __attribute__((section(".data_l1"))) = { - [0] = { - .ddr_clk = 125, - .dmc_ddrctl = 0x00000904, - .dmc_ddrcfg = 0x00000422, - .dmc_ddrtr0 = 0x20705212, - .dmc_ddrtr1 = 0x201003CF, - .dmc_ddrtr2 = 0x00320107, - .dmc_ddrmr = 0x00000422, - .dmc_ddrmr1 = 0x4, - }, - [1] = { - .ddr_clk = 133, - .dmc_ddrctl = 0x00000904, - .dmc_ddrcfg = 0x00000422, - .dmc_ddrtr0 = 0x20806313, - .dmc_ddrtr1 = 0x2013040D, - .dmc_ddrtr2 = 0x00320108, - .dmc_ddrmr = 0x00000632, - .dmc_ddrmr1 = 0x4, - }, - [2] = { - .ddr_clk = 150, - .dmc_ddrctl = 0x00000904, - .dmc_ddrcfg = 0x00000422, - .dmc_ddrtr0 = 0x20A07323, - .dmc_ddrtr1 = 0x20160492, - .dmc_ddrtr2 = 0x00320209, - .dmc_ddrmr = 0x00000632, - .dmc_ddrmr1 = 0x4, - }, - [3] = { - .ddr_clk = 166, - .dmc_ddrctl = 0x00000904, - .dmc_ddrcfg = 0x00000422, - .dmc_ddrtr0 = 0x20A07323, - .dmc_ddrtr1 = 0x2016050E, - .dmc_ddrtr2 = 0x00320209, - .dmc_ddrmr = 0x00000632, - .dmc_ddrmr1 = 0x4, - }, - [4] = { - .ddr_clk = 200, - .dmc_ddrctl = 0x00000904, - .dmc_ddrcfg = 0x00000422, - .dmc_ddrtr0 = 0x20a07323, - .dmc_ddrtr1 = 0x2016050f, - .dmc_ddrtr2 = 0x00320509, - .dmc_ddrmr = 0x00000632, - .dmc_ddrmr1 = 0x4, - }, - [5] = { - .ddr_clk = 225, - .dmc_ddrctl = 0x00000904, - .dmc_ddrcfg = 0x00000422, - .dmc_ddrtr0 = 0x20E0A424, - .dmc_ddrtr1 = 0x302006DB, - .dmc_ddrtr2 = 0x0032020D, - .dmc_ddrmr = 0x00000842, - .dmc_ddrmr1 = 0x4, - }, - [6] = { - .ddr_clk = 250, - .dmc_ddrctl = 0x00000904, - .dmc_ddrcfg = 0x00000422, - .dmc_ddrtr0 = 0x20E0A424, - .dmc_ddrtr1 = 0x3020079E, - .dmc_ddrtr2 = 0x0032020D, - .dmc_ddrmr = 0x00000842, - .dmc_ddrmr1 = 0x4, - }, -}; #else #define SDGCTL_WIDTH (1 << 31) /* SDRAM external data path width */ #define PLL_CTL_VAL \ @@ -144,43 +53,9 @@ void init_clocks(void) * in the middle of reprogramming things, and that'll screw us up. * For example, any automatic DMAs left by U-Boot for splash screens. */ - #ifdef CONFIG_BF60x - int i, dlldatacycle, dll_ctl; - bfin_write32(CGU0_DIV, CGU_DIV_VAL); - bfin_write32(CGU0_CTL, CGU_CTL_VAL); - while ((bfin_read32(CGU0_STAT) & 0x8) || !(bfin_read32(CGU0_STAT) & 0x4)) - continue; - - bfin_write32(CGU0_DIV, CGU_DIV_VAL | (1 << UPDT_P)); - while (bfin_read32(CGU0_STAT) & (1 << 3)) - continue; - - for (i = 0; i < 7; i++) { - if (ddr_config_table[i].ddr_clk == CONFIG_BFIN_DCLK) { - bfin_write_DDR0_CFG(ddr_config_table[i].dmc_ddrcfg); - bfin_write_DDR0_TR0(ddr_config_table[i].dmc_ddrtr0); - bfin_write_DDR0_TR1(ddr_config_table[i].dmc_ddrtr1); - bfin_write_DDR0_TR2(ddr_config_table[i].dmc_ddrtr2); - bfin_write_DDR0_MR(ddr_config_table[i].dmc_ddrmr); - bfin_write_DDR0_EMR1(ddr_config_table[i].dmc_ddrmr1); - bfin_write_DDR0_CTL(ddr_config_table[i].dmc_ddrctl); - break; - } - } - - do_sync(); - while (!(bfin_read_DDR0_STAT() & 0x4)) - continue; - - dlldatacycle = (bfin_read_DDR0_STAT() & 0x00f00000) >> 20; - dll_ctl = bfin_read_DDR0_DLLCTL(); - dll_ctl &= 0x0ff; - bfin_write_DDR0_DLLCTL(dll_ctl | (dlldatacycle << 8)); - - do_sync(); - while (!(bfin_read_DDR0_STAT() & 0x2000)) - continue; + init_cgu(CGU_DIV_VAL, CGU_CTL_VAL); + init_dmc(CONFIG_BFIN_DCLK); #else size_t i; for (i = 0; i < MAX_DMA_CHANNELS; ++i) { diff --git a/arch/blackfin/mach-common/cpufreq.c b/arch/blackfin/mach-common/cpufreq.c index 6e87dc13f6b..c854a27cbea 100644 --- a/arch/blackfin/mach-common/cpufreq.c +++ b/arch/blackfin/mach-common/cpufreq.c @@ -64,7 +64,8 @@ static void __init bfin_init_tables(unsigned long cclk, unsigned long sclk) /* Anomaly 273 seems to still exist on non-BF54x w/dcache turned on */ #if ANOMALY_05000273 || ANOMALY_05000274 || \ - (!defined(CONFIG_BF54x) && defined(CONFIG_BFIN_EXTMEM_DCACHEABLE)) + (!(defined(CONFIG_BF54x) || defined(CONFIG_BF60x)) \ + && defined(CONFIG_BFIN_EXTMEM_DCACHEABLE)) min_cclk = sclk * 2; #else min_cclk = sclk; @@ -173,7 +174,7 @@ static int bfin_target(struct cpufreq_policy *poli, #else ret = cpu_set_cclk(cpu, freqs.new * 1000); if (ret != 0) { - pr_debug("cpufreq set freq failed %d\n", ret); + WARN_ONCE(ret, "cpufreq set freq failed %d\n", ret); break; } #endif diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S index 04c2fbe41a7..1c3d2c5bb0b 100644 --- a/arch/blackfin/mach-common/entry.S +++ b/arch/blackfin/mach-common/entry.S @@ -25,13 +25,6 @@ #include <asm/context.S> -#if defined(CONFIG_BFIN_SCRATCH_REG_RETN) -# define EX_SCRATCH_REG RETN -#elif defined(CONFIG_BFIN_SCRATCH_REG_RETE) -# define EX_SCRATCH_REG RETE -#else -# define EX_SCRATCH_REG CYCLES -#endif #ifdef CONFIG_EXCPT_IRQ_SYSC_L1 .section .l1.text diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c index 2729cba715b..7ca09ec2ca5 100644 --- a/arch/blackfin/mach-common/ints-priority.c +++ b/arch/blackfin/mach-common/ints-priority.c @@ -26,8 +26,9 @@ #include <asm/gpio.h> #include <asm/irq_handler.h> #include <asm/dpmc.h> +#include <asm/traps.h> -#ifndef CONFIG_BF60x +#ifndef SEC_GCTL # define SIC_SYSIRQ(irq) (irq - (IRQ_CORETMR + 1)) #else # define SIC_SYSIRQ(irq) ((irq) - IVG15) @@ -56,7 +57,7 @@ unsigned long bfin_sic_iwr[3]; /* Up to 3 SIC_IWRx registers */ unsigned vr_wakeup; #endif -#ifndef CONFIG_BF60x +#ifndef SEC_GCTL static struct ivgx { /* irq number for request_irq, available in mach-bf5xx/irq.h */ unsigned int irqno; @@ -143,7 +144,7 @@ static void bfin_core_unmask_irq(struct irq_data *d) void bfin_internal_mask_irq(unsigned int irq) { unsigned long flags = hard_local_irq_save(); -#ifndef CONFIG_BF60x +#ifndef SEC_GCTL #ifdef SIC_IMASK0 unsigned mask_bank = SIC_SYSIRQ(irq) / 32; unsigned mask_bit = SIC_SYSIRQ(irq) % 32; @@ -175,7 +176,7 @@ void bfin_internal_unmask_irq(unsigned int irq) { unsigned long flags = hard_local_irq_save(); -#ifndef CONFIG_BF60x +#ifndef SEC_GCTL #ifdef SIC_IMASK0 unsigned mask_bank = SIC_SYSIRQ(irq) / 32; unsigned mask_bit = SIC_SYSIRQ(irq) % 32; @@ -199,7 +200,7 @@ void bfin_internal_unmask_irq(unsigned int irq) hard_local_irq_restore(flags); } -#ifdef CONFIG_BF60x +#ifdef SEC_GCTL static void bfin_sec_preflow_handler(struct irq_data *d) { unsigned long flags = hard_local_irq_save(); @@ -310,7 +311,24 @@ static void bfin_sec_disable(struct irq_data *d) hard_local_irq_restore(flags); } -static void bfin_sec_raise_irq(unsigned int sid) +static void bfin_sec_set_priority(unsigned int sec_int_levels, u8 *sec_int_priority) +{ + unsigned long flags = hard_local_irq_save(); + uint32_t reg_sctl; + int i; + + bfin_write_SEC_SCI(0, SEC_CPLVL, sec_int_levels); + + for (i = 0; i < SYS_IRQS - BFIN_IRQ(0); i++) { + reg_sctl = bfin_read_SEC_SCTL(i) & ~SEC_SCTL_PRIO; + reg_sctl |= sec_int_priority[i] << SEC_SCTL_PRIO_OFFSET; + bfin_write_SEC_SCTL(i, reg_sctl); + } + + hard_local_irq_restore(flags); +} + +void bfin_sec_raise_irq(unsigned int sid) { unsigned long flags = hard_local_irq_save(); @@ -396,24 +414,34 @@ void handle_sec_fault(unsigned int irq, struct irq_desc *desc) raw_spin_unlock(&desc->lock); } -static int sec_suspend(void) +void handle_core_fault(unsigned int irq, struct irq_desc *desc) { - return 0; -} + struct pt_regs *fp = get_irq_regs(); -static void sec_resume(void) -{ - bfin_write_SEC_SCI(0, SEC_CCTL, SEC_CCTL_RESET); - udelay(100); - bfin_write_SEC_GCTL(SEC_GCTL_EN); - bfin_write_SEC_SCI(0, SEC_CCTL, SEC_CCTL_EN | SEC_CCTL_NMI_EN); -} + raw_spin_lock(&desc->lock); -static struct syscore_ops sec_pm_syscore_ops = { - .suspend = sec_suspend, - .resume = sec_resume, -}; + switch (irq) { + case IRQ_C0_DBL_FAULT: + double_fault_c(fp); + break; + case IRQ_C0_HW_ERR: + dump_bfin_process(fp); + dump_bfin_mem(fp); + show_regs(fp); + printk(KERN_NOTICE "Kernel Stack\n"); + show_stack(current, NULL); + print_modules(); + panic("Kernel core hardware error"); + break; + case IRQ_C0_NMI_L1_PARITY_ERR: + panic("NMI occurs unexpectedly"); + break; + default: + panic("Core 1 fault occurs unexpectedly"); + } + raw_spin_unlock(&desc->lock); +} #endif #ifdef CONFIG_SMP @@ -437,7 +465,7 @@ static void bfin_internal_unmask_irq_chip(struct irq_data *d) } #endif -#if defined(CONFIG_PM) && !defined(CONFIG_BF60x) +#if defined(CONFIG_PM) && !defined(SEC_GCTL) int bfin_internal_set_wake(unsigned int irq, unsigned int state) { u32 bank, bit, wakeup = 0; @@ -496,7 +524,10 @@ static int bfin_internal_set_wake_chip(struct irq_data *d, unsigned int state) return bfin_internal_set_wake(d->irq, state); } #else -# define bfin_internal_set_wake(irq, state) +inline int bfin_internal_set_wake(unsigned int irq, unsigned int state) +{ + return 0; +} # define bfin_internal_set_wake_chip NULL #endif @@ -518,7 +549,7 @@ static struct irq_chip bfin_internal_irqchip = { .irq_set_wake = bfin_internal_set_wake_chip, }; -#ifdef CONFIG_BF60x +#ifdef SEC_GCTL static struct irq_chip bfin_sec_irqchip = { .name = "SEC", .irq_mask_ack = bfin_sec_mask_ack_irq, @@ -868,14 +899,6 @@ void bfin_demux_gpio_irq(unsigned int inta_irq, #else -# ifndef CONFIG_BF60x -#define NR_PINT_SYS_IRQS 4 -#define NR_PINTS 160 -# else -#define NR_PINT_SYS_IRQS 6 -#define NR_PINTS 112 -#endif - #define NR_PINT_BITS 32 #define IRQ_NOT_AVAIL 0xFF @@ -897,29 +920,21 @@ static struct bfin_pint_regs * const pint[NR_PINT_SYS_IRQS] = { #endif }; -#ifndef CONFIG_BF60x inline unsigned int get_irq_base(u32 bank, u8 bmap) { unsigned int irq_base; +#ifndef CONFIG_BF60x if (bank < 2) { /*PA-PB */ irq_base = IRQ_PA0 + bmap * 16; } else { /*PC-PJ */ irq_base = IRQ_PC0 + bmap * 16; } - - return irq_base; -} #else -inline unsigned int get_irq_base(u32 bank, u8 bmap) -{ - unsigned int irq_base; - irq_base = IRQ_PA0 + bank * 16 + bmap * 16; - +#endif return irq_base; } -#endif /* Whenever PINTx_ASSIGN is altered init_pint_lut() must be executed! */ void init_pint_lut(void) @@ -1089,6 +1104,9 @@ static int bfin_gpio_irq_type(struct irq_data *d, unsigned int type) } #ifdef CONFIG_PM +static struct bfin_pm_pint_save save_pint_reg[NR_PINT_SYS_IRQS]; +static u32 save_pint_sec_ctl[NR_PINT_SYS_IRQS]; + static int bfin_gpio_set_wake(struct irq_data *d, unsigned int state) { u32 pint_irq; @@ -1124,6 +1142,59 @@ static int bfin_gpio_set_wake(struct irq_data *d, unsigned int state) return 0; } + +void bfin_pint_suspend(void) +{ + u32 bank; + + for (bank = 0; bank < NR_PINT_SYS_IRQS; bank++) { + save_pint_reg[bank].mask_set = pint[bank]->mask_set; + save_pint_reg[bank].assign = pint[bank]->assign; + save_pint_reg[bank].edge_set = pint[bank]->edge_set; + save_pint_reg[bank].invert_set = pint[bank]->invert_set; + } +} + +void bfin_pint_resume(void) +{ + u32 bank; + + for (bank = 0; bank < NR_PINT_SYS_IRQS; bank++) { + pint[bank]->mask_set = save_pint_reg[bank].mask_set; + pint[bank]->assign = save_pint_reg[bank].assign; + pint[bank]->edge_set = save_pint_reg[bank].edge_set; + pint[bank]->invert_set = save_pint_reg[bank].invert_set; + } +} + +#ifdef SEC_GCTL +static int sec_suspend(void) +{ + u32 bank; + + for (bank = 0; bank < NR_PINT_SYS_IRQS; bank++) + save_pint_sec_ctl[bank] = bfin_read_SEC_SCTL(bank + SIC_SYSIRQ(IRQ_PINT0)); + return 0; +} + +static void sec_resume(void) +{ + u32 bank; + + bfin_write_SEC_SCI(0, SEC_CCTL, SEC_CCTL_RESET); + udelay(100); + bfin_write_SEC_GCTL(SEC_GCTL_EN); + bfin_write_SEC_SCI(0, SEC_CCTL, SEC_CCTL_EN | SEC_CCTL_NMI_EN); + + for (bank = 0; bank < NR_PINT_SYS_IRQS; bank++) + bfin_write_SEC_SCTL(bank + SIC_SYSIRQ(IRQ_PINT0), save_pint_sec_ctl[bank]); +} + +static struct syscore_ops sec_pm_syscore_ops = { + .suspend = sec_suspend, + .resume = sec_resume, +}; +#endif #else # define bfin_gpio_set_wake NULL #endif @@ -1230,6 +1301,7 @@ void __cpuinit init_exception_vectors(void) CSYNC(); } +#ifndef SEC_GCTL /* * This function should be called during kernel startup to initialize * the BFin IRQ handling routines. @@ -1240,7 +1312,6 @@ int __init init_arch_irq(void) int irq; unsigned long ilat = 0; -#ifndef CONFIG_BF60x /* Disable all the peripheral intrs - page 4-29 HW Ref manual */ #ifdef SIC_IMASK0 bfin_write_SIC_IMASK0(SIC_UNMASK_ALL); @@ -1255,9 +1326,6 @@ int __init init_arch_irq(void) #else bfin_write_SIC_IMASK(SIC_UNMASK_ALL); #endif -#else /* CONFIG_BF60x */ - bfin_write_SEC_GCTL(SEC_GCTL_RESET); -#endif local_irq_disable(); @@ -1267,10 +1335,6 @@ int __init init_arch_irq(void) pint[1]->assign = CONFIG_PINT1_ASSIGN; pint[2]->assign = CONFIG_PINT2_ASSIGN; pint[3]->assign = CONFIG_PINT3_ASSIGN; -# ifdef CONFIG_BF60x - pint[4]->assign = CONFIG_PINT4_ASSIGN; - pint[5]->assign = CONFIG_PINT5_ASSIGN; -# endif # endif /* Whenever PINTx_ASSIGN is altered init_pint_lut() must be executed! */ init_pint_lut(); @@ -1283,7 +1347,6 @@ int __init init_arch_irq(void) irq_set_chip(irq, &bfin_internal_irqchip); switch (irq) { -#ifndef CONFIG_BF60x #if BFIN_GPIO_PINT case IRQ_PINT0: case IRQ_PINT1: @@ -1319,7 +1382,6 @@ int __init init_arch_irq(void) irq_set_handler(irq, handle_percpu_irq); break; #endif -#endif #ifdef CONFIG_TICKSOURCE_CORETMR case IRQ_CORETMR: @@ -1349,8 +1411,7 @@ int __init init_arch_irq(void) init_mach_irq(); -#ifndef CONFIG_BF60x -#if (defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)) && !defined(CONFIG_BF60x) +#if (defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)) for (irq = IRQ_MAC_PHYINT; irq <= IRQ_MAC_STMDONE; irq++) irq_set_chip_and_handler(irq, &bfin_mac_status_irqchip, handle_level_irq); @@ -1360,28 +1421,6 @@ int __init init_arch_irq(void) irq < (GPIO_IRQ_BASE + MAX_BLACKFIN_GPIOS); irq++) irq_set_chip_and_handler(irq, &bfin_gpio_irqchip, handle_level_irq); -#else - for (irq = BFIN_IRQ(0); irq <= SYS_IRQS; irq++) { - if (irq < CORE_IRQS) { - irq_set_chip(irq, &bfin_sec_irqchip); - __irq_set_handler(irq, handle_sec_fault, 0, NULL); - } else if (irq >= BFIN_IRQ(21) && irq <= BFIN_IRQ(26)) { - irq_set_chip(irq, &bfin_sec_irqchip); - irq_set_chained_handler(irq, bfin_demux_gpio_irq); - } else if (irq >= BFIN_IRQ(34) && irq <= BFIN_IRQ(37)) { - irq_set_chip(irq, &bfin_sec_irqchip); - irq_set_handler(irq, handle_percpu_irq); - } else { - irq_set_chip_and_handler(irq, &bfin_sec_irqchip, - handle_fasteoi_irq); - __irq_set_preflow_handler(irq, bfin_sec_preflow_handler); - } - } - for (irq = GPIO_IRQ_BASE; - irq < (GPIO_IRQ_BASE + MAX_BLACKFIN_GPIOS); irq++) - irq_set_chip_and_handler(irq, &bfin_gpio_irqchip, - handle_level_irq); -#endif bfin_write_IMASK(0); CSYNC(); ilat = bfin_read_ILAT(); @@ -1393,7 +1432,6 @@ int __init init_arch_irq(void) /* IMASK=xxx is equivalent to STI xx or bfin_irq_flags=xx, * local_irq_enable() */ -#ifndef CONFIG_BF60x program_IAR(); /* Therefore it's better to setup IARs before interrupts enabled */ search_IAR(); @@ -1427,23 +1465,6 @@ int __init init_arch_irq(void) #else bfin_write_SIC_IWR(IWR_DISABLE_ALL); #endif -#else /* CONFIG_BF60x */ - /* Enable interrupts IVG7-15 */ - bfin_irq_flags |= IMASK_IVG15 | - IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 | - IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW; - - - bfin_write_SEC_FCTL(SEC_FCTL_EN | SEC_FCTL_SYSRST_EN | SEC_FCTL_FLTIN_EN); - bfin_sec_enable_sci(SIC_SYSIRQ(IRQ_WATCH0)); - bfin_sec_enable_ssi(SIC_SYSIRQ(IRQ_WATCH0)); - bfin_write_SEC_SCI(0, SEC_CCTL, SEC_CCTL_RESET); - udelay(100); - bfin_write_SEC_GCTL(SEC_GCTL_EN); - bfin_write_SEC_SCI(0, SEC_CCTL, SEC_CCTL_EN | SEC_CCTL_NMI_EN); - init_software_driven_irq(); - register_syscore_ops(&sec_pm_syscore_ops); -#endif return 0; } @@ -1452,14 +1473,11 @@ __attribute__((l1_text)) #endif static int vec_to_irq(int vec) { -#ifndef CONFIG_BF60x struct ivgx *ivg = ivg7_13[vec - IVG7].ifirst; struct ivgx *ivg_stop = ivg7_13[vec - IVG7].istop; unsigned long sic_status[3]; -#endif if (likely(vec == EVT_IVTMR_P)) return IRQ_CORETMR; -#ifndef CONFIG_BF60x #ifdef SIC_ISR sic_status[0] = bfin_read_SIC_IMASK() & bfin_read_SIC_ISR(); #else @@ -1488,11 +1506,119 @@ static int vec_to_irq(int vec) #endif return ivg->irqno; } -#else - /* for bf60x read */ +} + +#else /* SEC_GCTL */ + +/* + * This function should be called during kernel startup to initialize + * the BFin IRQ handling routines. + */ + +int __init init_arch_irq(void) +{ + int irq; + unsigned long ilat = 0; + + bfin_write_SEC_GCTL(SEC_GCTL_RESET); + + local_irq_disable(); + +#if BFIN_GPIO_PINT +# ifdef CONFIG_PINTx_REASSIGN + pint[0]->assign = CONFIG_PINT0_ASSIGN; + pint[1]->assign = CONFIG_PINT1_ASSIGN; + pint[2]->assign = CONFIG_PINT2_ASSIGN; + pint[3]->assign = CONFIG_PINT3_ASSIGN; + pint[4]->assign = CONFIG_PINT4_ASSIGN; + pint[5]->assign = CONFIG_PINT5_ASSIGN; +# endif + /* Whenever PINTx_ASSIGN is altered init_pint_lut() must be executed! */ + init_pint_lut(); +#endif + + for (irq = 0; irq <= SYS_IRQS; irq++) { + if (irq <= IRQ_CORETMR) { + irq_set_chip(irq, &bfin_core_irqchip); +#ifdef CONFIG_TICKSOURCE_CORETMR + if (irq == IRQ_CORETMR) +# ifdef CONFIG_SMP + irq_set_handler(irq, handle_percpu_irq); +# else + irq_set_handler(irq, handle_simple_irq); +# endif +#endif + } else if (irq < BFIN_IRQ(0)) { + irq_set_chip_and_handler(irq, &bfin_internal_irqchip, + handle_simple_irq); + } else if (irq == IRQ_SEC_ERR) { + irq_set_chip_and_handler(irq, &bfin_sec_irqchip, + handle_sec_fault); + } else if (irq < CORE_IRQS && irq >= IRQ_C0_DBL_FAULT) { + irq_set_chip_and_handler(irq, &bfin_sec_irqchip, + handle_core_fault); + } else if (irq >= BFIN_IRQ(21) && irq <= BFIN_IRQ(26)) { + irq_set_chip(irq, &bfin_sec_irqchip); + irq_set_chained_handler(irq, bfin_demux_gpio_irq); + } else if (irq >= BFIN_IRQ(34) && irq <= BFIN_IRQ(37)) { + irq_set_chip(irq, &bfin_sec_irqchip); + irq_set_handler(irq, handle_percpu_irq); + } else { + irq_set_chip_and_handler(irq, &bfin_sec_irqchip, + handle_fasteoi_irq); + __irq_set_preflow_handler(irq, bfin_sec_preflow_handler); + } + } + for (irq = GPIO_IRQ_BASE; + irq < (GPIO_IRQ_BASE + MAX_BLACKFIN_GPIOS); irq++) + irq_set_chip_and_handler(irq, &bfin_gpio_irqchip, + handle_level_irq); + + bfin_write_IMASK(0); + CSYNC(); + ilat = bfin_read_ILAT(); + CSYNC(); + bfin_write_ILAT(ilat); + CSYNC(); + + printk(KERN_INFO "Configuring Blackfin Priority Driven Interrupts\n"); + + bfin_sec_set_priority(CONFIG_SEC_IRQ_PRIORITY_LEVELS, sec_int_priority); + + bfin_sec_set_priority(CONFIG_SEC_IRQ_PRIORITY_LEVELS, sec_int_priority); + + /* Enable interrupts IVG7-15 */ + bfin_irq_flags |= IMASK_IVG15 | + IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 | + IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW; + + + bfin_write_SEC_FCTL(SEC_FCTL_EN | SEC_FCTL_SYSRST_EN | SEC_FCTL_FLTIN_EN); + bfin_sec_enable_sci(SIC_SYSIRQ(IRQ_WATCH0)); + bfin_sec_enable_ssi(SIC_SYSIRQ(IRQ_WATCH0)); + bfin_write_SEC_SCI(0, SEC_CCTL, SEC_CCTL_RESET); + udelay(100); + bfin_write_SEC_GCTL(SEC_GCTL_EN); + bfin_write_SEC_SCI(0, SEC_CCTL, SEC_CCTL_EN | SEC_CCTL_NMI_EN); + bfin_write_SEC_SCI(1, SEC_CCTL, SEC_CCTL_EN | SEC_CCTL_NMI_EN); + + init_software_driven_irq(); + register_syscore_ops(&sec_pm_syscore_ops); + + return 0; +} + +#ifdef CONFIG_DO_IRQ_L1 +__attribute__((l1_text)) +#endif +static int vec_to_irq(int vec) +{ + if (likely(vec == EVT_IVTMR_P)) + return IRQ_CORETMR; + return BFIN_IRQ(bfin_read_SEC_SCI(0, SEC_CSID)); -#endif /* end of CONFIG_BF60x */ } +#endif /* SEC_GCTL */ #ifdef CONFIG_DO_IRQ_L1 __attribute__((l1_text)) @@ -1514,6 +1640,10 @@ int __ipipe_get_irq_priority(unsigned irq) if (irq <= IRQ_CORETMR) return irq; +#ifdef SEC_GCTL + if (irq >= BFIN_IRQ(0)) + return IVG11; +#else for (ient = 0; ient < NR_PERI_INTS; ient++) { struct ivgx *ivg = ivg_table + ient; if (ivg->irqno == irq) { @@ -1524,6 +1654,7 @@ int __ipipe_get_irq_priority(unsigned irq) } } } +#endif return IVG15; } @@ -1536,8 +1667,6 @@ asmlinkage int __ipipe_grab_irq(int vec, struct pt_regs *regs) { struct ipipe_percpu_domain_data *p = ipipe_root_cpudom_ptr(); struct ipipe_domain *this_domain = __ipipe_current_domain; - struct ivgx *ivg_stop = ivg7_13[vec-IVG7].istop; - struct ivgx *ivg = ivg7_13[vec-IVG7].ifirst; int irq, s = 0; irq = vec_to_irq(vec); diff --git a/arch/blackfin/mach-common/pm.c b/arch/blackfin/mach-common/pm.c index ca6655e0d65..87bfe549ad3 100644 --- a/arch/blackfin/mach-common/pm.c +++ b/arch/blackfin/mach-common/pm.c @@ -172,6 +172,10 @@ int bfin_pm_suspend_mem_enter(void) bfin_gpio_pm_hibernate_suspend(); +#if BFIN_GPIO_PINT + bfin_pint_suspend(); +#endif + #if defined(CONFIG_BFIN_EXTMEM_WRITEBACK) || defined(CONFIG_BFIN_L2_WRITEBACK) flushinv_all_dcache(); #endif @@ -190,6 +194,10 @@ int bfin_pm_suspend_mem_enter(void) _enable_icplb(); _enable_dcplb(); +#if BFIN_GPIO_PINT + bfin_pint_resume(); +#endif + bfin_gpio_pm_hibernate_restore(); blackfin_dma_resume(); |