[PATCH 04/10] x86, olpc: Use a correct version when making up a battery node

From: Lubomir Rintel
Date: Sun Mar 10 2019 - 12:24:56 EST


The XO-1 and XO-1.5 batteries apparently differ in an ability to report
ambient temperature. We need to use a different compatible string for the
XO-1.5 battery.

Previously olpc_dt_fixup() used the presence od the battery node's
compatible property to decide whether the DT is up to date. Now we need
to look for a particular value in the compatible string, to decide

Signed-off-by: Lubomir Rintel <lkundrak@xxxxx>
Acked-by: Pavel Machek <pavel@xxxxxx>

---
Changes since v5:
- Split the "x86, olpc: Don't split string literals when fixing up the DT"
and "x86, olpc: trivial code move in DT fixup" parts off from this
- Clarify some comments

Changes since v1:
- Avoid splitting string literals

arch/x86/platform/olpc/olpc_dt.c | 64 +++++++++++++++++++++++++-------
1 file changed, 50 insertions(+), 14 deletions(-)

diff --git a/arch/x86/platform/olpc/olpc_dt.c b/arch/x86/platform/olpc/olpc_dt.c
index adf98b5623c0..1728f8992850 100644
--- a/arch/x86/platform/olpc/olpc_dt.c
+++ b/arch/x86/platform/olpc/olpc_dt.c
@@ -217,10 +217,28 @@ static u32 __init olpc_dt_get_board_revision(void)
return be32_to_cpu(rev);
}

+int olpc_dt_compatible_match(phandle node, const char *compat)
+{
+ char buf[64];
+ int plen;
+ char *p;
+ int len;
+
+ plen = olpc_dt_getproperty(node, "compatible", buf, sizeof(buf));
+ if (plen <= 0)
+ return 0;
+
+ len = strlen(compat);
+ for (p = buf; p < buf + plen; p += strlen(p) + 1) {
+ if (strcmp(p, compat) == 0)
+ return 1;
+ }
+
+ return 0;
+}
+
void __init olpc_dt_fixup(void)
{
- int r;
- char buf[64];
phandle node;
u32 board_rev;

@@ -228,22 +246,30 @@ void __init olpc_dt_fixup(void)
if (!node)
return;

- /*
- * If the battery node has a compatible property, we are running a new
- * enough firmware and don't have fixups to make.
- */
- r = olpc_dt_getproperty(node, "compatible", buf, sizeof(buf));
- if (r > 0)
- return;
-
- pr_info("PROM DT: Old firmware detected, applying fixes\n");
-
board_rev = olpc_dt_get_board_revision();
if (!board_rev)
return;

if (board_rev >= olpc_board_pre(0xd0)) {
- /* XO-1.5: add dcon device */
+ /* XO-1.5 */
+
+ if (olpc_dt_compatible_match(node, "olpc,xo1.5-battery"))
+ return;
+
+ /* Add olpc,xo1.5-battery compatible marker to battery node */
+ olpc_dt_interpret("\" /battery@0\" find-device");
+ olpc_dt_interpret(" \" olpc,xo1.5-battery\" +compatible");
+ olpc_dt_interpret("device-end");
+
+ if (olpc_dt_compatible_match(node, "olpc,xo1-battery")) {
+ /* If we have a olpc,xo1-battery compatible, then we're
+ * running a new enough firmware that already has
+ * the dcon node.
+ */
+ return;
+ }
+
+ /* Add dcon device */
olpc_dt_interpret("\" /pci/display@1\" find-device");
olpc_dt_interpret(" new-device");
olpc_dt_interpret(" \" dcon\" device-name");
@@ -251,7 +277,17 @@ void __init olpc_dt_fixup(void)
olpc_dt_interpret(" finish-device");
olpc_dt_interpret("device-end");
} else {
- /* XO-1: add dcon device, mark RTC as olpc,xo1-rtc */
+ /* XO-1 */
+
+ if (olpc_dt_compatible_match(node, "olpc,xo1-battery")) {
+ /* If we have a olpc,xo1-battery compatible, then we're
+ * running a new enough firmware that already has
+ * the dcon and RTC nodes.
+ */
+ return;
+ }
+
+ /* Add dcon device, mark RTC as olpc,xo1-rtc */
olpc_dt_interpret("\" /pci/display@1,1\" find-device");
olpc_dt_interpret(" new-device");
olpc_dt_interpret(" \" dcon\" device-name");
--
2.20.1