diff options
author | Peter Rosin <peda@axentia.se> | 2017-05-14 21:51:06 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-06-03 19:29:26 +0900 |
commit | a3b02a9c6591ce154cd44e2383406390a45b530c (patch) | |
tree | d6d0547b25d3117c103370ee24020cfd6cced3fe /include/linux/mux | |
parent | 256ac0375098e50d59c415fcbb561f2927fa8780 (diff) |
mux: minimal mux subsystem
Add a new minimalistic subsystem that handles multiplexer controllers.
When multiplexers are used in various places in the kernel, and the
same multiplexer controller can be used for several independent things,
there should be one place to implement support for said multiplexer
controller.
A single multiplexer controller can also be used to control several
parallel multiplexers, that are in turn used by different subsystems
in the kernel, leading to a need to coordinate multiplexer accesses.
The multiplexer subsystem handles this coordination.
Thanks go out to Lars-Peter Clausen, Jonathan Cameron, Rob Herring,
Wolfram Sang, Paul Gortmaker, Dan Carpenter, Colin Ian King, Greg
Kroah-Hartman and last but certainly not least to Philipp Zabel for
helpful comments, reviews, patches and general encouragement!
Reviewed-by: Jonathan Cameron <jic23@kernel.org>
Signed-off-by: Peter Rosin <peda@axentia.se>
Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
Tested-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'include/linux/mux')
-rw-r--r-- | include/linux/mux/consumer.h | 32 | ||||
-rw-r--r-- | include/linux/mux/driver.h | 108 |
2 files changed, 140 insertions, 0 deletions
diff --git a/include/linux/mux/consumer.h b/include/linux/mux/consumer.h new file mode 100644 index 000000000000..5577e1b773c4 --- /dev/null +++ b/include/linux/mux/consumer.h @@ -0,0 +1,32 @@ +/* + * mux/consumer.h - definitions for the multiplexer consumer interface + * + * Copyright (C) 2017 Axentia Technologies AB + * + * Author: Peter Rosin <peda@axentia.se> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef _LINUX_MUX_CONSUMER_H +#define _LINUX_MUX_CONSUMER_H + +struct device; +struct mux_control; + +unsigned int mux_control_states(struct mux_control *mux); +int __must_check mux_control_select(struct mux_control *mux, + unsigned int state); +int __must_check mux_control_try_select(struct mux_control *mux, + unsigned int state); +int mux_control_deselect(struct mux_control *mux); + +struct mux_control *mux_control_get(struct device *dev, const char *mux_name); +void mux_control_put(struct mux_control *mux); + +struct mux_control *devm_mux_control_get(struct device *dev, + const char *mux_name); + +#endif /* _LINUX_MUX_CONSUMER_H */ diff --git a/include/linux/mux/driver.h b/include/linux/mux/driver.h new file mode 100644 index 000000000000..35c3579c3304 --- /dev/null +++ b/include/linux/mux/driver.h @@ -0,0 +1,108 @@ +/* + * mux/driver.h - definitions for the multiplexer driver interface + * + * Copyright (C) 2017 Axentia Technologies AB + * + * Author: Peter Rosin <peda@axentia.se> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef _LINUX_MUX_DRIVER_H +#define _LINUX_MUX_DRIVER_H + +#include <dt-bindings/mux/mux.h> +#include <linux/device.h> +#include <linux/semaphore.h> + +struct mux_chip; +struct mux_control; + +/** + * struct mux_control_ops - Mux controller operations for a mux chip. + * @set: Set the state of the given mux controller. + */ +struct mux_control_ops { + int (*set)(struct mux_control *mux, int state); +}; + +/** + * struct mux_control - Represents a mux controller. + * @lock: Protects the mux controller state. + * @chip: The mux chip that is handling this mux controller. + * @cached_state: The current mux controller state, or -1 if none. + * @states: The number of mux controller states. + * @idle_state: The mux controller state to use when inactive, or one + * of MUX_IDLE_AS_IS and MUX_IDLE_DISCONNECT. + * + * Mux drivers may only change @states and @idle_state, and may only do so + * between allocation and registration of the mux controller. Specifically, + * @cached_state is internal to the mux core and should never be written by + * mux drivers. + */ +struct mux_control { + struct semaphore lock; /* protects the state of the mux */ + + struct mux_chip *chip; + int cached_state; + + unsigned int states; + int idle_state; +}; + +/** + * struct mux_chip - Represents a chip holding mux controllers. + * @controllers: Number of mux controllers handled by the chip. + * @mux: Array of mux controllers that are handled. + * @dev: Device structure. + * @id: Used to identify the device internally. + * @ops: Mux controller operations. + */ +struct mux_chip { + unsigned int controllers; + struct mux_control *mux; + struct device dev; + int id; + + const struct mux_control_ops *ops; +}; + +#define to_mux_chip(x) container_of((x), struct mux_chip, dev) + +/** + * mux_chip_priv() - Get the extra memory reserved by mux_chip_alloc(). + * @mux_chip: The mux-chip to get the private memory from. + * + * Return: Pointer to the private memory reserved by the allocator. + */ +static inline void *mux_chip_priv(struct mux_chip *mux_chip) +{ + return &mux_chip->mux[mux_chip->controllers]; +} + +struct mux_chip *mux_chip_alloc(struct device *dev, + unsigned int controllers, size_t sizeof_priv); +int mux_chip_register(struct mux_chip *mux_chip); +void mux_chip_unregister(struct mux_chip *mux_chip); +void mux_chip_free(struct mux_chip *mux_chip); + +struct mux_chip *devm_mux_chip_alloc(struct device *dev, + unsigned int controllers, + size_t sizeof_priv); +int devm_mux_chip_register(struct device *dev, struct mux_chip *mux_chip); + +/** + * mux_control_get_index() - Get the index of the given mux controller + * @mux: The mux-control to get the index for. + * + * Return: The index of the mux controller within the mux chip the mux + * controller is a part of. + */ +static inline unsigned int mux_control_get_index(struct mux_control *mux) +{ + return mux - mux->chip->mux; +} + +#endif /* _LINUX_MUX_DRIVER_H */ |