+ * Print cpu online, possible, present, and system maps
+ */
+static ssize_t print_cpus_map(char *buf, const struct cpumask *map)
+{
+ int n = cpulist_scnprintf(buf, PAGE_SIZE-2, map);
+
+ buf[n++] = '\n';
+ buf[n] = '\0';
+ return n;
+}
+
+#define print_cpus_func(type) \
+static ssize_t print_cpus_##type(struct sysdev_class *class, char *buf) \
+{ \
+ return print_cpus_map(buf, cpu_##type##_mask); \
+} \
+static struct sysdev_class_attribute attr_##type##_map = \
+ _SYSDEV_CLASS_ATTR(type, 0444, print_cpus_##type, NULL)
+
+print_cpus_func(online);
+print_cpus_func(possible);
+print_cpus_func(present);
+
+/*
+ * Print values for NR_CPUS and offlined cpus
+ */
+static ssize_t print_cpus_kernel_max(struct sysdev_class *class, char *buf)
+{
+ int n = snprintf(buf, PAGE_SIZE-2, "%d\n", NR_CPUS - 1);
+ return n;
+}
+static SYSDEV_CLASS_ATTR(kernel_max, 0444, print_cpus_kernel_max, NULL);
+
+/* arch-optional setting to enable display of offline cpus >= nr_cpu_ids */
+unsigned int total_cpus;
+
+static ssize_t print_cpus_offline(struct sysdev_class *class, char *buf)
+{
+ int n = 0, len = PAGE_SIZE-2;
+ cpumask_var_t offline;
+
+ /* display offline cpus < nr_cpu_ids */
+ if (!alloc_cpumask_var(&offline, GFP_KERNEL))
+ return -ENOMEM;
+ cpumask_complement(offline, cpu_online_mask);
+ n = cpulist_scnprintf(buf, len, offline);
+ free_cpumask_var(offline);
+
+ /* display offline cpus >= nr_cpu_ids */
+ if (total_cpus && nr_cpu_ids < total_cpus) {
+ if (n && n < len)
+ buf[n++] = ',';
+
+ if (nr_cpu_ids == total_cpus-1)
+ n += snprintf(&buf[n], len - n, "%d", nr_cpu_ids);
+ else
+ n += snprintf(&buf[n], len - n, "%d-%d",
+ nr_cpu_ids, total_cpus-1);
+ }
+
+ n += snprintf(&buf[n], len - n, "\n");
+ return n;
+}
+static SYSDEV_CLASS_ATTR(offline, 0444, print_cpus_offline, NULL);
+
+static struct sysdev_class_attribute *cpu_state_attr[] = {
+ &attr_online_map,
+ &attr_possible_map,
+ &attr_present_map,
+ &attr_kernel_max,
+ &attr_offline,
+};
+
+static int cpu_states_init(void)
+{
+ int i;
+ int err = 0;
+
+ for (i = 0; i < ARRAY_SIZE(cpu_state_attr); i++) {
+ int ret;
+ ret = sysdev_class_create_file(&cpu_sysdev_class,
+ cpu_state_attr[i]);
+ if (!err)
+ err = ret;
+ }
+ return err;
+}
+
+/*