summaryrefslogtreecommitdiff
path: root/drivers/misc/mei
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/mei')
-rw-r--r--drivers/misc/mei/Kconfig2
-rw-r--r--drivers/misc/mei/bus.c58
-rw-r--r--drivers/misc/mei/client.c22
-rw-r--r--drivers/misc/mei/client.h2
-rw-r--r--drivers/misc/mei/hw-me-regs.h1
-rw-r--r--drivers/misc/mei/hw-txe.c45
-rw-r--r--drivers/misc/mei/hw-txe.h2
-rw-r--r--drivers/misc/mei/interrupt.c2
-rw-r--r--drivers/misc/mei/pci-me.c1
-rw-r--r--drivers/misc/mei/platform-vsc.c8
-rw-r--r--drivers/misc/mei/vsc-tp.c108
-rw-r--r--drivers/misc/mei/vsc-tp.h3
12 files changed, 64 insertions, 190 deletions
diff --git a/drivers/misc/mei/Kconfig b/drivers/misc/mei/Kconfig
index 67d9391f1855..7575fee96cc6 100644
--- a/drivers/misc/mei/Kconfig
+++ b/drivers/misc/mei/Kconfig
@@ -3,7 +3,7 @@
config INTEL_MEI
tristate "Intel Management Engine Interface"
depends on X86 && PCI
- default GENERIC_CPU || MCORE2 || MATOM || X86_GENERIC
+ default X86_64 || MATOM
help
The Intel Management Engine (Intel ME) provides Manageability,
Security and Media services for system containing Intel chipsets.
diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c
index 718ec5d81d94..1958c043ac14 100644
--- a/drivers/misc/mei/bus.c
+++ b/drivers/misc/mei/bus.c
@@ -324,28 +324,6 @@ ssize_t mei_cldev_recv_vtag(struct mei_cl_device *cldev, u8 *buf, size_t length,
EXPORT_SYMBOL_GPL(mei_cldev_recv_vtag);
/**
- * mei_cldev_recv_nonblock_vtag - non block client receive with vtag (read)
- *
- * @cldev: me client device
- * @buf: buffer to receive
- * @length: buffer length
- * @vtag: virtual tag
- *
- * Return:
- * * read size in bytes
- * * -EAGAIN if function will block.
- * * < 0 on other error
- */
-ssize_t mei_cldev_recv_nonblock_vtag(struct mei_cl_device *cldev, u8 *buf,
- size_t length, u8 *vtag)
-{
- struct mei_cl *cl = cldev->cl;
-
- return __mei_cl_recv(cl, buf, length, vtag, MEI_CL_IO_RX_NONBLOCK, 0);
-}
-EXPORT_SYMBOL_GPL(mei_cldev_recv_nonblock_vtag);
-
-/**
* mei_cldev_recv_timeout - client receive with timeout (read)
*
* @cldev: me client device
@@ -439,23 +417,6 @@ ssize_t mei_cldev_recv(struct mei_cl_device *cldev, u8 *buf, size_t length)
EXPORT_SYMBOL_GPL(mei_cldev_recv);
/**
- * mei_cldev_recv_nonblock - non block client receive (read)
- *
- * @cldev: me client device
- * @buf: buffer to receive
- * @length: buffer length
- *
- * Return: read size in bytes of < 0 on error
- * -EAGAIN if function will block.
- */
-ssize_t mei_cldev_recv_nonblock(struct mei_cl_device *cldev, u8 *buf,
- size_t length)
-{
- return mei_cldev_recv_nonblock_vtag(cldev, buf, length, NULL);
-}
-EXPORT_SYMBOL_GPL(mei_cldev_recv_nonblock);
-
-/**
* mei_cl_bus_rx_work - dispatch rx event for a bus device
*
* @work: work
@@ -641,19 +602,6 @@ void mei_cldev_set_drvdata(struct mei_cl_device *cldev, void *data)
EXPORT_SYMBOL_GPL(mei_cldev_set_drvdata);
/**
- * mei_cldev_uuid - return uuid of the underlying me client
- *
- * @cldev: mei client device
- *
- * Return: me client uuid
- */
-const uuid_le *mei_cldev_uuid(const struct mei_cl_device *cldev)
-{
- return mei_me_cl_uuid(cldev->me_cl);
-}
-EXPORT_SYMBOL_GPL(mei_cldev_uuid);
-
-/**
* mei_cldev_ver - return protocol version of the underlying me client
*
* @cldev: mei client device
@@ -1353,10 +1301,16 @@ static void mei_dev_bus_put(struct mei_device *bus)
static void mei_cl_bus_dev_release(struct device *dev)
{
struct mei_cl_device *cldev = to_mei_cl_device(dev);
+ struct mei_device *mdev = cldev->cl->dev;
+ struct mei_cl *cl;
mei_cl_flush_queues(cldev->cl, NULL);
mei_me_cl_put(cldev->me_cl);
mei_dev_bus_put(cldev->bus);
+
+ list_for_each_entry(cl, &mdev->file_list, link)
+ WARN_ON(cl == cldev->cl);
+
kfree(cldev->cl);
kfree(cldev);
}
diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c
index be011cef12e5..3db07d2a881f 100644
--- a/drivers/misc/mei/client.c
+++ b/drivers/misc/mei/client.c
@@ -272,28 +272,6 @@ void mei_me_cl_rm_by_uuid(struct mei_device *dev, const uuid_le *uuid)
}
/**
- * mei_me_cl_rm_by_uuid_id - remove all me clients matching client id
- *
- * @dev: the device structure
- * @uuid: me client uuid
- * @id: me client id
- *
- * Locking: called under "dev->device_lock" lock
- */
-void mei_me_cl_rm_by_uuid_id(struct mei_device *dev, const uuid_le *uuid, u8 id)
-{
- struct mei_me_client *me_cl;
-
- dev_dbg(dev->dev, "remove %pUl %d\n", uuid, id);
-
- down_write(&dev->me_clients_rwsem);
- me_cl = __mei_me_cl_by_uuid_id(dev, uuid, id);
- __mei_me_cl_del(dev, me_cl);
- mei_me_cl_put(me_cl);
- up_write(&dev->me_clients_rwsem);
-}
-
-/**
* mei_me_cl_rm_all - remove all me clients
*
* @dev: the device structure
diff --git a/drivers/misc/mei/client.h b/drivers/misc/mei/client.h
index 9052860bcfe0..01ed26a148c4 100644
--- a/drivers/misc/mei/client.h
+++ b/drivers/misc/mei/client.h
@@ -29,8 +29,6 @@ struct mei_me_client *mei_me_cl_by_id(struct mei_device *dev, u8 client_id);
struct mei_me_client *mei_me_cl_by_uuid_id(struct mei_device *dev,
const uuid_le *uuid, u8 client_id);
void mei_me_cl_rm_by_uuid(struct mei_device *dev, const uuid_le *uuid);
-void mei_me_cl_rm_by_uuid_id(struct mei_device *dev,
- const uuid_le *uuid, u8 id);
void mei_me_cl_rm_all(struct mei_device *dev);
/**
diff --git a/drivers/misc/mei/hw-me-regs.h b/drivers/misc/mei/hw-me-regs.h
index a5f88ec97df7..bc40b940ae21 100644
--- a/drivers/misc/mei/hw-me-regs.h
+++ b/drivers/misc/mei/hw-me-regs.h
@@ -117,6 +117,7 @@
#define MEI_DEV_ID_LNL_M 0xA870 /* Lunar Lake Point M */
+#define MEI_DEV_ID_PTL_H 0xE370 /* Panther Lake H */
#define MEI_DEV_ID_PTL_P 0xE470 /* Panther Lake P */
/*
diff --git a/drivers/misc/mei/hw-txe.c b/drivers/misc/mei/hw-txe.c
index 5d0f68b95c29..e9476f9ae25d 100644
--- a/drivers/misc/mei/hw-txe.c
+++ b/drivers/misc/mei/hw-txe.c
@@ -1209,48 +1209,3 @@ struct mei_device *mei_txe_dev_init(struct pci_dev *pdev)
return dev;
}
-
-/**
- * mei_txe_setup_satt2 - SATT2 configuration for DMA support.
- *
- * @dev: the device structure
- * @addr: physical address start of the range
- * @range: physical range size
- *
- * Return: 0 on success an error code otherwise
- */
-int mei_txe_setup_satt2(struct mei_device *dev, phys_addr_t addr, u32 range)
-{
- struct mei_txe_hw *hw = to_txe_hw(dev);
-
- u32 lo32 = lower_32_bits(addr);
- u32 hi32 = upper_32_bits(addr);
- u32 ctrl;
-
- /* SATT is limited to 36 Bits */
- if (hi32 & ~0xF)
- return -EINVAL;
-
- /* SATT has to be 16Byte aligned */
- if (lo32 & 0xF)
- return -EINVAL;
-
- /* SATT range has to be 4Bytes aligned */
- if (range & 0x4)
- return -EINVAL;
-
- /* SATT is limited to 32 MB range*/
- if (range > SATT_RANGE_MAX)
- return -EINVAL;
-
- ctrl = SATT2_CTRL_VALID_MSK;
- ctrl |= hi32 << SATT2_CTRL_BR_BASE_ADDR_REG_SHIFT;
-
- mei_txe_br_reg_write(hw, SATT2_SAP_SIZE_REG, range);
- mei_txe_br_reg_write(hw, SATT2_BRG_BA_LSB_REG, lo32);
- mei_txe_br_reg_write(hw, SATT2_CTRL_REG, ctrl);
- dev_dbg(dev->dev, "SATT2: SAP_SIZE_OFFSET=0x%08X, BRG_BA_LSB_OFFSET=0x%08X, CTRL_OFFSET=0x%08X\n",
- range, lo32, ctrl);
-
- return 0;
-}
diff --git a/drivers/misc/mei/hw-txe.h b/drivers/misc/mei/hw-txe.h
index 96511b04bf88..6790e646895d 100644
--- a/drivers/misc/mei/hw-txe.h
+++ b/drivers/misc/mei/hw-txe.h
@@ -59,7 +59,5 @@ irqreturn_t mei_txe_irq_thread_handler(int irq, void *dev_id);
int mei_txe_aliveness_set_sync(struct mei_device *dev, u32 req);
-int mei_txe_setup_satt2(struct mei_device *dev, phys_addr_t addr, u32 range);
-
#endif /* _MEI_HW_TXE_H_ */
diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c
index b09b79fedaba..c484f416fae4 100644
--- a/drivers/misc/mei/interrupt.c
+++ b/drivers/misc/mei/interrupt.c
@@ -133,7 +133,7 @@ static int mei_cl_irq_read_msg(struct mei_cl *cl,
break;
case MEI_EXT_HDR_GSC:
gsc_f2h = (struct mei_ext_hdr_gsc_f2h *)ext;
- cb->ext_hdr = kzalloc(sizeof(*gsc_f2h), GFP_KERNEL);
+ cb->ext_hdr = (struct mei_ext_hdr *)kzalloc(sizeof(*gsc_f2h), GFP_KERNEL);
if (!cb->ext_hdr) {
cb->status = -ENOMEM;
goto discard;
diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c
index d6ff9d82ae94..3f9c60b579ae 100644
--- a/drivers/misc/mei/pci-me.c
+++ b/drivers/misc/mei/pci-me.c
@@ -124,6 +124,7 @@ static const struct pci_device_id mei_me_pci_tbl[] = {
{MEI_PCI_DEVICE(MEI_DEV_ID_LNL_M, 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)},
/* required last entry */
diff --git a/drivers/misc/mei/platform-vsc.c b/drivers/misc/mei/platform-vsc.c
index 435760b1e86f..b2b5a20ae3fa 100644
--- a/drivers/misc/mei/platform-vsc.c
+++ b/drivers/misc/mei/platform-vsc.c
@@ -256,6 +256,9 @@ static int mei_vsc_hw_reset(struct mei_device *mei_dev, bool intr_enable)
vsc_tp_reset(hw->tp);
+ if (!intr_enable)
+ return 0;
+
return vsc_tp_init(hw->tp, mei_dev->dev);
}
@@ -377,6 +380,8 @@ err_stop:
err_cancel:
mei_cancel_work(mei_dev);
+ vsc_tp_register_event_cb(tp, NULL, NULL);
+
mei_disable_interrupts(mei_dev);
return ret;
@@ -385,11 +390,14 @@ err_cancel:
static void mei_vsc_remove(struct platform_device *pdev)
{
struct mei_device *mei_dev = platform_get_drvdata(pdev);
+ struct mei_vsc_hw *hw = mei_dev_to_vsc_hw(mei_dev);
pm_runtime_disable(mei_dev->dev);
mei_stop(mei_dev);
+ vsc_tp_register_event_cb(hw->tp, NULL, NULL);
+
mei_disable_interrupts(mei_dev);
mei_deregister(mei_dev);
diff --git a/drivers/misc/mei/vsc-tp.c b/drivers/misc/mei/vsc-tp.c
index 7be1649b1972..0de5acc33b74 100644
--- a/drivers/misc/mei/vsc-tp.c
+++ b/drivers/misc/mei/vsc-tp.c
@@ -18,6 +18,7 @@
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
#include <linux/types.h>
+#include <linux/workqueue.h>
#include "vsc-tp.h"
@@ -36,20 +37,24 @@
#define VSC_TP_XFER_TIMEOUT_BYTES 700
#define VSC_TP_PACKET_PADDING_SIZE 1
#define VSC_TP_PACKET_SIZE(pkt) \
- (sizeof(struct vsc_tp_packet) + le16_to_cpu((pkt)->len) + VSC_TP_CRC_SIZE)
+ (sizeof(struct vsc_tp_packet_hdr) + le16_to_cpu((pkt)->hdr.len) + VSC_TP_CRC_SIZE)
#define VSC_TP_MAX_PACKET_SIZE \
- (sizeof(struct vsc_tp_packet) + VSC_TP_MAX_MSG_SIZE + VSC_TP_CRC_SIZE)
+ (sizeof(struct vsc_tp_packet_hdr) + VSC_TP_MAX_MSG_SIZE + VSC_TP_CRC_SIZE)
#define VSC_TP_MAX_XFER_SIZE \
(VSC_TP_MAX_PACKET_SIZE + VSC_TP_XFER_TIMEOUT_BYTES)
#define VSC_TP_NEXT_XFER_LEN(len, offset) \
- (len + sizeof(struct vsc_tp_packet) + VSC_TP_CRC_SIZE - offset + VSC_TP_PACKET_PADDING_SIZE)
+ (len + sizeof(struct vsc_tp_packet_hdr) + VSC_TP_CRC_SIZE - offset + VSC_TP_PACKET_PADDING_SIZE)
-struct vsc_tp_packet {
+struct vsc_tp_packet_hdr {
__u8 sync;
__u8 cmd;
__le16 len;
__le32 seq;
- __u8 buf[] __counted_by(len);
+};
+
+struct vsc_tp_packet {
+ struct vsc_tp_packet_hdr hdr;
+ __u8 buf[VSC_TP_MAX_XFER_SIZE - sizeof(struct vsc_tp_packet_hdr)];
};
struct vsc_tp {
@@ -67,17 +72,17 @@ struct vsc_tp {
u32 seq;
/* command buffer */
- void *tx_buf;
- void *rx_buf;
+ struct vsc_tp_packet *tx_buf;
+ struct vsc_tp_packet *rx_buf;
atomic_t assert_cnt;
wait_queue_head_t xfer_wait;
+ struct work_struct event_work;
vsc_tp_event_cb_t event_notify;
void *event_notify_context;
-
- /* used to protect command download */
- struct mutex mutex;
+ struct mutex event_notify_mutex; /* protects event_notify + context */
+ struct mutex mutex; /* protects command download */
};
/* GPIO resources */
@@ -102,17 +107,19 @@ static irqreturn_t vsc_tp_isr(int irq, void *data)
wake_up(&tp->xfer_wait);
- return IRQ_WAKE_THREAD;
+ schedule_work(&tp->event_work);
+
+ return IRQ_HANDLED;
}
-static irqreturn_t vsc_tp_thread_isr(int irq, void *data)
+static void vsc_tp_event_work(struct work_struct *work)
{
- struct vsc_tp *tp = data;
+ struct vsc_tp *tp = container_of(work, struct vsc_tp, event_work);
+
+ guard(mutex)(&tp->event_notify_mutex);
if (tp->event_notify)
tp->event_notify(tp->event_notify_context);
-
- return IRQ_HANDLED;
}
/* wakeup firmware and wait for response */
@@ -158,12 +165,12 @@ static int vsc_tp_dev_xfer(struct vsc_tp *tp, void *obuf, void *ibuf, size_t len
static int vsc_tp_xfer_helper(struct vsc_tp *tp, struct vsc_tp_packet *pkt,
void *ibuf, u16 ilen)
{
- int ret, offset = 0, cpy_len, src_len, dst_len = sizeof(struct vsc_tp_packet);
+ int ret, offset = 0, cpy_len, src_len, dst_len = sizeof(struct vsc_tp_packet_hdr);
int next_xfer_len = VSC_TP_PACKET_SIZE(pkt) + VSC_TP_XFER_TIMEOUT_BYTES;
- u8 *src, *crc_src, *rx_buf = tp->rx_buf;
+ u8 *src, *crc_src, *rx_buf = (u8 *)tp->rx_buf;
int count_down = VSC_TP_MAX_XFER_COUNT;
u32 recv_crc = 0, crc = ~0;
- struct vsc_tp_packet ack;
+ struct vsc_tp_packet_hdr ack;
u8 *dst = (u8 *)&ack;
bool synced = false;
@@ -280,10 +287,10 @@ int vsc_tp_xfer(struct vsc_tp *tp, u8 cmd, const void *obuf, size_t olen,
guard(mutex)(&tp->mutex);
- pkt->sync = VSC_TP_PACKET_SYNC;
- pkt->cmd = cmd;
- pkt->len = cpu_to_le16(olen);
- pkt->seq = cpu_to_le32(++tp->seq);
+ pkt->hdr.sync = VSC_TP_PACKET_SYNC;
+ pkt->hdr.cmd = cmd;
+ pkt->hdr.len = cpu_to_le16(olen);
+ pkt->hdr.seq = cpu_to_le32(++tp->seq);
memcpy(pkt->buf, obuf, olen);
crc = ~crc32(~0, (u8 *)pkt, sizeof(pkt) + olen);
@@ -320,7 +327,7 @@ int vsc_tp_rom_xfer(struct vsc_tp *tp, const void *obuf, void *ibuf, size_t len)
guard(mutex)(&tp->mutex);
/* rom xfer is big endian */
- cpu_to_be32_array(tp->tx_buf, obuf, words);
+ cpu_to_be32_array((__be32 *)tp->tx_buf, obuf, words);
ret = read_poll_timeout(gpiod_get_value_cansleep, ret,
!ret, VSC_TP_ROM_XFER_POLL_DELAY_US,
@@ -336,7 +343,7 @@ int vsc_tp_rom_xfer(struct vsc_tp *tp, const void *obuf, void *ibuf, size_t len)
return ret;
if (ibuf)
- be32_to_cpu_array(ibuf, tp->rx_buf, words);
+ be32_to_cpu_array(ibuf, (__be32 *)tp->rx_buf, words);
return ret;
}
@@ -395,6 +402,8 @@ EXPORT_SYMBOL_NS_GPL(vsc_tp_need_read, "VSC_TP");
int vsc_tp_register_event_cb(struct vsc_tp *tp, vsc_tp_event_cb_t event_cb,
void *context)
{
+ guard(mutex)(&tp->event_notify_mutex);
+
tp->event_notify = event_cb;
tp->event_notify_context = context;
@@ -403,37 +412,6 @@ 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");
/**
- * 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
* @tp: vsc_tp device handle
*/
@@ -490,11 +468,11 @@ static int vsc_tp_probe(struct spi_device *spi)
if (!tp)
return -ENOMEM;
- tp->tx_buf = devm_kzalloc(dev, VSC_TP_MAX_XFER_SIZE, GFP_KERNEL);
+ tp->tx_buf = devm_kzalloc(dev, sizeof(*tp->tx_buf), GFP_KERNEL);
if (!tp->tx_buf)
return -ENOMEM;
- tp->rx_buf = devm_kzalloc(dev, VSC_TP_MAX_XFER_SIZE, GFP_KERNEL);
+ tp->rx_buf = devm_kzalloc(dev, sizeof(*tp->rx_buf), GFP_KERNEL);
if (!tp->rx_buf)
return -ENOMEM;
@@ -519,13 +497,15 @@ static int vsc_tp_probe(struct spi_device *spi)
tp->spi = spi;
irq_set_status_flags(spi->irq, IRQ_DISABLE_UNLAZY);
- ret = request_threaded_irq(spi->irq, vsc_tp_isr, vsc_tp_thread_isr,
+ ret = request_threaded_irq(spi->irq, NULL, vsc_tp_isr,
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
dev_name(dev), tp);
if (ret)
return ret;
mutex_init(&tp->mutex);
+ mutex_init(&tp->event_notify_mutex);
+ INIT_WORK(&tp->event_work, vsc_tp_event_work);
/* only one child acpi device */
ret = acpi_dev_for_each_child(ACPI_COMPANION(dev),
@@ -548,10 +528,12 @@ static int vsc_tp_probe(struct spi_device *spi)
return 0;
err_destroy_lock:
- mutex_destroy(&tp->mutex);
-
free_irq(spi->irq, tp);
+ cancel_work_sync(&tp->event_work);
+ mutex_destroy(&tp->event_notify_mutex);
+ mutex_destroy(&tp->mutex);
+
return ret;
}
@@ -561,9 +543,11 @@ static void vsc_tp_remove(struct spi_device *spi)
platform_device_unregister(tp->pdev);
- mutex_destroy(&tp->mutex);
-
free_irq(spi->irq, tp);
+
+ cancel_work_sync(&tp->event_work);
+ mutex_destroy(&tp->event_notify_mutex);
+ mutex_destroy(&tp->mutex);
}
static void vsc_tp_shutdown(struct spi_device *spi)
diff --git a/drivers/misc/mei/vsc-tp.h b/drivers/misc/mei/vsc-tp.h
index 14ca195cbddc..f9513ddc3e40 100644
--- a/drivers/misc/mei/vsc-tp.h
+++ b/drivers/misc/mei/vsc-tp.h
@@ -37,9 +37,6 @@ 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,
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_disable(struct vsc_tp *tp);
void vsc_tp_intr_synchronize(struct vsc_tp *tp);