aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/sh
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /drivers/sh
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'drivers/sh')
-rw-r--r--drivers/sh/Kconfig1
-rw-r--r--drivers/sh/Makefile4
-rw-r--r--drivers/sh/clk/core.c116
-rw-r--r--drivers/sh/clk/cpg.c482
-rw-r--r--drivers/sh/intc/Kconfig4
-rw-r--r--drivers/sh/intc/Makefile2
-rw-r--r--drivers/sh/intc/access.c45
-rw-r--r--drivers/sh/intc/balancing.c2
-rw-r--r--drivers/sh/intc/chip.c52
-rw-r--r--drivers/sh/intc/core.c90
-rw-r--r--drivers/sh/intc/handle.c7
-rw-r--r--drivers/sh/intc/internals.h21
-rw-r--r--drivers/sh/intc/irqdomain.c68
-rw-r--r--drivers/sh/intc/userimask.c17
-rw-r--r--drivers/sh/intc/virq.c7
-rw-r--r--drivers/sh/maple/maple.c1
-rw-r--r--drivers/sh/pfc/Kconfig26
-rw-r--r--drivers/sh/pfc/Makefile3
-rw-r--r--drivers/sh/pfc/core.c572
-rw-r--r--drivers/sh/pfc/gpio.c240
-rw-r--r--drivers/sh/pfc/pinctrl.c527
-rw-r--r--drivers/sh/pm_runtime.c65
22 files changed, 383 insertions, 1969 deletions
diff --git a/drivers/sh/Kconfig b/drivers/sh/Kconfig
index d860ef74356..f168a615996 100644
--- a/drivers/sh/Kconfig
+++ b/drivers/sh/Kconfig
@@ -1,6 +1,5 @@
1menu "SuperH / SH-Mobile Driver Options" 1menu "SuperH / SH-Mobile Driver Options"
2 2
3source "drivers/sh/intc/Kconfig" 3source "drivers/sh/intc/Kconfig"
4source "drivers/sh/pfc/Kconfig"
5 4
6endmenu 5endmenu
diff --git a/drivers/sh/Makefile b/drivers/sh/Makefile
index e57895b1a42..24e6cec0ae8 100644
--- a/drivers/sh/Makefile
+++ b/drivers/sh/Makefile
@@ -5,7 +5,5 @@ obj-y := intc/
5 5
6obj-$(CONFIG_HAVE_CLK) += clk/ 6obj-$(CONFIG_HAVE_CLK) += clk/
7obj-$(CONFIG_MAPLE) += maple/ 7obj-$(CONFIG_MAPLE) += maple/
8obj-$(CONFIG_SH_PFC) += pfc/
9obj-$(CONFIG_SUPERHYWAY) += superhyway/ 8obj-$(CONFIG_SUPERHYWAY) += superhyway/
10 9obj-$(CONFIG_GENERIC_GPIO) += pfc.o
11obj-y += pm_runtime.o
diff --git a/drivers/sh/clk/core.c b/drivers/sh/clk/core.c
index 7715de2629c..dc8d022c07a 100644
--- a/drivers/sh/clk/core.c
+++ b/drivers/sh/clk/core.c
@@ -25,6 +25,7 @@
25#include <linux/seq_file.h> 25#include <linux/seq_file.h>
26#include <linux/err.h> 26#include <linux/err.h>
27#include <linux/io.h> 27#include <linux/io.h>
28#include <linux/debugfs.h>
28#include <linux/cpufreq.h> 29#include <linux/cpufreq.h>
29#include <linux/clk.h> 30#include <linux/clk.h>
30#include <linux/sh_clk.h> 31#include <linux/sh_clk.h>
@@ -172,26 +173,6 @@ long clk_rate_div_range_round(struct clk *clk, unsigned int div_min,
172 return clk_rate_round_helper(&div_range_round); 173 return clk_rate_round_helper(&div_range_round);
173} 174}
174 175
175static long clk_rate_mult_range_iter(unsigned int pos,
176 struct clk_rate_round_data *rounder)
177{
178 return clk_get_rate(rounder->arg) * pos;
179}
180
181long clk_rate_mult_range_round(struct clk *clk, unsigned int mult_min,
182 unsigned int mult_max, unsigned long rate)
183{
184 struct clk_rate_round_data mult_range_round = {
185 .min = mult_min,
186 .max = mult_max,
187 .func = clk_rate_mult_range_iter,
188 .arg = clk_get_parent(clk),
189 .rate = rate,
190 };
191
192 return clk_rate_round_helper(&mult_range_round);
193}
194
195int clk_rate_table_find(struct clk *clk, 176int clk_rate_table_find(struct clk *clk,
196 struct cpufreq_frequency_table *freq_table, 177 struct cpufreq_frequency_table *freq_table,
197 unsigned long rate) 178 unsigned long rate)
@@ -224,6 +205,9 @@ int clk_reparent(struct clk *child, struct clk *parent)
224 list_add(&child->sibling, &parent->children); 205 list_add(&child->sibling, &parent->children);
225 child->parent = parent; 206 child->parent = parent;
226 207
208 /* now do the debugfs renaming to reattach the child
209 to the proper parent */
210
227 return 0; 211 return 0;
228} 212}
229 213
@@ -355,7 +339,7 @@ static int clk_establish_mapping(struct clk *clk)
355 */ 339 */
356 if (!clk->parent) { 340 if (!clk->parent) {
357 clk->mapping = &dummy_mapping; 341 clk->mapping = &dummy_mapping;
358 goto out; 342 return 0;
359 } 343 }
360 344
361 /* 345 /*
@@ -384,9 +368,6 @@ static int clk_establish_mapping(struct clk *clk)
384 } 368 }
385 369
386 clk->mapping = mapping; 370 clk->mapping = mapping;
387out:
388 clk->mapped_reg = clk->mapping->base;
389 clk->mapped_reg += (phys_addr_t)clk->enable_reg - clk->mapping->phys;
390 return 0; 371 return 0;
391} 372}
392 373
@@ -405,12 +386,10 @@ static void clk_teardown_mapping(struct clk *clk)
405 386
406 /* Nothing to do */ 387 /* Nothing to do */
407 if (mapping == &dummy_mapping) 388 if (mapping == &dummy_mapping)
408 goto out; 389 return;
409 390
410 kref_put(&mapping->ref, clk_destroy_mapping); 391 kref_put(&mapping->ref, clk_destroy_mapping);
411 clk->mapping = NULL; 392 clk->mapping = NULL;
412out:
413 clk->mapped_reg = NULL;
414} 393}
415 394
416int clk_register(struct clk *clk) 395int clk_register(struct clk *clk)
@@ -686,6 +665,89 @@ static int __init clk_syscore_init(void)
686subsys_initcall(clk_syscore_init); 665subsys_initcall(clk_syscore_init);
687#endif 666#endif
688 667
668/*
669 * debugfs support to trace clock tree hierarchy and attributes
670 */
671static struct dentry *clk_debugfs_root;
672
673static int clk_debugfs_register_one(struct clk *c)
674{
675 int err;
676 struct dentry *d;
677 struct clk *pa = c->parent;
678 char s[255];
679 char *p = s;
680
681 p += sprintf(p, "%p", c);
682 d = debugfs_create_dir(s, pa ? pa->dentry : clk_debugfs_root);
683 if (!d)
684 return -ENOMEM;
685 c->dentry = d;
686
687 d = debugfs_create_u8("usecount", S_IRUGO, c->dentry, (u8 *)&c->usecount);
688 if (!d) {
689 err = -ENOMEM;
690 goto err_out;
691 }
692 d = debugfs_create_u32("rate", S_IRUGO, c->dentry, (u32 *)&c->rate);
693 if (!d) {
694 err = -ENOMEM;
695 goto err_out;
696 }
697 d = debugfs_create_x32("flags", S_IRUGO, c->dentry, (u32 *)&c->flags);
698 if (!d) {
699 err = -ENOMEM;
700 goto err_out;
701 }
702 return 0;
703
704err_out:
705 debugfs_remove_recursive(c->dentry);
706 return err;
707}
708
709static int clk_debugfs_register(struct clk *c)
710{
711 int err;
712 struct clk *pa = c->parent;
713
714 if (pa && !pa->dentry) {
715 err = clk_debugfs_register(pa);
716 if (err)
717 return err;
718 }
719
720 if (!c->dentry) {
721 err = clk_debugfs_register_one(c);
722 if (err)
723 return err;
724 }
725 return 0;
726}
727
728static int __init clk_debugfs_init(void)
729{
730 struct clk *c;
731 struct dentry *d;
732 int err;
733
734 d = debugfs_create_dir("clock", NULL);
735 if (!d)
736 return -ENOMEM;
737 clk_debugfs_root = d;
738
739 list_for_each_entry(c, &clock_list, node) {
740 err = clk_debugfs_register(c);
741 if (err)
742 goto err_out;
743 }
744 return 0;
745err_out:
746 debugfs_remove_recursive(clk_debugfs_root);
747 return err;
748}
749late_initcall(clk_debugfs_init);
750
689static int __init clk_late_init(void) 751static int __init clk_late_init(void)
690{ 752{
691 unsigned long flags; 753 unsigned long flags;
diff --git a/drivers/sh/clk/cpg.c b/drivers/sh/clk/cpg.c
index 5aedcdf4ac5..82dd6fb1783 100644
--- a/drivers/sh/clk/cpg.c
+++ b/drivers/sh/clk/cpg.c
@@ -2,7 +2,6 @@
2 * Helper routines for SuperH Clock Pulse Generator blocks (CPG). 2 * Helper routines for SuperH Clock Pulse Generator blocks (CPG).
3 * 3 *
4 * Copyright (C) 2010 Magnus Damm 4 * Copyright (C) 2010 Magnus Damm
5 * Copyright (C) 2010 - 2012 Paul Mundt
6 * 5 *
7 * This file is subject to the terms and conditions of the GNU General Public 6 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive 7 * License. See the file "COPYING" in the main directory of this archive
@@ -14,46 +13,26 @@
14#include <linux/io.h> 13#include <linux/io.h>
15#include <linux/sh_clk.h> 14#include <linux/sh_clk.h>
16 15
17#define CPG_CKSTP_BIT BIT(8) 16static int sh_clk_mstp32_enable(struct clk *clk)
18
19static unsigned int sh_clk_read(struct clk *clk)
20{
21 if (clk->flags & CLK_ENABLE_REG_8BIT)
22 return ioread8(clk->mapped_reg);
23 else if (clk->flags & CLK_ENABLE_REG_16BIT)
24 return ioread16(clk->mapped_reg);
25
26 return ioread32(clk->mapped_reg);
27}
28
29static void sh_clk_write(int value, struct clk *clk)
30{ 17{
31 if (clk->flags & CLK_ENABLE_REG_8BIT) 18 __raw_writel(__raw_readl(clk->enable_reg) & ~(1 << clk->enable_bit),
32 iowrite8(value, clk->mapped_reg); 19 clk->enable_reg);
33 else if (clk->flags & CLK_ENABLE_REG_16BIT)
34 iowrite16(value, clk->mapped_reg);
35 else
36 iowrite32(value, clk->mapped_reg);
37}
38
39static int sh_clk_mstp_enable(struct clk *clk)
40{
41 sh_clk_write(sh_clk_read(clk) & ~(1 << clk->enable_bit), clk);
42 return 0; 20 return 0;
43} 21}
44 22
45static void sh_clk_mstp_disable(struct clk *clk) 23static void sh_clk_mstp32_disable(struct clk *clk)
46{ 24{
47 sh_clk_write(sh_clk_read(clk) | (1 << clk->enable_bit), clk); 25 __raw_writel(__raw_readl(clk->enable_reg) | (1 << clk->enable_bit),
26 clk->enable_reg);
48} 27}
49 28
50static struct sh_clk_ops sh_clk_mstp_clk_ops = { 29static struct clk_ops sh_clk_mstp32_clk_ops = {
51 .enable = sh_clk_mstp_enable, 30 .enable = sh_clk_mstp32_enable,
52 .disable = sh_clk_mstp_disable, 31 .disable = sh_clk_mstp32_disable,
53 .recalc = followparent_recalc, 32 .recalc = followparent_recalc,
54}; 33};
55 34
56int __init sh_clk_mstp_register(struct clk *clks, int nr) 35int __init sh_clk_mstp32_register(struct clk *clks, int nr)
57{ 36{
58 struct clk *clkp; 37 struct clk *clkp;
59 int ret = 0; 38 int ret = 0;
@@ -61,145 +40,139 @@ int __init sh_clk_mstp_register(struct clk *clks, int nr)
61 40
62 for (k = 0; !ret && (k < nr); k++) { 41 for (k = 0; !ret && (k < nr); k++) {
63 clkp = clks + k; 42 clkp = clks + k;
64 clkp->ops = &sh_clk_mstp_clk_ops; 43 clkp->ops = &sh_clk_mstp32_clk_ops;
65 ret |= clk_register(clkp); 44 ret |= clk_register(clkp);
66 } 45 }
67 46
68 return ret; 47 return ret;
69} 48}
70 49
71/*
72 * Div/mult table lookup helpers
73 */
74static inline struct clk_div_table *clk_to_div_table(struct clk *clk)
75{
76 return clk->priv;
77}
78
79static inline struct clk_div_mult_table *clk_to_div_mult_table(struct clk *clk)
80{
81 return clk_to_div_table(clk)->div_mult_table;
82}
83
84/*
85 * Common div ops
86 */
87static long sh_clk_div_round_rate(struct clk *clk, unsigned long rate) 50static long sh_clk_div_round_rate(struct clk *clk, unsigned long rate)
88{ 51{
89 return clk_rate_table_round(clk, clk->freq_table, rate); 52 return clk_rate_table_round(clk, clk->freq_table, rate);
90} 53}
91 54
92static unsigned long sh_clk_div_recalc(struct clk *clk) 55static int sh_clk_div6_divisors[64] = {
56 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
57 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
58 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
59 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64
60};
61
62static struct clk_div_mult_table sh_clk_div6_table = {
63 .divisors = sh_clk_div6_divisors,
64 .nr_divisors = ARRAY_SIZE(sh_clk_div6_divisors),
65};
66
67static unsigned long sh_clk_div6_recalc(struct clk *clk)
93{ 68{
94 struct clk_div_mult_table *table = clk_to_div_mult_table(clk); 69 struct clk_div_mult_table *table = &sh_clk_div6_table;
95 unsigned int idx; 70 unsigned int idx;
96 71
97 clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, 72 clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
98 table, clk->arch_flags ? &clk->arch_flags : NULL); 73 table, NULL);
99 74
100 idx = (sh_clk_read(clk) >> clk->enable_bit) & clk->div_mask; 75 idx = __raw_readl(clk->enable_reg) & 0x003f;
101 76
102 return clk->freq_table[idx].frequency; 77 return clk->freq_table[idx].frequency;
103} 78}
104 79
105static int sh_clk_div_set_rate(struct clk *clk, unsigned long rate) 80static int sh_clk_div6_set_parent(struct clk *clk, struct clk *parent)
106{ 81{
107 struct clk_div_table *dt = clk_to_div_table(clk); 82 struct clk_div_mult_table *table = &sh_clk_div6_table;
108 unsigned long value; 83 u32 value;
109 int idx; 84 int ret, i;
110 85
111 idx = clk_rate_table_find(clk, clk->freq_table, rate); 86 if (!clk->parent_table || !clk->parent_num)
112 if (idx < 0) 87 return -EINVAL;
113 return idx;
114 88
115 value = sh_clk_read(clk); 89 /* Search the parent */
116 value &= ~(clk->div_mask << clk->enable_bit); 90 for (i = 0; i < clk->parent_num; i++)
117 value |= (idx << clk->enable_bit); 91 if (clk->parent_table[i] == parent)
118 sh_clk_write(value, clk); 92 break;
93
94 if (i == clk->parent_num)
95 return -ENODEV;
96
97 ret = clk_reparent(clk, parent);
98 if (ret < 0)
99 return ret;
100
101 value = __raw_readl(clk->enable_reg) &
102 ~(((1 << clk->src_width) - 1) << clk->src_shift);
103
104 __raw_writel(value | (i << clk->src_shift), clk->enable_reg);
119 105
120 /* XXX: Should use a post-change notifier */ 106 /* Rebuild the frequency table */
121 if (dt->kick) 107 clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
122 dt->kick(clk); 108 table, NULL);
123 109
124 return 0; 110 return 0;
125} 111}
126 112
127static int sh_clk_div_enable(struct clk *clk) 113static int sh_clk_div6_set_rate(struct clk *clk, unsigned long rate)
128{ 114{
129 sh_clk_write(sh_clk_read(clk) & ~CPG_CKSTP_BIT, clk); 115 unsigned long value;
116 int idx;
117
118 idx = clk_rate_table_find(clk, clk->freq_table, rate);
119 if (idx < 0)
120 return idx;
121
122 value = __raw_readl(clk->enable_reg);
123 value &= ~0x3f;
124 value |= idx;
125 __raw_writel(value, clk->enable_reg);
130 return 0; 126 return 0;
131} 127}
132 128
133static void sh_clk_div_disable(struct clk *clk) 129static int sh_clk_div6_enable(struct clk *clk)
134{ 130{
135 unsigned int val; 131 unsigned long value;
132 int ret;
136 133
137 val = sh_clk_read(clk); 134 ret = sh_clk_div6_set_rate(clk, clk->rate);
138 val |= CPG_CKSTP_BIT; 135 if (ret == 0) {
136 value = __raw_readl(clk->enable_reg);
137 value &= ~0x100; /* clear stop bit to enable clock */
138 __raw_writel(value, clk->enable_reg);
139 }
140 return ret;
141}
139 142
140 /* 143static void sh_clk_div6_disable(struct clk *clk)
141 * div6 clocks require the divisor field to be non-zero or the 144{
142 * above CKSTP toggle silently fails. Ensure that the divisor 145 unsigned long value;
143 * array is reset to its initial state on disable.
144 */
145 if (clk->flags & CLK_MASK_DIV_ON_DISABLE)
146 val |= clk->div_mask;
147 146
148 sh_clk_write(val, clk); 147 value = __raw_readl(clk->enable_reg);
148 value |= 0x100; /* stop clock */
149 value |= 0x3f; /* VDIV bits must be non-zero, overwrite divider */
150 __raw_writel(value, clk->enable_reg);
149} 151}
150 152
151static struct sh_clk_ops sh_clk_div_clk_ops = { 153static struct clk_ops sh_clk_div6_clk_ops = {
152 .recalc = sh_clk_div_recalc, 154 .recalc = sh_clk_div6_recalc,
153 .set_rate = sh_clk_div_set_rate,
154 .round_rate = sh_clk_div_round_rate, 155 .round_rate = sh_clk_div_round_rate,
156 .set_rate = sh_clk_div6_set_rate,
157 .enable = sh_clk_div6_enable,
158 .disable = sh_clk_div6_disable,
155}; 159};
156 160
157static struct sh_clk_ops sh_clk_div_enable_clk_ops = { 161static struct clk_ops sh_clk_div6_reparent_clk_ops = {
158 .recalc = sh_clk_div_recalc, 162 .recalc = sh_clk_div6_recalc,
159 .set_rate = sh_clk_div_set_rate,
160 .round_rate = sh_clk_div_round_rate, 163 .round_rate = sh_clk_div_round_rate,
161 .enable = sh_clk_div_enable, 164 .set_rate = sh_clk_div6_set_rate,
162 .disable = sh_clk_div_disable, 165 .enable = sh_clk_div6_enable,
166 .disable = sh_clk_div6_disable,
167 .set_parent = sh_clk_div6_set_parent,
163}; 168};
164 169
165static int __init sh_clk_init_parent(struct clk *clk) 170static int __init sh_clk_div6_register_ops(struct clk *clks, int nr,
166{ 171 struct clk_ops *ops)
167 u32 val;
168
169 if (clk->parent)
170 return 0;
171
172 if (!clk->parent_table || !clk->parent_num)
173 return 0;
174
175 if (!clk->src_width) {
176 pr_err("sh_clk_init_parent: cannot select parent clock\n");
177 return -EINVAL;
178 }
179
180 val = (sh_clk_read(clk) >> clk->src_shift);
181 val &= (1 << clk->src_width) - 1;
182
183 if (val >= clk->parent_num) {
184 pr_err("sh_clk_init_parent: parent table size failed\n");
185 return -EINVAL;
186 }
187
188 clk_reparent(clk, clk->parent_table[val]);
189 if (!clk->parent) {
190 pr_err("sh_clk_init_parent: unable to set parent");
191 return -EINVAL;
192 }
193
194 return 0;
195}
196
197static int __init sh_clk_div_register_ops(struct clk *clks, int nr,
198 struct clk_div_table *table, struct sh_clk_ops *ops)
199{ 172{
200 struct clk *clkp; 173 struct clk *clkp;
201 void *freq_table; 174 void *freq_table;
202 int nr_divs = table->div_mult_table->nr_divisors; 175 int nr_divs = sh_clk_div6_table.nr_divisors;
203 int freq_table_size = sizeof(struct cpufreq_frequency_table); 176 int freq_table_size = sizeof(struct cpufreq_frequency_table);
204 int ret = 0; 177 int ret = 0;
205 int k; 178 int k;
@@ -207,7 +180,7 @@ static int __init sh_clk_div_register_ops(struct clk *clks, int nr,
207 freq_table_size *= (nr_divs + 1); 180 freq_table_size *= (nr_divs + 1);
208 freq_table = kzalloc(freq_table_size * nr, GFP_KERNEL); 181 freq_table = kzalloc(freq_table_size * nr, GFP_KERNEL);
209 if (!freq_table) { 182 if (!freq_table) {
210 pr_err("%s: unable to alloc memory\n", __func__); 183 pr_err("sh_clk_div6_register: unable to alloc memory\n");
211 return -ENOMEM; 184 return -ENOMEM;
212 } 185 }
213 186
@@ -215,98 +188,44 @@ static int __init sh_clk_div_register_ops(struct clk *clks, int nr,
215 clkp = clks + k; 188 clkp = clks + k;
216 189
217 clkp->ops = ops; 190 clkp->ops = ops;
218 clkp->priv = table;
219
220 clkp->freq_table = freq_table + (k * freq_table_size); 191 clkp->freq_table = freq_table + (k * freq_table_size);
221 clkp->freq_table[nr_divs].frequency = CPUFREQ_TABLE_END; 192 clkp->freq_table[nr_divs].frequency = CPUFREQ_TABLE_END;
222 193
223 ret = clk_register(clkp); 194 ret = clk_register(clkp);
224 if (ret == 0)
225 ret = sh_clk_init_parent(clkp);
226 } 195 }
227 196
228 return ret; 197 return ret;
229} 198}
230 199
231/* 200int __init sh_clk_div6_register(struct clk *clks, int nr)
232 * div6 support
233 */
234static int sh_clk_div6_divisors[64] = {
235 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
236 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
237 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
238 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64
239};
240
241static struct clk_div_mult_table div6_div_mult_table = {
242 .divisors = sh_clk_div6_divisors,
243 .nr_divisors = ARRAY_SIZE(sh_clk_div6_divisors),
244};
245
246static struct clk_div_table sh_clk_div6_table = {
247 .div_mult_table = &div6_div_mult_table,
248};
249
250static int sh_clk_div6_set_parent(struct clk *clk, struct clk *parent)
251{ 201{
252 struct clk_div_mult_table *table = clk_to_div_mult_table(clk); 202 return sh_clk_div6_register_ops(clks, nr, &sh_clk_div6_clk_ops);
253 u32 value;
254 int ret, i;
255
256 if (!clk->parent_table || !clk->parent_num)
257 return -EINVAL;
258
259 /* Search the parent */
260 for (i = 0; i < clk->parent_num; i++)
261 if (clk->parent_table[i] == parent)
262 break;
263
264 if (i == clk->parent_num)
265 return -ENODEV;
266
267 ret = clk_reparent(clk, parent);
268 if (ret < 0)
269 return ret;
270
271 value = sh_clk_read(clk) &
272 ~(((1 << clk->src_width) - 1) << clk->src_shift);
273
274 sh_clk_write(value | (i << clk->src_shift), clk);
275
276 /* Rebuild the frequency table */
277 clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
278 table, NULL);
279
280 return 0;
281} 203}
282 204
283static struct sh_clk_ops sh_clk_div6_reparent_clk_ops = { 205int __init sh_clk_div6_reparent_register(struct clk *clks, int nr)
284 .recalc = sh_clk_div_recalc,
285 .round_rate = sh_clk_div_round_rate,
286 .set_rate = sh_clk_div_set_rate,
287 .enable = sh_clk_div_enable,
288 .disable = sh_clk_div_disable,
289 .set_parent = sh_clk_div6_set_parent,
290};
291
292int __init sh_clk_div6_register(struct clk *clks, int nr)
293{ 206{
294 return sh_clk_div_register_ops(clks, nr, &sh_clk_div6_table, 207 return sh_clk_div6_register_ops(clks, nr,
295 &sh_clk_div_enable_clk_ops); 208 &sh_clk_div6_reparent_clk_ops);
296} 209}
297 210
298int __init sh_clk_div6_reparent_register(struct clk *clks, int nr) 211static unsigned long sh_clk_div4_recalc(struct clk *clk)
299{ 212{
300 return sh_clk_div_register_ops(clks, nr, &sh_clk_div6_table, 213 struct clk_div4_table *d4t = clk->priv;
301 &sh_clk_div6_reparent_clk_ops); 214 struct clk_div_mult_table *table = d4t->div_mult_table;
215 unsigned int idx;
216
217 clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
218 table, &clk->arch_flags);
219
220 idx = (__raw_readl(clk->enable_reg) >> clk->enable_bit) & 0x000f;
221
222 return clk->freq_table[idx].frequency;
302} 223}
303 224
304/*
305 * div4 support
306 */
307static int sh_clk_div4_set_parent(struct clk *clk, struct clk *parent) 225static int sh_clk_div4_set_parent(struct clk *clk, struct clk *parent)
308{ 226{
309 struct clk_div_mult_table *table = clk_to_div_mult_table(clk); 227 struct clk_div4_table *d4t = clk->priv;
228 struct clk_div_mult_table *table = d4t->div_mult_table;
310 u32 value; 229 u32 value;
311 int ret; 230 int ret;
312 231
@@ -316,15 +235,15 @@ static int sh_clk_div4_set_parent(struct clk *clk, struct clk *parent)
316 */ 235 */
317 236
318 if (parent->flags & CLK_ENABLE_ON_INIT) 237 if (parent->flags & CLK_ENABLE_ON_INIT)
319 value = sh_clk_read(clk) & ~(1 << 7); 238 value = __raw_readl(clk->enable_reg) & ~(1 << 7);
320 else 239 else
321 value = sh_clk_read(clk) | (1 << 7); 240 value = __raw_readl(clk->enable_reg) | (1 << 7);
322 241
323 ret = clk_reparent(clk, parent); 242 ret = clk_reparent(clk, parent);
324 if (ret < 0) 243 if (ret < 0)
325 return ret; 244 return ret;
326 245
327 sh_clk_write(value, clk); 246 __raw_writel(value, clk->enable_reg);
328 247
329 /* Rebiuld the frequency table */ 248 /* Rebiuld the frequency table */
330 clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, 249 clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
@@ -333,116 +252,107 @@ static int sh_clk_div4_set_parent(struct clk *clk, struct clk *parent)
333 return 0; 252 return 0;
334} 253}
335 254
336static struct sh_clk_ops sh_clk_div4_reparent_clk_ops = { 255static int sh_clk_div4_set_rate(struct clk *clk, unsigned long rate)
337 .recalc = sh_clk_div_recalc,
338 .set_rate = sh_clk_div_set_rate,
339 .round_rate = sh_clk_div_round_rate,
340 .enable = sh_clk_div_enable,
341 .disable = sh_clk_div_disable,
342 .set_parent = sh_clk_div4_set_parent,
343};
344
345int __init sh_clk_div4_register(struct clk *clks, int nr,
346 struct clk_div4_table *table)
347{ 256{
348 return sh_clk_div_register_ops(clks, nr, table, &sh_clk_div_clk_ops); 257 struct clk_div4_table *d4t = clk->priv;
349} 258 unsigned long value;
350 259 int idx = clk_rate_table_find(clk, clk->freq_table, rate);
351int __init sh_clk_div4_enable_register(struct clk *clks, int nr, 260 if (idx < 0)
352 struct clk_div4_table *table) 261 return idx;
353{
354 return sh_clk_div_register_ops(clks, nr, table,
355 &sh_clk_div_enable_clk_ops);
356}
357
358int __init sh_clk_div4_reparent_register(struct clk *clks, int nr,
359 struct clk_div4_table *table)
360{
361 return sh_clk_div_register_ops(clks, nr, table,
362 &sh_clk_div4_reparent_clk_ops);
363}
364
365/* FSI-DIV */
366static unsigned long fsidiv_recalc(struct clk *clk)
367{
368 u32 value;
369 262
370 value = __raw_readl(clk->mapping->base); 263 value = __raw_readl(clk->enable_reg);
264 value &= ~(0xf << clk->enable_bit);
265 value |= (idx << clk->enable_bit);
266 __raw_writel(value, clk->enable_reg);
371 267
372 value >>= 16; 268 if (d4t->kick)
373 if (value < 2) 269 d4t->kick(clk);
374 return clk->parent->rate;
375 270
376 return clk->parent->rate / value; 271 return 0;
377} 272}
378 273
379static long fsidiv_round_rate(struct clk *clk, unsigned long rate) 274static int sh_clk_div4_enable(struct clk *clk)
380{ 275{
381 return clk_rate_div_range_round(clk, 1, 0xffff, rate); 276 __raw_writel(__raw_readl(clk->enable_reg) & ~(1 << 8), clk->enable_reg);
277 return 0;
382} 278}
383 279
384static void fsidiv_disable(struct clk *clk) 280static void sh_clk_div4_disable(struct clk *clk)
385{ 281{
386 __raw_writel(0, clk->mapping->base); 282 __raw_writel(__raw_readl(clk->enable_reg) | (1 << 8), clk->enable_reg);
387} 283}
388 284
389static int fsidiv_enable(struct clk *clk) 285static struct clk_ops sh_clk_div4_clk_ops = {
390{ 286 .recalc = sh_clk_div4_recalc,
391 u32 value; 287 .set_rate = sh_clk_div4_set_rate,
392 288 .round_rate = sh_clk_div_round_rate,
393 value = __raw_readl(clk->mapping->base) >> 16; 289};
394 if (value < 2)
395 return 0;
396 290
397 __raw_writel((value << 16) | 0x3, clk->mapping->base); 291static struct clk_ops sh_clk_div4_enable_clk_ops = {
292 .recalc = sh_clk_div4_recalc,
293 .set_rate = sh_clk_div4_set_rate,
294 .round_rate = sh_clk_div_round_rate,
295 .enable = sh_clk_div4_enable,
296 .disable = sh_clk_div4_disable,
297};
398 298
399 return 0; 299static struct clk_ops sh_clk_div4_reparent_clk_ops = {
400} 300 .recalc = sh_clk_div4_recalc,
301 .set_rate = sh_clk_div4_set_rate,
302 .round_rate = sh_clk_div_round_rate,
303 .enable = sh_clk_div4_enable,
304 .disable = sh_clk_div4_disable,
305 .set_parent = sh_clk_div4_set_parent,
306};
401 307
402static int fsidiv_set_rate(struct clk *clk, unsigned long rate) 308static int __init sh_clk_div4_register_ops(struct clk *clks, int nr,
309 struct clk_div4_table *table, struct clk_ops *ops)
403{ 310{
404 int idx; 311 struct clk *clkp;
405 312 void *freq_table;
406 idx = (clk->parent->rate / rate) & 0xffff; 313 int nr_divs = table->div_mult_table->nr_divisors;
407 if (idx < 2) 314 int freq_table_size = sizeof(struct cpufreq_frequency_table);
408 __raw_writel(0, clk->mapping->base); 315 int ret = 0;
409 else 316 int k;
410 __raw_writel(idx << 16, clk->mapping->base);
411 317
412 return 0; 318 freq_table_size *= (nr_divs + 1);
413} 319 freq_table = kzalloc(freq_table_size * nr, GFP_KERNEL);
320 if (!freq_table) {
321 pr_err("sh_clk_div4_register: unable to alloc memory\n");
322 return -ENOMEM;
323 }
414 324
415static struct sh_clk_ops fsidiv_clk_ops = { 325 for (k = 0; !ret && (k < nr); k++) {
416 .recalc = fsidiv_recalc, 326 clkp = clks + k;
417 .round_rate = fsidiv_round_rate,
418 .set_rate = fsidiv_set_rate,
419 .enable = fsidiv_enable,
420 .disable = fsidiv_disable,
421};
422 327
423int __init sh_clk_fsidiv_register(struct clk *clks, int nr) 328 clkp->ops = ops;
424{ 329 clkp->priv = table;
425 struct clk_mapping *map;
426 int i;
427 330
428 for (i = 0; i < nr; i++) { 331 clkp->freq_table = freq_table + (k * freq_table_size);
332 clkp->freq_table[nr_divs].frequency = CPUFREQ_TABLE_END;
429 333
430 map = kzalloc(sizeof(struct clk_mapping), GFP_KERNEL); 334 ret = clk_register(clkp);
431 if (!map) { 335 }
432 pr_err("%s: unable to alloc memory\n", __func__);
433 return -ENOMEM;
434 }
435 336
436 /* clks[i].enable_reg came from SH_CLK_FSIDIV() */ 337 return ret;
437 map->phys = (phys_addr_t)clks[i].enable_reg; 338}
438 map->len = 8;
439 339
440 clks[i].enable_reg = 0; /* remove .enable_reg */ 340int __init sh_clk_div4_register(struct clk *clks, int nr,
441 clks[i].ops = &fsidiv_clk_ops; 341 struct clk_div4_table *table)
442 clks[i].mapping = map; 342{
343 return sh_clk_div4_register_ops(clks, nr, table, &sh_clk_div4_clk_ops);
344}
443 345
444 clk_register(&clks[i]); 346int __init sh_clk_div4_enable_register(struct clk *clks, int nr,
445 } 347 struct clk_div4_table *table)
348{
349 return sh_clk_div4_register_ops(clks, nr, table,
350 &sh_clk_div4_enable_clk_ops);
351}
446 352
447 return 0; 353int __init sh_clk_div4_reparent_register(struct clk *clks, int nr,
354 struct clk_div4_table *table)
355{
356 return sh_clk_div4_register_ops(clks, nr, table,
357 &sh_clk_div4_reparent_clk_ops);
448} 358}
diff --git a/drivers/sh/intc/Kconfig b/drivers/sh/intc/Kconfig
index a305731742a..c88cbccc62b 100644
--- a/drivers/sh/intc/Kconfig
+++ b/drivers/sh/intc/Kconfig
@@ -1,7 +1,3 @@
1config SH_INTC
2 def_bool y
3 select IRQ_DOMAIN
4
5comment "Interrupt controller options" 1comment "Interrupt controller options"
6 2
7config INTC_USERIMASK 3config INTC_USERIMASK
diff --git a/drivers/sh/intc/Makefile b/drivers/sh/intc/Makefile
index 54ec2a0643d..bb5df868d77 100644
--- a/drivers/sh/intc/Makefile
+++ b/drivers/sh/intc/Makefile
@@ -1,4 +1,4 @@
1obj-y := access.o chip.o core.o handle.o irqdomain.o virq.o 1obj-y := access.o chip.o core.o dynamic.o handle.o virq.o
2 2
3obj-$(CONFIG_INTC_BALANCING) += balancing.o 3obj-$(CONFIG_INTC_BALANCING) += balancing.o
4obj-$(CONFIG_INTC_USERIMASK) += userimask.o 4obj-$(CONFIG_INTC_USERIMASK) += userimask.o
diff --git a/drivers/sh/intc/access.c b/drivers/sh/intc/access.c
index 114390f967d..f892ae1d212 100644
--- a/drivers/sh/intc/access.c
+++ b/drivers/sh/intc/access.c
@@ -75,61 +75,54 @@ unsigned long intc_get_field_from_handle(unsigned int value, unsigned int handle
75static unsigned long test_8(unsigned long addr, unsigned long h, 75static unsigned long test_8(unsigned long addr, unsigned long h,
76 unsigned long ignore) 76 unsigned long ignore)
77{ 77{
78 void __iomem *ptr = (void __iomem *)addr; 78 return intc_get_field_from_handle(__raw_readb(addr), h);
79 return intc_get_field_from_handle(__raw_readb(ptr), h);
80} 79}
81 80
82static unsigned long test_16(unsigned long addr, unsigned long h, 81static unsigned long test_16(unsigned long addr, unsigned long h,
83 unsigned long ignore) 82 unsigned long ignore)
84{ 83{
85 void __iomem *ptr = (void __iomem *)addr; 84 return intc_get_field_from_handle(__raw_readw(addr), h);
86 return intc_get_field_from_handle(__raw_readw(ptr), h);
87} 85}
88 86
89static unsigned long test_32(unsigned long addr, unsigned long h, 87static unsigned long test_32(unsigned long addr, unsigned long h,
90 unsigned long ignore) 88 unsigned long ignore)
91{ 89{
92 void __iomem *ptr = (void __iomem *)addr; 90 return intc_get_field_from_handle(__raw_readl(addr), h);
93 return intc_get_field_from_handle(__raw_readl(ptr), h);
94} 91}
95 92
96static unsigned long write_8(unsigned long addr, unsigned long h, 93static unsigned long write_8(unsigned long addr, unsigned long h,
97 unsigned long data) 94 unsigned long data)
98{ 95{
99 void __iomem *ptr = (void __iomem *)addr; 96 __raw_writeb(intc_set_field_from_handle(0, data, h), addr);
100 __raw_writeb(intc_set_field_from_handle(0, data, h), ptr); 97 (void)__raw_readb(addr); /* Defeat write posting */
101 (void)__raw_readb(ptr); /* Defeat write posting */
102 return 0; 98 return 0;
103} 99}
104 100
105static unsigned long write_16(unsigned long addr, unsigned long h, 101static unsigned long write_16(unsigned long addr, unsigned long h,
106 unsigned long data) 102 unsigned long data)
107{ 103{
108 void __iomem *ptr = (void __iomem *)addr; 104 __raw_writew(intc_set_field_from_handle(0, data, h), addr);
109 __raw_writew(intc_set_field_from_handle(0, data, h), ptr); 105 (void)__raw_readw(addr); /* Defeat write posting */
110 (void)__raw_readw(ptr); /* Defeat write posting */
111 return 0; 106 return 0;
112} 107}
113 108
114static unsigned long write_32(unsigned long addr, unsigned long h, 109static unsigned long write_32(unsigned long addr, unsigned long h,
115 unsigned long data) 110 unsigned long data)
116{ 111{
117 void __iomem *ptr = (void __iomem *)addr; 112 __raw_writel(intc_set_field_from_handle(0, data, h), addr);
118 __raw_writel(intc_set_field_from_handle(0, data, h), ptr); 113 (void)__raw_readl(addr); /* Defeat write posting */
119 (void)__raw_readl(ptr); /* Defeat write posting */
120 return 0; 114 return 0;
121} 115}
122 116
123static unsigned long modify_8(unsigned long addr, unsigned long h, 117static unsigned long modify_8(unsigned long addr, unsigned long h,
124 unsigned long data) 118 unsigned long data)
125{ 119{
126 void __iomem *ptr = (void __iomem *)addr;
127 unsigned long flags; 120 unsigned long flags;
128 unsigned int value; 121 unsigned int value;
129 local_irq_save(flags); 122 local_irq_save(flags);
130 value = intc_set_field_from_handle(__raw_readb(ptr), data, h); 123 value = intc_set_field_from_handle(__raw_readb(addr), data, h);
131 __raw_writeb(value, ptr); 124 __raw_writeb(value, addr);
132 (void)__raw_readb(ptr); /* Defeat write posting */ 125 (void)__raw_readb(addr); /* Defeat write posting */
133 local_irq_restore(flags); 126 local_irq_restore(flags);
134 return 0; 127 return 0;
135} 128}
@@ -137,13 +130,12 @@ static unsigned long modify_8(unsigned long addr, unsigned long h,
137static unsigned long modify_16(unsigned long addr, unsigned long h, 130static unsigned long modify_16(unsigned long addr, unsigned long h,
138 unsigned long data) 131 unsigned long data)
139{ 132{
140 void __iomem *ptr = (void __iomem *)addr;
141 unsigned long flags; 133 unsigned long flags;
142 unsigned int value; 134 unsigned int value;
143 local_irq_save(flags); 135 local_irq_save(flags);
144 value = intc_set_field_from_handle(__raw_readw(ptr), data, h); 136 value = intc_set_field_from_handle(__raw_readw(addr), data, h);
145 __raw_writew(value, ptr); 137 __raw_writew(value, addr);
146 (void)__raw_readw(ptr); /* Defeat write posting */ 138 (void)__raw_readw(addr); /* Defeat write posting */
147 local_irq_restore(flags); 139 local_irq_restore(flags);
148 return 0; 140 return 0;
149} 141}
@@ -151,13 +143,12 @@ static unsigned long modify_16(unsigned long addr, unsigned long h,
151static unsigned long modify_32(unsigned long addr, unsigned long h, 143static unsigned long modify_32(unsigned long addr, unsigned long h,
152 unsigned long data) 144 unsigned long data)
153{ 145{
154 void __iomem *ptr = (void __iomem *)addr;
155 unsigned long flags; 146 unsigned long flags;
156 unsigned int value; 147 unsigned int value;
157 local_irq_save(flags); 148 local_irq_save(flags);
158 value = intc_set_field_from_handle(__raw_readl(ptr), data, h); 149 value = intc_set_field_from_handle(__raw_readl(addr), data, h);
159 __raw_writel(value, ptr); 150 __raw_writel(value, addr);
160 (void)__raw_readl(ptr); /* Defeat write posting */ 151 (void)__raw_readl(addr); /* Defeat write posting */
161 local_irq_restore(flags); 152 local_irq_restore(flags);
162 return 0; 153 return 0;
163} 154}
diff --git a/drivers/sh/intc/balancing.c b/drivers/sh/intc/balancing.c
index bc780807ccb..cec7a96f2c0 100644
--- a/drivers/sh/intc/balancing.c
+++ b/drivers/sh/intc/balancing.c
@@ -9,7 +9,7 @@
9 */ 9 */
10#include "internals.h" 10#include "internals.h"
11 11
12static unsigned long dist_handle[INTC_NR_IRQS]; 12static unsigned long dist_handle[NR_IRQS];
13 13
14void intc_balancing_enable(unsigned int irq) 14void intc_balancing_enable(unsigned int irq)
15{ 15{
diff --git a/drivers/sh/intc/chip.c b/drivers/sh/intc/chip.c
index 46427b48e2f..33b2ed451e0 100644
--- a/drivers/sh/intc/chip.c
+++ b/drivers/sh/intc/chip.c
@@ -2,14 +2,13 @@
2 * IRQ chip definitions for INTC IRQs. 2 * IRQ chip definitions for INTC IRQs.
3 * 3 *
4 * Copyright (C) 2007, 2008 Magnus Damm 4 * Copyright (C) 2007, 2008 Magnus Damm
5 * Copyright (C) 2009 - 2012 Paul Mundt 5 * Copyright (C) 2009, 2010 Paul Mundt
6 * 6 *
7 * This file is subject to the terms and conditions of the GNU General Public 7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive 8 * License. See the file "COPYING" in the main directory of this archive
9 * for more details. 9 * for more details.
10 */ 10 */
11#include <linux/cpumask.h> 11#include <linux/cpumask.h>
12#include <linux/bsearch.h>
13#include <linux/io.h> 12#include <linux/io.h>
14#include "internals.h" 13#include "internals.h"
15 14
@@ -59,6 +58,11 @@ static void intc_disable(struct irq_data *data)
59 } 58 }
60} 59}
61 60
61static int intc_set_wake(struct irq_data *data, unsigned int on)
62{
63 return 0; /* allow wakeup, but setup hardware in intc_suspend() */
64}
65
62#ifdef CONFIG_SMP 66#ifdef CONFIG_SMP
63/* 67/*
64 * This is held with the irq desc lock held, so we don't require any 68 * This is held with the irq desc lock held, so we don't require any
@@ -74,7 +78,7 @@ static int intc_set_affinity(struct irq_data *data,
74 78
75 cpumask_copy(data->affinity, cpumask); 79 cpumask_copy(data->affinity, cpumask);
76 80
77 return IRQ_SET_MASK_OK_NOCOPY; 81 return 0;
78} 82}
79#endif 83#endif
80 84
@@ -83,7 +87,7 @@ static void intc_mask_ack(struct irq_data *data)
83 unsigned int irq = data->irq; 87 unsigned int irq = data->irq;
84 struct intc_desc_int *d = get_intc_desc(irq); 88 struct intc_desc_int *d = get_intc_desc(irq);
85 unsigned long handle = intc_get_ack_handle(irq); 89 unsigned long handle = intc_get_ack_handle(irq);
86 void __iomem *addr; 90 unsigned long addr;
87 91
88 intc_disable(data); 92 intc_disable(data);
89 93
@@ -91,7 +95,7 @@ static void intc_mask_ack(struct irq_data *data)
91 if (handle) { 95 if (handle) {
92 unsigned int value; 96 unsigned int value;
93 97
94 addr = (void __iomem *)INTC_REG(d, _INTC_ADDR_D(handle), 0); 98 addr = INTC_REG(d, _INTC_ADDR_D(handle), 0);
95 value = intc_set_field_from_handle(0, 1, handle); 99 value = intc_set_field_from_handle(0, 1, handle);
96 100
97 switch (_INTC_FN(handle)) { 101 switch (_INTC_FN(handle)) {
@@ -118,12 +122,28 @@ static struct intc_handle_int *intc_find_irq(struct intc_handle_int *hp,
118 unsigned int nr_hp, 122 unsigned int nr_hp,
119 unsigned int irq) 123 unsigned int irq)
120{ 124{
121 struct intc_handle_int key; 125 int i;
126
127 /*
128 * this doesn't scale well, but...
129 *
130 * this function should only be used for cerain uncommon
131 * operations such as intc_set_priority() and intc_set_type()
132 * and in those rare cases performance doesn't matter that much.
133 * keeping the memory footprint low is more important.
134 *
135 * one rather simple way to speed this up and still keep the
136 * memory footprint down is to make sure the array is sorted
137 * and then perform a bisect to lookup the irq.
138 */
139 for (i = 0; i < nr_hp; i++) {
140 if ((hp + i)->irq != irq)
141 continue;
122 142
123 key.irq = irq; 143 return hp + i;
124 key.handle = 0; 144 }
125 145
126 return bsearch(&key, hp, nr_hp, sizeof(*hp), intc_handle_int_cmp); 146 return NULL;
127} 147}
128 148
129int intc_set_priority(unsigned int irq, unsigned int prio) 149int intc_set_priority(unsigned int irq, unsigned int prio)
@@ -166,7 +186,7 @@ static unsigned char intc_irq_sense_table[IRQ_TYPE_SENSE_MASK + 1] = {
166 !defined(CONFIG_CPU_SUBTYPE_SH7709) 186 !defined(CONFIG_CPU_SUBTYPE_SH7709)
167 [IRQ_TYPE_LEVEL_HIGH] = VALID(3), 187 [IRQ_TYPE_LEVEL_HIGH] = VALID(3),
168#endif 188#endif
169#if defined(CONFIG_ARM) /* all recent SH-Mobile / R-Mobile ARM support this */ 189#if defined(CONFIG_ARCH_SH7372)
170 [IRQ_TYPE_EDGE_BOTH] = VALID(4), 190 [IRQ_TYPE_EDGE_BOTH] = VALID(4),
171#endif 191#endif
172}; 192};
@@ -182,16 +202,11 @@ static int intc_set_type(struct irq_data *data, unsigned int type)
182 if (!value) 202 if (!value)
183 return -EINVAL; 203 return -EINVAL;
184 204
185 value &= ~SENSE_VALID_FLAG;
186
187 ihp = intc_find_irq(d->sense, d->nr_sense, irq); 205 ihp = intc_find_irq(d->sense, d->nr_sense, irq);
188 if (ihp) { 206 if (ihp) {
189 /* PINT has 2-bit sense registers, should fail on EDGE_BOTH */
190 if (value >= (1 << _INTC_WIDTH(ihp->handle)))
191 return -EINVAL;
192
193 addr = INTC_REG(d, _INTC_ADDR_E(ihp->handle), 0); 207 addr = INTC_REG(d, _INTC_ADDR_E(ihp->handle), 0);
194 intc_reg_fns[_INTC_FN(ihp->handle)](addr, ihp->handle, value); 208 intc_reg_fns[_INTC_FN(ihp->handle)](addr, ihp->handle,
209 value & ~SENSE_VALID_FLAG);
195 } 210 }
196 211
197 return 0; 212 return 0;
@@ -203,9 +218,10 @@ struct irq_chip intc_irq_chip = {
203 .irq_mask_ack = intc_mask_ack, 218 .irq_mask_ack = intc_mask_ack,
204 .irq_enable = intc_enable, 219 .irq_enable = intc_enable,
205 .irq_disable = intc_disable, 220 .irq_disable = intc_disable,
221 .irq_shutdown = intc_disable,
206 .irq_set_type = intc_set_type, 222 .irq_set_type = intc_set_type,
223 .irq_set_wake = intc_set_wake,
207#ifdef CONFIG_SMP 224#ifdef CONFIG_SMP
208 .irq_set_affinity = intc_set_affinity, 225 .irq_set_affinity = intc_set_affinity,
209#endif 226#endif
210 .flags = IRQCHIP_SKIP_SET_WAKE,
211}; 227};
diff --git a/drivers/sh/intc/core.c b/drivers/sh/intc/core.c
index 8f32a1323a7..c6ca115c71d 100644
--- a/drivers/sh/intc/core.c
+++ b/drivers/sh/intc/core.c
@@ -2,7 +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 - 2012 Paul Mundt 5 * Copyright (C) 2009, 2010 Paul Mundt
6 * 6 *
7 * Based on intc2.c and ipr.c 7 * Based on intc2.c and ipr.c
8 * 8 *
@@ -22,29 +22,25 @@
22#include <linux/irq.h> 22#include <linux/irq.h>
23#include <linux/io.h> 23#include <linux/io.h>
24#include <linux/slab.h> 24#include <linux/slab.h>
25#include <linux/stat.h>
26#include <linux/interrupt.h> 25#include <linux/interrupt.h>
27#include <linux/sh_intc.h> 26#include <linux/sh_intc.h>
28#include <linux/irqdomain.h> 27#include <linux/sysdev.h>
29#include <linux/device.h>
30#include <linux/syscore_ops.h> 28#include <linux/syscore_ops.h>
31#include <linux/list.h> 29#include <linux/list.h>
32#include <linux/spinlock.h> 30#include <linux/spinlock.h>
33#include <linux/radix-tree.h> 31#include <linux/radix-tree.h>
34#include <linux/export.h>
35#include <linux/sort.h>
36#include "internals.h" 32#include "internals.h"
37 33
38LIST_HEAD(intc_list); 34LIST_HEAD(intc_list);
39DEFINE_RAW_SPINLOCK(intc_big_lock); 35DEFINE_RAW_SPINLOCK(intc_big_lock);
40static unsigned int nr_intc_controllers; 36unsigned int nr_intc_controllers;
41 37
42/* 38/*
43 * Default priority level 39 * Default priority level
44 * - this needs to be at least 2 for 5-bit priorities on 7780 40 * - this needs to be at least 2 for 5-bit priorities on 7780
45 */ 41 */
46static unsigned int default_prio_level = 2; /* 2 - 16 */ 42static unsigned int default_prio_level = 2; /* 2 - 16 */
47static unsigned int intc_prio_level[INTC_NR_IRQS]; /* for now */ 43static unsigned int intc_prio_level[NR_IRQS]; /* for now */
48 44
49unsigned int intc_get_dfl_prio_level(void) 45unsigned int intc_get_dfl_prio_level(void)
50{ 46{
@@ -269,9 +265,6 @@ int __init register_intc_controller(struct intc_desc *desc)
269 k += save_reg(d, k, hw->prio_regs[i].set_reg, smp); 265 k += save_reg(d, k, hw->prio_regs[i].set_reg, smp);
270 k += save_reg(d, k, hw->prio_regs[i].clr_reg, smp); 266 k += save_reg(d, k, hw->prio_regs[i].clr_reg, smp);
271 } 267 }
272
273 sort(d->prio, hw->nr_prio_regs, sizeof(*d->prio),
274 intc_handle_int_cmp, NULL);
275 } 268 }
276 269
277 if (hw->sense_regs) { 270 if (hw->sense_regs) {
@@ -282,9 +275,6 @@ int __init register_intc_controller(struct intc_desc *desc)
282 275
283 for (i = 0; i < hw->nr_sense_regs; i++) 276 for (i = 0; i < hw->nr_sense_regs; i++)
284 k += save_reg(d, k, hw->sense_regs[i].reg, 0); 277 k += save_reg(d, k, hw->sense_regs[i].reg, 0);
285
286 sort(d->sense, hw->nr_sense_regs, sizeof(*d->sense),
287 intc_handle_int_cmp, NULL);
288 } 278 }
289 279
290 if (hw->subgroups) 280 if (hw->subgroups)
@@ -311,8 +301,6 @@ int __init register_intc_controller(struct intc_desc *desc)
311 301
312 BUG_ON(k > 256); /* _INTC_ADDR_E() and _INTC_ADDR_D() are 8 bits */ 302 BUG_ON(k > 256); /* _INTC_ADDR_E() and _INTC_ADDR_D() are 8 bits */
313 303
314 intc_irq_domain_init(d, hw);
315
316 /* register the vectors one by one */ 304 /* register the vectors one by one */
317 for (i = 0; i < hw->nr_vectors; i++) { 305 for (i = 0; i < hw->nr_vectors; i++) {
318 struct intc_vect *vect = hw->vectors + i; 306 struct intc_vect *vect = hw->vectors + i;
@@ -322,18 +310,10 @@ int __init register_intc_controller(struct intc_desc *desc)
322 if (!vect->enum_id) 310 if (!vect->enum_id)
323 continue; 311 continue;
324 312
325 res = irq_create_identity_mapping(d->domain, irq); 313 res = irq_alloc_desc_at(irq, numa_node_id());
326 if (unlikely(res)) { 314 if (res != irq && res != -EEXIST) {
327 if (res == -EEXIST) { 315 pr_err("can't get irq_desc for %d\n", irq);
328 res = irq_domain_associate(d->domain, irq, irq); 316 continue;
329 if (unlikely(res)) {
330 pr_err("domain association failure\n");
331 continue;
332 }
333 } else {
334 pr_err("can't identity map IRQ %d\n", irq);
335 continue;
336 }
337 } 317 }
338 318
339 intc_irq_xlate_set(irq, vect->enum_id, d); 319 intc_irq_xlate_set(irq, vect->enum_id, d);
@@ -351,21 +331,10 @@ int __init register_intc_controller(struct intc_desc *desc)
351 * IRQ support, each vector still needs to have 331 * IRQ support, each vector still needs to have
352 * its own backing irq_desc. 332 * its own backing irq_desc.
353 */ 333 */
354 res = irq_create_identity_mapping(d->domain, irq2); 334 res = irq_alloc_desc_at(irq2, numa_node_id());
355 if (unlikely(res)) { 335 if (res != irq2 && res != -EEXIST) {
356 if (res == -EEXIST) { 336 pr_err("can't get irq_desc for %d\n", irq2);
357 res = irq_domain_associate(d->domain, 337 continue;
358 irq2, irq2);
359 if (unlikely(res)) {
360 pr_err("domain association "
361 "failure\n");
362 continue;
363 }
364 } else {
365 pr_err("can't identity map IRQ %d\n",
366 irq);
367 continue;
368 }
369 } 338 }
370 339
371 vect2->enum_id = 0; 340 vect2->enum_id = 0;
@@ -383,8 +352,6 @@ int __init register_intc_controller(struct intc_desc *desc)
383 if (desc->force_enable) 352 if (desc->force_enable)
384 intc_enable_disable_enum(desc, d, desc->force_enable, 1); 353 intc_enable_disable_enum(desc, d, desc->force_enable, 1);
385 354
386 d->skip_suspend = desc->skip_syscore_suspend;
387
388 nr_intc_controllers++; 355 nr_intc_controllers++;
389 356
390 return 0; 357 return 0;
@@ -417,9 +384,6 @@ static int intc_suspend(void)
417 list_for_each_entry(d, &intc_list, list) { 384 list_for_each_entry(d, &intc_list, list) {
418 int irq; 385 int irq;
419 386
420 if (d->skip_suspend)
421 continue;
422
423 /* enable wakeup irqs belonging to this intc controller */ 387 /* enable wakeup irqs belonging to this intc controller */
424 for_each_active_irq(irq) { 388 for_each_active_irq(irq) {
425 struct irq_data *data; 389 struct irq_data *data;
@@ -443,9 +407,6 @@ static void intc_resume(void)
443 list_for_each_entry(d, &intc_list, list) { 407 list_for_each_entry(d, &intc_list, list) {
444 int irq; 408 int irq;
445 409
446 if (d->skip_suspend)
447 continue;
448
449 for_each_active_irq(irq) { 410 for_each_active_irq(irq) {
450 struct irq_data *data; 411 struct irq_data *data;
451 struct irq_chip *chip; 412 struct irq_chip *chip;
@@ -471,47 +432,46 @@ struct syscore_ops intc_syscore_ops = {
471 .resume = intc_resume, 432 .resume = intc_resume,
472}; 433};
473 434
474struct bus_type intc_subsys = { 435struct sysdev_class intc_sysdev_class = {
475 .name = "intc", 436 .name = "intc",
476 .dev_name = "intc",
477}; 437};
478 438
479static ssize_t 439static ssize_t
480show_intc_name(struct device *dev, struct device_attribute *attr, char *buf) 440show_intc_name(struct sys_device *dev, struct sysdev_attribute *attr, char *buf)
481{ 441{
482 struct intc_desc_int *d; 442 struct intc_desc_int *d;
483 443
484 d = container_of(dev, struct intc_desc_int, dev); 444 d = container_of(dev, struct intc_desc_int, sysdev);
485 445
486 return sprintf(buf, "%s\n", d->chip.name); 446 return sprintf(buf, "%s\n", d->chip.name);
487} 447}
488 448
489static DEVICE_ATTR(name, S_IRUGO, show_intc_name, NULL); 449static SYSDEV_ATTR(name, S_IRUGO, show_intc_name, NULL);
490 450
491static int __init register_intc_devs(void) 451static int __init register_intc_sysdevs(void)
492{ 452{
493 struct intc_desc_int *d; 453 struct intc_desc_int *d;
494 int error; 454 int error;
495 455
496 register_syscore_ops(&intc_syscore_ops); 456 register_syscore_ops(&intc_syscore_ops);
497 457
498 error = subsys_system_register(&intc_subsys, NULL); 458 error = sysdev_class_register(&intc_sysdev_class);
499 if (!error) { 459 if (!error) {
500 list_for_each_entry(d, &intc_list, list) { 460 list_for_each_entry(d, &intc_list, list) {
501 d->dev.id = d->index; 461 d->sysdev.id = d->index;
502 d->dev.bus = &intc_subsys; 462 d->sysdev.cls = &intc_sysdev_class;
503 error = device_register(&d->dev); 463 error = sysdev_register(&d->sysdev);
504 if (error == 0) 464 if (error == 0)
505 error = device_create_file(&d->dev, 465 error = sysdev_create_file(&d->sysdev,
506 &dev_attr_name); 466 &attr_name);
507 if (error) 467 if (error)
508 break; 468 break;
509 } 469 }
510 } 470 }
511 471
512 if (error) 472 if (error)
513 pr_err("device registration error\n"); 473 pr_err("sysdev registration error\n");
514 474
515 return error; 475 return error;
516} 476}
517device_initcall(register_intc_devs); 477device_initcall(register_intc_sysdevs);
diff --git a/drivers/sh/intc/handle.c b/drivers/sh/intc/handle.c
index 7863a44918a..057ce56829b 100644
--- a/drivers/sh/intc/handle.c
+++ b/drivers/sh/intc/handle.c
@@ -13,7 +13,7 @@
13#include <linux/spinlock.h> 13#include <linux/spinlock.h>
14#include "internals.h" 14#include "internals.h"
15 15
16static unsigned long ack_handle[INTC_NR_IRQS]; 16static unsigned long ack_handle[NR_IRQS];
17 17
18static intc_enum __init intc_grp_id(struct intc_desc *desc, 18static intc_enum __init intc_grp_id(struct intc_desc *desc,
19 intc_enum enum_id) 19 intc_enum enum_id)
@@ -172,8 +172,9 @@ intc_get_prio_handle(struct intc_desc *desc, struct intc_desc_int *d,
172 return 0; 172 return 0;
173} 173}
174 174
175static unsigned int intc_ack_data(struct intc_desc *desc, 175static unsigned int __init intc_ack_data(struct intc_desc *desc,
176 struct intc_desc_int *d, intc_enum enum_id) 176 struct intc_desc_int *d,
177 intc_enum enum_id)
177{ 178{
178 struct intc_mask_reg *mr = desc->hw.ack_regs; 179 struct intc_mask_reg *mr = desc->hw.ack_regs;
179 unsigned int i, j, fn, mode; 180 unsigned int i, j, fn, mode;
diff --git a/drivers/sh/intc/internals.h b/drivers/sh/intc/internals.h
index 7dff08e2a07..5b934851efa 100644
--- a/drivers/sh/intc/internals.h
+++ b/drivers/sh/intc/internals.h
@@ -1,11 +1,10 @@
1#include <linux/sh_intc.h> 1#include <linux/sh_intc.h>
2#include <linux/irq.h> 2#include <linux/irq.h>
3#include <linux/irqdomain.h>
4#include <linux/list.h> 3#include <linux/list.h>
5#include <linux/kernel.h> 4#include <linux/kernel.h>
6#include <linux/types.h> 5#include <linux/types.h>
7#include <linux/radix-tree.h> 6#include <linux/radix-tree.h>
8#include <linux/device.h> 7#include <linux/sysdev.h>
9 8
10#define _INTC_MK(fn, mode, addr_e, addr_d, width, shift) \ 9#define _INTC_MK(fn, mode, addr_e, addr_d, width, shift) \
11 ((shift) | ((width) << 5) | ((fn) << 9) | ((mode) << 13) | \ 10 ((shift) | ((width) << 5) | ((fn) << 9) | ((mode) << 13) | \
@@ -52,7 +51,7 @@ struct intc_subgroup_entry {
52 51
53struct intc_desc_int { 52struct intc_desc_int {
54 struct list_head list; 53 struct list_head list;
55 struct device dev; 54 struct sys_device sysdev;
56 struct radix_tree_root tree; 55 struct radix_tree_root tree;
57 raw_spinlock_t lock; 56 raw_spinlock_t lock;
58 unsigned int index; 57 unsigned int index;
@@ -67,9 +66,7 @@ struct intc_desc_int {
67 unsigned int nr_sense; 66 unsigned int nr_sense;
68 struct intc_window *window; 67 struct intc_window *window;
69 unsigned int nr_windows; 68 unsigned int nr_windows;
70 struct irq_domain *domain;
71 struct irq_chip chip; 69 struct irq_chip chip;
72 bool skip_suspend;
73}; 70};
74 71
75 72
@@ -110,14 +107,6 @@ static inline void activate_irq(int irq)
110#endif 107#endif
111} 108}
112 109
113static inline int intc_handle_int_cmp(const void *a, const void *b)
114{
115 const struct intc_handle_int *_a = a;
116 const struct intc_handle_int *_b = b;
117
118 return _a->irq - _b->irq;
119}
120
121/* access.c */ 110/* access.c */
122extern unsigned long 111extern unsigned long
123(*intc_reg_fns[])(unsigned long addr, unsigned long h, unsigned long data); 112(*intc_reg_fns[])(unsigned long addr, unsigned long h, unsigned long data);
@@ -167,7 +156,8 @@ void _intc_enable(struct irq_data *data, unsigned long handle);
167/* core.c */ 156/* core.c */
168extern struct list_head intc_list; 157extern struct list_head intc_list;
169extern raw_spinlock_t intc_big_lock; 158extern raw_spinlock_t intc_big_lock;
170extern struct bus_type intc_subsys; 159extern unsigned int nr_intc_controllers;
160extern struct sysdev_class intc_sysdev_class;
171 161
172unsigned int intc_get_dfl_prio_level(void); 162unsigned int intc_get_dfl_prio_level(void);
173unsigned int intc_get_prio_level(unsigned int irq); 163unsigned int intc_get_prio_level(unsigned int irq);
@@ -189,9 +179,6 @@ unsigned long intc_get_ack_handle(unsigned int irq);
189void intc_enable_disable_enum(struct intc_desc *desc, struct intc_desc_int *d, 179void intc_enable_disable_enum(struct intc_desc *desc, struct intc_desc_int *d,
190 intc_enum enum_id, int enable); 180 intc_enum enum_id, int enable);
191 181
192/* irqdomain.c */
193void intc_irq_domain_init(struct intc_desc_int *d, struct intc_hw_desc *hw);
194
195/* virq.c */ 182/* virq.c */
196void intc_subgroup_init(struct intc_desc *desc, struct intc_desc_int *d); 183void intc_subgroup_init(struct intc_desc *desc, struct intc_desc_int *d);
197void intc_irq_xlate_set(unsigned int irq, intc_enum id, struct intc_desc_int *d); 184void intc_irq_xlate_set(unsigned int irq, intc_enum id, struct intc_desc_int *d);
diff --git a/drivers/sh/intc/irqdomain.c b/drivers/sh/intc/irqdomain.c
deleted file mode 100644
index 3968f1c3c5c..00000000000
--- a/drivers/sh/intc/irqdomain.c
+++ /dev/null
@@ -1,68 +0,0 @@
1/*
2 * IRQ domain support for SH INTC subsystem
3 *
4 * Copyright (C) 2012 Paul Mundt
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#define pr_fmt(fmt) "intc: " fmt
11
12#include <linux/irqdomain.h>
13#include <linux/sh_intc.h>
14#include <linux/export.h>
15#include "internals.h"
16
17/**
18 * intc_irq_domain_evt_xlate() - Generic xlate for vectored IRQs.
19 *
20 * This takes care of exception vector to hwirq translation through
21 * by way of evt2irq() translation.
22 *
23 * Note: For platforms that use a flat vector space without INTEVT this
24 * basically just mimics irq_domain_xlate_onecell() by way of a nopped
25 * out evt2irq() implementation.
26 */
27static int intc_evt_xlate(struct irq_domain *d, struct device_node *ctrlr,
28 const u32 *intspec, unsigned int intsize,
29 unsigned long *out_hwirq, unsigned int *out_type)
30{
31 if (WARN_ON(intsize < 1))
32 return -EINVAL;
33
34 *out_hwirq = evt2irq(intspec[0]);
35 *out_type = IRQ_TYPE_NONE;
36
37 return 0;
38}
39
40static const struct irq_domain_ops intc_evt_ops = {
41 .xlate = intc_evt_xlate,
42};
43
44void __init intc_irq_domain_init(struct intc_desc_int *d,
45 struct intc_hw_desc *hw)
46{
47 unsigned int irq_base, irq_end;
48
49 /*
50 * Quick linear revmap check
51 */
52 irq_base = evt2irq(hw->vectors[0].vect);
53 irq_end = evt2irq(hw->vectors[hw->nr_vectors - 1].vect);
54
55 /*
56 * Linear domains have a hard-wired assertion that IRQs start at
57 * 0 in order to make some performance optimizations. Lamely
58 * restrict the linear case to these conditions here, taking the
59 * tree penalty for linear cases with non-zero hwirq bases.
60 */
61 if (irq_base == 0 && irq_end == (irq_base + hw->nr_vectors - 1))
62 d->domain = irq_domain_add_linear(NULL, hw->nr_vectors,
63 &intc_evt_ops, NULL);
64 else
65 d->domain = irq_domain_add_tree(NULL, &intc_evt_ops, NULL);
66
67 BUG_ON(!d->domain);
68}
diff --git a/drivers/sh/intc/userimask.c b/drivers/sh/intc/userimask.c
index e649ceaaa41..e32304b66cf 100644
--- a/drivers/sh/intc/userimask.c
+++ b/drivers/sh/intc/userimask.c
@@ -10,25 +10,24 @@
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/device.h> 13#include <linux/sysdev.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>
17#include <asm/sizes.h> 16#include <asm/sizes.h>
18#include "internals.h" 17#include "internals.h"
19 18
20static void __iomem *uimask; 19static void __iomem *uimask;
21 20
22static ssize_t 21static ssize_t
23show_intc_userimask(struct device *dev, 22show_intc_userimask(struct sysdev_class *cls,
24 struct device_attribute *attr, char *buf) 23 struct sysdev_class_attribute *attr, char *buf)
25{ 24{
26 return sprintf(buf, "%d\n", (__raw_readl(uimask) >> 4) & 0xf); 25 return sprintf(buf, "%d\n", (__raw_readl(uimask) >> 4) & 0xf);
27} 26}
28 27
29static ssize_t 28static ssize_t
30store_intc_userimask(struct device *dev, 29store_intc_userimask(struct sysdev_class *cls,
31 struct device_attribute *attr, 30 struct sysdev_class_attribute *attr,
32 const char *buf, size_t count) 31 const char *buf, size_t count)
33{ 32{
34 unsigned long level; 33 unsigned long level;
@@ -55,8 +54,8 @@ store_intc_userimask(struct device *dev,
55 return count; 54 return count;
56} 55}
57 56
58static DEVICE_ATTR(userimask, S_IRUSR | S_IWUSR, 57static SYSDEV_CLASS_ATTR(userimask, S_IRUSR | S_IWUSR,
59 show_intc_userimask, store_intc_userimask); 58 show_intc_userimask, store_intc_userimask);
60 59
61 60
62static int __init userimask_sysdev_init(void) 61static int __init userimask_sysdev_init(void)
@@ -64,7 +63,7 @@ static int __init userimask_sysdev_init(void)
64 if (unlikely(!uimask)) 63 if (unlikely(!uimask))
65 return -ENXIO; 64 return -ENXIO;
66 65
67 return device_create_file(intc_subsys.dev_root, &dev_attr_userimask); 66 return sysdev_class_create_file(&intc_sysdev_class, &attr_userimask);
68} 67}
69late_initcall(userimask_sysdev_init); 68late_initcall(userimask_sysdev_init);
70 69
diff --git a/drivers/sh/intc/virq.c b/drivers/sh/intc/virq.c
index f30ac9354ff..1e6e2d0353e 100644
--- a/drivers/sh/intc/virq.c
+++ b/drivers/sh/intc/virq.c
@@ -14,10 +14,9 @@
14#include <linux/list.h> 14#include <linux/list.h>
15#include <linux/radix-tree.h> 15#include <linux/radix-tree.h>
16#include <linux/spinlock.h> 16#include <linux/spinlock.h>
17#include <linux/export.h>
18#include "internals.h" 17#include "internals.h"
19 18
20static struct intc_map_entry intc_irq_xlate[INTC_NR_IRQS]; 19static struct intc_map_entry intc_irq_xlate[NR_IRQS];
21 20
22struct intc_virq_list { 21struct intc_virq_list {
23 unsigned int irq; 22 unsigned int irq;
@@ -219,14 +218,12 @@ restart:
219 if (radix_tree_deref_retry(entry)) 218 if (radix_tree_deref_retry(entry))
220 goto restart; 219 goto restart;
221 220
222 irq = irq_alloc_desc(numa_node_id()); 221 irq = create_irq();
223 if (unlikely(irq < 0)) { 222 if (unlikely(irq < 0)) {
224 pr_err("no more free IRQs, bailing..\n"); 223 pr_err("no more free IRQs, bailing..\n");
225 break; 224 break;
226 } 225 }
227 226
228 activate_irq(irq);
229
230 pr_info("Setting up a chained VIRQ from %d -> %d\n", 227 pr_info("Setting up a chained VIRQ from %d -> %d\n",
231 irq, entry->pirq); 228 irq, entry->pirq);
232 229
diff --git a/drivers/sh/maple/maple.c b/drivers/sh/maple/maple.c
index bec81c2404f..1e20604257a 100644
--- a/drivers/sh/maple/maple.c
+++ b/drivers/sh/maple/maple.c
@@ -20,7 +20,6 @@
20#include <linux/maple.h> 20#include <linux/maple.h>
21#include <linux/dma-mapping.h> 21#include <linux/dma-mapping.h>
22#include <linux/delay.h> 22#include <linux/delay.h>
23#include <linux/module.h>
24#include <asm/cacheflush.h> 23#include <asm/cacheflush.h>
25#include <asm/dma.h> 24#include <asm/dma.h>
26#include <asm/io.h> 25#include <asm/io.h>
diff --git a/drivers/sh/pfc/Kconfig b/drivers/sh/pfc/Kconfig
deleted file mode 100644
index 804f9ad1bf4..00000000000
--- a/drivers/sh/pfc/Kconfig
+++ /dev/null
@@ -1,26 +0,0 @@
1comment "Pin function controller options"
2
3config SH_PFC
4 # XXX move off the gpio dependency
5 depends on GENERIC_GPIO
6 select GPIO_SH_PFC if ARCH_REQUIRE_GPIOLIB
7 select PINCTRL_SH_PFC
8 def_bool y
9
10#
11# Placeholder for now, rehome to drivers/pinctrl once the PFC APIs
12# have settled.
13#
14config PINCTRL_SH_PFC
15 tristate "SuperH PFC pin controller driver"
16 depends on SH_PFC
17 select PINCTRL
18 select PINMUX
19 select PINCONF
20
21config GPIO_SH_PFC
22 tristate "SuperH PFC GPIO support"
23 depends on SH_PFC && GPIOLIB
24 help
25 This enables support for GPIOs within the SoC's pin function
26 controller.
diff --git a/drivers/sh/pfc/Makefile b/drivers/sh/pfc/Makefile
deleted file mode 100644
index 7916027cce3..00000000000
--- a/drivers/sh/pfc/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
1obj-y += core.o
2obj-$(CONFIG_PINCTRL_SH_PFC) += pinctrl.o
3obj-$(CONFIG_GPIO_SH_PFC) += gpio.o
diff --git a/drivers/sh/pfc/core.c b/drivers/sh/pfc/core.c
deleted file mode 100644
index 68169373c98..00000000000
--- a/drivers/sh/pfc/core.c
+++ /dev/null
@@ -1,572 +0,0 @@
1/*
2 * SuperH Pin Function Controller support.
3 *
4 * Copyright (C) 2008 Magnus Damm
5 * Copyright (C) 2009 - 2012 Paul Mundt
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive
9 * for more details.
10 */
11#define pr_fmt(fmt) "sh_pfc " KBUILD_MODNAME ": " fmt
12
13#include <linux/errno.h>
14#include <linux/kernel.h>
15#include <linux/sh_pfc.h>
16#include <linux/module.h>
17#include <linux/err.h>
18#include <linux/io.h>
19#include <linux/bitops.h>
20#include <linux/slab.h>
21#include <linux/ioport.h>
22#include <linux/pinctrl/machine.h>
23
24static struct sh_pfc *sh_pfc __read_mostly;
25
26static inline bool sh_pfc_initialized(void)
27{
28 return !!sh_pfc;
29}
30
31static void pfc_iounmap(struct sh_pfc *pfc)
32{
33 int k;
34
35 for (k = 0; k < pfc->num_resources; k++)
36 if (pfc->window[k].virt)
37 iounmap(pfc->window[k].virt);
38
39 kfree(pfc->window);
40 pfc->window = NULL;
41}
42
43static int pfc_ioremap(struct sh_pfc *pfc)
44{
45 struct resource *res;
46 int k;
47
48 if (!pfc->num_resources)
49 return 0;
50
51 pfc->window = kzalloc(pfc->num_resources * sizeof(*pfc->window),
52 GFP_NOWAIT);
53 if (!pfc->window)
54 goto err1;
55
56 for (k = 0; k < pfc->num_resources; k++) {
57 res = pfc->resource + k;
58 WARN_ON(resource_type(res) != IORESOURCE_MEM);
59 pfc->window[k].phys = res->start;
60 pfc->window[k].size = resource_size(res);
61 pfc->window[k].virt = ioremap_nocache(res->start,
62 resource_size(res));
63 if (!pfc->window[k].virt)
64 goto err2;
65 }
66
67 return 0;
68
69err2:
70 pfc_iounmap(pfc);
71err1:
72 return -1;
73}
74
75static void __iomem *pfc_phys_to_virt(struct sh_pfc *pfc,
76 unsigned long address)
77{
78 struct pfc_window *window;
79 int k;
80
81 /* scan through physical windows and convert address */
82 for (k = 0; k < pfc->num_resources; k++) {
83 window = pfc->window + k;
84
85 if (address < window->phys)
86 continue;
87
88 if (address >= (window->phys + window->size))
89 continue;
90
91 return window->virt + (address - window->phys);
92 }
93
94 /* no windows defined, register must be 1:1 mapped virt:phys */
95 return (void __iomem *)address;
96}
97
98static int enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r)
99{
100 if (enum_id < r->begin)
101 return 0;
102
103 if (enum_id > r->end)
104 return 0;
105
106 return 1;
107}
108
109static unsigned long gpio_read_raw_reg(void __iomem *mapped_reg,
110 unsigned long reg_width)
111{
112 switch (reg_width) {
113 case 8:
114 return ioread8(mapped_reg);
115 case 16:
116 return ioread16(mapped_reg);
117 case 32:
118 return ioread32(mapped_reg);
119 }
120
121 BUG();
122 return 0;
123}
124
125static void gpio_write_raw_reg(void __iomem *mapped_reg,
126 unsigned long reg_width,
127 unsigned long data)
128{
129 switch (reg_width) {
130 case 8:
131 iowrite8(data, mapped_reg);
132 return;
133 case 16:
134 iowrite16(data, mapped_reg);
135 return;
136 case 32:
137 iowrite32(data, mapped_reg);
138 return;
139 }
140
141 BUG();
142}
143
144int sh_pfc_read_bit(struct pinmux_data_reg *dr, unsigned long in_pos)
145{
146 unsigned long pos;
147
148 pos = dr->reg_width - (in_pos + 1);
149
150 pr_debug("read_bit: addr = %lx, pos = %ld, "
151 "r_width = %ld\n", dr->reg, pos, dr->reg_width);
152
153 return (gpio_read_raw_reg(dr->mapped_reg, dr->reg_width) >> pos) & 1;
154}
155EXPORT_SYMBOL_GPL(sh_pfc_read_bit);
156
157void sh_pfc_write_bit(struct pinmux_data_reg *dr, unsigned long in_pos,
158 unsigned long value)
159{
160 unsigned long pos;
161
162 pos = dr->reg_width - (in_pos + 1);
163
164 pr_debug("write_bit addr = %lx, value = %d, pos = %ld, "
165 "r_width = %ld\n",
166 dr->reg, !!value, pos, dr->reg_width);
167
168 if (value)
169 set_bit(pos, &dr->reg_shadow);
170 else
171 clear_bit(pos, &dr->reg_shadow);
172
173 gpio_write_raw_reg(dr->mapped_reg, dr->reg_width, dr->reg_shadow);
174}
175EXPORT_SYMBOL_GPL(sh_pfc_write_bit);
176
177static void config_reg_helper(struct sh_pfc *pfc,
178 struct pinmux_cfg_reg *crp,
179 unsigned long in_pos,
180 void __iomem **mapped_regp,
181 unsigned long *maskp,
182 unsigned long *posp)
183{
184 int k;
185
186 *mapped_regp = pfc_phys_to_virt(pfc, crp->reg);
187
188 if (crp->field_width) {
189 *maskp = (1 << crp->field_width) - 1;
190 *posp = crp->reg_width - ((in_pos + 1) * crp->field_width);
191 } else {
192 *maskp = (1 << crp->var_field_width[in_pos]) - 1;
193 *posp = crp->reg_width;
194 for (k = 0; k <= in_pos; k++)
195 *posp -= crp->var_field_width[k];
196 }
197}
198
199static int read_config_reg(struct sh_pfc *pfc,
200 struct pinmux_cfg_reg *crp,
201 unsigned long field)
202{
203 void __iomem *mapped_reg;
204 unsigned long mask, pos;
205
206 config_reg_helper(pfc, crp, field, &mapped_reg, &mask, &pos);
207
208 pr_debug("read_reg: addr = %lx, field = %ld, "
209 "r_width = %ld, f_width = %ld\n",
210 crp->reg, field, crp->reg_width, crp->field_width);
211
212 return (gpio_read_raw_reg(mapped_reg, crp->reg_width) >> pos) & mask;
213}
214
215static void write_config_reg(struct sh_pfc *pfc,
216 struct pinmux_cfg_reg *crp,
217 unsigned long field, unsigned long value)
218{
219 void __iomem *mapped_reg;
220 unsigned long mask, pos, data;
221
222 config_reg_helper(pfc, crp, field, &mapped_reg, &mask, &pos);
223
224 pr_debug("write_reg addr = %lx, value = %ld, field = %ld, "
225 "r_width = %ld, f_width = %ld\n",
226 crp->reg, value, field, crp->reg_width, crp->field_width);
227
228 mask = ~(mask << pos);
229 value = value << pos;
230
231 data = gpio_read_raw_reg(mapped_reg, crp->reg_width);
232 data &= mask;
233 data |= value;
234
235 if (pfc->unlock_reg)
236 gpio_write_raw_reg(pfc_phys_to_virt(pfc, pfc->unlock_reg),
237 32, ~data);
238
239 gpio_write_raw_reg(mapped_reg, crp->reg_width, data);
240}
241
242static int setup_data_reg(struct sh_pfc *pfc, unsigned gpio)
243{
244 struct pinmux_gpio *gpiop = &pfc->gpios[gpio];
245 struct pinmux_data_reg *data_reg;
246 int k, n;
247
248 if (!enum_in_range(gpiop->enum_id, &pfc->data))
249 return -1;
250
251 k = 0;
252 while (1) {
253 data_reg = pfc->data_regs + k;
254
255 if (!data_reg->reg_width)
256 break;
257
258 data_reg->mapped_reg = pfc_phys_to_virt(pfc, data_reg->reg);
259
260 for (n = 0; n < data_reg->reg_width; n++) {
261 if (data_reg->enum_ids[n] == gpiop->enum_id) {
262 gpiop->flags &= ~PINMUX_FLAG_DREG;
263 gpiop->flags |= (k << PINMUX_FLAG_DREG_SHIFT);
264 gpiop->flags &= ~PINMUX_FLAG_DBIT;
265 gpiop->flags |= (n << PINMUX_FLAG_DBIT_SHIFT);
266 return 0;
267 }
268 }
269 k++;
270 }
271
272 BUG();
273
274 return -1;
275}
276
277static void setup_data_regs(struct sh_pfc *pfc)
278{
279 struct pinmux_data_reg *drp;
280 int k;
281
282 for (k = pfc->first_gpio; k <= pfc->last_gpio; k++)
283 setup_data_reg(pfc, k);
284
285 k = 0;
286 while (1) {
287 drp = pfc->data_regs + k;
288
289 if (!drp->reg_width)
290 break;
291
292 drp->reg_shadow = gpio_read_raw_reg(drp->mapped_reg,
293 drp->reg_width);
294 k++;
295 }
296}
297
298int sh_pfc_get_data_reg(struct sh_pfc *pfc, unsigned gpio,
299 struct pinmux_data_reg **drp, int *bitp)
300{
301 struct pinmux_gpio *gpiop = &pfc->gpios[gpio];
302 int k, n;
303
304 if (!enum_in_range(gpiop->enum_id, &pfc->data))
305 return -1;
306
307 k = (gpiop->flags & PINMUX_FLAG_DREG) >> PINMUX_FLAG_DREG_SHIFT;
308 n = (gpiop->flags & PINMUX_FLAG_DBIT) >> PINMUX_FLAG_DBIT_SHIFT;
309 *drp = pfc->data_regs + k;
310 *bitp = n;
311 return 0;
312}
313EXPORT_SYMBOL_GPL(sh_pfc_get_data_reg);
314
315static int get_config_reg(struct sh_pfc *pfc, pinmux_enum_t enum_id,
316 struct pinmux_cfg_reg **crp,
317 int *fieldp, int *valuep,
318 unsigned long **cntp)
319{
320 struct pinmux_cfg_reg *config_reg;
321 unsigned long r_width, f_width, curr_width, ncomb;
322 int k, m, n, pos, bit_pos;
323
324 k = 0;
325 while (1) {
326 config_reg = pfc->cfg_regs + k;
327
328 r_width = config_reg->reg_width;
329 f_width = config_reg->field_width;
330
331 if (!r_width)
332 break;
333
334 pos = 0;
335 m = 0;
336 for (bit_pos = 0; bit_pos < r_width; bit_pos += curr_width) {
337 if (f_width)
338 curr_width = f_width;
339 else
340 curr_width = config_reg->var_field_width[m];
341
342 ncomb = 1 << curr_width;
343 for (n = 0; n < ncomb; n++) {
344 if (config_reg->enum_ids[pos + n] == enum_id) {
345 *crp = config_reg;
346 *fieldp = m;
347 *valuep = n;
348 *cntp = &config_reg->cnt[m];
349 return 0;
350 }
351 }
352 pos += ncomb;
353 m++;
354 }
355 k++;
356 }
357
358 return -1;
359}
360
361int sh_pfc_gpio_to_enum(struct sh_pfc *pfc, unsigned gpio, int pos,
362 pinmux_enum_t *enum_idp)
363{
364 pinmux_enum_t enum_id = pfc->gpios[gpio].enum_id;
365 pinmux_enum_t *data = pfc->gpio_data;
366 int k;
367
368 if (!enum_in_range(enum_id, &pfc->data)) {
369 if (!enum_in_range(enum_id, &pfc->mark)) {
370 pr_err("non data/mark enum_id for gpio %d\n", gpio);
371 return -1;
372 }
373 }
374
375 if (pos) {
376 *enum_idp = data[pos + 1];
377 return pos + 1;
378 }
379
380 for (k = 0; k < pfc->gpio_data_size; k++) {
381 if (data[k] == enum_id) {
382 *enum_idp = data[k + 1];
383 return k + 1;
384 }
385 }
386
387 pr_err("cannot locate data/mark enum_id for gpio %d\n", gpio);
388 return -1;
389}
390EXPORT_SYMBOL_GPL(sh_pfc_gpio_to_enum);
391
392int sh_pfc_config_gpio(struct sh_pfc *pfc, unsigned gpio, int pinmux_type,
393 int cfg_mode)
394{
395 struct pinmux_cfg_reg *cr = NULL;
396 pinmux_enum_t enum_id;
397 struct pinmux_range *range;
398 int in_range, pos, field, value;
399 unsigned long *cntp;
400
401 switch (pinmux_type) {
402
403 case PINMUX_TYPE_FUNCTION:
404 range = NULL;
405 break;
406
407 case PINMUX_TYPE_OUTPUT:
408 range = &pfc->output;
409 break;
410
411 case PINMUX_TYPE_INPUT:
412 range = &pfc->input;
413 break;
414
415 case PINMUX_TYPE_INPUT_PULLUP:
416 range = &pfc->input_pu;
417 break;
418
419 case PINMUX_TYPE_INPUT_PULLDOWN:
420 range = &pfc->input_pd;
421 break;
422
423 default:
424 goto out_err;
425 }
426
427 pos = 0;
428 enum_id = 0;
429 field = 0;
430 value = 0;
431 while (1) {
432 pos = sh_pfc_gpio_to_enum(pfc, gpio, pos, &enum_id);
433 if (pos <= 0)
434 goto out_err;
435
436 if (!enum_id)
437 break;
438
439 /* first check if this is a function enum */
440 in_range = enum_in_range(enum_id, &pfc->function);
441 if (!in_range) {
442 /* not a function enum */
443 if (range) {
444 /*
445 * other range exists, so this pin is
446 * a regular GPIO pin that now is being
447 * bound to a specific direction.
448 *
449 * for this case we only allow function enums
450 * and the enums that match the other range.
451 */
452 in_range = enum_in_range(enum_id, range);
453
454 /*
455 * special case pass through for fixed
456 * input-only or output-only pins without
457 * function enum register association.
458 */
459 if (in_range && enum_id == range->force)
460 continue;
461 } else {
462 /*
463 * no other range exists, so this pin
464 * must then be of the function type.
465 *
466 * allow function type pins to select
467 * any combination of function/in/out
468 * in their MARK lists.
469 */
470 in_range = 1;
471 }
472 }
473
474 if (!in_range)
475 continue;
476
477 if (get_config_reg(pfc, enum_id, &cr,
478 &field, &value, &cntp) != 0)
479 goto out_err;
480
481 switch (cfg_mode) {
482 case GPIO_CFG_DRYRUN:
483 if (!*cntp ||
484 (read_config_reg(pfc, cr, field) != value))
485 continue;
486 break;
487
488 case GPIO_CFG_REQ:
489 write_config_reg(pfc, cr, field, value);
490 *cntp = *cntp + 1;
491 break;
492
493 case GPIO_CFG_FREE:
494 *cntp = *cntp - 1;
495 break;
496 }
497 }
498
499 return 0;
500 out_err:
501 return -1;
502}
503EXPORT_SYMBOL_GPL(sh_pfc_config_gpio);
504
505int register_sh_pfc(struct sh_pfc *pfc)
506{
507 int (*initroutine)(struct sh_pfc *) = NULL;
508 int ret;
509
510 /*
511 * Ensure that the type encoding fits
512 */
513 BUILD_BUG_ON(PINMUX_FLAG_TYPE > ((1 << PINMUX_FLAG_DBIT_SHIFT) - 1));
514
515 if (sh_pfc)
516 return -EBUSY;
517
518 ret = pfc_ioremap(pfc);
519 if (unlikely(ret < 0))
520 return ret;
521
522 spin_lock_init(&pfc->lock);
523
524 pinctrl_provide_dummies();
525 setup_data_regs(pfc);
526
527 sh_pfc = pfc;
528
529 /*
530 * Initialize pinctrl bindings first
531 */
532 initroutine = symbol_request(sh_pfc_register_pinctrl);
533 if (initroutine) {
534 ret = (*initroutine)(pfc);
535 symbol_put_addr(initroutine);
536
537 if (unlikely(ret != 0))
538 goto err;
539 } else {
540 pr_err("failed to initialize pinctrl bindings\n");
541 goto err;
542 }
543
544 /*
545 * Then the GPIO chip
546 */
547 initroutine = symbol_request(sh_pfc_register_gpiochip);
548 if (initroutine) {
549 ret = (*initroutine)(pfc);
550 symbol_put_addr(initroutine);
551
552 /*
553 * If the GPIO chip fails to come up we still leave the
554 * PFC state as it is, given that there are already
555 * extant users of it that have succeeded by this point.
556 */
557 if (unlikely(ret != 0)) {
558 pr_notice("failed to init GPIO chip, ignoring...\n");
559 ret = 0;
560 }
561 }
562
563 pr_info("%s support registered\n", pfc->name);
564
565 return 0;
566
567err:
568 pfc_iounmap(pfc);
569 sh_pfc = NULL;
570
571 return ret;
572}
diff --git a/drivers/sh/pfc/gpio.c b/drivers/sh/pfc/gpio.c
deleted file mode 100644
index 6a24f07c201..00000000000
--- a/drivers/sh/pfc/gpio.c
+++ /dev/null
@@ -1,240 +0,0 @@
1/*
2 * SuperH Pin Function Controller GPIO driver.
3 *
4 * Copyright (C) 2008 Magnus Damm
5 * Copyright (C) 2009 - 2012 Paul Mundt
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive
9 * for more details.
10 */
11#define pr_fmt(fmt) "sh_pfc " KBUILD_MODNAME ": " fmt
12
13#include <linux/init.h>
14#include <linux/gpio.h>
15#include <linux/slab.h>
16#include <linux/spinlock.h>
17#include <linux/module.h>
18#include <linux/platform_device.h>
19#include <linux/pinctrl/consumer.h>
20#include <linux/sh_pfc.h>
21
22struct sh_pfc_chip {
23 struct sh_pfc *pfc;
24 struct gpio_chip gpio_chip;
25};
26
27static struct sh_pfc_chip *gpio_to_pfc_chip(struct gpio_chip *gc)
28{
29 return container_of(gc, struct sh_pfc_chip, gpio_chip);
30}
31
32static struct sh_pfc *gpio_to_pfc(struct gpio_chip *gc)
33{
34 return gpio_to_pfc_chip(gc)->pfc;
35}
36
37static int sh_gpio_request(struct gpio_chip *gc, unsigned offset)
38{
39 return pinctrl_request_gpio(offset);
40}
41
42static void sh_gpio_free(struct gpio_chip *gc, unsigned offset)
43{
44 pinctrl_free_gpio(offset);
45}
46
47static void sh_gpio_set_value(struct sh_pfc *pfc, unsigned gpio, int value)
48{
49 struct pinmux_data_reg *dr = NULL;
50 int bit = 0;
51
52 if (!pfc || sh_pfc_get_data_reg(pfc, gpio, &dr, &bit) != 0)
53 BUG();
54 else
55 sh_pfc_write_bit(dr, bit, value);
56}
57
58static int sh_gpio_get_value(struct sh_pfc *pfc, unsigned gpio)
59{
60 struct pinmux_data_reg *dr = NULL;
61 int bit = 0;
62
63 if (!pfc || sh_pfc_get_data_reg(pfc, gpio, &dr, &bit) != 0)
64 return -EINVAL;
65
66 return sh_pfc_read_bit(dr, bit);
67}
68
69static int sh_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
70{
71 return pinctrl_gpio_direction_input(offset);
72}
73
74static int sh_gpio_direction_output(struct gpio_chip *gc, unsigned offset,
75 int value)
76{
77 sh_gpio_set_value(gpio_to_pfc(gc), offset, value);
78
79 return pinctrl_gpio_direction_output(offset);
80}
81
82static int sh_gpio_get(struct gpio_chip *gc, unsigned offset)
83{
84 return sh_gpio_get_value(gpio_to_pfc(gc), offset);
85}
86
87static void sh_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
88{
89 sh_gpio_set_value(gpio_to_pfc(gc), offset, value);
90}
91
92static int sh_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
93{
94 struct sh_pfc *pfc = gpio_to_pfc(gc);
95 pinmux_enum_t enum_id;
96 pinmux_enum_t *enum_ids;
97 int i, k, pos;
98
99 pos = 0;
100 enum_id = 0;
101 while (1) {
102 pos = sh_pfc_gpio_to_enum(pfc, offset, pos, &enum_id);
103 if (pos <= 0 || !enum_id)
104 break;
105
106 for (i = 0; i < pfc->gpio_irq_size; i++) {
107 enum_ids = pfc->gpio_irq[i].enum_ids;
108 for (k = 0; enum_ids[k]; k++) {
109 if (enum_ids[k] == enum_id)
110 return pfc->gpio_irq[i].irq;
111 }
112 }
113 }
114
115 return -ENOSYS;
116}
117
118static void sh_pfc_gpio_setup(struct sh_pfc_chip *chip)
119{
120 struct sh_pfc *pfc = chip->pfc;
121 struct gpio_chip *gc = &chip->gpio_chip;
122
123 gc->request = sh_gpio_request;
124 gc->free = sh_gpio_free;
125 gc->direction_input = sh_gpio_direction_input;
126 gc->get = sh_gpio_get;
127 gc->direction_output = sh_gpio_direction_output;
128 gc->set = sh_gpio_set;
129 gc->to_irq = sh_gpio_to_irq;
130
131 WARN_ON(pfc->first_gpio != 0); /* needs testing */
132
133 gc->label = pfc->name;
134 gc->owner = THIS_MODULE;
135 gc->base = pfc->first_gpio;
136 gc->ngpio = (pfc->last_gpio - pfc->first_gpio) + 1;
137}
138
139int sh_pfc_register_gpiochip(struct sh_pfc *pfc)
140{
141 struct sh_pfc_chip *chip;
142 int ret;
143
144 chip = kzalloc(sizeof(struct sh_pfc_chip), GFP_KERNEL);
145 if (unlikely(!chip))
146 return -ENOMEM;
147
148 chip->pfc = pfc;
149
150 sh_pfc_gpio_setup(chip);
151
152 ret = gpiochip_add(&chip->gpio_chip);
153 if (unlikely(ret < 0))
154 kfree(chip);
155
156 pr_info("%s handling gpio %d -> %d\n",
157 pfc->name, pfc->first_gpio, pfc->last_gpio);
158
159 return ret;
160}
161EXPORT_SYMBOL_GPL(sh_pfc_register_gpiochip);
162
163static int sh_pfc_gpio_match(struct gpio_chip *gc, void *data)
164{
165 return !!strstr(gc->label, data);
166}
167
168static int sh_pfc_gpio_probe(struct platform_device *pdev)
169{
170 struct sh_pfc_chip *chip;
171 struct gpio_chip *gc;
172
173 gc = gpiochip_find("_pfc", sh_pfc_gpio_match);
174 if (unlikely(!gc)) {
175 pr_err("Cant find gpio chip\n");
176 return -ENODEV;
177 }
178
179 chip = gpio_to_pfc_chip(gc);
180 platform_set_drvdata(pdev, chip);
181
182 pr_info("attaching to GPIO chip %s\n", chip->pfc->name);
183
184 return 0;
185}
186
187static int sh_pfc_gpio_remove(struct platform_device *pdev)
188{
189 struct sh_pfc_chip *chip = platform_get_drvdata(pdev);
190 int ret;
191
192 ret = gpiochip_remove(&chip->gpio_chip);
193 if (unlikely(ret < 0))
194 return ret;
195
196 kfree(chip);
197 return 0;
198}
199
200static struct platform_driver sh_pfc_gpio_driver = {
201 .probe = sh_pfc_gpio_probe,
202 .remove = sh_pfc_gpio_remove,
203 .driver = {
204 .name = KBUILD_MODNAME,
205 .owner = THIS_MODULE,
206 },
207};
208
209static struct platform_device sh_pfc_gpio_device = {
210 .name = KBUILD_MODNAME,
211 .id = -1,
212};
213
214static int __init sh_pfc_gpio_init(void)
215{
216 int rc;
217
218 rc = platform_driver_register(&sh_pfc_gpio_driver);
219 if (likely(!rc)) {
220 rc = platform_device_register(&sh_pfc_gpio_device);
221 if (unlikely(rc))
222 platform_driver_unregister(&sh_pfc_gpio_driver);
223 }
224
225 return rc;
226}
227
228static void __exit sh_pfc_gpio_exit(void)
229{
230 platform_device_unregister(&sh_pfc_gpio_device);
231 platform_driver_unregister(&sh_pfc_gpio_driver);
232}
233
234module_init(sh_pfc_gpio_init);
235module_exit(sh_pfc_gpio_exit);
236
237MODULE_AUTHOR("Magnus Damm, Paul Mundt");
238MODULE_DESCRIPTION("GPIO driver for SuperH pin function controller");
239MODULE_LICENSE("GPL v2");
240MODULE_ALIAS("platform:pfc-gpio");
diff --git a/drivers/sh/pfc/pinctrl.c b/drivers/sh/pfc/pinctrl.c
deleted file mode 100644
index 4109b769eac..00000000000
--- a/drivers/sh/pfc/pinctrl.c
+++ /dev/null
@@ -1,527 +0,0 @@
1/*
2 * SuperH Pin Function Controller pinmux support.
3 *
4 * Copyright (C) 2012 Paul Mundt
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#define DRV_NAME "pinctrl-sh_pfc"
11
12#define pr_fmt(fmt) DRV_NAME " " KBUILD_MODNAME ": " fmt
13
14#include <linux/init.h>
15#include <linux/module.h>
16#include <linux/sh_pfc.h>
17#include <linux/err.h>
18#include <linux/slab.h>
19#include <linux/spinlock.h>
20#include <linux/platform_device.h>
21#include <linux/pinctrl/consumer.h>
22#include <linux/pinctrl/pinctrl.h>
23#include <linux/pinctrl/pinconf.h>
24#include <linux/pinctrl/pinmux.h>
25#include <linux/pinctrl/pinconf-generic.h>
26
27struct sh_pfc_pinctrl {
28 struct pinctrl_dev *pctl;
29 struct sh_pfc *pfc;
30
31 struct pinmux_gpio **functions;
32 unsigned int nr_functions;
33
34 struct pinctrl_pin_desc *pads;
35 unsigned int nr_pads;
36
37 spinlock_t lock;
38};
39
40static struct sh_pfc_pinctrl *sh_pfc_pmx;
41
42static int sh_pfc_get_groups_count(struct pinctrl_dev *pctldev)
43{
44 struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
45
46 return pmx->nr_pads;
47}
48
49static const char *sh_pfc_get_group_name(struct pinctrl_dev *pctldev,
50 unsigned selector)
51{
52 struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
53
54 return pmx->pads[selector].name;
55}
56
57static int sh_pfc_get_group_pins(struct pinctrl_dev *pctldev, unsigned group,
58 const unsigned **pins, unsigned *num_pins)
59{
60 struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
61
62 *pins = &pmx->pads[group].number;
63 *num_pins = 1;
64
65 return 0;
66}
67
68static void sh_pfc_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
69 unsigned offset)
70{
71 seq_printf(s, "%s", DRV_NAME);
72}
73
74static struct pinctrl_ops sh_pfc_pinctrl_ops = {
75 .get_groups_count = sh_pfc_get_groups_count,
76 .get_group_name = sh_pfc_get_group_name,
77 .get_group_pins = sh_pfc_get_group_pins,
78 .pin_dbg_show = sh_pfc_pin_dbg_show,
79};
80
81static int sh_pfc_get_functions_count(struct pinctrl_dev *pctldev)
82{
83 struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
84
85 return pmx->nr_functions;
86}
87
88static const char *sh_pfc_get_function_name(struct pinctrl_dev *pctldev,
89 unsigned selector)
90{
91 struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
92
93 return pmx->functions[selector]->name;
94}
95
96static int sh_pfc_get_function_groups(struct pinctrl_dev *pctldev, unsigned func,
97 const char * const **groups,
98 unsigned * const num_groups)
99{
100 struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
101
102 *groups = &pmx->functions[func]->name;
103 *num_groups = 1;
104
105 return 0;
106}
107
108static int sh_pfc_noop_enable(struct pinctrl_dev *pctldev, unsigned func,
109 unsigned group)
110{
111 return 0;
112}
113
114static void sh_pfc_noop_disable(struct pinctrl_dev *pctldev, unsigned func,
115 unsigned group)
116{
117}
118
119static inline int sh_pfc_config_function(struct sh_pfc *pfc, unsigned offset)
120{
121 if (sh_pfc_config_gpio(pfc, offset,
122 PINMUX_TYPE_FUNCTION,
123 GPIO_CFG_DRYRUN) != 0)
124 return -EINVAL;
125
126 if (sh_pfc_config_gpio(pfc, offset,
127 PINMUX_TYPE_FUNCTION,
128 GPIO_CFG_REQ) != 0)
129 return -EINVAL;
130
131 return 0;
132}
133
134static int sh_pfc_reconfig_pin(struct sh_pfc *pfc, unsigned offset,
135 int new_type)
136{
137 unsigned long flags;
138 int pinmux_type;
139 int ret = -EINVAL;
140
141 spin_lock_irqsave(&pfc->lock, flags);
142
143 pinmux_type = pfc->gpios[offset].flags & PINMUX_FLAG_TYPE;
144
145 /*
146 * See if the present config needs to first be de-configured.
147 */
148 switch (pinmux_type) {
149 case PINMUX_TYPE_GPIO:
150 break;
151 case PINMUX_TYPE_OUTPUT:
152 case PINMUX_TYPE_INPUT:
153 case PINMUX_TYPE_INPUT_PULLUP:
154 case PINMUX_TYPE_INPUT_PULLDOWN:
155 sh_pfc_config_gpio(pfc, offset, pinmux_type, GPIO_CFG_FREE);
156 break;
157 default:
158 goto err;
159 }
160
161 /*
162 * Dry run
163 */
164 if (sh_pfc_config_gpio(pfc, offset, new_type,
165 GPIO_CFG_DRYRUN) != 0)
166 goto err;
167
168 /*
169 * Request
170 */
171 if (sh_pfc_config_gpio(pfc, offset, new_type,
172 GPIO_CFG_REQ) != 0)
173 goto err;
174
175 pfc->gpios[offset].flags &= ~PINMUX_FLAG_TYPE;
176 pfc->gpios[offset].flags |= new_type;
177
178 ret = 0;
179
180err:
181 spin_unlock_irqrestore(&pfc->lock, flags);
182
183 return ret;
184}
185
186
187static int sh_pfc_gpio_request_enable(struct pinctrl_dev *pctldev,
188 struct pinctrl_gpio_range *range,
189 unsigned offset)
190{
191 struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
192 struct sh_pfc *pfc = pmx->pfc;
193 unsigned long flags;
194 int ret, pinmux_type;
195
196 spin_lock_irqsave(&pfc->lock, flags);
197
198 pinmux_type = pfc->gpios[offset].flags & PINMUX_FLAG_TYPE;
199
200 switch (pinmux_type) {
201 case PINMUX_TYPE_FUNCTION:
202 pr_notice_once("Use of GPIO API for function requests is "
203 "deprecated, convert to pinctrl\n");
204 /* handle for now */
205 ret = sh_pfc_config_function(pfc, offset);
206 if (unlikely(ret < 0))
207 goto err;
208
209 break;
210 case PINMUX_TYPE_GPIO:
211 case PINMUX_TYPE_INPUT:
212 case PINMUX_TYPE_OUTPUT:
213 break;
214 default:
215 pr_err("Unsupported mux type (%d), bailing...\n", pinmux_type);
216 ret = -ENOTSUPP;
217 goto err;
218 }
219
220 ret = 0;
221
222err:
223 spin_unlock_irqrestore(&pfc->lock, flags);
224
225 return ret;
226}
227
228static void sh_pfc_gpio_disable_free(struct pinctrl_dev *pctldev,
229 struct pinctrl_gpio_range *range,
230 unsigned offset)
231{
232 struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
233 struct sh_pfc *pfc = pmx->pfc;
234 unsigned long flags;
235 int pinmux_type;
236
237 spin_lock_irqsave(&pfc->lock, flags);
238
239 pinmux_type = pfc->gpios[offset].flags & PINMUX_FLAG_TYPE;
240
241 sh_pfc_config_gpio(pfc, offset, pinmux_type, GPIO_CFG_FREE);
242
243 spin_unlock_irqrestore(&pfc->lock, flags);
244}
245
246static int sh_pfc_gpio_set_direction(struct pinctrl_dev *pctldev,
247 struct pinctrl_gpio_range *range,
248 unsigned offset, bool input)
249{
250 struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
251 int type = input ? PINMUX_TYPE_INPUT : PINMUX_TYPE_OUTPUT;
252
253 return sh_pfc_reconfig_pin(pmx->pfc, offset, type);
254}
255
256static struct pinmux_ops sh_pfc_pinmux_ops = {
257 .get_functions_count = sh_pfc_get_functions_count,
258 .get_function_name = sh_pfc_get_function_name,
259 .get_function_groups = sh_pfc_get_function_groups,
260 .enable = sh_pfc_noop_enable,
261 .disable = sh_pfc_noop_disable,
262 .gpio_request_enable = sh_pfc_gpio_request_enable,
263 .gpio_disable_free = sh_pfc_gpio_disable_free,
264 .gpio_set_direction = sh_pfc_gpio_set_direction,
265};
266
267static int sh_pfc_pinconf_get(struct pinctrl_dev *pctldev, unsigned pin,
268 unsigned long *config)
269{
270 struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
271 struct sh_pfc *pfc = pmx->pfc;
272
273 *config = pfc->gpios[pin].flags & PINMUX_FLAG_TYPE;
274
275 return 0;
276}
277
278static int sh_pfc_pinconf_set(struct pinctrl_dev *pctldev, unsigned pin,
279 unsigned long config)
280{
281 struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
282
283 /* Validate the new type */
284 if (config >= PINMUX_FLAG_TYPE)
285 return -EINVAL;
286
287 return sh_pfc_reconfig_pin(pmx->pfc, pin, config);
288}
289
290static void sh_pfc_pinconf_dbg_show(struct pinctrl_dev *pctldev,
291 struct seq_file *s, unsigned pin)
292{
293 const char *pinmux_type_str[] = {
294 [PINMUX_TYPE_NONE] = "none",
295 [PINMUX_TYPE_FUNCTION] = "function",
296 [PINMUX_TYPE_GPIO] = "gpio",
297 [PINMUX_TYPE_OUTPUT] = "output",
298 [PINMUX_TYPE_INPUT] = "input",
299 [PINMUX_TYPE_INPUT_PULLUP] = "input bias pull up",
300 [PINMUX_TYPE_INPUT_PULLDOWN] = "input bias pull down",
301 };
302 unsigned long config;
303 int rc;
304
305 rc = sh_pfc_pinconf_get(pctldev, pin, &config);
306 if (unlikely(rc != 0))
307 return;
308
309 seq_printf(s, " %s", pinmux_type_str[config]);
310}
311
312static struct pinconf_ops sh_pfc_pinconf_ops = {
313 .pin_config_get = sh_pfc_pinconf_get,
314 .pin_config_set = sh_pfc_pinconf_set,
315 .pin_config_dbg_show = sh_pfc_pinconf_dbg_show,
316};
317
318static struct pinctrl_gpio_range sh_pfc_gpio_range = {
319 .name = DRV_NAME,
320 .id = 0,
321};
322
323static struct pinctrl_desc sh_pfc_pinctrl_desc = {
324 .name = DRV_NAME,
325 .owner = THIS_MODULE,
326 .pctlops = &sh_pfc_pinctrl_ops,
327 .pmxops = &sh_pfc_pinmux_ops,
328 .confops = &sh_pfc_pinconf_ops,
329};
330
331static inline void sh_pfc_map_one_gpio(struct sh_pfc *pfc,
332 struct sh_pfc_pinctrl *pmx,
333 struct pinmux_gpio *gpio,
334 unsigned offset)
335{
336 struct pinmux_data_reg *dummy;
337 unsigned long flags;
338 int bit;
339
340 gpio->flags &= ~PINMUX_FLAG_TYPE;
341
342 if (sh_pfc_get_data_reg(pfc, offset, &dummy, &bit) == 0)
343 gpio->flags |= PINMUX_TYPE_GPIO;
344 else {
345 gpio->flags |= PINMUX_TYPE_FUNCTION;
346
347 spin_lock_irqsave(&pmx->lock, flags);
348 pmx->nr_functions++;
349 spin_unlock_irqrestore(&pmx->lock, flags);
350 }
351}
352
353/* pinmux ranges -> pinctrl pin descs */
354static int sh_pfc_map_gpios(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx)
355{
356 unsigned long flags;
357 int i;
358
359 pmx->nr_pads = pfc->last_gpio - pfc->first_gpio + 1;
360
361 pmx->pads = kmalloc(sizeof(struct pinctrl_pin_desc) * pmx->nr_pads,
362 GFP_KERNEL);
363 if (unlikely(!pmx->pads)) {
364 pmx->nr_pads = 0;
365 return -ENOMEM;
366 }
367
368 spin_lock_irqsave(&pfc->lock, flags);
369
370 /*
371 * We don't necessarily have a 1:1 mapping between pin and linux
372 * GPIO number, as the latter maps to the associated enum_id.
373 * Care needs to be taken to translate back to pin space when
374 * dealing with any pin configurations.
375 */
376 for (i = 0; i < pmx->nr_pads; i++) {
377 struct pinctrl_pin_desc *pin = pmx->pads + i;
378 struct pinmux_gpio *gpio = pfc->gpios + i;
379
380 pin->number = pfc->first_gpio + i;
381 pin->name = gpio->name;
382
383 /* XXX */
384 if (unlikely(!gpio->enum_id))
385 continue;
386
387 sh_pfc_map_one_gpio(pfc, pmx, gpio, i);
388 }
389
390 spin_unlock_irqrestore(&pfc->lock, flags);
391
392 sh_pfc_pinctrl_desc.pins = pmx->pads;
393 sh_pfc_pinctrl_desc.npins = pmx->nr_pads;
394
395 return 0;
396}
397
398static int sh_pfc_map_functions(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx)
399{
400 unsigned long flags;
401 int i, fn;
402
403 pmx->functions = kzalloc(pmx->nr_functions * sizeof(void *),
404 GFP_KERNEL);
405 if (unlikely(!pmx->functions))
406 return -ENOMEM;
407
408 spin_lock_irqsave(&pmx->lock, flags);
409
410 for (i = fn = 0; i < pmx->nr_pads; i++) {
411 struct pinmux_gpio *gpio = pfc->gpios + i;
412
413 if ((gpio->flags & PINMUX_FLAG_TYPE) == PINMUX_TYPE_FUNCTION)
414 pmx->functions[fn++] = gpio;
415 }
416
417 spin_unlock_irqrestore(&pmx->lock, flags);
418
419 return 0;
420}
421
422static int sh_pfc_pinctrl_probe(struct platform_device *pdev)
423{
424 struct sh_pfc *pfc;
425 int ret;
426
427 if (unlikely(!sh_pfc_pmx))
428 return -ENODEV;
429
430 pfc = sh_pfc_pmx->pfc;
431
432 ret = sh_pfc_map_gpios(pfc, sh_pfc_pmx);
433 if (unlikely(ret != 0))
434 return ret;
435
436 ret = sh_pfc_map_functions(pfc, sh_pfc_pmx);
437 if (unlikely(ret != 0))
438 goto free_pads;
439
440 sh_pfc_pmx->pctl = pinctrl_register(&sh_pfc_pinctrl_desc, &pdev->dev,
441 sh_pfc_pmx);
442 if (IS_ERR(sh_pfc_pmx->pctl)) {
443 ret = PTR_ERR(sh_pfc_pmx->pctl);
444 goto free_functions;
445 }
446
447 sh_pfc_gpio_range.npins = pfc->last_gpio - pfc->first_gpio + 1;
448 sh_pfc_gpio_range.base = pfc->first_gpio;
449 sh_pfc_gpio_range.pin_base = pfc->first_gpio;
450
451 pinctrl_add_gpio_range(sh_pfc_pmx->pctl, &sh_pfc_gpio_range);
452
453 platform_set_drvdata(pdev, sh_pfc_pmx);
454
455 return 0;
456
457free_functions:
458 kfree(sh_pfc_pmx->functions);
459free_pads:
460 kfree(sh_pfc_pmx->pads);
461 kfree(sh_pfc_pmx);
462
463 return ret;
464}
465
466static int sh_pfc_pinctrl_remove(struct platform_device *pdev)
467{
468 struct sh_pfc_pinctrl *pmx = platform_get_drvdata(pdev);
469
470 pinctrl_unregister(pmx->pctl);
471
472 platform_set_drvdata(pdev, NULL);
473
474 kfree(sh_pfc_pmx->functions);
475 kfree(sh_pfc_pmx->pads);
476 kfree(sh_pfc_pmx);
477
478 return 0;
479}
480
481static struct platform_driver sh_pfc_pinctrl_driver = {
482 .probe = sh_pfc_pinctrl_probe,
483 .remove = sh_pfc_pinctrl_remove,
484 .driver = {
485 .name = DRV_NAME,
486 .owner = THIS_MODULE,
487 },
488};
489
490static struct platform_device sh_pfc_pinctrl_device = {
491 .name = DRV_NAME,
492 .id = -1,
493};
494
495static int sh_pfc_pinctrl_init(void)
496{
497 int rc;
498
499 rc = platform_driver_register(&sh_pfc_pinctrl_driver);
500 if (likely(!rc)) {
501 rc = platform_device_register(&sh_pfc_pinctrl_device);
502 if (unlikely(rc))
503 platform_driver_unregister(&sh_pfc_pinctrl_driver);
504 }
505
506 return rc;
507}
508
509int sh_pfc_register_pinctrl(struct sh_pfc *pfc)
510{
511 sh_pfc_pmx = kzalloc(sizeof(struct sh_pfc_pinctrl), GFP_KERNEL);
512 if (unlikely(!sh_pfc_pmx))
513 return -ENOMEM;
514
515 spin_lock_init(&sh_pfc_pmx->lock);
516
517 sh_pfc_pmx->pfc = pfc;
518
519 return sh_pfc_pinctrl_init();
520}
521EXPORT_SYMBOL_GPL(sh_pfc_register_pinctrl);
522
523static void __exit sh_pfc_pinctrl_exit(void)
524{
525 platform_driver_unregister(&sh_pfc_pinctrl_driver);
526}
527module_exit(sh_pfc_pinctrl_exit);
diff --git a/drivers/sh/pm_runtime.c b/drivers/sh/pm_runtime.c
deleted file mode 100644
index afe9282629b..00000000000
--- a/drivers/sh/pm_runtime.c
+++ /dev/null
@@ -1,65 +0,0 @@
1/*
2 * Runtime PM support code
3 *
4 * Copyright (C) 2009-2010 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
11#include <linux/init.h>
12#include <linux/kernel.h>
13#include <linux/io.h>
14#include <linux/pm_runtime.h>
15#include <linux/pm_domain.h>
16#include <linux/pm_clock.h>
17#include <linux/platform_device.h>
18#include <linux/clk.h>
19#include <linux/sh_clk.h>
20#include <linux/bitmap.h>
21#include <linux/slab.h>
22
23#ifdef CONFIG_PM_RUNTIME
24
25static int default_platform_runtime_idle(struct device *dev)
26{
27 /* suspend synchronously to disable clocks immediately */
28 return pm_runtime_suspend(dev);
29}
30
31static struct dev_pm_domain default_pm_domain = {
32 .ops = {
33 .runtime_suspend = pm_clk_suspend,
34 .runtime_resume = pm_clk_resume,
35 .runtime_idle = default_platform_runtime_idle,
36 USE_PLATFORM_PM_SLEEP_OPS
37 },
38};
39
40#define DEFAULT_PM_DOMAIN_PTR (&default_pm_domain)
41
42#else
43
44#define DEFAULT_PM_DOMAIN_PTR NULL
45
46#endif /* CONFIG_PM_RUNTIME */
47
48static struct pm_clk_notifier_block platform_bus_notifier = {
49 .pm_domain = DEFAULT_PM_DOMAIN_PTR,
50 .con_ids = { NULL, },
51};
52
53static int __init sh_pm_runtime_init(void)
54{
55 pm_clk_add_notifier(&platform_bus_type, &platform_bus_notifier);
56 return 0;
57}
58core_initcall(sh_pm_runtime_init);
59
60static int __init sh_pm_runtime_late_init(void)
61{
62 pm_genpd_poweroff_unused();
63 return 0;
64}
65late_initcall(sh_pm_runtime_late_init);