提交 2d6be4ab 编写于 作者: L 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.
...@@ -257,7 +257,7 @@ and tell you when they come and go. ...@@ -257,7 +257,7 @@ and tell you when they come and go.
Creating the User 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 ipmi_create_user. The interface number specifies which SMI you want
to connect to, and you must supply callback functions to be called to connect to, and you must supply callback functions to be called
when data comes in. The callback function can run at interrupt level, when data comes in. The callback function can run at interrupt level,
......
...@@ -56,7 +56,7 @@ struct acpi_ipmi_device { ...@@ -56,7 +56,7 @@ struct acpi_ipmi_device {
struct ipmi_driver_data { struct ipmi_driver_data {
struct list_head ipmi_devices; struct list_head ipmi_devices;
struct ipmi_smi_watcher bmc_events; struct ipmi_smi_watcher bmc_events;
struct ipmi_user_hndl ipmi_hndlrs; const struct ipmi_user_hndl ipmi_hndlrs;
struct mutex ipmi_lock; struct mutex ipmi_lock;
/* /*
......
...@@ -78,7 +78,8 @@ config IPMI_POWEROFF ...@@ -78,7 +78,8 @@ config IPMI_POWEROFF
endif # IPMI_HANDLER endif # IPMI_HANDLER
config ASPEED_BT_IPMI_BMC 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" tristate "BT IPMI bmc driver"
help help
Provides a driver for the BT (Block Transfer) IPMI interface Provides a driver for the BT (Block Transfer) IPMI interface
......
...@@ -12,10 +12,13 @@ ...@@ -12,10 +12,13 @@
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/mfd/syscon.h>
#include <linux/miscdevice.h> #include <linux/miscdevice.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/poll.h> #include <linux/poll.h>
#include <linux/regmap.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/timer.h> #include <linux/timer.h>
...@@ -60,7 +63,8 @@ ...@@ -60,7 +63,8 @@
struct bt_bmc { struct bt_bmc {
struct device dev; struct device dev;
struct miscdevice miscdev; struct miscdevice miscdev;
void __iomem *base; struct regmap *map;
int offset;
int irq; int irq;
wait_queue_head_t queue; wait_queue_head_t queue;
struct timer_list poll_timer; struct timer_list poll_timer;
...@@ -69,14 +73,29 @@ struct bt_bmc { ...@@ -69,14 +73,29 @@ struct bt_bmc {
static atomic_t open_count = ATOMIC_INIT(0); 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) 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) 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) static void clr_rd_ptr(struct bt_bmc *bt_bmc)
...@@ -367,14 +386,18 @@ static irqreturn_t bt_bmc_irq(int irq, void *arg) ...@@ -367,14 +386,18 @@ static irqreturn_t bt_bmc_irq(int irq, void *arg)
{ {
struct bt_bmc *bt_bmc = arg; struct bt_bmc *bt_bmc = arg;
u32 reg; 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; reg &= BT_CR2_IRQ_H2B | BT_CR2_IRQ_HBUSY;
if (!reg) if (!reg)
return IRQ_NONE; return IRQ_NONE;
/* ack pending IRQs */ /* 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); wake_up(&bt_bmc->queue);
return IRQ_HANDLED; return IRQ_HANDLED;
...@@ -384,7 +407,6 @@ static int bt_bmc_config_irq(struct bt_bmc *bt_bmc, ...@@ -384,7 +407,6 @@ static int bt_bmc_config_irq(struct bt_bmc *bt_bmc,
struct platform_device *pdev) struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
u32 reg;
int rc; int rc;
bt_bmc->irq = platform_get_irq(pdev, 0); bt_bmc->irq = platform_get_irq(pdev, 0);
...@@ -405,18 +427,17 @@ static int bt_bmc_config_irq(struct bt_bmc *bt_bmc, ...@@ -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 * will be cleared (along with B2H) when we can write the next
* message to the BT buffer * message to the BT buffer
*/ */
reg = ioread32(bt_bmc->base + BT_CR1); rc = regmap_update_bits(bt_bmc->map, bt_bmc->offset + BT_CR1,
reg |= BT_CR1_IRQ_H2B | BT_CR1_IRQ_HBUSY; (BT_CR1_IRQ_H2B | BT_CR1_IRQ_HBUSY),
iowrite32(reg, bt_bmc->base + BT_CR1); (BT_CR1_IRQ_H2B | BT_CR1_IRQ_HBUSY));
return 0; return rc;
} }
static int bt_bmc_probe(struct platform_device *pdev) static int bt_bmc_probe(struct platform_device *pdev)
{ {
struct bt_bmc *bt_bmc; struct bt_bmc *bt_bmc;
struct device *dev; struct device *dev;
struct resource *res;
int rc; int rc;
if (!pdev || !pdev->dev.of_node) if (!pdev || !pdev->dev.of_node)
...@@ -431,10 +452,27 @@ static int bt_bmc_probe(struct platform_device *pdev) ...@@ -431,10 +452,27 @@ static int bt_bmc_probe(struct platform_device *pdev)
dev_set_drvdata(&pdev->dev, bt_bmc); dev_set_drvdata(&pdev->dev, bt_bmc);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); bt_bmc->map = syscon_node_to_regmap(pdev->dev.parent->of_node);
bt_bmc->base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(bt_bmc->map)) {
if (IS_ERR(bt_bmc->base)) struct resource *res;
return PTR_ERR(bt_bmc->base); 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); mutex_init(&bt_bmc->mutex);
init_waitqueue_head(&bt_bmc->queue); init_waitqueue_head(&bt_bmc->queue);
...@@ -461,12 +499,12 @@ static int bt_bmc_probe(struct platform_device *pdev) ...@@ -461,12 +499,12 @@ static int bt_bmc_probe(struct platform_device *pdev)
add_timer(&bt_bmc->poll_timer); add_timer(&bt_bmc->poll_timer);
} }
iowrite32((BT_IO_BASE << BT_CR0_IO_BASE) | regmap_write(bt_bmc->map, bt_bmc->offset + BT_CR0,
(BT_IRQ << BT_CR0_IRQ) | (BT_IO_BASE << BT_CR0_IO_BASE) |
BT_CR0_EN_CLR_SLV_RDP | (BT_IRQ << BT_CR0_IRQ) |
BT_CR0_EN_CLR_SLV_WRP | BT_CR0_EN_CLR_SLV_RDP |
BT_CR0_ENABLE_IBT, BT_CR0_EN_CLR_SLV_WRP |
bt_bmc->base + BT_CR0); BT_CR0_ENABLE_IBT);
clr_b_busy(bt_bmc); clr_b_busy(bt_bmc);
......
...@@ -108,7 +108,7 @@ static int ipmi_fasync(int fd, struct file *file, int on) ...@@ -108,7 +108,7 @@ static int ipmi_fasync(int fd, struct file *file, int on)
return (result); return (result);
} }
static struct ipmi_user_hndl ipmi_hndlrs = static const struct ipmi_user_hndl ipmi_hndlrs =
{ {
.ipmi_recv_hndl = file_receive_handler, .ipmi_recv_hndl = file_receive_handler,
}; };
......
...@@ -102,7 +102,7 @@ struct ipmi_user { ...@@ -102,7 +102,7 @@ struct ipmi_user {
struct kref refcount; struct kref refcount;
/* The upper layer that handles receive messages. */ /* The upper layer that handles receive messages. */
struct ipmi_user_hndl *handler; const struct ipmi_user_hndl *handler;
void *handler_data; void *handler_data;
/* The interface this user is bound to. */ /* The interface this user is bound to. */
...@@ -919,7 +919,7 @@ static int intf_err_seq(ipmi_smi_t intf, ...@@ -919,7 +919,7 @@ static int intf_err_seq(ipmi_smi_t intf,
int ipmi_create_user(unsigned int if_num, int ipmi_create_user(unsigned int if_num,
struct ipmi_user_hndl *handler, const struct ipmi_user_hndl *handler,
void *handler_data, void *handler_data,
ipmi_user_t *user) ipmi_user_t *user)
{ {
......
...@@ -196,7 +196,7 @@ static void ipmi_powernv_poll(void *send_info) ...@@ -196,7 +196,7 @@ static void ipmi_powernv_poll(void *send_info)
ipmi_powernv_recv(smi); 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, .owner = THIS_MODULE,
.start_processing = ipmi_powernv_start_processing, .start_processing = ipmi_powernv_start_processing,
.sender = ipmi_powernv_send, .sender = ipmi_powernv_send,
......
...@@ -985,7 +985,7 @@ static void ipmi_wdog_pretimeout_handler(void *handler_data) ...@@ -985,7 +985,7 @@ static void ipmi_wdog_pretimeout_handler(void *handler_data)
pretimeout_since_last_heartbeat = 1; 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_recv_hndl = ipmi_wdog_msg_handler,
.ipmi_watchdog_pretimeout = ipmi_wdog_pretimeout_handler .ipmi_watchdog_pretimeout = ipmi_wdog_pretimeout_handler
}; };
......
...@@ -100,7 +100,7 @@ struct ipmi_user_hndl { ...@@ -100,7 +100,7 @@ struct ipmi_user_hndl {
/* Create a new user of the IPMI layer on the given interface number. */ /* Create a new user of the IPMI layer on the given interface number. */
int ipmi_create_user(unsigned int if_num, int ipmi_create_user(unsigned int if_num,
struct ipmi_user_hndl *handler, const struct ipmi_user_hndl *handler,
void *handler_data, void *handler_data,
ipmi_user_t *user); ipmi_user_t *user);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册