0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0016
0017 #include <linux/acpi.h>
0018 #include <linux/kernel.h>
0019 #include <linux/module.h>
0020 #include <linux/pci.h>
0021 #include <linux/pm.h>
0022 #include <linux/slab.h>
0023 #include <linux/thermal.h>
0024 #include <linux/types.h>
0025 #include <linux/units.h>
0026
0027 MODULE_AUTHOR("Thomas Sujith");
0028 MODULE_AUTHOR("Zhang Rui");
0029 MODULE_DESCRIPTION("Intel Menlow platform specific driver");
0030 MODULE_LICENSE("GPL v2");
0031
0032
0033
0034
0035
0036 #define MEMORY_GET_BANDWIDTH "GTHS"
0037 #define MEMORY_SET_BANDWIDTH "STHS"
0038 #define MEMORY_ARG_CUR_BANDWIDTH 1
0039 #define MEMORY_ARG_MAX_BANDWIDTH 0
0040
0041 static void intel_menlow_unregister_sensor(void);
0042
0043
0044
0045
0046
0047
0048 static int memory_get_max_bandwidth(struct thermal_cooling_device *cdev,
0049 unsigned long *max_state)
0050 {
0051 struct acpi_device *device = cdev->devdata;
0052 acpi_handle handle = device->handle;
0053 unsigned long long value;
0054 struct acpi_object_list arg_list;
0055 union acpi_object arg;
0056 acpi_status status = AE_OK;
0057
0058 arg_list.count = 1;
0059 arg_list.pointer = &arg;
0060 arg.type = ACPI_TYPE_INTEGER;
0061 arg.integer.value = MEMORY_ARG_MAX_BANDWIDTH;
0062 status = acpi_evaluate_integer(handle, MEMORY_GET_BANDWIDTH,
0063 &arg_list, &value);
0064 if (ACPI_FAILURE(status))
0065 return -EFAULT;
0066
0067 if (!value)
0068 return -EINVAL;
0069
0070 *max_state = value - 1;
0071 return 0;
0072 }
0073
0074 static int memory_get_cur_bandwidth(struct thermal_cooling_device *cdev,
0075 unsigned long *value)
0076 {
0077 struct acpi_device *device = cdev->devdata;
0078 acpi_handle handle = device->handle;
0079 unsigned long long result;
0080 struct acpi_object_list arg_list;
0081 union acpi_object arg;
0082 acpi_status status = AE_OK;
0083
0084 arg_list.count = 1;
0085 arg_list.pointer = &arg;
0086 arg.type = ACPI_TYPE_INTEGER;
0087 arg.integer.value = MEMORY_ARG_CUR_BANDWIDTH;
0088 status = acpi_evaluate_integer(handle, MEMORY_GET_BANDWIDTH,
0089 &arg_list, &result);
0090 if (ACPI_FAILURE(status))
0091 return -EFAULT;
0092
0093 *value = result;
0094 return 0;
0095 }
0096
0097 static int memory_set_cur_bandwidth(struct thermal_cooling_device *cdev,
0098 unsigned long state)
0099 {
0100 struct acpi_device *device = cdev->devdata;
0101 acpi_handle handle = device->handle;
0102 struct acpi_object_list arg_list;
0103 union acpi_object arg;
0104 acpi_status status;
0105 unsigned long long temp;
0106 unsigned long max_state;
0107
0108 if (memory_get_max_bandwidth(cdev, &max_state))
0109 return -EFAULT;
0110
0111 if (state > max_state)
0112 return -EINVAL;
0113
0114 arg_list.count = 1;
0115 arg_list.pointer = &arg;
0116 arg.type = ACPI_TYPE_INTEGER;
0117 arg.integer.value = state;
0118
0119 status =
0120 acpi_evaluate_integer(handle, MEMORY_SET_BANDWIDTH, &arg_list,
0121 &temp);
0122
0123 pr_info("Bandwidth value was %ld: status is %d\n", state, status);
0124 if (ACPI_FAILURE(status))
0125 return -EFAULT;
0126
0127 return 0;
0128 }
0129
0130 static const struct thermal_cooling_device_ops memory_cooling_ops = {
0131 .get_max_state = memory_get_max_bandwidth,
0132 .get_cur_state = memory_get_cur_bandwidth,
0133 .set_cur_state = memory_set_cur_bandwidth,
0134 };
0135
0136
0137
0138
0139 static int intel_menlow_memory_add(struct acpi_device *device)
0140 {
0141 int result = -ENODEV;
0142 struct thermal_cooling_device *cdev;
0143
0144 if (!device)
0145 return -EINVAL;
0146
0147 if (!acpi_has_method(device->handle, MEMORY_GET_BANDWIDTH))
0148 goto end;
0149
0150 if (!acpi_has_method(device->handle, MEMORY_SET_BANDWIDTH))
0151 goto end;
0152
0153 cdev = thermal_cooling_device_register("Memory controller", device,
0154 &memory_cooling_ops);
0155 if (IS_ERR(cdev)) {
0156 result = PTR_ERR(cdev);
0157 goto end;
0158 }
0159
0160 device->driver_data = cdev;
0161 result = sysfs_create_link(&device->dev.kobj,
0162 &cdev->device.kobj, "thermal_cooling");
0163 if (result)
0164 goto unregister;
0165
0166 result = sysfs_create_link(&cdev->device.kobj,
0167 &device->dev.kobj, "device");
0168 if (result) {
0169 sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
0170 goto unregister;
0171 }
0172
0173 end:
0174 return result;
0175
0176 unregister:
0177 thermal_cooling_device_unregister(cdev);
0178 return result;
0179
0180 }
0181
0182 static int intel_menlow_memory_remove(struct acpi_device *device)
0183 {
0184 struct thermal_cooling_device *cdev;
0185
0186 if (!device)
0187 return -EINVAL;
0188
0189 cdev = acpi_driver_data(device);
0190 if (!cdev)
0191 return -EINVAL;
0192
0193 sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
0194 sysfs_remove_link(&cdev->device.kobj, "device");
0195 thermal_cooling_device_unregister(cdev);
0196
0197 return 0;
0198 }
0199
0200 static const struct acpi_device_id intel_menlow_memory_ids[] = {
0201 {"INT0002", 0},
0202 {"", 0},
0203 };
0204
0205 static struct acpi_driver intel_menlow_memory_driver = {
0206 .name = "intel_menlow_thermal_control",
0207 .ids = intel_menlow_memory_ids,
0208 .ops = {
0209 .add = intel_menlow_memory_add,
0210 .remove = intel_menlow_memory_remove,
0211 },
0212 };
0213
0214
0215
0216
0217
0218 #define THERMAL_AUX0 0
0219 #define THERMAL_AUX1 1
0220 #define GET_AUX0 "GAX0"
0221 #define GET_AUX1 "GAX1"
0222 #define SET_AUX0 "SAX0"
0223 #define SET_AUX1 "SAX1"
0224
0225 struct intel_menlow_attribute {
0226 struct device_attribute attr;
0227 struct device *device;
0228 acpi_handle handle;
0229 struct list_head node;
0230 };
0231
0232 static LIST_HEAD(intel_menlow_attr_list);
0233 static DEFINE_MUTEX(intel_menlow_attr_lock);
0234
0235
0236
0237
0238
0239
0240
0241 static int sensor_get_auxtrip(acpi_handle handle, int index,
0242 unsigned long long *value)
0243 {
0244 acpi_status status;
0245
0246 if ((index != 0 && index != 1) || !value)
0247 return -EINVAL;
0248
0249 status = acpi_evaluate_integer(handle, index ? GET_AUX1 : GET_AUX0,
0250 NULL, value);
0251 if (ACPI_FAILURE(status))
0252 return -EIO;
0253
0254 return 0;
0255 }
0256
0257
0258
0259
0260
0261
0262
0263 static int sensor_set_auxtrip(acpi_handle handle, int index, int value)
0264 {
0265 acpi_status status;
0266 union acpi_object arg = {
0267 ACPI_TYPE_INTEGER
0268 };
0269 struct acpi_object_list args = {
0270 1, &arg
0271 };
0272 unsigned long long temp;
0273
0274 if (index != 0 && index != 1)
0275 return -EINVAL;
0276
0277 status = acpi_evaluate_integer(handle, index ? GET_AUX0 : GET_AUX1,
0278 NULL, &temp);
0279 if (ACPI_FAILURE(status))
0280 return -EIO;
0281 if ((index && value < temp) || (!index && value > temp))
0282 return -EINVAL;
0283
0284 arg.integer.value = value;
0285 status = acpi_evaluate_integer(handle, index ? SET_AUX1 : SET_AUX0,
0286 &args, &temp);
0287 if (ACPI_FAILURE(status))
0288 return -EIO;
0289
0290
0291
0292 return 0;
0293 }
0294
0295 #define to_intel_menlow_attr(_attr) \
0296 container_of(_attr, struct intel_menlow_attribute, attr)
0297
0298 static ssize_t aux_show(struct device *dev, struct device_attribute *dev_attr,
0299 char *buf, int idx)
0300 {
0301 struct intel_menlow_attribute *attr = to_intel_menlow_attr(dev_attr);
0302 unsigned long long value;
0303 int result;
0304
0305 result = sensor_get_auxtrip(attr->handle, idx, &value);
0306 if (result)
0307 return result;
0308
0309 return sprintf(buf, "%lu", deci_kelvin_to_celsius(value));
0310 }
0311
0312 static ssize_t aux0_show(struct device *dev,
0313 struct device_attribute *dev_attr, char *buf)
0314 {
0315 return aux_show(dev, dev_attr, buf, 0);
0316 }
0317
0318 static ssize_t aux1_show(struct device *dev,
0319 struct device_attribute *dev_attr, char *buf)
0320 {
0321 return aux_show(dev, dev_attr, buf, 1);
0322 }
0323
0324 static ssize_t aux_store(struct device *dev, struct device_attribute *dev_attr,
0325 const char *buf, size_t count, int idx)
0326 {
0327 struct intel_menlow_attribute *attr = to_intel_menlow_attr(dev_attr);
0328 int value;
0329 int result;
0330
0331
0332 if (!sscanf(buf, "%d", &value))
0333 return -EINVAL;
0334
0335 if (value < 0)
0336 return -EINVAL;
0337
0338 result = sensor_set_auxtrip(attr->handle, idx,
0339 celsius_to_deci_kelvin(value));
0340 return result ? result : count;
0341 }
0342
0343 static ssize_t aux0_store(struct device *dev,
0344 struct device_attribute *dev_attr,
0345 const char *buf, size_t count)
0346 {
0347 return aux_store(dev, dev_attr, buf, count, 0);
0348 }
0349
0350 static ssize_t aux1_store(struct device *dev,
0351 struct device_attribute *dev_attr,
0352 const char *buf, size_t count)
0353 {
0354 return aux_store(dev, dev_attr, buf, count, 1);
0355 }
0356
0357
0358 #define BIOS_ENABLED "\\_TZ.GSTS"
0359 static ssize_t bios_enabled_show(struct device *dev,
0360 struct device_attribute *attr, char *buf)
0361 {
0362 acpi_status status;
0363 unsigned long long bios_enabled;
0364
0365 status = acpi_evaluate_integer(NULL, BIOS_ENABLED, NULL, &bios_enabled);
0366 if (ACPI_FAILURE(status))
0367 return -ENODEV;
0368
0369 return sprintf(buf, "%s\n", bios_enabled ? "enabled" : "disabled");
0370 }
0371
0372 static int intel_menlow_add_one_attribute(char *name, umode_t mode, void *show,
0373 void *store, struct device *dev,
0374 acpi_handle handle)
0375 {
0376 struct intel_menlow_attribute *attr;
0377 int result;
0378
0379 attr = kzalloc(sizeof(struct intel_menlow_attribute), GFP_KERNEL);
0380 if (!attr)
0381 return -ENOMEM;
0382
0383 sysfs_attr_init(&attr->attr.attr);
0384 attr->attr.attr.name = name;
0385 attr->attr.attr.mode = mode;
0386 attr->attr.show = show;
0387 attr->attr.store = store;
0388 attr->device = dev;
0389 attr->handle = handle;
0390
0391 result = device_create_file(dev, &attr->attr);
0392 if (result) {
0393 kfree(attr);
0394 return result;
0395 }
0396
0397 mutex_lock(&intel_menlow_attr_lock);
0398 list_add_tail(&attr->node, &intel_menlow_attr_list);
0399 mutex_unlock(&intel_menlow_attr_lock);
0400
0401 return 0;
0402 }
0403
0404 static acpi_status intel_menlow_register_sensor(acpi_handle handle, u32 lvl,
0405 void *context, void **rv)
0406 {
0407 acpi_status status;
0408 acpi_handle dummy;
0409 struct thermal_zone_device *thermal;
0410 int result;
0411
0412 result = acpi_bus_get_private_data(handle, (void **)&thermal);
0413 if (result)
0414 return 0;
0415
0416
0417 status = acpi_get_handle(handle, GET_AUX0, &dummy);
0418 if (ACPI_FAILURE(status))
0419 return (status == AE_NOT_FOUND) ? AE_OK : status;
0420
0421 status = acpi_get_handle(handle, SET_AUX0, &dummy);
0422 if (ACPI_FAILURE(status))
0423 return (status == AE_NOT_FOUND) ? AE_OK : status;
0424
0425 result = intel_menlow_add_one_attribute("aux0", 0644,
0426 aux0_show, aux0_store,
0427 &thermal->device, handle);
0428 if (result)
0429 return AE_ERROR;
0430
0431 status = acpi_get_handle(handle, GET_AUX1, &dummy);
0432 if (ACPI_FAILURE(status))
0433 goto aux1_not_found;
0434
0435 status = acpi_get_handle(handle, SET_AUX1, &dummy);
0436 if (ACPI_FAILURE(status))
0437 goto aux1_not_found;
0438
0439 result = intel_menlow_add_one_attribute("aux1", 0644,
0440 aux1_show, aux1_store,
0441 &thermal->device, handle);
0442 if (result) {
0443 intel_menlow_unregister_sensor();
0444 return AE_ERROR;
0445 }
0446
0447
0448
0449
0450
0451
0452 result = intel_menlow_add_one_attribute("bios_enabled", 0444,
0453 bios_enabled_show, NULL,
0454 &thermal->device, handle);
0455 if (result) {
0456 intel_menlow_unregister_sensor();
0457 return AE_ERROR;
0458 }
0459
0460 return AE_OK;
0461
0462 aux1_not_found:
0463 if (status == AE_NOT_FOUND)
0464 return AE_OK;
0465
0466 intel_menlow_unregister_sensor();
0467 return status;
0468 }
0469
0470 static void intel_menlow_unregister_sensor(void)
0471 {
0472 struct intel_menlow_attribute *pos, *next;
0473
0474 mutex_lock(&intel_menlow_attr_lock);
0475 list_for_each_entry_safe(pos, next, &intel_menlow_attr_list, node) {
0476 list_del(&pos->node);
0477 device_remove_file(pos->device, &pos->attr);
0478 kfree(pos);
0479 }
0480 mutex_unlock(&intel_menlow_attr_lock);
0481
0482 return;
0483 }
0484
0485 static int __init intel_menlow_module_init(void)
0486 {
0487 int result = -ENODEV;
0488 acpi_status status;
0489 unsigned long long enable;
0490
0491 if (acpi_disabled)
0492 return result;
0493
0494
0495 status = acpi_evaluate_integer(NULL, BIOS_ENABLED, NULL, &enable);
0496 if (ACPI_FAILURE(status) || !enable)
0497 return -ENODEV;
0498
0499
0500 result = acpi_bus_register_driver(&intel_menlow_memory_driver);
0501 if (result)
0502 return result;
0503
0504
0505 status = acpi_walk_namespace(ACPI_TYPE_THERMAL, ACPI_ROOT_OBJECT,
0506 ACPI_UINT32_MAX,
0507 intel_menlow_register_sensor, NULL, NULL, NULL);
0508 if (ACPI_FAILURE(status)) {
0509 acpi_bus_unregister_driver(&intel_menlow_memory_driver);
0510 return -ENODEV;
0511 }
0512
0513 return 0;
0514 }
0515
0516 static void __exit intel_menlow_module_exit(void)
0517 {
0518 acpi_bus_unregister_driver(&intel_menlow_memory_driver);
0519 intel_menlow_unregister_sensor();
0520 }
0521
0522 module_init(intel_menlow_module_init);
0523 module_exit(intel_menlow_module_exit);