--- zzzz-none-000/linux-3.10.107/drivers/platform/x86/compal-laptop.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/drivers/platform/x86/compal-laptop.c 2021-02-04 17:41:59.000000000 +0000 @@ -82,7 +82,7 @@ #include #include #include - +#include /* ======= */ /* Defines */ @@ -151,6 +151,8 @@ #define BAT_STATUS2 0xF1 #define BAT_STOP_CHARGE1 0xF2 #define BAT_STOP_CHARGE2 0xF3 +#define BAT_CHARGE_LIMIT 0x03 +#define BAT_CHARGE_LIMIT_MAX 100 #define BAT_S0_DISCHARGE (1 << 0) #define BAT_S0_DISCHRG_CRITICAL (1 << 2) @@ -173,12 +175,11 @@ /* ======= */ struct compal_data{ /* Fan control */ - struct device *hwmon_dev; - int pwm_enable; /* 0:full on, 1:set by pwm1, 2:control by moterboard */ + int pwm_enable; /* 0:full on, 1:set by pwm1, 2:control by motherboard */ unsigned char curr_pwm; /* Power supply */ - struct power_supply psy; + struct power_supply *psy; struct power_supply_info psy_info; char bat_model_name[BAT_MODEL_NAME_LEN + 1]; char bat_manufacturer_name[BAT_MANUFACTURER_NAME_LEN + 1]; @@ -402,15 +403,6 @@ SIMPLE_MASKED_STORE_SHOW(wake_up_key, WAKE_UP_ADDR, WAKE_UP_KEY) SIMPLE_MASKED_STORE_SHOW(wake_up_mouse, WAKE_UP_ADDR, WAKE_UP_MOUSE) - -/* General hwmon interface */ -static ssize_t hwmon_name_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sprintf(buf, "%s\n", DRIVER_NAME); -} - - /* Fan control interface */ static ssize_t pwm_enable_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -425,7 +417,8 @@ struct compal_data *data = dev_get_drvdata(dev); long val; int err; - err = strict_strtol(buf, 10, &val); + + err = kstrtol(buf, 10, &val); if (err) return err; if (val < 0) @@ -463,7 +456,8 @@ struct compal_data *data = dev_get_drvdata(dev); long val; int err; - err = strict_strtol(buf, 10, &val); + + err = kstrtol(buf, 10, &val); if (err) return err; if (val < 0 || val > 255) @@ -573,8 +567,7 @@ enum power_supply_property psp, union power_supply_propval *val) { - struct compal_data *data; - data = container_of(psy, struct compal_data, psy); + struct compal_data *data = power_supply_get_drvdata(psy); switch (psp) { case POWER_SUPPLY_PROP_STATUS: @@ -610,6 +603,12 @@ case POWER_SUPPLY_PROP_CHARGE_NOW: val->intval = ec_read_u16(BAT_CHARGE_NOW) * 1000; break; + case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT: + val->intval = ec_read_u8(BAT_CHARGE_LIMIT); + break; + case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX: + val->intval = BAT_CHARGE_LIMIT_MAX; + break; case POWER_SUPPLY_PROP_CAPACITY: val->intval = ec_read_u8(BAT_CAPACITY); break; @@ -643,6 +642,36 @@ return 0; } +static int bat_set_property(struct power_supply *psy, + enum power_supply_property psp, + const union power_supply_propval *val) +{ + int level; + + switch (psp) { + case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT: + level = val->intval; + if (level < 0 || level > BAT_CHARGE_LIMIT_MAX) + return -EINVAL; + if (ec_write(BAT_CHARGE_LIMIT, level) < 0) + return -EIO; + break; + default: + break; + } + return 0; +} + +static int bat_writeable_property(struct power_supply *psy, + enum power_supply_property psp) +{ + switch (psp) { + case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT: + return 1; + default: + return 0; + } +} @@ -663,62 +692,61 @@ static DEVICE_ATTR(wake_up_mouse, 0644, wake_up_mouse_show, wake_up_mouse_store); -static SENSOR_DEVICE_ATTR(name, S_IRUGO, hwmon_name_show, NULL, 1); -static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, fan_show, NULL, 1); -static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, temp_cpu, NULL, 1); -static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, temp_cpu_local, NULL, 1); -static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, temp_cpu_DTS, NULL, 1); -static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, temp_northbridge, NULL, 1); -static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO, temp_vga, NULL, 1); -static SENSOR_DEVICE_ATTR(temp6_input, S_IRUGO, temp_SKIN, NULL, 1); -static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, label_cpu, NULL, 1); -static SENSOR_DEVICE_ATTR(temp2_label, S_IRUGO, label_cpu_local, NULL, 1); -static SENSOR_DEVICE_ATTR(temp3_label, S_IRUGO, label_cpu_DTS, NULL, 1); -static SENSOR_DEVICE_ATTR(temp4_label, S_IRUGO, label_northbridge, NULL, 1); -static SENSOR_DEVICE_ATTR(temp5_label, S_IRUGO, label_vga, NULL, 1); -static SENSOR_DEVICE_ATTR(temp6_label, S_IRUGO, label_SKIN, NULL, 1); -static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, pwm_show, pwm_store, 1); -static SENSOR_DEVICE_ATTR(pwm1_enable, - S_IRUGO | S_IWUSR, pwm_enable_show, pwm_enable_store, 0); +static DEVICE_ATTR(fan1_input, S_IRUGO, fan_show, NULL); +static DEVICE_ATTR(temp1_input, S_IRUGO, temp_cpu, NULL); +static DEVICE_ATTR(temp2_input, S_IRUGO, temp_cpu_local, NULL); +static DEVICE_ATTR(temp3_input, S_IRUGO, temp_cpu_DTS, NULL); +static DEVICE_ATTR(temp4_input, S_IRUGO, temp_northbridge, NULL); +static DEVICE_ATTR(temp5_input, S_IRUGO, temp_vga, NULL); +static DEVICE_ATTR(temp6_input, S_IRUGO, temp_SKIN, NULL); +static DEVICE_ATTR(temp1_label, S_IRUGO, label_cpu, NULL); +static DEVICE_ATTR(temp2_label, S_IRUGO, label_cpu_local, NULL); +static DEVICE_ATTR(temp3_label, S_IRUGO, label_cpu_DTS, NULL); +static DEVICE_ATTR(temp4_label, S_IRUGO, label_northbridge, NULL); +static DEVICE_ATTR(temp5_label, S_IRUGO, label_vga, NULL); +static DEVICE_ATTR(temp6_label, S_IRUGO, label_SKIN, NULL); +static DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, pwm_show, pwm_store); +static DEVICE_ATTR(pwm1_enable, + S_IRUGO | S_IWUSR, pwm_enable_show, pwm_enable_store); -static struct attribute *compal_attributes[] = { +static struct attribute *compal_platform_attrs[] = { &dev_attr_wake_up_pme.attr, &dev_attr_wake_up_modem.attr, &dev_attr_wake_up_lan.attr, &dev_attr_wake_up_wlan.attr, &dev_attr_wake_up_key.attr, &dev_attr_wake_up_mouse.attr, - /* Maybe put the sensor-stuff in a separate hwmon-driver? That way, - * the hwmon sysfs won't be cluttered with the above files. */ - &sensor_dev_attr_name.dev_attr.attr, - &sensor_dev_attr_pwm1_enable.dev_attr.attr, - &sensor_dev_attr_pwm1.dev_attr.attr, - &sensor_dev_attr_fan1_input.dev_attr.attr, - &sensor_dev_attr_temp1_input.dev_attr.attr, - &sensor_dev_attr_temp2_input.dev_attr.attr, - &sensor_dev_attr_temp3_input.dev_attr.attr, - &sensor_dev_attr_temp4_input.dev_attr.attr, - &sensor_dev_attr_temp5_input.dev_attr.attr, - &sensor_dev_attr_temp6_input.dev_attr.attr, - &sensor_dev_attr_temp1_label.dev_attr.attr, - &sensor_dev_attr_temp2_label.dev_attr.attr, - &sensor_dev_attr_temp3_label.dev_attr.attr, - &sensor_dev_attr_temp4_label.dev_attr.attr, - &sensor_dev_attr_temp5_label.dev_attr.attr, - &sensor_dev_attr_temp6_label.dev_attr.attr, NULL }; +static struct attribute_group compal_platform_attr_group = { + .attrs = compal_platform_attrs +}; -static struct attribute_group compal_attribute_group = { - .attrs = compal_attributes +static struct attribute *compal_hwmon_attrs[] = { + &dev_attr_pwm1_enable.attr, + &dev_attr_pwm1.attr, + &dev_attr_fan1_input.attr, + &dev_attr_temp1_input.attr, + &dev_attr_temp2_input.attr, + &dev_attr_temp3_input.attr, + &dev_attr_temp4_input.attr, + &dev_attr_temp5_input.attr, + &dev_attr_temp6_input.attr, + &dev_attr_temp1_label.attr, + &dev_attr_temp2_label.attr, + &dev_attr_temp3_label.attr, + &dev_attr_temp4_label.attr, + &dev_attr_temp5_label.attr, + &dev_attr_temp6_label.attr, + NULL }; +ATTRIBUTE_GROUPS(compal_hwmon); static int compal_probe(struct platform_device *); static int compal_remove(struct platform_device *); static struct platform_driver compal_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, }, .probe = compal_probe, .remove = compal_remove, @@ -736,6 +764,8 @@ POWER_SUPPLY_PROP_POWER_NOW, POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, POWER_SUPPLY_PROP_CHARGE_NOW, + POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT, + POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX, POWER_SUPPLY_PROP_CAPACITY, POWER_SUPPLY_PROP_CAPACITY_LEVEL, POWER_SUPPLY_PROP_TEMP, @@ -884,14 +914,18 @@ }; MODULE_DEVICE_TABLE(dmi, compal_dmi_table); +static const struct power_supply_desc psy_bat_desc = { + .name = DRIVER_NAME, + .type = POWER_SUPPLY_TYPE_BATTERY, + .properties = compal_bat_properties, + .num_properties = ARRAY_SIZE(compal_bat_properties), + .get_property = bat_get_property, + .set_property = bat_set_property, + .property_is_writeable = bat_writeable_property, +}; + static void initialize_power_supply_data(struct compal_data *data) { - data->psy.name = DRIVER_NAME; - data->psy.type = POWER_SUPPLY_TYPE_BATTERY; - data->psy.properties = compal_bat_properties; - data->psy.num_properties = ARRAY_SIZE(compal_bat_properties); - data->psy.get_property = bat_get_property; - ec_read_sequence(BAT_MANUFACTURER_NAME_ADDR, data->bat_manufacturer_name, BAT_MANUFACTURER_NAME_LEN); @@ -966,7 +1000,7 @@ return -ENODEV; } - if (!acpi_video_backlight_support()) { + if (acpi_video_get_backlight_type() == acpi_backlight_vendor) { struct backlight_properties props; memset(&props, 0, sizeof(struct backlight_properties)); props.type = BACKLIGHT_PLATFORM; @@ -1019,39 +1053,48 @@ { int err; struct compal_data *data; + struct device *hwmon_dev; + struct power_supply_config psy_cfg = {}; if (!extra_features) return 0; /* Fan control */ - data = kzalloc(sizeof(struct compal_data), GFP_KERNEL); + data = devm_kzalloc(&pdev->dev, sizeof(struct compal_data), GFP_KERNEL); if (!data) return -ENOMEM; initialize_fan_control_data(data); - err = sysfs_create_group(&pdev->dev.kobj, &compal_attribute_group); - if (err) { - kfree(data); + err = sysfs_create_group(&pdev->dev.kobj, &compal_platform_attr_group); + if (err) return err; - } - data->hwmon_dev = hwmon_device_register(&pdev->dev); - if (IS_ERR(data->hwmon_dev)) { - err = PTR_ERR(data->hwmon_dev); - sysfs_remove_group(&pdev->dev.kobj, - &compal_attribute_group); - kfree(data); - return err; + hwmon_dev = devm_hwmon_device_register_with_groups(&pdev->dev, + "compal", data, + compal_hwmon_groups); + if (IS_ERR(hwmon_dev)) { + err = PTR_ERR(hwmon_dev); + goto remove; } /* Power supply */ initialize_power_supply_data(data); - power_supply_register(&compal_device->dev, &data->psy); + psy_cfg.drv_data = data; + data->psy = power_supply_register(&compal_device->dev, &psy_bat_desc, + &psy_cfg); + if (IS_ERR(data->psy)) { + err = PTR_ERR(data->psy); + goto remove; + } platform_set_drvdata(pdev, data); return 0; + +remove: + sysfs_remove_group(&pdev->dev.kobj, &compal_platform_attr_group); + return err; } static void __exit compal_cleanup(void) @@ -1078,13 +1121,9 @@ pwm_disable_control(); data = platform_get_drvdata(pdev); - hwmon_device_unregister(data->hwmon_dev); - power_supply_unregister(&data->psy); - - platform_set_drvdata(pdev, NULL); - kfree(data); + power_supply_unregister(data->psy); - sysfs_remove_group(&pdev->dev.kobj, &compal_attribute_group); + sysfs_remove_group(&pdev->dev.kobj, &compal_platform_attr_group); return 0; }