spi: expose spi_master and spi_device statistics via sysfs
per spi-master statistics accessible as: /sys/class/spi_master/spi*/statistics/* per spi-device statistics accessible via: /sys/class/spi_master/spi*/spi*.*/statistics/* The following statistics are exposed as separate "files" inside these directories: * messages number of spi_messages * transfers number of spi_transfers * bytes number of bytes transferred * bytes_rx number of bytes transmitted * bytes_tx number of bytes received * errors number of errors encounterd * timedout number of messages that have timed out * spi_async number of spi_messages submitted using spi_async * spi_sync number of spi_messages submitted using spi_sync * spi_sync_immediate number of spi_messages submitted using spi_sync, that are handled immediately without a context switch to the spi_pump worker-thread Signed-off-by: Martin Sperl <kernel@martin.sperl.org> Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
@@ -23,6 +23,8 @@
|
||||
#include <linux/scatterlist.h>
|
||||
|
||||
struct dma_chan;
|
||||
struct spi_master;
|
||||
struct spi_transfer;
|
||||
|
||||
/*
|
||||
* INTERFACES between SPI master-side drivers and SPI infrastructure.
|
||||
@@ -30,6 +32,59 @@ struct dma_chan;
|
||||
*/
|
||||
extern struct bus_type spi_bus_type;
|
||||
|
||||
/**
|
||||
* struct spi_statistics - statistics for spi transfers
|
||||
* @clock: lock protecting this structure
|
||||
*
|
||||
* @messages: number of spi-messages handled
|
||||
* @transfers: number of spi_transfers handled
|
||||
* @errors: number of errors during spi_transfer
|
||||
* @timedout: number of timeouts during spi_transfer
|
||||
*
|
||||
* @spi_sync: number of times spi_sync is used
|
||||
* @spi_sync_immediate:
|
||||
* number of times spi_sync is executed immediately
|
||||
* in calling context without queuing and scheduling
|
||||
* @spi_async: number of times spi_async is used
|
||||
*
|
||||
* @bytes: number of bytes transferred to/from device
|
||||
* @bytes_tx: number of bytes sent to device
|
||||
* @bytes_rx: number of bytes received from device
|
||||
*
|
||||
*/
|
||||
struct spi_statistics {
|
||||
spinlock_t lock; /* lock for the whole structure */
|
||||
|
||||
unsigned long messages;
|
||||
unsigned long transfers;
|
||||
unsigned long errors;
|
||||
unsigned long timedout;
|
||||
|
||||
unsigned long spi_sync;
|
||||
unsigned long spi_sync_immediate;
|
||||
unsigned long spi_async;
|
||||
|
||||
unsigned long long bytes;
|
||||
unsigned long long bytes_rx;
|
||||
unsigned long long bytes_tx;
|
||||
|
||||
};
|
||||
|
||||
void spi_statistics_add_transfer_stats(struct spi_statistics *stats,
|
||||
struct spi_transfer *xfer,
|
||||
struct spi_master *master);
|
||||
|
||||
#define SPI_STATISTICS_ADD_TO_FIELD(stats, field, count) \
|
||||
do { \
|
||||
unsigned long flags; \
|
||||
spin_lock_irqsave(&(stats)->lock, flags); \
|
||||
(stats)->field += count; \
|
||||
spin_unlock_irqrestore(&(stats)->lock, flags); \
|
||||
} while (0)
|
||||
|
||||
#define SPI_STATISTICS_INCREMENT_FIELD(stats, field) \
|
||||
SPI_STATISTICS_ADD_TO_FIELD(stats, field, 1)
|
||||
|
||||
/**
|
||||
* struct spi_device - Master side proxy for an SPI slave device
|
||||
* @dev: Driver model representation of the device.
|
||||
@@ -60,6 +115,8 @@ extern struct bus_type spi_bus_type;
|
||||
* @cs_gpio: gpio number of the chipselect line (optional, -ENOENT when
|
||||
* when not using a GPIO line)
|
||||
*
|
||||
* @statistics: statistics for the spi_device
|
||||
*
|
||||
* A @spi_device is used to interchange data between an SPI slave
|
||||
* (usually a discrete chip) and CPU memory.
|
||||
*
|
||||
@@ -98,6 +155,9 @@ struct spi_device {
|
||||
char modalias[SPI_NAME_SIZE];
|
||||
int cs_gpio; /* chip select gpio */
|
||||
|
||||
/* the statistics */
|
||||
struct spi_statistics statistics;
|
||||
|
||||
/*
|
||||
* likely need more hooks for more protocol options affecting how
|
||||
* the controller talks to each chip, like:
|
||||
@@ -296,6 +356,7 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)
|
||||
* @cs_gpios: Array of GPIOs to use as chip select lines; one per CS
|
||||
* number. Any individual value may be -ENOENT for CS lines that
|
||||
* are not GPIOs (driven by the SPI controller itself).
|
||||
* @statistics: statistics for the spi_master
|
||||
* @dma_tx: DMA transmit channel
|
||||
* @dma_rx: DMA receive channel
|
||||
* @dummy_rx: dummy receive buffer for full-duplex devices
|
||||
@@ -452,6 +513,9 @@ struct spi_master {
|
||||
/* gpio chip select */
|
||||
int *cs_gpios;
|
||||
|
||||
/* statistics */
|
||||
struct spi_statistics statistics;
|
||||
|
||||
/* DMA channels for use with core dmaengine helpers */
|
||||
struct dma_chan *dma_tx;
|
||||
struct dma_chan *dma_rx;
|
||||
|
Reference in New Issue
Block a user