Commit f469cf96 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'char-misc-6.10-final' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc

Pull char / misc driver fixes from Greg KH:
 "Here are some small remaining driver fixes for 6.10-final that have
  all been in linux-next for a while and resolve reported issues.
  Included in here are:

   - mei driver fixes (and a spelling fix at the end just to be clean)

   - iio driver fixes for reported problems

   - fastrpc bugfixes

   - nvmem small fixes"

* tag 'char-misc-6.10-final' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc:
  mei: vsc: Fix spelling error
  mei: vsc: Enhance SPI transfer of IVSC ROM
  mei: vsc: Utilize the appropriate byte order swap function
  mei: vsc: Prevent timeout error with added delay post-firmware download
  mei: vsc: Enhance IVSC chipset stability during warm reboot
  nvmem: core: limit cell sysfs permissions to main attribute ones
  nvmem: core: only change name to fram for current attribute
  nvmem: meson-efuse: Fix return value of nvmem callbacks
  nvmem: rmem: Fix return value of rmem_read()
  misc: microchip: pci1xxxx: Fix return value of nvmem callbacks
  hpet: Support 32-bit userspace
  misc: fastrpc: Restrict untrusted app to attach to privileged PD
  misc: fastrpc: Fix ownership reassignment of remote heap
  misc: fastrpc: Fix memory leak in audio daemon attach operation
  misc: fastrpc: Avoid updating PD type for capability request
  misc: fastrpc: Copy the complete capability structure to user
  misc: fastrpc: Fix DSP capabilities request
  iio: light: apds9306: Fix error handing
  iio: trigger: Fix condition for own trigger
parents 1cb67bcc 389637d4
...@@ -269,8 +269,13 @@ hpet_read(struct file *file, char __user *buf, size_t count, loff_t * ppos) ...@@ -269,8 +269,13 @@ hpet_read(struct file *file, char __user *buf, size_t count, loff_t * ppos)
if (!devp->hd_ireqfreq) if (!devp->hd_ireqfreq)
return -EIO; return -EIO;
if (count < sizeof(unsigned long)) if (in_compat_syscall()) {
return -EINVAL; if (count < sizeof(compat_ulong_t))
return -EINVAL;
} else {
if (count < sizeof(unsigned long))
return -EINVAL;
}
add_wait_queue(&devp->hd_waitqueue, &wait); add_wait_queue(&devp->hd_waitqueue, &wait);
...@@ -294,9 +299,16 @@ hpet_read(struct file *file, char __user *buf, size_t count, loff_t * ppos) ...@@ -294,9 +299,16 @@ hpet_read(struct file *file, char __user *buf, size_t count, loff_t * ppos)
schedule(); schedule();
} }
retval = put_user(data, (unsigned long __user *)buf); if (in_compat_syscall()) {
if (!retval) retval = put_user(data, (compat_ulong_t __user *)buf);
retval = sizeof(unsigned long); if (!retval)
retval = sizeof(compat_ulong_t);
} else {
retval = put_user(data, (unsigned long __user *)buf);
if (!retval)
retval = sizeof(unsigned long);
}
out: out:
__set_current_state(TASK_RUNNING); __set_current_state(TASK_RUNNING);
remove_wait_queue(&devp->hd_waitqueue, &wait); remove_wait_queue(&devp->hd_waitqueue, &wait);
...@@ -651,12 +663,24 @@ struct compat_hpet_info { ...@@ -651,12 +663,24 @@ struct compat_hpet_info {
unsigned short hi_timer; unsigned short hi_timer;
}; };
/* 32-bit types would lead to different command codes which should be
* translated into 64-bit ones before passed to hpet_ioctl_common
*/
#define COMPAT_HPET_INFO _IOR('h', 0x03, struct compat_hpet_info)
#define COMPAT_HPET_IRQFREQ _IOW('h', 0x6, compat_ulong_t)
static long static long
hpet_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) hpet_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{ {
struct hpet_info info; struct hpet_info info;
int err; int err;
if (cmd == COMPAT_HPET_INFO)
cmd = HPET_INFO;
if (cmd == COMPAT_HPET_IRQFREQ)
cmd = HPET_IRQFREQ;
mutex_lock(&hpet_mutex); mutex_lock(&hpet_mutex);
err = hpet_ioctl_common(file->private_data, cmd, arg, &info); err = hpet_ioctl_common(file->private_data, cmd, arg, &info);
mutex_unlock(&hpet_mutex); mutex_unlock(&hpet_mutex);
......
...@@ -315,7 +315,7 @@ int iio_trigger_attach_poll_func(struct iio_trigger *trig, ...@@ -315,7 +315,7 @@ int iio_trigger_attach_poll_func(struct iio_trigger *trig,
* this is the case if the IIO device and the trigger device share the * this is the case if the IIO device and the trigger device share the
* same parent device. * same parent device.
*/ */
if (iio_validate_own_trigger(pf->indio_dev, trig)) if (!iio_validate_own_trigger(pf->indio_dev, trig))
trig->attached_own_device = true; trig->attached_own_device = true;
return ret; return ret;
......
...@@ -583,8 +583,8 @@ static int apds9306_intg_time_set(struct apds9306_data *data, int val2) ...@@ -583,8 +583,8 @@ static int apds9306_intg_time_set(struct apds9306_data *data, int val2)
return ret; return ret;
intg_old = iio_gts_find_int_time_by_sel(&data->gts, intg_time_idx); intg_old = iio_gts_find_int_time_by_sel(&data->gts, intg_time_idx);
if (ret < 0) if (intg_old < 0)
return ret; return intg_old;
if (intg_old == val2) if (intg_old == val2)
return 0; return 0;
......
...@@ -1238,6 +1238,7 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl, ...@@ -1238,6 +1238,7 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
struct fastrpc_phy_page pages[1]; struct fastrpc_phy_page pages[1];
char *name; char *name;
int err; int err;
bool scm_done = false;
struct { struct {
int pgid; int pgid;
u32 namelen; u32 namelen;
...@@ -1289,6 +1290,7 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl, ...@@ -1289,6 +1290,7 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
fl->cctx->remote_heap->phys, fl->cctx->remote_heap->size, err); fl->cctx->remote_heap->phys, fl->cctx->remote_heap->size, err);
goto err_map; goto err_map;
} }
scm_done = true;
} }
} }
...@@ -1320,10 +1322,11 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl, ...@@ -1320,10 +1322,11 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
goto err_invoke; goto err_invoke;
kfree(args); kfree(args);
kfree(name);
return 0; return 0;
err_invoke: err_invoke:
if (fl->cctx->vmcount) { if (fl->cctx->vmcount && scm_done) {
u64 src_perms = 0; u64 src_perms = 0;
struct qcom_scm_vmperm dst_perms; struct qcom_scm_vmperm dst_perms;
u32 i; u32 i;
...@@ -1693,16 +1696,20 @@ static int fastrpc_get_info_from_dsp(struct fastrpc_user *fl, uint32_t *dsp_attr ...@@ -1693,16 +1696,20 @@ static int fastrpc_get_info_from_dsp(struct fastrpc_user *fl, uint32_t *dsp_attr
{ {
struct fastrpc_invoke_args args[2] = { 0 }; struct fastrpc_invoke_args args[2] = { 0 };
/* Capability filled in userspace */ /*
* Capability filled in userspace. This carries the information
* about the remoteproc support which is fetched from the remoteproc
* sysfs node by userspace.
*/
dsp_attr_buf[0] = 0; dsp_attr_buf[0] = 0;
dsp_attr_buf_len -= 1;
args[0].ptr = (u64)(uintptr_t)&dsp_attr_buf_len; args[0].ptr = (u64)(uintptr_t)&dsp_attr_buf_len;
args[0].length = sizeof(dsp_attr_buf_len); args[0].length = sizeof(dsp_attr_buf_len);
args[0].fd = -1; args[0].fd = -1;
args[1].ptr = (u64)(uintptr_t)&dsp_attr_buf[1]; args[1].ptr = (u64)(uintptr_t)&dsp_attr_buf[1];
args[1].length = dsp_attr_buf_len; args[1].length = dsp_attr_buf_len * sizeof(u32);
args[1].fd = -1; args[1].fd = -1;
fl->pd = USER_PD;
return fastrpc_internal_invoke(fl, true, FASTRPC_DSP_UTILITIES_HANDLE, return fastrpc_internal_invoke(fl, true, FASTRPC_DSP_UTILITIES_HANDLE,
FASTRPC_SCALARS(0, 1, 1), args); FASTRPC_SCALARS(0, 1, 1), args);
...@@ -1730,7 +1737,7 @@ static int fastrpc_get_info_from_kernel(struct fastrpc_ioctl_capability *cap, ...@@ -1730,7 +1737,7 @@ static int fastrpc_get_info_from_kernel(struct fastrpc_ioctl_capability *cap,
if (!dsp_attributes) if (!dsp_attributes)
return -ENOMEM; return -ENOMEM;
err = fastrpc_get_info_from_dsp(fl, dsp_attributes, FASTRPC_MAX_DSP_ATTRIBUTES_LEN); err = fastrpc_get_info_from_dsp(fl, dsp_attributes, FASTRPC_MAX_DSP_ATTRIBUTES);
if (err == DSP_UNSUPPORTED_API) { if (err == DSP_UNSUPPORTED_API) {
dev_info(&cctx->rpdev->dev, dev_info(&cctx->rpdev->dev,
"Warning: DSP capabilities not supported on domain: %d\n", domain); "Warning: DSP capabilities not supported on domain: %d\n", domain);
...@@ -1783,7 +1790,7 @@ static int fastrpc_get_dsp_info(struct fastrpc_user *fl, char __user *argp) ...@@ -1783,7 +1790,7 @@ static int fastrpc_get_dsp_info(struct fastrpc_user *fl, char __user *argp)
if (err) if (err)
return err; return err;
if (copy_to_user(argp, &cap.capability, sizeof(cap.capability))) if (copy_to_user(argp, &cap, sizeof(cap)))
return -EFAULT; return -EFAULT;
return 0; return 0;
...@@ -2080,6 +2087,16 @@ static int fastrpc_req_mem_map(struct fastrpc_user *fl, char __user *argp) ...@@ -2080,6 +2087,16 @@ static int fastrpc_req_mem_map(struct fastrpc_user *fl, char __user *argp)
return err; return err;
} }
static int is_attach_rejected(struct fastrpc_user *fl)
{
/* Check if the device node is non-secure */
if (!fl->is_secure_dev) {
dev_dbg(&fl->cctx->rpdev->dev, "untrusted app trying to attach to privileged DSP PD\n");
return -EACCES;
}
return 0;
}
static long fastrpc_device_ioctl(struct file *file, unsigned int cmd, static long fastrpc_device_ioctl(struct file *file, unsigned int cmd,
unsigned long arg) unsigned long arg)
{ {
...@@ -2092,13 +2109,19 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int cmd, ...@@ -2092,13 +2109,19 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int cmd,
err = fastrpc_invoke(fl, argp); err = fastrpc_invoke(fl, argp);
break; break;
case FASTRPC_IOCTL_INIT_ATTACH: case FASTRPC_IOCTL_INIT_ATTACH:
err = fastrpc_init_attach(fl, ROOT_PD); err = is_attach_rejected(fl);
if (!err)
err = fastrpc_init_attach(fl, ROOT_PD);
break; break;
case FASTRPC_IOCTL_INIT_ATTACH_SNS: case FASTRPC_IOCTL_INIT_ATTACH_SNS:
err = fastrpc_init_attach(fl, SENSORS_PD); err = is_attach_rejected(fl);
if (!err)
err = fastrpc_init_attach(fl, SENSORS_PD);
break; break;
case FASTRPC_IOCTL_INIT_CREATE_STATIC: case FASTRPC_IOCTL_INIT_CREATE_STATIC:
err = fastrpc_init_create_static_process(fl, argp); err = is_attach_rejected(fl);
if (!err)
err = fastrpc_init_create_static_process(fl, argp);
break; break;
case FASTRPC_IOCTL_INIT_CREATE: case FASTRPC_IOCTL_INIT_CREATE:
err = fastrpc_init_create_process(fl, argp); err = fastrpc_init_create_process(fl, argp);
......
...@@ -153,7 +153,6 @@ static int pci1xxxx_eeprom_read(void *priv_t, unsigned int off, ...@@ -153,7 +153,6 @@ static int pci1xxxx_eeprom_read(void *priv_t, unsigned int off,
buf[byte] = readl(rb + MMAP_EEPROM_OFFSET(EEPROM_DATA_REG)); buf[byte] = readl(rb + MMAP_EEPROM_OFFSET(EEPROM_DATA_REG));
} }
ret = byte;
error: error:
release_sys_lock(priv); release_sys_lock(priv);
return ret; return ret;
...@@ -197,7 +196,6 @@ static int pci1xxxx_eeprom_write(void *priv_t, unsigned int off, ...@@ -197,7 +196,6 @@ static int pci1xxxx_eeprom_write(void *priv_t, unsigned int off,
goto error; goto error;
} }
} }
ret = byte;
error: error:
release_sys_lock(priv); release_sys_lock(priv);
return ret; return ret;
...@@ -258,7 +256,6 @@ static int pci1xxxx_otp_read(void *priv_t, unsigned int off, ...@@ -258,7 +256,6 @@ static int pci1xxxx_otp_read(void *priv_t, unsigned int off,
buf[byte] = readl(rb + MMAP_OTP_OFFSET(OTP_RD_DATA_OFFSET)); buf[byte] = readl(rb + MMAP_OTP_OFFSET(OTP_RD_DATA_OFFSET));
} }
ret = byte;
error: error:
release_sys_lock(priv); release_sys_lock(priv);
return ret; return ret;
...@@ -315,7 +312,6 @@ static int pci1xxxx_otp_write(void *priv_t, unsigned int off, ...@@ -315,7 +312,6 @@ static int pci1xxxx_otp_write(void *priv_t, unsigned int off,
goto error; goto error;
} }
} }
ret = byte;
error: error:
release_sys_lock(priv); release_sys_lock(priv);
return ret; return ret;
......
...@@ -28,8 +28,8 @@ ...@@ -28,8 +28,8 @@
#define MEI_VSC_MAX_MSG_SIZE 512 #define MEI_VSC_MAX_MSG_SIZE 512
#define MEI_VSC_POLL_DELAY_US (50 * USEC_PER_MSEC) #define MEI_VSC_POLL_DELAY_US (100 * USEC_PER_MSEC)
#define MEI_VSC_POLL_TIMEOUT_US (200 * USEC_PER_MSEC) #define MEI_VSC_POLL_TIMEOUT_US (400 * USEC_PER_MSEC)
#define mei_dev_to_vsc_hw(dev) ((struct mei_vsc_hw *)((dev)->hw)) #define mei_dev_to_vsc_hw(dev) ((struct mei_vsc_hw *)((dev)->hw))
......
...@@ -204,7 +204,7 @@ struct vsc_img_frag { ...@@ -204,7 +204,7 @@ struct vsc_img_frag {
/** /**
* struct vsc_fw_loader - represent vsc firmware loader * struct vsc_fw_loader - represent vsc firmware loader
* @dev: device used to request fimware * @dev: device used to request firmware
* @tp: transport layer used with the firmware loader * @tp: transport layer used with the firmware loader
* @csi: CSI image * @csi: CSI image
* @ace: ACE image * @ace: ACE image
......
...@@ -331,12 +331,12 @@ int vsc_tp_rom_xfer(struct vsc_tp *tp, const void *obuf, void *ibuf, size_t len) ...@@ -331,12 +331,12 @@ int vsc_tp_rom_xfer(struct vsc_tp *tp, const void *obuf, void *ibuf, size_t len)
return ret; return ret;
} }
ret = vsc_tp_dev_xfer(tp, tp->tx_buf, tp->rx_buf, len); ret = vsc_tp_dev_xfer(tp, tp->tx_buf, ibuf ? tp->rx_buf : NULL, len);
if (ret) if (ret)
return ret; return ret;
if (ibuf) if (ibuf)
cpu_to_be32_array(ibuf, tp->rx_buf, words); be32_to_cpu_array(ibuf, tp->rx_buf, words);
return ret; return ret;
} }
...@@ -568,6 +568,19 @@ static void vsc_tp_remove(struct spi_device *spi) ...@@ -568,6 +568,19 @@ static void vsc_tp_remove(struct spi_device *spi)
free_irq(spi->irq, tp); free_irq(spi->irq, tp);
} }
static void vsc_tp_shutdown(struct spi_device *spi)
{
struct vsc_tp *tp = spi_get_drvdata(spi);
platform_device_unregister(tp->pdev);
mutex_destroy(&tp->mutex);
vsc_tp_reset(tp);
free_irq(spi->irq, tp);
}
static const struct acpi_device_id vsc_tp_acpi_ids[] = { static const struct acpi_device_id vsc_tp_acpi_ids[] = {
{ "INTC1009" }, /* Raptor Lake */ { "INTC1009" }, /* Raptor Lake */
{ "INTC1058" }, /* Tiger Lake */ { "INTC1058" }, /* Tiger Lake */
...@@ -580,6 +593,7 @@ MODULE_DEVICE_TABLE(acpi, vsc_tp_acpi_ids); ...@@ -580,6 +593,7 @@ MODULE_DEVICE_TABLE(acpi, vsc_tp_acpi_ids);
static struct spi_driver vsc_tp_driver = { static struct spi_driver vsc_tp_driver = {
.probe = vsc_tp_probe, .probe = vsc_tp_probe,
.remove = vsc_tp_remove, .remove = vsc_tp_remove,
.shutdown = vsc_tp_shutdown,
.driver = { .driver = {
.name = "vsc-tp", .name = "vsc-tp",
.acpi_match_table = vsc_tp_acpi_ids, .acpi_match_table = vsc_tp_acpi_ids,
......
...@@ -396,10 +396,9 @@ static int nvmem_sysfs_setup_compat(struct nvmem_device *nvmem, ...@@ -396,10 +396,9 @@ static int nvmem_sysfs_setup_compat(struct nvmem_device *nvmem,
if (!config->base_dev) if (!config->base_dev)
return -EINVAL; return -EINVAL;
if (config->type == NVMEM_TYPE_FRAM)
bin_attr_nvmem_eeprom_compat.attr.name = "fram";
nvmem->eeprom = bin_attr_nvmem_eeprom_compat; nvmem->eeprom = bin_attr_nvmem_eeprom_compat;
if (config->type == NVMEM_TYPE_FRAM)
nvmem->eeprom.attr.name = "fram";
nvmem->eeprom.attr.mode = nvmem_bin_attr_get_umode(nvmem); nvmem->eeprom.attr.mode = nvmem_bin_attr_get_umode(nvmem);
nvmem->eeprom.size = nvmem->size; nvmem->eeprom.size = nvmem->size;
#ifdef CONFIG_DEBUG_LOCK_ALLOC #ifdef CONFIG_DEBUG_LOCK_ALLOC
...@@ -463,7 +462,7 @@ static int nvmem_populate_sysfs_cells(struct nvmem_device *nvmem) ...@@ -463,7 +462,7 @@ static int nvmem_populate_sysfs_cells(struct nvmem_device *nvmem)
"%s@%x,%x", entry->name, "%s@%x,%x", entry->name,
entry->offset, entry->offset,
entry->bit_offset); entry->bit_offset);
attrs[i].attr.mode = 0444; attrs[i].attr.mode = 0444 & nvmem_bin_attr_get_umode(nvmem);
attrs[i].size = entry->bytes; attrs[i].size = entry->bytes;
attrs[i].read = &nvmem_cell_attr_read; attrs[i].read = &nvmem_cell_attr_read;
attrs[i].private = entry; attrs[i].private = entry;
......
...@@ -18,18 +18,24 @@ static int meson_efuse_read(void *context, unsigned int offset, ...@@ -18,18 +18,24 @@ static int meson_efuse_read(void *context, unsigned int offset,
void *val, size_t bytes) void *val, size_t bytes)
{ {
struct meson_sm_firmware *fw = context; struct meson_sm_firmware *fw = context;
int ret;
return meson_sm_call_read(fw, (u8 *)val, bytes, SM_EFUSE_READ, offset, ret = meson_sm_call_read(fw, (u8 *)val, bytes, SM_EFUSE_READ, offset,
bytes, 0, 0, 0); bytes, 0, 0, 0);
return ret < 0 ? ret : 0;
} }
static int meson_efuse_write(void *context, unsigned int offset, static int meson_efuse_write(void *context, unsigned int offset,
void *val, size_t bytes) void *val, size_t bytes)
{ {
struct meson_sm_firmware *fw = context; struct meson_sm_firmware *fw = context;
int ret;
ret = meson_sm_call_write(fw, (u8 *)val, bytes, SM_EFUSE_WRITE, offset,
bytes, 0, 0, 0);
return meson_sm_call_write(fw, (u8 *)val, bytes, SM_EFUSE_WRITE, offset, return ret < 0 ? ret : 0;
bytes, 0, 0, 0);
} }
static const struct of_device_id meson_efuse_match[] = { static const struct of_device_id meson_efuse_match[] = {
......
...@@ -46,7 +46,10 @@ static int rmem_read(void *context, unsigned int offset, ...@@ -46,7 +46,10 @@ static int rmem_read(void *context, unsigned int offset,
memunmap(addr); memunmap(addr);
return count; if (count < 0)
return count;
return count == bytes ? 0 : -EIO;
} }
static int rmem_probe(struct platform_device *pdev) static int rmem_probe(struct platform_device *pdev)
......
...@@ -8,11 +8,14 @@ ...@@ -8,11 +8,14 @@
#define FASTRPC_IOCTL_ALLOC_DMA_BUFF _IOWR('R', 1, struct fastrpc_alloc_dma_buf) #define FASTRPC_IOCTL_ALLOC_DMA_BUFF _IOWR('R', 1, struct fastrpc_alloc_dma_buf)
#define FASTRPC_IOCTL_FREE_DMA_BUFF _IOWR('R', 2, __u32) #define FASTRPC_IOCTL_FREE_DMA_BUFF _IOWR('R', 2, __u32)
#define FASTRPC_IOCTL_INVOKE _IOWR('R', 3, struct fastrpc_invoke) #define FASTRPC_IOCTL_INVOKE _IOWR('R', 3, struct fastrpc_invoke)
/* This ioctl is only supported with secure device nodes */
#define FASTRPC_IOCTL_INIT_ATTACH _IO('R', 4) #define FASTRPC_IOCTL_INIT_ATTACH _IO('R', 4)
#define FASTRPC_IOCTL_INIT_CREATE _IOWR('R', 5, struct fastrpc_init_create) #define FASTRPC_IOCTL_INIT_CREATE _IOWR('R', 5, struct fastrpc_init_create)
#define FASTRPC_IOCTL_MMAP _IOWR('R', 6, struct fastrpc_req_mmap) #define FASTRPC_IOCTL_MMAP _IOWR('R', 6, struct fastrpc_req_mmap)
#define FASTRPC_IOCTL_MUNMAP _IOWR('R', 7, struct fastrpc_req_munmap) #define FASTRPC_IOCTL_MUNMAP _IOWR('R', 7, struct fastrpc_req_munmap)
/* This ioctl is only supported with secure device nodes */
#define FASTRPC_IOCTL_INIT_ATTACH_SNS _IO('R', 8) #define FASTRPC_IOCTL_INIT_ATTACH_SNS _IO('R', 8)
/* This ioctl is only supported with secure device nodes */
#define FASTRPC_IOCTL_INIT_CREATE_STATIC _IOWR('R', 9, struct fastrpc_init_create_static) #define FASTRPC_IOCTL_INIT_CREATE_STATIC _IOWR('R', 9, struct fastrpc_init_create_static)
#define FASTRPC_IOCTL_MEM_MAP _IOWR('R', 10, struct fastrpc_mem_map) #define FASTRPC_IOCTL_MEM_MAP _IOWR('R', 10, struct fastrpc_mem_map)
#define FASTRPC_IOCTL_MEM_UNMAP _IOWR('R', 11, struct fastrpc_mem_unmap) #define FASTRPC_IOCTL_MEM_UNMAP _IOWR('R', 11, struct fastrpc_mem_unmap)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment