void modem_release_mmio(struct modemctl *mc, unsigned bits) { unsigned long flags; spin_lock_irqsave(&mc->lock, flags); mc->mmio_req_count--; mc->mmio_signal_bits |= bits; if ((mc->mmio_req_count == 0) && modem_running(mc)) { if (mc->mmio_bp_request) { mc->mmio_bp_request = 0; writel(0, mc->mmio + OFF_SEM); writel(MB_COMMAND | MB_VALID | MBC_RES_SEM, mc->mmio + OFF_MBOX_AP); MODEM_COUNT(mc,release_bp_waiting); } else if (mc->mmio_signal_bits) { writel(0, mc->mmio + OFF_SEM); writel(MB_VALID | mc->mmio_signal_bits, mc->mmio + OFF_MBOX_AP); MODEM_COUNT(mc,release_bp_signaled); } else { MODEM_COUNT(mc,release_no_action); } mc->mmio_owner = 0; mc->mmio_signal_bits = 0; } spin_unlock_irqrestore(&mc->lock, flags); }
int modem_request_mmio(struct modemctl *mc) { unsigned long flags; int ret; spin_lock_irqsave(&mc->lock, flags); mc->mmio_req_count++; ret = mc->mmio_owner; if (!ret) { if (mmio_sem(mc) == 1) { /* surprise! we already have control */ ret = mc->mmio_owner = 1; wake_up(&mc->wq); modem_update_state(mc); MODEM_COUNT(mc,request_no_wait); } else { /* ask the modem for mmio access */ if (modem_running(mc)) modem_request_sem(mc); MODEM_COUNT(mc,request_wait); } } else { MODEM_COUNT(mc,request_no_wait); } /* TODO: timer to retry? */ spin_unlock_irqrestore(&mc->lock, flags); return ret; }
int modem_acquire_mmio(struct modemctl *mc) { if (modem_request_mmio(mc) == 0) if (wait_event_interruptible(mc->wq, mmio_owner_p(mc))) { modem_release_mmio(mc, 0); return -ERESTARTSYS; } if (!modem_running(mc)) { modem_release_mmio(mc, 0); return -ENODEV; } return 0; }
static int modem_start(struct modemctl *mc, int ramdump) { int ret; pr_info("[MODEM] modem_start() %s\n", ramdump ? "ramdump" : "normal"); if (mc->status != MODEM_POWER_ON) { pr_err("[MODEM] modem not powered on\n"); return -EINVAL; } if (!mc->is_cdma_modem && readl(mc->mmio + OFF_MBOX_BP) != MODEM_MSG_SBL_DONE) { pr_err("[MODEM] bootloader not ready\n"); return -EIO; } writel(0, mc->mmio + OFF_SEM); if (ramdump) { mc->status = MODEM_BOOTING_RAMDUMP; mc->ramdump_size = 0; mc->ramdump_pos = 0; writel(MODEM_CMD_RAMDUMP_START, mc->mmio + OFF_MBOX_AP); ret = wait_event_timeout(mc->wq, mc->status == MODEM_DUMPING, 25 * HZ); if (ret == 0) return -ENODEV; } else { if (mc->is_cdma_modem) mc->status = MODEM_RUNNING; else { mc->status = MODEM_BOOTING_NORMAL; writel(MODEM_CMD_BINARY_LOAD, mc->mmio + OFF_MBOX_AP); ret = wait_event_timeout(mc->wq, modem_running(mc), 25 * HZ); if (ret == 0) return -ENODEV; } } pr_info("[MODEM] modem_start() DONE\n"); return 0; }
void *rx_thread_fnc(void* ptr) { printf(": Running Rx thread...\n"); while(modem_running()) { modem_read((uint64_t*)rx_buffer, RX_BUF_SIZE); #if(DEBUG>0) int i = 0; printf("-------Receiver Side-------\n"); printf("Received Header Data\n"); for(i = 0; i < HEADER_FRAME_SIZE+HEADER_FRAME_SIZE; i++) printf("%d, ", rx_buffer[i]); printf("\n"); #endif if(*(uint64_t*)&(rx_buffer[RX_BUF_SIZE - CRC_SIZE])) printf("RADIO: CRC ERROR\n"); #if(DEBUG>0) printf("Received Full Payload\n"); for(i = 0; i < TX_BUF_SIZE; i++) { printf("%d, ", rx_buffer[i]); } printf("\n"); if (INTERNAL_PACKET_GEN > 0) { printf("|"); // Use for internal packet generation print for(i = 0; i < RX_BUF_SIZE; i=i+8) { printf("%c", rx_buffer[i]); } printf("|\n"); } #endif break; } printf("Exiting Rx thread\n"); return NULL; }
static int modem_start(struct modemctl *mc, int ramdump) { pr_info("[MODEM] modem_start() %s\n", ramdump ? "ramdump" : "normal"); if (mc->status != MODEM_POWER_ON) { pr_err("[MODEM] modem not powered on\n"); return -EINVAL; } if (readl(mc->mmio + OFF_MBOX_BP) != MODEM_MSG_SBL_DONE) { pr_err("[MODEM] bootloader not ready\n"); return -EIO; } if (mmio_sem(mc) != 1) { pr_err("[MODEM] we do not own the semaphore\n"); return -EIO; } writel(0, mc->mmio + OFF_SEM); if (ramdump) { mc->status = MODEM_BOOTING_RAMDUMP; mc->ramdump_size = 0; mc->ramdump_pos = 0; writel(MODEM_CMD_RAMDUMP_START, mc->mmio + OFF_MBOX_AP); /* TODO: timeout and fail */ wait_event(mc->wq, mc->status == MODEM_DUMPING); } else { mc->status = MODEM_BOOTING_NORMAL; writel(MODEM_CMD_BINARY_LOAD, mc->mmio + OFF_MBOX_AP); /* TODO: timeout and fail */ wait_event(mc->wq, modem_running(mc)); } pr_info("[MODEM] modem_start() DONE\n"); return 0; }
int modem_acquire_mmio(struct modemctl *mc) { if (modem_request_mmio(mc) == 0) { int ret = wait_event_interruptible_timeout( mc->wq, mmio_owner_p(mc), 5 * HZ); if (ret <= 0) { modem_release_mmio(mc, 0); if (ret == 0) { pr_err("modem_acquire_mmio() TIMEOUT\n"); return -ENODEV; } else { return -ERESTARTSYS; } } } if (!modem_running(mc)) { modem_release_mmio(mc, 0); return -ENODEV; } return 0; }