OSDN Git Service

net: dsa: sja1105: Replace sja1105_spi_send_int with sja1105_xfer_{u32, u64}
authorVladimir Oltean <olteanv@gmail.com>
Tue, 1 Oct 2019 19:18:00 +0000 (22:18 +0300)
committerDavid S. Miller <davem@davemloft.net>
Wed, 2 Oct 2019 16:25:11 +0000 (12:25 -0400)
Having a function that takes a variable number of unpacked bytes which
it generically calls an "int" is confusing and makes auditing patches
next to impossible.

We only use spi_send_int with the int sizes of 32 and 64 bits. So just
make the spi_send_int function less generic and replace it with the
appropriate two explicit functions, which can now type-check the int
pointer type.

Note that there is still a small weirdness in the u32 function, which
has to convert it to a u64 temporary. This is because of how the packing
API works at the moment, but the weirdness is at least hidden from
callers of sja1105_xfer_u32 now.

Suggested-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/dsa/sja1105/sja1105.h
drivers/net/dsa/sja1105/sja1105_main.c
drivers/net/dsa/sja1105/sja1105_ptp.c
drivers/net/dsa/sja1105/sja1105_spi.c

index e53e494..cba0beb 100644 (file)
@@ -130,9 +130,10 @@ int sja1105_static_config_reload(struct sja1105_private *priv);
 int sja1105_spi_send_packed_buf(const struct sja1105_private *priv,
                                sja1105_spi_rw_mode_t rw, u64 reg_addr,
                                void *packed_buf, size_t size_bytes);
-int sja1105_spi_send_int(const struct sja1105_private *priv,
-                        sja1105_spi_rw_mode_t rw, u64 reg_addr,
-                        u64 *value, u64 size_bytes);
+int sja1105_xfer_u32(const struct sja1105_private *priv,
+                    sja1105_spi_rw_mode_t rw, u64 reg_addr, u32 *value);
+int sja1105_xfer_u64(const struct sja1105_private *priv,
+                    sja1105_spi_rw_mode_t rw, u64 reg_addr, u64 *value);
 int sja1105_spi_send_long_packed_buf(const struct sja1105_private *priv,
                                     sja1105_spi_rw_mode_t rw, u64 base_addr,
                                     void *packed_buf, u64 buf_len);
index c418fe3..fd567ee 100644 (file)
@@ -2109,17 +2109,16 @@ static int sja1105_check_device_id(struct sja1105_private *priv)
        const struct sja1105_regs *regs = priv->info->regs;
        u8 prod_id[SJA1105_SIZE_DEVICE_ID] = {0};
        struct device *dev = &priv->spidev->dev;
-       u64 device_id;
+       u32 device_id;
        u64 part_no;
        int rc;
 
-       rc = sja1105_spi_send_int(priv, SPI_READ, regs->device_id,
-                                 &device_id, SJA1105_SIZE_DEVICE_ID);
+       rc = sja1105_xfer_u32(priv, SPI_READ, regs->device_id, &device_id);
        if (rc < 0)
                return rc;
 
        if (device_id != priv->info->device_id) {
-               dev_err(dev, "Expected device ID 0x%llx but read 0x%llx\n",
+               dev_err(dev, "Expected device ID 0x%llx but read 0x%x\n",
                        priv->info->device_id, device_id);
                return -ENODEV;
        }
index d8e8dd5..42cc698 100644 (file)
@@ -327,8 +327,7 @@ static u64 sja1105_ptptsclk_read(const struct cyclecounter *cc)
        u64 ptptsclk = 0;
        int rc;
 
-       rc = sja1105_spi_send_int(priv, SPI_READ, regs->ptptsclk,
-                                 &ptptsclk, 8);
+       rc = sja1105_xfer_u64(priv, SPI_READ, regs->ptptsclk, &ptptsclk);
        if (rc < 0)
                dev_err_ratelimited(priv->ds->dev,
                                    "failed to read ptp cycle counter: %d\n",
index 84dc603..77a8c0f 100644 (file)
@@ -7,7 +7,6 @@
 #include <linux/packing.h>
 #include "sja1105.h"
 
-#define SJA1105_SIZE_PORT_CTRL         4
 #define SJA1105_SIZE_RESET_CMD         4
 #define SJA1105_SIZE_SPI_MSG_HEADER    4
 #define SJA1105_SIZE_SPI_MSG_MAXLEN    (64 * 4)
@@ -103,35 +102,52 @@ int sja1105_spi_send_packed_buf(const struct sja1105_private *priv,
 
 /* If @rw is:
  * - SPI_WRITE: creates and sends an SPI write message at absolute
- *             address reg_addr, taking size_bytes from *packed_buf
+ *             address reg_addr
  * - SPI_READ:  creates and sends an SPI read message from absolute
- *             address reg_addr, writing size_bytes into *packed_buf
+ *             address reg_addr
  *
  * The u64 *value is unpacked, meaning that it's stored in the native
  * CPU endianness and directly usable by software running on the core.
- *
- * This is a wrapper around sja1105_spi_send_packed_buf().
  */
-int sja1105_spi_send_int(const struct sja1105_private *priv,
-                        sja1105_spi_rw_mode_t rw, u64 reg_addr,
-                        u64 *value, u64 size_bytes)
+int sja1105_xfer_u64(const struct sja1105_private *priv,
+                    sja1105_spi_rw_mode_t rw, u64 reg_addr, u64 *value)
 {
-       u8 packed_buf[SJA1105_SIZE_SPI_MSG_MAXLEN];
+       u8 packed_buf[8];
        int rc;
 
-       if (size_bytes > SJA1105_SIZE_SPI_MSG_MAXLEN)
-               return -ERANGE;
-
        if (rw == SPI_WRITE)
-               sja1105_pack(packed_buf, value, 8 * size_bytes - 1, 0,
-                            size_bytes);
+               sja1105_pack(packed_buf, value, 63, 0, 8);
 
-       rc = sja1105_spi_send_packed_buf(priv, rw, reg_addr, packed_buf,
-                                        size_bytes);
+       rc = sja1105_spi_send_packed_buf(priv, rw, reg_addr, packed_buf, 8);
 
        if (rw == SPI_READ)
-               sja1105_unpack(packed_buf, value, 8 * size_bytes - 1, 0,
-                              size_bytes);
+               sja1105_unpack(packed_buf, value, 63, 0, 8);
+
+       return rc;
+}
+
+/* Same as above, but transfers only a 4 byte word */
+int sja1105_xfer_u32(const struct sja1105_private *priv,
+                    sja1105_spi_rw_mode_t rw, u64 reg_addr, u32 *value)
+{
+       u8 packed_buf[4];
+       u64 tmp;
+       int rc;
+
+       if (rw == SPI_WRITE) {
+               /* The packing API only supports u64 as CPU word size,
+                * so we need to convert.
+                */
+               tmp = *value;
+               sja1105_pack(packed_buf, &tmp, 31, 0, 4);
+       }
+
+       rc = sja1105_spi_send_packed_buf(priv, rw, reg_addr, packed_buf, 4);
+
+       if (rw == SPI_READ) {
+               sja1105_unpack(packed_buf, &tmp, 31, 0, 4);
+               *value = tmp;
+       }
 
        return rc;
 }
@@ -287,11 +303,11 @@ int sja1105_inhibit_tx(const struct sja1105_private *priv,
                       unsigned long port_bitmap, bool tx_inhibited)
 {
        const struct sja1105_regs *regs = priv->info->regs;
-       u64 inhibit_cmd;
+       u32 inhibit_cmd;
        int rc;
 
-       rc = sja1105_spi_send_int(priv, SPI_READ, regs->port_control,
-                                 &inhibit_cmd, SJA1105_SIZE_PORT_CTRL);
+       rc = sja1105_xfer_u32(priv, SPI_READ, regs->port_control,
+                             &inhibit_cmd);
        if (rc < 0)
                return rc;
 
@@ -300,8 +316,8 @@ int sja1105_inhibit_tx(const struct sja1105_private *priv,
        else
                inhibit_cmd &= ~port_bitmap;
 
-       return sja1105_spi_send_int(priv, SPI_WRITE, regs->port_control,
-                                   &inhibit_cmd, SJA1105_SIZE_PORT_CTRL);
+       return sja1105_xfer_u32(priv, SPI_WRITE, regs->port_control,
+                               &inhibit_cmd);
 }
 
 struct sja1105_status {