Changes in uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.c [071a1ddb:24abb85d] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.c
r071a1ddb r24abb85d 27 27 */ 28 28 29 /** @addtogroup driver_serial 30 * @{ 31 */ 29 32 /** 30 33 * @file … … 34 37 */ 35 38 39 #include <ddi.h> 40 #include <loc.h> 41 #include <ipc/char.h> 36 42 #include <async.h> 37 #include <ddi.h>38 #include <errno.h>39 #include <inttypes.h>40 #include <io/chardev_srv.h>41 #include <loc.h>42 43 #include <stdio.h> 43 44 #include <stdlib.h> 44 45 #include <sysinfo.h> 46 #include <errno.h> 47 #include <inttypes.h> 45 48 #include "s3c24xx_uart.h" 46 49 … … 65 68 66 69 static void s3c24xx_uart_connection(ipc_callid_t, ipc_call_t *, void *); 67 static void s3c24xx_uart_irq_handler(ipc_call _t *, void *);70 static void s3c24xx_uart_irq_handler(ipc_callid_t, ipc_call_t *, void *); 68 71 static int s3c24xx_uart_init(s3c24xx_uart_t *); 69 72 static void s3c24xx_uart_sendb(s3c24xx_uart_t *, uint8_t); 70 73 71 static int s3c24xx_uart_read(chardev_srv_t *, void *, size_t, size_t *);72 static int s3c24xx_uart_write(chardev_srv_t *, const void *, size_t, size_t *);73 74 static chardev_ops_t s3c24xx_uart_chardev_ops = {75 .read = s3c24xx_uart_read,76 .write = s3c24xx_uart_write77 };78 79 74 int main(int argc, char *argv[]) 80 75 { 81 76 printf("%s: S3C24xx on-chip UART driver\n", NAME); 82 77 83 async_set_fallback_port_handler(s3c24xx_uart_connection, uart);78 async_set_fallback_port_handler(s3c24xx_uart_connection, NULL); 84 79 int rc = loc_server_register(NAME); 85 80 if (rc != EOK) { … … 116 111 void *arg) 117 112 { 118 s3c24xx_uart_t *uart = (s3c24xx_uart_t *) arg; 119 120 chardev_conn(iid, icall, &uart->cds); 121 } 122 123 124 static void s3c24xx_uart_irq_handler(ipc_call_t *call, void *arg) 125 { 126 int rc; 127 113 /* Answer the IPC_M_CONNECT_ME_TO call. */ 114 async_answer_0(iid, EOK); 115 116 while (true) { 117 ipc_call_t call; 118 ipc_callid_t callid = async_get_call(&call); 119 sysarg_t method = IPC_GET_IMETHOD(call); 120 121 if (!method) { 122 /* The other side has hung up. */ 123 async_answer_0(callid, EOK); 124 return; 125 } 126 127 async_sess_t *sess = 128 async_callback_receive_start(EXCHANGE_SERIALIZE, &call); 129 if (sess != NULL) { 130 if (uart->client_sess == NULL) { 131 uart->client_sess = sess; 132 async_answer_0(callid, EOK); 133 } else 134 async_answer_0(callid, ELIMIT); 135 } else { 136 switch (method) { 137 case CHAR_WRITE_BYTE: 138 printf(NAME ": write %" PRIun " to device\n", 139 IPC_GET_ARG1(call)); 140 s3c24xx_uart_sendb(uart, (uint8_t) IPC_GET_ARG1(call)); 141 async_answer_0(callid, EOK); 142 break; 143 default: 144 async_answer_0(callid, EINVAL); 145 } 146 } 147 } 148 } 149 150 static void s3c24xx_uart_irq_handler(ipc_callid_t iid, ipc_call_t *call, 151 void *arg) 152 { 153 (void) iid; 128 154 (void) call; 129 155 (void) arg; … … 133 159 uint32_t status = pio_read_32(&uart->io->uerstat); 134 160 135 fibril_mutex_lock(&uart->buf_lock); 136 137 rc = circ_buf_push(&uart->cbuf, &data); 138 if (rc != EOK) 139 printf(NAME ": Buffer overrun\n"); 140 141 fibril_mutex_unlock(&uart->buf_lock); 142 fibril_condvar_broadcast(&uart->buf_cv); 161 if (uart->client_sess != NULL) { 162 async_exch_t *exch = async_exchange_begin(uart->client_sess); 163 async_msg_1(exch, CHAR_NOTIF_BYTE, data); 164 async_exchange_end(exch); 165 } 143 166 144 167 if (status != 0) … … 153 176 sysarg_t inr; 154 177 155 circ_buf_init(&uart->cbuf, uart->buf, s3c24xx_uart_buf_size, 1);156 fibril_mutex_initialize(&uart->buf_lock);157 fibril_condvar_initialize(&uart->buf_cv);158 159 178 if (sysinfo_get_value("s3c24xx_uart.address.physical", 160 179 &uart->paddr) != EOK) … … 169 188 170 189 uart->io = vaddr; 190 uart->client_sess = NULL; 171 191 172 192 printf(NAME ": device at physical address %p, inr %" PRIun ".\n", 173 193 (void *) uart->paddr, inr); 174 194 175 async_irq_subscribe(inr, s3c24xx_uart_irq_handler, NULL, &uart_irq_code , NULL);195 async_irq_subscribe(inr, s3c24xx_uart_irq_handler, NULL, &uart_irq_code); 176 196 177 197 /* Enable FIFO, Tx trigger level: empty, Rx trigger level: 1 byte. */ … … 183 203 pio_read_32(&uart->io->ucon) & ~UCON_RX_INT_LEVEL); 184 204 185 chardev_srvs_init(&uart->cds);186 uart->cds.ops = &s3c24xx_uart_chardev_ops;187 uart->cds.sarg = uart;188 189 205 return EOK; 190 206 } … … 200 216 } 201 217 202 static int s3c24xx_uart_read(chardev_srv_t *srv, void *buf, size_t size,203 size_t *nread)204 {205 s3c24xx_uart_t *uart = (s3c24xx_uart_t *) srv->srvs->sarg;206 size_t p;207 uint8_t *bp = (uint8_t *) buf;208 int rc;209 210 fibril_mutex_lock(&uart->buf_lock);211 212 while (circ_buf_nused(&uart->cbuf) == 0)213 fibril_condvar_wait(&uart->buf_cv, &uart->buf_lock);214 215 p = 0;216 while (p < size) {217 rc = circ_buf_pop(&uart->cbuf, &bp[p]);218 if (rc != EOK)219 break;220 ++p;221 }222 223 fibril_mutex_unlock(&uart->buf_lock);224 225 *nread = p;226 return EOK;227 }228 229 static int s3c24xx_uart_write(chardev_srv_t *srv, const void *data, size_t size,230 size_t *nwr)231 {232 s3c24xx_uart_t *uart = (s3c24xx_uart_t *) srv->srvs->sarg;233 size_t i;234 uint8_t *dp = (uint8_t *) data;235 236 for (i = 0; i < size; i++)237 s3c24xx_uart_sendb(uart, dp[i]);238 239 *nwr = size;240 return EOK;241 }242 243 244 218 /** @} 245 219 */
Note:
See TracChangeset
for help on using the changeset viewer.