From f2f16ae9cc9cba4e3c70941cf6a6443c9ea920f4 Mon Sep 17 00:00:00 2001 From: David Mosberger-Tang Date: Thu, 2 Dec 2021 04:50:09 +0000 Subject: wilc1000: Add id_table to spi_driver This eliminates warning message: SPI driver WILC_SPI has no spi_device_id for microchip,wilc1000 and makes device-tree autoloading work. Signed-off-by: David Mosberger-Tang Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20211202045001.2901903-1-davidm@egauge.net --- drivers/net/wireless/microchip/wilc1000/spi.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers/net/wireless/microchip/wilc1000/spi.c') diff --git a/drivers/net/wireless/microchip/wilc1000/spi.c b/drivers/net/wireless/microchip/wilc1000/spi.c index 640850f989dd..6e7fd18c14e7 100644 --- a/drivers/net/wireless/microchip/wilc1000/spi.c +++ b/drivers/net/wireless/microchip/wilc1000/spi.c @@ -203,11 +203,18 @@ static const struct of_device_id wilc_of_match[] = { }; MODULE_DEVICE_TABLE(of, wilc_of_match); +static const struct spi_device_id wilc_spi_id[] = { + { "wilc1000", 0 }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(spi, wilc_spi_id); + static struct spi_driver wilc_spi_driver = { .driver = { .name = MODALIAS, .of_match_table = wilc_of_match, }, + .id_table = wilc_spi_id, .probe = wilc_bus_probe, .remove = wilc_bus_remove, }; -- cgit v1.2.3 From dde02213fa64ac7f99eb65cd51f9e04812d8bc40 Mon Sep 17 00:00:00 2001 From: David Mosberger-Tang Date: Tue, 7 Dec 2021 00:26:01 +0000 Subject: wilc1000: Remove misleading USE_SPI_DMA macro The USE_SPI_DMA macro name suggests that it could be set to 1 to control whether or not SPI DMA should be used. However, that's not what it does. If set to 1, it'll set the SPI messages' "is_dma_mapped" flag to true, even though the tx/rx buffers aren't actually DMA mapped by the driver. In other words, setting this flag to 1 will break the driver. Best to clean up this confusion by removing the macro altogether. There is no need to explicitly initialize "is_dma_mapped" because the message is cleared to zero anyhow, so "is_dma_mapped" is set to false by default. Signed-off-by: David Mosberger-Tang Acked-by: Ajay Singh Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20211207002453.3193737-1-davidm@egauge.net --- drivers/net/wireless/microchip/wilc1000/spi.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers/net/wireless/microchip/wilc1000/spi.c') diff --git a/drivers/net/wireless/microchip/wilc1000/spi.c b/drivers/net/wireless/microchip/wilc1000/spi.c index 6e7fd18c14e7..fc02217d6924 100644 --- a/drivers/net/wireless/microchip/wilc1000/spi.c +++ b/drivers/net/wireless/microchip/wilc1000/spi.c @@ -99,8 +99,6 @@ static int wilc_spi_reset(struct wilc *wilc); #define DATA_PKT_LOG_SZ DATA_PKT_LOG_SZ_MAX #define DATA_PKT_SZ (1 << DATA_PKT_LOG_SZ) -#define USE_SPI_DMA 0 - #define WILC_SPI_COMMAND_STAT_SUCCESS 0 #define WILC_GET_RESP_HDR_START(h) (((h) >> 4) & 0xf) @@ -247,7 +245,6 @@ static int wilc_spi_tx(struct wilc *wilc, u8 *b, u32 len) memset(&msg, 0, sizeof(msg)); spi_message_init(&msg); msg.spi = spi; - msg.is_dma_mapped = USE_SPI_DMA; spi_message_add_tail(&tr, &msg); ret = spi_sync(spi, &msg); @@ -291,7 +288,6 @@ static int wilc_spi_rx(struct wilc *wilc, u8 *rb, u32 rlen) memset(&msg, 0, sizeof(msg)); spi_message_init(&msg); msg.spi = spi; - msg.is_dma_mapped = USE_SPI_DMA; spi_message_add_tail(&tr, &msg); ret = spi_sync(spi, &msg); @@ -330,7 +326,6 @@ static int wilc_spi_tx_rx(struct wilc *wilc, u8 *wb, u8 *rb, u32 rlen) memset(&msg, 0, sizeof(msg)); spi_message_init(&msg); msg.spi = spi; - msg.is_dma_mapped = USE_SPI_DMA; spi_message_add_tail(&tr, &msg); ret = spi_sync(spi, &msg); -- cgit v1.2.3 From 4347d34e6a7699cb61a8bc19b86e460d6b67e5fb Mon Sep 17 00:00:00 2001 From: David Mosberger-Tang Date: Thu, 9 Dec 2021 04:44:27 +0000 Subject: wilc1000: Rename SPI driver from "WILC_SPI" to "wilc1000_spi" The name "wilc1000_spi" follows normal Linux conventions and also is analogous to the SDIO driver, which uses "wilc1000_sdio". Signed-off-by: David Mosberger-Tang Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20211209044411.3482259-2-davidm@egauge.net --- drivers/net/wireless/microchip/wilc1000/spi.c | 4 +++- drivers/net/wireless/microchip/wilc1000/wlan.h | 2 -- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/net/wireless/microchip/wilc1000/spi.c') diff --git a/drivers/net/wireless/microchip/wilc1000/spi.c b/drivers/net/wireless/microchip/wilc1000/spi.c index fc02217d6924..e0871b89917d 100644 --- a/drivers/net/wireless/microchip/wilc1000/spi.c +++ b/drivers/net/wireless/microchip/wilc1000/spi.c @@ -12,6 +12,8 @@ #include "netdev.h" #include "cfg80211.h" +#define SPI_MODALIAS "wilc1000_spi" + static bool enable_crc7; /* protect SPI commands with CRC7 */ module_param(enable_crc7, bool, 0644); MODULE_PARM_DESC(enable_crc7, @@ -209,7 +211,7 @@ MODULE_DEVICE_TABLE(spi, wilc_spi_id); static struct spi_driver wilc_spi_driver = { .driver = { - .name = MODALIAS, + .name = SPI_MODALIAS, .of_match_table = wilc_of_match, }, .id_table = wilc_spi_id, diff --git a/drivers/net/wireless/microchip/wilc1000/wlan.h b/drivers/net/wireless/microchip/wilc1000/wlan.h index 13fde636aa0e..eb7978166d73 100644 --- a/drivers/net/wireless/microchip/wilc1000/wlan.h +++ b/drivers/net/wireless/microchip/wilc1000/wlan.h @@ -213,8 +213,6 @@ #define WILC_RX_BUFF_SIZE (96 * 1024) #define WILC_TX_BUFF_SIZE (64 * 1024) -#define MODALIAS "WILC_SPI" - #define NQUEUES 4 #define AC_BUFFER_SIZE 1000 -- cgit v1.2.3 From 4894edacfa93d7046bec4fc61fc402ac6a2ac9e8 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 17 Dec 2021 18:03:12 +0300 Subject: wilc1000: fix double free error in probe() Smatch complains that there is a double free in probe: drivers/net/wireless/microchip/wilc1000/spi.c:186 wilc_bus_probe() error: double free of 'spi_priv' drivers/net/wireless/microchip/wilc1000/sdio.c:163 wilc_sdio_probe() error: double free of 'sdio_priv' The problem is that wilc_netdev_cleanup() function frees "wilc->bus_data". That's confusing and a layering violation. Leave the frees in probe(), delete the free in wilc_netdev_cleanup(), and add some new frees to the remove() functions. Fixes: dc8b338f3bcd ("wilc1000: use goto labels on error path") Signed-off-by: Dan Carpenter Reviewed-by: Claudiu Beznea Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20211217150311.GC16611@kili --- drivers/net/wireless/microchip/wilc1000/netdev.c | 1 - drivers/net/wireless/microchip/wilc1000/sdio.c | 2 ++ drivers/net/wireless/microchip/wilc1000/spi.c | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/net/wireless/microchip/wilc1000/spi.c') diff --git a/drivers/net/wireless/microchip/wilc1000/netdev.c b/drivers/net/wireless/microchip/wilc1000/netdev.c index 03e3485d7e7f..643bddaae32a 100644 --- a/drivers/net/wireless/microchip/wilc1000/netdev.c +++ b/drivers/net/wireless/microchip/wilc1000/netdev.c @@ -905,7 +905,6 @@ void wilc_netdev_cleanup(struct wilc *wilc) wilc_wlan_cfg_deinit(wilc); wlan_deinit_locks(wilc); - kfree(wilc->bus_data); wiphy_unregister(wilc->wiphy); wiphy_free(wilc->wiphy); } diff --git a/drivers/net/wireless/microchip/wilc1000/sdio.c b/drivers/net/wireless/microchip/wilc1000/sdio.c index 26ebf6664342..ec595dbd8959 100644 --- a/drivers/net/wireless/microchip/wilc1000/sdio.c +++ b/drivers/net/wireless/microchip/wilc1000/sdio.c @@ -167,9 +167,11 @@ free: static void wilc_sdio_remove(struct sdio_func *func) { struct wilc *wilc = sdio_get_drvdata(func); + struct wilc_sdio *sdio_priv = wilc->bus_data; clk_disable_unprepare(wilc->rtc_clk); wilc_netdev_cleanup(wilc); + kfree(sdio_priv); } static int wilc_sdio_reset(struct wilc *wilc) diff --git a/drivers/net/wireless/microchip/wilc1000/spi.c b/drivers/net/wireless/microchip/wilc1000/spi.c index e0871b89917d..5ace9e3a56fc 100644 --- a/drivers/net/wireless/microchip/wilc1000/spi.c +++ b/drivers/net/wireless/microchip/wilc1000/spi.c @@ -190,9 +190,11 @@ free: static int wilc_bus_remove(struct spi_device *spi) { struct wilc *wilc = spi_get_drvdata(spi); + struct wilc_spi *spi_priv = wilc->bus_data; clk_disable_unprepare(wilc->rtc_clk); wilc_netdev_cleanup(wilc); + kfree(spi_priv); return 0; } -- cgit v1.2.3 From ec031ac4792c72d9e925313366df8064e092f685 Mon Sep 17 00:00:00 2001 From: David Mosberger-Tang Date: Tue, 21 Dec 2021 21:25:34 +0000 Subject: wilc1000: Add reset/enable GPIO support to SPI driver For the SDIO driver, the RESET/ENABLE pins of WILC1000 are controlled through the SDIO power sequence driver. This commit adds analogous support for the SPI driver. Specifically, during initialization, the chip will be ENABLEd and taken out of RESET and during deinitialization, the chip will be placed back into RESET and disabled (both to reduce power consumption and to ensure the WiFi radio is off). Both RESET and ENABLE GPIOs are optional. However, if the ENABLE GPIO is specified, then the RESET GPIO should normally also be specified as otherwise there is no way to ensure proper timing of the ENABLE/RESET sequence. Signed-off-by: David Mosberger-Tang Reviewed-by: Claudiu Beznea Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20211221212531.4011609-2-davidm@egauge.net --- drivers/net/wireless/microchip/wilc1000/spi.c | 62 ++++++++++++++++++++++++-- drivers/net/wireless/microchip/wilc1000/wlan.c | 2 +- 2 files changed, 60 insertions(+), 4 deletions(-) (limited to 'drivers/net/wireless/microchip/wilc1000/spi.c') diff --git a/drivers/net/wireless/microchip/wilc1000/spi.c b/drivers/net/wireless/microchip/wilc1000/spi.c index 5ace9e3a56fc..2c2ed4b09efd 100644 --- a/drivers/net/wireless/microchip/wilc1000/spi.c +++ b/drivers/net/wireless/microchip/wilc1000/spi.c @@ -8,6 +8,7 @@ #include #include #include +#include #include "netdev.h" #include "cfg80211.h" @@ -45,6 +46,10 @@ struct wilc_spi { bool probing_crc; /* true if we're probing chip's CRC config */ bool crc7_enabled; /* true if crc7 is currently enabled */ bool crc16_enabled; /* true if crc16 is currently enabled */ + struct wilc_gpios { + struct gpio_desc *enable; /* ENABLE GPIO or NULL */ + struct gpio_desc *reset; /* RESET GPIO or NULL */ + } gpios; }; static const struct wilc_hif_func wilc_hif_spi; @@ -152,6 +157,50 @@ struct wilc_spi_special_cmd_rsp { u8 status; } __packed; +static int wilc_parse_gpios(struct wilc *wilc) +{ + struct spi_device *spi = to_spi_device(wilc->dev); + struct wilc_spi *spi_priv = wilc->bus_data; + struct wilc_gpios *gpios = &spi_priv->gpios; + + /* get ENABLE pin and deassert it (if it is defined): */ + gpios->enable = devm_gpiod_get_optional(&spi->dev, + "enable", GPIOD_OUT_LOW); + /* get RESET pin and assert it (if it is defined): */ + if (gpios->enable) { + /* if enable pin exists, reset must exist as well */ + gpios->reset = devm_gpiod_get(&spi->dev, + "reset", GPIOD_OUT_HIGH); + if (IS_ERR(gpios->reset)) { + dev_err(&spi->dev, "missing reset gpio.\n"); + return PTR_ERR(gpios->reset); + } + } else { + gpios->reset = devm_gpiod_get_optional(&spi->dev, + "reset", GPIOD_OUT_HIGH); + } + return 0; +} + +static void wilc_wlan_power(struct wilc *wilc, bool on) +{ + struct wilc_spi *spi_priv = wilc->bus_data; + struct wilc_gpios *gpios = &spi_priv->gpios; + + if (on) { + /* assert ENABLE: */ + gpiod_set_value(gpios->enable, 1); + mdelay(5); + /* deassert RESET: */ + gpiod_set_value(gpios->reset, 0); + } else { + /* assert RESET: */ + gpiod_set_value(gpios->reset, 1); + /* deassert ENABLE: */ + gpiod_set_value(gpios->enable, 0); + } +} + static int wilc_bus_probe(struct spi_device *spi) { int ret; @@ -171,6 +220,10 @@ static int wilc_bus_probe(struct spi_device *spi) wilc->bus_data = spi_priv; wilc->dev_irq_num = spi->irq; + ret = wilc_parse_gpios(wilc); + if (ret < 0) + goto netdev_cleanup; + wilc->rtc_clk = devm_clk_get_optional(&spi->dev, "rtc"); if (IS_ERR(wilc->rtc_clk)) { ret = PTR_ERR(wilc->rtc_clk); @@ -983,9 +1036,10 @@ static int wilc_spi_reset(struct wilc *wilc) static int wilc_spi_deinit(struct wilc *wilc) { - /* - * TODO: - */ + struct wilc_spi *spi_priv = wilc->bus_data; + + spi_priv->isinit = false; + wilc_wlan_power(wilc, false); return 0; } @@ -1006,6 +1060,8 @@ static int wilc_spi_init(struct wilc *wilc, bool resume) dev_err(&spi->dev, "Fail cmd read chip id...\n"); } + wilc_wlan_power(wilc, true); + /* * configure protocol */ diff --git a/drivers/net/wireless/microchip/wilc1000/wlan.c b/drivers/net/wireless/microchip/wilc1000/wlan.c index a2aa8894320f..fb5633a05fd5 100644 --- a/drivers/net/wireless/microchip/wilc1000/wlan.c +++ b/drivers/net/wireless/microchip/wilc1000/wlan.c @@ -1254,7 +1254,7 @@ void wilc_wlan_cleanup(struct net_device *dev) wilc->rx_buffer = NULL; kfree(wilc->tx_buffer); wilc->tx_buffer = NULL; - wilc->hif_func->hif_deinit(NULL); + wilc->hif_func->hif_deinit(wilc); } static int wilc_wlan_cfg_commit(struct wilc_vif *vif, int type, -- cgit v1.2.3