fsi/scom: Add mutex around FSI2PIB accesses
PATCH 1/3 fsi/scom: Add mutex around FSI2PIB accesses
Otherwise, multiple clients can open the driver and attempt to access the PIB at the same time, thus clobbering each other in the process.
Signed-off-by Benjamin Herrenschmidt <[email protected]>
--- drivers/fsi/fsi-scom.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-)
drivers/fsi/fsi-scom.c +18 -7
@@ -37,6 +37,7 @@ struct scom_device {struct list_head link;struct fsi_device *fsi_dev;struct miscdevice mdev; +struct mutex lock;char name[32 ];int idx; };
@@ -53,21 +54,26 @@ static int put_scom(struct scom_device *scom_dev, uint64_t value,int rc;uint32_t data; +mutex_lock (&scom_dev->lock); + data =cpu_to_be32 ((value >>32 ) &0xffffffff ); rc =fsi_device_write (scom_dev->fsi_dev,SCOM_DATA0_REG , &data,sizeof (uint32_t ));if (rc) -return rc; + goto bail; data =cpu_to_be32 (value &0xffffffff ); rc =fsi_device_write (scom_dev->fsi_dev,SCOM_DATA1_REG , &data,sizeof (uint32_t ));if (rc) -return rc; + goto bail; data =cpu_to_be32 (SCOM_WRITE_CMD | addr); -return fsi_device_write (scom_dev->fsi_dev,SCOM_CMD_REG , &data, + rc =fsi_device_write (scom_dev->fsi_dev,SCOM_CMD_REG , &data,sizeof (uint32_t )); + bail: +mutex_unlock (&scom_dev->lock); +return rc; } static int get_scom(struct scom_device *scom_dev, uint64_t *value,
@@ -76,27 +82,31 @@ static int get_scom(struct scom_device *scom_dev, uint64_t *value,uint32_t result, data;int rc; + +mutex_lock (&scom_dev->lock); *value =0ULL ; data =cpu_to_be32 (addr); rc =fsi_device_write (scom_dev->fsi_dev,SCOM_CMD_REG , &data,sizeof (uint32_t ));if (rc) -return rc; + goto bail; rc =fsi_device_read (scom_dev->fsi_dev,SCOM_DATA0_REG , &result,sizeof (uint32_t ));if (rc) -return rc; + goto bail; *value |= (uint64_t )cpu_to_be32 (result) <<32 ; rc =fsi_device_read (scom_dev->fsi_dev,SCOM_DATA1_REG , &result,sizeof (uint32_t ));if (rc) -return rc; + goto bail; *value |=cpu_to_be32 (result); -return 0 ; + bail: +mutex_unlock (&scom_dev->lock); +return rc; } static ssize_t scom_read(struct file *filep, char __user *buf, size_t len,
@@ -183,6 +193,7 @@ static int scom_probe(struct device *dev)if (!scom)return -ENOMEM ; +mutex_init (&scom->lock); scom->idx =ida_simple_get (&scom_ida,1 ,INT_MAX ,GFP_KERNEL );snprintf (scom->name,sizeof (scom->name),"scom%d" , scom->idx); scom->fsi_dev = fsi_dev;
Signature · 1 line
2.17.0
PATCH 2/3 fsi/scom: Whitespace fixes
No functional changes
Signed-off-by Benjamin Herrenschmidt <[email protected]>
--- drivers/fsi/fsi-scom.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/fsi/fsi-scom.c +4 -4
@@ -49,7 +49,7 @@ static struct list_head scom_devices;static DEFINE_IDA (scom_ida);static int put_scom (struct scom_device *scom_dev,uint64_t value, -uint32_t addr) +uint32_t addr) {int rc;uint32_t data;
@@ -77,7 +77,7 @@ static int put_scom(struct scom_device *scom_dev, uint64_t value, }static int get_scom (struct scom_device *scom_dev,uint64_t *value, -uint32_t addr) +uint32_t addr) {uint32_t result, data;int rc;
@@ -110,7 +110,7 @@ static int get_scom(struct scom_device *scom_dev, uint64_t *value, }static ssize_t scom_read (struct file *filep,char __user *buf,size_t len, -loff_t *offset) +loff_t *offset) {int rc; struct miscdevice *mdev =
@@ -136,7 +136,7 @@ static ssize_t scom_read(struct file *filep, char __user *buf, size_t len, }static ssize_t scom_write (struct file *filep,const char __user *buf, -size_t len,loff_t *offset) +size_t len,loff_t *offset) {int rc;struct miscdevice *mdev = filep->private_data;
Signature · 1 line
2.17.0
PATCH 3/3 fsi/scom: Fixup endian annotations
In reply to Benjamin HerrenschmidtUse the proper annotated type __be32 and fixup the accessor used for get_scom()
Signed-off-by Benjamin Herrenschmidt <[email protected]>
--- drivers/fsi/fsi-scom.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
drivers/fsi/fsi-scom.c +4 -5
@@ -51,8 +51,8 @@ static DEFINE_IDA(scom_ida);static int put_scom (struct scom_device *scom_dev,uint64_t value,uint32_t addr) { +__be32 data;int rc; -uint32_t data;mutex_lock (&scom_dev->lock);
@@ -79,7 +79,7 @@ static int put_scom(struct scom_device *scom_dev, uint64_t value,static int get_scom (struct scom_device *scom_dev,uint64_t *value,uint32_t addr) { -uint32_t result, data; +__be32 result, data;int rc;
@@ -96,14 +96,13 @@ static int get_scom(struct scom_device *scom_dev, uint64_t *value,if (rc) goto bail; - *value |= (uint64_t )cpu_to_be32 (result) <<32 ; + *value |= (uint64_t )be32_to_cpu (result) <<32 ; rc =fsi_device_read (scom_dev->fsi_dev,SCOM_DATA1_REG , &result,sizeof (uint32_t ));if (rc) goto bail; - *value |=cpu_to_be32 (result); - + *value |=be32_to_cpu (result); bail:mutex_unlock (&scom_dev->lock);return rc;
Signature · 1 line
2.17.0