]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
platform/x86/intel/pmt: use a version struct
authorMichael J. Ruhl <michael.j.ruhl@intel.com>
Sun, 13 Jul 2025 17:29:42 +0000 (13:29 -0400)
committerIlpo Järvinen <ilpo.jarvinen@linux.intel.com>
Tue, 22 Jul 2025 14:39:10 +0000 (17:39 +0300)
In preparation for supporting multiple crashlog versions, use a struct
to keep bit offset info for the status and control bits.

Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Michael J. Ruhl <michael.j.ruhl@intel.com>
Link: https://lore.kernel.org/r/20250713172943.7335-13-michael.j.ruhl@intel.com
[ij: move crashlog_type1_ver0 to its final place & add consts to crashlog_info]
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
drivers/platform/x86/intel/pmt/crashlog.c

index 087b7110ddd26b88b90cc05eae5b6b42403d7ade..db54f881ba576fd89eb371b4e6cb98879f837dce 100644 (file)
 /* Crashlog discovery header types */
 #define CRASH_TYPE_OOBMSM      1
 
-/* Control Flags */
-#define CRASHLOG_FLAG_DISABLE          BIT(28)
-
-/*
- * Bits 29 and 30 control the state of bit 31.
- *
- * Bit 29 will clear bit 31, if set, allowing a new crashlog to be captured.
- * Bit 30 will immediately trigger a crashlog to be generated, setting bit 31.
- * Bit 31 is the read-only status with a 1 indicating log is complete.
- */
-#define CRASHLOG_FLAG_TRIGGER_CLEAR    BIT(29)
-#define CRASHLOG_FLAG_TRIGGER_EXECUTE  BIT(30)
-#define CRASHLOG_FLAG_TRIGGER_COMPLETE BIT(31)
-#define CRASHLOG_FLAG_TRIGGER_MASK     GENMASK(31, 28)
-
 /* Crashlog Discovery Header */
 #define CONTROL_OFFSET         0x0
 #define GUID_OFFSET            0x4
 /* size is in bytes */
 #define GET_SIZE(v)            ((v) * sizeof(u32))
 
+/*
+ * Type 1 Version 0
+ * status and control registers are combined.
+ *
+ * Bits 29 and 30 control the state of bit 31.
+ * Bit 29 will clear bit 31, if set, allowing a new crashlog to be captured.
+ * Bit 30 will immediately trigger a crashlog to be generated, setting bit 31.
+ * Bit 31 is the read-only status with a 1 indicating log is complete.
+ */
+#define TYPE1_VER0_STATUS_OFFSET       0x00
+#define TYPE1_VER0_CONTROL_OFFSET      0x00
+
+#define TYPE1_VER0_DISABLE             BIT(28)
+#define TYPE1_VER0_CLEAR               BIT(29)
+#define TYPE1_VER0_EXECUTE             BIT(30)
+#define TYPE1_VER0_COMPLETE            BIT(31)
+#define TYPE1_VER0_TRIGGER_MASK                GENMASK(31, 28)
+
+/* After offset, order alphabetically, not bit ordered */
+struct crashlog_status {
+       u32 offset;
+       u32 cleared;
+       u32 complete;
+       u32 disabled;
+};
+
+struct crashlog_control {
+       u32 offset;
+       u32 trigger_mask;
+       u32 clear;
+       u32 disable;
+       u32 manual;
+};
+
+struct crashlog_info {
+       const struct crashlog_status status;
+       const struct crashlog_control control;
+};
+
 struct crashlog_entry {
        /* entry must be first member of struct */
        struct intel_pmt_entry          entry;
        struct mutex                    control_mutex;
+       const struct crashlog_info      *info;
 };
 
 struct pmt_crashlog_priv {
@@ -68,24 +93,25 @@ struct pmt_crashlog_priv {
 /* Read, modify, write the control register, setting or clearing @bit based on @set */
 static void pmt_crashlog_rmw(struct crashlog_entry *crashlog, u32 bit, bool set)
 {
+       const struct crashlog_control *control = &crashlog->info->control;
        struct intel_pmt_entry *entry = &crashlog->entry;
-       u32 reg = readl(entry->disc_table + CONTROL_OFFSET);
+       u32 reg = readl(entry->disc_table + control->offset);
 
-       reg &= ~CRASHLOG_FLAG_TRIGGER_MASK;
+       reg &= ~control->trigger_mask;
 
        if (set)
                reg |= bit;
        else
                reg &= ~bit;
 
-       writel(reg, entry->disc_table + CONTROL_OFFSET);
+       writel(reg, entry->disc_table + control->offset);
 }
 
 /* Read the status register and see if the specified @bit is set */
 static bool pmt_crashlog_rc(struct crashlog_entry *crashlog, u32 bit)
 {
-       struct intel_pmt_entry *entry = &crashlog->entry;
-       u32 reg = readl(entry->disc_table + CONTROL_OFFSET);
+       const struct crashlog_status *status = &crashlog->info->status;
+       u32 reg = readl(crashlog->entry.disc_table + status->offset);
 
        return !!(reg & bit);
 }
@@ -93,13 +119,13 @@ static bool pmt_crashlog_rc(struct crashlog_entry *crashlog, u32 bit)
 static bool pmt_crashlog_complete(struct crashlog_entry *crashlog)
 {
        /* return current value of the crashlog complete flag */
-       return pmt_crashlog_rc(crashlog, CRASHLOG_FLAG_TRIGGER_COMPLETE);
+       return pmt_crashlog_rc(crashlog, crashlog->info->status.complete);
 }
 
 static bool pmt_crashlog_disabled(struct crashlog_entry *crashlog)
 {
        /* return current value of the crashlog disabled flag */
-       return pmt_crashlog_rc(crashlog, CRASHLOG_FLAG_DISABLE);
+       return pmt_crashlog_rc(crashlog, crashlog->info->status.disabled);
 }
 
 static bool pmt_crashlog_supported(struct intel_pmt_entry *entry)
@@ -120,17 +146,17 @@ static bool pmt_crashlog_supported(struct intel_pmt_entry *entry)
 static void pmt_crashlog_set_disable(struct crashlog_entry *crashlog,
                                     bool disable)
 {
-       pmt_crashlog_rmw(crashlog, CRASHLOG_FLAG_DISABLE, disable);
+       pmt_crashlog_rmw(crashlog, crashlog->info->control.disable, disable);
 }
 
 static void pmt_crashlog_set_clear(struct crashlog_entry *crashlog)
 {
-       pmt_crashlog_rmw(crashlog, CRASHLOG_FLAG_TRIGGER_CLEAR, true);
+       pmt_crashlog_rmw(crashlog, crashlog->info->control.clear, true);
 }
 
 static void pmt_crashlog_set_execute(struct crashlog_entry *crashlog)
 {
-       pmt_crashlog_rmw(crashlog, CRASHLOG_FLAG_TRIGGER_EXECUTE, true);
+       pmt_crashlog_rmw(crashlog, crashlog->info->control.manual, true);
 }
 
 /*
@@ -224,6 +250,19 @@ static const struct attribute_group pmt_crashlog_group = {
        .attrs  = pmt_crashlog_attrs,
 };
 
+static const struct crashlog_info crashlog_type1_ver0 = {
+       .status.offset = TYPE1_VER0_STATUS_OFFSET,
+       .status.cleared = TYPE1_VER0_CLEAR,
+       .status.complete = TYPE1_VER0_COMPLETE,
+       .status.disabled = TYPE1_VER0_DISABLE,
+
+       .control.offset = TYPE1_VER0_CONTROL_OFFSET,
+       .control.trigger_mask = TYPE1_VER0_TRIGGER_MASK,
+       .control.clear = TYPE1_VER0_CLEAR,
+       .control.disable = TYPE1_VER0_DISABLE,
+       .control.manual = TYPE1_VER0_EXECUTE,
+};
+
 static int pmt_crashlog_header_decode(struct intel_pmt_entry *entry,
                                      struct device *dev)
 {
@@ -234,9 +273,10 @@ static int pmt_crashlog_header_decode(struct intel_pmt_entry *entry,
        if (!pmt_crashlog_supported(entry))
                return 1;
 
-       /* initialize control mutex */
+       /* initialize the crashlog struct */
        crashlog = container_of(entry, struct crashlog_entry, entry);
        mutex_init(&crashlog->control_mutex);
+       crashlog->info = &crashlog_type1_ver0;
 
        header->access_type = GET_ACCESS(readl(disc_table));
        header->guid = readl(disc_table + GUID_OFFSET);