[PATCH linux dev-4.7] drivers: fsi: scom: Add reset functionality and sysfs interface

Eddie James eajames at linux.vnet.ibm.com
Sat Feb 18 08:41:11 AEDT 2017


From: "Edward A. James" <eajames at us.ibm.com>

full reset only

Signed-off-by: Edward A. James <eajames at us.ibm.com>
---
 drivers/fsi/fsi-scom.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 50 insertions(+), 1 deletion(-)

diff --git a/drivers/fsi/fsi-scom.c b/drivers/fsi/fsi-scom.c
index ff8267b..c73bd91 100644
--- a/drivers/fsi/fsi-scom.c
+++ b/drivers/fsi/fsi-scom.c
@@ -32,7 +32,10 @@
 #define SCOM_DATA0_REG		0x00
 #define SCOM_DATA1_REG		0x04
 #define SCOM_CMD_REG		0x08
+#define SCOM_FSI2PIB_RESET_REG	0x18
 #define SCOM_RESET_REG		0x1C
+#define SCOM_COMP_MASK_REG	0x30
+#define SCOM_TRUE_MASK_REG	0x34
 
 #define SCOM_RESET_CMD		0x80000000
 #define SCOM_WRITE_CMD		0x80000000
@@ -156,7 +159,7 @@ static ssize_t scom_write(struct file *filep, const char __user *buf,
 	if (rc)
 		dev_dbg(dev, "put_scom failed with:%d\n", rc);
 
-	return rc;
+	return rc ? rc : len;
 }
 
 static loff_t scom_llseek(struct file *file, loff_t offset, int whence)
@@ -181,6 +184,48 @@ static const struct file_operations scom_fops = {
 	.write	= scom_write,
 };
 
+static int scom_reset_fsi2pib(struct fsi_device *fsi_dev)
+{
+	int rc;
+	u32 dummy = 0xFFFFFFFF;
+
+	rc = fsi_device_write(fsi_dev, SCOM_FSI2PIB_RESET_REG, &dummy,
+			      sizeof(u32));
+	if (rc)
+		dev_dbg(&fsi_dev->dev,
+			"failed to write fsi2pib reset register rc:%d\n", rc);
+
+	return rc;
+}
+
+static int scom_full_reset(struct fsi_device *fsi_dev)
+{
+	int rc = 0;
+	u32 dummy = 0xFFFFFFFF;
+
+	rc = fsi_device_write(fsi_dev, SCOM_RESET_REG, &dummy, sizeof(u32));
+	if (rc) {
+		dev_dbg(&fsi_dev->dev,
+			"failed to write scom reset register rc:%d\n", rc);
+		return rc;
+	}
+
+	return scom_reset_fsi2pib(fsi_dev);
+}
+
+static ssize_t store_reset_register(struct device *dev,
+				    struct device_attribute *attr,
+				    const char *buf, size_t count)
+{
+	int rc;
+	struct fsi_device *fsi_dev = to_fsi_dev(dev);
+
+	rc = scom_full_reset(fsi_dev);
+
+	return rc ? rc : count;
+}
+DEVICE_ATTR(reset, 0200, NULL, store_reset_register);
+
 static int scom_probe(struct device *dev)
 {
 	struct fsi_device *fsi_dev = to_fsi_dev(dev);
@@ -200,6 +245,8 @@ static int scom_probe(struct device *dev)
 	scom->mdev.parent = dev;
 	list_add(&scom->link, &scom_devices);
 
+	device_create_file(dev, &dev_attr_reset);
+
 	return misc_register(&scom->mdev);
 }
 
@@ -207,6 +254,8 @@ static int scom_remove(struct device *dev)
 {
 	struct scom_device *scom, *scom_tmp;
 	struct fsi_device *fsi_dev = to_fsi_dev(dev);
+
+	device_remove_file(dev, &dev_attr_reset);
 	
 	list_for_each_entry_safe(scom, scom_tmp, &scom_devices, link) {
 		if (scom->fsi_dev == fsi_dev) {
-- 
1.8.3.1



More information about the openbmc mailing list