* [PATCH 4/5 v2] staging:iio:lis3l02dq use iio_sw_ring_helper_state and funcs
@ 2010-06-30 16:07 Jonathan Cameron
2010-06-30 16:07 ` [PATCH 5/5 v2] staging:iio:adis16209 " Jonathan Cameron
2010-07-08 9:32 ` [PATCH 4/5 v2] staging:iio:lis3l02dq " Barry Song
0 siblings, 2 replies; 5+ messages in thread
From: Jonathan Cameron @ 2010-06-30 16:07 UTC (permalink / raw)
To: linux-iio; +Cc: barry.song, Jonathan Cameron
Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
Couple of silly bugs fixed and this has now actually been tested!
drivers/staging/iio/accel/lis3l02dq.h | 11 +-
drivers/staging/iio/accel/lis3l02dq_core.c | 116 +++++++++++++----------
drivers/staging/iio/accel/lis3l02dq_ring.c | 137 +++++++++++-----------------
3 files changed, 124 insertions(+), 140 deletions(-)
diff --git a/drivers/staging/iio/accel/lis3l02dq.h b/drivers/staging/iio/accel/lis3l02dq.h
index 6de172e..44669ee 100644
--- a/drivers/staging/iio/accel/lis3l02dq.h
+++ b/drivers/staging/iio/accel/lis3l02dq.h
@@ -148,30 +148,29 @@ Form of high byte dependant 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
- * @work_trigger_to_ring: bh for triggered event handling
* @work_thresh: bh for threshold events
* @inter: used to check if new interrupt has been triggered
- * @last_timestamp: passing timestamp from th to bh of interrupt handler
- * @indio_dev: industrial I/O device structure
* @trig: data ready trigger registered with iio
* @tx: transmit buffer
* @rx: recieve buffer
* @buf_lock: mutex to protect tx and rx
**/
struct lis3l02dq_state {
+ struct iio_sw_ring_helper_state help;
struct spi_device *us;
- struct work_struct work_trigger_to_ring;
struct work_struct work_thresh;
bool inter;
- s64 last_timestamp;
- struct iio_dev *indio_dev;
struct iio_trigger *trig;
u8 *tx;
u8 *rx;
struct mutex buf_lock;
};
+#define lis3l02dq_h_to_s(_h) \
+ container_of(_h, struct lis3l02dq_state, help)
+
int lis3l02dq_spi_read_reg_8(struct device *dev,
u8 reg_address,
u8 *val);
diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c
index f86ffb8..2ce8d11 100644
--- a/drivers/staging/iio/accel/lis3l02dq_core.c
+++ b/drivers/staging/iio/accel/lis3l02dq_core.c
@@ -28,6 +28,8 @@
#include "../iio.h"
#include "../sysfs.h"
#include "../ring_generic.h"
+#include "../ring_sw.h"
+
#include "accel.h"
#include "lis3l02dq.h"
@@ -48,7 +50,9 @@ int lis3l02dq_spi_read_reg_8(struct device *dev, u8 reg_address, u8 *val)
int ret;
struct spi_message msg;
struct iio_dev *indio_dev = dev_get_drvdata(dev);
- struct lis3l02dq_state *st = iio_dev_get_devdata(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 spi_transfer xfer = {
.tx_buf = st->tx,
.rx_buf = st->rx,
@@ -83,7 +87,9 @@ int lis3l02dq_spi_write_reg_8(struct device *dev,
int ret;
struct spi_message msg;
struct iio_dev *indio_dev = dev_get_drvdata(dev);
- struct lis3l02dq_state *st = iio_dev_get_devdata(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 spi_transfer xfer = {
.tx_buf = st->tx,
.bits_per_word = 8,
@@ -117,7 +123,9 @@ static int lis3l02dq_spi_write_reg_s16(struct device *dev,
int ret;
struct spi_message msg;
struct iio_dev *indio_dev = dev_get_drvdata(dev);
- struct lis3l02dq_state *st = iio_dev_get_devdata(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 spi_transfer xfers[] = { {
.tx_buf = st->tx,
.bits_per_word = 8,
@@ -159,7 +167,9 @@ static int lis3l02dq_spi_read_reg_s16(struct device *dev,
{
struct spi_message msg;
struct iio_dev *indio_dev = dev_get_drvdata(dev);
- struct lis3l02dq_state *st = iio_dev_get_devdata(indio_dev);
+ struct iio_sw_ring_helper_state *h
+ = iio_dev_get_devdata(indio_dev);
+ struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
int ret;
struct spi_transfer xfers[] = { {
.tx_buf = st->tx,
@@ -412,7 +422,7 @@ static int lis3l02dq_initial_setup(struct lis3l02dq_state *st)
val = LIS3L02DQ_DEFAULT_CTRL1;
/* Write suitable defaults to ctrl1 */
- ret = lis3l02dq_spi_write_reg_8(&st->indio_dev->dev,
+ ret = lis3l02dq_spi_write_reg_8(&st->help.indio_dev->dev,
LIS3L02DQ_REG_CTRL_1_ADDR,
&val);
if (ret) {
@@ -420,7 +430,7 @@ static int lis3l02dq_initial_setup(struct lis3l02dq_state *st)
goto err_ret;
}
/* Repeat as sometimes doesn't work first time?*/
- ret = lis3l02dq_spi_write_reg_8(&st->indio_dev->dev,
+ ret = lis3l02dq_spi_write_reg_8(&st->help.indio_dev->dev,
LIS3L02DQ_REG_CTRL_1_ADDR,
&val);
if (ret) {
@@ -430,17 +440,17 @@ static int lis3l02dq_initial_setup(struct lis3l02dq_state *st)
/* Read back to check this has worked acts as loose test of correct
* chip */
- ret = lis3l02dq_spi_read_reg_8(&st->indio_dev->dev,
+ ret = lis3l02dq_spi_read_reg_8(&st->help.indio_dev->dev,
LIS3L02DQ_REG_CTRL_1_ADDR,
&valtest);
if (ret || (valtest != val)) {
- dev_err(&st->indio_dev->dev, "device not playing ball");
+ dev_err(&st->help.indio_dev->dev, "device not playing ball");
ret = -EINVAL;
goto err_ret;
}
val = LIS3L02DQ_DEFAULT_CTRL2;
- ret = lis3l02dq_spi_write_reg_8(&st->indio_dev->dev,
+ ret = lis3l02dq_spi_write_reg_8(&st->help.indio_dev->dev,
LIS3L02DQ_REG_CTRL_2_ADDR,
&val);
if (ret) {
@@ -449,7 +459,7 @@ static int lis3l02dq_initial_setup(struct lis3l02dq_state *st)
}
val = LIS3L02DQ_REG_WAKE_UP_CFG_LATCH_SRC;
- ret = lis3l02dq_spi_write_reg_8(&st->indio_dev->dev,
+ ret = lis3l02dq_spi_write_reg_8(&st->help.indio_dev->dev,
LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
&val);
if (ret)
@@ -595,15 +605,17 @@ error_mutex_unlock:
}
-static int lis3l02dq_thresh_handler_th(struct iio_dev *dev_info,
+static int lis3l02dq_thresh_handler_th(struct iio_dev *indio_dev,
int index,
s64 timestamp,
int no_test)
{
- struct lis3l02dq_state *st = dev_info->dev_data;
+ struct iio_sw_ring_helper_state *h
+ = iio_dev_get_devdata(indio_dev);
+ struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
/* Stash the timestamp somewhere convenient for the bh */
- st->last_timestamp = timestamp;
+ h->last_timestamp = timestamp;
schedule_work(&st->work_thresh);
return 0;
@@ -621,43 +633,43 @@ static void lis3l02dq_thresh_handler_bh_no_check(struct work_struct *work_s)
u8 t;
- lis3l02dq_spi_read_reg_8(&st->indio_dev->dev,
+ lis3l02dq_spi_read_reg_8(&st->help.indio_dev->dev,
LIS3L02DQ_REG_WAKE_UP_SRC_ADDR,
&t);
if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Z_HIGH)
- iio_push_event(st->indio_dev, 0,
+ iio_push_event(st->help.indio_dev, 0,
IIO_EVENT_CODE_ACCEL_Z_HIGH,
- st->last_timestamp);
+ st->help.last_timestamp);
if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Z_LOW)
- iio_push_event(st->indio_dev, 0,
+ iio_push_event(st->help.indio_dev, 0,
IIO_EVENT_CODE_ACCEL_Z_LOW,
- st->last_timestamp);
+ st->help.last_timestamp);
if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Y_HIGH)
- iio_push_event(st->indio_dev, 0,
+ iio_push_event(st->help.indio_dev, 0,
IIO_EVENT_CODE_ACCEL_Y_HIGH,
- st->last_timestamp);
+ st->help.last_timestamp);
if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Y_LOW)
- iio_push_event(st->indio_dev, 0,
+ iio_push_event(st->help.indio_dev, 0,
IIO_EVENT_CODE_ACCEL_Y_LOW,
- st->last_timestamp);
+ st->help.last_timestamp);
if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_X_HIGH)
- iio_push_event(st->indio_dev, 0,
+ iio_push_event(st->help.indio_dev, 0,
IIO_EVENT_CODE_ACCEL_X_HIGH,
- st->last_timestamp);
+ st->help.last_timestamp);
if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_X_LOW)
- iio_push_event(st->indio_dev, 0,
+ iio_push_event(st->help.indio_dev, 0,
IIO_EVENT_CODE_ACCEL_X_LOW,
- st->last_timestamp);
+ st->help.last_timestamp);
/* reenable the irq */
enable_irq(st->us->irq);
/* Ack and allow for new interrupts */
- lis3l02dq_spi_read_reg_8(&st->indio_dev->dev,
+ lis3l02dq_spi_read_reg_8(&st->help.indio_dev->dev,
LIS3L02DQ_REG_WAKE_UP_ACK_ADDR,
&t);
@@ -769,30 +781,30 @@ static int __devinit lis3l02dq_probe(struct spi_device *spi)
st->us = spi;
mutex_init(&st->buf_lock);
/* setup the industrialio driver allocated elements */
- st->indio_dev = iio_allocate_device();
- if (st->indio_dev == NULL) {
+ st->help.indio_dev = iio_allocate_device();
+ if (st->help.indio_dev == NULL) {
ret = -ENOMEM;
goto error_free_tx;
}
- st->indio_dev->dev.parent = &spi->dev;
- st->indio_dev->num_interrupt_lines = 1;
- st->indio_dev->event_attrs = &lis3l02dq_event_attribute_group;
- st->indio_dev->attrs = &lis3l02dq_attribute_group;
- st->indio_dev->dev_data = (void *)(st);
- st->indio_dev->driver_module = THIS_MODULE;
- st->indio_dev->modes = INDIO_DIRECT_MODE;
+ st->help.indio_dev->dev.parent = &spi->dev;
+ st->help.indio_dev->num_interrupt_lines = 1;
+ st->help.indio_dev->event_attrs = &lis3l02dq_event_attribute_group;
+ st->help.indio_dev->attrs = &lis3l02dq_attribute_group;
+ st->help.indio_dev->dev_data = (void *)(&st->help);
+ st->help.indio_dev->driver_module = THIS_MODULE;
+ st->help.indio_dev->modes = INDIO_DIRECT_MODE;
- ret = lis3l02dq_configure_ring(st->indio_dev);
+ ret = lis3l02dq_configure_ring(st->help.indio_dev);
if (ret)
goto error_free_dev;
- ret = iio_device_register(st->indio_dev);
+ ret = iio_device_register(st->help.indio_dev);
if (ret)
goto error_unreg_ring_funcs;
regdone = 1;
- ret = iio_ring_buffer_register(st->indio_dev->ring, 0);
+ ret = iio_ring_buffer_register(st->help.indio_dev->ring, 0);
if (ret) {
printk(KERN_ERR "failed to initialize the ring\n");
goto error_unreg_ring_funcs;
@@ -801,14 +813,14 @@ static int __devinit lis3l02dq_probe(struct spi_device *spi)
if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) {
st->inter = 0;
ret = iio_register_interrupt_line(spi->irq,
- st->indio_dev,
+ st->help.indio_dev,
0,
IRQF_TRIGGER_RISING,
"lis3l02dq");
if (ret)
goto error_uninitialize_ring;
- ret = lis3l02dq_probe_trigger(st->indio_dev);
+ ret = lis3l02dq_probe_trigger(st->help.indio_dev);
if (ret)
goto error_unregister_line;
}
@@ -820,20 +832,20 @@ static int __devinit lis3l02dq_probe(struct spi_device *spi)
return 0;
error_remove_trigger:
- if (st->indio_dev->modes & INDIO_RING_TRIGGERED)
- lis3l02dq_remove_trigger(st->indio_dev);
+ if (st->help.indio_dev->modes & INDIO_RING_TRIGGERED)
+ lis3l02dq_remove_trigger(st->help.indio_dev);
error_unregister_line:
- if (st->indio_dev->modes & INDIO_RING_TRIGGERED)
- iio_unregister_interrupt_line(st->indio_dev, 0);
+ if (st->help.indio_dev->modes & INDIO_RING_TRIGGERED)
+ iio_unregister_interrupt_line(st->help.indio_dev, 0);
error_uninitialize_ring:
- iio_ring_buffer_unregister(st->indio_dev->ring);
+ iio_ring_buffer_unregister(st->help.indio_dev->ring);
error_unreg_ring_funcs:
- lis3l02dq_unconfigure_ring(st->indio_dev);
+ lis3l02dq_unconfigure_ring(st->help.indio_dev);
error_free_dev:
if (regdone)
- iio_device_unregister(st->indio_dev);
+ iio_device_unregister(st->help.indio_dev);
else
- iio_free_device(st->indio_dev);
+ iio_free_device(st->help.indio_dev);
error_free_tx:
kfree(st->tx);
error_free_rx:
@@ -848,7 +860,9 @@ error_ret:
static int lis3l02dq_stop_device(struct iio_dev *indio_dev)
{
int ret;
- struct lis3l02dq_state *st = indio_dev->dev_data;
+ struct iio_sw_ring_helper_state *h
+ = iio_dev_get_devdata(indio_dev);
+ struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
u8 val = 0;
mutex_lock(&indio_dev->mlock);
@@ -875,7 +889,7 @@ static int lis3l02dq_remove(struct spi_device *spi)
{
int ret;
struct lis3l02dq_state *st = spi_get_drvdata(spi);
- struct iio_dev *indio_dev = st->indio_dev;
+ struct iio_dev *indio_dev = st->help.indio_dev;
ret = lis3l02dq_stop_device(indio_dev);
if (ret)
diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c
index 2c11209..dd840ee 100644
--- a/drivers/staging/iio/accel/lis3l02dq_ring.c
+++ b/drivers/staging/iio/accel/lis3l02dq_ring.c
@@ -105,11 +105,13 @@ static struct attribute_group lis3l02dq_scan_el_group = {
**/
static void lis3l02dq_poll_func_th(struct iio_dev *indio_dev, s64 time)
{
- struct lis3l02dq_state *st = iio_dev_get_devdata(indio_dev);
- st->last_timestamp = time;
- schedule_work(&st->work_trigger_to_ring);
- /* Indicate that this interrupt is being handled */
+ struct iio_sw_ring_helper_state *h
+ = iio_dev_get_devdata(indio_dev);
+ struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
+ /* in this case we need to slightly extend the helper function */
+ iio_sw_poll_func_th(indio_dev, time);
+ /* Indicate that this interrupt is being handled */
/* Technically this is trigger related, but without this
* handler running there is currently now way for the interrupt
* to clear.
@@ -120,15 +122,16 @@ static void lis3l02dq_poll_func_th(struct iio_dev *indio_dev, s64 time)
/**
* lis3l02dq_data_rdy_trig_poll() the event handler for the data rdy trig
**/
-static int lis3l02dq_data_rdy_trig_poll(struct iio_dev *dev_info,
+static int lis3l02dq_data_rdy_trig_poll(struct iio_dev *indio_dev,
int index,
s64 timestamp,
int no_test)
{
- struct lis3l02dq_state *st = iio_dev_get_devdata(dev_info);
- struct iio_trigger *trig = st->trig;
+ struct iio_sw_ring_helper_state *h
+ = iio_dev_get_devdata(indio_dev);
+ struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
- iio_trigger_poll(trig, timestamp);
+ iio_trigger_poll(st->trig, timestamp);
return IRQ_HANDLED;
}
@@ -212,7 +215,7 @@ static int lis3l02dq_read_all(struct lis3l02dq_state *st, u8 *rx_array)
struct spi_message msg;
int ret, i, j = 0;
- xfers = kzalloc((st->indio_dev->scan_count) * 2
+ xfers = kzalloc((st->help.indio_dev->scan_count) * 2
* sizeof(*xfers), GFP_KERNEL);
if (!xfers)
return -ENOMEM;
@@ -220,7 +223,7 @@ static int lis3l02dq_read_all(struct lis3l02dq_state *st, u8 *rx_array)
mutex_lock(&st->buf_lock);
for (i = 0; i < ARRAY_SIZE(read_all_tx_array)/4; i++) {
- if (st->indio_dev->scan_mask & (1 << i)) {
+ if (st->help.indio_dev->scan_mask & (1 << i)) {
/* lower byte */
xfers[j].tx_buf = st->tx + 2*j;
st->tx[2*j] = read_all_tx_array[i*4];
@@ -248,7 +251,7 @@ static int lis3l02dq_read_all(struct lis3l02dq_state *st, u8 *rx_array)
* values in alternate bytes
*/
spi_message_init(&msg);
- for (j = 0; j < st->indio_dev->scan_count * 2; j++)
+ for (j = 0; j < st->help.indio_dev->scan_count * 2; j++)
spi_message_add_tail(&xfers[j], &msg);
ret = spi_sync(st->us, &msg);
@@ -258,62 +261,35 @@ static int lis3l02dq_read_all(struct lis3l02dq_state *st, u8 *rx_array)
return ret;
}
-
-/* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device
- * specific to be rolled into the core.
- */
static void lis3l02dq_trigger_bh_to_ring(struct work_struct *work_s)
{
- struct lis3l02dq_state *st
- = container_of(work_s, struct lis3l02dq_state,
- work_trigger_to_ring);
-
- u8 *rx_array;
- int i = 0;
- u16 *data;
- size_t datasize = st->indio_dev
- ->ring->access.get_bpd(st->indio_dev->ring);
-
- data = kmalloc(datasize , GFP_KERNEL);
- if (data == NULL) {
- dev_err(&st->us->dev, "memory alloc failed in ring bh");
- return;
- }
- /* Due to interleaved nature of transmission this buffer must be
- * twice the number of bytes, or 4 times the number of channels
- */
- rx_array = kmalloc(4 * (st->indio_dev->scan_count), GFP_KERNEL);
- if (rx_array == NULL) {
- dev_err(&st->us->dev, "memory alloc failed in ring bh");
- kfree(data);
- return;
- }
-
- /* whilst trigger specific, if this read does nto occur the data
- ready interrupt will not be cleared. Need to add a mechanism
- to provide a dummy read function if this is not triggering on
- the data ready function but something else is.
- */
+ struct iio_sw_ring_helper_state *h
+ = container_of(work_s, struct iio_sw_ring_helper_state,
+ work_trigger_to_ring);
+ struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
st->inter = 0;
+ iio_sw_trigger_bh_to_ring(work_s);
+}
- if (st->indio_dev->scan_count)
- if (lis3l02dq_read_all(st, rx_array) >= 0)
- for (; i < st->indio_dev->scan_count; i++)
- data[i] = combine_8_to_16(rx_array[i*4+1],
- rx_array[i*4+3]);
- /* Guaranteed to be aligned with 8 byte boundary */
- if (st->indio_dev->scan_timestamp)
- *((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
-
- st->indio_dev->ring->access.store_to(st->indio_dev->ring,
- (u8 *)data,
- st->last_timestamp);
-
- iio_trigger_notify_done(st->indio_dev->trig);
+static int lis3l02dq_get_ring_element(struct iio_sw_ring_helper_state *h,
+ u8 *buf)
+{
+ int ret, i;
+ u8 *rx_array ;
+ s16 *data = (s16 *)buf;
+
+ rx_array = kzalloc(4 * (h->indio_dev->scan_count), GFP_KERNEL);
+ if (rx_array == NULL)
+ return -ENOMEM;
+ ret = lis3l02dq_read_all(lis3l02dq_h_to_s(h), rx_array);
+ if (ret < 0)
+ return ret;
+ for (i = 0; i < h->indio_dev->scan_count; i++)
+ data[i] = combine_8_to_16(rx_array[i*4+1],
+ rx_array[i*4+3]);
kfree(rx_array);
- kfree(data);
- return;
+ return i*sizeof(data[0]);
}
/* Caller responsible for locking as necessary. */
@@ -387,7 +363,7 @@ static int lis3l02dq_data_rdy_trigger_set_state(struct iio_trigger *trig,
struct lis3l02dq_state *st = trig->private_data;
int ret = 0;
u8 t;
- __lis3l02dq_write_data_ready_config(&st->indio_dev->dev,
+ __lis3l02dq_write_data_ready_config(&st->help.indio_dev->dev,
&iio_event_data_rdy_trig,
state);
if (state == false) {
@@ -397,7 +373,7 @@ static int lis3l02dq_data_rdy_trigger_set_state(struct iio_trigger *trig,
/* Clear any outstanding ready events */
ret = lis3l02dq_read_all(st, NULL);
}
- lis3l02dq_spi_read_reg_8(&st->indio_dev->dev,
+ lis3l02dq_spi_read_reg_8(&st->help.indio_dev->dev,
LIS3L02DQ_REG_WAKE_UP_SRC_ADDR,
&t);
return ret;
@@ -500,12 +476,12 @@ void lis3l02dq_unconfigure_ring(struct iio_dev *indio_dev)
int lis3l02dq_configure_ring(struct iio_dev *indio_dev)
{
- int ret = 0;
- struct lis3l02dq_state *st = indio_dev->dev_data;
- struct iio_ring_buffer *ring;
- INIT_WORK(&st->work_trigger_to_ring, lis3l02dq_trigger_bh_to_ring);
+ int ret;
+ struct iio_sw_ring_helper_state *h = iio_dev_get_devdata(indio_dev);
+
+ INIT_WORK(&h->work_trigger_to_ring, lis3l02dq_trigger_bh_to_ring);
/* Set default scan mode */
-
+ h->get_ring_element = &lis3l02dq_get_ring_element;
iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number);
iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number);
iio_scan_mask_set(indio_dev, iio_scan_el_accel_z.number);
@@ -513,19 +489,17 @@ int lis3l02dq_configure_ring(struct iio_dev *indio_dev)
indio_dev->scan_el_attrs = &lis3l02dq_scan_el_group;
- ring = iio_sw_rb_allocate(indio_dev);
- if (!ring) {
- ret = -ENOMEM;
- return ret;
- }
- indio_dev->ring = ring;
+ indio_dev->ring = iio_sw_rb_allocate(indio_dev);
+ if (!indio_dev->ring)
+ return -ENOMEM;
+
/* Effectively select the ring buffer implementation */
- iio_ring_sw_register_funcs(&ring->access);
- ring->bpe = 2;
- ring->preenable = &iio_sw_ring_preenable;
- ring->postenable = &iio_triggered_ring_postenable;
- ring->predisable = &iio_triggered_ring_predisable;
- ring->owner = THIS_MODULE;
+ iio_ring_sw_register_funcs(&indio_dev->ring->access);
+ indio_dev->ring->bpe = 2;
+ indio_dev->ring->preenable = &iio_sw_ring_preenable;
+ indio_dev->ring->postenable = &iio_triggered_ring_postenable;
+ indio_dev->ring->predisable = &iio_triggered_ring_predisable;
+ indio_dev->ring->owner = THIS_MODULE;
ret = iio_alloc_pollfunc(indio_dev, NULL, &lis3l02dq_poll_func_th);
if (ret)
@@ -537,6 +511,3 @@ error_iio_sw_rb_free:
iio_sw_rb_free(indio_dev->ring);
return ret;
}
-
-
-
--
1.7.0.4
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 5/5 v2] staging:iio:adis16209 use iio_sw_ring_helper_state and funcs
2010-06-30 16:07 [PATCH 4/5 v2] staging:iio:lis3l02dq use iio_sw_ring_helper_state and funcs Jonathan Cameron
@ 2010-06-30 16:07 ` Jonathan Cameron
2010-07-08 9:37 ` Barry Song
2010-07-08 9:32 ` [PATCH 4/5 v2] staging:iio:lis3l02dq " Barry Song
1 sibling, 1 reply; 5+ messages in thread
From: Jonathan Cameron @ 2010-06-30 16:07 UTC (permalink / raw)
To: linux-iio; +Cc: barry.song, Jonathan Cameron
Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
The get element fuction should return how much of the buffer it has
used. Now it actually does this.
drivers/staging/iio/accel/adis16209.h | 7 ++-
drivers/staging/iio/accel/adis16209_core.c | 54 +++++++++++----------
drivers/staging/iio/accel/adis16209_ring.c | 65 ++++++-------------------
drivers/staging/iio/accel/adis16209_trigger.c | 8 ++-
4 files changed, 53 insertions(+), 81 deletions(-)
diff --git a/drivers/staging/iio/accel/adis16209.h b/drivers/staging/iio/accel/adis16209.h
index 92daf6f..84e1a2f 100644
--- a/drivers/staging/iio/accel/adis16209.h
+++ b/drivers/staging/iio/accel/adis16209.h
@@ -113,16 +113,17 @@
* @buf_lock: mutex to protect tx and rx
**/
struct adis16209_state {
+ struct iio_sw_ring_helper_state help;
struct spi_device *us;
- struct work_struct work_trigger_to_ring;
- s64 last_timestamp;
- struct iio_dev *indio_dev;
struct iio_trigger *trig;
u8 *tx;
u8 *rx;
struct mutex buf_lock;
};
+#define adis16209_h_to_s(_h) \
+ container_of(_h, struct adis16209_state, help)
+
int adis16209_set_irq(struct device *dev, bool enable);
#ifdef CONFIG_IIO_RING_BUFFER
diff --git a/drivers/staging/iio/accel/adis16209_core.c b/drivers/staging/iio/accel/adis16209_core.c
index 6c6923f..9c7aafe 100644
--- a/drivers/staging/iio/accel/adis16209_core.c
+++ b/drivers/staging/iio/accel/adis16209_core.c
@@ -21,6 +21,7 @@
#include "../iio.h"
#include "../sysfs.h"
#include "../ring_generic.h"
+#include "../ring_sw.h"
#include "accel.h"
#include "inclinometer.h"
#include "../gyro/gyro.h"
@@ -44,7 +45,8 @@ static int adis16209_spi_write_reg_8(struct device *dev,
{
int ret;
struct iio_dev *indio_dev = dev_get_drvdata(dev);
- struct adis16209_state *st = iio_dev_get_devdata(indio_dev);
+ struct iio_sw_ring_helper_state *h = iio_dev_get_devdata(indio_dev);
+ struct adis16209_state *st = adis16209_h_to_s(h);
mutex_lock(&st->buf_lock);
st->tx[0] = ADIS16209_WRITE_REG(reg_address);
@@ -70,7 +72,8 @@ static int adis16209_spi_write_reg_16(struct device *dev,
int ret;
struct spi_message msg;
struct iio_dev *indio_dev = dev_get_drvdata(dev);
- struct adis16209_state *st = iio_dev_get_devdata(indio_dev);
+ struct iio_sw_ring_helper_state *h = iio_dev_get_devdata(indio_dev);
+ struct adis16209_state *st = adis16209_h_to_s(h);
struct spi_transfer xfers[] = {
{
.tx_buf = st->tx,
@@ -115,7 +118,8 @@ static int adis16209_spi_read_reg_16(struct device *dev,
{
struct spi_message msg;
struct iio_dev *indio_dev = dev_get_drvdata(dev);
- struct adis16209_state *st = iio_dev_get_devdata(indio_dev);
+ struct iio_sw_ring_helper_state *h = iio_dev_get_devdata(indio_dev);
+ struct adis16209_state *st = adis16209_h_to_s(h);
int ret;
struct spi_transfer xfers[] = {
{
@@ -355,7 +359,7 @@ err_ret:
static int adis16209_initial_setup(struct adis16209_state *st)
{
int ret;
- struct device *dev = &st->indio_dev->dev;
+ struct device *dev = &st->help.indio_dev->dev;
/* Disable IRQ */
ret = adis16209_set_irq(dev, false);
@@ -498,30 +502,30 @@ static int __devinit adis16209_probe(struct spi_device *spi)
st->us = spi;
mutex_init(&st->buf_lock);
/* setup the industrialio driver allocated elements */
- st->indio_dev = iio_allocate_device();
- if (st->indio_dev == NULL) {
+ st->help.indio_dev = iio_allocate_device();
+ if (st->help.indio_dev == NULL) {
ret = -ENOMEM;
goto error_free_tx;
}
- st->indio_dev->dev.parent = &spi->dev;
- st->indio_dev->num_interrupt_lines = 1;
- st->indio_dev->event_attrs = &adis16209_event_attribute_group;
- st->indio_dev->attrs = &adis16209_attribute_group;
- st->indio_dev->dev_data = (void *)(st);
- st->indio_dev->driver_module = THIS_MODULE;
- st->indio_dev->modes = INDIO_DIRECT_MODE;
+ st->help.indio_dev->dev.parent = &spi->dev;
+ st->help.indio_dev->num_interrupt_lines = 1;
+ st->help.indio_dev->event_attrs = &adis16209_event_attribute_group;
+ st->help.indio_dev->attrs = &adis16209_attribute_group;
+ st->help.indio_dev->dev_data = (void *)(&st->help);
+ st->help.indio_dev->driver_module = THIS_MODULE;
+ st->help.indio_dev->modes = INDIO_DIRECT_MODE;
- ret = adis16209_configure_ring(st->indio_dev);
+ ret = adis16209_configure_ring(st->help.indio_dev);
if (ret)
goto error_free_dev;
- ret = iio_device_register(st->indio_dev);
+ ret = iio_device_register(st->help.indio_dev);
if (ret)
goto error_unreg_ring_funcs;
regdone = 1;
- ret = iio_ring_buffer_register(st->indio_dev->ring, 0);
+ ret = iio_ring_buffer_register(st->help.indio_dev->ring, 0);
if (ret) {
printk(KERN_ERR "failed to initialize the ring\n");
goto error_unreg_ring_funcs;
@@ -529,14 +533,14 @@ static int __devinit adis16209_probe(struct spi_device *spi)
if (spi->irq) {
ret = iio_register_interrupt_line(spi->irq,
- st->indio_dev,
+ st->help.indio_dev,
0,
IRQF_TRIGGER_RISING,
"adis16209");
if (ret)
goto error_uninitialize_ring;
- ret = adis16209_probe_trigger(st->indio_dev);
+ ret = adis16209_probe_trigger(st->help.indio_dev);
if (ret)
goto error_unregister_line;
}
@@ -548,19 +552,19 @@ static int __devinit adis16209_probe(struct spi_device *spi)
return 0;
error_remove_trigger:
- adis16209_remove_trigger(st->indio_dev);
+ adis16209_remove_trigger(st->help.indio_dev);
error_unregister_line:
if (spi->irq)
- iio_unregister_interrupt_line(st->indio_dev, 0);
+ iio_unregister_interrupt_line(st->help.indio_dev, 0);
error_uninitialize_ring:
- iio_ring_buffer_unregister(st->indio_dev->ring);
+ iio_ring_buffer_unregister(st->help.indio_dev->ring);
error_unreg_ring_funcs:
- adis16209_unconfigure_ring(st->indio_dev);
+ adis16209_unconfigure_ring(st->help.indio_dev);
error_free_dev:
if (regdone)
- iio_device_unregister(st->indio_dev);
+ iio_device_unregister(st->help.indio_dev);
else
- iio_free_device(st->indio_dev);
+ iio_free_device(st->help.indio_dev);
error_free_tx:
kfree(st->tx);
error_free_rx:
@@ -574,7 +578,7 @@ error_ret:
static int adis16209_remove(struct spi_device *spi)
{
struct adis16209_state *st = spi_get_drvdata(spi);
- struct iio_dev *indio_dev = st->indio_dev;
+ struct iio_dev *indio_dev = st->help.indio_dev;
flush_scheduled_work();
diff --git a/drivers/staging/iio/accel/adis16209_ring.c b/drivers/staging/iio/accel/adis16209_ring.c
index 25fde65..bb2389e 100644
--- a/drivers/staging/iio/accel/adis16209_ring.c
+++ b/drivers/staging/iio/accel/adis16209_ring.c
@@ -55,17 +55,6 @@ static struct attribute_group adis16209_scan_el_group = {
};
/**
- * adis16209_poll_func_th() top half interrupt handler called by trigger
- * @private_data: iio_dev
- **/
-static void adis16209_poll_func_th(struct iio_dev *indio_dev, s64 time)
-{
- struct adis16209_state *st = iio_dev_get_devdata(indio_dev);
- st->last_timestamp = time;
- schedule_work(&st->work_trigger_to_ring);
-}
-
-/**
* adis16209_read_ring_data() read data registers which will be placed into ring
* @dev: device associated with child of actual device (iio_dev or iio_trig)
* @rx: somewhere to pass back the value read
@@ -107,44 +96,20 @@ static int adis16209_read_ring_data(struct device *dev, u8 *rx)
return ret;
}
-/* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device
- * specific to be rolled into the core.
- */
-static void adis16209_trigger_bh_to_ring(struct work_struct *work_s)
+static int adis16209_get_ring_element(struct iio_sw_ring_helper_state *h,
+ u8 *buf)
{
- struct adis16209_state *st
- = container_of(work_s, struct adis16209_state,
- work_trigger_to_ring);
-
- int i = 0;
- s16 *data;
- size_t datasize = st->indio_dev
- ->ring->access.get_bpd(st->indio_dev->ring);
-
- data = kmalloc(datasize , GFP_KERNEL);
- if (data == NULL) {
- dev_err(&st->us->dev, "memory alloc failed in ring bh");
- return;
- }
-
- if (st->indio_dev->scan_count)
- if (adis16209_read_ring_data(&st->indio_dev->dev, st->rx) >= 0)
- for (; i < st->indio_dev->scan_count; i++)
- data[i] = be16_to_cpup(
- (__be16 *)&(st->rx[i*2]));
-
- /* Guaranteed to be aligned with 8 byte boundary */
- if (st->indio_dev->scan_timestamp)
- *((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
+ int i, ret;
+ s16 *data = (s16 *)buf;
+ struct adis16209_state *st = adis16209_h_to_s(h);
- st->indio_dev->ring->access.store_to(st->indio_dev->ring,
- (u8 *)data,
- st->last_timestamp);
-
- iio_trigger_notify_done(st->indio_dev->trig);
- kfree(data);
+ ret = adis16209_read_ring_data(&h->indio_dev->dev, st->rx);
+ if (ret < 0)
+ return ret;
+ for (i = 0; i < h->indio_dev->scan_count; i++)
+ data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2]));
- return;
+ return i*sizeof(data[0]);
}
void adis16209_unconfigure_ring(struct iio_dev *indio_dev)
@@ -156,11 +121,11 @@ void adis16209_unconfigure_ring(struct iio_dev *indio_dev)
int adis16209_configure_ring(struct iio_dev *indio_dev)
{
int ret = 0;
- struct adis16209_state *st = indio_dev->dev_data;
struct iio_ring_buffer *ring;
- INIT_WORK(&st->work_trigger_to_ring, adis16209_trigger_bh_to_ring);
+ struct iio_sw_ring_helper_state *h = iio_dev_get_devdata(indio_dev);
+ INIT_WORK(&h->work_trigger_to_ring, iio_sw_trigger_bh_to_ring);
/* Set default scan mode */
-
+ h->get_ring_element = &adis16209_get_ring_element;
iio_scan_mask_set(indio_dev, iio_scan_el_supply.number);
iio_scan_mask_set(indio_dev, iio_scan_el_rot.number);
iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number);
@@ -187,7 +152,7 @@ int adis16209_configure_ring(struct iio_dev *indio_dev)
ring->predisable = &iio_triggered_ring_predisable;
ring->owner = THIS_MODULE;
- ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16209_poll_func_th);
+ ret = iio_alloc_pollfunc(indio_dev, NULL, &iio_sw_poll_func_th);
if (ret)
goto error_iio_sw_rb_free;
diff --git a/drivers/staging/iio/accel/adis16209_trigger.c b/drivers/staging/iio/accel/adis16209_trigger.c
index 1487eff..51cdf4a 100644
--- a/drivers/staging/iio/accel/adis16209_trigger.c
+++ b/drivers/staging/iio/accel/adis16209_trigger.c
@@ -10,6 +10,7 @@
#include "../iio.h"
#include "../sysfs.h"
#include "../trigger.h"
+#include "../ring_sw.h"
#include "adis16209.h"
/**
@@ -48,11 +49,11 @@ static int adis16209_data_rdy_trigger_set_state(struct iio_trigger *trig,
bool state)
{
struct adis16209_state *st = trig->private_data;
- struct iio_dev *indio_dev = st->indio_dev;
+ struct iio_dev *indio_dev = st->help.indio_dev;
int ret = 0;
dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state);
- ret = adis16209_set_irq(&st->indio_dev->dev, state);
+ ret = adis16209_set_irq(&indio_dev->dev, state);
if (state == false) {
iio_remove_event_from_list(&iio_event_data_rdy_trig,
&indio_dev->interrupts[0]
@@ -79,7 +80,8 @@ static int adis16209_trig_try_reen(struct iio_trigger *trig)
int adis16209_probe_trigger(struct iio_dev *indio_dev)
{
int ret;
- struct adis16209_state *st = indio_dev->dev_data;
+ struct iio_sw_ring_helper_state *h = iio_dev_get_devdata(indio_dev);
+ struct adis16209_state *st = adis16209_h_to_s(h);
st->trig = iio_allocate_trigger();
st->trig->name = kasprintf(GFP_KERNEL,
--
1.7.0.4
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 4/5 v2] staging:iio:lis3l02dq use iio_sw_ring_helper_state and funcs
2010-06-30 16:07 [PATCH 4/5 v2] staging:iio:lis3l02dq use iio_sw_ring_helper_state and funcs Jonathan Cameron
2010-06-30 16:07 ` [PATCH 5/5 v2] staging:iio:adis16209 " Jonathan Cameron
@ 2010-07-08 9:32 ` Barry Song
1 sibling, 0 replies; 5+ messages in thread
From: Barry Song @ 2010-07-08 9:32 UTC (permalink / raw)
To: Jonathan Cameron; +Cc: linux-iio, barry.song
T24gVGh1LCBKdWwgMSwgMjAxMCBhdCAxMjowNyBBTSwgSm9uYXRoYW4gQ2FtZXJvbiA8amljMjNA
Y2FtLmFjLnVrPiB3cm90ZToKPiBTaWduZWQtb2ZmLWJ5OiBKb25hdGhhbiBDYW1lcm9uIDxqaWMy
M0BjYW0uYWMudWs+CkFja2VkLWJ5OiBCYXJyeSBTb25nIDwyMWNuYmFvQGdtYWlsLmNvbT4KPiAt
LS0KPgo+IMKgQ291cGxlIG9mIHNpbGx5IGJ1Z3MgZml4ZWQgYW5kIHRoaXMgaGFzIG5vdyBhY3R1
YWxseSBiZWVuIHRlc3RlZCEKPgo+IMKgZHJpdmVycy9zdGFnaW5nL2lpby9hY2NlbC9saXMzbDAy
ZHEuaCDCoCDCoCDCoHwgwqAgMTEgKy0KPiDCoGRyaXZlcnMvc3RhZ2luZy9paW8vYWNjZWwvbGlz
M2wwMmRxX2NvcmUuYyB8IMKgMTE2ICsrKysrKysrKysrKystLS0tLS0tLS0tCj4gwqBkcml2ZXJz
L3N0YWdpbmcvaWlvL2FjY2VsL2xpczNsMDJkcV9yaW5nLmMgfCDCoDEzNyArKysrKysrKysrKy0t
LS0tLS0tLS0tLS0tLS0tCj4gwqAzIGZpbGVzIGNoYW5nZWQsIDEyNCBpbnNlcnRpb25zKCspLCAx
NDAgZGVsZXRpb25zKC0pCj4KPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9zdGFnaW5nL2lpby9hY2Nl
bC9saXMzbDAyZHEuaCBiL2RyaXZlcnMvc3RhZ2luZy9paW8vYWNjZWwvbGlzM2wwMmRxLmgKPiBp
bmRleCA2ZGUxNzJlLi40NDY2OWVlIDEwMDY0NAo+IC0tLSBhL2RyaXZlcnMvc3RhZ2luZy9paW8v
YWNjZWwvbGlzM2wwMmRxLmgKPiArKysgYi9kcml2ZXJzL3N0YWdpbmcvaWlvL2FjY2VsL2xpczNs
MDJkcS5oCj4gQEAgLTE0OCwzMCArMTQ4LDI5IEBAIEZvcm0gb2YgaGlnaCBieXRlIGRlcGVuZGFu
dCBvbiBqdXN0aWZpY2F0aW9uIHNldCBpbiBjdHJsIHJlZyAqLwo+IMKgI2RlZmluZSBMSVMzTDAy
RFFfTUFYX1JYIDEyCj4gwqAvKioKPiDCoCogc3RydWN0IGxpczNsMDJkcV9zdGF0ZSAtIGRldmlj
ZSBpbnN0YW5jZSBzcGVjaWZpYyBkYXRhCj4gKyAqIEBoZWxwZXI6IMKgIMKgIMKgIMKgIMKgIMKg
ZGF0YSBhbmQgZnVuYyBwb2ludGVyIGFsbG93aW5nIGdlbmVyaWMgZnVuY3Rpb25zCj4gwqAqIEB1
czogwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBhY3R1YWwgc3BpX2RldmljZQo+
IC0gKiBAd29ya190cmlnZ2VyX3RvX3Jpbmc6IGJoIGZvciB0cmlnZ2VyZWQgZXZlbnQgaGFuZGxp
bmcKPiDCoCogQHdvcmtfdGhyZXNoOiDCoCDCoCDCoCBiaCBmb3IgdGhyZXNob2xkIGV2ZW50cwo+
IMKgKiBAaW50ZXI6IMKgIMKgIMKgIMKgIMKgIMKgIHVzZWQgdG8gY2hlY2sgaWYgbmV3IGludGVy
cnVwdCBoYXMgYmVlbiB0cmlnZ2VyZWQKPiAtICogQGxhc3RfdGltZXN0YW1wOiDCoCDCoHBhc3Np
bmcgdGltZXN0YW1wIGZyb20gdGggdG8gYmggb2YgaW50ZXJydXB0IGhhbmRsZXIKPiAtICogQGlu
ZGlvX2RldjogwqAgwqAgwqAgwqAgaW5kdXN0cmlhbCBJL08gZGV2aWNlIHN0cnVjdHVyZQo+IMKg
KiBAdHJpZzogwqAgwqAgwqAgwqAgwqAgwqAgwqBkYXRhIHJlYWR5IHRyaWdnZXIgcmVnaXN0ZXJl
ZCB3aXRoIGlpbwo+IMKgKiBAdHg6IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
dHJhbnNtaXQgYnVmZmVyCj4gwqAqIEByeDogwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqByZWNpZXZlIGJ1ZmZlcgo+IMKgKiBAYnVmX2xvY2s6IMKgIMKgIMKgIMKgIMKgbXV0ZXgg
dG8gcHJvdGVjdCB0eCBhbmQgcngKPiDCoCoqLwo+IMKgc3RydWN0IGxpczNsMDJkcV9zdGF0ZSB7
Cj4gKyDCoCDCoCDCoCBzdHJ1Y3QgaWlvX3N3X3JpbmdfaGVscGVyX3N0YXRlIGhlbHA7Cj4gwqAg
wqAgwqAgwqBzdHJ1Y3Qgc3BpX2RldmljZSDCoCDCoCDCoCDCoCDCoCDCoCDCoCAqdXM7Cj4gLSDC
oCDCoCDCoCBzdHJ1Y3Qgd29ya19zdHJ1Y3QgwqAgwqAgwqAgwqAgwqAgwqAgwqB3b3JrX3RyaWdn
ZXJfdG9fcmluZzsKPiDCoCDCoCDCoCDCoHN0cnVjdCB3b3JrX3N0cnVjdCDCoCDCoCDCoCDCoCDC
oCDCoCDCoHdvcmtfdGhyZXNoOwo+IMKgIMKgIMKgIMKgYm9vbCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoGludGVyOwo+IC0gwqAgwqAgwqAgczY0IMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGxhc3RfdGltZXN0YW1wOwo+IC0gwqAgwqAg
wqAgc3RydWN0IGlpb19kZXYgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAqaW5kaW9fZGV2Owo+
IMKgIMKgIMKgIMKgc3RydWN0IGlpb190cmlnZ2VyIMKgIMKgIMKgIMKgIMKgIMKgIMKgKnRyaWc7
Cj4gwqAgwqAgwqAgwqB1OCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCp0eDsKPiDCoCDCoCDCoCDCoHU4IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgKnJ4Owo+IMKgIMKgIMKgIMKgc3RydWN0IG11dGV4IMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgYnVmX2xvY2s7Cj4gwqB9Owo+Cj4gKyNkZWZpbmUgbGlzM2wwMmRxX2hf
dG9fcyhfaCkgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgXAo+ICsgwqAg
wqAgwqAgY29udGFpbmVyX29mKF9oLCBzdHJ1Y3QgbGlzM2wwMmRxX3N0YXRlLCBoZWxwKQo+ICsK
PiDCoGludCBsaXMzbDAyZHFfc3BpX3JlYWRfcmVnXzgoc3RydWN0IGRldmljZSAqZGV2LAo+IMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHU4IHJlZ19hZGRyZXNzLAo+
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHU4ICp2YWwpOwo+IGRp
ZmYgLS1naXQgYS9kcml2ZXJzL3N0YWdpbmcvaWlvL2FjY2VsL2xpczNsMDJkcV9jb3JlLmMgYi9k
cml2ZXJzL3N0YWdpbmcvaWlvL2FjY2VsL2xpczNsMDJkcV9jb3JlLmMKPiBpbmRleCBmODZmZmI4
Li4yY2U4ZDExIDEwMDY0NAo+IC0tLSBhL2RyaXZlcnMvc3RhZ2luZy9paW8vYWNjZWwvbGlzM2ww
MmRxX2NvcmUuYwo+ICsrKyBiL2RyaXZlcnMvc3RhZ2luZy9paW8vYWNjZWwvbGlzM2wwMmRxX2Nv
cmUuYwo+IEBAIC0yOCw2ICsyOCw4IEBACj4gwqAjaW5jbHVkZSAiLi4vaWlvLmgiCj4gwqAjaW5j
bHVkZSAiLi4vc3lzZnMuaCIKPiDCoCNpbmNsdWRlICIuLi9yaW5nX2dlbmVyaWMuaCIKPiArI2lu
Y2x1ZGUgIi4uL3Jpbmdfc3cuaCIKPiArCj4gwqAjaW5jbHVkZSAiYWNjZWwuaCIKPgo+IMKgI2lu
Y2x1ZGUgImxpczNsMDJkcS5oIgo+IEBAIC00OCw3ICs1MCw5IEBAIGludCBsaXMzbDAyZHFfc3Bp
X3JlYWRfcmVnXzgoc3RydWN0IGRldmljZSAqZGV2LCB1OCByZWdfYWRkcmVzcywgdTggKnZhbCkK
PiDCoCDCoCDCoCDCoGludCByZXQ7Cj4gwqAgwqAgwqAgwqBzdHJ1Y3Qgc3BpX21lc3NhZ2UgbXNn
Owo+IMKgIMKgIMKgIMKgc3RydWN0IGlpb19kZXYgKmluZGlvX2RldiA9IGRldl9nZXRfZHJ2ZGF0
YShkZXYpOwo+IC0gwqAgwqAgwqAgc3RydWN0IGxpczNsMDJkcV9zdGF0ZSAqc3QgPSBpaW9fZGV2
X2dldF9kZXZkYXRhKGluZGlvX2Rldik7Cj4gKyDCoCDCoCDCoCBzdHJ1Y3QgaWlvX3N3X3Jpbmdf
aGVscGVyX3N0YXRlICpoID0gaWlvX2Rldl9nZXRfZGV2ZGF0YShpbmRpb19kZXYpOwo+ICsgwqAg
wqAgwqAgc3RydWN0IGxpczNsMDJkcV9zdGF0ZSAqc3QgPSBsaXMzbDAyZHFfaF90b19zKGgpOwo+
ICsKPiDCoCDCoCDCoCDCoHN0cnVjdCBzcGlfdHJhbnNmZXIgeGZlciA9IHsKPiDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoC50eF9idWYgPSBzdC0+dHgsCj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAu
cnhfYnVmID0gc3QtPnJ4LAo+IEBAIC04Myw3ICs4Nyw5IEBAIGludCBsaXMzbDAyZHFfc3BpX3dy
aXRlX3JlZ184KHN0cnVjdCBkZXZpY2UgKmRldiwKPiDCoCDCoCDCoCDCoGludCByZXQ7Cj4gwqAg
wqAgwqAgwqBzdHJ1Y3Qgc3BpX21lc3NhZ2UgbXNnOwo+IMKgIMKgIMKgIMKgc3RydWN0IGlpb19k
ZXYgKmluZGlvX2RldiA9IGRldl9nZXRfZHJ2ZGF0YShkZXYpOwo+IC0gwqAgwqAgwqAgc3RydWN0
IGxpczNsMDJkcV9zdGF0ZSAqc3QgPSBpaW9fZGV2X2dldF9kZXZkYXRhKGluZGlvX2Rldik7Cj4g
KyDCoCDCoCDCoCBzdHJ1Y3QgaWlvX3N3X3JpbmdfaGVscGVyX3N0YXRlICpoCj4gKyDCoCDCoCDC
oCDCoCDCoCDCoCDCoCA9IGlpb19kZXZfZ2V0X2RldmRhdGEoaW5kaW9fZGV2KTsKPiArIMKgIMKg
IMKgIHN0cnVjdCBsaXMzbDAyZHFfc3RhdGUgKnN0ID0gbGlzM2wwMmRxX2hfdG9fcyhoKTsKPiDC
oCDCoCDCoCDCoHN0cnVjdCBzcGlfdHJhbnNmZXIgeGZlciA9IHsKPiDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoC50eF9idWYgPSBzdC0+dHgsCj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAuYml0c19w
ZXJfd29yZCA9IDgsCj4gQEAgLTExNyw3ICsxMjMsOSBAQCBzdGF0aWMgaW50IGxpczNsMDJkcV9z
cGlfd3JpdGVfcmVnX3MxNihzdHJ1Y3QgZGV2aWNlICpkZXYsCj4gwqAgwqAgwqAgwqBpbnQgcmV0
Owo+IMKgIMKgIMKgIMKgc3RydWN0IHNwaV9tZXNzYWdlIG1zZzsKPiDCoCDCoCDCoCDCoHN0cnVj
dCBpaW9fZGV2ICppbmRpb19kZXYgPSBkZXZfZ2V0X2RydmRhdGEoZGV2KTsKPiAtIMKgIMKgIMKg
IHN0cnVjdCBsaXMzbDAyZHFfc3RhdGUgKnN0ID0gaWlvX2Rldl9nZXRfZGV2ZGF0YShpbmRpb19k
ZXYpOwo+ICsgwqAgwqAgwqAgc3RydWN0IGlpb19zd19yaW5nX2hlbHBlcl9zdGF0ZSAqaAo+ICsg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgPSBpaW9fZGV2X2dldF9kZXZkYXRhKGluZGlvX2Rldik7Cj4g
KyDCoCDCoCDCoCBzdHJ1Y3QgbGlzM2wwMmRxX3N0YXRlICpzdCA9IGxpczNsMDJkcV9oX3RvX3Mo
aCk7Cj4gwqAgwqAgwqAgwqBzdHJ1Y3Qgc3BpX3RyYW5zZmVyIHhmZXJzW10gPSB7IHsKPiDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoC50eF9idWYgPSBzdC0+dHgsCj4gwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAuYml0c19wZXJfd29yZCA9IDgsCj4gQEAgLTE1
OSw3ICsxNjcsOSBAQCBzdGF0aWMgaW50IGxpczNsMDJkcV9zcGlfcmVhZF9yZWdfczE2KHN0cnVj
dCBkZXZpY2UgKmRldiwKPiDCoHsKPiDCoCDCoCDCoCDCoHN0cnVjdCBzcGlfbWVzc2FnZSBtc2c7
Cj4gwqAgwqAgwqAgwqBzdHJ1Y3QgaWlvX2RldiAqaW5kaW9fZGV2ID0gZGV2X2dldF9kcnZkYXRh
KGRldik7Cj4gLSDCoCDCoCDCoCBzdHJ1Y3QgbGlzM2wwMmRxX3N0YXRlICpzdCA9IGlpb19kZXZf
Z2V0X2RldmRhdGEoaW5kaW9fZGV2KTsKPiArIMKgIMKgIMKgIHN0cnVjdCBpaW9fc3dfcmluZ19o
ZWxwZXJfc3RhdGUgKmgKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgID0gaWlvX2Rldl9nZXRfZGV2
ZGF0YShpbmRpb19kZXYpOwo+ICsgwqAgwqAgwqAgc3RydWN0IGxpczNsMDJkcV9zdGF0ZSAqc3Qg
PSBsaXMzbDAyZHFfaF90b19zKGgpOwo+IMKgIMKgIMKgIMKgaW50IHJldDsKPiDCoCDCoCDCoCDC
oHN0cnVjdCBzcGlfdHJhbnNmZXIgeGZlcnNbXSA9IHsgewo+IMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgLnR4X2J1ZiA9IHN0LT50eCwKPiBAQCAtNDEyLDcgKzQyMiw3IEBAIHN0
YXRpYyBpbnQgbGlzM2wwMmRxX2luaXRpYWxfc2V0dXAoc3RydWN0IGxpczNsMDJkcV9zdGF0ZSAq
c3QpCj4KPiDCoCDCoCDCoCDCoHZhbCA9IExJUzNMMDJEUV9ERUZBVUxUX0NUUkwxOwo+IMKgIMKg
IMKgIMKgLyogV3JpdGUgc3VpdGFibGUgZGVmYXVsdHMgdG8gY3RybDEgKi8KPiAtIMKgIMKgIMKg
IHJldCA9IGxpczNsMDJkcV9zcGlfd3JpdGVfcmVnXzgoJnN0LT5pbmRpb19kZXYtPmRldiwKPiAr
IMKgIMKgIMKgIHJldCA9IGxpczNsMDJkcV9zcGlfd3JpdGVfcmVnXzgoJnN0LT5oZWxwLmluZGlv
X2Rldi0+ZGV2LAo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgTElTM0wwMkRRX1JFR19DVFJMXzFfQUREUiwKPiDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCZ2YWwpOwo+IMKg
IMKgIMKgIMKgaWYgKHJldCkgewo+IEBAIC00MjAsNyArNDMwLDcgQEAgc3RhdGljIGludCBsaXMz
bDAyZHFfaW5pdGlhbF9zZXR1cChzdHJ1Y3QgbGlzM2wwMmRxX3N0YXRlICpzdCkKPiDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoGdvdG8gZXJyX3JldDsKPiDCoCDCoCDCoCDCoH0KPiDCoCDCoCDCoCDC
oC8qIFJlcGVhdCBhcyBzb21ldGltZXMgZG9lc24ndCB3b3JrIGZpcnN0IHRpbWU/Ki8KPiAtIMKg
IMKgIMKgIHJldCA9IGxpczNsMDJkcV9zcGlfd3JpdGVfcmVnXzgoJnN0LT5pbmRpb19kZXYtPmRl
diwKPiArIMKgIMKgIMKgIHJldCA9IGxpczNsMDJkcV9zcGlfd3JpdGVfcmVnXzgoJnN0LT5oZWxw
LmluZGlvX2Rldi0+ZGV2LAo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgTElTM0wwMkRRX1JFR19DVFJMXzFfQUREUiwKPiDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCZ2YWwp
Owo+IMKgIMKgIMKgIMKgaWYgKHJldCkgewo+IEBAIC00MzAsMTcgKzQ0MCwxNyBAQCBzdGF0aWMg
aW50IGxpczNsMDJkcV9pbml0aWFsX3NldHVwKHN0cnVjdCBsaXMzbDAyZHFfc3RhdGUgKnN0KQo+
Cj4gwqAgwqAgwqAgwqAvKiBSZWFkIGJhY2sgdG8gY2hlY2sgdGhpcyBoYXMgd29ya2VkIGFjdHMg
YXMgbG9vc2UgdGVzdCBvZiBjb3JyZWN0Cj4gwqAgwqAgwqAgwqAgKiBjaGlwICovCj4gLSDCoCDC
oCDCoCByZXQgPSBsaXMzbDAyZHFfc3BpX3JlYWRfcmVnXzgoJnN0LT5pbmRpb19kZXYtPmRldiwK
PiArIMKgIMKgIMKgIHJldCA9IGxpczNsMDJkcV9zcGlfcmVhZF9yZWdfOCgmc3QtPmhlbHAuaW5k
aW9fZGV2LT5kZXYsCj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgTElTM0wwMkRRX1JFR19DVFJMXzFfQUREUiwKPiDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAmdmFsdGVzdCk7Cj4g
wqAgwqAgwqAgwqBpZiAocmV0IHx8ICh2YWx0ZXN0ICE9IHZhbCkpIHsKPiAtIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIGRldl9lcnIoJnN0LT5pbmRpb19kZXYtPmRldiwgImRldmljZSBub3QgcGxheWlu
ZyBiYWxsIik7Cj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCBkZXZfZXJyKCZzdC0+aGVscC5pbmRp
b19kZXYtPmRldiwgImRldmljZSBub3QgcGxheWluZyBiYWxsIik7Cj4gwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqByZXQgPSAtRUlOVkFMOwo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgZ290byBlcnJf
cmV0Owo+IMKgIMKgIMKgIMKgfQo+Cj4gwqAgwqAgwqAgwqB2YWwgPSBMSVMzTDAyRFFfREVGQVVM
VF9DVFJMMjsKPiAtIMKgIMKgIMKgIHJldCA9IGxpczNsMDJkcV9zcGlfd3JpdGVfcmVnXzgoJnN0
LT5pbmRpb19kZXYtPmRldiwKPiArIMKgIMKgIMKgIHJldCA9IGxpczNsMDJkcV9zcGlfd3JpdGVf
cmVnXzgoJnN0LT5oZWxwLmluZGlvX2Rldi0+ZGV2LAo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgTElTM0wwMkRRX1JFR19DVFJMXzJf
QUREUiwKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCZ2YWwpOwo+IMKgIMKgIMKgIMKgaWYgKHJldCkgewo+IEBAIC00NDksNyArNDU5
LDcgQEAgc3RhdGljIGludCBsaXMzbDAyZHFfaW5pdGlhbF9zZXR1cChzdHJ1Y3QgbGlzM2wwMmRx
X3N0YXRlICpzdCkKPiDCoCDCoCDCoCDCoH0KPgo+IMKgIMKgIMKgIMKgdmFsID0gTElTM0wwMkRR
X1JFR19XQUtFX1VQX0NGR19MQVRDSF9TUkM7Cj4gLSDCoCDCoCDCoCByZXQgPSBsaXMzbDAyZHFf
c3BpX3dyaXRlX3JlZ184KCZzdC0+aW5kaW9fZGV2LT5kZXYsCj4gKyDCoCDCoCDCoCByZXQgPSBs
aXMzbDAyZHFfc3BpX3dyaXRlX3JlZ184KCZzdC0+aGVscC5pbmRpb19kZXYtPmRldiwKPiDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoExJ
UzNMMDJEUV9SRUdfV0FLRV9VUF9DRkdfQUREUiwKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCZ2YWwpOwo+IMKgIMKgIMKgIMKgaWYg
KHJldCkKPiBAQCAtNTk1LDE1ICs2MDUsMTcgQEAgZXJyb3JfbXV0ZXhfdW5sb2NrOgo+IMKgfQo+
Cj4KPiAtc3RhdGljIGludCBsaXMzbDAyZHFfdGhyZXNoX2hhbmRsZXJfdGgoc3RydWN0IGlpb19k
ZXYgKmRldl9pbmZvLAo+ICtzdGF0aWMgaW50IGxpczNsMDJkcV90aHJlc2hfaGFuZGxlcl90aChz
dHJ1Y3QgaWlvX2RldiAqaW5kaW9fZGV2LAo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGludCBpbmRleCwKPiDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBzNjQgdGltZXN0YW1wLAo+
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IGludCBub190ZXN0KQo+IMKgewo+IC0gwqAgwqAgwqAgc3RydWN0IGxpczNsMDJkcV9zdGF0ZSAq
c3QgPSBkZXZfaW5mby0+ZGV2X2RhdGE7Cj4gKyDCoCDCoCDCoCBzdHJ1Y3QgaWlvX3N3X3Jpbmdf
aGVscGVyX3N0YXRlICpoCj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCA9IGlpb19kZXZfZ2V0X2Rl
dmRhdGEoaW5kaW9fZGV2KTsKPiArIMKgIMKgIMKgIHN0cnVjdCBsaXMzbDAyZHFfc3RhdGUgKnN0
ID0gbGlzM2wwMmRxX2hfdG9fcyhoKTsKPgo+IMKgIMKgIMKgIMKgLyogU3Rhc2ggdGhlIHRpbWVz
dGFtcCBzb21ld2hlcmUgY29udmVuaWVudCBmb3IgdGhlIGJoICovCj4gLSDCoCDCoCDCoCBzdC0+
bGFzdF90aW1lc3RhbXAgPSB0aW1lc3RhbXA7Cj4gKyDCoCDCoCDCoCBoLT5sYXN0X3RpbWVzdGFt
cCA9IHRpbWVzdGFtcDsKPiDCoCDCoCDCoCDCoHNjaGVkdWxlX3dvcmsoJnN0LT53b3JrX3RocmVz
aCk7Cj4KPiDCoCDCoCDCoCDCoHJldHVybiAwOwo+IEBAIC02MjEsNDMgKzYzMyw0MyBAQCBzdGF0
aWMgdm9pZCBsaXMzbDAyZHFfdGhyZXNoX2hhbmRsZXJfYmhfbm9fY2hlY2soc3RydWN0IHdvcmtf
c3RydWN0ICp3b3JrX3MpCj4KPiDCoCDCoCDCoCDCoHU4IHQ7Cj4KPiAtIMKgIMKgIMKgIGxpczNs
MDJkcV9zcGlfcmVhZF9yZWdfOCgmc3QtPmluZGlvX2Rldi0+ZGV2LAo+ICsgwqAgwqAgwqAgbGlz
M2wwMmRxX3NwaV9yZWFkX3JlZ184KCZzdC0+aGVscC5pbmRpb19kZXYtPmRldiwKPiDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBMSVMzTDAyRFFfUkVHX1dB
S0VfVVBfU1JDX0FERFIsCj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgJnQpOwo+Cj4gwqAgwqAgwqAgwqBpZiAodCAmIExJUzNMMDJEUV9SRUdfV0FLRV9V
UF9TUkNfSU5URVJSVVBUX1pfSElHSCkKPiAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGlpb19wdXNo
X2V2ZW50KHN0LT5pbmRpb19kZXYsIDAsCj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCBpaW9fcHVz
aF9ldmVudChzdC0+aGVscC5pbmRpb19kZXYsIDAsCj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgSUlPX0VWRU5UX0NPREVfQUNDRUxfWl9ISUdILAo+IC0gwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBzdC0+bGFzdF90aW1lc3Rh
bXApOwo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBzdC0+
aGVscC5sYXN0X3RpbWVzdGFtcCk7Cj4KPiDCoCDCoCDCoCDCoGlmICh0ICYgTElTM0wwMkRRX1JF
R19XQUtFX1VQX1NSQ19JTlRFUlJVUFRfWl9MT1cpCj4gLSDCoCDCoCDCoCDCoCDCoCDCoCDCoCBp
aW9fcHVzaF9ldmVudChzdC0+aW5kaW9fZGV2LCAwLAo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
aWlvX3B1c2hfZXZlbnQoc3QtPmhlbHAuaW5kaW9fZGV2LCAwLAo+IMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIElJT19FVkVOVF9DT0RFX0FDQ0VMX1pfTE9XLAo+
IC0gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBzdC0+bGFzdF90
aW1lc3RhbXApOwo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqBzdC0+aGVscC5sYXN0X3RpbWVzdGFtcCk7Cj4KPiDCoCDCoCDCoCDCoGlmICh0ICYgTElTM0ww
MkRRX1JFR19XQUtFX1VQX1NSQ19JTlRFUlJVUFRfWV9ISUdIKQo+IC0gwqAgwqAgwqAgwqAgwqAg
wqAgwqAgaWlvX3B1c2hfZXZlbnQoc3QtPmluZGlvX2RldiwgMCwKPiArIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIGlpb19wdXNoX2V2ZW50KHN0LT5oZWxwLmluZGlvX2RldiwgMCwKPiDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBJSU9fRVZFTlRfQ09ERV9BQ0NFTF9Z
X0hJR0gsCj4gLSDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHN0
LT5sYXN0X3RpbWVzdGFtcCk7Cj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoHN0LT5oZWxwLmxhc3RfdGltZXN0YW1wKTsKPgo+IMKgIMKgIMKgIMKgaWYgKHQg
JiBMSVMzTDAyRFFfUkVHX1dBS0VfVVBfU1JDX0lOVEVSUlVQVF9ZX0xPVykKPiAtIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIGlpb19wdXNoX2V2ZW50KHN0LT5pbmRpb19kZXYsIDAsCj4gKyDCoCDCoCDC
oCDCoCDCoCDCoCDCoCBpaW9fcHVzaF9ldmVudChzdC0+aGVscC5pbmRpb19kZXYsIDAsCj4gwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgSUlPX0VWRU5UX0NPREVf
QUNDRUxfWV9MT1csCj4gLSDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoHN0LT5sYXN0X3RpbWVzdGFtcCk7Cj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoHN0LT5oZWxwLmxhc3RfdGltZXN0YW1wKTsKPgo+IMKgIMKgIMKgIMKg
aWYgKHQgJiBMSVMzTDAyRFFfUkVHX1dBS0VfVVBfU1JDX0lOVEVSUlVQVF9YX0hJR0gpCj4gLSDC
oCDCoCDCoCDCoCDCoCDCoCDCoCBpaW9fcHVzaF9ldmVudChzdC0+aW5kaW9fZGV2LCAwLAo+ICsg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgaWlvX3B1c2hfZXZlbnQoc3QtPmhlbHAuaW5kaW9fZGV2LCAw
LAo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIElJT19FVkVO
VF9DT0RFX0FDQ0VMX1hfSElHSCwKPiAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgc3QtPmxhc3RfdGltZXN0YW1wKTsKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgc3QtPmhlbHAubGFzdF90aW1lc3RhbXApOwo+Cj4gwqAg
wqAgwqAgwqBpZiAodCAmIExJUzNMMDJEUV9SRUdfV0FLRV9VUF9TUkNfSU5URVJSVVBUX1hfTE9X
KQo+IC0gwqAgwqAgwqAgwqAgwqAgwqAgwqAgaWlvX3B1c2hfZXZlbnQoc3QtPmluZGlvX2Rldiwg
MCwKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGlpb19wdXNoX2V2ZW50KHN0LT5oZWxwLmluZGlv
X2RldiwgMCwKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBJ
SU9fRVZFTlRfQ09ERV9BQ0NFTF9YX0xPVywKPiAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgc3QtPmxhc3RfdGltZXN0YW1wKTsKPiArIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgc3QtPmhlbHAubGFzdF90aW1lc3RhbXApOwo+
IMKgIMKgIMKgIMKgLyogcmVlbmFibGUgdGhlIGlycSAqLwo+IMKgIMKgIMKgIMKgZW5hYmxlX2ly
cShzdC0+dXMtPmlycSk7Cj4gwqAgwqAgwqAgwqAvKiBBY2sgYW5kIGFsbG93IGZvciBuZXcgaW50
ZXJydXB0cyAqLwo+IC0gwqAgwqAgwqAgbGlzM2wwMmRxX3NwaV9yZWFkX3JlZ184KCZzdC0+aW5k
aW9fZGV2LT5kZXYsCj4gKyDCoCDCoCDCoCBsaXMzbDAyZHFfc3BpX3JlYWRfcmVnXzgoJnN0LT5o
ZWxwLmluZGlvX2Rldi0+ZGV2LAo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIExJUzNMMDJEUV9SRUdfV0FLRV9VUF9BQ0tfQUREUiwKPiDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAmdCk7Cj4KPiBAQCAtNzY5LDMw
ICs3ODEsMzAgQEAgc3RhdGljIGludCBfX2RldmluaXQgbGlzM2wwMmRxX3Byb2JlKHN0cnVjdCBz
cGlfZGV2aWNlICpzcGkpCj4gwqAgwqAgwqAgwqBzdC0+dXMgPSBzcGk7Cj4gwqAgwqAgwqAgwqBt
dXRleF9pbml0KCZzdC0+YnVmX2xvY2spOwo+IMKgIMKgIMKgIMKgLyogc2V0dXAgdGhlIGluZHVz
dHJpYWxpbyBkcml2ZXIgYWxsb2NhdGVkIGVsZW1lbnRzICovCj4gLSDCoCDCoCDCoCBzdC0+aW5k
aW9fZGV2ID0gaWlvX2FsbG9jYXRlX2RldmljZSgpOwo+IC0gwqAgwqAgwqAgaWYgKHN0LT5pbmRp
b19kZXYgPT0gTlVMTCkgewo+ICsgwqAgwqAgwqAgc3QtPmhlbHAuaW5kaW9fZGV2ID0gaWlvX2Fs
bG9jYXRlX2RldmljZSgpOwo+ICsgwqAgwqAgwqAgaWYgKHN0LT5oZWxwLmluZGlvX2RldiA9PSBO
VUxMKSB7Cj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqByZXQgPSAtRU5PTUVNOwo+IMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgZ290byBlcnJvcl9mcmVlX3R4Owo+IMKgIMKgIMKgIMKgfQo+Cj4gLSDC
oCDCoCDCoCBzdC0+aW5kaW9fZGV2LT5kZXYucGFyZW50ID0gJnNwaS0+ZGV2Owo+IC0gwqAgwqAg
wqAgc3QtPmluZGlvX2Rldi0+bnVtX2ludGVycnVwdF9saW5lcyA9IDE7Cj4gLSDCoCDCoCDCoCBz
dC0+aW5kaW9fZGV2LT5ldmVudF9hdHRycyA9ICZsaXMzbDAyZHFfZXZlbnRfYXR0cmlidXRlX2dy
b3VwOwo+IC0gwqAgwqAgwqAgc3QtPmluZGlvX2Rldi0+YXR0cnMgPSAmbGlzM2wwMmRxX2F0dHJp
YnV0ZV9ncm91cDsKPiAtIMKgIMKgIMKgIHN0LT5pbmRpb19kZXYtPmRldl9kYXRhID0gKHZvaWQg
Kikoc3QpOwo+IC0gwqAgwqAgwqAgc3QtPmluZGlvX2Rldi0+ZHJpdmVyX21vZHVsZSA9IFRISVNf
TU9EVUxFOwo+IC0gwqAgwqAgwqAgc3QtPmluZGlvX2Rldi0+bW9kZXMgPSBJTkRJT19ESVJFQ1Rf
TU9ERTsKPiArIMKgIMKgIMKgIHN0LT5oZWxwLmluZGlvX2Rldi0+ZGV2LnBhcmVudCA9ICZzcGkt
PmRldjsKPiArIMKgIMKgIMKgIHN0LT5oZWxwLmluZGlvX2Rldi0+bnVtX2ludGVycnVwdF9saW5l
cyA9IDE7Cj4gKyDCoCDCoCDCoCBzdC0+aGVscC5pbmRpb19kZXYtPmV2ZW50X2F0dHJzID0gJmxp
czNsMDJkcV9ldmVudF9hdHRyaWJ1dGVfZ3JvdXA7Cj4gKyDCoCDCoCDCoCBzdC0+aGVscC5pbmRp
b19kZXYtPmF0dHJzID0gJmxpczNsMDJkcV9hdHRyaWJ1dGVfZ3JvdXA7Cj4gKyDCoCDCoCDCoCBz
dC0+aGVscC5pbmRpb19kZXYtPmRldl9kYXRhID0gKHZvaWQgKikoJnN0LT5oZWxwKTsKPiArIMKg
IMKgIMKgIHN0LT5oZWxwLmluZGlvX2Rldi0+ZHJpdmVyX21vZHVsZSA9IFRISVNfTU9EVUxFOwo+
ICsgwqAgwqAgwqAgc3QtPmhlbHAuaW5kaW9fZGV2LT5tb2RlcyA9IElORElPX0RJUkVDVF9NT0RF
Owo+Cj4gLSDCoCDCoCDCoCByZXQgPSBsaXMzbDAyZHFfY29uZmlndXJlX3Jpbmcoc3QtPmluZGlv
X2Rldik7Cj4gKyDCoCDCoCDCoCByZXQgPSBsaXMzbDAyZHFfY29uZmlndXJlX3Jpbmcoc3QtPmhl
bHAuaW5kaW9fZGV2KTsKPiDCoCDCoCDCoCDCoGlmIChyZXQpCj4gwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqBnb3RvIGVycm9yX2ZyZWVfZGV2Owo+Cj4gLSDCoCDCoCDCoCByZXQgPSBpaW9fZGV2aWNl
X3JlZ2lzdGVyKHN0LT5pbmRpb19kZXYpOwo+ICsgwqAgwqAgwqAgcmV0ID0gaWlvX2RldmljZV9y
ZWdpc3RlcihzdC0+aGVscC5pbmRpb19kZXYpOwo+IMKgIMKgIMKgIMKgaWYgKHJldCkKPiDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoGdvdG8gZXJyb3JfdW5yZWdfcmluZ19mdW5jczsKPiDCoCDCoCDC
oCDCoHJlZ2RvbmUgPSAxOwo+Cj4gLSDCoCDCoCDCoCByZXQgPSBpaW9fcmluZ19idWZmZXJfcmVn
aXN0ZXIoc3QtPmluZGlvX2Rldi0+cmluZywgMCk7Cj4gKyDCoCDCoCDCoCByZXQgPSBpaW9fcmlu
Z19idWZmZXJfcmVnaXN0ZXIoc3QtPmhlbHAuaW5kaW9fZGV2LT5yaW5nLCAwKTsKPiDCoCDCoCDC
oCDCoGlmIChyZXQpIHsKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHByaW50ayhLRVJOX0VSUiAi
ZmFpbGVkIHRvIGluaXRpYWxpemUgdGhlIHJpbmdcbiIpOwo+IMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgZ290byBlcnJvcl91bnJlZ19yaW5nX2Z1bmNzOwo+IEBAIC04MDEsMTQgKzgxMywxNCBAQCBz
dGF0aWMgaW50IF9fZGV2aW5pdCBsaXMzbDAyZHFfcHJvYmUoc3RydWN0IHNwaV9kZXZpY2UgKnNw
aSkKPiDCoCDCoCDCoCDCoGlmIChzcGktPmlycSAmJiBncGlvX2lzX3ZhbGlkKGlycV90b19ncGlv
KHNwaS0+aXJxKSkgPiAwKSB7Cj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBzdC0+aW50ZXIgPSAw
Owo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgcmV0ID0gaWlvX3JlZ2lzdGVyX2ludGVycnVwdF9s
aW5lKHNwaS0+aXJxLAo+IC0gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgc3QtPmluZGlvX2RldiwKPiArIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIHN0LT5oZWxwLmluZGlvX2RldiwKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoDAsCj4gwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqBJUlFGX1RSSUdHRVJfUklTSU5HLAo+IMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgImxp
czNsMDJkcSIpOwo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgaWYgKHJldCkKPiDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGdvdG8gZXJyb3JfdW5pbml0aWFsaXplX3Jpbmc7Cj4K
PiAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHJldCA9IGxpczNsMDJkcV9wcm9iZV90cmlnZ2VyKHN0
LT5pbmRpb19kZXYpOwo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgcmV0ID0gbGlzM2wwMmRxX3By
b2JlX3RyaWdnZXIoc3QtPmhlbHAuaW5kaW9fZGV2KTsKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oGlmIChyZXQpCj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBnb3RvIGVycm9y
X3VucmVnaXN0ZXJfbGluZTsKPiDCoCDCoCDCoCDCoH0KPiBAQCAtODIwLDIwICs4MzIsMjAgQEAg
c3RhdGljIGludCBfX2RldmluaXQgbGlzM2wwMmRxX3Byb2JlKHN0cnVjdCBzcGlfZGV2aWNlICpz
cGkpCj4gwqAgwqAgwqAgwqByZXR1cm4gMDsKPgo+IMKgZXJyb3JfcmVtb3ZlX3RyaWdnZXI6Cj4g
LSDCoCDCoCDCoCBpZiAoc3QtPmluZGlvX2Rldi0+bW9kZXMgJiBJTkRJT19SSU5HX1RSSUdHRVJF
RCkKPiAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGxpczNsMDJkcV9yZW1vdmVfdHJpZ2dlcihzdC0+
aW5kaW9fZGV2KTsKPiArIMKgIMKgIMKgIGlmIChzdC0+aGVscC5pbmRpb19kZXYtPm1vZGVzICYg
SU5ESU9fUklOR19UUklHR0VSRUQpCj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCBsaXMzbDAyZHFf
cmVtb3ZlX3RyaWdnZXIoc3QtPmhlbHAuaW5kaW9fZGV2KTsKPiDCoGVycm9yX3VucmVnaXN0ZXJf
bGluZToKPiAtIMKgIMKgIMKgIGlmIChzdC0+aW5kaW9fZGV2LT5tb2RlcyAmIElORElPX1JJTkdf
VFJJR0dFUkVEKQo+IC0gwqAgwqAgwqAgwqAgwqAgwqAgwqAgaWlvX3VucmVnaXN0ZXJfaW50ZXJy
dXB0X2xpbmUoc3QtPmluZGlvX2RldiwgMCk7Cj4gKyDCoCDCoCDCoCBpZiAoc3QtPmhlbHAuaW5k
aW9fZGV2LT5tb2RlcyAmIElORElPX1JJTkdfVFJJR0dFUkVEKQo+ICsgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgaWlvX3VucmVnaXN0ZXJfaW50ZXJydXB0X2xpbmUoc3QtPmhlbHAuaW5kaW9fZGV2LCAw
KTsKPiDCoGVycm9yX3VuaW5pdGlhbGl6ZV9yaW5nOgo+IC0gwqAgwqAgwqAgaWlvX3JpbmdfYnVm
ZmVyX3VucmVnaXN0ZXIoc3QtPmluZGlvX2Rldi0+cmluZyk7Cj4gKyDCoCDCoCDCoCBpaW9fcmlu
Z19idWZmZXJfdW5yZWdpc3RlcihzdC0+aGVscC5pbmRpb19kZXYtPnJpbmcpOwo+IMKgZXJyb3Jf
dW5yZWdfcmluZ19mdW5jczoKPiAtIMKgIMKgIMKgIGxpczNsMDJkcV91bmNvbmZpZ3VyZV9yaW5n
KHN0LT5pbmRpb19kZXYpOwo+ICsgwqAgwqAgwqAgbGlzM2wwMmRxX3VuY29uZmlndXJlX3Jpbmco
c3QtPmhlbHAuaW5kaW9fZGV2KTsKPiDCoGVycm9yX2ZyZWVfZGV2Ogo+IMKgIMKgIMKgIMKgaWYg
KHJlZ2RvbmUpCj4gLSDCoCDCoCDCoCDCoCDCoCDCoCDCoCBpaW9fZGV2aWNlX3VucmVnaXN0ZXIo
c3QtPmluZGlvX2Rldik7Cj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCBpaW9fZGV2aWNlX3VucmVn
aXN0ZXIoc3QtPmhlbHAuaW5kaW9fZGV2KTsKPiDCoCDCoCDCoCDCoGVsc2UKPiAtIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIGlpb19mcmVlX2RldmljZShzdC0+aW5kaW9fZGV2KTsKPiArIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIGlpb19mcmVlX2RldmljZShzdC0+aGVscC5pbmRpb19kZXYpOwo+IMKgZXJy
b3JfZnJlZV90eDoKPiDCoCDCoCDCoCDCoGtmcmVlKHN0LT50eCk7Cj4gwqBlcnJvcl9mcmVlX3J4
Ogo+IEBAIC04NDgsNyArODYwLDkgQEAgZXJyb3JfcmV0Ogo+IMKgc3RhdGljIGludCBsaXMzbDAy
ZHFfc3RvcF9kZXZpY2Uoc3RydWN0IGlpb19kZXYgKmluZGlvX2RldikKPiDCoHsKPiDCoCDCoCDC
oCDCoGludCByZXQ7Cj4gLSDCoCDCoCDCoCBzdHJ1Y3QgbGlzM2wwMmRxX3N0YXRlICpzdCA9IGlu
ZGlvX2Rldi0+ZGV2X2RhdGE7Cj4gKyDCoCDCoCDCoCBzdHJ1Y3QgaWlvX3N3X3JpbmdfaGVscGVy
X3N0YXRlICpoCj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCA9IGlpb19kZXZfZ2V0X2RldmRhdGEo
aW5kaW9fZGV2KTsKPiArIMKgIMKgIMKgIHN0cnVjdCBsaXMzbDAyZHFfc3RhdGUgKnN0ID0gbGlz
M2wwMmRxX2hfdG9fcyhoKTsKPiDCoCDCoCDCoCDCoHU4IHZhbCA9IDA7Cj4KPiDCoCDCoCDCoCDC
oG11dGV4X2xvY2soJmluZGlvX2Rldi0+bWxvY2spOwo+IEBAIC04NzUsNyArODg5LDcgQEAgc3Rh
dGljIGludCBsaXMzbDAyZHFfcmVtb3ZlKHN0cnVjdCBzcGlfZGV2aWNlICpzcGkpCj4gwqB7Cj4g
wqAgwqAgwqAgwqBpbnQgcmV0Owo+IMKgIMKgIMKgIMKgc3RydWN0IGxpczNsMDJkcV9zdGF0ZSAq
c3QgPSBzcGlfZ2V0X2RydmRhdGEoc3BpKTsKPiAtIMKgIMKgIMKgIHN0cnVjdCBpaW9fZGV2ICpp
bmRpb19kZXYgPSBzdC0+aW5kaW9fZGV2Owo+ICsgwqAgwqAgwqAgc3RydWN0IGlpb19kZXYgKmlu
ZGlvX2RldiA9IHN0LT5oZWxwLmluZGlvX2RldjsKPgo+IMKgIMKgIMKgIMKgcmV0ID0gbGlzM2ww
MmRxX3N0b3BfZGV2aWNlKGluZGlvX2Rldik7Cj4gwqAgwqAgwqAgwqBpZiAocmV0KQo+IGRpZmYg
LS1naXQgYS9kcml2ZXJzL3N0YWdpbmcvaWlvL2FjY2VsL2xpczNsMDJkcV9yaW5nLmMgYi9kcml2
ZXJzL3N0YWdpbmcvaWlvL2FjY2VsL2xpczNsMDJkcV9yaW5nLmMKPiBpbmRleCAyYzExMjA5Li5k
ZDg0MGVlIDEwMDY0NAo+IC0tLSBhL2RyaXZlcnMvc3RhZ2luZy9paW8vYWNjZWwvbGlzM2wwMmRx
X3JpbmcuYwo+ICsrKyBiL2RyaXZlcnMvc3RhZ2luZy9paW8vYWNjZWwvbGlzM2wwMmRxX3Jpbmcu
Ywo+IEBAIC0xMDUsMTEgKzEwNSwxMyBAQCBzdGF0aWMgc3RydWN0IGF0dHJpYnV0ZV9ncm91cCBs
aXMzbDAyZHFfc2Nhbl9lbF9ncm91cCA9IHsKPiDCoCoqLwo+IMKgc3RhdGljIHZvaWQgbGlzM2ww
MmRxX3BvbGxfZnVuY190aChzdHJ1Y3QgaWlvX2RldiAqaW5kaW9fZGV2LCBzNjQgdGltZSkKPiDC
oHsKPiAtIMKgIMKgIMKgIHN0cnVjdCBsaXMzbDAyZHFfc3RhdGUgKnN0ID0gaWlvX2Rldl9nZXRf
ZGV2ZGF0YShpbmRpb19kZXYpOwo+IC0gwqAgwqAgwqAgc3QtPmxhc3RfdGltZXN0YW1wID0gdGlt
ZTsKPiAtIMKgIMKgIMKgIHNjaGVkdWxlX3dvcmsoJnN0LT53b3JrX3RyaWdnZXJfdG9fcmluZyk7
Cj4gLSDCoCDCoCDCoCAvKiBJbmRpY2F0ZSB0aGF0IHRoaXMgaW50ZXJydXB0IGlzIGJlaW5nIGhh
bmRsZWQgKi8KPiArIMKgIMKgIMKgIHN0cnVjdCBpaW9fc3dfcmluZ19oZWxwZXJfc3RhdGUgKmgK
PiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgID0gaWlvX2Rldl9nZXRfZGV2ZGF0YShpbmRpb19kZXYp
Owo+ICsgwqAgwqAgwqAgc3RydWN0IGxpczNsMDJkcV9zdGF0ZSAqc3QgPSBsaXMzbDAyZHFfaF90
b19zKGgpOwo+ICsgwqAgwqAgwqAgLyogaW4gdGhpcyBjYXNlIHdlIG5lZWQgdG8gc2xpZ2h0bHkg
ZXh0ZW5kIHRoZSBoZWxwZXIgZnVuY3Rpb24gKi8KPiArIMKgIMKgIMKgIGlpb19zd19wb2xsX2Z1
bmNfdGgoaW5kaW9fZGV2LCB0aW1lKTsKPgo+ICsgwqAgwqAgwqAgLyogSW5kaWNhdGUgdGhhdCB0
aGlzIGludGVycnVwdCBpcyBiZWluZyBoYW5kbGVkICovCj4gwqAgwqAgwqAgwqAvKiBUZWNobmlj
YWxseSB0aGlzIGlzIHRyaWdnZXIgcmVsYXRlZCwgYnV0IHdpdGhvdXQgdGhpcwo+IMKgIMKgIMKg
IMKgICogaGFuZGxlciBydW5uaW5nIHRoZXJlIGlzIGN1cnJlbnRseSBub3cgd2F5IGZvciB0aGUg
aW50ZXJydXB0Cj4gwqAgwqAgwqAgwqAgKiB0byBjbGVhci4KPiBAQCAtMTIwLDE1ICsxMjIsMTYg
QEAgc3RhdGljIHZvaWQgbGlzM2wwMmRxX3BvbGxfZnVuY190aChzdHJ1Y3QgaWlvX2RldiAqaW5k
aW9fZGV2LCBzNjQgdGltZSkKPiDCoC8qKgo+IMKgKiBsaXMzbDAyZHFfZGF0YV9yZHlfdHJpZ19w
b2xsKCkgdGhlIGV2ZW50IGhhbmRsZXIgZm9yIHRoZSBkYXRhIHJkeSB0cmlnCj4gwqAqKi8KPiAt
c3RhdGljIGludCBsaXMzbDAyZHFfZGF0YV9yZHlfdHJpZ19wb2xsKHN0cnVjdCBpaW9fZGV2ICpk
ZXZfaW5mbywKPiArc3RhdGljIGludCBsaXMzbDAyZHFfZGF0YV9yZHlfdHJpZ19wb2xsKHN0cnVj
dCBpaW9fZGV2ICppbmRpb19kZXYsCj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgaW50IGluZGV4LAo+IMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHM2NCB0aW1lc3RhbXAsCj4gwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgaW50
IG5vX3Rlc3QpCj4gwqB7Cj4gLSDCoCDCoCDCoCBzdHJ1Y3QgbGlzM2wwMmRxX3N0YXRlICpzdCA9
IGlpb19kZXZfZ2V0X2RldmRhdGEoZGV2X2luZm8pOwo+IC0gwqAgwqAgwqAgc3RydWN0IGlpb190
cmlnZ2VyICp0cmlnID0gc3QtPnRyaWc7Cj4gKyDCoCDCoCDCoCBzdHJ1Y3QgaWlvX3N3X3Jpbmdf
aGVscGVyX3N0YXRlICpoCj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCA9IGlpb19kZXZfZ2V0X2Rl
dmRhdGEoaW5kaW9fZGV2KTsKPiArIMKgIMKgIMKgIHN0cnVjdCBsaXMzbDAyZHFfc3RhdGUgKnN0
ID0gbGlzM2wwMmRxX2hfdG9fcyhoKTsKPgo+IC0gwqAgwqAgwqAgaWlvX3RyaWdnZXJfcG9sbCh0
cmlnLCB0aW1lc3RhbXApOwo+ICsgwqAgwqAgwqAgaWlvX3RyaWdnZXJfcG9sbChzdC0+dHJpZywg
dGltZXN0YW1wKTsKPgo+IMKgIMKgIMKgIMKgcmV0dXJuIElSUV9IQU5ETEVEOwo+IMKgfQo+IEBA
IC0yMTIsNyArMjE1LDcgQEAgc3RhdGljIGludCBsaXMzbDAyZHFfcmVhZF9hbGwoc3RydWN0IGxp
czNsMDJkcV9zdGF0ZSAqc3QsIHU4ICpyeF9hcnJheSkKPiDCoCDCoCDCoCDCoHN0cnVjdCBzcGlf
bWVzc2FnZSBtc2c7Cj4gwqAgwqAgwqAgwqBpbnQgcmV0LCBpLCBqID0gMDsKPgo+IC0gwqAgwqAg
wqAgeGZlcnMgPSBremFsbG9jKChzdC0+aW5kaW9fZGV2LT5zY2FuX2NvdW50KSAqIDIKPiArIMKg
IMKgIMKgIHhmZXJzID0ga3phbGxvYygoc3QtPmhlbHAuaW5kaW9fZGV2LT5zY2FuX2NvdW50KSAq
IDIKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCogc2l6ZW9mKCp4ZmVycyks
IEdGUF9LRVJORUwpOwo+IMKgIMKgIMKgIMKgaWYgKCF4ZmVycykKPiDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoHJldHVybiAtRU5PTUVNOwo+IEBAIC0yMjAsNyArMjIzLDcgQEAgc3RhdGljIGludCBs
aXMzbDAyZHFfcmVhZF9hbGwoc3RydWN0IGxpczNsMDJkcV9zdGF0ZSAqc3QsIHU4ICpyeF9hcnJh
eSkKPiDCoCDCoCDCoCDCoG11dGV4X2xvY2soJnN0LT5idWZfbG9jayk7Cj4KPiDCoCDCoCDCoCDC
oGZvciAoaSA9IDA7IGkgPCBBUlJBWV9TSVpFKHJlYWRfYWxsX3R4X2FycmF5KS80OyBpKyspIHsK
PiAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGlmIChzdC0+aW5kaW9fZGV2LT5zY2FuX21hc2sgJiAo
MSA8PCBpKSkgewo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgaWYgKHN0LT5oZWxwLmluZGlvX2Rl
di0+c2Nhbl9tYXNrICYgKDEgPDwgaSkpIHsKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoC8qIGxvd2VyIGJ5dGUgKi8KPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoHhmZXJzW2pdLnR4X2J1ZiA9IHN0LT50eCArIDIqajsKPiDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoHN0LT50eFsyKmpdID0gcmVhZF9hbGxfdHhfYXJyYXlbaSo0XTsKPiBA
QCAtMjQ4LDcgKzI1MSw3IEBAIHN0YXRpYyBpbnQgbGlzM2wwMmRxX3JlYWRfYWxsKHN0cnVjdCBs
aXMzbDAyZHFfc3RhdGUgKnN0LCB1OCAqcnhfYXJyYXkpCj4gwqAgwqAgwqAgwqAgKiB2YWx1ZXMg
aW4gYWx0ZXJuYXRlIGJ5dGVzCj4gwqAgwqAgwqAgwqAgKi8KPiDCoCDCoCDCoCDCoHNwaV9tZXNz
YWdlX2luaXQoJm1zZyk7Cj4gLSDCoCDCoCDCoCBmb3IgKGogPSAwOyBqIDwgc3QtPmluZGlvX2Rl
di0+c2Nhbl9jb3VudCAqIDI7IGorKykKPiArIMKgIMKgIMKgIGZvciAoaiA9IDA7IGogPCBzdC0+
aGVscC5pbmRpb19kZXYtPnNjYW5fY291bnQgKiAyOyBqKyspCj4gwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqBzcGlfbWVzc2FnZV9hZGRfdGFpbCgmeGZlcnNbal0sICZtc2cpOwo+Cj4gwqAgwqAgwqAg
wqByZXQgPSBzcGlfc3luYyhzdC0+dXMsICZtc2cpOwo+IEBAIC0yNTgsNjIgKzI2MSwzNSBAQCBz
dGF0aWMgaW50IGxpczNsMDJkcV9yZWFkX2FsbChzdHJ1Y3QgbGlzM2wwMmRxX3N0YXRlICpzdCwg
dTggKnJ4X2FycmF5KQo+IMKgIMKgIMKgIMKgcmV0dXJuIHJldDsKPiDCoH0KPgo+IC0KPiAtLyog
V2hpbHN0IHRoaXMgbWFrZXMgYSBsb3Qgb2YgY2FsbHMgdG8gaWlvX3N3X3JpbmcgZnVuY3Rpb25z
IC0gaXQgaXMgdG8gZGV2aWNlCj4gLSAqIHNwZWNpZmljIHRvIGJlIHJvbGxlZCBpbnRvIHRoZSBj
b3JlLgo+IC0gKi8KPiDCoHN0YXRpYyB2b2lkIGxpczNsMDJkcV90cmlnZ2VyX2JoX3RvX3Jpbmco
c3RydWN0IHdvcmtfc3RydWN0ICp3b3JrX3MpCj4gwqB7Cj4gLSDCoCDCoCDCoCBzdHJ1Y3QgbGlz
M2wwMmRxX3N0YXRlICpzdAo+IC0gwqAgwqAgwqAgwqAgwqAgwqAgwqAgPSBjb250YWluZXJfb2Yo
d29ya19zLCBzdHJ1Y3QgbGlzM2wwMmRxX3N0YXRlLAo+IC0gwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqB3b3JrX3RyaWdnZXJfdG9fcmluZyk7Cj4gLQo+IC0gwqAg
wqAgwqAgdTggKnJ4X2FycmF5Owo+IC0gwqAgwqAgwqAgaW50IGkgPSAwOwo+IC0gwqAgwqAgwqAg
dTE2ICpkYXRhOwo+IC0gwqAgwqAgwqAgc2l6ZV90IGRhdGFzaXplID0gc3QtPmluZGlvX2Rldgo+
IC0gwqAgwqAgwqAgwqAgwqAgwqAgwqAgLT5yaW5nLT5hY2Nlc3MuZ2V0X2JwZChzdC0+aW5kaW9f
ZGV2LT5yaW5nKTsKPiAtCj4gLSDCoCDCoCDCoCBkYXRhID0ga21hbGxvYyhkYXRhc2l6ZSAsIEdG
UF9LRVJORUwpOwo+IC0gwqAgwqAgwqAgaWYgKGRhdGEgPT0gTlVMTCkgewo+IC0gwqAgwqAgwqAg
wqAgwqAgwqAgwqAgZGV2X2Vycigmc3QtPnVzLT5kZXYsICJtZW1vcnkgYWxsb2MgZmFpbGVkIGlu
IHJpbmcgYmgiKTsKPiAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHJldHVybjsKPiAtIMKgIMKgIMKg
IH0KPiAtIMKgIMKgIMKgIC8qIER1ZSB0byBpbnRlcmxlYXZlZCBuYXR1cmUgb2YgdHJhbnNtaXNz
aW9uIHRoaXMgYnVmZmVyIG11c3QgYmUKPiAtIMKgIMKgIMKgIMKgKiB0d2ljZSB0aGUgbnVtYmVy
IG9mIGJ5dGVzLCBvciA0IHRpbWVzIHRoZSBudW1iZXIgb2YgY2hhbm5lbHMKPiAtIMKgIMKgIMKg
IMKgKi8KPiAtIMKgIMKgIMKgIHJ4X2FycmF5ID0ga21hbGxvYyg0ICogKHN0LT5pbmRpb19kZXYt
PnNjYW5fY291bnQpLCBHRlBfS0VSTkVMKTsKPiAtIMKgIMKgIMKgIGlmIChyeF9hcnJheSA9PSBO
VUxMKSB7Cj4gLSDCoCDCoCDCoCDCoCDCoCDCoCDCoCBkZXZfZXJyKCZzdC0+dXMtPmRldiwgIm1l
bW9yeSBhbGxvYyBmYWlsZWQgaW4gcmluZyBiaCIpOwo+IC0gwqAgwqAgwqAgwqAgwqAgwqAgwqAg
a2ZyZWUoZGF0YSk7Cj4gLSDCoCDCoCDCoCDCoCDCoCDCoCDCoCByZXR1cm47Cj4gLSDCoCDCoCDC
oCB9Cj4gLQo+IC0gwqAgwqAgwqAgLyogd2hpbHN0IHRyaWdnZXIgc3BlY2lmaWMsIGlmIHRoaXMg
cmVhZCBkb2VzIG50byBvY2N1ciB0aGUgZGF0YQo+IC0gwqAgwqAgwqAgwqAgwqByZWFkeSBpbnRl
cnJ1cHQgd2lsbCBub3QgYmUgY2xlYXJlZC4gwqBOZWVkIHRvIGFkZCBhIG1lY2hhbmlzbQo+IC0g
wqAgwqAgwqAgwqAgwqB0byBwcm92aWRlIGEgZHVtbXkgcmVhZCBmdW5jdGlvbiBpZiB0aGlzIGlz
IG5vdCB0cmlnZ2VyaW5nIG9uCj4gLSDCoCDCoCDCoCDCoCDCoHRoZSBkYXRhIHJlYWR5IGZ1bmN0
aW9uIGJ1dCBzb21ldGhpbmcgZWxzZSBpcy4KPiAtIMKgIMKgIMKgICovCj4gKyDCoCDCoCDCoCBz
dHJ1Y3QgaWlvX3N3X3JpbmdfaGVscGVyX3N0YXRlICpoCj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDC
oCA9IGNvbnRhaW5lcl9vZih3b3JrX3MsIHN0cnVjdCBpaW9fc3dfcmluZ19oZWxwZXJfc3RhdGUs
Cj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCB3b3JrX3RyaWdnZXJfdG9fcmlu
Zyk7Cj4gKyDCoCDCoCDCoCBzdHJ1Y3QgbGlzM2wwMmRxX3N0YXRlICpzdCA9IGxpczNsMDJkcV9o
X3RvX3MoaCk7Cj4gwqAgwqAgwqAgwqBzdC0+aW50ZXIgPSAwOwo+ICsgwqAgwqAgwqAgaWlvX3N3
X3RyaWdnZXJfYmhfdG9fcmluZyh3b3JrX3MpOwo+ICt9Cj4KPiAtIMKgIMKgIMKgIGlmIChzdC0+
aW5kaW9fZGV2LT5zY2FuX2NvdW50KQo+IC0gwqAgwqAgwqAgwqAgwqAgwqAgwqAgaWYgKGxpczNs
MDJkcV9yZWFkX2FsbChzdCwgcnhfYXJyYXkpID49IDApCj4gLSDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCBmb3IgKDsgaSA8IHN0LT5pbmRpb19kZXYtPnNjYW5fY291bnQ7IGkrKykK
PiAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGRhdGFbaV0g
PSBjb21iaW5lXzhfdG9fMTYocnhfYXJyYXlbaSo0KzFdLAo+IC0gwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgcnhfYXJyYXlbaSo0KzNdKTsKPiAtIMKgIMKgIMKgIC8qIEd1YXJhbnRlZWQgdG8g
YmUgYWxpZ25lZCB3aXRoIDggYnl0ZSBib3VuZGFyeSAqLwo+IC0gwqAgwqAgwqAgaWYgKHN0LT5p
bmRpb19kZXYtPnNjYW5fdGltZXN0YW1wKQo+IC0gwqAgwqAgwqAgwqAgwqAgwqAgwqAgKigoczY0
ICopKGRhdGEgKyAoKGkgKyAzKS80KSo0KSkgPSBzdC0+bGFzdF90aW1lc3RhbXA7Cj4gLQo+IC0g
wqAgwqAgwqAgc3QtPmluZGlvX2Rldi0+cmluZy0+YWNjZXNzLnN0b3JlX3RvKHN0LT5pbmRpb19k
ZXYtPnJpbmcsCj4gLSDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCAodTggKilkYXRhLAo+IC0gwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgc3QtPmxhc3RfdGltZXN0
YW1wKTsKPiAtCj4gLSDCoCDCoCDCoCBpaW9fdHJpZ2dlcl9ub3RpZnlfZG9uZShzdC0+aW5kaW9f
ZGV2LT50cmlnKTsKPiArc3RhdGljIGludCBsaXMzbDAyZHFfZ2V0X3JpbmdfZWxlbWVudChzdHJ1
Y3QgaWlvX3N3X3JpbmdfaGVscGVyX3N0YXRlICpoLAo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgdTggKmJ1ZikKPiArewo+ICsgwqAgwqAgwqAgaW50IHJl
dCwgaTsKPiArIMKgIMKgIMKgIHU4ICpyeF9hcnJheSA7Cj4gKyDCoCDCoCDCoCBzMTYgKmRhdGEg
PSAoczE2ICopYnVmOwo+ICsKPiArIMKgIMKgIMKgIHJ4X2FycmF5ID0ga3phbGxvYyg0ICogKGgt
PmluZGlvX2Rldi0+c2Nhbl9jb3VudCksIEdGUF9LRVJORUwpOwo+ICsgwqAgwqAgwqAgaWYgKHJ4
X2FycmF5ID09IE5VTEwpCj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCByZXR1cm4gLUVOT01FTTsK
PiArIMKgIMKgIMKgIHJldCA9IGxpczNsMDJkcV9yZWFkX2FsbChsaXMzbDAyZHFfaF90b19zKGgp
LCByeF9hcnJheSk7Cj4gKyDCoCDCoCDCoCBpZiAocmV0IDwgMCkKPiArIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIHJldHVybiByZXQ7Cj4gKyDCoCDCoCDCoCBmb3IgKGkgPSAwOyBpIDwgaC0+aW5kaW9f
ZGV2LT5zY2FuX2NvdW50OyBpKyspCj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCBkYXRhW2ldID0g
Y29tYmluZV84X3RvXzE2KHJ4X2FycmF5W2kqNCsxXSwKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHJ4X2FycmF5W2kqNCszXSk7Cj4g
wqAgwqAgwqAgwqBrZnJlZShyeF9hcnJheSk7Cj4gLSDCoCDCoCDCoCBrZnJlZShkYXRhKTsKPgo+
IC0gwqAgwqAgwqAgcmV0dXJuOwo+ICsgwqAgwqAgwqAgcmV0dXJuIGkqc2l6ZW9mKGRhdGFbMF0p
Owo+IMKgfQo+Cj4gwqAvKiBDYWxsZXIgcmVzcG9uc2libGUgZm9yIGxvY2tpbmcgYXMgbmVjZXNz
YXJ5LiAqLwo+IEBAIC0zODcsNyArMzYzLDcgQEAgc3RhdGljIGludCBsaXMzbDAyZHFfZGF0YV9y
ZHlfdHJpZ2dlcl9zZXRfc3RhdGUoc3RydWN0IGlpb190cmlnZ2VyICp0cmlnLAo+IMKgIMKgIMKg
IMKgc3RydWN0IGxpczNsMDJkcV9zdGF0ZSAqc3QgPSB0cmlnLT5wcml2YXRlX2RhdGE7Cj4gwqAg
wqAgwqAgwqBpbnQgcmV0ID0gMDsKPiDCoCDCoCDCoCDCoHU4IHQ7Cj4gLSDCoCDCoCDCoCBfX2xp
czNsMDJkcV93cml0ZV9kYXRhX3JlYWR5X2NvbmZpZygmc3QtPmluZGlvX2Rldi0+ZGV2LAo+ICsg
wqAgwqAgwqAgX19saXMzbDAyZHFfd3JpdGVfZGF0YV9yZWFkeV9jb25maWcoJnN0LT5oZWxwLmlu
ZGlvX2Rldi0+ZGV2LAo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgJmlpb19ldmVudF9kYXRhX3JkeV90cmlnLAo+IMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgc3RhdGUpOwo+IMKgIMKgIMKgIMKgaWYgKHN0YXRlID09IGZhbHNlKSB7Cj4gQEAgLTM5Nyw3
ICszNzMsNyBAQCBzdGF0aWMgaW50IGxpczNsMDJkcV9kYXRhX3JkeV90cmlnZ2VyX3NldF9zdGF0
ZShzdHJ1Y3QgaWlvX3RyaWdnZXIgKnRyaWcsCj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAvKiBD
bGVhciBhbnkgb3V0c3RhbmRpbmcgcmVhZHkgZXZlbnRzICovCj4gwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqByZXQgPSBsaXMzbDAyZHFfcmVhZF9hbGwoc3QsIE5VTEwpOwo+IMKgIMKgIMKgIMKgfQo+
IC0gwqAgwqAgwqAgbGlzM2wwMmRxX3NwaV9yZWFkX3JlZ184KCZzdC0+aW5kaW9fZGV2LT5kZXYs
Cj4gKyDCoCDCoCDCoCBsaXMzbDAyZHFfc3BpX3JlYWRfcmVnXzgoJnN0LT5oZWxwLmluZGlvX2Rl
di0+ZGV2LAo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IExJUzNMMDJEUV9SRUdfV0FLRV9VUF9TUkNfQUREUiwKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAmdCk7Cj4gwqAgwqAgwqAgwqByZXR1cm4gcmV0Owo+
IEBAIC01MDAsMTIgKzQ3NiwxMiBAQCB2b2lkIGxpczNsMDJkcV91bmNvbmZpZ3VyZV9yaW5nKHN0
cnVjdCBpaW9fZGV2ICppbmRpb19kZXYpCj4KPiDCoGludCBsaXMzbDAyZHFfY29uZmlndXJlX3Jp
bmcoc3RydWN0IGlpb19kZXYgKmluZGlvX2RldikKPiDCoHsKPiAtIMKgIMKgIMKgIGludCByZXQg
PSAwOwo+IC0gwqAgwqAgwqAgc3RydWN0IGxpczNsMDJkcV9zdGF0ZSAqc3QgPSBpbmRpb19kZXYt
PmRldl9kYXRhOwo+IC0gwqAgwqAgwqAgc3RydWN0IGlpb19yaW5nX2J1ZmZlciAqcmluZzsKPiAt
IMKgIMKgIMKgIElOSVRfV09SSygmc3QtPndvcmtfdHJpZ2dlcl90b19yaW5nLCBsaXMzbDAyZHFf
dHJpZ2dlcl9iaF90b19yaW5nKTsKPiArIMKgIMKgIMKgIGludCByZXQ7Cj4gKyDCoCDCoCDCoCBz
dHJ1Y3QgaWlvX3N3X3JpbmdfaGVscGVyX3N0YXRlICpoID0gaWlvX2Rldl9nZXRfZGV2ZGF0YShp
bmRpb19kZXYpOwo+ICsKPiArIMKgIMKgIMKgIElOSVRfV09SSygmaC0+d29ya190cmlnZ2VyX3Rv
X3JpbmcsIGxpczNsMDJkcV90cmlnZ2VyX2JoX3RvX3JpbmcpOwo+IMKgIMKgIMKgIMKgLyogU2V0
IGRlZmF1bHQgc2NhbiBtb2RlICovCj4gLQo+ICsgwqAgwqAgwqAgaC0+Z2V0X3JpbmdfZWxlbWVu
dCA9ICZsaXMzbDAyZHFfZ2V0X3JpbmdfZWxlbWVudDsKPiDCoCDCoCDCoCDCoGlpb19zY2FuX21h
c2tfc2V0KGluZGlvX2RldiwgaWlvX3NjYW5fZWxfYWNjZWxfeC5udW1iZXIpOwo+IMKgIMKgIMKg
IMKgaWlvX3NjYW5fbWFza19zZXQoaW5kaW9fZGV2LCBpaW9fc2Nhbl9lbF9hY2NlbF95Lm51bWJl
cik7Cj4gwqAgwqAgwqAgwqBpaW9fc2Nhbl9tYXNrX3NldChpbmRpb19kZXYsIGlpb19zY2FuX2Vs
X2FjY2VsX3oubnVtYmVyKTsKPiBAQCAtNTEzLDE5ICs0ODksMTcgQEAgaW50IGxpczNsMDJkcV9j
b25maWd1cmVfcmluZyhzdHJ1Y3QgaWlvX2RldiAqaW5kaW9fZGV2KQo+Cj4gwqAgwqAgwqAgwqBp
bmRpb19kZXYtPnNjYW5fZWxfYXR0cnMgPSAmbGlzM2wwMmRxX3NjYW5fZWxfZ3JvdXA7Cj4KPiAt
IMKgIMKgIMKgIHJpbmcgPSBpaW9fc3dfcmJfYWxsb2NhdGUoaW5kaW9fZGV2KTsKPiAtIMKgIMKg
IMKgIGlmICghcmluZykgewo+IC0gwqAgwqAgwqAgwqAgwqAgwqAgwqAgcmV0ID0gLUVOT01FTTsK
PiAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHJldHVybiByZXQ7Cj4gLSDCoCDCoCDCoCB9Cj4gLSDC
oCDCoCDCoCBpbmRpb19kZXYtPnJpbmcgPSByaW5nOwo+ICsgwqAgwqAgwqAgaW5kaW9fZGV2LT5y
aW5nID0gaWlvX3N3X3JiX2FsbG9jYXRlKGluZGlvX2Rldik7Cj4gKyDCoCDCoCDCoCBpZiAoIWlu
ZGlvX2Rldi0+cmluZykKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHJldHVybiAtRU5PTUVNOwo+
ICsKPiDCoCDCoCDCoCDCoC8qIEVmZmVjdGl2ZWx5IHNlbGVjdCB0aGUgcmluZyBidWZmZXIgaW1w
bGVtZW50YXRpb24gKi8KPiAtIMKgIMKgIMKgIGlpb19yaW5nX3N3X3JlZ2lzdGVyX2Z1bmNzKCZy
aW5nLT5hY2Nlc3MpOwo+IC0gwqAgwqAgwqAgcmluZy0+YnBlID0gMjsKPiAtIMKgIMKgIMKgIHJp
bmctPnByZWVuYWJsZSA9ICZpaW9fc3dfcmluZ19wcmVlbmFibGU7Cj4gLSDCoCDCoCDCoCByaW5n
LT5wb3N0ZW5hYmxlID0gJmlpb190cmlnZ2VyZWRfcmluZ19wb3N0ZW5hYmxlOwo+IC0gwqAgwqAg
wqAgcmluZy0+cHJlZGlzYWJsZSA9ICZpaW9fdHJpZ2dlcmVkX3JpbmdfcHJlZGlzYWJsZTsKPiAt
IMKgIMKgIMKgIHJpbmctPm93bmVyID0gVEhJU19NT0RVTEU7Cj4gKyDCoCDCoCDCoCBpaW9fcmlu
Z19zd19yZWdpc3Rlcl9mdW5jcygmaW5kaW9fZGV2LT5yaW5nLT5hY2Nlc3MpOwo+ICsgwqAgwqAg
wqAgaW5kaW9fZGV2LT5yaW5nLT5icGUgPSAyOwo+ICsgwqAgwqAgwqAgaW5kaW9fZGV2LT5yaW5n
LT5wcmVlbmFibGUgPSAmaWlvX3N3X3JpbmdfcHJlZW5hYmxlOwo+ICsgwqAgwqAgwqAgaW5kaW9f
ZGV2LT5yaW5nLT5wb3N0ZW5hYmxlID0gJmlpb190cmlnZ2VyZWRfcmluZ19wb3N0ZW5hYmxlOwo+
ICsgwqAgwqAgwqAgaW5kaW9fZGV2LT5yaW5nLT5wcmVkaXNhYmxlID0gJmlpb190cmlnZ2VyZWRf
cmluZ19wcmVkaXNhYmxlOwo+ICsgwqAgwqAgwqAgaW5kaW9fZGV2LT5yaW5nLT5vd25lciA9IFRI
SVNfTU9EVUxFOwo+Cj4gwqAgwqAgwqAgwqByZXQgPSBpaW9fYWxsb2NfcG9sbGZ1bmMoaW5kaW9f
ZGV2LCBOVUxMLCAmbGlzM2wwMmRxX3BvbGxfZnVuY190aCk7Cj4gwqAgwqAgwqAgwqBpZiAocmV0
KQo+IEBAIC01MzcsNiArNTExLDMgQEAgZXJyb3JfaWlvX3N3X3JiX2ZyZWU6Cj4gwqAgwqAgwqAg
wqBpaW9fc3dfcmJfZnJlZShpbmRpb19kZXYtPnJpbmcpOwo+IMKgIMKgIMKgIMKgcmV0dXJuIHJl
dDsKPiDCoH0KPiAtCj4gLQo+IC0KPiAtLQo+IDEuNy4wLjQKPgo+IC0tCj4gVG8gdW5zdWJzY3Jp
YmUgZnJvbSB0aGlzIGxpc3Q6IHNlbmQgdGhlIGxpbmUgInVuc3Vic2NyaWJlIGxpbnV4LWlpbyIg
aW4KPiB0aGUgYm9keSBvZiBhIG1lc3NhZ2UgdG8gbWFqb3Jkb21vQHZnZXIua2VybmVsLm9yZwo+
IE1vcmUgbWFqb3Jkb21vIGluZm8gYXQgwqBodHRwOi8vdmdlci5rZXJuZWwub3JnL21ham9yZG9t
by1pbmZvLmh0bWwKPgo=
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 5/5 v2] staging:iio:adis16209 use iio_sw_ring_helper_state and funcs
2010-06-30 16:07 ` [PATCH 5/5 v2] staging:iio:adis16209 " Jonathan Cameron
@ 2010-07-08 9:37 ` Barry Song
2010-07-08 14:46 ` Jonathan Cameron
0 siblings, 1 reply; 5+ messages in thread
From: Barry Song @ 2010-07-08 9:37 UTC (permalink / raw)
To: Jonathan Cameron; +Cc: linux-iio
On Thu, Jul 1, 2010 at 12:07 AM, Jonathan Cameron <jic23@cam.ac.uk> wrote:
> =C2=A0Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
Thanks very much. Has this one been tested? If so,
Acked-by: Barry Song <21cnbao@gmail.com>.
And I will send related patches for other drivers too.
-barry
> ---
>
> =C2=A0The get element fuction should return how much of the buffer it has
> =C2=A0used. =C2=A0Now it actually does this.
>
> =C2=A0drivers/staging/iio/accel/adis16209.h =C2=A0 =C2=A0 =C2=A0 =C2=A0 |=
=C2=A0 =C2=A07 ++-
> =C2=A0drivers/staging/iio/accel/adis16209_core.c =C2=A0 =C2=A0| =C2=A0 54=
+++++++++++----------
> =C2=A0drivers/staging/iio/accel/adis16209_ring.c =C2=A0 =C2=A0| =C2=A0 65=
++++++-------------------
> =C2=A0drivers/staging/iio/accel/adis16209_trigger.c | =C2=A0 =C2=A08 ++-
> =C2=A04 files changed, 53 insertions(+), 81 deletions(-)
>
> diff --git a/drivers/staging/iio/accel/adis16209.h b/drivers/staging/iio/=
accel/adis16209.h
> index 92daf6f..84e1a2f 100644
> --- a/drivers/staging/iio/accel/adis16209.h
> +++ b/drivers/staging/iio/accel/adis16209.h
> @@ -113,16 +113,17 @@
> =C2=A0* @buf_lock: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0mutex to protect tx =
and rx
> =C2=A0**/
> =C2=A0struct adis16209_state {
> + =C2=A0 =C2=A0 =C2=A0 struct iio_sw_ring_helper_state help;
> =C2=A0 =C2=A0 =C2=A0 =C2=A0struct spi_device =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 *us;
> - =C2=A0 =C2=A0 =C2=A0 struct work_struct =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0work_trigger_to_ring;
> - =C2=A0 =C2=A0 =C2=A0 s64 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 last_timestamp;
> - =C2=A0 =C2=A0 =C2=A0 struct iio_dev =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0*indio_dev;
> =C2=A0 =C2=A0 =C2=A0 =C2=A0struct iio_trigger =C2=A0 =C2=A0 =C2=A0 =C2=A0=
=C2=A0 =C2=A0 =C2=A0*trig;
> =C2=A0 =C2=A0 =C2=A0 =C2=A0u8 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0*tx;
> =C2=A0 =C2=A0 =C2=A0 =C2=A0u8 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0*rx;
> =C2=A0 =C2=A0 =C2=A0 =C2=A0struct mutex =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0buf_lock;
> =C2=A0};
>
> +#define adis16209_h_to_s(_h) =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 \
> + =C2=A0 =C2=A0 =C2=A0 container_of(_h, struct adis16209_state, help)
> +
> =C2=A0int adis16209_set_irq(struct device *dev, bool enable);
>
> =C2=A0#ifdef CONFIG_IIO_RING_BUFFER
> diff --git a/drivers/staging/iio/accel/adis16209_core.c b/drivers/staging=
/iio/accel/adis16209_core.c
> index 6c6923f..9c7aafe 100644
> --- a/drivers/staging/iio/accel/adis16209_core.c
> +++ b/drivers/staging/iio/accel/adis16209_core.c
> @@ -21,6 +21,7 @@
> =C2=A0#include "../iio.h"
> =C2=A0#include "../sysfs.h"
> =C2=A0#include "../ring_generic.h"
> +#include "../ring_sw.h"
> =C2=A0#include "accel.h"
> =C2=A0#include "inclinometer.h"
> =C2=A0#include "../gyro/gyro.h"
> @@ -44,7 +45,8 @@ static int adis16209_spi_write_reg_8(struct device *dev=
,
> =C2=A0{
> =C2=A0 =C2=A0 =C2=A0 =C2=A0int ret;
> =C2=A0 =C2=A0 =C2=A0 =C2=A0struct iio_dev *indio_dev =3D dev_get_drvdata(=
dev);
> - =C2=A0 =C2=A0 =C2=A0 struct adis16209_state *st =3D iio_dev_get_devdata=
(indio_dev);
> + =C2=A0 =C2=A0 =C2=A0 struct iio_sw_ring_helper_state *h =3D iio_dev_get=
_devdata(indio_dev);
> + =C2=A0 =C2=A0 =C2=A0 struct adis16209_state *st =3D adis16209_h_to_s(h)=
;
>
> =C2=A0 =C2=A0 =C2=A0 =C2=A0mutex_lock(&st->buf_lock);
> =C2=A0 =C2=A0 =C2=A0 =C2=A0st->tx[0] =3D ADIS16209_WRITE_REG(reg_address)=
;
> @@ -70,7 +72,8 @@ static int adis16209_spi_write_reg_16(struct device *de=
v,
> =C2=A0 =C2=A0 =C2=A0 =C2=A0int ret;
> =C2=A0 =C2=A0 =C2=A0 =C2=A0struct spi_message msg;
> =C2=A0 =C2=A0 =C2=A0 =C2=A0struct iio_dev *indio_dev =3D dev_get_drvdata(=
dev);
> - =C2=A0 =C2=A0 =C2=A0 struct adis16209_state *st =3D iio_dev_get_devdata=
(indio_dev);
> + =C2=A0 =C2=A0 =C2=A0 struct iio_sw_ring_helper_state *h =3D iio_dev_get=
_devdata(indio_dev);
> + =C2=A0 =C2=A0 =C2=A0 struct adis16209_state *st =3D adis16209_h_to_s(h)=
;
> =C2=A0 =C2=A0 =C2=A0 =C2=A0struct spi_transfer xfers[] =3D {
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0.tx_buf =3D st->tx,
> @@ -115,7 +118,8 @@ static int adis16209_spi_read_reg_16(struct device *d=
ev,
> =C2=A0{
> =C2=A0 =C2=A0 =C2=A0 =C2=A0struct spi_message msg;
> =C2=A0 =C2=A0 =C2=A0 =C2=A0struct iio_dev *indio_dev =3D dev_get_drvdata(=
dev);
> - =C2=A0 =C2=A0 =C2=A0 struct adis16209_state *st =3D iio_dev_get_devdata=
(indio_dev);
> + =C2=A0 =C2=A0 =C2=A0 struct iio_sw_ring_helper_state *h =3D iio_dev_get=
_devdata(indio_dev);
> + =C2=A0 =C2=A0 =C2=A0 struct adis16209_state *st =3D adis16209_h_to_s(h)=
;
> =C2=A0 =C2=A0 =C2=A0 =C2=A0int ret;
> =C2=A0 =C2=A0 =C2=A0 =C2=A0struct spi_transfer xfers[] =3D {
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{
> @@ -355,7 +359,7 @@ err_ret:
> =C2=A0static int adis16209_initial_setup(struct adis16209_state *st)
> =C2=A0{
> =C2=A0 =C2=A0 =C2=A0 =C2=A0int ret;
> - =C2=A0 =C2=A0 =C2=A0 struct device *dev =3D &st->indio_dev->dev;
> + =C2=A0 =C2=A0 =C2=A0 struct device *dev =3D &st->help.indio_dev->dev;
>
> =C2=A0 =C2=A0 =C2=A0 =C2=A0/* Disable IRQ */
> =C2=A0 =C2=A0 =C2=A0 =C2=A0ret =3D adis16209_set_irq(dev, false);
> @@ -498,30 +502,30 @@ static int __devinit adis16209_probe(struct spi_dev=
ice *spi)
> =C2=A0 =C2=A0 =C2=A0 =C2=A0st->us =3D spi;
> =C2=A0 =C2=A0 =C2=A0 =C2=A0mutex_init(&st->buf_lock);
> =C2=A0 =C2=A0 =C2=A0 =C2=A0/* setup the industrialio driver allocated ele=
ments */
> - =C2=A0 =C2=A0 =C2=A0 st->indio_dev =3D iio_allocate_device();
> - =C2=A0 =C2=A0 =C2=A0 if (st->indio_dev =3D=3D NULL) {
> + =C2=A0 =C2=A0 =C2=A0 st->help.indio_dev =3D iio_allocate_device();
> + =C2=A0 =C2=A0 =C2=A0 if (st->help.indio_dev =3D=3D NULL) {
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ret =3D -ENOMEM;
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0goto error_free_tx=
;
> =C2=A0 =C2=A0 =C2=A0 =C2=A0}
>
> - =C2=A0 =C2=A0 =C2=A0 st->indio_dev->dev.parent =3D &spi->dev;
> - =C2=A0 =C2=A0 =C2=A0 st->indio_dev->num_interrupt_lines =3D 1;
> - =C2=A0 =C2=A0 =C2=A0 st->indio_dev->event_attrs =3D &adis16209_event_at=
tribute_group;
> - =C2=A0 =C2=A0 =C2=A0 st->indio_dev->attrs =3D &adis16209_attribute_grou=
p;
> - =C2=A0 =C2=A0 =C2=A0 st->indio_dev->dev_data =3D (void *)(st);
> - =C2=A0 =C2=A0 =C2=A0 st->indio_dev->driver_module =3D THIS_MODULE;
> - =C2=A0 =C2=A0 =C2=A0 st->indio_dev->modes =3D INDIO_DIRECT_MODE;
> + =C2=A0 =C2=A0 =C2=A0 st->help.indio_dev->dev.parent =3D &spi->dev;
> + =C2=A0 =C2=A0 =C2=A0 st->help.indio_dev->num_interrupt_lines =3D 1;
> + =C2=A0 =C2=A0 =C2=A0 st->help.indio_dev->event_attrs =3D &adis16209_eve=
nt_attribute_group;
> + =C2=A0 =C2=A0 =C2=A0 st->help.indio_dev->attrs =3D &adis16209_attribute=
_group;
> + =C2=A0 =C2=A0 =C2=A0 st->help.indio_dev->dev_data =3D (void *)(&st->hel=
p);
> + =C2=A0 =C2=A0 =C2=A0 st->help.indio_dev->driver_module =3D THIS_MODULE;
> + =C2=A0 =C2=A0 =C2=A0 st->help.indio_dev->modes =3D INDIO_DIRECT_MODE;
>
> - =C2=A0 =C2=A0 =C2=A0 ret =3D adis16209_configure_ring(st->indio_dev);
> + =C2=A0 =C2=A0 =C2=A0 ret =3D adis16209_configure_ring(st->help.indio_de=
v);
> =C2=A0 =C2=A0 =C2=A0 =C2=A0if (ret)
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0goto error_free_de=
v;
>
> - =C2=A0 =C2=A0 =C2=A0 ret =3D iio_device_register(st->indio_dev);
> + =C2=A0 =C2=A0 =C2=A0 ret =3D iio_device_register(st->help.indio_dev);
> =C2=A0 =C2=A0 =C2=A0 =C2=A0if (ret)
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0goto error_unreg_r=
ing_funcs;
> =C2=A0 =C2=A0 =C2=A0 =C2=A0regdone =3D 1;
>
> - =C2=A0 =C2=A0 =C2=A0 ret =3D iio_ring_buffer_register(st->indio_dev->ri=
ng, 0);
> + =C2=A0 =C2=A0 =C2=A0 ret =3D iio_ring_buffer_register(st->help.indio_de=
v->ring, 0);
> =C2=A0 =C2=A0 =C2=A0 =C2=A0if (ret) {
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0printk(KERN_ERR "f=
ailed to initialize the ring\n");
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0goto error_unreg_r=
ing_funcs;
> @@ -529,14 +533,14 @@ static int __devinit adis16209_probe(struct spi_dev=
ice *spi)
>
> =C2=A0 =C2=A0 =C2=A0 =C2=A0if (spi->irq) {
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ret =3D iio_regist=
er_interrupt_line(spi->irq,
> - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 st->indio_dev,
> + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 st->help.indio_dev,
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A00,
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0IRQF_TRIGGER_RISING,
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"adis16209");
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (ret)
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0goto error_uninitialize_ring;
>
> - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ret =3D adis16209_prob=
e_trigger(st->indio_dev);
> + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ret =3D adis16209_prob=
e_trigger(st->help.indio_dev);
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (ret)
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0goto error_unregister_line;
> =C2=A0 =C2=A0 =C2=A0 =C2=A0}
> @@ -548,19 +552,19 @@ static int __devinit adis16209_probe(struct spi_dev=
ice *spi)
> =C2=A0 =C2=A0 =C2=A0 =C2=A0return 0;
>
> =C2=A0error_remove_trigger:
> - =C2=A0 =C2=A0 =C2=A0 adis16209_remove_trigger(st->indio_dev);
> + =C2=A0 =C2=A0 =C2=A0 adis16209_remove_trigger(st->help.indio_dev);
> =C2=A0error_unregister_line:
> =C2=A0 =C2=A0 =C2=A0 =C2=A0if (spi->irq)
> - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 iio_unregister_interru=
pt_line(st->indio_dev, 0);
> + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 iio_unregister_interru=
pt_line(st->help.indio_dev, 0);
> =C2=A0error_uninitialize_ring:
> - =C2=A0 =C2=A0 =C2=A0 iio_ring_buffer_unregister(st->indio_dev->ring);
> + =C2=A0 =C2=A0 =C2=A0 iio_ring_buffer_unregister(st->help.indio_dev->rin=
g);
> =C2=A0error_unreg_ring_funcs:
> - =C2=A0 =C2=A0 =C2=A0 adis16209_unconfigure_ring(st->indio_dev);
> + =C2=A0 =C2=A0 =C2=A0 adis16209_unconfigure_ring(st->help.indio_dev);
> =C2=A0error_free_dev:
> =C2=A0 =C2=A0 =C2=A0 =C2=A0if (regdone)
> - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 iio_device_unregister(=
st->indio_dev);
> + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 iio_device_unregister(=
st->help.indio_dev);
> =C2=A0 =C2=A0 =C2=A0 =C2=A0else
> - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 iio_free_device(st->in=
dio_dev);
> + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 iio_free_device(st->he=
lp.indio_dev);
> =C2=A0error_free_tx:
> =C2=A0 =C2=A0 =C2=A0 =C2=A0kfree(st->tx);
> =C2=A0error_free_rx:
> @@ -574,7 +578,7 @@ error_ret:
> =C2=A0static int adis16209_remove(struct spi_device *spi)
> =C2=A0{
> =C2=A0 =C2=A0 =C2=A0 =C2=A0struct adis16209_state *st =3D spi_get_drvdata=
(spi);
> - =C2=A0 =C2=A0 =C2=A0 struct iio_dev *indio_dev =3D st->indio_dev;
> + =C2=A0 =C2=A0 =C2=A0 struct iio_dev *indio_dev =3D st->help.indio_dev;
>
> =C2=A0 =C2=A0 =C2=A0 =C2=A0flush_scheduled_work();
>
> diff --git a/drivers/staging/iio/accel/adis16209_ring.c b/drivers/staging=
/iio/accel/adis16209_ring.c
> index 25fde65..bb2389e 100644
> --- a/drivers/staging/iio/accel/adis16209_ring.c
> +++ b/drivers/staging/iio/accel/adis16209_ring.c
> @@ -55,17 +55,6 @@ static struct attribute_group adis16209_scan_el_group =
=3D {
> =C2=A0};
>
> =C2=A0/**
> - * adis16209_poll_func_th() top half interrupt handler called by trigger
> - * @private_data: =C2=A0 =C2=A0 =C2=A0iio_dev
> - **/
> -static void adis16209_poll_func_th(struct iio_dev *indio_dev, s64 time)
> -{
> - =C2=A0 =C2=A0 =C2=A0 struct adis16209_state *st =3D iio_dev_get_devdata=
(indio_dev);
> - =C2=A0 =C2=A0 =C2=A0 st->last_timestamp =3D time;
> - =C2=A0 =C2=A0 =C2=A0 schedule_work(&st->work_trigger_to_ring);
> -}
> -
> -/**
> =C2=A0* adis16209_read_ring_data() read data registers which will be plac=
ed into ring
> =C2=A0* @dev: device associated with child of actual device (iio_dev or i=
io_trig)
> =C2=A0* @rx: somewhere to pass back the value read
> @@ -107,44 +96,20 @@ static int adis16209_read_ring_data(struct device *d=
ev, u8 *rx)
> =C2=A0 =C2=A0 =C2=A0 =C2=A0return ret;
> =C2=A0}
>
> -/* Whilst this makes a lot of calls to iio_sw_ring functions - it is to =
device
> - * specific to be rolled into the core.
> - */
> -static void adis16209_trigger_bh_to_ring(struct work_struct *work_s)
> +static int adis16209_get_ring_element(struct iio_sw_ring_helper_state *h=
,
> + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 u8 *buf)
> =C2=A0{
> - =C2=A0 =C2=A0 =C2=A0 struct adis16209_state *st
> - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =3D container_of(work_=
s, struct adis16209_state,
> - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0work_trigger_to_ring);
> -
> - =C2=A0 =C2=A0 =C2=A0 int i =3D 0;
> - =C2=A0 =C2=A0 =C2=A0 s16 *data;
> - =C2=A0 =C2=A0 =C2=A0 size_t datasize =3D st->indio_dev
> - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ->ring->access.get_bpd=
(st->indio_dev->ring);
> -
> - =C2=A0 =C2=A0 =C2=A0 data =3D kmalloc(datasize , GFP_KERNEL);
> - =C2=A0 =C2=A0 =C2=A0 if (data =3D=3D NULL) {
> - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 dev_err(&st->us->dev, =
"memory alloc failed in ring bh");
> - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return;
> - =C2=A0 =C2=A0 =C2=A0 }
> -
> - =C2=A0 =C2=A0 =C2=A0 if (st->indio_dev->scan_count)
> - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (adis16209_read_rin=
g_data(&st->indio_dev->dev, st->rx) >=3D 0)
> - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 for (; i < st->indio_dev->scan_count; i++)
> - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 data[i] =3D be16_to_cpup(
> - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (__be16 *)&(=
st->rx[i*2]));
> -
> - =C2=A0 =C2=A0 =C2=A0 /* Guaranteed to be aligned with 8 byte boundary *=
/
> - =C2=A0 =C2=A0 =C2=A0 if (st->indio_dev->scan_timestamp)
> - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 *((s64 *)(data + ((i +=
3)/4)*4)) =3D st->last_timestamp;
> + =C2=A0 =C2=A0 =C2=A0 int i, ret;
> + =C2=A0 =C2=A0 =C2=A0 s16 *data =3D (s16 *)buf;
> + =C2=A0 =C2=A0 =C2=A0 struct adis16209_state *st =3D adis16209_h_to_s(h)=
;
>
> - =C2=A0 =C2=A0 =C2=A0 st->indio_dev->ring->access.store_to(st->indio_dev=
->ring,
> - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 (u8 *)data,
> - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 st->last_timestamp);
> -
> - =C2=A0 =C2=A0 =C2=A0 iio_trigger_notify_done(st->indio_dev->trig);
> - =C2=A0 =C2=A0 =C2=A0 kfree(data);
> + =C2=A0 =C2=A0 =C2=A0 ret =3D adis16209_read_ring_data(&h->indio_dev->de=
v, st->rx);
> + =C2=A0 =C2=A0 =C2=A0 if (ret < 0)
> + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return ret;
> + =C2=A0 =C2=A0 =C2=A0 for (i =3D 0; i < h->indio_dev->scan_count; i++)
> + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 data[i] =3D be16_to_cp=
up((__be16 *)&(st->rx[i*2]));
>
> - =C2=A0 =C2=A0 =C2=A0 return;
> + =C2=A0 =C2=A0 =C2=A0 return i*sizeof(data[0]);
> =C2=A0}
>
> =C2=A0void adis16209_unconfigure_ring(struct iio_dev *indio_dev)
> @@ -156,11 +121,11 @@ void adis16209_unconfigure_ring(struct iio_dev *ind=
io_dev)
> =C2=A0int adis16209_configure_ring(struct iio_dev *indio_dev)
> =C2=A0{
> =C2=A0 =C2=A0 =C2=A0 =C2=A0int ret =3D 0;
> - =C2=A0 =C2=A0 =C2=A0 struct adis16209_state *st =3D indio_dev->dev_data=
;
> =C2=A0 =C2=A0 =C2=A0 =C2=A0struct iio_ring_buffer *ring;
> - =C2=A0 =C2=A0 =C2=A0 INIT_WORK(&st->work_trigger_to_ring, adis16209_tri=
gger_bh_to_ring);
> + =C2=A0 =C2=A0 =C2=A0 struct iio_sw_ring_helper_state *h =3D iio_dev_get=
_devdata(indio_dev);
> + =C2=A0 =C2=A0 =C2=A0 INIT_WORK(&h->work_trigger_to_ring, iio_sw_trigger=
_bh_to_ring);
> =C2=A0 =C2=A0 =C2=A0 =C2=A0/* Set default scan mode */
> -
> + =C2=A0 =C2=A0 =C2=A0 h->get_ring_element =3D &adis16209_get_ring_elemen=
t;
> =C2=A0 =C2=A0 =C2=A0 =C2=A0iio_scan_mask_set(indio_dev, iio_scan_el_suppl=
y.number);
> =C2=A0 =C2=A0 =C2=A0 =C2=A0iio_scan_mask_set(indio_dev, iio_scan_el_rot.n=
umber);
> =C2=A0 =C2=A0 =C2=A0 =C2=A0iio_scan_mask_set(indio_dev, iio_scan_el_accel=
_x.number);
> @@ -187,7 +152,7 @@ int adis16209_configure_ring(struct iio_dev *indio_de=
v)
> =C2=A0 =C2=A0 =C2=A0 =C2=A0ring->predisable =3D &iio_triggered_ring_predi=
sable;
> =C2=A0 =C2=A0 =C2=A0 =C2=A0ring->owner =3D THIS_MODULE;
>
> - =C2=A0 =C2=A0 =C2=A0 ret =3D iio_alloc_pollfunc(indio_dev, NULL, &adis1=
6209_poll_func_th);
> + =C2=A0 =C2=A0 =C2=A0 ret =3D iio_alloc_pollfunc(indio_dev, NULL, &iio_s=
w_poll_func_th);
> =C2=A0 =C2=A0 =C2=A0 =C2=A0if (ret)
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0goto error_iio_sw_=
rb_free;
>
> diff --git a/drivers/staging/iio/accel/adis16209_trigger.c b/drivers/stag=
ing/iio/accel/adis16209_trigger.c
> index 1487eff..51cdf4a 100644
> --- a/drivers/staging/iio/accel/adis16209_trigger.c
> +++ b/drivers/staging/iio/accel/adis16209_trigger.c
> @@ -10,6 +10,7 @@
> =C2=A0#include "../iio.h"
> =C2=A0#include "../sysfs.h"
> =C2=A0#include "../trigger.h"
> +#include "../ring_sw.h"
> =C2=A0#include "adis16209.h"
>
> =C2=A0/**
> @@ -48,11 +49,11 @@ static int adis16209_data_rdy_trigger_set_state(struc=
t iio_trigger *trig,
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0bool state)
> =C2=A0{
> =C2=A0 =C2=A0 =C2=A0 =C2=A0struct adis16209_state *st =3D trig->private_d=
ata;
> - =C2=A0 =C2=A0 =C2=A0 struct iio_dev *indio_dev =3D st->indio_dev;
> + =C2=A0 =C2=A0 =C2=A0 struct iio_dev *indio_dev =3D st->help.indio_dev;
> =C2=A0 =C2=A0 =C2=A0 =C2=A0int ret =3D 0;
>
> =C2=A0 =C2=A0 =C2=A0 =C2=A0dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__=
, state);
> - =C2=A0 =C2=A0 =C2=A0 ret =3D adis16209_set_irq(&st->indio_dev->dev, sta=
te);
> + =C2=A0 =C2=A0 =C2=A0 ret =3D adis16209_set_irq(&indio_dev->dev, state);
> =C2=A0 =C2=A0 =C2=A0 =C2=A0if (state =3D=3D false) {
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0iio_remove_event_f=
rom_list(&iio_event_data_rdy_trig,
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 &=
indio_dev->interrupts[0]
> @@ -79,7 +80,8 @@ static int adis16209_trig_try_reen(struct iio_trigger *=
trig)
> =C2=A0int adis16209_probe_trigger(struct iio_dev *indio_dev)
> =C2=A0{
> =C2=A0 =C2=A0 =C2=A0 =C2=A0int ret;
> - =C2=A0 =C2=A0 =C2=A0 struct adis16209_state *st =3D indio_dev->dev_data=
;
> + =C2=A0 =C2=A0 =C2=A0 struct iio_sw_ring_helper_state *h =3D iio_dev_get=
_devdata(indio_dev);
> + =C2=A0 =C2=A0 =C2=A0 struct adis16209_state *st =3D adis16209_h_to_s(h)=
;
>
> =C2=A0 =C2=A0 =C2=A0 =C2=A0st->trig =3D iio_allocate_trigger();
> =C2=A0 =C2=A0 =C2=A0 =C2=A0st->trig->name =3D kasprintf(GFP_KERNEL,
> --
> 1.7.0.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at =C2=A0http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 5/5 v2] staging:iio:adis16209 use iio_sw_ring_helper_state and funcs
2010-07-08 9:37 ` Barry Song
@ 2010-07-08 14:46 ` Jonathan Cameron
0 siblings, 0 replies; 5+ messages in thread
From: Jonathan Cameron @ 2010-07-08 14:46 UTC (permalink / raw)
To: Barry Song; +Cc: linux-iio
On 07/08/10 10:37, Barry Song wrote:
> On Thu, Jul 1, 2010 at 12:07 AM, Jonathan Cameron <jic23@cam.ac.uk> wrote:
>> Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
> Thanks very much. Has this one been tested? If so,
> Acked-by: Barry Song <21cnbao@gmail.com>.
Nope. Don't have one of these... I'll hold off on sending this
to Greg until I have confirmation it works.
> And I will send related patches for other drivers too.
Excellent.
> -barry
>> ---
>>
>> The get element fuction should return how much of the buffer it has
>> used. Now it actually does this.
>>
>> drivers/staging/iio/accel/adis16209.h | 7 ++-
>> drivers/staging/iio/accel/adis16209_core.c | 54 +++++++++++----------
>> drivers/staging/iio/accel/adis16209_ring.c | 65 ++++++-------------------
>> drivers/staging/iio/accel/adis16209_trigger.c | 8 ++-
>> 4 files changed, 53 insertions(+), 81 deletions(-)
>>
>> diff --git a/drivers/staging/iio/accel/adis16209.h b/drivers/staging/iio/accel/adis16209.h
>> index 92daf6f..84e1a2f 100644
>> --- a/drivers/staging/iio/accel/adis16209.h
>> +++ b/drivers/staging/iio/accel/adis16209.h
>> @@ -113,16 +113,17 @@
>> * @buf_lock: mutex to protect tx and rx
>> **/
>> struct adis16209_state {
>> + struct iio_sw_ring_helper_state help;
>> struct spi_device *us;
>> - struct work_struct work_trigger_to_ring;
>> - s64 last_timestamp;
>> - struct iio_dev *indio_dev;
>> struct iio_trigger *trig;
>> u8 *tx;
>> u8 *rx;
>> struct mutex buf_lock;
>> };
>>
>> +#define adis16209_h_to_s(_h) \
>> + container_of(_h, struct adis16209_state, help)
>> +
>> int adis16209_set_irq(struct device *dev, bool enable);
>>
>> #ifdef CONFIG_IIO_RING_BUFFER
>> diff --git a/drivers/staging/iio/accel/adis16209_core.c b/drivers/staging/iio/accel/adis16209_core.c
>> index 6c6923f..9c7aafe 100644
>> --- a/drivers/staging/iio/accel/adis16209_core.c
>> +++ b/drivers/staging/iio/accel/adis16209_core.c
>> @@ -21,6 +21,7 @@
>> #include "../iio.h"
>> #include "../sysfs.h"
>> #include "../ring_generic.h"
>> +#include "../ring_sw.h"
>> #include "accel.h"
>> #include "inclinometer.h"
>> #include "../gyro/gyro.h"
>> @@ -44,7 +45,8 @@ static int adis16209_spi_write_reg_8(struct device *dev,
>> {
>> int ret;
>> struct iio_dev *indio_dev = dev_get_drvdata(dev);
>> - struct adis16209_state *st = iio_dev_get_devdata(indio_dev);
>> + struct iio_sw_ring_helper_state *h = iio_dev_get_devdata(indio_dev);
>> + struct adis16209_state *st = adis16209_h_to_s(h);
>>
>> mutex_lock(&st->buf_lock);
>> st->tx[0] = ADIS16209_WRITE_REG(reg_address);
>> @@ -70,7 +72,8 @@ static int adis16209_spi_write_reg_16(struct device *dev,
>> int ret;
>> struct spi_message msg;
>> struct iio_dev *indio_dev = dev_get_drvdata(dev);
>> - struct adis16209_state *st = iio_dev_get_devdata(indio_dev);
>> + struct iio_sw_ring_helper_state *h = iio_dev_get_devdata(indio_dev);
>> + struct adis16209_state *st = adis16209_h_to_s(h);
>> struct spi_transfer xfers[] = {
>> {
>> .tx_buf = st->tx,
>> @@ -115,7 +118,8 @@ static int adis16209_spi_read_reg_16(struct device *dev,
>> {
>> struct spi_message msg;
>> struct iio_dev *indio_dev = dev_get_drvdata(dev);
>> - struct adis16209_state *st = iio_dev_get_devdata(indio_dev);
>> + struct iio_sw_ring_helper_state *h = iio_dev_get_devdata(indio_dev);
>> + struct adis16209_state *st = adis16209_h_to_s(h);
>> int ret;
>> struct spi_transfer xfers[] = {
>> {
>> @@ -355,7 +359,7 @@ err_ret:
>> static int adis16209_initial_setup(struct adis16209_state *st)
>> {
>> int ret;
>> - struct device *dev = &st->indio_dev->dev;
>> + struct device *dev = &st->help.indio_dev->dev;
>>
>> /* Disable IRQ */
>> ret = adis16209_set_irq(dev, false);
>> @@ -498,30 +502,30 @@ static int __devinit adis16209_probe(struct spi_device *spi)
>> st->us = spi;
>> mutex_init(&st->buf_lock);
>> /* setup the industrialio driver allocated elements */
>> - st->indio_dev = iio_allocate_device();
>> - if (st->indio_dev == NULL) {
>> + st->help.indio_dev = iio_allocate_device();
>> + if (st->help.indio_dev == NULL) {
>> ret = -ENOMEM;
>> goto error_free_tx;
>> }
>>
>> - st->indio_dev->dev.parent = &spi->dev;
>> - st->indio_dev->num_interrupt_lines = 1;
>> - st->indio_dev->event_attrs = &adis16209_event_attribute_group;
>> - st->indio_dev->attrs = &adis16209_attribute_group;
>> - st->indio_dev->dev_data = (void *)(st);
>> - st->indio_dev->driver_module = THIS_MODULE;
>> - st->indio_dev->modes = INDIO_DIRECT_MODE;
>> + st->help.indio_dev->dev.parent = &spi->dev;
>> + st->help.indio_dev->num_interrupt_lines = 1;
>> + st->help.indio_dev->event_attrs = &adis16209_event_attribute_group;
>> + st->help.indio_dev->attrs = &adis16209_attribute_group;
>> + st->help.indio_dev->dev_data = (void *)(&st->help);
>> + st->help.indio_dev->driver_module = THIS_MODULE;
>> + st->help.indio_dev->modes = INDIO_DIRECT_MODE;
>>
>> - ret = adis16209_configure_ring(st->indio_dev);
>> + ret = adis16209_configure_ring(st->help.indio_dev);
>> if (ret)
>> goto error_free_dev;
>>
>> - ret = iio_device_register(st->indio_dev);
>> + ret = iio_device_register(st->help.indio_dev);
>> if (ret)
>> goto error_unreg_ring_funcs;
>> regdone = 1;
>>
>> - ret = iio_ring_buffer_register(st->indio_dev->ring, 0);
>> + ret = iio_ring_buffer_register(st->help.indio_dev->ring, 0);
>> if (ret) {
>> printk(KERN_ERR "failed to initialize the ring\n");
>> goto error_unreg_ring_funcs;
>> @@ -529,14 +533,14 @@ static int __devinit adis16209_probe(struct spi_device *spi)
>>
>> if (spi->irq) {
>> ret = iio_register_interrupt_line(spi->irq,
>> - st->indio_dev,
>> + st->help.indio_dev,
>> 0,
>> IRQF_TRIGGER_RISING,
>> "adis16209");
>> if (ret)
>> goto error_uninitialize_ring;
>>
>> - ret = adis16209_probe_trigger(st->indio_dev);
>> + ret = adis16209_probe_trigger(st->help.indio_dev);
>> if (ret)
>> goto error_unregister_line;
>> }
>> @@ -548,19 +552,19 @@ static int __devinit adis16209_probe(struct spi_device *spi)
>> return 0;
>>
>> error_remove_trigger:
>> - adis16209_remove_trigger(st->indio_dev);
>> + adis16209_remove_trigger(st->help.indio_dev);
>> error_unregister_line:
>> if (spi->irq)
>> - iio_unregister_interrupt_line(st->indio_dev, 0);
>> + iio_unregister_interrupt_line(st->help.indio_dev, 0);
>> error_uninitialize_ring:
>> - iio_ring_buffer_unregister(st->indio_dev->ring);
>> + iio_ring_buffer_unregister(st->help.indio_dev->ring);
>> error_unreg_ring_funcs:
>> - adis16209_unconfigure_ring(st->indio_dev);
>> + adis16209_unconfigure_ring(st->help.indio_dev);
>> error_free_dev:
>> if (regdone)
>> - iio_device_unregister(st->indio_dev);
>> + iio_device_unregister(st->help.indio_dev);
>> else
>> - iio_free_device(st->indio_dev);
>> + iio_free_device(st->help.indio_dev);
>> error_free_tx:
>> kfree(st->tx);
>> error_free_rx:
>> @@ -574,7 +578,7 @@ error_ret:
>> static int adis16209_remove(struct spi_device *spi)
>> {
>> struct adis16209_state *st = spi_get_drvdata(spi);
>> - struct iio_dev *indio_dev = st->indio_dev;
>> + struct iio_dev *indio_dev = st->help.indio_dev;
>>
>> flush_scheduled_work();
>>
>> diff --git a/drivers/staging/iio/accel/adis16209_ring.c b/drivers/staging/iio/accel/adis16209_ring.c
>> index 25fde65..bb2389e 100644
>> --- a/drivers/staging/iio/accel/adis16209_ring.c
>> +++ b/drivers/staging/iio/accel/adis16209_ring.c
>> @@ -55,17 +55,6 @@ static struct attribute_group adis16209_scan_el_group = {
>> };
>>
>> /**
>> - * adis16209_poll_func_th() top half interrupt handler called by trigger
>> - * @private_data: iio_dev
>> - **/
>> -static void adis16209_poll_func_th(struct iio_dev *indio_dev, s64 time)
>> -{
>> - struct adis16209_state *st = iio_dev_get_devdata(indio_dev);
>> - st->last_timestamp = time;
>> - schedule_work(&st->work_trigger_to_ring);
>> -}
>> -
>> -/**
>> * adis16209_read_ring_data() read data registers which will be placed into ring
>> * @dev: device associated with child of actual device (iio_dev or iio_trig)
>> * @rx: somewhere to pass back the value read
>> @@ -107,44 +96,20 @@ static int adis16209_read_ring_data(struct device *dev, u8 *rx)
>> return ret;
>> }
>>
>> -/* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device
>> - * specific to be rolled into the core.
>> - */
>> -static void adis16209_trigger_bh_to_ring(struct work_struct *work_s)
>> +static int adis16209_get_ring_element(struct iio_sw_ring_helper_state *h,
>> + u8 *buf)
>> {
>> - struct adis16209_state *st
>> - = container_of(work_s, struct adis16209_state,
>> - work_trigger_to_ring);
>> -
>> - int i = 0;
>> - s16 *data;
>> - size_t datasize = st->indio_dev
>> - ->ring->access.get_bpd(st->indio_dev->ring);
>> -
>> - data = kmalloc(datasize , GFP_KERNEL);
>> - if (data == NULL) {
>> - dev_err(&st->us->dev, "memory alloc failed in ring bh");
>> - return;
>> - }
>> -
>> - if (st->indio_dev->scan_count)
>> - if (adis16209_read_ring_data(&st->indio_dev->dev, st->rx) >= 0)
>> - for (; i < st->indio_dev->scan_count; i++)
>> - data[i] = be16_to_cpup(
>> - (__be16 *)&(st->rx[i*2]));
>> -
>> - /* Guaranteed to be aligned with 8 byte boundary */
>> - if (st->indio_dev->scan_timestamp)
>> - *((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
>> + int i, ret;
>> + s16 *data = (s16 *)buf;
>> + struct adis16209_state *st = adis16209_h_to_s(h);
>>
>> - st->indio_dev->ring->access.store_to(st->indio_dev->ring,
>> - (u8 *)data,
>> - st->last_timestamp);
>> -
>> - iio_trigger_notify_done(st->indio_dev->trig);
>> - kfree(data);
>> + ret = adis16209_read_ring_data(&h->indio_dev->dev, st->rx);
>> + if (ret < 0)
>> + return ret;
>> + for (i = 0; i < h->indio_dev->scan_count; i++)
>> + data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2]));
>>
>> - return;
>> + return i*sizeof(data[0]);
>> }
>>
>> void adis16209_unconfigure_ring(struct iio_dev *indio_dev)
>> @@ -156,11 +121,11 @@ void adis16209_unconfigure_ring(struct iio_dev *indio_dev)
>> int adis16209_configure_ring(struct iio_dev *indio_dev)
>> {
>> int ret = 0;
>> - struct adis16209_state *st = indio_dev->dev_data;
>> struct iio_ring_buffer *ring;
>> - INIT_WORK(&st->work_trigger_to_ring, adis16209_trigger_bh_to_ring);
>> + struct iio_sw_ring_helper_state *h = iio_dev_get_devdata(indio_dev);
>> + INIT_WORK(&h->work_trigger_to_ring, iio_sw_trigger_bh_to_ring);
>> /* Set default scan mode */
>> -
>> + h->get_ring_element = &adis16209_get_ring_element;
>> iio_scan_mask_set(indio_dev, iio_scan_el_supply.number);
>> iio_scan_mask_set(indio_dev, iio_scan_el_rot.number);
>> iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number);
>> @@ -187,7 +152,7 @@ int adis16209_configure_ring(struct iio_dev *indio_dev)
>> ring->predisable = &iio_triggered_ring_predisable;
>> ring->owner = THIS_MODULE;
>>
>> - ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16209_poll_func_th);
>> + ret = iio_alloc_pollfunc(indio_dev, NULL, &iio_sw_poll_func_th);
>> if (ret)
>> goto error_iio_sw_rb_free;
>>
>> diff --git a/drivers/staging/iio/accel/adis16209_trigger.c b/drivers/staging/iio/accel/adis16209_trigger.c
>> index 1487eff..51cdf4a 100644
>> --- a/drivers/staging/iio/accel/adis16209_trigger.c
>> +++ b/drivers/staging/iio/accel/adis16209_trigger.c
>> @@ -10,6 +10,7 @@
>> #include "../iio.h"
>> #include "../sysfs.h"
>> #include "../trigger.h"
>> +#include "../ring_sw.h"
>> #include "adis16209.h"
>>
>> /**
>> @@ -48,11 +49,11 @@ static int adis16209_data_rdy_trigger_set_state(struct iio_trigger *trig,
>> bool state)
>> {
>> struct adis16209_state *st = trig->private_data;
>> - struct iio_dev *indio_dev = st->indio_dev;
>> + struct iio_dev *indio_dev = st->help.indio_dev;
>> int ret = 0;
>>
>> dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state);
>> - ret = adis16209_set_irq(&st->indio_dev->dev, state);
>> + ret = adis16209_set_irq(&indio_dev->dev, state);
>> if (state == false) {
>> iio_remove_event_from_list(&iio_event_data_rdy_trig,
>> &indio_dev->interrupts[0]
>> @@ -79,7 +80,8 @@ static int adis16209_trig_try_reen(struct iio_trigger *trig)
>> int adis16209_probe_trigger(struct iio_dev *indio_dev)
>> {
>> int ret;
>> - struct adis16209_state *st = indio_dev->dev_data;
>> + struct iio_sw_ring_helper_state *h = iio_dev_get_devdata(indio_dev);
>> + struct adis16209_state *st = adis16209_h_to_s(h);
>>
>> st->trig = iio_allocate_trigger();
>> st->trig->name = kasprintf(GFP_KERNEL,
>> --
>> 1.7.0.4
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>>
>
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2010-07-08 14:45 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-06-30 16:07 [PATCH 4/5 v2] staging:iio:lis3l02dq use iio_sw_ring_helper_state and funcs Jonathan Cameron
2010-06-30 16:07 ` [PATCH 5/5 v2] staging:iio:adis16209 " Jonathan Cameron
2010-07-08 9:37 ` Barry Song
2010-07-08 14:46 ` Jonathan Cameron
2010-07-08 9:32 ` [PATCH 4/5 v2] staging:iio:lis3l02dq " Barry Song
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.