aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/power/tegra_bpc_mgmt.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/power/tegra_bpc_mgmt.c')
-rw-r--r--drivers/power/tegra_bpc_mgmt.c139
1 files changed, 139 insertions, 0 deletions
diff --git a/drivers/power/tegra_bpc_mgmt.c b/drivers/power/tegra_bpc_mgmt.c
new file mode 100644
index 00000000000..0d9ddeee282
--- /dev/null
+++ b/drivers/power/tegra_bpc_mgmt.c
@@ -0,0 +1,139 @@
1/*
2 * Copyright (C) 2010-2011 NVIDIA Corporation
3 *
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 */
14
15#include <linux/module.h>
16#include <linux/gpio.h>
17#include <linux/platform_device.h>
18#include <linux/interrupt.h>
19#include <linux/irqflags.h>
20#include <linux/slab.h>
21#include <linux/irq.h>
22#include <linux/sched.h>
23#include <linux/jiffies.h>
24#include <linux/platform_data/tegra_bpc_mgmt.h>
25
26#include <mach/edp.h>
27
28static irqreturn_t tegra_bpc_mgmt_bh(int irq, void *data)
29{
30 int gpio_val = 0;
31 struct tegra_bpc_mgmt_platform_data *bpc_platform_data;
32 bpc_platform_data = (struct tegra_bpc_mgmt_platform_data *)data;
33
34 tegra_system_edp_alarm(true);
35 /**
36 * Keep on checking whether event has passed or not.
37 */
38 while (!gpio_val) {
39 set_current_state(TASK_INTERRUPTIBLE);
40 schedule_timeout(msecs_to_jiffies(
41 bpc_platform_data->bpc_mgmt_timeout));
42
43 gpio_val = gpio_get_value(bpc_platform_data->gpio_trigger);
44 }
45
46 tegra_system_edp_alarm(false);
47
48 return IRQ_HANDLED;
49}
50
51static irqreturn_t tegra_bpc_mgmt_isr(int irq, void *data)
52{
53 tegra_edp_throttle_cpu_now(2);
54 return IRQ_WAKE_THREAD;
55}
56
57static __devinit int tegra_bpc_mgmt_probe(struct platform_device *pdev)
58{
59 u32 ret;
60 struct task_struct *bh_thread;
61 struct irq_desc *bat_desc;
62 struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 };
63 struct tegra_bpc_mgmt_platform_data *bpc_platform_data;
64
65 bpc_platform_data = pdev->dev.platform_data;
66 if (!bpc_platform_data)
67 return -ENODEV;
68
69 if (gpio_is_valid(bpc_platform_data->gpio_trigger)) {
70 ret = gpio_request(bpc_platform_data->gpio_trigger,
71 "tegra-bpc-mgmt");
72
73 if (ret < 0) {
74 pr_err("BPC: GPIO request failed");
75 return -ENODEV;
76 }
77 } else {
78 pr_err("BPC: GPIO check failed, gpio %d",
79 bpc_platform_data->gpio_trigger);
80 return -ENODEV;
81 }
82
83 gpio_direction_input(bpc_platform_data->gpio_trigger);
84
85 ret = request_threaded_irq(
86 gpio_to_irq(bpc_platform_data->gpio_trigger),
87 tegra_bpc_mgmt_isr,
88 tegra_bpc_mgmt_bh, IRQF_TRIGGER_LOW | IRQF_ONESHOT,
89 "tegra-bpc-mgmt", bpc_platform_data);
90 if (ret < 0) {
91 pr_err("BPC:IRQ Installation failed\n");
92 return -ENODEV;
93 }
94 bat_desc = irq_to_desc(
95 gpio_to_irq(bpc_platform_data->gpio_trigger));
96
97 if (bat_desc) {
98 bh_thread = bat_desc->action->thread;
99 if (bh_thread)
100 sched_setscheduler_nocheck(bh_thread,
101 SCHED_FIFO, &param);
102 }
103
104 return 0;
105}
106
107static __devexit int tegra_bpc_mgmt_remove(struct platform_device *pdev)
108{
109 struct tegra_bpc_mgmt_platform_data *bpc_platform_data;
110 bpc_platform_data = pdev->dev.platform_data;
111 free_irq(gpio_to_irq(bpc_platform_data->gpio_trigger), NULL);
112 return 0;
113}
114
115static struct platform_driver tegra_bpc_mgmt_driver = {
116 .probe = tegra_bpc_mgmt_probe,
117 .remove = tegra_bpc_mgmt_remove,
118 .driver = {
119 .name = "tegra-bpc-mgmt",
120 .owner = THIS_MODULE,
121 },
122};
123
124static int __init tegra_bpc_mgmt_init(void)
125{
126 return platform_driver_register(&tegra_bpc_mgmt_driver);
127}
128
129static void __exit tegra_bpc_mgmt_exit(void)
130{
131 platform_driver_unregister(&tegra_bpc_mgmt_driver);
132}
133
134module_init(tegra_bpc_mgmt_init);
135module_exit(tegra_bpc_mgmt_exit);
136
137MODULE_DESCRIPTION("TEGRA Battery Peak current Management");
138MODULE_AUTHOR("NVIDIA");
139MODULE_LICENSE("GPL");