diff options
author | Jonathan Cameron <jic23@cam.ac.uk> | 2011-05-18 09:42:23 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-05-19 19:15:03 -0400 |
commit | 38d15f06f942306050a063abd111467d39c5cc37 (patch) | |
tree | 845d3de4cdc07833e51ed906c23b42980376232e /drivers/staging/iio/imu/adis16400_core.c | |
parent | 59c85e82c2e7a672cb4342dc5ccf9df8a3a14f73 (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.c | 112 |
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 | ||
359 | static int adis16400_initial_setup(struct adis16400_state *st) | 359 | static 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[] = { | |||
774 | static int __devinit adis16400_probe(struct spi_device *spi) | 775 | static 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 | ||
845 | error_remove_trigger: | 832 | error_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); |
848 | error_uninitialize_ring: | 835 | error_uninitialize_ring: |
849 | iio_ring_buffer_unregister(st->indio_dev->ring); | 836 | iio_ring_buffer_unregister(indio_dev->ring); |
850 | error_unreg_ring_funcs: | 837 | error_unreg_ring_funcs: |
851 | adis16400_unconfigure_ring(st->indio_dev); | 838 | adis16400_unconfigure_ring(indio_dev); |
852 | error_free_dev: | 839 | error_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); |
857 | error_free_tx: | ||
858 | kfree(st->tx); | ||
859 | error_free_rx: | ||
860 | kfree(st->rx); | ||
861 | error_free_st: | ||
862 | kfree(st); | ||
863 | error_ret: | 844 | error_ret: |
864 | return ret; | 845 | return ret; |
865 | } | 846 | } |
@@ -868,22 +849,17 @@ error_ret: | |||
868 | static int adis16400_remove(struct spi_device *spi) | 849 | static 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 | ||
889 | err_ret: | 865 | err_ret: |