Commit 965af1cf authored by Olof Johansson's avatar Olof Johansson
Browse files

Merge tag 'scmi-updates-5.6' of...

Merge tag 'scmi-updates-5.6' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux into arm/drivers

ARM SCMI updates for v5.6

1. Addition of multiple device support per protocol to enable use of
   some procotols by multiple kernel subsystems simultaneously and
   corresponding updates to the existing scmi drivers
2. Addition of trace events around the scmi transfer code to measure
   any delays and capture anomalies that can also be used during
   investigation of some platform firmware related issues

* tag 'scmi-updates-5.6' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux:
  drivers: firmware: scmi: Extend SCMI transport layer by trace events
  include: trace: Add SCMI header with trace events
  reset: reset-scmi: Match scmi device by both name and protocol id
  hwmon: (scmi-hwmon) Match scmi device by both name and protocol id
  cpufreq: scmi: Match scmi device by both name and protocol id
  clk: scmi: Match scmi device by both name and protocol id
  firmware: arm_scmi: Skip protocol initialisation for additional devices
  firmware: arm_scmi: Stash version in protocol init functions
  firmware: arm_scmi: Match scmi device by both name and protocol id
  firmware: arm_scmi: Add versions and identifier attributes using dev_groups
  firmware: arm_scmi: Add names to scmi devices created
  firmware: arm_scmi: Skip scmi mbox channel setup for addtional devices
  firmware: arm_scmi: Add support for multiple device per protocol

Link: https://lore.kernel.org/r/20191230182956.GA29349@bogus


Signed-off-by: default avatarOlof Johansson <olof@lixom.net>
parents d1eef1c6 729d3530
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -15966,6 +15966,7 @@ F: drivers/firmware/arm_scpi.c
F:	drivers/firmware/arm_scmi/
F:	drivers/reset/reset-scmi.c
F:	include/linux/sc[mp]i_protocol.h
F:	include/trace/events/scmi.h
SYSTEM RESET/SHUTDOWN DRIVERS
M:	Sebastian Reichel <sre@kernel.org>
+1 −1
Original line number Diff line number Diff line
@@ -176,7 +176,7 @@ static int scmi_clocks_probe(struct scmi_device *sdev)
}

static const struct scmi_device_id scmi_id_table[] = {
	{ SCMI_PROTOCOL_CLOCK },
	{ SCMI_PROTOCOL_CLOCK, "clocks" },
	{ },
};
MODULE_DEVICE_TABLE(scmi, scmi_id_table);
+1 −1
Original line number Diff line number Diff line
@@ -261,7 +261,7 @@ static void scmi_cpufreq_remove(struct scmi_device *sdev)
}

static const struct scmi_device_id scmi_id_table[] = {
	{ SCMI_PROTOCOL_PERF },
	{ SCMI_PROTOCOL_PERF, "cpufreq" },
	{ },
};
MODULE_DEVICE_TABLE(scmi, scmi_id_table);
+26 −3
Original line number Diff line number Diff line
@@ -28,8 +28,12 @@ scmi_dev_match_id(struct scmi_device *scmi_dev, struct scmi_driver *scmi_drv)
		return NULL;

	for (; id->protocol_id; id++)
		if (id->protocol_id == scmi_dev->protocol_id)
		if (id->protocol_id == scmi_dev->protocol_id) {
			if (!id->name)
				return id;
			else if (!strcmp(id->name, scmi_dev->name))
				return id;
		}

	return NULL;
}
@@ -56,6 +60,11 @@ static int scmi_protocol_init(int protocol_id, struct scmi_handle *handle)
	return fn(handle);
}

static int scmi_protocol_dummy_init(struct scmi_handle *handle)
{
	return 0;
}

static int scmi_dev_probe(struct device *dev)
{
	struct scmi_driver *scmi_drv = to_scmi_driver(dev->driver);
@@ -74,6 +83,10 @@ static int scmi_dev_probe(struct device *dev)
	if (ret)
		return ret;

	/* Skip protocol initialisation for additional devices */
	idr_replace(&scmi_protocols, &scmi_protocol_dummy_init,
		    scmi_dev->protocol_id);

	return scmi_drv->probe(scmi_dev);
}

@@ -125,7 +138,8 @@ static void scmi_device_release(struct device *dev)
}

struct scmi_device *
scmi_device_create(struct device_node *np, struct device *parent, int protocol)
scmi_device_create(struct device_node *np, struct device *parent, int protocol,
		   const char *name)
{
	int id, retval;
	struct scmi_device *scmi_dev;
@@ -134,8 +148,15 @@ scmi_device_create(struct device_node *np, struct device *parent, int protocol)
	if (!scmi_dev)
		return NULL;

	scmi_dev->name = kstrdup_const(name ?: "unknown", GFP_KERNEL);
	if (!scmi_dev->name) {
		kfree(scmi_dev);
		return NULL;
	}

	id = ida_simple_get(&scmi_bus_id, 1, 0, GFP_KERNEL);
	if (id < 0) {
		kfree_const(scmi_dev->name);
		kfree(scmi_dev);
		return NULL;
	}
@@ -154,6 +175,7 @@ scmi_device_create(struct device_node *np, struct device *parent, int protocol)

	return scmi_dev;
put_dev:
	kfree_const(scmi_dev->name);
	put_device(&scmi_dev->dev);
	ida_simple_remove(&scmi_bus_id, id);
	return NULL;
@@ -161,6 +183,7 @@ scmi_device_create(struct device_node *np, struct device *parent, int protocol)

void scmi_device_destroy(struct scmi_device *scmi_dev)
{
	kfree_const(scmi_dev->name);
	scmi_handle_put(scmi_dev->handle);
	ida_simple_remove(&scmi_bus_id, scmi_dev->id);
	device_unregister(&scmi_dev->dev);
+2 −0
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@ struct scmi_clock_set_rate {
};

struct clock_info {
	u32 version;
	int num_clocks;
	int max_async_req;
	atomic_t cur_async_req;
@@ -340,6 +341,7 @@ static int scmi_clock_protocol_init(struct scmi_handle *handle)
			scmi_clock_describe_rates_get(handle, clkid, clk);
	}

	cinfo->version = version;
	handle->clk_ops = &clk_ops;
	handle->clk_priv = cinfo;

Loading