diff options
Diffstat (limited to 'drivers/net/wwan/iosm/iosm_ipc_imem.c')
-rw-r--r-- | drivers/net/wwan/iosm/iosm_ipc_imem.c | 103 |
1 files changed, 25 insertions, 78 deletions
diff --git a/drivers/net/wwan/iosm/iosm_ipc_imem.c b/drivers/net/wwan/iosm/iosm_ipc_imem.c index 1cf49e9959f4..9f00e36b7f79 100644 --- a/drivers/net/wwan/iosm/iosm_ipc_imem.c +++ b/drivers/net/wwan/iosm/iosm_ipc_imem.c @@ -6,8 +6,6 @@ #include <linux/delay.h> #include "iosm_ipc_chnl_cfg.h" -#include "iosm_ipc_devlink.h" -#include "iosm_ipc_flash.h" #include "iosm_ipc_imem.h" #include "iosm_ipc_port.h" @@ -265,12 +263,9 @@ static void ipc_imem_dl_skb_process(struct iosm_imem *ipc_imem, switch (pipe->channel->ctype) { case IPC_CTYPE_CTRL: port_id = pipe->channel->channel_id; - if (port_id == IPC_MEM_CTRL_CHL_ID_7) - ipc_imem_sys_devlink_notify_rx(ipc_imem->ipc_devlink, - skb); - else - wwan_port_rx(ipc_imem->ipc_port[port_id]->iosm_port, - skb); + + /* Pass the packet to the wwan layer. */ + wwan_port_rx(ipc_imem->ipc_port[port_id]->iosm_port, skb); break; case IPC_CTYPE_WWAN: @@ -404,8 +399,19 @@ static void ipc_imem_rom_irq_exec(struct iosm_imem *ipc_imem) { struct ipc_mem_channel *channel; - channel = ipc_imem->ipc_devlink->devlink_sio.channel; + if (ipc_imem->flash_channel_id < 0) { + ipc_imem->rom_exit_code = IMEM_ROM_EXIT_FAIL; + dev_err(ipc_imem->dev, "Missing flash app:%d", + ipc_imem->flash_channel_id); + return; + } + ipc_imem->rom_exit_code = ipc_mmio_get_rom_exit_code(ipc_imem->mmio); + + /* Wake up the flash app to continue or to terminate depending + * on the CP ROM exit code. + */ + channel = &ipc_imem->channels[ipc_imem->flash_channel_id]; complete(&channel->ul_sem); } @@ -566,7 +572,7 @@ static void ipc_imem_handle_irq(struct iosm_imem *ipc_imem, int irq) enum ipc_phase old_phase, phase; bool retry_allocation = false; bool ul_pending = false; - int i; + int ch_id, i; if (irq != IMEM_IRQ_DONT_CARE) ipc_imem->ev_irq_pending[irq] = false; @@ -690,8 +696,11 @@ static void ipc_imem_handle_irq(struct iosm_imem *ipc_imem, int irq) if ((phase == IPC_P_PSI || phase == IPC_P_EBL) && ipc_imem->ipc_requested_state == IPC_MEM_DEVICE_IPC_RUNNING && ipc_mmio_get_ipc_state(ipc_imem->mmio) == - IPC_MEM_DEVICE_IPC_RUNNING) { - complete(&ipc_imem->ipc_devlink->devlink_sio.channel->ul_sem); + IPC_MEM_DEVICE_IPC_RUNNING && + ipc_imem->flash_channel_id >= 0) { + /* Wake up the flash app to open the pipes. */ + ch_id = ipc_imem->flash_channel_id; + complete(&ipc_imem->channels[ch_id].ul_sem); } /* Reset the expected CP state. */ @@ -1167,9 +1176,6 @@ void ipc_imem_cleanup(struct iosm_imem *ipc_imem) ipc_port_deinit(ipc_imem->ipc_port); } - if (ipc_imem->ipc_devlink) - ipc_devlink_deinit(ipc_imem->ipc_devlink); - ipc_imem_device_ipc_uninit(ipc_imem); ipc_imem_channel_reset(ipc_imem); @@ -1252,7 +1258,6 @@ struct iosm_imem *ipc_imem_init(struct iosm_pcie *pcie, unsigned int device_id, void __iomem *mmio, struct device *dev) { struct iosm_imem *ipc_imem = kzalloc(sizeof(*pcie->imem), GFP_KERNEL); - enum ipc_mem_exec_stage stage; if (!ipc_imem) return NULL; @@ -1267,6 +1272,9 @@ struct iosm_imem *ipc_imem_init(struct iosm_pcie *pcie, unsigned int device_id, ipc_imem->cp_version = 0; ipc_imem->device_sleep = IPC_HOST_SLEEP_ENTER_SLEEP; + /* Reset the flash channel id. */ + ipc_imem->flash_channel_id = -1; + /* Reset the max number of configured channels */ ipc_imem->nr_of_channels = 0; @@ -1320,21 +1328,8 @@ struct iosm_imem *ipc_imem_init(struct iosm_pcie *pcie, unsigned int device_id, goto imem_config_fail; } - stage = ipc_mmio_get_exec_stage(ipc_imem->mmio); - if (stage == IPC_MEM_EXEC_STAGE_BOOT) { - /* Alloc and Register devlink */ - ipc_imem->ipc_devlink = ipc_devlink_init(ipc_imem); - if (!ipc_imem->ipc_devlink) { - dev_err(ipc_imem->dev, "Devlink register failed"); - goto imem_config_fail; - } - - if (ipc_flash_link_establish(ipc_imem)) - goto devlink_channel_fail; - } return ipc_imem; -devlink_channel_fail: - ipc_devlink_deinit(ipc_imem->ipc_devlink); + imem_config_fail: hrtimer_cancel(&ipc_imem->td_alloc_timer); hrtimer_cancel(&ipc_imem->fast_update_timer); @@ -1366,51 +1361,3 @@ void ipc_imem_td_update_timer_suspend(struct iosm_imem *ipc_imem, bool suspend) { ipc_imem->td_update_timer_suspended = suspend; } - -/* Verify the CP execution state, copy the chip info, - * change the execution phase to ROM - */ -static int ipc_imem_devlink_trigger_chip_info_cb(struct iosm_imem *ipc_imem, - int arg, void *msg, - size_t msgsize) -{ - enum ipc_mem_exec_stage stage; - struct sk_buff *skb; - int rc = -EINVAL; - size_t size; - - /* Test the CP execution state. */ - stage = ipc_mmio_get_exec_stage(ipc_imem->mmio); - if (stage != IPC_MEM_EXEC_STAGE_BOOT) { - dev_err(ipc_imem->dev, - "Execution_stage: expected BOOT, received = %X", stage); - goto trigger_chip_info_fail; - } - /* Allocate a new sk buf for the chip info. */ - size = ipc_imem->mmio->chip_info_size; - if (size > IOSM_CHIP_INFO_SIZE_MAX) - goto trigger_chip_info_fail; - - skb = ipc_pcie_alloc_local_skb(ipc_imem->pcie, GFP_ATOMIC, size); - if (!skb) { - dev_err(ipc_imem->dev, "exhausted skbuf kernel DL memory"); - rc = -ENOMEM; - goto trigger_chip_info_fail; - } - /* Copy the chip info characters into the ipc_skb. */ - ipc_mmio_copy_chip_info(ipc_imem->mmio, skb_put(skb, size), size); - /* First change to the ROM boot phase. */ - dev_dbg(ipc_imem->dev, "execution_stage[%X] eq. BOOT", stage); - ipc_imem->phase = ipc_imem_phase_update(ipc_imem); - ipc_imem_sys_devlink_notify_rx(ipc_imem->ipc_devlink, skb); - rc = 0; -trigger_chip_info_fail: - return rc; -} - -int ipc_imem_devlink_trigger_chip_info(struct iosm_imem *ipc_imem) -{ - return ipc_task_queue_send_task(ipc_imem, - ipc_imem_devlink_trigger_chip_info_cb, - 0, NULL, 0, true); -} |