summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorGeert Uytterhoeven <geert+renesas@glider.be>2023-02-28 15:43:08 +0100
committerMark Brown <broonie@kernel.org>2023-03-05 23:41:25 +0000
commitfc12d4bb3227f21e1e7d6d78231074ca542c060d (patch)
tree9d9837893a359ec9ccaab9107533f574fc99445b /drivers
parentfe15c26ee26efa11741a7b632e9f23b01aca4cc6 (diff)
spi: Replace spi_pcpu_stats_totalize() macro by a C function
spi_pcpu_stats_totalize() is a rather large macro, and is instantiated 28 times, causing a large amount of duplication in the amount of generated code. Reduce the duplication by replacing spi_pcpu_stats_totalize() by a real C function, and absorb all other common code from spi_statistics_##name##_show(). As (a) the old "field" parameter was the name of a structure member, which cannot be passed to a function, and (b) passing a pointer to the member is also not an option, due to the loop over all possible CPUs, the "field" parameter is replaced by an "offset" parameter, pointing to a location within the structure. This reduces kernel size by ca. 4 KiB (on arm32 and arm64). Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be> Link: https://lore.kernel.org/r/cb7690d9d04c06eec23dbb98fbb5444082125cff.1677594432.git.geert+renesas@glider.be Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/spi/spi.c47
1 files changed, 24 insertions, 23 deletions
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 44b85a8d47f1..798030c0c5ce 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -117,24 +117,28 @@ static struct spi_statistics __percpu *spi_alloc_pcpu_stats(struct device *dev)
return pcpu_stats;
}
-#define spi_pcpu_stats_totalize(ret, in, field) \
-do { \
- int i; \
- ret = 0; \
- for_each_possible_cpu(i) { \
- const struct spi_statistics *pcpu_stats; \
- u64 inc; \
- unsigned int start; \
- pcpu_stats = per_cpu_ptr(in, i); \
- do { \
- start = u64_stats_fetch_begin( \
- &pcpu_stats->syncp); \
- inc = u64_stats_read(&pcpu_stats->field); \
- } while (u64_stats_fetch_retry( \
- &pcpu_stats->syncp, start)); \
- ret += inc; \
- } \
-} while (0)
+static ssize_t spi_emit_pcpu_stats(struct spi_statistics __percpu *stat,
+ char *buf, size_t offset)
+{
+ u64 val = 0;
+ int i;
+
+ for_each_possible_cpu(i) {
+ const struct spi_statistics *pcpu_stats;
+ u64_stats_t *field;
+ unsigned int start;
+ u64 inc;
+
+ pcpu_stats = per_cpu_ptr(stat, i);
+ field = (void *)pcpu_stats + offset;
+ do {
+ start = u64_stats_fetch_begin(&pcpu_stats->syncp);
+ inc = u64_stats_read(field);
+ } while (u64_stats_fetch_retry(&pcpu_stats->syncp, start));
+ val += inc;
+ }
+ return sysfs_emit(buf, "%llu\n", val);
+}
#define SPI_STATISTICS_ATTRS(field, file) \
static ssize_t spi_controller_##field##_show(struct device *dev, \
@@ -165,11 +169,8 @@ static struct device_attribute dev_attr_spi_device_##field = { \
static ssize_t spi_statistics_##name##_show(struct spi_statistics __percpu *stat, \
char *buf) \
{ \
- ssize_t len; \
- u64 val; \
- spi_pcpu_stats_totalize(val, stat, field); \
- len = sysfs_emit(buf, "%llu\n", val); \
- return len; \
+ return spi_emit_pcpu_stats(stat, buf, \
+ offsetof(struct spi_statistics, field)); \
} \
SPI_STATISTICS_ATTRS(name, file)