in mwave/tp3780i.c [279:406]
int tp3780I_EnableDSP(THINKPAD_BD_DATA * pBDData)
{
DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings;
bool bDSPPoweredUp = 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", NULL)) {
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, NULL);
}
if (request_irq(pSettings->usDspIrq, &DspInterrupt, 0, "mwave_3780i", NULL)) {
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;
}
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 (bDSPPoweredUp)
smapi_set_DSP_power_state(false);
if (bInterruptAllocated) {
free_irq(pSettings->usDspIrq, NULL);
pSettings->bInterruptClaimed = false;
}
return -EIO;
}