Merge master.kernel.org:/pub/scm/linux/kernel/git/lethal/genesis-2.6 into devel-stable
[pandora-kernel.git] / arch / arm / mach-ux500 / prcmu.c
1 /*
2  * Copyright (C) ST Ericsson SA 2010
3  *
4  * License Terms: GNU General Public License v2
5  * Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com>
6  *
7  * U8500 PRCMU driver.
8  */
9 #include <linux/kernel.h>
10 #include <linux/module.h>
11 #include <linux/errno.h>
12 #include <linux/err.h>
13 #include <linux/io.h>
14 #include <linux/mutex.h>
15 #include <linux/completion.h>
16 #include <linux/jiffies.h>
17 #include <linux/bitops.h>
18 #include <linux/interrupt.h>
19
20 #include <mach/hardware.h>
21 #include <mach/prcmu-regs.h>
22
23 #define PRCMU_TCDM_BASE __io_address(U8500_PRCMU_TCDM_BASE)
24
25 #define REQ_MB5 (PRCMU_TCDM_BASE + 0xE44)
26 #define ACK_MB5 (PRCMU_TCDM_BASE + 0xDF4)
27
28 #define REQ_MB5_I2C_SLAVE_OP (REQ_MB5)
29 #define REQ_MB5_I2C_HW_BITS (REQ_MB5 + 1)
30 #define REQ_MB5_I2C_REG (REQ_MB5 + 2)
31 #define REQ_MB5_I2C_VAL (REQ_MB5 + 3)
32
33 #define ACK_MB5_I2C_STATUS (ACK_MB5 + 1)
34 #define ACK_MB5_I2C_VAL (ACK_MB5 + 3)
35
36 #define I2C_WRITE(slave) ((slave) << 1)
37 #define I2C_READ(slave) (((slave) << 1) | BIT(0))
38 #define I2C_STOP_EN BIT(3)
39
40 enum ack_mb5_status {
41         I2C_WR_OK = 0x01,
42         I2C_RD_OK = 0x02,
43 };
44
45 #define MBOX_BIT BIT
46 #define NUM_MBOX 8
47
48 static struct {
49         struct mutex lock;
50         struct completion work;
51         bool failed;
52         struct {
53                 u8 status;
54                 u8 value;
55         } ack;
56 } mb5_transfer;
57
58 /**
59  * prcmu_abb_read() - Read register value(s) from the ABB.
60  * @slave:      The I2C slave address.
61  * @reg:        The (start) register address.
62  * @value:      The read out value(s).
63  * @size:       The number of registers to read.
64  *
65  * Reads register value(s) from the ABB.
66  * @size has to be 1 for the current firmware version.
67  */
68 int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size)
69 {
70         int r;
71
72         if (size != 1)
73                 return -EINVAL;
74
75         r = mutex_lock_interruptible(&mb5_transfer.lock);
76         if (r)
77                 return r;
78
79         while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(5))
80                 cpu_relax();
81
82         writeb(I2C_READ(slave), REQ_MB5_I2C_SLAVE_OP);
83         writeb(I2C_STOP_EN, REQ_MB5_I2C_HW_BITS);
84         writeb(reg, REQ_MB5_I2C_REG);
85
86         writel(MBOX_BIT(5), PRCM_MBOX_CPU_SET);
87         if (!wait_for_completion_timeout(&mb5_transfer.work,
88                         msecs_to_jiffies(500))) {
89                 pr_err("prcmu: prcmu_abb_read timed out.\n");
90                 r = -EIO;
91                 goto unlock_and_return;
92         }
93         r = ((mb5_transfer.ack.status == I2C_RD_OK) ? 0 : -EIO);
94         if (!r)
95                 *value = mb5_transfer.ack.value;
96
97 unlock_and_return:
98         mutex_unlock(&mb5_transfer.lock);
99         return r;
100 }
101 EXPORT_SYMBOL(prcmu_abb_read);
102
103 /**
104  * prcmu_abb_write() - Write register value(s) to the ABB.
105  * @slave:      The I2C slave address.
106  * @reg:        The (start) register address.
107  * @value:      The value(s) to write.
108  * @size:       The number of registers to write.
109  *
110  * Reads register value(s) from the ABB.
111  * @size has to be 1 for the current firmware version.
112  */
113 int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size)
114 {
115         int r;
116
117         if (size != 1)
118                 return -EINVAL;
119
120         r = mutex_lock_interruptible(&mb5_transfer.lock);
121         if (r)
122                 return r;
123
124
125         while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(5))
126                 cpu_relax();
127
128         writeb(I2C_WRITE(slave), REQ_MB5_I2C_SLAVE_OP);
129         writeb(I2C_STOP_EN, REQ_MB5_I2C_HW_BITS);
130         writeb(reg, REQ_MB5_I2C_REG);
131         writeb(*value, REQ_MB5_I2C_VAL);
132
133         writel(MBOX_BIT(5), PRCM_MBOX_CPU_SET);
134         if (!wait_for_completion_timeout(&mb5_transfer.work,
135                         msecs_to_jiffies(500))) {
136                 pr_err("prcmu: prcmu_abb_write timed out.\n");
137                 r = -EIO;
138                 goto unlock_and_return;
139         }
140         r = ((mb5_transfer.ack.status == I2C_WR_OK) ? 0 : -EIO);
141
142 unlock_and_return:
143         mutex_unlock(&mb5_transfer.lock);
144         return r;
145 }
146 EXPORT_SYMBOL(prcmu_abb_write);
147
148 static void read_mailbox_0(void)
149 {
150         writel(MBOX_BIT(0), PRCM_ARM_IT1_CLEAR);
151 }
152
153 static void read_mailbox_1(void)
154 {
155         writel(MBOX_BIT(1), PRCM_ARM_IT1_CLEAR);
156 }
157
158 static void read_mailbox_2(void)
159 {
160         writel(MBOX_BIT(2), PRCM_ARM_IT1_CLEAR);
161 }
162
163 static void read_mailbox_3(void)
164 {
165         writel(MBOX_BIT(3), PRCM_ARM_IT1_CLEAR);
166 }
167
168 static void read_mailbox_4(void)
169 {
170         writel(MBOX_BIT(4), PRCM_ARM_IT1_CLEAR);
171 }
172
173 static void read_mailbox_5(void)
174 {
175         mb5_transfer.ack.status = readb(ACK_MB5_I2C_STATUS);
176         mb5_transfer.ack.value = readb(ACK_MB5_I2C_VAL);
177         complete(&mb5_transfer.work);
178         writel(MBOX_BIT(5), PRCM_ARM_IT1_CLEAR);
179 }
180
181 static void read_mailbox_6(void)
182 {
183         writel(MBOX_BIT(6), PRCM_ARM_IT1_CLEAR);
184 }
185
186 static void read_mailbox_7(void)
187 {
188         writel(MBOX_BIT(7), PRCM_ARM_IT1_CLEAR);
189 }
190
191 static void (* const read_mailbox[NUM_MBOX])(void) = {
192         read_mailbox_0,
193         read_mailbox_1,
194         read_mailbox_2,
195         read_mailbox_3,
196         read_mailbox_4,
197         read_mailbox_5,
198         read_mailbox_6,
199         read_mailbox_7
200 };
201
202 static irqreturn_t prcmu_irq_handler(int irq, void *data)
203 {
204         u32 bits;
205         u8 n;
206
207         bits = (readl(PRCM_ARM_IT1_VAL) & (MBOX_BIT(NUM_MBOX) - 1));
208         if (unlikely(!bits))
209                 return IRQ_NONE;
210
211         for (n = 0; bits; n++) {
212                 if (bits & MBOX_BIT(n)) {
213                         bits -= MBOX_BIT(n);
214                         read_mailbox[n]();
215                 }
216         }
217         return IRQ_HANDLED;
218 }
219
220 static int __init prcmu_init(void)
221 {
222         mutex_init(&mb5_transfer.lock);
223         init_completion(&mb5_transfer.work);
224
225         /* Clean up the mailbox interrupts after pre-kernel code. */
226         writel((MBOX_BIT(NUM_MBOX) - 1), PRCM_ARM_IT1_CLEAR);
227
228         return request_irq(IRQ_PRCMU, prcmu_irq_handler, 0, "prcmu", NULL);
229 }
230
231 arch_initcall(prcmu_init);