void fio_unlock(int module) { unsigned long flags; if (fio_owner == module) { #if (SD_HAS_INTERNAL_MUXER == 1) if (fio_select_sdio_as_default && (module != SELECT_FIO_SDIO)) { u32 fio_dmactr; #if (HANDLE_SDIO_FAKE_IRQ == 1) /* When swtich back to SDIO, SMIO38 ~ 43 connected to */ /* SD controller internally and a detection of low of */ /* SMIO41 cause fake SDIO irq. */ unsigned long flags; flags = arm_irq_save(); /* SMIO_38 ~ 43 HW */ amba_setbitsl(GPIO2_AFSEL_REG, 0x000007e0); fio_dmactr = amba_readl(FIO_DMACTR_REG); fio_dmactr = (fio_dmactr & 0xcfffffff) | FIO_DMACTR_SD; amba_writel(FIO_DMACTR_REG, fio_dmactr); amba_setbitsl(FIO_CTR_REG, FIO_CTR_XD); fio_reactive_sdio_irq(); arm_irq_restore(flags); #else fio_dmactr = amba_readl(FIO_DMACTR_REG); fio_dmactr = (fio_dmactr & 0xcfffffff) | FIO_DMACTR_SD; amba_writel(FIO_DMACTR_REG, fio_dmactr); amba_setbitsl(FIO_CTR_REG, FIO_CTR_XD); #endif } #endif } if (!(fio_owner & (~module)) && (fio_default_owner != SELECT_FIO_FREE) && (fio_default_owner != module)) { __fio_select_lock(fio_default_owner); } spin_lock_irqsave(&fio_lock, flags); #if (SD_HOST1_HOST2_HAS_MUX == 1) if (module & (SELECT_FIO_SD | SELECT_FIO_SD2)) { if (fio_owner & module) { fio_owner &= (~module); wake_up(&fio_wait); } else { pr_err("%s: fio_owner(0x%x) != module(0x%x)!.\n", __func__, fio_owner, module); } } else #endif if (fio_owner == module) { fio_owner = SELECT_FIO_FREE; wake_up(&fio_wait); } else { pr_err("%s: fio_owner(%d) != module(%d)!.\n", __func__, fio_owner, module); } spin_unlock_irqrestore(&fio_lock, flags); #if defined(CONFIG_AMBALINK_LOCK) #if (SD_HOST1_HOST2_HAS_MUX == 1) switch (module) { case SELECT_FIO_SD: case SELECT_FIO_SDIO: aipc_mutex_unlock(AMBA_IPC_MUTEX_SD0); return; case SELECT_FIO_SD2: aipc_mutex_unlock(AMBA_IPC_MUTEX_SD1); return; default: aipc_mutex_unlock(AMBA_IPC_MUTEX_SD0); aipc_mutex_unlock(AMBA_IPC_MUTEX_SD1); return; } #else aipc_mutex_unlock(AMBA_IPC_MUTEX_FIO); #endif /* SD_HOST1_HOST2_HAS_MUX */ #endif /* CONFIG_AMBALINK_LOCK */ }
void fio_unlock(int module) { if (atomic_read(&fio_owner) == module) { #if (SD_HAS_INTERNAL_MUXER == 1) if (fio_select_sdio_as_default && (module != SELECT_FIO_SDIO)) { u32 fio_dmactr; #if (HANDLE_SDIO_FAKE_IRQ == 1) /* When swtich back to SDIO, SMIO38 ~ 43 connected to */ /* SD controller internally and a detection of low of */ /* SMIO41 cause fake SDIO irq. */ unsigned long flags; flags = arm_irq_save(); /* SMIO_38 ~ 43 HW */ amba_setbitsl(GPIO2_AFSEL_REG, 0x000007e0); fio_dmactr = amba_readl(FIO_DMACTR_REG); fio_dmactr = (fio_dmactr & 0xcfffffff) | FIO_DMACTR_SD; amba_writel(FIO_DMACTR_REG, fio_dmactr); amba_setbitsl(FIO_CTR_REG, FIO_CTR_XD); fio_reactive_sdio_irq(); arm_irq_restore(flags); #else fio_dmactr = amba_readl(FIO_DMACTR_REG); fio_dmactr = (fio_dmactr & 0xcfffffff) | FIO_DMACTR_SD; amba_writel(FIO_DMACTR_REG, fio_dmactr); amba_setbitsl(FIO_CTR_REG, FIO_CTR_XD); #endif } #endif #if (FIO_SUPPORT_AHB_CLK_ENA == 1) if (fio_select_sdio_as_default && (module == SELECT_FIO_CF)) { fio_amb_cf_disable(); fio_amb_sd2_enable(); } #endif } if ((atomic_read(&fio_owner) == module) && (fio_default_owner != SELECT_FIO_FREE) && (fio_default_owner != module)) { __fio_select_lock(fio_default_owner); } #if defined(CONFIG_AMBARELLA_IPC) atomic_set(&fio_owner, SELECT_FIO_FREE); #if (SD_HOST1_HOST2_HAS_MUX == 1) switch (module) { case SELECT_FIO_SD: case SELECT_FIO_SDIO: ipc_mutex_unlock(IPC_MUTEX_ID_SD); return; case SELECT_FIO_SD2: ipc_mutex_unlock(IPC_MUTEX_ID_SD2); return; default: ipc_mutex_unlock(IPC_MUTEX_ID_SD); ipc_mutex_unlock(IPC_MUTEX_ID_SD2); return; } #else ipc_mutex_unlock(IPC_MUTEX_ID_FIO); #endif /* SD_HOST1_HOST2_HAS_MUX */ #else if (atomic_cmpxchg(&fio_owner, module, SELECT_FIO_FREE) == module) { wake_up(&fio_lock); } else { pr_err("%s: fio_owner[%d] != module[%d]!.\n", __func__, atomic_read(&fio_owner), module); } #endif }