public inbox for devicetree@vger.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 0/2] Let the compiler remove unneeded compatible checks.
@ 2026-01-07  3:07 Daniel Palmer
  2026-01-07  3:07 ` [RFC PATCH 1/2] of: Add a variant of of_device_is_compatible() that can be build time culled Daniel Palmer
                   ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Daniel Palmer @ 2026-01-07  3:07 UTC (permalink / raw)
  To: linusw, brgl, robh, saravanak, linux-gpio, devicetree
  Cc: linux-kernel, Daniel Palmer

I like devicetree but I dislike the way it removes the compiler's ability
to remove dead code because the compiler can't know what is in the runtime
devicetree.

One common pattern is checking if a node is compatible with some compatible
string that should never happen on the target machine. i.e checking for
something that only exists on a very specific PPC platform on ARM etc.

For weird people like me that want to run Linux on FPGA softcores, processors
from 1979 etc it is better to have the most minimal kernel config possible and
for the compiler to strip out as much unneeded code and data as possible.

The following is my quick hack to add a way to hint to the compiler whether
a specific compatible check is even possible or not so it can remove deadcode
and then an example usecase.

I think this is cleaner than #ifdef..#endif all over the place but maybe
someone has a nicer way to do it.

Daniel Palmer (2):
  of: Add a variant of of_device_is_compatible() that can be build time
    culled
  gpiolib: of: Remove a bunch of compatible checks for spi controllers
    you don't have

 drivers/gpio/gpiolib-of.c | 6 +++---
 include/linux/of.h        | 2 ++
 2 files changed, 5 insertions(+), 3 deletions(-)

-- 
2.51.0


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [RFC PATCH 1/2] of: Add a variant of of_device_is_compatible() that can be build time culled
  2026-01-07  3:07 [RFC PATCH 0/2] Let the compiler remove unneeded compatible checks Daniel Palmer
@ 2026-01-07  3:07 ` Daniel Palmer
  2026-01-08 23:38   ` Rob Herring
  2026-01-07  3:07 ` [RFC PATCH 2/2] gpiolib: of: Remove a bunch of compatible checks for spi controllers you don't have Daniel Palmer
  2026-01-07  8:17 ` [RFC PATCH 0/2] Let the compiler remove unneeded compatible checks Bartosz Golaszewski
  2 siblings, 1 reply; 10+ messages in thread
From: Daniel Palmer @ 2026-01-07  3:07 UTC (permalink / raw)
  To: linusw, brgl, robh, saravanak, linux-gpio, devicetree
  Cc: linux-kernel, Daniel Palmer

In a lot of places we are using of_device_is_compatible() to check for quirks
etc that are simply not possible on some targets, i.e. a piece of hardware
that needs special handling is only on one specific ARM machine and your
target isn't even ARM.

Add of_device_is_possible_and_compatible() that also takes a Kconfig
symbol and checks if that is enabled before calling of_device_is_compatible().

The Kconfig symbol is build time constant and the compiler should
remove the call to of_device_is_compatible() if it is unneeded and also
remove the data for the compatible string.

Another merit of this is that in places were we are checking for quirks
outside of drivers themselves, i.e. in the gpio and spi subsystems where
some legacy devicetree handling is being handled for specific devices
is in the core code, when the drivers that need the quirks are removed
their Kconfig symbol should also be removed and it'll be easier to spot
that the quirk handling can also go.

Signed-off-by: Daniel Palmer <daniel@thingy.jp>
---
 include/linux/of.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/linux/of.h b/include/linux/of.h
index 9bbdcf25a2b4..70be20b0be22 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -358,6 +358,8 @@ extern int of_property_read_string_helper(const struct device_node *np,
 					      const char **out_strs, size_t sz, int index);
 extern int of_device_is_compatible(const struct device_node *device,
 				   const char *);
+#define of_device_is_possible_and_compatible(symbol, device, string) \
+	(IS_ENABLED(symbol) && of_device_is_compatible(device, string))
 extern int of_device_compatible_match(const struct device_node *device,
 				      const char *const *compat);
 extern bool of_device_is_available(const struct device_node *device);
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [RFC PATCH 2/2] gpiolib: of: Remove a bunch of compatible checks for spi controllers you don't have
  2026-01-07  3:07 [RFC PATCH 0/2] Let the compiler remove unneeded compatible checks Daniel Palmer
  2026-01-07  3:07 ` [RFC PATCH 1/2] of: Add a variant of of_device_is_compatible() that can be build time culled Daniel Palmer
@ 2026-01-07  3:07 ` Daniel Palmer
  2026-01-07  8:17 ` [RFC PATCH 0/2] Let the compiler remove unneeded compatible checks Bartosz Golaszewski
  2 siblings, 0 replies; 10+ messages in thread
From: Daniel Palmer @ 2026-01-07  3:07 UTC (permalink / raw)
  To: linusw, brgl, robh, saravanak, linux-gpio, devicetree
  Cc: linux-kernel, Daniel Palmer

Use of_device_is_possible_and_compatible() + The kconfig symbols that should indicate
if the compatibles being checked are even possible to allow the compiler to totally
remove the code for most users.

Signed-off-by: Daniel Palmer <daniel@thingy.jp>
---
 drivers/gpio/gpiolib-of.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
index 8657379e9165..2c87f1fa1f95 100644
--- a/drivers/gpio/gpiolib-of.c
+++ b/drivers/gpio/gpiolib-of.c
@@ -93,9 +93,9 @@ static int of_gpio_spi_cs_get_count(const struct device_node *np,
 		return 0;
 	if (!con_id || strcmp(con_id, "cs"))
 		return 0;
-	if (!of_device_is_compatible(np, "fsl,spi") &&
-	    !of_device_is_compatible(np, "aeroflexgaisler,spictrl") &&
-	    !of_device_is_compatible(np, "ibm,ppc4xx-spi"))
+	if (!of_device_is_possible_and_compatible(CONFIG_SPI_FSL_SPI, np, "fsl,spi") &&
+	    !of_device_is_possible_and_compatible(CONFIG_SPI_FSL_SPI, np, "aeroflexgaisler,spictrl") &&
+	    !of_device_is_possible_and_compatible(CONFIG_SPI_PPC4xx, np, "ibm,ppc4xx-spi"))
 		return 0;
 	return of_gpio_named_count(np, "gpios");
 }
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [RFC PATCH 0/2] Let the compiler remove unneeded compatible checks.
  2026-01-07  3:07 [RFC PATCH 0/2] Let the compiler remove unneeded compatible checks Daniel Palmer
  2026-01-07  3:07 ` [RFC PATCH 1/2] of: Add a variant of of_device_is_compatible() that can be build time culled Daniel Palmer
  2026-01-07  3:07 ` [RFC PATCH 2/2] gpiolib: of: Remove a bunch of compatible checks for spi controllers you don't have Daniel Palmer
@ 2026-01-07  8:17 ` Bartosz Golaszewski
  2 siblings, 0 replies; 10+ messages in thread
From: Bartosz Golaszewski @ 2026-01-07  8:17 UTC (permalink / raw)
  To: Daniel Palmer
  Cc: linusw, robh, saravanak, linux-gpio, devicetree, linux-kernel

On Wed, Jan 7, 2026 at 4:07 AM Daniel Palmer <daniel@thingy.jp> wrote:
>
> I like devicetree but I dislike the way it removes the compiler's ability
> to remove dead code because the compiler can't know what is in the runtime
> devicetree.
>
> One common pattern is checking if a node is compatible with some compatible
> string that should never happen on the target machine. i.e checking for
> something that only exists on a very specific PPC platform on ARM etc.
>
> For weird people like me that want to run Linux on FPGA softcores, processors
> from 1979 etc it is better to have the most minimal kernel config possible and
> for the compiler to strip out as much unneeded code and data as possible.
>
> The following is my quick hack to add a way to hint to the compiler whether
> a specific compatible check is even possible or not so it can remove deadcode
> and then an example usecase.
>
> I think this is cleaner than #ifdef..#endif all over the place but maybe
> someone has a nicer way to do it.
>
> Daniel Palmer (2):
>   of: Add a variant of of_device_is_compatible() that can be build time
>     culled
>   gpiolib: of: Remove a bunch of compatible checks for spi controllers
>     you don't have
>
>  drivers/gpio/gpiolib-of.c | 6 +++---
>  include/linux/of.h        | 2 ++
>  2 files changed, 5 insertions(+), 3 deletions(-)
>
> --
> 2.51.0
>

That is an awesome idea, let's hear what Rob says but for GPIO I'll be
happy to take it.

Bart

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RFC PATCH 1/2] of: Add a variant of of_device_is_compatible() that can be build time culled
  2026-01-07  3:07 ` [RFC PATCH 1/2] of: Add a variant of of_device_is_compatible() that can be build time culled Daniel Palmer
@ 2026-01-08 23:38   ` Rob Herring
  2026-01-09  2:51     ` Daniel Palmer
  0 siblings, 1 reply; 10+ messages in thread
From: Rob Herring @ 2026-01-08 23:38 UTC (permalink / raw)
  To: Daniel Palmer
  Cc: linusw, brgl, saravanak, linux-gpio, devicetree, linux-kernel

On Wed, Jan 07, 2026 at 12:07:30PM +0900, Daniel Palmer wrote:
> In a lot of places we are using of_device_is_compatible() to check for quirks

I'm assuming 'a lot' is not just 3 places? Got a rough estimate?

This seems fine to me assuming there are more.

> etc that are simply not possible on some targets, i.e. a piece of hardware
> that needs special handling is only on one specific ARM machine and your
> target isn't even ARM.
> 
> Add of_device_is_possible_and_compatible() that also takes a Kconfig
> symbol and checks if that is enabled before calling of_device_is_compatible().
> 
> The Kconfig symbol is build time constant and the compiler should
> remove the call to of_device_is_compatible() if it is unneeded and also
> remove the data for the compatible string.
> 
> Another merit of this is that in places were we are checking for quirks
> outside of drivers themselves, i.e. in the gpio and spi subsystems where
> some legacy devicetree handling is being handled for specific devices
> is in the core code, when the drivers that need the quirks are removed
> their Kconfig symbol should also be removed and it'll be easier to spot
> that the quirk handling can also go.
> 
> Signed-off-by: Daniel Palmer <daniel@thingy.jp>
> ---
>  include/linux/of.h | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/include/linux/of.h b/include/linux/of.h
> index 9bbdcf25a2b4..70be20b0be22 100644
> --- a/include/linux/of.h
> +++ b/include/linux/of.h
> @@ -358,6 +358,8 @@ extern int of_property_read_string_helper(const struct device_node *np,
>  					      const char **out_strs, size_t sz, int index);
>  extern int of_device_is_compatible(const struct device_node *device,
>  				   const char *);
> +#define of_device_is_possible_and_compatible(symbol, device, string) \
> +	(IS_ENABLED(symbol) && of_device_is_compatible(device, string))
>  extern int of_device_compatible_match(const struct device_node *device,
>  				      const char *const *compat);
>  extern bool of_device_is_available(const struct device_node *device);
> -- 
> 2.51.0
> 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RFC PATCH 1/2] of: Add a variant of of_device_is_compatible() that can be build time culled
  2026-01-08 23:38   ` Rob Herring
@ 2026-01-09  2:51     ` Daniel Palmer
  2026-01-09 14:29       ` Rob Herring
  2026-01-11 10:59       ` Linus Walleij
  0 siblings, 2 replies; 10+ messages in thread
From: Daniel Palmer @ 2026-01-09  2:51 UTC (permalink / raw)
  To: Rob Herring; +Cc: linusw, brgl, saravanak, linux-gpio, devicetree, linux-kernel

Hi Rob,

On Fri, 9 Jan 2026 at 08:38, Rob Herring <robh@kernel.org> wrote:
>
> On Wed, Jan 07, 2026 at 12:07:30PM +0900, Daniel Palmer wrote:
> > In a lot of places we are using of_device_is_compatible() to check for quirks
>
> I'm assuming 'a lot' is not just 3 places? Got a rough estimate?
>
> This seems fine to me assuming there are more.

In core code (like the gpio core, and not in a specific driver) there
are only a few places. I think around 10.
There are more when we get into drivers that handle lots of variants
of the same hardware and check the compatible string during probe.
(There are ~700 calls to of_device_is_compatible() in drivers/, most
of which seems to be quirks checking during probe).

Since this didn't get shot down I'll prepare a version that has more examples.

Thanks,

Daniel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RFC PATCH 1/2] of: Add a variant of of_device_is_compatible() that can be build time culled
  2026-01-09  2:51     ` Daniel Palmer
@ 2026-01-09 14:29       ` Rob Herring
  2026-01-12  2:32         ` Saravana Kannan
  2026-01-11 10:59       ` Linus Walleij
  1 sibling, 1 reply; 10+ messages in thread
From: Rob Herring @ 2026-01-09 14:29 UTC (permalink / raw)
  To: Daniel Palmer
  Cc: linusw, brgl, saravanak, linux-gpio, devicetree, linux-kernel

On Fri, Jan 09, 2026 at 11:51:52AM +0900, Daniel Palmer wrote:
> Hi Rob,
> 
> On Fri, 9 Jan 2026 at 08:38, Rob Herring <robh@kernel.org> wrote:
> >
> > On Wed, Jan 07, 2026 at 12:07:30PM +0900, Daniel Palmer wrote:
> > > In a lot of places we are using of_device_is_compatible() to check for quirks
> >
> > I'm assuming 'a lot' is not just 3 places? Got a rough estimate?
> >
> > This seems fine to me assuming there are more.
> 
> In core code (like the gpio core, and not in a specific driver) there
> are only a few places. I think around 10.
> There are more when we get into drivers that handle lots of variants
> of the same hardware and check the compatible string during probe.
> (There are ~700 calls to of_device_is_compatible() in drivers/, most
> of which seems to be quirks checking during probe).

Generally in drivers, it is preferred to use match data rather than 
of_device_is_compatible(). And if we're going in and touching 
of_device_is_compatible() in drivers, that's what we want to do. Using 
match data of course doesn't help your cause of reducing size. I suppose 
you could define a macro that includes a compatible in the match table 
or not. If the match data is function ptrs, then if those functions 
aren't referenced, they would be dropped by the compiler.

Rob

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RFC PATCH 1/2] of: Add a variant of of_device_is_compatible() that can be build time culled
  2026-01-09  2:51     ` Daniel Palmer
  2026-01-09 14:29       ` Rob Herring
@ 2026-01-11 10:59       ` Linus Walleij
  1 sibling, 0 replies; 10+ messages in thread
From: Linus Walleij @ 2026-01-11 10:59 UTC (permalink / raw)
  To: Daniel Palmer
  Cc: Rob Herring, brgl, saravanak, linux-gpio, devicetree,
	linux-kernel

Hi Daniel,

thanks for your patch!

I like the idea in this patch set. Footprint is something we need
to think more about, if for nothing else so for the increasing tendency
of RAM prices.

On Fri, Jan 9, 2026 at 3:52 AM Daniel Palmer <daniel@thingy.jp> wrote:
> On Fri, 9 Jan 2026 at 08:38, Rob Herring <robh@kernel.org> wrote:
> >
> > On Wed, Jan 07, 2026 at 12:07:30PM +0900, Daniel Palmer wrote:
> > > In a lot of places we are using of_device_is_compatible() to check for quirks
> >
> > I'm assuming 'a lot' is not just 3 places? Got a rough estimate?
> >
> > This seems fine to me assuming there are more.
>
> In core code (like the gpio core, and not in a specific driver) there
> are only a few places. I think around 10.

Actually, if you look in gpiolib-of.c in e.g. of_gpio_try_fixup_polarity()
you find:

#if IS_ENABLED(CONFIG_LCD_HX8357)
                /*
                 * Himax LCD controllers used incorrectly named
                 * "gpios-reset" property and also specified wrong
                 * polarity.
                 */
                { "himax,hx8357",       "gpios-reset",  false },
                { "himax,hx8369",       "gpios-reset",  false },
#endif

etc etc etc.

It is actually a similar idea just clunkier, but maybe necessary
for these quirks since they are in a table.

But as you can see, there is some of the same thinking: if it's
not configured in, then we need to compile it out.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RFC PATCH 1/2] of: Add a variant of of_device_is_compatible() that can be build time culled
  2026-01-09 14:29       ` Rob Herring
@ 2026-01-12  2:32         ` Saravana Kannan
  2026-01-12  3:10           ` Daniel Palmer
  0 siblings, 1 reply; 10+ messages in thread
From: Saravana Kannan @ 2026-01-12  2:32 UTC (permalink / raw)
  To: Rob Herring
  Cc: Daniel Palmer, linusw, brgl, saravanak, linux-gpio, devicetree,
	linux-kernel

On Fri, Jan 9, 2026 at 6:29 AM Rob Herring <robh@kernel.org> wrote:
>
> On Fri, Jan 09, 2026 at 11:51:52AM +0900, Daniel Palmer wrote:
> > Hi Rob,
> >
> > On Fri, 9 Jan 2026 at 08:38, Rob Herring <robh@kernel.org> wrote:
> > >
> > > On Wed, Jan 07, 2026 at 12:07:30PM +0900, Daniel Palmer wrote:
> > > > In a lot of places we are using of_device_is_compatible() to check for quirks
> > >
> > > I'm assuming 'a lot' is not just 3 places? Got a rough estimate?
> > >
> > > This seems fine to me assuming there are more.
> >
> > In core code (like the gpio core, and not in a specific driver) there
> > are only a few places. I think around 10.
> > There are more when we get into drivers that handle lots of variants
> > of the same hardware and check the compatible string during probe.
> > (There are ~700 calls to of_device_is_compatible() in drivers/, most
> > of which seems to be quirks checking during probe).
>
> Generally in drivers, it is preferred to use match data rather than
> of_device_is_compatible(). And if we're going in and touching
> of_device_is_compatible() in drivers, that's what we want to do. Using
> match data of course doesn't help your cause of reducing size. I suppose
> you could define a macro that includes a compatible in the match table
> or not. If the match data is function ptrs, then if those functions
> aren't referenced, they would be dropped by the compiler.

For the 10 or so instances in the core, I'm not sure the macro is even
worth it. It's just hiding the IS_ENABLED() and obscuring the intent
for not much of a reduction in code size. Not going to Nack it if Rob
agrees, but I don't see the point of the macro. I see the point behind
the idea though.

Also, if we do land it, maybe call it "enabled" instead of "possible"?
That lines up better with IS_ENABLED.

-Saravana

>
> Rob

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RFC PATCH 1/2] of: Add a variant of of_device_is_compatible() that can be build time culled
  2026-01-12  2:32         ` Saravana Kannan
@ 2026-01-12  3:10           ` Daniel Palmer
  0 siblings, 0 replies; 10+ messages in thread
From: Daniel Palmer @ 2026-01-12  3:10 UTC (permalink / raw)
  To: Saravana Kannan
  Cc: Rob Herring, linusw, brgl, linux-gpio, devicetree, linux-kernel

Hi Saravana,

On Mon, 12 Jan 2026 at 11:32, Saravana Kannan <saravanak@kernel.org> wrote:

> For the 10 or so instances in the core, I'm not sure the macro is even
> worth it. It's just hiding the IS_ENABLED() and obscuring the intent
> for not much of a reduction in code size. Not going to Nack it if Rob
> agrees, but I don't see the point of the macro. I see the point behind
> the idea though.

Understood. This is very niche. In my case by doing stuff like this I
could make the kernel small enough for my userland to boot again.
I have no mmu, 8MB of RAM, CPU frequency in the tens of MHz. Not very common.

But I think it'd also be nice if all of the tons of arm64 machines out
there don't check for hacks for stuff that is only in ppc and
therefore can never happen. :)
While looking through the users of of_device_is_compatible() I also
found some, I think, bad patterns that are probably worse than the
unneeded code/data.

For example, in drivers/usb/host/uhci-platform.c we have:

static int uhci_hcd_platform_probe(struct platform_device *pdev)
{
...

if (of_device_is_compatible(np, "aspeed,ast2400-uhci") ||
   of_device_is_compatible(np, "aspeed,ast2500-uhci") ||
   of_device_is_compatible(np, "aspeed,ast2600-uhci")) {
uhci->is_aspeed = 1;
dev_info(&pdev->dev,
"Enabled Aspeed implementation workarounds\n");
}
...

The compiler will always include those calls if this driver is built.
But the is_aspeed flag they are setting is accessed via a macro that
always returns false if the aspeed platform that needs workarounds
isn't enabled to remove the unneeded code.
I don't think this is a bug that can cause problems but this means if
you use a DT with those strings and the kernel doesn't have that
platform enabled (and it somehow boots far enough etc etc) you'd see
this message saying the workarounds are enabled but actually the
compiler removed all of that code and the message is a lie.

I think Rob wrote basically the same thing but it seems like
of_device_is_compatible() in probe functions is just a bad idea and
workaround flags etc should be in the match data not decided at
runtime with of_device_is_compatible().

Cheers,

Daniel

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2026-01-12  3:10 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-07  3:07 [RFC PATCH 0/2] Let the compiler remove unneeded compatible checks Daniel Palmer
2026-01-07  3:07 ` [RFC PATCH 1/2] of: Add a variant of of_device_is_compatible() that can be build time culled Daniel Palmer
2026-01-08 23:38   ` Rob Herring
2026-01-09  2:51     ` Daniel Palmer
2026-01-09 14:29       ` Rob Herring
2026-01-12  2:32         ` Saravana Kannan
2026-01-12  3:10           ` Daniel Palmer
2026-01-11 10:59       ` Linus Walleij
2026-01-07  3:07 ` [RFC PATCH 2/2] gpiolib: of: Remove a bunch of compatible checks for spi controllers you don't have Daniel Palmer
2026-01-07  8:17 ` [RFC PATCH 0/2] Let the compiler remove unneeded compatible checks Bartosz Golaszewski

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