Linux Input/HID development
 help / color / mirror / Atom feed
* Re: [PATCH v2 01/10] backlight: Match backlight device against struct fb_info.bl_dev
From: Thomas Zimmermann @ 2024-02-21 15:44 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: lee, daniel.thompson, jingoohan1, deller, robin, javierm,
	dri-devel, linux-fbdev, linux-input, linux-pwm
In-Reply-To: <ZdYJ4FhJ9vhzUeiW@smile.fi.intel.com>

Hi

Am 21.02.24 um 15:34 schrieb Andy Shevchenko:
> On Wed, Feb 21, 2024 at 10:41:28AM +0100, Thomas Zimmermann wrote:
>> Framebuffer drivers for devices with dedicated backlight are supposed
>> to set struct fb_info.bl_dev to the backlight's respective device. Use
>> the value to match backlight and framebuffer in the backlight core code.
> ...
>
>>   	if (!bd->ops)
>>   		goto out;
>> -	if (bd->ops->check_fb && !bd->ops->check_fb(bd, evdata->info))
>> +	else if (bd->ops->check_fb && !bd->ops->check_fb(bd, info))
> What's the point of adding redundant 'else'?
>
>>   		goto out;
>> +#if IS_ENABLED(CONFIG_FB_BACKLIGHT)
>> +	else if (info->bl_dev && info->bl_dev != bd)
> Ditto.

They group these tests into one single block of code; signaling that 
these tests serve the same purpose.

Best regards
Thomas

>
>> +		goto out;
>> +#endif

-- 
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)


^ permalink raw reply

* Re: [PATCH v2 02/10] auxdisplay/ht16k33: Remove struct backlight_ops.check_fb
From: Andy Shevchenko @ 2024-02-21 14:35 UTC (permalink / raw)
  To: Thomas Zimmermann
  Cc: lee, daniel.thompson, jingoohan1, deller, robin, javierm,
	dri-devel, linux-fbdev, linux-input, linux-pwm
In-Reply-To: <20240221094324.27436-3-tzimmermann@suse.de>

On Wed, Feb 21, 2024 at 10:41:29AM +0100, Thomas Zimmermann wrote:
> The driver sets struct fb_info.bl_dev to the correct backlight
> device. Thus rely on the backlight core code to match backlight
> and framebuffer devices, and remove the extra check_fb function
> from struct backlight_ops.

check_fb()

Acked-by: Andy Shevchenko <andy@kernel.org>

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply

* Re: [PATCH v2 01/10] backlight: Match backlight device against struct fb_info.bl_dev
From: Andy Shevchenko @ 2024-02-21 14:34 UTC (permalink / raw)
  To: Thomas Zimmermann
  Cc: lee, daniel.thompson, jingoohan1, deller, robin, javierm,
	dri-devel, linux-fbdev, linux-input, linux-pwm
In-Reply-To: <20240221094324.27436-2-tzimmermann@suse.de>

On Wed, Feb 21, 2024 at 10:41:28AM +0100, Thomas Zimmermann wrote:
> Framebuffer drivers for devices with dedicated backlight are supposed
> to set struct fb_info.bl_dev to the backlight's respective device. Use
> the value to match backlight and framebuffer in the backlight core code.

...

>  	if (!bd->ops)
>  		goto out;
> -	if (bd->ops->check_fb && !bd->ops->check_fb(bd, evdata->info))
> +	else if (bd->ops->check_fb && !bd->ops->check_fb(bd, info))

What's the point of adding redundant 'else'?

>  		goto out;
> +#if IS_ENABLED(CONFIG_FB_BACKLIGHT)
> +	else if (info->bl_dev && info->bl_dev != bd)

Ditto.

> +		goto out;
> +#endif

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply

* Future handling of complex RGB devices on Linux v2
From: Werner Sembach @ 2024-02-21 11:12 UTC (permalink / raw)
  To: Hans de Goede, Pavel Machek
  Cc: Lee Jones, jikos, linux-kernel, Jelle van der Waa, Miguel Ojeda,
	dri-devel@lists.freedesktop.org, linux-input, ojeda, linux-leds
In-Reply-To: <e21a7d87-3059-4a51-af04-1062dac977d2@tuxedocomputers.com>

Hi,

so after more feedback from the OpenRGB maintainers I came up with an even more 
generic proposal: 
https://gitlab.com/CalcProgrammer1/OpenRGB/-/issues/3916#note_1753072869

Copy pasting the relevant part:

 >Another, yet more generic, approach:
 >
 >```
 >get-device-info ioctl returning:
 >{
 >    char name[64]                /* Device model name / identifier */
 >    enum device_type            /* e.g. keyboard, mouse, lightbar, etc. */
 >    char firmware_version_string[64]    /* if known to the driver, empty 
otherwise */
 >    char serial_number[64]            /* if known to the driver, empty 
otherwise */
 >    enum supported_commands[128]        /* comands supported by the firmware */
 >}
 >
 >evaluate-set-command ioctl taking:
 >{
 >    enum command                /* one of supported_commands */
 >    union data
 >    {
 >        char raw[3072],
 >        {
 >            <input struct for command 0>
 >        },
 >        {
 >            <input struct for command 1>
 >        },
 >        ...
 >    }
 >}
 >
 >evaluate-get-command ioctl taking:
 >{
 >    enum command                /* one of supported_commands */
 >    union data
 >    {
 >        char raw[3072],
 >        {
 >            <input struct for command 0>
 >        },
 >        {
 >            <input struct for command 1>
 >        },
 >        ...
 >    }
 >}
 >and returning:
 >{
 >    union data
 >    {
 >        char raw[3072],
 >        {
 >            <return struct for command 0>    /* not every command might have 
one */
 >        },
 >        {
 >            <return struct for command 1>    /* not every command might have 
one */
 >        },
 >        ...
 >    }
 >}
 >```
 >
 >- char name[64] still includes, if know to the driver, information about 
physical or even printed layout.
 >- differentiation between evaluate-set-command and evaluate-get-command is 
mainly there for performance optimization for direct mode (for 
evaluate-set-command the kernel does not have to copy anything back to userspace)
 >- commands without a return struct must not be used with evaluate-get-command
 >- the input struct might be empty for very simple commands (or "int unused" to 
not confuse the compiler if neccessary)
 >
 >Now is the question: How does userspace know which commands takes/returns 
which structs? Define them in one big header file (as struct 
clevo_set_breathing_mode_1_input, struct tongfang_set_breathing_mode_1_input, 
etc.), or somehow dynamicaly? I'm warming up to Hans suggestion to just do it 
statically, unlike my suggestion yesterday.
 >
 >Min/Max values are documented in the header file (if not implied by variable 
type). With different max value -> different command, e.g. 
clevo_set_breathing_mode_1 for devices with speed from 0 to 7 and 
clevo_set_breathing_mode_2 for devices with speed from 1 to 10.

But at this point it is almost a generic interface that can be used to expose 
anything to userspace, looping back to the sanitized-wmiraw idea that was 
floating around earlier.

So a new approach (Please correct me if there is already something similar I'm 
not aware of):

New subsystem "Platform Device Commands" (short platdevcom) (I'm open for better 
name suggestions):

- Registers /sys/class/platdevcom/platdevcom[0-9]* (similar to hidraw)
- Has get-device-info ioctl, evaluate-set-command ioctl, and 
evaluate-get-command ioctl as described above
- device_type enum entries for rgb would be for example rgbleds_keyboard, 
rgbleds_mouse, etc.

On a high level this subsystem can be used to expose any platform functionality 
to userspace that doesn't fit another subsystem in a central location. This 
could be for example a nearly 1 to 1 sanitized mapping to wmi calls. Or writing 
a specific EC register to control OEM BIOS features like flexi charging (only 
charge battery to specific percentage to extend the live).

However I am aware that this is hardly an api. So Maybe it's best to just fall 
back on extending the leds subsystem with the deactivate command, and from there 
just implement the few rgb devices that are not hidraw as misc devices in a per 
OEM fasion without a unified api.


^ permalink raw reply

* [PATCH v2 10/10] backlight: Add controls_device callback to struct backlight_ops
From: Thomas Zimmermann @ 2024-02-21  9:41 UTC (permalink / raw)
  To: lee, daniel.thompson, jingoohan1, deller, andy, robin, javierm
  Cc: dri-devel, linux-fbdev, linux-input, linux-pwm, Thomas Zimmermann
In-Reply-To: <20240221094324.27436-1-tzimmermann@suse.de>

Replace check_fb with controls_device in struct backlight_ops. The
new callback interface takes a Linux device instead of a framebuffer.
Resolves one of the dependencies of backlight.h on fb.h.

The few drivers that had custom implementations of check_fb can easily
use the framebuffer's Linux device instead. Update them accordingly.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Daniel Thompson <daniel.thompson@linaro.org>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
---
 drivers/video/backlight/backlight.c      |  2 +-
 drivers/video/backlight/bd6107.c         | 12 ++++++------
 drivers/video/backlight/gpio_backlight.c | 12 ++++++------
 drivers/video/backlight/lv5207lp.c       | 12 ++++++------
 include/linux/backlight.h                | 16 ++++++++--------
 5 files changed, 27 insertions(+), 27 deletions(-)

diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c
index 48844a4f28ad3..18a0ac4bd6005 100644
--- a/drivers/video/backlight/backlight.c
+++ b/drivers/video/backlight/backlight.c
@@ -111,7 +111,7 @@ static int fb_notifier_callback(struct notifier_block *self,
 
 	if (!bd->ops)
 		goto out;
-	else if (bd->ops->check_fb && !bd->ops->check_fb(bd, info))
+	else if (bd->ops->controls_device && !bd->ops->controls_device(bd, info->device))
 		goto out;
 #if IS_ENABLED(CONFIG_FB_BACKLIGHT)
 	else if (info->bl_dev && info->bl_dev != bd)
diff --git a/drivers/video/backlight/bd6107.c b/drivers/video/backlight/bd6107.c
index c95a12bf0ce26..d124ede084ef9 100644
--- a/drivers/video/backlight/bd6107.c
+++ b/drivers/video/backlight/bd6107.c
@@ -99,18 +99,18 @@ static int bd6107_backlight_update_status(struct backlight_device *backlight)
 	return 0;
 }
 
-static int bd6107_backlight_check_fb(struct backlight_device *backlight,
-				       struct fb_info *info)
+static bool bd6107_backlight_controls_device(struct backlight_device *backlight,
+					     struct device *display_dev)
 {
 	struct bd6107 *bd = bl_get_data(backlight);
 
-	return !bd->pdata->dev || bd->pdata->dev == info->device;
+	return !bd->pdata->dev || bd->pdata->dev == display_dev;
 }
 
 static const struct backlight_ops bd6107_backlight_ops = {
-	.options	= BL_CORE_SUSPENDRESUME,
-	.update_status	= bd6107_backlight_update_status,
-	.check_fb	= bd6107_backlight_check_fb,
+	.options	 = BL_CORE_SUSPENDRESUME,
+	.update_status	 = bd6107_backlight_update_status,
+	.controls_device = bd6107_backlight_controls_device,
 };
 
 static int bd6107_probe(struct i2c_client *client)
diff --git a/drivers/video/backlight/gpio_backlight.c b/drivers/video/backlight/gpio_backlight.c
index d28c30b2a35d2..c0cff685ea848 100644
--- a/drivers/video/backlight/gpio_backlight.c
+++ b/drivers/video/backlight/gpio_backlight.c
@@ -30,18 +30,18 @@ static int gpio_backlight_update_status(struct backlight_device *bl)
 	return 0;
 }
 
-static int gpio_backlight_check_fb(struct backlight_device *bl,
-				   struct fb_info *info)
+static bool gpio_backlight_controls_device(struct backlight_device *bl,
+					   struct device *display_dev)
 {
 	struct gpio_backlight *gbl = bl_get_data(bl);
 
-	return !gbl->dev || gbl->dev == info->device;
+	return !gbl->dev || gbl->dev == display_dev;
 }
 
 static const struct backlight_ops gpio_backlight_ops = {
-	.options	= BL_CORE_SUSPENDRESUME,
-	.update_status	= gpio_backlight_update_status,
-	.check_fb	= gpio_backlight_check_fb,
+	.options	 = BL_CORE_SUSPENDRESUME,
+	.update_status	 = gpio_backlight_update_status,
+	.controls_device = gpio_backlight_controls_device,
 };
 
 static int gpio_backlight_probe(struct platform_device *pdev)
diff --git a/drivers/video/backlight/lv5207lp.c b/drivers/video/backlight/lv5207lp.c
index 1f1d06b4e119a..0cf00fee0f605 100644
--- a/drivers/video/backlight/lv5207lp.c
+++ b/drivers/video/backlight/lv5207lp.c
@@ -62,18 +62,18 @@ static int lv5207lp_backlight_update_status(struct backlight_device *backlight)
 	return 0;
 }
 
-static int lv5207lp_backlight_check_fb(struct backlight_device *backlight,
-				       struct fb_info *info)
+static bool lv5207lp_backlight_controls_device(struct backlight_device *backlight,
+					       struct device *display_dev)
 {
 	struct lv5207lp *lv = bl_get_data(backlight);
 
-	return !lv->pdata->dev || lv->pdata->dev == info->device;
+	return !lv->pdata->dev || lv->pdata->dev == display_dev;
 }
 
 static const struct backlight_ops lv5207lp_backlight_ops = {
-	.options	= BL_CORE_SUSPENDRESUME,
-	.update_status	= lv5207lp_backlight_update_status,
-	.check_fb	= lv5207lp_backlight_check_fb,
+	.options	 = BL_CORE_SUSPENDRESUME,
+	.update_status	 = lv5207lp_backlight_update_status,
+	.controls_device = lv5207lp_backlight_controls_device,
 };
 
 static int lv5207lp_probe(struct i2c_client *client)
diff --git a/include/linux/backlight.h b/include/linux/backlight.h
index 614653e07e3a8..2db4c70053c46 100644
--- a/include/linux/backlight.h
+++ b/include/linux/backlight.h
@@ -13,6 +13,7 @@
 #include <linux/fb.h>
 #include <linux/mutex.h>
 #include <linux/notifier.h>
+#include <linux/types.h>
 
 /**
  * enum backlight_update_reason - what method was used to update backlight
@@ -110,7 +111,6 @@ enum backlight_scale {
 };
 
 struct backlight_device;
-struct fb_info;
 
 /**
  * struct backlight_ops - backlight operations
@@ -160,18 +160,18 @@ struct backlight_ops {
 	int (*get_brightness)(struct backlight_device *);
 
 	/**
-	 * @check_fb: Check the framebuffer device.
+	 * @controls_device: Check against the display device
 	 *
-	 * Check if given framebuffer device is the one bound to this backlight.
-	 * This operation is optional and if not implemented it is assumed that the
-	 * fbdev is always the one bound to the backlight.
+	 * Check if the backlight controls the given display device. This
+	 * operation is optional and if not implemented it is assumed that
+	 * the display is always the one controlled by the backlight.
 	 *
 	 * RETURNS:
 	 *
-	 * If info is NULL or the info matches the fbdev bound to the backlight return true.
-	 * If info does not match the fbdev bound to the backlight return false.
+	 * If display_dev is NULL or display_dev matches the device controlled by
+	 * the backlight, return true. Otherwise return false.
 	 */
-	int (*check_fb)(struct backlight_device *bd, struct fb_info *info);
+	bool (*controls_device)(struct backlight_device *bd, struct device *display_dev);
 };
 
 /**
-- 
2.43.0


^ permalink raw reply related

* [PATCH v2 09/10] fbdev/ssd1307fb: Remove struct backlight_ops.check_fb
From: Thomas Zimmermann @ 2024-02-21  9:41 UTC (permalink / raw)
  To: lee, daniel.thompson, jingoohan1, deller, andy, robin, javierm
  Cc: dri-devel, linux-fbdev, linux-input, linux-pwm, Thomas Zimmermann
In-Reply-To: <20240221094324.27436-1-tzimmermann@suse.de>

The driver sets struct fb_info.bl_dev to the correct backlight
device. Thus rely on the backlight core code to match backlight
and framebuffer devices, and remove the extra check_fb function
from struct backlight_ops.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
---
 drivers/video/fbdev/ssd1307fb.c | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/drivers/video/fbdev/ssd1307fb.c b/drivers/video/fbdev/ssd1307fb.c
index 0d1590c61eb06..3f30af3c059e0 100644
--- a/drivers/video/fbdev/ssd1307fb.c
+++ b/drivers/video/fbdev/ssd1307fb.c
@@ -530,17 +530,10 @@ static int ssd1307fb_get_brightness(struct backlight_device *bdev)
 	return par->contrast;
 }
 
-static int ssd1307fb_check_fb(struct backlight_device *bdev,
-				   struct fb_info *info)
-{
-	return (info->bl_dev == bdev);
-}
-
 static const struct backlight_ops ssd1307fb_bl_ops = {
 	.options	= BL_CORE_SUSPENDRESUME,
 	.update_status	= ssd1307fb_update_bl,
 	.get_brightness	= ssd1307fb_get_brightness,
-	.check_fb	= ssd1307fb_check_fb,
 };
 
 static struct ssd1307fb_deviceinfo ssd1307fb_ssd1305_deviceinfo = {
-- 
2.43.0


^ permalink raw reply related

* [PATCH v2 08/10] fbdev/ssd1307fb: Init backlight before registering framebuffer
From: Thomas Zimmermann @ 2024-02-21  9:41 UTC (permalink / raw)
  To: lee, daniel.thompson, jingoohan1, deller, andy, robin, javierm
  Cc: dri-devel, linux-fbdev, linux-input, linux-pwm, Thomas Zimmermann
In-Reply-To: <20240221094324.27436-1-tzimmermann@suse.de>

For drivers that support backlight, LCD and fbdev devices, fbdev has
to be initialized last. See documentation for struct fbinfo.bl_dev.

The backlight name's index number comes from register_framebuffer(),
which now happens after initializing the backlight device. So like
in all other backlight drivers, we now give the backlight device a
generic name without the fbdev index.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
---
 drivers/video/fbdev/ssd1307fb.c | 24 +++++++++++-------------
 1 file changed, 11 insertions(+), 13 deletions(-)

diff --git a/drivers/video/fbdev/ssd1307fb.c b/drivers/video/fbdev/ssd1307fb.c
index 1a4f90ea7d5a8..0d1590c61eb06 100644
--- a/drivers/video/fbdev/ssd1307fb.c
+++ b/drivers/video/fbdev/ssd1307fb.c
@@ -594,7 +594,6 @@ static int ssd1307fb_probe(struct i2c_client *client)
 {
 	struct device *dev = &client->dev;
 	struct backlight_device *bl;
-	char bl_name[12];
 	struct fb_info *info;
 	struct fb_deferred_io *ssd1307fb_defio;
 	u32 vmem_size;
@@ -733,31 +732,30 @@ static int ssd1307fb_probe(struct i2c_client *client)
 	if (ret)
 		goto regulator_enable_error;
 
-	ret = register_framebuffer(info);
-	if (ret) {
-		dev_err(dev, "Couldn't register the framebuffer\n");
-		goto panel_init_error;
-	}
-
-	snprintf(bl_name, sizeof(bl_name), "ssd1307fb%d", info->node);
-	bl = backlight_device_register(bl_name, dev, par, &ssd1307fb_bl_ops,
+	bl = backlight_device_register("ssd1307fb-bl", dev, par, &ssd1307fb_bl_ops,
 				       NULL);
 	if (IS_ERR(bl)) {
 		ret = PTR_ERR(bl);
 		dev_err(dev, "unable to register backlight device: %d\n", ret);
-		goto bl_init_error;
+		goto panel_init_error;
+	}
+	info->bl_dev = bl;
+
+	ret = register_framebuffer(info);
+	if (ret) {
+		dev_err(dev, "Couldn't register the framebuffer\n");
+		goto fb_init_error;
 	}
 
 	bl->props.brightness = par->contrast;
 	bl->props.max_brightness = MAX_CONTRAST;
-	info->bl_dev = bl;
 
 	dev_info(dev, "fb%d: %s framebuffer device registered, using %d bytes of video memory\n", info->node, info->fix.id, vmem_size);
 
 	return 0;
 
-bl_init_error:
-	unregister_framebuffer(info);
+fb_init_error:
+	backlight_device_unregister(bl);
 panel_init_error:
 	pwm_disable(par->pwm);
 	pwm_put(par->pwm);
-- 
2.43.0


^ permalink raw reply related

* [PATCH v2 06/10] backlight/pwm-backlight: Remove struct backlight_ops.check_fb
From: Thomas Zimmermann @ 2024-02-21  9:41 UTC (permalink / raw)
  To: lee, daniel.thompson, jingoohan1, deller, andy, robin, javierm
  Cc: dri-devel, linux-fbdev, linux-input, linux-pwm, Thomas Zimmermann,
	Uwe Kleine-König
In-Reply-To: <20240221094324.27436-1-tzimmermann@suse.de>

The internal check_fb callback from struct pwm_bl_data is never
implemented. The driver's implementation of check_fb always
returns true, which is the backlight core's default if no
implementation has been set. So remove the code from the driver.

v2:
	* reword commit message

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Cc: "Uwe Kleine-König" <u.kleine-koenig@pengutronix.de>
Acked-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Reviewed-by: Daniel Thompson <daniel.thompson@linaro.org>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
---
 drivers/video/backlight/pwm_bl.c | 12 ------------
 include/linux/pwm_backlight.h    |  1 -
 2 files changed, 13 deletions(-)

diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
index ffcebf6aa76a9..61d30bc98eea5 100644
--- a/drivers/video/backlight/pwm_bl.c
+++ b/drivers/video/backlight/pwm_bl.c
@@ -11,7 +11,6 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
-#include <linux/fb.h>
 #include <linux/backlight.h>
 #include <linux/err.h>
 #include <linux/pwm.h>
@@ -34,7 +33,6 @@ struct pwm_bl_data {
 					  int brightness);
 	void			(*notify_after)(struct device *,
 					int brightness);
-	int			(*check_fb)(struct device *, struct fb_info *);
 	void			(*exit)(struct device *);
 };
 
@@ -129,17 +127,8 @@ static int pwm_backlight_update_status(struct backlight_device *bl)
 	return 0;
 }
 
-static int pwm_backlight_check_fb(struct backlight_device *bl,
-				  struct fb_info *info)
-{
-	struct pwm_bl_data *pb = bl_get_data(bl);
-
-	return !pb->check_fb || pb->check_fb(pb->dev, info);
-}
-
 static const struct backlight_ops pwm_backlight_ops = {
 	.update_status	= pwm_backlight_update_status,
-	.check_fb	= pwm_backlight_check_fb,
 };
 
 #ifdef CONFIG_OF
@@ -482,7 +471,6 @@ static int pwm_backlight_probe(struct platform_device *pdev)
 
 	pb->notify = data->notify;
 	pb->notify_after = data->notify_after;
-	pb->check_fb = data->check_fb;
 	pb->exit = data->exit;
 	pb->dev = &pdev->dev;
 	pb->enabled = false;
diff --git a/include/linux/pwm_backlight.h b/include/linux/pwm_backlight.h
index cdd2ac366bc72..0bf80e98d5b40 100644
--- a/include/linux/pwm_backlight.h
+++ b/include/linux/pwm_backlight.h
@@ -19,7 +19,6 @@ struct platform_pwm_backlight_data {
 	int (*notify)(struct device *dev, int brightness);
 	void (*notify_after)(struct device *dev, int brightness);
 	void (*exit)(struct device *dev);
-	int (*check_fb)(struct device *dev, struct fb_info *info);
 };
 
 #endif
-- 
2.43.0


^ permalink raw reply related

* [PATCH v2 07/10] fbdev/sh_mobile_lcdc_fb: Remove struct backlight_ops.check_fb
From: Thomas Zimmermann @ 2024-02-21  9:41 UTC (permalink / raw)
  To: lee, daniel.thompson, jingoohan1, deller, andy, robin, javierm
  Cc: dri-devel, linux-fbdev, linux-input, linux-pwm, Thomas Zimmermann
In-Reply-To: <20240221094324.27436-1-tzimmermann@suse.de>

The driver sets struct fb_info.bl_dev to the correct backlight
device. Thus rely on the backlight core code to match backlight
and framebuffer devices, and remove the extra check_fb function
from struct backlight_ops.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
---
 drivers/video/fbdev/sh_mobile_lcdcfb.c | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/drivers/video/fbdev/sh_mobile_lcdcfb.c b/drivers/video/fbdev/sh_mobile_lcdcfb.c
index eb2297b37504c..bf34c8ec1a26c 100644
--- a/drivers/video/fbdev/sh_mobile_lcdcfb.c
+++ b/drivers/video/fbdev/sh_mobile_lcdcfb.c
@@ -2140,17 +2140,10 @@ static int sh_mobile_lcdc_get_brightness(struct backlight_device *bdev)
 	return ch->bl_brightness;
 }
 
-static int sh_mobile_lcdc_check_fb(struct backlight_device *bdev,
-				   struct fb_info *info)
-{
-	return (info->bl_dev == bdev);
-}
-
 static const struct backlight_ops sh_mobile_lcdc_bl_ops = {
 	.options	= BL_CORE_SUSPENDRESUME,
 	.update_status	= sh_mobile_lcdc_update_bl,
 	.get_brightness	= sh_mobile_lcdc_get_brightness,
-	.check_fb	= sh_mobile_lcdc_check_fb,
 };
 
 static struct backlight_device *sh_mobile_lcdc_bl_probe(struct device *parent,
-- 
2.43.0


^ permalink raw reply related

* [PATCH v2 01/10] backlight: Match backlight device against struct fb_info.bl_dev
From: Thomas Zimmermann @ 2024-02-21  9:41 UTC (permalink / raw)
  To: lee, daniel.thompson, jingoohan1, deller, andy, robin, javierm
  Cc: dri-devel, linux-fbdev, linux-input, linux-pwm, Thomas Zimmermann
In-Reply-To: <20240221094324.27436-1-tzimmermann@suse.de>

Framebuffer drivers for devices with dedicated backlight are supposed
to set struct fb_info.bl_dev to the backlight's respective device. Use
the value to match backlight and framebuffer in the backlight core code.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Daniel Thompson <daniel.thompson@linaro.org>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
---
 drivers/video/backlight/backlight.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c
index 86e1cdc8e3697..48844a4f28ad3 100644
--- a/drivers/video/backlight/backlight.c
+++ b/drivers/video/backlight/backlight.c
@@ -98,7 +98,8 @@ static int fb_notifier_callback(struct notifier_block *self,
 {
 	struct backlight_device *bd;
 	struct fb_event *evdata = data;
-	int node = evdata->info->node;
+	struct fb_info *info = evdata->info;
+	int node = info->node;
 	int fb_blank = 0;
 
 	/* If we aren't interested in this event, skip it immediately ... */
@@ -110,8 +111,12 @@ static int fb_notifier_callback(struct notifier_block *self,
 
 	if (!bd->ops)
 		goto out;
-	if (bd->ops->check_fb && !bd->ops->check_fb(bd, evdata->info))
+	else if (bd->ops->check_fb && !bd->ops->check_fb(bd, info))
 		goto out;
+#if IS_ENABLED(CONFIG_FB_BACKLIGHT)
+	else if (info->bl_dev && info->bl_dev != bd)
+		goto out;
+#endif
 
 	fb_blank = *(int *)evdata->data;
 	if (fb_blank == FB_BLANK_UNBLANK && !bd->fb_bl_on[node]) {
-- 
2.43.0


^ permalink raw reply related

* [PATCH v2 04/10] hid/hid-picolcd: Remove struct backlight_ops.check_fb
From: Thomas Zimmermann @ 2024-02-21  9:41 UTC (permalink / raw)
  To: lee, daniel.thompson, jingoohan1, deller, andy, robin, javierm
  Cc: dri-devel, linux-fbdev, linux-input, linux-pwm, Thomas Zimmermann,
	Bruno Prémont
In-Reply-To: <20240221094324.27436-1-tzimmermann@suse.de>

Update the driver to initialize struct fb_info.bl_dev to its backlight
device, if any. Thus rely on the backlight core code to match backlight
and framebuffer devices, and remove the extra check_fb function from
struct backlight_ops.

v2:
	* protect against CONFIG_FB_BACKLIGHT (Javier, kernel test robot)
	* reword commit message (Daniel)

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Cc: "Bruno Prémont" <bonbons@linux-vserver.org>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
---
 drivers/hid/hid-picolcd_backlight.c | 7 -------
 drivers/hid/hid-picolcd_fb.c        | 6 ++++++
 2 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/hid/hid-picolcd_backlight.c b/drivers/hid/hid-picolcd_backlight.c
index 5bd2a8c4bbd66..08d16917eb60b 100644
--- a/drivers/hid/hid-picolcd_backlight.c
+++ b/drivers/hid/hid-picolcd_backlight.c
@@ -9,7 +9,6 @@
 
 #include <linux/hid.h>
 
-#include <linux/fb.h>
 #include <linux/backlight.h>
 
 #include "hid-picolcd.h"
@@ -39,15 +38,9 @@ static int picolcd_set_brightness(struct backlight_device *bdev)
 	return 0;
 }
 
-static int picolcd_check_bl_fb(struct backlight_device *bdev, struct fb_info *fb)
-{
-	return fb && fb == picolcd_fbinfo((struct picolcd_data *)bl_get_data(bdev));
-}
-
 static const struct backlight_ops picolcd_blops = {
 	.update_status  = picolcd_set_brightness,
 	.get_brightness = picolcd_get_brightness,
-	.check_fb       = picolcd_check_bl_fb,
 };
 
 int picolcd_init_backlight(struct picolcd_data *data, struct hid_report *report)
diff --git a/drivers/hid/hid-picolcd_fb.c b/drivers/hid/hid-picolcd_fb.c
index d7dddd99d325e..750206f5fc674 100644
--- a/drivers/hid/hid-picolcd_fb.c
+++ b/drivers/hid/hid-picolcd_fb.c
@@ -493,6 +493,12 @@ int picolcd_init_framebuffer(struct picolcd_data *data)
 	info->fix = picolcdfb_fix;
 	info->fix.smem_len   = PICOLCDFB_SIZE*8;
 
+#ifdef CONFIG_FB_BACKLIGHT
+#ifdef CONFIG_HID_PICOLCD_BACKLIGHT
+	info->bl_dev = data->backlight;
+#endif
+#endif
+
 	fbdata = info->par;
 	spin_lock_init(&fbdata->lock);
 	fbdata->picolcd = data;
-- 
2.43.0


^ permalink raw reply related

* [PATCH v2 05/10] backlight/aat2870-backlight: Remove struct backlight.check_fb
From: Thomas Zimmermann @ 2024-02-21  9:41 UTC (permalink / raw)
  To: lee, daniel.thompson, jingoohan1, deller, andy, robin, javierm
  Cc: dri-devel, linux-fbdev, linux-input, linux-pwm, Thomas Zimmermann
In-Reply-To: <20240221094324.27436-1-tzimmermann@suse.de>

The driver's implementation of check_fb always returns true, which
is the default if no implementation has been set. So remove the code
from the driver.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Daniel Thompson <daniel.thompson@linaro.org>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
---
 drivers/video/backlight/aat2870_bl.c | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/drivers/video/backlight/aat2870_bl.c b/drivers/video/backlight/aat2870_bl.c
index 81fde3abb92c4..b4c3354a1a8a6 100644
--- a/drivers/video/backlight/aat2870_bl.c
+++ b/drivers/video/backlight/aat2870_bl.c
@@ -12,7 +12,6 @@
 #include <linux/platform_device.h>
 #include <linux/mutex.h>
 #include <linux/delay.h>
-#include <linux/fb.h>
 #include <linux/backlight.h>
 #include <linux/mfd/aat2870.h>
 
@@ -90,15 +89,9 @@ static int aat2870_bl_update_status(struct backlight_device *bd)
 	return 0;
 }
 
-static int aat2870_bl_check_fb(struct backlight_device *bd, struct fb_info *fi)
-{
-	return 1;
-}
-
 static const struct backlight_ops aat2870_bl_ops = {
 	.options = BL_CORE_SUSPENDRESUME,
 	.update_status = aat2870_bl_update_status,
-	.check_fb = aat2870_bl_check_fb,
 };
 
 static int aat2870_bl_probe(struct platform_device *pdev)
-- 
2.43.0


^ permalink raw reply related

* [PATCH v2 03/10] hid/hid-picolcd: Fix initialization order
From: Thomas Zimmermann @ 2024-02-21  9:41 UTC (permalink / raw)
  To: lee, daniel.thompson, jingoohan1, deller, andy, robin, javierm
  Cc: dri-devel, linux-fbdev, linux-input, linux-pwm, Thomas Zimmermann,
	Bruno Prémont
In-Reply-To: <20240221094324.27436-1-tzimmermann@suse.de>

For drivers that support backlight, LCD and fbdev devices, fbdev has
to be initialized last. See documentation for struct fbinfo.bl_dev.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Cc: "Bruno Prémont" <bonbons@linux-vserver.org>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
---
 drivers/hid/hid-picolcd_core.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/hid/hid-picolcd_core.c b/drivers/hid/hid-picolcd_core.c
index bbda231a7ce30..5ddebe25eb91f 100644
--- a/drivers/hid/hid-picolcd_core.c
+++ b/drivers/hid/hid-picolcd_core.c
@@ -474,11 +474,6 @@ static int picolcd_probe_lcd(struct hid_device *hdev, struct picolcd_data *data)
 	if (error)
 		goto err;
 
-	/* Set up the framebuffer device */
-	error = picolcd_init_framebuffer(data);
-	if (error)
-		goto err;
-
 	/* Setup lcd class device */
 	error = picolcd_init_lcd(data, picolcd_out_report(REPORT_CONTRAST, hdev));
 	if (error)
@@ -489,6 +484,11 @@ static int picolcd_probe_lcd(struct hid_device *hdev, struct picolcd_data *data)
 	if (error)
 		goto err;
 
+	/* Set up the framebuffer device */
+	error = picolcd_init_framebuffer(data);
+	if (error)
+		goto err;
+
 	/* Setup the LED class devices */
 	error = picolcd_init_leds(data, picolcd_out_report(REPORT_LED_STATE, hdev));
 	if (error)
@@ -502,9 +502,9 @@ static int picolcd_probe_lcd(struct hid_device *hdev, struct picolcd_data *data)
 	return 0;
 err:
 	picolcd_exit_leds(data);
+	picolcd_exit_framebuffer(data);
 	picolcd_exit_backlight(data);
 	picolcd_exit_lcd(data);
-	picolcd_exit_framebuffer(data);
 	picolcd_exit_cir(data);
 	picolcd_exit_keys(data);
 	return error;
@@ -623,9 +623,9 @@ static void picolcd_remove(struct hid_device *hdev)
 	/* Cleanup LED */
 	picolcd_exit_leds(data);
 	/* Clean up the framebuffer */
+	picolcd_exit_framebuffer(data);
 	picolcd_exit_backlight(data);
 	picolcd_exit_lcd(data);
-	picolcd_exit_framebuffer(data);
 	/* Cleanup input */
 	picolcd_exit_cir(data);
 	picolcd_exit_keys(data);
-- 
2.43.0


^ permalink raw reply related

* [PATCH v2 02/10] auxdisplay/ht16k33: Remove struct backlight_ops.check_fb
From: Thomas Zimmermann @ 2024-02-21  9:41 UTC (permalink / raw)
  To: lee, daniel.thompson, jingoohan1, deller, andy, robin, javierm
  Cc: dri-devel, linux-fbdev, linux-input, linux-pwm, Thomas Zimmermann
In-Reply-To: <20240221094324.27436-1-tzimmermann@suse.de>

The driver sets struct fb_info.bl_dev to the correct backlight
device. Thus rely on the backlight core code to match backlight
and framebuffer devices, and remove the extra check_fb function
from struct backlight_ops.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Cc: Robin van der Gracht <robin@protonic.nl>
Acked-by: Robin van der Gracht <robin@protonic.nl>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
---
 drivers/auxdisplay/ht16k33.c | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/drivers/auxdisplay/ht16k33.c b/drivers/auxdisplay/ht16k33.c
index a90430b7d07ba..0a858db32486b 100644
--- a/drivers/auxdisplay/ht16k33.c
+++ b/drivers/auxdisplay/ht16k33.c
@@ -325,16 +325,8 @@ static int ht16k33_bl_update_status(struct backlight_device *bl)
 	return ht16k33_brightness_set(priv, brightness);
 }
 
-static int ht16k33_bl_check_fb(struct backlight_device *bl, struct fb_info *fi)
-{
-	struct ht16k33_priv *priv = bl_get_data(bl);
-
-	return (fi == NULL) || (fi->par == priv);
-}
-
 static const struct backlight_ops ht16k33_bl_ops = {
 	.update_status	= ht16k33_bl_update_status,
-	.check_fb	= ht16k33_bl_check_fb,
 };
 
 /*
-- 
2.43.0


^ permalink raw reply related

* [PATCH v2 00/10] backlight: Replace struct fb_info in interfaces
From: Thomas Zimmermann @ 2024-02-21  9:41 UTC (permalink / raw)
  To: lee, daniel.thompson, jingoohan1, deller, andy, robin, javierm
  Cc: dri-devel, linux-fbdev, linux-input, linux-pwm, Thomas Zimmermann

Backlight drivers implement struct backlight_ops.check_fb, which
uses struct fb_info in its interface. Replace the callback with one
that does not use fb_info.

In DRM, we have several drivers that implement backlight support. By
including <linux/backlight.h> these drivers depend on <linux/fb.h>.
At the same time, fbdev is deprecated for new drivers and likely to
be replaced on many systems.

This patchset is part of a larger effort to implement the backlight
code without depending on fbdev.

Patch 1 makes the backlight core match backlight and framebuffer
devices via struct fb_info.bl_dev. Patches 2 to 9 then go through
drivers and remove unnecessary implementations of check_fb. Finally,
patch 10 replaces the check_fb hook with controls_device, which
uses the framebuffer's Linux device instead of the framebuffer.

v2:
	* fix hid-picolcd for CONFIG_FB_BACKLIGHT=n
	* fixes to commit messages

Thomas Zimmermann (10):
  backlight: Match backlight device against struct fb_info.bl_dev
  auxdisplay/ht16k33: Remove struct backlight_ops.check_fb
  hid/hid-picolcd: Fix initialization order
  hid/hid-picolcd: Remove struct backlight_ops.check_fb
  backlight/aat2870-backlight: Remove struct backlight.check_fb
  backlight/pwm-backlight: Remove struct backlight_ops.check_fb
  fbdev/sh_mobile_lcdc_fb: Remove struct backlight_ops.check_fb
  fbdev/ssd1307fb: Init backlight before registering framebuffer
  fbdev/ssd1307fb: Remove struct backlight_ops.check_fb
  backlight: Add controls_device callback to struct backlight_ops

 drivers/auxdisplay/ht16k33.c             |  8 ------
 drivers/hid/hid-picolcd_backlight.c      |  7 ------
 drivers/hid/hid-picolcd_core.c           | 14 +++++------
 drivers/hid/hid-picolcd_fb.c             |  6 +++++
 drivers/video/backlight/aat2870_bl.c     |  7 ------
 drivers/video/backlight/backlight.c      |  9 +++++--
 drivers/video/backlight/bd6107.c         | 12 ++++-----
 drivers/video/backlight/gpio_backlight.c | 12 ++++-----
 drivers/video/backlight/lv5207lp.c       | 12 ++++-----
 drivers/video/backlight/pwm_bl.c         | 12 ---------
 drivers/video/fbdev/sh_mobile_lcdcfb.c   |  7 ------
 drivers/video/fbdev/ssd1307fb.c          | 31 +++++++++---------------
 include/linux/backlight.h                | 16 ++++++------
 include/linux/pwm_backlight.h            |  1 -
 14 files changed, 57 insertions(+), 97 deletions(-)

-- 
2.43.0


^ permalink raw reply

* Re: [PATCH 00/10] backlight: Replace struct fb_info in interfaces
From: Thomas Zimmermann @ 2024-02-21  9:23 UTC (permalink / raw)
  To: Lee Jones
  Cc: Daniel Thompson, jingoohan1, deller, javierm, dri-devel,
	linux-fbdev, linux-input, linux-pwm
In-Reply-To: <20240219150209.GB10170@google.com>

Hi

Am 19.02.24 um 16:02 schrieb Lee Jones:
> On Thu, 15 Feb 2024, Thomas Zimmermann wrote:
>
>> Hi
>>
>> Am 15.02.24 um 13:13 schrieb Daniel Thompson:
>>> On Mon, Feb 12, 2024 at 05:16:33PM +0100, Thomas Zimmermann wrote:
>>>> Backlight drivers implement struct backlight_ops.check_fb, which
>>>> uses struct fb_info in its interface. Replace the callback with one
>>>> the does not use fb_info.
>>>>
>>>> In DRM, we have several drivers that implement backlight support. By
>>>> including <linux/backlight.h> these drivers depend on <linux/fb.h>.
>>>> At the same time, fbdev is deprecated for new drivers and likely to
>>>> be replaced on many systems.
>>>>
>>>> This patchset is part of a larger effort to implement the backlight
>>>> code without depending on fbdev.
>>>>
>>>> Patch 1 makes the backlight core match backlight and framebuffer
>>>> devices via struct fb_info.bl_dev. Patches 2 to 9 then go through
>>>> drivers and remove unnecessary implementations of check_fb. Finally,
>>>> patch 10 replaces the check_fb hook with controls_device, which
>>>> uses the framebuffer's Linux device instead of the framebuffer.
>>> I won't reply individually but I also took a look at the patches for
>>> the combo devices and it all looked good to me from a backlight
>>> point of view.
>>>
>>> However I don't want to drop Reviewed-by: on them since it risks those
>>> bit being mistaken for an ack and merged ahead of the patch 1...
>> Thanks for reviewing. Unless someone objects, my intention is to merge
>> everything via the drm-misc, so all patches should go in at once. I do have
>> a lot more patches that untangle backlight and fbdev almost completely, but
>> most of these changes are in the actual graphics drivers rather than the
>> backlight core code. So hopefully everything can go through the DRM tree; or
>> maybe the fbdev tree.
> This is only acceptable if the maintainers of those trees can provide me
> with a pull-request to a succinct (_only_ these patches) immutable
> branch.  If this is not possible, then I should like to merge the set
> through the Backlight tree and I can provide everyone else with said PR.

I see, there's a separate backlight tree.

I'm going to send another revision of this patchset. You either merge 
all of the patches via the backlight tree, or you could just merge 
patches 1, 5 and 6 for now. I'll take care to get the rest merged via 
other trees and I'll re-submoit patch 10 for a final clean up. Your choice.

Best regards
Thomas

>

-- 
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)


^ permalink raw reply

* Re: [PATCH v8 1/5] firmware: cs_dsp: Add write sequencer interface
From: Charles Keepax @ 2024-02-21  9:22 UTC (permalink / raw)
  To: James Ogletree
  Cc: dmitry.torokhov, robh+dt, krzysztof.kozlowski+dt, conor+dt, lee,
	broonie, jeff, patches, linux-sound, linux-input, devicetree
In-Reply-To: <20240221003630.2535938-2-jogletre@opensource.cirrus.com>

On Wed, Feb 21, 2024 at 12:36:26AM +0000, James Ogletree wrote:
> A write sequencer is a sequence of register addresses
> and values executed by some Cirrus DSPs following
> power state transitions.
> 
> Add support for Cirrus drivers to update or add to a
> write sequencer present in firmware.
> 
> Signed-off-by: James Ogletree <jogletre@opensource.cirrus.com>
> ---

Think this one looks good to me:

Reviewed-by: Charles Keepax <ckeepax@opensource.cirrus.com>

Thanks,
Charles

^ permalink raw reply

* Re: v6.8-rc4: Crash in rmi_unregister_function still present
From: Torsten Hilbrich @ 2024-02-21  7:24 UTC (permalink / raw)
  To: Dan Carpenter; +Cc: Dmitry Torokhov, Sasha Levin, linux-input, Brad Spengler
In-Reply-To: <3401abdc-32c5-4b88-8edf-75d4683d4be0@moroto.mountain>

On 21.02.24 08:15, Dan Carpenter wrote:
> On Wed, Feb 21, 2024 at 07:55:40AM +0100, Torsten Hilbrich wrote:
>> Hello,
>>
>> updating our codebase to v6.8-rc4 which contains:
>>
>> eb988e46da2e Input: synaptics-rmi4 - fix use after free in rmi_unregister_function()
>>
>> I noticed that the previously noticed crash in the rmi4 was present again.
>>
>> Previously, we were using a fix from the grsecurity codebase which changed the function in the following way:
>>
>> void rmi_unregister_function(struct rmi_function *fn)
>> {
>> 	int i;
>>
>> 	rmi_dbg(RMI_DEBUG_CORE, &fn->dev, "Unregistering F%02X.\n",
>> 			fn->fd.function_number);
>>
>> 	for (i = 0; i < fn->num_of_irqs; i++)
>> 		irq_dispose_mapping(fn->irq[i]);
>>
>> 	device_del(&fn->dev);
>> 	of_node_put(fn->dev.of_node);
>> 	put_device(&fn->dev);
>> }
>>
>> With this version of the fix the crash didn't happen. Please note, that the crash happens in device_del which is before the irq_dispose_mapping call in eb988e46da2e.
>>
>> Attached is a kernel log from the crash with a kernel based on v6.8-rc4.
> 
> Hi Torsten,
> 
> Thanks for the bug report.  The truth is that I don't really understand
> how IRQ mappings work.  It would be simple enough to apply the same
> fix that grsecurity does.  The only question how to assign authorship
> credit.  Dmitry, how do you want to handle this?

The original patch was supplied to me by Brad Spengler <spender@grsecurity.net>

There is also a bugreport https://bugzilla.kernel.org/show_bug.cgi?id=215604 related to that problem.

	Torsten

^ permalink raw reply

* Re: v6.8-rc4: Crash in rmi_unregister_function still present
From: Dan Carpenter @ 2024-02-21  7:15 UTC (permalink / raw)
  To: Torsten Hilbrich; +Cc: Dmitry Torokhov, Sasha Levin, linux-input, Brad Spengler
In-Reply-To: <1932038e-2776-04ac-5fcd-b15bb3cd088d@secunet.com>

On Wed, Feb 21, 2024 at 07:55:40AM +0100, Torsten Hilbrich wrote:
> Hello,
> 
> updating our codebase to v6.8-rc4 which contains:
> 
> eb988e46da2e Input: synaptics-rmi4 - fix use after free in rmi_unregister_function()
> 
> I noticed that the previously noticed crash in the rmi4 was present again.
> 
> Previously, we were using a fix from the grsecurity codebase which changed the function in the following way:
> 
> void rmi_unregister_function(struct rmi_function *fn)
> {
> 	int i;
> 
> 	rmi_dbg(RMI_DEBUG_CORE, &fn->dev, "Unregistering F%02X.\n",
> 			fn->fd.function_number);
> 
> 	for (i = 0; i < fn->num_of_irqs; i++)
> 		irq_dispose_mapping(fn->irq[i]);
> 
> 	device_del(&fn->dev);
> 	of_node_put(fn->dev.of_node);
> 	put_device(&fn->dev);
> }
> 
> With this version of the fix the crash didn't happen. Please note, that the crash happens in device_del which is before the irq_dispose_mapping call in eb988e46da2e.
> 
> Attached is a kernel log from the crash with a kernel based on v6.8-rc4.

Hi Torsten,

Thanks for the bug report.  The truth is that I don't really understand
how IRQ mappings work.  It would be simple enough to apply the same
fix that grsecurity does.  The only question how to assign authorship
credit.  Dmitry, how do you want to handle this?

regards,
dan carpenter

diff --git a/drivers/input/rmi4/rmi_bus.c b/drivers/input/rmi4/rmi_bus.c
index 1b45b1d3077d..02acc81b9d3e 100644
--- a/drivers/input/rmi4/rmi_bus.c
+++ b/drivers/input/rmi4/rmi_bus.c
@@ -275,12 +275,11 @@ void rmi_unregister_function(struct rmi_function *fn)
 	rmi_dbg(RMI_DEBUG_CORE, &fn->dev, "Unregistering F%02X.\n",
 			fn->fd.function_number);
 
-	device_del(&fn->dev);
-	of_node_put(fn->dev.of_node);
-
 	for (i = 0; i < fn->num_of_irqs; i++)
 		irq_dispose_mapping(fn->irq[i]);
 
+	device_del(&fn->dev);
+	of_node_put(fn->dev.of_node);
 	put_device(&fn->dev);
 }
 

^ permalink raw reply related

* v6.8-rc4: Crash in rmi_unregister_function still present
From: Torsten Hilbrich @ 2024-02-21  6:55 UTC (permalink / raw)
  To: Dan Carpenter; +Cc: Dmitry Torokhov, Sasha Levin, linux-input, Brad Spengler

[-- Attachment #1: Type: text/plain, Size: 901 bytes --]

Hello,

updating our codebase to v6.8-rc4 which contains:

eb988e46da2e Input: synaptics-rmi4 - fix use after free in rmi_unregister_function()

I noticed that the previously noticed crash in the rmi4 was present again.

Previously, we were using a fix from the grsecurity codebase which changed the function in the following way:

void rmi_unregister_function(struct rmi_function *fn)
{
	int i;

	rmi_dbg(RMI_DEBUG_CORE, &fn->dev, "Unregistering F%02X.\n",
			fn->fd.function_number);

	for (i = 0; i < fn->num_of_irqs; i++)
		irq_dispose_mapping(fn->irq[i]);

	device_del(&fn->dev);
	of_node_put(fn->dev.of_node);
	put_device(&fn->dev);
}

With this version of the fix the crash didn't happen. Please note, that the crash happens in device_del which is before the irq_dispose_mapping call in eb988e46da2e.

Attached is a kernel log from the crash with a kernel based on v6.8-rc4.

Thanks,

	Torsten

[-- Attachment #2: kernel.log --]
[-- Type: text/x-log, Size: 81747 bytes --]

Oops#1 Part1
<5>[    0.000000] Linux version 6.8.0-devel+ (thilbrich@ws-3) (gcc (Debian 12.2.0-14) 12.2.0, GNU ld (GNU Binutils for Debian) 2.40) #1 SMP PREEMPT_DYNAMIC Thu Feb 15 12:52:10 CET 2024
<6>[    0.000000] Command line: BOOT_IMAGE=/isolinux/bzImage loglevel=1 sina_toram console=tty1 intel_iommu=on,igfx_off
<6>[    0.000000] BIOS-provided physical RAM map:
<6>[    0.000000] BIOS-e820: [mem 0x0000000000000000-0x000000000009efff] usable
<6>[    0.000000] BIOS-e820: [mem 0x000000000009f000-0x00000000000fffff] reserved
<6>[    0.000000] BIOS-e820: [mem 0x0000000000100000-0x00000000944b6fff] usable
<6>[    0.000000] BIOS-e820: [mem 0x00000000944b7000-0x000000009456efff] type 20
<6>[    0.000000] BIOS-e820: [mem 0x000000009456f000-0x0000000098694fff] reserved
<6>[    0.000000] BIOS-e820: [mem 0x0000000098695000-0x0000000099a1efff] ACPI NVS
<6>[    0.000000] BIOS-e820: [mem 0x0000000099a1f000-0x0000000099b4efff] ACPI data
<6>[    0.000000] BIOS-e820: [mem 0x0000000099b4f000-0x0000000099b4ffff] usable
<6>[    0.000000] BIOS-e820: [mem 0x0000000099b50000-0x000000009f7fffff] reserved
<6>[    0.000000] BIOS-e820: [mem 0x0000000100000000-0x000000085e7fffff] usable
<6>[    0.000000] NX (Execute Disable) protection: active
<6>[    0.000000] APIC: Static calls initialized
<6>[    0.000000] user-defined physical RAM map:
<6>[    0.000000] user: [mem 0x0000000000000000-0x000000000009efff] usable
<6>[    0.000000] user: [mem 0x000000000009f000-0x00000000000fffff] reserved
<6>[    0.000000] user: [mem 0x0000000000100000-0x00000000944b6fff] usable
<6>[    0.000000] user: [mem 0x00000000944b7000-0x000000009456efff] type 20
<6>[    0.000000] user: [mem 0x000000009456f000-0x0000000098694fff] reserved
<6>[    0.000000] user: [mem 0x0000000098695000-0x0000000099a1efff] ACPI NVS
<6>[    0.000000] user: [mem 0x0000000099a1f000-0x0000000099b4efff] ACPI data
<6>[    0.000000] user: [mem 0x0000000099b4f000-0x0000000099b4ffff] usable
<6>[    0.000000] user: [mem 0x0000000099b50000-0x000000009f7fffff] reserved
<6>[    0.000000] user: [mem 0x0000000100000000-0x0000000187ffffff] usable
<6>[    0.000000] user: [mem 0x0000000188000000-0x0000000189ffffff] reserved
<6>[    0.000000] user: [mem 0x000000018a000000-0x000000085e7fffff] usable
<6>[    0.000000] efi: EFI v2.7 by Lenovo
<6>[    0.000000] efi: SMBIOS=0x96ab8000 SMBIOS 3.0=0x96aab000 ACPI=0x99b4e000 ACPI 2.0=0x99b4e014 MEMATTR=0x911d8018 ESRT=0x96965000 
<6>[    0.000000] SMBIOS 3.2.0 present.
<6>[    0.000000] DMI: LENOVO 20S1S19N00/20S1S19N00, BIOS N2XET24S (3.14 ) 10/10/2020
<6>[    0.000000] tsc: Detected 2300.000 MHz processor
<6>[    0.000000] tsc: Detected 2299.968 MHz TSC
<7>[    0.000010] e820: update [mem 0x00000000-0x00000fff] usable ==> reserved
<7>[    0.000015] e820: remove [mem 0x000a0000-0x000fffff] usable
<6>[    0.000026] last_pfn = 0x85e800 max_arch_pfn = 0x400000000
<6>[    0.000033] MTRR map: 5 entries (3 fixed + 2 variable; max 23), built from 10 variable MTRRs
<6>[    0.000036] x86/PAT: Configuration [0-7]: WB  WC  UC- UC  WB  WP  UC- WT  
<6>[    0.000594] last_pfn = 0x99b50 max_arch_pfn = 0x400000000
<6>[    0.013872] Using GB pages for direct mapping
<6>[    0.014342] Secure boot enabled
<6>[    0.014343] RAMDISK: [mem 0x32f2b000-0x3578cfff]
<6>[    0.014351] ACPI: Early table checksum verification disabled
<6>[    0.014355] ACPI: RSDP 0x0000000099B4E014 000024 (v02 LENOVO)
<6>[    0.014361] ACPI: XSDT 0x0000000099B4C188 0000FC (v01 LENOVO TP-N2X   00003140 PTEC 00000002)
<6>[    0.014370] ACPI: FACP 0x0000000096962000 000114 (v06 LENOVO TP-N2X   00003140 PTEC 00000002)
<6>[    0.014378] ACPI: DSDT 0x0000000096932000 02BFF1 (v02 LENOVO CML      20170001 INTL 20160422)
<6>[    0.014384] ACPI: FACS 0x0000000099884000 000040
<6>[    0.014388] ACPI: SSDT 0x00000000969BC000 0020AE (v02 LENOVO CpuSsdt  00003000 INTL 20160527)
<6>[    0.014394] ACPI: SSDT 0x00000000969BB000 0005A1 (v02 LENOVO CtdpB    00001000 INTL 20160527)
<6>[    0.014399] ACPI: SSDT 0x000000009697E000 003532 (v02 LENOVO DptfTabl 00001000 INTL 20160527)
<6>[    0.014404] ACPI: SSDT 0x0000000096968000 00331E (v02 LENOVO SaSsdt   00003000 INTL 20160527)
<6>[    0.014409] ACPI: BOOT 0x0000000096966000 000028 (v01 LENOVO TP-N2X   00003140 PTEC 00000002)
<6>[    0.014413] ACPI: SSDT 0x0000000096963000 0005D8 (v02 LENOVO PerfTune 00001000 INTL 20160527)
<6>[    0.014418] ACPI: HPET 0x0000000096961000 000038 (v01 LENOVO TP-N2X   00003140 PTEC 00000002)
<6>[    0.014423] ACPI: APIC 0x0000000096960000 000164 (v03 LENOVO TP-N2X   00003140 PTEC 00000002)
<6>[    0.014428] ACPI: MCFG 0x000000009695F000 00003C (v01 LENOVO TP-N2X   00003140 PTEC 00000002)
<6>[    0.014433] ACPI: ECDT 0x000000009695E000 000053 (v01 LENOVO TP-N2X   00003140 PTEC 00000002)
<6>[    0.014438] ACPI: SSDT 0x0000000096930000 001F31 (v02 LENOVO WHL_Tbt_ 00001000 INTL 20160527)
<6>[    0.014443] ACPI: SSDT 0x000000009692F000 0000A6 (v02 LENOVO PID0Ssdt 00000010 INTL 20160527)
<6>[    0.014448] ACPI: SSDT 0x000000009692B000 0037A1 (v02 LENOVO ProjSsdt 00000010 INTL 20160527)
<6>[    0.014452] ACPI: NHLT 0x0000000096929000 00189E (v00 LENOVO TP-N2X   00003140 PTEC 00000002)
<6>[    0.014457] ACPI: MSDM 0x0000000096928000 000055 (v03 LENOVO TP-N2X   00003140 PTEC 00000002)
<6>[    0.014462] ACPI: SSDT 0x000000009674B000 000EF6 (v02 LENOVO UsbCTabl 00001000 INTL 20160527)
<6>[    0.014467] ACPI: LPIT 0x000000009674A000 000094 (v01 LENOVO TP-N2X   00003140 PTEC 00000002)
<6>[    0.014472] ACPI: WSMT 0x0000000096749000 000028 (v01 LENOVO TP-N2X   00003140 PTEC 00000002)
<6>[    0.014477] ACPI: SSDT 0x0000000096746000 00281B (v02 LENOVO TbtTypeC 00000000 INTL 20160527)
<6>[    0.014481] ACPI: DBGP 0x0000000096745000 000034 (v01 LENOVO TP-N2X   00003140 PTEC 00000002)
<6>[    0.014486] ACPI: DBG2 0x0000000096744000 000054 (v00 LENOVO TP-N2X   00003140 PTEC 00000002)
<6>[    0.014491] ACPI: BATB 0x0000000096743000 00004A (v02 LENOVO TP-N2X   00003140 PTEC 00000002)
<6>[    0.014496] ACPI: DMAR 0x0000000094F3C000 0000A8 (v01 LENOVO TP-N2X   00003140 PTEC 00000002)
<6>[    0.014501] ACPI: BGRT 0x0000000094F3B000 000038 (v01 LENOVO TP-N2X   00003140 PTEC 00000002)
<6>[    0.014506] ACPI: UEFI 0x0000000099839000 00012A (v01 LENOVO TP-N2X   00003140 PTEC 00000002)
<6>[    0.014510] ACPI: FPDT 0x0000000094F3A000 000044 (v01 LENOVO TP-N2X   00003140 PTEC 00003140)
<6>[    0.014514] ACPI: Reserving FACP table memory at [mem 0x96962000-0x96962113]
<6>[    0.014517] ACPI: Reserving DSDT table memory at [mem 0x96932000-0x9695dff0]
<6>[    0.014519] ACPI: Reserving FACS table memory at [mem 0x99884000-0x9988403f]
<6>[    0.014520] ACPI: Reserving SSDT table memory at [mem 0x969bc000-0x969be0ad]
<6>[    0.014522] ACPI: Reserving SSDT table memory at [mem 0x969bb000-0x969bb5a0]
<6>[    0.014523] ACPI: Reserving SSDT table memory at [mem 0x9697e000-0x96981531]
<6>[    0.014524] ACPI: Reserving SSDT table memory at [mem 0x96968000-0x9696b31d]
<6>[    0.014526] ACPI: Reserving BOOT table memory at [mem 0x96966000-0x96966027]
<6>[    0.014527] ACPI: Reserving SSDT table memory at [mem 0x96963000-0x969635d7]
<6>[    0.014529] ACPI: Reserving HPET table memory at [mem 0x96961000-0x96961037]
<6>[    0.014530] ACPI: Reserving APIC table memory at [mem 0x96960000-0x96960163]
<6>[    0.014532] ACPI: Reserving MCFG table memory at [mem 0x9695f000-0x9695f03b]
<6>[    0.014533] ACPI: Reserving ECDT table memory at [mem 0x9695e000-0x9695e052]
<6>[    0.014534] ACPI: Reserving SSDT table memory at [mem 0x96930000-0x96931f30]
<6>[    0.014536] ACPI: Reserving SSDT table memory at [mem 0x9692f000-0x9692f0a5]
<6>[    0.014537] ACPI: Reserving SSDT table memory at [mem 0x9692b000-0x9692e7a0]
<6>[    0.014539] ACPI: Reserving NHLT table memory at [mem 0x96929000-0x9692a89d]
<6>[    0.014540] ACPI: Reserving MSDM table memory at [mem 0x96928000-0x96928054]
<6>[    0.014541] ACPI: Reserving SSDT table memory at [mem 0x9674b000-0x9674bef5]
<6>[    0.014543] ACPI: Reserving LPIT table memory at [mem 0x9674a000-0x9674a093]
<6>[    0.014544] ACPI: Reserving WSMT table memory at [mem 0x96749000-0x96749027]
<6>[    0.014546] ACPI: Reserving SSDT table memory at [mem 0x96746000-0x9674881a]
<6>[    0.014547] ACPI: Reserving DBGP table memory at [mem 0x96745000-0x96745033]
<6>[    0.014549] ACPI: Reserving DBG2 table memory at [mem 0x96744000-0x96744053]
<6>[    0.014550] ACPI: Reserving BATB table memory at [mem 0x96743000-0x96743049]
<6>[    0.014552] ACPI: Reserving DMAR table memory at [mem 0x94f3c000-0x94f3c0a7]
<6>[    0.014553] ACPI: Reserving BGRT table memory at [mem 0x94f3b000-0x94f3b037]
<6>[    0.014554] ACPI: Reserving UEFI table memory at [mem 0x99839000-0x99839129]
<6>[    0.014556] ACPI: Reserving FPDT table memory at [mem 0x94f3a000-0x94f3a043]
<6>[    0.014620] Zone ranges:
<6>[    0.014622]   DMA      [mem 0x0000000000001000-0x0000000000ffffff]
<6>[    0.014625]   DMA32    [mem 0x0000000001000000-0x00000000ffffffff]
<6>[    0.014628]   Normal   [mem 0x0000000100000000-0x000000085e7fffff]
<6>[    0.014630] Movable zone start for each node
<6>[    0.014631] Early memory node ranges
<6>[    0.014632]   node   0: [mem 0x0000000000001000-0x000000000009efff]
<6>[    0.014635]   node   0: [mem 0x0000000000100000-0x00000000944b6fff]
<6>[    0.014637]   node   0: [mem 0x0000000099b4f000-0x0000000099b4ffff]
<6>[    0.014639]   node   0: [mem 0x0000000100000000-0x0000000187ffffff]
<6>[    0.014641]   node   0: [mem 0x000000018a000000-0x000000085e7fffff]
<6>[    0.014646] Initmem setup node 0 [mem 0x0000000000001000-0x000000085e7fffff]
<6>[    0.014651] On node 0, zone DMA: 1 pages in unavailable ranges
<6>[    0.014685] On node 0, zone DMA: 97 pages in unavailable ranges
<6>[    0.020051] On node 0, zone DMA32: 22168 pages in unavailable ranges
<6>[    0.025101] On node 0, zone Normal: 25776 pages in unavailable ranges
<6>[    0.082996] On node 0, zone Normal: 8192 pages in unavailable ranges
<6>[    0.083079] On node 0, zone Normal: 6144 pages in unavailable ranges
<6>[    0.083097] Reserving Intel graphics memory at [mem 0x9b800000-0x9f7fffff]
<6>[    0.083373] ACPI: PM-Timer IO Port: 0x1808
<6>[    0.083383] ACPI: LAPIC_NMI (acpi_id[0x01] high edge lint[0x1])
<6>[    0.083386] ACPI: LAPIC_NMI (acpi_id[0x02] high edge lint[0x1])
<6>[    0.083387] ACPI: LAPIC_NMI (acpi_id[0x03] high edge lint[0x1])
<6>[    0.083389] ACPI: LAPIC_NMI (acpi_id[0x04] high edge lint[0x1])
<6>[    0.083390] ACPI: LAPIC_NMI (acpi_id[0x05] high edge lint[0x1])
<6>[    0.083391] ACPI: LAPIC_NMI (acpi_id[0x06] high edge lint[0x1])
<6>[    0.083392] ACPI: LAPIC_NMI (acpi_id[0x07] high edge lint[0x1])
<6>[    0.083393] ACPI: LAPIC_NMI (acpi_id[0x08] high edge lint[0x1])
<6>[    0.083395] ACPI: LAPIC_NMI (acpi_id[0x09] high edge lint[0x1])
<6>[    0.083396] ACPI: LAPIC_NMI (acpi_id[0x0a] high edge lint[0x1])
<6>[    0.083397] ACPI: LAPIC_NMI (acpi_id[0x0b] high edge lint[0x1])
<6>[    0.083398] ACPI: LAPIC_NMI (acpi_id[0x0c] high edge lint[0x1])
<6>[    0.083400] ACPI: LAPIC_NMI (acpi_id[0x0d] high edge lint[0x1])
<6>[    0.083401] ACPI: LAPIC_NMI (acpi_id[0x0e] high edge lint[0x1])
<6>[    0.083402] ACPI: LAPIC_NMI (acpi_id[0x0f] high edge lint[0x1])
<6>[    0.083403] ACPI: LAPIC_NMI (acpi_id[0x10] high edge lint[0x1])
<6>[    0.083405] ACPI: LAPIC_NMI (acpi_id[0x11] high edge lint[0x1])
<6>[    0.083406] ACPI: LAPIC_NMI (acpi_id[0x12] high edge lint[0x1])
<6>[    0.083407] ACPI: LAPIC_NMI (acpi_id[0x13] high edge lint[0x1])
<6>[    0.083409] ACPI: LAPIC_NMI (acpi_id[0x14] high edge lint[0x1])
<6>[    0.083450] IOAPIC[0]: apic_id 2, version 32, address 0xfec00000, GSI 0-119
<6>[    0.083455] ACPI: INT_SRC_OVR (bus 0 bus_irq 0 global_irq 2 dfl dfl)
<6>[    0.083458] ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 9 high level)
<6>[    0.083465] ACPI: Using ACPI (MADT) for SMP configuration information
<6>[    0.083466] ACPI: HPET id: 0x8086a201 base: 0xfed00000
<6>[    0.083472] TSC deadline timer available
<6>[    0.083473] smpboot: Allowing 8 CPUs, 0 hotplug CPUs
<6>[    0.083486] [mem 0x9f800000-0xffffffff] available for PCI devices
<6>[    0.083488] Booting paravirtualized kernel on bare hardware
<6>[    0.083491] clocksource: refined-jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 1910969940391419 ns
<6>[    0.096308] setup_percpu: NR_CPUS:32 nr_cpumask_bits:8 nr_cpu_ids:8 nr_node_ids:1
<6>[    0.096784] percpu: Embedded 56 pages/cpu s191336 r8192 d29848 u262144
<7>[    0.096792] pcpu-alloc: s191336 r8192 d29848 u262144 alloc=1*2097152
<7>[    0.096796] pcpu-alloc: [0] 0 1 2 3 4 5 6 7 
<5>[    0.096819] Kernel command line: memmap=0x2000000$0x188000000 ramoops.mem_address=0x188000000 ramoops.mem_size=0x2000000 ramoops.ecc=1 ramoops.record_size=0x200000 ramoops.console_size=0 ramoops.ftrace_size=0 ramoops.pmsg_size=0 mem_sleep_default=deep mitigations=auto nosmt, g_mass_storage.idVendor=0x22e0 g_mass_storage.idProduct=0x0300 g_mass_storage.iManufacturer=Secunet g_mass_storage.iProduct="SINA Virtual USB Stick" g_mass_storage.removable=1 BOOT_IMAGE=/isolinux/bzImage loglevel=1 sina_toram console=tty1 intel_iommu=on,igfx_off
<6>[    0.096998] DMAR: IOMMU enabled
<6>[    0.096999] DMAR: Disable GFX device mapping
<5>[    0.097002] Unknown kernel command line parameters "nosmt, sina_toram BOOT_IMAGE=/isolinux/bzImage", will be passed to user space.
<5>[    0.097066] random: crng init done
<6>[    0.101119] Dentry cache hash table entries: 4194304 (order: 13, 33554432 bytes, linear)
<6>[    0.103140] Inode-cache hash table entries: 2097152 (order: 12, 16777216 bytes, linear)
<6>[    0.103295] Built 1 zonelists, mobility grouping on.  Total pages: 8195845
<6>[    0.103298] mem auto-init: stack:all(zero), heap alloc:off, heap free:off
<6>[    0.103307] software IO TLB: area num 8.
<6>[    0.215335] Memory: 32567712K/33304920K available (20480K kernel code, 9365K rwdata, 8776K rodata, 3616K init, 3228K bss, 736948K reserved, 0K cma-reserved)
<6>[    0.215407] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=8, Nodes=1
<6>[    0.215435] ftrace: allocating 61258 entries in 240 pages
<6>[    0.237086] ftrace: allocated 240 pages with 4 groups
<6>[    0.238874] Dynamic Preempt: voluntary
<6>[    0.238928] rcu: Preemptible hierarchical RCU implementation.
<6>[    0.238929] rcu: 	RCU event tracing is enabled.
<6>[    0.238930] rcu: 	RCU restricting CPUs from NR_CPUS=32 to nr_cpu_ids=8.
<6>[    0.238932] 	Trampoline variant of Tasks RCU enabled.
<6>[    0.238933] 	Rude variant of Tasks RCU enabled.
<6>[    0.238934] 	Tracing variant of Tasks RCU enabled.
<6>[    0.238935] rcu: RCU calculated value of scheduler-enlistment delay is 100 jiffies.
<6>[    0.238937] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=8
<6>[    0.245255] NR_IRQS: 4352, nr_irqs: 2048, preallocated irqs: 16
<6>[    0.245579] rcu: srcu_init: Setting srcu_struct sizes based on contention.
<6>[    0.245877] Console: colour dummy device 80x25
<6>[    0.245881] printk: legacy console [tty1] enabled
<6>[    0.245935] ACPI: Core revision 20230628
<6>[    0.246465] hpet: HPET dysfunctional in PC10. Force disabled.
<6>[    0.246467] APIC: Switch to symmetric I/O mode setup
<6>[    0.248434] x2apic: IRQ remapping doesn't support X2APIC mode
<6>[    0.254425] clocksource: tsc-early: mask: 0xffffffffffffffff max_cycles: 0x212717146a7, max_idle_ns: 440795291431 ns
<6>[    0.254436] Calibrating delay loop (skipped), value calculated using timer frequency.. 4599.93 BogoMIPS (lpj=2299968)
<6>[    0.254481] CPU0: Thermal monitoring enabled (TM1)
<6>[    0.254560] process: using mwait in idle threads
<6>[    0.254567] Last level iTLB entries: 4KB 64, 2MB 8, 4MB 8
<6>[    0.254570] Last level dTLB entries: 4KB 64, 2MB 0, 4MB 0, 1GB 4
<6>[    0.254575] Spectre V1 : Mitigation: usercopy/swapgs barriers and __user pointer sanitization
<6>[    0.254583] Spectre V2 : Mitigation: Enhanced / Automatic IBRS
<6>[    0.254584] Spectre V2 : Spectre v2 / SpectreRSB mitigation: Filling RSB on context switch
<6>[    0.254586] Spectre V2 : Spectre v2 / PBRSB-eIBRS: Retire a single CALL on VMEXIT
<6>[    0.254587] RETBleed: Mitigation: Enhanced IBRS
<6>[    0.254592] Spectre V2 : mitigation: Enabling conditional Indirect Branch Prediction Barrier
<6>[    0.254598] Speculative Store Bypass: Mitigation: Speculative Store Bypass disabled via prctl
<6>[    0.254609] MMIO Stale Data: Mitigation: Clear CPU buffers
<6>[    0.254612] SRBDS: Mitigation: Microcode
<6>[    0.254616] GDS: Mitigation: Microcode
<6>[    0.254623] x86/fpu: Supporting XSAVE feature 0x001: 'x87 floating point registers'
<6>[    0.254626] x86/fpu: Supporting XSAVE feature 0x002: 'SSE registers'
<6>[    0.254627] x86/fpu: Supporting XSAVE feature 0x004: 'AVX registers'
<6>[    0.254629] x86/fpu: Supporting XSAVE feature 0x008: 'MPX bounds registers'
<6>[    0.254630] x86/fpu: Supporting XSAVE feature 0x010: 'MPX CSR'
<6>[    0.254632] x86/fpu: xstate_offset[2]:  576, xstate_sizes[2]:  256
<6>[    0.254635] x86/fpu: xstate_offset[3]:  832, xstate_sizes[3]:   64
<6>[    0.254637] x86/fpu: xstate_offset[4]:  896, xstate_sizes[4]:   64
<6>[    0.254639] x86/fpu: Enabled xstate features 0x1f, context size is 960 bytes, using 'compacted' format.
<6>[    0.255431] Freeing SMP alternatives memory: 48K
<6>[    0.255431] pid_max: default: 32768 minimum: 301
<6>[    0.255431] LSM: initializing lsm=capability,sina
<6>[    0.255431] Mount-cache hash table entries: 65536 (order: 7, 524288 bytes, linear)
<6>[    0.255431] Mountpoint-cache hash table entries: 65536 (order: 7, 524288 bytes, linear)
<6>[    0.255431] smpboot: CPU0: Intel(R) Core(TM) i7-10510U CPU @ 1.80GHz (family: 0x6, model: 0x8e, stepping: 0xc)
<6>[    0.255431] RCU Tasks: Setting shift to 3 and lim to 1 rcu_task_cb_adjust=1.
<6>[    0.255431] RCU Tasks Rude: Setting shift to 3 and lim to 1 rcu_task_cb_adjust=1.
<6>[    0.255431] RCU Tasks Trace: Setting shift to 3 and lim to 1 rcu_task_cb_adjust=1.
<6>[    0.255431] Performance Events: PEBS fmt3+, Skylake events, 32-deep LBR, full-width counters, Intel PMU driver.
<6>[    0.255431] ... version:                4
<6>[    0.255431] ... bit width:              48
<6>[    0.255431] ... generic registers:      4
<6>[    0.255431] ... value mask:             0000ffffffffffff
<6>[    0.255431] ... max period:             00007fffffffffff
<6>[    0.255431] ... fixed-purpose events:   3
<6>[    0.255431] ... event mask:             000000070000000f
<6>[    0.255431] signal: max sigframe size: 1616
<6>[    0.255431] Estimated ratio of average max frequency by base frequency (times 1024): 1914
<6>[    0.257614] rcu: Hierarchical SRCU implementation.
<6>[    0.257616] rcu: 	Max phase no-delay instances is 400.
<6>[    0.258532] NMI watchdog: Enabled. Permanently consumes one hw-PMU counter.
<6>[    0.258619] smp: Bringing up secondary CPUs ...
<6>[    0.258718] smpboot: x86: Booting SMP configuration:
<6>[    0.258719] .... node  #0, CPUs:      #1 #2 #3 #4 #5 #6 #7
<4>[    0.263878] MMIO Stale Data CPU bug present and SMT on, data leak possible. See https://www.kernel.org/doc/html/latest/admin-guide/hw-vuln/processor_mmio_stale_data.html for more details.
<6>[    0.264467] smp: Brought up 1 node, 8 CPUs
<6>[    0.264467] smpboot: Max logical packages: 1
<6>[    0.264467] smpboot: Total of 8 processors activated (36799.48 BogoMIPS)
<6>[    0.266581] devtmpfs: initialized
<6>[    0.267479] ACPI: PM: Registering ACPI NVS region [mem 0x98695000-0x99a1efff] (20488192 bytes)
<6>[    0.267821] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 1911260446275000 ns
<6>[    0.267828] futex hash table entries: 2048 (order: 5, 131072 bytes, linear)
<6>[    0.267890] pinctrl core: initialized pinctrl subsystem
<6>[    0.268162] PM: RTC time: 13:18:48, date: 2024-02-16
<6>[    0.268855] NET: Registered PF_NETLINK/PF_ROUTE protocol family
<6>[    0.269131] ramoops: using module parameters
<6>[    0.270657] pstore: Using crash dump compression: deflate
<6>[    0.270659] pstore: Registered ramoops as persistent store backend
<6>[    0.270661] ramoops: using 0x2000000@0x188000000, ecc: 16
<6>[    0.270770] thermal_sys: Registered thermal governor 'step_wise'
<6>[    0.270773] thermal_sys: Registered thermal governor 'user_space'
<6>[    0.270790] cpuidle: using governor menu
<6>[    0.270890] Simple Boot Flag at 0x47 set to 0x1
<6>[    0.270890] ACPI FADT declares the system doesn't support PCIe ASPM, so disable it
<6>[    0.270890] acpiphp: ACPI Hot Plug PCI Controller Driver version: 0.5
<6>[    0.271454] PCI: ECAM [mem 0xf0000000-0xf7ffffff] (base 0xf0000000) for domain 0000 [bus 00-7f]
<6>[    0.271464] PCI: not using ECAM ([mem 0xf0000000-0xf7ffffff] not reserved)
<6>[    0.271467] PCI: Using configuration type 1 for base access
<6>[    0.271587] kprobes: kprobe jump-optimization is enabled. All kprobes are optimized if possible.
<6>[    0.271600] HugeTLB: registered 2.00 MiB page size, pre-allocated 0 pages
<6>[    0.271600] HugeTLB: 28 KiB vmemmap can be freed for a 2.00 MiB page
<6>[    0.271600] ACPI: Added _OSI(Module Device)
<6>[    0.271600] ACPI: Added _OSI(Processor Device)
<6>[    0.271600] ACPI: Added _OSI(3.0 _SCP Extensions)
<6>[    0.271600] ACPI: Added _OSI(Processor Aggregator Device)
<6>[    0.357393] ACPI: 11 ACPI AML tables successfully acquired and loaded
<6>[    0.359151] ACPI: EC: EC started
<6>[    0.359153] ACPI: EC: interrupt blocked
<6>[    0.360408] ACPI: EC: EC_CMD/EC_SC=0x66, EC_DATA=0x62
<6>[    0.360412] ACPI: EC: Boot ECDT EC used to handle transactions
<5>[    0.363067] ACPI: [Firmware Bug]: BIOS _OSI(Linux) query ignored
<6>[    0.427182] ACPI: Dynamic OEM Table Load:
<6>[    0.427201] ACPI: SSDT 0xFFFF986080C18000 000400 (v02 PmRef  Cpu0Cst  00003001 INTL 20160527)
<6>[    0.428864] ACPI: Dynamic OEM Table Load:
<6>[    0.428879] ACPI: SSDT 0xFFFF986080C11000 00061E (v02 PmRef  Cpu0Ist  00003000 INTL 20160527)
<6>[    0.431574] ACPI: Dynamic OEM Table Load:
<6>[    0.431586] ACPI: SSDT 0xFFFF986080C38000 0000FC (v02 PmRef  Cpu0Psd  00003000 INTL 20160527)
<6>[    0.433160] ACPI: Dynamic OEM Table Load:
<6>[    0.433172] ACPI: SSDT 0xFFFF986081DB4000 00016C (v02 PmRef  Cpu0Hwp  00003000 INTL 20160527)
<6>[    0.434721] ACPI: Dynamic OEM Table Load:
<6>[    0.434737] ACPI: SSDT 0xFFFF986080C20000 000BEA (v02 PmRef  HwpLvt   00003000 INTL 20160527)
<6>[    0.436580] ACPI: Dynamic OEM Table Load:
<6>[    0.436596] ACPI: SSDT 0xFFFF986080C12800 000778 (v02 PmRef  ApIst    00003000 INTL 20160527)
<6>[    0.438370] ACPI: Dynamic OEM Table Load:
<6>[    0.438382] ACPI: SSDT 0xFFFF986080C18400 0003D7 (v02 PmRef  ApHwp    00003000 INTL 20160527)
<6>[    0.440151] ACPI: Dynamic OEM Table Load:
<6>[    0.440166] ACPI: SSDT 0xFFFF986080C21000 000D22 (v02 PmRef  ApPsd    00003000 INTL 20160527)
<6>[    0.442580] ACPI: Dynamic OEM Table Load:
<6>[    0.442592] ACPI: SSDT 0xFFFF986080C18800 0003CA (v02 PmRef  ApCst    00003000 INTL 20160527)
<6>[    0.447067] ACPI: _OSC evaluated successfully for all CPUs
<6>[    0.447070] ACPI: Interpreter enabled
<6>[    0.447123] ACPI: PM: (supports S0 S3 S5)
<6>[    0.447125] ACPI: Using IOAPIC for interrupt routing
<6>[    0.447178] PCI: ECAM [mem 0xf0000000-0xf7ffffff] (base 0xf0000000) for domain 0000 [bus 00-7f]
<6>[    0.448413] PCI: ECAM [mem 0xf0000000-0xf7ffffff] reserved as ACPI motherboard resource
<6>[    0.448429] PCI: Using host bridge windows from ACPI; if necessary, use "pci=nocrs" and report a bug
<6>[    0.448431] PCI: Using E820 reservations for host bridge windows
<6>[    0.448962] ACPI: Enabled 7 GPEs in block 00 to 7F
<6>[    0.453831] ACPI: \_SB_.PCI0.LPCB.EC__.PUBS: New power resource
<6>[    0.457894] ACPI: \_SB_.PCI0.XHC_.RHUB.HS10.BTPR: New power resource
<6>[    0.459577] ACPI: \_SB_.PCI0.XDCI.USBC: New power resource
<6>[    0.461770] ACPI: \_SB_.PCI0.RP05.PXP_: New power resource
<6>[    0.465277] ACPI: \_SB_.PCI0.RP07.PXP_: New power resource
<6>[    0.472558] ACPI: \_SB_.PCI0.SAT0.VOL0.V0PR: New power resource
<6>[    0.472773] ACPI: \_SB_.PCI0.SAT0.VOL1.V1PR: New power resource
<6>[    0.472974] ACPI: \_SB_.PCI0.SAT0.VOL2.V2PR: New power resource
<6>[    0.474713] ACPI: \_SB_.PCI0.CNVW.WRST: New power resource
<6>[    0.479449] ACPI: \PIN_: New power resource
<6>[    0.479485] ACPI: \PINP: New power resource
<6>[    0.480079] ACPI: PCI Root Bridge [PCI0] (domain 0000 [bus 00-7e])
<6>[    0.480089] acpi PNP0A08:00: _OSC: OS supports [ExtendedConfig ASPM ClockPM Segments MSI HPX-Type3]
<6>[    0.482724] acpi PNP0A08:00: _OSC: OS now controls [PCIeHotplug SHPCHotplug PME PCIeCapability LTR]
<6>[    0.482728] acpi PNP0A08:00: FADT indicates ASPM is unsupported, using BIOS configuration
<6>[    0.484807] PCI host bridge to bus 0000:00
<6>[    0.484810] pci_bus 0000:00: root bus resource [io  0x0000-0x0cf7 window]
<6>[    0.484814] pci_bus 0000:00: root bus resource [io  0x0d00-0xffff window]
<6>[    0.484817] pci_bus 0000:00: root bus resource [mem 0x000a0000-0x000bffff window]
<6>[    0.484819] pci_bus 0000:00: root bus resource [mem 0x9f800000-0xefffffff window]
<6>[    0.484821] pci_bus 0000:00: root bus resource [mem 0xfc800000-0xfe7fffff window]
<6>[    0.484824] pci_bus 0000:00: root bus resource [bus 00-7e]
<6>[    0.484859] pci 0000:00:00.0: [8086:9b61] type 00 class 0x060000 conventional PCI endpoint
<6>[    0.484990] pci 0000:00:02.0: [8086:9b41] type 00 class 0x030000 PCIe Root Complex Integrated Endpoint
<6>[    0.485005] pci 0000:00:02.0: BAR 0 [mem 0xe9000000-0xe9ffffff 64bit]
<6>[    0.485015] pci 0000:00:02.0: BAR 2 [mem 0xa0000000-0xbfffffff 64bit pref]
<6>[    0.485022] pci 0000:00:02.0: BAR 4 [io  0x4000-0x403f]
<6>[    0.485046] pci 0000:00:02.0: BAR 2: assigned to efifb
<6>[    0.485051] pci 0000:00:02.0: Video device with shadowed ROM at [mem 0x000c0000-0x000dffff]
<6>[    0.485281] pci 0000:00:04.0: [8086:1903] type 00 class 0x118000 conventional PCI endpoint
<6>[    0.485296] pci 0000:00:04.0: BAR 0 [mem 0xeb730000-0xeb737fff 64bit]
<6>[    0.485693] pci 0000:00:08.0: [8086:1911] type 00 class 0x088000 conventional PCI endpoint
<6>[    0.485710] pci 0000:00:08.0: BAR 0 [mem 0xeb742000-0xeb742fff 64bit]
<6>[    0.485848] pci 0000:00:12.0: [8086:02f9] type 00 class 0x118000 conventional PCI endpoint
<6>[    0.485870] pci 0000:00:12.0: BAR 0 [mem 0xeb743000-0xeb743fff 64bit]
<6>[    0.486040] pci 0000:00:14.0: [8086:02ed] type 00 class 0x0c0330 conventional PCI endpoint
<6>[    0.486061] pci 0000:00:14.0: BAR 0 [mem 0xeb720000-0xeb72ffff 64bit]
<6>[    0.486140] pci 0000:00:14.0: PME# supported from D3hot D3cold
<6>[    0.486641] pci 0000:00:14.2: [8086:02ef] type 00 class 0x050000 conventional PCI endpoint
<6>[    0.486664] pci 0000:00:14.2: BAR 0 [mem 0xeb740000-0xeb741fff 64bit]
<6>[    0.486678] pci 0000:00:14.2: BAR 2 [mem 0xeb744000-0xeb744fff 64bit]
<6>[    0.486833] pci 0000:00:14.3: [8086:02f0] type 00 class 0x028000 PCIe Root Complex Integrated Endpoint
<6>[    0.486869] pci 0000:00:14.3: BAR 0 [mem 0xeb738000-0xeb73bfff 64bit]
<6>[    0.487006] pci 0000:00:14.3: PME# supported from D0 D3hot D3cold
<6>[    0.487272] pci 0000:00:16.0: [8086:02e0] type 00 class 0x078000 conventional PCI endpoint
<6>[    0.487297] pci 0000:00:16.0: BAR 0 [mem 0xeb745000-0xeb745fff 64bit]
<6>[    0.487387] pci 0000:00:16.0: PME# supported from D3hot
<6>[    0.487823] pci 0000:00:1c.0: [8086:02b8] type 01 class 0x060400 PCIe Root Port
<6>[    0.487852] pci 0000:00:1c.0: PCI bridge to [bus 02]
<6>[    0.487859] pci 0000:00:1c.0:   bridge window [mem 0xeb600000-0xeb6fffff]
<6>[    0.487940] pci 0000:00:1c.0: PME# supported from D0 D3hot D3cold
<6>[    0.488629] pci 0000:00:1c.4: [8086:02bc] type 01 class 0x060400 PCIe Root Port
<6>[    0.488658] pci 0000:00:1c.4: PCI bridge to [bus 03-2b]
<6>[    0.488665] pci 0000:00:1c.4:   bridge window [mem 0xdc000000-0xe81fffff]
<6>[    0.488675] pci 0000:00:1c.4:   bridge window [mem 0xc0000000-0xdbffffff 64bit pref]
<6>[    0.488750] pci 0000:00:1c.4: PME# supported from D0 D3hot D3cold
<6>[    0.489428] pci 0000:00:1d.0: [8086:02b0] type 01 class 0x060400 PCIe Root Port
<6>[    0.489459] pci 0000:00:1d.0: PCI bridge to [bus 2d]
<6>[    0.489465] pci 0000:00:1d.0:   bridge window [io  0x3000-0x3fff]
<6>[    0.489469] pci 0000:00:1d.0:   bridge window [mem 0xeac00000-0xeb5fffff]
<6>[    0.489480] pci 0000:00:1d.0:   bridge window [mem 0xea000000-0xea9fffff 64bit pref]
<6>[    0.489556] pci 0000:00:1d.0: PME# supported from D0 D3hot D3cold
<6>[    0.490199] pci 0000:00:1d.4: [8086:02b4] type 01 class 0x060400 PCIe Root Port
<6>[    0.490230] pci 0000:00:1d.4: PCI bridge to [bus 2e]
<6>[    0.490237] pci 0000:00:1d.4:   bridge window [mem 0xeab00000-0xeabfffff]
<6>[    0.490322] pci 0000:00:1d.4: PME# supported from D0 D3hot D3cold
<6>[    0.491016] pci 0000:00:1f.0: [8086:0284] type 00 class 0x060100 conventional PCI endpoint
<6>[    0.491659] pci 0000:00:1f.3: [8086:02c8] type 00 class 0x040380 conventional PCI endpoint
<6>[    0.491712] pci 0000:00:1f.3: BAR 0 [mem 0xeb73c000-0xeb73ffff 64bit]
<6>[    0.491777] pci 0000:00:1f.3: BAR 4 [mem 0xeaa00000-0xeaafffff 64bit]
<6>[    0.491908] pci 0000:00:1f.3: PME# supported from D3hot D3cold
<6>[    0.492405] pci 0000:00:1f.4: [8086:02a3] type 00 class 0x0c0500 conventional PCI endpoint
<6>[    0.492440] pci 0000:00:1f.4: BAR 0 [mem 0xeb746000-0xeb7460ff 64bit]
<6>[    0.492474] pci 0000:00:1f.4: BAR 4 [io  0xefa0-0xefbf]
<6>[    0.492841] pci 0000:00:1f.5: [8086:02a4] type 00 class 0x0c8000 conventional PCI endpoint
<6>[    0.492861] pci 0000:00:1f.5: BAR 0 [mem 0xfe010000-0xfe010fff]
<6>[    0.493022] pci 0000:00:1f.6: [8086:0d4f] type 00 class 0x020000 conventional PCI endpoint
<6>[    0.493067] pci 0000:00:1f.6: BAR 0 [mem 0xeb700000-0xeb71ffff]
<6>[    0.493303] pci 0000:00:1f.6: PME# supported from D0 D3hot D3cold
<6>[    0.493499] pci 0000:02:00.0: [10ec:522a] type 00 class 0xff0000 PCIe Endpoint
<6>[    0.493525] pci 0000:02:00.0: BAR 0 [mem 0xeb600000-0xeb600fff]
<6>[    0.493695] pci 0000:02:00.0: supports D1 D2
<6>[    0.493697] pci 0000:02:00.0: PME# supported from D1 D2 D3hot D3cold
<6>[    0.493960] pci 0000:00:1c.0: PCI bridge to [bus 02]
<6>[    0.494052] pci 0000:03:00.0: [8086:15c0] type 01 class 0x060400 PCIe Switch Upstream Port
<6>[    0.494092] pci 0000:03:00.0: PCI bridge to [bus 04-2b]
<6>[    0.494104] pci 0000:03:00.0:   bridge window [mem 0xdc000000-0xe81fffff]
<6>[    0.494119] pci 0000:03:00.0:   bridge window [mem 0xc0000000-0xdbffffff 64bit pref]
<6>[    0.494135] pci 0000:03:00.0: enabling Extended Tags
<6>[    0.494241] pci 0000:03:00.0: supports D1 D2
<6>[    0.494243] pci 0000:03:00.0: PME# supported from D0 D1 D2 D3hot D3cold
<6>[    0.494439] pci 0000:00:1c.4: PCI bridge to [bus 03-2b]
<6>[    0.494536] pci 0000:04:00.0: [8086:15c0] type 01 class 0x060400 PCIe Switch Downstream Port
<6>[    0.494578] pci 0000:04:00.0: PCI bridge to [bus 05]
<6>[    0.494589] pci 0000:04:00.0:   bridge window [mem 0xe8100000-0xe81fffff]
<6>[    0.494621] pci 0000:04:00.0: enabling Extended Tags
<6>[    0.494724] pci 0000:04:00.0: supports D1 D2
<6>[    0.494726] pci 0000:04:00.0: PME# supported from D0 D1 D2 D3hot D3cold
<6>[    0.494883] pci 0000:04:01.0: [8086:15c0] type 01 class 0x060400 PCIe Switch Downstream Port
<6>[    0.494924] pci 0000:04:01.0: PCI bridge to [bus 06-2a]
<6>[    0.494936] pci 0000:04:01.0:   bridge window [mem 0xdc100000-0xe80fffff]
<6>[    0.494950] pci 0000:04:01.0:   bridge window [mem 0xc0000000-0xdbffffff 64bit pref]
<6>[    0.494970] pci 0000:04:01.0: enabling Extended Tags
<6>[    0.495080] pci 0000:04:01.0: supports D1 D2
<6>[    0.495081] pci 0000:04:01.0: PME# supported from D0 D1 D2 D3hot D3cold
<6>[    0.495236] pci 0000:04:02.0: [8086:15c0] type 01 class 0x060400 PCIe Switch Downstream Port
<6>[    0.495277] pci 0000:04:02.0: PCI bridge to [bus 2b]
<6>[    0.495289] pci 0000:04:02.0:   bridge window [mem 0xdc000000-0xdc0fffff]
<6>[    0.495320] pci 0000:04:02.0: enabling Extended Tags
<6>[    0.495421] pci 0000:04:02.0: supports D1 D2
<6>[    0.495423] pci 0000:04:02.0: PME# supported from D0 D1 D2 D3hot D3cold
<6>[    0.495617] pci 0000:03:00.0: PCI bridge to [bus 04-2b]
<6>[    0.495713] pci 0000:05:00.0: [8086:15bf] type 00 class 0x088000 PCIe Endpoint
<6>[    0.495735] pci 0000:05:00.0: BAR 0 [mem 0xe8100000-0xe813ffff]
<6>[    0.495745] pci 0000:05:00.0: BAR 1 [mem 0xe8140000-0xe8140fff]
<6>[    0.495799] pci 0000:05:00.0: enabling Extended Tags
<6>[    0.495920] pci 0000:05:00.0: supports D1 D2
<6>[    0.495922] pci 0000:05:00.0: PME# supported from D0 D1 D2 D3hot D3cold
<6>[    0.496105] pci 0000:04:00.0: PCI bridge to [bus 05]
<6>[    0.496172] pci 0000:04:01.0: PCI bridge to [bus 06-2a]
<6>[    0.496280] pci 0000:2b:00.0: [8086:15c1] type 00 class 0x0c0330 PCIe Endpoint
<6>[    0.496306] pci 0000:2b:00.0: BAR 0 [mem 0xdc000000-0xdc00ffff]
<6>[    0.496394] pci 0000:2b:00.0: enabling Extended Tags
<6>[    0.496523] pci 0000:2b:00.0: supports D1 D2
<6>[    0.496525] pci 0000:2b:00.0: PME# supported from D0 D1 D2 D3hot D3cold
<6>[    0.496593] pci 0000:2b:00.0: 8.000 Gb/s available PCIe bandwidth, limited by 2.5 GT/s PCIe x4 link at 0000:04:02.0 (capable of 31.504 Gb/s with 8.0 GT/s PCIe x4 link)
<6>[    0.496764] pci 0000:04:02.0: PCI bridge to [bus 2b]
<6>[    0.496871] pci 0000:00:1d.0: PCI bridge to [bus 2d]
<6>[    0.496955] pci 0000:2e:00.0: [15b7:5006] type 00 class 0x010802 PCIe Endpoint
<6>[    0.496981] pci 0000:2e:00.0: BAR 0 [mem 0xeab00000-0xeab03fff 64bit]
<6>[    0.497016] pci 0000:2e:00.0: BAR 4 [mem 0xeab04000-0xeab040ff 64bit]
<6>[    0.497289] pci 0000:00:1d.4: PCI bridge to [bus 2e]
<7>[    0.497322] pci_bus 0000:00: on NUMA node 0
<6>[    0.500539] ACPI: EC: interrupt unblocked
<6>[    0.500541] ACPI: EC: event unblocked
<6>[    0.500553] ACPI: EC: EC_CMD/EC_SC=0x66, EC_DATA=0x62
<6>[    0.500555] ACPI: EC: GPE=0x16
<6>[    0.500557] ACPI: \_SB_.PCI0.LPCB.EC__: Boot ECDT EC initialization complete
<6>[    0.500561] ACPI: \_SB_.PCI0.LPCB.EC__: EC: Used to handle transactions and events
<6>[    0.500656] iommu: Default domain type: Translated
<6>[    0.500658] iommu: DMA domain TLB invalidation policy: lazy mode
<5>[    0.500754] SCSI subsystem initialized
<7>[    0.500764] libata version 3.00 loaded.
<6>[    0.500764] ACPI: bus type USB registered
<6>[    0.500764] usbcore: registered new interface driver usbfs
<6>[    0.500764] usbcore: registered new interface driver hub
<6>[    0.500764] usbcore: registered new device driver usb
<6>[    0.500764] pps_core: LinuxPPS API ver. 1 registered
<6>[    0.500764] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
<6>[    0.500764] PTP clock support registered
<6>[    0.500764] Advanced Linux Sound Architecture Driver Initialized.
<6>[    0.500884] NetLabel: Initializing
<6>[    0.500886] NetLabel:  domain hash size = 128
<6>[    0.500888] NetLabel:  protocols = UNLABELED CIPSOv4 CALIPSO
<6>[    0.500911] NetLabel:  unlabeled traffic allowed by default
<6>[    0.501459] PCI: Using ACPI for IRQ routing
<7>[    0.517540] PCI: pci_cache_line_size set to 64 bytes
<7>[    0.517682] e820: reserve RAM buffer [mem 0x0009f000-0x0009ffff]
<7>[    0.517685] e820: reserve RAM buffer [mem 0x944b7000-0x97ffffff]
<7>[    0.517687] e820: reserve RAM buffer [mem 0x99b50000-0x9bffffff]
<7>[    0.517689] e820: reserve RAM buffer [mem 0x85e800000-0x85fffffff]
<6>[    0.519432] clocksource: Switched to clocksource tsc-early
<6>[    0.519620] pnp: PnP ACPI init
<6>[    0.519908] system 00:00: [io  0x1800-0x18fe] has been reserved
<6>[    0.519913] system 00:00: [mem 0xfd000000-0xfd69ffff] has been reserved
<6>[    0.519916] system 00:00: [mem 0xfd6b0000-0xfd6cffff] has been reserved
<6>[    0.519919] system 00:00: [mem 0xfd6f0000-0xfdffffff] has been reserved
<6>[    0.519921] system 00:00: [mem 0xfe000000-0xfe01ffff] could not be reserved
<6>[    0.519923] system 00:00: [mem 0xfe200000-0xfe7fffff] has been reserved
<6>[    0.519925] system 00:00: [mem 0xff000000-0xffffffff] has been reserved
<6>[    0.520257] system 00:01: [io  0x2000-0x20fe] has been reserved
<6>[    0.520815] system 00:02: [io  0x0680-0x069f] has been reserved
<6>[    0.520818] system 00:02: [io  0x164e-0x164f] has been reserved
<6>[    0.520983] system 00:04: [io  0x1854-0x1857] has been reserved
<6>[    0.521113] system 00:07: [io  0x1800-0x189f] could not be reserved
<6>[    0.521116] system 00:07: [io  0x0800-0x087f] has been reserved
<6>[    0.521119] system 00:07: [io  0x0880-0x08ff] has been reserved
<6>[    0.521121] system 00:07: [io  0x0900-0x097f] has been reserved
<6>[    0.521123] system 00:07: [io  0x0980-0x09ff] has been reserved
<6>[    0.521125] system 00:07: [io  0x0a00-0x0a7f] has been reserved
<6>[    0.521127] system 00:07: [io  0x0a80-0x0aff] has been reserved
<6>[    0.521129] system 00:07: [io  0x0b00-0x0b7f] has been reserved
<6>[    0.521131] system 00:07: [io  0x0b80-0x0bff] has been reserved
<6>[    0.521133] system 00:07: [io  0x15e0-0x15ef] has been reserved
<6>[    0.521135] system 00:07: [io  0x1600-0x167f] could not be reserved
<6>[    0.521137] system 00:07: [io  0x1640-0x165f] could not be reserved
<6>[    0.521140] system 00:07: [mem 0xf0000000-0xf7ffffff] has been reserved
<6>[    0.521142] system 00:07: [mem 0xfed10000-0xfed13fff] has been reserved
<6>[    0.521144] system 00:07: [mem 0xfed18000-0xfed18fff] has been reserved
<6>[    0.521146] system 00:07: [mem 0xfed19000-0xfed19fff] has been reserved
<6>[    0.521148] system 00:07: [mem 0xfeb00000-0xfebfffff] has been reserved
<6>[    0.521151] system 00:07: [mem 0xfed20000-0xfed3ffff] has been reserved
<6>[    0.521153] system 00:07: [mem 0xfed90000-0xfed93fff] has been reserved
<6>[    0.521820] system 00:08: [mem 0xfed10000-0xfed17fff] could not be reserved
<6>[    0.521824] system 00:08: [mem 0xfed18000-0xfed18fff] has been reserved
<6>[    0.521827] system 00:08: [mem 0xfed19000-0xfed19fff] has been reserved
<6>[    0.521829] system 00:08: [mem 0xf0000000-0xf7ffffff] has been reserved
<6>[    0.521831] system 00:08: [mem 0xfed20000-0xfed3ffff] has been reserved
<6>[    0.521834] system 00:08: [mem 0xfed90000-0xfed93fff] has been reserved
<6>[    0.521836] system 00:08: [mem 0xfed45000-0xfed8ffff] has been reserved
<6>[    0.521838] system 00:08: [mem 0xfee00000-0xfeefffff] has been reserved
<6>[    0.522070] system 00:09: [mem 0xfe038000-0xfe038fff] has been reserved
<4>[    0.522373] pnp 00:0a: disabling [mem 0x000c0000-0x000c3fff] because it overlaps 0000:00:02.0 BAR 6 [mem 0x000c0000-0x000dffff]
<4>[    0.522379] pnp 00:0a: disabling [mem 0x000c8000-0x000cbfff] because it overlaps 0000:00:02.0 BAR 6 [mem 0x000c0000-0x000dffff]
<4>[    0.522382] pnp 00:0a: disabling [mem 0x000d0000-0x000d3fff] because it overlaps 0000:00:02.0 BAR 6 [mem 0x000c0000-0x000dffff]
<4>[    0.522385] pnp 00:0a: disabling [mem 0x000d8000-0x000dbfff] because it overlaps 0000:00:02.0 BAR 6 [mem 0x000c0000-0x000dffff]
<6>[    0.522428] system 00:0a: [mem 0x00000000-0x0009ffff] could not be reserved
<6>[    0.522431] system 00:0a: [mem 0x000e0000-0x000e3fff] could not be reserved
<6>[    0.522433] system 00:0a: [mem 0x000e8000-0x000ebfff] could not be reserved
<6>[    0.522436] system 00:0a: [mem 0x000f0000-0x000fffff] could not be reserved
<6>[    0.522438] system 00:0a: [mem 0x00100000-0x9f7fffff] could not be reserved
<6>[    0.522441] system 00:0a: [mem 0xfec00000-0xfed3ffff] could not be reserved
<6>[    0.522443] system 00:0a: [mem 0xfed4c000-0xffffffff] could not be reserved
<6>[    0.522530] pnp: PnP ACPI: found 11 devices
<6>[    0.528739] clocksource: acpi_pm: mask: 0xffffff max_cycles: 0xffffff, max_idle_ns: 2085701024 ns
<6>[    0.528860] NET: Registered PF_INET protocol family
<6>[    0.529078] IP idents hash table entries: 262144 (order: 9, 2097152 bytes, linear)
<6>[    0.533794] tcp_listen_portaddr_hash hash table entries: 16384 (order: 6, 262144 bytes, linear)
<6>[    0.533839] Table-perturb hash table entries: 65536 (order: 6, 262144 bytes, linear)
<6>[    0.533857] TCP established hash table entries: 262144 (order: 9, 2097152 bytes, linear)
<6>[    0.534225] TCP bind hash table entries: 65536 (order: 9, 2097152 bytes, linear)
<6>[    0.534675] TCP: Hash tables configured (established 262144 bind 65536)
<6>[    0.534706] UDP hash table entries: 16384 (order: 7, 524288 bytes, linear)
<6>[    0.534791] UDP-Lite hash table entries: 16384 (order: 7, 524288 bytes, linear)
<6>[    0.534900] NET: Registered PF_UNIX/PF_LOCAL protocol family
<6>[    0.535444] pci 0000:04:01.0: bridge window [io  0x1000-0x0fff] to [bus 06-2a] add_size 1000
<6>[    0.535452] pci 0000:03:00.0: bridge window [io  0x1000-0x0fff] to [bus 04-2b] add_size 1000
<6>[    0.535455] pci 0000:00:1c.4: bridge window [io  0x1000-0x0fff] to [bus 03-2b] add_size 2000
<6>[    0.535465] pci 0000:00:1c.4: bridge window [io  0x5000-0x6fff]: assigned
<6>[    0.535469] pci 0000:00:1c.0: PCI bridge to [bus 02]
<6>[    0.535475] pci 0000:00:1c.0:   bridge window [mem 0xeb600000-0xeb6fffff]
<6>[    0.535484] pci 0000:03:00.0: bridge window [io  0x5000-0x5fff]: assigned
<6>[    0.535487] pci 0000:04:01.0: bridge window [io  0x5000-0x5fff]: assigned
<6>[    0.535490] pci 0000:04:00.0: PCI bridge to [bus 05]
<6>[    0.535496] pci 0000:04:00.0:   bridge window [mem 0xe8100000-0xe81fffff]
<6>[    0.535507] pci 0000:04:01.0: PCI bridge to [bus 06-2a]
<6>[    0.535510] pci 0000:04:01.0:   bridge window [io  0x5000-0x5fff]
<6>[    0.535517] pci 0000:04:01.0:   bridge window [mem 0xdc100000-0xe80fffff]
<6>[    0.535521] pci 0000:04:01.0:   bridge window [mem 0xc0000000-0xdbffffff 64bit pref]
<6>[    0.535529] pci 0000:04:02.0: PCI bridge to [bus 2b]
<6>[    0.535536] pci 0000:04:02.0:   bridge window [mem 0xdc000000-0xdc0fffff]
<6>[    0.535546] pci 0000:03:00.0: PCI bridge to [bus 04-2b]
<6>[    0.535549] pci 0000:03:00.0:   bridge window [io  0x5000-0x5fff]
<6>[    0.535555] pci 0000:03:00.0:   bridge window [mem 0xdc000000-0xe81fffff]
<6>[    0.535560] pci 0000:03:00.0:   bridge window [mem 0xc0000000-0xdbffffff 64bit pref]
<6>[    0.535567] pci 0000:00:1c.4: PCI bridge to [bus 03-2b]
<6>[    0.535570] pci 0000:00:1c.4:   bridge window [io  0x5000-0x6fff]
<6>[    0.535575] pci 0000:00:1c.4:   bridge window [mem 0xdc000000-0xe81fffff]
<6>[    0.535579] pci 0000:00:1c.4:   bridge window [mem 0xc0000000-0xdbffffff 64bit pref]
<6>[    0.535584] pci 0000:00:1d.0: PCI bridge to [bus 2d]
<6>[    0.535606] pci 0000:00:1d.0:   bridge window [io  0x3000-0x3fff]
<6>[    0.535616] pci 0000:00:1d.0:   bridge window [mem 0xeac00000-0xeb5fffff]
<6>[    0.535620] pci 0000:00:1d.0:   bridge window [mem 0xea000000-0xea9fffff 64bit pref]
<6>[    0.535632] pci 0000:00:1d.4: PCI bridge to [bus 2e]
<6>[    0.535637] pci 0000:00:1d.4:   bridge window [mem 0xeab00000-0xeabfffff]
<6>[    0.535645] pci_bus 0000:00: resource 4 [io  0x0000-0x0cf7 window]
<6>[    0.535648] pci_bus 0000:00: resource 5 [io  0x0d00-0xffff window]
<6>[    0.535651] pci_bus 0000:00: resource 6 [mem 0x000a0000-0x000bffff window]
<6>[    0.535653] pci_bus 0000:00: resource 7 [mem 0x9f800000-0xefffffff window]
<6>[    0.535655] pci_bus 0000:00: resource 8 [mem 0xfc800000-0xfe7fffff window]
<6>[    0.535657] pci_bus 0000:02: resource 1 [mem 0xeb600000-0xeb6fffff]
<6>[    0.535660] pci_bus 0000:03: resource 0 [io  0x5000-0x6fff]
<6>[    0.535662] pci_bus 0000:03: resource 1 [mem 0xdc000000-0xe81fffff]
<6>[    0.535663] pci_bus 0000:03: resource 2 [mem 0xc0000000-0xdbffffff 64bit pref]
<6>[    0.535666] pci_bus 0000:04: resource 0 [io  0x5000-0x5fff]
<6>[    0.535668] pci_bus 0000:04: resource 1 [mem 0xdc000000-0xe81fffff]
<6>[    0.535669] pci_bus 0000:04: resource 2 [mem 0xc0000000-0xdbffffff 64bit pref]
<6>[    0.535672] pci_bus 0000:05: resource 1 [mem 0xe8100000-0xe81fffff]
<6>[    0.535674] pci_bus 0000:06: resource 0 [io  0x5000-0x5fff]
<6>[    0.535676] pci_bus 0000:06: resource 1 [mem 0xdc100000-0xe80fffff]
<6>[    0.535678] pci_bus 0000:06: resource 2 [mem 0xc0000000-0xdbffffff 64bit pref]
<6>[    0.535680] pci_bus 0000:2b: resource 1 [mem 0xdc000000-0xdc0fffff]
<6>[    0.535682] pci_bus 0000:2d: resource 0 [io  0x3000-0x3fff]
<6>[    0.535684] pci_bus 0000:2d: resource 1 [mem 0xeac00000-0xeb5fffff]
<6>[    0.535686] pci_bus 0000:2d: resource 2 [mem 0xea000000-0xea9fffff 64bit pref]
<6>[    0.535688] pci_bus 0000:2e: resource 1 [mem 0xeab00000-0xeabfffff]
<6>[    0.536683] PCI: CLS 0 bytes, default 64
<6>[    0.536693] DMAR: Host address width 39
<6>[    0.536695] DMAR: DRHD base: 0x000000fed90000 flags: 0x0
<6>[    0.536708] DMAR: dmar0: reg_base_addr fed90000 ver 1:0 cap 1c0000c40660462 ecap 19e2ff0505e
<6>[    0.536712] DMAR: DRHD base: 0x000000fed91000 flags: 0x1
<6>[    0.536720] DMAR: dmar1: reg_base_addr fed91000 ver 1:0 cap d2008c40660462 ecap f050da
<6>[    0.536723] DMAR: RMRR base: 0x0000009864f000 end: 0x0000009866efff
<6>[    0.536726] DMAR: RMRR base: 0x0000009b000000 end: 0x0000009f7fffff
<6>[    0.536738] DMAR: No ATSR found
<6>[    0.536738] Unpacking initramfs...
<6>[    0.536740] DMAR: No SATC found
<6>[    0.536748] DMAR: dmar1: Using Queued invalidation
<6>[    0.536838] pci 0000:00:00.0: Adding to iommu group 0
<6>[    0.536854] pci 0000:00:04.0: Adding to iommu group 1
<6>[    0.536869] pci 0000:00:08.0: Adding to iommu group 2
<6>[    0.536891] pci 0000:00:12.0: Adding to iommu group 3
<6>[    0.536918] pci 0000:00:14.0: Adding to iommu group 4
<6>[    0.536931] pci 0000:00:14.2: Adding to iommu group 4
<6>[    0.536946] pci 0000:00:14.3: Adding to iommu group 5
<6>[    0.536967] pci 0000:00:16.0: Adding to iommu group 6
<6>[    0.536986] pci 0000:00:1c.0: Adding to iommu group 7
<6>[    0.537009] pci 0000:00:1c.4: Adding to iommu group 8
<6>[    0.537033] pci 0000:00:1d.0: Adding to iommu group 9
<6>[    0.537049] pci 0000:00:1d.4: Adding to iommu group 10
<6>[    0.537097] pci 0000:00:1f.0: Adding to iommu group 11
<6>[    0.537112] pci 0000:00:1f.3: Adding to iommu group 11
<6>[    0.537127] pci 0000:00:1f.4: Adding to iommu group 11
<6>[    0.537143] pci 0000:00:1f.5: Adding to iommu group 11
<6>[    0.537160] pci 0000:00:1f.6: Adding to iommu group 11
<6>[    0.537177] pci 0000:02:00.0: Adding to iommu group 12
<6>[    0.537193] pci 0000:03:00.0: Adding to iommu group 13
<6>[    0.537210] pci 0000:04:00.0: Adding to iommu group 14
<6>[    0.537227] pci 0000:04:01.0: Adding to iommu group 15
<6>[    0.537243] pci 0000:04:02.0: Adding to iommu group 16
<6>[    0.537249] pci 0000:05:00.0: Adding to iommu group 14
<6>[    0.537254] pci 0000:2b:00.0: Adding to iommu group 16
<6>[    0.537270] pci 0000:2e:00.0: Adding to iommu group 17
<6>[    0.538250] DMAR: Intel(R) Virtualization Technology for Directed I/O
<6>[    0.538252] PCI-DMA: Using software bounce buffering for IO (SWIOTLB)
<6>[    0.538254] software IO TLB: mapped [mem 0x000000008d1d8000-0x00000000911d8000] (64MB)
<6>[    0.538264] ACPI: bus type thunderbolt registered
<6>[    0.538393] thunderbolt 0000:05:00.0: enabling device (0000 -> 0002)
<6>[    0.717819] RAPL PMU: API unit is 2^-32 Joules, 5 fixed counters, 655360 ms ovfl timer
<6>[    0.717823] RAPL PMU: hw unit of domain pp0-core 2^-14 Joules
<6>[    0.717825] RAPL PMU: hw unit of domain package 2^-14 Joules
<6>[    0.717826] RAPL PMU: hw unit of domain dram 2^-14 Joules
<6>[    0.717828] RAPL PMU: hw unit of domain pp1-gpu 2^-14 Joules
<6>[    0.717829] RAPL PMU: hw unit of domain psys 2^-14 Joules
<4>[    0.717945] resource: resource sanity check: requesting [mem 0x00000000fed10000-0x00000000fed15fff], which spans more than pnp 00:07 [mem 0xfed10000-0xfed13fff]
<4>[    0.717950] caller snb_uncore_imc_init_box+0x84/0xe0 mapping multiple BARs
<5>[    0.719944] Initialise system trusted keyrings
<6>[    0.720004] workingset: timestamp_bits=62 max_order=23 bucket_order=0
<6>[    0.720080] squashfs: version 4.0 (2009/01/31) Phillip Lougher
<6>[    0.720120] 9p: Installing v9fs 9p2000 file system support
<6>[    0.742266] NET: Registered PF_ALG protocol family
<5>[    0.742270] Key type asymmetric registered
<5>[    0.742271] Asymmetric key parser 'x509' registered
<6>[    0.742287] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 249)
<6>[    0.742290] io scheduler mq-deadline registered
<6>[    0.742292] io scheduler kyber registered
<6>[    0.744062] pcieport 0000:00:1c.0: PME: Signaling with IRQ 137
<6>[    0.744234] pcieport 0000:00:1c.4: PME: Signaling with IRQ 138
<6>[    0.744269] pcieport 0000:00:1c.4: pciehp: Slot #4 AttnBtn- PwrCtrl- MRL- AttnInd- PwrInd- HotPlug+ Surprise+ Interlock- NoCompl+ IbPresDis- LLActRep+
<6>[    0.744537] pcieport 0000:00:1d.0: PME: Signaling with IRQ 139
<6>[    0.744577] pcieport 0000:00:1d.0: pciehp: Slot #0 AttnBtn- PwrCtrl- MRL- AttnInd- PwrInd- HotPlug+ Surprise+ Interlock- NoCompl+ IbPresDis- LLActRep+
<6>[    0.744957] pcieport 0000:00:1d.4: PME: Signaling with IRQ 140
<6>[    0.745475] pcieport 0000:04:01.0: pciehp: Slot #1 AttnBtn- PwrCtrl- MRL- AttnInd- PwrInd- HotPlug+ Surprise+ Interlock- NoCompl+ IbPresDis- LLActRep+
<6>[    0.745889] shpchp: Standard Hot Plug PCI Controller Driver version: 0.4
<3>[    0.751739] acpiphp_ibm: ibm_acpiphp_init: acpi_walk_namespace failed
<6>[    0.753479] ACPI: AC: AC Adapter [AC] (off-line)
<6>[    0.753578] input: Sleep Button as /devices/LNXSYSTM:00/LNXSYBUS:00/PNP0C0E:00/input/input0
<6>[    0.753747] ACPI: button: Sleep Button [SLPB]
<6>[    0.753816] input: Lid Switch as /devices/LNXSYSTM:00/LNXSYBUS:00/PNP0C0D:00/input/input1
<6>[    0.754073] ACPI: button: Lid Switch [LID]
<6>[    0.754139] input: Power Button as /devices/LNXSYSTM:00/LNXPWRBN:00/input/input2
<6>[    0.754442] ACPI: button: Power Button [PWRF]
<6>[    0.762698] thermal LNXTHERM:00: registered as thermal_zone0
<6>[    0.762703] ACPI: thermal: Thermal Zone [THM0] (49 C)
<6>[    0.763905] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
<6>[    0.765076] Non-volatile memory driver v1.3
<6>[    0.765161] Linux agpgart interface v0.103
<6>[    0.765362] ACPI: bus type drm_connector registered
<6>[    0.765714] i915 0000:00:02.0: enabling device (0006 -> 0007)
<6>[    0.805790] ACPI: battery: Slot [BAT0] (battery present)
<6>[    1.453639] [drm] drm_dp_dpcd_access UNKNOWN via AUX B/DDI B/PHY B: Too many retries, giving up. First error: -110, First reply: 0x0, Last reply: 0x0, Request: 0x9, Address: 0x0, Size: 0x1
<6>[    1.757695] tsc: Refined TSC clocksource calibration: 2304.002 MHz
<6>[    1.757714] clocksource: tsc: mask: 0xffffffffffffffff max_cycles: 0x2135f9f0f74, max_idle_ns: 440795301392 ns
<6>[    1.757746] clocksource: Switched to clocksource tsc
<6>[    2.093639] [drm] drm_dp_dpcd_access UNKNOWN via AUX B/DDI B/PHY B: Too many retries, giving up. First error: -110, First reply: 0x0, Last reply: 0x0, Request: 0x9, Address: 0x0, Size: 0x1
<6>[    2.734638] [drm] drm_dp_dpcd_access UNKNOWN via AUX C/DDI C/PHY C: Too many retries, giving up. First error: -110, First reply: 0x0, Last reply: 0x0, Request: 0x9, Address: 0x0, Size: 0x1
<6>[    3.374638] [drm] drm_dp_dpcd_access UNKNOWN via AUX C/DDI C/PHY C: Too many retries, giving up. First error: -110, First reply: 0x0, Last reply: 0x0, Request: 0x9, Address: 0x0, Size: 0x1
<6>[    3.388348] [drm] Initialized i915 1.6.0 20230929 for 0000:00:02.0 on minor 0
<6>[    3.393418] ACPI: video: Video Device [GFX0] (multi-head: yes  rom: no  post: no)
<6>[    3.393745] input: Video Bus as /devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/LNXVIDEO:00/input/input3
<7>[    3.393907] i915 display info: display version: 9
<7>[    3.393913] i915 display info: cursor_needs_physical: no
<7>[    3.393917] i915 display info: has_cdclk_crawl: no
<7>[    3.393921] i915 display info: has_cdclk_squash: no
<7>[    3.393924] i915 display info: has_ddi: yes
<7>[    3.393927] i915 display info: has_dp_mst: yes
<7>[    3.393930] i915 display info: has_dsb: no
<7>[    3.393933] i915 display info: has_fpga_dbg: yes
<7>[    3.393936] i915 display info: has_gmch: no
<7>[    3.393940] i915 display info: has_hotplug: yes
<7>[    3.393943] i915 display info: has_hti: no
<7>[    3.393946] i915 display info: has_ipc: yes
<7>[    3.393948] i915 display info: has_overlay: no
<7>[    3.393950] i915 display info: has_psr: yes
<7>[    3.393952] i915 display info: has_psr_hw_tracking: yes
<7>[    3.393955] i915 display info: overlay_needs_physical: no
<7>[    3.393957] i915 display info: supports_tv: no
<7>[    3.393959] i915 display info: has_hdcp: yes
<7>[    3.393969] i915 display info: has_dmc: yes
<7>[    3.393973] i915 display info: has_dsc: no
<6>[    3.397917] loop: module loaded
<6>[    3.398145] mei_me 0000:00:16.0: enabling device (0000 -> 0002)
<6>[    3.398714] nvme nvme0: pci function 0000:2e:00.0
<6>[    3.399192] tun: Universal TUN/TAP device driver, 1.6
<6>[    3.399293] e100: Intel(R) PRO/100 Network Driver
<6>[    3.399296] e100: Copyright(c) 1999-2006 Intel Corporation
<6>[    3.399313] e1000: Intel(R) PRO/1000 Network Driver
<6>[    3.399315] e1000: Copyright (c) 1999-2006 Intel Corporation.
<6>[    3.399331] e1000e: Intel(R) PRO/1000 Network Driver
<6>[    3.399333] e1000e: Copyright(c) 1999 - 2015 Intel Corporation.
<6>[    3.399666] e1000e 0000:00:1f.6: Interrupt Throttling Rate (ints/sec) set to dynamic conservative mode
<6>[    3.407621] nvme nvme0: 8/0/0 default/read/poll queues
<6>[    3.412202]  nvme0n1: p3 p5
<6>[    3.433253] Console: switching to colour frame buffer device 240x67
<6>[    3.453341] i915 0000:00:02.0: [drm] fb0: i915drmfb frame buffer device
<6>[    3.635880] e1000e 0000:00:1f.6 0000:00:1f.6 (uninitialized): registered PHC clock
<6>[    3.700974] e1000e 0000:00:1f.6 eth0: (PCI Express:2.5GT/s:Width x1) 54:05:db:12:2a:f1
<6>[    3.700981] e1000e 0000:00:1f.6 eth0: Intel(R) PRO/1000 Network Connection
<6>[    3.701121] e1000e 0000:00:1f.6 eth0: MAC: 13, PHY: 12, PBA No: FFFFFF-0FF
<6>[    3.701153] Intel(R) 2.5G Ethernet Linux Driver
<6>[    3.701155] Copyright(c) 2018 Intel Corporation.
<6>[    3.701173] sky2: driver version 1.30
<6>[    3.701220] Intel(R) Wireless WiFi driver for Linux
<6>[    3.701263] iwlwifi 0000:00:14.3: enabling device (0000 -> 0002)
<6>[    3.703846] iwlwifi 0000:00:14.3: Detected crf-id 0x3617, cnv-id 0x20000302 wfpm id 0x80000000
<6>[    3.703864] iwlwifi 0000:00:14.3: PCI dev 02f0/0074, rev=0x351, rfid=0x10a100
<6>[    3.703972] usbcore: registered new device driver r8152-cfgselector
<6>[    3.703981] usbcore: registered new interface driver r8152
<6>[    3.703990] usbcore: registered new interface driver asix
<6>[    3.703998] usbcore: registered new interface driver ax88179_178a
<6>[    3.704005] usbcore: registered new interface driver cdc_ether
<6>[    3.704012] usbcore: registered new interface driver net1080
<6>[    3.704019] usbcore: registered new interface driver zaurus
<6>[    3.704028] usbcore: registered new interface driver cdc_ncm
<6>[    3.704035] usbcore: registered new interface driver qmi_wwan
<6>[    3.704043] usbcore: registered new interface driver cdc_mbim
<6>[    3.704050] usbcore: registered new interface driver r8153_ecm
<6>[    3.704465] xhci_hcd 0000:00:14.0: xHCI Host Controller
<6>[    3.704518] xhci_hcd 0000:00:14.0: new USB bus registered, assigned bus number 1
<6>[    3.704534] xhci_hcd 0000:00:14.0: Disabled LPM!
<6>[    3.705723] xhci_hcd 0000:00:14.0: hcc params 0x200077c1 hci version 0x110 quirks 0x0000000000009010
<6>[    3.705991] xhci_hcd 0000:00:14.0: xHCI Host Controller
<6>[    3.706090] xhci_hcd 0000:00:14.0: new USB bus registered, assigned bus number 2
<6>[    3.706095] xhci_hcd 0000:00:14.0: Host supports USB 3.1 Enhanced SuperSpeed
<6>[    3.706246] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice= 6.08
<6>[    3.706251] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
<6>[    3.706254] usb usb1: Product: xHCI Host Controller
<6>[    3.706256] usb usb1: Manufacturer: Linux 6.8.0-devel+ xhci-hcd
<6>[    3.706258] usb usb1: SerialNumber: 0000:00:14.0
<6>[    3.706565] hub 1-0:1.0: USB hub found
<6>[    3.706597] hub 1-0:1.0: 12 ports detected
<6>[    3.709796] usb usb2: We don't know the algorithms for LPM for this host, disabling LPM.
<6>[    3.709853] usb usb2: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice= 6.08
<6>[    3.709858] usb usb2: New USB device strings: Mfr=3, Product=2, SerialNumber=1
<6>[    3.709862] usb usb2: Product: xHCI Host Controller
<6>[    3.709864] usb usb2: Manufacturer: Linux 6.8.0-devel+ xhci-hcd
<6>[    3.709866] usb usb2: SerialNumber: 0000:00:14.0
<6>[    3.710027] hub 2-0:1.0: USB hub found
<6>[    3.710048] hub 2-0:1.0: 6 ports detected
<4>[    3.711546] usb: port power management may be unreliable
<6>[    3.712147] xhci_hcd 0000:2b:00.0: xHCI Host Controller
<6>[    3.712253] xhci_hcd 0000:2b:00.0: new USB bus registered, assigned bus number 3
<6>[    3.712274] xhci_hcd 0000:2b:00.0: Disabled LPM!
<6>[    3.713489] xhci_hcd 0000:2b:00.0: hcc params 0x200077c1 hci version 0x110 quirks 0x0000000200009010
<6>[    3.713803] xhci_hcd 0000:2b:00.0: xHCI Host Controller
<6>[    3.713892] xhci_hcd 0000:2b:00.0: new USB bus registered, assigned bus number 4
<6>[    3.713897] xhci_hcd 0000:2b:00.0: Host supports USB 3.1 Enhanced SuperSpeed
<6>[    3.714032] usb usb3: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice= 6.08
<6>[    3.714040] usb usb3: New USB device strings: Mfr=3, Product=2, SerialNumber=1
<6>[    3.714043] usb usb3: Product: xHCI Host Controller
<6>[    3.714046] usb usb3: Manufacturer: Linux 6.8.0-devel+ xhci-hcd
<6>[    3.714048] usb usb3: SerialNumber: 0000:2b:00.0
<6>[    3.714299] hub 3-0:1.0: USB hub found
<6>[    3.714356] hub 3-0:1.0: 2 ports detected
<6>[    3.717338] usb usb4: We don't know the algorithms for LPM for this host, disabling LPM.
<6>[    3.717397] usb usb4: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice= 6.08
<6>[    3.717402] usb usb4: New USB device strings: Mfr=3, Product=2, SerialNumber=1
<6>[    3.717406] usb usb4: Product: xHCI Host Controller
<6>[    3.717408] usb usb4: Manufacturer: Linux 6.8.0-devel+ xhci-hcd
<6>[    3.717411] usb usb4: SerialNumber: 0000:2b:00.0
<6>[    3.717642] hub 4-0:1.0: USB hub found
<6>[    3.717663] hub 4-0:1.0: 2 ports detected
<6>[    3.721095] usbcore: registered new interface driver cdc_acm
<6>[    3.721098] cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters
<6>[    3.721109] usbcore: registered new interface driver usblp
<6>[    3.721118] usbcore: registered new interface driver cdc_wdm
<6>[    3.721269] usbcore: registered new interface driver uas
<6>[    3.721296] usbcore: registered new interface driver usb-storage
<6>[    3.721305] usbcore: registered new interface driver ums-datafab
<6>[    3.721315] usbcore: registered new interface driver ums-freecom
<6>[    3.721323] usbcore: registered new interface driver ums-isd200
<6>[    3.721331] usbcore: registered new interface driver ums-jumpshot
<6>[    3.721339] usbcore: registered new interface driver ums-sddr09
<6>[    3.721347] usbcore: registered new interface driver ums-sddr55
<6>[    3.721355] usbcore: registered new interface driver ums-usbat
<6>[    3.721446] dummy_hcd dummy_hcd.0: USB Host+Gadget Emulator, driver 02 May 2005
<6>[    3.721451] dummy_hcd dummy_hcd.0: Dummy host controller
<6>[    3.721551] dummy_hcd dummy_hcd.0: new USB bus registered, assigned bus number 5
<6>[    3.721676] usb usb5: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice= 6.08
<6>[    3.721682] usb usb5: New USB device strings: Mfr=3, Product=2, SerialNumber=1
<6>[    3.721685] usb usb5: Product: Dummy host controller
<6>[    3.721687] usb usb5: Manufacturer: Linux 6.8.0-devel+ dummy_hcd
<6>[    3.721689] usb usb5: SerialNumber: dummy_hcd.0
<6>[    3.721931] hub 5-0:1.0: USB hub found
<6>[    3.721953] hub 5-0:1.0: 1 port detected
<6>[    3.722224] Mass Storage Function, version: 2009/09/11
<6>[    3.722227] LUN: removable file: (no medium)
<6>[    3.722247] LUN: removable file: (no medium)
<6>[    3.722249] Number of LUNs=1
<6>[    3.722296] g_mass_storage gadget.0: Mass Storage Gadget, version: 2009/09/11
<4>[    3.722299] g_mass_storage gadget.0: userspace failed to provide iSerialNumber
<6>[    3.722301] g_mass_storage gadget.0: g_mass_storage ready
<6>[    3.730849] i8042: PNP: PS/2 Controller [PNP0303:KBD,PNP0f13:MOU] at 0x60,0x64 irq 1,12
<6>[    3.735606] serio: i8042 KBD port at 0x60,0x64 irq 1
<6>[    3.735620] serio: i8042 AUX port at 0x60,0x64 irq 12
<6>[    3.735935] mousedev: PS/2 mouse device common for all mice
<6>[    3.737115] rtc_cmos 00:03: RTC can wake from S4
<6>[    3.740074] rtc_cmos 00:03: registered as rtc0
<6>[    3.740126] rtc_cmos 00:03: alarms up to one month, y3k, 242 bytes nvram
<3>[    3.740238] fail to initialize ptp_kvm
<6>[    3.740522] i801_smbus 0000:00:1f.4: SPD Write Disable is set
<6>[    3.740587] i801_smbus 0000:00:1f.4: SMBus using PCI interrupt
<6>[    3.742206] input: AT Raw Set 2 keyboard as /devices/platform/i8042/serio0/input/input4
<6>[    3.747673] Consider using thermal netlink events interface
<6>[    3.753103] i2c i2c-7: 2/4 memory slots populated (from DMI)
<6>[    3.754055] i2c i2c-7: Successfully instantiated SPD at 0x51
<6>[    3.754168] proc_thermal 0000:00:04.0: enabling device (0000 -> 0002)
<6>[    3.757456] intel_rapl_common: Found RAPL domain package
<6>[    3.757460] intel_rapl_common: Found RAPL domain dram
<6>[    3.757922] intel_pch_thermal 0000:00:12.0: enabling device (0000 -> 0002)
<6>[    3.758421] intel_pstate: Intel P-state driver initializing
<6>[    3.758984] intel_pstate: HWP enabled
<6>[    3.759001] efifb: probing for efifb
<6>[    3.759006] efifb: framebuffer at 0xa0000000, using 8128k, total 8128k
<6>[    3.759008] efifb: mode is 1920x1080x32, linelength=7680, pages=1
<6>[    3.759009] efifb: scrolling: redraw
<6>[    3.759009] efifb: Truecolor: size=8:8:8:8, shift=24:16:8:0
<6>[    3.759033] fb1: EFI VGA frame buffer device
<6>[    3.759043] hid: raw HID events driver (C) Jiri Kosina
<6>[    3.759078] usbcore: registered new interface driver usbhid
<6>[    3.759078] usbhid: USB HID core driver
<6>[    3.759178] fujitsu_laptop: driver 0.6.0 successfully loaded
<6>[    3.759203] thinkpad_acpi: ThinkPad ACPI Extras v0.26
<6>[    3.759204] thinkpad_acpi: http://ibm-acpi.sf.net/
<6>[    3.759205] thinkpad_acpi: ThinkPad BIOS N2XET24S (3.14 ), EC N2XHT25W
<6>[    3.759205] thinkpad_acpi: Lenovo ThinkPad T14 Gen 1, model 20S1S19N00
<6>[    3.759302] thinkpad_acpi: radio switch found; radios are enabled
<6>[    3.759305] thinkpad_acpi: This ThinkPad has standard ACPI backlight brightness control, supported by the ACPI video driver
<5>[    3.759306] thinkpad_acpi: Disabling thinkpad-acpi brightness events by default...
<6>[    3.760052] thinkpad_acpi: rfkill switch tpacpi_bluetooth_sw: radio is unblocked
<6>[    3.760158] thinkpad_acpi: Forcing WWAN always present
<6>[    3.760481] thinkpad_acpi: rfkill switch tpacpi_wwan_sw: radio is blocked
<6>[    3.774201] thinkpad_acpi: battery 1 registered (start 0, stop 100, behaviours: 0x7)
<6>[    3.774206] ACPI: battery: new extension: ThinkPad Battery Extension
<6>[    3.783152] input: ThinkPad Extra Buttons as /devices/platform/thinkpad_acpi/input/input7
<3>[    3.913506] ucsi_acpi USBC000:00: error -ENODEV: con1: failed to get usb role switch
<6>[    3.943681] usb 5-1: new high-speed USB device number 2 using dummy_hcd
<3>[    3.949683] ucsi_acpi USBC000:00: error -ENODEV: PPM init failed
<6>[    3.953687] usb 1-1: new full-speed USB device number 2 using xhci_hcd
<6>[    4.085686] usb 5-1: New USB device found, idVendor=22e0, idProduct=0300, bcdDevice= 6.08
<6>[    4.085688] usb 5-1: New USB device strings: Mfr=3, Product=4, SerialNumber=0
<6>[    4.085689] usb 5-1: Product: SINA Virtual USB Stick
<6>[    4.085690] usb 5-1: Manufacturer: Secunet
<6>[    4.089229] usb 1-1: New USB device found, idVendor=058f, idProduct=9540, bcdDevice= 1.20
<6>[    4.089231] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
<6>[    4.089233] usb 1-1: Product: EMV Smartcard Reader
<6>[    4.089233] usb 1-1: Manufacturer: Generic
<6>[    4.194776] usb 2-4: new SuperSpeed USB device number 2 using xhci_hcd
<6>[    4.207781] usb 2-4: New USB device found, idVendor=8564, idProduct=1000, bcdDevice=11.00
<6>[    4.207783] usb 2-4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
<6>[    4.207784] usb 2-4: Product: Mass Storage Device
<6>[    4.207785] usb 2-4: Manufacturer: JetFlash
<6>[    4.207786] usb 2-4: SerialNumber: 03HLUN227MDN24XN
<6>[    4.320686] usb 1-7: new high-speed USB device number 3 using xhci_hcd
<6>[    4.560820] psmouse serio1: synaptics: queried max coordinates: x [..5678], y [..4694]
<6>[    4.561628] intel_rapl_common: Found RAPL domain package
<6>[    4.561630] intel_rapl_common: Found RAPL domain core
<6>[    4.561631] intel_rapl_common: Found RAPL domain uncore
<6>[    4.561632] intel_rapl_common: Found RAPL domain dram
<6>[    4.561633] intel_rapl_common: Found RAPL domain psys
<6>[    4.561918] snd_hda_intel 0000:00:1f.3: DSP detected with PCI class/subclass/prog-if info 0x040380
<6>[    4.561946] snd_hda_intel 0000:00:1f.3: Digital mics found on Skylake+ platform, using SOF driver
<6>[    4.561965] usbcore: registered new interface driver snd-usb-audio
<6>[    4.562011] snd_soc_skl 0000:00:1f.3: DSP detected with PCI class/subclass/prog-if info 0x040380
<6>[    4.562036] snd_soc_skl 0000:00:1f.3: Digital mics found on Skylake+ platform, using SOF driver
<6>[    4.562059] sof-audio-pci-intel-cnl 0000:00:1f.3: DSP detected with PCI class/subclass/prog-if info 0x040380
<6>[    4.562084] sof-audio-pci-intel-cnl 0000:00:1f.3: Digital mics found on Skylake+ platform, using SOF driver
<6>[    4.562092] sof-audio-pci-intel-cnl 0000:00:1f.3: enabling device (0004 -> 0006)
<6>[    4.562158] sof-audio-pci-intel-cnl 0000:00:1f.3: DSP detected with PCI class/subclass/prog-if 0x040380
<6>[    4.562183] sof-audio-pci-intel-cnl 0000:00:1f.3: bound 0000:00:02.0 (ops i915_audio_component_bind_ops)
<6>[    4.568431] sof-audio-pci-intel-cnl 0000:00:1f.3: use msi interrupt mode
<6>[    4.568887] ipip: IPv4 and MPLS over IPv4 tunneling driver
<6>[    4.568973] Initializing XFRM netlink socket
<6>[    4.568976] IPsec XFRM device driver
<6>[    4.568986] NET: Registered PF_INET6 protocol family
<6>[    4.569297] Segment Routing with IPv6
<6>[    4.569301] In-situ OAM (IOAM) with IPv6
<6>[    4.569322] sit: IPv6, IPv4 and MPLS over IPv4 tunneling driver
<6>[    4.569461] NET: Registered PF_PACKET protocol family
<6>[    4.569463] NET: Registered PF_KEY protocol family
<6>[    4.569465] 8021q: 802.1Q VLAN Support v1.8
<6>[    4.569474] 9pnet: Installing 9P2000 support
<4>[    4.569986] ENERGY_PERF_BIAS: Set to 'normal', was 'performance'
<6>[    4.570267] microcode: Current revision: 0x000000f8
<6>[    4.570268] microcode: Updated early from: 0x000000d6
<6>[    4.570525] IPI shorthand broadcast: enabled
<6>[    4.572266] sched_clock: Marking stable (4563000521, 8625527)->(4637230504, -65604456)
<5>[    4.572444] Loading compiled-in X.509 certificates
<6>[    4.579304] sof-audio-pci-intel-cnl 0000:00:1f.3: hda codecs found, mask 5
<6>[    4.579306] sof-audio-pci-intel-cnl 0000:00:1f.3: using HDA machine driver skl_hda_dsp_generic now
<6>[    4.579308] sof-audio-pci-intel-cnl 0000:00:1f.3: DMICs detected in NHLT tables: 2
<6>[    4.592389] psmouse serio1: synaptics: queried min coordinates: x [1266..], y [1162..]
<6>[    4.592393] psmouse serio1: synaptics: Trying to set up SMBus access
<6>[    4.627309] rmi4_smbus 7-002c: registering SMbus-connected sensor
<6>[    4.756395] rmi4_f01 rmi4-00.fn01: found RMI device, manufacturer: Synaptics, product: TM3471-010, fw id: 2867793
<6>[    4.841481] input: Synaptics TM3471-010 as /devices/pci0000:00/0000:00:1f.4/i2c-7/7-002c/rmi4-00/input/input8
<6>[    4.851682] serio: RMI4 PS/2 pass-through port at rmi4-00.fn03
<6>[    5.315767] Freeing initrd memory: 41352K
<6>[    5.316431] modprobe (136) used greatest stack depth: 13304 bytes left
<5>[    5.317613] Loaded X.509 cert 'Build time autogenerated kernel key: 38df7aa89675866473e0091facb285e903a80814'
<6>[    5.317893] sof-audio-pci-intel-cnl 0000:00:1f.3: Firmware paths/files for ipc type 0:
<6>[    5.317896] sof-audio-pci-intel-cnl 0000:00:1f.3:  Firmware file:     intel/sof/sof-cml.ri
<6>[    5.317897] sof-audio-pci-intel-cnl 0000:00:1f.3:  Topology file:     intel/sof-tplg/sof-hda-generic-2ch.tplg
<6>[    5.318429] PM:   Magic number: 12:825:331
<6>[    5.318471] tty tty52: hash matches
<5>[    5.318548] cfg80211: Loading compiled-in X.509 certificates for regulatory database
<5>[    5.319737] Loaded X.509 cert 'sforshee: 00b28ddf47aef9cea7'
<5>[    5.319840] Loaded X.509 cert 'wens: 61c038651aabdcf94bd0ac7ff06c7248db18c600'
<6>[    5.319858] clk: Disabling unused clocks
<6>[    5.319859] ALSA device list:
<6>[    5.319860]   No soundcards found.
<6>[    5.320098] i915 0000:00:02.0: [drm] Finished loading DMC firmware i915/kbl_dmc_ver1_04.bin (v1.4)
<6>[    5.320592] Freeing unused kernel image (initmem) memory: 3616K
<6>[    5.324758] sof-audio-pci-intel-cnl 0000:00:1f.3: Firmware info: version 2:2:0-57864
<6>[    5.324759] sof-audio-pci-intel-cnl 0000:00:1f.3: Firmware: ABI 3:22:1 Kernel ABI 3:23:0
<6>[    5.324762] sof-audio-pci-intel-cnl 0000:00:1f.3: unknown sof_ext_man header type 3 size 0x30
<6>[    5.324872] iwlwifi 0000:00:14.3: TLV_FW_FSEQ_VERSION: FSEQ Version: 89.3.35.37
<6>[    5.325074] iwlwifi 0000:00:14.3: loaded firmware version 77.2dda880d.0 QuZ-a0-hr-b0-77.ucode op_mode iwlmvm
<6>[    5.325968] iwlwifi 0000:00:14.3: Detected Intel(R) Wi-Fi 6 AX201 160MHz, REV=0x351
<4>[    5.326002] thermal thermal_zone7: failed to read out thermal zone (-61)
<6>[    5.327683] Write protecting the kernel read-only data: 30720k
<6>[    5.328099] Freeing unused kernel image (rodata/data gap) memory: 1464K
<6>[    5.328497] x86/mm: Checked W+X mappings: passed, no W+X pages found.
<6>[    5.328501] Run /init as init process
<7>[    5.328502]   with arguments:
<7>[    5.328502]     /init
<7>[    5.328503]     nosmt,
<7>[    5.328504]     sina_toram
<7>[    5.328504]   with environment:
<7>[    5.328504]     HOME=/
<7>[    5.328505]     TERM=linux
<7>[    5.328505]     BOOT_IMAGE=/isolinux/bzImage
<6>[    5.441451] sof-audio-pci-intel-cnl 0000:00:1f.3: Firmware info: version 2:2:0-57864
<6>[    5.441454] sof-audio-pci-intel-cnl 0000:00:1f.3: Firmware: ABI 3:22:1 Kernel ABI 3:23:0
<6>[    5.441759] sof-audio-pci-intel-cnl 0000:00:1f.3: Topology: ABI 3:22:1 Kernel ABI 3:23:0
<4>[    5.441915] skl_hda_dsp_generic skl_hda_dsp_generic: ASoC: Parent card not yet available, widget card binding deferred
<6>[    5.445973] iwlwifi 0000:00:14.3: Detected RF HR B3, rfid=0x10a100
<6>[    5.452813] snd_hda_codec_realtek ehdaudio0D0: autoconfig for ALC257: line_outs=1 (0x14/0x0/0x0/0x0/0x0) type:speaker
<6>[    5.452816] snd_hda_codec_realtek ehdaudio0D0:    speaker_outs=0 (0x0/0x0/0x0/0x0/0x0)
<6>[    5.452817] snd_hda_codec_realtek ehdaudio0D0:    hp_outs=1 (0x21/0x0/0x0/0x0/0x0)
<6>[    5.452818] snd_hda_codec_realtek ehdaudio0D0:    mono: mono_out=0x0
<6>[    5.452819] snd_hda_codec_realtek ehdaudio0D0:    inputs:
<6>[    5.452820] snd_hda_codec_realtek ehdaudio0D0:      Mic=0x19
<3>[    5.468721] ACPI Error: Needed [Integer/String/Buffer], found [Package] 0000000093b1791b (20230628/exresop-469)
<3>[    5.468728] ACPI Error: AE_AML_OPERAND_TYPE, While resolving operands for [OpcodeName unavailable] (20230628/dswexec-433)
<3>[    5.468732] ACPI Error: Aborting method \ADBG due to previous error (AE_AML_OPERAND_TYPE) (20230628/psparse-529)
<3>[    5.468738] ACPI Error: Aborting method \_SB.HIDD._DSM due to previous error (AE_AML_OPERAND_TYPE) (20230628/psparse-529)
<4>[    5.468745] ACPI: \_SB_.HIDD: failed to evaluate _DSM b356ecee-4244-8f40-a792-4edd4d758054 (0x3003)
<6>[    5.468792] input: Intel HID events as /devices/platform/INT33D5:00/input/input11
<6>[    5.512277] iwlwifi 0000:00:14.3: base HW address: 34:2e:b7:52:c0:92
<6>[    5.523969] input: sof-hda-dsp Mic as /devices/pci0000:00/0000:00:1f.3/skl_hda_dsp_generic/sound/card0/input12
<6>[    5.524392] input: sof-hda-dsp Headphone as /devices/pci0000:00/0000:00:1f.3/skl_hda_dsp_generic/sound/card0/input13
<6>[    5.524802] input: sof-hda-dsp HDMI/DP,pcm=3 as /devices/pci0000:00/0000:00:1f.3/skl_hda_dsp_generic/sound/card0/input14
<6>[    5.524859] input: sof-hda-dsp HDMI/DP,pcm=4 as /devices/pci0000:00/0000:00:1f.3/skl_hda_dsp_generic/sound/card0/input15
<6>[    5.524909] input: sof-hda-dsp HDMI/DP,pcm=5 as /devices/pci0000:00/0000:00:1f.3/skl_hda_dsp_generic/sound/card0/input16
<6>[    5.680003] psmouse serio1: synaptics: queried max coordinates: x [..5678], y [..4694]
<6>[    5.721204] psmouse serio1: synaptics: queried min coordinates: x [1266..], y [1162..]
<6>[    5.721218] psmouse serio1: synaptics: Trying to set up SMBus access
<4>[    5.726329] sysfs: cannot create duplicate filename '/devices/pci0000:00/0000:00:1f.4/i2c-7/7-002c'
<4>[    5.726336] CPU: 6 PID: 78 Comm: kworker/6:1 Not tainted 6.8.0-devel+ #1
<4>[    5.726342] Hardware name: LENOVO 20S1S19N00/20S1S19N00, BIOS N2XET24S (3.14 ) 10/10/2020
<4>[    5.726345] Workqueue: events_long serio_handle_event
<4>[    5.726354] Call Trace:
<4>[    5.726358]  <TASK>
<4>[    5.726362]  dump_stack_lvl+0x64/0x80
<4>[    5.726370]  sysfs_warn_dup+0x5a/0x70
<4>[    5.726376]  sysfs_create_dir_ns+0xd4/0xf0
<4>[    5.726381]  kobject_add_internal+0xa3/0x2c0
<4>[    5.726389]  kobject_add+0x97/0x100
<4>[    5.726395]  ? get_device_parent+0x25/0x1d0
<4>[    5.726403]  device_add+0xc9/0x890
<4>[    5.726410]  i2c_new_client_device+0x1b8/0x340
<4>[    5.726418]  ? __pfx_psmouse_smbus_create_companion+0x10/0x10
<4>[    5.726426]  psmouse_smbus_create_companion+0x88/0xa0
<4>[    5.726432]  bus_for_each_dev+0x85/0xd0
<4>[    5.726436]  ? __pfx_psmouse_smbus_create_companion+0x10/0x10
<4>[    5.726442]  i2c_for_each_dev+0x31/0x50
<4>[    5.726447]  psmouse_smbus_init+0x157/0x260
<4>[    5.726453]  synaptics_create_intertouch+0xfb/0x140
<4>[    5.726462]  synaptics_init+0x93/0x1e0
<4>[    5.726469]  psmouse_extensions+0x259/0x520
<4>[    5.726474]  psmouse_switch_protocol+0x143/0x190
<4>[    5.726479]  psmouse_connect+0x1cb/0x410
<4>[    5.726484]  serio_driver_probe+0x31/0x50
<4>[    5.726489]  really_probe+0x19f/0x400
<4>[    5.726494]  ? __pfx___device_attach_driver+0x10/0x10
<4>[    5.726499]  __driver_probe_device+0x78/0x160
<4>[    5.726504]  driver_probe_device+0x1f/0x90
<4>[    5.726509]  __device_attach_driver+0x89/0x110
<4>[    5.726515]  bus_for_each_drv+0x92/0xf0
<4>[    5.726519]  __device_attach+0xb2/0x1b0
<4>[    5.726524]  serio_handle_event+0x179/0x290
<4>[    5.726529]  process_one_work+0x138/0x2f0
<4>[    5.726534]  worker_thread+0x2f5/0x420
<4>[    5.726538]  ? trace_hardirqs_off.part.0+0x16/0x70
<4>[    5.726543]  ? __pfx_worker_thread+0x10/0x10
<4>[    5.726547]  kthread+0xd4/0x100
<4>[    5.726553]  ? __pfx_kthread+0x10/0x10
<4>[    5.726558]  ret_from_fork+0x31/0x50
<4>[    5.726565]  ? __pfx_kthread+0x10/0x10
<4>[    5.726570]  ret_from_fork_asm+0x1b/0x30
<4>[    5.726578]  </TASK>
<3>[    5.726580] kobject: kobject_add_internal failed for 7-002c with -EEXIST, don't try to register things with the same name in the same directory.
<3>[    5.726585] i2c i2c-7: Failed to register i2c client rmi4_smbus at 0x2c (-17)
<6>[    5.726595] psmouse serio1: synaptics: SMbus companion is not ready yet
<6>[    5.810012] psmouse serio1: synaptics: Touchpad model: 1, fw: 10.32, id: 0x1e2a1, caps: 0xf00aa3/0x940300/0x12e800/0x500000, board id: 3471, fw id: 2867793
<6>[    5.810036] psmouse serio1: synaptics: serio: Synaptics pass-through port at isa0060/serio1/input0
<6>[    5.862718] input: SynPS/2 Synaptics TouchPad as /devices/platform/i8042/serio1/input/input10
<3>[    5.935532] rmi4_physical rmi4-00: rmi_driver_set_irq_bits: Failed to change enabled interrupts!
<4>[    5.935547] psmouse: probe of serio2 failed with error -1
<6>[    6.569592] psmouse serio3: trackpoint: Elan TrackPoint firmware: 0x11, buttons: 3/3
<6>[    6.711455] usb 1-7: New USB device found, idVendor=2cb7, idProduct=0007, bcdDevice= 3.33
<6>[    6.711467] usb 1-7: New USB device strings: Mfr=1, Product=2, SerialNumber=3
<6>[    6.711472] usb 1-7: Product: L850-GL
<6>[    6.711475] usb 1-7: Manufacturer: Fibocom Wireless Inc.
<6>[    6.711479] usb 1-7: SerialNumber: 004999010640000
<6>[    6.851130] input: TPPS/2 Elan TrackPoint as /devices/platform/i8042/serio1/serio3/input/input18
<6>[    6.852713] usb 1-8: new high-speed USB device number 4 using xhci_hcd
<1>[    6.939521] BUG: kernel NULL pointer dereference, address: 0000000000000040
<1>[    6.939533] #PF: supervisor read access in kernel mode
<1>[    6.939538] #PF: error_code(0x0000) - not-present page
<6>[    6.939544] PGD 0 P4D 0 
<4>[    6.939551] Oops: 0000 [#1] PREEMPT SMP NOPTI
<4>[    6.939559] CPU: 6 PID: 48 Comm: kworker/6:0 Not tainted 6.8.0-devel+ #1
<4>[    6.939567] Hardware name: LENOVO 20S1S19N00/20S1S19N00, BIOS N2XET24S (3.14 ) 10/10/2020
<4>[    6.939572] Workqueue: psmouse-smbus psmouse_smbus_remove_i2c_device
<4>[    6.939588] RIP: 0010:__irq_domain_deactivate_irq+0x14/0x50
<4>[    6.939602] Code: 84 00 00 00 00 00 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 0f 1f 44 00 00 48 85 ff 74 33 53 48 89 fb eb 1e 48 8b 47 18 <48> 8b 40 40 48 85 c0 74 08 48 89 de ff d0 0f 1f 00 48 8b 5b 28 48
<4>[    6.939609] RSP: 0018:ffffa7510024bae8 EFLAGS: 00010086
<4>[    6.939616] RAX: 0000000000000000 RBX: ffff98608504c828 RCX: 0000000000150014
<4>[    6.939621] RDX: 0000000000000001 RSI: ffffffffa93f42fc RDI: ffff986080d9d800
<4>[    6.939625] RBP: ffff98608504c828 R08: 0000000000000000 R09: ffffffffa8562d01
<4>[    6.939630] R10: ffff986080042600 R11: 0000000000000001 R12: ffff98608504c960
<4>[    6.939634] R13: ffff98608504c8a4 R14: 0000000000000246 R15: ffff98608504c800
<4>[    6.939638] FS:  0000000000000000(0000) GS:ffff9867be580000(0000) knlGS:0000000000000000
<4>[    6.939644] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
<4>[    6.939649] CR2: 0000000000000040 CR3: 00000002f222e003 CR4: 00000000003706f0
<4>[    6.939654] Call Trace:
<4>[    6.939659]  <TASK>
<4>[    6.939665]  ? __die+0x23/0x70
<4>[    6.939676]  ? page_fault_oops+0x181/0x470
<4>[    6.939686]  ? trace_hardirqs_on+0x21/0x90
<4>[    6.939694]  ? _raw_spin_unlock_irqrestore+0x19/0x40
<4>[    6.939706]  ? __wake_up+0x44/0x60
<4>[    6.939716]  ? exc_page_fault+0x68/0x150
<4>[    6.939724]  ? asm_exc_page_fault+0x26/0x30
<4>[    6.939734]  ? remove_proc_subtree+0x151/0x1f0
<4>[    6.939765]  ? _raw_spin_lock_irqsave+0x3c/0x60
<4>[    6.939777]  ? __irq_domain_deactivate_irq+0x14/0x50
<4>[    6.939786]  ? trace_hardirqs_off.part.0+0x16/0x70
<4>[    6.939793]  irq_domain_deactivate_irq+0x22/0x40
<4>[    6.939800]  free_irq+0x1ef/0x2d0
<4>[    6.939807]  devres_release_all+0xb9/0x110
<4>[    6.939820]  device_unbind_cleanup+0xe/0x70
<4>[    6.939829]  device_release_driver_internal+0x1c4/0x200
<4>[    6.939839]  bus_remove_device+0xc6/0x130
<4>[    6.939846]  device_del+0x15c/0x3f0
<4>[    6.939855]  rmi_unregister_function+0x34/0x70
<4>[    6.939867]  rmi_free_function_list+0x7c/0xf0
<4>[    6.939874]  rmi_driver_remove+0x40/0x50
<4>[    6.939880]  device_release_driver_internal+0x19f/0x200
<4>[    6.939890]  bus_remove_device+0xc6/0x130
<4>[    6.939897]  device_del+0x15c/0x3f0
<4>[    6.939904]  ? kernfs_name_hash+0x12/0x80
<4>[    6.939915]  rmi_unregister_transport_device+0x16/0x20
<4>[    6.939925]  i2c_device_remove+0x23/0xb0
<4>[    6.939935]  device_release_driver_internal+0x19f/0x200
<4>[    6.939944]  bus_remove_device+0xc6/0x130
<4>[    6.939952]  device_del+0x15c/0x3f0
<4>[    6.939959]  ? trace_hardirqs_off.part.0+0x16/0x70
<4>[    6.939965]  ? _raw_spin_lock_irqsave+0x3c/0x60
<4>[    6.939976]  device_unregister+0x17/0x60
<4>[    6.939983]  psmouse_smbus_remove_i2c_device+0x18/0x40
<4>[    6.939994]  process_one_work+0x138/0x2f0
<4>[    6.940002]  worker_thread+0x2f5/0x420
<4>[    6.940008]  ? __pfx_worker_thread+0x10/0x10
<4>[    6.940015]  kthread+0xd4/0x100
<4>[    6.940024]  ? __pfx_kthread+0x10/0x10
<4>[    6.940032]  ret_from_fork+0x31/0x50
<4>[    6.940043]  ? __pfx_kthread+0x10/0x10
<4>[    6.940052]  ret_from_fork_asm+0x1b/0x30
<4>[    6.940065]  </TASK>
<4>[    6.940068] Modules linked in: pinctrl_cannonlake pinctrl_intel intel_hid
<4>[    6.940081] CR2: 0000000000000040
<4>[    6.940086] ---[ end trace 0000000000000000 ]---

ECC: No errors detected

^ permalink raw reply

* Re: [PATCH RFC bpf-next v2 02/10] bpf/helpers: introduce sleepable timers
From: Alexei Starovoitov @ 2024-02-21  2:59 UTC (permalink / raw)
  To: Benjamin Tissoires
  Cc: Alexei Starovoitov, Daniel Borkmann, John Fastabend,
	Andrii Nakryiko, Martin KaFai Lau, Eduard Zingerman, Song Liu,
	Yonghong Song, KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa,
	Jiri Kosina, Benjamin Tissoires, Jonathan Corbet, Shuah Khan, bpf,
	linux-kernel, linux-input, linux-doc, linux-kselftest
In-Reply-To: <rhdu4st5tfabsdqs27ewhvdlwblhj2re4o56iz3fq3bsuokxxe@gtuqdjffj2hn>

On Fri, Feb 16, 2024 at 10:50:10AM +0100, Benjamin Tissoires wrote:
>  static bool is_rbtree_lock_required_kfunc(u32 btf_id)
>  {
>  	return is_bpf_rbtree_api_kfunc(btf_id);
> @@ -12140,6 +12143,16 @@ static int check_kfunc_call(struct bpf_verifier_env *env, struct bpf_insn *insn,
>  		}
>  	}
>  
> +	if (is_bpf_timer_set_sleepable_cb_kfunc(meta.func_id)) {
> +		err = push_callback_call(env, insn, insn_idx, meta.subprogno,
> +					 set_timer_callback_state);
> +		if (err) {
> +			verbose(env, "kfunc %s#%d failed callback verification\n",
> +				func_name, meta.func_id);
> +			return err;
> +		}
> +	}

All makes sense so far.
Please squash all the fix and repost.
It's hard to do a proper review in this shape of the patch.
As far as rcu_read_lock/unlock that is done in callback...
it feels buggy and unnecessary.
bpf prog and timer won't disappear while work is queued.
array and hash map will call bpf_obj_free_timer() before going away.

And things like:
+       rcu_read_lock();
+       callback_fn = rcu_dereference(t->sleepable_cb_fn);
+       rcu_read_unlock();
+       if (!callback_fn)
+               return;

is 99% broken. if (!callback_fn) line is UAF.

^ permalink raw reply

* Re: [PATCH RFC bpf-next v2 03/10] bpf/verifier: allow more maps in sleepable bpf programs
From: Alexei Starovoitov @ 2024-02-21  2:51 UTC (permalink / raw)
  To: Benjamin Tissoires
  Cc: Alexei Starovoitov, Daniel Borkmann, John Fastabend,
	Andrii Nakryiko, Martin KaFai Lau, Eduard Zingerman, Song Liu,
	Yonghong Song, KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa,
	Jiri Kosina, Benjamin Tissoires, Jonathan Corbet, Shuah Khan, bpf,
	linux-kernel, linux-input, linux-doc, linux-kselftest
In-Reply-To: <20240214-hid-bpf-sleepable-v2-3-5756b054724d@kernel.org>

On Wed, Feb 14, 2024 at 06:18:32PM +0100, Benjamin Tissoires wrote:
> These 2 maps types are required for HID-BPF when a user wants to do
> IO with a device from a sleepable tracing point.
> 
> Allowing BPF_MAP_TYPE_QUEUE (and therefore BPF_MAP_TYPE_STACK) allows
> for a BPF program to prepare from an IRQ the list of HID commands to send
> back to the device and then these commands can be retrieved from the
> sleepable trace point.
> 
> Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
> 
> ---
> 
> changes in v2:
> - dropped BPF_MAP_TYPE_PROG_ARRAY from the list
> ---
>  kernel/bpf/verifier.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> index 67da3f7bddb5..cb1266566b69 100644
> --- a/kernel/bpf/verifier.c
> +++ b/kernel/bpf/verifier.c
> @@ -18094,6 +18094,8 @@ static int check_map_prog_compatibility(struct bpf_verifier_env *env,
>  		case BPF_MAP_TYPE_SK_STORAGE:
>  		case BPF_MAP_TYPE_TASK_STORAGE:
>  		case BPF_MAP_TYPE_CGRP_STORAGE:
> +		case BPF_MAP_TYPE_QUEUE:
> +		case BPF_MAP_TYPE_STACK:
>  			break;

Maybe resend this one and patch 1 without RFC, so we can start landing them?

^ permalink raw reply

* Re: [PATCH RFC bpf-next v2 02/10] bpf/helpers: introduce sleepable timers
From: Alexei Starovoitov @ 2024-02-21  2:49 UTC (permalink / raw)
  To: Benjamin Tissoires
  Cc: Toke Høiland-Jørgensen, Martin KaFai Lau, bpf,
	linux-kernel, linux-input, linux-doc, linux-kselftest,
	Alexei Starovoitov, Daniel Borkmann, John Fastabend,
	Andrii Nakryiko, Eduard Zingerman, Song Liu, Yonghong Song,
	KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa, Jiri Kosina,
	Benjamin Tissoires, Jonathan Corbet, Shuah Khan
In-Reply-To: <fckhc367l6eha2gpftixhzjdsmo2jts5p6ir6ukx2q5xndsbhf@btzjwvuamcv4>

On Fri, Feb 16, 2024 at 03:58:20PM +0100, Benjamin Tissoires wrote:
> 
> So (and this also answers your second email today) I'm thinking at:
> - have multiple flags to control the timer (with dedicated timer_cb
>   kernel functions):
>   - BPF_F_TIMER_HRTIMER (default)
>   - BPF_F_TIMER_WORKER (no timer, just workqueue)

These two make sense, but

>   - BPF_F_TIMER_DELAYED_WORKER (hrtimer + workqueue, or actual
>     delayed_work, but that's re-implementing stuffs)

This one doesn't.
Unlike hrtimer the workqueue is non deterministic.
Requesting a callback after a specific delay only to be randomized
by the workqueue is a confusing UX to give to bpf progs.
If bpf author really want to do something like that they can implement
such anti-feature manually with two bpf_timers.

Later we'll add a selector for WQ. At that time we'd need to decide
whether to use a dedicated kthread or any of system_*_wq or WQ_BH.
For now I'd only expose 'sleepable' as a guarantee in bpf api.
Hence BPF_F_TIMER_SLEEPABLE is the only extra bit in flags for bpf_timer_start().
Not sure whether it's needed in bpf_timer_init() too.

^ permalink raw reply

* [PATCH v8 3/5] mfd: cs40l50: Add support for CS40L50 core driver
From: James Ogletree @ 2024-02-21  0:36 UTC (permalink / raw)
  To: dmitry.torokhov, robh+dt, krzysztof.kozlowski+dt, conor+dt, lee,
	broonie, jeff
  Cc: patches, linux-sound, linux-input, devicetree, James Ogletree
In-Reply-To: <20240221003630.2535938-1-jogletre@opensource.cirrus.com>

Introduce support for Cirrus Logic Device CS40L50: a
haptic driver with waveform memory, integrated DSP,
and closed-loop algorithms.

The MFD component registers and initializes the device.

Signed-off-by: James Ogletree <jogletre@opensource.cirrus.com>
---
 MAINTAINERS                 |   2 +
 drivers/mfd/Kconfig         |  30 ++
 drivers/mfd/Makefile        |   4 +
 drivers/mfd/cs40l50-core.c  | 531 ++++++++++++++++++++++++++++++++++++
 drivers/mfd/cs40l50-i2c.c   |  69 +++++
 drivers/mfd/cs40l50-spi.c   |  69 +++++
 include/linux/mfd/cs40l50.h | 142 ++++++++++
 7 files changed, 847 insertions(+)
 create mode 100644 drivers/mfd/cs40l50-core.c
 create mode 100644 drivers/mfd/cs40l50-i2c.c
 create mode 100644 drivers/mfd/cs40l50-spi.c
 create mode 100644 include/linux/mfd/cs40l50.h

diff --git a/MAINTAINERS b/MAINTAINERS
index b71017a187f8..69a9e0a3b968 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4940,6 +4940,8 @@ M:	Ben Bright <ben.bright@cirrus.com>
 L:	patches@opensource.cirrus.com
 S:	Supported
 F:	Documentation/devicetree/bindings/input/cirrus,cs40l50.yaml
+F:	drivers/mfd/cs40l*
+F:	include/linux/mfd/cs40l*
 
 CIRRUS LOGIC DSP FIRMWARE DRIVER
 M:	Simon Trimmer <simont@opensource.cirrus.com>
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 90ce58fd629e..6273c255f107 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -2241,6 +2241,36 @@ config MCP_UCB1200_TS
 
 endmenu
 
+config MFD_CS40L50_CORE
+	tristate
+	select MFD_CORE
+	select FW_CS_DSP
+	select REGMAP_IRQ
+
+config MFD_CS40L50_I2C
+	tristate "Cirrus Logic CS40L50 (I2C)"
+	select REGMAP_I2C
+	select MFD_CS40L50_CORE
+	depends on I2C
+	help
+	  Select this to support the Cirrus Logic CS40L50 Haptic
+	  Driver over I2C.
+
+	  This driver can be built as a module. If built as a module it will be
+	  called "cs40l50-i2c".
+
+config MFD_CS40L50_SPI
+	tristate "Cirrus Logic CS40L50 (SPI)"
+	select REGMAP_SPI
+	select MFD_CS40L50_CORE
+	depends on SPI
+	help
+	  Select this to support the Cirrus Logic CS40L50 Haptic
+	  Driver over SPI.
+
+	  This driver can be built as a module. If built as a module it will be
+	  called "cs40l50-spi".
+
 config MFD_VEXPRESS_SYSREG
 	tristate "Versatile Express System Registers"
 	depends on VEXPRESS_CONFIG && GPIOLIB
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index c66f07edcd0e..a8d18ba155d0 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -88,6 +88,10 @@ obj-$(CONFIG_MFD_MADERA)	+= madera.o
 obj-$(CONFIG_MFD_MADERA_I2C)	+= madera-i2c.o
 obj-$(CONFIG_MFD_MADERA_SPI)	+= madera-spi.o
 
+obj-$(CONFIG_MFD_CS40L50_CORE)	+= cs40l50-core.o
+obj-$(CONFIG_MFD_CS40L50_I2C)	+= cs40l50-i2c.o
+obj-$(CONFIG_MFD_CS40L50_SPI)	+= cs40l50-spi.o
+
 obj-$(CONFIG_TPS6105X)		+= tps6105x.o
 obj-$(CONFIG_TPS65010)		+= tps65010.o
 obj-$(CONFIG_TPS6507X)		+= tps6507x.o
diff --git a/drivers/mfd/cs40l50-core.c b/drivers/mfd/cs40l50-core.c
new file mode 100644
index 000000000000..949a7b7c4e44
--- /dev/null
+++ b/drivers/mfd/cs40l50-core.c
@@ -0,0 +1,531 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * CS40L50 Advanced Haptic Driver with waveform memory,
+ * integrated DSP, and closed-loop algorithms
+ *
+ * Copyright 2024 Cirrus Logic, Inc.
+ *
+ * Author: James Ogletree <james.ogletree@cirrus.com>
+ */
+
+#include <linux/firmware/cirrus/cs_dsp.h>
+#include <linux/firmware/cirrus/wmfw.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/cs40l50.h>
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
+
+static const struct mfd_cell cs40l50_devs[] = {
+	{ .name = "cs40l50-codec", },
+	{ .name = "cs40l50-vibra", },
+};
+
+const struct regmap_config cs40l50_regmap = {
+	.reg_bits =		32,
+	.reg_stride =		4,
+	.val_bits =		32,
+	.reg_format_endian =	REGMAP_ENDIAN_BIG,
+	.val_format_endian =	REGMAP_ENDIAN_BIG,
+};
+EXPORT_SYMBOL_GPL(cs40l50_regmap);
+
+static const char * const cs40l50_supplies[] = {
+	"vp", "vio",
+};
+
+static const struct regmap_irq cs40l50_reg_irqs[] = {
+	REGMAP_IRQ_REG(CS40L50_DSP_QUEUE_IRQ, CS40L50_IRQ1_INT_2_OFFSET,
+		       CS40L50_DSP_QUEUE_MASK),
+	REGMAP_IRQ_REG(CS40L50_AMP_SHORT_IRQ, CS40L50_IRQ1_INT_1_OFFSET,
+		       CS40L50_AMP_SHORT_MASK),
+	REGMAP_IRQ_REG(CS40L50_TEMP_ERR_IRQ, CS40L50_IRQ1_INT_8_OFFSET,
+		       CS40L50_TEMP_ERR_MASK),
+	REGMAP_IRQ_REG(CS40L50_BST_UVP_IRQ, CS40L50_IRQ1_INT_9_OFFSET,
+		       CS40L50_BST_UVP_MASK),
+	REGMAP_IRQ_REG(CS40L50_BST_SHORT_IRQ, CS40L50_IRQ1_INT_9_OFFSET,
+		       CS40L50_BST_SHORT_MASK),
+	REGMAP_IRQ_REG(CS40L50_BST_ILIMIT_IRQ, CS40L50_IRQ1_INT_9_OFFSET,
+		       CS40L50_BST_ILIMIT_MASK),
+	REGMAP_IRQ_REG(CS40L50_UVLO_VDDBATT_IRQ, CS40L50_IRQ1_INT_10_OFFSET,
+		       CS40L50_UVLO_VDDBATT_MASK),
+	REGMAP_IRQ_REG(CS40L50_GLOBAL_ERROR_IRQ, CS40L50_IRQ1_INT_18_OFFSET,
+		       CS40L50_GLOBAL_ERROR_MASK),
+};
+
+static struct regmap_irq_chip cs40l50_irq_chip = {
+	.name =		"CS40L50 IRQ Controller",
+
+	.status_base =	CS40L50_IRQ1_INT_1,
+	.mask_base =	CS40L50_IRQ1_MASK_1,
+	.ack_base =	CS40L50_IRQ1_INT_1,
+	.num_regs =	22,
+
+	.irqs =		cs40l50_reg_irqs,
+	.num_irqs =	ARRAY_SIZE(cs40l50_reg_irqs),
+
+	.runtime_pm =	true,
+};
+
+int cs40l50_dsp_write(struct device *dev, struct regmap *regmap, u32 val)
+{
+	int err, i;
+	u32 ack;
+
+	/* Device NAKs if exiting hibernation, so optionally retry here */
+	for (i = 0; i < CS40L50_DSP_TIMEOUT_COUNT; i++) {
+		err = regmap_write(regmap, CS40L50_DSP_QUEUE, val);
+		if (!err)
+			break;
+
+		usleep_range(CS40L50_DSP_POLL_US, CS40L50_DSP_POLL_US + 100);
+	}
+
+	/* If we never wrote, don't bother checking for ACK */
+	if (i == CS40L50_DSP_TIMEOUT_COUNT) {
+		dev_err(dev, "Timed out writing %#X to DSP: %d\n", val, err);
+		return err;
+	}
+
+	err = regmap_read_poll_timeout(regmap, CS40L50_DSP_QUEUE, ack, !ack,
+				       CS40L50_DSP_POLL_US,
+				       CS40L50_DSP_POLL_US * CS40L50_DSP_TIMEOUT_COUNT);
+	if (err)
+		dev_err(dev, "DSP did not ack %#X: %d\n", val, err);
+
+	return err;
+}
+EXPORT_SYMBOL_GPL(cs40l50_dsp_write);
+
+static const struct cs_dsp_region cs40l50_dsp_regions[] = {
+	{ .type = WMFW_HALO_PM_PACKED, .base = CS40L50_PMEM_0 },
+	{ .type = WMFW_HALO_XM_PACKED, .base = CS40L50_XMEM_PACKED_0 },
+	{ .type = WMFW_HALO_YM_PACKED, .base = CS40L50_YMEM_PACKED_0 },
+	{ .type = WMFW_ADSP2_XM, .base = CS40L50_XMEM_UNPACKED24_0 },
+	{ .type = WMFW_ADSP2_YM, .base = CS40L50_YMEM_UNPACKED24_0 },
+};
+
+static void cs40l50_dsp_remove(void *data)
+{
+	cs_dsp_remove((struct cs_dsp *)data);
+}
+
+static const struct cs_dsp_client_ops cs40l50_client_ops;
+
+static int cs40l50_dsp_init(struct cs40l50 *cs40l50)
+{
+	int err;
+
+	cs40l50->dsp.num = 1;
+	cs40l50->dsp.type = WMFW_HALO;
+	cs40l50->dsp.dev = cs40l50->dev;
+	cs40l50->dsp.regmap = cs40l50->regmap;
+	cs40l50->dsp.base = CS40L50_CORE_BASE;
+	cs40l50->dsp.base_sysinfo = CS40L50_SYS_INFO_ID;
+	cs40l50->dsp.mem = cs40l50_dsp_regions;
+	cs40l50->dsp.num_mems = ARRAY_SIZE(cs40l50_dsp_regions);
+	cs40l50->dsp.no_core_startstop = true;
+	cs40l50->dsp.client_ops = &cs40l50_client_ops;
+
+	err = cs_dsp_halo_init(&cs40l50->dsp);
+	if (err)
+		return err;
+
+	return devm_add_action_or_reset(cs40l50->dev, cs40l50_dsp_remove,
+					&cs40l50->dsp);
+}
+
+struct cs40l50_irq {
+	const char *name;
+	int virq;
+};
+
+static struct cs40l50_irq cs40l50_irqs[] = {
+	{ "DSP", },
+	{ "Global", },
+	{ "Boost UVLO", },
+	{ "Boost current limit", },
+	{ "Boost short", },
+	{ "Boost undervolt", },
+	{ "Overtemp", },
+	{ "Amp short", },
+};
+
+static const struct reg_sequence cs40l50_err_rls[] = {
+	{ CS40L50_ERR_RLS, CS40L50_GLOBAL_ERR_RLS_SET },
+	{ CS40L50_ERR_RLS, CS40L50_GLOBAL_ERR_RLS_CLEAR },
+};
+
+static irqreturn_t cs40l50_hw_err(int irq, void *data)
+{
+	struct cs40l50 *cs40l50 = data;
+	int err = 0, i;
+
+	mutex_lock(&cs40l50->lock);
+
+	/* Log hardware interrupt and execute error release sequence */
+	for (i = 1; i < ARRAY_SIZE(cs40l50_irqs); i++) {
+		if (cs40l50_irqs[i].virq == irq) {
+			dev_err(cs40l50->dev, "%s error\n", cs40l50_irqs[i].name);
+			err = regmap_multi_reg_write(cs40l50->regmap, cs40l50_err_rls,
+						     ARRAY_SIZE(cs40l50_err_rls));
+			goto exit;
+		}
+	}
+exit:
+	mutex_unlock(&cs40l50->lock);
+	return IRQ_RETVAL(!err);
+}
+
+static irqreturn_t cs40l50_dsp_queue(int irq, void *data)
+{
+	struct cs40l50 *cs40l50 = data;
+	u32 rd_ptr, val, wt_ptr;
+	int err = 0;
+
+	mutex_lock(&cs40l50->lock);
+
+	/* Read from DSP queue and update read pointer */
+	while (!err) {
+		err = regmap_read(cs40l50->regmap, CS40L50_DSP_QUEUE_WT, &wt_ptr);
+		if (err)
+			goto exit;
+
+		err = regmap_read(cs40l50->regmap, CS40L50_DSP_QUEUE_RD, &rd_ptr);
+		if (err)
+			goto exit;
+
+		/* Check if queue is empty */
+		if (wt_ptr == rd_ptr)
+			goto exit;
+
+		err = regmap_read(cs40l50->regmap, rd_ptr, &val);
+		if (err)
+			goto exit;
+
+		dev_dbg(cs40l50->dev, "DSP payload: %#X", val);
+
+		rd_ptr += sizeof(u32);
+
+		if (rd_ptr > CS40L50_DSP_QUEUE_END)
+			rd_ptr = CS40L50_DSP_QUEUE_BASE;
+
+		err =  regmap_write(cs40l50->regmap, CS40L50_DSP_QUEUE_RD, rd_ptr);
+		if (err)
+			goto exit;
+	}
+exit:
+	mutex_unlock(&cs40l50->lock);
+
+	return IRQ_RETVAL(!err);
+}
+
+static int cs40l50_irq_init(struct cs40l50 *cs40l50)
+{
+	struct device *dev = cs40l50->dev;
+	int err, i, virq;
+
+	err = devm_regmap_add_irq_chip(dev, cs40l50->regmap, cs40l50->irq,
+				       IRQF_ONESHOT | IRQF_SHARED, 0,
+				       &cs40l50_irq_chip, &cs40l50->irq_data);
+	if (err) {
+		dev_err(dev, "Failed adding IRQ chip\n");
+		return err;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(cs40l50_irqs); i++) {
+		virq = regmap_irq_get_virq(cs40l50->irq_data, i);
+		if (virq < 0) {
+			dev_err(dev, "Failed getting %s\n", cs40l50_irqs[i].name);
+			return virq;
+		}
+
+		cs40l50_irqs[i].virq = virq;
+
+		/* Handle DSP and non-DSP interrupts separately */
+		err = devm_request_threaded_irq(dev, virq, NULL,
+						i ? cs40l50_hw_err : cs40l50_dsp_queue,
+						IRQF_ONESHOT | IRQF_SHARED,
+						cs40l50_irqs[i].name, cs40l50);
+		if (err) {
+			dev_err(dev, "Failed requesting %s IRQ\n", cs40l50_irqs[i].name);
+			return err;
+		}
+	}
+
+	return 0;
+}
+
+static const struct reg_sequence cs40l50_stop_core[] = {
+	{ CS40L50_CCM_CORE_CONTROL,	CS40L50_CLOCK_DISABLE},
+	{ CS40L50_RAM_INIT,		CS40L50_RAM_INIT_FLAG},
+	{ CS40L50_PWRMGT_CTL,		CS40L50_MEM_RDY_HW},
+};
+
+static const struct reg_sequence cs40l50_internal_vamp_config[] = {
+	{ CS40L50_BST_LPMODE_SEL,	CS40L50_DCM_LOW_POWER },
+	{ CS40L50_BLOCK_ENABLES2,	CS40L50_OVERTEMP_WARN },
+};
+
+static const struct reg_sequence cs40l50_irq_mask_override[] = {
+	{ CS40L50_IRQ1_MASK_2,	CS40L50_IRQ_MASK_2_OVERRIDE },
+	{ CS40L50_IRQ1_MASK_20,	CS40L50_IRQ_MASK_20_OVERRIDE },
+};
+
+static void cs40l50_dsp_power_down(void *data)
+{
+	cs_dsp_power_down((struct cs_dsp *)data);
+}
+
+static int cs40l50_power_up_dsp(struct cs40l50 *cs40l50)
+{
+	int err;
+
+	mutex_lock(&cs40l50->lock);
+
+	/* Stop and resume core to load patch file */
+	err = regmap_multi_reg_write(cs40l50->regmap, cs40l50_stop_core,
+				     ARRAY_SIZE(cs40l50_stop_core));
+	if (err)
+		goto err_mutex;
+
+	err = cs_dsp_power_up(&cs40l50->dsp, cs40l50->patch, "cs40l50.wmfw",
+			      cs40l50->bin, "cs40l50.bin", "cs40l50");
+	if (err)
+		goto err_mutex;
+
+	err = devm_add_action_or_reset(cs40l50->dev, cs40l50_dsp_power_down,
+				       &cs40l50->dsp);
+	if (err)
+		goto err_mutex;
+
+	err = regmap_write(cs40l50->regmap, CS40L50_CCM_CORE_CONTROL,
+			   CS40L50_CLOCK_ENABLE);
+
+err_mutex:
+	mutex_unlock(&cs40l50->lock);
+
+	return err;
+}
+
+static int cs40l50_configure_dsp(struct cs40l50 *cs40l50)
+{
+	u32 nwaves;
+	int err;
+
+	if (cs40l50->bin) {
+		/* Log number of effects if wavetable was loaded */
+		err = regmap_read(cs40l50->regmap, CS40L50_NUM_WAVES, &nwaves);
+		if (err)
+			return err;
+
+		dev_info(cs40l50->dev, "Loaded with %u effects\n", nwaves);
+	}
+
+	mutex_lock(&cs40l50->dsp.pwr_lock);
+	cs40l50->wseqs[CS40L50_PWR_ON].ctl = cs_dsp_get_ctl(&cs40l50->dsp,
+							    "PM_PWR_ON_SEQ",
+							    WMFW_ADSP2_XM,
+							    CS40L50_PM_ALGO);
+	mutex_unlock(&cs40l50->dsp.pwr_lock);
+	if (!cs40l50->wseqs[CS40L50_PWR_ON].ctl) {
+		dev_err(cs40l50->dev, "No control for power-on write sequence\n");
+		return -ENOENT;
+	}
+
+	/* Initialize the power-on write sequencer */
+	err = cs_dsp_wseq_init(&cs40l50->dsp, cs40l50->wseqs, 1);
+	if (err) {
+		dev_err(cs40l50->dev, "Failed to initialize write sequences\n");
+		return err;
+	}
+
+	/* Use internal V_AMP supply */
+	err = regmap_multi_reg_write(cs40l50->regmap, cs40l50_internal_vamp_config,
+				     ARRAY_SIZE(cs40l50_internal_vamp_config));
+	if (err)
+		return err;
+
+	err = cs_dsp_wseq_multi_write(&cs40l50->dsp, &cs40l50->wseqs[CS40L50_PWR_ON],
+				      cs40l50_internal_vamp_config, CS_DSP_WSEQ_FULL,
+				      ARRAY_SIZE(cs40l50_internal_vamp_config), false);
+	if (err)
+		return err;
+
+	/* Override firmware defaults for IRQ masks */
+	err = regmap_multi_reg_write(cs40l50->regmap, cs40l50_irq_mask_override,
+				     ARRAY_SIZE(cs40l50_irq_mask_override));
+	if (err)
+		return err;
+
+	return cs_dsp_wseq_multi_write(&cs40l50->dsp, &cs40l50->wseqs[CS40L50_PWR_ON],
+				       cs40l50_irq_mask_override, CS_DSP_WSEQ_FULL,
+				       ARRAY_SIZE(cs40l50_irq_mask_override), false);
+}
+
+static void cs40l50_start_dsp(const struct firmware *bin, void *context)
+{
+	struct cs40l50 *cs40l50 = context;
+	int err;
+
+	/* Wavetable is optional; power up DSP regardless */
+	cs40l50->bin = bin;
+
+	err = cs40l50_power_up_dsp(cs40l50);
+	if (err) {
+		dev_err(cs40l50->dev, "Failed to power up DSP: %d\n", err);
+		goto err_fw;
+	}
+
+	err = cs40l50_configure_dsp(cs40l50);
+	if (err)
+		dev_err(cs40l50->dev, "Failed to configure DSP: %d\n", err);
+
+	err = devm_mfd_add_devices(cs40l50->dev, PLATFORM_DEVID_NONE, cs40l50_devs,
+				   ARRAY_SIZE(cs40l50_devs), NULL, 0, NULL);
+	if (err)
+		dev_err(cs40l50->dev, "Failed to add sub devices: %d\n", err);
+
+err_fw:
+	release_firmware(cs40l50->bin);
+	release_firmware(cs40l50->patch);
+}
+
+static void cs40l50_request_patch(const struct firmware *patch, void *context)
+{
+	struct cs40l50 *cs40l50 = context;
+
+	if (!patch) {
+		dev_err(cs40l50->dev, "Failed to request patch file\n");
+		return;
+	}
+
+	cs40l50->patch = patch;
+
+	if (request_firmware_nowait(THIS_MODULE, FW_ACTION_UEVENT, CS40L50_WT,
+				    cs40l50->dev, GFP_KERNEL, cs40l50,
+				    cs40l50_start_dsp)) {
+		dev_err(cs40l50->dev, "Failed to request %s\n", CS40L50_WT);
+		release_firmware(cs40l50->patch);
+	}
+}
+
+static int cs40l50_get_model(struct cs40l50 *cs40l50)
+{
+	int err;
+
+	err = regmap_read(cs40l50->regmap, CS40L50_DEVID, &cs40l50->devid);
+	if (err)
+		return err;
+
+	if (cs40l50->devid != CS40L50_DEVID_A)
+		return -EINVAL;
+
+	err = regmap_read(cs40l50->regmap, CS40L50_REVID, &cs40l50->revid);
+	if (err)
+		return err;
+
+	if (cs40l50->revid < CS40L50_REVID_B0)
+		return -EINVAL;
+
+	dev_info(cs40l50->dev, "Cirrus Logic CS40L50 rev. %02X\n", cs40l50->revid);
+
+	return 0;
+}
+
+static int cs40l50_pm_runtime_setup(struct device *dev)
+{
+	int err;
+
+	pm_runtime_set_autosuspend_delay(dev, CS40L50_AUTOSUSPEND_MS);
+	pm_runtime_use_autosuspend(dev);
+	pm_runtime_get_noresume(dev);
+	err = pm_runtime_set_active(dev);
+	if (err)
+		return err;
+
+	return devm_pm_runtime_enable(dev);
+}
+
+int cs40l50_probe(struct cs40l50 *cs40l50)
+{
+	struct device *dev = cs40l50->dev;
+	int err;
+
+	mutex_init(&cs40l50->lock);
+
+	cs40l50->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
+	if (IS_ERR(cs40l50->reset_gpio))
+		return dev_err_probe(dev, PTR_ERR(cs40l50->reset_gpio),
+				     "Failed getting reset GPIO\n");
+
+	err = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(cs40l50_supplies),
+					     cs40l50_supplies);
+	if (err)
+		return dev_err_probe(dev, err, "Failed getting supplies\n");
+
+	/* Ensure minimum reset pulse width */
+	usleep_range(CS40L50_RESET_PULSE_US, CS40L50_RESET_PULSE_US + 100);
+
+	gpiod_set_value_cansleep(cs40l50->reset_gpio, 0);
+
+	/* Wait for control port to be ready */
+	usleep_range(CS40L50_CP_READY_US, CS40L50_CP_READY_US + 100);
+
+	err = cs40l50_dsp_init(cs40l50);
+	if (err)
+		return dev_err_probe(dev, err, "Failed to initialize DSP\n");
+
+	err = cs40l50_pm_runtime_setup(dev);
+	if (err)
+		return dev_err_probe(dev, err, "Failed to initialize runtime PM\n");
+
+	err = cs40l50_get_model(cs40l50);
+	if (err)
+		return dev_err_probe(dev, err, "Failed to get part number\n");
+
+	err = cs40l50_irq_init(cs40l50);
+	if (err)
+		return dev_err_probe(dev, err, "Failed to request IRQs\n");
+
+	err = request_firmware_nowait(THIS_MODULE, FW_ACTION_UEVENT, CS40L50_FW,
+				      dev, GFP_KERNEL, cs40l50, cs40l50_request_patch);
+	if (err)
+		return dev_err_probe(dev, err, "Failed to request %s\n", CS40L50_FW);
+
+	pm_runtime_mark_last_busy(dev);
+	pm_runtime_put_autosuspend(dev);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(cs40l50_probe);
+
+int cs40l50_remove(struct cs40l50 *cs40l50)
+{
+	gpiod_set_value_cansleep(cs40l50->reset_gpio, 1);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(cs40l50_remove);
+
+static int cs40l50_runtime_suspend(struct device *dev)
+{
+	struct cs40l50 *cs40l50 = dev_get_drvdata(dev);
+
+	return regmap_write(cs40l50->regmap, CS40L50_DSP_QUEUE, CS40L50_ALLOW_HIBER);
+}
+
+static int cs40l50_runtime_resume(struct device *dev)
+{
+	struct cs40l50 *cs40l50 = dev_get_drvdata(dev);
+
+	return cs40l50_dsp_write(dev, cs40l50->regmap, CS40L50_PREVENT_HIBER);
+}
+
+EXPORT_GPL_DEV_PM_OPS(cs40l50_pm_ops) = {
+	RUNTIME_PM_OPS(cs40l50_runtime_suspend, cs40l50_runtime_resume, NULL)
+};
+
+MODULE_DESCRIPTION("CS40L50 Advanced Haptic Driver");
+MODULE_AUTHOR("James Ogletree, Cirrus Logic Inc. <james.ogletree@cirrus.com>");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS(FW_CS_DSP);
diff --git a/drivers/mfd/cs40l50-i2c.c b/drivers/mfd/cs40l50-i2c.c
new file mode 100644
index 000000000000..e18938dbddaa
--- /dev/null
+++ b/drivers/mfd/cs40l50-i2c.c
@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * CS40L50 Advanced Haptic Driver with waveform memory,
+ * integrated DSP, and closed-loop algorithms
+ *
+ * Copyright 2024 Cirrus Logic, Inc.
+ *
+ * Author: James Ogletree <james.ogletree@cirrus.com>
+ */
+
+#include <linux/i2c.h>
+#include <linux/mfd/cs40l50.h>
+
+static int cs40l50_i2c_probe(struct i2c_client *client)
+{
+	struct device *dev = &client->dev;
+	struct cs40l50 *cs40l50;
+
+	cs40l50 = devm_kzalloc(dev, sizeof(*cs40l50), GFP_KERNEL);
+	if (!cs40l50)
+		return -ENOMEM;
+
+	i2c_set_clientdata(client, cs40l50);
+
+	cs40l50->regmap = devm_regmap_init_i2c(client, &cs40l50_regmap);
+	if (IS_ERR(cs40l50->regmap))
+		return dev_err_probe(cs40l50->dev, PTR_ERR(cs40l50->regmap),
+				     "Failed to initialize register map\n");
+
+	cs40l50->dev = dev;
+	cs40l50->irq = client->irq;
+
+	return cs40l50_probe(cs40l50);
+}
+
+static void cs40l50_i2c_remove(struct i2c_client *client)
+{
+	struct cs40l50 *cs40l50 = i2c_get_clientdata(client);
+
+	cs40l50_remove(cs40l50);
+}
+
+static const struct i2c_device_id cs40l50_id_i2c[] = {
+	{"cs40l50"},
+	{}
+};
+MODULE_DEVICE_TABLE(i2c, cs40l50_id_i2c);
+
+static const struct of_device_id cs40l50_of_match[] = {
+	{ .compatible = "cirrus,cs40l50" },
+	{}
+};
+MODULE_DEVICE_TABLE(of, cs40l50_of_match);
+
+static struct i2c_driver cs40l50_i2c_driver = {
+	.driver = {
+		.name = "cs40l50",
+		.of_match_table = cs40l50_of_match,
+		.pm = pm_ptr(&cs40l50_pm_ops),
+	},
+	.id_table = cs40l50_id_i2c,
+	.probe = cs40l50_i2c_probe,
+	.remove = cs40l50_i2c_remove,
+};
+module_i2c_driver(cs40l50_i2c_driver);
+
+MODULE_DESCRIPTION("CS40L50 I2C Driver");
+MODULE_AUTHOR("James Ogletree, Cirrus Logic Inc. <james.ogletree@cirrus.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/cs40l50-spi.c b/drivers/mfd/cs40l50-spi.c
new file mode 100644
index 000000000000..9e18bb74eae0
--- /dev/null
+++ b/drivers/mfd/cs40l50-spi.c
@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * CS40L50 Advanced Haptic Driver with waveform memory,
+ * integrated DSP, and closed-loop algorithms
+ *
+ * Copyright 2024 Cirrus Logic, Inc.
+ *
+ * Author: James Ogletree <james.ogletree@cirrus.com>
+ */
+
+#include <linux/mfd/cs40l50.h>
+#include <linux/spi/spi.h>
+
+static int cs40l50_spi_probe(struct spi_device *spi)
+{
+	struct cs40l50 *cs40l50;
+	struct device *dev = &spi->dev;
+
+	cs40l50 = devm_kzalloc(dev, sizeof(*cs40l50), GFP_KERNEL);
+	if (!cs40l50)
+		return -ENOMEM;
+
+	spi_set_drvdata(spi, cs40l50);
+
+	cs40l50->regmap = devm_regmap_init_spi(spi, &cs40l50_regmap);
+	if (IS_ERR(cs40l50->regmap))
+		return dev_err_probe(cs40l50->dev, PTR_ERR(cs40l50->regmap),
+				     "Failed to initialize register map\n");
+
+	cs40l50->dev = dev;
+	cs40l50->irq = spi->irq;
+
+	return cs40l50_probe(cs40l50);
+}
+
+static void cs40l50_spi_remove(struct spi_device *spi)
+{
+	struct cs40l50 *cs40l50 = spi_get_drvdata(spi);
+
+	cs40l50_remove(cs40l50);
+}
+
+static const struct spi_device_id cs40l50_id_spi[] = {
+	{"cs40l50"},
+	{}
+};
+MODULE_DEVICE_TABLE(spi, cs40l50_id_spi);
+
+static const struct of_device_id cs40l50_of_match[] = {
+	{ .compatible = "cirrus,cs40l50" },
+	{}
+};
+MODULE_DEVICE_TABLE(of, cs40l50_of_match);
+
+static struct spi_driver cs40l50_spi_driver = {
+	.driver = {
+		.name = "cs40l50",
+		.of_match_table = cs40l50_of_match,
+		.pm = pm_ptr(&cs40l50_pm_ops),
+	},
+	.id_table = cs40l50_id_spi,
+	.probe = cs40l50_spi_probe,
+	.remove = cs40l50_spi_remove,
+};
+module_spi_driver(cs40l50_spi_driver);
+
+MODULE_DESCRIPTION("CS40L50 SPI Driver");
+MODULE_AUTHOR("James Ogletree, Cirrus Logic Inc. <james.ogletree@cirrus.com>");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/mfd/cs40l50.h b/include/linux/mfd/cs40l50.h
new file mode 100644
index 000000000000..d855784a88a9
--- /dev/null
+++ b/include/linux/mfd/cs40l50.h
@@ -0,0 +1,142 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * CS40L50 Advanced Haptic Driver with waveform memory,
+ * integrated DSP, and closed-loop algorithms
+ *
+ * Copyright 2024 Cirrus Logic, Inc.
+ *
+ * Author: James Ogletree <james.ogletree@cirrus.com>
+ */
+
+#ifndef __CS40L50_H__
+#define __CS40L50_H__
+
+#include <linux/firmware/cirrus/cs_dsp.h>
+#include <linux/gpio/consumer.h>
+#include <linux/pm.h>
+#include <linux/regmap.h>
+
+/* Power Supply Configuration */
+#define CS40L50_BLOCK_ENABLES2		0x201C
+#define CS40L50_ERR_RLS			0x2034
+#define CS40L50_PWRMGT_CTL		0x2900
+#define CS40L50_BST_LPMODE_SEL		0x3810
+#define CS40L50_DCM_LOW_POWER		0x1
+#define CS40L50_OVERTEMP_WARN		0x4000010
+
+/* Interrupts */
+#define CS40L50_IRQ1_INT_1		0xE010
+#define CS40L50_IRQ1_BASE		CS40L50_IRQ1_INT_1
+#define CS40L50_IRQ1_INT_2		0xE014
+#define CS40L50_IRQ1_INT_8		0xE02C
+#define CS40L50_IRQ1_INT_9		0xE030
+#define CS40L50_IRQ1_INT_10		0xE034
+#define CS40L50_IRQ1_INT_18		0xE054
+#define CS40L50_IRQ1_MASK_1		0xE090
+#define CS40L50_IRQ1_MASK_2		0xE094
+#define CS40L50_IRQ1_MASK_20		0xE0DC
+#define CS40L50_IRQ1_INT_1_OFFSET	(CS40L50_IRQ1_INT_1 - CS40L50_IRQ1_BASE)
+#define CS40L50_IRQ1_INT_2_OFFSET	(CS40L50_IRQ1_INT_2 - CS40L50_IRQ1_BASE)
+#define CS40L50_IRQ1_INT_8_OFFSET	(CS40L50_IRQ1_INT_8 - CS40L50_IRQ1_BASE)
+#define CS40L50_IRQ1_INT_9_OFFSET	(CS40L50_IRQ1_INT_9 - CS40L50_IRQ1_BASE)
+#define CS40L50_IRQ1_INT_10_OFFSET	(CS40L50_IRQ1_INT_10 - CS40L50_IRQ1_BASE)
+#define CS40L50_IRQ1_INT_18_OFFSET	(CS40L50_IRQ1_INT_18 - CS40L50_IRQ1_BASE)
+#define CS40L50_IRQ_MASK_2_OVERRIDE	0xFFDF7FFF
+#define CS40L50_IRQ_MASK_20_OVERRIDE	0x15C01000
+#define CS40L50_AMP_SHORT_MASK		BIT(31)
+#define CS40L50_DSP_QUEUE_MASK		BIT(21)
+#define CS40L50_TEMP_ERR_MASK		BIT(31)
+#define CS40L50_BST_UVP_MASK		BIT(6)
+#define CS40L50_BST_SHORT_MASK		BIT(7)
+#define CS40L50_BST_ILIMIT_MASK		BIT(18)
+#define CS40L50_UVLO_VDDBATT_MASK	BIT(16)
+#define CS40L50_GLOBAL_ERROR_MASK	BIT(15)
+
+enum cs40l50_irq_list {
+	CS40L50_DSP_QUEUE_IRQ,
+	CS40L50_GLOBAL_ERROR_IRQ,
+	CS40L50_UVLO_VDDBATT_IRQ,
+	CS40L50_BST_ILIMIT_IRQ,
+	CS40L50_BST_SHORT_IRQ,
+	CS40L50_BST_UVP_IRQ,
+	CS40L50_TEMP_ERR_IRQ,
+	CS40L50_AMP_SHORT_IRQ,
+};
+
+/* DSP */
+#define CS40L50_XMEM_PACKED_0		0x2000000
+#define CS40L50_XMEM_UNPACKED24_0	0x2800000
+#define CS40L50_SYS_INFO_ID		0x25E0000
+#define CS40L50_RAM_INIT		0x28021DC
+#define CS40L50_DSP_QUEUE_WT		0x28042C8
+#define CS40L50_DSP_QUEUE_RD		0x28042CC
+#define CS40L50_NUM_WAVES		0x2805C18
+#define CS40L50_CORE_BASE		0x2B80000
+#define CS40L50_CCM_CORE_CONTROL	0x2BC1000
+#define CS40L50_YMEM_PACKED_0		0x2C00000
+#define CS40L50_YMEM_UNPACKED24_0	0x3400000
+#define CS40L50_PMEM_0			0x3800000
+#define CS40L50_MEM_RDY_HW		0x2
+#define CS40L50_RAM_INIT_FLAG		0x1
+#define CS40L50_CLOCK_DISABLE		0x80
+#define CS40L50_CLOCK_ENABLE		0x281
+#define CS40L50_DSP_POLL_US		1000
+#define CS40L50_DSP_TIMEOUT_COUNT	100
+#define CS40L50_RESET_PULSE_US		2200
+#define CS40L50_CP_READY_US		3100
+#define CS40L50_AUTOSUSPEND_MS		2000
+#define CS40L50_PM_ALGO			0x9F206
+#define CS40L50_GLOBAL_ERR_RLS_SET	BIT(11)
+#define CS40L50_GLOBAL_ERR_RLS_CLEAR	0
+
+enum cs40l50_wseqs {
+	CS40L50_PWR_ON,
+	CS40L50_STANDBY,
+	CS40L50_ACTIVE,
+	CS40L50_NUM_WSEQS,
+};
+
+/* DSP Commands */
+#define CS40L50_DSP_QUEUE_BASE		0x11004
+#define CS40L50_DSP_QUEUE_END		0x1101C
+#define CS40L50_DSP_QUEUE		0x11020
+#define CS40L50_PREVENT_HIBER		0x2000003
+#define CS40L50_ALLOW_HIBER		0x2000004
+#define CS40L50_START_I2S		0x3000002
+#define CS40L50_OWT_PUSH		0x3000008
+#define CS40L50_STOP_PLAYBACK		0x5000000
+#define CS40L50_OWT_DELETE		0xD000000
+
+/* Firmware files */
+#define CS40L50_FW			"cs40l50.wmfw"
+#define CS40L50_WT			"cs40l50.bin"
+
+/* Device */
+#define CS40L50_DEVID			0x0
+#define CS40L50_REVID			0x4
+#define CS40L50_DEVID_A			0x40A50
+#define CS40L50_REVID_B0		0xB0
+
+struct cs40l50 {
+	struct device *dev;
+	struct regmap *regmap;
+	struct mutex lock;
+	struct cs_dsp dsp;
+	struct gpio_desc *reset_gpio;
+	struct regmap_irq_chip_data *irq_data;
+	const struct firmware *patch;
+	const struct firmware *bin;
+	struct cs_dsp_wseq wseqs[CS40L50_NUM_WSEQS];
+	int irq;
+	u32 devid;
+	u32 revid;
+};
+
+int cs40l50_dsp_write(struct device *dev, struct regmap *regmap, u32 val);
+int cs40l50_probe(struct cs40l50 *cs40l50);
+int cs40l50_remove(struct cs40l50 *cs40l50);
+
+extern const struct regmap_config cs40l50_regmap;
+extern const struct dev_pm_ops cs40l50_pm_ops;
+
+#endif /* __CS40L50_H__ */
-- 
2.25.1


^ permalink raw reply related

* [PATCH v8 2/5] dt-bindings: input: cirrus,cs40l50: Add initial DT binding
From: James Ogletree @ 2024-02-21  0:36 UTC (permalink / raw)
  To: dmitry.torokhov, robh+dt, krzysztof.kozlowski+dt, conor+dt, lee,
	broonie, jeff
  Cc: patches, linux-sound, linux-input, devicetree, James Ogletree,
	Krzysztof Kozlowski
In-Reply-To: <20240221003630.2535938-1-jogletre@opensource.cirrus.com>

The CS40L50 is a haptic driver with waveform memory,
integrated DSP, and closed-loop algorithms.

Add a YAML DT binding document for this device.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Signed-off-by: James Ogletree <jogletre@opensource.cirrus.com>
---
 .../bindings/input/cirrus,cs40l50.yaml        | 70 +++++++++++++++++++
 MAINTAINERS                                   |  8 +++
 2 files changed, 78 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/cirrus,cs40l50.yaml

diff --git a/Documentation/devicetree/bindings/input/cirrus,cs40l50.yaml b/Documentation/devicetree/bindings/input/cirrus,cs40l50.yaml
new file mode 100644
index 000000000000..6a5bdafed56b
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/cirrus,cs40l50.yaml
@@ -0,0 +1,70 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/input/cirrus,cs40l50.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Cirrus Logic CS40L50 Advanced Haptic Driver
+
+maintainers:
+  - James Ogletree <james.ogletree@cirrus.com>
+
+description:
+  CS40L50 is a haptic driver with waveform memory,
+  integrated DSP, and closed-loop algorithms.
+
+properties:
+  compatible:
+    enum:
+      - cirrus,cs40l50
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  reset-gpios:
+    maxItems: 1
+
+  va-supply:
+    description: Power supply for internal analog circuits.
+
+  vp-supply:
+    description: Power supply for always-on circuits.
+
+  vio-supply:
+    description: Power supply for digital input/output.
+
+  vamp-supply:
+    description: Power supply for the Class D amplifier.
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - reset-gpios
+  - vp-supply
+  - vio-supply
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    i2c {
+      #address-cells = <1>;
+      #size-cells = <0>;
+
+      haptic-driver@34 {
+        compatible = "cirrus,cs40l50";
+        reg = <0x34>;
+        interrupt-parent = <&gpio>;
+        interrupts = <113 IRQ_TYPE_LEVEL_LOW>;
+        reset-gpios = <&gpio 112 GPIO_ACTIVE_LOW>;
+        vp-supply = <&vreg>;
+        vio-supply = <&vreg>;
+      };
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index dd5de540ec0b..b71017a187f8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4933,6 +4933,14 @@ F:	sound/pci/hda/cs*
 F:	sound/pci/hda/hda_cs_dsp_ctl.*
 F:	sound/soc/codecs/cs*
 
+CIRRUS LOGIC HAPTIC DRIVERS
+M:	James Ogletree <james.ogletree@cirrus.com>
+M:	Fred Treven <fred.treven@cirrus.com>
+M:	Ben Bright <ben.bright@cirrus.com>
+L:	patches@opensource.cirrus.com
+S:	Supported
+F:	Documentation/devicetree/bindings/input/cirrus,cs40l50.yaml
+
 CIRRUS LOGIC DSP FIRMWARE DRIVER
 M:	Simon Trimmer <simont@opensource.cirrus.com>
 M:	Charles Keepax <ckeepax@opensource.cirrus.com>
-- 
2.25.1


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox