* [PATCH 0/6] Dynamic aspeed-smc flash chips via "reserved" DT status
@ 2021-09-29 11:54 Zev Weiss
2021-09-29 11:54 ` [PATCH 1/6] of: base: Add function to check for status = "reserved" Zev Weiss
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Zev Weiss @ 2021-09-29 11:54 UTC (permalink / raw)
To: openbmc
Cc: Greg Kroah-Hartman, Jeremy Kerr, Joel Stanley,
Cédric Le Goater, Zev Weiss, Rob Herring, Frank Rowand,
devicetree, linux-kernel, Miquel Raynal, Richard Weinberger,
Vignesh Raghavendra, linux-mtd, Tudor Ambarus, Michael Walle,
Pratyush Yadav, Andrew Jeffery, linux-arm-kernel, linux-aspeed
Hello,
This patch series aims to improve a scenario that arises in OpenBMC
and which isn't handled very well at the moment. Certain devices, the
example at hand being the flash chip used to store the host's firmware
(e.g. the BIOS), may be shared between the BMC and the host system but
only available to one or the other at any given time. The device may
thus be effectively off-limits to the BMC when it boots, and only
usable after userspace performs the necessary steps to coordinate
appropriately with the host (tracking its power state, twiddling
GPIOs, sending IPMI commands, etc.).
Neither the "okay" nor the "disabled" device-tree status values works
nicely for the flash device this case -- an "okay" device gets probed
automatically as soon as the device and a driver for it are available,
and a "disabled" one gets forgotten about entirely, whereas we want
the BMC's kernel to be aware of the existence of the device, but not
try to actually do anything with it (i.e. probe it) until explicitly
requested to do so by userspace.
However, while there's no support for it currently in the kernel tree,
the device-tree spec [0] also lists "reserved" as a possible status
value, and its description seems like a fairly reasonable fit for this
situation:
Indicates that the device is operational, but should not be used.
Typically this is used for devices that are controlled by another
software component, such as platform firmware.
These patches start making use of this status value in the aspeed-smc
driver. The first patch adds a companion routine to
of_device_is_available() that checks for a "reserved" status instead
of "okay". The second patch is a small MTD adjustment to allow an
unregistered device to be cleanly re-registered. Patches 3 through 5
modify the aspeed-smc driver to allow individual chips to be attached
and detached at runtime, and to avoid automatically attaching any
marked as reserved. Finally, patch 6 employs the newly-supported
status in adding support for the BIOS flash device to the ASRock Rack
e3c246d4i BMC.
Thanks,
Zev
[0] https://github.com/devicetree-org/devicetree-specification/releases/download/v0.3/devicetree-specification-v0.3.pdf
Zev Weiss (6):
of: base: Add function to check for status = "reserved"
mtd: core: clear out unregistered devices a bit more
mtd: spi-nor: aspeed: Refactor registration/unregistration
mtd: spi-nor: aspeed: Allow attaching & detaching chips at runtime
mtd: spi-nor: aspeed: Don't automatically attach reserved chips
ARM: dts: aspeed: Add e3c246d4i BIOS flash device
.../ABI/stable/sysfs-driver-aspeed-smc | 17 ++
.../boot/dts/aspeed-bmc-asrock-e3c246d4i.dts | 16 ++
drivers/mtd/mtdcore.c | 7 +-
drivers/mtd/spi-nor/controllers/aspeed-smc.c | 177 +++++++++++++++---
drivers/of/base.c | 53 +++++-
include/linux/of.h | 6 +
6 files changed, 238 insertions(+), 38 deletions(-)
create mode 100644 Documentation/ABI/stable/sysfs-driver-aspeed-smc
--
2.33.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/6] of: base: Add function to check for status = "reserved"
2021-09-29 11:54 [PATCH 0/6] Dynamic aspeed-smc flash chips via "reserved" DT status Zev Weiss
@ 2021-09-29 11:54 ` Zev Weiss
2021-09-29 15:49 ` Rob Herring
2021-09-29 11:54 ` [PATCH 6/6] ARM: dts: aspeed: Add e3c246d4i BIOS flash device Zev Weiss
2021-09-29 16:08 ` [PATCH 0/6] Dynamic aspeed-smc flash chips via "reserved" DT status Rob Herring
2 siblings, 1 reply; 6+ messages in thread
From: Zev Weiss @ 2021-09-29 11:54 UTC (permalink / raw)
To: openbmc
Cc: Greg Kroah-Hartman, Jeremy Kerr, Joel Stanley,
Cédric Le Goater, Zev Weiss, Rob Herring, Frank Rowand,
devicetree, linux-kernel
Per v0.3 of the Devicetree Specification [0]:
Indicates that the device is operational, but should not be used.
Typically this is used for devices that are controlled by another
software component, such as platform firmware.
One use-case for this is in OpenBMC, where certain devices (such as a
BIOS flash chip) may be shared by the host and the BMC, but cannot be
accessed by the BMC during its usual boot-time device probing, because
they require additional (potentially elaborate) coordination with the
host to arbitrate which processor is controlling the device.
Devices marked with this status should thus be instantiated, but not
have a driver bound to them or be otherwise touched.
[0] https://github.com/devicetree-org/devicetree-specification/releases/download/v0.3/devicetree-specification-v0.3.pdf
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
---
drivers/of/base.c | 53 +++++++++++++++++++++++++++++++++++++++-------
include/linux/of.h | 6 ++++++
2 files changed, 51 insertions(+), 8 deletions(-)
diff --git a/drivers/of/base.c b/drivers/of/base.c
index f720c0d246f2..c5cc178fc6bd 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -579,14 +579,18 @@ int of_machine_is_compatible(const char *compat)
EXPORT_SYMBOL(of_machine_is_compatible);
/**
- * __of_device_is_available - check if a device is available for use
+ * __of_device_check_status - check if a device's status matches a particular string
*
- * @device: Node to check for availability, with locks already held
+ * @device: Node to check status of, with locks already held
+ * @val: Status string to check for
+ * @alt: Optional alternate status string to check for (NULL to check only @val)
+ * @dflt: default to return if status property absent
*
- * Return: True if the status property is absent or set to "okay" or "ok",
- * false otherwise
+ * Return: True if status property exists and matches either @val or @alt.
+ * @dflt if status property is absent. False otherwise.
*/
-static bool __of_device_is_available(const struct device_node *device)
+static bool __of_device_check_status(const struct device_node *device, const char *val,
+ const char *alt, bool dflt)
{
const char *status;
int statlen;
@@ -595,17 +599,30 @@ static bool __of_device_is_available(const struct device_node *device)
return false;
status = __of_get_property(device, "status", &statlen);
- if (status == NULL)
- return true;
+ if (!status)
+ return dflt;
if (statlen > 0) {
- if (!strcmp(status, "okay") || !strcmp(status, "ok"))
+ if (!strcmp(status, val) || (alt && !strcmp(status, alt)))
return true;
}
return false;
}
+/**
+ * __of_device_is_available - check if a device is available for use
+ *
+ * @device: Node to check for availability, with locks already held
+ *
+ * Return: True if the status property is absent or set to "okay" or "ok",
+ * false otherwise
+ */
+static bool __of_device_is_available(const struct device_node *device)
+{
+ return __of_device_check_status(device, "okay", "ok", true);
+}
+
/**
* of_device_is_available - check if a device is available for use
*
@@ -627,6 +644,26 @@ bool of_device_is_available(const struct device_node *device)
}
EXPORT_SYMBOL(of_device_is_available);
+/**
+ * of_device_is_reserved - check if a device is marked as reserved
+ *
+ * @device: Node to check for reservation
+ *
+ * Return: True if the status property is set to "reserved", false otherwise
+ */
+bool of_device_is_reserved(const struct device_node *device)
+{
+ unsigned long flags;
+ bool res;
+
+ raw_spin_lock_irqsave(&devtree_lock, flags);
+ res = __of_device_check_status(device, "reserved", NULL, false);
+ raw_spin_unlock_irqrestore(&devtree_lock, flags);
+
+ return res;
+}
+EXPORT_SYMBOL(of_device_is_reserved);
+
/**
* of_device_is_big_endian - check if a device has BE registers
*
diff --git a/include/linux/of.h b/include/linux/of.h
index 6f1c41f109bb..aa9762da5e7c 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -345,6 +345,7 @@ extern int of_device_is_compatible(const struct device_node *device,
extern int of_device_compatible_match(struct device_node *device,
const char *const *compat);
extern bool of_device_is_available(const struct device_node *device);
+extern bool of_device_is_reserved(const struct device_node *device);
extern bool of_device_is_big_endian(const struct device_node *device);
extern const void *of_get_property(const struct device_node *node,
const char *name,
@@ -707,6 +708,11 @@ static inline bool of_device_is_available(const struct device_node *device)
return false;
}
+static inline bool of_device_is_reserved(const struct device_node *device)
+{
+ return false;
+}
+
static inline bool of_device_is_big_endian(const struct device_node *device)
{
return false;
--
2.33.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 6/6] ARM: dts: aspeed: Add e3c246d4i BIOS flash device
2021-09-29 11:54 [PATCH 0/6] Dynamic aspeed-smc flash chips via "reserved" DT status Zev Weiss
2021-09-29 11:54 ` [PATCH 1/6] of: base: Add function to check for status = "reserved" Zev Weiss
@ 2021-09-29 11:54 ` Zev Weiss
2021-09-29 16:08 ` [PATCH 0/6] Dynamic aspeed-smc flash chips via "reserved" DT status Rob Herring
2 siblings, 0 replies; 6+ messages in thread
From: Zev Weiss @ 2021-09-29 11:54 UTC (permalink / raw)
To: openbmc
Cc: Greg Kroah-Hartman, Jeremy Kerr, Joel Stanley,
Cédric Le Goater, Zev Weiss, Rob Herring, Andrew Jeffery,
devicetree, linux-arm-kernel, linux-aspeed, linux-kernel
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
---
.../arm/boot/dts/aspeed-bmc-asrock-e3c246d4i.dts | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/arch/arm/boot/dts/aspeed-bmc-asrock-e3c246d4i.dts b/arch/arm/boot/dts/aspeed-bmc-asrock-e3c246d4i.dts
index 9b4cf5ebe6d5..456f4de53869 100644
--- a/arch/arm/boot/dts/aspeed-bmc-asrock-e3c246d4i.dts
+++ b/arch/arm/boot/dts/aspeed-bmc-asrock-e3c246d4i.dts
@@ -68,6 +68,22 @@ flash@0 {
};
};
+&spi1 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spi1_default>;
+ flash@0 {
+ /*
+ * The BIOS SPI flash is shared with the host via an
+ * external mux, and is not accessible by the BMC by
+ * default (hence "reserved" rather than "okay").
+ */
+ status = "reserved";
+ label = "bios";
+ m25p,fast-read;
+ };
+};
+
&uart5 {
status = "okay";
};
--
2.33.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 1/6] of: base: Add function to check for status = "reserved"
2021-09-29 11:54 ` [PATCH 1/6] of: base: Add function to check for status = "reserved" Zev Weiss
@ 2021-09-29 15:49 ` Rob Herring
0 siblings, 0 replies; 6+ messages in thread
From: Rob Herring @ 2021-09-29 15:49 UTC (permalink / raw)
To: Zev Weiss
Cc: OpenBMC Maillist, Greg Kroah-Hartman, Jeremy Kerr, Joel Stanley,
Cédric Le Goater, Frank Rowand, devicetree,
linux-kernel@vger.kernel.org
On Wed, Sep 29, 2021 at 6:54 AM Zev Weiss <zev@bewilderbeest.net> wrote:
>
> Per v0.3 of the Devicetree Specification [0]:
>
> Indicates that the device is operational, but should not be used.
> Typically this is used for devices that are controlled by another
> software component, such as platform firmware.
>
> One use-case for this is in OpenBMC, where certain devices (such as a
> BIOS flash chip) may be shared by the host and the BMC, but cannot be
> accessed by the BMC during its usual boot-time device probing, because
> they require additional (potentially elaborate) coordination with the
> host to arbitrate which processor is controlling the device.
>
> Devices marked with this status should thus be instantiated, but not
> have a driver bound to them or be otherwise touched.
>
> [0] https://github.com/devicetree-org/devicetree-specification/releases/download/v0.3/devicetree-specification-v0.3.pdf
>
> Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
> ---
> drivers/of/base.c | 53 +++++++++++++++++++++++++++++++++++++++-------
> include/linux/of.h | 6 ++++++
> 2 files changed, 51 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/of/base.c b/drivers/of/base.c
> index f720c0d246f2..c5cc178fc6bd 100644
> --- a/drivers/of/base.c
> +++ b/drivers/of/base.c
> @@ -579,14 +579,18 @@ int of_machine_is_compatible(const char *compat)
> EXPORT_SYMBOL(of_machine_is_compatible);
>
> /**
> - * __of_device_is_available - check if a device is available for use
> + * __of_device_check_status - check if a device's status matches a particular string
> *
> - * @device: Node to check for availability, with locks already held
> + * @device: Node to check status of, with locks already held
> + * @val: Status string to check for
> + * @alt: Optional alternate status string to check for (NULL to check only @val)
> + * @dflt: default to return if status property absent
> *
> - * Return: True if the status property is absent or set to "okay" or "ok",
> - * false otherwise
> + * Return: True if status property exists and matches either @val or @alt.
> + * @dflt if status property is absent. False otherwise.
> */
> -static bool __of_device_is_available(const struct device_node *device)
> +static bool __of_device_check_status(const struct device_node *device, const char *val,
> + const char *alt, bool dflt)
How about val==NULL means available/okay and then you can get rid of
alt and dflt.
Otherwise, I'd simply not try to share the implementation here and
just add of_device_is_reserved().
Rob
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 0/6] Dynamic aspeed-smc flash chips via "reserved" DT status
2021-09-29 11:54 [PATCH 0/6] Dynamic aspeed-smc flash chips via "reserved" DT status Zev Weiss
2021-09-29 11:54 ` [PATCH 1/6] of: base: Add function to check for status = "reserved" Zev Weiss
2021-09-29 11:54 ` [PATCH 6/6] ARM: dts: aspeed: Add e3c246d4i BIOS flash device Zev Weiss
@ 2021-09-29 16:08 ` Rob Herring
2021-09-29 22:00 ` Zev Weiss
2 siblings, 1 reply; 6+ messages in thread
From: Rob Herring @ 2021-09-29 16:08 UTC (permalink / raw)
To: Zev Weiss
Cc: OpenBMC Maillist, Greg Kroah-Hartman, Jeremy Kerr, Joel Stanley,
Cédric Le Goater, Frank Rowand, devicetree,
linux-kernel@vger.kernel.org, Miquel Raynal, Richard Weinberger,
Vignesh Raghavendra, MTD Maling List, Tudor Ambarus,
Michael Walle, Pratyush Yadav, Andrew Jeffery, linux-arm-kernel,
linux-aspeed
On Wed, Sep 29, 2021 at 6:54 AM Zev Weiss <zev@bewilderbeest.net> wrote:
>
> Hello,
>
> This patch series aims to improve a scenario that arises in OpenBMC
> and which isn't handled very well at the moment. Certain devices, the
> example at hand being the flash chip used to store the host's firmware
> (e.g. the BIOS), may be shared between the BMC and the host system but
> only available to one or the other at any given time. The device may
> thus be effectively off-limits to the BMC when it boots, and only
> usable after userspace performs the necessary steps to coordinate
> appropriately with the host (tracking its power state, twiddling
> GPIOs, sending IPMI commands, etc.).
>
> Neither the "okay" nor the "disabled" device-tree status values works
> nicely for the flash device this case -- an "okay" device gets probed
> automatically as soon as the device and a driver for it are available,
> and a "disabled" one gets forgotten about entirely, whereas we want
> the BMC's kernel to be aware of the existence of the device, but not
> try to actually do anything with it (i.e. probe it) until explicitly
> requested to do so by userspace.
While Linux treats 'disabled' as gone forever, that's not exactly what
the spec says. Either disabled or reserved could change in theory. But
I do agree 'reserved' is the right choice for your use.
> However, while there's no support for it currently in the kernel tree,
> the device-tree spec [0] also lists "reserved" as a possible status
> value, and its description seems like a fairly reasonable fit for this
> situation:
>
> Indicates that the device is operational, but should not be used.
> Typically this is used for devices that are controlled by another
> software component, such as platform firmware.
>
> These patches start making use of this status value in the aspeed-smc
> driver. The first patch adds a companion routine to
> of_device_is_available() that checks for a "reserved" status instead
> of "okay". The second patch is a small MTD adjustment to allow an
> unregistered device to be cleanly re-registered. Patches 3 through 5
> modify the aspeed-smc driver to allow individual chips to be attached
> and detached at runtime, and to avoid automatically attaching any
> marked as reserved. Finally, patch 6 employs the newly-supported
> status in adding support for the BIOS flash device to the ASRock Rack
> e3c246d4i BMC.
I'm not sure this should be MTD specific. There's other cases where we
may want devices to become available. So the question is whether there
should be a more generic mechanism rather than each subsystem coming
up with their own thing.
There's out of tree support for applying overlays which could be used
here. The issue with it is we don't want it to be unconstrained where
an overlay can make any change anywhere in a DT.
Another possibility is making 'status' writeable from userspace. It is
just a sysfs file. That too may need to be opt-in.
Rob
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 0/6] Dynamic aspeed-smc flash chips via "reserved" DT status
2021-09-29 16:08 ` [PATCH 0/6] Dynamic aspeed-smc flash chips via "reserved" DT status Rob Herring
@ 2021-09-29 22:00 ` Zev Weiss
0 siblings, 0 replies; 6+ messages in thread
From: Zev Weiss @ 2021-09-29 22:00 UTC (permalink / raw)
To: Rob Herring
Cc: Zev Weiss, devicetree@vger.kernel.org, Vignesh Raghavendra,
linux-aspeed, Tudor Ambarus, Andrew Jeffery, Greg Kroah-Hartman,
OpenBMC Maillist, linux-kernel@vger.kernel.org,
Richard Weinberger, Michael Walle, MTD Maling List, Miquel Raynal,
Jeremy Kerr, Frank Rowand, Pratyush Yadav, linux-arm-kernel,
Cédric Le Goater
On Wed, Sep 29, 2021 at 09:08:03AM PDT, Rob Herring wrote:
>On Wed, Sep 29, 2021 at 6:54 AM Zev Weiss <zev@bewilderbeest.net> wrote:
>>
>> Hello,
>>
>> This patch series aims to improve a scenario that arises in OpenBMC
>> and which isn't handled very well at the moment. Certain devices, the
>> example at hand being the flash chip used to store the host's firmware
>> (e.g. the BIOS), may be shared between the BMC and the host system but
>> only available to one or the other at any given time. The device may
>> thus be effectively off-limits to the BMC when it boots, and only
>> usable after userspace performs the necessary steps to coordinate
>> appropriately with the host (tracking its power state, twiddling
>> GPIOs, sending IPMI commands, etc.).
>>
>> Neither the "okay" nor the "disabled" device-tree status values works
>> nicely for the flash device this case -- an "okay" device gets probed
>> automatically as soon as the device and a driver for it are available,
>> and a "disabled" one gets forgotten about entirely, whereas we want
>> the BMC's kernel to be aware of the existence of the device, but not
>> try to actually do anything with it (i.e. probe it) until explicitly
>> requested to do so by userspace.
>
>While Linux treats 'disabled' as gone forever, that's not exactly what
>the spec says. Either disabled or reserved could change in theory. But
>I do agree 'reserved' is the right choice for your use.
True -- the spec's description of "disabled" also sounds like it could
be an appropriate fit for this case, but the existing (somewhat
different) interpretation in the kernel is well-established enough that
I figured that ship had sailed.
>
>> However, while there's no support for it currently in the kernel tree,
>> the device-tree spec [0] also lists "reserved" as a possible status
>> value, and its description seems like a fairly reasonable fit for this
>> situation:
>>
>> Indicates that the device is operational, but should not be used.
>> Typically this is used for devices that are controlled by another
>> software component, such as platform firmware.
>>
>> These patches start making use of this status value in the aspeed-smc
>> driver. The first patch adds a companion routine to
>> of_device_is_available() that checks for a "reserved" status instead
>> of "okay". The second patch is a small MTD adjustment to allow an
>> unregistered device to be cleanly re-registered. Patches 3 through 5
>> modify the aspeed-smc driver to allow individual chips to be attached
>> and detached at runtime, and to avoid automatically attaching any
>> marked as reserved. Finally, patch 6 employs the newly-supported
>> status in adding support for the BIOS flash device to the ASRock Rack
>> e3c246d4i BMC.
>
>I'm not sure this should be MTD specific. There's other cases where we
>may want devices to become available. So the question is whether there
>should be a more generic mechanism rather than each subsystem coming
>up with their own thing.
>
Agreed, and in fact in an earlier version of these patches I had
approached this via a more generic tweak to the driver-core code to
inhibit attaching drivers to devices marked as reserved. The problem I
had with that is that it ended up being kind of limited in how far down
the device tree it would actually take effect. For example in this
particular case, I could mark the entire aspeed-smc controller as
reserved and prevent the driver core from binding the driver to it, but
nothing more fine-grained than that. If I marked an individual flash
chip behind that controller as reserved, the aspeed-smc driver would get
attached (as expected), but that driver (not the driver core) is
responsible for inspecting its child devices and attaching them, and its
existing probe routine only checks of_device_is_available() and hence
can't distinguish between reserved and disabled.
So while I should probably reincorporate the corresponding driver-core
change, I don't see it as a complete solution, and I don't see an
obvious way to achieve one centrally without requiring modifications in
individual drivers, unfortunately.
>There's out of tree support for applying overlays which could be used
>here. The issue with it is we don't want it to be unconstrained where
>an overlay can make any change anywhere in a DT.
>
Yeah, I'm vaguely aware of the dt-overlay patches, but had been under
the impression that their prospects for mainlining were fairly dim and
hence was looking at alternate approaches (of somewhat more limited scope).
>Another possibility is making 'status' writeable from userspace. It is
>just a sysfs file. That too may need to be opt-in.
>
The sysfs file you're referring to being those under
/sys/firmware/devicetree I assume? That's an interesting idea...in
addition to making it opt-in, we'd presumably need to restrict what
state transitions are allowed (maybe only okay<->reserved?). Keeping
/sys/firmware/fdt in sync with that seems like it might be a bit of a
headache though...perhaps that would just remain a static reflection of
whatever the state was at boot?
Thanks,
Zev
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2021-09-29 23:40 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-09-29 11:54 [PATCH 0/6] Dynamic aspeed-smc flash chips via "reserved" DT status Zev Weiss
2021-09-29 11:54 ` [PATCH 1/6] of: base: Add function to check for status = "reserved" Zev Weiss
2021-09-29 15:49 ` Rob Herring
2021-09-29 11:54 ` [PATCH 6/6] ARM: dts: aspeed: Add e3c246d4i BIOS flash device Zev Weiss
2021-09-29 16:08 ` [PATCH 0/6] Dynamic aspeed-smc flash chips via "reserved" DT status Rob Herring
2021-09-29 22:00 ` Zev Weiss
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).