From a3294658232852248461b79c8c0a532956974568 Mon Sep 17 00:00:00 2001 From: Lionel VITTE Date: Mon, 5 Oct 2020 13:19:51 +0200 Subject: [PATCH 17/22] ARM-stm32mp1-r2-rc8-PINCTRL-REGULATOR-SPI-PWM --- .../bindings/pinctrl/st,stm32-pinctrl.yaml | 8 + .../devicetree/bindings/pwm/pwm-stm32.txt | 8 +- drivers/pinctrl/pinctrl-stmfx.c | 36 +- drivers/pinctrl/stm32/pinctrl-stm32.c | 268 +++++++--- drivers/pinctrl/stm32/pinctrl-stm32.h | 17 +- drivers/pinctrl/stm32/pinctrl-stm32mp157.c | 1 + drivers/pwm/pwm-stm32.c | 116 ++-- drivers/regulator/stm32-pwr.c | 85 ++- drivers/regulator/stpmic1_regulator.c | 203 ++++++- drivers/spi/spi-stm32-qspi.c | 155 ++++-- drivers/spi/spi-stm32.c | 495 ++++++++++-------- include/dt-bindings/pinctrl/stm32-pinfunc.h | 1 + 12 files changed, 1019 insertions(+), 374 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml index 400df2da018a3..4e24a8e863475 100644 --- a/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml @@ -144,9 +144,13 @@ patternProperties: * ... * 16 : Alternate Function 15 * 17 : Analog + * 18 : Reserved To simplify the usage, macro is available to generate "pinmux" field. This macro is available here: - include/dt-bindings/pinctrl/stm32-pinfunc.h + Setting the pinmux's function to the Reserved (RSVD) value is used to inform + the driver that it shall not apply the mux setting. This can be used to + reserve some pins, for example to a co-processor not running Linux. Some examples of using macro: /* GPIO A9 set as alernate function 2 */ ... { @@ -160,6 +164,10 @@ patternProperties: ... { pinmux = ; }; + /* GPIO A9 reserved for co-processor */ + ... { + pinmux = ; + }; bias-disable: type: boolean diff --git a/Documentation/devicetree/bindings/pwm/pwm-stm32.txt b/Documentation/devicetree/bindings/pwm/pwm-stm32.txt index a8690bfa5e1fa..f1620c1feebfc 100644 --- a/Documentation/devicetree/bindings/pwm/pwm-stm32.txt +++ b/Documentation/devicetree/bindings/pwm/pwm-stm32.txt @@ -5,8 +5,9 @@ See ../mfd/stm32-timers.txt for details about the parent node. Required parameters: - compatible: Must be "st,stm32-pwm". -- pinctrl-names: Set to "default". -- pinctrl-0: List of phandles pointing to pin configuration nodes for PWM module. +- pinctrl-names: Set to "default". An additional "sleep" state can be + defined to set pins in sleep state when in low power. +- pinctrl-n: List of phandles pointing to pin configuration nodes for PWM module. For Pinctrl properties see ../pinctrl/pinctrl-bindings.txt - #pwm-cells: Should be set to 3. This PWM chip uses the default 3 cells bindings defined in pwm.txt. @@ -32,7 +33,8 @@ Example: compatible = "st,stm32-pwm"; #pwm-cells = <3>; pinctrl-0 = <&pwm1_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&pwm1_sleep_pins>; + pinctrl-names = "default", "sleep"; st,breakinput = <0 1 5>; }; }; diff --git a/drivers/pinctrl/pinctrl-stmfx.c b/drivers/pinctrl/pinctrl-stmfx.c index ccdf0bb214149..f7958eece5e0e 100644 --- a/drivers/pinctrl/pinctrl-stmfx.c +++ b/drivers/pinctrl/pinctrl-stmfx.c @@ -277,7 +277,7 @@ static int stmfx_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, struct pinctrl_gpio_range *range; enum pin_config_param param; u32 arg; - int dir, i, ret; + int i, ret; range = pinctrl_find_gpio_range_from_pin_nolock(pctldev, pin); if (!range) { @@ -285,10 +285,6 @@ static int stmfx_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, return -EINVAL; } - dir = stmfx_gpio_get_direction(&pctl->gpio_chip, pin); - if (dir < 0) - return dir; - for (i = 0; i < num_configs; i++) { param = pinconf_to_config_param(configs[i]); arg = pinconf_to_config_argument(configs[i]); @@ -505,6 +501,34 @@ static void stmfx_pinctrl_irq_bus_sync_unlock(struct irq_data *data) mutex_unlock(&pctl->lock); } +static int stmfx_gpio_irq_request_resources(struct irq_data *data) +{ + struct gpio_chip *gpio_chip = irq_data_get_irq_chip_data(data); + struct stmfx_pinctrl *pctl = gpiochip_get_data(gpio_chip); + int ret; + + ret = stmfx_gpio_direction_input(&pctl->gpio_chip, data->hwirq); + if (ret) + return ret; + + ret = gpiochip_lock_as_irq(&pctl->gpio_chip, data->hwirq); + if (ret) { + dev_err(pctl->dev, "Unable to lock gpio %lu as IRQ: %d\n", + data->hwirq, ret); + return ret; + } + + return 0; +} + +static void stmfx_gpio_irq_release_resources(struct irq_data *data) +{ + struct gpio_chip *gpio_chip = irq_data_get_irq_chip_data(data); + struct stmfx_pinctrl *pctl = gpiochip_get_data(gpio_chip); + + gpiochip_unlock_as_irq(&pctl->gpio_chip, data->hwirq); +} + static void stmfx_pinctrl_irq_toggle_trigger(struct stmfx_pinctrl *pctl, unsigned int offset) { @@ -664,6 +688,8 @@ static int stmfx_pinctrl_probe(struct platform_device *pdev) pctl->irq_chip.irq_set_type = stmfx_pinctrl_irq_set_type; pctl->irq_chip.irq_bus_lock = stmfx_pinctrl_irq_bus_lock; pctl->irq_chip.irq_bus_sync_unlock = stmfx_pinctrl_irq_bus_sync_unlock; + pctl->irq_chip.irq_request_resources = stmfx_gpio_irq_request_resources; + pctl->irq_chip.irq_release_resources = stmfx_gpio_irq_release_resources; ret = gpiochip_irqchip_add_nested(&pctl->gpio_chip, &pctl->irq_chip, 0, handle_bad_irq, IRQ_TYPE_NONE); diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c index 2d5e0435af0a4..ef3b081d27983 100644 --- a/drivers/pinctrl/stm32/pinctrl-stm32.c +++ b/drivers/pinctrl/stm32/pinctrl-stm32.c @@ -64,7 +64,7 @@ #define gpio_range_to_bank(chip) \ container_of(chip, struct stm32_gpio_bank, range) -#define HWSPINLOCK_TIMEOUT 5 /* msec */ +#define HWSPNLCK_TIMEOUT 1000 /* usec */ static const char * const stm32_gpio_functions[] = { "gpio", "af0", "af1", @@ -73,6 +73,7 @@ static const char * const stm32_gpio_functions[] = { "af8", "af9", "af10", "af11", "af12", "af13", "af14", "af15", "analog", + "reserved", }; struct stm32_pinctrl_group { @@ -84,6 +85,7 @@ struct stm32_pinctrl_group { struct stm32_gpio_bank { void __iomem *base; struct clk *clk; + struct reset_control *rstc; spinlock_t lock; struct gpio_chip gpio_chip; struct pinctrl_gpio_range range; @@ -92,6 +94,7 @@ struct stm32_gpio_bank { u32 bank_nr; u32 bank_ioport_nr; u32 pin_backup[STM32_GPIO_PINS_PER_BANK]; + u8 irq_type[STM32_GPIO_PINS_PER_BANK]; }; struct stm32_pinctrl { @@ -113,6 +116,7 @@ struct stm32_pinctrl { u32 pkg; u16 irqmux_map; spinlock_t irqmux_lock; + u32 pin_base_shift; }; static inline int stm32_gpio_pin(int gpio) @@ -301,6 +305,51 @@ static const struct gpio_chip stm32_gpio_template = { .direction_output = stm32_gpio_direction_output, .to_irq = stm32_gpio_to_irq, .get_direction = stm32_gpio_get_direction, + .set_config = gpiochip_generic_config, +}; + +static void stm32_gpio_irq_trigger(struct irq_data *d) +{ + struct stm32_gpio_bank *bank = d->domain->host_data; + int level; + + /* If level interrupt type then retrig */ + level = stm32_gpio_get(&bank->gpio_chip, d->hwirq); + if ((level == 0 && bank->irq_type[d->hwirq] == IRQ_TYPE_LEVEL_LOW) || + (level == 1 && bank->irq_type[d->hwirq] == IRQ_TYPE_LEVEL_HIGH)) + irq_chip_retrigger_hierarchy(d); +} + +static void stm32_gpio_irq_eoi(struct irq_data *d) +{ + irq_chip_eoi_parent(d); + stm32_gpio_irq_trigger(d); +}; + +static int stm32_gpio_set_type(struct irq_data *d, unsigned int type) +{ + struct stm32_gpio_bank *bank = d->domain->host_data; + u32 parent_type; + + switch (type) { + case IRQ_TYPE_EDGE_RISING: + case IRQ_TYPE_EDGE_FALLING: + case IRQ_TYPE_EDGE_BOTH: + parent_type = type; + break; + case IRQ_TYPE_LEVEL_HIGH: + parent_type = IRQ_TYPE_EDGE_RISING; + break; + case IRQ_TYPE_LEVEL_LOW: + parent_type = IRQ_TYPE_EDGE_FALLING; + break; + default: + return -EINVAL; + } + + bank->irq_type[d->hwirq] = type; + + return irq_chip_set_type_parent(d, parent_type); }; static int stm32_gpio_irq_request_resources(struct irq_data *irq_data) @@ -330,13 +379,19 @@ static void stm32_gpio_irq_release_resources(struct irq_data *irq_data) gpiochip_unlock_as_irq(&bank->gpio_chip, irq_data->hwirq); } +static void stm32_gpio_irq_unmask(struct irq_data *d) +{ + irq_chip_unmask_parent(d); + stm32_gpio_irq_trigger(d); +} + static struct irq_chip stm32_gpio_irq_chip = { .name = "stm32gpio", - .irq_eoi = irq_chip_eoi_parent, + .irq_eoi = stm32_gpio_irq_eoi, .irq_ack = irq_chip_ack_parent, .irq_mask = irq_chip_mask_parent, - .irq_unmask = irq_chip_unmask_parent, - .irq_set_type = irq_chip_set_type_parent, + .irq_unmask = stm32_gpio_irq_unmask, + .irq_set_type = stm32_gpio_set_type, .irq_set_wake = irq_chip_set_wake_parent, .irq_request_resources = stm32_gpio_irq_request_resources, .irq_release_resources = stm32_gpio_irq_release_resources, @@ -369,12 +424,14 @@ static int stm32_gpio_domain_activate(struct irq_domain *d, * to avoid overriding. */ spin_lock_irqsave(&pctl->irqmux_lock, flags); - if (pctl->hwlock) - ret = hwspin_lock_timeout(pctl->hwlock, HWSPINLOCK_TIMEOUT); - if (ret) { - dev_err(pctl->dev, "Can't get hwspinlock\n"); - goto unlock; + if (pctl->hwlock) { + ret = hwspin_lock_timeout_in_atomic(pctl->hwlock, + HWSPNLCK_TIMEOUT); + if (ret) { + dev_err(pctl->dev, "Can't get hwspinlock\n"); + goto unlock; + } } if (pctl->irqmux_map & BIT(irq_data->hwirq)) { @@ -382,7 +439,7 @@ static int stm32_gpio_domain_activate(struct irq_domain *d, irq_data->hwirq); ret = -EBUSY; if (pctl->hwlock) - hwspin_unlock(pctl->hwlock); + hwspin_unlock_in_atomic(pctl->hwlock); goto unlock; } else { pctl->irqmux_map |= BIT(irq_data->hwirq); @@ -391,7 +448,7 @@ static int stm32_gpio_domain_activate(struct irq_domain *d, regmap_field_write(pctl->irqmux[irq_data->hwirq], bank->bank_ioport_nr); if (pctl->hwlock) - hwspin_unlock(pctl->hwlock); + hwspin_unlock_in_atomic(pctl->hwlock); unlock: spin_unlock_irqrestore(&pctl->irqmux_lock, flags); @@ -458,7 +515,7 @@ stm32_pctrl_find_group_by_pin(struct stm32_pinctrl *pctl, u32 pin) static bool stm32_pctrl_is_function_valid(struct stm32_pinctrl *pctl, u32 pin_num, u32 fnum) { - int i; + int i, k; for (i = 0; i < pctl->npins; i++) { const struct stm32_desc_pin *pin = pctl->pins + i; @@ -467,7 +524,10 @@ static bool stm32_pctrl_is_function_valid(struct stm32_pinctrl *pctl, if (pin->pin.number != pin_num) continue; - while (func && func->name) { + if (fnum == STM32_PIN_RSVD) + return true; + + for (k = 0; k < STM32_CONFIG_NUM; k++) { if (func->num == fnum) return true; func++; @@ -699,12 +759,13 @@ static int stm32_pmx_set_mode(struct stm32_gpio_bank *bank, clk_enable(bank->clk); spin_lock_irqsave(&bank->lock, flags); - if (pctl->hwlock) - err = hwspin_lock_timeout(pctl->hwlock, HWSPINLOCK_TIMEOUT); - - if (err) { - dev_err(pctl->dev, "Can't get hwspinlock\n"); - goto unlock; + if (pctl->hwlock) { + err = hwspin_lock_timeout_in_atomic(pctl->hwlock, + HWSPNLCK_TIMEOUT); + if (err) { + dev_err(pctl->dev, "Can't get hwspinlock\n"); + goto unlock; + } } val = readl_relaxed(bank->base + alt_offset); @@ -718,7 +779,7 @@ static int stm32_pmx_set_mode(struct stm32_gpio_bank *bank, writel_relaxed(val, bank->base + STM32_GPIO_MODER); if (pctl->hwlock) - hwspin_unlock(pctl->hwlock); + hwspin_unlock_in_atomic(pctl->hwlock); stm32_gpio_backup_mode(bank, pin, mode, alt); @@ -777,6 +838,11 @@ static int stm32_pmx_set_mux(struct pinctrl_dev *pctldev, return -EINVAL; } + if (function == STM32_PIN_RSVD) { + dev_dbg(pctl->dev, "Reserved pins, skipping HW update.\n"); + return 0; + } + bank = gpiochip_get_data(range->gc); pin = stm32_gpio_pin(g->pin); @@ -818,12 +884,13 @@ static int stm32_pconf_set_driving(struct stm32_gpio_bank *bank, clk_enable(bank->clk); spin_lock_irqsave(&bank->lock, flags); - if (pctl->hwlock) - err = hwspin_lock_timeout(pctl->hwlock, HWSPINLOCK_TIMEOUT); - - if (err) { - dev_err(pctl->dev, "Can't get hwspinlock\n"); - goto unlock; + if (pctl->hwlock) { + err = hwspin_lock_timeout_in_atomic(pctl->hwlock, + HWSPNLCK_TIMEOUT); + if (err) { + dev_err(pctl->dev, "Can't get hwspinlock\n"); + goto unlock; + } } val = readl_relaxed(bank->base + STM32_GPIO_TYPER); @@ -832,7 +899,7 @@ static int stm32_pconf_set_driving(struct stm32_gpio_bank *bank, writel_relaxed(val, bank->base + STM32_GPIO_TYPER); if (pctl->hwlock) - hwspin_unlock(pctl->hwlock); + hwspin_unlock_in_atomic(pctl->hwlock); stm32_gpio_backup_driving(bank, offset, drive); @@ -872,12 +939,13 @@ static int stm32_pconf_set_speed(struct stm32_gpio_bank *bank, clk_enable(bank->clk); spin_lock_irqsave(&bank->lock, flags); - if (pctl->hwlock) - err = hwspin_lock_timeout(pctl->hwlock, HWSPINLOCK_TIMEOUT); - - if (err) { - dev_err(pctl->dev, "Can't get hwspinlock\n"); - goto unlock; + if (pctl->hwlock) { + err = hwspin_lock_timeout_in_atomic(pctl->hwlock, + HWSPNLCK_TIMEOUT); + if (err) { + dev_err(pctl->dev, "Can't get hwspinlock\n"); + goto unlock; + } } val = readl_relaxed(bank->base + STM32_GPIO_SPEEDR); @@ -886,7 +954,7 @@ static int stm32_pconf_set_speed(struct stm32_gpio_bank *bank, writel_relaxed(val, bank->base + STM32_GPIO_SPEEDR); if (pctl->hwlock) - hwspin_unlock(pctl->hwlock); + hwspin_unlock_in_atomic(pctl->hwlock); stm32_gpio_backup_speed(bank, offset, speed); @@ -926,12 +994,13 @@ static int stm32_pconf_set_bias(struct stm32_gpio_bank *bank, clk_enable(bank->clk); spin_lock_irqsave(&bank->lock, flags); - if (pctl->hwlock) - err = hwspin_lock_timeout(pctl->hwlock, HWSPINLOCK_TIMEOUT); - - if (err) { - dev_err(pctl->dev, "Can't get hwspinlock\n"); - goto unlock; + if (pctl->hwlock) { + err = hwspin_lock_timeout_in_atomic(pctl->hwlock, + HWSPNLCK_TIMEOUT); + if (err) { + dev_err(pctl->dev, "Can't get hwspinlock\n"); + goto unlock; + } } val = readl_relaxed(bank->base + STM32_GPIO_PUPDR); @@ -940,7 +1009,7 @@ static int stm32_pconf_set_bias(struct stm32_gpio_bank *bank, writel_relaxed(val, bank->base + STM32_GPIO_PUPDR); if (pctl->hwlock) - hwspin_unlock(pctl->hwlock); + hwspin_unlock_in_atomic(pctl->hwlock); stm32_gpio_backup_bias(bank, offset, bias); @@ -992,20 +1061,14 @@ static bool stm32_pconf_get(struct stm32_gpio_bank *bank, } static int stm32_pconf_parse_conf(struct pinctrl_dev *pctldev, - unsigned int pin, enum pin_config_param param, - enum pin_config_param arg) + struct pinctrl_gpio_range *range, + unsigned int pin, + enum pin_config_param param, + enum pin_config_param arg) { - struct stm32_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); - struct pinctrl_gpio_range *range; struct stm32_gpio_bank *bank; int offset, ret = 0; - range = pinctrl_find_gpio_range_from_pin(pctldev, pin); - if (!range) { - dev_err(pctl->dev, "No gpio range defined.\n"); - return -EINVAL; - } - bank = gpiochip_get_data(range->gc); offset = stm32_gpio_pin(pin); @@ -1033,7 +1096,8 @@ static int stm32_pconf_parse_conf(struct pinctrl_dev *pctldev, ret = stm32_pmx_gpio_set_direction(pctldev, range, pin, false); break; default: - ret = -EINVAL; + dev_dbg(pctldev->dev, "configuration %d not supported.\n", + param); } return ret; @@ -1055,12 +1119,19 @@ static int stm32_pconf_group_set(struct pinctrl_dev *pctldev, unsigned group, { struct stm32_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); struct stm32_pinctrl_group *g = &pctl->groups[group]; + struct pinctrl_gpio_range *range; int i, ret; + range = pinctrl_find_gpio_range_from_pin(pctldev, g->pin); + if (!range) { + dev_err(pctl->dev, "No gpio range defined.\n"); + return -EINVAL; + } + for (i = 0; i < num_configs; i++) { - ret = stm32_pconf_parse_conf(pctldev, g->pin, - pinconf_to_config_param(configs[i]), - pinconf_to_config_argument(configs[i])); + ret = stm32_pconf_parse_conf(pctldev, range, g->pin, + pinconf_to_config_param(configs[i]), + pinconf_to_config_argument(configs[i])); if (ret < 0) return ret; @@ -1070,10 +1141,51 @@ static int stm32_pconf_group_set(struct pinctrl_dev *pctldev, unsigned group, return 0; } +static int stm32_pconf_set(struct pinctrl_dev *pctldev, unsigned int pin, + unsigned long *configs, unsigned int num_configs) +{ + struct stm32_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); + struct pinctrl_gpio_range *range; + int i, ret; + + range = pinctrl_find_gpio_range_from_pin_nolock(pctldev, pin); + if (!range) { + dev_err(pctl->dev, "No gpio range defined.\n"); + return -EINVAL; + } + + for (i = 0; i < num_configs; i++) { + ret = stm32_pconf_parse_conf(pctldev, range, pin, + pinconf_to_config_param(configs[i]), + pinconf_to_config_argument(configs[i])); + if (ret < 0) + return ret; + } + + return 0; +} + +static struct stm32_desc_pin * +stm32_pconf_get_pin_desc_by_pin_number(struct stm32_pinctrl *pctl, + unsigned int pin_number) +{ + struct stm32_desc_pin *pins = pctl->pins; + int i; + + for (i = 0; i < pctl->npins; i++) { + if (pins->pin.number == pin_number) + return pins; + pins++; + } + return NULL; +} + static void stm32_pconf_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, unsigned int pin) { + struct stm32_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); + const struct stm32_desc_pin *pin_desc; struct pinctrl_gpio_range *range; struct stm32_gpio_bank *bank; int offset; @@ -1123,7 +1235,12 @@ static void stm32_pconf_dbg_show(struct pinctrl_dev *pctldev, case 2: drive = stm32_pconf_get_driving(bank, offset); speed = stm32_pconf_get_speed(bank, offset); - seq_printf(s, "%d - %s - %s - %s %s", alt, + pin_desc = stm32_pconf_get_pin_desc_by_pin_number(pctl, pin); + if (!pin_desc) + return; + + seq_printf(s, "%d (%s) - %s - %s - %s %s", alt, + pin_desc->functions[alt + 1].name, drive ? "open drain" : "push pull", biasing[bias], speeds[speed], "speed"); @@ -1140,6 +1257,7 @@ static const struct pinconf_ops stm32_pconf_ops = { .pin_config_group_get = stm32_pconf_group_get, .pin_config_group_set = stm32_pconf_group_set, .pin_config_dbg_show = stm32_pconf_dbg_show, + .pin_config_set = stm32_pconf_set, }; static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, @@ -1151,13 +1269,11 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, struct of_phandle_args args; struct device *dev = pctl->dev; struct resource res; - struct reset_control *rstc; int npins = STM32_GPIO_PINS_PER_BANK; int bank_nr, err; - rstc = of_reset_control_get_exclusive(np, NULL); - if (!IS_ERR(rstc)) - reset_control_deassert(rstc); + if (!IS_ERR(bank->rstc)) + reset_control_deassert(bank->rstc); if (of_address_to_resource(np, 0, &res)) return -ENODEV; @@ -1166,12 +1282,6 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, if (IS_ERR(bank->base)) return PTR_ERR(bank->base); - bank->clk = of_clk_get_by_name(np, NULL); - if (IS_ERR(bank->clk)) { - dev_err(dev, "failed to get clk (%ld)\n", PTR_ERR(bank->clk)); - return PTR_ERR(bank->clk); - } - err = clk_prepare(bank->clk); if (err) { dev_err(dev, "failed to prepare clk (%d)\n", err); @@ -1335,7 +1445,8 @@ static int stm32_pctrl_create_pins_tab(struct stm32_pinctrl *pctl, if (pctl->pkg && !(pctl->pkg & p->pkg)) continue; pins->pin = p->pin; - pins->functions = p->functions; + memcpy((struct stm32_desc_pin *)pins->functions, p->functions, + STM32_CONFIG_NUM * sizeof(struct stm32_desc_function)); pins++; nb_pins_available++; } @@ -1444,6 +1555,7 @@ int stm32_pctl_probe(struct platform_device *pdev) pctl->pctl_desc.pctlops = &stm32_pctrl_ops; pctl->pctl_desc.pmxops = &stm32_pmx_ops; pctl->dev = &pdev->dev; + pctl->pin_base_shift = pctl->match_data->pin_base_shift; pctl->pctl_dev = devm_pinctrl_register(&pdev->dev, &pctl->pctl_desc, pctl); @@ -1466,6 +1578,28 @@ int stm32_pctl_probe(struct platform_device *pdev) if (!pctl->banks) return -ENOMEM; + i = 0; + for_each_available_child_of_node(np, child) { + struct stm32_gpio_bank *bank = &pctl->banks[i]; + + if (of_property_read_bool(child, "gpio-controller")) { + bank->rstc = of_reset_control_get_exclusive(child, + NULL); + if (PTR_ERR(bank->rstc) == -EPROBE_DEFER) + return -EPROBE_DEFER; + + bank->clk = of_clk_get_by_name(child, NULL); + if (IS_ERR(bank->clk)) { + if (PTR_ERR(bank->clk) != -EPROBE_DEFER) + dev_err(dev, + "failed to get clk (%ld)\n", + PTR_ERR(bank->clk)); + return PTR_ERR(bank->clk); + } + i++; + } + } + for_each_available_child_of_node(np, child) { if (of_property_read_bool(child, "gpio-controller")) { ret = stm32_gpiolib_register_bank(pctl, child); diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.h b/drivers/pinctrl/stm32/pinctrl-stm32.h index ec0d34c339031..b11a223f3504c 100644 --- a/drivers/pinctrl/stm32/pinctrl-stm32.h +++ b/drivers/pinctrl/stm32/pinctrl-stm32.h @@ -17,6 +17,8 @@ #define STM32_PIN_GPIO 0 #define STM32_PIN_AF(x) ((x) + 1) #define STM32_PIN_ANALOG (STM32_PIN_AF(15) + 1) +#define STM32_PIN_RSVD (STM32_PIN_ANALOG + 1) +#define STM32_CONFIG_NUM (STM32_PIN_RSVD + 1) /* package information */ #define STM32MP_PKG_AA BIT(0) @@ -24,6 +26,8 @@ #define STM32MP_PKG_AC BIT(2) #define STM32MP_PKG_AD BIT(3) +#define STM32MP157_Z_BASE_SHIFT 400 + struct stm32_desc_function { const char *name; const unsigned char num; @@ -31,26 +35,26 @@ struct stm32_desc_function { struct stm32_desc_pin { struct pinctrl_pin_desc pin; - const struct stm32_desc_function *functions; + const struct stm32_desc_function functions[STM32_CONFIG_NUM]; const unsigned int pkg; }; #define STM32_PIN(_pin, ...) \ { \ .pin = _pin, \ - .functions = (struct stm32_desc_function[]){ \ - __VA_ARGS__, { } }, \ + .functions = { \ + __VA_ARGS__}, \ } #define STM32_PIN_PKG(_pin, _pkg, ...) \ { \ .pin = _pin, \ .pkg = _pkg, \ - .functions = (struct stm32_desc_function[]){ \ - __VA_ARGS__, { } }, \ + .functions = { \ + __VA_ARGS__}, \ } #define STM32_FUNCTION(_num, _name) \ - { \ + [_num] = { \ .num = _num, \ .name = _name, \ } @@ -58,6 +62,7 @@ struct stm32_desc_pin { struct stm32_pinctrl_match_data { const struct stm32_desc_pin *pins; const unsigned int npins; + const unsigned int pin_base_shift; }; struct stm32_gpio_bank; diff --git a/drivers/pinctrl/stm32/pinctrl-stm32mp157.c b/drivers/pinctrl/stm32/pinctrl-stm32mp157.c index 2ccb99d64df83..86fe6d5ac54d6 100644 --- a/drivers/pinctrl/stm32/pinctrl-stm32mp157.c +++ b/drivers/pinctrl/stm32/pinctrl-stm32mp157.c @@ -2328,6 +2328,7 @@ static struct stm32_pinctrl_match_data stm32mp157_match_data = { static struct stm32_pinctrl_match_data stm32mp157_z_match_data = { .pins = stm32mp157_z_pins, .npins = ARRAY_SIZE(stm32mp157_z_pins), + .pin_base_shift = STM32MP157_Z_BASE_SHIFT, }; static const struct of_device_id stm32mp157_pctrl_match[] = { diff --git a/drivers/pwm/pwm-stm32.c b/drivers/pwm/pwm-stm32.c index 359b08596d9e3..d3be944f2ae96 100644 --- a/drivers/pwm/pwm-stm32.c +++ b/drivers/pwm/pwm-stm32.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -19,6 +20,12 @@ #define CCMR_CHANNEL_MASK 0xFF #define MAX_BREAKINPUT 2 +struct stm32_breakinput { + u32 index; + u32 level; + u32 filter; +}; + struct stm32_pwm { struct pwm_chip chip; struct mutex lock; /* protect pwm config/enable */ @@ -26,15 +33,11 @@ struct stm32_pwm { struct regmap *regmap; u32 max_arr; bool have_complementary_output; + struct stm32_breakinput breakinputs[MAX_BREAKINPUT]; + unsigned int num_breakinputs; u32 capture[4] ____cacheline_aligned; /* DMA'able buffer */ }; -struct stm32_breakinput { - u32 index; - u32 level; - u32 filter; -}; - static inline struct stm32_pwm *to_stm32_pwm_dev(struct pwm_chip *chip) { return container_of(chip, struct stm32_pwm, chip); @@ -374,9 +377,7 @@ static int stm32_pwm_config(struct stm32_pwm *priv, int ch, else regmap_update_bits(priv->regmap, TIM_CCMR2, mask, ccmr); - regmap_update_bits(priv->regmap, TIM_BDTR, - TIM_BDTR_MOE | TIM_BDTR_AOE, - TIM_BDTR_MOE | TIM_BDTR_AOE); + regmap_update_bits(priv->regmap, TIM_BDTR, TIM_BDTR_MOE, TIM_BDTR_MOE); return 0; } @@ -488,22 +489,19 @@ static const struct pwm_ops stm32pwm_ops = { }; static int stm32_pwm_set_breakinput(struct stm32_pwm *priv, - int index, int level, int filter) + const struct stm32_breakinput *bi) { - u32 bke = (index == 0) ? TIM_BDTR_BKE : TIM_BDTR_BK2E; - int shift = (index == 0) ? TIM_BDTR_BKF_SHIFT : TIM_BDTR_BK2F_SHIFT; - u32 mask = (index == 0) ? TIM_BDTR_BKE | TIM_BDTR_BKP | TIM_BDTR_BKF - : TIM_BDTR_BK2E | TIM_BDTR_BK2P | TIM_BDTR_BK2F; - u32 bdtr = bke; + u32 shift = TIM_BDTR_BKF_SHIFT(bi->index); + u32 bke = TIM_BDTR_BKE(bi->index); + u32 bkp = TIM_BDTR_BKP(bi->index); + u32 bkf = TIM_BDTR_BKF(bi->index); + u32 mask = bkf | bkp | bke; + u32 bdtr; - /* - * The both bits could be set since only one will be wrote - * due to mask value. - */ - if (level) - bdtr |= TIM_BDTR_BKP | TIM_BDTR_BK2P; + bdtr = (bi->filter & TIM_BDTR_BKF_MASK) << shift | bke; - bdtr |= (filter & TIM_BDTR_BKF_MASK) << shift; + if (bi->level) + bdtr |= bkp; regmap_update_bits(priv->regmap, TIM_BDTR, mask, bdtr); @@ -512,11 +510,25 @@ static int stm32_pwm_set_breakinput(struct stm32_pwm *priv, return (bdtr & bke) ? 0 : -EINVAL; } -static int stm32_pwm_apply_breakinputs(struct stm32_pwm *priv, +static int stm32_pwm_apply_breakinputs(struct stm32_pwm *priv) +{ + unsigned int i; + int ret; + + for (i = 0; i < priv->num_breakinputs; i++) { + ret = stm32_pwm_set_breakinput(priv, &priv->breakinputs[i]); + if (ret < 0) + return ret; + } + + return 0; +} + +static int stm32_pwm_probe_breakinputs(struct stm32_pwm *priv, struct device_node *np) { - struct stm32_breakinput breakinput[MAX_BREAKINPUT]; - int nb, ret, i, array_size; + int nb, ret, array_size; + unsigned int i; nb = of_property_count_elems_of_size(np, "st,breakinput", sizeof(struct stm32_breakinput)); @@ -531,20 +543,21 @@ static int stm32_pwm_apply_breakinputs(struct stm32_pwm *priv, if (nb > MAX_BREAKINPUT) return -EINVAL; + priv->num_breakinputs = nb; array_size = nb * sizeof(struct stm32_breakinput) / sizeof(u32); ret = of_property_read_u32_array(np, "st,breakinput", - (u32 *)breakinput, array_size); + (u32 *)priv->breakinputs, array_size); if (ret) return ret; - for (i = 0; i < nb && !ret; i++) { - ret = stm32_pwm_set_breakinput(priv, - breakinput[i].index, - breakinput[i].level, - breakinput[i].filter); + for (i = 0; i < priv->num_breakinputs; i++) { + if (priv->breakinputs[i].index > 1 || + priv->breakinputs[i].level > 1 || + priv->breakinputs[i].filter > 15) + return -EINVAL; } - return ret; + return stm32_pwm_apply_breakinputs(priv); } static void stm32_pwm_detect_complementary(struct stm32_pwm *priv) @@ -614,7 +627,7 @@ static int stm32_pwm_probe(struct platform_device *pdev) if (!priv->regmap || !priv->clk) return -EINVAL; - ret = stm32_pwm_apply_breakinputs(priv, np); + ret = stm32_pwm_probe_breakinputs(priv, np); if (ret) return ret; @@ -647,6 +660,42 @@ static int stm32_pwm_remove(struct platform_device *pdev) return 0; } +static int __maybe_unused stm32_pwm_suspend(struct device *dev) +{ + struct stm32_pwm *priv = dev_get_drvdata(dev); + unsigned int i; + u32 ccer, mask; + + /* Look for active channels */ + ccer = active_channels(priv); + + for (i = 0; i < priv->chip.npwm; i++) { + mask = TIM_CCER_CC1E << (i * 4); + if (ccer & mask) { + dev_err(dev, "PWM %u still in use by consumer %s\n", + i, priv->chip.pwms[i].label); + return -EBUSY; + } + } + + return pinctrl_pm_select_sleep_state(dev); +} + +static int __maybe_unused stm32_pwm_resume(struct device *dev) +{ + struct stm32_pwm *priv = dev_get_drvdata(dev); + int ret; + + ret = pinctrl_pm_select_default_state(dev); + if (ret) + return ret; + + /* restore breakinput registers that may have been lost in low power */ + return stm32_pwm_apply_breakinputs(priv); +} + +static SIMPLE_DEV_PM_OPS(stm32_pwm_pm_ops, stm32_pwm_suspend, stm32_pwm_resume); + static const struct of_device_id stm32_pwm_of_match[] = { { .compatible = "st,stm32-pwm", }, { /* end node */ }, @@ -659,6 +708,7 @@ static struct platform_driver stm32_pwm_driver = { .driver = { .name = "stm32-pwm", .of_match_table = stm32_pwm_of_match, + .pm = &stm32_pwm_pm_ops, }, }; module_platform_driver(stm32_pwm_driver); diff --git a/drivers/regulator/stm32-pwr.c b/drivers/regulator/stm32-pwr.c index e0e627b0106e0..373d83797ea86 100644 --- a/drivers/regulator/stm32-pwr.c +++ b/drivers/regulator/stm32-pwr.c @@ -3,12 +3,15 @@ // Authors: Gabriel Fernandez // Pascal Paillet . +#include #include #include +#include #include #include #include #include +#include #include #include @@ -24,6 +27,11 @@ #define REG_1_1_EN BIT(30) #define REG_1_1_RDY BIT(31) +#define STM32_SMC_PWR 0x82001001 +#define STM32_WRITE 0x1 +#define STM32_SMC_REG_SET 0x2 +#define STM32_SMC_REG_CLEAR 0x3 + /* list of supported regulators */ enum { PWR_REG11, @@ -39,10 +47,18 @@ static u32 ready_mask_table[STM32PWR_REG_NUM_REGS] = { }; struct stm32_pwr_reg { + int tzen; void __iomem *base; u32 ready_mask; }; +#define SMC(class, op, address, val)\ + ({\ + struct arm_smccc_res res;\ + arm_smccc_smc(class, op, address, val,\ + 0, 0, 0, 0, &res);\ + }) + static int stm32_pwr_reg_is_ready(struct regulator_dev *rdev) { struct stm32_pwr_reg *priv = rdev_get_drvdata(rdev); @@ -69,9 +85,15 @@ static int stm32_pwr_reg_enable(struct regulator_dev *rdev) int ret; u32 val; - val = readl_relaxed(priv->base + REG_PWR_CR3); - val |= rdev->desc->enable_mask; - writel_relaxed(val, priv->base + REG_PWR_CR3); + if (priv->tzen) { + SMC(STM32_SMC_PWR, STM32_SMC_REG_SET, REG_PWR_CR3, + rdev->desc->enable_mask); + } else { + val = readl_relaxed(priv->base + REG_PWR_CR3); + val |= rdev->desc->enable_mask; + writel_relaxed(val, priv->base + REG_PWR_CR3); + } + /* use an arbitrary timeout of 20ms */ ret = readx_poll_timeout(stm32_pwr_reg_is_ready, rdev, val, val, @@ -88,9 +110,14 @@ static int stm32_pwr_reg_disable(struct regulator_dev *rdev) int ret; u32 val; - val = readl_relaxed(priv->base + REG_PWR_CR3); - val &= ~rdev->desc->enable_mask; - writel_relaxed(val, priv->base + REG_PWR_CR3); + if (priv->tzen) { + SMC(STM32_SMC_PWR, STM32_SMC_REG_CLEAR, REG_PWR_CR3, + rdev->desc->enable_mask); + } else { + val = readl_relaxed(priv->base + REG_PWR_CR3); + val &= ~rdev->desc->enable_mask; + writel_relaxed(val, priv->base + REG_PWR_CR3); + } /* use an arbitrary timeout of 20ms */ ret = readx_poll_timeout(stm32_pwr_reg_is_ready, rdev, val, !val, @@ -121,12 +148,50 @@ static const struct regulator_ops stm32_pwr_reg_ops = { .supply_name = _supply, \ } \ -static const struct regulator_desc stm32_pwr_desc[] = { +static struct regulator_desc stm32_pwr_desc[] = { PWR_REG(PWR_REG11, "reg11", 1100000, REG_1_1_EN, "vdd"), PWR_REG(PWR_REG18, "reg18", 1800000, REG_1_8_EN, "vdd"), PWR_REG(PWR_USB33, "usb33", 3300000, USB_3_3_EN, "vdd_3v3_usbfs"), }; +static int is_stm32_soc_secured(struct platform_device *pdev, int *val) +{ + struct device_node *np = pdev->dev.of_node; + struct regmap *syscon; + u32 reg, mask; + int tzc_val = 0; + int err; + + syscon = syscon_regmap_lookup_by_phandle(np, "st,tzcr"); + if (IS_ERR(syscon)) { + if (PTR_ERR(syscon) != -EPROBE_DEFER) + dev_err(&pdev->dev, "tzcr syscon required\n"); + return PTR_ERR(syscon); + } + + err = of_property_read_u32_index(np, "st,tzcr", 1, ®); + if (err) { + dev_err(&pdev->dev, "tzcr offset required !\n"); + return err; + } + + err = of_property_read_u32_index(np, "st,tzcr", 2, &mask); + if (err) { + dev_err(&pdev->dev, "tzcr mask required !\n"); + return err; + } + + err = regmap_read(syscon, reg, &tzc_val); + if (err) { + dev_err(&pdev->dev, "failed to read tzcr status !\n"); + return err; + } + + *val = tzc_val & mask; + + return 0; +} + static int stm32_pwr_regulator_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; @@ -135,6 +200,11 @@ static int stm32_pwr_regulator_probe(struct platform_device *pdev) struct regulator_dev *rdev; struct regulator_config config = { }; int i, ret = 0; + int tzen = 0; + + ret = is_stm32_soc_secured(pdev, &tzen); + if (ret) + return ret; base = of_iomap(np, 0); if (!base) { @@ -149,6 +219,7 @@ static int stm32_pwr_regulator_probe(struct platform_device *pdev) GFP_KERNEL); if (!priv) return -ENOMEM; + priv->tzen = tzen; priv->base = base; priv->ready_mask = ready_mask_table[i]; config.driver_data = priv; diff --git a/drivers/regulator/stpmic1_regulator.c b/drivers/regulator/stpmic1_regulator.c index f09061473613c..4537e3ab143ca 100644 --- a/drivers/regulator/stpmic1_regulator.c +++ b/drivers/regulator/stpmic1_regulator.c @@ -2,7 +2,9 @@ // Copyright (C) STMicroelectronics 2018 // Author: Pascal Paillet for STMicroelectronics. +#include #include +#include #include #include #include @@ -30,10 +32,26 @@ struct stpmic1_regulator_cfg { u8 icc_mask; }; +/** + * struct boost_data - this structure is used as driver data for the usb boost + * @boost_rdev: device for boost regulator + * @vbus_otg_rdev: device for vbus_otg regulator + * @sw_out_rdev: device for sw_out regulator + * @occ_timeout: overcurrent detection timeout + */ +struct boost_data { + struct regulator_dev *boost_rdev; + struct regulator_dev *vbus_otg_rdev; + struct regulator_dev *sw_out_rdev; + ktime_t occ_timeout; +}; + static int stpmic1_set_mode(struct regulator_dev *rdev, unsigned int mode); static unsigned int stpmic1_get_mode(struct regulator_dev *rdev); static int stpmic1_set_icc(struct regulator_dev *rdev); static unsigned int stpmic1_map_mode(unsigned int mode); +static int regulator_enable_boost(struct regulator_dev *rdev); +static int regulator_disable_boost(struct regulator_dev *rdev); enum { STPMIC1_BUCK1 = 0, @@ -54,6 +72,8 @@ enum { /* Enable time worst case is 5000mV/(2250uV/uS) */ #define PMIC_ENABLE_TIME_US 2200 +/* Ramp delay worst case is (2250uV/uS) */ +#define PMIC_RAMP_DELAY 2200 static const struct regulator_linear_range buck1_ranges[] = { REGULATOR_LINEAR_RANGE(725000, 0, 4, 0), @@ -179,8 +199,8 @@ static const struct regulator_ops stpmic1_vref_ddr_ops = { static const struct regulator_ops stpmic1_boost_regul_ops = { .is_enabled = regulator_is_enabled_regmap, - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, + .enable = regulator_enable_boost, + .disable = regulator_disable_boost, .set_over_current_protection = stpmic1_set_icc, }; @@ -208,6 +228,7 @@ static const struct regulator_ops stpmic1_switch_regul_ops = { .enable_val = 1, \ .disable_val = 0, \ .enable_time = PMIC_ENABLE_TIME_US, \ + .ramp_delay = PMIC_RAMP_DELAY, \ .supply_name = #base, \ } @@ -227,6 +248,7 @@ static const struct regulator_ops stpmic1_switch_regul_ops = { .enable_val = 1, \ .disable_val = 0, \ .enable_time = PMIC_ENABLE_TIME_US, \ + .ramp_delay = PMIC_RAMP_DELAY, \ .bypass_reg = LDO3_ACTIVE_CR, \ .bypass_mask = LDO_BYPASS_MASK, \ .bypass_val_on = LDO_BYPASS_MASK, \ @@ -248,6 +270,7 @@ static const struct regulator_ops stpmic1_switch_regul_ops = { .enable_val = 1, \ .disable_val = 0, \ .enable_time = PMIC_ENABLE_TIME_US, \ + .ramp_delay = PMIC_RAMP_DELAY, \ .supply_name = #base, \ } @@ -267,6 +290,7 @@ static const struct regulator_ops stpmic1_switch_regul_ops = { .enable_val = 1, \ .disable_val = 0, \ .enable_time = PMIC_ENABLE_TIME_US, \ + .ramp_delay = PMIC_RAMP_DELAY, \ .of_map_mode = stpmic1_map_mode, \ .pull_down_reg = ids##_PULL_DOWN_REG, \ .pull_down_mask = ids##_PULL_DOWN_MASK, \ @@ -511,6 +535,94 @@ static irqreturn_t stpmic1_curlim_irq_handler(int irq, void *data) return IRQ_HANDLED; } +static int regulator_enable_boost(struct regulator_dev *rdev) +{ + struct boost_data *usb_data = rdev_get_drvdata(rdev); + + usb_data->occ_timeout = ktime_add_us(ktime_get(), 100000); + + return regulator_enable_regmap(rdev); +} + +static int regulator_disable_boost(struct regulator_dev *rdev) +{ + struct boost_data *usb_data = rdev_get_drvdata(rdev); + + usb_data->occ_timeout = 0; + + return regulator_disable_regmap(rdev); +} + +static void stpmic1_reset_boost(struct boost_data *usb_data) +{ + int otg_on = 0; + int sw_out_on = 0; + + dev_dbg(rdev_get_dev(usb_data->boost_rdev), "reset usb boost\n"); + + regulator_lock(usb_data->boost_rdev); + + /* the boost was actually disabled by the over-current protection */ + regulator_disable_regmap(usb_data->boost_rdev); + + if (usb_data->vbus_otg_rdev) + otg_on = regulator_is_enabled_regmap(usb_data->vbus_otg_rdev); + if (otg_on) { + regulator_lock(usb_data->vbus_otg_rdev); + regulator_disable_regmap(usb_data->vbus_otg_rdev); + } + + if (usb_data->sw_out_rdev) + sw_out_on = regulator_is_enabled_regmap(usb_data->sw_out_rdev); + if (sw_out_on) { + regulator_lock(usb_data->sw_out_rdev); + regulator_disable_regmap(usb_data->sw_out_rdev); + } + + regulator_enable_regmap(usb_data->boost_rdev); + + /* sleep at least 5ms */ + usleep_range(5000, 10000); + + if (otg_on) { + regulator_enable_regmap(usb_data->vbus_otg_rdev); + regulator_unlock(usb_data->vbus_otg_rdev); + } + + if (sw_out_on) { + regulator_enable_regmap(usb_data->sw_out_rdev); + regulator_unlock(usb_data->sw_out_rdev); + } + + regulator_unlock(usb_data->boost_rdev); +} + +static irqreturn_t stpmic1_boost_irq_handler(int irq, void *data) +{ + struct boost_data *usb_data = (struct boost_data *)data; + + dev_dbg(rdev_get_dev(usb_data->boost_rdev), "usb boost irq handler\n"); + + /* overcurrent detected on boost after timeout */ + if (usb_data->occ_timeout != 0 && + ktime_compare(ktime_get(), usb_data->occ_timeout) > 0) { + /* reset usb boost and usb power switches */ + stpmic1_reset_boost(usb_data); + return IRQ_HANDLED; + } + + regulator_lock(usb_data->boost_rdev); + + /* Send an overcurrent notification */ + regulator_notifier_call_chain(usb_data->boost_rdev, + REGULATOR_EVENT_OVER_CURRENT, + NULL); + + regulator_unlock(usb_data->boost_rdev); + + return IRQ_HANDLED; +} + #define MATCH(_name, _id) \ [STPMIC1_##_id] = { \ .name = #_name, \ @@ -534,9 +646,10 @@ static struct of_regulator_match stpmic1_matches[] = { MATCH(pwr_sw2, SW_OUT), }; -static int stpmic1_regulator_register(struct platform_device *pdev, int id, - struct of_regulator_match *match, - const struct stpmic1_regulator_cfg *cfg) +static struct regulator_dev * +stpmic1_regulator_register(struct platform_device *pdev, int id, + struct of_regulator_match *match, + const struct stpmic1_regulator_cfg *cfg) { struct stpmic1 *pmic_dev = dev_get_drvdata(pdev->dev.parent); struct regulator_dev *rdev; @@ -554,7 +667,7 @@ static int stpmic1_regulator_register(struct platform_device *pdev, int id, if (IS_ERR(rdev)) { dev_err(&pdev->dev, "failed to register %s regulator\n", cfg->desc.name); - return PTR_ERR(rdev); + return rdev; } /* set mask reset */ @@ -566,7 +679,7 @@ static int stpmic1_regulator_register(struct platform_device *pdev, int id, cfg->mask_reset_mask); if (ret) { dev_err(&pdev->dev, "set mask reset failed\n"); - return ret; + return ERR_PTR(ret); } } @@ -580,15 +693,60 @@ static int stpmic1_regulator_register(struct platform_device *pdev, int id, pdev->name, rdev); if (ret) { dev_err(&pdev->dev, "Request IRQ failed\n"); - return ret; + return ERR_PTR(ret); } } - return 0; + + return rdev; +} + +static struct regulator_dev * +stpmic1_boost_register(struct platform_device *pdev, int id, + struct of_regulator_match *match, + const struct stpmic1_regulator_cfg *cfg, + struct boost_data *usb_data) +{ + struct stpmic1 *pmic_dev = dev_get_drvdata(pdev->dev.parent); + struct regulator_dev *rdev; + struct regulator_config config = {}; + int ret = 0; + int irq; + + config.dev = &pdev->dev; + config.init_data = match->init_data; + config.of_node = match->of_node; + config.regmap = pmic_dev->regmap; + config.driver_data = (void *)usb_data; + + rdev = devm_regulator_register(&pdev->dev, &cfg->desc, &config); + if (IS_ERR(rdev)) { + dev_err(&pdev->dev, "failed to register %s regulator\n", + cfg->desc.name); + return rdev; + } + + /* setup an irq handler for over-current detection */ + irq = of_irq_get(config.of_node, 0); + if (irq > 0) { + ret = devm_request_threaded_irq(&pdev->dev, + irq, NULL, + stpmic1_boost_irq_handler, + IRQF_ONESHOT, pdev->name, + usb_data); + if (ret) { + dev_err(&pdev->dev, "Request IRQ failed\n"); + return ERR_PTR(ret); + } + } + + return rdev; } static int stpmic1_regulator_probe(struct platform_device *pdev) { int i, ret; + struct boost_data *usb_data; + struct regulator_dev *rdev; ret = of_regulator_match(&pdev->dev, pdev->dev.of_node, stpmic1_matches, ARRAY_SIZE(stpmic1_matches)); @@ -598,11 +756,30 @@ static int stpmic1_regulator_probe(struct platform_device *pdev) return ret; } + usb_data = devm_kzalloc(&pdev->dev, sizeof(*usb_data), GFP_KERNEL); + if (!usb_data) + return -ENOMEM; + for (i = 0; i < ARRAY_SIZE(stpmic1_regulator_cfgs); i++) { - ret = stpmic1_regulator_register(pdev, i, &stpmic1_matches[i], - &stpmic1_regulator_cfgs[i]); - if (ret < 0) - return ret; + if (i == STPMIC1_BOOST) { + rdev = + stpmic1_boost_register(pdev, i, &stpmic1_matches[i], + &stpmic1_regulator_cfgs[i], + usb_data); + + usb_data->boost_rdev = rdev; + } else { + rdev = + stpmic1_regulator_register(pdev, i, &stpmic1_matches[i], + &stpmic1_regulator_cfgs[i]); + + if (i == STPMIC1_VBUS_OTG) + usb_data->vbus_otg_rdev = rdev; + else if (i == STPMIC1_SW_OUT) + usb_data->sw_out_rdev = rdev; + } + if (IS_ERR(rdev)) + return PTR_ERR(rdev); } dev_dbg(&pdev->dev, "stpmic1_regulator driver probed\n"); diff --git a/drivers/spi/spi-stm32-qspi.c b/drivers/spi/spi-stm32-qspi.c index 4e726929bb4f5..77c1da13a3f05 100644 --- a/drivers/spi/spi-stm32-qspi.c +++ b/drivers/spi/spi-stm32-qspi.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -87,6 +88,7 @@ #define STM32_BUSY_TIMEOUT_US 100000 #define STM32_ABT_TIMEOUT_US 100000 #define STM32_COMP_TIMEOUT_MS 1000 +#define STM32_AUTOSUSPEND_DELAY -1 struct stm32_qspi_flash { struct stm32_qspi *qspi; @@ -431,10 +433,17 @@ static int stm32_qspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op) struct stm32_qspi *qspi = spi_controller_get_devdata(mem->spi->master); int ret; + ret = pm_runtime_get_sync(qspi->dev); + if (ret < 0) + return ret; + mutex_lock(&qspi->lock); ret = stm32_qspi_send(mem, op); mutex_unlock(&qspi->lock); + pm_runtime_mark_last_busy(qspi->dev); + pm_runtime_put_autosuspend(qspi->dev); + return ret; } @@ -444,6 +453,7 @@ static int stm32_qspi_setup(struct spi_device *spi) struct stm32_qspi *qspi = spi_controller_get_devdata(ctrl); struct stm32_qspi_flash *flash; u32 presc; + int ret; if (ctrl->busy) return -EBUSY; @@ -451,6 +461,10 @@ static int stm32_qspi_setup(struct spi_device *spi) if (!spi->max_speed_hz) return -EINVAL; + ret = pm_runtime_get_sync(qspi->dev); + if (ret < 0) + return ret; + presc = DIV_ROUND_UP(qspi->clk_rate, spi->max_speed_hz) - 1; flash = &qspi->flash[spi->chip_select]; @@ -467,13 +481,17 @@ static int stm32_qspi_setup(struct spi_device *spi) writel_relaxed(qspi->dcr_reg, qspi->io_base + QSPI_DCR); mutex_unlock(&qspi->lock); + pm_runtime_mark_last_busy(qspi->dev); + pm_runtime_put_autosuspend(qspi->dev); + return 0; } -static void stm32_qspi_dma_setup(struct stm32_qspi *qspi) +static int stm32_qspi_dma_setup(struct stm32_qspi *qspi) { struct dma_slave_config dma_cfg; struct device *dev = qspi->dev; + int ret = 0; memset(&dma_cfg, 0, sizeof(dma_cfg)); @@ -484,8 +502,13 @@ static void stm32_qspi_dma_setup(struct stm32_qspi *qspi) dma_cfg.src_maxburst = 4; dma_cfg.dst_maxburst = 4; - qspi->dma_chrx = dma_request_slave_channel(dev, "rx"); - if (qspi->dma_chrx) { + qspi->dma_chrx = dma_request_chan(dev, "rx"); + if (IS_ERR(qspi->dma_chrx)) { + ret = PTR_ERR(qspi->dma_chrx); + qspi->dma_chrx = NULL; + if (ret == -EPROBE_DEFER) + goto out; + } else { if (dmaengine_slave_config(qspi->dma_chrx, &dma_cfg)) { dev_err(dev, "dma rx config failed\n"); dma_release_channel(qspi->dma_chrx); @@ -493,8 +516,11 @@ static void stm32_qspi_dma_setup(struct stm32_qspi *qspi) } } - qspi->dma_chtx = dma_request_slave_channel(dev, "tx"); - if (qspi->dma_chtx) { + qspi->dma_chtx = dma_request_chan(dev, "tx"); + if (IS_ERR(qspi->dma_chtx)) { + ret = PTR_ERR(qspi->dma_chtx); + qspi->dma_chtx = NULL; + } else { if (dmaengine_slave_config(qspi->dma_chtx, &dma_cfg)) { dev_err(dev, "dma tx config failed\n"); dma_release_channel(qspi->dma_chtx); @@ -502,7 +528,13 @@ static void stm32_qspi_dma_setup(struct stm32_qspi *qspi) } } +out: init_completion(&qspi->dma_completion); + + if (ret != -EPROBE_DEFER) + ret = 0; + + return ret; } static void stm32_qspi_dma_free(struct stm32_qspi *qspi) @@ -521,15 +553,6 @@ static const struct spi_controller_mem_ops stm32_qspi_mem_ops = { .exec_op = stm32_qspi_exec_op, }; -static void stm32_qspi_release(struct stm32_qspi *qspi) -{ - /* disable qspi */ - writel_relaxed(0, qspi->io_base + QSPI_CR); - stm32_qspi_dma_free(qspi); - mutex_destroy(&qspi->lock); - clk_disable_unprepare(qspi->clk); -} - static int stm32_qspi_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -550,7 +573,7 @@ static int stm32_qspi_probe(struct platform_device *pdev) qspi->io_base = devm_ioremap_resource(dev, res); if (IS_ERR(qspi->io_base)) { ret = PTR_ERR(qspi->io_base); - goto err; + goto err_master_put; } qspi->phys_base = res->start; @@ -559,24 +582,26 @@ static int stm32_qspi_probe(struct platform_device *pdev) qspi->mm_base = devm_ioremap_resource(dev, res); if (IS_ERR(qspi->mm_base)) { ret = PTR_ERR(qspi->mm_base); - goto err; + goto err_master_put; } qspi->mm_size = resource_size(res); if (qspi->mm_size > STM32_QSPI_MAX_MMAP_SZ) { ret = -EINVAL; - goto err; + goto err_master_put; } irq = platform_get_irq(pdev, 0); - if (irq < 0) - return irq; + if (irq < 0) { + ret = irq; + goto err_master_put; + } ret = devm_request_irq(dev, irq, stm32_qspi_irq, 0, dev_name(dev), qspi); if (ret) { dev_err(dev, "failed to request irq\n"); - goto err; + goto err_master_put; } init_completion(&qspi->data_completion); @@ -584,23 +609,27 @@ static int stm32_qspi_probe(struct platform_device *pdev) qspi->clk = devm_clk_get(dev, NULL); if (IS_ERR(qspi->clk)) { ret = PTR_ERR(qspi->clk); - goto err; + goto err_master_put; } qspi->clk_rate = clk_get_rate(qspi->clk); if (!qspi->clk_rate) { ret = -EINVAL; - goto err; + goto err_master_put; } ret = clk_prepare_enable(qspi->clk); if (ret) { dev_err(dev, "can not enable the clock\n"); - goto err; + goto err_master_put; } rstc = devm_reset_control_get_exclusive(dev, NULL); - if (!IS_ERR(rstc)) { + if (IS_ERR(rstc)) { + ret = PTR_ERR(rstc); + if (ret == -EPROBE_DEFER) + goto err_clk_disable; + } else { reset_control_assert(rstc); udelay(2); reset_control_deassert(rstc); @@ -608,7 +637,10 @@ static int stm32_qspi_probe(struct platform_device *pdev) qspi->dev = dev; platform_set_drvdata(pdev, qspi); - stm32_qspi_dma_setup(qspi); + ret = stm32_qspi_dma_setup(qspi); + if (ret) + goto err_dma_free; + mutex_init(&qspi->lock); ctrl->mode_bits = SPI_RX_DUAL | SPI_RX_QUAD @@ -619,12 +651,35 @@ static int stm32_qspi_probe(struct platform_device *pdev) ctrl->num_chipselect = STM32_QSPI_MAX_NORCHIP; ctrl->dev.of_node = dev->of_node; + pm_runtime_set_autosuspend_delay(dev, STM32_AUTOSUSPEND_DELAY); + pm_runtime_use_autosuspend(dev); + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + pm_runtime_get_noresume(dev); + ret = devm_spi_register_master(dev, ctrl); - if (!ret) - return 0; + if (ret) + goto err_pm_runtime_free; + + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); + + return 0; -err: - stm32_qspi_release(qspi); +err_pm_runtime_free: + pm_runtime_get_sync(qspi->dev); + /* disable qspi */ + writel_relaxed(0, qspi->io_base + QSPI_CR); + mutex_destroy(&qspi->lock); + pm_runtime_put_noidle(qspi->dev); + pm_runtime_disable(qspi->dev); + pm_runtime_set_suspended(qspi->dev); + pm_runtime_dont_use_autosuspend(qspi->dev); +err_dma_free: + stm32_qspi_dma_free(qspi); +err_clk_disable: + clk_disable_unprepare(qspi->clk); +err_master_put: spi_master_put(qspi->ctrl); return ret; @@ -634,15 +689,38 @@ static int stm32_qspi_remove(struct platform_device *pdev) { struct stm32_qspi *qspi = platform_get_drvdata(pdev); - stm32_qspi_release(qspi); + pm_runtime_get_sync(qspi->dev); + /* disable qspi */ + writel_relaxed(0, qspi->io_base + QSPI_CR); + stm32_qspi_dma_free(qspi); + mutex_destroy(&qspi->lock); + pm_runtime_put_noidle(qspi->dev); + pm_runtime_disable(qspi->dev); + pm_runtime_set_suspended(qspi->dev); + pm_runtime_dont_use_autosuspend(qspi->dev); + clk_disable_unprepare(qspi->clk); + return 0; } -static int __maybe_unused stm32_qspi_suspend(struct device *dev) +static int __maybe_unused stm32_qspi_runtime_suspend(struct device *dev) { struct stm32_qspi *qspi = dev_get_drvdata(dev); clk_disable_unprepare(qspi->clk); + + return 0; +} + +static int __maybe_unused stm32_qspi_runtime_resume(struct device *dev) +{ + struct stm32_qspi *qspi = dev_get_drvdata(dev); + + return clk_prepare_enable(qspi->clk); +} + +static int __maybe_unused stm32_qspi_suspend(struct device *dev) +{ pinctrl_pm_select_sleep_state(dev); return 0; @@ -651,17 +729,28 @@ static int __maybe_unused stm32_qspi_suspend(struct device *dev) static int __maybe_unused stm32_qspi_resume(struct device *dev) { struct stm32_qspi *qspi = dev_get_drvdata(dev); + int ret; pinctrl_pm_select_default_state(dev); - clk_prepare_enable(qspi->clk); + + ret = pm_runtime_get_sync(qspi->dev); + if (ret < 0) + return ret; writel_relaxed(qspi->cr_reg, qspi->io_base + QSPI_CR); writel_relaxed(qspi->dcr_reg, qspi->io_base + QSPI_DCR); + pm_runtime_mark_last_busy(qspi->dev); + pm_runtime_put_autosuspend(qspi->dev); + return 0; } -static SIMPLE_DEV_PM_OPS(stm32_qspi_pm_ops, stm32_qspi_suspend, stm32_qspi_resume); +static const struct dev_pm_ops stm32_qspi_pm_ops = { + SET_RUNTIME_PM_OPS(stm32_qspi_runtime_suspend, + stm32_qspi_runtime_resume, NULL) + SET_SYSTEM_SLEEP_PM_OPS(stm32_qspi_suspend, stm32_qspi_resume) +}; static const struct of_device_id stm32_qspi_match[] = { {.compatible = "st,stm32f469-qspi"}, diff --git a/drivers/spi/spi-stm32.c b/drivers/spi/spi-stm32.c index b222ce8d083ef..feed9206323be 100644 --- a/drivers/spi/spi-stm32.c +++ b/drivers/spi/spi-stm32.c @@ -5,6 +5,7 @@ // Copyright (C) 2017, STMicroelectronics - All Rights Reserved // Author(s): Amelie Delaunay for STMicroelectronics. +#include #include #include #include @@ -13,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -31,8 +33,8 @@ #define STM32F4_SPI_CR1_CPHA BIT(0) #define STM32F4_SPI_CR1_CPOL BIT(1) #define STM32F4_SPI_CR1_MSTR BIT(2) -#define STM32F4_SPI_CR1_BR_SHIFT 3 #define STM32F4_SPI_CR1_BR GENMASK(5, 3) +#define STM32F4_SPI_CR1_BR_SHIFT 3 #define STM32F4_SPI_CR1_SPE BIT(6) #define STM32F4_SPI_CR1_LSBFRST BIT(7) #define STM32F4_SPI_CR1_SSI BIT(8) @@ -94,27 +96,22 @@ #define STM32H7_SPI_CR1_SSI BIT(12) /* STM32H7_SPI_CR2 bit fields */ -#define STM32H7_SPI_CR2_TSIZE_SHIFT 0 #define STM32H7_SPI_CR2_TSIZE GENMASK(15, 0) +#define STM32H7_SPI_TSIZE_MAX GENMASK(15, 0) /* STM32H7_SPI_CFG1 bit fields */ -#define STM32H7_SPI_CFG1_DSIZE_SHIFT 0 #define STM32H7_SPI_CFG1_DSIZE GENMASK(4, 0) -#define STM32H7_SPI_CFG1_FTHLV_SHIFT 5 #define STM32H7_SPI_CFG1_FTHLV GENMASK(8, 5) #define STM32H7_SPI_CFG1_RXDMAEN BIT(14) #define STM32H7_SPI_CFG1_TXDMAEN BIT(15) -#define STM32H7_SPI_CFG1_MBR_SHIFT 28 #define STM32H7_SPI_CFG1_MBR GENMASK(30, 28) +#define STM32H7_SPI_CFG1_MBR_SHIFT 28 #define STM32H7_SPI_CFG1_MBR_MIN 0 #define STM32H7_SPI_CFG1_MBR_MAX (GENMASK(30, 28) >> 28) /* STM32H7_SPI_CFG2 bit fields */ -#define STM32H7_SPI_CFG2_MIDI_SHIFT 4 #define STM32H7_SPI_CFG2_MIDI GENMASK(7, 4) -#define STM32H7_SPI_CFG2_COMM_SHIFT 17 #define STM32H7_SPI_CFG2_COMM GENMASK(18, 17) -#define STM32H7_SPI_CFG2_SP_SHIFT 19 #define STM32H7_SPI_CFG2_SP GENMASK(21, 19) #define STM32H7_SPI_CFG2_MASTER BIT(22) #define STM32H7_SPI_CFG2_LSBFRST BIT(23) @@ -137,10 +134,10 @@ #define STM32H7_SPI_SR_RXP BIT(0) #define STM32H7_SPI_SR_TXP BIT(1) #define STM32H7_SPI_SR_EOT BIT(3) +#define STM32H7_SPI_SR_TXTF BIT(4) #define STM32H7_SPI_SR_OVR BIT(6) #define STM32H7_SPI_SR_MODF BIT(9) #define STM32H7_SPI_SR_SUSP BIT(11) -#define STM32H7_SPI_SR_RXPLVL_SHIFT 13 #define STM32H7_SPI_SR_RXPLVL GENMASK(14, 13) #define STM32H7_SPI_SR_RXWNE BIT(15) @@ -167,8 +164,6 @@ #define SPI_3WIRE_TX 3 #define SPI_3WIRE_RX 4 -#define SPI_1HZ_NS 1000000000 - /* * use PIO for small transfers, avoiding DMA setup/teardown overhead for drivers * without fifo buffers. @@ -249,7 +244,7 @@ struct stm32_spi_cfg { int (*set_mode)(struct stm32_spi *spi, unsigned int comm_type); void (*set_data_idleness)(struct stm32_spi *spi, u32 length); int (*set_number_of_data)(struct stm32_spi *spi, u32 length); - void (*transfer_one_dma_start)(struct stm32_spi *spi); + int (*transfer_one_dma_start)(struct stm32_spi *spi); void (*dma_rx_cb)(void *data); void (*dma_tx_cb)(void *data); int (*transfer_one_irq)(struct stm32_spi *spi); @@ -268,7 +263,6 @@ struct stm32_spi_cfg { * @base: virtual memory area * @clk: hw kernel clock feeding the SPI clock generator * @clk_rate: rate of the hw kernel clock feeding the SPI clock generator - * @rst: SPI controller reset line * @lock: prevent I/O concurrent access * @irq: SPI controller interrupt line * @fifo_size: size of the embedded fifo in bytes @@ -294,7 +288,6 @@ struct stm32_spi { void __iomem *base; struct clk *clk; u32 clk_rate; - struct reset_control *rst; spinlock_t lock; /* prevent I/O concurrent access */ int irq; unsigned int fifo_size; @@ -313,7 +306,10 @@ struct stm32_spi { int rx_len; struct dma_chan *dma_tx; struct dma_chan *dma_rx; + struct completion dma_completion; dma_addr_t phys_addr; + struct completion xfer_completion; + int xfer_status; }; static const struct stm32_spi_regspec stm32f4_spi_regspec = { @@ -417,9 +413,7 @@ static int stm32h7_spi_get_bpw_mask(struct stm32_spi *spi) stm32_spi_set_bits(spi, STM32H7_SPI_CFG1, STM32H7_SPI_CFG1_DSIZE); cfg1 = readl_relaxed(spi->base + STM32H7_SPI_CFG1); - max_bpw = (cfg1 & STM32H7_SPI_CFG1_DSIZE) >> - STM32H7_SPI_CFG1_DSIZE_SHIFT; - max_bpw += 1; + max_bpw = FIELD_GET(STM32H7_SPI_CFG1_DSIZE, cfg1) + 1; spin_unlock_irqrestore(&spi->lock, flags); @@ -442,7 +436,8 @@ static int stm32_spi_prepare_mbr(struct stm32_spi *spi, u32 speed_hz, { u32 div, mbrdiv; - div = DIV_ROUND_UP(spi->clk_rate, speed_hz); + /* Ensure spi->clk_rate is even */ + div = DIV_ROUND_UP(spi->clk_rate & ~0x1, speed_hz); /* * SPI framework set xfer->speed_hz to master->max_speed_hz if @@ -469,19 +464,22 @@ static int stm32_spi_prepare_mbr(struct stm32_spi *spi, u32 speed_hz, * stm32h7_spi_prepare_fthlv - Determine FIFO threshold level * @spi: pointer to the spi controller data structure */ -static u32 stm32h7_spi_prepare_fthlv(struct stm32_spi *spi) +static u32 stm32h7_spi_prepare_fthlv(struct stm32_spi *spi, u32 xfer_len) { - u32 fthlv, half_fifo; + u32 fthlv, half_fifo, packet; /* data packet should not exceed 1/2 of fifo space */ half_fifo = (spi->fifo_size / 2); + /* data_packet should not exceed transfer length */ + packet = (half_fifo > xfer_len) ? xfer_len : half_fifo; + if (spi->cur_bpw <= 8) - fthlv = half_fifo; + fthlv = packet; else if (spi->cur_bpw <= 16) - fthlv = half_fifo / 2; + fthlv = packet / 2; else - fthlv = half_fifo / 4; + fthlv = packet / 4; /* align packet size with data registers access */ if (spi->cur_bpw > 8) @@ -489,6 +487,9 @@ static u32 stm32h7_spi_prepare_fthlv(struct stm32_spi *spi) else fthlv -= (fthlv % 4); /* multiple of 4 */ + if (!fthlv) + fthlv = 1; + return fthlv; } @@ -592,25 +593,26 @@ static void stm32f4_spi_read_rx(struct stm32_spi *spi) * Write in rx_buf depends on remaining bytes to avoid to write beyond * rx_buf end. */ -static void stm32h7_spi_read_rxfifo(struct stm32_spi *spi, bool flush) +static void stm32h7_spi_read_rxfifo(struct stm32_spi *spi) { u32 sr = readl_relaxed(spi->base + STM32H7_SPI_SR); - u32 rxplvl = (sr & STM32H7_SPI_SR_RXPLVL) >> - STM32H7_SPI_SR_RXPLVL_SHIFT; + u32 rxplvl = FIELD_GET(STM32H7_SPI_SR_RXPLVL, sr); while ((spi->rx_len > 0) && ((sr & STM32H7_SPI_SR_RXP) || - (flush && ((sr & STM32H7_SPI_SR_RXWNE) || (rxplvl > 0))))) { + ((sr & STM32H7_SPI_SR_EOT) && + ((sr & STM32H7_SPI_SR_RXWNE) || (rxplvl > 0))))) { u32 offs = spi->cur_xferlen - spi->rx_len; if ((spi->rx_len >= sizeof(u32)) || - (flush && (sr & STM32H7_SPI_SR_RXWNE))) { + (sr & STM32H7_SPI_SR_RXWNE)) { u32 *rx_buf32 = (u32 *)(spi->rx_buf + offs); *rx_buf32 = readl_relaxed(spi->base + STM32H7_SPI_RXDR); spi->rx_len -= sizeof(u32); } else if ((spi->rx_len >= sizeof(u16)) || - (flush && (rxplvl >= 2 || spi->cur_bpw > 8))) { + (!(sr & STM32H7_SPI_SR_RXWNE) && + (rxplvl >= 2 || spi->cur_bpw > 8))) { u16 *rx_buf16 = (u16 *)(spi->rx_buf + offs); *rx_buf16 = readw_relaxed(spi->base + STM32H7_SPI_RXDR); @@ -623,12 +625,11 @@ static void stm32h7_spi_read_rxfifo(struct stm32_spi *spi, bool flush) } sr = readl_relaxed(spi->base + STM32H7_SPI_SR); - rxplvl = (sr & STM32H7_SPI_SR_RXPLVL) >> - STM32H7_SPI_SR_RXPLVL_SHIFT; + rxplvl = FIELD_GET(STM32H7_SPI_SR_RXPLVL, sr); } - dev_dbg(spi->dev, "%s%s: %d bytes left\n", __func__, - flush ? "(flush)" : "", spi->rx_len); + dev_dbg(spi->dev, "%s: %d bytes left (sr=%08x)\n", + __func__, spi->rx_len, sr); } /** @@ -696,12 +697,7 @@ static void stm32f4_spi_disable(struct stm32_spi *spi) * @spi: pointer to the spi controller data structure * * RX-Fifo is flushed when SPI controller is disabled. To prevent any data - * loss, use stm32h7_spi_read_rxfifo(flush) to read the remaining bytes in - * RX-Fifo. - * Normally, if TSIZE has been configured, we should relax the hardware at the - * reception of the EOT interrupt. But in case of error, EOT will not be - * raised. So the subsystem unprepare_message call allows us to properly - * complete the transfer from an hardware point of view. + * loss, use stm32_spi_read_rxfifo to read the remaining bytes in RX-Fifo. */ static void stm32h7_spi_disable(struct stm32_spi *spi) { @@ -736,7 +732,7 @@ static void stm32h7_spi_disable(struct stm32_spi *spi) } if (!spi->cur_usedma && spi->rx_buf && (spi->rx_len > 0)) - stm32h7_spi_read_rxfifo(spi, true); + stm32h7_spi_read_rxfifo(spi); if (spi->cur_usedma && spi->dma_tx) dmaengine_terminate_all(spi->dma_tx); @@ -891,7 +887,7 @@ static irqreturn_t stm32h7_spi_irq_thread(int irq, void *dev_id) { struct spi_master *master = dev_id; struct stm32_spi *spi = spi_master_get_devdata(master); - u32 sr, ier, mask; + u32 sr, ier, mask, ifcr; unsigned long flags; bool end = false; @@ -899,77 +895,77 @@ static irqreturn_t stm32h7_spi_irq_thread(int irq, void *dev_id) sr = readl_relaxed(spi->base + STM32H7_SPI_SR); ier = readl_relaxed(spi->base + STM32H7_SPI_IER); + ifcr = 0; mask = ier; - /* EOTIE is triggered on EOT, SUSP and TXC events. */ + /* + * EOTIE enables irq from EOT, SUSP and TXC events. We need to set + * SUSP to acknowledge it later. TXC is automatically cleared + */ mask |= STM32H7_SPI_SR_SUSP; /* - * When TXTF is set, DXPIE and TXPIE are cleared. So in case of - * Full-Duplex, need to poll RXP event to know if there are remaining - * data, before disabling SPI. + * DXPIE is set in Full-Duplex, one IT will be raised if TXP and RXP + * are set. So in case of Full-Duplex, need to poll TXP and RXP event. */ - if (spi->rx_buf && !spi->cur_usedma) - mask |= STM32H7_SPI_SR_RXP; + if ((spi->cur_comm == SPI_FULL_DUPLEX) && (!spi->cur_usedma)) + mask |= STM32H7_SPI_SR_TXP | STM32H7_SPI_SR_RXP; - if (!(sr & mask)) { - dev_dbg(spi->dev, "spurious IT (sr=0x%08x, ier=0x%08x)\n", - sr, ier); + mask &= sr; + + if (!mask) { + dev_warn(spi->dev, "spurious IT (sr=0x%08x, ier=0x%08x)\n", + sr, ier); spin_unlock_irqrestore(&spi->lock, flags); return IRQ_NONE; } - if (sr & STM32H7_SPI_SR_SUSP) { - dev_warn(spi->dev, "Communication suspended\n"); + if (mask & STM32H7_SPI_SR_SUSP) { + dev_warn_once(spi->dev, + "System too slow is limiting data throughput\n"); + if (!spi->cur_usedma && (spi->rx_buf && (spi->rx_len > 0))) - stm32h7_spi_read_rxfifo(spi, false); - /* - * If communication is suspended while using DMA, it means - * that something went wrong, so stop the current transfer - */ - if (spi->cur_usedma) - end = true; + stm32h7_spi_read_rxfifo(spi); + + ifcr |= STM32H7_SPI_SR_SUSP; } - if (sr & STM32H7_SPI_SR_MODF) { - dev_warn(spi->dev, "Mode fault: transfer aborted\n"); + if (mask & STM32H7_SPI_SR_OVR) { + dev_err(spi->dev, "Overrun: RX data lost\n"); + spi->xfer_status = -EIO; end = true; + ifcr |= STM32H7_SPI_SR_OVR; } - if (sr & STM32H7_SPI_SR_OVR) { - dev_warn(spi->dev, "Overrun: received value discarded\n"); - if (!spi->cur_usedma && (spi->rx_buf && (spi->rx_len > 0))) - stm32h7_spi_read_rxfifo(spi, false); - /* - * If overrun is detected while using DMA, it means that - * something went wrong, so stop the current transfer - */ - if (spi->cur_usedma) - end = true; - } + if (mask & STM32H7_SPI_SR_TXTF) + ifcr |= STM32H7_SPI_SR_TXTF; - if (sr & STM32H7_SPI_SR_EOT) { + if (mask & STM32H7_SPI_SR_EOT) { if (!spi->cur_usedma && (spi->rx_buf && (spi->rx_len > 0))) - stm32h7_spi_read_rxfifo(spi, true); + stm32h7_spi_read_rxfifo(spi); end = true; + ifcr |= STM32H7_SPI_SR_EOT; } - if (sr & STM32H7_SPI_SR_TXP) + if (mask & STM32H7_SPI_SR_TXP) if (!spi->cur_usedma && (spi->tx_buf && (spi->tx_len > 0))) stm32h7_spi_write_txfifo(spi); - if (sr & STM32H7_SPI_SR_RXP) + if (mask & STM32H7_SPI_SR_RXP) if (!spi->cur_usedma && (spi->rx_buf && (spi->rx_len > 0))) - stm32h7_spi_read_rxfifo(spi, false); - - writel_relaxed(mask, spi->base + STM32H7_SPI_IFCR); - - spin_unlock_irqrestore(&spi->lock, flags); + stm32h7_spi_read_rxfifo(spi); if (end) { - spi_finalize_current_transfer(master); - stm32h7_spi_disable(spi); + /* Disable interrupts and clear status flags */ + writel_relaxed(0, spi->base + STM32H7_SPI_IER); + writel_relaxed(STM32H7_SPI_IFCR_ALL, + spi->base + STM32H7_SPI_IFCR); + + complete(&spi->xfer_completion); + } else { + writel_relaxed(ifcr, spi->base + STM32H7_SPI_IFCR); } + spin_unlock_irqrestore(&spi->lock, flags); return IRQ_HANDLED; } @@ -980,11 +976,8 @@ static int stm32_spi_setup(struct spi_device *spi_dev) { int ret = 0; - if (!gpio_is_valid(spi_dev->cs_gpio)) { - dev_err(&spi_dev->dev, "%d is not a valid gpio\n", - spi_dev->cs_gpio); - return -EINVAL; - } + if (!gpio_is_valid(spi_dev->cs_gpio)) + return 0; dev_dbg(&spi_dev->dev, "%s: set gpio%d output %s\n", __func__, spi_dev->cs_gpio, @@ -1034,6 +1027,20 @@ static int stm32_spi_prepare_msg(struct spi_master *master, spi_dev->mode & SPI_LSB_FIRST, spi_dev->mode & SPI_CS_HIGH); + /* On STM32H7, messages should not exceed a maximum size setted + * afterward via the set_number_of_data function. In order to + * ensure that, split large messages into several messages + */ + if (spi->cfg->set_number_of_data) { + int ret; + + ret = spi_split_transfers_maxsize(master, msg, + STM32H7_SPI_TSIZE_MAX, + GFP_KERNEL | GFP_DMA); + if (ret) + return ret; + } + spin_lock_irqsave(&spi->lock, flags); /* CPOL, CPHA and LSB FIRST bits have common register */ @@ -1079,25 +1086,18 @@ static void stm32f4_spi_dma_rx_cb(void *data) /** * stm32h7_spi_dma_cb - dma callback * - * DMA callback is called when the transfer is complete or when an error - * occurs. If the transfer is complete, EOT flag is raised. + * DMA callback is called when the transfer is complete. */ static void stm32h7_spi_dma_cb(void *data) { struct stm32_spi *spi = data; unsigned long flags; - u32 sr; spin_lock_irqsave(&spi->lock, flags); - sr = readl_relaxed(spi->base + STM32H7_SPI_SR); + complete(&spi->dma_completion); spin_unlock_irqrestore(&spi->lock, flags); - - if (!(sr & STM32H7_SPI_SR_EOT)) - dev_warn(spi->dev, "DMA error (sr=0x%08x)\n", sr); - - /* Now wait for EOT, or SUSP or OVR in case of error */ } /** @@ -1190,9 +1190,6 @@ static int stm32f4_spi_transfer_one_irq(struct stm32_spi *spi) /** * stm32h7_spi_transfer_one_irq - transfer a single spi_transfer using * interrupts - * - * It must returns 0 if the transfer is finished or 1 if the transfer is still - * in progress. */ static int stm32h7_spi_transfer_one_irq(struct stm32_spi *spi) { @@ -1209,7 +1206,7 @@ static int stm32h7_spi_transfer_one_irq(struct stm32_spi *spi) /* Enable the interrupts relative to the end of transfer */ ier |= STM32H7_SPI_IER_EOTIE | STM32H7_SPI_IER_TXTFIE | - STM32H7_SPI_IER_OVRIE | STM32H7_SPI_IER_MODFIE; + STM32H7_SPI_IER_OVRIE; spin_lock_irqsave(&spi->lock, flags); @@ -1225,15 +1222,19 @@ static int stm32h7_spi_transfer_one_irq(struct stm32_spi *spi) spin_unlock_irqrestore(&spi->lock, flags); - return 1; + return 0; } /** * stm32f4_spi_transfer_one_dma_start - Set SPI driver registers to start * transfer using DMA */ -static void stm32f4_spi_transfer_one_dma_start(struct stm32_spi *spi) +static int stm32f4_spi_transfer_one_dma_start(struct stm32_spi *spi) { + unsigned long flags; + + spin_lock_irqsave(&spi->lock, flags); + /* In DMA mode end of transfer is handled by DMA TX or RX callback. */ if (spi->cur_comm == SPI_SIMPLEX_RX || spi->cur_comm == SPI_3WIRE_RX || spi->cur_comm == SPI_FULL_DUPLEX) { @@ -1246,40 +1247,56 @@ static void stm32f4_spi_transfer_one_dma_start(struct stm32_spi *spi) } stm32_spi_enable(spi); + + spin_unlock_irqrestore(&spi->lock, flags); + + return 1; } /** * stm32h7_spi_transfer_one_dma_start - Set SPI driver registers to start * transfer using DMA */ -static void stm32h7_spi_transfer_one_dma_start(struct stm32_spi *spi) +static int stm32h7_spi_transfer_one_dma_start(struct stm32_spi *spi) { + unsigned long flags; + + spin_lock_irqsave(&spi->lock, flags); + /* Enable the interrupts relative to the end of transfer */ stm32_spi_set_bits(spi, STM32H7_SPI_IER, STM32H7_SPI_IER_EOTIE | STM32H7_SPI_IER_TXTFIE | - STM32H7_SPI_IER_OVRIE | - STM32H7_SPI_IER_MODFIE); + STM32H7_SPI_IER_OVRIE); stm32_spi_enable(spi); stm32_spi_set_bits(spi, STM32H7_SPI_CR1, STM32H7_SPI_CR1_CSTART); + + spin_unlock_irqrestore(&spi->lock, flags); + + return 0; } /** * stm32_spi_transfer_one_dma - transfer a single spi_transfer using DMA - * - * It must returns 0 if the transfer is finished or 1 if the transfer is still - * in progress. */ static int stm32_spi_transfer_one_dma(struct stm32_spi *spi, struct spi_transfer *xfer) { + dma_async_tx_callback rx_done = NULL, tx_done = NULL; struct dma_slave_config tx_dma_conf, rx_dma_conf; struct dma_async_tx_descriptor *tx_dma_desc, *rx_dma_desc; unsigned long flags; spin_lock_irqsave(&spi->lock, flags); + if (spi->rx_buf) + rx_done = spi->cfg->dma_rx_cb; + else if (spi->tx_buf) + tx_done = spi->cfg->dma_tx_cb; + + reinit_completion(&spi->dma_completion); + rx_dma_desc = NULL; if (spi->rx_buf && spi->dma_rx) { stm32_spi_dma_config(spi, &rx_dma_conf, DMA_DEV_TO_MEM); @@ -1316,7 +1333,7 @@ static int stm32_spi_transfer_one_dma(struct stm32_spi *spi, goto dma_desc_error; if (rx_dma_desc) { - rx_dma_desc->callback = spi->cfg->dma_rx_cb; + rx_dma_desc->callback = rx_done; rx_dma_desc->callback_param = spi; if (dma_submit_error(dmaengine_submit(rx_dma_desc))) { @@ -1330,7 +1347,7 @@ static int stm32_spi_transfer_one_dma(struct stm32_spi *spi, if (tx_dma_desc) { if (spi->cur_comm == SPI_SIMPLEX_TX || spi->cur_comm == SPI_3WIRE_TX) { - tx_dma_desc->callback = spi->cfg->dma_tx_cb; + tx_dma_desc->callback = tx_done; tx_dma_desc->callback_param = spi; } @@ -1345,12 +1362,9 @@ static int stm32_spi_transfer_one_dma(struct stm32_spi *spi, stm32_spi_set_bits(spi, spi->cfg->regs->dma_tx_en.reg, spi->cfg->regs->dma_tx_en.mask); } - - spi->cfg->transfer_one_dma_start(spi); - spin_unlock_irqrestore(&spi->lock, flags); - return 1; + return spi->cfg->transfer_one_dma_start(spi); dma_submit_error: if (spi->dma_rx) @@ -1392,15 +1406,13 @@ static void stm32h7_spi_set_bpw(struct stm32_spi *spi) bpw = spi->cur_bpw - 1; cfg1_clrb |= STM32H7_SPI_CFG1_DSIZE; - cfg1_setb |= (bpw << STM32H7_SPI_CFG1_DSIZE_SHIFT) & - STM32H7_SPI_CFG1_DSIZE; + cfg1_setb |= FIELD_PREP(STM32H7_SPI_CFG1_DSIZE, bpw); - spi->cur_fthlv = stm32h7_spi_prepare_fthlv(spi); + spi->cur_fthlv = stm32h7_spi_prepare_fthlv(spi, spi->cur_xferlen); fthlv = spi->cur_fthlv - 1; cfg1_clrb |= STM32H7_SPI_CFG1_FTHLV; - cfg1_setb |= (fthlv << STM32H7_SPI_CFG1_FTHLV_SHIFT) & - STM32H7_SPI_CFG1_FTHLV; + cfg1_setb |= FIELD_PREP(STM32H7_SPI_CFG1_FTHLV, fthlv); writel_relaxed( (readl_relaxed(spi->base + STM32H7_SPI_CFG1) & @@ -1418,8 +1430,7 @@ static void stm32_spi_set_mbr(struct stm32_spi *spi, u32 mbrdiv) u32 clrb = 0, setb = 0; clrb |= spi->cfg->regs->br.mask; - setb |= ((u32)mbrdiv << spi->cfg->regs->br.shift) & - spi->cfg->regs->br.mask; + setb |= (mbrdiv << spi->cfg->regs->br.shift) & spi->cfg->regs->br.mask; writel_relaxed((readl_relaxed(spi->base + spi->cfg->regs->br.reg) & ~clrb) | setb, @@ -1504,8 +1515,7 @@ static int stm32h7_spi_set_mode(struct stm32_spi *spi, unsigned int comm_type) } cfg2_clrb |= STM32H7_SPI_CFG2_COMM; - cfg2_setb |= (mode << STM32H7_SPI_CFG2_COMM_SHIFT) & - STM32H7_SPI_CFG2_COMM; + cfg2_setb |= FIELD_PREP(STM32H7_SPI_CFG2_COMM, mode); writel_relaxed( (readl_relaxed(spi->base + STM32H7_SPI_CFG2) & @@ -1527,15 +1537,15 @@ static void stm32h7_spi_data_idleness(struct stm32_spi *spi, u32 len) cfg2_clrb |= STM32H7_SPI_CFG2_MIDI; if ((len > 1) && (spi->cur_midi > 0)) { - u32 sck_period_ns = DIV_ROUND_UP(SPI_1HZ_NS, spi->cur_speed); - u32 midi = min((u32)DIV_ROUND_UP(spi->cur_midi, sck_period_ns), - (u32)STM32H7_SPI_CFG2_MIDI >> - STM32H7_SPI_CFG2_MIDI_SHIFT); + u32 sck_period_ns = DIV_ROUND_UP(NSEC_PER_SEC, spi->cur_speed); + u32 midi = min_t(u32, + DIV_ROUND_UP(spi->cur_midi, sck_period_ns), + FIELD_GET(STM32H7_SPI_CFG2_MIDI, + STM32H7_SPI_CFG2_MIDI)); dev_dbg(spi->dev, "period=%dns, midi=%d(=%dns)\n", sck_period_ns, midi, midi * sck_period_ns); - cfg2_setb |= (midi << STM32H7_SPI_CFG2_MIDI_SHIFT) & - STM32H7_SPI_CFG2_MIDI; + cfg2_setb |= FIELD_PREP(STM32H7_SPI_CFG2_MIDI, midi); } writel_relaxed((readl_relaxed(spi->base + STM32H7_SPI_CFG2) & @@ -1550,14 +1560,8 @@ static void stm32h7_spi_data_idleness(struct stm32_spi *spi, u32 len) */ static int stm32h7_spi_number_of_data(struct stm32_spi *spi, u32 nb_words) { - u32 cr2_clrb = 0, cr2_setb = 0; - - if (nb_words <= (STM32H7_SPI_CR2_TSIZE >> - STM32H7_SPI_CR2_TSIZE_SHIFT)) { - cr2_clrb |= STM32H7_SPI_CR2_TSIZE; - cr2_setb = nb_words << STM32H7_SPI_CR2_TSIZE_SHIFT; - writel_relaxed((readl_relaxed(spi->base + STM32H7_SPI_CR2) & - ~cr2_clrb) | cr2_setb, + if (nb_words <= STM32H7_SPI_TSIZE_MAX) { + writel_relaxed(FIELD_PREP(STM32H7_SPI_CR2_TSIZE, nb_words), spi->base + STM32H7_SPI_CR2); } else { return -EMSGSIZE; @@ -1578,39 +1582,33 @@ static int stm32_spi_transfer_one_setup(struct stm32_spi *spi, unsigned long flags; unsigned int comm_type; int nb_words, ret = 0; + int mbr; spin_lock_irqsave(&spi->lock, flags); - if (spi->cur_bpw != transfer->bits_per_word) { - spi->cur_bpw = transfer->bits_per_word; - spi->cfg->set_bpw(spi); - } + spi->cur_xferlen = transfer->len; - if (spi->cur_speed != transfer->speed_hz) { - int mbr; + spi->cur_bpw = transfer->bits_per_word; + spi->cfg->set_bpw(spi); - /* Update spi->cur_speed with real clock speed */ - mbr = stm32_spi_prepare_mbr(spi, transfer->speed_hz, - spi->cfg->baud_rate_div_min, - spi->cfg->baud_rate_div_max); - if (mbr < 0) { - ret = mbr; - goto out; - } - - transfer->speed_hz = spi->cur_speed; - stm32_spi_set_mbr(spi, mbr); + /* Update spi->cur_speed with real clock speed */ + mbr = stm32_spi_prepare_mbr(spi, transfer->speed_hz, + spi->cfg->baud_rate_div_min, + spi->cfg->baud_rate_div_max); + if (mbr < 0) { + ret = mbr; + goto out; } - comm_type = stm32_spi_communication_type(spi_dev, transfer); - if (spi->cur_comm != comm_type) { - ret = spi->cfg->set_mode(spi, comm_type); + transfer->speed_hz = spi->cur_speed; + stm32_spi_set_mbr(spi, mbr); - if (ret < 0) - goto out; + comm_type = stm32_spi_communication_type(spi_dev, transfer); + ret = spi->cfg->set_mode(spi, comm_type); + if (ret < 0) + goto out; - spi->cur_comm = comm_type; - } + spi->cur_comm = comm_type; if (spi->cfg->set_data_idleness) spi->cfg->set_data_idleness(spi, transfer->len); @@ -1628,8 +1626,6 @@ static int stm32_spi_transfer_one_setup(struct stm32_spi *spi, goto out; } - spi->cur_xferlen = transfer->len; - dev_dbg(spi->dev, "transfer communication mode set to %d\n", spi->cur_comm); dev_dbg(spi->dev, @@ -1658,8 +1654,16 @@ static int stm32_spi_transfer_one(struct spi_master *master, struct spi_transfer *transfer) { struct stm32_spi *spi = spi_master_get_devdata(master); + u32 xfer_time, midi_delay_ns; + unsigned long timeout; int ret; + /* Don't do anything on 0 bytes transfers */ + if (transfer->len == 0) { + spi->xfer_status = 0; + goto finalize; + } + spi->tx_buf = transfer->tx_buf; spi->rx_buf = transfer->rx_buf; spi->tx_len = spi->tx_buf ? transfer->len : 0; @@ -1674,10 +1678,40 @@ static int stm32_spi_transfer_one(struct spi_master *master, return ret; } + reinit_completion(&spi->xfer_completion); + spi->xfer_status = 0; + if (spi->cur_usedma) - return stm32_spi_transfer_one_dma(spi, transfer); + ret = stm32_spi_transfer_one_dma(spi, transfer); else - return spi->cfg->transfer_one_irq(spi); + ret = spi->cfg->transfer_one_irq(spi); + + if (ret) + return ret; + + /* Wait for transfer to complete */ + xfer_time = spi->cur_xferlen * 8 * MSEC_PER_SEC / spi->cur_speed; + midi_delay_ns = spi->cur_xferlen * 8 / spi->cur_bpw * spi->cur_midi; + xfer_time += DIV_ROUND_UP(midi_delay_ns, NSEC_PER_MSEC); + xfer_time = max(2 * xfer_time, 100U); + timeout = msecs_to_jiffies(xfer_time); + + timeout = wait_for_completion_timeout(&spi->xfer_completion, timeout); + if (timeout && spi->cur_usedma) + timeout = wait_for_completion_timeout(&spi->dma_completion, + timeout); + + if (!timeout) { + dev_err(spi->dev, "SPI transfer timeout (%u ms)\n", xfer_time); + spi->xfer_status = -ETIMEDOUT; + } + + spi->cfg->disable(spi); + +finalize: + spi_finalize_current_transfer(master); + + return spi->xfer_status; } /** @@ -1810,7 +1844,8 @@ static int stm32_spi_probe(struct platform_device *pdev) struct spi_master *master; struct stm32_spi *spi; struct resource *res; - int i, ret; + struct reset_control *rst; + int i, ret, num_cs, cs_gpio; master = spi_alloc_master(&pdev->dev, sizeof(struct stm32_spi)); if (!master) { @@ -1823,6 +1858,8 @@ static int stm32_spi_probe(struct platform_device *pdev) spi->dev = &pdev->dev; spi->master = master; spin_lock_init(&spi->lock); + init_completion(&spi->xfer_completion); + init_completion(&spi->dma_completion); spi->cfg = (const struct stm32_spi_cfg *) of_match_device(pdev->dev.driver->of_match_table, @@ -1873,11 +1910,20 @@ static int stm32_spi_probe(struct platform_device *pdev) goto err_clk_disable; } - spi->rst = devm_reset_control_get_exclusive(&pdev->dev, NULL); - if (!IS_ERR(spi->rst)) { - reset_control_assert(spi->rst); + rst = devm_reset_control_get_optional_exclusive(&pdev->dev, NULL); + if (rst) { + if (IS_ERR(rst)) { + ret = PTR_ERR(rst); + if (ret != -EPROBE_DEFER) + dev_err(&pdev->dev, "reset get failed: %d\n", + ret); + + goto err_clk_disable; + } + + reset_control_assert(rst); udelay(2); - reset_control_deassert(spi->rst); + reset_control_deassert(rst); } if (spi->cfg->has_fifo) @@ -1903,17 +1949,29 @@ static int stm32_spi_probe(struct platform_device *pdev) master->transfer_one = stm32_spi_transfer_one; master->unprepare_message = stm32_spi_unprepare_msg; - spi->dma_tx = dma_request_slave_channel(spi->dev, "tx"); - if (!spi->dma_tx) - dev_warn(&pdev->dev, "failed to request tx dma channel\n"); - else - master->dma_tx = spi->dma_tx; + spi->dma_tx = dma_request_chan(spi->dev, "tx"); + if (IS_ERR(spi->dma_tx)) { + ret = PTR_ERR(spi->dma_tx); + spi->dma_tx = NULL; + if (ret == -EPROBE_DEFER) + goto err_dma_release; + else if (ret != -ENODEV) + dev_warn(&pdev->dev, "failed to request tx dma: %d\n", + ret); + } + master->dma_tx = spi->dma_tx; - spi->dma_rx = dma_request_slave_channel(spi->dev, "rx"); - if (!spi->dma_rx) - dev_warn(&pdev->dev, "failed to request rx dma channel\n"); - else - master->dma_rx = spi->dma_rx; + spi->dma_rx = dma_request_chan(spi->dev, "rx"); + if (IS_ERR(spi->dma_rx)) { + ret = PTR_ERR(spi->dma_rx); + spi->dma_rx = NULL; + if (ret == -EPROBE_DEFER) + goto err_dma_release; + else if (ret != -ENODEV) + dev_warn(&pdev->dev, "failed to request rx dma: %d\n", + ret); + } + master->dma_rx = spi->dma_rx; if (spi->dma_tx || spi->dma_rx) master->can_dma = stm32_spi_can_dma; @@ -1921,36 +1979,33 @@ static int stm32_spi_probe(struct platform_device *pdev) pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); - ret = devm_spi_register_master(&pdev->dev, master); - if (ret) { - dev_err(&pdev->dev, "spi master registration failed: %d\n", - ret); - goto err_dma_release; - } + num_cs = of_gpio_named_count(pdev->dev.of_node, "cs-gpios"); - if (!master->cs_gpios) { - dev_err(&pdev->dev, "no CS gpios available\n"); - ret = -EINVAL; - goto err_dma_release; - } - - for (i = 0; i < master->num_chipselect; i++) { - if (!gpio_is_valid(master->cs_gpios[i])) { - dev_err(&pdev->dev, "%i is not a valid gpio\n", - master->cs_gpios[i]); - ret = -EINVAL; + for (i = 0; i < num_cs; i++) { + cs_gpio = of_get_named_gpio(pdev->dev.of_node, "cs-gpios", i); + if (cs_gpio == -EPROBE_DEFER) { + ret = -EPROBE_DEFER; goto err_dma_release; } - ret = devm_gpio_request(&pdev->dev, master->cs_gpios[i], - DRIVER_NAME); - if (ret) { - dev_err(&pdev->dev, "can't get CS gpio %i\n", - master->cs_gpios[i]); - goto err_dma_release; + if (gpio_is_valid(cs_gpio)) { + ret = devm_gpio_request(&pdev->dev, cs_gpio, + DRIVER_NAME); + if (ret) { + dev_err(&pdev->dev, "can't get CS gpio %i\n", + cs_gpio); + goto err_dma_release; + } } } + ret = spi_register_master(master); + if (ret) { + dev_err(&pdev->dev, "spi master registration failed: %d\n", + ret); + goto err_dma_release; + } + dev_info(&pdev->dev, "driver initialized\n"); return 0; @@ -1975,6 +2030,9 @@ static int stm32_spi_remove(struct platform_device *pdev) struct spi_master *master = platform_get_drvdata(pdev); struct stm32_spi *spi = spi_master_get_devdata(master); + pm_runtime_get_sync(&pdev->dev); + + spi_unregister_master(master); spi->cfg->disable(spi); if (master->dma_tx) @@ -1984,7 +2042,12 @@ static int stm32_spi_remove(struct platform_device *pdev) clk_disable_unprepare(spi->clk); + pm_runtime_put_noidle(&pdev->dev); pm_runtime_disable(&pdev->dev); + pm_runtime_set_suspended(&pdev->dev); + pm_runtime_dont_use_autosuspend(&pdev->dev); + + pinctrl_pm_select_sleep_state(&pdev->dev); return 0; } @@ -1997,13 +2060,18 @@ static int stm32_spi_runtime_suspend(struct device *dev) clk_disable_unprepare(spi->clk); - return 0; + return pinctrl_pm_select_sleep_state(dev); } static int stm32_spi_runtime_resume(struct device *dev) { struct spi_master *master = dev_get_drvdata(dev); struct stm32_spi *spi = spi_master_get_devdata(master); + int ret; + + ret = pinctrl_pm_select_default_state(dev); + if (ret) + return ret; return clk_prepare_enable(spi->clk); } @@ -2033,10 +2101,23 @@ static int stm32_spi_resume(struct device *dev) return ret; ret = spi_master_resume(master); - if (ret) + if (ret) { clk_disable_unprepare(spi->clk); + return ret; + } - return ret; + ret = pm_runtime_get_sync(dev); + if (ret) { + dev_err(dev, "Unable to power device:%d\n", ret); + return ret; + } + + spi->cfg->config(spi); + + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); + + return 0; } #endif diff --git a/include/dt-bindings/pinctrl/stm32-pinfunc.h b/include/dt-bindings/pinctrl/stm32-pinfunc.h index e6fb8ada3f4d3..370a25a9366cc 100644 --- a/include/dt-bindings/pinctrl/stm32-pinfunc.h +++ b/include/dt-bindings/pinctrl/stm32-pinfunc.h @@ -26,6 +26,7 @@ #define AF14 0xf #define AF15 0x10 #define ANALOG 0x11 +#define RSVD 0x12 /* define Pins number*/ #define PIN_NO(port, line) (((port) - 'A') * 0x10 + (line)) -- 2.17.1