diff options
Diffstat (limited to 'drivers/sh')
-rw-r--r-- | drivers/sh/intc/core.c | 37 | ||||
-rw-r--r-- | drivers/sh/intc/internals.h | 7 | ||||
-rw-r--r-- | drivers/sh/intc/userimask.c | 16 | ||||
-rw-r--r-- | drivers/sh/pfc.c | 137 |
4 files changed, 148 insertions, 49 deletions
diff --git a/drivers/sh/intc/core.c b/drivers/sh/intc/core.c index 8b7a141ff35e..e53e449b4eca 100644 --- a/drivers/sh/intc/core.c +++ b/drivers/sh/intc/core.c | |||
@@ -25,7 +25,7 @@ | |||
25 | #include <linux/stat.h> | 25 | #include <linux/stat.h> |
26 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
27 | #include <linux/sh_intc.h> | 27 | #include <linux/sh_intc.h> |
28 | #include <linux/sysdev.h> | 28 | #include <linux/device.h> |
29 | #include <linux/syscore_ops.h> | 29 | #include <linux/syscore_ops.h> |
30 | #include <linux/list.h> | 30 | #include <linux/list.h> |
31 | #include <linux/spinlock.h> | 31 | #include <linux/spinlock.h> |
@@ -354,6 +354,8 @@ int __init register_intc_controller(struct intc_desc *desc) | |||
354 | if (desc->force_enable) | 354 | if (desc->force_enable) |
355 | intc_enable_disable_enum(desc, d, desc->force_enable, 1); | 355 | intc_enable_disable_enum(desc, d, desc->force_enable, 1); |
356 | 356 | ||
357 | d->skip_suspend = desc->skip_syscore_suspend; | ||
358 | |||
357 | nr_intc_controllers++; | 359 | nr_intc_controllers++; |
358 | 360 | ||
359 | return 0; | 361 | return 0; |
@@ -386,6 +388,9 @@ static int intc_suspend(void) | |||
386 | list_for_each_entry(d, &intc_list, list) { | 388 | list_for_each_entry(d, &intc_list, list) { |
387 | int irq; | 389 | int irq; |
388 | 390 | ||
391 | if (d->skip_suspend) | ||
392 | continue; | ||
393 | |||
389 | /* enable wakeup irqs belonging to this intc controller */ | 394 | /* enable wakeup irqs belonging to this intc controller */ |
390 | for_each_active_irq(irq) { | 395 | for_each_active_irq(irq) { |
391 | struct irq_data *data; | 396 | struct irq_data *data; |
@@ -409,6 +414,9 @@ static void intc_resume(void) | |||
409 | list_for_each_entry(d, &intc_list, list) { | 414 | list_for_each_entry(d, &intc_list, list) { |
410 | int irq; | 415 | int irq; |
411 | 416 | ||
417 | if (d->skip_suspend) | ||
418 | continue; | ||
419 | |||
412 | for_each_active_irq(irq) { | 420 | for_each_active_irq(irq) { |
413 | struct irq_data *data; | 421 | struct irq_data *data; |
414 | struct irq_chip *chip; | 422 | struct irq_chip *chip; |
@@ -434,46 +442,47 @@ struct syscore_ops intc_syscore_ops = { | |||
434 | .resume = intc_resume, | 442 | .resume = intc_resume, |
435 | }; | 443 | }; |
436 | 444 | ||
437 | struct sysdev_class intc_sysdev_class = { | 445 | struct bus_type intc_subsys = { |
438 | .name = "intc", | 446 | .name = "intc", |
447 | .dev_name = "intc", | ||
439 | }; | 448 | }; |
440 | 449 | ||
441 | static ssize_t | 450 | static ssize_t |
442 | show_intc_name(struct sys_device *dev, struct sysdev_attribute *attr, char *buf) | 451 | show_intc_name(struct device *dev, struct device_attribute *attr, char *buf) |
443 | { | 452 | { |
444 | struct intc_desc_int *d; | 453 | struct intc_desc_int *d; |
445 | 454 | ||
446 | d = container_of(dev, struct intc_desc_int, sysdev); | 455 | d = container_of(dev, struct intc_desc_int, dev); |
447 | 456 | ||
448 | return sprintf(buf, "%s\n", d->chip.name); | 457 | return sprintf(buf, "%s\n", d->chip.name); |
449 | } | 458 | } |
450 | 459 | ||
451 | static SYSDEV_ATTR(name, S_IRUGO, show_intc_name, NULL); | 460 | static DEVICE_ATTR(name, S_IRUGO, show_intc_name, NULL); |
452 | 461 | ||
453 | static int __init register_intc_sysdevs(void) | 462 | static int __init register_intc_devs(void) |
454 | { | 463 | { |
455 | struct intc_desc_int *d; | 464 | struct intc_desc_int *d; |
456 | int error; | 465 | int error; |
457 | 466 | ||
458 | register_syscore_ops(&intc_syscore_ops); | 467 | register_syscore_ops(&intc_syscore_ops); |
459 | 468 | ||
460 | error = sysdev_class_register(&intc_sysdev_class); | 469 | error = subsys_system_register(&intc_subsys, NULL); |
461 | if (!error) { | 470 | if (!error) { |
462 | list_for_each_entry(d, &intc_list, list) { | 471 | list_for_each_entry(d, &intc_list, list) { |
463 | d->sysdev.id = d->index; | 472 | d->dev.id = d->index; |
464 | d->sysdev.cls = &intc_sysdev_class; | 473 | d->dev.bus = &intc_subsys; |
465 | error = sysdev_register(&d->sysdev); | 474 | error = device_register(&d->dev); |
466 | if (error == 0) | 475 | if (error == 0) |
467 | error = sysdev_create_file(&d->sysdev, | 476 | error = device_create_file(&d->dev, |
468 | &attr_name); | 477 | &dev_attr_name); |
469 | if (error) | 478 | if (error) |
470 | break; | 479 | break; |
471 | } | 480 | } |
472 | } | 481 | } |
473 | 482 | ||
474 | if (error) | 483 | if (error) |
475 | pr_err("sysdev registration error\n"); | 484 | pr_err("device registration error\n"); |
476 | 485 | ||
477 | return error; | 486 | return error; |
478 | } | 487 | } |
479 | device_initcall(register_intc_sysdevs); | 488 | device_initcall(register_intc_devs); |
diff --git a/drivers/sh/intc/internals.h b/drivers/sh/intc/internals.h index 5b934851efa8..b0e9155ff739 100644 --- a/drivers/sh/intc/internals.h +++ b/drivers/sh/intc/internals.h | |||
@@ -4,7 +4,7 @@ | |||
4 | #include <linux/kernel.h> | 4 | #include <linux/kernel.h> |
5 | #include <linux/types.h> | 5 | #include <linux/types.h> |
6 | #include <linux/radix-tree.h> | 6 | #include <linux/radix-tree.h> |
7 | #include <linux/sysdev.h> | 7 | #include <linux/device.h> |
8 | 8 | ||
9 | #define _INTC_MK(fn, mode, addr_e, addr_d, width, shift) \ | 9 | #define _INTC_MK(fn, mode, addr_e, addr_d, width, shift) \ |
10 | ((shift) | ((width) << 5) | ((fn) << 9) | ((mode) << 13) | \ | 10 | ((shift) | ((width) << 5) | ((fn) << 9) | ((mode) << 13) | \ |
@@ -51,7 +51,7 @@ struct intc_subgroup_entry { | |||
51 | 51 | ||
52 | struct intc_desc_int { | 52 | struct intc_desc_int { |
53 | struct list_head list; | 53 | struct list_head list; |
54 | struct sys_device sysdev; | 54 | struct device dev; |
55 | struct radix_tree_root tree; | 55 | struct radix_tree_root tree; |
56 | raw_spinlock_t lock; | 56 | raw_spinlock_t lock; |
57 | unsigned int index; | 57 | unsigned int index; |
@@ -67,6 +67,7 @@ struct intc_desc_int { | |||
67 | struct intc_window *window; | 67 | struct intc_window *window; |
68 | unsigned int nr_windows; | 68 | unsigned int nr_windows; |
69 | struct irq_chip chip; | 69 | struct irq_chip chip; |
70 | bool skip_suspend; | ||
70 | }; | 71 | }; |
71 | 72 | ||
72 | 73 | ||
@@ -157,7 +158,7 @@ void _intc_enable(struct irq_data *data, unsigned long handle); | |||
157 | extern struct list_head intc_list; | 158 | extern struct list_head intc_list; |
158 | extern raw_spinlock_t intc_big_lock; | 159 | extern raw_spinlock_t intc_big_lock; |
159 | extern unsigned int nr_intc_controllers; | 160 | extern unsigned int nr_intc_controllers; |
160 | extern struct sysdev_class intc_sysdev_class; | 161 | extern struct bus_type intc_subsys; |
161 | 162 | ||
162 | unsigned int intc_get_dfl_prio_level(void); | 163 | unsigned int intc_get_dfl_prio_level(void); |
163 | unsigned int intc_get_prio_level(unsigned int irq); | 164 | unsigned int intc_get_prio_level(unsigned int irq); |
diff --git a/drivers/sh/intc/userimask.c b/drivers/sh/intc/userimask.c index 56bf9336b92b..e649ceaaa410 100644 --- a/drivers/sh/intc/userimask.c +++ b/drivers/sh/intc/userimask.c | |||
@@ -10,7 +10,7 @@ | |||
10 | #define pr_fmt(fmt) "intc: " fmt | 10 | #define pr_fmt(fmt) "intc: " fmt |
11 | 11 | ||
12 | #include <linux/errno.h> | 12 | #include <linux/errno.h> |
13 | #include <linux/sysdev.h> | 13 | #include <linux/device.h> |
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <linux/io.h> | 15 | #include <linux/io.h> |
16 | #include <linux/stat.h> | 16 | #include <linux/stat.h> |
@@ -20,15 +20,15 @@ | |||
20 | static void __iomem *uimask; | 20 | static void __iomem *uimask; |
21 | 21 | ||
22 | static ssize_t | 22 | static ssize_t |
23 | show_intc_userimask(struct sysdev_class *cls, | 23 | show_intc_userimask(struct device *dev, |
24 | struct sysdev_class_attribute *attr, char *buf) | 24 | struct device_attribute *attr, char *buf) |
25 | { | 25 | { |
26 | return sprintf(buf, "%d\n", (__raw_readl(uimask) >> 4) & 0xf); | 26 | return sprintf(buf, "%d\n", (__raw_readl(uimask) >> 4) & 0xf); |
27 | } | 27 | } |
28 | 28 | ||
29 | static ssize_t | 29 | static ssize_t |
30 | store_intc_userimask(struct sysdev_class *cls, | 30 | store_intc_userimask(struct device *dev, |
31 | struct sysdev_class_attribute *attr, | 31 | struct device_attribute *attr, |
32 | const char *buf, size_t count) | 32 | const char *buf, size_t count) |
33 | { | 33 | { |
34 | unsigned long level; | 34 | unsigned long level; |
@@ -55,8 +55,8 @@ store_intc_userimask(struct sysdev_class *cls, | |||
55 | return count; | 55 | return count; |
56 | } | 56 | } |
57 | 57 | ||
58 | static SYSDEV_CLASS_ATTR(userimask, S_IRUSR | S_IWUSR, | 58 | static DEVICE_ATTR(userimask, S_IRUSR | S_IWUSR, |
59 | show_intc_userimask, store_intc_userimask); | 59 | show_intc_userimask, store_intc_userimask); |
60 | 60 | ||
61 | 61 | ||
62 | static int __init userimask_sysdev_init(void) | 62 | static int __init userimask_sysdev_init(void) |
@@ -64,7 +64,7 @@ static int __init userimask_sysdev_init(void) | |||
64 | if (unlikely(!uimask)) | 64 | if (unlikely(!uimask)) |
65 | return -ENXIO; | 65 | return -ENXIO; |
66 | 66 | ||
67 | return sysdev_class_create_file(&intc_sysdev_class, &attr_userimask); | 67 | return device_create_file(intc_subsys.dev_root, &dev_attr_userimask); |
68 | } | 68 | } |
69 | late_initcall(userimask_sysdev_init); | 69 | late_initcall(userimask_sysdev_init); |
70 | 70 | ||
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 | |||
25 | static 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 | |||
37 | static 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 | |||
63 | err2: | ||
64 | pfc_iounmap(pip); | ||
65 | err1: | ||
66 | return -1; | ||
67 | } | ||
68 | |||
69 | static 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 | ||
23 | static int enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r) | 92 | static 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 | ||
34 | static unsigned long gpio_read_raw_reg(unsigned long reg, | 103 | static 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 | ||
50 | static void gpio_write_raw_reg(unsigned long reg, | 119 | static 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 | ||
88 | static int gpio_read_reg(unsigned long reg, unsigned long reg_width, | 157 | static 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 | ||
105 | static void gpio_write_reg(unsigned long reg, unsigned long reg_width, | 175 | static 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 | ||
277 | static int check_config_reg(struct pinmux_info *gpioc, | 354 | static 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 | ||
570 | static int sh_gpio_get(struct gpio_chip *chip, unsigned offset) | 650 | static 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) | |||
606 | int register_pinmux(struct pinmux_info *pip) | 686 | int 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 | ||
633 | int unregister_pinmux(struct pinmux_info *pip) | 722 | int 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 | } |