aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-ns9xxx/gpio.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-ns9xxx/gpio.c')
-rw-r--r--arch/arm/mach-ns9xxx/gpio.c141
1 files changed, 48 insertions, 93 deletions
diff --git a/arch/arm/mach-ns9xxx/gpio.c b/arch/arm/mach-ns9xxx/gpio.c
index 5286e9fc1d3..b3c963b0c8f 100644
--- a/arch/arm/mach-ns9xxx/gpio.c
+++ b/arch/arm/mach-ns9xxx/gpio.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * arch/arm/mach-ns9xxx/gpio.c 2 * arch/arm/mach-ns9xxx/gpio.c
3 * 3 *
4 * Copyright (C) 2006 by Digi International Inc. 4 * Copyright (C) 2006,2007 by Digi International Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify it
@@ -15,12 +15,13 @@
15 15
16#include <asm/arch-ns9xxx/gpio.h> 16#include <asm/arch-ns9xxx/gpio.h>
17#include <asm/arch-ns9xxx/processor.h> 17#include <asm/arch-ns9xxx/processor.h>
18#include <asm/arch-ns9xxx/regs-bbu.h> 18#include <asm/arch-ns9xxx/processor-ns9360.h>
19#include <asm/io.h>
20#include <asm/bug.h> 19#include <asm/bug.h>
21#include <asm/types.h> 20#include <asm/types.h>
22#include <asm/bitops.h> 21#include <asm/bitops.h>
23 22
23#include "gpio-ns9360.h"
24
24#if defined(CONFIG_PROCESSOR_NS9360) 25#if defined(CONFIG_PROCESSOR_NS9360)
25#define GPIO_MAX 72 26#define GPIO_MAX 72
26#elif defined(CONFIG_PROCESSOR_NS9750) 27#elif defined(CONFIG_PROCESSOR_NS9750)
@@ -45,41 +46,10 @@ static inline int ns9xxx_valid_gpio(unsigned gpio)
45 return gpio <= 49; 46 return gpio <= 49;
46 else 47 else
47#endif 48#endif
49 {
48 BUG(); 50 BUG();
49} 51 return 0;
50 52 }
51static inline void __iomem *ns9xxx_gpio_get_gconfaddr(unsigned gpio)
52{
53 if (gpio < 56)
54 return BBU_GCONFb1(gpio / 8);
55 else
56 /*
57 * this could be optimised away on
58 * ns9750 only builds, but it isn't ...
59 */
60 return BBU_GCONFb2((gpio - 56) / 8);
61}
62
63static inline void __iomem *ns9xxx_gpio_get_gctrladdr(unsigned gpio)
64{
65 if (gpio < 32)
66 return BBU_GCTRL1;
67 else if (gpio < 64)
68 return BBU_GCTRL2;
69 else
70 /* this could be optimised away on ns9750 only builds */
71 return BBU_GCTRL3;
72}
73
74static inline void __iomem *ns9xxx_gpio_get_gstataddr(unsigned gpio)
75{
76 if (gpio < 32)
77 return BBU_GSTAT1;
78 else if (gpio < 64)
79 return BBU_GSTAT2;
80 else
81 /* this could be optimised away on ns9750 only builds */
82 return BBU_GSTAT3;
83} 53}
84 54
85int gpio_request(unsigned gpio, const char *label) 55int gpio_request(unsigned gpio, const char *label)
@@ -98,49 +68,24 @@ void gpio_free(unsigned gpio)
98} 68}
99EXPORT_SYMBOL(gpio_free); 69EXPORT_SYMBOL(gpio_free);
100 70
101/* 71int gpio_direction_input(unsigned gpio)
102 * each gpio can serve for 4 different purposes [0..3]. These are called
103 * "functions" and passed in the parameter func. Functions 0-2 are always some
104 * special things, function 3 is GPIO. If func == 3 dir specifies input or
105 * output, and with inv you can enable an inverter (independent of func).
106 */
107static int __ns9xxx_gpio_configure(unsigned gpio, int dir, int inv, int func)
108{ 72{
109 void __iomem *conf = ns9xxx_gpio_get_gconfaddr(gpio); 73 if (likely(ns9xxx_valid_gpio(gpio))) {
110 u32 confval; 74 int ret = -EINVAL;
111 unsigned long flags; 75 unsigned long flags;
112
113 spin_lock_irqsave(&gpio_lock, flags);
114
115 confval = __raw_readl(conf);
116 REGSETIM_IDX(confval, BBU_GCONFx, DIR, gpio & 7, dir);
117 REGSETIM_IDX(confval, BBU_GCONFx, INV, gpio & 7, inv);
118 REGSETIM_IDX(confval, BBU_GCONFx, FUNC, gpio & 7, func);
119 __raw_writel(confval, conf);
120 76
121 spin_unlock_irqrestore(&gpio_lock, flags); 77 spin_lock_irqsave(&gpio_lock, flags);
78#if defined(CONFIG_PROCESSOR_NS9360)
79 if (processor_is_ns9360())
80 ret = __ns9360_gpio_configure(gpio, 0, 0, 3);
81 else
82#endif
83 BUG();
122 84
123 return 0; 85 spin_unlock_irqrestore(&gpio_lock, flags);
124}
125 86
126int ns9xxx_gpio_configure(unsigned gpio, int inv, int func) 87 return ret;
127{
128 if (likely(ns9xxx_valid_gpio(gpio))) {
129 if (func == 3) {
130 printk(KERN_WARNING "use gpio_direction_input "
131 "or gpio_direction_output\n");
132 return -EINVAL;
133 } else
134 return __ns9xxx_gpio_configure(gpio, 0, inv, func);
135 } else
136 return -EINVAL;
137}
138EXPORT_SYMBOL(ns9xxx_gpio_configure);
139 88
140int gpio_direction_input(unsigned gpio)
141{
142 if (likely(ns9xxx_valid_gpio(gpio))) {
143 return __ns9xxx_gpio_configure(gpio, 0, 0, 3);
144 } else 89 } else
145 return -EINVAL; 90 return -EINVAL;
146} 91}
@@ -149,9 +94,22 @@ EXPORT_SYMBOL(gpio_direction_input);
149int gpio_direction_output(unsigned gpio, int value) 94int gpio_direction_output(unsigned gpio, int value)
150{ 95{
151 if (likely(ns9xxx_valid_gpio(gpio))) { 96 if (likely(ns9xxx_valid_gpio(gpio))) {
97 int ret = -EINVAL;
98 unsigned long flags;
99
152 gpio_set_value(gpio, value); 100 gpio_set_value(gpio, value);
153 101
154 return __ns9xxx_gpio_configure(gpio, 1, 0, 3); 102 spin_lock_irqsave(&gpio_lock, flags);
103#if defined(CONFIG_PROCESSOR_NS9360)
104 if (processor_is_ns9360())
105 ret = __ns9360_gpio_configure(gpio, 1, 0, 3);
106 else
107#endif
108 BUG();
109
110 spin_unlock_irqrestore(&gpio_lock, flags);
111
112 return ret;
155 } else 113 } else
156 return -EINVAL; 114 return -EINVAL;
157} 115}
@@ -159,31 +117,28 @@ EXPORT_SYMBOL(gpio_direction_output);
159 117
160int gpio_get_value(unsigned gpio) 118int gpio_get_value(unsigned gpio)
161{ 119{
162 void __iomem *stat = ns9xxx_gpio_get_gstataddr(gpio); 120#if defined(CONFIG_PROCESSOR_NS9360)
163 int ret; 121 if (processor_is_ns9360())
164 122 return ns9360_gpio_get_value(gpio);
165 ret = 1 & (__raw_readl(stat) >> (gpio & 31)); 123 else
166 124#endif
167 return ret; 125 {
126 BUG();
127 return -EINVAL;
128 }
168} 129}
169EXPORT_SYMBOL(gpio_get_value); 130EXPORT_SYMBOL(gpio_get_value);
170 131
171void gpio_set_value(unsigned gpio, int value) 132void gpio_set_value(unsigned gpio, int value)
172{ 133{
173 void __iomem *ctrl = ns9xxx_gpio_get_gctrladdr(gpio);
174 u32 ctrlval;
175 unsigned long flags; 134 unsigned long flags;
176
177 spin_lock_irqsave(&gpio_lock, flags); 135 spin_lock_irqsave(&gpio_lock, flags);
178 136#if defined(CONFIG_PROCESSOR_NS9360)
179 ctrlval = __raw_readl(ctrl); 137 if (processor_is_ns9360())
180 138 ns9360_gpio_set_value(gpio, value);
181 if (value)
182 ctrlval |= 1 << (gpio & 31);
183 else 139 else
184 ctrlval &= ~(1 << (gpio & 31)); 140#endif
185 141 BUG();
186 __raw_writel(ctrlval, ctrl);
187 142
188 spin_unlock_irqrestore(&gpio_lock, flags); 143 spin_unlock_irqrestore(&gpio_lock, flags);
189} 144}