Ejemplo n.º 1
0
static int dw_dma_transfer_stop(struct device *dev, u32_t channel)
{
	const struct dw_dma_dev_cfg *const dev_cfg = DEV_CFG(dev);

	if (channel >= DW_MAX_CHAN) {
		return -EINVAL;
	}

	/* mask block, transfer and error interrupts for channel */
	dw_write(dev_cfg->base, DW_MASK_TFR, INT_MASK(channel));
	dw_write(dev_cfg->base, DW_MASK_BLOCK, INT_MASK(channel));
	dw_write(dev_cfg->base, DW_MASK_ERR, INT_MASK(channel));

	/* disable the channel */
	dw_write(dev_cfg->base, DW_DMA_CHAN_EN, CHAN_DISABLE(channel));
	return 0;
}
Ejemplo n.º 2
0
/* Return a pt_regs pointer for a valid fault handler frame */
static struct pt_regs *valid_fault_handler(struct KBacktraceIterator* kbt)
{
	const char *fault = NULL;  /* happy compiler */
	char fault_buf[64];
	unsigned long sp = kbt->it.sp;
	struct pt_regs *p;

	if (!in_kernel_stack(kbt, sp))
		return NULL;
	if (!in_kernel_stack(kbt, sp + C_ABI_SAVE_AREA_SIZE + PTREGS_SIZE-1))
		return NULL;
	p = (struct pt_regs *)(sp + C_ABI_SAVE_AREA_SIZE);
	if (p->faultnum == INT_SWINT_1 || p->faultnum == INT_SWINT_1_SIGRETURN)
		fault = "syscall";
	else {
		if (kbt->verbose) {     /* else we aren't going to use it */
			snprintf(fault_buf, sizeof(fault_buf),
				 "interrupt %ld", p->faultnum);
			fault = fault_buf;
		}
	}
	if (EX1_PL(p->ex1) == KERNEL_PL &&
	    __kernel_text_address(p->pc) &&
	    in_kernel_stack(kbt, p->sp) &&
	    p->sp >= sp) {
		if (kbt->verbose)
			pr_err("  <%s while in kernel mode>\n", fault);
	} else if (EX1_PL(p->ex1) == USER_PL &&
	    p->pc < PAGE_OFFSET &&
	    p->sp < PAGE_OFFSET) {
		if (kbt->verbose)
			pr_err("  <%s while in user mode>\n", fault);
	} else if (kbt->verbose) {
		pr_err("  (odd fault: pc %#lx, sp %#lx, ex1 %#lx?)\n",
		       p->pc, p->sp, p->ex1);
		p = NULL;
	}
	if (!kbt->profile || (INT_MASK(p->faultnum) & QUEUED_INTERRUPTS) == 0)
		return p;
	return NULL;
}