Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 17183
b: refs/heads/master
c: 3a843d7
h: refs/heads/master
i:
  17181: 9a8215b
  17179: 889b906
  17175: ace1c64
  17167: 056699c
  17151: d245559
v: v3
  • Loading branch information
Arnd Bergmann authored and Paul Mackerras committed Jan 9, 2006
1 parent d2dc8f9 commit 65ee373
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 25 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 2a911f0bb73e67826062b7d073dd7367ca449724
refs/heads/master: 3a843d7cd30ab6815610d9d6aa66b56df0ee1228
11 changes: 8 additions & 3 deletions trunk/arch/powerpc/platforms/cell/spu_base.c
Original file line number Diff line number Diff line change
Expand Up @@ -202,12 +202,15 @@ spu_irq_class_0(int irq, void *data, struct pt_regs *regs)
int
spu_irq_class_0_bottom(struct spu *spu)
{
unsigned long stat;
unsigned long stat, mask;

spu->class_0_pending = 0;

mask = in_be64(&spu->priv1->int_mask_class0_RW);
stat = in_be64(&spu->priv1->int_stat_class0_RW);

stat &= mask;

if (stat & 1) /* invalid MFC DMA */
__spu_trap_invalid_dma(spu);

Expand Down Expand Up @@ -263,13 +266,15 @@ spu_irq_class_2(int irq, void *data, struct pt_regs *regs)
{
struct spu *spu;
unsigned long stat;
unsigned long mask;

spu = data;
stat = in_be64(&spu->priv1->int_stat_class2_RW);
mask = in_be64(&spu->priv1->int_mask_class2_RW);

pr_debug("class 2 interrupt %d, %lx, %lx\n", irq, stat,
in_be64(&spu->priv1->int_mask_class2_RW));
pr_debug("class 2 interrupt %d, %lx, %lx\n", irq, stat, mask);

stat &= mask;

if (stat & 1) /* PPC core mailbox */
__spu_trap_mailbox(spu);
Expand Down
37 changes: 37 additions & 0 deletions trunk/arch/powerpc/platforms/cell/spufs/backing_ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include <linux/smp_lock.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/poll.h>

#include <asm/io.h>
#include <asm/spu.h>
Expand Down Expand Up @@ -87,6 +88,41 @@ static u32 spu_backing_mbox_stat_read(struct spu_context *ctx)
return ctx->csa.prob.mb_stat_R;
}

static unsigned int spu_backing_mbox_stat_poll(struct spu_context *ctx,
unsigned int events)
{
int ret;
u32 stat;

ret = 0;
spin_lock_irq(&ctx->csa.register_lock);
stat = ctx->csa.prob.mb_stat_R;

/* if the requested event is there, return the poll
mask, otherwise enable the interrupt to get notified,
but first mark any pending interrupts as done so
we don't get woken up unnecessarily */

if (events & (POLLIN | POLLRDNORM)) {
if (stat & 0xff0000)
ret |= POLLIN | POLLRDNORM;
else {
ctx->csa.priv1.int_stat_class0_RW &= ~0x1;
ctx->csa.priv1.int_mask_class2_RW |= 0x1;
}
}
if (events & (POLLOUT | POLLWRNORM)) {
if (stat & 0x00ff00)
ret = POLLOUT | POLLWRNORM;
else {
ctx->csa.priv1.int_stat_class0_RW &= ~0x10;
ctx->csa.priv1.int_mask_class2_RW |= 0x10;
}
}
spin_unlock_irq(&ctx->csa.register_lock);
return ret;
}

static int spu_backing_ibox_read(struct spu_context *ctx, u32 * data)
{
int ret;
Expand Down Expand Up @@ -252,6 +288,7 @@ static void spu_backing_runcntl_stop(struct spu_context *ctx)
struct spu_context_ops spu_backing_ops = {
.mbox_read = spu_backing_mbox_read,
.mbox_stat_read = spu_backing_mbox_stat_read,
.mbox_stat_poll = spu_backing_mbox_stat_poll,
.ibox_read = spu_backing_ibox_read,
.wbox_write = spu_backing_wbox_write,
.signal1_read = spu_backing_signal1_read,
Expand Down
24 changes: 6 additions & 18 deletions trunk/arch/powerpc/platforms/cell/spufs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -389,20 +389,13 @@ static ssize_t spufs_ibox_read(struct file *file, char __user *buf,
static unsigned int spufs_ibox_poll(struct file *file, poll_table *wait)
{
struct spu_context *ctx = file->private_data;
u32 mbox_stat;
unsigned int mask;

spu_acquire(ctx);

mbox_stat = ctx->ops->mbox_stat_read(ctx);

spu_release(ctx);

poll_wait(file, &ctx->ibox_wq, wait);

mask = 0;
if (mbox_stat & 0xff0000)
mask |= POLLIN | POLLRDNORM;
spu_acquire(ctx);
mask = ctx->ops->mbox_stat_poll(ctx, POLLIN | POLLRDNORM);
spu_release(ctx);

return mask;
}
Expand Down Expand Up @@ -494,18 +487,13 @@ static ssize_t spufs_wbox_write(struct file *file, const char __user *buf,
static unsigned int spufs_wbox_poll(struct file *file, poll_table *wait)
{
struct spu_context *ctx = file->private_data;
u32 mbox_stat;
unsigned int mask;

spu_acquire(ctx);
mbox_stat = ctx->ops->mbox_stat_read(ctx);
spu_release(ctx);

poll_wait(file, &ctx->wbox_wq, wait);

mask = 0;
if (mbox_stat & 0x00ff00)
mask = POLLOUT | POLLWRNORM;
spu_acquire(ctx);
mask = ctx->ops->mbox_stat_poll(ctx, POLLOUT | POLLWRNORM);
spu_release(ctx);

return mask;
}
Expand Down
41 changes: 40 additions & 1 deletion trunk/arch/powerpc/platforms/cell/spufs/hw_ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/vmalloc.h>
#include <linux/poll.h>
#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/stddef.h>
Expand Down Expand Up @@ -58,6 +58,44 @@ static u32 spu_hw_mbox_stat_read(struct spu_context *ctx)
return in_be32(&ctx->spu->problem->mb_stat_R);
}

static unsigned int spu_hw_mbox_stat_poll(struct spu_context *ctx,
unsigned int events)
{
struct spu *spu = ctx->spu;
struct spu_priv1 __iomem *priv1 = spu->priv1;
int ret = 0;
u32 stat;

spin_lock_irq(&spu->register_lock);
stat = in_be32(&spu->problem->mb_stat_R);

/* if the requested event is there, return the poll
mask, otherwise enable the interrupt to get notified,
but first mark any pending interrupts as done so
we don't get woken up unnecessarily */

if (events & (POLLIN | POLLRDNORM)) {
if (stat & 0xff0000)
ret |= POLLIN | POLLRDNORM;
else {
out_be64(&priv1->int_stat_class2_RW, 0x1);
out_be64(&priv1->int_mask_class2_RW,
in_be64(&priv1->int_mask_class2_RW) | 0x1);
}
}
if (events & (POLLOUT | POLLWRNORM)) {
if (stat & 0x00ff00)
ret = POLLOUT | POLLWRNORM;
else {
out_be64(&priv1->int_stat_class2_RW, 0x10);
out_be64(&priv1->int_mask_class2_RW,
in_be64(&priv1->int_mask_class2_RW) | 0x10);
}
}
spin_unlock_irq(&spu->register_lock);
return ret;
}

static int spu_hw_ibox_read(struct spu_context *ctx, u32 * data)
{
struct spu *spu = ctx->spu;
Expand Down Expand Up @@ -204,6 +242,7 @@ static void spu_hw_runcntl_stop(struct spu_context *ctx)
struct spu_context_ops spu_hw_ops = {
.mbox_read = spu_hw_mbox_read,
.mbox_stat_read = spu_hw_mbox_stat_read,
.mbox_stat_poll = spu_hw_mbox_stat_poll,
.ibox_read = spu_hw_ibox_read,
.wbox_write = spu_hw_wbox_write,
.signal1_read = spu_hw_signal1_read,
Expand Down
2 changes: 2 additions & 0 deletions trunk/arch/powerpc/platforms/cell/spufs/spufs.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ struct spu_context {
struct spu_context_ops {
int (*mbox_read) (struct spu_context * ctx, u32 * data);
u32(*mbox_stat_read) (struct spu_context * ctx);
unsigned int (*mbox_stat_poll)(struct spu_context *ctx,
unsigned int events);
int (*ibox_read) (struct spu_context * ctx, u32 * data);
int (*wbox_write) (struct spu_context * ctx, u32 data);
u32(*signal1_read) (struct spu_context * ctx);
Expand Down
4 changes: 2 additions & 2 deletions trunk/arch/powerpc/platforms/cell/spufs/switch.c
Original file line number Diff line number Diff line change
Expand Up @@ -2155,8 +2155,8 @@ static void init_priv1(struct spu_state *csa)
CLASS0_ENABLE_SPU_ERROR_INTR;
csa->priv1.int_mask_class1_RW = CLASS1_ENABLE_SEGMENT_FAULT_INTR |
CLASS1_ENABLE_STORAGE_FAULT_INTR;
csa->priv1.int_mask_class2_RW = CLASS2_ENABLE_MAILBOX_INTR |
CLASS2_ENABLE_SPU_STOP_INTR | CLASS2_ENABLE_SPU_HALT_INTR;
csa->priv1.int_mask_class2_RW = CLASS2_ENABLE_SPU_STOP_INTR |
CLASS2_ENABLE_SPU_HALT_INTR;
}

static void init_priv2(struct spu_state *csa)
Expand Down

0 comments on commit 65ee373

Please sign in to comment.