static void srp_wait_for_pending(void) { unsigned long deadline = jiffies + HZ / 10; do { /* Wait for SRP Pending */ if (readl(srp.commbox + SRP_PENDING)) break; msleep_interruptible(5); } while (time_before(jiffies, deadline)); srp_info("Pending status[%s]\n", readl(srp.commbox + SRP_PENDING) ? "STALL" : "RUN"); }
static void srp_enable(int stat, const char *func) { unsigned long flags; spin_lock_irqsave(&lock_srp_cnt, flags); if (stat) srp_cnt ++; else srp_cnt --; srp_info("%s: srp_cnt %d(%s)\n", __func__, srp_cnt, func); spin_unlock_irqrestore(&lock_srp_cnt, flags); }
static void srp_pending_ctrl(int ctrl) { unsigned int srp_ctrl = readl(srp.commbox + SRP_PENDING); if (ctrl == srp_ctrl) { srp_info("Already set SRP pending control[%d]\n", ctrl); if (ctrl) return; else srp_wait_for_pending(); } writel(ctrl, srp.commbox + SRP_PENDING); srp.is_pending = ctrl; srp_debug("Current SRP Status[%s]\n", readl(srp.commbox + SRP_PENDING) ? "STALL" : "RUN"); }
int srp_check(int noti) { mutex_lock(&srp_mutex); srp_info("%s : noti : %d\n", __func__, noti); if (noti == SRP_DISABLE) { /* Disable flag set to disable */ if (srp.is_opened) { mutex_unlock(&srp_mutex); return 0; /* return fail */ } else { srp_disable = 1; /* flag set */ mutex_unlock(&srp_mutex); return 1; /* return success */ } } else if (noti == SRP_ENABLE) { /* Disable flag set to enable */ if (!srp_firmware_broken) srp_disable = 0; /* flag set */ } else if (noti == SRP_FIRM_BROKEN) /* srp firmware broken noti flag */ srp_firmware_broken = 1; mutex_unlock(&srp_mutex); return 0; }
static int srp_request_intr_mode(int mode) { unsigned int reset_type = srp.pdata->type; unsigned long deadline; u32 pwr_mode = readl(srp.commbox + SRP_POWER_MODE); u32 intr_en = readl(srp.commbox + SRP_INTREN); u32 intr_msk = readl(srp.commbox + SRP_INTRMASK); u32 intr_src = readl(srp.commbox + SRP_INTRSRC); u32 intr_irq; u32 check_mode = 0x0; int ret = 0; pwr_mode &= ~SRP_POWER_MODE_MASK; intr_en &= ~SRP_INTR_DI; intr_msk |= (SRP_ARM_INTR_MASK | SRP_DMA_INTR_MASK | SRP_TMR_INTR_MASK); intr_src &= ~(SRP_INTRSRC_MASK); switch (mode) { case SUSPEND: srp_info("Request Suspend to SRP\n"); pwr_mode &= ~SRP_POWER_MODE_TRIGGER; check_mode = SRP_SUSPEND_CHECKED; break; case RESUME: srp_info("Request Resume to SRP\n"); pwr_mode |= SRP_POWER_MODE_TRIGGER; check_mode = 0x0; break; case SW_RESET: srp_info("Request Reset to SRP\n"); pwr_mode |= SRP_SW_RESET_TRIGGER; check_mode = SRP_SW_RESET_DONE; break; default: srp_err("Not support request mode to srp\n"); break; } intr_en |= SRP_INTR_EN; intr_msk &= ~SRP_ARM_INTR_MASK; intr_src |= SRP_ARM_INTR_SRC; if (reset_type == SRP_SW_RESET) { intr_irq = readl(srp.commbox + SRP_INTRIRQ); intr_irq &= ~(SRP_INTRIRQ_MASK); intr_irq |= SRP_INTRIRQ_CONF; writel(intr_irq, srp.commbox + SRP_INTRIRQ); } writel(pwr_mode, srp.commbox + SRP_POWER_MODE); writel(intr_msk, srp.commbox + SRP_INTRMASK); writel(intr_src, srp.commbox + SRP_INTRSRC); writel(intr_en, srp.commbox + SRP_INTREN); srp_debug("PWR_MODE[0x%x], INTREN[0x%x], INTRMSK[0x%x], INTRSRC[0x%x]\n", readl(srp.commbox + SRP_POWER_MODE), readl(srp.commbox + SRP_INTREN), readl(srp.commbox + SRP_INTRMASK), readl(srp.commbox + SRP_INTRSRC)); if (check_mode) { srp_pending_ctrl(RUN); deadline = jiffies + (HZ / 2); do { /* Waiting for completed suspend mode */ if ((readl(srp.commbox + SRP_POWER_MODE) & check_mode)) { srp_info("Success! requested power[%s] mode!\n", mode == SUSPEND ? "SUSPEND" : "SW_RESET"); ret = 1; break; } } while (time_before(jiffies, deadline)); } writel(STALL, srp.commbox + SRP_PENDING); if (check_mode) { /* Clear Suspend mode */ pwr_mode = readl(srp.commbox + SRP_POWER_MODE); pwr_mode &= ~check_mode; writel(pwr_mode, srp.commbox + SRP_POWER_MODE); } return ret; }