cda8925044
* 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>
336 lines
7.6 KiB
C
336 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");
|