diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2021-04-26 12:11:52 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2021-04-26 12:11:52 -0700 |
commit | 37f00ab4a003f371f81e0eae76cf372f06dec780 (patch) | |
tree | c6217483f22a0fac876f12af53f4b8948200f2fd /drivers/firmware/arm_scmi/power.c | |
parent | 2b90506a8186df5f7c81ad1ebd250103d8469e27 (diff) | |
parent | 5ffa828534036348fa90fb3079ccc0972d202c4a (diff) | |
download | linux-37f00ab4a003f371f81e0eae76cf372f06dec780.tar.bz2 |
Merge tag 'arm-drivers-5.13' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc
Pull ARM SoC driver updates from Arnd Bergmann:
"Updates for SoC specific drivers include a few subsystems that have
their own maintainers but send them through the soc tree:
TEE/OP-TEE:
- Add tracepoints around calls to secure world
Memory controller drivers:
- Minor fixes for Renesas, Exynos, Mediatek and Tegra platforms
- Add debug statistics to Tegra20 memory controller
- Update Tegra bindings and convert to dtschema
ARM SCMI Firmware:
- Support for modular SCMI protocols and vendor specific extensions
- New SCMI IIO driver
- Per-cpu DVFS
The other driver changes are all from the platform maintainers
directly and reflect the drivers that don't fit into any other
subsystem as well as treewide changes for a particular platform.
SoCFPGA:
- Various cleanups contributed by Krzysztof Kozlowski
Mediatek:
- add MT8183 support to mutex driver
- MMSYS: use per SoC array to describe the possible routing
- add MMSYS support for MT8183 and MT8167
- add support for PMIC wrapper with integrated arbiter
- add support for MT8192/MT6873
Tegra:
- Bug fixes to PMC and clock drivers
NXP/i.MX:
- Update SCU power domain driver to keep console domain power on.
- Add missing ADC1 power domain to SCU power domain driver.
- Update comments for single global power domain in SCU power domain
driver.
- Add i.MX51/i.MX53 unique id support to i.MX SoC driver.
NXP/FSL SoC driver updates for v5.13
- Add ACPI support for RCPM driver
- Use generic io{read,write} for QE drivers after performance
optimized for PowerPC
- Fix QBMAN probe to cleanup HW states correctly for kexec
- Various cleanup and style fix for QBMAN/QE/GUTS drivers
OMAP:
- Preparation to use devicetree for genpd
- ti-sysc needs iorange check improved when the interconnect target
module has no control registers listed
- ti-sysc needs to probe l4_wkup and l4_cfg interconnects first to
avoid issues with missing resources and unnecessary deferred probe
- ti-sysc debug option can now detect more devices
- ti-sysc now warns if an old incomplete devicetree data is found as
we now rely on it being complete for am3 and 4
- soc init code needs to check for prcm and prm nodes for omap4/5 and
dra7
- omap-prm driver needs to enable autoidle retention support for
omap4
- omap5 clocks are missing gpmc and ocmc clock registers
- pci-dra7xx now needs to use builtin_platform_driver instead of
using builtin_platform_driver_probe for deferred probe to work
Raspberry Pi:
- Fix-up all RPi firmware drivers so as for unbind to happen in an
orderly fashion
- Support for RPi's PoE hat PWM bus
Qualcomm
- Improved detection for SCM calling conventions
- Support for OEM specific wifi firmware path
- Added drivers for SC7280/SM8350: RPMH, LLCC< AOSS QMP"
* tag 'arm-drivers-5.13' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc: (165 commits)
soc: aspeed: fix a ternary sign expansion bug
memory: mtk-smi: Add device-link between smi-larb and smi-common
memory: samsung: exynos5422-dmc: handle clk_set_parent() failure
memory: renesas-rpc-if: fix possible NULL pointer dereference of resource
clk: socfpga: fix iomem pointer cast on 64-bit
soc: aspeed: Adapt to new LPC device tree layout
pinctrl: aspeed-g5: Adapt to new LPC device tree layout
ipmi: kcs: aspeed: Adapt to new LPC DTS layout
ARM: dts: Remove LPC BMC and Host partitions
dt-bindings: aspeed-lpc: Remove LPC partitioning
soc: fsl: enable acpi support in RCPM driver
soc: qcom: mdt_loader: Detect truncated read of segments
soc: qcom: mdt_loader: Validate that p_filesz < p_memsz
soc: qcom: pdr: Fix error return code in pdr_register_listener
firmware: qcom_scm: Fix kernel-doc function names to match
firmware: qcom_scm: Suppress sysfs bind attributes
firmware: qcom_scm: Workaround lack of "is available" call on SC7180
firmware: qcom_scm: Reduce locking section for __get_convention()
firmware: qcom_scm: Make __qcom_scm_is_call_available() return bool
Revert "soc: fsl: qe: introduce qe_io{read,write}* wrappers"
...
Diffstat (limited to 'drivers/firmware/arm_scmi/power.c')
-rw-r--r-- | drivers/firmware/arm_scmi/power.c | 134 |
1 files changed, 76 insertions, 58 deletions
diff --git a/drivers/firmware/arm_scmi/power.c b/drivers/firmware/arm_scmi/power.c index 1f37258e9bee..ad2ab080f344 100644 --- a/drivers/firmware/arm_scmi/power.c +++ b/drivers/firmware/arm_scmi/power.c @@ -2,11 +2,12 @@ /* * System Control and Management Interface (SCMI) Power Protocol * - * Copyright (C) 2018 ARM Ltd. + * Copyright (C) 2018-2021 ARM Ltd. */ #define pr_fmt(fmt) "SCMI Notifications POWER - " fmt +#include <linux/module.h> #include <linux/scmi_protocol.h> #include "common.h" @@ -68,21 +69,21 @@ struct scmi_power_info { struct power_dom_info *dom_info; }; -static int scmi_power_attributes_get(const struct scmi_handle *handle, +static int scmi_power_attributes_get(const struct scmi_protocol_handle *ph, struct scmi_power_info *pi) { int ret; struct scmi_xfer *t; struct scmi_msg_resp_power_attributes *attr; - ret = scmi_xfer_get_init(handle, PROTOCOL_ATTRIBUTES, - SCMI_PROTOCOL_POWER, 0, sizeof(*attr), &t); + ret = ph->xops->xfer_get_init(ph, PROTOCOL_ATTRIBUTES, + 0, sizeof(*attr), &t); if (ret) return ret; attr = t->rx.buf; - ret = scmi_do_xfer(handle, t); + ret = ph->xops->do_xfer(ph, t); if (!ret) { pi->num_domains = le16_to_cpu(attr->num_domains); pi->stats_addr = le32_to_cpu(attr->stats_addr_low) | @@ -90,28 +91,27 @@ static int scmi_power_attributes_get(const struct scmi_handle *handle, pi->stats_size = le32_to_cpu(attr->stats_size); } - scmi_xfer_put(handle, t); + ph->xops->xfer_put(ph, t); return ret; } static int -scmi_power_domain_attributes_get(const struct scmi_handle *handle, u32 domain, - struct power_dom_info *dom_info) +scmi_power_domain_attributes_get(const struct scmi_protocol_handle *ph, + u32 domain, struct power_dom_info *dom_info) { int ret; struct scmi_xfer *t; struct scmi_msg_resp_power_domain_attributes *attr; - ret = scmi_xfer_get_init(handle, POWER_DOMAIN_ATTRIBUTES, - SCMI_PROTOCOL_POWER, sizeof(domain), - sizeof(*attr), &t); + ret = ph->xops->xfer_get_init(ph, POWER_DOMAIN_ATTRIBUTES, + sizeof(domain), sizeof(*attr), &t); if (ret) return ret; put_unaligned_le32(domain, t->tx.buf); attr = t->rx.buf; - ret = scmi_do_xfer(handle, t); + ret = ph->xops->do_xfer(ph, t); if (!ret) { u32 flags = le32_to_cpu(attr->flags); @@ -121,19 +121,18 @@ scmi_power_domain_attributes_get(const struct scmi_handle *handle, u32 domain, strlcpy(dom_info->name, attr->name, SCMI_MAX_STR_SIZE); } - scmi_xfer_put(handle, t); + ph->xops->xfer_put(ph, t); return ret; } -static int -scmi_power_state_set(const struct scmi_handle *handle, u32 domain, u32 state) +static int scmi_power_state_set(const struct scmi_protocol_handle *ph, + u32 domain, u32 state) { int ret; struct scmi_xfer *t; struct scmi_power_set_state *st; - ret = scmi_xfer_get_init(handle, POWER_STATE_SET, SCMI_PROTOCOL_POWER, - sizeof(*st), 0, &t); + ret = ph->xops->xfer_get_init(ph, POWER_STATE_SET, sizeof(*st), 0, &t); if (ret) return ret; @@ -142,64 +141,64 @@ scmi_power_state_set(const struct scmi_handle *handle, u32 domain, u32 state) st->domain = cpu_to_le32(domain); st->state = cpu_to_le32(state); - ret = scmi_do_xfer(handle, t); + ret = ph->xops->do_xfer(ph, t); - scmi_xfer_put(handle, t); + ph->xops->xfer_put(ph, t); return ret; } -static int -scmi_power_state_get(const struct scmi_handle *handle, u32 domain, u32 *state) +static int scmi_power_state_get(const struct scmi_protocol_handle *ph, + u32 domain, u32 *state) { int ret; struct scmi_xfer *t; - ret = scmi_xfer_get_init(handle, POWER_STATE_GET, SCMI_PROTOCOL_POWER, - sizeof(u32), sizeof(u32), &t); + ret = ph->xops->xfer_get_init(ph, POWER_STATE_GET, sizeof(u32), sizeof(u32), &t); if (ret) return ret; put_unaligned_le32(domain, t->tx.buf); - ret = scmi_do_xfer(handle, t); + ret = ph->xops->do_xfer(ph, t); if (!ret) *state = get_unaligned_le32(t->rx.buf); - scmi_xfer_put(handle, t); + ph->xops->xfer_put(ph, t); return ret; } -static int scmi_power_num_domains_get(const struct scmi_handle *handle) +static int scmi_power_num_domains_get(const struct scmi_protocol_handle *ph) { - struct scmi_power_info *pi = handle->power_priv; + struct scmi_power_info *pi = ph->get_priv(ph); return pi->num_domains; } -static char *scmi_power_name_get(const struct scmi_handle *handle, u32 domain) +static char *scmi_power_name_get(const struct scmi_protocol_handle *ph, + u32 domain) { - struct scmi_power_info *pi = handle->power_priv; + struct scmi_power_info *pi = ph->get_priv(ph); struct power_dom_info *dom = pi->dom_info + domain; return dom->name; } -static const struct scmi_power_ops power_ops = { +static const struct scmi_power_proto_ops power_proto_ops = { .num_domains_get = scmi_power_num_domains_get, .name_get = scmi_power_name_get, .state_set = scmi_power_state_set, .state_get = scmi_power_state_get, }; -static int scmi_power_request_notify(const struct scmi_handle *handle, +static int scmi_power_request_notify(const struct scmi_protocol_handle *ph, u32 domain, bool enable) { int ret; struct scmi_xfer *t; struct scmi_power_state_notify *notify; - ret = scmi_xfer_get_init(handle, POWER_STATE_NOTIFY, - SCMI_PROTOCOL_POWER, sizeof(*notify), 0, &t); + ret = ph->xops->xfer_get_init(ph, POWER_STATE_NOTIFY, + sizeof(*notify), 0, &t); if (ret) return ret; @@ -207,18 +206,18 @@ static int scmi_power_request_notify(const struct scmi_handle *handle, notify->domain = cpu_to_le32(domain); notify->notify_enable = enable ? cpu_to_le32(BIT(0)) : 0; - ret = scmi_do_xfer(handle, t); + ret = ph->xops->do_xfer(ph, t); - scmi_xfer_put(handle, t); + ph->xops->xfer_put(ph, t); return ret; } -static int scmi_power_set_notify_enabled(const struct scmi_handle *handle, +static int scmi_power_set_notify_enabled(const struct scmi_protocol_handle *ph, u8 evt_id, u32 src_id, bool enable) { int ret; - ret = scmi_power_request_notify(handle, src_id, enable); + ret = scmi_power_request_notify(ph, src_id, enable); if (ret) pr_debug("FAIL_ENABLE - evt[%X] dom[%d] - ret:%d\n", evt_id, src_id, ret); @@ -226,10 +225,11 @@ static int scmi_power_set_notify_enabled(const struct scmi_handle *handle, return ret; } -static void *scmi_power_fill_custom_report(const struct scmi_handle *handle, - u8 evt_id, ktime_t timestamp, - const void *payld, size_t payld_sz, - void *report, u32 *src_id) +static void * +scmi_power_fill_custom_report(const struct scmi_protocol_handle *ph, + u8 evt_id, ktime_t timestamp, + const void *payld, size_t payld_sz, + void *report, u32 *src_id) { const struct scmi_power_state_notify_payld *p = payld; struct scmi_power_state_changed_report *r = report; @@ -246,6 +246,16 @@ static void *scmi_power_fill_custom_report(const struct scmi_handle *handle, return r; } +static int scmi_power_get_num_sources(const struct scmi_protocol_handle *ph) +{ + struct scmi_power_info *pinfo = ph->get_priv(ph); + + if (!pinfo) + return -EINVAL; + + return pinfo->num_domains; +} + static const struct scmi_event power_events[] = { { .id = SCMI_EVENT_POWER_STATE_CHANGED, @@ -256,28 +266,36 @@ static const struct scmi_event power_events[] = { }; static const struct scmi_event_ops power_event_ops = { + .get_num_sources = scmi_power_get_num_sources, .set_notify_enabled = scmi_power_set_notify_enabled, .fill_custom_report = scmi_power_fill_custom_report, }; -static int scmi_power_protocol_init(struct scmi_handle *handle) +static const struct scmi_protocol_events power_protocol_events = { + .queue_sz = SCMI_PROTO_QUEUE_SZ, + .ops = &power_event_ops, + .evts = power_events, + .num_events = ARRAY_SIZE(power_events), +}; + +static int scmi_power_protocol_init(const struct scmi_protocol_handle *ph) { int domain; u32 version; struct scmi_power_info *pinfo; - scmi_version_get(handle, SCMI_PROTOCOL_POWER, &version); + ph->xops->version_get(ph, &version); - dev_dbg(handle->dev, "Power Version %d.%d\n", + dev_dbg(ph->dev, "Power Version %d.%d\n", PROTOCOL_REV_MAJOR(version), PROTOCOL_REV_MINOR(version)); - pinfo = devm_kzalloc(handle->dev, sizeof(*pinfo), GFP_KERNEL); + pinfo = devm_kzalloc(ph->dev, sizeof(*pinfo), GFP_KERNEL); if (!pinfo) return -ENOMEM; - scmi_power_attributes_get(handle, pinfo); + scmi_power_attributes_get(ph, pinfo); - pinfo->dom_info = devm_kcalloc(handle->dev, pinfo->num_domains, + pinfo->dom_info = devm_kcalloc(ph->dev, pinfo->num_domains, sizeof(*pinfo->dom_info), GFP_KERNEL); if (!pinfo->dom_info) return -ENOMEM; @@ -285,20 +303,20 @@ static int scmi_power_protocol_init(struct scmi_handle *handle) for (domain = 0; domain < pinfo->num_domains; domain++) { struct power_dom_info *dom = pinfo->dom_info + domain; - scmi_power_domain_attributes_get(handle, domain, dom); + scmi_power_domain_attributes_get(ph, domain, dom); } - scmi_register_protocol_events(handle, - SCMI_PROTOCOL_POWER, SCMI_PROTO_QUEUE_SZ, - &power_event_ops, power_events, - ARRAY_SIZE(power_events), - pinfo->num_domains); - pinfo->version = version; - handle->power_ops = &power_ops; - handle->power_priv = pinfo; - return 0; + return ph->set_priv(ph, pinfo); } -DEFINE_SCMI_PROTOCOL_REGISTER_UNREGISTER(SCMI_PROTOCOL_POWER, power) +static const struct scmi_protocol scmi_power = { + .id = SCMI_PROTOCOL_POWER, + .owner = THIS_MODULE, + .instance_init = &scmi_power_protocol_init, + .ops = &power_proto_ops, + .events = &power_protocol_events, +}; + +DEFINE_SCMI_PROTOCOL_REGISTER_UNREGISTER(power, scmi_power) |