aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/ibmaem.c
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /drivers/hwmon/ibmaem.c
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'drivers/hwmon/ibmaem.c')
-rw-r--r--drivers/hwmon/ibmaem.c112
1 files changed, 67 insertions, 45 deletions
diff --git a/drivers/hwmon/ibmaem.c b/drivers/hwmon/ibmaem.c
index a14f634248e..c316294c48b 100644
--- a/drivers/hwmon/ibmaem.c
+++ b/drivers/hwmon/ibmaem.c
@@ -36,7 +36,6 @@
36#include <linux/platform_device.h> 36#include <linux/platform_device.h>
37#include <linux/math64.h> 37#include <linux/math64.h>
38#include <linux/time.h> 38#include <linux/time.h>
39#include <linux/err.h>
40 39
41#define REFRESH_INTERVAL (HZ) 40#define REFRESH_INTERVAL (HZ)
42#define IPMI_TIMEOUT (30 * HZ) 41#define IPMI_TIMEOUT (30 * HZ)
@@ -89,7 +88,8 @@
89#define AEM_MIN_POWER_INTERVAL 200 88#define AEM_MIN_POWER_INTERVAL 200
90#define UJ_PER_MJ 1000L 89#define UJ_PER_MJ 1000L
91 90
92static DEFINE_IDA(aem_ida); 91static DEFINE_IDR(aem_idr);
92static DEFINE_SPINLOCK(aem_idr_lock);
93 93
94static struct platform_driver aem_driver = { 94static struct platform_driver aem_driver = {
95 .driver = { 95 .driver = {
@@ -148,9 +148,8 @@ struct aem_data {
148 int id; 148 int id;
149 struct aem_ipmi_data ipmi; 149 struct aem_ipmi_data ipmi;
150 150
151 /* Function and buffer to update sensors */ 151 /* Function to update sensors */
152 void (*update)(struct aem_data *data); 152 void (*update)(struct aem_data *data);
153 struct aem_read_sensor_resp *rs_resp;
154 153
155 /* 154 /*
156 * AEM 1.x sensors: 155 * AEM 1.x sensors:
@@ -247,6 +246,8 @@ static void aem_bmc_gone(int iface);
247static void aem_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data); 246static void aem_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data);
248 247
249static void aem_remove_sensors(struct aem_data *data); 248static void aem_remove_sensors(struct aem_data *data);
249static int aem_init_aem1(struct aem_ipmi_data *probe);
250static int aem_init_aem2(struct aem_ipmi_data *probe);
250static int aem1_find_sensors(struct aem_data *data); 251static int aem1_find_sensors(struct aem_data *data);
251static int aem2_find_sensors(struct aem_data *data); 252static int aem2_find_sensors(struct aem_data *data);
252static void update_aem1_sensors(struct aem_data *data); 253static void update_aem1_sensors(struct aem_data *data);
@@ -355,16 +356,47 @@ static void aem_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data)
355 complete(&data->read_complete); 356 complete(&data->read_complete);
356} 357}
357 358
359/* ID functions */
360
361/* Obtain an id */
362static int aem_idr_get(int *id)
363{
364 int i, err;
365
366again:
367 if (unlikely(!idr_pre_get(&aem_idr, GFP_KERNEL)))
368 return -ENOMEM;
369
370 spin_lock(&aem_idr_lock);
371 err = idr_get_new(&aem_idr, NULL, &i);
372 spin_unlock(&aem_idr_lock);
373
374 if (unlikely(err == -EAGAIN))
375 goto again;
376 else if (unlikely(err))
377 return err;
378
379 *id = i & MAX_ID_MASK;
380 return 0;
381}
382
383/* Release an object ID */
384static void aem_idr_put(int id)
385{
386 spin_lock(&aem_idr_lock);
387 idr_remove(&aem_idr, id);
388 spin_unlock(&aem_idr_lock);
389}
390
358/* Sensor support functions */ 391/* Sensor support functions */
359 392
360/* Read a sensor value; must be called with data->lock held */ 393/* Read a sensor value */
361static int aem_read_sensor(struct aem_data *data, u8 elt, u8 reg, 394static int aem_read_sensor(struct aem_data *data, u8 elt, u8 reg,
362 void *buf, size_t size) 395 void *buf, size_t size)
363{ 396{
364 int rs_size, res; 397 int rs_size, res;
365 struct aem_read_sensor_req rs_req; 398 struct aem_read_sensor_req rs_req;
366 /* Use preallocated rx buffer */ 399 struct aem_read_sensor_resp *rs_resp;
367 struct aem_read_sensor_resp *rs_resp = data->rs_resp;
368 struct aem_ipmi_data *ipmi = &data->ipmi; 400 struct aem_ipmi_data *ipmi = &data->ipmi;
369 401
370 /* AEM registers are 1, 2, 4 or 8 bytes */ 402 /* AEM registers are 1, 2, 4 or 8 bytes */
@@ -390,6 +422,10 @@ static int aem_read_sensor(struct aem_data *data, u8 elt, u8 reg,
390 ipmi->tx_message.data_len = sizeof(rs_req); 422 ipmi->tx_message.data_len = sizeof(rs_req);
391 423
392 rs_size = sizeof(*rs_resp) + size; 424 rs_size = sizeof(*rs_resp) + size;
425 rs_resp = kzalloc(rs_size, GFP_KERNEL);
426 if (!rs_resp)
427 return -ENOMEM;
428
393 ipmi->rx_msg_data = rs_resp; 429 ipmi->rx_msg_data = rs_resp;
394 ipmi->rx_msg_len = rs_size; 430 ipmi->rx_msg_len = rs_size;
395 431
@@ -432,6 +468,7 @@ static int aem_read_sensor(struct aem_data *data, u8 elt, u8 reg,
432 res = 0; 468 res = 0;
433 469
434out: 470out:
471 kfree(rs_resp);
435 return res; 472 return res;
436} 473}
437 474
@@ -489,12 +526,11 @@ static void aem_delete(struct aem_data *data)
489{ 526{
490 list_del(&data->list); 527 list_del(&data->list);
491 aem_remove_sensors(data); 528 aem_remove_sensors(data);
492 kfree(data->rs_resp);
493 hwmon_device_unregister(data->hwmon_dev); 529 hwmon_device_unregister(data->hwmon_dev);
494 ipmi_destroy_user(data->ipmi.user); 530 ipmi_destroy_user(data->ipmi.user);
495 platform_set_drvdata(data->pdev, NULL); 531 platform_set_drvdata(data->pdev, NULL);
496 platform_device_unregister(data->pdev); 532 platform_device_unregister(data->pdev);
497 ida_simple_remove(&aem_ida, data->id); 533 aem_idr_put(data->id);
498 kfree(data); 534 kfree(data);
499} 535}
500 536
@@ -551,8 +587,7 @@ static int aem_init_aem1_inst(struct aem_ipmi_data *probe, u8 module_handle)
551 data->power_period[i] = AEM_DEFAULT_POWER_INTERVAL; 587 data->power_period[i] = AEM_DEFAULT_POWER_INTERVAL;
552 588
553 /* Create sub-device for this fw instance */ 589 /* Create sub-device for this fw instance */
554 data->id = ida_simple_get(&aem_ida, 0, 0, GFP_KERNEL); 590 if (aem_idr_get(&data->id))
555 if (data->id < 0)
556 goto id_err; 591 goto id_err;
557 592
558 data->pdev = platform_device_alloc(DRVNAME, data->id); 593 data->pdev = platform_device_alloc(DRVNAME, data->id);
@@ -567,31 +602,24 @@ static int aem_init_aem1_inst(struct aem_ipmi_data *probe, u8 module_handle)
567 platform_set_drvdata(data->pdev, data); 602 platform_set_drvdata(data->pdev, data);
568 603
569 /* Set up IPMI interface */ 604 /* Set up IPMI interface */
570 res = aem_init_ipmi_data(&data->ipmi, probe->interface, 605 if (aem_init_ipmi_data(&data->ipmi, probe->interface,
571 probe->bmc_device); 606 probe->bmc_device))
572 if (res)
573 goto ipmi_err; 607 goto ipmi_err;
574 608
575 /* Register with hwmon */ 609 /* Register with hwmon */
576 data->hwmon_dev = hwmon_device_register(&data->pdev->dev); 610 data->hwmon_dev = hwmon_device_register(&data->pdev->dev);
611
577 if (IS_ERR(data->hwmon_dev)) { 612 if (IS_ERR(data->hwmon_dev)) {
578 dev_err(&data->pdev->dev, "Unable to register hwmon " 613 dev_err(&data->pdev->dev, "Unable to register hwmon "
579 "device for IPMI interface %d\n", 614 "device for IPMI interface %d\n",
580 probe->interface); 615 probe->interface);
581 res = PTR_ERR(data->hwmon_dev);
582 goto hwmon_reg_err; 616 goto hwmon_reg_err;
583 } 617 }
584 618
585 data->update = update_aem1_sensors; 619 data->update = update_aem1_sensors;
586 data->rs_resp = kzalloc(sizeof(*(data->rs_resp)) + 8, GFP_KERNEL);
587 if (!data->rs_resp) {
588 res = -ENOMEM;
589 goto alloc_resp_err;
590 }
591 620
592 /* Find sensors */ 621 /* Find sensors */
593 res = aem1_find_sensors(data); 622 if (aem1_find_sensors(data))
594 if (res)
595 goto sensor_err; 623 goto sensor_err;
596 624
597 /* Add to our list of AEM devices */ 625 /* Add to our list of AEM devices */
@@ -603,8 +631,6 @@ static int aem_init_aem1_inst(struct aem_ipmi_data *probe, u8 module_handle)
603 return 0; 631 return 0;
604 632
605sensor_err: 633sensor_err:
606 kfree(data->rs_resp);
607alloc_resp_err:
608 hwmon_device_unregister(data->hwmon_dev); 634 hwmon_device_unregister(data->hwmon_dev);
609hwmon_reg_err: 635hwmon_reg_err:
610 ipmi_destroy_user(data->ipmi.user); 636 ipmi_destroy_user(data->ipmi.user);
@@ -612,7 +638,7 @@ ipmi_err:
612 platform_set_drvdata(data->pdev, NULL); 638 platform_set_drvdata(data->pdev, NULL);
613 platform_device_unregister(data->pdev); 639 platform_device_unregister(data->pdev);
614dev_err: 640dev_err:
615 ida_simple_remove(&aem_ida, data->id); 641 aem_idr_put(data->id);
616id_err: 642id_err:
617 kfree(data); 643 kfree(data);
618 644
@@ -620,7 +646,7 @@ id_err:
620} 646}
621 647
622/* Find and initialize all AEM1 instances */ 648/* Find and initialize all AEM1 instances */
623static void aem_init_aem1(struct aem_ipmi_data *probe) 649static int aem_init_aem1(struct aem_ipmi_data *probe)
624{ 650{
625 int num, i, err; 651 int num, i, err;
626 652
@@ -631,8 +657,11 @@ static void aem_init_aem1(struct aem_ipmi_data *probe)
631 dev_err(probe->bmc_device, 657 dev_err(probe->bmc_device,
632 "Error %d initializing AEM1 0x%X\n", 658 "Error %d initializing AEM1 0x%X\n",
633 err, i); 659 err, i);
660 return err;
634 } 661 }
635 } 662 }
663
664 return 0;
636} 665}
637 666
638/* Probe functions for AEM2 devices */ 667/* Probe functions for AEM2 devices */
@@ -691,8 +720,7 @@ static int aem_init_aem2_inst(struct aem_ipmi_data *probe,
691 data->power_period[i] = AEM_DEFAULT_POWER_INTERVAL; 720 data->power_period[i] = AEM_DEFAULT_POWER_INTERVAL;
692 721
693 /* Create sub-device for this fw instance */ 722 /* Create sub-device for this fw instance */
694 data->id = ida_simple_get(&aem_ida, 0, 0, GFP_KERNEL); 723 if (aem_idr_get(&data->id))
695 if (data->id < 0)
696 goto id_err; 724 goto id_err;
697 725
698 data->pdev = platform_device_alloc(DRVNAME, data->id); 726 data->pdev = platform_device_alloc(DRVNAME, data->id);
@@ -707,31 +735,24 @@ static int aem_init_aem2_inst(struct aem_ipmi_data *probe,
707 platform_set_drvdata(data->pdev, data); 735 platform_set_drvdata(data->pdev, data);
708 736
709 /* Set up IPMI interface */ 737 /* Set up IPMI interface */
710 res = aem_init_ipmi_data(&data->ipmi, probe->interface, 738 if (aem_init_ipmi_data(&data->ipmi, probe->interface,
711 probe->bmc_device); 739 probe->bmc_device))
712 if (res)
713 goto ipmi_err; 740 goto ipmi_err;
714 741
715 /* Register with hwmon */ 742 /* Register with hwmon */
716 data->hwmon_dev = hwmon_device_register(&data->pdev->dev); 743 data->hwmon_dev = hwmon_device_register(&data->pdev->dev);
744
717 if (IS_ERR(data->hwmon_dev)) { 745 if (IS_ERR(data->hwmon_dev)) {
718 dev_err(&data->pdev->dev, "Unable to register hwmon " 746 dev_err(&data->pdev->dev, "Unable to register hwmon "
719 "device for IPMI interface %d\n", 747 "device for IPMI interface %d\n",
720 probe->interface); 748 probe->interface);
721 res = PTR_ERR(data->hwmon_dev);
722 goto hwmon_reg_err; 749 goto hwmon_reg_err;
723 } 750 }
724 751
725 data->update = update_aem2_sensors; 752 data->update = update_aem2_sensors;
726 data->rs_resp = kzalloc(sizeof(*(data->rs_resp)) + 8, GFP_KERNEL);
727 if (!data->rs_resp) {
728 res = -ENOMEM;
729 goto alloc_resp_err;
730 }
731 753
732 /* Find sensors */ 754 /* Find sensors */
733 res = aem2_find_sensors(data); 755 if (aem2_find_sensors(data))
734 if (res)
735 goto sensor_err; 756 goto sensor_err;
736 757
737 /* Add to our list of AEM devices */ 758 /* Add to our list of AEM devices */
@@ -743,8 +764,6 @@ static int aem_init_aem2_inst(struct aem_ipmi_data *probe,
743 return 0; 764 return 0;
744 765
745sensor_err: 766sensor_err:
746 kfree(data->rs_resp);
747alloc_resp_err:
748 hwmon_device_unregister(data->hwmon_dev); 767 hwmon_device_unregister(data->hwmon_dev);
749hwmon_reg_err: 768hwmon_reg_err:
750 ipmi_destroy_user(data->ipmi.user); 769 ipmi_destroy_user(data->ipmi.user);
@@ -752,7 +771,7 @@ ipmi_err:
752 platform_set_drvdata(data->pdev, NULL); 771 platform_set_drvdata(data->pdev, NULL);
753 platform_device_unregister(data->pdev); 772 platform_device_unregister(data->pdev);
754dev_err: 773dev_err:
755 ida_simple_remove(&aem_ida, data->id); 774 aem_idr_put(data->id);
756id_err: 775id_err:
757 kfree(data); 776 kfree(data);
758 777
@@ -760,7 +779,7 @@ id_err:
760} 779}
761 780
762/* Find and initialize all AEM2 instances */ 781/* Find and initialize all AEM2 instances */
763static void aem_init_aem2(struct aem_ipmi_data *probe) 782static int aem_init_aem2(struct aem_ipmi_data *probe)
764{ 783{
765 struct aem_find_instance_resp fi_resp; 784 struct aem_find_instance_resp fi_resp;
766 int err; 785 int err;
@@ -779,9 +798,12 @@ static void aem_init_aem2(struct aem_ipmi_data *probe)
779 dev_err(probe->bmc_device, 798 dev_err(probe->bmc_device,
780 "Error %d initializing AEM2 0x%X\n", 799 "Error %d initializing AEM2 0x%X\n",
781 err, fi_resp.module_handle); 800 err, fi_resp.module_handle);
801 return err;
782 } 802 }
783 i++; 803 i++;
784 } 804 }
805
806 return 0;
785} 807}
786 808
787/* Probe a BMC for AEM firmware instances */ 809/* Probe a BMC for AEM firmware instances */
@@ -905,7 +927,7 @@ static ssize_t aem_set_power_period(struct device *dev,
905 unsigned long temp; 927 unsigned long temp;
906 int res; 928 int res;
907 929
908 res = kstrtoul(buf, 10, &temp); 930 res = strict_strtoul(buf, 10, &temp);
909 if (res) 931 if (res)
910 return res; 932 return res;
911 933
@@ -1046,7 +1068,7 @@ static struct aem_ro_sensor_template aem2_ro_sensors[] = {
1046{"power6_average", aem2_show_pcap_value, POWER_CAP_MIN_WARNING}, 1068{"power6_average", aem2_show_pcap_value, POWER_CAP_MIN_WARNING},
1047{"power7_average", aem2_show_pcap_value, POWER_CAP_MIN}, 1069{"power7_average", aem2_show_pcap_value, POWER_CAP_MIN},
1048 1070
1049{"power3_average", aem2_show_pcap_value, POWER_AUX}, 1071{"power3_average", aem2_show_pcap_value, POWER_AUX},
1050{"power_cap", aem2_show_pcap_value, POWER_CAP}, 1072{"power_cap", aem2_show_pcap_value, POWER_CAP},
1051{NULL, NULL, 0}, 1073{NULL, NULL, 0},
1052}; 1074};