コード例 #1
0
int mif_dump_dpram(struct io_device *iod)
{
	struct link_device *ld = get_current_link(iod);
	struct dpram_link_device *dpld = to_dpram_link_device(ld);
	u32 size = dpld->size;
	unsigned long read_len = 0;
	struct sk_buff *skb;
	char *buff;

	buff = kzalloc(size, GFP_ATOMIC);
	if (!buff) {
		mif_err("ERR! kzalloc fail\n");
		return -ENOMEM;
	} else {
		dpld->dpram_dump(ld, buff);
	}

	while (read_len < size) {
		skb = alloc_skb(MAX_IPC_SKB_SIZE, GFP_ATOMIC);
		if (!skb) {
			mif_err("ERR! alloc_skb fail\n");
			kfree(buff);
			return -ENOMEM;
		}
		memcpy(skb_put(skb, MAX_IPC_SKB_SIZE),
			buff + read_len, MAX_IPC_SKB_SIZE);
		skb_queue_tail(&iod->sk_rx_q, skb);
		read_len += MAX_IPC_SKB_SIZE;
		wake_up(&iod->wq);
	}
	kfree(buff);
	return 0;
}
コード例 #2
0
static int dpram_ioctl(struct link_device *ld, struct io_device *iod,
		unsigned int cmd, unsigned long arg)
{
	struct dpram_link_device *dpld = to_dpram_link_device(ld);
	int err = 0;

	mif_info("%s: cmd 0x%08X\n", ld->name, cmd);

	switch (cmd) {
	case IOCTL_DPRAM_INIT_STATUS:
		mif_debug("%s: get dpram init status\n", ld->name);
		return dpld->dpram_init_status;

	default:
		if (dpld->ext_ioctl) {
			err = dpld->ext_ioctl(dpld, iod, cmd, arg);
		} else {
			mif_err("%s: ERR! invalid cmd 0x%08X\n", ld->name, cmd);
			err = -EINVAL;
		}

		break;
	}

	return err;
}
void dpram_force_cp_crash(struct link_device *ld)
{
	int ret;
	struct dpram_link_device *dpld = to_dpram_link_device(ld);

	pr_info("MIF: <%s+>", __func__);

	/*
	1. set the magic number to 0x554C
	2. send mbx cmd 0x000F
	3. wait for completon
	4. CP responds with cmd = 0xCF
	5. call panic("CP Crashed");
	*/
	dpram_write_magic_code(dpld, 0x554C);

	dpram_write_command(dpld, INT_CMD(0x000F));

	init_completion(&dpld->cp_crash_done);
	ret = wait_for_completion_interruptible_timeout(
		&dpld->cp_crash_done, 20 * HZ);
	if (!ret) {
		pr_err("MIF: CP didn't ack MBX_CMD_PHONE_RESET\n");
		dpram_write_magic_code(dpld, DP_MAGIC_CODE);
	}

	pr_info("MIF: <%s->", __func__);
}
static int qsc6085_on(struct modem_ctl *mc)
{
	struct dpram_link_device *dpld = to_dpram_link_device(mc->iod->link);

	pr_info("MIF : <%s> start!!!\n", __func__);

	if (!mc->gpio_cp_on || !mc->gpio_cp_reset) {
		pr_err("[MODEM_IF] no gpio data\n");
		return -ENXIO;
	}

	dpld->init_magic_num(dpld);

	mc->iod->modem_state_changed(mc->iod, STATE_BOOTING);

	gpio_set_value(mc->gpio_cp_reset, 1);
	gpio_set_value(mc->gpio_cp_on, 0);

	msleep(100);

	gpio_set_value(mc->gpio_cp_on, 1);

	msleep(400);
	msleep(400);
	msleep(200);

	gpio_set_value(mc->gpio_cp_on, 0);

	return 0;
}
コード例 #5
0
static int qsc6085_on(struct modem_ctl *mc)
{
	struct dpram_link_device *dpld = to_dpram_link_device(mc->iod->link);

	pr_info("MIF: <%s+>\n", __func__);

	if (!mc->gpio_cp_on || !mc->gpio_cp_reset) {
		pr_err("MIF: no gpio data\n");
		return -ENXIO;
	}

	dpld->init_magic_num(dpld);

	mc->iod->modem_state_changed(mc->iod, STATE_BOOTING);

	gpio_set_value(mc->gpio_cp_reset, 1);
	gpio_set_value(mc->gpio_cp_on, 0);

	msleep(100);

	gpio_set_value(mc->gpio_cp_on, 1);

	msleep(400);
	msleep(400);
	msleep(200);

	gpio_set_value(mc->gpio_cp_on, 0);

	mc->ramdump_active = false;
	mc->power_off_in_progress = false;

	pr_info("MIF: <%s->\n", __func__);
	return 0;
}
static int cbp72_boot_off(struct modem_ctl *mc)
{
	int ret;
	struct link_device *ld = get_current_link(mc->bootd);
	struct dpram_link_device *dpld = to_dpram_link_device(ld);
	mif_debug("\n");
	/* Wait here until the PHONE is up.
	 * Waiting as the this called from IOCTL->UM thread */
	mif_info("Waiting for INT_CMD_PHONE_START\n");
	ret = wait_for_completion_interruptible_timeout(
			&dpld->dpram_init_cmd, DPRAM_INIT_TIMEOUT);
	if (!ret) {
		/* ret == 0 on timeout, ret < 0 if interrupted */
		mif_err("Timeout!!! (PHONE_START was not arrived.)\n");
		return -ENXIO;
	}

	mif_info("Waiting for INT_CMD_PIF_INIT_DONE\n");
	ret = wait_for_completion_interruptible_timeout(
			&dpld->modem_pif_init_done, PIF_TIMEOUT);
	if (!ret) {
		mif_err("Timeout!!! (PIF_INIT_DONE was not arrived.)\n");
		return -ENXIO;
	}
	mc->bootd->modem_state_changed(mc->bootd, STATE_ONLINE);

	wake_unlock(&mc->mc_wake_lock);

	return 0;
}
static int sprd6500_on(struct modem_ctl *mc)
{
	int ret;
	struct dpram_link_device *dpram_ld =
		to_dpram_link_device(get_current_link(mc->iod));

	pr_info("[MODEM_IF:ESC] <%s> start!!!\n", __func__);

	if (!mc->gpio_cp_reset) {
		pr_err("[MODEM_IF:ESC] no gpio data\n");
		return -ENXIO;
	}

	if (mc->gpio_reset_req_n)
		gpio_set_value(mc->gpio_reset_req_n, 1);

	gpio_set_value(mc->gpio_cp_reset, 1);
	msleep(30);

	gpio_set_value(mc->gpio_cp_on, 1);
	msleep(500);

	gpio_set_value(GPIO_FPGA_SPI_MOSI, 1);
	gpio_set_value(mc->gpio_fpga1_cs_n, 1);
	gpio_set_value(mc->gpio_pda_active, 1);

	dpram_ld->dpram_init_status = DPRAM_INIT_STATE_READY;
	dpram_ld->cmd_phone_start_handler(dpram_ld);
	complete_all(&dpram_ld->dpram_init_cmd);

	mc->iod->modem_state_changed(mc->iod, STATE_BOOTING);
	return 0;
}
コード例 #8
0
static int cbp71_on(struct modem_ctl *mc)
{

	int ret;

	struct dpram_link_device *dpram_ld =
				to_dpram_link_device(mc->iod->link);

	pr_err("MIF : cbp71_on()\n");

	if (!mc->gpio_cp_off || !mc->gpio_cp_reset || !mc->gpio_cp_on) {
		pr_err("MIF : <%s>no gpio data\n", __func__);
		return -ENXIO;
	}
	gpio_set_value(mc->gpio_cp_on, 1);
	mdelay(10);
	gpio_set_value(mc->gpio_cp_reset, GPIO_LEVEL_LOW);
	gpio_set_value(mc->gpio_cp_off, GPIO_LEVEL_LOW);
	mdelay(600);
	gpio_set_value(mc->gpio_cp_reset, GPIO_LEVEL_HIGH);
	gpio_set_value(mc->gpio_cp_on, GPIO_LEVEL_HIGH);


	mc->iod->modem_state_changed(mc->iod, STATE_BOOTING);

	/* Wait here until the PHONE is up.
	* Waiting as the this called from IOCTL->UM thread */
	pr_debug("MIF : power control waiting for INT_MASK_CMD_PIF_INIT_DONE\n");

	mc->clear_intr();

	msleep(100);

	gpio_set_value(mc->gpio_pda_active, 1);
	printk(KERN_INFO "MIF : PDA_ACTIVE sets high.\n");

	ret = wait_for_completion_interruptible_timeout(
			&dpram_ld->dpram_init_cmd, DPRAM_INIT_TIMEOUT);
	if (!ret) {
		/* ret will be 0 on timeout, < zero if interrupted */
		pr_warn("MIF : INIT_START cmd was not arrived.\n");
		pr_warn("init_cmd_wait_condition is 0 and wait timeout happend\n");
		return -ENXIO;
	}

	ret = wait_for_completion_interruptible_timeout(
			&dpram_ld->modem_pif_init_done, PIF_TIMEOUT);
	if (!ret) {
		pr_warn("MIF : PIF init failed\n");
		pr_warn("pif_init_wait_condition is 0 and wait timeout happend\n");
		return -ENXIO;
	}

	pr_debug("MIF : complete cbp71_on\n");

	mc->iod->modem_state_changed(mc->iod, STATE_ONLINE);

	return 0;
}
static irqreturn_t phone_active_irq_handler(int irq, void *arg)
{
	struct modem_ctl *mc = (struct modem_ctl *)arg;
	int phone_reset = 0;
	int phone_active = 0;
	int phone_state = 0;
	int cp_dump_int = 0;

	if (!mc->gpio_cp_reset ||
		!mc->gpio_phone_active) { /* || !mc->gpio_cp_dump_int) { */
		pr_err("[MODEM_IF:ESC] no gpio data\n");
		return IRQ_HANDLED;
	}

	phone_reset = gpio_get_value(mc->gpio_cp_reset);
	phone_active = gpio_get_value(mc->gpio_phone_active);
	cp_dump_int = gpio_get_value(mc->gpio_cp_dump_int);

	phone_reset = 1; // actually, we don't use "reset pin"

	pr_info("[MODEM_IF:ESC] <%s> phone_reset=%d, phone_active=%d, cp_dump_int=%d\n",
		__func__, phone_reset, phone_active, cp_dump_int);

	if (phone_reset && phone_active) {
		phone_state = STATE_ONLINE;
		if (mc->iod && mc->iod->modem_state_changed)	{
			struct dpram_link_device *dpram_ld =
				to_dpram_link_device(get_current_link(mc->iod));

			mc->iod->modem_state_changed(mc->iod, phone_state);
		
			/* Do after PHONE_ACTIVE High */
			dpram_ld->dpram_init_status = DPRAM_INIT_STATE_READY;
			dpram_ld->cmd_phone_start_handler(dpram_ld);
			complete_all(&dpram_ld->dpram_init_cmd);
		}
	} else if (phone_reset && !phone_active) {
		if (mc->phone_state == STATE_ONLINE) {
			phone_state = STATE_CRASH_EXIT;
			if (mc->iod && mc->iod->modem_state_changed)
				mc->iod->modem_state_changed(mc->iod,
							     phone_state);
		}
	} else {
		phone_state = STATE_OFFLINE;
		if (mc->iod && mc->iod->modem_state_changed)
			mc->iod->modem_state_changed(mc->iod, phone_state);
	}

	if (phone_active)
		irq_set_irq_type(mc->irq_phone_active, IRQ_TYPE_LEVEL_LOW);
	else
		irq_set_irq_type(mc->irq_phone_active, IRQ_TYPE_LEVEL_HIGH);

	pr_info("[MODEM_IF:ESC] <%s> phone_state = %d\n",
			__func__, phone_state);

	return IRQ_HANDLED;
}
コード例 #10
0
static int cbp71_on(struct modem_ctl *mc)
{
	int RetVal = 0;
	int dpram_init_RetVal = 0;
	struct link_device *ld = get_current_link(mc->iod);
	struct dpram_link_device *dpram_ld = to_dpram_link_device(ld);

	mif_info("cbp71_on()\n");

	if (!mc->gpio_cp_off || !mc->gpio_cp_reset) {
		mif_err("no gpio data\n");
		return -ENXIO;
	}
	gpio_set_value(mc->gpio_cp_reset, 0);
	gpio_set_value(mc->gpio_cp_on, 1);
	mdelay(300);
	gpio_set_value(mc->gpio_cp_off, 1);
	mdelay(300);
	gpio_set_value(mc->gpio_cp_on, 0);
	gpio_set_value(mc->gpio_cp_reset, 1);
	gpio_set_value(mc->gpio_pda_active, 1);

	mc->iod->modem_state_changed(mc->iod, STATE_BOOTING);

	/* Wait here until the PHONE is up.
	* Waiting as the this called from IOCTL->UM thread */
	mif_debug("power control waiting for INT_MASK_CMD_PIF_INIT_DONE\n");

	/* 1HZ = 1 clock tick, 100 default */
	dpram_ld->dpctl->clear_intr();

	dpram_init_RetVal =
		wait_for_completion_interruptible_timeout(
			&dpram_ld->dpram_init_cmd, DPRAM_INIT_TIMEOUT);

	if (!dpram_init_RetVal) {
		/*RetVal will be 0 on timeout, non zero if interrupted */
		mif_err("INIT_START cmd was not arrived.\n");
		mif_err("init_cmd_wait_condition is 0 and wait timeout happend\n");
		return -ENXIO;
	}

	RetVal = wait_for_completion_interruptible_timeout(
			&dpram_ld->modem_pif_init_done, PIF_TIMEOUT);

	if (!RetVal) {
		/*RetVal will be 0 on timeout, non zero if interrupted */
		mif_err("PIF init failed\n");
		mif_err("pif_init_wait_condition is 0 and wait timeout happend\n");
		return -ENXIO;
	}

	mif_debug("complete cbp71_on\n");

	mc->iod->modem_state_changed(mc->iod, STATE_ONLINE);

	return 0;
}
コード例 #11
0
static int dpram_dump_start(struct link_device *ld, struct io_device *iod)
{
	struct dpram_link_device *dpld = to_dpram_link_device(ld);

	if (dpld->ext_op && dpld->ext_op->dump_start)
		return dpld->ext_op->dump_start(dpld);
	else
		return -ENODEV;
}
コード例 #12
0
static void dpram_dump_memory(struct link_device *ld, char *buff)
{
	struct dpram_link_device *dpld = to_dpram_link_device(ld);
	u8 __iomem *base = dpld->dpctl->dp_base;
	u32 size = dpld->dpctl->dp_size;

	dpram_wake_up(dpld);
	memcpy(buff, base, size);
}
コード例 #13
0
static int dpram_send_binary(struct link_device *ld, struct sk_buff *skb)
{
	struct dpram_link_device *dpld = to_dpram_link_device(ld);

	if (dpld->ext_op && dpld->ext_op->download_skb)
		return dpld->ext_op->download_skb(dpld, skb);
	else
		return -ENODEV;
}
コード例 #14
0
static int cbp71_on(struct modem_ctl *mc)
{
	int RetVal = 0;
	int dpram_init_RetVal = 0;
	struct dpram_link_device *dpram_ld =
				to_dpram_link_device(mc->iod->link);

	pr_info("[MODEM_IF] cbp71_on()\n");

	if (!mc->gpio_cp_reset) {
		pr_err("[MODEM_IF] no gpio data\n");
		return -ENXIO;
	}
	gpio_set_value(mc->gpio_cp_reset, 0);
	msleep(600);
	gpio_set_value(mc->gpio_cp_reset, 1);

	gpio_set_value(mc->gpio_pda_active, 1);

	/* Wait here until the PHONE is up.
	* Waiting as the this called from IOCTL->UM thread */
	pr_debug("[MODEM_IF] power control waiting for INT_MASK_CMD_PIF_INIT_DONE\n");

	/* 1HZ = 1 clock tick, 100 default */
	dpram_ld->clear_interrupt(dpram_ld);

	dpram_init_RetVal =
		wait_event_interruptible_timeout(
		dpram_ld->dpram_init_cmd_wait_q,
					dpram_ld->dpram_init_cmd_wait_condition,
					DPRAM_INIT_TIMEOUT);

	if (!dpram_init_RetVal) {
		/*RetVal will be 0 on timeout, non zero if interrupted */
		pr_warn("[MODEM_IF] INIT_START cmd was not arrived.\n");
		pr_warn("init_cmd_wait_condition is 0 and wait timeout happend\n");
		return -ENXIO;
	}

	RetVal =
		wait_event_interruptible_timeout(
		dpram_ld->modem_pif_init_done_wait_q,
					dpram_ld->modem_pif_init_wait_condition,
					PIF_TIMEOUT);

	if (!RetVal) {
		/*RetVal will be 0 on timeout, non zero if interrupted */
		pr_warn("[MODEM_IF] PIF init failed\n");
		pr_warn("pif_init_wait_condition is 0 and wait timeout happend\n");
		return -ENXIO;
	}

	pr_debug("[MODEM_IF] complete cbp71_on\n");
	mc->phone_state = STATE_BOOTING;

	return 0;
}
コード例 #15
0
static int dpram_dump_update(struct link_device *ld, struct io_device *iod,
		unsigned long arg)
{
	struct dpram_link_device *dpld = to_dpram_link_device(ld);

	if (dpld->ext_op && dpld->ext_op->dump_update)
		return dpld->ext_op->dump_update(dpld, (void *)arg);
	else
		return -ENODEV;
}
コード例 #16
0
static int cbp72_set_dl_magic(struct link_device *ld, struct io_device *iod)
{
	struct dpram_link_device *dpld = to_dpram_link_device(ld);

	ld->mode = LINK_MODE_DLOAD;

	iowrite32(DP_MAGIC_DMDL, dpld->dl_map.magic);

	return 0;
}
コード例 #17
0
int esc6270_boot_on(struct modem_ctl *mc)
{
	struct link_device *ld = get_current_link(mc->iod);
#if defined(CONFIG_LINK_DEVICE_DPRAM)
	/* clear intr */
	struct dpram_link_device *dpld = to_dpram_link_device(ld);
	u16 recv_msg = dpld->recv_intr(dpld);

	pr_info("[MODEM_IF:ESC] dpram intr: %x\n", recv_msg);
#endif

	pr_info("[MODEM_IF:ESC] <%s>\n", __func__);

	/* Need to init uart byt gpio_flm_uart_sel GPIO */
	if (!mc->gpio_cp_reset || !mc->gpio_flm_uart_sel) {
		pr_err("[MODEM_IF:ESC] no gpio data\n");
		return -ENXIO;
	}
	gpio_set_value(mc->gpio_flm_uart_sel, 1);

	pr_info("  - ESC_PHONE_ON : %d, ESC_RESET_N : %d\n",
			gpio_get_value(mc->gpio_cp_on),
			gpio_get_value(mc->gpio_cp_reset));

	gpio_set_value(mc->gpio_cp_on, 0);
	gpio_direction_output(mc->gpio_cp_reset, 0);
	msleep(100);

	gpio_direction_output(mc->gpio_cp_on, 1);
	msleep(44);

	pr_info("  - ESC_PHONE_ON : %d, ESC_RESET_N : %d\n",
			gpio_get_value(mc->gpio_cp_on),
			gpio_get_value(mc->gpio_cp_reset));

	gpio_direction_input(mc->gpio_cp_reset);
	msleep(600);
	gpio_direction_output(mc->gpio_cp_on, 0);

	msleep(20);
	pr_info("  - ESC_PHONE_ON : %d, ESC_RESET_N : %d\n",
			gpio_get_value(mc->gpio_cp_on),
			gpio_get_value(mc->gpio_cp_reset));

#if defined(CONFIG_LINK_DEVICE_PLD)
	gpio_direction_output(mc->gpio_fpga_cs_n, 1);
#endif

	mc->iod->modem_state_changed(mc->iod, STATE_BOOTING);
	ld->mode = LINK_MODE_BOOT;

	return 0;
}
static int cbp71_on(struct modem_ctl *mc)
{
	int ret;
	struct dpram_link_device *dpram_ld =
				to_dpram_link_device(mc->iod->link);

	pr_info("[MODEM_IF] cbp71_on()\n");

	if (!mc->gpio_cp_off || !mc->gpio_cp_reset) {
		pr_err("[MODEM_IF] no gpio data\n");
		return -ENXIO;
	}
	gpio_set_value(mc->gpio_cp_reset, 0);
	gpio_set_value(mc->gpio_cp_off, 1);
	msleep(600);
	gpio_set_value(mc->gpio_cp_reset, 1);
	gpio_set_value(mc->gpio_cp_off, 0);

	msleep(300);
	gpio_set_value(mc->gpio_pda_active, 1);

	mc->iod->modem_state_changed(mc->iod, STATE_BOOTING);

	/* Wait here until the PHONE is up.
	* Waiting as the this called from IOCTL->UM thread */
	pr_debug("[MODEM_IF] power control waiting for INT_MASK_CMD_PIF_INIT_DONE\n");

	dpram_ld->clear_interrupt(dpram_ld);

	ret = wait_for_completion_interruptible_timeout(
			&dpram_ld->dpram_init_cmd, DPRAM_INIT_TIMEOUT);
	if (!ret) {
		/* ret will be 0 on timeout, < zero if interrupted */
		pr_warn("[MODEM_IF] INIT_START cmd was not arrived.\n");
		pr_warn("init_cmd_wait_condition is 0 and wait timeout happend\n");
		return -ENXIO;
	}

	ret = wait_for_completion_interruptible_timeout(
			&dpram_ld->modem_pif_init_done, PIF_TIMEOUT);
	if (!ret) {
		pr_warn("[MODEM_IF] PIF init failed\n");
		pr_warn("pif_init_wait_condition is 0 and wait timeout happend\n");
		return -ENXIO;
	}

	pr_debug("[MODEM_IF] complete cbp71_on\n");

	mc->iod->modem_state_changed(mc->iod, STATE_ONLINE);

	return 0;
}
コード例 #19
0
static int cbp71_force_crash_exit(struct modem_ctl *mc)
{
	struct link_device *ld = get_current_link(mc->iod);
	struct dpram_link_device *dpld = to_dpram_link_device(ld);

	mif_err("force_crash_exit\n");
	mif_err("<%s>\n", mc->bootd->name);

	dpld->dpctl->send_intr(INT_CMD(INT_CMD_ERR_DISPLAY));
	mc->iod->modem_state_changed(mc->iod, STATE_CRASH_EXIT);

	return 0;
}
コード例 #20
0
static int qsc6085_reset(struct modem_ctl *mc)
{
	struct dpram_link_device *dpld = to_dpram_link_device(mc->iod->link);

	pr_info("MIF : %s\n", __func__);

	dpld->init_magic_num(dpld);

	gpio_set_value(mc->gpio_cp_reset, 0);
	msleep(100);
	gpio_set_value(mc->gpio_cp_reset, 1);

	return 0;
}
static int sprd6500_on(struct modem_ctl *mc)
{
	int ret;
	struct dpram_link_device *dpram_ld =
		to_dpram_link_device(get_current_link(mc->iod));

	pr_err("[MODEM_IF:ESC] <%s> start!!!\n", __func__);

	if (!mc->gpio_cp_reset) {
		pr_err("[MODEM_IF:ESC] no gpio data\n");
		return -ENXIO;
	}

	disable_irq(mc->irq_phone_active);

#if defined(CONFIG_MACH_DELOS_DUOS_CTC)
	// UART1_SEL for UART download
	sprd6500_UART_config(mc, 1);
	gpio_set_value(GPIO_UART1_SEL, 0);
#endif

	if (mc->gpio_reset_req_n)
		gpio_set_value(mc->gpio_reset_req_n, 1);

	pr_err("[MODEM_IF:ESC] <%s> CP On(%d,%d)\n", __func__, 
			gpio_get_value(mc->gpio_cp_on),
			gpio_get_value(mc->gpio_phone_active));

	gpio_set_value(mc->gpio_cp_on, 1);
	msleep(100);

	pr_err("[MODEM_IF:ESC] <%s> IRQ enabled\n", __func__);
	pr_err("[MODEM_IF:ESC] <%s> Active = %d\n", __func__, 
			gpio_get_value(mc->gpio_phone_active));

	enable_irq(mc->irq_phone_active);
	msleep(280);

	pr_err("[MODEM_IF:ESC] <%s> Active = %d\n", __func__, 
			gpio_get_value(mc->gpio_phone_active));

	gpio_set_value(GPIO_FPGA_SPI_MOSI, 1);
	gpio_set_value(mc->gpio_fpga1_cs_n, 1);
	gpio_set_value(mc->gpio_pda_active, 1);

	return 0;
}
コード例 #22
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);
}
コード例 #23
0
static int cmc221_boot_off(struct modem_ctl *mc)
{
	int ret;
	struct link_device *ld = get_current_link(mc->bootd);
	struct dpram_link_device *dpld = to_dpram_link_device(ld);

	mif_err("%s\n", mc->name);

	ret = wait_for_completion_interruptible_timeout(&dpld->dpram_init_cmd,
			DPRAM_INIT_TIMEOUT);
	if (!ret) {
		/* ret == 0 on timeout, ret < 0 if interrupted */
		mif_err("%s: ERR! timeout (CP_START not arrived)\n", mc->name);
		return -ENXIO;
	}

	enable_irq(mc->irq_phone_active);

	return 0;
}
コード例 #24
0
static int mdm6600_boot_on(struct modem_ctl *mc)
{
	struct regulator *regulator;
	struct link_device *ld = get_current_link(mc->iod);
	struct dpram_link_device *dpld = to_dpram_link_device(ld);

	pr_info("[MSM] <%s>\n", __func__);

	dpld->recv_intr(dpld);

	if (!mc->gpio_flm_uart_sel) {
		pr_err("[MSM] no gpio data\n");
		return -ENXIO;
	}

#if defined(CONFIG_MACH_M0_DUOSCTC) || defined(CONFIG_MACH_T0_CHN_CTC)
	mdm6600_vbus_on();
#elif defined(CONFIG_MACH_M0_GRANDECTC)
	if (system_rev >= 14)
		mdm6600_vbus_on();
#endif

	pr_info("[MSM] <%s> %s\n", __func__, "USB_BOOT_EN initializing");
	if (system_rev < 11) {

		gpio_direction_output(GPIO_USB_BOOT_EN, 0);
		s3c_gpio_setpull(GPIO_USB_BOOT_EN, S3C_GPIO_PULL_NONE);
		gpio_set_value(GPIO_USB_BOOT_EN, 0);

		gpio_direction_output(GPIO_BOOT_SW_SEL, 0);
		s3c_gpio_setpull(GPIO_BOOT_SW_SEL, S3C_GPIO_PULL_NONE);
		gpio_set_value(GPIO_BOOT_SW_SEL, 0);

		msleep(100);

		gpio_direction_output(GPIO_USB_BOOT_EN, 1);
		gpio_set_value(GPIO_USB_BOOT_EN, 1);

		pr_info("[MSM] <%s> USB_BOOT_EN:[%d]\n", __func__,
			gpio_get_value(GPIO_USB_BOOT_EN));

		gpio_direction_output(GPIO_BOOT_SW_SEL, 1);
		gpio_set_value(GPIO_BOOT_SW_SEL, 1);

		pr_info("[MSM] <%s> BOOT_SW_SEL : [%d]\n", __func__,
			gpio_get_value(GPIO_BOOT_SW_SEL));
	} else if (system_rev == 11) {
		gpio_direction_output(GPIO_USB_BOOT_EN, 0);
		s3c_gpio_setpull(GPIO_USB_BOOT_EN, S3C_GPIO_PULL_NONE);
		gpio_set_value(GPIO_USB_BOOT_EN, 0);

		gpio_direction_output(GPIO_USB_BOOT_EN_REV06, 0);
		s3c_gpio_setpull(GPIO_USB_BOOT_EN_REV06, S3C_GPIO_PULL_NONE);
		gpio_set_value(GPIO_USB_BOOT_EN_REV06, 0);

		msleep(100);

		gpio_direction_output(GPIO_USB_BOOT_EN, 1);
		gpio_set_value(GPIO_USB_BOOT_EN, 1);

		pr_info("[MSM] <%s> USB_BOOT_EN:[%d]\n", __func__,
			gpio_get_value(GPIO_USB_BOOT_EN));

		gpio_direction_output(GPIO_USB_BOOT_EN_REV06, 1);
		gpio_set_value(GPIO_USB_BOOT_EN_REV06, 1);

		pr_info("[MSM(%d)] <%s> USB_BOOT_EN:[%d]\n", system_rev,
			__func__, gpio_get_value(GPIO_USB_BOOT_EN_REV06));

		gpio_direction_output(GPIO_BOOT_SW_SEL, 0);
		s3c_gpio_setpull(GPIO_BOOT_SW_SEL, S3C_GPIO_PULL_NONE);
		gpio_set_value(GPIO_BOOT_SW_SEL, 0);

		gpio_direction_output(GPIO_BOOT_SW_SEL_REV06, 0);
		s3c_gpio_setpull(GPIO_BOOT_SW_SEL_REV06, S3C_GPIO_PULL_NONE);
		gpio_set_value(GPIO_BOOT_SW_SEL_REV06, 0);

		msleep(100);

		gpio_direction_output(GPIO_BOOT_SW_SEL, 1);
		gpio_set_value(GPIO_BOOT_SW_SEL, 1);

		pr_info("[MSM] <%s> BOOT_SW_SEL : [%d]\n", __func__,
			gpio_get_value(GPIO_BOOT_SW_SEL));

		gpio_direction_output(GPIO_BOOT_SW_SEL_REV06, 1);
		gpio_set_value(GPIO_BOOT_SW_SEL_REV06, 1);

		pr_info("[MSM(%d)] <%s> BOOT_SW_SEL : [%d]\n", system_rev,
			__func__, gpio_get_value(GPIO_BOOT_SW_SEL_REV06));

	} else {	/* system_rev>11 */
		gpio_direction_output(GPIO_USB_BOOT_EN_REV06, 0);
		s3c_gpio_setpull(GPIO_USB_BOOT_EN_REV06, S3C_GPIO_PULL_NONE);
		gpio_set_value(GPIO_USB_BOOT_EN_REV06, 0);

		gpio_direction_output(GPIO_BOOT_SW_SEL_REV06, 0);
		s3c_gpio_setpull(GPIO_BOOT_SW_SEL_REV06, S3C_GPIO_PULL_NONE);
		gpio_set_value(GPIO_BOOT_SW_SEL_REV06, 0);

		msleep(100);

		gpio_direction_output(GPIO_USB_BOOT_EN_REV06, 1);
		gpio_set_value(GPIO_USB_BOOT_EN_REV06, 1);

		pr_info("[MSM] <%s> USB_BOOT_EN:[%d]\n", __func__,
			gpio_get_value(GPIO_USB_BOOT_EN_REV06));

		gpio_direction_output(GPIO_BOOT_SW_SEL_REV06, 1);
		gpio_set_value(GPIO_BOOT_SW_SEL_REV06, 1);

	pr_info("[MSM] <%s> BOOT_SW_SEL : [%d]\n", __func__,
			gpio_get_value(GPIO_BOOT_SW_SEL_REV06));

	}

	mc->iod->modem_state_changed(mc->iod, STATE_BOOTING);

	return 0;
}
コード例 #25
0
static int dpram_force_dump(struct link_device *ld, struct io_device *iod)
{
	struct dpram_link_device *dpld = to_dpram_link_device(ld);
	dpram_trigger_force_cp_crash(dpld);
	return 0;
}
コード例 #26
0
static int dpram_ioctl(struct link_device *ld, struct io_device *iod,
		unsigned int cmd, unsigned long arg)
{
	int err = -EFAULT;
	struct dpram_link_device *dpld = to_dpram_link_device(ld);

	mif_info("%s: cmd 0x%08X\n", ld->name, cmd);

	switch (cmd) {
	case IOCTL_DPRAM_SEND_BOOT:
		if (dpld->ext_op && dpld->ext_op->download_boot) {
			err = dpld->ext_op->download_boot(dpld, (void *)arg);
			if (err < 0) {
				mif_info("%s: ERR! download_boot fail\n",
					ld->name);
				goto exit;
			}
		}
		break;

	case IOCTL_DPRAM_PHONE_POWON:
		if (dpld->ext_op && dpld->ext_op->prepare_download) {
			err = dpld->ext_op->prepare_download(dpld);
			if (err < 0) {
				mif_info("%s: ERR! prepare_download fail\n",
					ld->name);
				goto exit;
			}
		}
		break;

	case IOCTL_DPRAM_PHONEIMG_LOAD:
		if (dpld->ext_op && dpld->ext_op->download_bin) {
			err = dpld->ext_op->download_bin(dpld, (void *)arg);
			if (err < 0) {
				mif_info("%s: ERR! download_bin fail\n",
					ld->name);
				goto exit;
			}
		}
		break;

	case IOCTL_DPRAM_NVDATA_LOAD:
		if (dpld->ext_op && dpld->ext_op->download_nv) {
			err = dpld->ext_op->download_nv(dpld, (void *)arg);
			if (err < 0) {
				mif_info("%s: ERR! download_nv fail\n",
					ld->name);
				goto exit;
			}
		}
		break;

	case IOCTL_DPRAM_PHONE_BOOTSTART:
		if (dpld->ext_op && dpld->ext_op->cp_boot_start) {
			err = dpld->ext_op->cp_boot_start(dpld);
			if (err < 0) {
				mif_info("%s: ERR! cp_boot_start fail\n",
					ld->name);
				goto exit;
			}
		}
		if (dpld->ext_op && dpld->ext_op->cp_boot_post_process) {
			err = dpld->ext_op->cp_boot_post_process(dpld);
			if (err < 0) {
				mif_info("%s: ERR! cp_boot_post_process fail\n",
					ld->name);
				goto exit;
			}
		}
		break;

	case IOCTL_DPRAM_PHONE_UPLOAD_STEP1:
		disable_irq_nosync(dpld->irq);

		if (dpld->ext_op && dpld->ext_op->upload_step1) {
			err = dpld->ext_op->upload_step1(dpld);
			if (err < 0) {
				clear_intr(dpld);
				enable_irq(dpld->irq);
				mif_info("%s: ERR! upload_step1 fail\n",
					ld->name);
				goto exit;
			}
		}
		break;

	case IOCTL_DPRAM_PHONE_UPLOAD_STEP2:
		if (dpld->ext_op->upload_step2) {
			err = dpld->ext_op->upload_step2(dpld, (void *)arg);
			if (err < 0) {
				clear_intr(dpld);
				enable_irq(dpld->irq);
				mif_info("%s: ERR! upload_step2 fail\n",
					ld->name);
				goto exit;
			}
		}
		break;

	case IOCTL_DPRAM_INIT_STATUS:
		mif_debug("%s: get dpram init status\n", ld->name);
		return dpld->dpram_init_status;

	case IOCTL_MODEM_DL_START:
		err = dpram_set_dload_magic(ld, iod);
		if (err < 0) {
			mif_info("%s: ERR! dpram_set_dload_magic fail\n",
				ld->name);
			goto exit;
		}

	default:
		break;
	}

	return 0;

exit:
	return err;
}