All of lore.kernel.org
 help / color / mirror / Atom feed
* [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.