Ejemplo n.º 1
0
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 */
}
Ejemplo n.º 2
0
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
}