Commit 2d6be4ab authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'for-linus-4.11' of git://git.code.sf.net/p/openipmi/linux-ipmi

Pull IPMI updates from Corey Minyard:
 "This is a few small fixes to the main IPMI driver, make some things
  const, fix typos, etc.

  The last patch came in about a week ago, but IMHO it's best to go in
  now. It is not for the main driver, it's for the bt-bmc driver, which
  runs on the managment controller side, not on the host side, so the
  scope is limited and the change is necessary"

* tag 'for-linus-4.11' of git://git.code.sf.net/p/openipmi/linux-ipmi:
  ipmi: bt-bmc: Use a regmap for register access
  char: ipmi: constify ipmi_smi_handlers structures
  acpi:ipmi: Make IPMI user handler const
  ipmi: make ipmi_usr_hndl const
  Documentation: Fix a typo in IPMI.txt.
parents cf393195 eb994594
......@@ -257,7 +257,7 @@ and tell you when they come and go.
Creating the User
To user the message handler, you must first create a user using
To use the message handler, you must first create a user using
ipmi_create_user. The interface number specifies which SMI you want
to connect to, and you must supply callback functions to be called
when data comes in. The callback function can run at interrupt level,
......
......@@ -56,7 +56,7 @@ struct acpi_ipmi_device {
struct ipmi_driver_data {
struct list_head ipmi_devices;
struct ipmi_smi_watcher bmc_events;
struct ipmi_user_hndl ipmi_hndlrs;
const struct ipmi_user_hndl ipmi_hndlrs;
struct mutex ipmi_lock;
/*
......
......@@ -78,7 +78,8 @@ config IPMI_POWEROFF
endif # IPMI_HANDLER
config ASPEED_BT_IPMI_BMC
depends on ARCH_ASPEED
depends on ARCH_ASPEED || COMPILE_TEST
depends on REGMAP && REGMAP_MMIO && MFD_SYSCON
tristate "BT IPMI bmc driver"
help
Provides a driver for the BT (Block Transfer) IPMI interface
......
......@@ -12,10 +12,13 @@
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/mfd/syscon.h>
#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/poll.h>
#include <linux/regmap.h>
#include <linux/sched.h>
#include <linux/timer.h>
......@@ -60,7 +63,8 @@
struct bt_bmc {
struct device dev;
struct miscdevice miscdev;
void __iomem *base;
struct regmap *map;
int offset;
int irq;
wait_queue_head_t queue;
struct timer_list poll_timer;
......@@ -69,14 +73,29 @@ struct bt_bmc {
static atomic_t open_count = ATOMIC_INIT(0);
static const struct regmap_config bt_regmap_cfg = {
.reg_bits = 32,
.val_bits = 32,
.reg_stride = 4,
};
static u8 bt_inb(struct bt_bmc *bt_bmc, int reg)
{
return ioread8(bt_bmc->base + reg);
uint32_t val = 0;
int rc;
rc = regmap_read(bt_bmc->map, bt_bmc->offset + reg, &val);
WARN(rc != 0, "regmap_read() failed: %d\n", rc);
return rc == 0 ? (u8) val : 0;
}
static void bt_outb(struct bt_bmc *bt_bmc, u8 data, int reg)
{
iowrite8(data, bt_bmc->base + reg);
int rc;
rc = regmap_write(bt_bmc->map, bt_bmc->offset + reg, data);
WARN(rc != 0, "regmap_write() failed: %d\n", rc);
}
static void clr_rd_ptr(struct bt_bmc *bt_bmc)
......@@ -367,14 +386,18 @@ static irqreturn_t bt_bmc_irq(int irq, void *arg)
{
struct bt_bmc *bt_bmc = arg;
u32 reg;
int rc;
rc = regmap_read(bt_bmc->map, bt_bmc->offset + BT_CR2, &reg);
if (rc)
return IRQ_NONE;
reg = ioread32(bt_bmc->base + BT_CR2);
reg &= BT_CR2_IRQ_H2B | BT_CR2_IRQ_HBUSY;
if (!reg)
return IRQ_NONE;
/* ack pending IRQs */
iowrite32(reg, bt_bmc->base + BT_CR2);
regmap_write(bt_bmc->map, bt_bmc->offset + BT_CR2, reg);
wake_up(&bt_bmc->queue);
return IRQ_HANDLED;
......@@ -384,7 +407,6 @@ static int bt_bmc_config_irq(struct bt_bmc *bt_bmc,
struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
u32 reg;
int rc;
bt_bmc->irq = platform_get_irq(pdev, 0);
......@@ -405,18 +427,17 @@ static int bt_bmc_config_irq(struct bt_bmc *bt_bmc,
* will be cleared (along with B2H) when we can write the next
* message to the BT buffer
*/
reg = ioread32(bt_bmc->base + BT_CR1);
reg |= BT_CR1_IRQ_H2B | BT_CR1_IRQ_HBUSY;
iowrite32(reg, bt_bmc->base + BT_CR1);
rc = regmap_update_bits(bt_bmc->map, bt_bmc->offset + BT_CR1,
(BT_CR1_IRQ_H2B | BT_CR1_IRQ_HBUSY),
(BT_CR1_IRQ_H2B | BT_CR1_IRQ_HBUSY));
return 0;
return rc;
}
static int bt_bmc_probe(struct platform_device *pdev)
{
struct bt_bmc *bt_bmc;
struct device *dev;
struct resource *res;
int rc;
if (!pdev || !pdev->dev.of_node)
......@@ -431,10 +452,27 @@ static int bt_bmc_probe(struct platform_device *pdev)
dev_set_drvdata(&pdev->dev, bt_bmc);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
bt_bmc->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(bt_bmc->base))
return PTR_ERR(bt_bmc->base);
bt_bmc->map = syscon_node_to_regmap(pdev->dev.parent->of_node);
if (IS_ERR(bt_bmc->map)) {
struct resource *res;
void __iomem *base;
/*
* Assume it's not the MFD-based devicetree description, in
* which case generate a regmap ourselves
*/
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(base))
return PTR_ERR(base);
bt_bmc->map = devm_regmap_init_mmio(dev, base, &bt_regmap_cfg);
bt_bmc->offset = 0;
} else {
rc = of_property_read_u32(dev->of_node, "reg", &bt_bmc->offset);
if (rc)
return rc;
}
mutex_init(&bt_bmc->mutex);
init_waitqueue_head(&bt_bmc->queue);
......@@ -461,12 +499,12 @@ static int bt_bmc_probe(struct platform_device *pdev)
add_timer(&bt_bmc->poll_timer);
}
iowrite32((BT_IO_BASE << BT_CR0_IO_BASE) |
(BT_IRQ << BT_CR0_IRQ) |
BT_CR0_EN_CLR_SLV_RDP |
BT_CR0_EN_CLR_SLV_WRP |
BT_CR0_ENABLE_IBT,
bt_bmc->base + BT_CR0);
regmap_write(bt_bmc->map, bt_bmc->offset + BT_CR0,
(BT_IO_BASE << BT_CR0_IO_BASE) |
(BT_IRQ << BT_CR0_IRQ) |
BT_CR0_EN_CLR_SLV_RDP |
BT_CR0_EN_CLR_SLV_WRP |
BT_CR0_ENABLE_IBT);
clr_b_busy(bt_bmc);
......
......@@ -108,7 +108,7 @@ static int ipmi_fasync(int fd, struct file *file, int on)
return (result);
}
static struct ipmi_user_hndl ipmi_hndlrs =
static const struct ipmi_user_hndl ipmi_hndlrs =
{
.ipmi_recv_hndl = file_receive_handler,
};
......
......@@ -102,7 +102,7 @@ struct ipmi_user {
struct kref refcount;
/* The upper layer that handles receive messages. */
struct ipmi_user_hndl *handler;
const struct ipmi_user_hndl *handler;
void *handler_data;
/* The interface this user is bound to. */
......@@ -919,7 +919,7 @@ static int intf_err_seq(ipmi_smi_t intf,
int ipmi_create_user(unsigned int if_num,
struct ipmi_user_hndl *handler,
const struct ipmi_user_hndl *handler,
void *handler_data,
ipmi_user_t *user)
{
......
......@@ -196,7 +196,7 @@ static void ipmi_powernv_poll(void *send_info)
ipmi_powernv_recv(smi);
}
static struct ipmi_smi_handlers ipmi_powernv_smi_handlers = {
static const struct ipmi_smi_handlers ipmi_powernv_smi_handlers = {
.owner = THIS_MODULE,
.start_processing = ipmi_powernv_start_processing,
.sender = ipmi_powernv_send,
......
......@@ -985,7 +985,7 @@ static void ipmi_wdog_pretimeout_handler(void *handler_data)
pretimeout_since_last_heartbeat = 1;
}
static struct ipmi_user_hndl ipmi_hndlrs = {
static const struct ipmi_user_hndl ipmi_hndlrs = {
.ipmi_recv_hndl = ipmi_wdog_msg_handler,
.ipmi_watchdog_pretimeout = ipmi_wdog_pretimeout_handler
};
......
......@@ -100,7 +100,7 @@ struct ipmi_user_hndl {
/* Create a new user of the IPMI layer on the given interface number. */
int ipmi_create_user(unsigned int if_num,
struct ipmi_user_hndl *handler,
const struct ipmi_user_hndl *handler,
void *handler_data,
ipmi_user_t *user);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment