static int _cmc221_idpram_wait_resp(struct dpram_link_device *dpld, u32 resp) { struct link_device *ld = &dpld->ld; int count = 50000; u32 rcvd = 0; if (resp == CMC22x_CP_REQ_NV_DATA) { while (1) { rcvd = ioread32(dpld->bt_map.resp); if (rcvd == resp) break; rcvd = cmc221_idpram_recv_msg(dpld); if (rcvd == 0x9999) { mif_info("%s: Invalid resp 0x%04X\n", ld->name, rcvd); panic("CP Crash ... BAD CRC in CP"); } if (count-- < 0) { mif_info("%s: Invalid resp 0x%08X\n", ld->name, rcvd); return -EAGAIN; } udelay(100); } } else { while (1) { rcvd = cmc221_idpram_recv_msg(dpld); if (rcvd == resp) break; if (resp == CMC22x_CP_RECV_NV_END && rcvd == CMC22x_CP_CAL_BAD) { mif_info("%s: CMC22x_CP_CAL_BAD\n", ld->name); break; } if (count-- < 0) { mif_info("%s: Invalid resp 0x%04X\n", ld->name, rcvd); return -EAGAIN; } udelay(100); } } return rcvd; }
static int _cmc221_idpram_upload(struct dpram_link_device *dpld, struct dpram_dump_arg *dumparg) { struct link_device *ld = &dpld->ld; int ret; u8 __iomem *src; int buff_size = CMC22x_DUMP_BUFF_SIZE; if ((dpld->dump_rcvd & 0x1) == 0) cmc221_idpram_send_msg(dpld, CMC22x_1ST_BUFF_READY); else cmc221_idpram_send_msg(dpld, CMC22x_2ND_BUFF_READY); init_completion(&dpld->dump_recv_done); mif_add_timer(&dpld->dump_timer, DUMP_WAIT_TIMEOUT, _cmc221_idpram_wait_dump, (unsigned long)dpld); ret = wait_for_completion_interruptible_timeout( &dpld->dump_recv_done, DUMP_TIMEOUT); if (!ret) { mif_info("%s: ERR! CP didn't send dump data!!!\n", ld->name); goto err_out; } if (cmc221_idpram_recv_msg(dpld) == CMC22x_CP_DUMP_END) { mif_info("%s: CMC22x_CP_DUMP_END\n", ld->name); return 0; } if ((dpld->dump_rcvd & 0x1) == 0) src = dpld->ul_map.buff; else src = dpld->ul_map.buff + CMC22x_DUMP_BUFF_SIZE; memcpy(dpld->buff, src, buff_size); ret = copy_to_user(dumparg->buff, dpld->buff, buff_size); if (ret < 0) { mif_info("%s: ERR! copy_to_user fail\n", ld->name); goto err_out; } dpld->dump_rcvd++; return buff_size; err_out: return -EIO; }
static int cmc221_idpram_upload(struct dpram_link_device *dpld, struct dpram_dump_arg *dumparg) { int ret; u8 __iomem *src; int buff_size = CMC22x_DUMP_BUFF_SIZE; if ((dpld->crash_rcvd & 0x1) == 0) cmc221_idpram_send_msg(dpld, CMC22x_1ST_BUFF_READY); else cmc221_idpram_send_msg(dpld, CMC22x_2ND_BUFF_READY); init_completion(&dpld->crash_cmpl); mif_add_timer(&dpld->crash_timer, DUMP_WAIT_TIMEOUT, cmc221_idpram_wait_dump, (unsigned long)dpld); ret = wait_for_completion_timeout(&dpld->crash_cmpl, DUMP_TIMEOUT); if (!ret) { mif_info("ERR! no dump from CP!!!\n"); goto err_out; } if (cmc221_idpram_recv_msg(dpld) == CMC22x_CP_DUMP_END) { mif_info("recv CMC22x_CP_DUMP_END\n"); return 0; } if ((dpld->crash_rcvd & 0x1) == 0) src = dpld->ul_map.buff; else src = dpld->ul_map.buff + CMC22x_DUMP_BUFF_SIZE; memcpy(dpld->buff, src, buff_size); ret = copy_to_user(dumparg->buff, dpld->buff, buff_size); if (ret < 0) { mif_info("ERR! copy_to_user fail\n"); goto err_out; } dpld->crash_rcvd++; return buff_size; err_out: return -EIO; }
static void _cmc221_idpram_wait_dump(unsigned long arg) { struct dpram_link_device *dpld = (struct dpram_link_device *)arg; u16 msg; msg = cmc221_idpram_recv_msg(dpld); if (msg == CMC22x_CP_DUMP_END) { complete_all(&dpld->dump_recv_done); return; } if (((dpld->dump_rcvd & 0x1) == 0) && (msg == CMC22x_1ST_BUFF_FULL)) { complete_all(&dpld->dump_recv_done); return; } if (((dpld->dump_rcvd & 0x1) == 1) && (msg == CMC22x_2ND_BUFF_FULL)) { complete_all(&dpld->dump_recv_done); return; } mif_add_timer(&dpld->dump_timer, DUMP_WAIT_TIMEOUT, _cmc221_idpram_wait_dump, (unsigned long)dpld); }