--- /dev/null
+What:          /sys/devices/platform/soc@X/XXXXXXX.ipa/
+Date:          June 2021
+KernelVersion: v5.14
+Contact:       Alex Elder <elder@kernel.org>
+Description:
+               The /sys/devices/platform/soc@X/XXXXXXX.ipa/ directory
+               contains read-only attributes exposing information about
+               an IPA device.  The X values could vary, but are typically
+               "soc@0/1e40000.ipa".
+
+What:          .../XXXXXXX.ipa/version
+Date:          June 2021
+KernelVersion: v5.14
+Contact:       Alex Elder <elder@kernel.org>
+Description:
+               The .../XXXXXXX.ipa/version file contains the IPA hardware
+               version, as a period-separated set of two or three integers
+               (e.g., "3.5.1" or "4.2").
+
+What:          .../XXXXXXX.ipa/feature/
+Date:          June 2021
+KernelVersion: v5.14
+Contact:       Alex Elder <elder@kernel.org>
+Description:
+               The .../XXXXXXX.ipa/feature/ directory contains a set of
+               attributes describing features implemented by the IPA
+               hardware.
+
+What:          .../XXXXXXX.ipa/feature/rx_offload
+Date:          June 2021
+KernelVersion: v5.14
+Contact:       Alex Elder <elder@kernel.org>
+Description:
+               The .../XXXXXXX.ipa/feature/rx_offload file contains a
+               string indicating the type of receive checksum offload
+               that is supported by the hardware.  The possible values
+               are "MAPv4" or "MAPv5".
+
+What:          .../XXXXXXX.ipa/feature/tx_offload
+Date:          June 2021
+KernelVersion: v5.14
+Contact:       Alex Elder <elder@kernel.org>
+Description:
+               The .../XXXXXXX.ipa/feature/tx_offload file contains a
+               string indicating the type of transmit checksum offload
+               that is supported by the hardware.  The possible values
+               are "MAPv4" or "MAPv5".
+
+What:          .../XXXXXXX.ipa/modem/
+Date:          June 2021
+KernelVersion: v5.14
+Contact:       Alex Elder <elder@kernel.org>
+Description:
+               The .../XXXXXXX.ipa/modem/ directory contains a set of
+               attributes describing properties of the modem execution
+               environment reachable by the IPA hardware.
+
+What:          .../XXXXXXX.ipa/modem/rx_endpoint_id
+Date:          June 2021
+KernelVersion: v5.14
+Contact:       Alex Elder <elder@kernel.org>
+Description:
+               The .../XXXXXXX.ipa/feature/rx_endpoint_id file contains
+               the AP endpoint ID that receives packets originating from
+               the modem execution environment.  The "rx" is from the
+               perspective of the AP; this endpoint is considered an "IPA
+               producer".  An endpoint ID is a small unsigned integer.
+
+What:          .../XXXXXXX.ipa/modem/tx_endpoint_id
+Date:          June 2021
+KernelVersion: v5.14
+Contact:       Alex Elder <elder@kernel.org>
+Description:
+               The .../XXXXXXX.ipa/feature/tx_endpoint_id file contains
+               the AP endpoint ID used to transmit packets destined for
+               the modem execution environment.  The "tx" is from the
+               perspective of the AP; this endpoint is considered an "IPA
+               consumer".  An endpoint ID is a small unsigned integer.
 
                                ipa_table.o ipa_interrupt.o gsi.o gsi_trans.o \
                                ipa_gsi.o ipa_smp2p.o ipa_uc.o \
                                ipa_endpoint.o ipa_cmd.o ipa_modem.o \
-                               ipa_resource.o ipa_qmi.o ipa_qmi_msg.o
+                               ipa_resource.o ipa_qmi.o ipa_qmi_msg.o \
+                               ipa_sysfs.o
 
 ipa-y                  +=      ipa_data-v3.5.1.o ipa_data-v4.2.o \
                                ipa_data-v4.5.o ipa_data-v4.9.o \
 
 #include "ipa_uc.h"
 #include "ipa_interrupt.h"
 #include "gsi_trans.h"
+#include "ipa_sysfs.h"
 
 /**
  * DOC: The IP Accelerator
        .resume         = ipa_resume,
 };
 
+static const struct attribute_group *ipa_attribute_groups[] = {
+       &ipa_attribute_group,
+       &ipa_feature_attribute_group,
+       &ipa_modem_attribute_group,
+       NULL,
+};
+
 static struct platform_driver ipa_driver = {
        .probe          = ipa_probe,
        .remove         = ipa_remove,
                .name           = "ipa",
                .pm             = &ipa_pm_ops,
                .of_match_table = ipa_match,
+               .dev_groups     = ipa_attribute_groups,
        },
 };
 
 
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0
+
+/* Copyright (C) 2021 Linaro Ltd. */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/sysfs.h>
+
+#include "ipa.h"
+#include "ipa_version.h"
+#include "ipa_sysfs.h"
+
+static const char *ipa_version_string(struct ipa *ipa)
+{
+       switch (ipa->version) {
+       case IPA_VERSION_3_0:
+               return "3.0";
+       case IPA_VERSION_3_1:
+               return "3.1";
+       case IPA_VERSION_3_5:
+               return "3.5";
+       case IPA_VERSION_3_5_1:
+               return "3.5.1";
+       case IPA_VERSION_4_0:
+               return "4.0";
+       case IPA_VERSION_4_1:
+               return "4.1";
+       case IPA_VERSION_4_2:
+               return "4.2";
+       case IPA_VERSION_4_5:
+               return "4.5";
+       case IPA_VERSION_4_7:
+               return "4.7";
+       case IPA_VERSION_4_9:
+               return "4.9";
+       case IPA_VERSION_4_11:
+               return "4.11";
+       default:
+               return "0.0";   /* Won't happen (checked at probe time) */
+       }
+}
+
+static ssize_t
+version_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct ipa *ipa = dev_get_drvdata(dev);
+
+       return scnprintf(buf, PAGE_SIZE, "%s\n", ipa_version_string(ipa));
+}
+
+static DEVICE_ATTR_RO(version);
+
+static struct attribute *ipa_attrs[] = {
+       &dev_attr_version.attr,
+       NULL
+};
+
+const struct attribute_group ipa_attribute_group = {
+       .attrs          = ipa_attrs,
+};
+
+static const char *ipa_offload_string(struct ipa *ipa)
+{
+       return ipa->version < IPA_VERSION_4_5 ? "MAPv4" : "MAPv5";
+}
+
+static ssize_t rx_offload_show(struct device *dev,
+                              struct device_attribute *attr, char *buf)
+{
+       struct ipa *ipa = dev_get_drvdata(dev);
+
+       return scnprintf(buf, PAGE_SIZE, "%s\n", ipa_offload_string(ipa));
+}
+
+static DEVICE_ATTR_RO(rx_offload);
+
+static ssize_t tx_offload_show(struct device *dev,
+                              struct device_attribute *attr, char *buf)
+{
+       struct ipa *ipa = dev_get_drvdata(dev);
+
+       return scnprintf(buf, PAGE_SIZE, "%s\n", ipa_offload_string(ipa));
+}
+
+static DEVICE_ATTR_RO(tx_offload);
+
+static struct attribute *ipa_feature_attrs[] = {
+       &dev_attr_rx_offload.attr,
+       &dev_attr_tx_offload.attr,
+       NULL
+};
+
+const struct attribute_group ipa_feature_attribute_group = {
+       .name           = "feature",
+       .attrs          = ipa_feature_attrs,
+};
+
+static ssize_t
+ipa_endpoint_id_show(struct ipa *ipa, char *buf, enum ipa_endpoint_name name)
+{
+       u32 endpoint_id = ipa->name_map[name]->endpoint_id;
+
+       return scnprintf(buf, PAGE_SIZE, "%u\n", endpoint_id);
+}
+
+static ssize_t rx_endpoint_id_show(struct device *dev,
+                                  struct device_attribute *attr, char *buf)
+{
+       struct ipa *ipa = dev_get_drvdata(dev);
+
+       return ipa_endpoint_id_show(ipa, buf, IPA_ENDPOINT_AP_MODEM_RX);
+}
+
+static DEVICE_ATTR_RO(rx_endpoint_id);
+
+static ssize_t tx_endpoint_id_show(struct device *dev,
+                                  struct device_attribute *attr, char *buf)
+{
+       struct ipa *ipa = dev_get_drvdata(dev);
+
+       return ipa_endpoint_id_show(ipa, buf, IPA_ENDPOINT_AP_MODEM_TX);
+}
+
+static DEVICE_ATTR_RO(tx_endpoint_id);
+
+static struct attribute *ipa_modem_attrs[] = {
+       &dev_attr_rx_endpoint_id.attr,
+       &dev_attr_tx_endpoint_id.attr,
+       NULL
+};
+
+const struct attribute_group ipa_modem_attribute_group = {
+       .name           = "modem",
+       .attrs          = ipa_modem_attrs,
+};
 
--- /dev/null
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2019-2021 Linaro Ltd.
+ */
+#ifndef _IPA_SYSFS_H_
+#define _IPA_SYSFS_H_
+
+struct attribute_group;
+
+extern const struct attribute_group ipa_attribute_group;
+extern const struct attribute_group ipa_feature_attribute_group;
+extern const struct attribute_group ipa_modem_attribute_group;
+
+#endif /* _IPA_SYSFS_H_ */
 
  * @IPA_VERSION_4_11:  IPA version 4.11/GSI version 2.11 (2.1.1)
  *
  * Defines the version of IPA (and GSI) hardware present on the platform.
+ * Please update ipa_version_valid() and ipa_version_string() whenever a
+ * new version is added.
  */
 enum ipa_version {
        IPA_VERSION_3_0,