blob: 888e066c715b870c0553a76f2727652dd0635ec3 [file] [log] [blame]
Mattias Nilsson90550d12011-02-14 11:17:12 +01001/*
2 * Copyright (C) ST-Ericsson SA 2010
3 * Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com> for ST Ericsson.
4 * License terms: GNU General Public License (GPL) version 2
5 */
6
7#include <linux/err.h>
Paul Gortmaker4e36dd32011-07-03 15:13:27 -04008#include <linux/module.h>
Mattias Nilsson90550d12011-02-14 11:17:12 +01009#include <linux/platform_device.h>
Lee Jones379749c2013-01-14 13:26:15 +000010#include <linux/pm.h>
11#include <linux/signal.h>
Mattias Nilsson90550d12011-02-14 11:17:12 +010012#include <linux/mfd/abx500.h>
Linus Walleijee66e652011-12-02 14:16:33 +010013#include <linux/mfd/abx500/ab8500.h>
14#include <linux/mfd/abx500/ab8500-sysctrl.h>
Mattias Nilsson90550d12011-02-14 11:17:12 +010015
16static struct device *sysctrl_dev;
17
Lee Jones379749c2013-01-14 13:26:15 +000018void ab8500_power_off(void)
19{
20 sigset_t old;
21 sigset_t all;
22
23 sigfillset(&all);
24
25 if (!sigprocmask(SIG_BLOCK, &all, &old)) {
26 (void)ab8500_sysctrl_set(AB8500_STW4500CTRL1,
27 AB8500_STW4500CTRL1_SWOFF |
28 AB8500_STW4500CTRL1_SWRESET4500N);
29 (void)sigprocmask(SIG_SETMASK, &old, NULL);
30 }
31}
32
Mattias Nilsson90550d12011-02-14 11:17:12 +010033static inline bool valid_bank(u8 bank)
34{
35 return ((bank == AB8500_SYS_CTRL1_BLOCK) ||
36 (bank == AB8500_SYS_CTRL2_BLOCK));
37}
38
39int ab8500_sysctrl_read(u16 reg, u8 *value)
40{
41 u8 bank;
42
43 if (sysctrl_dev == NULL)
44 return -EAGAIN;
45
46 bank = (reg >> 8);
47 if (!valid_bank(bank))
48 return -EINVAL;
49
50 return abx500_get_register_interruptible(sysctrl_dev, bank,
51 (u8)(reg & 0xFF), value);
52}
53
54int ab8500_sysctrl_write(u16 reg, u8 mask, u8 value)
55{
56 u8 bank;
57
58 if (sysctrl_dev == NULL)
59 return -EAGAIN;
60
61 bank = (reg >> 8);
62 if (!valid_bank(bank))
63 return -EINVAL;
64
65 return abx500_mask_and_set_register_interruptible(sysctrl_dev, bank,
66 (u8)(reg & 0xFF), mask, value);
67}
68
Bill Pembertonf791be42012-11-19 13:23:04 -050069static int ab8500_sysctrl_probe(struct platform_device *pdev)
Mattias Nilsson90550d12011-02-14 11:17:12 +010070{
Lee Jones379749c2013-01-14 13:26:15 +000071 struct ab8500_platform_data *plat;
72
Mattias Nilsson90550d12011-02-14 11:17:12 +010073 sysctrl_dev = &pdev->dev;
Lee Jones379749c2013-01-14 13:26:15 +000074 plat = dev_get_platdata(pdev->dev.parent);
75 if (plat->pm_power_off)
76 pm_power_off = ab8500_power_off;
Mattias Nilsson90550d12011-02-14 11:17:12 +010077 return 0;
78}
79
Bill Pemberton4740f732012-11-19 13:26:01 -050080static int ab8500_sysctrl_remove(struct platform_device *pdev)
Mattias Nilsson90550d12011-02-14 11:17:12 +010081{
82 sysctrl_dev = NULL;
83 return 0;
84}
85
86static struct platform_driver ab8500_sysctrl_driver = {
87 .driver = {
88 .name = "ab8500-sysctrl",
89 .owner = THIS_MODULE,
Mattias Nilsson90550d12011-02-14 11:17:12 +010090 },
91 .probe = ab8500_sysctrl_probe,
Bill Pemberton84449212012-11-19 13:20:24 -050092 .remove = ab8500_sysctrl_remove,
Mattias Nilsson90550d12011-02-14 11:17:12 +010093};
94
95static int __init ab8500_sysctrl_init(void)
96{
97 return platform_driver_register(&ab8500_sysctrl_driver);
98}
99subsys_initcall(ab8500_sysctrl_init);
100
101MODULE_AUTHOR("Mattias Nilsson <mattias.i.nilsson@stericsson.com");
102MODULE_DESCRIPTION("AB8500 system control driver");
103MODULE_LICENSE("GPL v2");