From patchwork Wed Aug 17 14:35:26 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dario Binacchi X-Patchwork-Id: 2299 Return-Path: X-Original-To: linux-amarula@patchwork.amarulasolutions.com Delivered-To: linux-amarula@patchwork.amarulasolutions.com Received: from mail-ed1-f72.google.com (mail-ed1-f72.google.com [209.85.208.72]) by ganimede.amarulasolutions.com (Postfix) with ESMTPS id 7D2633F03E for ; Wed, 17 Aug 2022 16:36:31 +0200 (CEST) Received: by mail-ed1-f72.google.com with SMTP id t13-20020a056402524d00b0043db1fbefdesf8829268edd.2 for ; Wed, 17 Aug 2022 07:36:31 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1660746991; cv=pass; d=google.com; s=arc-20160816; b=cEnkltpGYqMm8uSytYszm36Gy/lLU8LFzhIMWAB2YwDpiSsABBCCjAb4RqfZejwGSl UJFMnJb7R3AdtahX/DtZ9vPiQPBCkfmii1yL/gqOKRDdbAuXIlnvMmsFpHgWXEPfH8V2 wTv67iwTt/RfhIhlH5pNCm06nfknSmCgEc+1mbdlYNrEmfp24Rfy95wJtT+DhToolO8Q +P3pqHbEc9zBmX5Z+8nBfeIYRfgOCY3FIvz+Dxaioh5yhxxSJZm2qLkPxDssmAscza0M bHe2lp/J3QEUIloLAvO/uCjW8ZAtb/SzBwiFGWIQheWZgeMkxNjetFpNrILN8bxfY26M Nllw== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-unsubscribe:list-archive:list-help:list-post:list-id :mailing-list:precedence:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=yjxj7wdJ/W8/hSqbd9bf9zTvrvREkfFcwRVZNS73hbI=; b=F0fYv73PhQ7tsFXUTBegDDB/lyPHd6eXiILPdKpAXeTK55h5Ozll1QyWC4ZdsmblaK Ya/D2uPK9anl0quiWudhdkLjNmErEHeqOj74voh0G5zPAf6/er0+DFztDPCm6M/5Zukn LysG1EBeUF4IZES7kwvKM/0Z/KGDdgpqRj4roNwuCobIgnL69OTNNSedQOpp6oFI0fZ5 GBwe/32/7rgPvm/J+9Oq2yirjZLF04ChpplY6OpTOdoQbuayLA7oqfjEzgD1RQVSlPSR yx4dBoG//hHILXR+4UTWW8/Zmc1JsBtiZCHr1ubfxdorrR0qvaB0RNampQKe6n7y/Ibw WEGA== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b=f1d9zEDh; spf=pass (google.com: domain of dario.binacchi@amarulasolutions.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=dario.binacchi@amarulasolutions.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=amarulasolutions.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amarulasolutions.com; s=google; h=list-unsubscribe:list-archive:list-help:list-post:list-id :mailing-list:precedence:x-original-authentication-results :x-original-sender:mime-version:references:in-reply-to:message-id :date:subject:cc:to:from:from:to:cc; bh=yjxj7wdJ/W8/hSqbd9bf9zTvrvREkfFcwRVZNS73hbI=; b=XBg6pqYPBO/eOI+RdJ5PutqMqpG7VA2lTmwAy1zXUcwK0OwV8BdxvJfr6sAJ9YVw66 gHpsxeDbFjdrNggH4Twd/m7jyorXBYQjC78krSUD1h+bNmxSK/zqNWZDCslQkOUvMjZV Ev7NLgLdskeRWsvybfW3k+U57TyGNWYtOpZkk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=list-unsubscribe:list-archive:list-help:list-post :x-spam-checked-in-group:list-id:mailing-list:precedence :x-original-authentication-results:x-original-sender:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :x-gm-message-state:from:to:cc; bh=yjxj7wdJ/W8/hSqbd9bf9zTvrvREkfFcwRVZNS73hbI=; b=zgwuJOyueMwY0V04k24KhMztD9k294gr1r3czqECnmgSVvG/w7J4sXA2piCPdjeMFr KZr9NQmiy1XbjWibB6T1Lx+Tr2w4hOV642js4X7U5TPDyXkvcqFJ0DO0DceemcgFoajT WfHDAoUNicBzCIpsUDqGc1FFMkcCY5cDLMbsl5XaM9jEl/I34WwzDV3F+3HYESxwy4DB h5k/Xijiu9CXiD2QTauZiKt2BayleqoRl6l8x67f4xOaAOV6yaDadH00VM3cnYrV+j2O kwDgnQ+xMdYjuSMmhy0yAWYSXY0/1qSiBT72yMyHF4DvxxCU8tFTV3ap06hrXpQfu12c pyTg== X-Gm-Message-State: ACgBeo03kXbu/bGQra+Bqwbn/DRirhkj7tEj9kkbo+kYKO9QOVSsTUdk WE34A2ztXfDU/k98bT6TmZRrEmfV X-Google-Smtp-Source: AA6agR5Tvx6eAom1BxQRggeNVEn+bAADJa5/ZuO0QHIV9O7GQZA7bqChAu57AWj1hQsvljDqXfkArw== X-Received: by 2002:a17:907:7d86:b0:730:cd48:e2bc with SMTP id oz6-20020a1709077d8600b00730cd48e2bcmr16981901ejc.167.1660746991035; Wed, 17 Aug 2022 07:36:31 -0700 (PDT) X-BeenThere: linux-amarula@amarulasolutions.com Received: by 2002:a17:906:3f91:b0:726:abf9:5f2e with SMTP id b17-20020a1709063f9100b00726abf95f2els6074886ejj.9.-pod-prod-gmail; Wed, 17 Aug 2022 07:36:30 -0700 (PDT) X-Received: by 2002:a17:907:b0d:b0:730:aa17:a0b7 with SMTP id h13-20020a1709070b0d00b00730aa17a0b7mr16844429ejl.661.1660746989801; Wed, 17 Aug 2022 07:36:29 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1660746989; cv=none; d=google.com; s=arc-20160816; b=edjzvUQIWkyAYF2vWXrRC3OY3D8KNk2yORGThaJRPENl/078w/vnNWdfkBuQo4AIHV SyRlC2SvRelMKCFNU5JO1yAOOYzTyuZL1PfG1wp75pxvLZgPXSRjFe5T7JGZSTmkrPyZ 0bXsAqyR9m/raiAHsGtjSm9sdZMysB5plKNpidMN5ZcozfNcoOODUfhQaqS3N39qSstf Hw6HliLYKa/4+WkrzPtbQbek8heAt6iPFMbwrMl9Sq3i22x+yC4XoiKpW7lVvgDw/lvs dHWU/8gu8YkbR25FUCKDlzSwp7nWTykLHqGsjKcaSJpEL35CS//wdLltTMxW3DGysQsh 0DSg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=vUjsIUj0sjtjNDnJJ6/7r96WzwA0T1BZA3Wt0Kn9xQk=; b=EqT/9IFKS+mJ27iq66c7yBpg6C8UdYkNG2Aaa9Cp6F4sIoUdMo7Hsl5rQH6hXz5TGt n7zReSAsekliJQ66bgc5oAal4njTuanmCsmw4vs1xuqWyBd3vHfLsyZhIJ16s14VHPlW PGZp6Jh1Z/lFSFz9P1D0ErbieL0lb8VDcGLMCdUlnqrJKiZOCuRy1x1HRa/fIJdjisz9 FnASxv5veFkClJ7ozuUjl8BHMrUS8T8ZtunyHfb3/DlPSUVF5Pok+ra8c7Nn3Xkdx0LM S6PuMHHNk0nS/ubEOjQqYQmbAXzs74tWF1j/oxzLtsuJIpKgCowGSedS0+S0oVIdu3O6 GY/A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b=f1d9zEDh; spf=pass (google.com: domain of dario.binacchi@amarulasolutions.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=dario.binacchi@amarulasolutions.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=amarulasolutions.com Received: from mail-sor-f41.google.com (mail-sor-f41.google.com. [209.85.220.41]) by mx.google.com with SMTPS id yk15-20020a17090770cf00b0073841340cb3sor3698419ejb.111.2022.08.17.07.36.29 for (Google Transport Security); Wed, 17 Aug 2022 07:36:29 -0700 (PDT) Received-SPF: pass (google.com: domain of dario.binacchi@amarulasolutions.com designates 209.85.220.41 as permitted sender) client-ip=209.85.220.41; X-Received: by 2002:a17:907:2721:b0:731:2aeb:7940 with SMTP id d1-20020a170907272100b007312aeb7940mr17579840ejl.448.1660746989538; Wed, 17 Aug 2022 07:36:29 -0700 (PDT) Received: from dario-ThinkPad-T14s-Gen-2i.homenet.telecomitalia.it (host-79-31-31-9.retail.telecomitalia.it. [79.31.31.9]) by smtp.gmail.com with ESMTPSA id o9-20020aa7c7c9000000b0043cab10f702sm10711982eds.90.2022.08.17.07.36.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Aug 2022 07:36:29 -0700 (PDT) From: Dario Binacchi To: linux-kernel@vger.kernel.org Cc: Alexandre Torgue , Amarula patchwork , michael@amarulasolutions.com, Marc Kleine-Budde , Dario Binacchi , Dario Binacchi , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Krzysztof Kozlowski , Paolo Abeni , Rob Herring , Wolfgang Grandegger , devicetree@vger.kernel.org, linux-can@vger.kernel.org, netdev@vger.kernel.org Subject: [RFC PATCH 1/4] dt-bindings: net: can: add STM32 bxcan DT bindings Date: Wed, 17 Aug 2022 16:35:26 +0200 Message-Id: <20220817143529.257908-2-dario.binacchi@amarulasolutions.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220817143529.257908-1-dario.binacchi@amarulasolutions.com> References: <20220817143529.257908-1-dario.binacchi@amarulasolutions.com> MIME-Version: 1.0 X-Original-Sender: dario.binacchi@amarulasolutions.com X-Original-Authentication-Results: mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b=f1d9zEDh; spf=pass (google.com: domain of dario.binacchi@amarulasolutions.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=dario.binacchi@amarulasolutions.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=amarulasolutions.com Content-Type: text/plain; charset="UTF-8" Precedence: list Mailing-list: list linux-amarula@amarulasolutions.com; contact linux-amarula+owners@amarulasolutions.com List-ID: X-Spam-Checked-In-Group: linux-amarula@amarulasolutions.com X-Google-Group-Id: 476853432473 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , Add documentation of device tree bindings for the STM32 basic extended CAN (bxcan) controller. Signed-off-by: Dario Binacchi Signed-off-by: Dario Binacchi --- .../devicetree/bindings/net/can/st,bxcan.yaml | 139 ++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 Documentation/devicetree/bindings/net/can/st,bxcan.yaml diff --git a/Documentation/devicetree/bindings/net/can/st,bxcan.yaml b/Documentation/devicetree/bindings/net/can/st,bxcan.yaml new file mode 100644 index 000000000000..f4cfd26e4785 --- /dev/null +++ b/Documentation/devicetree/bindings/net/can/st,bxcan.yaml @@ -0,0 +1,139 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/net/can/st,bxcan.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: STMicroelectronics bxCAN controller Device Tree Bindings + +description: STMicroelectronics BxCAN controller for CAN bus + +maintainers: + - Dario Binacchi + +allOf: + - $ref: can-controller.yaml# + +properties: + compatible: + enum: + - st,stm32-bxcan-core + + reg: + maxItems: 1 + + resets: + maxItems: 1 + + clocks: + description: + Input clock for registers access + maxItems: 1 + + '#address-cells': + const: 1 + + '#size-cells': + const: 0 + +required: + - compatible + - reg + - resets + - clocks + - '#address-cells' + - '#size-cells' + +additionalProperties: false + +patternProperties: + "^can@[0-9]+$": + type: object + description: + A CAN block node contains two subnodes, representing each one a CAN + instance available on the machine. + + properties: + compatible: + enum: + - st,stm32-bxcan + + master: + description: + Master and slave mode of the bxCAN peripheral is only relevant + if the chip has two CAN peripherals. In that case they share + some of the required logic, and that means you cannot use the + slave CAN without the master CAN. + type: boolean + + reg: + description: | + Offset of CAN instance in CAN block. Valid values are: + - 0x0: CAN1 + - 0x400: CAN2 + maxItems: 1 + + interrupts: + items: + - description: transmit interrupt + - description: FIFO 0 receive interrupt + - description: FIFO 1 receive interrupt + - description: status change error interrupt + + interrupt-names: + items: + - const: tx + - const: rx0 + - const: rx1 + - const: sce + + resets: + maxItems: 1 + + clocks: + description: + Input clock for registers access + maxItems: 1 + + additionalProperties: false + + required: + - compatible + - reg + - interrupts + - resets + +examples: + - | + #include + #include + + can: can@40006400 { + compatible = "st,stm32-bxcan-core"; + reg = <0x40006400 0x800>; + resets = <&rcc STM32F4_APB1_RESET(CAN1)>; + clocks = <&rcc 0 STM32F4_APB1_CLOCK(CAN1)>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + can1: can@0 { + compatible = "st,stm32-bxcan"; + reg = <0x0>; + interrupts = <19>, <20>, <21>, <22>; + interrupt-names = "tx", "rx0", "rx1", "sce"; + resets = <&rcc STM32F4_APB1_RESET(CAN1)>; + master; + status = "disabled"; + }; + + can2: can@400 { + compatible = "st,stm32-bxcan"; + reg = <0x400>; + interrupts = <63>, <64>, <65>, <66>; + interrupt-names = "tx", "rx0", "rx1", "sce"; + resets = <&rcc STM32F4_APB1_RESET(CAN2)>; + clocks = <&rcc 0 STM32F4_APB1_CLOCK(CAN2)>; + status = "disabled"; + }; + }; From patchwork Wed Aug 17 14:35:27 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dario Binacchi X-Patchwork-Id: 2300 Return-Path: X-Original-To: linux-amarula@patchwork.amarulasolutions.com Delivered-To: linux-amarula@patchwork.amarulasolutions.com Received: from mail-ed1-f71.google.com (mail-ed1-f71.google.com [209.85.208.71]) by ganimede.amarulasolutions.com (Postfix) with ESMTPS id DC9213F03E for ; Wed, 17 Aug 2022 16:36:38 +0200 (CEST) Received: by mail-ed1-f71.google.com with SMTP id y14-20020a056402440e00b0044301c7ccd9sf8851766eda.19 for ; Wed, 17 Aug 2022 07:36:38 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1660746998; cv=pass; d=google.com; s=arc-20160816; b=j1MvSPixRyqfutfQSBOLml9Vn+8ULfD7WkgkV2haWu6dVOny+nNB3XN1cIIxGjpeYB Wt6sfQdKRacPwlQ+a11RW6hrzEkD61Y7s7JR73cbsi2v7jsjT19HKOWuv32p9eYj5zba 7SDQpkDTNw7xIfdvbdYUSc6VLlsWN22mq1oLyI+WbdpmMYcs6v1xQTOL7i59GgeNtVKE 5tZCCFm/m4u0BiFgpzrJhC3RTaYx1JdukgpGSDb48L0OnUGu+xpJN4AmrXBTZtacMLEq 0BqpOc1M/Jnb1jPh+QmUwcRykydUE/0TE+4RAQhw56s2R8q/tjR0TJmRo7fvkB7mA8a3 VdLQ== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-unsubscribe:list-archive:list-help:list-post:list-id :mailing-list:precedence:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=r7Xf/8kx30ehIDnWRLEQxHSawnXLWq+dbWHmCFHjKEI=; b=jzWZna3nNKCu1Blqp58AcH+uewumMzQzaDeT52X2wIkg4FQDuuRqdBD5zU5lDPPk/j 7LjDLnqL/rcnKFBaWpqi0OyOaZ8o3TDDFMouqdfQtc820AExlaTGH2C5Q4XMVh8IfCi6 bPqbUsuFlVhjtADuHob3GA59bAyCTXWeBXZTDSVfQrtIv4wM/foByha61J4PPZXRMouo tPNmGvvGgahYo+7gKbSDZD743sSUrm/jHj+sF/3cs8O9GyRBhMhOfxrb4Mf6PdJBx8e9 m30iO/X8/aPUYjXGY83XYxbAI1zHLHrSq2GXxVWiCwdAm5kbErnyWpOEIBhO/YeulISb 6lWQ== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b=kNgAFIpe; spf=pass (google.com: domain of dario.binacchi@amarulasolutions.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=dario.binacchi@amarulasolutions.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=amarulasolutions.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amarulasolutions.com; s=google; h=list-unsubscribe:list-archive:list-help:list-post:list-id :mailing-list:precedence:x-original-authentication-results :x-original-sender:mime-version:references:in-reply-to:message-id :date:subject:cc:to:from:from:to:cc; bh=r7Xf/8kx30ehIDnWRLEQxHSawnXLWq+dbWHmCFHjKEI=; b=QoiGkRdza97hmttaIOYaAsINNWwqN+BX7TrkV1JbUlFle0Rb+NHN28bYZHdMPDmML2 TEOtxgF+IUrvIj3IaFC8UKndShYvBX1CfL+9umrDenmpAauOHcLBHKjvGvug2fA5ZBla hYMn8Hh8kSnhVZvBN5Zew0YAxVdxAPGy08baA= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=list-unsubscribe:list-archive:list-help:list-post :x-spam-checked-in-group:list-id:mailing-list:precedence :x-original-authentication-results:x-original-sender:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :x-gm-message-state:from:to:cc; bh=r7Xf/8kx30ehIDnWRLEQxHSawnXLWq+dbWHmCFHjKEI=; b=ZgclXKVFUeOCEe2zHP+0cJnCuwwJBgCstRzuxsl/R9GQw4kXl6GCYf7faYdmNxLjN1 nlODh5PFMRNZF2HdIFfHGZDSlk/mK7u5n+9sy+f1HVehJph0jYi7TeUYYIvHlVY0+Ul1 iYSLWXUgcNIy2TreoHTfodlGc/WFBMS1LeaqokEkls1DzTpf9GAkUT6nDrOVV4dlTac/ 6q8efX8gRKYqYZ/83Ui85/dJ1SX1OJ2Tpd67XfG8+nbU45tiSeCocLCIVU6M++LRAhtn xfcXZa2TgY374FoLm+ZJWJK1WVONa7TIiAJqwvbv6xmr56T9SmhBWpcXGpzxFm34VcRD AapQ== X-Gm-Message-State: ACgBeo20C3LHQ44U8xNaWkCIidjgBX1ipRmuajhyc1qQ8Gg0+xiXOtBU 3vEBvehVmIw8OKfq5pf1k8s4a2xp X-Google-Smtp-Source: AA6agR56LKMqa7y2EcLLUEpxnwWVyLkt7abrnyVWu5aEz1aBNSsG3Pm5vhxrCGi4Zg4MpSZVGH6waA== X-Received: by 2002:a17:907:3e86:b0:6f5:917:10cc with SMTP id hs6-20020a1709073e8600b006f5091710ccmr17214292ejc.53.1660746998508; Wed, 17 Aug 2022 07:36:38 -0700 (PDT) X-BeenThere: linux-amarula@amarulasolutions.com Received: by 2002:a05:6402:27ce:b0:43d:2444:3c5c with SMTP id c14-20020a05640227ce00b0043d24443c5cls2339010ede.0.-pod-prod-gmail; Wed, 17 Aug 2022 07:36:37 -0700 (PDT) X-Received: by 2002:a05:6402:4515:b0:443:7833:3d7b with SMTP id ez21-20020a056402451500b0044378333d7bmr17263521edb.151.1660746997400; Wed, 17 Aug 2022 07:36:37 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1660746997; cv=none; d=google.com; s=arc-20160816; b=JgTybLjFPLRaw4TaAP97XEH/T8qQY9NrqF+IFJGfXev1syUDbp1DV9QDxaoTlDxNRG iJWoPjL5FDZCrZVgEOFZr/5A+esbPp2l+AW5/EtpelqozcxcKny/ewsH5pyiR3yzBpyB HltNdYQqt8f1qO/RkStn6lngHoJujP+0wVlu1j9Y0JX9tftQ6/KInfOtN7W0W912KTnR 4SoBXMFZ24DTNhI/FnDFtaDXpK2DQTiD0RbCkjm1h1EjTW5JYsgUQi1rob+VK7g6T0KO 9UhOx/MXM/Jzw4OisSGepci58vRV/1UFW21/FRrYkFUAs/5NE3TKly9iXicri7xAyxzC cLhw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=44iy7ssOSOFDHgG+aTzhL/TF56VP+7fbMIq0O0tw95M=; b=uYInuLwhlcwANUyeYC3cPKYm0AuqpKEibutF4uno5XVl5u2Aq78c+fgHGFe7TttuOr lPjLyDUN6LaDFN3f88P3B3A8ereVNX4/qXDLTT4GLKDUs/Lw7/FvKYYKAiDwYJb/FFKX kmzxVTQgzGJt6hi1VL7i0U8dIdBOPmWbnHcXaCGmpAYbRu07oAcJs6Ol3kd8lGscxM/G 80eGJ6Q6odJ5mGYqhdVOFnfuDh/KqVLz76VUp509M2Nthr2ySRgJHI0CRUVWcUe2Upte SbWKItFIptgBNb6LSWgpbyXjn+wGITTp2ySCH+STs83WArh4ekp2m9S1GyI9kKnrMqVO colw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b=kNgAFIpe; spf=pass (google.com: domain of dario.binacchi@amarulasolutions.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=dario.binacchi@amarulasolutions.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=amarulasolutions.com Received: from mail-sor-f41.google.com (mail-sor-f41.google.com. [209.85.220.41]) by mx.google.com with SMTPS id n1-20020a05640205c100b0043bb71e93fbsor7262475edx.41.2022.08.17.07.36.37 for (Google Transport Security); Wed, 17 Aug 2022 07:36:37 -0700 (PDT) Received-SPF: pass (google.com: domain of dario.binacchi@amarulasolutions.com designates 209.85.220.41 as permitted sender) client-ip=209.85.220.41; X-Received: by 2002:a05:6402:10d2:b0:445:d9ee:fc19 with SMTP id p18-20020a05640210d200b00445d9eefc19mr2920832edu.81.1660746997217; Wed, 17 Aug 2022 07:36:37 -0700 (PDT) Received: from dario-ThinkPad-T14s-Gen-2i.homenet.telecomitalia.it (host-79-31-31-9.retail.telecomitalia.it. [79.31.31.9]) by smtp.gmail.com with ESMTPSA id o9-20020aa7c7c9000000b0043cab10f702sm10711982eds.90.2022.08.17.07.36.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Aug 2022 07:36:36 -0700 (PDT) From: Dario Binacchi To: linux-kernel@vger.kernel.org Cc: Alexandre Torgue , Amarula patchwork , michael@amarulasolutions.com, Marc Kleine-Budde , Dario Binacchi , Dario Binacchi , Krzysztof Kozlowski , Maxime Coquelin , Rob Herring , devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-stm32@st-md-mailman.stormreply.com Subject: [RFC PATCH 2/4] ARM: dts: stm32: add CAN support on stm32f429 Date: Wed, 17 Aug 2022 16:35:27 +0200 Message-Id: <20220817143529.257908-3-dario.binacchi@amarulasolutions.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220817143529.257908-1-dario.binacchi@amarulasolutions.com> References: <20220817143529.257908-1-dario.binacchi@amarulasolutions.com> MIME-Version: 1.0 X-Original-Sender: dario.binacchi@amarulasolutions.com X-Original-Authentication-Results: mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b=kNgAFIpe; spf=pass (google.com: domain of dario.binacchi@amarulasolutions.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=dario.binacchi@amarulasolutions.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=amarulasolutions.com Content-Type: text/plain; charset="UTF-8" Precedence: list Mailing-list: list linux-amarula@amarulasolutions.com; contact linux-amarula+owners@amarulasolutions.com List-ID: X-Spam-Checked-In-Group: linux-amarula@amarulasolutions.com X-Google-Group-Id: 476853432473 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , Add support for bxcan (Basic eXtended CAN controller) to STM32F429. The chip contains two CAN peripherals, CAN1 the master and CAN2 the slave, that share some of the required logic like clock and filters. This means that the slave CAN can't be used without the master CAN. Signed-off-by: Dario Binacchi Signed-off-by: Dario Binacchi --- arch/arm/boot/dts/stm32f429.dtsi | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/arch/arm/boot/dts/stm32f429.dtsi b/arch/arm/boot/dts/stm32f429.dtsi index c31ceb821231..28db387ad5e8 100644 --- a/arch/arm/boot/dts/stm32f429.dtsi +++ b/arch/arm/boot/dts/stm32f429.dtsi @@ -362,6 +362,36 @@ i2c3: i2c@40005c00 { status = "disabled"; }; + can: can@40006400 { + compatible = "st,stm32-bxcan-core"; + reg = <0x40006400 0x800>; + resets = <&rcc STM32F4_APB1_RESET(CAN1)>; + clocks = <&rcc 0 STM32F4_APB1_CLOCK(CAN1)>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + can1: can@0 { + compatible = "st,stm32-bxcan"; + reg = <0x0>; + interrupts = <19>, <20>, <21>, <22>; + interrupt-names = "tx", "rx0", "rx1", "sce"; + resets = <&rcc STM32F4_APB1_RESET(CAN1)>; + master; + status = "disabled"; + }; + + can2: can@400 { + compatible = "st,stm32-bxcan"; + reg = <0x400>; + interrupts = <63>, <64>, <65>, <66>; + interrupt-names = "tx", "rx0", "rx1", "sce"; + resets = <&rcc STM32F4_APB1_RESET(CAN2)>; + clocks = <&rcc 0 STM32F4_APB1_CLOCK(CAN2)>; + status = "disabled"; + }; + }; + dac: dac@40007400 { compatible = "st,stm32f4-dac-core"; reg = <0x40007400 0x400>; From patchwork Wed Aug 17 14:35:28 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dario Binacchi X-Patchwork-Id: 2301 Return-Path: X-Original-To: linux-amarula@patchwork.amarulasolutions.com Delivered-To: linux-amarula@patchwork.amarulasolutions.com Received: from mail-ej1-f72.google.com (mail-ej1-f72.google.com [209.85.218.72]) by ganimede.amarulasolutions.com (Postfix) with ESMTPS id A20943F03E for ; Wed, 17 Aug 2022 16:36:46 +0200 (CEST) Received: by mail-ej1-f72.google.com with SMTP id sc31-20020a1709078a1f00b0073096c2b4e1sf3085454ejc.22 for ; Wed, 17 Aug 2022 07:36:46 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1660747006; cv=pass; d=google.com; s=arc-20160816; b=WK8pxu8WohP62GllvN3RTGdgxXqjdMSyZlQFZoXvvdwDjQ4TY+3f4kImtVxwx0Dc+e nTUHNztG/zuNpKFIvibGEEWYE1W1sthgZrjYlSd5u2i6/BLvR/WUJdNB48vvr6WQbZoO lrMm9pOMyb1TSt3M0FjvX9SbufFebS/uXe+pnmu2N8SALO/jTI0Om5jVBTtdaWX5T3OY 8yFD50CkR91mW0H5PiIJRVSlzlzMrXF9m+5ELWPHLJc2oC/IKPKpo2TZUNYvJX8wcYFi Bs+V7iAImVnBVnPy6qtI+TVt7murQSKnZhuHVdJz/lY33YKF87pcDGXOwta1G39q8Blv OEfw== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-unsubscribe:list-archive:list-help:list-post:list-id :mailing-list:precedence:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=hg/3tGe1gOzdtNw3sFAxJf+/WMG14fGM4bCbEHynxmA=; b=z9WynlallWZhCjf8+WLkjW24c+5nmf/uuVfWt05JHbJ8NrW/K/BbyjxIGluJwvPc1h WXvFjbm3k99sIZptM4Xl3XZeOkRA6BzaZ6NFTv6T0zsbraBkL+P7mkNi+AqJJZhGtuhW Y9yO/liLp9cgA4fDhsC+LdFdyXBLaERxny9pGBzawK8DX9SNF/9AxTfTYyAdsqAVMUXp xSybY1KQkx4K8MMVGVtDcvgHU0l74NWL4SGOJHQodj5lUw9Qjpxe050gZn3Bk/QPPZ/y VM6A7YYwdhRvSslN1sTW0C7N0+6W+icWhbLp9icniihzHqG1AiF97abUzNYaqP0AW5s/ gpRw== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b="LkqmS/nu"; spf=pass (google.com: domain of dario.binacchi@amarulasolutions.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=dario.binacchi@amarulasolutions.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=amarulasolutions.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amarulasolutions.com; s=google; h=list-unsubscribe:list-archive:list-help:list-post:list-id :mailing-list:precedence:x-original-authentication-results :x-original-sender:mime-version:references:in-reply-to:message-id :date:subject:cc:to:from:from:to:cc; bh=hg/3tGe1gOzdtNw3sFAxJf+/WMG14fGM4bCbEHynxmA=; b=Q14/L/h9vSEtCGDgfZbLBA0bEsXf8fdyUuP3GsI6DRwRTe6/FT5vl8CmHnjCW/TYAh GraO7Yxi2IZ0d8UhAgTr/owgbZHji4c3lluolW5x7JOTsVFTaQkZ+nkz6kiLlPn9WpfU 9m2JOGsC4u2mTcMJ7ZQuEIvXoDo4crERBE7BU= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=list-unsubscribe:list-archive:list-help:list-post :x-spam-checked-in-group:list-id:mailing-list:precedence :x-original-authentication-results:x-original-sender:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :x-gm-message-state:from:to:cc; bh=hg/3tGe1gOzdtNw3sFAxJf+/WMG14fGM4bCbEHynxmA=; b=BcxkKrDuutolKbm6a90WDJgdAMF5160hoHcaW64ikywODSmBjhlR3O2Uhwn/XA4+iZ bTb7zqxrxDwpd/WyEkiUiJaZbf+sYLQi8Qta56K/5BzPH0+2jShNuvMEFh/5Up5HcbvC RnGGgJoWafev1tY15AIIucG5ZgChju5WLVWn9+Y5mDpq2C7yUu1TPEYaZvVa4MYevPaf Dh08W7RaNgTIJOx1qjvWZlbumnzNQNz5LCvHMYV63nCPYaGP2c/8Ki0QarUJ7P4w/cLN XjUYVxrLZ2GFyhMCqjt/Kj+d4fz8Gglt/w6znHh97PjIzUQzaONFEHZ2G6bOh5j0ntuh ENLw== X-Gm-Message-State: ACgBeo2aAJfr6VAwceyepnScr0QeHp35vlZkB4J3fIa5bEdMtsxwg+NO Y92IjqoO6tOUefxMwWlbzdJAcZOi X-Google-Smtp-Source: AA6agR7vWf6sLOkjqMfJ8rZl95Z6SEmZDs8dELwGatJpehZu/6ASOZBD/mtotEwloP+uVzcIIsZUcw== X-Received: by 2002:a17:907:72d1:b0:730:a0c4:2aaa with SMTP id du17-20020a17090772d100b00730a0c42aaamr16532642ejc.560.1660747006326; Wed, 17 Aug 2022 07:36:46 -0700 (PDT) X-BeenThere: linux-amarula@amarulasolutions.com Received: by 2002:a17:906:612:b0:6fe:b664:4b5f with SMTP id s18-20020a170906061200b006feb6644b5fls6074521ejb.2.-pod-prod-gmail; Wed, 17 Aug 2022 07:36:45 -0700 (PDT) X-Received: by 2002:a17:907:3f2a:b0:730:ec00:1b19 with SMTP id hq42-20020a1709073f2a00b00730ec001b19mr17416696ejc.722.1660747005117; Wed, 17 Aug 2022 07:36:45 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1660747005; cv=none; d=google.com; s=arc-20160816; b=CYy0h2j3+Qif63mmjyY78bL/NlH0pdAtP+ofmOZgX0sTUTPlFy+nowreFq82sNPaoa m03/CgAGnWRMQEkrQ7+C4QhStB2rlgoUhIqh1zqOSebFjMqenOA2LoEVpddvoIzUU/FZ CqNZCGpRGdKMWpqaZnva4ClV10e3j4MuktlQDa+rmCFeTSCMpPTi+lm/Ye8Z7CggrFKs EN2cI1JVY4+NIIo02tPcyd8QDQDnHplbSXPuHRUDPUMGdecvq5LLDIKIkLIgOtjRwMuX jxJwVkoqxcLGOt2THltFvNJzs6r+p5sVQh85iZoFZZxhCOCqH1uVEmdt8NleRP49aoOo E+ug== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=Y2S6KTpUrSCMwTgBob27SzJraLan/JemfvDuj7xYqWU=; b=OI2FenWaPdPG7IiIDKXhIjodicznySv7y/OFwMQcGTeo8pdTPUUc5FNL5R8oTSiApj BSqfsjR6DTPWv/fmeCk0AwkXFhTW/ST61Df/94c1d5YI+Agrjfui4viHMdqNXVrrZ1Ml y0oTgOYgv6cmRO2XS0/OMgh0qPx2I05X2eQNVh7tOFL6tWUocRxerhnbzwCFV50IvlMt ZtDVfH46Gr+cCM5xIWCgyLFtsghmuz4p4jIFNR4Y2b23sXBrB5mOlBvtvJspB4ucdqyb IZtzC3K2N1DYWjKM7MpBeqD1J1kdfw/IrA8eBVdnhtfrfK4+L3u4Dp6BiMf3A0mH9SF6 7EJQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b="LkqmS/nu"; spf=pass (google.com: domain of dario.binacchi@amarulasolutions.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=dario.binacchi@amarulasolutions.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=amarulasolutions.com Received: from mail-sor-f41.google.com (mail-sor-f41.google.com. [209.85.220.41]) by mx.google.com with SMTPS id o5-20020a170906774500b007388c28074fsor2163783ejn.61.2022.08.17.07.36.45 for (Google Transport Security); Wed, 17 Aug 2022 07:36:45 -0700 (PDT) Received-SPF: pass (google.com: domain of dario.binacchi@amarulasolutions.com designates 209.85.220.41 as permitted sender) client-ip=209.85.220.41; X-Received: by 2002:a17:907:2e0b:b0:730:8aee:d674 with SMTP id ig11-20020a1709072e0b00b007308aeed674mr17258033ejc.104.1660747004949; Wed, 17 Aug 2022 07:36:44 -0700 (PDT) Received: from dario-ThinkPad-T14s-Gen-2i.homenet.telecomitalia.it (host-79-31-31-9.retail.telecomitalia.it. [79.31.31.9]) by smtp.gmail.com with ESMTPSA id o9-20020aa7c7c9000000b0043cab10f702sm10711982eds.90.2022.08.17.07.36.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Aug 2022 07:36:44 -0700 (PDT) From: Dario Binacchi To: linux-kernel@vger.kernel.org Cc: Alexandre Torgue , Amarula patchwork , michael@amarulasolutions.com, Marc Kleine-Budde , Dario Binacchi , Dario Binacchi , Krzysztof Kozlowski , Maxime Coquelin , Rob Herring , devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-stm32@st-md-mailman.stormreply.com Subject: [RFC PATCH 3/4] ARM: dts: stm32: add pin map for CAN controller on stm32f4 Date: Wed, 17 Aug 2022 16:35:28 +0200 Message-Id: <20220817143529.257908-4-dario.binacchi@amarulasolutions.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220817143529.257908-1-dario.binacchi@amarulasolutions.com> References: <20220817143529.257908-1-dario.binacchi@amarulasolutions.com> MIME-Version: 1.0 X-Original-Sender: dario.binacchi@amarulasolutions.com X-Original-Authentication-Results: mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b="LkqmS/nu"; spf=pass (google.com: domain of dario.binacchi@amarulasolutions.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=dario.binacchi@amarulasolutions.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=amarulasolutions.com Content-Type: text/plain; charset="UTF-8" Precedence: list Mailing-list: list linux-amarula@amarulasolutions.com; contact linux-amarula+owners@amarulasolutions.com List-ID: X-Spam-Checked-In-Group: linux-amarula@amarulasolutions.com X-Google-Group-Id: 476853432473 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , Add pin configurations for using CAN controller on stm32f469-disco board. They are located on the Arduino compatible connector CN5 (CAN1) and on the extension connector CN12 (CAN2). Signed-off-by: Dario Binacchi Signed-off-by: Dario Binacchi --- arch/arm/boot/dts/stm32f4-pinctrl.dtsi | 32 ++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/arch/arm/boot/dts/stm32f4-pinctrl.dtsi b/arch/arm/boot/dts/stm32f4-pinctrl.dtsi index 500bcc302d42..a8709363898a 100644 --- a/arch/arm/boot/dts/stm32f4-pinctrl.dtsi +++ b/arch/arm/boot/dts/stm32f4-pinctrl.dtsi @@ -448,6 +448,38 @@ pins2 { slew-rate = <2>; }; }; + + can1_pins_a: can1-0 { + pins1 { + pinmux = ; /* CAN1_TX */ + }; + pins2 { + pinmux = ; /* CAN1_RX */ + bias-pull-up; + }; + }; + + can2_pins_a: can2-0 { + pins1 { + pinmux = ; /* CAN2_TX */ + }; + pins2 { + pinmux = ; /* CAN2_RX */ + bias-pull-up; + }; + }; + + can2_pins_b: can2-1 { + pins1 { + pinmux = ; /* CAN2_TX */ + + }; + pins2 { + pinmux = ; /* CAN2_RX */ + bias-pull-up; + }; + }; + }; }; }; From patchwork Wed Aug 17 14:35:29 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dario Binacchi X-Patchwork-Id: 2302 Return-Path: X-Original-To: linux-amarula@patchwork.amarulasolutions.com Delivered-To: linux-amarula@patchwork.amarulasolutions.com Received: from mail-ed1-f70.google.com (mail-ed1-f70.google.com [209.85.208.70]) by ganimede.amarulasolutions.com (Postfix) with ESMTPS id 2AC8D3F03E for ; Wed, 17 Aug 2022 16:36:50 +0200 (CEST) Received: by mail-ed1-f70.google.com with SMTP id j19-20020a05640211d300b0043ddce5c23asf8871193edw.14 for ; Wed, 17 Aug 2022 07:36:50 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1660747010; cv=pass; d=google.com; s=arc-20160816; b=1F0kVefqdpczo6c7R7+YDN83mE2SXJ6Ms975v2wa7SnMj3RlBiHzJFFaCeg6ZIXA/B WIlP67MFqn6Y0ibR+Eg2qgWJ89LsxYnobi1vvTejEzjO/Sdgk9DEX3rHtMio2qxyM5xi o562i6HzanfQrtRWqPEYymZ0pyC1i7REzI9D4A5P9v7U0e6helpRfwVgVKXTQxl+ZiQX fhd2FYY9OT4/VetlqK3Gqaf6YArA4DwmozJ9wS0HvOS+H+NNZNxWbonK0qcvcSNJ2XHx AYp23N1PA1WF8mgi08a8JUT+O4FUaqxjWpqM+w+YRgfYyS7HfqqjcIQScrgjXtAjxQ4B dvUw== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-unsubscribe:list-archive:list-help:list-post:list-id :mailing-list:precedence:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=8q71DWeAPk85vem/SrkmFoAcRSjOx/HdHNhcMuy3kSc=; b=LsZgfFezquHQiKV4QCo5m8HJ9bgG0J9ReLkmiPbzqWACwvIzMwPrW2Dp3FLM0wQsLE MQeqnVTtr96RGNFS77hs888rpB7SqWhXeEeelBPJ+g5+p81y+73sFOxbR3LOv2GrTt2b ZG4gDNY9JILq+Kvr/8IzUkgDkemA0SxziJ3gYSMAyFy3AkK1YzUMEUdn+uXu9Jji2mwM TweZ2M9j3e50PUSVzRUXCbLIkojI+pDOQq1jyrxlRNcWD6fOtQczNxzK4+I+pgrWHpvI pfNPftHyOx4JfqQVgMGtnGnAq67DmlC7lqrdxdj8j4ut8eYNxJ45VpILv4CwQO7yJTty b38Q== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b=P6u1yEjB; spf=pass (google.com: domain of dario.binacchi@amarulasolutions.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=dario.binacchi@amarulasolutions.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=amarulasolutions.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amarulasolutions.com; s=google; h=list-unsubscribe:list-archive:list-help:list-post:list-id :mailing-list:precedence:x-original-authentication-results :x-original-sender:mime-version:references:in-reply-to:message-id :date:subject:cc:to:from:from:to:cc; bh=8q71DWeAPk85vem/SrkmFoAcRSjOx/HdHNhcMuy3kSc=; b=VcqNupGPViya0GQBUcDyjxDNXa2GtGC3GZ9710of3KEFcTLs7S3OT0CnShW7zsucsB jSOAYWnekGOoiJT4J+5h17U3yS6aFEIWIjSephi1ZqyIkKRf1iTqvEmz278h75sIEEuG CRMd/dV4O1ZlnW55q6IEp+pAXp5j6xWmS5sf0= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=list-unsubscribe:list-archive:list-help:list-post :x-spam-checked-in-group:list-id:mailing-list:precedence :x-original-authentication-results:x-original-sender:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :x-gm-message-state:from:to:cc; bh=8q71DWeAPk85vem/SrkmFoAcRSjOx/HdHNhcMuy3kSc=; b=xdJHN92u1pVfCz2XM6EyBq3bw/pFcd62iMmxzsoguDF8RZMPKy3XXd4aiQjKy6Ktqj /Ei7z8ZETogiM8OHhbMxan4si0Wg1fJ/vm8bT2yVNJDad5z5fMgILv+5lIxAMBYTJ4Y6 NipspsmEpGyQ18Hvx6a1W0G9ka2cy7GpzaWeA2lLOnD01W3QAJ+8Y0E1InaonoUqRatG iLa/oWaBcVFgq1D9Fq8o1Fms34yf0f7TQ1uPB3LrLhMWkbaI4rn5O/DcsQHQI7aoQhKA r+JZ9ifEhWfjUaNg4aoTaFR4nPYrWAk7lhaoF4UymLHru4h32hT93lZign2p9646s7f4 f7UA== X-Gm-Message-State: ACgBeo2tEHHQ9KutP16Wr+IIzWgVh5m/KjVO6BuAqjG7HMwmG8ru6Hsm 5hSCOV7isATC3geyG7WeyEOQpl5i X-Google-Smtp-Source: AA6agR4ZkcO7fG7y2cUdwFrLFt2Zg9nwi6O6vXTtDbP0XdODhka3Azk9vhkX72o545HCKGhAYMQmbg== X-Received: by 2002:a17:907:7615:b0:730:e1ad:b132 with SMTP id jx21-20020a170907761500b00730e1adb132mr16887967ejc.744.1660747009773; Wed, 17 Aug 2022 07:36:49 -0700 (PDT) X-BeenThere: linux-amarula@amarulasolutions.com Received: by 2002:a17:907:209c:b0:731:366b:d9a8 with SMTP id pv28-20020a170907209c00b00731366bd9a8ls3756264ejb.3.-pod-prod-gmail; Wed, 17 Aug 2022 07:36:48 -0700 (PDT) X-Received: by 2002:a17:907:3d90:b0:730:a7d2:23f0 with SMTP id he16-20020a1709073d9000b00730a7d223f0mr16783339ejc.358.1660747008475; Wed, 17 Aug 2022 07:36:48 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1660747008; cv=none; d=google.com; s=arc-20160816; b=HBDMPmo+yBX9BW/oLYRCQ38Jxa0e7Y5R1wukFTLHZuiiUzVMaIVtZ/FrZuLtYA5qrE 4oYLc3t7bKnjx7kMVRlgdPzIe4YMZZZyt4H+dqDncAOsMinQE7zo1uoUZBXWtoTSMaun gONa4JHtP6Giz3ME/3ZnoIIcc1KNGZpmnNhIzKgsyXnvG9ZmcGzC6/wSXKJdpoYSFLh3 WvT9eSHdegqIyYYQ0JnAHMIUW/NG8YP9eoFAtLFOCmU4PaaWgw0/dorD0rIG8tCvM2pn 6lqi8xuQVhqOo52YxKdSApPhm02qTuHJSn5udS6ItygBjklJcOB8lnhqgeVV6viNzSKn 7Rpg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=AgMgbh/oLddMZPBoOQHfUpECQ+KTIAY4HesxfB5erIE=; b=fVzk1lSozKeyMFkpOYOoWSBrP8qvYVpBN81EgN31lo02h+cBaHPvGcSZasGkof9TXd JVtRj6Tv0ZDYjYjY2y1CZKUdRyZye/kVZOw2AcoO2+D5lFRduR//LizDKnJU6MkS3ib2 trgAznpld5JWu4k9ZpK4YEV94q9ssvZgH47hPnRppoF4x3D+c0BbKsSnq4Z69RBho3oI PuY+OAbd8EiiQh/igB3ZW/Tkt+UnluFnLGGOmw/KxJm2xlHbY/IhWQ6s5dWkEdMGkQ3Y XLsu5DQTJH/YSs2eC2OaPCZha0k6dk//z7jSwxQDkCJEmIZT9B+8UHgmYYLUp8Nx9NK+ /Y9Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b=P6u1yEjB; spf=pass (google.com: domain of dario.binacchi@amarulasolutions.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=dario.binacchi@amarulasolutions.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=amarulasolutions.com Received: from mail-sor-f41.google.com (mail-sor-f41.google.com. [209.85.220.41]) by mx.google.com with SMTPS id w1-20020a1709062f8100b0072aadc1868bsor5397203eji.80.2022.08.17.07.36.48 for (Google Transport Security); Wed, 17 Aug 2022 07:36:48 -0700 (PDT) Received-SPF: pass (google.com: domain of dario.binacchi@amarulasolutions.com designates 209.85.220.41 as permitted sender) client-ip=209.85.220.41; X-Received: by 2002:a17:907:3ea7:b0:730:9a8b:b8f1 with SMTP id hs39-20020a1709073ea700b007309a8bb8f1mr16813617ejc.168.1660747008064; Wed, 17 Aug 2022 07:36:48 -0700 (PDT) Received: from dario-ThinkPad-T14s-Gen-2i.homenet.telecomitalia.it (host-79-31-31-9.retail.telecomitalia.it. [79.31.31.9]) by smtp.gmail.com with ESMTPSA id o9-20020aa7c7c9000000b0043cab10f702sm10711982eds.90.2022.08.17.07.36.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Aug 2022 07:36:47 -0700 (PDT) From: Dario Binacchi To: linux-kernel@vger.kernel.org Cc: Alexandre Torgue , Amarula patchwork , michael@amarulasolutions.com, Marc Kleine-Budde , Dario Binacchi , Dario Binacchi , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Wolfgang Grandegger , linux-can@vger.kernel.org, netdev@vger.kernel.org Subject: [RFC PATCH 4/4] can: bxcan: add support for ST bxCAN controller Date: Wed, 17 Aug 2022 16:35:29 +0200 Message-Id: <20220817143529.257908-5-dario.binacchi@amarulasolutions.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220817143529.257908-1-dario.binacchi@amarulasolutions.com> References: <20220817143529.257908-1-dario.binacchi@amarulasolutions.com> MIME-Version: 1.0 X-Original-Sender: dario.binacchi@amarulasolutions.com X-Original-Authentication-Results: mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b=P6u1yEjB; spf=pass (google.com: domain of dario.binacchi@amarulasolutions.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=dario.binacchi@amarulasolutions.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=amarulasolutions.com Content-Type: text/plain; charset="UTF-8" Precedence: list Mailing-list: list linux-amarula@amarulasolutions.com; contact linux-amarula+owners@amarulasolutions.com List-ID: X-Spam-Checked-In-Group: linux-amarula@amarulasolutions.com X-Google-Group-Id: 476853432473 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , Add support for the basic extended CAN controller (bxCAN) found in many low- to middle-end STM32 SoCs. It supports the Basic Extended CAN protocol versions 2.0A and B with a maximum bit rate of 1 Mbit/s. The controller supports two channels (CAN1 as master and CAN2 as slave) and the driver can enable either or both of the channels. They share some of the required logic (e. g. clocks and filters), and that means you cannot use the slave CAN without enabling some hardware resources managed by the master CAN. Each channel has 3 transmit mailboxes, 2 receive FIFOs with 3 stages and 28 scalable filter banks. It also manages 4 dedicated interrupt vectors: - transmit interrupt - FIFO 0 receive interrupt - FIFO 1 receive interrupt - status change error interrupt Driver uses all 3 available mailboxes for transmission and FIFO 0 for reception. Rx filter rules are configured to the minimum. They accept all messages and assign filter 0 to CAN1 and filter 14 to CAN2 in identifier mask mode with 32 bits width. It enables and uses transmit, receive buffers for FIFO 0 and error and status change interrupts. Signed-off-by: Dario Binacchi Signed-off-by: Dario Binacchi --- drivers/net/can/Kconfig | 1 + drivers/net/can/Makefile | 1 + drivers/net/can/bxcan/Kconfig | 34 + drivers/net/can/bxcan/Makefile | 4 + drivers/net/can/bxcan/bxcan-core.c | 201 ++++++ drivers/net/can/bxcan/bxcan-core.h | 33 + drivers/net/can/bxcan/bxcan-drv.c | 980 +++++++++++++++++++++++++++++ 7 files changed, 1254 insertions(+) create mode 100644 drivers/net/can/bxcan/Kconfig create mode 100644 drivers/net/can/bxcan/Makefile create mode 100644 drivers/net/can/bxcan/bxcan-core.c create mode 100644 drivers/net/can/bxcan/bxcan-core.h create mode 100644 drivers/net/can/bxcan/bxcan-drv.c diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig index 3048ad77edb3..d55355a0e583 100644 --- a/drivers/net/can/Kconfig +++ b/drivers/net/can/Kconfig @@ -206,6 +206,7 @@ config PCH_CAN is an IOH for x86 embedded processor (Intel Atom E6xx series). This driver can access CAN bus. +source "drivers/net/can/bxcan/Kconfig" source "drivers/net/can/c_can/Kconfig" source "drivers/net/can/cc770/Kconfig" source "drivers/net/can/ctucanfd/Kconfig" diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile index 61c75ce9d500..373f2c99689a 100644 --- a/drivers/net/can/Makefile +++ b/drivers/net/can/Makefile @@ -14,6 +14,7 @@ obj-y += usb/ obj-y += softing/ obj-$(CONFIG_CAN_AT91) += at91_can.o +obj-$(CONFIG_CAN_BXCAN) += bxcan/ obj-$(CONFIG_CAN_CAN327) += can327.o obj-$(CONFIG_CAN_CC770) += cc770/ obj-$(CONFIG_CAN_C_CAN) += c_can/ diff --git a/drivers/net/can/bxcan/Kconfig b/drivers/net/can/bxcan/Kconfig new file mode 100644 index 000000000000..df34c212bf51 --- /dev/null +++ b/drivers/net/can/bxcan/Kconfig @@ -0,0 +1,34 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# bxCAN driver configuration +# +menuconfig CAN_BXCAN + tristate "STMicroelectronics STM32 Basic Extended CAN (bxCAN) devices" + depends on ARCH_STM32 || COMPILE_TEST + depends on OF + depends on HAS_IOMEM + help + Say Y here if you want support for ST bxCAN controller framework. + This is common support for devices that embed the ST bxCAN IP. + +if CAN_BXCAN + +config CAN_BXCAN_CORE + tristate "STMicroelectronics STM32 bxCAN core" + help + Select this option to enable the core driver for STMicroelectronics + STM32 basic extended CAN controller (bxCAN). + + This driver can also be built as a module. If so, the module + will be called bxcan-core. + +config CAN_BXCAN_DRV + tristate "STMicroelectronics STM32 bxCAN driver" + depends on CAN_BXCAN_CORE + help + Say yes here to build support for the STMicroelectronics STM32 basic + extended CAN Controller (bxCAN). + + This driver can also be built as a module. If so, the module + will be called bxcan-drv. +endif diff --git a/drivers/net/can/bxcan/Makefile b/drivers/net/can/bxcan/Makefile new file mode 100644 index 000000000000..60350f055271 --- /dev/null +++ b/drivers/net/can/bxcan/Makefile @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only + +obj-$(CONFIG_CAN_BXCAN_CORE) += bxcan-core.o +obj-$(CONFIG_CAN_BXCAN_DRV) += bxcan-drv.o diff --git a/drivers/net/can/bxcan/bxcan-core.c b/drivers/net/can/bxcan/bxcan-core.c new file mode 100644 index 000000000000..16cbc8faf583 --- /dev/null +++ b/drivers/net/can/bxcan/bxcan-core.c @@ -0,0 +1,201 @@ +// SPDX-License-Identifier: GPL-2.0 +/* bxcan-core.c - STM32 Basic Extended CAN core controller driver + * + * This file is part of STM32 bxcan driver + * + * Copyright (c) 2022 Dario Binacchi + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include + +#include "bxcan-core.h" + +#define BXCAN_FILTER_ID(master) (master ? 0 : 14) + +/* Filter master register (FMR) bits */ +#define BXCAN_FMR_CANSB_MASK GENMASK(13, 8) +#define BXCAN_FMR_CANSB(x) (((x) & 0x3f) << 8) +#define BXCAN_FMR_FINIT BIT(0) + +/* Structure of the filter bank */ +struct bxcan_fb { + u32 fr1; /* filter 1 */ + u32 fr2; /* filter 2 */ +}; + +/* Structure of the hardware filter registers */ +struct bxcan_fregs { + u32 fmr; /* 0x00 - filter master */ + u32 fm1r; /* 0x04 - filter mode */ + u32 reserved2; /* 0x08 */ + u32 fs1r; /* 0x0c - filter scale */ + u32 reserved3; /* 0x10 */ + u32 ffa1r; /* 0x14 - filter FIFO assignment */ + u32 reserved4; /* 0x18 */ + u32 fa1r; /* 0x1c - filter activation */ + u32 reserved5[8]; /* 0x20 */ + struct bxcan_fb fb[28]; /* 0x40 - filter banks */ +}; + +struct bxcan_core_priv { + void __iomem *base; + struct bxcan_fregs __iomem *fregs; + struct clk *clk_master; + unsigned int clk_master_ref; +}; + +void bxcan_disable_filters(struct device *dev, bool master) +{ + struct bxcan_core_priv *priv = dev_get_drvdata(dev); + unsigned int fid = BXCAN_FILTER_ID(master); + u32 fmask = BIT(fid); + + bxcan_rmw(&priv->fregs->fa1r, fmask, 0); +} + +void bxcan_enable_filters(struct device *dev, bool master) +{ + struct bxcan_core_priv *priv = dev_get_drvdata(dev); + unsigned int fid = BXCAN_FILTER_ID(master); + u32 fmask = BIT(fid); + + /* Filter settings: + * + * Accept all messages. + * Assign filter 0 to CAN1 and filter 14 to CAN2 in identifier + * mask mode with 32 bits width. + */ + + /* Enter filter initialization mode and assing filters to CAN + * controllers. + */ + bxcan_rmw(&priv->fregs->fmr, BXCAN_FMR_CANSB_MASK, + BXCAN_FMR_CANSB(14) | BXCAN_FMR_FINIT); + + /* Deactivate filter */ + bxcan_rmw(&priv->fregs->fa1r, fmask, 0); + + /* Two 32-bit registers in identifier mask mode */ + bxcan_rmw(&priv->fregs->fm1r, fmask, 0); + + /* Single 32-bit scale configuration */ + bxcan_rmw(&priv->fregs->fs1r, 0, fmask); + + /* Assign filter to FIFO 0 */ + bxcan_rmw(&priv->fregs->ffa1r, fmask, 0); + + /* Accept all messages */ + writel(0, &priv->fregs->fb[fid].fr1); + writel(0, &priv->fregs->fb[fid].fr2); + + /* Activate filter */ + bxcan_rmw(&priv->fregs->fa1r, 0, fmask); + + /* Exit filter initialization mode */ + bxcan_rmw(&priv->fregs->fmr, BXCAN_FMR_FINIT, 0); +} + +int bxcan_enable_master_clk(struct device *dev) +{ + struct bxcan_core_priv *priv = dev_get_drvdata(dev); + int err; + + if (priv->clk_master_ref == 0) { + err = clk_prepare_enable(priv->clk_master); + if (err) + return err; + } + + priv->clk_master_ref++; + return 0; +} + +void bxcan_disable_master_clk(struct device *dev) +{ + struct bxcan_core_priv *priv = dev_get_drvdata(dev); + + if (priv->clk_master_ref == 0) + return; + + if (priv->clk_master_ref == 1) + clk_disable_unprepare(priv->clk_master); + + priv->clk_master_ref--; +} + +unsigned long bxcan_get_master_clk_rate(struct device *dev) +{ + struct bxcan_core_priv *priv = dev_get_drvdata(dev); + + return clk_get_rate(priv->clk_master); +} + +void __iomem *bxcan_get_base_addr(struct device *dev) +{ + struct bxcan_core_priv *priv = dev_get_drvdata(dev); + + return priv->base; +} + +static const struct of_device_id bxcan_core_of_match[] = { + {.compatible = "st,stm32-bxcan-core"}, + { /* sentinel */ }, +}; + +MODULE_DEVICE_TABLE(of, bxcan_core_of_match); + +static int bxcan_core_probe(struct platform_device *pdev) +{ + struct bxcan_core_priv *priv; + struct device *dev = &pdev->dev; + struct device_node *np = pdev->dev.of_node; + void __iomem *regs; + struct clk *clk; + int ret; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + platform_set_drvdata(pdev, priv); + regs = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(regs)) + return PTR_ERR(regs); + + clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(clk)) { + dev_err(dev, "failed to get clock\n"); + return PTR_ERR(clk); + } + + priv->base = regs; + priv->fregs = regs + 0x200; + priv->clk_master = clk; + + dev_info(&pdev->dev, "regs: %px\n", priv->base); + ret = of_platform_populate(np, NULL, NULL, dev); + if (ret < 0) { + dev_err(dev, "failed to populate DT children\n"); + return ret; + } + + return 0; +} + +static struct platform_driver bxcan_core_driver = { + .driver = { + .name = KBUILD_MODNAME, + .of_match_table = bxcan_core_of_match, + }, + .probe = bxcan_core_probe, +}; + +module_platform_driver(bxcan_core_driver); + +MODULE_AUTHOR("Dario Binacchi "); +MODULE_DESCRIPTION("STMicroelectronics Basic Extended CAN core driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/net/can/bxcan/bxcan-core.h b/drivers/net/can/bxcan/bxcan-core.h new file mode 100644 index 000000000000..51846b1ae698 --- /dev/null +++ b/drivers/net/can/bxcan/bxcan-core.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0 + * + * bxcan-core - STM32 Basic Extended CAN core controller driver + * + * Copyright (c) 2022 Dario Binacchi + */ + +#ifndef __BXCAN_CORE_H +#define __BXCAN_CORE_H + +#include +#include + +int bxcan_enable_master_clk(struct device *dev); +void bxcan_disable_master_clk(struct device *dev); +unsigned long bxcan_get_master_clk_rate(struct device *dev); +void __iomem *bxcan_get_base_addr(struct device *dev); +void bxcan_enable_filters(struct device *dev, bool master); +void bxcan_disable_filters(struct device *dev, bool master); + +static inline void bxcan_rmw(volatile void __iomem *addr, u32 clear, u32 set) +{ + u32 old, val; + + old = readl(addr); + val = (old & ~clear) | set; + if (val != old) + writel(val, addr); + + pr_debug("rmw 0x%08x @ 0x%08x\n", val, (u32)addr); +} + +#endif diff --git a/drivers/net/can/bxcan/bxcan-drv.c b/drivers/net/can/bxcan/bxcan-drv.c new file mode 100644 index 000000000000..5fbb0327d104 --- /dev/null +++ b/drivers/net/can/bxcan/bxcan-drv.c @@ -0,0 +1,980 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// bxcan-drv.c - STM32 Basic Extended CAN controller driver +// +// Copyright (c) 2022 Dario Binacchi +// + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "bxcan-core.h" + +#define BXCAN_NAPI_WEIGHT 3 +#define BXCAN_TIMEOUT_US 10000 + +#define BXCAN_TX_MB_NUM 3 + +/* Master control register (MCR) bits */ +#define BXCAN_MCR_DBF BIT(16) +#define BXCAN_MCR_RESET BIT(15) +#define BXCAN_MCR_TTCM BIT(7) +#define BXCAN_MCR_ABOM BIT(6) +#define BXCAN_MCR_AWUM BIT(5) +#define BXCAN_MCR_NART BIT(4) +#define BXCAN_MCR_RFLM BIT(3) +#define BXCAN_MCR_TXFP BIT(2) +#define BXCAN_MCR_SLEEP BIT(1) +#define BXCAN_MCR_INRQ BIT(0) + +/* Master status register (MSR) bits */ +#define BXCAN_MSR_RX BIT(11) +#define BXCAN_MSR_SAMP BIT(10) +#define BXCAN_MSR_RXM BIT(9) +#define BXCAN_MSR_TXM BIT(8) +#define BXCAN_MSR_SLAKI BIT(4) +#define BXCAN_MSR_WKUI BIT(3) +#define BXCAN_MSR_ERRI BIT(2) +#define BXCAN_MSR_SLAK BIT(1) +#define BXCAN_MSR_INAK BIT(0) + +/* Transmit status register (TSR) bits */ +#define BXCAN_TSR_LOW2 BIT(31) +#define BXCAN_TSR_LOW1 BIT(30) +#define BXCAN_TSR_LOW0 BIT(29) +#define BXCAN_TSR_TME GENMASK(28, 26) +#define BXCAN_TSR_TME_SHIFT (26) +#define BXCAN_TSR_TME2 BIT(28) +#define BXCAN_TSR_TME1 BIT(27) +#define BXCAN_TSR_TME0 BIT(26) +#define BXCAN_TSR_CODE GENMASK(25, 24) +#define BXCAN_TSR_ABRQ2 BIT(23) +#define BXCAN_TSR_TERR2 BIT(19) +#define BXCAN_TSR_ALST2 BIT(18) +#define BXCAN_TSR_TXOK2 BIT(17) +#define BXCAN_TSR_RQCP2 BIT(16) +#define BXCAN_TSR_ABRQ1 BIT(15) +#define BXCAN_TSR_TERR1 BIT(11) +#define BXCAN_TSR_ALST1 BIT(10) +#define BXCAN_TSR_TXOK1 BIT(9) +#define BXCAN_TSR_RQCP1 BIT(8) +#define BXCAN_TSR_ABRQ0 BIT(7) +#define BXCAN_TSR_TERR0 BIT(3) +#define BXCAN_TSR_ALST0 BIT(2) +#define BXCAN_TSR_TXOK0 BIT(1) +#define BXCAN_TSR_RQCP0 BIT(0) + +/* Receive FIFO 0 register (RF0R) bits */ +#define BXCAN_RF0R_RFOM0 BIT(5) +#define BXCAN_RF0R_FOVR0 BIT(4) +#define BXCAN_RF0R_FULL0 BIT(3) +#define BXCAN_RF0R_FMP0 GENMASK(1, 0) + +/* Interrupt enable register (IER) bits */ +#define BXCAN_IER_SLKIE BIT(17) +#define BXCAN_IER_WKUIE BIT(16) +#define BXCAN_IER_ERRIE BIT(15) +#define BXCAN_IER_LECIE BIT(11) +#define BXCAN_IER_BOFIE BIT(10) +#define BXCAN_IER_EPVIE BIT(9) +#define BXCAN_IER_EWGIE BIT(8) +#define BXCAN_IER_FOVIE1 BIT(6) +#define BXCAN_IER_FFIE1 BIT(5) +#define BXCAN_IER_FMPIE1 BIT(4) +#define BXCAN_IER_FOVIE0 BIT(3) +#define BXCAN_IER_FFIE0 BIT(2) +#define BXCAN_IER_FMPIE0 BIT(1) +#define BXCAN_IER_TMEIE BIT(0) + +/* Error status register (ESR) bits */ +#define BXCAN_ESR_REC_SHIFT (24) +#define BXCAN_ESR_REC GENMASK(31, 24) +#define BXCAN_ESR_TEC_SHIFT (16) +#define BXCAN_ESR_TEC GENMASK(23, 16) +#define BXCAN_ESR_LEC_SHIFT (4) +#define BXCAN_ESR_LEC GENMASK(6, 4) +#define BXCAN_ESR_BOFF BIT(1) +#define BXCAN_ESR_EPVF BIT(1) +#define BXCAN_ESR_EWGF BIT(0) +#define BXCAN_TEC(esr) (((esr) & BXCAN_ESR_TEC) >> \ + BXCAN_ESR_TEC_SHIFT) +#define BXCAN_REC(esr) (((esr) & BXCAN_ESR_REC) >> \ + BXCAN_ESR_REC_SHIFT) + +/* Bit timing register (BTR) bits */ +#define BXCAN_BTR_SILM BIT(31) +#define BXCAN_BTR_LBKM BIT(30) +#define BXCAN_BTR_SJW_MASK GENMASK(25, 24) +#define BXCAN_BTR_SJW(x) (((x) & 0x03) << 24) +#define BXCAN_BTR_TS2_MASK GENMASK(22, 20) +#define BXCAN_BTR_TS2(x) (((x) & 0x07) << 20) +#define BXCAN_BTR_TS1_MASK GENMASK(19, 16) +#define BXCAN_BTR_TS1(x) (((x) & 0x0f) << 16) +#define BXCAN_BTR_BRP_MASK GENMASK(9, 0) +#define BXCAN_BTR_BRP(x) ((x) & 0x3ff) + +/* TX mailbox identifier register (TIxR, x = 0..2) bits */ +#define BXCAN_TIxR_STID(x) (((x) & 0x7ff) << 21) +#define BXCAN_TIxR_EXID(x) ((x) << 3) +#define BXCAN_TIxR_IDE BIT(2) +#define BXCAN_TIxR_RTR BIT(1) +#define BXCAN_TIxR_TXRQ BIT(0) + +/* TX mailbox data length and time stamp register (TDTxR, x = 0..2 bits */ +#define BXCAN_TDTxR_TIME(x) (((x) & 0x0f) << 16) +#define BXCAN_TDTxR_TGT BIT(8) +#define BXCAN_TDTxR_DLC_MASK GENMASK(3, 0) +#define BXCAN_TDTxR_DLC(x) ((x) & 0x0f) + +/* RX FIFO mailbox identifier register (RIxR, x = 0..1 */ +#define BXCAN_RIxR_STID_SHIFT (21) +#define BXCAN_RIxR_EXID_SHIFT (3) +#define BXCAN_RIxR_IDE BIT(2) +#define BXCAN_RIxR_RTR BIT(1) + +/* RX FIFO mailbox data length and timestamp register (RDTxR, x = 0..1) bits */ +#define BXCAN_RDTxR_TIME GENMASK(31, 16) +#define BXCAN_RDTxR_FMI GENMASK(15, 8) +#define BXCAN_RDTxR_DLC GENMASK(3, 0) + +enum bxcan_lec_code { + LEC_NO_ERROR = 0, + LEC_STUFF_ERROR, + LEC_FORM_ERROR, + LEC_ACK_ERROR, + LEC_BIT1_ERROR, + LEC_BIT0_ERROR, + LEC_CRC_ERROR, + LEC_UNUSED +}; + +/* Structure of the message buffer */ +struct bxcan_mb { + u32 id; /* can identifier */ + u32 dlc; /* data length control and timestamp */ + u32 data[2]; /* data */ +}; + +/* Structure of the hardware registers */ +struct bxcan_regs { + u32 mcr; /* 0x00 - master control */ + u32 msr; /* 0x04 - master status */ + u32 tsr; /* 0x08 - transmit status */ + u32 rf0r; /* 0x0c - FIFO 0 */ + u32 rf1r; /* 0x10 - FIFO 1 */ + u32 ier; /* 0x14 - interrupt enable */ + u32 esr; /* 0x18 - error status */ + u32 btr; /* 0x1c - bit timing*/ + u32 reserved0[88]; /* 0x20 */ + struct bxcan_mb tx_mb[BXCAN_TX_MB_NUM]; /* 0x180 - tx mailbox */ + struct bxcan_mb rx_mb[2]; /* 0x1b0 - rx mailbox */ +}; + +struct bxcan_priv { + struct can_priv can; + struct device *dev; + struct napi_struct napi; + + struct bxcan_regs __iomem *regs; + int tx_irq; + int sce_irq; + u8 tx_dlc[BXCAN_TX_MB_NUM]; + bool master; + struct clk *clk; +}; + +static const struct can_bittiming_const bxcan_bittiming_const = { + .name = KBUILD_MODNAME, + .tseg1_min = 1, + .tseg1_max = 16, + .tseg2_min = 1, + .tseg2_max = 8, + .sjw_max = 4, + .brp_min = 1, + .brp_max = 1024, + .brp_inc = 1, +}; + +static int bxcan_chip_softreset(struct bxcan_priv *priv) +{ + struct bxcan_regs __iomem *regs = priv->regs; + unsigned int timeout = BXCAN_TIMEOUT_US / 10; + + bxcan_rmw(®s->mcr, 0, BXCAN_MCR_RESET); + while (timeout-- && !(readl(®s->msr) & BXCAN_MSR_SLAK)) + udelay(10); + + if (!(readl(®s->msr) & BXCAN_MSR_SLAK)) + return -ETIMEDOUT; + + return 0; +} + +static int bxcan_enter_init_mode(struct bxcan_priv *priv) +{ + struct bxcan_regs __iomem *regs = priv->regs; + unsigned int timeout = BXCAN_TIMEOUT_US / 10; + + bxcan_rmw(®s->mcr, 0, BXCAN_MCR_INRQ); + while (timeout-- && !(readl(®s->msr) & BXCAN_MSR_INAK)) + udelay(100); + + if (!(readl(®s->msr) & BXCAN_MSR_INAK)) + return -ETIMEDOUT; + + return 0; +} + +static int bxcan_leave_init_mode(struct bxcan_priv *priv) +{ + struct bxcan_regs __iomem *regs = priv->regs; + unsigned int timeout = BXCAN_TIMEOUT_US / 10; + + bxcan_rmw(®s->mcr, BXCAN_MCR_INRQ, 0); + while (timeout-- && (readl(®s->msr) & BXCAN_MSR_INAK)) + udelay(100); + + if (readl(®s->msr) & BXCAN_MSR_INAK) + return -ETIMEDOUT; + + return 0; +} + +static int bxcan_leave_sleep_mode(struct bxcan_priv *priv) +{ + struct bxcan_regs __iomem *regs = priv->regs; + unsigned int timeout = BXCAN_TIMEOUT_US / 10; + + bxcan_rmw(®s->mcr, BXCAN_MCR_SLEEP, 0); + while (timeout-- && (readl(®s->msr) & BXCAN_MSR_SLAK)) + udelay(100); + + if (readl(®s->msr) & BXCAN_MSR_SLAK) + return -ETIMEDOUT; + + return 0; +} + +static int bxcan_enter_sleep_mode(struct bxcan_priv *priv) +{ + struct bxcan_regs __iomem *regs = priv->regs; + unsigned int timeout = BXCAN_TIMEOUT_US / 10; + + bxcan_rmw(®s->mcr, 0, BXCAN_MCR_SLEEP); + while (timeout-- && !(readl(®s->msr) & BXCAN_MSR_SLAK)) + udelay(100); + + if (!(readl(®s->msr) & BXCAN_MSR_SLAK)) + return -ETIMEDOUT; + + return 0; +} + +static irqreturn_t bxcan_rx_isr(int irq, void *dev_id) +{ + struct net_device *ndev = dev_id; + struct bxcan_priv *priv = netdev_priv(ndev); + struct bxcan_regs __iomem *regs = priv->regs; + + if (napi_schedule_prep(&priv->napi)) { + /* Disable Rx FIFO message pending interrupt */ + bxcan_rmw(®s->ier, BXCAN_IER_FMPIE0, 0); + __napi_schedule(&priv->napi); + } + + return IRQ_HANDLED; +} + +static irqreturn_t bxcan_tx_isr(int irq, void *dev_id) +{ + struct net_device *ndev = dev_id; + struct bxcan_priv *priv = netdev_priv(ndev); + struct bxcan_regs __iomem *regs = priv->regs; + struct net_device_stats *stats = &ndev->stats; + u32 tsr, rqcp_bit = BXCAN_TSR_RQCP0; + int i; + + tsr = readl(®s->tsr); + for (i = 0; i < BXCAN_TX_MB_NUM; rqcp_bit <<= 8, i++) { + if (!(tsr & rqcp_bit)) + continue; + + stats->tx_packets++; + stats->tx_bytes += priv->tx_dlc[i]; + } + + writel(tsr, ®s->tsr); + + if (netif_queue_stopped(ndev)) + netif_wake_queue(ndev); + + return IRQ_HANDLED; +} + +static void bxcan_handle_state_change(struct net_device *ndev, u32 esr) +{ + struct bxcan_priv *priv = netdev_priv(ndev); + struct net_device_stats *stats = &ndev->stats; + enum can_state new_state = priv->can.state; + struct can_berr_counter bec; + enum can_state rx_state, tx_state; + struct sk_buff *skb; + struct can_frame *cf; + + /* Early exit if no error flag is set */ + if (!(esr & (BXCAN_ESR_EWGF | BXCAN_ESR_EPVF | BXCAN_ESR_BOFF))) + return; + + bec.txerr = BXCAN_TEC(esr); + bec.rxerr = BXCAN_REC(esr); + + if (esr & BXCAN_ESR_BOFF) + new_state = CAN_STATE_BUS_OFF; + else if (esr & BXCAN_ESR_EPVF) + new_state = CAN_STATE_ERROR_PASSIVE; + else if (esr & BXCAN_ESR_EWGF) + new_state = CAN_STATE_ERROR_WARNING; + + /* state hasn't changed */ + if (unlikely(new_state == priv->can.state)) + return; + + skb = alloc_can_err_skb(ndev, &cf); + if (unlikely(!skb)) + return; + + tx_state = bec.txerr >= bec.rxerr ? new_state : 0; + rx_state = bec.txerr <= bec.rxerr ? new_state : 0; + can_change_state(ndev, cf, tx_state, rx_state); + + if (new_state == CAN_STATE_BUS_OFF) + can_bus_off(ndev); + + stats->rx_bytes += cf->len; + stats->rx_packets++; + netif_rx(skb); +} + +static void bxcan_handle_bus_err(struct net_device *ndev, u32 esr) +{ + struct bxcan_priv *priv = netdev_priv(ndev); + enum bxcan_lec_code lec_code; + struct can_frame *cf; + struct sk_buff *skb; + + lec_code = (esr & BXCAN_ESR_LEC_SHIFT) >> BXCAN_ESR_LEC_SHIFT; + + /* Early exit if no lec update or no error. + * No lec update means that no CAN bus event has been detected + * since CPU wrote LEC_UNUSED value to status reg. + */ + if (lec_code == LEC_UNUSED || lec_code == LEC_NO_ERROR) + return; + + if (!(priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)) + return; + + /* Common for all type of bus errors */ + priv->can.can_stats.bus_error++; + + /* Propagate the error condition to the CAN stack */ + skb = alloc_can_err_skb(ndev, &cf); + if (unlikely(!skb)) + return; + + ndev->stats.rx_bytes += cf->len; + + /* Check for 'last error code' which tells us the + * type of the last error to occur on the CAN bus + */ + cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; + + switch (lec_code) { + case LEC_STUFF_ERROR: + netdev_dbg(ndev, "Stuff error\n"); + ndev->stats.rx_errors++; + cf->data[2] |= CAN_ERR_PROT_STUFF; + break; + case LEC_FORM_ERROR: + netdev_dbg(ndev, "Form error\n"); + ndev->stats.rx_errors++; + cf->data[2] |= CAN_ERR_PROT_FORM; + break; + case LEC_ACK_ERROR: + netdev_dbg(ndev, "Ack error\n"); + ndev->stats.tx_errors++; + cf->data[3] = CAN_ERR_PROT_LOC_ACK; + break; + case LEC_BIT1_ERROR: + netdev_dbg(ndev, "Bit error (recessive)\n"); + ndev->stats.tx_errors++; + cf->data[2] |= CAN_ERR_PROT_BIT1; + break; + case LEC_BIT0_ERROR: + netdev_dbg(ndev, "Bit error (dominant)\n"); + ndev->stats.tx_errors++; + cf->data[2] |= CAN_ERR_PROT_BIT0; + break; + case LEC_CRC_ERROR: + netdev_dbg(ndev, "CRC error\n"); + ndev->stats.rx_errors++; + cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ; + break; + default: + break; + } + + netif_rx(skb); +} + +static irqreturn_t bxcan_state_change_isr(int irq, void *dev_id) +{ + struct net_device *ndev = dev_id; + struct bxcan_priv *priv = netdev_priv(ndev); + struct bxcan_regs __iomem *regs = priv->regs; + u32 msr, esr; + + msr = readl(®s->msr); + if (!(msr & BXCAN_MSR_ERRI)) + return IRQ_NONE; + + esr = readl(®s->esr); + bxcan_handle_state_change(ndev, esr); + bxcan_handle_bus_err(ndev, esr); + + msr |= BXCAN_MSR_ERRI; + writel(msr, ®s->msr); + return IRQ_HANDLED; +} + +static int bxcan_start(struct net_device *ndev) +{ + struct bxcan_priv *priv = netdev_priv(ndev); + struct bxcan_regs __iomem *regs = priv->regs; + struct can_bittiming *bt = &priv->can.bittiming; + u32 set; + int err; + + err = bxcan_chip_softreset(priv); + if (err) { + netdev_err(ndev, "failed to reset chip, error %d\n", err); + return err; + } + + err = bxcan_leave_sleep_mode(priv); + if (err) { + netdev_err(ndev, "failed to leave sleep mode, error %d\n", err); + goto failed_leave_sleep; + } + + err = bxcan_enter_init_mode(priv); + if (err) { + netdev_err(ndev, "failed to enter init mode, error %d\n", err); + goto failed_enter_init; + } + + /* MCR + * + * select request order priority + * disable time triggered mode + * bus-off state left on sw request + * sleep mode left on sw request + * retransmit automatically on error + * do not lock RX FIFO on overrun + */ + bxcan_rmw(®s->mcr, BXCAN_MCR_TTCM | BXCAN_MCR_ABOM | BXCAN_MCR_AWUM | + BXCAN_MCR_NART | BXCAN_MCR_RFLM, BXCAN_MCR_TXFP); + + /* Bit timing register settings */ + set = BXCAN_BTR_BRP(bt->brp - 1) | + BXCAN_BTR_TS1(bt->phase_seg1 + bt->prop_seg - 1) | + BXCAN_BTR_TS2(bt->phase_seg2 - 1) | BXCAN_BTR_SJW(bt->sjw - 1); + + /* loopback + silent mode put the controller in test mode, + * useful for hot self-test + */ + if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) + set |= BXCAN_BTR_LBKM; + + if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) + set |= BXCAN_BTR_SILM; + + netdev_dbg(ndev, + "TQ[ns]: %d, PrS: %d, PhS1: %d, PhS2: %d, SJW: %d, BRP: %d, CAN_BTR: 0x%08x\n", + bt->tq, bt->prop_seg, bt->phase_seg1, bt->phase_seg2, + bt->sjw, bt->brp, set); + bxcan_rmw(®s->btr, BXCAN_BTR_SILM | BXCAN_BTR_LBKM | + BXCAN_BTR_BRP_MASK | BXCAN_BTR_TS1_MASK | BXCAN_BTR_TS2_MASK | + BXCAN_BTR_SJW_MASK, set); + + bxcan_enable_filters(priv->dev->parent, priv->master); + + err = bxcan_leave_init_mode(priv); + if (err) { + netdev_err(ndev, "failed to leave init mode, error %d\n", err); + goto failed_leave_init; + } + + /* Set a `lec` value so that we can check for updates later */ + bxcan_rmw(®s->esr, BXCAN_ESR_LEC, LEC_UNUSED << BXCAN_ESR_LEC_SHIFT); + + /* IER + * + * Enable interrupt for: + * bus-off + * passive error + * warning error + * last error code + * RX FIFO pending message + * TX mailbox empty + */ + bxcan_rmw(®s->ier, BXCAN_IER_WKUIE | BXCAN_IER_SLKIE | + BXCAN_IER_FOVIE1 | BXCAN_IER_FFIE1 | BXCAN_IER_FMPIE1 | + BXCAN_IER_FOVIE0 | BXCAN_IER_FFIE0, + BXCAN_IER_ERRIE | BXCAN_IER_LECIE | BXCAN_IER_BOFIE | + BXCAN_IER_EPVIE | BXCAN_IER_EWGIE | BXCAN_IER_FMPIE0 | + BXCAN_IER_TMEIE); + + priv->can.state = CAN_STATE_ERROR_ACTIVE; + return 0; + +failed_leave_init: +failed_enter_init: +failed_leave_sleep: + bxcan_chip_softreset(priv); + return err; +} + +static int bxcan_open(struct net_device *ndev) +{ + struct bxcan_priv *priv = netdev_priv(ndev); + int err; + + err = open_candev(ndev); + if (err) { + netdev_err(ndev, "open_candev() failed, error %d\n", err); + goto failed_open; + } + + napi_enable(&priv->napi); + err = request_irq(ndev->irq, bxcan_rx_isr, IRQF_SHARED, ndev->name, + ndev); + if (err) { + netdev_err(ndev, "failed to register rx irq(%d), error %d\n", + ndev->irq, err); + goto failed_rx_irq_request; + } + + err = request_irq(priv->tx_irq, bxcan_tx_isr, IRQF_SHARED, ndev->name, + ndev); + if (err) { + netdev_err(ndev, "failed to register tx irq(%d), error %d\n", + priv->tx_irq, err); + goto failed_tx_irq_request; + } + + err = request_irq(priv->sce_irq, bxcan_state_change_isr, IRQF_SHARED, + ndev->name, ndev); + if (err) { + netdev_err(ndev, "failed to register sce irq(%d), error %d\n", + priv->sce_irq, err); + goto failed_sce_irq_request; + } + + err = bxcan_start(ndev); + if (err) + goto failed_start; + + netif_start_queue(ndev); + return 0; + +failed_start: +failed_sce_irq_request: + free_irq(priv->tx_irq, ndev); +failed_tx_irq_request: + free_irq(ndev->irq, ndev); +failed_rx_irq_request: + napi_disable(&priv->napi); + close_candev(ndev); +failed_open: + return err; +} + +static void bxcan_stop(struct net_device *ndev) +{ + struct bxcan_priv *priv = netdev_priv(ndev); + + bxcan_disable_filters(priv->dev->parent, priv->master); + bxcan_enter_sleep_mode(priv); + priv->can.state = CAN_STATE_STOPPED; +} + +static int bxcan_close(struct net_device *ndev) +{ + struct bxcan_priv *priv = netdev_priv(ndev); + + netif_stop_queue(ndev); + bxcan_stop(ndev); + free_irq(ndev->irq, ndev); + free_irq(priv->tx_irq, ndev); + free_irq(priv->sce_irq, ndev); + napi_disable(&priv->napi); + close_candev(ndev); + return 0; +} + +static netdev_tx_t bxcan_start_xmit(struct sk_buff *skb, + struct net_device *ndev) +{ + struct bxcan_priv *priv = netdev_priv(ndev); + struct can_frame *cf = (struct can_frame *)skb->data; + struct bxcan_regs *regs = priv->regs; + struct bxcan_mb *mb_regs; + unsigned int mb_id; + u32 id, tsr; + int i, j; + + if (can_dropped_invalid_skb(ndev, skb)) + return NETDEV_TX_OK; + + tsr = readl(®s->tsr); + mb_id = ffs((tsr & BXCAN_TSR_TME) >> BXCAN_TSR_TME_SHIFT); + if (mb_id == 0) + return NETDEV_TX_BUSY; + + mb_id -= 1; + mb_regs = ®s->tx_mb[mb_id]; + + if (cf->can_id & CAN_EFF_FLAG) + id = BXCAN_TIxR_EXID(cf->can_id & CAN_EFF_MASK) | + BXCAN_TIxR_IDE; + else + id = BXCAN_TIxR_STID(cf->can_id & CAN_SFF_MASK); + + if (cf->can_id & CAN_RTR_FLAG) + id |= BXCAN_TIxR_RTR; + + bxcan_rmw(&mb_regs->dlc, BXCAN_TDTxR_DLC_MASK, + BXCAN_TDTxR_DLC(cf->len)); + priv->tx_dlc[mb_id] = cf->len; + + for (i = 0, j = 0; i < cf->len; i += 4, j++) + writel(*(u32 *)(cf->data + i), &mb_regs->data[j]); + + /* Start transmission */ + writel(id | BXCAN_TIxR_TXRQ, &mb_regs->id); + /* Stop the queue if we've filled all mailbox entries */ + if (!(readl(®s->tsr) & BXCAN_TSR_TME)) + netif_stop_queue(ndev); + + return NETDEV_TX_OK; +} + +static const struct net_device_ops bxcan_netdev_ops = { + .ndo_open = bxcan_open, + .ndo_stop = bxcan_close, + .ndo_start_xmit = bxcan_start_xmit, + .ndo_change_mtu = can_change_mtu, +}; + +static void bxcan_rx_pkt(struct net_device *ndev, struct bxcan_mb *mb_regs) +{ + struct net_device_stats *stats = &ndev->stats; + struct can_frame *cf; + struct sk_buff *skb; + u32 id, dlc; + + skb = alloc_can_skb(ndev, &cf); + if (!skb) { + stats->rx_dropped++; + return; + } + + id = readl(&mb_regs->id); + if (id & BXCAN_RIxR_IDE) + cf->can_id = (id >> BXCAN_RIxR_EXID_SHIFT) | CAN_EFF_FLAG; + else + cf->can_id = (id >> BXCAN_RIxR_STID_SHIFT) & CAN_SFF_MASK; + + dlc = readl(&mb_regs->dlc) & BXCAN_RDTxR_DLC; + cf->len = can_cc_dlc2len(dlc); + + if (id & BXCAN_RIxR_RTR) { + cf->can_id |= CAN_RTR_FLAG; + } else { + int i, j; + + for (i = 0, j = 0; i < cf->len; i += 4, j++) + *(u32 *)(cf->data + i) = readl(&mb_regs->data[j]); + } + + stats->rx_bytes += cf->len; + stats->rx_packets++; + netif_receive_skb(skb); +} + +static int bxcan_rx_poll(struct napi_struct *napi, int quota) +{ + struct net_device *ndev = napi->dev; + struct bxcan_priv *priv = netdev_priv(ndev); + struct bxcan_regs *regs = priv->regs; + int num_pkts; + u32 rf0r; + + for (num_pkts = 0; num_pkts < quota; num_pkts++) { + rf0r = readl(®s->rf0r); + if (!(rf0r & BXCAN_RF0R_FMP0)) + break; + + bxcan_rx_pkt(ndev, ®s->rx_mb[0]); + + rf0r |= BXCAN_RF0R_RFOM0; + writel(rf0r, ®s->rf0r); + } + + if (num_pkts < quota) { + napi_complete_done(napi, num_pkts); + bxcan_rmw(®s->ier, 0, BXCAN_IER_FMPIE0); + } + + return num_pkts; +} + +static int bxcan_do_set_mode(struct net_device *ndev, enum can_mode mode) +{ + int err; + + switch (mode) { + case CAN_MODE_START: + err = bxcan_start(ndev); + if (err) + return err; + + netif_wake_queue(ndev); + break; + default: + return -EOPNOTSUPP; + } + + return 0; +} + +static int bxcan_disable_clks(struct bxcan_priv *priv) +{ + if (priv->clk) + clk_disable_unprepare(priv->clk); + + bxcan_disable_master_clk(priv->dev->parent); + return 0; +} + +static int bxcan_enable_clks(struct bxcan_priv *priv) +{ + int err; + + err = bxcan_enable_master_clk(priv->dev->parent); + if (err) + return err; + + if (priv->clk) { + err = clk_prepare_enable(priv->clk); + if (err) + bxcan_disable_master_clk(priv->dev->parent); + } + + return err; +} + +static int bxcan_get_berr_counter(const struct net_device *ndev, + struct can_berr_counter *bec) +{ + struct bxcan_priv *priv = netdev_priv(ndev); + struct bxcan_regs *regs = priv->regs; + u32 esr; + int err; + + err = bxcan_enable_clks(priv); + if (err) + return err; + + esr = readl(®s->esr); + bec->txerr = BXCAN_TEC(esr); + bec->rxerr = BXCAN_REC(esr); + err = bxcan_disable_clks(priv); + return 0; +} + +static int bxcan_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct device *dev = &pdev->dev; + struct net_device *ndev; + struct bxcan_priv *priv; + struct clk *clk = NULL; + bool master; + u32 offset; + int err, rx_irq, tx_irq, sce_irq; + + master = of_property_read_bool(np, "master"); + if (!master) { + clk = devm_clk_get(dev, NULL); + if (IS_ERR(clk)) { + dev_err(dev, "failed to get clock\n"); + return PTR_ERR(clk); + } + } + + rx_irq = platform_get_irq_byname(pdev, "rx0"); + if (rx_irq < 0) { + dev_err(dev, "failed to get rx0 irq\n"); + return rx_irq; + } + + tx_irq = platform_get_irq_byname(pdev, "tx"); + if (tx_irq < 0) { + dev_err(dev, "failed to get tx irq\n"); + return tx_irq; + } + + sce_irq = platform_get_irq_byname(pdev, "sce"); + if (sce_irq < 0) { + dev_err(dev, "failed to get sce irq\n"); + return sce_irq; + } + + err = of_property_read_u32(np, "reg", &offset); + if (err) { + dev_err(dev, "failed to get reg property\n"); + return err; + } + + ndev = alloc_candev(sizeof(struct bxcan_priv), 1); + if (!ndev) { + dev_err(dev, "alloc_candev() failed\n"); + return -ENOMEM; + } + + priv = netdev_priv(ndev); + platform_set_drvdata(pdev, ndev); + SET_NETDEV_DEV(ndev, dev); + ndev->netdev_ops = &bxcan_netdev_ops; + ndev->irq = rx_irq; + + priv->dev = dev; + priv->regs = bxcan_get_base_addr(dev->parent) + offset; + priv->clk = clk; + priv->tx_irq = tx_irq; + priv->sce_irq = sce_irq; + priv->master = master; + priv->can.clock.freq = + master ? bxcan_get_master_clk_rate(dev->parent) : + clk_get_rate(clk); + priv->can.bittiming_const = &bxcan_bittiming_const; + priv->can.do_set_mode = bxcan_do_set_mode; + priv->can.do_get_berr_counter = bxcan_get_berr_counter; + priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK | + CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_BERR_REPORTING; + netif_napi_add(ndev, &priv->napi, bxcan_rx_poll, BXCAN_NAPI_WEIGHT); + + err = bxcan_enable_clks(priv); + if (err) { + dev_err(dev, "failed to enable clocks\n"); + return err; + } + + err = register_candev(ndev); + if (err) { + dev_err(dev, "failed to register netdev\n"); + goto failed_register; + } + + dev_info(dev, "regs: %px, clk: %d Hz, IRQs: %d, %d, %d\n", + priv->regs, priv->can.clock.freq, tx_irq, rx_irq, + sce_irq); + return 0; + +failed_register: + netif_napi_del(&priv->napi); + free_candev(ndev); + return err; +} + +static int bxcan_remove(struct platform_device *pdev) +{ + struct net_device *ndev = platform_get_drvdata(pdev); + struct bxcan_priv *priv = netdev_priv(ndev); + + unregister_candev(ndev); + bxcan_disable_clks(priv); + netif_napi_del(&priv->napi); + free_candev(ndev); + return 0; +} + +static int __maybe_unused bxcan_suspend(struct device *dev) +{ + struct net_device *ndev = dev_get_drvdata(dev); + struct bxcan_priv *priv = netdev_priv(ndev); + + if (!netif_running(ndev)) + return 0; + + netif_stop_queue(ndev); + netif_device_detach(ndev); + + bxcan_enter_sleep_mode(priv); + priv->can.state = CAN_STATE_SLEEPING; + bxcan_disable_clks(priv); + return 0; +} + +static int __maybe_unused bxcan_resume(struct device *dev) +{ + struct net_device *ndev = dev_get_drvdata(dev); + struct bxcan_priv *priv = netdev_priv(ndev); + + if (!netif_running(ndev)) + return 0; + + bxcan_enable_clks(priv); + bxcan_leave_sleep_mode(priv); + priv->can.state = CAN_STATE_ERROR_ACTIVE; + + netif_device_attach(ndev); + netif_start_queue(ndev); + return 0; +} + +static SIMPLE_DEV_PM_OPS(bxcan_pm_ops, bxcan_suspend, bxcan_resume); + +static const struct of_device_id bxcan_of_match[] = { + {.compatible = "st,stm32-bxcan"}, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, bxcan_of_match); + +static struct platform_driver bxcan_driver = { + .driver = { + .name = KBUILD_MODNAME, + .pm = &bxcan_pm_ops, + .of_match_table = bxcan_of_match, + }, + .probe = bxcan_probe, + .remove = bxcan_remove, +}; + +module_platform_driver(bxcan_driver); + +MODULE_AUTHOR("Dario Binacchi "); +MODULE_DESCRIPTION("STMicroelectronics Basic Extended CAN controller driver"); +MODULE_LICENSE("GPL");