From nobody Fri Oct 2 01:57:45 2026 Received: from BYAPR05CU005.outbound.protection.outlook.com (mail-westusazon11020103.outbound.protection.outlook.com [52.101.85.103]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3F18530DEA3; Thu, 6 Aug 2026 09:01:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.85.103 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786006901; cv=fail; b=VLUwRgC9HecwmnRl78GbQVQ7/tvlco3R7zVokRCiZo4gAnwG2jSxL/dyJ53HJ2fQ8k7+pOPkp0JBnwLyTWGU/zrMAQm20907SNQmBUifMiZiRhSWetVeCxyIUNSWnp1N9NLb989YBOwubMHdrHB0AOpB/7fM9RyADufTxKBLkNw= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786006901; c=relaxed/simple; bh=0AjNPWV5OPhrQhjPlrG6C5c7ICRCle76yQboEFhoosQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=EFw3bdEV13duPo9QhILRqCsWqbdFidEtswRtH/8y/Bx6nL+nMtTGmi/GZF3NT6N8gg8wbRxRBc6XfxfWkB/2HzlFEIiw+7WVJ3d0RVVO2PMI3yRynaucekRCfFBfJ1yaXswzqjebzpbjxjXHgCA0nSvkwmdTEmP62XXt9BubpDw= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=axiado.com; spf=pass smtp.mailfrom=axiado.com; dkim=pass (2048-bit key) header.d=axiado.com header.i=@axiado.com header.b=bBONLShZ; arc=fail smtp.client-ip=52.101.85.103 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=axiado.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=axiado.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=axiado.com header.i=@axiado.com header.b="bBONLShZ" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=w84G5CqXi4g9q/JzACxj7A6qg2KGfyQ+IZrPrC9ZAccleRtzQ5Bl/fziJWCS1nIrft1u2DCY8+T/vwcjdp1y8EDs0/a0BI57Z6ENf/4VGm69EX71IjL9CaWtaDdk9jmhdSfuTEESg4/Uo57AC8/wOHzoixApOLTANM2OLiwVgz3+g0LNeKbcub9iQvEwZvw5J51ZEkieHC6a/BaeeUJe8mPF/7iep6YGHDYhH8kpVGfy1x1cuhDWTUXzxjck59uBEipT1wUMkd6a6RllxLDJtV2mXlLL9tTfEIfQh9sxbbWV+wQdxqJEROZRxxqQ5aW9aFRsYKGP04m6kjt8CeCpJA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=5cumNkGH2fsBGNARNBjuk9zDJze4M94YJWYb1DucRGM=; b=GzTTDFHIF7Kl+09pBI2YoR5eB2PPePZm/kMv9ve7z3lYWITXq8yvXnUdx3ivu735tYz5fHpvWbOXhl8QUOSMjSm02umeFKpl5We3xdM0D8PyjccKurx7V1dxsVI1z4aDjT2XheIyvNLvLD6sL7xUCSyNL3ybP4BvuRlzyLlLBKcDO+Xo1AmwL9WtQIAx0N3KNKv2AWUNAomCLMX0NfdLeXFgft4dACLyEeO0p6OcZHYo9dfDyGffeAZEmxtlCN5ut57ERB7SklIyVi0RlyZN/a68afCXsIz4yBe0pR/iLfiPVWR3UI7Z3m/4yZzBeDZ03iLwBepLaO9p3350qSiaFw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=fail (sender ip is 64.62.143.114) smtp.rcpttodomain=axiado.com smtp.mailfrom=axiado.com; dmarc=none action=none header.from=axiado.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=axiado.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=5cumNkGH2fsBGNARNBjuk9zDJze4M94YJWYb1DucRGM=; b=bBONLShZYAvFGSEIYoE7y7k1ksFkvs72nc0CgHv5nO0C+PfIEe7THmdv8hocNkaVtJDeMTh07D/TpLp3drOyFT5Y+sYDNTkbqmhuVDr+qw94eYBZ3RBpXtBRB0SQ2ewbzu2m5Dy+G79iLfjdm49VpxxKMJIpXfJ82gYAey6yQggwQTqtxTkYLMwAS4XfacACpR3U1VmBsKt8TVouI/VqYHS5b0gZfYVz5uvngoUbjgYrtJestjqy1540PHPsgdcRewLDnKEh4FOfemS1GZoBhPaciJiaRgFP3XTSteP5SYtBm1XbvUzMNrluOm3Fkb4vWx29r3aDj3d0ueID1NeI2A== Received: from SJ0PR03CA0196.namprd03.prod.outlook.com (2603:10b6:a03:2ef::21) by SA3PR18MB5391.namprd18.prod.outlook.com (2603:10b6:806:2f3::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.292.19; Thu, 6 Aug 2026 09:01:36 +0000 Received: from SJ1PEPF000023D2.namprd02.prod.outlook.com (2603:10b6:a03:2ef:cafe::26) by SJ0PR03CA0196.outlook.office365.com (2603:10b6:a03:2ef::21) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.292.19 via Frontend Transport; Thu, 6 Aug 2026 09:01:36 +0000 X-MS-Exchange-Authentication-Results: spf=fail (sender IP is 64.62.143.114) smtp.mailfrom=axiado.com; dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=axiado.com; Received-SPF: Fail (protection.outlook.com: domain of axiado.com does not designate 64.62.143.114 as permitted sender) receiver=protection.outlook.com; client-ip=64.62.143.114; helo=smtp.corp.axiado.com; Received: from smtp.corp.axiado.com (64.62.143.114) by SJ1PEPF000023D2.mail.protection.outlook.com (10.167.244.9) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.315.6 via Frontend Transport; Thu, 6 Aug 2026 09:01:35 +0000 Received: from axz-uw1-build-vm02.corp.axiado.com (unknown [10.14.1.22]) by smtp.corp.axiado.com (Postfix) with ESMTP id 8B4984186B58; Thu, 6 Aug 2026 02:01:35 -0700 (PDT) From: Petar Stepanovic Date: Thu, 06 Aug 2026 02:01:29 -0700 Subject: [PATCH 1/2] dt-bindings: hwmon: add Axiado AX3000 and AX3005 PWM fan controller Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260806-axiado-ax3000-pwm-fan-v1-1-f6db4cf2166b@axiado.com> References: <20260806-axiado-ax3000-pwm-fan-v1-0-f6db4cf2166b@axiado.com> In-Reply-To: <20260806-axiado-ax3000-pwm-fan-v1-0-f6db4cf2166b@axiado.com> To: Petar Stepanovic , Akhila Kavi , Prasad Bolisetty , Guenter Roeck , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Harshit Shah , =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Tzu-Hao Wei , Karthikeyan Mitran , Jonathan Corbet , Shuah Khan Cc: linux-hwmon@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-pwm@vger.kernel.org, linux-doc@vger.kernel.org X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786006895; l=3222; i=pstepanovic@axiado.com; s=20250916; h=from:subject:message-id; bh=0AjNPWV5OPhrQhjPlrG6C5c7ICRCle76yQboEFhoosQ=; b=ntmYImKE9EO1zK/rQXo5qJwdIotDKd1YGbfZWuzYV83+acbAYrKEilY/j9UPaLZkVL+pw+qPg XXea6ws0rygDhRMf/BNvfLFf14WLlYSNuToF/VLB6j+Z4i8OfybQq7t X-Developer-Key: i=pstepanovic@axiado.com; a=ed25519; pk=70f1UJOGT9U11ZK6o+ENXtv0I5wBE3e+Y9YWODzRsdI= X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ1PEPF000023D2:EE_|SA3PR18MB5391:EE_ X-MS-Office365-Filtering-Correlation-Id: 19e26bbb-3e39-4fe1-9d3f-08def399519c X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|23010399003|1800799024|36860700016|82310400026|7416014|376014|10067099003|56012099006|3023799007|18002099003|22082099003|921020; X-Microsoft-Antispam-Message-Info: W3HMMw/e9KJQ7VZoDBXkUJxp/y7tVSmJqsxHKrcvU5pIJAy/ODDyF57Cwcv/I4Al9SHR3wuAhTrKuUU9Mvs4Shn1SvNE1tWEm0mzh6sx2kyBXgNn8jFtSnl24vgVx9WGtRHHrRIT3IuVn0iQCPhqE8rj8pjPXVCMidTBe8dAkaL8YYKtYImnnLn+xCABPvnG9TEylCvK54SR3E75IMy0nMPgZEvrmbJsGWM0OQoUlk+ddjyQuxhlaUFOQkDcwTCmvxhN7pvva+C/9WXqEHzdeiDvpzjb2qWYoCDl/p2lDdZivPcDVLNtQ1IkfzieIy0e6LXaJdiJVtsTYPMj5R+hBVG1uBAWwleN1qmQl2UO1Cg3D6c88a8jgsy5oa+5S0toi+DRuoDGXDjXwrs+zkh1xIPg+hOIwmGAr907VIT4094ySICpn3BYepDTqxI3av1SzMIBeV0k3eZiQU/ei5P5z7tpbr8YFXe6NsTZSGPoelTLaESmP+MjV1wTkyGsRnsT6B23GyEfit7C1+A/w8o6SC4XV+7ufDmgO06gzGvA55ZSZDzPloLGrOiamM4DdWyWgCScCTMqgRs8/tvJbi/YXyVOQoebx1/9FmY5WxdLe1MfOrHwV7Xdd733fl6k443CSx3gR3E835RBzaIv5K5FpdSIGQXfaw1WutjhjjRkSw44VwQ+ksjpJj4ujRRFcME6nfqg0wZ9fBw/XZuWoduk0cG77cHVVrBGqY2f7Ww5EU1jzoPmTgNhiXxMFTu+hm7b X-Forefront-Antispam-Report: CIP:64.62.143.114;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:smtp.corp.axiado.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(23010399003)(1800799024)(36860700016)(82310400026)(7416014)(376014)(10067099003)(56012099006)(3023799007)(18002099003)(22082099003)(921020);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: kWQDZBoAoJyWSShn8BRUsULSJEe6eEQjY5tSjaD0dATShEmgpQ2J68Nto11McmWaBm1+PxAgG8HH9AMK0E8qisxTobDq0iJm/+AWNJ/1eQCwcRQ8UQ+XB7PAJtdjwkcefII+TfrIy7x0yjsVw9ZYbjygf9olhdqGFNiwLx0b/DZ5/Rd/XiAvRKVl5afcu+Lib99kwwRQlIj6cQ30J6pyA9svAlObZuQHpRvFrPwV8gDQedQeTOLX5kHdYorDL66WprXX9Q1ySTYsROemrASpbwdHuOeulfEULUlbEyWxEQvR3IEssIWg+XADunDVmrcNGxyGdwKTbbpoLVf6Bav0YaRIetV7a45NM53lNbOt+4/VErQM8mHUzkN2JKidbYqf0WjqBEmmTuSFJ5pibUz1FXbc5Skt2L6T/beriMmxub2z4YOk2OvJQx5Q43kmyA1X X-OriginatorOrg: axiado.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 06 Aug 2026 09:01:35.7482 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 19e26bbb-3e39-4fe1-9d3f-08def399519c X-MS-Exchange-CrossTenant-Id: ff2db17c-4338-408e-9036-2dee8e3e17d7 X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=ff2db17c-4338-408e-9036-2dee8e3e17d7;Ip=[64.62.143.114];Helo=[smtp.corp.axiado.com] X-MS-Exchange-CrossTenant-AuthSource: SJ1PEPF000023D2.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: SA3PR18MB5391 Add a Devicetree binding for the PWM fan controller found on the Axiado AX3000 and AX3005 SoCs. The controller measures fan speed using a hardware tachometer block. Fan speed is controlled through a PWM signal supplied by an external PWM controller. Add a MAINTAINERS entry for the binding. Signed-off-by: Petar Stepanovic --- .../bindings/hwmon/axiado,ax3000-pwm-fan.yaml | 68 ++++++++++++++++++= ++++ MAINTAINERS | 8 +++ 2 files changed, 76 insertions(+) diff --git a/Documentation/devicetree/bindings/hwmon/axiado,ax3000-pwm-fan.= yaml b/Documentation/devicetree/bindings/hwmon/axiado,ax3000-pwm-fan.yaml new file mode 100644 index 000000000000..a985f49bbdcd --- /dev/null +++ b/Documentation/devicetree/bindings/hwmon/axiado,ax3000-pwm-fan.yaml @@ -0,0 +1,68 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/hwmon/axiado,ax3000-pwm-fan.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Axiado AX3000 and AX3005 PWM Fan Controller + +maintainers: + - Petar Stepanovic + - Akhila Kavi + - Prasad Bolisetty + +description: + The Axiado AX3000 and AX3005 fan controllers use a hardware tachometer + block to measure fan speed. Fan speed is controlled through a PWM signal + supplied by an external PWM controller. + +properties: + compatible: + oneOf: + - const: axiado,ax3000-pwm-fan + - items: + - const: axiado,ax3005-pwm-fan + - const: axiado,ax3000-pwm-fan + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 1 + + pwms: + maxItems: 1 + description: + PWM specifier used to control fan speed. + + pulses-per-revolution: + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 1 + default: 2 + description: + Number of tachometer pulses generated per fan revolution. + +required: + - compatible + - reg + - interrupts + - clocks + - pwms + +additionalProperties: false + +examples: + - | + #include + + fan@33001400 { + compatible =3D "axiado,ax3000-pwm-fan"; + reg =3D <0x0 0x33001400 0x0 0x400>; + interrupts =3D ; + clocks =3D <&clk>; + pwms =3D <&pwm0 0 400>; + }; +... diff --git a/MAINTAINERS b/MAINTAINERS index a674e36529f7..f528b1a42e0f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4457,6 +4457,14 @@ W: https://ez.analog.com/linux-software-drivers F: Documentation/devicetree/bindings/pwm/adi,axi-pwmgen.yaml F: drivers/pwm/pwm-axi-pwmgen.c =20 +AXIADO PWM FAN CONTROLLER DRIVER +M: Petar Stepanovic +M: Akhila Kavi +M: Prasad Bolisetty +L: linux-hwmon@vger.kernel.org +S: Supported +F: Documentation/devicetree/bindings/hwmon/axiado,ax3000-pwm-fan.yaml + AXIADO SPI DB DRIVER M: Vladimir Moravcevic M: Tzu-Hao Wei --=20 2.34.1 From nobody Fri Oct 2 01:57:45 2026 Received: from CO1PR03CU002.outbound.protection.outlook.com (mail-westus2azon11020127.outbound.protection.outlook.com [52.101.46.127]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 34E923EE1E5; Thu, 6 Aug 2026 09:01:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.46.127 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786006901; cv=fail; b=lPL8kKB99paH3WhMqoKrC7UTthZAWE5inYAb/fSwE5qHANU3tQiL29dJJJHeJAFrx8eyhl7Bj7pHxzfFcGGS+XenPhLjeEzXnQh9fM7khrPATcc2eB1+QtwRj6l5b0tMAVoJ3tDdqfnnq7J/kIiXAHhawCZ1k5JL6wlqbyWoRv0= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786006901; c=relaxed/simple; bh=Z77WBjh0Aq+oBYpObsNok2aBwqUPPNoxqyDI9zAhbZc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=oD4y7cKUcQZC1qzHJLMtBzl7v3B9sMIXgTz8th+iVRu3AORMPSO58Igq9SCELZecYSa24BZxP05XzIUdbLiS8q+MU71mmxk07Ku3DgmorwBLIvnqZpjuQ/keNtKpupDaOrhWX/mGUru+tKW/rJ7CET3jVbTFCY31LTkWCvVrRFg= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=axiado.com; spf=pass smtp.mailfrom=axiado.com; dkim=pass (2048-bit key) header.d=axiado.com header.i=@axiado.com header.b=qtqDORKT; arc=fail smtp.client-ip=52.101.46.127 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=axiado.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=axiado.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=axiado.com header.i=@axiado.com header.b="qtqDORKT" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=ejndZ6w7q2UXUokT+0egnZPdJ20SGevGQ0CHhMa+tltzBTU7HekbWoxeay3ZTcl9DtaY/EHCAB0m3wnQKH//88umar7R2o1sHfaP8RG5bqmz4JRKb3zukiJxKrwvHbTaBffiaOnPdyyi4ClrBzkYR/2ha8WeTZzLDN14RaZUhnch9yH87ZYhkGaiiNW3tzjnVtemJc17SUXq/Tg0SakeSjFtsuX3LdJKLNegerkcIc/CKCJg435sVWjxPqWjaxdgbCaoSwskiAu9XxSt0f8JkfLS8VxLOiACaQcxjfjZGybpF0ObM4C85g3yFZWo6Li0n4/pM4+CZRgcpOoki2QO3w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=GQdBpwmy1p6NJAKv+mWKwiZ+G/Txt/w3AU9gQqqYqGs=; b=PdI3aRMM7Keh57KOMTvCfeI1rr/oZZghxSjsnaljIzR6l2pHntRYxnOVe457B4y43fCwCDl1plnQ2mdFaYkhJjhxGevAuWe8+Qvfs1cK0n2fgKhdOkaBwxEGVi5wdo+BTJ4HY5A0BFHLMZHbgdhswXADR76AxMpe//dar8FYNkm05A4NuVewZSlx8nyE9k3y5GCCA1u8IG6YeHZ1svH10FUR+BragyatdpTne0BZcwjHWNLiXryUJcGxn0mRcN0ikr+dgHV/WhJSvvq3qW0uwof4VC0qnn9r/S/u1qHSIE70jXncwXuTo0WBdmUNghOikiUgZdSQ/NnQAr8sA9lwoA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=fail (sender ip is 64.62.143.114) smtp.rcpttodomain=axiado.com smtp.mailfrom=axiado.com; dmarc=none action=none header.from=axiado.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=axiado.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=GQdBpwmy1p6NJAKv+mWKwiZ+G/Txt/w3AU9gQqqYqGs=; b=qtqDORKTZYKpV8FsTEIbAZ2HGbn9bmGL4ewONY0BQektgVObzgWAGUutxL4CyhHNPQYhFhvrblNr0r/kXOKlKqhiAz0HUeQZRJ1vvjP+FFkaBNLo8ZIoFLA/rlQvBeiffPafUi18x+CCTPskhEuji27yocP3wPuJiS63P2qinejvpTMYiBFMYToBRO1uz5o+bgXi7gSm7JIfR2ID31gutMC54inVN5p99wsqGDAuxkEtzhs9itsq7grKjSkQgZiuTx7IdG7yOjyqSJ/5UoYtEeSuvGbn84I0Lu5fI8AUt7n2aa263ZQwqX4/24PigrbS5Qnktq9XRj1Co5BGuuE6Eg== Received: from SA9PR03CA0006.namprd03.prod.outlook.com (2603:10b6:806:20::11) by BN9PR18MB4363.namprd18.prod.outlook.com (2603:10b6:408:101::20) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.292.20; Thu, 6 Aug 2026 09:01:36 +0000 Received: from SA2PEPF00003F61.namprd04.prod.outlook.com (2603:10b6:806:20:cafe::62) by SA9PR03CA0006.outlook.office365.com (2603:10b6:806:20::11) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.292.21 via Frontend Transport; Thu, 6 Aug 2026 09:01:36 +0000 X-MS-Exchange-Authentication-Results: spf=fail (sender IP is 64.62.143.114) smtp.mailfrom=axiado.com; dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=axiado.com; Received-SPF: Fail (protection.outlook.com: domain of axiado.com does not designate 64.62.143.114 as permitted sender) receiver=protection.outlook.com; client-ip=64.62.143.114; helo=smtp.corp.axiado.com; Received: from smtp.corp.axiado.com (64.62.143.114) by SA2PEPF00003F61.mail.protection.outlook.com (10.167.248.36) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.315.6 via Frontend Transport; Thu, 6 Aug 2026 09:01:36 +0000 Received: from axz-uw1-build-vm02.corp.axiado.com (unknown [10.14.1.22]) by smtp.corp.axiado.com (Postfix) with ESMTP id 9B4324186B59; Thu, 6 Aug 2026 02:01:35 -0700 (PDT) From: Petar Stepanovic Date: Thu, 06 Aug 2026 02:01:30 -0700 Subject: [PATCH 2/2] hwmon: add Axiado AX3000 and AX3005 PWM fan controller driver Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260806-axiado-ax3000-pwm-fan-v1-2-f6db4cf2166b@axiado.com> References: <20260806-axiado-ax3000-pwm-fan-v1-0-f6db4cf2166b@axiado.com> In-Reply-To: <20260806-axiado-ax3000-pwm-fan-v1-0-f6db4cf2166b@axiado.com> To: Petar Stepanovic , Akhila Kavi , Prasad Bolisetty , Guenter Roeck , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Harshit Shah , =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Tzu-Hao Wei , Karthikeyan Mitran , Jonathan Corbet , Shuah Khan Cc: linux-hwmon@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-pwm@vger.kernel.org, linux-doc@vger.kernel.org X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786006895; l=14838; i=pstepanovic@axiado.com; s=20250916; h=from:subject:message-id; bh=Z77WBjh0Aq+oBYpObsNok2aBwqUPPNoxqyDI9zAhbZc=; b=ikA2Ko+PqUaSG7rZPtJXgoIuF/QGtjICdqthFeULM3REmj0ZGQHTCdIX64vEwDZmRfQjJRm5d uWeVJSYAMm8DoO0k9592dOvbC6DOWqOaQgV8hZ8BhvPlKHkpp8pBJ4f X-Developer-Key: i=pstepanovic@axiado.com; a=ed25519; pk=70f1UJOGT9U11ZK6o+ENXtv0I5wBE3e+Y9YWODzRsdI= X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SA2PEPF00003F61:EE_|BN9PR18MB4363:EE_ X-MS-Office365-Filtering-Correlation-Id: e3e91246-61d3-4b3d-8ccc-08def39951ef X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|376014|7416014|82310400026|1800799024|36860700016|23010399003|56012099006|10067099003|6133799003|3023799007|18002099003|22082099003|921020; X-Microsoft-Antispam-Message-Info: kOpt6xWtKml5bLQwiQagRHbKU1xWKa7X9WZdDN2Ie7FW5dD2s2y3BioSk85Vzlq2cLtmMgOM/l0hRJ1XDsGiNt7zrf5xXDpnQR0+ujbGRsfy6dsfSGH3E4M5m9O0nSVSeLx3SczF5OGo9hB6ksbrMGA4u4ydYr2p+GLorbakH8L5NNVVcWlXyqoGJjr+mnuXYvkcYcAiSMI49se5v/qjIp2mHsHTib9M88o+mKEXYOnvITmWX+MYHvp2A/+c2T6jbz6il30tXA2HLK+cU5XkESKJddK/+MVZpGIJ2rnRAeAMY1B6u0Pc7F8WmZ1cbCbMQKYXrRkdVLr3rfQd8UpXRzGsD1ZrTLs+Ijnk3RaFm/51B1VHtlsiSM9Pm3Lo2S4J38DOcRYG01B6BtYt+MS/pesaLtTBveiEapgxw9DCjTqmBuYkaBzFZlKNTjLldKx9lq/FWY2V2W+Risa76/q04wMJ46oJWAGpdmoVUfkoZIq4jDucpQDIPRnj/zwPSa6/uybsaIzlhxNst2ligdCzAklDuULS/5ebRPVXonkyADekcuaVSeHbcedehhG8Pcv/SmBUkFzh2/DuSxvUhZDpAanQ61jMd6TYebi2CMKC4BUgI026obwe4zw91xziTL76zjIYkMZDnpoO5PXkZjw5fPHwgAl2KoAM3e/heTcjtYGfKwi8aUfDN11Nf6VordTnXGx0ojt1tAKjwr2MF1CITu5LV2oy2kahbqMAxHd1CX4USPMxthp1Uoy0tlBB6mZO X-Forefront-Antispam-Report: CIP:64.62.143.114;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:smtp.corp.axiado.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(376014)(7416014)(82310400026)(1800799024)(36860700016)(23010399003)(56012099006)(10067099003)(6133799003)(3023799007)(18002099003)(22082099003)(921020);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: MG9pmjDT4ugr2RwnWf5Tyhzj0CkdaVB+Hb2CGLe2p9t/gKZqa03WF2UiqfeOwCkbkmGVnE0tAbs2JwAnIJCo1XamDtkTxW/o/OSPmZ1SSijhnvb1p9nDHrCyJ7v6jVtR6q/e/34hCXhJIgml55W7C6hsGkM3vauVFDTtbLkTIWmJLy/wGbXjJ8F3EJZbcTa+RGLCGrDqxDqau+FtJeeG+MEKoj23wk2zVrPXdiuEmxC18Mr9bSloFadHLMwm90w0/HWfTWcSRYq4LHNciRoOCaXAZOErDhy0i+SHu86bgEy14InEuA/2KjkeH6bPqwoL1+OQ5s/wUteRgzGTGk8WcxE/XldP9TOLCXeGSOfDo5QkrwCHkB9oc6dkVMp+X1jEto0prnIu6J4pVKtTfnIA1GOpZlvybCIOW+9Tks957Avm1Wvgs5C6hwtQs4qHkWxm X-OriginatorOrg: axiado.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 06 Aug 2026 09:01:36.1665 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: e3e91246-61d3-4b3d-8ccc-08def39951ef X-MS-Exchange-CrossTenant-Id: ff2db17c-4338-408e-9036-2dee8e3e17d7 X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=ff2db17c-4338-408e-9036-2dee8e3e17d7;Ip=[64.62.143.114];Helo=[smtp.corp.axiado.com] X-MS-Exchange-CrossTenant-AuthSource: SA2PEPF00003F61.namprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN9PR18MB4363 Add support for the PWM fan controller found on the Axiado AX3000 and AX3005 SoCs. The controller uses a hardware tachometer block and interrupt to measure fan speed. Fan speed is controlled through a PWM signal supplied by an external PWM controller. Register the controller with the hwmon subsystem and expose the standard fan1_input and pwm1 attributes. The number of tachometer pulses generated per fan revolution can be configured using the pulses-per-revolution Devicetree property. The driver was tested on AX3000 and AX3005 boards. Signed-off-by: Petar Stepanovic --- Documentation/hwmon/axiado-pwm-fan.rst | 38 ++++ Documentation/hwmon/index.rst | 1 + MAINTAINERS | 2 + drivers/hwmon/Kconfig | 12 + drivers/hwmon/Makefile | 1 + drivers/hwmon/axiado-pwm-fan.c | 389 +++++++++++++++++++++++++++++= ++++ 6 files changed, 443 insertions(+) diff --git a/Documentation/hwmon/axiado-pwm-fan.rst b/Documentation/hwmon/a= xiado-pwm-fan.rst new file mode 100644 index 000000000000..d110e170b0df --- /dev/null +++ b/Documentation/hwmon/axiado-pwm-fan.rst @@ -0,0 +1,38 @@ +.. SPDX-License-Identifier: GPL-2.0 + +Kernel driver axiado-pwm-fan +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D + +Supported chips: + + * Axiado AX3000 + * Axiado AX3005 + + Datasheet: Not publicly available + +Author: + + * Petar Stepanovic + +Description +----------- + +The Axiado AX3000 and AX3005 PWM fan controllers measure the rotational +speed of one fan using a hardware tachometer block. Fan speed is controlled +through a PWM signal supplied by an external PWM controller. + +The number of tachometer pulses generated per fan revolution is configured +through the ``pulses-per-revolution`` devicetree property. If the property +is not specified, the driver uses two pulses per revolution. + +Sysfs attributes +---------------- + +The driver provides the following standard hwmon attributes: + +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D =3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +fan1_input RO Fan speed in revolutions per minute (RPM). + +pwm1 RW Relative PWM control value from 0 to 255. A value of + 255 selects the maximum PWM duty cycle. +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D =3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D diff --git a/Documentation/hwmon/index.rst b/Documentation/hwmon/index.rst index 29130df44d12..857924205861 100644 --- a/Documentation/hwmon/index.rst +++ b/Documentation/hwmon/index.rst @@ -51,6 +51,7 @@ Hardware Monitoring Kernel Drivers asus_ec_sensors asus_rog_ryujin asus_wmi_sensors + axiado-pwm-fan bcm54140 bel-pfe bpa-rs600 diff --git a/MAINTAINERS b/MAINTAINERS index f528b1a42e0f..61e7a0939002 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4464,6 +4464,8 @@ M: Prasad Bolisetty L: linux-hwmon@vger.kernel.org S: Supported F: Documentation/devicetree/bindings/hwmon/axiado,ax3000-pwm-fan.yaml +F: Documentation/hwmon/axiado-pwm-fan.rst +F: drivers/hwmon/axiado-pwm-fan.c =20 AXIADO SPI DB DRIVER M: Vladimir Moravcevic diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 2bfbcc033d59..161054ba7312 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -469,6 +469,18 @@ config SENSORS_ATXP1 This driver can also be built as a module. If so, the module will be called atxp1. =20 +config SENSORS_AXIADO_PWM_FAN + tristate "Axiado PWM fan controller" + depends on ARCH_AXIADO || COMPILE_TEST + depends on PWM + help + This driver supports the Axiado PWM fan controller. It uses a PWM + output to control fan speed and a tachometer interrupt to report fan + speed as RPM through the hardware monitoring sysfs interface. + + This driver can also be built as a module. If so, the module will be + called axiado-pwm-fan. + config SENSORS_CGBC tristate "Congatec Board Controller Sensors" depends on MFD_CGBC diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 63effc0ab8d1..78fcb22a1777 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile @@ -58,6 +58,7 @@ obj-$(CONFIG_SENSORS_ASPEED) +=3D aspeed-pwm-tacho.o obj-$(CONFIG_SENSORS_ASPEED_G6) +=3D aspeed-g6-pwm-tach.o obj-$(CONFIG_SENSORS_ASUS_ROG_RYUJIN) +=3D asus_rog_ryujin.o obj-$(CONFIG_SENSORS_ATXP1) +=3D atxp1.o +obj-$(CONFIG_SENSORS_AXIADO_PWM_FAN) +=3D axiado-pwm-fan.o obj-$(CONFIG_SENSORS_AXI_FAN_CONTROL) +=3D axi-fan-control.o obj-$(CONFIG_SENSORS_CGBC) +=3D cgbc-hwmon.o obj-$(CONFIG_SENSORS_CHIPCAP2) +=3D chipcap2.o diff --git a/drivers/hwmon/axiado-pwm-fan.c b/drivers/hwmon/axiado-pwm-fan.c new file mode 100644 index 000000000000..b15bd3513d5e --- /dev/null +++ b/drivers/hwmon/axiado-pwm-fan.c @@ -0,0 +1,389 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2021-2026 Axiado Corporation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PWM_MAX 255 + +/* TACH Register offsets */ +#define AX_TACH_CTRL_REG 0x00 +#define AX_TACH_TIMER_COUNT_REG 0x04 +#define AX_TACH_COUNT_REG 0x08 +#define AX_TACH_INT_STATUS_REG 0x0c + +#define AX_TACH_CTRL_ENABLE BIT(0) +#define AX_TACH_CTRL_INT_ENABLE BIT(1) + +#define AX_TACH_INT_PENDING BIT(0) + +struct axiado_pwm_fan_tach { + int irq; + u32 pulses_per_revolution; + u32 timer_count; + u32 count; +}; + +struct axiado_pwm_fan_ctx { + /* Protects PWM state and cached PWM value. */ + struct mutex pwm_lock; + /* Protects tachometer count updated from interrupt context. */ + spinlock_t tach_lock; + struct pwm_device *pwm; + struct pwm_state pwm_state; + void __iomem *tach_base; + struct axiado_pwm_fan_tach tach; + unsigned int pwm_value; +}; + +static const struct hwmon_channel_info * const pwm_fan_info[] =3D { + HWMON_CHANNEL_INFO(pwm, HWMON_PWM_INPUT), + HWMON_CHANNEL_INFO(fan, HWMON_F_INPUT), + NULL +}; + +static irqreturn_t axiado_tach_irq_handler(int irq, void *dev) +{ + struct axiado_pwm_fan_ctx *ctx =3D dev; + u32 status; + + status =3D ioread32(ctx->tach_base + AX_TACH_INT_STATUS_REG); + + if (!status) + return IRQ_NONE; + + scoped_guard(spinlock_irqsave, &ctx->tach_lock) { + ctx->tach.count =3D ioread32(ctx->tach_base + AX_TACH_COUNT_REG); + } + + iowrite32(AX_TACH_INT_PENDING, ctx->tach_base + AX_TACH_INT_STATUS_REG); + + return IRQ_HANDLED; +} + +static int axiado_set_pwm(struct axiado_pwm_fan_ctx *ctx, unsigned int pwm) +{ + struct pwm_state state; + int ret; + + guard(mutex)(&ctx->pwm_lock); + + if (ctx->pwm_value =3D=3D pwm) + return 0; + + state =3D ctx->pwm_state; + state.duty_cycle =3D DIV_ROUND_UP_ULL((u64)pwm * state.period, PWM_MAX); + state.enabled =3D pwm > 0; + + ret =3D pwm_apply_might_sleep(ctx->pwm, &state); + if (ret) + return ret; + + ctx->pwm_state =3D state; + ctx->pwm_value =3D pwm; + + return 0; +} + +static int axiado_pwm_fan_write(struct device *dev, + enum hwmon_sensor_types type, u32 attr, + int channel, long val) +{ + struct axiado_pwm_fan_ctx *ctx =3D dev_get_drvdata(dev); + + if (type !=3D hwmon_pwm || attr !=3D hwmon_pwm_input) + return -EOPNOTSUPP; + + if (val < 0 || val > PWM_MAX) + return -EINVAL; + + return axiado_set_pwm(ctx, val); +} + +static unsigned int axiado_tach_get_rpm(struct axiado_pwm_fan_ctx *ctx) +{ + u32 pulses_per_revolution =3D ctx->tach.pulses_per_revolution; + u64 pulses, rpm; + + scoped_guard(spinlock_irqsave, &ctx->tach_lock) + pulses =3D ctx->tach.count; + + if (!pulses_per_revolution) + return 0; + + rpm =3D pulses * 60; + do_div(rpm, pulses_per_revolution); + + return rpm; +} + +static int axiado_pwm_fan_read(struct device *dev, enum hwmon_sensor_types= type, + u32 attr, int channel, long *val) +{ + struct axiado_pwm_fan_ctx *ctx =3D dev_get_drvdata(dev); + + switch (type) { + case hwmon_pwm: + if (attr !=3D hwmon_pwm_input) + return -EOPNOTSUPP; + + scoped_guard(mutex, &ctx->pwm_lock) + *val =3D ctx->pwm_value; + + return 0; + + case hwmon_fan: + if (attr !=3D hwmon_fan_input) + return -EOPNOTSUPP; + + *val =3D axiado_tach_get_rpm(ctx); + + return 0; + + default: + return -EOPNOTSUPP; + } +} + +static umode_t axiado_pwm_fan_is_visible(const void *data, + enum hwmon_sensor_types type, u32 attr, + int channel) +{ + if (type =3D=3D hwmon_fan && attr =3D=3D hwmon_fan_input) + return 0444; + + if (type =3D=3D hwmon_pwm && attr =3D=3D hwmon_pwm_input) + return 0644; + + return 0; +} + +static const struct hwmon_ops pwm_fan_hwmon_ops =3D { + .is_visible =3D axiado_pwm_fan_is_visible, + .read =3D axiado_pwm_fan_read, + .write =3D axiado_pwm_fan_write, +}; + +static const struct hwmon_chip_info pwm_fan_chip_info =3D { + .ops =3D &pwm_fan_hwmon_ops, + .info =3D pwm_fan_info, +}; + +static int axiado_pwm_apply_disabled(struct axiado_pwm_fan_ctx *ctx) +{ + struct pwm_state state; + + guard(mutex)(&ctx->pwm_lock); + + if (!ctx->pwm_value) + return 0; + + state =3D ctx->pwm_state; + state.duty_cycle =3D 0; + state.enabled =3D false; + + return pwm_apply_might_sleep(ctx->pwm, &state); +} + +static void axiado_pwm_disable(void *data) +{ + struct axiado_pwm_fan_ctx *ctx =3D data; + + axiado_pwm_apply_disabled(ctx); +} + +static void axiado_tach_enable(struct axiado_pwm_fan_ctx *ctx) +{ + iowrite32(AX_TACH_INT_PENDING, + ctx->tach_base + AX_TACH_INT_STATUS_REG); + iowrite32(ctx->tach.timer_count, + ctx->tach_base + AX_TACH_TIMER_COUNT_REG); + iowrite32(AX_TACH_CTRL_ENABLE | AX_TACH_CTRL_INT_ENABLE, + ctx->tach_base + AX_TACH_CTRL_REG); +} + +static void axiado_tach_disable(void *data) +{ + struct axiado_pwm_fan_ctx *ctx =3D data; + + iowrite32(0, ctx->tach_base + AX_TACH_CTRL_REG); + iowrite32(AX_TACH_INT_PENDING, + ctx->tach_base + AX_TACH_INT_STATUS_REG); +} + +static int axiado_pwm_fan_probe(struct platform_device *pdev) +{ + struct device *dev =3D &pdev->dev; + struct axiado_pwm_fan_ctx *ctx; + unsigned long tach_clk_rate; + struct device *hwmon; + struct clk *tach_clk; + int ret; + + ctx =3D devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); + if (!ctx) + return -ENOMEM; + + mutex_init(&ctx->pwm_lock); + spin_lock_init(&ctx->tach_lock); + + ctx->tach_base =3D devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(ctx->tach_base)) + return PTR_ERR(ctx->tach_base); + + ctx->pwm =3D devm_pwm_get(dev, NULL); + if (IS_ERR(ctx->pwm)) + return dev_err_probe(dev, PTR_ERR(ctx->pwm), + "Could not get PWM\n"); + + platform_set_drvdata(pdev, ctx); + + pwm_init_state(ctx->pwm, &ctx->pwm_state); + + if (!ctx->pwm_state.period) + return dev_err_probe(dev, -EINVAL, "PWM period is zero\n"); + + tach_clk =3D devm_clk_get_enabled(dev, NULL); + if (IS_ERR(tach_clk)) + return dev_err_probe(dev, PTR_ERR(tach_clk), + "Failed to get tachometer clock\n"); + + tach_clk_rate =3D clk_get_rate(tach_clk); + if (!tach_clk_rate || tach_clk_rate > U32_MAX) + return dev_err_probe(dev, -EINVAL, + "Invalid tachometer clock rate: %lu\n", + tach_clk_rate); + + ctx->tach.timer_count =3D tach_clk_rate; + ctx->tach.pulses_per_revolution =3D 2; + device_property_read_u32(dev, "pulses-per-revolution", + &ctx->tach.pulses_per_revolution); + + if (!ctx->tach.pulses_per_revolution) + return dev_err_probe(dev, -EINVAL, + "pulses-per-revolution cannot be zero\n"); + + ctx->tach.irq =3D platform_get_irq(pdev, 0); + if (ctx->tach.irq < 0) + return dev_err_probe(dev, ctx->tach.irq, + "Failed to get tachometer IRQ\n"); + + ret =3D devm_request_irq(dev, ctx->tach.irq, axiado_tach_irq_handler, 0, + dev_name(dev), ctx); + if (ret) + return dev_err_probe(dev, ret, "Failed to request tach IRQ\n"); + + ret =3D devm_add_action_or_reset(dev, axiado_tach_disable, ctx); + if (ret) + return ret; + + dev_dbg(dev, "Fan tachometer: irq=3D%d, pulses_per_revolution=3D%u\n", + ctx->tach.irq, ctx->tach.pulses_per_revolution); + + axiado_tach_enable(ctx); + + ret =3D axiado_set_pwm(ctx, PWM_MAX); + + if (ret) + return dev_err_probe(dev, ret, "Failed to configure PWM\n"); + + ret =3D devm_add_action_or_reset(dev, axiado_pwm_disable, ctx); + if (ret) + return dev_err_probe(dev, ret, + "Failed to add PWM disable action\n"); + + hwmon =3D devm_hwmon_device_register_with_info(dev, "axpwmfan", ctx, + &pwm_fan_chip_info, NULL); + if (IS_ERR(hwmon)) + return dev_err_probe(dev, PTR_ERR(hwmon), + "Failed to register hwmon device\n"); + + return 0; +} + +static int axiado_pwm_fan_disable(struct device *dev) +{ + struct axiado_pwm_fan_ctx *ctx =3D dev_get_drvdata(dev); + int ret; + + ret =3D axiado_pwm_apply_disabled(ctx); + if (ret) + return ret; + + axiado_tach_disable(ctx); + synchronize_irq(ctx->tach.irq); + + return 0; +} + +static void axiado_pwm_fan_shutdown(struct platform_device *pdev) +{ + struct axiado_pwm_fan_ctx *ctx =3D platform_get_drvdata(pdev); + + /* Best effort during shutdown. */ + axiado_pwm_apply_disabled(ctx); + + axiado_tach_disable(ctx); + synchronize_irq(ctx->tach.irq); +} + +static int axiado_pwm_fan_suspend(struct device *dev) +{ + return axiado_pwm_fan_disable(dev); +} + +static int axiado_pwm_fan_resume(struct device *dev) +{ + struct axiado_pwm_fan_ctx *ctx =3D dev_get_drvdata(dev); + int ret; + + axiado_tach_enable(ctx); + + scoped_guard(mutex, &ctx->pwm_lock) + ret =3D pwm_apply_might_sleep(ctx->pwm, &ctx->pwm_state); + + if (ret) + axiado_tach_disable(ctx); + + return ret; +} + +static DEFINE_SIMPLE_DEV_PM_OPS(axiado_pwm_fan_pm, + axiado_pwm_fan_suspend, + axiado_pwm_fan_resume); + +static const struct of_device_id axiado_pwm_fan_match[] =3D { + { .compatible =3D "axiado,ax3000-pwm-fan" }, + { }, +}; +MODULE_DEVICE_TABLE(of, axiado_pwm_fan_match); + +static struct platform_driver axiado_pwm_fan_driver =3D { + .probe =3D axiado_pwm_fan_probe, + .shutdown =3D axiado_pwm_fan_shutdown, + .driver =3D { + .name =3D "axiado-pwm-fan", + .pm =3D pm_sleep_ptr(&axiado_pwm_fan_pm), + .of_match_table =3D axiado_pwm_fan_match, + }, +}; + +module_platform_driver(axiado_pwm_fan_driver); +MODULE_AUTHOR("Axiado Corporation"); +MODULE_DESCRIPTION("Axiado PWM fan controller driver"); +MODULE_LICENSE("GPL"); + --=20 2.34.1