aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/sh
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-12-09 22:03:16 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-12-09 22:03:16 -0500
commit3a43aaa31790c36b69ebf8a6396f37fade86b531 (patch)
tree7c7f8da6219d546f2b44534cb7be1fb5591d6ac4 /drivers/sh
parentaed886ce777590eac87f7ce2897d9f8357754331 (diff)
parent6a5a0b9139b19dd1a107870269a35bc9cf18d2dc (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6: (137 commits) sh: include empty zero page in romImage sh: Make associative cache writes fatal on all SH-4A parts. sh: Drop associative writes for SH-4 cache flushes. sh: Partial revert of copy/clear_user_highpage() optimizations. sh: Add default uImage rule for se7724, ap325rxa, and migor. sh: allow runtime pm without suspend/resume callbacks sh: mach-ecovec24: Remove un-defined settings for VPU sh: mach-ecovec24: LCDC drive ability become high sh: fix sh7724 VEU3F resource size serial: sh-sci: Fix too early port disabling. sh: pfc: pr_info() -> pr_debug() cleanups. sh: pfc: Convert from ctrl_xxx() to __raw_xxx() I/O routines. sh: Improve kfr2r09 serial port setup code sh: Break out SuperH PFC code sh: Move KEYSC header file sh: convert /proc/cpu/aligmnent, /proc/cpu/kernel_alignment to seq_file sh: Add CPG save/restore code for sh7724 R-standby sh: Add SDHI power control support to Ecovec mfd: Add power control platform data to SDHI driver sh: mach-ecovec24: modify address map ...
Diffstat (limited to 'drivers/sh')
-rw-r--r--drivers/sh/Makefile1
-rw-r--r--drivers/sh/intc.c123
-rw-r--r--drivers/sh/maple/maple.c4
-rw-r--r--drivers/sh/pfc.c577
4 files changed, 689 insertions, 16 deletions
diff --git a/drivers/sh/Makefile b/drivers/sh/Makefile
index 6a025cefe6dc..4956bf1f2134 100644
--- a/drivers/sh/Makefile
+++ b/drivers/sh/Makefile
@@ -3,4 +3,5 @@
3# 3#
4obj-$(CONFIG_SUPERHYWAY) += superhyway/ 4obj-$(CONFIG_SUPERHYWAY) += superhyway/
5obj-$(CONFIG_MAPLE) += maple/ 5obj-$(CONFIG_MAPLE) += maple/
6obj-$(CONFIG_GENERIC_GPIO) += pfc.o
6obj-y += intc.o 7obj-y += intc.o
diff --git a/drivers/sh/intc.c b/drivers/sh/intc.c
index 559b5fe9dc0f..a7e5c2e9986c 100644
--- a/drivers/sh/intc.c
+++ b/drivers/sh/intc.c
@@ -2,6 +2,7 @@
2 * Shared interrupt handling code for IPR and INTC2 types of IRQs. 2 * Shared interrupt handling code for IPR and INTC2 types of IRQs.
3 * 3 *
4 * Copyright (C) 2007, 2008 Magnus Damm 4 * Copyright (C) 2007, 2008 Magnus Damm
5 * Copyright (C) 2009 Paul Mundt
5 * 6 *
6 * Based on intc2.c and ipr.c 7 * Based on intc2.c and ipr.c
7 * 8 *
@@ -24,6 +25,7 @@
24#include <linux/sysdev.h> 25#include <linux/sysdev.h>
25#include <linux/list.h> 26#include <linux/list.h>
26#include <linux/topology.h> 27#include <linux/topology.h>
28#include <linux/bitmap.h>
27 29
28#define _INTC_MK(fn, mode, addr_e, addr_d, width, shift) \ 30#define _INTC_MK(fn, mode, addr_e, addr_d, width, shift) \
29 ((shift) | ((width) << 5) | ((fn) << 9) | ((mode) << 13) | \ 31 ((shift) | ((width) << 5) | ((fn) << 9) | ((mode) << 13) | \
@@ -59,6 +61,20 @@ struct intc_desc_int {
59 61
60static LIST_HEAD(intc_list); 62static LIST_HEAD(intc_list);
61 63
64/*
65 * The intc_irq_map provides a global map of bound IRQ vectors for a
66 * given platform. Allocation of IRQs are either static through the CPU
67 * vector map, or dynamic in the case of board mux vectors or MSI.
68 *
69 * As this is a central point for all IRQ controllers on the system,
70 * each of the available sources are mapped out here. This combined with
71 * sparseirq makes it quite trivial to keep the vector map tightly packed
72 * when dynamically creating IRQs, as well as tying in to otherwise
73 * unused irq_desc positions in the sparse array.
74 */
75static DECLARE_BITMAP(intc_irq_map, NR_IRQS);
76static DEFINE_SPINLOCK(vector_lock);
77
62#ifdef CONFIG_SMP 78#ifdef CONFIG_SMP
63#define IS_SMP(x) x.smp 79#define IS_SMP(x) x.smp
64#define INTC_REG(d, x, c) (d->reg[(x)] + ((d->smp[(x)] & 0xff) * c)) 80#define INTC_REG(d, x, c) (d->reg[(x)] + ((d->smp[(x)] & 0xff) * c))
@@ -70,9 +86,7 @@ static LIST_HEAD(intc_list);
70#endif 86#endif
71 87
72static unsigned int intc_prio_level[NR_IRQS]; /* for now */ 88static unsigned int intc_prio_level[NR_IRQS]; /* for now */
73#if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A)
74static unsigned long ack_handle[NR_IRQS]; 89static unsigned long ack_handle[NR_IRQS];
75#endif
76 90
77static inline struct intc_desc_int *get_intc_desc(unsigned int irq) 91static inline struct intc_desc_int *get_intc_desc(unsigned int irq)
78{ 92{
@@ -250,7 +264,6 @@ static int intc_set_wake(unsigned int irq, unsigned int on)
250 return 0; /* allow wakeup, but setup hardware in intc_suspend() */ 264 return 0; /* allow wakeup, but setup hardware in intc_suspend() */
251} 265}
252 266
253#if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A)
254static void intc_mask_ack(unsigned int irq) 267static void intc_mask_ack(unsigned int irq)
255{ 268{
256 struct intc_desc_int *d = get_intc_desc(irq); 269 struct intc_desc_int *d = get_intc_desc(irq);
@@ -282,7 +295,6 @@ static void intc_mask_ack(unsigned int irq)
282 } 295 }
283 } 296 }
284} 297}
285#endif
286 298
287static struct intc_handle_int *intc_find_irq(struct intc_handle_int *hp, 299static struct intc_handle_int *intc_find_irq(struct intc_handle_int *hp,
288 unsigned int nr_hp, 300 unsigned int nr_hp,
@@ -501,7 +513,6 @@ static unsigned int __init intc_prio_data(struct intc_desc *desc,
501 return 0; 513 return 0;
502} 514}
503 515
504#if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A)
505static unsigned int __init intc_ack_data(struct intc_desc *desc, 516static unsigned int __init intc_ack_data(struct intc_desc *desc,
506 struct intc_desc_int *d, 517 struct intc_desc_int *d,
507 intc_enum enum_id) 518 intc_enum enum_id)
@@ -533,7 +544,6 @@ static unsigned int __init intc_ack_data(struct intc_desc *desc,
533 544
534 return 0; 545 return 0;
535} 546}
536#endif
537 547
538static unsigned int __init intc_sense_data(struct intc_desc *desc, 548static unsigned int __init intc_sense_data(struct intc_desc *desc,
539 struct intc_desc_int *d, 549 struct intc_desc_int *d,
@@ -572,6 +582,11 @@ static void __init intc_register_irq(struct intc_desc *desc,
572 struct intc_handle_int *hp; 582 struct intc_handle_int *hp;
573 unsigned int data[2], primary; 583 unsigned int data[2], primary;
574 584
585 /*
586 * Register the IRQ position with the global IRQ map
587 */
588 set_bit(irq, intc_irq_map);
589
575 /* Prefer single interrupt source bitmap over other combinations: 590 /* Prefer single interrupt source bitmap over other combinations:
576 * 1. bitmap, single interrupt source 591 * 1. bitmap, single interrupt source
577 * 2. priority, single interrupt source 592 * 2. priority, single interrupt source
@@ -641,10 +656,8 @@ static void __init intc_register_irq(struct intc_desc *desc,
641 /* irq should be disabled by default */ 656 /* irq should be disabled by default */
642 d->chip.mask(irq); 657 d->chip.mask(irq);
643 658
644#if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A)
645 if (desc->ack_regs) 659 if (desc->ack_regs)
646 ack_handle[irq] = intc_ack_data(desc, d, enum_id); 660 ack_handle[irq] = intc_ack_data(desc, d, enum_id);
647#endif
648} 661}
649 662
650static unsigned int __init save_reg(struct intc_desc_int *d, 663static unsigned int __init save_reg(struct intc_desc_int *d,
@@ -681,10 +694,8 @@ void __init register_intc_controller(struct intc_desc *desc)
681 d->nr_reg = desc->mask_regs ? desc->nr_mask_regs * 2 : 0; 694 d->nr_reg = desc->mask_regs ? desc->nr_mask_regs * 2 : 0;
682 d->nr_reg += desc->prio_regs ? desc->nr_prio_regs * 2 : 0; 695 d->nr_reg += desc->prio_regs ? desc->nr_prio_regs * 2 : 0;
683 d->nr_reg += desc->sense_regs ? desc->nr_sense_regs : 0; 696 d->nr_reg += desc->sense_regs ? desc->nr_sense_regs : 0;
684
685#if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A)
686 d->nr_reg += desc->ack_regs ? desc->nr_ack_regs : 0; 697 d->nr_reg += desc->ack_regs ? desc->nr_ack_regs : 0;
687#endif 698
688 d->reg = kzalloc(d->nr_reg * sizeof(*d->reg), GFP_NOWAIT); 699 d->reg = kzalloc(d->nr_reg * sizeof(*d->reg), GFP_NOWAIT);
689#ifdef CONFIG_SMP 700#ifdef CONFIG_SMP
690 d->smp = kzalloc(d->nr_reg * sizeof(*d->smp), GFP_NOWAIT); 701 d->smp = kzalloc(d->nr_reg * sizeof(*d->smp), GFP_NOWAIT);
@@ -727,14 +738,12 @@ void __init register_intc_controller(struct intc_desc *desc)
727 d->chip.set_type = intc_set_sense; 738 d->chip.set_type = intc_set_sense;
728 d->chip.set_wake = intc_set_wake; 739 d->chip.set_wake = intc_set_wake;
729 740
730#if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A)
731 if (desc->ack_regs) { 741 if (desc->ack_regs) {
732 for (i = 0; i < desc->nr_ack_regs; i++) 742 for (i = 0; i < desc->nr_ack_regs; i++)
733 k += save_reg(d, k, desc->ack_regs[i].set_reg, 0); 743 k += save_reg(d, k, desc->ack_regs[i].set_reg, 0);
734 744
735 d->chip.mask_ack = intc_mask_ack; 745 d->chip.mask_ack = intc_mask_ack;
736 } 746 }
737#endif
738 747
739 BUG_ON(k > 256); /* _INTC_ADDR_E() and _INTC_ADDR_D() are 8 bits */ 748 BUG_ON(k > 256); /* _INTC_ADDR_E() and _INTC_ADDR_D() are 8 bits */
740 749
@@ -856,5 +865,91 @@ static int __init register_intc_sysdevs(void)
856 865
857 return error; 866 return error;
858} 867}
859
860device_initcall(register_intc_sysdevs); 868device_initcall(register_intc_sysdevs);
869
870/*
871 * Dynamic IRQ allocation and deallocation
872 */
873static unsigned int create_irq_on_node(unsigned int irq_want, int node)
874{
875 unsigned int irq = 0, new;
876 unsigned long flags;
877 struct irq_desc *desc;
878
879 spin_lock_irqsave(&vector_lock, flags);
880
881 /*
882 * First try the wanted IRQ, then scan.
883 */
884 if (test_and_set_bit(irq_want, intc_irq_map)) {
885 new = find_first_zero_bit(intc_irq_map, nr_irqs);
886 if (unlikely(new == nr_irqs))
887 goto out_unlock;
888
889 desc = irq_to_desc_alloc_node(new, node);
890 if (unlikely(!desc)) {
891 pr_info("can't get irq_desc for %d\n", new);
892 goto out_unlock;
893 }
894
895 desc = move_irq_desc(desc, node);
896 __set_bit(new, intc_irq_map);
897 irq = new;
898 }
899
900out_unlock:
901 spin_unlock_irqrestore(&vector_lock, flags);
902
903 if (irq > 0)
904 dynamic_irq_init(irq);
905
906 return irq;
907}
908
909int create_irq(void)
910{
911 int nid = cpu_to_node(smp_processor_id());
912 int irq;
913
914 irq = create_irq_on_node(NR_IRQS_LEGACY, nid);
915 if (irq == 0)
916 irq = -1;
917
918 return irq;
919}
920
921void destroy_irq(unsigned int irq)
922{
923 unsigned long flags;
924
925 dynamic_irq_cleanup(irq);
926
927 spin_lock_irqsave(&vector_lock, flags);
928 __clear_bit(irq, intc_irq_map);
929 spin_unlock_irqrestore(&vector_lock, flags);
930}
931
932int reserve_irq_vector(unsigned int irq)
933{
934 unsigned long flags;
935 int ret = 0;
936
937 spin_lock_irqsave(&vector_lock, flags);
938 if (test_and_set_bit(irq, intc_irq_map))
939 ret = -EBUSY;
940 spin_unlock_irqrestore(&vector_lock, flags);
941
942 return ret;
943}
944
945void reserve_irq_legacy(void)
946{
947 unsigned long flags;
948 int i, j;
949
950 spin_lock_irqsave(&vector_lock, flags);
951 j = find_first_bit(intc_irq_map, nr_irqs);
952 for (i = 0; i < j; i++)
953 __set_bit(i, intc_irq_map);
954 spin_unlock_irqrestore(&vector_lock, flags);
955}
diff --git a/drivers/sh/maple/maple.c b/drivers/sh/maple/maple.c
index 93c20e135ee1..4e8f57d4131f 100644
--- a/drivers/sh/maple/maple.c
+++ b/drivers/sh/maple/maple.c
@@ -106,7 +106,7 @@ static void maple_dma_reset(void)
106 * max delay is 11 106 * max delay is 11
107 */ 107 */
108 ctrl_outl(MAPLE_2MBPS | MAPLE_TIMEOUT(0xFFFF), MAPLE_SPEED); 108 ctrl_outl(MAPLE_2MBPS | MAPLE_TIMEOUT(0xFFFF), MAPLE_SPEED);
109 ctrl_outl(PHYSADDR(maple_sendbuf), MAPLE_DMAADDR); 109 ctrl_outl(virt_to_phys(maple_sendbuf), MAPLE_DMAADDR);
110 ctrl_outl(1, MAPLE_ENABLE); 110 ctrl_outl(1, MAPLE_ENABLE);
111} 111}
112 112
@@ -258,7 +258,7 @@ static void maple_build_block(struct mapleq *mq)
258 maple_lastptr = maple_sendptr; 258 maple_lastptr = maple_sendptr;
259 259
260 *maple_sendptr++ = (port << 16) | len | 0x80000000; 260 *maple_sendptr++ = (port << 16) | len | 0x80000000;
261 *maple_sendptr++ = PHYSADDR(mq->recvbuf->buf); 261 *maple_sendptr++ = virt_to_phys(mq->recvbuf->buf);
262 *maple_sendptr++ = 262 *maple_sendptr++ =
263 mq->command | (to << 8) | (from << 16) | (len << 24); 263 mq->command | (to << 8) | (from << 16) | (len << 24);
264 while (len-- > 0) 264 while (len-- > 0)
diff --git a/drivers/sh/pfc.c b/drivers/sh/pfc.c
new file mode 100644
index 000000000000..841ed5030c8f
--- /dev/null
+++ b/drivers/sh/pfc.c
@@ -0,0 +1,577 @@
1/*
2 * Pinmuxed GPIO support for SuperH.
3 *
4 * Copyright (C) 2008 Magnus Damm
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10#include <linux/errno.h>
11#include <linux/kernel.h>
12#include <linux/list.h>
13#include <linux/module.h>
14#include <linux/clk.h>
15#include <linux/err.h>
16#include <linux/io.h>
17#include <linux/irq.h>
18#include <linux/bitops.h>
19#include <linux/gpio.h>
20
21static int enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r)
22{
23 if (enum_id < r->begin)
24 return 0;
25
26 if (enum_id > r->end)
27 return 0;
28
29 return 1;
30}
31
32static unsigned long gpio_read_raw_reg(unsigned long reg,
33 unsigned long reg_width)
34{
35 switch (reg_width) {
36 case 8:
37 return __raw_readb(reg);
38 case 16:
39 return __raw_readw(reg);
40 case 32:
41 return __raw_readl(reg);
42 }
43
44 BUG();
45 return 0;
46}
47
48static void gpio_write_raw_reg(unsigned long reg,
49 unsigned long reg_width,
50 unsigned long data)
51{
52 switch (reg_width) {
53 case 8:
54 __raw_writeb(data, reg);
55 return;
56 case 16:
57 __raw_writew(data, reg);
58 return;
59 case 32:
60 __raw_writel(data, reg);
61 return;
62 }
63
64 BUG();
65}
66
67static void gpio_write_bit(struct pinmux_data_reg *dr,
68 unsigned long in_pos, unsigned long value)
69{
70 unsigned long pos;
71
72 pos = dr->reg_width - (in_pos + 1);
73
74 pr_debug("write_bit addr = %lx, value = %ld, pos = %ld, "
75 "r_width = %ld\n",
76 dr->reg, !!value, pos, dr->reg_width);
77
78 if (value)
79 set_bit(pos, &dr->reg_shadow);
80 else
81 clear_bit(pos, &dr->reg_shadow);
82
83 gpio_write_raw_reg(dr->reg, dr->reg_width, dr->reg_shadow);
84}
85
86static int gpio_read_reg(unsigned long reg, unsigned long reg_width,
87 unsigned long field_width, unsigned long in_pos)
88{
89 unsigned long data, mask, pos;
90
91 data = 0;
92 mask = (1 << field_width) - 1;
93 pos = reg_width - ((in_pos + 1) * field_width);
94
95 pr_debug("read_reg: addr = %lx, pos = %ld, "
96 "r_width = %ld, f_width = %ld\n",
97 reg, pos, reg_width, field_width);
98
99 data = gpio_read_raw_reg(reg, reg_width);
100 return (data >> pos) & mask;
101}
102
103static void gpio_write_reg(unsigned long reg, unsigned long reg_width,
104 unsigned long field_width, unsigned long in_pos,
105 unsigned long value)
106{
107 unsigned long mask, pos;
108
109 mask = (1 << field_width) - 1;
110 pos = reg_width - ((in_pos + 1) * field_width);
111
112 pr_debug("write_reg addr = %lx, value = %ld, pos = %ld, "
113 "r_width = %ld, f_width = %ld\n",
114 reg, value, pos, reg_width, field_width);
115
116 mask = ~(mask << pos);
117 value = value << pos;
118
119 switch (reg_width) {
120 case 8:
121 __raw_writeb((__raw_readb(reg) & mask) | value, reg);
122 break;
123 case 16:
124 __raw_writew((__raw_readw(reg) & mask) | value, reg);
125 break;
126 case 32:
127 __raw_writel((__raw_readl(reg) & mask) | value, reg);
128 break;
129 }
130}
131
132static int setup_data_reg(struct pinmux_info *gpioc, unsigned gpio)
133{
134 struct pinmux_gpio *gpiop = &gpioc->gpios[gpio];
135 struct pinmux_data_reg *data_reg;
136 int k, n;
137
138 if (!enum_in_range(gpiop->enum_id, &gpioc->data))
139 return -1;
140
141 k = 0;
142 while (1) {
143 data_reg = gpioc->data_regs + k;
144
145 if (!data_reg->reg_width)
146 break;
147
148 for (n = 0; n < data_reg->reg_width; n++) {
149 if (data_reg->enum_ids[n] == gpiop->enum_id) {
150 gpiop->flags &= ~PINMUX_FLAG_DREG;
151 gpiop->flags |= (k << PINMUX_FLAG_DREG_SHIFT);
152 gpiop->flags &= ~PINMUX_FLAG_DBIT;
153 gpiop->flags |= (n << PINMUX_FLAG_DBIT_SHIFT);
154 return 0;
155 }
156 }
157 k++;
158 }
159
160 BUG();
161
162 return -1;
163}
164
165static void setup_data_regs(struct pinmux_info *gpioc)
166{
167 struct pinmux_data_reg *drp;
168 int k;
169
170 for (k = gpioc->first_gpio; k <= gpioc->last_gpio; k++)
171 setup_data_reg(gpioc, k);
172
173 k = 0;
174 while (1) {
175 drp = gpioc->data_regs + k;
176
177 if (!drp->reg_width)
178 break;
179
180 drp->reg_shadow = gpio_read_raw_reg(drp->reg, drp->reg_width);
181 k++;
182 }
183}
184
185static int get_data_reg(struct pinmux_info *gpioc, unsigned gpio,
186 struct pinmux_data_reg **drp, int *bitp)
187{
188 struct pinmux_gpio *gpiop = &gpioc->gpios[gpio];
189 int k, n;
190
191 if (!enum_in_range(gpiop->enum_id, &gpioc->data))
192 return -1;
193
194 k = (gpiop->flags & PINMUX_FLAG_DREG) >> PINMUX_FLAG_DREG_SHIFT;
195 n = (gpiop->flags & PINMUX_FLAG_DBIT) >> PINMUX_FLAG_DBIT_SHIFT;
196 *drp = gpioc->data_regs + k;
197 *bitp = n;
198 return 0;
199}
200
201static int get_config_reg(struct pinmux_info *gpioc, pinmux_enum_t enum_id,
202 struct pinmux_cfg_reg **crp, int *indexp,
203 unsigned long **cntp)
204{
205 struct pinmux_cfg_reg *config_reg;
206 unsigned long r_width, f_width;
207 int k, n;
208
209 k = 0;
210 while (1) {
211 config_reg = gpioc->cfg_regs + k;
212
213 r_width = config_reg->reg_width;
214 f_width = config_reg->field_width;
215
216 if (!r_width)
217 break;
218 for (n = 0; n < (r_width / f_width) * 1 << f_width; n++) {
219 if (config_reg->enum_ids[n] == enum_id) {
220 *crp = config_reg;
221 *indexp = n;
222 *cntp = &config_reg->cnt[n / (1 << f_width)];
223 return 0;
224 }
225 }
226 k++;
227 }
228
229 return -1;
230}
231
232static int get_gpio_enum_id(struct pinmux_info *gpioc, unsigned gpio,
233 int pos, pinmux_enum_t *enum_idp)
234{
235 pinmux_enum_t enum_id = gpioc->gpios[gpio].enum_id;
236 pinmux_enum_t *data = gpioc->gpio_data;
237 int k;
238
239 if (!enum_in_range(enum_id, &gpioc->data)) {
240 if (!enum_in_range(enum_id, &gpioc->mark)) {
241 pr_err("non data/mark enum_id for gpio %d\n", gpio);
242 return -1;
243 }
244 }
245
246 if (pos) {
247 *enum_idp = data[pos + 1];
248 return pos + 1;
249 }
250
251 for (k = 0; k < gpioc->gpio_data_size; k++) {
252 if (data[k] == enum_id) {
253 *enum_idp = data[k + 1];
254 return k + 1;
255 }
256 }
257
258 pr_err("cannot locate data/mark enum_id for gpio %d\n", gpio);
259 return -1;
260}
261
262static void write_config_reg(struct pinmux_info *gpioc,
263 struct pinmux_cfg_reg *crp,
264 int index)
265{
266 unsigned long ncomb, pos, value;
267
268 ncomb = 1 << crp->field_width;
269 pos = index / ncomb;
270 value = index % ncomb;
271
272 gpio_write_reg(crp->reg, crp->reg_width, crp->field_width, pos, value);
273}
274
275static int check_config_reg(struct pinmux_info *gpioc,
276 struct pinmux_cfg_reg *crp,
277 int index)
278{
279 unsigned long ncomb, pos, value;
280
281 ncomb = 1 << crp->field_width;
282 pos = index / ncomb;
283 value = index % ncomb;
284
285 if (gpio_read_reg(crp->reg, crp->reg_width,
286 crp->field_width, pos) == value)
287 return 0;
288
289 return -1;
290}
291
292enum { GPIO_CFG_DRYRUN, GPIO_CFG_REQ, GPIO_CFG_FREE };
293
294static int pinmux_config_gpio(struct pinmux_info *gpioc, unsigned gpio,
295 int pinmux_type, int cfg_mode)
296{
297 struct pinmux_cfg_reg *cr = NULL;
298 pinmux_enum_t enum_id;
299 struct pinmux_range *range;
300 int in_range, pos, index;
301 unsigned long *cntp;
302
303 switch (pinmux_type) {
304
305 case PINMUX_TYPE_FUNCTION:
306 range = NULL;
307 break;
308
309 case PINMUX_TYPE_OUTPUT:
310 range = &gpioc->output;
311 break;
312
313 case PINMUX_TYPE_INPUT:
314 range = &gpioc->input;
315 break;
316
317 case PINMUX_TYPE_INPUT_PULLUP:
318 range = &gpioc->input_pu;
319 break;
320
321 case PINMUX_TYPE_INPUT_PULLDOWN:
322 range = &gpioc->input_pd;
323 break;
324
325 default:
326 goto out_err;
327 }
328
329 pos = 0;
330 enum_id = 0;
331 index = 0;
332 while (1) {
333 pos = get_gpio_enum_id(gpioc, gpio, pos, &enum_id);
334 if (pos <= 0)
335 goto out_err;
336
337 if (!enum_id)
338 break;
339
340 in_range = enum_in_range(enum_id, &gpioc->function);
341 if (!in_range && range) {
342 in_range = enum_in_range(enum_id, range);
343
344 if (in_range && enum_id == range->force)
345 continue;
346 }
347
348 if (!in_range)
349 continue;
350
351 if (get_config_reg(gpioc, enum_id, &cr, &index, &cntp) != 0)
352 goto out_err;
353
354 switch (cfg_mode) {
355 case GPIO_CFG_DRYRUN:
356 if (!*cntp || !check_config_reg(gpioc, cr, index))
357 continue;
358 break;
359
360 case GPIO_CFG_REQ:
361 write_config_reg(gpioc, cr, index);
362 *cntp = *cntp + 1;
363 break;
364
365 case GPIO_CFG_FREE:
366 *cntp = *cntp - 1;
367 break;
368 }
369 }
370
371 return 0;
372 out_err:
373 return -1;
374}
375
376static DEFINE_SPINLOCK(gpio_lock);
377
378static struct pinmux_info *chip_to_pinmux(struct gpio_chip *chip)
379{
380 return container_of(chip, struct pinmux_info, chip);
381}
382
383static int sh_gpio_request(struct gpio_chip *chip, unsigned offset)
384{
385 struct pinmux_info *gpioc = chip_to_pinmux(chip);
386 struct pinmux_data_reg *dummy;
387 unsigned long flags;
388 int i, ret, pinmux_type;
389
390 ret = -EINVAL;
391
392 if (!gpioc)
393 goto err_out;
394
395 spin_lock_irqsave(&gpio_lock, flags);
396
397 if ((gpioc->gpios[offset].flags & PINMUX_FLAG_TYPE) != PINMUX_TYPE_NONE)
398 goto err_unlock;
399
400 /* setup pin function here if no data is associated with pin */
401
402 if (get_data_reg(gpioc, offset, &dummy, &i) != 0)
403 pinmux_type = PINMUX_TYPE_FUNCTION;
404 else
405 pinmux_type = PINMUX_TYPE_GPIO;
406
407 if (pinmux_type == PINMUX_TYPE_FUNCTION) {
408 if (pinmux_config_gpio(gpioc, offset,
409 pinmux_type,
410 GPIO_CFG_DRYRUN) != 0)
411 goto err_unlock;
412
413 if (pinmux_config_gpio(gpioc, offset,
414 pinmux_type,
415 GPIO_CFG_REQ) != 0)
416 BUG();
417 }
418
419 gpioc->gpios[offset].flags &= ~PINMUX_FLAG_TYPE;
420 gpioc->gpios[offset].flags |= pinmux_type;
421
422 ret = 0;
423 err_unlock:
424 spin_unlock_irqrestore(&gpio_lock, flags);
425 err_out:
426 return ret;
427}
428
429static void sh_gpio_free(struct gpio_chip *chip, unsigned offset)
430{
431 struct pinmux_info *gpioc = chip_to_pinmux(chip);
432 unsigned long flags;
433 int pinmux_type;
434
435 if (!gpioc)
436 return;
437
438 spin_lock_irqsave(&gpio_lock, flags);
439
440 pinmux_type = gpioc->gpios[offset].flags & PINMUX_FLAG_TYPE;
441 pinmux_config_gpio(gpioc, offset, pinmux_type, GPIO_CFG_FREE);
442 gpioc->gpios[offset].flags &= ~PINMUX_FLAG_TYPE;
443 gpioc->gpios[offset].flags |= PINMUX_TYPE_NONE;
444
445 spin_unlock_irqrestore(&gpio_lock, flags);
446}
447
448static int pinmux_direction(struct pinmux_info *gpioc,
449 unsigned gpio, int new_pinmux_type)
450{
451 int pinmux_type;
452 int ret = -EINVAL;
453
454 if (!gpioc)
455 goto err_out;
456
457 pinmux_type = gpioc->gpios[gpio].flags & PINMUX_FLAG_TYPE;
458
459 switch (pinmux_type) {
460 case PINMUX_TYPE_GPIO:
461 break;
462 case PINMUX_TYPE_OUTPUT:
463 case PINMUX_TYPE_INPUT:
464 case PINMUX_TYPE_INPUT_PULLUP:
465 case PINMUX_TYPE_INPUT_PULLDOWN:
466 pinmux_config_gpio(gpioc, gpio, pinmux_type, GPIO_CFG_FREE);
467 break;
468 default:
469 goto err_out;
470 }
471
472 if (pinmux_config_gpio(gpioc, gpio,
473 new_pinmux_type,
474 GPIO_CFG_DRYRUN) != 0)
475 goto err_out;
476
477 if (pinmux_config_gpio(gpioc, gpio,
478 new_pinmux_type,
479 GPIO_CFG_REQ) != 0)
480 BUG();
481
482 gpioc->gpios[gpio].flags &= ~PINMUX_FLAG_TYPE;
483 gpioc->gpios[gpio].flags |= new_pinmux_type;
484
485 ret = 0;
486 err_out:
487 return ret;
488}
489
490static int sh_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
491{
492 struct pinmux_info *gpioc = chip_to_pinmux(chip);
493 unsigned long flags;
494 int ret;
495
496 spin_lock_irqsave(&gpio_lock, flags);
497 ret = pinmux_direction(gpioc, offset, PINMUX_TYPE_INPUT);
498 spin_unlock_irqrestore(&gpio_lock, flags);
499
500 return ret;
501}
502
503static void sh_gpio_set_value(struct pinmux_info *gpioc,
504 unsigned gpio, int value)
505{
506 struct pinmux_data_reg *dr = NULL;
507 int bit = 0;
508
509 if (!gpioc || get_data_reg(gpioc, gpio, &dr, &bit) != 0)
510 BUG();
511 else
512 gpio_write_bit(dr, bit, value);
513}
514
515static int sh_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
516 int value)
517{
518 struct pinmux_info *gpioc = chip_to_pinmux(chip);
519 unsigned long flags;
520 int ret;
521
522 sh_gpio_set_value(gpioc, offset, value);
523 spin_lock_irqsave(&gpio_lock, flags);
524 ret = pinmux_direction(gpioc, offset, PINMUX_TYPE_OUTPUT);
525 spin_unlock_irqrestore(&gpio_lock, flags);
526
527 return ret;
528}
529
530static int sh_gpio_get_value(struct pinmux_info *gpioc, unsigned gpio)
531{
532 struct pinmux_data_reg *dr = NULL;
533 int bit = 0;
534
535 if (!gpioc || get_data_reg(gpioc, gpio, &dr, &bit) != 0) {
536 BUG();
537 return 0;
538 }
539
540 return gpio_read_reg(dr->reg, dr->reg_width, 1, bit);
541}
542
543static int sh_gpio_get(struct gpio_chip *chip, unsigned offset)
544{
545 return sh_gpio_get_value(chip_to_pinmux(chip), offset);
546}
547
548static void sh_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
549{
550 sh_gpio_set_value(chip_to_pinmux(chip), offset, value);
551}
552
553int register_pinmux(struct pinmux_info *pip)
554{
555 struct gpio_chip *chip = &pip->chip;
556
557 pr_info("sh pinmux: %s handling gpio %d -> %d\n",
558 pip->name, pip->first_gpio, pip->last_gpio);
559
560 setup_data_regs(pip);
561
562 chip->request = sh_gpio_request;
563 chip->free = sh_gpio_free;
564 chip->direction_input = sh_gpio_direction_input;
565 chip->get = sh_gpio_get;
566 chip->direction_output = sh_gpio_direction_output;
567 chip->set = sh_gpio_set;
568
569 WARN_ON(pip->first_gpio != 0); /* needs testing */
570
571 chip->label = pip->name;
572 chip->owner = THIS_MODULE;
573 chip->base = pip->first_gpio;
574 chip->ngpio = (pip->last_gpio - pip->first_gpio) + 1;
575
576 return gpiochip_add(chip);
577}