.. | .. |
---|
38 | 38 | u32 eint_con; |
---|
39 | 39 | u32 eint_mask; |
---|
40 | 40 | u32 eint_pend; |
---|
41 | | - u32 eint_wake_mask_value; |
---|
| 41 | + u32 *eint_wake_mask_value; |
---|
42 | 42 | u32 eint_wake_mask_reg; |
---|
43 | 43 | void (*set_eint_wakeup_mask)(struct samsung_pinctrl_drv_data *drvdata, |
---|
44 | 44 | struct exynos_irq_chip *irq_chip); |
---|
.. | .. |
---|
207 | 207 | /* |
---|
208 | 208 | * irq_chip for gpio interrupts. |
---|
209 | 209 | */ |
---|
210 | | -static struct exynos_irq_chip exynos_gpio_irq_chip = { |
---|
| 210 | +static const struct exynos_irq_chip exynos_gpio_irq_chip __initconst = { |
---|
211 | 211 | .chip = { |
---|
212 | 212 | .name = "exynos_gpio_irq_chip", |
---|
213 | 213 | .irq_unmask = exynos_irq_unmask, |
---|
.. | .. |
---|
274 | 274 | * exynos_eint_gpio_init() - setup handling of external gpio interrupts. |
---|
275 | 275 | * @d: driver data of samsung pinctrl driver. |
---|
276 | 276 | */ |
---|
277 | | -int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d) |
---|
| 277 | +__init int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d) |
---|
278 | 278 | { |
---|
279 | 279 | struct samsung_pin_bank *bank; |
---|
280 | 280 | struct device *dev = d->dev; |
---|
.. | .. |
---|
297 | 297 | for (i = 0; i < d->nr_banks; ++i, ++bank) { |
---|
298 | 298 | if (bank->eint_type != EINT_TYPE_GPIO) |
---|
299 | 299 | continue; |
---|
| 300 | + |
---|
| 301 | + bank->irq_chip = devm_kmemdup(dev, &exynos_gpio_irq_chip, |
---|
| 302 | + sizeof(*bank->irq_chip), GFP_KERNEL); |
---|
| 303 | + if (!bank->irq_chip) { |
---|
| 304 | + ret = -ENOMEM; |
---|
| 305 | + goto err_domains; |
---|
| 306 | + } |
---|
| 307 | + bank->irq_chip->chip.name = bank->name; |
---|
| 308 | + |
---|
300 | 309 | bank->irq_domain = irq_domain_add_linear(bank->of_node, |
---|
301 | 310 | bank->nr_pins, &exynos_eint_irqd_ops, bank); |
---|
302 | 311 | if (!bank->irq_domain) { |
---|
.. | .. |
---|
313 | 322 | goto err_domains; |
---|
314 | 323 | } |
---|
315 | 324 | |
---|
316 | | - bank->irq_chip = &exynos_gpio_irq_chip; |
---|
317 | 325 | } |
---|
318 | 326 | |
---|
319 | 327 | return 0; |
---|
.. | .. |
---|
328 | 336 | return ret; |
---|
329 | 337 | } |
---|
330 | 338 | |
---|
331 | | -static u32 exynos_eint_wake_mask = 0xffffffff; |
---|
332 | | - |
---|
333 | | -u32 exynos_get_eint_wake_mask(void) |
---|
334 | | -{ |
---|
335 | | - return exynos_eint_wake_mask; |
---|
336 | | -} |
---|
337 | | - |
---|
338 | 339 | static int exynos_wkup_irq_set_wake(struct irq_data *irqd, unsigned int on) |
---|
339 | 340 | { |
---|
340 | 341 | struct irq_chip *chip = irq_data_get_irq_chip(irqd); |
---|
.. | .. |
---|
345 | 346 | pr_info("wake %s for irq %d\n", on ? "enabled" : "disabled", irqd->irq); |
---|
346 | 347 | |
---|
347 | 348 | if (!on) |
---|
348 | | - exynos_eint_wake_mask |= bit; |
---|
| 349 | + *our_chip->eint_wake_mask_value |= bit; |
---|
349 | 350 | else |
---|
350 | | - exynos_eint_wake_mask &= ~bit; |
---|
351 | | - our_chip->eint_wake_mask_value = exynos_eint_wake_mask; |
---|
| 351 | + *our_chip->eint_wake_mask_value &= ~bit; |
---|
352 | 352 | |
---|
353 | 353 | return 0; |
---|
354 | 354 | } |
---|
.. | .. |
---|
368 | 368 | pmu_regs = drvdata->retention_ctrl->priv; |
---|
369 | 369 | dev_info(drvdata->dev, |
---|
370 | 370 | "Setting external wakeup interrupt mask: 0x%x\n", |
---|
371 | | - irq_chip->eint_wake_mask_value); |
---|
| 371 | + *irq_chip->eint_wake_mask_value); |
---|
372 | 372 | |
---|
373 | 373 | regmap_write(pmu_regs, irq_chip->eint_wake_mask_reg, |
---|
374 | | - irq_chip->eint_wake_mask_value); |
---|
| 374 | + *irq_chip->eint_wake_mask_value); |
---|
375 | 375 | } |
---|
376 | 376 | |
---|
377 | 377 | static void |
---|
.. | .. |
---|
390 | 390 | |
---|
391 | 391 | clk_base = (void __iomem *) drvdata->retention_ctrl->priv; |
---|
392 | 392 | |
---|
393 | | - __raw_writel(irq_chip->eint_wake_mask_value, |
---|
| 393 | + __raw_writel(*irq_chip->eint_wake_mask_value, |
---|
394 | 394 | clk_base + irq_chip->eint_wake_mask_reg); |
---|
395 | 395 | } |
---|
396 | 396 | |
---|
| 397 | +static u32 eint_wake_mask_value = EXYNOS_EINT_WAKEUP_MASK_DISABLED; |
---|
397 | 398 | /* |
---|
398 | 399 | * irq_chip for wakeup interrupts |
---|
399 | 400 | */ |
---|
.. | .. |
---|
411 | 412 | .eint_con = EXYNOS_WKUP_ECON_OFFSET, |
---|
412 | 413 | .eint_mask = EXYNOS_WKUP_EMASK_OFFSET, |
---|
413 | 414 | .eint_pend = EXYNOS_WKUP_EPEND_OFFSET, |
---|
414 | | - .eint_wake_mask_value = EXYNOS_EINT_WAKEUP_MASK_DISABLED, |
---|
| 415 | + .eint_wake_mask_value = &eint_wake_mask_value, |
---|
415 | 416 | /* Only differences with exynos4210_wkup_irq_chip: */ |
---|
416 | 417 | .eint_wake_mask_reg = S5PV210_EINT_WAKEUP_MASK, |
---|
417 | 418 | .set_eint_wakeup_mask = s5pv210_pinctrl_set_eint_wakeup_mask, |
---|
.. | .. |
---|
431 | 432 | .eint_con = EXYNOS_WKUP_ECON_OFFSET, |
---|
432 | 433 | .eint_mask = EXYNOS_WKUP_EMASK_OFFSET, |
---|
433 | 434 | .eint_pend = EXYNOS_WKUP_EPEND_OFFSET, |
---|
434 | | - .eint_wake_mask_value = EXYNOS_EINT_WAKEUP_MASK_DISABLED, |
---|
| 435 | + .eint_wake_mask_value = &eint_wake_mask_value, |
---|
435 | 436 | .eint_wake_mask_reg = EXYNOS_EINT_WAKEUP_MASK, |
---|
436 | 437 | .set_eint_wakeup_mask = exynos_pinctrl_set_eint_wakeup_mask, |
---|
437 | 438 | }; |
---|
.. | .. |
---|
450 | 451 | .eint_con = EXYNOS7_WKUP_ECON_OFFSET, |
---|
451 | 452 | .eint_mask = EXYNOS7_WKUP_EMASK_OFFSET, |
---|
452 | 453 | .eint_pend = EXYNOS7_WKUP_EPEND_OFFSET, |
---|
453 | | - .eint_wake_mask_value = EXYNOS_EINT_WAKEUP_MASK_DISABLED, |
---|
| 454 | + .eint_wake_mask_value = &eint_wake_mask_value, |
---|
454 | 455 | .eint_wake_mask_reg = EXYNOS5433_EINT_WAKEUP_MASK, |
---|
455 | 456 | .set_eint_wakeup_mask = exynos_pinctrl_set_eint_wakeup_mask, |
---|
456 | 457 | }; |
---|
.. | .. |
---|
521 | 522 | * exynos_eint_wkup_init() - setup handling of external wakeup interrupts. |
---|
522 | 523 | * @d: driver data of samsung pinctrl driver. |
---|
523 | 524 | */ |
---|
524 | | -int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d) |
---|
| 525 | +__init int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d) |
---|
525 | 526 | { |
---|
526 | 527 | struct device *dev = d->dev; |
---|
527 | 528 | struct device_node *wkup_np = NULL; |
---|
.. | .. |
---|
529 | 530 | struct samsung_pin_bank *bank; |
---|
530 | 531 | struct exynos_weint_data *weint_data; |
---|
531 | 532 | struct exynos_muxed_weint_data *muxed_data; |
---|
532 | | - struct exynos_irq_chip *irq_chip; |
---|
| 533 | + const struct exynos_irq_chip *irq_chip; |
---|
533 | 534 | unsigned int muxed_banks = 0; |
---|
534 | 535 | unsigned int i; |
---|
535 | 536 | int idx, irq; |
---|
.. | .. |
---|
539 | 540 | |
---|
540 | 541 | match = of_match_node(exynos_wkup_irq_ids, np); |
---|
541 | 542 | if (match) { |
---|
542 | | - irq_chip = kmemdup(match->data, |
---|
543 | | - sizeof(*irq_chip), GFP_KERNEL); |
---|
544 | | - if (!irq_chip) { |
---|
545 | | - of_node_put(np); |
---|
546 | | - return -ENOMEM; |
---|
547 | | - } |
---|
| 543 | + irq_chip = match->data; |
---|
548 | 544 | wkup_np = np; |
---|
549 | 545 | break; |
---|
550 | 546 | } |
---|
.. | .. |
---|
557 | 553 | if (bank->eint_type != EINT_TYPE_WKUP) |
---|
558 | 554 | continue; |
---|
559 | 555 | |
---|
| 556 | + bank->irq_chip = devm_kmemdup(dev, irq_chip, sizeof(*irq_chip), |
---|
| 557 | + GFP_KERNEL); |
---|
| 558 | + if (!bank->irq_chip) { |
---|
| 559 | + of_node_put(wkup_np); |
---|
| 560 | + return -ENOMEM; |
---|
| 561 | + } |
---|
| 562 | + bank->irq_chip->chip.name = bank->name; |
---|
| 563 | + |
---|
560 | 564 | bank->irq_domain = irq_domain_add_linear(bank->of_node, |
---|
561 | 565 | bank->nr_pins, &exynos_eint_irqd_ops, bank); |
---|
562 | 566 | if (!bank->irq_domain) { |
---|
.. | .. |
---|
564 | 568 | of_node_put(wkup_np); |
---|
565 | 569 | return -ENXIO; |
---|
566 | 570 | } |
---|
567 | | - |
---|
568 | | - bank->irq_chip = irq_chip; |
---|
569 | 571 | |
---|
570 | 572 | if (!of_find_property(bank->of_node, "interrupts", NULL)) { |
---|
571 | 573 | bank->eint_type = EINT_TYPE_WKUP_MUX; |
---|
.. | .. |
---|
665 | 667 | irq_chip = bank->irq_chip; |
---|
666 | 668 | irq_chip->set_eint_wakeup_mask(drvdata, |
---|
667 | 669 | irq_chip); |
---|
668 | | - } else if (bank->irq_chip != irq_chip) { |
---|
669 | | - dev_warn(drvdata->dev, |
---|
670 | | - "More than one external wakeup interrupt chip configured (bank: %s). This is not supported by hardware nor by driver.\n", |
---|
671 | | - bank->name); |
---|
672 | 670 | } |
---|
673 | 671 | } |
---|
674 | 672 | } |
---|