mirror of
https://github.com/torvalds/linux.git
synced 2025-12-01 07:26:02 +07:00
Merge tag 'char-misc-6.18-rc3' 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 char/misc/android driver fixes for 6.18-rc3 for reported issues. Included in here are: - rust binder fixes for reported issues - mei device id addition - mei driver fixes - comedi bugfix - most usb driver bugfixes - fastrpc memory leak fix All of these have been in linux-next for a while with no reported issues" * tag 'char-misc-6.18-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: most: usb: hdm_probe: Fix calling put_device() before device initialization most: usb: Fix use-after-free in hdm_disconnect binder: remove "invalid inc weak" check mei: txe: fix initialization order comedi: fix divide-by-zero in comedi_buf_munge() mei: late_bind: Fix -Wincompatible-function-pointer-types-strict misc: fastrpc: Fix dma_buf object leak in fastrpc_map_lookup mei: me: add wildcat lake P DID misc: amd-sbi: Clarify that this is a BMC driver nvmem: rcar-efuse: add missing MODULE_DEVICE_TABLE binder: Fix missing kernel-doc entries in binder.c rust_binder: report freeze notification only when fully frozen rust_binder: don't delete FreezeListener if there are pending duplicates rust_binder: freeze_notif_done should resend if wrong state rust_binder: remove warning about orphan mappings rust_binder: clean `clippy::mem_replace_with_default` warning
This commit is contained in:
@@ -851,17 +851,8 @@ static int binder_inc_node_nilocked(struct binder_node *node, int strong,
|
|||||||
} else {
|
} else {
|
||||||
if (!internal)
|
if (!internal)
|
||||||
node->local_weak_refs++;
|
node->local_weak_refs++;
|
||||||
if (!node->has_weak_ref && list_empty(&node->work.entry)) {
|
if (!node->has_weak_ref && target_list && list_empty(&node->work.entry))
|
||||||
if (target_list == NULL) {
|
|
||||||
pr_err("invalid inc weak node for %d\n",
|
|
||||||
node->debug_id);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* See comment above
|
|
||||||
*/
|
|
||||||
binder_enqueue_work_ilocked(&node->work, target_list);
|
binder_enqueue_work_ilocked(&node->work, target_list);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -2418,10 +2409,10 @@ err_fd_not_accepted:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* struct binder_ptr_fixup - data to be fixed-up in target buffer
|
* struct binder_ptr_fixup - data to be fixed-up in target buffer
|
||||||
* @offset offset in target buffer to fixup
|
* @offset: offset in target buffer to fixup
|
||||||
* @skip_size bytes to skip in copy (fixup will be written later)
|
* @skip_size: bytes to skip in copy (fixup will be written later)
|
||||||
* @fixup_data data to write at fixup offset
|
* @fixup_data: data to write at fixup offset
|
||||||
* @node list node
|
* @node: list node
|
||||||
*
|
*
|
||||||
* This is used for the pointer fixup list (pf) which is created and consumed
|
* This is used for the pointer fixup list (pf) which is created and consumed
|
||||||
* during binder_transaction() and is only accessed locally. No
|
* during binder_transaction() and is only accessed locally. No
|
||||||
@@ -2438,10 +2429,10 @@ struct binder_ptr_fixup {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* struct binder_sg_copy - scatter-gather data to be copied
|
* struct binder_sg_copy - scatter-gather data to be copied
|
||||||
* @offset offset in target buffer
|
* @offset: offset in target buffer
|
||||||
* @sender_uaddr user address in source buffer
|
* @sender_uaddr: user address in source buffer
|
||||||
* @length bytes to copy
|
* @length: bytes to copy
|
||||||
* @node list node
|
* @node: list node
|
||||||
*
|
*
|
||||||
* This is used for the sg copy list (sgc) which is created and consumed
|
* This is used for the sg copy list (sgc) which is created and consumed
|
||||||
* during binder_transaction() and is only accessed locally. No
|
* during binder_transaction() and is only accessed locally. No
|
||||||
@@ -4063,14 +4054,15 @@ binder_freeze_notification_done(struct binder_proc *proc,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* binder_free_buf() - free the specified buffer
|
* binder_free_buf() - free the specified buffer
|
||||||
* @proc: binder proc that owns buffer
|
* @proc: binder proc that owns buffer
|
||||||
* @buffer: buffer to be freed
|
* @thread: binder thread performing the buffer release
|
||||||
* @is_failure: failed to send transaction
|
* @buffer: buffer to be freed
|
||||||
|
* @is_failure: failed to send transaction
|
||||||
*
|
*
|
||||||
* If buffer for an async transaction, enqueue the next async
|
* If the buffer is for an async transaction, enqueue the next async
|
||||||
* transaction from the node.
|
* transaction from the node.
|
||||||
*
|
*
|
||||||
* Cleanup buffer and free it.
|
* Cleanup the buffer and free it.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
binder_free_buf(struct binder_proc *proc,
|
binder_free_buf(struct binder_proc *proc,
|
||||||
|
|||||||
@@ -106,13 +106,22 @@ impl DeliverToRead for FreezeMessage {
|
|||||||
return Ok(true);
|
return Ok(true);
|
||||||
}
|
}
|
||||||
if freeze.is_clearing {
|
if freeze.is_clearing {
|
||||||
_removed_listener = freeze_entry.remove_node();
|
kernel::warn_on!(freeze.num_cleared_duplicates != 0);
|
||||||
|
if freeze.num_pending_duplicates > 0 {
|
||||||
|
// The primary freeze listener was deleted, so convert a pending duplicate back
|
||||||
|
// into the primary one.
|
||||||
|
freeze.num_pending_duplicates -= 1;
|
||||||
|
freeze.is_pending = true;
|
||||||
|
freeze.is_clearing = true;
|
||||||
|
} else {
|
||||||
|
_removed_listener = freeze_entry.remove_node();
|
||||||
|
}
|
||||||
drop(node_refs);
|
drop(node_refs);
|
||||||
writer.write_code(BR_CLEAR_FREEZE_NOTIFICATION_DONE)?;
|
writer.write_code(BR_CLEAR_FREEZE_NOTIFICATION_DONE)?;
|
||||||
writer.write_payload(&self.cookie.0)?;
|
writer.write_payload(&self.cookie.0)?;
|
||||||
Ok(true)
|
Ok(true)
|
||||||
} else {
|
} else {
|
||||||
let is_frozen = freeze.node.owner.inner.lock().is_frozen;
|
let is_frozen = freeze.node.owner.inner.lock().is_frozen.is_fully_frozen();
|
||||||
if freeze.last_is_frozen == Some(is_frozen) {
|
if freeze.last_is_frozen == Some(is_frozen) {
|
||||||
return Ok(true);
|
return Ok(true);
|
||||||
}
|
}
|
||||||
@@ -245,8 +254,9 @@ impl Process {
|
|||||||
);
|
);
|
||||||
return Err(EINVAL);
|
return Err(EINVAL);
|
||||||
}
|
}
|
||||||
if freeze.is_clearing {
|
let is_frozen = freeze.node.owner.inner.lock().is_frozen.is_fully_frozen();
|
||||||
// Immediately send another FreezeMessage for BR_CLEAR_FREEZE_NOTIFICATION_DONE.
|
if freeze.is_clearing || freeze.last_is_frozen != Some(is_frozen) {
|
||||||
|
// Immediately send another FreezeMessage.
|
||||||
clear_msg = Some(FreezeMessage::init(alloc, cookie));
|
clear_msg = Some(FreezeMessage::init(alloc, cookie));
|
||||||
}
|
}
|
||||||
freeze.is_pending = false;
|
freeze.is_pending = false;
|
||||||
|
|||||||
@@ -687,7 +687,7 @@ impl Node {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
if inner.freeze_list.is_empty() {
|
if inner.freeze_list.is_empty() {
|
||||||
_unused_capacity = mem::replace(&mut inner.freeze_list, KVVec::new());
|
_unused_capacity = mem::take(&mut inner.freeze_list);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -72,6 +72,33 @@ impl Mapping {
|
|||||||
const PROC_DEFER_FLUSH: u8 = 1;
|
const PROC_DEFER_FLUSH: u8 = 1;
|
||||||
const PROC_DEFER_RELEASE: u8 = 2;
|
const PROC_DEFER_RELEASE: u8 = 2;
|
||||||
|
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
pub(crate) enum IsFrozen {
|
||||||
|
Yes,
|
||||||
|
No,
|
||||||
|
InProgress,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IsFrozen {
|
||||||
|
/// Whether incoming transactions should be rejected due to freeze.
|
||||||
|
pub(crate) fn is_frozen(self) -> bool {
|
||||||
|
match self {
|
||||||
|
IsFrozen::Yes => true,
|
||||||
|
IsFrozen::No => false,
|
||||||
|
IsFrozen::InProgress => true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Whether freeze notifications consider this process frozen.
|
||||||
|
pub(crate) fn is_fully_frozen(self) -> bool {
|
||||||
|
match self {
|
||||||
|
IsFrozen::Yes => true,
|
||||||
|
IsFrozen::No => false,
|
||||||
|
IsFrozen::InProgress => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// The fields of `Process` protected by the spinlock.
|
/// The fields of `Process` protected by the spinlock.
|
||||||
pub(crate) struct ProcessInner {
|
pub(crate) struct ProcessInner {
|
||||||
is_manager: bool,
|
is_manager: bool,
|
||||||
@@ -98,7 +125,7 @@ pub(crate) struct ProcessInner {
|
|||||||
/// are woken up.
|
/// are woken up.
|
||||||
outstanding_txns: u32,
|
outstanding_txns: u32,
|
||||||
/// Process is frozen and unable to service binder transactions.
|
/// Process is frozen and unable to service binder transactions.
|
||||||
pub(crate) is_frozen: bool,
|
pub(crate) is_frozen: IsFrozen,
|
||||||
/// Process received sync transactions since last frozen.
|
/// Process received sync transactions since last frozen.
|
||||||
pub(crate) sync_recv: bool,
|
pub(crate) sync_recv: bool,
|
||||||
/// Process received async transactions since last frozen.
|
/// Process received async transactions since last frozen.
|
||||||
@@ -124,7 +151,7 @@ impl ProcessInner {
|
|||||||
started_thread_count: 0,
|
started_thread_count: 0,
|
||||||
defer_work: 0,
|
defer_work: 0,
|
||||||
outstanding_txns: 0,
|
outstanding_txns: 0,
|
||||||
is_frozen: false,
|
is_frozen: IsFrozen::No,
|
||||||
sync_recv: false,
|
sync_recv: false,
|
||||||
async_recv: false,
|
async_recv: false,
|
||||||
binderfs_file: None,
|
binderfs_file: None,
|
||||||
@@ -1260,7 +1287,7 @@ impl Process {
|
|||||||
let is_manager = {
|
let is_manager = {
|
||||||
let mut inner = self.inner.lock();
|
let mut inner = self.inner.lock();
|
||||||
inner.is_dead = true;
|
inner.is_dead = true;
|
||||||
inner.is_frozen = false;
|
inner.is_frozen = IsFrozen::No;
|
||||||
inner.sync_recv = false;
|
inner.sync_recv = false;
|
||||||
inner.async_recv = false;
|
inner.async_recv = false;
|
||||||
inner.is_manager
|
inner.is_manager
|
||||||
@@ -1346,10 +1373,6 @@ impl Process {
|
|||||||
.alloc
|
.alloc
|
||||||
.take_for_each(|offset, size, debug_id, odata| {
|
.take_for_each(|offset, size, debug_id, odata| {
|
||||||
let ptr = offset + address;
|
let ptr = offset + address;
|
||||||
pr_warn!(
|
|
||||||
"{}: removing orphan mapping {offset}:{size}\n",
|
|
||||||
self.pid_in_current_ns()
|
|
||||||
);
|
|
||||||
let mut alloc =
|
let mut alloc =
|
||||||
Allocation::new(self.clone(), debug_id, offset, size, ptr, false);
|
Allocation::new(self.clone(), debug_id, offset, size, ptr, false);
|
||||||
if let Some(data) = odata {
|
if let Some(data) = odata {
|
||||||
@@ -1371,7 +1394,7 @@ impl Process {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
inner.outstanding_txns -= 1;
|
inner.outstanding_txns -= 1;
|
||||||
inner.is_frozen && inner.outstanding_txns == 0
|
inner.is_frozen.is_frozen() && inner.outstanding_txns == 0
|
||||||
};
|
};
|
||||||
|
|
||||||
if wake {
|
if wake {
|
||||||
@@ -1385,7 +1408,7 @@ impl Process {
|
|||||||
let mut inner = self.inner.lock();
|
let mut inner = self.inner.lock();
|
||||||
inner.sync_recv = false;
|
inner.sync_recv = false;
|
||||||
inner.async_recv = false;
|
inner.async_recv = false;
|
||||||
inner.is_frozen = false;
|
inner.is_frozen = IsFrozen::No;
|
||||||
drop(inner);
|
drop(inner);
|
||||||
msgs.send_messages();
|
msgs.send_messages();
|
||||||
return Ok(());
|
return Ok(());
|
||||||
@@ -1394,7 +1417,7 @@ impl Process {
|
|||||||
let mut inner = self.inner.lock();
|
let mut inner = self.inner.lock();
|
||||||
inner.sync_recv = false;
|
inner.sync_recv = false;
|
||||||
inner.async_recv = false;
|
inner.async_recv = false;
|
||||||
inner.is_frozen = true;
|
inner.is_frozen = IsFrozen::InProgress;
|
||||||
|
|
||||||
if info.timeout_ms > 0 {
|
if info.timeout_ms > 0 {
|
||||||
let mut jiffies = kernel::time::msecs_to_jiffies(info.timeout_ms);
|
let mut jiffies = kernel::time::msecs_to_jiffies(info.timeout_ms);
|
||||||
@@ -1408,7 +1431,7 @@ impl Process {
|
|||||||
.wait_interruptible_timeout(&mut inner, jiffies)
|
.wait_interruptible_timeout(&mut inner, jiffies)
|
||||||
{
|
{
|
||||||
CondVarTimeoutResult::Signal { .. } => {
|
CondVarTimeoutResult::Signal { .. } => {
|
||||||
inner.is_frozen = false;
|
inner.is_frozen = IsFrozen::No;
|
||||||
return Err(ERESTARTSYS);
|
return Err(ERESTARTSYS);
|
||||||
}
|
}
|
||||||
CondVarTimeoutResult::Woken { jiffies: remaining } => {
|
CondVarTimeoutResult::Woken { jiffies: remaining } => {
|
||||||
@@ -1422,17 +1445,18 @@ impl Process {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if inner.txns_pending_locked() {
|
if inner.txns_pending_locked() {
|
||||||
inner.is_frozen = false;
|
inner.is_frozen = IsFrozen::No;
|
||||||
Err(EAGAIN)
|
Err(EAGAIN)
|
||||||
} else {
|
} else {
|
||||||
drop(inner);
|
drop(inner);
|
||||||
match self.prepare_freeze_messages() {
|
match self.prepare_freeze_messages() {
|
||||||
Ok(batch) => {
|
Ok(batch) => {
|
||||||
|
self.inner.lock().is_frozen = IsFrozen::Yes;
|
||||||
batch.send_messages();
|
batch.send_messages();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Err(kernel::alloc::AllocError) => {
|
Err(kernel::alloc::AllocError) => {
|
||||||
self.inner.lock().is_frozen = false;
|
self.inner.lock().is_frozen = IsFrozen::No;
|
||||||
Err(ENOMEM)
|
Err(ENOMEM)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -249,7 +249,7 @@ impl Transaction {
|
|||||||
|
|
||||||
if oneway {
|
if oneway {
|
||||||
if let Some(target_node) = self.target_node.clone() {
|
if let Some(target_node) = self.target_node.clone() {
|
||||||
if process_inner.is_frozen {
|
if process_inner.is_frozen.is_frozen() {
|
||||||
process_inner.async_recv = true;
|
process_inner.async_recv = true;
|
||||||
if self.flags & TF_UPDATE_TXN != 0 {
|
if self.flags & TF_UPDATE_TXN != 0 {
|
||||||
if let Some(t_outdated) =
|
if let Some(t_outdated) =
|
||||||
@@ -270,7 +270,7 @@ impl Transaction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if process_inner.is_frozen {
|
if process_inner.is_frozen.is_frozen() {
|
||||||
return Err(BinderError::new_frozen_oneway());
|
return Err(BinderError::new_frozen_oneway());
|
||||||
} else {
|
} else {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
@@ -280,7 +280,7 @@ impl Transaction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if process_inner.is_frozen {
|
if process_inner.is_frozen.is_frozen() {
|
||||||
process_inner.sync_recv = true;
|
process_inner.sync_recv = true;
|
||||||
return Err(BinderError::new_frozen());
|
return Err(BinderError::new_frozen());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -317,7 +317,7 @@ static unsigned int comedi_buf_munge(struct comedi_subdevice *s,
|
|||||||
unsigned int count = 0;
|
unsigned int count = 0;
|
||||||
const unsigned int num_sample_bytes = comedi_bytes_per_sample(s);
|
const unsigned int num_sample_bytes = comedi_bytes_per_sample(s);
|
||||||
|
|
||||||
if (!s->munge || (async->cmd.flags & CMDF_RAWDATA)) {
|
if (!s->munge || (async->cmd.flags & CMDF_RAWDATA) || async->cmd.chanlist_len == 0) {
|
||||||
async->munge_count += num_bytes;
|
async->munge_count += num_bytes;
|
||||||
return num_bytes;
|
return num_bytes;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,9 +2,11 @@
|
|||||||
config AMD_SBRMI_I2C
|
config AMD_SBRMI_I2C
|
||||||
tristate "AMD side band RMI support"
|
tristate "AMD side band RMI support"
|
||||||
depends on I2C
|
depends on I2C
|
||||||
|
depends on ARM || ARM64 || COMPILE_TEST
|
||||||
select REGMAP_I2C
|
select REGMAP_I2C
|
||||||
help
|
help
|
||||||
Side band RMI over I2C support for AMD out of band management.
|
Side band RMI over I2C support for AMD out of band management.
|
||||||
|
This driver is intended to run on the BMC, not the managed node.
|
||||||
|
|
||||||
This driver can also be built as a module. If so, the module will
|
This driver can also be built as a module. If so, the module will
|
||||||
be called sbrmi-i2c.
|
be called sbrmi-i2c.
|
||||||
|
|||||||
@@ -381,6 +381,8 @@ static int fastrpc_map_lookup(struct fastrpc_user *fl, int fd,
|
|||||||
}
|
}
|
||||||
spin_unlock(&fl->lock);
|
spin_unlock(&fl->lock);
|
||||||
|
|
||||||
|
dma_buf_put(buf);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -120,6 +120,8 @@
|
|||||||
#define MEI_DEV_ID_PTL_H 0xE370 /* Panther Lake H */
|
#define MEI_DEV_ID_PTL_H 0xE370 /* Panther Lake H */
|
||||||
#define MEI_DEV_ID_PTL_P 0xE470 /* Panther Lake P */
|
#define MEI_DEV_ID_PTL_P 0xE470 /* Panther Lake P */
|
||||||
|
|
||||||
|
#define MEI_DEV_ID_WCL_P 0x4D70 /* Wildcat Lake P */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MEI HW Section
|
* MEI HW Section
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -134,8 +134,7 @@ static bool mei_lb_check_response(const struct device *dev, ssize_t bytes,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mei_lb_push_payload(struct device *dev,
|
static int mei_lb_push_payload(struct device *dev, u32 type, u32 flags,
|
||||||
enum intel_lb_type type, u32 flags,
|
|
||||||
const void *payload, size_t payload_size)
|
const void *payload, size_t payload_size)
|
||||||
{
|
{
|
||||||
struct mei_cl_device *cldev;
|
struct mei_cl_device *cldev;
|
||||||
|
|||||||
@@ -127,6 +127,8 @@ static const struct pci_device_id mei_me_pci_tbl[] = {
|
|||||||
{MEI_PCI_DEVICE(MEI_DEV_ID_PTL_H, MEI_ME_PCH15_CFG)},
|
{MEI_PCI_DEVICE(MEI_DEV_ID_PTL_H, MEI_ME_PCH15_CFG)},
|
||||||
{MEI_PCI_DEVICE(MEI_DEV_ID_PTL_P, MEI_ME_PCH15_CFG)},
|
{MEI_PCI_DEVICE(MEI_DEV_ID_PTL_P, MEI_ME_PCH15_CFG)},
|
||||||
|
|
||||||
|
{MEI_PCI_DEVICE(MEI_DEV_ID_WCL_P, MEI_ME_PCH15_CFG)},
|
||||||
|
|
||||||
/* required last entry */
|
/* required last entry */
|
||||||
{0, }
|
{0, }
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -109,19 +109,19 @@ static int mei_txe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = mei_register(dev, &pdev->dev);
|
||||||
|
if (err)
|
||||||
|
goto release_irq;
|
||||||
|
|
||||||
if (mei_start(dev)) {
|
if (mei_start(dev)) {
|
||||||
dev_err(&pdev->dev, "init hw failure.\n");
|
dev_err(&pdev->dev, "init hw failure.\n");
|
||||||
err = -ENODEV;
|
err = -ENODEV;
|
||||||
goto release_irq;
|
goto deregister;
|
||||||
}
|
}
|
||||||
|
|
||||||
pm_runtime_set_autosuspend_delay(&pdev->dev, MEI_TXI_RPM_TIMEOUT);
|
pm_runtime_set_autosuspend_delay(&pdev->dev, MEI_TXI_RPM_TIMEOUT);
|
||||||
pm_runtime_use_autosuspend(&pdev->dev);
|
pm_runtime_use_autosuspend(&pdev->dev);
|
||||||
|
|
||||||
err = mei_register(dev, &pdev->dev);
|
|
||||||
if (err)
|
|
||||||
goto stop;
|
|
||||||
|
|
||||||
pci_set_drvdata(pdev, dev);
|
pci_set_drvdata(pdev, dev);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -144,8 +144,8 @@ static int mei_txe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
stop:
|
deregister:
|
||||||
mei_stop(dev);
|
mei_deregister(dev);
|
||||||
release_irq:
|
release_irq:
|
||||||
mei_cancel_work(dev);
|
mei_cancel_work(dev);
|
||||||
mei_disable_interrupts(dev);
|
mei_disable_interrupts(dev);
|
||||||
|
|||||||
@@ -929,6 +929,10 @@ static void release_mdev(struct device *dev)
|
|||||||
{
|
{
|
||||||
struct most_dev *mdev = to_mdev_from_dev(dev);
|
struct most_dev *mdev = to_mdev_from_dev(dev);
|
||||||
|
|
||||||
|
kfree(mdev->busy_urbs);
|
||||||
|
kfree(mdev->cap);
|
||||||
|
kfree(mdev->conf);
|
||||||
|
kfree(mdev->ep_address);
|
||||||
kfree(mdev);
|
kfree(mdev);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@@ -1093,7 +1097,7 @@ err_free_cap:
|
|||||||
err_free_conf:
|
err_free_conf:
|
||||||
kfree(mdev->conf);
|
kfree(mdev->conf);
|
||||||
err_free_mdev:
|
err_free_mdev:
|
||||||
put_device(&mdev->dev);
|
kfree(mdev);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1121,13 +1125,6 @@ static void hdm_disconnect(struct usb_interface *interface)
|
|||||||
if (mdev->dci)
|
if (mdev->dci)
|
||||||
device_unregister(&mdev->dci->dev);
|
device_unregister(&mdev->dci->dev);
|
||||||
most_deregister_interface(&mdev->iface);
|
most_deregister_interface(&mdev->iface);
|
||||||
|
|
||||||
kfree(mdev->busy_urbs);
|
|
||||||
kfree(mdev->cap);
|
|
||||||
kfree(mdev->conf);
|
|
||||||
kfree(mdev->ep_address);
|
|
||||||
put_device(&mdev->dci->dev);
|
|
||||||
put_device(&mdev->dev);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hdm_suspend(struct usb_interface *interface, pm_message_t message)
|
static int hdm_suspend(struct usb_interface *interface, pm_message_t message)
|
||||||
|
|||||||
@@ -127,6 +127,7 @@ static const struct of_device_id rcar_fuse_match[] = {
|
|||||||
{ .compatible = "renesas,r8a779h0-otp", .data = &rcar_fuse_v4m },
|
{ .compatible = "renesas,r8a779h0-otp", .data = &rcar_fuse_v4m },
|
||||||
{ /* sentinel */ }
|
{ /* sentinel */ }
|
||||||
};
|
};
|
||||||
|
MODULE_DEVICE_TABLE(of, rcar_fuse_match);
|
||||||
|
|
||||||
static struct platform_driver rcar_fuse_driver = {
|
static struct platform_driver rcar_fuse_driver = {
|
||||||
.probe = rcar_fuse_probe,
|
.probe = rcar_fuse_probe,
|
||||||
|
|||||||
Reference in New Issue
Block a user