drivers/tty/serial/serial_mctrl_gpio.c
Source file repositories/reference/linux-study-clean/drivers/tty/serial/serial_mctrl_gpio.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/tty/serial/serial_mctrl_gpio.c- Extension
.c- Size
- 8885 bytes
- Lines
- 384
- Domain
- Driver Families
- Bucket
- drivers/tty
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/err.hlinux/device.hlinux/irq.hlinux/gpio/consumer.hlinux/termios.hlinux/serial_core.hlinux/module.hlinux/property.hserial_mctrl_gpio.h
Detected Declarations
struct mctrl_gpiosfunction mctrl_gpio_flags_is_dir_outfunction mctrl_gpio_setfunction mctrl_gpio_getfunction mctrl_gpio_get_outputsfunction mctrl_gpio_irq_handlefunction mctrl_gpio_enable_msfunction mctrl_gpio_disable_msfunction mctrl_gpio_disable_ms_syncfunction mctrl_gpio_disable_ms_no_syncfunction mctrl_gpio_enable_irq_wakefunction mctrl_gpio_disable_irq_wakeexport mctrl_gpio_setexport mctrl_gpio_to_gpiodexport mctrl_gpio_getexport mctrl_gpio_get_outputsexport mctrl_gpio_init_noautoexport mctrl_gpio_initexport mctrl_gpio_enable_msexport mctrl_gpio_disable_ms_syncexport mctrl_gpio_disable_ms_no_syncexport mctrl_gpio_enable_irq_wakeexport mctrl_gpio_disable_irq_wake
Annotated Snippet
struct mctrl_gpios {
struct uart_port *port;
struct gpio_desc *gpio[UART_GPIO_MAX];
int irq[UART_GPIO_MAX];
unsigned int mctrl_prev;
bool mctrl_on;
};
static const struct {
const char *name;
unsigned int mctrl;
enum gpiod_flags flags;
} mctrl_gpios_desc[UART_GPIO_MAX] = {
{ "cts", TIOCM_CTS, GPIOD_IN, },
{ "dsr", TIOCM_DSR, GPIOD_IN, },
{ "dcd", TIOCM_CD, GPIOD_IN, },
{ "rng", TIOCM_RNG, GPIOD_IN, },
{ "rts", TIOCM_RTS, GPIOD_OUT_LOW, },
{ "dtr", TIOCM_DTR, GPIOD_OUT_LOW, },
};
static bool mctrl_gpio_flags_is_dir_out(unsigned int idx)
{
return mctrl_gpios_desc[idx].flags & GPIOD_FLAGS_BIT_DIR_OUT;
}
/**
* mctrl_gpio_set - set gpios according to mctrl state
* @gpios: gpios to set
* @mctrl: state to set
*
* Set the gpios according to the mctrl state.
*/
void mctrl_gpio_set(struct mctrl_gpios *gpios, unsigned int mctrl)
{
enum mctrl_gpio_idx i;
struct gpio_desc *desc_array[UART_GPIO_MAX];
DECLARE_BITMAP(values, UART_GPIO_MAX);
unsigned int count = 0;
if (gpios == NULL)
return;
for (i = 0; i < UART_GPIO_MAX; i++)
if (gpios->gpio[i] && mctrl_gpio_flags_is_dir_out(i)) {
desc_array[count] = gpios->gpio[i];
__assign_bit(count, values,
mctrl & mctrl_gpios_desc[i].mctrl);
count++;
}
gpiod_set_array_value(count, desc_array, NULL, values);
}
EXPORT_SYMBOL_GPL(mctrl_gpio_set);
/**
* mctrl_gpio_to_gpiod - obtain gpio_desc of modem line index
* @gpios: gpios to look into
* @gidx: index of the modem line
* Returns: the gpio_desc structure associated to the modem line index
*/
struct gpio_desc *mctrl_gpio_to_gpiod(struct mctrl_gpios *gpios,
enum mctrl_gpio_idx gidx)
{
if (gpios == NULL)
return NULL;
return gpios->gpio[gidx];
}
EXPORT_SYMBOL_GPL(mctrl_gpio_to_gpiod);
/**
* mctrl_gpio_get - update mctrl with the gpios values.
* @gpios: gpios to get the info from
* @mctrl: mctrl to set
* Returns: modified mctrl (the same value as in @mctrl)
*
* Update mctrl with the gpios values.
*/
unsigned int mctrl_gpio_get(struct mctrl_gpios *gpios, unsigned int *mctrl)
{
enum mctrl_gpio_idx i;
if (gpios == NULL)
return *mctrl;
for (i = 0; i < UART_GPIO_MAX; i++) {
if (gpios->gpio[i] && !mctrl_gpio_flags_is_dir_out(i)) {
if (gpiod_get_value(gpios->gpio[i]))
*mctrl |= mctrl_gpios_desc[i].mctrl;
else
Annotation
- Immediate include surface: `linux/err.h`, `linux/device.h`, `linux/irq.h`, `linux/gpio/consumer.h`, `linux/termios.h`, `linux/serial_core.h`, `linux/module.h`, `linux/property.h`.
- Detected declarations: `struct mctrl_gpios`, `function mctrl_gpio_flags_is_dir_out`, `function mctrl_gpio_set`, `function mctrl_gpio_get`, `function mctrl_gpio_get_outputs`, `function mctrl_gpio_irq_handle`, `function mctrl_gpio_enable_ms`, `function mctrl_gpio_disable_ms`, `function mctrl_gpio_disable_ms_sync`, `function mctrl_gpio_disable_ms_no_sync`.
- Atlas domain: Driver Families / drivers/tty.
- Implementation status: integration implementation candidate.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.