diff options
author | Kukjin Kim <kgene.kim@samsung.com> | 2012-11-18 20:00:41 -0500 |
---|---|---|
committer | Kukjin Kim <kgene.kim@samsung.com> | 2012-11-18 20:00:41 -0500 |
commit | bab797f8e36a4dd0476eda5197182aeea44e23db (patch) | |
tree | 925ec0c9a0041c4b7b09a5d3a5869d57e45a5da7 /drivers/pinctrl | |
parent | 3d70f8c617a436c7146ecb81df2265b4626dfe89 (diff) | |
parent | b33ef91f4b799a5de5904c4b361df97a0c3ec7dd (diff) |
Merge remote-tracking branch 'pinctrl/samsung' into next/pinctrl-samsung
Diffstat (limited to 'drivers/pinctrl')
-rw-r--r-- | drivers/pinctrl/pinctrl-exynos.c | 367 | ||||
-rw-r--r-- | drivers/pinctrl/pinctrl-exynos.h | 170 | ||||
-rw-r--r-- | drivers/pinctrl/pinctrl-samsung.c | 203 | ||||
-rw-r--r-- | drivers/pinctrl/pinctrl-samsung.h | 29 |
4 files changed, 369 insertions, 400 deletions
diff --git a/drivers/pinctrl/pinctrl-exynos.c b/drivers/pinctrl/pinctrl-exynos.c index 21362f48d370..73a0aa27cd56 100644 --- a/drivers/pinctrl/pinctrl-exynos.c +++ b/drivers/pinctrl/pinctrl-exynos.c | |||
@@ -40,46 +40,46 @@ static const struct of_device_id exynos_wkup_irq_ids[] = { | |||
40 | 40 | ||
41 | static void exynos_gpio_irq_unmask(struct irq_data *irqd) | 41 | static void exynos_gpio_irq_unmask(struct irq_data *irqd) |
42 | { | 42 | { |
43 | struct samsung_pinctrl_drv_data *d = irqd->domain->host_data; | 43 | struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); |
44 | struct exynos_geint_data *edata = irq_data_get_irq_handler_data(irqd); | 44 | struct samsung_pinctrl_drv_data *d = bank->drvdata; |
45 | unsigned long reg_mask = d->ctrl->geint_mask + edata->eint_offset; | 45 | unsigned long reg_mask = d->ctrl->geint_mask + bank->eint_offset; |
46 | unsigned long mask; | 46 | unsigned long mask; |
47 | 47 | ||
48 | mask = readl(d->virt_base + reg_mask); | 48 | mask = readl(d->virt_base + reg_mask); |
49 | mask &= ~(1 << edata->pin); | 49 | mask &= ~(1 << irqd->hwirq); |
50 | writel(mask, d->virt_base + reg_mask); | 50 | writel(mask, d->virt_base + reg_mask); |
51 | } | 51 | } |
52 | 52 | ||
53 | static void exynos_gpio_irq_mask(struct irq_data *irqd) | 53 | static void exynos_gpio_irq_mask(struct irq_data *irqd) |
54 | { | 54 | { |
55 | struct samsung_pinctrl_drv_data *d = irqd->domain->host_data; | 55 | struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); |
56 | struct exynos_geint_data *edata = irq_data_get_irq_handler_data(irqd); | 56 | struct samsung_pinctrl_drv_data *d = bank->drvdata; |
57 | unsigned long reg_mask = d->ctrl->geint_mask + edata->eint_offset; | 57 | unsigned long reg_mask = d->ctrl->geint_mask + bank->eint_offset; |
58 | unsigned long mask; | 58 | unsigned long mask; |
59 | 59 | ||
60 | mask = readl(d->virt_base + reg_mask); | 60 | mask = readl(d->virt_base + reg_mask); |
61 | mask |= 1 << edata->pin; | 61 | mask |= 1 << irqd->hwirq; |
62 | writel(mask, d->virt_base + reg_mask); | 62 | writel(mask, d->virt_base + reg_mask); |
63 | } | 63 | } |
64 | 64 | ||
65 | static void exynos_gpio_irq_ack(struct irq_data *irqd) | 65 | static void exynos_gpio_irq_ack(struct irq_data *irqd) |
66 | { | 66 | { |
67 | struct samsung_pinctrl_drv_data *d = irqd->domain->host_data; | 67 | struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); |
68 | struct exynos_geint_data *edata = irq_data_get_irq_handler_data(irqd); | 68 | struct samsung_pinctrl_drv_data *d = bank->drvdata; |
69 | unsigned long reg_pend = d->ctrl->geint_pend + edata->eint_offset; | 69 | unsigned long reg_pend = d->ctrl->geint_pend + bank->eint_offset; |
70 | 70 | ||
71 | writel(1 << edata->pin, d->virt_base + reg_pend); | 71 | writel(1 << irqd->hwirq, d->virt_base + reg_pend); |
72 | } | 72 | } |
73 | 73 | ||
74 | static int exynos_gpio_irq_set_type(struct irq_data *irqd, unsigned int type) | 74 | static int exynos_gpio_irq_set_type(struct irq_data *irqd, unsigned int type) |
75 | { | 75 | { |
76 | struct samsung_pinctrl_drv_data *d = irqd->domain->host_data; | 76 | struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); |
77 | struct samsung_pinctrl_drv_data *d = bank->drvdata; | ||
77 | struct samsung_pin_ctrl *ctrl = d->ctrl; | 78 | struct samsung_pin_ctrl *ctrl = d->ctrl; |
78 | struct exynos_geint_data *edata = irq_data_get_irq_handler_data(irqd); | 79 | unsigned int pin = irqd->hwirq; |
79 | struct samsung_pin_bank *bank = edata->bank; | 80 | unsigned int shift = EXYNOS_EINT_CON_LEN * pin; |
80 | unsigned int shift = EXYNOS_EINT_CON_LEN * edata->pin; | ||
81 | unsigned int con, trig_type; | 81 | unsigned int con, trig_type; |
82 | unsigned long reg_con = ctrl->geint_con + edata->eint_offset; | 82 | unsigned long reg_con = ctrl->geint_con + bank->eint_offset; |
83 | unsigned int mask; | 83 | unsigned int mask; |
84 | 84 | ||
85 | switch (type) { | 85 | switch (type) { |
@@ -114,7 +114,7 @@ static int exynos_gpio_irq_set_type(struct irq_data *irqd, unsigned int type) | |||
114 | writel(con, d->virt_base + reg_con); | 114 | writel(con, d->virt_base + reg_con); |
115 | 115 | ||
116 | reg_con = bank->pctl_offset; | 116 | reg_con = bank->pctl_offset; |
117 | shift = edata->pin * bank->func_width; | 117 | shift = pin * bank->func_width; |
118 | mask = (1 << bank->func_width) - 1; | 118 | mask = (1 << bank->func_width) - 1; |
119 | 119 | ||
120 | con = readl(d->virt_base + reg_con); | 120 | con = readl(d->virt_base + reg_con); |
@@ -136,82 +136,23 @@ static struct irq_chip exynos_gpio_irq_chip = { | |||
136 | .irq_set_type = exynos_gpio_irq_set_type, | 136 | .irq_set_type = exynos_gpio_irq_set_type, |
137 | }; | 137 | }; |
138 | 138 | ||
139 | /* | ||
140 | * given a controller-local external gpio interrupt number, prepare the handler | ||
141 | * data for it. | ||
142 | */ | ||
143 | static struct exynos_geint_data *exynos_get_eint_data(irq_hw_number_t hw, | ||
144 | struct samsung_pinctrl_drv_data *d) | ||
145 | { | ||
146 | struct samsung_pin_bank *bank = d->ctrl->pin_banks; | ||
147 | struct exynos_geint_data *eint_data; | ||
148 | unsigned int nr_banks = d->ctrl->nr_banks, idx; | ||
149 | unsigned int irq_base = 0, eint_offset = 0; | ||
150 | |||
151 | if (hw >= d->ctrl->nr_gint) { | ||
152 | dev_err(d->dev, "unsupported ext-gpio interrupt\n"); | ||
153 | return NULL; | ||
154 | } | ||
155 | |||
156 | for (idx = 0; idx < nr_banks; idx++, bank++) { | ||
157 | if (bank->eint_type != EINT_TYPE_GPIO) | ||
158 | continue; | ||
159 | if ((hw >= irq_base) && (hw < (irq_base + bank->nr_pins))) | ||
160 | break; | ||
161 | irq_base += bank->nr_pins; | ||
162 | eint_offset += 4; | ||
163 | } | ||
164 | |||
165 | if (idx == nr_banks) { | ||
166 | dev_err(d->dev, "pin bank not found for ext-gpio interrupt\n"); | ||
167 | return NULL; | ||
168 | } | ||
169 | |||
170 | eint_data = devm_kzalloc(d->dev, sizeof(*eint_data), GFP_KERNEL); | ||
171 | if (!eint_data) { | ||
172 | dev_err(d->dev, "no memory for eint-gpio data\n"); | ||
173 | return NULL; | ||
174 | } | ||
175 | |||
176 | eint_data->bank = bank; | ||
177 | eint_data->pin = hw - irq_base; | ||
178 | eint_data->eint_offset = eint_offset; | ||
179 | return eint_data; | ||
180 | } | ||
181 | |||
182 | static int exynos_gpio_irq_map(struct irq_domain *h, unsigned int virq, | 139 | static int exynos_gpio_irq_map(struct irq_domain *h, unsigned int virq, |
183 | irq_hw_number_t hw) | 140 | irq_hw_number_t hw) |
184 | { | 141 | { |
185 | struct samsung_pinctrl_drv_data *d = h->host_data; | 142 | struct samsung_pin_bank *b = h->host_data; |
186 | struct exynos_geint_data *eint_data; | ||
187 | 143 | ||
188 | eint_data = exynos_get_eint_data(hw, d); | 144 | irq_set_chip_data(virq, b); |
189 | if (!eint_data) | ||
190 | return -EINVAL; | ||
191 | |||
192 | irq_set_handler_data(virq, eint_data); | ||
193 | irq_set_chip_data(virq, h->host_data); | ||
194 | irq_set_chip_and_handler(virq, &exynos_gpio_irq_chip, | 145 | irq_set_chip_and_handler(virq, &exynos_gpio_irq_chip, |
195 | handle_level_irq); | 146 | handle_level_irq); |
196 | set_irq_flags(virq, IRQF_VALID); | 147 | set_irq_flags(virq, IRQF_VALID); |
197 | return 0; | 148 | return 0; |
198 | } | 149 | } |
199 | 150 | ||
200 | static void exynos_gpio_irq_unmap(struct irq_domain *h, unsigned int virq) | ||
201 | { | ||
202 | struct samsung_pinctrl_drv_data *d = h->host_data; | ||
203 | struct exynos_geint_data *eint_data; | ||
204 | |||
205 | eint_data = irq_get_handler_data(virq); | ||
206 | devm_kfree(d->dev, eint_data); | ||
207 | } | ||
208 | |||
209 | /* | 151 | /* |
210 | * irq domain callbacks for external gpio interrupt controller. | 152 | * irq domain callbacks for external gpio interrupt controller. |
211 | */ | 153 | */ |
212 | static const struct irq_domain_ops exynos_gpio_irqd_ops = { | 154 | static const struct irq_domain_ops exynos_gpio_irqd_ops = { |
213 | .map = exynos_gpio_irq_map, | 155 | .map = exynos_gpio_irq_map, |
214 | .unmap = exynos_gpio_irq_unmap, | ||
215 | .xlate = irq_domain_xlate_twocell, | 156 | .xlate = irq_domain_xlate_twocell, |
216 | }; | 157 | }; |
217 | 158 | ||
@@ -230,7 +171,7 @@ static irqreturn_t exynos_eint_gpio_irq(int irq, void *data) | |||
230 | return IRQ_HANDLED; | 171 | return IRQ_HANDLED; |
231 | bank += (group - 1); | 172 | bank += (group - 1); |
232 | 173 | ||
233 | virq = irq_linear_revmap(d->gpio_irqd, bank->irq_base + pin); | 174 | virq = irq_linear_revmap(bank->irq_domain, pin); |
234 | if (!virq) | 175 | if (!virq) |
235 | return IRQ_NONE; | 176 | return IRQ_NONE; |
236 | generic_handle_irq(virq); | 177 | generic_handle_irq(virq); |
@@ -243,8 +184,10 @@ static irqreturn_t exynos_eint_gpio_irq(int irq, void *data) | |||
243 | */ | 184 | */ |
244 | static int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d) | 185 | static int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d) |
245 | { | 186 | { |
187 | struct samsung_pin_bank *bank; | ||
246 | struct device *dev = d->dev; | 188 | struct device *dev = d->dev; |
247 | unsigned int ret; | 189 | unsigned int ret; |
190 | unsigned int i; | ||
248 | 191 | ||
249 | if (!d->irq) { | 192 | if (!d->irq) { |
250 | dev_err(dev, "irq number not available\n"); | 193 | dev_err(dev, "irq number not available\n"); |
@@ -258,11 +201,16 @@ static int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d) | |||
258 | return -ENXIO; | 201 | return -ENXIO; |
259 | } | 202 | } |
260 | 203 | ||
261 | d->gpio_irqd = irq_domain_add_linear(dev->of_node, d->ctrl->nr_gint, | 204 | bank = d->ctrl->pin_banks; |
262 | &exynos_gpio_irqd_ops, d); | 205 | for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) { |
263 | if (!d->gpio_irqd) { | 206 | if (bank->eint_type != EINT_TYPE_GPIO) |
264 | dev_err(dev, "gpio irq domain allocation failed\n"); | 207 | continue; |
265 | return -ENXIO; | 208 | bank->irq_domain = irq_domain_add_linear(bank->of_node, |
209 | bank->nr_pins, &exynos_gpio_irqd_ops, bank); | ||
210 | if (!bank->irq_domain) { | ||
211 | dev_err(dev, "gpio irq domain add failed\n"); | ||
212 | return -ENXIO; | ||
213 | } | ||
266 | } | 214 | } |
267 | 215 | ||
268 | return 0; | 216 | return 0; |
@@ -270,48 +218,46 @@ static int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d) | |||
270 | 218 | ||
271 | static void exynos_wkup_irq_unmask(struct irq_data *irqd) | 219 | static void exynos_wkup_irq_unmask(struct irq_data *irqd) |
272 | { | 220 | { |
273 | struct samsung_pinctrl_drv_data *d = irq_data_get_irq_chip_data(irqd); | 221 | struct samsung_pin_bank *b = irq_data_get_irq_chip_data(irqd); |
274 | unsigned int bank = irqd->hwirq / EXYNOS_EINT_MAX_PER_BANK; | 222 | struct samsung_pinctrl_drv_data *d = b->drvdata; |
275 | unsigned int pin = irqd->hwirq & (EXYNOS_EINT_MAX_PER_BANK - 1); | 223 | unsigned long reg_mask = d->ctrl->weint_mask + b->eint_offset; |
276 | unsigned long reg_mask = d->ctrl->weint_mask + (bank << 2); | ||
277 | unsigned long mask; | 224 | unsigned long mask; |
278 | 225 | ||
279 | mask = readl(d->virt_base + reg_mask); | 226 | mask = readl(d->virt_base + reg_mask); |
280 | mask &= ~(1 << pin); | 227 | mask &= ~(1 << irqd->hwirq); |
281 | writel(mask, d->virt_base + reg_mask); | 228 | writel(mask, d->virt_base + reg_mask); |
282 | } | 229 | } |
283 | 230 | ||
284 | static void exynos_wkup_irq_mask(struct irq_data *irqd) | 231 | static void exynos_wkup_irq_mask(struct irq_data *irqd) |
285 | { | 232 | { |
286 | struct samsung_pinctrl_drv_data *d = irq_data_get_irq_chip_data(irqd); | 233 | struct samsung_pin_bank *b = irq_data_get_irq_chip_data(irqd); |
287 | unsigned int bank = irqd->hwirq / EXYNOS_EINT_MAX_PER_BANK; | 234 | struct samsung_pinctrl_drv_data *d = b->drvdata; |
288 | unsigned int pin = irqd->hwirq & (EXYNOS_EINT_MAX_PER_BANK - 1); | 235 | unsigned long reg_mask = d->ctrl->weint_mask + b->eint_offset; |
289 | unsigned long reg_mask = d->ctrl->weint_mask + (bank << 2); | ||
290 | unsigned long mask; | 236 | unsigned long mask; |
291 | 237 | ||
292 | mask = readl(d->virt_base + reg_mask); | 238 | mask = readl(d->virt_base + reg_mask); |
293 | mask |= 1 << pin; | 239 | mask |= 1 << irqd->hwirq; |
294 | writel(mask, d->virt_base + reg_mask); | 240 | writel(mask, d->virt_base + reg_mask); |
295 | } | 241 | } |
296 | 242 | ||
297 | static void exynos_wkup_irq_ack(struct irq_data *irqd) | 243 | static void exynos_wkup_irq_ack(struct irq_data *irqd) |
298 | { | 244 | { |
299 | struct samsung_pinctrl_drv_data *d = irq_data_get_irq_chip_data(irqd); | 245 | struct samsung_pin_bank *b = irq_data_get_irq_chip_data(irqd); |
300 | unsigned int bank = irqd->hwirq / EXYNOS_EINT_MAX_PER_BANK; | 246 | struct samsung_pinctrl_drv_data *d = b->drvdata; |
301 | unsigned int pin = irqd->hwirq & (EXYNOS_EINT_MAX_PER_BANK - 1); | 247 | unsigned long pend = d->ctrl->weint_pend + b->eint_offset; |
302 | unsigned long pend = d->ctrl->weint_pend + (bank << 2); | ||
303 | 248 | ||
304 | writel(1 << pin, d->virt_base + pend); | 249 | writel(1 << irqd->hwirq, d->virt_base + pend); |
305 | } | 250 | } |
306 | 251 | ||
307 | static int exynos_wkup_irq_set_type(struct irq_data *irqd, unsigned int type) | 252 | static int exynos_wkup_irq_set_type(struct irq_data *irqd, unsigned int type) |
308 | { | 253 | { |
309 | struct samsung_pinctrl_drv_data *d = irq_data_get_irq_chip_data(irqd); | 254 | struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); |
310 | unsigned int bank = irqd->hwirq / EXYNOS_EINT_MAX_PER_BANK; | 255 | struct samsung_pinctrl_drv_data *d = bank->drvdata; |
311 | unsigned int pin = irqd->hwirq & (EXYNOS_EINT_MAX_PER_BANK - 1); | 256 | unsigned int pin = irqd->hwirq; |
312 | unsigned long reg_con = d->ctrl->weint_con + (bank << 2); | 257 | unsigned long reg_con = d->ctrl->weint_con + bank->eint_offset; |
313 | unsigned long shift = EXYNOS_EINT_CON_LEN * pin; | 258 | unsigned long shift = EXYNOS_EINT_CON_LEN * pin; |
314 | unsigned long con, trig_type; | 259 | unsigned long con, trig_type; |
260 | unsigned int mask; | ||
315 | 261 | ||
316 | switch (type) { | 262 | switch (type) { |
317 | case IRQ_TYPE_EDGE_RISING: | 263 | case IRQ_TYPE_EDGE_RISING: |
@@ -343,6 +289,16 @@ static int exynos_wkup_irq_set_type(struct irq_data *irqd, unsigned int type) | |||
343 | con &= ~(EXYNOS_EINT_CON_MASK << shift); | 289 | con &= ~(EXYNOS_EINT_CON_MASK << shift); |
344 | con |= trig_type << shift; | 290 | con |= trig_type << shift; |
345 | writel(con, d->virt_base + reg_con); | 291 | writel(con, d->virt_base + reg_con); |
292 | |||
293 | reg_con = bank->pctl_offset; | ||
294 | shift = pin * bank->func_width; | ||
295 | mask = (1 << bank->func_width) - 1; | ||
296 | |||
297 | con = readl(d->virt_base + reg_con); | ||
298 | con &= ~(mask << shift); | ||
299 | con |= EXYNOS_EINT_FUNC << shift; | ||
300 | writel(con, d->virt_base + reg_con); | ||
301 | |||
346 | return 0; | 302 | return 0; |
347 | } | 303 | } |
348 | 304 | ||
@@ -361,6 +317,7 @@ static struct irq_chip exynos_wkup_irq_chip = { | |||
361 | static void exynos_irq_eint0_15(unsigned int irq, struct irq_desc *desc) | 317 | static void exynos_irq_eint0_15(unsigned int irq, struct irq_desc *desc) |
362 | { | 318 | { |
363 | struct exynos_weint_data *eintd = irq_get_handler_data(irq); | 319 | struct exynos_weint_data *eintd = irq_get_handler_data(irq); |
320 | struct samsung_pin_bank *bank = eintd->bank; | ||
364 | struct irq_chip *chip = irq_get_chip(irq); | 321 | struct irq_chip *chip = irq_get_chip(irq); |
365 | int eint_irq; | 322 | int eint_irq; |
366 | 323 | ||
@@ -370,20 +327,20 @@ static void exynos_irq_eint0_15(unsigned int irq, struct irq_desc *desc) | |||
370 | if (chip->irq_ack) | 327 | if (chip->irq_ack) |
371 | chip->irq_ack(&desc->irq_data); | 328 | chip->irq_ack(&desc->irq_data); |
372 | 329 | ||
373 | eint_irq = irq_linear_revmap(eintd->domain, eintd->irq); | 330 | eint_irq = irq_linear_revmap(bank->irq_domain, eintd->irq); |
374 | generic_handle_irq(eint_irq); | 331 | generic_handle_irq(eint_irq); |
375 | chip->irq_unmask(&desc->irq_data); | 332 | chip->irq_unmask(&desc->irq_data); |
376 | chained_irq_exit(chip, desc); | 333 | chained_irq_exit(chip, desc); |
377 | } | 334 | } |
378 | 335 | ||
379 | static inline void exynos_irq_demux_eint(int irq_base, unsigned long pend, | 336 | static inline void exynos_irq_demux_eint(unsigned long pend, |
380 | struct irq_domain *domain) | 337 | struct irq_domain *domain) |
381 | { | 338 | { |
382 | unsigned int irq; | 339 | unsigned int irq; |
383 | 340 | ||
384 | while (pend) { | 341 | while (pend) { |
385 | irq = fls(pend) - 1; | 342 | irq = fls(pend) - 1; |
386 | generic_handle_irq(irq_find_mapping(domain, irq_base + irq)); | 343 | generic_handle_irq(irq_find_mapping(domain, irq)); |
387 | pend &= ~(1 << irq); | 344 | pend &= ~(1 << irq); |
388 | } | 345 | } |
389 | } | 346 | } |
@@ -392,18 +349,22 @@ static inline void exynos_irq_demux_eint(int irq_base, unsigned long pend, | |||
392 | static void exynos_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc) | 349 | static void exynos_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc) |
393 | { | 350 | { |
394 | struct irq_chip *chip = irq_get_chip(irq); | 351 | struct irq_chip *chip = irq_get_chip(irq); |
395 | struct exynos_weint_data *eintd = irq_get_handler_data(irq); | 352 | struct exynos_muxed_weint_data *eintd = irq_get_handler_data(irq); |
396 | struct samsung_pinctrl_drv_data *d = eintd->domain->host_data; | 353 | struct samsung_pinctrl_drv_data *d = eintd->banks[0]->drvdata; |
354 | struct samsung_pin_ctrl *ctrl = d->ctrl; | ||
397 | unsigned long pend; | 355 | unsigned long pend; |
398 | unsigned long mask; | 356 | unsigned long mask; |
357 | int i; | ||
399 | 358 | ||
400 | chained_irq_enter(chip, desc); | 359 | chained_irq_enter(chip, desc); |
401 | pend = readl(d->virt_base + d->ctrl->weint_pend + 0x8); | 360 | |
402 | mask = readl(d->virt_base + d->ctrl->weint_mask + 0x8); | 361 | for (i = 0; i < eintd->nr_banks; ++i) { |
403 | exynos_irq_demux_eint(16, pend & ~mask, eintd->domain); | 362 | struct samsung_pin_bank *b = eintd->banks[i]; |
404 | pend = readl(d->virt_base + d->ctrl->weint_pend + 0xC); | 363 | pend = readl(d->virt_base + ctrl->weint_pend + b->eint_offset); |
405 | mask = readl(d->virt_base + d->ctrl->weint_mask + 0xC); | 364 | mask = readl(d->virt_base + ctrl->weint_mask + b->eint_offset); |
406 | exynos_irq_demux_eint(24, pend & ~mask, eintd->domain); | 365 | exynos_irq_demux_eint(pend & ~mask, b->irq_domain); |
366 | } | ||
367 | |||
407 | chained_irq_exit(chip, desc); | 368 | chained_irq_exit(chip, desc); |
408 | } | 369 | } |
409 | 370 | ||
@@ -433,7 +394,11 @@ static int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d) | |||
433 | struct device *dev = d->dev; | 394 | struct device *dev = d->dev; |
434 | struct device_node *wkup_np = NULL; | 395 | struct device_node *wkup_np = NULL; |
435 | struct device_node *np; | 396 | struct device_node *np; |
397 | struct samsung_pin_bank *bank; | ||
436 | struct exynos_weint_data *weint_data; | 398 | struct exynos_weint_data *weint_data; |
399 | struct exynos_muxed_weint_data *muxed_data; | ||
400 | unsigned int muxed_banks = 0; | ||
401 | unsigned int i; | ||
437 | int idx, irq; | 402 | int idx, irq; |
438 | 403 | ||
439 | for_each_child_of_node(dev->of_node, np) { | 404 | for_each_child_of_node(dev->of_node, np) { |
@@ -445,90 +410,124 @@ static int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d) | |||
445 | if (!wkup_np) | 410 | if (!wkup_np) |
446 | return -ENODEV; | 411 | return -ENODEV; |
447 | 412 | ||
448 | d->wkup_irqd = irq_domain_add_linear(wkup_np, d->ctrl->nr_wint, | 413 | bank = d->ctrl->pin_banks; |
449 | &exynos_wkup_irqd_ops, d); | 414 | for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) { |
450 | if (!d->wkup_irqd) { | 415 | if (bank->eint_type != EINT_TYPE_WKUP) |
451 | dev_err(dev, "wakeup irq domain allocation failed\n"); | 416 | continue; |
452 | return -ENXIO; | ||
453 | } | ||
454 | 417 | ||
455 | weint_data = devm_kzalloc(dev, sizeof(*weint_data) * 17, GFP_KERNEL); | 418 | bank->irq_domain = irq_domain_add_linear(bank->of_node, |
456 | if (!weint_data) { | 419 | bank->nr_pins, &exynos_wkup_irqd_ops, bank); |
457 | dev_err(dev, "could not allocate memory for weint_data\n"); | 420 | if (!bank->irq_domain) { |
458 | return -ENOMEM; | 421 | dev_err(dev, "wkup irq domain add failed\n"); |
459 | } | 422 | return -ENXIO; |
423 | } | ||
460 | 424 | ||
461 | irq = irq_of_parse_and_map(wkup_np, 16); | 425 | if (!of_find_property(bank->of_node, "interrupts", NULL)) { |
462 | if (irq) { | 426 | bank->eint_type = EINT_TYPE_WKUP_MUX; |
463 | weint_data[16].domain = d->wkup_irqd; | 427 | ++muxed_banks; |
464 | irq_set_chained_handler(irq, exynos_irq_demux_eint16_31); | 428 | continue; |
465 | irq_set_handler_data(irq, &weint_data[16]); | 429 | } |
466 | } else { | ||
467 | dev_err(dev, "irq number for EINT16-32 not found\n"); | ||
468 | } | ||
469 | 430 | ||
470 | for (idx = 0; idx < 16; idx++) { | 431 | weint_data = devm_kzalloc(dev, bank->nr_pins |
471 | weint_data[idx].domain = d->wkup_irqd; | 432 | * sizeof(*weint_data), GFP_KERNEL); |
472 | weint_data[idx].irq = idx; | 433 | if (!weint_data) { |
434 | dev_err(dev, "could not allocate memory for weint_data\n"); | ||
435 | return -ENOMEM; | ||
436 | } | ||
473 | 437 | ||
474 | irq = irq_of_parse_and_map(wkup_np, idx); | 438 | for (idx = 0; idx < bank->nr_pins; ++idx) { |
475 | if (irq) { | 439 | irq = irq_of_parse_and_map(bank->of_node, idx); |
440 | if (!irq) { | ||
441 | dev_err(dev, "irq number for eint-%s-%d not found\n", | ||
442 | bank->name, idx); | ||
443 | continue; | ||
444 | } | ||
445 | weint_data[idx].irq = idx; | ||
446 | weint_data[idx].bank = bank; | ||
476 | irq_set_handler_data(irq, &weint_data[idx]); | 447 | irq_set_handler_data(irq, &weint_data[idx]); |
477 | irq_set_chained_handler(irq, exynos_irq_eint0_15); | 448 | irq_set_chained_handler(irq, exynos_irq_eint0_15); |
478 | } else { | ||
479 | dev_err(dev, "irq number for eint-%x not found\n", idx); | ||
480 | } | 449 | } |
481 | } | 450 | } |
451 | |||
452 | if (!muxed_banks) | ||
453 | return 0; | ||
454 | |||
455 | irq = irq_of_parse_and_map(wkup_np, 0); | ||
456 | if (!irq) { | ||
457 | dev_err(dev, "irq number for muxed EINTs not found\n"); | ||
458 | return 0; | ||
459 | } | ||
460 | |||
461 | muxed_data = devm_kzalloc(dev, sizeof(*muxed_data) | ||
462 | + muxed_banks*sizeof(struct samsung_pin_bank *), GFP_KERNEL); | ||
463 | if (!muxed_data) { | ||
464 | dev_err(dev, "could not allocate memory for muxed_data\n"); | ||
465 | return -ENOMEM; | ||
466 | } | ||
467 | |||
468 | irq_set_chained_handler(irq, exynos_irq_demux_eint16_31); | ||
469 | irq_set_handler_data(irq, muxed_data); | ||
470 | |||
471 | bank = d->ctrl->pin_banks; | ||
472 | idx = 0; | ||
473 | for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) { | ||
474 | if (bank->eint_type != EINT_TYPE_WKUP_MUX) | ||
475 | continue; | ||
476 | |||
477 | muxed_data->banks[idx++] = bank; | ||
478 | } | ||
479 | muxed_data->nr_banks = muxed_banks; | ||
480 | |||
482 | return 0; | 481 | return 0; |
483 | } | 482 | } |
484 | 483 | ||
485 | /* pin banks of exynos4210 pin-controller 0 */ | 484 | /* pin banks of exynos4210 pin-controller 0 */ |
486 | static struct samsung_pin_bank exynos4210_pin_banks0[] = { | 485 | static struct samsung_pin_bank exynos4210_pin_banks0[] = { |
487 | EXYNOS_PIN_BANK_EINTG(0x000, EXYNOS4210_GPIO_A0, "gpa0"), | 486 | EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00), |
488 | EXYNOS_PIN_BANK_EINTG(0x020, EXYNOS4210_GPIO_A1, "gpa1"), | 487 | EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpa1", 0x04), |
489 | EXYNOS_PIN_BANK_EINTG(0x040, EXYNOS4210_GPIO_B, "gpb"), | 488 | EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpb", 0x08), |
490 | EXYNOS_PIN_BANK_EINTG(0x060, EXYNOS4210_GPIO_C0, "gpc0"), | 489 | EXYNOS_PIN_BANK_EINTG(5, 0x060, "gpc0", 0x0c), |
491 | EXYNOS_PIN_BANK_EINTG(0x080, EXYNOS4210_GPIO_C1, "gpc1"), | 490 | EXYNOS_PIN_BANK_EINTG(5, 0x080, "gpc1", 0x10), |
492 | EXYNOS_PIN_BANK_EINTG(0x0A0, EXYNOS4210_GPIO_D0, "gpd0"), | 491 | EXYNOS_PIN_BANK_EINTG(4, 0x0A0, "gpd0", 0x14), |
493 | EXYNOS_PIN_BANK_EINTG(0x0C0, EXYNOS4210_GPIO_D1, "gpd1"), | 492 | EXYNOS_PIN_BANK_EINTG(4, 0x0C0, "gpd1", 0x18), |
494 | EXYNOS_PIN_BANK_EINTG(0x0E0, EXYNOS4210_GPIO_E0, "gpe0"), | 493 | EXYNOS_PIN_BANK_EINTG(5, 0x0E0, "gpe0", 0x1c), |
495 | EXYNOS_PIN_BANK_EINTG(0x100, EXYNOS4210_GPIO_E1, "gpe1"), | 494 | EXYNOS_PIN_BANK_EINTG(8, 0x100, "gpe1", 0x20), |
496 | EXYNOS_PIN_BANK_EINTG(0x120, EXYNOS4210_GPIO_E2, "gpe2"), | 495 | EXYNOS_PIN_BANK_EINTG(6, 0x120, "gpe2", 0x24), |
497 | EXYNOS_PIN_BANK_EINTG(0x140, EXYNOS4210_GPIO_E3, "gpe3"), | 496 | EXYNOS_PIN_BANK_EINTG(8, 0x140, "gpe3", 0x28), |
498 | EXYNOS_PIN_BANK_EINTG(0x160, EXYNOS4210_GPIO_E4, "gpe4"), | 497 | EXYNOS_PIN_BANK_EINTG(8, 0x160, "gpe4", 0x2c), |
499 | EXYNOS_PIN_BANK_EINTG(0x180, EXYNOS4210_GPIO_F0, "gpf0"), | 498 | EXYNOS_PIN_BANK_EINTG(8, 0x180, "gpf0", 0x30), |
500 | EXYNOS_PIN_BANK_EINTG(0x1A0, EXYNOS4210_GPIO_F1, "gpf1"), | 499 | EXYNOS_PIN_BANK_EINTG(8, 0x1A0, "gpf1", 0x34), |
501 | EXYNOS_PIN_BANK_EINTG(0x1C0, EXYNOS4210_GPIO_F2, "gpf2"), | 500 | EXYNOS_PIN_BANK_EINTG(8, 0x1C0, "gpf2", 0x38), |
502 | EXYNOS_PIN_BANK_EINTG(0x1E0, EXYNOS4210_GPIO_F3, "gpf3"), | 501 | EXYNOS_PIN_BANK_EINTG(6, 0x1E0, "gpf3", 0x3c), |
503 | }; | 502 | }; |
504 | 503 | ||
505 | /* pin banks of exynos4210 pin-controller 1 */ | 504 | /* pin banks of exynos4210 pin-controller 1 */ |
506 | static struct samsung_pin_bank exynos4210_pin_banks1[] = { | 505 | static struct samsung_pin_bank exynos4210_pin_banks1[] = { |
507 | EXYNOS_PIN_BANK_EINTG(0x000, EXYNOS4210_GPIO_J0, "gpj0"), | 506 | EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpj0", 0x00), |
508 | EXYNOS_PIN_BANK_EINTG(0x020, EXYNOS4210_GPIO_J1, "gpj1"), | 507 | EXYNOS_PIN_BANK_EINTG(5, 0x020, "gpj1", 0x04), |
509 | EXYNOS_PIN_BANK_EINTG(0x040, EXYNOS4210_GPIO_K0, "gpk0"), | 508 | EXYNOS_PIN_BANK_EINTG(7, 0x040, "gpk0", 0x08), |
510 | EXYNOS_PIN_BANK_EINTG(0x060, EXYNOS4210_GPIO_K1, "gpk1"), | 509 | EXYNOS_PIN_BANK_EINTG(7, 0x060, "gpk1", 0x0c), |
511 | EXYNOS_PIN_BANK_EINTG(0x080, EXYNOS4210_GPIO_K2, "gpk2"), | 510 | EXYNOS_PIN_BANK_EINTG(7, 0x080, "gpk2", 0x10), |
512 | EXYNOS_PIN_BANK_EINTG(0x0A0, EXYNOS4210_GPIO_K3, "gpk3"), | 511 | EXYNOS_PIN_BANK_EINTG(7, 0x0A0, "gpk3", 0x14), |
513 | EXYNOS_PIN_BANK_EINTG(0x0C0, EXYNOS4210_GPIO_L0, "gpl0"), | 512 | EXYNOS_PIN_BANK_EINTG(8, 0x0C0, "gpl0", 0x18), |
514 | EXYNOS_PIN_BANK_EINTG(0x0E0, EXYNOS4210_GPIO_L1, "gpl1"), | 513 | EXYNOS_PIN_BANK_EINTG(3, 0x0E0, "gpl1", 0x1c), |
515 | EXYNOS_PIN_BANK_EINTG(0x100, EXYNOS4210_GPIO_L2, "gpl2"), | 514 | EXYNOS_PIN_BANK_EINTG(8, 0x100, "gpl2", 0x20), |
516 | EXYNOS_PIN_BANK_EINTN(0x120, EXYNOS4210_GPIO_Y0, "gpy0"), | 515 | EXYNOS_PIN_BANK_EINTN(6, 0x120, "gpy0"), |
517 | EXYNOS_PIN_BANK_EINTN(0x140, EXYNOS4210_GPIO_Y1, "gpy1"), | 516 | EXYNOS_PIN_BANK_EINTN(4, 0x140, "gpy1"), |
518 | EXYNOS_PIN_BANK_EINTN(0x160, EXYNOS4210_GPIO_Y2, "gpy2"), | 517 | EXYNOS_PIN_BANK_EINTN(6, 0x160, "gpy2"), |
519 | EXYNOS_PIN_BANK_EINTN(0x180, EXYNOS4210_GPIO_Y3, "gpy3"), | 518 | EXYNOS_PIN_BANK_EINTN(8, 0x180, "gpy3"), |
520 | EXYNOS_PIN_BANK_EINTN(0x1A0, EXYNOS4210_GPIO_Y4, "gpy4"), | 519 | EXYNOS_PIN_BANK_EINTN(8, 0x1A0, "gpy4"), |
521 | EXYNOS_PIN_BANK_EINTN(0x1C0, EXYNOS4210_GPIO_Y5, "gpy5"), | 520 | EXYNOS_PIN_BANK_EINTN(8, 0x1C0, "gpy5"), |
522 | EXYNOS_PIN_BANK_EINTN(0x1E0, EXYNOS4210_GPIO_Y6, "gpy6"), | 521 | EXYNOS_PIN_BANK_EINTN(8, 0x1E0, "gpy6"), |
523 | EXYNOS_PIN_BANK_EINTN(0xC00, EXYNOS4210_GPIO_X0, "gpx0"), | 522 | EXYNOS_PIN_BANK_EINTW(8, 0xC00, "gpx0", 0x00), |
524 | EXYNOS_PIN_BANK_EINTN(0xC20, EXYNOS4210_GPIO_X1, "gpx1"), | 523 | EXYNOS_PIN_BANK_EINTW(8, 0xC20, "gpx1", 0x04), |
525 | EXYNOS_PIN_BANK_EINTN(0xC40, EXYNOS4210_GPIO_X2, "gpx2"), | 524 | EXYNOS_PIN_BANK_EINTW(8, 0xC40, "gpx2", 0x08), |
526 | EXYNOS_PIN_BANK_EINTN(0xC60, EXYNOS4210_GPIO_X3, "gpx3"), | 525 | EXYNOS_PIN_BANK_EINTW(8, 0xC60, "gpx3", 0x0c), |
527 | }; | 526 | }; |
528 | 527 | ||
529 | /* pin banks of exynos4210 pin-controller 2 */ | 528 | /* pin banks of exynos4210 pin-controller 2 */ |
530 | static struct samsung_pin_bank exynos4210_pin_banks2[] = { | 529 | static struct samsung_pin_bank exynos4210_pin_banks2[] = { |
531 | EXYNOS_PIN_BANK_EINTN(0x000, EXYNOS4210_GPIO_Z, "gpz"), | 530 | EXYNOS_PIN_BANK_EINTN(7, 0x000, "gpz"), |
532 | }; | 531 | }; |
533 | 532 | ||
534 | /* | 533 | /* |
@@ -540,9 +539,6 @@ struct samsung_pin_ctrl exynos4210_pin_ctrl[] = { | |||
540 | /* pin-controller instance 0 data */ | 539 | /* pin-controller instance 0 data */ |
541 | .pin_banks = exynos4210_pin_banks0, | 540 | .pin_banks = exynos4210_pin_banks0, |
542 | .nr_banks = ARRAY_SIZE(exynos4210_pin_banks0), | 541 | .nr_banks = ARRAY_SIZE(exynos4210_pin_banks0), |
543 | .base = EXYNOS4210_GPIO_A0_START, | ||
544 | .nr_pins = EXYNOS4210_GPIOA_NR_PINS, | ||
545 | .nr_gint = EXYNOS4210_GPIOA_NR_GINT, | ||
546 | .geint_con = EXYNOS_GPIO_ECON_OFFSET, | 542 | .geint_con = EXYNOS_GPIO_ECON_OFFSET, |
547 | .geint_mask = EXYNOS_GPIO_EMASK_OFFSET, | 543 | .geint_mask = EXYNOS_GPIO_EMASK_OFFSET, |
548 | .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, | 544 | .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, |
@@ -553,10 +549,6 @@ struct samsung_pin_ctrl exynos4210_pin_ctrl[] = { | |||
553 | /* pin-controller instance 1 data */ | 549 | /* pin-controller instance 1 data */ |
554 | .pin_banks = exynos4210_pin_banks1, | 550 | .pin_banks = exynos4210_pin_banks1, |
555 | .nr_banks = ARRAY_SIZE(exynos4210_pin_banks1), | 551 | .nr_banks = ARRAY_SIZE(exynos4210_pin_banks1), |
556 | .base = EXYNOS4210_GPIOA_NR_PINS, | ||
557 | .nr_pins = EXYNOS4210_GPIOB_NR_PINS, | ||
558 | .nr_gint = EXYNOS4210_GPIOB_NR_GINT, | ||
559 | .nr_wint = 32, | ||
560 | .geint_con = EXYNOS_GPIO_ECON_OFFSET, | 552 | .geint_con = EXYNOS_GPIO_ECON_OFFSET, |
561 | .geint_mask = EXYNOS_GPIO_EMASK_OFFSET, | 553 | .geint_mask = EXYNOS_GPIO_EMASK_OFFSET, |
562 | .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, | 554 | .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, |
@@ -571,9 +563,6 @@ struct samsung_pin_ctrl exynos4210_pin_ctrl[] = { | |||
571 | /* pin-controller instance 2 data */ | 563 | /* pin-controller instance 2 data */ |
572 | .pin_banks = exynos4210_pin_banks2, | 564 | .pin_banks = exynos4210_pin_banks2, |
573 | .nr_banks = ARRAY_SIZE(exynos4210_pin_banks2), | 565 | .nr_banks = ARRAY_SIZE(exynos4210_pin_banks2), |
574 | .base = EXYNOS4210_GPIOA_NR_PINS + | ||
575 | EXYNOS4210_GPIOB_NR_PINS, | ||
576 | .nr_pins = EXYNOS4210_GPIOC_NR_PINS, | ||
577 | .label = "exynos4210-gpio-ctrl2", | 566 | .label = "exynos4210-gpio-ctrl2", |
578 | }, | 567 | }, |
579 | }; | 568 | }; |
diff --git a/drivers/pinctrl/pinctrl-exynos.h b/drivers/pinctrl/pinctrl-exynos.h index 31d0a06174e4..0a708890d8b4 100644 --- a/drivers/pinctrl/pinctrl-exynos.h +++ b/drivers/pinctrl/pinctrl-exynos.h | |||
@@ -17,125 +17,6 @@ | |||
17 | * (at your option) any later version. | 17 | * (at your option) any later version. |
18 | */ | 18 | */ |
19 | 19 | ||
20 | #define EXYNOS_GPIO_START(__gpio) ((__gpio##_START) + (__gpio##_NR)) | ||
21 | |||
22 | #define EXYNOS4210_GPIO_A0_NR (8) | ||
23 | #define EXYNOS4210_GPIO_A1_NR (6) | ||
24 | #define EXYNOS4210_GPIO_B_NR (8) | ||
25 | #define EXYNOS4210_GPIO_C0_NR (5) | ||
26 | #define EXYNOS4210_GPIO_C1_NR (5) | ||
27 | #define EXYNOS4210_GPIO_D0_NR (4) | ||
28 | #define EXYNOS4210_GPIO_D1_NR (4) | ||
29 | #define EXYNOS4210_GPIO_E0_NR (5) | ||
30 | #define EXYNOS4210_GPIO_E1_NR (8) | ||
31 | #define EXYNOS4210_GPIO_E2_NR (6) | ||
32 | #define EXYNOS4210_GPIO_E3_NR (8) | ||
33 | #define EXYNOS4210_GPIO_E4_NR (8) | ||
34 | #define EXYNOS4210_GPIO_F0_NR (8) | ||
35 | #define EXYNOS4210_GPIO_F1_NR (8) | ||
36 | #define EXYNOS4210_GPIO_F2_NR (8) | ||
37 | #define EXYNOS4210_GPIO_F3_NR (6) | ||
38 | #define EXYNOS4210_GPIO_J0_NR (8) | ||
39 | #define EXYNOS4210_GPIO_J1_NR (5) | ||
40 | #define EXYNOS4210_GPIO_K0_NR (7) | ||
41 | #define EXYNOS4210_GPIO_K1_NR (7) | ||
42 | #define EXYNOS4210_GPIO_K2_NR (7) | ||
43 | #define EXYNOS4210_GPIO_K3_NR (7) | ||
44 | #define EXYNOS4210_GPIO_L0_NR (8) | ||
45 | #define EXYNOS4210_GPIO_L1_NR (3) | ||
46 | #define EXYNOS4210_GPIO_L2_NR (8) | ||
47 | #define EXYNOS4210_GPIO_Y0_NR (6) | ||
48 | #define EXYNOS4210_GPIO_Y1_NR (4) | ||
49 | #define EXYNOS4210_GPIO_Y2_NR (6) | ||
50 | #define EXYNOS4210_GPIO_Y3_NR (8) | ||
51 | #define EXYNOS4210_GPIO_Y4_NR (8) | ||
52 | #define EXYNOS4210_GPIO_Y5_NR (8) | ||
53 | #define EXYNOS4210_GPIO_Y6_NR (8) | ||
54 | #define EXYNOS4210_GPIO_X0_NR (8) | ||
55 | #define EXYNOS4210_GPIO_X1_NR (8) | ||
56 | #define EXYNOS4210_GPIO_X2_NR (8) | ||
57 | #define EXYNOS4210_GPIO_X3_NR (8) | ||
58 | #define EXYNOS4210_GPIO_Z_NR (7) | ||
59 | |||
60 | enum exynos4210_gpio_xa_start { | ||
61 | EXYNOS4210_GPIO_A0_START = 0, | ||
62 | EXYNOS4210_GPIO_A1_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_A0), | ||
63 | EXYNOS4210_GPIO_B_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_A1), | ||
64 | EXYNOS4210_GPIO_C0_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_B), | ||
65 | EXYNOS4210_GPIO_C1_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_C0), | ||
66 | EXYNOS4210_GPIO_D0_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_C1), | ||
67 | EXYNOS4210_GPIO_D1_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_D0), | ||
68 | EXYNOS4210_GPIO_E0_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_D1), | ||
69 | EXYNOS4210_GPIO_E1_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_E0), | ||
70 | EXYNOS4210_GPIO_E2_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_E1), | ||
71 | EXYNOS4210_GPIO_E3_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_E2), | ||
72 | EXYNOS4210_GPIO_E4_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_E3), | ||
73 | EXYNOS4210_GPIO_F0_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_E4), | ||
74 | EXYNOS4210_GPIO_F1_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_F0), | ||
75 | EXYNOS4210_GPIO_F2_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_F1), | ||
76 | EXYNOS4210_GPIO_F3_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_F2), | ||
77 | }; | ||
78 | |||
79 | enum exynos4210_gpio_xb_start { | ||
80 | EXYNOS4210_GPIO_J0_START = 0, | ||
81 | EXYNOS4210_GPIO_J1_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_J0), | ||
82 | EXYNOS4210_GPIO_K0_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_J1), | ||
83 | EXYNOS4210_GPIO_K1_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_K0), | ||
84 | EXYNOS4210_GPIO_K2_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_K1), | ||
85 | EXYNOS4210_GPIO_K3_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_K2), | ||
86 | EXYNOS4210_GPIO_L0_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_K3), | ||
87 | EXYNOS4210_GPIO_L1_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_L0), | ||
88 | EXYNOS4210_GPIO_L2_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_L1), | ||
89 | EXYNOS4210_GPIO_Y0_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_L2), | ||
90 | EXYNOS4210_GPIO_Y1_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_Y0), | ||
91 | EXYNOS4210_GPIO_Y2_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_Y1), | ||
92 | EXYNOS4210_GPIO_Y3_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_Y2), | ||
93 | EXYNOS4210_GPIO_Y4_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_Y3), | ||
94 | EXYNOS4210_GPIO_Y5_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_Y4), | ||
95 | EXYNOS4210_GPIO_Y6_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_Y5), | ||
96 | EXYNOS4210_GPIO_X0_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_Y6), | ||
97 | EXYNOS4210_GPIO_X1_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_X0), | ||
98 | EXYNOS4210_GPIO_X2_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_X1), | ||
99 | EXYNOS4210_GPIO_X3_START = EXYNOS_GPIO_START(EXYNOS4210_GPIO_X2), | ||
100 | }; | ||
101 | |||
102 | enum exynos4210_gpio_xc_start { | ||
103 | EXYNOS4210_GPIO_Z_START = 0, | ||
104 | }; | ||
105 | |||
106 | #define EXYNOS4210_GPIO_A0_IRQ EXYNOS4210_GPIO_A0_START | ||
107 | #define EXYNOS4210_GPIO_A1_IRQ EXYNOS4210_GPIO_A1_START | ||
108 | #define EXYNOS4210_GPIO_B_IRQ EXYNOS4210_GPIO_B_START | ||
109 | #define EXYNOS4210_GPIO_C0_IRQ EXYNOS4210_GPIO_C0_START | ||
110 | #define EXYNOS4210_GPIO_C1_IRQ EXYNOS4210_GPIO_C1_START | ||
111 | #define EXYNOS4210_GPIO_D0_IRQ EXYNOS4210_GPIO_D0_START | ||
112 | #define EXYNOS4210_GPIO_D1_IRQ EXYNOS4210_GPIO_D1_START | ||
113 | #define EXYNOS4210_GPIO_E0_IRQ EXYNOS4210_GPIO_E0_START | ||
114 | #define EXYNOS4210_GPIO_E1_IRQ EXYNOS4210_GPIO_E1_START | ||
115 | #define EXYNOS4210_GPIO_E2_IRQ EXYNOS4210_GPIO_E2_START | ||
116 | #define EXYNOS4210_GPIO_E3_IRQ EXYNOS4210_GPIO_E3_START | ||
117 | #define EXYNOS4210_GPIO_E4_IRQ EXYNOS4210_GPIO_E4_START | ||
118 | #define EXYNOS4210_GPIO_F0_IRQ EXYNOS4210_GPIO_F0_START | ||
119 | #define EXYNOS4210_GPIO_F1_IRQ EXYNOS4210_GPIO_F1_START | ||
120 | #define EXYNOS4210_GPIO_F2_IRQ EXYNOS4210_GPIO_F2_START | ||
121 | #define EXYNOS4210_GPIO_F3_IRQ EXYNOS4210_GPIO_F3_START | ||
122 | #define EXYNOS4210_GPIO_J0_IRQ EXYNOS4210_GPIO_J0_START | ||
123 | #define EXYNOS4210_GPIO_J1_IRQ EXYNOS4210_GPIO_J1_START | ||
124 | #define EXYNOS4210_GPIO_K0_IRQ EXYNOS4210_GPIO_K0_START | ||
125 | #define EXYNOS4210_GPIO_K1_IRQ EXYNOS4210_GPIO_K1_START | ||
126 | #define EXYNOS4210_GPIO_K2_IRQ EXYNOS4210_GPIO_K2_START | ||
127 | #define EXYNOS4210_GPIO_K3_IRQ EXYNOS4210_GPIO_K3_START | ||
128 | #define EXYNOS4210_GPIO_L0_IRQ EXYNOS4210_GPIO_L0_START | ||
129 | #define EXYNOS4210_GPIO_L1_IRQ EXYNOS4210_GPIO_L1_START | ||
130 | #define EXYNOS4210_GPIO_L2_IRQ EXYNOS4210_GPIO_L2_START | ||
131 | #define EXYNOS4210_GPIO_Z_IRQ EXYNOS4210_GPIO_Z_START | ||
132 | |||
133 | #define EXYNOS4210_GPIOA_NR_PINS EXYNOS_GPIO_START(EXYNOS4210_GPIO_F3) | ||
134 | #define EXYNOS4210_GPIOA_NR_GINT EXYNOS_GPIO_START(EXYNOS4210_GPIO_F3) | ||
135 | #define EXYNOS4210_GPIOB_NR_PINS EXYNOS_GPIO_START(EXYNOS4210_GPIO_X3) | ||
136 | #define EXYNOS4210_GPIOB_NR_GINT EXYNOS_GPIO_START(EXYNOS4210_GPIO_L2) | ||
137 | #define EXYNOS4210_GPIOC_NR_PINS EXYNOS_GPIO_START(EXYNOS4210_GPIO_Z) | ||
138 | |||
139 | /* External GPIO and wakeup interrupt related definitions */ | 20 | /* External GPIO and wakeup interrupt related definitions */ |
140 | #define EXYNOS_GPIO_ECON_OFFSET 0x700 | 21 | #define EXYNOS_GPIO_ECON_OFFSET 0x700 |
141 | #define EXYNOS_GPIO_EMASK_OFFSET 0x900 | 22 | #define EXYNOS_GPIO_EMASK_OFFSET 0x900 |
@@ -165,11 +46,10 @@ enum exynos4210_gpio_xc_start { | |||
165 | #define EXYNOS_EINT_MAX_PER_BANK 8 | 46 | #define EXYNOS_EINT_MAX_PER_BANK 8 |
166 | #define EXYNOS_EINT_NR_WKUP_EINT | 47 | #define EXYNOS_EINT_NR_WKUP_EINT |
167 | 48 | ||
168 | #define EXYNOS_PIN_BANK_EINTN(reg, __gpio, id) \ | 49 | #define EXYNOS_PIN_BANK_EINTN(pins, reg, id) \ |
169 | { \ | 50 | { \ |
170 | .pctl_offset = reg, \ | 51 | .pctl_offset = reg, \ |
171 | .pin_base = (__gpio##_START), \ | 52 | .nr_pins = pins, \ |
172 | .nr_pins = (__gpio##_NR), \ | ||
173 | .func_width = 4, \ | 53 | .func_width = 4, \ |
174 | .pud_width = 2, \ | 54 | .pud_width = 2, \ |
175 | .drv_width = 2, \ | 55 | .drv_width = 2, \ |
@@ -179,40 +59,50 @@ enum exynos4210_gpio_xc_start { | |||
179 | .name = id \ | 59 | .name = id \ |
180 | } | 60 | } |
181 | 61 | ||
182 | #define EXYNOS_PIN_BANK_EINTG(reg, __gpio, id) \ | 62 | #define EXYNOS_PIN_BANK_EINTG(pins, reg, id, offs) \ |
183 | { \ | 63 | { \ |
184 | .pctl_offset = reg, \ | 64 | .pctl_offset = reg, \ |
185 | .pin_base = (__gpio##_START), \ | 65 | .nr_pins = pins, \ |
186 | .nr_pins = (__gpio##_NR), \ | ||
187 | .func_width = 4, \ | 66 | .func_width = 4, \ |
188 | .pud_width = 2, \ | 67 | .pud_width = 2, \ |
189 | .drv_width = 2, \ | 68 | .drv_width = 2, \ |
190 | .conpdn_width = 2, \ | 69 | .conpdn_width = 2, \ |
191 | .pudpdn_width = 2, \ | 70 | .pudpdn_width = 2, \ |
192 | .eint_type = EINT_TYPE_GPIO, \ | 71 | .eint_type = EINT_TYPE_GPIO, \ |
193 | .irq_base = (__gpio##_IRQ), \ | 72 | .eint_offset = offs, \ |
194 | .name = id \ | 73 | .name = id \ |
195 | } | 74 | } |
196 | 75 | ||
197 | /** | 76 | #define EXYNOS_PIN_BANK_EINTW(pins, reg, id, offs) \ |
198 | * struct exynos_geint_data: gpio eint specific data for irq_chip callbacks. | 77 | { \ |
199 | * @bank: pin bank from which this gpio interrupt originates. | 78 | .pctl_offset = reg, \ |
200 | * @pin: pin number within the bank. | 79 | .nr_pins = pins, \ |
201 | * @eint_offset: offset to be added to the con/pend/mask register bank base. | 80 | .func_width = 4, \ |
202 | */ | 81 | .pud_width = 2, \ |
203 | struct exynos_geint_data { | 82 | .drv_width = 2, \ |
204 | struct samsung_pin_bank *bank; | 83 | .eint_type = EINT_TYPE_WKUP, \ |
205 | u32 pin; | 84 | .eint_offset = offs, \ |
206 | u32 eint_offset; | 85 | .name = id \ |
207 | }; | 86 | } |
208 | 87 | ||
209 | /** | 88 | /** |
210 | * struct exynos_weint_data: irq specific data for all the wakeup interrupts | 89 | * struct exynos_weint_data: irq specific data for all the wakeup interrupts |
211 | * generated by the external wakeup interrupt controller. | 90 | * generated by the external wakeup interrupt controller. |
212 | * @domain: irq domain representing the external wakeup interrupts | ||
213 | * @irq: interrupt number within the domain. | 91 | * @irq: interrupt number within the domain. |
92 | * @bank: bank responsible for this interrupt | ||
214 | */ | 93 | */ |
215 | struct exynos_weint_data { | 94 | struct exynos_weint_data { |
216 | struct irq_domain *domain; | 95 | unsigned int irq; |
217 | u32 irq; | 96 | struct samsung_pin_bank *bank; |
97 | }; | ||
98 | |||
99 | /** | ||
100 | * struct exynos_muxed_weint_data: irq specific data for muxed wakeup interrupts | ||
101 | * generated by the external wakeup interrupt controller. | ||
102 | * @nr_banks: count of banks being part of the mux | ||
103 | * @banks: array of banks being part of the mux | ||
104 | */ | ||
105 | struct exynos_muxed_weint_data { | ||
106 | unsigned int nr_banks; | ||
107 | struct samsung_pin_bank *banks[]; | ||
218 | }; | 108 | }; |
diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c index 861cd5f04d5e..fc34cac8a1b0 100644 --- a/drivers/pinctrl/pinctrl-samsung.c +++ b/drivers/pinctrl/pinctrl-samsung.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
27 | #include <linux/err.h> | 27 | #include <linux/err.h> |
28 | #include <linux/gpio.h> | 28 | #include <linux/gpio.h> |
29 | #include <linux/irqdomain.h> | ||
29 | 30 | ||
30 | #include "core.h" | 31 | #include "core.h" |
31 | #include "pinctrl-samsung.h" | 32 | #include "pinctrl-samsung.h" |
@@ -46,6 +47,13 @@ struct pin_config { | |||
46 | { "samsung,pin-pud-pdn", PINCFG_TYPE_PUD_PDN }, | 47 | { "samsung,pin-pud-pdn", PINCFG_TYPE_PUD_PDN }, |
47 | }; | 48 | }; |
48 | 49 | ||
50 | static unsigned int pin_base = 0; | ||
51 | |||
52 | static inline struct samsung_pin_bank *gc_to_pin_bank(struct gpio_chip *gc) | ||
53 | { | ||
54 | return container_of(gc, struct samsung_pin_bank, gpio_chip); | ||
55 | } | ||
56 | |||
49 | /* check if the selector is a valid pin group selector */ | 57 | /* check if the selector is a valid pin group selector */ |
50 | static int samsung_get_group_count(struct pinctrl_dev *pctldev) | 58 | static int samsung_get_group_count(struct pinctrl_dev *pctldev) |
51 | { | 59 | { |
@@ -250,14 +258,12 @@ static int samsung_pinmux_get_groups(struct pinctrl_dev *pctldev, | |||
250 | * given a pin number that is local to a pin controller, find out the pin bank | 258 | * given a pin number that is local to a pin controller, find out the pin bank |
251 | * and the register base of the pin bank. | 259 | * and the register base of the pin bank. |
252 | */ | 260 | */ |
253 | static void pin_to_reg_bank(struct gpio_chip *gc, unsigned pin, | 261 | static void pin_to_reg_bank(struct samsung_pinctrl_drv_data *drvdata, |
254 | void __iomem **reg, u32 *offset, | 262 | unsigned pin, void __iomem **reg, u32 *offset, |
255 | struct samsung_pin_bank **bank) | 263 | struct samsung_pin_bank **bank) |
256 | { | 264 | { |
257 | struct samsung_pinctrl_drv_data *drvdata; | ||
258 | struct samsung_pin_bank *b; | 265 | struct samsung_pin_bank *b; |
259 | 266 | ||
260 | drvdata = dev_get_drvdata(gc->dev); | ||
261 | b = drvdata->ctrl->pin_banks; | 267 | b = drvdata->ctrl->pin_banks; |
262 | 268 | ||
263 | while ((pin >= b->pin_base) && | 269 | while ((pin >= b->pin_base) && |
@@ -292,7 +298,7 @@ static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector, | |||
292 | * pin function number in the config register. | 298 | * pin function number in the config register. |
293 | */ | 299 | */ |
294 | for (cnt = 0; cnt < drvdata->pin_groups[group].num_pins; cnt++) { | 300 | for (cnt = 0; cnt < drvdata->pin_groups[group].num_pins; cnt++) { |
295 | pin_to_reg_bank(drvdata->gc, pins[cnt] - drvdata->ctrl->base, | 301 | pin_to_reg_bank(drvdata, pins[cnt] - drvdata->ctrl->base, |
296 | ®, &pin_offset, &bank); | 302 | ®, &pin_offset, &bank); |
297 | mask = (1 << bank->func_width) - 1; | 303 | mask = (1 << bank->func_width) - 1; |
298 | shift = pin_offset * bank->func_width; | 304 | shift = pin_offset * bank->func_width; |
@@ -329,10 +335,16 @@ static int samsung_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev, | |||
329 | struct pinctrl_gpio_range *range, unsigned offset, bool input) | 335 | struct pinctrl_gpio_range *range, unsigned offset, bool input) |
330 | { | 336 | { |
331 | struct samsung_pin_bank *bank; | 337 | struct samsung_pin_bank *bank; |
338 | struct samsung_pinctrl_drv_data *drvdata; | ||
332 | void __iomem *reg; | 339 | void __iomem *reg; |
333 | u32 data, pin_offset, mask, shift; | 340 | u32 data, pin_offset, mask, shift; |
334 | 341 | ||
335 | pin_to_reg_bank(range->gc, offset, ®, &pin_offset, &bank); | 342 | bank = gc_to_pin_bank(range->gc); |
343 | drvdata = pinctrl_dev_get_drvdata(pctldev); | ||
344 | |||
345 | pin_offset = offset - bank->pin_base; | ||
346 | reg = drvdata->virt_base + bank->pctl_offset; | ||
347 | |||
336 | mask = (1 << bank->func_width) - 1; | 348 | mask = (1 << bank->func_width) - 1; |
337 | shift = pin_offset * bank->func_width; | 349 | shift = pin_offset * bank->func_width; |
338 | 350 | ||
@@ -366,7 +378,7 @@ static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin, | |||
366 | u32 cfg_value, cfg_reg; | 378 | u32 cfg_value, cfg_reg; |
367 | 379 | ||
368 | drvdata = pinctrl_dev_get_drvdata(pctldev); | 380 | drvdata = pinctrl_dev_get_drvdata(pctldev); |
369 | pin_to_reg_bank(drvdata->gc, pin - drvdata->ctrl->base, ®_base, | 381 | pin_to_reg_bank(drvdata, pin - drvdata->ctrl->base, ®_base, |
370 | &pin_offset, &bank); | 382 | &pin_offset, &bank); |
371 | 383 | ||
372 | switch (cfg_type) { | 384 | switch (cfg_type) { |
@@ -391,6 +403,9 @@ static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin, | |||
391 | return -EINVAL; | 403 | return -EINVAL; |
392 | } | 404 | } |
393 | 405 | ||
406 | if (!width) | ||
407 | return -EINVAL; | ||
408 | |||
394 | mask = (1 << width) - 1; | 409 | mask = (1 << width) - 1; |
395 | shift = pin_offset * width; | 410 | shift = pin_offset * width; |
396 | data = readl(reg_base + cfg_reg); | 411 | data = readl(reg_base + cfg_reg); |
@@ -463,14 +478,16 @@ static struct pinconf_ops samsung_pinconf_ops = { | |||
463 | /* gpiolib gpio_set callback function */ | 478 | /* gpiolib gpio_set callback function */ |
464 | static void samsung_gpio_set(struct gpio_chip *gc, unsigned offset, int value) | 479 | static void samsung_gpio_set(struct gpio_chip *gc, unsigned offset, int value) |
465 | { | 480 | { |
481 | struct samsung_pin_bank *bank = gc_to_pin_bank(gc); | ||
466 | void __iomem *reg; | 482 | void __iomem *reg; |
467 | u32 pin_offset, data; | 483 | u32 data; |
484 | |||
485 | reg = bank->drvdata->virt_base + bank->pctl_offset; | ||
468 | 486 | ||
469 | pin_to_reg_bank(gc, offset, ®, &pin_offset, NULL); | ||
470 | data = readl(reg + DAT_REG); | 487 | data = readl(reg + DAT_REG); |
471 | data &= ~(1 << pin_offset); | 488 | data &= ~(1 << offset); |
472 | if (value) | 489 | if (value) |
473 | data |= 1 << pin_offset; | 490 | data |= 1 << offset; |
474 | writel(data, reg + DAT_REG); | 491 | writel(data, reg + DAT_REG); |
475 | } | 492 | } |
476 | 493 | ||
@@ -478,11 +495,13 @@ static void samsung_gpio_set(struct gpio_chip *gc, unsigned offset, int value) | |||
478 | static int samsung_gpio_get(struct gpio_chip *gc, unsigned offset) | 495 | static int samsung_gpio_get(struct gpio_chip *gc, unsigned offset) |
479 | { | 496 | { |
480 | void __iomem *reg; | 497 | void __iomem *reg; |
481 | u32 pin_offset, data; | 498 | u32 data; |
499 | struct samsung_pin_bank *bank = gc_to_pin_bank(gc); | ||
500 | |||
501 | reg = bank->drvdata->virt_base + bank->pctl_offset; | ||
482 | 502 | ||
483 | pin_to_reg_bank(gc, offset, ®, &pin_offset, NULL); | ||
484 | data = readl(reg + DAT_REG); | 503 | data = readl(reg + DAT_REG); |
485 | data >>= pin_offset; | 504 | data >>= offset; |
486 | data &= 1; | 505 | data &= 1; |
487 | return data; | 506 | return data; |
488 | } | 507 | } |
@@ -510,6 +529,23 @@ static int samsung_gpio_direction_output(struct gpio_chip *gc, unsigned offset, | |||
510 | } | 529 | } |
511 | 530 | ||
512 | /* | 531 | /* |
532 | * gpiolib gpio_to_irq callback function. Creates a mapping between a GPIO pin | ||
533 | * and a virtual IRQ, if not already present. | ||
534 | */ | ||
535 | static int samsung_gpio_to_irq(struct gpio_chip *gc, unsigned offset) | ||
536 | { | ||
537 | struct samsung_pin_bank *bank = gc_to_pin_bank(gc); | ||
538 | unsigned int virq; | ||
539 | |||
540 | if (!bank->irq_domain) | ||
541 | return -ENXIO; | ||
542 | |||
543 | virq = irq_create_mapping(bank->irq_domain, offset); | ||
544 | |||
545 | return (virq) ? : -ENXIO; | ||
546 | } | ||
547 | |||
548 | /* | ||
513 | * Parse the pin names listed in the 'samsung,pins' property and convert it | 549 | * Parse the pin names listed in the 'samsung,pins' property and convert it |
514 | * into a list of gpio numbers are create a pin group from it. | 550 | * into a list of gpio numbers are create a pin group from it. |
515 | */ | 551 | */ |
@@ -597,7 +633,7 @@ static int __devinit samsung_pinctrl_parse_dt(struct platform_device *pdev, | |||
597 | */ | 633 | */ |
598 | for_each_child_of_node(dev_np, cfg_np) { | 634 | for_each_child_of_node(dev_np, cfg_np) { |
599 | u32 function; | 635 | u32 function; |
600 | if (of_find_property(cfg_np, "interrupt-controller", NULL)) | 636 | if (!of_find_property(cfg_np, "samsung,pins", NULL)) |
601 | continue; | 637 | continue; |
602 | 638 | ||
603 | ret = samsung_pinctrl_parse_dt_pins(pdev, cfg_np, | 639 | ret = samsung_pinctrl_parse_dt_pins(pdev, cfg_np, |
@@ -712,12 +748,16 @@ static int __devinit samsung_pinctrl_register(struct platform_device *pdev, | |||
712 | return -EINVAL; | 748 | return -EINVAL; |
713 | } | 749 | } |
714 | 750 | ||
715 | drvdata->grange.name = "samsung-pctrl-gpio-range"; | 751 | for (bank = 0; bank < drvdata->ctrl->nr_banks; ++bank) { |
716 | drvdata->grange.id = 0; | 752 | pin_bank = &drvdata->ctrl->pin_banks[bank]; |
717 | drvdata->grange.base = drvdata->ctrl->base; | 753 | pin_bank->grange.name = pin_bank->name; |
718 | drvdata->grange.npins = drvdata->ctrl->nr_pins; | 754 | pin_bank->grange.id = bank; |
719 | drvdata->grange.gc = drvdata->gc; | 755 | pin_bank->grange.pin_base = pin_bank->pin_base; |
720 | pinctrl_add_gpio_range(drvdata->pctl_dev, &drvdata->grange); | 756 | pin_bank->grange.base = pin_bank->gpio_chip.base; |
757 | pin_bank->grange.npins = pin_bank->gpio_chip.ngpio; | ||
758 | pin_bank->grange.gc = &pin_bank->gpio_chip; | ||
759 | pinctrl_add_gpio_range(drvdata->pctl_dev, &pin_bank->grange); | ||
760 | } | ||
721 | 761 | ||
722 | ret = samsung_pinctrl_parse_dt(pdev, drvdata); | 762 | ret = samsung_pinctrl_parse_dt(pdev, drvdata); |
723 | if (ret) { | 763 | if (ret) { |
@@ -728,68 +768,117 @@ static int __devinit samsung_pinctrl_register(struct platform_device *pdev, | |||
728 | return 0; | 768 | return 0; |
729 | } | 769 | } |
730 | 770 | ||
771 | static const struct gpio_chip samsung_gpiolib_chip = { | ||
772 | .set = samsung_gpio_set, | ||
773 | .get = samsung_gpio_get, | ||
774 | .direction_input = samsung_gpio_direction_input, | ||
775 | .direction_output = samsung_gpio_direction_output, | ||
776 | .to_irq = samsung_gpio_to_irq, | ||
777 | .owner = THIS_MODULE, | ||
778 | }; | ||
779 | |||
731 | /* register the gpiolib interface with the gpiolib subsystem */ | 780 | /* register the gpiolib interface with the gpiolib subsystem */ |
732 | static int __devinit samsung_gpiolib_register(struct platform_device *pdev, | 781 | static int __devinit samsung_gpiolib_register(struct platform_device *pdev, |
733 | struct samsung_pinctrl_drv_data *drvdata) | 782 | struct samsung_pinctrl_drv_data *drvdata) |
734 | { | 783 | { |
784 | struct samsung_pin_ctrl *ctrl = drvdata->ctrl; | ||
785 | struct samsung_pin_bank *bank = ctrl->pin_banks; | ||
735 | struct gpio_chip *gc; | 786 | struct gpio_chip *gc; |
736 | int ret; | 787 | int ret; |
737 | 788 | int i; | |
738 | gc = devm_kzalloc(&pdev->dev, sizeof(*gc), GFP_KERNEL); | 789 | |
739 | if (!gc) { | 790 | for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { |
740 | dev_err(&pdev->dev, "mem alloc for gpio_chip failed\n"); | 791 | bank->gpio_chip = samsung_gpiolib_chip; |
741 | return -ENOMEM; | 792 | |
742 | } | 793 | gc = &bank->gpio_chip; |
743 | 794 | gc->base = ctrl->base + bank->pin_base; | |
744 | drvdata->gc = gc; | 795 | gc->ngpio = bank->nr_pins; |
745 | gc->base = drvdata->ctrl->base; | 796 | gc->dev = &pdev->dev; |
746 | gc->ngpio = drvdata->ctrl->nr_pins; | 797 | gc->of_node = bank->of_node; |
747 | gc->dev = &pdev->dev; | 798 | gc->label = bank->name; |
748 | gc->set = samsung_gpio_set; | 799 | |
749 | gc->get = samsung_gpio_get; | 800 | ret = gpiochip_add(gc); |
750 | gc->direction_input = samsung_gpio_direction_input; | 801 | if (ret) { |
751 | gc->direction_output = samsung_gpio_direction_output; | 802 | dev_err(&pdev->dev, "failed to register gpio_chip %s, error code: %d\n", |
752 | gc->label = drvdata->ctrl->label; | 803 | gc->label, ret); |
753 | gc->owner = THIS_MODULE; | 804 | goto fail; |
754 | ret = gpiochip_add(gc); | 805 | } |
755 | if (ret) { | ||
756 | dev_err(&pdev->dev, "failed to register gpio_chip %s, error " | ||
757 | "code: %d\n", gc->label, ret); | ||
758 | return ret; | ||
759 | } | 806 | } |
760 | 807 | ||
761 | return 0; | 808 | return 0; |
809 | |||
810 | fail: | ||
811 | for (--i, --bank; i >= 0; --i, --bank) | ||
812 | if (gpiochip_remove(&bank->gpio_chip)) | ||
813 | dev_err(&pdev->dev, "gpio chip %s remove failed\n", | ||
814 | bank->gpio_chip.label); | ||
815 | return ret; | ||
762 | } | 816 | } |
763 | 817 | ||
764 | /* unregister the gpiolib interface with the gpiolib subsystem */ | 818 | /* unregister the gpiolib interface with the gpiolib subsystem */ |
765 | static int __devinit samsung_gpiolib_unregister(struct platform_device *pdev, | 819 | static int __devinit samsung_gpiolib_unregister(struct platform_device *pdev, |
766 | struct samsung_pinctrl_drv_data *drvdata) | 820 | struct samsung_pinctrl_drv_data *drvdata) |
767 | { | 821 | { |
768 | int ret = gpiochip_remove(drvdata->gc); | 822 | struct samsung_pin_ctrl *ctrl = drvdata->ctrl; |
769 | if (ret) { | 823 | struct samsung_pin_bank *bank = ctrl->pin_banks; |
824 | int ret = 0; | ||
825 | int i; | ||
826 | |||
827 | for (i = 0; !ret && i < ctrl->nr_banks; ++i, ++bank) | ||
828 | ret = gpiochip_remove(&bank->gpio_chip); | ||
829 | |||
830 | if (ret) | ||
770 | dev_err(&pdev->dev, "gpio chip remove failed\n"); | 831 | dev_err(&pdev->dev, "gpio chip remove failed\n"); |
771 | return ret; | 832 | |
772 | } | 833 | return ret; |
773 | return 0; | ||
774 | } | 834 | } |
775 | 835 | ||
776 | static const struct of_device_id samsung_pinctrl_dt_match[]; | 836 | static const struct of_device_id samsung_pinctrl_dt_match[]; |
777 | 837 | ||
778 | /* retrieve the soc specific data */ | 838 | /* retrieve the soc specific data */ |
779 | static struct samsung_pin_ctrl *samsung_pinctrl_get_soc_data( | 839 | static struct samsung_pin_ctrl *samsung_pinctrl_get_soc_data( |
840 | struct samsung_pinctrl_drv_data *d, | ||
780 | struct platform_device *pdev) | 841 | struct platform_device *pdev) |
781 | { | 842 | { |
782 | int id; | 843 | int id; |
783 | const struct of_device_id *match; | 844 | const struct of_device_id *match; |
784 | const struct device_node *node = pdev->dev.of_node; | 845 | struct device_node *node = pdev->dev.of_node; |
846 | struct device_node *np; | ||
847 | struct samsung_pin_ctrl *ctrl; | ||
848 | struct samsung_pin_bank *bank; | ||
849 | int i; | ||
785 | 850 | ||
786 | id = of_alias_get_id(pdev->dev.of_node, "pinctrl"); | 851 | id = of_alias_get_id(node, "pinctrl"); |
787 | if (id < 0) { | 852 | if (id < 0) { |
788 | dev_err(&pdev->dev, "failed to get alias id\n"); | 853 | dev_err(&pdev->dev, "failed to get alias id\n"); |
789 | return NULL; | 854 | return NULL; |
790 | } | 855 | } |
791 | match = of_match_node(samsung_pinctrl_dt_match, node); | 856 | match = of_match_node(samsung_pinctrl_dt_match, node); |
792 | return (struct samsung_pin_ctrl *)match->data + id; | 857 | ctrl = (struct samsung_pin_ctrl *)match->data + id; |
858 | |||
859 | bank = ctrl->pin_banks; | ||
860 | for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { | ||
861 | bank->drvdata = d; | ||
862 | bank->pin_base = ctrl->nr_pins; | ||
863 | ctrl->nr_pins += bank->nr_pins; | ||
864 | } | ||
865 | |||
866 | for_each_child_of_node(node, np) { | ||
867 | if (!of_find_property(np, "gpio-controller", NULL)) | ||
868 | continue; | ||
869 | bank = ctrl->pin_banks; | ||
870 | for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { | ||
871 | if (!strcmp(bank->name, np->name)) { | ||
872 | bank->of_node = np; | ||
873 | break; | ||
874 | } | ||
875 | } | ||
876 | } | ||
877 | |||
878 | ctrl->base = pin_base; | ||
879 | pin_base += ctrl->nr_pins; | ||
880 | |||
881 | return ctrl; | ||
793 | } | 882 | } |
794 | 883 | ||
795 | static int __devinit samsung_pinctrl_probe(struct platform_device *pdev) | 884 | static int __devinit samsung_pinctrl_probe(struct platform_device *pdev) |
@@ -805,18 +894,18 @@ static int __devinit samsung_pinctrl_probe(struct platform_device *pdev) | |||
805 | return -ENODEV; | 894 | return -ENODEV; |
806 | } | 895 | } |
807 | 896 | ||
808 | ctrl = samsung_pinctrl_get_soc_data(pdev); | ||
809 | if (!ctrl) { | ||
810 | dev_err(&pdev->dev, "driver data not available\n"); | ||
811 | return -EINVAL; | ||
812 | } | ||
813 | |||
814 | drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); | 897 | drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); |
815 | if (!drvdata) { | 898 | if (!drvdata) { |
816 | dev_err(dev, "failed to allocate memory for driver's " | 899 | dev_err(dev, "failed to allocate memory for driver's " |
817 | "private data\n"); | 900 | "private data\n"); |
818 | return -ENOMEM; | 901 | return -ENOMEM; |
819 | } | 902 | } |
903 | |||
904 | ctrl = samsung_pinctrl_get_soc_data(drvdata, pdev); | ||
905 | if (!ctrl) { | ||
906 | dev_err(&pdev->dev, "driver data not available\n"); | ||
907 | return -EINVAL; | ||
908 | } | ||
820 | drvdata->ctrl = ctrl; | 909 | drvdata->ctrl = ctrl; |
821 | drvdata->dev = dev; | 910 | drvdata->dev = dev; |
822 | 911 | ||
diff --git a/drivers/pinctrl/pinctrl-samsung.h b/drivers/pinctrl/pinctrl-samsung.h index b8956934cda6..0670d9ea43fa 100644 --- a/drivers/pinctrl/pinctrl-samsung.h +++ b/drivers/pinctrl/pinctrl-samsung.h | |||
@@ -23,6 +23,8 @@ | |||
23 | #include <linux/pinctrl/consumer.h> | 23 | #include <linux/pinctrl/consumer.h> |
24 | #include <linux/pinctrl/machine.h> | 24 | #include <linux/pinctrl/machine.h> |
25 | 25 | ||
26 | #include <linux/gpio.h> | ||
27 | |||
26 | /* register offsets within a pin bank */ | 28 | /* register offsets within a pin bank */ |
27 | #define DAT_REG 0x4 | 29 | #define DAT_REG 0x4 |
28 | #define PUD_REG 0x8 | 30 | #define PUD_REG 0x8 |
@@ -64,6 +66,7 @@ enum pincfg_type { | |||
64 | * @EINT_TYPE_NONE: bank does not support external interrupts | 66 | * @EINT_TYPE_NONE: bank does not support external interrupts |
65 | * @EINT_TYPE_GPIO: bank supportes external gpio interrupts | 67 | * @EINT_TYPE_GPIO: bank supportes external gpio interrupts |
66 | * @EINT_TYPE_WKUP: bank supportes external wakeup interrupts | 68 | * @EINT_TYPE_WKUP: bank supportes external wakeup interrupts |
69 | * @EINT_TYPE_WKUP_MUX: bank supports multiplexed external wakeup interrupts | ||
67 | * | 70 | * |
68 | * Samsung GPIO controller groups all the available pins into banks. The pins | 71 | * Samsung GPIO controller groups all the available pins into banks. The pins |
69 | * in a pin bank can support external gpio interrupts or external wakeup | 72 | * in a pin bank can support external gpio interrupts or external wakeup |
@@ -76,6 +79,7 @@ enum eint_type { | |||
76 | EINT_TYPE_NONE, | 79 | EINT_TYPE_NONE, |
77 | EINT_TYPE_GPIO, | 80 | EINT_TYPE_GPIO, |
78 | EINT_TYPE_WKUP, | 81 | EINT_TYPE_WKUP, |
82 | EINT_TYPE_WKUP_MUX, | ||
79 | }; | 83 | }; |
80 | 84 | ||
81 | /* maximum length of a pin in pin descriptor (example: "gpa0-0") */ | 85 | /* maximum length of a pin in pin descriptor (example: "gpa0-0") */ |
@@ -109,8 +113,12 @@ struct samsung_pinctrl_drv_data; | |||
109 | * @conpdn_width: width of the sleep mode function selector bin field. | 113 | * @conpdn_width: width of the sleep mode function selector bin field. |
110 | * @pudpdn_width: width of the sleep mode pull up/down selector bit field. | 114 | * @pudpdn_width: width of the sleep mode pull up/down selector bit field. |
111 | * @eint_type: type of the external interrupt supported by the bank. | 115 | * @eint_type: type of the external interrupt supported by the bank. |
112 | * @irq_base: starting controller local irq number of the bank. | ||
113 | * @name: name to be prefixed for each pin in this pin bank. | 116 | * @name: name to be prefixed for each pin in this pin bank. |
117 | * @of_node: OF node of the bank. | ||
118 | * @drvdata: link to controller driver data | ||
119 | * @irq_domain: IRQ domain of the bank. | ||
120 | * @gpio_chip: GPIO chip of the bank. | ||
121 | * @grange: linux gpio pin range supported by this bank. | ||
114 | */ | 122 | */ |
115 | struct samsung_pin_bank { | 123 | struct samsung_pin_bank { |
116 | u32 pctl_offset; | 124 | u32 pctl_offset; |
@@ -122,8 +130,13 @@ struct samsung_pin_bank { | |||
122 | u8 conpdn_width; | 130 | u8 conpdn_width; |
123 | u8 pudpdn_width; | 131 | u8 pudpdn_width; |
124 | enum eint_type eint_type; | 132 | enum eint_type eint_type; |
125 | u32 irq_base; | 133 | u32 eint_offset; |
126 | char *name; | 134 | char *name; |
135 | struct device_node *of_node; | ||
136 | struct samsung_pinctrl_drv_data *drvdata; | ||
137 | struct irq_domain *irq_domain; | ||
138 | struct gpio_chip gpio_chip; | ||
139 | struct pinctrl_gpio_range grange; | ||
127 | }; | 140 | }; |
128 | 141 | ||
129 | /** | 142 | /** |
@@ -132,8 +145,6 @@ struct samsung_pin_bank { | |||
132 | * @nr_banks: number of pin banks. | 145 | * @nr_banks: number of pin banks. |
133 | * @base: starting system wide pin number. | 146 | * @base: starting system wide pin number. |
134 | * @nr_pins: number of pins supported by the controller. | 147 | * @nr_pins: number of pins supported by the controller. |
135 | * @nr_gint: number of external gpio interrupts supported. | ||
136 | * @nr_wint: number of external wakeup interrupts supported. | ||
137 | * @geint_con: offset of the ext-gpio controller registers. | 148 | * @geint_con: offset of the ext-gpio controller registers. |
138 | * @geint_mask: offset of the ext-gpio interrupt mask registers. | 149 | * @geint_mask: offset of the ext-gpio interrupt mask registers. |
139 | * @geint_pend: offset of the ext-gpio interrupt pending registers. | 150 | * @geint_pend: offset of the ext-gpio interrupt pending registers. |
@@ -153,8 +164,6 @@ struct samsung_pin_ctrl { | |||
153 | 164 | ||
154 | u32 base; | 165 | u32 base; |
155 | u32 nr_pins; | 166 | u32 nr_pins; |
156 | u32 nr_gint; | ||
157 | u32 nr_wint; | ||
158 | 167 | ||
159 | u32 geint_con; | 168 | u32 geint_con; |
160 | u32 geint_mask; | 169 | u32 geint_mask; |
@@ -183,8 +192,6 @@ struct samsung_pin_ctrl { | |||
183 | * @nr_groups: number of such pin groups. | 192 | * @nr_groups: number of such pin groups. |
184 | * @pmx_functions: list of pin functions available to the driver. | 193 | * @pmx_functions: list of pin functions available to the driver. |
185 | * @nr_function: number of such pin functions. | 194 | * @nr_function: number of such pin functions. |
186 | * @gc: gpio_chip instance registered with gpiolib. | ||
187 | * @grange: linux gpio pin range supported by this controller. | ||
188 | */ | 195 | */ |
189 | struct samsung_pinctrl_drv_data { | 196 | struct samsung_pinctrl_drv_data { |
190 | void __iomem *virt_base; | 197 | void __iomem *virt_base; |
@@ -199,12 +206,6 @@ struct samsung_pinctrl_drv_data { | |||
199 | unsigned int nr_groups; | 206 | unsigned int nr_groups; |
200 | const struct samsung_pmx_func *pmx_functions; | 207 | const struct samsung_pmx_func *pmx_functions; |
201 | unsigned int nr_functions; | 208 | unsigned int nr_functions; |
202 | |||
203 | struct irq_domain *gpio_irqd; | ||
204 | struct irq_domain *wkup_irqd; | ||
205 | |||
206 | struct gpio_chip *gc; | ||
207 | struct pinctrl_gpio_range grange; | ||
208 | }; | 209 | }; |
209 | 210 | ||
210 | /** | 211 | /** |