Keywords covered in this lecture
struct clk_mux
clk_hw_register_mux
CLK_MUX_READ_ONLY
free linux kernel development course
free linux device drivers course
Every base clock type covered so far in this chapter has had exactly one parent, or
none at all. The linux mux clock driver type is the first one where
that stops being true: a mux clock has two or more possible parents, and its entire
job is picking which one is currently active. This is also the clock type the
mandatory-callbacks lecture flagged as the one case where set_parent and
get_parent are required rather than forbidden.
What You Will Learn
- The struct clk_mux wrapper and its reg/table/mask/shift fields
- All five mux-specific flags and what each one changes
- clk_hw_register_mux() and its full parameter list
- Why CLK_MUX_READ_ONLY swaps in a different, smaller built-in ops struct
- Registering both a switchable and a read-only mux clock
Prerequisites
- I2C/SPI and GPIO gate clocks (previous lecture)
- Mandatory clk_ops by clock type (Multiplexer column)
- Understanding hiword mask (from the gate clock case study)
The struct clk_mux Wrapper
A mux clock’s hardware-specific state is a register plus enough information to turn a
parent index into the right bit pattern for that register.
struct clk_mux {
struct clk_hw hw;
void __iomem *reg;
u32 *table;
u32 mask;
u8 shift;
u8 flags;
spinlock_t *lock;
};
#define to_clk_mux(_hw) container_of(_hw, struct clk_mux, hw)
- reg: the MMIO register used for parent selection
- table: an optional array mapping each parent index to an explicit register value
- mask/shift: used to extract or place the selector bits within reg
- flags: mux-specific behavior flags, covered next
- lock: shared spinlock protecting register access
By default, when the register’s selector field reads 0, that corresponds
to the first parent, 1 to the second, and so on — a plain sequential
mapping. The flags below exist for hardware that deviates from this default.
The Five Mux-Specific Flags
- CLK_MUX_INDEX_BIT: the register value is a power of two rather than a plain index (parent 2 maps to the value 4, not 2)
- CLK_MUX_HIWORD_MASK: uses the same hiword-mask write pattern introduced in the gate clock lecture
- CLK_MUX_INDEX_ONE: register values start counting from 1 instead of 0
- CLK_MUX_READ_ONLY: the mux is preconfigured at reset and cannot be changed at runtime
- CLK_MUX_ROUND_CLOSEST: when validating a requested rate, prefer whichever parent’s rate is closest to the target instead of the first one that fits
Registering With clk_hw_register_mux()
struct clk_hw *clk_hw_register_mux(struct device *dev, const char *name,
const char * const *parent_names,
u8 num_parents, unsigned long flags,
void __iomem *reg, u8 shift, u8 width,
u8 clk_mux_flags, spinlock_t *lock);
parent_names lists every possible parent by name, and
num_parents says how many there are — both are new here compared to
earlier single/no-parent clock types, since a mux is the first type in this chapter that
genuinely needs to describe more than one parent at registration time.
Two Different Built-In Ops, Chosen at Registration
Depending on whether CLK_MUX_READ_ONLY is set, the framework silently
assigns one of two different ops structs:
const struct clk_ops clk_mux_ops = {
.get_parent = clk_mux_get_parent,
.set_parent = clk_mux_set_parent,
.determine_rate = clk_mux_determine_rate,
};
EXPORT_SYMBOL_GPL(clk_mux_ops);
const struct clk_ops clk_mux_ro_ops = {
.get_parent = clk_mux_get_parent,
};
EXPORT_SYMBOL_GPL(clk_mux_ro_ops);
A read-only mux has no way to change parent at runtime, so
clk_mux_ro_ops only reports which parent is active; a normal switchable mux
gets the full clk_mux_ops, which can also switch parents and validate a
requested rate across them.
Original Demo: A Two-Parent Switchable Mux
/* ep_mux_clk_demo.c - selects between two parent clocks via a single register bit */
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/clk-provider.h>
#include <linux/of.h>
#include <linux/io.h>
#include <linux/spinlock.h>
static const char * const ep_mux_parents[] = { "ep_bus_clk", "ep_ext_osc" };
struct ep_mux_demo_data {
void __iomem *base;
spinlock_t lock;
struct clk_hw *mux_hw;
};
static int ep_mux_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct ep_mux_demo_data *data;
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
spin_lock_init(&data->lock);
data->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(data->base))
return PTR_ERR(data->base);
/* bit 0 of the mux register selects between the two parents above */
data->mux_hw = devm_clk_hw_register_mux(dev, "ep_mux_out",
ep_mux_parents,
ARRAY_SIZE(ep_mux_parents),
0, data->base, 0, 1, 0, &data->lock);
if (IS_ERR(data->mux_hw))
return PTR_ERR(data->mux_hw);
return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, data->mux_hw);
}
static const struct of_device_id ep_mux_of_match[] = {
{ .compatible = "ep,clk-mux-demo" },
{ }
};
MODULE_DEVICE_TABLE(of, ep_mux_of_match);
static struct platform_driver ep_mux_driver = {
.probe = ep_mux_probe,
.driver = {
.name = "ep_clk_mux_demo",
.of_match_table = ep_mux_of_match,
},
};
module_platform_driver(ep_mux_driver);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("EmbeddedPathashala mux clock demo");
Matching device tree node:
ep_mux_ctrl: clock-controller@8000 {
compatible = "ep,clk-mux-demo";
reg = <0x8000 0x4>;
#clock-cells = <0>;
clocks = <&ep_bus_clk>, <&ep_ext_osc>;
};
Build and Run
make -C /lib/modules/$(uname -r)/build M=$(pwd) modules
sudo insmod ep_mux_clk_demo.ko
cat /sys/kernel/debug/clk/clk_summary | grep -A2 ep_mux_out
Expected clk_summary excerpt, showing which of the two parents is currently active:
ep_mux_out 1 1 0 100000000 0
Registering a Read-Only Mux Variant
Some SoCs preconfigure a mux at reset and never allow software to change it. Only the
clk_mux_flags argument changes to express this:
data->mux_hw = devm_clk_hw_register_mux(dev, "ep_mux_readonly",
ep_mux_parents,
ARRAY_SIZE(ep_mux_parents),
0, data->base, 0, 1,
CLK_MUX_READ_ONLY, &data->lock);
The framework automatically assigns clk_mux_ro_ops instead of
clk_mux_ops in this case, so any attempt to call
clk_set_parent() against it will simply have no effect — there is no
set_parent callback for the CCF to call at all.
Switchable vs Read-Only Mux Clocks
| Aspect | Switchable Mux | CLK_MUX_READ_ONLY Mux |
|---|---|---|
| Ops assigned | clk_mux_ops | clk_mux_ro_ops |
| set_parent available? | Yes | No |
| Typical use | Software-selectable clock source | Boot-time-fixed hardware strapping |
Common Mistakes
- Forgetting CLK_MUX_INDEX_BIT when the register genuinely uses power-of-two encoding
- Mismatching parent_names order against the actual register value ordering
- Setting CLK_MUX_READ_ONLY on a mux the hardware can actually switch at runtime
- Sharing a mux register’s spinlock incorrectly with an unrelated clock
Best Practices
- Use clk_hw_register_mux()/devm_ variant instead of building struct clk_mux by hand
- Double check register-value-to-parent-index mapping against the datasheet before choosing flags
- Mark genuinely fixed hardware muxes CLK_MUX_READ_ONLY rather than leaving set_parent silently ineffective
- List parent_names in the exact order the register’s default sequential mapping expects
Summary and Key Takeaways
- struct clk_mux adds reg/table/mask/shift on top of the embedded clk_hw
- Five flags (INDEX_BIT, HIWORD_MASK, INDEX_ONE, READ_ONLY, ROUND_CLOSEST) cover common register quirks
- clk_hw_register_mux() assigns clk_mux_ops or clk_mux_ro_ops depending on CLK_MUX_READ_ONLY
- A mux is the one base clock type where set_parent/get_parent are genuinely required
Frequently Asked Questions
Can a mux clock also gate?
Not on its own; a plain mux clock only selects a parent. Combining muxing with
gating requires a composite clock, covered earlier in this chapter.
What happens if I call clk_set_parent() on a CLK_MUX_READ_ONLY mux?
Nothing happens at the hardware level, since clk_mux_ro_ops has no set_parent
callback for the CCF to invoke.
Do I need CLK_MUX_INDEX_BIT for every mux clock?
No, only when the datasheet confirms the register genuinely expects power-of-two
values instead of a plain sequential index.
What does CLK_MUX_ROUND_CLOSEST change?
It changes how a requested rate is validated across parents, preferring whichever
parent’s rate is closest to the target instead of simply the first one that fits.
Is a lock required for every mux clock?
It is optional but strongly recommended whenever the register could be accessed
concurrently, exactly as with gate clocks.
Suggested Images For This Lecture
- Diagram: struct clk_mux fields and two-parent selection
- Diagram: clk_mux_ops vs clk_mux_ro_ops decision based on CLK_MUX_READ_ONLY
- Screenshot: clk_summary showing an active mux clock and its selected parent
Continue This Free Linux Kernel Development Course
Next, we go inside the mux clock’s index-to-register-value translation logic and
cover the table-based variant for irregular register mappings.
