.. | .. |
---|
19 | 19 | * and drives the real SMI state machine. |
---|
20 | 20 | */ |
---|
21 | 21 | |
---|
| 22 | +#define pr_fmt(fmt) "ipmi_si: " fmt |
---|
| 23 | + |
---|
22 | 24 | #include <linux/module.h> |
---|
23 | 25 | #include <linux/moduleparam.h> |
---|
24 | 26 | #include <linux/sched.h> |
---|
.. | .. |
---|
38 | 40 | #include <linux/ipmi.h> |
---|
39 | 41 | #include <linux/ipmi_smi.h> |
---|
40 | 42 | #include "ipmi_si.h" |
---|
| 43 | +#include "ipmi_si_sm.h" |
---|
41 | 44 | #include <linux/string.h> |
---|
42 | 45 | #include <linux/ctype.h> |
---|
43 | | - |
---|
44 | | -#define PFX "ipmi_si: " |
---|
45 | 46 | |
---|
46 | 47 | /* Measure times between events in the driver. */ |
---|
47 | 48 | #undef DEBUG_TIMING |
---|
.. | .. |
---|
71 | 72 | |
---|
72 | 73 | static const char * const si_to_str[] = { "invalid", "kcs", "smic", "bt" }; |
---|
73 | 74 | |
---|
74 | | -static int initialized; |
---|
| 75 | +static bool initialized; |
---|
75 | 76 | |
---|
76 | 77 | /* |
---|
77 | 78 | * Indexes into stats[] in smi_info below. |
---|
.. | .. |
---|
232 | 233 | /* From the get device id response... */ |
---|
233 | 234 | struct ipmi_device_id device_id; |
---|
234 | 235 | |
---|
235 | | - /* Default driver model device. */ |
---|
236 | | - struct platform_device *pdev; |
---|
237 | | - |
---|
238 | 236 | /* Have we added the device group to the device? */ |
---|
239 | 237 | bool dev_group_added; |
---|
240 | | - |
---|
241 | | - /* Have we added the platform device? */ |
---|
242 | | - bool pdev_registered; |
---|
243 | 238 | |
---|
244 | 239 | /* Counters and things for the proc filesystem. */ |
---|
245 | 240 | atomic_t stats[SI_NUM_STATS]; |
---|
.. | .. |
---|
272 | 267 | { |
---|
273 | 268 | struct timespec64 t; |
---|
274 | 269 | |
---|
275 | | - getnstimeofday64(&t); |
---|
276 | | - pr_debug("**%s: %lld.%9.9ld\n", msg, (long long) t.tv_sec, t.tv_nsec); |
---|
| 270 | + ktime_get_ts64(&t); |
---|
| 271 | + pr_debug("**%s: %lld.%9.9ld\n", msg, t.tv_sec, t.tv_nsec); |
---|
277 | 272 | } |
---|
278 | 273 | #else |
---|
279 | 274 | #define debug_timestamp(x) |
---|
.. | .. |
---|
940 | 935 | } |
---|
941 | 936 | |
---|
942 | 937 | /* |
---|
943 | | - * Use -1 in the nsec value of the busy waiting timespec to tell that |
---|
944 | | - * we are spinning in kipmid looking for something and not delaying |
---|
945 | | - * between checks |
---|
| 938 | + * Use -1 as a special constant to tell that we are spinning in kipmid |
---|
| 939 | + * looking for something and not delaying between checks |
---|
946 | 940 | */ |
---|
947 | | -static inline void ipmi_si_set_not_busy(struct timespec64 *ts) |
---|
948 | | -{ |
---|
949 | | - ts->tv_nsec = -1; |
---|
950 | | -} |
---|
951 | | -static inline int ipmi_si_is_busy(struct timespec64 *ts) |
---|
952 | | -{ |
---|
953 | | - return ts->tv_nsec != -1; |
---|
954 | | -} |
---|
955 | | - |
---|
956 | | -static inline int ipmi_thread_busy_wait(enum si_sm_result smi_result, |
---|
957 | | - const struct smi_info *smi_info, |
---|
958 | | - struct timespec64 *busy_until) |
---|
| 941 | +#define IPMI_TIME_NOT_BUSY ns_to_ktime(-1ull) |
---|
| 942 | +static inline bool ipmi_thread_busy_wait(enum si_sm_result smi_result, |
---|
| 943 | + const struct smi_info *smi_info, |
---|
| 944 | + ktime_t *busy_until) |
---|
959 | 945 | { |
---|
960 | 946 | unsigned int max_busy_us = 0; |
---|
961 | 947 | |
---|
962 | 948 | if (smi_info->si_num < num_max_busy_us) |
---|
963 | 949 | max_busy_us = kipmid_max_busy_us[smi_info->si_num]; |
---|
964 | 950 | if (max_busy_us == 0 || smi_result != SI_SM_CALL_WITH_DELAY) |
---|
965 | | - ipmi_si_set_not_busy(busy_until); |
---|
966 | | - else if (!ipmi_si_is_busy(busy_until)) { |
---|
967 | | - getnstimeofday64(busy_until); |
---|
968 | | - timespec64_add_ns(busy_until, max_busy_us*NSEC_PER_USEC); |
---|
| 951 | + *busy_until = IPMI_TIME_NOT_BUSY; |
---|
| 952 | + else if (*busy_until == IPMI_TIME_NOT_BUSY) { |
---|
| 953 | + *busy_until = ktime_get() + max_busy_us * NSEC_PER_USEC; |
---|
969 | 954 | } else { |
---|
970 | | - struct timespec64 now; |
---|
971 | | - |
---|
972 | | - getnstimeofday64(&now); |
---|
973 | | - if (unlikely(timespec64_compare(&now, busy_until) > 0)) { |
---|
974 | | - ipmi_si_set_not_busy(busy_until); |
---|
975 | | - return 0; |
---|
| 955 | + if (unlikely(ktime_get() > *busy_until)) { |
---|
| 956 | + *busy_until = IPMI_TIME_NOT_BUSY; |
---|
| 957 | + return false; |
---|
976 | 958 | } |
---|
977 | 959 | } |
---|
978 | | - return 1; |
---|
| 960 | + return true; |
---|
979 | 961 | } |
---|
980 | 962 | |
---|
981 | 963 | |
---|
.. | .. |
---|
986 | 968 | * that are not BT and do not have interrupts. It starts spinning |
---|
987 | 969 | * when an operation is complete or until max_busy tells it to stop |
---|
988 | 970 | * (if that is enabled). See the paragraph on kimid_max_busy_us in |
---|
989 | | - * Documentation/IPMI.txt for details. |
---|
| 971 | + * Documentation/driver-api/ipmi.rst for details. |
---|
990 | 972 | */ |
---|
991 | 973 | static int ipmi_thread(void *data) |
---|
992 | 974 | { |
---|
993 | 975 | struct smi_info *smi_info = data; |
---|
994 | 976 | unsigned long flags; |
---|
995 | 977 | enum si_sm_result smi_result; |
---|
996 | | - struct timespec64 busy_until; |
---|
| 978 | + ktime_t busy_until = IPMI_TIME_NOT_BUSY; |
---|
997 | 979 | |
---|
998 | | - ipmi_si_set_not_busy(&busy_until); |
---|
999 | 980 | set_user_nice(current, MAX_NICE); |
---|
1000 | 981 | while (!kthread_should_stop()) { |
---|
1001 | 982 | int busy_wait; |
---|
.. | .. |
---|
1073 | 1054 | atomic_set(&smi_info->req_events, 1); |
---|
1074 | 1055 | } |
---|
1075 | 1056 | |
---|
1076 | | -static void set_need_watch(void *send_info, bool enable) |
---|
| 1057 | +static void set_need_watch(void *send_info, unsigned int watch_mask) |
---|
1077 | 1058 | { |
---|
1078 | 1059 | struct smi_info *smi_info = send_info; |
---|
1079 | 1060 | unsigned long flags; |
---|
| 1061 | + int enable; |
---|
| 1062 | + |
---|
| 1063 | + enable = !!watch_mask; |
---|
1080 | 1064 | |
---|
1081 | 1065 | atomic_set(&smi_info->need_watch, enable); |
---|
1082 | 1066 | spin_lock_irqsave(&smi_info->si_lock, flags); |
---|
.. | .. |
---|
1283 | 1267 | rv = request_irq(io->irq, |
---|
1284 | 1268 | ipmi_si_irq_handler, |
---|
1285 | 1269 | IRQF_SHARED, |
---|
1286 | | - DEVICE_NAME, |
---|
| 1270 | + SI_DEVICE_NAME, |
---|
1287 | 1271 | io->irq_handler_data); |
---|
1288 | 1272 | if (rv) { |
---|
1289 | 1273 | dev_warn(io->dev, "%s unable to claim interrupt %d," |
---|
1290 | 1274 | " running polled\n", |
---|
1291 | | - DEVICE_NAME, io->irq); |
---|
| 1275 | + SI_DEVICE_NAME, io->irq); |
---|
1292 | 1276 | io->irq = 0; |
---|
1293 | 1277 | } else { |
---|
1294 | 1278 | io->irq_cleanup = std_irq_cleanup; |
---|
.. | .. |
---|
1332 | 1316 | unsigned char *resp; |
---|
1333 | 1317 | unsigned long resp_len; |
---|
1334 | 1318 | int rv = 0; |
---|
| 1319 | + unsigned int retry_count = 0; |
---|
1335 | 1320 | |
---|
1336 | 1321 | resp = kmalloc(IPMI_MAX_MSG_LENGTH, GFP_KERNEL); |
---|
1337 | 1322 | if (!resp) |
---|
.. | .. |
---|
1343 | 1328 | */ |
---|
1344 | 1329 | msg[0] = IPMI_NETFN_APP_REQUEST << 2; |
---|
1345 | 1330 | msg[1] = IPMI_GET_DEVICE_ID_CMD; |
---|
| 1331 | + |
---|
| 1332 | +retry: |
---|
1346 | 1333 | smi_info->handlers->start_transaction(smi_info->si_sm, msg, 2); |
---|
1347 | 1334 | |
---|
1348 | 1335 | rv = wait_for_msg_done(smi_info); |
---|
.. | .. |
---|
1355 | 1342 | /* Check and record info from the get device id, in case we need it. */ |
---|
1356 | 1343 | rv = ipmi_demangle_device_id(resp[0] >> 2, resp[1], |
---|
1357 | 1344 | resp + 2, resp_len - 2, &smi_info->device_id); |
---|
| 1345 | + if (rv) { |
---|
| 1346 | + /* record completion code */ |
---|
| 1347 | + unsigned char cc = *(resp + 2); |
---|
| 1348 | + |
---|
| 1349 | + if ((cc == IPMI_DEVICE_IN_FW_UPDATE_ERR |
---|
| 1350 | + || cc == IPMI_DEVICE_IN_INIT_ERR |
---|
| 1351 | + || cc == IPMI_NOT_IN_MY_STATE_ERR) |
---|
| 1352 | + && ++retry_count <= GET_DEVICE_ID_MAX_RETRY) { |
---|
| 1353 | + dev_warn(smi_info->io.dev, |
---|
| 1354 | + "BMC returned 0x%2.2x, retry get bmc device id\n", |
---|
| 1355 | + cc); |
---|
| 1356 | + goto retry; |
---|
| 1357 | + } |
---|
| 1358 | + } |
---|
1358 | 1359 | |
---|
1359 | 1360 | out: |
---|
1360 | 1361 | kfree(resp); |
---|
.. | .. |
---|
1544 | 1545 | |
---|
1545 | 1546 | rv = wait_for_msg_done(smi_info); |
---|
1546 | 1547 | if (rv) { |
---|
1547 | | - pr_warn(PFX "Error getting response from get global enables command, the event buffer is not enabled.\n"); |
---|
| 1548 | + pr_warn("Error getting response from get global enables command, the event buffer is not enabled\n"); |
---|
1548 | 1549 | goto out; |
---|
1549 | 1550 | } |
---|
1550 | 1551 | |
---|
.. | .. |
---|
1555 | 1556 | resp[0] != (IPMI_NETFN_APP_REQUEST | 1) << 2 || |
---|
1556 | 1557 | resp[1] != IPMI_GET_BMC_GLOBAL_ENABLES_CMD || |
---|
1557 | 1558 | resp[2] != 0) { |
---|
1558 | | - pr_warn(PFX "Invalid return from get global enables command, cannot enable the event buffer.\n"); |
---|
| 1559 | + pr_warn("Invalid return from get global enables command, cannot enable the event buffer\n"); |
---|
1559 | 1560 | rv = -EINVAL; |
---|
1560 | 1561 | goto out; |
---|
1561 | 1562 | } |
---|
.. | .. |
---|
1573 | 1574 | |
---|
1574 | 1575 | rv = wait_for_msg_done(smi_info); |
---|
1575 | 1576 | if (rv) { |
---|
1576 | | - pr_warn(PFX "Error getting response from set global, enables command, the event buffer is not enabled.\n"); |
---|
| 1577 | + pr_warn("Error getting response from set global, enables command, the event buffer is not enabled\n"); |
---|
1577 | 1578 | goto out; |
---|
1578 | 1579 | } |
---|
1579 | 1580 | |
---|
.. | .. |
---|
1583 | 1584 | if (resp_len < 3 || |
---|
1584 | 1585 | resp[0] != (IPMI_NETFN_APP_REQUEST | 1) << 2 || |
---|
1585 | 1586 | resp[1] != IPMI_SET_BMC_GLOBAL_ENABLES_CMD) { |
---|
1586 | | - pr_warn(PFX "Invalid return from get global, enables command, not enable the event buffer.\n"); |
---|
| 1587 | + pr_warn("Invalid return from get global, enables command, not enable the event buffer\n"); |
---|
1587 | 1588 | rv = -EINVAL; |
---|
1588 | 1589 | goto out; |
---|
1589 | 1590 | } |
---|
.. | .. |
---|
1603 | 1604 | } |
---|
1604 | 1605 | |
---|
1605 | 1606 | #define IPMI_SI_ATTR(name) \ |
---|
1606 | | -static ssize_t ipmi_##name##_show(struct device *dev, \ |
---|
1607 | | - struct device_attribute *attr, \ |
---|
1608 | | - char *buf) \ |
---|
| 1607 | +static ssize_t name##_show(struct device *dev, \ |
---|
| 1608 | + struct device_attribute *attr, \ |
---|
| 1609 | + char *buf) \ |
---|
1609 | 1610 | { \ |
---|
1610 | 1611 | struct smi_info *smi_info = dev_get_drvdata(dev); \ |
---|
1611 | 1612 | \ |
---|
1612 | 1613 | return snprintf(buf, 10, "%u\n", smi_get_stat(smi_info, name)); \ |
---|
1613 | 1614 | } \ |
---|
1614 | | -static DEVICE_ATTR(name, S_IRUGO, ipmi_##name##_show, NULL) |
---|
| 1615 | +static DEVICE_ATTR(name, 0444, name##_show, NULL) |
---|
1615 | 1616 | |
---|
1616 | | -static ssize_t ipmi_type_show(struct device *dev, |
---|
1617 | | - struct device_attribute *attr, |
---|
1618 | | - char *buf) |
---|
| 1617 | +static ssize_t type_show(struct device *dev, |
---|
| 1618 | + struct device_attribute *attr, |
---|
| 1619 | + char *buf) |
---|
1619 | 1620 | { |
---|
1620 | 1621 | struct smi_info *smi_info = dev_get_drvdata(dev); |
---|
1621 | 1622 | |
---|
1622 | 1623 | return snprintf(buf, 10, "%s\n", si_to_str[smi_info->io.si_type]); |
---|
1623 | 1624 | } |
---|
1624 | | -static DEVICE_ATTR(type, S_IRUGO, ipmi_type_show, NULL); |
---|
| 1625 | +static DEVICE_ATTR(type, 0444, type_show, NULL); |
---|
1625 | 1626 | |
---|
1626 | | -static ssize_t ipmi_interrupts_enabled_show(struct device *dev, |
---|
1627 | | - struct device_attribute *attr, |
---|
1628 | | - char *buf) |
---|
| 1627 | +static ssize_t interrupts_enabled_show(struct device *dev, |
---|
| 1628 | + struct device_attribute *attr, |
---|
| 1629 | + char *buf) |
---|
1629 | 1630 | { |
---|
1630 | 1631 | struct smi_info *smi_info = dev_get_drvdata(dev); |
---|
1631 | 1632 | int enabled = smi_info->io.irq && !smi_info->interrupt_disabled; |
---|
1632 | 1633 | |
---|
1633 | 1634 | return snprintf(buf, 10, "%d\n", enabled); |
---|
1634 | 1635 | } |
---|
1635 | | -static DEVICE_ATTR(interrupts_enabled, S_IRUGO, |
---|
1636 | | - ipmi_interrupts_enabled_show, NULL); |
---|
| 1636 | +static DEVICE_ATTR(interrupts_enabled, 0444, |
---|
| 1637 | + interrupts_enabled_show, NULL); |
---|
1637 | 1638 | |
---|
1638 | 1639 | IPMI_SI_ATTR(short_timeouts); |
---|
1639 | 1640 | IPMI_SI_ATTR(long_timeouts); |
---|
.. | .. |
---|
1647 | 1648 | IPMI_SI_ATTR(watchdog_pretimeouts); |
---|
1648 | 1649 | IPMI_SI_ATTR(incoming_messages); |
---|
1649 | 1650 | |
---|
1650 | | -static ssize_t ipmi_params_show(struct device *dev, |
---|
1651 | | - struct device_attribute *attr, |
---|
1652 | | - char *buf) |
---|
| 1651 | +static ssize_t params_show(struct device *dev, |
---|
| 1652 | + struct device_attribute *attr, |
---|
| 1653 | + char *buf) |
---|
1653 | 1654 | { |
---|
1654 | 1655 | struct smi_info *smi_info = dev_get_drvdata(dev); |
---|
1655 | 1656 | |
---|
1656 | 1657 | return snprintf(buf, 200, |
---|
1657 | 1658 | "%s,%s,0x%lx,rsp=%d,rsi=%d,rsh=%d,irq=%d,ipmb=%d\n", |
---|
1658 | 1659 | si_to_str[smi_info->io.si_type], |
---|
1659 | | - addr_space_to_str[smi_info->io.addr_type], |
---|
| 1660 | + addr_space_to_str[smi_info->io.addr_space], |
---|
1660 | 1661 | smi_info->io.addr_data, |
---|
1661 | 1662 | smi_info->io.regspacing, |
---|
1662 | 1663 | smi_info->io.regsize, |
---|
.. | .. |
---|
1664 | 1665 | smi_info->io.irq, |
---|
1665 | 1666 | smi_info->io.slave_addr); |
---|
1666 | 1667 | } |
---|
1667 | | -static DEVICE_ATTR(params, S_IRUGO, ipmi_params_show, NULL); |
---|
| 1668 | +static DEVICE_ATTR(params, 0444, params_show, NULL); |
---|
1668 | 1669 | |
---|
1669 | 1670 | static struct attribute *ipmi_si_dev_attrs[] = { |
---|
1670 | 1671 | &dev_attr_type.attr, |
---|
.. | .. |
---|
1845 | 1846 | } |
---|
1846 | 1847 | |
---|
1847 | 1848 | smi_info->timer_can_start = false; |
---|
1848 | | - if (smi_info->timer_running) |
---|
1849 | | - del_timer_sync(&smi_info->si_timer); |
---|
| 1849 | + del_timer_sync(&smi_info->si_timer); |
---|
1850 | 1850 | } |
---|
1851 | 1851 | |
---|
1852 | 1852 | static struct smi_info *find_dup_si(struct smi_info *info) |
---|
.. | .. |
---|
1854 | 1854 | struct smi_info *e; |
---|
1855 | 1855 | |
---|
1856 | 1856 | list_for_each_entry(e, &smi_infos, link) { |
---|
1857 | | - if (e->io.addr_type != info->io.addr_type) |
---|
| 1857 | + if (e->io.addr_space != info->io.addr_space) |
---|
1858 | 1858 | continue; |
---|
1859 | 1859 | if (e->io.addr_data == info->io.addr_data) { |
---|
1860 | 1860 | /* |
---|
.. | .. |
---|
1881 | 1881 | * address, they presumably want us to use it and not what is |
---|
1882 | 1882 | * in the firmware. |
---|
1883 | 1883 | */ |
---|
1884 | | - if (io->addr_source != SI_HARDCODED && |
---|
1885 | | - ipmi_si_hardcode_match(io->addr_type, io->addr_data)) { |
---|
| 1884 | + if (io->addr_source != SI_HARDCODED && io->addr_source != SI_HOTMOD && |
---|
| 1885 | + ipmi_si_hardcode_match(io->addr_space, io->addr_data)) { |
---|
1886 | 1886 | dev_info(io->dev, |
---|
1887 | 1887 | "Hard-coded device at this address already exists"); |
---|
1888 | 1888 | return -ENODEV; |
---|
1889 | 1889 | } |
---|
1890 | 1890 | |
---|
1891 | 1891 | if (!io->io_setup) { |
---|
1892 | | - if (io->addr_type == IPMI_IO_ADDR_SPACE) { |
---|
| 1892 | + if (io->addr_space == IPMI_IO_ADDR_SPACE) { |
---|
1893 | 1893 | io->io_setup = ipmi_si_port_setup; |
---|
1894 | | - } else if (io->addr_type == IPMI_MEM_ADDR_SPACE) { |
---|
| 1894 | + } else if (io->addr_space == IPMI_MEM_ADDR_SPACE) { |
---|
1895 | 1895 | io->io_setup = ipmi_si_mem_setup; |
---|
1896 | 1896 | } else { |
---|
1897 | 1897 | return -EINVAL; |
---|
.. | .. |
---|
1926 | 1926 | } |
---|
1927 | 1927 | } |
---|
1928 | 1928 | |
---|
1929 | | - pr_info(PFX "Adding %s-specified %s state machine\n", |
---|
| 1929 | + pr_info("Adding %s-specified %s state machine\n", |
---|
1930 | 1930 | ipmi_addr_src_to_str(new_smi->io.addr_source), |
---|
1931 | 1931 | si_to_str[new_smi->io.si_type]); |
---|
1932 | 1932 | |
---|
.. | .. |
---|
1948 | 1948 | { |
---|
1949 | 1949 | int rv = 0; |
---|
1950 | 1950 | int i; |
---|
1951 | | - char *init_name = NULL; |
---|
1952 | 1951 | |
---|
1953 | | - pr_info(PFX "Trying %s-specified %s state machine at %s address 0x%lx, slave address 0x%x, irq %d\n", |
---|
| 1952 | + pr_info("Trying %s-specified %s state machine at %s address 0x%lx, slave address 0x%x, irq %d\n", |
---|
1954 | 1953 | ipmi_addr_src_to_str(new_smi->io.addr_source), |
---|
1955 | 1954 | si_to_str[new_smi->io.si_type], |
---|
1956 | | - addr_space_to_str[new_smi->io.addr_type], |
---|
| 1955 | + addr_space_to_str[new_smi->io.addr_space], |
---|
1957 | 1956 | new_smi->io.addr_data, |
---|
1958 | 1957 | new_smi->io.slave_addr, new_smi->io.irq); |
---|
1959 | 1958 | |
---|
.. | .. |
---|
1980 | 1979 | |
---|
1981 | 1980 | /* Do this early so it's available for logs. */ |
---|
1982 | 1981 | if (!new_smi->io.dev) { |
---|
1983 | | - init_name = kasprintf(GFP_KERNEL, "ipmi_si.%d", |
---|
1984 | | - new_smi->si_num); |
---|
1985 | | - |
---|
1986 | | - /* |
---|
1987 | | - * If we don't already have a device from something |
---|
1988 | | - * else (like PCI), then register a new one. |
---|
1989 | | - */ |
---|
1990 | | - new_smi->pdev = platform_device_alloc("ipmi_si", |
---|
1991 | | - new_smi->si_num); |
---|
1992 | | - if (!new_smi->pdev) { |
---|
1993 | | - pr_err(PFX "Unable to allocate platform device\n"); |
---|
1994 | | - rv = -ENOMEM; |
---|
1995 | | - goto out_err; |
---|
1996 | | - } |
---|
1997 | | - new_smi->io.dev = &new_smi->pdev->dev; |
---|
1998 | | - new_smi->io.dev->driver = &ipmi_platform_driver.driver; |
---|
1999 | | - /* Nulled by device_add() */ |
---|
2000 | | - new_smi->io.dev->init_name = init_name; |
---|
| 1982 | + pr_err("IPMI interface added with no device\n"); |
---|
| 1983 | + rv = -EIO; |
---|
| 1984 | + goto out_err; |
---|
2001 | 1985 | } |
---|
2002 | 1986 | |
---|
2003 | 1987 | /* Allocate the state machine's data and initialize it. */ |
---|
.. | .. |
---|
2070 | 2054 | atomic_set(&new_smi->req_events, 1); |
---|
2071 | 2055 | } |
---|
2072 | 2056 | |
---|
2073 | | - if (new_smi->pdev && !new_smi->pdev_registered) { |
---|
2074 | | - rv = platform_device_add(new_smi->pdev); |
---|
2075 | | - if (rv) { |
---|
2076 | | - dev_err(new_smi->io.dev, |
---|
2077 | | - "Unable to register system interface device: %d\n", |
---|
2078 | | - rv); |
---|
2079 | | - goto out_err; |
---|
2080 | | - } |
---|
2081 | | - new_smi->pdev_registered = true; |
---|
2082 | | - } |
---|
2083 | | - |
---|
2084 | 2057 | dev_set_drvdata(new_smi->io.dev, new_smi); |
---|
2085 | 2058 | rv = device_add_group(new_smi->io.dev, &ipmi_si_dev_attr_group); |
---|
2086 | 2059 | if (rv) { |
---|
.. | .. |
---|
2116 | 2089 | new_smi->io.io_cleanup = NULL; |
---|
2117 | 2090 | } |
---|
2118 | 2091 | |
---|
2119 | | - kfree(init_name); |
---|
2120 | 2092 | return rv; |
---|
2121 | 2093 | } |
---|
2122 | 2094 | |
---|
.. | .. |
---|
2129 | 2101 | return 0; |
---|
2130 | 2102 | |
---|
2131 | 2103 | ipmi_hardcode_init(); |
---|
2132 | | - pr_info("IPMI System Interface driver.\n"); |
---|
| 2104 | + |
---|
| 2105 | + pr_info("IPMI System Interface driver\n"); |
---|
2133 | 2106 | |
---|
2134 | 2107 | ipmi_si_platform_init(); |
---|
2135 | 2108 | |
---|
.. | .. |
---|
2168 | 2141 | } |
---|
2169 | 2142 | |
---|
2170 | 2143 | skip_fallback_noirq: |
---|
2171 | | - initialized = 1; |
---|
| 2144 | + initialized = true; |
---|
2172 | 2145 | mutex_unlock(&smi_infos_lock); |
---|
2173 | 2146 | |
---|
2174 | 2147 | if (type) |
---|
.. | .. |
---|
2178 | 2151 | if (unload_when_empty && list_empty(&smi_infos)) { |
---|
2179 | 2152 | mutex_unlock(&smi_infos_lock); |
---|
2180 | 2153 | cleanup_ipmi_si(); |
---|
2181 | | - pr_warn(PFX "Unable to find any System Interface(s)\n"); |
---|
| 2154 | + pr_warn("Unable to find any System Interface(s)\n"); |
---|
2182 | 2155 | return -ENODEV; |
---|
2183 | 2156 | } else { |
---|
2184 | 2157 | mutex_unlock(&smi_infos_lock); |
---|
.. | .. |
---|
2214 | 2187 | * handlers might have been running before we freed the |
---|
2215 | 2188 | * interrupt. |
---|
2216 | 2189 | */ |
---|
2217 | | - synchronize_sched(); |
---|
| 2190 | + synchronize_rcu(); |
---|
2218 | 2191 | |
---|
2219 | 2192 | /* |
---|
2220 | 2193 | * Timeouts are stopped, now make sure the interrupts are off |
---|
.. | .. |
---|
2263 | 2236 | if (smi_info->intf) |
---|
2264 | 2237 | ipmi_unregister_smi(smi_info->intf); |
---|
2265 | 2238 | |
---|
2266 | | - if (smi_info->pdev) { |
---|
2267 | | - if (smi_info->pdev_registered) |
---|
2268 | | - platform_device_unregister(smi_info->pdev); |
---|
2269 | | - else |
---|
2270 | | - platform_device_put(smi_info->pdev); |
---|
2271 | | - } |
---|
2272 | | - |
---|
2273 | 2239 | kfree(smi_info); |
---|
2274 | 2240 | } |
---|
2275 | 2241 | |
---|
.. | .. |
---|
2291 | 2257 | return rv; |
---|
2292 | 2258 | } |
---|
2293 | 2259 | |
---|
2294 | | -void ipmi_si_remove_by_data(int addr_space, enum si_type si_type, |
---|
2295 | | - unsigned long addr) |
---|
| 2260 | +struct device *ipmi_si_remove_by_data(int addr_space, enum si_type si_type, |
---|
| 2261 | + unsigned long addr) |
---|
2296 | 2262 | { |
---|
2297 | 2263 | /* remove */ |
---|
2298 | 2264 | struct smi_info *e, *tmp_e; |
---|
| 2265 | + struct device *dev = NULL; |
---|
2299 | 2266 | |
---|
2300 | 2267 | mutex_lock(&smi_infos_lock); |
---|
2301 | 2268 | list_for_each_entry_safe(e, tmp_e, &smi_infos, link) { |
---|
2302 | | - if (e->io.addr_type != addr_space) |
---|
| 2269 | + if (e->io.addr_space != addr_space) |
---|
2303 | 2270 | continue; |
---|
2304 | 2271 | if (e->io.si_type != si_type) |
---|
2305 | 2272 | continue; |
---|
2306 | | - if (e->io.addr_data == addr) |
---|
| 2273 | + if (e->io.addr_data == addr) { |
---|
| 2274 | + dev = get_device(e->io.dev); |
---|
2307 | 2275 | cleanup_one_si(e); |
---|
| 2276 | + } |
---|
2308 | 2277 | } |
---|
2309 | 2278 | mutex_unlock(&smi_infos_lock); |
---|
| 2279 | + |
---|
| 2280 | + return dev; |
---|
2310 | 2281 | } |
---|
2311 | 2282 | |
---|
2312 | 2283 | static void cleanup_ipmi_si(void) |
---|
.. | .. |
---|
2328 | 2299 | mutex_unlock(&smi_infos_lock); |
---|
2329 | 2300 | |
---|
2330 | 2301 | ipmi_si_hardcode_exit(); |
---|
| 2302 | + ipmi_si_hotmod_exit(); |
---|
2331 | 2303 | } |
---|
2332 | 2304 | module_exit(cleanup_ipmi_si); |
---|
2333 | 2305 | |
---|