Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S935018AbcCPIiI (ORCPT ); Wed, 16 Mar 2016 04:38:08 -0400 Received: from mail.kernel.org ([198.145.29.136]:59494 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S964857AbcCPIIv (ORCPT ); Wed, 16 Mar 2016 04:08:51 -0400 From: lizf@kernel.org To: stable@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Stefan Agner , Marc Kleine-Budde , Zefan Li Subject: [PATCH 3.4 031/107] can: mcp251x: fix resume when device is down Date: Wed, 16 Mar 2016 16:05:25 +0800 Message-Id: <1458115601-5762-31-git-send-email-lizf@kernel.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1458115541-5712-1-git-send-email-lizf@kernel.org> References: <1458115541-5712-1-git-send-email-lizf@kernel.org> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2143 Lines: 64 From: Stefan Agner 3.4.111-rc1 review patch. If anyone has any objections, please let me know. ------------------ commit 25b401c1816ae64bcc5dcb1d39ab41812522a0ce upstream. If a valid power regulator or a dummy regulator is used (which happens to be the case when no regulator is specified), restart_work is queued no matter whether the device was running or not at suspend time. Since work queues get initialized in the ndo_open callback, resuming leads to a NULL pointer exception. Reverse exactly the steps executed at suspend time: - Enable the power regulator in any case - Enable the transceiver regulator if the device was running, even in case we have a power regulator - Queue restart_work only in case the device was running Fixes: bf66f3736a94 ("can: mcp251x: Move to threaded interrupts instead of workqueues.") Signed-off-by: Stefan Agner Signed-off-by: Marc Kleine-Budde [lizf: Backported to 3.4: - adjust filename - adjust context] Signed-off-by: Zefan Li --- drivers/net/can/mcp251x.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c index 9d60742..d07426d 100644 --- a/drivers/net/can/mcp251x.c +++ b/drivers/net/can/mcp251x.c @@ -1161,18 +1161,17 @@ static int mcp251x_can_resume(struct spi_device *spi) struct mcp251x_platform_data *pdata = spi->dev.platform_data; struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev); - if (priv->after_suspend & AFTER_SUSPEND_POWER) { + if (priv->after_suspend & AFTER_SUSPEND_POWER) pdata->power_enable(1); + + if (priv->after_suspend & AFTER_SUSPEND_UP) { + if (pdata->transceiver_enable) + pdata->transceiver_enable(1); queue_work(priv->wq, &priv->restart_work); } else { - if (priv->after_suspend & AFTER_SUSPEND_UP) { - if (pdata->transceiver_enable) - pdata->transceiver_enable(1); - queue_work(priv->wq, &priv->restart_work); - } else { - priv->after_suspend = 0; - } + priv->after_suspend = 0; } + priv->force_quit = 0; enable_irq(spi->irq); return 0; -- 1.9.1