static int uart_close(FAR struct file *filep) { FAR struct inode *inode = filep->f_inode; FAR uart_dev_t *dev = inode->i_private; irqstate_t flags; uart_takesem(&dev->closesem); if (dev->open_count > 1) { dev->open_count--; uart_givesem(&dev->closesem); return OK; } /* There are no more references to the port */ dev->open_count = 0; /* Stop accepting input */ uart_disablerxint(dev); /* Now we wait for the transmit buffer to clear */ while (dev->xmit.head != dev->xmit.tail) { #ifndef CONFIG_DISABLE_SIGNALS usleep(HALF_SECOND_USEC); #else up_mdelay(HALF_SECOND_MSEC); #endif } /* And wait for the TX fifo to drain */ while (!uart_txempty(dev)) { #ifndef CONFIG_DISABLE_SIGNALS usleep(HALF_SECOND_USEC); #else up_mdelay(HALF_SECOND_MSEC); #endif } /* Free the IRQ and disable the UART */ flags = irqsave(); /* Disable interrupts */ uart_detach(dev); /* Detach interrupts */ if (!dev->isconsole) /* Check for the serial console UART */ { uart_shutdown(dev); /* Disable the UART */ } irqrestore(flags); uart_givesem(&dev->closesem); return OK; }
static int uart_close(FAR struct file *filep) { FAR struct inode *inode = filep->f_inode; FAR uart_dev_t *dev = inode->i_private; irqstate_t flags; /* Get exclusive access to the close semaphore (to synchronize open/close operations. * NOTE: that we do not let this wait be interrupted by a signal. Technically, we * should, but almost no one every checks the return value from close() so we avoid * a potential memory leak by ignoring signals in this case. */ (void)uart_takesem(&dev->closesem, false); if (dev->open_count > 1) { dev->open_count--; uart_givesem(&dev->closesem); return OK; } /* There are no more references to the port */ dev->open_count = 0; /* Stop accepting input */ uart_disablerxint(dev); /* Now we wait for the transmit buffer to clear */ while (dev->xmit.head != dev->xmit.tail) { #ifndef CONFIG_DISABLE_SIGNALS usleep(HALF_SECOND_USEC); #else up_mdelay(HALF_SECOND_MSEC); #endif } /* And wait for the TX fifo to drain */ while (!uart_txempty(dev)) { #ifndef CONFIG_DISABLE_SIGNALS usleep(HALF_SECOND_USEC); #else up_mdelay(HALF_SECOND_MSEC); #endif } /* Free the IRQ and disable the UART */ flags = irqsave(); /* Disable interrupts */ uart_detach(dev); /* Detach interrupts */ if (!dev->isconsole) /* Check for the serial console UART */ { uart_shutdown(dev); /* Disable the UART */ } irqrestore(flags); uart_givesem(&dev->closesem); return OK; }
static int uart_close(FAR struct file *filep) { FAR struct inode *inode = filep->f_inode; FAR uart_dev_t *dev = inode->i_private; irqstate_t flags; /* Get exclusive access to the close semaphore (to synchronize open/close operations. * NOTE: that we do not let this wait be interrupted by a signal. Technically, we * should, but almost no one every checks the return value from close() so we avoid * a potential memory leak by ignoring signals in this case. */ (void)uart_takesem(&dev->closesem, false); if (dev->open_count > 1) { dev->open_count--; uart_givesem(&dev->closesem); return OK; } /* There are no more references to the port */ dev->open_count = 0; /* Stop accepting input */ uart_disablerxint(dev); /* Now we wait for the transmit buffer to clear */ while (dev->xmit.head != dev->xmit.tail) { #ifndef CONFIG_DISABLE_SIGNALS usleep(HALF_SECOND_USEC); #else up_mdelay(HALF_SECOND_MSEC); #endif } /* And wait for the TX fifo to drain */ while (!uart_txempty(dev)) { #ifndef CONFIG_DISABLE_SIGNALS usleep(HALF_SECOND_USEC); #else up_mdelay(HALF_SECOND_MSEC); #endif } /* Free the IRQ and disable the UART */ flags = irqsave(); /* Disable interrupts */ uart_detach(dev); /* Detach interrupts */ if (!dev->isconsole) /* Check for the serial console UART */ { uart_shutdown(dev); /* Disable the UART */ } irqrestore(flags); /* We need to re-initialize the semaphores if this is the last close * of the device, as the close might be caused by pthread_cancel() of * a thread currently blocking on any of them. * * REVISIT: This logic *only* works in the case where the cancelled * thread had the only reference to the serial driver. If there other * references, then the this logic will not be executed and the * semaphore count will still be incorrect. */ sem_reinit(&dev->xmitsem, 0, 0); sem_reinit(&dev->recvsem, 0, 0); sem_reinit(&dev->xmit.sem, 0, 1); sem_reinit(&dev->recv.sem, 0, 1); #ifndef CONFIG_DISABLE_POLL sem_reinit(&dev->pollsem, 0, 1); #endif uart_givesem(&dev->closesem); return OK; }