summaryrefslogtreecommitdiff
path: root/arch/powerpc/platforms/cell/spufs/file.c
diff options
context:
space:
mode:
authorDwayne Grant McConnell <decimal@us.ibm.com>2006-11-20 18:45:01 +0100
committerPaul Mackerras <paulus@samba.org>2006-12-04 20:39:50 +1100
commit17f88cebc2c3aff9d90f0d49f6e0628835eddc32 (patch)
treed22b5b04d4bd4d3cc2ab87dcee28918c2abbd2fa /arch/powerpc/platforms/cell/spufs/file.c
parent69a2f00ce5d3a19a70b36f08eaf9049677277710 (diff)
[POWERPC] spufs: Read from signal files only if data is there
We need to check the channel count of the signal notification registers before reading them, because it can be undefined when the count is zero. In order to read count and data atomically, we read from the saved context. This patch uses spu_acquire_saved() to force a context save before a /signal1 or /signal2 read. Because of this it is no longer necessary to have backing_ops and hw_ops versions of this function so they have been removed. Regular applications should not rely on reading this register to be fast, as it's conceptually a write-only file from the PPE perspective. Signed-off-by: Dwayne Grant McConnell <decimal@us.ibm.com> Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/platforms/cell/spufs/file.c')
-rw-r--r--arch/powerpc/platforms/cell/spufs/file.c30
1 files changed, 22 insertions, 8 deletions
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index 2a2dd6441010..c0cf9ee4d45f 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -723,19 +723,27 @@ static ssize_t spufs_signal1_read(struct file *file, char __user *buf,
size_t len, loff_t *pos)
{
struct spu_context *ctx = file->private_data;
+ int ret = 0;
u32 data;
if (len < 4)
return -EINVAL;
- spu_acquire(ctx);
- data = ctx->ops->signal1_read(ctx);
+ spu_acquire_saved(ctx);
+ if (ctx->csa.spu_chnlcnt_RW[3]) {
+ data = ctx->csa.spu_chnldata_RW[3];
+ ret = 4;
+ }
spu_release(ctx);
+ if (!ret)
+ goto out;
+
if (copy_to_user(buf, &data, 4))
return -EFAULT;
- return 4;
+out:
+ return ret;
}
static ssize_t spufs_signal1_write(struct file *file, const char __user *buf,
@@ -811,21 +819,27 @@ static int spufs_signal2_open(struct inode *inode, struct file *file)
static ssize_t spufs_signal2_read(struct file *file, char __user *buf,
size_t len, loff_t *pos)
{
- struct spu_context *ctx;
+ struct spu_context *ctx = file->private_data;
+ int ret = 0;
u32 data;
- ctx = file->private_data;
-
if (len < 4)
return -EINVAL;
- spu_acquire(ctx);
- data = ctx->ops->signal2_read(ctx);
+ spu_acquire_saved(ctx);
+ if (ctx->csa.spu_chnlcnt_RW[4]) {
+ data = ctx->csa.spu_chnldata_RW[4];
+ ret = 4;
+ }
spu_release(ctx);
+ if (!ret)
+ goto out;
+
if (copy_to_user(buf, &data, 4))
return -EFAULT;
+out:
return 4;
}