Commit cd0bd184 authored by A. Hahn's avatar A. Hahn

Merge remote-tracking branch 'origin/realtime_fixes'

parents b2dcb185 f6b8c321
......@@ -289,7 +289,7 @@ static irqreturn_t irq_handler(int irq, void *dev_id)
}
pcie_int_enable(dev, 0); /* disable IRQ on Etherbone layer - Etherbone */
wishbone_slave_ready(&dev->wb);
wishbone_process_msi(&dev->wb);
return IRQ_HANDLED;
}
......@@ -462,7 +462,8 @@ static int probe(struct pci_dev *pdev, const struct pci_device_id *id)
goto fail_msi;
}
if (request_irq(pdev->irq, irq_handler, IRQF_SHARED, "pcie_wb", dev) < 0) {
if (request_threaded_irq(pdev->irq, NULL, irq_handler, IRQF_SHARED | IRQF_ONESHOT,
"pcie_wb", dev) < 0) {
printk(KERN_ALERT PCIE_WB ": could not register interrupt handler\n");
goto fail_reg;
}
......
......@@ -111,17 +111,14 @@ static inline void eb_from_cpu(unsigned char* x, wb_data_t dat)
}
}
/* Called from the wb->msi_workqueue */
static void wishbone_dispatch_msi(struct work_struct *work)
void wishbone_process_msi(struct wishbone* wb)
{
struct wishbone* wb;
struct wishbone_request request;
struct etherbone_master_context *context;
unsigned long flags;
uint8_t *wptr;
int index;
wb = container_of(work, struct wishbone, msi_handler);
context = 0;
/* Hold this mutex for the whole handler */
......@@ -207,6 +204,16 @@ static void wishbone_dispatch_msi(struct work_struct *work)
mutex_unlock(&wb->msi_mutex);
}
EXPORT_SYMBOL(wishbone_process_msi);
/* Called from the wb->msi_workqueue */
static void wishbone_dispatch_msi(struct work_struct *work)
{
struct wishbone* wb;
wb = container_of(work, struct wishbone, msi_handler);
wishbone_process_msi(wb);
}
/* Must be called with context_mutex held */
static void claim_msi(struct etherbone_master_context* context)
......@@ -249,9 +256,10 @@ static wb_data_t handle_read_cfg(struct etherbone_master_context* context, wb_ad
}
/* Must be called with both context_mutex and device_mutex held */
static void handle_write_cfg(struct etherbone_master_context* context, wb_addr_t addr, wb_data_t data)
static bool handle_write_cfg(struct etherbone_master_context* context, wb_addr_t addr, wb_data_t data)
{
struct wishbone *wb = context->wishbone;
bool need_process = false;
switch (addr) {
case 36:
......@@ -269,24 +277,26 @@ static void handle_write_cfg(struct etherbone_master_context* context, wb_addr_t
context->msi_pending = 0;
wb->msi_pending = 0;
wb->wops->reply(wb, data&1, context->msi_data);
wishbone_slave_ready(wb);
need_process = true;
}
break;
}
return need_process;
}
/* Must be called with context_mutex held */
static void etherbone_master_process(struct etherbone_master_context* context)
static bool etherbone_master_process(struct etherbone_master_context* context)
{
struct wishbone *wb;
const struct wishbone_operations *wops;
unsigned int size, left, i, record_len;
bool need_process_msi = false;
unsigned char *buf;
if (context->state == header) {
if (context->received < 8) {
/* no-op */
return;
return need_process_msi;
}
context->buf[0] = 0x4E;
......@@ -346,7 +356,7 @@ static void etherbone_master_process(struct etherbone_master_context* context)
for (j = wcount; j > 0; --j) {
eb_from_cpu(buf+i, 0);
i = RING_INDEX(i + sizeof(wb_data_t));
handle_write_cfg(context, base_address, eb_to_cpu(buf+i));
need_process_msi |= handle_write_cfg(context, base_address, eb_to_cpu(buf+i));
base_address += increment;
}
} else {
......@@ -396,6 +406,8 @@ static void etherbone_master_process(struct etherbone_master_context* context)
}
context->processed = RING_POS(context->processed + size - left);
return need_process_msi;
}
static int char_master_open(struct inode *inode, struct file *filep)
......@@ -532,6 +544,7 @@ static ssize_t char_master_aio_write(struct kiocb *iocb, const struct iovec *iov
struct file *filep = iocb->ki_filp;
struct etherbone_master_context *context = filep->private_data;
unsigned int len, iov_len, ring_len, buf_len;
bool need_process_msi;
iov_len = iov_length(iov, nr_segs);
if (unlikely(iov_len == 0)) return 0;
......@@ -554,9 +567,11 @@ static ssize_t char_master_aio_write(struct kiocb *iocb, const struct iovec *iov
context->received = RING_POS(context->received + len);
/* Process buffers */
etherbone_master_process(context);
need_process_msi = etherbone_master_process(context);
mutex_unlock(&context->context_mutex);
if (need_process_msi)
wishbone_process_msi(context->wishbone);
/* Wake-up polling descriptors */
wake_up_interruptible(&context->waitq);
......
......@@ -126,5 +126,6 @@ int wishbone_unregister(struct wishbone* wb); /* disable interrupts before calli
/* call when device has data pending. disable non-MSI interrupt generation before calling. */
void wishbone_slave_ready(struct wishbone* wb);
void wishbone_process_msi(struct wishbone* wb);
#endif
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