aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/IPMI.txt2
-rw-r--r--drivers/acpi/acpi_ipmi.c2
-rw-r--r--drivers/char/ipmi/Kconfig3
-rw-r--r--drivers/char/ipmi/bt-bmc.c80
-rw-r--r--drivers/char/ipmi/ipmi_devintf.c2
-rw-r--r--drivers/char/ipmi/ipmi_msghandler.c4
-rw-r--r--drivers/char/ipmi/ipmi_powernv.c2
-rw-r--r--drivers/char/ipmi/ipmi_watchdog.c2
-rw-r--r--include/linux/ipmi.h2
9 files changed, 69 insertions, 30 deletions
diff --git a/Documentation/IPMI.txt b/Documentation/IPMI.txt
index 72292308d0f5..6962cab997ef 100644
--- a/Documentation/IPMI.txt
+++ b/Documentation/IPMI.txt
@@ -257,7 +257,7 @@ and tell you when they come and go.
257 257
258Creating the User 258Creating the User
259 259
260To user the message handler, you must first create a user using 260To use the message handler, you must first create a user using
261ipmi_create_user. The interface number specifies which SMI you want 261ipmi_create_user. The interface number specifies which SMI you want
262to connect to, and you must supply callback functions to be called 262to connect to, and you must supply callback functions to be called
263when data comes in. The callback function can run at interrupt level, 263when data comes in. The callback function can run at interrupt level,
diff --git a/drivers/acpi/acpi_ipmi.c b/drivers/acpi/acpi_ipmi.c
index f77956c3fd45..747c2ba98534 100644
--- a/drivers/acpi/acpi_ipmi.c
+++ b/drivers/acpi/acpi_ipmi.c
@@ -56,7 +56,7 @@ struct acpi_ipmi_device {
56struct ipmi_driver_data { 56struct ipmi_driver_data {
57 struct list_head ipmi_devices; 57 struct list_head ipmi_devices;
58 struct ipmi_smi_watcher bmc_events; 58 struct ipmi_smi_watcher bmc_events;
59 struct ipmi_user_hndl ipmi_hndlrs; 59 const struct ipmi_user_hndl ipmi_hndlrs;
60 struct mutex ipmi_lock; 60 struct mutex ipmi_lock;
61 61
62 /* 62 /*
diff --git a/drivers/char/ipmi/Kconfig b/drivers/char/ipmi/Kconfig
index 7f816655cbbf..90f3edffb067 100644
--- a/drivers/char/ipmi/Kconfig
+++ b/drivers/char/ipmi/Kconfig
@@ -78,7 +78,8 @@ config IPMI_POWEROFF
78endif # IPMI_HANDLER 78endif # IPMI_HANDLER
79 79
80config ASPEED_BT_IPMI_BMC 80config ASPEED_BT_IPMI_BMC
81 depends on ARCH_ASPEED 81 depends on ARCH_ASPEED || COMPILE_TEST
82 depends on REGMAP && REGMAP_MMIO && MFD_SYSCON
82 tristate "BT IPMI bmc driver" 83 tristate "BT IPMI bmc driver"
83 help 84 help
84 Provides a driver for the BT (Block Transfer) IPMI interface 85 Provides a driver for the BT (Block Transfer) IPMI interface
diff --git a/drivers/char/ipmi/bt-bmc.c b/drivers/char/ipmi/bt-bmc.c
index fc9e8891eae3..d6f5d9eb102d 100644
--- a/drivers/char/ipmi/bt-bmc.c
+++ b/drivers/char/ipmi/bt-bmc.c
@@ -12,10 +12,13 @@
12#include <linux/errno.h> 12#include <linux/errno.h>
13#include <linux/interrupt.h> 13#include <linux/interrupt.h>
14#include <linux/io.h> 14#include <linux/io.h>
15#include <linux/mfd/syscon.h>
15#include <linux/miscdevice.h> 16#include <linux/miscdevice.h>
16#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/of.h>
17#include <linux/platform_device.h> 19#include <linux/platform_device.h>
18#include <linux/poll.h> 20#include <linux/poll.h>
21#include <linux/regmap.h>
19#include <linux/sched.h> 22#include <linux/sched.h>
20#include <linux/timer.h> 23#include <linux/timer.h>
21 24
@@ -60,7 +63,8 @@
60struct bt_bmc { 63struct bt_bmc {
61 struct device dev; 64 struct device dev;
62 struct miscdevice miscdev; 65 struct miscdevice miscdev;
63 void __iomem *base; 66 struct regmap *map;
67 int offset;
64 int irq; 68 int irq;
65 wait_queue_head_t queue; 69 wait_queue_head_t queue;
66 struct timer_list poll_timer; 70 struct timer_list poll_timer;
@@ -69,14 +73,29 @@ struct bt_bmc {
69 73
70static atomic_t open_count = ATOMIC_INIT(0); 74static atomic_t open_count = ATOMIC_INIT(0);
71 75
76static const struct regmap_config bt_regmap_cfg = {
77 .reg_bits = 32,
78 .val_bits = 32,
79 .reg_stride = 4,
80};
81
72static u8 bt_inb(struct bt_bmc *bt_bmc, int reg) 82static u8 bt_inb(struct bt_bmc *bt_bmc, int reg)
73{ 83{
74 return ioread8(bt_bmc->base + reg); 84 uint32_t val = 0;
85 int rc;
86
87 rc = regmap_read(bt_bmc->map, bt_bmc->offset + reg, &val);
88 WARN(rc != 0, "regmap_read() failed: %d\n", rc);
89
90 return rc == 0 ? (u8) val : 0;
75} 91}
76 92
77static void bt_outb(struct bt_bmc *bt_bmc, u8 data, int reg) 93static void bt_outb(struct bt_bmc *bt_bmc, u8 data, int reg)
78{ 94{
79 iowrite8(data, bt_bmc->base + reg); 95 int rc;
96
97 rc = regmap_write(bt_bmc->map, bt_bmc->offset + reg, data);
98 WARN(rc != 0, "regmap_write() failed: %d\n", rc);
80} 99}
81 100
82static void clr_rd_ptr(struct bt_bmc *bt_bmc) 101static void clr_rd_ptr(struct bt_bmc *bt_bmc)
@@ -367,14 +386,18 @@ static irqreturn_t bt_bmc_irq(int irq, void *arg)
367{ 386{
368 struct bt_bmc *bt_bmc = arg; 387 struct bt_bmc *bt_bmc = arg;
369 u32 reg; 388 u32 reg;
389 int rc;
390
391 rc = regmap_read(bt_bmc->map, bt_bmc->offset + BT_CR2, &reg);
392 if (rc)
393 return IRQ_NONE;
370 394
371 reg = ioread32(bt_bmc->base + BT_CR2);
372 reg &= BT_CR2_IRQ_H2B | BT_CR2_IRQ_HBUSY; 395 reg &= BT_CR2_IRQ_H2B | BT_CR2_IRQ_HBUSY;
373 if (!reg) 396 if (!reg)
374 return IRQ_NONE; 397 return IRQ_NONE;
375 398
376 /* ack pending IRQs */ 399 /* ack pending IRQs */
377 iowrite32(reg, bt_bmc->base + BT_CR2); 400 regmap_write(bt_bmc->map, bt_bmc->offset + BT_CR2, reg);
378 401
379 wake_up(&bt_bmc->queue); 402 wake_up(&bt_bmc->queue);
380 return IRQ_HANDLED; 403 return IRQ_HANDLED;
@@ -384,7 +407,6 @@ static int bt_bmc_config_irq(struct bt_bmc *bt_bmc,
384 struct platform_device *pdev) 407 struct platform_device *pdev)
385{ 408{
386 struct device *dev = &pdev->dev; 409 struct device *dev = &pdev->dev;
387 u32 reg;
388 int rc; 410 int rc;
389 411
390 bt_bmc->irq = platform_get_irq(pdev, 0); 412 bt_bmc->irq = platform_get_irq(pdev, 0);
@@ -405,18 +427,17 @@ static int bt_bmc_config_irq(struct bt_bmc *bt_bmc,
405 * will be cleared (along with B2H) when we can write the next 427 * will be cleared (along with B2H) when we can write the next
406 * message to the BT buffer 428 * message to the BT buffer
407 */ 429 */
408 reg = ioread32(bt_bmc->base + BT_CR1); 430 rc = regmap_update_bits(bt_bmc->map, bt_bmc->offset + BT_CR1,
409 reg |= BT_CR1_IRQ_H2B | BT_CR1_IRQ_HBUSY; 431 (BT_CR1_IRQ_H2B | BT_CR1_IRQ_HBUSY),
410 iowrite32(reg, bt_bmc->base + BT_CR1); 432 (BT_CR1_IRQ_H2B | BT_CR1_IRQ_HBUSY));
411 433
412 return 0; 434 return rc;
413} 435}
414 436
415static int bt_bmc_probe(struct platform_device *pdev) 437static int bt_bmc_probe(struct platform_device *pdev)
416{ 438{
417 struct bt_bmc *bt_bmc; 439 struct bt_bmc *bt_bmc;
418 struct device *dev; 440 struct device *dev;
419 struct resource *res;
420 int rc; 441 int rc;
421 442
422 if (!pdev || !pdev->dev.of_node) 443 if (!pdev || !pdev->dev.of_node)
@@ -431,10 +452,27 @@ static int bt_bmc_probe(struct platform_device *pdev)
431 452
432 dev_set_drvdata(&pdev->dev, bt_bmc); 453 dev_set_drvdata(&pdev->dev, bt_bmc);
433 454
434 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 455 bt_bmc->map = syscon_node_to_regmap(pdev->dev.parent->of_node);
435 bt_bmc->base = devm_ioremap_resource(&pdev->dev, res); 456 if (IS_ERR(bt_bmc->map)) {
436 if (IS_ERR(bt_bmc->base)) 457 struct resource *res;
437 return PTR_ERR(bt_bmc->base); 458 void __iomem *base;
459
460 /*
461 * Assume it's not the MFD-based devicetree description, in
462 * which case generate a regmap ourselves
463 */
464 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
465 base = devm_ioremap_resource(&pdev->dev, res);
466 if (IS_ERR(base))
467 return PTR_ERR(base);
468
469 bt_bmc->map = devm_regmap_init_mmio(dev, base, &bt_regmap_cfg);
470 bt_bmc->offset = 0;
471 } else {
472 rc = of_property_read_u32(dev->of_node, "reg", &bt_bmc->offset);
473 if (rc)
474 return rc;
475 }
438 476
439 mutex_init(&bt_bmc->mutex); 477 mutex_init(&bt_bmc->mutex);
440 init_waitqueue_head(&bt_bmc->queue); 478 init_waitqueue_head(&bt_bmc->queue);
@@ -461,12 +499,12 @@ static int bt_bmc_probe(struct platform_device *pdev)
461 add_timer(&bt_bmc->poll_timer); 499 add_timer(&bt_bmc->poll_timer);
462 } 500 }
463 501
464 iowrite32((BT_IO_BASE << BT_CR0_IO_BASE) | 502 regmap_write(bt_bmc->map, bt_bmc->offset + BT_CR0,
465 (BT_IRQ << BT_CR0_IRQ) | 503 (BT_IO_BASE << BT_CR0_IO_BASE) |
466 BT_CR0_EN_CLR_SLV_RDP | 504 (BT_IRQ << BT_CR0_IRQ) |
467 BT_CR0_EN_CLR_SLV_WRP | 505 BT_CR0_EN_CLR_SLV_RDP |
468 BT_CR0_ENABLE_IBT, 506 BT_CR0_EN_CLR_SLV_WRP |
469 bt_bmc->base + BT_CR0); 507 BT_CR0_ENABLE_IBT);
470 508
471 clr_b_busy(bt_bmc); 509 clr_b_busy(bt_bmc);
472 510
diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c
index a21407de46ae..f45119c5337d 100644
--- a/drivers/char/ipmi/ipmi_devintf.c
+++ b/drivers/char/ipmi/ipmi_devintf.c
@@ -108,7 +108,7 @@ static int ipmi_fasync(int fd, struct file *file, int on)
108 return (result); 108 return (result);
109} 109}
110 110
111static struct ipmi_user_hndl ipmi_hndlrs = 111static const struct ipmi_user_hndl ipmi_hndlrs =
112{ 112{
113 .ipmi_recv_hndl = file_receive_handler, 113 .ipmi_recv_hndl = file_receive_handler,
114}; 114};
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index 92e53acf2cd2..9f699951b75a 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -102,7 +102,7 @@ struct ipmi_user {
102 struct kref refcount; 102 struct kref refcount;
103 103
104 /* The upper layer that handles receive messages. */ 104 /* The upper layer that handles receive messages. */
105 struct ipmi_user_hndl *handler; 105 const struct ipmi_user_hndl *handler;
106 void *handler_data; 106 void *handler_data;
107 107
108 /* The interface this user is bound to. */ 108 /* The interface this user is bound to. */
@@ -919,7 +919,7 @@ static int intf_err_seq(ipmi_smi_t intf,
919 919
920 920
921int ipmi_create_user(unsigned int if_num, 921int ipmi_create_user(unsigned int if_num,
922 struct ipmi_user_hndl *handler, 922 const struct ipmi_user_hndl *handler,
923 void *handler_data, 923 void *handler_data,
924 ipmi_user_t *user) 924 ipmi_user_t *user)
925{ 925{
diff --git a/drivers/char/ipmi/ipmi_powernv.c b/drivers/char/ipmi/ipmi_powernv.c
index 6e658aa114f1..b338a4becbf8 100644
--- a/drivers/char/ipmi/ipmi_powernv.c
+++ b/drivers/char/ipmi/ipmi_powernv.c
@@ -196,7 +196,7 @@ static void ipmi_powernv_poll(void *send_info)
196 ipmi_powernv_recv(smi); 196 ipmi_powernv_recv(smi);
197} 197}
198 198
199static struct ipmi_smi_handlers ipmi_powernv_smi_handlers = { 199static const struct ipmi_smi_handlers ipmi_powernv_smi_handlers = {
200 .owner = THIS_MODULE, 200 .owner = THIS_MODULE,
201 .start_processing = ipmi_powernv_start_processing, 201 .start_processing = ipmi_powernv_start_processing,
202 .sender = ipmi_powernv_send, 202 .sender = ipmi_powernv_send,
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c
index 4035495f3a86..30b9e83bf1bf 100644
--- a/drivers/char/ipmi/ipmi_watchdog.c
+++ b/drivers/char/ipmi/ipmi_watchdog.c
@@ -985,7 +985,7 @@ static void ipmi_wdog_pretimeout_handler(void *handler_data)
985 pretimeout_since_last_heartbeat = 1; 985 pretimeout_since_last_heartbeat = 1;
986} 986}
987 987
988static struct ipmi_user_hndl ipmi_hndlrs = { 988static const struct ipmi_user_hndl ipmi_hndlrs = {
989 .ipmi_recv_hndl = ipmi_wdog_msg_handler, 989 .ipmi_recv_hndl = ipmi_wdog_msg_handler,
990 .ipmi_watchdog_pretimeout = ipmi_wdog_pretimeout_handler 990 .ipmi_watchdog_pretimeout = ipmi_wdog_pretimeout_handler
991}; 991};
diff --git a/include/linux/ipmi.h b/include/linux/ipmi.h
index 78c5d5ae3857..f1045b2c6a00 100644
--- a/include/linux/ipmi.h
+++ b/include/linux/ipmi.h
@@ -100,7 +100,7 @@ struct ipmi_user_hndl {
100 100
101/* Create a new user of the IPMI layer on the given interface number. */ 101/* Create a new user of the IPMI layer on the given interface number. */
102int ipmi_create_user(unsigned int if_num, 102int ipmi_create_user(unsigned int if_num,
103 struct ipmi_user_hndl *handler, 103 const struct ipmi_user_hndl *handler,
104 void *handler_data, 104 void *handler_data,
105 ipmi_user_t *user); 105 ipmi_user_t *user);
106 106