From patchwork Tue Mar 19 17:26:47 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dan Murphy X-Patchwork-Id: 160598 Delivered-To: patch@linaro.org Received: by 2002:a02:5cc1:0:0:0:0:0 with SMTP id w62csp4139477jad; Tue, 19 Mar 2019 10:27:34 -0700 (PDT) X-Google-Smtp-Source: APXvYqyYpqkD7In+BNRBQ0zR6bZzljD9nVkc6d1k5JSIeQ+KZbpOINF62lSlGFE/rqFiOoBGgJrs X-Received: by 2002:a63:7e08:: with SMTP id z8mr2883835pgc.239.1553016454540; Tue, 19 Mar 2019 10:27:34 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1553016454; cv=none; d=google.com; s=arc-20160816; b=LuDOsHRSTGHqnWEIPvwzCCNkYT7GTPj9eYpYzBLqmfJx6+Ob7SzHxyKrRccKt0SDDA eQ/Yg1WWUmIEcC4AgiOG+Ay7uXRXLhMV2naKjsNbtUB/hS6RDjerZE/Fg/zB69l400pa ivcbYTmHphPtXQbXIR37UzTLr00/5k1Esn98nA+C7T1Kf8VBc/t+bS+5c46uJcVE6Ids BDUmf/TTtdXhbQzHrchDaz/3S6M0JAtNJeJSsWbbvxRkApnWpfbuZIwRyEbpflWwj9xX bBTQ+YyeGoHLtz9ZfdaFIPNxdTyJPrKLj/nAR0XnqgQarTQ9e6yf7pfwTtWggLDhUZnM o7Pw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:message-id:date:subject:cc :to:from:dkim-signature; bh=bR/u5QFX/vmJKRXwDqGDUz9v7pX8Zma7HcEKlOBkvQM=; b=tZs3dJLCJBBzztIzlct45gbvpreSimT4hyY5l3BbcBLzUU3WjjgfFCnchMy86kmF/H co/GY9pzjdAzi4aSaxY7MDsJ5nyI027sjkEIVcFj8+VZBpDO5BZHx85tUNLB4HNL1Pzk UyxISCaMCJoGDfiq2eeZV5ltYJE8BlEboLg/G43H241Wt168/YEGoyMG0jGDBMm9xK2H fo6Wwgq+e7CIWqQu1icaP3lLdG0BemYnvMEofWX0GW68nBBqT+Ze8hxbG3pjAcYRK7G4 L1eLnEKTgz21PqmKUizFe7kpob0czrwxULotJImqsGt4A4HSk+i8fLHdOfHd/cmoMm14 25Tg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=FJziigXK; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id w5si11333750pgs.268.2019.03.19.10.27.33; Tue, 19 Mar 2019 10:27:34 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=FJziigXK; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727850AbfCSR1b (ORCPT + 31 others); Tue, 19 Mar 2019 13:27:31 -0400 Received: from lelv0142.ext.ti.com ([198.47.23.249]:52434 "EHLO lelv0142.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727667AbfCSR11 (ORCPT ); Tue, 19 Mar 2019 13:27:27 -0400 Received: from lelv0266.itg.ti.com ([10.180.67.225]) by lelv0142.ext.ti.com (8.15.2/8.15.2) with ESMTP id x2JHRG4J092745; Tue, 19 Mar 2019 12:27:16 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1553016436; bh=bR/u5QFX/vmJKRXwDqGDUz9v7pX8Zma7HcEKlOBkvQM=; h=From:To:CC:Subject:Date; b=FJziigXK9k6Fm15X77XbbGBJzMukMBZWVSoXu2vKyWTwDJTF9xkW6gcba5YEn3VwC +M2MJTa/VaFxyIXXQGCkjUy9QzKXEP3mGmmPo2koDIN9340ZO6Hh7KnGVDYtTa68n9 AwQLQ5u3RK1yV3+g99/psSyqkCoMD6d/3Lrmrve8= Received: from DLEE113.ent.ti.com (dlee113.ent.ti.com [157.170.170.24]) by lelv0266.itg.ti.com (8.15.2/8.15.2) with ESMTPS id x2JHRGsS086920 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 19 Mar 2019 12:27:16 -0500 Received: from DLEE107.ent.ti.com (157.170.170.37) by DLEE113.ent.ti.com (157.170.170.24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1713.5; Tue, 19 Mar 2019 12:27:15 -0500 Received: from dlep32.itg.ti.com (157.170.170.100) by DLEE107.ent.ti.com (157.170.170.37) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.1713.5 via Frontend Transport; Tue, 19 Mar 2019 12:27:15 -0500 Received: from localhost (ileax41-snat.itg.ti.com [10.172.224.153]) by dlep32.itg.ti.com (8.14.3/8.13.8) with ESMTP id x2JHRFnU011772; Tue, 19 Mar 2019 12:27:15 -0500 From: Dan Murphy To: , , CC: , , , Dan Murphy Subject: [PATCH v11 1/5] can: m_can: Create a m_can platform framework Date: Tue, 19 Mar 2019 12:26:47 -0500 Message-ID: <20190319172651.10012-1-dmurphy@ti.com> X-Mailer: git-send-email 2.12.2 MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Create a m_can platform framework that peripheral devices can register to and use common code and register sets. The peripheral devices may provide read/write and configuration support of the IP. Acked-by: Wolfgang Grandegger Signed-off-by: Dan Murphy --- v11 - Fixed final checkpatch issue add comment on needed skb queue as future enhancement - https://lore.kernel.org/patchwork/patch/1051179/ v10 - Fixed misspelled peripheral, moved index declaration, and added back stop queue on TX_BUSY in hard_xmit - https://lore.kernel.org/patchwork/patch/1050487/ v9 - Added back the CSR clearing as this is needed for TCAN device, fixed clean function to clean index for version > 30, removed extra skb free and fixed work handler to handle FIFO full for perpheral devices - https://lore.kernel.org/patchwork/patch/1050120/ v8 - Added a clean function for the tx_skb, cleaned up skb on BUS_OFF and on xmit BUSY - https://lore.kernel.org/patchwork/patch/1047980/ v7 - Fixed remaining new checkpatch issues, removed CSR setting, fixed tx hard start function to return tx_busy, and renamed device callbacks - https://lore.kernel.org/patchwork/patch/1047220/ v6 - Squashed platform patch to this patch for bissectablity, fixed coding style issues, updated Kconfig help, placed mcan reg offsets back into c file, renamed priv->skb to priv->tx_skb and cleared perp interrupts at ISR start - Patch 1 comments - https://lore.kernel.org/patchwork/patch/1042446/ Patch 2 comments - https://lore.kernel.org/patchwork/patch/1042442/ drivers/net/can/m_can/Kconfig | 13 +- drivers/net/can/m_can/Makefile | 1 + drivers/net/can/m_can/m_can.c | 740 +++++++++++++------------ drivers/net/can/m_can/m_can.h | 110 ++++ drivers/net/can/m_can/m_can_platform.c | 202 +++++++ 5 files changed, 721 insertions(+), 345 deletions(-) create mode 100644 drivers/net/can/m_can/m_can.h create mode 100644 drivers/net/can/m_can/m_can_platform.c -- 2.20.1.390.gb5101f9297 diff --git a/drivers/net/can/m_can/Kconfig b/drivers/net/can/m_can/Kconfig index 04f20dd39007..f7119fd72df4 100644 --- a/drivers/net/can/m_can/Kconfig +++ b/drivers/net/can/m_can/Kconfig @@ -1,5 +1,14 @@ config CAN_M_CAN + tristate "Bosch M_CAN support" + ---help--- + Say Y here if you want support for Bosch M_CAN controller framework. + This is common support for devices that embed the Bosch M_CAN IP. + +config CAN_M_CAN_PLATFORM + tristate "Bosch M_CAN support for io-mapped devices" depends on HAS_IOMEM - tristate "Bosch M_CAN devices" + depends on CAN_M_CAN ---help--- - Say Y here if you want to support for Bosch M_CAN controller. + Say Y here if you want support for IO Mapped Bosch M_CAN controller. + This support is for devices that have the Bosch M_CAN controller + IP embedded into the device and the IP is IO Mapped to the processor. diff --git a/drivers/net/can/m_can/Makefile b/drivers/net/can/m_can/Makefile index 8bbd7f24f5be..057bbcdb3c74 100644 --- a/drivers/net/can/m_can/Makefile +++ b/drivers/net/can/m_can/Makefile @@ -3,3 +3,4 @@ # obj-$(CONFIG_CAN_M_CAN) += m_can.o +obj-$(CONFIG_CAN_M_CAN_PLATFORM) += m_can_platform.o diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c index 9b449400376b..98641a0046a6 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c @@ -1,20 +1,14 @@ -/* - * CAN bus driver for Bosch M_CAN controller - * - * Copyright (C) 2014 Freescale Semiconductor, Inc. - * Dong Aisheng - * - * Bosch M_CAN user manual can be obtained from: +// SPDX-License-Identifier: GPL-2.0 +// CAN bus driver for Bosch M_CAN controller +// Copyright (C) 2014 Freescale Semiconductor, Inc. +// Dong Aisheng +// Copyright (C) 2018-19 Texas Instruments Incorporated - http://www.ti.com/ + +/* Bosch M_CAN user manual can be obtained from: * http://www.bosch-semiconductors.de/media/pdf_1/ipmodules_1/m_can/ * mcan_users_manual_v302.pdf - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. */ -#include -#include #include #include #include @@ -28,11 +22,7 @@ #include #include -/* napi related */ -#define M_CAN_NAPI_WEIGHT 64 - -/* message ram configuration data length */ -#define MRAM_CFG_LEN 8 +#include "m_can.h" /* registers definition */ enum m_can_reg { @@ -86,28 +76,11 @@ enum m_can_reg { M_CAN_TXEFA = 0xf8, }; -/* m_can lec values */ -enum m_can_lec_type { - LEC_NO_ERROR = 0, - LEC_STUFF_ERROR, - LEC_FORM_ERROR, - LEC_ACK_ERROR, - LEC_BIT1_ERROR, - LEC_BIT0_ERROR, - LEC_CRC_ERROR, - LEC_UNUSED, -}; +/* napi related */ +#define M_CAN_NAPI_WEIGHT 64 -enum m_can_mram_cfg { - MRAM_SIDF = 0, - MRAM_XIDF, - MRAM_RXF0, - MRAM_RXF1, - MRAM_RXB, - MRAM_TXE, - MRAM_TXB, - MRAM_CFG_NUM, -}; +/* message ram configuration data length */ +#define MRAM_CFG_LEN 8 /* Core Release Register (CREL) */ #define CREL_REL_SHIFT 28 @@ -347,74 +320,86 @@ enum m_can_mram_cfg { #define TX_EVENT_MM_SHIFT TX_BUF_MM_SHIFT #define TX_EVENT_MM_MASK (0xff << TX_EVENT_MM_SHIFT) -/* address offset and element number for each FIFO/Buffer in the Message RAM */ -struct mram_cfg { - u16 off; - u8 num; -}; - -/* m_can private data structure */ -struct m_can_priv { - struct can_priv can; /* must be the first member */ - struct napi_struct napi; - struct net_device *dev; - struct device *device; - struct clk *hclk; - struct clk *cclk; - void __iomem *base; - u32 irqstatus; - int version; - - /* message ram configuration */ - void __iomem *mram_base; - struct mram_cfg mcfg[MRAM_CFG_NUM]; -}; +static u32 m_can_read(struct m_can_priv *priv, enum m_can_reg reg) +{ + if (priv->ops->read_reg) + return priv->ops->read_reg(priv, reg); + else + return -EINVAL; +} -static inline u32 m_can_read(const struct m_can_priv *priv, enum m_can_reg reg) +static int m_can_write(struct m_can_priv *priv, enum m_can_reg reg, u32 val) { - return readl(priv->base + reg); + if (priv->ops->write_reg) + return priv->ops->write_reg(priv, reg, val); + else + return -EINVAL; } -static inline void m_can_write(const struct m_can_priv *priv, - enum m_can_reg reg, u32 val) +static u32 m_can_fifo_read(struct m_can_priv *priv, + u32 fgi, unsigned int offset) { - writel(val, priv->base + reg); + u32 addr_offset = priv->mcfg[MRAM_RXF0].off + fgi * RXF0_ELEMENT_SIZE + + offset; + + if (priv->ops->read_fifo) + return priv->ops->read_fifo(priv, addr_offset); + else + return -EINVAL; } -static inline u32 m_can_fifo_read(const struct m_can_priv *priv, - u32 fgi, unsigned int offset) +static u32 m_can_fifo_write(struct m_can_priv *priv, + u32 fpi, unsigned int offset, u32 val) { - return readl(priv->mram_base + priv->mcfg[MRAM_RXF0].off + - fgi * RXF0_ELEMENT_SIZE + offset); + u32 addr_offset = priv->mcfg[MRAM_TXB].off + fpi * TXB_ELEMENT_SIZE + + offset; + + if (priv->ops->write_fifo) + return priv->ops->write_fifo(priv, addr_offset, val); + else + return -EINVAL; } -static inline void m_can_fifo_write(const struct m_can_priv *priv, - u32 fpi, unsigned int offset, u32 val) +static u32 m_can_fifo_write_no_off(struct m_can_priv *priv, + u32 fpi, u32 val) { - writel(val, priv->mram_base + priv->mcfg[MRAM_TXB].off + - fpi * TXB_ELEMENT_SIZE + offset); + if (priv->ops->write_fifo) + return priv->ops->write_fifo(priv, fpi, val); + else + return 0; } -static inline u32 m_can_txe_fifo_read(const struct m_can_priv *priv, - u32 fgi, - u32 offset) { - return readl(priv->mram_base + priv->mcfg[MRAM_TXE].off + - fgi * TXE_ELEMENT_SIZE + offset); +static u32 m_can_txe_fifo_read(struct m_can_priv *priv, u32 fgi, u32 offset) +{ + u32 addr_offset = priv->mcfg[MRAM_TXE].off + fgi * TXE_ELEMENT_SIZE + + offset; + + if (priv->ops->read_fifo) + return priv->ops->read_fifo(priv, addr_offset); + else + return -EINVAL; } -static inline bool m_can_tx_fifo_full(const struct m_can_priv *priv) +static inline bool m_can_tx_fifo_full(struct m_can_priv *priv) { return !!(m_can_read(priv, M_CAN_TXFQS) & TXFQS_TFQF); } -static inline void m_can_config_endisable(const struct m_can_priv *priv, - bool enable) +void m_can_config_endisable(struct m_can_priv *priv, bool enable) { u32 cccr = m_can_read(priv, M_CAN_CCCR); u32 timeout = 10; u32 val = 0; + /* Clear the Clock stop request if it was set */ + if (cccr & CCCR_CSR) + cccr &= ~CCCR_CSR; + if (enable) { + /* Clear the Clock stop request if it was set */ + if (cccr & CCCR_CSR) + cccr &= ~CCCR_CSR; + /* enable m_can configuration */ m_can_write(priv, M_CAN_CCCR, cccr | CCCR_INIT); udelay(5); @@ -430,7 +415,7 @@ static inline void m_can_config_endisable(const struct m_can_priv *priv, while ((m_can_read(priv, M_CAN_CCCR) & (CCCR_INIT | CCCR_CCE)) != val) { if (timeout == 0) { - netdev_warn(priv->dev, "Failed to init module\n"); + netdev_warn(priv->net, "Failed to init module\n"); return; } timeout--; @@ -438,17 +423,34 @@ static inline void m_can_config_endisable(const struct m_can_priv *priv, } } -static inline void m_can_enable_all_interrupts(const struct m_can_priv *priv) +static inline void m_can_enable_all_interrupts(struct m_can_priv *priv) { /* Only interrupt line 0 is used in this driver */ m_can_write(priv, M_CAN_ILE, ILE_EINT0); } -static inline void m_can_disable_all_interrupts(const struct m_can_priv *priv) +static inline void m_can_disable_all_interrupts(struct m_can_priv *priv) { m_can_write(priv, M_CAN_ILE, 0x0); } +static void m_can_clean(struct net_device *net) +{ + struct m_can_priv *priv = netdev_priv(net); + + if (priv->tx_skb) { + int putidx = 0; + + net->stats.tx_errors++; + if (priv->version > 30) + putidx = ((m_can_read(priv, M_CAN_TXFQS) & + TXFQS_TFQPI_MASK) >> TXFQS_TFQPI_SHIFT); + + can_free_echo_skb(priv->net, putidx); + priv->tx_skb = NULL; + } +} + static void m_can_read_fifo(struct net_device *dev, u32 rxfs) { struct net_device_stats *stats = &dev->stats; @@ -633,9 +635,12 @@ static int m_can_clk_start(struct m_can_priv *priv) { int err; - err = pm_runtime_get_sync(priv->device); + if (priv->pm_clock_support == 0) + return 0; + + err = pm_runtime_get_sync(priv->dev); if (err < 0) { - pm_runtime_put_noidle(priv->device); + pm_runtime_put_noidle(priv->dev); return err; } @@ -644,7 +649,8 @@ static int m_can_clk_start(struct m_can_priv *priv) static void m_can_clk_stop(struct m_can_priv *priv) { - pm_runtime_put_sync(priv->device); + if (priv->pm_clock_support) + pm_runtime_put_sync(priv->dev); } static int m_can_get_berr_counter(const struct net_device *dev, @@ -811,9 +817,8 @@ static int m_can_handle_bus_errors(struct net_device *dev, u32 irqstatus, return work_done; } -static int m_can_poll(struct napi_struct *napi, int quota) +static int m_can_rx_handler(struct net_device *dev, int quota) { - struct net_device *dev = napi->dev; struct m_can_priv *priv = netdev_priv(dev); int work_done = 0; u32 irqstatus, psr; @@ -831,13 +836,33 @@ static int m_can_poll(struct napi_struct *napi, int quota) if (irqstatus & IR_RF0N) work_done += m_can_do_rx_poll(dev, (quota - work_done)); +end: + return work_done; +} + +static int m_can_rx_peripheral(struct net_device *dev) +{ + struct m_can_priv *priv = netdev_priv(dev); + m_can_rx_handler(dev, 1); + + m_can_enable_all_interrupts(priv); + + return 0; +} + +static int m_can_poll(struct napi_struct *napi, int quota) +{ + struct net_device *dev = napi->dev; + struct m_can_priv *priv = netdev_priv(dev); + int work_done; + + work_done = m_can_rx_handler(dev, quota); if (work_done < quota) { napi_complete_done(napi, work_done); m_can_enable_all_interrupts(priv); } -end: return work_done; } @@ -894,6 +919,9 @@ static irqreturn_t m_can_isr(int irq, void *dev_id) if (ir & IR_ALL_INT) m_can_write(priv, M_CAN_IR, ir); + if (priv->ops->clear_interrupts) + priv->ops->clear_interrupts(priv); + /* schedule NAPI in case of * - rx IRQ * - state change IRQ @@ -902,7 +930,10 @@ static irqreturn_t m_can_isr(int irq, void *dev_id) if ((ir & IR_RF0N) || (ir & IR_ERR_ALL_30X)) { priv->irqstatus = ir; m_can_disable_all_interrupts(priv); - napi_schedule(&priv->napi); + if (!priv->is_peripheral) + napi_schedule(&priv->napi); + else + m_can_rx_peripheral(dev); } if (priv->version == 30) { @@ -1155,6 +1186,9 @@ static void m_can_chip_config(struct net_device *dev) m_can_set_bittiming(dev); m_can_config_endisable(priv, false); + + if (priv->ops->init) + priv->ops->init(priv); } static void m_can_start(struct net_device *dev) @@ -1173,6 +1207,7 @@ static int m_can_set_mode(struct net_device *dev, enum can_mode mode) { switch (mode) { case CAN_MODE_START: + m_can_clean(dev); m_can_start(dev); netif_wake_queue(dev); break; @@ -1188,20 +1223,17 @@ static int m_can_set_mode(struct net_device *dev, enum can_mode mode) * else it returns the release and step coded as: * return value = 10 * + 1 * */ -static int m_can_check_core_release(void __iomem *m_can_base) +static int m_can_check_core_release(struct m_can_priv *priv) { u32 crel_reg; u8 rel; u8 step; int res; - struct m_can_priv temp_priv = { - .base = m_can_base - }; /* Read Core Release Version and split into version number * Example: Version 3.2.1 => rel = 3; step = 2; substep = 1; */ - crel_reg = m_can_read(&temp_priv, M_CAN_CREL); + crel_reg = m_can_read(priv, M_CAN_CREL); rel = (u8)((crel_reg & CREL_REL_MASK) >> CREL_REL_SHIFT); step = (u8)((crel_reg & CREL_STEP_MASK) >> CREL_STEP_SHIFT); @@ -1219,18 +1251,26 @@ static int m_can_check_core_release(void __iomem *m_can_base) /* Selectable Non ISO support only in version 3.2.x * This function checks if the bit is writable. */ -static bool m_can_niso_supported(const struct m_can_priv *priv) +static bool m_can_niso_supported(struct m_can_priv *priv) { - u32 cccr_reg, cccr_poll; - int niso_timeout; + u32 cccr_reg, cccr_poll = 0; + int niso_timeout = -ETIMEDOUT; + int i; m_can_config_endisable(priv, true); cccr_reg = m_can_read(priv, M_CAN_CCCR); cccr_reg |= CCCR_NISO; m_can_write(priv, M_CAN_CCCR, cccr_reg); - niso_timeout = readl_poll_timeout((priv->base + M_CAN_CCCR), cccr_poll, - (cccr_poll == cccr_reg), 0, 10); + for (i = 0; i <= 10; i++) { + cccr_poll = m_can_read(priv, M_CAN_CCCR); + if (cccr_poll == cccr_reg) { + niso_timeout = 0; + break; + } + + usleep_range(1, 5); + } /* Clear NISO */ cccr_reg &= ~(CCCR_NISO); @@ -1242,107 +1282,79 @@ static bool m_can_niso_supported(const struct m_can_priv *priv) return !niso_timeout; } -static int m_can_dev_setup(struct platform_device *pdev, struct net_device *dev, - void __iomem *addr) +static int m_can_dev_setup(struct m_can_priv *m_can_dev) { - struct m_can_priv *priv; + struct net_device *dev = m_can_dev->net; int m_can_version; - m_can_version = m_can_check_core_release(addr); + m_can_version = m_can_check_core_release(m_can_dev); /* return if unsupported version */ if (!m_can_version) { - dev_err(&pdev->dev, "Unsupported version number: %2d", + dev_err(m_can_dev->dev, "Unsupported version number: %2d", m_can_version); return -EINVAL; } - priv = netdev_priv(dev); - netif_napi_add(dev, &priv->napi, m_can_poll, M_CAN_NAPI_WEIGHT); + if (!m_can_dev->is_peripheral) + netif_napi_add(dev, &m_can_dev->napi, + m_can_poll, M_CAN_NAPI_WEIGHT); /* Shared properties of all M_CAN versions */ - priv->version = m_can_version; - priv->dev = dev; - priv->base = addr; - priv->can.do_set_mode = m_can_set_mode; - priv->can.do_get_berr_counter = m_can_get_berr_counter; + m_can_dev->version = m_can_version; + m_can_dev->can.do_set_mode = m_can_set_mode; + m_can_dev->can.do_get_berr_counter = m_can_get_berr_counter; /* Set M_CAN supported operations */ - priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK | + m_can_dev->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK | CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_BERR_REPORTING | CAN_CTRLMODE_FD; /* Set properties depending on M_CAN version */ - switch (priv->version) { + switch (m_can_dev->version) { case 30: /* CAN_CTRLMODE_FD_NON_ISO is fixed with M_CAN IP v3.0.x */ can_set_static_ctrlmode(dev, CAN_CTRLMODE_FD_NON_ISO); - priv->can.bittiming_const = &m_can_bittiming_const_30X; - priv->can.data_bittiming_const = - &m_can_data_bittiming_const_30X; + m_can_dev->can.bittiming_const = m_can_dev->bit_timing ? + m_can_dev->bit_timing : &m_can_bittiming_const_30X; + + m_can_dev->can.data_bittiming_const = m_can_dev->data_timing ? + m_can_dev->data_timing : + &m_can_data_bittiming_const_30X; break; case 31: /* CAN_CTRLMODE_FD_NON_ISO is fixed with M_CAN IP v3.1.x */ can_set_static_ctrlmode(dev, CAN_CTRLMODE_FD_NON_ISO); - priv->can.bittiming_const = &m_can_bittiming_const_31X; - priv->can.data_bittiming_const = - &m_can_data_bittiming_const_31X; + m_can_dev->can.bittiming_const = m_can_dev->bit_timing ? + m_can_dev->bit_timing : &m_can_bittiming_const_31X; + + m_can_dev->can.data_bittiming_const = m_can_dev->data_timing ? + m_can_dev->data_timing : + &m_can_data_bittiming_const_31X; break; case 32: - priv->can.bittiming_const = &m_can_bittiming_const_31X; - priv->can.data_bittiming_const = - &m_can_data_bittiming_const_31X; - priv->can.ctrlmode_supported |= (m_can_niso_supported(priv) + m_can_dev->can.bittiming_const = m_can_dev->bit_timing ? + m_can_dev->bit_timing : &m_can_bittiming_const_31X; + + m_can_dev->can.data_bittiming_const = m_can_dev->data_timing ? + m_can_dev->data_timing : + &m_can_data_bittiming_const_31X; + + m_can_dev->can.ctrlmode_supported |= + (m_can_niso_supported(m_can_dev) ? CAN_CTRLMODE_FD_NON_ISO : 0); break; default: - dev_err(&pdev->dev, "Unsupported version number: %2d", - priv->version); + dev_err(m_can_dev->dev, "Unsupported version number: %2d", + m_can_dev->version); return -EINVAL; } - return 0; -} - -static int m_can_open(struct net_device *dev) -{ - struct m_can_priv *priv = netdev_priv(dev); - int err; - - err = m_can_clk_start(priv); - if (err) - return err; - - /* open the can device */ - err = open_candev(dev); - if (err) { - netdev_err(dev, "failed to open can device\n"); - goto exit_disable_clks; - } - - /* register interrupt handler */ - err = request_irq(dev->irq, m_can_isr, IRQF_SHARED, dev->name, - dev); - if (err < 0) { - netdev_err(dev, "failed to request interrupt\n"); - goto exit_irq_fail; - } - - /* start the m_can controller */ - m_can_start(dev); - - can_led_event(dev, CAN_LED_EVENT_OPEN); - napi_enable(&priv->napi); - netif_start_queue(dev); + if (m_can_dev->ops->init) + m_can_dev->ops->init(m_can_dev); return 0; - -exit_irq_fail: - close_candev(dev); -exit_disable_clks: - m_can_clk_stop(priv); - return err; } static void m_can_stop(struct net_device *dev) @@ -1361,10 +1373,18 @@ static int m_can_close(struct net_device *dev) struct m_can_priv *priv = netdev_priv(dev); netif_stop_queue(dev); - napi_disable(&priv->napi); + if (!priv->is_peripheral) + napi_disable(&priv->napi); m_can_stop(dev); m_can_clk_stop(priv); free_irq(dev->irq, dev); + + if (priv->is_peripheral) { + priv->tx_skb = NULL; + destroy_workqueue(priv->tx_wq); + priv->tx_wq = NULL; + } + close_candev(dev); can_led_event(dev, CAN_LED_EVENT_STOP); @@ -1385,18 +1405,15 @@ static int m_can_next_echo_skb_occupied(struct net_device *dev, int putidx) return !!priv->can.echo_skb[next_idx]; } -static netdev_tx_t m_can_start_xmit(struct sk_buff *skb, - struct net_device *dev) +static netdev_tx_t m_can_tx_handler(struct m_can_priv *priv) { - struct m_can_priv *priv = netdev_priv(dev); - struct canfd_frame *cf = (struct canfd_frame *)skb->data; + struct canfd_frame *cf = (struct canfd_frame *)priv->tx_skb->data; + struct net_device *dev = priv->net; + struct sk_buff *skb = priv->tx_skb; u32 id, cccr, fdflags; int i; int putidx; - if (can_dropped_invalid_skb(dev, skb)) - return NETDEV_TX_OK; - /* Generate ID field for TX buffer Element */ /* Common to all supported M_CAN versions */ if (cf->can_id & CAN_EFF_FLAG) { @@ -1451,7 +1468,13 @@ static netdev_tx_t m_can_start_xmit(struct sk_buff *skb, netif_stop_queue(dev); netdev_warn(dev, "TX queue active although FIFO is full."); - return NETDEV_TX_BUSY; + if (priv->is_peripheral) { + kfree_skb(skb); + dev->stats.tx_dropped++; + return NETDEV_TX_OK; + } else { + return NETDEV_TX_BUSY; + } } /* get put index for frame */ @@ -1492,14 +1515,119 @@ static netdev_tx_t m_can_start_xmit(struct sk_buff *skb, m_can_write(priv, M_CAN_TXBAR, (1 << putidx)); /* stop network queue if fifo full */ - if (m_can_tx_fifo_full(priv) || - m_can_next_echo_skb_occupied(dev, putidx)) - netif_stop_queue(dev); + if (m_can_tx_fifo_full(priv) || + m_can_next_echo_skb_occupied(dev, putidx)) + netif_stop_queue(dev); } return NETDEV_TX_OK; } +static void m_can_tx_work_queue(struct work_struct *ws) +{ + struct m_can_priv *priv = container_of(ws, struct m_can_priv, + tx_work); + m_can_tx_handler(priv); + priv->tx_skb = NULL; +} + +static netdev_tx_t m_can_start_xmit(struct sk_buff *skb, + struct net_device *dev) +{ + struct m_can_priv *priv = netdev_priv(dev); + + if (can_dropped_invalid_skb(dev, skb)) + return NETDEV_TX_OK; + + if (priv->is_peripheral) { + if (priv->tx_skb) { + netdev_err(dev, "hard_xmit called while tx busy\n"); + return NETDEV_TX_BUSY; + } + + if (priv->can.state == CAN_STATE_BUS_OFF) { + m_can_clean(dev); + } else { + /* Need to stop the queue to avoid numerous requests + * from being sent. Suggested improvement is to create + * a queueing mechanism that will queue the skbs and + * process them in order. + */ + priv->tx_skb = skb; + netif_stop_queue(priv->net); + queue_work(priv->tx_wq, &priv->tx_work); + } + } else { + priv->tx_skb = skb; + return m_can_tx_handler(priv); + } + + return NETDEV_TX_OK; +} + +static int m_can_open(struct net_device *dev) +{ + struct m_can_priv *priv = netdev_priv(dev); + int err; + + err = m_can_clk_start(priv); + if (err) + return err; + + /* open the can device */ + err = open_candev(dev); + if (err) { + netdev_err(dev, "failed to open can device\n"); + goto exit_disable_clks; + } + + /* register interrupt handler */ + if (priv->is_peripheral) { + priv->tx_skb = NULL; + priv->tx_wq = alloc_workqueue("mcan_wq", + WQ_FREEZABLE | WQ_MEM_RECLAIM, 0); + if (!priv->tx_wq) { + err = -ENOMEM; + goto out_wq_fail; + } + + INIT_WORK(&priv->tx_work, m_can_tx_work_queue); + + err = request_threaded_irq(dev->irq, NULL, m_can_isr, + IRQF_ONESHOT | IRQF_TRIGGER_FALLING, + dev->name, dev); + } else { + err = request_irq(dev->irq, m_can_isr, IRQF_SHARED, dev->name, + dev); + } + + if (err < 0) { + netdev_err(dev, "failed to request interrupt\n"); + goto exit_irq_fail; + } + + /* start the m_can controller */ + m_can_start(dev); + + can_led_event(dev, CAN_LED_EVENT_OPEN); + + if (!priv->is_peripheral) + napi_enable(&priv->napi); + + netif_start_queue(dev); + + return 0; + +exit_irq_fail: + if (priv->is_peripheral) + destroy_workqueue(priv->tx_wq); +out_wq_fail: + close_candev(dev); +exit_disable_clks: + m_can_clk_stop(priv); + return err; +} + static const struct net_device_ops m_can_netdev_ops = { .ndo_open = m_can_open, .ndo_stop = m_can_close, @@ -1515,20 +1643,6 @@ static int register_m_can_dev(struct net_device *dev) return register_candev(dev); } -static void m_can_init_ram(struct m_can_priv *priv) -{ - int end, i, start; - - /* initialize the entire Message RAM in use to avoid possible - * ECC/parity checksum errors when reading an uninitialized buffer - */ - start = priv->mcfg[MRAM_SIDF].off; - end = priv->mcfg[MRAM_TXB].off + - priv->mcfg[MRAM_TXB].num * TXB_ELEMENT_SIZE; - for (i = start; i < end; i += 4) - writel(0x0, priv->mram_base + i); -} - static void m_can_of_parse_mram(struct m_can_priv *priv, const u32 *mram_config_vals) { @@ -1556,9 +1670,8 @@ static void m_can_of_parse_mram(struct m_can_priv *priv, priv->mcfg[MRAM_TXB].num = mram_config_vals[7] & (TXBC_NDTB_MASK >> TXBC_NDTB_SHIFT); - dev_dbg(priv->device, - "mram_base %p sidf 0x%x %d xidf 0x%x %d rxf0 0x%x %d rxf1 0x%x %d rxb 0x%x %d txe 0x%x %d txb 0x%x %d\n", - priv->mram_base, + dev_dbg(priv->dev, + "sidf 0x%x %d xidf 0x%x %d rxf0 0x%x %d rxf1 0x%x %d rxb 0x%x %d txe 0x%x %d txb 0x%x %d\n", priv->mcfg[MRAM_SIDF].off, priv->mcfg[MRAM_SIDF].num, priv->mcfg[MRAM_XIDF].off, priv->mcfg[MRAM_XIDF].num, priv->mcfg[MRAM_RXF0].off, priv->mcfg[MRAM_RXF0].num, @@ -1566,63 +1679,55 @@ static void m_can_of_parse_mram(struct m_can_priv *priv, priv->mcfg[MRAM_RXB].off, priv->mcfg[MRAM_RXB].num, priv->mcfg[MRAM_TXE].off, priv->mcfg[MRAM_TXE].num, priv->mcfg[MRAM_TXB].off, priv->mcfg[MRAM_TXB].num); - - m_can_init_ram(priv); } -static int m_can_plat_probe(struct platform_device *pdev) +void m_can_init_ram(struct m_can_priv *priv) { - struct net_device *dev; - struct m_can_priv *priv; - struct resource *res; - void __iomem *addr; - void __iomem *mram_addr; - struct clk *hclk, *cclk; - int irq, ret; - struct device_node *np; - u32 mram_config_vals[MRAM_CFG_LEN]; - u32 tx_fifo_size; - - np = pdev->dev.of_node; + int end, i, start; - hclk = devm_clk_get(&pdev->dev, "hclk"); - cclk = devm_clk_get(&pdev->dev, "cclk"); + /* initialize the entire Message RAM in use to avoid possible + * ECC/parity checksum errors when reading an uninitialized buffer + */ + start = priv->mcfg[MRAM_SIDF].off; + end = priv->mcfg[MRAM_TXB].off + + priv->mcfg[MRAM_TXB].num * TXB_ELEMENT_SIZE; - if (IS_ERR(hclk) || IS_ERR(cclk)) { - dev_err(&pdev->dev, "no clock found\n"); - ret = -ENODEV; - goto failed_ret; - } + for (i = start; i < end; i += 4) + m_can_fifo_write_no_off(priv, i, 0x0); +} +EXPORT_SYMBOL_GPL(m_can_init_ram); - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "m_can"); - addr = devm_ioremap_resource(&pdev->dev, res); - irq = platform_get_irq_byname(pdev, "int0"); +int m_can_class_get_clocks(struct m_can_priv *m_can_dev) +{ + int ret = 0; - if (IS_ERR(addr) || irq < 0) { - ret = -EINVAL; - goto failed_ret; - } + m_can_dev->hclk = devm_clk_get(m_can_dev->dev, "hclk"); + m_can_dev->cclk = devm_clk_get(m_can_dev->dev, "cclk"); - /* message ram could be shared */ - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "message_ram"); - if (!res) { + if (IS_ERR(m_can_dev->cclk)) { + dev_err(m_can_dev->dev, "no clock found\n"); ret = -ENODEV; - goto failed_ret; } - mram_addr = devm_ioremap(&pdev->dev, res->start, resource_size(res)); - if (!mram_addr) { - ret = -ENOMEM; - goto failed_ret; - } + return ret; +} +EXPORT_SYMBOL_GPL(m_can_class_get_clocks); + +struct m_can_priv *m_can_class_allocate_dev(struct device *dev) +{ + struct m_can_priv *class_dev = NULL; + u32 mram_config_vals[MRAM_CFG_LEN]; + struct net_device *net_dev; + u32 tx_fifo_size; + int ret; - /* get message ram configuration */ - ret = of_property_read_u32_array(np, "bosch,mram-cfg", - mram_config_vals, - sizeof(mram_config_vals) / 4); + ret = fwnode_property_read_u32_array(dev_fwnode(dev), + "bosch,mram-cfg", + mram_config_vals, + sizeof(mram_config_vals) / 4); if (ret) { - dev_err(&pdev->dev, "Could not get Message RAM configuration."); - goto failed_ret; + dev_err(dev, "Could not get Message RAM configuration."); + goto out; } /* Get TX FIFO size @@ -1631,66 +1736,74 @@ static int m_can_plat_probe(struct platform_device *pdev) tx_fifo_size = mram_config_vals[7]; /* allocate the m_can device */ - dev = alloc_candev(sizeof(*priv), tx_fifo_size); - if (!dev) { - ret = -ENOMEM; - goto failed_ret; + net_dev = alloc_candev(sizeof(*class_dev), tx_fifo_size); + if (!net_dev) { + dev_err(dev, "Failed to allocate CAN device"); + goto out; } - priv = netdev_priv(dev); - dev->irq = irq; - priv->device = &pdev->dev; - priv->hclk = hclk; - priv->cclk = cclk; - priv->can.clock.freq = clk_get_rate(cclk); - priv->mram_base = mram_addr; + class_dev = netdev_priv(net_dev); + if (!class_dev) { + dev_err(dev, "Failed to init netdev private"); + goto out; + } - platform_set_drvdata(pdev, dev); - SET_NETDEV_DEV(dev, &pdev->dev); + class_dev->net = net_dev; + class_dev->dev = dev; + SET_NETDEV_DEV(net_dev, dev); - /* Enable clocks. Necessary to read Core Release in order to determine - * M_CAN version - */ - pm_runtime_enable(&pdev->dev); - ret = m_can_clk_start(priv); - if (ret) - goto pm_runtime_fail; + m_can_of_parse_mram(class_dev, mram_config_vals); +out: + return class_dev; +} +EXPORT_SYMBOL_GPL(m_can_class_allocate_dev); - ret = m_can_dev_setup(pdev, dev, addr); +int m_can_class_register(struct m_can_priv *m_can_dev) +{ + int ret; + + if (m_can_dev->pm_clock_support) { + pm_runtime_enable(m_can_dev->dev); + ret = m_can_clk_start(m_can_dev); + if (ret) + goto pm_runtime_fail; + } + + ret = m_can_dev_setup(m_can_dev); if (ret) goto clk_disable; - ret = register_m_can_dev(dev); + ret = register_m_can_dev(m_can_dev->net); if (ret) { - dev_err(&pdev->dev, "registering %s failed (err=%d)\n", - KBUILD_MODNAME, ret); + dev_err(m_can_dev->dev, "registering %s failed (err=%d)\n", + m_can_dev->net->name, ret); goto clk_disable; } - m_can_of_parse_mram(priv, mram_config_vals); - - devm_can_led_init(dev); + devm_can_led_init(m_can_dev->net); - of_can_transceiver(dev); + of_can_transceiver(m_can_dev->net); - dev_info(&pdev->dev, "%s device registered (irq=%d, version=%d)\n", - KBUILD_MODNAME, dev->irq, priv->version); + dev_info(m_can_dev->dev, "%s device registered (irq=%d, version=%d)\n", + KBUILD_MODNAME, m_can_dev->net->irq, m_can_dev->version); /* Probe finished * Stop clocks. They will be reactivated once the M_CAN device is opened */ clk_disable: - m_can_clk_stop(priv); + m_can_clk_stop(m_can_dev); pm_runtime_fail: if (ret) { - pm_runtime_disable(&pdev->dev); - free_candev(dev); + if (m_can_dev->pm_clock_support) + pm_runtime_disable(m_can_dev->dev); + free_candev(m_can_dev->net); } -failed_ret: + return ret; } +EXPORT_SYMBOL_GPL(m_can_class_register); -static __maybe_unused int m_can_suspend(struct device *dev) +int m_can_class_suspend(struct device *dev) { struct net_device *ndev = dev_get_drvdata(dev); struct m_can_priv *priv = netdev_priv(ndev); @@ -1708,8 +1821,9 @@ static __maybe_unused int m_can_suspend(struct device *dev) return 0; } +EXPORT_SYMBOL_GPL(m_can_class_suspend); -static __maybe_unused int m_can_resume(struct device *dev) +int m_can_class_resume(struct device *dev) { struct net_device *ndev = dev_get_drvdata(dev); struct m_can_priv *priv = netdev_priv(ndev); @@ -1733,79 +1847,19 @@ static __maybe_unused int m_can_resume(struct device *dev) return 0; } +EXPORT_SYMBOL_GPL(m_can_class_resume); -static void unregister_m_can_dev(struct net_device *dev) +void m_can_class_unregister(struct m_can_priv *m_can_dev) { - unregister_candev(dev); -} - -static int m_can_plat_remove(struct platform_device *pdev) -{ - struct net_device *dev = platform_get_drvdata(pdev); - - unregister_m_can_dev(dev); - - pm_runtime_disable(&pdev->dev); - - platform_set_drvdata(pdev, NULL); - - free_candev(dev); - - return 0; -} - -static int __maybe_unused m_can_runtime_suspend(struct device *dev) -{ - struct net_device *ndev = dev_get_drvdata(dev); - struct m_can_priv *priv = netdev_priv(ndev); - - clk_disable_unprepare(priv->cclk); - clk_disable_unprepare(priv->hclk); - - return 0; -} + unregister_candev(m_can_dev->net); -static int __maybe_unused m_can_runtime_resume(struct device *dev) -{ - struct net_device *ndev = dev_get_drvdata(dev); - struct m_can_priv *priv = netdev_priv(ndev); - int err; + m_can_clk_stop(m_can_dev); - err = clk_prepare_enable(priv->hclk); - if (err) - return err; - - err = clk_prepare_enable(priv->cclk); - if (err) - clk_disable_unprepare(priv->hclk); - - return err; + free_candev(m_can_dev->net); } - -static const struct dev_pm_ops m_can_pmops = { - SET_RUNTIME_PM_OPS(m_can_runtime_suspend, - m_can_runtime_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(m_can_suspend, m_can_resume) -}; - -static const struct of_device_id m_can_of_table[] = { - { .compatible = "bosch,m_can", .data = NULL }, - { /* sentinel */ }, -}; -MODULE_DEVICE_TABLE(of, m_can_of_table); - -static struct platform_driver m_can_plat_driver = { - .driver = { - .name = KBUILD_MODNAME, - .of_match_table = m_can_of_table, - .pm = &m_can_pmops, - }, - .probe = m_can_plat_probe, - .remove = m_can_plat_remove, -}; - -module_platform_driver(m_can_plat_driver); +EXPORT_SYMBOL_GPL(m_can_class_unregister); MODULE_AUTHOR("Dong Aisheng "); +MODULE_AUTHOR("Dan Murphy "); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("CAN bus driver for Bosch M_CAN controller"); diff --git a/drivers/net/can/m_can/m_can.h b/drivers/net/can/m_can/m_can.h new file mode 100644 index 000000000000..5671f5423887 --- /dev/null +++ b/drivers/net/can/m_can/m_can.h @@ -0,0 +1,110 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* CAN bus driver for Bosch M_CAN controller + * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/ + */ + +#ifndef _CAN_M_CAN_H_ +#define _CAN_M_CAN_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* m_can lec values */ +enum m_can_lec_type { + LEC_NO_ERROR = 0, + LEC_STUFF_ERROR, + LEC_FORM_ERROR, + LEC_ACK_ERROR, + LEC_BIT1_ERROR, + LEC_BIT0_ERROR, + LEC_CRC_ERROR, + LEC_UNUSED, +}; + +enum m_can_mram_cfg { + MRAM_SIDF = 0, + MRAM_XIDF, + MRAM_RXF0, + MRAM_RXF1, + MRAM_RXB, + MRAM_TXE, + MRAM_TXB, + MRAM_CFG_NUM, +}; + +/* address offset and element number for each FIFO/Buffer in the Message RAM */ +struct mram_cfg { + u16 off; + u8 num; +}; + +struct m_can_priv; +struct m_can_ops { + /* Device specific call backs */ + int (*clear_interrupts)(struct m_can_priv *m_can_class); + u32 (*read_reg)(struct m_can_priv *m_can_class, int reg); + int (*write_reg)(struct m_can_priv *m_can_class, int reg, int val); + u32 (*read_fifo)(struct m_can_priv *m_can_class, int addr_offset); + int (*write_fifo)(struct m_can_priv *m_can_class, int addr_offset, + int val); + int (*init)(struct m_can_priv *m_can_class); +}; + +struct m_can_priv { + struct can_priv can; + struct napi_struct napi; + struct net_device *net; + struct device *dev; + struct clk *hclk; + struct clk *cclk; + + struct workqueue_struct *tx_wq; + struct work_struct tx_work; + struct sk_buff *tx_skb; + + struct can_bittiming_const *bit_timing; + struct can_bittiming_const *data_timing; + + struct m_can_ops *ops; + + void *device_data; + + int version; + int freq; + u32 irqstatus; + + int pm_clock_support; + int is_peripheral; + + struct mram_cfg mcfg[MRAM_CFG_NUM]; +}; + +struct m_can_priv *m_can_class_allocate_dev(struct device *dev); +int m_can_class_register(struct m_can_priv *m_can_dev); +void m_can_class_unregister(struct m_can_priv *m_can_dev); +int m_can_class_get_clocks(struct m_can_priv *m_can_dev); +void m_can_init_ram(struct m_can_priv *priv); +void m_can_config_endisable(struct m_can_priv *priv, bool enable); + +int m_can_class_suspend(struct device *dev); +int m_can_class_resume(struct device *dev); +#endif /* _CAN_M_H_ */ diff --git a/drivers/net/can/m_can/m_can_platform.c b/drivers/net/can/m_can/m_can_platform.c new file mode 100644 index 000000000000..026053f62f77 --- /dev/null +++ b/drivers/net/can/m_can/m_can_platform.c @@ -0,0 +1,202 @@ +// SPDX-License-Identifier: GPL-2.0 +// IOMapped CAN bus driver for Bosch M_CAN controller +// Copyright (C) 2014 Freescale Semiconductor, Inc. +// Dong Aisheng +// +// Copyright (C) 2018-19 Texas Instruments Incorporated - http://www.ti.com/ + +#include + +#include "m_can.h" + +struct m_can_plat_priv { + void __iomem *base; + void __iomem *mram_base; +}; + +static u32 iomap_read_reg(struct m_can_priv *cdev, int reg) +{ + struct m_can_plat_priv *priv = + (struct m_can_plat_priv *)cdev->device_data; + + return readl(priv->base + reg); +} + +static u32 iomap_read_fifo(struct m_can_priv *cdev, int offset) +{ + struct m_can_plat_priv *priv = + (struct m_can_plat_priv *)cdev->device_data; + + return readl(priv->mram_base + offset); +} + +static int iomap_write_reg(struct m_can_priv *cdev, int reg, int val) +{ + struct m_can_plat_priv *priv = + (struct m_can_plat_priv *)cdev->device_data; + + writel(val, priv->base + reg); + + return 0; +} + +static int iomap_write_fifo(struct m_can_priv *cdev, int offset, int val) +{ + struct m_can_plat_priv *priv = + (struct m_can_plat_priv *)cdev->device_data; + + writel(val, priv->mram_base + offset); + + return 0; +} + +static struct m_can_ops m_can_plat_ops = { + .read_reg = iomap_read_reg, + .write_reg = iomap_write_reg, + .write_fifo = iomap_write_fifo, + .read_fifo = iomap_read_fifo, +}; + +static int m_can_plat_probe(struct platform_device *pdev) +{ + struct m_can_priv *mcan_class; + struct m_can_plat_priv *priv; + struct resource *res; + void __iomem *addr; + void __iomem *mram_addr; + int irq, ret = 0; + + mcan_class = m_can_class_allocate_dev(&pdev->dev); + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + mcan_class->device_data = priv; + + m_can_class_get_clocks(mcan_class); + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "m_can"); + addr = devm_ioremap_resource(&pdev->dev, res); + irq = platform_get_irq_byname(pdev, "int0"); + if (IS_ERR(addr) || irq < 0) { + ret = -EINVAL; + goto failed_ret; + } + + /* message ram could be shared */ + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "message_ram"); + if (!res) { + ret = -ENODEV; + goto failed_ret; + } + + mram_addr = devm_ioremap(&pdev->dev, res->start, resource_size(res)); + if (!mram_addr) { + ret = -ENOMEM; + goto failed_ret; + } + + priv->base = addr; + priv->mram_base = mram_addr; + + mcan_class->net->irq = irq; + mcan_class->pm_clock_support = 1; + mcan_class->can.clock.freq = clk_get_rate(mcan_class->cclk); + mcan_class->dev = &pdev->dev; + + mcan_class->ops = &m_can_plat_ops; + + mcan_class->is_peripheral = false; + + platform_set_drvdata(pdev, mcan_class->dev); + + m_can_init_ram(mcan_class); + + ret = m_can_class_register(mcan_class); + +failed_ret: + return ret; +} + +static __maybe_unused int m_can_suspend(struct device *dev) +{ + return m_can_class_suspend(dev); +} + +static __maybe_unused int m_can_resume(struct device *dev) +{ + return m_can_class_resume(dev); +} + +static int m_can_plat_remove(struct platform_device *pdev) +{ + struct net_device *dev = platform_get_drvdata(pdev); + struct m_can_priv *mcan_class = netdev_priv(dev); + + m_can_class_unregister(mcan_class); + + platform_set_drvdata(pdev, NULL); + + return 0; +} + +static int __maybe_unused m_can_runtime_suspend(struct device *dev) +{ + struct net_device *ndev = dev_get_drvdata(dev); + struct m_can_priv *mcan_class = netdev_priv(ndev); + + m_can_class_suspend(dev); + + clk_disable_unprepare(mcan_class->cclk); + clk_disable_unprepare(mcan_class->hclk); + + return 0; +} + +static int __maybe_unused m_can_runtime_resume(struct device *dev) +{ + struct net_device *ndev = dev_get_drvdata(dev); + struct m_can_priv *mcan_class = netdev_priv(ndev); + int err; + + err = clk_prepare_enable(mcan_class->hclk); + if (err) + return err; + + err = clk_prepare_enable(mcan_class->cclk); + if (err) + clk_disable_unprepare(mcan_class->hclk); + + m_can_class_resume(dev); + + return err; +} + +static const struct dev_pm_ops m_can_pmops = { + SET_RUNTIME_PM_OPS(m_can_runtime_suspend, + m_can_runtime_resume, NULL) + SET_SYSTEM_SLEEP_PM_OPS(m_can_suspend, m_can_resume) +}; + +static const struct of_device_id m_can_of_table[] = { + { .compatible = "bosch,m_can", .data = NULL }, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, m_can_of_table); + +static struct platform_driver m_can_plat_driver = { + .driver = { + .name = KBUILD_MODNAME, + .of_match_table = m_can_of_table, + .pm = &m_can_pmops, + }, + .probe = m_can_plat_probe, + .remove = m_can_plat_remove, +}; + +module_platform_driver(m_can_plat_driver); + +MODULE_AUTHOR("Dong Aisheng "); +MODULE_AUTHOR("Dan Murphy "); +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("M_CAN driver for IO Mapped Bosch controllers"); From patchwork Tue Mar 19 17:26:48 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dan Murphy X-Patchwork-Id: 160599 Delivered-To: patch@linaro.org Received: by 2002:a02:5cc1:0:0:0:0:0 with SMTP id w62csp4139657jad; Tue, 19 Mar 2019 10:27:44 -0700 (PDT) X-Google-Smtp-Source: APXvYqwvPr9s4c54KbiI2SiOK1NqxhQQTR6lkIiQUo90264Ho+isjQ8QXn+8THqLkVTsPlov7t4Z X-Received: by 2002:a65:63d9:: with SMTP id n25mr2903719pgv.243.1553016464612; Tue, 19 Mar 2019 10:27:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1553016464; cv=none; d=google.com; s=arc-20160816; b=S+mouTNcUfKxe7GGwA5UGesAAEWGLMhLQnVEBmhioDAiWKM+ppa4I45TRIo7wl0csM 1XANx7XnDPMX5QZHh/7IVS8SzWAO/6+dq0ebU2rgDxzRp8HAK5gDNMQFsHM7JzKtfPZF xiEhiDaI2B1B1nWViC6VGFYBMsgLdqHfTFJiZxrYAxexjyK985GNTEH/CS0vC7vMpWUs Djju/GD/s902MHcKarUBS3RJQW+2mJTeT18z3elpsbGh2pAaXaoAmPGhxbdUgMnJh3jR SnlylBpMAM6cJFEgTE+PQAoO2ymgQVb48AIghLXFE9Rd6a1swi9RIPRAyHeLy3SRtvks FsJg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=Bh/k0lAs5PLh3uxOQ7EMlALslPIRrM8V6hovQuXEpVg=; b=fzFAh1PGP/g+EpBBfjKZE79X2E/ZuCn5+FOVLypvF6wACNhnjhPrBDgdGm/xLqfwrG qAjTk9VQru+LmBNRHJ7jnHeMC1LZGnY2iHz/LPCn6nXioQXdDjZcxejF4dKTS3NKq025 LldUi1MRYb7p8U4iHyioHrrBV0YNbbbqkNlGujg1RYuWAWs4ZkXO7Sq1T8vAPWkaKVjX CZ/PZJfWXqNgcTVZEoBkfGoVD2FpzydVxHNrLpza3y1hSKuQLnUopM/ey4upiPgxTNeH 8W/lO0e3yPAqKs5srsm5gH2ftIIoRfmaAIIwSbOHBt8pBSjQM5suoJJt5TIFwF3qBEyv InUQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=Evzk+NFt; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id p87si12560007pfa.48.2019.03.19.10.27.44; Tue, 19 Mar 2019 10:27:44 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=Evzk+NFt; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726778AbfCSR1n (ORCPT + 31 others); Tue, 19 Mar 2019 13:27:43 -0400 Received: from lelv0142.ext.ti.com ([198.47.23.249]:52432 "EHLO lelv0142.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727673AbfCSR12 (ORCPT ); Tue, 19 Mar 2019 13:27:28 -0400 Received: from lelv0265.itg.ti.com ([10.180.67.224]) by lelv0142.ext.ti.com (8.15.2/8.15.2) with ESMTP id x2JHRGu8092749; Tue, 19 Mar 2019 12:27:16 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1553016436; bh=Bh/k0lAs5PLh3uxOQ7EMlALslPIRrM8V6hovQuXEpVg=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=Evzk+NFtG62t1gsmKXaK5c69VVN7l64ARiKXxwNaaPiIUhxNhquN4jNqJyFMu0nQV iOL9BtrXWRpxp3odoKAGThhtPvUbZEL795RplruYsd5JjU6AYxgQBjZncKvIf8evFy BwuXVyc4q/Tk9ysl15eJsL3HR+EnOoigHJTwaAVI= Received: from DLEE113.ent.ti.com (dlee113.ent.ti.com [157.170.170.24]) by lelv0265.itg.ti.com (8.15.2/8.15.2) with ESMTPS id x2JHRGMv080013 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 19 Mar 2019 12:27:16 -0500 Received: from DLEE107.ent.ti.com (157.170.170.37) by DLEE113.ent.ti.com (157.170.170.24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1713.5; Tue, 19 Mar 2019 12:27:15 -0500 Received: from dflp32.itg.ti.com (10.64.6.15) by DLEE107.ent.ti.com (157.170.170.37) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.1713.5 via Frontend Transport; Tue, 19 Mar 2019 12:27:16 -0500 Received: from localhost (ileax41-snat.itg.ti.com [10.172.224.153]) by dflp32.itg.ti.com (8.14.3/8.13.8) with ESMTP id x2JHRFLq008297; Tue, 19 Mar 2019 12:27:15 -0500 From: Dan Murphy To: , , CC: , , , Dan Murphy Subject: [PATCH v11 2/5] can: m_can: Rename m_can_priv to m_can_classdev Date: Tue, 19 Mar 2019 12:26:48 -0500 Message-ID: <20190319172651.10012-2-dmurphy@ti.com> X-Mailer: git-send-email 2.12.2 In-Reply-To: <20190319172651.10012-1-dmurphy@ti.com> References: <20190319172651.10012-1-dmurphy@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Rename the common m_can_priv class structure to m_can_classdev as this is more descriptive. Acked-by: Wolfgang Grandegger Signed-off-by: Dan Murphy --- v11 - No changes - https://lore.kernel.org/patchwork/patch/1051181/ v10 - No changes - https://lore.kernel.org/patchwork/patch/1050489/ v9 - Made additional changes on new code to make priv->cdev other wise no changes https://lore.kernel.org/patchwork/patch/1050121/ v8 - Made additional changes on new code to make priv->cdev, and updated the header file class_dev variable to be consistent. - https://lore.kernel.org/patchwork/patch/1047979/ v7 - Fixed remaining checkpatch issues, renamed priv to cdev - https://lore.kernel.org/patchwork/patch/1047219/ v6 - No changes only rebase changes possibly can squash into the first patch - https://lore.kernel.org/patchwork/patch/1042444/ drivers/net/can/m_can/m_can.c | 544 +++++++++++++------------ drivers/net/can/m_can/m_can.h | 28 +- drivers/net/can/m_can/m_can_platform.c | 16 +- 3 files changed, 296 insertions(+), 292 deletions(-) -- 2.20.1.390.gb5101f9297 diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c index 98641a0046a6..0759c61a7e5a 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c @@ -320,74 +320,74 @@ enum m_can_reg { #define TX_EVENT_MM_SHIFT TX_BUF_MM_SHIFT #define TX_EVENT_MM_MASK (0xff << TX_EVENT_MM_SHIFT) -static u32 m_can_read(struct m_can_priv *priv, enum m_can_reg reg) +static u32 m_can_read(struct m_can_classdev *cdev, enum m_can_reg reg) { - if (priv->ops->read_reg) - return priv->ops->read_reg(priv, reg); + if (cdev->ops->read_reg) + return cdev->ops->read_reg(cdev, reg); else return -EINVAL; } -static int m_can_write(struct m_can_priv *priv, enum m_can_reg reg, u32 val) +static int m_can_write(struct m_can_classdev *cdev, enum m_can_reg reg, u32 val) { - if (priv->ops->write_reg) - return priv->ops->write_reg(priv, reg, val); + if (cdev->ops->write_reg) + return cdev->ops->write_reg(cdev, reg, val); else return -EINVAL; } -static u32 m_can_fifo_read(struct m_can_priv *priv, +static u32 m_can_fifo_read(struct m_can_classdev *cdev, u32 fgi, unsigned int offset) { - u32 addr_offset = priv->mcfg[MRAM_RXF0].off + fgi * RXF0_ELEMENT_SIZE + + u32 addr_offset = cdev->mcfg[MRAM_RXF0].off + fgi * RXF0_ELEMENT_SIZE + offset; - if (priv->ops->read_fifo) - return priv->ops->read_fifo(priv, addr_offset); + if (cdev->ops->read_fifo) + return cdev->ops->read_fifo(cdev, addr_offset); else return -EINVAL; } -static u32 m_can_fifo_write(struct m_can_priv *priv, +static u32 m_can_fifo_write(struct m_can_classdev *cdev, u32 fpi, unsigned int offset, u32 val) { - u32 addr_offset = priv->mcfg[MRAM_TXB].off + fpi * TXB_ELEMENT_SIZE + + u32 addr_offset = cdev->mcfg[MRAM_TXB].off + fpi * TXB_ELEMENT_SIZE + offset; - if (priv->ops->write_fifo) - return priv->ops->write_fifo(priv, addr_offset, val); + if (cdev->ops->write_fifo) + return cdev->ops->write_fifo(cdev, addr_offset, val); else return -EINVAL; } -static u32 m_can_fifo_write_no_off(struct m_can_priv *priv, +static u32 m_can_fifo_write_no_off(struct m_can_classdev *cdev, u32 fpi, u32 val) { - if (priv->ops->write_fifo) - return priv->ops->write_fifo(priv, fpi, val); + if (cdev->ops->write_fifo) + return cdev->ops->write_fifo(cdev, fpi, val); else return 0; } -static u32 m_can_txe_fifo_read(struct m_can_priv *priv, u32 fgi, u32 offset) +static u32 m_can_txe_fifo_read(struct m_can_classdev *cdev, u32 fgi, u32 offset) { - u32 addr_offset = priv->mcfg[MRAM_TXE].off + fgi * TXE_ELEMENT_SIZE + + u32 addr_offset = cdev->mcfg[MRAM_TXE].off + fgi * TXE_ELEMENT_SIZE + offset; - if (priv->ops->read_fifo) - return priv->ops->read_fifo(priv, addr_offset); + if (cdev->ops->read_fifo) + return cdev->ops->read_fifo(cdev, addr_offset); else return -EINVAL; } -static inline bool m_can_tx_fifo_full(struct m_can_priv *priv) +static inline bool m_can_tx_fifo_full(struct m_can_classdev *cdev) { - return !!(m_can_read(priv, M_CAN_TXFQS) & TXFQS_TFQF); + return !!(m_can_read(cdev, M_CAN_TXFQS) & TXFQS_TFQF); } -void m_can_config_endisable(struct m_can_priv *priv, bool enable) +void m_can_config_endisable(struct m_can_classdev *cdev, bool enable) { - u32 cccr = m_can_read(priv, M_CAN_CCCR); + u32 cccr = m_can_read(cdev, M_CAN_CCCR); u32 timeout = 10; u32 val = 0; @@ -401,21 +401,21 @@ void m_can_config_endisable(struct m_can_priv *priv, bool enable) cccr &= ~CCCR_CSR; /* enable m_can configuration */ - m_can_write(priv, M_CAN_CCCR, cccr | CCCR_INIT); + m_can_write(cdev, M_CAN_CCCR, cccr | CCCR_INIT); udelay(5); /* CCCR.CCE can only be set/reset while CCCR.INIT = '1' */ - m_can_write(priv, M_CAN_CCCR, cccr | CCCR_INIT | CCCR_CCE); + m_can_write(cdev, M_CAN_CCCR, cccr | CCCR_INIT | CCCR_CCE); } else { - m_can_write(priv, M_CAN_CCCR, cccr & ~(CCCR_INIT | CCCR_CCE)); + m_can_write(cdev, M_CAN_CCCR, cccr & ~(CCCR_INIT | CCCR_CCE)); } /* there's a delay for module initialization */ if (enable) val = CCCR_INIT | CCCR_CCE; - while ((m_can_read(priv, M_CAN_CCCR) & (CCCR_INIT | CCCR_CCE)) != val) { + while ((m_can_read(cdev, M_CAN_CCCR) & (CCCR_INIT | CCCR_CCE)) != val) { if (timeout == 0) { - netdev_warn(priv->net, "Failed to init module\n"); + netdev_warn(cdev->net, "Failed to init module\n"); return; } timeout--; @@ -423,38 +423,38 @@ void m_can_config_endisable(struct m_can_priv *priv, bool enable) } } -static inline void m_can_enable_all_interrupts(struct m_can_priv *priv) +static inline void m_can_enable_all_interrupts(struct m_can_classdev *cdev) { /* Only interrupt line 0 is used in this driver */ - m_can_write(priv, M_CAN_ILE, ILE_EINT0); + m_can_write(cdev, M_CAN_ILE, ILE_EINT0); } -static inline void m_can_disable_all_interrupts(struct m_can_priv *priv) +static inline void m_can_disable_all_interrupts(struct m_can_classdev *cdev) { - m_can_write(priv, M_CAN_ILE, 0x0); + m_can_write(cdev, M_CAN_ILE, 0x0); } static void m_can_clean(struct net_device *net) { - struct m_can_priv *priv = netdev_priv(net); + struct m_can_classdev *cdev = netdev_priv(net); - if (priv->tx_skb) { + if (cdev->tx_skb) { int putidx = 0; net->stats.tx_errors++; - if (priv->version > 30) - putidx = ((m_can_read(priv, M_CAN_TXFQS) & + if (cdev->version > 30) + putidx = ((m_can_read(cdev, M_CAN_TXFQS) & TXFQS_TFQPI_MASK) >> TXFQS_TFQPI_SHIFT); - can_free_echo_skb(priv->net, putidx); - priv->tx_skb = NULL; + can_free_echo_skb(cdev->net, putidx); + cdev->tx_skb = NULL; } } static void m_can_read_fifo(struct net_device *dev, u32 rxfs) { struct net_device_stats *stats = &dev->stats; - struct m_can_priv *priv = netdev_priv(dev); + struct m_can_classdev *cdev = netdev_priv(dev); struct canfd_frame *cf; struct sk_buff *skb; u32 id, fgi, dlc; @@ -462,7 +462,7 @@ static void m_can_read_fifo(struct net_device *dev, u32 rxfs) /* calculate the fifo get index for where to read data */ fgi = (rxfs & RXFS_FGI_MASK) >> RXFS_FGI_SHIFT; - dlc = m_can_fifo_read(priv, fgi, M_CAN_FIFO_DLC); + dlc = m_can_fifo_read(cdev, fgi, M_CAN_FIFO_DLC); if (dlc & RX_BUF_FDF) skb = alloc_canfd_skb(dev, &cf); else @@ -477,7 +477,7 @@ static void m_can_read_fifo(struct net_device *dev, u32 rxfs) else cf->len = get_can_dlc((dlc >> 16) & 0x0F); - id = m_can_fifo_read(priv, fgi, M_CAN_FIFO_ID); + id = m_can_fifo_read(cdev, fgi, M_CAN_FIFO_ID); if (id & RX_BUF_XTD) cf->can_id = (id & CAN_EFF_MASK) | CAN_EFF_FLAG; else @@ -496,12 +496,12 @@ static void m_can_read_fifo(struct net_device *dev, u32 rxfs) for (i = 0; i < cf->len; i += 4) *(u32 *)(cf->data + i) = - m_can_fifo_read(priv, fgi, + m_can_fifo_read(cdev, fgi, M_CAN_FIFO_DATA(i / 4)); } /* acknowledge rx fifo 0 */ - m_can_write(priv, M_CAN_RXF0A, fgi); + m_can_write(cdev, M_CAN_RXF0A, fgi); stats->rx_packets++; stats->rx_bytes += cf->len; @@ -511,11 +511,11 @@ static void m_can_read_fifo(struct net_device *dev, u32 rxfs) static int m_can_do_rx_poll(struct net_device *dev, int quota) { - struct m_can_priv *priv = netdev_priv(dev); + struct m_can_classdev *cdev = netdev_priv(dev); u32 pkts = 0; u32 rxfs; - rxfs = m_can_read(priv, M_CAN_RXF0S); + rxfs = m_can_read(cdev, M_CAN_RXF0S); if (!(rxfs & RXFS_FFL_MASK)) { netdev_dbg(dev, "no messages in fifo0\n"); return 0; @@ -529,7 +529,7 @@ static int m_can_do_rx_poll(struct net_device *dev, int quota) quota--; pkts++; - rxfs = m_can_read(priv, M_CAN_RXF0S); + rxfs = m_can_read(cdev, M_CAN_RXF0S); } if (pkts) @@ -564,12 +564,12 @@ static int m_can_handle_lost_msg(struct net_device *dev) static int m_can_handle_lec_err(struct net_device *dev, enum m_can_lec_type lec_type) { - struct m_can_priv *priv = netdev_priv(dev); + struct m_can_classdev *cdev = netdev_priv(dev); struct net_device_stats *stats = &dev->stats; struct can_frame *cf; struct sk_buff *skb; - priv->can.can_stats.bus_error++; + cdev->can.can_stats.bus_error++; stats->rx_errors++; /* propagate the error condition to the CAN stack */ @@ -621,51 +621,51 @@ static int m_can_handle_lec_err(struct net_device *dev, static int __m_can_get_berr_counter(const struct net_device *dev, struct can_berr_counter *bec) { - struct m_can_priv *priv = netdev_priv(dev); + struct m_can_classdev *cdev = netdev_priv(dev); unsigned int ecr; - ecr = m_can_read(priv, M_CAN_ECR); + ecr = m_can_read(cdev, M_CAN_ECR); bec->rxerr = (ecr & ECR_REC_MASK) >> ECR_REC_SHIFT; bec->txerr = (ecr & ECR_TEC_MASK) >> ECR_TEC_SHIFT; return 0; } -static int m_can_clk_start(struct m_can_priv *priv) +static int m_can_clk_start(struct m_can_classdev *cdev) { int err; - if (priv->pm_clock_support == 0) + if (cdev->pm_clock_support == 0) return 0; - err = pm_runtime_get_sync(priv->dev); + err = pm_runtime_get_sync(cdev->dev); if (err < 0) { - pm_runtime_put_noidle(priv->dev); + pm_runtime_put_noidle(cdev->dev); return err; } return 0; } -static void m_can_clk_stop(struct m_can_priv *priv) +static void m_can_clk_stop(struct m_can_classdev *cdev) { - if (priv->pm_clock_support) - pm_runtime_put_sync(priv->dev); + if (cdev->pm_clock_support) + pm_runtime_put_sync(cdev->dev); } static int m_can_get_berr_counter(const struct net_device *dev, struct can_berr_counter *bec) { - struct m_can_priv *priv = netdev_priv(dev); + struct m_can_classdev *cdev = netdev_priv(dev); int err; - err = m_can_clk_start(priv); + err = m_can_clk_start(cdev); if (err) return err; __m_can_get_berr_counter(dev, bec); - m_can_clk_stop(priv); + m_can_clk_stop(cdev); return 0; } @@ -673,7 +673,7 @@ static int m_can_get_berr_counter(const struct net_device *dev, static int m_can_handle_state_change(struct net_device *dev, enum can_state new_state) { - struct m_can_priv *priv = netdev_priv(dev); + struct m_can_classdev *cdev = netdev_priv(dev); struct net_device_stats *stats = &dev->stats; struct can_frame *cf; struct sk_buff *skb; @@ -683,19 +683,19 @@ static int m_can_handle_state_change(struct net_device *dev, switch (new_state) { case CAN_STATE_ERROR_ACTIVE: /* error warning state */ - priv->can.can_stats.error_warning++; - priv->can.state = CAN_STATE_ERROR_WARNING; + cdev->can.can_stats.error_warning++; + cdev->can.state = CAN_STATE_ERROR_WARNING; break; case CAN_STATE_ERROR_PASSIVE: /* error passive state */ - priv->can.can_stats.error_passive++; - priv->can.state = CAN_STATE_ERROR_PASSIVE; + cdev->can.can_stats.error_passive++; + cdev->can.state = CAN_STATE_ERROR_PASSIVE; break; case CAN_STATE_BUS_OFF: /* bus-off state */ - priv->can.state = CAN_STATE_BUS_OFF; - m_can_disable_all_interrupts(priv); - priv->can.can_stats.bus_off++; + cdev->can.state = CAN_STATE_BUS_OFF; + m_can_disable_all_interrupts(cdev); + cdev->can.can_stats.bus_off++; can_bus_off(dev); break; default: @@ -722,7 +722,7 @@ static int m_can_handle_state_change(struct net_device *dev, case CAN_STATE_ERROR_PASSIVE: /* error passive state */ cf->can_id |= CAN_ERR_CRTL; - ecr = m_can_read(priv, M_CAN_ECR); + ecr = m_can_read(cdev, M_CAN_ECR); if (ecr & ECR_RP) cf->data[1] |= CAN_ERR_CRTL_RX_PASSIVE; if (bec.txerr > 127) @@ -747,25 +747,25 @@ static int m_can_handle_state_change(struct net_device *dev, static int m_can_handle_state_errors(struct net_device *dev, u32 psr) { - struct m_can_priv *priv = netdev_priv(dev); + struct m_can_classdev *cdev = netdev_priv(dev); int work_done = 0; if ((psr & PSR_EW) && - (priv->can.state != CAN_STATE_ERROR_WARNING)) { + (cdev->can.state != CAN_STATE_ERROR_WARNING)) { netdev_dbg(dev, "entered error warning state\n"); work_done += m_can_handle_state_change(dev, CAN_STATE_ERROR_WARNING); } if ((psr & PSR_EP) && - (priv->can.state != CAN_STATE_ERROR_PASSIVE)) { + (cdev->can.state != CAN_STATE_ERROR_PASSIVE)) { netdev_dbg(dev, "entered error passive state\n"); work_done += m_can_handle_state_change(dev, CAN_STATE_ERROR_PASSIVE); } if ((psr & PSR_BO) && - (priv->can.state != CAN_STATE_BUS_OFF)) { + (cdev->can.state != CAN_STATE_BUS_OFF)) { netdev_dbg(dev, "entered error bus off state\n"); work_done += m_can_handle_state_change(dev, CAN_STATE_BUS_OFF); @@ -800,14 +800,14 @@ static inline bool is_lec_err(u32 psr) static int m_can_handle_bus_errors(struct net_device *dev, u32 irqstatus, u32 psr) { - struct m_can_priv *priv = netdev_priv(dev); + struct m_can_classdev *cdev = netdev_priv(dev); int work_done = 0; if (irqstatus & IR_RF0L) work_done += m_can_handle_lost_msg(dev); /* handle lec errors on the bus */ - if ((priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) && + if ((cdev->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) && is_lec_err(psr)) work_done += m_can_handle_lec_err(dev, psr & LEC_UNUSED); @@ -819,15 +819,15 @@ static int m_can_handle_bus_errors(struct net_device *dev, u32 irqstatus, static int m_can_rx_handler(struct net_device *dev, int quota) { - struct m_can_priv *priv = netdev_priv(dev); + struct m_can_classdev *cdev = netdev_priv(dev); int work_done = 0; u32 irqstatus, psr; - irqstatus = priv->irqstatus | m_can_read(priv, M_CAN_IR); + irqstatus = cdev->irqstatus | m_can_read(cdev, M_CAN_IR); if (!irqstatus) goto end; - psr = m_can_read(priv, M_CAN_PSR); + psr = m_can_read(cdev, M_CAN_PSR); if (irqstatus & IR_ERR_STATE) work_done += m_can_handle_state_errors(dev, psr); @@ -842,11 +842,11 @@ static int m_can_rx_handler(struct net_device *dev, int quota) static int m_can_rx_peripheral(struct net_device *dev) { - struct m_can_priv *priv = netdev_priv(dev); + struct m_can_classdev *cdev = netdev_priv(dev); m_can_rx_handler(dev, 1); - m_can_enable_all_interrupts(priv); + m_can_enable_all_interrupts(cdev); return 0; } @@ -854,13 +854,13 @@ static int m_can_rx_peripheral(struct net_device *dev) static int m_can_poll(struct napi_struct *napi, int quota) { struct net_device *dev = napi->dev; - struct m_can_priv *priv = netdev_priv(dev); + struct m_can_classdev *cdev = netdev_priv(dev); int work_done; work_done = m_can_rx_handler(dev, quota); if (work_done < quota) { napi_complete_done(napi, work_done); - m_can_enable_all_interrupts(priv); + m_can_enable_all_interrupts(cdev); } return work_done; @@ -874,11 +874,11 @@ static void m_can_echo_tx_event(struct net_device *dev) int i = 0; unsigned int msg_mark; - struct m_can_priv *priv = netdev_priv(dev); + struct m_can_classdev *cdev = netdev_priv(dev); struct net_device_stats *stats = &dev->stats; /* read tx event fifo status */ - m_can_txefs = m_can_read(priv, M_CAN_TXEFS); + m_can_txefs = m_can_read(cdev, M_CAN_TXEFS); /* Get Tx Event fifo element count */ txe_count = (m_can_txefs & TXEFS_EFFL_MASK) @@ -887,15 +887,15 @@ static void m_can_echo_tx_event(struct net_device *dev) /* Get and process all sent elements */ for (i = 0; i < txe_count; i++) { /* retrieve get index */ - fgi = (m_can_read(priv, M_CAN_TXEFS) & TXEFS_EFGI_MASK) + fgi = (m_can_read(cdev, M_CAN_TXEFS) & TXEFS_EFGI_MASK) >> TXEFS_EFGI_SHIFT; /* get message marker */ - msg_mark = (m_can_txe_fifo_read(priv, fgi, 4) & + msg_mark = (m_can_txe_fifo_read(cdev, fgi, 4) & TX_EVENT_MM_MASK) >> TX_EVENT_MM_SHIFT; /* ack txe element */ - m_can_write(priv, M_CAN_TXEFA, (TXEFA_EFAI_MASK & + m_can_write(cdev, M_CAN_TXEFA, (TXEFA_EFAI_MASK & (fgi << TXEFA_EFAI_SHIFT))); /* update stats */ @@ -907,20 +907,20 @@ static void m_can_echo_tx_event(struct net_device *dev) static irqreturn_t m_can_isr(int irq, void *dev_id) { struct net_device *dev = (struct net_device *)dev_id; - struct m_can_priv *priv = netdev_priv(dev); + struct m_can_classdev *cdev = netdev_priv(dev); struct net_device_stats *stats = &dev->stats; u32 ir; - ir = m_can_read(priv, M_CAN_IR); + ir = m_can_read(cdev, M_CAN_IR); if (!ir) return IRQ_NONE; /* ACK all irqs */ if (ir & IR_ALL_INT) - m_can_write(priv, M_CAN_IR, ir); + m_can_write(cdev, M_CAN_IR, ir); - if (priv->ops->clear_interrupts) - priv->ops->clear_interrupts(priv); + if (cdev->ops->clear_interrupts) + cdev->ops->clear_interrupts(cdev); /* schedule NAPI in case of * - rx IRQ @@ -928,15 +928,15 @@ static irqreturn_t m_can_isr(int irq, void *dev_id) * - bus error IRQ and bus error reporting */ if ((ir & IR_RF0N) || (ir & IR_ERR_ALL_30X)) { - priv->irqstatus = ir; - m_can_disable_all_interrupts(priv); - if (!priv->is_peripheral) - napi_schedule(&priv->napi); + cdev->irqstatus = ir; + m_can_disable_all_interrupts(cdev); + if (!cdev->is_peripheral) + napi_schedule(&cdev->napi); else m_can_rx_peripheral(dev); } - if (priv->version == 30) { + if (cdev->version == 30) { if (ir & IR_TC) { /* Transmission Complete Interrupt*/ stats->tx_bytes += can_get_echo_skb(dev, 0); @@ -950,7 +950,7 @@ static irqreturn_t m_can_isr(int irq, void *dev_id) m_can_echo_tx_event(dev); can_led_event(dev, CAN_LED_EVENT_TX); if (netif_queue_stopped(dev) && - !m_can_tx_fifo_full(priv)) + !m_can_tx_fifo_full(cdev)) netif_wake_queue(dev); } } @@ -1008,9 +1008,9 @@ static const struct can_bittiming_const m_can_data_bittiming_const_31X = { static int m_can_set_bittiming(struct net_device *dev) { - struct m_can_priv *priv = netdev_priv(dev); - const struct can_bittiming *bt = &priv->can.bittiming; - const struct can_bittiming *dbt = &priv->can.data_bittiming; + struct m_can_classdev *cdev = netdev_priv(dev); + const struct can_bittiming *bt = &cdev->can.bittiming; + const struct can_bittiming *dbt = &cdev->can.data_bittiming; u16 brp, sjw, tseg1, tseg2; u32 reg_btp; @@ -1020,9 +1020,9 @@ static int m_can_set_bittiming(struct net_device *dev) tseg2 = bt->phase_seg2 - 1; reg_btp = (brp << NBTP_NBRP_SHIFT) | (sjw << NBTP_NSJW_SHIFT) | (tseg1 << NBTP_NTSEG1_SHIFT) | (tseg2 << NBTP_NTSEG2_SHIFT); - m_can_write(priv, M_CAN_NBTP, reg_btp); + m_can_write(cdev, M_CAN_NBTP, reg_btp); - if (priv->can.ctrlmode & CAN_CTRLMODE_FD) { + if (cdev->can.ctrlmode & CAN_CTRLMODE_FD) { reg_btp = 0; brp = dbt->brp - 1; sjw = dbt->sjw - 1; @@ -1044,7 +1044,7 @@ static int m_can_set_bittiming(struct net_device *dev) /* Equation based on Bosch's M_CAN User Manual's * Transmitter Delay Compensation Section */ - tdco = (priv->can.clock.freq / 1000) * + tdco = (cdev->can.clock.freq / 1000) * ssp / dbt->bitrate; /* Max valid TDCO value is 127 */ @@ -1055,7 +1055,7 @@ static int m_can_set_bittiming(struct net_device *dev) } reg_btp |= DBTP_TDC; - m_can_write(priv, M_CAN_TDCR, + m_can_write(cdev, M_CAN_TDCR, tdco << TDCR_TDCO_SHIFT); } @@ -1064,7 +1064,7 @@ static int m_can_set_bittiming(struct net_device *dev) (tseg1 << DBTP_DTSEG1_SHIFT) | (tseg2 << DBTP_DTSEG2_SHIFT); - m_can_write(priv, M_CAN_DBTP, reg_btp); + m_can_write(cdev, M_CAN_DBTP, reg_btp); } return 0; @@ -1081,63 +1081,63 @@ static int m_can_set_bittiming(struct net_device *dev) */ static void m_can_chip_config(struct net_device *dev) { - struct m_can_priv *priv = netdev_priv(dev); + struct m_can_classdev *cdev = netdev_priv(dev); u32 cccr, test; - m_can_config_endisable(priv, true); + m_can_config_endisable(cdev, true); /* RX Buffer/FIFO Element Size 64 bytes data field */ - m_can_write(priv, M_CAN_RXESC, M_CAN_RXESC_64BYTES); + m_can_write(cdev, M_CAN_RXESC, M_CAN_RXESC_64BYTES); /* Accept Non-matching Frames Into FIFO 0 */ - m_can_write(priv, M_CAN_GFC, 0x0); + m_can_write(cdev, M_CAN_GFC, 0x0); - if (priv->version == 30) { + if (cdev->version == 30) { /* only support one Tx Buffer currently */ - m_can_write(priv, M_CAN_TXBC, (1 << TXBC_NDTB_SHIFT) | - priv->mcfg[MRAM_TXB].off); + m_can_write(cdev, M_CAN_TXBC, (1 << TXBC_NDTB_SHIFT) | + cdev->mcfg[MRAM_TXB].off); } else { /* TX FIFO is used for newer IP Core versions */ - m_can_write(priv, M_CAN_TXBC, - (priv->mcfg[MRAM_TXB].num << TXBC_TFQS_SHIFT) | - (priv->mcfg[MRAM_TXB].off)); + m_can_write(cdev, M_CAN_TXBC, + (cdev->mcfg[MRAM_TXB].num << TXBC_TFQS_SHIFT) | + (cdev->mcfg[MRAM_TXB].off)); } /* support 64 bytes payload */ - m_can_write(priv, M_CAN_TXESC, TXESC_TBDS_64BYTES); + m_can_write(cdev, M_CAN_TXESC, TXESC_TBDS_64BYTES); /* TX Event FIFO */ - if (priv->version == 30) { - m_can_write(priv, M_CAN_TXEFC, (1 << TXEFC_EFS_SHIFT) | - priv->mcfg[MRAM_TXE].off); + if (cdev->version == 30) { + m_can_write(cdev, M_CAN_TXEFC, (1 << TXEFC_EFS_SHIFT) | + cdev->mcfg[MRAM_TXE].off); } else { /* Full TX Event FIFO is used */ - m_can_write(priv, M_CAN_TXEFC, - ((priv->mcfg[MRAM_TXE].num << TXEFC_EFS_SHIFT) + m_can_write(cdev, M_CAN_TXEFC, + ((cdev->mcfg[MRAM_TXE].num << TXEFC_EFS_SHIFT) & TXEFC_EFS_MASK) | - priv->mcfg[MRAM_TXE].off); + cdev->mcfg[MRAM_TXE].off); } /* rx fifo configuration, blocking mode, fifo size 1 */ - m_can_write(priv, M_CAN_RXF0C, - (priv->mcfg[MRAM_RXF0].num << RXFC_FS_SHIFT) | - priv->mcfg[MRAM_RXF0].off); + m_can_write(cdev, M_CAN_RXF0C, + (cdev->mcfg[MRAM_RXF0].num << RXFC_FS_SHIFT) | + cdev->mcfg[MRAM_RXF0].off); - m_can_write(priv, M_CAN_RXF1C, - (priv->mcfg[MRAM_RXF1].num << RXFC_FS_SHIFT) | - priv->mcfg[MRAM_RXF1].off); + m_can_write(cdev, M_CAN_RXF1C, + (cdev->mcfg[MRAM_RXF1].num << RXFC_FS_SHIFT) | + cdev->mcfg[MRAM_RXF1].off); - cccr = m_can_read(priv, M_CAN_CCCR); - test = m_can_read(priv, M_CAN_TEST); + cccr = m_can_read(cdev, M_CAN_CCCR); + test = m_can_read(cdev, M_CAN_TEST); test &= ~TEST_LBCK; - if (priv->version == 30) { + if (cdev->version == 30) { /* Version 3.0.x */ cccr &= ~(CCCR_TEST | CCCR_MON | (CCCR_CMR_MASK << CCCR_CMR_SHIFT) | (CCCR_CME_MASK << CCCR_CME_SHIFT)); - if (priv->can.ctrlmode & CAN_CTRLMODE_FD) + if (cdev->can.ctrlmode & CAN_CTRLMODE_FD) cccr |= CCCR_CME_CANFD_BRS << CCCR_CME_SHIFT; } else { @@ -1146,61 +1146,61 @@ static void m_can_chip_config(struct net_device *dev) CCCR_NISO); /* Only 3.2.x has NISO Bit implemented */ - if (priv->can.ctrlmode & CAN_CTRLMODE_FD_NON_ISO) + if (cdev->can.ctrlmode & CAN_CTRLMODE_FD_NON_ISO) cccr |= CCCR_NISO; - if (priv->can.ctrlmode & CAN_CTRLMODE_FD) + if (cdev->can.ctrlmode & CAN_CTRLMODE_FD) cccr |= (CCCR_BRSE | CCCR_FDOE); } /* Loopback Mode */ - if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) { + if (cdev->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) { cccr |= CCCR_TEST | CCCR_MON; test |= TEST_LBCK; } /* Enable Monitoring (all versions) */ - if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) + if (cdev->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) cccr |= CCCR_MON; /* Write config */ - m_can_write(priv, M_CAN_CCCR, cccr); - m_can_write(priv, M_CAN_TEST, test); + m_can_write(cdev, M_CAN_CCCR, cccr); + m_can_write(cdev, M_CAN_TEST, test); /* Enable interrupts */ - m_can_write(priv, M_CAN_IR, IR_ALL_INT); - if (!(priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)) - if (priv->version == 30) - m_can_write(priv, M_CAN_IE, IR_ALL_INT & + m_can_write(cdev, M_CAN_IR, IR_ALL_INT); + if (!(cdev->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)) + if (cdev->version == 30) + m_can_write(cdev, M_CAN_IE, IR_ALL_INT & ~(IR_ERR_LEC_30X)); else - m_can_write(priv, M_CAN_IE, IR_ALL_INT & + m_can_write(cdev, M_CAN_IE, IR_ALL_INT & ~(IR_ERR_LEC_31X)); else - m_can_write(priv, M_CAN_IE, IR_ALL_INT); + m_can_write(cdev, M_CAN_IE, IR_ALL_INT); /* route all interrupts to INT0 */ - m_can_write(priv, M_CAN_ILS, ILS_ALL_INT0); + m_can_write(cdev, M_CAN_ILS, ILS_ALL_INT0); /* set bittiming params */ m_can_set_bittiming(dev); - m_can_config_endisable(priv, false); + m_can_config_endisable(cdev, false); - if (priv->ops->init) - priv->ops->init(priv); + if (cdev->ops->init) + cdev->ops->init(cdev); } static void m_can_start(struct net_device *dev) { - struct m_can_priv *priv = netdev_priv(dev); + struct m_can_classdev *cdev = netdev_priv(dev); /* basic m_can configuration */ m_can_chip_config(dev); - priv->can.state = CAN_STATE_ERROR_ACTIVE; + cdev->can.state = CAN_STATE_ERROR_ACTIVE; - m_can_enable_all_interrupts(priv); + m_can_enable_all_interrupts(cdev); } static int m_can_set_mode(struct net_device *dev, enum can_mode mode) @@ -1223,7 +1223,7 @@ static int m_can_set_mode(struct net_device *dev, enum can_mode mode) * else it returns the release and step coded as: * return value = 10 * + 1 * */ -static int m_can_check_core_release(struct m_can_priv *priv) +static int m_can_check_core_release(struct m_can_classdev *cdev) { u32 crel_reg; u8 rel; @@ -1233,7 +1233,7 @@ static int m_can_check_core_release(struct m_can_priv *priv) /* Read Core Release Version and split into version number * Example: Version 3.2.1 => rel = 3; step = 2; substep = 1; */ - crel_reg = m_can_read(priv, M_CAN_CREL); + crel_reg = m_can_read(cdev, M_CAN_CREL); rel = (u8)((crel_reg & CREL_REL_MASK) >> CREL_REL_SHIFT); step = (u8)((crel_reg & CREL_STEP_MASK) >> CREL_STEP_SHIFT); @@ -1251,19 +1251,19 @@ static int m_can_check_core_release(struct m_can_priv *priv) /* Selectable Non ISO support only in version 3.2.x * This function checks if the bit is writable. */ -static bool m_can_niso_supported(struct m_can_priv *priv) +static bool m_can_niso_supported(struct m_can_classdev *cdev) { u32 cccr_reg, cccr_poll = 0; int niso_timeout = -ETIMEDOUT; int i; - m_can_config_endisable(priv, true); - cccr_reg = m_can_read(priv, M_CAN_CCCR); + m_can_config_endisable(cdev, true); + cccr_reg = m_can_read(cdev, M_CAN_CCCR); cccr_reg |= CCCR_NISO; - m_can_write(priv, M_CAN_CCCR, cccr_reg); + m_can_write(cdev, M_CAN_CCCR, cccr_reg); for (i = 0; i <= 10; i++) { - cccr_poll = m_can_read(priv, M_CAN_CCCR); + cccr_poll = m_can_read(cdev, M_CAN_CCCR); if (cccr_poll == cccr_reg) { niso_timeout = 0; break; @@ -1274,15 +1274,15 @@ static bool m_can_niso_supported(struct m_can_priv *priv) /* Clear NISO */ cccr_reg &= ~(CCCR_NISO); - m_can_write(priv, M_CAN_CCCR, cccr_reg); + m_can_write(cdev, M_CAN_CCCR, cccr_reg); - m_can_config_endisable(priv, false); + m_can_config_endisable(cdev, false); /* return false if time out (-ETIMEDOUT), else return true */ return !niso_timeout; } -static int m_can_dev_setup(struct m_can_priv *m_can_dev) +static int m_can_dev_setup(struct m_can_classdev *m_can_dev) { struct net_device *dev = m_can_dev->net; int m_can_version; @@ -1359,30 +1359,32 @@ static int m_can_dev_setup(struct m_can_priv *m_can_dev) static void m_can_stop(struct net_device *dev) { - struct m_can_priv *priv = netdev_priv(dev); + struct m_can_classdev *cdev = netdev_priv(dev); /* disable all interrupts */ - m_can_disable_all_interrupts(priv); + m_can_disable_all_interrupts(cdev); /* set the state as STOPPED */ - priv->can.state = CAN_STATE_STOPPED; + cdev->can.state = CAN_STATE_STOPPED; } static int m_can_close(struct net_device *dev) { - struct m_can_priv *priv = netdev_priv(dev); + struct m_can_classdev *cdev = netdev_priv(dev); netif_stop_queue(dev); - if (!priv->is_peripheral) - napi_disable(&priv->napi); + + if (!cdev->is_peripheral) + napi_disable(&cdev->napi); + m_can_stop(dev); - m_can_clk_stop(priv); + m_can_clk_stop(cdev); free_irq(dev->irq, dev); - if (priv->is_peripheral) { - priv->tx_skb = NULL; - destroy_workqueue(priv->tx_wq); - priv->tx_wq = NULL; + if (cdev->is_peripheral) { + cdev->tx_skb = NULL; + destroy_workqueue(cdev->tx_wq); + cdev->tx_wq = NULL; } close_candev(dev); @@ -1393,23 +1395,23 @@ static int m_can_close(struct net_device *dev) static int m_can_next_echo_skb_occupied(struct net_device *dev, int putidx) { - struct m_can_priv *priv = netdev_priv(dev); + struct m_can_classdev *cdev = netdev_priv(dev); /*get wrap around for loopback skb index */ - unsigned int wrap = priv->can.echo_skb_max; + unsigned int wrap = cdev->can.echo_skb_max; int next_idx; /* calculate next index */ next_idx = (++putidx >= wrap ? 0 : putidx); /* check if occupied */ - return !!priv->can.echo_skb[next_idx]; + return !!cdev->can.echo_skb[next_idx]; } -static netdev_tx_t m_can_tx_handler(struct m_can_priv *priv) +static netdev_tx_t m_can_tx_handler(struct m_can_classdev *cdev) { - struct canfd_frame *cf = (struct canfd_frame *)priv->tx_skb->data; - struct net_device *dev = priv->net; - struct sk_buff *skb = priv->tx_skb; + struct canfd_frame *cf = (struct canfd_frame *)cdev->tx_skb->data; + struct net_device *dev = cdev->net; + struct sk_buff *skb = cdev->tx_skb; u32 id, cccr, fdflags; int i; int putidx; @@ -1426,23 +1428,23 @@ static netdev_tx_t m_can_tx_handler(struct m_can_priv *priv) if (cf->can_id & CAN_RTR_FLAG) id |= TX_BUF_RTR; - if (priv->version == 30) { + if (cdev->version == 30) { netif_stop_queue(dev); /* message ram configuration */ - m_can_fifo_write(priv, 0, M_CAN_FIFO_ID, id); - m_can_fifo_write(priv, 0, M_CAN_FIFO_DLC, + m_can_fifo_write(cdev, 0, M_CAN_FIFO_ID, id); + m_can_fifo_write(cdev, 0, M_CAN_FIFO_DLC, can_len2dlc(cf->len) << 16); for (i = 0; i < cf->len; i += 4) - m_can_fifo_write(priv, 0, + m_can_fifo_write(cdev, 0, M_CAN_FIFO_DATA(i / 4), *(u32 *)(cf->data + i)); can_put_echo_skb(skb, dev, 0); - if (priv->can.ctrlmode & CAN_CTRLMODE_FD) { - cccr = m_can_read(priv, M_CAN_CCCR); + if (cdev->can.ctrlmode & CAN_CTRLMODE_FD) { + cccr = m_can_read(cdev, M_CAN_CCCR); cccr &= ~(CCCR_CMR_MASK << CCCR_CMR_SHIFT); if (can_is_canfd_skb(skb)) { if (cf->flags & CANFD_BRS) @@ -1454,21 +1456,22 @@ static netdev_tx_t m_can_tx_handler(struct m_can_priv *priv) } else { cccr |= CCCR_CMR_CAN << CCCR_CMR_SHIFT; } - m_can_write(priv, M_CAN_CCCR, cccr); + m_can_write(cdev, M_CAN_CCCR, cccr); } - m_can_write(priv, M_CAN_TXBTIE, 0x1); - m_can_write(priv, M_CAN_TXBAR, 0x1); + m_can_write(cdev, M_CAN_TXBTIE, 0x1); + m_can_write(cdev, M_CAN_TXBAR, 0x1); /* End of xmit function for version 3.0.x */ } else { /* Transmit routine for version >= v3.1.x */ /* Check if FIFO full */ - if (m_can_tx_fifo_full(priv)) { + if (m_can_tx_fifo_full(cdev)) { /* This shouldn't happen */ netif_stop_queue(dev); netdev_warn(dev, "TX queue active although FIFO is full."); - if (priv->is_peripheral) { + + if (cdev->is_peripheral) { kfree_skb(skb); dev->stats.tx_dropped++; return NETDEV_TX_OK; @@ -1478,10 +1481,10 @@ static netdev_tx_t m_can_tx_handler(struct m_can_priv *priv) } /* get put index for frame */ - putidx = ((m_can_read(priv, M_CAN_TXFQS) & TXFQS_TFQPI_MASK) + putidx = ((m_can_read(cdev, M_CAN_TXFQS) & TXFQS_TFQPI_MASK) >> TXFQS_TFQPI_SHIFT); /* Write ID Field to FIFO Element */ - m_can_fifo_write(priv, putidx, M_CAN_FIFO_ID, id); + m_can_fifo_write(cdev, putidx, M_CAN_FIFO_ID, id); /* get CAN FD configuration of frame */ fdflags = 0; @@ -1496,14 +1499,14 @@ static netdev_tx_t m_can_tx_handler(struct m_can_priv *priv) * it is used in TX interrupt for * sending the correct echo frame */ - m_can_fifo_write(priv, putidx, M_CAN_FIFO_DLC, + m_can_fifo_write(cdev, putidx, M_CAN_FIFO_DLC, ((putidx << TX_BUF_MM_SHIFT) & TX_BUF_MM_MASK) | (can_len2dlc(cf->len) << 16) | fdflags | TX_BUF_EFC); for (i = 0; i < cf->len; i += 4) - m_can_fifo_write(priv, putidx, M_CAN_FIFO_DATA(i / 4), + m_can_fifo_write(cdev, putidx, M_CAN_FIFO_DATA(i / 4), *(u32 *)(cf->data + i)); /* Push loopback echo. @@ -1512,10 +1515,10 @@ static netdev_tx_t m_can_tx_handler(struct m_can_priv *priv) can_put_echo_skb(skb, dev, putidx); /* Enable TX FIFO element to start transfer */ - m_can_write(priv, M_CAN_TXBAR, (1 << putidx)); + m_can_write(cdev, M_CAN_TXBAR, (1 << putidx)); /* stop network queue if fifo full */ - if (m_can_tx_fifo_full(priv) || + if (m_can_tx_fifo_full(cdev) || m_can_next_echo_skb_occupied(dev, putidx)) netif_stop_queue(dev); } @@ -1525,27 +1528,28 @@ static netdev_tx_t m_can_tx_handler(struct m_can_priv *priv) static void m_can_tx_work_queue(struct work_struct *ws) { - struct m_can_priv *priv = container_of(ws, struct m_can_priv, + struct m_can_classdev *cdev = container_of(ws, struct m_can_classdev, tx_work); - m_can_tx_handler(priv); - priv->tx_skb = NULL; + + m_can_tx_handler(cdev); + cdev->tx_skb = NULL; } static netdev_tx_t m_can_start_xmit(struct sk_buff *skb, struct net_device *dev) { - struct m_can_priv *priv = netdev_priv(dev); + struct m_can_classdev *cdev = netdev_priv(dev); if (can_dropped_invalid_skb(dev, skb)) return NETDEV_TX_OK; - if (priv->is_peripheral) { - if (priv->tx_skb) { + if (cdev->is_peripheral) { + if (cdev->tx_skb) { netdev_err(dev, "hard_xmit called while tx busy\n"); return NETDEV_TX_BUSY; } - if (priv->can.state == CAN_STATE_BUS_OFF) { + if (cdev->can.state == CAN_STATE_BUS_OFF) { m_can_clean(dev); } else { /* Need to stop the queue to avoid numerous requests @@ -1553,13 +1557,13 @@ static netdev_tx_t m_can_start_xmit(struct sk_buff *skb, * a queueing mechanism that will queue the skbs and * process them in order. */ - priv->tx_skb = skb; - netif_stop_queue(priv->net); - queue_work(priv->tx_wq, &priv->tx_work); + cdev->tx_skb = skb; + netif_stop_queue(cdev->net); + queue_work(cdev->tx_wq, &cdev->tx_work); } } else { - priv->tx_skb = skb; - return m_can_tx_handler(priv); + cdev->tx_skb = skb; + return m_can_tx_handler(cdev); } return NETDEV_TX_OK; @@ -1567,10 +1571,10 @@ static netdev_tx_t m_can_start_xmit(struct sk_buff *skb, static int m_can_open(struct net_device *dev) { - struct m_can_priv *priv = netdev_priv(dev); + struct m_can_classdev *cdev = netdev_priv(dev); int err; - err = m_can_clk_start(priv); + err = m_can_clk_start(cdev); if (err) return err; @@ -1582,16 +1586,16 @@ static int m_can_open(struct net_device *dev) } /* register interrupt handler */ - if (priv->is_peripheral) { - priv->tx_skb = NULL; - priv->tx_wq = alloc_workqueue("mcan_wq", + if (cdev->is_peripheral) { + cdev->tx_skb = NULL; + cdev->tx_wq = alloc_workqueue("mcan_wq", WQ_FREEZABLE | WQ_MEM_RECLAIM, 0); - if (!priv->tx_wq) { + if (!cdev->tx_wq) { err = -ENOMEM; goto out_wq_fail; } - INIT_WORK(&priv->tx_work, m_can_tx_work_queue); + INIT_WORK(&cdev->tx_work, m_can_tx_work_queue); err = request_threaded_irq(dev->irq, NULL, m_can_isr, IRQF_ONESHOT | IRQF_TRIGGER_FALLING, @@ -1611,20 +1615,20 @@ static int m_can_open(struct net_device *dev) can_led_event(dev, CAN_LED_EVENT_OPEN); - if (!priv->is_peripheral) - napi_enable(&priv->napi); + if (!cdev->is_peripheral) + napi_enable(&cdev->napi); netif_start_queue(dev); return 0; exit_irq_fail: - if (priv->is_peripheral) - destroy_workqueue(priv->tx_wq); + if (cdev->is_peripheral) + destroy_workqueue(cdev->tx_wq); out_wq_fail: close_candev(dev); exit_disable_clks: - m_can_clk_stop(priv); + m_can_clk_stop(cdev); return err; } @@ -1643,61 +1647,61 @@ static int register_m_can_dev(struct net_device *dev) return register_candev(dev); } -static void m_can_of_parse_mram(struct m_can_priv *priv, +static void m_can_of_parse_mram(struct m_can_classdev *cdev, const u32 *mram_config_vals) { - priv->mcfg[MRAM_SIDF].off = mram_config_vals[0]; - priv->mcfg[MRAM_SIDF].num = mram_config_vals[1]; - priv->mcfg[MRAM_XIDF].off = priv->mcfg[MRAM_SIDF].off + - priv->mcfg[MRAM_SIDF].num * SIDF_ELEMENT_SIZE; - priv->mcfg[MRAM_XIDF].num = mram_config_vals[2]; - priv->mcfg[MRAM_RXF0].off = priv->mcfg[MRAM_XIDF].off + - priv->mcfg[MRAM_XIDF].num * XIDF_ELEMENT_SIZE; - priv->mcfg[MRAM_RXF0].num = mram_config_vals[3] & + cdev->mcfg[MRAM_SIDF].off = mram_config_vals[0]; + cdev->mcfg[MRAM_SIDF].num = mram_config_vals[1]; + cdev->mcfg[MRAM_XIDF].off = cdev->mcfg[MRAM_SIDF].off + + cdev->mcfg[MRAM_SIDF].num * SIDF_ELEMENT_SIZE; + cdev->mcfg[MRAM_XIDF].num = mram_config_vals[2]; + cdev->mcfg[MRAM_RXF0].off = cdev->mcfg[MRAM_XIDF].off + + cdev->mcfg[MRAM_XIDF].num * XIDF_ELEMENT_SIZE; + cdev->mcfg[MRAM_RXF0].num = mram_config_vals[3] & (RXFC_FS_MASK >> RXFC_FS_SHIFT); - priv->mcfg[MRAM_RXF1].off = priv->mcfg[MRAM_RXF0].off + - priv->mcfg[MRAM_RXF0].num * RXF0_ELEMENT_SIZE; - priv->mcfg[MRAM_RXF1].num = mram_config_vals[4] & + cdev->mcfg[MRAM_RXF1].off = cdev->mcfg[MRAM_RXF0].off + + cdev->mcfg[MRAM_RXF0].num * RXF0_ELEMENT_SIZE; + cdev->mcfg[MRAM_RXF1].num = mram_config_vals[4] & (RXFC_FS_MASK >> RXFC_FS_SHIFT); - priv->mcfg[MRAM_RXB].off = priv->mcfg[MRAM_RXF1].off + - priv->mcfg[MRAM_RXF1].num * RXF1_ELEMENT_SIZE; - priv->mcfg[MRAM_RXB].num = mram_config_vals[5]; - priv->mcfg[MRAM_TXE].off = priv->mcfg[MRAM_RXB].off + - priv->mcfg[MRAM_RXB].num * RXB_ELEMENT_SIZE; - priv->mcfg[MRAM_TXE].num = mram_config_vals[6]; - priv->mcfg[MRAM_TXB].off = priv->mcfg[MRAM_TXE].off + - priv->mcfg[MRAM_TXE].num * TXE_ELEMENT_SIZE; - priv->mcfg[MRAM_TXB].num = mram_config_vals[7] & + cdev->mcfg[MRAM_RXB].off = cdev->mcfg[MRAM_RXF1].off + + cdev->mcfg[MRAM_RXF1].num * RXF1_ELEMENT_SIZE; + cdev->mcfg[MRAM_RXB].num = mram_config_vals[5]; + cdev->mcfg[MRAM_TXE].off = cdev->mcfg[MRAM_RXB].off + + cdev->mcfg[MRAM_RXB].num * RXB_ELEMENT_SIZE; + cdev->mcfg[MRAM_TXE].num = mram_config_vals[6]; + cdev->mcfg[MRAM_TXB].off = cdev->mcfg[MRAM_TXE].off + + cdev->mcfg[MRAM_TXE].num * TXE_ELEMENT_SIZE; + cdev->mcfg[MRAM_TXB].num = mram_config_vals[7] & (TXBC_NDTB_MASK >> TXBC_NDTB_SHIFT); - dev_dbg(priv->dev, + dev_dbg(cdev->dev, "sidf 0x%x %d xidf 0x%x %d rxf0 0x%x %d rxf1 0x%x %d rxb 0x%x %d txe 0x%x %d txb 0x%x %d\n", - priv->mcfg[MRAM_SIDF].off, priv->mcfg[MRAM_SIDF].num, - priv->mcfg[MRAM_XIDF].off, priv->mcfg[MRAM_XIDF].num, - priv->mcfg[MRAM_RXF0].off, priv->mcfg[MRAM_RXF0].num, - priv->mcfg[MRAM_RXF1].off, priv->mcfg[MRAM_RXF1].num, - priv->mcfg[MRAM_RXB].off, priv->mcfg[MRAM_RXB].num, - priv->mcfg[MRAM_TXE].off, priv->mcfg[MRAM_TXE].num, - priv->mcfg[MRAM_TXB].off, priv->mcfg[MRAM_TXB].num); + cdev->mcfg[MRAM_SIDF].off, cdev->mcfg[MRAM_SIDF].num, + cdev->mcfg[MRAM_XIDF].off, cdev->mcfg[MRAM_XIDF].num, + cdev->mcfg[MRAM_RXF0].off, cdev->mcfg[MRAM_RXF0].num, + cdev->mcfg[MRAM_RXF1].off, cdev->mcfg[MRAM_RXF1].num, + cdev->mcfg[MRAM_RXB].off, cdev->mcfg[MRAM_RXB].num, + cdev->mcfg[MRAM_TXE].off, cdev->mcfg[MRAM_TXE].num, + cdev->mcfg[MRAM_TXB].off, cdev->mcfg[MRAM_TXB].num); } -void m_can_init_ram(struct m_can_priv *priv) +void m_can_init_ram(struct m_can_classdev *cdev) { int end, i, start; /* initialize the entire Message RAM in use to avoid possible * ECC/parity checksum errors when reading an uninitialized buffer */ - start = priv->mcfg[MRAM_SIDF].off; - end = priv->mcfg[MRAM_TXB].off + - priv->mcfg[MRAM_TXB].num * TXB_ELEMENT_SIZE; + start = cdev->mcfg[MRAM_SIDF].off; + end = cdev->mcfg[MRAM_TXB].off + + cdev->mcfg[MRAM_TXB].num * TXB_ELEMENT_SIZE; for (i = start; i < end; i += 4) - m_can_fifo_write_no_off(priv, i, 0x0); + m_can_fifo_write_no_off(cdev, i, 0x0); } EXPORT_SYMBOL_GPL(m_can_init_ram); -int m_can_class_get_clocks(struct m_can_priv *m_can_dev) +int m_can_class_get_clocks(struct m_can_classdev *m_can_dev) { int ret = 0; @@ -1713,9 +1717,9 @@ int m_can_class_get_clocks(struct m_can_priv *m_can_dev) } EXPORT_SYMBOL_GPL(m_can_class_get_clocks); -struct m_can_priv *m_can_class_allocate_dev(struct device *dev) +struct m_can_classdev *m_can_class_allocate_dev(struct device *dev) { - struct m_can_priv *class_dev = NULL; + struct m_can_classdev *class_dev = NULL; u32 mram_config_vals[MRAM_CFG_LEN]; struct net_device *net_dev; u32 tx_fifo_size; @@ -1744,7 +1748,7 @@ struct m_can_priv *m_can_class_allocate_dev(struct device *dev) class_dev = netdev_priv(net_dev); if (!class_dev) { - dev_err(dev, "Failed to init netdev private"); + dev_err(dev, "Failed to init netdev cdevate"); goto out; } @@ -1758,7 +1762,7 @@ struct m_can_priv *m_can_class_allocate_dev(struct device *dev) } EXPORT_SYMBOL_GPL(m_can_class_allocate_dev); -int m_can_class_register(struct m_can_priv *m_can_dev) +int m_can_class_register(struct m_can_classdev *m_can_dev) { int ret; @@ -1806,18 +1810,18 @@ EXPORT_SYMBOL_GPL(m_can_class_register); int m_can_class_suspend(struct device *dev) { struct net_device *ndev = dev_get_drvdata(dev); - struct m_can_priv *priv = netdev_priv(ndev); + struct m_can_classdev *cdev = netdev_priv(ndev); if (netif_running(ndev)) { netif_stop_queue(ndev); netif_device_detach(ndev); m_can_stop(ndev); - m_can_clk_stop(priv); + m_can_clk_stop(cdev); } pinctrl_pm_select_sleep_state(dev); - priv->can.state = CAN_STATE_SLEEPING; + cdev->can.state = CAN_STATE_SLEEPING; return 0; } @@ -1826,20 +1830,20 @@ EXPORT_SYMBOL_GPL(m_can_class_suspend); int m_can_class_resume(struct device *dev) { struct net_device *ndev = dev_get_drvdata(dev); - struct m_can_priv *priv = netdev_priv(ndev); + struct m_can_classdev *cdev = netdev_priv(ndev); pinctrl_pm_select_default_state(dev); - priv->can.state = CAN_STATE_ERROR_ACTIVE; + cdev->can.state = CAN_STATE_ERROR_ACTIVE; if (netif_running(ndev)) { int ret; - ret = m_can_clk_start(priv); + ret = m_can_clk_start(cdev); if (ret) return ret; - m_can_init_ram(priv); + m_can_init_ram(cdev); m_can_start(ndev); netif_device_attach(ndev); netif_start_queue(ndev); @@ -1849,7 +1853,7 @@ int m_can_class_resume(struct device *dev) } EXPORT_SYMBOL_GPL(m_can_class_resume); -void m_can_class_unregister(struct m_can_priv *m_can_dev) +void m_can_class_unregister(struct m_can_classdev *m_can_dev) { unregister_candev(m_can_dev->net); diff --git a/drivers/net/can/m_can/m_can.h b/drivers/net/can/m_can/m_can.h index 5671f5423887..49f42b50627a 100644 --- a/drivers/net/can/m_can/m_can.h +++ b/drivers/net/can/m_can/m_can.h @@ -57,19 +57,19 @@ struct mram_cfg { u8 num; }; -struct m_can_priv; +struct m_can_classdev; struct m_can_ops { /* Device specific call backs */ - int (*clear_interrupts)(struct m_can_priv *m_can_class); - u32 (*read_reg)(struct m_can_priv *m_can_class, int reg); - int (*write_reg)(struct m_can_priv *m_can_class, int reg, int val); - u32 (*read_fifo)(struct m_can_priv *m_can_class, int addr_offset); - int (*write_fifo)(struct m_can_priv *m_can_class, int addr_offset, + int (*clear_interrupts)(struct m_can_classdev *cdev); + u32 (*read_reg)(struct m_can_classdev *cdev, int reg); + int (*write_reg)(struct m_can_classdev *cdev, int reg, int val); + u32 (*read_fifo)(struct m_can_classdev *cdev, int addr_offset); + int (*write_fifo)(struct m_can_classdev *cdev, int addr_offset, int val); - int (*init)(struct m_can_priv *m_can_class); + int (*init)(struct m_can_classdev *cdev); }; -struct m_can_priv { +struct m_can_classdev { struct can_priv can; struct napi_struct napi; struct net_device *net; @@ -98,12 +98,12 @@ struct m_can_priv { struct mram_cfg mcfg[MRAM_CFG_NUM]; }; -struct m_can_priv *m_can_class_allocate_dev(struct device *dev); -int m_can_class_register(struct m_can_priv *m_can_dev); -void m_can_class_unregister(struct m_can_priv *m_can_dev); -int m_can_class_get_clocks(struct m_can_priv *m_can_dev); -void m_can_init_ram(struct m_can_priv *priv); -void m_can_config_endisable(struct m_can_priv *priv, bool enable); +struct m_can_classdev *m_can_class_allocate_dev(struct device *dev); +int m_can_class_register(struct m_can_classdev *cdev); +void m_can_class_unregister(struct m_can_classdev *cdev); +int m_can_class_get_clocks(struct m_can_classdev *cdev); +void m_can_init_ram(struct m_can_classdev *priv); +void m_can_config_endisable(struct m_can_classdev *priv, bool enable); int m_can_class_suspend(struct device *dev); int m_can_class_resume(struct device *dev); diff --git a/drivers/net/can/m_can/m_can_platform.c b/drivers/net/can/m_can/m_can_platform.c index 026053f62f77..c2989e0431f2 100644 --- a/drivers/net/can/m_can/m_can_platform.c +++ b/drivers/net/can/m_can/m_can_platform.c @@ -14,7 +14,7 @@ struct m_can_plat_priv { void __iomem *mram_base; }; -static u32 iomap_read_reg(struct m_can_priv *cdev, int reg) +static u32 iomap_read_reg(struct m_can_classdev *cdev, int reg) { struct m_can_plat_priv *priv = (struct m_can_plat_priv *)cdev->device_data; @@ -22,7 +22,7 @@ static u32 iomap_read_reg(struct m_can_priv *cdev, int reg) return readl(priv->base + reg); } -static u32 iomap_read_fifo(struct m_can_priv *cdev, int offset) +static u32 iomap_read_fifo(struct m_can_classdev *cdev, int offset) { struct m_can_plat_priv *priv = (struct m_can_plat_priv *)cdev->device_data; @@ -30,7 +30,7 @@ static u32 iomap_read_fifo(struct m_can_priv *cdev, int offset) return readl(priv->mram_base + offset); } -static int iomap_write_reg(struct m_can_priv *cdev, int reg, int val) +static int iomap_write_reg(struct m_can_classdev *cdev, int reg, int val) { struct m_can_plat_priv *priv = (struct m_can_plat_priv *)cdev->device_data; @@ -40,7 +40,7 @@ static int iomap_write_reg(struct m_can_priv *cdev, int reg, int val) return 0; } -static int iomap_write_fifo(struct m_can_priv *cdev, int offset, int val) +static int iomap_write_fifo(struct m_can_classdev *cdev, int offset, int val) { struct m_can_plat_priv *priv = (struct m_can_plat_priv *)cdev->device_data; @@ -59,7 +59,7 @@ static struct m_can_ops m_can_plat_ops = { static int m_can_plat_probe(struct platform_device *pdev) { - struct m_can_priv *mcan_class; + struct m_can_classdev *mcan_class; struct m_can_plat_priv *priv; struct resource *res; void __iomem *addr; @@ -131,7 +131,7 @@ static __maybe_unused int m_can_resume(struct device *dev) static int m_can_plat_remove(struct platform_device *pdev) { struct net_device *dev = platform_get_drvdata(pdev); - struct m_can_priv *mcan_class = netdev_priv(dev); + struct m_can_classdev *mcan_class = netdev_priv(dev); m_can_class_unregister(mcan_class); @@ -143,7 +143,7 @@ static int m_can_plat_remove(struct platform_device *pdev) static int __maybe_unused m_can_runtime_suspend(struct device *dev) { struct net_device *ndev = dev_get_drvdata(dev); - struct m_can_priv *mcan_class = netdev_priv(ndev); + struct m_can_classdev *mcan_class = netdev_priv(ndev); m_can_class_suspend(dev); @@ -156,7 +156,7 @@ static int __maybe_unused m_can_runtime_suspend(struct device *dev) static int __maybe_unused m_can_runtime_resume(struct device *dev) { struct net_device *ndev = dev_get_drvdata(dev); - struct m_can_priv *mcan_class = netdev_priv(ndev); + struct m_can_classdev *mcan_class = netdev_priv(ndev); int err; err = clk_prepare_enable(mcan_class->hclk); From patchwork Tue Mar 19 17:26:49 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dan Murphy X-Patchwork-Id: 160596 Delivered-To: patch@linaro.org Received: by 2002:a02:5cc1:0:0:0:0:0 with SMTP id w62csp4139358jad; Tue, 19 Mar 2019 10:27:26 -0700 (PDT) X-Google-Smtp-Source: APXvYqzhzYtasC8Uk+bVJphI3lgNYwbyCGDYysHQJzMdpUqONTJVf7lYV4JrvdlUSmPHC8C87wD+ X-Received: by 2002:a63:9a4a:: with SMTP id e10mr2776604pgo.366.1553016446030; Tue, 19 Mar 2019 10:27:26 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1553016446; cv=none; d=google.com; s=arc-20160816; b=R+BZMMqf/NVbqlDjFVVWF2eyUNS2zTWXuZQvNW1XOQN34tc2CdGXMsSjbhAxwwCwgd MzGwgJuWNVVQfKwMp5wZSjjSaJbSATpJRoRUURCkcWBAW29fd6W626GjwxV2qZGqX5Lr nTmzVVtEx5ZlGVNNeUM3Cd7voKDgxGLYXINd5RlSxf+QjQ7gXYzQj4/VCdsPMopjGI60 ch0yg3ksloinKfb0k/O877P2I/RNGJi+qa2f1i6QPeqn3LflKokT5HGBKkB0FVNNa7nW D5b+JLJ1DnHMlx+DGUQCpHxnHrS2dC2x4sSS5Ynj/B9ALIbLw4SgxrZaNwJ2LtzYvF6i dFnw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=5cXwXP9bwo/nqhmt0UXQ/YanJPauYYzEYg6KInyzYII=; b=WylOLehagHPNoYB25+mrwxBfXson6FE65MGPE6hAhVowoFv69KDzT3C0oVY/NbJcoQ OaqPDI2DbXRFSsUXjlg2JmPgTVvV9thR5xPgnkh0kYUeJBxiUUY8dkS6XuOU3gUui3Rz Z0olF03ZtQ7AzDGCGBHrnoaC4E35JhoTACk33ujlBV1XQDI5geA28vN68nbQJTFH5uHf MUy/x/iKdmetfRcliPUGEg5Z601BuLcdmacwy0u0SrXC6nm0aueDOeu3nf4jZ39lQaNB 5/gzjZ2BltPKZ1JlYqpBbOMq1t0l4A1png6Q6JKNfkdw5anS+E/4agivDDEsEGsaK+qw 4g4g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=Wr+UqHBP; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id r18si12568531pgd.585.2019.03.19.10.27.25; Tue, 19 Mar 2019 10:27:26 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=Wr+UqHBP; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727653AbfCSR1Y (ORCPT + 31 others); Tue, 19 Mar 2019 13:27:24 -0400 Received: from fllv0015.ext.ti.com ([198.47.19.141]:34392 "EHLO fllv0015.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726860AbfCSR1X (ORCPT ); Tue, 19 Mar 2019 13:27:23 -0400 Received: from fllv0034.itg.ti.com ([10.64.40.246]) by fllv0015.ext.ti.com (8.15.2/8.15.2) with ESMTP id x2JHRGQG094704; Tue, 19 Mar 2019 12:27:16 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1553016436; bh=5cXwXP9bwo/nqhmt0UXQ/YanJPauYYzEYg6KInyzYII=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=Wr+UqHBPi2dWcSoXLgtyg1AiOc/onV6d84JdcnVTRJp7BmK0gHq85NMHvFC7MNO8X 0CkA1TPd7/2MdkXdvD/sbCnCAn3rUaaN2vM/0tP9J2h36y6gawfglX2EWe0hdNk/l/ pAMHbVlvwwpiyNGey/4Ekae4bMhC0eCWFFmTjnSI= Received: from DFLE115.ent.ti.com (dfle115.ent.ti.com [10.64.6.36]) by fllv0034.itg.ti.com (8.15.2/8.15.2) with ESMTPS id x2JHRGlS106769 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 19 Mar 2019 12:27:16 -0500 Received: from DFLE110.ent.ti.com (10.64.6.31) by DFLE115.ent.ti.com (10.64.6.36) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1713.5; Tue, 19 Mar 2019 12:27:16 -0500 Received: from dlep33.itg.ti.com (157.170.170.75) by DFLE110.ent.ti.com (10.64.6.31) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.1713.5 via Frontend Transport; Tue, 19 Mar 2019 12:27:16 -0500 Received: from localhost (ileax41-snat.itg.ti.com [10.172.224.153]) by dlep33.itg.ti.com (8.14.3/8.13.8) with ESMTP id x2JHRGRq000383; Tue, 19 Mar 2019 12:27:16 -0500 From: Dan Murphy To: , , CC: , , , Dan Murphy Subject: [PATCH v11 3/5] dt-bindings: can: tcan4x5x: Add DT bindings for TCAN4x5X driver Date: Tue, 19 Mar 2019 12:26:49 -0500 Message-ID: <20190319172651.10012-3-dmurphy@ti.com> X-Mailer: git-send-email 2.12.2 In-Reply-To: <20190319172651.10012-1-dmurphy@ti.com> References: <20190319172651.10012-1-dmurphy@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org DT binding documentation for TI TCAN4x5x driver. Signed-off-by: Dan Murphy --- v11 - No changes - https://lore.kernel.org/patchwork/patch/1051178/ v10 - No changes - https://lore.kernel.org/patchwork/patch/1050488/ v9 - No Changes - https://lore.kernel.org/patchwork/patch/1050118/ v8 - No Changes - https://lore.kernel.org/patchwork/patch/1047981/ v7 - Made device state optional - https://lore.kernel.org/patchwork/patch/1047218/ v6 - No changes - https://lore.kernel.org/patchwork/patch/1042445/ .../devicetree/bindings/net/can/tcan4x5x.txt | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 Documentation/devicetree/bindings/net/can/tcan4x5x.txt -- 2.20.1.390.gb5101f9297 diff --git a/Documentation/devicetree/bindings/net/can/tcan4x5x.txt b/Documentation/devicetree/bindings/net/can/tcan4x5x.txt new file mode 100644 index 000000000000..c388f7d9feb1 --- /dev/null +++ b/Documentation/devicetree/bindings/net/can/tcan4x5x.txt @@ -0,0 +1,37 @@ +Texas Instruments TCAN4x5x CAN Controller +================================================ + +This file provides device node information for the TCAN4x5x interface contains. + +Required properties: + - compatible: "ti,tcan4x5x" + - reg: 0 + - #address-cells: 1 + - #size-cells: 0 + - spi-max-frequency: Maximum frequency of the SPI bus the chip can + operate at should be less than or equal to 18 MHz. + - data-ready-gpios: Interrupt GPIO for data and error reporting. + - device-wake-gpios: Wake up GPIO to wake up the TCAN device. + +See Documentation/devicetree/bindings/net/can/m_can.txt for additional +required property details. + +Optional properties: + - reset-gpios: Hardwired output GPIO. If not defined then software + reset. + - device-state-gpios: Input GPIO that indicates if the device is in + a sleep state or if the device is active. + +Example: +tcan4x5x: tcan4x5x@0 { + compatible = "ti,tcan4x5x"; + reg = <0>; + #address-cells = <1>; + #size-cells = <1>; + spi-max-frequency = <10000000>; + bosch,mram-cfg = <0x0 0 0 32 0 0 1 1>; + data-ready-gpios = <&gpio1 14 GPIO_ACTIVE_LOW>; + device-state-gpios = <&gpio3 21 GPIO_ACTIVE_HIGH>; + device-wake-gpios = <&gpio1 15 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio1 27 GPIO_ACTIVE_LOW>; +}; From patchwork Tue Mar 19 17:26:51 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dan Murphy X-Patchwork-Id: 160600 Delivered-To: patch@linaro.org Received: by 2002:a02:5cc1:0:0:0:0:0 with SMTP id w62csp4139909jad; Tue, 19 Mar 2019 10:28:00 -0700 (PDT) X-Google-Smtp-Source: APXvYqydLAQC4TyDI3DvtN0nsEGReVXY4soulWP4mbYoavaeEsbZ5RVskNMSu8rFMi0ZzMubFMFi X-Received: by 2002:a65:654d:: with SMTP id a13mr24480251pgw.181.1553016480045; Tue, 19 Mar 2019 10:28:00 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1553016480; cv=none; d=google.com; s=arc-20160816; b=Ti3IxaXEwGCXKxnCzJrwgW6a47VPAFZ5UQGEMnM9pFvm+xOfN6V+MZQprKk8H0pGxU aB6D1zvtuTEGLjo/lRsdBNBTgnCQhUnd2dJw6kL2zsW/M1xbgyku26WJcxU965NPlfDh beIrX8zpPN3OOTTm7zRbrpfPa4BDgu/d4kI/nGPBBhT7EyrGWF1W8Bp524eHS+ZlhWU3 o1tT9kb1uTm54kFI1gHS6sgHLFxHpY4KWWALAc90msCbm1QR0y2uiQrLs37Pa/AOeY7f h4qI81yMoPGvGmMU2DQlnb/eEJ5sK0INfUWnej8kypMWs+1bqoeuZC8fAqyvt/nITUvU acYw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=/eXXnbyeXFctQ7VxAcrpv2Z0MSDXtIQMGy69zq2cvxc=; b=C9QU6nk8PETZOWOu+WOfrjPWZZiYkO5ubzbxx2lbSOm5C2F8zDin2XdUQp1QzRB0H4 zNrUGloOPG2k5uOj2419QdinavtHx7g+90az9uqlC17qbyf/+E4HooBXhHifU6gGBGo1 B4HssJAjx/gLhdtKBEn2gDAZT2hNIxCq0zmIy1T+zLt+2n2U7IRvY8dbkKZJQL9t9r+U WD3wOzt2ScFYt+mPDORMfcNf+Ox0hHgCs+izPCuZRf+YlM0YBebXdAmJXuJdxTjCWLOO iLRnmVOoC9G1RCSwHYKElg3kL47GacQK0sItfRZIHvNjSrsMulULTsJ4qNp9kSN9zrPs E2kg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=rXV8vIqM; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 1si12408894ply.232.2019.03.19.10.27.59; Tue, 19 Mar 2019 10:28:00 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=rXV8vIqM; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727416AbfCSR1Y (ORCPT + 31 others); Tue, 19 Mar 2019 13:27:24 -0400 Received: from fllv0016.ext.ti.com ([198.47.19.142]:42110 "EHLO fllv0016.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726776AbfCSR1X (ORCPT ); Tue, 19 Mar 2019 13:27:23 -0400 Received: from lelv0265.itg.ti.com ([10.180.67.224]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id x2JHRHBh030867; Tue, 19 Mar 2019 12:27:17 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1553016437; bh=/eXXnbyeXFctQ7VxAcrpv2Z0MSDXtIQMGy69zq2cvxc=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=rXV8vIqMgyILN2ZlNYEzWfg4eNqywgHoybwA80lhoO5rOQyGvEdBmWRjMUE6HiCRR zSwD3Ec+trrqcMe2sEmfiv5Qdc8QMtQeu686UUdkJ0HD8HOtZqi5Wf86v1INf+Yr6I 2dPgLu08ad0UQ/oOiQWwriW62kl3eXrNvdlD4w8Q= Received: from DLEE110.ent.ti.com (dlee110.ent.ti.com [157.170.170.21]) by lelv0265.itg.ti.com (8.15.2/8.15.2) with ESMTPS id x2JHRHHk080028 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 19 Mar 2019 12:27:17 -0500 Received: from DLEE100.ent.ti.com (157.170.170.30) by DLEE110.ent.ti.com (157.170.170.21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1713.5; Tue, 19 Mar 2019 12:27:16 -0500 Received: from dflp32.itg.ti.com (10.64.6.15) by DLEE100.ent.ti.com (157.170.170.30) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.1713.5 via Frontend Transport; Tue, 19 Mar 2019 12:27:16 -0500 Received: from localhost (ileax41-snat.itg.ti.com [10.172.224.153]) by dflp32.itg.ti.com (8.14.3/8.13.8) with ESMTP id x2JHRG4i008318; Tue, 19 Mar 2019 12:27:16 -0500 From: Dan Murphy To: , , CC: , , , Dan Murphy Subject: [PATCH v11 5/5] can: m_can: Fix checkpatch issues on existing code Date: Tue, 19 Mar 2019 12:26:51 -0500 Message-ID: <20190319172651.10012-5-dmurphy@ti.com> X-Mailer: git-send-email 2.12.2 In-Reply-To: <20190319172651.10012-1-dmurphy@ti.com> References: <20190319172651.10012-1-dmurphy@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Fix checkpatch issues found during the m_can framework creation. The code the issues were in, was in untouched code and these changes should be done separately as to not be confused with the framework changes. Fix these 3 check issues: CHECK: Unnecessary parentheses around 'cdev->can.state != CAN_STATE_ERROR_WARNING' if (psr & PSR_EW && (cdev->can.state != CAN_STATE_ERROR_WARNING)) { CHECK: Unnecessary parentheses around 'cdev->can.state != CAN_STATE_ERROR_PASSIVE' if ((psr & PSR_EP) && (cdev->can.state != CAN_STATE_ERROR_PASSIVE)) { CHECK: Unnecessary parentheses around 'cdev->can.state != CAN_STATE_BUS_OFF' if ((psr & PSR_BO) && (cdev->can.state != CAN_STATE_BUS_OFF)) { Signed-off-by: Dan Murphy --- v11 - New change to clean up last remaining checkpatch issues on original code. drivers/net/can/m_can/m_can.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) -- 2.20.1.390.gb5101f9297 diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c index 0759c61a7e5a..1245da6f79ff 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c @@ -750,22 +750,19 @@ static int m_can_handle_state_errors(struct net_device *dev, u32 psr) struct m_can_classdev *cdev = netdev_priv(dev); int work_done = 0; - if ((psr & PSR_EW) && - (cdev->can.state != CAN_STATE_ERROR_WARNING)) { + if (psr & PSR_EW && cdev->can.state != CAN_STATE_ERROR_WARNING) { netdev_dbg(dev, "entered error warning state\n"); work_done += m_can_handle_state_change(dev, CAN_STATE_ERROR_WARNING); } - if ((psr & PSR_EP) && - (cdev->can.state != CAN_STATE_ERROR_PASSIVE)) { + if (psr & PSR_EP && cdev->can.state != CAN_STATE_ERROR_PASSIVE) { netdev_dbg(dev, "entered error passive state\n"); work_done += m_can_handle_state_change(dev, CAN_STATE_ERROR_PASSIVE); } - if ((psr & PSR_BO) && - (cdev->can.state != CAN_STATE_BUS_OFF)) { + if (psr & PSR_BO && cdev->can.state != CAN_STATE_BUS_OFF) { netdev_dbg(dev, "entered error bus off state\n"); work_done += m_can_handle_state_change(dev, CAN_STATE_BUS_OFF);