diff mbox series

[3/5] driver core: make struct device_type.uevent() take a const *

Message ID 20221123122523.1332370-3-gregkh@linuxfoundation.org
State New
Headers show
Series [1/5] driver core: make struct class.dev_uevent() take a const * | expand

Commit Message

Greg KH Nov. 23, 2022, 12:25 p.m. UTC
The uevent() callback in struct device_type should not be modifying the
device that is passed into it, so mark it as a const * and propagate the
function signature changes out into all relevant subsystems that use
this callback.

Cc: Jens Axboe <axboe@kernel.dk>
Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Cc: Len Brown <lenb@kernel.org>
Cc: Stefan Richter <stefanr@s5r6.in-berlin.de>
Cc: Wolfram Sang <wsa@kernel.org>
Cc: Alexandre Belloni <alexandre.belloni@bootlin.com>
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: Sean Young <sean@mess.org>
Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Frank Rowand <frowand.list@gmail.com>
Cc: Maximilian Luz <luzmaximilian@gmail.com>
Cc: Hans de Goede <hdegoede@redhat.com>
Cc: Mark Gross <markgross@kernel.org>
Cc: Vinod Koul <vkoul@kernel.org>
Cc: Bard Liao <yung-chuan.liao@linux.intel.com>
Cc: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Cc: Sanyog Kale <sanyog.r.kale@intel.com>
Cc: Andreas Noever <andreas.noever@gmail.com>
Cc: Michael Jamet <michael.jamet@intel.com>
Cc: Mika Westerberg <mika.westerberg@linux.intel.com>
Cc: Yehezkel Bernat <YehezkelShB@gmail.com>
Cc: Jiri Slaby <jirislaby@kernel.org>
Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Cc: "Matthew Wilcox (Oracle)" <willy@infradead.org>
Cc: "Martin K. Petersen" <martin.petersen@oracle.com>
Cc: Chaitanya Kulkarni <kch@nvidia.com>
Cc: Ming Lei <ming.lei@redhat.com>
Cc: Jilin Yuan <yuanjilin@cdjrlc.com>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: Sakari Ailus <sakari.ailus@linux.intel.com>
Cc: Jason Gunthorpe <jgg@ziepe.ca>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ira Weiny <ira.weiny@intel.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Won Chung <wonchung@google.com>
Cc: alsa-devel@alsa-project.org
Cc: devicetree@vger.kernel.org
Cc: linux-acpi@vger.kernel.org
Cc: linux-block@vger.kernel.org
Cc: linux-i2c@vger.kernel.org
Cc: linux-i3c@lists.infradead.org
Cc: linux-input@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-media@vger.kernel.org
Cc: linux-serial@vger.kernel.org
Cc: linux-usb@vger.kernel.org
Cc: linux1394-devel@lists.sourceforge.net
Cc: platform-driver-x86@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 block/partitions/core.c                   |  4 ++--
 drivers/acpi/device_sysfs.c               |  8 ++++----
 drivers/acpi/internal.h                   |  2 +-
 drivers/firewire/core-device.c            |  8 ++++----
 drivers/i2c/i2c-core-base.c               |  4 ++--
 drivers/i3c/device.c                      |  4 ++--
 drivers/i3c/master.c                      |  4 ++--
 drivers/input/input.c                     | 16 ++++++++--------
 drivers/media/rc/rc-main.c                |  2 +-
 drivers/of/device.c                       |  4 ++--
 drivers/platform/surface/aggregator/bus.c |  4 ++--
 drivers/soundwire/bus_type.c              |  4 ++--
 drivers/thunderbolt/switch.c              |  4 ++--
 drivers/thunderbolt/tb.h                  |  2 +-
 drivers/thunderbolt/xdomain.c             |  6 +++---
 drivers/tty/serdev/core.c                 |  2 +-
 drivers/usb/core/message.c                |  8 ++++----
 drivers/usb/core/usb.c                    |  4 ++--
 drivers/usb/phy/phy.c                     |  6 +++---
 drivers/usb/roles/class.c                 |  3 +--
 drivers/usb/typec/class.c                 |  2 +-
 include/linux/acpi.h                      |  4 ++--
 include/linux/device.h                    |  2 +-
 include/linux/firewire.h                  |  6 +++---
 include/linux/i3c/device.h                |  4 ++--
 include/linux/of_device.h                 |  4 ++--
 include/linux/soundwire/sdw_type.h        |  2 +-
 include/linux/surface_aggregator/device.h |  2 +-
 28 files changed, 62 insertions(+), 63 deletions(-)

Comments

Andy Shevchenko Nov. 23, 2022, 1:34 p.m. UTC | #1
On Wed, Nov 23, 2022 at 02:14:31PM +0100, Maximilian Luz wrote:
> On 11/23/22 13:25, Greg Kroah-Hartman wrote:
> > The uevent() callback in struct device_type should not be modifying the
> > device that is passed into it, so mark it as a const * and propagate the
> > function signature changes out into all relevant subsystems that use
> > this callback.

[...]

> > -static inline struct ssam_device *to_ssam_device(struct device *d)
> > +static inline struct ssam_device *to_ssam_device(const struct device *d)
> >   {
> >   	return container_of(d, struct ssam_device, dev);
> >   }
> 
> I am slightly conflicted about this change as that now more or less
> implicitly drops the const. So I'm wondering if it wouldn't be better to
> either create a function specifically for const pointers or to just
> open-code it in the instance above.
> 
> I guess we could also convert this to a macro. Then at least there
> wouldn't be an explicit and potentially misleading const-conversion
> indicated in the function signature.

This is an intermediate step as far as I know since moving container_of to
recognize const is a bit noisy right now. I guess you can find a discussion
on the topic between Greg and Sakari.
Mika Westerberg Nov. 23, 2022, 1:56 p.m. UTC | #2
On Wed, Nov 23, 2022 at 01:25:21PM +0100, Greg Kroah-Hartman wrote:
> The uevent() callback in struct device_type should not be modifying the
> device that is passed into it, so mark it as a const * and propagate the
> function signature changes out into all relevant subsystems that use
> this callback.
> 
> Cc: Jens Axboe <axboe@kernel.dk>
> Cc: "Rafael J. Wysocki" <rafael@kernel.org>
> Cc: Len Brown <lenb@kernel.org>
> Cc: Stefan Richter <stefanr@s5r6.in-berlin.de>
> Cc: Wolfram Sang <wsa@kernel.org>
> Cc: Alexandre Belloni <alexandre.belloni@bootlin.com>
> Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
> Cc: Sean Young <sean@mess.org>
> Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Frank Rowand <frowand.list@gmail.com>
> Cc: Maximilian Luz <luzmaximilian@gmail.com>
> Cc: Hans de Goede <hdegoede@redhat.com>
> Cc: Mark Gross <markgross@kernel.org>
> Cc: Vinod Koul <vkoul@kernel.org>
> Cc: Bard Liao <yung-chuan.liao@linux.intel.com>
> Cc: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> Cc: Sanyog Kale <sanyog.r.kale@intel.com>
> Cc: Andreas Noever <andreas.noever@gmail.com>
> Cc: Michael Jamet <michael.jamet@intel.com>
> Cc: Mika Westerberg <mika.westerberg@linux.intel.com>

Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com> # for Thunderbolt
Matthew Wilcox Nov. 23, 2022, 2:52 p.m. UTC | #3
On Wed, Nov 23, 2022 at 02:59:00PM +0100, Maximilian Luz wrote:
> On 11/23/22 14:34, Andy Shevchenko wrote:
> > On Wed, Nov 23, 2022 at 02:14:31PM +0100, Maximilian Luz wrote:
> > > On 11/23/22 13:25, Greg Kroah-Hartman wrote:
> > > > The uevent() callback in struct device_type should not be modifying the
> > > > device that is passed into it, so mark it as a const * and propagate the
> > > > function signature changes out into all relevant subsystems that use
> > > > this callback.
> > 
> > [...]
> > 
> > > > -static inline struct ssam_device *to_ssam_device(struct device *d)
> > > > +static inline struct ssam_device *to_ssam_device(const struct device *d)
> > > >    {
> > > >    	return container_of(d, struct ssam_device, dev);
> > > >    }
> > > 
> > > I am slightly conflicted about this change as that now more or less
> > > implicitly drops the const. So I'm wondering if it wouldn't be better to
> > > either create a function specifically for const pointers or to just
> > > open-code it in the instance above.
> > > 
> > > I guess we could also convert this to a macro. Then at least there
> > > wouldn't be an explicit and potentially misleading const-conversion
> > > indicated in the function signature.
> > 
> > This is an intermediate step as far as I know since moving container_of to
> > recognize const is a bit noisy right now. I guess you can find a discussion
> > on the topic between Greg and Sakari.
> 
> Thanks! I assume you are referring to the following?
> 
> 	https://lore.kernel.org/lkml/4218173bd72b4f1899d4c41a8e251f0d@AcuMS.aculab.com/T/
> 
> As far as I can tell this is only a warning in documentation, not
> compile time (which would probably be impossible?).
> 
> As I've said I'd be fine with converting the function to a macro (and
> preferably adding a similar warning like the one proposed in that
> thread). The point that irks me up is just that, as proposed, the
> function signature would now advertise a conversion that should never be
> happening.
> 
> Having two separate functions would create a compile-time guarantee, so
> I'd prefer that, but I can understand if that might be considered too
> noisy in code. Or if there is a push to make container_of() emit a
> compile-time warning I'd also be perfectly happy with converting it to a
> macro now as that'd alleviate the need for functions in the future.

Can't we do:

static inline const struct ssam_device *to_ssam_device(const struct device *d)
{
	return container_of(d, const struct ssam_device, dev);
}
Maximilian Luz Nov. 23, 2022, 3:14 p.m. UTC | #4
On 11/23/22 15:52, Matthew Wilcox wrote:
> On Wed, Nov 23, 2022 at 02:59:00PM +0100, Maximilian Luz wrote:
>> On 11/23/22 14:34, Andy Shevchenko wrote:
>>> On Wed, Nov 23, 2022 at 02:14:31PM +0100, Maximilian Luz wrote:
>>>> On 11/23/22 13:25, Greg Kroah-Hartman wrote:
>>>>> The uevent() callback in struct device_type should not be modifying the
>>>>> device that is passed into it, so mark it as a const * and propagate the
>>>>> function signature changes out into all relevant subsystems that use
>>>>> this callback.
>>>
>>> [...]
>>>
>>>>> -static inline struct ssam_device *to_ssam_device(struct device *d)
>>>>> +static inline struct ssam_device *to_ssam_device(const struct device *d)
>>>>>     {
>>>>>     	return container_of(d, struct ssam_device, dev);
>>>>>     }
>>>>
>>>> I am slightly conflicted about this change as that now more or less
>>>> implicitly drops the const. So I'm wondering if it wouldn't be better to
>>>> either create a function specifically for const pointers or to just
>>>> open-code it in the instance above.
>>>>
>>>> I guess we could also convert this to a macro. Then at least there
>>>> wouldn't be an explicit and potentially misleading const-conversion
>>>> indicated in the function signature.
>>>
>>> This is an intermediate step as far as I know since moving container_of to
>>> recognize const is a bit noisy right now. I guess you can find a discussion
>>> on the topic between Greg and Sakari.
>>
>> Thanks! I assume you are referring to the following?
>>
>> 	https://lore.kernel.org/lkml/4218173bd72b4f1899d4c41a8e251f0d@AcuMS.aculab.com/T/
>>
>> As far as I can tell this is only a warning in documentation, not
>> compile time (which would probably be impossible?).
>>
>> As I've said I'd be fine with converting the function to a macro (and
>> preferably adding a similar warning like the one proposed in that
>> thread). The point that irks me up is just that, as proposed, the
>> function signature would now advertise a conversion that should never be
>> happening.
>>
>> Having two separate functions would create a compile-time guarantee, so
>> I'd prefer that, but I can understand if that might be considered too
>> noisy in code. Or if there is a push to make container_of() emit a
>> compile-time warning I'd also be perfectly happy with converting it to a
>> macro now as that'd alleviate the need for functions in the future.
> 
> Can't we do:
> 
> static inline const struct ssam_device *to_ssam_device(const struct device *d)
> {
> 	return container_of(d, const struct ssam_device, dev);
> }

There are at least a couple of places (device/driver-management and
device-removal related, I think) using this function and requiring
non-const access.

A bunch of other instances could be converted to const-access only, but
that would require a couple more function signature changes (I should
probably set up a patch for that regardless of this here as being a bit
more strict about this makes sense).

Regards,
Max
Greg KH Nov. 23, 2022, 3:37 p.m. UTC | #5
On Wed, Nov 23, 2022 at 02:52:59PM +0000, Matthew Wilcox wrote:
> On Wed, Nov 23, 2022 at 02:59:00PM +0100, Maximilian Luz wrote:
> > On 11/23/22 14:34, Andy Shevchenko wrote:
> > > On Wed, Nov 23, 2022 at 02:14:31PM +0100, Maximilian Luz wrote:
> > > > On 11/23/22 13:25, Greg Kroah-Hartman wrote:
> > > > > The uevent() callback in struct device_type should not be modifying the
> > > > > device that is passed into it, so mark it as a const * and propagate the
> > > > > function signature changes out into all relevant subsystems that use
> > > > > this callback.
> > > 
> > > [...]
> > > 
> > > > > -static inline struct ssam_device *to_ssam_device(struct device *d)
> > > > > +static inline struct ssam_device *to_ssam_device(const struct device *d)
> > > > >    {
> > > > >    	return container_of(d, struct ssam_device, dev);
> > > > >    }
> > > > 
> > > > I am slightly conflicted about this change as that now more or less
> > > > implicitly drops the const. So I'm wondering if it wouldn't be better to
> > > > either create a function specifically for const pointers or to just
> > > > open-code it in the instance above.
> > > > 
> > > > I guess we could also convert this to a macro. Then at least there
> > > > wouldn't be an explicit and potentially misleading const-conversion
> > > > indicated in the function signature.
> > > 
> > > This is an intermediate step as far as I know since moving container_of to
> > > recognize const is a bit noisy right now. I guess you can find a discussion
> > > on the topic between Greg and Sakari.
> > 
> > Thanks! I assume you are referring to the following?
> > 
> > 	https://lore.kernel.org/lkml/4218173bd72b4f1899d4c41a8e251f0d@AcuMS.aculab.com/T/
> > 
> > As far as I can tell this is only a warning in documentation, not
> > compile time (which would probably be impossible?).
> > 
> > As I've said I'd be fine with converting the function to a macro (and
> > preferably adding a similar warning like the one proposed in that
> > thread). The point that irks me up is just that, as proposed, the
> > function signature would now advertise a conversion that should never be
> > happening.
> > 
> > Having two separate functions would create a compile-time guarantee, so
> > I'd prefer that, but I can understand if that might be considered too
> > noisy in code. Or if there is a push to make container_of() emit a
> > compile-time warning I'd also be perfectly happy with converting it to a
> > macro now as that'd alleviate the need for functions in the future.
> 
> Can't we do:
> 
> static inline const struct ssam_device *to_ssam_device(const struct device *d)
> {
> 	return container_of(d, const struct ssam_device, dev);
> }
> 

You could, if you can always handle a const pointer coming out of this
function, but I don't think you can.

What you might want to do instead, and I'll be glad to do it for all of
the functions like this I change, is to do what we have for struct
device now:

static inline struct device *__kobj_to_dev(struct kobject *kobj)
{
        return container_of(kobj, struct device, kobj);
}

static inline const struct device *__kobj_to_dev_const(const struct kobject *kobj)
{
        return container_of(kobj, const struct device, kobj);
}

/*
 * container_of() will happily take a const * and spit back a non-const * as it
 * is just doing pointer math.  But we want to be a bit more careful in the
 * driver code, so manually force any const * of a kobject to also be a const *
 * to a device.
 */
#define kobj_to_dev(kobj)                                       \
        _Generic((kobj),                                        \
                 const struct kobject *: __kobj_to_dev_const,   \
                 struct kobject *: __kobj_to_dev)(kobj)


Want me to do the same thing here as well?

thanks,

greg k-h
Maximilian Luz Nov. 23, 2022, 3:48 p.m. UTC | #6
On 11/23/22 16:37, Greg Kroah-Hartman wrote:
> On Wed, Nov 23, 2022 at 02:52:59PM +0000, Matthew Wilcox wrote:
>> On Wed, Nov 23, 2022 at 02:59:00PM +0100, Maximilian Luz wrote:
>>> On 11/23/22 14:34, Andy Shevchenko wrote:
>>>> On Wed, Nov 23, 2022 at 02:14:31PM +0100, Maximilian Luz wrote:
>>>>> On 11/23/22 13:25, Greg Kroah-Hartman wrote:
>>>>>> The uevent() callback in struct device_type should not be modifying the
>>>>>> device that is passed into it, so mark it as a const * and propagate the
>>>>>> function signature changes out into all relevant subsystems that use
>>>>>> this callback.
>>>>
>>>> [...]
>>>>
>>>>>> -static inline struct ssam_device *to_ssam_device(struct device *d)
>>>>>> +static inline struct ssam_device *to_ssam_device(const struct device *d)
>>>>>>     {
>>>>>>     	return container_of(d, struct ssam_device, dev);
>>>>>>     }
>>>>>
>>>>> I am slightly conflicted about this change as that now more or less
>>>>> implicitly drops the const. So I'm wondering if it wouldn't be better to
>>>>> either create a function specifically for const pointers or to just
>>>>> open-code it in the instance above.
>>>>>
>>>>> I guess we could also convert this to a macro. Then at least there
>>>>> wouldn't be an explicit and potentially misleading const-conversion
>>>>> indicated in the function signature.
>>>>
>>>> This is an intermediate step as far as I know since moving container_of to
>>>> recognize const is a bit noisy right now. I guess you can find a discussion
>>>> on the topic between Greg and Sakari.
>>>
>>> Thanks! I assume you are referring to the following?
>>>
>>> 	https://lore.kernel.org/lkml/4218173bd72b4f1899d4c41a8e251f0d@AcuMS.aculab.com/T/
>>>
>>> As far as I can tell this is only a warning in documentation, not
>>> compile time (which would probably be impossible?).
>>>
>>> As I've said I'd be fine with converting the function to a macro (and
>>> preferably adding a similar warning like the one proposed in that
>>> thread). The point that irks me up is just that, as proposed, the
>>> function signature would now advertise a conversion that should never be
>>> happening.
>>>
>>> Having two separate functions would create a compile-time guarantee, so
>>> I'd prefer that, but I can understand if that might be considered too
>>> noisy in code. Or if there is a push to make container_of() emit a
>>> compile-time warning I'd also be perfectly happy with converting it to a
>>> macro now as that'd alleviate the need for functions in the future.
>>
>> Can't we do:
>>
>> static inline const struct ssam_device *to_ssam_device(const struct device *d)
>> {
>> 	return container_of(d, const struct ssam_device, dev);
>> }
>>
> 
> You could, if you can always handle a const pointer coming out of this
> function, but I don't think you can.
> 
> What you might want to do instead, and I'll be glad to do it for all of
> the functions like this I change, is to do what we have for struct
> device now:
> 
> static inline struct device *__kobj_to_dev(struct kobject *kobj)
> {
>          return container_of(kobj, struct device, kobj);
> }
> 
> static inline const struct device *__kobj_to_dev_const(const struct kobject *kobj)
> {
>          return container_of(kobj, const struct device, kobj);
> }
> 
> /*
>   * container_of() will happily take a const * and spit back a non-const * as it
>   * is just doing pointer math.  But we want to be a bit more careful in the
>   * driver code, so manually force any const * of a kobject to also be a const *
>   * to a device.
>   */
> #define kobj_to_dev(kobj)                                       \
>          _Generic((kobj),                                        \
>                   const struct kobject *: __kobj_to_dev_const,   \
>                   struct kobject *: __kobj_to_dev)(kobj)
> 
> 
> Want me to do the same thing here as well?

That looks great! Thanks!

I would very much prefer that.

Regards,
Max
Greg KH Nov. 23, 2022, 3:52 p.m. UTC | #7
On Wed, Nov 23, 2022 at 04:48:41PM +0100, Maximilian Luz wrote:
> On 11/23/22 16:37, Greg Kroah-Hartman wrote:
> > On Wed, Nov 23, 2022 at 02:52:59PM +0000, Matthew Wilcox wrote:
> > > On Wed, Nov 23, 2022 at 02:59:00PM +0100, Maximilian Luz wrote:
> > > > On 11/23/22 14:34, Andy Shevchenko wrote:
> > > > > On Wed, Nov 23, 2022 at 02:14:31PM +0100, Maximilian Luz wrote:
> > > > > > On 11/23/22 13:25, Greg Kroah-Hartman wrote:
> > > > > > > The uevent() callback in struct device_type should not be modifying the
> > > > > > > device that is passed into it, so mark it as a const * and propagate the
> > > > > > > function signature changes out into all relevant subsystems that use
> > > > > > > this callback.
> > > > > 
> > > > > [...]
> > > > > 
> > > > > > > -static inline struct ssam_device *to_ssam_device(struct device *d)
> > > > > > > +static inline struct ssam_device *to_ssam_device(const struct device *d)
> > > > > > >     {
> > > > > > >     	return container_of(d, struct ssam_device, dev);
> > > > > > >     }
> > > > > > 
> > > > > > I am slightly conflicted about this change as that now more or less
> > > > > > implicitly drops the const. So I'm wondering if it wouldn't be better to
> > > > > > either create a function specifically for const pointers or to just
> > > > > > open-code it in the instance above.
> > > > > > 
> > > > > > I guess we could also convert this to a macro. Then at least there
> > > > > > wouldn't be an explicit and potentially misleading const-conversion
> > > > > > indicated in the function signature.
> > > > > 
> > > > > This is an intermediate step as far as I know since moving container_of to
> > > > > recognize const is a bit noisy right now. I guess you can find a discussion
> > > > > on the topic between Greg and Sakari.
> > > > 
> > > > Thanks! I assume you are referring to the following?
> > > > 
> > > > 	https://lore.kernel.org/lkml/4218173bd72b4f1899d4c41a8e251f0d@AcuMS.aculab.com/T/
> > > > 
> > > > As far as I can tell this is only a warning in documentation, not
> > > > compile time (which would probably be impossible?).
> > > > 
> > > > As I've said I'd be fine with converting the function to a macro (and
> > > > preferably adding a similar warning like the one proposed in that
> > > > thread). The point that irks me up is just that, as proposed, the
> > > > function signature would now advertise a conversion that should never be
> > > > happening.
> > > > 
> > > > Having two separate functions would create a compile-time guarantee, so
> > > > I'd prefer that, but I can understand if that might be considered too
> > > > noisy in code. Or if there is a push to make container_of() emit a
> > > > compile-time warning I'd also be perfectly happy with converting it to a
> > > > macro now as that'd alleviate the need for functions in the future.
> > > 
> > > Can't we do:
> > > 
> > > static inline const struct ssam_device *to_ssam_device(const struct device *d)
> > > {
> > > 	return container_of(d, const struct ssam_device, dev);
> > > }
> > > 
> > 
> > You could, if you can always handle a const pointer coming out of this
> > function, but I don't think you can.
> > 
> > What you might want to do instead, and I'll be glad to do it for all of
> > the functions like this I change, is to do what we have for struct
> > device now:
> > 
> > static inline struct device *__kobj_to_dev(struct kobject *kobj)
> > {
> >          return container_of(kobj, struct device, kobj);
> > }
> > 
> > static inline const struct device *__kobj_to_dev_const(const struct kobject *kobj)
> > {
> >          return container_of(kobj, const struct device, kobj);
> > }
> > 
> > /*
> >   * container_of() will happily take a const * and spit back a non-const * as it
> >   * is just doing pointer math.  But we want to be a bit more careful in the
> >   * driver code, so manually force any const * of a kobject to also be a const *
> >   * to a device.
> >   */
> > #define kobj_to_dev(kobj)                                       \
> >          _Generic((kobj),                                        \
> >                   const struct kobject *: __kobj_to_dev_const,   \
> >                   struct kobject *: __kobj_to_dev)(kobj)
> > 
> > 
> > Want me to do the same thing here as well?
> 
> That looks great! Thanks!
> 
> I would very much prefer that.

Ok, will respin this patch as at least 2 individual patches, one that
does the change to to_ssam_device() and the next that does the bus-wide
changes.

I'll review the other container_of() users in this patch as well to see
if they can be converted as well.

thanks,

greg k-h
Jason Gunthorpe Nov. 23, 2022, 4:25 p.m. UTC | #8
On Wed, Nov 23, 2022 at 04:37:59PM +0100, Greg Kroah-Hartman wrote:
> static inline struct device *__kobj_to_dev(struct kobject *kobj)
> {
>         return container_of(kobj, struct device, kobj);
> }
> 
> static inline const struct device *__kobj_to_dev_const(const struct kobject *kobj)
> {
>         return container_of(kobj, const struct device, kobj);
> }
> 
> /*
>  * container_of() will happily take a const * and spit back a non-const * as it
>  * is just doing pointer math.  But we want to be a bit more careful in the
>  * driver code, so manually force any const * of a kobject to also be a const *
>  * to a device.
>  */
> #define kobj_to_dev(kobj)                                       \
>         _Generic((kobj),                                        \
>                  const struct kobject *: __kobj_to_dev_const,   \
>                  struct kobject *: __kobj_to_dev)(kobj)
> 
> 
> Want me to do the same thing here as well?

It would be nice to have a shared macro code gen all of the above
instead of copy and pasting it. Then maybe other cases beyond struct
device could adopt const too..

Jason
Greg KH Nov. 23, 2022, 5:01 p.m. UTC | #9
On Wed, Nov 23, 2022 at 12:25:32PM -0400, Jason Gunthorpe wrote:
> On Wed, Nov 23, 2022 at 04:37:59PM +0100, Greg Kroah-Hartman wrote:
> > static inline struct device *__kobj_to_dev(struct kobject *kobj)
> > {
> >         return container_of(kobj, struct device, kobj);
> > }
> > 
> > static inline const struct device *__kobj_to_dev_const(const struct kobject *kobj)
> > {
> >         return container_of(kobj, const struct device, kobj);
> > }
> > 
> > /*
> >  * container_of() will happily take a const * and spit back a non-const * as it
> >  * is just doing pointer math.  But we want to be a bit more careful in the
> >  * driver code, so manually force any const * of a kobject to also be a const *
> >  * to a device.
> >  */
> > #define kobj_to_dev(kobj)                                       \
> >         _Generic((kobj),                                        \
> >                  const struct kobject *: __kobj_to_dev_const,   \
> >                  struct kobject *: __kobj_to_dev)(kobj)
> > 
> > 
> > Want me to do the same thing here as well?
> 
> It would be nice to have a shared macro code gen all of the above
> instead of copy and pasting it. Then maybe other cases beyond struct
> device could adopt const too..

I think I tried to create such a beast, but failed, so ended up
open-coding it in a few places in the USB headers already.  I can try it
again, but the redirection gets tricky (defines creating defines...)

thanks,

greg k-h
Jason Gunthorpe Nov. 23, 2022, 5:29 p.m. UTC | #10
On Wed, Nov 23, 2022 at 06:01:47PM +0100, Greg Kroah-Hartman wrote:
> On Wed, Nov 23, 2022 at 12:25:32PM -0400, Jason Gunthorpe wrote:
> > On Wed, Nov 23, 2022 at 04:37:59PM +0100, Greg Kroah-Hartman wrote:
> > > static inline struct device *__kobj_to_dev(struct kobject *kobj)
> > > {
> > >         return container_of(kobj, struct device, kobj);
> > > }
> > > 
> > > static inline const struct device *__kobj_to_dev_const(const struct kobject *kobj)
> > > {
> > >         return container_of(kobj, const struct device, kobj);
> > > }
> > > 
> > > /*
> > >  * container_of() will happily take a const * and spit back a non-const * as it
> > >  * is just doing pointer math.  But we want to be a bit more careful in the
> > >  * driver code, so manually force any const * of a kobject to also be a const *
> > >  * to a device.
> > >  */
> > > #define kobj_to_dev(kobj)                                       \
> > >         _Generic((kobj),                                        \
> > >                  const struct kobject *: __kobj_to_dev_const,   \
> > >                  struct kobject *: __kobj_to_dev)(kobj)
> > > 
> > > 
> > > Want me to do the same thing here as well?
> > 
> > It would be nice to have a shared macro code gen all of the above
> > instead of copy and pasting it. Then maybe other cases beyond struct
> > device could adopt const too..
> 
> I think I tried to create such a beast, but failed, so ended up
> open-coding it in a few places in the USB headers already.  I can try it
> again, but the redirection gets tricky (defines creating defines...)

This seems OK:

#define generic_container_of(in_type, in, out_type, out_member) \
	_Generic(in,                                        \
                  const in_type *: ((const out_type *)container_of(in, out_type, out_member)),   \
                  in_type *: ((out_type *)container_of(in, out_type, out_member)) \
		  )

#define kobj_to_dev(__kobj) \
	generic_container_of(struct kobject, __kobj, struct device, kobj)

Jason
Matthew Wilcox Nov. 23, 2022, 5:49 p.m. UTC | #11
On Wed, Nov 23, 2022 at 01:29:56PM -0400, Jason Gunthorpe wrote:
> #define generic_container_of(in_type, in, out_type, out_member) \
> 	_Generic(in,                                        \
>                   const in_type *: ((const out_type *)container_of(in, out_type, out_member)),   \
>                   in_type *: ((out_type *)container_of(in, out_type, out_member)) \
> 		  )

There's a neat trick I found in seqlock.h:

#define generic_container_of(in_t, in, out_t, m)			\
	_Generic(*(in),							\
		const in_t: ((const out_t *)container_of(in, out_t, m)), \
		in_t: ((out_t *)container_of(in, out_type, m))	\
	)

and now it fits in 80 columns ;-)

> #define kobj_to_dev(__kobj) \
> 	generic_container_of(struct kobject, __kobj, struct device, kobj)
> 
> Jason
Jason Gunthorpe Nov. 23, 2022, 5:55 p.m. UTC | #12
On Wed, Nov 23, 2022 at 05:49:36PM +0000, Matthew Wilcox wrote:
> On Wed, Nov 23, 2022 at 01:29:56PM -0400, Jason Gunthorpe wrote:
> > #define generic_container_of(in_type, in, out_type, out_member) \
> > 	_Generic(in,                                        \
> >                   const in_type *: ((const out_type *)container_of(in, out_type, out_member)),   \
> >                   in_type *: ((out_type *)container_of(in, out_type, out_member)) \
> > 		  )
> 
> There's a neat trick I found in seqlock.h:
> 
> #define generic_container_of(in_t, in, out_t, m)			\
> 	_Generic(*(in),							\
> 		const in_t: ((const out_t *)container_of(in, out_t, m)), \
> 		in_t: ((out_t *)container_of(in, out_type, m))	\
> 	)
>
> and now it fits in 80 columns ;-)

Aside from less letters, is their another benifit to using *(in) ?

Jason
Greg KH Nov. 23, 2022, 6:10 p.m. UTC | #13
On Wed, Nov 23, 2022 at 05:49:36PM +0000, Matthew Wilcox wrote:
> On Wed, Nov 23, 2022 at 01:29:56PM -0400, Jason Gunthorpe wrote:
> > #define generic_container_of(in_type, in, out_type, out_member) \
> > 	_Generic(in,                                        \
> >                   const in_type *: ((const out_type *)container_of(in, out_type, out_member)),   \
> >                   in_type *: ((out_type *)container_of(in, out_type, out_member)) \
> > 		  )
> 
> There's a neat trick I found in seqlock.h:
> 
> #define generic_container_of(in_t, in, out_t, m)			\
> 	_Generic(*(in),							\
> 		const in_t: ((const out_t *)container_of(in, out_t, m)), \
> 		in_t: ((out_t *)container_of(in, out_type, m))	\
> 	)
> 
> and now it fits in 80 columns ;-)

Nice trick!  Dropping the inline functions is a bit different, let me
see if that still gives a sane error if we pass an incorrect type or
mess with the const * the wrong way.  I'll run some tests tomorrow
afternoon...

thanks,

greg k-h
Greg KH Nov. 23, 2022, 7:06 p.m. UTC | #14
On Wed, Nov 23, 2022 at 02:25:59PM -0400, Jason Gunthorpe wrote:
> On Wed, Nov 23, 2022 at 07:10:49PM +0100, Greg Kroah-Hartman wrote:
> > On Wed, Nov 23, 2022 at 05:49:36PM +0000, Matthew Wilcox wrote:
> > > On Wed, Nov 23, 2022 at 01:29:56PM -0400, Jason Gunthorpe wrote:
> > > > #define generic_container_of(in_type, in, out_type, out_member) \
> > > > 	_Generic(in,                                        \
> > > >                   const in_type *: ((const out_type *)container_of(in, out_type, out_member)),   \
> > > >                   in_type *: ((out_type *)container_of(in, out_type, out_member)) \
> > > > 		  )
> > > 
> > > There's a neat trick I found in seqlock.h:
> > > 
> > > #define generic_container_of(in_t, in, out_t, m)			\
> > > 	_Generic(*(in),							\
> > > 		const in_t: ((const out_t *)container_of(in, out_t, m)), \
> > > 		in_t: ((out_t *)container_of(in, out_type, m))	\
> > > 	)
> > > 
> > > and now it fits in 80 columns ;-)
> > 
> > Nice trick!  Dropping the inline functions is a bit different, let me
> > see if that still gives a sane error if we pass an incorrect type or
> > mess with the const * the wrong way.  I'll run some tests tomorrow
> > afternoon...
> 
> The errors in some cases are very verbose, but it is somewhat
> understandable - the worst is when _Generic fails to match anything,
> but also at least clang partially expanded container_of and it throws
> other assertions too.
> 
> I also wonder if this could just be rolled into the normal
> container_of.

I think we might be able to now, my previous attempts with inline
functions prevented that.  I'll beat on that tomorrow...

> in_type would have to be derived like:
> 
>   in_type = typeof((out_type *)NULL)->out_member)
> 
> But I don't know if you can use typeof in a generic type matching expression..

Maybe that is what threw me before, I can't remember.  I do know we
tried a number of different attempts, can't recall the failed ones...

thanks,

greg k-h
Mauro Carvalho Chehab Nov. 25, 2022, 11:56 a.m. UTC | #15
Em Wed, 23 Nov 2022 13:25:21 +0100
Greg Kroah-Hartman <gregkh@linuxfoundation.org> escreveu:

> The uevent() callback in struct device_type should not be modifying the
> device that is passed into it, so mark it as a const * and propagate the
> function signature changes out into all relevant subsystems that use
> this callback.

Acked-by: Mauro Carvalho Chehab <mchehab@kernel.org>

> 
> Cc: Jens Axboe <axboe@kernel.dk>
> Cc: "Rafael J. Wysocki" <rafael@kernel.org>
> Cc: Len Brown <lenb@kernel.org>
> Cc: Stefan Richter <stefanr@s5r6.in-berlin.de>
> Cc: Wolfram Sang <wsa@kernel.org>
> Cc: Alexandre Belloni <alexandre.belloni@bootlin.com>
> Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
> Cc: Sean Young <sean@mess.org>
> Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Frank Rowand <frowand.list@gmail.com>
> Cc: Maximilian Luz <luzmaximilian@gmail.com>
> Cc: Hans de Goede <hdegoede@redhat.com>
> Cc: Mark Gross <markgross@kernel.org>
> Cc: Vinod Koul <vkoul@kernel.org>
> Cc: Bard Liao <yung-chuan.liao@linux.intel.com>
> Cc: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> Cc: Sanyog Kale <sanyog.r.kale@intel.com>
> Cc: Andreas Noever <andreas.noever@gmail.com>
> Cc: Michael Jamet <michael.jamet@intel.com>
> Cc: Mika Westerberg <mika.westerberg@linux.intel.com>
> Cc: Yehezkel Bernat <YehezkelShB@gmail.com>
> Cc: Jiri Slaby <jirislaby@kernel.org>
> Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> Cc: "Matthew Wilcox (Oracle)" <willy@infradead.org>
> Cc: "Martin K. Petersen" <martin.petersen@oracle.com>
> Cc: Chaitanya Kulkarni <kch@nvidia.com>
> Cc: Ming Lei <ming.lei@redhat.com>
> Cc: Jilin Yuan <yuanjilin@cdjrlc.com>
> Cc: Alan Stern <stern@rowland.harvard.edu>
> Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> Cc: Sakari Ailus <sakari.ailus@linux.intel.com>
> Cc: Jason Gunthorpe <jgg@ziepe.ca>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Ira Weiny <ira.weiny@intel.com>
> Cc: Dan Williams <dan.j.williams@intel.com>
> Cc: Won Chung <wonchung@google.com>
> Cc: alsa-devel@alsa-project.org
> Cc: devicetree@vger.kernel.org
> Cc: linux-acpi@vger.kernel.org
> Cc: linux-block@vger.kernel.org
> Cc: linux-i2c@vger.kernel.org
> Cc: linux-i3c@lists.infradead.org
> Cc: linux-input@vger.kernel.org
> Cc: linux-kernel@vger.kernel.org
> Cc: linux-media@vger.kernel.org
> Cc: linux-serial@vger.kernel.org
> Cc: linux-usb@vger.kernel.org
> Cc: linux1394-devel@lists.sourceforge.net
> Cc: platform-driver-x86@vger.kernel.org
> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> ---
>  block/partitions/core.c                   |  4 ++--
>  drivers/acpi/device_sysfs.c               |  8 ++++----
>  drivers/acpi/internal.h                   |  2 +-
>  drivers/firewire/core-device.c            |  8 ++++----
>  drivers/i2c/i2c-core-base.c               |  4 ++--
>  drivers/i3c/device.c                      |  4 ++--
>  drivers/i3c/master.c                      |  4 ++--
>  drivers/input/input.c                     | 16 ++++++++--------
>  drivers/media/rc/rc-main.c                |  2 +-
>  drivers/of/device.c                       |  4 ++--
>  drivers/platform/surface/aggregator/bus.c |  4 ++--
>  drivers/soundwire/bus_type.c              |  4 ++--
>  drivers/thunderbolt/switch.c              |  4 ++--
>  drivers/thunderbolt/tb.h                  |  2 +-
>  drivers/thunderbolt/xdomain.c             |  6 +++---
>  drivers/tty/serdev/core.c                 |  2 +-
>  drivers/usb/core/message.c                |  8 ++++----
>  drivers/usb/core/usb.c                    |  4 ++--
>  drivers/usb/phy/phy.c                     |  6 +++---
>  drivers/usb/roles/class.c                 |  3 +--
>  drivers/usb/typec/class.c                 |  2 +-
>  include/linux/acpi.h                      |  4 ++--
>  include/linux/device.h                    |  2 +-
>  include/linux/firewire.h                  |  6 +++---
>  include/linux/i3c/device.h                |  4 ++--
>  include/linux/of_device.h                 |  4 ++--
>  include/linux/soundwire/sdw_type.h        |  2 +-
>  include/linux/surface_aggregator/device.h |  2 +-
>  28 files changed, 62 insertions(+), 63 deletions(-)
> 
> diff --git a/block/partitions/core.c b/block/partitions/core.c
> index b8112f52d388..7b8ef6296abd 100644
> --- a/block/partitions/core.c
> +++ b/block/partitions/core.c
> @@ -254,9 +254,9 @@ static void part_release(struct device *dev)
>  	iput(dev_to_bdev(dev)->bd_inode);
>  }
>  
> -static int part_uevent(struct device *dev, struct kobj_uevent_env *env)
> +static int part_uevent(const struct device *dev, struct kobj_uevent_env *env)
>  {
> -	struct block_device *part = dev_to_bdev(dev);
> +	const struct block_device *part = dev_to_bdev(dev);
>  
>  	add_uevent_var(env, "PARTN=%u", part->bd_partno);
>  	if (part->bd_meta_info && part->bd_meta_info->volname[0])
> diff --git a/drivers/acpi/device_sysfs.c b/drivers/acpi/device_sysfs.c
> index 120873dad2cc..daff2c0c5c52 100644
> --- a/drivers/acpi/device_sysfs.c
> +++ b/drivers/acpi/device_sysfs.c
> @@ -133,7 +133,7 @@ static void acpi_hide_nondev_subnodes(struct acpi_device_data *data)
>   *         -EINVAL: output error
>   *         -ENOMEM: output is truncated
>   */
> -static int create_pnp_modalias(struct acpi_device *acpi_dev, char *modalias,
> +static int create_pnp_modalias(const struct acpi_device *acpi_dev, char *modalias,
>  			       int size)
>  {
>  	int len;
> @@ -191,7 +191,7 @@ static int create_pnp_modalias(struct acpi_device *acpi_dev, char *modalias,
>   * only be called for devices having ACPI_DT_NAMESPACE_HID in their list of
>   * ACPI/PNP IDs.
>   */
> -static int create_of_modalias(struct acpi_device *acpi_dev, char *modalias,
> +static int create_of_modalias(const struct acpi_device *acpi_dev, char *modalias,
>  			      int size)
>  {
>  	struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
> @@ -239,7 +239,7 @@ static int create_of_modalias(struct acpi_device *acpi_dev, char *modalias,
>  	return len;
>  }
>  
> -int __acpi_device_uevent_modalias(struct acpi_device *adev,
> +int __acpi_device_uevent_modalias(const struct acpi_device *adev,
>  				  struct kobj_uevent_env *env)
>  {
>  	int len;
> @@ -277,7 +277,7 @@ int __acpi_device_uevent_modalias(struct acpi_device *adev,
>   * Because other buses do not support ACPI HIDs & CIDs, e.g. for a device with
>   * hid:IBM0001 and cid:ACPI0001 you get: "acpi:IBM0001:ACPI0001".
>   */
> -int acpi_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env)
> +int acpi_device_uevent_modalias(const struct device *dev, struct kobj_uevent_env *env)
>  {
>  	return __acpi_device_uevent_modalias(acpi_companion_match(dev), env);
>  }
> diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
> index 219c02df9a08..d422884eb3d0 100644
> --- a/drivers/acpi/internal.h
> +++ b/drivers/acpi/internal.h
> @@ -120,7 +120,7 @@ int acpi_bus_register_early_device(int type);
>                       Device Matching and Notification
>     -------------------------------------------------------------------------- */
>  struct acpi_device *acpi_companion_match(const struct device *dev);
> -int __acpi_device_uevent_modalias(struct acpi_device *adev,
> +int __acpi_device_uevent_modalias(const struct acpi_device *adev,
>  				  struct kobj_uevent_env *env);
>  
>  /* --------------------------------------------------------------------------
> diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c
> index adddd8c45d0c..aa597cda0d88 100644
> --- a/drivers/firewire/core-device.c
> +++ b/drivers/firewire/core-device.c
> @@ -133,7 +133,7 @@ static void get_ids(const u32 *directory, int *id)
>  	}
>  }
>  
> -static void get_modalias_ids(struct fw_unit *unit, int *id)
> +static void get_modalias_ids(const struct fw_unit *unit, int *id)
>  {
>  	get_ids(&fw_parent_device(unit)->config_rom[5], id);
>  	get_ids(unit->directory, id);
> @@ -195,7 +195,7 @@ static void fw_unit_remove(struct device *dev)
>  	driver->remove(fw_unit(dev));
>  }
>  
> -static int get_modalias(struct fw_unit *unit, char *buffer, size_t buffer_size)
> +static int get_modalias(const struct fw_unit *unit, char *buffer, size_t buffer_size)
>  {
>  	int id[] = {0, 0, 0, 0};
>  
> @@ -206,9 +206,9 @@ static int get_modalias(struct fw_unit *unit, char *buffer, size_t buffer_size)
>  			id[0], id[1], id[2], id[3]);
>  }
>  
> -static int fw_unit_uevent(struct device *dev, struct kobj_uevent_env *env)
> +static int fw_unit_uevent(const struct device *dev, struct kobj_uevent_env *env)
>  {
> -	struct fw_unit *unit = fw_unit(dev);
> +	const struct fw_unit *unit = fw_unit(dev);
>  	char modalias[64];
>  
>  	get_modalias(unit, modalias, sizeof(modalias));
> diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
> index b4edf10e8fd0..fb16e33e52c6 100644
> --- a/drivers/i2c/i2c-core-base.c
> +++ b/drivers/i2c/i2c-core-base.c
> @@ -136,9 +136,9 @@ static int i2c_device_match(struct device *dev, struct device_driver *drv)
>  	return 0;
>  }
>  
> -static int i2c_device_uevent(struct device *dev, struct kobj_uevent_env *env)
> +static int i2c_device_uevent(const struct device *dev, struct kobj_uevent_env *env)
>  {
> -	struct i2c_client *client = to_i2c_client(dev);
> +	const struct i2c_client *client = to_i2c_client(dev);
>  	int rc;
>  
>  	rc = of_device_uevent_modalias(dev, env);
> diff --git a/drivers/i3c/device.c b/drivers/i3c/device.c
> index e92d3e9a52bd..05f8ab762e34 100644
> --- a/drivers/i3c/device.c
> +++ b/drivers/i3c/device.c
> @@ -58,7 +58,7 @@ EXPORT_SYMBOL_GPL(i3c_device_do_priv_xfers);
>   *
>   * Retrieve I3C dev info.
>   */
> -void i3c_device_get_info(struct i3c_device *dev,
> +void i3c_device_get_info(const struct i3c_device *dev,
>  			 struct i3c_device_info *info)
>  {
>  	if (!info)
> @@ -194,7 +194,7 @@ EXPORT_SYMBOL_GPL(i3cdev_to_dev);
>   *
>   * Return: a pointer to an I3C device object.
>   */
> -struct i3c_device *dev_to_i3cdev(struct device *dev)
> +struct i3c_device *dev_to_i3cdev(const struct device *dev)
>  {
>  	return container_of(dev, struct i3c_device, dev);
>  }
> diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
> index 351c81a929a6..bf1a2b2f34c4 100644
> --- a/drivers/i3c/master.c
> +++ b/drivers/i3c/master.c
> @@ -273,9 +273,9 @@ static struct attribute *i3c_device_attrs[] = {
>  };
>  ATTRIBUTE_GROUPS(i3c_device);
>  
> -static int i3c_device_uevent(struct device *dev, struct kobj_uevent_env *env)
> +static int i3c_device_uevent(const struct device *dev, struct kobj_uevent_env *env)
>  {
> -	struct i3c_device *i3cdev = dev_to_i3cdev(dev);
> +	const struct i3c_device *i3cdev = dev_to_i3cdev(dev);
>  	struct i3c_device_info devinfo;
>  	u16 manuf, part, ext;
>  
> diff --git a/drivers/input/input.c b/drivers/input/input.c
> index 50597165dc54..a612afffa196 100644
> --- a/drivers/input/input.c
> +++ b/drivers/input/input.c
> @@ -1371,7 +1371,7 @@ INPUT_DEV_STRING_ATTR_SHOW(phys);
>  INPUT_DEV_STRING_ATTR_SHOW(uniq);
>  
>  static int input_print_modalias_bits(char *buf, int size,
> -				     char name, unsigned long *bm,
> +				     char name, const unsigned long *bm,
>  				     unsigned int min_bit, unsigned int max_bit)
>  {
>  	int len = 0, i;
> @@ -1383,7 +1383,7 @@ static int input_print_modalias_bits(char *buf, int size,
>  	return len;
>  }
>  
> -static int input_print_modalias(char *buf, int size, struct input_dev *id,
> +static int input_print_modalias(char *buf, int size, const struct input_dev *id,
>  				int add_cr)
>  {
>  	int len;
> @@ -1431,7 +1431,7 @@ static ssize_t input_dev_show_modalias(struct device *dev,
>  }
>  static DEVICE_ATTR(modalias, S_IRUGO, input_dev_show_modalias, NULL);
>  
> -static int input_print_bitmap(char *buf, int buf_size, unsigned long *bitmap,
> +static int input_print_bitmap(char *buf, int buf_size, const unsigned long *bitmap,
>  			      int max, int add_cr);
>  
>  static ssize_t input_dev_show_properties(struct device *dev,
> @@ -1523,7 +1523,7 @@ static const struct attribute_group input_dev_id_attr_group = {
>  	.attrs	= input_dev_id_attrs,
>  };
>  
> -static int input_print_bitmap(char *buf, int buf_size, unsigned long *bitmap,
> +static int input_print_bitmap(char *buf, int buf_size, const unsigned long *bitmap,
>  			      int max, int add_cr)
>  {
>  	int i;
> @@ -1620,7 +1620,7 @@ static void input_dev_release(struct device *device)
>   * device bitfields.
>   */
>  static int input_add_uevent_bm_var(struct kobj_uevent_env *env,
> -				   const char *name, unsigned long *bitmap, int max)
> +				   const char *name, const unsigned long *bitmap, int max)
>  {
>  	int len;
>  
> @@ -1638,7 +1638,7 @@ static int input_add_uevent_bm_var(struct kobj_uevent_env *env,
>  }
>  
>  static int input_add_uevent_modalias_var(struct kobj_uevent_env *env,
> -					 struct input_dev *dev)
> +					 const struct input_dev *dev)
>  {
>  	int len;
>  
> @@ -1676,9 +1676,9 @@ static int input_add_uevent_modalias_var(struct kobj_uevent_env *env,
>  			return err;					\
>  	} while (0)
>  
> -static int input_dev_uevent(struct device *device, struct kobj_uevent_env *env)
> +static int input_dev_uevent(const struct device *device, struct kobj_uevent_env *env)
>  {
> -	struct input_dev *dev = to_input_dev(device);
> +	const struct input_dev *dev = to_input_dev(device);
>  
>  	INPUT_ADD_HOTPLUG_VAR("PRODUCT=%x/%x/%x/%x",
>  				dev->id.bustype, dev->id.vendor,
> diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
> index 527d9324742b..6bdad6341844 100644
> --- a/drivers/media/rc/rc-main.c
> +++ b/drivers/media/rc/rc-main.c
> @@ -1614,7 +1614,7 @@ static void rc_dev_release(struct device *device)
>  	kfree(dev);
>  }
>  
> -static int rc_dev_uevent(struct device *device, struct kobj_uevent_env *env)
> +static int rc_dev_uevent(const struct device *device, struct kobj_uevent_env *env)
>  {
>  	struct rc_dev *dev = to_rc_dev(device);
>  	int ret = 0;
> diff --git a/drivers/of/device.c b/drivers/of/device.c
> index c674a13c3055..dda51b7ce597 100644
> --- a/drivers/of/device.c
> +++ b/drivers/of/device.c
> @@ -248,7 +248,7 @@ const void *of_device_get_match_data(const struct device *dev)
>  }
>  EXPORT_SYMBOL(of_device_get_match_data);
>  
> -static ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len)
> +static ssize_t of_device_get_modalias(const struct device *dev, char *str, ssize_t len)
>  {
>  	const char *compat;
>  	char *c;
> @@ -372,7 +372,7 @@ void of_device_uevent(const struct device *dev, struct kobj_uevent_env *env)
>  	mutex_unlock(&of_mutex);
>  }
>  
> -int of_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env)
> +int of_device_uevent_modalias(const struct device *dev, struct kobj_uevent_env *env)
>  {
>  	int sl;
>  
> diff --git a/drivers/platform/surface/aggregator/bus.c b/drivers/platform/surface/aggregator/bus.c
> index de539938896e..407eb55050a6 100644
> --- a/drivers/platform/surface/aggregator/bus.c
> +++ b/drivers/platform/surface/aggregator/bus.c
> @@ -35,9 +35,9 @@ static struct attribute *ssam_device_attrs[] = {
>  };
>  ATTRIBUTE_GROUPS(ssam_device);
>  
> -static int ssam_device_uevent(struct device *dev, struct kobj_uevent_env *env)
> +static int ssam_device_uevent(const struct device *dev, struct kobj_uevent_env *env)
>  {
> -	struct ssam_device *sdev = to_ssam_device(dev);
> +	const struct ssam_device *sdev = to_ssam_device(dev);
>  
>  	return add_uevent_var(env, "MODALIAS=ssam:d%02Xc%02Xt%02Xi%02Xf%02X",
>  			      sdev->uid.domain, sdev->uid.category,
> diff --git a/drivers/soundwire/bus_type.c b/drivers/soundwire/bus_type.c
> index 04b3529f8929..26c9a0a85d49 100644
> --- a/drivers/soundwire/bus_type.c
> +++ b/drivers/soundwire/bus_type.c
> @@ -58,9 +58,9 @@ int sdw_slave_modalias(const struct sdw_slave *slave, char *buf, size_t size)
>  			slave->id.sdw_version, slave->id.class_id);
>  }
>  
> -int sdw_slave_uevent(struct device *dev, struct kobj_uevent_env *env)
> +int sdw_slave_uevent(const struct device *dev, struct kobj_uevent_env *env)
>  {
> -	struct sdw_slave *slave = dev_to_sdw_dev(dev);
> +	const struct sdw_slave *slave = dev_to_sdw_dev(dev);
>  	char modalias[32];
>  
>  	sdw_slave_modalias(slave, modalias, sizeof(modalias));
> diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c
> index 60da5c23ccaf..2f4ef156b210 100644
> --- a/drivers/thunderbolt/switch.c
> +++ b/drivers/thunderbolt/switch.c
> @@ -2175,9 +2175,9 @@ static void tb_switch_release(struct device *dev)
>  	kfree(sw);
>  }
>  
> -static int tb_switch_uevent(struct device *dev, struct kobj_uevent_env *env)
> +static int tb_switch_uevent(const struct device *dev, struct kobj_uevent_env *env)
>  {
> -	struct tb_switch *sw = tb_to_switch(dev);
> +	const struct tb_switch *sw = tb_to_switch(dev);
>  	const char *type;
>  
>  	if (sw->config.thunderbolt_version == USB4_VERSION_1_0) {
> diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h
> index f9786976f5ec..909da0a98134 100644
> --- a/drivers/thunderbolt/tb.h
> +++ b/drivers/thunderbolt/tb.h
> @@ -815,7 +815,7 @@ static inline bool tb_is_switch(const struct device *dev)
>  	return dev->type == &tb_switch_type;
>  }
>  
> -static inline struct tb_switch *tb_to_switch(struct device *dev)
> +static inline struct tb_switch *tb_to_switch(const struct device *dev)
>  {
>  	if (tb_is_switch(dev))
>  		return container_of(dev, struct tb_switch, dev);
> diff --git a/drivers/thunderbolt/xdomain.c b/drivers/thunderbolt/xdomain.c
> index f00b2f62d8e3..aeb40a384bea 100644
> --- a/drivers/thunderbolt/xdomain.c
> +++ b/drivers/thunderbolt/xdomain.c
> @@ -881,7 +881,7 @@ static ssize_t key_show(struct device *dev, struct device_attribute *attr,
>  }
>  static DEVICE_ATTR_RO(key);
>  
> -static int get_modalias(struct tb_service *svc, char *buf, size_t size)
> +static int get_modalias(const struct tb_service *svc, char *buf, size_t size)
>  {
>  	return snprintf(buf, size, "tbsvc:k%sp%08Xv%08Xr%08X", svc->key,
>  			svc->prtcid, svc->prtcvers, svc->prtcrevs);
> @@ -953,9 +953,9 @@ static const struct attribute_group *tb_service_attr_groups[] = {
>  	NULL,
>  };
>  
> -static int tb_service_uevent(struct device *dev, struct kobj_uevent_env *env)
> +static int tb_service_uevent(const struct device *dev, struct kobj_uevent_env *env)
>  {
> -	struct tb_service *svc = container_of(dev, struct tb_service, dev);
> +	const struct tb_service *svc = container_of(dev, struct tb_service, dev);
>  	char modalias[64];
>  
>  	get_modalias(svc, modalias, sizeof(modalias));
> diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c
> index 0180e1e4e75d..aa80de3a8194 100644
> --- a/drivers/tty/serdev/core.c
> +++ b/drivers/tty/serdev/core.c
> @@ -42,7 +42,7 @@ static struct attribute *serdev_device_attrs[] = {
>  };
>  ATTRIBUTE_GROUPS(serdev_device);
>  
> -static int serdev_device_uevent(struct device *dev, struct kobj_uevent_env *env)
> +static int serdev_device_uevent(const struct device *dev, struct kobj_uevent_env *env)
>  {
>  	int rc;
>  
> diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
> index 4d59d927ae3e..c397574a6570 100644
> --- a/drivers/usb/core/message.c
> +++ b/drivers/usb/core/message.c
> @@ -1818,11 +1818,11 @@ void usb_authorize_interface(struct usb_interface *intf)
>  	}
>  }
>  
> -static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env)
> +static int usb_if_uevent(const struct device *dev, struct kobj_uevent_env *env)
>  {
> -	struct usb_device *usb_dev;
> -	struct usb_interface *intf;
> -	struct usb_host_interface *alt;
> +	const struct usb_device *usb_dev;
> +	const struct usb_interface *intf;
> +	const struct usb_host_interface *alt;
>  
>  	intf = to_usb_interface(dev);
>  	usb_dev = interface_to_usbdev(intf);
> diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
> index 11b15d7b357a..8527c06b65e6 100644
> --- a/drivers/usb/core/usb.c
> +++ b/drivers/usb/core/usb.c
> @@ -423,9 +423,9 @@ static void usb_release_dev(struct device *dev)
>  	kfree(udev);
>  }
>  
> -static int usb_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
> +static int usb_dev_uevent(const struct device *dev, struct kobj_uevent_env *env)
>  {
> -	struct usb_device *usb_dev;
> +	const struct usb_device *usb_dev;
>  
>  	usb_dev = to_usb_device(dev);
>  
> diff --git a/drivers/usb/phy/phy.c b/drivers/usb/phy/phy.c
> index 1b24492bb4e5..4b468bde19cf 100644
> --- a/drivers/usb/phy/phy.c
> +++ b/drivers/usb/phy/phy.c
> @@ -80,7 +80,7 @@ static struct usb_phy *__of_usb_find_phy(struct device_node *node)
>  	return ERR_PTR(-EPROBE_DEFER);
>  }
>  
> -static struct usb_phy *__device_to_usb_phy(struct device *dev)
> +static struct usb_phy *__device_to_usb_phy(const struct device *dev)
>  {
>  	struct usb_phy *usb_phy;
>  
> @@ -145,9 +145,9 @@ static void usb_phy_notify_charger_work(struct work_struct *work)
>  	kobject_uevent(&usb_phy->dev->kobj, KOBJ_CHANGE);
>  }
>  
> -static int usb_phy_uevent(struct device *dev, struct kobj_uevent_env *env)
> +static int usb_phy_uevent(const struct device *dev, struct kobj_uevent_env *env)
>  {
> -	struct usb_phy *usb_phy;
> +	const struct usb_phy *usb_phy;
>  	char uchger_state[50] = { 0 };
>  	char uchger_type[50] = { 0 };
>  	unsigned long flags;
> diff --git a/drivers/usb/roles/class.c b/drivers/usb/roles/class.c
> index a3575a5a18ce..3708fb70b693 100644
> --- a/drivers/usb/roles/class.c
> +++ b/drivers/usb/roles/class.c
> @@ -271,8 +271,7 @@ static const struct attribute_group *usb_role_switch_groups[] = {
>  	NULL,
>  };
>  
> -static int
> -usb_role_switch_uevent(struct device *dev, struct kobj_uevent_env *env)
> +static int usb_role_switch_uevent(const struct device *dev, struct kobj_uevent_env *env)
>  {
>  	int ret;
>  
> diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c
> index bd5e5dd70431..8e2b2077f262 100644
> --- a/drivers/usb/typec/class.c
> +++ b/drivers/usb/typec/class.c
> @@ -1718,7 +1718,7 @@ static const struct attribute_group *typec_groups[] = {
>  	NULL
>  };
>  
> -static int typec_uevent(struct device *dev, struct kobj_uevent_env *env)
> +static int typec_uevent(const struct device *dev, struct kobj_uevent_env *env)
>  {
>  	int ret;
>  
> diff --git a/include/linux/acpi.h b/include/linux/acpi.h
> index 3015235d65e3..fc956c3f8324 100644
> --- a/include/linux/acpi.h
> +++ b/include/linux/acpi.h
> @@ -722,7 +722,7 @@ const struct acpi_device_id *acpi_match_device(const struct acpi_device_id *ids,
>  const void *acpi_device_get_match_data(const struct device *dev);
>  extern bool acpi_driver_match_device(struct device *dev,
>  				     const struct device_driver *drv);
> -int acpi_device_uevent_modalias(struct device *, struct kobj_uevent_env *);
> +int acpi_device_uevent_modalias(const struct device *, struct kobj_uevent_env *);
>  int acpi_device_modalias(struct device *, char *, int);
>  
>  struct platform_device *acpi_create_platform_device(struct acpi_device *,
> @@ -957,7 +957,7 @@ static inline union acpi_object *acpi_evaluate_dsm(acpi_handle handle,
>  	return NULL;
>  }
>  
> -static inline int acpi_device_uevent_modalias(struct device *dev,
> +static inline int acpi_device_uevent_modalias(const struct device *dev,
>  				struct kobj_uevent_env *env)
>  {
>  	return -ENODEV;
> diff --git a/include/linux/device.h b/include/linux/device.h
> index 84ae52de6746..46093bae6905 100644
> --- a/include/linux/device.h
> +++ b/include/linux/device.h
> @@ -88,7 +88,7 @@ int subsys_virtual_register(struct bus_type *subsys,
>  struct device_type {
>  	const char *name;
>  	const struct attribute_group **groups;
> -	int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
> +	int (*uevent)(const struct device *dev, struct kobj_uevent_env *env);
>  	char *(*devnode)(struct device *dev, umode_t *mode,
>  			 kuid_t *uid, kgid_t *gid);
>  	void (*release)(struct device *dev);
> diff --git a/include/linux/firewire.h b/include/linux/firewire.h
> index 980019053e54..4c882d57df02 100644
> --- a/include/linux/firewire.h
> +++ b/include/linux/firewire.h
> @@ -208,7 +208,7 @@ struct fw_device {
>  	struct fw_attribute_group attribute_group;
>  };
>  
> -static inline struct fw_device *fw_device(struct device *dev)
> +static inline struct fw_device *fw_device(const struct device *dev)
>  {
>  	return container_of(dev, struct fw_device, device);
>  }
> @@ -229,7 +229,7 @@ struct fw_unit {
>  	struct fw_attribute_group attribute_group;
>  };
>  
> -static inline struct fw_unit *fw_unit(struct device *dev)
> +static inline struct fw_unit *fw_unit(const struct device *dev)
>  {
>  	return container_of(dev, struct fw_unit, device);
>  }
> @@ -246,7 +246,7 @@ static inline void fw_unit_put(struct fw_unit *unit)
>  	put_device(&unit->device);
>  }
>  
> -static inline struct fw_device *fw_parent_device(struct fw_unit *unit)
> +static inline struct fw_device *fw_parent_device(const struct fw_unit *unit)
>  {
>  	return fw_device(unit->device.parent);
>  }
> diff --git a/include/linux/i3c/device.h b/include/linux/i3c/device.h
> index 8242e13e7b0b..cda61c1d6d60 100644
> --- a/include/linux/i3c/device.h
> +++ b/include/linux/i3c/device.h
> @@ -186,7 +186,7 @@ static inline struct i3c_driver *drv_to_i3cdrv(struct device_driver *drv)
>  }
>  
>  struct device *i3cdev_to_dev(struct i3c_device *i3cdev);
> -struct i3c_device *dev_to_i3cdev(struct device *dev);
> +struct i3c_device *dev_to_i3cdev(const struct device *dev);
>  
>  const struct i3c_device_id *
>  i3c_device_match_id(struct i3c_device *i3cdev,
> @@ -293,7 +293,7 @@ int i3c_device_do_priv_xfers(struct i3c_device *dev,
>  			     struct i3c_priv_xfer *xfers,
>  			     int nxfers);
>  
> -void i3c_device_get_info(struct i3c_device *dev, struct i3c_device_info *info);
> +void i3c_device_get_info(const struct i3c_device *dev, struct i3c_device_info *info);
>  
>  struct i3c_ibi_payload {
>  	unsigned int len;
> diff --git a/include/linux/of_device.h b/include/linux/of_device.h
> index ab7d557d541d..f4b57614979d 100644
> --- a/include/linux/of_device.h
> +++ b/include/linux/of_device.h
> @@ -36,7 +36,7 @@ extern ssize_t of_device_modalias(struct device *dev, char *str, ssize_t len);
>  extern int of_device_request_module(struct device *dev);
>  
>  extern void of_device_uevent(const struct device *dev, struct kobj_uevent_env *env);
> -extern int of_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env);
> +extern int of_device_uevent_modalias(const struct device *dev, struct kobj_uevent_env *env);
>  
>  static inline struct device_node *of_cpu_device_node_get(int cpu)
>  {
> @@ -83,7 +83,7 @@ static inline int of_device_request_module(struct device *dev)
>  	return -ENODEV;
>  }
>  
> -static inline int of_device_uevent_modalias(struct device *dev,
> +static inline int of_device_uevent_modalias(const struct device *dev,
>  				   struct kobj_uevent_env *env)
>  {
>  	return -ENODEV;
> diff --git a/include/linux/soundwire/sdw_type.h b/include/linux/soundwire/sdw_type.h
> index 52eb66cd11bc..d8c27f1e5559 100644
> --- a/include/linux/soundwire/sdw_type.h
> +++ b/include/linux/soundwire/sdw_type.h
> @@ -21,7 +21,7 @@ static inline int is_sdw_slave(const struct device *dev)
>  int __sdw_register_driver(struct sdw_driver *drv, struct module *owner);
>  void sdw_unregister_driver(struct sdw_driver *drv);
>  
> -int sdw_slave_uevent(struct device *dev, struct kobj_uevent_env *env);
> +int sdw_slave_uevent(const struct device *dev, struct kobj_uevent_env *env);
>  
>  /**
>   * module_sdw_driver() - Helper macro for registering a Soundwire driver
> diff --git a/include/linux/surface_aggregator/device.h b/include/linux/surface_aggregator/device.h
> index 46c45d1b6368..a5dff729edb7 100644
> --- a/include/linux/surface_aggregator/device.h
> +++ b/include/linux/surface_aggregator/device.h
> @@ -229,7 +229,7 @@ static inline bool is_ssam_device(struct device *d)
>   * Return: Returns a pointer to the &struct ssam_device wrapping the given
>   * device @d.
>   */
> -static inline struct ssam_device *to_ssam_device(struct device *d)
> +static inline struct ssam_device *to_ssam_device(const struct device *d)
>  {
>  	return container_of(d, struct ssam_device, dev);
>  }
Greg KH Dec. 1, 2022, 6:43 p.m. UTC | #16
On Wed, Nov 23, 2022 at 06:00:23PM +0000, Matthew Wilcox wrote:
> On Wed, Nov 23, 2022 at 01:55:42PM -0400, Jason Gunthorpe wrote:
> > On Wed, Nov 23, 2022 at 05:49:36PM +0000, Matthew Wilcox wrote:
> > > On Wed, Nov 23, 2022 at 01:29:56PM -0400, Jason Gunthorpe wrote:
> > > > #define generic_container_of(in_type, in, out_type, out_member) \
> > > > 	_Generic(in,                                        \
> > > >                   const in_type *: ((const out_type *)container_of(in, out_type, out_member)),   \
> > > >                   in_type *: ((out_type *)container_of(in, out_type, out_member)) \
> > > > 		  )
> > > 
> > > There's a neat trick I found in seqlock.h:
> > > 
> > > #define generic_container_of(in_t, in, out_t, m)			\
> > > 	_Generic(*(in),							\
> > > 		const in_t: ((const out_t *)container_of(in, out_t, m)), \
> > > 		in_t: ((out_t *)container_of(in, out_type, m))	\
> > > 	)
> > >
> > > and now it fits in 80 columns ;-)
> > 
> > Aside from less letters, is their another benifit to using *(in) ?
> 
> I don't think so.  It just looks nicer to me than putting the star in
> each case.  If I'd thought of it, I would have done it to page_folio(),
> but I won't change it now.

Ah, but your trick will not work, that blows up and will not build.  The
original one from Jason here does work.  _Generic is tricky...

thanks,

greg k-h
Greg KH Jan. 11, 2023, 9:52 a.m. UTC | #17
On Fri, Nov 25, 2022 at 11:56:18AM +0000, Mauro Carvalho Chehab wrote:
> Em Wed, 23 Nov 2022 13:25:21 +0100
> Greg Kroah-Hartman <gregkh@linuxfoundation.org> escreveu:
> 
> > The uevent() callback in struct device_type should not be modifying the
> > device that is passed into it, so mark it as a const * and propagate the
> > function signature changes out into all relevant subsystems that use
> > this callback.
> 
> Acked-by: Mauro Carvalho Chehab <mchehab@kernel.org>

Thanks for the review.
diff mbox series

Patch

diff --git a/block/partitions/core.c b/block/partitions/core.c
index b8112f52d388..7b8ef6296abd 100644
--- a/block/partitions/core.c
+++ b/block/partitions/core.c
@@ -254,9 +254,9 @@  static void part_release(struct device *dev)
 	iput(dev_to_bdev(dev)->bd_inode);
 }
 
-static int part_uevent(struct device *dev, struct kobj_uevent_env *env)
+static int part_uevent(const struct device *dev, struct kobj_uevent_env *env)
 {
-	struct block_device *part = dev_to_bdev(dev);
+	const struct block_device *part = dev_to_bdev(dev);
 
 	add_uevent_var(env, "PARTN=%u", part->bd_partno);
 	if (part->bd_meta_info && part->bd_meta_info->volname[0])
diff --git a/drivers/acpi/device_sysfs.c b/drivers/acpi/device_sysfs.c
index 120873dad2cc..daff2c0c5c52 100644
--- a/drivers/acpi/device_sysfs.c
+++ b/drivers/acpi/device_sysfs.c
@@ -133,7 +133,7 @@  static void acpi_hide_nondev_subnodes(struct acpi_device_data *data)
  *         -EINVAL: output error
  *         -ENOMEM: output is truncated
  */
-static int create_pnp_modalias(struct acpi_device *acpi_dev, char *modalias,
+static int create_pnp_modalias(const struct acpi_device *acpi_dev, char *modalias,
 			       int size)
 {
 	int len;
@@ -191,7 +191,7 @@  static int create_pnp_modalias(struct acpi_device *acpi_dev, char *modalias,
  * only be called for devices having ACPI_DT_NAMESPACE_HID in their list of
  * ACPI/PNP IDs.
  */
-static int create_of_modalias(struct acpi_device *acpi_dev, char *modalias,
+static int create_of_modalias(const struct acpi_device *acpi_dev, char *modalias,
 			      int size)
 {
 	struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
@@ -239,7 +239,7 @@  static int create_of_modalias(struct acpi_device *acpi_dev, char *modalias,
 	return len;
 }
 
-int __acpi_device_uevent_modalias(struct acpi_device *adev,
+int __acpi_device_uevent_modalias(const struct acpi_device *adev,
 				  struct kobj_uevent_env *env)
 {
 	int len;
@@ -277,7 +277,7 @@  int __acpi_device_uevent_modalias(struct acpi_device *adev,
  * Because other buses do not support ACPI HIDs & CIDs, e.g. for a device with
  * hid:IBM0001 and cid:ACPI0001 you get: "acpi:IBM0001:ACPI0001".
  */
-int acpi_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env)
+int acpi_device_uevent_modalias(const struct device *dev, struct kobj_uevent_env *env)
 {
 	return __acpi_device_uevent_modalias(acpi_companion_match(dev), env);
 }
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 219c02df9a08..d422884eb3d0 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -120,7 +120,7 @@  int acpi_bus_register_early_device(int type);
                      Device Matching and Notification
    -------------------------------------------------------------------------- */
 struct acpi_device *acpi_companion_match(const struct device *dev);
-int __acpi_device_uevent_modalias(struct acpi_device *adev,
+int __acpi_device_uevent_modalias(const struct acpi_device *adev,
 				  struct kobj_uevent_env *env);
 
 /* --------------------------------------------------------------------------
diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c
index adddd8c45d0c..aa597cda0d88 100644
--- a/drivers/firewire/core-device.c
+++ b/drivers/firewire/core-device.c
@@ -133,7 +133,7 @@  static void get_ids(const u32 *directory, int *id)
 	}
 }
 
-static void get_modalias_ids(struct fw_unit *unit, int *id)
+static void get_modalias_ids(const struct fw_unit *unit, int *id)
 {
 	get_ids(&fw_parent_device(unit)->config_rom[5], id);
 	get_ids(unit->directory, id);
@@ -195,7 +195,7 @@  static void fw_unit_remove(struct device *dev)
 	driver->remove(fw_unit(dev));
 }
 
-static int get_modalias(struct fw_unit *unit, char *buffer, size_t buffer_size)
+static int get_modalias(const struct fw_unit *unit, char *buffer, size_t buffer_size)
 {
 	int id[] = {0, 0, 0, 0};
 
@@ -206,9 +206,9 @@  static int get_modalias(struct fw_unit *unit, char *buffer, size_t buffer_size)
 			id[0], id[1], id[2], id[3]);
 }
 
-static int fw_unit_uevent(struct device *dev, struct kobj_uevent_env *env)
+static int fw_unit_uevent(const struct device *dev, struct kobj_uevent_env *env)
 {
-	struct fw_unit *unit = fw_unit(dev);
+	const struct fw_unit *unit = fw_unit(dev);
 	char modalias[64];
 
 	get_modalias(unit, modalias, sizeof(modalias));
diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
index b4edf10e8fd0..fb16e33e52c6 100644
--- a/drivers/i2c/i2c-core-base.c
+++ b/drivers/i2c/i2c-core-base.c
@@ -136,9 +136,9 @@  static int i2c_device_match(struct device *dev, struct device_driver *drv)
 	return 0;
 }
 
-static int i2c_device_uevent(struct device *dev, struct kobj_uevent_env *env)
+static int i2c_device_uevent(const struct device *dev, struct kobj_uevent_env *env)
 {
-	struct i2c_client *client = to_i2c_client(dev);
+	const struct i2c_client *client = to_i2c_client(dev);
 	int rc;
 
 	rc = of_device_uevent_modalias(dev, env);
diff --git a/drivers/i3c/device.c b/drivers/i3c/device.c
index e92d3e9a52bd..05f8ab762e34 100644
--- a/drivers/i3c/device.c
+++ b/drivers/i3c/device.c
@@ -58,7 +58,7 @@  EXPORT_SYMBOL_GPL(i3c_device_do_priv_xfers);
  *
  * Retrieve I3C dev info.
  */
-void i3c_device_get_info(struct i3c_device *dev,
+void i3c_device_get_info(const struct i3c_device *dev,
 			 struct i3c_device_info *info)
 {
 	if (!info)
@@ -194,7 +194,7 @@  EXPORT_SYMBOL_GPL(i3cdev_to_dev);
  *
  * Return: a pointer to an I3C device object.
  */
-struct i3c_device *dev_to_i3cdev(struct device *dev)
+struct i3c_device *dev_to_i3cdev(const struct device *dev)
 {
 	return container_of(dev, struct i3c_device, dev);
 }
diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
index 351c81a929a6..bf1a2b2f34c4 100644
--- a/drivers/i3c/master.c
+++ b/drivers/i3c/master.c
@@ -273,9 +273,9 @@  static struct attribute *i3c_device_attrs[] = {
 };
 ATTRIBUTE_GROUPS(i3c_device);
 
-static int i3c_device_uevent(struct device *dev, struct kobj_uevent_env *env)
+static int i3c_device_uevent(const struct device *dev, struct kobj_uevent_env *env)
 {
-	struct i3c_device *i3cdev = dev_to_i3cdev(dev);
+	const struct i3c_device *i3cdev = dev_to_i3cdev(dev);
 	struct i3c_device_info devinfo;
 	u16 manuf, part, ext;
 
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 50597165dc54..a612afffa196 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -1371,7 +1371,7 @@  INPUT_DEV_STRING_ATTR_SHOW(phys);
 INPUT_DEV_STRING_ATTR_SHOW(uniq);
 
 static int input_print_modalias_bits(char *buf, int size,
-				     char name, unsigned long *bm,
+				     char name, const unsigned long *bm,
 				     unsigned int min_bit, unsigned int max_bit)
 {
 	int len = 0, i;
@@ -1383,7 +1383,7 @@  static int input_print_modalias_bits(char *buf, int size,
 	return len;
 }
 
-static int input_print_modalias(char *buf, int size, struct input_dev *id,
+static int input_print_modalias(char *buf, int size, const struct input_dev *id,
 				int add_cr)
 {
 	int len;
@@ -1431,7 +1431,7 @@  static ssize_t input_dev_show_modalias(struct device *dev,
 }
 static DEVICE_ATTR(modalias, S_IRUGO, input_dev_show_modalias, NULL);
 
-static int input_print_bitmap(char *buf, int buf_size, unsigned long *bitmap,
+static int input_print_bitmap(char *buf, int buf_size, const unsigned long *bitmap,
 			      int max, int add_cr);
 
 static ssize_t input_dev_show_properties(struct device *dev,
@@ -1523,7 +1523,7 @@  static const struct attribute_group input_dev_id_attr_group = {
 	.attrs	= input_dev_id_attrs,
 };
 
-static int input_print_bitmap(char *buf, int buf_size, unsigned long *bitmap,
+static int input_print_bitmap(char *buf, int buf_size, const unsigned long *bitmap,
 			      int max, int add_cr)
 {
 	int i;
@@ -1620,7 +1620,7 @@  static void input_dev_release(struct device *device)
  * device bitfields.
  */
 static int input_add_uevent_bm_var(struct kobj_uevent_env *env,
-				   const char *name, unsigned long *bitmap, int max)
+				   const char *name, const unsigned long *bitmap, int max)
 {
 	int len;
 
@@ -1638,7 +1638,7 @@  static int input_add_uevent_bm_var(struct kobj_uevent_env *env,
 }
 
 static int input_add_uevent_modalias_var(struct kobj_uevent_env *env,
-					 struct input_dev *dev)
+					 const struct input_dev *dev)
 {
 	int len;
 
@@ -1676,9 +1676,9 @@  static int input_add_uevent_modalias_var(struct kobj_uevent_env *env,
 			return err;					\
 	} while (0)
 
-static int input_dev_uevent(struct device *device, struct kobj_uevent_env *env)
+static int input_dev_uevent(const struct device *device, struct kobj_uevent_env *env)
 {
-	struct input_dev *dev = to_input_dev(device);
+	const struct input_dev *dev = to_input_dev(device);
 
 	INPUT_ADD_HOTPLUG_VAR("PRODUCT=%x/%x/%x/%x",
 				dev->id.bustype, dev->id.vendor,
diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index 527d9324742b..6bdad6341844 100644
--- a/drivers/media/rc/rc-main.c
+++ b/drivers/media/rc/rc-main.c
@@ -1614,7 +1614,7 @@  static void rc_dev_release(struct device *device)
 	kfree(dev);
 }
 
-static int rc_dev_uevent(struct device *device, struct kobj_uevent_env *env)
+static int rc_dev_uevent(const struct device *device, struct kobj_uevent_env *env)
 {
 	struct rc_dev *dev = to_rc_dev(device);
 	int ret = 0;
diff --git a/drivers/of/device.c b/drivers/of/device.c
index c674a13c3055..dda51b7ce597 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -248,7 +248,7 @@  const void *of_device_get_match_data(const struct device *dev)
 }
 EXPORT_SYMBOL(of_device_get_match_data);
 
-static ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len)
+static ssize_t of_device_get_modalias(const struct device *dev, char *str, ssize_t len)
 {
 	const char *compat;
 	char *c;
@@ -372,7 +372,7 @@  void of_device_uevent(const struct device *dev, struct kobj_uevent_env *env)
 	mutex_unlock(&of_mutex);
 }
 
-int of_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env)
+int of_device_uevent_modalias(const struct device *dev, struct kobj_uevent_env *env)
 {
 	int sl;
 
diff --git a/drivers/platform/surface/aggregator/bus.c b/drivers/platform/surface/aggregator/bus.c
index de539938896e..407eb55050a6 100644
--- a/drivers/platform/surface/aggregator/bus.c
+++ b/drivers/platform/surface/aggregator/bus.c
@@ -35,9 +35,9 @@  static struct attribute *ssam_device_attrs[] = {
 };
 ATTRIBUTE_GROUPS(ssam_device);
 
-static int ssam_device_uevent(struct device *dev, struct kobj_uevent_env *env)
+static int ssam_device_uevent(const struct device *dev, struct kobj_uevent_env *env)
 {
-	struct ssam_device *sdev = to_ssam_device(dev);
+	const struct ssam_device *sdev = to_ssam_device(dev);
 
 	return add_uevent_var(env, "MODALIAS=ssam:d%02Xc%02Xt%02Xi%02Xf%02X",
 			      sdev->uid.domain, sdev->uid.category,
diff --git a/drivers/soundwire/bus_type.c b/drivers/soundwire/bus_type.c
index 04b3529f8929..26c9a0a85d49 100644
--- a/drivers/soundwire/bus_type.c
+++ b/drivers/soundwire/bus_type.c
@@ -58,9 +58,9 @@  int sdw_slave_modalias(const struct sdw_slave *slave, char *buf, size_t size)
 			slave->id.sdw_version, slave->id.class_id);
 }
 
-int sdw_slave_uevent(struct device *dev, struct kobj_uevent_env *env)
+int sdw_slave_uevent(const struct device *dev, struct kobj_uevent_env *env)
 {
-	struct sdw_slave *slave = dev_to_sdw_dev(dev);
+	const struct sdw_slave *slave = dev_to_sdw_dev(dev);
 	char modalias[32];
 
 	sdw_slave_modalias(slave, modalias, sizeof(modalias));
diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c
index 60da5c23ccaf..2f4ef156b210 100644
--- a/drivers/thunderbolt/switch.c
+++ b/drivers/thunderbolt/switch.c
@@ -2175,9 +2175,9 @@  static void tb_switch_release(struct device *dev)
 	kfree(sw);
 }
 
-static int tb_switch_uevent(struct device *dev, struct kobj_uevent_env *env)
+static int tb_switch_uevent(const struct device *dev, struct kobj_uevent_env *env)
 {
-	struct tb_switch *sw = tb_to_switch(dev);
+	const struct tb_switch *sw = tb_to_switch(dev);
 	const char *type;
 
 	if (sw->config.thunderbolt_version == USB4_VERSION_1_0) {
diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h
index f9786976f5ec..909da0a98134 100644
--- a/drivers/thunderbolt/tb.h
+++ b/drivers/thunderbolt/tb.h
@@ -815,7 +815,7 @@  static inline bool tb_is_switch(const struct device *dev)
 	return dev->type == &tb_switch_type;
 }
 
-static inline struct tb_switch *tb_to_switch(struct device *dev)
+static inline struct tb_switch *tb_to_switch(const struct device *dev)
 {
 	if (tb_is_switch(dev))
 		return container_of(dev, struct tb_switch, dev);
diff --git a/drivers/thunderbolt/xdomain.c b/drivers/thunderbolt/xdomain.c
index f00b2f62d8e3..aeb40a384bea 100644
--- a/drivers/thunderbolt/xdomain.c
+++ b/drivers/thunderbolt/xdomain.c
@@ -881,7 +881,7 @@  static ssize_t key_show(struct device *dev, struct device_attribute *attr,
 }
 static DEVICE_ATTR_RO(key);
 
-static int get_modalias(struct tb_service *svc, char *buf, size_t size)
+static int get_modalias(const struct tb_service *svc, char *buf, size_t size)
 {
 	return snprintf(buf, size, "tbsvc:k%sp%08Xv%08Xr%08X", svc->key,
 			svc->prtcid, svc->prtcvers, svc->prtcrevs);
@@ -953,9 +953,9 @@  static const struct attribute_group *tb_service_attr_groups[] = {
 	NULL,
 };
 
-static int tb_service_uevent(struct device *dev, struct kobj_uevent_env *env)
+static int tb_service_uevent(const struct device *dev, struct kobj_uevent_env *env)
 {
-	struct tb_service *svc = container_of(dev, struct tb_service, dev);
+	const struct tb_service *svc = container_of(dev, struct tb_service, dev);
 	char modalias[64];
 
 	get_modalias(svc, modalias, sizeof(modalias));
diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c
index 0180e1e4e75d..aa80de3a8194 100644
--- a/drivers/tty/serdev/core.c
+++ b/drivers/tty/serdev/core.c
@@ -42,7 +42,7 @@  static struct attribute *serdev_device_attrs[] = {
 };
 ATTRIBUTE_GROUPS(serdev_device);
 
-static int serdev_device_uevent(struct device *dev, struct kobj_uevent_env *env)
+static int serdev_device_uevent(const struct device *dev, struct kobj_uevent_env *env)
 {
 	int rc;
 
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index 4d59d927ae3e..c397574a6570 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -1818,11 +1818,11 @@  void usb_authorize_interface(struct usb_interface *intf)
 	}
 }
 
-static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env)
+static int usb_if_uevent(const struct device *dev, struct kobj_uevent_env *env)
 {
-	struct usb_device *usb_dev;
-	struct usb_interface *intf;
-	struct usb_host_interface *alt;
+	const struct usb_device *usb_dev;
+	const struct usb_interface *intf;
+	const struct usb_host_interface *alt;
 
 	intf = to_usb_interface(dev);
 	usb_dev = interface_to_usbdev(intf);
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 11b15d7b357a..8527c06b65e6 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -423,9 +423,9 @@  static void usb_release_dev(struct device *dev)
 	kfree(udev);
 }
 
-static int usb_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
+static int usb_dev_uevent(const struct device *dev, struct kobj_uevent_env *env)
 {
-	struct usb_device *usb_dev;
+	const struct usb_device *usb_dev;
 
 	usb_dev = to_usb_device(dev);
 
diff --git a/drivers/usb/phy/phy.c b/drivers/usb/phy/phy.c
index 1b24492bb4e5..4b468bde19cf 100644
--- a/drivers/usb/phy/phy.c
+++ b/drivers/usb/phy/phy.c
@@ -80,7 +80,7 @@  static struct usb_phy *__of_usb_find_phy(struct device_node *node)
 	return ERR_PTR(-EPROBE_DEFER);
 }
 
-static struct usb_phy *__device_to_usb_phy(struct device *dev)
+static struct usb_phy *__device_to_usb_phy(const struct device *dev)
 {
 	struct usb_phy *usb_phy;
 
@@ -145,9 +145,9 @@  static void usb_phy_notify_charger_work(struct work_struct *work)
 	kobject_uevent(&usb_phy->dev->kobj, KOBJ_CHANGE);
 }
 
-static int usb_phy_uevent(struct device *dev, struct kobj_uevent_env *env)
+static int usb_phy_uevent(const struct device *dev, struct kobj_uevent_env *env)
 {
-	struct usb_phy *usb_phy;
+	const struct usb_phy *usb_phy;
 	char uchger_state[50] = { 0 };
 	char uchger_type[50] = { 0 };
 	unsigned long flags;
diff --git a/drivers/usb/roles/class.c b/drivers/usb/roles/class.c
index a3575a5a18ce..3708fb70b693 100644
--- a/drivers/usb/roles/class.c
+++ b/drivers/usb/roles/class.c
@@ -271,8 +271,7 @@  static const struct attribute_group *usb_role_switch_groups[] = {
 	NULL,
 };
 
-static int
-usb_role_switch_uevent(struct device *dev, struct kobj_uevent_env *env)
+static int usb_role_switch_uevent(const struct device *dev, struct kobj_uevent_env *env)
 {
 	int ret;
 
diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c
index bd5e5dd70431..8e2b2077f262 100644
--- a/drivers/usb/typec/class.c
+++ b/drivers/usb/typec/class.c
@@ -1718,7 +1718,7 @@  static const struct attribute_group *typec_groups[] = {
 	NULL
 };
 
-static int typec_uevent(struct device *dev, struct kobj_uevent_env *env)
+static int typec_uevent(const struct device *dev, struct kobj_uevent_env *env)
 {
 	int ret;
 
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 3015235d65e3..fc956c3f8324 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -722,7 +722,7 @@  const struct acpi_device_id *acpi_match_device(const struct acpi_device_id *ids,
 const void *acpi_device_get_match_data(const struct device *dev);
 extern bool acpi_driver_match_device(struct device *dev,
 				     const struct device_driver *drv);
-int acpi_device_uevent_modalias(struct device *, struct kobj_uevent_env *);
+int acpi_device_uevent_modalias(const struct device *, struct kobj_uevent_env *);
 int acpi_device_modalias(struct device *, char *, int);
 
 struct platform_device *acpi_create_platform_device(struct acpi_device *,
@@ -957,7 +957,7 @@  static inline union acpi_object *acpi_evaluate_dsm(acpi_handle handle,
 	return NULL;
 }
 
-static inline int acpi_device_uevent_modalias(struct device *dev,
+static inline int acpi_device_uevent_modalias(const struct device *dev,
 				struct kobj_uevent_env *env)
 {
 	return -ENODEV;
diff --git a/include/linux/device.h b/include/linux/device.h
index 84ae52de6746..46093bae6905 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -88,7 +88,7 @@  int subsys_virtual_register(struct bus_type *subsys,
 struct device_type {
 	const char *name;
 	const struct attribute_group **groups;
-	int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
+	int (*uevent)(const struct device *dev, struct kobj_uevent_env *env);
 	char *(*devnode)(struct device *dev, umode_t *mode,
 			 kuid_t *uid, kgid_t *gid);
 	void (*release)(struct device *dev);
diff --git a/include/linux/firewire.h b/include/linux/firewire.h
index 980019053e54..4c882d57df02 100644
--- a/include/linux/firewire.h
+++ b/include/linux/firewire.h
@@ -208,7 +208,7 @@  struct fw_device {
 	struct fw_attribute_group attribute_group;
 };
 
-static inline struct fw_device *fw_device(struct device *dev)
+static inline struct fw_device *fw_device(const struct device *dev)
 {
 	return container_of(dev, struct fw_device, device);
 }
@@ -229,7 +229,7 @@  struct fw_unit {
 	struct fw_attribute_group attribute_group;
 };
 
-static inline struct fw_unit *fw_unit(struct device *dev)
+static inline struct fw_unit *fw_unit(const struct device *dev)
 {
 	return container_of(dev, struct fw_unit, device);
 }
@@ -246,7 +246,7 @@  static inline void fw_unit_put(struct fw_unit *unit)
 	put_device(&unit->device);
 }
 
-static inline struct fw_device *fw_parent_device(struct fw_unit *unit)
+static inline struct fw_device *fw_parent_device(const struct fw_unit *unit)
 {
 	return fw_device(unit->device.parent);
 }
diff --git a/include/linux/i3c/device.h b/include/linux/i3c/device.h
index 8242e13e7b0b..cda61c1d6d60 100644
--- a/include/linux/i3c/device.h
+++ b/include/linux/i3c/device.h
@@ -186,7 +186,7 @@  static inline struct i3c_driver *drv_to_i3cdrv(struct device_driver *drv)
 }
 
 struct device *i3cdev_to_dev(struct i3c_device *i3cdev);
-struct i3c_device *dev_to_i3cdev(struct device *dev);
+struct i3c_device *dev_to_i3cdev(const struct device *dev);
 
 const struct i3c_device_id *
 i3c_device_match_id(struct i3c_device *i3cdev,
@@ -293,7 +293,7 @@  int i3c_device_do_priv_xfers(struct i3c_device *dev,
 			     struct i3c_priv_xfer *xfers,
 			     int nxfers);
 
-void i3c_device_get_info(struct i3c_device *dev, struct i3c_device_info *info);
+void i3c_device_get_info(const struct i3c_device *dev, struct i3c_device_info *info);
 
 struct i3c_ibi_payload {
 	unsigned int len;
diff --git a/include/linux/of_device.h b/include/linux/of_device.h
index ab7d557d541d..f4b57614979d 100644
--- a/include/linux/of_device.h
+++ b/include/linux/of_device.h
@@ -36,7 +36,7 @@  extern ssize_t of_device_modalias(struct device *dev, char *str, ssize_t len);
 extern int of_device_request_module(struct device *dev);
 
 extern void of_device_uevent(const struct device *dev, struct kobj_uevent_env *env);
-extern int of_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env);
+extern int of_device_uevent_modalias(const struct device *dev, struct kobj_uevent_env *env);
 
 static inline struct device_node *of_cpu_device_node_get(int cpu)
 {
@@ -83,7 +83,7 @@  static inline int of_device_request_module(struct device *dev)
 	return -ENODEV;
 }
 
-static inline int of_device_uevent_modalias(struct device *dev,
+static inline int of_device_uevent_modalias(const struct device *dev,
 				   struct kobj_uevent_env *env)
 {
 	return -ENODEV;
diff --git a/include/linux/soundwire/sdw_type.h b/include/linux/soundwire/sdw_type.h
index 52eb66cd11bc..d8c27f1e5559 100644
--- a/include/linux/soundwire/sdw_type.h
+++ b/include/linux/soundwire/sdw_type.h
@@ -21,7 +21,7 @@  static inline int is_sdw_slave(const struct device *dev)
 int __sdw_register_driver(struct sdw_driver *drv, struct module *owner);
 void sdw_unregister_driver(struct sdw_driver *drv);
 
-int sdw_slave_uevent(struct device *dev, struct kobj_uevent_env *env);
+int sdw_slave_uevent(const struct device *dev, struct kobj_uevent_env *env);
 
 /**
  * module_sdw_driver() - Helper macro for registering a Soundwire driver
diff --git a/include/linux/surface_aggregator/device.h b/include/linux/surface_aggregator/device.h
index 46c45d1b6368..a5dff729edb7 100644
--- a/include/linux/surface_aggregator/device.h
+++ b/include/linux/surface_aggregator/device.h
@@ -229,7 +229,7 @@  static inline bool is_ssam_device(struct device *d)
  * Return: Returns a pointer to the &struct ssam_device wrapping the given
  * device @d.
  */
-static inline struct ssam_device *to_ssam_device(struct device *d)
+static inline struct ssam_device *to_ssam_device(const struct device *d)
 {
 	return container_of(d, struct ssam_device, dev);
 }