aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/iio/imu/adis16400_core.c
diff options
context:
space:
mode:
authorJonathan Cameron <jic23@cam.ac.uk>2011-05-18 09:42:23 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-05-19 19:15:03 -0400
commit38d15f06f942306050a063abd111467d39c5cc37 (patch)
tree845d3de4cdc07833e51ed906c23b42980376232e /drivers/staging/iio/imu/adis16400_core.c
parent59c85e82c2e7a672cb4342dc5ccf9df8a3a14f73 (diff)
staging:iio:imu:adis16400 avoid allocating rx, tx, and state separately from iio_dev.
Uses the iio_allocate_device parameter to set aside space for adis16400_state and ____cacheline_aligned buffers for tx and rx to avoid separatel allocating them. Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging/iio/imu/adis16400_core.c')
-rw-r--r--drivers/staging/iio/imu/adis16400_core.c112
1 files changed, 44 insertions, 68 deletions
diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c
index 6419b756421..0067bc70acb 100644
--- a/drivers/staging/iio/imu/adis16400_core.c
+++ b/drivers/staging/iio/imu/adis16400_core.c
@@ -66,7 +66,7 @@ static int adis16400_spi_write_reg_8(struct iio_dev *indio_dev,
66 u8 val) 66 u8 val)
67{ 67{
68 int ret; 68 int ret;
69 struct adis16400_state *st = iio_dev_get_devdata(indio_dev); 69 struct adis16400_state *st = iio_priv(indio_dev);
70 70
71 mutex_lock(&st->buf_lock); 71 mutex_lock(&st->buf_lock);
72 st->tx[0] = ADIS16400_WRITE_REG(reg_address); 72 st->tx[0] = ADIS16400_WRITE_REG(reg_address);
@@ -91,7 +91,7 @@ static int adis16400_spi_write_reg_16(struct iio_dev *indio_dev,
91{ 91{
92 int ret; 92 int ret;
93 struct spi_message msg; 93 struct spi_message msg;
94 struct adis16400_state *st = iio_dev_get_devdata(indio_dev); 94 struct adis16400_state *st = iio_priv(indio_dev);
95 struct spi_transfer xfers[] = { 95 struct spi_transfer xfers[] = {
96 { 96 {
97 .tx_buf = st->tx, 97 .tx_buf = st->tx,
@@ -132,7 +132,7 @@ static int adis16400_spi_read_reg_16(struct iio_dev *indio_dev,
132 u16 *val) 132 u16 *val)
133{ 133{
134 struct spi_message msg; 134 struct spi_message msg;
135 struct adis16400_state *st = iio_dev_get_devdata(indio_dev); 135 struct adis16400_state *st = iio_priv(indio_dev);
136 int ret; 136 int ret;
137 struct spi_transfer xfers[] = { 137 struct spi_transfer xfers[] = {
138 { 138 {
@@ -195,7 +195,7 @@ static ssize_t adis16400_write_frequency(struct device *dev,
195 size_t len) 195 size_t len)
196{ 196{
197 struct iio_dev *indio_dev = dev_get_drvdata(dev); 197 struct iio_dev *indio_dev = dev_get_drvdata(dev);
198 struct adis16400_state *st = iio_dev_get_devdata(indio_dev); 198 struct adis16400_state *st = iio_priv(indio_dev);
199 long val; 199 long val;
200 int ret; 200 int ret;
201 u8 t; 201 u8 t;
@@ -356,11 +356,12 @@ error_ret:
356 return ret; 356 return ret;
357} 357}
358 358
359static int adis16400_initial_setup(struct adis16400_state *st) 359static int adis16400_initial_setup(struct iio_dev *indio_dev)
360{ 360{
361 int ret; 361 int ret;
362 u16 prod_id, smp_prd; 362 u16 prod_id, smp_prd;
363 struct device *dev = &st->indio_dev->dev; 363 struct device *dev = &indio_dev->dev;
364 struct adis16400_state *st = iio_priv(indio_dev);
364 365
365 /* use low spi speed for init */ 366 /* use low spi speed for init */
366 st->us->max_speed_hz = ADIS16400_SPI_SLOW; 367 st->us->max_speed_hz = ADIS16400_SPI_SLOW;
@@ -368,33 +369,33 @@ static int adis16400_initial_setup(struct adis16400_state *st)
368 spi_setup(st->us); 369 spi_setup(st->us);
369 370
370 /* Disable IRQ */ 371 /* Disable IRQ */
371 ret = adis16400_set_irq(st->indio_dev, false); 372 ret = adis16400_set_irq(indio_dev, false);
372 if (ret) { 373 if (ret) {
373 dev_err(dev, "disable irq failed"); 374 dev_err(dev, "disable irq failed");
374 goto err_ret; 375 goto err_ret;
375 } 376 }
376 377
377 /* Do self test */ 378 /* Do self test */
378 ret = adis16400_self_test(st->indio_dev); 379 ret = adis16400_self_test(indio_dev);
379 if (ret) { 380 if (ret) {
380 dev_err(dev, "self test failure"); 381 dev_err(dev, "self test failure");
381 goto err_ret; 382 goto err_ret;
382 } 383 }
383 384
384 /* Read status register to check the result */ 385 /* Read status register to check the result */
385 ret = adis16400_check_status(st->indio_dev); 386 ret = adis16400_check_status(indio_dev);
386 if (ret) { 387 if (ret) {
387 adis16400_reset(st->indio_dev); 388 adis16400_reset(indio_dev);
388 dev_err(dev, "device not playing ball -> reset"); 389 dev_err(dev, "device not playing ball -> reset");
389 msleep(ADIS16400_STARTUP_DELAY); 390 msleep(ADIS16400_STARTUP_DELAY);
390 ret = adis16400_check_status(st->indio_dev); 391 ret = adis16400_check_status(indio_dev);
391 if (ret) { 392 if (ret) {
392 dev_err(dev, "giving up"); 393 dev_err(dev, "giving up");
393 goto err_ret; 394 goto err_ret;
394 } 395 }
395 } 396 }
396 if (st->variant->flags & ADIS16400_HAS_PROD_ID) { 397 if (st->variant->flags & ADIS16400_HAS_PROD_ID) {
397 ret = adis16400_spi_read_reg_16(st->indio_dev, 398 ret = adis16400_spi_read_reg_16(indio_dev,
398 ADIS16400_PRODUCT_ID, &prod_id); 399 ADIS16400_PRODUCT_ID, &prod_id);
399 if (ret) 400 if (ret)
400 goto err_ret; 401 goto err_ret;
@@ -406,7 +407,7 @@ static int adis16400_initial_setup(struct adis16400_state *st)
406 prod_id, st->us->chip_select, st->us->irq); 407 prod_id, st->us->chip_select, st->us->irq);
407 } 408 }
408 /* use high spi speed if possible */ 409 /* use high spi speed if possible */
409 ret = adis16400_spi_read_reg_16(st->indio_dev, 410 ret = adis16400_spi_read_reg_16(indio_dev,
410 ADIS16400_SMPL_PRD, &smp_prd); 411 ADIS16400_SMPL_PRD, &smp_prd);
411 if (!ret && (smp_prd & ADIS16400_SMPL_PRD_DIV_MASK) < 0x0A) { 412 if (!ret && (smp_prd & ADIS16400_SMPL_PRD_DIV_MASK) < 0x0A) {
412 st->us->max_speed_hz = ADIS16400_SPI_SLOW; 413 st->us->max_speed_hz = ADIS16400_SPI_SLOW;
@@ -487,7 +488,7 @@ static int adis16400_read_raw(struct iio_dev *indio_dev,
487 int *val2, 488 int *val2,
488 long mask) 489 long mask)
489{ 490{
490 struct adis16400_state *st = iio_dev_get_devdata(indio_dev); 491 struct adis16400_state *st = iio_priv(indio_dev);
491 int ret; 492 int ret;
492 s16 val16; 493 s16 val16;
493 int shift; 494 int shift;
@@ -774,55 +775,41 @@ static struct adis16400_chip_info adis16400_chips[] = {
774static int __devinit adis16400_probe(struct spi_device *spi) 775static int __devinit adis16400_probe(struct spi_device *spi)
775{ 776{
776 int ret, regdone = 0; 777 int ret, regdone = 0;
777 struct adis16400_state *st = kzalloc(sizeof *st, GFP_KERNEL); 778 struct adis16400_state *st;
778 if (!st) { 779 struct iio_dev *indio_dev = iio_allocate_device(sizeof(*st));
780 if (indio_dev == NULL) {
779 ret = -ENOMEM; 781 ret = -ENOMEM;
780 goto error_ret; 782 goto error_ret;
781 } 783 }
784 st = iio_priv(indio_dev);
782 /* this is only used for removal purposes */ 785 /* this is only used for removal purposes */
783 spi_set_drvdata(spi, st); 786 spi_set_drvdata(spi, indio_dev);
784 787
785 /* Allocate the comms buffers */
786 st->rx = kzalloc(sizeof(*st->rx)*ADIS16400_MAX_RX, GFP_KERNEL);
787 if (st->rx == NULL) {
788 ret = -ENOMEM;
789 goto error_free_st;
790 }
791 st->tx = kzalloc(sizeof(*st->tx)*ADIS16400_MAX_TX, GFP_KERNEL);
792 if (st->tx == NULL) {
793 ret = -ENOMEM;
794 goto error_free_rx;
795 }
796 st->us = spi; 788 st->us = spi;
797 mutex_init(&st->buf_lock); 789 mutex_init(&st->buf_lock);
790
798 /* setup the industrialio driver allocated elements */ 791 /* setup the industrialio driver allocated elements */
799 st->indio_dev = iio_allocate_device(0);
800 if (st->indio_dev == NULL) {
801 ret = -ENOMEM;
802 goto error_free_tx;
803 }
804 st->variant = &adis16400_chips[spi_get_device_id(spi)->driver_data]; 792 st->variant = &adis16400_chips[spi_get_device_id(spi)->driver_data];
805 st->indio_dev->dev.parent = &spi->dev; 793 indio_dev->dev.parent = &spi->dev;
806 st->indio_dev->name = spi_get_device_id(spi)->name; 794 indio_dev->name = spi_get_device_id(spi)->name;
807 st->indio_dev->attrs = &adis16400_attribute_group; 795 indio_dev->attrs = &adis16400_attribute_group;
808 st->indio_dev->channels = st->variant->channels; 796 indio_dev->channels = st->variant->channels;
809 st->indio_dev->num_channels = st->variant->num_channels; 797 indio_dev->num_channels = st->variant->num_channels;
810 st->indio_dev->read_raw = &adis16400_read_raw; 798 indio_dev->read_raw = &adis16400_read_raw;
811 st->indio_dev->write_raw = &adis16400_write_raw; 799 indio_dev->write_raw = &adis16400_write_raw;
812 st->indio_dev->dev_data = (void *)(st); 800 indio_dev->driver_module = THIS_MODULE;
813 st->indio_dev->driver_module = THIS_MODULE; 801 indio_dev->modes = INDIO_DIRECT_MODE;
814 st->indio_dev->modes = INDIO_DIRECT_MODE; 802
815 803 ret = adis16400_configure_ring(indio_dev);
816 ret = adis16400_configure_ring(st->indio_dev);
817 if (ret) 804 if (ret)
818 goto error_free_dev; 805 goto error_free_dev;
819 806
820 ret = iio_device_register(st->indio_dev); 807 ret = iio_device_register(indio_dev);
821 if (ret) 808 if (ret)
822 goto error_unreg_ring_funcs; 809 goto error_unreg_ring_funcs;
823 regdone = 1; 810 regdone = 1;
824 811
825 ret = iio_ring_buffer_register_ex(st->indio_dev->ring, 0, 812 ret = iio_ring_buffer_register_ex(indio_dev->ring, 0,
826 st->variant->channels, 813 st->variant->channels,
827 st->variant->num_channels); 814 st->variant->num_channels);
828 if (ret) { 815 if (ret) {
@@ -831,35 +818,29 @@ static int __devinit adis16400_probe(struct spi_device *spi)
831 } 818 }
832 819
833 if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) { 820 if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) {
834 ret = adis16400_probe_trigger(st->indio_dev); 821 ret = adis16400_probe_trigger(indio_dev);
835 if (ret) 822 if (ret)
836 goto error_uninitialize_ring; 823 goto error_uninitialize_ring;
837 } 824 }
838 825
839 /* Get the device into a sane initial state */ 826 /* Get the device into a sane initial state */
840 ret = adis16400_initial_setup(st); 827 ret = adis16400_initial_setup(indio_dev);
841 if (ret) 828 if (ret)
842 goto error_remove_trigger; 829 goto error_remove_trigger;
843 return 0; 830 return 0;
844 831
845error_remove_trigger: 832error_remove_trigger:
846 if (st->indio_dev->modes & INDIO_RING_TRIGGERED) 833 if (indio_dev->modes & INDIO_RING_TRIGGERED)
847 adis16400_remove_trigger(st->indio_dev); 834 adis16400_remove_trigger(indio_dev);
848error_uninitialize_ring: 835error_uninitialize_ring:
849 iio_ring_buffer_unregister(st->indio_dev->ring); 836 iio_ring_buffer_unregister(indio_dev->ring);
850error_unreg_ring_funcs: 837error_unreg_ring_funcs:
851 adis16400_unconfigure_ring(st->indio_dev); 838 adis16400_unconfigure_ring(indio_dev);
852error_free_dev: 839error_free_dev:
853 if (regdone) 840 if (regdone)
854 iio_device_unregister(st->indio_dev); 841 iio_device_unregister(indio_dev);
855 else 842 else
856 iio_free_device(st->indio_dev); 843 iio_free_device(indio_dev);
857error_free_tx:
858 kfree(st->tx);
859error_free_rx:
860 kfree(st->rx);
861error_free_st:
862 kfree(st);
863error_ret: 844error_ret:
864 return ret; 845 return ret;
865} 846}
@@ -868,22 +849,17 @@ error_ret:
868static int adis16400_remove(struct spi_device *spi) 849static int adis16400_remove(struct spi_device *spi)
869{ 850{
870 int ret; 851 int ret;
871 struct adis16400_state *st = spi_get_drvdata(spi); 852 struct iio_dev *indio_dev = spi_get_drvdata(spi);
872 struct iio_dev *indio_dev = st->indio_dev;
873 853
874 ret = adis16400_stop_device(indio_dev); 854 ret = adis16400_stop_device(indio_dev);
875 if (ret) 855 if (ret)
876 goto err_ret; 856 goto err_ret;
877 857
878 adis16400_remove_trigger(indio_dev); 858 adis16400_remove_trigger(indio_dev);
879 iio_ring_buffer_unregister(st->indio_dev->ring); 859 iio_ring_buffer_unregister(indio_dev->ring);
880 adis16400_unconfigure_ring(indio_dev); 860 adis16400_unconfigure_ring(indio_dev);
881 iio_device_unregister(indio_dev); 861 iio_device_unregister(indio_dev);
882 862
883 kfree(st->tx);
884 kfree(st->rx);
885 kfree(st);
886
887 return 0; 863 return 0;
888 864
889err_ret: 865err_ret: