summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorZbigniew Lukwinski <zbigniew.lukwinski@linux.intel.com>2022-05-10 18:37:55 +0300
committerZbigniew Lukwinski <zbigniew.lukwinski@linux.intel.com>2022-05-20 14:49:59 +0300
commit8dcd772516812e8dd37fdf748b1724726b9fd31d (patch)
treeb2d89068298cf5f5095b3b6b6eaff716e4f80f55 /drivers
parentefe6d9649b1d6b85b50cef64745df2e6749a8a45 (diff)
downloadlinux-8dcd772516812e8dd37fdf748b1724726b9fd31d.tar.xz
i3c: master: Enable support for PEC
PEC (Packet Error Check) support enabled in I3C controller driver. API for I3C device driver to control (enable or disable) PEC support in lower layer driver added. Signed-off-by: Zbigniew Lukwinski <zbigniew.lukwinski@linux.intel.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/i3c/device.c18
-rw-r--r--drivers/i3c/internals.h1
-rw-r--r--drivers/i3c/master.c20
3 files changed, 39 insertions, 0 deletions
diff --git a/drivers/i3c/device.c b/drivers/i3c/device.c
index be6669cf0846..cf2055dc238c 100644
--- a/drivers/i3c/device.c
+++ b/drivers/i3c/device.c
@@ -330,3 +330,21 @@ int i3c_device_getstatus_ccc(struct i3c_device *dev, struct i3c_device_info *inf
return ret;
}
EXPORT_SYMBOL_GPL(i3c_device_getstatus_ccc);
+
+/**
+ * i3c_device_control_pec() - enable or disable PEC support in HW
+ *
+ * @dev: I3C device to get the status for
+ * @pec: flag telling whether PEC support shall be enabled or disabled
+ *
+ * Try to enable or disable HW support for PEC (Packet Error Check).
+ * In case no HW support for PEC, software implementation could be used.
+ *
+ * Return: 0 in case of success, -EOPNOTSUPP in case PEC is not supported by HW,
+ * other negative error codes when PEC enabling failed.
+ */
+int i3c_device_control_pec(struct i3c_device *dev, bool pec)
+{
+ return i3c_dev_control_pec(dev->desc, pec);
+}
+EXPORT_SYMBOL_GPL(i3c_device_control_pec);
diff --git a/drivers/i3c/internals.h b/drivers/i3c/internals.h
index 524ad47fd916..5e6bd53637e4 100644
--- a/drivers/i3c/internals.h
+++ b/drivers/i3c/internals.h
@@ -28,4 +28,5 @@ void i3c_dev_free_ibi_locked(struct i3c_dev_desc *dev);
int i3c_dev_getstatus_locked(struct i3c_dev_desc *dev, struct i3c_device_info *info);
int i3c_for_each_dev(void *data, int (*fn)(struct device *, void *));
int i3c_dev_generate_ibi_locked(struct i3c_dev_desc *dev, const u8 *data, int len);
+int i3c_dev_control_pec(struct i3c_dev_desc *dev, bool pec);
#endif /* I3C_INTERNAL_H */
diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
index 656f0398d3e5..8ad15e2dcc62 100644
--- a/drivers/i3c/master.c
+++ b/drivers/i3c/master.c
@@ -3048,6 +3048,26 @@ int i3c_for_each_dev(void *data, int (*fn)(struct device *, void *))
}
EXPORT_SYMBOL_GPL(i3c_for_each_dev);
+int i3c_dev_control_pec(struct i3c_dev_desc *dev, bool pec)
+{
+ struct i3c_master_controller *master = i3c_dev_get_master(dev);
+
+ if (!master->pec_supported)
+ return -EOPNOTSUPP;
+
+ dev->info.pec = pec;
+
+ /*
+ * TODO: There are two cases which shall be covered
+ * 1. Controller doesn't support PEC.
+ * In this case we could just fallback to SW implementation.
+ * 2. Device doesn't support PEC.
+ * Then we really can't use PEC - and should error-out.
+ */
+
+ return 0;
+}
+
static int __init i3c_init(void)
{
return bus_register(&i3c_bus_type);