diff options
author | Vladimir Oltean <olteanv@gmail.com> | 2019-11-13 00:16:41 +0200 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-11-14 15:11:17 -0800 |
commit | abfb228ae64268991653a6e73eb203c759764075 (patch) | |
tree | 91483a7f8ab8efa82bdaf1f34db2beae7a0fb4df /drivers/net/dsa/sja1105 | |
parent | ccb689939280b9dfdedee8b8b45e616e42696609 (diff) | |
download | linux-abfb228ae64268991653a6e73eb203c759764075.tar.bz2 |
net: dsa: sja1105: Simplify reset handling
We don't really need 10k species of reset. Remove everything except cold
reset which is what is actually used. Too bad the hardware designers
couldn't agree to use the same bit field for rev 1 and rev 2, so the
(*reset_cmd) function pointer is there to stay.
However let's simplify the prototype and give it a struct dsa_switch (we
want to avoid forward-declarations of structures, in this case struct
sja1105_private, wherever we can).
Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/dsa/sja1105')
-rw-r--r-- | drivers/net/dsa/sja1105/sja1105.h | 2 | ||||
-rw-r--r-- | drivers/net/dsa/sja1105/sja1105_spi.c | 110 |
2 files changed, 15 insertions, 97 deletions
diff --git a/drivers/net/dsa/sja1105/sja1105.h b/drivers/net/dsa/sja1105/sja1105.h index 29c7ed60cfdc..d801fc204d19 100644 --- a/drivers/net/dsa/sja1105/sja1105.h +++ b/drivers/net/dsa/sja1105/sja1105.h @@ -78,7 +78,7 @@ struct sja1105_info { const struct sja1105_dynamic_table_ops *dyn_ops; const struct sja1105_table_ops *static_ops; const struct sja1105_regs *regs; - int (*reset_cmd)(const void *ctx, const void *data); + int (*reset_cmd)(struct dsa_switch *ds); int (*setup_rgmii_delay)(const void *ctx, int port); /* Prototypes from include/net/dsa.h */ int (*fdb_add_cmd)(struct dsa_switch *ds, int port, diff --git a/drivers/net/dsa/sja1105/sja1105_spi.c b/drivers/net/dsa/sja1105/sja1105_spi.c index fca3a973764b..29b127f3bf9c 100644 --- a/drivers/net/dsa/sja1105/sja1105_spi.c +++ b/drivers/net/dsa/sja1105/sja1105_spi.c @@ -205,116 +205,34 @@ int sja1105_xfer_u32(const struct sja1105_private *priv, return rc; } -/* Back-ported structure from UM11040 Table 112. - * Reset control register (addr. 100440h) - * In the SJA1105 E/T, only warm_rst and cold_rst are - * supported (exposed in UM10944 as rst_ctrl), but the bit - * offsets of warm_rst and cold_rst are actually reversed. - */ -struct sja1105_reset_cmd { - u64 switch_rst; - u64 cfg_rst; - u64 car_rst; - u64 otp_rst; - u64 warm_rst; - u64 cold_rst; - u64 por_rst; -}; - -static void -sja1105et_reset_cmd_pack(void *buf, const struct sja1105_reset_cmd *reset) +static int sja1105et_reset_cmd(struct dsa_switch *ds) { - const int size = SJA1105_SIZE_RESET_CMD; - - memset(buf, 0, size); - - sja1105_pack(buf, &reset->cold_rst, 3, 3, size); - sja1105_pack(buf, &reset->warm_rst, 2, 2, size); -} - -static void -sja1105pqrs_reset_cmd_pack(void *buf, const struct sja1105_reset_cmd *reset) -{ - const int size = SJA1105_SIZE_RESET_CMD; - - memset(buf, 0, size); - - sja1105_pack(buf, &reset->switch_rst, 8, 8, size); - sja1105_pack(buf, &reset->cfg_rst, 7, 7, size); - sja1105_pack(buf, &reset->car_rst, 5, 5, size); - sja1105_pack(buf, &reset->otp_rst, 4, 4, size); - sja1105_pack(buf, &reset->warm_rst, 3, 3, size); - sja1105_pack(buf, &reset->cold_rst, 2, 2, size); - sja1105_pack(buf, &reset->por_rst, 1, 1, size); -} - -static int sja1105et_reset_cmd(const void *ctx, const void *data) -{ - const struct sja1105_private *priv = ctx; - const struct sja1105_reset_cmd *reset = data; + struct sja1105_private *priv = ds->priv; const struct sja1105_regs *regs = priv->info->regs; - struct device *dev = priv->ds->dev; - u8 packed_buf[SJA1105_SIZE_RESET_CMD]; - - if (reset->switch_rst || - reset->cfg_rst || - reset->car_rst || - reset->otp_rst || - reset->por_rst) { - dev_err(dev, "Only warm and cold reset is supported " - "for SJA1105 E/T!\n"); - return -EINVAL; - } - - if (reset->warm_rst) - dev_dbg(dev, "Warm reset requested\n"); - if (reset->cold_rst) - dev_dbg(dev, "Cold reset requested\n"); + u8 packed_buf[SJA1105_SIZE_RESET_CMD] = {0}; + const int size = SJA1105_SIZE_RESET_CMD; + u64 cold_rst = 1; - sja1105et_reset_cmd_pack(packed_buf, reset); + sja1105_pack(packed_buf, &cold_rst, 3, 3, size); return sja1105_xfer_buf(priv, SPI_WRITE, regs->rgu, packed_buf, SJA1105_SIZE_RESET_CMD); } -static int sja1105pqrs_reset_cmd(const void *ctx, const void *data) +static int sja1105pqrs_reset_cmd(struct dsa_switch *ds) { - const struct sja1105_private *priv = ctx; - const struct sja1105_reset_cmd *reset = data; + struct sja1105_private *priv = ds->priv; const struct sja1105_regs *regs = priv->info->regs; - struct device *dev = priv->ds->dev; - u8 packed_buf[SJA1105_SIZE_RESET_CMD]; - - if (reset->switch_rst) - dev_dbg(dev, "Main reset for all functional modules requested\n"); - if (reset->cfg_rst) - dev_dbg(dev, "Chip configuration reset requested\n"); - if (reset->car_rst) - dev_dbg(dev, "Clock and reset control logic reset requested\n"); - if (reset->otp_rst) - dev_dbg(dev, "OTP read cycle for reading product " - "config settings requested\n"); - if (reset->warm_rst) - dev_dbg(dev, "Warm reset requested\n"); - if (reset->cold_rst) - dev_dbg(dev, "Cold reset requested\n"); - if (reset->por_rst) - dev_dbg(dev, "Power-on reset requested\n"); - - sja1105pqrs_reset_cmd_pack(packed_buf, reset); + u8 packed_buf[SJA1105_SIZE_RESET_CMD] = {0}; + const int size = SJA1105_SIZE_RESET_CMD; + u64 cold_rst = 1; + + sja1105_pack(packed_buf, &cold_rst, 2, 2, size); return sja1105_xfer_buf(priv, SPI_WRITE, regs->rgu, packed_buf, SJA1105_SIZE_RESET_CMD); } -static int sja1105_cold_reset(const struct sja1105_private *priv) -{ - struct sja1105_reset_cmd reset = {0}; - - reset.cold_rst = 1; - return priv->info->reset_cmd(priv, &reset); -} - int sja1105_inhibit_tx(const struct sja1105_private *priv, unsigned long port_bitmap, bool tx_inhibited) { @@ -459,7 +377,7 @@ int sja1105_static_config_upload(struct sja1105_private *priv) usleep_range(500, 1000); do { /* Put the SJA1105 in programming mode */ - rc = sja1105_cold_reset(priv); + rc = priv->info->reset_cmd(priv->ds); if (rc < 0) { dev_err(dev, "Failed to reset switch, retrying...\n"); continue; |