mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-24 10:11:26 +03:00
Import tegra platform drivers from linux-4.4. These files
are introduced or touched by the following commits in
linux-4.4:
5798930 arm: mach-tegra: Get rid of apbio.{c,h}
618d424 platform: tegra: enable denver_serr only for t18x
c9f681e arm: tegra: get rid of nct header
14cb7cf platform: tegra: nvdumper: Remove code which need NCT
46adb21 platform: tegra: mc: make mc-sid driver scalable and upstreamable
b0ea9ac usb: phy: Move header files to include/linux
7d63191 platform: tegra: mc: allow modules to access mc registers
1d5ac46 soc/tegra: Add GPU EDP Management
09166fd soc/tegra: Add CPU EDP Management
7118c16 platform: powergate: tegra: update ISPA name
59cebf1 bwmgr: Add tegra21 specific bwmgr functionality
e91ada2 bwmgr: merge dram specific functionality to common code
19fb2fe drivers: platform: tegra: remove TEGRA_21x defconfig
b87f6739 platform: nvadsp: fix is_mboxq_full check
b11cdba platform: tegra: powergate: do not handle SATA clk
8324487 platform: tegra: mc: remove cl34000094 hacks
a77d415 platform: tegra: mc: rename mc-sid.c to tegra-mc-sid.c
df6d5a8 platform: tegra: remove support for soctherm
e96ddb9 Merge "Merge branch 'dev/praithatha/k4.4_mc_sid' into dev-kernel-4.4" into dev-kernel-4.4
2f69aa5 Merge branch 'dev/praithatha/k4.4_mc_sid' into dev-kernel-4.4
e171bb1 adsp: dfs: override adsp dfs and reinit actmon
b7ca294 platform: tegra: mc: Add streamID configuration
457e747 nvdumper: fixed Coverity defects
e12c0c0 platform: tegra: Use ARCH_TEGRA_APE for APE PD code
40eba0d platform: tegra: drop flowctrl code
568ad6e central actmon: fix extra interrupt
944bdbf clk: tegra: Correct some nvenc clock names
5c957fe driver: platform: tegra: GR support
5af5163 coverity: Fix the error reported by Coverity
576ea23 tegra-virt-alt: Add adsp virtualization support
7407552 platform: tegra: nvadsp: Fix coverity defect
d11b6a0 platform: tegra: nvadsp: Fix coverity defect
6c41ef0 tegra: nvadsp: fix compilation when CONFIG_PM=n
4262e32 adsp: Add virtualization check
85384e2 Fix an uninitialized local value error
44a8d9c tegra: mc: export symbol tegra_set_latency_allowance
f699ce7 platform: nvadsp: disable app loading for secload
5ed4b72 drivers: tegra: allow to get "version" from dt
9b6fe36 tegra: add path to allow include
60d96e4 platform: tegra: nvadsp: nvadsp_os_get_version fix
79622a2 drivers: tegra: ape firmware version
27fb719 platform: tegra: iommu: enable linear map setup
b77bade platform: nvadsp: fix adsp clock handle
110b085 platform: tegra: Remove code for shared pad control
b770e0e bwmgr: pmqos: fix sparse warning
dd0400a platform: tegra: remove unused tegra_map_common_io
b343db9 platform: tegra: remove Tegra core voltage cap support
df9df6b platform/tegra: remove PMC wakeup support codes
c669b9a platform/tegra: pmc-iopower: switch to upstream PMC driver
688b6a6 platform/tegra: bootrom-pmc: switch to upstream PMC driver
d7d34e6 platform/tegra: remove reboot.c
60b4a47 soc/tegra: pmc: switch to upstream PMC driver
2c9409f bootprof: Separate discontinuous regions
e0cb4d2 arm64: tegra186: remove unused register nodes
12c2ba4 fiq reverts
65d8ccb platform: nvadsp: fix clk checks
b2eb017 platform: tegra: remove support for auto power detection
c403625 tegra: powergate: cleanup code for unsupported platform
589fecb platform: tegra: Removing unsupported platform sources
5f578a8 irqchip: gic: use CPU_PM only when registering
d45c1ea platform: tegra: remove nvdump support for t12x/t13x
9b0b6de Revert "Revert "android: fiq_debugger: FIQ glue for ARM64 CPUs""
d5351a1 Revert "Revert "drivers: platform: enumerate fiq_debugger device""
27af58f Revert "Revert "platform: tegra: clean up fiq_enable() implementation""
688e514 platform: tegra: Remove support for Tegra clock framework
c15896d tegra: denver-knobs: Remove nvmstat_pg stats
019f065 platform: tegra: Remove support for TEGRA_13x_SOC
207db5f drivers: platform: iommu: add linear mapping on lut
1bc0602 denver: hardwood: use device tree to find IRQ number
b11f182 isomgr: Apply ISO client's BW limit
132843c platform: tegra: Remove the API tegra_gpio_to_wake()
8a2892d platform: tegra: deprecate APIs to change waketable runtime
e2f5924 prod: Add support for masked write in partially prod config
e94ac08 platform: tegra: powergate: Remove support for TEGRA_12x_SOC
6b4c4cb platform: tegra: mc: Remove support for TEGRA_12x_SOC
39977fb platform: tegra: Remove drivers for TEGRA_12x_SOC
e17670c drivers: platform: fix denver_mca driver
61c6f5e tegra: powergate: add clocks for XUSBB
bb10919 tegra: powergate: cleanup clock and reset handling
73b944e tegra: powergate: correct xusbb partition reset ID
b3dc4f4 iommu: arm-smmu: add linear mapping support
6c9bcbb platform: tegra: support disabling CONFIG_PM
98d04a5 platform: tegra: remove legacy speedo files
c6b9acf platform: tegra: APIs to set prod based on name/index/offset/mask
a04d242 platform: tegra: mc: fix build error
1d8c939 platform: tegra: Remove miscellaneous platform specific drivers
daab9eb tegra: powergate: shorten some con ids
229a25f platform: tegra: remove tegra common support
3e71442 bwmgr: Remove checks to limit emc_freq
9f3f176 tegra: powergate: use new reset API and use ioremap
11cd9c8 platform: tegra: Disable T210 TCF cpufreq driver
224ecab platform: tegra: Remove the common board support
1813dd1 ivc: fix missing peer notification
a56ac67 ivc: fix incorrect counter reset
844c7a1 ivc: Remove nframes power of two check
5a3ec3a bwmgr: Add more information to clients info sysfs
522777c platform: tegra: remove raydium touch support
251660a platform: tegra: remove unneccessary panel file
0915b9a bwmgr: Add API to get core emc rate
c66f6bc platform: tegra: Add pmqos emc floor handling
a7b51df Add CONFIG_TEGRA_BOND_OUT and disable by default
29cd4ee Stubbed out tegra_periph_reset
3c07fd4 iommu: smmu: Changed the chip ids for 4.4 naming
3d780a1 platform: nvadsp: fix MAXCLKLATENCY offset
e470cdd platform: tegra: bwmgr: add a disable knob
1d8e851 tegra: denver-knobs: Use correct CPU id for bgallowed
db9711f bwmgr: Add errno to debug print
96ed52e drivers: usb: pmc: rebase pmc driver for kernel-4.4
6510703 tegra: denver-knobs: add tracer_control support
3a285a9 tegra: actmon: missing sysfs_attr_init()
0c83659 tegra: actmon: add sysfs node for emc load
2477286 platform: tegra: pmc: add usb2 sleepwalk APIs
8bcf839 pinctrl: add Tegra21x PADCTL/UPHY driver
acaa486 platform: nvadsp: make version func static
6028232 Revert "platform: tegra: clean up fiq_enable() implementation"
cc80660 Revert "drivers: platform: enumerate fiq_debugger device"
ab2cc4c Revert "android: fiq_debugger: FIQ glue for ARM64 CPUs"
38ff9fd drivers: platform: enumerate fiq_debugger device
1dd509c platform: tegra: clean up fiq_enable() implementation
0a87d11 android: fiq_debugger: FIQ glue for ARM64 CPUs
74ec787 platform: nvadsp: add adsp os version
9bd6a7f platform: tegra: Remove use of is_partition_clk_disabled
a56b821 drivers: class 'tegra-firmwares'
c859a13 Kconfig: Rename included Kconfigs
804f706 platform: tegra: add kfuse sensing for hdcp 1.x
9b3510f drivers: platform: tegra: only compile tegra_irq_to_wake for Tegra186
fb5394c drivers: platform: tegra: switch powergating driver to CCF
66d0faf tegra: mc: declare tegra_get_chip_id and use in mc
eb90d56 drivers: platform: Move DPD IO control into pmc driver
3816cef arm64: enable CCF
a196e10 soc/tegra: Add TEGRA148 and TEGRA186 chip id
8354256 drivers: platform: tegra: switch powergate driver to tegra_get_chip_id()
473ce73 platform: tegra: mc: adapt la driver to upstream tegra_get_chip_id()
0f2668b Kconfig: replace source with trysource for external projects
266255a platform: tegra: Add support to find prod setting
ac65ac1 platfor: tegra: prod: Do not use kmemleak_not_leak() for managed allocation
96358ea platform: tegra: prod: use devm_ for allocation
53933ed platform: tegra: Add sysfs entry for suspend/resume time
bfef5bc drivers: platform: tegra: add tegra_wake_to_gpio() interface
4409ca6 tegra: central_actmon: fix DEBUG_FS=n build
80aa543 platform:tegra:bwmgr: fix build issue.
f97d139 tegra: denver-knobs: fix build issue.
bcfc89c platform: tegra: prod: Add managed version of tegra_prod_get_from_node
85288f1 platform: tegra: prod: Add support for nested prod nodes.
0be37d5 platform: tegra: prod: Get rid of tegra_prod_release()
753f71d platform: tegra: prod: Remove unused APIs from public header
5b92965 platform: tegra: pmc: Use devm for tegra_prod allocation
21af9cb platform: tegra: prod: Add APIs to managed allocation of prod_list
2d9312b platform: tegra: move definition of tegra_prod_list structure to private
0d1efe1 platform: tegra: prod: Use for_each_available_child_of_node()
3014a93 tegra:nvadsp:fix issue with CONFIG_DEBUG_FS=n
edd37fd platform: tegra: prod: Use proper variable name
168ec7b platform: tegra: prod: Fix parsing of prod setting for package/board
bc8cd66 platform: tegra: prod: Make allocated memory as kmemleak_not_leak()
380f89f PM/Domains: Remove use of 'need_save' and 'need_restore'
fdf13ea platform: nvadsp: change perms of debugfs files
bc34a73 nvadsp: console: keep track of app context
62d0040 nvadsp: console: fix app name handling
f113a66 platform: nvadsp: export adsp dump sys
e0e907b platform: tegra: nvadsp: fix setting boot freqs
c7fb6ee Revert "drivers: platform: tegra: add proper config check"
c5b1e8b platform:tegra:bwmgr: Fix bwmgr floor aggregation
584b06e platform: tegra: bwmgr: Add Security Engine Client
f63d36d tegra: gpo: move gpio-tegra
8171ecb security: Use a common secure monitor interface
1359955 platform: nvadsp: fix unused function build issue
aa55e67 platform: tegra: Remove unused functions
6f2d8d8 platform: tegra: Change value of need_save to 'true'
0c28fab Merge "Merge agic changes" into dev-kernel
0174199 platform: nvadsp: Correct AGIC irqs state dumps
0d7fec4 irqchip: Move AGIC Kconfig from nvadsp
b7ce47f kernel: change kernel path
7627eeb platform: tegra: mc: fix coverity defects
d4afd62 platform: tegra: remove platform emc driver for Tegra210
93e504f platform: tegra: mc: include module.h
4a3d8fa platform: tegra: add thermal throttling config
b99e994 platform: tegra: move tegra_fiq_debugger from mach-tegra
b89bbf4b tegra: t21x: restore irqs-t21x.h file
3ec5fa9 arm64: Copy over more T210 files
0c3285d platform: tegra: mc: enable latency allowance code compile
80b090f platform: tegra: mc: add T18x PTSA vars
345b7ee tegra: mc: add set LA funcion pointers
26c3314 platform: tegra: Add support for mask with 1s
62e11eb platform: tegra: mc: Don't compile latency_allowance for k4.4
dc9cafc platform: tegra: Add protection to code
55dabeb drivers: platform: tegra: add proper config check
99a65ef platform: tegra: tegra_usb_pmc depends on T210
eae2a6d tegra: denver-knobs: fix seq_printf return value
74467a6 TEMP: drivers: Kconfig: Use source instead of trysource
000acb1 platform: tegra: add missing headers and build fixes
e228595 kconfig: add trysource to kernel-t18x
94daaaa drivers: platform: tegra: Initialize drivers/platform/tegra inside kernel-next
c5c90b8 drivers: platform: tegra: Add miscellaneous platform specific drivers
3faa2fe drivers: platform: tegra: PTM driver for t12x and t21x
8953022 drivers: platform: tegra: Add kfuse driver
19a844c drivers: platform: tegra: Tegra USB Padctrl driver
4596579 drivers: platform: tegra: Add nvdumper source for platforms
a03e4b0 drivers: platform: tegra: Add wakeup related source
363b7ee drivers: platform: tegra: central_actmon: Add common and support for T21x
9fe72d5 drivers: platform: tegra: mc: Add platform specific MC source
6c2b078 drivers: platform: tegra: Adding denver specific drivers
976c8b9 drivers: platform: tegra: Add bootloader drivers
a97be5b drivers: platform: tegra: nvadsp: Add platform specific nvadsp drivers
b29af75 drivers: platform: tegra: Add powergating drivers
899dddd platform: tegra: Add Tegra Clocks drivers for various platforms
Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com>
Change-Id: Ic232ac71a09fe5176247692630db5bc6107573fa
Signed-off-by: Nitin Kumbhar <nkumbhar@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1537316
Reviewed-by: svccoveritychecker <svccoveritychecker@nvidia.com>
GVS: Gerrit_Virtual_Submit
423 lines
10 KiB
C
423 lines
10 KiB
C
/*
|
|
* Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms and conditions of the GNU General Public License,
|
|
* version 2, as published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope 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/fs.h>
|
|
#include <asm/segment.h>
|
|
#include <asm/uaccess.h>
|
|
|
|
#include <linux/slab.h>
|
|
#include <linux/workqueue.h>
|
|
|
|
#include <linux/tegra_nvadsp.h>
|
|
|
|
#include "adspff.h"
|
|
|
|
struct file_struct {
|
|
struct file *fp;
|
|
unsigned long long wr_offset;
|
|
unsigned long long rd_offset;
|
|
};
|
|
|
|
|
|
static spinlock_t adspff_lock;
|
|
|
|
/******************************************************************************
|
|
* Kernel file functions
|
|
******************************************************************************/
|
|
|
|
struct file *file_open(const char *path, int flags, int rights)
|
|
{
|
|
struct file *filp = NULL;
|
|
mm_segment_t oldfs;
|
|
int err = 0;
|
|
|
|
oldfs = get_fs();
|
|
set_fs(get_ds());
|
|
filp = filp_open(path, flags, rights);
|
|
set_fs(oldfs);
|
|
if (IS_ERR(filp)) {
|
|
err = PTR_ERR(filp);
|
|
return NULL;
|
|
}
|
|
return filp;
|
|
}
|
|
|
|
void file_close(struct file *file)
|
|
{
|
|
filp_close(file, NULL);
|
|
}
|
|
|
|
int file_write(struct file *file, unsigned long long *offset,
|
|
unsigned char *data, unsigned int size)
|
|
{
|
|
mm_segment_t oldfs;
|
|
int ret = 0;
|
|
|
|
oldfs = get_fs();
|
|
set_fs(get_ds());
|
|
|
|
ret = vfs_write(file, data, size, offset);
|
|
|
|
set_fs(oldfs);
|
|
return ret;
|
|
}
|
|
|
|
uint32_t file_read(struct file *file, unsigned long long *offset,
|
|
unsigned char *data, unsigned int size)
|
|
{
|
|
mm_segment_t oldfs;
|
|
uint32_t ret = 0;
|
|
|
|
oldfs = get_fs();
|
|
set_fs(get_ds());
|
|
|
|
ret = vfs_read(file, data, size, offset);
|
|
|
|
set_fs(oldfs);
|
|
|
|
return ret;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* ADSPFF file functions
|
|
******************************************************************************/
|
|
|
|
static struct adspff_shared_state_t *adspff;
|
|
static struct nvadsp_mbox rx_mbox;
|
|
|
|
/** *
|
|
* w - open for writing (file need not exist) *
|
|
* a - open for appending (file need not exist) *
|
|
* r+ - open for reading and writing, start at beginning *
|
|
* w+ - open for reading and writing (overwrite file) *
|
|
* a+ - open for reading and writing (append if file exists) */
|
|
|
|
void set_flags(union adspff_message_t *m, int *flags)
|
|
{
|
|
if (0 == strcmp(m->msg.payload.fopen_msg.modes, "r+"))
|
|
*flags = O_RDWR;
|
|
|
|
else if (0 == strcmp(m->msg.payload.fopen_msg.modes, "w+"))
|
|
*flags = O_CREAT | O_RDWR | O_TRUNC;
|
|
|
|
else if (0 == strcmp(m->msg.payload.fopen_msg.modes, "a+"))
|
|
*flags = O_APPEND | O_RDWR;
|
|
|
|
else if (0 == strcmp(m->msg.payload.fopen_msg.modes, "r"))
|
|
*flags = O_RDONLY;
|
|
|
|
else if (0 == strcmp(m->msg.payload.fopen_msg.modes, "w"))
|
|
*flags = O_CREAT | O_WRONLY | O_TRUNC;
|
|
|
|
else if (0 == strcmp(m->msg.payload.fopen_msg.modes, "a"))
|
|
*flags = O_CREAT | O_APPEND | O_WRONLY;
|
|
|
|
else
|
|
*flags = O_CREAT | O_RDWR;
|
|
}
|
|
|
|
void adspff_fopen(struct work_struct *work)
|
|
{
|
|
union adspff_message_t *message;
|
|
union adspff_message_t *msg_recv;
|
|
int flags = 0, ret = 0;
|
|
|
|
struct file_struct *file = kzalloc(sizeof(struct file_struct), GFP_KERNEL);
|
|
|
|
message = kzalloc(sizeof(union adspff_message_t), GFP_KERNEL);
|
|
msg_recv = kzalloc(sizeof(union adspff_message_t), GFP_KERNEL);
|
|
|
|
message->msgq_msg.size = MSGQ_MSG_SIZE(struct fopen_msg_t);
|
|
|
|
ret = msgq_dequeue_message(&adspff->msgq_send.msgq,
|
|
(msgq_message_t *)message);
|
|
|
|
if (ret < 0) {
|
|
pr_err("fopen Dequeue failed %d.", ret);
|
|
kfree(message);
|
|
kfree(msg_recv);
|
|
return;
|
|
}
|
|
|
|
set_flags(message, &flags);
|
|
|
|
file->fp = file_open(
|
|
(const char *)message->msg.payload.fopen_msg.fname,
|
|
flags, S_IRWXU|S_IRWXG|S_IRWXO);
|
|
|
|
file->wr_offset = 0;
|
|
file->rd_offset = 0;
|
|
|
|
msg_recv->msgq_msg.size = MSGQ_MSG_SIZE(struct fopen_recv_msg_t);
|
|
msg_recv->msg.payload.fopen_recv_msg.file = (int64_t)file;
|
|
|
|
ret = msgq_queue_message(&adspff->msgq_recv.msgq,
|
|
(msgq_message_t *)msg_recv);
|
|
if (ret < 0) {
|
|
pr_err("fopen Enqueue failed %d.", ret);
|
|
kfree(message);
|
|
kfree(msg_recv);
|
|
return;
|
|
}
|
|
|
|
nvadsp_mbox_send(&rx_mbox, adspff_cmd_fopen_recv,
|
|
NVADSP_MBOX_SMSG, 0, 0);
|
|
kfree(message);
|
|
kfree(msg_recv);
|
|
}
|
|
|
|
void adspff_fclose(struct work_struct *work)
|
|
{
|
|
union adspff_message_t *message;
|
|
struct file_struct *file = NULL;
|
|
int32_t ret = 0;
|
|
|
|
message = kzalloc(sizeof(union adspff_message_t), GFP_KERNEL);
|
|
|
|
message->msgq_msg.size = MSGQ_MSG_SIZE(struct fclose_msg_t);
|
|
|
|
ret = msgq_dequeue_message(&adspff->msgq_send.msgq,
|
|
(msgq_message_t *)message);
|
|
|
|
if (ret < 0) {
|
|
pr_err("fclose Dequeue failed %d.", ret);
|
|
kfree(message);
|
|
return;
|
|
}
|
|
file = (struct file_struct *)message->msg.payload.fclose_msg.file;
|
|
if (file) {
|
|
file_close(file->fp);
|
|
kfree(file);
|
|
file = NULL;
|
|
}
|
|
kfree(message);
|
|
}
|
|
|
|
void adspff_fwrite(struct work_struct *work)
|
|
{
|
|
union adspff_message_t message;
|
|
union adspff_message_t *msg_recv;
|
|
struct file_struct *file = NULL;
|
|
int ret = 0;
|
|
uint32_t size = 0;
|
|
uint32_t bytes_to_write = 0;
|
|
uint32_t bytes_written = 0;
|
|
|
|
msg_recv = kzalloc(sizeof(union adspff_message_t), GFP_KERNEL);
|
|
msg_recv->msgq_msg.size = MSGQ_MSG_SIZE(struct ack_msg_t);
|
|
|
|
message.msgq_msg.size = MSGQ_MSG_SIZE(struct fwrite_msg_t);
|
|
ret = msgq_dequeue_message(&adspff->msgq_send.msgq,
|
|
(msgq_message_t *)&message);
|
|
if (ret < 0) {
|
|
pr_err("fwrite Dequeue failed %d.", ret);
|
|
return;
|
|
}
|
|
|
|
file = (struct file_struct *)message.msg.payload.fwrite_msg.file;
|
|
size = message.msg.payload.fwrite_msg.size;
|
|
|
|
bytes_to_write = ((adspff->write_buf.read_index + size) < ADSPFF_SHARED_BUFFER_SIZE) ?
|
|
size : (ADSPFF_SHARED_BUFFER_SIZE - adspff->write_buf.read_index);
|
|
ret = file_write(file->fp, &file->wr_offset,
|
|
adspff->write_buf.data + adspff->write_buf.read_index, bytes_to_write);
|
|
bytes_written += ret;
|
|
|
|
if ((size - bytes_to_write) > 0) {
|
|
ret = file_write(file->fp, &file->wr_offset,
|
|
adspff->write_buf.data, size - bytes_to_write);
|
|
bytes_written += ret;
|
|
}
|
|
|
|
adspff->write_buf.read_index =
|
|
(adspff->write_buf.read_index + size) % ADSPFF_SHARED_BUFFER_SIZE;
|
|
|
|
/* send ack */
|
|
msg_recv->msg.payload.ack_msg.size = bytes_written;
|
|
ret = msgq_queue_message(&adspff->msgq_recv.msgq,
|
|
(msgq_message_t *)msg_recv);
|
|
|
|
if (ret < 0) {
|
|
pr_err("fread Enqueue failed %d.", ret);
|
|
kfree(msg_recv);
|
|
return;
|
|
}
|
|
nvadsp_mbox_send(&rx_mbox, adspff_cmd_ack,
|
|
NVADSP_MBOX_SMSG, 0, 0);
|
|
kfree(msg_recv);
|
|
}
|
|
|
|
void adspff_fread(struct work_struct *work)
|
|
{
|
|
union adspff_message_t *message;
|
|
union adspff_message_t *msg_recv;
|
|
struct file_struct *file = NULL;
|
|
uint32_t bytes_free;
|
|
uint32_t wi = adspff->read_buf.write_index;
|
|
uint32_t ri = adspff->read_buf.read_index;
|
|
uint8_t can_wrap = 0;
|
|
uint32_t size = 0, size_read = 0;
|
|
int32_t ret = 0;
|
|
|
|
if (ri <= wi) {
|
|
bytes_free = ADSPFF_SHARED_BUFFER_SIZE - wi + ri - 1;
|
|
can_wrap = 1;
|
|
} else {
|
|
bytes_free = ri - wi - 1;
|
|
can_wrap = 0;
|
|
}
|
|
message = kzalloc(sizeof(union adspff_message_t), GFP_KERNEL);
|
|
msg_recv = kzalloc(sizeof(union adspff_message_t), GFP_KERNEL);
|
|
|
|
msg_recv->msgq_msg.size = MSGQ_MSG_SIZE(struct ack_msg_t);
|
|
message->msgq_msg.size = MSGQ_MSG_SIZE(struct fread_msg_t);
|
|
|
|
ret = msgq_dequeue_message(&adspff->msgq_send.msgq,
|
|
(msgq_message_t *)message);
|
|
|
|
if (ret < 0) {
|
|
pr_err("fread Dequeue failed %d.", ret);
|
|
kfree(message);
|
|
kfree(msg_recv);
|
|
return;
|
|
}
|
|
|
|
file = (struct file_struct *)message->msg.payload.fread_msg.file;
|
|
size = message->msg.payload.fread_msg.size;
|
|
if (bytes_free < size) {
|
|
size_read = 0;
|
|
goto send_ack;
|
|
}
|
|
|
|
if (can_wrap) {
|
|
uint32_t bytes_to_read = (size < (ADSPFF_SHARED_BUFFER_SIZE - wi)) ?
|
|
size : (ADSPFF_SHARED_BUFFER_SIZE - wi);
|
|
ret = file_read(file->fp, &file->rd_offset,
|
|
adspff->read_buf.data + wi, bytes_to_read);
|
|
size_read = ret;
|
|
if (ret < bytes_to_read)
|
|
goto send_ack;
|
|
if ((size - bytes_to_read) > 0) {
|
|
ret = file_read(file->fp, &file->rd_offset,
|
|
adspff->read_buf.data, size - bytes_to_read);
|
|
size_read += ret;
|
|
goto send_ack;
|
|
}
|
|
} else {
|
|
ret = file_read(file->fp, &file->rd_offset,
|
|
adspff->read_buf.data + wi, size);
|
|
size_read = ret;
|
|
goto send_ack;
|
|
}
|
|
send_ack:
|
|
msg_recv->msg.payload.ack_msg.size = size_read;
|
|
ret = msgq_queue_message(&adspff->msgq_recv.msgq,
|
|
(msgq_message_t *)msg_recv);
|
|
|
|
if (ret < 0) {
|
|
pr_err("fread Enqueue failed %d.", ret);
|
|
kfree(message);
|
|
kfree(msg_recv);
|
|
return;
|
|
}
|
|
adspff->read_buf.write_index =
|
|
(adspff->read_buf.write_index + size_read) % ADSPFF_SHARED_BUFFER_SIZE;
|
|
|
|
nvadsp_mbox_send(&rx_mbox, adspff_cmd_ack,
|
|
NVADSP_MBOX_SMSG, 0, 0);
|
|
kfree(message);
|
|
kfree(msg_recv);
|
|
}
|
|
|
|
static struct workqueue_struct *adspff_wq;
|
|
DECLARE_WORK(fopen_work, adspff_fopen);
|
|
DECLARE_WORK(fwrite_work, adspff_fwrite);
|
|
DECLARE_WORK(fread_work, adspff_fread);
|
|
DECLARE_WORK(fclose_work, adspff_fclose);
|
|
|
|
/******************************************************************************
|
|
* ADSP mailbox message handler
|
|
******************************************************************************/
|
|
|
|
|
|
static int adspff_msg_handler(uint32_t msg, void *data)
|
|
{
|
|
unsigned long flags;
|
|
|
|
spin_lock_irqsave(&adspff_lock, flags);
|
|
switch (msg) {
|
|
case adspff_cmd_fopen: {
|
|
queue_work(adspff_wq, &fopen_work);
|
|
}
|
|
break;
|
|
case adspff_cmd_fclose: {
|
|
queue_work(adspff_wq, &fclose_work);
|
|
}
|
|
break;
|
|
case adspff_cmd_fwrite: {
|
|
queue_work(adspff_wq, &fwrite_work);
|
|
}
|
|
break;
|
|
case adspff_cmd_fread: {
|
|
queue_work(adspff_wq, &fread_work);
|
|
}
|
|
break;
|
|
default:
|
|
pr_err("Unsupported mbox msg %d.\n", msg);
|
|
}
|
|
spin_unlock_irqrestore(&adspff_lock, flags);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int adspff_init(void)
|
|
{
|
|
int ret = 0;
|
|
nvadsp_app_handle_t handle;
|
|
nvadsp_app_info_t *app_info;
|
|
|
|
handle = nvadsp_app_load("adspff", "adspff.elf");
|
|
if (!handle)
|
|
return -1;
|
|
|
|
app_info = nvadsp_app_init(handle, NULL);
|
|
if (!app_info) {
|
|
pr_err("unable to init app adspff\n");
|
|
return -1;
|
|
}
|
|
|
|
adspff = ADSPFF_SHARED_STATE(app_info->mem.shared);
|
|
|
|
ret = nvadsp_mbox_open(&rx_mbox, &adspff->mbox_id,
|
|
"adspff", adspff_msg_handler, NULL);
|
|
|
|
if (ret < 0) {
|
|
pr_err("Failed to open mbox %d", adspff->mbox_id);
|
|
return -1;
|
|
}
|
|
|
|
if (adspff_wq == NULL)
|
|
adspff_wq = create_singlethread_workqueue("adspff_wq");
|
|
|
|
spin_lock_init(&adspff_lock);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void adspff_exit(void)
|
|
{
|
|
nvadsp_mbox_close(&rx_mbox);
|
|
flush_workqueue(adspff_wq);
|
|
destroy_workqueue(adspff_wq);
|
|
}
|