Commit 90b12f42 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'for-linus-6.2-1' of https://github.com/cminyard/linux-ipmi

Pull IPMI updates from Corey Minyard:
 "This includes a number of small fixes, as usual.

  It also includes a new driver for doing the i2c (SSIF) interface
  BMC-side, pretty much completing the BMC side interfaces"

* tag 'for-linus-6.2-1' of https://github.com/cminyard/linux-ipmi:
  ipmi/watchdog: use strscpy() to instead of strncpy()
  ipmi: ssif_bmc: Convert to i2c's .probe_new()
  ipmi: fix use after free in _ipmi_destroy_user()
  ipmi/watchdog: Include <linux/kstrtox.h> when appropriate
  ipmi:ssif: Increase the message retry time
  ipmi: Fix some kernel-doc warnings
  ipmi: ssif_bmc: Use EPOLLIN instead of POLLIN
  ipmi: fix msg stack when IPMI is disconnected
  ipmi: fix memleak when unload ipmi driver
  ipmi: fix long wait in unload when IPMI disconnect
  ipmi: kcs: Poll OBF briefly to reduce OBE latency
  bindings: ipmi: Add binding for SSIF BMC driver
  ipmi: ssif_bmc: Add SSIF BMC driver
parents 2043f9a3 c6f613e5
Loading
Loading
Loading
Loading
+38 −0
Original line number Diff line number Diff line
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/ipmi/ssif-bmc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: SSIF IPMI BMC interface

description: SSIF IPMI BMC device bindings

maintainers:
  - Quan Nguyen <quan@os.amperecomputing.com>

properties:
  compatible:
    enum:
      - ssif-bmc

  reg:
    maxItems: 1

required:
  - compatible
  - reg

additionalProperties: false

examples:
  - |
    i2c {
        #address-cells = <1>;
        #size-cells = <0>;

        ssif-bmc@10 {
            compatible = "ssif-bmc";
            reg = <0x10>;
        };
    };
+10 −0
Original line number Diff line number Diff line
@@ -169,6 +169,16 @@ config ASPEED_BT_IPMI_BMC
	  found on Aspeed SOCs (AST2400 and AST2500). The driver
	  implements the BMC side of the BT interface.

config SSIF_IPMI_BMC
	tristate "SSIF IPMI BMC driver"
	depends on I2C && I2C_SLAVE
	help
	  This enables the IPMI SMBus system interface (SSIF) at the
	  management (BMC) side.

	  The driver implements the BMC side of the SMBus system
	  interface (SSIF).

config IPMB_DEVICE_INTERFACE
	tristate 'IPMB Interface handler'
	depends on I2C
+1 −0
Original line number Diff line number Diff line
@@ -30,3 +30,4 @@ obj-$(CONFIG_ASPEED_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
obj-$(CONFIG_SSIF_IPMI_BMC) += ssif_bmc.o
+11 −5
Original line number Diff line number Diff line
@@ -122,10 +122,10 @@ struct si_sm_data {
	unsigned long  error0_timeout;
};

static unsigned int init_kcs_data(struct si_sm_data *kcs,
				  struct si_sm_io *io)
static unsigned int init_kcs_data_with_state(struct si_sm_data *kcs,
				  struct si_sm_io *io, enum kcs_states state)
{
	kcs->state = KCS_IDLE;
	kcs->state = state;
	kcs->io = io;
	kcs->write_pos = 0;
	kcs->write_count = 0;
@@ -140,6 +140,12 @@ static unsigned int init_kcs_data(struct si_sm_data *kcs,
	return 2;
}

static unsigned int init_kcs_data(struct si_sm_data *kcs,
				  struct si_sm_io *io)
{
	return init_kcs_data_with_state(kcs, io, KCS_IDLE);
}

static inline unsigned char read_status(struct si_sm_data *kcs)
{
	return kcs->io->inputb(kcs->io, 1);
@@ -270,7 +276,7 @@ static int start_kcs_transaction(struct si_sm_data *kcs, unsigned char *data,
	if (size > MAX_KCS_WRITE_SIZE)
		return IPMI_REQ_LEN_EXCEEDED_ERR;

	if ((kcs->state != KCS_IDLE) && (kcs->state != KCS_HOSED)) {
	if (kcs->state != KCS_IDLE) {
		dev_warn(kcs->io->dev, "KCS in invalid state %d\n", kcs->state);
		return IPMI_NOT_IN_MY_STATE_ERR;
	}
@@ -495,7 +501,7 @@ static enum si_sm_result kcs_event(struct si_sm_data *kcs, long time)
	}

	if (kcs->state == KCS_HOSED) {
		init_kcs_data(kcs, kcs->io);
		init_kcs_data_with_state(kcs, kcs->io, KCS_ERROR0);
		return SI_SM_HOSED;
	}

+10 −4
Original line number Diff line number Diff line
@@ -614,7 +614,7 @@ static int __ipmi_bmc_register(struct ipmi_smi *intf,
static int __scan_channels(struct ipmi_smi *intf, struct ipmi_device_id *id);


/**
/*
 * The driver model view of the IPMI messaging driver.
 */
static struct platform_driver ipmidriver = {
@@ -1330,6 +1330,7 @@ static void _ipmi_destroy_user(struct ipmi_user *user)
	unsigned long    flags;
	struct cmd_rcvr  *rcvr;
	struct cmd_rcvr  *rcvrs = NULL;
	struct module    *owner;

	if (!acquire_ipmi_user(user, &i)) {
		/*
@@ -1392,8 +1393,9 @@ static void _ipmi_destroy_user(struct ipmi_user *user)
		kfree(rcvr);
	}

	owner = intf->owner;
	kref_put(&intf->refcount, intf_free);
	module_put(intf->owner);
	module_put(owner);
}

int ipmi_destroy_user(struct ipmi_user *user)
@@ -3704,12 +3706,16 @@ static void deliver_smi_err_response(struct ipmi_smi *intf,
				     struct ipmi_smi_msg *msg,
				     unsigned char err)
{
	int rv;
	msg->rsp[0] = msg->data[0] | 4;
	msg->rsp[1] = msg->data[1];
	msg->rsp[2] = err;
	msg->rsp_size = 3;
	/* It's an error, so it will never requeue, no need to check return. */
	handle_one_recv_msg(intf, msg);

	/* This will never requeue, but it may ask us to free the message. */
	rv = handle_one_recv_msg(intf, msg);
	if (rv == 0)
		ipmi_free_smi_msg(msg);
}

static void cleanup_smi_msgs(struct ipmi_smi *intf)
Loading