Skip to content

Commit

Permalink
Merge tag 'for-linus-4.11' of git://git.code.sf.net/p/openipmi/linux-…
Browse files Browse the repository at this point in the history
…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.
  • Loading branch information
torvalds committed Mar 1, 2017
2 parents cf39319 + eb99459 commit 2d6be4a
Show file tree
Hide file tree
Showing 9 changed files with 69 additions and 30 deletions.
2 changes: 1 addition & 1 deletion Documentation/IPMI.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion drivers/acpi/acpi_ipmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/*
Expand Down
3 changes: 2 additions & 1 deletion drivers/char/ipmi/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
80 changes: 59 additions & 21 deletions drivers/char/ipmi/bt-bmc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>

Expand Down Expand Up @@ -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;
Expand All @@ -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)
Expand Down Expand Up @@ -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;
Expand All @@ -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);
Expand All @@ -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)
Expand All @@ -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);
Expand All @@ -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);

Expand Down
2 changes: 1 addition & 1 deletion drivers/char/ipmi/ipmi_devintf.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};
Expand Down
4 changes: 2 additions & 2 deletions drivers/char/ipmi/ipmi_msghandler.c
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand Down Expand Up @@ -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)
{
Expand Down
2 changes: 1 addition & 1 deletion drivers/char/ipmi/ipmi_powernv.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion drivers/char/ipmi/ipmi_watchdog.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
};
Expand Down
2 changes: 1 addition & 1 deletion include/linux/ipmi.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down

0 comments on commit 2d6be4a

Please sign in to comment.