Ejemplo n.º 1
0
static irqreturn_t cp_idpram_irq_handler(int irq, void *data)
{
	struct dpram_link_device *dpld = (struct dpram_link_device *)data;
	struct link_device *ld = (struct link_device *)&dpld->ld;
	u16 int2ap;

	if (unlikely(ld->mode == LINK_MODE_OFFLINE))
		return IRQ_HANDLED;

	if (dpram_wake_up(dpld) < 0) {
		log_dpram_status(dpld);
		trigger_force_cp_crash(dpld);
		return IRQ_HANDLED;
	}

	int2ap = recv_intr(dpld);

	dpram_intr_handler(dpld, int2ap);

	clear_intr(dpld);

	dpram_allow_sleep(dpld);

	return IRQ_HANDLED;
}
Ejemplo n.º 2
0
static void dpram_reset_rx_circ(struct dpram_link_device *dpld, int dev)
{
	set_rx_head(dpld, dev, 0);
	set_rx_tail(dpld, dev, 0);
	if (dev == IPC_FMT)
		trigger_force_cp_crash(dpld);
}
Ejemplo n.º 3
0
static irqreturn_t dpram_irq_handler(int irq, void *data)
{
	struct dpram_link_device *dpld = (struct dpram_link_device *)data;
	struct link_device *ld = (struct link_device *)&dpld->ld;
	u16 int2ap = 0;

	if (unlikely(ld->mode == LINK_MODE_OFFLINE))
		return IRQ_HANDLED;

	if (dpram_wake_up(dpld) < 0) {
		log_dpram_status(dpld);
		trigger_force_cp_crash(dpld);
		return IRQ_HANDLED;
	}

	int2ap = recv_intr(dpld);

	if (unlikely(int2ap == INT_POWERSAFE_FAIL)) {
		mif_info("%s: int2ap == INT_POWERSAFE_FAIL\n", ld->name);
		goto exit;
	} else if (int2ap == 0x1234 || int2ap == 0xDBAB || int2ap == 0xABCD) {
		if (dpld->ext_op && dpld->ext_op->dload_cmd_handler) {
			dpld->ext_op->dload_cmd_handler(dpld, int2ap);
			goto exit;
		}
	}

	if (unlikely(EXT_UDL_CMD(int2ap))) {
		if (likely(EXT_INT_VALID(int2ap))) {
			if (UDL_CMD_VALID(int2ap))
				udl_command_handler(dpld, int2ap);
			else if (EXT_CMD_VALID(int2ap))
				ext_command_handler(dpld, int2ap);
			else
				mif_info("%s: ERR! invalid intr 0x%04X\n",
					ld->name, int2ap);
		} else {
			mif_info("%s: ERR! invalid intr 0x%04X\n",
				ld->name, int2ap);
		}
	} else {
		if (likely(INT_VALID(int2ap))) {
			if (unlikely(INT_CMD_VALID(int2ap)))
				command_handler(dpld, int2ap);
			else
				non_command_handler(dpld, int2ap);
		} else {
			mif_info("%s: ERR! invalid intr 0x%04X\n",
				ld->name, int2ap);
		}
	}

exit:
	clear_intr(dpld);
	dpram_allow_sleep(dpld);
	return IRQ_HANDLED;
}
Ejemplo n.º 4
0
static void dpram_send_ipc(struct link_device *ld, int dev,
			struct io_device *iod, struct sk_buff *skb)
{
	struct dpram_link_device *dpld = to_dpram_link_device(ld);
	struct sk_buff_head *txq = ld->skb_txq[dev];
	int ret;
	u16 mask;

	skb_queue_tail(txq, skb);
	if (txq->qlen > 1024) {
		mif_debug("%s: %s txq->qlen %d > 1024\n",
			ld->name, get_dev_name(dev), txq->qlen);
	}

	if (dpld->dp_type == CP_IDPRAM) {
		if (dpram_wake_up(dpld) < 0) {
			trigger_force_cp_crash(dpld);
			return;
		}
	}

	if (!dpram_ipc_active(dpld))
		goto exit;

	if (atomic_read(&dpld->res_required[dev]) > 0) {
		mif_debug("%s: %s_TXQ is full\n", ld->name, get_dev_name(dev));
		goto exit;
	}

	ret = dpram_try_ipc_tx(dpld, dev);
	if (ret > 0) {
		mask = get_mask_send(dpld, dev);
		send_intr(dpld, INT_NON_CMD(mask));
	} else if (ret == -ENOSPC) {
		mask = get_mask_req_ack(dpld, dev);
		send_intr(dpld, INT_NON_CMD(mask));
		mif_info("%s: Send REQ_ACK 0x%04X\n", ld->name, mask);
	} else {
		mif_info("%s: dpram_try_ipc_tx fail (err %d)\n", ld->name, ret);
	}

exit:
	if (dpld->dp_type == CP_IDPRAM)
		dpram_allow_sleep(dpld);
}
Ejemplo n.º 5
0
static void dpram_ipc_write(struct dpram_link_device *dpld, int dev,
		u32 qsize, u32 in, u32 out, struct sk_buff *skb)
{
	struct link_device *ld = &dpld->ld;
	u8 __iomem *buff = get_tx_buff(dpld, dev);
	u8 *src = skb->data;
	u32 len = skb->len;
	u32 inp;
	struct mif_irq_map map;

	if (in < out) {
		/* +++++++++ in ---------- out ++++++++++ */
		memcpy((buff + in), src, len);
	} else {
		/* ------ out +++++++++++ in ------------ */
		u32 space = qsize - in;

		/* 1) in -> buffer end */
		memcpy((buff + in), src, ((len > space) ? space : len));

		/* 2) buffer start -> out */
		if (len > space)
			memcpy(buff, (src + space), (len - space));
	}

	/* update new in pointer */
	inp = in + len;
	if (inp >= qsize)
		inp -= qsize;
	set_tx_head(dpld, dev, inp);

	if (dev == IPC_FMT) {
		set_dpram_map(dpld, &map);
		mif_irq_log(ld->mc->msd, map, "ipc_write", sizeof("ipc_write"));
		mif_ipc_log(MIF_IPC_AP2CP, ld->mc->msd, skb->data, skb->len);
	}

	if (ld->aligned && memcmp16_to_io((buff + in), src, 4)) {
		mif_err("%s: memcmp16_to_io fail\n", ld->name);
		trigger_force_cp_crash(dpld);
	}
}
Ejemplo n.º 6
0
static inline void set_rx_tail(struct dpram_link_device *dpld, int id, u32 out)
{
	int cnt = 3;
	u32 val = 0;

	iowrite16((u16)out, dpld->dev[id]->rxq.tail);

	do {
		/* Check tail value written */
		val = ioread16(dpld->dev[id]->rxq.tail);
		if (val == out)
			return;

		mif_err("ERR: %s rxq.tail(%d) != out(%d)\n",
			get_dev_name(id), val, out);
		udelay(100);

		/* Write tail value again */
		iowrite16((u16)out, dpld->dev[id]->rxq.tail);
	} while (cnt--);

	trigger_force_cp_crash(dpld);
}
Ejemplo n.º 7
0
static inline void set_rx_head(struct dpram_link_device *dpld, int id, u32 in)
{
	int cnt = 3;
	u32 val = 0;

	iowrite16((u16)in, dpld->dev[id]->rxq.head);

	do {
		/* Check head value written */
		val = ioread16(dpld->dev[id]->rxq.head);
		if (val == in)
			return;

		mif_err("ERR: %s rxq.head(%d) != in(%d)\n",
			get_dev_name(id), val, in);
		udelay(100);

		/* Write head value again */
		iowrite16((u16)in, dpld->dev[id]->rxq.head);
	} while (cnt--);

	trigger_force_cp_crash(dpld);
}
Ejemplo n.º 8
0
static int dpram_force_dump(struct link_device *ld, struct io_device *iod)
{
	struct dpram_link_device *dpld = to_dpram_link_device(ld);
	trigger_force_cp_crash(dpld);
	return 0;
}