* refs/heads/tmp-d9e388f: Linux 4.19.78 9p/cache.c: Fix memory leak in v9fs_cache_session_get_cookie kexec: bail out upon SIGKILL when allocating memory. NFC: fix attrs checks in netlink interface smack: use GFP_NOFS while holding inode_smack::smk_lock Smack: Don't ignore other bprm->unsafe flags if LSM_UNSAFE_PTRACE is set soundwire: fix regmap dependencies and align with other serial links soundwire: Kconfig: fix help format sch_cbq: validate TCA_CBQ_WRROPT to avoid crash tipc: fix unlimited bundling of small messages xen-netfront: do not use ~0U as error return value for xennet_fill_frags() net/rds: Fix error handling in rds_ib_add_one() udp: only do GSO if # of segs > 1 net: dsa: rtl8366: Check VLAN ID and not ports vsock: Fix a lockdep warning in __vsock_release() udp: fix gso_segs calculations sch_dsmark: fix potential NULL deref in dsmark_init() rxrpc: Fix rxrpc_recvmsg tracepoint qmi_wwan: add support for Cinterion CLS8 devices nfc: fix memory leak in llcp_sock_bind() net: Unpublish sk from sk_reuseport_cb before call_rcu net: qlogic: Fix memory leak in ql_alloc_large_buffers net: ipv4: avoid mixed n_redirects and rate_tokens usage ipv6: Handle missing host route in __ipv6_ifa_notify ipv6: drop incoming packets having a v4mapped source address hso: fix NULL-deref on tty open erspan: remove the incorrect mtu limit for erspan cxgb4:Fix out-of-bounds MSI-X info array access bpf: fix use after free in prog symbol exposure block: mq-deadline: Fix queue restart handling arm: use STACK_TOP when computing mmap base address arm: properly account for stack randomization and stack guard gap mips: properly account for stack randomization and stack guard gap arm64: consider stack randomization for mmap base only when necessary kmemleak: increase DEBUG_KMEMLEAK_EARLY_LOG_SIZE default to 16K ocfs2: wait for recovering done after direct unlock request kbuild: clean compressed initramfs image crypto: hisilicon - Fix double free in sec_free_hw_sgl() hypfs: Fix error number left in struct pointer member pktcdvd: remove warning on attempting to register non-passthrough dev fat: work around race with userspace's read via blockdev while mounting ARM: 8903/1: ensure that usable memory in bank 0 starts from a PMD-aligned address security: smack: Fix possible null-pointer dereferences in smack_socket_sock_rcv_skb() PCI: exynos: Propagate errors for optional PHYs PCI: imx6: Propagate errors for optional regulators PCI: histb: Propagate errors for optional regulators PCI: rockchip: Propagate errors for optional regulators HID: apple: Fix stuck function keys when using FN rtc: pcf85363/pcf85263: fix regmap error in set_time rtc: snvs: fix possible race condition ARM: 8875/1: Kconfig: default to AEABI w/ Clang soundwire: intel: fix channel number reported by hardware ARM: 8898/1: mm: Don't treat faults reported from cache maintenance as writes livepatch: Nullify obj->mod in klp_module_coming()'s error path HID: wacom: Fix several minor compiler warnings PCI: tegra: Fix OF node reference leak mfd: intel-lpss: Remove D3cold delay i2c-cht-wc: Fix lockdep warning MIPS: tlbex: Explicitly cast _PAGE_NO_EXEC to a boolean MIPS: Ingenic: Disable broken BTB lookup optimization. ext4: fix potential use after free after remounting with noblock_validity dma-buf/sw_sync: Synchronize signal vs syncpt free scsi: core: Reduce memory required for SCSI logging clk: sprd: add missing kfree mbox: qcom: add APCS child device for QCS404 powerpc: dump kernel log before carrying out fadump or kdump clk: at91: select parent if main oscillator or bypass is enabled arm64: fix unreachable code issue with cmpxchg pinctrl: meson-gxbb: Fix wrong pinning definition for uart_c powerpc/pseries: correctly track irq state in default idle clk: qcom: gcc-sdm845: Use floor ops for sdcc clks pstore: fs superblock limits powerpc/64s/exception: machine check use correct cfar for late handler drm/amdgpu/si: fix ASIC tests drm/amd/display: support spdif clk: renesas: cpg-mssr: Set GENPD_FLAG_ALWAYS_ON for clock domain clk: renesas: mstp: Set GENPD_FLAG_ALWAYS_ON for clock domain pinctrl: amd: disable spurious-firing GPIO IRQs drm/nouveau/volt: Fix for some cards having 0 maximum voltage vfio_pci: Restore original state on release powerpc/eeh: Clear stale EEH_DEV_NO_HANDLER flag pinctrl: tegra: Fix write barrier placement in pmx_writel powerpc/pseries/mobility: use cond_resched when updating device tree powerpc/futex: Fix warning: 'oldval' may be used uninitialized in this function powerpc/rtas: use device model APIs and serialization during LPM powerpc/xmon: Check for HV mode when dumping XIVE info from OPAL clk: zx296718: Don't reference clk_init_data after registration clk: sprd: Don't reference clk_init_data after registration clk: sirf: Don't reference clk_init_data after registration clk: actions: Don't reference clk_init_data after registration powerpc/powernv/ioda2: Allocate TCE table levels on demand for default DMA window drm/amd/display: reprogram VM config when system resume drm/amd/display: fix issue where 252-255 values are clipped clk: sunxi-ng: v3s: add missing clock slices for MMC2 module clocks clk: qoriq: Fix -Wunused-const-variable ipmi_si: Only schedule continuously in the thread in maintenance mode PCI: rpaphp: Avoid a sometimes-uninitialized warning gpu: drm: radeon: Fix a possible null-pointer dereference in radeon_connector_set_property() drm/radeon: Fix EEH during kexec drm/rockchip: Check for fast link training before enabling psr drm/panel: check failure cases in the probe func drm/stm: attach gem fence to atomic state video: ssd1307fb: Start page range at page_offset drm/panel: simple: fix AUO g185han01 horizontal blanking drm/bridge: tc358767: Increase AUX transfer length limit tpm: Fix TPM 1.2 Shutdown sequence to prevent future TPM operations tpm: use tpm_try_get_ops() in tpm-sysfs.c. Change-Id: Icc0d8f26a806544c3f8969403522021169ea2f5c Signed-off-by: Ivaylo Georgiev <irgeorgiev@codeaurora.org>
168 lines
4.6 KiB
C
168 lines
4.6 KiB
C
/*
|
|
* Copyright (c) 2017, Linaro Ltd
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 and
|
|
* only version 2 as published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*/
|
|
|
|
#include <linux/kernel.h>
|
|
#include <linux/module.h>
|
|
#include <linux/io.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/of.h>
|
|
#include <linux/of_platform.h>
|
|
#include <linux/platform_device.h>
|
|
#include <linux/regmap.h>
|
|
#include <linux/mailbox_controller.h>
|
|
|
|
#define QCOM_APCS_IPC_BITS 32
|
|
|
|
struct qcom_apcs_ipc {
|
|
struct mbox_controller mbox;
|
|
struct mbox_chan mbox_chans[QCOM_APCS_IPC_BITS];
|
|
|
|
struct regmap *regmap;
|
|
unsigned long offset;
|
|
struct platform_device *clk;
|
|
};
|
|
|
|
static const struct regmap_config apcs_regmap_config = {
|
|
.reg_bits = 32,
|
|
.reg_stride = 4,
|
|
.val_bits = 32,
|
|
.max_register = 0x1000,
|
|
.fast_io = true,
|
|
};
|
|
|
|
static int qcom_apcs_ipc_send_data(struct mbox_chan *chan, void *data)
|
|
{
|
|
struct qcom_apcs_ipc *apcs = container_of(chan->mbox,
|
|
struct qcom_apcs_ipc, mbox);
|
|
unsigned long idx = (unsigned long)chan->con_priv;
|
|
|
|
return regmap_write(apcs->regmap, apcs->offset, BIT(idx));
|
|
}
|
|
|
|
static const struct mbox_chan_ops qcom_apcs_ipc_ops = {
|
|
.send_data = qcom_apcs_ipc_send_data,
|
|
};
|
|
|
|
static int qcom_apcs_ipc_probe(struct platform_device *pdev)
|
|
{
|
|
struct qcom_apcs_ipc *apcs;
|
|
struct regmap *regmap;
|
|
struct resource *res;
|
|
unsigned long offset;
|
|
void __iomem *base;
|
|
unsigned long i;
|
|
int ret;
|
|
const struct of_device_id apcs_clk_match_table[] = {
|
|
{ .compatible = "qcom,msm8916-apcs-kpss-global", },
|
|
{ .compatible = "qcom,qcs404-apcs-apps-global", },
|
|
{}
|
|
};
|
|
|
|
apcs = devm_kzalloc(&pdev->dev, sizeof(*apcs), GFP_KERNEL);
|
|
if (!apcs)
|
|
return -ENOMEM;
|
|
|
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
|
if (!res)
|
|
return -ENODEV;
|
|
base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
|
|
if (IS_ERR(base))
|
|
return PTR_ERR(base);
|
|
|
|
regmap = devm_regmap_init_mmio(&pdev->dev, base, &apcs_regmap_config);
|
|
if (IS_ERR(regmap))
|
|
return PTR_ERR(regmap);
|
|
|
|
offset = (unsigned long)of_device_get_match_data(&pdev->dev);
|
|
|
|
apcs->regmap = regmap;
|
|
apcs->offset = offset;
|
|
|
|
/* Initialize channel identifiers */
|
|
for (i = 0; i < ARRAY_SIZE(apcs->mbox_chans); i++)
|
|
apcs->mbox_chans[i].con_priv = (void *)i;
|
|
|
|
apcs->mbox.dev = &pdev->dev;
|
|
apcs->mbox.ops = &qcom_apcs_ipc_ops;
|
|
apcs->mbox.chans = apcs->mbox_chans;
|
|
apcs->mbox.num_chans = ARRAY_SIZE(apcs->mbox_chans);
|
|
|
|
ret = mbox_controller_register(&apcs->mbox);
|
|
if (ret) {
|
|
dev_err(&pdev->dev, "failed to register APCS IPC controller\n");
|
|
return ret;
|
|
}
|
|
|
|
if (of_match_device(apcs_clk_match_table, &pdev->dev)) {
|
|
apcs->clk = platform_device_register_data(&pdev->dev,
|
|
"qcom-apcs-msm8916-clk",
|
|
-1, NULL, 0);
|
|
if (IS_ERR(apcs->clk))
|
|
dev_err(&pdev->dev, "failed to register APCS clk\n");
|
|
}
|
|
|
|
platform_set_drvdata(pdev, apcs);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int qcom_apcs_ipc_remove(struct platform_device *pdev)
|
|
{
|
|
struct qcom_apcs_ipc *apcs = platform_get_drvdata(pdev);
|
|
struct platform_device *clk = apcs->clk;
|
|
|
|
mbox_controller_unregister(&apcs->mbox);
|
|
platform_device_unregister(clk);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* .data is the offset of the ipc register within the global block */
|
|
static const struct of_device_id qcom_apcs_ipc_of_match[] = {
|
|
{ .compatible = "qcom,msm8916-apcs-kpss-global", .data = (void *)8 },
|
|
{ .compatible = "qcom,msm8996-apcs-hmss-global", .data = (void *)16 },
|
|
{ .compatible = "qcom,msm8998-apcs-hmss-global", .data = (void *)8 },
|
|
{ .compatible = "qcom,sdm845-apss-shared", .data = (void *)12 },
|
|
{ .compatible = "qcom,sm8150-apcs-hmss-global", .data = (void *) 12 },
|
|
{ .compatible = "qcom,sm8150-spcs-global", .data = (void *)0 },
|
|
{ .compatible = "qcom,kona-spcs-global", .data = (void *)0 },
|
|
{ .compatible = "qcom,bengal-apcs-hmss-global", .data = (void *)8 },
|
|
{}
|
|
};
|
|
MODULE_DEVICE_TABLE(of, qcom_apcs_ipc_of_match);
|
|
|
|
static struct platform_driver qcom_apcs_ipc_driver = {
|
|
.probe = qcom_apcs_ipc_probe,
|
|
.remove = qcom_apcs_ipc_remove,
|
|
.driver = {
|
|
.name = "qcom_apcs_ipc",
|
|
.of_match_table = qcom_apcs_ipc_of_match,
|
|
.suppress_bind_attrs = true,
|
|
},
|
|
};
|
|
|
|
static int __init qcom_apcs_ipc_init(void)
|
|
{
|
|
return platform_driver_register(&qcom_apcs_ipc_driver);
|
|
}
|
|
postcore_initcall(qcom_apcs_ipc_init);
|
|
|
|
static void __exit qcom_apcs_ipc_exit(void)
|
|
{
|
|
platform_driver_unregister(&qcom_apcs_ipc_driver);
|
|
}
|
|
module_exit(qcom_apcs_ipc_exit);
|
|
|
|
MODULE_LICENSE("GPL v2");
|
|
MODULE_DESCRIPTION("Qualcomm APCS IPC driver");
|