diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-24 20:00:58 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-24 20:00:58 -0800 |
commit | ab7826595e9ec51a51f622c5fc91e2f59440481a (patch) | |
tree | 34241b399fa7a12c260e06e6c1c31bc69d46e1e3 /drivers/mfd/ab8500-sysctrl.c | |
parent | 21fbd5809ad126b949206d78e0a0e07ec872ea11 (diff) | |
parent | ff7109fa632654eaef657186f2942f5b679023d6 (diff) | |
download | talos-obmc-linux-ab7826595e9ec51a51f622c5fc91e2f59440481a.tar.gz talos-obmc-linux-ab7826595e9ec51a51f622c5fc91e2f59440481a.zip |
Merge tag 'mfd-3.9-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6
Pull MFS updates from Samuel Ortiz:
"This is the MFD pull request for the 3.9 merge window.
No new drivers this time, but a bunch of fairly big cleanups:
- Roger Quadros worked on a OMAP USBHS and TLL platform data
consolidation, OMAP5 support and clock management code cleanup.
- The first step of a major sync for the ab8500 driver from Lee
Jones. In particular, the debugfs and the sysct interfaces got
extended and improved.
- Peter Ujfalusi sent a nice patchset for cleaning and fixing the
twl-core driver, with a much needed module id lookup code
improvement.
- The regular wm5102 and arizona cleanups and fixes from Mark Brown.
- Laxman Dewangan extended the palmas APIs in order to implement the
palmas GPIO and rt drivers.
- Laxman also added DT support for the tps65090 driver.
- The Intel SCH and ICH drivers got a couple fixes from Aaron Sierra
and Darren Hart.
- Linus Walleij patchset for the ab8500 driver allowed ab8500 and
ab9540 based devices to switch to the new abx500 pin-ctrl driver.
- The max8925 now has device tree and irqdomain support thanks to
Qing Xu.
- The recently added rtsx driver got a few cleanups and fixes for a
better card detection code path and now also supports the RTS5227
chipset, thanks to Wei Wang and Roger Tseng."
* tag 'mfd-3.9-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6: (109 commits)
mfd: lpc_ich: Use devres API to allocate private data
mfd: lpc_ich: Add Device IDs for Intel Wellsburg PCH
mfd: lpc_sch: Accomodate partial population of the MFD devices
mfd: da9052-i2c: Staticize da9052_i2c_fix()
mfd: syscon: Fix sparse warning
mfd: twl-core: Fix kernel panic on boot
mfd: rtsx: Fix issue that booting OS with SD card inserted
mfd: ab8500: Fix compile error
mfd: Add missing GENERIC_HARDIRQS dependecies
Documentation: Add docs for max8925 dt
mfd: max8925: Add dts
mfd: max8925: Support dt for backlight
mfd: max8925: Fix onkey driver irq base
mfd: max8925: Fix mfd device register failure
mfd: max8925: Add irqdomain for dt
mfd: vexpress: Allow vexpress-sysreg to self-initialise
mfd: rtsx: Support RTS5227
mfd: rtsx: Implement driving adjustment to device-dependent callbacks
mfd: vexpress: Add pseudo-GPIO based LEDs
mfd: ab8500: Rename ab8500 to abx500 for hwmon driver
...
Diffstat (limited to 'drivers/mfd/ab8500-sysctrl.c')
-rw-r--r-- | drivers/mfd/ab8500-sysctrl.c | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/drivers/mfd/ab8500-sysctrl.c b/drivers/mfd/ab8500-sysctrl.c index 8a33b2c7eead..108fd86552f0 100644 --- a/drivers/mfd/ab8500-sysctrl.c +++ b/drivers/mfd/ab8500-sysctrl.c @@ -7,12 +7,73 @@ #include <linux/err.h> #include <linux/module.h> #include <linux/platform_device.h> +#include <linux/pm.h> +#include <linux/reboot.h> +#include <linux/signal.h> +#include <linux/power_supply.h> #include <linux/mfd/abx500.h> #include <linux/mfd/abx500/ab8500.h> #include <linux/mfd/abx500/ab8500-sysctrl.h> static struct device *sysctrl_dev; +void ab8500_power_off(void) +{ + sigset_t old; + sigset_t all; + static char *pss[] = {"ab8500_ac", "ab8500_usb"}; + int i; + bool charger_present = false; + union power_supply_propval val; + struct power_supply *psy; + int ret; + + /* + * If we have a charger connected and we're powering off, + * reboot into charge-only mode. + */ + + for (i = 0; i < ARRAY_SIZE(pss); i++) { + psy = power_supply_get_by_name(pss[i]); + if (!psy) + continue; + + ret = psy->get_property(psy, POWER_SUPPLY_PROP_ONLINE, &val); + + 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 = psy->get_property(psy, POWER_SUPPLY_PROP_TECHNOLOGY, + &val); + if (!ret && val.intval != POWER_SUPPLY_TECHNOLOGY_UNKNOWN) { + printk(KERN_INFO + "Charger \"%s\" is connected with known battery." + " Rebooting.\n", + pss[i]); + machine_restart("charging"); + } + } + +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) || @@ -33,6 +94,7 @@ int ab8500_sysctrl_read(u16 reg, u8 *value) 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) { @@ -48,10 +110,40 @@ int ab8500_sysctrl_write(u16 reg, u8 mask, u8 value) 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) { + struct ab8500_platform_data *plat; + struct ab8500_sysctrl_platform_data *pdata; + sysctrl_dev = &pdev->dev; + plat = dev_get_platdata(pdev->dev.parent); + if (plat->pm_power_off) + pm_power_off = ab8500_power_off; + + pdata = plat->sysctrl; + + if (pdata) { + int ret, i, j; + + for (i = AB8500_SYSCLKREQ1RFCLKBUF; + i <= AB8500_SYSCLKREQ8RFCLKBUF; i++) { + j = i - AB8500_SYSCLKREQ1RFCLKBUF; + ret = ab8500_sysctrl_write(i, 0xff, + pdata->initial_req_buf_config[j]); + dev_dbg(&pdev->dev, + "Setting SysClkReq%dRfClkBuf 0x%X\n", + j + 1, + pdata->initial_req_buf_config[j]); + if (ret < 0) { + dev_err(&pdev->dev, + "unable to set sysClkReq%dRfClkBuf: " + "%d\n", j + 1, ret); + } + } + } + return 0; } |