static int if_hsi_close_channel(struct if_hsi_channel *channel) { unsigned long int flags; if (!channel->opened) { pr_debug("[MIPI-HSI] channel %d is already closed\n", channel->channel_id); return 0; } if_hsi_set_wakeline(channel, 0); hsi_write_cancel(channel->dev); hsi_read_cancel(channel->dev); spin_lock_irqsave(&channel->tx_state_lock, flags); channel->tx_state &= ~HSI_CHANNEL_TX_STATE_WRITING; spin_unlock_irqrestore(&channel->tx_state_lock, flags); spin_lock_irqsave(&channel->rx_state_lock, flags); channel->rx_state &= ~HSI_CHANNEL_RX_STATE_READING; spin_unlock_irqrestore(&channel->rx_state_lock, flags); hsi_close(channel->dev); channel->opened = 0; channel->send_step = STEP_CLOSED; channel->recv_step = STEP_CLOSED; pr_debug("[MIPI-HSI] hsi_close Done : %d\n", channel->channel_id); return 0; }
void if_hsi_cancel_read(int ch) { struct if_hsi_channel *channel; channel = &hsi_protocol_iface.channels[ch]; dev_dbg(&channel->dev->device, "%s, ch = %d\n", __func__, ch); if (channel->state & HSI_CHANNEL_STATE_READING) hsi_read_cancel(channel->dev); spin_lock(&channel->lock); channel->state &= ~HSI_CHANNEL_STATE_READING; spin_unlock(&channel->lock); }
int if_hsi_closechannel(struct if_hsi_channel *channel) { int ret = 0; dev_dbg(&channel->dev->device, "%s, ch = %d\n", __func__, channel->channel_id); spin_lock(&channel->lock); if (!channel->opened) goto leave; if (!channel->dev) { pr_err("Channel %d is not ready??\n", channel->channel_id); ret = -ENODEV; goto leave; } /* Stop any pending read/write */ if (channel->state & HSI_CHANNEL_STATE_READING) { channel->state &= ~HSI_CHANNEL_STATE_READING; spin_unlock(&channel->lock); hsi_read_cancel(channel->dev); spin_lock(&channel->lock); } if (channel->state & HSI_CHANNEL_STATE_WRITING) { channel->state &= ~HSI_CHANNEL_STATE_WRITING; spin_unlock(&channel->lock); hsi_write_cancel(channel->dev); } else spin_unlock(&channel->lock); hsi_close(channel->dev); spin_lock(&channel->lock); channel->opened = 0; channel->tx_state = HSI_LL_TX_STATE_CLOSED; channel->rx_state = HSI_LL_RX_STATE_CLOSED; leave: spin_unlock(&channel->lock); return ret; }
static int hsi_init_handshake(struct mipi_link_device *mipi_ld, int mode) { int ret; int i; struct hst_ctx tx_config; struct hsr_ctx rx_config; switch (mode) { case HSI_INIT_MODE_NORMAL: if (timer_pending(&mipi_ld->hsi_acwake_down_timer)) del_timer(&mipi_ld->hsi_acwake_down_timer); for (i = 0; i < HSI_NUM_OF_USE_CHANNELS; i++) { if (mipi_ld->hsi_channles[i].opened) { hsi_write_cancel(mipi_ld->hsi_channles[i].dev); hsi_read_cancel(mipi_ld->hsi_channles[i].dev); } else { ret = if_hsi_open_channel( &mipi_ld->hsi_channles[i]); if (ret) return ret; } mipi_ld->hsi_channles[i].send_step = STEP_IDLE; mipi_ld->hsi_channles[i].recv_step = STEP_IDLE; hsi_ioctl(mipi_ld->hsi_channles[i].dev, HSI_IOCTL_GET_TX, &tx_config); tx_config.mode = 2; tx_config.divisor = 0; /* Speed : 96MHz */ tx_config.channels = HSI_MAX_CHANNELS; hsi_ioctl(mipi_ld->hsi_channles[i].dev, HSI_IOCTL_SET_TX, &tx_config); hsi_ioctl(mipi_ld->hsi_channles[i].dev, HSI_IOCTL_GET_RX, &rx_config); rx_config.mode = 2; rx_config.divisor = 0; /* Speed : 96MHz */ rx_config.channels = HSI_MAX_CHANNELS; hsi_ioctl(mipi_ld->hsi_channles[i].dev, HSI_IOCTL_SET_RX, &rx_config); pr_debug("[MIPI-HSI] Set TX/RX MIPI-HSI\n"); } hsi_ioctl(mipi_ld->hsi_channles[HSI_CONTROL_CHANNEL].dev, HSI_IOCTL_SET_WAKE_RX_4WIRES_MODE, NULL); pr_debug("[MIPI-HSI] Set 4 WIRE MODE\n"); if (mipi_ld->ld.com_state != COM_ONLINE) mipi_ld->ld.com_state = COM_HANDSHAKE; ret = hsi_read(mipi_ld->hsi_channles[HSI_CONTROL_CHANNEL].dev, mipi_ld->hsi_channles[HSI_CONTROL_CHANNEL].rx_data, 1); if (ret) pr_err("[MIPI-HSI] hsi_read fail : %d\n", ret); if (mipi_ld->ld.com_state != COM_ONLINE) schedule_delayed_work(&mipi_ld->start_work, 3 * HZ); pr_debug("[MIPI-HSI] hsi_init_handshake Done : MODE_NORMAL\n"); return 0; case HSI_INIT_MODE_FLASHLESS_BOOT: mipi_ld->ld.com_state = COM_BOOT; if (mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].opened) { hsi_ioctl(mipi_ld->hsi_channles[ HSI_FLASHLESS_CHANNEL].dev, HSI_IOCTL_SW_RESET, NULL); for (i = 0; i < HSI_NUM_OF_USE_CHANNELS; i++) mipi_ld->hsi_channles[i].opened = 0; } if (!mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].opened) if_hsi_open_channel( &mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL]); mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].send_step = STEP_IDLE; mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].recv_step = STEP_IDLE; hsi_ioctl(mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].dev, HSI_IOCTL_GET_TX, &tx_config); tx_config.mode = 2; tx_config.divisor = 3; /* Speed : 24MHz */ tx_config.channels = 1; hsi_ioctl(mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].dev, HSI_IOCTL_SET_TX, &tx_config); hsi_ioctl(mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].dev, HSI_IOCTL_GET_RX, &rx_config); rx_config.mode = 2; rx_config.divisor = 3; /* Speed : 24MHz */ rx_config.channels = 1; hsi_ioctl(mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].dev, HSI_IOCTL_SET_RX, &rx_config); pr_debug("[MIPI-HSI] Set TX/RX MIPI-HSI\n"); hsi_ioctl(mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].dev, HSI_IOCTL_SET_WAKE_RX_3WIRES_MODE, NULL); pr_debug("[MIPI-HSI] Set 3 WIRE MODE\n"); if (!wake_lock_active(&mipi_ld->wlock)) { wake_lock(&mipi_ld->wlock); pr_debug("[MIPI-HSI] wake_lock\n"); } ret = hsi_read(mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].dev, mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].rx_data, 1); if (ret) pr_err("[MIPI-HSI] hsi_read fail : %d\n", ret); pr_debug("[MIPI-HSI] hsi_init_handshake Done : FLASHLESS_BOOT\n"); return 0; case HSI_INIT_MODE_FLASHLESS_BOOT_EBL: mipi_ld->ld.com_state = COM_BOOT_EBL; if (mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].opened) { hsi_ioctl(mipi_ld->hsi_channles[ HSI_FLASHLESS_CHANNEL].dev, HSI_IOCTL_SW_RESET, NULL); for (i = 0; i < HSI_NUM_OF_USE_CHANNELS; i++) mipi_ld->hsi_channles[i].opened = 0; } if (!mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].opened) if_hsi_open_channel( &mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL]); hsi_ioctl(mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].dev, HSI_IOCTL_GET_TX, &tx_config); tx_config.mode = 2; tx_config.divisor = 0; /* Speed : 96MHz */ tx_config.channels = 1; hsi_ioctl(mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].dev, HSI_IOCTL_SET_TX, &tx_config); hsi_ioctl(mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].dev, HSI_IOCTL_GET_RX, &rx_config); rx_config.mode = 2; rx_config.divisor = 0; /* Speed : 96MHz */ rx_config.channels = 1; hsi_ioctl(mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].dev, HSI_IOCTL_SET_RX, &rx_config); pr_debug("[MIPI-HSI] Set TX/RX MIPI-HSI\n"); hsi_ioctl(mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].dev, HSI_IOCTL_SET_WAKE_RX_4WIRES_MODE, NULL); pr_debug("[MIPI-HSI] Set 4 WIRE MODE\n"); if (!wake_lock_active(&mipi_ld->wlock)) { wake_lock(&mipi_ld->wlock); pr_debug("[MIPI-HSI] wake_lock\n"); } if_hsi_set_wakeline( &mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL], 1); ret = hsi_read(mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].dev, mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].rx_data, 1); if (ret) pr_err("[MIPI-HSI] hsi_read fail : %d\n", ret); pr_debug("[MIPI-HSI] hsi_init_handshake Done : FLASHLESS_BOOT_EBL\n"); return 0; case HSI_INIT_MODE_CP_RAMDUMP: mipi_ld->ld.com_state = COM_CRASH; if (mipi_ld->hsi_channles[HSI_CP_RAMDUMP_CHANNEL].opened) { hsi_ioctl(mipi_ld->hsi_channles[ HSI_CP_RAMDUMP_CHANNEL].dev, HSI_IOCTL_SW_RESET, NULL); for (i = 0; i < HSI_NUM_OF_USE_CHANNELS; i++) mipi_ld->hsi_channles[i].opened = 0; } if (!mipi_ld->hsi_channles[HSI_CP_RAMDUMP_CHANNEL].opened) if_hsi_open_channel( &mipi_ld->hsi_channles[HSI_CP_RAMDUMP_CHANNEL]); mipi_ld->hsi_channles[HSI_CP_RAMDUMP_CHANNEL].send_step = STEP_IDLE; mipi_ld->hsi_channles[HSI_CP_RAMDUMP_CHANNEL].recv_step = STEP_IDLE; hsi_ioctl(mipi_ld->hsi_channles[HSI_CP_RAMDUMP_CHANNEL].dev, HSI_IOCTL_GET_TX, &tx_config); tx_config.mode = 2; tx_config.divisor = 0; /* Speed : 96MHz */ tx_config.channels = 1; hsi_ioctl(mipi_ld->hsi_channles[HSI_CP_RAMDUMP_CHANNEL].dev, HSI_IOCTL_SET_TX, &tx_config); hsi_ioctl(mipi_ld->hsi_channles[HSI_CP_RAMDUMP_CHANNEL].dev, HSI_IOCTL_GET_RX, &rx_config); rx_config.mode = 2; rx_config.divisor = 0; /* Speed : 96MHz */ rx_config.channels = 1; hsi_ioctl(mipi_ld->hsi_channles[HSI_CP_RAMDUMP_CHANNEL].dev, HSI_IOCTL_SET_RX, &rx_config); pr_debug("[MIPI-HSI] Set TX/RX MIPI-HSI\n"); hsi_ioctl(mipi_ld->hsi_channles[HSI_CP_RAMDUMP_CHANNEL].dev, HSI_IOCTL_SET_WAKE_RX_4WIRES_MODE, NULL); pr_debug("[MIPI-HSI] Set 4 WIRE MODE\n"); if (!wake_lock_active(&mipi_ld->wlock)) { wake_lock(&mipi_ld->wlock); pr_debug("[MIPI-HSI] wake_lock\n"); } if_hsi_set_wakeline( &mipi_ld->hsi_channles[HSI_CP_RAMDUMP_CHANNEL], 1); ret = hsi_read( mipi_ld->hsi_channles[HSI_CP_RAMDUMP_CHANNEL].dev, mipi_ld->hsi_channles[HSI_CP_RAMDUMP_CHANNEL].rx_data, DUMP_ERR_INFO_SIZE); if (ret) pr_err("[MIPI-HSI] hsi_read fail : %d\n", ret); pr_debug("[MIPI-HSI] hsi_init_handshake Done : RAMDUMP\n"); return 0; default: return -EINVAL; } }