int tp3780I_DisableDSP(THINKPAD_BD_DATA * pBDData)
{
	int retval = 0;
	DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings;

	PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_DisableDSP entry pBDData %p\n", pBDData);

	if (pBDData->bDSPEnabled) {
		dsp3780I_DisableDSP(&pBDData->rDspSettings);
		if (pSettings->bInterruptClaimed) {
			free_irq(pSettings->usDspIrq, NULL);
			pSettings->bInterruptClaimed = FALSE;
		}
		smapi_set_DSP_power_state(FALSE);
		pBDData->bDSPEnabled = FALSE;
	}

	PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_DisableDSP exit retval %x\n", retval);

	return retval;
}
Example #2
0
int tp3780I_EnableDSP(THINKPAD_BD_DATA * pBDData)
{
	DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings;
	BOOLEAN bDSPPoweredUp = FALSE, bDSPEnabled = FALSE, bInterruptAllocated = FALSE;

	PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_EnableDSP entry pBDData %p\n", pBDData);

	if (pBDData->bDSPEnabled) {
		PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_EnableDSP: Error: DSP already enabled!\n");
		goto exit_cleanup;
	}

	if (!pSettings->bDSPEnabled) {
		PRINTK_ERROR(KERN_ERR_MWAVE "tp3780::tp3780I_EnableDSP: Error: pSettings->bDSPEnabled not set\n");
		goto exit_cleanup;
	}

	if (
		(pSettings->usDspIrq >= s_numIrqs)
		|| (pSettings->usDspDma >= s_numDmas)
		|| (s_ausThinkpadIrqToField[pSettings->usDspIrq] == 0xFFFF)
		|| (s_ausThinkpadDmaToField[pSettings->usDspDma] == 0xFFFF)
	) {
		PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_EnableDSP: Error: invalid irq %x\n", pSettings->usDspIrq);
		goto exit_cleanup;
	}

	if (
		((pSettings->usDspBaseIO & 0xF00F) != 0)
		|| (pSettings->usDspBaseIO & 0x0FF0) == 0
	) {
		PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_EnableDSP: Error: Invalid DSP base I/O address %x\n", pSettings->usDspBaseIO);
		goto exit_cleanup;
	}

	if (pSettings->bModemEnabled) {
		if (
			pSettings->usUartIrq >= s_numIrqs
			|| s_ausThinkpadIrqToField[pSettings->usUartIrq] == 0xFFFF
		) {
			PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_EnableDSP: Error: Invalid UART IRQ %x\n", pSettings->usUartIrq);
			goto exit_cleanup;
		}
		switch (pSettings->usUartBaseIO) {
			case 0x03F8:
			case 0x02F8:
			case 0x03E8:
			case 0x02E8:
				break;

			default:
				PRINTK_ERROR("tp3780i::tp3780I_EnableDSP: Error: Invalid UART base I/O address %x\n", pSettings->usUartBaseIO);
				goto exit_cleanup;
		}
	}

	pSettings->bDspIrqActiveLow = pSettings->bDspIrqPulse = TRUE;
	pSettings->bUartIrqActiveLow = pSettings->bUartIrqPulse = TRUE;

	if (pBDData->bShareDspIrq) {
		pSettings->bDspIrqActiveLow = FALSE;
	}
	if (pBDData->bShareUartIrq) {
		pSettings->bUartIrqActiveLow = FALSE;
	}

	pSettings->usNumTransfers = TP_CFG_NumTransfers;
	pSettings->usReRequest = TP_CFG_RerequestTimer;
	pSettings->bEnableMEMCS16 = TP_CFG_MEMCS16;
	pSettings->usIsaMemCmdWidth = TP_CFG_IsaMemCmdWidth;
	pSettings->bGateIOCHRDY = TP_CFG_GateIOCHRDY;
	pSettings->bEnablePwrMgmt = TP_CFG_EnablePwrMgmt;
	pSettings->usHBusTimerLoadValue = TP_CFG_HBusTimerValue;
	pSettings->bDisableLBusTimeout = TP_CFG_DisableLBusTimeout;
	pSettings->usN_Divisor = TP_CFG_N_Divisor;
	pSettings->usM_Multiplier = TP_CFG_M_Multiplier;
	pSettings->bPllBypass = TP_CFG_PllBypass;
	pSettings->usChipletEnable = TP_CFG_ChipletEnable;

	if (request_irq(pSettings->usUartIrq, &UartInterrupt, 0, "mwave_uart", 0)) {
		PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_EnableDSP: Error: Could not get UART IRQ %x\n", pSettings->usUartIrq);
		goto exit_cleanup;
	} else {		/* no conflict just release */
		free_irq(pSettings->usUartIrq, 0);
	}

	if (request_irq(pSettings->usDspIrq, &DspInterrupt, 0, "mwave_3780i", 0)) {
		PRINTK_ERROR("tp3780i::tp3780I_EnableDSP: Error: Could not get 3780i IRQ %x\n", pSettings->usDspIrq);
		goto exit_cleanup;
	} else {
		PRINTK_3(TRACE_TP3780I,
			"tp3780i::tp3780I_EnableDSP, got interrupt %x bShareDspIrq %x\n",
			pSettings->usDspIrq, pBDData->bShareDspIrq);
		bInterruptAllocated = TRUE;
		pSettings->bInterruptClaimed = TRUE;
	}

	smapi_set_DSP_power_state(FALSE);
	if (smapi_set_DSP_power_state(TRUE)) {
		PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_EnableDSP: Error: smapi_set_DSP_power_state(TRUE) failed\n");
		goto exit_cleanup;
	} else {
		bDSPPoweredUp = TRUE;
	}

	if (dsp3780I_EnableDSP(pSettings, s_ausThinkpadIrqToField, s_ausThinkpadDmaToField)) {
		PRINTK_ERROR("tp3780i::tp3780I_EnableDSP: Error: dsp7880I_EnableDSP() failed\n");
		goto exit_cleanup;
	} else {
		bDSPEnabled = TRUE;
	}

	EnableSRAM(pBDData);

	pBDData->bDSPEnabled = TRUE;

	PRINTK_1(TRACE_TP3780I, "tp3780i::tp3780I_EnableDSP exit\n");

	return 0;

exit_cleanup:
	PRINTK_ERROR("tp3780i::tp3780I_EnableDSP: Cleaning up\n");
	if (bDSPEnabled)
		dsp3780I_DisableDSP(pSettings);
	if (bDSPPoweredUp)
		smapi_set_DSP_power_state(FALSE);
	if (bInterruptAllocated) {
		free_irq(pSettings->usDspIrq, 0);
		pSettings->bInterruptClaimed = FALSE;
	}
	return -EIO;
}