| .. | .. |
|---|
| 8 | 8 | |
|---|
| 9 | 9 | #include <linux/clk.h> |
|---|
| 10 | 10 | #include <linux/delay.h> |
|---|
| 11 | | -#include <linux/gpio.h> |
|---|
| 11 | +#include <linux/gpio/consumer.h> |
|---|
| 12 | 12 | #include <linux/interrupt.h> |
|---|
| 13 | | -#include <linux/of_gpio.h> |
|---|
| 14 | 13 | #include <linux/of_irq.h> |
|---|
| 15 | 14 | #include <linux/module.h> |
|---|
| 16 | 15 | #include <linux/pinctrl/consumer.h> |
|---|
| .. | .. |
|---|
| 20 | 19 | #include <linux/spinlock.h> |
|---|
| 21 | 20 | #include "arche_platform.h" |
|---|
| 22 | 21 | |
|---|
| 23 | | - |
|---|
| 24 | 22 | static void apb_bootret_deassert(struct device *dev); |
|---|
| 25 | 23 | |
|---|
| 26 | 24 | struct arche_apb_ctrl_drvdata { |
|---|
| 27 | 25 | /* Control GPIO signals to and from AP <=> AP Bridges */ |
|---|
| 28 | | - int resetn_gpio; |
|---|
| 29 | | - int boot_ret_gpio; |
|---|
| 30 | | - int pwroff_gpio; |
|---|
| 31 | | - int wake_in_gpio; |
|---|
| 32 | | - int wake_out_gpio; |
|---|
| 33 | | - int pwrdn_gpio; |
|---|
| 26 | + struct gpio_desc *resetn; |
|---|
| 27 | + struct gpio_desc *boot_ret; |
|---|
| 28 | + struct gpio_desc *pwroff; |
|---|
| 29 | + struct gpio_desc *wake_in; |
|---|
| 30 | + struct gpio_desc *wake_out; |
|---|
| 31 | + struct gpio_desc *pwrdn; |
|---|
| 34 | 32 | |
|---|
| 35 | 33 | enum arche_platform_state state; |
|---|
| 36 | 34 | bool init_disabled; |
|---|
| .. | .. |
|---|
| 38 | 36 | struct regulator *vcore; |
|---|
| 39 | 37 | struct regulator *vio; |
|---|
| 40 | 38 | |
|---|
| 41 | | - int clk_en_gpio; |
|---|
| 39 | + struct gpio_desc *clk_en; |
|---|
| 42 | 40 | struct clk *clk; |
|---|
| 43 | 41 | |
|---|
| 44 | 42 | struct pinctrl *pinctrl; |
|---|
| 45 | 43 | struct pinctrl_state *pin_default; |
|---|
| 46 | 44 | |
|---|
| 47 | 45 | /* V2: SPI Bus control */ |
|---|
| 48 | | - int spi_en_gpio; |
|---|
| 46 | + struct gpio_desc *spi_en; |
|---|
| 49 | 47 | bool spi_en_polarity_high; |
|---|
| 50 | 48 | }; |
|---|
| 51 | 49 | |
|---|
| 52 | 50 | /* |
|---|
| 53 | 51 | * Note that these low level api's are active high |
|---|
| 54 | 52 | */ |
|---|
| 55 | | -static inline void deassert_reset(unsigned int gpio) |
|---|
| 53 | +static inline void deassert_reset(struct gpio_desc *gpio) |
|---|
| 56 | 54 | { |
|---|
| 57 | | - gpio_set_value(gpio, 1); |
|---|
| 55 | + gpiod_set_raw_value(gpio, 1); |
|---|
| 58 | 56 | } |
|---|
| 59 | 57 | |
|---|
| 60 | | -static inline void assert_reset(unsigned int gpio) |
|---|
| 58 | +static inline void assert_reset(struct gpio_desc *gpio) |
|---|
| 61 | 59 | { |
|---|
| 62 | | - gpio_set_value(gpio, 0); |
|---|
| 60 | + gpiod_set_raw_value(gpio, 0); |
|---|
| 63 | 61 | } |
|---|
| 64 | 62 | |
|---|
| 65 | 63 | /* |
|---|
| .. | .. |
|---|
| 76 | 74 | return 0; |
|---|
| 77 | 75 | |
|---|
| 78 | 76 | /* Hold APB in reset state */ |
|---|
| 79 | | - assert_reset(apb->resetn_gpio); |
|---|
| 77 | + assert_reset(apb->resetn); |
|---|
| 80 | 78 | |
|---|
| 81 | | - if (apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING && |
|---|
| 82 | | - gpio_is_valid(apb->spi_en_gpio)) |
|---|
| 83 | | - devm_gpio_free(dev, apb->spi_en_gpio); |
|---|
| 79 | + if (apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING && apb->spi_en) |
|---|
| 80 | + devm_gpiod_put(dev, apb->spi_en); |
|---|
| 84 | 81 | |
|---|
| 85 | 82 | /* Enable power to APB */ |
|---|
| 86 | 83 | if (!IS_ERR(apb->vcore)) { |
|---|
| .. | .. |
|---|
| 102 | 99 | apb_bootret_deassert(dev); |
|---|
| 103 | 100 | |
|---|
| 104 | 101 | /* On DB3 clock was not mandatory */ |
|---|
| 105 | | - if (gpio_is_valid(apb->clk_en_gpio)) |
|---|
| 106 | | - gpio_set_value(apb->clk_en_gpio, 1); |
|---|
| 102 | + if (apb->clk_en) |
|---|
| 103 | + gpiod_set_value(apb->clk_en, 1); |
|---|
| 107 | 104 | |
|---|
| 108 | 105 | usleep_range(100, 200); |
|---|
| 109 | 106 | |
|---|
| 110 | 107 | /* deassert reset to APB : Active-low signal */ |
|---|
| 111 | | - deassert_reset(apb->resetn_gpio); |
|---|
| 108 | + deassert_reset(apb->resetn); |
|---|
| 112 | 109 | |
|---|
| 113 | 110 | apb->state = ARCHE_PLATFORM_STATE_ACTIVE; |
|---|
| 114 | 111 | |
|---|
| .. | .. |
|---|
| 137 | 134 | return ret; |
|---|
| 138 | 135 | } |
|---|
| 139 | 136 | |
|---|
| 140 | | - if (gpio_is_valid(apb->spi_en_gpio)) { |
|---|
| 137 | + if (apb->spi_en) { |
|---|
| 141 | 138 | unsigned long flags; |
|---|
| 142 | 139 | |
|---|
| 143 | 140 | if (apb->spi_en_polarity_high) |
|---|
| 144 | | - flags = GPIOF_OUT_INIT_HIGH; |
|---|
| 141 | + flags = GPIOD_OUT_HIGH; |
|---|
| 145 | 142 | else |
|---|
| 146 | | - flags = GPIOF_OUT_INIT_LOW; |
|---|
| 143 | + flags = GPIOD_OUT_LOW; |
|---|
| 147 | 144 | |
|---|
| 148 | | - ret = devm_gpio_request_one(dev, apb->spi_en_gpio, |
|---|
| 149 | | - flags, "apb_spi_en"); |
|---|
| 150 | | - if (ret) { |
|---|
| 151 | | - dev_err(dev, "Failed requesting SPI bus en gpio %d\n", |
|---|
| 152 | | - apb->spi_en_gpio); |
|---|
| 145 | + apb->spi_en = devm_gpiod_get(dev, "spi-en", flags); |
|---|
| 146 | + if (IS_ERR(apb->spi_en)) { |
|---|
| 147 | + ret = PTR_ERR(apb->spi_en); |
|---|
| 148 | + dev_err(dev, "Failed requesting SPI bus en GPIO: %d\n", |
|---|
| 149 | + ret); |
|---|
| 153 | 150 | return ret; |
|---|
| 154 | 151 | } |
|---|
| 155 | 152 | } |
|---|
| 156 | 153 | |
|---|
| 157 | 154 | /* for flashing device should be in reset state */ |
|---|
| 158 | | - assert_reset(apb->resetn_gpio); |
|---|
| 155 | + assert_reset(apb->resetn); |
|---|
| 159 | 156 | apb->state = ARCHE_PLATFORM_STATE_FW_FLASHING; |
|---|
| 160 | 157 | |
|---|
| 161 | 158 | return 0; |
|---|
| .. | .. |
|---|
| 177 | 174 | apb->state == ARCHE_PLATFORM_STATE_OFF) |
|---|
| 178 | 175 | return 0; |
|---|
| 179 | 176 | |
|---|
| 180 | | - if (apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING && |
|---|
| 181 | | - gpio_is_valid(apb->spi_en_gpio)) |
|---|
| 182 | | - devm_gpio_free(dev, apb->spi_en_gpio); |
|---|
| 177 | + if (apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING && apb->spi_en) |
|---|
| 178 | + devm_gpiod_put(dev, apb->spi_en); |
|---|
| 183 | 179 | |
|---|
| 184 | 180 | /* |
|---|
| 185 | 181 | * As per WDM spec, do nothing |
|---|
| .. | .. |
|---|
| 202 | 198 | if (apb->init_disabled || apb->state == ARCHE_PLATFORM_STATE_OFF) |
|---|
| 203 | 199 | return; |
|---|
| 204 | 200 | |
|---|
| 205 | | - if (apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING && |
|---|
| 206 | | - gpio_is_valid(apb->spi_en_gpio)) |
|---|
| 207 | | - devm_gpio_free(dev, apb->spi_en_gpio); |
|---|
| 201 | + if (apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING && apb->spi_en) |
|---|
| 202 | + devm_gpiod_put(dev, apb->spi_en); |
|---|
| 208 | 203 | |
|---|
| 209 | 204 | /* disable the clock */ |
|---|
| 210 | | - if (gpio_is_valid(apb->clk_en_gpio)) |
|---|
| 211 | | - gpio_set_value(apb->clk_en_gpio, 0); |
|---|
| 205 | + if (apb->clk_en) |
|---|
| 206 | + gpiod_set_value(apb->clk_en, 0); |
|---|
| 212 | 207 | |
|---|
| 213 | 208 | if (!IS_ERR(apb->vcore) && regulator_is_enabled(apb->vcore) > 0) |
|---|
| 214 | 209 | regulator_disable(apb->vcore); |
|---|
| .. | .. |
|---|
| 217 | 212 | regulator_disable(apb->vio); |
|---|
| 218 | 213 | |
|---|
| 219 | 214 | /* As part of exit, put APB back in reset state */ |
|---|
| 220 | | - assert_reset(apb->resetn_gpio); |
|---|
| 215 | + assert_reset(apb->resetn); |
|---|
| 221 | 216 | apb->state = ARCHE_PLATFORM_STATE_OFF; |
|---|
| 222 | 217 | |
|---|
| 223 | 218 | /* TODO: May have to send an event to SVC about this exit */ |
|---|
| .. | .. |
|---|
| 227 | 222 | { |
|---|
| 228 | 223 | struct arche_apb_ctrl_drvdata *apb = dev_get_drvdata(dev); |
|---|
| 229 | 224 | |
|---|
| 230 | | - gpio_set_value(apb->boot_ret_gpio, 0); |
|---|
| 225 | + gpiod_set_value(apb->boot_ret, 0); |
|---|
| 231 | 226 | } |
|---|
| 232 | 227 | |
|---|
| 233 | 228 | int apb_ctrl_coldboot(struct device *dev) |
|---|
| .. | .. |
|---|
| 323 | 318 | struct arche_apb_ctrl_drvdata *apb) |
|---|
| 324 | 319 | { |
|---|
| 325 | 320 | struct device *dev = &pdev->dev; |
|---|
| 326 | | - struct device_node *np = dev->of_node; |
|---|
| 327 | 321 | int ret; |
|---|
| 328 | 322 | |
|---|
| 329 | | - apb->resetn_gpio = of_get_named_gpio(np, "reset-gpios", 0); |
|---|
| 330 | | - if (apb->resetn_gpio < 0) { |
|---|
| 331 | | - dev_err(dev, "failed to get reset gpio\n"); |
|---|
| 332 | | - return apb->resetn_gpio; |
|---|
| 333 | | - } |
|---|
| 334 | | - ret = devm_gpio_request_one(dev, apb->resetn_gpio, |
|---|
| 335 | | - GPIOF_OUT_INIT_LOW, "apb-reset"); |
|---|
| 336 | | - if (ret) { |
|---|
| 337 | | - dev_err(dev, "Failed requesting reset gpio %d\n", |
|---|
| 338 | | - apb->resetn_gpio); |
|---|
| 323 | + apb->resetn = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); |
|---|
| 324 | + if (IS_ERR(apb->resetn)) { |
|---|
| 325 | + ret = PTR_ERR(apb->resetn); |
|---|
| 326 | + dev_err(dev, "Failed requesting reset GPIO: %d\n", ret); |
|---|
| 339 | 327 | return ret; |
|---|
| 340 | 328 | } |
|---|
| 341 | 329 | |
|---|
| 342 | | - apb->boot_ret_gpio = of_get_named_gpio(np, "boot-ret-gpios", 0); |
|---|
| 343 | | - if (apb->boot_ret_gpio < 0) { |
|---|
| 344 | | - dev_err(dev, "failed to get boot retention gpio\n"); |
|---|
| 345 | | - return apb->boot_ret_gpio; |
|---|
| 346 | | - } |
|---|
| 347 | | - ret = devm_gpio_request_one(dev, apb->boot_ret_gpio, |
|---|
| 348 | | - GPIOF_OUT_INIT_LOW, "boot retention"); |
|---|
| 349 | | - if (ret) { |
|---|
| 350 | | - dev_err(dev, "Failed requesting bootret gpio %d\n", |
|---|
| 351 | | - apb->boot_ret_gpio); |
|---|
| 330 | + apb->boot_ret = devm_gpiod_get(dev, "boot-ret", GPIOD_OUT_LOW); |
|---|
| 331 | + if (IS_ERR(apb->boot_ret)) { |
|---|
| 332 | + ret = PTR_ERR(apb->boot_ret); |
|---|
| 333 | + dev_err(dev, "Failed requesting bootret GPIO: %d\n", ret); |
|---|
| 352 | 334 | return ret; |
|---|
| 353 | 335 | } |
|---|
| 354 | 336 | |
|---|
| 355 | 337 | /* It's not mandatory to support power management interface */ |
|---|
| 356 | | - apb->pwroff_gpio = of_get_named_gpio(np, "pwr-off-gpios", 0); |
|---|
| 357 | | - if (apb->pwroff_gpio < 0) { |
|---|
| 358 | | - dev_err(dev, "failed to get power off gpio\n"); |
|---|
| 359 | | - return apb->pwroff_gpio; |
|---|
| 360 | | - } |
|---|
| 361 | | - ret = devm_gpio_request_one(dev, apb->pwroff_gpio, |
|---|
| 362 | | - GPIOF_IN, "pwroff_n"); |
|---|
| 363 | | - if (ret) { |
|---|
| 364 | | - dev_err(dev, "Failed requesting pwroff_n gpio %d\n", |
|---|
| 365 | | - apb->pwroff_gpio); |
|---|
| 338 | + apb->pwroff = devm_gpiod_get_optional(dev, "pwr-off", GPIOD_IN); |
|---|
| 339 | + if (IS_ERR(apb->pwroff)) { |
|---|
| 340 | + ret = PTR_ERR(apb->pwroff); |
|---|
| 341 | + dev_err(dev, "Failed requesting pwroff_n GPIO: %d\n", ret); |
|---|
| 366 | 342 | return ret; |
|---|
| 367 | 343 | } |
|---|
| 368 | 344 | |
|---|
| 369 | 345 | /* Do not make clock mandatory as of now (for DB3) */ |
|---|
| 370 | | - apb->clk_en_gpio = of_get_named_gpio(np, "clock-en-gpio", 0); |
|---|
| 371 | | - if (apb->clk_en_gpio < 0) { |
|---|
| 372 | | - dev_warn(dev, "failed to get clock en gpio\n"); |
|---|
| 373 | | - } else if (gpio_is_valid(apb->clk_en_gpio)) { |
|---|
| 374 | | - ret = devm_gpio_request_one(dev, apb->clk_en_gpio, |
|---|
| 375 | | - GPIOF_OUT_INIT_LOW, "apb_clk_en"); |
|---|
| 376 | | - if (ret) { |
|---|
| 377 | | - dev_warn(dev, "Failed requesting APB clock en gpio %d\n", |
|---|
| 378 | | - apb->clk_en_gpio); |
|---|
| 379 | | - return ret; |
|---|
| 380 | | - } |
|---|
| 346 | + apb->clk_en = devm_gpiod_get_optional(dev, "clock-en", GPIOD_OUT_LOW); |
|---|
| 347 | + if (IS_ERR(apb->clk_en)) { |
|---|
| 348 | + ret = PTR_ERR(apb->clk_en); |
|---|
| 349 | + dev_err(dev, "Failed requesting APB clock en GPIO: %d\n", ret); |
|---|
| 350 | + return ret; |
|---|
| 381 | 351 | } |
|---|
| 382 | 352 | |
|---|
| 383 | | - apb->pwrdn_gpio = of_get_named_gpio(np, "pwr-down-gpios", 0); |
|---|
| 384 | | - if (apb->pwrdn_gpio < 0) |
|---|
| 385 | | - dev_warn(dev, "failed to get power down gpio\n"); |
|---|
| 353 | + apb->pwrdn = devm_gpiod_get(dev, "pwr-down", GPIOD_OUT_LOW); |
|---|
| 354 | + if (IS_ERR(apb->pwrdn)) { |
|---|
| 355 | + ret = PTR_ERR(apb->pwrdn); |
|---|
| 356 | + dev_warn(dev, "Failed requesting power down GPIO: %d\n", ret); |
|---|
| 357 | + return ret; |
|---|
| 358 | + } |
|---|
| 386 | 359 | |
|---|
| 387 | 360 | /* Regulators are optional, as we may have fixed supply coming in */ |
|---|
| 388 | 361 | apb->vcore = devm_regulator_get(dev, "vcore"); |
|---|
| .. | .. |
|---|
| 405 | 378 | } |
|---|
| 406 | 379 | |
|---|
| 407 | 380 | /* Only applicable for platform >= V2 */ |
|---|
| 408 | | - apb->spi_en_gpio = of_get_named_gpio(np, "spi-en-gpio", 0); |
|---|
| 409 | | - if (apb->spi_en_gpio >= 0) { |
|---|
| 410 | | - if (of_property_read_bool(pdev->dev.of_node, |
|---|
| 411 | | - "spi-en-active-high")) |
|---|
| 412 | | - apb->spi_en_polarity_high = true; |
|---|
| 413 | | - } |
|---|
| 381 | + if (of_property_read_bool(pdev->dev.of_node, "gb,spi-en-active-high")) |
|---|
| 382 | + apb->spi_en_polarity_high = true; |
|---|
| 414 | 383 | |
|---|
| 415 | 384 | return 0; |
|---|
| 416 | 385 | } |
|---|