diff options
| author | Martin Sperl <kernel@martin.sperl.org> | 2015-06-22 09:00:36 -0400 |
|---|---|---|
| committer | Mark Brown <broonie@kernel.org> | 2015-07-07 08:33:23 -0400 |
| commit | eca2ebc7e007c9e2b8f5ecfcfc74b53fbe68e42b (patch) | |
| tree | 0e38bce3f30bb7dcad9777f9724fd92ffcbb34a8 /include | |
| parent | d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754 (diff) | |
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>
Diffstat (limited to 'include')
| -rw-r--r-- | include/linux/spi/spi.h | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index d673072346f2..269e8afd3e2a 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h | |||
| @@ -23,6 +23,8 @@ | |||
| 23 | #include <linux/scatterlist.h> | 23 | #include <linux/scatterlist.h> |
| 24 | 24 | ||
| 25 | struct dma_chan; | 25 | struct dma_chan; |
| 26 | struct spi_master; | ||
| 27 | struct spi_transfer; | ||
| 26 | 28 | ||
| 27 | /* | 29 | /* |
| 28 | * INTERFACES between SPI master-side drivers and SPI infrastructure. | 30 | * INTERFACES between SPI master-side drivers and SPI infrastructure. |
| @@ -31,6 +33,59 @@ struct dma_chan; | |||
| 31 | extern struct bus_type spi_bus_type; | 33 | extern struct bus_type spi_bus_type; |
| 32 | 34 | ||
| 33 | /** | 35 | /** |
| 36 | * struct spi_statistics - statistics for spi transfers | ||
| 37 | * @clock: lock protecting this structure | ||
| 38 | * | ||
| 39 | * @messages: number of spi-messages handled | ||
| 40 | * @transfers: number of spi_transfers handled | ||
| 41 | * @errors: number of errors during spi_transfer | ||
| 42 | * @timedout: number of timeouts during spi_transfer | ||
| 43 | * | ||
| 44 | * @spi_sync: number of times spi_sync is used | ||
| 45 | * @spi_sync_immediate: | ||
| 46 | * number of times spi_sync is executed immediately | ||
| 47 | * in calling context without queuing and scheduling | ||
| 48 | * @spi_async: number of times spi_async is used | ||
| 49 | * | ||
| 50 | * @bytes: number of bytes transferred to/from device | ||
| 51 | * @bytes_tx: number of bytes sent to device | ||
| 52 | * @bytes_rx: number of bytes received from device | ||
| 53 | * | ||
| 54 | */ | ||
| 55 | struct spi_statistics { | ||
| 56 | spinlock_t lock; /* lock for the whole structure */ | ||
| 57 | |||
| 58 | unsigned long messages; | ||
| 59 | unsigned long transfers; | ||
| 60 | unsigned long errors; | ||
| 61 | unsigned long timedout; | ||
| 62 | |||
| 63 | unsigned long spi_sync; | ||
| 64 | unsigned long spi_sync_immediate; | ||
| 65 | unsigned long spi_async; | ||
| 66 | |||
| 67 | unsigned long long bytes; | ||
| 68 | unsigned long long bytes_rx; | ||
| 69 | unsigned long long bytes_tx; | ||
| 70 | |||
| 71 | }; | ||
| 72 | |||
| 73 | void spi_statistics_add_transfer_stats(struct spi_statistics *stats, | ||
| 74 | struct spi_transfer *xfer, | ||
| 75 | struct spi_master *master); | ||
| 76 | |||
| 77 | #define SPI_STATISTICS_ADD_TO_FIELD(stats, field, count) \ | ||
| 78 | do { \ | ||
| 79 | unsigned long flags; \ | ||
| 80 | spin_lock_irqsave(&(stats)->lock, flags); \ | ||
| 81 | (stats)->field += count; \ | ||
| 82 | spin_unlock_irqrestore(&(stats)->lock, flags); \ | ||
| 83 | } while (0) | ||
| 84 | |||
| 85 | #define SPI_STATISTICS_INCREMENT_FIELD(stats, field) \ | ||
| 86 | SPI_STATISTICS_ADD_TO_FIELD(stats, field, 1) | ||
| 87 | |||
| 88 | /** | ||
| 34 | * struct spi_device - Master side proxy for an SPI slave device | 89 | * struct spi_device - Master side proxy for an SPI slave device |
| 35 | * @dev: Driver model representation of the device. | 90 | * @dev: Driver model representation of the device. |
| 36 | * @master: SPI controller used with the device. | 91 | * @master: SPI controller used with the device. |
| @@ -60,6 +115,8 @@ extern struct bus_type spi_bus_type; | |||
| 60 | * @cs_gpio: gpio number of the chipselect line (optional, -ENOENT when | 115 | * @cs_gpio: gpio number of the chipselect line (optional, -ENOENT when |
| 61 | * when not using a GPIO line) | 116 | * when not using a GPIO line) |
| 62 | * | 117 | * |
| 118 | * @statistics: statistics for the spi_device | ||
| 119 | * | ||
| 63 | * A @spi_device is used to interchange data between an SPI slave | 120 | * A @spi_device is used to interchange data between an SPI slave |
| 64 | * (usually a discrete chip) and CPU memory. | 121 | * (usually a discrete chip) and CPU memory. |
| 65 | * | 122 | * |
| @@ -98,6 +155,9 @@ struct spi_device { | |||
| 98 | char modalias[SPI_NAME_SIZE]; | 155 | char modalias[SPI_NAME_SIZE]; |
| 99 | int cs_gpio; /* chip select gpio */ | 156 | int cs_gpio; /* chip select gpio */ |
| 100 | 157 | ||
| 158 | /* the statistics */ | ||
| 159 | struct spi_statistics statistics; | ||
| 160 | |||
| 101 | /* | 161 | /* |
| 102 | * likely need more hooks for more protocol options affecting how | 162 | * likely need more hooks for more protocol options affecting how |
| 103 | * the controller talks to each chip, like: | 163 | * the controller talks to each chip, like: |
| @@ -296,6 +356,7 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) | |||
| 296 | * @cs_gpios: Array of GPIOs to use as chip select lines; one per CS | 356 | * @cs_gpios: Array of GPIOs to use as chip select lines; one per CS |
| 297 | * number. Any individual value may be -ENOENT for CS lines that | 357 | * number. Any individual value may be -ENOENT for CS lines that |
| 298 | * are not GPIOs (driven by the SPI controller itself). | 358 | * are not GPIOs (driven by the SPI controller itself). |
| 359 | * @statistics: statistics for the spi_master | ||
| 299 | * @dma_tx: DMA transmit channel | 360 | * @dma_tx: DMA transmit channel |
| 300 | * @dma_rx: DMA receive channel | 361 | * @dma_rx: DMA receive channel |
| 301 | * @dummy_rx: dummy receive buffer for full-duplex devices | 362 | * @dummy_rx: dummy receive buffer for full-duplex devices |
| @@ -452,6 +513,9 @@ struct spi_master { | |||
| 452 | /* gpio chip select */ | 513 | /* gpio chip select */ |
| 453 | int *cs_gpios; | 514 | int *cs_gpios; |
| 454 | 515 | ||
| 516 | /* statistics */ | ||
| 517 | struct spi_statistics statistics; | ||
| 518 | |||
| 455 | /* DMA channels for use with core dmaengine helpers */ | 519 | /* DMA channels for use with core dmaengine helpers */ |
| 456 | struct dma_chan *dma_tx; | 520 | struct dma_chan *dma_tx; |
| 457 | struct dma_chan *dma_rx; | 521 | struct dma_chan *dma_rx; |
