@@ -574,10 +574,10 @@ static int cv1800_pinconf_compute_config(struct cv1800_pinctrl *pctrl,
574574 struct cv1800_pin * pin ,
575575 unsigned long * configs ,
576576 unsigned int num_configs ,
577- u32 * value )
577+ u32 * value , u32 * mask )
578578{
579579 int i ;
580- u32 v = 0 ;
580+ u32 v = 0 , m = 0 ;
581581 enum cv1800_pin_io_type type ;
582582 int ret ;
583583
@@ -596,61 +596,72 @@ static int cv1800_pinconf_compute_config(struct cv1800_pinctrl *pctrl,
596596 case PIN_CONFIG_BIAS_PULL_DOWN :
597597 v &= ~PIN_IO_PULLDOWN ;
598598 v |= FIELD_PREP (PIN_IO_PULLDOWN , arg );
599+ m |= PIN_IO_PULLDOWN ;
599600 break ;
600601 case PIN_CONFIG_BIAS_PULL_UP :
601602 v &= ~PIN_IO_PULLUP ;
602603 v |= FIELD_PREP (PIN_IO_PULLUP , arg );
604+ m |= PIN_IO_PULLUP ;
603605 break ;
604606 case PIN_CONFIG_DRIVE_STRENGTH_UA :
605607 ret = cv1800_pinctrl_oc2reg (pctrl , pin , arg );
606608 if (ret < 0 )
607609 return ret ;
608610 v &= ~PIN_IO_DRIVE ;
609611 v |= FIELD_PREP (PIN_IO_DRIVE , ret );
612+ m |= PIN_IO_DRIVE ;
610613 break ;
611614 case PIN_CONFIG_INPUT_SCHMITT_UV :
612615 ret = cv1800_pinctrl_schmitt2reg (pctrl , pin , arg );
613616 if (ret < 0 )
614617 return ret ;
615618 v &= ~PIN_IO_SCHMITT ;
616619 v |= FIELD_PREP (PIN_IO_SCHMITT , ret );
620+ m |= PIN_IO_SCHMITT ;
617621 break ;
618622 case PIN_CONFIG_POWER_SOURCE :
619623 /* Ignore power source as it is always fixed */
620624 break ;
621625 case PIN_CONFIG_SLEW_RATE :
622626 v &= ~PIN_IO_OUT_FAST_SLEW ;
623627 v |= FIELD_PREP (PIN_IO_OUT_FAST_SLEW , arg );
628+ m |= PIN_IO_OUT_FAST_SLEW ;
624629 break ;
625630 case PIN_CONFIG_BIAS_BUS_HOLD :
626631 v &= ~PIN_IO_BUS_HOLD ;
627632 v |= FIELD_PREP (PIN_IO_BUS_HOLD , arg );
633+ m |= PIN_IO_BUS_HOLD ;
628634 break ;
629635 default :
630636 return - ENOTSUPP ;
631637 }
632638 }
633639
634640 * value = v ;
641+ * mask = m ;
635642
636643 return 0 ;
637644}
638645
639646static int cv1800_pin_set_config (struct cv1800_pinctrl * pctrl ,
640647 unsigned int pin_id ,
641- u32 value )
648+ u32 value , u32 mask )
642649{
643650 struct cv1800_pin * pin = cv1800_get_pin (pctrl , pin_id );
644651 unsigned long flags ;
645652 void __iomem * addr ;
653+ u32 reg ;
646654
647655 if (!pin )
648656 return - EINVAL ;
649657
650658 addr = cv1800_pinctrl_get_component_addr (pctrl , & pin -> conf );
651659
652660 raw_spin_lock_irqsave (& pctrl -> lock , flags );
653- writel (value , addr );
661+ reg = readl (addr );
662+ reg &= ~mask ;
663+ reg |= value ;
664+ writel (reg , addr );
654665 raw_spin_unlock_irqrestore (& pctrl -> lock , flags );
655666
656667 return 0 ;
@@ -662,16 +673,17 @@ static int cv1800_pconf_set(struct pinctrl_dev *pctldev,
662673{
663674 struct cv1800_pinctrl * pctrl = pinctrl_dev_get_drvdata (pctldev );
664675 struct cv1800_pin * pin = cv1800_get_pin (pctrl , pin_id );
665- u32 value ;
676+ u32 value , mask ;
666677
667678 if (!pin )
668679 return - ENODEV ;
669680
670681 if (cv1800_pinconf_compute_config (pctrl , pin ,
671- configs , num_configs , & value ))
682+ configs , num_configs ,
683+ & value , & mask ))
672684 return - ENOTSUPP ;
673685
674- return cv1800_pin_set_config (pctrl , pin_id , value );
686+ return cv1800_pin_set_config (pctrl , pin_id , value , mask );
675687}
676688
677689static int cv1800_pconf_group_set (struct pinctrl_dev * pctldev ,
@@ -682,7 +694,7 @@ static int cv1800_pconf_group_set(struct pinctrl_dev *pctldev,
682694 struct cv1800_pinctrl * pctrl = pinctrl_dev_get_drvdata (pctldev );
683695 const struct group_desc * group ;
684696 const struct cv1800_pin_mux_config * pinmuxs ;
685- u32 value ;
697+ u32 value , mask ;
686698 int i ;
687699
688700 group = pinctrl_generic_get_group (pctldev , gsel );
@@ -692,11 +704,12 @@ static int cv1800_pconf_group_set(struct pinctrl_dev *pctldev,
692704 pinmuxs = group -> data ;
693705
694706 if (cv1800_pinconf_compute_config (pctrl , pinmuxs [0 ].pin ,
695- configs , num_configs , & value ))
707+ configs , num_configs ,
708+ & value , & mask ))
696709 return - ENOTSUPP ;
697710
698711 for (i = 0 ; i < group -> grp .npins ; i ++ )
699- cv1800_pin_set_config (pctrl , group -> grp .pins [i ], value );
712+ cv1800_pin_set_config (pctrl , group -> grp .pins [i ], value , mask );
700713
701714 return 0 ;
702715}
0 commit comments