linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [RFC 1/5] ipmi:bt-bmc: Separate out ASPEED specific bits
@ 2021-10-06  2:12 Anton Blanchard
  2021-10-06  2:12 ` [RFC 2/5] ipmi:bt-bmc: Prefix ASPEED specific registers with ASPEED_ Anton Blanchard
                   ` (4 more replies)
  0 siblings, 5 replies; 10+ messages in thread
From: Anton Blanchard @ 2021-10-06  2:12 UTC (permalink / raw)
  To: alistair, joel, andrew, clg, mikey, jk; +Cc: linuxppc-dev

Most of the IPMI BT BMC driver is architecture agnostic - it deals with
architected registers and behaviour in the IPMI specification.

Separate out the few ASPEED specific bits into their own functions
so we can use this driver on other architectures.

Signed-off-by: Anton Blanchard <anton@ozlabs.org>
---
 drivers/char/ipmi/bt-bmc.c | 26 ++++++++++++++++----------
 1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/drivers/char/ipmi/bt-bmc.c b/drivers/char/ipmi/bt-bmc.c
index 6e3d247b55d1..f85fafc96ef6 100644
--- a/drivers/char/ipmi/bt-bmc.c
+++ b/drivers/char/ipmi/bt-bmc.c
@@ -39,6 +39,7 @@
 #define   BT_CR2_IRQ_H2B	0x01
 #define   BT_CR2_IRQ_HBUSY	0x40
 #define BT_CR3		0xc
+
 #define BT_CTRL		0x10
 #define   BT_CTRL_B_BUSY		0x80
 #define   BT_CTRL_H_BUSY		0x40
@@ -372,7 +373,7 @@ static void poll_timer(struct timer_list *t)
 	add_timer(&bt_bmc->poll_timer);
 }
 
-static irqreturn_t bt_bmc_irq(int irq, void *arg)
+static irqreturn_t aspeed_bt_bmc_irq(int irq, void *arg)
 {
 	struct bt_bmc *bt_bmc = arg;
 	u32 reg;
@@ -393,7 +394,7 @@ static irqreturn_t bt_bmc_irq(int irq, void *arg)
 	return IRQ_HANDLED;
 }
 
-static int bt_bmc_config_irq(struct bt_bmc *bt_bmc,
+static int aspeed_bt_bmc_config_irq(struct bt_bmc *bt_bmc,
 			     struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -403,7 +404,7 @@ static int bt_bmc_config_irq(struct bt_bmc *bt_bmc,
 	if (bt_bmc->irq < 0)
 		return bt_bmc->irq;
 
-	rc = devm_request_irq(dev, bt_bmc->irq, bt_bmc_irq, IRQF_SHARED,
+	rc = devm_request_irq(dev, bt_bmc->irq, aspeed_bt_bmc_irq, IRQF_SHARED,
 			      DEVICE_NAME, bt_bmc);
 	if (rc < 0) {
 		dev_warn(dev, "Unable to request IRQ %d\n", bt_bmc->irq);
@@ -424,6 +425,16 @@ static int bt_bmc_config_irq(struct bt_bmc *bt_bmc,
 	return rc;
 }
 
+static void aspeed_enable_bt(struct bt_bmc *bt_bmc)
+{
+	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);
+}
+
 static int bt_bmc_probe(struct platform_device *pdev)
 {
 	struct bt_bmc *bt_bmc;
@@ -472,7 +483,7 @@ static int bt_bmc_probe(struct platform_device *pdev)
 		return rc;
 	}
 
-	bt_bmc_config_irq(bt_bmc, pdev);
+	aspeed_bt_bmc_config_irq(bt_bmc, pdev);
 
 	if (bt_bmc->irq >= 0) {
 		dev_info(dev, "Using IRQ %d\n", bt_bmc->irq);
@@ -483,12 +494,7 @@ static int bt_bmc_probe(struct platform_device *pdev)
 		add_timer(&bt_bmc->poll_timer);
 	}
 
-	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);
+	aspeed_enable_bt(bt_bmc);
 
 	clr_b_busy(bt_bmc);
 
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [RFC 2/5] ipmi:bt-bmc: Prefix ASPEED specific registers with ASPEED_
  2021-10-06  2:12 [RFC 1/5] ipmi:bt-bmc: Separate out ASPEED specific bits Anton Blanchard
@ 2021-10-06  2:12 ` Anton Blanchard
  2021-10-06  2:12 ` [RFC 3/5] ipmi:bt-bmc: Put arch specific function into bt_bmc_ops Anton Blanchard
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 10+ messages in thread
From: Anton Blanchard @ 2021-10-06  2:12 UTC (permalink / raw)
  To: alistair, joel, andrew, clg, mikey, jk; +Cc: linuxppc-dev

Signed-off-by: Anton Blanchard <anton@ozlabs.org>
---
 drivers/char/ipmi/bt-bmc.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/char/ipmi/bt-bmc.c b/drivers/char/ipmi/bt-bmc.c
index f85fafc96ef6..2b0fe1255026 100644
--- a/drivers/char/ipmi/bt-bmc.c
+++ b/drivers/char/ipmi/bt-bmc.c
@@ -26,19 +26,19 @@
 #define BT_IO_BASE	0xe4
 #define BT_IRQ		10
 
-#define BT_CR0		0x0
+#define ASPEED_BT_CR0	0x0
 #define   BT_CR0_IO_BASE		16
 #define   BT_CR0_IRQ			12
 #define   BT_CR0_EN_CLR_SLV_RDP		0x8
 #define   BT_CR0_EN_CLR_SLV_WRP		0x4
 #define   BT_CR0_ENABLE_IBT		0x1
-#define BT_CR1		0x4
+#define ASPEED_BT_CR1	0x4
 #define   BT_CR1_IRQ_H2B	0x01
 #define   BT_CR1_IRQ_HBUSY	0x40
-#define BT_CR2		0x8
+#define ASPEED_BT_CR2	0x8
 #define   BT_CR2_IRQ_H2B	0x01
 #define   BT_CR2_IRQ_HBUSY	0x40
-#define BT_CR3		0xc
+#define ASPEED_BT_CR3	0xc
 
 #define BT_CTRL		0x10
 #define   BT_CTRL_B_BUSY		0x80
@@ -379,7 +379,7 @@ static irqreturn_t aspeed_bt_bmc_irq(int irq, void *arg)
 	u32 reg;
 	int rc;
 
-	rc = regmap_read(bt_bmc->map, bt_bmc->offset + BT_CR2, &reg);
+	rc = regmap_read(bt_bmc->map, bt_bmc->offset + ASPEED_BT_CR2, &reg);
 	if (rc)
 		return IRQ_NONE;
 
@@ -388,7 +388,7 @@ static irqreturn_t aspeed_bt_bmc_irq(int irq, void *arg)
 		return IRQ_NONE;
 
 	/* ack pending IRQs */
-	regmap_write(bt_bmc->map, bt_bmc->offset + BT_CR2, reg);
+	regmap_write(bt_bmc->map, bt_bmc->offset + ASPEED_BT_CR2, reg);
 
 	wake_up(&bt_bmc->queue);
 	return IRQ_HANDLED;
@@ -418,7 +418,7 @@ static int aspeed_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
 	 */
-	rc = regmap_update_bits(bt_bmc->map, bt_bmc->offset + BT_CR1,
+	rc = regmap_update_bits(bt_bmc->map, bt_bmc->offset + ASPEED_BT_CR1,
 				(BT_CR1_IRQ_H2B | BT_CR1_IRQ_HBUSY),
 				(BT_CR1_IRQ_H2B | BT_CR1_IRQ_HBUSY));
 
@@ -427,7 +427,7 @@ static int aspeed_bt_bmc_config_irq(struct bt_bmc *bt_bmc,
 
 static void aspeed_enable_bt(struct bt_bmc *bt_bmc)
 {
-	regmap_write(bt_bmc->map, bt_bmc->offset + BT_CR0,
+	regmap_write(bt_bmc->map, bt_bmc->offset + ASPEED_BT_CR0,
 		     (BT_IO_BASE << BT_CR0_IO_BASE) |
 		     (BT_IRQ << BT_CR0_IRQ) |
 		     BT_CR0_EN_CLR_SLV_RDP |
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [RFC 3/5] ipmi:bt-bmc: Put arch specific function into bt_bmc_ops
  2021-10-06  2:12 [RFC 1/5] ipmi:bt-bmc: Separate out ASPEED specific bits Anton Blanchard
  2021-10-06  2:12 ` [RFC 2/5] ipmi:bt-bmc: Prefix ASPEED specific registers with ASPEED_ Anton Blanchard
@ 2021-10-06  2:12 ` Anton Blanchard
  2021-10-06  6:01   ` Cédric Le Goater
  2021-10-06  2:12 ` [RFC 4/5] ipmi:bt-bmc: No longer ASPEED specific Anton Blanchard
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 10+ messages in thread
From: Anton Blanchard @ 2021-10-06  2:12 UTC (permalink / raw)
  To: alistair, joel, andrew, clg, mikey, jk; +Cc: linuxppc-dev

While most of the driver is arch agnostic, setting up and handling
interrupts, and enabling the hardware is not. Create bt_bmc_ops to
handle these functions.

Signed-off-by: Anton Blanchard <anton@ozlabs.org>
---
 drivers/char/ipmi/bt-bmc.c | 24 ++++++++++++++++++++----
 1 file changed, 20 insertions(+), 4 deletions(-)

diff --git a/drivers/char/ipmi/bt-bmc.c b/drivers/char/ipmi/bt-bmc.c
index 2b0fe1255026..b48e04405ac4 100644
--- a/drivers/char/ipmi/bt-bmc.c
+++ b/drivers/char/ipmi/bt-bmc.c
@@ -17,6 +17,7 @@
 #include <linux/regmap.h>
 #include <linux/sched.h>
 #include <linux/timer.h>
+#include <linux/of_device.h>
 
 /*
  * This is a BMC device used to communicate to the host
@@ -435,15 +436,30 @@ static void aspeed_enable_bt(struct bt_bmc *bt_bmc)
 		     BT_CR0_ENABLE_IBT);
 }
 
+struct bt_bmc_ops {
+	int (*config_irq)(struct bt_bmc *bt_bmc, struct platform_device *pdev);
+	void (*enable_bt)(struct bt_bmc *bt_bmc);
+};
+
+static const struct bt_bmc_ops aspeed_bt_bmc_ops = {
+	.config_irq = aspeed_bt_bmc_config_irq,
+	.enable_bt = aspeed_enable_bt,
+};
+
 static int bt_bmc_probe(struct platform_device *pdev)
 {
 	struct bt_bmc *bt_bmc;
 	struct device *dev;
 	int rc;
+	const struct bt_bmc_ops *ops;
 
 	dev = &pdev->dev;
 	dev_info(dev, "Found bt bmc device\n");
 
+	ops = of_device_get_match_data(&pdev->dev);
+	if (!ops)
+		return -ENODEV;
+
 	bt_bmc = devm_kzalloc(dev, sizeof(*bt_bmc), GFP_KERNEL);
 	if (!bt_bmc)
 		return -ENOMEM;
@@ -483,7 +499,7 @@ static int bt_bmc_probe(struct platform_device *pdev)
 		return rc;
 	}
 
-	aspeed_bt_bmc_config_irq(bt_bmc, pdev);
+	ops->config_irq(bt_bmc, pdev);
 
 	if (bt_bmc->irq >= 0) {
 		dev_info(dev, "Using IRQ %d\n", bt_bmc->irq);
@@ -494,7 +510,7 @@ static int bt_bmc_probe(struct platform_device *pdev)
 		add_timer(&bt_bmc->poll_timer);
 	}
 
-	aspeed_enable_bt(bt_bmc);
+	ops->enable_bt(bt_bmc);
 
 	clr_b_busy(bt_bmc);
 
@@ -512,8 +528,8 @@ static int bt_bmc_remove(struct platform_device *pdev)
 }
 
 static const struct of_device_id bt_bmc_match[] = {
-	{ .compatible = "aspeed,ast2400-ibt-bmc" },
-	{ .compatible = "aspeed,ast2500-ibt-bmc" },
+	{ .compatible = "aspeed,ast2400-ibt-bmc", .data = &aspeed_bt_bmc_ops },
+	{ .compatible = "aspeed,ast2500-ibt-bmc", .data = &aspeed_bt_bmc_ops },
 	{ },
 };
 
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [RFC 4/5] ipmi:bt-bmc: No longer ASPEED specific
  2021-10-06  2:12 [RFC 1/5] ipmi:bt-bmc: Separate out ASPEED specific bits Anton Blanchard
  2021-10-06  2:12 ` [RFC 2/5] ipmi:bt-bmc: Prefix ASPEED specific registers with ASPEED_ Anton Blanchard
  2021-10-06  2:12 ` [RFC 3/5] ipmi:bt-bmc: Put arch specific function into bt_bmc_ops Anton Blanchard
@ 2021-10-06  2:12 ` Anton Blanchard
  2021-10-06  2:12 ` [RFC 5/5] ipmi:bt-bmc: Add Microwatt Anton Blanchard
  2021-10-06  6:02 ` [RFC 1/5] ipmi:bt-bmc: Separate out ASPEED specific bits Cédric Le Goater
  4 siblings, 0 replies; 10+ messages in thread
From: Anton Blanchard @ 2021-10-06  2:12 UTC (permalink / raw)
  To: alistair, joel, andrew, clg, mikey, jk; +Cc: linuxppc-dev

The driver is no longer specific to ASPEED, so rename the config option
and remove the dependency on ARCH_ASPEED.

Signed-off-by: Anton Blanchard <anton@ozlabs.org>
---
 .../bindings/ipmi/{aspeed,ast2400-ibt-bmc.txt => ibt-bmc.txt}   | 2 +-
 arch/arm/configs/aspeed_g4_defconfig                            | 2 +-
 arch/arm/configs/aspeed_g5_defconfig                            | 2 +-
 arch/arm/configs/multi_v5_defconfig                             | 2 +-
 arch/arm/configs/multi_v7_defconfig                             | 2 +-
 drivers/char/ipmi/Kconfig                                       | 2 +-
 drivers/char/ipmi/Makefile                                      | 2 +-
 7 files changed, 7 insertions(+), 7 deletions(-)
 rename Documentation/devicetree/bindings/ipmi/{aspeed,ast2400-ibt-bmc.txt => ibt-bmc.txt} (93%)

diff --git a/Documentation/devicetree/bindings/ipmi/aspeed,ast2400-ibt-bmc.txt b/Documentation/devicetree/bindings/ipmi/ibt-bmc.txt
similarity index 93%
rename from Documentation/devicetree/bindings/ipmi/aspeed,ast2400-ibt-bmc.txt
rename to Documentation/devicetree/bindings/ipmi/ibt-bmc.txt
index 028268fd99ee..78ee716a950e 100644
--- a/Documentation/devicetree/bindings/ipmi/aspeed,ast2400-ibt-bmc.txt
+++ b/Documentation/devicetree/bindings/ipmi/ibt-bmc.txt
@@ -1,4 +1,4 @@
-* Aspeed BT (Block Transfer) IPMI interface
+* BT (Block Transfer) IPMI interface
 
 The Aspeed SOCs (AST2400 and AST2500) are commonly used as BMCs
 (BaseBoard Management Controllers) and the BT interface can be used to
diff --git a/arch/arm/configs/aspeed_g4_defconfig b/arch/arm/configs/aspeed_g4_defconfig
index acaafa351d08..51696ba49c80 100644
--- a/arch/arm/configs/aspeed_g4_defconfig
+++ b/arch/arm/configs/aspeed_g4_defconfig
@@ -124,7 +124,7 @@ CONFIG_SERIAL_8250_ASPEED_VUART=y
 CONFIG_SERIAL_8250_SHARE_IRQ=y
 CONFIG_SERIAL_OF_PLATFORM=y
 CONFIG_ASPEED_KCS_IPMI_BMC=y
-CONFIG_ASPEED_BT_IPMI_BMC=y
+CONFIG_BT_IPMI_BMC=y
 CONFIG_HW_RANDOM_TIMERIOMEM=y
 # CONFIG_I2C_COMPAT is not set
 CONFIG_I2C_CHARDEV=y
diff --git a/arch/arm/configs/aspeed_g5_defconfig b/arch/arm/configs/aspeed_g5_defconfig
index 480dbbb4ff91..758dac62f34f 100644
--- a/arch/arm/configs/aspeed_g5_defconfig
+++ b/arch/arm/configs/aspeed_g5_defconfig
@@ -141,7 +141,7 @@ CONFIG_SERIAL_8250_DW=y
 CONFIG_SERIAL_OF_PLATFORM=y
 CONFIG_ASPEED_KCS_IPMI_BMC=y
 CONFIG_IPMI_KCS_BMC_SERIO=y
-CONFIG_ASPEED_BT_IPMI_BMC=y
+CONFIG_BT_IPMI_BMC=y
 CONFIG_HW_RANDOM_TIMERIOMEM=y
 # CONFIG_I2C_COMPAT is not set
 CONFIG_I2C_CHARDEV=y
diff --git a/arch/arm/configs/multi_v5_defconfig b/arch/arm/configs/multi_v5_defconfig
index 80a3ae02d759..f3ed5da74dfa 100644
--- a/arch/arm/configs/multi_v5_defconfig
+++ b/arch/arm/configs/multi_v5_defconfig
@@ -150,7 +150,7 @@ CONFIG_SERIAL_ATMEL_TTYAT=y
 CONFIG_SERIAL_IMX=y
 CONFIG_SERIAL_IMX_CONSOLE=y
 CONFIG_ASPEED_KCS_IPMI_BMC=m
-CONFIG_ASPEED_BT_IPMI_BMC=m
+CONFIG_BT_IPMI_BMC=m
 CONFIG_HW_RANDOM=y
 CONFIG_HW_RANDOM_TIMERIOMEM=m
 # CONFIG_I2C_COMPAT is not set
diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index ba67c4717dcc..03e97d95c251 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -384,7 +384,7 @@ CONFIG_SERIAL_OWL_CONSOLE=y
 CONFIG_SERIAL_DEV_BUS=y
 CONFIG_VIRTIO_CONSOLE=y
 CONFIG_ASPEED_KCS_IPMI_BMC=m
-CONFIG_ASPEED_BT_IPMI_BMC=m
+CONFIG_BT_IPMI_BMC=m
 CONFIG_HW_RANDOM=y
 CONFIG_HW_RANDOM_ST=y
 CONFIG_TCG_TPM=m
diff --git a/drivers/char/ipmi/Kconfig b/drivers/char/ipmi/Kconfig
index 249b31197eea..8b2f0f675e5f 100644
--- a/drivers/char/ipmi/Kconfig
+++ b/drivers/char/ipmi/Kconfig
@@ -151,7 +151,7 @@ config IPMI_KCS_BMC_SERIO
 	  This support is also available as a module. The module will be
 	  called kcs_bmc_serio.
 
-config ASPEED_BT_IPMI_BMC
+config BT_IPMI_BMC
 	depends on ARCH_ASPEED || COMPILE_TEST
 	depends on REGMAP && REGMAP_MMIO && MFD_SYSCON
 	tristate "BT IPMI bmc driver"
diff --git a/drivers/char/ipmi/Makefile b/drivers/char/ipmi/Makefile
index 84f47d18007f..75c71cbd568b 100644
--- a/drivers/char/ipmi/Makefile
+++ b/drivers/char/ipmi/Makefile
@@ -25,7 +25,7 @@ obj-$(CONFIG_IPMI_POWEROFF) += ipmi_poweroff.o
 obj-$(CONFIG_IPMI_KCS_BMC) += kcs_bmc.o
 obj-$(CONFIG_IPMI_KCS_BMC_SERIO) += kcs_bmc_serio.o
 obj-$(CONFIG_IPMI_KCS_BMC_CDEV_IPMI) += kcs_bmc_cdev_ipmi.o
-obj-$(CONFIG_ASPEED_BT_IPMI_BMC) += bt-bmc.o
+obj-$(CONFIG_BT_IPMI_BMC) += bt-bmc.o
 obj-$(CONFIG_ASPEED_KCS_IPMI_BMC) += kcs_bmc_aspeed.o
 obj-$(CONFIG_NPCM7XX_KCS_IPMI_BMC) += kcs_bmc_npcm7xx.o
 obj-$(CONFIG_IPMB_DEVICE_INTERFACE) += ipmb_dev_int.o
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [RFC 5/5] ipmi:bt-bmc: Add Microwatt
  2021-10-06  2:12 [RFC 1/5] ipmi:bt-bmc: Separate out ASPEED specific bits Anton Blanchard
                   ` (2 preceding siblings ...)
  2021-10-06  2:12 ` [RFC 4/5] ipmi:bt-bmc: No longer ASPEED specific Anton Blanchard
@ 2021-10-06  2:12 ` Anton Blanchard
  2021-10-06  2:35   ` Joel Stanley
  2021-10-06  6:00   ` Cédric Le Goater
  2021-10-06  6:02 ` [RFC 1/5] ipmi:bt-bmc: Separate out ASPEED specific bits Cédric Le Goater
  4 siblings, 2 replies; 10+ messages in thread
From: Anton Blanchard @ 2021-10-06  2:12 UTC (permalink / raw)
  To: alistair, joel, andrew, clg, mikey, jk; +Cc: linuxppc-dev

This adds the Microwatt specific bits, including interrupt support.

Signed-off-by: Anton Blanchard <anton@ozlabs.org>
---
 .../devicetree/bindings/ipmi/ibt-bmc.txt      |  1 +
 drivers/char/ipmi/Kconfig                     |  8 ++-
 drivers/char/ipmi/bt-bmc.c                    | 69 +++++++++++++++++++
 3 files changed, 75 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/ipmi/ibt-bmc.txt b/Documentation/devicetree/bindings/ipmi/ibt-bmc.txt
index 78ee716a950e..1b661daf0193 100644
--- a/Documentation/devicetree/bindings/ipmi/ibt-bmc.txt
+++ b/Documentation/devicetree/bindings/ipmi/ibt-bmc.txt
@@ -9,6 +9,7 @@ Required properties:
 - compatible : should be one of
 	"aspeed,ast2400-ibt-bmc"
 	"aspeed,ast2500-ibt-bmc"
+	"ibm,microwatt-ibt-bmc"
 - reg: physical address and size of the registers
 
 Optional properties:
diff --git a/drivers/char/ipmi/Kconfig b/drivers/char/ipmi/Kconfig
index 8b2f0f675e5f..079302f4eef2 100644
--- a/drivers/char/ipmi/Kconfig
+++ b/drivers/char/ipmi/Kconfig
@@ -152,13 +152,15 @@ config IPMI_KCS_BMC_SERIO
 	  called kcs_bmc_serio.
 
 config BT_IPMI_BMC
-	depends on ARCH_ASPEED || COMPILE_TEST
+	depends on ARCH_ASPEED || PPC_MICROWATT || 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
-	  found on Aspeed SOCs (AST2400 and AST2500). The driver
-	  implements the BMC side of the BT interface.
+	  found on Aspeed SOCs (AST2400 and AST2500) as well as the OpenPOWER
+	  LPC peripheral macro at
+	  <https://github.com/OpenPOWERFoundation/lpcperipheral>
+	  The driver implements the BMC side of the BT interface.
 
 config IPMB_DEVICE_INTERFACE
 	tristate 'IPMB Interface handler'
diff --git a/drivers/char/ipmi/bt-bmc.c b/drivers/char/ipmi/bt-bmc.c
index b48e04405ac4..24327b57c60b 100644
--- a/drivers/char/ipmi/bt-bmc.c
+++ b/drivers/char/ipmi/bt-bmc.c
@@ -41,6 +41,11 @@
 #define   BT_CR2_IRQ_HBUSY	0x40
 #define ASPEED_BT_CR3	0xc
 
+#define MICROWATT_IRQ_MASK	0x0
+#define MICROWATT_IRQ_STATUS	0x4
+#define   IRQ_HOST_TO_BMC_ATTN	0x1
+#define   IRQ_HOST_NOT_BUSY	0x2
+
 #define BT_CTRL		0x10
 #define   BT_CTRL_B_BUSY		0x80
 #define   BT_CTRL_H_BUSY		0x40
@@ -395,6 +400,27 @@ static irqreturn_t aspeed_bt_bmc_irq(int irq, void *arg)
 	return IRQ_HANDLED;
 }
 
+static irqreturn_t microwatt_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 + MICROWATT_IRQ_STATUS, &reg);
+	if (rc)
+		return IRQ_NONE;
+
+	/* Interrupt wasn't something we knew about */
+	if (!(reg & (IRQ_HOST_TO_BMC_ATTN | IRQ_HOST_NOT_BUSY)))
+		return IRQ_NONE;
+
+	/* ack all pending IRQs */
+	regmap_write(bt_bmc->map, bt_bmc->offset + MICROWATT_IRQ_STATUS, 0);
+
+	wake_up(&bt_bmc->queue);
+	return IRQ_HANDLED;
+}
+
 static int aspeed_bt_bmc_config_irq(struct bt_bmc *bt_bmc,
 			     struct platform_device *pdev)
 {
@@ -446,6 +472,48 @@ static const struct bt_bmc_ops aspeed_bt_bmc_ops = {
 	.enable_bt = aspeed_enable_bt,
 };
 
+static int microwatt_bt_bmc_config_irq(struct bt_bmc *bt_bmc,
+			     struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	int rc;
+
+	bt_bmc->irq = platform_get_irq_optional(pdev, 0);
+	if (bt_bmc->irq < 0)
+		return bt_bmc->irq;
+
+	rc = devm_request_irq(dev, bt_bmc->irq, microwatt_bt_bmc_irq, IRQF_SHARED,
+			      DEVICE_NAME, bt_bmc);
+	if (rc < 0) {
+		dev_warn(dev, "Unable to request IRQ %d\n", bt_bmc->irq);
+		bt_bmc->irq = rc;
+		return rc;
+	}
+
+	/*
+	 * Configure the hardware to give us an interrupt whenever the H2B
+	 * bit is set or the HBUSY bit is cleared.
+	 *
+	 * H2B will be asserted when the bmc has data for us; HBUSY
+	 * will be cleared (along with B2H) when we can write the next
+	 * message to the BT buffer
+	 */
+	rc = regmap_update_bits(bt_bmc->map, bt_bmc->offset + MICROWATT_IRQ_MASK,
+				(IRQ_HOST_TO_BMC_ATTN | IRQ_HOST_NOT_BUSY),
+				(IRQ_HOST_TO_BMC_ATTN | IRQ_HOST_NOT_BUSY));
+
+	return rc;
+}
+
+static void microwatt_enable_bt(struct bt_bmc *bt_bmc)
+{
+}
+
+static const struct bt_bmc_ops microwatt_bt_bmc_ops = {
+	.config_irq = microwatt_bt_bmc_config_irq,
+	.enable_bt = microwatt_enable_bt,
+};
+
 static int bt_bmc_probe(struct platform_device *pdev)
 {
 	struct bt_bmc *bt_bmc;
@@ -530,6 +598,7 @@ static int bt_bmc_remove(struct platform_device *pdev)
 static const struct of_device_id bt_bmc_match[] = {
 	{ .compatible = "aspeed,ast2400-ibt-bmc", .data = &aspeed_bt_bmc_ops },
 	{ .compatible = "aspeed,ast2500-ibt-bmc", .data = &aspeed_bt_bmc_ops },
+	{ .compatible = "ibm,microwatt-ibt-bmc", .data = &microwatt_bt_bmc_ops },
 	{ },
 };
 
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [RFC 5/5] ipmi:bt-bmc: Add Microwatt
  2021-10-06  2:12 ` [RFC 5/5] ipmi:bt-bmc: Add Microwatt Anton Blanchard
@ 2021-10-06  2:35   ` Joel Stanley
  2021-10-06  3:06     ` Anton Blanchard
  2021-10-06  6:00   ` Cédric Le Goater
  1 sibling, 1 reply; 10+ messages in thread
From: Joel Stanley @ 2021-10-06  2:35 UTC (permalink / raw)
  To: Anton Blanchard
  Cc: Michael Neuling, Andrew Jeffery, Alistair Popple,
	Cédric Le Goater, Jeremy Kerr, linuxppc-dev

Hi Anton,

On Wed, 6 Oct 2021 at 02:12, Anton Blanchard <anton@ozlabs.org> wrote:
>
> This adds the Microwatt specific bits, including interrupt support.

The series looks good.

I've got a couple of patches on the ipmi list that this will conflict with:

 https://sourceforge.net/p/openipmi/mailman/message/37345391/
 https://lore.kernel.org/all/20210903015314.177987-1-joel@jms.id.au/

If there's no feedback from others I suggest basing your series on top
of those, and sending them to Corey on the ipmi list to merge.

Cheers,

Joel

>
> Signed-off-by: Anton Blanchard <anton@ozlabs.org>
> ---
>  .../devicetree/bindings/ipmi/ibt-bmc.txt      |  1 +
>  drivers/char/ipmi/Kconfig                     |  8 ++-
>  drivers/char/ipmi/bt-bmc.c                    | 69 +++++++++++++++++++
>  3 files changed, 75 insertions(+), 3 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/ipmi/ibt-bmc.txt b/Documentation/devicetree/bindings/ipmi/ibt-bmc.txt
> index 78ee716a950e..1b661daf0193 100644
> --- a/Documentation/devicetree/bindings/ipmi/ibt-bmc.txt
> +++ b/Documentation/devicetree/bindings/ipmi/ibt-bmc.txt
> @@ -9,6 +9,7 @@ Required properties:
>  - compatible : should be one of
>         "aspeed,ast2400-ibt-bmc"
>         "aspeed,ast2500-ibt-bmc"
> +       "ibm,microwatt-ibt-bmc"
>  - reg: physical address and size of the registers
>
>  Optional properties:
> diff --git a/drivers/char/ipmi/Kconfig b/drivers/char/ipmi/Kconfig
> index 8b2f0f675e5f..079302f4eef2 100644
> --- a/drivers/char/ipmi/Kconfig
> +++ b/drivers/char/ipmi/Kconfig
> @@ -152,13 +152,15 @@ config IPMI_KCS_BMC_SERIO
>           called kcs_bmc_serio.
>
>  config BT_IPMI_BMC
> -       depends on ARCH_ASPEED || COMPILE_TEST
> +       depends on ARCH_ASPEED || PPC_MICROWATT || 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
> -         found on Aspeed SOCs (AST2400 and AST2500). The driver
> -         implements the BMC side of the BT interface.
> +         found on Aspeed SOCs (AST2400 and AST2500) as well as the OpenPOWER
> +         LPC peripheral macro at
> +         <https://github.com/OpenPOWERFoundation/lpcperipheral>
> +         The driver implements the BMC side of the BT interface.
>
>  config IPMB_DEVICE_INTERFACE
>         tristate 'IPMB Interface handler'
> diff --git a/drivers/char/ipmi/bt-bmc.c b/drivers/char/ipmi/bt-bmc.c
> index b48e04405ac4..24327b57c60b 100644
> --- a/drivers/char/ipmi/bt-bmc.c
> +++ b/drivers/char/ipmi/bt-bmc.c
> @@ -41,6 +41,11 @@
>  #define   BT_CR2_IRQ_HBUSY     0x40
>  #define ASPEED_BT_CR3  0xc
>
> +#define MICROWATT_IRQ_MASK     0x0
> +#define MICROWATT_IRQ_STATUS   0x4
> +#define   IRQ_HOST_TO_BMC_ATTN 0x1
> +#define   IRQ_HOST_NOT_BUSY    0x2
> +
>  #define BT_CTRL                0x10
>  #define   BT_CTRL_B_BUSY               0x80
>  #define   BT_CTRL_H_BUSY               0x40
> @@ -395,6 +400,27 @@ static irqreturn_t aspeed_bt_bmc_irq(int irq, void *arg)
>         return IRQ_HANDLED;
>  }
>
> +static irqreturn_t microwatt_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 + MICROWATT_IRQ_STATUS, &reg);
> +       if (rc)
> +               return IRQ_NONE;
> +
> +       /* Interrupt wasn't something we knew about */
> +       if (!(reg & (IRQ_HOST_TO_BMC_ATTN | IRQ_HOST_NOT_BUSY)))
> +               return IRQ_NONE;
> +
> +       /* ack all pending IRQs */
> +       regmap_write(bt_bmc->map, bt_bmc->offset + MICROWATT_IRQ_STATUS, 0);
> +
> +       wake_up(&bt_bmc->queue);
> +       return IRQ_HANDLED;
> +}
> +
>  static int aspeed_bt_bmc_config_irq(struct bt_bmc *bt_bmc,
>                              struct platform_device *pdev)
>  {
> @@ -446,6 +472,48 @@ static const struct bt_bmc_ops aspeed_bt_bmc_ops = {
>         .enable_bt = aspeed_enable_bt,
>  };
>
> +static int microwatt_bt_bmc_config_irq(struct bt_bmc *bt_bmc,
> +                            struct platform_device *pdev)
> +{
> +       struct device *dev = &pdev->dev;
> +       int rc;
> +
> +       bt_bmc->irq = platform_get_irq_optional(pdev, 0);
> +       if (bt_bmc->irq < 0)
> +               return bt_bmc->irq;
> +
> +       rc = devm_request_irq(dev, bt_bmc->irq, microwatt_bt_bmc_irq, IRQF_SHARED,
> +                             DEVICE_NAME, bt_bmc);
> +       if (rc < 0) {
> +               dev_warn(dev, "Unable to request IRQ %d\n", bt_bmc->irq);
> +               bt_bmc->irq = rc;
> +               return rc;
> +       }
> +
> +       /*
> +        * Configure the hardware to give us an interrupt whenever the H2B
> +        * bit is set or the HBUSY bit is cleared.
> +        *
> +        * H2B will be asserted when the bmc has data for us; HBUSY
> +        * will be cleared (along with B2H) when we can write the next
> +        * message to the BT buffer
> +        */
> +       rc = regmap_update_bits(bt_bmc->map, bt_bmc->offset + MICROWATT_IRQ_MASK,
> +                               (IRQ_HOST_TO_BMC_ATTN | IRQ_HOST_NOT_BUSY),
> +                               (IRQ_HOST_TO_BMC_ATTN | IRQ_HOST_NOT_BUSY));
> +
> +       return rc;
> +}
> +
> +static void microwatt_enable_bt(struct bt_bmc *bt_bmc)
> +{
> +}
> +
> +static const struct bt_bmc_ops microwatt_bt_bmc_ops = {
> +       .config_irq = microwatt_bt_bmc_config_irq,
> +       .enable_bt = microwatt_enable_bt,
> +};
> +
>  static int bt_bmc_probe(struct platform_device *pdev)
>  {
>         struct bt_bmc *bt_bmc;
> @@ -530,6 +598,7 @@ static int bt_bmc_remove(struct platform_device *pdev)
>  static const struct of_device_id bt_bmc_match[] = {
>         { .compatible = "aspeed,ast2400-ibt-bmc", .data = &aspeed_bt_bmc_ops },
>         { .compatible = "aspeed,ast2500-ibt-bmc", .data = &aspeed_bt_bmc_ops },
> +       { .compatible = "ibm,microwatt-ibt-bmc", .data = &microwatt_bt_bmc_ops },
>         { },
>  };
>
> --
> 2.31.1
>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RFC 5/5] ipmi:bt-bmc: Add Microwatt
  2021-10-06  2:35   ` Joel Stanley
@ 2021-10-06  3:06     ` Anton Blanchard
  0 siblings, 0 replies; 10+ messages in thread
From: Anton Blanchard @ 2021-10-06  3:06 UTC (permalink / raw)
  To: Joel Stanley
  Cc: Michael Neuling, Andrew Jeffery, Alistair Popple,
	Cédric Le Goater, Jeremy Kerr, linuxppc-dev

Hi Joel,

> The series looks good.
> 
> I've got a couple of patches on the ipmi list that this will conflict
> with:
> 
>  https://sourceforge.net/p/openipmi/mailman/message/37345391/
>  https://lore.kernel.org/all/20210903015314.177987-1-joel@jms.id.au/
> 
> If there's no feedback from others I suggest basing your series on top
> of those, and sending them to Corey on the ipmi list to merge.

Looks good, will do.

Thanks,
Anton

> Cheers,
> 
> Joel
> 
> >
> > Signed-off-by: Anton Blanchard <anton@ozlabs.org>
> > ---
> >  .../devicetree/bindings/ipmi/ibt-bmc.txt      |  1 +
> >  drivers/char/ipmi/Kconfig                     |  8 ++-
> >  drivers/char/ipmi/bt-bmc.c                    | 69
> > +++++++++++++++++++ 3 files changed, 75 insertions(+), 3
> > deletions(-)
> >
> > diff --git a/Documentation/devicetree/bindings/ipmi/ibt-bmc.txt
> > b/Documentation/devicetree/bindings/ipmi/ibt-bmc.txt index
> > 78ee716a950e..1b661daf0193 100644 ---
> > a/Documentation/devicetree/bindings/ipmi/ibt-bmc.txt +++
> > b/Documentation/devicetree/bindings/ipmi/ibt-bmc.txt @@ -9,6 +9,7
> > @@ Required properties:
> >  - compatible : should be one of
> >         "aspeed,ast2400-ibt-bmc"
> >         "aspeed,ast2500-ibt-bmc"
> > +       "ibm,microwatt-ibt-bmc"
> >  - reg: physical address and size of the registers
> >
> >  Optional properties:
> > diff --git a/drivers/char/ipmi/Kconfig b/drivers/char/ipmi/Kconfig
> > index 8b2f0f675e5f..079302f4eef2 100644
> > --- a/drivers/char/ipmi/Kconfig
> > +++ b/drivers/char/ipmi/Kconfig
> > @@ -152,13 +152,15 @@ config IPMI_KCS_BMC_SERIO
> >           called kcs_bmc_serio.
> >
> >  config BT_IPMI_BMC
> > -       depends on ARCH_ASPEED || COMPILE_TEST
> > +       depends on ARCH_ASPEED || PPC_MICROWATT || 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
> > -         found on Aspeed SOCs (AST2400 and AST2500). The driver
> > -         implements the BMC side of the BT interface.
> > +         found on Aspeed SOCs (AST2400 and AST2500) as well as the
> > OpenPOWER
> > +         LPC peripheral macro at
> > +         <https://github.com/OpenPOWERFoundation/lpcperipheral>
> > +         The driver implements the BMC side of the BT interface.
> >
> >  config IPMB_DEVICE_INTERFACE
> >         tristate 'IPMB Interface handler'
> > diff --git a/drivers/char/ipmi/bt-bmc.c b/drivers/char/ipmi/bt-bmc.c
> > index b48e04405ac4..24327b57c60b 100644
> > --- a/drivers/char/ipmi/bt-bmc.c
> > +++ b/drivers/char/ipmi/bt-bmc.c
> > @@ -41,6 +41,11 @@
> >  #define   BT_CR2_IRQ_HBUSY     0x40
> >  #define ASPEED_BT_CR3  0xc
> >
> > +#define MICROWATT_IRQ_MASK     0x0
> > +#define MICROWATT_IRQ_STATUS   0x4
> > +#define   IRQ_HOST_TO_BMC_ATTN 0x1
> > +#define   IRQ_HOST_NOT_BUSY    0x2
> > +
> >  #define BT_CTRL                0x10
> >  #define   BT_CTRL_B_BUSY               0x80
> >  #define   BT_CTRL_H_BUSY               0x40
> > @@ -395,6 +400,27 @@ static irqreturn_t aspeed_bt_bmc_irq(int irq,
> > void *arg) return IRQ_HANDLED;
> >  }
> >
> > +static irqreturn_t microwatt_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 +
> > MICROWATT_IRQ_STATUS, &reg);
> > +       if (rc)
> > +               return IRQ_NONE;
> > +
> > +       /* Interrupt wasn't something we knew about */
> > +       if (!(reg & (IRQ_HOST_TO_BMC_ATTN | IRQ_HOST_NOT_BUSY)))
> > +               return IRQ_NONE;
> > +
> > +       /* ack all pending IRQs */
> > +       regmap_write(bt_bmc->map, bt_bmc->offset +
> > MICROWATT_IRQ_STATUS, 0); +
> > +       wake_up(&bt_bmc->queue);
> > +       return IRQ_HANDLED;
> > +}
> > +
> >  static int aspeed_bt_bmc_config_irq(struct bt_bmc *bt_bmc,
> >                              struct platform_device *pdev)
> >  {
> > @@ -446,6 +472,48 @@ static const struct bt_bmc_ops
> > aspeed_bt_bmc_ops = { .enable_bt = aspeed_enable_bt,
> >  };
> >
> > +static int microwatt_bt_bmc_config_irq(struct bt_bmc *bt_bmc,
> > +                            struct platform_device *pdev)
> > +{
> > +       struct device *dev = &pdev->dev;
> > +       int rc;
> > +
> > +       bt_bmc->irq = platform_get_irq_optional(pdev, 0);
> > +       if (bt_bmc->irq < 0)
> > +               return bt_bmc->irq;
> > +
> > +       rc = devm_request_irq(dev, bt_bmc->irq,
> > microwatt_bt_bmc_irq, IRQF_SHARED,
> > +                             DEVICE_NAME, bt_bmc);
> > +       if (rc < 0) {
> > +               dev_warn(dev, "Unable to request IRQ %d\n",
> > bt_bmc->irq);
> > +               bt_bmc->irq = rc;
> > +               return rc;
> > +       }
> > +
> > +       /*
> > +        * Configure the hardware to give us an interrupt whenever
> > the H2B
> > +        * bit is set or the HBUSY bit is cleared.
> > +        *
> > +        * H2B will be asserted when the bmc has data for us; HBUSY
> > +        * will be cleared (along with B2H) when we can write the
> > next
> > +        * message to the BT buffer
> > +        */
> > +       rc = regmap_update_bits(bt_bmc->map, bt_bmc->offset +
> > MICROWATT_IRQ_MASK,
> > +                               (IRQ_HOST_TO_BMC_ATTN |
> > IRQ_HOST_NOT_BUSY),
> > +                               (IRQ_HOST_TO_BMC_ATTN |
> > IRQ_HOST_NOT_BUSY)); +
> > +       return rc;
> > +}
> > +
> > +static void microwatt_enable_bt(struct bt_bmc *bt_bmc)
> > +{
> > +}
> > +
> > +static const struct bt_bmc_ops microwatt_bt_bmc_ops = {
> > +       .config_irq = microwatt_bt_bmc_config_irq,
> > +       .enable_bt = microwatt_enable_bt,
> > +};
> > +
> >  static int bt_bmc_probe(struct platform_device *pdev)
> >  {
> >         struct bt_bmc *bt_bmc;
> > @@ -530,6 +598,7 @@ static int bt_bmc_remove(struct platform_device
> > *pdev) static const struct of_device_id bt_bmc_match[] = {
> >         { .compatible = "aspeed,ast2400-ibt-bmc", .data =
> > &aspeed_bt_bmc_ops }, { .compatible = "aspeed,ast2500-ibt-bmc",
> > .data = &aspeed_bt_bmc_ops },
> > +       { .compatible = "ibm,microwatt-ibt-bmc", .data =
> > &microwatt_bt_bmc_ops }, { },
> >  };
> >
> > --
> > 2.31.1
> >  
> 


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RFC 5/5] ipmi:bt-bmc: Add Microwatt
  2021-10-06  2:12 ` [RFC 5/5] ipmi:bt-bmc: Add Microwatt Anton Blanchard
  2021-10-06  2:35   ` Joel Stanley
@ 2021-10-06  6:00   ` Cédric Le Goater
  1 sibling, 0 replies; 10+ messages in thread
From: Cédric Le Goater @ 2021-10-06  6:00 UTC (permalink / raw)
  To: Anton Blanchard, alistair, joel, andrew, mikey, jk; +Cc: linuxppc-dev

On 10/6/21 04:12, Anton Blanchard wrote:
> This adds the Microwatt specific bits, including interrupt support.
> 
> Signed-off-by: Anton Blanchard <anton@ozlabs.org>
> ---
>   .../devicetree/bindings/ipmi/ibt-bmc.txt      |  1 +
>   drivers/char/ipmi/Kconfig                     |  8 ++-
>   drivers/char/ipmi/bt-bmc.c                    | 69 +++++++++++++++++++
>   3 files changed, 75 insertions(+), 3 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/ipmi/ibt-bmc.txt b/Documentation/devicetree/bindings/ipmi/ibt-bmc.txt
> index 78ee716a950e..1b661daf0193 100644
> --- a/Documentation/devicetree/bindings/ipmi/ibt-bmc.txt
> +++ b/Documentation/devicetree/bindings/ipmi/ibt-bmc.txt
> @@ -9,6 +9,7 @@ Required properties:
>   - compatible : should be one of
>   	"aspeed,ast2400-ibt-bmc"
>   	"aspeed,ast2500-ibt-bmc"
> +	"ibm,microwatt-ibt-bmc"
>   - reg: physical address and size of the registers
>   
>   Optional properties:
> diff --git a/drivers/char/ipmi/Kconfig b/drivers/char/ipmi/Kconfig
> index 8b2f0f675e5f..079302f4eef2 100644
> --- a/drivers/char/ipmi/Kconfig
> +++ b/drivers/char/ipmi/Kconfig
> @@ -152,13 +152,15 @@ config IPMI_KCS_BMC_SERIO
>   	  called kcs_bmc_serio.
>   
>   config BT_IPMI_BMC
> -	depends on ARCH_ASPEED || COMPILE_TEST
> +	depends on ARCH_ASPEED || PPC_MICROWATT || 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
> -	  found on Aspeed SOCs (AST2400 and AST2500). The driver
> -	  implements the BMC side of the BT interface.
> +	  found on Aspeed SOCs (AST2400 and AST2500) as well as the OpenPOWER
> +	  LPC peripheral macro at
> +	  <https://github.com/OpenPOWERFoundation/lpcperipheral>
> +	  The driver implements the BMC side of the BT interface.
>   
>   config IPMB_DEVICE_INTERFACE
>   	tristate 'IPMB Interface handler'
> diff --git a/drivers/char/ipmi/bt-bmc.c b/drivers/char/ipmi/bt-bmc.c
> index b48e04405ac4..24327b57c60b 100644
> --- a/drivers/char/ipmi/bt-bmc.c
> +++ b/drivers/char/ipmi/bt-bmc.c
> @@ -41,6 +41,11 @@
>   #define   BT_CR2_IRQ_HBUSY	0x40
>   #define ASPEED_BT_CR3	0xc
>   
> +#define MICROWATT_IRQ_MASK	0x0
> +#define MICROWATT_IRQ_STATUS	0x4
> +#define   IRQ_HOST_TO_BMC_ATTN	0x1
> +#define   IRQ_HOST_NOT_BUSY	0x2
> +
>   #define BT_CTRL		0x10
>   #define   BT_CTRL_B_BUSY		0x80
>   #define   BT_CTRL_H_BUSY		0x40
> @@ -395,6 +400,27 @@ static irqreturn_t aspeed_bt_bmc_irq(int irq, void *arg)
>   	return IRQ_HANDLED;
>   }
>   
> +static irqreturn_t microwatt_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 + MICROWATT_IRQ_STATUS, &reg);
> +	if (rc)
> +		return IRQ_NONE;
> +
> +	/* Interrupt wasn't something we knew about */
> +	if (!(reg & (IRQ_HOST_TO_BMC_ATTN | IRQ_HOST_NOT_BUSY)))
> +		return IRQ_NONE;
> +
> +	/* ack all pending IRQs */
> +	regmap_write(bt_bmc->map, bt_bmc->offset + MICROWATT_IRQ_STATUS, 0);
> +
> +	wake_up(&bt_bmc->queue);
> +	return IRQ_HANDLED;
> +}
> +
>   static int aspeed_bt_bmc_config_irq(struct bt_bmc *bt_bmc,
>   			     struct platform_device *pdev)
>   {
> @@ -446,6 +472,48 @@ static const struct bt_bmc_ops aspeed_bt_bmc_ops = {
>   	.enable_bt = aspeed_enable_bt,
>   };
>   
> +static int microwatt_bt_bmc_config_irq(struct bt_bmc *bt_bmc,
> +			     struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	int rc;
> +
> +	bt_bmc->irq = platform_get_irq_optional(pdev, 0);
> +	if (bt_bmc->irq < 0)
> +		return bt_bmc->irq;
> +
> +	rc = devm_request_irq(dev, bt_bmc->irq, microwatt_bt_bmc_irq, IRQF_SHARED,
> +			      DEVICE_NAME, bt_bmc);
> +	if (rc < 0) {
> +		dev_warn(dev, "Unable to request IRQ %d\n", bt_bmc->irq);
> +		bt_bmc->irq = rc;
> +		return rc;
> +	}
> +
> +	/*
> +	 * Configure the hardware to give us an interrupt whenever the H2B
> +	 * bit is set or the HBUSY bit is cleared.
> +	 *
> +	 * H2B will be asserted when the bmc has data for us; HBUSY
> +	 * will be cleared (along with B2H) when we can write the next
> +	 * message to the BT buffer
> +	 */
> +	rc = regmap_update_bits(bt_bmc->map, bt_bmc->offset + MICROWATT_IRQ_MASK,
> +				(IRQ_HOST_TO_BMC_ATTN | IRQ_HOST_NOT_BUSY),
> +				(IRQ_HOST_TO_BMC_ATTN | IRQ_HOST_NOT_BUSY));

This is the only difference. May be we could introduce a ->config_irq_hw()
handler to keep a larger part common. No big deal.

Reviewed-by: Cédric Le Goater <clg@kaod.org>

C.


> +	return rc;
> +}
> +
> +static void microwatt_enable_bt(struct bt_bmc *bt_bmc)
> +{
> +}
> +
> +static const struct bt_bmc_ops microwatt_bt_bmc_ops = {
> +	.config_irq = microwatt_bt_bmc_config_irq,
> +	.enable_bt = microwatt_enable_bt,
> +};
> +
>   static int bt_bmc_probe(struct platform_device *pdev)
>   {
>   	struct bt_bmc *bt_bmc;
> @@ -530,6 +598,7 @@ static int bt_bmc_remove(struct platform_device *pdev)
>   static const struct of_device_id bt_bmc_match[] = {
>   	{ .compatible = "aspeed,ast2400-ibt-bmc", .data = &aspeed_bt_bmc_ops },
>   	{ .compatible = "aspeed,ast2500-ibt-bmc", .data = &aspeed_bt_bmc_ops },
> +	{ .compatible = "ibm,microwatt-ibt-bmc", .data = &microwatt_bt_bmc_ops },
>   	{ },
>   };
>   
> 


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RFC 3/5] ipmi:bt-bmc: Put arch specific function into bt_bmc_ops
  2021-10-06  2:12 ` [RFC 3/5] ipmi:bt-bmc: Put arch specific function into bt_bmc_ops Anton Blanchard
@ 2021-10-06  6:01   ` Cédric Le Goater
  0 siblings, 0 replies; 10+ messages in thread
From: Cédric Le Goater @ 2021-10-06  6:01 UTC (permalink / raw)
  To: Anton Blanchard, alistair, joel, andrew, mikey, jk; +Cc: linuxppc-dev

On 10/6/21 04:12, Anton Blanchard wrote:
> While most of the driver is arch agnostic, setting up and handling
> interrupts, and enabling the hardware is not. Create bt_bmc_ops to
> handle these functions.
> 
> Signed-off-by: Anton Blanchard <anton@ozlabs.org>

See comment on patch 5. Any how,

Reviewed-by: Cédric Le Goater <clg@kaod.org>

Thanks

C.

> ---
>   drivers/char/ipmi/bt-bmc.c | 24 ++++++++++++++++++++----
>   1 file changed, 20 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/char/ipmi/bt-bmc.c b/drivers/char/ipmi/bt-bmc.c
> index 2b0fe1255026..b48e04405ac4 100644
> --- a/drivers/char/ipmi/bt-bmc.c
> +++ b/drivers/char/ipmi/bt-bmc.c
> @@ -17,6 +17,7 @@
>   #include <linux/regmap.h>
>   #include <linux/sched.h>
>   #include <linux/timer.h>
> +#include <linux/of_device.h>
>   
>   /*
>    * This is a BMC device used to communicate to the host
> @@ -435,15 +436,30 @@ static void aspeed_enable_bt(struct bt_bmc *bt_bmc)
>   		     BT_CR0_ENABLE_IBT);
>   }
>   
> +struct bt_bmc_ops {
> +	int (*config_irq)(struct bt_bmc *bt_bmc, struct platform_device *pdev);
> +	void (*enable_bt)(struct bt_bmc *bt_bmc);
> +};
> +
> +static const struct bt_bmc_ops aspeed_bt_bmc_ops = {
> +	.config_irq = aspeed_bt_bmc_config_irq,
> +	.enable_bt = aspeed_enable_bt,
> +};
> +
>   static int bt_bmc_probe(struct platform_device *pdev)
>   {
>   	struct bt_bmc *bt_bmc;
>   	struct device *dev;
>   	int rc;
> +	const struct bt_bmc_ops *ops;
>   
>   	dev = &pdev->dev;
>   	dev_info(dev, "Found bt bmc device\n");
>   
> +	ops = of_device_get_match_data(&pdev->dev);
> +	if (!ops)
> +		return -ENODEV;
> +
>   	bt_bmc = devm_kzalloc(dev, sizeof(*bt_bmc), GFP_KERNEL);
>   	if (!bt_bmc)
>   		return -ENOMEM;
> @@ -483,7 +499,7 @@ static int bt_bmc_probe(struct platform_device *pdev)
>   		return rc;
>   	}
>   
> -	aspeed_bt_bmc_config_irq(bt_bmc, pdev);
> +	ops->config_irq(bt_bmc, pdev);
>   
>   	if (bt_bmc->irq >= 0) {
>   		dev_info(dev, "Using IRQ %d\n", bt_bmc->irq);
> @@ -494,7 +510,7 @@ static int bt_bmc_probe(struct platform_device *pdev)
>   		add_timer(&bt_bmc->poll_timer);
>   	}
>   
> -	aspeed_enable_bt(bt_bmc);
> +	ops->enable_bt(bt_bmc);
>   
>   	clr_b_busy(bt_bmc);
>   
> @@ -512,8 +528,8 @@ static int bt_bmc_remove(struct platform_device *pdev)
>   }
>   
>   static const struct of_device_id bt_bmc_match[] = {
> -	{ .compatible = "aspeed,ast2400-ibt-bmc" },
> -	{ .compatible = "aspeed,ast2500-ibt-bmc" },
> +	{ .compatible = "aspeed,ast2400-ibt-bmc", .data = &aspeed_bt_bmc_ops },
> +	{ .compatible = "aspeed,ast2500-ibt-bmc", .data = &aspeed_bt_bmc_ops },
>   	{ },
>   };
>   
> 


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RFC 1/5] ipmi:bt-bmc: Separate out ASPEED specific bits
  2021-10-06  2:12 [RFC 1/5] ipmi:bt-bmc: Separate out ASPEED specific bits Anton Blanchard
                   ` (3 preceding siblings ...)
  2021-10-06  2:12 ` [RFC 5/5] ipmi:bt-bmc: Add Microwatt Anton Blanchard
@ 2021-10-06  6:02 ` Cédric Le Goater
  4 siblings, 0 replies; 10+ messages in thread
From: Cédric Le Goater @ 2021-10-06  6:02 UTC (permalink / raw)
  To: Anton Blanchard, alistair, joel, andrew, mikey, jk; +Cc: linuxppc-dev

On 10/6/21 04:12, Anton Blanchard wrote:
> Most of the IPMI BT BMC driver is architecture agnostic - it deals with
> architected registers and behaviour in the IPMI specification.
> 
> Separate out the few ASPEED specific bits into their own functions
> so we can use this driver on other architectures.
> 
> Signed-off-by: Anton Blanchard <anton@ozlabs.org>

Reviewed-by: Cédric Le Goater <clg@kaod.org>

Thanks,

C.

> ---
>   drivers/char/ipmi/bt-bmc.c | 26 ++++++++++++++++----------
>   1 file changed, 16 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/char/ipmi/bt-bmc.c b/drivers/char/ipmi/bt-bmc.c
> index 6e3d247b55d1..f85fafc96ef6 100644
> --- a/drivers/char/ipmi/bt-bmc.c
> +++ b/drivers/char/ipmi/bt-bmc.c
> @@ -39,6 +39,7 @@
>   #define   BT_CR2_IRQ_H2B	0x01
>   #define   BT_CR2_IRQ_HBUSY	0x40
>   #define BT_CR3		0xc
> +
>   #define BT_CTRL		0x10
>   #define   BT_CTRL_B_BUSY		0x80
>   #define   BT_CTRL_H_BUSY		0x40
> @@ -372,7 +373,7 @@ static void poll_timer(struct timer_list *t)
>   	add_timer(&bt_bmc->poll_timer);
>   }
>   
> -static irqreturn_t bt_bmc_irq(int irq, void *arg)
> +static irqreturn_t aspeed_bt_bmc_irq(int irq, void *arg)
>   {
>   	struct bt_bmc *bt_bmc = arg;
>   	u32 reg;
> @@ -393,7 +394,7 @@ static irqreturn_t bt_bmc_irq(int irq, void *arg)
>   	return IRQ_HANDLED;
>   }
>   
> -static int bt_bmc_config_irq(struct bt_bmc *bt_bmc,
> +static int aspeed_bt_bmc_config_irq(struct bt_bmc *bt_bmc,
>   			     struct platform_device *pdev)
>   {
>   	struct device *dev = &pdev->dev;
> @@ -403,7 +404,7 @@ static int bt_bmc_config_irq(struct bt_bmc *bt_bmc,
>   	if (bt_bmc->irq < 0)
>   		return bt_bmc->irq;
>   
> -	rc = devm_request_irq(dev, bt_bmc->irq, bt_bmc_irq, IRQF_SHARED,
> +	rc = devm_request_irq(dev, bt_bmc->irq, aspeed_bt_bmc_irq, IRQF_SHARED,
>   			      DEVICE_NAME, bt_bmc);
>   	if (rc < 0) {
>   		dev_warn(dev, "Unable to request IRQ %d\n", bt_bmc->irq);
> @@ -424,6 +425,16 @@ static int bt_bmc_config_irq(struct bt_bmc *bt_bmc,
>   	return rc;
>   }
>   
> +static void aspeed_enable_bt(struct bt_bmc *bt_bmc)
> +{
> +	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);
> +}
> +
>   static int bt_bmc_probe(struct platform_device *pdev)
>   {
>   	struct bt_bmc *bt_bmc;
> @@ -472,7 +483,7 @@ static int bt_bmc_probe(struct platform_device *pdev)
>   		return rc;
>   	}
>   
> -	bt_bmc_config_irq(bt_bmc, pdev);
> +	aspeed_bt_bmc_config_irq(bt_bmc, pdev);
>   
>   	if (bt_bmc->irq >= 0) {
>   		dev_info(dev, "Using IRQ %d\n", bt_bmc->irq);
> @@ -483,12 +494,7 @@ static int bt_bmc_probe(struct platform_device *pdev)
>   		add_timer(&bt_bmc->poll_timer);
>   	}
>   
> -	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);
> +	aspeed_enable_bt(bt_bmc);
>   
>   	clr_b_busy(bt_bmc);
>   
> 


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2021-10-06  6:28 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-06  2:12 [RFC 1/5] ipmi:bt-bmc: Separate out ASPEED specific bits Anton Blanchard
2021-10-06  2:12 ` [RFC 2/5] ipmi:bt-bmc: Prefix ASPEED specific registers with ASPEED_ Anton Blanchard
2021-10-06  2:12 ` [RFC 3/5] ipmi:bt-bmc: Put arch specific function into bt_bmc_ops Anton Blanchard
2021-10-06  6:01   ` Cédric Le Goater
2021-10-06  2:12 ` [RFC 4/5] ipmi:bt-bmc: No longer ASPEED specific Anton Blanchard
2021-10-06  2:12 ` [RFC 5/5] ipmi:bt-bmc: Add Microwatt Anton Blanchard
2021-10-06  2:35   ` Joel Stanley
2021-10-06  3:06     ` Anton Blanchard
2021-10-06  6:00   ` Cédric Le Goater
2021-10-06  6:02 ` [RFC 1/5] ipmi:bt-bmc: Separate out ASPEED specific bits Cédric Le Goater

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).