Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 3/3] sdhci: arasan: Add support to read Tap Delay values from DT
From: Manish Narani @ 2018-06-07 12:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1528373500-24663-1-git-send-email-manish.narani@xilinx.com>

This patch adds support for reading Tap Delay values from Device Tree
and write them via eemi calls. The macros containing these tap delay
values are removed from the driver.

Signed-off-by: Manish Narani <manish.narani@xilinx.com>
---
 drivers/mmc/host/sdhci-of-arasan.c | 131 +++++++++++++++++++++++++++++++++++++
 1 file changed, 131 insertions(+)

diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c
index e3332a5..fc0fd01 100644
--- a/drivers/mmc/host/sdhci-of-arasan.c
+++ b/drivers/mmc/host/sdhci-of-arasan.c
@@ -36,6 +36,8 @@

 #define PHY_CLK_TOO_SLOW_HZ            400000

+#define MMC_BANK2              0x2
+
 /*
  * On some SoCs the syscon area has a feature where the upper 16-bits of
  * each 32-bit register act as a write mask for the lower 16-bits.  This allows
@@ -90,6 +92,10 @@ struct sdhci_arasan_data {
        struct sdhci_host *host;
        struct clk      *clk_ahb;
        struct phy      *phy;
+       u32 mio_bank;
+       u32 device_id;
+       u32 itapdly[MMC_TIMING_MMC_HS400 + 1];
+       u32 otapdly[MMC_TIMING_MMC_HS400 + 1];
        bool            is_phy_on;

        bool            has_cqe;
@@ -160,11 +166,36 @@ static int sdhci_arasan_syscon_write(struct sdhci_host *host,
        return ret;
 }

+/**
+ * arasan_zynqmp_set_tap_delay - Program the tap delays.
+ * @deviceid:          Unique Id of device
+ * @itap_delay:                Input Tap Delay
+ * @oitap_delay:       Output Tap Delay
+ */
+static void arasan_zynqmp_set_tap_delay(u8 deviceid, u8 itap_delay, u8 otap_delay)
+{
+       const struct zynqmp_eemi_ops *eemi_ops = zynqmp_pm_get_eemi_ops();
+       u32 node_id = (deviceid == 0) ? NODE_SD_0 : NODE_SD_1;
+
+       if (!eemi_ops || !eemi_ops->ioctl)
+               return;
+
+       if (itap_delay)
+               eemi_ops->ioctl(node_id, IOCTL_SET_SD_TAPDELAY,
+                               PM_TAPDELAY_INPUT, itap_delay, NULL);
+
+       if (otap_delay)
+               eemi_ops->ioctl(node_id, IOCTL_SET_SD_TAPDELAY,
+                               PM_TAPDELAY_OUTPUT, otap_delay, NULL);
+}
+
 static void sdhci_arasan_set_clock(struct sdhci_host *host, unsigned int clock)
 {
        struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
        struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host);
        bool ctrl_phy = false;
+       u8 itap_delay;
+       u8 otap_delay;

        if (!IS_ERR(sdhci_arasan->phy)) {
                if (!sdhci_arasan->is_phy_on && clock <= PHY_CLK_TOO_SLOW_HZ) {
@@ -200,6 +231,16 @@ static void sdhci_arasan_set_clock(struct sdhci_host *host, unsigned int clock)
                }
        }

+       if (host->version >= SDHCI_SPEC_300) {
+               if ((host->timing != MMC_TIMING_LEGACY) &&
+                       (host->timing != MMC_TIMING_UHS_SDR12)) {
+                       itap_delay = sdhci_arasan->itapdly[host->timing];
+                       otap_delay = sdhci_arasan->otapdly[host->timing];
+                       arasan_zynqmp_set_tap_delay(sdhci_arasan->device_id,
+                                                   itap_delay, otap_delay);
+               }
+       }
+
        if (ctrl_phy && sdhci_arasan->is_phy_on) {
                phy_power_off(sdhci_arasan->phy);
                sdhci_arasan->is_phy_on = false;
@@ -456,6 +497,7 @@ static const struct of_device_id sdhci_arasan_of_match[] = {
        { .compatible = "arasan,sdhci-8.9a" },
        { .compatible = "arasan,sdhci-5.1" },
        { .compatible = "arasan,sdhci-4.9a" },
+       { .compatible = "xlnx,zynqmp-8.9a" },

        { /* sentinel */ }
 };
@@ -641,6 +683,74 @@ static void sdhci_arasan_unregister_sdclk(struct device *dev)
        of_clk_del_provider(dev->of_node);
 }

+/**
+ * arasan_zynqmp_dt_parse_tap_delays - Read Tap Delay values from DT
+ *
+ * Called at initialization to parse the values of Tap Delays.
+ *
+ * @dev:               Pointer to our struct device.
+ */
+static void arasan_zynqmp_dt_parse_tap_delays(struct device *dev)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct sdhci_host *host = platform_get_drvdata(pdev);
+       struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+       struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host);
+       struct device_node *np = dev->of_node;
+
+       of_property_read_u32(np, "xlnx,itap_delay_sd_hsd",
+                            &sdhci_arasan->itapdly[MMC_TIMING_SD_HS]);
+       of_property_read_u32(np, "xlnx,otap_delay_sd_hsd",
+                            &sdhci_arasan->otapdly[MMC_TIMING_SD_HS]);
+       of_property_read_u32(np, "xlnx,itap_delay_sdr25",
+                            &sdhci_arasan->itapdly[MMC_TIMING_UHS_SDR25]);
+       of_property_read_u32(np, "xlnx,otap_delay_sdr25",
+                            &sdhci_arasan->otapdly[MMC_TIMING_UHS_SDR25]);
+       of_property_read_u32(np, "xlnx,itap_delay_sdr50",
+                            &sdhci_arasan->itapdly[MMC_TIMING_UHS_SDR50]);
+       of_property_read_u32(np, "xlnx,otap_delay_sdr50",
+                            &sdhci_arasan->otapdly[MMC_TIMING_UHS_SDR50]);
+       of_property_read_u32(np, "xlnx,itap_delay_sd_ddr50",
+                            &sdhci_arasan->itapdly[MMC_TIMING_UHS_DDR50]);
+       of_property_read_u32(np, "xlnx,otap_delay_sd_ddr50",
+                            &sdhci_arasan->otapdly[MMC_TIMING_UHS_DDR50]);
+       of_property_read_u32(np, "xlnx,itap_delay_mmc_hsd",
+                            &sdhci_arasan->itapdly[MMC_TIMING_MMC_HS]);
+       of_property_read_u32(np, "xlnx,otap_delay_mmc_hsd",
+                            &sdhci_arasan->otapdly[MMC_TIMING_MMC_HS]);
+       of_property_read_u32(np, "xlnx,itap_delay_mmc_ddr50",
+                            &sdhci_arasan->itapdly[MMC_TIMING_MMC_DDR52]);
+       of_property_read_u32(np, "xlnx,otap_delay_mmc_ddr50",
+                            &sdhci_arasan->otapdly[MMC_TIMING_MMC_DDR52]);
+       if (sdhci_arasan->mio_bank == MMC_BANK2) {
+               of_property_read_u32(np,
+                                    "xlnx,itap_delay_sdr104_b2",
+                               &sdhci_arasan->itapdly[MMC_TIMING_UHS_SDR104]);
+               of_property_read_u32(np,
+                                    "xlnx,otap_delay_sdr104_b2",
+                               &sdhci_arasan->otapdly[MMC_TIMING_UHS_SDR104]);
+               of_property_read_u32(np,
+                                    "xlnx,itap_delay_mmc_hs200_b2",
+                               &sdhci_arasan->itapdly[MMC_TIMING_MMC_HS200]);
+               of_property_read_u32(np,
+                                    "xlnx,otap_delay_mmc_hs200_b2",
+                               &sdhci_arasan->otapdly[MMC_TIMING_MMC_HS200]);
+       } else {
+               of_property_read_u32(np,
+                                    "xlnx,itap_delay_sdr104_b0",
+                               &sdhci_arasan->itapdly[MMC_TIMING_UHS_SDR104]);
+               of_property_read_u32(np,
+                                    "xlnx,otap_delay_sdr104_b0",
+                               &sdhci_arasan->otapdly[MMC_TIMING_UHS_SDR104]);
+               of_property_read_u32(np,
+                                    "xlnx,itap_delay_mmc_hs200_b0",
+                               &sdhci_arasan->itapdly[MMC_TIMING_MMC_HS200]);
+               of_property_read_u32(np,
+                                    "xlnx,otap_delay_mmc_hs200_b0",
+                               &sdhci_arasan->otapdly[MMC_TIMING_MMC_HS200]);
+       }
+}
+
 static int sdhci_arasan_add_host(struct sdhci_arasan_data *sdhci_arasan)
 {
        struct sdhci_host *host = sdhci_arasan->host;
@@ -776,6 +886,27 @@ static int sdhci_arasan_probe(struct platform_device *pdev)
                goto unreg_clk;
        }

+       if (of_device_is_compatible(pdev->dev.of_node,
+                                   "xlnx,zynqmp-8.9a")) {
+               ret = of_property_read_u32(pdev->dev.of_node,
+                                          "xlnx,mio_bank",
+                                          &sdhci_arasan->mio_bank);
+               if (ret < 0) {
+                       dev_err(&pdev->dev,
+                               "\"xlnx,mio_bank \" property is missing.\n");
+                       goto clk_disable_all;
+               }
+               ret = of_property_read_u32(pdev->dev.of_node,
+                                          "xlnx,device_id",
+                                          &sdhci_arasan->device_id);
+               if (ret < 0) {
+                       dev_err(&pdev->dev,
+                               "\"xlnx,device_id \" property is missing.\n");
+                       goto clk_disable_all;
+               }
+               arasan_zynqmp_dt_parse_tap_delays(&pdev->dev);
+       }
+
        sdhci_arasan->phy = ERR_PTR(-ENODEV);
        if (of_device_is_compatible(pdev->dev.of_node,
                                    "arasan,sdhci-5.1")) {
--
2.7.4

This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

^ permalink raw reply related

* [RFC PATCH 2/3] dt: bindings: Add SD tap value properties details
From: Manish Narani @ 2018-06-07 12:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1528373500-24663-1-git-send-email-manish.narani@xilinx.com>

This patch adds details of SD tap value properties in device tree.

Signed-off-by: Manish Narani <manish.narani@xilinx.com>
---
 .../devicetree/bindings/mmc/arasan,sdhci.txt       | 26 ++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt
index 60481bf..0e08877 100644
--- a/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt
+++ b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt
@@ -15,6 +15,8 @@ Required Properties:
     - "arasan,sdhci-5.1": generic Arasan SDHCI 5.1 PHY
     - "rockchip,rk3399-sdhci-5.1", "arasan,sdhci-5.1": rk3399 eMMC PHY
       For this device it is strongly suggested to include arasan,soc-ctl-syscon.
+    - "xlnx,zynqmp-8.9a": Xilinx ZynqMP Arasan SDHCI 8.9a PHY
+      For this device it is strongly suggested to include arasan,soc-ctl-syscon.
   - reg: From mmc bindings: Register location and length.
   - clocks: From clock bindings: Handles to clock inputs.
   - clock-names: From clock bindings: Tuple including "clk_xin" and "clk_ahb"
@@ -26,6 +28,30 @@ Required Properties for "arasan,sdhci-5.1":
   - phys: From PHY bindings: Phandle for the Generic PHY for arasan.
   - phy-names:  MUST be "phy_arasan".

+Required Properties for "xlnx,zynqmp-8.9a":
+  - xlnx,mio_bank: The value will be 0/1/2 depending on MIO bank selection.
+  - xlnx,device_id: Unique Id of the device, value will be 0/1.
+  - xlnx,itap_delay_sd_hsd: Input Tap Delay for SD HS.
+  - xlnx,itap_delay_sdr25: Input Tap Delay for SDR25.
+  - xlnx,itap_delay_sdr50: Input Tap Delay for SDR50.
+  - xlnx,itap_delay_sdr104_b0: Input Tap Delay for SDR104.
+  - xlnx,itap_delay_sdr104_b2: Input Tap Delay for SDR104.
+  - xlnx,itap_delay_sd_ddr50: Input Tap Delay for SD DDR50.
+  - xlnx,itap_delay_mmc_hsd: Input Tap Delay for MMC HS.
+  - xlnx,itap_delay_mmc_ddr50: Input Tap Delay for MMC DDR50.
+  - xlnx,itap_delay_mmc_hs200_b0: Input Tap Delay for MMC HS200.
+  - xlnx,itap_delay_mmc_hs200_b2: Input Tap Delay for MMC HS200.
+  - xlnx,otap_delay_sd_hsd: Output Tap Delay for SD HS.
+  - xlnx,otap_delay_sdr25: Output Tap Delay for SDR25.
+  - xlnx,otap_delay_sdr50: Output Tap Delay for SDR50.
+  - xlnx,otap_delay_sdr104_b0: Output Tap Delay for SDR104.
+  - xlnx,otap_delay_sdr104_b2: Output Tap Delay for SDR104.
+  - xlnx,otap_delay_sd_ddr50: Output Tap Delay for DDR50.
+  - xlnx,otap_delay_mmc_hsd: Output Tap Delay for MMC HS.
+  - xlnx,otap_delay_mmc_ddr50: Output Tap Delay for MMC DDR50.
+  - xlnx,otap_delay_mmc_hs200_b0: Output Tap Delay for MMC HS200.
+  - xlnx,otap_delay_mmc_hs200_b2: Output Tap Delay for MMC HS200.
+
 Optional Properties:
   - arasan,soc-ctl-syscon: A phandle to a syscon device (see ../mfd/syscon.txt)
     used to access core corecfg registers.  Offsets of registers in this
--
2.7.4

This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

^ permalink raw reply related

* [RFC PATCH 1/3] arm64: zynqmp: dt: Add support for setting SD tap delays
From: Manish Narani @ 2018-06-07 12:11 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds support for setting SD tap delays from Device Tree.
Earlier, these tap values were made static via macros in the driver.
So changing the tap values in the device tree makes the driver free
from handling different tap values inside it.

Signed-off-by: Manish Narani <manish.narani@xilinx.com>
---
 arch/arm64/boot/dts/xilinx/zynqmp.dtsi | 40 ++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
index a091e6f..696aac8 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
+++ b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
@@ -491,6 +491,26 @@
                        interrupts = <0 48 4>;
                        reg = <0x0 0xff160000 0x0 0x1000>;
                        clock-names = "clk_xin", "clk_ahb";
+                       xlnx,itap_delay_sd_hsd = <0x15>;
+                       xlnx,otap_delay_sd_hsd = <0x5>;
+                       xlnx,itap_delay_sdr25 = <0x15>;
+                       xlnx,otap_delay_sdr25 = <0x5>;
+                       xlnx,itap_delay_sdr50 = <0>;
+                       xlnx,otap_delay_sdr50 = <0x3>;
+                       xlnx,itap_delay_sd_ddr50 = <0x3D>;
+                       xlnx,otap_delay_sd_ddr50 = <0x4>;
+                       xlnx,itap_delay_mmc_hsd = <0x15>;
+                       xlnx,otap_delay_mmc_hsd = <0x6>;
+                       xlnx,itap_delay_mmc_ddr50 = <0x12>;
+                       xlnx,otap_delay_mmc_ddr50 = <0x6>;
+                       xlnx,itap_delay_sdr104_b0 = <0>;
+                       xlnx,otap_delay_sdr104_b0 = <0x3>;
+                       xlnx,itap_delay_sdr104_b2 = <0>;
+                       xlnx,otap_delay_sdr104_b2 = <0x2>;
+                       xlnx,itap_delay_mmc_hs200_b0 = <0>;
+                       xlnx,otap_delay_mmc_hs200_b0 = <0x3>;
+                       xlnx,itap_delay_mmc_hs200_b2 = <0>;
+                       xlnx,otap_delay_mmc_hs200_b2 = <0x2>;
                };

                sdhci1: sdhci at ff170000 {
@@ -500,6 +520,26 @@
                        interrupts = <0 49 4>;
                        reg = <0x0 0xff170000 0x0 0x1000>;
                        clock-names = "clk_xin", "clk_ahb";
+                       xlnx,itap_delay_sd_hsd = <0x15>;
+                       xlnx,otap_delay_sd_hsd = <0x5>;
+                       xlnx,itap_delay_sdr25 = <0x15>;
+                       xlnx,otap_delay_sdr25 = <0x5>;
+                       xlnx,itap_delay_sdr50 = <0>;
+                       xlnx,otap_delay_sdr50 = <0x3>;
+                       xlnx,itap_delay_sd_ddr50 = <0x3D>;
+                       xlnx,otap_delay_sd_ddr50 = <0x4>;
+                       xlnx,itap_delay_mmc_hsd = <0x15>;
+                       xlnx,otap_delay_mmc_hsd = <0x6>;
+                       xlnx,itap_delay_mmc_ddr50 = <0x12>;
+                       xlnx,otap_delay_mmc_ddr50 = <0x6>;
+                       xlnx,itap_delay_sdr104_b0 = <0>;
+                       xlnx,otap_delay_sdr104_b0 = <0x3>;
+                       xlnx,itap_delay_sdr104_b2 = <0>;
+                       xlnx,otap_delay_sdr104_b2 = <0x2>;
+                       xlnx,itap_delay_mmc_hs200_b0 = <0>;
+                       xlnx,otap_delay_mmc_hs200_b0 = <0x3>;
+                       xlnx,itap_delay_mmc_hs200_b2 = <0>;
+                       xlnx,otap_delay_mmc_hs200_b2 = <0x2>;
                };

                smmu: smmu at fd800000 {
--
2.7.4

This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

^ permalink raw reply related

* [PATCH/RFT 2/2] arm64: dts: renesas: r8a77965: Add PCIe device nodes
From: Yoshihiro Kaneko @ 2018-06-07 12:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1528373494-18503-1-git-send-email-ykaneko0929@gmail.com>

From: Takeshi Kihara <takeshi.kihara.df@renesas.com>

This patch adds PCIe{0,1} device nodes to R8A77965 SoC.

Based on a similar patches of the R8A7796 device tree
by Harunobu Kurokawa <harunobu.kurokawa.dn@renesas.com>.

Signed-off-by: Takeshi Kihara <takeshi.kihara.df@renesas.com>
Signed-off-by: Yoshihiro Kaneko <ykaneko0929@gmail.com>
---
 arch/arm64/boot/dts/renesas/r8a77965.dtsi | 48 +++++++++++++++++++++++++++++--
 1 file changed, 46 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/renesas/r8a77965.dtsi b/arch/arm64/boot/dts/renesas/r8a77965.dtsi
index d740c79..0d39a31 100644
--- a/arch/arm64/boot/dts/renesas/r8a77965.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77965.dtsi
@@ -1433,13 +1433,57 @@
 		};
 
 		pciec0: pcie at fe000000 {
+			compatible = "renesas,pcie-r8a77965",
+				     "renesas,pcie-rcar-gen3";
 			reg = <0 0xfe000000 0 0x80000>;
-			/* placeholder */
+			#address-cells = <3>;
+			#size-cells = <2>;
+			bus-range = <0x00 0xff>;
+			device_type = "pci";
+			ranges = <0x01000000 0 0x00000000 0 0xfe100000 0 0x00100000
+				0x02000000 0 0xfe200000 0 0xfe200000 0 0x00200000
+				0x02000000 0 0x30000000 0 0x30000000 0 0x08000000
+				0x42000000 0 0x38000000 0 0x38000000 0 0x08000000>;
+			/* Map all possible DDR as inbound ranges */
+			dma-ranges = <0x42000000 0 0x40000000 0 0x40000000 0 0x80000000>;
+			interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 0>;
+			interrupt-map = <0 0 0 0 &gic GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 319>, <&pcie_bus_clk>;
+			clock-names = "pcie", "pcie_bus";
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 319>;
+			status = "disabled";
 		};
 
 		pciec1: pcie at ee800000 {
+			compatible = "renesas,pcie-r8a77965",
+				     "renesas,pcie-rcar-gen3";
 			reg = <0 0xee800000 0 0x80000>;
-			/* placeholder */
+			#address-cells = <3>;
+			#size-cells = <2>;
+			bus-range = <0x00 0xff>;
+			device_type = "pci";
+			ranges = <0x01000000 0 0x00000000 0 0xee900000 0 0x00100000
+				0x02000000 0 0xeea00000 0 0xeea00000 0 0x00200000
+				0x02000000 0 0xc0000000 0 0xc0000000 0 0x08000000
+				0x42000000 0 0xc8000000 0 0xc8000000 0 0x08000000>;
+			/* Map all possible DDR as inbound ranges */
+			dma-ranges = <0x42000000 0 0x40000000 0 0x40000000 0 0x80000000>;
+			interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>;
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 0>;
+			interrupt-map = <0 0 0 0 &gic GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 318>, <&pcie_bus_clk>;
+			clock-names = "pcie", "pcie_bus";
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 318>;
+			status = "disabled";
 		};
 
 		fcpf0: fcp at fe950000 {
-- 
1.9.1

^ permalink raw reply related

* [PATCH/RFT 1/2] PCI: rcar: Add compatible string for r8a77965
From: Yoshihiro Kaneko @ 2018-06-07 12:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1528373494-18503-1-git-send-email-ykaneko0929@gmail.com>

This patch adds support for r8a77965 (R-Car M3-N)

Signed-off-by: Yoshihiro Kaneko <ykaneko0929@gmail.com>
---
 Documentation/devicetree/bindings/pci/rcar-pci.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/pci/rcar-pci.txt b/Documentation/devicetree/bindings/pci/rcar-pci.txt
index 1fb614e..dd71cfe 100644
--- a/Documentation/devicetree/bindings/pci/rcar-pci.txt
+++ b/Documentation/devicetree/bindings/pci/rcar-pci.txt
@@ -8,6 +8,7 @@ compatible: "renesas,pcie-r8a7743" for the R8A7743 SoC;
 	    "renesas,pcie-r8a7793" for the R8A7793 SoC;
 	    "renesas,pcie-r8a7795" for the R8A7795 SoC;
 	    "renesas,pcie-r8a7796" for the R8A7796 SoC;
+	    "renesas,pcie-r8a77965" for the R8A77965 SoC;
 	    "renesas,pcie-rcar-gen2" for a generic R-Car Gen2 or
 				     RZ/G1 compatible device.
 	    "renesas,pcie-rcar-gen3" for a generic R-Car Gen3 compatible device.
-- 
1.9.1

^ permalink raw reply related

* [PATCH/RFT 0/2] Add PCIe support for r8a77965
From: Yoshihiro Kaneko @ 2018-06-07 12:11 UTC (permalink / raw)
  To: linux-arm-kernel

This series adds PCIe support for r8a77965 (R-Car M3-N).
It is not necessary to update driver and PFC.

This series is based on the devel branch of Simon Horman's renesas tree.

Takeshi Kihara (1):
  arm64: dts: renesas: r8a77965: Add PCIe device nodes

Yoshihiro Kaneko (1):
  PCI: rcar: Add compatible string for r8a77965

 Documentation/devicetree/bindings/pci/rcar-pci.txt |  1 +
 arch/arm64/boot/dts/renesas/r8a77965.dtsi          | 48 +++++++++++++++++++++-
 2 files changed, 47 insertions(+), 2 deletions(-)

-- 
1.9.1

^ permalink raw reply

* [PATCH 1/2] arm64: avoid alloc memory on offline node
From: Hanjun Guo @ 2018-06-07 11:55 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180607105514.GA13139@dhcp22.suse.cz>

On 2018/6/7 18:55, Michal Hocko wrote:
> On Wed 06-06-18 15:39:34, Bjorn Helgaas wrote:
>> [+cc akpm, linux-mm, linux-pci]
>>
>> On Wed, Jun 6, 2018 at 10:44 AM Will Deacon <will.deacon@arm.com> wrote:
>>>
>>> On Thu, May 31, 2018 at 08:14:38PM +0800, Xie XiuQi wrote:
>>>> A numa system may return node which is not online.
>>>> For example, a numa node:
>>>> 1) without memory
>>>> 2) NR_CPUS is very small, and the cpus on the node are not brought up
>>>>
>>>> In this situation, we use NUMA_NO_NODE to avoid oops.
>>>>
>>>> [   25.732905] Unable to handle kernel NULL pointer dereference at virtual address 00001988
>>>> [   25.740982] Mem abort info:
>>>> [   25.743762]   ESR = 0x96000005
>>>> [   25.746803]   Exception class = DABT (current EL), IL = 32 bits
>>>> [   25.752711]   SET = 0, FnV = 0
>>>> [   25.755751]   EA = 0, S1PTW = 0
>>>> [   25.758878] Data abort info:
>>>> [   25.761745]   ISV = 0, ISS = 0x00000005
>>>> [   25.765568]   CM = 0, WnR = 0
>>>> [   25.768521] [0000000000001988] user address but active_mm is swapper
>>>> [   25.774861] Internal error: Oops: 96000005 [#1] SMP
>>>> [   25.779724] Modules linked in:
>>>> [   25.782768] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 4.17.0-rc6-mpam+ #115
>>>> [   25.789714] Hardware name: Huawei D06/D06, BIOS Hisilicon D06 EC UEFI Nemo 2.0 RC0 - B305 05/28/2018
>>>> [   25.798831] pstate: 80c00009 (Nzcv daif +PAN +UAO)
>>>> [   25.803612] pc : __alloc_pages_nodemask+0xf0/0xe70
>>>> [   25.808389] lr : __alloc_pages_nodemask+0x184/0xe70
>>>> [   25.813252] sp : ffff00000996f660
>>>> [   25.816553] x29: ffff00000996f660 x28: 0000000000000000
>>>> [   25.821852] x27: 00000000014012c0 x26: 0000000000000000
>>>> [   25.827150] x25: 0000000000000003 x24: ffff000008099eac
>>>> [   25.832449] x23: 0000000000400000 x22: 0000000000000000
>>>> [   25.837747] x21: 0000000000000001 x20: 0000000000000000
>>>> [   25.843045] x19: 0000000000400000 x18: 0000000000010e00
>>>> [   25.848343] x17: 000000000437f790 x16: 0000000000000020
>>>> [   25.853641] x15: 0000000000000000 x14: 6549435020524541
>>>> [   25.858939] x13: 20454d502067756c x12: 0000000000000000
>>>> [   25.864237] x11: ffff00000996f6f0 x10: 0000000000000006
>>>> [   25.869536] x9 : 00000000000012a4 x8 : ffff8023c000ff90
>>>> [   25.874834] x7 : 0000000000000000 x6 : ffff000008d73c08
>>>> [   25.880132] x5 : 0000000000000000 x4 : 0000000000000081
>>>> [   25.885430] x3 : 0000000000000000 x2 : 0000000000000000
>>>> [   25.890728] x1 : 0000000000000001 x0 : 0000000000001980
>>>> [   25.896027] Process swapper/0 (pid: 1, stack limit = 0x        (ptrval))
>>>> [   25.902712] Call trace:
>>>> [   25.905146]  __alloc_pages_nodemask+0xf0/0xe70
>>>> [   25.909577]  allocate_slab+0x94/0x590
>>>> [   25.913225]  new_slab+0x68/0xc8
>>>> [   25.916353]  ___slab_alloc+0x444/0x4f8
>>>> [   25.920088]  __slab_alloc+0x50/0x68
>>>> [   25.923562]  kmem_cache_alloc_node_trace+0xe8/0x230
>>>> [   25.928426]  pci_acpi_scan_root+0x94/0x278
>>>> [   25.932510]  acpi_pci_root_add+0x228/0x4b0
>>>> [   25.936593]  acpi_bus_attach+0x10c/0x218
>>>> [   25.940501]  acpi_bus_attach+0xac/0x218
>>>> [   25.944323]  acpi_bus_attach+0xac/0x218
>>>> [   25.948144]  acpi_bus_scan+0x5c/0xc0
>>>> [   25.951708]  acpi_scan_init+0xf8/0x254
>>>> [   25.955443]  acpi_init+0x310/0x37c
>>>> [   25.958831]  do_one_initcall+0x54/0x208
>>>> [   25.962653]  kernel_init_freeable+0x244/0x340
>>>> [   25.966999]  kernel_init+0x18/0x118
>>>> [   25.970474]  ret_from_fork+0x10/0x1c
>>>> [   25.974036] Code: 7100047f 321902a4 1a950095 b5000602 (b9400803)
>>>> [   25.980162] ---[ end trace 64f0893eb21ec283 ]---
>>>> [   25.984765] Kernel panic - not syncing: Fatal exception
>>>>
>>>> Signed-off-by: Xie XiuQi <xiexiuqi@huawei.com>
>>>> Tested-by: Huiqiang Wang <wanghuiqiang@huawei.com>
>>>> Cc: Hanjun Guo <hanjun.guo@linaro.org>
>>>> Cc: Tomasz Nowicki <Tomasz.Nowicki@caviumnetworks.com>
>>>> Cc: Xishi Qiu <qiuxishi@huawei.com>
>>>> ---
>>>>  arch/arm64/kernel/pci.c | 3 +++
>>>>  1 file changed, 3 insertions(+)
>>>>
>>>> diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c
>>>> index 0e2ea1c..e17cc45 100644
>>>> --- a/arch/arm64/kernel/pci.c
>>>> +++ b/arch/arm64/kernel/pci.c
>>>> @@ -170,6 +170,9 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
>>>>       struct pci_bus *bus, *child;
>>>>       struct acpi_pci_root_ops *root_ops;
>>>>
>>>> +     if (node != NUMA_NO_NODE && !node_online(node))
>>>> +             node = NUMA_NO_NODE;
>>>> +
>>>
>>> This really feels like a bodge, but it does appear to be what other
>>> architectures do, so:
>>>
>>> Acked-by: Will Deacon <will.deacon@arm.com>
>>
>> I agree, this doesn't feel like something we should be avoiding in the
>> caller of kzalloc_node().
>>
>> I would not expect kzalloc_node() to return memory that's offline, no
>> matter what node we told it to allocate from.  I could imagine it
>> returning failure, or returning memory from a node that *is* online,
>> but returning a pointer to offline memory seems broken.
>>
>> Are we putting memory that's offline in the free list?  I don't know
>> where to look to figure this out.
> 
> I am not sure I have the full context but pci_acpi_scan_root calls
> kzalloc_node(sizeof(*info), GFP_KERNEL, node)
> and that should fall back to whatever node that is online. Offline node
> shouldn't keep any pages behind. So there must be something else going
> on here and the patch is not the right way to handle it. What does
> faddr2line __alloc_pages_nodemask+0xf0 tells on this kernel?

The whole context is:

The system is booted with a NUMA node has no memory attaching to it
(memory-less NUMA node), also with NR_CPUS less than CPUs presented
in MADT, so CPUs on this memory-less node are not brought up, and
this NUMA node will not be online (but SRAT presents this NUMA node);

Devices attaching to this NUMA node such as PCI host bridge still
return the valid NUMA node via _PXM, but actually that valid NUMA node
is not online which lead to this issue.

Thanks
Hanjun

> 

^ permalink raw reply

* [RFC PATCH -tip v5 24/27] bpf: error-inject: kprobes: Clear current_kprobe and enable preempt in kprobe
From: Naveen N. Rao @ 2018-06-07 11:42 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <152812800822.10068.3306094708706993432.stgit@devbox>

Masami Hiramatsu wrote:
> Clear current_kprobe and enable preemption in kprobe
> even if pre_handler returns !0.
> 
> This simplifies function override using kprobes.
> 
> Jprobe used to require to keep the preemption disabled and
> keep current_kprobe until it returned to original function
> entry. For this reason kprobe_int3_handler() and similar
> arch dependent kprobe handers checks pre_handler result
> and exit without enabling preemption if the result is !0.
> 
> After removing the jprobe, Kprobes does not need to
> keep preempt disabled even if user handler returns !0
> anymore.
> 
> But since the function override handler in error-inject
> and bpf is also returns !0 if it overrides a function,
> to balancing the preempt count, it enables preemption
> and reset current kprobe by itself.
> 
> That is a bad design that is very buggy. This fixes
> such unbalanced preempt-count and current_kprobes setting
> in kprobes, bpf and error-inject.
> 
> Note: for powerpc and x86, this removes all preempt_disable
> from kprobe_ftrace_handler because ftrace callbacks are
> called under preempt disabled.
> 
> Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
> Cc: Vineet Gupta <vgupta@synopsys.com>
> Cc: Russell King <linux@armlinux.org.uk>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Cc: Tony Luck <tony.luck@intel.com>
> Cc: Fenghua Yu <fenghua.yu@intel.com>
> Cc: Ralf Baechle <ralf@linux-mips.org>
> Cc: James Hogan <jhogan@kernel.org>
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Paul Mackerras <paulus@samba.org>
> Cc: Michael Ellerman <mpe@ellerman.id.au>
> Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
> Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
> Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
> Cc: Rich Felker <dalias@libc.org>
> Cc: "David S. Miller" <davem@davemloft.net>
> Cc: "Naveen N. Rao" <naveen.n.rao@linux.vnet.ibm.com>
> Cc: Josef Bacik <jbacik@fb.com>
> Cc: Alexei Starovoitov <ast@kernel.org>
> Cc: x86 at kernel.org
> Cc: linux-snps-arc at lists.infradead.org
> Cc: linux-kernel at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-ia64 at vger.kernel.org
> Cc: linux-mips at linux-mips.org
> Cc: linuxppc-dev at lists.ozlabs.org
> Cc: linux-s390 at vger.kernel.org
> Cc: linux-sh at vger.kernel.org
> Cc: sparclinux at vger.kernel.org
> ---
>  Changes in v5:
>   - Fix kprobe_ftrace_handler in arch/powerpc too.
> ---
>  arch/arc/kernel/kprobes.c            |    5 +++--
>  arch/arm/probes/kprobes/core.c       |   10 +++++-----
>  arch/arm64/kernel/probes/kprobes.c   |   10 +++++-----
>  arch/ia64/kernel/kprobes.c           |   13 ++++---------
>  arch/mips/kernel/kprobes.c           |    4 ++--
>  arch/powerpc/kernel/kprobes-ftrace.c |   15 ++++++---------
>  arch/powerpc/kernel/kprobes.c        |    7 +++++--

For the powerpc bits:
Acked-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>

Thanks,
Naveen

^ permalink raw reply

* [PATCH] arm64: Fix syscall restarting around signal suppressed by tracer
From: Dave Martin @ 2018-06-07 11:32 UTC (permalink / raw)
  To: linux-arm-kernel

Commit 17c2895 ("arm64: Abstract syscallno manipulation") abstracts
out the pt_regs.syscallno value for a syscall cancelled by a tracer
as NO_SYSCALL, and provides helpers to set and check for this
condition.  However, the way this was implemented has the
unintended side-effect of disabling part of the syscall restart
logic.

This comes about because the second in_syscall() check in
do_signal() re-evaluates the "in a syscall" condition based on the
updated pt_regs instead of the original pt_regs.  forget_syscall()
is explicitly called prior to the second check in order to prevent
restart logic in the ret_to_user path being spuriously triggered,
which means that the second in_syscall() check always yields false.

This triggers a failure in
tools/testing/selftests/seccomp/seccomp_bpf.c, when using ptrace to
suppress a signal that interrups a nanosleep() syscall.

Misbehaviour of this type is only expected in the case where a
tracer suppresses a signal and the target process is either being
single-stepped or the interrupted syscall attempts to restart via
-ERESTARTBLOCK.

This patch restores the old behaviour by performing the
in_syscall() check only once at the start of the function.

Fixes: 17c289586009 ("arm64: Abstract syscallno manipulation")
Signed-off-by: Dave Martin <Dave.Martin@arm.com>
Reported-by: Sumit Semwal <sumit.semwal@linaro.org>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: <stable@vger.kernel.org> # 4.14.x-
---
 arch/arm64/kernel/signal.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 154b7d3..f212090 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -830,11 +830,12 @@ static void do_signal(struct pt_regs *regs)
 	unsigned long continue_addr = 0, restart_addr = 0;
 	int retval = 0;
 	struct ksignal ksig;
+	bool syscall = in_syscall(regs);
 
 	/*
 	 * If we were from a system call, check for system call restarting...
 	 */
-	if (in_syscall(regs)) {
+	if (syscall) {
 		continue_addr = regs->pc;
 		restart_addr = continue_addr - (compat_thumb_mode(regs) ? 2 : 4);
 		retval = regs->regs[0];
@@ -886,7 +887,7 @@ static void do_signal(struct pt_regs *regs)
 	 * Handle restarting a different system call. As above, if a debugger
 	 * has chosen to restart at a different PC, ignore the restart.
 	 */
-	if (in_syscall(regs) && regs->pc == restart_addr) {
+	if (syscall && regs->pc == restart_addr) {
 		if (retval == -ERESTART_RESTARTBLOCK)
 			setup_restart_syscall(regs);
 		user_rewind_single_step(current);
-- 
2.1.4

^ permalink raw reply related

* [PATCH v6 6/6] tty/serial: atmel: change the driver to work under at91-usart mfd
From: Radu Pirea @ 2018-06-07 11:00 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180607110020.20565-1-radu.pirea@microchip.com>

This patch modifies the place where resources and device tree properties
are searched.

Signed-off-by: Radu Pirea <radu.pirea@microchip.com>
---
 drivers/tty/serial/Kconfig        |  1 +
 drivers/tty/serial/atmel_serial.c | 42 ++++++++++++++++++++-----------
 2 files changed, 28 insertions(+), 15 deletions(-)

diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index 3682fd3e960c..25e55332f8b1 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -119,6 +119,7 @@ config SERIAL_ATMEL
 	depends on ARCH_AT91 || COMPILE_TEST
 	select SERIAL_CORE
 	select SERIAL_MCTRL_GPIO if GPIOLIB
+	select MFD_AT91_USART
 	help
 	  This enables the driver for the on-chip UARTs of the Atmel
 	  AT91 processors.
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c
index df46a9e88c34..5ef8a6a6fe17 100644
--- a/drivers/tty/serial/atmel_serial.c
+++ b/drivers/tty/serial/atmel_serial.c
@@ -193,8 +193,7 @@ static struct console atmel_console;
 
 #if defined(CONFIG_OF)
 static const struct of_device_id atmel_serial_dt_ids[] = {
-	{ .compatible = "atmel,at91rm9200-usart" },
-	{ .compatible = "atmel,at91sam9260-usart" },
+	{ .compatible = "atmel,at91rm9200-usart-serial" },
 	{ /* sentinel */ }
 };
 #endif
@@ -915,6 +914,7 @@ static void atmel_tx_dma(struct uart_port *port)
 static int atmel_prepare_tx_dma(struct uart_port *port)
 {
 	struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
+	struct device *mfd_dev = port->dev->parent;
 	dma_cap_mask_t		mask;
 	struct dma_slave_config config;
 	int ret, nent;
@@ -922,7 +922,7 @@ static int atmel_prepare_tx_dma(struct uart_port *port)
 	dma_cap_zero(mask);
 	dma_cap_set(DMA_SLAVE, mask);
 
-	atmel_port->chan_tx = dma_request_slave_channel(port->dev, "tx");
+	atmel_port->chan_tx = dma_request_slave_channel(mfd_dev, "tx");
 	if (atmel_port->chan_tx == NULL)
 		goto chan_err;
 	dev_info(port->dev, "using %s for tx DMA transfers\n",
@@ -1093,6 +1093,7 @@ static void atmel_rx_from_dma(struct uart_port *port)
 static int atmel_prepare_rx_dma(struct uart_port *port)
 {
 	struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
+	struct device *mfd_dev = port->dev->parent;
 	struct dma_async_tx_descriptor *desc;
 	dma_cap_mask_t		mask;
 	struct dma_slave_config config;
@@ -1104,7 +1105,7 @@ static int atmel_prepare_rx_dma(struct uart_port *port)
 	dma_cap_zero(mask);
 	dma_cap_set(DMA_CYCLIC, mask);
 
-	atmel_port->chan_rx = dma_request_slave_channel(port->dev, "rx");
+	atmel_port->chan_rx = dma_request_slave_channel(mfd_dev, "rx");
 	if (atmel_port->chan_rx == NULL)
 		goto chan_err;
 	dev_info(port->dev, "using %s for rx DMA transfers\n",
@@ -2222,8 +2223,8 @@ static const char *atmel_type(struct uart_port *port)
  */
 static void atmel_release_port(struct uart_port *port)
 {
-	struct platform_device *pdev = to_platform_device(port->dev);
-	int size = pdev->resource[0].end - pdev->resource[0].start + 1;
+	struct platform_device *mpdev = to_platform_device(port->dev->parent);
+	int size = resource_size(mpdev->resource);
 
 	release_mem_region(port->mapbase, size);
 
@@ -2238,8 +2239,8 @@ static void atmel_release_port(struct uart_port *port)
  */
 static int atmel_request_port(struct uart_port *port)
 {
-	struct platform_device *pdev = to_platform_device(port->dev);
-	int size = pdev->resource[0].end - pdev->resource[0].start + 1;
+	struct platform_device *mpdev = to_platform_device(port->dev->parent);
+	int size = resource_size(mpdev->resource);
 
 	if (!request_mem_region(port->mapbase, size, "atmel_serial"))
 		return -EBUSY;
@@ -2341,27 +2342,28 @@ static int atmel_init_port(struct atmel_uart_port *atmel_port,
 {
 	int ret;
 	struct uart_port *port = &atmel_port->uart;
+	struct platform_device *mpdev = to_platform_device(pdev->dev.parent);
 
 	atmel_init_property(atmel_port, pdev);
 	atmel_set_ops(port);
 
-	uart_get_rs485_mode(&pdev->dev, &port->rs485);
+	uart_get_rs485_mode(&mpdev->dev, &port->rs485);
 
 	port->iotype		= UPIO_MEM;
 	port->flags		= UPF_BOOT_AUTOCONF | UPF_IOREMAP;
 	port->ops		= &atmel_pops;
 	port->fifosize		= 1;
 	port->dev		= &pdev->dev;
-	port->mapbase	= pdev->resource[0].start;
-	port->irq	= pdev->resource[1].start;
+	port->mapbase		= mpdev->resource[0].start;
+	port->irq		= mpdev->resource[1].start;
 	port->rs485_config	= atmel_config_rs485;
-	port->membase	= NULL;
+	port->membase		= NULL;
 
 	memset(&atmel_port->rx_ring, 0, sizeof(atmel_port->rx_ring));
 
 	/* for console, the clock could already be configured */
 	if (!atmel_port->clk) {
-		atmel_port->clk = clk_get(&pdev->dev, "usart");
+		atmel_port->clk = clk_get(&mpdev->dev, "usart");
 		if (IS_ERR(atmel_port->clk)) {
 			ret = PTR_ERR(atmel_port->clk);
 			atmel_port->clk = NULL;
@@ -2694,13 +2696,22 @@ static void atmel_serial_probe_fifos(struct atmel_uart_port *atmel_port,
 static int atmel_serial_probe(struct platform_device *pdev)
 {
 	struct atmel_uart_port *atmel_port;
-	struct device_node *np = pdev->dev.of_node;
+	struct device_node *np = pdev->dev.parent->of_node;
 	void *data;
 	int ret = -ENODEV;
 	bool rs485_enabled;
 
 	BUILD_BUG_ON(ATMEL_SERIAL_RINGSIZE & (ATMEL_SERIAL_RINGSIZE - 1));
 
+	/*
+	 * In device tree is no node with "atmel,at91rm9200-usart-serial"
+	 * as compatible string. This driver is probed by at91-usart mfd driver
+	 * which is just a wrapper over the atmel_serial driver and
+	 * spi-at91-usart driver. All attributes needed by this driver are
+	 * found in of_node of parent.
+	 */
+	pdev->dev.of_node = np;
+
 	ret = of_alias_get_id(np, "serial");
 	if (ret < 0)
 		/* port id not found in platform data nor device-tree aliases:
@@ -2835,6 +2846,7 @@ static int atmel_serial_remove(struct platform_device *pdev)
 
 	clk_put(atmel_port->clk);
 	atmel_port->clk = NULL;
+	pdev->dev.of_node = NULL;
 
 	return ret;
 }
@@ -2845,7 +2857,7 @@ static struct platform_driver atmel_serial_driver = {
 	.suspend	= atmel_serial_suspend,
 	.resume		= atmel_serial_resume,
 	.driver		= {
-		.name			= "atmel_usart",
+		.name			= "atmel_usart_serial",
 		.of_match_table		= of_match_ptr(atmel_serial_dt_ids),
 	},
 };
-- 
2.17.1

^ permalink raw reply related

* [PATCH v6 5/6] spi: at91-usart: add driver for at91-usart as spi
From: Radu Pirea @ 2018-06-07 11:00 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180607110020.20565-1-radu.pirea@microchip.com>

This is the driver for at91-usart in spi mode. The USART IP can be configured
to work in many modes and one of them is SPI.

The driver was tested on sama5d3-xplained and sama5d4-xplained boards with
enc28j60 ethernet controller as slave.

Signed-off-by: Radu Pirea <radu.pirea@microchip.com>
---
 drivers/spi/Kconfig          |   9 +
 drivers/spi/Makefile         |   1 +
 drivers/spi/spi-at91-usart.c | 434 +++++++++++++++++++++++++++++++++++
 3 files changed, 444 insertions(+)
 create mode 100644 drivers/spi/spi-at91-usart.c

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 6fb0347a24f2..1a002a32d7aa 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -77,6 +77,15 @@ config SPI_ATMEL
 	  This selects a driver for the Atmel SPI Controller, present on
 	  many AT91 (ARM) chips.
 
+config SPI_AT91_USART
+	tristate "Atmel USART Controller SPI driver"
+	depends on HAS_DMA
+	depends on (ARCH_AT91 || COMPILE_TEST)
+	select MFD_AT91_USART
+	help
+	  This selects a driver for the AT91 USART Controller as SPI Master,
+	  present on AT91 and SAMA5 SoC series.
+
 config SPI_AU1550
 	tristate "Au1550/Au1200/Au1300 SPI Controller"
 	depends on MIPS_ALCHEMY
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 34c5f2832ddf..fb6cb42f4eaa 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_SPI_LOOPBACK_TEST)		+= spi-loopback-test.o
 obj-$(CONFIG_SPI_ALTERA)		+= spi-altera.o
 obj-$(CONFIG_SPI_ARMADA_3700)		+= spi-armada-3700.o
 obj-$(CONFIG_SPI_ATMEL)			+= spi-atmel.o
+obj-$(CONFIG_SPI_AT91_USART)		+= spi-at91-usart.o
 obj-$(CONFIG_SPI_ATH79)			+= spi-ath79.o
 obj-$(CONFIG_SPI_AU1550)		+= spi-au1550.o
 obj-$(CONFIG_SPI_AXI_SPI_ENGINE)	+= spi-axi-spi-engine.o
diff --git a/drivers/spi/spi-at91-usart.c b/drivers/spi/spi-at91-usart.c
new file mode 100644
index 000000000000..ae889aa6bda3
--- /dev/null
+++ b/drivers/spi/spi-at91-usart.c
@@ -0,0 +1,434 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for AT91 USART Controllers as SPI
+ *
+ * Copyright (C) 2018 Microchip Technology Inc.
+ * Author: Radu Pirea <radu.pirea@microchip.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_gpio.h>
+#include <linux/platform_device.h>
+
+#include <linux/spi/spi.h>
+
+#define US_CR			0x00
+#define US_MR			0x04
+#define US_IER			0x08
+#define US_IDR			0x0C
+#define US_CSR			0x14
+#define US_RHR			0x18
+#define US_THR			0x1C
+#define US_BRGR			0x20
+#define US_VERSION		0xFC
+
+#define US_CR_RSTRX		BIT(2)
+#define US_CR_RSTTX		BIT(3)
+#define US_CR_RXEN		BIT(4)
+#define US_CR_RXDIS		BIT(5)
+#define US_CR_TXEN		BIT(6)
+#define US_CR_TXDIS		BIT(7)
+
+#define US_MR_SPI_MASTER	0x0E
+#define US_MR_CHRL		GENMASK(7, 6)
+#define US_MR_CPHA		BIT(8)
+#define US_MR_CPOL		BIT(16)
+#define US_MR_CLKO		BIT(18)
+#define US_MR_WRDBT		BIT(20)
+#define US_MR_LOOP		BIT(15)
+
+#define US_IR_RXRDY		BIT(0)
+#define US_IR_TXRDY		BIT(1)
+#define US_IR_OVRE		BIT(5)
+
+#define US_BRGR_SIZE		BIT(16)
+
+#define US_MIN_CLK_DIV		0x06
+#define US_MAX_CLK_DIV		BIT(16)
+
+#define US_RESET		(US_CR_RSTRX | US_CR_RSTTX)
+#define US_DISABLE		(US_CR_RXDIS | US_CR_TXDIS)
+#define US_ENABLE		(US_CR_RXEN | US_CR_TXEN)
+#define US_OVRE_RXRDY_IRQS	(US_IR_OVRE | US_IR_RXRDY)
+
+#define US_INIT \
+	(US_MR_SPI_MASTER | US_MR_CHRL | US_MR_CLKO | US_MR_WRDBT)
+
+/* Register access macros */
+#define at91_usart_spi_readl(port, reg) \
+	readl_relaxed((port)->regs + US_##reg)
+#define at91_usart_spi_writel(port, reg, value) \
+	writel_relaxed((value), (port)->regs + US_##reg)
+
+#define at91_usart_spi_readb(port, reg) \
+	readb_relaxed((port)->regs + US_##reg)
+#define at91_usart_spi_writeb(port, reg, value) \
+	writeb_relaxed((value), (port)->regs + US_##reg)
+
+struct at91_usart_spi {
+	struct spi_transfer	*current_transfer;
+	void __iomem		*regs;
+	struct device		*dev;
+	struct clk		*clk;
+
+	/*used in interrupt to protect data reading*/
+	spinlock_t		lock;
+
+	int			irq;
+	unsigned int		current_tx_remaining_bytes;
+	unsigned int		current_rx_remaining_bytes;
+	int			done_status;
+
+	u32			spi_clk;
+	u32			status;
+
+	bool			xfer_failed;
+};
+
+static inline u32 at91_usart_spi_tx_ready(struct at91_usart_spi *aus)
+{
+	return aus->status & US_IR_TXRDY;
+}
+
+static inline u32 at91_usart_spi_rx_ready(struct at91_usart_spi *aus)
+{
+	return aus->status & US_IR_RXRDY;
+}
+
+static inline u32 at91_usart_spi_check_overrun(struct at91_usart_spi *aus)
+{
+	return aus->status & US_IR_OVRE;
+}
+
+static inline u32 at91_usart_spi_read_status(struct at91_usart_spi *aus)
+{
+	aus->status = at91_usart_spi_readl(aus, CSR);
+	return aus->status;
+}
+
+static inline void at91_usart_spi_tx(struct at91_usart_spi *aus)
+{
+	unsigned int len = aus->current_transfer->len;
+	unsigned int remaining = aus->current_tx_remaining_bytes;
+	const u8  *tx_buf = aus->current_transfer->tx_buf;
+
+	if (!remaining)
+		return;
+
+	if (at91_usart_spi_tx_ready(aus)) {
+		at91_usart_spi_writeb(aus, THR, tx_buf[len - remaining]);
+		aus->current_tx_remaining_bytes--;
+	}
+}
+
+static inline void at91_usart_spi_rx(struct at91_usart_spi *aus)
+{
+	int len = aus->current_transfer->len;
+	int remaining = aus->current_rx_remaining_bytes;
+	u8  *rx_buf = aus->current_transfer->rx_buf;
+
+	if (!remaining)
+		return;
+
+	rx_buf[len - remaining] = at91_usart_spi_readb(aus, RHR);
+	aus->current_rx_remaining_bytes--;
+}
+
+static inline void
+at91_usart_spi_set_xfer_speed(struct at91_usart_spi *aus,
+			      struct spi_transfer *xfer)
+{
+	at91_usart_spi_writel(aus, BRGR,
+			      DIV_ROUND_UP(aus->spi_clk, xfer->speed_hz));
+}
+
+static irqreturn_t at91_usart_spi_interrupt(int irq, void *dev_id)
+{
+	struct spi_controller *controller = dev_id;
+	struct at91_usart_spi *aus = spi_master_get_devdata(controller);
+
+	spin_lock(&aus->lock);
+	at91_usart_spi_read_status(aus);
+
+	if (at91_usart_spi_check_overrun(aus)) {
+		aus->xfer_failed = true;
+		aus->done_status = -EIO;
+		at91_usart_spi_writel(aus, IDR, US_IR_OVRE | US_IR_RXRDY);
+		spin_unlock(&aus->lock);
+		return IRQ_HANDLED;
+	}
+
+	if (at91_usart_spi_rx_ready(aus)) {
+		at91_usart_spi_rx(aus);
+		spin_unlock(&aus->lock);
+		return IRQ_HANDLED;
+	}
+
+	spin_unlock(&aus->lock);
+
+	return IRQ_NONE;
+}
+
+static int at91_usart_spi_setup(struct spi_device *spi)
+{
+	struct at91_usart_spi *aus = spi_master_get_devdata(spi->controller);
+	u32 *ausd = spi->controller_state;
+	unsigned int mr = at91_usart_spi_readl(aus, MR);
+	u8 bits = spi->bits_per_word;
+
+	if (bits != 8) {
+		dev_dbg(&spi->dev, "Only 8 bits per word are supported\n");
+		return -EINVAL;
+	}
+
+	if (spi->mode & SPI_CPOL)
+		mr |= US_MR_CPOL;
+	else
+		mr &= ~US_MR_CPOL;
+
+	if (spi->mode & SPI_CPHA)
+		mr |= US_MR_CPHA;
+	else
+		mr &= ~US_MR_CPHA;
+
+	if (spi->mode & SPI_LOOP)
+		mr |= US_MR_LOOP;
+	else
+		mr &= ~US_MR_LOOP;
+
+	if (!ausd) {
+		ausd = kzalloc(sizeof(*ausd), GFP_KERNEL);
+		if (!ausd)
+			return -ENOMEM;
+
+		spi->controller_state = ausd;
+	}
+
+	*ausd = mr;
+
+	dev_dbg(&spi->dev,
+		"setup: bpw %u mode 0x%x -> mr %d %08x\n",
+		bits, spi->mode, spi->chip_select, mr);
+
+	return 0;
+}
+
+int at91_usart_spi_transfer_one(struct spi_controller *ctlr,
+				struct spi_device *spi,
+				struct spi_transfer *xfer)
+{
+	struct at91_usart_spi *aus = spi_master_get_devdata(ctlr);
+
+	at91_usart_spi_set_xfer_speed(aus, xfer);
+	aus->done_status = 0;
+	aus->xfer_failed = false;
+	aus->current_transfer = xfer;
+	aus->current_tx_remaining_bytes = xfer->len;
+	aus->current_rx_remaining_bytes = xfer->len;
+
+	while ((aus->current_tx_remaining_bytes ||
+		aus->current_rx_remaining_bytes) && !aus->xfer_failed) {
+		at91_usart_spi_read_status(aus);
+		at91_usart_spi_tx(aus);
+		cpu_relax();
+	}
+	if (aus->xfer_failed) {
+		dev_err(aus->dev, "Overrun!\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+int at91_usart_spi_prepare_message(struct spi_controller *ctlr,
+				   struct spi_message *message)
+{
+	struct at91_usart_spi *aus = spi_master_get_devdata(ctlr);
+	struct spi_device *spi = message->spi;
+	u32 *ausd = spi->controller_state;
+
+	at91_usart_spi_writel(aus, CR, US_ENABLE);
+	at91_usart_spi_writel(aus, IER, US_OVRE_RXRDY_IRQS);
+	at91_usart_spi_writel(aus, MR, *ausd);
+
+	return 0;
+}
+
+int at91_usart_spi_unprepare_message(struct spi_controller *ctlr,
+				     struct spi_message *message)
+{
+	struct at91_usart_spi *aus = spi_master_get_devdata(ctlr);
+
+	at91_usart_spi_writel(aus, CR, US_RESET | US_DISABLE);
+	at91_usart_spi_writel(aus, IDR, US_OVRE_RXRDY_IRQS);
+
+	return 0;
+}
+
+static void at91_usart_spi_cleanup(struct spi_device *spi)
+{
+	struct at91_usart_spi_device *ausd = spi->controller_state;
+
+	spi->controller_state = NULL;
+	kfree(ausd);
+}
+
+static void at91_usart_spi_init(struct at91_usart_spi *aus)
+{
+	at91_usart_spi_writel(aus, MR, US_INIT);
+	at91_usart_spi_writel(aus, CR, US_RESET | US_DISABLE);
+}
+
+static int at91_usart_gpio_setup(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.parent->of_node;
+	int i;
+	int ret;
+	int nb;
+
+	if (!np)
+		return -EINVAL;
+
+	nb = of_gpio_named_count(np, "cs-gpios");
+	for (i = 0; i < nb; i++) {
+		int cs_gpio = of_get_named_gpio(np, "cs-gpios", i);
+
+		if (cs_gpio < 0)
+			return cs_gpio;
+
+		if (gpio_is_valid(cs_gpio)) {
+			ret = devm_gpio_request_one(&pdev->dev, cs_gpio,
+						    GPIOF_DIR_OUT,
+						    dev_name(&pdev->dev));
+			if (ret)
+				return ret;
+		}
+	}
+
+	return 0;
+}
+
+static int at91_usart_spi_probe(struct platform_device *pdev)
+{
+	struct resource *regs;
+	struct spi_controller *controller;
+	struct at91_usart_spi *aus;
+	struct clk *clk;
+	int irq;
+	int ret;
+
+	regs = platform_get_resource(to_platform_device(pdev->dev.parent),
+				     IORESOURCE_MEM, 0);
+	if (!regs)
+		return -EINVAL;
+
+	irq = platform_get_irq(to_platform_device(pdev->dev.parent), 0);
+	if (irq < 0)
+		return irq;
+
+	clk = devm_clk_get(pdev->dev.parent, "usart");
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	ret = -ENOMEM;
+	controller = spi_alloc_master(&pdev->dev, sizeof(*aus));
+	if (!controller)
+		goto at91_usart_spi_probe_fail;
+
+	ret = at91_usart_gpio_setup(pdev);
+	if (ret)
+		goto at91_usart_spi_probe_fail;
+
+	controller->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LOOP | SPI_CS_HIGH;
+	controller->dev.of_node = pdev->dev.parent->of_node;
+	controller->bits_per_word_mask = SPI_BPW_MASK(8);
+	controller->setup = at91_usart_spi_setup;
+	controller->flags = SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX;
+	controller->transfer_one = at91_usart_spi_transfer_one;
+	controller->prepare_message = at91_usart_spi_prepare_message;
+	controller->unprepare_message = at91_usart_spi_unprepare_message;
+	controller->cleanup = at91_usart_spi_cleanup;
+	controller->max_speed_hz = DIV_ROUND_UP(clk_get_rate(clk),
+						US_MIN_CLK_DIV);
+	controller->min_speed_hz = DIV_ROUND_UP(clk_get_rate(clk),
+						US_MAX_CLK_DIV);
+	platform_set_drvdata(pdev, controller);
+
+	aus = spi_master_get_devdata(controller);
+
+	aus->dev = &pdev->dev;
+	aus->regs = devm_ioremap_resource(&pdev->dev, regs);
+	if (IS_ERR(aus->regs)) {
+		ret = PTR_ERR(aus->regs);
+		goto at91_usart_spi_probe_fail;
+	}
+
+	aus->irq = irq;
+	aus->clk = clk;
+
+	ret = devm_request_irq(&pdev->dev, irq, at91_usart_spi_interrupt, 0,
+			       dev_name(&pdev->dev), controller);
+	if (ret)
+		goto at91_usart_spi_probe_fail;
+
+	ret = clk_prepare_enable(clk);
+	if (ret)
+		goto at91_usart_spi_probe_fail;
+
+	aus->spi_clk = clk_get_rate(clk);
+	at91_usart_spi_init(aus);
+
+	spin_lock_init(&aus->lock);
+	ret = devm_spi_register_master(&pdev->dev, controller);
+	if (ret)
+		goto fail_register_master;
+
+	dev_info(&pdev->dev,
+		 "Atmel USART SPI Controller version 0x%x at 0x%08x (irq %d)\n",
+		 at91_usart_spi_readl(aus, VERSION),
+		 regs->start, irq);
+
+	return 0;
+
+fail_register_master:
+	clk_disable_unprepare(clk);
+at91_usart_spi_probe_fail:
+	spi_master_put(controller);
+	return ret;
+}
+
+static int at91_usart_spi_remove(struct platform_device *pdev)
+{
+	struct spi_master *master = platform_get_drvdata(pdev);
+	struct at91_usart_spi *aus = spi_master_get_devdata(master);
+
+	clk_disable_unprepare(aus->clk);
+
+	return 0;
+}
+
+static const struct of_device_id at91_usart_spi_dt_ids[] = {
+	{ .compatible = "microchip,at91sam9g45-usart-spi"},
+	{ /* sentinel */}
+};
+
+MODULE_DEVICE_TABLE(of, at91_usart_spi_dt_ids);
+
+static struct platform_driver at91_usart_spi_driver = {
+	.driver = {
+		.name = "at91_usart_spi",
+	},
+	.probe = at91_usart_spi_probe,
+	.remove = at91_usart_spi_remove,
+};
+
+module_platform_driver(at91_usart_spi_driver);
+
+MODULE_DESCRIPTION("Microchip AT91 USART SPI Controller driver");
+MODULE_AUTHOR("Radu Pirea <radu.pirea@microchip.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:at91_usart_spi");
-- 
2.17.1

^ permalink raw reply related

* [PATCH v6 4/6] MAINTAINERS: add at91 usart spi driver
From: Radu Pirea @ 2018-06-07 11:00 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180607110020.20565-1-radu.pirea@microchip.com>

Added entry for at91 usart mfd driver.

Signed-off-by: Radu Pirea <radu.pirea@microchip.com>
---
 MAINTAINERS | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 12203d07c6af..dae31df711fb 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9201,6 +9201,13 @@ F:	drivers/mfd/at91-usart.c
 F:	include/dt-bindings/mfd/at91-usart.h
 F:	Documentation/devicetree/bindings/mfd/atmel-usart.txt
 
+MICROCHIP AT91 USART SPI DRIVER
+M:	Radu Pirea <radu.pirea@microchip.com>
+L:	linux-spi at vger.kernel.org
+S:	Supported
+F:	drivers/spi/spi-at91-usart.c
+F:	Documentation/devicetree/bindings/mfd/atmel-usart.txt
+
 MICROCHIP KSZ SERIES ETHERNET SWITCH DRIVER
 M:	Woojung Huh <Woojung.Huh@microchip.com>
 M:	Microchip Linux Driver Support <UNGLinuxDriver@microchip.com>
-- 
2.17.1

^ permalink raw reply related

* [PATCH v6 3/6] mfd: at91-usart: added mfd driver for usart
From: Radu Pirea @ 2018-06-07 11:00 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180607110020.20565-1-radu.pirea@microchip.com>

This mfd driver is just a wrapper over atmel_serial driver and
spi-at91-usart driver. Selection of one of the drivers is based on a
property from device tree. If the property is not specified, the default
driver is atmel_serial.

Signed-off-by: Radu Pirea <radu.pirea@microchip.com>
Acked-by: Rob Herring <robh@kernel.org>
---
 drivers/mfd/Kconfig      |  9 ++++++
 drivers/mfd/Makefile     |  1 +
 drivers/mfd/at91-usart.c | 68 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 78 insertions(+)
 create mode 100644 drivers/mfd/at91-usart.c

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index b860eb5aa194..a886672b960d 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -99,6 +99,15 @@ config MFD_AAT2870_CORE
 	  additional drivers must be enabled in order to use the
 	  functionality of the device.
 
+config MFD_AT91_USART
+	tristate "AT91 USART Driver"
+	select MFD_CORE
+	help
+	  Select this to get support for AT91 USART IP. This is a wrapper
+	  over at91-usart-serial driver and usart-spi-driver. Only one function
+	  can be used at a time. The choice is done at boot time by the probe
+	  function of this MFD driver according to a device tree property.
+
 config MFD_ATMEL_FLEXCOM
 	tristate "Atmel Flexcom (Flexible Serial Communication Unit)"
 	select MFD_CORE
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index d9d2cf0d32ef..db1332aa96db 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -185,6 +185,7 @@ obj-$(CONFIG_MFD_SPMI_PMIC)	+= qcom-spmi-pmic.o
 obj-$(CONFIG_TPS65911_COMPARATOR)	+= tps65911-comparator.o
 obj-$(CONFIG_MFD_TPS65090)	+= tps65090.o
 obj-$(CONFIG_MFD_AAT2870_CORE)	+= aat2870-core.o
+obj-$(CONFIG_MFD_AT91_USART)	+= at91-usart.o
 obj-$(CONFIG_MFD_ATMEL_FLEXCOM)	+= atmel-flexcom.o
 obj-$(CONFIG_MFD_ATMEL_HLCDC)	+= atmel-hlcdc.o
 obj-$(CONFIG_MFD_ATMEL_SMC)	+= atmel-smc.o
diff --git a/drivers/mfd/at91-usart.c b/drivers/mfd/at91-usart.c
new file mode 100644
index 000000000000..1a2bdeff7f6d
--- /dev/null
+++ b/drivers/mfd/at91-usart.c
@@ -0,0 +1,68 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Driver for AT91 USART
+ *
+ * Copyright (C) 2018 Microchip Technology
+ *
+ * Author: Radu Pirea <radu.pirea@microchip.com>
+ *
+ */
+
+#include <dt-bindings/mfd/at91-usart.h>
+
+#include <linux/module.h>
+#include <linux/mfd/core.h>
+#include <linux/property.h>
+
+static struct mfd_cell at91_usart_spi_subdev = {
+		.name = "at91_usart_spi",
+		.of_compatible = "microchip,at91sam9g45-usart-spi",
+	};
+
+static struct mfd_cell at91_usart_serial_subdev = {
+		.name = "atmel_usart_serial",
+		.of_compatible = "atmel,at91rm9200-usart-serial",
+	};
+
+static int at91_usart_mode_probe(struct platform_device *pdev)
+{
+	struct mfd_cell cell;
+	u32 opmode;
+	int err;
+
+	err = device_property_read_u32(&pdev->dev, "atmel,usart-mode", &opmode);
+
+	switch (opmode) {
+	case AT91_USART_MODE_SPI:
+		cell = at91_usart_spi_subdev;
+		break;
+	case AT91_USART_MODE_SERIAL:
+	default:
+		cell = at91_usart_serial_subdev;
+	}
+
+	return devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_AUTO, &cell, 1,
+			      NULL, 0, NULL);
+}
+
+static const struct of_device_id at91_usart_mode_of_match[] = {
+	{ .compatible = "atmel,at91rm9200-usart" },
+	{ .compatible = "atmel,at91sam9260-usart" },
+	{ /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(of, at91_flexcom_of_match);
+
+static struct platform_driver at91_usart_mfd = {
+	.probe	= at91_usart_mode_probe,
+	.driver	= {
+		.name		= "at91_usart_mode",
+		.of_match_table	= at91_usart_mode_of_match,
+	},
+};
+
+module_platform_driver(at91_usart_mfd);
+
+MODULE_AUTHOR("Radu Pirea <radu.pirea@microchip.com>");
+MODULE_DESCRIPTION("AT91 USART MFD driver");
+MODULE_LICENSE("GPL v2");
-- 
2.17.1

^ permalink raw reply related

* [PATCH v6 2/6] dt-bindings: add binding for atmel-usart in SPI mode
From: Radu Pirea @ 2018-06-07 11:00 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180607110020.20565-1-radu.pirea@microchip.com>

This patch moves the bindings for serial from serial/atmel-usart.txt to
mfd/atmel-usart.txt and adds bindings for USART in SPI mode.

Signed-off-by: Radu Pirea <radu.pirea@microchip.com>
Reviewed-by: Rob Herring <robh@kernel.org>
---
 .../bindings/{serial => mfd}/atmel-usart.txt  | 25 +++++++++++++++++--
 include/dt-bindings/mfd/at91-usart.h          | 17 +++++++++++++
 2 files changed, 40 insertions(+), 2 deletions(-)
 rename Documentation/devicetree/bindings/{serial => mfd}/atmel-usart.txt (76%)
 create mode 100644 include/dt-bindings/mfd/at91-usart.h

diff --git a/Documentation/devicetree/bindings/serial/atmel-usart.txt b/Documentation/devicetree/bindings/mfd/atmel-usart.txt
similarity index 76%
rename from Documentation/devicetree/bindings/serial/atmel-usart.txt
rename to Documentation/devicetree/bindings/mfd/atmel-usart.txt
index 7c0d6b2f53e4..3b9e18642c3b 100644
--- a/Documentation/devicetree/bindings/serial/atmel-usart.txt
+++ b/Documentation/devicetree/bindings/mfd/atmel-usart.txt
@@ -1,6 +1,6 @@
 * Atmel Universal Synchronous Asynchronous Receiver/Transmitter (USART)
 
-Required properties:
+Required properties for USART:
 - compatible: Should be "atmel,<chip>-usart" or "atmel,<chip>-dbgu"
   The compatible <chip> indicated will be the first SoC to support an
   additional mode or an USART new feature.
@@ -11,7 +11,13 @@ Required properties:
 	Required elements: "usart"
 - clocks: phandles to input clocks.
 
-Optional properties:
+Required properties for USART in SPI mode:
+- #size-cells      : Must be <0>
+- #address-cells   : Must be <1>
+- cs-gpios: chipselects (internal cs not supported)
+- atmel,usart-mode : Must be <USART_MODE_SPI> (found in dt-bindings/mfd/at91-usart.h)
+
+Optional properties in serial mode:
 - atmel,use-dma-rx: use of PDC or DMA for receiving data
 - atmel,use-dma-tx: use of PDC or DMA for transmitting data
 - {rts,cts,dtr,dsr,rng,dcd}-gpios: specify a GPIO for RTS/CTS/DTR/DSR/RI/DCD line respectively.
@@ -62,3 +68,18 @@ Example:
 		dma-names = "tx", "rx";
 		atmel,fifo-size = <32>;
 	};
+
+- SPI mode:
+	#include <dt-bindings/mfd/at91-usart.h>
+
+	spi0: spi at f001c000 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "atmel,at91rm9200-usart", "atmel,at91sam9260-usart";
+		atmel,usart-mode = <USART_MODE_SPI>;
+		reg = <0xf001c000 0x100>;
+		interrupts = <12 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&usart0_clk>;
+		clock-names = "usart";
+		cs-gpios = <&pioB 3 0>;
+	};
diff --git a/include/dt-bindings/mfd/at91-usart.h b/include/dt-bindings/mfd/at91-usart.h
new file mode 100644
index 000000000000..ac811628a42d
--- /dev/null
+++ b/include/dt-bindings/mfd/at91-usart.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * This header provides macros for AT91 USART DT bindings.
+ *
+ * Copyright (C) 2018 Microchip Technology
+ *
+ * Author: Radu Pirea <radu.pirea@microchip.com>
+ *
+ */
+
+#ifndef __DT_BINDINGS_AT91_USART_H__
+#define __DT_BINDINGS_AT91_USART_H__
+
+#define AT91_USART_MODE_SERIAL	1
+#define AT91_USART_MODE_SPI	2
+
+#endif /* __DT_BINDINGS_AT91_USART_H__ */
-- 
2.17.1

^ permalink raw reply related

* [PATCH v6 1/6] MAINTAINERS: add at91 usart mfd driver
From: Radu Pirea @ 2018-06-07 11:00 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180607110020.20565-1-radu.pirea@microchip.com>

Added entry for at91 usart mfd driver.

Signed-off-by: Radu Pirea <radu.pirea@microchip.com>
---
 MAINTAINERS | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 8e2a2fddbd19..12203d07c6af 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9160,6 +9160,7 @@ M:	Richard Genoud <richard.genoud@gmail.com>
 S:	Maintained
 F:	drivers/tty/serial/atmel_serial.c
 F:	drivers/tty/serial/atmel_serial.h
+F:	Documentation/devicetree/bindings/mfd/atmel-usart.txt
 
 MICROCHIP / ATMEL DMA DRIVER
 M:	Ludovic Desroches <ludovic.desroches@microchip.com>
@@ -9192,6 +9193,14 @@ S:	Supported
 F:	drivers/mtd/nand/raw/atmel/*
 F:	Documentation/devicetree/bindings/mtd/atmel-nand.txt
 
+MICROCHIP AT91 USART MFD DRIVER
+M:	Radu Pirea <radu.pirea@microchip.com>
+L:	linux-kernel at vger.kernel.org
+S:	Supported
+F:	drivers/mfd/at91-usart.c
+F:	include/dt-bindings/mfd/at91-usart.h
+F:	Documentation/devicetree/bindings/mfd/atmel-usart.txt
+
 MICROCHIP KSZ SERIES ETHERNET SWITCH DRIVER
 M:	Woojung Huh <Woojung.Huh@microchip.com>
 M:	Microchip Linux Driver Support <UNGLinuxDriver@microchip.com>
-- 
2.17.1

^ permalink raw reply related

* [PATCH v6 0/6] Driver for at91 usart in spi mode
From: Radu Pirea @ 2018-06-07 11:00 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

This is the second version of driver. I added a mfd driver which by
default probes atmel_serial driver and if in dt is specified to probe
the spi driver, then the spi-at91-usart driver will be probed. The
compatible for atmel_serial is now the compatible for at91-usart mfd
driver and compatilbe for atmel_serial driver was changed in order to
keep the bindings for serial as they are.

Changes in v1:
- added spi-at91-usart driver

Changes in v2:
- added at91-usart mfd driver
- modified spi-at91-usart driver to work as mfd driver child
- modified atmel_serial driver to work as mfd driver child

Changes in v3:
- fixed spi slaves probing

Changes in v4:
- modified the spi driver to use cs gpio support form spi subsystem
- fixed dma transfers for serial driver
- squashed binding for spi and serial and moved them to mfd/atmel-usart.txt

Changes in v5:
- fixed usage of stdout-path property with atmel_serial driver

Changes in v6:
- removed unused compatible strings from serial and spi drivers

Radu Pirea (6):
  MAINTAINERS: add at91 usart mfd driver
  dt-bindings: add binding for atmel-usart in SPI mode
  mfd: at91-usart: added mfd driver for usart
  MAINTAINERS: add at91 usart spi driver
  spi: at91-usart: add driver for at91-usart as spi
  tty/serial: atmel: change the driver to work under at91-usart mfd

 .../bindings/{serial => mfd}/atmel-usart.txt  |  25 +-
 MAINTAINERS                                   |  16 +
 drivers/mfd/Kconfig                           |   9 +
 drivers/mfd/Makefile                          |   1 +
 drivers/mfd/at91-usart.c                      |  68 +++
 drivers/spi/Kconfig                           |   9 +
 drivers/spi/Makefile                          |   1 +
 drivers/spi/spi-at91-usart.c                  | 434 ++++++++++++++++++
 drivers/tty/serial/Kconfig                    |   1 +
 drivers/tty/serial/atmel_serial.c             |  42 +-
 include/dt-bindings/mfd/at91-usart.h          |  17 +
 11 files changed, 606 insertions(+), 17 deletions(-)
 rename Documentation/devicetree/bindings/{serial => mfd}/atmel-usart.txt (76%)
 create mode 100644 drivers/mfd/at91-usart.c
 create mode 100644 drivers/spi/spi-at91-usart.c
 create mode 100644 include/dt-bindings/mfd/at91-usart.h

-- 
2.17.1

^ permalink raw reply

* [PATCH v1 3/4] clk: rockchip: add support for half divider
From: Heiko Stübner @ 2018-06-07 10:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1528340786-462-4-git-send-email-zhangqing@rock-chips.com>

Hi Elaine,

looks good to me overall, some minor things below.

Am Donnerstag, 7. Juni 2018, 05:06:25 CEST schrieb Elaine Zhang:
> The new Rockchip socs have optional half divider,
> so we use "branch_half_divider" + "COMPOSITE_NOMUX_HALFDIV \ DIV_HALF"
> to hook that special divider clock-type into our clock-tree.
> 
> Signed-off-by: Elaine Zhang <zhangqing@rock-chips.com>

Please provide a bit more explanation on how this clock type, so
people reading the git log later can understand how the divider works.


> ---
>  drivers/clk/rockchip/Makefile           |   1 +
>  drivers/clk/rockchip/clk-half-divider.c | 235
> ++++++++++++++++++++++++++++++++ drivers/clk/rockchip/clk.c              | 
> 10 ++
>  drivers/clk/rockchip/clk.h              |  45 ++++++
>  4 files changed, 291 insertions(+)
>  create mode 100644 drivers/clk/rockchip/clk-half-divider.c
> 
> diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
> index 59b8d320960a..023f83ad3429 100644
> --- a/drivers/clk/rockchip/Makefile
> +++ b/drivers/clk/rockchip/Makefile
> @@ -7,6 +7,7 @@ obj-y	+= clk-rockchip.o
>  obj-y	+= clk.o
>  obj-y	+= clk-pll.o
>  obj-y	+= clk-cpu.o
> +obj-y   += clk-half-divider.o

all other entries use tabs as spacers between obj-y and the +=

>  obj-y	+= clk-inverter.o
>  obj-y	+= clk-mmc-phase.o
>  obj-y	+= clk-muxgrf.o
> diff --git a/drivers/clk/rockchip/clk-half-divider.c
> b/drivers/clk/rockchip/clk-half-divider.c new file mode 100644
> index 000000000000..23830de254ec
> --- /dev/null
> +++ b/drivers/clk/rockchip/clk-half-divider.c
> @@ -0,0 +1,235 @@
> +/*

copyright line missing?

> + *
> + * This software is licensed under the terms of the GNU General Public
> + * License version 2, as published by the Free Software Foundation, and
> + * may be copied, distributed, and modified under those terms.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/slab.h>
> +#include <linux/bitops.h>
> +#include <linux/regmap.h>
> +#include <linux/clk.h>
> +#include <linux/clk-provider.h>
> +#include "clk.h"
> +
> +#define div_mask(width)	((1 << (width)) - 1)
> +
> +static bool _is_best_half_div(unsigned long rate, unsigned long now,
> +			      unsigned long best, unsigned long flags)
> +{
> +	if (flags & CLK_DIVIDER_ROUND_CLOSEST)
> +		return abs(rate - now) < abs(rate - best);
> +
> +	return now <= rate && now > best;
> +}
> +
> +static unsigned long clk_half_divider_recalc_rate(struct clk_hw *hw,
> +						  unsigned long parent_rate)
> +{
> +	struct clk_divider *divider = to_clk_divider(hw);

While I find it very cool that we can reuse the clk_divider struct
and see no issue doing it, I'm hoping for either Mike or Stephen
to indicate if we're allowed to do that ;-)


> +const struct clk_ops clk_half_divider_ops = {
> +	.recalc_rate = clk_half_divider_recalc_rate,
> +	.round_rate = clk_half_divider_round_rate,
> +	.set_rate = clk_half_divider_set_rate,
> +};
> +EXPORT_SYMBOL_GPL(clk_half_divider_ops);

this is only used locally in rockchip_clk_register_halfdiv, so doesn't
need to be exported.


Heiko

^ permalink raw reply

* [PATCH 1/2] arm64: avoid alloc memory on offline node
From: Michal Hocko @ 2018-06-07 10:55 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAErSpo6S0qtR42tjGZrFu4aMFFyThx1hkHTSowTt6t3XerpHnA@mail.gmail.com>

On Wed 06-06-18 15:39:34, Bjorn Helgaas wrote:
> [+cc akpm, linux-mm, linux-pci]
> 
> On Wed, Jun 6, 2018 at 10:44 AM Will Deacon <will.deacon@arm.com> wrote:
> >
> > On Thu, May 31, 2018 at 08:14:38PM +0800, Xie XiuQi wrote:
> > > A numa system may return node which is not online.
> > > For example, a numa node:
> > > 1) without memory
> > > 2) NR_CPUS is very small, and the cpus on the node are not brought up
> > >
> > > In this situation, we use NUMA_NO_NODE to avoid oops.
> > >
> > > [   25.732905] Unable to handle kernel NULL pointer dereference at virtual address 00001988
> > > [   25.740982] Mem abort info:
> > > [   25.743762]   ESR = 0x96000005
> > > [   25.746803]   Exception class = DABT (current EL), IL = 32 bits
> > > [   25.752711]   SET = 0, FnV = 0
> > > [   25.755751]   EA = 0, S1PTW = 0
> > > [   25.758878] Data abort info:
> > > [   25.761745]   ISV = 0, ISS = 0x00000005
> > > [   25.765568]   CM = 0, WnR = 0
> > > [   25.768521] [0000000000001988] user address but active_mm is swapper
> > > [   25.774861] Internal error: Oops: 96000005 [#1] SMP
> > > [   25.779724] Modules linked in:
> > > [   25.782768] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 4.17.0-rc6-mpam+ #115
> > > [   25.789714] Hardware name: Huawei D06/D06, BIOS Hisilicon D06 EC UEFI Nemo 2.0 RC0 - B305 05/28/2018
> > > [   25.798831] pstate: 80c00009 (Nzcv daif +PAN +UAO)
> > > [   25.803612] pc : __alloc_pages_nodemask+0xf0/0xe70
> > > [   25.808389] lr : __alloc_pages_nodemask+0x184/0xe70
> > > [   25.813252] sp : ffff00000996f660
> > > [   25.816553] x29: ffff00000996f660 x28: 0000000000000000
> > > [   25.821852] x27: 00000000014012c0 x26: 0000000000000000
> > > [   25.827150] x25: 0000000000000003 x24: ffff000008099eac
> > > [   25.832449] x23: 0000000000400000 x22: 0000000000000000
> > > [   25.837747] x21: 0000000000000001 x20: 0000000000000000
> > > [   25.843045] x19: 0000000000400000 x18: 0000000000010e00
> > > [   25.848343] x17: 000000000437f790 x16: 0000000000000020
> > > [   25.853641] x15: 0000000000000000 x14: 6549435020524541
> > > [   25.858939] x13: 20454d502067756c x12: 0000000000000000
> > > [   25.864237] x11: ffff00000996f6f0 x10: 0000000000000006
> > > [   25.869536] x9 : 00000000000012a4 x8 : ffff8023c000ff90
> > > [   25.874834] x7 : 0000000000000000 x6 : ffff000008d73c08
> > > [   25.880132] x5 : 0000000000000000 x4 : 0000000000000081
> > > [   25.885430] x3 : 0000000000000000 x2 : 0000000000000000
> > > [   25.890728] x1 : 0000000000000001 x0 : 0000000000001980
> > > [   25.896027] Process swapper/0 (pid: 1, stack limit = 0x        (ptrval))
> > > [   25.902712] Call trace:
> > > [   25.905146]  __alloc_pages_nodemask+0xf0/0xe70
> > > [   25.909577]  allocate_slab+0x94/0x590
> > > [   25.913225]  new_slab+0x68/0xc8
> > > [   25.916353]  ___slab_alloc+0x444/0x4f8
> > > [   25.920088]  __slab_alloc+0x50/0x68
> > > [   25.923562]  kmem_cache_alloc_node_trace+0xe8/0x230
> > > [   25.928426]  pci_acpi_scan_root+0x94/0x278
> > > [   25.932510]  acpi_pci_root_add+0x228/0x4b0
> > > [   25.936593]  acpi_bus_attach+0x10c/0x218
> > > [   25.940501]  acpi_bus_attach+0xac/0x218
> > > [   25.944323]  acpi_bus_attach+0xac/0x218
> > > [   25.948144]  acpi_bus_scan+0x5c/0xc0
> > > [   25.951708]  acpi_scan_init+0xf8/0x254
> > > [   25.955443]  acpi_init+0x310/0x37c
> > > [   25.958831]  do_one_initcall+0x54/0x208
> > > [   25.962653]  kernel_init_freeable+0x244/0x340
> > > [   25.966999]  kernel_init+0x18/0x118
> > > [   25.970474]  ret_from_fork+0x10/0x1c
> > > [   25.974036] Code: 7100047f 321902a4 1a950095 b5000602 (b9400803)
> > > [   25.980162] ---[ end trace 64f0893eb21ec283 ]---
> > > [   25.984765] Kernel panic - not syncing: Fatal exception
> > >
> > > Signed-off-by: Xie XiuQi <xiexiuqi@huawei.com>
> > > Tested-by: Huiqiang Wang <wanghuiqiang@huawei.com>
> > > Cc: Hanjun Guo <hanjun.guo@linaro.org>
> > > Cc: Tomasz Nowicki <Tomasz.Nowicki@caviumnetworks.com>
> > > Cc: Xishi Qiu <qiuxishi@huawei.com>
> > > ---
> > >  arch/arm64/kernel/pci.c | 3 +++
> > >  1 file changed, 3 insertions(+)
> > >
> > > diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c
> > > index 0e2ea1c..e17cc45 100644
> > > --- a/arch/arm64/kernel/pci.c
> > > +++ b/arch/arm64/kernel/pci.c
> > > @@ -170,6 +170,9 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
> > >       struct pci_bus *bus, *child;
> > >       struct acpi_pci_root_ops *root_ops;
> > >
> > > +     if (node != NUMA_NO_NODE && !node_online(node))
> > > +             node = NUMA_NO_NODE;
> > > +
> >
> > This really feels like a bodge, but it does appear to be what other
> > architectures do, so:
> >
> > Acked-by: Will Deacon <will.deacon@arm.com>
> 
> I agree, this doesn't feel like something we should be avoiding in the
> caller of kzalloc_node().
> 
> I would not expect kzalloc_node() to return memory that's offline, no
> matter what node we told it to allocate from.  I could imagine it
> returning failure, or returning memory from a node that *is* online,
> but returning a pointer to offline memory seems broken.
> 
> Are we putting memory that's offline in the free list?  I don't know
> where to look to figure this out.

I am not sure I have the full context but pci_acpi_scan_root calls
kzalloc_node(sizeof(*info), GFP_KERNEL, node)
and that should fall back to whatever node that is online. Offline node
shouldn't keep any pages behind. So there must be something else going
on here and the patch is not the right way to handle it. What does
faddr2line __alloc_pages_nodemask+0xf0 tells on this kernel?

-- 
Michal Hocko
SUSE Labs

^ permalink raw reply

* [PATCH v4 1/7] dt-bindings: clk: at91: add an I2S mux clock
From: Codrin Ciubotariu @ 2018-06-07 10:30 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAL_JsqJu6=ORfutZ5tAyNp2q2rH6P+fgJMRKw750RyFy=ptjPw@mail.gmail.com>

On 31.05.2018 18:56, Rob Herring wrote:
> On Thu, May 31, 2018 at 10:31 AM, Stephen Boyd <sboyd@kernel.org> wrote:
>> Quoting Rob Herring (2018-05-31 07:20:57)
>>> On Thu, May 31, 2018 at 5:25 AM, Codrin Ciubotariu
>>> <codrin.ciubotariu@microchip.com> wrote:
>>>> On 31.05.2018 03:58, Rob Herring wrote:
>>>>>
>>>>> On Fri, May 25, 2018 at 03:34:22PM +0300, Codrin Ciubotariu wrote:
>>>>>>
>>>>>> The I2S mux clock can be used to select the I2S input clock. The
>>>>>> available parents are the peripheral and the generated clocks.
>>>>>>
>>>>>> Signed-off-by: Codrin Ciubotariu <codrin.ciubotariu@microchip.com>
>>>>>> ---
>>>>>>    .../devicetree/bindings/clock/at91-clock.txt       | 34
>>>>>> ++++++++++++++++++++++
>>>>>>    1 file changed, 34 insertions(+)
>>>>>>
>>>>>> diff --git a/Documentation/devicetree/bindings/clock/at91-clock.txt
>>>>>> b/Documentation/devicetree/bindings/clock/at91-clock.txt
>>>>>> index 51c259a..1c46b3c 100644
>>>>>> --- a/Documentation/devicetree/bindings/clock/at91-clock.txt
>>>>>> +++ b/Documentation/devicetree/bindings/clock/at91-clock.txt
>>>>>> @@ -90,6 +90,8 @@ Required properties:
>>>>>>          "atmel,sama5d2-clk-audio-pll-pmc"
>>>>>>                  at91 audio pll output on AUDIOPLLCLK that feeds the PMC
>>>>>>                  and can be used by peripheral clock or generic clock
>>>>>> +       "atmel,sama5d2-clk-i2s-mux":
>>>>>> +               at91 I2S clock source selection
>>>>>
>>>>>
>>>>> Is this boolean or takes some values. If latter, what are valid values?
>>>>
>>>>
>>>> This is the compatible string of the clock driver.
>>>
>>> Ah, now I remember. AT91 uses fine grained clock nodes in DT. Is there
>>> still a plan to fix this?
>>
>> I'm also interested in a plan.
>>
>>>>>
>>>>>> +               compatible = "atmel,sama5d2-clk-i2s-mux";
>>>>>> +               #address-cells = <1>;
>>>>>> +               #size-cells = <0>;
>>>>>
>>>>>
>>>>> How do you address this block? My guess is you don't because it is just
>>>>> part of some other block and you are just creating this node to
>>>>> instantiate a driver. Just make the node for the actual h/w block a
>>>>> clock provider and define the clock ids (0 and 1).
>>>>
>>>>
>>>> This block is not addressed, but its children are. The register we access in
>>>> this driver is not part of other block. It's a SFR register, accessed
>>>> through syscon and it has nothing to do with the I2S IP (see SAMA5D2 DS,
>>>> page 1256, fig. 44-1: I2SC Block Diagram) that is the consumer of this
>>>> clock. Adding a clock-id property in the I2S node would be just like v3 of
>>>> this series, with the difference that we use clock-id instead of alias id to
>>>> set the clock parent, which is not how you suggested back then.
>>>
>>> I wasn't suggesting a clock-id property, but a clock specifier (i.e.
>>> make #clock-cells 1).
>>>
>>> But AT91 clocks are all a mess, so I don't know what to tell you.
>>>
>>
>> If #clock-cells of 1 works then we should go with that. It's still weird
>> that we need random nodes to add more clks, but I guess that's how it's
>> going to be for each at91 clk driver until it changes to be one big
>> provider node.
> 
> Seems to me that clock additions could use a new binding and we start
> with a new driver that handles these few clocks initially. But I
> haven't looked whether both can coexist.

Mark already applied to broonie/sound.git the I2S bindings that have a 
phandle to this clock. If I am to change #clock-cells to 1, I will have 
to change the bindings to include the clock-id.
Which approach should I take now?

Thanks and best regards,
Codrin

^ permalink raw reply

* [PATCH v5 2/4] kernel hacking: new config NO_AUTO_INLINE to disable compiler auto-inline optimizations
From: Johan Hovold @ 2018-06-07 10:27 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <314bb2b3-186e-d7b0-d800-f77a42fd80fa@linaro.org>

On Thu, Jun 07, 2018 at 05:12:51AM -0500, Alex Elder wrote:
> On 06/07/2018 04:19 AM, Viresh Kumar wrote:
> > On 07-06-18, 11:18, Johan Hovold wrote:
> >> If you want to work around the warning and think you can do it in some
> >> non-contrived way, then go for it.
> >>
> >> Clearing the request buffer, checking for termination using strnlen, and
> >> then using memcpy might not be too bad.
> >>
> >> But after all, it is a false positive, so leaving things as they stand
> >> is fine too.
> > 
> > Leave it then :)
> > 
> 
> It's interesting that the warning isn't reported for this in
> fw_mgmt_interface_fw_version_operation().  The difference there is
> that you actually put a zero byte at that last position before
> returning.  I'm mildly impressed if gcc is distinguishing that.

Found a redhat blog post claiming it does check for some cases like
that:

	https://developers.redhat.com/blog/2018/05/24/detecting-string-truncation-with-gcc-8/

> You *are* returning the fw_info->firmware_tag array newly filled
> with a non-null-terminated string in one of the two cases that
> get warnings in "fw-management.c".

No, there's no warning for that one (line 250), and there fw_info is
used as the source, not the destination, so no unterminated string is
returned there either.

> But the other one is only
> updating a buffer in a local/automatic variable.

All three cases, except the one that is explicitly terminated.

> Weird.  I wish there were a non-clumsy way of marking false positives
> like this as A-OK.

The gcc docs mentions an attribute for that but it seems a bit overkill
here.

Thanks,
Johan

^ permalink raw reply

* Common config for N900 and D4
From: Pavel Machek @ 2018-06-07 10:26 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180605042627.GB5738@atomide.com>

Hi!

> > > > [    0.000000] L2C-310 erratum 727915 enabled
> > > > [    0.000000] L2C-310 enabling early BRESP for Cortex-A9
> > > > [    0.000000] L2C-310 full line of zeros enabled for Cortex-A9
> > > 
> > > I tried disabling outer cache to get rid of this. That got me further
> > > in boot, but not to working system:
> > 
> > I now have config that works.
> > 
> > My kernels were probably grossly misconfigured (OMAP4 not enabled on
> > droid4)... still I'd expect some kind of panic explaining board is not
> > compatible with kernel, not a random oops...
> 
> Like "clk-provider not found" error? :) I agree it's not very
> descriptive and I think we could easily print something from
> after the SoC detection for missing pdata.

If you had patch for testing, or pointer where such check would
belong, that would be nice. I might try to do something, but now it
boots so it is not too high priority for me.

Thanks,
							Pavel

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply

* [PATCH v3 4/6] bus: ti-sysc: Add support for software reset
From: Faiz Abbas @ 2018-06-07 10:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180607073530.GH5738@atomide.com>

Hi,

On Thursday 07 June 2018 01:05 PM, Tony Lindgren wrote:
> * Faiz Abbas <faiz_abbas@ti.com> [180606 06:14]:
>> +static int sysc_reset(struct sysc *ddata)
>> +{
>> +	int offset = ddata->offsets[SYSC_SYSCONFIG];
>> +	int val = sysc_read(ddata, offset);
>> +
>> +	val |= (0x1 << ddata->cap->regbits->srst_shift);
>> +	sysc_write(ddata, offset, val);
>> +
>> +	/* Poll on reset status */
>> +	if (ddata->cfg.quirks & SYSC_QUIRK_RESET_STATUS) {
>> +		offset = ddata->offsets[SYSC_SYSSTATUS];
>> +
>> +		return readl_poll_timeout(ddata->module_va + offset, val,
>> +				(val & ddata->cfg.syss_mask) == 0x0,
>> +				100, MAX_MODULE_SOFTRESET_WAIT);
>> +	}
>> +
>> +	return 0;
>> +}
> 
> I wonder if we should also add SYSS_QUIRK_RESET_STATUS in
> addition to SYSC_QUIRK_RESET status to make it easy to
> read the right register?

I assumed SYSC_QUIRK is the prefix to indicate the ti-sysc driver not
the register. Are there layouts in which the reset status bit is in the
sysconfig register rather than the sysstatus register?

Thanks,
Faiz

^ permalink raw reply

* [PATCH v5 2/4] kernel hacking: new config NO_AUTO_INLINE to disable compiler auto-inline optimizations
From: Alex Elder @ 2018-06-07 10:12 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180607091923.n5q5uzsxuymy3vov@vireshk-i7>

On 06/07/2018 04:19 AM, Viresh Kumar wrote:
> On 07-06-18, 11:18, Johan Hovold wrote:
>> If you want to work around the warning and think you can do it in some
>> non-contrived way, then go for it.
>>
>> Clearing the request buffer, checking for termination using strnlen, and
>> then using memcpy might not be too bad.
>>
>> But after all, it is a false positive, so leaving things as they stand
>> is fine too.
> 
> Leave it then :)
> 

It's interesting that the warning isn't reported for this in
fw_mgmt_interface_fw_version_operation().  The difference there is
that you actually put a zero byte at that last position before
returning.  I'm mildly impressed if gcc is distinguishing that.

You *are* returning the fw_info->firmware_tag array newly filled
with a non-null-terminated string in one of the two cases that
get warnings in "fw-management.c".  But the other one is only
updating a buffer in a local/automatic variable.

Weird.  I wish there were a non-clumsy way of marking false positives
like this as A-OK.

					-Alex

^ permalink raw reply

* [PATCH v4 05/14] coresight: get/put module in coresight_build/release_path
From: Suzuki K Poulose @ 2018-06-07 10:07 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180607095322.GA26174@kroah.com>

On 06/07/2018 10:53 AM, Greg Kroah-Hartman wrote:
> On Thu, Jun 07, 2018 at 10:32:21AM +0100, Suzuki K Poulose wrote:
>> On 06/07/2018 10:13 AM, Greg Kroah-Hartman wrote:
>>> On Thu, Jun 07, 2018 at 10:04:33AM +0100, Suzuki K Poulose wrote:
>>>> Hi Greg,
>>>>
>>>> On 06/07/2018 09:34 AM, Greg Kroah-Hartman wrote:
>>>>> On Wed, Jun 06, 2018 at 03:55:01PM -0500, Kim Phillips wrote:
>>>>>> On Wed, 6 Jun 2018 10:46:36 +0100
>>>>>> Suzuki K Poulose <suzuki.poulose@arm.com> wrote:
>>>>>>
>>>>>>> On 06/06/2018 09:24 AM, Greg Kroah-Hartman wrote:
>>>>>>>> On Tue, Jun 05, 2018 at 04:07:01PM -0500, Kim Phillips wrote:
>>>>>>>>> Increment the refcnt for driver modules in current use by calling
>>>>>>>>> module_get in coresight_build_path and module_put in release_path.
>>>>>>>>>
>>>>>>>>> This prevents driver modules from being unloaded when they are in use,
>>>>>>>>> either in sysfs or perf mode.
>>>>>>>>
>>>>>>>> Why does it matter?  Shouldn't you be allowed to remove any module at
>>>>>>>> any point in time, much like a networking driver?
>>>>
>>>> The user doesn't have an explicit refcount on the individual components
>>>> in a trace session. So, when a trace session is in progress, it is as
>>>> good as having a "file" open on each component that is part of the
>>>> active trace session. So, we don't want the driver to be removed when
>>>> the component is being used in the trace collection.
>>>
>>> Why not?  What's wrong with that happening and then the trace collection
>>> starts failing with -ENODEV or something?
>>
>> May be I am missing something here. Can we allow the driver to be removed
>> when one of its device is "turned ON" and we need the same
>> driver to "turn it OFF" when the session ends ? To make a better
>> comparison :
>>
>> Can we unload a usb_mass_storage module when a USB disk(which uses the
>> module driver) is mounted and is being used ? I believe, the module
>> will eventually get unloaded when we unmount the disk, if someone did
>> a unload.
> 
> No, mount causes the module count to be incrememted.  Mount and
> "open/close" are the old-school way of doing module reference counting.
> 
> Look at how network drivers work today, you can unload any network
> driver even if there is a valid network connection "up and running"
> attached to it.  It just gets torn down when that request happens.

Ok, that makes more sense now. Thanks for the hints. However, it doesn't
look that easy from the coresight point due to the way the devices are
used in an interconnected manner which could be part of multiple trace
sessions.

e.g, a funnel could be part of two independent trace sessions with
different sets of sources/sinks. Tearing down the trace sessions is
going to be a difficult task unless we make drastic changes to the PMU
framework itself. But will see, what best we can do to make it modern
:-)

> 
>> We have a similar situation here. The only difference is the driver is
>> referenced only when one of its device is in a trace session.
> 
> I understand, I'm saying that you have to be very careful when messing
> around with module reference counts to get it correct and perhaps you
> should just change your design to not care about module reference counts
> at all, like networking did 15+ years ago.
> 
> Let's learn from the good examples in our past (like networking), and
> not like the older bad examples (like mount/files).
> 
>>> Remember, removing a kernel module is something that only happens very
>>> rarely, and is an explicit choice by someone with root permissions.  If
>>> you want to remove that module, it should be able to go, as you know
>>> what you are doing at that point in time.
>>
>> Right, but when a device is "in use" can we do that ? I thought the user
>> will get a module is in use or busy, error.
> 
> Try it on networking today :)
> 
>>> Don't try to "protect the user from themselves" here, they want to shoot
>>> their foot, make it hurt if they are aiming it there :)
>>>
>>
>> The module_get/put added here are only triggered when we start a trace
>> session, where we build a path for the current session from the configured
>> "source" to the configured "sink" and the path is destroyed
>> at the end of the trace session. i.e, the path is not a permanent thing.
>> It is constructed per session. So it is perfectly possible to remove a
>> device in between trace sessions.
> 
> That's fine, but again, just be careful to get this correct.  The patch
> I reviewed did not seem to do that.

Thanks for the useful suggestions, we will explore this more.

Cheers
Suzuki

^ permalink raw reply

* [PATCH V6] arm64: alternative:flush cache with unpatched code
From: Will Deacon @ 2018-06-07 10:01 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1528327743-29263-1-git-send-email-rokhanna@nvidia.com>

On Wed, Jun 06, 2018 at 04:29:03PM -0700, Rohit Khanna wrote:
> In the current implementation,  __apply_alternatives patches
> flush_icache_range and then executes it without invalidating the icache.
> Thus, icache can contain some of the old instructions for
> flush_icache_range. This can cause unpredictable behavior as during
> execution we can get a mix of old and new instructions for
> flush_icache_range.
> 
> This patch modifies __apply_alternatives so that it uses non hot-patched
> __flush_icache_all after applying all the alternatives.

Please can you try the diff I posted the other day? [1]

Will

--->8

[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2018-June/582861.html

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox