Commit 3d85fb6f authored by Daniel Baluta's avatar Daniel Baluta Committed by Jonathan Cameron

iio: dummy: Convert IIO dummy to configfs

We register a new device type named "dummy", this will create a
configfs entry under:
	* /config/iio/devices/dummy.

Creating dummy devices is now as simple as:

$ mkdir /config/iio/devices/dummy/my_dummy_device
Signed-off-by: default avatarDaniel Baluta <daniel.baluta@intel.com>
Signed-off-by: default avatarJonathan Cameron <jic23@kernel.org>
parent 0f3a8c3f
...@@ -10,6 +10,7 @@ config IIO_DUMMY_EVGEN ...@@ -10,6 +10,7 @@ config IIO_DUMMY_EVGEN
config IIO_SIMPLE_DUMMY config IIO_SIMPLE_DUMMY
tristate "An example driver with no hardware requirements" tristate "An example driver with no hardware requirements"
depends on IIO_SW_DEVICE
help help
Driver intended mainly as documentation for how to write Driver intended mainly as documentation for how to write
a driver. May also be useful for testing userspace code a driver. May also be useful for testing userspace code
......
...@@ -17,26 +17,18 @@ ...@@ -17,26 +17,18 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/string.h>
#include <linux/iio/iio.h> #include <linux/iio/iio.h>
#include <linux/iio/sysfs.h> #include <linux/iio/sysfs.h>
#include <linux/iio/events.h> #include <linux/iio/events.h>
#include <linux/iio/buffer.h> #include <linux/iio/buffer.h>
#include <linux/iio/sw_device.h>
#include "iio_simple_dummy.h" #include "iio_simple_dummy.h"
/* static struct config_item_type iio_dummy_type = {
* A few elements needed to fake a bus for this driver .ct_owner = THIS_MODULE,
* Note instances parameter controls how many of these };
* dummy devices are registered.
*/
static unsigned instances = 1;
module_param(instances, uint, 0);
/* Pointer array used to fake bus elements */
static struct iio_dev **iio_dummy_devs;
/* Fake a name for the part number, usually obtained from the id table */
static const char *iio_dummy_part_number = "iio_dummy_part_no";
/** /**
* struct iio_dummy_accel_calibscale - realworld to register mapping * struct iio_dummy_accel_calibscale - realworld to register mapping
...@@ -572,12 +564,18 @@ static int iio_dummy_init_device(struct iio_dev *indio_dev) ...@@ -572,12 +564,18 @@ static int iio_dummy_init_device(struct iio_dev *indio_dev)
* const struct i2c_device_id *id) * const struct i2c_device_id *id)
* SPI: iio_dummy_probe(struct spi_device *spi) * SPI: iio_dummy_probe(struct spi_device *spi)
*/ */
static int iio_dummy_probe(int index) static struct iio_sw_device *iio_dummy_probe(const char *name)
{ {
int ret; int ret;
struct iio_dev *indio_dev; struct iio_dev *indio_dev;
struct iio_dummy_state *st; struct iio_dummy_state *st;
struct iio_sw_device *swd;
swd = kzalloc(sizeof(*swd), GFP_KERNEL);
if (!swd) {
ret = -ENOMEM;
goto error_kzalloc;
}
/* /*
* Allocate an IIO device. * Allocate an IIO device.
* *
...@@ -608,7 +606,7 @@ static int iio_dummy_probe(int index) ...@@ -608,7 +606,7 @@ static int iio_dummy_probe(int index)
* i2c_set_clientdata(client, indio_dev); * i2c_set_clientdata(client, indio_dev);
* spi_set_drvdata(spi, indio_dev); * spi_set_drvdata(spi, indio_dev);
*/ */
iio_dummy_devs[index] = indio_dev; swd->device = indio_dev;
/* /*
* Set the device name. * Set the device name.
...@@ -619,7 +617,7 @@ static int iio_dummy_probe(int index) ...@@ -619,7 +617,7 @@ static int iio_dummy_probe(int index)
* indio_dev->name = id->name; * indio_dev->name = id->name;
* indio_dev->name = spi_get_device_id(spi)->name; * indio_dev->name = spi_get_device_id(spi)->name;
*/ */
indio_dev->name = iio_dummy_part_number; indio_dev->name = kstrdup(name, GFP_KERNEL);
/* Provide description of available channels */ /* Provide description of available channels */
indio_dev->channels = iio_dummy_channels; indio_dev->channels = iio_dummy_channels;
...@@ -646,7 +644,9 @@ static int iio_dummy_probe(int index) ...@@ -646,7 +644,9 @@ static int iio_dummy_probe(int index)
if (ret < 0) if (ret < 0)
goto error_unconfigure_buffer; goto error_unconfigure_buffer;
return 0; iio_swd_group_init_type_name(swd, name, &iio_dummy_type);
return swd;
error_unconfigure_buffer: error_unconfigure_buffer:
iio_simple_dummy_unconfigure_buffer(indio_dev); iio_simple_dummy_unconfigure_buffer(indio_dev);
error_unregister_events: error_unregister_events:
...@@ -654,16 +654,18 @@ static int iio_dummy_probe(int index) ...@@ -654,16 +654,18 @@ static int iio_dummy_probe(int index)
error_free_device: error_free_device:
iio_device_free(indio_dev); iio_device_free(indio_dev);
error_ret: error_ret:
return ret; kfree(swd);
error_kzalloc:
return ERR_PTR(ret);
} }
/** /**
* iio_dummy_remove() - device instance removal function * iio_dummy_remove() - device instance removal function
* @index: device index. * @swd: pointer to software IIO device abstraction
* *
* Parameters follow those of iio_dummy_probe for buses. * Parameters follow those of iio_dummy_probe for buses.
*/ */
static void iio_dummy_remove(int index) static int iio_dummy_remove(struct iio_sw_device *swd)
{ {
/* /*
* Get a pointer to the device instance iio_dev structure * Get a pointer to the device instance iio_dev structure
...@@ -671,7 +673,7 @@ static void iio_dummy_remove(int index) ...@@ -671,7 +673,7 @@ static void iio_dummy_remove(int index)
* struct iio_dev *indio_dev = i2c_get_clientdata(client); * struct iio_dev *indio_dev = i2c_get_clientdata(client);
* struct iio_dev *indio_dev = spi_get_drvdata(spi); * struct iio_dev *indio_dev = spi_get_drvdata(spi);
*/ */
struct iio_dev *indio_dev = iio_dummy_devs[index]; struct iio_dev *indio_dev = swd->device;
/* Unregister the device */ /* Unregister the device */
iio_device_unregister(indio_dev); iio_device_unregister(indio_dev);
...@@ -684,11 +686,13 @@ static void iio_dummy_remove(int index) ...@@ -684,11 +686,13 @@ static void iio_dummy_remove(int index)
iio_simple_dummy_events_unregister(indio_dev); iio_simple_dummy_events_unregister(indio_dev);
/* Free all structures */ /* Free all structures */
kfree(indio_dev->name);
iio_device_free(indio_dev); iio_device_free(indio_dev);
}
return 0;
}
/** /**
* iio_dummy_init() - device driver registration * module_iio_sw_device_driver() - device driver registration
* *
* Varies depending on bus type of the device. As there is no device * Varies depending on bus type of the device. As there is no device
* here, call probe directly. For information on device registration * here, call probe directly. For information on device registration
...@@ -697,50 +701,18 @@ static void iio_dummy_remove(int index) ...@@ -697,50 +701,18 @@ static void iio_dummy_remove(int index)
* spi: * spi:
* Documentation/spi/spi-summary * Documentation/spi/spi-summary
*/ */
static __init int iio_dummy_init(void) static const struct iio_sw_device_ops iio_dummy_device_ops = {
{ .probe = iio_dummy_probe,
int i, ret; .remove = iio_dummy_remove,
};
if (instances > 10) {
instances = 1;
return -EINVAL;
}
/* Fake a bus */
iio_dummy_devs = kcalloc(instances, sizeof(*iio_dummy_devs),
GFP_KERNEL);
/* Here we have no actual device so call probe */
for (i = 0; i < instances; i++) {
ret = iio_dummy_probe(i);
if (ret < 0)
goto error_remove_devs;
}
return 0;
error_remove_devs:
while (i--)
iio_dummy_remove(i);
kfree(iio_dummy_devs);
return ret;
}
module_init(iio_dummy_init);
/** static struct iio_sw_device_type iio_dummy_device = {
* iio_dummy_exit() - device driver removal .name = "dummy",
* .owner = THIS_MODULE,
* Varies depending on bus type of the device. .ops = &iio_dummy_device_ops,
* As there is no device here, call remove directly. };
*/
static __exit void iio_dummy_exit(void)
{
int i;
for (i = 0; i < instances; i++) module_iio_sw_device_driver(iio_dummy_device);
iio_dummy_remove(i);
kfree(iio_dummy_devs);
}
module_exit(iio_dummy_exit);
MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>"); MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>");
MODULE_DESCRIPTION("IIO dummy driver"); MODULE_DESCRIPTION("IIO dummy driver");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment