drivers/rpmsg_port_spi_slave: add getrecvbuf callback for zero-copy receive

Add a new getrecvbuf callback to the SPI slave device operations
that allows the slave device to provide a pre-allocated receive
buffer directly to the controller. This enables zero-copy data
transfer by allowing the controller to receive data directly into
the device's buffer instead of copying.

Changes:
- Add SPIS_DEV_GETRECVBUF macro and getrecvbuf callback to
  spi_slave_devops_s structure in include/nuttx/spi/slave.h
- Implement getrecvbuf in rpmsg_port_spi_slave driver
- Update getdata to return 0 as it's no longer used for this path

Signed-off-by: liaoao <liaoao@xiaomi.com>
This commit is contained in:
liaoao
2025-05-30 20:53:36 +08:00
committed by Xiang Xiao
parent fd6ab20362
commit ae6ad9c193
2 changed files with 42 additions and 1 deletions
+16 -1
View File
@@ -146,6 +146,9 @@ static size_t rpmsg_port_spi_slave_receive(FAR struct spi_slave_dev_s *dev,
size_t nwords);
static void rpmsg_port_spi_slave_notify(FAR struct spi_slave_dev_s *dev,
spi_slave_state_t state);
static size_t
rpmsg_port_spi_slave_getrecvbuf(FAR struct spi_slave_dev_s *dev,
FAR void **buffer);
/****************************************************************************
* Private Data
@@ -165,6 +168,7 @@ static const struct spi_slave_devops_s g_rpmsg_port_spi_slave_ops =
rpmsg_port_spi_slave_getdata, /* getdata */
rpmsg_port_spi_slave_receive, /* receive */
rpmsg_port_spi_slave_notify, /* notify */
rpmsg_port_spi_slave_getrecvbuf, /* getrecvbuf */
};
/****************************************************************************
@@ -359,11 +363,22 @@ static void rpmsg_port_spi_slave_cmddata(FAR struct spi_slave_dev_s *dev,
static size_t rpmsg_port_spi_slave_getdata(FAR struct spi_slave_dev_s *dev,
FAR const void **data)
{
return 0;
}
/****************************************************************************
* Name: rpmsg_port_spi_slave_getrecvbuf
****************************************************************************/
static size_t
rpmsg_port_spi_slave_getrecvbuf(FAR struct spi_slave_dev_s *dev,
FAR void **buffer)
{
FAR struct rpmsg_port_spi_s *rpspi =
container_of(dev, struct rpmsg_port_spi_s, spislv);
*data = rpspi->rxhdr;
*buffer = rpspi->rxhdr;
return RPMSG_PORT_SPI_BYTES2WORDS(rpspi, rpspi->port.rxq.len);
}
+26
View File
@@ -266,6 +266,30 @@
#define SPIS_DEV_GETDATA(d,v) ((d)->ops->getdata(d,v))
/****************************************************************************
* Name: SPIS_DEV_GETRECVBUF
*
* Description:
* This is a SPI device callback should be called when the device would
* like to do a nocopy transfer though the device. When the buffer pointer
* controller get is not NULL, it will transfer the data from enqueue
* directly.
*
* Input Parameters:
* dev - SPI Slave device interface instance
* buffer - Pointer to the receive buffer pointer to be shifted in.
*
* Returned Value:
* The size of data units can be received from this exchange.
*
* Assumptions:
* May be called from an interrupt handler and the response is usually
* time-critical.
*
****************************************************************************/
#define SPIS_DEV_GETRECVBUF(d,b) ((d)->ops->getrecvbuf(d,b))
/****************************************************************************
* Name: SPIS_DEV_RECEIVE
*
@@ -544,6 +568,8 @@ struct spi_slave_devops_s
FAR const void *data, size_t nwords);
CODE void (*notify)(FAR struct spi_slave_dev_s *sdev,
spi_slave_state_t state);
CODE size_t (*getrecvbuf)(FAR struct spi_slave_dev_s *sdev,
FAR void **buffer);
};
/* SPI slave device private data. This structure only defines the initial