aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/ipmi
diff options
context:
space:
mode:
authorThomas Bogendoerfer <tsbogend@alpha.franken.de>2013-09-05 07:36:36 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-09-05 11:34:32 -0400
commitfdbeb7de700a3c8fc85d7e595a6bf1c92a27c0a1 (patch)
tree6d57dd6f1f7df3ddf08dc816efc2bb479c3c569c /drivers/char/ipmi
parenta798e2d2d7374ba1e35e2244506f56c8363902cf (diff)
BMC support for PARISC machines
The last line of PARISC machines (C8000, RP34x0, etc.) have a BMC for controlling temperature, fan speed and other stuff. The BMC is connected via a special bus and listed in the firmware device tree. This change adds support for these BMCs to the IPMI driver. Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de> Signed-off-by: Corey Minyard <cminyard@mvista.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/char/ipmi')
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c75
1 files changed, 75 insertions, 0 deletions
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index 810372c0a22f..15e4a6031934 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -71,6 +71,11 @@
71#include <linux/of_address.h> 71#include <linux/of_address.h>
72#include <linux/of_irq.h> 72#include <linux/of_irq.h>
73 73
74#ifdef CONFIG_PARISC
75#include <asm/hardware.h> /* for register_parisc_driver() stuff */
76#include <asm/parisc-device.h>
77#endif
78
74#define PFX "ipmi_si: " 79#define PFX "ipmi_si: "
75 80
76/* Measure times between events in the driver. */ 81/* Measure times between events in the driver. */
@@ -298,6 +303,9 @@ static int pci_registered;
298#ifdef CONFIG_ACPI 303#ifdef CONFIG_ACPI
299static int pnp_registered; 304static int pnp_registered;
300#endif 305#endif
306#ifdef CONFIG_PARISC
307static int parisc_registered;
308#endif
301 309
302static unsigned int kipmid_max_busy_us[SI_MAX_PARMS]; 310static unsigned int kipmid_max_busy_us[SI_MAX_PARMS];
303static int num_max_busy_us; 311static int num_max_busy_us;
@@ -2699,6 +2707,62 @@ static struct platform_driver ipmi_driver = {
2699 .remove = ipmi_remove, 2707 .remove = ipmi_remove,
2700}; 2708};
2701 2709
2710#ifdef CONFIG_PARISC
2711static int ipmi_parisc_probe(struct parisc_device *dev)
2712{
2713 struct smi_info *info;
2714
2715 info = smi_info_alloc();
2716
2717 if (!info) {
2718 dev_err(&dev->dev,
2719 "could not allocate memory for PARISC probe\n");
2720 return -ENOMEM;
2721 }
2722
2723 info->si_type = SI_KCS;
2724 info->addr_source = SI_DEVICETREE;
2725 info->io_setup = mem_setup;
2726 info->io.addr_type = IPMI_MEM_ADDR_SPACE;
2727 info->io.addr_data = dev->hpa.start;
2728 info->io.regsize = 1;
2729 info->io.regspacing = 1;
2730 info->io.regshift = 0;
2731 info->irq = 0; /* no interrupt */
2732 info->irq_setup = NULL;
2733 info->dev = &dev->dev;
2734
2735 dev_dbg(&dev->dev, "addr 0x%lx\n", info->io.addr_data);
2736
2737 dev_set_drvdata(&dev->dev, info);
2738
2739 if (add_smi(info)) {
2740 kfree(info);
2741 return -EBUSY;
2742 }
2743
2744 return 0;
2745}
2746
2747static int ipmi_parisc_remove(struct parisc_device *dev)
2748{
2749 cleanup_one_si(dev_get_drvdata(&dev->dev));
2750 return 0;
2751}
2752
2753static struct parisc_device_id ipmi_parisc_tbl[] = {
2754 { HPHW_MC, HVERSION_REV_ANY_ID, 0x004, 0xC0 },
2755 { 0, }
2756};
2757
2758static struct parisc_driver ipmi_parisc_driver = {
2759 .name = "ipmi",
2760 .id_table = ipmi_parisc_tbl,
2761 .probe = ipmi_parisc_probe,
2762 .remove = ipmi_parisc_remove,
2763};
2764#endif /* CONFIG_PARISC */
2765
2702static int wait_for_msg_done(struct smi_info *smi_info) 2766static int wait_for_msg_done(struct smi_info *smi_info)
2703{ 2767{
2704 enum si_sm_result smi_result; 2768 enum si_sm_result smi_result;
@@ -3464,6 +3528,13 @@ static int init_ipmi_si(void)
3464 spmi_find_bmc(); 3528 spmi_find_bmc();
3465#endif 3529#endif
3466 3530
3531#ifdef CONFIG_PARISC
3532 register_parisc_driver(&ipmi_parisc_driver);
3533 parisc_registered = 1;
3534 /* poking PC IO addresses will crash machine, don't do it */
3535 si_trydefaults = 0;
3536#endif
3537
3467 /* We prefer devices with interrupts, but in the case of a machine 3538 /* We prefer devices with interrupts, but in the case of a machine
3468 with multiple BMCs we assume that there will be several instances 3539 with multiple BMCs we assume that there will be several instances
3469 of a given type so if we succeed in registering a type then also 3540 of a given type so if we succeed in registering a type then also
@@ -3610,6 +3681,10 @@ static void cleanup_ipmi_si(void)
3610 if (pnp_registered) 3681 if (pnp_registered)
3611 pnp_unregister_driver(&ipmi_pnp_driver); 3682 pnp_unregister_driver(&ipmi_pnp_driver);
3612#endif 3683#endif
3684#ifdef CONFIG_PARISC
3685 if (parisc_registered)
3686 unregister_parisc_driver(&ipmi_parisc_driver);
3687#endif
3613 3688
3614 platform_driver_unregister(&ipmi_driver); 3689 platform_driver_unregister(&ipmi_driver);
3615 3690