drivers/mfd/menelaus.c
Source file repositories/reference/linux-study-clean/drivers/mfd/menelaus.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/mfd/menelaus.c- Extension
.c- Size
- 29932 bytes
- Lines
- 1252
- Domain
- Driver Families
- Bucket
- drivers/mfd
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- 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/module.hlinux/i2c.hlinux/interrupt.hlinux/sched.hlinux/mutex.hlinux/workqueue.hlinux/delay.hlinux/rtc.hlinux/bcd.hlinux/slab.hlinux/mfd/menelaus.hasm/mach/irq.h
Detected Declarations
struct menelaus_chipstruct menelaus_vtgstruct menelaus_vtg_valuefunction menelaus_write_regfunction menelaus_read_regfunction menelaus_enable_irqfunction menelaus_disable_irqfunction menelaus_ack_irqfunction menelaus_add_irq_workfunction menelaus_remove_irq_workfunction menelaus_mmc_cd_workfunction menelaus_set_mmc_opendrainfunction menelaus_set_slot_selfunction menelaus_set_mmc_slotfunction menelaus_register_mmc_callbackfunction menelaus_unregister_mmc_callbackfunction menelaus_set_voltagefunction menelaus_get_vtg_valuefunction menelaus_set_vcore_hwfunction menelaus_set_vmemfunction menelaus_set_viofunction menelaus_set_vdcdcfunction menelaus_set_vmmcfunction menelaus_set_vauxfunction menelaus_get_slot_pin_statesfunction menelaus_set_regulator_sleepfunction menelaus_workfunction menelaus_irqfunction menelaus_to_timefunction time_to_menelausfunction menelaus_read_timefunction menelaus_set_timefunction menelaus_read_alarmfunction menelaus_set_alarmfunction menelaus_rtc_update_workfunction menelaus_ioctlfunction menelaus_rtc_alarm_workfunction menelaus_rtc_initfunction menelaus_rtc_initfunction menelaus_probefunction menelaus_removeexport menelaus_set_mmc_opendrainexport menelaus_set_slot_selexport menelaus_set_mmc_slotexport menelaus_register_mmc_callbackexport menelaus_unregister_mmc_callbackexport menelaus_set_vmemexport menelaus_set_vio
Annotated Snippet
struct menelaus_chip {
struct mutex lock;
struct i2c_client *client;
struct work_struct work;
#ifdef CONFIG_RTC_DRV_TWL92330
struct rtc_device *rtc;
u8 rtc_control;
unsigned uie:1;
#endif
unsigned vcore_hw_mode:1;
u8 mask1, mask2;
void (*handlers[16])(struct menelaus_chip *);
void (*mmc_callback)(void *data, u8 mask);
void *mmc_callback_data;
};
static struct menelaus_chip *the_menelaus;
static int menelaus_write_reg(int reg, u8 value)
{
int val = i2c_smbus_write_byte_data(the_menelaus->client, reg, value);
if (val < 0) {
pr_err(DRIVER_NAME ": write error");
return val;
}
return 0;
}
static int menelaus_read_reg(int reg)
{
int val = i2c_smbus_read_byte_data(the_menelaus->client, reg);
if (val < 0)
pr_err(DRIVER_NAME ": read error");
return val;
}
static int menelaus_enable_irq(int irq)
{
if (irq > 7) {
irq -= 8;
the_menelaus->mask2 &= ~(1 << irq);
return menelaus_write_reg(MENELAUS_INT_MASK2,
the_menelaus->mask2);
} else {
the_menelaus->mask1 &= ~(1 << irq);
return menelaus_write_reg(MENELAUS_INT_MASK1,
the_menelaus->mask1);
}
}
static int menelaus_disable_irq(int irq)
{
if (irq > 7) {
irq -= 8;
the_menelaus->mask2 |= (1 << irq);
return menelaus_write_reg(MENELAUS_INT_MASK2,
the_menelaus->mask2);
} else {
the_menelaus->mask1 |= (1 << irq);
return menelaus_write_reg(MENELAUS_INT_MASK1,
the_menelaus->mask1);
}
}
static int menelaus_ack_irq(int irq)
{
if (irq > 7)
return menelaus_write_reg(MENELAUS_INT_ACK2, 1 << (irq - 8));
else
return menelaus_write_reg(MENELAUS_INT_ACK1, 1 << irq);
}
/* Adds a handler for an interrupt. Does not run in interrupt context */
static int menelaus_add_irq_work(int irq,
void (*handler)(struct menelaus_chip *))
{
int ret = 0;
mutex_lock(&the_menelaus->lock);
the_menelaus->handlers[irq] = handler;
ret = menelaus_enable_irq(irq);
mutex_unlock(&the_menelaus->lock);
return ret;
}
Annotation
- Immediate include surface: `linux/module.h`, `linux/i2c.h`, `linux/interrupt.h`, `linux/sched.h`, `linux/mutex.h`, `linux/workqueue.h`, `linux/delay.h`, `linux/rtc.h`.
- Detected declarations: `struct menelaus_chip`, `struct menelaus_vtg`, `struct menelaus_vtg_value`, `function menelaus_write_reg`, `function menelaus_read_reg`, `function menelaus_enable_irq`, `function menelaus_disable_irq`, `function menelaus_ack_irq`, `function menelaus_add_irq_work`, `function menelaus_remove_irq_work`.
- Atlas domain: Driver Families / drivers/mfd.
- Implementation status: integration implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- 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.