Commit 7b2fdd19 authored by Jonathan Cameron's avatar Jonathan Cameron Committed by Greg Kroah-Hartman

staging:iio: Rip out helper for software rings.

It seemed like a good idea at the time, it wasn't.
The code with this in place is larger and more complex for
no real gain.  Basically we've cleaned up the core around
it so much that this no longer makes sense.

Only really effects the lis3l02dq driver.
Signed-off-by: default avatarJonathan Cameron <jic23@cam.acuk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent cc4a48e4
......@@ -148,7 +148,6 @@ Form of high byte dependent on justification set in ctrl reg */
#define LIS3L02DQ_MAX_RX 12
/**
* struct lis3l02dq_state - device instance specific data
* @helper: data and func pointer allowing generic functions
* @us: actual spi_device
* @trig: data ready trigger registered with iio
* @tx: transmit buffer
......@@ -156,17 +155,14 @@ Form of high byte dependent on justification set in ctrl reg */
* @buf_lock: mutex to protect tx and rx
**/
struct lis3l02dq_state {
struct iio_sw_ring_helper_state help;
struct spi_device *us;
struct iio_trigger *trig;
u8 *tx;
u8 *rx;
struct mutex buf_lock;
bool trigger_on;
};
#define lis3l02dq_h_to_s(_h) \
container_of(_h, struct lis3l02dq_state, help)
u8 tx[LIS3L02DQ_MAX_RX] ____cacheline_aligned;
u8 rx[LIS3L02DQ_MAX_RX] ____cacheline_aligned;
};
int lis3l02dq_spi_read_reg_8(struct iio_dev *indio_dev,
u8 reg_address,
......
This diff is collapsed.
......@@ -32,8 +32,7 @@ static inline u16 combine_8_to_16(u8 lower, u8 upper)
irqreturn_t lis3l02dq_data_rdy_trig_poll(int irq, void *private)
{
struct iio_dev *indio_dev = private;
struct iio_sw_ring_helper_state *h = iio_dev_get_devdata(indio_dev);
struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
struct lis3l02dq_state *st = iio_priv(indio_dev);
if (st->trigger_on) {
iio_trigger_poll(st->trig, iio_get_time_ns());
......@@ -83,9 +82,10 @@ static const u8 read_all_tx_array[] = {
* @rx_array: (dma capable) receive array, must be at least
* 4*number of channels
**/
static int lis3l02dq_read_all(struct lis3l02dq_state *st, u8 *rx_array)
static int lis3l02dq_read_all(struct iio_dev *indio_dev, u8 *rx_array)
{
struct iio_ring_buffer *ring = st->help.indio_dev->ring;
struct iio_ring_buffer *ring = indio_dev->ring;
struct lis3l02dq_state *st = iio_priv(indio_dev);
struct spi_transfer *xfers;
struct spi_message msg;
int ret, i, j = 0;
......@@ -136,32 +136,20 @@ static int lis3l02dq_read_all(struct lis3l02dq_state *st, u8 *rx_array)
return ret;
}
static irqreturn_t lis3l02dq_trigger_handler(int irq, void *p)
{
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->private_data;
struct iio_sw_ring_helper_state *h = iio_dev_get_devdata(indio_dev);
h->last_timestamp = pf->timestamp;
iio_sw_trigger_to_ring(h);
return IRQ_HANDLED;
}
static int lis3l02dq_get_ring_element(struct iio_sw_ring_helper_state *h,
static int lis3l02dq_get_ring_element(struct iio_dev *indio_dev,
u8 *buf)
{
int ret, i;
u8 *rx_array ;
s16 *data = (s16 *)buf;
rx_array = kzalloc(4 * (h->indio_dev->ring->scan_count), GFP_KERNEL);
rx_array = kzalloc(4 * (indio_dev->ring->scan_count), GFP_KERNEL);
if (rx_array == NULL)
return -ENOMEM;
ret = lis3l02dq_read_all(lis3l02dq_h_to_s(h), rx_array);
ret = lis3l02dq_read_all(indio_dev, rx_array);
if (ret < 0)
return ret;
for (i = 0; i < h->indio_dev->ring->scan_count; i++)
for (i = 0; i < indio_dev->ring->scan_count; i++)
data[i] = combine_8_to_16(rx_array[i*4+1],
rx_array[i*4+3]);
kfree(rx_array);
......@@ -169,6 +157,36 @@ static int lis3l02dq_get_ring_element(struct iio_sw_ring_helper_state *h,
return i*sizeof(data[0]);
}
static irqreturn_t lis3l02dq_trigger_handler(int irq, void *p)
{
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->private_data;
struct iio_ring_buffer *ring = indio_dev->ring;
int len = 0;
size_t datasize = ring->access->get_bytes_per_datum(ring);
char *data = kmalloc(datasize, GFP_KERNEL);
if (data == NULL) {
dev_err(indio_dev->dev.parent,
"memory alloc failed in ring bh");
return -ENOMEM;
}
if (ring->scan_count)
len = lis3l02dq_get_ring_element(indio_dev, data);
/* Guaranteed to be aligned with 8 byte boundary */
if (ring->scan_timestamp)
*(s64 *)(((phys_addr_t)data + len
+ sizeof(s64) - 1) & ~(sizeof(s64) - 1))
= pf->timestamp;
ring->access->store_to(ring, (u8 *)data, pf->timestamp);
iio_trigger_notify_done(indio_dev->trig);
kfree(data);
return IRQ_HANDLED;
}
/* Caller responsible for locking as necessary. */
static int
__lis3l02dq_write_data_ready_config(struct device *dev, bool state)
......@@ -177,9 +195,7 @@ __lis3l02dq_write_data_ready_config(struct device *dev, bool state)
u8 valold;
bool currentlyset;
struct iio_dev *indio_dev = dev_get_drvdata(dev);
struct iio_sw_ring_helper_state *h
= iio_dev_get_devdata(indio_dev);
struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
struct lis3l02dq_state *st = iio_priv(indio_dev);
/* Get the current event mask register */
ret = lis3l02dq_spi_read_reg_8(indio_dev,
......@@ -242,19 +258,19 @@ __lis3l02dq_write_data_ready_config(struct device *dev, bool state)
static int lis3l02dq_data_rdy_trigger_set_state(struct iio_trigger *trig,
bool state)
{
struct lis3l02dq_state *st = trig->private_data;
struct iio_dev *indio_dev = trig->private_data;
int ret = 0;
u8 t;
__lis3l02dq_write_data_ready_config(&st->help.indio_dev->dev, state);
__lis3l02dq_write_data_ready_config(&indio_dev->dev, state);
if (state == false) {
/*
* A possible quirk with teh handler is currently worked around
* by ensuring outstanding read events are cleared.
*/
ret = lis3l02dq_read_all(st, NULL);
ret = lis3l02dq_read_all(indio_dev, NULL);
}
lis3l02dq_spi_read_reg_8(st->help.indio_dev,
lis3l02dq_spi_read_reg_8(indio_dev,
LIS3L02DQ_REG_WAKE_UP_SRC_ADDR,
&t);
return ret;
......@@ -266,14 +282,15 @@ static int lis3l02dq_data_rdy_trigger_set_state(struct iio_trigger *trig,
*/
static int lis3l02dq_trig_try_reen(struct iio_trigger *trig)
{
struct lis3l02dq_state *st = trig->private_data;
struct iio_dev *indio_dev = trig->private_data;
struct lis3l02dq_state *st = iio_priv(indio_dev);
int i;
/* If gpio still high (or high again) */
/* In theory possible we will need to do this several times */
for (i = 0; i < 5; i++)
if (gpio_get_value(irq_to_gpio(st->us->irq)))
lis3l02dq_read_all(st, NULL);
lis3l02dq_read_all(indio_dev, NULL);
else
break;
if (i == 5)
......@@ -287,9 +304,7 @@ static int lis3l02dq_trig_try_reen(struct iio_trigger *trig)
int lis3l02dq_probe_trigger(struct iio_dev *indio_dev)
{
int ret;
struct iio_sw_ring_helper_state *h
= iio_dev_get_devdata(indio_dev);
struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
struct lis3l02dq_state *st = iio_priv(indio_dev);
st->trig = iio_allocate_trigger("lis3l02dq-dev%d", indio_dev->id);
if (!st->trig) {
......@@ -299,7 +314,7 @@ int lis3l02dq_probe_trigger(struct iio_dev *indio_dev)
st->trig->dev.parent = &st->us->dev;
st->trig->owner = THIS_MODULE;
st->trig->private_data = st;
st->trig->private_data = indio_dev;
st->trig->set_trigger_state = &lis3l02dq_data_rdy_trigger_set_state;
st->trig->try_reenable = &lis3l02dq_trig_try_reen;
ret = iio_trigger_register(st->trig);
......@@ -316,9 +331,7 @@ int lis3l02dq_probe_trigger(struct iio_dev *indio_dev)
void lis3l02dq_remove_trigger(struct iio_dev *indio_dev)
{
struct iio_sw_ring_helper_state *h
= iio_dev_get_devdata(indio_dev);
struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
struct lis3l02dq_state *st = iio_priv(indio_dev);
iio_trigger_unregister(st->trig);
iio_free_trigger(st->trig);
......@@ -409,11 +422,8 @@ static const struct iio_ring_setup_ops lis3l02dq_ring_setup_ops = {
int lis3l02dq_configure_ring(struct iio_dev *indio_dev)
{
int ret;
struct iio_sw_ring_helper_state *h = iio_dev_get_devdata(indio_dev);
struct iio_ring_buffer *ring;
h->get_ring_element = &lis3l02dq_get_ring_element;
ring = lis3l02dq_alloc_buf(indio_dev);
if (!ring)
return -ENOMEM;
......
......@@ -452,55 +452,6 @@ void iio_sw_rb_free(struct iio_ring_buffer *r)
}
EXPORT_SYMBOL(iio_sw_rb_free);
void iio_sw_trigger_to_ring(struct iio_sw_ring_helper_state *st)
{
struct iio_ring_buffer *ring = st->indio_dev->ring;
int len = 0;
size_t datasize = ring->access->get_bytes_per_datum(ring);
char *data = kmalloc(datasize, GFP_KERNEL);
if (data == NULL) {
dev_err(st->indio_dev->dev.parent,
"memory alloc failed in ring bh");
return;
}
if (ring->scan_count)
len = st->get_ring_element(st, data);
/* Guaranteed to be aligned with 8 byte boundary */
if (ring->scan_timestamp)
*(s64 *)(((phys_addr_t)data + len
+ sizeof(s64) - 1) & ~(sizeof(s64) - 1))
= st->last_timestamp;
ring->access->store_to(ring,
(u8 *)data,
st->last_timestamp);
iio_trigger_notify_done(st->indio_dev->trig);
kfree(data);
return;
}
EXPORT_SYMBOL(iio_sw_trigger_to_ring);
void iio_sw_trigger_bh_to_ring(struct work_struct *work_s)
{
struct iio_sw_ring_helper_state *st
= container_of(work_s, struct iio_sw_ring_helper_state,
work_trigger_to_ring);
iio_sw_trigger_to_ring(st);
}
EXPORT_SYMBOL(iio_sw_trigger_bh_to_ring);
void iio_sw_poll_func_th(struct iio_dev *indio_dev, s64 time)
{ struct iio_sw_ring_helper_state *h
= iio_dev_get_devdata(indio_dev);
h->last_timestamp = time;
schedule_work(&h->work_trigger_to_ring);
}
EXPORT_SYMBOL(iio_sw_poll_func_th);
const struct iio_ring_access_funcs ring_sw_access_funcs = {
.mark_in_use = &iio_mark_sw_rb_in_use,
.unmark_in_use = &iio_unmark_sw_rb_in_use,
......
......@@ -23,10 +23,8 @@
#ifndef _IIO_RING_SW_H_
#define _IIO_RING_SW_H_
#include "iio.h"
#include "ring_generic.h"
#if defined CONFIG_IIO_SW_RING || defined CONFIG_IIO_SW_RING_MODULE
/**
* ring_sw_access_funcs - access functions for a software ring buffer
**/
......@@ -34,21 +32,4 @@ extern const struct iio_ring_access_funcs ring_sw_access_funcs;
struct iio_ring_buffer *iio_sw_rb_allocate(struct iio_dev *indio_dev);
void iio_sw_rb_free(struct iio_ring_buffer *ring);
struct iio_sw_ring_helper_state {
struct work_struct work_trigger_to_ring;
struct iio_dev *indio_dev;
int (*get_ring_element)(struct iio_sw_ring_helper_state *st, u8 *buf);
s64 last_timestamp;
};
void iio_sw_poll_func_th(struct iio_dev *indio_dev, s64 time);
void iio_sw_trigger_bh_to_ring(struct work_struct *work_s);
void iio_sw_trigger_to_ring(struct iio_sw_ring_helper_state *st);
#else /* CONFIG_IIO_RING_BUFFER*/
struct iio_sw_ring_helper_state {
struct iio_dev *indio_dev;
};
#endif /* !CONFIG_IIO_RING_BUFFER */
#endif /* _IIO_RING_SW_H_ */
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