]> git.ipfire.org Git - thirdparty/linux.git/blame - arch/arm/mach-ixp4xx/common.c
Merge remote-tracking branches 'regulator/topic/helpers', 'regulator/topic/hi655x...
[thirdparty/linux.git] / arch / arm / mach-ixp4xx / common.c
CommitLineData
1da177e4
LT
1/*
2 * arch/arm/mach-ixp4xx/common.c
3 *
4 * Generic code shared across all IXP4XX platforms
5 *
6 * Maintainer: Deepak Saxena <dsaxena@plexity.net>
7 *
8 * Copyright 2002 (c) Intel Corporation
9 * Copyright 2003-2004 (c) MontaVista, Software, Inc.
10 *
11 * This file is licensed under the terms of the GNU General Public
12 * License version 2. This program is licensed "as is" without any
13 * warranty of any kind, whether express or implied.
14 */
15
1da177e4
LT
16#include <linux/kernel.h>
17#include <linux/mm.h>
18#include <linux/init.h>
19#include <linux/serial.h>
1da177e4 20#include <linux/tty.h>
d052d1be 21#include <linux/platform_device.h>
1da177e4 22#include <linux/serial_core.h>
1da177e4
LT
23#include <linux/interrupt.h>
24#include <linux/bitops.h>
25#include <linux/time.h>
84904d0e 26#include <linux/clocksource.h>
e32f1502 27#include <linux/clockchips.h>
fced80c7 28#include <linux/io.h>
dc28094b 29#include <linux/export.h>
010b16d4 30#include <linux/gpio/driver.h>
f7b861b7 31#include <linux/cpu.h>
00e1b3a3 32#include <linux/pci.h>
38ff87f7 33#include <linux/sched_clock.h>
a09e64fb
RK
34#include <mach/udc.h>
35#include <mach/hardware.h>
f449588c 36#include <mach/io.h>
7c0f6ba6 37#include <linux/uaccess.h>
1da177e4
LT
38#include <asm/pgtable.h>
39#include <asm/page.h>
40#include <asm/irq.h>
86dfe446 41#include <asm/system_misc.h>
1da177e4
LT
42#include <asm/mach/map.h>
43#include <asm/mach/irq.h>
44#include <asm/mach/time.h>
45
f0402f9b 46#define IXP4XX_TIMER_FREQ 66666000
fb3174e4
UKK
47
48/*
49 * The timer register doesn't allow to specify the two least significant bits of
50 * the timeout value and assumes them being zero. So make sure IXP4XX_LATCH is
51 * the best value with the two least significant bits unset.
52 */
53#define IXP4XX_LATCH DIV_ROUND_CLOSEST(IXP4XX_TIMER_FREQ, \
54 (IXP4XX_OST_RELOAD_MASK + 1) * HZ) * \
55 (IXP4XX_OST_RELOAD_MASK + 1)
f0402f9b 56
ceb69a89
MP
57static void __init ixp4xx_clocksource_init(void);
58static void __init ixp4xx_clockevent_init(void);
e32f1502 59static struct clock_event_device clockevent_ixp4xx;
f9a8ca1c 60
1da177e4
LT
61/*************************************************************************
62 * IXP4xx chipset I/O mapping
63 *************************************************************************/
64static struct map_desc ixp4xx_io_desc[] __initdata = {
65 { /* UART, Interrupt ctrl, GPIO, timers, NPEs, MACs, USB .... */
13ec32f4 66 .virtual = (unsigned long)IXP4XX_PERIPHERAL_BASE_VIRT,
87fe04bd 67 .pfn = __phys_to_pfn(IXP4XX_PERIPHERAL_BASE_PHYS),
1da177e4
LT
68 .length = IXP4XX_PERIPHERAL_REGION_SIZE,
69 .type = MT_DEVICE
70 }, { /* Expansion Bus Config Registers */
13ec32f4 71 .virtual = (unsigned long)IXP4XX_EXP_CFG_BASE_VIRT,
87fe04bd 72 .pfn = __phys_to_pfn(IXP4XX_EXP_CFG_BASE_PHYS),
1da177e4
LT
73 .length = IXP4XX_EXP_CFG_REGION_SIZE,
74 .type = MT_DEVICE
75 }, { /* PCI Registers */
13ec32f4 76 .virtual = (unsigned long)IXP4XX_PCI_CFG_BASE_VIRT,
87fe04bd 77 .pfn = __phys_to_pfn(IXP4XX_PCI_CFG_BASE_PHYS),
1da177e4
LT
78 .length = IXP4XX_PCI_CFG_REGION_SIZE,
79 .type = MT_DEVICE
f0cdb153
KH
80 }, { /* Queue Manager */
81 .virtual = (unsigned long)IXP4XX_QMGR_BASE_VIRT,
82 .pfn = __phys_to_pfn(IXP4XX_QMGR_BASE_PHYS),
83 .length = IXP4XX_QMGR_REGION_SIZE,
84 .type = MT_DEVICE
5932ae3f 85 },
1da177e4
LT
86};
87
88void __init ixp4xx_map_io(void)
89{
90 iotable_init(ixp4xx_io_desc, ARRAY_SIZE(ixp4xx_io_desc));
91}
92
098e30f6
LW
93/*
94 * GPIO-functions
95 */
96/*
97 * The following converted to the real HW bits the gpio_line_config
98 */
99/* GPIO pin types */
100#define IXP4XX_GPIO_OUT 0x1
101#define IXP4XX_GPIO_IN 0x2
102
103/* GPIO signal types */
104#define IXP4XX_GPIO_LOW 0
105#define IXP4XX_GPIO_HIGH 1
106
107/* GPIO Clocks */
108#define IXP4XX_GPIO_CLK_0 14
109#define IXP4XX_GPIO_CLK_1 15
110
111static void gpio_line_config(u8 line, u32 direction)
112{
113 if (direction == IXP4XX_GPIO_IN)
114 *IXP4XX_GPIO_GPOER |= (1 << line);
115 else
116 *IXP4XX_GPIO_GPOER &= ~(1 << line);
117}
118
119static void gpio_line_get(u8 line, int *value)
120{
121 *value = (*IXP4XX_GPIO_GPINR >> line) & 0x1;
122}
123
124static void gpio_line_set(u8 line, int value)
125{
126 if (value == IXP4XX_GPIO_HIGH)
127 *IXP4XX_GPIO_GPOUTR |= (1 << line);
128 else if (value == IXP4XX_GPIO_LOW)
129 *IXP4XX_GPIO_GPOUTR &= ~(1 << line);
130}
1da177e4
LT
131
132/*************************************************************************
133 * IXP4xx chipset IRQ handling
134 *
135 * TODO: GPIO IRQs should be marked invalid until the user of the IRQ
136 * (be it PCI or something else) configures that GPIO line
137 * as an IRQ.
138 **************************************************************************/
bdf82b59
DS
139enum ixp4xx_irq_type {
140 IXP4XX_IRQ_LEVEL, IXP4XX_IRQ_EDGE
141};
142
984d115b
KH
143/* Each bit represents an IRQ: 1: edge-triggered, 0: level triggered */
144static unsigned long long ixp4xx_irq_edge = 0;
bdf82b59
DS
145
146/*
147 * IRQ -> GPIO mapping table
148 */
6cc1b658 149static signed char irq2gpio[32] = {
bdf82b59
DS
150 -1, -1, -1, -1, -1, -1, 0, 1,
151 -1, -1, -1, -1, -1, -1, -1, -1,
152 -1, -1, -1, 2, 3, 4, 5, 6,
153 7, 8, 9, 10, 11, 12, -1, -1,
154};
155
9dde0ae3 156static int ixp4xx_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
25735d10
MS
157{
158 int irq;
159
160 for (irq = 0; irq < 32; irq++) {
161 if (irq2gpio[irq] == gpio)
162 return irq;
163 }
164 return -EINVAL;
165}
25735d10 166
ee04087a 167static int ixp4xx_set_irq_type(struct irq_data *d, unsigned int type)
bdf82b59 168{
ee04087a 169 int line = irq2gpio[d->irq];
bdf82b59
DS
170 u32 int_style;
171 enum ixp4xx_irq_type irq_type;
172 volatile u32 *int_reg;
173
174 /*
175 * Only for GPIO IRQs
176 */
177 if (line < 0)
178 return -EINVAL;
179