Blame view

drivers/sh/pfc.c 15.7 KB
2967dab1a   Magnus Damm   sh: GPIO and pinm...
1
2
3
4
5
6
7
8
9
  /*
   * Pinmuxed GPIO support for SuperH.
   *
   * Copyright (C) 2008 Magnus Damm
   *
   * This file is subject to the terms and conditions of the GNU General Public
   * License.  See the file "COPYING" in the main directory of this archive
   * for more details.
   */
b72421d8a   Paul Mundt   sh: pfc: support ...
10
  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
2967dab1a   Magnus Damm   sh: GPIO and pinm...
11
12
13
14
15
16
17
18
19
20
  #include <linux/errno.h>
  #include <linux/kernel.h>
  #include <linux/list.h>
  #include <linux/module.h>
  #include <linux/clk.h>
  #include <linux/err.h>
  #include <linux/io.h>
  #include <linux/irq.h>
  #include <linux/bitops.h>
  #include <linux/gpio.h>
b0e10211c   Magnus Damm   sh: pfc: ioremap(...
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
  #include <linux/slab.h>
  #include <linux/ioport.h>
  
  static void pfc_iounmap(struct pinmux_info *pip)
  {
  	int k;
  
  	for (k = 0; k < pip->num_resources; k++)
  		if (pip->window[k].virt)
  			iounmap(pip->window[k].virt);
  
  	kfree(pip->window);
  	pip->window = NULL;
  }
  
  static int pfc_ioremap(struct pinmux_info *pip)
  {
  	struct resource *res;
  	int k;
  
  	if (!pip->num_resources)
  		return 0;
  
  	pip->window = kzalloc(pip->num_resources * sizeof(*pip->window),
  			      GFP_NOWAIT);
  	if (!pip->window)
  		goto err1;
  
  	for (k = 0; k < pip->num_resources; k++) {
  		res = pip->resource + k;
  		WARN_ON(resource_type(res) != IORESOURCE_MEM);
  		pip->window[k].phys = res->start;
  		pip->window[k].size = resource_size(res);
  		pip->window[k].virt = ioremap_nocache(res->start,
  							 resource_size(res));
  		if (!pip->window[k].virt)
  			goto err2;
  	}
  
  	return 0;
  
  err2:
  	pfc_iounmap(pip);
  err1:
  	return -1;
  }
  
  static void __iomem *pfc_phys_to_virt(struct pinmux_info *pip,
  				      unsigned long address)
  {
  	struct pfc_window *window;
  	int k;
  
  	/* scan through physical windows and convert address */
  	for (k = 0; k < pip->num_resources; k++) {
  		window = pip->window + k;
  
  		if (address < window->phys)
  			continue;
  
  		if (address >= (window->phys + window->size))
  			continue;
  
  		return window->virt + (address - window->phys);
  	}
  
  	/* no windows defined, register must be 1:1 mapped virt:phys */
  	return (void __iomem *)address;
  }
2967dab1a   Magnus Damm   sh: GPIO and pinm...
90

2967dab1a   Magnus Damm   sh: GPIO and pinm...
91
92
93
94
95
96
97
98
99
100
  static int enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r)
  {
  	if (enum_id < r->begin)
  		return 0;
  
  	if (enum_id > r->end)
  		return 0;
  
  	return 1;
  }
b0e10211c   Magnus Damm   sh: pfc: ioremap(...
101
  static unsigned long gpio_read_raw_reg(void __iomem *mapped_reg,
3292094e8   Magnus Damm   sh: lockless gpio...
102
103
104
105
  				       unsigned long reg_width)
  {
  	switch (reg_width) {
  	case 8:
b0e10211c   Magnus Damm   sh: pfc: ioremap(...
106
  		return ioread8(mapped_reg);
3292094e8   Magnus Damm   sh: lockless gpio...
107
  	case 16:
b0e10211c   Magnus Damm   sh: pfc: ioremap(...
108
  		return ioread16(mapped_reg);
3292094e8   Magnus Damm   sh: lockless gpio...
109
  	case 32:
b0e10211c   Magnus Damm   sh: pfc: ioremap(...
110
  		return ioread32(mapped_reg);
3292094e8   Magnus Damm   sh: lockless gpio...
111
112
113
114
115
  	}
  
  	BUG();
  	return 0;
  }
b0e10211c   Magnus Damm   sh: pfc: ioremap(...
116
  static void gpio_write_raw_reg(void __iomem *mapped_reg,
3292094e8   Magnus Damm   sh: lockless gpio...
117
118
119
120
121
  			       unsigned long reg_width,
  			       unsigned long data)
  {
  	switch (reg_width) {
  	case 8:
b0e10211c   Magnus Damm   sh: pfc: ioremap(...
122
  		iowrite8(data, mapped_reg);
3292094e8   Magnus Damm   sh: lockless gpio...
123
124
  		return;
  	case 16:
b0e10211c   Magnus Damm   sh: pfc: ioremap(...
125
  		iowrite16(data, mapped_reg);
3292094e8   Magnus Damm   sh: lockless gpio...
126
127
  		return;
  	case 32:
b0e10211c   Magnus Damm   sh: pfc: ioremap(...
128
  		iowrite32(data, mapped_reg);
3292094e8   Magnus Damm   sh: lockless gpio...
129
130
131
132
133
  		return;
  	}
  
  	BUG();
  }
92554d97c   Magnus Damm   sh: pfc: Add gpio...
134
135
136
137
138
139
140
141
142
143
144
145
146
  static int gpio_read_bit(struct pinmux_data_reg *dr,
  			 unsigned long in_pos)
  {
  	unsigned long pos;
  
  	pos = dr->reg_width - (in_pos + 1);
  
  	pr_debug("read_bit: addr = %lx, pos = %ld, "
  		 "r_width = %ld
  ", dr->reg, pos, dr->reg_width);
  
  	return (gpio_read_raw_reg(dr->mapped_reg, dr->reg_width) >> pos) & 1;
  }
3292094e8   Magnus Damm   sh: lockless gpio...
147
148
149
150
151
152
  static void gpio_write_bit(struct pinmux_data_reg *dr,
  			   unsigned long in_pos, unsigned long value)
  {
  	unsigned long pos;
  
  	pos = dr->reg_width - (in_pos + 1);
ca6f2d7fa   Paul Mundt   sh: pfc: Fixup ty...
153
  	pr_debug("write_bit addr = %lx, value = %d, pos = %ld, "
fd2cb0ce7   Paul Mundt   sh: pfc: pr_info(...
154
155
156
  		 "r_width = %ld
  ",
  		 dr->reg, !!value, pos, dr->reg_width);
3292094e8   Magnus Damm   sh: lockless gpio...
157
158
159
160
161
  
  	if (value)
  		set_bit(pos, &dr->reg_shadow);
  	else
  		clear_bit(pos, &dr->reg_shadow);
b0e10211c   Magnus Damm   sh: pfc: ioremap(...
162
  	gpio_write_raw_reg(dr->mapped_reg, dr->reg_width, dr->reg_shadow);
3292094e8   Magnus Damm   sh: lockless gpio...
163
  }
18925e118   Magnus Damm   sh: pfc: Add conf...
164
165
166
167
168
169
  static void config_reg_helper(struct pinmux_info *gpioc,
  			      struct pinmux_cfg_reg *crp,
  			      unsigned long in_pos,
  			      void __iomem **mapped_regp,
  			      unsigned long *maskp,
  			      unsigned long *posp)
2967dab1a   Magnus Damm   sh: GPIO and pinm...
170
  {
f78a26f55   Magnus Damm   sh: pfc: Variable...
171
  	int k;
18925e118   Magnus Damm   sh: pfc: Add conf...
172
  	*mapped_regp = pfc_phys_to_virt(gpioc, crp->reg);
2967dab1a   Magnus Damm   sh: GPIO and pinm...
173

f78a26f55   Magnus Damm   sh: pfc: Variable...
174
175
176
177
178
179
180
181
182
  	if (crp->field_width) {
  		*maskp = (1 << crp->field_width) - 1;
  		*posp = crp->reg_width - ((in_pos + 1) * crp->field_width);
  	} else {
  		*maskp = (1 << crp->var_field_width[in_pos]) - 1;
  		*posp = crp->reg_width;
  		for (k = 0; k <= in_pos; k++)
  			*posp -= crp->var_field_width[k];
  	}
18925e118   Magnus Damm   sh: pfc: Add conf...
183
184
185
186
187
188
189
190
191
192
  }
  
  static int read_config_reg(struct pinmux_info *gpioc,
  			   struct pinmux_cfg_reg *crp,
  			   unsigned long field)
  {
  	void __iomem *mapped_reg;
  	unsigned long mask, pos;
  
  	config_reg_helper(gpioc, crp, field, &mapped_reg, &mask, &pos);
2967dab1a   Magnus Damm   sh: GPIO and pinm...
193

18925e118   Magnus Damm   sh: pfc: Add conf...
194
  	pr_debug("read_reg: addr = %lx, field = %ld, "
fd2cb0ce7   Paul Mundt   sh: pfc: pr_info(...
195
196
  		 "r_width = %ld, f_width = %ld
  ",
18925e118   Magnus Damm   sh: pfc: Add conf...
197
  		 crp->reg, field, crp->reg_width, crp->field_width);
2967dab1a   Magnus Damm   sh: GPIO and pinm...
198

18925e118   Magnus Damm   sh: pfc: Add conf...
199
  	return (gpio_read_raw_reg(mapped_reg, crp->reg_width) >> pos) & mask;
0fc64cc0a   Magnus Damm   sh: lockless gpio...
200
  }
18925e118   Magnus Damm   sh: pfc: Add conf...
201
202
203
  static void write_config_reg(struct pinmux_info *gpioc,
  			     struct pinmux_cfg_reg *crp,
  			     unsigned long field, unsigned long value)
0fc64cc0a   Magnus Damm   sh: lockless gpio...
204
  {
18925e118   Magnus Damm   sh: pfc: Add conf...
205
  	void __iomem *mapped_reg;
e499ada82   Magnus Damm   sh: pfc: Unlock r...
206
  	unsigned long mask, pos, data;
0fc64cc0a   Magnus Damm   sh: lockless gpio...
207

18925e118   Magnus Damm   sh: pfc: Add conf...
208
  	config_reg_helper(gpioc, crp, field, &mapped_reg, &mask, &pos);
2967dab1a   Magnus Damm   sh: GPIO and pinm...
209

18925e118   Magnus Damm   sh: pfc: Add conf...
210
  	pr_debug("write_reg addr = %lx, value = %ld, field = %ld, "
fd2cb0ce7   Paul Mundt   sh: pfc: pr_info(...
211
212
  		 "r_width = %ld, f_width = %ld
  ",
18925e118   Magnus Damm   sh: pfc: Add conf...
213
  		 crp->reg, value, field, crp->reg_width, crp->field_width);
0fc64cc0a   Magnus Damm   sh: lockless gpio...
214
215
216
  
  	mask = ~(mask << pos);
  	value = value << pos;
2967dab1a   Magnus Damm   sh: GPIO and pinm...
217

e499ada82   Magnus Damm   sh: pfc: Unlock r...
218
219
220
221
222
223
224
225
226
  	data = gpio_read_raw_reg(mapped_reg, crp->reg_width);
  	data &= mask;
  	data |= value;
  
  	if (gpioc->unlock_reg)
  		gpio_write_raw_reg(pfc_phys_to_virt(gpioc, gpioc->unlock_reg),
  				   32, ~data);
  
  	gpio_write_raw_reg(mapped_reg, crp->reg_width, data);
2967dab1a   Magnus Damm   sh: GPIO and pinm...
227
  }
18801be7f   Magnus Damm   sh: make gpio_get...
228
  static int setup_data_reg(struct pinmux_info *gpioc, unsigned gpio)
2967dab1a   Magnus Damm   sh: GPIO and pinm...
229
  {
18801be7f   Magnus Damm   sh: make gpio_get...
230
  	struct pinmux_gpio *gpiop = &gpioc->gpios[gpio];
2967dab1a   Magnus Damm   sh: GPIO and pinm...
231
232
  	struct pinmux_data_reg *data_reg;
  	int k, n;
18801be7f   Magnus Damm   sh: make gpio_get...
233
  	if (!enum_in_range(gpiop->enum_id, &gpioc->data))
2967dab1a   Magnus Damm   sh: GPIO and pinm...
234
235
236
237
238
239
240
241
  		return -1;
  
  	k = 0;
  	while (1) {
  		data_reg = gpioc->data_regs + k;
  
  		if (!data_reg->reg_width)
  			break;
b0e10211c   Magnus Damm   sh: pfc: ioremap(...
242
  		data_reg->mapped_reg = pfc_phys_to_virt(gpioc, data_reg->reg);
2967dab1a   Magnus Damm   sh: GPIO and pinm...
243
  		for (n = 0; n < data_reg->reg_width; n++) {
18801be7f   Magnus Damm   sh: make gpio_get...
244
245
246
247
248
  			if (data_reg->enum_ids[n] == gpiop->enum_id) {
  				gpiop->flags &= ~PINMUX_FLAG_DREG;
  				gpiop->flags |= (k << PINMUX_FLAG_DREG_SHIFT);
  				gpiop->flags &= ~PINMUX_FLAG_DBIT;
  				gpiop->flags |= (n << PINMUX_FLAG_DBIT_SHIFT);
2967dab1a   Magnus Damm   sh: GPIO and pinm...
249
  				return 0;
2967dab1a   Magnus Damm   sh: GPIO and pinm...
250
251
252
253
  			}
  		}
  		k++;
  	}
18801be7f   Magnus Damm   sh: make gpio_get...
254
  	BUG();
2967dab1a   Magnus Damm   sh: GPIO and pinm...
255
256
  	return -1;
  }
3292094e8   Magnus Damm   sh: lockless gpio...
257
258
259
260
261
262
263
264
265
266
267
268
269
270
  static void setup_data_regs(struct pinmux_info *gpioc)
  {
  	struct pinmux_data_reg *drp;
  	int k;
  
  	for (k = gpioc->first_gpio; k <= gpioc->last_gpio; k++)
  		setup_data_reg(gpioc, k);
  
  	k = 0;
  	while (1) {
  		drp = gpioc->data_regs + k;
  
  		if (!drp->reg_width)
  			break;
b0e10211c   Magnus Damm   sh: pfc: ioremap(...
271
272
  		drp->reg_shadow = gpio_read_raw_reg(drp->mapped_reg,
  						    drp->reg_width);
3292094e8   Magnus Damm   sh: lockless gpio...
273
274
275
  		k++;
  	}
  }
18801be7f   Magnus Damm   sh: make gpio_get...
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
  static int get_data_reg(struct pinmux_info *gpioc, unsigned gpio,
  			struct pinmux_data_reg **drp, int *bitp)
  {
  	struct pinmux_gpio *gpiop = &gpioc->gpios[gpio];
  	int k, n;
  
  	if (!enum_in_range(gpiop->enum_id, &gpioc->data))
  		return -1;
  
  	k = (gpiop->flags & PINMUX_FLAG_DREG) >> PINMUX_FLAG_DREG_SHIFT;
  	n = (gpiop->flags & PINMUX_FLAG_DBIT) >> PINMUX_FLAG_DBIT_SHIFT;
  	*drp = gpioc->data_regs + k;
  	*bitp = n;
  	return 0;
  }
2967dab1a   Magnus Damm   sh: GPIO and pinm...
291
  static int get_config_reg(struct pinmux_info *gpioc, pinmux_enum_t enum_id,
ad4a07ff8   Magnus Damm   sh: pfc: Convert ...
292
293
  			  struct pinmux_cfg_reg **crp,
  			  int *fieldp, int *valuep,
2967dab1a   Magnus Damm   sh: GPIO and pinm...
294
295
296
  			  unsigned long **cntp)
  {
  	struct pinmux_cfg_reg *config_reg;
f78a26f55   Magnus Damm   sh: pfc: Variable...
297
298
  	unsigned long r_width, f_width, curr_width, ncomb;
  	int k, m, n, pos, bit_pos;
2967dab1a   Magnus Damm   sh: GPIO and pinm...
299
300
301
302
303
304
305
306
307
308
  
  	k = 0;
  	while (1) {
  		config_reg = gpioc->cfg_regs + k;
  
  		r_width = config_reg->reg_width;
  		f_width = config_reg->field_width;
  
  		if (!r_width)
  			break;
f78a26f55   Magnus Damm   sh: pfc: Variable...
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
  
  		pos = 0;
  		m = 0;
  		for (bit_pos = 0; bit_pos < r_width; bit_pos += curr_width) {
  			if (f_width)
  				curr_width = f_width;
  			else
  				curr_width = config_reg->var_field_width[m];
  
  			ncomb = 1 << curr_width;
  			for (n = 0; n < ncomb; n++) {
  				if (config_reg->enum_ids[pos + n] == enum_id) {
  					*crp = config_reg;
  					*fieldp = m;
  					*valuep = n;
  					*cntp = &config_reg->cnt[m];
  					return 0;
  				}
2967dab1a   Magnus Damm   sh: GPIO and pinm...
327
  			}
f78a26f55   Magnus Damm   sh: pfc: Variable...
328
329
  			pos += ncomb;
  			m++;
2967dab1a   Magnus Damm   sh: GPIO and pinm...
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
  		}
  		k++;
  	}
  
  	return -1;
  }
  
  static int get_gpio_enum_id(struct pinmux_info *gpioc, unsigned gpio,
  			    int pos, pinmux_enum_t *enum_idp)
  {
  	pinmux_enum_t enum_id = gpioc->gpios[gpio].enum_id;
  	pinmux_enum_t *data = gpioc->gpio_data;
  	int k;
  
  	if (!enum_in_range(enum_id, &gpioc->data)) {
  		if (!enum_in_range(enum_id, &gpioc->mark)) {
  			pr_err("non data/mark enum_id for gpio %d
  ", gpio);
  			return -1;
  		}
  	}
  
  	if (pos) {
  		*enum_idp = data[pos + 1];
  		return pos + 1;
  	}
  
  	for (k = 0; k < gpioc->gpio_data_size; k++) {
  		if (data[k] == enum_id) {
  			*enum_idp = data[k + 1];
  			return k + 1;
  		}
  	}
  
  	pr_err("cannot locate data/mark enum_id for gpio %d
  ", gpio);
  	return -1;
  }
2967dab1a   Magnus Damm   sh: GPIO and pinm...
368
  enum { GPIO_CFG_DRYRUN, GPIO_CFG_REQ, GPIO_CFG_FREE };
0fc64cc0a   Magnus Damm   sh: lockless gpio...
369
370
  static int pinmux_config_gpio(struct pinmux_info *gpioc, unsigned gpio,
  			      int pinmux_type, int cfg_mode)
2967dab1a   Magnus Damm   sh: GPIO and pinm...
371
372
373
374
  {
  	struct pinmux_cfg_reg *cr = NULL;
  	pinmux_enum_t enum_id;
  	struct pinmux_range *range;
ad4a07ff8   Magnus Damm   sh: pfc: Convert ...
375
  	int in_range, pos, field, value;
2967dab1a   Magnus Damm   sh: GPIO and pinm...
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
  	unsigned long *cntp;
  
  	switch (pinmux_type) {
  
  	case PINMUX_TYPE_FUNCTION:
  		range = NULL;
  		break;
  
  	case PINMUX_TYPE_OUTPUT:
  		range = &gpioc->output;
  		break;
  
  	case PINMUX_TYPE_INPUT:
  		range = &gpioc->input;
  		break;
  
  	case PINMUX_TYPE_INPUT_PULLUP:
  		range = &gpioc->input_pu;
  		break;
  
  	case PINMUX_TYPE_INPUT_PULLDOWN:
  		range = &gpioc->input_pd;
  		break;
  
  	default:
  		goto out_err;
  	}
  
  	pos = 0;
  	enum_id = 0;
ad4a07ff8   Magnus Damm   sh: pfc: Convert ...
406
407
  	field = 0;
  	value = 0;
2967dab1a   Magnus Damm   sh: GPIO and pinm...
408
409
410
411
412
413
414
  	while (1) {
  		pos = get_gpio_enum_id(gpioc, gpio, pos, &enum_id);
  		if (pos <= 0)
  			goto out_err;
  
  		if (!enum_id)
  			break;
50dd3145a   Magnus Damm   sh: update PFC to...
415
  		/* first check if this is a function enum */
2967dab1a   Magnus Damm   sh: GPIO and pinm...
416
  		in_range = enum_in_range(enum_id, &gpioc->function);
50dd3145a   Magnus Damm   sh: update PFC to...
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
  		if (!in_range) {
  			/* not a function enum */
  			if (range) {
  				/*
  				 * other range exists, so this pin is
  				 * a regular GPIO pin that now is being
  				 * bound to a specific direction.
  				 *
  				 * for this case we only allow function enums
  				 * and the enums that match the other range.
  				 */
  				in_range = enum_in_range(enum_id, range);
  
  				/*
  				 * special case pass through for fixed
  				 * input-only or output-only pins without
  				 * function enum register association.
  				 */
  				if (in_range && enum_id == range->force)
  					continue;
  			} else {
  				/*
  				 * no other range exists, so this pin
  				 * must then be of the function type.
  				 *
  				 * allow function type pins to select
  				 * any combination of function/in/out
  				 * in their MARK lists.
  				 */
  				in_range = 1;
  			}
42eed42ba   Magnus Damm   sh: improve pinmu...
448
  		}
2967dab1a   Magnus Damm   sh: GPIO and pinm...
449
450
  		if (!in_range)
  			continue;
ad4a07ff8   Magnus Damm   sh: pfc: Convert ...
451
452
  		if (get_config_reg(gpioc, enum_id, &cr,
  				   &field, &value, &cntp) != 0)
2967dab1a   Magnus Damm   sh: GPIO and pinm...
453
454
455
456
  			goto out_err;
  
  		switch (cfg_mode) {
  		case GPIO_CFG_DRYRUN:
18925e118   Magnus Damm   sh: pfc: Add conf...
457
458
  			if (!*cntp ||
  			    (read_config_reg(gpioc, cr, field) != value))
2967dab1a   Magnus Damm   sh: GPIO and pinm...
459
460
461
462
  				continue;
  			break;
  
  		case GPIO_CFG_REQ:
ad4a07ff8   Magnus Damm   sh: pfc: Convert ...
463
  			write_config_reg(gpioc, cr, field, value);
2967dab1a   Magnus Damm   sh: GPIO and pinm...
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
  			*cntp = *cntp + 1;
  			break;
  
  		case GPIO_CFG_FREE:
  			*cntp = *cntp - 1;
  			break;
  		}
  	}
  
  	return 0;
   out_err:
  	return -1;
  }
  
  static DEFINE_SPINLOCK(gpio_lock);
69edbba00   Magnus Damm   sh: use gpiolib
479
  static struct pinmux_info *chip_to_pinmux(struct gpio_chip *chip)
2967dab1a   Magnus Damm   sh: GPIO and pinm...
480
  {
69edbba00   Magnus Damm   sh: use gpiolib
481
482
483
484
485
486
  	return container_of(chip, struct pinmux_info, chip);
  }
  
  static int sh_gpio_request(struct gpio_chip *chip, unsigned offset)
  {
  	struct pinmux_info *gpioc = chip_to_pinmux(chip);
2967dab1a   Magnus Damm   sh: GPIO and pinm...
487
488
489
490
491
492
493
494
495
496
  	struct pinmux_data_reg *dummy;
  	unsigned long flags;
  	int i, ret, pinmux_type;
  
  	ret = -EINVAL;
  
  	if (!gpioc)
  		goto err_out;
  
  	spin_lock_irqsave(&gpio_lock, flags);
69edbba00   Magnus Damm   sh: use gpiolib
497
  	if ((gpioc->gpios[offset].flags & PINMUX_FLAG_TYPE) != PINMUX_TYPE_NONE)
2967dab1a   Magnus Damm   sh: GPIO and pinm...
498
499
500
  		goto err_unlock;
  
  	/* setup pin function here if no data is associated with pin */
69edbba00   Magnus Damm   sh: use gpiolib
501
  	if (get_data_reg(gpioc, offset, &dummy, &i) != 0)
2967dab1a   Magnus Damm   sh: GPIO and pinm...
502
503
504
505
506
  		pinmux_type = PINMUX_TYPE_FUNCTION;
  	else
  		pinmux_type = PINMUX_TYPE_GPIO;
  
  	if (pinmux_type == PINMUX_TYPE_FUNCTION) {
69edbba00   Magnus Damm   sh: use gpiolib
507
  		if (pinmux_config_gpio(gpioc, offset,
2967dab1a   Magnus Damm   sh: GPIO and pinm...
508
509
510
  				       pinmux_type,
  				       GPIO_CFG_DRYRUN) != 0)
  			goto err_unlock;
69edbba00   Magnus Damm   sh: use gpiolib
511
  		if (pinmux_config_gpio(gpioc, offset,
2967dab1a   Magnus Damm   sh: GPIO and pinm...
512
513
514
515
  				       pinmux_type,
  				       GPIO_CFG_REQ) != 0)
  			BUG();
  	}
69edbba00   Magnus Damm   sh: use gpiolib
516
517
  	gpioc->gpios[offset].flags &= ~PINMUX_FLAG_TYPE;
  	gpioc->gpios[offset].flags |= pinmux_type;
2967dab1a   Magnus Damm   sh: GPIO and pinm...
518
519
520
521
522
523
524
  
  	ret = 0;
   err_unlock:
  	spin_unlock_irqrestore(&gpio_lock, flags);
   err_out:
  	return ret;
  }
2967dab1a   Magnus Damm   sh: GPIO and pinm...
525

69edbba00   Magnus Damm   sh: use gpiolib
526
  static void sh_gpio_free(struct gpio_chip *chip, unsigned offset)
2967dab1a   Magnus Damm   sh: GPIO and pinm...
527
  {
69edbba00   Magnus Damm   sh: use gpiolib
528
  	struct pinmux_info *gpioc = chip_to_pinmux(chip);
2967dab1a   Magnus Damm   sh: GPIO and pinm...
529
530
531
532
533
534
535
  	unsigned long flags;
  	int pinmux_type;
  
  	if (!gpioc)
  		return;
  
  	spin_lock_irqsave(&gpio_lock, flags);
69edbba00   Magnus Damm   sh: use gpiolib
536
537
538
539
  	pinmux_type = gpioc->gpios[offset].flags & PINMUX_FLAG_TYPE;
  	pinmux_config_gpio(gpioc, offset, pinmux_type, GPIO_CFG_FREE);
  	gpioc->gpios[offset].flags &= ~PINMUX_FLAG_TYPE;
  	gpioc->gpios[offset].flags |= PINMUX_TYPE_NONE;
2967dab1a   Magnus Damm   sh: GPIO and pinm...
540
541
542
  
  	spin_unlock_irqrestore(&gpio_lock, flags);
  }
2967dab1a   Magnus Damm   sh: GPIO and pinm...
543
544
545
546
  
  static int pinmux_direction(struct pinmux_info *gpioc,
  			    unsigned gpio, int new_pinmux_type)
  {
0fc64cc0a   Magnus Damm   sh: lockless gpio...
547
548
549
550
551
  	int pinmux_type;
  	int ret = -EINVAL;
  
  	if (!gpioc)
  		goto err_out;
2967dab1a   Magnus Damm   sh: GPIO and pinm...
552

2967dab1a   Magnus Damm   sh: GPIO and pinm...
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
  	pinmux_type = gpioc->gpios[gpio].flags & PINMUX_FLAG_TYPE;
  
  	switch (pinmux_type) {
  	case PINMUX_TYPE_GPIO:
  		break;
  	case PINMUX_TYPE_OUTPUT:
  	case PINMUX_TYPE_INPUT:
  	case PINMUX_TYPE_INPUT_PULLUP:
  	case PINMUX_TYPE_INPUT_PULLDOWN:
  		pinmux_config_gpio(gpioc, gpio, pinmux_type, GPIO_CFG_FREE);
  		break;
  	default:
  		goto err_out;
  	}
  
  	if (pinmux_config_gpio(gpioc, gpio,
  			       new_pinmux_type,
  			       GPIO_CFG_DRYRUN) != 0)
  		goto err_out;
  
  	if (pinmux_config_gpio(gpioc, gpio,
  			       new_pinmux_type,
  			       GPIO_CFG_REQ) != 0)
  		BUG();
18801be7f   Magnus Damm   sh: make gpio_get...
577
578
  	gpioc->gpios[gpio].flags &= ~PINMUX_FLAG_TYPE;
  	gpioc->gpios[gpio].flags |= new_pinmux_type;
2967dab1a   Magnus Damm   sh: GPIO and pinm...
579
580
581
582
583
  
  	ret = 0;
   err_out:
  	return ret;
  }
69edbba00   Magnus Damm   sh: use gpiolib
584
  static int sh_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
2967dab1a   Magnus Damm   sh: GPIO and pinm...
585
  {
69edbba00   Magnus Damm   sh: use gpiolib
586
  	struct pinmux_info *gpioc = chip_to_pinmux(chip);
2967dab1a   Magnus Damm   sh: GPIO and pinm...
587
  	unsigned long flags;
0fc64cc0a   Magnus Damm   sh: lockless gpio...
588
  	int ret;
2967dab1a   Magnus Damm   sh: GPIO and pinm...
589
590
  
  	spin_lock_irqsave(&gpio_lock, flags);
69edbba00   Magnus Damm   sh: use gpiolib
591
  	ret = pinmux_direction(gpioc, offset, PINMUX_TYPE_INPUT);
2967dab1a   Magnus Damm   sh: GPIO and pinm...
592
  	spin_unlock_irqrestore(&gpio_lock, flags);
0fc64cc0a   Magnus Damm   sh: lockless gpio...
593

2967dab1a   Magnus Damm   sh: GPIO and pinm...
594
595
  	return ret;
  }
2967dab1a   Magnus Damm   sh: GPIO and pinm...
596

69edbba00   Magnus Damm   sh: use gpiolib
597
  static void sh_gpio_set_value(struct pinmux_info *gpioc,
0fc64cc0a   Magnus Damm   sh: lockless gpio...
598
  			     unsigned gpio, int value)
2967dab1a   Magnus Damm   sh: GPIO and pinm...
599
600
601
  {
  	struct pinmux_data_reg *dr = NULL;
  	int bit = 0;
0fc64cc0a   Magnus Damm   sh: lockless gpio...
602
  	if (!gpioc || get_data_reg(gpioc, gpio, &dr, &bit) != 0)
2967dab1a   Magnus Damm   sh: GPIO and pinm...
603
604
  		BUG();
  	else
3292094e8   Magnus Damm   sh: lockless gpio...
605
  		gpio_write_bit(dr, bit, value);
2967dab1a   Magnus Damm   sh: GPIO and pinm...
606
  }
69edbba00   Magnus Damm   sh: use gpiolib
607
608
  static int sh_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
  				    int value)
2967dab1a   Magnus Damm   sh: GPIO and pinm...
609
  {
69edbba00   Magnus Damm   sh: use gpiolib
610
  	struct pinmux_info *gpioc = chip_to_pinmux(chip);
2967dab1a   Magnus Damm   sh: GPIO and pinm...
611
  	unsigned long flags;
0fc64cc0a   Magnus Damm   sh: lockless gpio...
612
  	int ret;
2967dab1a   Magnus Damm   sh: GPIO and pinm...
613

69edbba00   Magnus Damm   sh: use gpiolib
614
  	sh_gpio_set_value(gpioc, offset, value);
3292094e8   Magnus Damm   sh: lockless gpio...
615
  	spin_lock_irqsave(&gpio_lock, flags);
69edbba00   Magnus Damm   sh: use gpiolib
616
  	ret = pinmux_direction(gpioc, offset, PINMUX_TYPE_OUTPUT);
2967dab1a   Magnus Damm   sh: GPIO and pinm...
617
  	spin_unlock_irqrestore(&gpio_lock, flags);
0fc64cc0a   Magnus Damm   sh: lockless gpio...
618

2967dab1a   Magnus Damm   sh: GPIO and pinm...
619
620
  	return ret;
  }
2967dab1a   Magnus Damm   sh: GPIO and pinm...
621

69edbba00   Magnus Damm   sh: use gpiolib
622
  static int sh_gpio_get_value(struct pinmux_info *gpioc, unsigned gpio)
2967dab1a   Magnus Damm   sh: GPIO and pinm...
623
  {
0fc64cc0a   Magnus Damm   sh: lockless gpio...
624
625
  	struct pinmux_data_reg *dr = NULL;
  	int bit = 0;
2967dab1a   Magnus Damm   sh: GPIO and pinm...
626

e8184a47c   Paul Mundt   sh: pfc: Fix up B...
627
628
  	if (!gpioc || get_data_reg(gpioc, gpio, &dr, &bit) != 0)
  		return -EINVAL;
2967dab1a   Magnus Damm   sh: GPIO and pinm...
629

92554d97c   Magnus Damm   sh: pfc: Add gpio...
630
  	return gpio_read_bit(dr, bit);
0fc64cc0a   Magnus Damm   sh: lockless gpio...
631
  }
69edbba00   Magnus Damm   sh: use gpiolib
632
  static int sh_gpio_get(struct gpio_chip *chip, unsigned offset)
0fc64cc0a   Magnus Damm   sh: lockless gpio...
633
  {
69edbba00   Magnus Damm   sh: use gpiolib
634
  	return sh_gpio_get_value(chip_to_pinmux(chip), offset);
2967dab1a   Magnus Damm   sh: GPIO and pinm...
635
  }
2967dab1a   Magnus Damm   sh: GPIO and pinm...
636

69edbba00   Magnus Damm   sh: use gpiolib
637
  static void sh_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
2967dab1a   Magnus Damm   sh: GPIO and pinm...
638
  {
69edbba00   Magnus Damm   sh: use gpiolib
639
  	sh_gpio_set_value(chip_to_pinmux(chip), offset, value);
2967dab1a   Magnus Damm   sh: GPIO and pinm...
640
  }
2967dab1a   Magnus Damm   sh: GPIO and pinm...
641

ad2a8e7ea   Magnus Damm   sh: pfc: Add GPIO...
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
  static int sh_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
  {
  	struct pinmux_info *gpioc = chip_to_pinmux(chip);
  	pinmux_enum_t enum_id;
  	pinmux_enum_t *enum_ids;
  	int i, k, pos;
  
  	pos = 0;
  	enum_id = 0;
  	while (1) {
  		pos = get_gpio_enum_id(gpioc, offset, pos, &enum_id);
  		if (pos <= 0 || !enum_id)
  			break;
  
  		for (i = 0; i < gpioc->gpio_irq_size; i++) {
  			enum_ids = gpioc->gpio_irq[i].enum_ids;
  			for (k = 0; enum_ids[k]; k++) {
  				if (enum_ids[k] == enum_id)
  					return gpioc->gpio_irq[i].irq;
  			}
  		}
  	}
  
  	return -ENOSYS;
  }
2967dab1a   Magnus Damm   sh: GPIO and pinm...
667
668
  int register_pinmux(struct pinmux_info *pip)
  {
69edbba00   Magnus Damm   sh: use gpiolib
669
  	struct gpio_chip *chip = &pip->chip;
b0e10211c   Magnus Damm   sh: pfc: ioremap(...
670
  	int ret;
69edbba00   Magnus Damm   sh: use gpiolib
671

b72421d8a   Paul Mundt   sh: pfc: support ...
672
673
  	pr_info("%s handling gpio %d -> %d
  ",
2967dab1a   Magnus Damm   sh: GPIO and pinm...
674
  		pip->name, pip->first_gpio, pip->last_gpio);
b0e10211c   Magnus Damm   sh: pfc: ioremap(...
675
676
677
  	ret = pfc_ioremap(pip);
  	if (ret < 0)
  		return ret;
69edbba00   Magnus Damm   sh: use gpiolib
678
679
680
681
682
683
684
685
  	setup_data_regs(pip);
  
  	chip->request = sh_gpio_request;
  	chip->free = sh_gpio_free;
  	chip->direction_input = sh_gpio_direction_input;
  	chip->get = sh_gpio_get;
  	chip->direction_output = sh_gpio_direction_output;
  	chip->set = sh_gpio_set;
ad2a8e7ea   Magnus Damm   sh: pfc: Add GPIO...
686
  	chip->to_irq = sh_gpio_to_irq;
69edbba00   Magnus Damm   sh: use gpiolib
687
688
689
690
691
692
693
  
  	WARN_ON(pip->first_gpio != 0); /* needs testing */
  
  	chip->label = pip->name;
  	chip->owner = THIS_MODULE;
  	chip->base = pip->first_gpio;
  	chip->ngpio = (pip->last_gpio - pip->first_gpio) + 1;
b0e10211c   Magnus Damm   sh: pfc: ioremap(...
694
695
696
697
698
  	ret = gpiochip_add(chip);
  	if (ret < 0)
  		pfc_iounmap(pip);
  
  	return ret;
2967dab1a   Magnus Damm   sh: GPIO and pinm...
699
  }
b72421d8a   Paul Mundt   sh: pfc: support ...
700
701
702
703
704
  
  int unregister_pinmux(struct pinmux_info *pip)
  {
  	pr_info("%s deregistering
  ", pip->name);
b0e10211c   Magnus Damm   sh: pfc: ioremap(...
705
  	pfc_iounmap(pip);
b72421d8a   Paul Mundt   sh: pfc: support ...
706
707
  	return gpiochip_remove(&pip->chip);
  }