mirror of
https://github.com/torvalds/linux.git
synced 2026-04-18 06:44:00 -04:00
Merge tag 'soc-drivers-7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc
Pull SoC driver updates from Arnd Bergmann:
"The driver updates again are all over the place with many minor fixes
going into platform specific code. The most notable changes are:
- Support for Microchip pic64gx system controllers
- Work on cleaning up devicetree bindings for SoC drivers, and
converting them into the new format
- Lots of smaller changes for Qualcomm SoC drivers, including support
for a number of newly supported chips
- reset controller API cleanups and a new driver for Cix Sky1
- Reworks of the Tegra PMC and CBB drivers, along with a change to
how individual Tegra SoCs get selected in Kconfig and BPMP firmware
driver updates including a refresh of the ABI header to match the
version used by firmware
- STM32 updates to the firewall bus driver and support for the debug
bus through OP-TEE
- SCMI firmware driver improvements for reliability, in particular
for dealing with broken firmware interrupts
- Memory driver updates for Tegra, and a patch to remove the unused
Baikal T1 driver"
* tag 'soc-drivers-7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc: (193 commits)
firmware: arm_ffa: Use the correct buffer size during RXTX_MAP
firmware: qcom: scm: Allow QSEECOM on Lenovo IdeaCentre Mini X
clk: spear: fix resource leak in clk_register_vco_pll()
reset: rzv2h-usb2phy: Add support for VBUS mux controller registration
reset: rzv2h-usb2phy: Convert to regmap API
dt-bindings: reset: renesas,rzv2h-usb2phy: Document RZ/G3E USB2PHY reset
dt-bindings: reset: renesas,rzv2h-usb2phy: Add '#mux-state-cells' property
soc: microchip: add mpfs gpio interrupt mux driver
dt-bindings: soc: microchip: document PolarFire SoC's gpio interrupt mux
gpio: mpfs: Add interrupt support
soc: qcom: ubwc: add helpers to get programmable values
soc: qcom: ubwc: add helper to get min_acc length
firmware: qcom: scm: Register gunyah watchdog device
soc: qcom: socinfo: Add SoC ID for SA8650P
dt-bindings: arm: qcom,ids: Add SoC ID for SA8650P
firmware: qcom: scm: Allow QSEECOM on Mahua CRD
soc: qcom: wcnss: simplify allocation of req
soc: qcom: pd-mapper: Add support for Eliza
soc: qcom: aoss: compare against normalized cooling state
soc: qcom: llcc: fix v1 SB syndrome register offset
...
This commit is contained in:
@@ -2078,7 +2078,7 @@ static int __init ffa_init(void)
|
||||
|
||||
ret = ffa_rxtx_map(virt_to_phys(drv_info->tx_buffer),
|
||||
virt_to_phys(drv_info->rx_buffer),
|
||||
rxtx_bufsz / FFA_PAGE_SIZE);
|
||||
PAGE_ALIGN(rxtx_bufsz) / FFA_PAGE_SIZE);
|
||||
if (ret) {
|
||||
pr_err("failed to register FFA RxTx buffers\n");
|
||||
goto free_pages;
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#define pr_fmt(fmt) "SCMI Notifications BASE - " fmt
|
||||
|
||||
#include <linux/math.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/scmi_protocol.h>
|
||||
|
||||
@@ -219,8 +220,7 @@ scmi_base_implementation_list_get(const struct scmi_protocol_handle *ph,
|
||||
}
|
||||
|
||||
real_list_sz = t->rx.len - sizeof(u32);
|
||||
calc_list_sz = (1 + (loop_num_ret - 1) / sizeof(u32)) *
|
||||
sizeof(u32);
|
||||
calc_list_sz = round_up(loop_num_ret, sizeof(u32));
|
||||
if (calc_list_sz != real_list_sz) {
|
||||
dev_warn(dev,
|
||||
"Malformed reply - real_sz:%zd calc_sz:%u (loop_num_ret:%d)\n",
|
||||
|
||||
@@ -235,6 +235,9 @@ struct scmi_transport_ops {
|
||||
* to have an execution latency lesser-equal to the threshold
|
||||
* should be considered for atomic mode operation: such
|
||||
* decision is finally left up to the SCMI drivers.
|
||||
* @no_completion_irq: Flag to indicate that this transport has no completion
|
||||
* interrupt and has to be polled. This is similar to the
|
||||
* force_polling below, except this is set via DT property.
|
||||
* @force_polling: Flag to force this whole transport to use SCMI core polling
|
||||
* mechanism instead of completion interrupts even if available.
|
||||
* @sync_cmds_completed_on_ret: Flag to indicate that the transport assures
|
||||
@@ -254,6 +257,7 @@ struct scmi_desc {
|
||||
int max_msg;
|
||||
int max_msg_size;
|
||||
unsigned int atomic_threshold;
|
||||
bool no_completion_irq;
|
||||
const bool force_polling;
|
||||
const bool sync_cmds_completed_on_ret;
|
||||
const bool atomic_enabled;
|
||||
|
||||
@@ -2735,6 +2735,7 @@ static int scmi_chan_setup(struct scmi_info *info, struct device_node *of_node,
|
||||
cinfo->is_p2a = !tx;
|
||||
cinfo->rx_timeout_ms = info->desc->max_rx_timeout_ms;
|
||||
cinfo->max_msg_size = info->desc->max_msg_size;
|
||||
cinfo->no_completion_irq = info->desc->no_completion_irq;
|
||||
|
||||
/* Create a unique name for this transport device */
|
||||
snprintf(name, 32, "__scmi_transport_device_%s_%02X",
|
||||
@@ -3150,6 +3151,9 @@ static const struct scmi_desc *scmi_transport_setup(struct device *dev)
|
||||
if (ret && ret != -EINVAL)
|
||||
dev_err(dev, "Malformed arm,max-msg DT property.\n");
|
||||
|
||||
trans->desc.no_completion_irq = of_property_read_bool(dev->of_node,
|
||||
"arm,no-completion-irq");
|
||||
|
||||
dev_info(dev,
|
||||
"SCMI max-rx-timeout: %dms / max-msg-size: %dbytes / max-msg: %d\n",
|
||||
trans->desc.max_rx_timeout_ms, trans->desc.max_msg_size,
|
||||
|
||||
@@ -20,10 +20,10 @@
|
||||
* named as _qn.
|
||||
*/
|
||||
#define SCMI_QUIRK(_qn, _blk) \
|
||||
do { \
|
||||
({ \
|
||||
if (static_branch_unlikely(&(scmi_quirk_ ## _qn))) \
|
||||
(_blk); \
|
||||
} while (0)
|
||||
})
|
||||
|
||||
void scmi_quirks_initialize(void);
|
||||
void scmi_quirks_enable(struct device *dev, const char *vend,
|
||||
@@ -34,10 +34,10 @@ void scmi_quirks_enable(struct device *dev, const char *vend,
|
||||
#define DECLARE_SCMI_QUIRK(_qn)
|
||||
/* Force quirks compilation even when SCMI Quirks are disabled */
|
||||
#define SCMI_QUIRK(_qn, _blk) \
|
||||
do { \
|
||||
({ \
|
||||
if (0) \
|
||||
(_blk); \
|
||||
} while (0)
|
||||
})
|
||||
|
||||
static inline void scmi_quirks_initialize(void) { }
|
||||
static inline void scmi_quirks_enable(struct device *dev, const char *vend,
|
||||
|
||||
@@ -699,20 +699,18 @@ static DEFINE_MUTEX(__qcuefi_lock);
|
||||
|
||||
static int qcuefi_set_reference(struct qcuefi_client *qcuefi)
|
||||
{
|
||||
mutex_lock(&__qcuefi_lock);
|
||||
guard(mutex)(&__qcuefi_lock);
|
||||
|
||||
if (qcuefi && __qcuefi) {
|
||||
mutex_unlock(&__qcuefi_lock);
|
||||
if (qcuefi && __qcuefi)
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
__qcuefi = qcuefi;
|
||||
|
||||
mutex_unlock(&__qcuefi_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct qcuefi_client *qcuefi_acquire(void)
|
||||
__acquires(__qcuefi_lock)
|
||||
{
|
||||
mutex_lock(&__qcuefi_lock);
|
||||
if (!__qcuefi) {
|
||||
@@ -723,6 +721,7 @@ static struct qcuefi_client *qcuefi_acquire(void)
|
||||
}
|
||||
|
||||
static void qcuefi_release(void)
|
||||
__releases(__qcuefi_lock)
|
||||
{
|
||||
mutex_unlock(&__qcuefi_lock);
|
||||
}
|
||||
|
||||
@@ -199,19 +199,18 @@ static int qcom_scm_bw_enable(void)
|
||||
if (!__scm->path)
|
||||
return 0;
|
||||
|
||||
mutex_lock(&__scm->scm_bw_lock);
|
||||
guard(mutex)(&__scm->scm_bw_lock);
|
||||
|
||||
if (!__scm->scm_vote_count) {
|
||||
ret = icc_set_bw(__scm->path, 0, UINT_MAX);
|
||||
if (ret < 0) {
|
||||
dev_err(__scm->dev, "failed to set bandwidth request\n");
|
||||
goto err_bw;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
__scm->scm_vote_count++;
|
||||
err_bw:
|
||||
mutex_unlock(&__scm->scm_bw_lock);
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void qcom_scm_bw_disable(void)
|
||||
@@ -923,14 +922,13 @@ struct resource_table *qcom_scm_pas_get_rsc_table(struct qcom_scm_pas_context *c
|
||||
goto free_input_rt;
|
||||
}
|
||||
|
||||
tbl_ptr = kzalloc(size, GFP_KERNEL);
|
||||
tbl_ptr = kmemdup(output_rt_tzm, size, GFP_KERNEL);
|
||||
if (!tbl_ptr) {
|
||||
qcom_tzmem_free(output_rt_tzm);
|
||||
ret = -ENOMEM;
|
||||
goto free_input_rt;
|
||||
}
|
||||
|
||||
memcpy(tbl_ptr, output_rt_tzm, size);
|
||||
*output_rt_size = size;
|
||||
qcom_tzmem_free(output_rt_tzm);
|
||||
|
||||
@@ -2290,15 +2288,18 @@ EXPORT_SYMBOL_GPL(qcom_scm_qseecom_app_send);
|
||||
*/
|
||||
static const struct of_device_id qcom_scm_qseecom_allowlist[] __maybe_unused = {
|
||||
{ .compatible = "asus,vivobook-s15" },
|
||||
{ .compatible = "asus,vivobook-s15-x1p4" },
|
||||
{ .compatible = "asus,zenbook-a14-ux3407qa" },
|
||||
{ .compatible = "asus,zenbook-a14-ux3407ra" },
|
||||
{ .compatible = "dell,inspiron-14-plus-7441" },
|
||||
{ .compatible = "dell,latitude-7455" },
|
||||
{ .compatible = "dell,xps13-9345" },
|
||||
{ .compatible = "ecs,liva-qc710" },
|
||||
{ .compatible = "hp,elitebook-ultra-g1q" },
|
||||
{ .compatible = "hp,omnibook-x14" },
|
||||
{ .compatible = "huawei,gaokun3" },
|
||||
{ .compatible = "lenovo,flex-5g" },
|
||||
{ .compatible = "lenovo,ideacentre-mini-01q8x10" },
|
||||
{ .compatible = "lenovo,thinkbook-16" },
|
||||
{ .compatible = "lenovo,thinkpad-t14s" },
|
||||
{ .compatible = "lenovo,thinkpad-x13s", },
|
||||
@@ -2309,7 +2310,10 @@ static const struct of_device_id qcom_scm_qseecom_allowlist[] __maybe_unused = {
|
||||
{ .compatible = "microsoft,denali", },
|
||||
{ .compatible = "microsoft,romulus13", },
|
||||
{ .compatible = "microsoft,romulus15", },
|
||||
{ .compatible = "qcom,glymur-crd" },
|
||||
{ .compatible = "qcom,hamoa-iot-evk" },
|
||||
{ .compatible = "qcom,mahua-crd" },
|
||||
{ .compatible = "qcom,purwa-iot-evk" },
|
||||
{ .compatible = "qcom,sc8180x-primus" },
|
||||
{ .compatible = "qcom,x1e001de-devkit" },
|
||||
{ .compatible = "qcom,x1e80100-crd" },
|
||||
@@ -2467,6 +2471,56 @@ int qcom_scm_qtee_callback_response(phys_addr_t buf, size_t buf_size,
|
||||
}
|
||||
EXPORT_SYMBOL(qcom_scm_qtee_callback_response);
|
||||
|
||||
static void qcom_scm_gunyah_wdt_free(void *data)
|
||||
{
|
||||
struct platform_device *gunyah_wdt_dev = data;
|
||||
|
||||
platform_device_unregister(gunyah_wdt_dev);
|
||||
}
|
||||
|
||||
static void qcom_scm_gunyah_wdt_init(struct qcom_scm *scm)
|
||||
{
|
||||
struct platform_device *gunyah_wdt_dev;
|
||||
struct device_node *np;
|
||||
bool of_wdt_available;
|
||||
int i;
|
||||
static const uuid_t gunyah_uuid = UUID_INIT(0xc1d58fcd, 0xa453, 0x5fdb,
|
||||
0x92, 0x65, 0xce, 0x36,
|
||||
0x67, 0x3d, 0x5f, 0x14);
|
||||
static const char * const of_wdt_compatible[] = {
|
||||
"qcom,kpss-wdt",
|
||||
"arm,sbsa-gwdt",
|
||||
};
|
||||
|
||||
/* Bail out if we are not running under Gunyah */
|
||||
if (!IS_ENABLED(CONFIG_HAVE_ARM_SMCCC_DISCOVERY) ||
|
||||
!arm_smccc_hypervisor_has_uuid(&gunyah_uuid))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Gunyah emulates either of Qualcomm watchdog or ARM SBSA watchdog on
|
||||
* newer platforms. Bail out if we find them in the devicetree.
|
||||
*/
|
||||
for (i = 0; i < ARRAY_SIZE(of_wdt_compatible); i++) {
|
||||
np = of_find_compatible_node(NULL, NULL, of_wdt_compatible[i]);
|
||||
of_wdt_available = of_device_is_available(np);
|
||||
of_node_put(np);
|
||||
if (of_wdt_available)
|
||||
return;
|
||||
}
|
||||
|
||||
gunyah_wdt_dev = platform_device_register_simple("gunyah-wdt", -1,
|
||||
NULL, 0);
|
||||
if (IS_ERR(gunyah_wdt_dev)) {
|
||||
dev_err(scm->dev, "Failed to register Gunyah watchdog device: %ld\n",
|
||||
PTR_ERR(gunyah_wdt_dev));
|
||||
return;
|
||||
}
|
||||
|
||||
devm_add_action_or_reset(scm->dev, qcom_scm_gunyah_wdt_free,
|
||||
gunyah_wdt_dev);
|
||||
}
|
||||
|
||||
static void qcom_scm_qtee_free(void *data)
|
||||
{
|
||||
struct platform_device *qtee_dev = data;
|
||||
@@ -2811,6 +2865,9 @@ static int qcom_scm_probe(struct platform_device *pdev)
|
||||
/* Initialize the QTEE object interface. */
|
||||
qcom_scm_qtee_init(scm);
|
||||
|
||||
/* Initialize the Gunyah watchdog platform device. */
|
||||
qcom_scm_gunyah_wdt_init(scm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
* Copyright 2025 Linaro Ltd.
|
||||
*/
|
||||
|
||||
#include <linux/array_size.h>
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/firmware/samsung/exynos-acpm-protocol.h>
|
||||
#include <linux/ktime.h>
|
||||
@@ -24,12 +25,12 @@ static void acpm_dvfs_set_xfer(struct acpm_xfer *xfer, u32 *cmd, size_t cmdlen,
|
||||
unsigned int acpm_chan_id, bool response)
|
||||
{
|
||||
xfer->acpm_chan_id = acpm_chan_id;
|
||||
xfer->txcnt = cmdlen;
|
||||
xfer->txd = cmd;
|
||||
xfer->txlen = cmdlen;
|
||||
|
||||
if (response) {
|
||||
xfer->rxcnt = cmdlen;
|
||||
xfer->rxd = cmd;
|
||||
xfer->rxlen = cmdlen;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +43,7 @@ static void acpm_dvfs_init_set_rate_cmd(u32 cmd[4], unsigned int clk_id,
|
||||
cmd[3] = ktime_to_ms(ktime_get());
|
||||
}
|
||||
|
||||
int acpm_dvfs_set_rate(const struct acpm_handle *handle,
|
||||
int acpm_dvfs_set_rate(struct acpm_handle *handle,
|
||||
unsigned int acpm_chan_id, unsigned int clk_id,
|
||||
unsigned long rate)
|
||||
{
|
||||
@@ -50,7 +51,7 @@ int acpm_dvfs_set_rate(const struct acpm_handle *handle,
|
||||
u32 cmd[4];
|
||||
|
||||
acpm_dvfs_init_set_rate_cmd(cmd, clk_id, rate);
|
||||
acpm_dvfs_set_xfer(&xfer, cmd, sizeof(cmd), acpm_chan_id, false);
|
||||
acpm_dvfs_set_xfer(&xfer, cmd, ARRAY_SIZE(cmd), acpm_chan_id, false);
|
||||
|
||||
return acpm_do_xfer(handle, &xfer);
|
||||
}
|
||||
@@ -62,7 +63,7 @@ static void acpm_dvfs_init_get_rate_cmd(u32 cmd[4], unsigned int clk_id)
|
||||
cmd[3] = ktime_to_ms(ktime_get());
|
||||
}
|
||||
|
||||
unsigned long acpm_dvfs_get_rate(const struct acpm_handle *handle,
|
||||
unsigned long acpm_dvfs_get_rate(struct acpm_handle *handle,
|
||||
unsigned int acpm_chan_id, unsigned int clk_id)
|
||||
{
|
||||
struct acpm_xfer xfer;
|
||||
@@ -70,7 +71,7 @@ unsigned long acpm_dvfs_get_rate(const struct acpm_handle *handle,
|
||||
int ret;
|
||||
|
||||
acpm_dvfs_init_get_rate_cmd(cmd, clk_id);
|
||||
acpm_dvfs_set_xfer(&xfer, cmd, sizeof(cmd), acpm_chan_id, true);
|
||||
acpm_dvfs_set_xfer(&xfer, cmd, ARRAY_SIZE(cmd), acpm_chan_id, true);
|
||||
|
||||
ret = acpm_do_xfer(handle, &xfer);
|
||||
if (ret)
|
||||
|
||||
@@ -11,10 +11,10 @@
|
||||
|
||||
struct acpm_handle;
|
||||
|
||||
int acpm_dvfs_set_rate(const struct acpm_handle *handle,
|
||||
int acpm_dvfs_set_rate(struct acpm_handle *handle,
|
||||
unsigned int acpm_chan_id, unsigned int id,
|
||||
unsigned long rate);
|
||||
unsigned long acpm_dvfs_get_rate(const struct acpm_handle *handle,
|
||||
unsigned long acpm_dvfs_get_rate(struct acpm_handle *handle,
|
||||
unsigned int acpm_chan_id,
|
||||
unsigned int clk_id);
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ static const int acpm_pmic_linux_errmap[] = {
|
||||
[2] = -EACCES, /* Write register can't be accessed or issues to access it. */
|
||||
};
|
||||
|
||||
static int acpm_pmic_to_linux_err(int err)
|
||||
static int acpm_pmic_to_linux_err(unsigned int err)
|
||||
{
|
||||
if (err >= 0 && err < ARRAY_SIZE(acpm_pmic_linux_errmap))
|
||||
return acpm_pmic_linux_errmap[err];
|
||||
@@ -63,8 +63,8 @@ static void acpm_pmic_set_xfer(struct acpm_xfer *xfer, u32 *cmd, size_t cmdlen,
|
||||
{
|
||||
xfer->txd = cmd;
|
||||
xfer->rxd = cmd;
|
||||
xfer->txlen = cmdlen;
|
||||
xfer->rxlen = cmdlen;
|
||||
xfer->txcnt = cmdlen;
|
||||
xfer->rxcnt = cmdlen;
|
||||
xfer->acpm_chan_id = acpm_chan_id;
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ static void acpm_pmic_init_read_cmd(u32 cmd[4], u8 type, u8 reg, u8 chan)
|
||||
cmd[3] = ktime_to_ms(ktime_get());
|
||||
}
|
||||
|
||||
int acpm_pmic_read_reg(const struct acpm_handle *handle,
|
||||
int acpm_pmic_read_reg(struct acpm_handle *handle,
|
||||
unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan,
|
||||
u8 *buf)
|
||||
{
|
||||
@@ -86,7 +86,7 @@ int acpm_pmic_read_reg(const struct acpm_handle *handle,
|
||||
int ret;
|
||||
|
||||
acpm_pmic_init_read_cmd(cmd, type, reg, chan);
|
||||
acpm_pmic_set_xfer(&xfer, cmd, sizeof(cmd), acpm_chan_id);
|
||||
acpm_pmic_set_xfer(&xfer, cmd, ARRAY_SIZE(cmd), acpm_chan_id);
|
||||
|
||||
ret = acpm_do_xfer(handle, &xfer);
|
||||
if (ret)
|
||||
@@ -107,7 +107,7 @@ static void acpm_pmic_init_bulk_read_cmd(u32 cmd[4], u8 type, u8 reg, u8 chan,
|
||||
FIELD_PREP(ACPM_PMIC_VALUE, count);
|
||||
}
|
||||
|
||||
int acpm_pmic_bulk_read(const struct acpm_handle *handle,
|
||||
int acpm_pmic_bulk_read(struct acpm_handle *handle,
|
||||
unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan,
|
||||
u8 count, u8 *buf)
|
||||
{
|
||||
@@ -119,7 +119,7 @@ int acpm_pmic_bulk_read(const struct acpm_handle *handle,
|
||||
return -EINVAL;
|
||||
|
||||
acpm_pmic_init_bulk_read_cmd(cmd, type, reg, chan, count);
|
||||
acpm_pmic_set_xfer(&xfer, cmd, sizeof(cmd), acpm_chan_id);
|
||||
acpm_pmic_set_xfer(&xfer, cmd, ARRAY_SIZE(cmd), acpm_chan_id);
|
||||
|
||||
ret = acpm_do_xfer(handle, &xfer);
|
||||
if (ret)
|
||||
@@ -150,7 +150,7 @@ static void acpm_pmic_init_write_cmd(u32 cmd[4], u8 type, u8 reg, u8 chan,
|
||||
cmd[3] = ktime_to_ms(ktime_get());
|
||||
}
|
||||
|
||||
int acpm_pmic_write_reg(const struct acpm_handle *handle,
|
||||
int acpm_pmic_write_reg(struct acpm_handle *handle,
|
||||
unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan,
|
||||
u8 value)
|
||||
{
|
||||
@@ -159,7 +159,7 @@ int acpm_pmic_write_reg(const struct acpm_handle *handle,
|
||||
int ret;
|
||||
|
||||
acpm_pmic_init_write_cmd(cmd, type, reg, chan, value);
|
||||
acpm_pmic_set_xfer(&xfer, cmd, sizeof(cmd), acpm_chan_id);
|
||||
acpm_pmic_set_xfer(&xfer, cmd, ARRAY_SIZE(cmd), acpm_chan_id);
|
||||
|
||||
ret = acpm_do_xfer(handle, &xfer);
|
||||
if (ret)
|
||||
@@ -187,7 +187,7 @@ static void acpm_pmic_init_bulk_write_cmd(u32 cmd[4], u8 type, u8 reg, u8 chan,
|
||||
}
|
||||
}
|
||||
|
||||
int acpm_pmic_bulk_write(const struct acpm_handle *handle,
|
||||
int acpm_pmic_bulk_write(struct acpm_handle *handle,
|
||||
unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan,
|
||||
u8 count, const u8 *buf)
|
||||
{
|
||||
@@ -199,7 +199,7 @@ int acpm_pmic_bulk_write(const struct acpm_handle *handle,
|
||||
return -EINVAL;
|
||||
|
||||
acpm_pmic_init_bulk_write_cmd(cmd, type, reg, chan, count, buf);
|
||||
acpm_pmic_set_xfer(&xfer, cmd, sizeof(cmd), acpm_chan_id);
|
||||
acpm_pmic_set_xfer(&xfer, cmd, ARRAY_SIZE(cmd), acpm_chan_id);
|
||||
|
||||
ret = acpm_do_xfer(handle, &xfer);
|
||||
if (ret)
|
||||
@@ -220,7 +220,7 @@ static void acpm_pmic_init_update_cmd(u32 cmd[4], u8 type, u8 reg, u8 chan,
|
||||
cmd[3] = ktime_to_ms(ktime_get());
|
||||
}
|
||||
|
||||
int acpm_pmic_update_reg(const struct acpm_handle *handle,
|
||||
int acpm_pmic_update_reg(struct acpm_handle *handle,
|
||||
unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan,
|
||||
u8 value, u8 mask)
|
||||
{
|
||||
@@ -229,7 +229,7 @@ int acpm_pmic_update_reg(const struct acpm_handle *handle,
|
||||
int ret;
|
||||
|
||||
acpm_pmic_init_update_cmd(cmd, type, reg, chan, value, mask);
|
||||
acpm_pmic_set_xfer(&xfer, cmd, sizeof(cmd), acpm_chan_id);
|
||||
acpm_pmic_set_xfer(&xfer, cmd, ARRAY_SIZE(cmd), acpm_chan_id);
|
||||
|
||||
ret = acpm_do_xfer(handle, &xfer);
|
||||
if (ret)
|
||||
|
||||
@@ -11,19 +11,19 @@
|
||||
|
||||
struct acpm_handle;
|
||||
|
||||
int acpm_pmic_read_reg(const struct acpm_handle *handle,
|
||||
int acpm_pmic_read_reg(struct acpm_handle *handle,
|
||||
unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan,
|
||||
u8 *buf);
|
||||
int acpm_pmic_bulk_read(const struct acpm_handle *handle,
|
||||
int acpm_pmic_bulk_read(struct acpm_handle *handle,
|
||||
unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan,
|
||||
u8 count, u8 *buf);
|
||||
int acpm_pmic_write_reg(const struct acpm_handle *handle,
|
||||
int acpm_pmic_write_reg(struct acpm_handle *handle,
|
||||
unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan,
|
||||
u8 value);
|
||||
int acpm_pmic_bulk_write(const struct acpm_handle *handle,
|
||||
int acpm_pmic_bulk_write(struct acpm_handle *handle,
|
||||
unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan,
|
||||
u8 count, const u8 *buf);
|
||||
int acpm_pmic_update_reg(const struct acpm_handle *handle,
|
||||
int acpm_pmic_update_reg(struct acpm_handle *handle,
|
||||
unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan,
|
||||
u8 value, u8 mask);
|
||||
#endif /* __EXYNOS_ACPM_PMIC_H__ */
|
||||
|
||||
@@ -205,7 +205,7 @@ static void acpm_get_saved_rx(struct acpm_chan *achan,
|
||||
rx_seqnum = FIELD_GET(ACPM_PROTOCOL_SEQNUM, rx_data->cmd[0]);
|
||||
|
||||
if (rx_seqnum == tx_seqnum) {
|
||||
memcpy(xfer->rxd, rx_data->cmd, xfer->rxlen);
|
||||
memcpy(xfer->rxd, rx_data->cmd, xfer->rxcnt * sizeof(*xfer->rxd));
|
||||
clear_bit(rx_seqnum - 1, achan->bitmap_seqnum);
|
||||
}
|
||||
}
|
||||
@@ -258,8 +258,7 @@ static int acpm_get_rx(struct acpm_chan *achan, const struct acpm_xfer *xfer)
|
||||
|
||||
if (rx_data->response) {
|
||||
if (rx_seqnum == tx_seqnum) {
|
||||
__ioread32_copy(xfer->rxd, addr,
|
||||
xfer->rxlen / 4);
|
||||
__ioread32_copy(xfer->rxd, addr, xfer->rxcnt);
|
||||
rx_set = true;
|
||||
clear_bit(seqnum, achan->bitmap_seqnum);
|
||||
} else {
|
||||
@@ -269,8 +268,7 @@ static int acpm_get_rx(struct acpm_chan *achan, const struct acpm_xfer *xfer)
|
||||
* clear yet the bitmap. It will be cleared
|
||||
* after the response is copied to the request.
|
||||
*/
|
||||
__ioread32_copy(rx_data->cmd, addr,
|
||||
xfer->rxlen / 4);
|
||||
__ioread32_copy(rx_data->cmd, addr, xfer->rxcnt);
|
||||
}
|
||||
} else {
|
||||
clear_bit(seqnum, achan->bitmap_seqnum);
|
||||
@@ -412,7 +410,7 @@ static int acpm_wait_for_message_response(struct acpm_chan *achan,
|
||||
*
|
||||
* Return: 0 on success, -errno otherwise.
|
||||
*/
|
||||
int acpm_do_xfer(const struct acpm_handle *handle, const struct acpm_xfer *xfer)
|
||||
int acpm_do_xfer(struct acpm_handle *handle, const struct acpm_xfer *xfer)
|
||||
{
|
||||
struct acpm_info *acpm = handle_to_acpm_info(handle);
|
||||
struct exynos_mbox_msg msg;
|
||||
@@ -425,7 +423,9 @@ int acpm_do_xfer(const struct acpm_handle *handle, const struct acpm_xfer *xfer)
|
||||
|
||||
achan = &acpm->chans[xfer->acpm_chan_id];
|
||||
|
||||
if (!xfer->txd || xfer->txlen > achan->mlen || xfer->rxlen > achan->mlen)
|
||||
if (!xfer->txd ||
|
||||
(xfer->txcnt * sizeof(*xfer->txd) > achan->mlen) ||
|
||||
(xfer->rxcnt * sizeof(*xfer->rxd) > achan->mlen))
|
||||
return -EINVAL;
|
||||
|
||||
if (!achan->poll_completion) {
|
||||
@@ -448,7 +448,7 @@ int acpm_do_xfer(const struct acpm_handle *handle, const struct acpm_xfer *xfer)
|
||||
|
||||
/* Write TX command. */
|
||||
__iowrite32_copy(achan->tx.base + achan->mlen * tx_front,
|
||||
xfer->txd, xfer->txlen / 4);
|
||||
xfer->txd, xfer->txcnt);
|
||||
|
||||
/* Advance TX front. */
|
||||
writel(idx, achan->tx.front);
|
||||
@@ -674,7 +674,7 @@ static int acpm_probe(struct platform_device *pdev)
|
||||
* acpm_handle_put() - release the handle acquired by acpm_get_by_phandle.
|
||||
* @handle: Handle acquired by acpm_get_by_phandle.
|
||||
*/
|
||||
static void acpm_handle_put(const struct acpm_handle *handle)
|
||||
static void acpm_handle_put(struct acpm_handle *handle)
|
||||
{
|
||||
struct acpm_info *acpm = handle_to_acpm_info(handle);
|
||||
struct device *dev = acpm->dev;
|
||||
@@ -700,9 +700,11 @@ static void devm_acpm_release(struct device *dev, void *res)
|
||||
* @np: ACPM device tree node.
|
||||
*
|
||||
* Return: pointer to handle on success, ERR_PTR(-errno) otherwise.
|
||||
*
|
||||
* Note: handle CANNOT be pointer to const
|
||||
*/
|
||||
static const struct acpm_handle *acpm_get_by_node(struct device *dev,
|
||||
struct device_node *np)
|
||||
static struct acpm_handle *acpm_get_by_node(struct device *dev,
|
||||
struct device_node *np)
|
||||
{
|
||||
struct platform_device *pdev;
|
||||
struct device_link *link;
|
||||
@@ -743,10 +745,10 @@ static const struct acpm_handle *acpm_get_by_node(struct device *dev,
|
||||
*
|
||||
* Return: pointer to handle on success, ERR_PTR(-errno) otherwise.
|
||||
*/
|
||||
const struct acpm_handle *devm_acpm_get_by_node(struct device *dev,
|
||||
struct device_node *np)
|
||||
struct acpm_handle *devm_acpm_get_by_node(struct device *dev,
|
||||
struct device_node *np)
|
||||
{
|
||||
const struct acpm_handle **ptr, *handle;
|
||||
struct acpm_handle **ptr, *handle;
|
||||
|
||||
ptr = devres_alloc(devm_acpm_release, sizeof(*ptr), GFP_KERNEL);
|
||||
if (!ptr)
|
||||
|
||||
@@ -8,16 +8,16 @@
|
||||
#define __EXYNOS_ACPM_H__
|
||||
|
||||
struct acpm_xfer {
|
||||
const u32 *txd;
|
||||
u32 *rxd;
|
||||
size_t txlen;
|
||||
size_t rxlen;
|
||||
const u32 *txd __counted_by_ptr(txcnt);
|
||||
u32 *rxd __counted_by_ptr(rxcnt);
|
||||
size_t txcnt;
|
||||
size_t rxcnt;
|
||||
unsigned int acpm_chan_id;
|
||||
};
|
||||
|
||||
struct acpm_handle;
|
||||
|
||||
int acpm_do_xfer(const struct acpm_handle *handle,
|
||||
int acpm_do_xfer(struct acpm_handle *handle,
|
||||
const struct acpm_xfer *xfer);
|
||||
|
||||
#endif /* __EXYNOS_ACPM_H__ */
|
||||
|
||||
@@ -32,6 +32,40 @@ channel_to_ops(struct tegra_bpmp_channel *channel)
|
||||
return bpmp->soc->ops;
|
||||
}
|
||||
|
||||
struct tegra_bpmp *tegra_bpmp_get_with_id(struct device *dev, unsigned int *id)
|
||||
{
|
||||
struct platform_device *pdev;
|
||||
struct of_phandle_args args;
|
||||
struct tegra_bpmp *bpmp;
|
||||
int err;
|
||||
|
||||
err = __of_parse_phandle_with_args(dev->of_node, "nvidia,bpmp", NULL,
|
||||
1, 0, &args);
|
||||
if (err < 0)
|
||||
return ERR_PTR(err);
|
||||
|
||||
pdev = of_find_device_by_node(args.np);
|
||||
if (!pdev) {
|
||||
bpmp = ERR_PTR(-ENODEV);
|
||||
goto put;
|
||||
}
|
||||
|
||||
bpmp = platform_get_drvdata(pdev);
|
||||
if (!bpmp) {
|
||||
bpmp = ERR_PTR(-EPROBE_DEFER);
|
||||
put_device(&pdev->dev);
|
||||
goto put;
|
||||
}
|
||||
|
||||
if (id)
|
||||
*id = args.args[0];
|
||||
|
||||
put:
|
||||
of_node_put(args.np);
|
||||
return bpmp;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(tegra_bpmp_get_with_id);
|
||||
|
||||
struct tegra_bpmp *tegra_bpmp_get(struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev;
|
||||
|
||||
Reference in New Issue
Block a user