2018-01-12 12:19:25

by Patrice CHOTARD

[permalink] [raw]
Subject: [PATCH 00/14] Add MMCI support for STM32F SoCs family

From: Patrice Chotard <[email protected]>

This series reworks patches submitted one year ago by Andrea Merello [1]
but without succeed to merged it.

STM32F4 and STM32F7 SoCs families embeds a variant of the ARM PrimeCell
PL18x SD host controller, for which the mmci driver exists.
This series adds support for these SoCs to the mmci driver.

As other variants, this one need some specific quirks, that this
series address.

This series has been tested on following boards :
_ stm32f429-eval
_ stm32f469-disco
_ stm32f746-eval
_ stm32f769-disco

DT update for stm32f7 pinctrl, stm32f746-eval and stm32f769-disco boards
will be sent later to avoid conflict with pending stm32f7 series [1] which
is not yet merged on kernel mainline.

[1] https://www.spinics.net/lists/linux-mmc/msg41616.html
[2] https://patchwork.kernel.org/patch/10104447/


Andrea Merello (2):
ARM: dts: stm32: Add pin map for SDIO controller on stm32f4
ARM: dts: stm32: Enable SDIO controller on stm32f469 disco board

Patrice Chotard (12):
mmc: mmci: Don't pretend all variants to have MMCIMASK1 register
mmc: mmci: Don't pretend all variants to have MCI_STARBITERR flag
mmc: mmci: Add support for setting pad type via pinctrl
mmc: mmci: Add STM32 variant
ARM: dts: stm32: Add SDIO controller for stm32f746
ARM: dts: stm32: Add SDIO controller for stm32f429
ARM: dts: stm32: Enable SDIO controller on stm32429i-eval board
ARM: stm32: Add AMBA support for STM32F4 and STM32F7 SoCs
ARM: configs: stm32: Enable MMC_ARMMMCI support
ARM: configs: stm32: Enable EXT3_FS support
clk: stm32: Add clk entry for SDMMC2 on stm32F769
gpio: stmpe: i2c transfer are forbiden in atomic context

arch/arm/boot/dts/stm32429i-eval.dts | 19 ++++++
arch/arm/boot/dts/stm32f4-pinctrl.dtsi | 31 +++++++++
arch/arm/boot/dts/stm32f429.dtsi | 11 +++
arch/arm/boot/dts/stm32f469-disco.dts | 19 ++++++
arch/arm/boot/dts/stm32f746.dtsi | 22 ++++++
arch/arm/configs/stm32_defconfig | 3 +
arch/arm/mach-stm32/Kconfig | 3 +
drivers/clk/clk-stm32f4.c | 3 +-
drivers/gpio/gpio-stmpe.c | 20 +++---
drivers/mmc/host/mmci.c | 120 ++++++++++++++++++++++++++++-----
drivers/mmc/host/mmci.h | 6 ++
11 files changed, 231 insertions(+), 26 deletions(-)

--
1.9.1


2018-01-12 12:17:19

by Patrice CHOTARD

[permalink] [raw]
Subject: [PATCH 02/14] mmc: mmci: Don't pretend all variants to have MCI_STARBITERR flag

From: Patrice Chotard <[email protected]>

This patch prepares for supporting the STM32 variant that
has no such bit in the status register.

Signed-off-by: Andrea Merello <[email protected]>
Signed-off-by: Patrice Chotard <[email protected]>
---
drivers/mmc/host/mmci.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 3125dc0..7e56f85 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -83,6 +83,8 @@
* @qcom_dml: enables qcom specific dma glue for dma transfers.
* @reversed_irq_handling: handle data irq before cmd irq.
* @mmcimask1: true if variant have a MMCIMASK1 register.
+ * @start_err: true is the variant has STARTBITERR bit inside MMCISTATUS
+ * register.
*/
struct variant_data {
unsigned int clkreg;
@@ -113,6 +115,7 @@ struct variant_data {
bool qcom_dml;
bool reversed_irq_handling;
bool mmcimask1;
+ bool start_err;
};

static struct variant_data variant_arm = {
@@ -123,6 +126,7 @@ struct variant_data {
.f_max = 100000000,
.reversed_irq_handling = true,
.mmcimask1 = true,
+ .start_err = true,
};

static struct variant_data variant_arm_extended_fifo = {
@@ -132,6 +136,7 @@ struct variant_data {
.pwrreg_powerup = MCI_PWR_UP,
.f_max = 100000000,
.mmcimask1 = true,
+ .start_err = true,
};

static struct variant_data variant_arm_extended_fifo_hwfc = {
@@ -142,6 +147,7 @@ struct variant_data {
.pwrreg_powerup = MCI_PWR_UP,
.f_max = 100000000,
.mmcimask1 = true,
+ .start_err = true,
};

static struct variant_data variant_u300 = {
@@ -158,6 +164,7 @@ struct variant_data {
.pwrreg_clkgate = true,
.pwrreg_nopower = true,
.mmcimask1 = true,
+ .start_err = true,
};

static struct variant_data variant_nomadik = {
@@ -175,6 +182,7 @@ struct variant_data {
.pwrreg_clkgate = true,
.pwrreg_nopower = true,
.mmcimask1 = true,
+ .start_err = true,
};

static struct variant_data variant_ux500 = {
@@ -198,6 +206,7 @@ struct variant_data {
.busy_detect_mask = MCI_ST_BUSYENDMASK,
.pwrreg_nopower = true,
.mmcimask1 = true,
+ .start_err = true,
};

static struct variant_data variant_ux500v2 = {
@@ -223,6 +232,7 @@ struct variant_data {
.busy_detect_mask = MCI_ST_BUSYENDMASK,
.pwrreg_nopower = true,
.mmcimask1 = true,
+ .start_err = true,
};

static struct variant_data variant_qcom = {
@@ -242,6 +252,7 @@ struct variant_data {
.qcom_fifo = true,
.qcom_dml = true,
.mmcimask1 = true,
+ .start_err = true,
};

/* Busy detection for the ST Micro variant */
@@ -935,8 +946,9 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
return;

/* First check for errors */
- if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_STARTBITERR|
- MCI_TXUNDERRUN|MCI_RXOVERRUN)) {
+ if (status & (MCI_DATACRCFAIL | MCI_DATATIMEOUT |
+ (host->variant->start_err ? MCI_STARTBITERR : 0) |
+ MCI_TXUNDERRUN | MCI_RXOVERRUN)) {
u32 remain, success;

/* Terminate the DMA transfer */
--
1.9.1

2018-01-12 12:17:22

by Patrice CHOTARD

[permalink] [raw]
Subject: [PATCH 01/14] mmc: mmci: Don't pretend all variants to have MMCIMASK1 register

From: Patrice Chotard <[email protected]>

Two mask registers are used in order to select which events have to
actually generate an interrupt on each IRQ line.

It seems that in the single-IRQ case it's assumed that the IRQs lines
are simply OR-ed, while the two mask registers are still present. The
driver still programs the two mask registers separately.

However the STM32 variant has only one IRQ, and also has only one mask
register.

This patch prepares for STM32 variant support by making the driver using
only one mask register.

This patch also optimize the MMCIMASK1 mask usage by caching it into
host->mask1_reg which avoid to read it into mmci_irq().

Tested only on STM32 variant. RFT for variants other than STM32

Signed-off-by: Andrea Merello <[email protected]>
Signed-off-by: Patrice Chotard <[email protected]>
---
drivers/mmc/host/mmci.c | 28 ++++++++++++++++++++++++----
drivers/mmc/host/mmci.h | 1 +
2 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 97da0fc..3125dc0 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -82,6 +82,7 @@
* @qcom_fifo: enables qcom specific fifo pio read logic.
* @qcom_dml: enables qcom specific dma glue for dma transfers.
* @reversed_irq_handling: handle data irq before cmd irq.
+ * @mmcimask1: true if variant have a MMCIMASK1 register.
*/
struct variant_data {
unsigned int clkreg;
@@ -111,6 +112,7 @@ struct variant_data {
bool qcom_fifo;
bool qcom_dml;
bool reversed_irq_handling;
+ bool mmcimask1;
};

static struct variant_data variant_arm = {
@@ -120,6 +122,7 @@ struct variant_data {
.pwrreg_powerup = MCI_PWR_UP,
.f_max = 100000000,
.reversed_irq_handling = true,
+ .mmcimask1 = true,
};

static struct variant_data variant_arm_extended_fifo = {
@@ -128,6 +131,7 @@ struct variant_data {
.datalength_bits = 16,
.pwrreg_powerup = MCI_PWR_UP,
.f_max = 100000000,
+ .mmcimask1 = true,
};

static struct variant_data variant_arm_extended_fifo_hwfc = {
@@ -137,6 +141,7 @@ struct variant_data {
.datalength_bits = 16,
.pwrreg_powerup = MCI_PWR_UP,
.f_max = 100000000,
+ .mmcimask1 = true,
};

static struct variant_data variant_u300 = {
@@ -152,6 +157,7 @@ struct variant_data {
.signal_direction = true,
.pwrreg_clkgate = true,
.pwrreg_nopower = true,
+ .mmcimask1 = true,
};

static struct variant_data variant_nomadik = {
@@ -168,6 +174,7 @@ struct variant_data {
.signal_direction = true,
.pwrreg_clkgate = true,
.pwrreg_nopower = true,
+ .mmcimask1 = true,
};

static struct variant_data variant_ux500 = {
@@ -190,6 +197,7 @@ struct variant_data {
.busy_detect_flag = MCI_ST_CARDBUSY,
.busy_detect_mask = MCI_ST_BUSYENDMASK,
.pwrreg_nopower = true,
+ .mmcimask1 = true,
};

static struct variant_data variant_ux500v2 = {
@@ -214,6 +222,7 @@ struct variant_data {
.busy_detect_flag = MCI_ST_CARDBUSY,
.busy_detect_mask = MCI_ST_BUSYENDMASK,
.pwrreg_nopower = true,
+ .mmcimask1 = true,
};

static struct variant_data variant_qcom = {
@@ -232,6 +241,7 @@ struct variant_data {
.explicit_mclk_control = true,
.qcom_fifo = true,
.qcom_dml = true,
+ .mmcimask1 = true,
};

/* Busy detection for the ST Micro variant */
@@ -396,6 +406,7 @@ static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired)
static void mmci_set_mask1(struct mmci_host *host, unsigned int mask)
{
void __iomem *base = host->base;
+ struct variant_data *variant = host->variant;

if (host->singleirq) {
unsigned int mask0 = readl(base + MMCIMASK0);
@@ -406,7 +417,10 @@ static void mmci_set_mask1(struct mmci_host *host, unsigned int mask)
writel(mask0, base + MMCIMASK0);
}

- writel(mask, base + MMCIMASK1);
+ if (variant->mmcimask1)
+ writel(mask, base + MMCIMASK1);
+
+ host->mask1_reg = mask;
}

static void mmci_stop_data(struct mmci_host *host)
@@ -1286,7 +1300,7 @@ static irqreturn_t mmci_irq(int irq, void *dev_id)
status = readl(host->base + MMCISTATUS);

if (host->singleirq) {
- if (status & readl(host->base + MMCIMASK1))
+ if (status & host->mask1_reg)
mmci_pio_irq(irq, dev_id);

status &= ~MCI_IRQ1MASK;
@@ -1729,7 +1743,10 @@ static int mmci_probe(struct amba_device *dev,
spin_lock_init(&host->lock);

writel(0, host->base + MMCIMASK0);
- writel(0, host->base + MMCIMASK1);
+
+ if (variant->mmcimask1)
+ writel(0, host->base + MMCIMASK1);
+
writel(0xfff, host->base + MMCICLEAR);

/*
@@ -1809,6 +1826,7 @@ static int mmci_remove(struct amba_device *dev)

if (mmc) {
struct mmci_host *host = mmc_priv(mmc);
+ struct variant_data *variant = host->variant;

/*
* Undo pm_runtime_put() in probe. We use the _sync
@@ -1819,7 +1837,9 @@ static int mmci_remove(struct amba_device *dev)
mmc_remove_host(mmc);

writel(0, host->base + MMCIMASK0);
- writel(0, host->base + MMCIMASK1);
+
+ if (variant->mmcimask1)
+ writel(0, host->base + MMCIMASK1);

writel(0, host->base + MMCICOMMAND);
writel(0, host->base + MMCIDATACTRL);
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h
index 4a8bef1..83160a9 100644
--- a/drivers/mmc/host/mmci.h
+++ b/drivers/mmc/host/mmci.h
@@ -223,6 +223,7 @@ struct mmci_host {
u32 clk_reg;
u32 datactrl_reg;
u32 busy_status;
+ u32 mask1_reg;
bool vqmmc_enabled;
struct mmci_platform_data *plat;
struct variant_data *variant;
--
1.9.1

2018-01-12 12:17:33

by Patrice CHOTARD

[permalink] [raw]
Subject: [PATCH 09/14] ARM: dts: stm32: Enable SDIO controller on stm32429i-eval board

From: Patrice Chotard <[email protected]>

This patch adds SDIO related DT nodes for stm32429i-eval board.

Signed-off-by: Patrice Chotard <[email protected]>
---
arch/arm/boot/dts/stm32429i-eval.dts | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)

diff --git a/arch/arm/boot/dts/stm32429i-eval.dts b/arch/arm/boot/dts/stm32429i-eval.dts
index 1e3d4c6..6a5c701 100644
--- a/arch/arm/boot/dts/stm32429i-eval.dts
+++ b/arch/arm/boot/dts/stm32429i-eval.dts
@@ -144,6 +144,13 @@
};
};
};
+
+ mmc_vcard: mmc_vcard {
+ compatible = "regulator-fixed";
+ regulator-name = "mmc_vcard";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
};

&adc {
@@ -254,6 +261,18 @@
status = "okay";
};

+&sdio {
+ status = "okay";
+ vmmc-supply = <&mmc_vcard>;
+ cd-gpios = <&stmpegpio 15 GPIO_ACTIVE_HIGH>;
+ cd-inverted;
+ pinctrl-names = "default", "opendrain";
+ pinctrl-0 = <&sdio_pins>;
+ pinctrl-1 = <&sdio_pins_od>;
+ bus-width = <4>;
+ max-frequency = <12500000>;
+};
+
&timers1 {
status = "okay";

--
1.9.1

2018-01-12 12:17:53

by Patrice CHOTARD

[permalink] [raw]
Subject: [PATCH 03/14] mmc: mmci: Add support for setting pad type via pinctrl

From: Patrice Chotard <[email protected]>

The STM32 variant hasn't the control bit to switch pads in opendrain mode.
In this case we can achieve the same result by asking to the pinmux driver
to configure pins for us.

This patch make the mmci driver able to do this whenever needed.

Signed-off-by: Andrea Merello <[email protected]>
Signed-off-by: Patrice Chotard <[email protected]>
---
drivers/mmc/host/mmci.c | 54 ++++++++++++++++++++++++++++++++++++++++---------
drivers/mmc/host/mmci.h | 5 +++++
2 files changed, 50 insertions(+), 9 deletions(-)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 7e56f85..38e8c20 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -85,6 +85,8 @@
* @mmcimask1: true if variant have a MMCIMASK1 register.
* @start_err: true is the variant has STARTBITERR bit inside MMCISTATUS
* register.
+ * @opendrain: true if variant have dedicated bit for opendrain pins
+ * configuration.
*/
struct variant_data {
unsigned int clkreg;
@@ -116,6 +118,7 @@ struct variant_data {
bool reversed_irq_handling;
bool mmcimask1;
bool start_err;
+ bool opendrain;
};

static struct variant_data variant_arm = {
@@ -127,6 +130,7 @@ struct variant_data {
.reversed_irq_handling = true,
.mmcimask1 = true,
.start_err = true,
+ .opendrain = true,
};

static struct variant_data variant_arm_extended_fifo = {
@@ -137,6 +141,7 @@ struct variant_data {
.f_max = 100000000,
.mmcimask1 = true,
.start_err = true,
+ .opendrain = true,
};

static struct variant_data variant_arm_extended_fifo_hwfc = {
@@ -148,6 +153,7 @@ struct variant_data {
.f_max = 100000000,
.mmcimask1 = true,
.start_err = true,
+ .opendrain = true,
};

static struct variant_data variant_u300 = {
@@ -165,6 +171,7 @@ struct variant_data {
.pwrreg_nopower = true,
.mmcimask1 = true,
.start_err = true,
+ .opendrain = true,
};

static struct variant_data variant_nomadik = {
@@ -183,6 +190,7 @@ struct variant_data {
.pwrreg_nopower = true,
.mmcimask1 = true,
.start_err = true,
+ .opendrain = true,
};

static struct variant_data variant_ux500 = {
@@ -207,6 +215,7 @@ struct variant_data {
.pwrreg_nopower = true,
.mmcimask1 = true,
.start_err = true,
+ .opendrain = true,
};

static struct variant_data variant_ux500v2 = {
@@ -233,6 +242,7 @@ struct variant_data {
.pwrreg_nopower = true,
.mmcimask1 = true,
.start_err = true,
+ .opendrain = true,
};

static struct variant_data variant_qcom = {
@@ -253,6 +263,7 @@ struct variant_data {
.qcom_dml = true,
.mmcimask1 = true,
.start_err = true,
+ .opendrain = true,
};

/* Busy detection for the ST Micro variant */
@@ -1394,9 +1405,11 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
{
struct mmci_host *host = mmc_priv(mmc);
struct variant_data *variant = host->variant;
+ struct pinctrl_state *pins;
u32 pwr = 0;
unsigned long flags;
int ret;
+ bool is_opendrain;

if (host->plat->ios_handler &&
host->plat->ios_handler(mmc_dev(mmc), ios))
@@ -1455,16 +1468,31 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
~MCI_ST_DATA2DIREN);
}

- if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) {
- if (host->hw_designer != AMBA_VENDOR_ST)
- pwr |= MCI_ROD;
- else {
- /*
- * The ST Micro variant use the ROD bit for something
- * else and only has OD (Open Drain).
- */
- pwr |= MCI_OD;
+ if (host->variant->opendrain) {
+ if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) {
+ if (host->hw_designer != AMBA_VENDOR_ST) {
+ pwr |= MCI_ROD;
+ } else {
+ /*
+ * The ST Micro variant use the ROD bit for
+ * something else and only has OD (Open Drain).
+ */
+ pwr |= MCI_OD;
+ }
}
+ } else {
+ /*
+ * If the variant cannot configure the pads by its own, then we
+ * expect the pinctrl to be able to do that for us
+ */
+ is_opendrain = (ios->bus_mode == MMC_BUSMODE_OPENDRAIN);
+ pins = pinctrl_lookup_state(host->pinctrl, is_opendrain ?
+ MMCI_PINCTRL_STATE_OPENDRAIN :
+ MMCI_PINCTRL_STATE_PUSHPULL);
+ if (IS_ERR(pins))
+ dev_warn(mmc_dev(mmc), "Cannot select pin drive type via pinctrl\n");
+ else
+ pinctrl_select_state(host->pinctrl, pins);
}

/*
@@ -1609,6 +1637,14 @@ static int mmci_probe(struct amba_device *dev,
host = mmc_priv(mmc);
host->mmc = mmc;

+ if (!variant->opendrain) {
+ host->pinctrl = devm_pinctrl_get(&dev->dev);
+ if (IS_ERR(host->pinctrl)) {
+ dev_err(&dev->dev, "failed to get pinctrl");
+ goto host_free;
+ }
+ }
+
host->hw_designer = amba_manf(dev);
host->hw_revision = amba_rev(dev);
dev_dbg(mmc_dev(mmc), "designer ID = 0x%02x\n", host->hw_designer);
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h
index 83160a9..de3d0b3 100644
--- a/drivers/mmc/host/mmci.h
+++ b/drivers/mmc/host/mmci.h
@@ -192,6 +192,10 @@

#define NR_SG 128

+/* pinctrl configs */
+#define MMCI_PINCTRL_STATE_PUSHPULL "default"
+#define MMCI_PINCTRL_STATE_OPENDRAIN "opendrain"
+
struct clk;
struct variant_data;
struct dma_chan;
@@ -227,6 +231,7 @@ struct mmci_host {
bool vqmmc_enabled;
struct mmci_platform_data *plat;
struct variant_data *variant;
+ struct pinctrl *pinctrl;

u8 hw_designer;
u8 hw_revision:4;
--
1.9.1

2018-01-12 12:17:51

by Patrice CHOTARD

[permalink] [raw]
Subject: [PATCH 07/14] ARM: dts: stm32: Add pin map for SDIO controller on stm32f4

From: Andrea Merello <[email protected]>

This patch adds the pin configuration for SDIO controller on
stm32f4.

Signed-off-by: Andrea Merello <[email protected]>
Signed-off-by: Patrice Chotard <[email protected]>
---
arch/arm/boot/dts/stm32f4-pinctrl.dtsi | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)

diff --git a/arch/arm/boot/dts/stm32f4-pinctrl.dtsi b/arch/arm/boot/dts/stm32f4-pinctrl.dtsi
index ae94d86..3520289 100644
--- a/arch/arm/boot/dts/stm32f4-pinctrl.dtsi
+++ b/arch/arm/boot/dts/stm32f4-pinctrl.dtsi
@@ -338,6 +338,37 @@
slew-rate = <3>;
};
};
+
+ sdio_pins: sdio_pins@0 {
+ pins {
+ pinmux = <STM32_PINMUX('C', 8, AF12)>, /* SDIO_D0 */
+ <STM32_PINMUX('C', 9, AF12)>, /* SDIO_D1 */
+ <STM32_PINMUX('C', 10, AF12)>, /* SDIO_D2 */
+ <STM32_PINMUX('C', 11, AF12)>, /* SDIO_D3 */
+ <STM32_PINMUX('C', 12, AF12)>, /* SDIO_CK */
+ <STM32_PINMUX('D', 2, AF12)>; /* SDIO_CMD */
+ drive-push-pull;
+ slew-rate = <2>;
+ };
+ };
+
+ sdio_pins_od: sdio_pins_od@0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('C', 8, AF12)>, /* SDIO_D0 */
+ <STM32_PINMUX('C', 9, AF12)>, /* SDIO_D1 */
+ <STM32_PINMUX('C', 10, AF12)>, /* SDIO_D2 */
+ <STM32_PINMUX('C', 11, AF12)>, /* SDIO_D3 */
+ <STM32_PINMUX('C', 12, AF12)>; /* SDIO_CK */
+ drive-push-pull;
+ slew-rate = <2>;
+ };
+
+ pins2 {
+ pinmux = <STM32_PINMUX('D', 2, AF12)>; /* SDIO_CMD */
+ drive-open-drain;
+ slew-rate = <2>;
+ };
+ };
};
};
};
--
1.9.1

2018-01-12 12:18:27

by Patrice CHOTARD

[permalink] [raw]
Subject: [PATCH 04/14] mmc: mmci: Add STM32 variant

From: Patrice Chotard <[email protected]>

STM32F4 and STM32F7 MCUs has a SDIO controller that looks like
an ARM pl810.
This patch adds the STM32 variant so that mmci driver supports it.

Signed-off-by: Andrea Merello <[email protected]>
Signed-off-by: Patrice Chotard <[email protected]>
---
drivers/mmc/host/mmci.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 38e8c20..9fb5035 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -245,6 +245,23 @@ struct variant_data {
.opendrain = true,
};

+static struct variant_data variant_stm32 = {
+ .fifosize = 32 * 4,
+ .fifohalfsize = 8 * 4,
+ .clkreg = MCI_CLK_ENABLE,
+ .clkreg_enable = MCI_ST_UX500_HWFCEN,
+ .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS,
+ .clkreg_neg_edge_enable = MCI_ST_UX500_NEG_EDGE,
+ .datalength_bits = 24,
+ .datactrl_mask_sdio = MCI_DPSM_ST_SDIOEN,
+ .st_sdio = true,
+ .st_clkdiv = true,
+ .pwrreg_powerup = MCI_PWR_ON,
+ .f_max = 48000000,
+ .pwrreg_clkgate = true,
+ .pwrreg_nopower = true,
+};
+
static struct variant_data variant_qcom = {
.fifosize = 16 * 4,
.fifohalfsize = 8 * 4,
@@ -2019,6 +2036,11 @@ static int mmci_runtime_resume(struct device *dev)
.mask = 0xf0ffffff,
.data = &variant_ux500v2,
},
+ {
+ .id = 0x00880180,
+ .mask = 0x00ffffff,
+ .data = &variant_stm32,
+ },
/* Qualcomm variants */
{
.id = 0x00051180,
--
1.9.1

2018-01-12 12:18:29

by Patrice CHOTARD

[permalink] [raw]
Subject: [PATCH 08/14] ARM: dts: stm32: Enable SDIO controller on stm32f469 disco board

From: Andrea Merello <[email protected]>

This patch adds SDIO-related DT nodes required by stm32f469 board

There is a hardware issue on these boards, it misses a pullup on
the GPIO line used as card detect to allow correct SD card
detection. To allow correct card detection "broken-cd" property
is used.

Signed-off-by: Andrea Merello <[email protected]>
Signed-off-by: Alexandre TORGUE <[email protected]>
Signed-off-by: Patrice Chotard <[email protected]>
---
arch/arm/boot/dts/stm32f469-disco.dts | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)

diff --git a/arch/arm/boot/dts/stm32f469-disco.dts b/arch/arm/boot/dts/stm32f469-disco.dts
index 318fb12..ebb97c3 100644
--- a/arch/arm/boot/dts/stm32f469-disco.dts
+++ b/arch/arm/boot/dts/stm32f469-disco.dts
@@ -66,6 +66,13 @@
serial0 = &usart3;
};

+ mmc_vcard: mmc_vcard {
+ compatible = "regulator-fixed";
+ regulator-name = "mmc_vcard";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
soc {
dma-ranges = <0xc0000000 0x0 0x10000000>;
};
@@ -120,6 +127,18 @@
};
};

+&sdio {
+ status = "okay";
+ vmmc-supply = <&mmc_vcard>;
+ cd-gpios = <&gpiog 2 0>;
+ cd-inverted;
+ broken-cd;
+ pinctrl-names = "default", "opendrain";
+ pinctrl-0 = <&sdio_pins>;
+ pinctrl-1 = <&sdio_pins_od>;
+ bus-width = <4>;
+};
+
&usart3 {
pinctrl-0 = <&usart3_pins_a>;
pinctrl-names = "default";
--
1.9.1

2018-01-12 12:18:25

by Patrice CHOTARD

[permalink] [raw]
Subject: [PATCH 11/14] ARM: configs: stm32: Enable MMC_ARMMMCI support

From: Patrice Chotard <[email protected]>

Enable MMC_ARMMCI support to add SDIO support for
STM32F4 and STM32F7 SoCs family

Signed-off-by: Patrice Chotard <[email protected]>
---
arch/arm/configs/stm32_defconfig | 2 ++
1 file changed, 2 insertions(+)

diff --git a/arch/arm/configs/stm32_defconfig b/arch/arm/configs/stm32_defconfig
index 21b2bf7..8b64a9e 100644
--- a/arch/arm/configs/stm32_defconfig
+++ b/arch/arm/configs/stm32_defconfig
@@ -56,6 +56,8 @@ CONFIG_MFD_STMPE=y
CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
# CONFIG_USB_SUPPORT is not set
+CONFIG_MMC=y
+CONFIG_MMC_ARMMMCI=y
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
CONFIG_LEDS_GPIO=y
--
1.9.1

2018-01-12 12:19:27

by Patrice CHOTARD

[permalink] [raw]
Subject: [PATCH 12/14] ARM: configs: stm32: Enable EXT3_FS support

From: Patrice Chotard <[email protected]>

Enable EXT3_FS support to be able to read rootfs from MMC partition
formatted in EXT2/3/4 .

Signed-off-by: Patrice Chotard <[email protected]>
---
arch/arm/configs/stm32_defconfig | 1 +
1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/stm32_defconfig b/arch/arm/configs/stm32_defconfig
index 8b64a9e..b736823 100644
--- a/arch/arm/configs/stm32_defconfig
+++ b/arch/arm/configs/stm32_defconfig
@@ -72,6 +72,7 @@ CONFIG_STM32_MDMA=y
CONFIG_IIO=y
CONFIG_STM32_ADC_CORE=y
CONFIG_STM32_ADC=y
+CONFIG_EXT3_FS=y
# CONFIG_FILE_LOCKING is not set
# CONFIG_DNOTIFY is not set
# CONFIG_INOTIFY_USER is not set
--
1.9.1

2018-01-12 12:19:23

by Patrice CHOTARD

[permalink] [raw]
Subject: [PATCH 14/14] gpio: stmpe: i2c transfer are forbiden in atomic context

From: Patrice Chotard <[email protected]>

Move the workaround from stmpe_gpio_irq_unmask() which is executed
in atomic context to stmpe_gpio_irq_sync_unlock() which is not.

It fixes the following issue:

[ 1.500000] BUG: scheduling while atomic: swapper/1/0x00000002
[ 1.500000] CPU: 0 PID: 1 Comm: swapper Not tainted 4.15.0-rc2-00020-gbd4301f-dirty #28
[ 1.520000] Hardware name: STM32 (Device Tree Support)
[ 1.520000] [<0000bfc9>] (unwind_backtrace) from [<0000b347>] (show_stack+0xb/0xc)
[ 1.530000] [<0000b347>] (show_stack) from [<0001fc49>] (__schedule_bug+0x39/0x58)
[ 1.530000] [<0001fc49>] (__schedule_bug) from [<00168211>] (__schedule+0x23/0x2b2)
[ 1.550000] [<00168211>] (__schedule) from [<001684f7>] (schedule+0x57/0x64)
[ 1.550000] [<001684f7>] (schedule) from [<0016a513>] (schedule_timeout+0x137/0x164)
[ 1.550000] [<0016a513>] (schedule_timeout) from [<00168b91>] (wait_for_common+0x8d/0xfc)
[ 1.570000] [<00168b91>] (wait_for_common) from [<00139753>] (stm32f4_i2c_xfer+0xe9/0xfe)
[ 1.580000] [<00139753>] (stm32f4_i2c_xfer) from [<00138545>] (__i2c_transfer+0x111/0x148)
[ 1.590000] [<00138545>] (__i2c_transfer) from [<001385cf>] (i2c_transfer+0x53/0x70)
[ 1.590000] [<001385cf>] (i2c_transfer) from [<001388a5>] (i2c_smbus_xfer+0x12f/0x36e)
[ 1.600000] [<001388a5>] (i2c_smbus_xfer) from [<00138b49>] (i2c_smbus_read_byte_data+0x1f/0x2a)
[ 1.610000] [<00138b49>] (i2c_smbus_read_byte_data) from [<00124fdd>] (__stmpe_reg_read+0xd/0x24)
[ 1.620000] [<00124fdd>] (__stmpe_reg_read) from [<001252b3>] (stmpe_reg_read+0x19/0x24)
[ 1.630000] [<001252b3>] (stmpe_reg_read) from [<0002c4d1>] (unmask_irq+0x17/0x22)
[ 1.640000] [<0002c4d1>] (unmask_irq) from [<0002c57f>] (irq_startup+0x6f/0x78)
[ 1.650000] [<0002c57f>] (irq_startup) from [<0002b7a1>] (__setup_irq+0x319/0x47c)
[ 1.650000] [<0002b7a1>] (__setup_irq) from [<0002bad3>] (request_threaded_irq+0x6b/0xe8)
[ 1.660000] [<0002bad3>] (request_threaded_irq) from [<0002d0b9>] (devm_request_threaded_irq+0x3b/0x6a)
[ 1.670000] [<0002d0b9>] (devm_request_threaded_irq) from [<001446e7>] (mmc_gpiod_request_cd_irq+0x49/0x8a)
[ 1.680000] [<001446e7>] (mmc_gpiod_request_cd_irq) from [<0013d45d>] (mmc_start_host+0x49/0x60)
[ 1.690000] [<0013d45d>] (mmc_start_host) from [<0013e40b>] (mmc_add_host+0x3b/0x54)
[ 1.700000] [<0013e40b>] (mmc_add_host) from [<00148119>] (mmci_probe+0x4d1/0x60c)
[ 1.710000] [<00148119>] (mmci_probe) from [<000f903b>] (amba_probe+0x7b/0xbe)
[ 1.720000] [<000f903b>] (amba_probe) from [<001170e5>] (driver_probe_device+0x169/0x1f8)
[ 1.730000] [<001170e5>] (driver_probe_device) from [<001171b7>] (__driver_attach+0x43/0x5c)
[ 1.740000] [<001171b7>] (__driver_attach) from [<0011618d>] (bus_for_each_dev+0x3d/0x46)
[ 1.740000] [<0011618d>] (bus_for_each_dev) from [<001165cd>] (bus_add_driver+0xcd/0x124)
[ 1.740000] [<001165cd>] (bus_add_driver) from [<00117713>] (driver_register+0x4d/0x7a)
[ 1.760000] [<00117713>] (driver_register) from [<001fc765>] (do_one_initcall+0xbd/0xe8)
[ 1.770000] [<001fc765>] (do_one_initcall) from [<001fc88b>] (kernel_init_freeable+0xfb/0x134)
[ 1.780000] [<001fc88b>] (kernel_init_freeable) from [<00167ee3>] (kernel_init+0x7/0x9c)
[ 1.790000] [<00167ee3>] (kernel_init) from [<00009b65>] (ret_from_fork+0x11/0x2c)

Signed-off-by: Alexandre TORGUE <[email protected]>
Signed-off-by: Patrice Chotard <[email protected]>
---
drivers/gpio/gpio-stmpe.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c
index e6e5cca..91c8ae2 100644
--- a/drivers/gpio/gpio-stmpe.c
+++ b/drivers/gpio/gpio-stmpe.c
@@ -190,6 +190,16 @@ static void stmpe_gpio_irq_sync_unlock(struct irq_data *d)
};
int i, j;

+ /*
+ * STMPE1600: to be able to get IRQ from pins,
+ * a read must be done on GPMR register, or a write in
+ * GPSR or GPCR registers
+ */
+ if (stmpe->partnum == STMPE1600) {
+ stmpe_reg_read(stmpe, stmpe->regs[STMPE_IDX_GPMR_LSB]);
+ stmpe_reg_read(stmpe, stmpe->regs[STMPE_IDX_GPMR_CSB]);
+ };
+
for (i = 0; i < CACHE_NR_REGS; i++) {
/* STMPE801 and STMPE1600 don't have RE and FE registers */
if ((stmpe->partnum == STMPE801 ||
@@ -227,21 +237,11 @@ static void stmpe_gpio_irq_unmask(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct stmpe_gpio *stmpe_gpio = gpiochip_get_data(gc);
- struct stmpe *stmpe = stmpe_gpio->stmpe;
int offset = d->hwirq;
int regoffset = offset / 8;
int mask = BIT(offset % 8);

stmpe_gpio->regs[REG_IE][regoffset] |= mask;
-
- /*
- * STMPE1600 workaround: to be able to get IRQ from pins,
- * a read must be done on GPMR register, or a write in
- * GPSR or GPCR registers
- */
- if (stmpe->partnum == STMPE1600)
- stmpe_reg_read(stmpe,
- stmpe->regs[STMPE_IDX_GPMR_LSB + regoffset]);
}

static void stmpe_dbg_show_one(struct seq_file *s,
--
1.9.1

2018-01-12 12:20:15

by Patrice CHOTARD

[permalink] [raw]
Subject: [PATCH 10/14] ARM: stm32: Add AMBA support for STM32F4 and STM32F7 SoCs

From: Patrice Chotard <[email protected]>

As both STM32F4 and STM32F7 SoCs embeds an AMBA PL180 mmci IP,
we need to enable AMBA support in mach-stm32.

Signed-off-by: Patrice Chotard <[email protected]>
---
arch/arm/mach-stm32/Kconfig | 3 +++
1 file changed, 3 insertions(+)

diff --git a/arch/arm/mach-stm32/Kconfig b/arch/arm/mach-stm32/Kconfig
index 0d1889b..f53a8db 100644
--- a/arch/arm/mach-stm32/Kconfig
+++ b/arch/arm/mach-stm32/Kconfig
@@ -13,16 +13,19 @@ config ARCH_STM32
config MACH_STM32F429
bool "STMicrolectronics STM32F429"
depends on ARCH_STM32
+ select ARM_AMBA
default y

config MACH_STM32F469
bool "STMicrolectronics STM32F469"
depends on ARCH_STM32
+ select ARM_AMBA
default y

config MACH_STM32F746
bool "STMicrolectronics STM32F746"
depends on ARCH_STM32
+ select ARM_AMBA
default y

config MACH_STM32H743
--
1.9.1

2018-01-12 12:20:50

by Patrice CHOTARD

[permalink] [raw]
Subject: [PATCH 13/14] clk: stm32: Add clk entry for SDMMC2 on stm32F769

From: Patrice Chotard <[email protected]>

STM32F769 has 2 SDMMC port, add clock entry for the second one.

Signed-off-by: Alexandre TORGUE <[email protected]>
Signed-off-by: Patrice Chotard <[email protected]>
---
drivers/clk/clk-stm32f4.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/clk-stm32f4.c b/drivers/clk/clk-stm32f4.c
index 96c6b6b..8f8a178 100644
--- a/drivers/clk/clk-stm32f4.c
+++ b/drivers/clk/clk-stm32f4.c
@@ -282,6 +282,7 @@ struct stm32f4_gate_data {

{ STM32F4_RCC_APB2ENR, 0, "tim1", "apb2_mul" },
{ STM32F4_RCC_APB2ENR, 1, "tim8", "apb2_mul" },
+ { STM32F4_RCC_APB2ENR, 7, "sdmmc2", "sdmux" },
{ STM32F4_RCC_APB2ENR, 8, "adc1", "apb2_div" },
{ STM32F4_RCC_APB2ENR, 9, "adc2", "apb2_div" },
{ STM32F4_RCC_APB2ENR, 10, "adc3", "apb2_div" },
@@ -315,7 +316,7 @@ struct stm32f4_gate_data {

static const u64 stm32f746_gate_map[MAX_GATE_MAP] = { 0x000000f17ef417ffull,
0x0000000000000003ull,
- 0x04f77f033e01c9ffull };
+ 0x04f77f833e01c9ffull };

static const u64 *stm32f4_gate_map;

--
1.9.1

2018-01-12 12:21:11

by Patrice CHOTARD

[permalink] [raw]
Subject: [PATCH 05/14] ARM: dts: stm32: Add SDIO controller for stm32f746

From: Patrice Chotard <[email protected]>

stm32f746 embeds ARM_PL180 sdio IP, adds SDIO controller
nodes to allow MMC support.

Signed-off-by: Patrice Chotard <[email protected]>
---
arch/arm/boot/dts/stm32f746.dtsi | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)

diff --git a/arch/arm/boot/dts/stm32f746.dtsi b/arch/arm/boot/dts/stm32f746.dtsi
index 5f66d15..cffe1b1 100644
--- a/arch/arm/boot/dts/stm32f746.dtsi
+++ b/arch/arm/boot/dts/stm32f746.dtsi
@@ -429,6 +429,28 @@
status = "disabled";
};

+ sdio2: sdio2@40011c00 {
+ compatible = "arm,pl180", "arm,primecell";
+ arm,primecell-periphid = <0x00880180>;
+ reg = <0x40011c00 0x400>;
+ clocks = <&rcc 0 167>;
+ clock-names = "apb_pclk";
+ interrupts = <103>;
+ max-frequency = <48000000>;
+ status = "disabled";
+ };
+
+ sdio: sdio@40012c00 {
+ compatible = "arm,pl180", "arm,primecell";
+ arm,primecell-periphid = <0x00880180>;
+ reg = <0x40012c00 0x400>;
+ clocks = <&rcc 0 171>;
+ clock-names = "apb_pclk";
+ interrupts = <49>;
+ max-frequency = <48000000>;
+ status = "disabled";
+ };
+
syscfg: system-config@40013800 {
compatible = "syscon";
reg = <0x40013800 0x400>;
--
1.9.1

2018-01-12 12:21:10

by Patrice CHOTARD

[permalink] [raw]
Subject: [PATCH 06/14] ARM: dts: stm32: Add SDIO controller for stm32f429

From: Patrice Chotard <[email protected]>

stm32f429 embeds ARM_PL180 sdi IP, adds SDIO controller
node to allow MMC support.

Signed-off-by: Andrea Merello <[email protected]>
Signed-off-by: Patrice Chotard <[email protected]>
---
arch/arm/boot/dts/stm32f429.dtsi | 11 +++++++++++
1 file changed, 11 insertions(+)

diff --git a/arch/arm/boot/dts/stm32f429.dtsi b/arch/arm/boot/dts/stm32f429.dtsi
index 10099df..ede77e0 100644
--- a/arch/arm/boot/dts/stm32f429.dtsi
+++ b/arch/arm/boot/dts/stm32f429.dtsi
@@ -511,6 +511,17 @@
};
};

+ sdio: sdio@40012c00 {
+ compatible = "arm,pl180", "arm,primecell";
+ arm,primecell-periphid = <0x00880180>;
+ reg = <0x40012c00 0x400>;
+ clocks = <&rcc 0 STM32F4_APB2_CLOCK(SDIO)>;
+ clock-names = "apb_pclk";
+ interrupts = <49>;
+ max-frequency = <48000000>;
+ status = "disabled";
+ };
+
syscfg: system-config@40013800 {
compatible = "syscon";
reg = <0x40013800 0x400>;
--
1.9.1

2018-01-12 18:52:49

by Stephen Boyd

[permalink] [raw]
Subject: Re: [PATCH 13/14] clk: stm32: Add clk entry for SDMMC2 on stm32F769

On 01/12, [email protected] wrote:
> From: Patrice Chotard <[email protected]>
>
> STM32F769 has 2 SDMMC port, add clock entry for the second one.
>
> Signed-off-by: Alexandre TORGUE <[email protected]>
> Signed-off-by: Patrice Chotard <[email protected]>
> ---

Acked-by: Stephen Boyd <[email protected]>

--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

2018-01-15 01:01:41

by Linus Walleij

[permalink] [raw]
Subject: Re: [PATCH 01/14] mmc: mmci: Don't pretend all variants to have MMCIMASK1 register

On Fri, Jan 12, 2018 at 1:15 PM, <[email protected]> wrote:

> From: Patrice Chotard <[email protected]>
>
> Two mask registers are used in order to select which events have to
> actually generate an interrupt on each IRQ line.
>
> It seems that in the single-IRQ case it's assumed that the IRQs lines
> are simply OR-ed, while the two mask registers are still present. The
> driver still programs the two mask registers separately.
>
> However the STM32 variant has only one IRQ, and also has only one mask
> register.
>
> This patch prepares for STM32 variant support by making the driver using
> only one mask register.
>
> This patch also optimize the MMCIMASK1 mask usage by caching it into
> host->mask1_reg which avoid to read it into mmci_irq().
>
> Tested only on STM32 variant. RFT for variants other than STM32
>
> Signed-off-by: Andrea Merello <[email protected]>
> Signed-off-by: Patrice Chotard <[email protected]>

Reviewed-by: Linus Walleij <[email protected]>

Yours,
Linus Walleij

2018-01-15 01:03:20

by Linus Walleij

[permalink] [raw]
Subject: Re: [PATCH 02/14] mmc: mmci: Don't pretend all variants to have MCI_STARBITERR flag

On Fri, Jan 12, 2018 at 1:15 PM, <[email protected]> wrote:

> From: Patrice Chotard <[email protected]>
>
> This patch prepares for supporting the STM32 variant that
> has no such bit in the status register.
>
> Signed-off-by: Andrea Merello <[email protected]>
> Signed-off-by: Patrice Chotard <[email protected]>

Reviewed-by: Linus Walleij <[email protected]>

Yours,
Linus Walleij

2018-01-15 01:07:28

by Linus Walleij

[permalink] [raw]
Subject: Re: [PATCH 03/14] mmc: mmci: Add support for setting pad type via pinctrl

On Fri, Jan 12, 2018 at 1:15 PM, <[email protected]> wrote:

> From: Patrice Chotard <[email protected]>
>
> The STM32 variant hasn't the control bit to switch pads in opendrain mode.
> In this case we can achieve the same result by asking to the pinmux driver
> to configure pins for us.
>
> This patch make the mmci driver able to do this whenever needed.
>
> Signed-off-by: Andrea Merello <[email protected]>
> Signed-off-by: Patrice Chotard <[email protected]>

Nice and clean way to use pin control for this.
Hats off!

Reviewed-by: Linus Walleij <[email protected]>

Yours,
Linus Walleij

2018-01-15 01:13:25

by Linus Walleij

[permalink] [raw]
Subject: Re: [PATCH 04/14] mmc: mmci: Add STM32 variant

On Fri, Jan 12, 2018 at 1:15 PM, <[email protected]> wrote:

> From: Patrice Chotard <[email protected]>
>
> STM32F4 and STM32F7 MCUs has a SDIO controller that looks like
> an ARM pl810.

PL180 you mean. Ulf can fix while applying.

> This patch adds the STM32 variant so that mmci driver supports it.
>
> Signed-off-by: Andrea Merello <[email protected]>
> Signed-off-by: Patrice Chotard <[email protected]>

(...)
> +static struct variant_data variant_stm32 = {
> + .fifosize = 32 * 4,
> + .fifohalfsize = 8 * 4,
> + .clkreg = MCI_CLK_ENABLE,
> + .clkreg_enable = MCI_ST_UX500_HWFCEN,

If the asic designed derived this from ux500 I guess it is proper.

> + .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS,
> + .clkreg_neg_edge_enable = MCI_ST_UX500_NEG_EDGE,
> + .datalength_bits = 24,
> + .datactrl_mask_sdio = MCI_DPSM_ST_SDIOEN,
> + .st_sdio = true,

Did you test SDIO? I think we lack features for that.

> + {
> + .id = 0x00880180,
> + .mask = 0x00ffffff,
> + .data = &variant_stm32,
> + },

Since ux500 was 480180 I wonder what variants 5,6,7 are...

Reviewed-by: Linus Walleij <[email protected]>

Yours,
Linus Walleij

2018-01-15 09:57:29

by Linus Walleij

[permalink] [raw]
Subject: Re: [PATCH 14/14] gpio: stmpe: i2c transfer are forbiden in atomic context

On Fri, Jan 12, 2018 at 1:16 PM, <[email protected]> wrote:

> From: Patrice Chotard <[email protected]>
>
> Move the workaround from stmpe_gpio_irq_unmask() which is executed
> in atomic context to stmpe_gpio_irq_sync_unlock() which is not.
>
> It fixes the following issue:
>
> [ 1.500000] BUG: scheduling while atomic: swapper/1/0x00000002
> [ 1.500000] CPU: 0 PID: 1 Comm: swapper Not tainted 4.15.0-rc2-00020-gbd4301f-dirty #28
> [ 1.520000] Hardware name: STM32 (Device Tree Support)
> [ 1.520000] [<0000bfc9>] (unwind_backtrace) from [<0000b347>] (show_stack+0xb/0xc)
> [ 1.530000] [<0000b347>] (show_stack) from [<0001fc49>] (__schedule_bug+0x39/0x58)
> [ 1.530000] [<0001fc49>] (__schedule_bug) from [<00168211>] (__schedule+0x23/0x2b2)
> [ 1.550000] [<00168211>] (__schedule) from [<001684f7>] (schedule+0x57/0x64)
> [ 1.550000] [<001684f7>] (schedule) from [<0016a513>] (schedule_timeout+0x137/0x164)
> [ 1.550000] [<0016a513>] (schedule_timeout) from [<00168b91>] (wait_for_common+0x8d/0xfc)
> [ 1.570000] [<00168b91>] (wait_for_common) from [<00139753>] (stm32f4_i2c_xfer+0xe9/0xfe)
> [ 1.580000] [<00139753>] (stm32f4_i2c_xfer) from [<00138545>] (__i2c_transfer+0x111/0x148)
> [ 1.590000] [<00138545>] (__i2c_transfer) from [<001385cf>] (i2c_transfer+0x53/0x70)
> [ 1.590000] [<001385cf>] (i2c_transfer) from [<001388a5>] (i2c_smbus_xfer+0x12f/0x36e)
> [ 1.600000] [<001388a5>] (i2c_smbus_xfer) from [<00138b49>] (i2c_smbus_read_byte_data+0x1f/0x2a)
> [ 1.610000] [<00138b49>] (i2c_smbus_read_byte_data) from [<00124fdd>] (__stmpe_reg_read+0xd/0x24)
> [ 1.620000] [<00124fdd>] (__stmpe_reg_read) from [<001252b3>] (stmpe_reg_read+0x19/0x24)
> [ 1.630000] [<001252b3>] (stmpe_reg_read) from [<0002c4d1>] (unmask_irq+0x17/0x22)
> [ 1.640000] [<0002c4d1>] (unmask_irq) from [<0002c57f>] (irq_startup+0x6f/0x78)
> [ 1.650000] [<0002c57f>] (irq_startup) from [<0002b7a1>] (__setup_irq+0x319/0x47c)
> [ 1.650000] [<0002b7a1>] (__setup_irq) from [<0002bad3>] (request_threaded_irq+0x6b/0xe8)
> [ 1.660000] [<0002bad3>] (request_threaded_irq) from [<0002d0b9>] (devm_request_threaded_irq+0x3b/0x6a)
> [ 1.670000] [<0002d0b9>] (devm_request_threaded_irq) from [<001446e7>] (mmc_gpiod_request_cd_irq+0x49/0x8a)
> [ 1.680000] [<001446e7>] (mmc_gpiod_request_cd_irq) from [<0013d45d>] (mmc_start_host+0x49/0x60)
> [ 1.690000] [<0013d45d>] (mmc_start_host) from [<0013e40b>] (mmc_add_host+0x3b/0x54)
> [ 1.700000] [<0013e40b>] (mmc_add_host) from [<00148119>] (mmci_probe+0x4d1/0x60c)
> [ 1.710000] [<00148119>] (mmci_probe) from [<000f903b>] (amba_probe+0x7b/0xbe)
> [ 1.720000] [<000f903b>] (amba_probe) from [<001170e5>] (driver_probe_device+0x169/0x1f8)
> [ 1.730000] [<001170e5>] (driver_probe_device) from [<001171b7>] (__driver_attach+0x43/0x5c)
> [ 1.740000] [<001171b7>] (__driver_attach) from [<0011618d>] (bus_for_each_dev+0x3d/0x46)
> [ 1.740000] [<0011618d>] (bus_for_each_dev) from [<001165cd>] (bus_add_driver+0xcd/0x124)
> [ 1.740000] [<001165cd>] (bus_add_driver) from [<00117713>] (driver_register+0x4d/0x7a)
> [ 1.760000] [<00117713>] (driver_register) from [<001fc765>] (do_one_initcall+0xbd/0xe8)
> [ 1.770000] [<001fc765>] (do_one_initcall) from [<001fc88b>] (kernel_init_freeable+0xfb/0x134)
> [ 1.780000] [<001fc88b>] (kernel_init_freeable) from [<00167ee3>] (kernel_init+0x7/0x9c)
> [ 1.790000] [<00167ee3>] (kernel_init) from [<00009b65>] (ret_from_fork+0x11/0x2c)
>
> Signed-off-by: Alexandre TORGUE <[email protected]>
> Signed-off-by: Patrice Chotard <[email protected]>

Patch applied.

Yours,
Linus Walleij

2018-01-15 12:32:19

by Ulf Hansson

[permalink] [raw]
Subject: Re: [PATCH 02/14] mmc: mmci: Don't pretend all variants to have MCI_STARBITERR flag

On 12 January 2018 at 13:15, <[email protected]> wrote:
> From: Patrice Chotard <[email protected]>
>
> This patch prepares for supporting the STM32 variant that
> has no such bit in the status register.
>
> Signed-off-by: Andrea Merello <[email protected]>
> Signed-off-by: Patrice Chotard <[email protected]>
> ---
> drivers/mmc/host/mmci.c | 16 ++++++++++++++--
> 1 file changed, 14 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
> index 3125dc0..7e56f85 100644
> --- a/drivers/mmc/host/mmci.c
> +++ b/drivers/mmc/host/mmci.c
> @@ -83,6 +83,8 @@
> * @qcom_dml: enables qcom specific dma glue for dma transfers.
> * @reversed_irq_handling: handle data irq before cmd irq.
> * @mmcimask1: true if variant have a MMCIMASK1 register.
> + * @start_err: true is the variant has STARTBITERR bit inside MMCISTATUS
> + * register.
> */
> struct variant_data {
> unsigned int clkreg;
> @@ -113,6 +115,7 @@ struct variant_data {
> bool qcom_dml;
> bool reversed_irq_handling;
> bool mmcimask1;
> + bool start_err;

To be consistent with how we implement support for similar variant
variations, I would prefer to have this being a u32. Something along
the lines of how the "busy_detect_flag" is being used.

Otherwise this looks good to me.

[...]

Kind regards
Uffe

2018-01-15 12:43:55

by Ulf Hansson

[permalink] [raw]
Subject: Re: [PATCH 03/14] mmc: mmci: Add support for setting pad type via pinctrl

On 12 January 2018 at 13:15, <[email protected]> wrote:
> From: Patrice Chotard <[email protected]>
>
> The STM32 variant hasn't the control bit to switch pads in opendrain mode.
> In this case we can achieve the same result by asking to the pinmux driver
> to configure pins for us.
>
> This patch make the mmci driver able to do this whenever needed.
>
> Signed-off-by: Andrea Merello <[email protected]>
> Signed-off-by: Patrice Chotard <[email protected]>
> ---
> drivers/mmc/host/mmci.c | 54 ++++++++++++++++++++++++++++++++++++++++---------
> drivers/mmc/host/mmci.h | 5 +++++
> 2 files changed, 50 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
> index 7e56f85..38e8c20 100644
> --- a/drivers/mmc/host/mmci.c
> +++ b/drivers/mmc/host/mmci.c
> @@ -85,6 +85,8 @@
> * @mmcimask1: true if variant have a MMCIMASK1 register.
> * @start_err: true is the variant has STARTBITERR bit inside MMCISTATUS
> * register.
> + * @opendrain: true if variant have dedicated bit for opendrain pins
> + * configuration.
> */
> struct variant_data {
> unsigned int clkreg;
> @@ -116,6 +118,7 @@ struct variant_data {
> bool reversed_irq_handling;
> bool mmcimask1;
> bool start_err;
> + bool opendrain;

Similar comment as for patch2.

To be consistent with how we implement support for similar variant
variations, I would prefer to have this being a u32. Something along
the lines of how the "busy_detect_flag" is being used.

[...]

> @@ -1394,9 +1405,11 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
> {
> struct mmci_host *host = mmc_priv(mmc);
> struct variant_data *variant = host->variant;
> + struct pinctrl_state *pins;
> u32 pwr = 0;
> unsigned long flags;
> int ret;
> + bool is_opendrain;
>
> if (host->plat->ios_handler &&
> host->plat->ios_handler(mmc_dev(mmc), ios))
> @@ -1455,16 +1468,31 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
> ~MCI_ST_DATA2DIREN);
> }
>
> - if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) {
> - if (host->hw_designer != AMBA_VENDOR_ST)
> - pwr |= MCI_ROD;
> - else {
> - /*
> - * The ST Micro variant use the ROD bit for something
> - * else and only has OD (Open Drain).
> - */
> - pwr |= MCI_OD;

Seems like you should actually split this change into two parts.

One that adds the variant flag for the open drain bit, when then can
clean up this code. Then a patch on top that starts using pinctrl in
case there is no open drain bit set.

Does that sounds reasonable?

> + if (host->variant->opendrain) {
> + if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) {
> + if (host->hw_designer != AMBA_VENDOR_ST) {
> + pwr |= MCI_ROD;
> + } else {
> + /*
> + * The ST Micro variant use the ROD bit for
> + * something else and only has OD (Open Drain).
> + */
> + pwr |= MCI_OD;
> + }
> }
> + } else {
> + /*
> + * If the variant cannot configure the pads by its own, then we
> + * expect the pinctrl to be able to do that for us
> + */
> + is_opendrain = (ios->bus_mode == MMC_BUSMODE_OPENDRAIN);
> + pins = pinctrl_lookup_state(host->pinctrl, is_opendrain ?

How about doing the lookup in ->probe() instead? Then just select the
state here, if supported?

> + MMCI_PINCTRL_STATE_OPENDRAIN :
> + MMCI_PINCTRL_STATE_PUSHPULL);
> + if (IS_ERR(pins))
> + dev_warn(mmc_dev(mmc), "Cannot select pin drive type via pinctrl\n");
> + else
> + pinctrl_select_state(host->pinctrl, pins);
> }
>
> /*
> @@ -1609,6 +1637,14 @@ static int mmci_probe(struct amba_device *dev,
> host = mmc_priv(mmc);
> host->mmc = mmc;
>
> + if (!variant->opendrain) {
> + host->pinctrl = devm_pinctrl_get(&dev->dev);
> + if (IS_ERR(host->pinctrl)) {
> + dev_err(&dev->dev, "failed to get pinctrl");
> + goto host_free;
> + }
> + }
> +
> host->hw_designer = amba_manf(dev);
> host->hw_revision = amba_rev(dev);
> dev_dbg(mmc_dev(mmc), "designer ID = 0x%02x\n", host->hw_designer);
> diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h
> index 83160a9..de3d0b3 100644
> --- a/drivers/mmc/host/mmci.h
> +++ b/drivers/mmc/host/mmci.h
> @@ -192,6 +192,10 @@
>
> #define NR_SG 128
>
> +/* pinctrl configs */
> +#define MMCI_PINCTRL_STATE_PUSHPULL "default"

Seems like we should be able to cope fine without having to add a
separate define for the PUSHPULL, but rather just select the default
state instead.

> +#define MMCI_PINCTRL_STATE_OPENDRAIN "opendrain"
> +
> struct clk;
> struct variant_data;
> struct dma_chan;
> @@ -227,6 +231,7 @@ struct mmci_host {
> bool vqmmc_enabled;
> struct mmci_platform_data *plat;
> struct variant_data *variant;
> + struct pinctrl *pinctrl;
>
> u8 hw_designer;
> u8 hw_revision:4;
> --
> 1.9.1
>

Kind regards
Uffe

2018-01-15 17:18:39

by Patrice CHOTARD

[permalink] [raw]
Subject: Re: [PATCH 04/14] mmc: mmci: Add STM32 variant

Hi Linus

On 01/15/2018 02:13 AM, Linus Walleij wrote:
> On Fri, Jan 12, 2018 at 1:15 PM, <[email protected]> wrote:
>
>> From: Patrice Chotard <[email protected]>
>>
>> STM32F4 and STM32F7 MCUs has a SDIO controller that looks like
>> an ARM pl810.
>
> PL180 you mean. Ulf can fix while applying.

I need to send a v2, i will fix it.

>
>> This patch adds the STM32 variant so that mmci driver supports it.
>>
>> Signed-off-by: Andrea Merello <[email protected]>
>> Signed-off-by: Patrice Chotard <[email protected]>
>
> (...)
>> +static struct variant_data variant_stm32 = {
>> + .fifosize = 32 * 4,
>> + .fifohalfsize = 8 * 4,
>> + .clkreg = MCI_CLK_ENABLE,
>> + .clkreg_enable = MCI_ST_UX500_HWFCEN,
>
> If the asic designed derived this from ux500 I guess it is proper.
>
>> + .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS,
>> + .clkreg_neg_edge_enable = MCI_ST_UX500_NEG_EDGE,
>> + .datalength_bits = 24,
>> + .datactrl_mask_sdio = MCI_DPSM_ST_SDIOEN,
>> + .st_sdio = true,
>
> Did you test SDIO? I think we lack features for that.

no, the board accept only micro SD card, so only MMC mode can be tested.

>
>> + {
>> + .id = 0x00880180,
>> + .mask = 0x00ffffff,
>> + .data = &variant_stm32,
>> + },
>
> Since ux500 was 480180 I wonder what variants 5,6,7 are...

What is the rule to define the id ? for ST Micro variants we got the
list below :
.id = 0x00180180, u300
.id = 0x10180180, nomadik
.id = 0x00280180, nomadik
.id = 0x00480180, ux500
.id = 0x10480180, ux500v2
.id = 0x00880180, variant_stm32

I simply update the sixth digit for stm32 variant.


Patrice

>
> Reviewed-by: Linus Walleij <[email protected]>
>
> Yours,
> Linus Walleij
>

2018-01-15 17:27:47

by Patrice CHOTARD

[permalink] [raw]
Subject: Re: [PATCH 02/14] mmc: mmci: Don't pretend all variants to have MCI_STARBITERR flag

Hi Ulf

On 01/15/2018 01:32 PM, Ulf Hansson wrote:
> On 12 January 2018 at 13:15, <[email protected]> wrote:
>> From: Patrice Chotard <[email protected]>
>>
>> This patch prepares for supporting the STM32 variant that
>> has no such bit in the status register.
>>
>> Signed-off-by: Andrea Merello <[email protected]>
>> Signed-off-by: Patrice Chotard <[email protected]>
>> ---
>> drivers/mmc/host/mmci.c | 16 ++++++++++++++--
>> 1 file changed, 14 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
>> index 3125dc0..7e56f85 100644
>> --- a/drivers/mmc/host/mmci.c
>> +++ b/drivers/mmc/host/mmci.c
>> @@ -83,6 +83,8 @@
>> * @qcom_dml: enables qcom specific dma glue for dma transfers.
>> * @reversed_irq_handling: handle data irq before cmd irq.
>> * @mmcimask1: true if variant have a MMCIMASK1 register.
>> + * @start_err: true is the variant has STARTBITERR bit inside MMCISTATUS
>> + * register.
>> */
>> struct variant_data {
>> unsigned int clkreg;
>> @@ -113,6 +115,7 @@ struct variant_data {
>> bool qcom_dml;
>> bool reversed_irq_handling;
>> bool mmcimask1;
>> + bool start_err;
>
> To be consistent with how we implement support for similar variant
> variations, I would prefer to have this being a u32. Something along
> the lines of how the "busy_detect_flag" is being used.

OK i will update this in v2

Thanks

Patrice

>
> Otherwise this looks good to me.
>
> [...]
>
> Kind regards
> Uffe
>

2018-01-15 17:42:56

by Patrice CHOTARD

[permalink] [raw]
Subject: Re: [PATCH 03/14] mmc: mmci: Add support for setting pad type via pinctrl

Hi Ulf

On 01/15/2018 01:43 PM, Ulf Hansson wrote:
> On 12 January 2018 at 13:15, <[email protected]> wrote:
>> From: Patrice Chotard <[email protected]>
>>
>> The STM32 variant hasn't the control bit to switch pads in opendrain mode.
>> In this case we can achieve the same result by asking to the pinmux driver
>> to configure pins for us.
>>
>> This patch make the mmci driver able to do this whenever needed.
>>
>> Signed-off-by: Andrea Merello <[email protected]>
>> Signed-off-by: Patrice Chotard <[email protected]>
>> ---
>> drivers/mmc/host/mmci.c | 54 ++++++++++++++++++++++++++++++++++++++++---------
>> drivers/mmc/host/mmci.h | 5 +++++
>> 2 files changed, 50 insertions(+), 9 deletions(-)
>>
>> diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
>> index 7e56f85..38e8c20 100644
>> --- a/drivers/mmc/host/mmci.c
>> +++ b/drivers/mmc/host/mmci.c
>> @@ -85,6 +85,8 @@
>> * @mmcimask1: true if variant have a MMCIMASK1 register.
>> * @start_err: true is the variant has STARTBITERR bit inside MMCISTATUS
>> * register.
>> + * @opendrain: true if variant have dedicated bit for opendrain pins
>> + * configuration.
>> */
>> struct variant_data {
>> unsigned int clkreg;
>> @@ -116,6 +118,7 @@ struct variant_data {
>> bool reversed_irq_handling;
>> bool mmcimask1;
>> bool start_err;
>> + bool opendrain;
>
> Similar comment as for patch2.
>
> To be consistent with how we implement support for similar variant
> variations, I would prefer to have this being a u32. Something along
> the lines of how the "busy_detect_flag" is being used.

ok

>
> [...]
>
>> @@ -1394,9 +1405,11 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
>> {
>> struct mmci_host *host = mmc_priv(mmc);
>> struct variant_data *variant = host->variant;
>> + struct pinctrl_state *pins;
>> u32 pwr = 0;
>> unsigned long flags;
>> int ret;
>> + bool is_opendrain;
>>
>> if (host->plat->ios_handler &&
>> host->plat->ios_handler(mmc_dev(mmc), ios))
>> @@ -1455,16 +1468,31 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
>> ~MCI_ST_DATA2DIREN);
>> }
>>
>> - if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) {
>> - if (host->hw_designer != AMBA_VENDOR_ST)
>> - pwr |= MCI_ROD;
>> - else {
>> - /*
>> - * The ST Micro variant use the ROD bit for something
>> - * else and only has OD (Open Drain).
>> - */
>> - pwr |= MCI_OD;
>
> Seems like you should actually split this change into two parts.
>
> One that adds the variant flag for the open drain bit, when then can
> clean up this code. Then a patch on top that starts using pinctrl in
> case there is no open drain bit set.
>
> Does that sounds reasonable?

Of course

>
>> + if (host->variant->opendrain) {
>> + if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) {
>> + if (host->hw_designer != AMBA_VENDOR_ST) {
>> + pwr |= MCI_ROD;
>> + } else {
>> + /*
>> + * The ST Micro variant use the ROD bit for
>> + * something else and only has OD (Open Drain).
>> + */
>> + pwr |= MCI_OD;
>> + }
>> }
>> + } else {
>> + /*
>> + * If the variant cannot configure the pads by its own, then we
>> + * expect the pinctrl to be able to do that for us
>> + */
>> + is_opendrain = (ios->bus_mode == MMC_BUSMODE_OPENDRAIN);
>> + pins = pinctrl_lookup_state(host->pinctrl, is_opendrain ?
>
> How about doing the lookup in ->probe() instead? Then just select the
> state here, if supported?

ok

>
>> + MMCI_PINCTRL_STATE_OPENDRAIN :
>> + MMCI_PINCTRL_STATE_PUSHPULL);
>> + if (IS_ERR(pins))
>> + dev_warn(mmc_dev(mmc), "Cannot select pin drive type via pinctrl\n");
>> + else
>> + pinctrl_select_state(host->pinctrl, pins);
>> }
>>
>> /*
>> @@ -1609,6 +1637,14 @@ static int mmci_probe(struct amba_device *dev,
>> host = mmc_priv(mmc);
>> host->mmc = mmc;
>>
>> + if (!variant->opendrain) {
>> + host->pinctrl = devm_pinctrl_get(&dev->dev);
>> + if (IS_ERR(host->pinctrl)) {
>> + dev_err(&dev->dev, "failed to get pinctrl");
>> + goto host_free;
>> + }
>> + }
>> +
>> host->hw_designer = amba_manf(dev);
>> host->hw_revision = amba_rev(dev);
>> dev_dbg(mmc_dev(mmc), "designer ID = 0x%02x\n", host->hw_designer);
>> diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h
>> index 83160a9..de3d0b3 100644
>> --- a/drivers/mmc/host/mmci.h
>> +++ b/drivers/mmc/host/mmci.h
>> @@ -192,6 +192,10 @@
>>
>> #define NR_SG 128
>>
>> +/* pinctrl configs */
>> +#define MMCI_PINCTRL_STATE_PUSHPULL "default"
>
> Seems like we should be able to cope fine without having to add a
> separate define for the PUSHPULL, but rather just select the default
> state instead.

yes agree

Thanks

Patrice

>
>> +#define MMCI_PINCTRL_STATE_OPENDRAIN "opendrain"
>> +
>> struct clk;
>> struct variant_data;
>> struct dma_chan;
>> @@ -227,6 +231,7 @@ struct mmci_host {
>> bool vqmmc_enabled;
>> struct mmci_platform_data *plat;
>> struct variant_data *variant;
>> + struct pinctrl *pinctrl;
>>
>> u8 hw_designer;
>> u8 hw_revision:4;
>> --
>> 1.9.1
>>
>
> Kind regards
> Uffe
>

2018-01-16 07:38:38

by Linus Walleij

[permalink] [raw]
Subject: Re: [PATCH 04/14] mmc: mmci: Add STM32 variant

On Mon, Jan 15, 2018 at 6:17 PM, Patrice CHOTARD <[email protected]> wrote:

>>> + {
>>> + .id = 0x00880180,
>>> + .mask = 0x00ffffff,
>>> + .data = &variant_stm32,
>>> + },
>>
>> Since ux500 was 480180 I wonder what variants 5,6,7 are...
>
> What is the rule to define the id ?

These four bits mean "revision".

The number comes from hardware, so the ST ASIC department
has some person who is responsible for revising the VHDL or
Verilog code that this hardware is compiled from, and that person
is bumping the version.

Theoretically it is a "company function" or something bureaucratic
like that updating the hardware so I guess it could be several
people following procedure who have updated this number in the
hardware over the years.

But I bet it is a single person in Grenoble who has been doing
the MMC/SD block since it appeared.

Yours,
Linus Walleij