arch/powerpc/platforms/powermac/low_i2c.c
Source file repositories/reference/linux-study-clean/arch/powerpc/platforms/powermac/low_i2c.c
File Facts
- System
- Linux kernel
- Corpus path
arch/powerpc/platforms/powermac/low_i2c.c- Extension
.c- Size
- 36461 bytes
- Lines
- 1484
- Domain
- Architecture Layer
- Bucket
- arch/powerpc
- Inferred role
- Architecture Layer: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- 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/types.hlinux/sched.hlinux/init.hlinux/export.hlinux/adb.hlinux/pmu.hlinux/delay.hlinux/completion.hlinux/platform_device.hlinux/interrupt.hlinux/timer.hlinux/mutex.hlinux/i2c.hlinux/slab.hlinux/of_irq.hasm/keylargo.hasm/uninorth.hasm/io.hasm/machdep.hasm/smu.hasm/pmac_pfunc.hasm/pmac_low_i2c.h
Detected Declarations
struct pmac_i2c_busstruct pmac_i2c_host_kwstruct pmu_i2c_hdrstruct pmac_i2c_pf_instfunction __kw_read_regfunction __kw_write_regfunction kw_i2c_wait_interruptfunction kw_i2c_do_stopfunction kw_i2c_handle_interruptfunction kw_i2c_irqfunction kw_i2c_timeoutfunction kw_i2c_openfunction kw_i2c_closefunction kw_i2c_xferfunction kw_i2c_host_initfunction kw_i2c_addfunction kw_i2c_probefunction for_each_child_of_nodefunction pmu_i2c_completefunction pmu_i2c_xferfunction pmu_i2c_probefunction smu_i2c_completefunction smu_i2c_xferfunction smu_i2c_probefunction pmac_i2c_get_dev_addrfunction pmac_i2c_get_typefunction pmac_i2c_get_flagsfunction pmac_i2c_get_channelfunction pmac_i2c_match_adapterfunction pmac_i2c_openfunction pmac_i2c_closefunction pmac_i2c_setmodefunction pmac_i2c_xferfunction pmac_i2c_devscanfunction for_each_child_of_nodefunction pmac_i2c_do_beginfunction pmac_i2c_do_endfunction pmac_i2c_do_readfunction pmac_i2c_do_writefunction pmac_i2c_do_apply_rmwfunction pmac_i2c_do_rmwfunction pmac_i2c_do_read_subfunction pmac_i2c_do_write_subfunction pmac_i2c_do_set_modefunction pmac_i2c_do_rmw_subfunction pmac_i2c_do_mask_and_compfunction pmac_i2c_do_delayfunction pmac_i2c_dev_create
Annotated Snippet
struct pmu_i2c_hdr {
u8 bus;
u8 mode;
u8 bus2;
u8 address;
u8 sub_addr;
u8 comb_addr;
u8 count;
u8 data[];
};
static void pmu_i2c_complete(struct adb_request *req)
{
complete(req->arg);
}
static int pmu_i2c_xfer(struct pmac_i2c_bus *bus, u8 addrdir, int subsize,
u32 subaddr, u8 *data, int len)
{
struct adb_request *req = bus->hostdata;
struct pmu_i2c_hdr *hdr = (struct pmu_i2c_hdr *)&req->data[1];
struct completion comp;
int read = addrdir & 1;
int retry;
int rc = 0;
/* For now, limit ourselves to 16 bytes transfers */
if (len > 16)
return -EINVAL;
init_completion(&comp);
for (retry = 0; retry < 16; retry++) {
memset(req, 0, sizeof(struct adb_request));
hdr->bus = bus->channel;
hdr->count = len;
switch(bus->mode) {
case pmac_i2c_mode_std:
if (subsize != 0)
return -EINVAL;
hdr->address = addrdir;
hdr->mode = PMU_I2C_MODE_SIMPLE;
break;
case pmac_i2c_mode_stdsub:
case pmac_i2c_mode_combined:
if (subsize != 1)
return -EINVAL;
hdr->address = addrdir & 0xfe;
hdr->comb_addr = addrdir;
hdr->sub_addr = subaddr;
if (bus->mode == pmac_i2c_mode_stdsub)
hdr->mode = PMU_I2C_MODE_STDSUB;
else
hdr->mode = PMU_I2C_MODE_COMBINED;
break;
default:
return -EINVAL;
}
reinit_completion(&comp);
req->data[0] = PMU_I2C_CMD;
req->reply[0] = 0xff;
req->nbytes = sizeof(struct pmu_i2c_hdr) + 1;
req->done = pmu_i2c_complete;
req->arg = ∁
if (!read && len) {
memcpy(hdr->data, data, len);
req->nbytes += len;
}
rc = pmu_queue_request(req);
if (rc)
return rc;
wait_for_completion(&comp);
if (req->reply[0] == PMU_I2C_STATUS_OK)
break;
msleep(15);
}
if (req->reply[0] != PMU_I2C_STATUS_OK)
return -EIO;
for (retry = 0; retry < 16; retry++) {
memset(req, 0, sizeof(struct adb_request));
/* I know that looks like a lot, slow as hell, but darwin
* does it so let's be on the safe side for now
*/
msleep(15);
hdr->bus = PMU_I2C_BUS_STATUS;
Annotation
- Immediate include surface: `linux/types.h`, `linux/sched.h`, `linux/init.h`, `linux/export.h`, `linux/adb.h`, `linux/pmu.h`, `linux/delay.h`, `linux/completion.h`.
- Detected declarations: `struct pmac_i2c_bus`, `struct pmac_i2c_host_kw`, `struct pmu_i2c_hdr`, `struct pmac_i2c_pf_inst`, `function __kw_read_reg`, `function __kw_write_reg`, `function kw_i2c_wait_interrupt`, `function kw_i2c_do_stop`, `function kw_i2c_handle_interrupt`, `function kw_i2c_irq`.
- Atlas domain: Architecture Layer / arch/powerpc.
- 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.