* refs/heads/tmp-10f1d14:
Linux 4.19.86
x86/resctrl: Fix rdt_find_domain() return value and checks
mmc: tmio: fix SCC error handling to avoid false positive CRC error
powerpc/time: Fix clockevent_decrementer initalisation for PR KVM
tools: PCI: Fix broken pcitest compilation
PM / devfreq: Fix static checker warning in try_then_request_governor
ACPI / LPSS: Use acpi_lpss_* instead of acpi_subsys_* functions for hibernate
tcp: start receiver buffer autotuning sooner
ARM: dts: omap5: Fix dual-role mode on Super-Speed port
mlxsw: spectrum_switchdev: Check notification relevance based on upper device
spi: rockchip: initialize dma_slave_config properly
mac80211: minstrel: fix sampling/reporting of CCK rates in HT mode
mac80211: minstrel: fix CCK rate group streams value
mac80211: minstrel: fix using short preamble CCK rates on HT clients
misc: cxl: Fix possible null pointer dereference
netfilter: nft_compat: do not dump private area
net: sched: avoid writing on noop_qdisc
selftests: forwarding: Have lldpad_app_wait_set() wait for unknown, too
hwmon: (npcm-750-pwm-fan) Change initial pwm target to 255
hwmon: (ina3221) Fix INA3221_CONFIG_MODE macros
hwmon: (pwm-fan) Silence error on probe deferral
hwmon: (nct6775) Fix names of DIMM temperature sources
hwmon: (k10temp) Support all Family 15h Model 6xh and Model 7xh processors
scsi: arcmsr: clean up clang warning on extraneous parentheses
pinctrl: gemini: Fix up TVC clock group
orangefs: rate limit the client not running info message
x86/mm: Do not warn about PCI BIOS W+X mappings
ARM: 8802/1: Call syscall_trace_exit even when system call skipped
spi: spidev: Fix OF tree warning logic
pinctrl: gemini: Mask and set properly
spi: fsl-lpspi: Prevent FIFO under/overrun by default
gpio: syscon: Fix possible NULL ptr usage
net: fix generic XDP to handle if eth header was mangled
bpf: btf: Fix a missing check bug
x86/kexec: Correct KEXEC_BACKUP_SRC_END off-by-one error
lightnvm: pblk: consider max hw sectors supported for max_write_pgs
lightnvm: pblk: fix error handling of pblk_lines_init()
lightnvm: do no update csecs and sos on 1.2
lightnvm: pblk: guarantee mw_cunits on read buffer
lightnvm: pblk: fix write amplificiation calculation
lightnvm: pblk: guarantee emeta on line close
lightnvm: pblk: fix incorrect min_write_pgs
lightnvm: pblk: fix rqd.error return value in pblk_blk_erase_sync
ALSA: hda/ca0132 - Fix input effect controls for desktop cards
media: venus: vdec: fix decoded data size
media: cx231xx: fix potential sign-extension overflow on large shift
GFS2: Flush the GFS2 delete workqueue before stopping the kernel threads
media: isif: fix a NULL pointer dereference bug
printk: Give error on attempt to set log buffer length to over 2G
mfd: ti_am335x_tscadc: Keep ADC interface on if child is wakeup capable
backlight: lm3639: Unconditionally call led_classdev_unregister
proc/vmcore: Fix i386 build error of missing copy_oldmem_page_encrypted()
s390/kasan: avoid user access code instrumentation
s390/kasan: avoid instrumentation of early C code
s390/kasan: avoid vdso instrumentation
mmc: mmci: expand startbiterr to irqmask and error check
x86/intel_rdt: CBM overlap should also check for overlap with CDP peer
x86/intel_rdt: Introduce utility to obtain CDP peer
mtd: devices: m25p80: Make sure WRITE_EN is issued before each write
mtd: spi-nor: cadence-quadspi: Use proper enum for dma_[un]map_single
media: cx18: Don't check for address of video_dev
media: dw9807-vcm: Fix probe error handling
media: dw9714: Fix error handling in probe function
platform/x86: mlx-platform: Properly use mlxplat_mlxcpld_msn201x_items
bcache: recal cached_dev_sectors on detach
bcache: account size of buckets used in uuid write to ca->meta_sectors_written
reset: Fix potential use-after-free in __of_reset_control_get()
fbdev: fix broken menu dependencies
fbdev: sbuslib: integer overflow in sbusfb_ioctl_helper()
fbdev: sbuslib: use checked version of put_user()
atmel_lcdfb: support native-mode display-timings
mmc: renesas_sdhi_internal_dmac: set scatter/gather max segment size
mmc: tmio: Fix SCC error detection
mmc: renesas_sdhi_internal_dmac: Whitelist r8a774a1
x86/fsgsbase/64: Fix ptrace() to read the FS/GS base accurately
xsk: proper AF_XDP socket teardown ordering
iwlwifi: mvm: don't send keys when entering D3
ACPI / SBS: Fix rare oops when removing modules
xfrm: use correct size to initialise sp->ovec
crypto: mxs-dcp - Fix AES issues
crypto: mxs-dcp - Fix SHA null hashes and output length
dmaengine: rcar-dmac: set scatter/gather max segment size
x86/olpc: Fix build error with CONFIG_MFD_CS5535=m
kexec: Allocate decrypted control pages for kdump if SME is enabled
remoteproc: qcom: q6v5: Fix a race condition on fatal crash
remoteproc: Check for NULL firmwares in sysfs interface
tc-testing: fix build of eBPF programs
net: hns3: Fix for rx vlan id handle to support Rev 0x21 hardware
soc: fsl: bman_portals: defer probe after bman's probe
Input: silead - try firmware reload after unsuccessful resume
Input: st1232 - set INPUT_PROP_DIRECT property
i2c: zx2967: use core to detect 'no zero length' quirk
i2c: tegra: use core to detect 'no zero length' quirk
i2c: qup: use core to detect 'no zero length' quirk
i2c: omap: use core to detect 'no zero length' quirk
gfs2: slow the deluge of io error messages
media: cec-gpio: select correct Signal Free Time
media: ov5640: fix framerate update
dmaengine: ioat: fix prototype of ioat_enumerate_channels
NFSv4.x: fix lock recovery during delegation recall
printk: Correct wrong casting
i2c: brcmstb: Allow enabling the driver on DSL SoCs
clk: samsung: Use clk_hw API for calling clk framework from clk notifiers
clk: samsung: exynos5420: Define CLK_SECKEY gate clock only or Exynos5420
clk: samsung: Use NOIRQ stage for Exynos5433 clocks suspend/resume
qtnfmac: drop error reports for out-of-bounds key indexes
qtnfmac: inform wireless core about supported extended capabilities
qtnfmac: pass sgi rate info flag to wireless core
qtnfmac: request userspace to do OBSS scanning if FW can not
brcmfmac: fix full timeout waiting for action frame on-channel tx
brcmfmac: reduce timeout for action frame scan
cpu/SMT: State SMT is disabled even with nosmt and without "=force"
mtd: physmap_of: Release resources on error
usb: dwc2: disable power_down on rockchip devices
USB: serial: cypress_m8: fix interrupt-out transfer length
KVM: PPC: Book3S PR: Exiting split hack mode needs to fixup both PC and LR
bnxt_en: return proper error when FW returns HWRM_ERR_CODE_RESOURCE_ACCESS_DENIED
ALSA: hda/sigmatel - Disable automute for Elo VuPoint
media: i2c: adv748x: Support probing a single output
media: rcar-vin: fix redeclaration of symbol
media: pxa_camera: Fix check for pdev->dev.of_node
media: rc: ir-rc6-decoder: enable toggle bit for Kathrein RCU-676 remote
qed: Avoid implicit enum conversion in qed_ooo_submit_tx_buffers
ata: ep93xx: Use proper enums for directions
powerpc/64s/radix: Explicitly flush ERAT with local LPID invalidation
powerpc/time: Use clockevents_register_device(), fixing an issue with large decrementer
ASoC: qdsp6: q6asm-dai: checking NULL vs IS_ERR()
cpuidle: menu: Fix wakeup statistics updates for polling state
ACPICA: Never run _REG on system_memory and system_IO
OPP: Return error on error from dev_pm_opp_get_opp_count()
msm/gpu/a6xx: Force of_dma_configure to setup DMA for GMU
rpmsg: glink: smem: Support rx peak for size less than 4 bytes
IB/mlx4: Avoid implicit enumerated type conversion
RDMA/hns: Limit the size of extend sge of sq
RDMA/hns: Bugfix for CM test
RDMA/hns: Submit bad wr when post send wr exception
RDMA/hns: Bugfix for reserved qp number
IB/rxe: avoid srq memory leak
IB/mthca: Fix error return code in __mthca_init_one()
ixgbe: Fix crash with VFs and flow director on interface flap
i40e: Use proper enum in i40e_ndo_set_vf_link_state
ixgbe: Fix ixgbe TX hangs with XDP_TX beyond queue limit
md: allow metadata updates while suspending an array - fix
ice: Fix forward to queue group logic
clocksource/drivers/sh_cmt: Fix clocksource width for 32-bit machines
clocksource/drivers/sh_cmt: Fixup for 64-bit machines
tools: PCI: Fix compilation warnings
PM / hibernate: Check the success of generating md5 digest before hibernation
mtd: rawnand: sh_flctl: Use proper enum for flctl_dma_fifo0_transfer
ARM: dts: at91: sama5d2_ptc_ek: fix bootloader env offsets
ARM: dts: at91: at91sam9x5cm: fix addressable nand flash size
ARM: dts: at91: sama5d4_xplained: fix addressable nand flash size
powerpc/xive: Move a dereference below a NULL test
powerpc/pseries: Fix how we iterate over the DTL entries
powerpc/pseries: Fix DTL buffer registration
cxgb4: Use proper enum in IEEE_FAUX_SYNC
cxgb4: Use proper enum in cxgb4_dcb_handle_fw_update
mei: samples: fix a signedness bug in amt_host_if_call()
x86/PCI: Apply VMD's AERSID fixup generically
sunrpc: Fix connect metrics
clk: keystone: Enable TISCI clocks if K3_ARCH
ext4: fix build error when DX_DEBUG is defined
ALSA: hda: Fix mismatch for register mask and value in ext controller.
dmaengine: timb_dma: Use proper enum in td_prep_slave_sg
dmaengine: ep93xx: Return proper enum in ep93xx_dma_chan_direction
printk: CON_PRINTBUFFER console registration is a bit racy
printk: Do not miss new messages when replaying the log
KVM: PPC: Inform the userspace about TCE update failures
watchdog: w83627hf_wdt: Support NCT6796D, NCT6797D, NCT6798D
watchdog: sama5d4: fix timeout-sec usage
watchdog: renesas_wdt: stop when unregistering
watchdog: core: fix null pointer dereference when releasing cdev
irqchip/irq-mvebu-icu: Fix wrong private data retrieval
nl80211: Fix a GET_KEY reply attribute
usb: dwc3: gadget: Check ENBLSLPM before sending ep command
usb: gadget: udc: fotg210-udc: Fix a sleep-in-atomic-context bug in fotg210_get_status()
selftests/tls: Fix recv(MSG_PEEK) & splice() test cases
ath9k: fix reporting calculated new FFT upper max
PM / devfreq: stopping the governor before device_unregister()
PM / devfreq: Fix handling of min/max_freq == 0
PM / devfreq: Fix devfreq_add_device() when drivers are built as modules.
ata: ahci_brcm: Allow using driver or DSL SoCs
rtlwifi: btcoex: Use proper enumerated types for Wi-Fi only interface
ath10k: fix vdev-start timeout on error
arm64/numa: Report correct memblock range for the dummy node
kvm: arm/arm64: Fix stage2_flush_memslot for 4 level page table
iommu/arm-smmu-v3: Fix unexpected CMD_SYNC timeout
iommu/io-pgtable-arm: Fix race handling in split_blk_unmap()
mt76: fix handling ps-poll frames
mt76x2: disable WLAN core before probe
mt76x2: fix tx power configuration for VHT mcs 9
IB/hfi1: Ensure ucast_dlid access doesnt exceed bounds
IB/hfi1: Error path MAD response size is incorrect
f2fs: keep lazytime on remount
ACPI / LPSS: Resume BYT/CHT I2C controllers from resume_noirq
ACPI / LPSS: Make acpi_lpss_find_device() also find PCI devices
SUNRPC: Fix priority queue fairness
tcp: up initial rmem to 128KB and SYN rwin to around 64KB
ARM: dts: sun8i: h3: bpi-m2-plus: Fix address for external RGMII Ethernet PHY
ARM: dts: sun8i: h3-h5: ir register size should be the whole memory block
f2fs: return correct errno in f2fs_gc
net: hns3: Fix loss of coal configuration while doing reset
net: hns3: Fix for netdev not up problem when setting mtu
ARM: dts: omap5: enable OTG role for DWC3 controller
ARM: dts: dra7: Enable workaround for errata i870 in PCIe host mode
net: xen-netback: fix return type of ndo_start_xmit function
net: ovs: fix return type of ndo_start_xmit function
bpf, x32: Fix bug for BPF_JMP | {BPF_JSGT, BPF_JSLE, BPF_JSLT, BPF_JSGE}
bpf, x32: Fix bug with ALU64 {LSH, RSH, ARSH} BPF_K shift by 0
bpf, x32: Fix bug with ALU64 {LSH, RSH, ARSH} BPF_X shift by 0
bpf, x32: Fix bug for BPF_ALU64 | BPF_NEG
fbdev: Ditch fb_edid_add_monspecs
arm64: uaccess: Ensure PAN is re-enabled after unhandled uaccess fault
mm/memory_hotplug: fix updating the node span
mm/memory_hotplug: don't access uninitialized memmaps in shrink_pgdat_span()
idr: Fix idr_get_next race with idr_remove
net: cdc_ncm: Signedness bug in cdc_ncm_set_dgram_size()
Revert "OPP: Protect dev_list with opp_table lock"
tee: optee: add missing of_node_put after of_device_is_available
i2c: mediatek: modify threshold passed to i2c_get_dma_safe_msg_buf()
spi: mediatek: use correct mata->xfer_len when in fifo transfer
Conflicts:
drivers/rpmsg/qcom_glink_smem.c
drivers/usb/dwc3/gadget.c
Change-Id: I6e0f156d860bf2afcaabcf70d653676eb7d3de4e
Signed-off-by: Ivaylo Georgiev <irgeorgiev@codeaurora.org>
337 lines
7.6 KiB
C
337 lines
7.6 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* Copyright (c) 2016, Linaro Ltd
|
|
* Copyright (c) 2018-2019, The Linux Foundation, All rights reserved.
|
|
*/
|
|
|
|
#include <linux/io.h>
|
|
#include <linux/module.h>
|
|
#include <linux/of.h>
|
|
#include <linux/of_address.h>
|
|
#include <linux/interrupt.h>
|
|
#include <linux/platform_device.h>
|
|
#include <linux/mfd/syscon.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/rpmsg.h>
|
|
#include <linux/idr.h>
|
|
#include <linux/circ_buf.h>
|
|
#include <linux/soc/qcom/smem.h>
|
|
#include <linux/sizes.h>
|
|
#include <linux/delay.h>
|
|
#include <linux/regmap.h>
|
|
#include <linux/workqueue.h>
|
|
#include <linux/list.h>
|
|
|
|
#include <linux/rpmsg/qcom_glink.h>
|
|
|
|
#include "qcom_glink_native.h"
|
|
|
|
#define FIFO_FULL_RESERVE 8
|
|
#define FIFO_ALIGNMENT 8
|
|
#define TX_BLOCKED_CMD_RESERVE 8 /* size of struct read_notif_request */
|
|
|
|
#define SMEM_GLINK_NATIVE_XPRT_DESCRIPTOR 478
|
|
#define SMEM_GLINK_NATIVE_XPRT_FIFO_0 479
|
|
#define SMEM_GLINK_NATIVE_XPRT_FIFO_1 480
|
|
|
|
struct glink_smem_pipe {
|
|
struct qcom_glink_pipe native;
|
|
|
|
__le32 *tail;
|
|
__le32 *head;
|
|
|
|
void *fifo;
|
|
|
|
int remote_pid;
|
|
};
|
|
|
|
#define to_smem_pipe(p) container_of(p, struct glink_smem_pipe, native)
|
|
|
|
static void glink_smem_rx_reset(struct qcom_glink_pipe *np)
|
|
{
|
|
struct glink_smem_pipe *pipe = to_smem_pipe(np);
|
|
*pipe->tail = 0;
|
|
}
|
|
|
|
static size_t glink_smem_rx_avail(struct qcom_glink_pipe *np)
|
|
{
|
|
struct glink_smem_pipe *pipe = to_smem_pipe(np);
|
|
size_t len;
|
|
void *fifo;
|
|
u32 head;
|
|
u32 tail;
|
|
|
|
if (!pipe->fifo) {
|
|
fifo = qcom_smem_get(pipe->remote_pid,
|
|
SMEM_GLINK_NATIVE_XPRT_FIFO_1, &len);
|
|
if (IS_ERR(fifo)) {
|
|
pr_err("failed to acquire RX fifo handle: %ld\n",
|
|
PTR_ERR(fifo));
|
|
return 0;
|
|
}
|
|
|
|
pipe->fifo = fifo;
|
|
pipe->native.length = len;
|
|
}
|
|
|
|
head = le32_to_cpu(*pipe->head);
|
|
tail = le32_to_cpu(*pipe->tail);
|
|
|
|
if (head < tail)
|
|
len = pipe->native.length - tail + head;
|
|
else
|
|
len = head - tail;
|
|
|
|
if (WARN_ON_ONCE(len > pipe->native.length))
|
|
len = 0;
|
|
|
|
return len;
|
|
}
|
|
|
|
static void glink_smem_rx_peak(struct qcom_glink_pipe *np,
|
|
void *data, unsigned int offset, size_t count)
|
|
{
|
|
struct glink_smem_pipe *pipe = to_smem_pipe(np);
|
|
size_t len;
|
|
u32 tail;
|
|
|
|
tail = le32_to_cpu(*pipe->tail);
|
|
|
|
if (WARN_ON_ONCE(tail > pipe->native.length))
|
|
return;
|
|
|
|
tail += offset;
|
|
if (tail >= pipe->native.length)
|
|
tail -= pipe->native.length;
|
|
|
|
len = min_t(size_t, count, pipe->native.length - tail);
|
|
if (len)
|
|
memcpy_fromio(data, pipe->fifo + tail, len);
|
|
|
|
if (len != count)
|
|
memcpy_fromio(data + len, pipe->fifo, (count - len));
|
|
}
|
|
|
|
static void glink_smem_rx_advance(struct qcom_glink_pipe *np,
|
|
size_t count)
|
|
{
|
|
struct glink_smem_pipe *pipe = to_smem_pipe(np);
|
|
u32 tail;
|
|
|
|
tail = le32_to_cpu(*pipe->tail);
|
|
|
|
tail += count;
|
|
if (tail >= pipe->native.length)
|
|
tail %= pipe->native.length;
|
|
|
|
*pipe->tail = cpu_to_le32(tail);
|
|
}
|
|
|
|
static void glink_smem_tx_reset(struct qcom_glink_pipe *np)
|
|
{
|
|
struct glink_smem_pipe *pipe = to_smem_pipe(np);
|
|
*pipe->head = 0;
|
|
}
|
|
|
|
static size_t glink_smem_tx_avail(struct qcom_glink_pipe *np)
|
|
{
|
|
struct glink_smem_pipe *pipe = to_smem_pipe(np);
|
|
u32 head;
|
|
u32 tail;
|
|
u32 avail;
|
|
|
|
head = le32_to_cpu(*pipe->head);
|
|
tail = le32_to_cpu(*pipe->tail);
|
|
|
|
if (tail <= head)
|
|
avail = pipe->native.length - head + tail;
|
|
else
|
|
avail = tail - head;
|
|
|
|
if (avail < (FIFO_FULL_RESERVE + TX_BLOCKED_CMD_RESERVE))
|
|
avail = 0;
|
|
else
|
|
avail -= FIFO_FULL_RESERVE + TX_BLOCKED_CMD_RESERVE;
|
|
|
|
if (WARN_ON_ONCE(avail > pipe->native.length))
|
|
avail = 0;
|
|
|
|
return avail;
|
|
}
|
|
|
|
static unsigned int glink_smem_tx_write_one(struct glink_smem_pipe *pipe,
|
|
unsigned int head,
|
|
const void *data, size_t count)
|
|
{
|
|
size_t len;
|
|
|
|
if (WARN_ON_ONCE(head > pipe->native.length))
|
|
return head;
|
|
|
|
len = min_t(size_t, count, pipe->native.length - head);
|
|
if (len)
|
|
memcpy(pipe->fifo + head, data, len);
|
|
|
|
if (len != count)
|
|
memcpy(pipe->fifo, data + len, count - len);
|
|
|
|
head += count;
|
|
if (head >= pipe->native.length)
|
|
head -= pipe->native.length;
|
|
|
|
return head;
|
|
}
|
|
|
|
static void glink_smem_tx_write(struct qcom_glink_pipe *glink_pipe,
|
|
const void *hdr, size_t hlen,
|
|
const void *data, size_t dlen)
|
|
{
|
|
struct glink_smem_pipe *pipe = to_smem_pipe(glink_pipe);
|
|
unsigned int head;
|
|
|
|
head = le32_to_cpu(*pipe->head);
|
|
|
|
head = glink_smem_tx_write_one(pipe, head, hdr, hlen);
|
|
head = glink_smem_tx_write_one(pipe, head, data, dlen);
|
|
|
|
/* Ensure head is always aligned to 8 bytes */
|
|
head = ALIGN(head, 8);
|
|
if (head >= pipe->native.length)
|
|
head -= pipe->native.length;
|
|
|
|
/* Ensure ordering of fifo and head update */
|
|
wmb();
|
|
|
|
*pipe->head = cpu_to_le32(head);
|
|
}
|
|
|
|
static void qcom_glink_smem_release(struct device *dev)
|
|
{
|
|
kfree(dev);
|
|
}
|
|
|
|
struct qcom_glink *qcom_glink_smem_register(struct device *parent,
|
|
struct device_node *node)
|
|
{
|
|
struct glink_smem_pipe *rx_pipe;
|
|
struct glink_smem_pipe *tx_pipe;
|
|
struct qcom_glink *glink;
|
|
struct device *dev;
|
|
u32 remote_pid;
|
|
__le32 *descs;
|
|
size_t size;
|
|
int ret;
|
|
|
|
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
|
|
if (!dev)
|
|
return ERR_PTR(-ENOMEM);
|
|
|
|
dev->parent = parent;
|
|
dev->of_node = node;
|
|
dev->release = qcom_glink_smem_release;
|
|
dev_set_name(dev, "%s:%s", node->parent->name, node->name);
|
|
ret = device_register(dev);
|
|
if (ret) {
|
|
pr_err("failed to register glink edge\n");
|
|
put_device(dev);
|
|
return ERR_PTR(ret);
|
|
}
|
|
|
|
ret = of_property_read_u32(dev->of_node, "qcom,remote-pid",
|
|
&remote_pid);
|
|
if (ret) {
|
|
dev_err(dev, "failed to parse qcom,remote-pid\n");
|
|
goto err_put_dev;
|
|
}
|
|
|
|
rx_pipe = devm_kzalloc(dev, sizeof(*rx_pipe), GFP_KERNEL);
|
|
tx_pipe = devm_kzalloc(dev, sizeof(*tx_pipe), GFP_KERNEL);
|
|
if (!rx_pipe || !tx_pipe) {
|
|
ret = -ENOMEM;
|
|
goto err_put_dev;
|
|
}
|
|
|
|
ret = qcom_smem_alloc(remote_pid,
|
|
SMEM_GLINK_NATIVE_XPRT_DESCRIPTOR, 32);
|
|
if (ret && ret != -EEXIST) {
|
|
dev_err(dev, "failed to allocate glink descriptors\n");
|
|
goto err_put_dev;
|
|
}
|
|
|
|
descs = qcom_smem_get(remote_pid,
|
|
SMEM_GLINK_NATIVE_XPRT_DESCRIPTOR, &size);
|
|
if (IS_ERR(descs)) {
|
|
dev_err(dev, "failed to acquire xprt descriptor\n");
|
|
ret = PTR_ERR(descs);
|
|
goto err_put_dev;
|
|
}
|
|
|
|
if (size != 32) {
|
|
dev_err(dev, "glink descriptor of invalid size\n");
|
|
ret = -EINVAL;
|
|
goto err_put_dev;
|
|
}
|
|
|
|
tx_pipe->tail = &descs[0];
|
|
tx_pipe->head = &descs[1];
|
|
rx_pipe->tail = &descs[2];
|
|
rx_pipe->head = &descs[3];
|
|
|
|
ret = qcom_smem_alloc(remote_pid, SMEM_GLINK_NATIVE_XPRT_FIFO_0,
|
|
SZ_16K);
|
|
if (ret && ret != -EEXIST) {
|
|
dev_err(dev, "failed to allocate TX fifo\n");
|
|
goto err_put_dev;
|
|
}
|
|
|
|
tx_pipe->fifo = qcom_smem_get(remote_pid, SMEM_GLINK_NATIVE_XPRT_FIFO_0,
|
|
&tx_pipe->native.length);
|
|
if (IS_ERR(tx_pipe->fifo)) {
|
|
dev_err(dev, "failed to acquire TX fifo\n");
|
|
ret = PTR_ERR(tx_pipe->fifo);
|
|
goto err_put_dev;
|
|
}
|
|
|
|
rx_pipe->native.reset = glink_smem_rx_reset;
|
|
rx_pipe->native.avail = glink_smem_rx_avail;
|
|
rx_pipe->native.peak = glink_smem_rx_peak;
|
|
rx_pipe->native.advance = glink_smem_rx_advance;
|
|
rx_pipe->remote_pid = remote_pid;
|
|
|
|
tx_pipe->native.reset = glink_smem_tx_reset;
|
|
tx_pipe->native.avail = glink_smem_tx_avail;
|
|
tx_pipe->native.write = glink_smem_tx_write;
|
|
tx_pipe->remote_pid = remote_pid;
|
|
|
|
*rx_pipe->tail = 0;
|
|
*tx_pipe->head = 0;
|
|
|
|
glink = qcom_glink_native_probe(dev,
|
|
GLINK_FEATURE_INTENT_REUSE,
|
|
&rx_pipe->native, &tx_pipe->native,
|
|
false);
|
|
if (IS_ERR(glink)) {
|
|
ret = PTR_ERR(glink);
|
|
goto err_put_dev;
|
|
}
|
|
|
|
return glink;
|
|
|
|
err_put_dev:
|
|
device_unregister(dev);
|
|
|
|
return ERR_PTR(ret);
|
|
}
|
|
EXPORT_SYMBOL_GPL(qcom_glink_smem_register);
|
|
|
|
void qcom_glink_smem_unregister(struct qcom_glink *glink)
|
|
{
|
|
qcom_glink_native_remove(glink);
|
|
qcom_glink_native_unregister(glink);
|
|
}
|
|
EXPORT_SYMBOL_GPL(qcom_glink_smem_unregister);
|
|
|
|
MODULE_AUTHOR("Bjorn Andersson <bjorn.andersson@linaro.org>");
|
|
MODULE_DESCRIPTION("Qualcomm GLINK SMEM driver");
|
|
MODULE_LICENSE("GPL v2");
|