diff options
-rw-r--r-- | drivers/thermal/intel_soc_dts_thermal.c | 46 |
1 files changed, 30 insertions, 16 deletions
diff --git a/drivers/thermal/intel_soc_dts_thermal.c b/drivers/thermal/intel_soc_dts_thermal.c index 5580f5b24eb9..9013505e43b7 100644 --- a/drivers/thermal/intel_soc_dts_thermal.c +++ b/drivers/thermal/intel_soc_dts_thermal.c | |||
@@ -309,10 +309,13 @@ static int soc_dts_enable(int id) | |||
309 | return ret; | 309 | return ret; |
310 | } | 310 | } |
311 | 311 | ||
312 | static struct soc_sensor_entry *alloc_soc_dts(int id, u32 tj_max) | 312 | static struct soc_sensor_entry *alloc_soc_dts(int id, u32 tj_max, |
313 | bool notification_support) | ||
313 | { | 314 | { |
314 | struct soc_sensor_entry *aux_entry; | 315 | struct soc_sensor_entry *aux_entry; |
315 | char name[10]; | 316 | char name[10]; |
317 | int trip_count = 0; | ||
318 | int trip_mask = 0; | ||
316 | int err; | 319 | int err; |
317 | 320 | ||
318 | aux_entry = kzalloc(sizeof(*aux_entry), GFP_KERNEL); | 321 | aux_entry = kzalloc(sizeof(*aux_entry), GFP_KERNEL); |
@@ -332,11 +335,16 @@ static struct soc_sensor_entry *alloc_soc_dts(int id, u32 tj_max) | |||
332 | aux_entry->tj_max = tj_max; | 335 | aux_entry->tj_max = tj_max; |
333 | aux_entry->temp_mask = 0x00FF << (id * 8); | 336 | aux_entry->temp_mask = 0x00FF << (id * 8); |
334 | aux_entry->temp_shift = id * 8; | 337 | aux_entry->temp_shift = id * 8; |
338 | if (notification_support) { | ||
339 | trip_count = SOC_MAX_DTS_TRIPS; | ||
340 | trip_mask = 0x02; | ||
341 | } | ||
335 | snprintf(name, sizeof(name), "soc_dts%d", id); | 342 | snprintf(name, sizeof(name), "soc_dts%d", id); |
336 | aux_entry->tzone = thermal_zone_device_register(name, | 343 | aux_entry->tzone = thermal_zone_device_register(name, |
337 | SOC_MAX_DTS_TRIPS, | 344 | trip_count, |
338 | 0x02, | 345 | trip_mask, |
339 | aux_entry, &tzone_ops, NULL, 0, 0); | 346 | aux_entry, &tzone_ops, |
347 | NULL, 0, 0); | ||
340 | if (IS_ERR(aux_entry->tzone)) { | 348 | if (IS_ERR(aux_entry->tzone)) { |
341 | err = PTR_ERR(aux_entry->tzone); | 349 | err = PTR_ERR(aux_entry->tzone); |
342 | goto err_ret; | 350 | goto err_ret; |
@@ -402,6 +410,7 @@ static irqreturn_t soc_irq_thread_fn(int irq, void *dev_data) | |||
402 | 410 | ||
403 | static const struct x86_cpu_id soc_thermal_ids[] = { | 411 | static const struct x86_cpu_id soc_thermal_ids[] = { |
404 | { X86_VENDOR_INTEL, X86_FAMILY_ANY, 0x37, 0, BYT_SOC_DTS_APIC_IRQ}, | 412 | { X86_VENDOR_INTEL, X86_FAMILY_ANY, 0x37, 0, BYT_SOC_DTS_APIC_IRQ}, |
413 | { X86_VENDOR_INTEL, X86_FAMILY_ANY, 0x4c, 0, 0}, | ||
405 | {} | 414 | {} |
406 | }; | 415 | }; |
407 | MODULE_DEVICE_TABLE(x86cpu, soc_thermal_ids); | 416 | MODULE_DEVICE_TABLE(x86cpu, soc_thermal_ids); |
@@ -420,8 +429,11 @@ static int __init intel_soc_thermal_init(void) | |||
420 | if (get_tj_max(&tj_max)) | 429 | if (get_tj_max(&tj_max)) |
421 | return -EINVAL; | 430 | return -EINVAL; |
422 | 431 | ||
432 | soc_dts_thres_irq = (int)match_cpu->driver_data; | ||
433 | |||
423 | for (i = 0; i < SOC_MAX_DTS_SENSORS; ++i) { | 434 | for (i = 0; i < SOC_MAX_DTS_SENSORS; ++i) { |
424 | soc_dts[i] = alloc_soc_dts(i, tj_max); | 435 | soc_dts[i] = alloc_soc_dts(i, tj_max, |
436 | soc_dts_thres_irq ? true : false); | ||
425 | if (IS_ERR(soc_dts[i])) { | 437 | if (IS_ERR(soc_dts[i])) { |
426 | err = PTR_ERR(soc_dts[i]); | 438 | err = PTR_ERR(soc_dts[i]); |
427 | goto err_free; | 439 | goto err_free; |
@@ -430,15 +442,15 @@ static int __init intel_soc_thermal_init(void) | |||
430 | 442 | ||
431 | spin_lock_init(&intr_notify_lock); | 443 | spin_lock_init(&intr_notify_lock); |
432 | 444 | ||
433 | soc_dts_thres_irq = (int)match_cpu->driver_data; | 445 | if (soc_dts_thres_irq) { |
434 | 446 | err = request_threaded_irq(soc_dts_thres_irq, NULL, | |
435 | err = request_threaded_irq(soc_dts_thres_irq, NULL, | 447 | soc_irq_thread_fn, |
436 | soc_irq_thread_fn, | 448 | IRQF_TRIGGER_RISING | IRQF_ONESHOT, |
437 | IRQF_TRIGGER_RISING | IRQF_ONESHOT, | 449 | "soc_dts", soc_dts); |
438 | "soc_dts", soc_dts); | 450 | if (err) { |
439 | if (err) { | 451 | pr_err("request_threaded_irq ret %d\n", err); |
440 | pr_err("request_threaded_irq ret %d\n", err); | 452 | goto err_free; |
441 | goto err_free; | 453 | } |
442 | } | 454 | } |
443 | 455 | ||
444 | for (i = 0; i < SOC_MAX_DTS_SENSORS; ++i) { | 456 | for (i = 0; i < SOC_MAX_DTS_SENSORS; ++i) { |
@@ -451,7 +463,8 @@ static int __init intel_soc_thermal_init(void) | |||
451 | 463 | ||
452 | err_trip_temp: | 464 | err_trip_temp: |
453 | i = SOC_MAX_DTS_SENSORS; | 465 | i = SOC_MAX_DTS_SENSORS; |
454 | free_irq(soc_dts_thres_irq, soc_dts); | 466 | if (soc_dts_thres_irq) |
467 | free_irq(soc_dts_thres_irq, soc_dts); | ||
455 | err_free: | 468 | err_free: |
456 | while (--i >= 0) | 469 | while (--i >= 0) |
457 | free_soc_dts(soc_dts[i]); | 470 | free_soc_dts(soc_dts[i]); |
@@ -466,7 +479,8 @@ static void __exit intel_soc_thermal_exit(void) | |||
466 | for (i = 0; i < SOC_MAX_DTS_SENSORS; ++i) | 479 | for (i = 0; i < SOC_MAX_DTS_SENSORS; ++i) |
467 | update_trip_temp(soc_dts[i], 0, 0); | 480 | update_trip_temp(soc_dts[i], 0, 0); |
468 | 481 | ||
469 | free_irq(soc_dts_thres_irq, soc_dts); | 482 | if (soc_dts_thres_irq) |
483 | free_irq(soc_dts_thres_irq, soc_dts); | ||
470 | 484 | ||
471 | for (i = 0; i < SOC_MAX_DTS_SENSORS; ++i) | 485 | for (i = 0; i < SOC_MAX_DTS_SENSORS; ++i) |
472 | free_soc_dts(soc_dts[i]); | 486 | free_soc_dts(soc_dts[i]); |