Merge branches 'release', 'asus', 'sony-laptop' and 'thinkpad' into release
[pandora-kernel.git] / arch / powerpc / platforms / cell / spufs / spufs.h
index 03e8315..0e11403 100644 (file)
@@ -40,7 +40,9 @@ enum {
 struct spu_context_ops;
 struct spu_gang;
 
+/* ctx->sched_flags */
 enum {
+       SPU_SCHED_NOTIFY_ACTIVE,
        SPU_SCHED_WAS_ACTIVE,   /* was active upon spu_acquire_saved()  */
 };
 
@@ -69,6 +71,7 @@ struct spu_context {
        wait_queue_head_t wbox_wq;
        wait_queue_head_t stop_wq;
        wait_queue_head_t mfc_wq;
+       wait_queue_head_t run_wq;
        struct fasync_struct *ibox_fasync;
        struct fasync_struct *wbox_fasync;
        struct fasync_struct *mfc_fasync;
@@ -80,6 +83,8 @@ struct spu_context {
 
        struct list_head gang_list;
        struct spu_gang *gang;
+       struct kref *prof_priv_kref;
+       void ( * prof_priv_release) (struct kref *kref);
 
        /* owner thread */
        pid_t tid;
@@ -109,6 +114,10 @@ struct spu_context {
                unsigned long long class2_intr_base; /* # at last ctx switch */
                unsigned long long libassist;
        } stats;
+
+       struct list_head aff_list;
+       int aff_head;
+       int aff_offset;
 };
 
 struct spu_gang {
@@ -116,8 +125,19 @@ struct spu_gang {
        struct mutex mutex;
        struct kref kref;
        int contexts;
+
+       struct spu_context *aff_ref_ctx;
+       struct list_head aff_list_head;
+       struct mutex aff_mutex;
+       int aff_flags;
+       struct spu *aff_ref_spu;
+       atomic_t aff_sched_count;
 };
 
+/* Flag bits for spu_gang aff_flags */
+#define AFF_OFFSETS_SET                1
+#define AFF_MERGED             2
+
 struct mfc_dma_command {
        int32_t pad;    /* reserved */
        uint32_t lsa;   /* local storage address */
@@ -149,8 +169,10 @@ struct spu_context_ops {
        void (*npc_write) (struct spu_context * ctx, u32 data);
         u32(*status_read) (struct spu_context * ctx);
        char*(*get_ls) (struct spu_context * ctx);
+       void (*privcntl_write) (struct spu_context *ctx, u64 data);
         u32 (*runcntl_read) (struct spu_context * ctx);
        void (*runcntl_write) (struct spu_context * ctx, u32 data);
+       void (*runcntl_stop) (struct spu_context * ctx);
        void (*master_start) (struct spu_context * ctx);
        void (*master_stop) (struct spu_context * ctx);
        int (*set_mfc_query)(struct spu_context * ctx, u32 mask, u32 mode);
@@ -181,9 +203,14 @@ extern struct tree_descr spufs_dir_contents[];
 extern struct tree_descr spufs_dir_nosched_contents[];
 
 /* system call implementation */
+extern struct spufs_calls spufs_calls;
 long spufs_run_spu(struct spu_context *ctx, u32 *npc, u32 *status);
-long spufs_create(struct nameidata *nd,
-                        unsigned int flags, mode_t mode);
+long spufs_create(struct nameidata *nd, unsigned int flags,
+                       mode_t mode, struct file *filp);
+/* ELF coredump callbacks for writing SPU ELF notes */
+extern int spufs_coredump_extra_notes_size(void);
+extern int spufs_coredump_extra_notes_write(struct file *file, loff_t *foffset);
+
 extern const struct file_operations spufs_context_fops;
 
 /* gang management */
@@ -195,12 +222,16 @@ void spu_gang_add_ctx(struct spu_gang *gang, struct spu_context *ctx);
 
 /* fault handling */
 int spufs_handle_class1(struct spu_context *ctx);
+int spufs_handle_class0(struct spu_context *ctx);
+
+/* affinity */
+struct spu *affinity_check(struct spu_context *ctx);
 
 /* context management */
 extern atomic_t nr_spu_contexts;
-static inline void spu_acquire(struct spu_context *ctx)
+static inline int __must_check spu_acquire(struct spu_context *ctx)
 {
-       mutex_lock(&ctx->state_mutex);
+       return mutex_lock_interruptible(&ctx->state_mutex);
 }
 
 static inline void spu_release(struct spu_context *ctx)
@@ -215,13 +246,15 @@ int put_spu_context(struct spu_context *ctx);
 void spu_unmap_mappings(struct spu_context *ctx);
 
 void spu_forget(struct spu_context *ctx);
-int spu_acquire_runnable(struct spu_context *ctx, unsigned long flags);
-void spu_acquire_saved(struct spu_context *ctx);
+int __must_check spu_acquire_saved(struct spu_context *ctx);
 void spu_release_saved(struct spu_context *ctx);
 
+int spu_stopped(struct spu_context *ctx, u32 * stat);
+void spu_del_from_rq(struct spu_context *ctx);
 int spu_activate(struct spu_context *ctx, unsigned long flags);
 void spu_deactivate(struct spu_context *ctx);
 void spu_yield(struct spu_context *ctx);
+void spu_switch_notify(struct spu *spu, struct spu_context *ctx);
 void spu_set_timeslice(struct spu_context *ctx);
 void spu_update_sched_info(struct spu_context *ctx);
 void __spu_update_sched_info(struct spu_context *ctx);
@@ -251,7 +284,9 @@ extern char *isolated_loader;
                }                                                       \
                spu_release(ctx);                                       \
                schedule();                                             \
-               spu_acquire(ctx);                                       \
+               __ret = spu_acquire(ctx);                               \
+               if (__ret)                                              \
+                       break;                                          \
        }                                                               \
        finish_wait(&(wq), &__wait);                                    \
        __ret;                                                          \
@@ -272,47 +307,22 @@ struct spufs_coredump_reader {
        char *name;
        ssize_t (*read)(struct spu_context *ctx,
                        char __user *buffer, size_t size, loff_t *pos);
-       u64 (*get)(void *data);
+       u64 (*get)(struct spu_context *ctx);
        size_t size;
 };
 extern struct spufs_coredump_reader spufs_coredump_read[];
 extern int spufs_coredump_num_notes;
 
-/*
- * This function is a little bit too large for an inline, but
- * as fault.c is built into the kernel we can't move it out of
- * line.
- */
-static inline void spuctx_switch_state(struct spu_context *ctx,
-               enum spu_utilization_state new_state)
-{
-       unsigned long long curtime;
-       signed long long delta;
-       struct timespec ts;
-       struct spu *spu;
-       enum spu_utilization_state old_state;
-
-       ktime_get_ts(&ts);
-       curtime = timespec_to_ns(&ts);
-       delta = curtime - ctx->stats.tstamp;
-
-       WARN_ON(!mutex_is_locked(&ctx->state_mutex));
-       WARN_ON(delta < 0);
-
-       spu = ctx->spu;
-       old_state = ctx->stats.util_state;
-       ctx->stats.util_state = new_state;
-       ctx->stats.tstamp = curtime;
-
-       /*
-        * Update the physical SPU utilization statistics.
-        */
-       if (spu) {
-               ctx->stats.times[old_state] += delta;
-               spu->stats.times[old_state] += delta;
-               spu->stats.util_state = new_state;
-               spu->stats.tstamp = curtime;
-       }
-}
+extern int spu_init_csa(struct spu_state *csa);
+extern void spu_fini_csa(struct spu_state *csa);
+extern int spu_save(struct spu_state *prev, struct spu *spu);
+extern int spu_restore(struct spu_state *new, struct spu *spu);
+extern int spu_switch(struct spu_state *prev, struct spu_state *new,
+                     struct spu *spu);
+extern int spu_alloc_lscsa(struct spu_state *csa);
+extern void spu_free_lscsa(struct spu_state *csa);
+
+extern void spuctx_switch_state(struct spu_context *ctx,
+               enum spu_utilization_state new_state);
 
 #endif