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

Commit 1b601239 authored by Sonic Zhang's avatar Sonic Zhang Committed by Steven Miao
Browse files

blackfin: Support L1 SRAM parity checking feature on bf60x



Move code for the SEC faults from the IRQ hanlders into IRQ actions.
refine bfin fault routine handle

Signed-off-by: default avatarSonic Zhang <sonic.zhang@analog.com>
Signed-off-by: default avatarSteven Miao <realmz6@gmail.com>
parent cccdfcf7
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -544,6 +544,7 @@ do { \
#define DCBS_P			0x04	/* L1 Data Cache Bank Select */
#define PORT_PREF0_P		0x12	/* DAG0 Port Preference */
#define PORT_PREF1_P		0x13	/* DAG1 Port Preference */
#define RDCHK			0x9	/* Enable L1 Parity Check */

/* Masks */
#define ENDM               0x00000001	/* (doesn't really exist) Enable
+6 −0
Original line number Diff line number Diff line
@@ -17,6 +17,12 @@ config SEC_IRQ_PRIORITY_LEVELS
	  Divide the total number of interrupt priority levels into sub-levels.
	  There is 2 ^ (SEC_IRQ_PRIORITY_LEVELS + 1) different levels.

config L1_PARITY_CHECK
	bool "Enable L1 parity check"
	default n
	help
	  Enable the L1 parity check in L1 sram. A fault event is raised
	  when L1 parity error is found.

comment "System Cross Bar Priority Assignment"

+10 −0
Original line number Diff line number Diff line
@@ -41,6 +41,16 @@ bfin_cache_init(struct cplb_entry *cplb_tbl, unsigned long cplb_addr,
                unsigned long mem_mask)
{
	int i;
#ifdef CONFIG_L1_PARITY_CHECK
	u32 ctrl;

	if (cplb_addr == DCPLB_ADDR0) {
		ctrl = bfin_read32(mem_control) | (1 << RDCHK);
		CSYNC();
		bfin_write32(mem_control, ctrl);
		SSYNC();
	}
#endif

	for (i = 0; i < MAX_CPLBS; i++) {
		bfin_write32(cplb_addr + i * 4, cplb_tbl[i].addr);
+20 −21
Original line number Diff line number Diff line
@@ -471,13 +471,8 @@ void handle_sec_ssi_fault(uint32_t gstat)

}

void handle_sec_fault(unsigned int irq, struct irq_desc *desc)
void handle_sec_fault(uint32_t sec_gstat)
{
	uint32_t sec_gstat;

	raw_spin_lock(&desc->lock);

	sec_gstat = bfin_read32(SEC_GSTAT);
	if (sec_gstat & SEC_GSTAT_ERR) {

		switch (sec_gstat & SEC_GSTAT_ERRC) {
@@ -494,18 +489,16 @@ 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)
static struct irqaction bfin_fault_irq = {
	.name = "Blackfin fault",
};

static irqreturn_t bfin_fault_routine(int irq, void *data)
{
	struct pt_regs *fp = get_irq_regs();

	raw_spin_lock(&desc->lock);

	switch (irq) {
	case IRQ_C0_DBL_FAULT:
		double_fault_c(fp);
@@ -522,11 +515,15 @@ void handle_core_fault(unsigned int irq, struct irq_desc *desc)
	case IRQ_C0_NMI_L1_PARITY_ERR:
		panic("Core 0 NMI L1 parity error");
		break;
	case IRQ_SEC_ERR:
		pr_err("SEC error\n");
		handle_sec_fault(bfin_read32(SEC_GSTAT));
		break;
	default:
		panic("Core 1 fault %d occurs unexpectedly", irq);
		panic("Unknown fault %d", irq);
	}

	raw_spin_unlock(&desc->lock);
	return IRQ_HANDLED;
}
#endif /* SEC_GCTL */

@@ -1195,11 +1192,6 @@ int __init init_arch_irq(void)
				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);
		}
@@ -1239,6 +1231,13 @@ int __init init_arch_irq(void)
	register_syscore_ops(&sec_pm_syscore_ops);
#endif

	bfin_fault_irq.handler = bfin_fault_routine;
#ifdef CONFIG_L1_PARITY_CHECK
	setup_irq(IRQ_C0_NMI_L1_PARITY_ERR, &bfin_fault_irq);
#endif
	setup_irq(IRQ_C0_DBL_FAULT, &bfin_fault_irq);
	setup_irq(IRQ_SEC_ERR, &bfin_fault_irq);

	return 0;
}