[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