Skip to content

Commit

Permalink
Merge tag 'scmi-fixes-5.4' of git://git.kernel.org/pub/scm/linux/kern…
Browse files Browse the repository at this point in the history
…el/git/sudeep.holla/linux into arm/fixes

ARM SCMI fixes for v5.4

Couple of fixes: one in scmi reset driver initialising missed scmi handle
and an other in scmi reset API implementation fixing the assignment of
reset state

* tag 'scmi-fixes-5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux:
  reset: reset-scmi: add missing handle initialisation
  firmware: arm_scmi: reset: fix reset_state assignment in scmi_domain_reset

Link: https://lore.kernel.org/r/20190918142139.GA4370@bogus
Signed-off-by: Olof Johansson <[email protected]>
  • Loading branch information
olofj committed Sep 29, 2019
2 parents b74d957 + 6142371 commit a4207a1
Show file tree
Hide file tree
Showing 17 changed files with 982 additions and 202 deletions.
17 changes: 17 additions & 0 deletions Documentation/devicetree/bindings/arm/arm,scmi.txt
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,16 @@ Required properties:
as used by the firmware. Refer to platform details
for your implementation for the IDs to use.

Reset signal bindings for the reset domains based on SCMI Message Protocol
------------------------------------------------------------

This binding for the SCMI reset domain providers uses the generic reset
signal binding[5].

Required properties:
- #reset-cells : Should be 1. Contains the reset domain ID value used
by SCMI commands.

SRAM and Shared Memory for SCMI
-------------------------------

Expand All @@ -93,6 +103,7 @@ Required sub-node properties:
[2] Documentation/devicetree/bindings/power/power_domain.txt
[3] Documentation/devicetree/bindings/thermal/thermal.txt
[4] Documentation/devicetree/bindings/sram/sram.txt
[5] Documentation/devicetree/bindings/reset/reset.txt

Example:

Expand Down Expand Up @@ -152,6 +163,11 @@ firmware {
reg = <0x15>;
#thermal-sensor-cells = <1>;
};

scmi_reset: protocol@16 {
reg = <0x16>;
#reset-cells = <1>;
};
};
};

Expand All @@ -166,6 +182,7 @@ hdlcd@7ff60000 {
reg = <0 0x7ff60000 0 0x1000>;
clocks = <&scmi_clk 4>;
power-domains = <&scmi_devpd 1>;
resets = <&scmi_reset 10>;
};

thermal-zones {
Expand Down
1 change: 1 addition & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -15575,6 +15575,7 @@ F: drivers/clk/clk-sc[mp]i.c
F: drivers/cpufreq/sc[mp]i-cpufreq.c
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

SYSTEM RESET/SHUTDOWN DRIVERS
Expand Down
2 changes: 1 addition & 1 deletion drivers/clk/clk-scmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ static int scmi_clk_set_rate(struct clk_hw *hw, unsigned long rate,
{
struct scmi_clk *clk = to_scmi_clk(hw);

return clk->handle->clk_ops->rate_set(clk->handle, clk->id, 0, rate);
return clk->handle->clk_ops->rate_set(clk->handle, clk->id, rate);
}

static int scmi_clk_enable(struct clk_hw *hw)
Expand Down
2 changes: 1 addition & 1 deletion drivers/firmware/arm_scmi/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
obj-y = scmi-bus.o scmi-driver.o scmi-protocols.o
scmi-bus-y = bus.o
scmi-driver-y = driver.o
scmi-protocols-y = base.o clock.o perf.o power.o sensors.o
scmi-protocols-y = base.o clock.o perf.o power.o reset.o sensors.o
obj-$(CONFIG_ARM_SCMI_POWER_DOMAIN) += scmi_pm_domain.o
2 changes: 1 addition & 1 deletion drivers/firmware/arm_scmi/base.c
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ static int scmi_base_discover_agent_get(const struct scmi_handle *handle,
if (ret)
return ret;

*(__le32 *)t->tx.buf = cpu_to_le32(id);
put_unaligned_le32(id, t->tx.buf);

ret = scmi_do_xfer(handle, t);
if (!ret)
Expand Down
33 changes: 21 additions & 12 deletions drivers/firmware/arm_scmi/clock.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ struct scmi_msg_resp_clock_describe_rates {
struct scmi_clock_set_rate {
__le32 flags;
#define CLOCK_SET_ASYNC BIT(0)
#define CLOCK_SET_DELAYED BIT(1)
#define CLOCK_SET_IGNORE_RESP BIT(1)
#define CLOCK_SET_ROUND_UP BIT(2)
#define CLOCK_SET_ROUND_AUTO BIT(3)
__le32 id;
Expand All @@ -67,6 +67,7 @@ struct scmi_clock_set_rate {
struct clock_info {
int num_clocks;
int max_async_req;
atomic_t cur_async_req;
struct scmi_clock_info *clk;
};

Expand Down Expand Up @@ -106,7 +107,7 @@ static int scmi_clock_attributes_get(const struct scmi_handle *handle,
if (ret)
return ret;

*(__le32 *)t->tx.buf = cpu_to_le32(clk_id);
put_unaligned_le32(clk_id, t->tx.buf);
attr = t->rx.buf;

ret = scmi_do_xfer(handle, t);
Expand Down Expand Up @@ -203,39 +204,47 @@ scmi_clock_rate_get(const struct scmi_handle *handle, u32 clk_id, u64 *value)
if (ret)
return ret;

*(__le32 *)t->tx.buf = cpu_to_le32(clk_id);
put_unaligned_le32(clk_id, t->tx.buf);

ret = scmi_do_xfer(handle, t);
if (!ret) {
__le32 *pval = t->rx.buf;

*value = le32_to_cpu(*pval);
*value |= (u64)le32_to_cpu(*(pval + 1)) << 32;
}
if (!ret)
*value = get_unaligned_le64(t->rx.buf);

scmi_xfer_put(handle, t);
return ret;
}

static int scmi_clock_rate_set(const struct scmi_handle *handle, u32 clk_id,
u32 config, u64 rate)
u64 rate)
{
int ret;
u32 flags = 0;
struct scmi_xfer *t;
struct scmi_clock_set_rate *cfg;
struct clock_info *ci = handle->clk_priv;

ret = scmi_xfer_get_init(handle, CLOCK_RATE_SET, SCMI_PROTOCOL_CLOCK,
sizeof(*cfg), 0, &t);
if (ret)
return ret;

if (ci->max_async_req &&
atomic_inc_return(&ci->cur_async_req) < ci->max_async_req)
flags |= CLOCK_SET_ASYNC;

cfg = t->tx.buf;
cfg->flags = cpu_to_le32(config);
cfg->flags = cpu_to_le32(flags);
cfg->id = cpu_to_le32(clk_id);
cfg->value_low = cpu_to_le32(rate & 0xffffffff);
cfg->value_high = cpu_to_le32(rate >> 32);

ret = scmi_do_xfer(handle, t);
if (flags & CLOCK_SET_ASYNC)
ret = scmi_do_xfer_with_response(handle, t);
else
ret = scmi_do_xfer(handle, t);

if (ci->max_async_req)
atomic_dec(&ci->cur_async_req);

scmi_xfer_put(handle, t);
return ret;
Expand Down
18 changes: 12 additions & 6 deletions drivers/firmware/arm_scmi/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
#include <linux/scmi_protocol.h>
#include <linux/types.h>

#include <asm/unaligned.h>

#define PROTOCOL_REV_MINOR_MASK GENMASK(15, 0)
#define PROTOCOL_REV_MAJOR_MASK GENMASK(31, 16)
#define PROTOCOL_REV_MAJOR(x) (u16)(FIELD_GET(PROTOCOL_REV_MAJOR_MASK, (x)))
Expand Down Expand Up @@ -48,11 +50,11 @@ struct scmi_msg_resp_prot_version {
/**
* struct scmi_msg_hdr - Message(Tx/Rx) header
*
* @id: The identifier of the command being sent
* @protocol_id: The identifier of the protocol used to send @id command
* @seq: The token to identify the message. when a message/command returns,
* the platform returns the whole message header unmodified including
* the token
* @id: The identifier of the message being sent
* @protocol_id: The identifier of the protocol used to send @id message
* @seq: The token to identify the message. When a message returns, the
* platform returns the whole message header unmodified including the
* token
* @status: Status of the transfer once it's complete
* @poll_completion: Indicate if the transfer needs to be polled for
* completion or interrupt mode is used
Expand Down Expand Up @@ -84,17 +86,21 @@ struct scmi_msg {
* @rx: Receive message, the buffer should be pre-allocated to store
* message. If request-ACK protocol is used, we can reuse the same
* buffer for the rx path as we use for the tx path.
* @done: completion event
* @done: command message transmit completion event
* @async: pointer to delayed response message received event completion
*/
struct scmi_xfer {
struct scmi_msg_hdr hdr;
struct scmi_msg tx;
struct scmi_msg rx;
struct completion done;
struct completion *async_done;
};

void scmi_xfer_put(const struct scmi_handle *h, struct scmi_xfer *xfer);
int scmi_do_xfer(const struct scmi_handle *h, struct scmi_xfer *xfer);
int scmi_do_xfer_with_response(const struct scmi_handle *h,
struct scmi_xfer *xfer);
int scmi_xfer_get_init(const struct scmi_handle *h, u8 msg_id, u8 prot_id,
size_t tx_size, size_t rx_size, struct scmi_xfer **p);
int scmi_handle_put(const struct scmi_handle *handle);
Expand Down
Loading

0 comments on commit a4207a1

Please sign in to comment.