diff options
author | Chew, Kean Ho <kean.ho.chew@intel.com> | 2014-03-06 08:59:49 -0500 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2014-03-11 06:22:54 -0400 |
commit | 42bd00706ce95d74ad6ebcb8528ee1fbbb992f6a (patch) | |
tree | d125223cf06776ffe8650e33c4ca31564295070f /drivers/pinctrl/pinctrl-baytrail.c | |
parent | a76cbd7eba1fa4b623fa35e2cb0ef5de1c504e2f (diff) |
pinctrl-baytrail: add function mux checking in gpio pin request
The requested gpio pin must has the func_pin_mux field set
to GPIO function by BIOS/FW in advanced. Else, the gpio pin
request would fail. This is to ensure that we do not expose
any gpio pins which shall be used for alternate functions,
for eg: wakeup pin, I/O interfaces for LPSS, etc.
Signed-off-by: Chew, Kean Ho <kean.ho.chew@intel.com>
Signed-off-by: Chew, Chiau Ee <chiau.ee.chew@intel.com>
Reviewed-by: Darren Hart <dvhart@linux.intel.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl/pinctrl-baytrail.c')
-rw-r--r-- | drivers/pinctrl/pinctrl-baytrail.c | 42 |
1 files changed, 39 insertions, 3 deletions
diff --git a/drivers/pinctrl/pinctrl-baytrail.c b/drivers/pinctrl/pinctrl-baytrail.c index 665b96bc0c3a..bf2b3f655469 100644 --- a/drivers/pinctrl/pinctrl-baytrail.c +++ b/drivers/pinctrl/pinctrl-baytrail.c | |||
@@ -60,6 +60,10 @@ | |||
60 | #define BYT_NGPIO_NCORE 28 | 60 | #define BYT_NGPIO_NCORE 28 |
61 | #define BYT_NGPIO_SUS 44 | 61 | #define BYT_NGPIO_SUS 44 |
62 | 62 | ||
63 | #define BYT_SCORE_ACPI_UID "1" | ||
64 | #define BYT_NCORE_ACPI_UID "2" | ||
65 | #define BYT_SUS_ACPI_UID "3" | ||
66 | |||
63 | /* | 67 | /* |
64 | * Baytrail gpio controller consist of three separate sub-controllers called | 68 | * Baytrail gpio controller consist of three separate sub-controllers called |
65 | * SCORE, NCORE and SUS. The sub-controllers are identified by their acpi UID. | 69 | * SCORE, NCORE and SUS. The sub-controllers are identified by their acpi UID. |
@@ -102,17 +106,17 @@ static unsigned const sus_pins[BYT_NGPIO_SUS] = { | |||
102 | 106 | ||
103 | static struct pinctrl_gpio_range byt_ranges[] = { | 107 | static struct pinctrl_gpio_range byt_ranges[] = { |
104 | { | 108 | { |
105 | .name = "1", /* match with acpi _UID in probe */ | 109 | .name = BYT_SCORE_ACPI_UID, /* match with acpi _UID in probe */ |
106 | .npins = BYT_NGPIO_SCORE, | 110 | .npins = BYT_NGPIO_SCORE, |
107 | .pins = score_pins, | 111 | .pins = score_pins, |
108 | }, | 112 | }, |
109 | { | 113 | { |
110 | .name = "2", | 114 | .name = BYT_NCORE_ACPI_UID, |
111 | .npins = BYT_NGPIO_NCORE, | 115 | .npins = BYT_NGPIO_NCORE, |
112 | .pins = ncore_pins, | 116 | .pins = ncore_pins, |
113 | }, | 117 | }, |
114 | { | 118 | { |
115 | .name = "3", | 119 | .name = BYT_SUS_ACPI_UID, |
116 | .npins = BYT_NGPIO_SUS, | 120 | .npins = BYT_NGPIO_SUS, |
117 | .pins = sus_pins, | 121 | .pins = sus_pins, |
118 | }, | 122 | }, |
@@ -145,9 +149,41 @@ static void __iomem *byt_gpio_reg(struct gpio_chip *chip, unsigned offset, | |||
145 | return vg->reg_base + reg_offset + reg; | 149 | return vg->reg_base + reg_offset + reg; |
146 | } | 150 | } |
147 | 151 | ||
152 | static bool is_special_pin(struct byt_gpio *vg, unsigned offset) | ||
153 | { | ||
154 | /* SCORE pin 92-93 */ | ||
155 | if (!strcmp(vg->range->name, BYT_SCORE_ACPI_UID) && | ||
156 | offset >= 92 && offset <= 93) | ||
157 | return true; | ||
158 | |||
159 | /* SUS pin 11-21 */ | ||
160 | if (!strcmp(vg->range->name, BYT_SUS_ACPI_UID) && | ||
161 | offset >= 11 && offset <= 21) | ||
162 | return true; | ||
163 | |||
164 | return false; | ||
165 | } | ||
166 | |||
148 | static int byt_gpio_request(struct gpio_chip *chip, unsigned offset) | 167 | static int byt_gpio_request(struct gpio_chip *chip, unsigned offset) |
149 | { | 168 | { |
150 | struct byt_gpio *vg = to_byt_gpio(chip); | 169 | struct byt_gpio *vg = to_byt_gpio(chip); |
170 | void __iomem *reg = byt_gpio_reg(chip, offset, BYT_CONF0_REG); | ||
171 | u32 value; | ||
172 | bool special; | ||
173 | |||
174 | /* | ||
175 | * In most cases, func pin mux 000 means GPIO function. | ||
176 | * But, some pins may have func pin mux 001 represents | ||
177 | * GPIO function. Only allow user to export pin with | ||
178 | * func pin mux preset as GPIO function by BIOS/FW. | ||
179 | */ | ||
180 | value = readl(reg) & BYT_PIN_MUX; | ||
181 | special = is_special_pin(vg, offset); | ||
182 | if ((special && value != 1) || (!special && value)) { | ||
183 | dev_err(&vg->pdev->dev, | ||
184 | "pin %u cannot be used as GPIO.\n", offset); | ||
185 | return -EINVAL; | ||
186 | } | ||
151 | 187 | ||
152 | pm_runtime_get(&vg->pdev->dev); | 188 | pm_runtime_get(&vg->pdev->dev); |
153 | 189 | ||