diff options
author | Olof Johansson <olof@lixom.net> | 2020-02-24 09:57:04 -0800 |
---|---|---|
committer | Olof Johansson <olof@lixom.net> | 2020-02-24 09:57:05 -0800 |
commit | f1e4920fe3303aa983073197bcbc97d6c6119ba7 (patch) | |
tree | 80b14e248920ccfbd2a841f32320a3e020fee436 /drivers | |
parent | 515fa3ee9de2b1543250ae47685e1b7e05a7a8ef (diff) | |
parent | f10e58a5d20e1cf3a39a842da92c9dd0c3c23849 (diff) |
Merge tag 'imx-fixes-5.6' of git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux into arm/fixes
i.MX fixes for 5.6:
- Build v7_cpu_resume() unconditionally to fix system hang in case that
suspend is disabled but cpuidle support is enabled.
- Drop unexisting Ethernet PHY device from imx8qxp-mek board.
- Fix SRAM compatible strings on imx6dl-colibri-eval-v3 board.
- Fix imx-scu driver to make sure that all messages words are written
sequentially.
- A series from Leonard Crestez to fix i.MX SC API users, having all
messages aligned on 4 bytes.
- Fix eMMC supply for phycore-som board.
- Drop bogus frequency setting from imx7-colibri SD/MMC device, so that
HS200 mode starts working and delivers better performance.
- Fix opp-supported-hw for i.MX7D to get consumer and industrial parts
work with correct frequency settings.
- Restore MDIO compatible to the correct one for LS1021A SoC.
* tag 'imx-fixes-5.6' of git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux:
soc: imx-scu: Align imx sc msg structs to 4
firmware: imx: Align imx_sc_msg_req_cpu_start to 4
firmware: imx: scu-pd: Align imx sc msg structs to 4
firmware: imx: misc: Align imx sc msg structs to 4
firmware: imx: scu: Ensure sequential TX
ARM: dts: imx7-colibri: Fix frequency for sd/mmc
arm64: dts: imx8qxp-mek: Remove unexisting Ethernet PHY
ARM: dts: imx6dl-colibri-eval-v3: fix sram compatible properties
ARM: dts: ls1021a: Restore MDIO compatible to gianfar
ARM: dts: imx7d: fix opp-supported-hw
ARM: imx: build v7_cpu_resume() unconditionally
ARM: dts: imx6: phycore-som: fix emmc supply
Link: https://lore.kernel.org/r/20200224120334.GH27688@dragon
Signed-off-by: Olof Johansson <olof@lixom.net>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/firmware/imx/imx-scu.c | 27 | ||||
-rw-r--r-- | drivers/firmware/imx/misc.c | 8 | ||||
-rw-r--r-- | drivers/firmware/imx/scu-pd.c | 2 | ||||
-rw-r--r-- | drivers/soc/imx/soc-imx-scu.c | 2 |
4 files changed, 33 insertions, 6 deletions
diff --git a/drivers/firmware/imx/imx-scu.c b/drivers/firmware/imx/imx-scu.c index 03b43b7a6d1d..f71eaa5bf52d 100644 --- a/drivers/firmware/imx/imx-scu.c +++ b/drivers/firmware/imx/imx-scu.c @@ -29,6 +29,7 @@ struct imx_sc_chan { struct mbox_client cl; struct mbox_chan *ch; int idx; + struct completion tx_done; }; struct imx_sc_ipc { @@ -100,6 +101,14 @@ int imx_scu_get_handle(struct imx_sc_ipc **ipc) } EXPORT_SYMBOL(imx_scu_get_handle); +/* Callback called when the word of a message is ack-ed, eg read by SCU */ +static void imx_scu_tx_done(struct mbox_client *cl, void *mssg, int r) +{ + struct imx_sc_chan *sc_chan = container_of(cl, struct imx_sc_chan, cl); + + complete(&sc_chan->tx_done); +} + static void imx_scu_rx_callback(struct mbox_client *c, void *msg) { struct imx_sc_chan *sc_chan = container_of(c, struct imx_sc_chan, cl); @@ -149,6 +158,19 @@ static int imx_scu_ipc_write(struct imx_sc_ipc *sc_ipc, void *msg) for (i = 0; i < hdr->size; i++) { sc_chan = &sc_ipc->chans[i % 4]; + + /* + * SCU requires that all messages words are written + * sequentially but linux MU driver implements multiple + * independent channels for each register so ordering between + * different channels must be ensured by SCU API interface. + * + * Wait for tx_done before every send to ensure that no + * queueing happens at the mailbox channel level. + */ + wait_for_completion(&sc_chan->tx_done); + reinit_completion(&sc_chan->tx_done); + ret = mbox_send_message(sc_chan->ch, &data[i]); if (ret < 0) return ret; @@ -247,6 +269,11 @@ static int imx_scu_probe(struct platform_device *pdev) cl->knows_txdone = true; cl->rx_callback = imx_scu_rx_callback; + /* Initial tx_done completion as "done" */ + cl->tx_done = imx_scu_tx_done; + init_completion(&sc_chan->tx_done); + complete(&sc_chan->tx_done); + sc_chan->sc_ipc = sc_ipc; sc_chan->idx = i % 4; sc_chan->ch = mbox_request_channel_byname(cl, chan_name); diff --git a/drivers/firmware/imx/misc.c b/drivers/firmware/imx/misc.c index 4b56a587dacd..d073cb3ce699 100644 --- a/drivers/firmware/imx/misc.c +++ b/drivers/firmware/imx/misc.c @@ -16,7 +16,7 @@ struct imx_sc_msg_req_misc_set_ctrl { u32 ctrl; u32 val; u16 resource; -} __packed; +} __packed __aligned(4); struct imx_sc_msg_req_cpu_start { struct imx_sc_rpc_msg hdr; @@ -24,18 +24,18 @@ struct imx_sc_msg_req_cpu_start { u32 address_lo; u16 resource; u8 enable; -} __packed; +} __packed __aligned(4); struct imx_sc_msg_req_misc_get_ctrl { struct imx_sc_rpc_msg hdr; u32 ctrl; u16 resource; -} __packed; +} __packed __aligned(4); struct imx_sc_msg_resp_misc_get_ctrl { struct imx_sc_rpc_msg hdr; u32 val; -} __packed; +} __packed __aligned(4); /* * This function sets a miscellaneous control value. diff --git a/drivers/firmware/imx/scu-pd.c b/drivers/firmware/imx/scu-pd.c index b556612207e5..af3ae0087de4 100644 --- a/drivers/firmware/imx/scu-pd.c +++ b/drivers/firmware/imx/scu-pd.c @@ -61,7 +61,7 @@ struct imx_sc_msg_req_set_resource_power_mode { struct imx_sc_rpc_msg hdr; u16 resource; u8 mode; -} __packed; +} __packed __aligned(4); #define IMX_SCU_PD_NAME_SIZE 20 struct imx_sc_pm_domain { diff --git a/drivers/soc/imx/soc-imx-scu.c b/drivers/soc/imx/soc-imx-scu.c index fb70b8a3f7c5..20d37eaeb5f2 100644 --- a/drivers/soc/imx/soc-imx-scu.c +++ b/drivers/soc/imx/soc-imx-scu.c @@ -25,7 +25,7 @@ struct imx_sc_msg_misc_get_soc_id { u32 id; } resp; } data; -} __packed; +} __packed __aligned(4); struct imx_sc_msg_misc_get_soc_uid { struct imx_sc_rpc_msg hdr; |