dect
/
linux-2.6
Archived
13
0
Fork 0

blackfin: SEC: clean up SEC interrupt initialization

Append the SEC IRQ after the IVG6, which is consistent to BF5xx SIC.
Exclude SIC irqchip fucntions from SEC code.
Call handle_fasteoi_irq in SEC error and fault handler.

Signed-off-by: Sonic Zhang <sonic.zhang@analog.com>
Signed-off-by: Bob Liu <lliubbo@gmail.com>
This commit is contained in:
Sonic Zhang 2012-12-14 11:19:24 +08:00 committed by Bob Liu
parent 1439d030b9
commit 86794b4356
4 changed files with 138 additions and 147 deletions

View File

@ -40,8 +40,6 @@
#define IRQ_HWERR 5 /* Hardware Error */
#define IRQ_CORETMR 6 /* Core timer */
#define BFIN_IRQ(x) ((x) + 7)
#define IVG7 7
#define IVG8 8
#define IVG9 9
@ -52,6 +50,9 @@
#define IVG14 14
#define IVG15 15
#define BFIN_IRQ(x) ((x) + IVG7)
#define BFIN_SYSIRQ(x) ((x) - IVG7)
#define NR_IRQS (NR_MACH_IRQS + NR_SPARE_IRQS)
#endif

View File

@ -9,9 +9,6 @@
#include <mach-common/irq.h>
#undef BFIN_IRQ
#define BFIN_IRQ(x) ((x) + IVG15)
#define NR_PERI_INTS (5 * 32)
#define IRQ_SEC_ERR BFIN_IRQ(0) /* SEC Error */

View File

@ -174,7 +174,6 @@ void bfin_hibernate_syscontrol(void)
bfin_write32(DPM0_RESTORE5, bfin_read32(DPM0_RESTORE5) | 4);
}
#define IRQ_SID(irq) ((irq) - IVG15)
asmlinkage void enter_deepsleep(void);
__attribute__((l1_text))
@ -311,7 +310,7 @@ static irqreturn_t test_isr(int irq, void *dev_id)
{
printk(KERN_DEBUG "gpio irq %d\n", irq);
if (irq == 231)
bfin_sec_raise_irq(IRQ_SID(IRQ_SOFT1));
bfin_sec_raise_irq(BFIN_SYSIRQ(IRQ_SOFT1));
return IRQ_HANDLED;
}

View File

@ -28,12 +28,6 @@
#include <asm/dpmc.h>
#include <asm/traps.h>
#ifndef SEC_GCTL
# define SIC_SYSIRQ(irq) (irq - (IRQ_CORETMR + 1))
#else
# define SIC_SYSIRQ(irq) ((irq) - IVG15)
#endif
/*
* NOTES:
* - we have separated the physical Hardware interrupt from the
@ -141,13 +135,13 @@ static void bfin_core_unmask_irq(struct irq_data *d)
return;
}
#ifndef SEC_GCTL
void bfin_internal_mask_irq(unsigned int irq)
{
unsigned long flags = hard_local_irq_save();
#ifndef SEC_GCTL
#ifdef SIC_IMASK0
unsigned mask_bank = SIC_SYSIRQ(irq) / 32;
unsigned mask_bit = SIC_SYSIRQ(irq) % 32;
unsigned mask_bank = BFIN_SYSIRQ(irq) / 32;
unsigned mask_bit = BFIN_SYSIRQ(irq) % 32;
bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) &
~(1 << mask_bit));
# if defined(CONFIG_SMP) || defined(CONFIG_ICC)
@ -156,9 +150,8 @@ void bfin_internal_mask_irq(unsigned int irq)
# endif
#else
bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() &
~(1 << SIC_SYSIRQ(irq)));
~(1 << BFIN_SYSIRQ(irq)));
#endif /* end of SIC_IMASK0 */
#endif
hard_local_irq_restore(flags);
}
@ -176,10 +169,9 @@ void bfin_internal_unmask_irq(unsigned int irq)
{
unsigned long flags = hard_local_irq_save();
#ifndef SEC_GCTL
#ifdef SIC_IMASK0
unsigned mask_bank = SIC_SYSIRQ(irq) / 32;
unsigned mask_bit = SIC_SYSIRQ(irq) % 32;
unsigned mask_bank = BFIN_SYSIRQ(irq) / 32;
unsigned mask_bit = BFIN_SYSIRQ(irq) % 32;
# ifdef CONFIG_SMP
if (cpumask_test_cpu(0, affinity))
# endif
@ -194,17 +186,103 @@ void bfin_internal_unmask_irq(unsigned int irq)
# endif
#else
bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() |
(1 << SIC_SYSIRQ(irq)));
#endif
(1 << BFIN_SYSIRQ(irq)));
#endif
hard_local_irq_restore(flags);
}
#ifdef SEC_GCTL
#ifdef CONFIG_SMP
static void bfin_internal_unmask_irq_chip(struct irq_data *d)
{
bfin_internal_unmask_irq_affinity(d->irq, d->affinity);
}
static int bfin_internal_set_affinity(struct irq_data *d,
const struct cpumask *mask, bool force)
{
bfin_internal_mask_irq(d->irq);
bfin_internal_unmask_irq_affinity(d->irq, mask);
return 0;
}
#else
static void bfin_internal_unmask_irq_chip(struct irq_data *d)
{
bfin_internal_unmask_irq(d->irq);
}
#endif
#if defined(CONFIG_PM)
int bfin_internal_set_wake(unsigned int irq, unsigned int state)
{
u32 bank, bit, wakeup = 0;
unsigned long flags;
bank = BFIN_SYSIRQ(irq) / 32;
bit = BFIN_SYSIRQ(irq) % 32;
switch (irq) {
#ifdef IRQ_RTC
case IRQ_RTC:
wakeup |= WAKE;
break;
#endif
#ifdef IRQ_CAN0_RX
case IRQ_CAN0_RX:
wakeup |= CANWE;
break;
#endif
#ifdef IRQ_CAN1_RX
case IRQ_CAN1_RX:
wakeup |= CANWE;
break;
#endif
#ifdef IRQ_USB_INT0
case IRQ_USB_INT0:
wakeup |= USBWE;
break;
#endif
#ifdef CONFIG_BF54x
case IRQ_CNT:
wakeup |= ROTWE;
break;
#endif
default:
break;
}
flags = hard_local_irq_save();
if (state) {
bfin_sic_iwr[bank] |= (1 << bit);
vr_wakeup |= wakeup;
} else {
bfin_sic_iwr[bank] &= ~(1 << bit);
vr_wakeup &= ~wakeup;
}
hard_local_irq_restore(flags);
return 0;
}
static int bfin_internal_set_wake_chip(struct irq_data *d, unsigned int state)
{
return bfin_internal_set_wake(d->irq, state);
}
#else
inline int bfin_internal_set_wake(unsigned int irq, unsigned int state)
{
return 0;
}
# define bfin_internal_set_wake_chip NULL
#endif
#else /* SEC_GCTL */
static void bfin_sec_preflow_handler(struct irq_data *d)
{
unsigned long flags = hard_local_irq_save();
unsigned int sid = SIC_SYSIRQ(d->irq);
unsigned int sid = BFIN_SYSIRQ(d->irq);
bfin_write_SEC_SCI(0, SEC_CSID, sid);
@ -214,7 +292,7 @@ static void bfin_sec_preflow_handler(struct irq_data *d)
static void bfin_sec_mask_ack_irq(struct irq_data *d)
{
unsigned long flags = hard_local_irq_save();
unsigned int sid = SIC_SYSIRQ(d->irq);
unsigned int sid = BFIN_SYSIRQ(d->irq);
bfin_write_SEC_SCI(0, SEC_CSID, sid);
@ -224,7 +302,7 @@ static void bfin_sec_mask_ack_irq(struct irq_data *d)
static void bfin_sec_unmask_irq(struct irq_data *d)
{
unsigned long flags = hard_local_irq_save();
unsigned int sid = SIC_SYSIRQ(d->irq);
unsigned int sid = BFIN_SYSIRQ(d->irq);
bfin_write32(SEC_END, sid);
@ -269,7 +347,7 @@ static void bfin_sec_enable_sci(unsigned int sid)
unsigned long flags = hard_local_irq_save();
uint32_t reg_sctl = bfin_read_SEC_SCTL(sid);
if (sid == SIC_SYSIRQ(IRQ_WATCH0))
if (sid == BFIN_SYSIRQ(IRQ_WATCH0))
reg_sctl |= SEC_SCTL_FAULT_EN;
else
reg_sctl |= SEC_SCTL_INT_EN;
@ -292,7 +370,7 @@ static void bfin_sec_disable_sci(unsigned int sid)
static void bfin_sec_enable(struct irq_data *d)
{
unsigned long flags = hard_local_irq_save();
unsigned int sid = SIC_SYSIRQ(d->irq);
unsigned int sid = BFIN_SYSIRQ(d->irq);
bfin_sec_enable_sci(sid);
bfin_sec_enable_ssi(sid);
@ -303,7 +381,7 @@ static void bfin_sec_enable(struct irq_data *d)
static void bfin_sec_disable(struct irq_data *d)
{
unsigned long flags = hard_local_irq_save();
unsigned int sid = SIC_SYSIRQ(d->irq);
unsigned int sid = BFIN_SYSIRQ(d->irq);
bfin_sec_disable_sci(sid);
bfin_sec_disable_ssi(sid);
@ -328,9 +406,10 @@ static void bfin_sec_set_priority(unsigned int sec_int_levels, u8 *sec_int_prior
hard_local_irq_restore(flags);
}
void bfin_sec_raise_irq(unsigned int sid)
void bfin_sec_raise_irq(unsigned int irq)
{
unsigned long flags = hard_local_irq_save();
unsigned int sid = BFIN_SYSIRQ(irq);
bfin_write32(SEC_RAISE, sid);
@ -341,8 +420,13 @@ static void init_software_driven_irq(void)
{
bfin_sec_set_ssi_coreid(34, 0);
bfin_sec_set_ssi_coreid(35, 1);
bfin_sec_enable_sci(35);
bfin_sec_enable_ssi(35);
bfin_sec_set_ssi_coreid(36, 0);
bfin_sec_set_ssi_coreid(37, 1);
bfin_sec_enable_sci(37);
bfin_sec_enable_ssi(37);
}
void bfin_sec_resume(void)
@ -412,6 +496,8 @@ void handle_sec_fault(unsigned int irq, struct irq_desc *desc)
}
raw_spin_unlock(&desc->lock);
handle_fasteoi_irq(irq, desc);
}
void handle_core_fault(unsigned int irq, struct irq_desc *desc)
@ -431,105 +517,18 @@ void handle_core_fault(unsigned int irq, struct irq_desc *desc)
printk(KERN_NOTICE "Kernel Stack\n");
show_stack(current, NULL);
print_modules();
panic("Kernel core hardware error");
panic("Core 0 hardware error");
break;
case IRQ_C0_NMI_L1_PARITY_ERR:
panic("NMI occurs unexpectedly");
panic("Core 0 NMI L1 parity error");
break;
default:
panic("Core 1 fault occurs unexpectedly");
panic("Core 1 fault %d occurs unexpectedly", irq);
}
raw_spin_unlock(&desc->lock);
}
#endif
#ifdef CONFIG_SMP
static void bfin_internal_unmask_irq_chip(struct irq_data *d)
{
bfin_internal_unmask_irq_affinity(d->irq, d->affinity);
}
static int bfin_internal_set_affinity(struct irq_data *d,
const struct cpumask *mask, bool force)
{
bfin_internal_mask_irq(d->irq);
bfin_internal_unmask_irq_affinity(d->irq, mask);
return 0;
}
#else
static void bfin_internal_unmask_irq_chip(struct irq_data *d)
{
bfin_internal_unmask_irq(d->irq);
}
#endif
#if defined(CONFIG_PM) && !defined(SEC_GCTL)
int bfin_internal_set_wake(unsigned int irq, unsigned int state)
{
u32 bank, bit, wakeup = 0;
unsigned long flags;
bank = SIC_SYSIRQ(irq) / 32;
bit = SIC_SYSIRQ(irq) % 32;
switch (irq) {
#ifdef IRQ_RTC
case IRQ_RTC:
wakeup |= WAKE;
break;
#endif
#ifdef IRQ_CAN0_RX
case IRQ_CAN0_RX:
wakeup |= CANWE;
break;
#endif
#ifdef IRQ_CAN1_RX
case IRQ_CAN1_RX:
wakeup |= CANWE;
break;
#endif
#ifdef IRQ_USB_INT0
case IRQ_USB_INT0:
wakeup |= USBWE;
break;
#endif
#ifdef CONFIG_BF54x
case IRQ_CNT:
wakeup |= ROTWE;
break;
#endif
default:
break;
}
flags = hard_local_irq_save();
if (state) {
bfin_sic_iwr[bank] |= (1 << bit);
vr_wakeup |= wakeup;
} else {
bfin_sic_iwr[bank] &= ~(1 << bit);
vr_wakeup &= ~wakeup;
}
hard_local_irq_restore(flags);
return 0;
}
static int bfin_internal_set_wake_chip(struct irq_data *d, unsigned int state)
{
return bfin_internal_set_wake(d->irq, state);
}
#else
inline int bfin_internal_set_wake(unsigned int irq, unsigned int state)
{
return 0;
}
# define bfin_internal_set_wake_chip NULL
#endif
#endif /* SEC_GCTL */
static struct irq_chip bfin_core_irqchip = {
.name = "CORE",
@ -537,6 +536,7 @@ static struct irq_chip bfin_core_irqchip = {
.irq_unmask = bfin_core_unmask_irq,
};
#ifndef SEC_GCTL
static struct irq_chip bfin_internal_irqchip = {
.name = "INTN",
.irq_mask = bfin_internal_mask_irq_chip,
@ -548,8 +548,7 @@ static struct irq_chip bfin_internal_irqchip = {
#endif
.irq_set_wake = bfin_internal_set_wake_chip,
};
#ifdef SEC_GCTL
#else
static struct irq_chip bfin_sec_irqchip = {
.name = "SEC",
.irq_mask_ack = bfin_sec_mask_ack_irq,
@ -1138,7 +1137,9 @@ static int bfin_gpio_set_wake(struct irq_data *d, unsigned int state)
return -EINVAL;
}
#ifndef SEC_GCTL
bfin_internal_set_wake(pint_irq, state);
#endif
return 0;
}
@ -1173,7 +1174,7 @@ 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));
save_pint_sec_ctl[bank] = bfin_read_SEC_SCTL(bank + BFIN_SYSIRQ(IRQ_PINT0));
return 0;
}
@ -1187,7 +1188,7 @@ static void sec_resume(void)
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]);
bfin_write_SEC_SCTL(bank + BFIN_SYSIRQ(IRQ_PINT0), save_pint_sec_ctl[bank]);
}
static struct syscore_ops sec_pm_syscore_ops = {
@ -1538,33 +1539,26 @@ int __init init_arch_irq(void)
for (irq = 0; irq <= SYS_IRQS; irq++) {
if (irq <= IRQ_CORETMR) {
irq_set_chip(irq, &bfin_core_irqchip);
#ifdef CONFIG_TICKSOURCE_CORETMR
irq_set_chip_and_handler(irq, &bfin_core_irqchip,
handle_simple_irq);
#if defined(CONFIG_TICKSOURCE_CORETMR) && defined(CONFIG_SMP)
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);
handle_percpu_irq);
} else {
irq_set_chip(irq, &bfin_sec_irqchip);
if (irq == IRQ_SEC_ERR)
irq_set_handler(irq, handle_sec_fault);
else if (irq >= IRQ_C0_DBL_FAULT && irq < CORE_IRQS)
irq_set_handler(irq, handle_core_fault);
else
irq_set_handler(irq, handle_fasteoi_irq);
__irq_set_preflow_handler(irq, bfin_sec_preflow_handler);
}
}
@ -1593,8 +1587,8 @@ int __init init_arch_irq(void)
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_sec_enable_sci(BFIN_SYSIRQ(IRQ_WATCH0));
bfin_sec_enable_ssi(BFIN_SYSIRQ(IRQ_WATCH0));
bfin_write_SEC_SCI(0, SEC_CCTL, SEC_CCTL_RESET);
udelay(100);
bfin_write_SEC_GCTL(SEC_GCTL_EN);