static int nr_packages;
 static struct device *cpu_hwmon_dev;
 
-static SENSOR_DEVICE_ATTR(name, 0444, NULL, NULL, 0);
-
-static struct attribute *cpu_hwmon_attributes[] = {
-       &sensor_dev_attr_name.dev_attr.attr,
-       NULL
-};
-
-/* Hwmon device attribute group */
-static struct attribute_group cpu_hwmon_attribute_group = {
-       .attrs = cpu_hwmon_attributes,
-};
-
-static ssize_t get_cpu_temp(struct device *dev,
-                       struct device_attribute *attr, char *buf);
-static ssize_t cpu_temp_label(struct device *dev,
-                       struct device_attribute *attr, char *buf);
-
-static SENSOR_DEVICE_ATTR(temp1_input, 0444, get_cpu_temp, NULL, 1);
-static SENSOR_DEVICE_ATTR(temp1_label, 0444, cpu_temp_label, NULL, 1);
-static SENSOR_DEVICE_ATTR(temp2_input, 0444, get_cpu_temp, NULL, 2);
-static SENSOR_DEVICE_ATTR(temp2_label, 0444, cpu_temp_label, NULL, 2);
-static SENSOR_DEVICE_ATTR(temp3_input, 0444, get_cpu_temp, NULL, 3);
-static SENSOR_DEVICE_ATTR(temp3_label, 0444, cpu_temp_label, NULL, 3);
-static SENSOR_DEVICE_ATTR(temp4_input, 0444, get_cpu_temp, NULL, 4);
-static SENSOR_DEVICE_ATTR(temp4_label, 0444, cpu_temp_label, NULL, 4);
-
-static const struct attribute *hwmon_cputemp[4][3] = {
-       {
-               &sensor_dev_attr_temp1_input.dev_attr.attr,
-               &sensor_dev_attr_temp1_label.dev_attr.attr,
-               NULL
-       },
-       {
-               &sensor_dev_attr_temp2_input.dev_attr.attr,
-               &sensor_dev_attr_temp2_label.dev_attr.attr,
-               NULL
-       },
-       {
-               &sensor_dev_attr_temp3_input.dev_attr.attr,
-               &sensor_dev_attr_temp3_label.dev_attr.attr,
-               NULL
-       },
-       {
-               &sensor_dev_attr_temp4_input.dev_attr.attr,
-               &sensor_dev_attr_temp4_label.dev_attr.attr,
-               NULL
-       }
-};
-
 static ssize_t cpu_temp_label(struct device *dev,
                        struct device_attribute *attr, char *buf)
 {
        return sprintf(buf, "%d\n", value);
 }
 
-static int create_sysfs_cputemp_files(struct kobject *kobj)
-{
-       int i, ret = 0;
-
-       for (i = 0; i < nr_packages; i++)
-               ret = sysfs_create_files(kobj, hwmon_cputemp[i]);
+static SENSOR_DEVICE_ATTR(temp1_input, 0444, get_cpu_temp, NULL, 1);
+static SENSOR_DEVICE_ATTR(temp1_label, 0444, cpu_temp_label, NULL, 1);
+static SENSOR_DEVICE_ATTR(temp2_input, 0444, get_cpu_temp, NULL, 2);
+static SENSOR_DEVICE_ATTR(temp2_label, 0444, cpu_temp_label, NULL, 2);
+static SENSOR_DEVICE_ATTR(temp3_input, 0444, get_cpu_temp, NULL, 3);
+static SENSOR_DEVICE_ATTR(temp3_label, 0444, cpu_temp_label, NULL, 3);
+static SENSOR_DEVICE_ATTR(temp4_input, 0444, get_cpu_temp, NULL, 4);
+static SENSOR_DEVICE_ATTR(temp4_label, 0444, cpu_temp_label, NULL, 4);
 
-       return ret;
-}
+static struct attribute *cpu_hwmon_attributes[] = {
+       &sensor_dev_attr_temp1_input.dev_attr.attr,
+       &sensor_dev_attr_temp1_label.dev_attr.attr,
+       &sensor_dev_attr_temp2_input.dev_attr.attr,
+       &sensor_dev_attr_temp2_label.dev_attr.attr,
+       &sensor_dev_attr_temp3_input.dev_attr.attr,
+       &sensor_dev_attr_temp3_label.dev_attr.attr,
+       &sensor_dev_attr_temp4_input.dev_attr.attr,
+       &sensor_dev_attr_temp4_label.dev_attr.attr,
+       NULL
+};
 
-static void remove_sysfs_cputemp_files(struct kobject *kobj)
+static umode_t cpu_hwmon_is_visible(struct kobject *kobj,
+                                   struct attribute *attr, int i)
 {
-       int i;
+       int id = i / 2;
 
-       for (i = 0; i < nr_packages; i++)
-               sysfs_remove_files(kobj, hwmon_cputemp[i]);
+       if (id < nr_packages)
+               return attr->mode;
+       return 0;
 }
 
+static struct attribute_group cpu_hwmon_group = {
+       .attrs = cpu_hwmon_attributes,
+       .is_visible = cpu_hwmon_is_visible,
+};
+
+static const struct attribute_group *cpu_hwmon_groups[] = {
+       &cpu_hwmon_group,
+       NULL
+};
+
 #define CPU_THERMAL_THRESHOLD 90000
 static struct delayed_work thermal_work;
 
 
 static int __init loongson_hwmon_init(void)
 {
-       int ret;
-
        pr_info("Loongson Hwmon Enter...\n");
 
        if (cpu_has_csr())
                csr_temp_enable = csr_readl(LOONGSON_CSR_FEATURES) &
                                  LOONGSON_CSRF_TEMP;
 
-       cpu_hwmon_dev = hwmon_device_register_with_info(NULL, "cpu_hwmon", NULL, NULL, NULL);
-       if (IS_ERR(cpu_hwmon_dev)) {
-               ret = PTR_ERR(cpu_hwmon_dev);
-               pr_err("hwmon_device_register fail!\n");
-               goto fail_hwmon_device_register;
-       }
-
        nr_packages = loongson_sysconf.nr_cpus /
                loongson_sysconf.cores_per_package;
 
-       ret = create_sysfs_cputemp_files(&cpu_hwmon_dev->kobj);
-       if (ret) {
-               pr_err("fail to create cpu temperature interface!\n");
-               goto fail_create_sysfs_cputemp_files;
+       cpu_hwmon_dev = hwmon_device_register_with_groups(NULL, "cpu_hwmon",
+                                                         NULL, cpu_hwmon_groups);
+       if (IS_ERR(cpu_hwmon_dev)) {
+               pr_err("hwmon_device_register fail!\n");
+               return PTR_ERR(cpu_hwmon_dev);
        }
 
        INIT_DEFERRABLE_WORK(&thermal_work, do_thermal_timer);
        schedule_delayed_work(&thermal_work, msecs_to_jiffies(20000));
 
-       return ret;
-
-fail_create_sysfs_cputemp_files:
-       sysfs_remove_group(&cpu_hwmon_dev->kobj,
-                               &cpu_hwmon_attribute_group);
-       hwmon_device_unregister(cpu_hwmon_dev);
-
-fail_hwmon_device_register:
-       return ret;
+       return 0;
 }
 
 static void __exit loongson_hwmon_exit(void)
 {
        cancel_delayed_work_sync(&thermal_work);
-       remove_sysfs_cputemp_files(&cpu_hwmon_dev->kobj);
-       sysfs_remove_group(&cpu_hwmon_dev->kobj,
-                               &cpu_hwmon_attribute_group);
        hwmon_device_unregister(cpu_hwmon_dev);
 }