drivers/gpio/gpio-macsmc.c
Source file repositories/reference/linux-study-clean/drivers/gpio/gpio-macsmc.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpio/gpio-macsmc.c- Extension
.c- Size
- 6941 bytes
- Lines
- 294
- Domain
- Driver Families
- Bucket
- drivers/gpio
- 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.
- 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/bitmap.hlinux/device.hlinux/gpio/driver.hlinux/hex.hlinux/mfd/core.hlinux/mfd/macsmc.h
Detected Declarations
struct macsmc_gpiofunction macsmc_gpio_nrfunction macsmc_gpio_keyfunction macsmc_gpio_find_first_gpio_indexfunction macsmc_gpio_get_directionfunction macsmc_gpio_getfunction macsmc_gpio_setfunction macsmc_gpio_init_valid_maskfunction macsmc_gpio_probe
Annotated Snippet
struct macsmc_gpio {
struct device *dev;
struct apple_smc *smc;
struct gpio_chip gc;
int first_index;
};
static int macsmc_gpio_nr(smc_key key)
{
int low = hex_to_bin(key & 0xff);
int high = hex_to_bin((key >> 8) & 0xff);
if (low < 0 || high < 0)
return -1;
return low | (high << 4);
}
static int macsmc_gpio_key(unsigned int offset)
{
return _SMC_KEY("gP\0\0") | hex_asc_hi(offset) << 8 | hex_asc_lo(offset);
}
static int macsmc_gpio_find_first_gpio_index(struct macsmc_gpio *smcgp)
{
struct apple_smc *smc = smcgp->smc;
smc_key key = macsmc_gpio_key(0);
smc_key first_key, last_key;
int start, count, ret;
/* Return early if the key is out of bounds */
ret = apple_smc_get_key_by_index(smc, 0, &first_key);
if (ret)
return ret;
if (key <= first_key)
return -ENODEV;
ret = apple_smc_get_key_by_index(smc, smc->key_count - 1, &last_key);
if (ret)
return ret;
if (key > last_key)
return -ENODEV;
/* Binary search to find index of first SMC key bigger or equal to key */
start = 0;
count = smc->key_count;
while (count > 1) {
smc_key pkey;
int pivot = start + ((count - 1) >> 1);
ret = apple_smc_get_key_by_index(smc, pivot, &pkey);
if (ret < 0)
return ret;
if (pkey == key)
return pivot;
pivot++;
if (pkey < key) {
count -= pivot - start;
start = pivot;
} else {
count = pivot - start;
}
}
return start;
}
static int macsmc_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
{
struct macsmc_gpio *smcgp = gpiochip_get_data(gc);
smc_key key = macsmc_gpio_key(offset);
u32 val;
int ret;
/* First try reading the explicit pin mode register */
ret = apple_smc_rw_u32(smcgp->smc, key, CMD_PINMODE, &val);
if (!ret)
return (val & MODE_OUTPUT) ? GPIO_LINE_DIRECTION_OUT : GPIO_LINE_DIRECTION_IN;
/*
* Less common IRQ configs cause CMD_PINMODE to fail, and so does open drain mode.
* Fall back to reading IRQ mode, which will only succeed for inputs.
*/
ret = apple_smc_rw_u32(smcgp->smc, key, CMD_IRQ_MODE, &val);
return ret ? GPIO_LINE_DIRECTION_OUT : GPIO_LINE_DIRECTION_IN;
}
Annotation
- Immediate include surface: `linux/bitmap.h`, `linux/device.h`, `linux/gpio/driver.h`, `linux/hex.h`, `linux/mfd/core.h`, `linux/mfd/macsmc.h`.
- Detected declarations: `struct macsmc_gpio`, `function macsmc_gpio_nr`, `function macsmc_gpio_key`, `function macsmc_gpio_find_first_gpio_index`, `function macsmc_gpio_get_direction`, `function macsmc_gpio_get`, `function macsmc_gpio_set`, `function macsmc_gpio_init_valid_mask`, `function macsmc_gpio_probe`.
- Atlas domain: Driver Families / drivers/gpio.
- Implementation status: source implementation candidate.
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.