aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/pinctrl-sunxi.c
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2013-08-29 03:46:30 -0400
committerLinus Walleij <linus.walleij@linaro.org>2013-08-29 03:46:30 -0400
commit6ad30ce046aefbdc3848232c665a728860d7bb68 (patch)
tree34af8fc78b28281fcfe531a26401b440c078038e /drivers/pinctrl/pinctrl-sunxi.c
parent0351c287952483dafa904f84496631198465fbf4 (diff)
parentd8dfad3876e4386666b759da3c833d62fb8b2267 (diff)
Merge tag 'v3.11-rc7' into devel
Merged in this to avoid conflicts with the big locking fixes from upstream. Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Conflicts: drivers/pinctrl/pinctrl-sunxi.c
Diffstat (limited to 'drivers/pinctrl/pinctrl-sunxi.c')
-rw-r--r--drivers/pinctrl/pinctrl-sunxi.c58
1 files changed, 53 insertions, 5 deletions
diff --git a/drivers/pinctrl/pinctrl-sunxi.c b/drivers/pinctrl/pinctrl-sunxi.c
index 8dbd465b01d3..532202bbfc33 100644
--- a/drivers/pinctrl/pinctrl-sunxi.c
+++ b/drivers/pinctrl/pinctrl-sunxi.c
@@ -279,11 +279,14 @@ static int sunxi_pconf_group_set(struct pinctrl_dev *pctldev,
279{ 279{
280 struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); 280 struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
281 struct sunxi_pinctrl_group *g = &pctl->groups[group]; 281 struct sunxi_pinctrl_group *g = &pctl->groups[group];
282 unsigned long flags;
282 u32 val, mask; 283 u32 val, mask;
283 u16 strength; 284 u16 strength;
284 u8 dlevel; 285 u8 dlevel;
285 int i; 286 int i;
286 287
288 spin_lock_irqsave(&pctl->lock, flags);
289
287 for (i = 0; i < num_configs; i++) { 290 for (i = 0; i < num_configs; i++) {
288 switch (pinconf_to_config_param(configs[i])) { 291 switch (pinconf_to_config_param(configs[i])) {
289 case PIN_CONFIG_DRIVE_STRENGTH: 292 case PIN_CONFIG_DRIVE_STRENGTH:
@@ -319,11 +322,12 @@ static int sunxi_pconf_group_set(struct pinctrl_dev *pctldev,
319 default: 322 default:
320 break; 323 break;
321 } 324 }
322
323 /* cache the config value */ 325 /* cache the config value */
324 g->config = configs[i]; 326 g->config = configs[i];
325 } /* for each config */ 327 } /* for each config */
326 328
329 spin_unlock_irqrestore(&pctl->lock, flags);
330
327 return 0; 331 return 0;
328} 332}
329 333
@@ -365,11 +369,17 @@ static void sunxi_pmx_set(struct pinctrl_dev *pctldev,
365 u8 config) 369 u8 config)
366{ 370{
367 struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); 371 struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
372 unsigned long flags;
373 u32 val, mask;
374
375 spin_lock_irqsave(&pctl->lock, flags);
368 376
369 u32 val = readl(pctl->membase + sunxi_mux_reg(pin)); 377 val = readl(pctl->membase + sunxi_mux_reg(pin));
370 u32 mask = MUX_PINS_MASK << sunxi_mux_offset(pin); 378 mask = MUX_PINS_MASK << sunxi_mux_offset(pin);
371 writel((val & ~mask) | config << sunxi_mux_offset(pin), 379 writel((val & ~mask) | config << sunxi_mux_offset(pin),
372 pctl->membase + sunxi_mux_reg(pin)); 380 pctl->membase + sunxi_mux_reg(pin));
381
382 spin_unlock_irqrestore(&pctl->lock, flags);
373} 383}
374 384
375static int sunxi_pmx_enable(struct pinctrl_dev *pctldev, 385static int sunxi_pmx_enable(struct pinctrl_dev *pctldev,
@@ -469,8 +479,21 @@ static void sunxi_pinctrl_gpio_set(struct gpio_chip *chip,
469 struct sunxi_pinctrl *pctl = dev_get_drvdata(chip->dev); 479 struct sunxi_pinctrl *pctl = dev_get_drvdata(chip->dev);
470 u32 reg = sunxi_data_reg(offset); 480 u32 reg = sunxi_data_reg(offset);
471 u8 index = sunxi_data_offset(offset); 481 u8 index = sunxi_data_offset(offset);
482 unsigned long flags;
483 u32 regval;
484
485 spin_lock_irqsave(&pctl->lock, flags);
486
487 regval = readl(pctl->membase + reg);
488
489 if (value)
490 regval |= BIT(index);
491 else
492 regval &= ~(BIT(index));
472 493
473 writel((value & DATA_PINS_MASK) << index, pctl->membase + reg); 494 writel(regval, pctl->membase + reg);
495
496 spin_unlock_irqrestore(&pctl->lock, flags);
474} 497}
475 498
476static int sunxi_pinctrl_gpio_of_xlate(struct gpio_chip *gc, 499static int sunxi_pinctrl_gpio_of_xlate(struct gpio_chip *gc,
@@ -531,6 +554,8 @@ static int sunxi_pinctrl_irq_set_type(struct irq_data *d,
531 struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d); 554 struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
532 u32 reg = sunxi_irq_cfg_reg(d->hwirq); 555 u32 reg = sunxi_irq_cfg_reg(d->hwirq);
533 u8 index = sunxi_irq_cfg_offset(d->hwirq); 556 u8 index = sunxi_irq_cfg_offset(d->hwirq);
557 unsigned long flags;
558 u32 regval;
534 u8 mode; 559 u8 mode;
535 560
536 switch (type) { 561 switch (type) {
@@ -553,7 +578,13 @@ static int sunxi_pinctrl_irq_set_type(struct irq_data *d,
553 return -EINVAL; 578 return -EINVAL;
554 } 579 }
555 580
556 writel((mode & IRQ_CFG_IRQ_MASK) << index, pctl->membase + reg); 581 spin_lock_irqsave(&pctl->lock, flags);
582
583 regval = readl(pctl->membase + reg);
584 regval &= ~IRQ_CFG_IRQ_MASK;
585 writel(regval | (mode << index), pctl->membase + reg);
586
587 spin_unlock_irqrestore(&pctl->lock, flags);
557 588
558 return 0; 589 return 0;
559} 590}
@@ -565,14 +596,19 @@ static void sunxi_pinctrl_irq_mask_ack(struct irq_data *d)
565 u8 ctrl_idx = sunxi_irq_ctrl_offset(d->hwirq); 596 u8 ctrl_idx = sunxi_irq_ctrl_offset(d->hwirq);
566 u32 status_reg = sunxi_irq_status_reg(d->hwirq); 597 u32 status_reg = sunxi_irq_status_reg(d->hwirq);
567 u8 status_idx = sunxi_irq_status_offset(d->hwirq); 598 u8 status_idx = sunxi_irq_status_offset(d->hwirq);
599 unsigned long flags;
568 u32 val; 600 u32 val;
569 601
602 spin_lock_irqsave(&pctl->lock, flags);
603
570 /* Mask the IRQ */ 604 /* Mask the IRQ */
571 val = readl(pctl->membase + ctrl_reg); 605 val = readl(pctl->membase + ctrl_reg);
572 writel(val & ~(1 << ctrl_idx), pctl->membase + ctrl_reg); 606 writel(val & ~(1 << ctrl_idx), pctl->membase + ctrl_reg);
573 607
574 /* Clear the IRQ */ 608 /* Clear the IRQ */
575 writel(1 << status_idx, pctl->membase + status_reg); 609 writel(1 << status_idx, pctl->membase + status_reg);
610
611 spin_unlock_irqrestore(&pctl->lock, flags);
576} 612}
577 613
578static void sunxi_pinctrl_irq_mask(struct irq_data *d) 614static void sunxi_pinctrl_irq_mask(struct irq_data *d)
@@ -580,11 +616,16 @@ static void sunxi_pinctrl_irq_mask(struct irq_data *d)
580 struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d); 616 struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
581 u32 reg = sunxi_irq_ctrl_reg(d->hwirq); 617 u32 reg = sunxi_irq_ctrl_reg(d->hwirq);
582 u8 idx = sunxi_irq_ctrl_offset(d->hwirq); 618 u8 idx = sunxi_irq_ctrl_offset(d->hwirq);
619 unsigned long flags;
583 u32 val; 620 u32 val;
584 621
622 spin_lock_irqsave(&pctl->lock, flags);
623
585 /* Mask the IRQ */ 624 /* Mask the IRQ */
586 val = readl(pctl->membase + reg); 625 val = readl(pctl->membase + reg);
587 writel(val & ~(1 << idx), pctl->membase + reg); 626 writel(val & ~(1 << idx), pctl->membase + reg);
627
628 spin_unlock_irqrestore(&pctl->lock, flags);
588} 629}
589 630
590static void sunxi_pinctrl_irq_unmask(struct irq_data *d) 631static void sunxi_pinctrl_irq_unmask(struct irq_data *d)
@@ -593,6 +634,7 @@ static void sunxi_pinctrl_irq_unmask(struct irq_data *d)
593 struct sunxi_desc_function *func; 634 struct sunxi_desc_function *func;
594 u32 reg = sunxi_irq_ctrl_reg(d->hwirq); 635 u32 reg = sunxi_irq_ctrl_reg(d->hwirq);
595 u8 idx = sunxi_irq_ctrl_offset(d->hwirq); 636 u8 idx = sunxi_irq_ctrl_offset(d->hwirq);
637 unsigned long flags;
596 u32 val; 638 u32 val;
597 639
598 func = sunxi_pinctrl_desc_find_function_by_pin(pctl, 640 func = sunxi_pinctrl_desc_find_function_by_pin(pctl,
@@ -602,9 +644,13 @@ static void sunxi_pinctrl_irq_unmask(struct irq_data *d)
602 /* Change muxing to INT mode */ 644 /* Change muxing to INT mode */
603 sunxi_pmx_set(pctl->pctl_dev, pctl->irq_array[d->hwirq], func->muxval); 645 sunxi_pmx_set(pctl->pctl_dev, pctl->irq_array[d->hwirq], func->muxval);
604 646
647 spin_lock_irqsave(&pctl->lock, flags);
648
605 /* Unmask the IRQ */ 649 /* Unmask the IRQ */
606 val = readl(pctl->membase + reg); 650 val = readl(pctl->membase + reg);
607 writel(val | (1 << idx), pctl->membase + reg); 651 writel(val | (1 << idx), pctl->membase + reg);
652
653 spin_unlock_irqrestore(&pctl->lock, flags);
608} 654}
609 655
610static struct irq_chip sunxi_pinctrl_irq_chip = { 656static struct irq_chip sunxi_pinctrl_irq_chip = {
@@ -759,6 +805,8 @@ static int sunxi_pinctrl_probe(struct platform_device *pdev)
759 return -ENOMEM; 805 return -ENOMEM;
760 platform_set_drvdata(pdev, pctl); 806 platform_set_drvdata(pdev, pctl);
761 807
808 spin_lock_init(&pctl->lock);
809
762 pctl->membase = of_iomap(node, 0); 810 pctl->membase = of_iomap(node, 0);
763 if (!pctl->membase) 811 if (!pctl->membase)
764 return -ENOMEM; 812 return -ENOMEM;