blob: 45429a12550b4bcf8a7bc3ec0598d5984578cd06 [file] [log] [blame]
Kenneth Heitke65a5ad22012-02-08 14:00:04 -07001/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#define pr_fmt(fmt) "%s: " fmt, __func__
14
15#include <linux/delay.h>
16#include <linux/err.h>
17#include <linux/io.h>
18#include <linux/kernel.h>
19#include <linux/platform_device.h>
20#include <linux/slab.h>
21#include <linux/spmi.h>
22#include <linux/of.h>
23#include <linux/interrupt.h>
24#include <linux/of_spmi.h>
Steve Mucklef132c6c2012-06-06 18:30:57 -070025#include <linux/module.h>
Kenneth Heitke65a5ad22012-02-08 14:00:04 -070026#include <mach/qpnp-int.h>
27
28#define SPMI_PMIC_ARB_NAME "spmi_pmic_arb"
29
30/* PMIC Arbiter configuration registers */
31#define PMIC_ARB_VERSION 0x0000
32#define PMIC_ARB_INT_EN 0x0004
33
34/* PMIC Arbiter channel registers */
35#define PMIC_ARB_CMD(N) (0x0800 + (0x80 * (N)))
36#define PMIC_ARB_CONFIG(N) (0x0804 + (0x80 * (N)))
37#define PMIC_ARB_STATUS(N) (0x0808 + (0x80 * (N)))
38#define PMIC_ARB_WDATA0(N) (0x0810 + (0x80 * (N)))
39#define PMIC_ARB_WDATA1(N) (0x0814 + (0x80 * (N)))
40#define PMIC_ARB_RDATA0(N) (0x0818 + (0x80 * (N)))
41#define PMIC_ARB_RDATA1(N) (0x081C + (0x80 * (N)))
42
43/* Interrupt Controller */
44#define SPMI_PIC_OWNER_ACC_STATUS(M, N) (0x0000 + ((32 * (M)) + (4 * (N))))
45#define SPMI_PIC_ACC_ENABLE(N) (0x0200 + (4 * (N)))
46#define SPMI_PIC_IRQ_STATUS(N) (0x0600 + (4 * (N)))
47#define SPMI_PIC_IRQ_CLEAR(N) (0x0A00 + (4 * (N)))
48
49/* Channel Status fields */
50enum pmic_arb_chnl_status {
51 PMIC_ARB_STATUS_DONE = (1 << 0),
52 PMIC_ARB_STATUS_FAILURE = (1 << 1),
53 PMIC_ARB_STATUS_DENIED = (1 << 2),
54 PMIC_ARB_STATUS_DROPPED = (1 << 3),
55};
56
57/* Command register fields */
58#define PMIC_ARB_CMD_MAX_BYTE_COUNT 8
59
60/* Command Opcodes */
61enum pmic_arb_cmd_op_code {
62 PMIC_ARB_OP_EXT_WRITEL = 0,
63 PMIC_ARB_OP_EXT_READL = 1,
64 PMIC_ARB_OP_EXT_WRITE = 2,
65 PMIC_ARB_OP_RESET = 3,
66 PMIC_ARB_OP_SLEEP = 4,
67 PMIC_ARB_OP_SHUTDOWN = 5,
68 PMIC_ARB_OP_WAKEUP = 6,
69 PMIC_ARB_OP_AUTHENTICATE = 7,
70 PMIC_ARB_OP_MSTR_READ = 8,
71 PMIC_ARB_OP_MSTR_WRITE = 9,
72 PMIC_ARB_OP_EXT_READ = 13,
73 PMIC_ARB_OP_WRITE = 14,
74 PMIC_ARB_OP_READ = 15,
75 PMIC_ARB_OP_ZERO_WRITE = 16,
76};
77
78/* Maximum number of support PMIC peripherals */
79#define PMIC_ARB_MAX_PERIPHS 256
80#define PMIC_ARB_PERIPH_ID_VALID (1 << 15)
81#define PMIC_ARB_TIMEOUT_US 100
Gilad Avidove0c3f702012-07-12 13:19:12 -060082#define PMIC_ARB_MAX_TRANS_BYTES (8)
Gilad Avidova11c0b52012-02-15 15:30:49 -070083
84#define PMIC_ARB_APID_MASK 0xFF
85#define PMIC_ARB_PPID_MASK 0xFFF
86/* extract PPID and APID from interrupt map in .dts config file format */
87#define PMIC_ARB_DEV_TRE_2_PPID(MAP_COMPRS_VAL) \
88 ((MAP_COMPRS_VAL) >> (20))
89#define PMIC_ARB_DEV_TRE_2_APID(MAP_COMPRS_VAL) \
90 ((MAP_COMPRS_VAL) & PMIC_ARB_APID_MASK)
Kenneth Heitke65a5ad22012-02-08 14:00:04 -070091
92/**
93 * base - base address of the PMIC Arbiter core registers.
94 * intr - base address of the SPMI interrupt control registers
95 */
96struct spmi_pmic_arb_dev {
97 struct spmi_controller controller;
98 struct device *dev;
99 struct device *slave;
100 void __iomem *base;
101 void __iomem *intr;
102 int pic_irq;
Kenneth Heitke65a5ad22012-02-08 14:00:04 -0700103 spinlock_t lock;
104 u8 owner;
105 u8 channel;
106 u8 min_apid;
107 u8 max_apid;
108 u16 periph_id_map[PMIC_ARB_MAX_PERIPHS];
109};
110
111static u32 pmic_arb_read(struct spmi_pmic_arb_dev *dev, u32 offset)
112{
113 u32 val = readl_relaxed(dev->base + offset);
114 pr_debug("address 0x%p, val 0x%x\n", dev->base + offset, val);
115 return val;
116}
117
118static void pmic_arb_write(struct spmi_pmic_arb_dev *dev, u32 offset, u32 val)
119{
120 pr_debug("address 0x%p, val 0x%x\n", dev->base + offset, val);
121 writel_relaxed(val, dev->base + offset);
122}
123
124static int pmic_arb_wait_for_done(struct spmi_pmic_arb_dev *dev)
125{
126 u32 status = 0;
127 u32 timeout = PMIC_ARB_TIMEOUT_US;
128 u32 offset = PMIC_ARB_STATUS(dev->channel);
129
130 while (timeout--) {
131 status = pmic_arb_read(dev, offset);
132
133 if (status & PMIC_ARB_STATUS_DONE) {
134 if (status & PMIC_ARB_STATUS_DENIED) {
135 dev_err(dev->dev,
136 "%s: transaction denied (0x%x)\n",
137 __func__, status);
138 return -EPERM;
139 }
140
141 if (status & PMIC_ARB_STATUS_FAILURE) {
142 dev_err(dev->dev,
143 "%s: transaction failed (0x%x)\n",
144 __func__, status);
145 return -EIO;
146 }
147
148 if (status & PMIC_ARB_STATUS_DROPPED) {
149 dev_err(dev->dev,
150 "%s: transaction dropped (0x%x)\n",
151 __func__, status);
152 return -EIO;
153 }
154
155 return 0;
156 }
157 udelay(1);
158 }
159
160 dev_err(dev->dev, "%s: timeout, status 0x%x\n", __func__, status);
161 return -ETIMEDOUT;
162}
163
Gilad Avidove0c3f702012-07-12 13:19:12 -0600164/**
165 * pa_read_data: reads pmic-arb's register and copy 1..4 bytes to buf
166 * @bc byte count -1. range: 0..3
167 * @reg register's address
168 * @buf output parameter, length must be bc+1
169 */
Kenneth Heitke65a5ad22012-02-08 14:00:04 -0700170static void pa_read_data(struct spmi_pmic_arb_dev *dev, u8 *buf, u32 reg, u8 bc)
171{
172 u32 data = pmic_arb_read(dev, reg);
Gilad Avidove0c3f702012-07-12 13:19:12 -0600173 memcpy(buf, &data, (bc & 3) + 1);
Kenneth Heitke65a5ad22012-02-08 14:00:04 -0700174}
175
Gilad Avidove0c3f702012-07-12 13:19:12 -0600176/**
177 * pa_write_data: write 1..4 bytes from buf to pmic-arb's register
178 * @bc byte-count -1. range: 0..3
179 * @reg register's address
180 * @buf buffer to write. length must be bc+1
181 */
Kenneth Heitke65a5ad22012-02-08 14:00:04 -0700182static void
183pa_write_data(struct spmi_pmic_arb_dev *dev, u8 *buf, u32 reg, u8 bc)
184{
185 u32 data = 0;
Gilad Avidove0c3f702012-07-12 13:19:12 -0600186 memcpy(&data, buf, (bc & 3) + 1);
Kenneth Heitke65a5ad22012-02-08 14:00:04 -0700187 pmic_arb_write(dev, reg, data);
188}
189
190/* Non-data command */
191static int pmic_arb_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid)
192{
193 struct spmi_pmic_arb_dev *pmic_arb = spmi_get_ctrldata(ctrl);
194 unsigned long flags;
195 u32 cmd;
196 int rc;
197
198 pr_debug("op:0x%x sid:%d\n", opc, sid);
199
200 /* Check for valid non-data command */
201 if (opc < SPMI_CMD_RESET || opc > SPMI_CMD_WAKEUP)
202 return -EINVAL;
203
204 cmd = ((opc | 0x40) << 27) | ((sid & 0xf) << 20);
205
206 spin_lock_irqsave(&pmic_arb->lock, flags);
207 pmic_arb_write(pmic_arb, PMIC_ARB_CMD(pmic_arb->channel), cmd);
208 rc = pmic_arb_wait_for_done(pmic_arb);
209 spin_unlock_irqrestore(&pmic_arb->lock, flags);
210
211 return rc;
212}
213
214static int pmic_arb_read_cmd(struct spmi_controller *ctrl,
215 u8 opc, u8 sid, u16 addr, u8 bc, u8 *buf)
216{
217 struct spmi_pmic_arb_dev *pmic_arb = spmi_get_ctrldata(ctrl);
218 unsigned long flags;
219 u32 cmd;
220 int rc;
221
Gilad Avidove0c3f702012-07-12 13:19:12 -0600222 if (bc >= PMIC_ARB_MAX_TRANS_BYTES) {
223 dev_err(pmic_arb->dev
224 , "pmic-arb supports 1..%d bytes per trans, but:%d requested"
225 , PMIC_ARB_MAX_TRANS_BYTES, bc+1);
226 return -EINVAL;
227 }
Kenneth Heitke65a5ad22012-02-08 14:00:04 -0700228 pr_debug("op:0x%x sid:%d bc:%d addr:0x%x\n", opc, sid, bc, addr);
229
230 /* Check the opcode */
231 if (opc >= 0x60 && opc <= 0x7F)
232 opc = PMIC_ARB_OP_READ;
233 else if (opc >= 0x20 && opc <= 0x2F)
234 opc = PMIC_ARB_OP_EXT_READ;
235 else if (opc >= 0x38 && opc <= 0x3F)
236 opc = PMIC_ARB_OP_EXT_READL;
237 else
238 return -EINVAL;
239
240 cmd = (opc << 27) | ((sid & 0xf) << 20) | (addr << 4) | (bc & 0x7);
241
242 spin_lock_irqsave(&pmic_arb->lock, flags);
243 pmic_arb_write(pmic_arb, PMIC_ARB_CMD(pmic_arb->channel), cmd);
244 rc = pmic_arb_wait_for_done(pmic_arb);
245 if (rc)
246 goto done;
247
248 /* Read from FIFO, note 'bc' is actually number of bytes minus 1 */
Gilad Avidove0c3f702012-07-12 13:19:12 -0600249 pa_read_data(pmic_arb, buf, PMIC_ARB_RDATA0(pmic_arb->channel)
250 , min_t(u8, bc, 3));
Kenneth Heitke65a5ad22012-02-08 14:00:04 -0700251
252 if (bc > 3)
253 pa_read_data(pmic_arb, buf + 4,
Gilad Avidove0c3f702012-07-12 13:19:12 -0600254 PMIC_ARB_RDATA1(pmic_arb->channel), bc - 4);
Kenneth Heitke65a5ad22012-02-08 14:00:04 -0700255
256done:
257 spin_unlock_irqrestore(&pmic_arb->lock, flags);
258 return rc;
259}
260
261static int pmic_arb_write_cmd(struct spmi_controller *ctrl,
262 u8 opc, u8 sid, u16 addr, u8 bc, u8 *buf)
263{
264 struct spmi_pmic_arb_dev *pmic_arb = spmi_get_ctrldata(ctrl);
265 unsigned long flags;
266 u32 cmd;
267 int rc;
268
Gilad Avidove0c3f702012-07-12 13:19:12 -0600269 if (bc >= PMIC_ARB_MAX_TRANS_BYTES) {
270 dev_err(pmic_arb->dev
271 , "pmic-arb supports 1..%d bytes per trans, but:%d requested"
272 , PMIC_ARB_MAX_TRANS_BYTES, bc+1);
273 return -EINVAL;
274 }
Kenneth Heitke65a5ad22012-02-08 14:00:04 -0700275 pr_debug("op:0x%x sid:%d bc:%d addr:0x%x\n", opc, sid, bc, addr);
276
277 /* Check the opcode */
278 if (opc >= 0x40 && opc <= 0x5F)
279 opc = PMIC_ARB_OP_WRITE;
280 else if (opc >= 0x00 && opc <= 0x0F)
281 opc = PMIC_ARB_OP_EXT_WRITE;
282 else if (opc >= 0x30 && opc <= 0x37)
283 opc = PMIC_ARB_OP_EXT_WRITEL;
284 else if (opc >= 0x80 && opc <= 0xFF)
285 opc = PMIC_ARB_OP_ZERO_WRITE;
286 else
287 return -EINVAL;
288
289 cmd = (opc << 27) | ((sid & 0xf) << 20) | (addr << 4) | (bc & 0x7);
290
291 /* Write data to FIFOs */
292 spin_lock_irqsave(&pmic_arb->lock, flags);
Gilad Avidove0c3f702012-07-12 13:19:12 -0600293 pa_write_data(pmic_arb, buf, PMIC_ARB_WDATA0(pmic_arb->channel)
294 , min_t(u8, bc, 3));
Kenneth Heitke65a5ad22012-02-08 14:00:04 -0700295 if (bc > 3)
296 pa_write_data(pmic_arb, buf + 4,
Gilad Avidove0c3f702012-07-12 13:19:12 -0600297 PMIC_ARB_WDATA1(pmic_arb->channel), bc - 4);
Kenneth Heitke65a5ad22012-02-08 14:00:04 -0700298
299 /* Start the transaction */
300 pmic_arb_write(pmic_arb, PMIC_ARB_CMD(pmic_arb->channel), cmd);
301 rc = pmic_arb_wait_for_done(pmic_arb);
302 spin_unlock_irqrestore(&pmic_arb->lock, flags);
303
304 return rc;
305}
306
307/* APID to PPID */
308static u16 get_peripheral_id(struct spmi_pmic_arb_dev *pmic_arb, u8 apid)
309{
310 return pmic_arb->periph_id_map[apid] & PMIC_ARB_PPID_MASK;
311}
312
313/* APID to PPID, returns valid flag */
314static int is_apid_valid(struct spmi_pmic_arb_dev *pmic_arb, u8 apid)
315{
316 return pmic_arb->periph_id_map[apid] & PMIC_ARB_PERIPH_ID_VALID;
317}
318
319/* PPID to APID */
320static uint32_t map_peripheral_id(struct spmi_pmic_arb_dev *pmic_arb, u16 ppid)
321{
322 int first = pmic_arb->min_apid;
323 int last = pmic_arb->max_apid;
324 int i;
325
326 /* Search table for a matching PPID */
327 for (i = first; i <= last; ++i) {
328 if ((pmic_arb->periph_id_map[i] & PMIC_ARB_PPID_MASK) == ppid)
329 return i;
330 }
331
332 dev_err(pmic_arb->dev, "Unknown ppid 0x%x\n", ppid);
333 return PMIC_ARB_MAX_PERIPHS;
334}
335
336/* Enable interrupt at the PMIC Arbiter PIC */
337static int pmic_arb_pic_enable(struct spmi_controller *ctrl,
338 struct qpnp_irq_spec *spec, uint32_t data)
339{
340 struct spmi_pmic_arb_dev *pmic_arb = spmi_get_ctrldata(ctrl);
341 u8 apid = data & PMIC_ARB_APID_MASK;
342 unsigned long flags;
343 u32 status;
344
345 dev_dbg(pmic_arb->dev, "PIC enable, apid:0x%x, sid:0x%x, pid:0x%x\n",
346 apid, spec->slave, spec->per);
347
348 if (data < pmic_arb->min_apid || data > pmic_arb->max_apid) {
349 dev_err(pmic_arb->dev, "int enable: invalid APID %d\n", data);
350 return -EINVAL;
351 }
352
353 if (!is_apid_valid(pmic_arb, apid)) {
354 dev_err(pmic_arb->dev, "int enable: int not supported\n");
355 return -EINVAL;
356 }
357
358 spin_lock_irqsave(&pmic_arb->lock, flags);
359 status = readl_relaxed(pmic_arb->intr + SPMI_PIC_ACC_ENABLE(apid));
360 if (!status) {
Kenneth Heitke65a5ad22012-02-08 14:00:04 -0700361 writel_relaxed(0x1, pmic_arb->intr + SPMI_PIC_ACC_ENABLE(apid));
362 /* Interrupt needs to be enabled before returning to caller */
363 wmb();
364 }
365 spin_unlock_irqrestore(&pmic_arb->lock, flags);
366 return 0;
367}
368
369/* Disable interrupt at the PMIC Arbiter PIC */
370static int pmic_arb_pic_disable(struct spmi_controller *ctrl,
371 struct qpnp_irq_spec *spec, uint32_t data)
372{
373 struct spmi_pmic_arb_dev *pmic_arb = spmi_get_ctrldata(ctrl);
374 u8 apid = data & PMIC_ARB_APID_MASK;
375 unsigned long flags;
376 u32 status;
377
378 dev_dbg(pmic_arb->dev, "PIC disable, apid:0x%x, sid:0x%x, pid:0x%x\n",
379 apid, spec->slave, spec->per);
380
381 if (data < pmic_arb->min_apid || data > pmic_arb->max_apid) {
382 dev_err(pmic_arb->dev, "int disable: invalid APID %d\n", data);
383 return -EINVAL;
384 }
385
386 if (!is_apid_valid(pmic_arb, apid)) {
387 dev_err(pmic_arb->dev, "int disable: int not supported\n");
388 return -EINVAL;
389 }
390
391 spin_lock_irqsave(&pmic_arb->lock, flags);
392 status = readl_relaxed(pmic_arb->intr + SPMI_PIC_ACC_ENABLE(apid));
393 if (status) {
Kenneth Heitke65a5ad22012-02-08 14:00:04 -0700394 writel_relaxed(0x0, pmic_arb->intr + SPMI_PIC_ACC_ENABLE(apid));
395 /* Interrupt needs to be disabled before returning to caller */
396 wmb();
397 }
398 spin_unlock_irqrestore(&pmic_arb->lock, flags);
399 return 0;
400}
401
402static irqreturn_t
403periph_interrupt(struct spmi_pmic_arb_dev *pmic_arb, u8 apid)
404{
405 u16 ppid = get_peripheral_id(pmic_arb, apid);
406 void __iomem *base = pmic_arb->intr;
407 u8 sid = (ppid >> 8) & 0x0F;
408 u8 pid = ppid & 0xFF;
409 u32 status;
410 int i;
411
412 if (!is_apid_valid(pmic_arb, apid)) {
413 dev_err(pmic_arb->dev, "unknown peripheral id 0x%x\n", ppid);
414 /* return IRQ_NONE; */
415 }
416
417 /* Read the peripheral specific interrupt bits */
418 status = readl_relaxed(base + SPMI_PIC_IRQ_STATUS(apid));
419
420 /* Clear the peripheral interrupts */
421 writel_relaxed(status, base + SPMI_PIC_IRQ_CLEAR(apid));
422 /* Interrupt needs to be cleared/acknowledged before exiting ISR */
423 mb();
424
425 dev_dbg(pmic_arb->dev,
426 "interrupt, apid:0x%x, sid:0x%x, pid:0x%x, intr:0x%x\n",
427 apid, sid, pid, status);
428
429 /* Send interrupt notification */
430 for (i = 0; status && i < 8; ++i, status >>= 1) {
431 if (status & 0x1) {
432 struct qpnp_irq_spec irq_spec = {
433 .slave = sid,
434 .per = pid,
435 .irq = i,
436 };
437 qpnpint_handle_irq(&pmic_arb->controller, &irq_spec);
438 }
439 }
440 return IRQ_HANDLED;
441}
442
443/* Peripheral interrupt handler */
444static irqreturn_t pmic_arb_periph_irq(int irq, void *dev_id)
445{
446 struct spmi_pmic_arb_dev *pmic_arb = dev_id;
447 void __iomem *intr = pmic_arb->intr;
448 u8 ee = pmic_arb->owner;
449 u32 ret = IRQ_NONE;
450 u32 status;
451
452 int first = pmic_arb->min_apid >> 5;
453 int last = pmic_arb->max_apid >> 5;
454 int i, j;
455
456 dev_dbg(pmic_arb->dev, "Peripheral interrupt detected\n");
457
458 /* Check the accumulated interrupt status */
459 for (i = first; i <= last; ++i) {
460 status = readl_relaxed(intr + SPMI_PIC_OWNER_ACC_STATUS(ee, i));
461
462 for (j = 0; status && j < 32; ++j, status >>= 1) {
463 if (status & 0x1) {
464 u8 id = (i * 32) + j;
465 ret |= periph_interrupt(pmic_arb, id);
466 }
467 }
468 }
469
470 return ret;
471}
472
473/* Callback to register an APID for specific slave/peripheral */
474static int pmic_arb_intr_priv_data(struct spmi_controller *ctrl,
475 struct qpnp_irq_spec *spec, uint32_t *data)
476{
477 struct spmi_pmic_arb_dev *pmic_arb = spmi_get_ctrldata(ctrl);
478 u16 ppid = ((spec->slave & 0x0F) << 8) | (spec->per & 0xFF);
479 *data = map_peripheral_id(pmic_arb, ppid);
480 return 0;
481}
482
483static int __devinit
484spmi_pmic_arb_get_property(struct platform_device *pdev, char *pname, u32 *prop)
485{
486 int ret = of_property_read_u32(pdev->dev.of_node, pname, prop);
487
488 if (ret)
489 dev_err(&pdev->dev, "missing property: %s\n", pname);
490 else
491 pr_debug("%s = 0x%x\n", pname, *prop);
492
493 return ret;
494}
495
496static int __devinit spmi_pmic_arb_get_map_data(struct platform_device *pdev,
497 struct spmi_pmic_arb_dev *pmic_arb)
498{
499 int i;
500 int ret;
501 int map_size;
502 u32 *map_data;
Gilad Avidova11c0b52012-02-15 15:30:49 -0700503 const int map_width = sizeof(*map_data);
Kenneth Heitke65a5ad22012-02-08 14:00:04 -0700504 const struct device_node *of_node = pdev->dev.of_node;
505
506 /* Get size of the mapping table (in bytes) */
507 if (!of_get_property(of_node, "qcom,pmic-arb-ppid-map", &map_size)) {
508 dev_err(&pdev->dev, "missing ppid mapping table\n");
509 return -ENODEV;
510 }
511
512 /* Map size can't exceed the maximum number of peripherals */
Gilad Avidova11c0b52012-02-15 15:30:49 -0700513 if (map_size == 0 || map_size > map_width * PMIC_ARB_MAX_PERIPHS) {
Kenneth Heitke65a5ad22012-02-08 14:00:04 -0700514 dev_err(&pdev->dev, "map size of %d is not valid\n", map_size);
515 return -ENODEV;
516 }
517
518 map_data = kzalloc(map_size, GFP_KERNEL);
519 if (!map_data) {
520 dev_err(&pdev->dev, "can not allocate map data\n");
521 return -ENOMEM;
522 }
523
524 ret = of_property_read_u32_array(of_node,
525 "qcom,pmic-arb-ppid-map", map_data, map_size/sizeof(u32));
526 if (ret) {
527 dev_err(&pdev->dev, "invalid or missing property: ppid-map\n");
528 goto err;
529 };
530
531 pmic_arb->max_apid = 0;
532 pmic_arb->min_apid = PMIC_ARB_MAX_PERIPHS - 1;
533
534 /* Build the mapping table from the data */
535 for (i = 0; i < map_size/sizeof(u32);) {
Gilad Avidova11c0b52012-02-15 15:30:49 -0700536 u32 map_compressed_val = map_data[i++];
537 u32 ppid = PMIC_ARB_DEV_TRE_2_PPID(map_compressed_val) ;
538 u32 apid = PMIC_ARB_DEV_TRE_2_APID(map_compressed_val) ;
Kenneth Heitke65a5ad22012-02-08 14:00:04 -0700539
540 if (pmic_arb->periph_id_map[apid] & PMIC_ARB_PERIPH_ID_VALID)
541 dev_warn(&pdev->dev, "duplicate APID 0x%x\n", apid);
542
543 pmic_arb->periph_id_map[apid] = ppid | PMIC_ARB_PERIPH_ID_VALID;
544
545 if (apid > pmic_arb->max_apid)
546 pmic_arb->max_apid = apid;
547
548 if (apid < pmic_arb->min_apid)
549 pmic_arb->min_apid = apid;
550 }
551
552 pr_debug("%d value(s) mapped, min:%d, max:%d\n",
553 map_size/map_width, pmic_arb->min_apid, pmic_arb->max_apid);
554
555err:
556 kfree(map_data);
557 return ret;
558}
559
560static struct qpnp_local_int spmi_pmic_arb_intr_cb = {
561 .mask = pmic_arb_pic_disable,
562 .unmask = pmic_arb_pic_enable,
563 .register_priv_data = pmic_arb_intr_priv_data,
564};
565
566static int __devinit spmi_pmic_arb_probe(struct platform_device *pdev)
567{
568 struct spmi_pmic_arb_dev *pmic_arb;
569 struct resource *mem_res;
570 u32 cell_index;
571 u32 prop;
572 int ret = 0;
573
574 pr_debug("SPMI PMIC Arbiter\n");
575
576 pmic_arb = devm_kzalloc(&pdev->dev,
577 sizeof(struct spmi_pmic_arb_dev), GFP_KERNEL);
578 if (!pmic_arb) {
579 dev_err(&pdev->dev, "can not allocate pmic_arb data\n");
580 return -ENOMEM;
581 }
582
583 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
584 if (!mem_res) {
585 dev_err(&pdev->dev, "missing base memory resource\n");
586 return -ENODEV;
587 }
588
589 pmic_arb->base = devm_ioremap(&pdev->dev,
590 mem_res->start, resource_size(mem_res));
591 if (!pmic_arb->base) {
592 dev_err(&pdev->dev, "ioremap of 'base' failed\n");
593 return -ENOMEM;
594 }
595
596 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
597 if (!mem_res) {
598 dev_err(&pdev->dev, "missing mem resource (interrupts)\n");
599 return -ENODEV;
600 }
601
602 pmic_arb->intr = devm_ioremap(&pdev->dev,
603 mem_res->start, resource_size(mem_res));
604 if (!pmic_arb->intr) {
605 dev_err(&pdev->dev, "ioremap of 'intr' failed\n");
606 return -ENOMEM;
607 }
608
609 pmic_arb->pic_irq = platform_get_irq(pdev, 0);
610 if (!pmic_arb->pic_irq) {
611 dev_err(&pdev->dev, "missing IRQ resource\n");
612 return -ENODEV;
613 }
614
615 ret = devm_request_irq(&pdev->dev, pmic_arb->pic_irq,
616 pmic_arb_periph_irq, IRQF_TRIGGER_HIGH, pdev->name, pmic_arb);
617 if (ret) {
618 dev_err(&pdev->dev, "request IRQ failed\n");
619 return ret;
620 }
Kenneth Heitke65a5ad22012-02-08 14:00:04 -0700621
622 /* Get properties from the device tree */
623 ret = spmi_pmic_arb_get_property(pdev, "cell-index", &cell_index);
624 if (ret)
625 return -ENODEV;
626
627 ret = spmi_pmic_arb_get_map_data(pdev, pmic_arb);
628 if (ret)
629 return ret;
630
631 ret = spmi_pmic_arb_get_property(pdev, "qcom,pmic-arb-ee", &prop);
632 if (ret)
633 return -ENODEV;
634 pmic_arb->owner = (u8)prop;
635
636 ret = spmi_pmic_arb_get_property(pdev, "qcom,pmic-arb-channel", &prop);
637 if (ret)
638 return -ENODEV;
639 pmic_arb->channel = (u8)prop;
640
Kenneth Heitke71f3d5d2012-09-07 13:54:38 -0600641 ret = irq_set_irq_wake(pmic_arb->pic_irq, 1);
642 if (unlikely(ret)) {
643 pr_err("Unable to set wakeup irq, err=%d\n", ret);
644 return -ENODEV;
645 }
646
Kenneth Heitke65a5ad22012-02-08 14:00:04 -0700647 pmic_arb->dev = &pdev->dev;
648 platform_set_drvdata(pdev, pmic_arb);
649 spmi_set_ctrldata(&pmic_arb->controller, pmic_arb);
650
651 spin_lock_init(&pmic_arb->lock);
652
653 pmic_arb->controller.nr = cell_index;
654 pmic_arb->controller.dev.parent = pdev->dev.parent;
655 pmic_arb->controller.dev.of_node = of_node_get(pdev->dev.of_node);
656
657 /* Callbacks */
658 pmic_arb->controller.cmd = pmic_arb_cmd;
659 pmic_arb->controller.read_cmd = pmic_arb_read_cmd;
660 pmic_arb->controller.write_cmd = pmic_arb_write_cmd;
661
662 ret = spmi_add_controller(&pmic_arb->controller);
663 if (ret)
664 goto err_add_controller;
665
666 /* Register the interrupt enable/disable functions */
Michael Bohanbb6b30f2012-06-01 13:33:51 -0700667 ret = qpnpint_register_controller(pmic_arb->controller.dev.of_node,
668 &pmic_arb->controller,
669 &spmi_pmic_arb_intr_cb);
670 if (ret) {
671 dev_err(&pdev->dev, "Unable to register controller %d\n",
672 cell_index);
673 goto err_reg_controller;
674 }
Kenneth Heitke65a5ad22012-02-08 14:00:04 -0700675
676 /* Register device(s) from the device tree */
677 of_spmi_register_devices(&pmic_arb->controller);
678
679 pr_debug("PMIC Arb Version 0x%x\n",
680 pmic_arb_read(pmic_arb, PMIC_ARB_VERSION));
681
682 return 0;
683
Michael Bohanbb6b30f2012-06-01 13:33:51 -0700684err_reg_controller:
685 spmi_del_controller(&pmic_arb->controller);
Kenneth Heitke65a5ad22012-02-08 14:00:04 -0700686err_add_controller:
687 platform_set_drvdata(pdev, NULL);
Kenneth Heitke71f3d5d2012-09-07 13:54:38 -0600688 irq_set_irq_wake(pmic_arb->pic_irq, 0);
Kenneth Heitke65a5ad22012-02-08 14:00:04 -0700689 return ret;
690}
691
692static int __devexit spmi_pmic_arb_remove(struct platform_device *pdev)
693{
694 struct spmi_pmic_arb_dev *pmic_arb = platform_get_drvdata(pdev);
695
Kenneth Heitke71f3d5d2012-09-07 13:54:38 -0600696 irq_set_irq_wake(pmic_arb->pic_irq, 0);
Kenneth Heitke65a5ad22012-02-08 14:00:04 -0700697 platform_set_drvdata(pdev, NULL);
698 spmi_del_controller(&pmic_arb->controller);
699 return 0;
700}
701
702static struct of_device_id spmi_pmic_arb_match_table[] = {
703 { .compatible = "qcom,spmi-pmic-arb",
704 },
705 {}
706};
707
708static struct platform_driver spmi_pmic_arb_driver = {
709 .probe = spmi_pmic_arb_probe,
710 .remove = __exit_p(spmi_pmic_arb_remove),
711 .driver = {
712 .name = SPMI_PMIC_ARB_NAME,
713 .owner = THIS_MODULE,
714 .of_match_table = spmi_pmic_arb_match_table,
715 },
716};
717
718static int __init spmi_pmic_arb_init(void)
719{
720 return platform_driver_register(&spmi_pmic_arb_driver);
721}
722postcore_initcall(spmi_pmic_arb_init);
723
724static void __exit spmi_pmic_arb_exit(void)
725{
726 platform_driver_unregister(&spmi_pmic_arb_driver);
727}
728module_exit(spmi_pmic_arb_exit);
729
730MODULE_LICENSE("GPL v2");
731MODULE_VERSION("1.0");
732MODULE_ALIAS("platform:spmi_pmic_arb");