From nobody Mon Sep 28 14:47:00 2026 Received: from mail-pg1-f178.google.com (mail-pg1-f178.google.com [209.85.215.178]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3BF6237882B for ; Fri, 21 Aug 2026 03:35:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.178 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787283330; cv=none; b=LVG+RvMpW2CEW4ufUevAg8M79o2hZfgd1pHWFtuhAdDETUy3Y9nTncV2f9O5QsyPhSpHW2z1LSTfWhyT63bm2LG4pQVVhriCV8IsAqHxbEboT6JlUzul7NK7BCLqgT6Y+UXA3TJgnWXxNGXnWUDu6u/KuZiLYTMV3kUUFq12G8Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787283330; c=relaxed/simple; bh=B1ouq7zNk3OffF9x05iRPTwxZeo6B5tYmbwVJug955A=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=mZII340wXzhWPmnX7gl+PspM88G1xCIE0C1ZcJvC5opcrpokeALikxBNYT/ZNLv1cCcfy5gKleKaiYawaaweUU2XZLVSzn+/OtaiTTnseAMWHmXed4JDskH82Pf6fEdnpBhXSLyuGsU6wCAM+WxqHgaFJS1+FY5lThCO6f1eNqg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=VnrhaUv2; arc=none smtp.client-ip=209.85.215.178 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="VnrhaUv2" Received: by mail-pg1-f178.google.com with SMTP id 41be03b00d2f7-cbedbaba5fdso360156a12.0 for ; Thu, 20 Aug 2026 20:35:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1787283327; x=1787888127; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=OlQ97Apv2CPkVoHg6S8Gou0Qv9jKg/Qt6XZBOTaFmHE=; b=VnrhaUv2dYCrSiZGhJIvCZ8tV7LnOpm60K2LIMMZzCw3FFjMuT8C23WKtg6yl1fowv W5Gq4KwK7y/M29WzGPX73wNw3JgxNFkyny25CZgqnicLG8hki6jRIpcVeE2WGMXz55sJ 0TJSG5KKG/u3W8orCNz/nFQMDrOLV39Lp2np5I/T6rGhTfpOKMBJWT5lvGRpbgrSnBqG IHK1GtHuMOR+xspbJ4sIKQg6xECz6Wh3pU5Im6LU9C8TMK9YamK5ZmrrgAaPhNaJggzD 2CcZiSauWJAymUfd7ZnbKzdTJRDdicXFiobBfjzv3j8CJb1uPjq4VQjs4Nzih+E57HKa cnGQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787283327; x=1787888127; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=OlQ97Apv2CPkVoHg6S8Gou0Qv9jKg/Qt6XZBOTaFmHE=; b=fZ0+cD3gKknCAhG76fYFEKH8GkjkpRiVM6EMTq79ZRJxPRWNZpn80vHYrsNVycd8Lj 8tIhwmM69cpNKuIDNzXgghZG1Fx8upX0lrvAGFibrMowaLmbqaHtkb9TB1KbIRlNrJyd 8npLJruABYxD00aSskTveFIXXcCNqZNhyjx148y/5yQqLWGQN+QOnehXzKy3kXyQHowj 5FcT/Si7fakLzoQmqJHz65jE1icVAxpwu6RcGHwExRqGIfaBpjPG7PFy/Nzwet5jUWeM h2mKGFJU1eTgu4rxQeD35DiDkNNGpREvCmeEhayoC0ywuB3C3qHTf4DC3asva7CqjhxM c++Q== X-Gm-Message-State: AOJu0YxdIETnsNvtB3q+TrdNEg0XTwbo8zw6rmYEbRNE6cztfkxU04Gw zt3iR0keSUUqSoXXBq6auybw1cLuNwmIOVKDqkd6IzK3crHOyzrHJQsP X-Gm-Gg: AR+sD1186L9mHvwuBpYHUWAxRTe17OlRgoqCdy0U1psEXqsuCWHEp/33jqvUC94v6e9 TI/+YTlu0cL+wSAk8pskxmKeX7XRcX45VU6K0z81sXnfBFRH2xnkkwwC8IQW6pCc0gTW1Si8I7B wol6qxG4NQvt2ecGX4QW6IP8g/TVrnH/IMnDONZ7Wwy9tRCXNg3zpX9iF8SaLeuR+HdSkmEsSQi P7m7XtEFBH6bjZ/WsTRK5h60l3dXlCVQO13KOzAveEKTKhJTPpimPnW7GUZzL6+bABQDmASsxeQ j87SINqErCk25ZZVtF5TY4+ZZPYmE5mAZY2yQ2IJ+DDQZE/cGMgv3kG1xdM3XSHIteLvL91ig57 A3hPA7PZjcZvzpLBsZjZIVHrKIwrV7qV7A1KpCxozqAa0SliUGJw44ZIal7dveiCy1cf5e16R/k /VDaMkbCNoqnFO6GfRY3ACUhEv70fZ0mxuv+rzAwXlw+yhH4raC6PVyPFApv8YRPmkzM73mdvcL xVwbrUv5JIjeQycDkUBXggq6iOFrTeOtsUusVnn8g== X-Received: by 2002:a05:6a21:3a46:b0:3bf:63af:855 with SMTP id adf61e73a8af0-3cd2fddf03emr6085839637.1.1787283327385; Thu, 20 Aug 2026 20:35:27 -0700 (PDT) Received: from hcdev-d520mt2.. (60-250-196-139.hinet-ip.hinet.net. [60.250.196.139]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-cc15891a04csm2204271a12.15.2026.08.20.20.35.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Aug 2026 20:35:27 -0700 (PDT) From: a0282524688@gmail.com To: lee@kernel.org, Ming Yu , Linus Walleij , Bartosz Golaszewski , Guenter Roeck , Andi Shyti , Marc Kleine-Budde , Vincent Mailhol , Alexandre Belloni , Wim Van Sebroeck Cc: linux-kernel@vger.kernel.org, Ming Yu , linux-gpio@vger.kernel.org, linux-hwmon@vger.kernel.org, linux-i2c@vger.kernel.org, linux-can@vger.kernel.org, linux-rtc@vger.kernel.org, linux-watchdog@vger.kernel.org, mfd@lists.linux.dev Subject: [PATCH v7 01/10] mfd: nct6694: Move module type macros to shared header Date: Fri, 21 Aug 2026 11:34:56 +0800 Message-Id: <20260821033505.4017901-2-a0282524688@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260821033505.4017901-1-a0282524688@gmail.com> References: <20260821033505.4017901-1-a0282524688@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Ming Yu Move NCT6694_XXX_MOD macro definitions from individual sub-device drivers into the shared header include/linux/mfd/nct6694.h. This is a prerequisite for supporting multiple transport interfaces (USB, HIF) without duplicating these definitions. No functional change. Signed-off-by: Ming Yu --- Changes in v7: Changes in v6: Changes in v5: - Split from the monolithic v4 patch to follow the single logical change principle. drivers/gpio/gpio-nct6694.c | 7 ------- drivers/hwmon/nct6694-hwmon.c | 21 --------------------- drivers/i2c/busses/i2c-nct6694.c | 7 ------- drivers/net/can/usb/nct6694_canfd.c | 6 ------ drivers/rtc/rtc-nct6694.c | 7 ------- drivers/watchdog/nct6694_wdt.c | 7 ------- include/linux/mfd/nct6694.h | 9 +++++++++ 7 files changed, 9 insertions(+), 55 deletions(-) diff --git a/drivers/gpio/gpio-nct6694.c b/drivers/gpio/gpio-nct6694.c index a8607f0d9915..53bfc5983648 100644 --- a/drivers/gpio/gpio-nct6694.c +++ b/drivers/gpio/gpio-nct6694.c @@ -13,13 +13,6 @@ #include #include =20 -/* - * USB command module type for NCT6694 GPIO controller. - * This defines the module type used for communication with the NCT6694 - * GPIO controller over the USB interface. - */ -#define NCT6694_GPIO_MOD 0xFF - #define NCT6694_GPIO_VER 0x90 #define NCT6694_GPIO_VALID 0x110 #define NCT6694_GPI_DATA 0x120 diff --git a/drivers/hwmon/nct6694-hwmon.c b/drivers/hwmon/nct6694-hwmon.c index 6dcf22ca5018..581451875f2c 100644 --- a/drivers/hwmon/nct6694-hwmon.c +++ b/drivers/hwmon/nct6694-hwmon.c @@ -15,13 +15,6 @@ #include #include =20 -/* - * USB command module type for NCT6694 report channel - * This defines the module type used for communication with the NCT6694 - * report channel over the USB interface. - */ -#define NCT6694_RPT_MOD 0xFF - /* Report channel */ /* * The report channel is used to report the status of the hardware monitor @@ -38,13 +31,6 @@ #define NCT6694_TIN_STS(x) (0x6A + (x)) #define NCT6694_FIN_STS(x) (0x6E + (x)) =20 -/* - * USB command module type for NCT6694 HWMON controller. - * This defines the module type used for communication with the NCT6694 - * HWMON controller over the USB interface. - */ -#define NCT6694_HWMON_MOD 0x00 - /* Command 00h - Hardware Monitor Control */ #define NCT6694_HWMON_CONTROL 0x00 #define NCT6694_HWMON_CONTROL_SEL 0x00 @@ -53,13 +39,6 @@ #define NCT6694_HWMON_ALARM 0x02 #define NCT6694_HWMON_ALARM_SEL 0x00 =20 -/* - * USB command module type for NCT6694 PWM controller. - * This defines the module type used for communication with the NCT6694 - * PWM controller over the USB interface. - */ -#define NCT6694_PWM_MOD 0x01 - /* PWM Command - Manual Control */ #define NCT6694_PWM_CONTROL 0x01 #define NCT6694_PWM_CONTROL_SEL 0x00 diff --git a/drivers/i2c/busses/i2c-nct6694.c b/drivers/i2c/busses/i2c-nct6= 694.c index 1413ab6f9462..ef3329f34246 100644 --- a/drivers/i2c/busses/i2c-nct6694.c +++ b/drivers/i2c/busses/i2c-nct6694.c @@ -12,13 +12,6 @@ #include #include =20 -/* - * USB command module type for NCT6694 I2C controller. - * This defines the module type used for communication with the NCT6694 - * I2C controller over the USB interface. - */ -#define NCT6694_I2C_MOD 0x03 - /* Command 00h - I2C Deliver */ #define NCT6694_I2C_DELIVER 0x00 #define NCT6694_I2C_DELIVER_SEL 0x00 diff --git a/drivers/net/can/usb/nct6694_canfd.c b/drivers/net/can/usb/nct6= 694_canfd.c index e5f7f8849a73..262b4c26c9d4 100644 --- a/drivers/net/can/usb/nct6694_canfd.c +++ b/drivers/net/can/usb/nct6694_canfd.c @@ -18,12 +18,6 @@ =20 #define DEVICE_NAME "nct6694-canfd" =20 -/* USB command module type for NCT6694 CANfd controller. - * This defines the module type used for communication with the NCT6694 - * CANfd controller over the USB interface. - */ -#define NCT6694_CANFD_MOD 0x05 - /* Command 00h - CAN Setting and Initialization */ #define NCT6694_CANFD_SETTING 0x00 #define NCT6694_CANFD_SETTING_ACTIVE_CTRL1 BIT(0) diff --git a/drivers/rtc/rtc-nct6694.c b/drivers/rtc/rtc-nct6694.c index 35401a0d9cf5..c06902f150c9 100644 --- a/drivers/rtc/rtc-nct6694.c +++ b/drivers/rtc/rtc-nct6694.c @@ -14,13 +14,6 @@ #include #include =20 -/* - * USB command module type for NCT6694 RTC controller. - * This defines the module type used for communication with the NCT6694 - * RTC controller over the USB interface. - */ -#define NCT6694_RTC_MOD 0x08 - /* Command 00h - RTC Time */ #define NCT6694_RTC_TIME 0x0000 #define NCT6694_RTC_TIME_SEL 0x00 diff --git a/drivers/watchdog/nct6694_wdt.c b/drivers/watchdog/nct6694_wdt.c index bc3689bd4b6b..4c06ac105562 100644 --- a/drivers/watchdog/nct6694_wdt.c +++ b/drivers/watchdog/nct6694_wdt.c @@ -20,13 +20,6 @@ =20 #define NCT6694_WDT_MAX_DEVS 2 =20 -/* - * USB command module type for NCT6694 WDT controller. - * This defines the module type used for communication with the NCT6694 - * WDT controller over the USB interface. - */ -#define NCT6694_WDT_MOD 0x07 - /* Command 00h - WDT Setup */ #define NCT6694_WDT_SETUP 0x00 #define NCT6694_WDT_SETUP_SEL(idx) (idx ? 0x01 : 0x00) diff --git a/include/linux/mfd/nct6694.h b/include/linux/mfd/nct6694.h index 6eb9be2cd4a0..3c683e317aa3 100644 --- a/include/linux/mfd/nct6694.h +++ b/include/linux/mfd/nct6694.h @@ -8,6 +8,15 @@ #ifndef __MFD_NCT6694_H #define __MFD_NCT6694_H =20 +#define NCT6694_HWMON_MOD 0x00 +#define NCT6694_PWM_MOD 0x01 +#define NCT6694_I2C_MOD 0x03 +#define NCT6694_CANFD_MOD 0x05 +#define NCT6694_WDT_MOD 0x07 +#define NCT6694_RTC_MOD 0x08 +#define NCT6694_RPT_MOD 0xFF +#define NCT6694_GPIO_MOD NCT6694_RPT_MOD + #define NCT6694_VENDOR_ID 0x0416 #define NCT6694_PRODUCT_ID 0x200B #define NCT6694_INT_IN_EP 0x81 --=20 2.34.1 From nobody Mon Sep 28 14:47:00 2026 Received: from mail-pg1-f175.google.com (mail-pg1-f175.google.com [209.85.215.175]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3EDB43783BB for ; Fri, 21 Aug 2026 03:35:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.175 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787283332; cv=none; b=VGqCJiHRdKZJrFRvz1gbom6RTM6COi1RBx4thSo9IihpB/qFgMBkxOLggB4wd/4UYCgrYej4xq6IFYksXLPlz4QKf1VU+zatyTrF2NXvyt4BSOFlyE8uodK3RsWRgKu7gCZoYqqv5qGzL+b/mPcSAyjiPysWSfEI4AQjSCqCnvY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787283332; c=relaxed/simple; bh=lxk/Nd15jNSj9ZzA0NEja15PMDVQF4j1a7JrrOl/ifk=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=WiQ3TCnRukIwJFU6cTVwAh0OgmEDjqcnIQKEOMqx5RlPkJd9J2KQU2vRREjHC4JoRiWZjdbiAAuL+iZHyZvXlYraU1KFnBpZ2mqM0hTYAAqiAivgFXJ0ujAk1HbpfP1RLlNBV8whxo4lE+bxyrWMcVxDHSqOIcM+Ll6Mrb87kGE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=ACcYXCzv; arc=none smtp.client-ip=209.85.215.175 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="ACcYXCzv" Received: by mail-pg1-f175.google.com with SMTP id 41be03b00d2f7-cb5b8572b70so700335a12.2 for ; Thu, 20 Aug 2026 20:35:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1787283329; x=1787888129; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=ZcsGJ3dy0JAsH0yRQSUgpcd+dXRyC1KJ48HZWVmKibU=; b=ACcYXCzvSnPsFbeXk/jd/8WNvtjTkcP6dzAWeggH6OAFck/IAGFeekmj+3xVR871Hk HlNr1zkNUvtykjX9vgr5yKKMN1UsVjkhOu8uPZnK5wCL8R+5bkr4A5bOaMr7f5HlPoFY jCAYLIoRVgxn2GUtSh5IPB/ptPiAHfSbYTzUAjQcSEgVNlvhTdgoy9LVAw76R6X+J5DC HE15m3Do+7QQEzFwGdku3ONFuMxVIHH27KoxJ3/I4wbzMqIiy9Iqj4T4pQEcW86xMm41 B3w4fgc9H76+LsY3hRyagFp42MRal3rBHRpiaH8y9+ie8qW72ulT0Z3L467ugE0CNqzX hZwg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787283329; x=1787888129; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=ZcsGJ3dy0JAsH0yRQSUgpcd+dXRyC1KJ48HZWVmKibU=; b=HPwsmSzDc5Pdm3lPodqKlxOmqdJoYfGV185343ZKIsgP59BbnZDDax2c0XYs676MRA NchxZJMmw3F6UNnJhAQeYxm8vksrUOcH1WbVfq/xfxvER5UCGbghjJ2+iEwiAZQXWKeo oz4VobLigLYtNmmF8iLe94zCP4ime0awoIiwGhzeeQwuqyq3gnir0dj1PF+5oit3WP5L 4a5KAAEnoh2U+l2SFcomuhzKOZePiB/kfpXhyxJr7h1grLEWCFp9298FQXf+GJ7sma8Q JYiznQoDoeIzES2CU4FeRe4o5dTczNPb2gQ1CchjtxUp+AEoidje9o4+S7yJ7nUjKg2a aAKg== X-Gm-Message-State: AOJu0Yx1JXhkKos3ch3yy4SgJ1sLynBf5KStvDzClOScSMinE4n9Zh4g RbxL6LU5cn20q13TFyd2s1j/qZ0D13IuqDdsk36pnMsG4kLMkcBFYDd4 X-Gm-Gg: AR+sD12kgxKYnsM3mWYRoPy31g1TI/mWrTpyWThEApOpu4VZB3Oc7cnzpKrduaesFnM i1NwnG44PUXC8JwLf8D7k0DOmuPR1msxprAOEZqOReKWclWQv6pRA5MMcSX5kawlqJKlNQrathd AG2UsyE8joETga9uEYtkr1ayhT6Ox+K/DeiO8djKsXQ3/AGA+TzorY7/zcqYfwNqBmCCN+5o6AQ YNiGux3nOZIoBRncJvFhWdNMk7354yoKRR0DSfZ2B0AVw7IpRlw2JQT0iYFoY3hp1trAPJrs48F KrE2RTxsulTI5ISiYsEXcLDebft+0NDoHhTrAqp5RtTSnM7OOpZZ3WALB8asKBo2n8S3j5wn1uJ 8byU1xM8sqlV9G4I0W3APy+CtAbVYyhYuvQ0mjeVtgD6o4UH2gUB9Tg89oZ+P8gezIdcuv/dqnW CCx2a1AaWdi05AsYv1LDHtGo7Xs/50OEr9MZaUC0AejjuZH7Oyvx3YDKHKsQ6OyXBF4i6Sg/u+Y XIA5jT6tBuZAZHiwRpSkx324Xd5MyUStXA5XKp07Rk= X-Received: by 2002:a05:6a21:3511:b0:3bf:6acf:2940 with SMTP id adf61e73a8af0-3cd30060d76mr7010037637.11.1787283329541; Thu, 20 Aug 2026 20:35:29 -0700 (PDT) Received: from hcdev-d520mt2.. (60-250-196-139.hinet-ip.hinet.net. [60.250.196.139]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-cc15891a04csm2204271a12.15.2026.08.20.20.35.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Aug 2026 20:35:29 -0700 (PDT) From: a0282524688@gmail.com To: lee@kernel.org, Ming Yu Cc: linux-kernel@vger.kernel.org, Ming Yu , mfd@lists.linux.dev Subject: [PATCH v7 02/10] mfd: nct6694: Refactor USB-specific data into nct6694_usb_data Date: Fri, 21 Aug 2026 11:34:57 +0800 Message-Id: <20260821033505.4017901-3-a0282524688@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260821033505.4017901-1-a0282524688@gmail.com> References: <20260821033505.4017901-1-a0282524688@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Ming Yu Separate USB transport-specific fields from the core nct6694 structure into a new nct6694_usb_data structure. This decouples the shared MFD core from the USB transport layer, preparing the driver for potential support of alternative transport backends in the future. The following fields are moved into nct6694_usb_data: - access_lock - int_in_urb - udev - usb_msg - int_buffer The core nct6694 structure now holds a void *priv pointer to reference the transport-specific data. USB-only definitions (vendor/product IDs, endpoint addresses, URB timeout, and the USB message union) are also moved from the shared header into the USB driver source file. Signed-off-by: Ming Yu --- Changes in v7: Changes in v6: Changes in v5: - Split from the monolithic v4 patch to follow the single logical change principle. drivers/mfd/nct6694.c | 76 ++++++++++++++++++++++++++----------- include/linux/mfd/nct6694.h | 27 ++++--------- 2 files changed, 62 insertions(+), 41 deletions(-) diff --git a/drivers/mfd/nct6694.c b/drivers/mfd/nct6694.c index 308b2fda3055..58c1cbcbe3f2 100644 --- a/drivers/mfd/nct6694.c +++ b/drivers/mfd/nct6694.c @@ -10,8 +10,8 @@ */ =20 #include -#include #include +#include #include #include #include @@ -22,6 +22,27 @@ #include #include =20 +#define NCT6694_VENDOR_ID 0x0416 +#define NCT6694_PRODUCT_ID 0x200B +#define NCT6694_INT_IN_EP 0x81 +#define NCT6694_BULK_IN_EP 0x02 +#define NCT6694_BULK_OUT_EP 0x03 + +#define NCT6694_URB_TIMEOUT 1000 + +union __packed nct6694_usb_msg { + struct nct6694_cmd_header cmd_header; + struct nct6694_response_header response_header; +}; + +struct nct6694_usb_data { + struct mutex access_lock; + struct urb *int_in_urb; + struct usb_device *udev; + union nct6694_usb_msg *usb_msg; + __le32 *int_buffer; +}; + static const struct mfd_cell nct6694_devs[] =3D { MFD_CELL_NAME("nct6694-gpio"), MFD_CELL_NAME("nct6694-gpio"), @@ -96,11 +117,12 @@ static int nct6694_response_err_handling(struct nct669= 4 *nct6694, unsigned char */ int nct6694_read_msg(struct nct6694 *nct6694, const struct nct6694_cmd_hea= der *cmd_hd, void *buf) { - union nct6694_usb_msg *msg =3D nct6694->usb_msg; - struct usb_device *udev =3D nct6694->udev; + struct nct6694_usb_data *udata =3D nct6694->priv; + union nct6694_usb_msg *msg =3D udata->usb_msg; + struct usb_device *udev =3D udata->udev; int tx_len, rx_len, ret; =20 - guard(mutex)(&nct6694->access_lock); + guard(mutex)(&udata->access_lock); =20 memcpy(&msg->cmd_header, cmd_hd, sizeof(*cmd_hd)); msg->cmd_header.hctrl =3D NCT6694_HCTRL_GET; @@ -146,11 +168,12 @@ EXPORT_SYMBOL_GPL(nct6694_read_msg); */ int nct6694_write_msg(struct nct6694 *nct6694, const struct nct6694_cmd_he= ader *cmd_hd, void *buf) { - union nct6694_usb_msg *msg =3D nct6694->usb_msg; - struct usb_device *udev =3D nct6694->udev; + struct nct6694_usb_data *udata =3D nct6694->priv; + union nct6694_usb_msg *msg =3D udata->usb_msg; + struct usb_device *udev =3D udata->udev; int tx_len, rx_len, ret; =20 - guard(mutex)(&nct6694->access_lock); + guard(mutex)(&udata->access_lock); =20 memcpy(&msg->cmd_header, cmd_hd, sizeof(*cmd_hd)); msg->cmd_header.hctrl =3D NCT6694_HCTRL_SET; @@ -277,6 +300,7 @@ static int nct6694_usb_probe(struct usb_interface *ifac= e, struct usb_endpoint_descriptor *int_endpoint; struct usb_host_interface *interface; struct device *dev =3D &iface->dev; + struct nct6694_usb_data *udata; struct nct6694 *nct6694; int ret; =20 @@ -284,18 +308,26 @@ static int nct6694_usb_probe(struct usb_interface *if= ace, if (!nct6694) return -ENOMEM; =20 - nct6694->usb_msg =3D devm_kzalloc(dev, sizeof(union nct6694_usb_msg), GFP= _KERNEL); - if (!nct6694->usb_msg) + udata =3D devm_kzalloc(dev, sizeof(*udata), GFP_KERNEL); + if (!udata) + return -ENOMEM; + + udata->usb_msg =3D devm_kzalloc(dev, sizeof(*udata->usb_msg), GFP_KERNEL); + if (!udata->usb_msg) return -ENOMEM; =20 - nct6694->int_buffer =3D devm_kzalloc(dev, sizeof(*nct6694->int_buffer), G= FP_KERNEL); - if (!nct6694->int_buffer) + udata->int_buffer =3D devm_kzalloc(dev, sizeof(*udata->int_buffer), GFP_K= ERNEL); + if (!udata->int_buffer) return -ENOMEM; =20 - nct6694->int_in_urb =3D usb_alloc_urb(0, GFP_KERNEL); - if (!nct6694->int_in_urb) + udata->int_in_urb =3D usb_alloc_urb(0, GFP_KERNEL); + if (!udata->int_in_urb) return -ENOMEM; =20 + udata->udev =3D udev; + + nct6694->priv =3D udata; + nct6694->domain =3D irq_domain_create_simple(NULL, NCT6694_NR_IRQS, 0, &nct6694_irq_domain_ops, nct6694); @@ -305,7 +337,6 @@ static int nct6694_usb_probe(struct usb_interface *ifac= e, } =20 nct6694->dev =3D dev; - nct6694->udev =3D udev; =20 ida_init(&nct6694->gpio_ida); ida_init(&nct6694->i2c_ida); @@ -314,7 +345,7 @@ static int nct6694_usb_probe(struct usb_interface *ifac= e, =20 spin_lock_init(&nct6694->irq_lock); =20 - ret =3D devm_mutex_init(dev, &nct6694->access_lock); + ret =3D devm_mutex_init(dev, &udata->access_lock); if (ret) goto err_ida; =20 @@ -326,11 +357,11 @@ static int nct6694_usb_probe(struct usb_interface *if= ace, goto err_ida; } =20 - usb_fill_int_urb(nct6694->int_in_urb, udev, usb_rcvintpipe(udev, NCT6694_= INT_IN_EP), - nct6694->int_buffer, sizeof(*nct6694->int_buffer), usb_int_callback, + usb_fill_int_urb(udata->int_in_urb, udev, usb_rcvintpipe(udev, NCT6694_IN= T_IN_EP), + udata->int_buffer, sizeof(*udata->int_buffer), usb_int_callback, nct6694, int_endpoint->bInterval); =20 - ret =3D usb_submit_urb(nct6694->int_in_urb, GFP_KERNEL); + ret =3D usb_submit_urb(udata->int_in_urb, GFP_KERNEL); if (ret) goto err_ida; =20 @@ -343,7 +374,7 @@ static int nct6694_usb_probe(struct usb_interface *ifac= e, return 0; =20 err_mfd: - usb_kill_urb(nct6694->int_in_urb); + usb_kill_urb(udata->int_in_urb); err_ida: ida_destroy(&nct6694->wdt_ida); ida_destroy(&nct6694->canfd_ida); @@ -351,22 +382,23 @@ static int nct6694_usb_probe(struct usb_interface *if= ace, ida_destroy(&nct6694->gpio_ida); irq_domain_remove(nct6694->domain); err_urb: - usb_free_urb(nct6694->int_in_urb); + usb_free_urb(udata->int_in_urb); return ret; } =20 static void nct6694_usb_disconnect(struct usb_interface *iface) { struct nct6694 *nct6694 =3D usb_get_intfdata(iface); + struct nct6694_usb_data *udata =3D nct6694->priv; =20 mfd_remove_devices(nct6694->dev); - usb_kill_urb(nct6694->int_in_urb); + usb_kill_urb(udata->int_in_urb); ida_destroy(&nct6694->wdt_ida); ida_destroy(&nct6694->canfd_ida); ida_destroy(&nct6694->i2c_ida); ida_destroy(&nct6694->gpio_ida); irq_domain_remove(nct6694->domain); - usb_free_urb(nct6694->int_in_urb); + usb_free_urb(udata->int_in_urb); } =20 static const struct usb_device_id nct6694_ids[] =3D { diff --git a/include/linux/mfd/nct6694.h b/include/linux/mfd/nct6694.h index 3c683e317aa3..3f5dd53f38de 100644 --- a/include/linux/mfd/nct6694.h +++ b/include/linux/mfd/nct6694.h @@ -2,12 +2,18 @@ /* * Copyright (C) 2025 Nuvoton Technology Corp. * - * Nuvoton NCT6694 USB transaction and data structure. + * Nuvoton NCT6694 core definitions shared by all transport drivers + * and sub-device drivers. */ =20 #ifndef __MFD_NCT6694_H #define __MFD_NCT6694_H =20 +#include +#include +#include +#include + #define NCT6694_HWMON_MOD 0x00 #define NCT6694_PWM_MOD 0x01 #define NCT6694_I2C_MOD 0x03 @@ -17,17 +23,9 @@ #define NCT6694_RPT_MOD 0xFF #define NCT6694_GPIO_MOD NCT6694_RPT_MOD =20 -#define NCT6694_VENDOR_ID 0x0416 -#define NCT6694_PRODUCT_ID 0x200B -#define NCT6694_INT_IN_EP 0x81 -#define NCT6694_BULK_IN_EP 0x02 -#define NCT6694_BULK_OUT_EP 0x03 - #define NCT6694_HCTRL_SET 0x40 #define NCT6694_HCTRL_GET 0x80 =20 -#define NCT6694_URB_TIMEOUT 1000 - enum nct6694_irq_id { NCT6694_IRQ_GPIO0 =3D 0, NCT6694_IRQ_GPIO1, @@ -84,11 +82,6 @@ struct __packed nct6694_response_header { __le16 len; }; =20 -union __packed nct6694_usb_msg { - struct nct6694_cmd_header cmd_header; - struct nct6694_response_header response_header; -}; - struct nct6694 { struct device *dev; struct ida gpio_ida; @@ -96,13 +89,9 @@ struct nct6694 { struct ida canfd_ida; struct ida wdt_ida; struct irq_domain *domain; - struct mutex access_lock; spinlock_t irq_lock; - struct urb *int_in_urb; - struct usb_device *udev; - union nct6694_usb_msg *usb_msg; - __le32 *int_buffer; unsigned int irq_enable; + void *priv; }; =20 int nct6694_read_msg(struct nct6694 *nct6694, const struct nct6694_cmd_hea= der *cmd_hd, void *buf); --=20 2.34.1 From nobody Mon Sep 28 14:47:00 2026 Received: from mail-pf1-f179.google.com (mail-pf1-f179.google.com [209.85.210.179]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 404AA3793B6 for ; Fri, 21 Aug 2026 03:35:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.179 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787283334; cv=none; b=IBnb1mf6dnIHFiC0luQeocQBvIR+8ib5iT96210o/+DAJCmBdOxVWSdCd/8Zv3XmOxQV0h79eGAxyou1sMswgVmiU7lU7DybnYQWvIP70LUiGxFJXMOtyiCB5LgNks9VAbAHeEOU2fjIXTxh//cx/1ec4+t7jW1it0A5Eh/11Ys= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787283334; c=relaxed/simple; bh=1qfPCAkHK6+3oGtSjpJ1THEbi1nrjMBdzidqeLK4VPI=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=BX9ZL55SshDK0B1qwr8/FdBtiJrwXzpVJ6UgF0ckfLGItgpwKzj7ukwwmsCgedob/hsQR6oOLnr/i/jfB2p+LZ9HYRABA7DURjL2WoR2RHr0d8RMvr8ETHPJl67GWe3p+U0KZtPnD1GQ5X6b3P59Tcx7qMxZ7QU0XGT2EDvvNG0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=QK6IhjRy; arc=none smtp.client-ip=209.85.210.179 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="QK6IhjRy" Received: by mail-pf1-f179.google.com with SMTP id d2e1a72fcca58-84eb992a881so375378b3a.2 for ; Thu, 20 Aug 2026 20:35:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1787283331; x=1787888131; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=wq2eh2UzCGmILxON+JYPWrNPEZ+By7fX4zFgbdbH1rY=; b=QK6IhjRykHP7HPHxLwqByYsya13018lKTIJw9kwbSe58IlX89qn3C+mTqtSZhkSS7k SUHWzPmGfkuQ0v6WMN9+vP+oGSjeJmWk6QEfJlxQSkG6gRrBP/J56KEQ1N1bGgfYYAfj cJGWO5hqQVNHhf0LU4YzWZYRWgXgqzfRtsbAZmWGdsmm+1qt5ECa2QicsBLhEPt3z1qE dNtkKgwBgaGrAyUoIjOYjKrzVUCQXoEHKlOs1Fu2CyvF3izXZe7ksSg9+SBXzHMs2aco QtIC+Xku1dd93wHtqlT5j4M/257ApYi1hITe0pJ26/54XGkAIw8kqWQQS9253RDkKmwr +jOA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787283331; x=1787888131; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=wq2eh2UzCGmILxON+JYPWrNPEZ+By7fX4zFgbdbH1rY=; b=gCjxpWtrsZAI0ZofNIheQrOPPopw9RXmNu1T3GCTzOHMyftycdt7cczYzPnC1R2nfl oe+76BV/PQ+QFO/5Bw3LLFQ0qieX9xtNXo6hck/PRttSxtd2JqZZYjXVUS50aaJcXrzE yEe2EWaN52SAkLDg6P7sjmzRIrQHzq9vzEf2JEAS0c92lMv89IRtD5cvzJkvuor/qZDq bi30WPDofx7cZXCue3G0/L9SRl+2sX8EyyTSCU+YperCwr0VMBecrVHHE/q2njt1Zv1/ V+elGI6b03RGhOa1q13xdqL/KbbHNSTm6YYPob3ckf70r9llMSP7+ZC7wAErUNwexu4Y A6pA== X-Gm-Message-State: AFuF++nwGYmqkKlWiJtqlApatQGIraBuyFkfECB2q+YhuT2gPP/l/m0g fHNAYN/JqUWALFXJnPmlasYPC/PI4UTikYCcDuqJIIPH97LMloRfOn4x X-Gm-Gg: AR+sD127ear9ZGej/ITc22WtG2TR5iYAMsGFSAztc4lypoyIJhg1VXbrMwk4vw/efR/ 4enk5DCCnV75sHLhfx//Iuz944yjrU6gVOjxsK08XRr9gmkXo2v+hufO5FuS9Y4khCKE/CPR6xt BjJFfVMratapz0z/aMIkTr24Qbg2y9V7/YJyY1AL1BYi25eUWlX1lyRE9+LNQIkteWX1cmfSKp3 V8xTac4jxVlWkKoB/I4clgz/1eu0N6giB8YOHQ+5KH/ZwK382PC/fterPIQ/+SNc5RmitNiCHiR 8dbGwsscyHEY5AwhAY3HILVzD4NAY16n9JbiL1s2pB1P8pXQX03EhxEfijWSm8wCzRtzAJ7wio5 j1AR8x1YoQmQ31SlXGizGYEZ4R50mwYmnZKTMArC0r9oFexNpAlqb/F6x2xyypxrkfXMXCKyTdS UrfOq61h224f6wZkYBRJNTTadbMqxCRZHUib+NYaFGkL5upz7Q7Bqfx3BD2iu/8ahgG0P4IP7b+ QEESOahm/JvB5VyxIGx19fqYSaeYeCYoLWNRNWUrQ== X-Received: by 2002:a05:6a00:448e:b0:84d:ff47:fa53 with SMTP id d2e1a72fcca58-851f972a7ebmr5130503b3a.2.1787283331556; Thu, 20 Aug 2026 20:35:31 -0700 (PDT) Received: from hcdev-d520mt2.. (60-250-196-139.hinet-ip.hinet.net. [60.250.196.139]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-cc15891a04csm2204271a12.15.2026.08.20.20.35.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Aug 2026 20:35:31 -0700 (PDT) From: a0282524688@gmail.com To: lee@kernel.org, Ming Yu Cc: linux-kernel@vger.kernel.org, Ming Yu , mfd@lists.linux.dev Subject: [PATCH v7 03/10] mfd: nct6694: Rename USB transport functions with _usb_ prefix Date: Fri, 21 Aug 2026 11:34:58 +0800 Message-Id: <20260821033505.4017901-4-a0282524688@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260821033505.4017901-1-a0282524688@gmail.com> References: <20260821033505.4017901-1-a0282524688@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Ming Yu Rename nct6694_{read,write,err_handling}_msg() to carry an `_usb_` prefix, marking them as USB transport-specific. This prepares for the core layer and HIF (eSPI) transport added in later patches. Add transitional static inline wrappers nct6694_{read,write}_msg() in the shared header so sub-device drivers remain untouched in this commit; they will be replaced by the transport dispatch layer in a subsequent patch. No functional change. Signed-off-by: Ming Yu --- Changes in v7: Changes in v6: - New patch replacing the v5 function-pointer transport abstraction: rename the exported I/O functions with an _usb_ prefix and add transitional inline nct6694_{read,write}_msg() wrappers in the shared header so sub-device drivers stay untouched in this commit. drivers/mfd/nct6694.c | 40 ++++++++++++++++++++----------------- include/linux/mfd/nct6694.h | 22 ++++++++++++++++++-- 2 files changed, 42 insertions(+), 20 deletions(-) diff --git a/drivers/mfd/nct6694.c b/drivers/mfd/nct6694.c index 58c1cbcbe3f2..7c6b986db7f7 100644 --- a/drivers/mfd/nct6694.c +++ b/drivers/mfd/nct6694.c @@ -43,7 +43,7 @@ struct nct6694_usb_data { __le32 *int_buffer; }; =20 -static const struct mfd_cell nct6694_devs[] =3D { +static const struct mfd_cell nct6694_usb_devs[] =3D { MFD_CELL_NAME("nct6694-gpio"), MFD_CELL_NAME("nct6694-gpio"), MFD_CELL_NAME("nct6694-gpio"), @@ -79,7 +79,7 @@ static const struct mfd_cell nct6694_devs[] =3D { MFD_CELL_NAME("nct6694-rtc"), }; =20 -static int nct6694_response_err_handling(struct nct6694 *nct6694, unsigned= char err_status) +static int nct6694_usb_err_handling(struct nct6694 *nct6694, unsigned char= err_status) { switch (err_status) { case NCT6694_NO_ERROR: @@ -104,7 +104,7 @@ static int nct6694_response_err_handling(struct nct6694= *nct6694, unsigned char } =20 /** - * nct6694_read_msg() - Read message from NCT6694 device + * nct6694_usb_read_msg() - Read message from NCT6694 device * @nct6694: NCT6694 device pointer * @cmd_hd: command header structure * @buf: buffer to store the response data @@ -115,7 +115,9 @@ static int nct6694_response_err_handling(struct nct6694= *nct6694, unsigned char * * Return: Negative value on error or 0 on success. */ -int nct6694_read_msg(struct nct6694 *nct6694, const struct nct6694_cmd_hea= der *cmd_hd, void *buf) +int nct6694_usb_read_msg(struct nct6694 *nct6694, + const struct nct6694_cmd_header *cmd_hd, + void *buf) { struct nct6694_usb_data *udata =3D nct6694->priv; union nct6694_usb_msg *msg =3D udata->usb_msg; @@ -151,12 +153,12 @@ int nct6694_read_msg(struct nct6694 *nct6694, const s= truct nct6694_cmd_header *c return -EIO; } =20 - return nct6694_response_err_handling(nct6694, msg->response_header.sts); + return nct6694_usb_err_handling(nct6694, msg->response_header.sts); } -EXPORT_SYMBOL_GPL(nct6694_read_msg); +EXPORT_SYMBOL_GPL(nct6694_usb_read_msg); =20 /** - * nct6694_write_msg() - Write message to NCT6694 device + * nct6694_usb_write_msg() - Write message to NCT6694 device * @nct6694: NCT6694 device pointer * @cmd_hd: command header structure * @buf: buffer containing the data to be sent @@ -166,7 +168,9 @@ EXPORT_SYMBOL_GPL(nct6694_read_msg); * * Return: Negative value on error or 0 on success. */ -int nct6694_write_msg(struct nct6694 *nct6694, const struct nct6694_cmd_he= ader *cmd_hd, void *buf) +int nct6694_usb_write_msg(struct nct6694 *nct6694, + const struct nct6694_cmd_header *cmd_hd, + void *buf) { struct nct6694_usb_data *udata =3D nct6694->priv; union nct6694_usb_msg *msg =3D udata->usb_msg; @@ -208,11 +212,11 @@ int nct6694_write_msg(struct nct6694 *nct6694, const = struct nct6694_cmd_header * return -EIO; } =20 - return nct6694_response_err_handling(nct6694, msg->response_header.sts); + return nct6694_usb_err_handling(nct6694, msg->response_header.sts); } -EXPORT_SYMBOL_GPL(nct6694_write_msg); +EXPORT_SYMBOL_GPL(nct6694_usb_write_msg); =20 -static void usb_int_callback(struct urb *urb) +static void nct6694_usb_int_callback(struct urb *urb) { struct nct6694 *nct6694 =3D urb->context; __le32 *status_le =3D urb->transfer_buffer; @@ -358,7 +362,7 @@ static int nct6694_usb_probe(struct usb_interface *ifac= e, } =20 usb_fill_int_urb(udata->int_in_urb, udev, usb_rcvintpipe(udev, NCT6694_IN= T_IN_EP), - udata->int_buffer, sizeof(*udata->int_buffer), usb_int_callback, + udata->int_buffer, sizeof(*udata->int_buffer), nct6694_usb_int_callbac= k, nct6694, int_endpoint->bInterval); =20 ret =3D usb_submit_urb(udata->int_in_urb, GFP_KERNEL); @@ -367,7 +371,7 @@ static int nct6694_usb_probe(struct usb_interface *ifac= e, =20 usb_set_intfdata(iface, nct6694); =20 - ret =3D mfd_add_hotplug_devices(dev, nct6694_devs, ARRAY_SIZE(nct6694_dev= s)); + ret =3D mfd_add_hotplug_devices(dev, nct6694_usb_devs, ARRAY_SIZE(nct6694= _usb_devs)); if (ret) goto err_mfd; =20 @@ -401,20 +405,20 @@ static void nct6694_usb_disconnect(struct usb_interfa= ce *iface) usb_free_urb(udata->int_in_urb); } =20 -static const struct usb_device_id nct6694_ids[] =3D { +static const struct usb_device_id nct6694_usb_ids[] =3D { { USB_DEVICE_AND_INTERFACE_INFO(NCT6694_VENDOR_ID, NCT6694_PRODUCT_ID, 0x= FF, 0x00, 0x00) }, { } }; -MODULE_DEVICE_TABLE(usb, nct6694_ids); +MODULE_DEVICE_TABLE(usb, nct6694_usb_ids); =20 static struct usb_driver nct6694_usb_driver =3D { - .name =3D "nct6694", - .id_table =3D nct6694_ids, + .name =3D "nct6694-usb", + .id_table =3D nct6694_usb_ids, .probe =3D nct6694_usb_probe, .disconnect =3D nct6694_usb_disconnect, }; module_usb_driver(nct6694_usb_driver); =20 -MODULE_DESCRIPTION("Nuvoton NCT6694 core driver"); +MODULE_DESCRIPTION("Nuvoton NCT6694 USB transport driver"); MODULE_AUTHOR("Ming Yu "); MODULE_LICENSE("GPL"); diff --git a/include/linux/mfd/nct6694.h b/include/linux/mfd/nct6694.h index 3f5dd53f38de..43b51f243e8e 100644 --- a/include/linux/mfd/nct6694.h +++ b/include/linux/mfd/nct6694.h @@ -94,7 +94,25 @@ struct nct6694 { void *priv; }; =20 -int nct6694_read_msg(struct nct6694 *nct6694, const struct nct6694_cmd_hea= der *cmd_hd, void *buf); -int nct6694_write_msg(struct nct6694 *nct6694, const struct nct6694_cmd_he= ader *cmd_hd, void *buf); +int nct6694_usb_read_msg(struct nct6694 *nct6694, + const struct nct6694_cmd_header *cmd_hd, + void *buf); +int nct6694_usb_write_msg(struct nct6694 *nct6694, + const struct nct6694_cmd_header *cmd_hd, + void *buf); + +static inline int nct6694_read_msg(struct nct6694 *nct6694, + const struct nct6694_cmd_header *cmd_hd, + void *buf) +{ + return nct6694_usb_read_msg(nct6694, cmd_hd, buf); +} + +static inline int nct6694_write_msg(struct nct6694 *nct6694, + const struct nct6694_cmd_header *cmd_hd, + void *buf) +{ + return nct6694_usb_write_msg(nct6694, cmd_hd, buf); +} =20 #endif --=20 2.34.1 From nobody Mon Sep 28 14:47:00 2026 Received: from mail-pf1-f169.google.com (mail-pf1-f169.google.com [209.85.210.169]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0A8A4375ADD for ; Fri, 21 Aug 2026 03:35:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.169 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787283337; cv=none; b=JyxMT8lgIx9gifed6AV20JB5rSNTGrmEgbU+b14kD5LnaoJhBrrBT+sOnl2VzUc3KxvlFxfck43zZY9VCX1PBUUbsB0PeCQhpP0bWKAngVNA39oudpzfEzahBC/vxJKVSafnKTwvUbWehQxu5uBTN8YzAs6OdtPltDTk1/aZ5do= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787283337; c=relaxed/simple; bh=nUnyQrDd5jdSYXKPWzUznh6SFwnlW5VeFcWQi8BwH8s=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Pp+/AlYYUIJfScnkzMm9NEO6sNGaN2dEqulILZtOyVRuEkhJOGz7uggZiaC8+ZvVLdrBFIeQHVzteIezFwYTkPm0k1cpAs680unH3YPbGJKZv/Hizm5hB9SAyqgEr2MK9IFJ20mmd5ozyg4f2pAYOmUz3TyPfEgLnmndqofL+S8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=MteOdrjH; arc=none smtp.client-ip=209.85.210.169 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="MteOdrjH" Received: by mail-pf1-f169.google.com with SMTP id d2e1a72fcca58-8486672f03cso487413b3a.0 for ; Thu, 20 Aug 2026 20:35:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1787283334; x=1787888134; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=8z8jtMwqCWMdyAG7GnrJyVQOSLL3vRy/5P+Lo2373Zg=; b=MteOdrjHUwEPHTMg4g2Yb6GsCE6NdX5G0QXbZ0OWyDCSydpdDWuNJOW5gsbUeih2u7 TwX2s1NaaKHhVNOnH9i6erLtyuDbVs7+ZKU2SJz6N5UCN6pRCJ2HIUm2J2RZOzmhRFIJ y/OYehK0NZczD29xNz18jlhe5TPhrffc5W30Hrwsm8+kBN9Ls/4vsI0lbJ3IRIW6F3AY 9jP8P/RTeRe2xJG9jHF4hrFxAodHb9XwqsTLvedPlplPAB92VlSJXQGGf5/7WeH7PWHI RT2AoRCnMhcXnU80x94aFmjF4d1Fis7udfDoRtGCcnw4Ereu9SzkPLqoRZA1o4vCuxrJ DZzg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787283334; x=1787888134; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=8z8jtMwqCWMdyAG7GnrJyVQOSLL3vRy/5P+Lo2373Zg=; b=lwPTK62MYr9DJdArVgbA3rDdvi3PhGiEZ/4FQZmK74vvLdzSLhf1iXE88i7zDdUpCc AFNVJZGi/4TIwObaYVtrw80sUr60jYvLLMHs9WLfgCFwDfq82toLyb3k/ME+LYxElQqd 6Lro6ZPW48qL9hZExif/LVHzUfuxsgwZSBz1Dm7iMboWjeR+k7NphyqB1+sRrMHxxOTm EpD++Il0dFflb7gH3D88Oqt+o/ESKfGnMoGNCk1/oOBvfpDl4ZASd3h+qQW7zLXGdis4 oPD79ZyYsSvOLYsKLsj5pvkfZ95Kum4kiqKws6QdiM43IVJaocmc1TjiwYsMmZX/TI3Q tThA== X-Gm-Message-State: AOJu0YzSPEYr3QBXM4h+fNBvQ44pP9ahc0DI/diy6/qYQC7n/sBZKSgc aKcpwnDSRDRKxA/0NbYHDp6Fn1Lm2tHnaf9dbOAeHFLAjX/yxbFYfNvjXw84+Q== X-Gm-Gg: AR+sD12twSvDFoIe9q8x7hedknRPcsESAnmb1D6nz3Lalk11aZN0R2k9fk+qMsSRc3A cQLL1W5DiST4usZAiroSJkrATZwZacOK7CUF1vC5cC+n6YSxpL6Rnvw+/Q+g/F5iIOo7ppHBuMG 1IMnwvLxZx1IDtYNiHe/n7Q4TyP9zgqg7RRBDNEWcv3xFOA29BU9M4q3dm624jk0ueoLSUalGUQ hNuOoXIZhrguxs54Fx0CSieOj4Yluj+op01/BilyccuA8gONXTO2OCZXssM32Ihnaeyt3wDE9nn WIA/Ihi2hedANPl3q50/DmZSlnCAQlAePBiXqu1bSSp5buOEknse5BGTPIeTd5ZzhOIqazmPuh2 6x0Jk4DPTZxyR269rqrmhCJxMv07lXWI34JEwI6P77cdzDFK9J+WUdavIk1ZKvPrfYy2e0RKnqa rxTMcVyOQIIVs2Sjq/y9weXrJI4FVT/6Hu5XoWXmfdoxWYAjRWUGrZ/jVOeWUWXG18x3qa6qZUq Ow/1NF8meXx3B6AKItHWzpAnKPtZN0= X-Received: by 2002:a05:6a20:9145:b0:3c4:46ca:334b with SMTP id adf61e73a8af0-3cd3076a57amr4722368637.9.1787283333906; Thu, 20 Aug 2026 20:35:33 -0700 (PDT) Received: from hcdev-d520mt2.. (60-250-196-139.hinet-ip.hinet.net. [60.250.196.139]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-cc15891a04csm2204271a12.15.2026.08.20.20.35.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Aug 2026 20:35:33 -0700 (PDT) From: a0282524688@gmail.com To: lee@kernel.org, Ming Yu Cc: linux-kernel@vger.kernel.org, Ming Yu , mfd@lists.linux.dev Subject: [PATCH v7 04/10] mfd: nct6694: Rename driver to nct6694-usb and update Kconfig Date: Fri, 21 Aug 2026 11:34:59 +0800 Message-Id: <20260821033505.4017901-5-a0282524688@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260821033505.4017901-1-a0282524688@gmail.com> References: <20260821033505.4017901-1-a0282524688@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Ming Yu Rename nct6694.c to nct6694-usb.c to accurately reflect that it implements the USB transport backend. Additionally, introduce a new MFD_NCT6694_USB Kconfig option and convert the existing MFD_NCT6694 into a hidden core symbol. The core symbol is now automatically selected by the transport drivers. This Kconfig and naming restructure aligns with standard MFD transport abstraction practices, paving the way for future interfaces (e.g., HIF) to be seamlessly integrated. Signed-off-by: Ming Yu --- Changes in v7: Changes in v6: Changes in v5: - Split from the monolithic v4 patch to follow the single logical change principle. MAINTAINERS | 2 +- drivers/mfd/Kconfig | 31 ++++++++++++++++-------- drivers/mfd/Makefile | 2 +- drivers/mfd/{nct6694.c =3D> nct6694-usb.c} | 0 4 files changed, 23 insertions(+), 12 deletions(-) rename drivers/mfd/{nct6694.c =3D> nct6694-usb.c} (100%) diff --git a/MAINTAINERS b/MAINTAINERS index 040df7bfb24f..89d7339f3613 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -19356,7 +19356,7 @@ S: Supported F: drivers/gpio/gpio-nct6694.c F: drivers/hwmon/nct6694-hwmon.c F: drivers/i2c/busses/i2c-nct6694.c -F: drivers/mfd/nct6694.c +F: drivers/mfd/nct6694-usb.c F: drivers/net/can/usb/nct6694_canfd.c F: drivers/rtc/rtc-nct6694.c F: drivers/watchdog/nct6694_wdt.c diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 763ce6a34782..5506a0adf3ec 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -1164,19 +1164,30 @@ config MFD_MENF21BMC will be called menf21bmc. =20 config MFD_NCT6694 - tristate "Nuvoton NCT6694 support" + tristate select MFD_CORE + help + Core MFD support for the Nuvoton NCT6694 peripheral expander. + This provides the common APIs and shared structures used by all + interfaces (USB, HIF) to access the NCT6694 hardware features + such as GPIO, I2C, CAN-FD, Watchdog, ADC, PWM, and RTC. + + It is selected automatically by the transport interface drivers. + +config MFD_NCT6694_USB + tristate "Nuvoton NCT6694 USB interface support" + select MFD_NCT6694 depends on USB help - This enables support for the Nuvoton USB device NCT6694, which shares - peripherals. - The Nuvoton NCT6694 is a peripheral expander with 16 GPIO chips, - 6 I2C controllers, 2 CANfd controllers, 2 Watchdog timers, ADC, - PWM, and RTC. - This driver provides core APIs to access the NCT6694 hardware - monitoring and control features. - Additional drivers must be enabled to utilize the specific - functionalities of the device. + This enables support for the Nuvoton NCT6694 peripheral expander + connected via the USB interface. + + The transport driver uses USB bulk and interrupt transfers to + communicate with the NCT6694 firmware. Enable this option if you + are using the NCT6694 via a USB connection. + + To compile this driver as a module, choose M here: the module + will be called nct6694-usb. =20 config MFD_OCELOT tristate "Microsemi Ocelot External Control Support" diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index dd4bb7e77c33..48caac64f3d8 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -124,7 +124,7 @@ obj-$(CONFIG_MFD_MC13XXX_I2C) +=3D mc13xxx-i2c.o =20 obj-$(CONFIG_MFD_PF1550) +=3D pf1550.o =20 -obj-$(CONFIG_MFD_NCT6694) +=3D nct6694.o +obj-$(CONFIG_MFD_NCT6694_USB) +=3D nct6694-usb.o =20 obj-$(CONFIG_MFD_CORE) +=3D mfd-core.o =20 diff --git a/drivers/mfd/nct6694.c b/drivers/mfd/nct6694-usb.c similarity index 100% rename from drivers/mfd/nct6694.c rename to drivers/mfd/nct6694-usb.c --=20 2.34.1 From nobody Mon Sep 28 14:47:00 2026 Received: from mail-pf1-f178.google.com (mail-pf1-f178.google.com [209.85.210.178]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BC2C0379EEC for ; Fri, 21 Aug 2026 03:35:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.178 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787283340; cv=none; b=cfIi9TV589mHSTkKmofE7yg0aSUicGFxGMxvlsMk6ixidDDS8umZvjnMu6/B1+5mzXhJ9iiWT6QwvmgPuIk1ANhsOZlh0Gf9ofaKa2oGYg+kUVjr9PQ91qXmblzujrCz3ntM4KWxkePbGK4e4eAz1Vf3DG4GFku0pic2hgSNzqM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787283340; c=relaxed/simple; bh=nSz6wcwgyRgc1iEzhbH88AYggGVwlQeE0IR33X9sbN8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=nZt9dYPEgfoGoFd5OksZEPfxoHC60VaaBQJ8OGvnZ66A+RametgPk6DMNgMSglct8P2Sq+gJrQhK4wTqKqKckoI2PjWcfApF8rGCx5GKosV0m070qKRIidBJFsNKy8oCTL1yeQ7I10WEGxPeB0TeE72RSMdA8sXn34qrmpAW6lk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=AFk7qczo; arc=none smtp.client-ip=209.85.210.178 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="AFk7qczo" Received: by mail-pf1-f178.google.com with SMTP id d2e1a72fcca58-84e04df8c46so554501b3a.2 for ; Thu, 20 Aug 2026 20:35:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1787283337; x=1787888137; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=1HV8tF5lTWFg/1+hCOdvfUfHSp/0aVR5guSwhRB7pK4=; b=AFk7qczoyjXFZ2lwf8VfZKOHhUDQeKCscPGbxYedoDppUlVG9mUV2w2ORCTcHzCXmM SKBxR8mJPvPfjGnb+OCbW0FYooOtuqR4Gz6+cxSYLpGWgWjw7f9IIXM16N7OsQifdfnb D3lZJWMk2/8JIdHgoWK+m7/rfv0SUJIeAFo39dhvJUCShCTMXPnF5iB9WMfoygGFBcvD T8c3/kXWRm3zz+u/eaiTs9jhF/Jo0UK/EcdaTfK8JPTW/p/NQDMEhlosgGL/dgjHSzGD k0MG/k+MYuvEyP0SVbOL+sBk9pA4j6m/7Kn5LDC24zh5Pzevd/nka34cclhp10MTHkOU jD2A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787283337; x=1787888137; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=1HV8tF5lTWFg/1+hCOdvfUfHSp/0aVR5guSwhRB7pK4=; b=I9kT1Cjjx3GKUcTzAhIr6tP/JG0K9NLDIkHyCCXnoA23r0nRTtWPSQgz45Sk3OBvFT UxBLZEQXayZWcYNlzampx88539pgqfuMQQqLTh6cxCE7rYDOHCsbZcfl3dZsgpNHEmzm fgUrSy6RSoXL4MYaAaRsG/sa6UsP1IoUpQrNvM1LajGLBuIlVe5c+cNZQaHmiW8R5emc O8Z072zzFCf5sytAz1ygpuDKSBAgxQPnvbHD/yHPuuHjrfsJyRple0j+c8Sau8J4G6nx 3oRBYwnVP8oSiGShuBVLMnHSeUingbNVhqE5AuVSewPLZklHS8MNSgJx56izUd+XhRYG 4KFA== X-Gm-Message-State: AOJu0YyyF4IzMVJngi1HqLugF0i3FHxW/KoNhBwfQnXYdqNJ7FRt7u2Q 4NYoaXIW2Glw6rYaujlTtS+D9Zqin85m40ZQlUxqSVsd57szwayk0Vyg X-Gm-Gg: AR+sD13KJ5ZCanYGvyx4WQvgT9nOcfOhj42LDvpdkaFlNOlRED61TrMZZsh9kRzmy1q yy1IMt6psx5T33hbwlee1O9qNs/tDYaHlNd1AKyUVmn1m5WTpdlUizXAMc3YRrm2DMiN5QKQRJp c5LdKakHHu26pf2z1sv8ZEnSrIGdmnq12EoRnEipnH4rW3WnWEt65/O4AxMtoWq7vnBiCCvhMaS OZeUWRToo/a0+QhdIp5DRYXR9SacweVEo7v02Lsg3U1oJAIs8LrHr9SfAj47eMDwlHganHR0o9/ afCFI/cKd41woVrkWYcNtRO9fXvTtvryCXPJP5DUA8X2oj9wQv18MemK3PIMyF1QVPOPYA6/e8i vI2ZSZ2ZBcuffmRqC7l2xRDMG7f2a7br8Q1xM9WnfOMI8j5NdXomeAotp1jjy/EV1mJz+jBgsY2 n21DuyVQ9nydnKWyFkwZP5qpfOtKe8EoeyweyRZfbqgOdv125NPdnwzNx9XBT4mzmlZ/LKSFhVq vtF2Ui+qmZPzcO7tRsXtQXckZxu0HDTPc5JPcyoxJw= X-Received: by 2002:a05:6a20:ac43:b0:3c3:935a:af2c with SMTP id adf61e73a8af0-3cd2fd03751mr6890208637.3.1787283336565; Thu, 20 Aug 2026 20:35:36 -0700 (PDT) Received: from hcdev-d520mt2.. (60-250-196-139.hinet-ip.hinet.net. [60.250.196.139]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-cc15891a04csm2204271a12.15.2026.08.20.20.35.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Aug 2026 20:35:36 -0700 (PDT) From: a0282524688@gmail.com To: lee@kernel.org, Ming Yu Cc: linux-kernel@vger.kernel.org, Ming Yu , mfd@lists.linux.dev Subject: [PATCH v7 05/10] mfd: nct6694: Extract core device management into a separate module Date: Fri, 21 Aug 2026 11:35:00 +0800 Message-Id: <20260821033505.4017901-6-a0282524688@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260821033505.4017901-1-a0282524688@gmail.com> References: <20260821033505.4017901-1-a0282524688@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Ming Yu Extract the transport-agnostic core logic, including IRQ domain setup, IDA initialization, and MFD sub-device registration, from the USB driver into a new nct6694-core.c module. The core routines are exported as nct6694_core_probe() and nct6694_core_remove() to be consumed by the transport drivers. The USB driver is updated to pass its specific MFD cells to the core probe routine. This completes the transport abstraction, ensuring that the shared device management logic is cleanly separated from the underlying I/O implementation, and is fully ready for new transport backends (e.g., HIF). Signed-off-by: Ming Yu --- Changes in v7: Changes in v6: - Reordered to sit before the transport-abstraction patch; no functional change. Changes in v5: - Split from the monolithic v4 patch to follow the single logical change principle. MAINTAINERS | 2 +- drivers/mfd/Makefile | 1 + drivers/mfd/nct6694-core.c | 136 ++++++++++++++++++++++++++++++++++++ drivers/mfd/nct6694-usb.c | 91 ++---------------------- include/linux/mfd/nct6694.h | 9 ++- 5 files changed, 153 insertions(+), 86 deletions(-) create mode 100644 drivers/mfd/nct6694-core.c diff --git a/MAINTAINERS b/MAINTAINERS index 89d7339f3613..f1894e88ba62 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -19356,7 +19356,7 @@ S: Supported F: drivers/gpio/gpio-nct6694.c F: drivers/hwmon/nct6694-hwmon.c F: drivers/i2c/busses/i2c-nct6694.c -F: drivers/mfd/nct6694-usb.c +F: drivers/mfd/nct6694-*.c F: drivers/net/can/usb/nct6694_canfd.c F: drivers/rtc/rtc-nct6694.c F: drivers/watchdog/nct6694_wdt.c diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 48caac64f3d8..10c19a19541e 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -124,6 +124,7 @@ obj-$(CONFIG_MFD_MC13XXX_I2C) +=3D mc13xxx-i2c.o =20 obj-$(CONFIG_MFD_PF1550) +=3D pf1550.o =20 +obj-$(CONFIG_MFD_NCT6694) +=3D nct6694-core.o obj-$(CONFIG_MFD_NCT6694_USB) +=3D nct6694-usb.o =20 obj-$(CONFIG_MFD_CORE) +=3D mfd-core.o diff --git a/drivers/mfd/nct6694-core.c b/drivers/mfd/nct6694-core.c new file mode 100644 index 000000000000..36dfaa2e327f --- /dev/null +++ b/drivers/mfd/nct6694-core.c @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2026 Nuvoton Technology Corp. + * + * Nuvoton NCT6694 MFD core driver. + * + * This provides common registration for IRQ domain, IDA pools, + * and MFD sub-devices shared by all transport drivers. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static void nct6694_irq_enable(struct irq_data *data) +{ + struct nct6694 *nct6694 =3D irq_data_get_irq_chip_data(data); + irq_hw_number_t hwirq =3D irqd_to_hwirq(data); + + guard(spinlock_irqsave)(&nct6694->irq_lock); + + nct6694->irq_enable |=3D BIT(hwirq); +} + +static void nct6694_irq_disable(struct irq_data *data) +{ + struct nct6694 *nct6694 =3D irq_data_get_irq_chip_data(data); + irq_hw_number_t hwirq =3D irqd_to_hwirq(data); + + guard(spinlock_irqsave)(&nct6694->irq_lock); + + nct6694->irq_enable &=3D ~BIT(hwirq); +} + +static const struct irq_chip nct6694_irq_chip =3D { + .name =3D "nct6694-irq", + .flags =3D IRQCHIP_SKIP_SET_WAKE, + .irq_enable =3D nct6694_irq_enable, + .irq_disable =3D nct6694_irq_disable, +}; + +static int nct6694_irq_domain_map(struct irq_domain *d, unsigned int irq, + irq_hw_number_t hw) +{ + struct nct6694 *nct6694 =3D d->host_data; + + irq_set_chip_data(irq, nct6694); + irq_set_chip_and_handler(irq, &nct6694_irq_chip, handle_simple_irq); + + return 0; +} + +static void nct6694_irq_domain_unmap(struct irq_domain *d, unsigned int ir= q) +{ + irq_set_chip_and_handler(irq, NULL, NULL); + irq_set_chip_data(irq, NULL); +} + +static const struct irq_domain_ops nct6694_irq_domain_ops =3D { + .map =3D nct6694_irq_domain_map, + .unmap =3D nct6694_irq_domain_unmap, +}; + +/** + * nct6694_core_probe() - Register IRQ domain, IDAs, and MFD sub-devices + * @dev: parent device (USB interface or platform device) + * @nct6694: initialized nct6694 structure with its transport regmap set + * + * This function completes the common probe steps shared by all transport + * drivers: IRQ domain creation, IDA initialization, and MFD cell registra= tion. + * + * The caller must have already set nct6694->dev, nct6694->priv, and + * nct6694->regmap before calling this. + * + * Return: 0 on success or negative errno on failure. + */ +int nct6694_core_probe(struct device *dev, struct nct6694 *nct6694, + const struct mfd_cell *cells, int n_cells) +{ + int ret; + + spin_lock_init(&nct6694->irq_lock); + + ida_init(&nct6694->gpio_ida); + ida_init(&nct6694->i2c_ida); + ida_init(&nct6694->canfd_ida); + ida_init(&nct6694->wdt_ida); + + nct6694->domain =3D irq_domain_create_simple(NULL, NCT6694_NR_IRQS, 0, + &nct6694_irq_domain_ops, + nct6694); + if (!nct6694->domain) { + ret =3D -ENODEV; + goto err_ida; + } + + ret =3D mfd_add_hotplug_devices(dev, cells, n_cells); + if (ret) + goto err_domain; + + return 0; + +err_domain: + irq_domain_remove(nct6694->domain); +err_ida: + ida_destroy(&nct6694->wdt_ida); + ida_destroy(&nct6694->canfd_ida); + ida_destroy(&nct6694->i2c_ida); + ida_destroy(&nct6694->gpio_ida); + return ret; +} +EXPORT_SYMBOL_GPL(nct6694_core_probe); + +/** + * nct6694_core_remove() - Unregister MFD sub-devices and free core resour= ces + * @nct6694: nct6694 structure previously passed to nct6694_core_probe() + */ +void nct6694_core_remove(struct nct6694 *nct6694) +{ + mfd_remove_devices(nct6694->dev); + irq_domain_remove(nct6694->domain); + ida_destroy(&nct6694->wdt_ida); + ida_destroy(&nct6694->canfd_ida); + ida_destroy(&nct6694->i2c_ida); + ida_destroy(&nct6694->gpio_ida); +} +EXPORT_SYMBOL_GPL(nct6694_core_remove); + +MODULE_DESCRIPTION("Nuvoton NCT6694 MFD core driver"); +MODULE_AUTHOR("Ming Yu "); +MODULE_LICENSE("GPL"); diff --git a/drivers/mfd/nct6694-usb.c b/drivers/mfd/nct6694-usb.c index 7c6b986db7f7..2289ebfde7fa 100644 --- a/drivers/mfd/nct6694-usb.c +++ b/drivers/mfd/nct6694-usb.c @@ -10,7 +10,6 @@ */ =20 #include -#include #include #include #include @@ -19,7 +18,6 @@ #include #include #include -#include #include =20 #define NCT6694_VENDOR_ID 0x0416 @@ -246,57 +244,9 @@ static void nct6694_usb_int_callback(struct urb *urb) resubmit: ret =3D usb_submit_urb(urb, GFP_ATOMIC); if (ret) - dev_warn(nct6694->dev, "Failed to resubmit urb, status %pe", ERR_PTR(re= t)); + dev_warn(nct6694->dev, "Failed to resubmit urb, status %pe", ERR_PTR(ret= )); } =20 -static void nct6694_irq_enable(struct irq_data *data) -{ - struct nct6694 *nct6694 =3D irq_data_get_irq_chip_data(data); - irq_hw_number_t hwirq =3D irqd_to_hwirq(data); - - guard(spinlock_irqsave)(&nct6694->irq_lock); - - nct6694->irq_enable |=3D BIT(hwirq); -} - -static void nct6694_irq_disable(struct irq_data *data) -{ - struct nct6694 *nct6694 =3D irq_data_get_irq_chip_data(data); - irq_hw_number_t hwirq =3D irqd_to_hwirq(data); - - guard(spinlock_irqsave)(&nct6694->irq_lock); - - nct6694->irq_enable &=3D ~BIT(hwirq); -} - -static const struct irq_chip nct6694_irq_chip =3D { - .name =3D "nct6694-irq", - .flags =3D IRQCHIP_SKIP_SET_WAKE, - .irq_enable =3D nct6694_irq_enable, - .irq_disable =3D nct6694_irq_disable, -}; - -static int nct6694_irq_domain_map(struct irq_domain *d, unsigned int irq, = irq_hw_number_t hw) -{ - struct nct6694 *nct6694 =3D d->host_data; - - irq_set_chip_data(irq, nct6694); - irq_set_chip_and_handler(irq, &nct6694_irq_chip, handle_simple_irq); - - return 0; -} - -static void nct6694_irq_domain_unmap(struct irq_domain *d, unsigned int ir= q) -{ - irq_set_chip_and_handler(irq, NULL, NULL); - irq_set_chip_data(irq, NULL); -} - -static const struct irq_domain_ops nct6694_irq_domain_ops =3D { - .map =3D nct6694_irq_domain_map, - .unmap =3D nct6694_irq_domain_unmap, -}; - static int nct6694_usb_probe(struct usb_interface *iface, const struct usb_device_id *id) { @@ -330,35 +280,19 @@ static int nct6694_usb_probe(struct usb_interface *if= ace, =20 udata->udev =3D udev; =20 - nct6694->priv =3D udata; - - nct6694->domain =3D irq_domain_create_simple(NULL, NCT6694_NR_IRQS, 0, - &nct6694_irq_domain_ops, - nct6694); - if (!nct6694->domain) { - ret =3D -ENODEV; - goto err_urb; - } - nct6694->dev =3D dev; - - ida_init(&nct6694->gpio_ida); - ida_init(&nct6694->i2c_ida); - ida_init(&nct6694->canfd_ida); - ida_init(&nct6694->wdt_ida); - - spin_lock_init(&nct6694->irq_lock); + nct6694->priv =3D udata; =20 ret =3D devm_mutex_init(dev, &udata->access_lock); if (ret) - goto err_ida; + goto err_urb; =20 interface =3D iface->cur_altsetting; =20 int_endpoint =3D &interface->endpoint[0].desc; if (!usb_endpoint_is_int_in(int_endpoint)) { ret =3D -ENODEV; - goto err_ida; + goto err_urb; } =20 usb_fill_int_urb(udata->int_in_urb, udev, usb_rcvintpipe(udev, NCT6694_IN= T_IN_EP), @@ -367,11 +301,11 @@ static int nct6694_usb_probe(struct usb_interface *if= ace, =20 ret =3D usb_submit_urb(udata->int_in_urb, GFP_KERNEL); if (ret) - goto err_ida; + goto err_urb; =20 usb_set_intfdata(iface, nct6694); =20 - ret =3D mfd_add_hotplug_devices(dev, nct6694_usb_devs, ARRAY_SIZE(nct6694= _usb_devs)); + ret =3D nct6694_core_probe(dev, nct6694, nct6694_usb_devs, ARRAY_SIZE(nct= 6694_usb_devs)); if (ret) goto err_mfd; =20 @@ -379,12 +313,6 @@ static int nct6694_usb_probe(struct usb_interface *ifa= ce, =20 err_mfd: usb_kill_urb(udata->int_in_urb); -err_ida: - ida_destroy(&nct6694->wdt_ida); - ida_destroy(&nct6694->canfd_ida); - ida_destroy(&nct6694->i2c_ida); - ida_destroy(&nct6694->gpio_ida); - irq_domain_remove(nct6694->domain); err_urb: usb_free_urb(udata->int_in_urb); return ret; @@ -395,13 +323,8 @@ static void nct6694_usb_disconnect(struct usb_interfac= e *iface) struct nct6694 *nct6694 =3D usb_get_intfdata(iface); struct nct6694_usb_data *udata =3D nct6694->priv; =20 - mfd_remove_devices(nct6694->dev); + nct6694_core_remove(nct6694); usb_kill_urb(udata->int_in_urb); - ida_destroy(&nct6694->wdt_ida); - ida_destroy(&nct6694->canfd_ida); - ida_destroy(&nct6694->i2c_ida); - ida_destroy(&nct6694->gpio_ida); - irq_domain_remove(nct6694->domain); usb_free_urb(udata->int_in_urb); } =20 diff --git a/include/linux/mfd/nct6694.h b/include/linux/mfd/nct6694.h index 43b51f243e8e..853b1530755d 100644 --- a/include/linux/mfd/nct6694.h +++ b/include/linux/mfd/nct6694.h @@ -10,10 +10,13 @@ #define __MFD_NCT6694_H =20 #include -#include #include #include =20 +struct device; +struct irq_domain; +struct mfd_cell; + #define NCT6694_HWMON_MOD 0x00 #define NCT6694_PWM_MOD 0x01 #define NCT6694_I2C_MOD 0x03 @@ -94,6 +97,10 @@ struct nct6694 { void *priv; }; =20 +int nct6694_core_probe(struct device *dev, struct nct6694 *nct6694, + const struct mfd_cell *cells, int n_cells); +void nct6694_core_remove(struct nct6694 *nct6694); + int nct6694_usb_read_msg(struct nct6694 *nct6694, const struct nct6694_cmd_header *cmd_hd, void *buf); --=20 2.34.1 From nobody Mon Sep 28 14:47:00 2026 Received: from mail-pf1-f182.google.com (mail-pf1-f182.google.com [209.85.210.182]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8D180377AA0 for ; Fri, 21 Aug 2026 03:35:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787283343; cv=none; b=J0W1W8f3XWgsMawO6v3xflmDE62cJSnPZ5kUUcGR56dJuW43omIQB6nof2Or1CWmVNXNCJ45LBdq1zmF+vIhc0sDMq5hmdBqJFirISh1PstS90DMxz0f1b3WxQsrSdooEWEC3g8l3foTctRd1o+y/VP3oIH9GCGK3XEY+7hj/Gs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787283343; c=relaxed/simple; bh=dh6ypal0eP9TY0RyxbOZW37QBS/0wHMrW1fkKLXmnZQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=grCmWvoS95EuI7BBYatUlsMSP5K2o3BF3bzs2SWDAcbq4rh35JJhLGbuAyVmsjrPBaYd/mQD8Zs4mFswKBsX/Jp88gNlsXTdOuaf8zSZfXIM7vyuB1aG91KjvCWGkWobPfO/IS5ED6K6dRbim3BSMv9eF8eV3sjmU0dqeh7+JfE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=J04DKAv0; arc=none smtp.client-ip=209.85.210.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="J04DKAv0" Received: by mail-pf1-f182.google.com with SMTP id d2e1a72fcca58-848643382fcso492540b3a.1 for ; Thu, 20 Aug 2026 20:35:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1787283339; x=1787888139; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=akgiGKYdVb/X1Q1qbgoX9eIBpnqoztnG/F+moLn7cbc=; b=J04DKAv0JsBSwy9GT1+MtuldkRbIwJAY6oF7JrHZ/VcbR/nVBBtcNqdi25BIqVIs92 gVOTVDa5WDRklHbRb4VsSV0QUkjHuMm1vbzVbEQyzKbed7dYRxFZUqnNZtWerl4xPv+r Nz5yg9f7bIp4X52AJWpDqROGy0IZlT6o2QjRRM4qQyjJW3Mf9rf/0WuTzdoVK9sKo6DU j3L5Z6Cn4yjsIH2Wm9AEqxbI9qRBI9msRGPQfdfxYuhQ9X6LVU9UdeOu5vKXdLlf/EvQ gpuYhkNEnjVRqJ+g9m1HX68Gj/cTIYg2hyoa4uMU5NtzzOcjrP7vlPQxSYDJ8OTCPvra oI5w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787283339; x=1787888139; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=akgiGKYdVb/X1Q1qbgoX9eIBpnqoztnG/F+moLn7cbc=; b=iXwTGd/jfM3Y6qBQvwf1ItNfbzVh6M9XqZhbSEfZb3BRMzRhxXr+vPLs9Zpi+iE/AS e0ctJy5Hra/n7NJAZmgrTIb3qwg2WyS/WMc9Fqq3gpFjpCPkiAUpGB/s2diISEcCxwr6 fOUW+VKOjmmKCady4U4wtWuEZo3dsiQPeOIbWkhLksmPctd+YmZ4kSOXfY+ArRLNh5P5 7QgeZtFYWgrCr0LEEdQiROstXASCwagXw4CzOWuz+xCSiBGA3xO313weJIc17zHRJ9Qt I1jGJApCXuXYmQWIZgs2xUx+azkx83ipNrAuwtyI1FvET9pLybw4FI25OvbgWsBfkyQk JmXA== X-Gm-Message-State: AOJu0YyMFPWmJAEoR6rT/oANnIF5A0XTzSTbyA8jqfz0rVljPWBpFWbb Qrx6vO5NljPZsNzRnEUf55MhUsSS3+hUhE3shaCs4oHXp+g24/mYzexET/W4vQ== X-Gm-Gg: AR+sD13j6ONPRnIRYWmhXVBEcx3ijGuRt/YYbST3ood5tC003pAL5jq952U2LbZTMI+ Yg+5qZeIvQZy8nI8x4y0HFYSef827aciokGVUeW/IyRg/gGfmc6N7vRlVHF/6zrkRtZmrCm72NB tTuJs4EhBBnYkoYiTYnGJW7N9S1AhdHRxzaV351fkAiQ/03pF/LAFRMQwRbqaS96IjYxQkP7zTK Lskb5Z51/C1cm/rT4QjRAfPKgD35JvVNfUyAYGyHoUDgeLjplhBZ0s2hLJFI5vfBd49LxM9Q0D8 sVoiFuuHcgDtp0/otY365W+kYaMAwnsz4RF9xjj5iEYXO1EFlwqN5ghUeqyWJ4Y44USGsAm1Cab 2JwtigHL4tARO33WFnlJnxEMQtsjzySQGwGB5rqKRHELh4XYW2A50e+ZtNM6BXoKF1o3//DjM8h SrsNZ3MqaefA39Psc+RUzmWtV0ZvPeCnvmZxoLAMu5Eg0NfajVktEfPlL/oJX9KIp9m/Hy08l1f J6LZnRgTodY7VAlY7zASpvwnBVHRen9 X-Received: by 2002:a05:6a20:3d94:b0:3b3:26aa:5455 with SMTP id adf61e73a8af0-3cd300f9e23mr6147186637.13.1787283338691; Thu, 20 Aug 2026 20:35:38 -0700 (PDT) Received: from hcdev-d520mt2.. (60-250-196-139.hinet-ip.hinet.net. [60.250.196.139]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-cc15891a04csm2204271a12.15.2026.08.20.20.35.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Aug 2026 20:35:38 -0700 (PDT) From: a0282524688@gmail.com To: lee@kernel.org, Ming Yu Cc: linux-kernel@vger.kernel.org, Ming Yu , mfd@lists.linux.dev Subject: [PATCH v7 06/10] mfd: nct6694: Transfer command payloads via a dedicated DMA buffer Date: Fri, 21 Aug 2026 11:35:01 +0800 Message-Id: <20260821033505.4017901-7-a0282524688@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260821033505.4017901-1-a0282524688@gmail.com> References: <20260821033505.4017901-1-a0282524688@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Ming Yu The transport hands the caller's payload buffer straight to usb_bulk_msg(). Sub-device drivers embed those buffers in their private data structures, so they are neither cacheline aligned nor exclusively owned by the transfer. On non-coherent architectures, mapping such a buffer for DMA can corrupt the unrelated fields sharing its cachelines. Transfer the payload through a buffer owned by the transport instead, and reject commands exceeding the maximum firmware packet size. Fixes: 51dad33ede63 ("mfd: Add core driver for Nuvoton NCT6694") Signed-off-by: Ming Yu --- Changes in v7: - New patch. Fixes the DMA-unsafe use of caller-owned payload buffers reported on v6 patch 6/7. drivers/mfd/nct6694-usb.c | 38 +++++++++++++++++++++++++++---------- include/linux/mfd/nct6694.h | 3 +++ 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/drivers/mfd/nct6694-usb.c b/drivers/mfd/nct6694-usb.c index 2289ebfde7fa..793ce54c02aa 100644 --- a/drivers/mfd/nct6694-usb.c +++ b/drivers/mfd/nct6694-usb.c @@ -38,6 +38,7 @@ struct nct6694_usb_data { struct urb *int_in_urb; struct usb_device *udev; union nct6694_usb_msg *usb_msg; + void *xfer_buf; __le32 *int_buffer; }; =20 @@ -120,8 +121,12 @@ int nct6694_usb_read_msg(struct nct6694 *nct6694, struct nct6694_usb_data *udata =3D nct6694->priv; union nct6694_usb_msg *msg =3D udata->usb_msg; struct usb_device *udev =3D udata->udev; + u16 len =3D le16_to_cpu(cmd_hd->len); int tx_len, rx_len, ret; =20 + if (len > NCT6694_MAX_PACKET_SIZE) + return -EINVAL; + guard(mutex)(&udata->access_lock); =20 memcpy(&msg->cmd_header, cmd_hd, sizeof(*cmd_hd)); @@ -140,17 +145,19 @@ int nct6694_usb_read_msg(struct nct6694 *nct6694, return ret; =20 /* Receive data packet from USB device */ - ret =3D usb_bulk_msg(udev, usb_rcvbulkpipe(udev, NCT6694_BULK_IN_EP), buf, - le16_to_cpu(cmd_hd->len), &rx_len, NCT6694_URB_TIMEOUT); + ret =3D usb_bulk_msg(udev, usb_rcvbulkpipe(udev, NCT6694_BULK_IN_EP), uda= ta->xfer_buf, + len, &rx_len, NCT6694_URB_TIMEOUT); if (ret) return ret; =20 - if (rx_len !=3D le16_to_cpu(cmd_hd->len)) { + if (rx_len !=3D len) { dev_err(nct6694->dev, "Expected received length %d, but got %d\n", - le16_to_cpu(cmd_hd->len), rx_len); + len, rx_len); return -EIO; } =20 + memcpy(buf, udata->xfer_buf, len); + return nct6694_usb_err_handling(nct6694, msg->response_header.sts); } EXPORT_SYMBOL_GPL(nct6694_usb_read_msg); @@ -173,12 +180,17 @@ int nct6694_usb_write_msg(struct nct6694 *nct6694, struct nct6694_usb_data *udata =3D nct6694->priv; union nct6694_usb_msg *msg =3D udata->usb_msg; struct usb_device *udev =3D udata->udev; + u16 len =3D le16_to_cpu(cmd_hd->len); int tx_len, rx_len, ret; =20 + if (len > NCT6694_MAX_PACKET_SIZE) + return -EINVAL; + guard(mutex)(&udata->access_lock); =20 memcpy(&msg->cmd_header, cmd_hd, sizeof(*cmd_hd)); msg->cmd_header.hctrl =3D NCT6694_HCTRL_SET; + memcpy(udata->xfer_buf, buf, len); =20 /* Send command packet to USB device */ ret =3D usb_bulk_msg(udev, usb_sndbulkpipe(udev, NCT6694_BULK_OUT_EP), &m= sg->cmd_header, @@ -187,8 +199,8 @@ int nct6694_usb_write_msg(struct nct6694 *nct6694, return ret; =20 /* Send data packet to USB device */ - ret =3D usb_bulk_msg(udev, usb_sndbulkpipe(udev, NCT6694_BULK_OUT_EP), bu= f, - le16_to_cpu(cmd_hd->len), &tx_len, NCT6694_URB_TIMEOUT); + ret =3D usb_bulk_msg(udev, usb_sndbulkpipe(udev, NCT6694_BULK_OUT_EP), ud= ata->xfer_buf, + len, &tx_len, NCT6694_URB_TIMEOUT); if (ret) return ret; =20 @@ -199,17 +211,19 @@ int nct6694_usb_write_msg(struct nct6694 *nct6694, return ret; =20 /* Receive data packet from USB device */ - ret =3D usb_bulk_msg(udev, usb_rcvbulkpipe(udev, NCT6694_BULK_IN_EP), buf, - le16_to_cpu(cmd_hd->len), &rx_len, NCT6694_URB_TIMEOUT); + ret =3D usb_bulk_msg(udev, usb_rcvbulkpipe(udev, NCT6694_BULK_IN_EP), uda= ta->xfer_buf, + len, &rx_len, NCT6694_URB_TIMEOUT); if (ret) return ret; =20 - if (rx_len !=3D le16_to_cpu(cmd_hd->len)) { + if (rx_len !=3D len) { dev_err(nct6694->dev, "Expected transmitted length %d, but got %d\n", - le16_to_cpu(cmd_hd->len), rx_len); + len, rx_len); return -EIO; } =20 + memcpy(buf, udata->xfer_buf, len); + return nct6694_usb_err_handling(nct6694, msg->response_header.sts); } EXPORT_SYMBOL_GPL(nct6694_usb_write_msg); @@ -270,6 +284,10 @@ static int nct6694_usb_probe(struct usb_interface *ifa= ce, if (!udata->usb_msg) return -ENOMEM; =20 + udata->xfer_buf =3D devm_kzalloc(dev, NCT6694_MAX_PACKET_SIZE, GFP_KERNEL= ); + if (!udata->xfer_buf) + return -ENOMEM; + udata->int_buffer =3D devm_kzalloc(dev, sizeof(*udata->int_buffer), GFP_K= ERNEL); if (!udata->int_buffer) return -ENOMEM; diff --git a/include/linux/mfd/nct6694.h b/include/linux/mfd/nct6694.h index 853b1530755d..cb311e58a437 100644 --- a/include/linux/mfd/nct6694.h +++ b/include/linux/mfd/nct6694.h @@ -29,6 +29,9 @@ struct mfd_cell; #define NCT6694_HCTRL_SET 0x40 #define NCT6694_HCTRL_GET 0x80 =20 +/* Maximum payload length the firmware accepts in a single command */ +#define NCT6694_MAX_PACKET_SIZE 0x3F0 + enum nct6694_irq_id { NCT6694_IRQ_GPIO0 =3D 0, NCT6694_IRQ_GPIO1, --=20 2.34.1 From nobody Mon Sep 28 14:47:00 2026 Received: from mail-pf1-f171.google.com (mail-pf1-f171.google.com [209.85.210.171]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B0052377560 for ; Fri, 21 Aug 2026 03:35:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787283344; cv=none; b=ripmqI18IhMYyZKmAd8H1xIv8049VmKUrqjewwZPpYNiuiVwWTbuJqovMJuv4+MpLV4mlraXTQj/nTlxTdzLMaZtxDot1xoMVYi37hIpqfCywf3gnGrCnwdYyDQkuueJ0o8osSVzwRWcuUJh+2bXaqxwhVotu5uLETE1qCXxWqw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787283344; c=relaxed/simple; bh=KWUdr7QjdL/P5FemNe2dO+4gc717FuyqKfmff+EFr0M=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=UHG5Ttx57nBpBEK3i/yEkWSoEXM0jDC8Q1Ny02Y5DddInvMjJGhFFQdsf3yWr1VeRqywcDKBzXS1xSXSWH2OuvRWCfMLrAoEsIwqwZWtXzpgMBWY+HoCGrAN+oR7r+piTQjK88iHURH7jeLlUbB4TKILw1gi8lzWh6uMiZJQ3wY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=qyURAstI; arc=none smtp.client-ip=209.85.210.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="qyURAstI" Received: by mail-pf1-f171.google.com with SMTP id d2e1a72fcca58-8518d5ddaabso392380b3a.2 for ; Thu, 20 Aug 2026 20:35:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1787283340; x=1787888140; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=UJkZ6RvxbNcjAoli9z1uAOHLN7PuUwcVnyV1b+h3Wd0=; b=qyURAstIjHh28uICehrxEJ/JZopCKDxkuH0DfLHIJLLNOCCL///F/OXsqRnabOa0iM 9ipBp4lz7SGkyBgmK9BPVzmScI51IobtW3/UiUi/sRLWvC/tGBbmy7vGp8SWsnMxGUWU /yoRAcw74FAq0e+MjmdxgA68xT/27TlDio8/Tc4z520kZftnqs0NNcXqmLD9wCOXvMBk oblMi4Q3p3r7JFPMy87exUfNOxZqRxWLTAYqByCzmYFNmsNMIQbsqf/riKpchfPAb4aG QbGGenISVLB5DF6v75AjO00PoCePPmwjHJb22hIwQgLXc9hk11/Ztb/O1rGYEJnmILuA kVLw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787283340; x=1787888140; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=UJkZ6RvxbNcjAoli9z1uAOHLN7PuUwcVnyV1b+h3Wd0=; b=Zxgv7P4TwQCmFea5kbc2ORjphL+L3A6E+0MAjuuKNfYqyjJg2JqT68hrTDhK4h2AN/ dJ8dns3bwbariDFVt/u9cEouwyU/SVNqWfbnF52uezjmf103Kzdc59iGW3PKCp15P5kx dPloWhy5uPSIPnBpKBdWoSlSCzAPDOZ60sP15QpzNYVt7cuzYjC4KyW0q2GZGvSEOTPB Pj3xgWkMy6J4Ao+dZEWqCJ6JBqMJAWQWUyCxG/Aw3nmxRSniHUGOpzs93Of4pxNXg3yB ID5wORsdKaN1yn/Mh2Eoz8aQG580nJ9J932f9cxT1GCE7PcMS9V31mRYsSsyB1G7HHPa n7Hg== X-Gm-Message-State: AOJu0Yz7C9x9dh1XUtviMOkEarbOuVier/RwFL7TTg+4wdB/l9nJEcQE SdZL3RjOSbIO7IDYDJOqKYliZVqs2iXO2Rt2dbz1fMVimJ9zTHS+Cqan X-Gm-Gg: AR+sD12DP5M1J62nw/wYepIm+MCsl1KtxUYsAgUzlwWY95s7FUGubA8QqEUwN9A+U5T 5qF41LEULMxw3lh1b/mwUW3bWqIjcbyPrfoKTetUzWSP8tzg9e8J7qloxciqL09AQ0LRvZZE9X2 /lVA138EU790bcuHV+nfClTyKoOoyHAokrLNKlQjUIEz8VNF24ZkxckOxNsyqGkMYf42agMeUsh ImT8Wymlaxe0cmEulVj1Py7utf/xlfdhwMxn5QW6k+Lqpm4YR/fmnaZ5XaLZQZohwDILMog4zB8 fYZyjGMg5vy3mMcs9QWsnV7hTSFerzHv6RGqrPSrpWW3SYvt1WwKvA0czv5pqMsKF1t0duGWq4b ODwUfn5KE5TDW6Belf4blUx+Evct/0sCJCMotbhoJ2ogVzo9aw9SS3bO5V5lJDgslCM/U2AZR5T AHJT8GNrV7VgkoluC5TpaTjLWjXqcqRno80Qj1tA1MzjEgpnWWtdFdt85DD6CU3LKIC3sSOFT03 jACwnyDnNYaOCzgV2sFNmm+zfZOkDU= X-Received: by 2002:a05:6a20:b7aa:b0:3cb:c1f8:5722 with SMTP id adf61e73a8af0-3cd3007cfb5mr5560517637.10.1787283340537; Thu, 20 Aug 2026 20:35:40 -0700 (PDT) Received: from hcdev-d520mt2.. (60-250-196-139.hinet-ip.hinet.net. [60.250.196.139]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-cc15891a04csm2204271a12.15.2026.08.20.20.35.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Aug 2026 20:35:40 -0700 (PDT) From: a0282524688@gmail.com To: lee@kernel.org, Ming Yu Cc: linux-kernel@vger.kernel.org, Ming Yu , mfd@lists.linux.dev Subject: [PATCH v7 07/10] mfd: nct6694: Validate the interrupt IN endpoint Date: Fri, 21 Aug 2026 11:35:02 +0800 Message-Id: <20260821033505.4017901-8-a0282524688@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260821033505.4017901-1-a0282524688@gmail.com> References: <20260821033505.4017901-1-a0282524688@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Ming Yu The probe reads endpoint[0] of the current altsetting without checking that the interface actually describes any endpoint. A device reporting zero endpoints makes the driver read past the endpoint array. Locate the interrupt IN endpoint with usb_find_int_in_endpoint(), which validates the descriptor before it is used. Fixes: 51dad33ede63 ("mfd: Add core driver for Nuvoton NCT6694") Signed-off-by: Ming Yu --- Changes in v7: - New patch. Fixes the out-of-bounds endpoint access reported on v6 patch 6/7. drivers/mfd/nct6694-usb.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/mfd/nct6694-usb.c b/drivers/mfd/nct6694-usb.c index 793ce54c02aa..c8667984df5e 100644 --- a/drivers/mfd/nct6694-usb.c +++ b/drivers/mfd/nct6694-usb.c @@ -266,7 +266,6 @@ static int nct6694_usb_probe(struct usb_interface *ifac= e, { struct usb_device *udev =3D interface_to_usbdev(iface); struct usb_endpoint_descriptor *int_endpoint; - struct usb_host_interface *interface; struct device *dev =3D &iface->dev; struct nct6694_usb_data *udata; struct nct6694 *nct6694; @@ -305,13 +304,9 @@ static int nct6694_usb_probe(struct usb_interface *ifa= ce, if (ret) goto err_urb; =20 - interface =3D iface->cur_altsetting; - - int_endpoint =3D &interface->endpoint[0].desc; - if (!usb_endpoint_is_int_in(int_endpoint)) { - ret =3D -ENODEV; + ret =3D usb_find_int_in_endpoint(iface->cur_altsetting, &int_endpoint); + if (ret) goto err_urb; - } =20 usb_fill_int_urb(udata->int_in_urb, udev, usb_rcvintpipe(udev, NCT6694_IN= T_IN_EP), udata->int_buffer, sizeof(*udata->int_buffer), nct6694_usb_int_callbac= k, --=20 2.34.1 From nobody Mon Sep 28 14:47:00 2026 Received: from mail-pf1-f180.google.com (mail-pf1-f180.google.com [209.85.210.180]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F121737B00C for ; Fri, 21 Aug 2026 03:35:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.180 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787283346; cv=none; b=qFV8VJ9syOvIQHqf4dY38ua9tW18aAVwS0wt3rIKOFBWWZgd/+qTr6kMJY5So+P/Tx9gam552+cWY937rxOY9pTvK0IkSrveNu4o9FWr68Tlvgoc4l5iwyMI09J4YDfm5UqJ39u5GW3ipxDr7ZX0LeExmb25sNzwS/CJk4SV4wc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787283346; c=relaxed/simple; bh=p3VsYFoBXKb6WPzu/fYT+GrFxHpG26k5gXURQNYGlmQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Rt5d+a0Dmdd788AAX7nQZr8TgxCRrPPTzB++FkV2uJO4iOiw6XDnWg1ssfNPKZnQMe8w2nV8IdeY+1CJLT7gtLM+w3rOosBzCXgn+IDHnXs3Lhs5a1/FlHBNajdPc0Y/wkN6LVQLU9QchR1QT/5g7oFjMBtTtJdgi65mzjOHkOQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Hsd7NAaZ; arc=none smtp.client-ip=209.85.210.180 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Hsd7NAaZ" Received: by mail-pf1-f180.google.com with SMTP id d2e1a72fcca58-84862b0d5f8so345733b3a.3 for ; Thu, 20 Aug 2026 20:35:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1787283342; x=1787888142; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=37lrRdVdH72rKqT8mTTOi84r0kl7oav2/onL05fr7B8=; b=Hsd7NAaZfU3+OQQMVy7GDi+7sN53ssIj09rjmiG5LF3EsA0t9ZVVmBVpNCaiHBpl+z sEqW9lFQMV7AUV8HP6QsK0/JIneQeQn4Z7CBSpZ+AEy01ElWsZ/aGnSHjd32/wVPF9sv Bh9pD2LPxjeijTFPJrcQTNo+rvC32VBrIpuBaj+pc0kHS4MRJyIqNxfCOlCTwKawJVRR H+4H3KVMmVuAqK/PCldFLy1dFOJGa8zMnlmH0eBEHPGs9iYQAaCEK0+Q2b2s3lnv6SXe Cf2nYmfz2cukq+/v5LcFeMLNVgrtlYunyHHfiWLP86vt3nzT9LSsLBzH0UoNPB+dylNy fcjQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787283342; x=1787888142; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=37lrRdVdH72rKqT8mTTOi84r0kl7oav2/onL05fr7B8=; b=GB0bCtmQg8P3ygclPWF+zWLSGQQOdwLvdFkv+b8ViT9oV13h1YrmhlEheiowcJiaL+ kkoJ6pidpZsmBBpJKpjoDPnGD3plDmHqUrm52AyP+OHQVyFI88eUpVy2Z/089p9VOEsh dEmH8FJEHcEJ1rXCMsWHvR/tx3Z/hpI+K+5opeXmBSIFar6LYKy/Zc7HeccNKso2JiRo zECxizNJebODUF0GTiRnTrhW35RPoAozhagLCYQf88ZFXQlSYErmejLZ1cCnAk3ZGLsl V/fbjtDZudRC+yYv/qcvta8dKrIChGKp9DsqPTs2cwqdl5ZI86VMPp2lxigxnro7Pd09 lwrQ== X-Gm-Message-State: AFuF++n2E3a7fIzYMnhZ0/iHRWoDfvnG0wDHCX2oLRPudPnIke1hO0nv jfoKkQwWb/bD7L5jJz5FYDsD8zgFO/7Pkivrrg/hZ/oYKZHCwfMBKl3NjKykiw== X-Gm-Gg: AR+sD11qd4vMPB1cWKmtKn4Me3o1WiDLHmwbK2wnkVbYAxry6AZey7VqdBu7UfymZz7 ecx0Ml4V4aDl0doG32jA2Om/aKihx8UY1XLtADjFBunbuUsJlIUgBr7GrMQiDeysKq4TgnnCTOC nCpi1dJm4D9GdntFg8KNpgmSjj9s7V1G0YR700D+OzKQMNq9f67y/0IcGASdbP0DT8iA9BC4RSr dg2BR2MfMSgv8ivtZiHutvaF5O72bJMrba8IogLadt1CEj69LK2dwW1GgfIalmh1NV1DP0uK8wf GkjVvkJLuGQIqjiV/lM3kKLxan3aCi1zgQh9gvo72VnRPR9Y6DtPfEhPr5GBmOY/7vL7+uE8x93 K/Py6+G6VHu3o/LjY+90N7wKjmTVqetoHNEO3TfEqajSWREPA6JAMmdydAovfglgD6lFc8tu7R7 HKzG/HnERvNvguxQaEnLcKTSBRWftKx/qX5sTDSP9Sn/R9E4ozKAdp57QmadXvuFxV9Ky87hM8q Na9euNd5EppaUUlonPKCykLfD9KQew= X-Received: by 2002:a05:6a00:410f:b0:845:c694:5c3d with SMTP id d2e1a72fcca58-851f972a856mr5396641b3a.1.1787283342432; Thu, 20 Aug 2026 20:35:42 -0700 (PDT) Received: from hcdev-d520mt2.. (60-250-196-139.hinet-ip.hinet.net. [60.250.196.139]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-cc15891a04csm2204271a12.15.2026.08.20.20.35.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Aug 2026 20:35:42 -0700 (PDT) From: a0282524688@gmail.com To: lee@kernel.org, Ming Yu Cc: linux-kernel@vger.kernel.org, Ming Yu , mfd@lists.linux.dev Subject: [PATCH v7 08/10] mfd: nct6694: Submit the interrupt URB after the core is registered Date: Fri, 21 Aug 2026 11:35:03 +0800 Message-Id: <20260821033505.4017901-9-a0282524688@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260821033505.4017901-1-a0282524688@gmail.com> References: <20260821033505.4017901-1-a0282524688@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Ming Yu The interrupt URB is submitted before nct6694_core_probe() creates the IRQ domain. A device completing the URB early makes the callback pass a NULL domain to irq_find_mapping(), which then falls back to the default domain and dispatches interrupts the device does not own. Submit the URB once the core is registered, and kill it before the core is removed so the callback never runs without a domain. Fixes: 51dad33ede63 ("mfd: Add core driver for Nuvoton NCT6694") Signed-off-by: Ming Yu --- Changes in v7: - New patch. Fixes the URB-before-IRQ-domain race reported on v6 patch 6/7. drivers/mfd/nct6694-usb.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/mfd/nct6694-usb.c b/drivers/mfd/nct6694-usb.c index c8667984df5e..cc3e7b7b3a0d 100644 --- a/drivers/mfd/nct6694-usb.c +++ b/drivers/mfd/nct6694-usb.c @@ -312,20 +312,20 @@ static int nct6694_usb_probe(struct usb_interface *if= ace, udata->int_buffer, sizeof(*udata->int_buffer), nct6694_usb_int_callbac= k, nct6694, int_endpoint->bInterval); =20 - ret =3D usb_submit_urb(udata->int_in_urb, GFP_KERNEL); - if (ret) - goto err_urb; - usb_set_intfdata(iface, nct6694); =20 ret =3D nct6694_core_probe(dev, nct6694, nct6694_usb_devs, ARRAY_SIZE(nct= 6694_usb_devs)); if (ret) - goto err_mfd; + goto err_urb; + + ret =3D usb_submit_urb(udata->int_in_urb, GFP_KERNEL); + if (ret) + goto err_core; =20 return 0; =20 -err_mfd: - usb_kill_urb(udata->int_in_urb); +err_core: + nct6694_core_remove(nct6694); err_urb: usb_free_urb(udata->int_in_urb); return ret; @@ -336,8 +336,8 @@ static void nct6694_usb_disconnect(struct usb_interface= *iface) struct nct6694 *nct6694 =3D usb_get_intfdata(iface); struct nct6694_usb_data *udata =3D nct6694->priv; =20 - nct6694_core_remove(nct6694); usb_kill_urb(udata->int_in_urb); + nct6694_core_remove(nct6694); usb_free_urb(udata->int_in_urb); } =20 --=20 2.34.1 From nobody Mon Sep 28 14:47:00 2026 Received: from mail-pg1-f173.google.com (mail-pg1-f173.google.com [209.85.215.173]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1F6D9377A87 for ; Fri, 21 Aug 2026 03:35:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787283352; cv=none; b=ZehHKkjcO1PR8v2KWU4CldZ2Qfzc5/jOMMYg701wwO0c/6InNo1dqxA//1GBS0TOyJKxjnx/FtzsQrVnu/lEBVzZpxsw4H8MrhKsrCUNV9S09v3dSOnpuyPqFqZIHMRbF5J1Iwta8LqX5jRgCxekmeaSb02UDDzE+4WyHyOH8qE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787283352; c=relaxed/simple; bh=wyfBHj1kfbB/Xu2NXnAjxXZqzOU15ldhxzy5vRJ/5ZI=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=oImQ6+6kxpcllkdbYhT0BqFM38khyzf2+0MlC7XLR/F7pWrtk5rflYNbRt18KsI/uvQ7MmpG45Mu8DVwr7GYTIKgzRKKN1zm91iTGsIirV5ZPmtewD8e4uXYLwjuthPKGhF0D+lVyY42okNSUv7Y/qbcXUPdG6iTmr9OVKOFleI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=KjCM5G+m; arc=none smtp.client-ip=209.85.215.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="KjCM5G+m" Received: by mail-pg1-f173.google.com with SMTP id 41be03b00d2f7-c9e607d81fcso356793a12.2 for ; Thu, 20 Aug 2026 20:35:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1787283345; x=1787888145; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=zVGJq/cPYPrGdMaDb09iv6l5Ams0yt9+9ZCGjPPurrE=; b=KjCM5G+mmxqDQUq/U/h+wdGBFwjwTIZVyrbhnqicPSnz4yfoiiv8feUEd+Qonaf6aB 7TIaiTZwqwNrPlbz1uc+Nwuivr72EmWOzJG+i634yBDw8bqkl9EmVYQ/MEDtYq0+TlkH XFe9T7Xr071kVZIUbXUGkL4qBJ+G20vUwHXrTss3suxJ7kgd64kwEWNAeeSbPcH6mFrH K2ZPKUE0aKtQDKh/j3QuxLPLwHDNSMQPTxJE/0MsqKtfDMwe27bwWEpazmiq+PxrKLtg fEKnjE9IKtgHk+BaAzfjrHsH/9ms0eOVHD7cTHO5S5pjkQgd3wce2D40VG8x9l3An3HZ gN4g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787283345; x=1787888145; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=zVGJq/cPYPrGdMaDb09iv6l5Ams0yt9+9ZCGjPPurrE=; b=YH2PtI4H2v5B7nRlaFmKw7grb0M9FjnUcLs8K4BMuD15XCAygCr8j4TwrKNjJ7pGWs 1oLiKiPvmHPdnPRlHQtfMvMFSA8bN9PvlVKBePKsMEbzU68SeG+rrgpbbee7pMr+VqOg ZUwmR/xr0b/c8pMJ/jyoVmTGlRf5J+cwUW+GaZa6W9Zp8tpJJ5TMT5Ttd3IvFJNr77CL e1mnKH4ub2z/CHSdBchQffro/+OdALYaUX41EDcQmqx2I5DfJVHQ0oj+db6jPjFjQkgl 5S/hlgXVSw7ZE74SoO+mr6yBeBwehrN7B3pLRMnffx9SkE6Ajoz6KSnOlMPUyKvgOJBd SCig== X-Gm-Message-State: AOJu0YxAZ0JYf7nn19EmldLOst64zju8MreSybnrZoCg9Hg4INrAy+N1 +bGwR62Kw2rchlCvD+Wg+AO9yxx1hOIP9vyjEYbi+81KtbtetACwcuJHBfsy3w== X-Gm-Gg: AR+sD11CPbljGcTsMTDjH2mhGxjKuoS5147jNYhQWJHcmGYudjSrQro1/w9+75wmMU5 Rbn3EC63rh9XEf+BV4OwjWuM4a7fjNRYwdPwZ72giG/G2H82CE2C9PKZnAiHZfC6Pu50InFurqn wsoW/PcxQasQsmtRllC2+B2y5lWrCjmxilhIlvmUdLrq6HlR+YdzXnhQJ0VA+sMwZQZUAPOGvPW qmFLdT1ghlShX1z+7mUjkJfhK6nPCehg4yYbJ8fHZlwD+uVtd3Lmipfb5oj6jA0sgPJpwzA6sl4 UowNWiXsJRPaEgUbC17/FfgnmWYdQb5obXRB9hThB+5ffE7nfC3cdmQHUgwiqlET3IJuFZcircs sOp7w1ya064f+b/nN61dNy+diZ2fQTCaktX3fN8XZqgLJ1hbRhBgbqARjaDgcbZgSzgqs7c8cM/ gpNuDC0f9N1XS3+s9UallFu821YBsMpqrC2cQYkY70mWLOxomwecyuJloeN5ceMvANhYIYTlbg9 7lknWUHzNqGQJLMel3jyCSnv0zk5ak= X-Received: by 2002:a05:6a21:e584:b0:3cc:c7cf:5a44 with SMTP id adf61e73a8af0-3cd2fd4d78amr6863464637.2.1787283345094; Thu, 20 Aug 2026 20:35:45 -0700 (PDT) Received: from hcdev-d520mt2.. (60-250-196-139.hinet-ip.hinet.net. [60.250.196.139]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-cc15891a04csm2204271a12.15.2026.08.20.20.35.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Aug 2026 20:35:44 -0700 (PDT) From: a0282524688@gmail.com To: lee@kernel.org, Ming Yu , Andi Shyti Cc: linux-kernel@vger.kernel.org, Ming Yu , linux-i2c@vger.kernel.org, mfd@lists.linux.dev Subject: [PATCH v7 09/10] mfd: nct6694: Introduce regmap-based transport abstraction Date: Fri, 21 Aug 2026 11:35:04 +0800 Message-Id: <20260821033505.4017901-10-a0282524688@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260821033505.4017901-1-a0282524688@gmail.com> References: <20260821033505.4017901-1-a0282524688@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Ming Yu Sub-device drivers call into the USB transport directly, so a second transport cannot be added without touching all of them. Wrap the transport behind a regmap bus and let the sub-device drivers reach the firmware only through nct6694_{read,write}_msg(). The command header maps onto the regmap bulk accessors by packing the host control byte, the module id and the 16-bit offset into a single 32-bit register. Add nct6694_write_read_msg() for the commands that transmit a request and read the reply back within the same firmware message, and use it for the I2C deliver command. Signed-off-by: Ming Yu --- Changes in v7: - Made the USB transport helpers static and gave nct6694_usb_write_msg() separate @tx/@rx buffers, so a SET command only copies the firmware reply back when the caller asks for it. - Documented in the shared header why nct6694_write_read_msg() is expressed as a read of a SET register. Changes in v6: - New patch. Replaces the v5 function-pointer abstraction with a regmap_bus based transport: the firmware command header is packed into a single 32-bit regmap register and sub-device drivers use the regmap bulk accessors. Adds nct6694_write_read_msg() for request/response commands and drops the per-transport access_lock (regmap already serialises bus accesses). drivers/i2c/busses/i2c-nct6694.c | 2 +- drivers/mfd/Kconfig | 1 + drivers/mfd/nct6694-usb.c | 106 +++++++++++++++++++------------ include/linux/mfd/nct6694.h | 62 ++++++++++++++---- 4 files changed, 120 insertions(+), 51 deletions(-) diff --git a/drivers/i2c/busses/i2c-nct6694.c b/drivers/i2c/busses/i2c-nct6= 694.c index ef3329f34246..7e32dab6e759 100644 --- a/drivers/i2c/busses/i2c-nct6694.c +++ b/drivers/i2c/busses/i2c-nct6694.c @@ -77,7 +77,7 @@ static int nct6694_i2c_xfer(struct i2c_adapter *adap, str= uct i2c_msg *msgs, int deliver->addr =3D i2c_8bit_addr_from_msg(msg_temp); if (msg_temp->flags & I2C_M_RD) { deliver->r_cnt =3D msg_temp->len; - ret =3D nct6694_write_msg(data->nct6694, &cmd_hd, deliver); + ret =3D nct6694_write_read_msg(data->nct6694, &cmd_hd, deliver); if (ret < 0) return ret; =20 diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 5506a0adf3ec..742fc26e6ff7 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -1166,6 +1166,7 @@ config MFD_MENF21BMC config MFD_NCT6694 tristate select MFD_CORE + select REGMAP help Core MFD support for the Nuvoton NCT6694 peripheral expander. This provides the common APIs and shared structures used by all diff --git a/drivers/mfd/nct6694-usb.c b/drivers/mfd/nct6694-usb.c index cc3e7b7b3a0d..979ae1125d16 100644 --- a/drivers/mfd/nct6694-usb.c +++ b/drivers/mfd/nct6694-usb.c @@ -9,6 +9,7 @@ * CAN, WDT, HWMON and RTC management. */ =20 +#include #include #include #include @@ -17,7 +18,9 @@ #include #include #include +#include #include +#include #include =20 #define NCT6694_VENDOR_ID 0x0416 @@ -34,7 +37,6 @@ union __packed nct6694_usb_msg { }; =20 struct nct6694_usb_data { - struct mutex access_lock; struct urb *int_in_urb; struct usb_device *udev; union nct6694_usb_msg *usb_msg; @@ -102,21 +104,9 @@ static int nct6694_usb_err_handling(struct nct6694 *nc= t6694, unsigned char err_s return -EIO; } =20 -/** - * nct6694_usb_read_msg() - Read message from NCT6694 device - * @nct6694: NCT6694 device pointer - * @cmd_hd: command header structure - * @buf: buffer to store the response data - * - * Sends a command to the NCT6694 device and reads the response. - * The command header is specified in @cmd_hd, and the response - * data is stored in @buf. - * - * Return: Negative value on error or 0 on success. - */ -int nct6694_usb_read_msg(struct nct6694 *nct6694, - const struct nct6694_cmd_header *cmd_hd, - void *buf) +static int nct6694_usb_read_msg(struct nct6694 *nct6694, + const struct nct6694_cmd_header *cmd_hd, + void *buf) { struct nct6694_usb_data *udata =3D nct6694->priv; union nct6694_usb_msg *msg =3D udata->usb_msg; @@ -127,8 +117,6 @@ int nct6694_usb_read_msg(struct nct6694 *nct6694, if (len > NCT6694_MAX_PACKET_SIZE) return -EINVAL; =20 - guard(mutex)(&udata->access_lock); - memcpy(&msg->cmd_header, cmd_hd, sizeof(*cmd_hd)); msg->cmd_header.hctrl =3D NCT6694_HCTRL_GET; =20 @@ -160,22 +148,15 @@ int nct6694_usb_read_msg(struct nct6694 *nct6694, =20 return nct6694_usb_err_handling(nct6694, msg->response_header.sts); } -EXPORT_SYMBOL_GPL(nct6694_usb_read_msg); =20 -/** - * nct6694_usb_write_msg() - Write message to NCT6694 device - * @nct6694: NCT6694 device pointer - * @cmd_hd: command header structure - * @buf: buffer containing the data to be sent - * - * Sends a command to the NCT6694 device and writes the data - * from @buf. The command header is specified in @cmd_hd. - * - * Return: Negative value on error or 0 on success. +/* + * @tx is const because regmap_bus->write() hands over the caller's buffer= . The + * firmware always answers a SET command with a payload of the same length; + * callers that need it pass @rx, the others pass NULL. */ -int nct6694_usb_write_msg(struct nct6694 *nct6694, - const struct nct6694_cmd_header *cmd_hd, - void *buf) +static int nct6694_usb_write_msg(struct nct6694 *nct6694, + const struct nct6694_cmd_header *cmd_hd, + const void *tx, void *rx) { struct nct6694_usb_data *udata =3D nct6694->priv; union nct6694_usb_msg *msg =3D udata->usb_msg; @@ -186,11 +167,9 @@ int nct6694_usb_write_msg(struct nct6694 *nct6694, if (len > NCT6694_MAX_PACKET_SIZE) return -EINVAL; =20 - guard(mutex)(&udata->access_lock); - memcpy(&msg->cmd_header, cmd_hd, sizeof(*cmd_hd)); msg->cmd_header.hctrl =3D NCT6694_HCTRL_SET; - memcpy(udata->xfer_buf, buf, len); + memcpy(udata->xfer_buf, tx, len); =20 /* Send command packet to USB device */ ret =3D usb_bulk_msg(udev, usb_sndbulkpipe(udev, NCT6694_BULK_OUT_EP), &m= sg->cmd_header, @@ -222,11 +201,57 @@ int nct6694_usb_write_msg(struct nct6694 *nct6694, return -EIO; } =20 - memcpy(buf, udata->xfer_buf, len); + if (rx) + memcpy(rx, udata->xfer_buf, len); =20 return nct6694_usb_err_handling(nct6694, msg->response_header.sts); } -EXPORT_SYMBOL_GPL(nct6694_usb_write_msg); + +static int nct6694_usb_regmap_read(void *context, const void *reg_buf, + size_t reg_size, void *val_buf, + size_t val_size) +{ + struct nct6694 *nct6694 =3D context; + u32 reg =3D get_unaligned_be32(reg_buf); + const struct nct6694_cmd_header cmd_hd =3D { + .mod =3D FIELD_GET(NCT6694_REG_MOD, reg), + .offset =3D cpu_to_le16(FIELD_GET(NCT6694_REG_OFFSET, reg)), + .len =3D cpu_to_le16(val_size), + }; + + if (FIELD_GET(NCT6694_REG_HCTRL, reg) =3D=3D NCT6694_HCTRL_SET) + return nct6694_usb_write_msg(nct6694, &cmd_hd, val_buf, val_buf); + + return nct6694_usb_read_msg(nct6694, &cmd_hd, val_buf); +} + +static int nct6694_usb_regmap_write(void *context, const void *data, + size_t count) +{ + struct nct6694 *nct6694 =3D context; + u32 reg =3D get_unaligned_be32(data); + size_t len =3D count - sizeof(reg); + const struct nct6694_cmd_header cmd_hd =3D { + .mod =3D FIELD_GET(NCT6694_REG_MOD, reg), + .offset =3D cpu_to_le16(FIELD_GET(NCT6694_REG_OFFSET, reg)), + .len =3D cpu_to_le16(len), + }; + + return nct6694_usb_write_msg(nct6694, &cmd_hd, data + sizeof(reg), NULL); +} + +static const struct regmap_bus nct6694_usb_regmap_bus =3D { + .read =3D nct6694_usb_regmap_read, + .write =3D nct6694_usb_regmap_write, +}; + +static const struct regmap_config nct6694_usb_regmap_config =3D { + .reg_bits =3D 32, + .val_bits =3D 8, + .reg_stride =3D 1, + .max_raw_read =3D NCT6694_MAX_PACKET_SIZE, + .max_raw_write =3D NCT6694_MAX_PACKET_SIZE, +}; =20 static void nct6694_usb_int_callback(struct urb *urb) { @@ -300,9 +325,12 @@ static int nct6694_usb_probe(struct usb_interface *ifa= ce, nct6694->dev =3D dev; nct6694->priv =3D udata; =20 - ret =3D devm_mutex_init(dev, &udata->access_lock); - if (ret) + nct6694->regmap =3D devm_regmap_init(dev, &nct6694_usb_regmap_bus, nct669= 4, + &nct6694_usb_regmap_config); + if (IS_ERR(nct6694->regmap)) { + ret =3D PTR_ERR(nct6694->regmap); goto err_urb; + } =20 ret =3D usb_find_int_in_endpoint(iface->cur_altsetting, &int_endpoint); if (ret) diff --git a/include/linux/mfd/nct6694.h b/include/linux/mfd/nct6694.h index cb311e58a437..aef0f9bd914c 100644 --- a/include/linux/mfd/nct6694.h +++ b/include/linux/mfd/nct6694.h @@ -9,7 +9,9 @@ #ifndef __MFD_NCT6694_H #define __MFD_NCT6694_H =20 +#include #include +#include #include #include =20 @@ -90,6 +92,7 @@ struct __packed nct6694_response_header { =20 struct nct6694 { struct device *dev; + struct regmap *regmap; struct ida gpio_ida; struct ida i2c_ida; struct ida canfd_ida; @@ -100,29 +103,66 @@ struct nct6694 { void *priv; }; =20 -int nct6694_core_probe(struct device *dev, struct nct6694 *nct6694, - const struct mfd_cell *cells, int n_cells); -void nct6694_core_remove(struct nct6694 *nct6694); +/* + * Firmware messages are addressed by a module id and a 16-bit offset (a + * command/selector pair). Pack them together with the host control byte i= nto a + * single 32-bit regmap register, so that sub-device drivers can issue com= mands + * through the regmap bulk accessors while each transport driver only has = to + * implement a regmap bus. + * + * bits [31:24] host control (NCT6694_HCTRL_GET / NCT6694_HCTRL_SET) + * bits [23:16] module id + * bits [15:0] offset (low byte =3D command, high byte =3D selector) + */ +#define NCT6694_REG_HCTRL GENMASK(31, 24) +#define NCT6694_REG_MOD GENMASK(23, 16) +#define NCT6694_REG_OFFSET GENMASK(15, 0) =20 -int nct6694_usb_read_msg(struct nct6694 *nct6694, - const struct nct6694_cmd_header *cmd_hd, - void *buf); -int nct6694_usb_write_msg(struct nct6694 *nct6694, - const struct nct6694_cmd_header *cmd_hd, - void *buf); +static inline u32 nct6694_cmd_to_reg(const struct nct6694_cmd_header *cmd_= hd, + u8 hctrl) +{ + return FIELD_PREP(NCT6694_REG_HCTRL, hctrl) | + FIELD_PREP(NCT6694_REG_MOD, cmd_hd->mod) | + FIELD_PREP(NCT6694_REG_OFFSET, le16_to_cpu(cmd_hd->offset)); +} =20 static inline int nct6694_read_msg(struct nct6694 *nct6694, const struct nct6694_cmd_header *cmd_hd, void *buf) { - return nct6694_usb_read_msg(nct6694, cmd_hd, buf); + return regmap_bulk_read(nct6694->regmap, + nct6694_cmd_to_reg(cmd_hd, NCT6694_HCTRL_GET), + buf, le16_to_cpu(cmd_hd->len)); } =20 static inline int nct6694_write_msg(struct nct6694 *nct6694, const struct nct6694_cmd_header *cmd_hd, void *buf) { - return nct6694_usb_write_msg(nct6694, cmd_hd, buf); + return regmap_bulk_write(nct6694->regmap, + nct6694_cmd_to_reg(cmd_hd, NCT6694_HCTRL_SET), + buf, le16_to_cpu(cmd_hd->len)); } =20 +/* + * A few commands, such as the I2C deliver, transmit a request and read the + * reply back within the same firmware message. regmap has no accessor for= such + * an exchange, so express it as a read of a SET register: @buf carries the + * request on entry and holds the reply on return. This relies on the tran= sport + * bus being handed @buf directly, which holds as long as the regmap is le= ft + * uncached and byte sized. + */ +static inline int nct6694_write_read_msg(struct nct6694 *nct6694, + const struct nct6694_cmd_header *cmd_hd, + void *buf) +{ + return regmap_bulk_read(nct6694->regmap, + nct6694_cmd_to_reg(cmd_hd, NCT6694_HCTRL_SET), + buf, le16_to_cpu(cmd_hd->len)); +} + +int nct6694_core_probe(struct device *dev, struct nct6694 *nct6694, + const struct mfd_cell *cells, int n_cells); +void nct6694_core_remove(struct nct6694 *nct6694); + #endif --=20 2.34.1 From nobody Mon Sep 28 14:47:00 2026 Received: from mail-pg1-f179.google.com (mail-pg1-f179.google.com [209.85.215.179]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 40ABD37DAB5 for ; Fri, 21 Aug 2026 03:35:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.179 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787283355; cv=none; b=mwLRz8xXU+yY4a0ESyoqVAvXh+CYjtuVlYwK46QxjcD/8+o8OWodgSwUg/lWgdMTTAECFfFOZKyGrWzVX3/x7pt3uqBD+ZzyDMlbZTKnj7I3+QwUm+2PFvoU3ZhkFvVoznyNSVDB2KPFwCsMKrlsztMEDAKR5lK8wkcLL+hZmz4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787283355; c=relaxed/simple; bh=Whms/+q4JoPzCtDw3QlXcuef1B5M1W4aqbOVC7Ygfug=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=gtZRnrLLu7K8lz371ONZhVKQ42KjcSYVvlAgHLN6gxo8LSMuQ7caxTFkYv2wq0Xq3PebeE+1GheK1WbrqYD+Kxz9ZCFR37VE1ZKS8+PzMgn3yz0nQ3Ti2Gx+WHxa1mRegauijDfG+lsqarLsBhL4eQwOAqSiQMoJL4PIwG7/tJo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=mfjR+uoE; arc=none smtp.client-ip=209.85.215.179 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="mfjR+uoE" Received: by mail-pg1-f179.google.com with SMTP id 41be03b00d2f7-c966b9ee9cbso387406a12.1 for ; Thu, 20 Aug 2026 20:35:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1787283348; x=1787888148; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=rlFmNHRW5eiulSAG/+fFQ1Eg/WOdNRIY5GXFaD+LV78=; b=mfjR+uoEcCcplW8+PX+api5isH0eMA4JHAAPa9mx3n/w4tZCtHjIf6RMq7Nng2SOJ3 7tbl+gkmRqumtQP5AzdxO+H4+feK3+uekN8PTnXow3gjhwM5fy7SKnLomgLwIIyWu7dj 8PqE8dye2Lz85uf+BmZOmZ8NZlJJ3BBcEE11rHA1zt9KisqQoodQ3MAzm+/OfS549lo6 qKUGLU1wYCY6J0CWC0EJEZmLDjc02o3tRQD8moLvegYzp8V5b6UAAs4IjsnV3/3xea25 FCkP84ys5jvFS//UviC0s0ssspKfBqc/4X6MSrrC3SANmiOyA8kYXYVd/hMT6BLPTAxc 9XHg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787283348; x=1787888148; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=rlFmNHRW5eiulSAG/+fFQ1Eg/WOdNRIY5GXFaD+LV78=; b=Ep5hcUL4bi4SjqkGPzwXpPgY+9P4JGk69CnLvD1XYAL7nMgAixJCpHvGuOYk85xBLa 3VQ3JCsmLc8eb0ly9WyOVn8/gy5khy9NKl+QHmj1QGvAmNtGhTQSVaevTmUi6+BuZeME 225KGnpMR1xwAx6z5trRk7ykKS9pTBQPDmg01WLgNvknBNuSASphhk6WRMFec/nyyGjn /vVpCjMtll61QvkhcekgdLod6KpAl1Nei+T7RsvNlIqyo55nu+YKemoYE3f5SU5JLmSn t92ZKyJSFgQQkzjGlnrgQtssHYcEn4FnbmogF+IEO/hNztVySuxPHoJEol/0/7C+YaGD 6vFg== X-Gm-Message-State: AOJu0YwLBmsT5MCh3BZfGSKIUutbZMEf9GIK00uar3QZli0eq4yIUnZG 1n+qCUWgj96EnhGqg8v98o/a6z8Vtcn4DkXl9Hno9w6POD8VSUCEZl3o X-Gm-Gg: AR+sD11GuLToVBhZB7oty1dxvamyyDFatYmsSpUKGk+hRoPcku1EsFciul7a2q/t7nO wWOyFxINfTvvDOy1A/vwxb4SaxwdvIT/NCOw/M0HDZZZyOEP0l8GVlrho+K2DuYCBsQV+zUrM+Q RuiGBb6oZeXIaSbp/wVz6t/GrjdjdczpV8zBbvWV2upGobJEd9D/l+PPNrRe8/uL4YvkcPI52e/ ooZ2z/PUGwYxlZ+NlqbrkCJQsYXvXs61FL2IYgvxlfv0wtSqD5yd+8SDE2TqbjHcaNg1Jal6JYk afluuzH+RCoZlXP9WgfYFhv+XqjEWObQwHNCuEftUHzpj5uBQMkSRyeY0+yObPVYgIV3NXec6Ag OFNEluz2cIYgJyJfPMWuRJpfISk86dTvcGkxwY7fioo209+OJ6vcSeDH52Ft0JtAONFuNsXT0bW 6Ea+bhbxuK4DPeS0xyY0d/Ya/XvMJZywXdkGO/wKca3TJP0UVKOMC53X5ImmWLbeoYaR7v+Z0iW T8NOs/9pHADV0LxmcDzA1O2fFJbBwk= X-Received: by 2002:a05:6a21:e081:b0:3c8:f342:132c with SMTP id adf61e73a8af0-3cd3000a342mr5655274637.11.1787283347733; Thu, 20 Aug 2026 20:35:47 -0700 (PDT) Received: from hcdev-d520mt2.. (60-250-196-139.hinet-ip.hinet.net. [60.250.196.139]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-cc15891a04csm2204271a12.15.2026.08.20.20.35.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Aug 2026 20:35:47 -0700 (PDT) From: a0282524688@gmail.com To: lee@kernel.org, Ming Yu Cc: linux-kernel@vger.kernel.org, Ming Yu , mfd@lists.linux.dev Subject: [PATCH v7 10/10] mfd: nct6694: Add Host Interface (HIF) eSPI transport driver Date: Fri, 21 Aug 2026 11:35:05 +0800 Message-Id: <20260821033505.4017901-11-a0282524688@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260821033505.4017901-1-a0282524688@gmail.com> References: <20260821033505.4017901-1-a0282524688@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Ming Yu Add support for the Host Interface (HIF) transport via eSPI for the Nuvoton NCT6694 peripheral expander. This transport driver initializes the Super-I/O to configure the device's shared memory base address and SIRQ. It provides a regmap_bus implementation that drives the firmware command/response exchange over the shared-memory window, plus an internal regmap_mmio for the report region. The initialized device config is then passed to the MFD core (nct6694_core_probe) for sub-device registration and IRQ domain setup. Signed-off-by: Ming Yu --- Changes in v7: - Zero the tail of the caller buffer when the firmware answers with fewer bytes than requested, and split the transfer helper into separate @tx/@rx buffers instead of a shared scratch buffer. - Request the interrupt before registering the core, so devres frees it after the sub-devices are removed. Mask the interrupt and clear a stale status in nct6694_hif_irq_init() so the handler cannot run before the IRQ domain exists. - Return IRQ_HANDLED once the interrupt status has been cleared. - Skip hardware interrupts that have no mapping instead of dispatching virq 0. - Bail out with -ENODEV if the BIOS left the shared memory base address unconfigured. - Program the SIRQ register with the hardware interrupt number rather than the Linux virq. Changes in v6: - Reworked the transport to implement a regmap_bus instead of the v5 read_msg/write_msg function pointers. Changes in v5: - Split from the monolithic v4 patch. - Adapted to re-use the newly introduced nct6694_core_probe() and abstracted I/O APIs. Changes since version 3: - Remove redundant module type macro definitions from sub-device drivers that are now provided by the shared header , fixing -Wmacro-redefined warnings. Changes since version 2: - Restore per-device IDA and mfd_add_hotplug_devices()/PLATFORM_DEVID_AUTO to avoid child device ID conflicts with multiple NCT6694 chips. - Validate irq_find_mapping() return value before dispatching IRQs. - Check superio_enter() return value in nct6694_irq_init(). Changes since version 1: - Drop function pointers from Super-I/O access and use static inline helpers with proper types. drivers/mfd/Kconfig | 16 ++ drivers/mfd/Makefile | 1 + drivers/mfd/nct6694-hif.c | 590 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 607 insertions(+) create mode 100644 drivers/mfd/nct6694-hif.c diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 742fc26e6ff7..f37acf585671 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -1175,6 +1175,22 @@ config MFD_NCT6694 =20 It is selected automatically by the transport interface drivers. =20 +config MFD_NCT6694_HIF + tristate "Nuvoton NCT6694 HIF (eSPI) interface support" + depends on HAS_IOPORT && ACPI + select MFD_NCT6694 + select REGMAP_MMIO + help + This enables support for the Nuvoton NCT6694 peripheral expander + connected via the Host Interface (HIF) using eSPI transport. + + The transport driver uses Super-I/O mapping and shared memory to + communicate with the NCT6694 firmware. Enable this option if you + are using the NCT6694 over an eSPI interface on an ACPI platform. + + To compile this driver as a module, choose M here: the module + will be called nct6694-hif. + config MFD_NCT6694_USB tristate "Nuvoton NCT6694 USB interface support" select MFD_NCT6694 diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 10c19a19541e..97924dd3552c 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -125,6 +125,7 @@ obj-$(CONFIG_MFD_MC13XXX_I2C) +=3D mc13xxx-i2c.o obj-$(CONFIG_MFD_PF1550) +=3D pf1550.o =20 obj-$(CONFIG_MFD_NCT6694) +=3D nct6694-core.o +obj-$(CONFIG_MFD_NCT6694_HIF) +=3D nct6694-hif.o obj-$(CONFIG_MFD_NCT6694_USB) +=3D nct6694-usb.o =20 obj-$(CONFIG_MFD_CORE) +=3D mfd-core.o diff --git a/drivers/mfd/nct6694-hif.c b/drivers/mfd/nct6694-hif.c new file mode 100644 index 000000000000..198838d3e7d8 --- /dev/null +++ b/drivers/mfd/nct6694-hif.c @@ -0,0 +1,590 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2026 Nuvoton Technology Corp. + * + * Nuvoton NCT6694 host-interface (eSPI) transport driver. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRVNAME "nct6694-hif" + +#define NCT6694_POLL_INTERVAL_US 10 +#define NCT6694_POLL_TIMEOUT_US 10000 + +/* + * Super-I/O registers + */ +#define SIO_REG_LDSEL 0x07 /* Logical device select */ +#define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */ +#define SIO_REG_LD_SHM 0x0F /* Logical device shared memory control */ + +#define SIO_REG_SHM_ENABLE 0x30 /* Enable shared memory */ +#define SIO_REG_SHM_BASE_ADDR 0x60 /* Shared memory base address (2 bytes)= */ +#define SIO_REG_SHM_IRQ_NR 0x70 /* Shared memory interrupt number */ +#define SIO_SHM_IRQ_NR_MAX 15 /* Highest ISA interrupt line */ + +#define SIO_REG_UNLOCK_KEY 0x87 /* Key to enable Super-I/O */ +#define SIO_REG_LOCK_KEY 0xAA /* Key to disable Super-I/O */ + +#define SIO_NCT6694B_ID 0xD029 +#define SIO_NCT6694D_ID 0x5832 + +/* + * Super-I/O Shared Memory Logical Device registers + */ +#define NCT6694_SHM_COFS_STS 0x2E +#define NCT6694_SHM_COFS_STS_COFS4W BIT(7) + +#define NCT6694_SHM_COFS_CTL2 0x3B +#define NCT6694_SHM_COFS_CTL2_COFS4W_IE BIT(3) + +/* COFS register block [STS..CTL2] is the only SHM range driven via inb/ou= tb */ +#define NCT6694_SHM_COFS_LEN \ + (NCT6694_SHM_COFS_CTL2 - NCT6694_SHM_COFS_STS + 1) + +#define NCT6694_SHM_INTR_STATUS 0x9C /* Interrupt status register (4 byt= es) */ + +enum nct6694_chips { + NCT6694B =3D 0, + NCT6694D, +}; + +struct __packed nct6694_hif_msg { + struct nct6694_cmd_header cmd_header; + struct nct6694_response_header response_header; + unsigned char data[]; +}; + +struct nct6694_sio_data { + enum nct6694_chips chip; + int sioreg; /* Super-I/O index port */ +}; + +struct nct6694_hif_data { + struct regmap *rpt_regmap; + struct nct6694_sio_data *sio_data; + void __iomem *msg_base; + unsigned int shm_base; +}; + +static const char * const nct6694_chip_names[] =3D { + [NCT6694B] =3D "NCT6694B", + [NCT6694D] =3D "NCT6694D", +}; + +/* + * Super-I/O functions. + */ +static inline int superio_enter(struct nct6694_sio_data *sio_data) +{ + int ioreg =3D sio_data->sioreg; + + /* + * Try to reserve and for exclusive access. + */ + if (!request_muxed_region(ioreg, 2, DRVNAME)) + return -EBUSY; + + outb(SIO_REG_UNLOCK_KEY, ioreg); + outb(SIO_REG_UNLOCK_KEY, ioreg); + + return 0; +} + +static inline void superio_exit(struct nct6694_sio_data *sio_data) +{ + int ioreg =3D sio_data->sioreg; + + outb(SIO_REG_LOCK_KEY, ioreg); + + release_region(ioreg, 2); +} + +static inline void superio_select(struct nct6694_sio_data *sio_data, int l= d) +{ + int ioreg =3D sio_data->sioreg; + + outb(SIO_REG_LDSEL, ioreg); + outb(ld, ioreg + 1); +} + +static inline int superio_inb(struct nct6694_sio_data *sio_data, int reg) +{ + int ioreg =3D sio_data->sioreg; + + outb(reg, ioreg); + return inb(ioreg + 1); +} + +static inline int superio_inw(struct nct6694_sio_data *sio_data, int reg) +{ + int ioreg =3D sio_data->sioreg; + int val; + + outb(reg++, ioreg); + val =3D inb(ioreg + 1) << 8; + outb(reg, ioreg); + val |=3D inb(ioreg + 1); + + return val; +} + +static inline void superio_outb(struct nct6694_sio_data *sio_data, int reg= , u8 val) +{ + int ioreg =3D sio_data->sioreg; + + outb(reg, ioreg); + outb(val, ioreg + 1); +} + +static int nct6694_sio_find(struct nct6694_sio_data *sio_data, u8 sioreg) +{ + int ret; + u16 devid; + + sio_data->sioreg =3D sioreg; + + ret =3D superio_enter(sio_data); + if (ret) + return ret; + + /* Check Chip ID */ + devid =3D superio_inw(sio_data, SIO_REG_DEVID); + switch (devid) { + case SIO_NCT6694B_ID: + sio_data->chip =3D NCT6694B; + break; + case SIO_NCT6694D_ID: + sio_data->chip =3D NCT6694D; + break; + default: + superio_exit(sio_data); + return -ENODEV; + } + + superio_exit(sio_data); + + return 0; +} + +static const struct mfd_cell nct6694_hif_devs[] =3D { + MFD_CELL_NAME("nct6694-gpio"), + MFD_CELL_NAME("nct6694-gpio"), + MFD_CELL_NAME("nct6694-gpio"), + MFD_CELL_NAME("nct6694-gpio"), + MFD_CELL_NAME("nct6694-gpio"), + MFD_CELL_NAME("nct6694-gpio"), + MFD_CELL_NAME("nct6694-gpio"), + MFD_CELL_NAME("nct6694-gpio"), + MFD_CELL_NAME("nct6694-gpio"), + MFD_CELL_NAME("nct6694-gpio"), + MFD_CELL_NAME("nct6694-gpio"), + MFD_CELL_NAME("nct6694-gpio"), + MFD_CELL_NAME("nct6694-gpio"), + MFD_CELL_NAME("nct6694-gpio"), + MFD_CELL_NAME("nct6694-gpio"), + MFD_CELL_NAME("nct6694-gpio"), + + MFD_CELL_NAME("nct6694-i2c"), + MFD_CELL_NAME("nct6694-i2c"), + MFD_CELL_NAME("nct6694-i2c"), + MFD_CELL_NAME("nct6694-i2c"), + MFD_CELL_NAME("nct6694-i2c"), + MFD_CELL_NAME("nct6694-i2c"), + + MFD_CELL_NAME("nct6694-canfd"), + MFD_CELL_NAME("nct6694-canfd"), +}; + +static int nct6694_hif_err_handling(struct nct6694 *nct6694, unsigned char= err_status) +{ + switch (err_status) { + case NCT6694_NO_ERROR: + return 0; + case NCT6694_NOT_SUPPORT_ERROR: + dev_err(nct6694->dev, "Command is not supported!\n"); + break; + case NCT6694_NO_RESPONSE_ERROR: + dev_warn(nct6694->dev, "Command received no response!\n"); + break; + case NCT6694_TIMEOUT_ERROR: + dev_warn(nct6694->dev, "Command timed out!\n"); + break; + case NCT6694_PENDING: + dev_err(nct6694->dev, "Command is pending!\n"); + break; + default: + return -EINVAL; + } + + return -EIO; +} + +/* + * @tx is const because regmap_bus->write() hands over the caller's buffer= . A + * GET command carries no request payload and passes @tx as NULL; callers = that + * need the response pass @rx, the others pass NULL. + */ +static int nct6694_hif_xfer_msg(struct nct6694 *nct6694, + const struct nct6694_cmd_header *cmd_hd, + u8 hctrl, const void *tx, void *rx) +{ + struct nct6694_hif_data *hdata =3D nct6694->priv; + void __iomem *hdr =3D hdata->msg_base + offsetof(struct nct6694_hif_msg, = cmd_header); + void __iomem *payload =3D hdata->msg_base + offsetof(struct nct6694_hif_m= sg, data); + struct nct6694_cmd_header cmd =3D *cmd_hd; + struct nct6694_response_header resp; + u16 len =3D le16_to_cpu(cmd.len); + u16 resp_len; + u8 status; + int ret; + + if (len > NCT6694_MAX_PACKET_SIZE) + return -EINVAL; + + /* Wait until the previous command is completed */ + ret =3D readb_poll_timeout(hdr + offsetof(struct nct6694_cmd_header, hctr= l), + status, status =3D=3D 0, NCT6694_POLL_INTERVAL_US, + NCT6694_POLL_TIMEOUT_US); + if (ret) + return ret; + + /* + * Write cmd header fields, but skip hctrl - writing to it triggers + * firmware command processing and must be deferred until data is ready. + */ + memcpy_toio(hdr, &cmd, offsetof(struct nct6694_cmd_header, hctrl)); + memcpy_toio(hdr + offsetof(struct nct6694_cmd_header, rsv2), &cmd.rsv2, + sizeof(cmd) - offsetof(struct nct6694_cmd_header, rsv2)); + + if (tx) + memcpy_toio(payload, tx, len); + + /* Write hctrl last to trigger command processing */ + writeb(hctrl, hdr + offsetof(struct nct6694_cmd_header, hctrl)); + + ret =3D readb_poll_timeout(hdr + offsetof(struct nct6694_cmd_header, hctr= l), + status, status =3D=3D 0, NCT6694_POLL_INTERVAL_US, + NCT6694_POLL_TIMEOUT_US); + if (ret) + return ret; + + memcpy_fromio(&resp, hdata->msg_base + offsetof(struct nct6694_hif_msg, r= esponse_header), + sizeof(resp)); + + ret =3D nct6694_hif_err_handling(nct6694, resp.sts); + if (ret) + return ret; + + if (!rx) + return 0; + + /* The firmware may answer with fewer bytes than requested */ + resp_len =3D min(len, le16_to_cpu(resp.len)); + memcpy_fromio(rx, payload, resp_len); + memset(rx + resp_len, 0, len - resp_len); + + return 0; +} + +static int nct6694_hif_regmap_read(void *context, const void *reg_buf, + size_t reg_size, void *val_buf, + size_t val_size) +{ + struct nct6694 *nct6694 =3D context; + struct nct6694_hif_data *hdata =3D nct6694->priv; + u32 reg =3D get_unaligned_be32(reg_buf); + u8 hctrl =3D FIELD_GET(NCT6694_REG_HCTRL, reg); + const struct nct6694_cmd_header cmd_hd =3D { + .mod =3D FIELD_GET(NCT6694_REG_MOD, reg), + .offset =3D cpu_to_le16(FIELD_GET(NCT6694_REG_OFFSET, reg)), + .len =3D cpu_to_le16(val_size), + }; + + if (cmd_hd.mod =3D=3D NCT6694_RPT_MOD) + return regmap_bulk_read(hdata->rpt_regmap, + FIELD_GET(NCT6694_REG_OFFSET, reg), + val_buf, val_size); + + return nct6694_hif_xfer_msg(nct6694, &cmd_hd, hctrl, + hctrl =3D=3D NCT6694_HCTRL_SET ? val_buf : NULL, + val_buf); +} + +static int nct6694_hif_regmap_write(void *context, const void *data, + size_t count) +{ + struct nct6694 *nct6694 =3D context; + struct nct6694_hif_data *hdata =3D nct6694->priv; + u32 reg =3D get_unaligned_be32(data); + size_t len =3D count - sizeof(reg); + const struct nct6694_cmd_header cmd_hd =3D { + .mod =3D FIELD_GET(NCT6694_REG_MOD, reg), + .offset =3D cpu_to_le16(FIELD_GET(NCT6694_REG_OFFSET, reg)), + .len =3D cpu_to_le16(len), + }; + + if (cmd_hd.mod =3D=3D NCT6694_RPT_MOD) + return regmap_bulk_write(hdata->rpt_regmap, + FIELD_GET(NCT6694_REG_OFFSET, reg), + data + sizeof(reg), len); + + return nct6694_hif_xfer_msg(nct6694, &cmd_hd, NCT6694_HCTRL_SET, + data + sizeof(reg), NULL); +} + +static const struct regmap_bus nct6694_hif_regmap_bus =3D { + .read =3D nct6694_hif_regmap_read, + .write =3D nct6694_hif_regmap_write, +}; + +static const struct regmap_config nct6694_hif_msg_regmap_config =3D { + .name =3D "msg", + .reg_bits =3D 32, + .val_bits =3D 8, + .reg_stride =3D 1, + .max_raw_read =3D NCT6694_MAX_PACKET_SIZE, + .max_raw_write =3D NCT6694_MAX_PACKET_SIZE, +}; + +static const struct regmap_config nct6694_hif_rpt_regmap_config =3D { + .name =3D "rpt", + .reg_bits =3D 8, + .val_bits =3D 8, + .reg_stride =3D 1, +}; + +static irqreturn_t nct6694_hif_irq_handler(int irq, void *data) +{ + struct nct6694 *nct6694 =3D data; + struct nct6694_hif_data *hdata =3D nct6694->priv; + u8 reg_data[4]; + u32 intr_status; + int ret; + + /* Check interrupt status is set */ + if (!(inb(hdata->shm_base + NCT6694_SHM_COFS_STS) & NCT6694_SHM_COFS_STS_= COFS4W)) + return IRQ_NONE; + + /* Clear interrupt status */ + outb(NCT6694_SHM_COFS_STS_COFS4W, hdata->shm_base + NCT6694_SHM_COFS_STS); + + ret =3D regmap_bulk_read(hdata->rpt_regmap, NCT6694_SHM_INTR_STATUS, + reg_data, ARRAY_SIZE(reg_data)); + if (ret) + return IRQ_HANDLED; + + intr_status =3D get_unaligned_le32(reg_data); + + while (intr_status) { + int hwirq =3D __ffs(intr_status); + unsigned int virq =3D irq_find_mapping(nct6694->domain, hwirq); + + if (virq) + generic_handle_irq_safe(virq); + + intr_status &=3D ~BIT(hwirq); + } + + return IRQ_HANDLED; +} + +static void nct6694_hif_irq_disable(void *data) +{ + struct nct6694 *nct6694 =3D data; + struct nct6694_hif_data *hdata =3D nct6694->priv; + u8 cofs_ctl2; + + /* Disable SIRQ interrupt */ + cofs_ctl2 =3D inb(hdata->shm_base + NCT6694_SHM_COFS_CTL2); + cofs_ctl2 &=3D ~NCT6694_SHM_COFS_CTL2_COFS4W_IE; + outb(cofs_ctl2, hdata->shm_base + NCT6694_SHM_COFS_CTL2); +} + +static void nct6694_hif_irq_enable(struct nct6694 *nct6694) +{ + struct nct6694_hif_data *hdata =3D nct6694->priv; + u8 cofs_ctl2; + + /* Enable SIRQ interrupt */ + cofs_ctl2 =3D inb(hdata->shm_base + NCT6694_SHM_COFS_CTL2); + cofs_ctl2 |=3D NCT6694_SHM_COFS_CTL2_COFS4W_IE; + outb(cofs_ctl2, hdata->shm_base + NCT6694_SHM_COFS_CTL2); +} + +static int nct6694_hif_irq_init(struct nct6694 *nct6694, int irq) +{ + struct nct6694_hif_data *hdata =3D nct6694->priv; + struct nct6694_sio_data *sio_data =3D hdata->sio_data; + struct irq_data *irq_data; + irq_hw_number_t hwirq; + int ret; + + /* The chip is programmed with the SIRQ line, not the Linux irq number */ + irq_data =3D irq_get_irq_data(irq); + if (!irq_data) + return -EINVAL; + + hwirq =3D irqd_to_hwirq(irq_data); + if (hwirq > SIO_SHM_IRQ_NR_MAX) + return -ERANGE; + + /* Set SIRQ number */ + ret =3D superio_enter(sio_data); + if (ret) + return ret; + + superio_select(sio_data, SIO_REG_LD_SHM); + + if (!superio_inb(sio_data, SIO_REG_SHM_ENABLE)) { + superio_exit(sio_data); + return -EIO; + } + + hdata->shm_base =3D superio_inw(sio_data, SIO_REG_SHM_BASE_ADDR); + if (!hdata->shm_base) { + superio_exit(sio_data); + return -ENODEV; + } + + superio_outb(sio_data, SIO_REG_SHM_IRQ_NR, hwirq); + + superio_exit(sio_data); + + if (!devm_request_region(nct6694->dev, + hdata->shm_base + NCT6694_SHM_COFS_STS, + NCT6694_SHM_COFS_LEN, DRVNAME)) + return -EBUSY; + + /* Keep the device quiet until the IRQ domain is ready */ + nct6694_hif_irq_disable(nct6694); + outb(NCT6694_SHM_COFS_STS_COFS4W, hdata->shm_base + NCT6694_SHM_COFS_STS); + + return 0; +} + +static void nct6694_hif_core_remove_action(void *data) +{ + struct nct6694 *nct6694 =3D data; + + nct6694_core_remove(nct6694); +} + +static const u8 sio_addrs[] =3D { 0x2e, 0x4e }; + +static int nct6694_hif_probe(struct platform_device *pdev) +{ + struct device *dev =3D &pdev->dev; + struct nct6694_sio_data *sio_data; + struct nct6694_hif_data *hdata; + struct nct6694 *nct6694; + void __iomem *rpt_base, *msg_base; + int ret, i, irq; + + rpt_base =3D devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(rpt_base)) + return PTR_ERR(rpt_base); + + msg_base =3D devm_platform_ioremap_resource(pdev, 1); + if (IS_ERR(msg_base)) + return PTR_ERR(msg_base); + + irq =3D platform_get_irq(pdev, 0); + if (irq < 0) + return irq; + + sio_data =3D devm_kzalloc(dev, sizeof(*sio_data), GFP_KERNEL); + if (!sio_data) + return -ENOMEM; + + for (i =3D 0; i < ARRAY_SIZE(sio_addrs); i++) { + if (!nct6694_sio_find(sio_data, sio_addrs[i])) + break; + } + if (i =3D=3D ARRAY_SIZE(sio_addrs)) + return -ENODEV; + + dev_dbg(dev, "Found %s at %#x\n", nct6694_chip_names[sio_data->chip], sio= _data->sioreg); + + nct6694 =3D devm_kzalloc(dev, sizeof(*nct6694), GFP_KERNEL); + if (!nct6694) + return -ENOMEM; + + hdata =3D devm_kzalloc(dev, sizeof(*hdata), GFP_KERNEL); + if (!hdata) + return -ENOMEM; + + hdata->sio_data =3D sio_data; + hdata->msg_base =3D msg_base; + hdata->rpt_regmap =3D devm_regmap_init_mmio(dev, rpt_base, + &nct6694_hif_rpt_regmap_config); + if (IS_ERR(hdata->rpt_regmap)) + return PTR_ERR(hdata->rpt_regmap); + + nct6694->dev =3D dev; + nct6694->priv =3D hdata; + nct6694->regmap =3D devm_regmap_init(dev, &nct6694_hif_regmap_bus, nct669= 4, + &nct6694_hif_msg_regmap_config); + if (IS_ERR(nct6694->regmap)) + return PTR_ERR(nct6694->regmap); + + ret =3D nct6694_hif_irq_init(nct6694, irq); + if (ret) + return ret; + + platform_set_drvdata(pdev, nct6694); + + /* Request the interrupt first so that devres releases it last */ + ret =3D devm_request_threaded_irq(dev, irq, NULL, nct6694_hif_irq_handler, + IRQF_ONESHOT | IRQF_SHARED, + dev_name(dev), nct6694); + if (ret) + return ret; + + ret =3D nct6694_core_probe(dev, nct6694, nct6694_hif_devs, + ARRAY_SIZE(nct6694_hif_devs)); + if (ret) + return ret; + + ret =3D devm_add_action_or_reset(dev, nct6694_hif_core_remove_action, nct= 6694); + if (ret) + return ret; + + nct6694_hif_irq_enable(nct6694); + + return devm_add_action_or_reset(dev, nct6694_hif_irq_disable, nct6694); +} + +static const struct acpi_device_id nct6694_hif_acpi_ids[] =3D { + { "NTN0538", 0 }, + {} +}; +MODULE_DEVICE_TABLE(acpi, nct6694_hif_acpi_ids); + +static struct platform_driver nct6694_hif_driver =3D { + .driver =3D { + .name =3D DRVNAME, + .acpi_match_table =3D nct6694_hif_acpi_ids, + }, + .probe =3D nct6694_hif_probe, +}; +module_platform_driver(nct6694_hif_driver); + +MODULE_DESCRIPTION("Nuvoton NCT6694 host-interface transport driver"); +MODULE_AUTHOR("Ming Yu "); +MODULE_LICENSE("GPL"); --=20 2.34.1