Linux 3.17-rc2
[linux/fpc-iii.git] / arch / mips / mti-sead3 / sead3-pic32-bus.c
blob3b12aa5a7c88f378d3122ff5587e6192c74e22ad
1 /*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
6 * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved.
7 */
8 #include <linux/delay.h>
9 #include <linux/kernel.h>
10 #include <linux/spinlock.h>
11 #include <linux/io.h>
12 #include <linux/errno.h>
14 #define PIC32_NULL 0x00
15 #define PIC32_RD 0x01
16 #define PIC32_SYSRD 0x02
17 #define PIC32_WR 0x10
18 #define PIC32_SYSWR 0x20
19 #define PIC32_IRQ_CLR 0x40
20 #define PIC32_STATUS 0x80
22 #define DELAY() udelay(100) /* FIXME: needed? */
24 /* spinlock to ensure atomic access to PIC32 */
25 static DEFINE_SPINLOCK(pic32_bus_lock);
27 /* FIXME: io_remap these */
28 static void __iomem *bus_xfer = (void __iomem *)0xbf000600;
29 static void __iomem *bus_status = (void __iomem *)0xbf000060;
31 static inline unsigned int ioready(void)
33 return readl(bus_status) & 1;
36 static inline void wait_ioready(void)
38 do { } while (!ioready());
41 static inline void wait_ioclear(void)
43 do { } while (ioready());
46 static inline void check_ioclear(void)
48 if (ioready()) {
49 pr_debug("ioclear: initially busy\n");
50 do {
51 (void) readl(bus_xfer);
52 DELAY();
53 } while (ioready());
54 pr_debug("ioclear: cleared busy\n");
58 u32 pic32_bus_readl(u32 reg)
60 unsigned long flags;
61 u32 status, val;
63 spin_lock_irqsave(&pic32_bus_lock, flags);
65 check_ioclear();
67 writel((PIC32_RD << 24) | (reg & 0x00ffffff), bus_xfer);
68 DELAY();
69 wait_ioready();
70 status = readl(bus_xfer);
71 DELAY();
72 val = readl(bus_xfer);
73 wait_ioclear();
75 pr_debug("pic32_bus_readl: *%x -> %x (status=%x)\n", reg, val, status);
77 spin_unlock_irqrestore(&pic32_bus_lock, flags);
79 return val;
82 void pic32_bus_writel(u32 val, u32 reg)
84 unsigned long flags;
85 u32 status;
87 spin_lock_irqsave(&pic32_bus_lock, flags);
89 check_ioclear();
91 writel((PIC32_WR << 24) | (reg & 0x00ffffff), bus_xfer);
92 DELAY();
93 writel(val, bus_xfer);
94 DELAY();
95 wait_ioready();
96 status = readl(bus_xfer);
97 wait_ioclear();
99 pr_debug("pic32_bus_writel: *%x <- %x (status=%x)\n", reg, val, status);
101 spin_unlock_irqrestore(&pic32_bus_lock, flags);