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; }
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; }
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; }
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); }
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; }
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(); }
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; }
void smd_uninit(smd_channel_info_t *ch) { smd_set_state(ch, SMD_SS_CLOSING, 1); smd_notify_rpm(); }