mirror of
https://github.com/openwrt/openwrt.git
synced 2025-02-18 16:40:29 +00:00
ramips: switch to 6.1 kernel
We have had the testing kernel for several weeks now. Let's switch to 6.1 to have more testers. Additionally, 6.6 is already in the pipeline. Signed-off-by: Nick Hainke <vincent@systemli.org>
This commit is contained in:
parent
4468cae502
commit
1576474f55
@ -10,8 +10,7 @@ BOARDNAME:=MediaTek Ralink MIPS
|
||||
SUBTARGETS:=mt7620 mt7621 mt76x8 rt288x rt305x rt3883
|
||||
FEATURES:=squashfs gpio
|
||||
|
||||
KERNEL_PATCHVER:=5.15
|
||||
KERNEL_TESTING_PATCHVER:=6.1
|
||||
KERNEL_PATCHVER:=6.1
|
||||
|
||||
define Target/Description
|
||||
Build firmware images for Ralink RT288x/RT3xxx based boards.
|
||||
|
@ -125,15 +125,10 @@ out_get_link:
|
||||
return ethtool_op_get_link(dev);
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)
|
||||
static int fe_set_ringparam(struct net_device *dev,
|
||||
struct ethtool_ringparam *ring,
|
||||
struct kernel_ethtool_ringparam *kernel_rp,
|
||||
struct netlink_ext_ack *extack)
|
||||
#else
|
||||
static int fe_set_ringparam(struct net_device *dev,
|
||||
struct ethtool_ringparam *ring)
|
||||
#endif
|
||||
{
|
||||
struct fe_priv *priv = netdev_priv(dev);
|
||||
|
||||
@ -153,15 +148,10 @@ static int fe_set_ringparam(struct net_device *dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)
|
||||
static void fe_get_ringparam(struct net_device *dev,
|
||||
struct ethtool_ringparam *ring,
|
||||
struct kernel_ethtool_ringparam *kernel_rp,
|
||||
struct netlink_ext_ack *extack)
|
||||
#else
|
||||
static void fe_get_ringparam(struct net_device *dev,
|
||||
struct ethtool_ringparam *ring)
|
||||
#endif
|
||||
{
|
||||
struct fe_priv *priv = netdev_priv(dev);
|
||||
|
||||
|
@ -1636,11 +1636,7 @@ static int fe_probe(struct platform_device *pdev)
|
||||
priv->tx_ring.tx_ring_size *= 4;
|
||||
priv->rx_ring.rx_ring_size *= 4;
|
||||
}
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)
|
||||
netif_napi_add_weight(netdev, &priv->rx_napi, fe_poll, napi_weight);
|
||||
#else
|
||||
netif_napi_add(netdev, &priv->rx_napi, fe_poll, napi_weight);
|
||||
#endif
|
||||
fe_set_ethtool_ops(netdev);
|
||||
|
||||
err = register_netdev(netdev);
|
||||
|
@ -1097,12 +1097,10 @@ static int aw9523_remove(struct i2c_client *client)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)
|
||||
static void aw9523_remove_void(struct i2c_client *client)
|
||||
{
|
||||
aw9523_remove(client);
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct i2c_device_id aw9523_i2c_id_table[] = {
|
||||
{ "aw9523_i2c", 0 },
|
||||
@ -1121,11 +1119,7 @@ static struct i2c_driver aw9523_driver = {
|
||||
.of_match_table = of_aw9523_i2c_match,
|
||||
},
|
||||
.probe = aw9523_probe,
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)
|
||||
.remove = aw9523_remove_void,
|
||||
#else
|
||||
.remove = aw9523_remove,
|
||||
#endif
|
||||
.id_table = aw9523_i2c_id_table,
|
||||
};
|
||||
module_i2c_driver(aw9523_driver);
|
||||
|
@ -101,8 +101,7 @@ define KernelPackage/hsdma-mtk
|
||||
CONFIG_MTK_HSDMA
|
||||
FILES:= \
|
||||
$(LINUX_DIR)/drivers/dma/virt-dma.ko \
|
||||
$(LINUX_DIR)/drivers/staging/mt7621-dma/hsdma-mt7621.ko@lt5.17 \
|
||||
$(LINUX_DIR)/drivers/dma/mediatek/hsdma-mt7621.ko@ge5.17
|
||||
$(LINUX_DIR)/drivers/dma/mediatek/hsdma-mt7621.ko
|
||||
AUTOLOAD:=$(call AutoLoad,53,hsdma-mt7621)
|
||||
endef
|
||||
|
||||
|
@ -1,60 +0,0 @@
|
||||
From f383b0770612838e78986231710c0a3afee4db42 Mon Sep 17 00:00:00 2001
|
||||
From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Date: Mon, 10 Jan 2022 12:49:27 +0100
|
||||
Subject: [PATCH 1/2] dt-bindings: reset: add dt binding header for Mediatek MT7621 resets
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Add dt binding header for resets lines in Mediatek MT7621 SoCs.
|
||||
|
||||
Acked-by: Rob Herring <robh@kernel.org>
|
||||
Tested-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Link: https://lore.kernel.org/r/20220110114930.1406665-2-sergio.paracuellos@gmail.com
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
include/dt-bindings/reset/mt7621-reset.h | 37 ++++++++++++++++++++++++++++++++
|
||||
1 file changed, 37 insertions(+)
|
||||
create mode 100644 include/dt-bindings/reset/mt7621-reset.h
|
||||
|
||||
--- /dev/null
|
||||
+++ b/include/dt-bindings/reset/mt7621-reset.h
|
||||
@@ -0,0 +1,37 @@
|
||||
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
|
||||
+/*
|
||||
+ * Copyright (c) 2021 Sergio Paracuellos
|
||||
+ * Author: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
+ */
|
||||
+
|
||||
+#ifndef DT_BINDING_MT7621_RESET_H
|
||||
+#define DT_BINDING_MT7621_RESET_H
|
||||
+
|
||||
+#define MT7621_RST_SYS 0
|
||||
+#define MT7621_RST_MCM 2
|
||||
+#define MT7621_RST_HSDMA 5
|
||||
+#define MT7621_RST_FE 6
|
||||
+#define MT7621_RST_SPDIFTX 7
|
||||
+#define MT7621_RST_TIMER 8
|
||||
+#define MT7621_RST_INT 9
|
||||
+#define MT7621_RST_MC 10
|
||||
+#define MT7621_RST_PCM 11
|
||||
+#define MT7621_RST_PIO 13
|
||||
+#define MT7621_RST_GDMA 14
|
||||
+#define MT7621_RST_NFI 15
|
||||
+#define MT7621_RST_I2C 16
|
||||
+#define MT7621_RST_I2S 17
|
||||
+#define MT7621_RST_SPI 18
|
||||
+#define MT7621_RST_UART1 19
|
||||
+#define MT7621_RST_UART2 20
|
||||
+#define MT7621_RST_UART3 21
|
||||
+#define MT7621_RST_ETH 23
|
||||
+#define MT7621_RST_PCIE0 24
|
||||
+#define MT7621_RST_PCIE1 25
|
||||
+#define MT7621_RST_PCIE2 26
|
||||
+#define MT7621_RST_AUX_STCK 28
|
||||
+#define MT7621_RST_CRYPTO 29
|
||||
+#define MT7621_RST_SDXC 30
|
||||
+#define MT7621_RST_PPE 31
|
||||
+
|
||||
+#endif /* DT_BINDING_MT7621_RESET_H */
|
@ -1,114 +0,0 @@
|
||||
From 64b2d6ffff862c0e7278198b4229e42e1abb3bb1 Mon Sep 17 00:00:00 2001
|
||||
From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Date: Mon, 10 Jan 2022 12:49:30 +0100
|
||||
Subject: [PATCH 2/2] staging: mt7621-dts: align resets with binding documentation
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Binding documentation for compatible 'mediatek,mt7621-sysc' has been updated
|
||||
to be used as a reset provider. Align reset related bits and system controller
|
||||
node with binding documentation along the dtsi file.
|
||||
|
||||
Tested-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
|
||||
Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Link: https://lore.kernel.org/r/20220110114930.1406665-5-sergio.paracuellos@gmail.com
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/staging/mt7621-dts/mt7621.dtsi | 21 +++++++++------------
|
||||
1 file changed, 9 insertions(+), 12 deletions(-)
|
||||
|
||||
--- a/drivers/staging/mt7621-dts/mt7621.dtsi
|
||||
+++ b/drivers/staging/mt7621-dts/mt7621.dtsi
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <dt-bindings/interrupt-controller/mips-gic.h>
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/clock/mt7621-clk.h>
|
||||
+#include <dt-bindings/reset/mt7621-reset.h>
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
@@ -59,6 +60,7 @@
|
||||
compatible = "mediatek,mt7621-sysc", "syscon";
|
||||
reg = <0x0 0x100>;
|
||||
#clock-cells = <1>;
|
||||
+ #reset-cells = <1>;
|
||||
ralink,memctl = <&memc>;
|
||||
clock-output-names = "xtal", "cpu", "bus",
|
||||
"50m", "125m", "150m",
|
||||
@@ -88,7 +90,7 @@
|
||||
|
||||
clocks = <&sysc MT7621_CLK_I2C>;
|
||||
clock-names = "i2c";
|
||||
- resets = <&rstctrl 16>;
|
||||
+ resets = <&sysc MT7621_RST_I2C>;
|
||||
reset-names = "i2c";
|
||||
|
||||
#address-cells = <1>;
|
||||
@@ -161,7 +163,7 @@
|
||||
clocks = <&sysc MT7621_CLK_SPI>;
|
||||
clock-names = "spi";
|
||||
|
||||
- resets = <&rstctrl 18>;
|
||||
+ resets = <&sysc MT7621_RST_SPI>;
|
||||
reset-names = "spi";
|
||||
|
||||
#address-cells = <1>;
|
||||
@@ -296,11 +298,6 @@
|
||||
};
|
||||
};
|
||||
|
||||
- rstctrl: rstctrl {
|
||||
- compatible = "ralink,rt2880-reset";
|
||||
- #reset-cells = <1>;
|
||||
- };
|
||||
-
|
||||
sdhci: sdhci@1e130000 {
|
||||
status = "disabled";
|
||||
|
||||
@@ -383,7 +380,7 @@
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
- resets = <&rstctrl 6 &rstctrl 23>;
|
||||
+ resets = <&sysc MT7621_RST_FE &sysc MT7621_RST_ETH>;
|
||||
reset-names = "fe", "eth";
|
||||
|
||||
interrupt-parent = <&gic>;
|
||||
@@ -423,7 +420,7 @@
|
||||
#size-cells = <0>;
|
||||
reg = <0>;
|
||||
mediatek,mcm;
|
||||
- resets = <&rstctrl 2>;
|
||||
+ resets = <&sysc MT7621_RST_MCM>;
|
||||
reset-names = "mcm";
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
@@ -516,7 +513,7 @@
|
||||
#interrupt-cells = <1>;
|
||||
interrupt-map-mask = <0 0 0 0>;
|
||||
interrupt-map = <0 0 0 0 &gic GIC_SHARED 4 IRQ_TYPE_LEVEL_HIGH>;
|
||||
- resets = <&rstctrl 24>;
|
||||
+ resets = <&sysc MT7621_RST_PCIE0>;
|
||||
clocks = <&sysc MT7621_CLK_PCIE0>;
|
||||
phys = <&pcie0_phy 1>;
|
||||
phy-names = "pcie-phy0";
|
||||
@@ -531,7 +528,7 @@
|
||||
#interrupt-cells = <1>;
|
||||
interrupt-map-mask = <0 0 0 0>;
|
||||
interrupt-map = <0 0 0 0 &gic GIC_SHARED 24 IRQ_TYPE_LEVEL_HIGH>;
|
||||
- resets = <&rstctrl 25>;
|
||||
+ resets = <&sysc MT7621_RST_PCIE1>;
|
||||
clocks = <&sysc MT7621_CLK_PCIE1>;
|
||||
phys = <&pcie0_phy 1>;
|
||||
phy-names = "pcie-phy1";
|
||||
@@ -546,7 +543,7 @@
|
||||
#interrupt-cells = <1>;
|
||||
interrupt-map-mask = <0 0 0 0>;
|
||||
interrupt-map = <0 0 0 0 &gic GIC_SHARED 25 IRQ_TYPE_LEVEL_HIGH>;
|
||||
- resets = <&rstctrl 26>;
|
||||
+ resets = <&sysc MT7621_RST_PCIE2>;
|
||||
clocks = <&sysc MT7621_CLK_PCIE2>;
|
||||
phys = <&pcie2_phy 0>;
|
||||
phy-names = "pcie-phy2";
|
@ -1,52 +0,0 @@
|
||||
From 478b09fa2c00cbc40d25bc061befdf11f04a27ad Mon Sep 17 00:00:00 2001
|
||||
From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Date: Thu, 10 Feb 2022 10:48:58 +0100
|
||||
Subject: [PATCH 1/2] dt-bindings: clock: mediatek,mt7621-sysc: add '#reset-cells' property
|
||||
|
||||
Make system controller a reset provider for all the peripherals in the
|
||||
MT7621 SoC adding '#reset-cells' property.
|
||||
|
||||
Acked-by: Rob Herring <robh@kernel.org>
|
||||
Acked-by: Stephen Boyd <sboyd@kernel.org>
|
||||
Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Link: https://lore.kernel.org/r/20220210094859.927868-2-sergio.paracuellos@gmail.com
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
.../devicetree/bindings/clock/mediatek,mt7621-sysc.yaml | 12 ++++++++++++
|
||||
1 file changed, 12 insertions(+)
|
||||
|
||||
--- a/Documentation/devicetree/bindings/clock/mediatek,mt7621-sysc.yaml
|
||||
+++ b/Documentation/devicetree/bindings/clock/mediatek,mt7621-sysc.yaml
|
||||
@@ -22,6 +22,11 @@ description: |
|
||||
|
||||
The clocks are provided inside a system controller node.
|
||||
|
||||
+ This node is also a reset provider for all the peripherals.
|
||||
+
|
||||
+ Reset related bits are defined in:
|
||||
+ [2]: <include/dt-bindings/reset/mt7621-reset.h>.
|
||||
+
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
@@ -37,6 +42,12 @@ properties:
|
||||
clocks.
|
||||
const: 1
|
||||
|
||||
+ "#reset-cells":
|
||||
+ description:
|
||||
+ The first cell indicates the reset bit within the register, see
|
||||
+ [2] for available resets.
|
||||
+ const: 1
|
||||
+
|
||||
ralink,memctl:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description:
|
||||
@@ -61,6 +72,7 @@ examples:
|
||||
compatible = "mediatek,mt7621-sysc", "syscon";
|
||||
reg = <0x0 0x100>;
|
||||
#clock-cells = <1>;
|
||||
+ #reset-cells = <1>;
|
||||
ralink,memctl = <&memc>;
|
||||
clock-output-names = "xtal", "cpu", "bus",
|
||||
"50m", "125m", "150m",
|
@ -1,148 +0,0 @@
|
||||
From 38a8553b0a22ed54f014d8402fedd268b529175c Mon Sep 17 00:00:00 2001
|
||||
From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Date: Thu, 10 Feb 2022 10:48:59 +0100
|
||||
Subject: [PATCH 2/2] clk: ralink: make system controller node a reset provider
|
||||
|
||||
MT7621 system controller node is already providing the clocks for the whole
|
||||
system but must also serve as a reset provider. Hence, add reset controller
|
||||
related code to the clock driver itself. To get resets properly ready for
|
||||
the rest of the world we need to move platform driver initialization process
|
||||
to 'arch_initcall'.
|
||||
|
||||
CC: Philipp Zabel <p.zabel@pengutronix.de>
|
||||
Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
|
||||
Acked-by: Stephen Boyd <sboyd@kernel.org>
|
||||
Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Link: https://lore.kernel.org/r/20220210094859.927868-3-sergio.paracuellos@gmail.com
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/clk/ralink/clk-mt7621.c | 92 ++++++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 91 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/clk/ralink/clk-mt7621.c
|
||||
+++ b/drivers/clk/ralink/clk-mt7621.c
|
||||
@@ -11,14 +11,17 @@
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
+#include <linux/reset-controller.h>
|
||||
#include <linux/slab.h>
|
||||
#include <dt-bindings/clock/mt7621-clk.h>
|
||||
+#include <dt-bindings/reset/mt7621-reset.h>
|
||||
|
||||
/* Configuration registers */
|
||||
#define SYSC_REG_SYSTEM_CONFIG0 0x10
|
||||
#define SYSC_REG_SYSTEM_CONFIG1 0x14
|
||||
#define SYSC_REG_CLKCFG0 0x2c
|
||||
#define SYSC_REG_CLKCFG1 0x30
|
||||
+#define SYSC_REG_RESET_CTRL 0x34
|
||||
#define SYSC_REG_CUR_CLK_STS 0x44
|
||||
#define MEMC_REG_CPU_PLL 0x648
|
||||
|
||||
@@ -398,6 +401,82 @@ free_clk_priv:
|
||||
}
|
||||
CLK_OF_DECLARE_DRIVER(mt7621_clk, "mediatek,mt7621-sysc", mt7621_clk_init);
|
||||
|
||||
+struct mt7621_rst {
|
||||
+ struct reset_controller_dev rcdev;
|
||||
+ struct regmap *sysc;
|
||||
+};
|
||||
+
|
||||
+static struct mt7621_rst *to_mt7621_rst(struct reset_controller_dev *dev)
|
||||
+{
|
||||
+ return container_of(dev, struct mt7621_rst, rcdev);
|
||||
+}
|
||||
+
|
||||
+static int mt7621_assert_device(struct reset_controller_dev *rcdev,
|
||||
+ unsigned long id)
|
||||
+{
|
||||
+ struct mt7621_rst *data = to_mt7621_rst(rcdev);
|
||||
+ struct regmap *sysc = data->sysc;
|
||||
+
|
||||
+ return regmap_update_bits(sysc, SYSC_REG_RESET_CTRL, BIT(id), BIT(id));
|
||||
+}
|
||||
+
|
||||
+static int mt7621_deassert_device(struct reset_controller_dev *rcdev,
|
||||
+ unsigned long id)
|
||||
+{
|
||||
+ struct mt7621_rst *data = to_mt7621_rst(rcdev);
|
||||
+ struct regmap *sysc = data->sysc;
|
||||
+
|
||||
+ return regmap_update_bits(sysc, SYSC_REG_RESET_CTRL, BIT(id), 0);
|
||||
+}
|
||||
+
|
||||
+static int mt7621_reset_device(struct reset_controller_dev *rcdev,
|
||||
+ unsigned long id)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = mt7621_assert_device(rcdev, id);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ return mt7621_deassert_device(rcdev, id);
|
||||
+}
|
||||
+
|
||||
+static int mt7621_rst_xlate(struct reset_controller_dev *rcdev,
|
||||
+ const struct of_phandle_args *reset_spec)
|
||||
+{
|
||||
+ unsigned long id = reset_spec->args[0];
|
||||
+
|
||||
+ if (id == MT7621_RST_SYS || id >= rcdev->nr_resets)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ return id;
|
||||
+}
|
||||
+
|
||||
+static const struct reset_control_ops reset_ops = {
|
||||
+ .reset = mt7621_reset_device,
|
||||
+ .assert = mt7621_assert_device,
|
||||
+ .deassert = mt7621_deassert_device
|
||||
+};
|
||||
+
|
||||
+static int mt7621_reset_init(struct device *dev, struct regmap *sysc)
|
||||
+{
|
||||
+ struct mt7621_rst *rst_data;
|
||||
+
|
||||
+ rst_data = devm_kzalloc(dev, sizeof(*rst_data), GFP_KERNEL);
|
||||
+ if (!rst_data)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ rst_data->sysc = sysc;
|
||||
+ rst_data->rcdev.ops = &reset_ops;
|
||||
+ rst_data->rcdev.owner = THIS_MODULE;
|
||||
+ rst_data->rcdev.nr_resets = 32;
|
||||
+ rst_data->rcdev.of_reset_n_cells = 1;
|
||||
+ rst_data->rcdev.of_xlate = mt7621_rst_xlate;
|
||||
+ rst_data->rcdev.of_node = dev_of_node(dev);
|
||||
+
|
||||
+ return devm_reset_controller_register(dev, &rst_data->rcdev);
|
||||
+}
|
||||
+
|
||||
static int mt7621_clk_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
@@ -424,6 +503,12 @@ static int mt7621_clk_probe(struct platf
|
||||
return ret;
|
||||
}
|
||||
|
||||
+ ret = mt7621_reset_init(dev, priv->sysc);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "Could not init reset controller\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
count = ARRAY_SIZE(mt7621_clks_base) +
|
||||
ARRAY_SIZE(mt7621_fixed_clks) + ARRAY_SIZE(mt7621_gates);
|
||||
clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, count),
|
||||
@@ -485,4 +570,9 @@ static struct platform_driver mt7621_clk
|
||||
.of_match_table = mt7621_clk_of_match,
|
||||
},
|
||||
};
|
||||
-builtin_platform_driver(mt7621_clk_driver);
|
||||
+
|
||||
+static int __init mt7621_clk_reset_init(void)
|
||||
+{
|
||||
+ return platform_driver_register(&mt7621_clk_driver);
|
||||
+}
|
||||
+arch_initcall(mt7621_clk_reset_init);
|
@ -1,43 +0,0 @@
|
||||
From bb3ababe7f986900672e0048153c31aa4a21f96b Mon Sep 17 00:00:00 2001
|
||||
From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Date: Sat, 17 Dec 2022 08:48:06 +0100
|
||||
Subject: [PATCH] MIPS: ralink: mt7621: avoid to init common ralink reset controller
|
||||
|
||||
[ Upstream commit 76ce51798cb16738a4a28a6662e7344aaf7ef769 ]
|
||||
|
||||
Commit 38a8553b0a22 ("clk: ralink: make system controller node a reset provider")
|
||||
make system controller a reset provider for mt7621 ralink SoCs. Ralink init code
|
||||
also tries to start previous common reset controller which at the end tries to
|
||||
find device tree node 'ralink,rt2880-reset'. mt7621 device tree file is not
|
||||
using at all this node anymore. Hence avoid to init this common reset controller
|
||||
for mt7621 ralink SoCs to avoid 'Failed to find reset controller node' boot
|
||||
error trace error.
|
||||
|
||||
Fixes: 64b2d6ffff86 ("staging: mt7621-dts: align resets with binding documentation")
|
||||
Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
|
||||
Signed-off-by: Sasha Levin <sashal@kernel.org>
|
||||
---
|
||||
arch/mips/ralink/of.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/arch/mips/ralink/of.c
|
||||
+++ b/arch/mips/ralink/of.c
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <asm/bootinfo.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/prom.h>
|
||||
+#include <asm/mach-ralink/ralink_regs.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
@@ -95,7 +96,8 @@ static int __init plat_of_setup(void)
|
||||
__dt_register_buses(soc_info.compatible, "palmbus");
|
||||
|
||||
/* make sure that the reset controller is setup early */
|
||||
- ralink_rst_init();
|
||||
+ if (ralink_soc != MT762X_SOC_MT7621AT)
|
||||
+ ralink_rst_init();
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,77 +0,0 @@
|
||||
From 35dcae535afc153fa83f2fe51c0812536c192c58 Mon Sep 17 00:00:00 2001
|
||||
From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Date: Mon, 6 Feb 2023 09:33:05 +0100
|
||||
Subject: [PATCH] clk: ralink: fix 'mt7621_gate_is_enabled()' function
|
||||
|
||||
Compiling clock driver with CONFIG_UBSAN enabled shows the following trace:
|
||||
|
||||
UBSAN: shift-out-of-bounds in drivers/clk/ralink/clk-mt7621.c:121:15
|
||||
shift exponent 131072 is too large for 32-bit type 'long unsigned int'
|
||||
CPU: 1 PID: 1 Comm: swapper/0 Not tainted 5.15.86 #0
|
||||
Stack : ...
|
||||
|
||||
Call Trace:
|
||||
[<80009a58>] show_stack+0x38/0x118
|
||||
[<8045ce04>] dump_stack_lvl+0x60/0x80
|
||||
[<80458868>] ubsan_epilogue+0x10/0x54
|
||||
[<804590e0>] __ubsan_handle_shift_out_of_bounds+0x118/0x190
|
||||
[<804c9a10>] mt7621_gate_is_enabled+0x98/0xa0
|
||||
[<804bb774>] clk_core_is_enabled+0x34/0x90
|
||||
[<80aad73c>] clk_disable_unused_subtree+0x98/0x1e4
|
||||
[<80aad6d4>] clk_disable_unused_subtree+0x30/0x1e4
|
||||
[<80aad6d4>] clk_disable_unused_subtree+0x30/0x1e4
|
||||
[<80aad900>] clk_disable_unused+0x78/0x120
|
||||
[<80002030>] do_one_initcall+0x54/0x1f0
|
||||
[<80a922a4>] kernel_init_freeable+0x280/0x31c
|
||||
[<808047c4>] kernel_init+0x20/0x118
|
||||
[<80003e58>] ret_from_kernel_thread+0x14/0x1c
|
||||
|
||||
Shifting a value (131032) larger than the type (32 bit unsigned integer)
|
||||
is undefined behaviour in C.
|
||||
|
||||
The problem is in 'mt7621_gate_is_enabled()' function which is using the
|
||||
'BIT()' kernel macro with the bit index for the clock gate to check if the
|
||||
bit is set. When the clock gates structure is created driver is already
|
||||
setting 'bit_idx' using 'BIT()' macro, so we are wrongly applying an extra
|
||||
'BIT()' mask here. Removing it solve the problem and makes this function
|
||||
correct. However when clock gating is correctly working, the kernel starts
|
||||
disabling those clocks that are not requested. Some drivers for this SoC
|
||||
are older than this clock driver itself. So to avoid the kernel to disable
|
||||
clocks that have been enabled until now, we must apply 'CLK_IS_CRITICAL'
|
||||
flag on gates initialization code.
|
||||
|
||||
Fixes: 48df7a26f470 ("clk: ralink: add clock driver for mt7621 SoC")
|
||||
Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Link: https://lore.kernel.org/r/20230206083305.147582-1-sergio.paracuellos@gmail.com
|
||||
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
|
||||
---
|
||||
drivers/clk/ralink/clk-mt7621.c | 10 ++++++++--
|
||||
1 file changed, 8 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/clk/ralink/clk-mt7621.c
|
||||
+++ b/drivers/clk/ralink/clk-mt7621.c
|
||||
@@ -121,7 +121,7 @@ static int mt7621_gate_is_enabled(struct
|
||||
if (regmap_read(sysc, SYSC_REG_CLKCFG1, &val))
|
||||
return 0;
|
||||
|
||||
- return val & BIT(clk_gate->bit_idx);
|
||||
+ return val & clk_gate->bit_idx;
|
||||
}
|
||||
|
||||
static const struct clk_ops mt7621_gate_ops = {
|
||||
@@ -133,8 +133,14 @@ static const struct clk_ops mt7621_gate_
|
||||
static int mt7621_gate_ops_init(struct device *dev,
|
||||
struct mt7621_gate *sclk)
|
||||
{
|
||||
+ /*
|
||||
+ * There are drivers for this SoC that are older
|
||||
+ * than clock driver and are not prepared for the clock.
|
||||
+ * We don't want the kernel to disable anything so we
|
||||
+ * add CLK_IS_CRITICAL flag here.
|
||||
+ */
|
||||
struct clk_init_data init = {
|
||||
- .flags = CLK_SET_RATE_PARENT,
|
||||
+ .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
|
||||
.num_parents = 1,
|
||||
.parent_names = &sclk->parent_name,
|
||||
.ops = &mt7621_gate_ops,
|
@ -1,86 +0,0 @@
|
||||
From 612616e6381929e7f9e303f8b8ad3655cc101516 Mon Sep 17 00:00:00 2001
|
||||
From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Date: Mon, 19 Jun 2023 06:09:33 +0200
|
||||
Subject: [PATCH 1/9] dt-bindings: clock: add mtmips SoCs system controller
|
||||
|
||||
Adds device tree binding documentation for system controller node present
|
||||
in Mediatek MIPS and Ralink SOCs. This node is a clock and reset provider
|
||||
for the rest of the world. This covers RT2880, RT3050, RT3052, RT3350,
|
||||
RT3883, RT5350, MT7620, MT7628 and MT7688 SoCs.
|
||||
|
||||
Reviewed-by: Rob Herring <robh@kernel.org>
|
||||
Acked-by: Stephen Boyd <sboyd@kernel.org>
|
||||
Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
|
||||
---
|
||||
.../bindings/clock/mediatek,mtmips-sysc.yaml | 64 ++++++++++++++++++++++
|
||||
1 file changed, 64 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/clock/mediatek,mtmips-sysc.yaml
|
||||
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/clock/mediatek,mtmips-sysc.yaml
|
||||
@@ -0,0 +1,64 @@
|
||||
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
+%YAML 1.2
|
||||
+---
|
||||
+$id: http://devicetree.org/schemas/clock/mediatek,mtmips-sysc.yaml#
|
||||
+$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
+
|
||||
+title: MTMIPS SoCs System Controller
|
||||
+
|
||||
+maintainers:
|
||||
+ - Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
+
|
||||
+description: |
|
||||
+ MediaTek MIPS and Ralink SoCs provides a system controller to allow
|
||||
+ to access to system control registers. These registers include clock
|
||||
+ and reset related ones so this node is both clock and reset provider
|
||||
+ for the rest of the world.
|
||||
+
|
||||
+ These SoCs have an XTAL from where the cpu clock is
|
||||
+ provided as well as derived clocks for the bus and the peripherals.
|
||||
+
|
||||
+properties:
|
||||
+ compatible:
|
||||
+ items:
|
||||
+ - enum:
|
||||
+ - ralink,mt7620-sysc
|
||||
+ - ralink,mt7628-sysc
|
||||
+ - ralink,mt7688-sysc
|
||||
+ - ralink,rt2880-sysc
|
||||
+ - ralink,rt3050-sysc
|
||||
+ - ralink,rt3052-sysc
|
||||
+ - ralink,rt3352-sysc
|
||||
+ - ralink,rt3883-sysc
|
||||
+ - ralink,rt5350-sysc
|
||||
+ - const: syscon
|
||||
+
|
||||
+ reg:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ '#clock-cells':
|
||||
+ description:
|
||||
+ The first cell indicates the clock number.
|
||||
+ const: 1
|
||||
+
|
||||
+ '#reset-cells':
|
||||
+ description:
|
||||
+ The first cell indicates the reset bit within the register.
|
||||
+ const: 1
|
||||
+
|
||||
+required:
|
||||
+ - compatible
|
||||
+ - reg
|
||||
+ - '#clock-cells'
|
||||
+ - '#reset-cells'
|
||||
+
|
||||
+additionalProperties: false
|
||||
+
|
||||
+examples:
|
||||
+ - |
|
||||
+ syscon@0 {
|
||||
+ compatible = "ralink,rt5350-sysc", "syscon";
|
||||
+ reg = <0x0 0x100>;
|
||||
+ #clock-cells = <1>;
|
||||
+ #reset-cells = <1>;
|
||||
+ };
|
File diff suppressed because it is too large
Load Diff
@ -1,81 +0,0 @@
|
||||
From ffcdf47379eae86dc8f8f02c62994dacf2c9038e Mon Sep 17 00:00:00 2001
|
||||
From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Date: Mon, 19 Jun 2023 06:09:35 +0200
|
||||
Subject: [PATCH 3/9] mips: ralink: rt288x: remove clock related code
|
||||
|
||||
A properly clock driver for ralink SoCs has been added. Hence there is no
|
||||
need to have clock related code in 'arch/mips/ralink' folder anymore.
|
||||
|
||||
Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
|
||||
---
|
||||
arch/mips/include/asm/mach-ralink/rt288x.h | 10 ----------
|
||||
arch/mips/ralink/rt288x.c | 31 ------------------------------
|
||||
2 files changed, 41 deletions(-)
|
||||
|
||||
--- a/arch/mips/include/asm/mach-ralink/rt288x.h
|
||||
+++ b/arch/mips/include/asm/mach-ralink/rt288x.h
|
||||
@@ -17,7 +17,6 @@
|
||||
#define SYSC_REG_CHIP_NAME1 0x04
|
||||
#define SYSC_REG_CHIP_ID 0x0c
|
||||
#define SYSC_REG_SYSTEM_CONFIG 0x10
|
||||
-#define SYSC_REG_CLKCFG 0x30
|
||||
|
||||
#define RT2880_CHIP_NAME0 0x38325452
|
||||
#define RT2880_CHIP_NAME1 0x20203038
|
||||
@@ -26,15 +25,6 @@
|
||||
#define CHIP_ID_ID_SHIFT 8
|
||||
#define CHIP_ID_REV_MASK 0xff
|
||||
|
||||
-#define SYSTEM_CONFIG_CPUCLK_SHIFT 20
|
||||
-#define SYSTEM_CONFIG_CPUCLK_MASK 0x3
|
||||
-#define SYSTEM_CONFIG_CPUCLK_250 0x0
|
||||
-#define SYSTEM_CONFIG_CPUCLK_266 0x1
|
||||
-#define SYSTEM_CONFIG_CPUCLK_280 0x2
|
||||
-#define SYSTEM_CONFIG_CPUCLK_300 0x3
|
||||
-
|
||||
-#define CLKCFG_SRAM_CS_N_WDT BIT(9)
|
||||
-
|
||||
#define RT2880_SDRAM_BASE 0x08000000
|
||||
#define RT2880_MEM_SIZE_MIN 2
|
||||
#define RT2880_MEM_SIZE_MAX 128
|
||||
--- a/arch/mips/ralink/rt288x.c
|
||||
+++ b/arch/mips/ralink/rt288x.c
|
||||
@@ -17,37 +17,6 @@
|
||||
|
||||
#include "common.h"
|
||||
|
||||
-void __init ralink_clk_init(void)
|
||||
-{
|
||||
- unsigned long cpu_rate, wmac_rate = 40000000;
|
||||
- u32 t = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG);
|
||||
- t = ((t >> SYSTEM_CONFIG_CPUCLK_SHIFT) & SYSTEM_CONFIG_CPUCLK_MASK);
|
||||
-
|
||||
- switch (t) {
|
||||
- case SYSTEM_CONFIG_CPUCLK_250:
|
||||
- cpu_rate = 250000000;
|
||||
- break;
|
||||
- case SYSTEM_CONFIG_CPUCLK_266:
|
||||
- cpu_rate = 266666667;
|
||||
- break;
|
||||
- case SYSTEM_CONFIG_CPUCLK_280:
|
||||
- cpu_rate = 280000000;
|
||||
- break;
|
||||
- case SYSTEM_CONFIG_CPUCLK_300:
|
||||
- cpu_rate = 300000000;
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- ralink_clk_add("cpu", cpu_rate);
|
||||
- ralink_clk_add("300100.timer", cpu_rate / 2);
|
||||
- ralink_clk_add("300120.watchdog", cpu_rate / 2);
|
||||
- ralink_clk_add("300500.uart", cpu_rate / 2);
|
||||
- ralink_clk_add("300900.i2c", cpu_rate / 2);
|
||||
- ralink_clk_add("300c00.uartlite", cpu_rate / 2);
|
||||
- ralink_clk_add("400000.ethernet", cpu_rate / 2);
|
||||
- ralink_clk_add("480000.wmac", wmac_rate);
|
||||
-}
|
||||
-
|
||||
void __init ralink_of_remap(void)
|
||||
{
|
||||
rt_sysc_membase = plat_of_remap_node("ralink,rt2880-sysc");
|
@ -1,145 +0,0 @@
|
||||
From daf73c70f69386fb15960526772ef584a4efcaf2 Mon Sep 17 00:00:00 2001
|
||||
From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Date: Mon, 19 Jun 2023 06:09:36 +0200
|
||||
Subject: [PATCH 4/9] mips: ralink: rt305x: remove clock related code
|
||||
|
||||
A properly clock driver for ralink SoCs has been added. Hence there is no
|
||||
need to have clock related code in 'arch/mips/ralink' folder anymore.
|
||||
|
||||
Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
|
||||
---
|
||||
arch/mips/include/asm/mach-ralink/rt305x.h | 21 --------
|
||||
arch/mips/ralink/rt305x.c | 78 ------------------------------
|
||||
2 files changed, 99 deletions(-)
|
||||
|
||||
--- a/arch/mips/include/asm/mach-ralink/rt305x.h
|
||||
+++ b/arch/mips/include/asm/mach-ralink/rt305x.h
|
||||
@@ -66,26 +66,9 @@ static inline int soc_is_rt5350(void)
|
||||
#define CHIP_ID_ID_SHIFT 8
|
||||
#define CHIP_ID_REV_MASK 0xff
|
||||
|
||||
-#define RT305X_SYSCFG_CPUCLK_SHIFT 18
|
||||
-#define RT305X_SYSCFG_CPUCLK_MASK 0x1
|
||||
-#define RT305X_SYSCFG_CPUCLK_LOW 0x0
|
||||
-#define RT305X_SYSCFG_CPUCLK_HIGH 0x1
|
||||
-
|
||||
#define RT305X_SYSCFG_SRAM_CS0_MODE_SHIFT 2
|
||||
-#define RT305X_SYSCFG_CPUCLK_MASK 0x1
|
||||
#define RT305X_SYSCFG_SRAM_CS0_MODE_WDT 0x1
|
||||
|
||||
-#define RT3352_SYSCFG0_CPUCLK_SHIFT 8
|
||||
-#define RT3352_SYSCFG0_CPUCLK_MASK 0x1
|
||||
-#define RT3352_SYSCFG0_CPUCLK_LOW 0x0
|
||||
-#define RT3352_SYSCFG0_CPUCLK_HIGH 0x1
|
||||
-
|
||||
-#define RT5350_SYSCFG0_CPUCLK_SHIFT 8
|
||||
-#define RT5350_SYSCFG0_CPUCLK_MASK 0x3
|
||||
-#define RT5350_SYSCFG0_CPUCLK_360 0x0
|
||||
-#define RT5350_SYSCFG0_CPUCLK_320 0x2
|
||||
-#define RT5350_SYSCFG0_CPUCLK_300 0x3
|
||||
-
|
||||
#define RT5350_SYSCFG0_DRAM_SIZE_SHIFT 12
|
||||
#define RT5350_SYSCFG0_DRAM_SIZE_MASK 7
|
||||
#define RT5350_SYSCFG0_DRAM_SIZE_2M 0
|
||||
@@ -116,13 +99,9 @@ static inline int soc_is_rt5350(void)
|
||||
|
||||
#define RT3352_SYSC_REG_SYSCFG0 0x010
|
||||
#define RT3352_SYSC_REG_SYSCFG1 0x014
|
||||
-#define RT3352_SYSC_REG_CLKCFG1 0x030
|
||||
#define RT3352_SYSC_REG_RSTCTRL 0x034
|
||||
#define RT3352_SYSC_REG_USB_PS 0x05c
|
||||
|
||||
-#define RT3352_CLKCFG0_XTAL_SEL BIT(20)
|
||||
-#define RT3352_CLKCFG1_UPHY0_CLK_EN BIT(18)
|
||||
-#define RT3352_CLKCFG1_UPHY1_CLK_EN BIT(20)
|
||||
#define RT3352_RSTCTRL_UHST BIT(22)
|
||||
#define RT3352_RSTCTRL_UDEV BIT(25)
|
||||
#define RT3352_SYSCFG1_USB0_HOST_MODE BIT(10)
|
||||
--- a/arch/mips/ralink/rt305x.c
|
||||
+++ b/arch/mips/ralink/rt305x.c
|
||||
@@ -53,84 +53,6 @@ static unsigned long rt5350_get_mem_size
|
||||
return ret;
|
||||
}
|
||||
|
||||
-void __init ralink_clk_init(void)
|
||||
-{
|
||||
- unsigned long cpu_rate, sys_rate, wdt_rate, uart_rate;
|
||||
- unsigned long wmac_rate = 40000000;
|
||||
-
|
||||
- u32 t = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG);
|
||||
-
|
||||
- if (soc_is_rt305x() || soc_is_rt3350()) {
|
||||
- t = (t >> RT305X_SYSCFG_CPUCLK_SHIFT) &
|
||||
- RT305X_SYSCFG_CPUCLK_MASK;
|
||||
- switch (t) {
|
||||
- case RT305X_SYSCFG_CPUCLK_LOW:
|
||||
- cpu_rate = 320000000;
|
||||
- break;
|
||||
- case RT305X_SYSCFG_CPUCLK_HIGH:
|
||||
- cpu_rate = 384000000;
|
||||
- break;
|
||||
- }
|
||||
- sys_rate = uart_rate = wdt_rate = cpu_rate / 3;
|
||||
- } else if (soc_is_rt3352()) {
|
||||
- t = (t >> RT3352_SYSCFG0_CPUCLK_SHIFT) &
|
||||
- RT3352_SYSCFG0_CPUCLK_MASK;
|
||||
- switch (t) {
|
||||
- case RT3352_SYSCFG0_CPUCLK_LOW:
|
||||
- cpu_rate = 384000000;
|
||||
- break;
|
||||
- case RT3352_SYSCFG0_CPUCLK_HIGH:
|
||||
- cpu_rate = 400000000;
|
||||
- break;
|
||||
- }
|
||||
- sys_rate = wdt_rate = cpu_rate / 3;
|
||||
- uart_rate = 40000000;
|
||||
- } else if (soc_is_rt5350()) {
|
||||
- t = (t >> RT5350_SYSCFG0_CPUCLK_SHIFT) &
|
||||
- RT5350_SYSCFG0_CPUCLK_MASK;
|
||||
- switch (t) {
|
||||
- case RT5350_SYSCFG0_CPUCLK_360:
|
||||
- cpu_rate = 360000000;
|
||||
- sys_rate = cpu_rate / 3;
|
||||
- break;
|
||||
- case RT5350_SYSCFG0_CPUCLK_320:
|
||||
- cpu_rate = 320000000;
|
||||
- sys_rate = cpu_rate / 4;
|
||||
- break;
|
||||
- case RT5350_SYSCFG0_CPUCLK_300:
|
||||
- cpu_rate = 300000000;
|
||||
- sys_rate = cpu_rate / 3;
|
||||
- break;
|
||||
- default:
|
||||
- BUG();
|
||||
- }
|
||||
- uart_rate = 40000000;
|
||||
- wdt_rate = sys_rate;
|
||||
- } else {
|
||||
- BUG();
|
||||
- }
|
||||
-
|
||||
- if (soc_is_rt3352() || soc_is_rt5350()) {
|
||||
- u32 val = rt_sysc_r32(RT3352_SYSC_REG_SYSCFG0);
|
||||
-
|
||||
- if (!(val & RT3352_CLKCFG0_XTAL_SEL))
|
||||
- wmac_rate = 20000000;
|
||||
- }
|
||||
-
|
||||
- ralink_clk_add("cpu", cpu_rate);
|
||||
- ralink_clk_add("sys", sys_rate);
|
||||
- ralink_clk_add("10000900.i2c", uart_rate);
|
||||
- ralink_clk_add("10000a00.i2s", uart_rate);
|
||||
- ralink_clk_add("10000b00.spi", sys_rate);
|
||||
- ralink_clk_add("10000b40.spi", sys_rate);
|
||||
- ralink_clk_add("10000100.timer", wdt_rate);
|
||||
- ralink_clk_add("10000120.watchdog", wdt_rate);
|
||||
- ralink_clk_add("10000500.uart", uart_rate);
|
||||
- ralink_clk_add("10000c00.uartlite", uart_rate);
|
||||
- ralink_clk_add("10100000.ethernet", sys_rate);
|
||||
- ralink_clk_add("10180000.wmac", wmac_rate);
|
||||
-}
|
||||
-
|
||||
void __init ralink_of_remap(void)
|
||||
{
|
||||
rt_sysc_membase = plat_of_remap_node("ralink,rt3050-sysc");
|
@ -1,85 +0,0 @@
|
||||
From 7cd1bb48885449a9323c7ff0f10012925e93b4e1 Mon Sep 17 00:00:00 2001
|
||||
From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Date: Mon, 19 Jun 2023 06:09:37 +0200
|
||||
Subject: [PATCH 5/9] mips: ralink: rt3883: remove clock related code
|
||||
|
||||
A properly clock driver for ralink SoCs has been added. Hence there is no
|
||||
need to have clock related code in 'arch/mips/ralink' folder anymore.
|
||||
|
||||
Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
|
||||
---
|
||||
arch/mips/include/asm/mach-ralink/rt3883.h | 8 ------
|
||||
arch/mips/ralink/rt3883.c | 44 ------------------------------
|
||||
2 files changed, 52 deletions(-)
|
||||
|
||||
--- a/arch/mips/include/asm/mach-ralink/rt3883.h
|
||||
+++ b/arch/mips/include/asm/mach-ralink/rt3883.h
|
||||
@@ -90,14 +90,6 @@
|
||||
#define RT3883_REVID_VER_ID_SHIFT 8
|
||||
#define RT3883_REVID_ECO_ID_MASK 0x0f
|
||||
|
||||
-#define RT3883_SYSCFG0_DRAM_TYPE_DDR2 BIT(17)
|
||||
-#define RT3883_SYSCFG0_CPUCLK_SHIFT 8
|
||||
-#define RT3883_SYSCFG0_CPUCLK_MASK 0x3
|
||||
-#define RT3883_SYSCFG0_CPUCLK_250 0x0
|
||||
-#define RT3883_SYSCFG0_CPUCLK_384 0x1
|
||||
-#define RT3883_SYSCFG0_CPUCLK_480 0x2
|
||||
-#define RT3883_SYSCFG0_CPUCLK_500 0x3
|
||||
-
|
||||
#define RT3883_SYSCFG1_USB0_HOST_MODE BIT(10)
|
||||
#define RT3883_SYSCFG1_PCIE_RC_MODE BIT(8)
|
||||
#define RT3883_SYSCFG1_PCI_HOST_MODE BIT(7)
|
||||
--- a/arch/mips/ralink/rt3883.c
|
||||
+++ b/arch/mips/ralink/rt3883.c
|
||||
@@ -17,50 +17,6 @@
|
||||
|
||||
#include "common.h"
|
||||
|
||||
-void __init ralink_clk_init(void)
|
||||
-{
|
||||
- unsigned long cpu_rate, sys_rate;
|
||||
- u32 syscfg0;
|
||||
- u32 clksel;
|
||||
- u32 ddr2;
|
||||
-
|
||||
- syscfg0 = rt_sysc_r32(RT3883_SYSC_REG_SYSCFG0);
|
||||
- clksel = ((syscfg0 >> RT3883_SYSCFG0_CPUCLK_SHIFT) &
|
||||
- RT3883_SYSCFG0_CPUCLK_MASK);
|
||||
- ddr2 = syscfg0 & RT3883_SYSCFG0_DRAM_TYPE_DDR2;
|
||||
-
|
||||
- switch (clksel) {
|
||||
- case RT3883_SYSCFG0_CPUCLK_250:
|
||||
- cpu_rate = 250000000;
|
||||
- sys_rate = (ddr2) ? 125000000 : 83000000;
|
||||
- break;
|
||||
- case RT3883_SYSCFG0_CPUCLK_384:
|
||||
- cpu_rate = 384000000;
|
||||
- sys_rate = (ddr2) ? 128000000 : 96000000;
|
||||
- break;
|
||||
- case RT3883_SYSCFG0_CPUCLK_480:
|
||||
- cpu_rate = 480000000;
|
||||
- sys_rate = (ddr2) ? 160000000 : 120000000;
|
||||
- break;
|
||||
- case RT3883_SYSCFG0_CPUCLK_500:
|
||||
- cpu_rate = 500000000;
|
||||
- sys_rate = (ddr2) ? 166000000 : 125000000;
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- ralink_clk_add("cpu", cpu_rate);
|
||||
- ralink_clk_add("10000100.timer", sys_rate);
|
||||
- ralink_clk_add("10000120.watchdog", sys_rate);
|
||||
- ralink_clk_add("10000500.uart", 40000000);
|
||||
- ralink_clk_add("10000900.i2c", 40000000);
|
||||
- ralink_clk_add("10000a00.i2s", 40000000);
|
||||
- ralink_clk_add("10000b00.spi", sys_rate);
|
||||
- ralink_clk_add("10000b40.spi", sys_rate);
|
||||
- ralink_clk_add("10000c00.uartlite", 40000000);
|
||||
- ralink_clk_add("10100000.ethernet", sys_rate);
|
||||
- ralink_clk_add("10180000.wmac", 40000000);
|
||||
-}
|
||||
-
|
||||
void __init ralink_of_remap(void)
|
||||
{
|
||||
rt_sysc_membase = plat_of_remap_node("ralink,rt3883-sysc");
|
@ -1,327 +0,0 @@
|
||||
From 04b153abdfcbaba70ceef5a846067d4447fd0078 Mon Sep 17 00:00:00 2001
|
||||
From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Date: Mon, 19 Jun 2023 06:09:38 +0200
|
||||
Subject: [PATCH 6/9] mips: ralink: mt7620: remove clock related code
|
||||
|
||||
A proper clock driver for ralink SoCs has been added. Hence there is no
|
||||
need to have clock related code in 'arch/mips/ralink' folder anymore.
|
||||
Since this is the last clock related code removal, remove also remaining
|
||||
prototypes in 'common.h' header file.
|
||||
|
||||
Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
|
||||
---
|
||||
arch/mips/include/asm/mach-ralink/mt7620.h | 35 -----
|
||||
arch/mips/ralink/common.h | 3 -
|
||||
arch/mips/ralink/mt7620.c | 226 -----------------------------
|
||||
3 files changed, 264 deletions(-)
|
||||
|
||||
--- a/arch/mips/include/asm/mach-ralink/mt7620.h
|
||||
+++ b/arch/mips/include/asm/mach-ralink/mt7620.h
|
||||
@@ -19,52 +19,17 @@
|
||||
#define SYSC_REG_CHIP_REV 0x0c
|
||||
#define SYSC_REG_SYSTEM_CONFIG0 0x10
|
||||
#define SYSC_REG_SYSTEM_CONFIG1 0x14
|
||||
-#define SYSC_REG_CLKCFG0 0x2c
|
||||
-#define SYSC_REG_CPU_SYS_CLKCFG 0x3c
|
||||
-#define SYSC_REG_CPLL_CONFIG0 0x54
|
||||
-#define SYSC_REG_CPLL_CONFIG1 0x58
|
||||
|
||||
#define MT7620_CHIP_NAME0 0x3637544d
|
||||
#define MT7620_CHIP_NAME1 0x20203032
|
||||
#define MT7628_CHIP_NAME1 0x20203832
|
||||
|
||||
-#define SYSCFG0_XTAL_FREQ_SEL BIT(6)
|
||||
-
|
||||
#define CHIP_REV_PKG_MASK 0x1
|
||||
#define CHIP_REV_PKG_SHIFT 16
|
||||
#define CHIP_REV_VER_MASK 0xf
|
||||
#define CHIP_REV_VER_SHIFT 8
|
||||
#define CHIP_REV_ECO_MASK 0xf
|
||||
|
||||
-#define CLKCFG0_PERI_CLK_SEL BIT(4)
|
||||
-
|
||||
-#define CPU_SYS_CLKCFG_OCP_RATIO_SHIFT 16
|
||||
-#define CPU_SYS_CLKCFG_OCP_RATIO_MASK 0xf
|
||||
-#define CPU_SYS_CLKCFG_OCP_RATIO_1 0 /* 1:1 (Reserved) */
|
||||
-#define CPU_SYS_CLKCFG_OCP_RATIO_1_5 1 /* 1:1.5 (Reserved) */
|
||||
-#define CPU_SYS_CLKCFG_OCP_RATIO_2 2 /* 1:2 */
|
||||
-#define CPU_SYS_CLKCFG_OCP_RATIO_2_5 3 /* 1:2.5 (Reserved) */
|
||||
-#define CPU_SYS_CLKCFG_OCP_RATIO_3 4 /* 1:3 */
|
||||
-#define CPU_SYS_CLKCFG_OCP_RATIO_3_5 5 /* 1:3.5 (Reserved) */
|
||||
-#define CPU_SYS_CLKCFG_OCP_RATIO_4 6 /* 1:4 */
|
||||
-#define CPU_SYS_CLKCFG_OCP_RATIO_5 7 /* 1:5 */
|
||||
-#define CPU_SYS_CLKCFG_OCP_RATIO_10 8 /* 1:10 */
|
||||
-#define CPU_SYS_CLKCFG_CPU_FDIV_SHIFT 8
|
||||
-#define CPU_SYS_CLKCFG_CPU_FDIV_MASK 0x1f
|
||||
-#define CPU_SYS_CLKCFG_CPU_FFRAC_SHIFT 0
|
||||
-#define CPU_SYS_CLKCFG_CPU_FFRAC_MASK 0x1f
|
||||
-
|
||||
-#define CPLL_CFG0_SW_CFG BIT(31)
|
||||
-#define CPLL_CFG0_PLL_MULT_RATIO_SHIFT 16
|
||||
-#define CPLL_CFG0_PLL_MULT_RATIO_MASK 0x7
|
||||
-#define CPLL_CFG0_LC_CURFCK BIT(15)
|
||||
-#define CPLL_CFG0_BYPASS_REF_CLK BIT(14)
|
||||
-#define CPLL_CFG0_PLL_DIV_RATIO_SHIFT 10
|
||||
-#define CPLL_CFG0_PLL_DIV_RATIO_MASK 0x3
|
||||
-
|
||||
-#define CPLL_CFG1_CPU_AUX1 BIT(25)
|
||||
-#define CPLL_CFG1_CPU_AUX0 BIT(24)
|
||||
-
|
||||
#define SYSCFG0_DRAM_TYPE_MASK 0x3
|
||||
#define SYSCFG0_DRAM_TYPE_SHIFT 4
|
||||
#define SYSCFG0_DRAM_TYPE_SDRAM 0
|
||||
--- a/arch/mips/ralink/common.h
|
||||
+++ b/arch/mips/ralink/common.h
|
||||
@@ -23,9 +23,6 @@ extern struct ralink_soc_info soc_info;
|
||||
|
||||
extern void ralink_of_remap(void);
|
||||
|
||||
-extern void ralink_clk_init(void);
|
||||
-extern void ralink_clk_add(const char *dev, unsigned long rate);
|
||||
-
|
||||
extern void ralink_rst_init(void);
|
||||
|
||||
extern void __init prom_soc_init(struct ralink_soc_info *soc_info);
|
||||
--- a/arch/mips/ralink/mt7620.c
|
||||
+++ b/arch/mips/ralink/mt7620.c
|
||||
@@ -34,12 +34,6 @@
|
||||
#define PMU1_CFG 0x8C
|
||||
#define DIG_SW_SEL BIT(25)
|
||||
|
||||
-/* clock scaling */
|
||||
-#define CLKCFG_FDIV_MASK 0x1f00
|
||||
-#define CLKCFG_FDIV_USB_VAL 0x0300
|
||||
-#define CLKCFG_FFRAC_MASK 0x001f
|
||||
-#define CLKCFG_FFRAC_USB_VAL 0x0003
|
||||
-
|
||||
/* EFUSE bits */
|
||||
#define EFUSE_MT7688 0x100000
|
||||
|
||||
@@ -49,226 +43,6 @@
|
||||
/* does the board have sdram or ddram */
|
||||
static int dram_type;
|
||||
|
||||
-static __init u32
|
||||
-mt7620_calc_rate(u32 ref_rate, u32 mul, u32 div)
|
||||
-{
|
||||
- u64 t;
|
||||
-
|
||||
- t = ref_rate;
|
||||
- t *= mul;
|
||||
- do_div(t, div);
|
||||
-
|
||||
- return t;
|
||||
-}
|
||||
-
|
||||
-#define MHZ(x) ((x) * 1000 * 1000)
|
||||
-
|
||||
-static __init unsigned long
|
||||
-mt7620_get_xtal_rate(void)
|
||||
-{
|
||||
- u32 reg;
|
||||
-
|
||||
- reg = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG0);
|
||||
- if (reg & SYSCFG0_XTAL_FREQ_SEL)
|
||||
- return MHZ(40);
|
||||
-
|
||||
- return MHZ(20);
|
||||
-}
|
||||
-
|
||||
-static __init unsigned long
|
||||
-mt7620_get_periph_rate(unsigned long xtal_rate)
|
||||
-{
|
||||
- u32 reg;
|
||||
-
|
||||
- reg = rt_sysc_r32(SYSC_REG_CLKCFG0);
|
||||
- if (reg & CLKCFG0_PERI_CLK_SEL)
|
||||
- return xtal_rate;
|
||||
-
|
||||
- return MHZ(40);
|
||||
-}
|
||||
-
|
||||
-static const u32 mt7620_clk_divider[] __initconst = { 2, 3, 4, 8 };
|
||||
-
|
||||
-static __init unsigned long
|
||||
-mt7620_get_cpu_pll_rate(unsigned long xtal_rate)
|
||||
-{
|
||||
- u32 reg;
|
||||
- u32 mul;
|
||||
- u32 div;
|
||||
-
|
||||
- reg = rt_sysc_r32(SYSC_REG_CPLL_CONFIG0);
|
||||
- if (reg & CPLL_CFG0_BYPASS_REF_CLK)
|
||||
- return xtal_rate;
|
||||
-
|
||||
- if ((reg & CPLL_CFG0_SW_CFG) == 0)
|
||||
- return MHZ(600);
|
||||
-
|
||||
- mul = (reg >> CPLL_CFG0_PLL_MULT_RATIO_SHIFT) &
|
||||
- CPLL_CFG0_PLL_MULT_RATIO_MASK;
|
||||
- mul += 24;
|
||||
- if (reg & CPLL_CFG0_LC_CURFCK)
|
||||
- mul *= 2;
|
||||
-
|
||||
- div = (reg >> CPLL_CFG0_PLL_DIV_RATIO_SHIFT) &
|
||||
- CPLL_CFG0_PLL_DIV_RATIO_MASK;
|
||||
-
|
||||
- WARN_ON(div >= ARRAY_SIZE(mt7620_clk_divider));
|
||||
-
|
||||
- return mt7620_calc_rate(xtal_rate, mul, mt7620_clk_divider[div]);
|
||||
-}
|
||||
-
|
||||
-static __init unsigned long
|
||||
-mt7620_get_pll_rate(unsigned long xtal_rate, unsigned long cpu_pll_rate)
|
||||
-{
|
||||
- u32 reg;
|
||||
-
|
||||
- reg = rt_sysc_r32(SYSC_REG_CPLL_CONFIG1);
|
||||
- if (reg & CPLL_CFG1_CPU_AUX1)
|
||||
- return xtal_rate;
|
||||
-
|
||||
- if (reg & CPLL_CFG1_CPU_AUX0)
|
||||
- return MHZ(480);
|
||||
-
|
||||
- return cpu_pll_rate;
|
||||
-}
|
||||
-
|
||||
-static __init unsigned long
|
||||
-mt7620_get_cpu_rate(unsigned long pll_rate)
|
||||
-{
|
||||
- u32 reg;
|
||||
- u32 mul;
|
||||
- u32 div;
|
||||
-
|
||||
- reg = rt_sysc_r32(SYSC_REG_CPU_SYS_CLKCFG);
|
||||
-
|
||||
- mul = reg & CPU_SYS_CLKCFG_CPU_FFRAC_MASK;
|
||||
- div = (reg >> CPU_SYS_CLKCFG_CPU_FDIV_SHIFT) &
|
||||
- CPU_SYS_CLKCFG_CPU_FDIV_MASK;
|
||||
-
|
||||
- return mt7620_calc_rate(pll_rate, mul, div);
|
||||
-}
|
||||
-
|
||||
-static const u32 mt7620_ocp_dividers[16] __initconst = {
|
||||
- [CPU_SYS_CLKCFG_OCP_RATIO_2] = 2,
|
||||
- [CPU_SYS_CLKCFG_OCP_RATIO_3] = 3,
|
||||
- [CPU_SYS_CLKCFG_OCP_RATIO_4] = 4,
|
||||
- [CPU_SYS_CLKCFG_OCP_RATIO_5] = 5,
|
||||
- [CPU_SYS_CLKCFG_OCP_RATIO_10] = 10,
|
||||
-};
|
||||
-
|
||||
-static __init unsigned long
|
||||
-mt7620_get_dram_rate(unsigned long pll_rate)
|
||||
-{
|
||||
- if (dram_type == SYSCFG0_DRAM_TYPE_SDRAM)
|
||||
- return pll_rate / 4;
|
||||
-
|
||||
- return pll_rate / 3;
|
||||
-}
|
||||
-
|
||||
-static __init unsigned long
|
||||
-mt7620_get_sys_rate(unsigned long cpu_rate)
|
||||
-{
|
||||
- u32 reg;
|
||||
- u32 ocp_ratio;
|
||||
- u32 div;
|
||||
-
|
||||
- reg = rt_sysc_r32(SYSC_REG_CPU_SYS_CLKCFG);
|
||||
-
|
||||
- ocp_ratio = (reg >> CPU_SYS_CLKCFG_OCP_RATIO_SHIFT) &
|
||||
- CPU_SYS_CLKCFG_OCP_RATIO_MASK;
|
||||
-
|
||||
- if (WARN_ON(ocp_ratio >= ARRAY_SIZE(mt7620_ocp_dividers)))
|
||||
- return cpu_rate;
|
||||
-
|
||||
- div = mt7620_ocp_dividers[ocp_ratio];
|
||||
- if (WARN(!div, "invalid divider for OCP ratio %u", ocp_ratio))
|
||||
- return cpu_rate;
|
||||
-
|
||||
- return cpu_rate / div;
|
||||
-}
|
||||
-
|
||||
-void __init ralink_clk_init(void)
|
||||
-{
|
||||
- unsigned long xtal_rate;
|
||||
- unsigned long cpu_pll_rate;
|
||||
- unsigned long pll_rate;
|
||||
- unsigned long cpu_rate;
|
||||
- unsigned long sys_rate;
|
||||
- unsigned long dram_rate;
|
||||
- unsigned long periph_rate;
|
||||
- unsigned long pcmi2s_rate;
|
||||
-
|
||||
- xtal_rate = mt7620_get_xtal_rate();
|
||||
-
|
||||
-#define RFMT(label) label ":%lu.%03luMHz "
|
||||
-#define RINT(x) ((x) / 1000000)
|
||||
-#define RFRAC(x) (((x) / 1000) % 1000)
|
||||
-
|
||||
- if (is_mt76x8()) {
|
||||
- if (xtal_rate == MHZ(40))
|
||||
- cpu_rate = MHZ(580);
|
||||
- else
|
||||
- cpu_rate = MHZ(575);
|
||||
- dram_rate = sys_rate = cpu_rate / 3;
|
||||
- periph_rate = MHZ(40);
|
||||
- pcmi2s_rate = MHZ(480);
|
||||
-
|
||||
- ralink_clk_add("10000d00.uartlite", periph_rate);
|
||||
- ralink_clk_add("10000e00.uartlite", periph_rate);
|
||||
- } else {
|
||||
- cpu_pll_rate = mt7620_get_cpu_pll_rate(xtal_rate);
|
||||
- pll_rate = mt7620_get_pll_rate(xtal_rate, cpu_pll_rate);
|
||||
-
|
||||
- cpu_rate = mt7620_get_cpu_rate(pll_rate);
|
||||
- dram_rate = mt7620_get_dram_rate(pll_rate);
|
||||
- sys_rate = mt7620_get_sys_rate(cpu_rate);
|
||||
- periph_rate = mt7620_get_periph_rate(xtal_rate);
|
||||
- pcmi2s_rate = periph_rate;
|
||||
-
|
||||
- pr_debug(RFMT("XTAL") RFMT("CPU_PLL") RFMT("PLL"),
|
||||
- RINT(xtal_rate), RFRAC(xtal_rate),
|
||||
- RINT(cpu_pll_rate), RFRAC(cpu_pll_rate),
|
||||
- RINT(pll_rate), RFRAC(pll_rate));
|
||||
-
|
||||
- ralink_clk_add("10000500.uart", periph_rate);
|
||||
- }
|
||||
-
|
||||
- pr_debug(RFMT("CPU") RFMT("DRAM") RFMT("SYS") RFMT("PERIPH"),
|
||||
- RINT(cpu_rate), RFRAC(cpu_rate),
|
||||
- RINT(dram_rate), RFRAC(dram_rate),
|
||||
- RINT(sys_rate), RFRAC(sys_rate),
|
||||
- RINT(periph_rate), RFRAC(periph_rate));
|
||||
-#undef RFRAC
|
||||
-#undef RINT
|
||||
-#undef RFMT
|
||||
-
|
||||
- ralink_clk_add("cpu", cpu_rate);
|
||||
- ralink_clk_add("10000100.timer", periph_rate);
|
||||
- ralink_clk_add("10000120.watchdog", periph_rate);
|
||||
- ralink_clk_add("10000900.i2c", periph_rate);
|
||||
- ralink_clk_add("10000a00.i2s", pcmi2s_rate);
|
||||
- ralink_clk_add("10000b00.spi", sys_rate);
|
||||
- ralink_clk_add("10000b40.spi", sys_rate);
|
||||
- ralink_clk_add("10000c00.uartlite", periph_rate);
|
||||
- ralink_clk_add("10000d00.uart1", periph_rate);
|
||||
- ralink_clk_add("10000e00.uart2", periph_rate);
|
||||
- ralink_clk_add("10180000.wmac", xtal_rate);
|
||||
-
|
||||
- if (IS_ENABLED(CONFIG_USB) && !is_mt76x8()) {
|
||||
- /*
|
||||
- * When the CPU goes into sleep mode, the BUS clock will be
|
||||
- * too low for USB to function properly. Adjust the busses
|
||||
- * fractional divider to fix this
|
||||
- */
|
||||
- u32 val = rt_sysc_r32(SYSC_REG_CPU_SYS_CLKCFG);
|
||||
-
|
||||
- val &= ~(CLKCFG_FDIV_MASK | CLKCFG_FFRAC_MASK);
|
||||
- val |= CLKCFG_FDIV_USB_VAL | CLKCFG_FFRAC_USB_VAL;
|
||||
-
|
||||
- rt_sysc_w32(val, SYSC_REG_CPU_SYS_CLKCFG);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
void __init ralink_of_remap(void)
|
||||
{
|
||||
rt_sysc_membase = plat_of_remap_node("ralink,mt7620a-sysc");
|
@ -1,121 +0,0 @@
|
||||
From 201ddc05777cd8e084b508bcdda22214bfe2895e Mon Sep 17 00:00:00 2001
|
||||
From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Date: Mon, 19 Jun 2023 06:09:39 +0200
|
||||
Subject: [PATCH 7/9] mips: ralink: remove reset related code
|
||||
|
||||
A proper clock driver for ralink SoCs has been added. This driver is also
|
||||
a reset provider for the SoC. Hence there is no need to have reset related
|
||||
code in 'arch/mips/ralink' folder anymore. The only code that remains is
|
||||
the one related with mips_reboot_setup where a PCI reset is performed.
|
||||
We maintain this because I cannot test old ralink board with PCI to be
|
||||
sure all works if we remove also this code.
|
||||
|
||||
Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
|
||||
---
|
||||
arch/mips/ralink/common.h | 2 --
|
||||
arch/mips/ralink/of.c | 4 ----
|
||||
arch/mips/ralink/reset.c | 61 -----------------------------------------------
|
||||
3 files changed, 67 deletions(-)
|
||||
|
||||
--- a/arch/mips/ralink/common.h
|
||||
+++ b/arch/mips/ralink/common.h
|
||||
@@ -23,8 +23,6 @@ extern struct ralink_soc_info soc_info;
|
||||
|
||||
extern void ralink_of_remap(void);
|
||||
|
||||
-extern void ralink_rst_init(void);
|
||||
-
|
||||
extern void __init prom_soc_init(struct ralink_soc_info *soc_info);
|
||||
|
||||
__iomem void *plat_of_remap_node(const char *node);
|
||||
--- a/arch/mips/ralink/of.c
|
||||
+++ b/arch/mips/ralink/of.c
|
||||
@@ -95,10 +95,6 @@ static int __init plat_of_setup(void)
|
||||
{
|
||||
__dt_register_buses(soc_info.compatible, "palmbus");
|
||||
|
||||
- /* make sure that the reset controller is setup early */
|
||||
- if (ralink_soc != MT762X_SOC_MT7621AT)
|
||||
- ralink_rst_init();
|
||||
-
|
||||
return 0;
|
||||
}
|
||||
|
||||
--- a/arch/mips/ralink/reset.c
|
||||
+++ b/arch/mips/ralink/reset.c
|
||||
@@ -10,7 +10,6 @@
|
||||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/delay.h>
|
||||
-#include <linux/reset-controller.h>
|
||||
|
||||
#include <asm/reboot.h>
|
||||
|
||||
@@ -22,66 +21,6 @@
|
||||
#define RSTCTL_RESET_PCI BIT(26)
|
||||
#define RSTCTL_RESET_SYSTEM BIT(0)
|
||||
|
||||
-static int ralink_assert_device(struct reset_controller_dev *rcdev,
|
||||
- unsigned long id)
|
||||
-{
|
||||
- u32 val;
|
||||
-
|
||||
- if (id == 0)
|
||||
- return -1;
|
||||
-
|
||||
- val = rt_sysc_r32(SYSC_REG_RESET_CTRL);
|
||||
- val |= BIT(id);
|
||||
- rt_sysc_w32(val, SYSC_REG_RESET_CTRL);
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static int ralink_deassert_device(struct reset_controller_dev *rcdev,
|
||||
- unsigned long id)
|
||||
-{
|
||||
- u32 val;
|
||||
-
|
||||
- if (id == 0)
|
||||
- return -1;
|
||||
-
|
||||
- val = rt_sysc_r32(SYSC_REG_RESET_CTRL);
|
||||
- val &= ~BIT(id);
|
||||
- rt_sysc_w32(val, SYSC_REG_RESET_CTRL);
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static int ralink_reset_device(struct reset_controller_dev *rcdev,
|
||||
- unsigned long id)
|
||||
-{
|
||||
- ralink_assert_device(rcdev, id);
|
||||
- return ralink_deassert_device(rcdev, id);
|
||||
-}
|
||||
-
|
||||
-static const struct reset_control_ops reset_ops = {
|
||||
- .reset = ralink_reset_device,
|
||||
- .assert = ralink_assert_device,
|
||||
- .deassert = ralink_deassert_device,
|
||||
-};
|
||||
-
|
||||
-static struct reset_controller_dev reset_dev = {
|
||||
- .ops = &reset_ops,
|
||||
- .owner = THIS_MODULE,
|
||||
- .nr_resets = 32,
|
||||
- .of_reset_n_cells = 1,
|
||||
-};
|
||||
-
|
||||
-void ralink_rst_init(void)
|
||||
-{
|
||||
- reset_dev.of_node = of_find_compatible_node(NULL, NULL,
|
||||
- "ralink,rt2880-reset");
|
||||
- if (!reset_dev.of_node)
|
||||
- pr_err("Failed to find reset controller node");
|
||||
- else
|
||||
- reset_controller_register(&reset_dev);
|
||||
-}
|
||||
-
|
||||
static void ralink_restart(char *command)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_PCI)) {
|
@ -1,102 +0,0 @@
|
||||
From ad38c17b0c26ae2108b50ac1eb0281a2e1ce08e9 Mon Sep 17 00:00:00 2001
|
||||
From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Date: Mon, 19 Jun 2023 06:09:40 +0200
|
||||
Subject: [PATCH 8/9] mips: ralink: get cpu rate from new driver code
|
||||
|
||||
At very early stage on boot, there is a need to set 'mips_hpt_frequency'.
|
||||
This timer frequency is a half of the CPU frequency. To get clocks properly
|
||||
set we need to call to 'of_clk_init()' and properly get cpu clock frequency
|
||||
afterwards. Depending on the SoC, CPU clock index and compatible differs, so
|
||||
use them to get the proper clock frm the clock provider. Hence, adapt code
|
||||
to be aligned with new clock driver.
|
||||
|
||||
Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
|
||||
---
|
||||
arch/mips/ralink/clk.c | 61 ++++++++++++++++++++++++++++++++++++++++++--------
|
||||
1 file changed, 52 insertions(+), 9 deletions(-)
|
||||
|
||||
--- a/arch/mips/ralink/clk.c
|
||||
+++ b/arch/mips/ralink/clk.c
|
||||
@@ -11,29 +11,72 @@
|
||||
#include <linux/clkdev.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
+#include <asm/mach-ralink/ralink_regs.h>
|
||||
|
||||
#include <asm/time.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
-void ralink_clk_add(const char *dev, unsigned long rate)
|
||||
+static const char *clk_cpu(int *idx)
|
||||
{
|
||||
- struct clk *clk = clk_register_fixed_rate(NULL, dev, NULL, 0, rate);
|
||||
-
|
||||
- if (!clk)
|
||||
- panic("failed to add clock");
|
||||
-
|
||||
- clkdev_create(clk, NULL, "%s", dev);
|
||||
+ switch (ralink_soc) {
|
||||
+ case RT2880_SOC:
|
||||
+ *idx = 0;
|
||||
+ return "ralink,rt2880-sysc";
|
||||
+ case RT3883_SOC:
|
||||
+ *idx = 0;
|
||||
+ return "ralink,rt3883-sysc";
|
||||
+ case RT305X_SOC_RT3050:
|
||||
+ *idx = 0;
|
||||
+ return "ralink,rt3050-sysc";
|
||||
+ case RT305X_SOC_RT3052:
|
||||
+ *idx = 0;
|
||||
+ return "ralink,rt3052-sysc";
|
||||
+ case RT305X_SOC_RT3350:
|
||||
+ *idx = 1;
|
||||
+ return "ralink,rt3350-sysc";
|
||||
+ case RT305X_SOC_RT3352:
|
||||
+ *idx = 1;
|
||||
+ return "ralink,rt3352-sysc";
|
||||
+ case RT305X_SOC_RT5350:
|
||||
+ *idx = 1;
|
||||
+ return "ralink,rt5350-sysc";
|
||||
+ case MT762X_SOC_MT7620A:
|
||||
+ *idx = 2;
|
||||
+ return "ralink,mt7620-sysc";
|
||||
+ case MT762X_SOC_MT7620N:
|
||||
+ *idx = 2;
|
||||
+ return "ralink,mt7620-sysc";
|
||||
+ case MT762X_SOC_MT7628AN:
|
||||
+ *idx = 1;
|
||||
+ return "ralink,mt7628-sysc";
|
||||
+ case MT762X_SOC_MT7688:
|
||||
+ *idx = 1;
|
||||
+ return "ralink,mt7688-sysc";
|
||||
+ default:
|
||||
+ *idx = -1;
|
||||
+ return "invalid";
|
||||
+ }
|
||||
}
|
||||
|
||||
void __init plat_time_init(void)
|
||||
{
|
||||
+ struct of_phandle_args clkspec;
|
||||
+ const char *compatible;
|
||||
struct clk *clk;
|
||||
+ int cpu_clk_idx;
|
||||
|
||||
ralink_of_remap();
|
||||
|
||||
- ralink_clk_init();
|
||||
- clk = clk_get_sys("cpu", NULL);
|
||||
+ compatible = clk_cpu(&cpu_clk_idx);
|
||||
+ if (cpu_clk_idx == -1)
|
||||
+ panic("unable to get CPU clock index");
|
||||
+
|
||||
+ of_clk_init(NULL);
|
||||
+ clkspec.np = of_find_compatible_node(NULL, NULL, compatible);
|
||||
+ clkspec.args_count = 1;
|
||||
+ clkspec.args[0] = cpu_clk_idx;
|
||||
+ clk = of_clk_get_from_provider(&clkspec);
|
||||
if (IS_ERR(clk))
|
||||
panic("unable to get CPU clock, err=%ld", PTR_ERR(clk));
|
||||
pr_info("CPU Clock: %ldMHz\n", clk_get_rate(clk) / 1000000);
|
@ -1,28 +0,0 @@
|
||||
From fc15a7193a4d37d79e873fa06cc423180ddd2ddf Mon Sep 17 00:00:00 2001
|
||||
From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Date: Mon, 19 Jun 2023 06:09:41 +0200
|
||||
Subject: [PATCH 9/9] MAINTAINERS: add Mediatek MTMIPS Clock maintainer
|
||||
|
||||
Adding myself as maintainer for Mediatek MTMIPS clock driver.
|
||||
|
||||
Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
|
||||
---
|
||||
MAINTAINERS | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -11859,6 +11859,12 @@ S: Maintained
|
||||
F: Documentation/devicetree/bindings/clock/mediatek,mt7621-sysc.yaml
|
||||
F: drivers/clk/ralink/clk-mt7621.c
|
||||
|
||||
+MEDIATEK MTMIPS CLOCK DRIVER
|
||||
+M: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
+S: Maintained
|
||||
+F: Documentation/devicetree/bindings/clock/mediatek,mtmips-sysc.yaml
|
||||
+F: drivers/clk/ralink/clk-mtmips.c
|
||||
+
|
||||
MEDIATEK MT7621/28/88 I2C DRIVER
|
||||
M: Stefan Roese <sr@denx.de>
|
||||
L: linux-i2c@vger.kernel.org
|
@ -1,189 +0,0 @@
|
||||
From fd99ac5055d4705e91c73d1adba18bc71c8511a8 Mon Sep 17 00:00:00 2001
|
||||
From: Shiji Yang <yangshiji66@outlook.com>
|
||||
Date: Tue, 20 Jun 2023 19:44:32 +0800
|
||||
Subject: [PATCH] mips: ralink: introduce commonly used remap node function
|
||||
|
||||
The ralink_of_remap() function is repeated several times on SoC specific
|
||||
source files. They have the same structure, but just differ in compatible
|
||||
strings. In order to make commonly use of these codes, this patch
|
||||
introduces a newly designed mtmips_of_remap_node() function to match and
|
||||
remap all supported system controller and memory controller nodes.
|
||||
|
||||
Build and run tested on MT7620 and MT7628.
|
||||
|
||||
Signed-off-by: Shiji Yang <yangshiji66@outlook.com>
|
||||
Reviewed-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
|
||||
---
|
||||
arch/mips/ralink/common.h | 2 --
|
||||
arch/mips/ralink/mt7620.c | 9 ---------
|
||||
arch/mips/ralink/mt7621.c | 9 ---------
|
||||
arch/mips/ralink/of.c | 42 +++++++++++++++++++++++++++++++++++-------
|
||||
arch/mips/ralink/rt288x.c | 9 ---------
|
||||
arch/mips/ralink/rt305x.c | 9 ---------
|
||||
arch/mips/ralink/rt3883.c | 9 ---------
|
||||
7 files changed, 35 insertions(+), 54 deletions(-)
|
||||
|
||||
--- a/arch/mips/ralink/common.h
|
||||
+++ b/arch/mips/ralink/common.h
|
||||
@@ -25,6 +25,4 @@ extern void ralink_of_remap(void);
|
||||
|
||||
extern void __init prom_soc_init(struct ralink_soc_info *soc_info);
|
||||
|
||||
-__iomem void *plat_of_remap_node(const char *node);
|
||||
-
|
||||
#endif /* _RALINK_COMMON_H__ */
|
||||
--- a/arch/mips/ralink/mt7620.c
|
||||
+++ b/arch/mips/ralink/mt7620.c
|
||||
@@ -43,15 +43,6 @@
|
||||
/* does the board have sdram or ddram */
|
||||
static int dram_type;
|
||||
|
||||
-void __init ralink_of_remap(void)
|
||||
-{
|
||||
- rt_sysc_membase = plat_of_remap_node("ralink,mt7620a-sysc");
|
||||
- rt_memc_membase = plat_of_remap_node("ralink,mt7620a-memc");
|
||||
-
|
||||
- if (!rt_sysc_membase || !rt_memc_membase)
|
||||
- panic("Failed to remap core resources");
|
||||
-}
|
||||
-
|
||||
static __init void
|
||||
mt7620_dram_init(struct ralink_soc_info *soc_info)
|
||||
{
|
||||
--- a/arch/mips/ralink/mt7621.c
|
||||
+++ b/arch/mips/ralink/mt7621.c
|
||||
@@ -58,15 +58,6 @@ static void __init mt7621_memory_detect(
|
||||
memblock_add(MT7621_HIGHMEM_BASE, MT7621_HIGHMEM_SIZE);
|
||||
}
|
||||
|
||||
-void __init ralink_of_remap(void)
|
||||
-{
|
||||
- rt_sysc_membase = plat_of_remap_node("mediatek,mt7621-sysc");
|
||||
- rt_memc_membase = plat_of_remap_node("mediatek,mt7621-memc");
|
||||
-
|
||||
- if (!rt_sysc_membase || !rt_memc_membase)
|
||||
- panic("Failed to remap core resources");
|
||||
-}
|
||||
-
|
||||
static unsigned int __init mt7621_get_soc_name0(void)
|
||||
{
|
||||
return __raw_readl(MT7621_SYSC_BASE + SYSC_REG_CHIP_NAME0);
|
||||
--- a/arch/mips/ralink/of.c
|
||||
+++ b/arch/mips/ralink/of.c
|
||||
@@ -29,26 +29,56 @@ __iomem void *rt_sysc_membase;
|
||||
__iomem void *rt_memc_membase;
|
||||
EXPORT_SYMBOL_GPL(rt_sysc_membase);
|
||||
|
||||
-__iomem void *plat_of_remap_node(const char *node)
|
||||
+static const struct of_device_id mtmips_memc_match[] = {
|
||||
+ { .compatible = "mediatek,mt7621-memc" },
|
||||
+ { .compatible = "ralink,mt7620a-memc" },
|
||||
+ { .compatible = "ralink,rt2880-memc" },
|
||||
+ { .compatible = "ralink,rt3050-memc" },
|
||||
+ { .compatible = "ralink,rt3883-memc" },
|
||||
+ {}
|
||||
+};
|
||||
+
|
||||
+static const struct of_device_id mtmips_sysc_match[] = {
|
||||
+ { .compatible = "mediatek,mt7621-sysc" },
|
||||
+ { .compatible = "ralink,mt7620a-sysc" },
|
||||
+ { .compatible = "ralink,rt2880-sysc" },
|
||||
+ { .compatible = "ralink,rt3050-sysc" },
|
||||
+ { .compatible = "ralink,rt3883-sysc" },
|
||||
+ {}
|
||||
+};
|
||||
+
|
||||
+static __iomem void *
|
||||
+mtmips_of_remap_node(const struct of_device_id *match, const char *type)
|
||||
{
|
||||
struct resource res;
|
||||
struct device_node *np;
|
||||
|
||||
- np = of_find_compatible_node(NULL, NULL, node);
|
||||
+ np = of_find_matching_node(NULL, match);
|
||||
if (!np)
|
||||
- panic("Failed to find %s node", node);
|
||||
+ panic("Failed to find %s controller node", type);
|
||||
|
||||
if (of_address_to_resource(np, 0, &res))
|
||||
- panic("Failed to get resource for %s", node);
|
||||
+ panic("Failed to get resource for %s node", np->name);
|
||||
|
||||
if (!request_mem_region(res.start,
|
||||
resource_size(&res),
|
||||
res.name))
|
||||
- panic("Failed to request resources for %s", node);
|
||||
+ panic("Failed to request resources for %s node", np->name);
|
||||
+
|
||||
+ of_node_put(np);
|
||||
|
||||
return ioremap(res.start, resource_size(&res));
|
||||
}
|
||||
|
||||
+void __init ralink_of_remap(void)
|
||||
+{
|
||||
+ rt_sysc_membase = mtmips_of_remap_node(mtmips_sysc_match, "system");
|
||||
+ rt_memc_membase = mtmips_of_remap_node(mtmips_memc_match, "memory");
|
||||
+
|
||||
+ if (!rt_sysc_membase || !rt_memc_membase)
|
||||
+ panic("Failed to remap core resources");
|
||||
+}
|
||||
+
|
||||
void __init device_tree_init(void)
|
||||
{
|
||||
unflatten_and_copy_device_tree();
|
||||
--- a/arch/mips/ralink/rt288x.c
|
||||
+++ b/arch/mips/ralink/rt288x.c
|
||||
@@ -17,15 +17,6 @@
|
||||
|
||||
#include "common.h"
|
||||
|
||||
-void __init ralink_of_remap(void)
|
||||
-{
|
||||
- rt_sysc_membase = plat_of_remap_node("ralink,rt2880-sysc");
|
||||
- rt_memc_membase = plat_of_remap_node("ralink,rt2880-memc");
|
||||
-
|
||||
- if (!rt_sysc_membase || !rt_memc_membase)
|
||||
- panic("Failed to remap core resources");
|
||||
-}
|
||||
-
|
||||
void __init prom_soc_init(struct ralink_soc_info *soc_info)
|
||||
{
|
||||
void __iomem *sysc = (void __iomem *) KSEG1ADDR(RT2880_SYSC_BASE);
|
||||
--- a/arch/mips/ralink/rt305x.c
|
||||
+++ b/arch/mips/ralink/rt305x.c
|
||||
@@ -53,15 +53,6 @@ static unsigned long rt5350_get_mem_size
|
||||
return ret;
|
||||
}
|
||||
|
||||
-void __init ralink_of_remap(void)
|
||||
-{
|
||||
- rt_sysc_membase = plat_of_remap_node("ralink,rt3050-sysc");
|
||||
- rt_memc_membase = plat_of_remap_node("ralink,rt3050-memc");
|
||||
-
|
||||
- if (!rt_sysc_membase || !rt_memc_membase)
|
||||
- panic("Failed to remap core resources");
|
||||
-}
|
||||
-
|
||||
void __init prom_soc_init(struct ralink_soc_info *soc_info)
|
||||
{
|
||||
void __iomem *sysc = (void __iomem *) KSEG1ADDR(RT305X_SYSC_BASE);
|
||||
--- a/arch/mips/ralink/rt3883.c
|
||||
+++ b/arch/mips/ralink/rt3883.c
|
||||
@@ -17,15 +17,6 @@
|
||||
|
||||
#include "common.h"
|
||||
|
||||
-void __init ralink_of_remap(void)
|
||||
-{
|
||||
- rt_sysc_membase = plat_of_remap_node("ralink,rt3883-sysc");
|
||||
- rt_memc_membase = plat_of_remap_node("ralink,rt3883-memc");
|
||||
-
|
||||
- if (!rt_sysc_membase || !rt_memc_membase)
|
||||
- panic("Failed to remap core resources");
|
||||
-}
|
||||
-
|
||||
void __init prom_soc_init(struct ralink_soc_info *soc_info)
|
||||
{
|
||||
void __iomem *sysc = (void __iomem *) KSEG1ADDR(RT3883_SYSC_BASE);
|
@ -1,56 +0,0 @@
|
||||
From 6e68dae946e3a0333fbde5487ce163142ca10ae0 Mon Sep 17 00:00:00 2001
|
||||
From: Nathan Chancellor <nathan@kernel.org>
|
||||
Date: Thu, 22 Jun 2023 15:56:19 +0000
|
||||
Subject: clk: ralink: mtmips: Fix uninitialized use of ret in
|
||||
mtmips_register_{fixed,factor}_clocks()
|
||||
|
||||
Clang warns:
|
||||
|
||||
drivers/clk/ralink/clk-mtmips.c:309:9: error: variable 'ret' is uninitialized when used here [-Werror,-Wuninitialized]
|
||||
309 | return ret;
|
||||
| ^~~
|
||||
drivers/clk/ralink/clk-mtmips.c:285:9: note: initialize the variable 'ret' to silence this warning
|
||||
285 | int ret, i;
|
||||
| ^
|
||||
| = 0
|
||||
drivers/clk/ralink/clk-mtmips.c:359:9: error: variable 'ret' is uninitialized when used here [-Werror,-Wuninitialized]
|
||||
359 | return ret;
|
||||
| ^~~
|
||||
drivers/clk/ralink/clk-mtmips.c:335:9: note: initialize the variable 'ret' to silence this warning
|
||||
335 | int ret, i;
|
||||
| ^
|
||||
| = 0
|
||||
2 errors generated.
|
||||
|
||||
Set ret to the return value of clk_hw_register_fixed_rate() using the
|
||||
PTR_ERR() macro, which ensures ret is not used uninitialized, clearing
|
||||
up the warning.
|
||||
|
||||
Fixes: 6f3b15586eef ("clk: ralink: add clock and reset driver for MTMIPS SoCs")
|
||||
Closes: https://github.com/ClangBuiltLinux/linux/issues/1879
|
||||
Signed-off-by: Nathan Chancellor <nathan@kernel.org>
|
||||
Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>
|
||||
Acked-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
|
||||
---
|
||||
drivers/clk/ralink/clk-mtmips.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
--- a/drivers/clk/ralink/clk-mtmips.c
|
||||
+++ b/drivers/clk/ralink/clk-mtmips.c
|
||||
@@ -292,6 +292,7 @@ static int mtmips_register_fixed_clocks(
|
||||
sclk->parent, 0,
|
||||
sclk->rate);
|
||||
if (IS_ERR(sclk->hw)) {
|
||||
+ ret = PTR_ERR(sclk->hw);
|
||||
pr_err("Couldn't register fixed clock %d\n", idx);
|
||||
goto err_clk_unreg;
|
||||
}
|
||||
@@ -342,6 +343,7 @@ static int mtmips_register_factor_clocks
|
||||
sclk->parent, sclk->flags,
|
||||
sclk->mult, sclk->div);
|
||||
if (IS_ERR(sclk->hw)) {
|
||||
+ ret = PTR_ERR(sclk->hw);
|
||||
pr_err("Couldn't register factor clock %d\n", idx);
|
||||
goto err_clk_unreg;
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
From 670f77f76f650b1b341d31d009cc2fb03a4d1fcf Mon Sep 17 00:00:00 2001
|
||||
From: Shiji Yang <yangshiji66@outlook.com>
|
||||
Date: Fri, 23 Jun 2023 08:17:48 +0800
|
||||
Subject: mips: ralink: match all supported system controller compatible
|
||||
strings
|
||||
|
||||
Recently, A new clock and reset controller driver has been introduced to
|
||||
the ralink mips target[1]. It provides proper system control and adds more
|
||||
SoC specific compatible strings. In order to better initialize CPUs, this
|
||||
patch removes the outdated "ralink,mt7620a-sysc" and add all dt-binding
|
||||
documented compatible strings to the system controller match table.
|
||||
|
||||
[1] https://lore.kernel.org/all/20230619040941.1340372-1-sergio.paracuellos@gmail.com/
|
||||
|
||||
Signed-off-by: Shiji Yang <yangshiji66@outlook.com>
|
||||
Reviewed-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
|
||||
---
|
||||
arch/mips/ralink/of.c | 7 ++++++-
|
||||
1 file changed, 6 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/arch/mips/ralink/of.c
|
||||
+++ b/arch/mips/ralink/of.c
|
||||
@@ -40,10 +40,15 @@ static const struct of_device_id mtmips_
|
||||
|
||||
static const struct of_device_id mtmips_sysc_match[] = {
|
||||
{ .compatible = "mediatek,mt7621-sysc" },
|
||||
- { .compatible = "ralink,mt7620a-sysc" },
|
||||
+ { .compatible = "ralink,mt7620-sysc" },
|
||||
+ { .compatible = "ralink,mt7628-sysc" },
|
||||
+ { .compatible = "ralink,mt7688-sysc" },
|
||||
{ .compatible = "ralink,rt2880-sysc" },
|
||||
{ .compatible = "ralink,rt3050-sysc" },
|
||||
+ { .compatible = "ralink,rt3052-sysc" },
|
||||
+ { .compatible = "ralink,rt3352-sysc" },
|
||||
{ .compatible = "ralink,rt3883-sysc" },
|
||||
+ { .compatible = "ralink,rt5350-sysc" },
|
||||
{}
|
||||
};
|
||||
|
@ -1,213 +0,0 @@
|
||||
From 783c7cb4659b53b5e1b809dac5e8cdf250145919 Mon Sep 17 00:00:00 2001
|
||||
From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Date: Tue, 14 Feb 2023 11:39:35 +0100
|
||||
Subject: [PATCH 1/2] watchdog: mt7621-wdt: avoid static global declarations
|
||||
|
||||
Instead of using static global definitions in driver code, refactor code
|
||||
introducing a new watchdog driver data structure and use it along the
|
||||
code.
|
||||
|
||||
Reviewed-by: Guenter Roeck <linux@roeck-us.net>
|
||||
Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Link: https://lore.kernel.org/r/20230214103936.1061078-5-sergio.paracuellos@gmail.com
|
||||
[groeck: unsigned -> unsigned int]
|
||||
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
|
||||
Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org>
|
||||
---
|
||||
drivers/watchdog/mt7621_wdt.c | 102 +++++++++++++++++++++++++++---------------
|
||||
1 file changed, 65 insertions(+), 37 deletions(-)
|
||||
|
||||
--- a/drivers/watchdog/mt7621_wdt.c
|
||||
+++ b/drivers/watchdog/mt7621_wdt.c
|
||||
@@ -31,8 +31,11 @@
|
||||
#define TMR1CTL_RESTART BIT(9)
|
||||
#define TMR1CTL_PRESCALE_SHIFT 16
|
||||
|
||||
-static void __iomem *mt7621_wdt_base;
|
||||
-static struct reset_control *mt7621_wdt_reset;
|
||||
+struct mt7621_wdt_data {
|
||||
+ void __iomem *base;
|
||||
+ struct reset_control *rst;
|
||||
+ struct watchdog_device wdt;
|
||||
+};
|
||||
|
||||
static bool nowayout = WATCHDOG_NOWAYOUT;
|
||||
module_param(nowayout, bool, 0);
|
||||
@@ -40,27 +43,31 @@ MODULE_PARM_DESC(nowayout,
|
||||
"Watchdog cannot be stopped once started (default="
|
||||
__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
|
||||
|
||||
-static inline void rt_wdt_w32(unsigned reg, u32 val)
|
||||
+static inline void rt_wdt_w32(void __iomem *base, unsigned int reg, u32 val)
|
||||
{
|
||||
- iowrite32(val, mt7621_wdt_base + reg);
|
||||
+ iowrite32(val, base + reg);
|
||||
}
|
||||
|
||||
-static inline u32 rt_wdt_r32(unsigned reg)
|
||||
+static inline u32 rt_wdt_r32(void __iomem *base, unsigned int reg)
|
||||
{
|
||||
- return ioread32(mt7621_wdt_base + reg);
|
||||
+ return ioread32(base + reg);
|
||||
}
|
||||
|
||||
static int mt7621_wdt_ping(struct watchdog_device *w)
|
||||
{
|
||||
- rt_wdt_w32(TIMER_REG_TMRSTAT, TMR1CTL_RESTART);
|
||||
+ struct mt7621_wdt_data *drvdata = watchdog_get_drvdata(w);
|
||||
+
|
||||
+ rt_wdt_w32(drvdata->base, TIMER_REG_TMRSTAT, TMR1CTL_RESTART);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt7621_wdt_set_timeout(struct watchdog_device *w, unsigned int t)
|
||||
{
|
||||
+ struct mt7621_wdt_data *drvdata = watchdog_get_drvdata(w);
|
||||
+
|
||||
w->timeout = t;
|
||||
- rt_wdt_w32(TIMER_REG_TMR1LOAD, t * 1000);
|
||||
+ rt_wdt_w32(drvdata->base, TIMER_REG_TMR1LOAD, t * 1000);
|
||||
mt7621_wdt_ping(w);
|
||||
|
||||
return 0;
|
||||
@@ -68,29 +75,31 @@ static int mt7621_wdt_set_timeout(struct
|
||||
|
||||
static int mt7621_wdt_start(struct watchdog_device *w)
|
||||
{
|
||||
+ struct mt7621_wdt_data *drvdata = watchdog_get_drvdata(w);
|
||||
u32 t;
|
||||
|
||||
/* set the prescaler to 1ms == 1000us */
|
||||
- rt_wdt_w32(TIMER_REG_TMR1CTL, 1000 << TMR1CTL_PRESCALE_SHIFT);
|
||||
+ rt_wdt_w32(drvdata->base, TIMER_REG_TMR1CTL, 1000 << TMR1CTL_PRESCALE_SHIFT);
|
||||
|
||||
mt7621_wdt_set_timeout(w, w->timeout);
|
||||
|
||||
- t = rt_wdt_r32(TIMER_REG_TMR1CTL);
|
||||
+ t = rt_wdt_r32(drvdata->base, TIMER_REG_TMR1CTL);
|
||||
t |= TMR1CTL_ENABLE;
|
||||
- rt_wdt_w32(TIMER_REG_TMR1CTL, t);
|
||||
+ rt_wdt_w32(drvdata->base, TIMER_REG_TMR1CTL, t);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt7621_wdt_stop(struct watchdog_device *w)
|
||||
{
|
||||
+ struct mt7621_wdt_data *drvdata = watchdog_get_drvdata(w);
|
||||
u32 t;
|
||||
|
||||
mt7621_wdt_ping(w);
|
||||
|
||||
- t = rt_wdt_r32(TIMER_REG_TMR1CTL);
|
||||
+ t = rt_wdt_r32(drvdata->base, TIMER_REG_TMR1CTL);
|
||||
t &= ~TMR1CTL_ENABLE;
|
||||
- rt_wdt_w32(TIMER_REG_TMR1CTL, t);
|
||||
+ rt_wdt_w32(drvdata->base, TIMER_REG_TMR1CTL, t);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -105,7 +114,9 @@ static int mt7621_wdt_bootcause(void)
|
||||
|
||||
static int mt7621_wdt_is_running(struct watchdog_device *w)
|
||||
{
|
||||
- return !!(rt_wdt_r32(TIMER_REG_TMR1CTL) & TMR1CTL_ENABLE);
|
||||
+ struct mt7621_wdt_data *drvdata = watchdog_get_drvdata(w);
|
||||
+
|
||||
+ return !!(rt_wdt_r32(drvdata->base, TIMER_REG_TMR1CTL) & TMR1CTL_ENABLE);
|
||||
}
|
||||
|
||||
static const struct watchdog_info mt7621_wdt_info = {
|
||||
@@ -121,30 +132,39 @@ static const struct watchdog_ops mt7621_
|
||||
.set_timeout = mt7621_wdt_set_timeout,
|
||||
};
|
||||
|
||||
-static struct watchdog_device mt7621_wdt_dev = {
|
||||
- .info = &mt7621_wdt_info,
|
||||
- .ops = &mt7621_wdt_ops,
|
||||
- .min_timeout = 1,
|
||||
- .max_timeout = 0xfffful / 1000,
|
||||
-};
|
||||
-
|
||||
static int mt7621_wdt_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
- mt7621_wdt_base = devm_platform_ioremap_resource(pdev, 0);
|
||||
- if (IS_ERR(mt7621_wdt_base))
|
||||
- return PTR_ERR(mt7621_wdt_base);
|
||||
-
|
||||
- mt7621_wdt_reset = devm_reset_control_get_exclusive(dev, NULL);
|
||||
- if (!IS_ERR(mt7621_wdt_reset))
|
||||
- reset_control_deassert(mt7621_wdt_reset);
|
||||
-
|
||||
- mt7621_wdt_dev.bootstatus = mt7621_wdt_bootcause();
|
||||
-
|
||||
- watchdog_init_timeout(&mt7621_wdt_dev, mt7621_wdt_dev.max_timeout,
|
||||
- dev);
|
||||
- watchdog_set_nowayout(&mt7621_wdt_dev, nowayout);
|
||||
- if (mt7621_wdt_is_running(&mt7621_wdt_dev)) {
|
||||
+ struct watchdog_device *mt7621_wdt;
|
||||
+ struct mt7621_wdt_data *drvdata;
|
||||
+ int err;
|
||||
+
|
||||
+ drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
|
||||
+ if (!drvdata)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ drvdata->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
+ if (IS_ERR(drvdata->base))
|
||||
+ return PTR_ERR(drvdata->base);
|
||||
+
|
||||
+ drvdata->rst = devm_reset_control_get_exclusive(dev, NULL);
|
||||
+ if (!IS_ERR(drvdata->rst))
|
||||
+ reset_control_deassert(drvdata->rst);
|
||||
+
|
||||
+ mt7621_wdt = &drvdata->wdt;
|
||||
+ mt7621_wdt->info = &mt7621_wdt_info;
|
||||
+ mt7621_wdt->ops = &mt7621_wdt_ops;
|
||||
+ mt7621_wdt->min_timeout = 1;
|
||||
+ mt7621_wdt->max_timeout = 0xfffful / 1000;
|
||||
+ mt7621_wdt->parent = dev;
|
||||
+
|
||||
+ mt7621_wdt->bootstatus = mt7621_wdt_bootcause();
|
||||
+
|
||||
+ watchdog_init_timeout(mt7621_wdt, mt7621_wdt->max_timeout, dev);
|
||||
+ watchdog_set_nowayout(mt7621_wdt, nowayout);
|
||||
+ watchdog_set_drvdata(mt7621_wdt, drvdata);
|
||||
+
|
||||
+ if (mt7621_wdt_is_running(mt7621_wdt)) {
|
||||
/*
|
||||
* Make sure to apply timeout from watchdog core, taking
|
||||
* the prescaler of this driver here into account (the
|
||||
@@ -154,17 +174,25 @@ static int mt7621_wdt_probe(struct platf
|
||||
* we first disable the watchdog, set the new prescaler
|
||||
* and timeout, and then re-enable the watchdog.
|
||||
*/
|
||||
- mt7621_wdt_stop(&mt7621_wdt_dev);
|
||||
- mt7621_wdt_start(&mt7621_wdt_dev);
|
||||
- set_bit(WDOG_HW_RUNNING, &mt7621_wdt_dev.status);
|
||||
+ mt7621_wdt_stop(mt7621_wdt);
|
||||
+ mt7621_wdt_start(mt7621_wdt);
|
||||
+ set_bit(WDOG_HW_RUNNING, &mt7621_wdt->status);
|
||||
}
|
||||
|
||||
- return devm_watchdog_register_device(dev, &mt7621_wdt_dev);
|
||||
+ err = devm_watchdog_register_device(dev, &drvdata->wdt);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ platform_set_drvdata(pdev, drvdata);
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static void mt7621_wdt_shutdown(struct platform_device *pdev)
|
||||
{
|
||||
- mt7621_wdt_stop(&mt7621_wdt_dev);
|
||||
+ struct mt7621_wdt_data *drvdata = platform_get_drvdata(pdev);
|
||||
+
|
||||
+ mt7621_wdt_stop(&drvdata->wdt);
|
||||
}
|
||||
|
||||
static const struct of_device_id mt7621_wdt_match[] = {
|
@ -1,104 +0,0 @@
|
||||
From ff8ec4ac39ad413b580d611dbf68e1d8a82eba56 Mon Sep 17 00:00:00 2001
|
||||
From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Date: Tue, 14 Feb 2023 11:39:36 +0100
|
||||
Subject: [PATCH 2/2] watchdog: mt7621-wdt: avoid ralink architecture dependent code
|
||||
|
||||
MT7621 SoC has a system controller node. Watchdog need to access to reset
|
||||
status register. Ralink architecture and related driver are old and from
|
||||
the beggining they are using some architecture dependent operations for
|
||||
accessing this shared registers through 'asm/mach-ralink/ralink_regs.h'
|
||||
header file. However this is not ideal from a driver perspective which can
|
||||
just access to the system controller registers in an arch independent way
|
||||
using regmap syscon APIs. Update Kconfig accordingly to select new added
|
||||
dependencies and allow driver to be compile tested.
|
||||
|
||||
Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Reviewed-by: Guenter Roeck <linux@roeck-us.net>
|
||||
Link: https://lore.kernel.org/r/20230214103936.1061078-6-sergio.paracuellos@gmail.com
|
||||
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
|
||||
Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org>
|
||||
---
|
||||
drivers/watchdog/Kconfig | 4 +++-
|
||||
drivers/watchdog/mt7621_wdt.c | 22 +++++++++++++++++-----
|
||||
2 files changed, 20 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/watchdog/Kconfig
|
||||
+++ b/drivers/watchdog/Kconfig
|
||||
@@ -1799,7 +1799,9 @@ config RALINK_WDT
|
||||
config MT7621_WDT
|
||||
tristate "Mediatek SoC watchdog"
|
||||
select WATCHDOG_CORE
|
||||
- depends on SOC_MT7620 || SOC_MT7621
|
||||
+ select REGMAP_MMIO
|
||||
+ select MFD_SYSCON
|
||||
+ depends on SOC_MT7620 || SOC_MT7621 || COMPILE_TEST
|
||||
help
|
||||
Hardware driver for the Mediatek/Ralink MT7621/8 SoC Watchdog Timer.
|
||||
|
||||
--- a/drivers/watchdog/mt7621_wdt.c
|
||||
+++ b/drivers/watchdog/mt7621_wdt.c
|
||||
@@ -15,8 +15,8 @@
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
-
|
||||
-#include <asm/mach-ralink/ralink_regs.h>
|
||||
+#include <linux/mfd/syscon.h>
|
||||
+#include <linux/regmap.h>
|
||||
|
||||
#define SYSC_RSTSTAT 0x38
|
||||
#define WDT_RST_CAUSE BIT(1)
|
||||
@@ -34,6 +34,7 @@
|
||||
struct mt7621_wdt_data {
|
||||
void __iomem *base;
|
||||
struct reset_control *rst;
|
||||
+ struct regmap *sysc;
|
||||
struct watchdog_device wdt;
|
||||
};
|
||||
|
||||
@@ -104,9 +105,12 @@ static int mt7621_wdt_stop(struct watchd
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int mt7621_wdt_bootcause(void)
|
||||
+static int mt7621_wdt_bootcause(struct mt7621_wdt_data *d)
|
||||
{
|
||||
- if (rt_sysc_r32(SYSC_RSTSTAT) & WDT_RST_CAUSE)
|
||||
+ u32 val;
|
||||
+
|
||||
+ regmap_read(d->sysc, SYSC_RSTSTAT, &val);
|
||||
+ if (val & WDT_RST_CAUSE)
|
||||
return WDIOF_CARDRESET;
|
||||
|
||||
return 0;
|
||||
@@ -134,6 +138,7 @@ static const struct watchdog_ops mt7621_
|
||||
|
||||
static int mt7621_wdt_probe(struct platform_device *pdev)
|
||||
{
|
||||
+ struct device_node *np = pdev->dev.of_node;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct watchdog_device *mt7621_wdt;
|
||||
struct mt7621_wdt_data *drvdata;
|
||||
@@ -143,6 +148,13 @@ static int mt7621_wdt_probe(struct platf
|
||||
if (!drvdata)
|
||||
return -ENOMEM;
|
||||
|
||||
+ drvdata->sysc = syscon_regmap_lookup_by_phandle(np, "mediatek,sysctl");
|
||||
+ if (IS_ERR(drvdata->sysc)) {
|
||||
+ drvdata->sysc = syscon_regmap_lookup_by_compatible("mediatek,mt7621-sysc");
|
||||
+ if (IS_ERR(drvdata->sysc))
|
||||
+ return PTR_ERR(drvdata->sysc);
|
||||
+ }
|
||||
+
|
||||
drvdata->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(drvdata->base))
|
||||
return PTR_ERR(drvdata->base);
|
||||
@@ -158,7 +170,7 @@ static int mt7621_wdt_probe(struct platf
|
||||
mt7621_wdt->max_timeout = 0xfffful / 1000;
|
||||
mt7621_wdt->parent = dev;
|
||||
|
||||
- mt7621_wdt->bootstatus = mt7621_wdt_bootcause();
|
||||
+ mt7621_wdt->bootstatus = mt7621_wdt_bootcause(drvdata);
|
||||
|
||||
watchdog_init_timeout(mt7621_wdt, mt7621_wdt->max_timeout, dev);
|
||||
watchdog_set_nowayout(mt7621_wdt, nowayout);
|
@ -1,32 +0,0 @@
|
||||
From 9f9a035e6156a57d9da062b26d2a48d031744a1e Mon Sep 17 00:00:00 2001
|
||||
From: Shiji Yang <yangshiji66@outlook.com>
|
||||
Date: Tue, 20 Jun 2023 18:43:22 +0800
|
||||
Subject: [PATCH 1/2] mips: pci-mt7620: do not print NFTS register value as
|
||||
error log
|
||||
|
||||
These codes are used to read NFTS_TIMEOUT_DELAY register value and
|
||||
write it into kernel log after writing the register. they are only
|
||||
used for debugging during driver development, so there is no need
|
||||
to keep them now.
|
||||
|
||||
Tested on MT7628AN router Motorola MWR03.
|
||||
|
||||
Signed-off-by: Shiji Yang <yangshiji66@outlook.com>
|
||||
Reviewed-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
|
||||
---
|
||||
arch/mips/pci/pci-mt7620.c | 3 ---
|
||||
1 file changed, 3 deletions(-)
|
||||
|
||||
--- a/arch/mips/pci/pci-mt7620.c
|
||||
+++ b/arch/mips/pci/pci-mt7620.c
|
||||
@@ -274,9 +274,6 @@ static int mt7628_pci_hw_init(struct pla
|
||||
val |= 0x50 << 8;
|
||||
pci_config_write(NULL, 0, 0x70c, 4, val);
|
||||
|
||||
- pci_config_read(NULL, 0, 0x70c, 4, &val);
|
||||
- dev_err(&pdev->dev, "Port 0 N_FTS = %x\n", (unsigned int) val);
|
||||
-
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,39 +0,0 @@
|
||||
From 89ec9bbe60b61cc6ae3eddd6d4f43e128f8a88de Mon Sep 17 00:00:00 2001
|
||||
From: Shiji Yang <yangshiji66@outlook.com>
|
||||
Date: Tue, 20 Jun 2023 18:43:23 +0800
|
||||
Subject: [PATCH 2/2] mips: pci-mt7620: use dev_info() to log PCIe device
|
||||
detection result
|
||||
|
||||
Usually, We only need to print the error log when there is a PCIe card but
|
||||
initialization fails. Whether the driver finds the PCIe card or not is the
|
||||
expected behavior. So it's better to log these information with dev_info().
|
||||
|
||||
Tested on MT7628AN router Motorola MWR03.
|
||||
|
||||
Signed-off-by: Shiji Yang <yangshiji66@outlook.com>
|
||||
Reviewed-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
|
||||
---
|
||||
arch/mips/pci/pci-mt7620.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/arch/mips/pci/pci-mt7620.c
|
||||
+++ b/arch/mips/pci/pci-mt7620.c
|
||||
@@ -331,7 +331,7 @@ static int mt7620_pci_probe(struct platf
|
||||
rt_sysc_m32(RALINK_PCIE0_CLK_EN, 0, RALINK_CLKCFG1);
|
||||
if (ralink_soc == MT762X_SOC_MT7620A)
|
||||
rt_sysc_m32(LC_CKDRVPD, PDRV_SW_SET, PPLL_DRV);
|
||||
- dev_err(&pdev->dev, "PCIE0 no card, disable it(RST&CLK)\n");
|
||||
+ dev_info(&pdev->dev, "PCIE0 no card, disable it(RST&CLK)\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -374,7 +374,7 @@ int pcibios_map_irq(const struct pci_dev
|
||||
dev->bus->number, slot);
|
||||
return 0;
|
||||
}
|
||||
- dev_err(&dev->dev, "card - bus=0x%x, slot = 0x%x irq=%d\n",
|
||||
+ dev_info(&dev->dev, "card - bus=0x%x, slot = 0x%x irq=%d\n",
|
||||
dev->bus->number, slot, irq);
|
||||
|
||||
/* configure the cache line size to 0x14 */
|
File diff suppressed because it is too large
Load Diff
@ -1,134 +0,0 @@
|
||||
From: Bjorn Helgaas <bhelgaas@google.com>
|
||||
Date: Wed, 22 Dec 2021 19:10:48 -0600
|
||||
Subject: [PATCH] PCI: mt7621: Rename mt7621_pci_ to mt7621_pcie_
|
||||
|
||||
Rename mt7621_pci_* structs and functions to mt7621_pcie_* for consistency
|
||||
with the rest of the file.
|
||||
|
||||
Link: https://lore.kernel.org/r/20211223011054.1227810-18-helgaas@kernel.org
|
||||
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
|
||||
Reviewed-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Cc: Matthias Brugger <matthias.bgg@gmail.com>
|
||||
---
|
||||
|
||||
--- a/drivers/pci/controller/pcie-mt7621.c
|
||||
+++ b/drivers/pci/controller/pcie-mt7621.c
|
||||
@@ -93,8 +93,8 @@ struct mt7621_pcie_port {
|
||||
* reset lines are inverted.
|
||||
*/
|
||||
struct mt7621_pcie {
|
||||
- void __iomem *base;
|
||||
struct device *dev;
|
||||
+ void __iomem *base;
|
||||
struct list_head ports;
|
||||
bool resets_inverted;
|
||||
};
|
||||
@@ -129,7 +129,7 @@ static inline void pcie_port_write(struc
|
||||
writel_relaxed(val, port->base + reg);
|
||||
}
|
||||
|
||||
-static inline u32 mt7621_pci_get_cfgaddr(unsigned int bus, unsigned int slot,
|
||||
+static inline u32 mt7621_pcie_get_cfgaddr(unsigned int bus, unsigned int slot,
|
||||
unsigned int func, unsigned int where)
|
||||
{
|
||||
return (((where & 0xf00) >> 8) << 24) | (bus << 16) | (slot << 11) |
|
||||
@@ -140,7 +140,7 @@ static void __iomem *mt7621_pcie_map_bus
|
||||
unsigned int devfn, int where)
|
||||
{
|
||||
struct mt7621_pcie *pcie = bus->sysdata;
|
||||
- u32 address = mt7621_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn),
|
||||
+ u32 address = mt7621_pcie_get_cfgaddr(bus->number, PCI_SLOT(devfn),
|
||||
PCI_FUNC(devfn), where);
|
||||
|
||||
writel_relaxed(address, pcie->base + RALINK_PCI_CONFIG_ADDR);
|
||||
@@ -148,7 +148,7 @@ static void __iomem *mt7621_pcie_map_bus
|
||||
return pcie->base + RALINK_PCI_CONFIG_DATA + (where & 3);
|
||||
}
|
||||
|
||||
-struct pci_ops mt7621_pci_ops = {
|
||||
+struct pci_ops mt7621_pcie_ops = {
|
||||
.map_bus = mt7621_pcie_map_bus,
|
||||
.read = pci_generic_config_read,
|
||||
.write = pci_generic_config_write,
|
||||
@@ -156,7 +156,7 @@ struct pci_ops mt7621_pci_ops = {
|
||||
|
||||
static u32 read_config(struct mt7621_pcie *pcie, unsigned int dev, u32 reg)
|
||||
{
|
||||
- u32 address = mt7621_pci_get_cfgaddr(0, dev, 0, reg);
|
||||
+ u32 address = mt7621_pcie_get_cfgaddr(0, dev, 0, reg);
|
||||
|
||||
pcie_write(pcie, address, RALINK_PCI_CONFIG_ADDR);
|
||||
return pcie_read(pcie, RALINK_PCI_CONFIG_DATA);
|
||||
@@ -165,7 +165,7 @@ static u32 read_config(struct mt7621_pci
|
||||
static void write_config(struct mt7621_pcie *pcie, unsigned int dev,
|
||||
u32 reg, u32 val)
|
||||
{
|
||||
- u32 address = mt7621_pci_get_cfgaddr(0, dev, 0, reg);
|
||||
+ u32 address = mt7621_pcie_get_cfgaddr(0, dev, 0, reg);
|
||||
|
||||
pcie_write(pcie, address, RALINK_PCI_CONFIG_ADDR);
|
||||
pcie_write(pcie, val, RALINK_PCI_CONFIG_DATA);
|
||||
@@ -505,16 +505,16 @@ static int mt7621_pcie_register_host(str
|
||||
{
|
||||
struct mt7621_pcie *pcie = pci_host_bridge_priv(host);
|
||||
|
||||
- host->ops = &mt7621_pci_ops;
|
||||
+ host->ops = &mt7621_pcie_ops;
|
||||
host->sysdata = pcie;
|
||||
return pci_host_probe(host);
|
||||
}
|
||||
|
||||
-static const struct soc_device_attribute mt7621_pci_quirks_match[] = {
|
||||
+static const struct soc_device_attribute mt7621_pcie_quirks_match[] = {
|
||||
{ .soc_id = "mt7621", .revision = "E2" }
|
||||
};
|
||||
|
||||
-static int mt7621_pci_probe(struct platform_device *pdev)
|
||||
+static int mt7621_pcie_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
const struct soc_device_attribute *attr;
|
||||
@@ -535,7 +535,7 @@ static int mt7621_pci_probe(struct platf
|
||||
platform_set_drvdata(pdev, pcie);
|
||||
INIT_LIST_HEAD(&pcie->ports);
|
||||
|
||||
- attr = soc_device_match(mt7621_pci_quirks_match);
|
||||
+ attr = soc_device_match(mt7621_pcie_quirks_match);
|
||||
if (attr)
|
||||
pcie->resets_inverted = true;
|
||||
|
||||
@@ -572,7 +572,7 @@ remove_resets:
|
||||
return err;
|
||||
}
|
||||
|
||||
-static int mt7621_pci_remove(struct platform_device *pdev)
|
||||
+static int mt7621_pcie_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct mt7621_pcie *pcie = platform_get_drvdata(pdev);
|
||||
struct mt7621_pcie_port *port;
|
||||
@@ -583,18 +583,18 @@ static int mt7621_pci_remove(struct plat
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static const struct of_device_id mt7621_pci_ids[] = {
|
||||
+static const struct of_device_id mt7621_pcie_ids[] = {
|
||||
{ .compatible = "mediatek,mt7621-pci" },
|
||||
{},
|
||||
};
|
||||
-MODULE_DEVICE_TABLE(of, mt7621_pci_ids);
|
||||
+MODULE_DEVICE_TABLE(of, mt7621_pcie_ids);
|
||||
|
||||
-static struct platform_driver mt7621_pci_driver = {
|
||||
- .probe = mt7621_pci_probe,
|
||||
- .remove = mt7621_pci_remove,
|
||||
+static struct platform_driver mt7621_pcie_driver = {
|
||||
+ .probe = mt7621_pcie_probe,
|
||||
+ .remove = mt7621_pcie_remove,
|
||||
.driver = {
|
||||
.name = "mt7621-pci",
|
||||
- .of_match_table = of_match_ptr(mt7621_pci_ids),
|
||||
+ .of_match_table = of_match_ptr(mt7621_pcie_ids),
|
||||
},
|
||||
};
|
||||
-builtin_platform_driver(mt7621_pci_driver);
|
||||
+builtin_platform_driver(mt7621_pcie_driver);
|
@ -1,30 +0,0 @@
|
||||
From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Date: Wed, 17 Nov 2021 16:29:52 +0100
|
||||
Subject: [PATCH] PCI: mt7621: Declare mt7621_pci_ops static
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Sparse complains about mt7621_pci_ops symbol is not declared and asks if
|
||||
it should be declared as static instead. Sparse is right. Hence declare
|
||||
symbol as static.
|
||||
|
||||
Link: https://lore.kernel.org/r/20211117152952.12271-1-sergio.paracuellos@gmail.com
|
||||
Reported-by: kernel test robot <lkp@intel.com>
|
||||
Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
|
||||
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
|
||||
Reviewed-by: Krzysztof Wilczyński <kw@linux.com>
|
||||
---
|
||||
|
||||
--- a/drivers/pci/controller/pcie-mt7621.c
|
||||
+++ b/drivers/pci/controller/pcie-mt7621.c
|
||||
@@ -148,7 +148,7 @@ static void __iomem *mt7621_pcie_map_bus
|
||||
return pcie->base + RALINK_PCI_CONFIG_DATA + (where & 3);
|
||||
}
|
||||
|
||||
-struct pci_ops mt7621_pcie_ops = {
|
||||
+static struct pci_ops mt7621_pcie_ops = {
|
||||
.map_bus = mt7621_pcie_map_bus,
|
||||
.read = pci_generic_config_read,
|
||||
.write = pci_generic_config_write,
|
@ -1,119 +0,0 @@
|
||||
From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Date: Tue, 7 Dec 2021 11:49:21 +0100
|
||||
Subject: [PATCH] PCI: mt7621: Move MIPS setup to pcibios_root_bridge_prepare()
|
||||
|
||||
On the MIPS ralink mt7621 platform, we need to set up I/O coherency units
|
||||
based on the host bridge apertures.
|
||||
|
||||
To remove this arch dependency from the driver itself, move the coherency
|
||||
setup from the driver to pcibios_root_bridge_prepare().
|
||||
|
||||
[bhelgaas: squash add/remove into one patch, commit log]
|
||||
Link: https://lore.kernel.org/r/20211207104924.21327-3-sergio.paracuellos@gmail.com
|
||||
Link: https://lore.kernel.org/r/20211207104924.21327-4-sergio.paracuellos@gmail.com
|
||||
Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
|
||||
Reviewed-by: Guenter Roeck <linux@roeck-us.net> # arch/mips
|
||||
Acked-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de> # arch/mips
|
||||
---
|
||||
|
||||
--- a/arch/mips/ralink/mt7621.c
|
||||
+++ b/arch/mips/ralink/mt7621.c
|
||||
@@ -10,6 +10,8 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/sys_soc.h>
|
||||
#include <linux/memblock.h>
|
||||
+#include <linux/pci.h>
|
||||
+#include <linux/bug.h>
|
||||
|
||||
#include <asm/bootinfo.h>
|
||||
#include <asm/mipsregs.h>
|
||||
@@ -25,6 +27,35 @@
|
||||
static u32 detect_magic __initdata;
|
||||
static struct ralink_soc_info *soc_info_ptr;
|
||||
|
||||
+int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
|
||||
+{
|
||||
+ struct resource_entry *entry;
|
||||
+ resource_size_t mask;
|
||||
+
|
||||
+ entry = resource_list_first_type(&bridge->windows, IORESOURCE_MEM);
|
||||
+ if (!entry) {
|
||||
+ pr_err("Cannot get memory resource\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ if (mips_cps_numiocu(0)) {
|
||||
+ /*
|
||||
+ * Hardware doesn't accept mask values with 1s after
|
||||
+ * 0s (e.g. 0xffef), so warn if that's happen
|
||||
+ */
|
||||
+ mask = ~(entry->res->end - entry->res->start) & CM_GCR_REGn_MASK_ADDRMASK;
|
||||
+ WARN_ON(mask && BIT(ffz(~mask)) - 1 != ~mask);
|
||||
+
|
||||
+ write_gcr_reg1_base(entry->res->start);
|
||||
+ write_gcr_reg1_mask(mask | CM_GCR_REGn_MASK_CMTGT_IOCU0);
|
||||
+ pr_info("PCI coherence region base: 0x%08llx, mask/settings: 0x%08llx\n",
|
||||
+ (unsigned long long)read_gcr_reg1_base(),
|
||||
+ (unsigned long long)read_gcr_reg1_mask());
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
phys_addr_t mips_cpc_default_phys_base(void)
|
||||
{
|
||||
panic("Cannot detect cpc address");
|
||||
--- a/drivers/pci/controller/pcie-mt7621.c
|
||||
+++ b/drivers/pci/controller/pcie-mt7621.c
|
||||
@@ -208,37 +208,6 @@ static inline void mt7621_control_deasse
|
||||
reset_control_assert(port->pcie_rst);
|
||||
}
|
||||
|
||||
-static int setup_cm_memory_region(struct pci_host_bridge *host)
|
||||
-{
|
||||
- struct mt7621_pcie *pcie = pci_host_bridge_priv(host);
|
||||
- struct device *dev = pcie->dev;
|
||||
- struct resource_entry *entry;
|
||||
- resource_size_t mask;
|
||||
-
|
||||
- entry = resource_list_first_type(&host->windows, IORESOURCE_MEM);
|
||||
- if (!entry) {
|
||||
- dev_err(dev, "cannot get memory resource\n");
|
||||
- return -EINVAL;
|
||||
- }
|
||||
-
|
||||
- if (mips_cps_numiocu(0)) {
|
||||
- /*
|
||||
- * FIXME: hardware doesn't accept mask values with 1s after
|
||||
- * 0s (e.g. 0xffef), so it would be great to warn if that's
|
||||
- * about to happen
|
||||
- */
|
||||
- mask = ~(entry->res->end - entry->res->start);
|
||||
-
|
||||
- write_gcr_reg1_base(entry->res->start);
|
||||
- write_gcr_reg1_mask(mask | CM_GCR_REGn_MASK_CMTGT_IOCU0);
|
||||
- dev_info(dev, "PCI coherence region base: 0x%08llx, mask/settings: 0x%08llx\n",
|
||||
- (unsigned long long)read_gcr_reg1_base(),
|
||||
- (unsigned long long)read_gcr_reg1_mask());
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
static int mt7621_pcie_parse_port(struct mt7621_pcie *pcie,
|
||||
struct device_node *node,
|
||||
int slot)
|
||||
@@ -557,12 +526,6 @@ static int mt7621_pcie_probe(struct plat
|
||||
goto remove_resets;
|
||||
}
|
||||
|
||||
- err = setup_cm_memory_region(bridge);
|
||||
- if (err) {
|
||||
- dev_err(dev, "error setting up iocu mem regions\n");
|
||||
- goto remove_resets;
|
||||
- }
|
||||
-
|
||||
return mt7621_pcie_register_host(bridge);
|
||||
|
||||
remove_resets:
|
@ -1,35 +0,0 @@
|
||||
From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Date: Mon, 24 Jan 2022 12:30:02 +0100
|
||||
Subject: [PATCH] PCI: mt7621: Drop of_match_ptr() to avoid unused variable
|
||||
|
||||
We have stubs for most OF interfaces even when CONFIG_OF is not set, so we
|
||||
allow building of pcie-mt7621.c in that case for compile testing.
|
||||
|
||||
When CONFIG_OF is not set, "of_match_ptr(mt7621_pcie_ids)" compiles to
|
||||
NULL, which leaves mt7621_pcie_ids unused:
|
||||
|
||||
$ make W=1
|
||||
drivers/pci/controller/pcie-mt7621.c:549:34: warning: unused variable 'mt7621_pcie_ids' [-Wunused-const-variable]
|
||||
|
||||
Drop of_match_ptr() to avoid the unused variable warning.
|
||||
|
||||
[bhelgaas: commit log]
|
||||
Fixes: 2bdd5238e756 ("PCI: mt7621: Add MediaTek MT7621 PCIe host controller driver")
|
||||
Link: https://lore.kernel.org/r/20220124113003.406224-2-sergio.paracuellos@gmail.com
|
||||
Link: https://lore.kernel.org/r/202201241754.igtHzgHv-lkp@intel.com
|
||||
Reported-by: kernel test robot <lkp@intel.com>
|
||||
Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
|
||||
---
|
||||
|
||||
--- a/drivers/pci/controller/pcie-mt7621.c
|
||||
+++ b/drivers/pci/controller/pcie-mt7621.c
|
||||
@@ -557,7 +557,7 @@ static struct platform_driver mt7621_pci
|
||||
.remove = mt7621_pcie_remove,
|
||||
.driver = {
|
||||
.name = "mt7621-pci",
|
||||
- .of_match_table = of_match_ptr(mt7621_pcie_ids),
|
||||
+ .of_match_table = mt7621_pcie_ids,
|
||||
},
|
||||
};
|
||||
builtin_platform_driver(mt7621_pcie_driver);
|
@ -1,35 +0,0 @@
|
||||
From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Date: Mon, 24 Jan 2022 12:30:03 +0100
|
||||
Subject: [PATCH] PCI: mt7621: Remove unused function pcie_rmw()
|
||||
|
||||
Function pcie_rmw() is not being used at all and can be deleted. Hence get
|
||||
rid of it, which fixes this warning:
|
||||
|
||||
drivers/pci/controller/pcie-mt7621.c:112:20: warning: unused function 'pcie_rmw' [-Wunused-function]
|
||||
|
||||
Fixes: 2bdd5238e756 ("PCI: mt7621: Add MediaTek MT7621 PCIe host controller driver")
|
||||
Link: https://lore.kernel.org/r/20220124113003.406224-3-sergio.paracuellos@gmail.com
|
||||
Link: https://lore.kernel.org/all/202201241754.igtHzgHv-lkp@intel.com/
|
||||
Reported-by: kernel test robot <lkp@intel.com>
|
||||
Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
|
||||
---
|
||||
|
||||
--- a/drivers/pci/controller/pcie-mt7621.c
|
||||
+++ b/drivers/pci/controller/pcie-mt7621.c
|
||||
@@ -109,15 +109,6 @@ static inline void pcie_write(struct mt7
|
||||
writel_relaxed(val, pcie->base + reg);
|
||||
}
|
||||
|
||||
-static inline void pcie_rmw(struct mt7621_pcie *pcie, u32 reg, u32 clr, u32 set)
|
||||
-{
|
||||
- u32 val = readl_relaxed(pcie->base + reg);
|
||||
-
|
||||
- val &= ~clr;
|
||||
- val |= set;
|
||||
- writel_relaxed(val, pcie->base + reg);
|
||||
-}
|
||||
-
|
||||
static inline u32 pcie_port_read(struct mt7621_pcie_port *port, u32 reg)
|
||||
{
|
||||
return readl_relaxed(port->base + reg);
|
@ -1,38 +0,0 @@
|
||||
From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Date: Tue, 7 Dec 2021 11:49:20 +0100
|
||||
Subject: [PATCH] PCI: Let pcibios_root_bridge_prepare() access bridge->windows
|
||||
|
||||
When pci_register_host_bridge() is called, bridge->windows are already
|
||||
available. However these windows are being moved temporarily from there.
|
||||
|
||||
To let pcibios_root_bridge_prepare() have access to these windows, move the
|
||||
windows movement after calling this function. This is useful for the MIPS
|
||||
ralink mt7621 platform so it can set up I/O coherence units and avoid
|
||||
custom MIPS code in the mt7621 PCIe controller driver.
|
||||
|
||||
Link: https://lore.kernel.org/r/20211207104924.21327-2-sergio.paracuellos@gmail.com
|
||||
Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
|
||||
Acked-by: Arnd Bergmann <arnd@arndb.de>
|
||||
---
|
||||
|
||||
--- a/drivers/pci/probe.c
|
||||
+++ b/drivers/pci/probe.c
|
||||
@@ -898,8 +898,6 @@ static int pci_register_host_bridge(stru
|
||||
|
||||
bridge->bus = bus;
|
||||
|
||||
- /* Temporarily move resources off the list */
|
||||
- list_splice_init(&bridge->windows, &resources);
|
||||
bus->sysdata = bridge->sysdata;
|
||||
bus->ops = bridge->ops;
|
||||
bus->number = bus->busn_res.start = bridge->busnr;
|
||||
@@ -925,6 +923,8 @@ static int pci_register_host_bridge(stru
|
||||
if (err)
|
||||
goto free;
|
||||
|
||||
+ /* Temporarily move resources off the list */
|
||||
+ list_splice_init(&bridge->windows, &resources);
|
||||
err = device_add(&bridge->dev);
|
||||
if (err) {
|
||||
put_device(&bridge->dev);
|
@ -1,38 +0,0 @@
|
||||
From 19098934f910b4d47cb30251dd39ffa57bef9523 Mon Sep 17 00:00:00 2001
|
||||
From: John Thomson <git@johnthomson.fastmail.com.au>
|
||||
Date: Tue, 6 Dec 2022 06:46:45 +1000
|
||||
Subject: [PATCH] PCI: mt7621: Add sentinel to quirks table
|
||||
|
||||
Current driver is missing a sentinel in the struct soc_device_attribute
|
||||
array, which causes an oops when assessed by the
|
||||
soc_device_match(mt7621_pcie_quirks_match) call.
|
||||
|
||||
This was only exposed once the CONFIG_SOC_MT7621 mt7621 soc_dev_attr
|
||||
was fixed to register the SOC as a device, in:
|
||||
|
||||
commit 7c18b64bba3b ("mips: ralink: mt7621: do not use kzalloc too early")
|
||||
|
||||
Fix it by adding the required sentinel.
|
||||
|
||||
Link: https://lore.kernel.org/lkml/26ebbed1-0fe9-4af9-8466-65f841d0b382@app.fastmail.com
|
||||
Link: https://lore.kernel.org/r/20221205204645.301301-1-git@johnthomson.fastmail.com.au
|
||||
Fixes: b483b4e4d3f6 ("staging: mt7621-pci: add quirks for 'E2' revision using 'soc_device_attribute'")
|
||||
Signed-off-by: John Thomson <git@johnthomson.fastmail.com.au>
|
||||
Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org>
|
||||
Acked-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
---
|
||||
drivers/pci/controller/pcie-mt7621.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/pci/controller/pcie-mt7621.c
|
||||
+++ b/drivers/pci/controller/pcie-mt7621.c
|
||||
@@ -471,7 +471,8 @@ static int mt7621_pcie_register_host(str
|
||||
}
|
||||
|
||||
static const struct soc_device_attribute mt7621_pcie_quirks_match[] = {
|
||||
- { .soc_id = "mt7621", .revision = "E2" }
|
||||
+ { .soc_id = "mt7621", .revision = "E2" },
|
||||
+ { /* sentinel */ }
|
||||
};
|
||||
|
||||
static int mt7621_pcie_probe(struct platform_device *pdev)
|
@ -1,52 +0,0 @@
|
||||
From 0cb2a8f3456ff1cc51d571e287a48e8fddc98ec2 Mon Sep 17 00:00:00 2001
|
||||
From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Date: Sat, 31 Dec 2022 08:40:41 +0100
|
||||
Subject: PCI: mt7621: Delay phy ports initialization
|
||||
|
||||
Some devices like ZBT WE1326 and ZBT WF3526-P and some Netgear models need
|
||||
to delay phy port initialization after calling the mt7621_pcie_init_port()
|
||||
driver function to get into reliable boots for both warm and hard resets.
|
||||
|
||||
The delay required to detect the ports seems to be in the range [75-100]
|
||||
milliseconds.
|
||||
|
||||
If the ports are not detected the controller is not functional.
|
||||
|
||||
There is no datasheet or something similar to really understand why this
|
||||
extra delay is needed only for these devices and it is not for most of
|
||||
the boards that are built on mt7621 SoC.
|
||||
|
||||
This issue has been reported by openWRT community and the complete
|
||||
discussion is in [0]. The 100 milliseconds delay has been tested in all
|
||||
devices to validate it.
|
||||
|
||||
Add the extra 100 milliseconds delay to fix the issue.
|
||||
|
||||
[0]: https://github.com/openwrt/openwrt/pull/11220
|
||||
|
||||
Link: https://lore.kernel.org/r/20221231074041.264738-1-sergio.paracuellos@gmail.com
|
||||
Fixes: 2bdd5238e756 ("PCI: mt7621: Add MediaTek MT7621 PCIe host controller driver")
|
||||
Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org>
|
||||
---
|
||||
drivers/pci/controller/pcie-mt7621.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
--- a/drivers/pci/controller/pcie-mt7621.c
|
||||
+++ b/drivers/pci/controller/pcie-mt7621.c
|
||||
@@ -58,6 +58,7 @@
|
||||
#define PCIE_PORT_LINKUP BIT(0)
|
||||
#define PCIE_PORT_CNT 3
|
||||
|
||||
+#define INIT_PORTS_DELAY_MS 100
|
||||
#define PERST_DELAY_MS 100
|
||||
|
||||
/**
|
||||
@@ -374,6 +375,7 @@ static int mt7621_pcie_init_ports(struct
|
||||
}
|
||||
}
|
||||
|
||||
+ msleep(INIT_PORTS_DELAY_MS);
|
||||
mt7621_pcie_reset_ep_deassert(pcie);
|
||||
|
||||
tmp = NULL;
|
@ -1,31 +0,0 @@
|
||||
From 3f6dfa25128e428acfba20792bc7506d58806baa Mon Sep 17 00:00:00 2001
|
||||
From: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Date: Sun, 7 May 2023 01:06:17 +0200
|
||||
Subject: [PATCH] drivers: mt7621-dma: handle error from device_reset
|
||||
|
||||
Handle error from device reset to fix compilation warning.
|
||||
Fix compilation warning:
|
||||
drivers/staging/mt7621-dma/hsdma-mt7621.c: In function 'mtk_hsdma_probe':
|
||||
drivers/staging/mt7621-dma/hsdma-mt7621.c:685:9: error: ignoring return value of 'device_reset' declared with attribute 'warn_unused_result' [-Werror=unused-result]
|
||||
685 | device_reset(&pdev->dev);
|
||||
| ^~~~~~~~~~~~~~~~~~~~~~~~
|
||||
cc1: all warnings being treated as errors
|
||||
|
||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
---
|
||||
drivers/staging/mt7621-dma/hsdma-mt7621.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/staging/mt7621-dma/hsdma-mt7621.c
|
||||
+++ b/drivers/staging/mt7621-dma/hsdma-mt7621.c
|
||||
@@ -682,7 +682,9 @@ static int mtk_hsdma_probe(struct platfo
|
||||
return ret;
|
||||
}
|
||||
|
||||
- device_reset(&pdev->dev);
|
||||
+ ret = device_reset(&pdev->dev);
|
||||
+ if (ret)
|
||||
+ dev_err(&pdev->dev, "failed to reset device\n");
|
||||
|
||||
dd = &hsdma->ddev;
|
||||
dma_cap_set(DMA_MEMCPY, dd->cap_mask);
|
@ -1,31 +0,0 @@
|
||||
From 50233e105a0332ec0f3bc83180c416e6b200471e Mon Sep 17 00:00:00 2001
|
||||
From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Date: Fri, 24 Mar 2023 08:37:33 +0100
|
||||
Subject: PCI: mt7621: Use dev_info() to log PCIe card detection
|
||||
|
||||
When there is no card plugged on a PCIe port a log reporting that
|
||||
the port will be disabled is flagged as an error (dev_err()).
|
||||
|
||||
Since this is not an error at all, change the log level by using
|
||||
dev_info() instead.
|
||||
|
||||
Link: https://lore.kernel.org/r/20230324073733.1596231-1-sergio.paracuellos@gmail.com
|
||||
Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org>
|
||||
---
|
||||
drivers/pci/controller/pcie-mt7621.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/pci/controller/pcie-mt7621.c
|
||||
+++ b/drivers/pci/controller/pcie-mt7621.c
|
||||
@@ -383,8 +383,8 @@ static int mt7621_pcie_init_ports(struct
|
||||
u32 slot = port->slot;
|
||||
|
||||
if (!mt7621_pcie_port_is_linkup(port)) {
|
||||
- dev_err(dev, "pcie%d no card, disable it (RST & CLK)\n",
|
||||
- slot);
|
||||
+ dev_info(dev, "pcie%d no card, disable it (RST & CLK)\n",
|
||||
+ slot);
|
||||
mt7621_control_assert(port);
|
||||
port->enabled = false;
|
||||
num_disabled++;
|
@ -1,20 +0,0 @@
|
||||
--- a/drivers/net/ethernet/Kconfig
|
||||
+++ b/drivers/net/ethernet/Kconfig
|
||||
@@ -162,6 +162,7 @@ source "drivers/net/ethernet/pensando/Kc
|
||||
source "drivers/net/ethernet/qlogic/Kconfig"
|
||||
source "drivers/net/ethernet/brocade/Kconfig"
|
||||
source "drivers/net/ethernet/qualcomm/Kconfig"
|
||||
+source "drivers/net/ethernet/ralink/Kconfig"
|
||||
source "drivers/net/ethernet/rdc/Kconfig"
|
||||
source "drivers/net/ethernet/realtek/Kconfig"
|
||||
source "drivers/net/ethernet/renesas/Kconfig"
|
||||
--- a/drivers/net/ethernet/Makefile
|
||||
+++ b/drivers/net/ethernet/Makefile
|
||||
@@ -73,6 +73,7 @@ obj-$(CONFIG_NET_VENDOR_PACKET_ENGINES)
|
||||
obj-$(CONFIG_NET_VENDOR_PASEMI) += pasemi/
|
||||
obj-$(CONFIG_NET_VENDOR_QLOGIC) += qlogic/
|
||||
obj-$(CONFIG_NET_VENDOR_QUALCOMM) += qualcomm/
|
||||
+obj-$(CONFIG_NET_VENDOR_RALINK) += ralink/
|
||||
obj-$(CONFIG_NET_VENDOR_REALTEK) += realtek/
|
||||
obj-$(CONFIG_NET_VENDOR_RENESAS) += renesas/
|
||||
obj-$(CONFIG_NET_VENDOR_RDC) += rdc/
|
@ -1,19 +0,0 @@
|
||||
--- a/arch/mips/include/asm/mach-ralink/mt7620.h
|
||||
+++ b/arch/mips/include/asm/mach-ralink/mt7620.h
|
||||
@@ -61,4 +61,16 @@ static inline int mt7620_get_eco(void)
|
||||
return rt_sysc_r32(SYSC_REG_CHIP_REV) & CHIP_REV_ECO_MASK;
|
||||
}
|
||||
|
||||
+static inline int mt7620_get_chipver(void)
|
||||
+{
|
||||
+ return (rt_sysc_r32(SYSC_REG_CHIP_REV) >> CHIP_REV_VER_SHIFT) &
|
||||
+ CHIP_REV_VER_MASK;
|
||||
+}
|
||||
+
|
||||
+static inline int mt7620_get_pkg(void)
|
||||
+{
|
||||
+ return (rt_sysc_r32(SYSC_REG_CHIP_REV) >> CHIP_REV_PKG_SHIFT) &
|
||||
+ CHIP_REV_PKG_MASK;
|
||||
+}
|
||||
+
|
||||
#endif
|
@ -1,100 +0,0 @@
|
||||
From ce3d4a4111a5f7e6b4e74bceae5faa6ce388e8ec Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Sun, 14 Jul 2013 23:08:11 +0200
|
||||
Subject: [PATCH 05/53] MIPS: use set_mode() to enable/disable the cevt-r4k
|
||||
irq
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
arch/mips/ralink/Kconfig | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
--- a/arch/mips/ralink/Kconfig
|
||||
+++ b/arch/mips/ralink/Kconfig
|
||||
@@ -1,12 +1,17 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
if RALINK
|
||||
|
||||
+config CEVT_SYSTICK_QUIRK
|
||||
+ bool
|
||||
+ default n
|
||||
+
|
||||
config CLKEVT_RT3352
|
||||
bool
|
||||
depends on SOC_RT305X || SOC_MT7620
|
||||
default y
|
||||
select TIMER_OF
|
||||
select CLKSRC_MMIO
|
||||
+ select CEVT_SYSTICK_QUIRK
|
||||
|
||||
config RALINK_ILL_ACC
|
||||
bool
|
||||
--- a/arch/mips/kernel/cevt-r4k.c
|
||||
+++ b/arch/mips/kernel/cevt-r4k.c
|
||||
@@ -16,6 +16,31 @@
|
||||
#include <asm/time.h>
|
||||
#include <asm/cevt-r4k.h>
|
||||
|
||||
+#ifdef CONFIG_CEVT_SYSTICK_QUIRK
|
||||
+static int mips_state_oneshot(struct clock_event_device *evt)
|
||||
+{
|
||||
+ unsigned long flags = IRQF_PERCPU | IRQF_TIMER | IRQF_SHARED;
|
||||
+ if (!cp0_timer_irq_installed) {
|
||||
+ cp0_timer_irq_installed = 1;
|
||||
+ if (request_irq(evt->irq, c0_compare_interrupt, flags, "timer",
|
||||
+ c0_compare_interrupt))
|
||||
+ pr_err("Failed to request irq %d (timer)\n", evt->irq);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int mips_state_shutdown(struct clock_event_device *evt)
|
||||
+{
|
||||
+ if (cp0_timer_irq_installed) {
|
||||
+ cp0_timer_irq_installed = 0;
|
||||
+ free_irq(evt->irq, NULL);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
static int mips_next_event(unsigned long delta,
|
||||
struct clock_event_device *evt)
|
||||
{
|
||||
@@ -292,7 +317,9 @@ core_initcall(r4k_register_cpufreq_notif
|
||||
|
||||
int r4k_clockevent_init(void)
|
||||
{
|
||||
+#ifndef CONFIG_CEVT_SYSTICK_QUIRK
|
||||
unsigned long flags = IRQF_PERCPU | IRQF_TIMER | IRQF_SHARED;
|
||||
+#endif
|
||||
unsigned int cpu = smp_processor_id();
|
||||
struct clock_event_device *cd;
|
||||
unsigned int irq, min_delta;
|
||||
@@ -322,11 +349,16 @@ int r4k_clockevent_init(void)
|
||||
cd->rating = 300;
|
||||
cd->irq = irq;
|
||||
cd->cpumask = cpumask_of(cpu);
|
||||
+#ifdef CONFIG_CEVT_SYSTICK_QUIRK
|
||||
+ cd->set_state_shutdown = mips_state_shutdown;
|
||||
+ cd->set_state_oneshot = mips_state_oneshot;
|
||||
+#endif
|
||||
cd->set_next_event = mips_next_event;
|
||||
cd->event_handler = mips_event_handler;
|
||||
|
||||
clockevents_config_and_register(cd, mips_hpt_frequency, min_delta, 0x7fffffff);
|
||||
|
||||
+#ifndef CONFIG_CEVT_SYSTICK_QUIRK
|
||||
if (cp0_timer_irq_installed)
|
||||
return 0;
|
||||
|
||||
@@ -335,6 +367,7 @@ int r4k_clockevent_init(void)
|
||||
if (request_irq(irq, c0_compare_interrupt, flags, "timer",
|
||||
c0_compare_interrupt))
|
||||
pr_err("Failed to request irq %d (timer)\n", irq);
|
||||
+#endif
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,195 +0,0 @@
|
||||
From bd30f19a006fb52bac80c6463c49dd2f4159f4ac Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Sun, 28 Jul 2013 16:26:41 +0200
|
||||
Subject: [PATCH 06/53] MIPS: ralink: add cpu frequency scaling
|
||||
|
||||
This feature will break udelay() and cause the delay loop to have longer delays
|
||||
when the frequency is scaled causing a performance hit.
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
arch/mips/ralink/cevt-rt3352.c | 38 ++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 38 insertions(+)
|
||||
|
||||
--- a/arch/mips/ralink/cevt-rt3352.c
|
||||
+++ b/arch/mips/ralink/cevt-rt3352.c
|
||||
@@ -29,6 +29,10 @@
|
||||
/* enable the counter */
|
||||
#define CFG_CNT_EN 0x1
|
||||
|
||||
+/* mt7620 frequency scaling defines */
|
||||
+#define CLK_LUT_CFG 0x40
|
||||
+#define SLEEP_EN BIT(31)
|
||||
+
|
||||
struct systick_device {
|
||||
void __iomem *membase;
|
||||
struct clock_event_device dev;
|
||||
@@ -36,21 +40,53 @@ struct systick_device {
|
||||
int freq_scale;
|
||||
};
|
||||
|
||||
+static void (*systick_freq_scaling)(struct systick_device *sdev, int status);
|
||||
+
|
||||
static int systick_set_oneshot(struct clock_event_device *evt);
|
||||
static int systick_shutdown(struct clock_event_device *evt);
|
||||
|
||||
+static inline void mt7620_freq_scaling(struct systick_device *sdev, int status)
|
||||
+{
|
||||
+ if (sdev->freq_scale == status)
|
||||
+ return;
|
||||
+
|
||||
+ sdev->freq_scale = status;
|
||||
+
|
||||
+ pr_info("%s: %s autosleep mode\n", sdev->dev.name,
|
||||
+ (status) ? ("enable") : ("disable"));
|
||||
+ if (status)
|
||||
+ rt_sysc_w32(rt_sysc_r32(CLK_LUT_CFG) | SLEEP_EN, CLK_LUT_CFG);
|
||||
+ else
|
||||
+ rt_sysc_w32(rt_sysc_r32(CLK_LUT_CFG) & ~SLEEP_EN, CLK_LUT_CFG);
|
||||
+}
|
||||
+
|
||||
+static inline unsigned int read_count(struct systick_device *sdev)
|
||||
+{
|
||||
+ return ioread32(sdev->membase + SYSTICK_COUNT);
|
||||
+}
|
||||
+
|
||||
+static inline unsigned int read_compare(struct systick_device *sdev)
|
||||
+{
|
||||
+ return ioread32(sdev->membase + SYSTICK_COMPARE);
|
||||
+}
|
||||
+
|
||||
+static inline void write_compare(struct systick_device *sdev, unsigned int val)
|
||||
+{
|
||||
+ iowrite32(val, sdev->membase + SYSTICK_COMPARE);
|
||||
+}
|
||||
+
|
||||
static int systick_next_event(unsigned long delta,
|
||||
struct clock_event_device *evt)
|
||||
{
|
||||
struct systick_device *sdev;
|
||||
- u32 count;
|
||||
+ int res;
|
||||
|
||||
sdev = container_of(evt, struct systick_device, dev);
|
||||
- count = ioread32(sdev->membase + SYSTICK_COUNT);
|
||||
- count = (count + delta) % SYSTICK_FREQ;
|
||||
- iowrite32(count, sdev->membase + SYSTICK_COMPARE);
|
||||
+ delta += read_count(sdev);
|
||||
+ write_compare(sdev, delta);
|
||||
+ res = ((int)(read_count(sdev) - delta) >= 0) ? -ETIME : 0;
|
||||
|
||||
- return 0;
|
||||
+ return res;
|
||||
}
|
||||
|
||||
static void systick_event_handler(struct clock_event_device *dev)
|
||||
@@ -60,20 +96,25 @@ static void systick_event_handler(struct
|
||||
|
||||
static irqreturn_t systick_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
- struct clock_event_device *dev = (struct clock_event_device *) dev_id;
|
||||
+ int ret = 0;
|
||||
+ struct clock_event_device *cdev;
|
||||
+ struct systick_device *sdev;
|
||||
|
||||
- dev->event_handler(dev);
|
||||
+ if (read_c0_cause() & STATUSF_IP7) {
|
||||
+ cdev = (struct clock_event_device *) dev_id;
|
||||
+ sdev = container_of(cdev, struct systick_device, dev);
|
||||
+
|
||||
+ /* Clear Count/Compare Interrupt */
|
||||
+ write_compare(sdev, read_compare(sdev));
|
||||
+ cdev->event_handler(cdev);
|
||||
+ ret = 1;
|
||||
+ }
|
||||
|
||||
- return IRQ_HANDLED;
|
||||
+ return IRQ_RETVAL(ret);
|
||||
}
|
||||
|
||||
static struct systick_device systick = {
|
||||
.dev = {
|
||||
- /*
|
||||
- * cevt-r4k uses 300, make sure systick
|
||||
- * gets used if available
|
||||
- */
|
||||
- .rating = 310,
|
||||
.features = CLOCK_EVT_FEAT_ONESHOT,
|
||||
.set_next_event = systick_next_event,
|
||||
.set_state_shutdown = systick_shutdown,
|
||||
@@ -91,7 +132,13 @@ static int systick_shutdown(struct clock
|
||||
if (sdev->irq_requested)
|
||||
free_irq(systick.dev.irq, &systick.dev);
|
||||
sdev->irq_requested = 0;
|
||||
- iowrite32(0, systick.membase + SYSTICK_CONFIG);
|
||||
+ iowrite32(CFG_CNT_EN, systick.membase + SYSTICK_CONFIG);
|
||||
+
|
||||
+ if (systick_freq_scaling)
|
||||
+ systick_freq_scaling(sdev, 0);
|
||||
+
|
||||
+ if (systick_freq_scaling)
|
||||
+ systick_freq_scaling(sdev, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -116,33 +163,46 @@ static int systick_set_oneshot(struct cl
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static const struct of_device_id systick_match[] = {
|
||||
+ { .compatible = "ralink,mt7620a-systick", .data = mt7620_freq_scaling},
|
||||
+ {},
|
||||
+};
|
||||
+
|
||||
static int __init ralink_systick_init(struct device_node *np)
|
||||
{
|
||||
- int ret;
|
||||
+ const struct of_device_id *match;
|
||||
+ int rating = 200;
|
||||
|
||||
systick.membase = of_iomap(np, 0);
|
||||
if (!systick.membase)
|
||||
return -ENXIO;
|
||||
|
||||
- systick.dev.name = np->name;
|
||||
- clockevents_calc_mult_shift(&systick.dev, SYSTICK_FREQ, 60);
|
||||
- systick.dev.max_delta_ns = clockevent_delta2ns(0x7fff, &systick.dev);
|
||||
- systick.dev.max_delta_ticks = 0x7fff;
|
||||
- systick.dev.min_delta_ns = clockevent_delta2ns(0x3, &systick.dev);
|
||||
- systick.dev.min_delta_ticks = 0x3;
|
||||
+ match = of_match_node(systick_match, np);
|
||||
+ if (match) {
|
||||
+ systick_freq_scaling = match->data;
|
||||
+ /*
|
||||
+ * cevt-r4k uses 300, make sure systick
|
||||
+ * gets used if available
|
||||
+ */
|
||||
+ rating = 310;
|
||||
+ }
|
||||
+
|
||||
+ /* enable counter than register clock source */
|
||||
+ iowrite32(CFG_CNT_EN, systick.membase + SYSTICK_CONFIG);
|
||||
+ clocksource_mmio_init(systick.membase + SYSTICK_COUNT, np->name,
|
||||
+ SYSTICK_FREQ, rating, 16, clocksource_mmio_readl_up);
|
||||
+
|
||||
+ /* register clock event */
|
||||
systick.dev.irq = irq_of_parse_and_map(np, 0);
|
||||
if (!systick.dev.irq) {
|
||||
pr_err("%pOFn: request_irq failed", np);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
- ret = clocksource_mmio_init(systick.membase + SYSTICK_COUNT, np->name,
|
||||
- SYSTICK_FREQ, 301, 16,
|
||||
- clocksource_mmio_readl_up);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
-
|
||||
- clockevents_register_device(&systick.dev);
|
||||
+ systick.dev.name = np->name;
|
||||
+ systick.dev.rating = rating;
|
||||
+ systick.dev.cpumask = cpumask_of(0);
|
||||
+ clockevents_config_and_register(&systick.dev, SYSTICK_FREQ, 0x3, 0x7fff);
|
||||
|
||||
pr_info("%pOFn: running - mult: %d, shift: %d\n",
|
||||
np, systick.dev.mult, systick.dev.shift);
|
@ -1,63 +0,0 @@
|
||||
From f15d27f9c90ede4b16eb37f9ae573ef81c2b6996 Mon Sep 17 00:00:00 2001
|
||||
From: David Bauer <mail@david-bauer.net>
|
||||
Date: Thu, 31 Dec 2020 18:49:12 +0100
|
||||
Subject: [PATCH] MIPS: add bootargs-override property
|
||||
|
||||
Add support for the bootargs-override property to the chosen node
|
||||
similar to the one used on ipq806x or mpc85xx.
|
||||
|
||||
This is necessary, as the U-Boot used on some boards, notably the
|
||||
Ubiquiti UniFi 6 Lite, overwrite the bootargs property of the chosen
|
||||
node leading to a kernel panic when loading OpenWrt.
|
||||
|
||||
Signed-off-by: David Bauer <mail@david-bauer.net>
|
||||
---
|
||||
arch/mips/kernel/setup.c | 30 ++++++++++++++++++++++++++++++
|
||||
1 file changed, 30 insertions(+)
|
||||
|
||||
--- a/arch/mips/kernel/setup.c
|
||||
+++ b/arch/mips/kernel/setup.c
|
||||
@@ -547,8 +547,28 @@ static int __init bootcmdline_scan_chose
|
||||
|
||||
#endif /* CONFIG_OF_EARLY_FLATTREE */
|
||||
|
||||
+static int __init bootcmdline_scan_chosen_override(unsigned long node, const char *uname,
|
||||
+ int depth, void *data)
|
||||
+{
|
||||
+ bool *dt_bootargs = data;
|
||||
+ const char *p;
|
||||
+ int l;
|
||||
+
|
||||
+ if (depth != 1 || !data || strcmp(uname, "chosen") != 0)
|
||||
+ return 0;
|
||||
+
|
||||
+ p = of_get_flat_dt_prop(node, "bootargs-override", &l);
|
||||
+ if (p != NULL && l > 0) {
|
||||
+ strlcpy(boot_command_line, p, COMMAND_LINE_SIZE);
|
||||
+ *dt_bootargs = true;
|
||||
+ }
|
||||
+
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
static void __init bootcmdline_init(void)
|
||||
{
|
||||
+ bool dt_bootargs_override = false;
|
||||
bool dt_bootargs = false;
|
||||
|
||||
/*
|
||||
@@ -562,6 +582,14 @@ static void __init bootcmdline_init(void
|
||||
}
|
||||
|
||||
/*
|
||||
+ * If bootargs-override in the chosen node is set, use this as the
|
||||
+ * command line
|
||||
+ */
|
||||
+ of_scan_flat_dt(bootcmdline_scan_chosen_override, &dt_bootargs_override);
|
||||
+ if (dt_bootargs_override)
|
||||
+ return;
|
||||
+
|
||||
+ /*
|
||||
* If the user specified a built-in command line &
|
||||
* MIPS_CMDLINE_BUILTIN_EXTEND, then the built-in command line is
|
||||
* prepended to arguments from the bootloader or DT so we'll copy them
|
@ -1,28 +0,0 @@
|
||||
From 5ede027f6c4a57ed25da872420508b7f1168b36b Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Mon, 7 Dec 2015 17:15:32 +0100
|
||||
Subject: [PATCH 13/53] owrt: hack: fix mt7688 cache issue
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
arch/mips/kernel/setup.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/arch/mips/kernel/setup.c
|
||||
+++ b/arch/mips/kernel/setup.c
|
||||
@@ -689,7 +689,6 @@ static void __init arch_mem_init(char **
|
||||
mips_reserve_vmcore();
|
||||
|
||||
mips_parse_crashkernel();
|
||||
- device_tree_init();
|
||||
|
||||
/*
|
||||
* In order to reduce the possibility of kernel panic when failed to
|
||||
@@ -806,6 +805,7 @@ void __init setup_arch(char **cmdline_p)
|
||||
|
||||
cpu_cache_init();
|
||||
paging_init();
|
||||
+ device_tree_init();
|
||||
|
||||
memblock_dump_all();
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
From 9e6ce539092a1dd605a20bf73c655a9de58d8641 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Mon, 7 Dec 2015 17:18:05 +0100
|
||||
Subject: [PATCH 15/53] arch: mips: do not select illegal access driver by
|
||||
default
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
arch/mips/ralink/Kconfig | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/arch/mips/ralink/Kconfig
|
||||
+++ b/arch/mips/ralink/Kconfig
|
||||
@@ -14,9 +14,9 @@ config CLKEVT_RT3352
|
||||
select CEVT_SYSTICK_QUIRK
|
||||
|
||||
config RALINK_ILL_ACC
|
||||
- bool
|
||||
+ bool "illegal access irq"
|
||||
depends on SOC_RT305X
|
||||
- default y
|
||||
+ default n
|
||||
|
||||
config IRQ_INTC
|
||||
bool
|
@ -1,74 +0,0 @@
|
||||
From 6decd1aad15f56b169217789630a0098b496de0e Mon Sep 17 00:00:00 2001
|
||||
From: Ilya Lipnitskiy <ilya.lipnitskiy@gmail.com>
|
||||
Date: Wed, 7 Apr 2021 13:07:38 -0700
|
||||
Subject: [PATCH] MIPS: add support for buggy MT7621S core detection
|
||||
|
||||
Most MT7621 SoCs have 2 cores, which is detected and supported properly
|
||||
by CPS.
|
||||
|
||||
Unfortunately, MT7621 SoC has a less common S variant with only one core.
|
||||
On MT7621S, GCR_CONFIG still reports 2 cores, which leads to hangs when
|
||||
starting SMP. CPULAUNCH registers can be used in that case to detect the
|
||||
absence of the second core and override the GCR_CONFIG PCORES field.
|
||||
|
||||
Rework a long-standing OpenWrt patch to override the value of
|
||||
mips_cps_numcores on single-core MT7621 systems.
|
||||
|
||||
Tested on a dual-core MT7621 device (Ubiquiti ER-X) and a single-core
|
||||
MT7621 device (Netgear R6220).
|
||||
|
||||
Original 4.14 OpenWrt patch:
|
||||
Link: https://git.openwrt.org/?p=openwrt/openwrt.git;a=commitdiff;h=4cdbc90a376dd0555201c1434a2081e055e9ceb7
|
||||
Current 5.10 OpenWrt patch:
|
||||
Link: https://git.openwrt.org/?p=openwrt/openwrt.git;a=blob;f=target/linux/ramips/patches-5.10/320-mt7621-core-detect-hack.patch;h=c63f0f4c1ec742e24d8480e80553863744b58f6a;hb=10267e17299806f9885d086147878f6c492cb904
|
||||
|
||||
Suggested-by: Felix Fietkau <nbd@nbd.name>
|
||||
Signed-off-by: Ilya Lipnitskiy <ilya.lipnitskiy@gmail.com>
|
||||
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
|
||||
---
|
||||
arch/mips/include/asm/mips-cps.h | 23 ++++++++++++++++++++++-
|
||||
1 file changed, 22 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/arch/mips/include/asm/mips-cps.h
|
||||
+++ b/arch/mips/include/asm/mips-cps.h
|
||||
@@ -10,6 +10,8 @@
|
||||
#include <linux/io.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
+#include <asm/mips-boards/launch.h>
|
||||
+
|
||||
extern unsigned long __cps_access_bad_size(void)
|
||||
__compiletime_error("Bad size for CPS accessor");
|
||||
|
||||
@@ -165,11 +167,30 @@ static inline uint64_t mips_cps_cluster_
|
||||
*/
|
||||
static inline unsigned int mips_cps_numcores(unsigned int cluster)
|
||||
{
|
||||
+ unsigned int ncores;
|
||||
+
|
||||
if (!mips_cm_present())
|
||||
return 0;
|
||||
|
||||
/* Add one before masking to handle 0xff indicating no cores */
|
||||
- return (mips_cps_cluster_config(cluster) + 1) & CM_GCR_CONFIG_PCORES;
|
||||
+ ncores = (mips_cps_cluster_config(cluster) + 1) & CM_GCR_CONFIG_PCORES;
|
||||
+
|
||||
+ if (IS_ENABLED(CONFIG_SOC_MT7621)) {
|
||||
+ struct cpulaunch *launch;
|
||||
+
|
||||
+ /*
|
||||
+ * Ralink MT7621S SoC is single core, but the GCR_CONFIG method
|
||||
+ * always reports 2 cores. Check the second core's LAUNCH_FREADY
|
||||
+ * flag to detect if the second core is missing. This method
|
||||
+ * only works before the core has been started.
|
||||
+ */
|
||||
+ launch = (struct cpulaunch *)CKSEG0ADDR(CPULAUNCH);
|
||||
+ launch += 2; /* MT7621 has 2 VPEs per core */
|
||||
+ if (!(launch->flags & LAUNCH_FREADY))
|
||||
+ ncores = 1;
|
||||
+ }
|
||||
+
|
||||
+ return ncores;
|
||||
}
|
||||
|
||||
/**
|
@ -1,15 +0,0 @@
|
||||
--- a/arch/mips/ralink/irq-gic.c
|
||||
+++ b/arch/mips/ralink/irq-gic.c
|
||||
@@ -13,6 +13,12 @@
|
||||
|
||||
int get_c0_perfcount_int(void)
|
||||
{
|
||||
+ /*
|
||||
+ * Performance counter events are routed through GIC.
|
||||
+ * Prevent them from firing on CPU IRQ7 as well
|
||||
+ */
|
||||
+ clear_c0_status(IE_SW0 << 7);
|
||||
+
|
||||
return gic_get_c0_perfcount_int();
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(get_c0_perfcount_int);
|
@ -1,20 +0,0 @@
|
||||
From ee9081b2726a5ca8cde5497afdc5425e21ff8f8b Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Mon, 15 Jul 2013 00:39:21 +0200
|
||||
Subject: [PATCH 37/53] mtd: cfi cmdset 0002 force word write
|
||||
|
||||
---
|
||||
drivers/mtd/chips/cfi_cmdset_0002.c | 9 +++++++--
|
||||
1 file changed, 7 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
|
||||
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
|
||||
@@ -40,7 +40,7 @@
|
||||
#include <linux/mtd/xip.h>
|
||||
|
||||
#define AMD_BOOTLOC_BUG
|
||||
-#define FORCE_WORD_WRITE 0
|
||||
+#define FORCE_WORD_WRITE 1
|
||||
|
||||
#define MAX_RETRIES 3
|
||||
|
@ -1,75 +0,0 @@
|
||||
From 52d14545d2fc276b1bf9ccf48d4612fab6edfb6a Mon Sep 17 00:00:00 2001
|
||||
From: David Bauer <mail@david-bauer.net>
|
||||
Date: Thu, 6 May 2021 17:49:55 +0200
|
||||
Subject: [PATCH] mtd: spi-nor: Add support for BoHong bh25q128as
|
||||
|
||||
Add MTD support for the BoHong bh25q128as SPI NOR chip.
|
||||
The chip has 16MB of total capacity, divided into a total of 256
|
||||
sectors, each 64KB sized. The chip also supports 4KB sectors.
|
||||
Additionally, it supports dual and quad read modes.
|
||||
|
||||
Functionality was verified on an Tenbay WR1800K / MTK MT7621 board.
|
||||
|
||||
Signed-off-by: David Bauer <mail@david-bauer.net>
|
||||
---
|
||||
drivers/mtd/spi-nor/Makefile | 1 +
|
||||
drivers/mtd/spi-nor/bohong.c | 21 +++++++++++++++++++++
|
||||
drivers/mtd/spi-nor/core.c | 1 +
|
||||
drivers/mtd/spi-nor/core.h | 1 +
|
||||
4 files changed, 24 insertions(+)
|
||||
create mode 100644 drivers/mtd/spi-nor/bohong.c
|
||||
|
||||
--- a/drivers/mtd/spi-nor/Makefile
|
||||
+++ b/drivers/mtd/spi-nor/Makefile
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
spi-nor-objs := core.o sfdp.o swp.o otp.o sysfs.o
|
||||
spi-nor-objs += atmel.o
|
||||
+spi-nor-objs += bohong.o
|
||||
spi-nor-objs += catalyst.o
|
||||
spi-nor-objs += eon.o
|
||||
spi-nor-objs += esmt.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/mtd/spi-nor/bohong.c
|
||||
@@ -0,0 +1,21 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+/*
|
||||
+ * Copyright (C) 2005, Intec Automation Inc.
|
||||
+ * Copyright (C) 2014, Freescale Semiconductor, Inc.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/mtd/spi-nor.h>
|
||||
+
|
||||
+#include "core.h"
|
||||
+
|
||||
+static const struct flash_info bohong_parts[] = {
|
||||
+ /* BoHong Microelectronics */
|
||||
+ { "bh25q128as", INFO(0x684018, 0, 64 * 1024, 256,
|
||||
+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
|
||||
+};
|
||||
+
|
||||
+const struct spi_nor_manufacturer spi_nor_bohong = {
|
||||
+ .name = "bohong",
|
||||
+ .parts = bohong_parts,
|
||||
+ .nparts = ARRAY_SIZE(bohong_parts),
|
||||
+};
|
||||
--- a/drivers/mtd/spi-nor/core.c
|
||||
+++ b/drivers/mtd/spi-nor/core.c
|
||||
@@ -1844,6 +1844,7 @@ int spi_nor_sr2_bit7_quad_enable(struct
|
||||
|
||||
static const struct spi_nor_manufacturer *manufacturers[] = {
|
||||
&spi_nor_atmel,
|
||||
+ &spi_nor_bohong,
|
||||
&spi_nor_catalyst,
|
||||
&spi_nor_eon,
|
||||
&spi_nor_esmt,
|
||||
--- a/drivers/mtd/spi-nor/core.h
|
||||
+++ b/drivers/mtd/spi-nor/core.h
|
||||
@@ -473,6 +473,7 @@ struct sfdp {
|
||||
|
||||
/* Manufacturer drivers. */
|
||||
extern const struct spi_nor_manufacturer spi_nor_atmel;
|
||||
+extern const struct spi_nor_manufacturer spi_nor_bohong;
|
||||
extern const struct spi_nor_manufacturer spi_nor_catalyst;
|
||||
extern const struct spi_nor_manufacturer spi_nor_eon;
|
||||
extern const struct spi_nor_manufacturer spi_nor_esmt;
|
@ -1,47 +0,0 @@
|
||||
From e84e2430ee0e483842b4ff013ae8a6e7e2fa2734 Mon Sep 17 00:00:00 2001
|
||||
From: Weijie Gao <weijie.gao@mediatek.com>
|
||||
Date: Wed, 1 Apr 2020 02:07:58 +0800
|
||||
Subject: [PATCH 1/2] mtd: rawnand: add driver support for MT7621 nand
|
||||
flash controller
|
||||
|
||||
This patch adds NAND flash controller driver for MediaTek MT7621 SoC.
|
||||
|
||||
The NAND flash controller is similar with controllers described in
|
||||
mtk_nand.c, except that the controller from MT7621 doesn't support DMA
|
||||
transmission, and some registers' offset and fields are different.
|
||||
|
||||
Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
|
||||
---
|
||||
drivers/mtd/nand/raw/Kconfig | 8 +
|
||||
drivers/mtd/nand/raw/Makefile | 1 +
|
||||
drivers/mtd/nand/raw/mt7621_nand.c | 1348 ++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 1357 insertions(+)
|
||||
create mode 100644 drivers/mtd/nand/raw/mt7621_nand.c
|
||||
|
||||
--- a/drivers/mtd/nand/raw/Kconfig
|
||||
+++ b/drivers/mtd/nand/raw/Kconfig
|
||||
@@ -358,6 +358,14 @@ config MTD_NAND_QCOM
|
||||
Enables support for NAND flash chips on SoCs containing the EBI2 NAND
|
||||
controller. This controller is found on IPQ806x SoC.
|
||||
|
||||
+config MTD_NAND_MT7621
|
||||
+ tristate "MT7621 NAND controller"
|
||||
+ depends on SOC_MT7621 || COMPILE_TEST
|
||||
+ depends on HAS_IOMEM
|
||||
+ help
|
||||
+ Enables support for NAND controller on MT7621 SoC.
|
||||
+ This driver uses PIO mode for data transmission instead of DMA mode.
|
||||
+
|
||||
config MTD_NAND_MTK
|
||||
tristate "MTK NAND controller"
|
||||
depends on ARCH_MEDIATEK || COMPILE_TEST
|
||||
--- a/drivers/mtd/nand/raw/Makefile
|
||||
+++ b/drivers/mtd/nand/raw/Makefile
|
||||
@@ -48,6 +48,7 @@ obj-$(CONFIG_MTD_NAND_SUNXI) += sunxi_n
|
||||
obj-$(CONFIG_MTD_NAND_HISI504) += hisi504_nand.o
|
||||
obj-$(CONFIG_MTD_NAND_BRCMNAND) += brcmnand/
|
||||
obj-$(CONFIG_MTD_NAND_QCOM) += qcom_nandc.o
|
||||
+obj-$(CONFIG_MTD_NAND_MT7621) += mt7621_nand.o
|
||||
obj-$(CONFIG_MTD_NAND_MTK) += mtk_ecc.o mtk_nand.o
|
||||
obj-$(CONFIG_MTD_NAND_MXIC) += mxic_nand.o
|
||||
obj-$(CONFIG_MTD_NAND_TEGRA) += tegra_nand.o
|
@ -1,85 +0,0 @@
|
||||
From 3d5f4da8296b23eb3abf8b13122b0d06a215e79c Mon Sep 17 00:00:00 2001
|
||||
From: Weijie Gao <weijie.gao@mediatek.com>
|
||||
Date: Wed, 1 Apr 2020 02:07:59 +0800
|
||||
Subject: [PATCH 2/2] dt-bindings: add documentation for mt7621-nand driver
|
||||
|
||||
This patch adds documentation for MediaTek MT7621 NAND flash controller
|
||||
driver.
|
||||
|
||||
Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
|
||||
---
|
||||
.../bindings/mtd/mediatek,mt7621-nfc.yaml | 68 ++++++++++++++++++++++
|
||||
1 file changed, 68 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/mtd/mediatek,mt7621-nfc.yaml
|
||||
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/mtd/mediatek,mt7621-nfc.yaml
|
||||
@@ -0,0 +1,68 @@
|
||||
+# SPDX-License-Identifier: GPL-2.0
|
||||
+%YAML 1.2
|
||||
+---
|
||||
+$id: http://devicetree.org/schemas/mtd/mediatek,mt7621-nfc.yaml#
|
||||
+$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
+
|
||||
+title: MediaTek MT7621 SoC NAND Flash Controller (NFC) DT binding
|
||||
+
|
||||
+maintainers:
|
||||
+ - Weijie Gao <weijie.gao@mediatek.com>
|
||||
+
|
||||
+description: |
|
||||
+ This driver uses a single node to describe both NAND Flash controller
|
||||
+ interface (NFI) and ECC engine for MT7621 SoC.
|
||||
+ MT7621 supports only one chip select.
|
||||
+
|
||||
+properties:
|
||||
+ "#address-cells": false
|
||||
+ "#size-cells": false
|
||||
+
|
||||
+ compatible:
|
||||
+ enum:
|
||||
+ - mediatek,mt7621-nfc
|
||||
+
|
||||
+ reg:
|
||||
+ items:
|
||||
+ - description: Register base of NFI core
|
||||
+ - description: Register base of ECC engine
|
||||
+
|
||||
+ reg-names:
|
||||
+ items:
|
||||
+ - const: nfi
|
||||
+ - const: ecc
|
||||
+
|
||||
+ clocks:
|
||||
+ items:
|
||||
+ - description: Source clock for NFI core, fixed 125MHz
|
||||
+
|
||||
+ clock-names:
|
||||
+ items:
|
||||
+ - const: nfi_clk
|
||||
+
|
||||
+required:
|
||||
+ - compatible
|
||||
+ - reg
|
||||
+ - reg-names
|
||||
+ - clocks
|
||||
+ - clock-names
|
||||
+
|
||||
+examples:
|
||||
+ - |
|
||||
+ nficlock: nficlock {
|
||||
+ #clock-cells = <0>;
|
||||
+ compatible = "fixed-clock";
|
||||
+
|
||||
+ clock-frequency = <125000000>;
|
||||
+ };
|
||||
+
|
||||
+ nand@1e003000 {
|
||||
+ compatible = "mediatek,mt7621-nfc";
|
||||
+
|
||||
+ reg = <0x1e003000 0x800
|
||||
+ 0x1e003800 0x800>;
|
||||
+ reg-names = "nfi", "ecc";
|
||||
+
|
||||
+ clocks = <&nficlock>;
|
||||
+ clock-names = "nfi_clk";
|
||||
+ };
|
@ -1,34 +0,0 @@
|
||||
From bd0f89de5476ca25e73fae829ba3e1dafae1d90d Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= <opensource@vdorst.com>
|
||||
Date: Fri, 21 Jun 2019 10:04:05 +0200
|
||||
Subject: [PATCH] net: ethernet: mediatek: support net-labels
|
||||
|
||||
With this patch, device name can be set within dts file in the same way as dsa
|
||||
port can.
|
||||
Add: label = "wan"; to GMAC node.
|
||||
|
||||
Signed-off-by: René van Dorst <opensource@vdorst.com>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
@@ -4558,6 +4558,7 @@ static const struct net_device_ops mtk_n
|
||||
|
||||
static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
|
||||
{
|
||||
+ const char *name = of_get_property(np, "label", NULL);
|
||||
const __be32 *_id = of_get_property(np, "reg", NULL);
|
||||
phy_interface_t phy_mode;
|
||||
struct phylink *phylink;
|
||||
@@ -4729,6 +4730,9 @@ static int mtk_add_mac(struct mtk_eth *e
|
||||
register_netdevice_notifier(&mac->device_notifier);
|
||||
}
|
||||
|
||||
+ if (name)
|
||||
+ strlcpy(eth->netdev[id]->name, name, IFNAMSIZ);
|
||||
+
|
||||
return 0;
|
||||
|
||||
free_netdev:
|
@ -1,118 +0,0 @@
|
||||
From ffbb1b37a3e1ce1a5c574a6bd4f5aede8bc468ac Mon Sep 17 00:00:00 2001
|
||||
From: Ilya Lipnitskiy <ilya.lipnitskiy@gmail.com>
|
||||
Date: Sat, 27 Feb 2021 20:20:07 -0800
|
||||
Subject: [PATCH] Revert "net: phy: simplify phy_link_change arguments"
|
||||
|
||||
This reverts commit a307593a644443db12888f45eed0dafb5869e2cc.
|
||||
|
||||
This brings back the do_carrier flags used by the (hacky) next patch,
|
||||
still required by target/linux/ramips/files/drivers/net/ethernet/ralink/mdio.c
|
||||
---
|
||||
drivers/net/phy/phy.c | 12 ++++++------
|
||||
drivers/net/phy/phy_device.c | 12 +++++++-----
|
||||
drivers/net/phy/phylink.c | 3 ++-
|
||||
include/linux/phy.h | 2 +-
|
||||
4 files changed, 16 insertions(+), 13 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/phy.c
|
||||
+++ b/drivers/net/phy/phy.c
|
||||
@@ -71,13 +71,13 @@ static void phy_process_state_change(str
|
||||
|
||||
static void phy_link_up(struct phy_device *phydev)
|
||||
{
|
||||
- phydev->phy_link_change(phydev, true);
|
||||
+ phydev->phy_link_change(phydev, true, true);
|
||||
phy_led_trigger_change_speed(phydev);
|
||||
}
|
||||
|
||||
-static void phy_link_down(struct phy_device *phydev)
|
||||
+static void phy_link_down(struct phy_device *phydev, bool do_carrier)
|
||||
{
|
||||
- phydev->phy_link_change(phydev, false);
|
||||
+ phydev->phy_link_change(phydev, false, do_carrier);
|
||||
phy_led_trigger_change_speed(phydev);
|
||||
}
|
||||
|
||||
@@ -591,7 +591,7 @@ int phy_start_cable_test(struct phy_devi
|
||||
goto out;
|
||||
|
||||
/* Mark the carrier down until the test is complete */
|
||||
- phy_link_down(phydev);
|
||||
+ phy_link_down(phydev, true);
|
||||
|
||||
netif_testing_on(dev);
|
||||
err = phydev->drv->cable_test_start(phydev);
|
||||
@@ -662,7 +662,7 @@ int phy_start_cable_test_tdr(struct phy_
|
||||
goto out;
|
||||
|
||||
/* Mark the carrier down until the test is complete */
|
||||
- phy_link_down(phydev);
|
||||
+ phy_link_down(phydev, true);
|
||||
|
||||
netif_testing_on(dev);
|
||||
err = phydev->drv->cable_test_tdr_start(phydev, config);
|
||||
@@ -734,7 +734,7 @@ static int phy_check_link_status(struct
|
||||
phy_link_up(phydev);
|
||||
} else if (!phydev->link && phydev->state != PHY_NOLINK) {
|
||||
phydev->state = PHY_NOLINK;
|
||||
- phy_link_down(phydev);
|
||||
+ phy_link_down(phydev, true);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -1220,7 +1220,7 @@ void phy_state_machine(struct work_struc
|
||||
case PHY_HALTED:
|
||||
if (phydev->link) {
|
||||
phydev->link = 0;
|
||||
- phy_link_down(phydev);
|
||||
+ phy_link_down(phydev, true);
|
||||
}
|
||||
do_suspend = true;
|
||||
break;
|
||||
--- a/drivers/net/phy/phy_device.c
|
||||
+++ b/drivers/net/phy/phy_device.c
|
||||
@@ -1035,14 +1035,16 @@ struct phy_device *phy_find_first(struct
|
||||
}
|
||||
EXPORT_SYMBOL(phy_find_first);
|
||||
|
||||
-static void phy_link_change(struct phy_device *phydev, bool up)
|
||||
+static void phy_link_change(struct phy_device *phydev, bool up, bool do_carrier)
|
||||
{
|
||||
struct net_device *netdev = phydev->attached_dev;
|
||||
|
||||
- if (up)
|
||||
- netif_carrier_on(netdev);
|
||||
- else
|
||||
- netif_carrier_off(netdev);
|
||||
+ if (do_carrier) {
|
||||
+ if (up)
|
||||
+ netif_carrier_on(netdev);
|
||||
+ else
|
||||
+ netif_carrier_off(netdev);
|
||||
+ }
|
||||
phydev->adjust_link(netdev);
|
||||
if (phydev->mii_ts && phydev->mii_ts->link_state)
|
||||
phydev->mii_ts->link_state(phydev->mii_ts, phydev);
|
||||
--- a/drivers/net/phy/phylink.c
|
||||
+++ b/drivers/net/phy/phylink.c
|
||||
@@ -1373,7 +1373,8 @@ void phylink_destroy(struct phylink *pl)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(phylink_destroy);
|
||||
|
||||
-static void phylink_phy_change(struct phy_device *phydev, bool up)
|
||||
+static void phylink_phy_change(struct phy_device *phydev, bool up,
|
||||
+ bool do_carrier)
|
||||
{
|
||||
struct phylink *pl = phydev->phylink;
|
||||
bool tx_pause, rx_pause;
|
||||
--- a/include/linux/phy.h
|
||||
+++ b/include/linux/phy.h
|
||||
@@ -716,7 +716,7 @@ struct phy_device {
|
||||
u8 mdix;
|
||||
u8 mdix_ctrl;
|
||||
|
||||
- void (*phy_link_change)(struct phy_device *phydev, bool up);
|
||||
+ void (*phy_link_change)(struct phy_device *, bool up, bool do_carrier);
|
||||
void (*adjust_link)(struct net_device *dev);
|
||||
|
||||
#if IS_ENABLED(CONFIG_MACSEC)
|
@ -1,47 +0,0 @@
|
||||
From 0b6eb1e68290243d439ee330ea8d0b239a5aec69 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Sun, 27 Jul 2014 09:38:50 +0100
|
||||
Subject: [PATCH 34/53] NET: multi phy support
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
drivers/net/phy/phy.c | 9 ++++++---
|
||||
include/linux/phy.h | 1 +
|
||||
2 files changed, 7 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/phy.c
|
||||
+++ b/drivers/net/phy/phy.c
|
||||
@@ -734,7 +734,10 @@ static int phy_check_link_status(struct
|
||||
phy_link_up(phydev);
|
||||
} else if (!phydev->link && phydev->state != PHY_NOLINK) {
|
||||
phydev->state = PHY_NOLINK;
|
||||
- phy_link_down(phydev, true);
|
||||
+ if (!phydev->no_auto_carrier_off)
|
||||
+ phy_link_down(phydev, true);
|
||||
+ else
|
||||
+ phy_link_down(phydev, false);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -1220,7 +1223,10 @@ void phy_state_machine(struct work_struc
|
||||
case PHY_HALTED:
|
||||
if (phydev->link) {
|
||||
phydev->link = 0;
|
||||
- phy_link_down(phydev, true);
|
||||
+ if (!phydev->no_auto_carrier_off)
|
||||
+ phy_link_down(phydev, true);
|
||||
+ else
|
||||
+ phy_link_down(phydev, false);
|
||||
}
|
||||
do_suspend = true;
|
||||
break;
|
||||
--- a/include/linux/phy.h
|
||||
+++ b/include/linux/phy.h
|
||||
@@ -630,6 +630,7 @@ struct phy_device {
|
||||
unsigned downshifted_rate:1;
|
||||
unsigned is_on_sfp_module:1;
|
||||
unsigned mac_managed_pm:1;
|
||||
+ unsigned no_auto_carrier_off:1;
|
||||
|
||||
unsigned autoneg:1;
|
||||
/* The most recently read link state */
|
@ -1,59 +0,0 @@
|
||||
From d410e5478c622c01fcf31427533df5f433df9146 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Sun, 28 Jul 2013 19:45:30 +0200
|
||||
Subject: [PATCH 26/53] DT: Add documentation for gpio-ralink
|
||||
|
||||
Describe gpio-ralink binding.
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
Cc: linux-mips@linux-mips.org
|
||||
Cc: devicetree@vger.kernel.org
|
||||
Cc: linux-gpio@vger.kernel.org
|
||||
---
|
||||
.../devicetree/bindings/gpio/gpio-ralink.txt | 40 ++++++++++++++++++++
|
||||
1 file changed, 40 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/gpio/gpio-ralink.txt
|
||||
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/gpio/gpio-ralink.txt
|
||||
@@ -0,0 +1,40 @@
|
||||
+Ralink SoC GPIO controller bindings
|
||||
+
|
||||
+Required properties:
|
||||
+- compatible:
|
||||
+ - "ralink,rt2880-gpio" for Ralink controllers
|
||||
+- #gpio-cells : Should be two.
|
||||
+ - first cell is the pin number
|
||||
+ - second cell is used to specify optional parameters (unused)
|
||||
+- gpio-controller : Marks the device node as a GPIO controller
|
||||
+- reg : Physical base address and length of the controller's registers
|
||||
+- interrupt-parent: phandle to the INTC device node
|
||||
+- interrupts : Specify the INTC interrupt number
|
||||
+- ngpios : Specify the number of GPIOs
|
||||
+- ralink,register-map : The register layout depends on the GPIO bank and actual
|
||||
+ SoC type. Register offsets need to be in this order.
|
||||
+ [ INT, EDGE, RENA, FENA, DATA, DIR, POL, SET, RESET, TOGGLE ]
|
||||
+
|
||||
+Optional properties:
|
||||
+- ralink,gpio-base : Specify the GPIO chips base number
|
||||
+
|
||||
+Example:
|
||||
+
|
||||
+ gpio0: gpio@600 {
|
||||
+ compatible = "ralink,rt5350-gpio", "ralink,rt2880-gpio";
|
||||
+
|
||||
+ #gpio-cells = <2>;
|
||||
+ gpio-controller;
|
||||
+
|
||||
+ reg = <0x600 0x34>;
|
||||
+
|
||||
+ interrupt-parent = <&intc>;
|
||||
+ interrupts = <6>;
|
||||
+
|
||||
+ ngpios = <24>;
|
||||
+ ralink,gpio-base = <0>;
|
||||
+ ralink,register-map = [ 00 04 08 0c
|
||||
+ 20 24 28 2c
|
||||
+ 30 34 ];
|
||||
+
|
||||
+ };
|
@ -1,416 +0,0 @@
|
||||
From 69fdd2c4f937796b934e89c33acde9d082e27bfd Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Mon, 4 Aug 2014 20:36:29 +0200
|
||||
Subject: [PATCH 27/53] GPIO: MIPS: ralink: add gpio driver for ralink SoC
|
||||
|
||||
Add gpio driver for Ralink SoC. This driver makes the gpio core on
|
||||
RT2880, RT305x, rt3352, rt3662, rt3883, rt5350 and mt7620 work.
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
Cc: linux-mips@linux-mips.org
|
||||
Cc: linux-gpio@vger.kernel.org
|
||||
---
|
||||
arch/mips/include/asm/mach-ralink/gpio.h | 24 ++
|
||||
drivers/gpio/Kconfig | 6 +
|
||||
drivers/gpio/Makefile | 1 +
|
||||
drivers/gpio/gpio-ralink.c | 355 ++++++++++++++++++++++++++++++
|
||||
4 files changed, 386 insertions(+)
|
||||
create mode 100644 arch/mips/include/asm/mach-ralink/gpio.h
|
||||
create mode 100644 drivers/gpio/gpio-ralink.c
|
||||
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/include/asm/mach-ralink/gpio.h
|
||||
@@ -0,0 +1,24 @@
|
||||
+/*
|
||||
+ * Ralink SoC GPIO API support
|
||||
+ *
|
||||
+ * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
|
||||
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify it
|
||||
+ * under the terms of the GNU General Public License version 2 as published
|
||||
+ * by the Free Software Foundation.
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#ifndef __ASM_MACH_RALINK_GPIO_H
|
||||
+#define __ASM_MACH_RALINK_GPIO_H
|
||||
+
|
||||
+#define ARCH_NR_GPIOS 128
|
||||
+#include <asm-generic/gpio.h>
|
||||
+
|
||||
+#define gpio_get_value __gpio_get_value
|
||||
+#define gpio_set_value __gpio_set_value
|
||||
+#define gpio_cansleep __gpio_cansleep
|
||||
+#define gpio_to_irq __gpio_to_irq
|
||||
+
|
||||
+#endif /* __ASM_MACH_RALINK_GPIO_H */
|
||||
--- a/drivers/gpio/Kconfig
|
||||
+++ b/drivers/gpio/Kconfig
|
||||
@@ -569,6 +569,12 @@ config GPIO_SNPS_CREG
|
||||
where only several fields in register belong to GPIO lines and
|
||||
each GPIO line owns a field with different length and on/off value.
|
||||
|
||||
+config GPIO_RALINK
|
||||
+ bool "Ralink GPIO Support"
|
||||
+ depends on RALINK
|
||||
+ help
|
||||
+ Say yes here to support the Ralink SoC GPIO device
|
||||
+
|
||||
config GPIO_SPEAR_SPICS
|
||||
bool "ST SPEAr13xx SPI Chip Select as GPIO support"
|
||||
depends on PLAT_SPEAR
|
||||
--- a/drivers/gpio/Makefile
|
||||
+++ b/drivers/gpio/Makefile
|
||||
@@ -121,6 +121,7 @@ obj-$(CONFIG_GPIO_PISOSR) += gpio-pisos
|
||||
obj-$(CONFIG_GPIO_PL061) += gpio-pl061.o
|
||||
obj-$(CONFIG_GPIO_PMIC_EIC_SPRD) += gpio-pmic-eic-sprd.o
|
||||
obj-$(CONFIG_GPIO_PXA) += gpio-pxa.o
|
||||
+obj-$(CONFIG_GPIO_RALINK) += gpio-ralink.o
|
||||
obj-$(CONFIG_GPIO_RASPBERRYPI_EXP) += gpio-raspberrypi-exp.o
|
||||
obj-$(CONFIG_GPIO_RC5T583) += gpio-rc5t583.o
|
||||
obj-$(CONFIG_GPIO_RCAR) += gpio-rcar.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/gpio/gpio-ralink.c
|
||||
@@ -0,0 +1,341 @@
|
||||
+/*
|
||||
+ * This program is free software; you can redistribute it and/or modify it
|
||||
+ * under the terms of the GNU General Public License version 2 as published
|
||||
+ * by the Free Software Foundation.
|
||||
+ *
|
||||
+ * Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org>
|
||||
+ * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/gpio.h>
|
||||
+#include <linux/spinlock.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/of_irq.h>
|
||||
+#include <linux/irqdomain.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+
|
||||
+enum ralink_gpio_reg {
|
||||
+ GPIO_REG_INT = 0,
|
||||
+ GPIO_REG_EDGE,
|
||||
+ GPIO_REG_RENA,
|
||||
+ GPIO_REG_FENA,
|
||||
+ GPIO_REG_DATA,
|
||||
+ GPIO_REG_DIR,
|
||||
+ GPIO_REG_POL,
|
||||
+ GPIO_REG_SET,
|
||||
+ GPIO_REG_RESET,
|
||||
+ GPIO_REG_TOGGLE,
|
||||
+ GPIO_REG_MAX
|
||||
+};
|
||||
+
|
||||
+struct ralink_gpio_chip {
|
||||
+ struct gpio_chip chip;
|
||||
+ u8 regs[GPIO_REG_MAX];
|
||||
+
|
||||
+ spinlock_t lock;
|
||||
+ void __iomem *membase;
|
||||
+ struct irq_domain *domain;
|
||||
+ int irq;
|
||||
+
|
||||
+ u32 rising;
|
||||
+ u32 falling;
|
||||
+};
|
||||
+
|
||||
+#define MAP_MAX 4
|
||||
+static struct irq_domain *irq_map[MAP_MAX];
|
||||
+static int irq_map_count;
|
||||
+static atomic_t irq_refcount = ATOMIC_INIT(0);
|
||||
+
|
||||
+static inline struct ralink_gpio_chip *to_ralink_gpio(struct gpio_chip *chip)
|
||||
+{
|
||||
+ struct ralink_gpio_chip *rg;
|
||||
+
|
||||
+ rg = container_of(chip, struct ralink_gpio_chip, chip);
|
||||
+
|
||||
+ return rg;
|
||||
+}
|
||||
+
|
||||
+static inline void rt_gpio_w32(struct ralink_gpio_chip *rg, u8 reg, u32 val)
|
||||
+{
|
||||
+ iowrite32(val, rg->membase + rg->regs[reg]);
|
||||
+}
|
||||
+
|
||||
+static inline u32 rt_gpio_r32(struct ralink_gpio_chip *rg, u8 reg)
|
||||
+{
|
||||
+ return ioread32(rg->membase + rg->regs[reg]);
|
||||
+}
|
||||
+
|
||||
+static void ralink_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
|
||||
+{
|
||||
+ struct ralink_gpio_chip *rg = to_ralink_gpio(chip);
|
||||
+
|
||||
+ rt_gpio_w32(rg, (value) ? GPIO_REG_SET : GPIO_REG_RESET, BIT(offset));
|
||||
+}
|
||||
+
|
||||
+static int ralink_gpio_get(struct gpio_chip *chip, unsigned offset)
|
||||
+{
|
||||
+ struct ralink_gpio_chip *rg = to_ralink_gpio(chip);
|
||||
+
|
||||
+ return !!(rt_gpio_r32(rg, GPIO_REG_DATA) & BIT(offset));
|
||||
+}
|
||||
+
|
||||
+static int ralink_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
|
||||
+{
|
||||
+ struct ralink_gpio_chip *rg = to_ralink_gpio(chip);
|
||||
+ unsigned long flags;
|
||||
+ u32 t;
|
||||
+
|
||||
+ spin_lock_irqsave(&rg->lock, flags);
|
||||
+ t = rt_gpio_r32(rg, GPIO_REG_DIR);
|
||||
+ t &= ~BIT(offset);
|
||||
+ rt_gpio_w32(rg, GPIO_REG_DIR, t);
|
||||
+ spin_unlock_irqrestore(&rg->lock, flags);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int ralink_gpio_direction_output(struct gpio_chip *chip,
|
||||
+ unsigned offset, int value)
|
||||
+{
|
||||
+ struct ralink_gpio_chip *rg = to_ralink_gpio(chip);
|
||||
+ unsigned long flags;
|
||||
+ u32 t;
|
||||
+
|
||||
+ spin_lock_irqsave(&rg->lock, flags);
|
||||
+ ralink_gpio_set(chip, offset, value);
|
||||
+ t = rt_gpio_r32(rg, GPIO_REG_DIR);
|
||||
+ t |= BIT(offset);
|
||||
+ rt_gpio_w32(rg, GPIO_REG_DIR, t);
|
||||
+ spin_unlock_irqrestore(&rg->lock, flags);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int ralink_gpio_to_irq(struct gpio_chip *chip, unsigned pin)
|
||||
+{
|
||||
+ struct ralink_gpio_chip *rg = to_ralink_gpio(chip);
|
||||
+
|
||||
+ if (rg->irq < 1)
|
||||
+ return -1;
|
||||
+
|
||||
+ return irq_create_mapping(rg->domain, pin);
|
||||
+}
|
||||
+
|
||||
+static void ralink_gpio_irq_handler(struct irq_desc *desc)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < irq_map_count; i++) {
|
||||
+ struct irq_domain *domain = irq_map[i];
|
||||
+ struct ralink_gpio_chip *rg;
|
||||
+ unsigned long pending;
|
||||
+ int bit;
|
||||
+
|
||||
+ rg = (struct ralink_gpio_chip *) domain->host_data;
|
||||
+ pending = rt_gpio_r32(rg, GPIO_REG_INT);
|
||||
+
|
||||
+ for_each_set_bit(bit, &pending, rg->chip.ngpio) {
|
||||
+ u32 map = irq_find_mapping(domain, bit);
|
||||
+ generic_handle_irq(map);
|
||||
+ rt_gpio_w32(rg, GPIO_REG_INT, BIT(bit));
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void ralink_gpio_irq_unmask(struct irq_data *d)
|
||||
+{
|
||||
+ struct ralink_gpio_chip *rg;
|
||||
+ unsigned long flags;
|
||||
+ u32 rise, fall;
|
||||
+
|
||||
+ rg = (struct ralink_gpio_chip *) d->domain->host_data;
|
||||
+ rise = rt_gpio_r32(rg, GPIO_REG_RENA);
|
||||
+ fall = rt_gpio_r32(rg, GPIO_REG_FENA);
|
||||
+
|
||||
+ spin_lock_irqsave(&rg->lock, flags);
|
||||
+ rt_gpio_w32(rg, GPIO_REG_RENA, rise | (BIT(d->hwirq) & rg->rising));
|
||||
+ rt_gpio_w32(rg, GPIO_REG_FENA, fall | (BIT(d->hwirq) & rg->falling));
|
||||
+ spin_unlock_irqrestore(&rg->lock, flags);
|
||||
+}
|
||||
+
|
||||
+static void ralink_gpio_irq_mask(struct irq_data *d)
|
||||
+{
|
||||
+ struct ralink_gpio_chip *rg;
|
||||
+ unsigned long flags;
|
||||
+ u32 rise, fall;
|
||||
+
|
||||
+ rg = (struct ralink_gpio_chip *) d->domain->host_data;
|
||||
+ rise = rt_gpio_r32(rg, GPIO_REG_RENA);
|
||||
+ fall = rt_gpio_r32(rg, GPIO_REG_FENA);
|
||||
+
|
||||
+ spin_lock_irqsave(&rg->lock, flags);
|
||||
+ rt_gpio_w32(rg, GPIO_REG_FENA, fall & ~BIT(d->hwirq));
|
||||
+ rt_gpio_w32(rg, GPIO_REG_RENA, rise & ~BIT(d->hwirq));
|
||||
+ spin_unlock_irqrestore(&rg->lock, flags);
|
||||
+}
|
||||
+
|
||||
+static int ralink_gpio_irq_type(struct irq_data *d, unsigned int type)
|
||||
+{
|
||||
+ struct ralink_gpio_chip *rg;
|
||||
+ u32 mask = BIT(d->hwirq);
|
||||
+
|
||||
+ rg = (struct ralink_gpio_chip *) d->domain->host_data;
|
||||
+
|
||||
+ if (type == IRQ_TYPE_PROBE) {
|
||||
+ if ((rg->rising | rg->falling) & mask)
|
||||
+ return 0;
|
||||
+
|
||||
+ type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
|
||||
+ }
|
||||
+
|
||||
+ if (type & IRQ_TYPE_EDGE_RISING)
|
||||
+ rg->rising |= mask;
|
||||
+ else
|
||||
+ rg->rising &= ~mask;
|
||||
+
|
||||
+ if (type & IRQ_TYPE_EDGE_FALLING)
|
||||
+ rg->falling |= mask;
|
||||
+ else
|
||||
+ rg->falling &= ~mask;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct irq_chip ralink_gpio_irq_chip = {
|
||||
+ .name = "GPIO",
|
||||
+ .irq_unmask = ralink_gpio_irq_unmask,
|
||||
+ .irq_mask = ralink_gpio_irq_mask,
|
||||
+ .irq_mask_ack = ralink_gpio_irq_mask,
|
||||
+ .irq_set_type = ralink_gpio_irq_type,
|
||||
+};
|
||||
+
|
||||
+static int gpio_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
|
||||
+{
|
||||
+ irq_set_chip_and_handler(irq, &ralink_gpio_irq_chip, handle_level_irq);
|
||||
+ irq_set_handler_data(irq, d);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct irq_domain_ops irq_domain_ops = {
|
||||
+ .xlate = irq_domain_xlate_onecell,
|
||||
+ .map = gpio_map,
|
||||
+};
|
||||
+
|
||||
+static void ralink_gpio_irq_init(struct device_node *np,
|
||||
+ struct ralink_gpio_chip *rg)
|
||||
+{
|
||||
+ if (irq_map_count >= MAP_MAX)
|
||||
+ return;
|
||||
+
|
||||
+ rg->irq = irq_of_parse_and_map(np, 0);
|
||||
+ if (!rg->irq)
|
||||
+ return;
|
||||
+
|
||||
+ rg->domain = irq_domain_add_linear(np, rg->chip.ngpio,
|
||||
+ &irq_domain_ops, rg);
|
||||
+ if (!rg->domain) {
|
||||
+ dev_err(rg->chip.parent, "irq_domain_add_linear failed\n");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ irq_map[irq_map_count++] = rg->domain;
|
||||
+
|
||||
+ rt_gpio_w32(rg, GPIO_REG_RENA, 0x0);
|
||||
+ rt_gpio_w32(rg, GPIO_REG_FENA, 0x0);
|
||||
+
|
||||
+ if (!atomic_read(&irq_refcount))
|
||||
+ irq_set_chained_handler(rg->irq, ralink_gpio_irq_handler);
|
||||
+ atomic_inc(&irq_refcount);
|
||||
+
|
||||
+ dev_info(rg->chip.parent, "registering %d irq handlers\n", rg->chip.ngpio);
|
||||
+}
|
||||
+
|
||||
+static int ralink_gpio_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct device_node *np = pdev->dev.of_node;
|
||||
+ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
+ struct ralink_gpio_chip *rg;
|
||||
+ const __be32 *ngpio, *gpiobase;
|
||||
+
|
||||
+ if (!res) {
|
||||
+ dev_err(&pdev->dev, "failed to find resource\n");
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ rg = devm_kzalloc(&pdev->dev,
|
||||
+ sizeof(struct ralink_gpio_chip), GFP_KERNEL);
|
||||
+ if (!rg)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ rg->membase = devm_ioremap_resource(&pdev->dev, res);
|
||||
+ if (!rg->membase) {
|
||||
+ dev_err(&pdev->dev, "cannot remap I/O memory region\n");
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ if (of_property_read_u8_array(np, "ralink,register-map",
|
||||
+ rg->regs, GPIO_REG_MAX)) {
|
||||
+ dev_err(&pdev->dev, "failed to read register definition\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ ngpio = of_get_property(np, "ngpios", NULL);
|
||||
+ if (!ngpio) {
|
||||
+ dev_err(&pdev->dev, "failed to read number of pins\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ gpiobase = of_get_property(np, "ralink,gpio-base", NULL);
|
||||
+ if (gpiobase)
|
||||
+ rg->chip.base = be32_to_cpu(*gpiobase);
|
||||
+ else
|
||||
+ rg->chip.base = -1;
|
||||
+
|
||||
+ spin_lock_init(&rg->lock);
|
||||
+
|
||||
+ rg->chip.parent = &pdev->dev;
|
||||
+ rg->chip.label = dev_name(&pdev->dev);
|
||||
+ rg->chip.of_node = np;
|
||||
+ rg->chip.ngpio = be32_to_cpu(*ngpio);
|
||||
+ rg->chip.direction_input = ralink_gpio_direction_input;
|
||||
+ rg->chip.direction_output = ralink_gpio_direction_output;
|
||||
+ rg->chip.get = ralink_gpio_get;
|
||||
+ rg->chip.set = ralink_gpio_set;
|
||||
+ rg->chip.request = gpiochip_generic_request;
|
||||
+ rg->chip.to_irq = ralink_gpio_to_irq;
|
||||
+ rg->chip.free = gpiochip_generic_free;
|
||||
+
|
||||
+ /* set polarity to low for all lines */
|
||||
+ rt_gpio_w32(rg, GPIO_REG_POL, 0);
|
||||
+
|
||||
+ dev_info(&pdev->dev, "registering %d gpios\n", rg->chip.ngpio);
|
||||
+
|
||||
+ ralink_gpio_irq_init(np, rg);
|
||||
+
|
||||
+ return gpiochip_add(&rg->chip);
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id ralink_gpio_match[] = {
|
||||
+ { .compatible = "ralink,rt2880-gpio" },
|
||||
+ {},
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, ralink_gpio_match);
|
||||
+
|
||||
+static struct platform_driver ralink_gpio_driver = {
|
||||
+ .probe = ralink_gpio_probe,
|
||||
+ .driver = {
|
||||
+ .name = "rt2880_gpio",
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .of_match_table = ralink_gpio_match,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static int __init ralink_gpio_init(void)
|
||||
+{
|
||||
+ return platform_driver_register(&ralink_gpio_driver);
|
||||
+}
|
||||
+
|
||||
+subsys_initcall(ralink_gpio_init);
|
@ -1,44 +0,0 @@
|
||||
From 57fa7f2f4ef6f78ce1d30509c0d111aa3791b524 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Santos <daniel.santos@pobox.com>
|
||||
Date: Sun, 4 Nov 2018 20:24:32 -0600
|
||||
Subject: gpio-ralink: Add support for GPIO as interrupt-controller
|
||||
|
||||
Signed-off-by: Daniel Santos <daniel.santos@pobox.com>
|
||||
---
|
||||
Documentation/devicetree/bindings/gpio/gpio-ralink.txt | 6 ++++++
|
||||
drivers/gpio/gpio-ralink.c | 2 +-
|
||||
2 files changed, 7 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/Documentation/devicetree/bindings/gpio/gpio-ralink.txt
|
||||
+++ b/Documentation/devicetree/bindings/gpio/gpio-ralink.txt
|
||||
@@ -17,6 +17,9 @@ Required properties:
|
||||
|
||||
Optional properties:
|
||||
- ralink,gpio-base : Specify the GPIO chips base number
|
||||
+- interrupt-controller : marks this as an interrupt controller
|
||||
+- #interrupt-cells : a standard two-cell interrupt flag, see
|
||||
+ interrupt-controller/interrupts.txt
|
||||
|
||||
Example:
|
||||
|
||||
@@ -28,6 +31,9 @@ Example:
|
||||
|
||||
reg = <0x600 0x34>;
|
||||
|
||||
+ interrupt-controller;
|
||||
+ #interrupt-cells = <2>;
|
||||
+
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <6>;
|
||||
|
||||
--- a/drivers/gpio/gpio-ralink.c
|
||||
+++ b/drivers/gpio/gpio-ralink.c
|
||||
@@ -220,7 +220,7 @@ static int gpio_map(struct irq_domain *d
|
||||
}
|
||||
|
||||
static const struct irq_domain_ops irq_domain_ops = {
|
||||
- .xlate = irq_domain_xlate_onecell,
|
||||
+ .xlate = irq_domain_xlate_twocell,
|
||||
.map = gpio_map,
|
||||
};
|
||||
|
@ -1,72 +0,0 @@
|
||||
From: AngeloGioacchino Del Regno
|
||||
<angelogioacchino.delregno@somainline.org>
|
||||
To: linus.walleij@linaro.org
|
||||
Cc: linux-kernel@vger.kernel.org, konrad.dybcio@somainline.org,
|
||||
marijn.suijten@somainline.org, martin.botka@somainline.org,
|
||||
phone-devel@vger.kernel.org, linux-gpio@vger.kernel.org,
|
||||
devicetree@vger.kernel.org, robh+dt@kernel.org,
|
||||
AngeloGioacchino Del Regno
|
||||
<angelogioacchino.delregno@somainline.org>
|
||||
Subject: [PATCH v5 1/2] pinctrl: Add driver for Awinic AW9523/B I2C GPIO
|
||||
Expander
|
||||
Date: Mon, 25 Jan 2021 19:22:18 +0100
|
||||
|
||||
The Awinic AW9523(B) is a multi-function I2C gpio expander in a
|
||||
TQFN-24L package, featuring PWM (max 37mA per pin, or total max
|
||||
power 3.2Watts) for LED driving capability.
|
||||
|
||||
It has two ports with 8 pins per port (for a total of 16 pins),
|
||||
configurable as either PWM with 1/256 stepping or GPIO input/output,
|
||||
1.8V logic input; each GPIO can be configured as input or output
|
||||
independently from each other.
|
||||
|
||||
This IC also has an internal interrupt controller, which is capable
|
||||
of generating an interrupt for each GPIO, depending on the
|
||||
configuration, and will raise an interrupt on the INTN pin to
|
||||
advertise this to an external interrupt controller.
|
||||
|
||||
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
|
||||
---
|
||||
drivers/pinctrl/Kconfig | 17 +
|
||||
drivers/pinctrl/Makefile | 1 +
|
||||
drivers/pinctrl/pinctrl-aw9523.c | 1122 ++++++++++++++++++++++++++++++
|
||||
3 files changed, 1140 insertions(+)
|
||||
create mode 100644 drivers/pinctrl/pinctrl-aw9523.c
|
||||
|
||||
--- a/drivers/pinctrl/Kconfig
|
||||
+++ b/drivers/pinctrl/Kconfig
|
||||
@@ -111,6 +111,24 @@ config PINCTRL_AMD
|
||||
Requires ACPI/FDT device enumeration code to set up a platform
|
||||
device.
|
||||
|
||||
+config PINCTRL_AW9523
|
||||
+ bool "Awinic AW9523/AW9523B I2C GPIO expander pinctrl driver"
|
||||
+ depends on OF && I2C
|
||||
+ select PINMUX
|
||||
+ select PINCONF
|
||||
+ select GENERIC_PINCONF
|
||||
+ select GPIOLIB
|
||||
+ select GPIOLIB_IRQCHIP
|
||||
+ select REGMAP
|
||||
+ select REGMAP_I2C
|
||||
+ help
|
||||
+ The Awinic AW9523/AW9523B is a multi-function I2C GPIO
|
||||
+ expander with PWM functionality. This driver bundles a
|
||||
+ pinctrl driver to select the function muxing and a GPIO
|
||||
+ driver to handle GPIO, when the GPIO function is selected.
|
||||
+
|
||||
+ Say yes to enable pinctrl and GPIO support for the AW9523(B).
|
||||
+
|
||||
config PINCTRL_BM1880
|
||||
bool "Bitmain BM1880 Pinctrl driver"
|
||||
depends on OF && (ARCH_BITMAIN || COMPILE_TEST)
|
||||
--- a/drivers/pinctrl/Makefile
|
||||
+++ b/drivers/pinctrl/Makefile
|
||||
@@ -14,6 +14,7 @@ obj-$(CONFIG_PINCTRL_AXP209) += pinctrl-
|
||||
obj-$(CONFIG_PINCTRL_AT91) += pinctrl-at91.o
|
||||
obj-$(CONFIG_PINCTRL_AT91PIO4) += pinctrl-at91-pio4.o
|
||||
obj-$(CONFIG_PINCTRL_AMD) += pinctrl-amd.o
|
||||
+obj-$(CONFIG_PINCTRL_AW9523) += pinctrl-aw9523.o
|
||||
obj-$(CONFIG_PINCTRL_BM1880) += pinctrl-bm1880.o
|
||||
obj-$(CONFIG_PINCTRL_DA850_PUPD) += pinctrl-da850-pupd.o
|
||||
obj-$(CONFIG_PINCTRL_DA9062) += pinctrl-da9062.o
|
@ -1,45 +0,0 @@
|
||||
From: Shiji Yang <yangshiji66@outlook.com>
|
||||
Date: Wed, 26 Jul 2023 01:32:55 +0800
|
||||
Subject: [PATCH] pinctrl: mtmips: support requesting different functions for
|
||||
same group
|
||||
|
||||
Sometimes pinctrl consumers may request different functions for the
|
||||
same pin group in different situations. This patch can help to reset
|
||||
the group function flag when requesting a different function.
|
||||
|
||||
Signed-off-by: Shiji Yang <yangshiji66@outlook.com>
|
||||
---
|
||||
drivers/pinctrl/ralink/pinctrl-ralink.c | 21 +++++++++++++++++----
|
||||
1 file changed, 17 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/pinctrl/ralink/pinctrl-ralink.c
|
||||
+++ b/drivers/pinctrl/ralink/pinctrl-ralink.c
|
||||
@@ -123,11 +123,24 @@ static int ralink_pmx_group_enable(struc
|
||||
int i;
|
||||
int shift;
|
||||
|
||||
- /* dont allow double use */
|
||||
+ /*
|
||||
+ * for the same pin group, if request a different function,
|
||||
+ * then clear the group function flag and continue, else exit.
|
||||
+ */
|
||||
if (p->groups[group].enabled) {
|
||||
- dev_err(p->dev, "%s is already enabled\n",
|
||||
- p->groups[group].name);
|
||||
- return 0;
|
||||
+ for (i = 0; i < p->groups[group].func_count; i++) {
|
||||
+ if (p->groups[group].func[i].enabled == 1) {
|
||||
+ if (!strcmp(p->func[func]->name,
|
||||
+ p->groups[group].func[i].name))
|
||||
+ return 0;
|
||||
+ p->groups[group].func[i].enabled = 0;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* exit if request the "gpio" function again */
|
||||
+ if (i == p->groups[group].func_count && func == 0)
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
p->groups[group].enabled = 1;
|
@ -1,244 +0,0 @@
|
||||
From 975e76214cd2516eb6cfff4c3eec581872645e88 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Thu, 19 Sep 2013 01:50:59 +0200
|
||||
Subject: [PATCH 31/53] uvc: add iPassion iP2970 support
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
drivers/media/usb/uvc/uvc_driver.c | 12 +++
|
||||
drivers/media/usb/uvc/uvc_status.c | 2 +
|
||||
drivers/media/usb/uvc/uvc_video.c | 147 ++++++++++++++++++++++++++++++++++++
|
||||
drivers/media/usb/uvc/uvcvideo.h | 5 +-
|
||||
4 files changed, 165 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/media/usb/uvc/uvc_driver.c
|
||||
+++ b/drivers/media/usb/uvc/uvc_driver.c
|
||||
@@ -3158,6 +3158,18 @@ static const struct usb_device_id uvc_id
|
||||
.bInterfaceSubClass = 1,
|
||||
.bInterfaceProtocol = 0,
|
||||
.driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) },
|
||||
+ /* iPassion iP2970 */
|
||||
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
|
||||
+ | USB_DEVICE_ID_MATCH_INT_INFO,
|
||||
+ .idVendor = 0x1B3B,
|
||||
+ .idProduct = 0x2970,
|
||||
+ .bInterfaceClass = USB_CLASS_VIDEO,
|
||||
+ .bInterfaceSubClass = 1,
|
||||
+ .bInterfaceProtocol = 0,
|
||||
+ .driver_info = UVC_QUIRK_PROBE_MINMAX
|
||||
+ | UVC_QUIRK_STREAM_NO_FID
|
||||
+ | UVC_QUIRK_MOTION
|
||||
+ | UVC_QUIRK_SINGLE_ISO },
|
||||
/* Generic USB Video Class */
|
||||
{ USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, UVC_PC_PROTOCOL_UNDEFINED) },
|
||||
{ USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, UVC_PC_PROTOCOL_15) },
|
||||
--- a/drivers/media/usb/uvc/uvc_status.c
|
||||
+++ b/drivers/media/usb/uvc/uvc_status.c
|
||||
@@ -224,6 +224,7 @@ static void uvc_status_complete(struct u
|
||||
if (uvc_event_control(urb, status, len))
|
||||
/* The URB will be resubmitted in work context. */
|
||||
return;
|
||||
+ dev->motion = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -272,6 +273,7 @@ int uvc_status_init(struct uvc_device *d
|
||||
}
|
||||
|
||||
pipe = usb_rcvintpipe(dev->udev, ep->desc.bEndpointAddress);
|
||||
+ dev->motion = 0;
|
||||
|
||||
/* For high-speed interrupt endpoints, the bInterval value is used as
|
||||
* an exponent of two. Some developers forgot about it.
|
||||
--- a/drivers/media/usb/uvc/uvc_video.c
|
||||
+++ b/drivers/media/usb/uvc/uvc_video.c
|
||||
@@ -19,6 +19,11 @@
|
||||
#include <linux/wait.h>
|
||||
#include <linux/atomic.h>
|
||||
#include <asm/unaligned.h>
|
||||
+#include <linux/skbuff.h>
|
||||
+#include <linux/kobject.h>
|
||||
+#include <linux/netlink.h>
|
||||
+#include <linux/kobject.h>
|
||||
+#include <linux/workqueue.h>
|
||||
|
||||
#include <media/v4l2-common.h>
|
||||
|
||||
@@ -1214,9 +1219,149 @@ static void uvc_video_decode_data(struct
|
||||
uvc_urb->async_operations++;
|
||||
}
|
||||
|
||||
+struct bh_priv {
|
||||
+ unsigned long seen;
|
||||
+};
|
||||
+
|
||||
+struct bh_event {
|
||||
+ const char *name;
|
||||
+ struct sk_buff *skb;
|
||||
+ struct work_struct work;
|
||||
+};
|
||||
+
|
||||
+#define BH_ERR(fmt, args...) printk(KERN_ERR "%s: " fmt, "webcam", ##args )
|
||||
+#define BH_DBG(fmt, args...) do {} while (0)
|
||||
+#define BH_SKB_SIZE 2048
|
||||
+
|
||||
+extern u64 uevent_next_seqnum(void);
|
||||
+static int seen = 0;
|
||||
+
|
||||
+static int bh_event_add_var(struct bh_event *event, int argv,
|
||||
+ const char *format, ...)
|
||||
+{
|
||||
+ static char buf[128];
|
||||
+ char *s;
|
||||
+ va_list args;
|
||||
+ int len;
|
||||
+
|
||||
+ if (argv)
|
||||
+ return 0;
|
||||
+
|
||||
+ va_start(args, format);
|
||||
+ len = vsnprintf(buf, sizeof(buf), format, args);
|
||||
+ va_end(args);
|
||||
+
|
||||
+ if (len >= sizeof(buf)) {
|
||||
+ BH_ERR("buffer size too small\n");
|
||||
+ WARN_ON(1);
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ s = skb_put(event->skb, len + 1);
|
||||
+ strcpy(s, buf);
|
||||
+
|
||||
+ BH_DBG("added variable '%s'\n", s);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int motion_hotplug_fill_event(struct bh_event *event)
|
||||
+{
|
||||
+ int s = jiffies;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (!seen)
|
||||
+ seen = jiffies;
|
||||
+
|
||||
+ ret = bh_event_add_var(event, 0, "HOME=%s", "/");
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = bh_event_add_var(event, 0, "PATH=%s",
|
||||
+ "/sbin:/bin:/usr/sbin:/usr/bin");
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = bh_event_add_var(event, 0, "SUBSYSTEM=usb");
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = bh_event_add_var(event, 0, "ACTION=motion");
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = bh_event_add_var(event, 0, "SEEN=%d", s - seen);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ seen = s;
|
||||
+
|
||||
+ ret = bh_event_add_var(event, 0, "SEQNUM=%llu", uevent_next_seqnum());
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static void motion_hotplug_work(struct work_struct *work)
|
||||
+{
|
||||
+ struct bh_event *event = container_of(work, struct bh_event, work);
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ event->skb = alloc_skb(BH_SKB_SIZE, GFP_KERNEL);
|
||||
+ if (!event->skb)
|
||||
+ goto out_free_event;
|
||||
+
|
||||
+ ret = bh_event_add_var(event, 0, "%s@", "add");
|
||||
+ if (ret)
|
||||
+ goto out_free_skb;
|
||||
+
|
||||
+ ret = motion_hotplug_fill_event(event);
|
||||
+ if (ret)
|
||||
+ goto out_free_skb;
|
||||
+
|
||||
+ NETLINK_CB(event->skb).dst_group = 1;
|
||||
+ broadcast_uevent(event->skb, 0, 1, GFP_KERNEL);
|
||||
+
|
||||
+out_free_skb:
|
||||
+ if (ret) {
|
||||
+ BH_ERR("work error %d\n", ret);
|
||||
+ kfree_skb(event->skb);
|
||||
+ }
|
||||
+out_free_event:
|
||||
+ kfree(event);
|
||||
+}
|
||||
+
|
||||
+static int motion_hotplug_create_event(void)
|
||||
+{
|
||||
+ struct bh_event *event;
|
||||
+
|
||||
+ event = kzalloc(sizeof(*event), GFP_KERNEL);
|
||||
+ if (!event)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ event->name = "motion";
|
||||
+
|
||||
+ INIT_WORK(&event->work, (void *)(void *)motion_hotplug_work);
|
||||
+ schedule_work(&event->work);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#define MOTION_FLAG_OFFSET 4
|
||||
static void uvc_video_decode_end(struct uvc_streaming *stream,
|
||||
struct uvc_buffer *buf, const u8 *data, int len)
|
||||
{
|
||||
+ if ((stream->dev->quirks & UVC_QUIRK_MOTION) &&
|
||||
+ (data[len - 2] == 0xff) && (data[len - 1] == 0xd9)) {
|
||||
+ u8 *mem;
|
||||
+ buf->state = UVC_BUF_STATE_READY;
|
||||
+ mem = (u8 *) (buf->mem + MOTION_FLAG_OFFSET);
|
||||
+ if ( stream->dev->motion ) {
|
||||
+ stream->dev->motion = 0;
|
||||
+ motion_hotplug_create_event();
|
||||
+ } else {
|
||||
+ *mem &= 0x7f;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
/* Mark the buffer as done if the EOF marker is set. */
|
||||
if (data[1] & UVC_STREAM_EOF && buf->bytesused != 0) {
|
||||
uvc_dbg(stream->dev, FRAME, "Frame complete (EOF found)\n");
|
||||
@@ -1801,6 +1946,8 @@ static int uvc_init_video_isoc(struct uv
|
||||
if (npackets == 0)
|
||||
return -ENOMEM;
|
||||
|
||||
+ if (stream->dev->quirks & UVC_QUIRK_SINGLE_ISO)
|
||||
+ npackets = 1;
|
||||
size = npackets * psize;
|
||||
|
||||
for_each_uvc_urb(uvc_urb, stream) {
|
||||
--- a/drivers/media/usb/uvc/uvcvideo.h
|
||||
+++ b/drivers/media/usb/uvc/uvcvideo.h
|
||||
@@ -210,6 +210,8 @@
|
||||
#define UVC_QUIRK_FORCE_Y8 0x00000800
|
||||
#define UVC_QUIRK_FORCE_BPP 0x00001000
|
||||
#define UVC_QUIRK_WAKE_AUTOSUSPEND 0x00002000
|
||||
+#define UVC_QUIRK_MOTION 0x00004000
|
||||
+#define UVC_QUIRK_SINGLE_ISO 0x00008000
|
||||
|
||||
/* Format flags */
|
||||
#define UVC_FMT_FLAG_COMPRESSED 0x00000001
|
||||
@@ -701,6 +703,7 @@ struct uvc_device {
|
||||
u8 *status;
|
||||
struct input_dev *input;
|
||||
char input_phys[64];
|
||||
+ int motion;
|
||||
|
||||
struct uvc_ctrl_work {
|
||||
struct work_struct work;
|
@ -1,44 +0,0 @@
|
||||
From da6015e7f19d749f135f7ac55c4ec47b06faa868 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Fri, 9 Aug 2013 20:12:59 +0200
|
||||
Subject: [PATCH 41/53] DT: Add documentation for spi-rt2880
|
||||
|
||||
Describe the SPI master found on the MIPS based Ralink RT2880 SoC.
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
.../devicetree/bindings/spi/spi-rt2880.txt | 28 ++++++++++++++++++++
|
||||
1 file changed, 28 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/spi/spi-rt2880.txt
|
||||
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/spi/spi-rt2880.txt
|
||||
@@ -0,0 +1,28 @@
|
||||
+Ralink SoC RT2880 SPI master controller.
|
||||
+
|
||||
+This SPI controller is found on most wireless SoCs made by ralink.
|
||||
+
|
||||
+Required properties:
|
||||
+- compatible : "ralink,rt2880-spi"
|
||||
+- reg : The register base for the controller.
|
||||
+- #address-cells : <1>, as required by generic SPI binding.
|
||||
+- #size-cells : <0>, also as required by generic SPI binding.
|
||||
+
|
||||
+Child nodes as per the generic SPI binding.
|
||||
+
|
||||
+Example:
|
||||
+
|
||||
+ spi@b00 {
|
||||
+ compatible = "ralink,rt2880-spi";
|
||||
+ reg = <0xb00 0x100>;
|
||||
+
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ m25p80@0 {
|
||||
+ compatible = "m25p80";
|
||||
+ reg = <0>;
|
||||
+ spi-max-frequency = <10000000>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
@ -1,579 +0,0 @@
|
||||
From 683af4ebb91a1600df1946ac4769d916b8a1be65 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Sun, 27 Jul 2014 11:15:12 +0100
|
||||
Subject: [PATCH 42/53] SPI: ralink: add Ralink SoC spi driver
|
||||
|
||||
Add the driver needed to make SPI work on Ralink SoC.
|
||||
|
||||
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
|
||||
Acked-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
drivers/spi/Kconfig | 6 +
|
||||
drivers/spi/Makefile | 1 +
|
||||
drivers/spi/spi-rt2880.c | 530 ++++++++++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 537 insertions(+)
|
||||
create mode 100644 drivers/spi/spi-rt2880.c
|
||||
|
||||
--- a/drivers/spi/Kconfig
|
||||
+++ b/drivers/spi/Kconfig
|
||||
@@ -718,6 +718,12 @@ config SPI_QCOM_GENI
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called spi-geni-qcom.
|
||||
|
||||
+config SPI_RT2880
|
||||
+ tristate "Ralink RT288x SPI Controller"
|
||||
+ depends on RALINK
|
||||
+ help
|
||||
+ This selects a driver for the Ralink RT288x/RT305x SPI Controller.
|
||||
+
|
||||
config SPI_S3C24XX
|
||||
tristate "Samsung S3C24XX series SPI"
|
||||
depends on ARCH_S3C24XX
|
||||
--- a/drivers/spi/Makefile
|
||||
+++ b/drivers/spi/Makefile
|
||||
@@ -100,6 +100,7 @@ obj-$(CONFIG_SPI_RB4XX) += spi-rb4xx.o
|
||||
obj-$(CONFIG_MACH_REALTEK_RTL) += spi-realtek-rtl.o
|
||||
obj-$(CONFIG_SPI_RPCIF) += spi-rpc-if.o
|
||||
obj-$(CONFIG_SPI_RSPI) += spi-rspi.o
|
||||
+obj-$(CONFIG_SPI_RT2880) += spi-rt2880.o
|
||||
obj-$(CONFIG_SPI_S3C24XX) += spi-s3c24xx-hw.o
|
||||
spi-s3c24xx-hw-y := spi-s3c24xx.o
|
||||
obj-$(CONFIG_SPI_S3C64XX) += spi-s3c64xx.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/spi/spi-rt2880.c
|
||||
@@ -0,0 +1,535 @@
|
||||
+/*
|
||||
+ * spi-rt2880.c -- Ralink RT288x/RT305x SPI controller driver
|
||||
+ *
|
||||
+ * Copyright (C) 2011 Sergiy <piratfm@gmail.com>
|
||||
+ * Copyright (C) 2011-2013 Gabor Juhos <juhosg@openwrt.org>
|
||||
+ *
|
||||
+ * Some parts are based on spi-orion.c:
|
||||
+ * Author: Shadi Ammouri <shadi@marvell.com>
|
||||
+ * Copyright (C) 2007-2008 Marvell Ltd.
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/err.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/reset.h>
|
||||
+#include <linux/spi/spi.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/gpio.h>
|
||||
+
|
||||
+#define DRIVER_NAME "spi-rt2880"
|
||||
+
|
||||
+#define RAMIPS_SPI_STAT 0x00
|
||||
+#define RAMIPS_SPI_CFG 0x10
|
||||
+#define RAMIPS_SPI_CTL 0x14
|
||||
+#define RAMIPS_SPI_DATA 0x20
|
||||
+#define RAMIPS_SPI_ADDR 0x24
|
||||
+#define RAMIPS_SPI_BS 0x28
|
||||
+#define RAMIPS_SPI_USER 0x2C
|
||||
+#define RAMIPS_SPI_TXFIFO 0x30
|
||||
+#define RAMIPS_SPI_RXFIFO 0x34
|
||||
+#define RAMIPS_SPI_FIFO_STAT 0x38
|
||||
+#define RAMIPS_SPI_MODE 0x3C
|
||||
+#define RAMIPS_SPI_DEV_OFFSET 0x40
|
||||
+#define RAMIPS_SPI_DMA 0x80
|
||||
+#define RAMIPS_SPI_DMASTAT 0x84
|
||||
+#define RAMIPS_SPI_ARBITER 0xF0
|
||||
+
|
||||
+/* SPISTAT register bit field */
|
||||
+#define SPISTAT_BUSY BIT(0)
|
||||
+
|
||||
+/* SPICFG register bit field */
|
||||
+#define SPICFG_ADDRMODE BIT(12)
|
||||
+#define SPICFG_RXENVDIS BIT(11)
|
||||
+#define SPICFG_RXCAP BIT(10)
|
||||
+#define SPICFG_SPIENMODE BIT(9)
|
||||
+#define SPICFG_MSBFIRST BIT(8)
|
||||
+#define SPICFG_SPICLKPOL BIT(6)
|
||||
+#define SPICFG_RXCLKEDGE_FALLING BIT(5)
|
||||
+#define SPICFG_TXCLKEDGE_FALLING BIT(4)
|
||||
+#define SPICFG_HIZSPI BIT(3)
|
||||
+#define SPICFG_SPICLK_PRESCALE_MASK 0x7
|
||||
+#define SPICFG_SPICLK_DIV2 0
|
||||
+#define SPICFG_SPICLK_DIV4 1
|
||||
+#define SPICFG_SPICLK_DIV8 2
|
||||
+#define SPICFG_SPICLK_DIV16 3
|
||||
+#define SPICFG_SPICLK_DIV32 4
|
||||
+#define SPICFG_SPICLK_DIV64 5
|
||||
+#define SPICFG_SPICLK_DIV128 6
|
||||
+#define SPICFG_SPICLK_DISABLE 7
|
||||
+
|
||||
+/* SPICTL register bit field */
|
||||
+#define SPICTL_START BIT(4)
|
||||
+#define SPICTL_HIZSDO BIT(3)
|
||||
+#define SPICTL_STARTWR BIT(2)
|
||||
+#define SPICTL_STARTRD BIT(1)
|
||||
+#define SPICTL_SPIENA BIT(0)
|
||||
+
|
||||
+/* SPIUSER register bit field */
|
||||
+#define SPIUSER_USERMODE BIT(21)
|
||||
+#define SPIUSER_INSTR_PHASE BIT(20)
|
||||
+#define SPIUSER_ADDR_PHASE_MASK 0x7
|
||||
+#define SPIUSER_ADDR_PHASE_OFFSET 17
|
||||
+#define SPIUSER_MODE_PHASE BIT(16)
|
||||
+#define SPIUSER_DUMMY_PHASE_MASK 0x3
|
||||
+#define SPIUSER_DUMMY_PHASE_OFFSET 14
|
||||
+#define SPIUSER_DATA_PHASE_MASK 0x3
|
||||
+#define SPIUSER_DATA_PHASE_OFFSET 12
|
||||
+#define SPIUSER_DATA_READ (BIT(0) << SPIUSER_DATA_PHASE_OFFSET)
|
||||
+#define SPIUSER_DATA_WRITE (BIT(1) << SPIUSER_DATA_PHASE_OFFSET)
|
||||
+#define SPIUSER_ADDR_TYPE_OFFSET 9
|
||||
+#define SPIUSER_MODE_TYPE_OFFSET 6
|
||||
+#define SPIUSER_DUMMY_TYPE_OFFSET 3
|
||||
+#define SPIUSER_DATA_TYPE_OFFSET 0
|
||||
+#define SPIUSER_TRANSFER_MASK 0x7
|
||||
+#define SPIUSER_TRANSFER_SINGLE BIT(0)
|
||||
+#define SPIUSER_TRANSFER_DUAL BIT(1)
|
||||
+#define SPIUSER_TRANSFER_QUAD BIT(2)
|
||||
+
|
||||
+#define SPIUSER_TRANSFER_TYPE(type) ( \
|
||||
+ (type << SPIUSER_ADDR_TYPE_OFFSET) | \
|
||||
+ (type << SPIUSER_MODE_TYPE_OFFSET) | \
|
||||
+ (type << SPIUSER_DUMMY_TYPE_OFFSET) | \
|
||||
+ (type << SPIUSER_DATA_TYPE_OFFSET) \
|
||||
+)
|
||||
+
|
||||
+/* SPIFIFOSTAT register bit field */
|
||||
+#define SPIFIFOSTAT_TXEMPTY BIT(19)
|
||||
+#define SPIFIFOSTAT_RXEMPTY BIT(18)
|
||||
+#define SPIFIFOSTAT_TXFULL BIT(17)
|
||||
+#define SPIFIFOSTAT_RXFULL BIT(16)
|
||||
+#define SPIFIFOSTAT_FIFO_MASK 0xff
|
||||
+#define SPIFIFOSTAT_TX_OFFSET 8
|
||||
+#define SPIFIFOSTAT_RX_OFFSET 0
|
||||
+
|
||||
+#define SPI_FIFO_DEPTH 16
|
||||
+
|
||||
+/* SPIMODE register bit field */
|
||||
+#define SPIMODE_MODE_OFFSET 24
|
||||
+#define SPIMODE_DUMMY_OFFSET 0
|
||||
+
|
||||
+/* SPIARB register bit field */
|
||||
+#define SPICTL_ARB_EN BIT(31)
|
||||
+#define SPICTL_CSCTL1 BIT(16)
|
||||
+#define SPI1_POR BIT(1)
|
||||
+#define SPI0_POR BIT(0)
|
||||
+
|
||||
+#define RT2880_SPI_MODE_BITS (SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST | \
|
||||
+ SPI_CS_HIGH)
|
||||
+
|
||||
+static atomic_t hw_reset_count = ATOMIC_INIT(0);
|
||||
+
|
||||
+struct rt2880_spi {
|
||||
+ struct spi_master *master;
|
||||
+ void __iomem *base;
|
||||
+ u32 speed;
|
||||
+ u16 wait_loops;
|
||||
+ u16 mode;
|
||||
+ struct clk *clk;
|
||||
+};
|
||||
+
|
||||
+static inline struct rt2880_spi *spidev_to_rt2880_spi(struct spi_device *spi)
|
||||
+{
|
||||
+ return spi_master_get_devdata(spi->master);
|
||||
+}
|
||||
+
|
||||
+static inline u32 rt2880_spi_read(struct rt2880_spi *rs, u32 reg)
|
||||
+{
|
||||
+ return ioread32(rs->base + reg);
|
||||
+}
|
||||
+
|
||||
+static inline void rt2880_spi_write(struct rt2880_spi *rs, u32 reg,
|
||||
+ const u32 val)
|
||||
+{
|
||||
+ iowrite32(val, rs->base + reg);
|
||||
+}
|
||||
+
|
||||
+static inline void rt2880_spi_setbits(struct rt2880_spi *rs, u32 reg, u32 mask)
|
||||
+{
|
||||
+ void __iomem *addr = rs->base + reg;
|
||||
+
|
||||
+ iowrite32((ioread32(addr) | mask), addr);
|
||||
+}
|
||||
+
|
||||
+static inline void rt2880_spi_clrbits(struct rt2880_spi *rs, u32 reg, u32 mask)
|
||||
+{
|
||||
+ void __iomem *addr = rs->base + reg;
|
||||
+
|
||||
+ iowrite32((ioread32(addr) & ~mask), addr);
|
||||
+}
|
||||
+
|
||||
+static u32 rt2880_spi_baudrate_get(struct spi_device *spi, unsigned int speed)
|
||||
+{
|
||||
+ struct rt2880_spi *rs = spidev_to_rt2880_spi(spi);
|
||||
+ u32 rate;
|
||||
+ u32 prescale;
|
||||
+
|
||||
+ /*
|
||||
+ * the supported rates are: 2, 4, 8, ... 128
|
||||
+ * round up as we look for equal or less speed
|
||||
+ */
|
||||
+ rate = DIV_ROUND_UP(clk_get_rate(rs->clk), speed);
|
||||
+ rate = roundup_pow_of_two(rate);
|
||||
+
|
||||
+ /* Convert the rate to SPI clock divisor value. */
|
||||
+ prescale = ilog2(rate / 2);
|
||||
+
|
||||
+ /* some tolerance. double and add 100 */
|
||||
+ rs->wait_loops = (8 * HZ * loops_per_jiffy) /
|
||||
+ (clk_get_rate(rs->clk) / rate);
|
||||
+ rs->wait_loops = (rs->wait_loops << 1) + 100;
|
||||
+ rs->speed = speed;
|
||||
+
|
||||
+ dev_dbg(&spi->dev, "speed: %lu/%u, rate: %u, prescal: %u, loops: %hu\n",
|
||||
+ clk_get_rate(rs->clk) / rate, speed, rate, prescale,
|
||||
+ rs->wait_loops);
|
||||
+
|
||||
+ return prescale;
|
||||
+}
|
||||
+
|
||||
+static u32 get_arbiter_offset(struct spi_master *master)
|
||||
+{
|
||||
+ u32 offset;
|
||||
+
|
||||
+ offset = RAMIPS_SPI_ARBITER;
|
||||
+ if (master->bus_num == 1)
|
||||
+ offset -= RAMIPS_SPI_DEV_OFFSET;
|
||||
+
|
||||
+ return offset;
|
||||
+}
|
||||
+
|
||||
+static void rt2880_spi_set_cs(struct spi_device *spi, bool enable)
|
||||
+{
|
||||
+ struct rt2880_spi *rs = spidev_to_rt2880_spi(spi);
|
||||
+
|
||||
+ if (enable)
|
||||
+ rt2880_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_SPIENA);
|
||||
+ else
|
||||
+ rt2880_spi_clrbits(rs, RAMIPS_SPI_CTL, SPICTL_SPIENA);
|
||||
+}
|
||||
+
|
||||
+static int rt2880_spi_wait_ready(struct rt2880_spi *rs, int len)
|
||||
+{
|
||||
+ int loop = rs->wait_loops * len;
|
||||
+
|
||||
+ while ((rt2880_spi_read(rs, RAMIPS_SPI_STAT) & SPISTAT_BUSY) && --loop)
|
||||
+ cpu_relax();
|
||||
+
|
||||
+ if (loop)
|
||||
+ return 0;
|
||||
+
|
||||
+ return -ETIMEDOUT;
|
||||
+}
|
||||
+
|
||||
+static void rt2880_dump_reg(struct spi_master *master)
|
||||
+{
|
||||
+ struct rt2880_spi *rs = spi_master_get_devdata(master);
|
||||
+
|
||||
+ dev_dbg(&master->dev, "stat: %08x, cfg: %08x, ctl: %08x, " \
|
||||
+ "data: %08x, arb: %08x\n",
|
||||
+ rt2880_spi_read(rs, RAMIPS_SPI_STAT),
|
||||
+ rt2880_spi_read(rs, RAMIPS_SPI_CFG),
|
||||
+ rt2880_spi_read(rs, RAMIPS_SPI_CTL),
|
||||
+ rt2880_spi_read(rs, RAMIPS_SPI_DATA),
|
||||
+ rt2880_spi_read(rs, get_arbiter_offset(master)));
|
||||
+}
|
||||
+
|
||||
+static int rt2880_spi_transfer_one(struct spi_master *master,
|
||||
+ struct spi_device *spi, struct spi_transfer *xfer)
|
||||
+{
|
||||
+ struct rt2880_spi *rs = spi_master_get_devdata(master);
|
||||
+ unsigned len;
|
||||
+ const u8 *tx = xfer->tx_buf;
|
||||
+ u8 *rx = xfer->rx_buf;
|
||||
+ int err = 0;
|
||||
+
|
||||
+ /* change clock speed */
|
||||
+ if (unlikely(rs->speed != xfer->speed_hz)) {
|
||||
+ u32 reg;
|
||||
+ reg = rt2880_spi_read(rs, RAMIPS_SPI_CFG);
|
||||
+ reg &= ~SPICFG_SPICLK_PRESCALE_MASK;
|
||||
+ reg |= rt2880_spi_baudrate_get(spi, xfer->speed_hz);
|
||||
+ rt2880_spi_write(rs, RAMIPS_SPI_CFG, reg);
|
||||
+ }
|
||||
+
|
||||
+ if (tx) {
|
||||
+ len = xfer->len;
|
||||
+ while (len-- > 0) {
|
||||
+ rt2880_spi_write(rs, RAMIPS_SPI_DATA, *tx++);
|
||||
+ rt2880_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_STARTWR);
|
||||
+ err = rt2880_spi_wait_ready(rs, 1);
|
||||
+ if (err) {
|
||||
+ dev_err(&spi->dev, "TX failed, err=%d\n", err);
|
||||
+ goto out;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (rx) {
|
||||
+ len = xfer->len;
|
||||
+ while (len-- > 0) {
|
||||
+ rt2880_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_STARTRD);
|
||||
+ err = rt2880_spi_wait_ready(rs, 1);
|
||||
+ if (err) {
|
||||
+ dev_err(&spi->dev, "RX failed, err=%d\n", err);
|
||||
+ goto out;
|
||||
+ }
|
||||
+ *rx++ = (u8) rt2880_spi_read(rs, RAMIPS_SPI_DATA);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+out:
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+/* copy from spi.c */
|
||||
+static void spi_set_cs(struct spi_device *spi, bool enable)
|
||||
+{
|
||||
+ if (spi->mode & SPI_CS_HIGH)
|
||||
+ enable = !enable;
|
||||
+
|
||||
+ if (spi->cs_gpio >= 0)
|
||||
+ gpio_set_value(spi->cs_gpio, !enable);
|
||||
+ else if (spi->master->set_cs)
|
||||
+ spi->master->set_cs(spi, !enable);
|
||||
+}
|
||||
+
|
||||
+static int rt2880_spi_setup(struct spi_device *spi)
|
||||
+{
|
||||
+ struct spi_master *master = spi->master;
|
||||
+ struct rt2880_spi *rs = spi_master_get_devdata(master);
|
||||
+ u32 reg, old_reg, arbit_off;
|
||||
+
|
||||
+ if ((spi->max_speed_hz > master->max_speed_hz) ||
|
||||
+ (spi->max_speed_hz < master->min_speed_hz)) {
|
||||
+ dev_err(&spi->dev, "invalide requested speed %d Hz\n",
|
||||
+ spi->max_speed_hz);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ if (!(master->bits_per_word_mask &
|
||||
+ BIT(spi->bits_per_word - 1))) {
|
||||
+ dev_err(&spi->dev, "invalide bits_per_word %d\n",
|
||||
+ spi->bits_per_word);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ /* the hardware seems can't work on mode0 force it to mode3 */
|
||||
+ if ((spi->mode & (SPI_CPOL | SPI_CPHA)) == SPI_MODE_0) {
|
||||
+ dev_warn(&spi->dev, "force spi mode3\n");
|
||||
+ spi->mode |= SPI_MODE_3;
|
||||
+ }
|
||||
+
|
||||
+ /* chip polarity */
|
||||
+ arbit_off = get_arbiter_offset(master);
|
||||
+ reg = old_reg = rt2880_spi_read(rs, arbit_off);
|
||||
+ if (spi->mode & SPI_CS_HIGH) {
|
||||
+ switch (master->bus_num) {
|
||||
+ case 1:
|
||||
+ reg |= SPI1_POR;
|
||||
+ break;
|
||||
+ default:
|
||||
+ reg |= SPI0_POR;
|
||||
+ break;
|
||||
+ }
|
||||
+ } else {
|
||||
+ switch (master->bus_num) {
|
||||
+ case 1:
|
||||
+ reg &= ~SPI1_POR;
|
||||
+ break;
|
||||
+ default:
|
||||
+ reg &= ~SPI0_POR;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* enable spi1 */
|
||||
+ if (master->bus_num == 1)
|
||||
+ reg |= SPICTL_ARB_EN;
|
||||
+
|
||||
+ if (reg != old_reg)
|
||||
+ rt2880_spi_write(rs, arbit_off, reg);
|
||||
+
|
||||
+ /* deselected the spi device */
|
||||
+ spi_set_cs(spi, false);
|
||||
+
|
||||
+ rt2880_dump_reg(master);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int rt2880_spi_prepare_message(struct spi_master *master,
|
||||
+ struct spi_message *msg)
|
||||
+{
|
||||
+ struct rt2880_spi *rs = spi_master_get_devdata(master);
|
||||
+ struct spi_device *spi = msg->spi;
|
||||
+ u32 reg;
|
||||
+
|
||||
+ if ((rs->mode == spi->mode) && (rs->speed == spi->max_speed_hz))
|
||||
+ return 0;
|
||||
+
|
||||
+#if 0
|
||||
+ /* set spido to tri-state */
|
||||
+ rt2880_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_HIZSDO);
|
||||
+#endif
|
||||
+
|
||||
+ reg = rt2880_spi_read(rs, RAMIPS_SPI_CFG);
|
||||
+
|
||||
+ reg &= ~(SPICFG_MSBFIRST | SPICFG_SPICLKPOL |
|
||||
+ SPICFG_RXCLKEDGE_FALLING |
|
||||
+ SPICFG_TXCLKEDGE_FALLING |
|
||||
+ SPICFG_SPICLK_PRESCALE_MASK);
|
||||
+
|
||||
+ /* MSB */
|
||||
+ if (!(spi->mode & SPI_LSB_FIRST))
|
||||
+ reg |= SPICFG_MSBFIRST;
|
||||
+
|
||||
+ /* spi mode */
|
||||
+ switch (spi->mode & (SPI_CPOL | SPI_CPHA)) {
|
||||
+ case SPI_MODE_0:
|
||||
+ reg |= SPICFG_TXCLKEDGE_FALLING;
|
||||
+ break;
|
||||
+ case SPI_MODE_1:
|
||||
+ reg |= SPICFG_RXCLKEDGE_FALLING;
|
||||
+ break;
|
||||
+ case SPI_MODE_2:
|
||||
+ reg |= SPICFG_SPICLKPOL | SPICFG_RXCLKEDGE_FALLING;
|
||||
+ break;
|
||||
+ case SPI_MODE_3:
|
||||
+ reg |= SPICFG_SPICLKPOL | SPICFG_TXCLKEDGE_FALLING;
|
||||
+ break;
|
||||
+ }
|
||||
+ rs->mode = spi->mode;
|
||||
+
|
||||
+#if 0
|
||||
+ /* set spiclk and spiena to tri-state */
|
||||
+ reg |= SPICFG_HIZSPI;
|
||||
+#endif
|
||||
+
|
||||
+ /* clock divide */
|
||||
+ reg |= rt2880_spi_baudrate_get(spi, spi->max_speed_hz);
|
||||
+
|
||||
+ rt2880_spi_write(rs, RAMIPS_SPI_CFG, reg);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int rt2880_spi_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct spi_master *master;
|
||||
+ struct rt2880_spi *rs;
|
||||
+ void __iomem *base;
|
||||
+ struct resource *r;
|
||||
+ struct clk *clk;
|
||||
+ int ret;
|
||||
+
|
||||
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
+ base = devm_ioremap_resource(&pdev->dev, r);
|
||||
+ if (IS_ERR(base))
|
||||
+ return PTR_ERR(base);
|
||||
+
|
||||
+ clk = devm_clk_get(&pdev->dev, NULL);
|
||||
+ if (IS_ERR(clk)) {
|
||||
+ dev_err(&pdev->dev, "unable to get SYS clock\n");
|
||||
+ return PTR_ERR(clk);
|
||||
+ }
|
||||
+
|
||||
+ ret = clk_prepare_enable(clk);
|
||||
+ if (ret)
|
||||
+ goto err_clk;
|
||||
+
|
||||
+ master = spi_alloc_master(&pdev->dev, sizeof(*rs));
|
||||
+ if (master == NULL) {
|
||||
+ dev_dbg(&pdev->dev, "master allocation failed\n");
|
||||
+ ret = -ENOMEM;
|
||||
+ goto err_clk;
|
||||
+ }
|
||||
+
|
||||
+ master->dev.of_node = pdev->dev.of_node;
|
||||
+ master->mode_bits = RT2880_SPI_MODE_BITS;
|
||||
+ master->bits_per_word_mask = SPI_BPW_MASK(8);
|
||||
+ master->min_speed_hz = clk_get_rate(clk) / 128;
|
||||
+ master->max_speed_hz = clk_get_rate(clk) / 2;
|
||||
+ master->flags = SPI_MASTER_HALF_DUPLEX;
|
||||
+ master->setup = rt2880_spi_setup;
|
||||
+ master->prepare_message = rt2880_spi_prepare_message;
|
||||
+ master->set_cs = rt2880_spi_set_cs;
|
||||
+ master->transfer_one = rt2880_spi_transfer_one,
|
||||
+
|
||||
+ dev_set_drvdata(&pdev->dev, master);
|
||||
+
|
||||
+ rs = spi_master_get_devdata(master);
|
||||
+ rs->master = master;
|
||||
+ rs->base = base;
|
||||
+ rs->clk = clk;
|
||||
+
|
||||
+ if (atomic_inc_return(&hw_reset_count) == 1) {
|
||||
+ ret = device_reset(&pdev->dev);
|
||||
+ if (ret) {
|
||||
+ dev_err(&pdev->dev, "device_reset error.\n");
|
||||
+ goto err_master;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ ret = devm_spi_register_master(&pdev->dev, master);
|
||||
+ if (ret < 0) {
|
||||
+ dev_err(&pdev->dev, "devm_spi_register_master error.\n");
|
||||
+ goto err_master;
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+
|
||||
+err_master:
|
||||
+ spi_master_put(master);
|
||||
+ kfree(master);
|
||||
+err_clk:
|
||||
+ clk_disable_unprepare(clk);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int rt2880_spi_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct spi_master *master;
|
||||
+ struct rt2880_spi *rs;
|
||||
+
|
||||
+ master = dev_get_drvdata(&pdev->dev);
|
||||
+ rs = spi_master_get_devdata(master);
|
||||
+
|
||||
+ clk_disable_unprepare(rs->clk);
|
||||
+ atomic_dec(&hw_reset_count);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+MODULE_ALIAS("platform:" DRIVER_NAME);
|
||||
+
|
||||
+static const struct of_device_id rt2880_spi_match[] = {
|
||||
+ { .compatible = "ralink,rt2880-spi" },
|
||||
+ {},
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, rt2880_spi_match);
|
||||
+
|
||||
+static struct platform_driver rt2880_spi_driver = {
|
||||
+ .driver = {
|
||||
+ .name = DRIVER_NAME,
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .of_match_table = rt2880_spi_match,
|
||||
+ },
|
||||
+ .probe = rt2880_spi_probe,
|
||||
+ .remove = rt2880_spi_remove,
|
||||
+};
|
||||
+
|
||||
+module_platform_driver(rt2880_spi_driver);
|
||||
+
|
||||
+MODULE_DESCRIPTION("Ralink SPI driver");
|
||||
+MODULE_AUTHOR("Sergiy <piratfm@gmail.com>");
|
||||
+MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
|
||||
+MODULE_LICENSE("GPL");
|
@ -1,512 +0,0 @@
|
||||
From 723b8beaabf3c3c4b1ce69480141f1e926f3f3b2 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Sun, 27 Jul 2014 09:52:56 +0100
|
||||
Subject: [PATCH 44/53] i2c: MIPS: adds ralink I2C driver
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
.../devicetree/bindings/i2c/i2c-ralink.txt | 27 ++
|
||||
drivers/i2c/busses/Kconfig | 4 +
|
||||
drivers/i2c/busses/Makefile | 1 +
|
||||
drivers/i2c/busses/i2c-ralink.c | 327 ++++++++++++++++++++
|
||||
4 files changed, 359 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/i2c/i2c-ralink.txt
|
||||
create mode 100644 drivers/i2c/busses/i2c-ralink.c
|
||||
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/i2c/i2c-ralink.txt
|
||||
@@ -0,0 +1,27 @@
|
||||
+I2C for Ralink platforms
|
||||
+
|
||||
+Required properties :
|
||||
+- compatible : Must be "link,rt3052-i2c"
|
||||
+- reg: physical base address of the controller and length of memory mapped
|
||||
+ region.
|
||||
+- #address-cells = <1>;
|
||||
+- #size-cells = <0>;
|
||||
+
|
||||
+Optional properties:
|
||||
+- Child nodes conforming to i2c bus binding
|
||||
+
|
||||
+Example :
|
||||
+
|
||||
+palmbus@10000000 {
|
||||
+ i2c@900 {
|
||||
+ compatible = "link,rt3052-i2c";
|
||||
+ reg = <0x900 0x100>;
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ hwmon@4b {
|
||||
+ compatible = "national,lm92";
|
||||
+ reg = <0x4b>;
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
--- a/drivers/i2c/busses/Kconfig
|
||||
+++ b/drivers/i2c/busses/Kconfig
|
||||
@@ -949,6 +949,11 @@ config I2C_RK3X
|
||||
This driver can also be built as a module. If so, the module will
|
||||
be called i2c-rk3x.
|
||||
|
||||
+config I2C_RALINK
|
||||
+ tristate "Ralink I2C Controller"
|
||||
+ depends on RALINK && !SOC_MT7621
|
||||
+ select OF_I2C
|
||||
+
|
||||
config HAVE_S3C2410_I2C
|
||||
bool
|
||||
help
|
||||
--- a/drivers/i2c/busses/Makefile
|
||||
+++ b/drivers/i2c/busses/Makefile
|
||||
@@ -89,6 +89,7 @@ obj-$(CONFIG_I2C_PCA_PLATFORM) += i2c-pc
|
||||
obj-$(CONFIG_I2C_PNX) += i2c-pnx.o
|
||||
obj-$(CONFIG_I2C_PXA) += i2c-pxa.o
|
||||
obj-$(CONFIG_I2C_PXA_PCI) += i2c-pxa-pci.o
|
||||
+obj-$(CONFIG_I2C_RALINK) += i2c-ralink.o
|
||||
obj-$(CONFIG_I2C_QCOM_CCI) += i2c-qcom-cci.o
|
||||
obj-$(CONFIG_I2C_QCOM_GENI) += i2c-qcom-geni.o
|
||||
obj-$(CONFIG_I2C_QUP) += i2c-qup.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/i2c/busses/i2c-ralink.c
|
||||
@@ -0,0 +1,440 @@
|
||||
+/*
|
||||
+ * drivers/i2c/busses/i2c-ralink.c
|
||||
+ *
|
||||
+ * Copyright (C) 2013 Steven Liu <steven_liu@mediatek.com>
|
||||
+ * Copyright (C) 2016 Michael Lee <igvtee@gmail.com>
|
||||
+ *
|
||||
+ * Improve driver for i2cdetect from i2c-tools to detect i2c devices on the bus.
|
||||
+ * (C) 2014 Sittisak <sittisaks@hotmail.com>
|
||||
+ *
|
||||
+ * 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/interrupt.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/reset.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/errno.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/of_platform.h>
|
||||
+#include <linux/i2c.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/err.h>
|
||||
+#include <linux/clk.h>
|
||||
+
|
||||
+#define REG_CONFIG_REG 0x00
|
||||
+#define REG_CLKDIV_REG 0x04
|
||||
+#define REG_DEVADDR_REG 0x08
|
||||
+#define REG_ADDR_REG 0x0C
|
||||
+#define REG_DATAOUT_REG 0x10
|
||||
+#define REG_DATAIN_REG 0x14
|
||||
+#define REG_STATUS_REG 0x18
|
||||
+#define REG_STARTXFR_REG 0x1C
|
||||
+#define REG_BYTECNT_REG 0x20
|
||||
+
|
||||
+/* REG_CONFIG_REG */
|
||||
+#define I2C_ADDRLEN_OFFSET 5
|
||||
+#define I2C_DEVADLEN_OFFSET 2
|
||||
+#define I2C_ADDRLEN_MASK 0x3
|
||||
+#define I2C_ADDR_DIS BIT(1)
|
||||
+#define I2C_DEVADDR_DIS BIT(0)
|
||||
+#define I2C_ADDRLEN_8 (7 << I2C_ADDRLEN_OFFSET)
|
||||
+#define I2C_DEVADLEN_7 (6 << I2C_DEVADLEN_OFFSET)
|
||||
+#define I2C_CONF_DEFAULT (I2C_ADDRLEN_8 | I2C_DEVADLEN_7)
|
||||
+
|
||||
+/* REG_CLKDIV_REG */
|
||||
+#define I2C_CLKDIV_MASK 0xffff
|
||||
+
|
||||
+/* REG_DEVADDR_REG */
|
||||
+#define I2C_DEVADDR_MASK 0x7f
|
||||
+
|
||||
+/* REG_ADDR_REG */
|
||||
+#define I2C_ADDR_MASK 0xff
|
||||
+
|
||||
+/* REG_STATUS_REG */
|
||||
+#define I2C_STARTERR BIT(4)
|
||||
+#define I2C_ACKERR BIT(3)
|
||||
+#define I2C_DATARDY BIT(2)
|
||||
+#define I2C_SDOEMPTY BIT(1)
|
||||
+#define I2C_BUSY BIT(0)
|
||||
+
|
||||
+/* REG_STARTXFR_REG */
|
||||
+#define NOSTOP_CMD BIT(2)
|
||||
+#define NODATA_CMD BIT(1)
|
||||
+#define READ_CMD BIT(0)
|
||||
+
|
||||
+/* REG_BYTECNT_REG */
|
||||
+#define BYTECNT_MAX 64
|
||||
+#define SET_BYTECNT(x) (x - 1)
|
||||
+
|
||||
+/* timeout waiting for I2C devices to respond (clock streching) */
|
||||
+#define TIMEOUT_MS 1000
|
||||
+#define DELAY_INTERVAL_US 100
|
||||
+
|
||||
+struct rt_i2c {
|
||||
+ void __iomem *base;
|
||||
+ struct clk *clk;
|
||||
+ struct device *dev;
|
||||
+ struct i2c_adapter adap;
|
||||
+ u32 cur_clk;
|
||||
+ u32 clk_div;
|
||||
+ u32 flags;
|
||||
+};
|
||||
+
|
||||
+static void rt_i2c_w32(struct rt_i2c *i2c, u32 val, unsigned reg)
|
||||
+{
|
||||
+ iowrite32(val, i2c->base + reg);
|
||||
+}
|
||||
+
|
||||
+static u32 rt_i2c_r32(struct rt_i2c *i2c, unsigned reg)
|
||||
+{
|
||||
+ return ioread32(i2c->base + reg);
|
||||
+}
|
||||
+
|
||||
+static int poll_down_timeout(void __iomem *addr, u32 mask)
|
||||
+{
|
||||
+ unsigned long timeout = jiffies + msecs_to_jiffies(TIMEOUT_MS);
|
||||
+
|
||||
+ do {
|
||||
+ if (!(readl_relaxed(addr) & mask))
|
||||
+ return 0;
|
||||
+
|
||||
+ usleep_range(DELAY_INTERVAL_US, DELAY_INTERVAL_US + 50);
|
||||
+ } while (time_before(jiffies, timeout));
|
||||
+
|
||||
+ return (readl_relaxed(addr) & mask) ? -EAGAIN : 0;
|
||||
+}
|
||||
+
|
||||
+static int rt_i2c_wait_idle(struct rt_i2c *i2c)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = poll_down_timeout(i2c->base + REG_STATUS_REG, I2C_BUSY);
|
||||
+ if (ret < 0)
|
||||
+ dev_dbg(i2c->dev, "idle err(%d)\n", ret);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int poll_up_timeout(void __iomem *addr, u32 mask)
|
||||
+{
|
||||
+ unsigned long timeout = jiffies + msecs_to_jiffies(TIMEOUT_MS);
|
||||
+ u32 status;
|
||||
+
|
||||
+ do {
|
||||
+ status = readl_relaxed(addr);
|
||||
+
|
||||
+ /* check error status */
|
||||
+ if (status & I2C_STARTERR)
|
||||
+ return -EAGAIN;
|
||||
+ else if (status & I2C_ACKERR)
|
||||
+ return -ENXIO;
|
||||
+ else if (status & mask)
|
||||
+ return 0;
|
||||
+
|
||||
+ usleep_range(DELAY_INTERVAL_US, DELAY_INTERVAL_US + 50);
|
||||
+ } while (time_before(jiffies, timeout));
|
||||
+
|
||||
+ return -ETIMEDOUT;
|
||||
+}
|
||||
+
|
||||
+static int rt_i2c_wait_rx_done(struct rt_i2c *i2c)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = poll_up_timeout(i2c->base + REG_STATUS_REG, I2C_DATARDY);
|
||||
+ if (ret < 0)
|
||||
+ dev_dbg(i2c->dev, "rx err(%d)\n", ret);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int rt_i2c_wait_tx_done(struct rt_i2c *i2c)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = poll_up_timeout(i2c->base + REG_STATUS_REG, I2C_SDOEMPTY);
|
||||
+ if (ret < 0)
|
||||
+ dev_dbg(i2c->dev, "tx err(%d)\n", ret);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static void rt_i2c_reset(struct rt_i2c *i2c)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = device_reset(i2c->adap.dev.parent);
|
||||
+ if (ret)
|
||||
+ dev_err(i2c->dev, "Failed to reset device");
|
||||
+
|
||||
+ barrier();
|
||||
+ rt_i2c_w32(i2c, i2c->clk_div, REG_CLKDIV_REG);
|
||||
+}
|
||||
+
|
||||
+static void rt_i2c_dump_reg(struct rt_i2c *i2c)
|
||||
+{
|
||||
+ dev_dbg(i2c->dev, "conf %08x, clkdiv %08x, devaddr %08x, " \
|
||||
+ "addr %08x, dataout %08x, datain %08x, " \
|
||||
+ "status %08x, startxfr %08x, bytecnt %08x\n",
|
||||
+ rt_i2c_r32(i2c, REG_CONFIG_REG),
|
||||
+ rt_i2c_r32(i2c, REG_CLKDIV_REG),
|
||||
+ rt_i2c_r32(i2c, REG_DEVADDR_REG),
|
||||
+ rt_i2c_r32(i2c, REG_ADDR_REG),
|
||||
+ rt_i2c_r32(i2c, REG_DATAOUT_REG),
|
||||
+ rt_i2c_r32(i2c, REG_DATAIN_REG),
|
||||
+ rt_i2c_r32(i2c, REG_STATUS_REG),
|
||||
+ rt_i2c_r32(i2c, REG_STARTXFR_REG),
|
||||
+ rt_i2c_r32(i2c, REG_BYTECNT_REG));
|
||||
+}
|
||||
+
|
||||
+static int rt_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
|
||||
+ int num)
|
||||
+{
|
||||
+ struct rt_i2c *i2c;
|
||||
+ struct i2c_msg *pmsg;
|
||||
+ unsigned char addr;
|
||||
+ int i, j, ret;
|
||||
+ u32 cmd;
|
||||
+
|
||||
+ i2c = i2c_get_adapdata(adap);
|
||||
+
|
||||
+ for (i = 0; i < num; i++) {
|
||||
+ pmsg = &msgs[i];
|
||||
+ if (i == (num - 1))
|
||||
+ cmd = 0;
|
||||
+ else
|
||||
+ cmd = NOSTOP_CMD;
|
||||
+
|
||||
+ dev_dbg(i2c->dev, "addr: 0x%x, len: %d, flags: 0x%x, stop: %d\n",
|
||||
+ pmsg->addr, pmsg->len, pmsg->flags,
|
||||
+ (cmd == 0)? 1 : 0);
|
||||
+
|
||||
+ /* wait hardware idle */
|
||||
+ if ((ret = rt_i2c_wait_idle(i2c)))
|
||||
+ goto err_timeout;
|
||||
+
|
||||
+ if (pmsg->flags & I2C_M_TEN) {
|
||||
+ rt_i2c_w32(i2c, I2C_CONF_DEFAULT, REG_CONFIG_REG);
|
||||
+ /* 10 bits address */
|
||||
+ addr = 0x78 | ((pmsg->addr >> 8) & 0x03);
|
||||
+ rt_i2c_w32(i2c, addr & I2C_DEVADDR_MASK,
|
||||
+ REG_DEVADDR_REG);
|
||||
+ rt_i2c_w32(i2c, pmsg->addr & I2C_ADDR_MASK,
|
||||
+ REG_ADDR_REG);
|
||||
+ } else {
|
||||
+ rt_i2c_w32(i2c, I2C_CONF_DEFAULT | I2C_ADDR_DIS,
|
||||
+ REG_CONFIG_REG);
|
||||
+ /* 7 bits address */
|
||||
+ rt_i2c_w32(i2c, pmsg->addr & I2C_DEVADDR_MASK,
|
||||
+ REG_DEVADDR_REG);
|
||||
+ }
|
||||
+
|
||||
+ /* buffer length */
|
||||
+ if (pmsg->len == 0)
|
||||
+ cmd |= NODATA_CMD;
|
||||
+ else
|
||||
+ rt_i2c_w32(i2c, SET_BYTECNT(pmsg->len),
|
||||
+ REG_BYTECNT_REG);
|
||||
+
|
||||
+ j = 0;
|
||||
+ if (pmsg->flags & I2C_M_RD) {
|
||||
+ cmd |= READ_CMD;
|
||||
+ /* start transfer */
|
||||
+ barrier();
|
||||
+ rt_i2c_w32(i2c, cmd, REG_STARTXFR_REG);
|
||||
+ do {
|
||||
+ /* wait */
|
||||
+ if ((ret = rt_i2c_wait_rx_done(i2c)))
|
||||
+ goto err_timeout;
|
||||
+ /* read data */
|
||||
+ if (pmsg->len)
|
||||
+ pmsg->buf[j] = rt_i2c_r32(i2c,
|
||||
+ REG_DATAIN_REG);
|
||||
+ j++;
|
||||
+ } while (j < pmsg->len);
|
||||
+ } else {
|
||||
+ do {
|
||||
+ /* write data */
|
||||
+ if (pmsg->len)
|
||||
+ rt_i2c_w32(i2c, pmsg->buf[j],
|
||||
+ REG_DATAOUT_REG);
|
||||
+ /* start transfer */
|
||||
+ if (j == 0) {
|
||||
+ barrier();
|
||||
+ rt_i2c_w32(i2c, cmd, REG_STARTXFR_REG);
|
||||
+ }
|
||||
+ /* wait */
|
||||
+ if ((ret = rt_i2c_wait_tx_done(i2c)))
|
||||
+ goto err_timeout;
|
||||
+ j++;
|
||||
+ } while (j < pmsg->len);
|
||||
+ }
|
||||
+ }
|
||||
+ /* the return value is number of executed messages */
|
||||
+ ret = i;
|
||||
+
|
||||
+ return ret;
|
||||
+
|
||||
+err_timeout:
|
||||
+ rt_i2c_dump_reg(i2c);
|
||||
+ rt_i2c_reset(i2c);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static u32 rt_i2c_func(struct i2c_adapter *a)
|
||||
+{
|
||||
+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
|
||||
+}
|
||||
+
|
||||
+static const struct i2c_algorithm rt_i2c_algo = {
|
||||
+ .master_xfer = rt_i2c_master_xfer,
|
||||
+ .functionality = rt_i2c_func,
|
||||
+};
|
||||
+
|
||||
+static const struct of_device_id i2c_rt_dt_ids[] = {
|
||||
+ { .compatible = "ralink,rt2880-i2c" },
|
||||
+ { /* sentinel */ }
|
||||
+};
|
||||
+
|
||||
+MODULE_DEVICE_TABLE(of, i2c_rt_dt_ids);
|
||||
+
|
||||
+static struct i2c_adapter_quirks rt_i2c_quirks = {
|
||||
+ .max_write_len = BYTECNT_MAX,
|
||||
+ .max_read_len = BYTECNT_MAX,
|
||||
+};
|
||||
+
|
||||
+static int rt_i2c_init(struct rt_i2c *i2c)
|
||||
+{
|
||||
+ u32 reg;
|
||||
+
|
||||
+ /* i2c_sclk = periph_clk / ((2 * clk_div) + 5) */
|
||||
+ i2c->clk_div = (clk_get_rate(i2c->clk) - (5 * i2c->cur_clk)) /
|
||||
+ (2 * i2c->cur_clk);
|
||||
+ if (i2c->clk_div < 8)
|
||||
+ i2c->clk_div = 8;
|
||||
+ if (i2c->clk_div > I2C_CLKDIV_MASK)
|
||||
+ i2c->clk_div = I2C_CLKDIV_MASK;
|
||||
+
|
||||
+ /* check support combinde/repeated start message */
|
||||
+ rt_i2c_w32(i2c, NOSTOP_CMD, REG_STARTXFR_REG);
|
||||
+ reg = rt_i2c_r32(i2c, REG_STARTXFR_REG) & NOSTOP_CMD;
|
||||
+
|
||||
+ rt_i2c_reset(i2c);
|
||||
+
|
||||
+ return reg;
|
||||
+}
|
||||
+
|
||||
+static int rt_i2c_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct resource *res;
|
||||
+ struct rt_i2c *i2c;
|
||||
+ struct i2c_adapter *adap;
|
||||
+ const struct of_device_id *match;
|
||||
+ int ret, restart;
|
||||
+
|
||||
+ match = of_match_device(i2c_rt_dt_ids, &pdev->dev);
|
||||
+
|
||||
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
+ if (!res) {
|
||||
+ dev_err(&pdev->dev, "no memory resource found\n");
|
||||
+ return -ENODEV;
|
||||
+ }
|
||||
+
|
||||
+ i2c = devm_kzalloc(&pdev->dev, sizeof(struct rt_i2c), GFP_KERNEL);
|
||||
+ if (!i2c) {
|
||||
+ dev_err(&pdev->dev, "failed to allocate i2c_adapter\n");
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ i2c->base = devm_ioremap_resource(&pdev->dev, res);
|
||||
+ if (IS_ERR(i2c->base))
|
||||
+ return PTR_ERR(i2c->base);
|
||||
+
|
||||
+ i2c->clk = devm_clk_get(&pdev->dev, NULL);
|
||||
+ if (IS_ERR(i2c->clk)) {
|
||||
+ dev_err(&pdev->dev, "no clock defined\n");
|
||||
+ return -ENODEV;
|
||||
+ }
|
||||
+ clk_prepare_enable(i2c->clk);
|
||||
+ i2c->dev = &pdev->dev;
|
||||
+
|
||||
+ if (of_property_read_u32(pdev->dev.of_node,
|
||||
+ "clock-frequency", &i2c->cur_clk))
|
||||
+ i2c->cur_clk = 100000;
|
||||
+
|
||||
+ adap = &i2c->adap;
|
||||
+ adap->owner = THIS_MODULE;
|
||||
+ adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
|
||||
+ adap->algo = &rt_i2c_algo;
|
||||
+ adap->retries = 3;
|
||||
+ adap->dev.parent = &pdev->dev;
|
||||
+ i2c_set_adapdata(adap, i2c);
|
||||
+ adap->dev.of_node = pdev->dev.of_node;
|
||||
+ strlcpy(adap->name, dev_name(&pdev->dev), sizeof(adap->name));
|
||||
+ adap->quirks = &rt_i2c_quirks;
|
||||
+
|
||||
+ platform_set_drvdata(pdev, i2c);
|
||||
+
|
||||
+ restart = rt_i2c_init(i2c);
|
||||
+
|
||||
+ ret = i2c_add_adapter(adap);
|
||||
+ if (ret < 0) {
|
||||
+ dev_err(&pdev->dev, "failed to add adapter\n");
|
||||
+ clk_disable_unprepare(i2c->clk);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ dev_info(&pdev->dev, "clock %uKHz, re-start %ssupport\n",
|
||||
+ i2c->cur_clk/1000, restart ? "" : "not ");
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int rt_i2c_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct rt_i2c *i2c = platform_get_drvdata(pdev);
|
||||
+
|
||||
+ i2c_del_adapter(&i2c->adap);
|
||||
+ clk_disable_unprepare(i2c->clk);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct platform_driver rt_i2c_driver = {
|
||||
+ .probe = rt_i2c_probe,
|
||||
+ .remove = rt_i2c_remove,
|
||||
+ .driver = {
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .name = "i2c-ralink",
|
||||
+ .of_match_table = i2c_rt_dt_ids,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static int __init i2c_rt_init (void)
|
||||
+{
|
||||
+ return platform_driver_register(&rt_i2c_driver);
|
||||
+}
|
||||
+subsys_initcall(i2c_rt_init);
|
||||
+
|
||||
+static void __exit i2c_rt_exit (void)
|
||||
+{
|
||||
+ platform_driver_unregister(&rt_i2c_driver);
|
||||
+}
|
||||
+module_exit(i2c_rt_exit);
|
||||
+
|
||||
+MODULE_AUTHOR("Steven Liu <steven_liu@mediatek.com>");
|
||||
+MODULE_DESCRIPTION("Ralink I2c host driver");
|
||||
+MODULE_LICENSE("GPL");
|
||||
+MODULE_ALIAS("platform:Ralink-I2C");
|
@ -1,43 +0,0 @@
|
||||
From 23147af14531cbdada194b94120ef8774f46292d Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Thu, 13 Nov 2014 19:08:40 +0100
|
||||
Subject: [PATCH 46/53] mmc: MIPS: ralink: add sdhci for mt7620a SoC
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
drivers/mmc/host/Kconfig | 2 +
|
||||
drivers/mmc/host/Makefile | 1 +
|
||||
drivers/mmc/host/mtk-mmc/Kconfig | 16 +
|
||||
drivers/mmc/host/mtk-mmc/Makefile | 42 +
|
||||
drivers/mmc/host/mtk-mmc/board.h | 137 ++
|
||||
drivers/mmc/host/mtk-mmc/dbg.c | 347 ++++
|
||||
drivers/mmc/host/mtk-mmc/dbg.h | 156 ++
|
||||
drivers/mmc/host/mtk-mmc/mt6575_sd.h | 1001 +++++++++++
|
||||
drivers/mmc/host/mtk-mmc/sd.c | 3060 ++++++++++++++++++++++++++++++++++
|
||||
9 files changed, 4762 insertions(+)
|
||||
create mode 100644 drivers/mmc/host/mtk-mmc/Kconfig
|
||||
create mode 100644 drivers/mmc/host/mtk-mmc/Makefile
|
||||
create mode 100644 drivers/mmc/host/mtk-mmc/board.h
|
||||
create mode 100644 drivers/mmc/host/mtk-mmc/dbg.c
|
||||
create mode 100644 drivers/mmc/host/mtk-mmc/dbg.h
|
||||
create mode 100644 drivers/mmc/host/mtk-mmc/mt6575_sd.h
|
||||
create mode 100644 drivers/mmc/host/mtk-mmc/sd.c
|
||||
|
||||
--- a/drivers/mmc/host/Kconfig
|
||||
+++ b/drivers/mmc/host/Kconfig
|
||||
@@ -1095,3 +1095,5 @@ config MMC_OWL
|
||||
|
||||
config MMC_SDHCI_EXTERNAL_DMA
|
||||
bool
|
||||
+
|
||||
+source "drivers/mmc/host/mtk-mmc/Kconfig"
|
||||
--- a/drivers/mmc/host/Makefile
|
||||
+++ b/drivers/mmc/host/Makefile
|
||||
@@ -3,6 +3,7 @@
|
||||
# Makefile for MMC/SD host controller drivers
|
||||
#
|
||||
|
||||
+obj-$(CONFIG_MTK_MMC) += mtk-mmc/
|
||||
obj-$(CONFIG_MMC_ARMMMCI) += armmmci.o
|
||||
armmmci-y := mmci.o
|
||||
armmmci-$(CONFIG_MMC_QCOM_DML) += mmci_qcom_dml.o
|
File diff suppressed because it is too large
Load Diff
@ -1,22 +0,0 @@
|
||||
From a7eb46e0ea4a11e4dfb56ab129bf816d1059a6c5 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Mon, 7 Dec 2015 17:31:08 +0100
|
||||
Subject: [PATCH 51/53] serial: add ugly custom baud rate hack
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
drivers/tty/serial/serial_core.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
--- a/drivers/tty/serial/serial_core.c
|
||||
+++ b/drivers/tty/serial/serial_core.c
|
||||
@@ -393,6 +393,9 @@ uart_get_baud_rate(struct uart_port *por
|
||||
break;
|
||||
}
|
||||
|
||||
+ if (tty_termios_baud_rate(termios) == 2500000)
|
||||
+ return 250000;
|
||||
+
|
||||
for (try = 0; try < 2; try++) {
|
||||
baud = tty_termios_baud_rate(termios);
|
||||
|
@ -1,219 +0,0 @@
|
||||
From fc8f96309c21c1bc3276427309cd7d361347d66e Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Mon, 7 Dec 2015 17:16:50 +0100
|
||||
Subject: [PATCH 52/53] pwm: add mediatek support
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
drivers/pwm/Kconfig | 9 +++
|
||||
drivers/pwm/Makefile | 1 +
|
||||
drivers/pwm/pwm-mediatek.c | 173 ++++++++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 183 insertions(+)
|
||||
create mode 100644 drivers/pwm/pwm-mediatek.c
|
||||
|
||||
--- a/drivers/pwm/Kconfig
|
||||
+++ b/drivers/pwm/Kconfig
|
||||
@@ -383,6 +383,15 @@ config PWM_MEDIATEK
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called pwm-mediatek.
|
||||
|
||||
+config PWM_MEDIATEK_RAMIPS
|
||||
+ tristate "Mediatek PWM support"
|
||||
+ depends on RALINK && OF
|
||||
+ help
|
||||
+ Generic PWM framework driver for Mediatek ARM SoC.
|
||||
+
|
||||
+ To compile this driver as a module, choose M here: the module
|
||||
+ will be called pwm-mxs.
|
||||
+
|
||||
config PWM_MXS
|
||||
tristate "Freescale MXS PWM support"
|
||||
depends on ARCH_MXS || COMPILE_TEST
|
||||
--- a/drivers/pwm/Makefile
|
||||
+++ b/drivers/pwm/Makefile
|
||||
@@ -33,6 +33,7 @@ obj-$(CONFIG_PWM_LPSS_PCI) += pwm-lpss-p
|
||||
obj-$(CONFIG_PWM_LPSS_PLATFORM) += pwm-lpss-platform.o
|
||||
obj-$(CONFIG_PWM_MESON) += pwm-meson.o
|
||||
obj-$(CONFIG_PWM_MEDIATEK) += pwm-mediatek.o
|
||||
+obj-$(CONFIG_PWM_MEDIATEK_RAMIPS) += pwm-mediatek-ramips.o
|
||||
obj-$(CONFIG_PWM_MTK_DISP) += pwm-mtk-disp.o
|
||||
obj-$(CONFIG_PWM_MXS) += pwm-mxs.o
|
||||
obj-$(CONFIG_PWM_NTXEC) += pwm-ntxec.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/pwm/pwm-mediatek-ramips.c
|
||||
@@ -0,0 +1,175 @@
|
||||
+/*
|
||||
+ * Mediatek Pulse Width Modulator driver
|
||||
+ *
|
||||
+ * Copyright (C) 2015 John Crispin <blogic@openwrt.org>
|
||||
+ *
|
||||
+ * This file is licensed under the terms of the GNU General Public
|
||||
+ * License version 2. This program is licensed "as is" without any
|
||||
+ * warranty of any kind, whether express or implied.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/err.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/ioport.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/pwm.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/types.h>
|
||||
+
|
||||
+#define NUM_PWM 4
|
||||
+
|
||||
+/* PWM registers and bits definitions */
|
||||
+#define PWMCON 0x00
|
||||
+#define PWMHDUR 0x04
|
||||
+#define PWMLDUR 0x08
|
||||
+#define PWMGDUR 0x0c
|
||||
+#define PWMWAVENUM 0x28
|
||||
+#define PWMDWIDTH 0x2c
|
||||
+#define PWMTHRES 0x30
|
||||
+
|
||||
+/**
|
||||
+ * struct mtk_pwm_chip - struct representing pwm chip
|
||||
+ *
|
||||
+ * @mmio_base: base address of pwm chip
|
||||
+ * @chip: linux pwm chip representation
|
||||
+ */
|
||||
+struct mtk_pwm_chip {
|
||||
+ void __iomem *mmio_base;
|
||||
+ struct pwm_chip chip;
|
||||
+};
|
||||
+
|
||||
+static inline struct mtk_pwm_chip *to_mtk_pwm_chip(struct pwm_chip *chip)
|
||||
+{
|
||||
+ return container_of(chip, struct mtk_pwm_chip, chip);
|
||||
+}
|
||||
+
|
||||
+static inline u32 mtk_pwm_readl(struct mtk_pwm_chip *chip, unsigned int num,
|
||||
+ unsigned long offset)
|
||||
+{
|
||||
+ return ioread32(chip->mmio_base + 0x10 + (num * 0x40) + offset);
|
||||
+}
|
||||
+
|
||||
+static inline void mtk_pwm_writel(struct mtk_pwm_chip *chip,
|
||||
+ unsigned int num, unsigned long offset,
|
||||
+ unsigned long val)
|
||||
+{
|
||||
+ iowrite32(val, chip->mmio_base + 0x10 + (num * 0x40) + offset);
|
||||
+}
|
||||
+
|
||||
+static int mtk_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
+ int duty_ns, int period_ns)
|
||||
+{
|
||||
+ struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip);
|
||||
+ u32 resolution = 100 / 4;
|
||||
+ u32 clkdiv = 0;
|
||||
+
|
||||
+ while (period_ns / resolution > 8191) {
|
||||
+ clkdiv++;
|
||||
+ resolution *= 2;
|
||||
+ }
|
||||
+
|
||||
+ if (clkdiv > 7)
|
||||
+ return -1;
|
||||
+
|
||||
+ mtk_pwm_writel(pc, pwm->hwpwm, PWMCON, BIT(15) | BIT(3) | clkdiv);
|
||||
+ mtk_pwm_writel(pc, pwm->hwpwm, PWMDWIDTH, period_ns / resolution);
|
||||
+ mtk_pwm_writel(pc, pwm->hwpwm, PWMTHRES, duty_ns / resolution);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int mtk_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
|
||||
+{
|
||||
+ struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip);
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = ioread32(pc->mmio_base);
|
||||
+ val |= BIT(pwm->hwpwm);
|
||||
+ iowrite32(val, pc->mmio_base);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void mtk_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
|
||||
+{
|
||||
+ struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip);
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = ioread32(pc->mmio_base);
|
||||
+ val &= ~BIT(pwm->hwpwm);
|
||||
+ iowrite32(val, pc->mmio_base);
|
||||
+}
|
||||
+
|
||||
+static const struct pwm_ops mtk_pwm_ops = {
|
||||
+ .config = mtk_pwm_config,
|
||||
+ .enable = mtk_pwm_enable,
|
||||
+ .disable = mtk_pwm_disable,
|
||||
+ .owner = THIS_MODULE,
|
||||
+};
|
||||
+
|
||||
+static int mtk_pwm_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct mtk_pwm_chip *pc;
|
||||
+ struct resource *r;
|
||||
+ int ret;
|
||||
+
|
||||
+ pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL);
|
||||
+ if (!pc)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
+ pc->mmio_base = devm_ioremap_resource(&pdev->dev, r);
|
||||
+ if (IS_ERR(pc->mmio_base))
|
||||
+ return PTR_ERR(pc->mmio_base);
|
||||
+
|
||||
+ platform_set_drvdata(pdev, pc);
|
||||
+
|
||||
+ pc->chip.dev = &pdev->dev;
|
||||
+ pc->chip.ops = &mtk_pwm_ops;
|
||||
+ pc->chip.base = -1;
|
||||
+ pc->chip.npwm = NUM_PWM;
|
||||
+
|
||||
+ ret = pwmchip_add(&pc->chip);
|
||||
+ if (ret < 0)
|
||||
+ dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int mtk_pwm_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct mtk_pwm_chip *pc = platform_get_drvdata(pdev);
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < NUM_PWM; i++)
|
||||
+ pwm_disable(&pc->chip.pwms[i]);
|
||||
+
|
||||
+ pwmchip_remove(&pc->chip);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id mtk_pwm_of_match[] = {
|
||||
+ { .compatible = "mediatek,mt7628-pwm" },
|
||||
+ { }
|
||||
+};
|
||||
+
|
||||
+MODULE_DEVICE_TABLE(of, mtk_pwm_of_match);
|
||||
+
|
||||
+static struct platform_driver mtk_pwm_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "mtk-pwm",
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .of_match_table = mtk_pwm_of_match,
|
||||
+ },
|
||||
+ .probe = mtk_pwm_probe,
|
||||
+ .remove = mtk_pwm_remove,
|
||||
+};
|
||||
+
|
||||
+module_platform_driver(mtk_pwm_driver);
|
||||
+
|
||||
+MODULE_LICENSE("GPL");
|
||||
+MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
|
||||
+MODULE_ALIAS("platform:mtk-pwm");
|
@ -1,15 +0,0 @@
|
||||
--- a/drivers/usb/dwc2/platform.c
|
||||
+++ b/drivers/usb/dwc2/platform.c
|
||||
@@ -508,6 +508,12 @@ static int dwc2_driver_probe(struct plat
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
+ /* Enable USB port before any regs access */
|
||||
+ if (readl(hsotg->regs + PCGCTL) & 0x0f) {
|
||||
+ writel(0x00, hsotg->regs + PCGCTL);
|
||||
+ /* TODO: mdelay(25) here? vendor driver don't use it */
|
||||
+ }
|
||||
+
|
||||
hsotg->needs_byte_swap = dwc2_check_core_endianness(hsotg);
|
||||
|
||||
retval = dwc2_get_dr_mode(hsotg);
|
@ -1,97 +0,0 @@
|
||||
--- a/drivers/misc/Makefile
|
||||
+++ b/drivers/misc/Makefile
|
||||
@@ -50,6 +50,7 @@ obj-$(CONFIG_ECHO) += echo/
|
||||
obj-$(CONFIG_CXL_BASE) += cxl/
|
||||
obj-$(CONFIG_DW_XDATA_PCIE) += dw-xdata-pcie.o
|
||||
obj-$(CONFIG_PCI_ENDPOINT_TEST) += pci_endpoint_test.o
|
||||
+obj-$(CONFIG_SOC_MT7620) += linkit.o
|
||||
obj-$(CONFIG_OCXL) += ocxl/
|
||||
obj-$(CONFIG_BCM_VK) += bcm-vk/
|
||||
obj-y += cardreader/
|
||||
--- /dev/null
|
||||
+++ b/drivers/misc/linkit.c
|
||||
@@ -0,0 +1,84 @@
|
||||
+/*
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * publishhed by the Free Software Foundation.
|
||||
+ *
|
||||
+ * Copyright (C) 2015 John Crispin <blogic@openwrt.org>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/mtd/mtd.h>
|
||||
+#include <linux/gpio.h>
|
||||
+
|
||||
+#define LINKIT_LATCH_GPIO 11
|
||||
+
|
||||
+struct linkit_hw_data {
|
||||
+ char board[16];
|
||||
+ char rev[16];
|
||||
+};
|
||||
+
|
||||
+static void sanify_string(char *s)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < 15; i++)
|
||||
+ if (s[i] <= 0x20)
|
||||
+ s[i] = '\0';
|
||||
+ s[15] = '\0';
|
||||
+}
|
||||
+
|
||||
+static int linkit_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct linkit_hw_data hw;
|
||||
+ struct mtd_info *mtd;
|
||||
+ size_t retlen;
|
||||
+ int ret;
|
||||
+
|
||||
+ mtd = get_mtd_device_nm("factory");
|
||||
+ if (IS_ERR(mtd))
|
||||
+ return PTR_ERR(mtd);
|
||||
+
|
||||
+ ret = mtd_read(mtd, 0x400, sizeof(hw), &retlen, (u_char *) &hw);
|
||||
+ put_mtd_device(mtd);
|
||||
+
|
||||
+ sanify_string(hw.board);
|
||||
+ sanify_string(hw.rev);
|
||||
+
|
||||
+ dev_info(&pdev->dev, "Version : %s\n", hw.board);
|
||||
+ dev_info(&pdev->dev, "Revision : %s\n", hw.rev);
|
||||
+
|
||||
+ if (!strcmp(hw.board, "LINKITS7688")) {
|
||||
+ dev_info(&pdev->dev, "setting up bootstrap latch\n");
|
||||
+
|
||||
+ if (devm_gpio_request(&pdev->dev, LINKIT_LATCH_GPIO, "bootstrap")) {
|
||||
+ dev_err(&pdev->dev, "failed to setup bootstrap gpio\n");
|
||||
+ return -1;
|
||||
+ }
|
||||
+ gpio_direction_output(LINKIT_LATCH_GPIO, 0);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id linkit_match[] = {
|
||||
+ { .compatible = "mediatek,linkit" },
|
||||
+ {},
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, linkit_match);
|
||||
+
|
||||
+static struct platform_driver linkit_driver = {
|
||||
+ .probe = linkit_probe,
|
||||
+ .driver = {
|
||||
+ .name = "mtk-linkit",
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .of_match_table = linkit_match,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+int __init linkit_init(void)
|
||||
+{
|
||||
+ return platform_driver_register(&linkit_driver);
|
||||
+}
|
||||
+late_initcall_sync(linkit_init);
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user