summaryrefslogtreecommitdiff
path: root/drivers/spi
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2023-01-13 15:56:45 +0000
committerMark Brown <broonie@kernel.org>2023-01-13 17:37:52 +0000
commitc5d808691c2cf61c7b85003027ee35267dd74d7b (patch)
tree6173acd7ec3c599b79a308e1786ff1339d332376 /drivers/spi
parentf66804bf7665f9d2db04791496ba2c7f4173941c (diff)
parent5827b31d858e399e0ba9fbd33da7a39b31769e11 (diff)
spi: SPI core CS delay fixes and additions
Merge series from Hector Martin <marcan@marcan.st>: Commits f6c911f3308c ("spi: dt-bindings: Introduce spi-cs-setup-ns property") and 33a2fde5f77b ("spi: Introduce spi-cs-setup-ns property") introduced a new property to represent the CS setup delay in the device tree, but they have some issues: - The property is only parsed as a 16-bit integer number of nanoseconds, which limits the maximum value to ~65us. This is not a reasonable upper limit, as some devices might need a lot more. - The property name is inconsistent with other delay properties, which use a "*-delay-ns" naming scheme. - Only the setup delay is introduced, but not the related hold and inactive delay times. This series fixes the issues and adds support for the two missing properties. Please pull in the first 3 patches as fixes for 6.2, to avoid introducing a problematic DT API in this release. The last two patches can wait until 6.3, though are probably harmless to throw in as fixes too, since they're trivial.
Diffstat (limited to 'drivers/spi')
-rw-r--r--drivers/spi/spi.c25
1 files changed, 20 insertions, 5 deletions
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 15f174f4e056..fc4f6308efd8 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -2220,11 +2220,26 @@ void spi_flush_queue(struct spi_controller *ctlr)
/*-------------------------------------------------------------------------*/
#if defined(CONFIG_OF)
+static void of_spi_parse_dt_cs_delay(struct device_node *nc,
+ struct spi_delay *delay, const char *prop)
+{
+ u32 value;
+
+ if (!of_property_read_u32(nc, prop, &value)) {
+ if (value > U16_MAX) {
+ delay->value = DIV_ROUND_UP(value, 1000);
+ delay->unit = SPI_DELAY_UNIT_USECS;
+ } else {
+ delay->value = value;
+ delay->unit = SPI_DELAY_UNIT_NSECS;
+ }
+ }
+}
+
static int of_spi_parse_dt(struct spi_controller *ctlr, struct spi_device *spi,
struct device_node *nc)
{
u32 value;
- u16 cs_setup;
int rc;
/* Mode (clock phase/polarity/etc.) */
@@ -2310,10 +2325,10 @@ static int of_spi_parse_dt(struct spi_controller *ctlr, struct spi_device *spi,
if (!of_property_read_u32(nc, "spi-max-frequency", &value))
spi->max_speed_hz = value;
- if (!of_property_read_u16(nc, "spi-cs-setup-delay-ns", &cs_setup)) {
- spi->cs_setup.value = cs_setup;
- spi->cs_setup.unit = SPI_DELAY_UNIT_NSECS;
- }
+ /* Device CS delays */
+ of_spi_parse_dt_cs_delay(nc, &spi->cs_setup, "spi-cs-setup-delay-ns");
+ of_spi_parse_dt_cs_delay(nc, &spi->cs_hold, "spi-cs-hold-delay-ns");
+ of_spi_parse_dt_cs_delay(nc, &spi->cs_inactive, "spi-cs-inactive-delay-ns");
return 0;
}