Commit 17f88ceb authored by Dwayne Grant McConnell's avatar Dwayne Grant McConnell Committed by Paul Mackerras

[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: default avatarDwayne Grant McConnell <decimal@us.ibm.com>
Signed-off-by: default avatarArnd Bergmann <arnd.bergmann@de.ibm.com>
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
parent 69a2f00c
...@@ -723,19 +723,27 @@ static ssize_t spufs_signal1_read(struct file *file, char __user *buf, ...@@ -723,19 +723,27 @@ static ssize_t spufs_signal1_read(struct file *file, char __user *buf,
size_t len, loff_t *pos) size_t len, loff_t *pos)
{ {
struct spu_context *ctx = file->private_data; struct spu_context *ctx = file->private_data;
int ret = 0;
u32 data; u32 data;
if (len < 4) if (len < 4)
return -EINVAL; return -EINVAL;
spu_acquire(ctx); spu_acquire_saved(ctx);
data = ctx->ops->signal1_read(ctx); if (ctx->csa.spu_chnlcnt_RW[3]) {
data = ctx->csa.spu_chnldata_RW[3];
ret = 4;
}
spu_release(ctx); spu_release(ctx);
if (!ret)
goto out;
if (copy_to_user(buf, &data, 4)) if (copy_to_user(buf, &data, 4))
return -EFAULT; return -EFAULT;
return 4; out:
return ret;
} }
static ssize_t spufs_signal1_write(struct file *file, const char __user *buf, 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) ...@@ -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, static ssize_t spufs_signal2_read(struct file *file, char __user *buf,
size_t len, loff_t *pos) size_t len, loff_t *pos)
{ {
struct spu_context *ctx; struct spu_context *ctx = file->private_data;
int ret = 0;
u32 data; u32 data;
ctx = file->private_data;
if (len < 4) if (len < 4)
return -EINVAL; return -EINVAL;
spu_acquire(ctx); spu_acquire_saved(ctx);
data = ctx->ops->signal2_read(ctx); if (ctx->csa.spu_chnlcnt_RW[4]) {
data = ctx->csa.spu_chnldata_RW[4];
ret = 4;
}
spu_release(ctx); spu_release(ctx);
if (!ret)
goto out;
if (copy_to_user(buf, &data, 4)) if (copy_to_user(buf, &data, 4))
return -EFAULT; return -EFAULT;
out:
return 4; return 4;
} }
......
...@@ -135,21 +135,11 @@ static int spu_hw_wbox_write(struct spu_context *ctx, u32 data) ...@@ -135,21 +135,11 @@ static int spu_hw_wbox_write(struct spu_context *ctx, u32 data)
return ret; return ret;
} }
static u32 spu_hw_signal1_read(struct spu_context *ctx)
{
return in_be32(&ctx->spu->problem->signal_notify1);
}
static void spu_hw_signal1_write(struct spu_context *ctx, u32 data) static void spu_hw_signal1_write(struct spu_context *ctx, u32 data)
{ {
out_be32(&ctx->spu->problem->signal_notify1, data); out_be32(&ctx->spu->problem->signal_notify1, data);
} }
static u32 spu_hw_signal2_read(struct spu_context *ctx)
{
return in_be32(&ctx->spu->problem->signal_notify2);
}
static void spu_hw_signal2_write(struct spu_context *ctx, u32 data) static void spu_hw_signal2_write(struct spu_context *ctx, u32 data)
{ {
out_be32(&ctx->spu->problem->signal_notify2, data); out_be32(&ctx->spu->problem->signal_notify2, data);
...@@ -294,9 +284,7 @@ struct spu_context_ops spu_hw_ops = { ...@@ -294,9 +284,7 @@ struct spu_context_ops spu_hw_ops = {
.mbox_stat_poll = spu_hw_mbox_stat_poll, .mbox_stat_poll = spu_hw_mbox_stat_poll,
.ibox_read = spu_hw_ibox_read, .ibox_read = spu_hw_ibox_read,
.wbox_write = spu_hw_wbox_write, .wbox_write = spu_hw_wbox_write,
.signal1_read = spu_hw_signal1_read,
.signal1_write = spu_hw_signal1_write, .signal1_write = spu_hw_signal1_write,
.signal2_read = spu_hw_signal2_read,
.signal2_write = spu_hw_signal2_write, .signal2_write = spu_hw_signal2_write,
.signal1_type_set = spu_hw_signal1_type_set, .signal1_type_set = spu_hw_signal1_type_set,
.signal1_type_get = spu_hw_signal1_type_get, .signal1_type_get = spu_hw_signal1_type_get,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment