| 
									
										
										
										
											2007-06-02 14:41:44 -07:00
										 |  |  | /* sysfs.c: Toplogy sysfs support code for sparc64.
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Copyright (C) 2007 David S. Miller <davem@davemloft.net> | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2009-08-13 10:05:43 +00:00
										 |  |  | #include <linux/sched.h>
 | 
					
						
							| 
									
										
										
										
											2011-12-21 14:29:42 -08:00
										 |  |  | #include <linux/device.h>
 | 
					
						
							| 
									
										
										
										
											2007-06-02 14:41:44 -07:00
										 |  |  | #include <linux/cpu.h>
 | 
					
						
							|  |  |  | #include <linux/smp.h>
 | 
					
						
							|  |  |  | #include <linux/percpu.h>
 | 
					
						
							|  |  |  | #include <linux/init.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-26 15:33:07 -08:00
										 |  |  | #include <asm/cpudata.h>
 | 
					
						
							| 
									
										
										
										
											2007-06-03 23:38:09 -07:00
										 |  |  | #include <asm/hypervisor.h>
 | 
					
						
							|  |  |  | #include <asm/spitfire.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static DEFINE_PER_CPU(struct hv_mmu_statistics, mmu_stats) __attribute__((aligned(64))); | 
					
						
							| 
									
										
										
										
											2007-06-02 14:41:44 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-06-03 23:38:09 -07:00
										 |  |  | #define SHOW_MMUSTAT_ULONG(NAME) \
 | 
					
						
							| 
									
										
										
										
											2011-12-21 14:29:42 -08:00
										 |  |  | static ssize_t show_##NAME(struct device *dev, \ | 
					
						
							|  |  |  | 			struct device_attribute *attr, char *buf) \ | 
					
						
							| 
									
										
										
										
											2007-06-02 20:46:36 -07:00
										 |  |  | { \ | 
					
						
							| 
									
										
										
										
											2007-06-03 23:38:09 -07:00
										 |  |  | 	struct hv_mmu_statistics *p = &per_cpu(mmu_stats, dev->id); \ | 
					
						
							|  |  |  | 	return sprintf(buf, "%lu\n", p->NAME); \ | 
					
						
							|  |  |  | } \ | 
					
						
							| 
									
										
										
										
											2011-12-21 14:29:42 -08:00
										 |  |  | static DEVICE_ATTR(NAME, 0444, show_##NAME, NULL) | 
					
						
							| 
									
										
										
										
											2007-06-03 23:38:09 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | SHOW_MMUSTAT_ULONG(immu_tsb_hits_ctx0_8k_tte); | 
					
						
							|  |  |  | SHOW_MMUSTAT_ULONG(immu_tsb_ticks_ctx0_8k_tte); | 
					
						
							|  |  |  | SHOW_MMUSTAT_ULONG(immu_tsb_hits_ctx0_64k_tte); | 
					
						
							|  |  |  | SHOW_MMUSTAT_ULONG(immu_tsb_ticks_ctx0_64k_tte); | 
					
						
							|  |  |  | SHOW_MMUSTAT_ULONG(immu_tsb_hits_ctx0_4mb_tte); | 
					
						
							|  |  |  | SHOW_MMUSTAT_ULONG(immu_tsb_ticks_ctx0_4mb_tte); | 
					
						
							|  |  |  | SHOW_MMUSTAT_ULONG(immu_tsb_hits_ctx0_256mb_tte); | 
					
						
							|  |  |  | SHOW_MMUSTAT_ULONG(immu_tsb_ticks_ctx0_256mb_tte); | 
					
						
							|  |  |  | SHOW_MMUSTAT_ULONG(immu_tsb_hits_ctxnon0_8k_tte); | 
					
						
							|  |  |  | SHOW_MMUSTAT_ULONG(immu_tsb_ticks_ctxnon0_8k_tte); | 
					
						
							|  |  |  | SHOW_MMUSTAT_ULONG(immu_tsb_hits_ctxnon0_64k_tte); | 
					
						
							|  |  |  | SHOW_MMUSTAT_ULONG(immu_tsb_ticks_ctxnon0_64k_tte); | 
					
						
							|  |  |  | SHOW_MMUSTAT_ULONG(immu_tsb_hits_ctxnon0_4mb_tte); | 
					
						
							|  |  |  | SHOW_MMUSTAT_ULONG(immu_tsb_ticks_ctxnon0_4mb_tte); | 
					
						
							|  |  |  | SHOW_MMUSTAT_ULONG(immu_tsb_hits_ctxnon0_256mb_tte); | 
					
						
							|  |  |  | SHOW_MMUSTAT_ULONG(immu_tsb_ticks_ctxnon0_256mb_tte); | 
					
						
							|  |  |  | SHOW_MMUSTAT_ULONG(dmmu_tsb_hits_ctx0_8k_tte); | 
					
						
							|  |  |  | SHOW_MMUSTAT_ULONG(dmmu_tsb_ticks_ctx0_8k_tte); | 
					
						
							|  |  |  | SHOW_MMUSTAT_ULONG(dmmu_tsb_hits_ctx0_64k_tte); | 
					
						
							|  |  |  | SHOW_MMUSTAT_ULONG(dmmu_tsb_ticks_ctx0_64k_tte); | 
					
						
							|  |  |  | SHOW_MMUSTAT_ULONG(dmmu_tsb_hits_ctx0_4mb_tte); | 
					
						
							|  |  |  | SHOW_MMUSTAT_ULONG(dmmu_tsb_ticks_ctx0_4mb_tte); | 
					
						
							|  |  |  | SHOW_MMUSTAT_ULONG(dmmu_tsb_hits_ctx0_256mb_tte); | 
					
						
							|  |  |  | SHOW_MMUSTAT_ULONG(dmmu_tsb_ticks_ctx0_256mb_tte); | 
					
						
							|  |  |  | SHOW_MMUSTAT_ULONG(dmmu_tsb_hits_ctxnon0_8k_tte); | 
					
						
							|  |  |  | SHOW_MMUSTAT_ULONG(dmmu_tsb_ticks_ctxnon0_8k_tte); | 
					
						
							|  |  |  | SHOW_MMUSTAT_ULONG(dmmu_tsb_hits_ctxnon0_64k_tte); | 
					
						
							|  |  |  | SHOW_MMUSTAT_ULONG(dmmu_tsb_ticks_ctxnon0_64k_tte); | 
					
						
							|  |  |  | SHOW_MMUSTAT_ULONG(dmmu_tsb_hits_ctxnon0_4mb_tte); | 
					
						
							|  |  |  | SHOW_MMUSTAT_ULONG(dmmu_tsb_ticks_ctxnon0_4mb_tte); | 
					
						
							|  |  |  | SHOW_MMUSTAT_ULONG(dmmu_tsb_hits_ctxnon0_256mb_tte); | 
					
						
							|  |  |  | SHOW_MMUSTAT_ULONG(dmmu_tsb_ticks_ctxnon0_256mb_tte); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct attribute *mmu_stat_attrs[] = { | 
					
						
							| 
									
										
										
										
											2011-12-21 14:29:42 -08:00
										 |  |  | 	&dev_attr_immu_tsb_hits_ctx0_8k_tte.attr, | 
					
						
							|  |  |  | 	&dev_attr_immu_tsb_ticks_ctx0_8k_tte.attr, | 
					
						
							|  |  |  | 	&dev_attr_immu_tsb_hits_ctx0_64k_tte.attr, | 
					
						
							|  |  |  | 	&dev_attr_immu_tsb_ticks_ctx0_64k_tte.attr, | 
					
						
							|  |  |  | 	&dev_attr_immu_tsb_hits_ctx0_4mb_tte.attr, | 
					
						
							|  |  |  | 	&dev_attr_immu_tsb_ticks_ctx0_4mb_tte.attr, | 
					
						
							|  |  |  | 	&dev_attr_immu_tsb_hits_ctx0_256mb_tte.attr, | 
					
						
							|  |  |  | 	&dev_attr_immu_tsb_ticks_ctx0_256mb_tte.attr, | 
					
						
							|  |  |  | 	&dev_attr_immu_tsb_hits_ctxnon0_8k_tte.attr, | 
					
						
							|  |  |  | 	&dev_attr_immu_tsb_ticks_ctxnon0_8k_tte.attr, | 
					
						
							|  |  |  | 	&dev_attr_immu_tsb_hits_ctxnon0_64k_tte.attr, | 
					
						
							|  |  |  | 	&dev_attr_immu_tsb_ticks_ctxnon0_64k_tte.attr, | 
					
						
							|  |  |  | 	&dev_attr_immu_tsb_hits_ctxnon0_4mb_tte.attr, | 
					
						
							|  |  |  | 	&dev_attr_immu_tsb_ticks_ctxnon0_4mb_tte.attr, | 
					
						
							|  |  |  | 	&dev_attr_immu_tsb_hits_ctxnon0_256mb_tte.attr, | 
					
						
							|  |  |  | 	&dev_attr_immu_tsb_ticks_ctxnon0_256mb_tte.attr, | 
					
						
							|  |  |  | 	&dev_attr_dmmu_tsb_hits_ctx0_8k_tte.attr, | 
					
						
							|  |  |  | 	&dev_attr_dmmu_tsb_ticks_ctx0_8k_tte.attr, | 
					
						
							|  |  |  | 	&dev_attr_dmmu_tsb_hits_ctx0_64k_tte.attr, | 
					
						
							|  |  |  | 	&dev_attr_dmmu_tsb_ticks_ctx0_64k_tte.attr, | 
					
						
							|  |  |  | 	&dev_attr_dmmu_tsb_hits_ctx0_4mb_tte.attr, | 
					
						
							|  |  |  | 	&dev_attr_dmmu_tsb_ticks_ctx0_4mb_tte.attr, | 
					
						
							|  |  |  | 	&dev_attr_dmmu_tsb_hits_ctx0_256mb_tte.attr, | 
					
						
							|  |  |  | 	&dev_attr_dmmu_tsb_ticks_ctx0_256mb_tte.attr, | 
					
						
							|  |  |  | 	&dev_attr_dmmu_tsb_hits_ctxnon0_8k_tte.attr, | 
					
						
							|  |  |  | 	&dev_attr_dmmu_tsb_ticks_ctxnon0_8k_tte.attr, | 
					
						
							|  |  |  | 	&dev_attr_dmmu_tsb_hits_ctxnon0_64k_tte.attr, | 
					
						
							|  |  |  | 	&dev_attr_dmmu_tsb_ticks_ctxnon0_64k_tte.attr, | 
					
						
							|  |  |  | 	&dev_attr_dmmu_tsb_hits_ctxnon0_4mb_tte.attr, | 
					
						
							|  |  |  | 	&dev_attr_dmmu_tsb_ticks_ctxnon0_4mb_tte.attr, | 
					
						
							|  |  |  | 	&dev_attr_dmmu_tsb_hits_ctxnon0_256mb_tte.attr, | 
					
						
							|  |  |  | 	&dev_attr_dmmu_tsb_ticks_ctxnon0_256mb_tte.attr, | 
					
						
							| 
									
										
										
										
											2007-06-03 23:38:09 -07:00
										 |  |  | 	NULL, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct attribute_group mmu_stat_group = { | 
					
						
							|  |  |  | 	.attrs = mmu_stat_attrs, | 
					
						
							|  |  |  | 	.name = "mmu_stats", | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* XXX convert to rusty's on_one_cpu */ | 
					
						
							|  |  |  | static unsigned long run_on_cpu(unsigned long cpu, | 
					
						
							|  |  |  | 			        unsigned long (*func)(unsigned long), | 
					
						
							|  |  |  | 				unsigned long arg) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-05-16 13:38:07 -07:00
										 |  |  | 	cpumask_t old_affinity; | 
					
						
							| 
									
										
										
										
											2007-06-03 23:38:09 -07:00
										 |  |  | 	unsigned long ret; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-16 13:38:07 -07:00
										 |  |  | 	cpumask_copy(&old_affinity, tsk_cpus_allowed(current)); | 
					
						
							| 
									
										
										
										
											2007-06-03 23:38:09 -07:00
										 |  |  | 	/* should return -EINVAL to userspace */ | 
					
						
							| 
									
										
										
										
											2010-03-27 21:11:56 -07:00
										 |  |  | 	if (set_cpus_allowed_ptr(current, cpumask_of(cpu))) | 
					
						
							| 
									
										
										
										
											2007-06-03 23:38:09 -07:00
										 |  |  | 		return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ret = func(arg); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-27 21:11:56 -07:00
										 |  |  | 	set_cpus_allowed_ptr(current, &old_affinity); | 
					
						
							| 
									
										
										
										
											2007-06-03 23:38:09 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static unsigned long read_mmustat_enable(unsigned long junk) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	unsigned long ra = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	sun4v_mmustat_info(&ra); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return ra != 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static unsigned long write_mmustat_enable(unsigned long val) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	unsigned long ra, orig_ra; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (val) | 
					
						
							|  |  |  | 		ra = __pa(&per_cpu(mmu_stats, smp_processor_id())); | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		ra = 0UL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return sun4v_mmustat_conf(ra, &orig_ra); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-21 14:29:42 -08:00
										 |  |  | static ssize_t show_mmustat_enable(struct device *s, | 
					
						
							|  |  |  | 				struct device_attribute *attr, char *buf) | 
					
						
							| 
									
										
										
										
											2007-06-03 23:38:09 -07:00
										 |  |  | { | 
					
						
							|  |  |  | 	unsigned long val = run_on_cpu(s->id, read_mmustat_enable, 0); | 
					
						
							|  |  |  | 	return sprintf(buf, "%lx\n", val); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-21 14:29:42 -08:00
										 |  |  | static ssize_t store_mmustat_enable(struct device *s, | 
					
						
							|  |  |  | 			struct device_attribute *attr, const char *buf, | 
					
						
							| 
									
										
										
										
											2008-07-01 18:48:41 +02:00
										 |  |  | 			size_t count) | 
					
						
							| 
									
										
										
										
											2007-06-03 23:38:09 -07:00
										 |  |  | { | 
					
						
							|  |  |  | 	unsigned long val, err; | 
					
						
							|  |  |  | 	int ret = sscanf(buf, "%ld", &val); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (ret != 1) | 
					
						
							|  |  |  | 		return -EINVAL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err = run_on_cpu(s->id, write_mmustat_enable, val); | 
					
						
							|  |  |  | 	if (err) | 
					
						
							|  |  |  | 		return -EIO; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return count; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-21 14:29:42 -08:00
										 |  |  | static DEVICE_ATTR(mmustat_enable, 0644, show_mmustat_enable, store_mmustat_enable); | 
					
						
							| 
									
										
										
										
											2007-06-03 23:38:09 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | static int mmu_stats_supported; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-21 14:29:42 -08:00
										 |  |  | static int register_mmu_stats(struct device *s) | 
					
						
							| 
									
										
										
										
											2007-06-03 23:38:09 -07:00
										 |  |  | { | 
					
						
							|  |  |  | 	if (!mmu_stats_supported) | 
					
						
							|  |  |  | 		return 0; | 
					
						
							| 
									
										
										
										
											2011-12-21 14:29:42 -08:00
										 |  |  | 	device_create_file(s, &dev_attr_mmustat_enable); | 
					
						
							| 
									
										
										
										
											2007-06-03 23:38:09 -07:00
										 |  |  | 	return sysfs_create_group(&s->kobj, &mmu_stat_group); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef CONFIG_HOTPLUG_CPU
 | 
					
						
							| 
									
										
										
										
											2011-12-21 14:29:42 -08:00
										 |  |  | static void unregister_mmu_stats(struct device *s) | 
					
						
							| 
									
										
										
										
											2007-06-03 23:38:09 -07:00
										 |  |  | { | 
					
						
							|  |  |  | 	if (!mmu_stats_supported) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	sysfs_remove_group(&s->kobj, &mmu_stat_group); | 
					
						
							| 
									
										
										
										
											2011-12-21 14:29:42 -08:00
										 |  |  | 	device_remove_file(s, &dev_attr_mmustat_enable); | 
					
						
							| 
									
										
										
										
											2007-06-03 23:38:09 -07:00
										 |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define SHOW_CPUDATA_ULONG_NAME(NAME, MEMBER) \
 | 
					
						
							| 
									
										
										
										
											2011-12-21 14:29:42 -08:00
										 |  |  | static ssize_t show_##NAME(struct device *dev, \ | 
					
						
							|  |  |  | 		struct device_attribute *attr, char *buf) \ | 
					
						
							| 
									
										
										
										
											2007-06-03 23:38:09 -07:00
										 |  |  | { \ | 
					
						
							|  |  |  | 	cpuinfo_sparc *c = &cpu_data(dev->id); \ | 
					
						
							| 
									
										
										
										
											2007-06-02 20:46:36 -07:00
										 |  |  | 	return sprintf(buf, "%lu\n", c->MEMBER); \ | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-06-03 23:38:09 -07:00
										 |  |  | #define SHOW_CPUDATA_UINT_NAME(NAME, MEMBER) \
 | 
					
						
							| 
									
										
										
										
											2011-12-21 14:29:42 -08:00
										 |  |  | static ssize_t show_##NAME(struct device *dev, \ | 
					
						
							|  |  |  | 		struct device_attribute *attr, char *buf) \ | 
					
						
							| 
									
										
										
										
											2007-06-02 20:46:36 -07:00
										 |  |  | { \ | 
					
						
							| 
									
										
										
										
											2007-06-03 23:38:09 -07:00
										 |  |  | 	cpuinfo_sparc *c = &cpu_data(dev->id); \ | 
					
						
							| 
									
										
										
										
											2007-06-02 20:46:36 -07:00
										 |  |  | 	return sprintf(buf, "%u\n", c->MEMBER); \ | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-06-03 23:38:09 -07:00
										 |  |  | SHOW_CPUDATA_ULONG_NAME(clock_tick, clock_tick); | 
					
						
							|  |  |  | SHOW_CPUDATA_UINT_NAME(l1_dcache_size, dcache_size); | 
					
						
							|  |  |  | SHOW_CPUDATA_UINT_NAME(l1_dcache_line_size, dcache_line_size); | 
					
						
							|  |  |  | SHOW_CPUDATA_UINT_NAME(l1_icache_size, icache_size); | 
					
						
							|  |  |  | SHOW_CPUDATA_UINT_NAME(l1_icache_line_size, icache_line_size); | 
					
						
							|  |  |  | SHOW_CPUDATA_UINT_NAME(l2_cache_size, ecache_size); | 
					
						
							|  |  |  | SHOW_CPUDATA_UINT_NAME(l2_cache_line_size, ecache_line_size); | 
					
						
							| 
									
										
										
										
											2007-06-02 20:46:36 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-21 14:29:42 -08:00
										 |  |  | static struct device_attribute cpu_core_attrs[] = { | 
					
						
							|  |  |  | 	__ATTR(clock_tick,          0444, show_clock_tick, NULL), | 
					
						
							|  |  |  | 	__ATTR(l1_dcache_size,      0444, show_l1_dcache_size, NULL), | 
					
						
							|  |  |  | 	__ATTR(l1_dcache_line_size, 0444, show_l1_dcache_line_size, NULL), | 
					
						
							|  |  |  | 	__ATTR(l1_icache_size,      0444, show_l1_icache_size, NULL), | 
					
						
							|  |  |  | 	__ATTR(l1_icache_line_size, 0444, show_l1_icache_line_size, NULL), | 
					
						
							|  |  |  | 	__ATTR(l2_cache_size,       0444, show_l2_cache_size, NULL), | 
					
						
							|  |  |  | 	__ATTR(l2_cache_line_size,  0444, show_l2_cache_line_size, NULL), | 
					
						
							| 
									
										
										
										
											2007-06-02 20:46:36 -07:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-06-03 23:38:09 -07:00
										 |  |  | static DEFINE_PER_CPU(struct cpu, cpu_devices); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-06-02 20:46:36 -07:00
										 |  |  | static void register_cpu_online(unsigned int cpu) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct cpu *c = &per_cpu(cpu_devices, cpu); | 
					
						
							| 
									
										
										
										
											2011-12-21 14:29:42 -08:00
										 |  |  | 	struct device *s = &c->dev; | 
					
						
							| 
									
										
										
										
											2007-06-02 20:46:36 -07:00
										 |  |  | 	int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (i = 0; i < ARRAY_SIZE(cpu_core_attrs); i++) | 
					
						
							| 
									
										
										
										
											2011-12-21 14:29:42 -08:00
										 |  |  | 		device_create_file(s, &cpu_core_attrs[i]); | 
					
						
							| 
									
										
										
										
											2007-06-03 23:38:09 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	register_mmu_stats(s); | 
					
						
							| 
									
										
										
										
											2007-06-02 20:46:36 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef CONFIG_HOTPLUG_CPU
 | 
					
						
							|  |  |  | static void unregister_cpu_online(unsigned int cpu) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct cpu *c = &per_cpu(cpu_devices, cpu); | 
					
						
							| 
									
										
										
										
											2011-12-21 14:29:42 -08:00
										 |  |  | 	struct device *s = &c->dev; | 
					
						
							| 
									
										
										
										
											2007-06-02 20:46:36 -07:00
										 |  |  | 	int i; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-06-03 23:38:09 -07:00
										 |  |  | 	unregister_mmu_stats(s); | 
					
						
							| 
									
										
										
										
											2007-06-02 20:46:36 -07:00
										 |  |  | 	for (i = 0; i < ARRAY_SIZE(cpu_core_attrs); i++) | 
					
						
							| 
									
										
										
										
											2011-12-21 14:29:42 -08:00
										 |  |  | 		device_remove_file(s, &cpu_core_attrs[i]); | 
					
						
							| 
									
										
										
										
											2007-06-02 20:46:36 -07:00
										 |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int __cpuinit sysfs_cpu_notify(struct notifier_block *self, | 
					
						
							|  |  |  | 				      unsigned long action, void *hcpu) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	unsigned int cpu = (unsigned int)(long)hcpu; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch (action) { | 
					
						
							|  |  |  | 	case CPU_ONLINE: | 
					
						
							|  |  |  | 	case CPU_ONLINE_FROZEN: | 
					
						
							|  |  |  | 		register_cpu_online(cpu); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | #ifdef CONFIG_HOTPLUG_CPU
 | 
					
						
							|  |  |  | 	case CPU_DEAD: | 
					
						
							|  |  |  | 	case CPU_DEAD_FROZEN: | 
					
						
							|  |  |  | 		unregister_cpu_online(cpu); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return NOTIFY_OK; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct notifier_block __cpuinitdata sysfs_cpu_nb = { | 
					
						
							|  |  |  | 	.notifier_call	= sysfs_cpu_notify, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-06-03 23:38:09 -07:00
										 |  |  | static void __init check_mmu_stats(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	unsigned long dummy1, err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (tlb_type != hypervisor) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err = sun4v_mmustat_info(&dummy1); | 
					
						
							|  |  |  | 	if (!err) | 
					
						
							|  |  |  | 		mmu_stats_supported = 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-23 05:40:25 -07:00
										 |  |  | static void register_nodes(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | #ifdef CONFIG_NUMA
 | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (i = 0; i < MAX_NUMNODES; i++) | 
					
						
							|  |  |  | 		register_one_node(i); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-06-02 14:41:44 -07:00
										 |  |  | static int __init topology_init(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int cpu; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-23 05:40:25 -07:00
										 |  |  | 	register_nodes(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-06-03 23:38:09 -07:00
										 |  |  | 	check_mmu_stats(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-06-02 20:46:36 -07:00
										 |  |  | 	register_cpu_notifier(&sysfs_cpu_nb); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-06-02 14:41:44 -07:00
										 |  |  | 	for_each_possible_cpu(cpu) { | 
					
						
							|  |  |  | 		struct cpu *c = &per_cpu(cpu_devices, cpu); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		register_cpu(c, cpu); | 
					
						
							| 
									
										
										
										
											2007-06-02 20:46:36 -07:00
										 |  |  | 		if (cpu_online(cpu)) | 
					
						
							|  |  |  | 			register_cpu_online(cpu); | 
					
						
							| 
									
										
										
										
											2007-06-02 14:41:44 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | subsys_initcall(topology_init); |