diff options
author | Len Brown <len.brown@intel.com> | 2009-12-16 02:20:58 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2009-12-16 02:20:58 -0500 |
commit | 1a544d28dd2fd7c90bb23118ab0ca09b1304a50c (patch) | |
tree | 891bedc62116b0e68c277d14dd749b94cc4d4f0b /drivers/char/ipmi | |
parent | 689a8ab32fa0ba11c4005b3733e59fb7094c2870 (diff) | |
parent | 9e368fa011d4e0aa050db348d69514900520e40b (diff) |
Merge branch 'ipmi' into release
Diffstat (limited to 'drivers/char/ipmi')
-rw-r--r-- | drivers/char/ipmi/ipmi_si_intf.c | 118 |
1 files changed, 109 insertions, 9 deletions
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index d2e698096ace..679cd08b80b4 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
@@ -64,6 +64,7 @@ | |||
64 | #include <linux/dmi.h> | 64 | #include <linux/dmi.h> |
65 | #include <linux/string.h> | 65 | #include <linux/string.h> |
66 | #include <linux/ctype.h> | 66 | #include <linux/ctype.h> |
67 | #include <linux/pnp.h> | ||
67 | 68 | ||
68 | #ifdef CONFIG_PPC_OF | 69 | #ifdef CONFIG_PPC_OF |
69 | #include <linux/of_device.h> | 70 | #include <linux/of_device.h> |
@@ -1919,7 +1920,7 @@ struct SPMITable { | |||
1919 | s8 spmi_id[1]; /* A '\0' terminated array starts here. */ | 1920 | s8 spmi_id[1]; /* A '\0' terminated array starts here. */ |
1920 | }; | 1921 | }; |
1921 | 1922 | ||
1922 | static __devinit int try_init_acpi(struct SPMITable *spmi) | 1923 | static __devinit int try_init_spmi(struct SPMITable *spmi) |
1923 | { | 1924 | { |
1924 | struct smi_info *info; | 1925 | struct smi_info *info; |
1925 | u8 addr_space; | 1926 | u8 addr_space; |
@@ -1940,7 +1941,7 @@ static __devinit int try_init_acpi(struct SPMITable *spmi) | |||
1940 | return -ENOMEM; | 1941 | return -ENOMEM; |
1941 | } | 1942 | } |
1942 | 1943 | ||
1943 | info->addr_source = "ACPI"; | 1944 | info->addr_source = "SPMI"; |
1944 | 1945 | ||
1945 | /* Figure out the interface type. */ | 1946 | /* Figure out the interface type. */ |
1946 | switch (spmi->InterfaceType) { | 1947 | switch (spmi->InterfaceType) { |
@@ -2002,7 +2003,7 @@ static __devinit int try_init_acpi(struct SPMITable *spmi) | |||
2002 | return 0; | 2003 | return 0; |
2003 | } | 2004 | } |
2004 | 2005 | ||
2005 | static __devinit void acpi_find_bmc(void) | 2006 | static __devinit void spmi_find_bmc(void) |
2006 | { | 2007 | { |
2007 | acpi_status status; | 2008 | acpi_status status; |
2008 | struct SPMITable *spmi; | 2009 | struct SPMITable *spmi; |
@@ -2020,9 +2021,106 @@ static __devinit void acpi_find_bmc(void) | |||
2020 | if (status != AE_OK) | 2021 | if (status != AE_OK) |
2021 | return; | 2022 | return; |
2022 | 2023 | ||
2023 | try_init_acpi(spmi); | 2024 | try_init_spmi(spmi); |
2024 | } | 2025 | } |
2025 | } | 2026 | } |
2027 | |||
2028 | static int __devinit ipmi_pnp_probe(struct pnp_dev *dev, | ||
2029 | const struct pnp_device_id *dev_id) | ||
2030 | { | ||
2031 | struct acpi_device *acpi_dev; | ||
2032 | struct smi_info *info; | ||
2033 | acpi_handle handle; | ||
2034 | acpi_status status; | ||
2035 | unsigned long long tmp; | ||
2036 | |||
2037 | acpi_dev = pnp_acpi_device(dev); | ||
2038 | if (!acpi_dev) | ||
2039 | return -ENODEV; | ||
2040 | |||
2041 | info = kzalloc(sizeof(*info), GFP_KERNEL); | ||
2042 | if (!info) | ||
2043 | return -ENOMEM; | ||
2044 | |||
2045 | info->addr_source = "ACPI"; | ||
2046 | |||
2047 | handle = acpi_dev->handle; | ||
2048 | |||
2049 | /* _IFT tells us the interface type: KCS, BT, etc */ | ||
2050 | status = acpi_evaluate_integer(handle, "_IFT", NULL, &tmp); | ||
2051 | if (ACPI_FAILURE(status)) | ||
2052 | goto err_free; | ||
2053 | |||
2054 | switch (tmp) { | ||
2055 | case 1: | ||
2056 | info->si_type = SI_KCS; | ||
2057 | break; | ||
2058 | case 2: | ||
2059 | info->si_type = SI_SMIC; | ||
2060 | break; | ||
2061 | case 3: | ||
2062 | info->si_type = SI_BT; | ||
2063 | break; | ||
2064 | default: | ||
2065 | dev_info(&dev->dev, "unknown interface type %lld\n", tmp); | ||
2066 | goto err_free; | ||
2067 | } | ||
2068 | |||
2069 | if (pnp_port_valid(dev, 0)) { | ||
2070 | info->io_setup = port_setup; | ||
2071 | info->io.addr_type = IPMI_IO_ADDR_SPACE; | ||
2072 | info->io.addr_data = pnp_port_start(dev, 0); | ||
2073 | } else if (pnp_mem_valid(dev, 0)) { | ||
2074 | info->io_setup = mem_setup; | ||
2075 | info->io.addr_type = IPMI_MEM_ADDR_SPACE; | ||
2076 | info->io.addr_data = pnp_mem_start(dev, 0); | ||
2077 | } else { | ||
2078 | dev_err(&dev->dev, "no I/O or memory address\n"); | ||
2079 | goto err_free; | ||
2080 | } | ||
2081 | |||
2082 | info->io.regspacing = DEFAULT_REGSPACING; | ||
2083 | info->io.regsize = DEFAULT_REGSPACING; | ||
2084 | info->io.regshift = 0; | ||
2085 | |||
2086 | /* If _GPE exists, use it; otherwise use standard interrupts */ | ||
2087 | status = acpi_evaluate_integer(handle, "_GPE", NULL, &tmp); | ||
2088 | if (ACPI_SUCCESS(status)) { | ||
2089 | info->irq = tmp; | ||
2090 | info->irq_setup = acpi_gpe_irq_setup; | ||
2091 | } else if (pnp_irq_valid(dev, 0)) { | ||
2092 | info->irq = pnp_irq(dev, 0); | ||
2093 | info->irq_setup = std_irq_setup; | ||
2094 | } | ||
2095 | |||
2096 | info->dev = &acpi_dev->dev; | ||
2097 | pnp_set_drvdata(dev, info); | ||
2098 | |||
2099 | return try_smi_init(info); | ||
2100 | |||
2101 | err_free: | ||
2102 | kfree(info); | ||
2103 | return -EINVAL; | ||
2104 | } | ||
2105 | |||
2106 | static void __devexit ipmi_pnp_remove(struct pnp_dev *dev) | ||
2107 | { | ||
2108 | struct smi_info *info = pnp_get_drvdata(dev); | ||
2109 | |||
2110 | cleanup_one_si(info); | ||
2111 | } | ||
2112 | |||
2113 | static const struct pnp_device_id pnp_dev_table[] = { | ||
2114 | {"IPI0001", 0}, | ||
2115 | {"", 0}, | ||
2116 | }; | ||
2117 | |||
2118 | static struct pnp_driver ipmi_pnp_driver = { | ||
2119 | .name = DEVICE_NAME, | ||
2120 | .probe = ipmi_pnp_probe, | ||
2121 | .remove = __devexit_p(ipmi_pnp_remove), | ||
2122 | .id_table = pnp_dev_table, | ||
2123 | }; | ||
2026 | #endif | 2124 | #endif |
2027 | 2125 | ||
2028 | #ifdef CONFIG_DMI | 2126 | #ifdef CONFIG_DMI |
@@ -2202,7 +2300,6 @@ static int __devinit ipmi_pci_probe(struct pci_dev *pdev, | |||
2202 | int rv; | 2300 | int rv; |
2203 | int class_type = pdev->class & PCI_ERMC_CLASSCODE_TYPE_MASK; | 2301 | int class_type = pdev->class & PCI_ERMC_CLASSCODE_TYPE_MASK; |
2204 | struct smi_info *info; | 2302 | struct smi_info *info; |
2205 | int first_reg_offset = 0; | ||
2206 | 2303 | ||
2207 | info = kzalloc(sizeof(*info), GFP_KERNEL); | 2304 | info = kzalloc(sizeof(*info), GFP_KERNEL); |
2208 | if (!info) | 2305 | if (!info) |
@@ -2241,9 +2338,6 @@ static int __devinit ipmi_pci_probe(struct pci_dev *pdev, | |||
2241 | info->addr_source_cleanup = ipmi_pci_cleanup; | 2338 | info->addr_source_cleanup = ipmi_pci_cleanup; |
2242 | info->addr_source_data = pdev; | 2339 | info->addr_source_data = pdev; |
2243 | 2340 | ||
2244 | if (pdev->subsystem_vendor == PCI_HP_VENDOR_ID) | ||
2245 | first_reg_offset = 1; | ||
2246 | |||
2247 | if (pci_resource_flags(pdev, 0) & IORESOURCE_IO) { | 2341 | if (pci_resource_flags(pdev, 0) & IORESOURCE_IO) { |
2248 | info->io_setup = port_setup; | 2342 | info->io_setup = port_setup; |
2249 | info->io.addr_type = IPMI_IO_ADDR_SPACE; | 2343 | info->io.addr_type = IPMI_IO_ADDR_SPACE; |
@@ -3108,7 +3202,10 @@ static __devinit int init_ipmi_si(void) | |||
3108 | #endif | 3202 | #endif |
3109 | 3203 | ||
3110 | #ifdef CONFIG_ACPI | 3204 | #ifdef CONFIG_ACPI |
3111 | acpi_find_bmc(); | 3205 | spmi_find_bmc(); |
3206 | #endif | ||
3207 | #ifdef CONFIG_PNP | ||
3208 | pnp_register_driver(&ipmi_pnp_driver); | ||
3112 | #endif | 3209 | #endif |
3113 | 3210 | ||
3114 | #ifdef CONFIG_PCI | 3211 | #ifdef CONFIG_PCI |
@@ -3233,6 +3330,9 @@ static __exit void cleanup_ipmi_si(void) | |||
3233 | #ifdef CONFIG_PCI | 3330 | #ifdef CONFIG_PCI |
3234 | pci_unregister_driver(&ipmi_pci_driver); | 3331 | pci_unregister_driver(&ipmi_pci_driver); |
3235 | #endif | 3332 | #endif |
3333 | #ifdef CONFIG_PNP | ||
3334 | pnp_unregister_driver(&ipmi_pnp_driver); | ||
3335 | #endif | ||
3236 | 3336 | ||
3237 | #ifdef CONFIG_PPC_OF | 3337 | #ifdef CONFIG_PPC_OF |
3238 | of_unregister_platform_driver(&ipmi_of_platform_driver); | 3338 | of_unregister_platform_driver(&ipmi_of_platform_driver); |