aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2021-11-04 08:21:47 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2021-11-04 08:21:47 -0700
commit5c904c66ed4e86c31ac7c033b64274cebed04e0e (patch)
tree769d366c5e61ffa45d5d8a99c61ae9d5ea39a0a0 /drivers/char
parentMerge tag 'staging-5.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging (diff)
parentcomedi: dt9812: fix DMA buffers on stack (diff)
downloadlinux-dev-5c904c66ed4e86c31ac7c033b64274cebed04e0e.tar.xz
linux-dev-5c904c66ed4e86c31ac7c033b64274cebed04e0e.zip
Merge tag 'char-misc-5.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char/misc driver updates from Greg KH: "Here is the big set of char and misc and other tiny driver subsystem updates for 5.16-rc1. Loads of things in here, all of which have been in linux-next for a while with no reported problems (except for one called out below.) Included are: - habanana labs driver updates, including dma_buf usage, reviewed and acked by the dma_buf maintainers - iio driver update (going through this tree not staging as they really do not belong going through that tree anymore) - counter driver updates - hwmon driver updates that the counter drivers needed, acked by the hwmon maintainer - xillybus driver updates - binder driver updates - extcon driver updates - dma_buf module namespaces added (will cause a build error in arm64 for allmodconfig, but that change is on its way through the drm tree) - lkdtm driver updates - pvpanic driver updates - phy driver updates - virt acrn and nitr_enclaves driver updates - smaller char and misc driver updates" * tag 'char-misc-5.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (386 commits) comedi: dt9812: fix DMA buffers on stack comedi: ni_usb6501: fix NULL-deref in command paths arm64: errata: Enable TRBE workaround for write to out-of-range address arm64: errata: Enable workaround for TRBE overwrite in FILL mode coresight: trbe: Work around write to out of range coresight: trbe: Make sure we have enough space coresight: trbe: Add a helper to determine the minimum buffer size coresight: trbe: Workaround TRBE errata overwrite in FILL mode coresight: trbe: Add infrastructure for Errata handling coresight: trbe: Allow driver to choose a different alignment coresight: trbe: Decouple buffer base from the hardware base coresight: trbe: Add a helper to pad a given buffer area coresight: trbe: Add a helper to calculate the trace generated coresight: trbe: Defer the probe on offline CPUs coresight: trbe: Fix incorrect access of the sink specific data coresight: etm4x: Add ETM PID for Kryo-5XX coresight: trbe: Prohibit trace before disabling TRBE coresight: trbe: End the AUX handle on truncation coresight: trbe: Do not truncate buffer on IRQ coresight: trbe: Fix handling of spurious interrupts ...
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/mem.c8
-rw-r--r--drivers/char/xillybus/xillybus.h31
-rw-r--r--drivers/char/xillybus/xillybus_core.c131
-rw-r--r--drivers/char/xillybus/xillybus_of.c86
-rw-r--r--drivers/char/xillybus/xillybus_pcie.c99
-rw-r--r--drivers/char/xillybus/xillyusb.c1
6 files changed, 96 insertions, 260 deletions
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 1c596b5cdb27..cc296f0823bd 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -495,6 +495,10 @@ static ssize_t read_iter_zero(struct kiocb *iocb, struct iov_iter *iter)
written += n;
if (signal_pending(current))
return written ? written : -ERESTARTSYS;
+ if (!need_resched())
+ continue;
+ if (iocb->ki_flags & IOCB_NOWAIT)
+ return written ? written : -EAGAIN;
cond_resched();
}
return written;
@@ -696,11 +700,11 @@ static const struct memdev {
#ifdef CONFIG_DEVMEM
[DEVMEM_MINOR] = { "mem", 0, &mem_fops, FMODE_UNSIGNED_OFFSET },
#endif
- [3] = { "null", 0666, &null_fops, 0 },
+ [3] = { "null", 0666, &null_fops, FMODE_NOWAIT },
#ifdef CONFIG_DEVPORT
[4] = { "port", 0, &port_fops, 0 },
#endif
- [5] = { "zero", 0666, &zero_fops, 0 },
+ [5] = { "zero", 0666, &zero_fops, FMODE_NOWAIT },
[7] = { "full", 0666, &full_fops, 0 },
[8] = { "random", 0666, &random_fops, 0 },
[9] = { "urandom", 0666, &urandom_fops, 0 },
diff --git a/drivers/char/xillybus/xillybus.h b/drivers/char/xillybus/xillybus.h
index c63ffc56637c..51de7cbc579e 100644
--- a/drivers/char/xillybus/xillybus.h
+++ b/drivers/char/xillybus/xillybus.h
@@ -87,13 +87,8 @@ struct xilly_channel {
};
struct xilly_endpoint {
- /*
- * One of pdev and dev is always NULL, and the other is a valid
- * pointer, depending on the type of device
- */
- struct pci_dev *pdev;
struct device *dev;
- struct xilly_endpoint_hardware *ephw;
+ struct module *owner;
int dma_using_dac; /* =1 if 64-bit DMA is used, =0 otherwise. */
__iomem void *registers;
@@ -113,25 +108,8 @@ struct xilly_endpoint {
unsigned int msg_buf_size;
};
-struct xilly_endpoint_hardware {
- struct module *owner;
- void (*hw_sync_sgl_for_cpu)(struct xilly_endpoint *,
- dma_addr_t,
- size_t,
- int);
- void (*hw_sync_sgl_for_device)(struct xilly_endpoint *,
- dma_addr_t,
- size_t,
- int);
- int (*map_single)(struct xilly_endpoint *,
- void *,
- size_t,
- int,
- dma_addr_t *);
-};
-
struct xilly_mapping {
- void *device;
+ struct device *device;
dma_addr_t dma_addr;
size_t size;
int direction;
@@ -139,10 +117,7 @@ struct xilly_mapping {
irqreturn_t xillybus_isr(int irq, void *data);
-struct xilly_endpoint *xillybus_init_endpoint(struct pci_dev *pdev,
- struct device *dev,
- struct xilly_endpoint_hardware
- *ephw);
+struct xilly_endpoint *xillybus_init_endpoint(struct device *dev);
int xillybus_endpoint_discovery(struct xilly_endpoint *endpoint);
diff --git a/drivers/char/xillybus/xillybus_core.c b/drivers/char/xillybus/xillybus_core.c
index 931d0bf4cec6..11b7c4749274 100644
--- a/drivers/char/xillybus/xillybus_core.c
+++ b/drivers/char/xillybus/xillybus_core.c
@@ -122,10 +122,8 @@ irqreturn_t xillybus_isr(int irq, void *data)
buf = ep->msgbuf_addr;
buf_size = ep->msg_buf_size/sizeof(u32);
- ep->ephw->hw_sync_sgl_for_cpu(ep,
- ep->msgbuf_dma_addr,
- ep->msg_buf_size,
- DMA_FROM_DEVICE);
+ dma_sync_single_for_cpu(ep->dev, ep->msgbuf_dma_addr,
+ ep->msg_buf_size, DMA_FROM_DEVICE);
for (i = 0; i < buf_size; i += 2) {
if (((buf[i+1] >> 28) & 0xf) != ep->msg_counter) {
@@ -140,11 +138,10 @@ irqreturn_t xillybus_isr(int irq, void *data)
dev_err(ep->dev,
"Lost sync with interrupt messages. Stopping.\n");
} else {
- ep->ephw->hw_sync_sgl_for_device(
- ep,
- ep->msgbuf_dma_addr,
- ep->msg_buf_size,
- DMA_FROM_DEVICE);
+ dma_sync_single_for_device(ep->dev,
+ ep->msgbuf_dma_addr,
+ ep->msg_buf_size,
+ DMA_FROM_DEVICE);
iowrite32(0x01, /* Message NACK */
ep->registers + fpga_msg_ctrl_reg);
@@ -275,10 +272,8 @@ irqreturn_t xillybus_isr(int irq, void *data)
}
}
- ep->ephw->hw_sync_sgl_for_device(ep,
- ep->msgbuf_dma_addr,
- ep->msg_buf_size,
- DMA_FROM_DEVICE);
+ dma_sync_single_for_device(ep->dev, ep->msgbuf_dma_addr,
+ ep->msg_buf_size, DMA_FROM_DEVICE);
ep->msg_counter = (ep->msg_counter + 1) & 0xf;
ep->failed_messages = 0;
@@ -304,6 +299,47 @@ struct xilly_alloc_state {
u32 regdirection;
};
+static void xilly_unmap(void *ptr)
+{
+ struct xilly_mapping *data = ptr;
+
+ dma_unmap_single(data->device, data->dma_addr,
+ data->size, data->direction);
+
+ kfree(ptr);
+}
+
+static int xilly_map_single(struct xilly_endpoint *ep,
+ void *ptr,
+ size_t size,
+ int direction,
+ dma_addr_t *ret_dma_handle
+ )
+{
+ dma_addr_t addr;
+ struct xilly_mapping *this;
+
+ this = kzalloc(sizeof(*this), GFP_KERNEL);
+ if (!this)
+ return -ENOMEM;
+
+ addr = dma_map_single(ep->dev, ptr, size, direction);
+
+ if (dma_mapping_error(ep->dev, addr)) {
+ kfree(this);
+ return -ENODEV;
+ }
+
+ this->device = ep->dev;
+ this->dma_addr = addr;
+ this->size = size;
+ this->direction = direction;
+
+ *ret_dma_handle = addr;
+
+ return devm_add_action_or_reset(ep->dev, xilly_unmap, this);
+}
+
static int xilly_get_dma_buffers(struct xilly_endpoint *ep,
struct xilly_alloc_state *s,
struct xilly_buffer **buffers,
@@ -355,9 +391,9 @@ static int xilly_get_dma_buffers(struct xilly_endpoint *ep,
s->left_of_salami = allocsize;
}
- rc = ep->ephw->map_single(ep, s->salami,
- bytebufsize, s->direction,
- &dma_addr);
+ rc = xilly_map_single(ep, s->salami,
+ bytebufsize, s->direction,
+ &dma_addr);
if (rc)
return rc;
@@ -620,11 +656,10 @@ static int xilly_obtain_idt(struct xilly_endpoint *endpoint)
return -ENODEV;
}
- endpoint->ephw->hw_sync_sgl_for_cpu(
- channel->endpoint,
- channel->wr_buffers[0]->dma_addr,
- channel->wr_buf_size,
- DMA_FROM_DEVICE);
+ dma_sync_single_for_cpu(channel->endpoint->dev,
+ channel->wr_buffers[0]->dma_addr,
+ channel->wr_buf_size,
+ DMA_FROM_DEVICE);
if (channel->wr_buffers[0]->end_offset != endpoint->idtlen) {
dev_err(endpoint->dev,
@@ -735,11 +770,10 @@ static ssize_t xillybus_read(struct file *filp, char __user *userbuf,
if (!empty) { /* Go on, now without the spinlock */
if (bufpos == 0) /* Position zero means it's virgin */
- channel->endpoint->ephw->hw_sync_sgl_for_cpu(
- channel->endpoint,
- channel->wr_buffers[bufidx]->dma_addr,
- channel->wr_buf_size,
- DMA_FROM_DEVICE);
+ dma_sync_single_for_cpu(channel->endpoint->dev,
+ channel->wr_buffers[bufidx]->dma_addr,
+ channel->wr_buf_size,
+ DMA_FROM_DEVICE);
if (copy_to_user(
userbuf,
@@ -751,11 +785,10 @@ static ssize_t xillybus_read(struct file *filp, char __user *userbuf,
bytes_done += howmany;
if (bufferdone) {
- channel->endpoint->ephw->hw_sync_sgl_for_device(
- channel->endpoint,
- channel->wr_buffers[bufidx]->dma_addr,
- channel->wr_buf_size,
- DMA_FROM_DEVICE);
+ dma_sync_single_for_device(channel->endpoint->dev,
+ channel->wr_buffers[bufidx]->dma_addr,
+ channel->wr_buf_size,
+ DMA_FROM_DEVICE);
/*
* Tell FPGA the buffer is done with. It's an
@@ -1055,11 +1088,10 @@ static int xillybus_myflush(struct xilly_channel *channel, long timeout)
else
channel->rd_host_buf_idx++;
- channel->endpoint->ephw->hw_sync_sgl_for_device(
- channel->endpoint,
- channel->rd_buffers[bufidx]->dma_addr,
- channel->rd_buf_size,
- DMA_TO_DEVICE);
+ dma_sync_single_for_device(channel->endpoint->dev,
+ channel->rd_buffers[bufidx]->dma_addr,
+ channel->rd_buf_size,
+ DMA_TO_DEVICE);
mutex_lock(&channel->endpoint->register_mutex);
@@ -1275,11 +1307,10 @@ static ssize_t xillybus_write(struct file *filp, const char __user *userbuf,
if ((bufpos == 0) || /* Zero means it's virgin */
(channel->rd_leftovers[3] != 0)) {
- channel->endpoint->ephw->hw_sync_sgl_for_cpu(
- channel->endpoint,
- channel->rd_buffers[bufidx]->dma_addr,
- channel->rd_buf_size,
- DMA_TO_DEVICE);
+ dma_sync_single_for_cpu(channel->endpoint->dev,
+ channel->rd_buffers[bufidx]->dma_addr,
+ channel->rd_buf_size,
+ DMA_TO_DEVICE);
/* Virgin, but leftovers are due */
for (i = 0; i < bufpos; i++)
@@ -1297,11 +1328,10 @@ static ssize_t xillybus_write(struct file *filp, const char __user *userbuf,
bytes_done += howmany;
if (bufferdone) {
- channel->endpoint->ephw->hw_sync_sgl_for_device(
- channel->endpoint,
- channel->rd_buffers[bufidx]->dma_addr,
- channel->rd_buf_size,
- DMA_TO_DEVICE);
+ dma_sync_single_for_device(channel->endpoint->dev,
+ channel->rd_buffers[bufidx]->dma_addr,
+ channel->rd_buf_size,
+ DMA_TO_DEVICE);
mutex_lock(&channel->endpoint->register_mutex);
@@ -1772,10 +1802,7 @@ static const struct file_operations xillybus_fops = {
.poll = xillybus_poll,
};
-struct xilly_endpoint *xillybus_init_endpoint(struct pci_dev *pdev,
- struct device *dev,
- struct xilly_endpoint_hardware
- *ephw)
+struct xilly_endpoint *xillybus_init_endpoint(struct device *dev)
{
struct xilly_endpoint *endpoint;
@@ -1783,9 +1810,7 @@ struct xilly_endpoint *xillybus_init_endpoint(struct pci_dev *pdev,
if (!endpoint)
return NULL;
- endpoint->pdev = pdev;
endpoint->dev = dev;
- endpoint->ephw = ephw;
endpoint->msg_counter = 0x0b;
endpoint->failed_messages = 0;
endpoint->fatal_error = 0;
@@ -1912,7 +1937,7 @@ int xillybus_endpoint_discovery(struct xilly_endpoint *endpoint)
goto failed_idt;
rc = xillybus_init_chrdev(dev, &xillybus_fops,
- endpoint->ephw->owner, endpoint,
+ endpoint->owner, endpoint,
idt_handle.names,
idt_handle.names_len,
endpoint->num_channels,
diff --git a/drivers/char/xillybus/xillybus_of.c b/drivers/char/xillybus/xillybus_of.c
index 1a20b286fd1d..e5372e45d211 100644
--- a/drivers/char/xillybus/xillybus_of.c
+++ b/drivers/char/xillybus/xillybus_of.c
@@ -31,102 +31,22 @@ static const struct of_device_id xillybus_of_match[] = {
MODULE_DEVICE_TABLE(of, xillybus_of_match);
-static void xilly_dma_sync_single_for_cpu_of(struct xilly_endpoint *ep,
- dma_addr_t dma_handle,
- size_t size,
- int direction)
-{
- dma_sync_single_for_cpu(ep->dev, dma_handle, size, direction);
-}
-
-static void xilly_dma_sync_single_for_device_of(struct xilly_endpoint *ep,
- dma_addr_t dma_handle,
- size_t size,
- int direction)
-{
- dma_sync_single_for_device(ep->dev, dma_handle, size, direction);
-}
-
-static void xilly_dma_sync_single_nop(struct xilly_endpoint *ep,
- dma_addr_t dma_handle,
- size_t size,
- int direction)
-{
-}
-
-static void xilly_of_unmap(void *ptr)
-{
- struct xilly_mapping *data = ptr;
-
- dma_unmap_single(data->device, data->dma_addr,
- data->size, data->direction);
-
- kfree(ptr);
-}
-
-static int xilly_map_single_of(struct xilly_endpoint *ep,
- void *ptr,
- size_t size,
- int direction,
- dma_addr_t *ret_dma_handle
- )
-{
- dma_addr_t addr;
- struct xilly_mapping *this;
-
- this = kzalloc(sizeof(*this), GFP_KERNEL);
- if (!this)
- return -ENOMEM;
-
- addr = dma_map_single(ep->dev, ptr, size, direction);
-
- if (dma_mapping_error(ep->dev, addr)) {
- kfree(this);
- return -ENODEV;
- }
-
- this->device = ep->dev;
- this->dma_addr = addr;
- this->size = size;
- this->direction = direction;
-
- *ret_dma_handle = addr;
-
- return devm_add_action_or_reset(ep->dev, xilly_of_unmap, this);
-}
-
-static struct xilly_endpoint_hardware of_hw = {
- .owner = THIS_MODULE,
- .hw_sync_sgl_for_cpu = xilly_dma_sync_single_for_cpu_of,
- .hw_sync_sgl_for_device = xilly_dma_sync_single_for_device_of,
- .map_single = xilly_map_single_of,
-};
-
-static struct xilly_endpoint_hardware of_hw_coherent = {
- .owner = THIS_MODULE,
- .hw_sync_sgl_for_cpu = xilly_dma_sync_single_nop,
- .hw_sync_sgl_for_device = xilly_dma_sync_single_nop,
- .map_single = xilly_map_single_of,
-};
-
static int xilly_drv_probe(struct platform_device *op)
{
struct device *dev = &op->dev;
struct xilly_endpoint *endpoint;
int rc;
int irq;
- struct xilly_endpoint_hardware *ephw = &of_hw;
- if (of_property_read_bool(dev->of_node, "dma-coherent"))
- ephw = &of_hw_coherent;
-
- endpoint = xillybus_init_endpoint(NULL, dev, ephw);
+ endpoint = xillybus_init_endpoint(dev);
if (!endpoint)
return -ENOMEM;
dev_set_drvdata(dev, endpoint);
+ endpoint->owner = THIS_MODULE;
+
endpoint->registers = devm_platform_ioremap_resource(op, 0);
if (IS_ERR(endpoint->registers))
return PTR_ERR(endpoint->registers);
diff --git a/drivers/char/xillybus/xillybus_pcie.c b/drivers/char/xillybus/xillybus_pcie.c
index bdf1c366b4fc..9858711e3e79 100644
--- a/drivers/char/xillybus/xillybus_pcie.c
+++ b/drivers/char/xillybus/xillybus_pcie.c
@@ -32,110 +32,21 @@ static const struct pci_device_id xillyids[] = {
{ /* End: all zeroes */ }
};
-static int xilly_pci_direction(int direction)
-{
- switch (direction) {
- case DMA_TO_DEVICE:
- return PCI_DMA_TODEVICE;
- case DMA_FROM_DEVICE:
- return PCI_DMA_FROMDEVICE;
- default:
- return PCI_DMA_BIDIRECTIONAL;
- }
-}
-
-static void xilly_dma_sync_single_for_cpu_pci(struct xilly_endpoint *ep,
- dma_addr_t dma_handle,
- size_t size,
- int direction)
-{
- pci_dma_sync_single_for_cpu(ep->pdev,
- dma_handle,
- size,
- xilly_pci_direction(direction));
-}
-
-static void xilly_dma_sync_single_for_device_pci(struct xilly_endpoint *ep,
- dma_addr_t dma_handle,
- size_t size,
- int direction)
-{
- pci_dma_sync_single_for_device(ep->pdev,
- dma_handle,
- size,
- xilly_pci_direction(direction));
-}
-
-static void xilly_pci_unmap(void *ptr)
-{
- struct xilly_mapping *data = ptr;
-
- pci_unmap_single(data->device, data->dma_addr,
- data->size, data->direction);
-
- kfree(ptr);
-}
-
-/*
- * Map either through the PCI DMA mapper or the non_PCI one. Behind the
- * scenes exactly the same functions are called with the same parameters,
- * but that can change.
- */
-
-static int xilly_map_single_pci(struct xilly_endpoint *ep,
- void *ptr,
- size_t size,
- int direction,
- dma_addr_t *ret_dma_handle
- )
-{
- int pci_direction;
- dma_addr_t addr;
- struct xilly_mapping *this;
-
- this = kzalloc(sizeof(*this), GFP_KERNEL);
- if (!this)
- return -ENOMEM;
-
- pci_direction = xilly_pci_direction(direction);
-
- addr = pci_map_single(ep->pdev, ptr, size, pci_direction);
-
- if (pci_dma_mapping_error(ep->pdev, addr)) {
- kfree(this);
- return -ENODEV;
- }
-
- this->device = ep->pdev;
- this->dma_addr = addr;
- this->size = size;
- this->direction = pci_direction;
-
- *ret_dma_handle = addr;
-
- return devm_add_action_or_reset(ep->dev, xilly_pci_unmap, this);
-}
-
-static struct xilly_endpoint_hardware pci_hw = {
- .owner = THIS_MODULE,
- .hw_sync_sgl_for_cpu = xilly_dma_sync_single_for_cpu_pci,
- .hw_sync_sgl_for_device = xilly_dma_sync_single_for_device_pci,
- .map_single = xilly_map_single_pci,
-};
-
static int xilly_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
struct xilly_endpoint *endpoint;
int rc;
- endpoint = xillybus_init_endpoint(pdev, &pdev->dev, &pci_hw);
+ endpoint = xillybus_init_endpoint(&pdev->dev);
if (!endpoint)
return -ENOMEM;
pci_set_drvdata(pdev, endpoint);
+ endpoint->owner = THIS_MODULE;
+
rc = pcim_enable_device(pdev);
if (rc) {
dev_err(endpoint->dev,
@@ -185,9 +96,9 @@ static int xilly_probe(struct pci_dev *pdev,
* So go for the 64-bit mask only when failing is the other option.
*/
- if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
+ if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(32))) {
endpoint->dma_using_dac = 0;
- } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
+ } else if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(64))) {
endpoint->dma_using_dac = 1;
} else {
dev_err(endpoint->dev, "Failed to set DMA mask. Aborting.\n");
diff --git a/drivers/char/xillybus/xillyusb.c b/drivers/char/xillybus/xillyusb.c
index e7f88f35c702..dc3551796e5e 100644
--- a/drivers/char/xillybus/xillyusb.c
+++ b/drivers/char/xillybus/xillyusb.c
@@ -1912,6 +1912,7 @@ static int xillyusb_setup_base_eps(struct xillyusb_dev *xdev)
dealloc:
endpoint_dealloc(xdev->msg_ep); /* Also frees FIFO mem if allocated */
+ xdev->msg_ep = NULL;
return -ENOMEM;
}