コード例 #1
0
ファイル: smd.c プロジェクト: jaehyek/lk
enum handler_return smd_irq_handler(void* data)
{
	smd_channel_info_t *ch = (smd_channel_info_t*)data;

	if(ch->current_state == SMD_SS_CLOSED)
	{
		free(smd_channel_alloc_entry);
		event_signal(&smd_closed, false);
		return INT_NO_RESCHEDULE;
	}

	if(ch->port_info->ch1.state_updated)
		ch->port_info->ch1.state_updated = 0;

	/* Should we have to use a do while and change states until we complete */
	if(ch->current_state != ch->port_info->ch1.stream_state)
	{
		smd_set_state(ch, ch->port_info->ch1.stream_state, 0);
	}

	if(ch->current_state == SMD_SS_CLOSING)
	{
		smd_set_state(ch, SMD_SS_CLOSED, 1);
		smd_notify_rpm();
		dprintf(CRITICAL,"Channel alloc freed\n");
	}

	return INT_NO_RESCHEDULE;
}
コード例 #2
0
ファイル: smd.c プロジェクト: sndnvaps/lk-1
int smd_init(smd_channel_info_t *ch, uint32_t ch_type)
{
	unsigned ret = 0;

	smd_channel_alloc_entry = (smd_channel_alloc_entry_t*)memalign(CACHE_LINE, SMD_CHANNEL_ALLOC_MAX);
	ASSERT(smd_channel_alloc_entry);

	ret = smem_read_alloc_entry(SMEM_CHANNEL_ALLOC_TBL,
							(void*)smd_channel_alloc_entry,
							SMD_CHANNEL_ALLOC_MAX);
	if(ret)
	{
		dprintf(CRITICAL,"ERROR reading smem channel alloc tbl\n");
		return -1;
	}

	smd_get_channel_info(ch, ch_type);

	register_int_handler(SMD_IRQ, smd_irq_handler, ch);
	unmask_interrupt(SMD_IRQ);

	smd_set_state(ch, SMD_SS_OPENING, 1);

	smd_notify_rpm();

	return 0;
}
コード例 #3
0
ファイル: smd.c プロジェクト: jaehyek/lk
int smd_write(smd_channel_info_t *ch, void *data, uint32_t len, int ch_type)
{
	smd_pkt_hdr smd_hdr;
	uint32_t size = 0;

	memset(&smd_hdr, 0, sizeof(smd_pkt_hdr));

	if(len + sizeof(smd_hdr) > ch->fifo_size)
	{
		dprintf(CRITICAL,"%s: len is greater than fifo sz\n", __func__);
		return -1;
	}

	/* Read the indices from smem */
	ch->port_info = smem_get_alloc_entry(SMEM_SMD_BASE_ID + ch->alloc_entry.cid,
                                                        &size);
	if(!ch->port_info)
	{
		dprintf(CRITICAL,"%s: unable to find index in smem\n", __func__);
		ASSERT(0);
	}

	if(!is_channel_open(ch))
	{
		dprintf(CRITICAL,"%s: channel is not in OPEN state \n", __func__);
		return -1;
	}

	if(!ch->port_info->ch0.DTR_DSR)
	{
		dprintf(CRITICAL,"%s: DTR is off\n", __func__);
		return -1;
	}

	/* Clear the data_read flag */
	ch->port_info->ch1.data_read = 0;

	/*copy the local buf to smd buf */
	smd_hdr.pkt_size = len;

	memcpy_to_fifo(ch, (uint32_t *)&smd_hdr, sizeof(smd_hdr));

	memcpy_to_fifo(ch, data, len);

	dsb();

	/* Set the necessary flags */

	ch->port_info->ch0.data_written = 1;
	ch->port_info->ch0.mask_recv_intr = 0;

	dsb();

	smd_notify_rpm();

	return 0;
}
コード例 #4
0
ファイル: smd.c プロジェクト: jaehyek/lk
void smd_uninit(smd_channel_info_t *ch)
{
	event_init(&smd_closed, false, EVENT_FLAG_AUTOUNSIGNAL);
	smd_set_state(ch, SMD_SS_CLOSING, 1);

	smd_notify_rpm();
	/* Wait for the SMD-RPM channel to be closed */
	event_wait(&smd_closed);
}
コード例 #5
0
ファイル: smd.c プロジェクト: sndnvaps/lk-1
int smd_write(smd_channel_info_t *ch, void *data, uint32_t len, int ch_type)
{
	smd_pkt_hdr smd_hdr;
	uint32_t size = 0;

	memset(&smd_hdr, 0, sizeof(smd_pkt_hdr));

	if(len + sizeof(smd_hdr) > ch->fifo_size)
	{
		dprintf(CRITICAL,"%s: len is greater than fifo sz\n", __func__);
		return -1;
	}

	/* Read the indices from smem */
	ch->port_info = smem_get_alloc_entry(SMEM_SMD_BASE_ID + ch->alloc_entry.cid,
                                                        &size);

	if(!is_channel_open(ch))
	{
		dprintf(CRITICAL,"%s: channel is not in OPEN state \n", __func__);
		return -1;
	}

	if(!ch->port_info->ch0.DTR_DSR)
	{
		dprintf(CRITICAL,"%s: DTR is off\n", __func__);
		return -1;
	}

	/* Clear the data_read flag */
	ch->port_info->ch1.data_read = 0;

	/*copy the local buf to smd buf */
	smd_hdr.pkt_size = len;

	memcpy(ch->send_buf + ch->port_info->ch0.write_index, &smd_hdr, sizeof(smd_hdr));

	memcpy(ch->send_buf + ch->port_info->ch0.write_index + sizeof(smd_hdr), data, len);

	arch_invalidate_cache_range((addr_t)ch->send_buf+ch->port_info->ch0.write_index, sizeof(smd_hdr) + len);

	/* Update write index */
	ch->port_info->ch0.write_index += sizeof(smd_hdr) + len;

	dsb();

	/* Set the necessary flags */

	ch->port_info->ch0.data_written = 1;
	ch->port_info->ch0.mask_recv_intr = 0;

	dsb();

	smd_notify_rpm();

	return 0;
}
コード例 #6
0
ファイル: smd.c プロジェクト: jaehyek/lk
void smd_signal_read_complete(smd_channel_info_t *ch, uint32_t len)
{
	/* Clear the data_written flag */
	ch->port_info->ch1.data_written = 0;

	/* Set the data_read flag */
	ch->port_info->ch0.data_read = 1;
	ch->port_info->ch0.mask_recv_intr = 1;

	dsb();

	smd_notify_rpm();
}
コード例 #7
0
ファイル: smd.c プロジェクト: jaehyek/lk
int smd_init(smd_channel_info_t *ch, uint32_t ch_type)
{
	unsigned ret = 0;
	int chnl_found = 0;
	uint64_t timeout = SMD_CHANNEL_ACCESS_RETRY;

	smd_channel_alloc_entry = (smd_channel_alloc_entry_t*)memalign(CACHE_LINE, SMD_CHANNEL_ALLOC_MAX);
	ASSERT(smd_channel_alloc_entry);

	dprintf(INFO, "Waiting for the RPM to populate smd channel table\n");

	do
	{
		ret = smem_read_alloc_entry(SMEM_CHANNEL_ALLOC_TBL,
									(void*)smd_channel_alloc_entry,
									SMD_CHANNEL_ALLOC_MAX);
		if(ret)
		{
			dprintf(CRITICAL,"ERROR reading smem channel alloc tbl\n");
			return -1;
		}

		chnl_found = smd_get_channel_info(ch, ch_type);
		timeout--;
		udelay(10);
	} while(timeout && chnl_found);

	if (!timeout)
	{
		dprintf(CRITICAL, "Apps timed out waiting for RPM-->APPS channel entry\n");
		ASSERT(0);
	}

	register_int_handler(SMD_IRQ, smd_irq_handler, ch);

	smd_set_state(ch, SMD_SS_OPENING, 1);

	smd_notify_rpm();

	unmask_interrupt(SMD_IRQ);

	return 0;
}
コード例 #8
0
ファイル: smd.c プロジェクト: sndnvaps/lk-1
void smd_uninit(smd_channel_info_t *ch)
{
	smd_set_state(ch, SMD_SS_CLOSING, 1);

	smd_notify_rpm();
}