diff options
| -rw-r--r-- | drivers/pinctrl/intel/pinctrl-baytrail.c | 35 |
1 files changed, 22 insertions, 13 deletions
diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c index 5afe03e28b91..e44f2fd6753f 100644 --- a/drivers/pinctrl/intel/pinctrl-baytrail.c +++ b/drivers/pinctrl/intel/pinctrl-baytrail.c | |||
| @@ -158,40 +158,49 @@ static void __iomem *byt_gpio_reg(struct gpio_chip *chip, unsigned offset, | |||
| 158 | return vg->reg_base + reg_offset + reg; | 158 | return vg->reg_base + reg_offset + reg; |
| 159 | } | 159 | } |
| 160 | 160 | ||
| 161 | static bool is_special_pin(struct byt_gpio *vg, unsigned offset) | 161 | static u32 byt_get_gpio_mux(struct byt_gpio *vg, unsigned offset) |
| 162 | { | 162 | { |
| 163 | /* SCORE pin 92-93 */ | 163 | /* SCORE pin 92-93 */ |
| 164 | if (!strcmp(vg->range->name, BYT_SCORE_ACPI_UID) && | 164 | if (!strcmp(vg->range->name, BYT_SCORE_ACPI_UID) && |
| 165 | offset >= 92 && offset <= 93) | 165 | offset >= 92 && offset <= 93) |
| 166 | return true; | 166 | return 1; |
| 167 | 167 | ||
| 168 | /* SUS pin 11-21 */ | 168 | /* SUS pin 11-21 */ |
| 169 | if (!strcmp(vg->range->name, BYT_SUS_ACPI_UID) && | 169 | if (!strcmp(vg->range->name, BYT_SUS_ACPI_UID) && |
| 170 | offset >= 11 && offset <= 21) | 170 | offset >= 11 && offset <= 21) |
| 171 | return true; | 171 | return 1; |
| 172 | 172 | ||
| 173 | return false; | 173 | return 0; |
| 174 | } | 174 | } |
| 175 | 175 | ||
| 176 | static int byt_gpio_request(struct gpio_chip *chip, unsigned offset) | 176 | static int byt_gpio_request(struct gpio_chip *chip, unsigned offset) |
| 177 | { | 177 | { |
| 178 | struct byt_gpio *vg = to_byt_gpio(chip); | 178 | struct byt_gpio *vg = to_byt_gpio(chip); |
| 179 | void __iomem *reg = byt_gpio_reg(chip, offset, BYT_CONF0_REG); | 179 | void __iomem *reg = byt_gpio_reg(chip, offset, BYT_CONF0_REG); |
| 180 | u32 value; | 180 | u32 value, gpio_mux; |
| 181 | bool special; | ||
| 182 | 181 | ||
| 183 | /* | 182 | /* |
| 184 | * In most cases, func pin mux 000 means GPIO function. | 183 | * In most cases, func pin mux 000 means GPIO function. |
| 185 | * But, some pins may have func pin mux 001 represents | 184 | * But, some pins may have func pin mux 001 represents |
| 186 | * GPIO function. Only allow user to export pin with | 185 | * GPIO function. |
| 187 | * func pin mux preset as GPIO function by BIOS/FW. | 186 | * |
| 187 | * Because there are devices out there where some pins were not | ||
| 188 | * configured correctly we allow changing the mux value from | ||
| 189 | * request (but print out warning about that). | ||
| 188 | */ | 190 | */ |
| 189 | value = readl(reg) & BYT_PIN_MUX; | 191 | value = readl(reg) & BYT_PIN_MUX; |
| 190 | special = is_special_pin(vg, offset); | 192 | gpio_mux = byt_get_gpio_mux(vg, offset); |
| 191 | if ((special && value != 1) || (!special && value)) { | 193 | if (WARN_ON(gpio_mux != value)) { |
| 192 | dev_err(&vg->pdev->dev, | 194 | unsigned long flags; |
| 193 | "pin %u cannot be used as GPIO.\n", offset); | 195 | |
| 194 | return -EINVAL; | 196 | spin_lock_irqsave(&vg->lock, flags); |
| 197 | value = readl(reg) & ~BYT_PIN_MUX; | ||
| 198 | value |= gpio_mux; | ||
| 199 | writel(value, reg); | ||
| 200 | spin_unlock_irqrestore(&vg->lock, flags); | ||
| 201 | |||
| 202 | dev_warn(&vg->pdev->dev, | ||
| 203 | "pin %u forcibly re-configured as GPIO\n", offset); | ||
| 195 | } | 204 | } |
| 196 | 205 | ||
| 197 | pm_runtime_get(&vg->pdev->dev); | 206 | pm_runtime_get(&vg->pdev->dev); |
