From patchwork Mon May 4 12:12:42 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Sperl X-Patchwork-Id: 6325601 Return-Path: X-Original-To: patchwork-linux-spi@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 6B5B1BEEE1 for ; Mon, 4 May 2015 12:13:00 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 73A4920351 for ; Mon, 4 May 2015 12:12:59 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 71F6B2034A for ; Mon, 4 May 2015 12:12:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752345AbbEDMM6 (ORCPT ); Mon, 4 May 2015 08:12:58 -0400 Received: from 212-186-180-163.dynamic.surfer.at ([212.186.180.163]:48467 "EHLO cgate.sperl.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752051AbbEDMM5 (ORCPT ); Mon, 4 May 2015 08:12:57 -0400 Received: from raspb.intern.sperl.org (account martin@sperl.org [10.10.10.32] verified) by sperl.org (CommuniGate Pro SMTP 6.1.2) with ESMTPSA id 6321317; Mon, 04 May 2015 12:12:54 +0000 From: kernel@martin.sperl.org To: Mark Brown , linux-spi@vger.kernel.org Cc: Martin Sperl Subject: [PATCH 1/2] spi: add spi_statistics framework Date: Mon, 4 May 2015 12:12:42 +0000 Message-Id: <1430741564-2849-1-git-send-email-kernel@martin.sperl.org> X-Mailer: git-send-email 1.7.10.4 Sender: linux-spi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Martin Sperl add spi_statistics to spi_master and spi_device also add a missing "to_spi_master" method Signed-off-by: Martin Sperl --- include/linux/spi/spi.h | 65 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index d673072..6898574d 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -31,6 +31,45 @@ struct dma_chan; extern struct bus_type spi_bus_type; /** + * struct spi_statistics - statistics for spi transfers + * @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 + * + * @bytes_l2histo: histogram of bytes per spi_transfer (log2 with saturation) + */ +struct spi_statistics { + 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; + + /* histogram of log2(size) between 0 and 65536 with saturation */ +#define SPI_STATISTICS_L2HISTO_SIZE 17 + unsigned long bytes_l2histo[SPI_STATISTICS_L2HISTO_SIZE]; + +}; + +/** * struct spi_device - Master side proxy for an SPI slave device * @dev: Driver model representation of the device. * @master: SPI controller used with the device. @@ -59,6 +98,7 @@ extern struct bus_type spi_bus_type; * for driver coldplugging, and in uevents used for hotplugging * @cs_gpio: gpio number of the chipselect line (optional, -ENOENT when * when not using a GPIO line) + * @stats: the statistics for this device * * A @spi_device is used to interchange data between an SPI slave * (usually a discrete chip) and CPU memory. @@ -98,6 +138,8 @@ struct spi_device { char modalias[SPI_NAME_SIZE]; int cs_gpio; /* chip select gpio */ + struct spi_statistics stats; + /* * likely need more hooks for more protocol options affecting how * the controller talks to each chip, like: @@ -301,6 +343,16 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) * @dummy_rx: dummy receive buffer for full-duplex devices * @dummy_tx: dummy transmit buffer for full-duplex devices * + * @stats: the statistics for this master + * @stats_spinlock: spinlock for stats locking + * (common lock for access to spi_master + * and spi_device stats structures) + * @show_stats: report extra data specific to this master/device + * - spi can be null indicating statistics for the master + * should get reported + * - returns number of bytes added to buffer + * - spinlock is held while in this operation + * * Each SPI master controller can communicate with one or more @spi_device * children. These make a small bus, sharing MOSI, MISO and SCK signals * but not chip select signals. Each device may be configured to use a @@ -452,6 +504,14 @@ struct spi_master { /* gpio chip select */ int *cs_gpios; + /* statistics reporting */ + struct spi_statistics stats; + spinlock_t stats_spinlock; + ssize_t (*show_stats)(struct spi_master *master, + struct spi_device *spi, + char *buf, + ssize_t buffer_size); + /* DMA channels for use with core dmaengine helpers */ struct dma_chan *dma_tx; struct dma_chan *dma_rx; @@ -461,6 +521,11 @@ struct spi_master { void *dummy_tx; }; +static inline struct spi_master *to_spi_master(struct device *dev) +{ + return dev ? container_of(dev, struct spi_master, dev) : NULL; +} + static inline void *spi_master_get_devdata(struct spi_master *master) { return dev_get_drvdata(&master->dev);