summaryrefslogtreecommitdiffstats
path: root/drivers/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/firmware')
-rw-r--r--drivers/firmware/arm_ffa/driver.c101
-rw-r--r--drivers/firmware/broadcom/bcm47xx_nvram.c18
-rw-r--r--drivers/firmware/cirrus/Kconfig2
-rw-r--r--drivers/firmware/cirrus/Makefile2
-rw-r--r--drivers/firmware/cirrus/cs_dsp.c79
-rw-r--r--drivers/firmware/efi/cper.c3
-rw-r--r--drivers/firmware/efi/earlycon.c8
-rw-r--r--drivers/firmware/efi/efi-pstore.c2
-rw-r--r--drivers/firmware/efi/efi.c19
-rw-r--r--drivers/firmware/efi/libstub/Makefile1
-rw-r--r--drivers/firmware/imx/scu-pd.c1
-rw-r--r--drivers/firmware/raspberrypi.c47
-rw-r--r--drivers/firmware/tegra/Kconfig1
-rw-r--r--drivers/firmware/tegra/bpmp-debugfs.c62
-rw-r--r--drivers/firmware/tegra/bpmp-tegra186.c36
-rw-r--r--drivers/firmware/tegra/bpmp-tegra210.c15
-rw-r--r--drivers/firmware/tegra/bpmp.c33
-rw-r--r--drivers/firmware/tegra/ivc.c150
-rw-r--r--drivers/firmware/ti_sci.c24
-rw-r--r--drivers/firmware/xilinx/zynqmp.c7
20 files changed, 317 insertions, 294 deletions
diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
index d5e86ef40b89..fa85c64d3ded 100644
--- a/drivers/firmware/arm_ffa/driver.c
+++ b/drivers/firmware/arm_ffa/driver.c
@@ -36,81 +36,6 @@
#include "common.h"
#define FFA_DRIVER_VERSION FFA_VERSION_1_0
-
-#define FFA_SMC(calling_convention, func_num) \
- ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, (calling_convention), \
- ARM_SMCCC_OWNER_STANDARD, (func_num))
-
-#define FFA_SMC_32(func_num) FFA_SMC(ARM_SMCCC_SMC_32, (func_num))
-#define FFA_SMC_64(func_num) FFA_SMC(ARM_SMCCC_SMC_64, (func_num))
-
-#define FFA_ERROR FFA_SMC_32(0x60)
-#define FFA_SUCCESS FFA_SMC_32(0x61)
-#define FFA_INTERRUPT FFA_SMC_32(0x62)
-#define FFA_VERSION FFA_SMC_32(0x63)
-#define FFA_FEATURES FFA_SMC_32(0x64)
-#define FFA_RX_RELEASE FFA_SMC_32(0x65)
-#define FFA_RXTX_MAP FFA_SMC_32(0x66)
-#define FFA_FN64_RXTX_MAP FFA_SMC_64(0x66)
-#define FFA_RXTX_UNMAP FFA_SMC_32(0x67)
-#define FFA_PARTITION_INFO_GET FFA_SMC_32(0x68)
-#define FFA_ID_GET FFA_SMC_32(0x69)
-#define FFA_MSG_POLL FFA_SMC_32(0x6A)
-#define FFA_MSG_WAIT FFA_SMC_32(0x6B)
-#define FFA_YIELD FFA_SMC_32(0x6C)
-#define FFA_RUN FFA_SMC_32(0x6D)
-#define FFA_MSG_SEND FFA_SMC_32(0x6E)
-#define FFA_MSG_SEND_DIRECT_REQ FFA_SMC_32(0x6F)
-#define FFA_FN64_MSG_SEND_DIRECT_REQ FFA_SMC_64(0x6F)
-#define FFA_MSG_SEND_DIRECT_RESP FFA_SMC_32(0x70)
-#define FFA_FN64_MSG_SEND_DIRECT_RESP FFA_SMC_64(0x70)
-#define FFA_MEM_DONATE FFA_SMC_32(0x71)
-#define FFA_FN64_MEM_DONATE FFA_SMC_64(0x71)
-#define FFA_MEM_LEND FFA_SMC_32(0x72)
-#define FFA_FN64_MEM_LEND FFA_SMC_64(0x72)
-#define FFA_MEM_SHARE FFA_SMC_32(0x73)
-#define FFA_FN64_MEM_SHARE FFA_SMC_64(0x73)
-#define FFA_MEM_RETRIEVE_REQ FFA_SMC_32(0x74)
-#define FFA_FN64_MEM_RETRIEVE_REQ FFA_SMC_64(0x74)
-#define FFA_MEM_RETRIEVE_RESP FFA_SMC_32(0x75)
-#define FFA_MEM_RELINQUISH FFA_SMC_32(0x76)
-#define FFA_MEM_RECLAIM FFA_SMC_32(0x77)
-#define FFA_MEM_OP_PAUSE FFA_SMC_32(0x78)
-#define FFA_MEM_OP_RESUME FFA_SMC_32(0x79)
-#define FFA_MEM_FRAG_RX FFA_SMC_32(0x7A)
-#define FFA_MEM_FRAG_TX FFA_SMC_32(0x7B)
-#define FFA_NORMAL_WORLD_RESUME FFA_SMC_32(0x7C)
-
-/*
- * For some calls it is necessary to use SMC64 to pass or return 64-bit values.
- * For such calls FFA_FN_NATIVE(name) will choose the appropriate
- * (native-width) function ID.
- */
-#ifdef CONFIG_64BIT
-#define FFA_FN_NATIVE(name) FFA_FN64_##name
-#else
-#define FFA_FN_NATIVE(name) FFA_##name
-#endif
-
-/* FFA error codes. */
-#define FFA_RET_SUCCESS (0)
-#define FFA_RET_NOT_SUPPORTED (-1)
-#define FFA_RET_INVALID_PARAMETERS (-2)
-#define FFA_RET_NO_MEMORY (-3)
-#define FFA_RET_BUSY (-4)
-#define FFA_RET_INTERRUPTED (-5)
-#define FFA_RET_DENIED (-6)
-#define FFA_RET_RETRY (-7)
-#define FFA_RET_ABORTED (-8)
-
-#define MAJOR_VERSION_MASK GENMASK(30, 16)
-#define MINOR_VERSION_MASK GENMASK(15, 0)
-#define MAJOR_VERSION(x) ((u16)(FIELD_GET(MAJOR_VERSION_MASK, (x))))
-#define MINOR_VERSION(x) ((u16)(FIELD_GET(MINOR_VERSION_MASK, (x))))
-#define PACK_VERSION_INFO(major, minor) \
- (FIELD_PREP(MAJOR_VERSION_MASK, (major)) | \
- FIELD_PREP(MINOR_VERSION_MASK, (minor)))
-#define FFA_VERSION_1_0 PACK_VERSION_INFO(1, 0)
#define FFA_MIN_VERSION FFA_VERSION_1_0
#define SENDER_ID_MASK GENMASK(31, 16)
@@ -121,12 +46,6 @@
(FIELD_PREP(SENDER_ID_MASK, (s)) | FIELD_PREP(RECEIVER_ID_MASK, (r)))
/*
- * FF-A specification mentions explicitly about '4K pages'. This should
- * not be confused with the kernel PAGE_SIZE, which is the translation
- * granule kernel is configured and may be one among 4K, 16K and 64K.
- */
-#define FFA_PAGE_SIZE SZ_4K
-/*
* Keeping RX TX buffer size as 4K for now
* 64K may be preferred to keep it min a page in 64K PAGE_SIZE config
*/
@@ -178,9 +97,9 @@ static struct ffa_drv_info *drv_info;
*/
static u32 ffa_compatible_version_find(u32 version)
{
- u16 major = MAJOR_VERSION(version), minor = MINOR_VERSION(version);
- u16 drv_major = MAJOR_VERSION(FFA_DRIVER_VERSION);
- u16 drv_minor = MINOR_VERSION(FFA_DRIVER_VERSION);
+ u16 major = FFA_MAJOR_VERSION(version), minor = FFA_MINOR_VERSION(version);
+ u16 drv_major = FFA_MAJOR_VERSION(FFA_DRIVER_VERSION);
+ u16 drv_minor = FFA_MINOR_VERSION(FFA_DRIVER_VERSION);
if ((major < drv_major) || (major == drv_major && minor <= drv_minor))
return version;
@@ -204,16 +123,16 @@ static int ffa_version_check(u32 *version)
if (ver.a0 < FFA_MIN_VERSION) {
pr_err("Incompatible v%d.%d! Earliest supported v%d.%d\n",
- MAJOR_VERSION(ver.a0), MINOR_VERSION(ver.a0),
- MAJOR_VERSION(FFA_MIN_VERSION),
- MINOR_VERSION(FFA_MIN_VERSION));
+ FFA_MAJOR_VERSION(ver.a0), FFA_MINOR_VERSION(ver.a0),
+ FFA_MAJOR_VERSION(FFA_MIN_VERSION),
+ FFA_MINOR_VERSION(FFA_MIN_VERSION));
return -EINVAL;
}
- pr_info("Driver version %d.%d\n", MAJOR_VERSION(FFA_DRIVER_VERSION),
- MINOR_VERSION(FFA_DRIVER_VERSION));
- pr_info("Firmware version %d.%d found\n", MAJOR_VERSION(ver.a0),
- MINOR_VERSION(ver.a0));
+ pr_info("Driver version %d.%d\n", FFA_MAJOR_VERSION(FFA_DRIVER_VERSION),
+ FFA_MINOR_VERSION(FFA_DRIVER_VERSION));
+ pr_info("Firmware version %d.%d found\n", FFA_MAJOR_VERSION(ver.a0),
+ FFA_MINOR_VERSION(ver.a0));
*version = ffa_compatible_version_find(ver.a0);
return 0;
diff --git a/drivers/firmware/broadcom/bcm47xx_nvram.c b/drivers/firmware/broadcom/bcm47xx_nvram.c
index bd235833b687..5f47dbf4889a 100644
--- a/drivers/firmware/broadcom/bcm47xx_nvram.c
+++ b/drivers/firmware/broadcom/bcm47xx_nvram.c
@@ -110,6 +110,24 @@ found:
return 0;
}
+int bcm47xx_nvram_init_from_iomem(void __iomem *nvram_start, size_t res_size)
+{
+ if (nvram_len) {
+ pr_warn("nvram already initialized\n");
+ return -EEXIST;
+ }
+
+ if (!bcm47xx_nvram_is_valid(nvram_start)) {
+ pr_err("No valid NVRAM found\n");
+ return -ENOENT;
+ }
+
+ bcm47xx_nvram_copy(nvram_start, res_size);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(bcm47xx_nvram_init_from_iomem);
+
/*
* On bcm47xx we need access to the NVRAM very early, so we can't use mtd
* subsystem to access flash. We can't even use platform device / driver to
diff --git a/drivers/firmware/cirrus/Kconfig b/drivers/firmware/cirrus/Kconfig
index f9503cb481d2..3ccbe14e4b0c 100644
--- a/drivers/firmware/cirrus/Kconfig
+++ b/drivers/firmware/cirrus/Kconfig
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: GPL-2.0-only
-config CS_DSP
+config FW_CS_DSP
tristate
default n
diff --git a/drivers/firmware/cirrus/Makefile b/drivers/firmware/cirrus/Makefile
index f074e2638c9c..b91318ca0ff4 100644
--- a/drivers/firmware/cirrus/Makefile
+++ b/drivers/firmware/cirrus/Makefile
@@ -1,3 +1,3 @@
# SPDX-License-Identifier: GPL-2.0
#
-obj-$(CONFIG_CS_DSP) += cs_dsp.o
+obj-$(CONFIG_FW_CS_DSP) += cs_dsp.o
diff --git a/drivers/firmware/cirrus/cs_dsp.c b/drivers/firmware/cirrus/cs_dsp.c
index 81cc3d0f6eec..f558b390fbfe 100644
--- a/drivers/firmware/cirrus/cs_dsp.c
+++ b/drivers/firmware/cirrus/cs_dsp.c
@@ -369,7 +369,7 @@ const char *cs_dsp_mem_region_name(unsigned int type)
return NULL;
}
}
-EXPORT_SYMBOL_GPL(cs_dsp_mem_region_name);
+EXPORT_SYMBOL_NS_GPL(cs_dsp_mem_region_name, FW_CS_DSP);
#ifdef CONFIG_DEBUG_FS
static void cs_dsp_debugfs_save_wmfwname(struct cs_dsp *dsp, const char *s)
@@ -480,7 +480,7 @@ void cs_dsp_init_debugfs(struct cs_dsp *dsp, struct dentry *debugfs_root)
dsp->debugfs_root = root;
}
-EXPORT_SYMBOL_GPL(cs_dsp_init_debugfs);
+EXPORT_SYMBOL_NS_GPL(cs_dsp_init_debugfs, FW_CS_DSP);
/**
* cs_dsp_cleanup_debugfs() - Removes DSP representation from debugfs
@@ -492,17 +492,17 @@ void cs_dsp_cleanup_debugfs(struct cs_dsp *dsp)
debugfs_remove_recursive(dsp->debugfs_root);
dsp->debugfs_root = NULL;
}
-EXPORT_SYMBOL_GPL(cs_dsp_cleanup_debugfs);
+EXPORT_SYMBOL_NS_GPL(cs_dsp_cleanup_debugfs, FW_CS_DSP);
#else
void cs_dsp_init_debugfs(struct cs_dsp *dsp, struct dentry *debugfs_root)
{
}
-EXPORT_SYMBOL_GPL(cs_dsp_init_debugfs);
+EXPORT_SYMBOL_NS_GPL(cs_dsp_init_debugfs, FW_CS_DSP);
void cs_dsp_cleanup_debugfs(struct cs_dsp *dsp)
{
}
-EXPORT_SYMBOL_GPL(cs_dsp_cleanup_debugfs);
+EXPORT_SYMBOL_NS_GPL(cs_dsp_cleanup_debugfs, FW_CS_DSP);
static inline void cs_dsp_debugfs_save_wmfwname(struct cs_dsp *dsp,
const char *s)
@@ -710,7 +710,7 @@ int cs_dsp_coeff_write_acked_control(struct cs_dsp_coeff_ctl *ctl, unsigned int
return -ETIMEDOUT;
}
-EXPORT_SYMBOL_GPL(cs_dsp_coeff_write_acked_control);
+EXPORT_SYMBOL_NS_GPL(cs_dsp_coeff_write_acked_control, FW_CS_DSP);
static int cs_dsp_coeff_write_ctrl_raw(struct cs_dsp_coeff_ctl *ctl,
unsigned int off, const void *buf, size_t len)
@@ -752,7 +752,7 @@ static int cs_dsp_coeff_write_ctrl_raw(struct cs_dsp_coeff_ctl *ctl,
*
* Must be called with pwr_lock held.
*
- * Return: Zero for success, a negative number on error.
+ * Return: < 0 on error, 1 when the control value changed and 0 when it has not.
*/
int cs_dsp_coeff_write_ctrl(struct cs_dsp_coeff_ctl *ctl,
unsigned int off, const void *buf, size_t len)
@@ -767,18 +767,25 @@ int cs_dsp_coeff_write_ctrl(struct cs_dsp_coeff_ctl *ctl,
if (len + off * sizeof(u32) > ctl->len)
return -EINVAL;
- if (ctl->flags & WMFW_CTL_FLAG_VOLATILE)
+ if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) {
ret = -EPERM;
- else if (buf != ctl->cache)
- memcpy(ctl->cache + off * sizeof(u32), buf, len);
+ } else if (buf != ctl->cache) {
+ if (memcmp(ctl->cache + off * sizeof(u32), buf, len))
+ memcpy(ctl->cache + off * sizeof(u32), buf, len);
+ else
+ return 0;
+ }
ctl->set = 1;
if (ctl->enabled && ctl->dsp->running)
ret = cs_dsp_coeff_write_ctrl_raw(ctl, off, buf, len);
- return ret;
+ if (ret < 0)
+ return ret;
+
+ return 1;
}
-EXPORT_SYMBOL_GPL(cs_dsp_coeff_write_ctrl);
+EXPORT_SYMBOL_NS_GPL(cs_dsp_coeff_write_ctrl, FW_CS_DSP);
static int cs_dsp_coeff_read_ctrl_raw(struct cs_dsp_coeff_ctl *ctl,
unsigned int off, void *buf, size_t len)
@@ -850,7 +857,7 @@ int cs_dsp_coeff_read_ctrl(struct cs_dsp_coeff_ctl *ctl,
return ret;
}
-EXPORT_SYMBOL_GPL(cs_dsp_coeff_read_ctrl);
+EXPORT_SYMBOL_NS_GPL(cs_dsp_coeff_read_ctrl, FW_CS_DSP);
static int cs_dsp_coeff_init_control_caches(struct cs_dsp *dsp)
{
@@ -1493,7 +1500,7 @@ struct cs_dsp_coeff_ctl *cs_dsp_get_ctl(struct cs_dsp *dsp, const char *name, in
return rslt;
}
-EXPORT_SYMBOL_GPL(cs_dsp_get_ctl);
+EXPORT_SYMBOL_NS_GPL(cs_dsp_get_ctl, FW_CS_DSP);
static void cs_dsp_ctl_fixup_base(struct cs_dsp *dsp,
const struct cs_dsp_alg_region *alg_region)
@@ -1583,7 +1590,7 @@ struct cs_dsp_alg_region *cs_dsp_find_alg_region(struct cs_dsp *dsp,
return NULL;
}
-EXPORT_SYMBOL_GPL(cs_dsp_find_alg_region);
+EXPORT_SYMBOL_NS_GPL(cs_dsp_find_alg_region, FW_CS_DSP);
static struct cs_dsp_alg_region *cs_dsp_create_region(struct cs_dsp *dsp,
int type, __be32 id,
@@ -2217,7 +2224,7 @@ int cs_dsp_adsp1_init(struct cs_dsp *dsp)
return cs_dsp_common_init(dsp);
}
-EXPORT_SYMBOL_GPL(cs_dsp_adsp1_init);
+EXPORT_SYMBOL_NS_GPL(cs_dsp_adsp1_init, FW_CS_DSP);
/**
* cs_dsp_adsp1_power_up() - Load and start the named firmware
@@ -2309,7 +2316,7 @@ err_mutex:
mutex_unlock(&dsp->pwr_lock);
return ret;
}
-EXPORT_SYMBOL_GPL(cs_dsp_adsp1_power_up);
+EXPORT_SYMBOL_NS_GPL(cs_dsp_adsp1_power_up, FW_CS_DSP);
/**
* cs_dsp_adsp1_power_down() - Halts the DSP
@@ -2341,7 +2348,7 @@ void cs_dsp_adsp1_power_down(struct cs_dsp *dsp)
mutex_unlock(&dsp->pwr_lock);
}
-EXPORT_SYMBOL_GPL(cs_dsp_adsp1_power_down);
+EXPORT_SYMBOL_NS_GPL(cs_dsp_adsp1_power_down, FW_CS_DSP);
static int cs_dsp_adsp2v2_enable_core(struct cs_dsp *dsp)
{
@@ -2493,7 +2500,7 @@ int cs_dsp_set_dspclk(struct cs_dsp *dsp, unsigned int freq)
return ret;
}
-EXPORT_SYMBOL_GPL(cs_dsp_set_dspclk);
+EXPORT_SYMBOL_NS_GPL(cs_dsp_set_dspclk, FW_CS_DSP);
static void cs_dsp_stop_watchdog(struct cs_dsp *dsp)
{
@@ -2583,7 +2590,7 @@ err_mutex:
return ret;
}
-EXPORT_SYMBOL_GPL(cs_dsp_power_up);
+EXPORT_SYMBOL_NS_GPL(cs_dsp_power_up, FW_CS_DSP);
/**
* cs_dsp_power_down() - Powers-down the DSP
@@ -2617,7 +2624,7 @@ void cs_dsp_power_down(struct cs_dsp *dsp)
cs_dsp_dbg(dsp, "Shutdown complete\n");
}
-EXPORT_SYMBOL_GPL(cs_dsp_power_down);
+EXPORT_SYMBOL_NS_GPL(cs_dsp_power_down, FW_CS_DSP);
static int cs_dsp_adsp2_start_core(struct cs_dsp *dsp)
{
@@ -2703,7 +2710,7 @@ err:
return ret;
}
-EXPORT_SYMBOL_GPL(cs_dsp_run);
+EXPORT_SYMBOL_NS_GPL(cs_dsp_run, FW_CS_DSP);
/**
* cs_dsp_stop() - Stops the firmware
@@ -2742,7 +2749,7 @@ void cs_dsp_stop(struct cs_dsp *dsp)
cs_dsp_dbg(dsp, "Execution stopped\n");
}
-EXPORT_SYMBOL_GPL(cs_dsp_stop);
+EXPORT_SYMBOL_NS_GPL(cs_dsp_stop, FW_CS_DSP);
static int cs_dsp_halo_start_core(struct cs_dsp *dsp)
{
@@ -2804,7 +2811,7 @@ int cs_dsp_adsp2_init(struct cs_dsp *dsp)
return cs_dsp_common_init(dsp);
}
-EXPORT_SYMBOL_GPL(cs_dsp_adsp2_init);
+EXPORT_SYMBOL_NS_GPL(cs_dsp_adsp2_init, FW_CS_DSP);
/**
* cs_dsp_halo_init() - Initialise a cs_dsp structure representing a HALO Core DSP
@@ -2818,7 +2825,7 @@ int cs_dsp_halo_init(struct cs_dsp *dsp)
return cs_dsp_common_init(dsp);
}
-EXPORT_SYMBOL_GPL(cs_dsp_halo_init);
+EXPORT_SYMBOL_NS_GPL(cs_dsp_halo_init, FW_CS_DSP);
/**
* cs_dsp_remove() - Clean a cs_dsp before deletion
@@ -2838,7 +2845,7 @@ void cs_dsp_remove(struct cs_dsp *dsp)
cs_dsp_free_ctl_blk(ctl);
}
}
-EXPORT_SYMBOL_GPL(cs_dsp_remove);
+EXPORT_SYMBOL_NS_GPL(cs_dsp_remove, FW_CS_DSP);
/**
* cs_dsp_read_raw_data_block() - Reads a block of data from DSP memory
@@ -2875,7 +2882,7 @@ int cs_dsp_read_raw_data_block(struct cs_dsp *dsp, int mem_type, unsigned int me
return 0;
}
-EXPORT_SYMBOL_GPL(cs_dsp_read_raw_data_block);
+EXPORT_SYMBOL_NS_GPL(cs_dsp_read_raw_data_block, FW_CS_DSP);
/**
* cs_dsp_read_data_word() - Reads a word from DSP memory
@@ -2899,7 +2906,7 @@ int cs_dsp_read_data_word(struct cs_dsp *dsp, int mem_type, unsigned int mem_add
return 0;
}
-EXPORT_SYMBOL_GPL(cs_dsp_read_data_word);
+EXPORT_SYMBOL_NS_GPL(cs_dsp_read_data_word, FW_CS_DSP);
/**
* cs_dsp_write_data_word() - Writes a word to DSP memory
@@ -2925,7 +2932,7 @@ int cs_dsp_write_data_word(struct cs_dsp *dsp, int mem_type, unsigned int mem_ad
return regmap_raw_write(dsp->regmap, reg, &val, sizeof(val));
}
-EXPORT_SYMBOL_GPL(cs_dsp_write_data_word);
+EXPORT_SYMBOL_NS_GPL(cs_dsp_write_data_word, FW_CS_DSP);
/**
* cs_dsp_remove_padding() - Convert unpacked words to packed bytes
@@ -2949,7 +2956,7 @@ void cs_dsp_remove_padding(u32 *buf, int nwords)
*pack_out++ = (u8)(word >> 16);
}
}
-EXPORT_SYMBOL_GPL(cs_dsp_remove_padding);
+EXPORT_SYMBOL_NS_GPL(cs_dsp_remove_padding, FW_CS_DSP);
/**
* cs_dsp_adsp2_bus_error() - Handle a DSP bus error interrupt
@@ -3019,7 +3026,7 @@ void cs_dsp_adsp2_bus_error(struct cs_dsp *dsp)
error:
mutex_unlock(&dsp->pwr_lock);
}
-EXPORT_SYMBOL_GPL(cs_dsp_adsp2_bus_error);
+EXPORT_SYMBOL_NS_GPL(cs_dsp_adsp2_bus_error, FW_CS_DSP);
/**
* cs_dsp_halo_bus_error() - Handle a DSP bus error interrupt
@@ -3079,7 +3086,7 @@ void cs_dsp_halo_bus_error(struct cs_dsp *dsp)
exit_unlock:
mutex_unlock(&dsp->pwr_lock);
}
-EXPORT_SYMBOL_GPL(cs_dsp_halo_bus_error);
+EXPORT_SYMBOL_NS_GPL(cs_dsp_halo_bus_error, FW_CS_DSP);
/**
* cs_dsp_halo_wdt_expire() - Handle DSP watchdog expiry
@@ -3099,7 +3106,7 @@ void cs_dsp_halo_wdt_expire(struct cs_dsp *dsp)
mutex_unlock(&dsp->pwr_lock);
}
-EXPORT_SYMBOL_GPL(cs_dsp_halo_wdt_expire);
+EXPORT_SYMBOL_NS_GPL(cs_dsp_halo_wdt_expire, FW_CS_DSP);
static const struct cs_dsp_ops cs_dsp_adsp1_ops = {
.validate_version = cs_dsp_validate_version,
@@ -3221,7 +3228,7 @@ int cs_dsp_chunk_write(struct cs_dsp_chunk *ch, int nbits, u32 val)
return 0;
}
-EXPORT_SYMBOL_GPL(cs_dsp_chunk_write);
+EXPORT_SYMBOL_NS_GPL(cs_dsp_chunk_write, FW_CS_DSP);
/**
* cs_dsp_chunk_flush() - Pad remaining data with zero and commit to chunk
@@ -3240,7 +3247,7 @@ int cs_dsp_chunk_flush(struct cs_dsp_chunk *ch)
return cs_dsp_chunk_write(ch, CS_DSP_DATA_WORD_BITS - ch->cachebits, 0);
}
-EXPORT_SYMBOL_GPL(cs_dsp_chunk_flush);
+EXPORT_SYMBOL_NS_GPL(cs_dsp_chunk_flush, FW_CS_DSP);
/**
* cs_dsp_chunk_read() - Parse data from a DSP memory chunk
@@ -3282,7 +3289,7 @@ int cs_dsp_chunk_read(struct cs_dsp_chunk *ch, int nbits)
return result;
}
-EXPORT_SYMBOL_GPL(cs_dsp_chunk_read);
+EXPORT_SYMBOL_NS_GPL(cs_dsp_chunk_read, FW_CS_DSP);
MODULE_DESCRIPTION("Cirrus Logic DSP Support");
MODULE_AUTHOR("Simon Trimmer <simont@opensource.cirrus.com>");
diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c
index 181deb9af527..35c37f667781 100644
--- a/drivers/firmware/efi/cper.c
+++ b/drivers/firmware/efi/cper.c
@@ -291,6 +291,7 @@ int cper_mem_err_location(struct cper_mem_err_compact *mem, char *msg)
return n;
}
+EXPORT_SYMBOL_GPL(cper_mem_err_location);
int cper_dimm_err_location(struct cper_mem_err_compact *mem, char *msg)
{
@@ -311,6 +312,7 @@ int cper_dimm_err_location(struct cper_mem_err_compact *mem, char *msg)
return n;
}
+EXPORT_SYMBOL_GPL(cper_dimm_err_location);
void cper_mem_err_pack(const struct cper_sec_mem_err *mem,
struct cper_mem_err_compact *cmem)
@@ -332,6 +334,7 @@ void cper_mem_err_pack(const struct cper_sec_mem_err *mem,
cmem->mem_array_handle = mem->mem_array_handle;
cmem->mem_dev_handle = mem->mem_dev_handle;
}
+EXPORT_SYMBOL_GPL(cper_mem_err_pack);
const char *cper_mem_err_unpack(struct trace_seq *p,
struct cper_mem_err_compact *cmem)
diff --git a/drivers/firmware/efi/earlycon.c b/drivers/firmware/efi/earlycon.c
index a52236e11e5f..4d6c5327471a 100644
--- a/drivers/firmware/efi/earlycon.c
+++ b/drivers/firmware/efi/earlycon.c
@@ -29,8 +29,8 @@ static void *efi_fb;
*/
static int __init efi_earlycon_remap_fb(void)
{
- /* bail if there is no bootconsole or it has been disabled already */
- if (!earlycon_console || !(earlycon_console->flags & CON_ENABLED))
+ /* bail if there is no bootconsole or it was unregistered already */
+ if (!earlycon_console || !console_is_registered(earlycon_console))
return 0;
efi_fb = memremap(fb_base, screen_info.lfb_size,
@@ -42,8 +42,8 @@ early_initcall(efi_earlycon_remap_fb);
static int __init efi_earlycon_unmap_fb(void)
{
- /* unmap the bootconsole fb unless keep_bootcon has left it enabled */
- if (efi_fb && !(earlycon_console->flags & CON_ENABLED))
+ /* unmap the bootconsole fb unless keep_bootcon left it registered */
+ if (efi_fb && !console_is_registered(earlycon_console))
memunmap(efi_fb);
return 0;
}
diff --git a/drivers/firmware/efi/efi-pstore.c b/drivers/firmware/efi/efi-pstore.c
index 81ed4fc6d76d..e7b9ec6f8a86 100644
--- a/drivers/firmware/efi/efi-pstore.c
+++ b/drivers/firmware/efi/efi-pstore.c
@@ -209,7 +209,7 @@ static int efi_pstore_erase(struct pstore_record *record)
static struct pstore_info efi_pstore_info = {
.owner = THIS_MODULE,
- .name = "efi",
+ .name = KBUILD_MODNAME,
.flags = PSTORE_FLAGS_DMESG,
.open = efi_pstore_open,
.close = efi_pstore_close,
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 297bf3fd9acc..31a4090c66b3 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -339,6 +339,24 @@ static void __init efi_debugfs_init(void)
static inline void efi_debugfs_init(void) {}
#endif
+static void refresh_nv_rng_seed(struct work_struct *work)
+{
+ u8 seed[EFI_RANDOM_SEED_SIZE];
+
+ get_random_bytes(seed, sizeof(seed));
+ efi.set_variable(L"RandomSeed", &LINUX_EFI_RANDOM_SEED_TABLE_GUID,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS, sizeof(seed), seed);
+ memzero_explicit(seed, sizeof(seed));
+}
+static int refresh_nv_rng_seed_notification(struct notifier_block *nb, unsigned long action, void *data)
+{
+ static DECLARE_WORK(work, refresh_nv_rng_seed);
+ schedule_work(&work);
+ return NOTIFY_DONE;
+}
+static struct notifier_block refresh_nv_rng_seed_nb = { .notifier_call = refresh_nv_rng_seed_notification };
+
/*
* We register the efi subsystem with the firmware subsystem and the
* efivars subsystem with the efi subsystem, if the system was booted with
@@ -411,6 +429,7 @@ static int __init efisubsys_init(void)
platform_device_register_simple("efi_secret", 0, NULL, 0);
#endif
+ execute_with_initialized_rng(&refresh_nv_rng_seed_nb);
return 0;
err_remove_group:
diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile
index e19dd1106fa1..be8b8c6e8b40 100644
--- a/drivers/firmware/efi/libstub/Makefile
+++ b/drivers/firmware/efi/libstub/Makefile
@@ -23,6 +23,7 @@ cflags-$(CONFIG_X86) += -m$(BITS) -D__KERNEL__ \
# arm64 uses the full KBUILD_CFLAGS so it's necessary to explicitly
# disable the stackleak plugin
cflags-$(CONFIG_ARM64) += -fpie $(DISABLE_STACKLEAK_PLUGIN) \
+ -fno-unwind-tables -fno-asynchronous-unwind-tables \
$(call cc-option,-mbranch-protection=none)
cflags-$(CONFIG_ARM) += -DEFI_HAVE_STRLEN -DEFI_HAVE_STRNLEN \
-DEFI_HAVE_MEMCHR -DEFI_HAVE_STRRCHR \
diff --git a/drivers/firmware/imx/scu-pd.c b/drivers/firmware/imx/scu-pd.c
index af3d057e6421..2a4f07423365 100644
--- a/drivers/firmware/imx/scu-pd.c
+++ b/drivers/firmware/imx/scu-pd.c
@@ -108,6 +108,7 @@ static const struct imx_sc_pd_range imx8qxp_scu_pd_ranges[] = {
/* CONN SS */
{ "usb", IMX_SC_R_USB_0, 2, true, 0 },
{ "usb0phy", IMX_SC_R_USB_0_PHY, 1, false, 0 },
+ { "usb1phy", IMX_SC_R_USB_1_PHY, 1, false, 0},
{ "usb2", IMX_SC_R_USB_2, 1, false, 0 },
{ "usb2phy", IMX_SC_R_USB_2_PHY, 1, false, 0 },
{ "sdhc", IMX_SC_R_SDHC_0, 3, true, 0 },
diff --git a/drivers/firmware/raspberrypi.c b/drivers/firmware/raspberrypi.c
index 4b8978b254f9..ec07bf26e5eb 100644
--- a/drivers/firmware/raspberrypi.c
+++ b/drivers/firmware/raspberrypi.c
@@ -228,6 +228,26 @@ static void rpi_register_clk_driver(struct device *dev)
-1, NULL, 0);
}
+unsigned int rpi_firmware_clk_get_max_rate(struct rpi_firmware *fw, unsigned int id)
+{
+ struct rpi_firmware_clk_rate_request msg =
+ RPI_FIRMWARE_CLK_RATE_REQUEST(id);
+ int ret;
+
+ ret = rpi_firmware_property(fw, RPI_FIRMWARE_GET_MAX_CLOCK_RATE,
+ &msg, sizeof(msg));
+ if (ret)
+ /*
+ * If our firmware doesn't support that operation, or fails, we
+ * assume the maximum clock rate is absolute maximum we can
+ * store over our type.
+ */
+ return UINT_MAX;
+
+ return le32_to_cpu(msg.rate);
+}
+EXPORT_SYMBOL_GPL(rpi_firmware_clk_get_max_rate);
+
static void rpi_firmware_delete(struct kref *kref)
{
struct rpi_firmware *fw = container_of(kref, struct rpi_firmware,
@@ -268,12 +288,9 @@ static int rpi_firmware_probe(struct platform_device *pdev)
fw->cl.tx_block = true;
fw->chan = mbox_request_channel(&fw->cl, 0);
- if (IS_ERR(fw->chan)) {
- int ret = PTR_ERR(fw->chan);
- if (ret != -EPROBE_DEFER)
- dev_err(dev, "Failed to get mbox channel: %d\n", ret);
- return ret;
- }
+ if (IS_ERR(fw->chan))
+ return dev_err_probe(dev, PTR_ERR(fw->chan),
+ "Failed to get mbox channel\n");
init_completion(&fw->c);
kref_init(&fw->consumers);
@@ -311,6 +328,18 @@ static int rpi_firmware_remove(struct platform_device *pdev)
return 0;
}
+static const struct of_device_id rpi_firmware_of_match[] = {
+ { .compatible = "raspberrypi,bcm2835-firmware", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, rpi_firmware_of_match);
+
+struct device_node *rpi_firmware_find_node(void)
+{
+ return of_find_matching_node(NULL, rpi_firmware_of_match);
+}
+EXPORT_SYMBOL_GPL(rpi_firmware_find_node);
+
/**
* rpi_firmware_get - Get pointer to rpi_firmware structure.
* @firmware_node: Pointer to the firmware Device Tree node.
@@ -366,12 +395,6 @@ struct rpi_firmware *devm_rpi_firmware_get(struct device *dev,
}
EXPORT_SYMBOL_GPL(devm_rpi_firmware_get);
-static const struct of_device_id rpi_firmware_of_match[] = {
- { .compatible = "raspberrypi,bcm2835-firmware", },
- {},
-};
-MODULE_DEVICE_TABLE(of, rpi_firmware_of_match);
-
static struct platform_driver rpi_firmware_driver = {
.driver = {
.name = "raspberrypi-firmware",
diff --git a/drivers/firmware/tegra/Kconfig b/drivers/firmware/tegra/Kconfig
index 1c8ba1f47c7c..cde1ab8bd9d1 100644
--- a/drivers/firmware/tegra/Kconfig
+++ b/drivers/firmware/tegra/Kconfig
@@ -14,6 +14,7 @@ config TEGRA_IVC
config TEGRA_BPMP
bool "Tegra BPMP driver"
depends on ARCH_TEGRA && TEGRA_HSP_MBOX && TEGRA_IVC
+ depends on !CPU_BIG_ENDIAN
help
BPMP (Boot and Power Management Processor) is designed to off-loading
the PM functions which include clock/DVFS/thermal/power from the CPU.
diff --git a/drivers/firmware/tegra/bpmp-debugfs.c b/drivers/firmware/tegra/bpmp-debugfs.c
index 9d3874cdaaee..3ca2b5d9e66f 100644
--- a/drivers/firmware/tegra/bpmp-debugfs.c
+++ b/drivers/firmware/tegra/bpmp-debugfs.c
@@ -48,13 +48,9 @@ static int seqbuf_read(struct seqbuf *seqbuf, void *buf, size_t nbyte)
return seqbuf_status(seqbuf);
}
-static int seqbuf_read_u32(struct seqbuf *seqbuf, uint32_t *v)
+static int seqbuf_read_u32(struct seqbuf *seqbuf, u32 *v)
{
- int err;
-
- err = seqbuf_read(seqbuf, v, 4);
- *v = le32_to_cpu(*v);
- return err;
+ return seqbuf_read(seqbuf, v, 4);
}
static int seqbuf_read_str(struct seqbuf *seqbuf, const char **str)
@@ -109,10 +105,10 @@ out:
}
static int mrq_debug_open(struct tegra_bpmp *bpmp, const char *name,
- uint32_t *fd, uint32_t *len, bool write)
+ u32 *fd, u32 *len, bool write)
{
struct mrq_debug_request req = {
- .cmd = cpu_to_le32(write ? CMD_DEBUG_OPEN_WO : CMD_DEBUG_OPEN_RO),
+ .cmd = write ? CMD_DEBUG_OPEN_WO : CMD_DEBUG_OPEN_RO,
};
struct mrq_debug_response resp;
struct tegra_bpmp_message msg = {
@@ -147,10 +143,10 @@ static int mrq_debug_open(struct tegra_bpmp *bpmp, const char *name,
return 0;
}
-static int mrq_debug_close(struct tegra_bpmp *bpmp, uint32_t fd)
+static int mrq_debug_close(struct tegra_bpmp *bpmp, u32 fd)
{
struct mrq_debug_request req = {
- .cmd = cpu_to_le32(CMD_DEBUG_CLOSE),
+ .cmd = CMD_DEBUG_CLOSE,
.frd = {
.fd = fd,
},
@@ -179,10 +175,10 @@ static int mrq_debug_close(struct tegra_bpmp *bpmp, uint32_t fd)
}
static int mrq_debug_read(struct tegra_bpmp *bpmp, const char *name,
- char *data, size_t sz_data, uint32_t *nbytes)
+ char *data, size_t sz_data, u32 *nbytes)
{
struct mrq_debug_request req = {
- .cmd = cpu_to_le32(CMD_DEBUG_READ),
+ .cmd = CMD_DEBUG_READ,
};
struct mrq_debug_response resp;
struct tegra_bpmp_message msg = {
@@ -196,7 +192,7 @@ static int mrq_debug_read(struct tegra_bpmp *bpmp, const char *name,
.size = sizeof(resp),
},
};
- uint32_t fd = 0, len = 0;
+ u32 fd = 0, len = 0;
int remaining, err;
mutex_lock(&bpmp_debug_lock);
@@ -245,7 +241,7 @@ static int mrq_debug_write(struct tegra_bpmp *bpmp, const char *name,
uint8_t *data, size_t sz_data)
{
struct mrq_debug_request req = {
- .cmd = cpu_to_le32(CMD_DEBUG_WRITE)
+ .cmd = CMD_DEBUG_WRITE
};
struct mrq_debug_response resp;
struct tegra_bpmp_message msg = {
@@ -259,7 +255,7 @@ static int mrq_debug_write(struct tegra_bpmp *bpmp, const char *name,
.size = sizeof(resp),
},
};
- uint32_t fd = 0, len = 0;
+ u32 fd = 0, len = 0;
size_t remaining;
int err;
@@ -308,7 +304,7 @@ static int bpmp_debug_show(struct seq_file *m, void *p)
char fnamebuf[256];
const char *filename;
struct mrq_debug_request req = {
- .cmd = cpu_to_le32(CMD_DEBUG_READ),
+ .cmd = CMD_DEBUG_READ,
};
struct mrq_debug_response resp;
struct tegra_bpmp_message msg = {
@@ -322,7 +318,7 @@ static int bpmp_debug_show(struct seq_file *m, void *p)
.size = sizeof(resp),
},
};
- uint32_t fd = 0, len = 0;
+ u32 fd = 0, len = 0;
int remaining, err;
filename = get_filename(bpmp, file, fnamebuf, sizeof(fnamebuf));
@@ -406,8 +402,8 @@ static int bpmp_populate_debugfs_inband(struct tegra_bpmp *bpmp,
{
const size_t pathlen = SZ_256;
const size_t bufsize = SZ_16K;
- uint32_t dsize, attrs = 0;
struct dentry *dentry;
+ u32 dsize, attrs = 0;
struct seqbuf seqbuf;
char *buf, *pathbuf;
const char *name;
@@ -487,12 +483,12 @@ static int mrq_debugfs_read(struct tegra_bpmp *bpmp,
size_t *nbytes)
{
struct mrq_debugfs_request req = {
- .cmd = cpu_to_le32(CMD_DEBUGFS_READ),
+ .cmd = CMD_DEBUGFS_READ,
.fop = {
- .fnameaddr = cpu_to_le32((uint32_t)name),
- .fnamelen = cpu_to_le32((uint32_t)sz_name),
- .dataaddr = cpu_to_le32((uint32_t)data),
- .datalen = cpu_to_le32((uint32_t)sz_data),
+ .fnameaddr = (u32)name,
+ .fnamelen = (u32)sz_name,
+ .dataaddr = (u32)data,
+ .datalen = (u32)sz_data,
},
};
struct mrq_debugfs_response resp;
@@ -525,12 +521,12 @@ static int mrq_debugfs_write(struct tegra_bpmp *bpmp,
dma_addr_t data, size_t sz_data)
{
const struct mrq_debugfs_request req = {
- .cmd = cpu_to_le32(CMD_DEBUGFS_WRITE),
+ .cmd = CMD_DEBUGFS_WRITE,
.fop = {
- .fnameaddr = cpu_to_le32((uint32_t)name),
- .fnamelen = cpu_to_le32((uint32_t)sz_name),
- .dataaddr = cpu_to_le32((uint32_t)data),
- .datalen = cpu_to_le32((uint32_t)sz_data),
+ .fnameaddr = (u32)name,
+ .fnamelen = (u32)sz_name,
+ .dataaddr = (u32)data,
+ .datalen = (u32)sz_data,
},
};
struct tegra_bpmp_message msg = {
@@ -548,10 +544,10 @@ static int mrq_debugfs_dumpdir(struct tegra_bpmp *bpmp, dma_addr_t addr,
size_t size, size_t *nbytes)
{
const struct mrq_debugfs_request req = {
- .cmd = cpu_to_le32(CMD_DEBUGFS_DUMPDIR),
+ .cmd = CMD_DEBUGFS_DUMPDIR,
.dumpdir = {
- .dataaddr = cpu_to_le32((uint32_t)addr),
- .datalen = cpu_to_le32((uint32_t)size),
+ .dataaddr = (u32)addr,
+ .datalen = (u32)size,
},
};
struct mrq_debugfs_response resp;
@@ -688,10 +684,10 @@ static const struct file_operations debugfs_fops = {
};
static int bpmp_populate_dir(struct tegra_bpmp *bpmp, struct seqbuf *seqbuf,
- struct dentry *parent, uint32_t depth)
+ struct dentry *parent, u32 depth)
{
int err;
- uint32_t d, t;
+ u32 d, t;
const char *name;
struct dentry *dentry;
diff --git a/drivers/firmware/tegra/bpmp-tegra186.c b/drivers/firmware/tegra/bpmp-tegra186.c
index 63ab21d89c2c..2e26199041cd 100644
--- a/drivers/firmware/tegra/bpmp-tegra186.c
+++ b/drivers/firmware/tegra/bpmp-tegra186.c
@@ -18,8 +18,8 @@ struct tegra186_bpmp {
struct {
struct gen_pool *pool;
+ void __iomem *virt;
dma_addr_t phys;
- void *virt;
} tx, rx;
struct {
@@ -40,31 +40,27 @@ mbox_client_to_bpmp(struct mbox_client *client)
static bool tegra186_bpmp_is_message_ready(struct tegra_bpmp_channel *channel)
{
- void *frame;
+ int err;
- frame = tegra_ivc_read_get_next_frame(channel->ivc);
- if (IS_ERR(frame)) {
- channel->ib = NULL;
+ err = tegra_ivc_read_get_next_frame(channel->ivc, &channel->ib);
+ if (err) {
+ iosys_map_clear(&channel->ib);
return false;
}
- channel->ib = frame;
-
return true;
}
static bool tegra186_bpmp_is_channel_free(struct tegra_bpmp_channel *channel)
{
- void *frame;
+ int err;
- frame = tegra_ivc_write_get_next_frame(channel->ivc);
- if (IS_ERR(frame)) {
- channel->ob = NULL;
+ err = tegra_ivc_write_get_next_frame(channel->ivc, &channel->ob);
+ if (err) {
+ iosys_map_clear(&channel->ob);
return false;
}
- channel->ob = frame;
-
return true;
}
@@ -109,6 +105,7 @@ static int tegra186_bpmp_channel_init(struct tegra_bpmp_channel *channel,
{
struct tegra186_bpmp *priv = bpmp->priv;
size_t message_size, queue_size;
+ struct iosys_map rx, tx;
unsigned int offset;
int err;
@@ -121,10 +118,11 @@ static int tegra186_bpmp_channel_init(struct tegra_bpmp_channel *channel,
queue_size = tegra_ivc_total_queue_size(message_size);
offset = queue_size * index;
- err = tegra_ivc_init(channel->ivc, NULL,
- priv->rx.virt + offset, priv->rx.phys + offset,
- priv->tx.virt + offset, priv->tx.phys + offset,
- 1, message_size, tegra186_bpmp_ivc_notify,
+ iosys_map_set_vaddr_iomem(&rx, priv->rx.virt + offset);
+ iosys_map_set_vaddr_iomem(&tx, priv->tx.virt + offset);
+
+ err = tegra_ivc_init(channel->ivc, NULL, &rx, priv->rx.phys + offset, &tx,
+ priv->tx.phys + offset, 1, message_size, tegra186_bpmp_ivc_notify,
bpmp);
if (err < 0) {
dev_err(bpmp->dev, "failed to setup IVC for channel %u: %d\n",
@@ -179,7 +177,7 @@ static int tegra186_bpmp_init(struct tegra_bpmp *bpmp)
return -EPROBE_DEFER;
}
- priv->tx.virt = gen_pool_dma_alloc(priv->tx.pool, 4096, &priv->tx.phys);
+ priv->tx.virt = (void __iomem *)gen_pool_dma_alloc(priv->tx.pool, 4096, &priv->tx.phys);
if (!priv->tx.virt) {
dev_err(bpmp->dev, "failed to allocate from TX pool\n");
return -ENOMEM;
@@ -192,7 +190,7 @@ static int tegra186_bpmp_init(struct tegra_bpmp *bpmp)
goto free_tx;
}
- priv->rx.virt = gen_pool_dma_alloc(priv->rx.pool, 4096, &priv->rx.phys);
+ priv->rx.virt = (void __iomem *)gen_pool_dma_alloc(priv->rx.pool, 4096, &priv->rx.phys);
if (!priv->rx.virt) {
dev_err(bpmp->dev, "failed to allocate from RX pool\n");
err = -ENOMEM;
diff --git a/drivers/firmware/tegra/bpmp-tegra210.c b/drivers/firmware/tegra/bpmp-tegra210.c
index c9c830f658c3..6295f5640c15 100644
--- a/drivers/firmware/tegra/bpmp-tegra210.c
+++ b/drivers/firmware/tegra/bpmp-tegra210.c
@@ -137,8 +137,8 @@ static int tegra210_bpmp_channel_init(struct tegra_bpmp_channel *channel,
unsigned int index)
{
struct tegra210_bpmp *priv = bpmp->priv;
+ void __iomem *p;
u32 address;
- void *p;
/* Retrieve channel base address from BPMP */
writel(index << TRIGGER_ID_SHIFT | TRIGGER_CMD_GET,
@@ -149,8 +149,9 @@ static int tegra210_bpmp_channel_init(struct tegra_bpmp_channel *channel,
if (!p)
return -ENOMEM;
- channel->ib = p;
- channel->ob = p;
+ iosys_map_set_vaddr_iomem(&channel->ib, p);
+ iosys_map_set_vaddr_iomem(&channel->ob, p);
+
channel->index = index;
init_completion(&channel->completion);
channel->bpmp = bpmp;
@@ -199,10 +200,8 @@ static int tegra210_bpmp_init(struct tegra_bpmp *bpmp)
}
err = platform_get_irq_byname(pdev, "tx");
- if (err < 0) {
- dev_err(&pdev->dev, "failed to get TX IRQ: %d\n", err);
+ if (err < 0)
return err;
- }
priv->tx_irq_data = irq_get_irq_data(err);
if (!priv->tx_irq_data) {
@@ -211,10 +210,8 @@ static int tegra210_bpmp_init(struct tegra_bpmp *bpmp)
}
err = platform_get_irq_byname(pdev, "rx");
- if (err < 0) {
- dev_err(&pdev->dev, "failed to get rx IRQ: %d\n", err);
+ if (err < 0)
return err;
- }
err = devm_request_irq(&pdev->dev, err, rx_irq,
IRQF_NO_SUSPEND, dev_name(&pdev->dev), bpmp);
diff --git a/drivers/firmware/tegra/bpmp.c b/drivers/firmware/tegra/bpmp.c
index 037db21de510..042c2043929d 100644
--- a/drivers/firmware/tegra/bpmp.c
+++ b/drivers/firmware/tegra/bpmp.c
@@ -201,13 +201,13 @@ static ssize_t __tegra_bpmp_channel_read(struct tegra_bpmp_channel *channel,
int err;
if (data && size > 0)
- memcpy_fromio(data, channel->ib->data, size);
+ tegra_bpmp_mb_read(data, &channel->ib, size);
err = tegra_bpmp_ack_response(channel);
if (err < 0)
return err;
- *ret = channel->ib->code;
+ *ret = tegra_bpmp_mb_read_field(&channel->ib, code);
return 0;
}
@@ -241,11 +241,11 @@ static ssize_t __tegra_bpmp_channel_write(struct tegra_bpmp_channel *channel,
unsigned int mrq, unsigned long flags,
const void *data, size_t size)
{
- channel->ob->code = mrq;
- channel->ob->flags = flags;
+ tegra_bpmp_mb_write_field(&channel->ob, code, mrq);
+ tegra_bpmp_mb_write_field(&channel->ob, flags, flags);
if (data && size > 0)
- memcpy_toio(channel->ob->data, data, size);
+ tegra_bpmp_mb_write(&channel->ob, data, size);
return tegra_bpmp_post_request(channel);
}
@@ -400,7 +400,7 @@ static struct tegra_bpmp_mrq *tegra_bpmp_find_mrq(struct tegra_bpmp *bpmp,
void tegra_bpmp_mrq_return(struct tegra_bpmp_channel *channel, int code,
const void *data, size_t size)
{
- unsigned long flags = channel->ib->flags;
+ unsigned long flags = tegra_bpmp_mb_read_field(&channel->ib, flags);
struct tegra_bpmp *bpmp = channel->bpmp;
int err;
@@ -417,10 +417,10 @@ void tegra_bpmp_mrq_return(struct tegra_bpmp_channel *channel, int code,
if (WARN_ON(!tegra_bpmp_is_response_channel_free(channel)))
return;
- channel->ob->code = code;
+ tegra_bpmp_mb_write_field(&channel->ob, code, code);
if (data && size > 0)
- memcpy_toio(channel->ob->data, data, size);
+ tegra_bpmp_mb_write(&channel->ob, data, size);
err = tegra_bpmp_post_response(channel);
if (WARN_ON(err < 0))
@@ -502,7 +502,7 @@ EXPORT_SYMBOL_GPL(tegra_bpmp_free_mrq);
bool tegra_bpmp_mrq_is_supported(struct tegra_bpmp *bpmp, unsigned int mrq)
{
- struct mrq_query_abi_request req = { .mrq = cpu_to_le32(mrq) };
+ struct mrq_query_abi_request req = { .mrq = mrq };
struct mrq_query_abi_response resp;
struct tegra_bpmp_message msg = {
.mrq = MRQ_QUERY_ABI,
@@ -529,13 +529,13 @@ static void tegra_bpmp_mrq_handle_ping(unsigned int mrq,
struct tegra_bpmp_channel *channel,
void *data)
{
- struct mrq_ping_request *request;
+ struct mrq_ping_request request;
struct mrq_ping_response response;
- request = (struct mrq_ping_request *)channel->ib->data;
+ tegra_bpmp_mb_read(&request, &channel->ib, sizeof(request));
memset(&response, 0, sizeof(response));
- response.reply = request->challenge << 1;
+ response.reply = request.challenge << 1;
tegra_bpmp_mrq_return(channel, 0, &response, sizeof(response));
}
@@ -648,7 +648,7 @@ static int tegra_bpmp_get_firmware_tag(struct tegra_bpmp *bpmp, char *tag,
static void tegra_bpmp_channel_signal(struct tegra_bpmp_channel *channel)
{
- unsigned long flags = channel->ob->flags;
+ unsigned long flags = tegra_bpmp_mb_read_field(&channel->ob, flags);
if ((flags & MSG_RING) == 0)
return;
@@ -666,8 +666,11 @@ void tegra_bpmp_handle_rx(struct tegra_bpmp *bpmp)
count = bpmp->soc->channels.thread.count;
busy = bpmp->threaded.busy;
- if (tegra_bpmp_is_request_ready(channel))
- tegra_bpmp_handle_mrq(bpmp, channel->ib->code, channel);
+ if (tegra_bpmp_is_request_ready(channel)) {
+ unsigned int mrq = tegra_bpmp_mb_read_field(&channel->ib, code);
+
+ tegra_bpmp_handle_mrq(bpmp, mrq, channel);
+ }
spin_lock(&bpmp->lock);
diff --git a/drivers/firmware/tegra/ivc.c b/drivers/firmware/tegra/ivc.c
index e2398cd7ca98..8c9aff9804c0 100644
--- a/drivers/firmware/tegra/ivc.c
+++ b/drivers/firmware/tegra/ivc.c
@@ -68,6 +68,12 @@ struct tegra_ivc_header {
} rx;
};
+#define tegra_ivc_header_read_field(hdr, field) \
+ iosys_map_rd_field(hdr, 0, struct tegra_ivc_header, field)
+
+#define tegra_ivc_header_write_field(hdr, field, value) \
+ iosys_map_wr_field(hdr, 0, struct tegra_ivc_header, field, value)
+
static inline void tegra_ivc_invalidate(struct tegra_ivc *ivc, dma_addr_t phys)
{
if (!ivc->peer)
@@ -86,16 +92,15 @@ static inline void tegra_ivc_flush(struct tegra_ivc *ivc, dma_addr_t phys)
DMA_TO_DEVICE);
}
-static inline bool tegra_ivc_empty(struct tegra_ivc *ivc,
- struct tegra_ivc_header *header)
+static inline bool tegra_ivc_empty(struct tegra_ivc *ivc, struct iosys_map *map)
{
/*
* This function performs multiple checks on the same values with
* security implications, so create snapshots with READ_ONCE() to
* ensure that these checks use the same values.
*/
- u32 tx = READ_ONCE(header->tx.count);
- u32 rx = READ_ONCE(header->rx.count);
+ u32 tx = tegra_ivc_header_read_field(map, tx.count);
+ u32 rx = tegra_ivc_header_read_field(map, rx.count);
/*
* Perform an over-full check to prevent denial of service attacks
@@ -113,11 +118,10 @@ static inline bool tegra_ivc_empty(struct tegra_ivc *ivc,
return tx == rx;
}
-static inline bool tegra_ivc_full(struct tegra_ivc *ivc,
- struct tegra_ivc_header *header)
+static inline bool tegra_ivc_full(struct tegra_ivc *ivc, struct iosys_map *map)
{
- u32 tx = READ_ONCE(header->tx.count);
- u32 rx = READ_ONCE(header->rx.count);
+ u32 tx = tegra_ivc_header_read_field(map, tx.count);
+ u32 rx = tegra_ivc_header_read_field(map, rx.count);
/*
* Invalid cases where the counters indicate that the queue is over
@@ -126,11 +130,10 @@ static inline bool tegra_ivc_full(struct tegra_ivc *ivc,
return tx - rx >= ivc->num_frames;
}
-static inline u32 tegra_ivc_available(struct tegra_ivc *ivc,
- struct tegra_ivc_header *header)
+static inline u32 tegra_ivc_available(struct tegra_ivc *ivc, struct iosys_map *map)
{
- u32 tx = READ_ONCE(header->tx.count);
- u32 rx = READ_ONCE(header->rx.count);
+ u32 tx = tegra_ivc_header_read_field(map, tx.count);
+ u32 rx = tegra_ivc_header_read_field(map, rx.count);
/*
* This function isn't expected to be used in scenarios where an
@@ -143,8 +146,9 @@ static inline u32 tegra_ivc_available(struct tegra_ivc *ivc,
static inline void tegra_ivc_advance_tx(struct tegra_ivc *ivc)
{
- WRITE_ONCE(ivc->tx.channel->tx.count,
- READ_ONCE(ivc->tx.channel->tx.count) + 1);
+ unsigned int count = tegra_ivc_header_read_field(&ivc->tx.map, tx.count);
+
+ tegra_ivc_header_write_field(&ivc->tx.map, tx.count, count + 1);
if (ivc->tx.position == ivc->num_frames - 1)
ivc->tx.position = 0;
@@ -154,8 +158,9 @@ static inline void tegra_ivc_advance_tx(struct tegra_ivc *ivc)
static inline void tegra_ivc_advance_rx(struct tegra_ivc *ivc)
{
- WRITE_ONCE(ivc->rx.channel->rx.count,
- READ_ONCE(ivc->rx.channel->rx.count) + 1);
+ unsigned int count = tegra_ivc_header_read_field(&ivc->rx.map, rx.count);
+
+ tegra_ivc_header_write_field(&ivc->rx.map, rx.count, count + 1);
if (ivc->rx.position == ivc->num_frames - 1)
ivc->rx.position = 0;
@@ -166,6 +171,7 @@ static inline void tegra_ivc_advance_rx(struct tegra_ivc *ivc)
static inline int tegra_ivc_check_read(struct tegra_ivc *ivc)
{
unsigned int offset = offsetof(struct tegra_ivc_header, tx.count);
+ unsigned int state;
/*
* tx.channel->state is set locally, so it is not synchronized with
@@ -175,7 +181,8 @@ static inline int tegra_ivc_check_read(struct tegra_ivc *ivc)
* asynchronous transition of rx.channel->state to
* TEGRA_IVC_STATE_ACK is not allowed.
*/
- if (ivc->tx.channel->tx.state != TEGRA_IVC_STATE_ESTABLISHED)
+ state = tegra_ivc_header_read_field(&ivc->tx.map, tx.state);
+ if (state != TEGRA_IVC_STATE_ESTABLISHED)
return -ECONNRESET;
/*
@@ -185,12 +192,12 @@ static inline int tegra_ivc_check_read(struct tegra_ivc *ivc)
* Synchronization is only necessary when these pointers indicate
* empty or full.
*/
- if (!tegra_ivc_empty(ivc, ivc->rx.channel))
+ if (!tegra_ivc_empty(ivc, &ivc->rx.map))
return 0;
tegra_ivc_invalidate(ivc, ivc->rx.phys + offset);
- if (tegra_ivc_empty(ivc, ivc->rx.channel))
+ if (tegra_ivc_empty(ivc, &ivc->rx.map))
return -ENOSPC;
return 0;
@@ -199,29 +206,34 @@ static inline int tegra_ivc_check_read(struct tegra_ivc *ivc)
static inline int tegra_ivc_check_write(struct tegra_ivc *ivc)
{
unsigned int offset = offsetof(struct tegra_ivc_header, rx.count);
+ unsigned int state;
- if (ivc->tx.channel->tx.state != TEGRA_IVC_STATE_ESTABLISHED)
+ state = tegra_ivc_header_read_field(&ivc->tx.map, tx.state);
+ if (state != TEGRA_IVC_STATE_ESTABLISHED)
return -ECONNRESET;
- if (!tegra_ivc_full(ivc, ivc->tx.channel))
+ if (!tegra_ivc_full(ivc, &ivc->tx.map))
return 0;
tegra_ivc_invalidate(ivc, ivc->tx.phys + offset);
- if (tegra_ivc_full(ivc, ivc->tx.channel))
+ if (tegra_ivc_full(ivc, &ivc->tx.map))
return -ENOSPC;
return 0;
}
-static void *tegra_ivc_frame_virt(struct tegra_ivc *ivc,
- struct tegra_ivc_header *header,
- unsigned int frame)
+static int tegra_ivc_frame_virt(struct tegra_ivc *ivc, const struct iosys_map *header,
+ unsigned int frame, struct iosys_map *map)
{
+ size_t offset = sizeof(struct tegra_ivc_header) + ivc->frame_size * frame;
+
if (WARN_ON(frame >= ivc->num_frames))
- return ERR_PTR(-EINVAL);
+ return -EINVAL;
- return (void *)(header + 1) + ivc->frame_size * frame;
+ *map = IOSYS_MAP_INIT_OFFSET(header, offset);
+
+ return 0;
}
static inline dma_addr_t tegra_ivc_frame_phys(struct tegra_ivc *ivc,
@@ -264,16 +276,16 @@ static inline void tegra_ivc_flush_frame(struct tegra_ivc *ivc,
}
/* directly peek at the next frame rx'ed */
-void *tegra_ivc_read_get_next_frame(struct tegra_ivc *ivc)
+int tegra_ivc_read_get_next_frame(struct tegra_ivc *ivc, struct iosys_map *map)
{
int err;
if (WARN_ON(ivc == NULL))
- return ERR_PTR(-EINVAL);
+ return -EINVAL;
err = tegra_ivc_check_read(ivc);
if (err < 0)
- return ERR_PTR(err);
+ return err;
/*
* Order observation of ivc->rx.position potentially indicating new
@@ -284,7 +296,7 @@ void *tegra_ivc_read_get_next_frame(struct tegra_ivc *ivc)
tegra_ivc_invalidate_frame(ivc, ivc->rx.phys, ivc->rx.position, 0,
ivc->frame_size);
- return tegra_ivc_frame_virt(ivc, ivc->rx.channel, ivc->rx.position);
+ return tegra_ivc_frame_virt(ivc, &ivc->rx.map, ivc->rx.position, map);
}
EXPORT_SYMBOL(tegra_ivc_read_get_next_frame);
@@ -320,7 +332,7 @@ int tegra_ivc_read_advance(struct tegra_ivc *ivc)
*/
tegra_ivc_invalidate(ivc, ivc->rx.phys + tx);
- if (tegra_ivc_available(ivc, ivc->rx.channel) == ivc->num_frames - 1)
+ if (tegra_ivc_available(ivc, &ivc->rx.map) == ivc->num_frames - 1)
ivc->notify(ivc, ivc->notify_data);
return 0;
@@ -328,15 +340,15 @@ int tegra_ivc_read_advance(struct tegra_ivc *ivc)
EXPORT_SYMBOL(tegra_ivc_read_advance);
/* directly poke at the next frame to be tx'ed */
-void *tegra_ivc_write_get_next_frame(struct tegra_ivc *ivc)
+int tegra_ivc_write_get_next_frame(struct tegra_ivc *ivc, struct iosys_map *map)
{
int err;
err = tegra_ivc_check_write(ivc);
if (err < 0)
- return ERR_PTR(err);
+ return err;
- return tegra_ivc_frame_virt(ivc, ivc->tx.channel, ivc->tx.position);
+ return tegra_ivc_frame_virt(ivc, &ivc->tx.map, ivc->tx.position, map);
}
EXPORT_SYMBOL(tegra_ivc_write_get_next_frame);
@@ -376,7 +388,7 @@ int tegra_ivc_write_advance(struct tegra_ivc *ivc)
*/
tegra_ivc_invalidate(ivc, ivc->tx.phys + rx);
- if (tegra_ivc_available(ivc, ivc->tx.channel) == 1)
+ if (tegra_ivc_available(ivc, &ivc->tx.map) == 1)
ivc->notify(ivc, ivc->notify_data);
return 0;
@@ -387,7 +399,7 @@ void tegra_ivc_reset(struct tegra_ivc *ivc)
{
unsigned int offset = offsetof(struct tegra_ivc_header, tx.count);
- ivc->tx.channel->tx.state = TEGRA_IVC_STATE_SYNC;
+ tegra_ivc_header_write_field(&ivc->tx.map, tx.state, TEGRA_IVC_STATE_SYNC);
tegra_ivc_flush(ivc, ivc->tx.phys + offset);
ivc->notify(ivc, ivc->notify_data);
}
@@ -416,13 +428,14 @@ EXPORT_SYMBOL(tegra_ivc_reset);
int tegra_ivc_notified(struct tegra_ivc *ivc)
{
unsigned int offset = offsetof(struct tegra_ivc_header, tx.count);
- enum tegra_ivc_state state;
+ enum tegra_ivc_state rx_state, tx_state;
/* Copy the receiver's state out of shared memory. */
tegra_ivc_invalidate(ivc, ivc->rx.phys + offset);
- state = READ_ONCE(ivc->rx.channel->tx.state);
+ rx_state = tegra_ivc_header_read_field(&ivc->rx.map, tx.state);
+ tx_state = tegra_ivc_header_read_field(&ivc->tx.map, tx.state);
- if (state == TEGRA_IVC_STATE_SYNC) {
+ if (rx_state == TEGRA_IVC_STATE_SYNC) {
offset = offsetof(struct tegra_ivc_header, tx.count);
/*
@@ -436,8 +449,8 @@ int tegra_ivc_notified(struct tegra_ivc *ivc)
* state and won't make progress until we change our state,
* so the counters are not in use at this time.
*/
- ivc->tx.channel->tx.count = 0;
- ivc->rx.channel->rx.count = 0;
+ tegra_ivc_header_write_field(&ivc->tx.map, tx.count, 0);
+ tegra_ivc_header_write_field(&ivc->rx.map, rx.count, 0);
ivc->tx.position = 0;
ivc->rx.position = 0;
@@ -452,7 +465,7 @@ int tegra_ivc_notified(struct tegra_ivc *ivc)
* Move to ACK state. We have just cleared our counters, so it
* is now safe for the remote end to start using these values.
*/
- ivc->tx.channel->tx.state = TEGRA_IVC_STATE_ACK;
+ tegra_ivc_header_write_field(&ivc->tx.map, tx.state, TEGRA_IVC_STATE_ACK);
tegra_ivc_flush(ivc, ivc->tx.phys + offset);
/*
@@ -460,8 +473,8 @@ int tegra_ivc_notified(struct tegra_ivc *ivc)
*/
ivc->notify(ivc, ivc->notify_data);
- } else if (ivc->tx.channel->tx.state == TEGRA_IVC_STATE_SYNC &&
- state == TEGRA_IVC_STATE_ACK) {
+ } else if (tx_state == TEGRA_IVC_STATE_SYNC &&
+ rx_state == TEGRA_IVC_STATE_ACK) {
offset = offsetof(struct tegra_ivc_header, tx.count);
/*
@@ -475,8 +488,8 @@ int tegra_ivc_notified(struct tegra_ivc *ivc)
* state and won't make progress until we change our state,
* so the counters are not in use at this time.
*/
- ivc->tx.channel->tx.count = 0;
- ivc->rx.channel->rx.count = 0;
+ tegra_ivc_header_write_field(&ivc->tx.map, tx.count, 0);
+ tegra_ivc_header_write_field(&ivc->rx.map, rx.count, 0);
ivc->tx.position = 0;
ivc->rx.position = 0;
@@ -492,7 +505,7 @@ int tegra_ivc_notified(struct tegra_ivc *ivc)
* already cleared its counters, so it is safe to start
* writing/reading on this channel.
*/
- ivc->tx.channel->tx.state = TEGRA_IVC_STATE_ESTABLISHED;
+ tegra_ivc_header_write_field(&ivc->tx.map, tx.state, TEGRA_IVC_STATE_ESTABLISHED);
tegra_ivc_flush(ivc, ivc->tx.phys + offset);
/*
@@ -500,7 +513,7 @@ int tegra_ivc_notified(struct tegra_ivc *ivc)
*/
ivc->notify(ivc, ivc->notify_data);
- } else if (ivc->tx.channel->tx.state == TEGRA_IVC_STATE_ACK) {
+ } else if (tx_state == TEGRA_IVC_STATE_ACK) {
offset = offsetof(struct tegra_ivc_header, tx.count);
/*
@@ -516,7 +529,7 @@ int tegra_ivc_notified(struct tegra_ivc *ivc)
* cleared its counters, so it is safe to start writing/reading
* on this channel.
*/
- ivc->tx.channel->tx.state = TEGRA_IVC_STATE_ESTABLISHED;
+ tegra_ivc_header_write_field(&ivc->tx.map, tx.state, TEGRA_IVC_STATE_ESTABLISHED);
tegra_ivc_flush(ivc, ivc->tx.phys + offset);
/*
@@ -533,7 +546,7 @@ int tegra_ivc_notified(struct tegra_ivc *ivc)
*/
}
- if (ivc->tx.channel->tx.state != TEGRA_IVC_STATE_ESTABLISHED)
+ if (tx_state != TEGRA_IVC_STATE_ESTABLISHED)
return -EAGAIN;
return 0;
@@ -609,8 +622,29 @@ static int tegra_ivc_check_params(unsigned long rx, unsigned long tx,
return 0;
}
-int tegra_ivc_init(struct tegra_ivc *ivc, struct device *peer, void *rx,
- dma_addr_t rx_phys, void *tx, dma_addr_t tx_phys,
+static inline void iosys_map_copy(struct iosys_map *dst, const struct iosys_map *src)
+{
+ *dst = *src;
+}
+
+static inline unsigned long iosys_map_get_address(const struct iosys_map *map)
+{
+ if (map->is_iomem)
+ return (unsigned long)map->vaddr_iomem;
+
+ return (unsigned long)map->vaddr;
+}
+
+static inline void *iosys_map_get_vaddr(const struct iosys_map *map)
+{
+ if (WARN_ON(map->is_iomem))
+ return NULL;
+
+ return map->vaddr;
+}
+
+int tegra_ivc_init(struct tegra_ivc *ivc, struct device *peer, const struct iosys_map *rx,
+ dma_addr_t rx_phys, const struct iosys_map *tx, dma_addr_t tx_phys,
unsigned int num_frames, size_t frame_size,
void (*notify)(struct tegra_ivc *ivc, void *data),
void *data)
@@ -628,7 +662,7 @@ int tegra_ivc_init(struct tegra_ivc *ivc, struct device *peer, void *rx,
if (frame_size > INT_MAX)
return -E2BIG;
- err = tegra_ivc_check_params((unsigned long)rx, (unsigned long)tx,
+ err = tegra_ivc_check_params(iosys_map_get_address(rx), iosys_map_get_address(tx),
num_frames, frame_size);
if (err < 0)
return err;
@@ -636,12 +670,12 @@ int tegra_ivc_init(struct tegra_ivc *ivc, struct device *peer, void *rx,
queue_size = tegra_ivc_total_queue_size(num_frames * frame_size);
if (peer) {
- ivc->rx.phys = dma_map_single(peer, rx, queue_size,
+ ivc->rx.phys = dma_map_single(peer, iosys_map_get_vaddr(rx), queue_size,
DMA_BIDIRECTIONAL);
if (dma_mapping_error(peer, ivc->rx.phys))
return -ENOMEM;
- ivc->tx.phys = dma_map_single(peer, tx, queue_size,
+ ivc->tx.phys = dma_map_single(peer, iosys_map_get_vaddr(tx), queue_size,
DMA_BIDIRECTIONAL);
if (dma_mapping_error(peer, ivc->tx.phys)) {
dma_unmap_single(peer, ivc->rx.phys, queue_size,
@@ -653,8 +687,8 @@ int tegra_ivc_init(struct tegra_ivc *ivc, struct device *peer, void *rx,
ivc->tx.phys = tx_phys;
}
- ivc->rx.channel = rx;
- ivc->tx.channel = tx;
+ iosys_map_copy(&ivc->rx.map, rx);
+ iosys_map_copy(&ivc->tx.map, tx);
ivc->peer = peer;
ivc->notify = notify;
ivc->notify_data = data;
diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c
index ebc32bbd9b83..039d92a595ec 100644
--- a/drivers/firmware/ti_sci.c
+++ b/drivers/firmware/ti_sci.c
@@ -429,15 +429,14 @@ static inline int ti_sci_do_xfer(struct ti_sci_info *info,
* during noirq phase, so we must manually poll the completion.
*/
ret = read_poll_timeout_atomic(try_wait_for_completion, done_state,
- true, 1,
+ done_state, 1,
info->desc->max_rx_timeout_ms * 1000,
false, &xfer->done);
}
- if (ret == -ETIMEDOUT || !done_state) {
+ if (ret == -ETIMEDOUT)
dev_err(dev, "Mbox timedout in resp(caller: %pS)\n",
(void *)_RET_IP_);
- }
/*
* NOTE: we might prefer not to need the mailbox ticker to manage the
@@ -3096,7 +3095,7 @@ u16 ti_sci_get_free_resource(struct ti_sci_resource *res)
free_bit = find_first_zero_bit(desc->res_map, res_count);
if (free_bit != res_count) {
- set_bit(free_bit, desc->res_map);
+ __set_bit(free_bit, desc->res_map);
raw_spin_unlock_irqrestore(&res->lock, flags);
if (desc->num && free_bit < desc->num)
@@ -3127,10 +3126,10 @@ void ti_sci_release_resource(struct ti_sci_resource *res, u16 id)
if (desc->num && desc->start <= id &&
(desc->start + desc->num) > id)
- clear_bit(id - desc->start, desc->res_map);
+ __clear_bit(id - desc->start, desc->res_map);
else if (desc->num_sec && desc->start_sec <= id &&
(desc->start_sec + desc->num_sec) > id)
- clear_bit(id - desc->start_sec, desc->res_map);
+ __clear_bit(id - desc->start_sec, desc->res_map);
}
raw_spin_unlock_irqrestore(&res->lock, flags);
}
@@ -3201,9 +3200,8 @@ devm_ti_sci_get_resource_sets(const struct ti_sci_handle *handle,
valid_set = true;
res_count = res->desc[i].num + res->desc[i].num_sec;
- res->desc[i].res_map =
- devm_kzalloc(dev, BITS_TO_LONGS(res_count) *
- sizeof(*res->desc[i].res_map), GFP_KERNEL);
+ res->desc[i].res_map = devm_bitmap_zalloc(dev, res_count,
+ GFP_KERNEL);
if (!res->desc[i].res_map)
return ERR_PTR(-ENOMEM);
}
@@ -3400,13 +3398,11 @@ static int ti_sci_probe(struct platform_device *pdev)
if (!minfo->xfer_block)
return -ENOMEM;
- minfo->xfer_alloc_table = devm_kcalloc(dev,
- BITS_TO_LONGS(desc->max_msgs),
- sizeof(unsigned long),
- GFP_KERNEL);
+ minfo->xfer_alloc_table = devm_bitmap_zalloc(dev,
+ desc->max_msgs,
+ GFP_KERNEL);
if (!minfo->xfer_alloc_table)
return -ENOMEM;
- bitmap_zero(minfo->xfer_alloc_table, desc->max_msgs);
/* Pre-initialize the buffer pointer to pre-allocated buffers */
for (i = 0, xfer = minfo->xfer_block; i < desc->max_msgs; i++, xfer++) {
diff --git a/drivers/firmware/xilinx/zynqmp.c b/drivers/firmware/xilinx/zynqmp.c
index ff5cabe70a2b..6bc6b6c84241 100644
--- a/drivers/firmware/xilinx/zynqmp.c
+++ b/drivers/firmware/xilinx/zynqmp.c
@@ -843,6 +843,13 @@ int zynqmp_pm_read_pggs(u32 index, u32 *value)
}
EXPORT_SYMBOL_GPL(zynqmp_pm_read_pggs);
+int zynqmp_pm_set_tapdelay_bypass(u32 index, u32 value)
+{
+ return zynqmp_pm_invoke_fn(PM_IOCTL, 0, IOCTL_SET_TAPDELAY_BYPASS,
+ index, value, NULL);
+}
+EXPORT_SYMBOL_GPL(zynqmp_pm_set_tapdelay_bypass);
+
/**
* zynqmp_pm_set_boot_health_status() - PM API for setting healthy boot status
* @value: Status value to be written