Char/Misc driver fixes for 6.9-rc5
Here are some small char/misc and other driver fixes for 6.9-rc5. Included in here are the following: - binder driver fix for reported problem - speakup crash fix - mei driver fixes for reported problems - comdei driver fix - interconnect driver fixes - rtsx driver fix - peci.h kernel doc fix All of these have been in linux-next for over a week with no reported problems. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCZiT2+g8cZ3JlZ0Brcm9h aC5jb20ACgkQMUfUDdst+ylExgCfdEFb54LOH10I3hstLdzKEYQlIdUAoK8fGerp o29X7GJ3kmKh7d2tIS1m =iXIs -----END PGP SIGNATURE----- Merge tag 'char-misc-6.9-rc5' 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 and other driver fixes for 6.9-rc5. Included in here are the following: - binder driver fix for reported problem - speakup crash fix - mei driver fixes for reported problems - comdei driver fix - interconnect driver fixes - rtsx driver fix - peci.h kernel doc fix All of these have been in linux-next for over a week with no reported problems" * tag 'char-misc-6.9-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: peci: linux/peci.h: fix Excess kernel-doc description warning binder: check offset alignment in binder_get_object() comedi: vmk80xx: fix incomplete endpoint checking mei: vsc: Unregister interrupt handler for system suspend Revert "mei: vsc: Call wake_up() in the threaded IRQ handler" misc: rtsx: Fix rts5264 driver status incorrect when card removed mei: me: disable RPL-S on SPS and IGN firmwares speakup: Avoid crash on very long word interconnect: Don't access req_list while it's being manipulated interconnect: qcom: x1e80100: Remove inexistent ACV_PERF BCM
This commit is contained in:
commit
48cf398f15
|
@ -574,7 +574,7 @@ static u_long get_word(struct vc_data *vc)
|
||||||
}
|
}
|
||||||
attr_ch = get_char(vc, (u_short *)tmp_pos, &spk_attr);
|
attr_ch = get_char(vc, (u_short *)tmp_pos, &spk_attr);
|
||||||
buf[cnt++] = attr_ch;
|
buf[cnt++] = attr_ch;
|
||||||
while (tmpx < vc->vc_cols - 1) {
|
while (tmpx < vc->vc_cols - 1 && cnt < sizeof(buf) - 1) {
|
||||||
tmp_pos += 2;
|
tmp_pos += 2;
|
||||||
tmpx++;
|
tmpx++;
|
||||||
ch = get_char(vc, (u_short *)tmp_pos, &temp);
|
ch = get_char(vc, (u_short *)tmp_pos, &temp);
|
||||||
|
|
|
@ -1708,8 +1708,10 @@ static size_t binder_get_object(struct binder_proc *proc,
|
||||||
size_t object_size = 0;
|
size_t object_size = 0;
|
||||||
|
|
||||||
read_size = min_t(size_t, sizeof(*object), buffer->data_size - offset);
|
read_size = min_t(size_t, sizeof(*object), buffer->data_size - offset);
|
||||||
if (offset > buffer->data_size || read_size < sizeof(*hdr))
|
if (offset > buffer->data_size || read_size < sizeof(*hdr) ||
|
||||||
|
!IS_ALIGNED(offset, sizeof(u32)))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (u) {
|
if (u) {
|
||||||
if (copy_from_user(object, u + offset, read_size))
|
if (copy_from_user(object, u + offset, read_size))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -641,32 +641,21 @@ static int vmk80xx_find_usb_endpoints(struct comedi_device *dev)
|
||||||
struct vmk80xx_private *devpriv = dev->private;
|
struct vmk80xx_private *devpriv = dev->private;
|
||||||
struct usb_interface *intf = comedi_to_usb_interface(dev);
|
struct usb_interface *intf = comedi_to_usb_interface(dev);
|
||||||
struct usb_host_interface *iface_desc = intf->cur_altsetting;
|
struct usb_host_interface *iface_desc = intf->cur_altsetting;
|
||||||
struct usb_endpoint_descriptor *ep_desc;
|
struct usb_endpoint_descriptor *ep_rx_desc, *ep_tx_desc;
|
||||||
int i;
|
int ret;
|
||||||
|
|
||||||
if (iface_desc->desc.bNumEndpoints != 2)
|
if (devpriv->model == VMK8061_MODEL)
|
||||||
|
ret = usb_find_common_endpoints(iface_desc, &ep_rx_desc,
|
||||||
|
&ep_tx_desc, NULL, NULL);
|
||||||
|
else
|
||||||
|
ret = usb_find_common_endpoints(iface_desc, NULL, NULL,
|
||||||
|
&ep_rx_desc, &ep_tx_desc);
|
||||||
|
|
||||||
|
if (ret)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) {
|
devpriv->ep_rx = ep_rx_desc;
|
||||||
ep_desc = &iface_desc->endpoint[i].desc;
|
devpriv->ep_tx = ep_tx_desc;
|
||||||
|
|
||||||
if (usb_endpoint_is_int_in(ep_desc) ||
|
|
||||||
usb_endpoint_is_bulk_in(ep_desc)) {
|
|
||||||
if (!devpriv->ep_rx)
|
|
||||||
devpriv->ep_rx = ep_desc;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (usb_endpoint_is_int_out(ep_desc) ||
|
|
||||||
usb_endpoint_is_bulk_out(ep_desc)) {
|
|
||||||
if (!devpriv->ep_tx)
|
|
||||||
devpriv->ep_tx = ep_desc;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!devpriv->ep_rx || !devpriv->ep_tx)
|
|
||||||
return -ENODEV;
|
|
||||||
|
|
||||||
if (!usb_endpoint_maxp(devpriv->ep_rx) || !usb_endpoint_maxp(devpriv->ep_tx))
|
if (!usb_endpoint_maxp(devpriv->ep_rx) || !usb_endpoint_maxp(devpriv->ep_tx))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
|
@ -176,6 +176,8 @@ static struct icc_path *path_init(struct device *dev, struct icc_node *dst,
|
||||||
|
|
||||||
path->num_nodes = num_nodes;
|
path->num_nodes = num_nodes;
|
||||||
|
|
||||||
|
mutex_lock(&icc_bw_lock);
|
||||||
|
|
||||||
for (i = num_nodes - 1; i >= 0; i--) {
|
for (i = num_nodes - 1; i >= 0; i--) {
|
||||||
node->provider->users++;
|
node->provider->users++;
|
||||||
hlist_add_head(&path->reqs[i].req_node, &node->req_list);
|
hlist_add_head(&path->reqs[i].req_node, &node->req_list);
|
||||||
|
@ -186,6 +188,8 @@ static struct icc_path *path_init(struct device *dev, struct icc_node *dst,
|
||||||
node = node->reverse;
|
node = node->reverse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mutex_unlock(&icc_bw_lock);
|
||||||
|
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -792,12 +796,16 @@ void icc_put(struct icc_path *path)
|
||||||
pr_err("%s: error (%d)\n", __func__, ret);
|
pr_err("%s: error (%d)\n", __func__, ret);
|
||||||
|
|
||||||
mutex_lock(&icc_lock);
|
mutex_lock(&icc_lock);
|
||||||
|
mutex_lock(&icc_bw_lock);
|
||||||
|
|
||||||
for (i = 0; i < path->num_nodes; i++) {
|
for (i = 0; i < path->num_nodes; i++) {
|
||||||
node = path->reqs[i].node;
|
node = path->reqs[i].node;
|
||||||
hlist_del(&path->reqs[i].req_node);
|
hlist_del(&path->reqs[i].req_node);
|
||||||
if (!WARN_ON(!node->provider->users))
|
if (!WARN_ON(!node->provider->users))
|
||||||
node->provider->users--;
|
node->provider->users--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mutex_unlock(&icc_bw_lock);
|
||||||
mutex_unlock(&icc_lock);
|
mutex_unlock(&icc_lock);
|
||||||
|
|
||||||
kfree_const(path->name);
|
kfree_const(path->name);
|
||||||
|
|
|
@ -116,15 +116,6 @@ static struct qcom_icc_node xm_sdc2 = {
|
||||||
.links = { X1E80100_SLAVE_A2NOC_SNOC },
|
.links = { X1E80100_SLAVE_A2NOC_SNOC },
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct qcom_icc_node ddr_perf_mode_master = {
|
|
||||||
.name = "ddr_perf_mode_master",
|
|
||||||
.id = X1E80100_MASTER_DDR_PERF_MODE,
|
|
||||||
.channels = 1,
|
|
||||||
.buswidth = 4,
|
|
||||||
.num_links = 1,
|
|
||||||
.links = { X1E80100_SLAVE_DDR_PERF_MODE },
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct qcom_icc_node qup0_core_master = {
|
static struct qcom_icc_node qup0_core_master = {
|
||||||
.name = "qup0_core_master",
|
.name = "qup0_core_master",
|
||||||
.id = X1E80100_MASTER_QUP_CORE_0,
|
.id = X1E80100_MASTER_QUP_CORE_0,
|
||||||
|
@ -688,14 +679,6 @@ static struct qcom_icc_node qns_a2noc_snoc = {
|
||||||
.links = { X1E80100_MASTER_A2NOC_SNOC },
|
.links = { X1E80100_MASTER_A2NOC_SNOC },
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct qcom_icc_node ddr_perf_mode_slave = {
|
|
||||||
.name = "ddr_perf_mode_slave",
|
|
||||||
.id = X1E80100_SLAVE_DDR_PERF_MODE,
|
|
||||||
.channels = 1,
|
|
||||||
.buswidth = 4,
|
|
||||||
.num_links = 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct qcom_icc_node qup0_core_slave = {
|
static struct qcom_icc_node qup0_core_slave = {
|
||||||
.name = "qup0_core_slave",
|
.name = "qup0_core_slave",
|
||||||
.id = X1E80100_SLAVE_QUP_CORE_0,
|
.id = X1E80100_SLAVE_QUP_CORE_0,
|
||||||
|
@ -1377,12 +1360,6 @@ static struct qcom_icc_bcm bcm_acv = {
|
||||||
.nodes = { &ebi },
|
.nodes = { &ebi },
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct qcom_icc_bcm bcm_acv_perf = {
|
|
||||||
.name = "ACV_PERF",
|
|
||||||
.num_nodes = 1,
|
|
||||||
.nodes = { &ddr_perf_mode_slave },
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct qcom_icc_bcm bcm_ce0 = {
|
static struct qcom_icc_bcm bcm_ce0 = {
|
||||||
.name = "CE0",
|
.name = "CE0",
|
||||||
.num_nodes = 1,
|
.num_nodes = 1,
|
||||||
|
@ -1583,18 +1560,15 @@ static const struct qcom_icc_desc x1e80100_aggre2_noc = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct qcom_icc_bcm * const clk_virt_bcms[] = {
|
static struct qcom_icc_bcm * const clk_virt_bcms[] = {
|
||||||
&bcm_acv_perf,
|
|
||||||
&bcm_qup0,
|
&bcm_qup0,
|
||||||
&bcm_qup1,
|
&bcm_qup1,
|
||||||
&bcm_qup2,
|
&bcm_qup2,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct qcom_icc_node * const clk_virt_nodes[] = {
|
static struct qcom_icc_node * const clk_virt_nodes[] = {
|
||||||
[MASTER_DDR_PERF_MODE] = &ddr_perf_mode_master,
|
|
||||||
[MASTER_QUP_CORE_0] = &qup0_core_master,
|
[MASTER_QUP_CORE_0] = &qup0_core_master,
|
||||||
[MASTER_QUP_CORE_1] = &qup1_core_master,
|
[MASTER_QUP_CORE_1] = &qup1_core_master,
|
||||||
[MASTER_QUP_CORE_2] = &qup2_core_master,
|
[MASTER_QUP_CORE_2] = &qup2_core_master,
|
||||||
[SLAVE_DDR_PERF_MODE] = &ddr_perf_mode_slave,
|
|
||||||
[SLAVE_QUP_CORE_0] = &qup0_core_slave,
|
[SLAVE_QUP_CORE_0] = &qup0_core_slave,
|
||||||
[SLAVE_QUP_CORE_1] = &qup1_core_slave,
|
[SLAVE_QUP_CORE_1] = &qup1_core_slave,
|
||||||
[SLAVE_QUP_CORE_2] = &qup2_core_slave,
|
[SLAVE_QUP_CORE_2] = &qup2_core_slave,
|
||||||
|
|
|
@ -1002,7 +1002,7 @@ static irqreturn_t rtsx_pci_isr(int irq, void *dev_id)
|
||||||
} else {
|
} else {
|
||||||
pcr->card_removed |= SD_EXIST;
|
pcr->card_removed |= SD_EXIST;
|
||||||
pcr->card_inserted &= ~SD_EXIST;
|
pcr->card_inserted &= ~SD_EXIST;
|
||||||
if (PCI_PID(pcr) == PID_5261) {
|
if ((PCI_PID(pcr) == PID_5261) || (PCI_PID(pcr) == PID_5264)) {
|
||||||
rtsx_pci_write_register(pcr, RTS5261_FW_STATUS,
|
rtsx_pci_write_register(pcr, RTS5261_FW_STATUS,
|
||||||
RTS5261_EXPRESS_LINK_FAIL_MASK, 0);
|
RTS5261_EXPRESS_LINK_FAIL_MASK, 0);
|
||||||
pcr->extra_caps |= EXTRA_CAPS_SD_EXPRESS;
|
pcr->extra_caps |= EXTRA_CAPS_SD_EXPRESS;
|
||||||
|
|
|
@ -116,7 +116,7 @@ static const struct pci_device_id mei_me_pci_tbl[] = {
|
||||||
{MEI_PCI_DEVICE(MEI_DEV_ID_ADP_P, MEI_ME_PCH15_CFG)},
|
{MEI_PCI_DEVICE(MEI_DEV_ID_ADP_P, MEI_ME_PCH15_CFG)},
|
||||||
{MEI_PCI_DEVICE(MEI_DEV_ID_ADP_N, MEI_ME_PCH15_CFG)},
|
{MEI_PCI_DEVICE(MEI_DEV_ID_ADP_N, MEI_ME_PCH15_CFG)},
|
||||||
|
|
||||||
{MEI_PCI_DEVICE(MEI_DEV_ID_RPL_S, MEI_ME_PCH15_CFG)},
|
{MEI_PCI_DEVICE(MEI_DEV_ID_RPL_S, MEI_ME_PCH15_SPS_CFG)},
|
||||||
|
|
||||||
{MEI_PCI_DEVICE(MEI_DEV_ID_MTL_M, MEI_ME_PCH15_CFG)},
|
{MEI_PCI_DEVICE(MEI_DEV_ID_MTL_M, MEI_ME_PCH15_CFG)},
|
||||||
{MEI_PCI_DEVICE(MEI_DEV_ID_ARL_S, MEI_ME_PCH15_CFG)},
|
{MEI_PCI_DEVICE(MEI_DEV_ID_ARL_S, MEI_ME_PCH15_CFG)},
|
||||||
|
|
|
@ -400,25 +400,40 @@ static void mei_vsc_remove(struct platform_device *pdev)
|
||||||
static int mei_vsc_suspend(struct device *dev)
|
static int mei_vsc_suspend(struct device *dev)
|
||||||
{
|
{
|
||||||
struct mei_device *mei_dev = dev_get_drvdata(dev);
|
struct mei_device *mei_dev = dev_get_drvdata(dev);
|
||||||
|
struct mei_vsc_hw *hw = mei_dev_to_vsc_hw(mei_dev);
|
||||||
|
|
||||||
mei_stop(mei_dev);
|
mei_stop(mei_dev);
|
||||||
|
|
||||||
|
mei_disable_interrupts(mei_dev);
|
||||||
|
|
||||||
|
vsc_tp_free_irq(hw->tp);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mei_vsc_resume(struct device *dev)
|
static int mei_vsc_resume(struct device *dev)
|
||||||
{
|
{
|
||||||
struct mei_device *mei_dev = dev_get_drvdata(dev);
|
struct mei_device *mei_dev = dev_get_drvdata(dev);
|
||||||
|
struct mei_vsc_hw *hw = mei_dev_to_vsc_hw(mei_dev);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
ret = vsc_tp_request_irq(hw->tp);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
ret = mei_restart(mei_dev);
|
ret = mei_restart(mei_dev);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
goto err_free;
|
||||||
|
|
||||||
/* start timer if stopped in suspend */
|
/* start timer if stopped in suspend */
|
||||||
schedule_delayed_work(&mei_dev->timer_work, HZ);
|
schedule_delayed_work(&mei_dev->timer_work, HZ);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
err_free:
|
||||||
|
vsc_tp_free_irq(hw->tp);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static DEFINE_SIMPLE_DEV_PM_OPS(mei_vsc_pm_ops, mei_vsc_suspend, mei_vsc_resume);
|
static DEFINE_SIMPLE_DEV_PM_OPS(mei_vsc_pm_ops, mei_vsc_suspend, mei_vsc_resume);
|
||||||
|
|
|
@ -94,6 +94,27 @@ static const struct acpi_gpio_mapping vsc_tp_acpi_gpios[] = {
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static irqreturn_t vsc_tp_isr(int irq, void *data)
|
||||||
|
{
|
||||||
|
struct vsc_tp *tp = data;
|
||||||
|
|
||||||
|
atomic_inc(&tp->assert_cnt);
|
||||||
|
|
||||||
|
wake_up(&tp->xfer_wait);
|
||||||
|
|
||||||
|
return IRQ_WAKE_THREAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
static irqreturn_t vsc_tp_thread_isr(int irq, void *data)
|
||||||
|
{
|
||||||
|
struct vsc_tp *tp = data;
|
||||||
|
|
||||||
|
if (tp->event_notify)
|
||||||
|
tp->event_notify(tp->event_notify_context);
|
||||||
|
|
||||||
|
return IRQ_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
/* wakeup firmware and wait for response */
|
/* wakeup firmware and wait for response */
|
||||||
static int vsc_tp_wakeup_request(struct vsc_tp *tp)
|
static int vsc_tp_wakeup_request(struct vsc_tp *tp)
|
||||||
{
|
{
|
||||||
|
@ -383,6 +404,37 @@ int vsc_tp_register_event_cb(struct vsc_tp *tp, vsc_tp_event_cb_t event_cb,
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_NS_GPL(vsc_tp_register_event_cb, VSC_TP);
|
EXPORT_SYMBOL_NS_GPL(vsc_tp_register_event_cb, VSC_TP);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* vsc_tp_request_irq - request irq for vsc_tp device
|
||||||
|
* @tp: vsc_tp device handle
|
||||||
|
*/
|
||||||
|
int vsc_tp_request_irq(struct vsc_tp *tp)
|
||||||
|
{
|
||||||
|
struct spi_device *spi = tp->spi;
|
||||||
|
struct device *dev = &spi->dev;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
irq_set_status_flags(spi->irq, IRQ_DISABLE_UNLAZY);
|
||||||
|
ret = request_threaded_irq(spi->irq, vsc_tp_isr, vsc_tp_thread_isr,
|
||||||
|
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
|
||||||
|
dev_name(dev), tp);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_NS_GPL(vsc_tp_request_irq, VSC_TP);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* vsc_tp_free_irq - free irq for vsc_tp device
|
||||||
|
* @tp: vsc_tp device handle
|
||||||
|
*/
|
||||||
|
void vsc_tp_free_irq(struct vsc_tp *tp)
|
||||||
|
{
|
||||||
|
free_irq(tp->spi->irq, tp);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_NS_GPL(vsc_tp_free_irq, VSC_TP);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* vsc_tp_intr_synchronize - synchronize vsc_tp interrupt
|
* vsc_tp_intr_synchronize - synchronize vsc_tp interrupt
|
||||||
* @tp: vsc_tp device handle
|
* @tp: vsc_tp device handle
|
||||||
|
@ -413,27 +465,6 @@ void vsc_tp_intr_disable(struct vsc_tp *tp)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_NS_GPL(vsc_tp_intr_disable, VSC_TP);
|
EXPORT_SYMBOL_NS_GPL(vsc_tp_intr_disable, VSC_TP);
|
||||||
|
|
||||||
static irqreturn_t vsc_tp_isr(int irq, void *data)
|
|
||||||
{
|
|
||||||
struct vsc_tp *tp = data;
|
|
||||||
|
|
||||||
atomic_inc(&tp->assert_cnt);
|
|
||||||
|
|
||||||
return IRQ_WAKE_THREAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
static irqreturn_t vsc_tp_thread_isr(int irq, void *data)
|
|
||||||
{
|
|
||||||
struct vsc_tp *tp = data;
|
|
||||||
|
|
||||||
wake_up(&tp->xfer_wait);
|
|
||||||
|
|
||||||
if (tp->event_notify)
|
|
||||||
tp->event_notify(tp->event_notify_context);
|
|
||||||
|
|
||||||
return IRQ_HANDLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int vsc_tp_match_any(struct acpi_device *adev, void *data)
|
static int vsc_tp_match_any(struct acpi_device *adev, void *data)
|
||||||
{
|
{
|
||||||
struct acpi_device **__adev = data;
|
struct acpi_device **__adev = data;
|
||||||
|
@ -490,10 +521,9 @@ static int vsc_tp_probe(struct spi_device *spi)
|
||||||
tp->spi = spi;
|
tp->spi = spi;
|
||||||
|
|
||||||
irq_set_status_flags(spi->irq, IRQ_DISABLE_UNLAZY);
|
irq_set_status_flags(spi->irq, IRQ_DISABLE_UNLAZY);
|
||||||
ret = devm_request_threaded_irq(dev, spi->irq, vsc_tp_isr,
|
ret = request_threaded_irq(spi->irq, vsc_tp_isr, vsc_tp_thread_isr,
|
||||||
vsc_tp_thread_isr,
|
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
|
||||||
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
|
dev_name(dev), tp);
|
||||||
dev_name(dev), tp);
|
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
@ -522,6 +552,8 @@ static int vsc_tp_probe(struct spi_device *spi)
|
||||||
err_destroy_lock:
|
err_destroy_lock:
|
||||||
mutex_destroy(&tp->mutex);
|
mutex_destroy(&tp->mutex);
|
||||||
|
|
||||||
|
free_irq(spi->irq, tp);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -532,6 +564,8 @@ static void vsc_tp_remove(struct spi_device *spi)
|
||||||
platform_device_unregister(tp->pdev);
|
platform_device_unregister(tp->pdev);
|
||||||
|
|
||||||
mutex_destroy(&tp->mutex);
|
mutex_destroy(&tp->mutex);
|
||||||
|
|
||||||
|
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[] = {
|
||||||
|
|
|
@ -37,6 +37,9 @@ int vsc_tp_xfer(struct vsc_tp *tp, u8 cmd, const void *obuf, size_t olen,
|
||||||
int vsc_tp_register_event_cb(struct vsc_tp *tp, vsc_tp_event_cb_t event_cb,
|
int vsc_tp_register_event_cb(struct vsc_tp *tp, vsc_tp_event_cb_t event_cb,
|
||||||
void *context);
|
void *context);
|
||||||
|
|
||||||
|
int vsc_tp_request_irq(struct vsc_tp *tp);
|
||||||
|
void vsc_tp_free_irq(struct vsc_tp *tp);
|
||||||
|
|
||||||
void vsc_tp_intr_enable(struct vsc_tp *tp);
|
void vsc_tp_intr_enable(struct vsc_tp *tp);
|
||||||
void vsc_tp_intr_disable(struct vsc_tp *tp);
|
void vsc_tp_intr_disable(struct vsc_tp *tp);
|
||||||
void vsc_tp_intr_synchronize(struct vsc_tp *tp);
|
void vsc_tp_intr_synchronize(struct vsc_tp *tp);
|
||||||
|
|
|
@ -58,7 +58,6 @@ static inline struct peci_controller *to_peci_controller(void *d)
|
||||||
/**
|
/**
|
||||||
* struct peci_device - PECI device
|
* struct peci_device - PECI device
|
||||||
* @dev: device object to register PECI device to the device model
|
* @dev: device object to register PECI device to the device model
|
||||||
* @controller: manages the bus segment hosting this PECI device
|
|
||||||
* @info: PECI device characteristics
|
* @info: PECI device characteristics
|
||||||
* @info.family: device family
|
* @info.family: device family
|
||||||
* @info.model: device model
|
* @info.model: device model
|
||||||
|
|
Loading…
Reference in New Issue