upgrade rtt 5.2.2

This commit is contained in:
wmano
2025-09-03 20:50:03 +08:00
parent f6985d97c5
commit 5409d3a614
41 changed files with 1130 additions and 988 deletions
@@ -15,7 +15,4 @@ config RT_USING_AUDIO
int "Record pipe size"
default 2048
config RT_UTEST_USING_AUDIO_DRIVER
bool "Enable rt_audio_api testcase"
default n
endif
@@ -210,6 +210,7 @@
#define RT_SERIAL_CTRL_RX_FLUSH 0x45 /* clear rx buffer. Discard all data */
#define RT_SERIAL_CTRL_TX_FLUSH 0x46 /* clear tx buffer. Blocking and wait for the send buffer data to be sent. not supported in poll mode */
#define RT_SERIAL_CTRL_GET_UNREAD_BYTES_COUNT 0x47 /* get unread bytes count. not supported in poll mode */
#define RT_SERIAL_CTRL_GET_CONFIG 0x48 /* get serial config */
#define RT_SERIAL_ERR_OVERRUN 0x01
#define RT_SERIAL_ERR_FRAMING 0x02
@@ -336,7 +337,12 @@ struct rt_serial_device
#ifdef RT_USING_SERIAL_BYPASS
struct rt_serial_bypass* bypass;
#endif
struct rt_device_notify rx_notify;
#ifdef RT_USING_POSIX_STDIO
rt_bool_t is_posix_mode;
#endif
};
/**
@@ -177,6 +177,7 @@ struct rt_pci_msi_desc
#define rt_pci_msix_table_size(flags) ((flags & PCIM_MSIXCTRL_TABLE_SIZE) + 1)
rt_err_t rt_pci_msi_setup_irqs(struct rt_pci_device *pdev, int nvec, int type);
rt_err_t rt_pci_msi_cleanup_irqs(struct rt_pci_device *pdev);
void rt_pci_msi_shutdown(struct rt_pci_device *pdev);
void rt_pci_msix_shutdown(struct rt_pci_device *pdev);
@@ -10,3 +10,5 @@ config RT_PCI_HOST_GENERIC
default y
rsource "dw/Kconfig"
osource "$(SOC_DM_PCI_DIR)/Kconfig"
@@ -204,6 +204,7 @@ void dw_pcie_free_msi(struct dw_pcie_port *port)
rt_dma_free_coherent(pci->dev, sizeof(rt_uint64_t), port->msi_data,
port->msi_data_phy);
port->msi_data = RT_NULL;
}
}
@@ -331,7 +332,8 @@ rt_err_t dw_pcie_host_init(struct dw_pcie_port *port)
{
LOG_E("Invalid count of irq = %d", port->irq_count);
return -RT_EINVAL;
err = -RT_EINVAL;
goto _err_free_cfg;
}
}
@@ -341,7 +343,8 @@ rt_err_t dw_pcie_host_init(struct dw_pcie_port *port)
if (!port->msi_pic)
{
return -RT_ENOMEM;
err = -RT_ENOMEM;
goto _err_free_cfg;
}
port->msi_pic->priv_data = port;
@@ -404,6 +407,13 @@ _err_free_bridge:
rt_pci_host_bridge_free(bridge);
port->bridge = RT_NULL;
_err_free_cfg:
if (port->cfg0_base)
{
rt_iounmap(port->cfg0_base);
port->cfg0_base = RT_NULL;
}
return err;
}
@@ -144,3 +144,42 @@ rt_err_t rt_pci_msi_setup_irqs(struct rt_pci_device *pdev, int nvec, int type)
return err;
}
rt_err_t rt_pci_msi_cleanup_irqs(struct rt_pci_device *pdev)
{
int type;
struct rt_pic *msi_pic;
struct rt_pci_msi_desc *desc;
if (!pdev)
{
return -RT_EINVAL;
}
msi_pic = pdev->msi_pic;
if (!msi_pic)
{
return -RT_EINVAL;
}
desc = rt_pci_msi_first_desc(pdev);
type = desc->is_msix ? PCIY_MSIX : PCIY_MSI;
if (type == PCIY_MSI)
{
for (int idx = 0; idx < desc->vector_used; ++idx)
{
msi_pic->ops->irq_free_msi(msi_pic, desc->irq + idx);
}
}
else if (type == PCIY_MSIX)
{
rt_pci_msi_for_each_desc(pdev, desc)
{
msi_pic->ops->irq_free_msi(msi_pic, desc->irq);
}
}
return RT_EOK;
}
@@ -233,6 +233,8 @@ void rt_pci_msi_free_irqs(struct rt_pci_device *pdev)
pdev->msix_base = RT_NULL;
}
rt_pci_msi_cleanup_irqs(pdev);
rt_pci_msi_for_each_desc(pdev, desc)
{
/* To safety */
+5 -2
View File
@@ -284,7 +284,7 @@ rt_err_t rt_pci_ofw_parse_ranges(struct rt_ofw_node *dev_np,
phy_addr_cells, phy_size_cells, cpu_addr_cells,
&host_bridge->dma_regions, &host_bridge->dma_regions_nr);
if (err != -RT_EEMPTY)
if (err && err != -RT_EEMPTY)
{
rt_free(host_bridge->bus_regions);
host_bridge->bus_regions_nr = 0;
@@ -314,7 +314,10 @@ rt_err_t rt_pci_ofw_host_bridge_init(struct rt_ofw_node *dev_np,
if (rt_ofw_prop_read_u32_array_index(dev_np, "bus-range", 0, 2, host_bridge->bus_range) < 0)
{
return -RT_EIO;
host_bridge->bus_range[0] = 0x00;
host_bridge->bus_range[1] = 0xff;
LOG_I("%s: No \"%s\" found, using [%#02x, %#02x]", rt_ofw_node_full_name(dev_np), "bus-range",
host_bridge->bus_range[0], host_bridge->bus_range[1]);
}
propname = rt_ofw_get_prop_fuzzy_name(dev_np, ",pci-domain$");
@@ -1463,9 +1463,8 @@ void rt_hw_serial_isr(struct rt_serial_device *serial, int event)
/* if the next position is read index, discard this 'read char' */
if (rx_fifo->put_index == rx_fifo->get_index)
{
rx_fifo->get_index += 1;
rx_fifo->get_index = rx_fifo->put_index;
rx_fifo->is_full = RT_TRUE;
if (rx_fifo->get_index >= serial->config.bufsz) rx_fifo->get_index = 0;
_serial_check_buffer_size();
}
@@ -61,9 +61,10 @@ static rt_err_t serial_fops_rx_ind(rt_device_t dev, rt_size_t size)
/* fops for serial */
static int serial_fops_open(struct dfs_file *fd)
{
rt_err_t ret = 0;
rt_uint16_t flags = 0;
rt_device_t device;
rt_err_t ret = 0;
rt_uint16_t flags = 0;
rt_device_t device;
struct rt_serial_device *serial;
device = (rt_device_t)fd->vnode->data;
RT_ASSERT(device != RT_NULL);
@@ -89,8 +90,14 @@ static int serial_fops_open(struct dfs_file *fd)
if ((fd->flags & O_ACCMODE) != O_WRONLY)
rt_device_set_rx_indicate(device, serial_fops_rx_ind);
rt_device_close(device);
ret = rt_device_open(device, flags | RT_SERIAL_RX_BLOCKING | RT_SERIAL_TX_BLOCKING);
if (ret == RT_EOK) return 0;
if (ret == RT_EOK)
{
serial = (struct rt_serial_device *)device;
serial->is_posix_mode = RT_TRUE;
}
return ret;
}
@@ -125,6 +132,8 @@ static int serial_fops_ioctl(struct dfs_file *fd, int cmd, void *args)
fd->flags &= ~mask;
fd->flags |= flags;
break;
default:
break;
}
return rt_device_control(device, cmd, args);
@@ -204,13 +213,10 @@ static ssize_t serial_fops_write(struct dfs_file *fd, const void *buf, size_t co
static int serial_fops_flush(struct dfs_file *fd)
{
rt_device_t device;
struct rt_serial_device *serial;
rt_device_t device;
device = (rt_device_t)fd->vnode->data;
RT_ASSERT(device != RT_NULL);
serial = (struct rt_serial_device *)device;
rt_device_control(device, RT_SERIAL_CTRL_TX_FLUSH, (void *)RT_NULL);
rt_device_control(device, RT_SERIAL_CTRL_RX_FLUSH, (void *)RT_NULL);
@@ -379,8 +385,8 @@ rt_ssize_t _serial_poll_rx(struct rt_device *dev,
int getc_element; /* Gets one byte of data received */
rt_uint8_t *getc_buffer; /* Pointer to the receive data buffer */
if (size == 0) return 0;
RT_ASSERT(dev != RT_NULL && buffer != RT_NULL);
if (size == 0) return 0;
serial = (struct rt_serial_device *)dev;
getc_buffer = (rt_uint8_t *)buffer;
@@ -389,7 +395,7 @@ rt_ssize_t _serial_poll_rx(struct rt_device *dev,
while (size)
{
getc_element = serial->ops->getc(serial);
if (getc_element == -1) break;
if (getc_element < 0) break;
*getc_buffer = getc_element;
@@ -424,6 +430,7 @@ rt_ssize_t _serial_poll_tx(struct rt_device *dev,
struct rt_serial_device *serial;
rt_size_t putc_size;
rt_uint8_t *putc_buffer; /* Pointer to the transmit data buffer */
int putc_result;
if (size == 0) return 0;
RT_ASSERT(dev != RT_NULL && buffer != RT_NULL);
@@ -441,7 +448,8 @@ rt_ssize_t _serial_poll_tx(struct rt_device *dev,
if (*putc_buffer == '\n')
serial->ops->putc(serial, '\r');
}
serial->ops->putc(serial, *putc_buffer);
putc_result = serial->ops->putc(serial, *putc_buffer);
if (putc_result < 0) break;
++putc_buffer;
--size;
@@ -461,7 +469,7 @@ rt_ssize_t _serial_poll_tx(struct rt_device *dev,
* @param pos Empty parameter.
* @param buffer Receive data buffer.
* @param size Receive data buffer length.
* @return Returns the actual length of data received. If a timeout occurs in blocking mode, it returns -RT_ETIMEOUT.
* @return Returns the actual length of data received.
*/
static rt_ssize_t _serial_fifo_rx(struct rt_device *dev,
rt_off_t pos,
@@ -482,15 +490,15 @@ static rt_ssize_t _serial_fifo_rx(struct rt_device *dev,
if (dev->open_flag & RT_SERIAL_RX_BLOCKING)
{
rt_size_t data_len;
rt_tick_t now_tick;
rt_tick_t delta_tick;
rt_size_t rx_bufsz_third = serial->config.rx_bufsz / 2;
rt_int32_t base_rx_timeout = rt_atomic_load(&rx_fifo->rx_timeout);
rt_int32_t rx_timeout = base_rx_timeout;
rt_int32_t rx_timeout_left = base_rx_timeout;
rt_tick_t begin_tick = rt_tick_get();
while (1)
{
if (rx_timeout != RT_WAITING_NO)
if (rx_timeout_left != RT_WAITING_NO)
{
level = rt_spin_lock_irqsave(&serial->spinlock);
data_len = rt_ringbuffer_data_len(&rx_fifo->rb);
@@ -512,26 +520,24 @@ static rt_ssize_t _serial_fifo_rx(struct rt_device *dev,
level = RT_SERIAL_FIFO_LOCK(&serial->spinlock);
recv_size += rt_ringbuffer_get(&rx_fifo->rb, (rt_uint8_t *)buffer + recv_size, size - recv_size);
RT_SERIAL_FIFO_UNLOCK(&serial->spinlock, level);
if (recv_size == size || rx_timeout == RT_WAITING_NO)
if (recv_size == size || rx_timeout_left == RT_WAITING_NO)
{
break;
}
rt_completion_wait(&rx_fifo->rx_cpt, rx_timeout);
if (rx_timeout != RT_WAITING_FOREVER)
rt_completion_wait(&rx_fifo->rx_cpt, rx_timeout_left);
if (rx_timeout_left != RT_WAITING_FOREVER)
{
now_tick = rt_tick_get();
if (now_tick - begin_tick >= base_rx_timeout)
delta_tick = rt_tick_get_delta(begin_tick);
if (delta_tick >= base_rx_timeout)
{
return -RT_ETIMEOUT;
}
else
{
if (now_tick > begin_tick)
rx_timeout = base_rx_timeout - (now_tick - begin_tick);
else
rx_timeout = begin_tick + base_rx_timeout - now_tick + 1;
level = RT_SERIAL_FIFO_LOCK(&serial->spinlock);
recv_size += rt_ringbuffer_get(&rx_fifo->rb, (rt_uint8_t *)buffer + recv_size, size - recv_size);
RT_SERIAL_FIFO_UNLOCK(&serial->spinlock, level);
return recv_size;
}
rx_timeout_left = base_rx_timeout - delta_tick;
}
}
}
@@ -554,7 +560,7 @@ static rt_ssize_t _serial_fifo_rx(struct rt_device *dev,
* @param pos Empty parameter.
* @param buffer Transmit data buffer.
* @param size Transmit data buffer length.
* @return Returns the actual length of data transmitted. If a timeout occurs, it returns -RT_ETIMEOUT.
* @return Returns the actual length of data transmitted.
*/
static rt_ssize_t _serial_fifo_tx_blocking_nbuf(struct rt_device *dev,
rt_off_t pos,
@@ -594,28 +600,29 @@ static rt_ssize_t _serial_fifo_tx_blocking_nbuf(struct rt_device *dev,
(rt_uint8_t *)buffer,
size,
RT_SERIAL_TX_BLOCKING);
if (send_size <= 0)
{
return 0;
}
if (rt_atomic_load(&tx_fifo->tx_timeout) == RT_WAITING_NO)
{
return send_size;
/* The implementation of POSIX nonblock mode is to set tx_timeout to RT_WAITING_NO */
#ifdef RT_USING_POSIX_STDIO
if (serial->is_posix_mode)
return send_size;
#endif
return 0;
}
/* Waiting for the transmission to complete */
ret = rt_completion_wait(&tx_fifo->tx_cpt, rt_atomic_load(&tx_fifo->tx_timeout));
if (ret != RT_EOK)
{
if (ret == -RT_ETIMEOUT)
{
return ret;
}
else
{
return 0;
}
/* Cannot get the number of bytes sent under DMA, so returns 0 directly */
return 0;
}
/* Inactive tx mode flag */
rt_atomic_flag_clear(&tx_fifo->activated);
return send_size;
}
@@ -626,7 +633,7 @@ static rt_ssize_t _serial_fifo_tx_blocking_nbuf(struct rt_device *dev,
* @param pos Empty parameter.
* @param buffer Transmit data buffer.
* @param size Transmit data buffer length.
* @return Returns the final length of data transmitted. If not all data can be sent within the timeout period, returns -RT_ETIMEOUT.
* @return Returns the final length of data transmitted.
*/
static rt_ssize_t _serial_fifo_tx_blocking_buf(struct rt_device *dev,
rt_off_t pos,
@@ -657,11 +664,13 @@ static rt_ssize_t _serial_fifo_tx_blocking_buf(struct rt_device *dev,
return 0;
}
rt_tick_t now_tick;
rt_tick_t delta_tick;
rt_int32_t base_tx_timeout = rt_atomic_load(&tx_fifo->tx_timeout);
rt_int32_t tx_timeout = base_tx_timeout;
rt_int32_t tx_timeout_left = base_tx_timeout;
rt_tick_t begin_tick = rt_tick_get();
rt_size_t send_size = 0;
rt_size_t rb_size;
rt_ssize_t transmit_size;
while (send_size != size)
{
@@ -671,6 +680,7 @@ static rt_ssize_t _serial_fifo_tx_blocking_buf(struct rt_device *dev,
tx_fifo->put_size = rt_ringbuffer_put(&tx_fifo->rb,
(rt_uint8_t *)buffer + send_size,
size - send_size);
rb_size = rt_ringbuffer_data_len(&tx_fifo->rb);
RT_SERIAL_FIFO_UNLOCK(&serial->spinlock, level);
/* clear tx_cpt flag */
@@ -679,39 +689,44 @@ static rt_ssize_t _serial_fifo_tx_blocking_buf(struct rt_device *dev,
/* Call the transmit interface for transmission again */
/* Note that in interrupt mode, buffer and tx_fifo->put_size
* are inactive parameters */
serial->ops->transmit(serial,
(rt_uint8_t *)buffer + send_size,
tx_fifo->put_size,
RT_SERIAL_TX_BLOCKING);
send_size += tx_fifo->put_size;
if (tx_timeout == RT_WAITING_NO)
transmit_size = serial->ops->transmit(serial,
(rt_uint8_t *)buffer + send_size,
tx_fifo->put_size,
RT_SERIAL_TX_BLOCKING);
if (transmit_size <= 0)
{
return send_size;
}
if (tx_timeout_left == RT_WAITING_NO)
{
/* The implementation of POSIX nonblock mode is to set tx_timeout to RT_WAITING_NO */
#ifdef RT_USING_POSIX_STDIO
if (serial->is_posix_mode)
send_size += tx_fifo->put_size;
#endif
break;
}
/* Waiting for the transmission to complete */
rt_completion_wait(&tx_fifo->tx_cpt, tx_timeout);
if (tx_timeout != RT_WAITING_FOREVER)
rt_completion_wait(&tx_fifo->tx_cpt, tx_timeout_left);
if (tx_timeout_left != RT_WAITING_FOREVER)
{
now_tick = rt_tick_get();
if (now_tick - begin_tick >= base_tx_timeout)
delta_tick = rt_tick_get_delta(begin_tick);
if (delta_tick >= base_tx_timeout)
{
return -RT_ETIMEOUT;
}
else
{
if (now_tick > begin_tick)
tx_timeout = base_tx_timeout - (now_tick - begin_tick);
else
tx_timeout = begin_tick + base_tx_timeout - now_tick + 1;
level = RT_SERIAL_FIFO_LOCK(&serial->spinlock);
send_size += rb_size - rt_ringbuffer_data_len(&tx_fifo->rb);
RT_SERIAL_FIFO_UNLOCK(&serial->spinlock, level);
return send_size;
}
tx_timeout_left = base_tx_timeout - delta_tick;
}
send_size += tx_fifo->put_size;
}
/* Finally Inactivate the tx->fifo */
rt_atomic_flag_clear(&tx_fifo->activated);
return send_size;
}
@@ -734,7 +749,8 @@ static rt_ssize_t _serial_fifo_tx_nonblocking(struct rt_device *dev,
struct rt_serial_tx_fifo *tx_fifo;
rt_uint8_t *put_ptr;
rt_base_t level;
rt_size_t send_size = 0;
rt_size_t send_size;
rt_ssize_t transmit_size;
if (size == 0) return 0;
RT_ASSERT(dev != RT_NULL && buffer != RT_NULL);
@@ -761,10 +777,14 @@ static rt_ssize_t _serial_fifo_tx_nonblocking(struct rt_device *dev,
/* Call the transmit interface for transmission again */
/* Note that in interrupt mode, put_ptr and tx_fifo->put_size
* are inactive parameters */
serial->ops->transmit(serial,
put_ptr,
tx_fifo->put_size,
RT_SERIAL_TX_NON_BLOCKING);
transmit_size = serial->ops->transmit(serial,
put_ptr,
tx_fifo->put_size,
RT_SERIAL_TX_NON_BLOCKING);
if (transmit_size <= 0)
{
return 0;
}
/* In tx_nonblocking mode, there is no need to call rt_completion_wait() APIs to wait
* for the rt_current_thread to resume */
return send_size;
@@ -794,7 +814,8 @@ static rt_err_t rt_serial_tx_enable(struct rt_device *dev,
rt_uint16_t tx_oflag)
{
struct rt_serial_device *serial;
struct rt_serial_tx_fifo *tx_fifo = RT_NULL;
struct rt_serial_tx_fifo *tx_fifo = RT_NULL;
rt_err_t control_result = RT_EOK;
RT_ASSERT(dev != RT_NULL);
serial = (struct rt_serial_device *)dev;
@@ -824,11 +845,16 @@ static rt_err_t rt_serial_tx_enable(struct rt_device *dev,
{
/* When using RT_SERIAL_TX_BLOCKING, it is necessary to determine
* whether serial device needs to use buffer */
rt_err_t optmode; /* The operating mode used by serial device */
/* Call the Control() API to get the operating mode */
optmode = serial->ops->control(serial,
RT_DEVICE_CHECK_OPTMODE,
(void *)RT_DEVICE_FLAG_TX_BLOCKING);
control_result = serial->ops->control(serial,
RT_DEVICE_CHECK_OPTMODE,
(void *)RT_DEVICE_FLAG_TX_BLOCKING);
if (control_result < 0)
{
return control_result;
}
rt_err_t optmode = control_result;
if (optmode == RT_SERIAL_TX_BLOCKING_BUFFER)
{
/* If use RT_SERIAL_TX_BLOCKING_BUFFER, the ringbuffer is initialized */
@@ -844,7 +870,7 @@ static rt_err_t rt_serial_tx_enable(struct rt_device *dev,
dev->write = _serial_fifo_tx_blocking_buf;
#endif
}
else
else if (optmode == RT_SERIAL_TX_BLOCKING_NO_BUFFER)
{
/* If not use RT_SERIAL_TX_BLOCKING_BUFFER,
* the control() API is called to configure the serial device */
@@ -860,9 +886,17 @@ static rt_err_t rt_serial_tx_enable(struct rt_device *dev,
#endif
/* Call the control() API to configure the serial device by RT_SERIAL_TX_BLOCKING*/
serial->ops->control(serial,
RT_DEVICE_CTRL_CONFIG,
(void *)RT_SERIAL_TX_BLOCKING);
control_result = serial->ops->control(serial,
RT_DEVICE_CTRL_CONFIG,
(void *)RT_SERIAL_TX_BLOCKING);
if (control_result < 0)
{
goto __exit;
}
}
else
{
return -RT_EIO;
}
rt_atomic_flag_clear(&tx_fifo->activated);
tx_fifo->put_size = 0;
@@ -897,11 +931,12 @@ static rt_err_t rt_serial_tx_enable(struct rt_device *dev,
dev->open_flag |= RT_SERIAL_TX_NON_BLOCKING;
/* Call the control() API to configure the serial device by RT_SERIAL_TX_NON_BLOCKING*/
serial->ops->control(serial,
RT_DEVICE_CTRL_CONFIG,
(void *)RT_SERIAL_TX_NON_BLOCKING);
control_result = serial->ops->control(serial,
RT_DEVICE_CTRL_CONFIG,
(void *)RT_SERIAL_TX_NON_BLOCKING);
return RT_EOK;
__exit:
return control_result;
}
@@ -974,11 +1009,7 @@ static rt_err_t rt_serial_rx_enable(struct rt_device *dev,
{
dev->open_flag |= RT_SERIAL_RX_NON_BLOCKING;
/* Call the control() API to configure the serial device by RT_SERIAL_RX_NON_BLOCKING*/
serial->ops->control(serial,
RT_DEVICE_CTRL_CONFIG,
(void *)RT_SERIAL_RX_NON_BLOCKING);
return RT_EOK;
return serial->ops->control(serial, RT_DEVICE_CTRL_CONFIG, (void *)RT_SERIAL_RX_NON_BLOCKING);
}
/* When using RT_SERIAL_RX_BLOCKING, rt_completion_init() and rx_cpt_index are initialized */
@@ -988,11 +1019,7 @@ static rt_err_t rt_serial_rx_enable(struct rt_device *dev,
rt_completion_init(&rx_fifo->rx_cpt);
dev->open_flag |= RT_SERIAL_RX_BLOCKING;
/* Call the control() API to configure the serial device by RT_SERIAL_RX_BLOCKING*/
serial->ops->control(serial,
RT_DEVICE_CTRL_CONFIG,
(void *)RT_SERIAL_RX_BLOCKING);
return RT_EOK;
return serial->ops->control(serial, RT_DEVICE_CTRL_CONFIG, (void *)RT_SERIAL_RX_BLOCKING);
}
/**
@@ -1016,23 +1043,27 @@ static rt_err_t rt_serial_rx_disable(struct rt_device *dev,
if (serial->serial_rx == RT_NULL) return RT_EOK;
rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx;
RT_ASSERT(rx_fifo != RT_NULL);
if (rx_oflag == RT_SERIAL_RX_NON_BLOCKING)
{
dev->open_flag &= ~RT_SERIAL_RX_NON_BLOCKING;
/* disable ignore return value */
serial->ops->control(serial,
RT_DEVICE_CTRL_CLR_INT,
(void *)RT_SERIAL_RX_NON_BLOCKING);
}
else
{
rt_completion_done(&rx_fifo->rx_cpt);
dev->open_flag &= ~RT_SERIAL_RX_BLOCKING;
/* disable ignore return value */
serial->ops->control(serial,
RT_DEVICE_CTRL_CLR_INT,
(void *)RT_SERIAL_RX_BLOCKING);
}
rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx;
RT_ASSERT(rx_fifo != RT_NULL);
rt_free(rx_fifo);
serial->serial_rx = RT_NULL;
@@ -1066,7 +1097,7 @@ static rt_err_t rt_serial_tx_disable(struct rt_device *dev,
if (tx_oflag == RT_SERIAL_TX_NON_BLOCKING)
{
dev->open_flag &= ~RT_SERIAL_TX_NON_BLOCKING;
/* disable ignore return value */
serial->ops->control(serial,
RT_DEVICE_CTRL_CLR_INT,
(void *)RT_SERIAL_TX_NON_BLOCKING);
@@ -1075,6 +1106,7 @@ static rt_err_t rt_serial_tx_disable(struct rt_device *dev,
{
rt_completion_done(&tx_fifo->tx_cpt);
dev->open_flag &= ~RT_SERIAL_TX_BLOCKING;
/* disable ignore return value */
serial->ops->control(serial,
RT_DEVICE_CTRL_CLR_INT,
(void *)RT_SERIAL_TX_BLOCKING);
@@ -1111,6 +1143,36 @@ static rt_err_t rt_serial_init(struct rt_device *dev)
return result;
}
/**
* @brief Close the serial device.
* @param dev The pointer of device driver structure
* @return Return the status of the operation.
*/
static rt_err_t rt_serial_close(struct rt_device *dev)
{
struct rt_serial_device *serial;
RT_ASSERT(dev != RT_NULL);
serial = (struct rt_serial_device *)dev;
/* Disable serial receive mode. */
rt_serial_rx_disable(dev, dev->open_flag & (RT_SERIAL_RX_BLOCKING | RT_SERIAL_RX_NON_BLOCKING));
/* Disable serial tranmit mode. */
rt_serial_tx_disable(dev, dev->open_flag & (RT_SERIAL_TX_BLOCKING | RT_SERIAL_TX_NON_BLOCKING));
/* Clear the callback function */
serial->parent.rx_indicate = RT_NULL;
serial->parent.tx_complete = RT_NULL;
rt_memset(&serial->rx_notify, RT_NULL, sizeof(struct rt_device_notify));
/* Call the control() API to close the serial device. disable ignore return value */
serial->ops->control(serial, RT_DEVICE_CTRL_CLOSE, RT_NULL);
dev->flag &= ~RT_DEVICE_FLAG_ACTIVATED;
return RT_EOK;
}
/**
* @brief Open the serial device.
* @param dev The pointer of device driver structure
@@ -1120,19 +1182,12 @@ static rt_err_t rt_serial_init(struct rt_device *dev)
static rt_err_t rt_serial_open(struct rt_device *dev, rt_uint16_t oflag)
{
struct rt_serial_device *serial;
rt_err_t result = RT_EOK;
RT_ASSERT(dev != RT_NULL);
serial = (struct rt_serial_device *)dev;
/* Check that the device has been turned on */
if ((dev->open_flag) & (15 << 12))
{
LOG_D("(%s) serial device has already been opened, it will run in its original configuration", dev->parent.name);
return RT_EOK;
}
LOG_D("open serial device: 0x%08x with open flag: 0x%04x",
dev, oflag);
LOG_D("open serial device: 0x%08x with open flag: 0x%04x", dev, oflag);
/* By default, the receive mode of a serial devide is RT_SERIAL_RX_NON_BLOCKING */
if ((oflag & RT_SERIAL_RX_BLOCKING) == RT_SERIAL_RX_BLOCKING)
@@ -1152,48 +1207,31 @@ static rt_err_t rt_serial_open(struct rt_device *dev, rt_uint16_t oflag)
/* initialize the Rx structure according to open flag */
if (serial->serial_rx == RT_NULL)
rt_serial_rx_enable(dev, dev->open_flag & (RT_SERIAL_RX_BLOCKING | RT_SERIAL_RX_NON_BLOCKING));
{
result = rt_serial_rx_enable(dev, dev->open_flag & (RT_SERIAL_RX_BLOCKING | RT_SERIAL_RX_NON_BLOCKING));
if (result != RT_EOK)
{
rt_serial_close(dev);
goto __exit;
}
}
/* initialize the Tx structure according to open flag */
if (serial->serial_tx == RT_NULL)
rt_serial_tx_enable(dev, dev->open_flag & (RT_SERIAL_TX_BLOCKING | RT_SERIAL_TX_NON_BLOCKING));
{
result = rt_serial_tx_enable(dev, dev->open_flag & (RT_SERIAL_TX_BLOCKING | RT_SERIAL_TX_NON_BLOCKING));
if (result != RT_EOK)
{
rt_serial_close(dev);
goto __exit;
}
}
return RT_EOK;
__exit:
return result;
}
/**
* @brief Close the serial device.
* @param dev The pointer of device driver structure
* @return Return the status of the operation.
*/
static rt_err_t rt_serial_close(struct rt_device *dev)
{
struct rt_serial_device *serial;
RT_ASSERT(dev != RT_NULL);
serial = (struct rt_serial_device *)dev;
/* this device has more reference count */
if (dev->ref_count > 1) return -RT_ERROR;
/* Disable serial receive mode. */
rt_serial_rx_disable(dev, dev->open_flag & (RT_SERIAL_RX_BLOCKING | RT_SERIAL_RX_NON_BLOCKING));
/* Disable serial tranmit mode. */
rt_serial_tx_disable(dev, dev->open_flag & (RT_SERIAL_TX_BLOCKING | RT_SERIAL_TX_NON_BLOCKING));
/* Clear the callback function */
serial->parent.rx_indicate = RT_NULL;
serial->parent.tx_complete = RT_NULL;
rt_memset(&serial->rx_notify, RT_NULL, sizeof(struct rt_device_notify));
/* Call the control() API to close the serial device */
serial->ops->control(serial, RT_DEVICE_CTRL_CLOSE, RT_NULL);
dev->flag &= ~RT_DEVICE_FLAG_ACTIVATED;
return RT_EOK;
}
static void _serial_rx_flush(struct rt_serial_device *serial)
{
rt_base_t level;
@@ -1202,8 +1240,10 @@ static void _serial_rx_flush(struct rt_serial_device *serial)
if (serial->config.rx_bufsz == 0)
{
while (serial->ops->getc(serial) != -1)
rt_uint32_t rx_flush_limit = 0xFFFFFFF;
while (serial->ops->getc(serial) != -1 && rx_flush_limit > 0)
{
rx_flush_limit--;
}
}
else
@@ -1235,7 +1275,6 @@ static void _serial_tx_flush(struct rt_serial_device *serial)
if (rt_atomic_load(&tx_fifo->activated))
{
rt_completion_wait(&tx_fifo->tx_cpt, RT_WAITING_FOREVER);
return;
}
}
}
@@ -1252,15 +1291,14 @@ static rt_err_t _serial_get_unread_bytes_count(struct rt_serial_device *serial,
*unread_bytes = -1;
return -RT_EPERM;
}
else
{
rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx;
RT_ASSERT(rx_fifo != RT_NULL);
level = RT_SERIAL_FIFO_LOCK(&serial->spinlock);
*unread_bytes = rt_ringbuffer_data_len(&rx_fifo->rb);
RT_SERIAL_FIFO_UNLOCK(&serial->spinlock, level);
}
rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx;
RT_ASSERT(rx_fifo != RT_NULL);
level = RT_SERIAL_FIFO_LOCK(&serial->spinlock);
*unread_bytes = rt_ringbuffer_data_len(&rx_fifo->rb);
RT_SERIAL_FIFO_UNLOCK(&serial->spinlock, level);
return RT_EOK;
}
@@ -1384,6 +1422,17 @@ static rt_err_t rt_serial_control(struct rt_device *dev,
serial->ops->configure(serial, (struct serial_configure *)args);
}
break;
case RT_SERIAL_CTRL_GET_CONFIG:
if (args == RT_NULL)
{
ret = -RT_EINVAL;
}
else
{
struct serial_configure *pconfig = (struct serial_configure *)args;
*pconfig = serial->config;
}
break;
case RT_DEVICE_CTRL_NOTIFY_SET:
if (args == RT_NULL)
{
@@ -1402,7 +1451,7 @@ static rt_err_t rt_serial_control(struct rt_device *dev,
}
else
{
*(rt_uint16_t *)args = RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM;
*(rt_uint16_t *)args = RT_DEVICE_FLAG_RDWR | RT_SERIAL_RX_BLOCKING | RT_SERIAL_TX_BLOCKING | RT_DEVICE_FLAG_STREAM;
}
break;
@@ -1944,21 +1993,17 @@ void rt_hw_serial_isr(struct rt_serial_device *serial, int event)
#ifdef RT_SERIAL_BUF_STRATEGY_DROP
rt_uint8_t *ptr;
rt_size_t size;
rt_size_t space_len;
rt_size_t put_len;
/* UART_IT_IDLE and dma isr */
level = rt_spin_lock_irqsave(&serial->spinlock);
do
{
space_len = rt_ringbuffer_space_len(&rx_fifo->rb);
if (space_len == 0)
break;
rt_serial_update_write_index(&rx_fifo->dma_ping_rb, rx_length);
size = rt_ringbuffer_peek(&rx_fifo->dma_ping_rb, &ptr);
space_len -= rt_ringbuffer_put(&rx_fifo->rb, ptr, size);
if (space_len == 0)
put_len = rt_ringbuffer_put(&rx_fifo->rb, ptr, size);
if (put_len != size)
break;
size = rt_ringbuffer_peek(&rx_fifo->dma_ping_rb, &ptr);
@@ -1973,9 +2018,10 @@ void rt_hw_serial_isr(struct rt_serial_device *serial, int event)
rt_size_t size;
/* UART_IT_IDLE and dma isr */
level = rt_spin_lock_irqsave(&serial->spinlock);
rt_serial_update_write_index(&rx_fifo->dma_ping_rb, rx_length);
do
{
rt_serial_update_write_index(&rx_fifo->dma_ping_rb, rx_length);
size = rt_ringbuffer_peek(&rx_fifo->dma_ping_rb, &ptr);
rt_ringbuffer_put_force(&rx_fifo->rb, ptr, size);
@@ -2022,8 +2068,9 @@ void rt_hw_serial_isr(struct rt_serial_device *serial, int event)
/* Interrupt transmit event */
case RT_SERIAL_EVENT_TX_DONE: {
struct rt_serial_tx_fifo *tx_fifo;
rt_size_t tx_length = 0;
tx_fifo = (struct rt_serial_tx_fifo *)serial->serial_tx;
rt_size_t tx_length;
rt_ssize_t transmit_size;
tx_fifo = (struct rt_serial_tx_fifo *)serial->serial_tx;
RT_ASSERT(tx_fifo != RT_NULL);
/* Get the length of the data from the ringbuffer */
@@ -2049,22 +2096,28 @@ void rt_hw_serial_isr(struct rt_serial_device *serial, int event)
/* Call the transmit interface for transmission again */
/* Note that in interrupt mode, tx_fifo->buffer and tx_length
* are inactive parameters */
serial->ops->transmit(serial,
tx_fifo->rb.buffer_ptr,
tx_length,
serial->parent.open_flag & (RT_SERIAL_TX_BLOCKING | RT_SERIAL_TX_NON_BLOCKING));
transmit_size = serial->ops->transmit(serial,
tx_fifo->rb.buffer_ptr,
tx_length,
serial->parent.open_flag & (RT_SERIAL_TX_BLOCKING | RT_SERIAL_TX_NON_BLOCKING));
if (transmit_size <= 0)
{
rt_atomic_flag_clear(&tx_fifo->activated);
}
break;
}
#ifdef RT_SERIAL_USING_DMA
case RT_SERIAL_EVENT_TX_DMADONE: {
struct rt_serial_tx_fifo *tx_fifo;
rt_size_t tx_length = 0;
tx_fifo = (struct rt_serial_tx_fifo *)serial->serial_tx;
rt_size_t tx_length;
rt_ssize_t transmit_size;
tx_fifo = (struct rt_serial_tx_fifo *)serial->serial_tx;
RT_ASSERT(tx_fifo != RT_NULL);
if ((serial->parent.open_flag & RT_SERIAL_TX_BLOCKING) != RT_SERIAL_TX_BLOCKING || rt_ringbuffer_get_size(&tx_fifo->rb) != 0)
/* nonblock */
if ((serial->parent.open_flag & RT_SERIAL_TX_BLOCKING) != RT_SERIAL_TX_BLOCKING)
{
// 每次进来中断就说明之前的put_size已经被发送完毕了
/* Each interruption upon entry indicates that the previous `put_size` has already been sent completely */
rt_serial_update_read_index(&tx_fifo->rb, tx_fifo->put_size);
/* Get the length of the data from the ringbuffer */
@@ -2076,15 +2129,19 @@ void rt_hw_serial_isr(struct rt_serial_device *serial, int event)
* then call the transmit interface for transmission again */
rt_atomic_flag_test_and_set(&tx_fifo->activated);
rt_uint8_t *put_ptr = RT_NULL;
rt_uint8_t *put_ptr;
/* Get the linear length buffer from ringbuffer */
tx_fifo->put_size = rt_serial_get_linear_buffer(&tx_fifo->rb, &put_ptr);
/* Call the transmit interface for transmission again */
serial->ops->transmit(serial,
put_ptr,
tx_fifo->put_size,
RT_SERIAL_TX_NON_BLOCKING);
transmit_size = serial->ops->transmit(serial,
put_ptr,
tx_fifo->put_size,
RT_SERIAL_TX_NON_BLOCKING);
if (transmit_size <= 0)
{
rt_atomic_flag_clear(&tx_fifo->activated);
}
break;
}
}
@@ -255,7 +255,7 @@ _fail:
static rt_err_t pwm_fan_cool_remove(struct rt_platform_device *pdev)
{
struct pwm_fan_cool *pf_cool = pdev->parent.ofw_node;
struct pwm_fan_cool *pf_cool = pdev->parent.user_data;
rt_thermal_cooling_device_unregister(&pf_cool->parent);
@@ -223,6 +223,7 @@ _scan_cooling:
}
}
_end:
;
}
#else
rt_inline void thermal_ofw_setup(struct rt_ofw_node *np, struct rt_thermal_zone_device *zdev)