aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/platforms/cell/spufs/context.c1
-rw-r--r--arch/powerpc/platforms/cell/spufs/file.c147
-rw-r--r--arch/powerpc/platforms/cell/spufs/inode.c1
-rw-r--r--arch/powerpc/platforms/cell/spufs/spufs.h12
4 files changed, 148 insertions, 13 deletions
diff --git a/arch/powerpc/platforms/cell/spufs/context.c b/arch/powerpc/platforms/cell/spufs/context.c
index 04ad2e364e97..b3954aba424e 100644
--- a/arch/powerpc/platforms/cell/spufs/context.c
+++ b/arch/powerpc/platforms/cell/spufs/context.c
@@ -41,6 +41,7 @@ struct spu_context *alloc_spu_context(struct spu_gang *gang)
41 goto out_free; 41 goto out_free;
42 } 42 }
43 spin_lock_init(&ctx->mmio_lock); 43 spin_lock_init(&ctx->mmio_lock);
44 spin_lock_init(&ctx->mapping_lock);
44 kref_init(&ctx->kref); 45 kref_init(&ctx->kref);
45 mutex_init(&ctx->state_mutex); 46 mutex_init(&ctx->state_mutex);
46 init_MUTEX(&ctx->run_sema); 47 init_MUTEX(&ctx->run_sema);
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index 505266a568d4..deb340e6e0ae 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -44,8 +44,26 @@ spufs_mem_open(struct inode *inode, struct file *file)
44{ 44{
45 struct spufs_inode_info *i = SPUFS_I(inode); 45 struct spufs_inode_info *i = SPUFS_I(inode);
46 struct spu_context *ctx = i->i_ctx; 46 struct spu_context *ctx = i->i_ctx;
47
48 spin_lock(&ctx->mapping_lock);
47 file->private_data = ctx; 49 file->private_data = ctx;
48 ctx->local_store = inode->i_mapping; 50 if (!i->i_openers++)
51 ctx->local_store = inode->i_mapping;
52 spin_unlock(&ctx->mapping_lock);
53 smp_wmb();
54 return 0;
55}
56
57static int
58spufs_mem_release(struct inode *inode, struct file *file)
59{
60 struct spufs_inode_info *i = SPUFS_I(inode);
61 struct spu_context *ctx = i->i_ctx;
62
63 spin_lock(&ctx->mapping_lock);
64 if (!--i->i_openers)
65 ctx->local_store = NULL;
66 spin_unlock(&ctx->mapping_lock);
49 smp_wmb(); 67 smp_wmb();
50 return 0; 68 return 0;
51} 69}
@@ -149,6 +167,7 @@ spufs_mem_mmap(struct file *file, struct vm_area_struct *vma)
149 167
150static const struct file_operations spufs_mem_fops = { 168static const struct file_operations spufs_mem_fops = {
151 .open = spufs_mem_open, 169 .open = spufs_mem_open,
170 .release = spufs_mem_release,
152 .read = spufs_mem_read, 171 .read = spufs_mem_read,
153 .write = spufs_mem_write, 172 .write = spufs_mem_write,
154 .llseek = generic_file_llseek, 173 .llseek = generic_file_llseek,
@@ -238,16 +257,35 @@ static int spufs_cntl_open(struct inode *inode, struct file *file)
238 struct spufs_inode_info *i = SPUFS_I(inode); 257 struct spufs_inode_info *i = SPUFS_I(inode);
239 struct spu_context *ctx = i->i_ctx; 258 struct spu_context *ctx = i->i_ctx;
240 259
260 spin_lock(&ctx->mapping_lock);
241 file->private_data = ctx; 261 file->private_data = ctx;
242 ctx->cntl = inode->i_mapping; 262 if (!i->i_openers++)
263 ctx->cntl = inode->i_mapping;
264 spin_unlock(&ctx->mapping_lock);
243 smp_wmb(); 265 smp_wmb();
244 return simple_attr_open(inode, file, spufs_cntl_get, 266 return simple_attr_open(inode, file, spufs_cntl_get,
245 spufs_cntl_set, "0x%08lx"); 267 spufs_cntl_set, "0x%08lx");
246} 268}
247 269
270static int
271spufs_cntl_release(struct inode *inode, struct file *file)
272{
273 struct spufs_inode_info *i = SPUFS_I(inode);
274 struct spu_context *ctx = i->i_ctx;
275
276 simple_attr_close(inode, file);
277
278 spin_lock(&ctx->mapping_lock);
279 if (!--i->i_openers)
280 ctx->cntl = NULL;
281 spin_unlock(&ctx->mapping_lock);
282 smp_wmb();
283 return 0;
284}
285
248static const struct file_operations spufs_cntl_fops = { 286static const struct file_operations spufs_cntl_fops = {
249 .open = spufs_cntl_open, 287 .open = spufs_cntl_open,
250 .release = simple_attr_close, 288 .release = spufs_cntl_release,
251 .read = simple_attr_read, 289 .read = simple_attr_read,
252 .write = simple_attr_write, 290 .write = simple_attr_write,
253 .mmap = spufs_cntl_mmap, 291 .mmap = spufs_cntl_mmap,
@@ -723,12 +761,30 @@ static int spufs_signal1_open(struct inode *inode, struct file *file)
723{ 761{
724 struct spufs_inode_info *i = SPUFS_I(inode); 762 struct spufs_inode_info *i = SPUFS_I(inode);
725 struct spu_context *ctx = i->i_ctx; 763 struct spu_context *ctx = i->i_ctx;
764
765 spin_lock(&ctx->mapping_lock);
726 file->private_data = ctx; 766 file->private_data = ctx;
727 ctx->signal1 = inode->i_mapping; 767 if (!i->i_openers++)
768 ctx->signal1 = inode->i_mapping;
769 spin_unlock(&ctx->mapping_lock);
728 smp_wmb(); 770 smp_wmb();
729 return nonseekable_open(inode, file); 771 return nonseekable_open(inode, file);
730} 772}
731 773
774static int
775spufs_signal1_release(struct inode *inode, struct file *file)
776{
777 struct spufs_inode_info *i = SPUFS_I(inode);
778 struct spu_context *ctx = i->i_ctx;
779
780 spin_lock(&ctx->mapping_lock);
781 if (!--i->i_openers)
782 ctx->signal1 = NULL;
783 spin_unlock(&ctx->mapping_lock);
784 smp_wmb();
785 return 0;
786}
787
732static ssize_t __spufs_signal1_read(struct spu_context *ctx, char __user *buf, 788static ssize_t __spufs_signal1_read(struct spu_context *ctx, char __user *buf,
733 size_t len, loff_t *pos) 789 size_t len, loff_t *pos)
734{ 790{
@@ -821,6 +877,7 @@ static int spufs_signal1_mmap(struct file *file, struct vm_area_struct *vma)
821 877
822static const struct file_operations spufs_signal1_fops = { 878static const struct file_operations spufs_signal1_fops = {
823 .open = spufs_signal1_open, 879 .open = spufs_signal1_open,
880 .release = spufs_signal1_release,
824 .read = spufs_signal1_read, 881 .read = spufs_signal1_read,
825 .write = spufs_signal1_write, 882 .write = spufs_signal1_write,
826 .mmap = spufs_signal1_mmap, 883 .mmap = spufs_signal1_mmap,
@@ -830,12 +887,30 @@ static int spufs_signal2_open(struct inode *inode, struct file *file)
830{ 887{
831 struct spufs_inode_info *i = SPUFS_I(inode); 888 struct spufs_inode_info *i = SPUFS_I(inode);
832 struct spu_context *ctx = i->i_ctx; 889 struct spu_context *ctx = i->i_ctx;
890
891 spin_lock(&ctx->mapping_lock);
833 file->private_data = ctx; 892 file->private_data = ctx;
834 ctx->signal2 = inode->i_mapping; 893 if (!i->i_openers++)
894 ctx->signal2 = inode->i_mapping;
895 spin_unlock(&ctx->mapping_lock);
835 smp_wmb(); 896 smp_wmb();
836 return nonseekable_open(inode, file); 897 return nonseekable_open(inode, file);
837} 898}
838 899
900static int
901spufs_signal2_release(struct inode *inode, struct file *file)
902{
903 struct spufs_inode_info *i = SPUFS_I(inode);
904 struct spu_context *ctx = i->i_ctx;
905
906 spin_lock(&ctx->mapping_lock);
907 if (!--i->i_openers)
908 ctx->signal2 = NULL;
909 spin_unlock(&ctx->mapping_lock);
910 smp_wmb();
911 return 0;
912}
913
839static ssize_t __spufs_signal2_read(struct spu_context *ctx, char __user *buf, 914static ssize_t __spufs_signal2_read(struct spu_context *ctx, char __user *buf,
840 size_t len, loff_t *pos) 915 size_t len, loff_t *pos)
841{ 916{
@@ -932,6 +1007,7 @@ static int spufs_signal2_mmap(struct file *file, struct vm_area_struct *vma)
932 1007
933static const struct file_operations spufs_signal2_fops = { 1008static const struct file_operations spufs_signal2_fops = {
934 .open = spufs_signal2_open, 1009 .open = spufs_signal2_open,
1010 .release = spufs_signal2_release,
935 .read = spufs_signal2_read, 1011 .read = spufs_signal2_read,
936 .write = spufs_signal2_write, 1012 .write = spufs_signal2_write,
937 .mmap = spufs_signal2_mmap, 1013 .mmap = spufs_signal2_mmap,
@@ -1031,13 +1107,32 @@ static int spufs_mss_open(struct inode *inode, struct file *file)
1031 struct spu_context *ctx = i->i_ctx; 1107 struct spu_context *ctx = i->i_ctx;
1032 1108
1033 file->private_data = i->i_ctx; 1109 file->private_data = i->i_ctx;
1034 ctx->mss = inode->i_mapping; 1110
1111 spin_lock(&ctx->mapping_lock);
1112 if (!i->i_openers++)
1113 ctx->mss = inode->i_mapping;
1114 spin_unlock(&ctx->mapping_lock);
1035 smp_wmb(); 1115 smp_wmb();
1036 return nonseekable_open(inode, file); 1116 return nonseekable_open(inode, file);
1037} 1117}
1038 1118
1119static int
1120spufs_mss_release(struct inode *inode, struct file *file)
1121{
1122 struct spufs_inode_info *i = SPUFS_I(inode);
1123 struct spu_context *ctx = i->i_ctx;
1124
1125 spin_lock(&ctx->mapping_lock);
1126 if (!--i->i_openers)
1127 ctx->mss = NULL;
1128 spin_unlock(&ctx->mapping_lock);
1129 smp_wmb();
1130 return 0;
1131}
1132
1039static const struct file_operations spufs_mss_fops = { 1133static const struct file_operations spufs_mss_fops = {
1040 .open = spufs_mss_open, 1134 .open = spufs_mss_open,
1135 .release = spufs_mss_release,
1041 .mmap = spufs_mss_mmap, 1136 .mmap = spufs_mss_mmap,
1042}; 1137};
1043 1138
@@ -1072,14 +1167,32 @@ static int spufs_psmap_open(struct inode *inode, struct file *file)
1072 struct spufs_inode_info *i = SPUFS_I(inode); 1167 struct spufs_inode_info *i = SPUFS_I(inode);
1073 struct spu_context *ctx = i->i_ctx; 1168 struct spu_context *ctx = i->i_ctx;
1074 1169
1170 spin_lock(&ctx->mapping_lock);
1075 file->private_data = i->i_ctx; 1171 file->private_data = i->i_ctx;
1076 ctx->psmap = inode->i_mapping; 1172 if (!i->i_openers++)
1173 ctx->psmap = inode->i_mapping;
1174 spin_unlock(&ctx->mapping_lock);
1077 smp_wmb(); 1175 smp_wmb();
1078 return nonseekable_open(inode, file); 1176 return nonseekable_open(inode, file);
1079} 1177}
1080 1178
1179static int
1180spufs_psmap_release(struct inode *inode, struct file *file)
1181{
1182 struct spufs_inode_info *i = SPUFS_I(inode);
1183 struct spu_context *ctx = i->i_ctx;
1184
1185 spin_lock(&ctx->mapping_lock);
1186 if (!--i->i_openers)
1187 ctx->psmap = NULL;
1188 spin_unlock(&ctx->mapping_lock);
1189 smp_wmb();
1190 return 0;
1191}
1192
1081static const struct file_operations spufs_psmap_fops = { 1193static const struct file_operations spufs_psmap_fops = {
1082 .open = spufs_psmap_open, 1194 .open = spufs_psmap_open,
1195 .release = spufs_psmap_release,
1083 .mmap = spufs_psmap_mmap, 1196 .mmap = spufs_psmap_mmap,
1084}; 1197};
1085 1198
@@ -1126,12 +1239,29 @@ static int spufs_mfc_open(struct inode *inode, struct file *file)
1126 if (atomic_read(&inode->i_count) != 1) 1239 if (atomic_read(&inode->i_count) != 1)
1127 return -EBUSY; 1240 return -EBUSY;
1128 1241
1242 spin_lock(&ctx->mapping_lock);
1129 file->private_data = ctx; 1243 file->private_data = ctx;
1130 ctx->mfc = inode->i_mapping; 1244 if (!i->i_openers++)
1245 ctx->mfc = inode->i_mapping;
1246 spin_unlock(&ctx->mapping_lock);
1131 smp_wmb(); 1247 smp_wmb();
1132 return nonseekable_open(inode, file); 1248 return nonseekable_open(inode, file);
1133} 1249}
1134 1250
1251static int
1252spufs_mfc_release(struct inode *inode, struct file *file)
1253{
1254 struct spufs_inode_info *i = SPUFS_I(inode);
1255 struct spu_context *ctx = i->i_ctx;
1256
1257 spin_lock(&ctx->mapping_lock);
1258 if (!--i->i_openers)
1259 ctx->mfc = NULL;
1260 spin_unlock(&ctx->mapping_lock);
1261 smp_wmb();
1262 return 0;
1263}
1264
1135/* interrupt-level mfc callback function. */ 1265/* interrupt-level mfc callback function. */
1136void spufs_mfc_callback(struct spu *spu) 1266void spufs_mfc_callback(struct spu *spu)
1137{ 1267{
@@ -1399,6 +1529,7 @@ static int spufs_mfc_fasync(int fd, struct file *file, int on)
1399 1529
1400static const struct file_operations spufs_mfc_fops = { 1530static const struct file_operations spufs_mfc_fops = {
1401 .open = spufs_mfc_open, 1531 .open = spufs_mfc_open,
1532 .release = spufs_mfc_release,
1402 .read = spufs_mfc_read, 1533 .read = spufs_mfc_read,
1403 .write = spufs_mfc_write, 1534 .write = spufs_mfc_write,
1404 .poll = spufs_mfc_poll, 1535 .poll = spufs_mfc_poll,
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
index e3f4ee97c913..423596a6b995 100644
--- a/arch/powerpc/platforms/cell/spufs/inode.c
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
@@ -54,6 +54,7 @@ spufs_alloc_inode(struct super_block *sb)
54 54
55 ei->i_gang = NULL; 55 ei->i_gang = NULL;
56 ei->i_ctx = NULL; 56 ei->i_ctx = NULL;
57 ei->i_openers = 0;
57 58
58 return &ei->vfs_inode; 59 return &ei->vfs_inode;
59} 60}
diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h
index f418378abdff..0fb366d9d257 100644
--- a/arch/powerpc/platforms/cell/spufs/spufs.h
+++ b/arch/powerpc/platforms/cell/spufs/spufs.h
@@ -50,11 +50,12 @@ struct spu_context {
50 spinlock_t mmio_lock; /* protects mmio access */ 50 spinlock_t mmio_lock; /* protects mmio access */
51 struct address_space *local_store; /* local store mapping. */ 51 struct address_space *local_store; /* local store mapping. */
52 struct address_space *mfc; /* 'mfc' area mappings. */ 52 struct address_space *mfc; /* 'mfc' area mappings. */
53 struct address_space *cntl; /* 'control' area mappings. */ 53 struct address_space *cntl; /* 'control' area mappings. */
54 struct address_space *signal1; /* 'signal1' area mappings. */ 54 struct address_space *signal1; /* 'signal1' area mappings. */
55 struct address_space *signal2; /* 'signal2' area mappings. */ 55 struct address_space *signal2; /* 'signal2' area mappings. */
56 struct address_space *mss; /* 'mss' area mappings. */ 56 struct address_space *mss; /* 'mss' area mappings. */
57 struct address_space *psmap; /* 'psmap' area mappings. */ 57 struct address_space *psmap; /* 'psmap' area mappings. */
58 spinlock_t mapping_lock;
58 u64 object_id; /* user space pointer for oprofile */ 59 u64 object_id; /* user space pointer for oprofile */
59 60
60 enum { SPU_STATE_RUNNABLE, SPU_STATE_SAVED } state; 61 enum { SPU_STATE_RUNNABLE, SPU_STATE_SAVED } state;
@@ -149,6 +150,7 @@ struct spufs_inode_info {
149 struct spu_context *i_ctx; 150 struct spu_context *i_ctx;
150 struct spu_gang *i_gang; 151 struct spu_gang *i_gang;
151 struct inode vfs_inode; 152 struct inode vfs_inode;
153 int i_openers;
152}; 154};
153#define SPUFS_I(inode) \ 155#define SPUFS_I(inode) \
154 container_of(inode, struct spufs_inode_info, vfs_inode) 156 container_of(inode, struct spufs_inode_info, vfs_inode)