diff options
Diffstat (limited to 'arch/powerpc/kernel/sysfs.c')
-rw-r--r-- | arch/powerpc/kernel/sysfs.c | 35 |
1 files changed, 7 insertions, 28 deletions
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c index 4a2ee08af6a7..f41aec85aa49 100644 --- a/arch/powerpc/kernel/sysfs.c +++ b/arch/powerpc/kernel/sysfs.c | |||
@@ -134,44 +134,23 @@ void ppc_enable_pmcs(void) | |||
134 | } | 134 | } |
135 | EXPORT_SYMBOL(ppc_enable_pmcs); | 135 | EXPORT_SYMBOL(ppc_enable_pmcs); |
136 | 136 | ||
137 | #if defined(CONFIG_6xx) || defined(CONFIG_PPC64) | ||
138 | /* XXX convert to rusty's on_one_cpu */ | ||
139 | static unsigned long run_on_cpu(unsigned long cpu, | ||
140 | unsigned long (*func)(unsigned long), | ||
141 | unsigned long arg) | ||
142 | { | ||
143 | cpumask_t old_affinity = current->cpus_allowed; | ||
144 | unsigned long ret; | ||
145 | |||
146 | /* should return -EINVAL to userspace */ | ||
147 | if (set_cpus_allowed(current, cpumask_of_cpu(cpu))) | ||
148 | return 0; | ||
149 | |||
150 | ret = func(arg); | ||
151 | |||
152 | set_cpus_allowed(current, old_affinity); | ||
153 | |||
154 | return ret; | ||
155 | } | ||
156 | #endif | ||
157 | |||
158 | #define SYSFS_PMCSETUP(NAME, ADDRESS) \ | 137 | #define SYSFS_PMCSETUP(NAME, ADDRESS) \ |
159 | static unsigned long read_##NAME(unsigned long junk) \ | 138 | static void read_##NAME(void *val) \ |
160 | { \ | 139 | { \ |
161 | return mfspr(ADDRESS); \ | 140 | *(unsigned long *)val = mfspr(ADDRESS); \ |
162 | } \ | 141 | } \ |
163 | static unsigned long write_##NAME(unsigned long val) \ | 142 | static void write_##NAME(void *val) \ |
164 | { \ | 143 | { \ |
165 | ppc_enable_pmcs(); \ | 144 | ppc_enable_pmcs(); \ |
166 | mtspr(ADDRESS, val); \ | 145 | mtspr(ADDRESS, *(unsigned long *)val); \ |
167 | return 0; \ | ||
168 | } \ | 146 | } \ |
169 | static ssize_t show_##NAME(struct sys_device *dev, \ | 147 | static ssize_t show_##NAME(struct sys_device *dev, \ |
170 | struct sysdev_attribute *attr, \ | 148 | struct sysdev_attribute *attr, \ |
171 | char *buf) \ | 149 | char *buf) \ |
172 | { \ | 150 | { \ |
173 | struct cpu *cpu = container_of(dev, struct cpu, sysdev); \ | 151 | struct cpu *cpu = container_of(dev, struct cpu, sysdev); \ |
174 | unsigned long val = run_on_cpu(cpu->sysdev.id, read_##NAME, 0); \ | 152 | unsigned long val; \ |
153 | smp_call_function_single(cpu->sysdev.id, read_##NAME, &val, 1); \ | ||
175 | return sprintf(buf, "%lx\n", val); \ | 154 | return sprintf(buf, "%lx\n", val); \ |
176 | } \ | 155 | } \ |
177 | static ssize_t __used \ | 156 | static ssize_t __used \ |
@@ -183,7 +162,7 @@ static ssize_t __used \ | |||
183 | int ret = sscanf(buf, "%lx", &val); \ | 162 | int ret = sscanf(buf, "%lx", &val); \ |
184 | if (ret != 1) \ | 163 | if (ret != 1) \ |
185 | return -EINVAL; \ | 164 | return -EINVAL; \ |
186 | run_on_cpu(cpu->sysdev.id, write_##NAME, val); \ | 165 | smp_call_function_single(cpu->sysdev.id, write_##NAME, &val, 1); \ |
187 | return count; \ | 166 | return count; \ |
188 | } | 167 | } |
189 | 168 | ||