drivers/mfd/ab8500-sysctrl.c

Source file repositories/reference/linux-study-clean/drivers/mfd/ab8500-sysctrl.c

File Facts

System
Linux kernel
Corpus path
drivers/mfd/ab8500-sysctrl.c
Extension
.c
Size
3690 bytes
Lines
170
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.

Dependency Surface

Detected Declarations

Annotated Snippet

if (!ret && val.intval) {
			charger_present = true;
			break;
		}
	}

	if (!charger_present)
		goto shutdown;

	/* Check if battery is known */
	psy = power_supply_get_by_name("ab8500_btemp");
	if (psy) {
		ret = power_supply_get_property(psy,
				POWER_SUPPLY_PROP_TECHNOLOGY, &val);
		if (!ret && val.intval != POWER_SUPPLY_TECHNOLOGY_UNKNOWN) {
			pr_info("Charger '%s' is connected with known battery",
				pss[i]);
			pr_info(" - Rebooting.\n");
			machine_restart("charging");
		}
		power_supply_put(psy);
	}

shutdown:
	sigfillset(&all);

	if (!sigprocmask(SIG_BLOCK, &all, &old)) {
		(void)ab8500_sysctrl_set(AB8500_STW4500CTRL1,
					 AB8500_STW4500CTRL1_SWOFF |
					 AB8500_STW4500CTRL1_SWRESET4500N);
		(void)sigprocmask(SIG_SETMASK, &old, NULL);
	}
}

static inline bool valid_bank(u8 bank)
{
	return ((bank == AB8500_SYS_CTRL1_BLOCK) ||
		(bank == AB8500_SYS_CTRL2_BLOCK));
}

int ab8500_sysctrl_read(u16 reg, u8 *value)
{
	u8 bank;

	if (sysctrl_dev == NULL)
		return -EPROBE_DEFER;

	bank = (reg >> 8);
	if (!valid_bank(bank))
		return -EINVAL;

	return abx500_get_register_interruptible(sysctrl_dev, bank,
		(u8)(reg & 0xFF), value);
}
EXPORT_SYMBOL(ab8500_sysctrl_read);

int ab8500_sysctrl_write(u16 reg, u8 mask, u8 value)
{
	u8 bank;

	if (sysctrl_dev == NULL)
		return -EPROBE_DEFER;

	bank = (reg >> 8);
	if (!valid_bank(bank)) {
		pr_err("invalid bank\n");
		return -EINVAL;
	}

	return abx500_mask_and_set_register_interruptible(sysctrl_dev, bank,
		(u8)(reg & 0xFF), mask, value);
}
EXPORT_SYMBOL(ab8500_sysctrl_write);

static int ab8500_sysctrl_probe(struct platform_device *pdev)
{
	sysctrl_dev = &pdev->dev;

	if (!pm_power_off)
		pm_power_off = ab8500_power_off;

	return 0;
}

static void ab8500_sysctrl_remove(struct platform_device *pdev)
{
	sysctrl_dev = NULL;

	if (pm_power_off == ab8500_power_off)
		pm_power_off = NULL;

Annotation

Implementation Notes