aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMagnus Damm <damm@opensource.se>2011-12-08 22:14:27 -0500
committerPaul Mundt <lethal@linux-sh.org>2011-12-09 04:07:15 -0500
commitb0e10211cba1629e2e534ca9cb3d87cfc7e389ea (patch)
treef545599adeabd07c3dc76a4d90860599fea800b0 /drivers
parent883381d9f1c5a6329bbb796e23ae52c939940310 (diff)
sh: pfc: ioremap() support
Add support for non-entity mapped PFC registers through the use of struct resource and ioremap()/iounmap(). The PFC main data structure gets updated with a pointer to a struct resources array that point out all register windows used by the PFC instance. The register definitions are kept as physical addresses but the PFC code will do transparent conversion into virtual addresses whenever register windows are specified using with struct resource. To introduce as little performance penalty as possible the virtual address of each data register is cached in memory. The virtual address of each configuration register is however calculated during run time. This because the configuration is considered slow path so focus is instead put on keeping memory foot print as small as possible. The PFC register access code is in this patch updated from __raw_readN() / __raw_writeN() into ioreadN() / iowriteN(). This patch is needed to support the PFC block in r8a7779. Signed-off-by: Magnus Damm <damm@opensource.se> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/sh/pfc.c137
1 files changed, 113 insertions, 24 deletions
diff --git a/drivers/sh/pfc.c b/drivers/sh/pfc.c
index e67fe170d8d5..e7d127a9c1c5 100644
--- a/drivers/sh/pfc.c
+++ b/drivers/sh/pfc.c
@@ -19,6 +19,75 @@
19#include <linux/irq.h> 19#include <linux/irq.h>
20#include <linux/bitops.h> 20#include <linux/bitops.h>
21#include <linux/gpio.h> 21#include <linux/gpio.h>
22#include <linux/slab.h>
23#include <linux/ioport.h>
24
25static void pfc_iounmap(struct pinmux_info *pip)
26{
27 int k;
28
29 for (k = 0; k < pip->num_resources; k++)
30 if (pip->window[k].virt)
31 iounmap(pip->window[k].virt);
32
33 kfree(pip->window);
34 pip->window = NULL;
35}
36
37static int pfc_ioremap(struct pinmux_info *pip)
38{
39 struct resource *res;
40 int k;
41
42 if (!pip->num_resources)
43 return 0;
44
45 pip->window = kzalloc(pip->num_resources * sizeof(*pip->window),
46 GFP_NOWAIT);
47 if (!pip->window)
48 goto err1;
49
50 for (k = 0; k < pip->num_resources; k++) {
51 res = pip->resource + k;
52 WARN_ON(resource_type(res) != IORESOURCE_MEM);
53 pip->window[k].phys = res->start;
54 pip->window[k].size = resource_size(res);
55 pip->window[k].virt = ioremap_nocache(res->start,
56 resource_size(res));
57 if (!pip->window[k].virt)
58 goto err2;
59 }
60
61 return 0;
62
63err2:
64 pfc_iounmap(pip);
65err1:
66 return -1;
67}
68
69static void __iomem *pfc_phys_to_virt(struct pinmux_info *pip,
70 unsigned long address)
71{
72 struct pfc_window *window;
73 int k;
74
75 /* scan through physical windows and convert address */
76 for (k = 0; k < pip->num_resources; k++) {
77 window = pip->window + k;
78
79 if (address < window->phys)
80 continue;
81
82 if (address >= (window->phys + window->size))
83 continue;
84
85 return window->virt + (address - window->phys);
86 }
87
88 /* no windows defined, register must be 1:1 mapped virt:phys */
89 return (void __iomem *)address;
90}
22 91
23static int enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r) 92static int enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r)
24{ 93{
@@ -31,35 +100,35 @@ static int enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r)
31 return 1; 100 return 1;
32} 101}
33 102
34static unsigned long gpio_read_raw_reg(unsigned long reg, 103static unsigned long gpio_read_raw_reg(void __iomem *mapped_reg,
35 unsigned long reg_width) 104 unsigned long reg_width)
36{ 105{
37 switch (reg_width) { 106 switch (reg_width) {
38 case 8: 107 case 8:
39 return __raw_readb(reg); 108 return ioread8(mapped_reg);
40 case 16: 109 case 16:
41 return __raw_readw(reg); 110 return ioread16(mapped_reg);
42 case 32: 111 case 32:
43 return __raw_readl(reg); 112 return ioread32(mapped_reg);
44 } 113 }
45 114
46 BUG(); 115 BUG();
47 return 0; 116 return 0;
48} 117}
49 118
50static void gpio_write_raw_reg(unsigned long reg, 119static void gpio_write_raw_reg(void __iomem *mapped_reg,
51 unsigned long reg_width, 120 unsigned long reg_width,
52 unsigned long data) 121 unsigned long data)
53{ 122{
54 switch (reg_width) { 123 switch (reg_width) {
55 case 8: 124 case 8:
56 __raw_writeb(data, reg); 125 iowrite8(data, mapped_reg);
57 return; 126 return;
58 case 16: 127 case 16:
59 __raw_writew(data, reg); 128 iowrite16(data, mapped_reg);
60 return; 129 return;
61 case 32: 130 case 32:
62 __raw_writel(data, reg); 131 iowrite32(data, mapped_reg);
63 return; 132 return;
64 } 133 }
65 134
@@ -82,11 +151,12 @@ static void gpio_write_bit(struct pinmux_data_reg *dr,
82 else 151 else
83 clear_bit(pos, &dr->reg_shadow); 152 clear_bit(pos, &dr->reg_shadow);
84 153
85 gpio_write_raw_reg(dr->reg, dr->reg_width, dr->reg_shadow); 154 gpio_write_raw_reg(dr->mapped_reg, dr->reg_width, dr->reg_shadow);
86} 155}
87 156
88static int gpio_read_reg(unsigned long reg, unsigned long reg_width, 157static int gpio_read_reg(void __iomem *mapped_reg, unsigned long reg_width,
89 unsigned long field_width, unsigned long in_pos) 158 unsigned long field_width, unsigned long in_pos,
159 unsigned long reg)
90{ 160{
91 unsigned long data, mask, pos; 161 unsigned long data, mask, pos;
92 162
@@ -98,13 +168,13 @@ static int gpio_read_reg(unsigned long reg, unsigned long reg_width,
98 "r_width = %ld, f_width = %ld\n", 168 "r_width = %ld, f_width = %ld\n",
99 reg, pos, reg_width, field_width); 169 reg, pos, reg_width, field_width);
100 170
101 data = gpio_read_raw_reg(reg, reg_width); 171 data = gpio_read_raw_reg(mapped_reg, reg_width);
102 return (data >> pos) & mask; 172 return (data >> pos) & mask;
103} 173}
104 174
105static void gpio_write_reg(unsigned long reg, unsigned long reg_width, 175static void gpio_write_reg(void __iomem *mapped_reg, unsigned long reg_width,
106 unsigned long field_width, unsigned long in_pos, 176 unsigned long field_width, unsigned long in_pos,
107 unsigned long value) 177 unsigned long value, unsigned long reg)
108{ 178{
109 unsigned long mask, pos; 179 unsigned long mask, pos;
110 180
@@ -120,13 +190,13 @@ static void gpio_write_reg(unsigned long reg, unsigned long reg_width,
120 190
121 switch (reg_width) { 191 switch (reg_width) {
122 case 8: 192 case 8:
123 __raw_writeb((__raw_readb(reg) & mask) | value, reg); 193 iowrite8((ioread8(mapped_reg) & mask) | value, mapped_reg);
124 break; 194 break;
125 case 16: 195 case 16:
126 __raw_writew((__raw_readw(reg) & mask) | value, reg); 196 iowrite16((ioread16(mapped_reg) & mask) | value, mapped_reg);
127 break; 197 break;
128 case 32: 198 case 32:
129 __raw_writel((__raw_readl(reg) & mask) | value, reg); 199 iowrite32((ioread32(mapped_reg) & mask) | value, mapped_reg);
130 break; 200 break;
131 } 201 }
132} 202}
@@ -147,6 +217,8 @@ static int setup_data_reg(struct pinmux_info *gpioc, unsigned gpio)
147 if (!data_reg->reg_width) 217 if (!data_reg->reg_width)
148 break; 218 break;
149 219
220 data_reg->mapped_reg = pfc_phys_to_virt(gpioc, data_reg->reg);
221
150 for (n = 0; n < data_reg->reg_width; n++) { 222 for (n = 0; n < data_reg->reg_width; n++) {
151 if (data_reg->enum_ids[n] == gpiop->enum_id) { 223 if (data_reg->enum_ids[n] == gpiop->enum_id) {
152 gpiop->flags &= ~PINMUX_FLAG_DREG; 224 gpiop->flags &= ~PINMUX_FLAG_DREG;
@@ -179,7 +251,8 @@ static void setup_data_regs(struct pinmux_info *gpioc)
179 if (!drp->reg_width) 251 if (!drp->reg_width)
180 break; 252 break;
181 253
182 drp->reg_shadow = gpio_read_raw_reg(drp->reg, drp->reg_width); 254 drp->reg_shadow = gpio_read_raw_reg(drp->mapped_reg,
255 drp->reg_width);
183 k++; 256 k++;
184 } 257 }
185} 258}
@@ -266,12 +339,16 @@ static void write_config_reg(struct pinmux_info *gpioc,
266 int index) 339 int index)
267{ 340{
268 unsigned long ncomb, pos, value; 341 unsigned long ncomb, pos, value;
342 void __iomem *mapped_reg;
269 343
270 ncomb = 1 << crp->field_width; 344 ncomb = 1 << crp->field_width;
271 pos = index / ncomb; 345 pos = index / ncomb;
272 value = index % ncomb; 346 value = index % ncomb;
273 347
274 gpio_write_reg(crp->reg, crp->reg_width, crp->field_width, pos, value); 348 mapped_reg = pfc_phys_to_virt(gpioc, crp->reg);
349
350 gpio_write_reg(mapped_reg, crp->reg_width, crp->field_width,
351 pos, value, crp->reg);
275} 352}
276 353
277static int check_config_reg(struct pinmux_info *gpioc, 354static int check_config_reg(struct pinmux_info *gpioc,
@@ -279,13 +356,16 @@ static int check_config_reg(struct pinmux_info *gpioc,
279 int index) 356 int index)
280{ 357{
281 unsigned long ncomb, pos, value; 358 unsigned long ncomb, pos, value;
359 void __iomem *mapped_reg;
282 360
283 ncomb = 1 << crp->field_width; 361 ncomb = 1 << crp->field_width;
284 pos = index / ncomb; 362 pos = index / ncomb;
285 value = index % ncomb; 363 value = index % ncomb;
286 364
287 if (gpio_read_reg(crp->reg, crp->reg_width, 365 mapped_reg = pfc_phys_to_virt(gpioc, crp->reg);
288 crp->field_width, pos) == value) 366
367 if (gpio_read_reg(mapped_reg, crp->reg_width,
368 crp->field_width, pos, crp->reg) == value)
289 return 0; 369 return 0;
290 370
291 return -1; 371 return -1;
@@ -564,7 +644,7 @@ static int sh_gpio_get_value(struct pinmux_info *gpioc, unsigned gpio)
564 if (!gpioc || get_data_reg(gpioc, gpio, &dr, &bit) != 0) 644 if (!gpioc || get_data_reg(gpioc, gpio, &dr, &bit) != 0)
565 return -EINVAL; 645 return -EINVAL;
566 646
567 return gpio_read_reg(dr->reg, dr->reg_width, 1, bit); 647 return gpio_read_reg(dr->mapped_reg, dr->reg_width, 1, bit, dr->reg);
568} 648}
569 649
570static int sh_gpio_get(struct gpio_chip *chip, unsigned offset) 650static int sh_gpio_get(struct gpio_chip *chip, unsigned offset)
@@ -606,10 +686,15 @@ static int sh_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
606int register_pinmux(struct pinmux_info *pip) 686int register_pinmux(struct pinmux_info *pip)
607{ 687{
608 struct gpio_chip *chip = &pip->chip; 688 struct gpio_chip *chip = &pip->chip;
689 int ret;
609 690
610 pr_info("%s handling gpio %d -> %d\n", 691 pr_info("%s handling gpio %d -> %d\n",
611 pip->name, pip->first_gpio, pip->last_gpio); 692 pip->name, pip->first_gpio, pip->last_gpio);
612 693
694 ret = pfc_ioremap(pip);
695 if (ret < 0)
696 return ret;
697
613 setup_data_regs(pip); 698 setup_data_regs(pip);
614 699
615 chip->request = sh_gpio_request; 700 chip->request = sh_gpio_request;
@@ -627,12 +712,16 @@ int register_pinmux(struct pinmux_info *pip)
627 chip->base = pip->first_gpio; 712 chip->base = pip->first_gpio;
628 chip->ngpio = (pip->last_gpio - pip->first_gpio) + 1; 713 chip->ngpio = (pip->last_gpio - pip->first_gpio) + 1;
629 714
630 return gpiochip_add(chip); 715 ret = gpiochip_add(chip);
716 if (ret < 0)
717 pfc_iounmap(pip);
718
719 return ret;
631} 720}
632 721
633int unregister_pinmux(struct pinmux_info *pip) 722int unregister_pinmux(struct pinmux_info *pip)
634{ 723{
635 pr_info("%s deregistering\n", pip->name); 724 pr_info("%s deregistering\n", pip->name);
636 725 pfc_iounmap(pip);
637 return gpiochip_remove(&pip->chip); 726 return gpiochip_remove(&pip->chip);
638} 727}