From 1dbac5c578ead0d0f20a06b036d19c109a5a4fb9 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 3 Nov 2015 15:03:33 +0100 Subject: NFC: nfcmrvl: fix SPI driver dependencies The newly added nfcmrvl_spi driver uses the spi_nci infrastructure, but does not have a Kconfig dependency on that, so we can get a link-time error: drivers/built-in.o: In function `nfcmrvl_spi_nci_send': (.text+0x1428dc): undefined reference to `nci_spi_send' drivers/built-in.o: In function `nfcmrvl_spi_probe': (.text+0x142a24): undefined reference to `nci_spi_allocate_spi' drivers/built-in.o: In function `nfcmrvl_spi_int_irq_thread_fn': (.text+0x142abc): undefined reference to `nci_spi_read' This clarifies the dependency. Signed-off-by: Arnd Bergmann Fixes: caf6e49bf6d0 ("NFC: nfcmrvl: add spi driver") Signed-off-by: Samuel Ortiz diff --git a/drivers/nfc/nfcmrvl/Kconfig b/drivers/nfc/nfcmrvl/Kconfig index 444ca94..670af76 100644 --- a/drivers/nfc/nfcmrvl/Kconfig +++ b/drivers/nfc/nfcmrvl/Kconfig @@ -44,7 +44,7 @@ config NFC_MRVL_I2C config NFC_MRVL_SPI tristate "Marvell NFC-over-SPI driver" - depends on NFC_MRVL && SPI + depends on NFC_MRVL && NFC_NCI_SPI help Marvell NFC-over-SPI driver. -- cgit v0.10.2 From feacf0024bfea807d7302d4aff83b391ac6e4077 Mon Sep 17 00:00:00 2001 From: Vincent Cuissard Date: Tue, 3 Nov 2015 19:19:32 +0100 Subject: NFC: nfcmrvl: avoid UART break control during FW download BootROM does not support any form of power management during FW download. On UART, the driver shall not try to send breaks. Signed-off-by: Vincent Cuissard Signed-off-by: Samuel Ortiz diff --git a/drivers/nfc/nfcmrvl/uart.c b/drivers/nfc/nfcmrvl/uart.c index f3d041c..b33249b 100644 --- a/drivers/nfc/nfcmrvl/uart.c +++ b/drivers/nfc/nfcmrvl/uart.c @@ -152,10 +152,6 @@ static int nfcmrvl_nci_uart_open(struct nci_uart *nu) nu->drv_data = priv; nu->ndev = priv->ndev; - /* Set BREAK */ - if (priv->config.break_control && nu->tty->ops->break_ctl) - nu->tty->ops->break_ctl(nu->tty, -1); - return 0; } @@ -174,6 +170,9 @@ static void nfcmrvl_nci_uart_tx_start(struct nci_uart *nu) { struct nfcmrvl_private *priv = (struct nfcmrvl_private *)nu->drv_data; + if (priv->ndev->nfc_dev->fw_download_in_progress) + return; + /* Remove BREAK to wake up the NFCC */ if (priv->config.break_control && nu->tty->ops->break_ctl) { nu->tty->ops->break_ctl(nu->tty, 0); @@ -185,6 +184,9 @@ static void nfcmrvl_nci_uart_tx_done(struct nci_uart *nu) { struct nfcmrvl_private *priv = (struct nfcmrvl_private *)nu->drv_data; + if (priv->ndev->nfc_dev->fw_download_in_progress) + return; + /* ** To ensure that if the NFCC goes in DEEP SLEEP sate we can wake him ** up. we set BREAK. Once we will be ready to send again we will remove -- cgit v0.10.2 From d2d2e6456ebccb5d31163dcc3191d83183bbd0b5 Mon Sep 17 00:00:00 2001 From: Vincent Cuissard Date: Tue, 3 Nov 2015 19:19:33 +0100 Subject: NFC: nfcmrvl: add a small wait after setting UART break A small wait is inserted to ensure that controller has enough time to handle the break character. Signed-off-by: Vincent Cuissard Signed-off-by: Samuel Ortiz diff --git a/drivers/nfc/nfcmrvl/uart.c b/drivers/nfc/nfcmrvl/uart.c index b33249b..b4c4796 100644 --- a/drivers/nfc/nfcmrvl/uart.c +++ b/drivers/nfc/nfcmrvl/uart.c @@ -192,8 +192,10 @@ static void nfcmrvl_nci_uart_tx_done(struct nci_uart *nu) ** up. we set BREAK. Once we will be ready to send again we will remove ** it. */ - if (priv->config.break_control && nu->tty->ops->break_ctl) + if (priv->config.break_control && nu->tty->ops->break_ctl) { nu->tty->ops->break_ctl(nu->tty, -1); + usleep_range(1000, 3000); + } } static struct nci_uart nfcmrvl_nci_uart = { -- cgit v0.10.2 From b2fe288eac7247f83b52377b4134ecc5cd856bf2 Mon Sep 17 00:00:00 2001 From: Vincent Cuissard Date: Tue, 3 Nov 2015 19:19:34 +0100 Subject: NFC: nfcmrvl: free reset gpio Reset GPIO shall be freed by the driver since the device used in devm_ calls can be still valid on unregister. If user removes the module and inserts it again, the devm_gpio_request will fail because the underlying physical device (e.g i2c) was not removed so the device management won't have freed the gpio. Signed-off-by: Vincent Cuissard Signed-off-by: Samuel Ortiz diff --git a/drivers/nfc/nfcmrvl/main.c b/drivers/nfc/nfcmrvl/main.c index 8079ae0..743c74c 100644 --- a/drivers/nfc/nfcmrvl/main.c +++ b/drivers/nfc/nfcmrvl/main.c @@ -194,6 +194,9 @@ void nfcmrvl_nci_unregister_dev(struct nfcmrvl_private *priv) nfcmrvl_fw_dnld_deinit(priv); + if (priv->config.reset_n_io) + devm_gpio_free(priv->dev, priv->config.reset_n_io); + nci_unregister_device(ndev); nci_free_device(ndev); kfree(priv); -- cgit v0.10.2 From 6f8c53695d6521c36052d39e29ac1e51ef37eba7 Mon Sep 17 00:00:00 2001 From: Vincent Cuissard Date: Tue, 3 Nov 2015 19:19:35 +0100 Subject: NFC: nfcmrvl: remove unneeded CONFIG_OF switches Signed-off-by: Vincent Cuissard Signed-off-by: Samuel Ortiz diff --git a/drivers/nfc/nfcmrvl/main.c b/drivers/nfc/nfcmrvl/main.c index 743c74c..51c8240 100644 --- a/drivers/nfc/nfcmrvl/main.c +++ b/drivers/nfc/nfcmrvl/main.c @@ -254,8 +254,6 @@ void nfcmrvl_chip_halt(struct nfcmrvl_private *priv) gpio_set_value(priv->config.reset_n_io, 0); } -#ifdef CONFIG_OF - int nfcmrvl_parse_dt(struct device_node *node, struct nfcmrvl_platform_data *pdata) { @@ -278,16 +276,6 @@ int nfcmrvl_parse_dt(struct device_node *node, return 0; } - -#else - -int nfcmrvl_parse_dt(struct device_node *node, - struct nfcmrvl_platform_data *pdata) -{ - return -ENODEV; -} - -#endif EXPORT_SYMBOL_GPL(nfcmrvl_parse_dt); MODULE_AUTHOR("Marvell International Ltd."); diff --git a/drivers/nfc/nfcmrvl/uart.c b/drivers/nfc/nfcmrvl/uart.c index b4c4796..83a99e3 100644 --- a/drivers/nfc/nfcmrvl/uart.c +++ b/drivers/nfc/nfcmrvl/uart.c @@ -67,8 +67,6 @@ static struct nfcmrvl_if_ops uart_ops = { .nci_update_config = nfcmrvl_uart_nci_update_config }; -#ifdef CONFIG_OF - static int nfcmrvl_uart_parse_dt(struct device_node *node, struct nfcmrvl_platform_data *pdata) { @@ -102,16 +100,6 @@ static int nfcmrvl_uart_parse_dt(struct device_node *node, return 0; } -#else - -static int nfcmrvl_uart_parse_dt(struct device_node *node, - struct nfcmrvl_platform_data *pdata) -{ - return -ENODEV; -} - -#endif - /* ** NCI UART OPS */ -- cgit v0.10.2 From 82aff3ea3b87892ce1476dad83de211741b3ac00 Mon Sep 17 00:00:00 2001 From: Vincent Cuissard Date: Tue, 3 Nov 2015 19:19:36 +0100 Subject: NFC: nfcmrvl: avoid being stuck on FW dnld timeout FW Download procedure can block on del_timer_sync because the timer is not running. This patch check that timer is scheduled before cancelling it. Signed-off-by: Vincent Cuissard Signed-off-by: Samuel Ortiz diff --git a/drivers/nfc/nfcmrvl/fw_dnld.c b/drivers/nfc/nfcmrvl/fw_dnld.c index bfa7713..f8dcdf4 100644 --- a/drivers/nfc/nfcmrvl/fw_dnld.c +++ b/drivers/nfc/nfcmrvl/fw_dnld.c @@ -113,9 +113,12 @@ static void fw_dnld_over(struct nfcmrvl_private *priv, u32 error) } atomic_set(&priv->ndev->cmd_cnt, 0); - del_timer_sync(&priv->ndev->cmd_timer); - del_timer_sync(&priv->fw_dnld.timer); + if (timer_pending(&priv->ndev->cmd_timer)) + del_timer_sync(&priv->ndev->cmd_timer); + + if (timer_pending(&priv->fw_dnld.timer)) + del_timer_sync(&priv->fw_dnld.timer); nfc_info(priv->dev, "FW loading over (%d)]\n", error); @@ -472,9 +475,12 @@ void nfcmrvl_fw_dnld_deinit(struct nfcmrvl_private *priv) void nfcmrvl_fw_dnld_recv_frame(struct nfcmrvl_private *priv, struct sk_buff *skb) { + /* Discard command timer */ + if (timer_pending(&priv->ndev->cmd_timer)) + del_timer_sync(&priv->ndev->cmd_timer); + /* Allow next command */ atomic_set(&priv->ndev->cmd_cnt, 1); - del_timer_sync(&priv->ndev->cmd_timer); /* Queue and trigger rx work */ skb_queue_tail(&priv->fw_dnld.rx_q, skb); -- cgit v0.10.2