drivers/i2c/busses/i2c-riic.c
Source file repositories/reference/linux-study-clean/drivers/i2c/busses/i2c-riic.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/i2c/busses/i2c-riic.c- Extension
.c- Size
- 20091 bytes
- Lines
- 778
- Domain
- Driver Families
- Bucket
- drivers/i2c
- Inferred role
- Driver Families: implementation source
- Status
- source 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.
- 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/bits.hlinux/clk.hlinux/completion.hlinux/err.hlinux/i2c.hlinux/interrupt.hlinux/io.hlinux/iopoll.hlinux/module.hlinux/of.hlinux/platform_device.hlinux/pm_runtime.hlinux/reset.hlinux/time.h
Detected Declarations
struct riic_of_datastruct riic_devstruct riic_irq_descenum riic_reg_listfunction riic_writebfunction riic_readbfunction riic_clear_set_bitfunction riic_bus_barrierfunction riic_xferfunction riic_tdre_isrfunction riic_tend_isrfunction riic_rdrf_isrfunction riic_stop_isrfunction riic_eei_isrfunction riic_funcfunction riic_init_hwfunction riic_get_sclfunction riic_get_sdafunction riic_set_sclfunction riic_set_sdafunction riic_i2c_probefunction riic_i2c_removefunction riic_i2c_suspendfunction riic_i2c_resumefunction riic_i2c_suspend_noirqfunction riic_i2c_resume_noirq
Annotated Snippet
struct riic_of_data {
const u8 *regs;
const struct riic_irq_desc *irqs;
u8 num_irqs;
bool fast_mode_plus;
};
struct riic_dev {
void __iomem *base;
u8 *buf;
struct i2c_msg *msg;
int bytes_left;
int err;
int is_last;
const struct riic_of_data *info;
struct completion msg_done;
struct i2c_adapter adapter;
struct clk *clk;
struct reset_control *rstc;
struct i2c_timings i2c_t;
};
struct riic_irq_desc {
int res_num;
irq_handler_t isr;
char *name;
};
static inline void riic_writeb(struct riic_dev *riic, u8 val, u8 offset)
{
writeb(val, riic->base + riic->info->regs[offset]);
}
static inline u8 riic_readb(struct riic_dev *riic, u8 offset)
{
return readb(riic->base + riic->info->regs[offset]);
}
static inline void riic_clear_set_bit(struct riic_dev *riic, u8 clear, u8 set, u8 reg)
{
riic_writeb(riic, (riic_readb(riic, reg) & ~clear) | set, reg);
}
static int riic_bus_barrier(struct riic_dev *riic)
{
int ret;
u8 val;
/*
* The SDA line can still be low even when BBSY = 0. Therefore, after checking
* the BBSY flag, also verify that the SDA and SCL lines are not being held low.
*/
ret = readb_poll_timeout(riic->base + riic->info->regs[RIIC_ICCR2], val,
!(val & ICCR2_BBSY), 10, riic->adapter.timeout);
if (ret)
return i2c_recover_bus(&riic->adapter);
if ((riic_readb(riic, RIIC_ICCR1) & (ICCR1_SDAI | ICCR1_SCLI)) !=
(ICCR1_SDAI | ICCR1_SCLI))
return i2c_recover_bus(&riic->adapter);
return 0;
}
static int riic_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
{
struct riic_dev *riic = i2c_get_adapdata(adap);
struct device *dev = adap->dev.parent;
unsigned long time_left;
int i, ret;
u8 start_bit;
ret = pm_runtime_resume_and_get(dev);
if (ret)
return ret;
riic->err = riic_bus_barrier(riic);
if (riic->err)
goto out;
reinit_completion(&riic->msg_done);
riic_writeb(riic, 0, RIIC_ICSR2);
for (i = 0, start_bit = ICCR2_ST; i < num; i++) {
riic->bytes_left = RIIC_INIT_MSG;
riic->buf = msgs[i].buf;
riic->msg = &msgs[i];
riic->is_last = (i == num - 1);
Annotation
- Immediate include surface: `linux/bits.h`, `linux/clk.h`, `linux/completion.h`, `linux/err.h`, `linux/i2c.h`, `linux/interrupt.h`, `linux/io.h`, `linux/iopoll.h`.
- Detected declarations: `struct riic_of_data`, `struct riic_dev`, `struct riic_irq_desc`, `enum riic_reg_list`, `function riic_writeb`, `function riic_readb`, `function riic_clear_set_bit`, `function riic_bus_barrier`, `function riic_xfer`, `function riic_tdre_isr`.
- Atlas domain: Driver Families / drivers/i2c.
- Implementation status: source 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.