|
@@ -124,15 +124,12 @@ struct cx23888_ir_state {
|
|
|
atomic_t rxclk_divider;
|
|
|
atomic_t rx_invert;
|
|
|
|
|
|
- struct kfifo *rx_kfifo;
|
|
|
+ struct kfifo rx_kfifo;
|
|
|
spinlock_t rx_kfifo_lock;
|
|
|
|
|
|
struct v4l2_subdev_ir_parameters tx_params;
|
|
|
struct mutex tx_params_lock;
|
|
|
atomic_t txclk_divider;
|
|
|
-
|
|
|
- struct kfifo *tx_kfifo;
|
|
|
- spinlock_t tx_kfifo_lock;
|
|
|
};
|
|
|
|
|
|
static inline struct cx23888_ir_state *to_state(struct v4l2_subdev *sd)
|
|
@@ -522,6 +519,7 @@ static int cx23888_ir_irq_handler(struct v4l2_subdev *sd, u32 status,
|
|
|
{
|
|
|
struct cx23888_ir_state *state = to_state(sd);
|
|
|
struct cx23885_dev *dev = state->dev;
|
|
|
+ unsigned long flags;
|
|
|
|
|
|
u32 cntrl = cx23888_ir_read4(dev, CX23888_IR_CNTRL_REG);
|
|
|
u32 irqen = cx23888_ir_read4(dev, CX23888_IR_IRQEN_REG);
|
|
@@ -594,8 +592,9 @@ static int cx23888_ir_irq_handler(struct v4l2_subdev *sd, u32 status,
|
|
|
if (i == 0)
|
|
|
break;
|
|
|
j = i * sizeof(u32);
|
|
|
- k = kfifo_put(state->rx_kfifo,
|
|
|
- (unsigned char *) rx_data, j);
|
|
|
+ k = kfifo_in_locked(&state->rx_kfifo,
|
|
|
+ (unsigned char *) rx_data, j,
|
|
|
+ &state->rx_kfifo_lock);
|
|
|
if (k != j)
|
|
|
kror++; /* rx_kfifo over run */
|
|
|
}
|
|
@@ -631,8 +630,11 @@ static int cx23888_ir_irq_handler(struct v4l2_subdev *sd, u32 status,
|
|
|
cx23888_ir_write4(dev, CX23888_IR_CNTRL_REG, cntrl);
|
|
|
*handled = true;
|
|
|
}
|
|
|
- if (kfifo_len(state->rx_kfifo) >= CX23888_IR_RX_KFIFO_SIZE / 2)
|
|
|
+
|
|
|
+ spin_lock_irqsave(&state->rx_kfifo_lock, flags);
|
|
|
+ if (kfifo_len(&state->rx_kfifo) >= CX23888_IR_RX_KFIFO_SIZE / 2)
|
|
|
events |= V4L2_SUBDEV_IR_RX_FIFO_SERVICE_REQ;
|
|
|
+ spin_unlock_irqrestore(&state->rx_kfifo_lock, flags);
|
|
|
|
|
|
if (events)
|
|
|
v4l2_subdev_notify(sd, V4L2_SUBDEV_IR_RX_NOTIFY, &events);
|
|
@@ -657,7 +659,7 @@ static int cx23888_ir_rx_read(struct v4l2_subdev *sd, u8 *buf, size_t count,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
- n = kfifo_get(state->rx_kfifo, buf, n);
|
|
|
+ n = kfifo_out_locked(&state->rx_kfifo, buf, n, &state->rx_kfifo_lock);
|
|
|
|
|
|
n /= sizeof(u32);
|
|
|
*num = n * sizeof(u32);
|
|
@@ -785,7 +787,12 @@ static int cx23888_ir_rx_s_parameters(struct v4l2_subdev *sd,
|
|
|
o->interrupt_enable = p->interrupt_enable;
|
|
|
o->enable = p->enable;
|
|
|
if (p->enable) {
|
|
|
- kfifo_reset(state->rx_kfifo);
|
|
|
+ unsigned long flags;
|
|
|
+
|
|
|
+ spin_lock_irqsave(&state->rx_kfifo_lock, flags);
|
|
|
+ kfifo_reset(&state->rx_kfifo);
|
|
|
+ /* reset tx_fifo too if there is one... */
|
|
|
+ spin_unlock_irqrestore(&state->rx_kfifo_lock, flags);
|
|
|
if (p->interrupt_enable)
|
|
|
irqenable_rx(dev, IRQEN_RSE | IRQEN_RTE | IRQEN_ROE);
|
|
|
control_rx_enable(dev, p->enable);
|
|
@@ -892,7 +899,6 @@ static int cx23888_ir_tx_s_parameters(struct v4l2_subdev *sd,
|
|
|
o->interrupt_enable = p->interrupt_enable;
|
|
|
o->enable = p->enable;
|
|
|
if (p->enable) {
|
|
|
- kfifo_reset(state->tx_kfifo);
|
|
|
if (p->interrupt_enable)
|
|
|
irqenable_tx(dev, IRQEN_TSE);
|
|
|
control_tx_enable(dev, p->enable);
|
|
@@ -1168,18 +1174,8 @@ int cx23888_ir_probe(struct cx23885_dev *dev)
|
|
|
return -ENOMEM;
|
|
|
|
|
|
spin_lock_init(&state->rx_kfifo_lock);
|
|
|
- state->rx_kfifo = kfifo_alloc(CX23888_IR_RX_KFIFO_SIZE, GFP_KERNEL,
|
|
|
- &state->rx_kfifo_lock);
|
|
|
- if (state->rx_kfifo == NULL)
|
|
|
- return -ENOMEM;
|
|
|
-
|
|
|
- spin_lock_init(&state->tx_kfifo_lock);
|
|
|
- state->tx_kfifo = kfifo_alloc(CX23888_IR_TX_KFIFO_SIZE, GFP_KERNEL,
|
|
|
- &state->tx_kfifo_lock);
|
|
|
- if (state->tx_kfifo == NULL) {
|
|
|
- kfifo_free(state->rx_kfifo);
|
|
|
+ if (kfifo_alloc(&state->rx_kfifo, CX23888_IR_RX_KFIFO_SIZE, GFP_KERNEL))
|
|
|
return -ENOMEM;
|
|
|
- }
|
|
|
|
|
|
state->dev = dev;
|
|
|
state->id = V4L2_IDENT_CX23888_IR;
|
|
@@ -1211,8 +1207,7 @@ int cx23888_ir_probe(struct cx23885_dev *dev)
|
|
|
sizeof(struct v4l2_subdev_ir_parameters));
|
|
|
v4l2_subdev_call(sd, ir, tx_s_parameters, &default_params);
|
|
|
} else {
|
|
|
- kfifo_free(state->rx_kfifo);
|
|
|
- kfifo_free(state->tx_kfifo);
|
|
|
+ kfifo_free(&state->rx_kfifo);
|
|
|
}
|
|
|
return ret;
|
|
|
}
|
|
@@ -1231,8 +1226,7 @@ int cx23888_ir_remove(struct cx23885_dev *dev)
|
|
|
|
|
|
state = to_state(sd);
|
|
|
v4l2_device_unregister_subdev(sd);
|
|
|
- kfifo_free(state->rx_kfifo);
|
|
|
- kfifo_free(state->tx_kfifo);
|
|
|
+ kfifo_free(&state->rx_kfifo);
|
|
|
kfree(state);
|
|
|
/* Nothing more to free() as state held the actual v4l2_subdev object */
|
|
|
return 0;
|