aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/sh/pfc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/sh/pfc.c')
-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}