From 80b7978c6014c65e3ee66cb31e6ba0167f2a59b7 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Wed, 3 Aug 2016 15:03:59 -0400 Subject: MIPS: Don't specify STACKPROTECTOR in defconfigs Only one defconfig has a STACKPROTECTOR value. And it asks for the strong variant, which isn't supported by older toolchains. Due to the nature of MIPS having more platform specific code than say x86, the allyesconfig and allmodconfig aren't as effective for build coverage. So, in addition, I like to use a trivial script to walk all the defconfigs and build each one. However I will get false positives on unsupported stackprotector values with an older toolchain like gcc-4.6.3. As in this instance I am just using the compiler as a glorified syntax checker on a machine where I build a bunch of other arch for the same reason, there is no real motivation to get a newer toolchain for improved optimization etc. Since there is only one of them, and there is nothing about these settings that are board/platform specific, I propose we just eliminate the existing instance and take the default. Signed-off-by: Paul Gortmaker Acked-by: James Hartley Cc: Ionela Voinescu Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/13846/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/configs/pistachio_defconfig b/arch/mips/configs/pistachio_defconfig index 8b74291..6986313 100644 --- a/arch/mips/configs/pistachio_defconfig +++ b/arch/mips/configs/pistachio_defconfig @@ -29,7 +29,6 @@ CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_EMBEDDED=y # CONFIG_COMPAT_BRK is not set CONFIG_PROFILING=y -CONFIG_CC_STACKPROTECTOR_STRONG=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y -- cgit v0.10.2 From 5035dd83cc57c7789ad38e0fe46b1e5796ca9079 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= Date: Wed, 3 Aug 2016 11:58:24 +0200 Subject: MIPS: BMIPS: add missing bcm97435svmb to DT_NONE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 380e4270 added support for bcm97435svmb.dtb but missed adding it to DT_NONE. Also refactor DT_NONE dtbs in order to add larger names in the future. Signed-off-by: Álvaro Fernández Rojas Cc: f.fainelli@gmail.com Cc: jogo@openwrt.org Cc: cernekee@gmail.com Cc: robh@kernel.org Cc: simon@fire.lp0.eu Cc: john@phrozen.org Cc: linux-kernel@vger.kernel.org Cc: devicetree@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/13839/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/boot/dts/brcm/Makefile b/arch/mips/boot/dts/brcm/Makefile index fda9d38..87e07e2 100644 --- a/arch/mips/boot/dts/brcm/Makefile +++ b/arch/mips/boot/dts/brcm/Makefile @@ -12,19 +12,20 @@ dtb-$(CONFIG_DT_BCM97420C) += bcm97420c.dtb dtb-$(CONFIG_DT_BCM97425SVMB) += bcm97425svmb.dtb dtb-$(CONFIG_DT_BCM97435SVMB) += bcm97435svmb.dtb -dtb-$(CONFIG_DT_NONE) += \ - bcm93384wvg.dtb \ - bcm93384wvg_viper.dtb \ - bcm96358nb4ser.dtb \ - bcm96368mvwg.dtb \ - bcm9ejtagprb.dtb \ - bcm97125cbmb.dtb \ - bcm97346dbsmb.dtb \ - bcm97358svmb.dtb \ - bcm97360svmb.dtb \ - bcm97362svmb.dtb \ - bcm97420c.dtb \ - bcm97425svmb.dtb +dtb-$(CONFIG_DT_NONE) += \ + bcm93384wvg.dtb \ + bcm93384wvg_viper.dtb \ + bcm96358nb4ser.dtb \ + bcm96368mvwg.dtb \ + bcm9ejtagprb.dtb \ + bcm97125cbmb.dtb \ + bcm97346dbsmb.dtb \ + bcm97358svmb.dtb \ + bcm97360svmb.dtb \ + bcm97362svmb.dtb \ + bcm97420c.dtb \ + bcm97425svmb.dtb \ + bcm97435svmb.dtb obj-y += $(patsubst %.dtb, %.dtb.o, $(dtb-y)) -- cgit v0.10.2 From 695835511f96599911f5ab28329e75a598a1116b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= Date: Wed, 3 Aug 2016 11:58:25 +0200 Subject: MIPS: BMIPS: rename bcm96358nb4ser to bcm6358-neufbox4-sercom MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The prefix bcm9* should only be used for reference and evaluation boards from Broadcom. Also adds missing console output to bootargs. Signed-off-by: Álvaro Fernández Rojas Cc: f.fainelli@gmail.com Cc: jogo@openwrt.org Cc: cernekee@gmail.com Cc: robh@kernel.org Cc: simon@fire.lp0.eu Cc: john@phrozen.org Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Cc: devicetree@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/13841/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/bmips/Kconfig b/arch/mips/bmips/Kconfig index 264328d..c8f1427 100644 --- a/arch/mips/bmips/Kconfig +++ b/arch/mips/bmips/Kconfig @@ -21,10 +21,6 @@ config DT_BCM93384WVG_VIPER bool "BCM93384WVG Viper CPU (EXPERIMENTAL)" select BUILTIN_DTB -config DT_BCM96358NB4SER - bool "BCM96358NB4SER" - select BUILTIN_DTB - config DT_BCM96368MVWG bool "BCM96368MVWG" select BUILTIN_DTB @@ -65,6 +61,10 @@ config DT_BCM97435SVMB bool "BCM97435SVMB" select BUILTIN_DTB +config DT_SFR_NEUFBOX4_SERCOMM + bool "SFR Neufbox 4 (Sercomm)" + select BUILTIN_DTB + endchoice endif diff --git a/arch/mips/boot/dts/brcm/Makefile b/arch/mips/boot/dts/brcm/Makefile index 87e07e2..0abe298 100644 --- a/arch/mips/boot/dts/brcm/Makefile +++ b/arch/mips/boot/dts/brcm/Makefile @@ -1,6 +1,5 @@ dtb-$(CONFIG_DT_BCM93384WVG) += bcm93384wvg.dtb dtb-$(CONFIG_DT_BCM93384WVG_VIPER) += bcm93384wvg_viper.dtb -dtb-$(CONFIG_DT_BCM96358NB4SER) += bcm96358nb4ser.dtb dtb-$(CONFIG_DT_BCM96368MVWG) += bcm96368mvwg.dtb dtb-$(CONFIG_DT_BCM9EJTAGPRB) += bcm9ejtagprb.dtb dtb-$(CONFIG_DT_BCM97125CBMB) += bcm97125cbmb.dtb @@ -11,8 +10,10 @@ dtb-$(CONFIG_DT_BCM97362SVMB) += bcm97362svmb.dtb dtb-$(CONFIG_DT_BCM97420C) += bcm97420c.dtb dtb-$(CONFIG_DT_BCM97425SVMB) += bcm97425svmb.dtb dtb-$(CONFIG_DT_BCM97435SVMB) += bcm97435svmb.dtb +dtb-$(CONFIG_DT_SFR_NEUFBOX4_SERCOMM) += bcm6358-neufbox4-sercomm.dtb dtb-$(CONFIG_DT_NONE) += \ + bcm6358-neufbox4-sercomm.dtb \ bcm93384wvg.dtb \ bcm93384wvg_viper.dtb \ bcm96358nb4ser.dtb \ diff --git a/arch/mips/boot/dts/brcm/bcm6358-neufbox4-sercomm.dts b/arch/mips/boot/dts/brcm/bcm6358-neufbox4-sercomm.dts new file mode 100644 index 0000000..702eae2 --- /dev/null +++ b/arch/mips/boot/dts/brcm/bcm6358-neufbox4-sercomm.dts @@ -0,0 +1,47 @@ +/dts-v1/; + +/include/ "bcm6358.dtsi" + +/ { + compatible = "sfr,nb4-ser", "brcm,bcm6358"; + model = "SFR Neufbox 4 (Sercomm)"; + + memory@0 { + device_type = "memory"; + reg = <0x00000000 0x02000000>; + }; + + chosen { + bootargs = "console=ttyS0,115200"; + stdout-path = &uart0; + }; +}; + +&leds0 { + status = "ok"; + + led@0 { + reg = <0>; + active-low; + label = "nb4-ser:white:alarm"; + }; + led@2 { + reg = <2>; + active-low; + label = "nb4-ser:white:tv"; + }; + led@3 { + reg = <3>; + active-low; + label = "nb4-ser:white:tel"; + }; + led@4 { + reg = <4>; + active-low; + label = "nb4-ser:white:adsl"; + }; +}; + +&uart0 { + status = "okay"; +}; diff --git a/arch/mips/boot/dts/brcm/bcm96358nb4ser.dts b/arch/mips/boot/dts/brcm/bcm96358nb4ser.dts deleted file mode 100644 index f412117..0000000 --- a/arch/mips/boot/dts/brcm/bcm96358nb4ser.dts +++ /dev/null @@ -1,46 +0,0 @@ -/dts-v1/; - -/include/ "bcm6358.dtsi" - -/ { - compatible = "sfr,nb4-ser", "brcm,bcm6358"; - model = "SFR Neufbox 4 (Sercomm)"; - - memory@0 { - device_type = "memory"; - reg = <0x00000000 0x02000000>; - }; - - chosen { - stdout-path = &uart0; - }; -}; - -&leds0 { - status = "ok"; - - led@0 { - reg = <0>; - active-low; - label = "nb4-ser:white:alarm"; - }; - led@2 { - reg = <2>; - active-low; - label = "nb4-ser:white:tv"; - }; - led@3 { - reg = <3>; - active-low; - label = "nb4-ser:white:tel"; - }; - led@4 { - reg = <4>; - active-low; - label = "nb4-ser:white:adsl"; - }; -}; - -&uart0 { - status = "okay"; -}; -- cgit v0.10.2 From 786e19a88895b6401313adfd5bc72789dc44f631 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= Date: Wed, 3 Aug 2016 11:58:26 +0200 Subject: MIPS: BMIPS: Add device tree example for BCM63268 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds a device tree example for Comtrend VR-3032u, which also serves as a real example for brcm,bcm6328-leds. Signed-off-by: Álvaro Fernández Rojas Cc: f.fainelli@gmail.com Cc: jogo@openwrt.org Cc: cernekee@gmail.com Cc: robh@kernel.org Cc: simon@fire.lp0.eu Cc: john@phrozen.org Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Cc: devicetree@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/13842/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/bmips/Kconfig b/arch/mips/bmips/Kconfig index c8f1427..6a0946c 100644 --- a/arch/mips/bmips/Kconfig +++ b/arch/mips/bmips/Kconfig @@ -61,6 +61,10 @@ config DT_BCM97435SVMB bool "BCM97435SVMB" select BUILTIN_DTB +config DT_COMTREND_VR3032U + bool "Comtrend VR-3032u" + select BUILTIN_DTB + config DT_SFR_NEUFBOX4_SERCOMM bool "SFR Neufbox 4 (Sercomm)" select BUILTIN_DTB diff --git a/arch/mips/boot/dts/brcm/Makefile b/arch/mips/boot/dts/brcm/Makefile index 0abe298..8281ec6 100644 --- a/arch/mips/boot/dts/brcm/Makefile +++ b/arch/mips/boot/dts/brcm/Makefile @@ -10,10 +10,12 @@ dtb-$(CONFIG_DT_BCM97362SVMB) += bcm97362svmb.dtb dtb-$(CONFIG_DT_BCM97420C) += bcm97420c.dtb dtb-$(CONFIG_DT_BCM97425SVMB) += bcm97425svmb.dtb dtb-$(CONFIG_DT_BCM97435SVMB) += bcm97435svmb.dtb +dtb-$(CONFIG_DT_COMTREND_VR3032U) += bcm63268-comtrend-vr-3032u.dtb dtb-$(CONFIG_DT_SFR_NEUFBOX4_SERCOMM) += bcm6358-neufbox4-sercomm.dtb dtb-$(CONFIG_DT_NONE) += \ bcm6358-neufbox4-sercomm.dtb \ + bcm63268-comtrend-vr-3032u.dtb \ bcm93384wvg.dtb \ bcm93384wvg_viper.dtb \ bcm96358nb4ser.dtb \ diff --git a/arch/mips/boot/dts/brcm/bcm63268-comtrend-vr-3032u.dts b/arch/mips/boot/dts/brcm/bcm63268-comtrend-vr-3032u.dts new file mode 100644 index 0000000..430d35c --- /dev/null +++ b/arch/mips/boot/dts/brcm/bcm63268-comtrend-vr-3032u.dts @@ -0,0 +1,108 @@ +/dts-v1/; + +/include/ "bcm63268.dtsi" + +/ { + compatible = "comtrend,vr-3032u", "brcm,bcm63268"; + model = "Comtrend VR-3032u"; + + memory@0 { + device_type = "memory"; + reg = <0x00000000 0x04000000>; + }; + + chosen { + bootargs = "console=ttyS0,115200"; + stdout-path = &uart0; + }; +}; + +&leds0 { + status = "ok"; + brcm,serial-leds; + brcm,serial-dat-low; + brcm,serial-shift-inv; + + led@0 { + reg = <0>; + brcm,hardware-controlled; + brcm,link-signal-sources = <0>; + /* GPHY0 Speed 0 */ + }; + led@1 { + reg = <1>; + brcm,hardware-controlled; + brcm,link-signal-sources = <1>; + /* GPHY0 Speed 1 */ + }; + led@2 { + reg = <2>; + active-low; + label = "vr-3032u:red:inet"; + }; + led@3 { + reg = <3>; + active-low; + label = "vr-3032u:green:dsl"; + }; + led@4 { + reg = <4>; + active-low; + label = "vr-3032u:green:usb"; + }; + led@7 { + reg = <7>; + active-low; + label = "vr-3032u:green:wps"; + }; + led@8 { + reg = <8>; + active-low; + label = "vr-3032u:green:inet"; + }; + led@9 { + reg = <9>; + brcm,hardware-controlled; + /* EPHY0 Activity */ + }; + led@10 { + reg = <10>; + brcm,hardware-controlled; + /* EPHY1 Activity */ + }; + led@11 { + reg = <11>; + brcm,hardware-controlled; + /* EPHY2 Activity */ + }; + led@12 { + reg = <12>; + brcm,hardware-controlled; + /* GPHY0 Activity */ + }; + led@13 { + reg = <13>; + brcm,hardware-controlled; + /* EPHY0 Speed */ + }; + led@14 { + reg = <14>; + brcm,hardware-controlled; + /* EPHY1 Speed */ + }; + led@15 { + reg = <15>; + brcm,hardware-controlled; + /* EPHY2 Speed */ + }; + led@20 { + reg = <20>; + active-low; + label = "vr-3032u:green:power"; + default-state = "on"; + }; +}; + +&uart0 { + status = "okay"; +}; diff --git a/arch/mips/boot/dts/brcm/bcm63268.dtsi b/arch/mips/boot/dts/brcm/bcm63268.dtsi new file mode 100644 index 0000000..7e6bf2c --- /dev/null +++ b/arch/mips/boot/dts/brcm/bcm63268.dtsi @@ -0,0 +1,134 @@ +/ { + #address-cells = <1>; + #size-cells = <1>; + compatible = "brcm,bcm63268"; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + mips-hpt-frequency = <200000000>; + + cpu@0 { + compatible = "brcm,bmips4350"; + device_type = "cpu"; + reg = <0>; + }; + + cpu@1 { + compatible = "brcm,bmips4350"; + device_type = "cpu"; + reg = <1>; + }; + }; + + clocks { + periph_clk: periph-clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <50000000>; + }; + }; + + aliases { + serial0 = &uart0; + serial1 = &uart1; + }; + + cpu_intc: interrupt-controller { + #address-cells = <0>; + compatible = "mti,cpu-interrupt-controller"; + + interrupt-controller; + #interrupt-cells = <1>; + }; + + ubus { + #address-cells = <1>; + #size-cells = <1>; + + compatible = "simple-bus"; + ranges; + + periph_cntl: syscon@10000000 { + compatible = "syscon"; + reg = <0x10000000 0x14>; + native-endian; + }; + + reboot: syscon-reboot@10000008 { + compatible = "syscon-reboot"; + regmap = <&periph_cntl>; + offset = <0x8>; + mask = <0x1>; + }; + + periph_intc: interrupt-controller@10000020 { + compatible = "brcm,bcm6345-l1-intc"; + reg = <0x10000020 0x20>, + <0x10000040 0x20>; + + interrupt-controller; + #interrupt-cells = <1>; + + interrupt-parent = <&cpu_intc>; + interrupts = <2>, <3>; + }; + + uart0: serial@10000180 { + compatible = "brcm,bcm6345-uart"; + reg = <0x10000180 0x18>; + + interrupt-parent = <&periph_intc>; + interrupts = <5>; + + clocks = <&periph_clk>; + + status = "disabled"; + }; + + uart1: serial@100001a0 { + compatible = "brcm,bcm6345-uart"; + reg = <0x100001a0 0x18>; + + interrupt-parent = <&periph_intc>; + interrupts = <34>; + + clocks = <&periph_clk>; + + status = "disabled"; + }; + + leds0: led-controller@10001900 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "brcm,bcm6328-leds"; + reg = <0x10001900 0x24>; + + status = "disabled"; + }; + + ehci: usb@10002500 { + compatible = "brcm,bcm63268-ehci", "generic-ehci"; + reg = <0x10002500 0x100>; + big-endian; + + interrupt-parent = <&periph_intc>; + interrupts = <10>; + + status = "disabled"; + }; + + ohci: usb@10002600 { + compatible = "brcm,bcm63268-ohci", "generic-ohci"; + reg = <0x10002600 0x100>; + big-endian; + no-big-frame-no; + + interrupt-parent = <&periph_intc>; + interrupts = <9>; + + status = "disabled"; + }; + }; +}; -- cgit v0.10.2 From 4bac0e2afc7b7603c1781733629254d7a6b9a83c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= Date: Wed, 3 Aug 2016 11:58:27 +0200 Subject: MIPS: BMIPS: Add BCM3368 support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BCM3368 has a shared TLB which conflicts with current SMP support, so it must be disabled for now. Signed-off-by: Álvaro Fernández Rojas Cc: f.fainelli@gmail.com Cc: jogo@openwrt.org Cc: cernekee@gmail.com Cc: robh@kernel.org Cc: simon@fire.lp0.eu Cc: john@phrozen.org Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Cc: devicetree@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/13840/ Signed-off-by: Ralf Baechle diff --git a/Documentation/devicetree/bindings/mips/brcm/soc.txt b/Documentation/devicetree/bindings/mips/brcm/soc.txt index 4a7e030..65bc572 100644 --- a/Documentation/devicetree/bindings/mips/brcm/soc.txt +++ b/Documentation/devicetree/bindings/mips/brcm/soc.txt @@ -2,7 +2,7 @@ Required properties: -- compatible: "brcm,bcm3384", "brcm,bcm33843" +- compatible: "brcm,bcm3368", "brcm,bcm3384", "brcm,bcm33843" "brcm,bcm3384-viper", "brcm,bcm33843-viper" "brcm,bcm6328", "brcm,bcm6358", "brcm,bcm6368", "brcm,bcm63168", "brcm,bcm63268", diff --git a/arch/mips/bmips/setup.c b/arch/mips/bmips/setup.c index 6776042..e219bc4 100644 --- a/arch/mips/bmips/setup.c +++ b/arch/mips/bmips/setup.c @@ -98,7 +98,7 @@ static void bcm6328_quirks(void) static void bcm6358_quirks(void) { /* - * BCM6358 needs special handling for its shared TLB, so + * BCM3368/BCM6358 need special handling for their shared TLB, so * disable SMP for now */ bmips_smp_enabled = 0; @@ -110,6 +110,7 @@ static void bcm6368_quirks(void) } static const struct bmips_quirk bmips_quirk_list[] = { + { "brcm,bcm3368", &bcm6358_quirks }, { "brcm,bcm3384-viper", &bcm3384_viper_quirks }, { "brcm,bcm33843-viper", &bcm3384_viper_quirks }, { "brcm,bcm6328", &bcm6328_quirks }, -- cgit v0.10.2 From 484d83b3d6a0b49b5f26bd9a375b9a1575e09682 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= Date: Wed, 3 Aug 2016 11:58:28 +0200 Subject: MIPS: BMIPS: Add device tree example for BCM3368 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds a device tree example for Netgear CVG834G. Signed-off-by: Álvaro Fernández Rojas Cc: f.fainelli@gmail.com Cc: jogo@openwrt.org Cc: cernekee@gmail.com Cc: robh@kernel.org Cc: simon@fire.lp0.eu Cc: john@phrozen.org Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Cc: devicetree@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/13843/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/bmips/Kconfig b/arch/mips/bmips/Kconfig index 6a0946c..f499fd2 100644 --- a/arch/mips/bmips/Kconfig +++ b/arch/mips/bmips/Kconfig @@ -65,6 +65,10 @@ config DT_COMTREND_VR3032U bool "Comtrend VR-3032u" select BUILTIN_DTB +config DT_NETGEAR_CVG834G + bool "NETGEAR CVG834G" + select BUILTIN_DTB + config DT_SFR_NEUFBOX4_SERCOMM bool "SFR Neufbox 4 (Sercomm)" select BUILTIN_DTB diff --git a/arch/mips/boot/dts/brcm/Makefile b/arch/mips/boot/dts/brcm/Makefile index 8281ec6..a698e84 100644 --- a/arch/mips/boot/dts/brcm/Makefile +++ b/arch/mips/boot/dts/brcm/Makefile @@ -11,9 +11,11 @@ dtb-$(CONFIG_DT_BCM97420C) += bcm97420c.dtb dtb-$(CONFIG_DT_BCM97425SVMB) += bcm97425svmb.dtb dtb-$(CONFIG_DT_BCM97435SVMB) += bcm97435svmb.dtb dtb-$(CONFIG_DT_COMTREND_VR3032U) += bcm63268-comtrend-vr-3032u.dtb +dtb-$(CONFIG_DT_NETGEAR_CVG834G) += bcm3368-netgear-cvg834g.dtb dtb-$(CONFIG_DT_SFR_NEUFBOX4_SERCOMM) += bcm6358-neufbox4-sercomm.dtb dtb-$(CONFIG_DT_NONE) += \ + bcm3368-netgear-cvg834g.dtb \ bcm6358-neufbox4-sercomm.dtb \ bcm63268-comtrend-vr-3032u.dtb \ bcm93384wvg.dtb \ diff --git a/arch/mips/boot/dts/brcm/bcm3368-netgear-cvg834g.dts b/arch/mips/boot/dts/brcm/bcm3368-netgear-cvg834g.dts new file mode 100644 index 0000000..2f2e80f --- /dev/null +++ b/arch/mips/boot/dts/brcm/bcm3368-netgear-cvg834g.dts @@ -0,0 +1,22 @@ +/dts-v1/; + +/include/ "bcm3368.dtsi" + +/ { + compatible = "netgear,cvg834g", "brcm,bcm3368"; + model = "NETGEAR CVG834G"; + + memory@0 { + device_type = "memory"; + reg = <0x00000000 0x02000000>; + }; + + chosen { + bootargs = "console=ttyS0,115200"; + stdout-path = &uart0; + }; +}; + +&uart0 { + status = "okay"; +}; diff --git a/arch/mips/boot/dts/brcm/bcm3368.dtsi b/arch/mips/boot/dts/brcm/bcm3368.dtsi new file mode 100644 index 0000000..bee855c --- /dev/null +++ b/arch/mips/boot/dts/brcm/bcm3368.dtsi @@ -0,0 +1,101 @@ +/ { + #address-cells = <1>; + #size-cells = <1>; + compatible = "brcm,bcm3368"; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + mips-hpt-frequency = <150000000>; + + cpu@0 { + compatible = "brcm,bmips4350"; + device_type = "cpu"; + reg = <0>; + }; + + cpu@1 { + compatible = "brcm,bmips4350"; + device_type = "cpu"; + reg = <1>; + }; + }; + + clocks { + periph_clk: periph-clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <50000000>; + }; + }; + + aliases { + serial0 = &uart0; + serial1 = &uart1; + }; + + cpu_intc: interrupt-controller { + #address-cells = <0>; + compatible = "mti,cpu-interrupt-controller"; + + interrupt-controller; + #interrupt-cells = <1>; + }; + + ubus { + #address-cells = <1>; + #size-cells = <1>; + + compatible = "simple-bus"; + ranges; + + periph_cntl: syscon@fff8c000 { + compatible = "syscon"; + reg = <0xfff8c000 0xc>; + native-endian; + }; + + reboot: syscon-reboot@fff8c008 { + compatible = "syscon-reboot"; + regmap = <&periph_cntl>; + offset = <0x8>; + mask = <0x1>; + }; + + periph_intc: interrupt-controller@fff8c00c { + compatible = "brcm,bcm6345-l1-intc"; + reg = <0xfff8c00c 0x8>; + + interrupt-controller; + #interrupt-cells = <1>; + + interrupt-parent = <&cpu_intc>; + interrupts = <2>; + }; + + uart0: serial@fff8c100 { + compatible = "brcm,bcm6345-uart"; + reg = <0xfff8c100 0x18>; + + interrupt-parent = <&periph_intc>; + interrupts = <2>; + + clocks = <&periph_clk>; + + status = "disabled"; + }; + + uart1: serial@fff8c120 { + compatible = "brcm,bcm6345-uart"; + reg = <0xfff8c120 0x18>; + + interrupt-parent = <&periph_intc>; + interrupts = <3>; + + clocks = <&periph_clk>; + + status = "disabled"; + }; + }; +}; -- cgit v0.10.2 From 8e385a66d7db14599457fdc7898403c1fa24acb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= Date: Wed, 3 Aug 2016 11:58:29 +0200 Subject: MIPS: BMIPS: Add BCM6362 support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BCM6362 is a BMIPS4350 SoC which needs the same fixup as BCM6368 in order to enable SMP support. Signed-off-by: Álvaro Fernández Rojas Cc: f.fainelli@gmail.com Cc: jogo@openwrt.org Cc: cernekee@gmail.com Cc: robh@kernel.org Cc: simon@fire.lp0.eu Cc: john@phrozen.org Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Cc: devicetree@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/13845/ Signed-off-by: Ralf Baechle diff --git a/Documentation/devicetree/bindings/mips/brcm/soc.txt b/Documentation/devicetree/bindings/mips/brcm/soc.txt index 65bc572..e4e1cd9 100644 --- a/Documentation/devicetree/bindings/mips/brcm/soc.txt +++ b/Documentation/devicetree/bindings/mips/brcm/soc.txt @@ -4,7 +4,7 @@ Required properties: - compatible: "brcm,bcm3368", "brcm,bcm3384", "brcm,bcm33843" "brcm,bcm3384-viper", "brcm,bcm33843-viper" - "brcm,bcm6328", "brcm,bcm6358", "brcm,bcm6368", + "brcm,bcm6328", "brcm,bcm6358", "brcm,bcm6362", "brcm,bcm6368", "brcm,bcm63168", "brcm,bcm63268", "brcm,bcm7125", "brcm,bcm7346", "brcm,bcm7358", "brcm,bcm7360", "brcm,bcm7362", "brcm,bcm7420", "brcm,bcm7425" diff --git a/arch/mips/bmips/setup.c b/arch/mips/bmips/setup.c index e219bc4..edf1b31 100644 --- a/arch/mips/bmips/setup.c +++ b/arch/mips/bmips/setup.c @@ -115,6 +115,7 @@ static const struct bmips_quirk bmips_quirk_list[] = { { "brcm,bcm33843-viper", &bcm3384_viper_quirks }, { "brcm,bcm6328", &bcm6328_quirks }, { "brcm,bcm6358", &bcm6358_quirks }, + { "brcm,bcm6362", &bcm6368_quirks }, { "brcm,bcm6368", &bcm6368_quirks }, { "brcm,bcm63168", &bcm6368_quirks }, { "brcm,bcm63268", &bcm6368_quirks }, -- cgit v0.10.2 From ef0c592ad099fd443d8aad36719f26f62acea18a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= Date: Wed, 3 Aug 2016 11:58:30 +0200 Subject: MIPS: BMIPS: Add device tree example for BCM6362 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds a device tree example for SFR NeufBox 6. Signed-off-by: Álvaro Fernández Rojas Cc: f.fainelli@gmail.com Cc: jogo@openwrt.org Cc: cernekee@gmail.com Cc: robh@kernel.org Cc: simon@fire.lp0.eu Cc: john@phrozen.org Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Cc: devicetree@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/13844/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/bmips/Kconfig b/arch/mips/bmips/Kconfig index f499fd2..2d60f25 100644 --- a/arch/mips/bmips/Kconfig +++ b/arch/mips/bmips/Kconfig @@ -73,6 +73,10 @@ config DT_SFR_NEUFBOX4_SERCOMM bool "SFR Neufbox 4 (Sercomm)" select BUILTIN_DTB +config DT_SFR_NEUFBOX6_SERCOMM + bool "SFR Neufbox 6 (Sercomm)" + select BUILTIN_DTB + endchoice endif diff --git a/arch/mips/boot/dts/brcm/Makefile b/arch/mips/boot/dts/brcm/Makefile index a698e84..d61bc2a 100644 --- a/arch/mips/boot/dts/brcm/Makefile +++ b/arch/mips/boot/dts/brcm/Makefile @@ -13,10 +13,12 @@ dtb-$(CONFIG_DT_BCM97435SVMB) += bcm97435svmb.dtb dtb-$(CONFIG_DT_COMTREND_VR3032U) += bcm63268-comtrend-vr-3032u.dtb dtb-$(CONFIG_DT_NETGEAR_CVG834G) += bcm3368-netgear-cvg834g.dtb dtb-$(CONFIG_DT_SFR_NEUFBOX4_SERCOMM) += bcm6358-neufbox4-sercomm.dtb +dtb-$(CONFIG_DT_SFR_NEUFBOX6_SERCOMM) += bcm6362-neufbox6-sercomm.dtb dtb-$(CONFIG_DT_NONE) += \ bcm3368-netgear-cvg834g.dtb \ bcm6358-neufbox4-sercomm.dtb \ + bcm6362-neufbox6-sercomm.dtb \ bcm63268-comtrend-vr-3032u.dtb \ bcm93384wvg.dtb \ bcm93384wvg_viper.dtb \ diff --git a/arch/mips/boot/dts/brcm/bcm6362-neufbox6-sercomm.dts b/arch/mips/boot/dts/brcm/bcm6362-neufbox6-sercomm.dts new file mode 100644 index 0000000..480f2a5 --- /dev/null +++ b/arch/mips/boot/dts/brcm/bcm6362-neufbox6-sercomm.dts @@ -0,0 +1,22 @@ +/dts-v1/; + +/include/ "bcm6362.dtsi" + +/ { + compatible = "sfr,nb6-ser", "brcm,bcm6362"; + model = "SFR NeufBox 6 (Sercomm)"; + + memory@0 { + device_type = "memory"; + reg = <0x00000000 0x08000000>; + }; + + chosen { + bootargs = "console=ttyS0,115200"; + stdout-path = &uart0; + }; +}; + +&uart0 { + status = "okay"; +}; diff --git a/arch/mips/boot/dts/brcm/bcm6362.dtsi b/arch/mips/boot/dts/brcm/bcm6362.dtsi new file mode 100644 index 0000000..c507da5 --- /dev/null +++ b/arch/mips/boot/dts/brcm/bcm6362.dtsi @@ -0,0 +1,134 @@ +/ { + #address-cells = <1>; + #size-cells = <1>; + compatible = "brcm,bcm6362"; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + mips-hpt-frequency = <200000000>; + + cpu@0 { + compatible = "brcm,bmips4350"; + device_type = "cpu"; + reg = <0>; + }; + + cpu@1 { + compatible = "brcm,bmips4350"; + device_type = "cpu"; + reg = <1>; + }; + }; + + clocks { + periph_clk: periph-clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <50000000>; + }; + }; + + aliases { + serial0 = &uart0; + serial1 = &uart1; + }; + + cpu_intc: interrupt-controller { + #address-cells = <0>; + compatible = "mti,cpu-interrupt-controller"; + + interrupt-controller; + #interrupt-cells = <1>; + }; + + ubus { + #address-cells = <1>; + #size-cells = <1>; + + compatible = "simple-bus"; + ranges; + + periph_cntl: syscon@10000000 { + compatible = "syscon"; + reg = <0x10000000 0x14>; + native-endian; + }; + + reboot: syscon-reboot@10000008 { + compatible = "syscon-reboot"; + regmap = <&periph_cntl>; + offset = <0x8>; + mask = <0x1>; + }; + + periph_intc: interrupt-controller@10000020 { + compatible = "brcm,bcm6345-l1-intc"; + reg = <0x10000020 0x10>, + <0x10000030 0x10>; + + interrupt-controller; + #interrupt-cells = <1>; + + interrupt-parent = <&cpu_intc>; + interrupts = <2>, <3>; + }; + + uart0: serial@10000100 { + compatible = "brcm,bcm6345-uart"; + reg = <0x10000100 0x18>; + + interrupt-parent = <&periph_intc>; + interrupts = <3>; + + clocks = <&periph_clk>; + + status = "disabled"; + }; + + uart1: serial@10000120 { + compatible = "brcm,bcm6345-uart"; + reg = <0x10000120 0x18>; + + interrupt-parent = <&periph_intc>; + interrupts = <4>; + + clocks = <&periph_clk>; + + status = "disabled"; + }; + + leds0: led-controller@10001900 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "brcm,bcm6328-leds"; + reg = <0x10001900 0x24>; + + status = "disabled"; + }; + + ehci: usb@10002500 { + compatible = "brcm,bcm6362-ehci", "generic-ehci"; + reg = <0x10002500 0x100>; + big-endian; + + interrupt-parent = <&periph_intc>; + interrupts = <10>; + + status = "disabled"; + }; + + ohci: usb@10002600 { + compatible = "brcm,bcm6362-ohci", "generic-ohci"; + reg = <0x10002600 0x100>; + big-endian; + no-big-frame-no; + + interrupt-parent = <&periph_intc>; + interrupts = <9>; + + status = "disabled"; + }; + }; +}; -- cgit v0.10.2 From 4c0f5a7124aa74b1a99035ca3d12f83c734e7fe8 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Tue, 24 May 2016 17:09:30 +0300 Subject: MIPS: Octeon: Take all memory into use by default. Take all memory into use by default, instead of limiting to 512 MB. Signed-off-by: Aaro Koskinen Acked-by: David Daney Cc: Sivasubramanian Palanisamy Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/13353/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c index cb16fcc..15c923d 100644 --- a/arch/mips/cavium-octeon/setup.c +++ b/arch/mips/cavium-octeon/setup.c @@ -65,7 +65,7 @@ EXPORT_SYMBOL(octeon_should_swizzle_table); extern void pci_console_init(const char *arg); #endif -static unsigned long long MAX_MEMORY = 512ull << 20; +static unsigned long long MAX_MEMORY = ULLONG_MAX; DEFINE_SEMAPHORE(octeon_bootbus_sem); EXPORT_SYMBOL(octeon_bootbus_sem); -- cgit v0.10.2 From fd6ecf42fb345e5a53fa2edc91162022e31cee41 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Tue, 24 May 2016 17:09:31 +0300 Subject: MIPS: Octeon: Rename upper case variables at setup time. Rename upper case variables. Signed-off-by: Aaro Koskinen Acked-by: David Daney Cc: Sivasubramanian Palanisamy Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/13352/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c index 15c923d..89be31b 100644 --- a/arch/mips/cavium-octeon/setup.c +++ b/arch/mips/cavium-octeon/setup.c @@ -65,7 +65,8 @@ EXPORT_SYMBOL(octeon_should_swizzle_table); extern void pci_console_init(const char *arg); #endif -static unsigned long long MAX_MEMORY = ULLONG_MAX; +static unsigned long long max_memory = ULLONG_MAX; +static unsigned long long reserve_low_mem; DEFINE_SEMAPHORE(octeon_bootbus_sem); EXPORT_SYMBOL(octeon_bootbus_sem); @@ -75,7 +76,6 @@ struct octeon_boot_descriptor *octeon_boot_desc_ptr; struct cvmx_bootinfo *octeon_bootinfo; EXPORT_SYMBOL(octeon_bootinfo); -static unsigned long long RESERVE_LOW_MEM = 0ull; #ifdef CONFIG_KEXEC #ifdef CONFIG_SMP /* @@ -125,18 +125,18 @@ static void kexec_bootmem_init(uint64_t mem_size, uint32_t low_reserved_bytes) bootmem_desc->major_version = CVMX_BOOTMEM_DESC_MAJ_VER; bootmem_desc->minor_version = CVMX_BOOTMEM_DESC_MIN_VER; - addr = (OCTEON_DDR0_BASE + RESERVE_LOW_MEM + low_reserved_bytes); + addr = (OCTEON_DDR0_BASE + reserve_low_mem + low_reserved_bytes); bootmem_desc->head_addr = 0; if (mem_size <= OCTEON_DDR0_SIZE) { __cvmx_bootmem_phy_free(addr, - mem_size - RESERVE_LOW_MEM - + mem_size - reserve_low_mem - low_reserved_bytes, 0); return; } __cvmx_bootmem_phy_free(addr, - OCTEON_DDR0_SIZE - RESERVE_LOW_MEM - + OCTEON_DDR0_SIZE - reserve_low_mem - low_reserved_bytes, 0); mem_size -= OCTEON_DDR0_SIZE; @@ -846,15 +846,15 @@ void __init prom_init(void) /* Default to 64MB in the simulator to speed things up */ if (octeon_is_simulation()) - MAX_MEMORY = 64ull << 20; + max_memory = 64ull << 20; arg = strstr(arcs_cmdline, "mem="); if (arg) { - MAX_MEMORY = memparse(arg + 4, &p); - if (MAX_MEMORY == 0) - MAX_MEMORY = 32ull << 30; + max_memory = memparse(arg + 4, &p); + if (max_memory == 0) + max_memory = 32ull << 30; if (*p == '@') - RESERVE_LOW_MEM = memparse(p + 1, &p); + reserve_low_mem = memparse(p + 1, &p); } arcs_cmdline[0] = 0; @@ -864,11 +864,11 @@ void __init prom_init(void) cvmx_phys_to_ptr(octeon_boot_desc_ptr->argv[i]); if ((strncmp(arg, "MEM=", 4) == 0) || (strncmp(arg, "mem=", 4) == 0)) { - MAX_MEMORY = memparse(arg + 4, &p); - if (MAX_MEMORY == 0) - MAX_MEMORY = 32ull << 30; + max_memory = memparse(arg + 4, &p); + if (max_memory == 0) + max_memory = 32ull << 30; if (*p == '@') - RESERVE_LOW_MEM = memparse(p + 1, &p); + reserve_low_mem = memparse(p + 1, &p); #ifdef CONFIG_KEXEC } else if (strncmp(arg, "crashkernel=", 12) == 0) { crashk_size = memparse(arg+12, &p); @@ -957,13 +957,13 @@ void __init plat_mem_setup(void) * to consistently work. */ mem_alloc_size = 4 << 20; - if (mem_alloc_size > MAX_MEMORY) - mem_alloc_size = MAX_MEMORY; + if (mem_alloc_size > max_memory) + mem_alloc_size = max_memory; /* Crashkernel ignores bootmem list. It relies on mem=X@Y option */ #ifdef CONFIG_CRASH_DUMP - add_memory_region(RESERVE_LOW_MEM, MAX_MEMORY, BOOT_MEM_RAM); - total += MAX_MEMORY; + add_memory_region(reserve_low_mem, max_memory, BOOT_MEM_RAM); + total += max_memory; #else #ifdef CONFIG_KEXEC if (crashk_size > 0) { @@ -978,7 +978,7 @@ void __init plat_mem_setup(void) */ cvmx_bootmem_lock(); while ((boot_mem_map.nr_map < BOOT_MEM_MAP_MAX) - && (total < MAX_MEMORY)) { + && (total < max_memory)) { memory = cvmx_bootmem_phy_alloc(mem_alloc_size, __pa_symbol(&_end), -1, 0x100000, -- cgit v0.10.2 From a1ca83869d4ea65afd5a6a403d5d5ec2c41ef60e Mon Sep 17 00:00:00 2001 From: Yang Ling Date: Thu, 19 May 2016 12:22:19 +0800 Subject: MIPS: Add CPU support for Loongson1C Loongson1C is a 32-bit SoC designed by Loongson Technology Co., Ltd, with many features similar to Loongson1B. Signed-off-by: Yang Ling Cc: paul.burton@imgtec.com Cc: markos.chandras@imgtec.com Cc: james.hogan@imgtec.com Cc: kumba@gentoo.org Cc: macro@imgtec.com Cc: david.daney@cavium.com Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/13303/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/include/asm/cpu-type.h b/arch/mips/include/asm/cpu-type.h index fbe1881..bdd6dc1 100644 --- a/arch/mips/include/asm/cpu-type.h +++ b/arch/mips/include/asm/cpu-type.h @@ -24,7 +24,8 @@ static inline int __pure __get_cpu_type(const int cpu_type) case CPU_LOONGSON3: #endif -#ifdef CONFIG_SYS_HAS_CPU_LOONGSON1B +#if defined(CONFIG_SYS_HAS_CPU_LOONGSON1B) || \ + defined(CONFIG_SYS_HAS_CPU_LOONGSON1C) case CPU_LOONGSON1: #endif diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h index f672df8..9a83724 100644 --- a/arch/mips/include/asm/cpu.h +++ b/arch/mips/include/asm/cpu.h @@ -240,6 +240,7 @@ #define PRID_REV_VR4130 0x0080 #define PRID_REV_34K_V1_0_2 0x0022 #define PRID_REV_LOONGSON1B 0x0020 +#define PRID_REV_LOONGSON1C 0x0020 /* Same as Loongson-1B */ #define PRID_REV_LOONGSON2E 0x0002 #define PRID_REV_LOONGSON2F 0x0003 #define PRID_REV_LOONGSON3A_R1 0x0005 -- cgit v0.10.2 From 12e3280b33fe1ada85b84f67613d03e1b6d8dbf6 Mon Sep 17 00:00:00 2001 From: Yang Ling Date: Thu, 19 May 2016 12:29:30 +0800 Subject: MIPS: Loongson1C: Add board support Adds basic platform devices for Loongson1C, including serial port and ethernet. Signed-off-by: Yang Ling Cc: keguang.zhang@gmail.com Cc: chenhc@lemote.com Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/13304/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 212ff92..6fba0ef 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -1402,6 +1402,16 @@ config CPU_LOONGSON1B The Loongson 1B is a 32-bit SoC, which implements the MIPS32 release 2 instruction set. +config CPU_LOONGSON1C + bool "Loongson 1C" + depends on SYS_HAS_CPU_LOONGSON1C + select CPU_LOONGSON1 + select ARCH_WANT_OPTIONAL_GPIOLIB + select LEDS_GPIO_REGISTER + help + The Loongson 1C is a 32-bit SoC, which implements the MIPS32 + release 2 instruction set. + config CPU_MIPS32_R1 bool "MIPS32 Release 1" depends on SYS_HAS_CPU_MIPS32_R1 @@ -1851,6 +1861,9 @@ config SYS_HAS_CPU_LOONGSON2F config SYS_HAS_CPU_LOONGSON1B bool +config SYS_HAS_CPU_LOONGSON1C + bool + config SYS_HAS_CPU_MIPS32_R1 bool diff --git a/arch/mips/include/asm/mach-loongson32/irq.h b/arch/mips/include/asm/mach-loongson32/irq.h index c1c7441..8c01b30 100644 --- a/arch/mips/include/asm/mach-loongson32/irq.h +++ b/arch/mips/include/asm/mach-loongson32/irq.h @@ -36,9 +36,14 @@ #define LS1X_IRQ(n, x) (LS1X_IRQ_BASE + (n << 5) + (x)) #define LS1X_UART0_IRQ LS1X_IRQ(0, 2) +#if defined(CONFIG_LOONGSON1_LS1B) #define LS1X_UART1_IRQ LS1X_IRQ(0, 3) #define LS1X_UART2_IRQ LS1X_IRQ(0, 4) #define LS1X_UART3_IRQ LS1X_IRQ(0, 5) +#elif defined(CONFIG_LOONGSON1_LS1C) +#define LS1X_UART1_IRQ LS1X_IRQ(0, 4) +#define LS1X_UART2_IRQ LS1X_IRQ(0, 5) +#endif #define LS1X_CAN0_IRQ LS1X_IRQ(0, 6) #define LS1X_CAN1_IRQ LS1X_IRQ(0, 7) #define LS1X_SPI0_IRQ LS1X_IRQ(0, 8) @@ -47,6 +52,9 @@ #define LS1X_DMA0_IRQ LS1X_IRQ(0, 13) #define LS1X_DMA1_IRQ LS1X_IRQ(0, 14) #define LS1X_DMA2_IRQ LS1X_IRQ(0, 15) +#if defined(CONFIG_LOONGSON1_LS1C) +#define LS1X_NAND_IRQ LS1X_IRQ(0, 16) +#endif #define LS1X_PWM0_IRQ LS1X_IRQ(0, 17) #define LS1X_PWM1_IRQ LS1X_IRQ(0, 18) #define LS1X_PWM2_IRQ LS1X_IRQ(0, 19) @@ -54,18 +62,49 @@ #define LS1X_RTC_INT0_IRQ LS1X_IRQ(0, 21) #define LS1X_RTC_INT1_IRQ LS1X_IRQ(0, 22) #define LS1X_RTC_INT2_IRQ LS1X_IRQ(0, 23) +#if defined(CONFIG_LOONGSON1_LS1B) #define LS1X_TOY_INT0_IRQ LS1X_IRQ(0, 24) #define LS1X_TOY_INT1_IRQ LS1X_IRQ(0, 25) #define LS1X_TOY_INT2_IRQ LS1X_IRQ(0, 26) #define LS1X_RTC_TICK_IRQ LS1X_IRQ(0, 27) #define LS1X_TOY_TICK_IRQ LS1X_IRQ(0, 28) +#define LS1X_UART4_IRQ LS1X_IRQ(0, 29) +#define LS1X_UART5_IRQ LS1X_IRQ(0, 30) +#elif defined(CONFIG_LOONGSON1_LS1C) +#define LS1X_UART3_IRQ LS1X_IRQ(0, 29) +#define LS1X_ADC_IRQ LS1X_IRQ(0, 30) +#define LS1X_SDIO_IRQ LS1X_IRQ(0, 31) +#endif #define LS1X_EHCI_IRQ LS1X_IRQ(1, 0) #define LS1X_OHCI_IRQ LS1X_IRQ(1, 1) +#if defined(CONFIG_LOONGSON1_LS1B) #define LS1X_GMAC0_IRQ LS1X_IRQ(1, 2) #define LS1X_GMAC1_IRQ LS1X_IRQ(1, 3) +#elif defined(CONFIG_LOONGSON1_LS1C) +#define LS1X_OTG_IRQ LS1X_IRQ(1, 2) +#define LS1X_GMAC0_IRQ LS1X_IRQ(1, 3) +#define LS1X_CAM_IRQ LS1X_IRQ(1, 4) +#define LS1X_UART4_IRQ LS1X_IRQ(1, 5) +#define LS1X_UART5_IRQ LS1X_IRQ(1, 6) +#define LS1X_UART6_IRQ LS1X_IRQ(1, 7) +#define LS1X_UART7_IRQ LS1X_IRQ(1, 8) +#define LS1X_UART8_IRQ LS1X_IRQ(1, 9) +#define LS1X_UART9_IRQ LS1X_IRQ(1, 13) +#define LS1X_UART10_IRQ LS1X_IRQ(1, 14) +#define LS1X_UART11_IRQ LS1X_IRQ(1, 15) +#define LS1X_I2C0_IRQ LS1X_IRQ(1, 17) +#define LS1X_I2C1_IRQ LS1X_IRQ(1, 18) +#define LS1X_I2C2_IRQ LS1X_IRQ(1, 19) +#endif -#define LS1X_IRQS (LS1X_IRQ(4, 31) + 1 - LS1X_IRQ_BASE) +#if defined(CONFIG_LOONGSON1_LS1B) +#define INTN 4 +#elif defined(CONFIG_LOONGSON1_LS1C) +#define INTN 5 +#endif + +#define LS1X_IRQS (LS1X_IRQ(INTN, 31) + 1 - LS1X_IRQ_BASE) #define NR_IRQS (MIPS_CPU_IRQS + LS1X_IRQS) diff --git a/arch/mips/include/asm/mach-loongson32/loongson1.h b/arch/mips/include/asm/mach-loongson32/loongson1.h index 978f6df..3584c40 100644 --- a/arch/mips/include/asm/mach-loongson32/loongson1.h +++ b/arch/mips/include/asm/mach-loongson32/loongson1.h @@ -12,7 +12,11 @@ #ifndef __ASM_MACH_LOONGSON32_LOONGSON1_H #define __ASM_MACH_LOONGSON32_LOONGSON1_H +#if defined(CONFIG_LOONGSON1_LS1B) #define DEFAULT_MEMSIZE 256 /* If no memsize provided */ +#elif defined(CONFIG_LOONGSON1_LS1C) +#define DEFAULT_MEMSIZE 32 +#endif /* Loongson 1 Register Bases */ #define LS1X_MUX_BASE 0x1fd00420 @@ -20,6 +24,7 @@ #define LS1X_GPIO0_BASE 0x1fd010c0 #define LS1X_GPIO1_BASE 0x1fd010c4 #define LS1X_DMAC_BASE 0x1fd01160 +#define LS1X_CBUS_BASE 0x1fd011c0 #define LS1X_EHCI_BASE 0x1fe00000 #define LS1X_OHCI_BASE 0x1fe08000 #define LS1X_GMAC0_BASE 0x1fe10000 diff --git a/arch/mips/include/asm/mach-loongson32/regs-clk.h b/arch/mips/include/asm/mach-loongson32/regs-clk.h index 4d56fc3..e5e8f11 100644 --- a/arch/mips/include/asm/mach-loongson32/regs-clk.h +++ b/arch/mips/include/asm/mach-loongson32/regs-clk.h @@ -18,6 +18,7 @@ #define LS1X_CLK_PLL_FREQ LS1X_CLK_REG(0x0) #define LS1X_CLK_PLL_DIV LS1X_CLK_REG(0x4) +#if defined(CONFIG_LOONGSON1_LS1B) /* Clock PLL Divisor Register Bits */ #define DIV_DC_EN BIT(31) #define DIV_DC_RST BIT(30) @@ -48,4 +49,37 @@ #define BYPASS_DDR_WIDTH 1 #define BYPASS_CPU_WIDTH 1 +#elif defined(CONFIG_LOONGSON1_LS1C) +/* PLL/SDRAM Frequency configuration register Bits */ +#define PLL_VALID BIT(31) +#define FRAC_N GENMASK(23, 16) +#define RST_TIME GENMASK(3, 2) +#define SDRAM_DIV GENMASK(1, 0) + +/* CPU/CAMERA/DC Frequency configuration register Bits */ +#define DIV_DC_EN BIT(31) +#define DIV_DC GENMASK(30, 24) +#define DIV_CAM_EN BIT(23) +#define DIV_CAM GENMASK(22, 16) +#define DIV_CPU_EN BIT(15) +#define DIV_CPU GENMASK(14, 8) +#define DIV_DC_SEL_EN BIT(5) +#define DIV_DC_SEL BIT(4) +#define DIV_CAM_SEL_EN BIT(3) +#define DIV_CAM_SEL BIT(2) +#define DIV_CPU_SEL_EN BIT(1) +#define DIV_CPU_SEL BIT(0) + +#define DIV_DC_SHIFT 24 +#define DIV_CAM_SHIFT 16 +#define DIV_CPU_SHIFT 8 +#define DIV_DDR_SHIFT 0 + +#define DIV_DC_WIDTH 7 +#define DIV_CAM_WIDTH 7 +#define DIV_CPU_WIDTH 7 +#define DIV_DDR_WIDTH 2 + +#endif + #endif /* __ASM_MACH_LOONGSON32_REGS_CLK_H */ diff --git a/arch/mips/include/asm/mach-loongson32/regs-mux.h b/arch/mips/include/asm/mach-loongson32/regs-mux.h index 7c394f9..4a0bdeb 100644 --- a/arch/mips/include/asm/mach-loongson32/regs-mux.h +++ b/arch/mips/include/asm/mach-loongson32/regs-mux.h @@ -18,6 +18,7 @@ #define LS1X_MUX_CTRL0 LS1X_MUX_REG(0x0) #define LS1X_MUX_CTRL1 LS1X_MUX_REG(0x4) +#if defined(CONFIG_LOONGSON1_LS1B) /* MUX CTRL0 Register Bits */ #define UART0_USE_PWM23 BIT(28) #define UART0_USE_PWM01 BIT(27) @@ -64,4 +65,64 @@ #define GMAC1_USE_PWM23 BIT(1) #define GMAC0_USE_PWM01 BIT(0) +#elif defined(CONFIG_LOONGSON1_LS1C) + +/* SHUT_CTRL Register Bits */ +#define UART_SPLIT GENMASK(31, 30) +#define OUTPUT_CLK GENMASK(29, 26) +#define ADC_SHUT BIT(25) +#define SDIO_SHUT BIT(24) +#define DMA2_SHUT BIT(23) +#define DMA1_SHUT BIT(22) +#define DMA0_SHUT BIT(21) +#define SPI1_SHUT BIT(20) +#define SPI0_SHUT BIT(19) +#define I2C2_SHUT BIT(18) +#define I2C1_SHUT BIT(17) +#define I2C0_SHUT BIT(16) +#define AC97_SHUT BIT(15) +#define I2S_SHUT BIT(14) +#define UART3_SHUT BIT(13) +#define UART2_SHUT BIT(12) +#define UART1_SHUT BIT(11) +#define UART0_SHUT BIT(10) +#define CAN1_SHUT BIT(9) +#define CAN0_SHUT BIT(8) +#define ECC_SHUT BIT(7) +#define GMAC_SHUT BIT(6) +#define USBHOST_SHUT BIT(5) +#define USBOTG_SHUT BIT(4) +#define SDRAM_SHUT BIT(3) +#define SRAM_SHUT BIT(2) +#define CAM_SHUT BIT(1) +#define LCD_SHUT BIT(0) + +#define UART_SPLIT_SHIFT 30 +#define OUTPUT_CLK_SHIFT 26 + +/* MISC_CTRL Register Bits */ +#define USBHOST_RSTN BIT(31) +#define PHY_INTF_SELI GENMASK(30, 28) +#define AC97_EN BIT(25) +#define SDIO_DMA_EN GENMASK(24, 23) +#define ADC_DMA_EN BIT(22) +#define SDIO_USE_SPI1 BIT(17) +#define SDIO_USE_SPI0 BIT(16) +#define SRAM_CTRL GENMASK(15, 0) + +#define PHY_INTF_SELI_SHIFT 28 +#define SDIO_DMA_EN_SHIFT 23 +#define SRAM_CTRL_SHIFT 0 + +#define LS1X_CBUS_REG(n, x) \ + ((void __iomem *)KSEG1ADDR(LS1X_CBUS_BASE + (n * 0x04) + (x))) + +#define LS1X_CBUS_FIRST(n) LS1X_CBUS_REG(n, 0x00) +#define LS1X_CBUS_SECOND(n) LS1X_CBUS_REG(n, 0x10) +#define LS1X_CBUS_THIRD(n) LS1X_CBUS_REG(n, 0x20) +#define LS1X_CBUS_FOURTHT(n) LS1X_CBUS_REG(n, 0x30) +#define LS1X_CBUS_FIFTHT(n) LS1X_CBUS_REG(n, 0x40) + +#endif + #endif /* __ASM_MACH_LOONGSON32_REGS_MUX_H */ diff --git a/arch/mips/loongson32/Kconfig b/arch/mips/loongson32/Kconfig index 7704f20..3c0c2f2 100644 --- a/arch/mips/loongson32/Kconfig +++ b/arch/mips/loongson32/Kconfig @@ -19,6 +19,21 @@ config LOONGSON1_LS1B select USE_GENERIC_EARLY_PRINTK_8250 select COMMON_CLK +config LOONGSON1_LS1C + bool "Loongson LS1C board" + select CEVT_R4K if !MIPS_EXTERNAL_TIMER + select CSRC_R4K if !MIPS_EXTERNAL_TIMER + select SYS_HAS_CPU_LOONGSON1C + select DMA_NONCOHERENT + select BOOT_ELF32 + select IRQ_MIPS_CPU + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_LITTLE_ENDIAN + select SYS_SUPPORTS_HIGHMEM + select SYS_SUPPORTS_MIPS16 + select SYS_HAS_EARLY_PRINTK + select USE_GENERIC_EARLY_PRINTK_8250 + select COMMON_CLK endchoice menuconfig CEVT_CSRC_LS1X diff --git a/arch/mips/loongson32/Makefile b/arch/mips/loongson32/Makefile index 5f4bd6e..1ab2c5b 100644 --- a/arch/mips/loongson32/Makefile +++ b/arch/mips/loongson32/Makefile @@ -9,3 +9,9 @@ obj-$(CONFIG_MACH_LOONGSON32) += common/ # obj-$(CONFIG_LOONGSON1_LS1B) += ls1b/ + +# +# Loongson LS1C board +# + +obj-$(CONFIG_LOONGSON1_LS1C) += ls1c/ diff --git a/arch/mips/loongson32/Platform b/arch/mips/loongson32/Platform index ebb6dc2..ffe01c6 100644 --- a/arch/mips/loongson32/Platform +++ b/arch/mips/loongson32/Platform @@ -5,3 +5,4 @@ cflags-$(CONFIG_CPU_LOONGSON1) += \ platform-$(CONFIG_MACH_LOONGSON32) += loongson32/ cflags-$(CONFIG_MACH_LOONGSON32) += -I$(srctree)/arch/mips/include/asm/mach-loongson32 load-$(CONFIG_LOONGSON1_LS1B) += 0xffffffff80100000 +load-$(CONFIG_LOONGSON1_LS1C) += 0xffffffff80100000 diff --git a/arch/mips/loongson32/common/irq.c b/arch/mips/loongson32/common/irq.c index 455a770..635a4ab 100644 --- a/arch/mips/loongson32/common/irq.c +++ b/arch/mips/loongson32/common/irq.c @@ -62,12 +62,58 @@ static void ls1x_irq_unmask(struct irq_data *d) | (1 << bit), LS1X_INTC_INTIEN(n)); } +static int ls1x_irq_settype(struct irq_data *d, unsigned int type) +{ + unsigned int bit = (d->irq - LS1X_IRQ_BASE) & 0x1f; + unsigned int n = (d->irq - LS1X_IRQ_BASE) >> 5; + + switch (type) { + case IRQ_TYPE_LEVEL_HIGH: + __raw_writel(__raw_readl(LS1X_INTC_INTPOL(n)) + | (1 << bit), LS1X_INTC_INTPOL(n)); + __raw_writel(__raw_readl(LS1X_INTC_INTEDGE(n)) + & ~(1 << bit), LS1X_INTC_INTEDGE(n)); + break; + case IRQ_TYPE_LEVEL_LOW: + __raw_writel(__raw_readl(LS1X_INTC_INTPOL(n)) + & ~(1 << bit), LS1X_INTC_INTPOL(n)); + __raw_writel(__raw_readl(LS1X_INTC_INTEDGE(n)) + & ~(1 << bit), LS1X_INTC_INTEDGE(n)); + break; + case IRQ_TYPE_EDGE_RISING: + __raw_writel(__raw_readl(LS1X_INTC_INTPOL(n)) + | (1 << bit), LS1X_INTC_INTPOL(n)); + __raw_writel(__raw_readl(LS1X_INTC_INTEDGE(n)) + | (1 << bit), LS1X_INTC_INTEDGE(n)); + break; + case IRQ_TYPE_EDGE_FALLING: + __raw_writel(__raw_readl(LS1X_INTC_INTPOL(n)) + & ~(1 << bit), LS1X_INTC_INTPOL(n)); + __raw_writel(__raw_readl(LS1X_INTC_INTEDGE(n)) + | (1 << bit), LS1X_INTC_INTEDGE(n)); + break; + case IRQ_TYPE_EDGE_BOTH: + __raw_writel(__raw_readl(LS1X_INTC_INTPOL(n)) + & ~(1 << bit), LS1X_INTC_INTPOL(n)); + __raw_writel(__raw_readl(LS1X_INTC_INTEDGE(n)) + | (1 << bit), LS1X_INTC_INTEDGE(n)); + break; + case IRQ_TYPE_NONE: + break; + default: + return -EINVAL; + } + + return 0; +} + static struct irq_chip ls1x_irq_chip = { .name = "LS1X-INTC", .irq_ack = ls1x_irq_ack, .irq_mask = ls1x_irq_mask, .irq_mask_ack = ls1x_irq_mask_ack, .irq_unmask = ls1x_irq_unmask, + .irq_set_type = ls1x_irq_settype, }; static void ls1x_irq_dispatch(int n) @@ -107,7 +153,7 @@ asmlinkage void plat_irq_dispatch(void) } -struct irqaction cascade_irqaction = { +static struct irqaction cascade_irqaction = { .handler = no_action, .name = "cascade", .flags = IRQF_NO_THREAD, @@ -120,7 +166,7 @@ static void __init ls1x_irq_init(int base) /* Disable interrupts and clear pending, * setup all IRQs as high level triggered */ - for (n = 0; n < 4; n++) { + for (n = 0; n < INTN; n++) { __raw_writel(0x0, LS1X_INTC_INTIEN(n)); __raw_writel(0xffffffff, LS1X_INTC_INTCLR(n)); __raw_writel(0xffffffff, LS1X_INTC_INTPOL(n)); @@ -129,7 +175,7 @@ static void __init ls1x_irq_init(int base) } - for (n = base; n < LS1X_IRQS; n++) { + for (n = base; n < NR_IRQS; n++) { irq_set_chip_and_handler(n, &ls1x_irq_chip, handle_level_irq); } @@ -138,6 +184,9 @@ static void __init ls1x_irq_init(int base) setup_irq(INT1_IRQ, &cascade_irqaction); setup_irq(INT2_IRQ, &cascade_irqaction); setup_irq(INT3_IRQ, &cascade_irqaction); +#if defined(CONFIG_LOONGSON1_LS1C) + setup_irq(INT4_IRQ, &cascade_irqaction); +#endif } void __init arch_init_irq(void) diff --git a/arch/mips/loongson32/common/platform.c b/arch/mips/loongson32/common/platform.c index f2c714d..4d12e36 100644 --- a/arch/mips/loongson32/common/platform.c +++ b/arch/mips/loongson32/common/platform.c @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -132,6 +133,7 @@ int ls1x_eth_mux_init(struct platform_device *pdev, void *priv) val = __raw_readl(LS1X_MUX_CTRL1); +#if defined(CONFIG_LOONGSON1_LS1B) plat_dat = dev_get_platdata(&pdev->dev); if (plat_dat->bus_id) { __raw_writel(__raw_readl(LS1X_MUX_CTRL0) | GMAC1_USE_UART1 | @@ -165,6 +167,17 @@ int ls1x_eth_mux_init(struct platform_device *pdev, void *priv) val &= ~GMAC0_SHUT; } __raw_writel(val, LS1X_MUX_CTRL1); +#elif defined(CONFIG_LOONGSON1_LS1C) + plat_dat = dev_get_platdata(&pdev->dev); + + val &= ~PHY_INTF_SELI; + if (plat_dat->interface == PHY_INTERFACE_MODE_RMII) + val |= 0x4 << PHY_INTF_SELI_SHIFT; + __raw_writel(val, LS1X_MUX_CTRL1); + + val = __raw_readl(LS1X_MUX_CTRL0); + __raw_writel(val & (~GMAC_SHUT), LS1X_MUX_CTRL0); +#endif return 0; } @@ -172,7 +185,11 @@ int ls1x_eth_mux_init(struct platform_device *pdev, void *priv) static struct plat_stmmacenet_data ls1x_eth0_pdata = { .bus_id = 0, .phy_addr = -1, +#if defined(CONFIG_LOONGSON1_LS1B) .interface = PHY_INTERFACE_MODE_MII, +#elif defined(CONFIG_LOONGSON1_LS1C) + .interface = PHY_INTERFACE_MODE_RMII, +#endif .mdio_bus_data = &ls1x_mdio_bus_data, .dma_cfg = &ls1x_eth_dma_cfg, .has_gmac = 1, @@ -203,6 +220,7 @@ struct platform_device ls1x_eth0_pdev = { }, }; +#ifdef CONFIG_LOONGSON1_LS1B static struct plat_stmmacenet_data ls1x_eth1_pdata = { .bus_id = 1, .phy_addr = -1, @@ -236,6 +254,7 @@ struct platform_device ls1x_eth1_pdev = { .platform_data = &ls1x_eth1_pdata, }, }; +#endif /* CONFIG_LOONGSON1_LS1B */ /* GPIO */ static struct resource ls1x_gpio0_resources[] = { diff --git a/arch/mips/loongson32/common/setup.c b/arch/mips/loongson32/common/setup.c index 62f41af..1640744 100644 --- a/arch/mips/loongson32/common/setup.c +++ b/arch/mips/loongson32/common/setup.c @@ -22,7 +22,11 @@ const char *get_system_type(void) switch (processor_id & PRID_REV_MASK) { case PRID_REV_LOONGSON1B: +#if defined(CONFIG_LOONGSON1_LS1B) return "LOONGSON LS1B"; +#elif defined(CONFIG_LOONGSON1_LS1C) + return "LOONGSON LS1C"; +#endif default: return "LOONGSON (unknown)"; } diff --git a/arch/mips/loongson32/ls1c/Makefile b/arch/mips/loongson32/ls1c/Makefile new file mode 100644 index 0000000..891eac4 --- /dev/null +++ b/arch/mips/loongson32/ls1c/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for loongson1B based machines. +# + +obj-y += board.o diff --git a/arch/mips/loongson32/ls1c/board.c b/arch/mips/loongson32/ls1c/board.c new file mode 100644 index 0000000..3d69bd6 --- /dev/null +++ b/arch/mips/loongson32/ls1c/board.c @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2016 Ling Yang + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include + +static struct platform_device *ls1c_platform_devices[] __initdata = { + &ls1x_uart_pdev, + &ls1x_eth0_pdev, +}; + +static int __init ls1c_platform_init(void) +{ + int err; + + ls1x_serial_set_uartclk(&ls1x_uart_pdev); + + err = platform_add_devices(ls1c_platform_devices, + ARRAY_SIZE(ls1c_platform_devices)); + return err; +} + +arch_initcall(ls1c_platform_init); -- cgit v0.10.2 From 5b9a15e891b80d0ea8bdb1bb571d01af83839803 Mon Sep 17 00:00:00 2001 From: Yang Ling Date: Thu, 19 May 2016 12:31:57 +0800 Subject: MIPS: Loongson1C: Add defconfig Signed-off-by: Yang Ling Cc: keguang.zhang@gmail.com Cc: chenhc@lemote.com Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/13305/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/configs/loongson1c_defconfig b/arch/mips/configs/loongson1c_defconfig new file mode 100644 index 0000000..2304d41 --- /dev/null +++ b/arch/mips/configs/loongson1c_defconfig @@ -0,0 +1,126 @@ +CONFIG_MACH_LOONGSON32=y +CONFIG_LOONGSON1_LS1C=y +CONFIG_PREEMPT=y +# CONFIG_SECCOMP is not set +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_KERNEL_XZ=y +CONFIG_SYSVIPC=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=16 +CONFIG_NAMESPACES=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_EXPERT=y +CONFIG_PERF_EVENTS=y +# CONFIG_COMPAT_BRK is not set +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODVERSIONS=y +# CONFIG_LBDAF is not set +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +# CONFIG_SUSPEND is not set +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_SYN_COOKIES=y +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_DIAG is not set +# CONFIG_IPV6 is not set +# CONFIG_WIRELESS is not set +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +# CONFIG_STANDALONE is not set +CONFIG_MTD=y +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_BLOCK=y +CONFIG_MTD_NAND=y +CONFIG_MTD_NAND_LOONGSON1=y +CONFIG_MTD_UBI=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_SCSI=m +# CONFIG_SCSI_PROC_FS is not set +CONFIG_BLK_DEV_SD=m +# CONFIG_SCSI_LOWLEVEL is not set +CONFIG_NETDEVICES=y +# CONFIG_NET_VENDOR_BROADCOM is not set +# CONFIG_NET_VENDOR_INTEL is not set +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_SMSC is not set +CONFIG_STMMAC_ETH=y +# CONFIG_NET_VENDOR_WIZNET is not set +# CONFIG_WLAN is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_SERIO is not set +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_LEGACY_PTY_COUNT=8 +# CONFIG_DEVKMEM is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_HW_RANDOM is not set +CONFIG_GPIOLIB=y +CONFIG_GPIO_LOONGSON1=y +# CONFIG_HWMON is not set +# CONFIG_VGA_CONSOLE is not set +CONFIG_HID_GENERIC=m +CONFIG_USB_HID=m +CONFIG_USB=y +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y +CONFIG_USB_EHCI_HCD=y +# CONFIG_USB_EHCI_TT_NEWSCHED is not set +CONFIG_USB_EHCI_HCD_PLATFORM=y +CONFIG_USB_STORAGE=m +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_LOONGSON1=y +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +# CONFIG_DNOTIFY is not set +CONFIG_VFAT_FS=y +CONFIG_PROC_KCORE=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_UBIFS_FS=y +CONFIG_UBIFS_FS_ADVANCED_COMPR=y +CONFIG_UBIFS_ATIME_SUPPORT=y +CONFIG_NFS_FS=y +CONFIG_ROOT_NFS=y +CONFIG_NLS_CODEPAGE_437=m +CONFIG_NLS_ISO8859_1=m +CONFIG_DYNAMIC_DEBUG=y +# CONFIG_ENABLE_WARN_DEPRECATED is not set +# CONFIG_ENABLE_MUST_CHECK is not set +CONFIG_DEBUG_FS=y +CONFIG_MAGIC_SYSRQ=y +# CONFIG_SCHED_DEBUG is not set +# CONFIG_DEBUG_PREEMPT is not set +# CONFIG_FTRACE is not set +# CONFIG_EARLY_PRINTK is not set +# CONFIG_CRYPTO_ECHAINIV is not set +# CONFIG_CRYPTO_HW is not set -- cgit v0.10.2 From 765b06479a47529336458598809d29d59b40ab65 Mon Sep 17 00:00:00 2001 From: Matt Redfearn Date: Thu, 4 Aug 2016 17:19:38 +0100 Subject: MIPS: Move identification of VP(E) into proc.c from smp-mt.c The addition of VPE information to /proc/cpuinfo used to be in smp-mt.c. This file is not used by MIPS r6 kernels, so the Virtual Processor information was not present for these CPU types. Move the code to print VPE information into proc.c, add a case for MIPS r6 CPUS, and remove the block from smp-mt.c. Signed-off-by: Matt Redfearn Reviewed-by: Paul Burton Cc: Qais Yousef Cc: Zubair Lutfullah Kakakhel Cc: Thomas Gleixner Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/13847/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c index 97dc01b..4eff2ae 100644 --- a/arch/mips/kernel/proc.c +++ b/arch/mips/kernel/proc.c @@ -135,6 +135,13 @@ static int show_cpuinfo(struct seq_file *m, void *v) seq_printf(m, "package\t\t\t: %d\n", cpu_data[n].package); seq_printf(m, "core\t\t\t: %d\n", cpu_data[n].core); +#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_CPU_MIPSR6) + if (cpu_has_mipsmt) + seq_printf(m, "VPE\t\t\t: %d\n", cpu_data[n].vpe_id); + else if (cpu_has_vp) + seq_printf(m, "VP\t\t\t: %d\n", cpu_data[n].vpe_id); +#endif + sprintf(fmt, "VCE%%c exceptions\t\t: %s\n", cpu_has_vce ? "%u" : "not available"); seq_printf(m, fmt, 'D', vced_count); diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c index 4f9570a..e077ea3 100644 --- a/arch/mips/kernel/smp-mt.c +++ b/arch/mips/kernel/smp-mt.c @@ -289,26 +289,3 @@ struct plat_smp_ops vsmp_smp_ops = { .prepare_cpus = vsmp_prepare_cpus, }; -#ifdef CONFIG_PROC_FS -static int proc_cpuinfo_chain_call(struct notifier_block *nfb, - unsigned long action_unused, void *data) -{ - struct proc_cpuinfo_notifier_args *pcn = data; - struct seq_file *m = pcn->m; - unsigned long n = pcn->n; - - if (!cpu_has_mipsmt) - return NOTIFY_OK; - - seq_printf(m, "VPE\t\t\t: %d\n", cpu_data[n].vpe_id); - - return NOTIFY_OK; -} - -static int __init proc_cpuinfo_notifier_init(void) -{ - return proc_cpuinfo_notifier(proc_cpuinfo_chain_call, 0); -} - -subsys_initcall(proc_cpuinfo_notifier_init); -#endif -- cgit v0.10.2 From 94a2de0fdb3466f92694fcff7e494344c2a744ea Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Mon, 15 Aug 2016 19:29:09 +0200 Subject: MIPS: pci-mt7620: Delete unnecessary assignment for the field "owner" The field "owner" is set by the core. Thus delete an unneeded initialisation. Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci Signed-off-by: Markus Elfring Cc: John Crispin Cc: Matthias Brugger Cc: Julia Lawall Cc: Wei Yongjun Cc: linux-arm-kernel@lists.infradead.org Cc: linux-mediatek@lists.infradead.org Cc: linux-mips@linux-mips.org Cc: LKML Cc: kernel-janitors@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/13929/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/pci/pci-mt7620.c b/arch/mips/pci/pci-mt7620.c index 6ce8162..eb39826 100644 --- a/arch/mips/pci/pci-mt7620.c +++ b/arch/mips/pci/pci-mt7620.c @@ -413,7 +413,6 @@ static struct platform_driver mt7620_pci_driver = { .probe = mt7620_pci_probe, .driver = { .name = "mt7620-pci", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(mt7620_pci_ids), }, }; -- cgit v0.10.2 From f715677f8f130967c34ee915e13e4bf2c924c64a Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Fri, 12 Aug 2016 23:59:19 +0200 Subject: MIPS: pistachio: Remove ANDROID_TIMED_OUTPUT from defconfig. According to commit 9f6b68774f29 ("android: remove timed output/gpio driver") Signed-off-by: Fabian Frederick Cc: Rob Herring Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/13904/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/configs/pistachio_defconfig b/arch/mips/configs/pistachio_defconfig index 6986313..7d32fbb 100644 --- a/arch/mips/configs/pistachio_defconfig +++ b/arch/mips/configs/pistachio_defconfig @@ -263,7 +263,6 @@ CONFIG_DMADEVICES=y CONFIG_IMG_MDC_DMA=y CONFIG_STAGING=y CONFIG_ASHMEM=y -# CONFIG_ANDROID_TIMED_OUTPUT is not set # CONFIG_IOMMU_SUPPORT is not set CONFIG_MEMORY=y CONFIG_IIO=y -- cgit v0.10.2 From d2b965b24895bbeb9c3da59da64eaa67d2d54cc3 Mon Sep 17 00:00:00 2001 From: Matt Redfearn Date: Wed, 10 Aug 2016 17:11:03 +0100 Subject: MIPS: Delete unused file smp-gic.c Commit 7eb8c99db26c ("MIPS: Delete smp-gic.c") removed the file from the Makefile and the option to build it from KConfig, but left the file itself floating in the tree. Remove the unused source file. Signed-off-by: Matt Redfearn Cc: Qais Yousef Cc: paul.burton@imgtec.com Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/13883/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/kernel/smp-gic.c b/arch/mips/kernel/smp-gic.c deleted file mode 100644 index 9b63829..0000000 --- a/arch/mips/kernel/smp-gic.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2013 Imagination Technologies - * Author: Paul Burton - * - * Based on smp-cmp.c: - * Copyright (C) 2007 MIPS Technologies, Inc. - * Author: Chris Dearman (chris@mips.com) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include - -#include -#include - -void gic_send_ipi_single(int cpu, unsigned int action) -{ - unsigned long flags; - unsigned int intr; - unsigned int core = cpu_data[cpu].core; - - pr_debug("CPU%d: %s cpu %d action %u status %08x\n", - smp_processor_id(), __func__, cpu, action, read_c0_status()); - - local_irq_save(flags); - - switch (action) { - case SMP_CALL_FUNCTION: - intr = plat_ipi_call_int_xlate(cpu); - break; - - case SMP_RESCHEDULE_YOURSELF: - intr = plat_ipi_resched_int_xlate(cpu); - break; - - default: - BUG(); - } - - gic_send_ipi(intr); - - if (mips_cpc_present() && (core != current_cpu_data.core)) { - while (!cpumask_test_cpu(cpu, &cpu_coherent_mask)) { - mips_cm_lock_other(core, 0); - mips_cpc_lock_other(core); - write_cpc_co_cmd(CPC_Cx_CMD_PWRUP); - mips_cpc_unlock_other(); - mips_cm_unlock_other(); - } - } - - local_irq_restore(flags); -} - -void gic_send_ipi_mask(const struct cpumask *mask, unsigned int action) -{ - unsigned int i; - - for_each_cpu(i, mask) - gic_send_ipi_single(i, action); -} -- cgit v0.10.2 From 191084bca8312956cc96f5ef471416c8bc08cef7 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Mon, 15 Aug 2016 16:30:52 -0400 Subject: MIPS: BCM47xx: Make serial explicitly non-modular MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Makefile entry controlling compilation of this code is "obj-y" meaning that it currently is not being built as a module by anyone. Lets remove the couple traces of modular infrastructure use, so that when reading the driver there is no doubt it is builtin-only. Since module_init translates to device_initcall in the non-modular case, the init ordering remains unchanged with this commit. We also delete the MODULE_LICENSE tag etc. since all that information was (or is now) contained at the top of the file in the comments. Signed-off-by: Paul Gortmaker Cc: Hauke Mehrtens Cc: "Rafał Miłecki" Cc: Aurelien Jarno Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/13933/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/bcm47xx/serial.c b/arch/mips/bcm47xx/serial.c index df761d3..e3c9872 100644 --- a/arch/mips/bcm47xx/serial.c +++ b/arch/mips/bcm47xx/serial.c @@ -1,4 +1,7 @@ /* + * 8250 UART probe driver for the BCM47XX platforms + * Author: Aurelien Jarno + * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. @@ -6,7 +9,6 @@ * Copyright (C) 2007 Aurelien Jarno */ -#include #include #include #include @@ -88,9 +90,4 @@ static int __init uart8250_init(void) } return -EINVAL; } - -module_init(uart8250_init); - -MODULE_AUTHOR("Aurelien Jarno "); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("8250 UART probe driver for the BCM47XX platforms"); +device_initcall(uart8250_init); -- cgit v0.10.2 From 62ee73d284e796d6df292b3df8c65e63a78a11a7 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Mon, 15 Aug 2016 16:30:53 -0400 Subject: MIPS: ralink: Make timer explicitly non-modular The Makefile entry controlling compilation of this code is "obj-y" meaning that it currently is not being built as a module by anyone. Lets remove the modular code that is essentially orphaned, so that when reading the driver there is no doubt it is builtin-only. We explicitly disallow a driver unbind, since that doesn't have a sensible use case anyway, and it allows us to drop the ".remove" code for non-modular drivers. Since module_platform_driver() uses the same init level priority as builtin_platform_driver() the init ordering remains unchanged with this commit. Also note that MODULE_DEVICE_TABLE is a no-op for non-modular code. We also delete the MODULE_LICENSE tag etc. since all that information was (or is now) contained at the top of the file in the comments. We don't replace module.h with init.h since the file already has that. Signed-off-by: Paul Gortmaker Cc: John Crispin Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/13931/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/ralink/timer.c b/arch/mips/ralink/timer.c index b0343ff..8077ff3 100644 --- a/arch/mips/ralink/timer.c +++ b/arch/mips/ralink/timer.c @@ -1,4 +1,7 @@ /* + * Ralink RT2880 timer + * Author: John Crispin + * * 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. @@ -6,7 +9,6 @@ * Copyright (C) 2013 John Crispin */ -#include #include #include #include @@ -152,33 +154,17 @@ static int rt_timer_probe(struct platform_device *pdev) return 0; } -static int rt_timer_remove(struct platform_device *pdev) -{ - struct rt_timer *rt = platform_get_drvdata(pdev); - - rt_timer_disable(rt); - rt_timer_free(rt); - - return 0; -} - static const struct of_device_id rt_timer_match[] = { { .compatible = "ralink,rt2880-timer" }, {}, }; -MODULE_DEVICE_TABLE(of, rt_timer_match); static struct platform_driver rt_timer_driver = { .probe = rt_timer_probe, - .remove = rt_timer_remove, .driver = { - .name = "rt-timer", - .of_match_table = rt_timer_match + .name = "rt-timer", + .of_match_table = rt_timer_match, + .suppress_bind_attrs = true, }, }; - -module_platform_driver(rt_timer_driver); - -MODULE_DESCRIPTION("Ralink RT2880 timer"); -MODULE_AUTHOR("John Crispin Date: Mon, 15 Aug 2016 16:30:54 -0400 Subject: MIPS: Lantiq: Make vmmc explicitly non-modular The Makefile entry controlling compilation of this code is: arch/mips/lantiq/xway/vmmc.o ---> arch/mips/lantiq/xway/Makefile:obj-y += vmmc.o ...meaning that it currently is not being built as a module by anyone. Since module_platform_driver() uses the same init level priority as builtin_platform_driver() the init ordering remains unchanged with this commit. Also note that MODULE_DEVICE_TABLE is a no-op for non-modular code. We replace module.h with export.h since the file does actually use EXPORT_SYMBOL. Signed-off-by: Paul Gortmaker Cc: John Crispin Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/13930/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/lantiq/xway/vmmc.c b/arch/mips/lantiq/xway/vmmc.c index 4625495..577ec81 100644 --- a/arch/mips/lantiq/xway/vmmc.c +++ b/arch/mips/lantiq/xway/vmmc.c @@ -6,7 +6,7 @@ * Copyright (C) 2012 John Crispin */ -#include +#include #include #include #include @@ -55,7 +55,6 @@ static const struct of_device_id vmmc_match[] = { { .compatible = "lantiq,vmmc-xway" }, {}, }; -MODULE_DEVICE_TABLE(of, vmmc_match); static struct platform_driver vmmc_driver = { .probe = vmmc_probe, @@ -64,5 +63,4 @@ static struct platform_driver vmmc_driver = { .of_match_table = vmmc_match, }, }; - -module_platform_driver(vmmc_driver); +builtin_platform_driver(vmmc_driver); -- cgit v0.10.2 From 6f42e0e384d64b5cd308fa319c6c57044f144eca Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Mon, 15 Aug 2016 16:30:55 -0400 Subject: MIPS: Lantiq: Make xrx200_phy_fw explicitly non-modular The Kconfig currently controlling compilation of this code is: arch/mips/lantiq/Kconfig:config XRX200_PHY_FW arch/mips/lantiq/Kconfig: bool "XRX200 PHY firmware loader" ...meaning that it currently is not being built as a module by anyone. Lets remove the couple traces of modular infrastructure use, so that when reading the driver there is no doubt it is builtin-only. Since module_platform_driver() uses the same init level priority as builtin_platform_driver() the init ordering remains unchanged with this commit. Also note that MODULE_DEVICE_TABLE is a no-op for non-modular code. We also delete the MODULE_LICENSE tag etc. since all that information was (or is now) contained at the top of the file in the comments. We don't replace module.h with init.h since the file doesn't need that. Signed-off-by: Paul Gortmaker Cc: John Crispin Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/13932/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/lantiq/xway/xrx200_phy_fw.c b/arch/mips/lantiq/xway/xrx200_phy_fw.c index 71e518c..f0a0f2d 100644 --- a/arch/mips/lantiq/xway/xrx200_phy_fw.c +++ b/arch/mips/lantiq/xway/xrx200_phy_fw.c @@ -1,4 +1,7 @@ /* + * Lantiq XRX200 PHY Firmware Loader + * Author: John Crispin + * * 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. @@ -8,7 +11,6 @@ #include #include -#include #include #include @@ -100,7 +102,6 @@ static const struct of_device_id xway_phy_match[] = { { .compatible = "lantiq,phy-xrx200" }, {}, }; -MODULE_DEVICE_TABLE(of, xway_phy_match); static struct platform_driver xway_phy_driver = { .probe = xway_phy_fw_probe, @@ -109,9 +110,4 @@ static struct platform_driver xway_phy_driver = { .of_match_table = xway_phy_match, }, }; - -module_platform_driver(xway_phy_driver); - -MODULE_AUTHOR("John Crispin "); -MODULE_DESCRIPTION("Lantiq XRX200 PHY Firmware Loader"); -MODULE_LICENSE("GPL"); +builtin_platform_driver(xway_phy_driver); -- cgit v0.10.2 From 9f3b8081a4763022ccfabaffc485094be0064fa4 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Mon, 15 Aug 2016 19:11:52 -0400 Subject: MIPS: Migrate exception table users off module.h and onto extable.h These files were only including module.h for exception table related functions. We've now separated that content out into its own file "extable.h" so now move over to that and avoid all the extra header content in module.h that we don't really need to compile these files. In the case of traps.c we can't dump the module.h include since it is also used to provide "print_modules". Signed-off-by: Paul Gortmaker Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/13934/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/kernel/module.c b/arch/mips/kernel/module.c index 79850e3..94627a3 100644 --- a/arch/mips/kernel/module.c +++ b/arch/mips/kernel/module.c @@ -20,6 +20,7 @@ #undef DEBUG +#include #include #include #include diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 3de85be..6061d47 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/mips/mm/extable.c b/arch/mips/mm/extable.c index 9d25d2b..e474fa2 100644 --- a/arch/mips/mm/extable.c +++ b/arch/mips/mm/extable.c @@ -5,7 +5,7 @@ * * Copyright (C) 1997, 99, 2001 - 2004 Ralf Baechle */ -#include +#include #include #include #include -- cgit v0.10.2 From 60219c563c9b62aac237631a7c9aa092e8396138 Mon Sep 17 00:00:00 2001 From: Yang Ling Date: Tue, 6 Sep 2016 10:11:38 +0800 Subject: MIPS: Add RTC support for Loongson1C board The patch adds RTC support for Loongson1C board, and enable the external crystal when the RTC is first powered up. Signed-off-by: Yang Ling Cc: keguang.zhang@gmail.com Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14214/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/include/asm/mach-loongson32/platform.h b/arch/mips/include/asm/mach-loongson32/platform.h index 672531a..7adc313 100644 --- a/arch/mips/include/asm/mach-loongson32/platform.h +++ b/arch/mips/include/asm/mach-loongson32/platform.h @@ -30,5 +30,6 @@ void __init ls1x_clk_init(void); void __init ls1x_dma_set_platdata(struct plat_ls1x_dma *pdata); void __init ls1x_nand_set_platdata(struct plat_ls1x_nand *pdata); void __init ls1x_serial_set_uartclk(struct platform_device *pdev); +void __init ls1x_rtc_set_extclk(struct platform_device *pdev); #endif /* __ASM_MACH_LOONGSON32_PLATFORM_H */ diff --git a/arch/mips/loongson32/common/platform.c b/arch/mips/loongson32/common/platform.c index 4d12e36..beff085 100644 --- a/arch/mips/loongson32/common/platform.c +++ b/arch/mips/loongson32/common/platform.c @@ -23,6 +23,10 @@ #include #include +#define LS1X_RTC_CTRL ((void __iomem *)KSEG1ADDR(LS1X_RTC_BASE + 0x40)) +#define RTC_EXTCLK_OK (BIT(5) | BIT(8)) +#define RTC_EXTCLK_EN BIT(8) + /* 8250/16550 compatible UART */ #define LS1X_UART(_id) \ { \ @@ -66,6 +70,15 @@ void __init ls1x_serial_set_uartclk(struct platform_device *pdev) p->uartclk = clk_get_rate(clk); } +void __init ls1x_rtc_set_extclk(struct platform_device *pdev) +{ + u32 val; + + val = __raw_readl(LS1X_RTC_CTRL); + if (!(val & RTC_EXTCLK_OK)) + __raw_writel(val | RTC_EXTCLK_EN, LS1X_RTC_CTRL); +} + /* CPUFreq */ static struct plat_ls1x_cpufreq ls1x_cpufreq_pdata = { .clk_name = "cpu_clk", diff --git a/arch/mips/loongson32/ls1c/Makefile b/arch/mips/loongson32/ls1c/Makefile index 891eac4..a92c6cd 100644 --- a/arch/mips/loongson32/ls1c/Makefile +++ b/arch/mips/loongson32/ls1c/Makefile @@ -1,5 +1,5 @@ # -# Makefile for loongson1B based machines. +# Makefile for loongson1C based machines. # obj-y += board.o diff --git a/arch/mips/loongson32/ls1c/board.c b/arch/mips/loongson32/ls1c/board.c index 3d69bd6..a96bed5 100644 --- a/arch/mips/loongson32/ls1c/board.c +++ b/arch/mips/loongson32/ls1c/board.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Ling Yang + * Copyright (c) 2016 Yang Ling * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -12,17 +12,16 @@ static struct platform_device *ls1c_platform_devices[] __initdata = { &ls1x_uart_pdev, &ls1x_eth0_pdev, + &ls1x_rtc_pdev, }; static int __init ls1c_platform_init(void) { - int err; - ls1x_serial_set_uartclk(&ls1x_uart_pdev); + ls1x_rtc_set_extclk(&ls1x_rtc_pdev); - err = platform_add_devices(ls1c_platform_devices, + return platform_add_devices(ls1c_platform_devices, ARRAY_SIZE(ls1c_platform_devices)); - return err; } arch_initcall(ls1c_platform_init); -- cgit v0.10.2 From db19462bb7acddd0a9881d75d960974982a454b8 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 15 Sep 2016 00:31:01 +0900 Subject: MIPS: Squash lines for simple wrapper functions Remove unneeded variables and assignments. Signed-off-by: Masahiro Yamada Cc: Boris Brezillon Cc: Brian Norris Cc: Michal Hocko Cc: Andrew Morton Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14260/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/include/asm/mach-generic/floppy.h b/arch/mips/include/asm/mach-generic/floppy.h index e2561d9..9ec2f6a 100644 --- a/arch/mips/include/asm/mach-generic/floppy.h +++ b/arch/mips/include/asm/mach-generic/floppy.h @@ -115,11 +115,7 @@ static inline unsigned long fd_getfdaddr1(void) static inline unsigned long fd_dma_mem_alloc(unsigned long size) { - unsigned long mem; - - mem = __get_dma_pages(GFP_KERNEL, get_order(size)); - - return mem; + return __get_dma_pages(GFP_KERNEL, get_order(size)); } static inline void fd_dma_mem_free(unsigned long addr, unsigned long size) diff --git a/arch/mips/include/asm/pgalloc.h b/arch/mips/include/asm/pgalloc.h index 93c079a..a03e869 100644 --- a/arch/mips/include/asm/pgalloc.h +++ b/arch/mips/include/asm/pgalloc.h @@ -67,11 +67,7 @@ static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) { - pte_t *pte; - - pte = (pte_t *) __get_free_pages(GFP_KERNEL|__GFP_ZERO, PTE_ORDER); - - return pte; + return (pte_t *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, PTE_ORDER); } static inline struct page *pte_alloc_one(struct mm_struct *mm, diff --git a/arch/mips/mti-malta/malta-platform.c b/arch/mips/mti-malta/malta-platform.c index e1dd1c1..20a53e7 100644 --- a/arch/mips/mti-malta/malta-platform.c +++ b/arch/mips/mti-malta/malta-platform.c @@ -135,13 +135,7 @@ static struct platform_device *malta_devices[] __initdata = { static int __init malta_add_devices(void) { - int err; - - err = platform_add_devices(malta_devices, ARRAY_SIZE(malta_devices)); - if (err) - return err; - - return 0; + return platform_add_devices(malta_devices, ARRAY_SIZE(malta_devices)); } device_initcall(malta_add_devices); diff --git a/arch/mips/pnx833x/common/platform.c b/arch/mips/pnx833x/common/platform.c index 3cd3577..7cf4eb5 100644 --- a/arch/mips/pnx833x/common/platform.c +++ b/arch/mips/pnx833x/common/platform.c @@ -232,12 +232,8 @@ static struct platform_device *pnx833x_platform_devices[] __initdata = { static int __init pnx833x_platform_init(void) { - int res; - - res = platform_add_devices(pnx833x_platform_devices, - ARRAY_SIZE(pnx833x_platform_devices)); - - return res; + return platform_add_devices(pnx833x_platform_devices, + ARRAY_SIZE(pnx833x_platform_devices)); } arch_initcall(pnx833x_platform_init); -- cgit v0.10.2 From 561eca4990557b684605090fe6a2f50cecec34e1 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 18 Aug 2016 14:57:47 +0200 Subject: MIPS: TXx9: tx39xx: Move GPIO setup from .mem_setup() to .arch_init() txx9_gpio_init() calls gpiochip_add_data(), which fails with -ENOMEM as it is called too early in the boot process. This causes all subsequent GPIO operations to fail silently. Postpone all GPIO setup to .arch_init() time to fix this. Suggested-by: Atsushi Nemoto Signed-off-by: Geert Uytterhoeven Acked-by: Linus Walleij Cc: linux-mips@linux-mips.org Cc: linux-gpio@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/13967/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/txx9/generic/setup_tx3927.c b/arch/mips/txx9/generic/setup_tx3927.c index 110e05c..d3b83a9 100644 --- a/arch/mips/txx9/generic/setup_tx3927.c +++ b/arch/mips/txx9/generic/setup_tx3927.c @@ -92,7 +92,6 @@ void __init tx3927_setup(void) /* PIO */ __raw_writel(0, &tx3927_pioptr->maskcpu); __raw_writel(0, &tx3927_pioptr->maskext); - txx9_gpio_init(TX3927_PIO_REG, 0, 16); conf = read_c0_conf(); if (conf & TX39_CONF_DCE) { diff --git a/arch/mips/txx9/jmr3927/setup.c b/arch/mips/txx9/jmr3927/setup.c index 3206f76..a455166 100644 --- a/arch/mips/txx9/jmr3927/setup.c +++ b/arch/mips/txx9/jmr3927/setup.c @@ -142,8 +142,6 @@ static void __init jmr3927_board_init(void) /* PIO[15:12] connected to LEDs */ __raw_writel(0x0000f000, &tx3927_pioptr->dir); - gpio_request(11, "dipsw1"); - gpio_request(10, "dipsw2"); jmr3927_pci_setup(); @@ -204,6 +202,14 @@ static void __init jmr3927_device_init(void) txx9_iocled_init(iocled_base, -1, 8, 1, "green", NULL); } +static void __init jmr3927_arch_init(void) +{ + txx9_gpio_init(TX3927_PIO_REG, 0, 16); + + gpio_request(11, "dipsw1"); + gpio_request(10, "dipsw2"); +} + struct txx9_board_vec jmr3927_vec __initdata = { .system = "Toshiba JMR_TX3927", .prom_init = jmr3927_prom_init, @@ -211,6 +217,7 @@ struct txx9_board_vec jmr3927_vec __initdata = { .irq_setup = jmr3927_irq_setup, .time_init = jmr3927_time_init, .device_init = jmr3927_device_init, + .arch_init = jmr3927_arch_init, #ifdef CONFIG_PCI .pci_map_irq = jmr3927_pci_map_irq, #endif -- cgit v0.10.2 From 5ac676ade1eac27fb311f0f2fb11eeac5089a66c Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 11 Sep 2016 10:48:33 +0200 Subject: MIPS: TXx9: tx49xx: Move GPIO setup from .mem_setup() to .arch_init() txx9_gpio_init() calls gpiochip_add_data(), which fails with -ENOMEM as it is called too early in the boot process. This causes all subsequent GPIO operations to fail silently (before commit 54d77198fdfbc4f0 ("gpio: bail out silently on NULL descriptors") it printed the error message "gpiod_direction_output_raw: invalid GPIO" on RBTX49[23]7). Postpone all GPIO setup to .arch_init() time to fix this. Suggested-by: Atsushi Nemoto Signed-off-by: Geert Uytterhoeven Acked-by: Linus Walleij Cc: linux-mips@linux-mips.org Cc: linux-gpio@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14237/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/txx9/generic/setup_tx4927.c b/arch/mips/txx9/generic/setup_tx4927.c index a4664cb..8d80115 100644 --- a/arch/mips/txx9/generic/setup_tx4927.c +++ b/arch/mips/txx9/generic/setup_tx4927.c @@ -215,7 +215,6 @@ void __init tx4927_setup(void) txx9_tmr_init(TX4927_TMR_REG(i) & 0xfffffffffULL); /* PIO */ - txx9_gpio_init(TX4927_PIO_REG & 0xfffffffffULL, 0, TX4927_NUM_PIO); __raw_writel(0, &tx4927_pioptr->maskcpu); __raw_writel(0, &tx4927_pioptr->maskext); diff --git a/arch/mips/txx9/generic/setup_tx4938.c b/arch/mips/txx9/generic/setup_tx4938.c index 58cdb2a..ba265bf 100644 --- a/arch/mips/txx9/generic/setup_tx4938.c +++ b/arch/mips/txx9/generic/setup_tx4938.c @@ -241,7 +241,6 @@ void __init tx4938_setup(void) txx9_tmr_init(TX4938_TMR_REG(i) & 0xfffffffffULL); /* PIO */ - txx9_gpio_init(TX4938_PIO_REG & 0xfffffffffULL, 0, TX4938_NUM_PIO); __raw_writel(0, &tx4938_pioptr->maskcpu); __raw_writel(0, &tx4938_pioptr->maskext); diff --git a/arch/mips/txx9/rbtx4927/setup.c b/arch/mips/txx9/rbtx4927/setup.c index 3c516ef..f5b367e 100644 --- a/arch/mips/txx9/rbtx4927/setup.c +++ b/arch/mips/txx9/rbtx4927/setup.c @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -151,20 +152,37 @@ static void __init tx4937_pci_setup(void) } tx4938_setup_pcierr_irq(); } +#else +static inline void tx4927_pci_setup(void) {} +static inline void tx4937_pci_setup(void) {} +#endif /* CONFIG_PCI */ + +static void __init rbtx4927_gpio_init(void) +{ + /* TX4927-SIO DTR on (PIO[15]) */ + gpio_request(15, "sio-dtr"); + gpio_direction_output(15, 1); + + tx4927_sio_init(0, 0); +} static void __init rbtx4927_arch_init(void) { + txx9_gpio_init(TX4927_PIO_REG & 0xfffffffffULL, 0, TX4927_NUM_PIO); + + rbtx4927_gpio_init(); + tx4927_pci_setup(); } static void __init rbtx4937_arch_init(void) { + txx9_gpio_init(TX4938_PIO_REG & 0xfffffffffULL, 0, TX4938_NUM_PIO); + + rbtx4927_gpio_init(); + tx4937_pci_setup(); } -#else -#define rbtx4927_arch_init NULL -#define rbtx4937_arch_init NULL -#endif /* CONFIG_PCI */ static void toshiba_rbtx4927_restart(char *command) { @@ -205,12 +223,6 @@ static void __init rbtx4927_mem_setup(void) #else set_io_port_base(KSEG1 + RBTX4927_ISA_IO_OFFSET); #endif - - /* TX4927-SIO DTR on (PIO[15]) */ - gpio_request(15, "sio-dtr"); - gpio_direction_output(15, 1); - - tx4927_sio_init(0, 0); } static void __init rbtx4927_clock_init(void) diff --git a/arch/mips/txx9/rbtx4938/setup.c b/arch/mips/txx9/rbtx4938/setup.c index 54de668..07939ed 100644 --- a/arch/mips/txx9/rbtx4938/setup.c +++ b/arch/mips/txx9/rbtx4938/setup.c @@ -336,6 +336,7 @@ static void __init rbtx4938_mtd_init(void) static void __init rbtx4938_arch_init(void) { + txx9_gpio_init(TX4938_PIO_REG & 0xfffffffffULL, 0, TX4938_NUM_PIO); gpiochip_add_data(&rbtx4938_spi_gpio_chip, NULL); rbtx4938_pci_setup(); rbtx4938_spi_init(); -- cgit v0.10.2 From 39a3b6355329397c30441b62c940bb9cecec0448 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 11 Sep 2016 10:59:57 +0200 Subject: WATCHDOG: txx9wdt: Add missing clock (un)prepare calls for CCF While the custom minimal TXx9 clock implementation doesn't need or use clock (un)prepare calls (they are dummies if !CONFIG_HAVE_CLK_PREPARE), they are mandatory when using the Common Clock Framework. Hence add them, to prepare for the advent of CCF. Signed-off-by: Geert Uytterhoeven Reviewed-by: Guenter Roeck Cc: Atsushi Nemoto Cc: Wim Van Sebroeck Cc: linux-clk@vger.kernel.org Cc: linux-mips@linux-mips.org Cc: linux-watchdog@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14238/ Signed-off-by: Ralf Baechle diff --git a/drivers/watchdog/txx9wdt.c b/drivers/watchdog/txx9wdt.c index c2da880..6f7a9de 100644 --- a/drivers/watchdog/txx9wdt.c +++ b/drivers/watchdog/txx9wdt.c @@ -112,7 +112,7 @@ static int __init txx9wdt_probe(struct platform_device *dev) txx9_imclk = NULL; goto exit; } - ret = clk_enable(txx9_imclk); + ret = clk_prepare_enable(txx9_imclk); if (ret) { clk_put(txx9_imclk); txx9_imclk = NULL; @@ -144,7 +144,7 @@ static int __init txx9wdt_probe(struct platform_device *dev) return 0; exit: if (txx9_imclk) { - clk_disable(txx9_imclk); + clk_disable_unprepare(txx9_imclk); clk_put(txx9_imclk); } return ret; @@ -153,7 +153,7 @@ exit: static int __exit txx9wdt_remove(struct platform_device *dev) { watchdog_unregister_device(&txx9wdt); - clk_disable(txx9_imclk); + clk_disable_unprepare(txx9_imclk); clk_put(txx9_imclk); return 0; } -- cgit v0.10.2 From 44ce9a9ae977736fe7f470a7b1e506028375165a Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 11 Sep 2016 10:59:58 +0200 Subject: MIPS: TXx9: Convert to Common Clock Framework Replace the custom minimal clock implementation for Toshiba TXx9 by a basic implementation using the Common Clock Framework. The only clocks that are provided are those needed by TXx9-specific drivers ("imbus" and "spi" (TX4938 only)), and their common parent clock "gbus". Other clocks can be added when needed. Signed-off-by: Geert Uytterhoeven Reviewed-by: Stephen Boyd Reviewed-by: Atsushi Nemoto Cc: Wim Van Sebroeck Cc: Guenter Roeck Cc: linux-clk@vger.kernel.org Cc: linux-mips@linux-mips.org Cc: linux-watchdog@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14239/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/txx9/Kconfig b/arch/mips/txx9/Kconfig index 8c337d6..4292347 100644 --- a/arch/mips/txx9/Kconfig +++ b/arch/mips/txx9/Kconfig @@ -20,7 +20,7 @@ config MACH_TXX9 select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_LITTLE_ENDIAN select SYS_SUPPORTS_BIG_ENDIAN - select HAVE_CLK + select COMMON_CLK config TOSHIBA_JMR3927 bool "Toshiba JMR-TX3927 board" diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c index ada92db..a1d98b5 100644 --- a/arch/mips/txx9/generic/setup.c +++ b/arch/mips/txx9/generic/setup.c @@ -15,7 +15,8 @@ #include #include #include -#include +#include +#include #include #include #include @@ -83,40 +84,6 @@ int txx9_ccfg_toeon __initdata; int txx9_ccfg_toeon __initdata = 1; #endif -/* Minimum CLK support */ - -struct clk *clk_get(struct device *dev, const char *id) -{ - if (!strcmp(id, "spi-baseclk")) - return (struct clk *)((unsigned long)txx9_gbus_clock / 2 / 2); - if (!strcmp(id, "imbus_clk")) - return (struct clk *)((unsigned long)txx9_gbus_clock / 2); - return ERR_PTR(-ENOENT); -} -EXPORT_SYMBOL(clk_get); - -int clk_enable(struct clk *clk) -{ - return 0; -} -EXPORT_SYMBOL(clk_enable); - -void clk_disable(struct clk *clk) -{ -} -EXPORT_SYMBOL(clk_disable); - -unsigned long clk_get_rate(struct clk *clk) -{ - return (unsigned long)clk; -} -EXPORT_SYMBOL(clk_get_rate); - -void clk_put(struct clk *clk) -{ -} -EXPORT_SYMBOL(clk_put); - #define BOARD_VEC(board) extern struct txx9_board_vec board; #include #undef BOARD_VEC @@ -560,8 +527,41 @@ void __init plat_time_init(void) txx9_board_vec->time_init(); } +static void txx9_clk_init(void) +{ + struct clk_hw *hw; + int error; + + hw = clk_hw_register_fixed_rate(NULL, "gbus", NULL, 0, txx9_gbus_clock); + if (IS_ERR(hw)) { + error = PTR_ERR(hw); + goto fail; + } + + hw = clk_hw_register_fixed_factor(NULL, "imbus", "gbus", 0, 1, 2); + error = clk_hw_register_clkdev(hw, "imbus_clk", NULL); + if (error) + goto fail; + +#ifdef CONFIG_CPU_TX49XX + if (TX4938_REV_PCODE() == 0x4938) { + hw = clk_hw_register_fixed_factor(NULL, "spi", "gbus", 0, 1, 4); + error = clk_hw_register_clkdev(hw, "spi-baseclk", NULL); + if (error) + goto fail; + } +#endif + + return; + +fail: + pr_err("Failed to register clocks: %d\n", error); +} + static int __init _txx9_arch_init(void) { + txx9_clk_init(); + if (txx9_board_vec->arch_init) txx9_board_vec->arch_init(); return 0; -- cgit v0.10.2 From 5f92635462d64f09f4643e7c15c48ea7a1f7d2b7 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Tue, 13 Sep 2016 09:21:47 -0600 Subject: MIPS: PCI: Reduce stack frame usage This patch removes creating a fake pci device in MIPS early config access and instead just uses the pci bus to get the same functionality. The struct pci_dev is too large to allocate on the stack, and was relying on compiler optimizations to remove its usage. Signed-off-by: Keith Busch Reviewed-by: Atsushi Nemoto Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/14253/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/txx9/generic/pci.c b/arch/mips/txx9/generic/pci.c index 1f6bc9a..285d84e 100644 --- a/arch/mips/txx9/generic/pci.c +++ b/arch/mips/txx9/generic/pci.c @@ -29,12 +29,8 @@ static int __init early_read_config_word(struct pci_controller *hose, int top_bus, int bus, int devfn, int offset, u16 *value) { - struct pci_dev fake_dev; struct pci_bus fake_bus; - fake_dev.bus = &fake_bus; - fake_dev.sysdata = hose; - fake_dev.devfn = devfn; fake_bus.number = bus; fake_bus.sysdata = hose; fake_bus.ops = hose->pci_ops; @@ -45,7 +41,7 @@ early_read_config_word(struct pci_controller *hose, else fake_bus.parent = NULL; - return pci_read_config_word(&fake_dev, offset, value); + return pci_bus_read_config_word(&fake_bus, devfn, offset, value); } int __init txx9_pci66_check(struct pci_controller *hose, int top_bus, -- cgit v0.10.2 From 00ca0250125934c8e47f58f973ea2f8905cee017 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 19 Sep 2016 03:04:35 +0900 Subject: MIPS: BCM63xx: Let clk_disable() return immediately if clk is NULL In many of clk_disable() implementations, it is a no-op for a NULL pointer input, but this is one of the exceptions. Making it treewide consistent will allow clock consumers to call clk_disable() without NULL pointer check. Signed-off-by: Masahiro Yamada Acked-by: Florian Fainelli Cc: Stephen Boyd Cc: Michael Turquette Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Cc: bcm-kernel-feedback-list@broadcom.com Cc: linux-arm-kernel@lists.infradead.org Patchwork: https://patchwork.linux-mips.org/patch/14264/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/bcm63xx/clk.c b/arch/mips/bcm63xx/clk.c index 6375652..b49fc9c 100644 --- a/arch/mips/bcm63xx/clk.c +++ b/arch/mips/bcm63xx/clk.c @@ -326,6 +326,9 @@ EXPORT_SYMBOL(clk_enable); void clk_disable(struct clk *clk) { + if (!clk) + return; + mutex_lock(&clocks_mutex); clk_disable_unlocked(clk); mutex_unlock(&clocks_mutex); -- cgit v0.10.2 From 23d1f8f589df4a537751f4d6accc5841ed6cb24e Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Fri, 2 Sep 2016 23:44:16 +0300 Subject: MIPS: Octeon: Delete legacy hack for broken bootloaders Delete legacy hack for broken bootloaders. The warning has been in kernel for several years, and if there are still users using such bootloaders, they can fix the boot by supplying a proper DTB. Signed-off-by: Aaro Koskinen Cc: David Daney Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/14201/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper-board.c b/arch/mips/cavium-octeon/executive/cvmx-helper-board.c index ff49fc0..3751c58 100644 --- a/arch/mips/cavium-octeon/executive/cvmx-helper-board.c +++ b/arch/mips/cavium-octeon/executive/cvmx-helper-board.c @@ -676,48 +676,6 @@ int __cvmx_helper_board_hardware_enable(int interface) 0xc); } } else if (cvmx_sysinfo_get()->board_type == - CVMX_BOARD_TYPE_CN3010_EVB_HS5) { - /* - * Broadcom PHYs require differnet ASX - * clocks. Unfortunately many boards don't define a - * new board Id and simply mangle the - * CN3010_EVB_HS5 - */ - if (interface == 0) { - /* - * Some boards use a hacked up bootloader that - * identifies them as CN3010_EVB_HS5 - * evaluation boards. This leads to all kinds - * of configuration problems. Detect one - * case, and print warning, while trying to do - * the right thing. - */ - int phy_addr = cvmx_helper_board_get_mii_address(0); - if (phy_addr != -1) { - int phy_identifier = - cvmx_mdio_read(phy_addr >> 8, - phy_addr & 0xff, 0x2); - /* Is it a Broadcom PHY? */ - if (phy_identifier == 0x0143) { - cvmx_dprintf("\n"); - cvmx_dprintf("ERROR:\n"); - cvmx_dprintf - ("ERROR: Board type is CVMX_BOARD_TYPE_CN3010_EVB_HS5, but Broadcom PHY found.\n"); - cvmx_dprintf - ("ERROR: The board type is mis-configured, and software malfunctions are likely.\n"); - cvmx_dprintf - ("ERROR: All boards require a unique board type to identify them.\n"); - cvmx_dprintf("ERROR:\n"); - cvmx_dprintf("\n"); - cvmx_wait(1000000000); - cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX - (0, interface), 5); - cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX - (0, interface), 5); - } - } - } - } else if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_UBNT_E100) { cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(0, interface), 0); cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(0, interface), 0x10); -- cgit v0.10.2 From b93ebc1d5bd127a0c6161cf4bbb098374b1d8956 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Fri, 2 Sep 2016 23:44:17 +0300 Subject: MIPS: Octeon: Don't try to maintain link state in early init. Leave that to actual ethernet/phy drivers. Signed-off-by: Aaro Koskinen Cc: David Daney Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/14202/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper-rgmii.c b/arch/mips/cavium-octeon/executive/cvmx-helper-rgmii.c index f59c88e..809cd8b 100644 --- a/arch/mips/cavium-octeon/executive/cvmx-helper-rgmii.c +++ b/arch/mips/cavium-octeon/executive/cvmx-helper-rgmii.c @@ -243,8 +243,7 @@ int __cvmx_helper_rgmii_enable(int interface) /* enable the ports now */ for (port = 0; port < num_ports; port++) { union cvmx_gmxx_prtx_cfg gmx_cfg; - cvmx_helper_link_autoconf(cvmx_helper_get_ipd_port - (interface, port)); + gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(port, interface)); gmx_cfg.s.en = 1; diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper-xaui.c b/arch/mips/cavium-octeon/executive/cvmx-helper-xaui.c index a56ee59..d347fe1 100644 --- a/arch/mips/cavium-octeon/executive/cvmx-helper-xaui.c +++ b/arch/mips/cavium-octeon/executive/cvmx-helper-xaui.c @@ -234,8 +234,6 @@ int __cvmx_helper_xaui_enable(int interface) cvmx_write_csr(CVMX_GMXX_TX_INT_EN(interface), gmx_tx_int_en.u64); cvmx_write_csr(CVMX_PCSXX_INT_EN_REG(interface), pcsx_int_en_reg.u64); - cvmx_helper_link_autoconf(cvmx_helper_get_ipd_port(interface, 0)); - /* (8) Enable packet reception */ xauiMiscCtl.s.gmxeno = 0; cvmx_write_csr(CVMX_PCSXX_MISC_CTL_REG(interface), xauiMiscCtl.u64); diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper.c b/arch/mips/cavium-octeon/executive/cvmx-helper.c index ff26d02..6456af6 100644 --- a/arch/mips/cavium-octeon/executive/cvmx-helper.c +++ b/arch/mips/cavium-octeon/executive/cvmx-helper.c @@ -841,7 +841,6 @@ int __cvmx_helper_errata_fix_ipd_ptr_alignment(void) int retry_cnt; int retry_loop_cnt; int i; - cvmx_helper_link_info_t link_info; /* Save values for restore at end */ uint64_t prtx_cfg = @@ -1002,15 +1001,6 @@ fix_ipd_exit: (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)), frame_max); cvmx_write_csr(CVMX_ASXX_PRT_LOOP(INTERFACE(FIX_IPD_OUTPORT)), 0); - /* Set link to down so autonegotiation will set it up again */ - link_info.u64 = 0; - cvmx_helper_link_set(FIX_IPD_OUTPORT, link_info); - - /* - * Bring the link back up as autonegotiation is not done in - * user applications. - */ - cvmx_helper_link_autoconf(FIX_IPD_OUTPORT); CVMX_SYNC; if (num_segs) -- cgit v0.10.2 From 80c73b3509f29b363a7bb07203c310ee0ad8b625 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Fri, 2 Sep 2016 23:44:18 +0300 Subject: MIPS: Octeon: Delete unused cvmx_override_board_link_get. Signed-off-by: Aaro Koskinen Cc: David Daney Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/14203/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper-board.c b/arch/mips/cavium-octeon/executive/cvmx-helper-board.c index 3751c58..0deeb82 100644 --- a/arch/mips/cavium-octeon/executive/cvmx-helper-board.c +++ b/arch/mips/cavium-octeon/executive/cvmx-helper-board.c @@ -46,17 +46,6 @@ #include /** - * cvmx_override_board_link_get(int ipd_port) is a function - * pointer. It is meant to allow customization of the process of - * talking to a PHY to determine link speed. It is called every - * time a PHY must be polled for link status. Users should set - * this pointer to a function before calling any cvmx-helper - * operations. - */ -cvmx_helper_link_info_t(*cvmx_override_board_link_get) (int ipd_port) = - NULL; - -/** * Return the MII PHY address associated with the given IPD * port. A result of -1 means there isn't a MII capable PHY * connected to this port. On chips supporting multiple MII @@ -225,10 +214,6 @@ cvmx_helper_link_info_t __cvmx_helper_board_link_get(int ipd_port) int phy_addr; int is_broadcom_phy = 0; - /* Give the user a chance to override the processing of this function */ - if (cvmx_override_board_link_get) - return cvmx_override_board_link_get(ipd_port); - /* Unless we fix it later, all links are defaulted to down */ result.u64 = 0; diff --git a/arch/mips/include/asm/octeon/cvmx-helper-board.h b/arch/mips/include/asm/octeon/cvmx-helper-board.h index cda93ae..271be7a 100644 --- a/arch/mips/include/asm/octeon/cvmx-helper-board.h +++ b/arch/mips/include/asm/octeon/cvmx-helper-board.h @@ -58,16 +58,6 @@ typedef enum { #define CVMX_HELPER_BOARD_MGMT_IPD_PORT -10 /** - * cvmx_override_board_link_get(int ipd_port) is a function - * pointer. It is meant to allow customization of the process of - * talking to a PHY to determine link speed. It is called every - * time a PHY must be polled for link status. Users should set - * this pointer to a function before calling any cvmx-helper - * operations. - */ -extern cvmx_helper_link_info_t(*cvmx_override_board_link_get) (int ipd_port); - -/** * Return the MII PHY address associated with the given IPD * port. A result of -1 means there isn't a MII capable PHY * connected to this port. On chips supporting multiple MII -- cgit v0.10.2 From 0a1e192d660db17c532a6ab36eb2f77332d9cb1c Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Fri, 2 Sep 2016 23:44:19 +0300 Subject: MIPS: Octeon: Delete unused cvmx_helper_board_link_set_phy. Signed-off-by: Aaro Koskinen Cc: David Daney Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/14204/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper-board.c b/arch/mips/cavium-octeon/executive/cvmx-helper-board.c index 0deeb82..5572e39 100644 --- a/arch/mips/cavium-octeon/executive/cvmx-helper-board.c +++ b/arch/mips/cavium-octeon/executive/cvmx-helper-board.c @@ -418,176 +418,6 @@ cvmx_helper_link_info_t __cvmx_helper_board_link_get(int ipd_port) } /** - * This function as a board specific method of changing the PHY - * speed, duplex, and auto-negotiation. This programs the PHY and - * not Octeon. This can be used to force Octeon's links to - * specific settings. - * - * @phy_addr: The address of the PHY to program - * @enable_autoneg: - * Non zero if you want to enable auto-negotiation. - * @link_info: Link speed to program. If the speed is zero and auto-negotiation - * is enabled, all possible negotiation speeds are advertised. - * - * Returns Zero on success, negative on failure - */ -int cvmx_helper_board_link_set_phy(int phy_addr, - cvmx_helper_board_set_phy_link_flags_types_t - link_flags, - cvmx_helper_link_info_t link_info) -{ - - /* Set the flow control settings based on link_flags */ - if ((link_flags & set_phy_link_flags_flow_control_mask) != - set_phy_link_flags_flow_control_dont_touch) { - cvmx_mdio_phy_reg_autoneg_adver_t reg_autoneg_adver; - reg_autoneg_adver.u16 = - cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, - CVMX_MDIO_PHY_REG_AUTONEG_ADVER); - reg_autoneg_adver.s.asymmetric_pause = - (link_flags & set_phy_link_flags_flow_control_mask) == - set_phy_link_flags_flow_control_enable; - reg_autoneg_adver.s.pause = - (link_flags & set_phy_link_flags_flow_control_mask) == - set_phy_link_flags_flow_control_enable; - cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff, - CVMX_MDIO_PHY_REG_AUTONEG_ADVER, - reg_autoneg_adver.u16); - } - - /* If speed isn't set and autoneg is on advertise all supported modes */ - if ((link_flags & set_phy_link_flags_autoneg) - && (link_info.s.speed == 0)) { - cvmx_mdio_phy_reg_control_t reg_control; - cvmx_mdio_phy_reg_status_t reg_status; - cvmx_mdio_phy_reg_autoneg_adver_t reg_autoneg_adver; - cvmx_mdio_phy_reg_extended_status_t reg_extended_status; - cvmx_mdio_phy_reg_control_1000_t reg_control_1000; - - reg_status.u16 = - cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, - CVMX_MDIO_PHY_REG_STATUS); - reg_autoneg_adver.u16 = - cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, - CVMX_MDIO_PHY_REG_AUTONEG_ADVER); - reg_autoneg_adver.s.advert_100base_t4 = - reg_status.s.capable_100base_t4; - reg_autoneg_adver.s.advert_10base_tx_full = - reg_status.s.capable_10_full; - reg_autoneg_adver.s.advert_10base_tx_half = - reg_status.s.capable_10_half; - reg_autoneg_adver.s.advert_100base_tx_full = - reg_status.s.capable_100base_x_full; - reg_autoneg_adver.s.advert_100base_tx_half = - reg_status.s.capable_100base_x_half; - cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff, - CVMX_MDIO_PHY_REG_AUTONEG_ADVER, - reg_autoneg_adver.u16); - if (reg_status.s.capable_extended_status) { - reg_extended_status.u16 = - cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, - CVMX_MDIO_PHY_REG_EXTENDED_STATUS); - reg_control_1000.u16 = - cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, - CVMX_MDIO_PHY_REG_CONTROL_1000); - reg_control_1000.s.advert_1000base_t_full = - reg_extended_status.s.capable_1000base_t_full; - reg_control_1000.s.advert_1000base_t_half = - reg_extended_status.s.capable_1000base_t_half; - cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff, - CVMX_MDIO_PHY_REG_CONTROL_1000, - reg_control_1000.u16); - } - reg_control.u16 = - cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, - CVMX_MDIO_PHY_REG_CONTROL); - reg_control.s.autoneg_enable = 1; - reg_control.s.restart_autoneg = 1; - cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff, - CVMX_MDIO_PHY_REG_CONTROL, reg_control.u16); - } else if ((link_flags & set_phy_link_flags_autoneg)) { - cvmx_mdio_phy_reg_control_t reg_control; - cvmx_mdio_phy_reg_status_t reg_status; - cvmx_mdio_phy_reg_autoneg_adver_t reg_autoneg_adver; - cvmx_mdio_phy_reg_control_1000_t reg_control_1000; - - reg_status.u16 = - cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, - CVMX_MDIO_PHY_REG_STATUS); - reg_autoneg_adver.u16 = - cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, - CVMX_MDIO_PHY_REG_AUTONEG_ADVER); - reg_autoneg_adver.s.advert_100base_t4 = 0; - reg_autoneg_adver.s.advert_10base_tx_full = 0; - reg_autoneg_adver.s.advert_10base_tx_half = 0; - reg_autoneg_adver.s.advert_100base_tx_full = 0; - reg_autoneg_adver.s.advert_100base_tx_half = 0; - if (reg_status.s.capable_extended_status) { - reg_control_1000.u16 = - cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, - CVMX_MDIO_PHY_REG_CONTROL_1000); - reg_control_1000.s.advert_1000base_t_full = 0; - reg_control_1000.s.advert_1000base_t_half = 0; - } - switch (link_info.s.speed) { - case 10: - reg_autoneg_adver.s.advert_10base_tx_full = - link_info.s.full_duplex; - reg_autoneg_adver.s.advert_10base_tx_half = - !link_info.s.full_duplex; - break; - case 100: - reg_autoneg_adver.s.advert_100base_tx_full = - link_info.s.full_duplex; - reg_autoneg_adver.s.advert_100base_tx_half = - !link_info.s.full_duplex; - break; - case 1000: - reg_control_1000.s.advert_1000base_t_full = - link_info.s.full_duplex; - reg_control_1000.s.advert_1000base_t_half = - !link_info.s.full_duplex; - break; - } - cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff, - CVMX_MDIO_PHY_REG_AUTONEG_ADVER, - reg_autoneg_adver.u16); - if (reg_status.s.capable_extended_status) - cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff, - CVMX_MDIO_PHY_REG_CONTROL_1000, - reg_control_1000.u16); - reg_control.u16 = - cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, - CVMX_MDIO_PHY_REG_CONTROL); - reg_control.s.autoneg_enable = 1; - reg_control.s.restart_autoneg = 1; - cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff, - CVMX_MDIO_PHY_REG_CONTROL, reg_control.u16); - } else { - cvmx_mdio_phy_reg_control_t reg_control; - reg_control.u16 = - cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, - CVMX_MDIO_PHY_REG_CONTROL); - reg_control.s.autoneg_enable = 0; - reg_control.s.restart_autoneg = 1; - reg_control.s.duplex = link_info.s.full_duplex; - if (link_info.s.speed == 1000) { - reg_control.s.speed_msb = 1; - reg_control.s.speed_lsb = 0; - } else if (link_info.s.speed == 100) { - reg_control.s.speed_msb = 0; - reg_control.s.speed_lsb = 1; - } else if (link_info.s.speed == 10) { - reg_control.s.speed_msb = 0; - reg_control.s.speed_lsb = 0; - } - cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff, - CVMX_MDIO_PHY_REG_CONTROL, reg_control.u16); - } - return 0; -} - -/** * This function is called by cvmx_helper_interface_probe() after it * determines the number of ports Octeon can support on a specific * interface. This function is the per board location to override diff --git a/arch/mips/include/asm/octeon/cvmx-helper-board.h b/arch/mips/include/asm/octeon/cvmx-helper-board.h index 271be7a..b4d19c21 100644 --- a/arch/mips/include/asm/octeon/cvmx-helper-board.h +++ b/arch/mips/include/asm/octeon/cvmx-helper-board.h @@ -76,26 +76,6 @@ typedef enum { extern int cvmx_helper_board_get_mii_address(int ipd_port); /** - * This function as a board specific method of changing the PHY - * speed, duplex, and autonegotiation. This programs the PHY and - * not Octeon. This can be used to force Octeon's links to - * specific settings. - * - * @phy_addr: The address of the PHY to program - * @link_flags: - * Flags to control autonegotiation. Bit 0 is autonegotiation - * enable/disable to maintain backward compatibility. - * @link_info: Link speed to program. If the speed is zero and autonegotiation - * is enabled, all possible negotiation speeds are advertised. - * - * Returns Zero on success, negative on failure - */ -int cvmx_helper_board_link_set_phy(int phy_addr, - cvmx_helper_board_set_phy_link_flags_types_t - link_flags, - cvmx_helper_link_info_t link_info); - -/** * This function is the board specific method of determining an * ethernet ports link speed. Most Octeon boards have Marvell PHYs * and are handled by the fall through case. This function must be -- cgit v0.10.2 From 0d19672e7807d7d365ca3b317f4b2d0db6847ca6 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Fri, 2 Sep 2016 23:44:20 +0300 Subject: MIPS: Octeon: Delete legacy code for PHY access PHY access through the board helper is impossible with the current drivers, so delete this code. Signed-off-by: Aaro Koskinen Cc: David Daney Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/14205/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper-board.c b/arch/mips/cavium-octeon/executive/cvmx-helper-board.c index 5572e39..bc37266 100644 --- a/arch/mips/cavium-octeon/executive/cvmx-helper-board.c +++ b/arch/mips/cavium-octeon/executive/cvmx-helper-board.c @@ -211,8 +211,6 @@ int cvmx_helper_board_get_mii_address(int ipd_port) cvmx_helper_link_info_t __cvmx_helper_board_link_get(int ipd_port) { cvmx_helper_link_info_t result; - int phy_addr; - int is_broadcom_phy = 0; /* Unless we fix it later, all links are defaulted to down */ result.u64 = 0; @@ -248,8 +246,7 @@ cvmx_helper_link_info_t __cvmx_helper_board_link_get(int ipd_port) result.s.full_duplex = 1; result.s.speed = 1000; return result; - } else /* The other port uses a broadcom PHY */ - is_broadcom_phy = 1; + } break; case CVMX_BOARD_TYPE_BBGW_REF: /* Port 1 on these boards is always Gigabit */ @@ -267,108 +264,7 @@ cvmx_helper_link_info_t __cvmx_helper_board_link_get(int ipd_port) break; } - phy_addr = cvmx_helper_board_get_mii_address(ipd_port); - if (phy_addr != -1) { - if (is_broadcom_phy) { - /* - * Below we are going to read SMI/MDIO - * register 0x19 which works on Broadcom - * parts - */ - int phy_status = - cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, - 0x19); - switch ((phy_status >> 8) & 0x7) { - case 0: - result.u64 = 0; - break; - case 1: - result.s.link_up = 1; - result.s.full_duplex = 0; - result.s.speed = 10; - break; - case 2: - result.s.link_up = 1; - result.s.full_duplex = 1; - result.s.speed = 10; - break; - case 3: - result.s.link_up = 1; - result.s.full_duplex = 0; - result.s.speed = 100; - break; - case 4: - result.s.link_up = 1; - result.s.full_duplex = 1; - result.s.speed = 100; - break; - case 5: - result.s.link_up = 1; - result.s.full_duplex = 1; - result.s.speed = 100; - break; - case 6: - result.s.link_up = 1; - result.s.full_duplex = 0; - result.s.speed = 1000; - break; - case 7: - result.s.link_up = 1; - result.s.full_duplex = 1; - result.s.speed = 1000; - break; - } - } else { - /* - * This code assumes we are using a Marvell - * Gigabit PHY. All the speed information can - * be read from register 17 in one - * go. Somebody using a different PHY will - * need to handle it above in the board - * specific area. - */ - int phy_status = - cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, 17); - - /* - * If the resolve bit 11 isn't set, see if - * autoneg is turned off (bit 12, reg 0). The - * resolve bit doesn't get set properly when - * autoneg is off, so force it. - */ - if ((phy_status & (1 << 11)) == 0) { - int auto_status = - cvmx_mdio_read(phy_addr >> 8, - phy_addr & 0xff, 0); - if ((auto_status & (1 << 12)) == 0) - phy_status |= 1 << 11; - } - - /* - * Only return a link if the PHY has finished - * auto negotiation and set the resolved bit - * (bit 11) - */ - if (phy_status & (1 << 11)) { - result.s.link_up = 1; - result.s.full_duplex = ((phy_status >> 13) & 1); - switch ((phy_status >> 14) & 3) { - case 0: /* 10 Mbps */ - result.s.speed = 10; - break; - case 1: /* 100 Mbps */ - result.s.speed = 100; - break; - case 2: /* 1 Gbps */ - result.s.speed = 1000; - break; - case 3: /* Illegal */ - result.u64 = 0; - break; - } - } - } - } else if (OCTEON_IS_MODEL(OCTEON_CN3XXX) + if (OCTEON_IS_MODEL(OCTEON_CN3XXX) || OCTEON_IS_MODEL(OCTEON_CN58XX) || OCTEON_IS_MODEL(OCTEON_CN50XX)) { /* -- cgit v0.10.2 From 6376d7baffb903bebebe32cc8c3610cfeade0849 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Fri, 2 Sep 2016 23:44:21 +0300 Subject: MIPS: Octeon: Delete unused cvmx-mdio.h Signed-off-by: Aaro Koskinen Cc: David Daney Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/14206/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper-board.c b/arch/mips/cavium-octeon/executive/cvmx-helper-board.c index bc37266..ab8362e 100644 --- a/arch/mips/cavium-octeon/executive/cvmx-helper-board.c +++ b/arch/mips/cavium-octeon/executive/cvmx-helper-board.c @@ -36,8 +36,6 @@ #include -#include - #include #include #include diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper-rgmii.c b/arch/mips/cavium-octeon/executive/cvmx-helper-rgmii.c index 809cd8b..671ab1d 100644 --- a/arch/mips/cavium-octeon/executive/cvmx-helper-rgmii.c +++ b/arch/mips/cavium-octeon/executive/cvmx-helper-rgmii.c @@ -33,8 +33,6 @@ #include - -#include #include #include #include diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper-sgmii.c b/arch/mips/cavium-octeon/executive/cvmx-helper-sgmii.c index 6f9609e..5437534 100644 --- a/arch/mips/cavium-octeon/executive/cvmx-helper-sgmii.c +++ b/arch/mips/cavium-octeon/executive/cvmx-helper-sgmii.c @@ -34,7 +34,6 @@ #include -#include #include #include diff --git a/arch/mips/include/asm/octeon/cvmx-mdio.h b/arch/mips/include/asm/octeon/cvmx-mdio.h deleted file mode 100644 index 9f6a4f3..0000000 --- a/arch/mips/include/asm/octeon/cvmx-mdio.h +++ /dev/null @@ -1,506 +0,0 @@ -/***********************license start*************** - * Author: Cavium Networks - * - * Contact: support@caviumnetworks.com - * This file is part of the OCTEON SDK - * - * Copyright (c) 2003-2008 Cavium Networks - * - * This file 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. - * - * This file is distributed in the hope that it will be useful, but - * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or - * NONINFRINGEMENT. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License - * along with this file; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * or visit http://www.gnu.org/licenses/. - * - * This file may also be available under a different license from Cavium. - * Contact Cavium Networks for more information - ***********************license end**************************************/ - -/* - * - * Interface to the SMI/MDIO hardware, including support for both IEEE 802.3 - * clause 22 and clause 45 operations. - * - */ - -#ifndef __CVMX_MIO_H__ -#define __CVMX_MIO_H__ - -#include - -/** - * PHY register 0 from the 802.3 spec - */ -#define CVMX_MDIO_PHY_REG_CONTROL 0 -typedef union { - uint16_t u16; - struct { - uint16_t reset:1; - uint16_t loopback:1; - uint16_t speed_lsb:1; - uint16_t autoneg_enable:1; - uint16_t power_down:1; - uint16_t isolate:1; - uint16_t restart_autoneg:1; - uint16_t duplex:1; - uint16_t collision_test:1; - uint16_t speed_msb:1; - uint16_t unidirectional_enable:1; - uint16_t reserved_0_4:5; - } s; -} cvmx_mdio_phy_reg_control_t; - -/** - * PHY register 1 from the 802.3 spec - */ -#define CVMX_MDIO_PHY_REG_STATUS 1 -typedef union { - uint16_t u16; - struct { - uint16_t capable_100base_t4:1; - uint16_t capable_100base_x_full:1; - uint16_t capable_100base_x_half:1; - uint16_t capable_10_full:1; - uint16_t capable_10_half:1; - uint16_t capable_100base_t2_full:1; - uint16_t capable_100base_t2_half:1; - uint16_t capable_extended_status:1; - uint16_t capable_unidirectional:1; - uint16_t capable_mf_preamble_suppression:1; - uint16_t autoneg_complete:1; - uint16_t remote_fault:1; - uint16_t capable_autoneg:1; - uint16_t link_status:1; - uint16_t jabber_detect:1; - uint16_t capable_extended_registers:1; - - } s; -} cvmx_mdio_phy_reg_status_t; - -/** - * PHY register 2 from the 802.3 spec - */ -#define CVMX_MDIO_PHY_REG_ID1 2 -typedef union { - uint16_t u16; - struct { - uint16_t oui_bits_3_18; - } s; -} cvmx_mdio_phy_reg_id1_t; - -/** - * PHY register 3 from the 802.3 spec - */ -#define CVMX_MDIO_PHY_REG_ID2 3 -typedef union { - uint16_t u16; - struct { - uint16_t oui_bits_19_24:6; - uint16_t model:6; - uint16_t revision:4; - } s; -} cvmx_mdio_phy_reg_id2_t; - -/** - * PHY register 4 from the 802.3 spec - */ -#define CVMX_MDIO_PHY_REG_AUTONEG_ADVER 4 -typedef union { - uint16_t u16; - struct { - uint16_t next_page:1; - uint16_t reserved_14:1; - uint16_t remote_fault:1; - uint16_t reserved_12:1; - uint16_t asymmetric_pause:1; - uint16_t pause:1; - uint16_t advert_100base_t4:1; - uint16_t advert_100base_tx_full:1; - uint16_t advert_100base_tx_half:1; - uint16_t advert_10base_tx_full:1; - uint16_t advert_10base_tx_half:1; - uint16_t selector:5; - } s; -} cvmx_mdio_phy_reg_autoneg_adver_t; - -/** - * PHY register 5 from the 802.3 spec - */ -#define CVMX_MDIO_PHY_REG_LINK_PARTNER_ABILITY 5 -typedef union { - uint16_t u16; - struct { - uint16_t next_page:1; - uint16_t ack:1; - uint16_t remote_fault:1; - uint16_t reserved_12:1; - uint16_t asymmetric_pause:1; - uint16_t pause:1; - uint16_t advert_100base_t4:1; - uint16_t advert_100base_tx_full:1; - uint16_t advert_100base_tx_half:1; - uint16_t advert_10base_tx_full:1; - uint16_t advert_10base_tx_half:1; - uint16_t selector:5; - } s; -} cvmx_mdio_phy_reg_link_partner_ability_t; - -/** - * PHY register 6 from the 802.3 spec - */ -#define CVMX_MDIO_PHY_REG_AUTONEG_EXPANSION 6 -typedef union { - uint16_t u16; - struct { - uint16_t reserved_5_15:11; - uint16_t parallel_detection_fault:1; - uint16_t link_partner_next_page_capable:1; - uint16_t local_next_page_capable:1; - uint16_t page_received:1; - uint16_t link_partner_autoneg_capable:1; - - } s; -} cvmx_mdio_phy_reg_autoneg_expansion_t; - -/** - * PHY register 9 from the 802.3 spec - */ -#define CVMX_MDIO_PHY_REG_CONTROL_1000 9 -typedef union { - uint16_t u16; - struct { - uint16_t test_mode:3; - uint16_t manual_master_slave:1; - uint16_t master:1; - uint16_t port_type:1; - uint16_t advert_1000base_t_full:1; - uint16_t advert_1000base_t_half:1; - uint16_t reserved_0_7:8; - } s; -} cvmx_mdio_phy_reg_control_1000_t; - -/** - * PHY register 10 from the 802.3 spec - */ -#define CVMX_MDIO_PHY_REG_STATUS_1000 10 -typedef union { - uint16_t u16; - struct { - uint16_t master_slave_fault:1; - uint16_t is_master:1; - uint16_t local_receiver_ok:1; - uint16_t remote_receiver_ok:1; - uint16_t remote_capable_1000base_t_full:1; - uint16_t remote_capable_1000base_t_half:1; - uint16_t reserved_8_9:2; - uint16_t idle_error_count:8; - } s; -} cvmx_mdio_phy_reg_status_1000_t; - -/** - * PHY register 15 from the 802.3 spec - */ -#define CVMX_MDIO_PHY_REG_EXTENDED_STATUS 15 -typedef union { - uint16_t u16; - struct { - uint16_t capable_1000base_x_full:1; - uint16_t capable_1000base_x_half:1; - uint16_t capable_1000base_t_full:1; - uint16_t capable_1000base_t_half:1; - uint16_t reserved_0_11:12; - } s; -} cvmx_mdio_phy_reg_extended_status_t; - -/** - * PHY register 13 from the 802.3 spec - */ -#define CVMX_MDIO_PHY_REG_MMD_CONTROL 13 -typedef union { - uint16_t u16; - struct { - uint16_t function:2; - uint16_t reserved_5_13:9; - uint16_t devad:5; - } s; -} cvmx_mdio_phy_reg_mmd_control_t; - -/** - * PHY register 14 from the 802.3 spec - */ -#define CVMX_MDIO_PHY_REG_MMD_ADDRESS_DATA 14 -typedef union { - uint16_t u16; - struct { - uint16_t address_data:16; - } s; -} cvmx_mdio_phy_reg_mmd_address_data_t; - -/* Operating request encodings. */ -#define MDIO_CLAUSE_22_WRITE 0 -#define MDIO_CLAUSE_22_READ 1 - -#define MDIO_CLAUSE_45_ADDRESS 0 -#define MDIO_CLAUSE_45_WRITE 1 -#define MDIO_CLAUSE_45_READ_INC 2 -#define MDIO_CLAUSE_45_READ 3 - -/* MMD identifiers, mostly for accessing devices within XENPAK modules. */ -#define CVMX_MMD_DEVICE_PMA_PMD 1 -#define CVMX_MMD_DEVICE_WIS 2 -#define CVMX_MMD_DEVICE_PCS 3 -#define CVMX_MMD_DEVICE_PHY_XS 4 -#define CVMX_MMD_DEVICE_DTS_XS 5 -#define CVMX_MMD_DEVICE_TC 6 -#define CVMX_MMD_DEVICE_CL22_EXT 29 -#define CVMX_MMD_DEVICE_VENDOR_1 30 -#define CVMX_MMD_DEVICE_VENDOR_2 31 - -/* Helper function to put MDIO interface into clause 45 mode */ -static inline void __cvmx_mdio_set_clause45_mode(int bus_id) -{ - union cvmx_smix_clk smi_clk; - /* Put bus into clause 45 mode */ - smi_clk.u64 = cvmx_read_csr(CVMX_SMIX_CLK(bus_id)); - smi_clk.s.mode = 1; - smi_clk.s.preamble = 1; - cvmx_write_csr(CVMX_SMIX_CLK(bus_id), smi_clk.u64); -} - -/* Helper function to put MDIO interface into clause 22 mode */ -static inline void __cvmx_mdio_set_clause22_mode(int bus_id) -{ - union cvmx_smix_clk smi_clk; - /* Put bus into clause 22 mode */ - smi_clk.u64 = cvmx_read_csr(CVMX_SMIX_CLK(bus_id)); - smi_clk.s.mode = 0; - cvmx_write_csr(CVMX_SMIX_CLK(bus_id), smi_clk.u64); -} - -/** - * Perform an MII read. This function is used to read PHY - * registers controlling auto negotiation. - * - * @bus_id: MDIO bus number. Zero on most chips, but some chips (ex CN56XX) - * support multiple busses. - * @phy_id: The MII phy id - * @location: Register location to read - * - * Returns Result from the read or -1 on failure - */ -static inline int cvmx_mdio_read(int bus_id, int phy_id, int location) -{ - union cvmx_smix_cmd smi_cmd; - union cvmx_smix_rd_dat smi_rd; - int timeout = 1000; - - if (octeon_has_feature(OCTEON_FEATURE_MDIO_CLAUSE_45)) - __cvmx_mdio_set_clause22_mode(bus_id); - - smi_cmd.u64 = 0; - smi_cmd.s.phy_op = MDIO_CLAUSE_22_READ; - smi_cmd.s.phy_adr = phy_id; - smi_cmd.s.reg_adr = location; - cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64); - - do { - cvmx_wait(1000); - smi_rd.u64 = cvmx_read_csr(CVMX_SMIX_RD_DAT(bus_id)); - } while (smi_rd.s.pending && timeout--); - - if (smi_rd.s.val) - return smi_rd.s.dat; - else - return -1; -} - -/** - * Perform an MII write. This function is used to write PHY - * registers controlling auto negotiation. - * - * @bus_id: MDIO bus number. Zero on most chips, but some chips (ex CN56XX) - * support multiple busses. - * @phy_id: The MII phy id - * @location: Register location to write - * @val: Value to write - * - * Returns -1 on error - * 0 on success - */ -static inline int cvmx_mdio_write(int bus_id, int phy_id, int location, int val) -{ - union cvmx_smix_cmd smi_cmd; - union cvmx_smix_wr_dat smi_wr; - int timeout = 1000; - - if (octeon_has_feature(OCTEON_FEATURE_MDIO_CLAUSE_45)) - __cvmx_mdio_set_clause22_mode(bus_id); - - smi_wr.u64 = 0; - smi_wr.s.dat = val; - cvmx_write_csr(CVMX_SMIX_WR_DAT(bus_id), smi_wr.u64); - - smi_cmd.u64 = 0; - smi_cmd.s.phy_op = MDIO_CLAUSE_22_WRITE; - smi_cmd.s.phy_adr = phy_id; - smi_cmd.s.reg_adr = location; - cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64); - - do { - cvmx_wait(1000); - smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(bus_id)); - } while (smi_wr.s.pending && --timeout); - if (timeout <= 0) - return -1; - - return 0; -} - -/** - * Perform an IEEE 802.3 clause 45 MII read. This function is used to - * read PHY registers controlling auto negotiation. - * - * @bus_id: MDIO bus number. Zero on most chips, but some chips (ex CN56XX) - * support multiple busses. - * @phy_id: The MII phy id - * @device: MDIO Managable Device (MMD) id - * @location: Register location to read - * - * Returns Result from the read or -1 on failure - */ - -static inline int cvmx_mdio_45_read(int bus_id, int phy_id, int device, - int location) -{ - union cvmx_smix_cmd smi_cmd; - union cvmx_smix_rd_dat smi_rd; - union cvmx_smix_wr_dat smi_wr; - int timeout = 1000; - - if (!octeon_has_feature(OCTEON_FEATURE_MDIO_CLAUSE_45)) - return -1; - - __cvmx_mdio_set_clause45_mode(bus_id); - - smi_wr.u64 = 0; - smi_wr.s.dat = location; - cvmx_write_csr(CVMX_SMIX_WR_DAT(bus_id), smi_wr.u64); - - smi_cmd.u64 = 0; - smi_cmd.s.phy_op = MDIO_CLAUSE_45_ADDRESS; - smi_cmd.s.phy_adr = phy_id; - smi_cmd.s.reg_adr = device; - cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64); - - do { - cvmx_wait(1000); - smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(bus_id)); - } while (smi_wr.s.pending && --timeout); - if (timeout <= 0) { - cvmx_dprintf("cvmx_mdio_45_read: bus_id %d phy_id %2d " - "device %2d register %2d TIME OUT(address)\n", - bus_id, phy_id, device, location); - return -1; - } - - smi_cmd.u64 = 0; - smi_cmd.s.phy_op = MDIO_CLAUSE_45_READ; - smi_cmd.s.phy_adr = phy_id; - smi_cmd.s.reg_adr = device; - cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64); - - do { - cvmx_wait(1000); - smi_rd.u64 = cvmx_read_csr(CVMX_SMIX_RD_DAT(bus_id)); - } while (smi_rd.s.pending && --timeout); - - if (timeout <= 0) { - cvmx_dprintf("cvmx_mdio_45_read: bus_id %d phy_id %2d " - "device %2d register %2d TIME OUT(data)\n", - bus_id, phy_id, device, location); - return -1; - } - - if (smi_rd.s.val) - return smi_rd.s.dat; - else { - cvmx_dprintf("cvmx_mdio_45_read: bus_id %d phy_id %2d " - "device %2d register %2d INVALID READ\n", - bus_id, phy_id, device, location); - return -1; - } -} - -/** - * Perform an IEEE 802.3 clause 45 MII write. This function is used to - * write PHY registers controlling auto negotiation. - * - * @bus_id: MDIO bus number. Zero on most chips, but some chips (ex CN56XX) - * support multiple busses. - * @phy_id: The MII phy id - * @device: MDIO Managable Device (MMD) id - * @location: Register location to write - * @val: Value to write - * - * Returns -1 on error - * 0 on success - */ -static inline int cvmx_mdio_45_write(int bus_id, int phy_id, int device, - int location, int val) -{ - union cvmx_smix_cmd smi_cmd; - union cvmx_smix_wr_dat smi_wr; - int timeout = 1000; - - if (!octeon_has_feature(OCTEON_FEATURE_MDIO_CLAUSE_45)) - return -1; - - __cvmx_mdio_set_clause45_mode(bus_id); - - smi_wr.u64 = 0; - smi_wr.s.dat = location; - cvmx_write_csr(CVMX_SMIX_WR_DAT(bus_id), smi_wr.u64); - - smi_cmd.u64 = 0; - smi_cmd.s.phy_op = MDIO_CLAUSE_45_ADDRESS; - smi_cmd.s.phy_adr = phy_id; - smi_cmd.s.reg_adr = device; - cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64); - - do { - cvmx_wait(1000); - smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(bus_id)); - } while (smi_wr.s.pending && --timeout); - if (timeout <= 0) - return -1; - - smi_wr.u64 = 0; - smi_wr.s.dat = val; - cvmx_write_csr(CVMX_SMIX_WR_DAT(bus_id), smi_wr.u64); - - smi_cmd.u64 = 0; - smi_cmd.s.phy_op = MDIO_CLAUSE_45_WRITE; - smi_cmd.s.phy_adr = phy_id; - smi_cmd.s.reg_adr = device; - cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64); - - do { - cvmx_wait(1000); - smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(bus_id)); - } while (smi_wr.s.pending && --timeout); - if (timeout <= 0) - return -1; - - return 0; -} - -#endif -- cgit v0.10.2 From 1491eaf970eeb5b1285d88592706217a1c60ed85 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Mon, 12 Sep 2016 23:39:08 +0300 Subject: MIPS: Octeon: Split dlink_dsr-1000n.dts to allow reuse with D-Link DSR-500N. Signed-off-by: Aaro Koskinen Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Cc: devicetree@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14248/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/boot/dts/cavium-octeon/dlink_dsr-1000n.dts b/arch/mips/boot/dts/cavium-octeon/dlink_dsr-1000n.dts index b134798..cfa2915 100644 --- a/arch/mips/boot/dts/cavium-octeon/dlink_dsr-1000n.dts +++ b/arch/mips/boot/dts/cavium-octeon/dlink_dsr-1000n.dts @@ -8,55 +8,16 @@ * published by the Free Software Foundation. */ -/include/ "octeon_3xxx.dtsi" +/include/ "dlink_dsr-500n-1000n.dtsi" #include / { model = "dlink,dsr-1000n"; soc@0 { - smi0: mdio@1180000001800 { - phy8: ethernet-phy@8 { - reg = <8>; - compatible = "ethernet-phy-ieee802.3-c22"; - }; - }; - - pip: pip@11800a0000000 { - interface@0 { - ethernet@0 { - fixed-link { - speed = <1000>; - full-duplex; - }; - }; - ethernet@1 { - fixed-link { - speed = <1000>; - full-duplex; - }; - }; - ethernet@2 { - phy-handle = <&phy8>; - }; - }; - }; - - twsi0: i2c@1180000001000 { - rtc@68 { - compatible = "dallas,ds1337"; - reg = <0x68>; - }; - }; - uart0: serial@1180000000800 { clock-frequency = <500000000>; }; - - usbn: usbn@1180068000000 { - refclk-frequency = <12000000>; - refclk-type = "crystal"; - }; }; leds { @@ -87,8 +48,4 @@ gpios = <&gpio 18 GPIO_ACTIVE_LOW>; }; }; - - aliases { - pip = &pip; - }; }; diff --git a/arch/mips/boot/dts/cavium-octeon/dlink_dsr-500n-1000n.dtsi b/arch/mips/boot/dts/cavium-octeon/dlink_dsr-500n-1000n.dtsi new file mode 100644 index 0000000..246b598 --- /dev/null +++ b/arch/mips/boot/dts/cavium-octeon/dlink_dsr-500n-1000n.dtsi @@ -0,0 +1,58 @@ +/* + * Device tree source for D-Link DSR-500N/1000N (common parts). + * + * Written by: Aaro Koskinen + * + * 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/ "octeon_3xxx.dtsi" + +/ { + soc@0 { + smi0: mdio@1180000001800 { + phy8: ethernet-phy@8 { + reg = <8>; + compatible = "ethernet-phy-ieee802.3-c22"; + }; + }; + + pip: pip@11800a0000000 { + interface@0 { + ethernet@0 { + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + ethernet@1 { + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + ethernet@2 { + phy-handle = <&phy8>; + }; + }; + }; + + twsi0: i2c@1180000001000 { + rtc@68 { + compatible = "dallas,ds1337"; + reg = <0x68>; + }; + }; + + usbn: usbn@1180068000000 { + refclk-frequency = <12000000>; + refclk-type = "crystal"; + }; + }; + + aliases { + pip = &pip; + }; +}; -- cgit v0.10.2 From 6fcdc71735a5537931f3155e86540c47df18b9f3 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Mon, 12 Sep 2016 23:39:09 +0300 Subject: MIPS: Octeon: Add DTS for D-Link DSR-500N. Signed-off-by: Aaro Koskinen Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Cc: devicetree@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14249/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/boot/dts/cavium-octeon/dlink_dsr-500n.dts b/arch/mips/boot/dts/cavium-octeon/dlink_dsr-500n.dts new file mode 100644 index 0000000..78886e1 --- /dev/null +++ b/arch/mips/boot/dts/cavium-octeon/dlink_dsr-500n.dts @@ -0,0 +1,40 @@ +/* + * Device tree source for D-Link DSR-500N. + * + * Written by: Aaro Koskinen + * + * 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/ "dlink_dsr-500n-1000n.dtsi" +#include + +/ { + model = "dlink,dsr-500n"; + compatible = "dlink,dsr-500n", "cavium,octeon-3860"; + + soc@0 { + uart0: serial@1180000000800 { + clock-frequency = <300000000>; + }; + }; + + leds { + compatible = "gpio-leds"; + + usb { + gpios = <&gpio 9 GPIO_ACTIVE_LOW>; + }; + + wps { + gpios = <&gpio 11 GPIO_ACTIVE_LOW>; + }; + + wireless { + label = "2.4g"; + gpios = <&gpio 18 GPIO_ACTIVE_LOW>; + }; + }; +}; -- cgit v0.10.2 From e6e5b7b6d0de7e2c25b45fc7a0c914ed6aa1d5e8 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Mon, 12 Sep 2016 23:39:10 +0300 Subject: MIPS: Octeon: Fix PCI interrupt routing on D-Link DSR-500N. Signed-off-by: Aaro Koskinen Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Cc: devicetree@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14250/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/pci/pci-octeon.c b/arch/mips/pci/pci-octeon.c index c258cd4..308d051 100644 --- a/arch/mips/pci/pci-octeon.c +++ b/arch/mips/pci/pci-octeon.c @@ -204,6 +204,8 @@ const char *octeon_get_pci_interrupts(void) * Interrupt Number (INTA# = 0, INTB# = 1, INTC# = 2, and * INTD# = 3) */ + if (of_machine_is_compatible("dlink,dsr-500n")) + return "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"; switch (octeon_bootinfo->board_type) { case CVMX_BOARD_TYPE_NAO38: /* This is really the NAC38 */ -- cgit v0.10.2 From 6b89d22e742aa3fbb1878c2e6684b0bfd591f7c8 Mon Sep 17 00:00:00 2001 From: Matt Redfearn Date: Wed, 7 Sep 2016 10:45:09 +0100 Subject: MIPS: CPC: Convert bare 'unsigned' to 'unsigned int' Checkpatch complains about use of bare unsigned type. Signed-off-by: Matt Redfearn Reviewed-by: Paul Burton Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14217/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/kernel/mips-cpc.c b/arch/mips/kernel/mips-cpc.c index 566b8d2..0e337f5 100644 --- a/arch/mips/kernel/mips-cpc.c +++ b/arch/mips/kernel/mips-cpc.c @@ -52,7 +52,7 @@ static phys_addr_t mips_cpc_phys_base(void) int mips_cpc_probe(void) { phys_addr_t addr; - unsigned cpu; + unsigned int cpu; for_each_possible_cpu(cpu) spin_lock_init(&per_cpu(cpc_core_lock, cpu)); @@ -70,7 +70,7 @@ int mips_cpc_probe(void) void mips_cpc_lock_other(unsigned int core) { - unsigned curr_core; + unsigned int curr_core; preempt_disable(); curr_core = current_cpu_data.core; spin_lock_irqsave(&per_cpu(cpc_core_lock, curr_core), @@ -86,7 +86,7 @@ void mips_cpc_lock_other(unsigned int core) void mips_cpc_unlock_other(void) { - unsigned curr_core = current_cpu_data.core; + unsigned int curr_core = current_cpu_data.core; spin_unlock_irqrestore(&per_cpu(cpc_core_lock, curr_core), per_cpu(cpc_core_lock_flags, curr_core)); preempt_enable(); -- cgit v0.10.2 From d6219420480b75258b93583caa3885fb80d83313 Mon Sep 17 00:00:00 2001 From: Matt Redfearn Date: Wed, 7 Sep 2016 10:45:10 +0100 Subject: MIPS: CPC: Avoid lock when MIPS CM >= 3 is present MIPS CM version 3 removed the CPC_CL_OTHER register and instead the CM_CL_OTHER register is used to redirect the CPC_OTHER region. As such, we should not write the unimplmented register and can avoid the spinlock as well. These lock functions should aleady be called within the context of a mips_cm_{lock,unlock}_other pair ensuring the correct CPC_OTHER region will be accessed. Signed-off-by: Matt Redfearn Reviewed-by: Paul Burton Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14219/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/kernel/mips-cpc.c b/arch/mips/kernel/mips-cpc.c index 0e337f5..2a45867 100644 --- a/arch/mips/kernel/mips-cpc.c +++ b/arch/mips/kernel/mips-cpc.c @@ -71,6 +71,11 @@ int mips_cpc_probe(void) void mips_cpc_lock_other(unsigned int core) { unsigned int curr_core; + + if (mips_cm_revision() >= CM_REV_CM3) + /* Systems with CM >= 3 lock the CPC via mips_cm_lock_other */ + return; + preempt_disable(); curr_core = current_cpu_data.core; spin_lock_irqsave(&per_cpu(cpc_core_lock, curr_core), @@ -86,7 +91,13 @@ void mips_cpc_lock_other(unsigned int core) void mips_cpc_unlock_other(void) { - unsigned int curr_core = current_cpu_data.core; + unsigned int curr_core; + + if (mips_cm_revision() >= CM_REV_CM3) + /* Systems with CM >= 3 lock the CPC via mips_cm_lock_other */ + return; + + curr_core = current_cpu_data.core; spin_unlock_irqrestore(&per_cpu(cpc_core_lock, curr_core), per_cpu(cpc_core_lock_flags, curr_core)); preempt_enable(); -- cgit v0.10.2 From b97d0b9099afcd5c569acaf9b0eb3f6e3b1b1f35 Mon Sep 17 00:00:00 2001 From: Matt Redfearn Date: Wed, 7 Sep 2016 10:45:11 +0100 Subject: MIPS: pm-cps: Change FSB workaround to CPU blacklist The check for whether a CPU required the FSB flush workaround previously required every CPU not requiring it to be whitelisted. That approach does not scale well as new CPUs are introduced so change the default from a WARN and returning an error to just returning 0. Any CPUs requiring the workaround can then be added to the blacklist. Signed-off-by: Matt Redfearn Reviewed-by: Paul Burton Cc: Adam Buchbinder Cc: Masahiro Yamada Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14218/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/kernel/pm-cps.c b/arch/mips/kernel/pm-cps.c index 5b31a94..2faa227 100644 --- a/arch/mips/kernel/pm-cps.c +++ b/arch/mips/kernel/pm-cps.c @@ -272,14 +272,9 @@ static int __init cps_gen_flush_fsb(u32 **pp, struct uasm_label **pl, /* On older ones it's unavailable */ return -1; - /* CPUs which do not require the workaround */ - case CPU_P5600: - case CPU_I6400: - return 0; - default: - WARN_ONCE(1, "pm-cps: FSB flush unsupported for this CPU\n"); - return -1; + /* Assume that the CPU does not need this workaround */ + return 0; } /* -- cgit v0.10.2 From f6b43d935482abe28e9206ad10e1d2aa3fc78996 Mon Sep 17 00:00:00 2001 From: Matt Redfearn Date: Wed, 7 Sep 2016 10:45:12 +0100 Subject: MIPS: pm-cps: Update comments on barrier instructions This code makes large use of barriers, which had quite vague descriptions. Update the comments to make the choice of barrier and reason for it more clear. Signed-off-by: Matt Redfearn Reviewed-by: Paul Burton Cc: Adam Buchbinder Cc: Masahiro Yamada Cc: Kees Cook Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14220/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/kernel/pm-cps.c b/arch/mips/kernel/pm-cps.c index 2faa227..7e8d4aa 100644 --- a/arch/mips/kernel/pm-cps.c +++ b/arch/mips/kernel/pm-cps.c @@ -315,7 +315,7 @@ static int __init cps_gen_flush_fsb(u32 **pp, struct uasm_label **pl, i * line_size * line_stride, t0); } - /* Completion barrier */ + /* Barrier ensuring previous cache invalidates are complete */ uasm_i_sync(pp, stype_memory); uasm_i_ehb(pp); @@ -414,7 +414,7 @@ static void * __init cps_gen_entry_code(unsigned cpu, enum cps_pm_state state) uasm_il_beqz(&p, &r, t2, lbl_incready); uasm_i_addiu(&p, t1, t1, 1); - /* Ordering barrier */ + /* Barrier ensuring all CPUs see the updated r_nc_count value */ uasm_i_sync(&p, stype_ordering); /* @@ -467,7 +467,7 @@ static void * __init cps_gen_entry_code(unsigned cpu, enum cps_pm_state state) cps_gen_cache_routine(&p, &l, &r, &cpu_data[cpu].dcache, Index_Writeback_Inv_D, lbl_flushdcache); - /* Completion barrier */ + /* Barrier ensuring previous cache invalidates are complete */ uasm_i_sync(&p, stype_memory); uasm_i_ehb(&p); @@ -480,7 +480,7 @@ static void * __init cps_gen_entry_code(unsigned cpu, enum cps_pm_state state) uasm_i_sw(&p, t0, 0, r_pcohctl); uasm_i_lw(&p, t0, 0, r_pcohctl); - /* Sync to ensure previous interventions are complete */ + /* Barrier to ensure write to coherence control is complete */ uasm_i_sync(&p, stype_intervention); uasm_i_ehb(&p); @@ -526,7 +526,7 @@ static void * __init cps_gen_entry_code(unsigned cpu, enum cps_pm_state state) goto gen_done; } - /* Completion barrier */ + /* Barrier to ensure write to CPC command is complete */ uasm_i_sync(&p, stype_memory); uasm_i_ehb(&p); } @@ -561,7 +561,7 @@ static void * __init cps_gen_entry_code(unsigned cpu, enum cps_pm_state state) uasm_i_sw(&p, t0, 0, r_pcohctl); uasm_i_lw(&p, t0, 0, r_pcohctl); - /* Completion barrier */ + /* Barrier to ensure write to coherence control is complete */ uasm_i_sync(&p, stype_memory); uasm_i_ehb(&p); @@ -575,7 +575,7 @@ static void * __init cps_gen_entry_code(unsigned cpu, enum cps_pm_state state) uasm_il_beqz(&p, &r, t2, lbl_decready); uasm_i_andi(&p, v0, t1, (1 << fls(smp_num_siblings)) - 1); - /* Ordering barrier */ + /* Barrier ensuring all CPUs see the updated r_nc_count value */ uasm_i_sync(&p, stype_ordering); } @@ -597,7 +597,7 @@ static void * __init cps_gen_entry_code(unsigned cpu, enum cps_pm_state state) */ uasm_build_label(&l, p, lbl_secondary_cont); - /* Ordering barrier */ + /* Barrier ensuring all CPUs see the updated r_nc_count value */ uasm_i_sync(&p, stype_ordering); } -- cgit v0.10.2 From 6622ada354ba2c865c6ee1854e130c3abb430808 Mon Sep 17 00:00:00 2001 From: Matt Redfearn Date: Wed, 7 Sep 2016 10:45:13 +0100 Subject: MIPS: Barrier: Add definitions of SYNC stype values Add the definitions of sync stype 0 (global completion barrier) and sync stype 0x10 (local ordering barrier) to barrier.h for use with the sync instruction. These types are defined by the MIPS Instruction Set since R2 of the architecture and are documented in document MD00087 table 6.5. Signed-off-by: Matt Redfearn Reviewed-by: Paul Burton Cc: Arnd Bergmann Cc: Michael S. Tsirkin Cc: Peter Zijlstra Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14222/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/include/asm/barrier.h b/arch/mips/include/asm/barrier.h index d296633..a5eb1bb 100644 --- a/arch/mips/include/asm/barrier.h +++ b/arch/mips/include/asm/barrier.h @@ -10,6 +10,102 @@ #include +/* + * Sync types defined by the MIPS architecture (document MD00087 table 6.5) + * These values are used with the sync instruction to perform memory barriers. + * Types of ordering guarantees available through the SYNC instruction: + * - Completion Barriers + * - Ordering Barriers + * As compared to the completion barrier, the ordering barrier is a + * lighter-weight operation as it does not require the specified instructions + * before the SYNC to be already completed. Instead it only requires that those + * specified instructions which are subsequent to the SYNC in the instruction + * stream are never re-ordered for processing ahead of the specified + * instructions which are before the SYNC in the instruction stream. + * This potentially reduces how many cycles the barrier instruction must stall + * before it completes. + * Implementations that do not use any of the non-zero values of stype to define + * different barriers, such as ordering barriers, must make those stype values + * act the same as stype zero. + */ + +/* + * Completion barriers: + * - Every synchronizable specified memory instruction (loads or stores or both) + * that occurs in the instruction stream before the SYNC instruction must be + * already globally performed before any synchronizable specified memory + * instructions that occur after the SYNC are allowed to be performed, with + * respect to any other processor or coherent I/O module. + * + * - The barrier does not guarantee the order in which instruction fetches are + * performed. + * + * - A stype value of zero will always be defined such that it performs the most + * complete set of synchronization operations that are defined.This means + * stype zero always does a completion barrier that affects both loads and + * stores preceding the SYNC instruction and both loads and stores that are + * subsequent to the SYNC instruction. Non-zero values of stype may be defined + * by the architecture or specific implementations to perform synchronization + * behaviors that are less complete than that of stype zero. If an + * implementation does not use one of these non-zero values to define a + * different synchronization behavior, then that non-zero value of stype must + * act the same as stype zero completion barrier. This allows software written + * for an implementation with a lighter-weight barrier to work on another + * implementation which only implements the stype zero completion barrier. + * + * - A completion barrier is required, potentially in conjunction with SSNOP (in + * Release 1 of the Architecture) or EHB (in Release 2 of the Architecture), + * to guarantee that memory reference results are visible across operating + * mode changes. For example, a completion barrier is required on some + * implementations on entry to and exit from Debug Mode to guarantee that + * memory effects are handled correctly. + */ + +/* + * stype 0 - A completion barrier that affects preceding loads and stores and + * subsequent loads and stores. + * Older instructions which must reach the load/store ordering point before the + * SYNC instruction completes: Loads, Stores + * Younger instructions which must reach the load/store ordering point only + * after the SYNC instruction completes: Loads, Stores + * Older instructions which must be globally performed when the SYNC instruction + * completes: Loads, Stores + */ +#define STYPE_SYNC 0x0 + +/* + * Ordering barriers: + * - Every synchronizable specified memory instruction (loads or stores or both) + * that occurs in the instruction stream before the SYNC instruction must + * reach a stage in the load/store datapath after which no instruction + * re-ordering is possible before any synchronizable specified memory + * instruction which occurs after the SYNC instruction in the instruction + * stream reaches the same stage in the load/store datapath. + * + * - If any memory instruction before the SYNC instruction in program order, + * generates a memory request to the external memory and any memory + * instruction after the SYNC instruction in program order also generates a + * memory request to external memory, the memory request belonging to the + * older instruction must be globally performed before the time the memory + * request belonging to the younger instruction is globally performed. + * + * - The barrier does not guarantee the order in which instruction fetches are + * performed. + */ + +/* + * stype 0x10 - An ordering barrier that affects preceding loads and stores and + * subsequent loads and stores. + * Older instructions which must reach the load/store ordering point before the + * SYNC instruction completes: Loads, Stores + * Younger instructions which must reach the load/store ordering point only + * after the SYNC instruction completes: Loads, Stores + * Older instructions which must be globally performed when the SYNC instruction + * completes: N/A + */ +#define STYPE_SYNC_MB 0x10 + + #ifdef CONFIG_CPU_HAS_SYNC #define __sync() \ __asm__ __volatile__( \ -- cgit v0.10.2 From 85e540be7549c8eda90f056d30534be8f58777a7 Mon Sep 17 00:00:00 2001 From: Matt Redfearn Date: Wed, 7 Sep 2016 10:45:14 +0100 Subject: MIPS: pm-cps: Use MIPS standard lightweight ordering barrier Since R2 of the MIPS architecture, SYNC(0x10) has been an optional but architecturally defined ordering barrier. If a CPU does not implement it, the arch specifies that it must fall back to SYNC(0). In places where we require that the instruction stream not be reordered, but do not require that loads / stores are gloablly completed, use the defined standard sync stype. Signed-off-by: Matt Redfearn Reviewed-by: Paul Burton Cc: Adam Buchbinder Cc: Masahiro Yamada Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14221/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/kernel/pm-cps.c b/arch/mips/kernel/pm-cps.c index 7e8d4aa..d7037fe0 100644 --- a/arch/mips/kernel/pm-cps.c +++ b/arch/mips/kernel/pm-cps.c @@ -76,7 +76,6 @@ static struct uasm_reloc relocs[32] __initdata; /* CPU dependant sync types */ static unsigned stype_intervention; static unsigned stype_memory; -static unsigned stype_ordering; enum mips_reg { zero, at, v0, v1, a0, a1, a2, a3, @@ -406,7 +405,7 @@ static void * __init cps_gen_entry_code(unsigned cpu, enum cps_pm_state state) if (coupled_coherence) { /* Increment ready_count */ - uasm_i_sync(&p, stype_ordering); + uasm_i_sync(&p, STYPE_SYNC_MB); uasm_build_label(&l, p, lbl_incready); uasm_i_ll(&p, t1, 0, r_nc_count); uasm_i_addiu(&p, t2, t1, 1); @@ -415,7 +414,7 @@ static void * __init cps_gen_entry_code(unsigned cpu, enum cps_pm_state state) uasm_i_addiu(&p, t1, t1, 1); /* Barrier ensuring all CPUs see the updated r_nc_count value */ - uasm_i_sync(&p, stype_ordering); + uasm_i_sync(&p, STYPE_SYNC_MB); /* * If this is the last VPE to become ready for non-coherence @@ -568,7 +567,7 @@ static void * __init cps_gen_entry_code(unsigned cpu, enum cps_pm_state state) if (coupled_coherence && (state == CPS_PM_NC_WAIT)) { /* Decrement ready_count */ uasm_build_label(&l, p, lbl_decready); - uasm_i_sync(&p, stype_ordering); + uasm_i_sync(&p, STYPE_SYNC_MB); uasm_i_ll(&p, t1, 0, r_nc_count); uasm_i_addiu(&p, t2, t1, -1); uasm_i_sc(&p, t2, 0, r_nc_count); @@ -576,7 +575,7 @@ static void * __init cps_gen_entry_code(unsigned cpu, enum cps_pm_state state) uasm_i_andi(&p, v0, t1, (1 << fls(smp_num_siblings)) - 1); /* Barrier ensuring all CPUs see the updated r_nc_count value */ - uasm_i_sync(&p, stype_ordering); + uasm_i_sync(&p, STYPE_SYNC_MB); } if (coupled_coherence && (state == CPS_PM_CLOCK_GATED)) { @@ -598,7 +597,7 @@ static void * __init cps_gen_entry_code(unsigned cpu, enum cps_pm_state state) uasm_build_label(&l, p, lbl_secondary_cont); /* Barrier ensuring all CPUs see the updated r_nc_count value */ - uasm_i_sync(&p, stype_ordering); + uasm_i_sync(&p, STYPE_SYNC_MB); } /* The core is coherent, time to return to C code */ @@ -677,7 +676,6 @@ static int __init cps_pm_init(void) case CPU_I6400: stype_intervention = 0x2; stype_memory = 0x3; - stype_ordering = 0x10; break; default: -- cgit v0.10.2 From 90b084b1bc7ebde5379017c29ae617fcc4ccd557 Mon Sep 17 00:00:00 2001 From: Matt Redfearn Date: Wed, 7 Sep 2016 10:45:15 +0100 Subject: MIPS: pm-cps: Use MIPS standard completion barrier SYNC type 0 is defined in the MIPS architecture as a completion barrier where all loads/stores in the pipeline before the sync instruction must complete before any loads/stores subsequent to the sync instruction. In places where we require loads / stores be globally completed, use the standard completion sync stype. Signed-off-by: Matt Redfearn Reviewed-by: Paul Burton Cc: Adam Buchbinder Cc: Masahiro Yamada Cc: Andrew Morton Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14224/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/kernel/pm-cps.c b/arch/mips/kernel/pm-cps.c index d7037fe0..953ff0d 100644 --- a/arch/mips/kernel/pm-cps.c +++ b/arch/mips/kernel/pm-cps.c @@ -315,7 +315,7 @@ static int __init cps_gen_flush_fsb(u32 **pp, struct uasm_label **pl, } /* Barrier ensuring previous cache invalidates are complete */ - uasm_i_sync(pp, stype_memory); + uasm_i_sync(pp, STYPE_SYNC); uasm_i_ehb(pp); /* Check whether the pipeline stalled due to the FSB being full */ @@ -467,7 +467,7 @@ static void * __init cps_gen_entry_code(unsigned cpu, enum cps_pm_state state) Index_Writeback_Inv_D, lbl_flushdcache); /* Barrier ensuring previous cache invalidates are complete */ - uasm_i_sync(&p, stype_memory); + uasm_i_sync(&p, STYPE_SYNC); uasm_i_ehb(&p); /* @@ -480,7 +480,7 @@ static void * __init cps_gen_entry_code(unsigned cpu, enum cps_pm_state state) uasm_i_lw(&p, t0, 0, r_pcohctl); /* Barrier to ensure write to coherence control is complete */ - uasm_i_sync(&p, stype_intervention); + uasm_i_sync(&p, STYPE_SYNC); uasm_i_ehb(&p); /* Disable coherence */ @@ -526,7 +526,7 @@ static void * __init cps_gen_entry_code(unsigned cpu, enum cps_pm_state state) } /* Barrier to ensure write to CPC command is complete */ - uasm_i_sync(&p, stype_memory); + uasm_i_sync(&p, STYPE_SYNC); uasm_i_ehb(&p); } @@ -561,7 +561,7 @@ static void * __init cps_gen_entry_code(unsigned cpu, enum cps_pm_state state) uasm_i_lw(&p, t0, 0, r_pcohctl); /* Barrier to ensure write to coherence control is complete */ - uasm_i_sync(&p, stype_memory); + uasm_i_sync(&p, STYPE_SYNC); uasm_i_ehb(&p); if (coupled_coherence && (state == CPS_PM_NC_WAIT)) { -- cgit v0.10.2 From 15ea26cf510ce07c9397579ce869f7f3713eaae4 Mon Sep 17 00:00:00 2001 From: Matt Redfearn Date: Wed, 7 Sep 2016 10:45:16 +0100 Subject: MIPS: pm-cps: Remove selection of sync types Instead of selecting an implementation or vendor specific sync type for the required sync operations, always use the architecturally mandated sync types which previous patches have put in place. The selection of special sync types is now redundant an can be removed. Signed-off-by: Matt Redfearn Reviewed-by: Paul Burton Cc: Adam Buchbinder Cc: Masahiro Yamada Cc: Kees Cook Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14223/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/kernel/pm-cps.c b/arch/mips/kernel/pm-cps.c index 953ff0d..b3a7d36 100644 --- a/arch/mips/kernel/pm-cps.c +++ b/arch/mips/kernel/pm-cps.c @@ -73,10 +73,6 @@ DEFINE_PER_CPU_ALIGNED(struct mips_static_suspend_state, cps_cpu_state); static struct uasm_label labels[32] __initdata; static struct uasm_reloc relocs[32] __initdata; -/* CPU dependant sync types */ -static unsigned stype_intervention; -static unsigned stype_memory; - enum mips_reg { zero, at, v0, v1, a0, a1, a2, a3, t0, t1, t2, t3, t4, t5, t6, t7, @@ -667,21 +663,6 @@ static int __init cps_pm_init(void) unsigned cpu; int err; - /* Detect appropriate sync types for the system */ - switch (current_cpu_data.cputype) { - case CPU_INTERAPTIV: - case CPU_PROAPTIV: - case CPU_M5150: - case CPU_P5600: - case CPU_I6400: - stype_intervention = 0x2; - stype_memory = 0x3; - break; - - default: - pr_warn("Power management is using heavyweight sync 0\n"); - } - /* A CM is required for all non-coherent states */ if (!mips_cm_present()) { pr_warn("pm-cps: no CM, non-coherent states unavailable\n"); -- cgit v0.10.2 From 929d4f51e6b87900c9179eb62d6b43db6ce4930d Mon Sep 17 00:00:00 2001 From: Matt Redfearn Date: Wed, 7 Sep 2016 10:45:17 +0100 Subject: MIPS: pm-cps: Add MIPSr6 CPU support This patch adds support for CPUs implementing the MIPSr6 ISA to the CPS power management code. Three changes are necessary: 1. In MIPSr6, coupled coherence is necessary when CPUS implement multiple Virtual Processors (VPs). 2. MIPSr6 virtual processors are more like real cores and cannot yield to other VPs on the same core, so drop the MT ASE yield instruction. 3. To halt a MIPSr6 VP, the CPC VP_STOP register is used rather than the MT ASE TCHalt CP0 register. Signed-off-by: Matt Redfearn Reviewed-by: Paul Burton Cc: Adam Buchbinder Cc: Masahiro Yamada Cc: Kees Cook Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14225/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/include/asm/pm-cps.h b/arch/mips/include/asm/pm-cps.h index 625eda5..89d58d8 100644 --- a/arch/mips/include/asm/pm-cps.h +++ b/arch/mips/include/asm/pm-cps.h @@ -13,10 +13,12 @@ /* * The CM & CPC can only handle coherence & power control on a per-core basis, - * thus in an MT system the VPEs within each core are coupled and can only + * thus in an MT system the VP(E)s within each core are coupled and can only * enter or exit states requiring CM or CPC assistance in unison. */ -#ifdef CONFIG_MIPS_MT +#if defined(CONFIG_CPU_MIPSR6) +# define coupled_coherence cpu_has_vp +#elif defined(CONFIG_MIPS_MT) # define coupled_coherence cpu_has_mipsmt #else # define coupled_coherence 0 diff --git a/arch/mips/kernel/pm-cps.c b/arch/mips/kernel/pm-cps.c index b3a7d36..440e792 100644 --- a/arch/mips/kernel/pm-cps.c +++ b/arch/mips/kernel/pm-cps.c @@ -129,7 +129,7 @@ int cps_pm_enter_state(enum cps_pm_state state) return -EINVAL; /* Calculate which coupled CPUs (VPEs) are online */ -#ifdef CONFIG_MIPS_MT +#if defined(CONFIG_MIPS_MT) || defined(CONFIG_CPU_MIPSR6) if (cpu_online(cpu)) { cpumask_and(coupled_mask, cpu_online_mask, &cpu_sibling_map[cpu]); @@ -431,7 +431,8 @@ static void * __init cps_gen_entry_code(unsigned cpu, enum cps_pm_state state) uasm_i_lw(&p, t0, 0, r_nc_count); uasm_il_bltz(&p, &r, t0, lbl_secondary_cont); uasm_i_ehb(&p); - uasm_i_yield(&p, zero, t1); + if (cpu_has_mipsmt) + uasm_i_yield(&p, zero, t1); uasm_il_b(&p, &r, lbl_poll_cont); uasm_i_nop(&p); } else { @@ -439,8 +440,21 @@ static void * __init cps_gen_entry_code(unsigned cpu, enum cps_pm_state state) * The core will lose power & this VPE will not continue * so it can simply halt here. */ - uasm_i_addiu(&p, t0, zero, TCHALT_H); - uasm_i_mtc0(&p, t0, 2, 4); + if (cpu_has_mipsmt) { + /* Halt the VPE via C0 tchalt register */ + uasm_i_addiu(&p, t0, zero, TCHALT_H); + uasm_i_mtc0(&p, t0, 2, 4); + } else if (cpu_has_vp) { + /* Halt the VP via the CPC VP_STOP register */ + unsigned int vpe_id; + + vpe_id = cpu_vpe_id(&cpu_data[cpu]); + uasm_i_addiu(&p, t0, zero, 1 << vpe_id); + UASM_i_LA(&p, t1, (long)addr_cpc_cl_vp_stop()); + uasm_i_sw(&p, t0, 0, t1); + } else { + BUG(); + } uasm_build_label(&l, p, lbl_secondary_hang); uasm_il_b(&p, &r, lbl_secondary_hang); uasm_i_nop(&p); -- cgit v0.10.2 From 77451997237fa7e8ba4f5e2f0fcd99898f78ff9b Mon Sep 17 00:00:00 2001 From: Matt Redfearn Date: Wed, 7 Sep 2016 10:45:18 +0100 Subject: MIPS: pm-cps: Support CM3 changes to Coherence Enable Register MIPS CM3 changed the management of coherence. Instead of a coherence control register with a bitmask of coherent domains, CM3 simply has a coherence enable register with a single bit to enable coherence of the local core. Support this by clearing and setting this single bit to disable / enable coherence. Signed-off-by: Matt Redfearn Reviewed-by: Paul Burton Cc: Adam Buchbinder Cc: Tony Wu Cc: Masahiro Yamada Cc: Nikolay Martynov Cc: Kees Cook Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14226/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/include/asm/mips-cm.h b/arch/mips/include/asm/mips-cm.h index 4fafeef..2e41807 100644 --- a/arch/mips/include/asm/mips-cm.h +++ b/arch/mips/include/asm/mips-cm.h @@ -359,6 +359,7 @@ BUILD_CM_Cx_R_(tcid_8_priority, 0x80) /* GCR_Cx_COHERENCE register fields */ #define CM_GCR_Cx_COHERENCE_COHDOMAINEN_SHF 0 #define CM_GCR_Cx_COHERENCE_COHDOMAINEN_MSK (_ULCAST_(0xff) << 0) +#define CM3_GCR_Cx_COHERENCE_COHEN_MSK (_ULCAST_(0x1) << 0) /* GCR_Cx_CONFIG register fields */ #define CM_GCR_Cx_CONFIG_IOCUTYPE_SHF 10 diff --git a/arch/mips/kernel/pm-cps.c b/arch/mips/kernel/pm-cps.c index 440e792..05bcded 100644 --- a/arch/mips/kernel/pm-cps.c +++ b/arch/mips/kernel/pm-cps.c @@ -480,18 +480,20 @@ static void * __init cps_gen_entry_code(unsigned cpu, enum cps_pm_state state) uasm_i_sync(&p, STYPE_SYNC); uasm_i_ehb(&p); - /* - * Disable all but self interventions. The load from COHCTL is defined - * by the interAptiv & proAptiv SUMs as ensuring that the operation - * resulting from the preceding store is complete. - */ - uasm_i_addiu(&p, t0, zero, 1 << cpu_data[cpu].core); - uasm_i_sw(&p, t0, 0, r_pcohctl); - uasm_i_lw(&p, t0, 0, r_pcohctl); - - /* Barrier to ensure write to coherence control is complete */ - uasm_i_sync(&p, STYPE_SYNC); - uasm_i_ehb(&p); + if (mips_cm_revision() < CM_REV_CM3) { + /* + * Disable all but self interventions. The load from COHCTL is + * defined by the interAptiv & proAptiv SUMs as ensuring that the + * operation resulting from the preceding store is complete. + */ + uasm_i_addiu(&p, t0, zero, 1 << cpu_data[cpu].core); + uasm_i_sw(&p, t0, 0, r_pcohctl); + uasm_i_lw(&p, t0, 0, r_pcohctl); + + /* Barrier to ensure write to coherence control is complete */ + uasm_i_sync(&p, STYPE_SYNC); + uasm_i_ehb(&p); + } /* Disable coherence */ uasm_i_sw(&p, zero, 0, r_pcohctl); @@ -566,7 +568,10 @@ static void * __init cps_gen_entry_code(unsigned cpu, enum cps_pm_state state) * will run this. The first will actually re-enable coherence & the * rest will just be performing a rather unusual nop. */ - uasm_i_addiu(&p, t0, zero, CM_GCR_Cx_COHERENCE_COHDOMAINEN_MSK); + uasm_i_addiu(&p, t0, zero, mips_cm_revision() < CM_REV_CM3 + ? CM_GCR_Cx_COHERENCE_COHDOMAINEN_MSK + : CM3_GCR_Cx_COHERENCE_COHEN_MSK); + uasm_i_sw(&p, t0, 0, r_pcohctl); uasm_i_lw(&p, t0, 0, r_pcohctl); -- cgit v0.10.2 From 4b6401365a6ccc53de820209cb328507a2103d30 Mon Sep 17 00:00:00 2001 From: Matt Redfearn Date: Wed, 7 Sep 2016 10:45:19 +0100 Subject: MIPS: SMP: Wrap call to mips_cpc_lock_other in mips_cm_lock_other All calls to mips_cpc_lock_other should be wrapped in mips_cm_lock_other. This only matters if the system has CM3 and is using cpu idle, since otherwise a) the CPC lock is sufficent for CM < 3 and b) any systems with CM > 3 have not been able to use cpu idle until now. Signed-off-by: Matt Redfearn Reviewed-by: Paul Burton Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Cc: Thomas Gleixner Cc: James Hogan Cc: Qais Yousef Patchwork: https://patchwork.linux-mips.org/patch/14227/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index b0baf48..cb02df2 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c @@ -192,9 +192,11 @@ void mips_smp_send_ipi_mask(const struct cpumask *mask, unsigned int action) continue; while (!cpumask_test_cpu(cpu, &cpu_coherent_mask)) { + mips_cm_lock_other(core, 0); mips_cpc_lock_other(core); write_cpc_co_cmd(CPC_Cx_CMD_PWRUP); mips_cpc_unlock_other(); + mips_cm_unlock_other(); } } } -- cgit v0.10.2 From 72bc8c75eaf72aa0e45652d09f1b80dd5346797e Mon Sep 17 00:00:00 2001 From: Matt Redfearn Date: Wed, 7 Sep 2016 10:45:20 +0100 Subject: cpuidle: cpuidle-cps: Enable use with MIPSr6 CPUs. This patch enables the MIPS CPS driver for MIPSr6 CPUs. Signed-off-by: Matt Redfearn Reviewed-by: Paul Burton Reviewed-by: Daniel Lezcano Cc: Rafael J. Wysocki Cc: linux-mips@linux-mips.org Cc: linux-pm@vger.kernel.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14228/ Signed-off-by: Ralf Baechle diff --git a/drivers/cpuidle/Kconfig.mips b/drivers/cpuidle/Kconfig.mips index 4102be0..512ee37 100644 --- a/drivers/cpuidle/Kconfig.mips +++ b/drivers/cpuidle/Kconfig.mips @@ -5,7 +5,7 @@ config MIPS_CPS_CPUIDLE bool "CPU Idle driver for MIPS CPS platforms" depends on CPU_IDLE && MIPS_CPS depends on SYS_SUPPORTS_MIPS_CPS - select ARCH_NEEDS_CPU_IDLE_COUPLED if MIPS_MT + select ARCH_NEEDS_CPU_IDLE_COUPLED if MIPS_MT || CPU_MIPSR6 select GENERIC_CLOCKEVENTS_BROADCAST if SMP select MIPS_CPS_PM default y diff --git a/drivers/cpuidle/cpuidle-cps.c b/drivers/cpuidle/cpuidle-cps.c index 1adb698..926ba98 100644 --- a/drivers/cpuidle/cpuidle-cps.c +++ b/drivers/cpuidle/cpuidle-cps.c @@ -163,7 +163,7 @@ static int __init cps_cpuidle_init(void) core = cpu_data[cpu].core; device = &per_cpu(cpuidle_dev, cpu); device->cpu = cpu; -#ifdef CONFIG_MIPS_MT +#ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED cpumask_copy(&device->coupled_cpus, &cpu_sibling_map[cpu]); #endif -- cgit v0.10.2 From 18022894eca1315851bfd0614f011fbc01e44d16 Mon Sep 17 00:00:00 2001 From: James Hogan Date: Thu, 1 Sep 2016 17:30:07 +0100 Subject: MIPS: traps: 64bit kernels should read CP0_EBase 64bit When reading the CP0_EBase register containing the WG (write gate) bit, the ebase variable should be set to the full value of the register, i.e. on a 64-bit kernel the full 64-bit width of the register via read_cp0_ebase_64(), and on a 32-bit kernel the full 32-bit width including bits 31:30 which may be writeable. Signed-off-by: James Hogan Signed-off-by: Matt Redfearn Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/14148/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 6061d47..4b60fb5 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -2215,8 +2215,17 @@ void __init trap_init(void) } else { ebase = CAC_BASE; - if (cpu_has_mips_r2_r6) - ebase += (read_c0_ebase() & 0x3ffff000); + if (cpu_has_mips_r2_r6) { + if (cpu_has_ebase_wg) { +#ifdef CONFIG_64BIT + ebase = (read_c0_ebase_64() & ~0xfff); +#else + ebase = (read_c0_ebase() & ~0xfff); +#endif + } else { + ebase += (read_c0_ebase() & 0x3ffff000); + } + } } if (cpu_has_mmips) { -- cgit v0.10.2 From c195e079e9dd00ffeb274965737280ca6d10ff70 Mon Sep 17 00:00:00 2001 From: James Hogan Date: Thu, 1 Sep 2016 17:30:08 +0100 Subject: MIPS: traps: Convert ebase to KSEG0 When allocating boot memory for the exception vector when vectored interrupts (vint) or vectored external interrupt controllers (veic) are enabled, try to ensure that the virtual address resides in KSeg0 (and WARN should that not be possible). This will be helpful on MIPS64 cores supporting the CP0_EBase Write Gate (WG) bit once we start using the WG bit to write the full ebase into CP0_EBase, as we ideally need to avoid hitting the architecturally poorly defined exception base for Cache Errors when CP0_EBase is in XKPhys. An exception is made for Enhanced Virtual Addressing (EVA) kernels which allow segments to be rearranged and to become uncached during cache error handling, making it valid for ebase to be elsewhere. Signed-off-by: James Hogan Cc: Matt Redfearn Cc: Leonid Yegoshin Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/14149/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 4b60fb5..edc0c3d 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -2210,8 +2210,25 @@ void __init trap_init(void) if (cpu_has_veic || cpu_has_vint) { unsigned long size = 0x200 + VECTORSPACING*64; + phys_addr_t ebase_pa; + ebase = (unsigned long) __alloc_bootmem(size, 1 << fls(size), 0); + + /* + * Try to ensure ebase resides in KSeg0 if possible. + * + * It shouldn't generally be in XKPhys on MIPS64 to avoid + * hitting a poorly defined exception base for Cache Errors. + * The allocation is likely to be in the low 512MB of physical, + * in which case we should be able to convert to KSeg0. + * + * EVA is special though as it allows segments to be rearranged + * and to become uncached during cache error handling. + */ + ebase_pa = __pa(ebase); + if (!IS_ENABLED(CONFIG_EVA) && !WARN_ON(ebase_pa >= 0x20000000)) + ebase = CKSEG0ADDR(ebase_pa); } else { ebase = CAC_BASE; -- cgit v0.10.2 From 4b22c693e325af075d78069e25d6c17cb102c73e Mon Sep 17 00:00:00 2001 From: Matt Redfearn Date: Thu, 1 Sep 2016 17:30:09 +0100 Subject: MIPS: traps: Ensure full EBase is written On CPUs which support the EBase WG (write gate) flag, the most significant bits of the exception base can be changed. Firmware running on a VP(E) using MIPS rproc may change EBase to point into the user segment where the firmware is located such that it can service interrupts. When control is transferred back to the kernel the EBase must be switched back into the kernel segment, such that the kernel's exception vectors are used. Similarly when vectored interrupts (vint) or vectored external interrupt controllers (veic) are enabled an exception vector is allocated from bootmem, and written to the EBase register. Due to the WG flag being clear, only bits 29:12 will be written. Asside from the rproc case above this is normally fine (as it will usually be a low allocation within the KSeg0 range, however when Enhanced Virtual Addressing (EVA) is enabled the allocation may be outside of the traditional KSeg0/KSeg1 address range, resulting in the wrong EBase being written. Correct both cases (configure_exception_vector() for the boot CPU, and per_cpu_trap_init() for secondary CPUs) to write EBase with the WG flag first if supported. On the Malta EVA configuration, KSeg0 is mapped to physical address 0, and memory is allocated from the KUSeg segment which is mapped to physical address 0x80000000, which physically aliases the RAM at 0. This only worked due to the exception base address aliasing the same underlying RAM that was written to & cache flushed, and due to flush_icache_range() going beyond the call of duty and flushing from the L2 cache too (due to the differing physical addresses). Signed-off-by: Matt Redfearn Signed-off-by: James Hogan Cc: Leonid Yegoshin Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/14150/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index edc0c3d..0c0270c 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -2092,6 +2092,14 @@ static void configure_exception_vector(void) { if (cpu_has_veic || cpu_has_vint) { unsigned long sr = set_c0_status(ST0_BEV); + /* If available, use WG to set top bits of EBASE */ + if (cpu_has_ebase_wg) { +#ifdef CONFIG_64BIT + write_c0_ebase_64(ebase | MIPS_EBASE_WG); +#else + write_c0_ebase(ebase | MIPS_EBASE_WG); +#endif + } write_c0_ebase(ebase); write_c0_status(sr); /* Setting vector spacing enables EI/VI mode */ @@ -2128,8 +2136,17 @@ void per_cpu_trap_init(bool is_boot_cpu) * We shouldn't trust a secondary core has a sane EBASE register * so use the one calculated by the boot CPU. */ - if (!is_boot_cpu) + if (!is_boot_cpu) { + /* If available, use WG to set top bits of EBASE */ + if (cpu_has_ebase_wg) { +#ifdef CONFIG_64BIT + write_c0_ebase_64(ebase | MIPS_EBASE_WG); +#else + write_c0_ebase(ebase | MIPS_EBASE_WG); +#endif + } write_c0_ebase(ebase); + } cp0_compare_irq_shift = CAUSEB_TI - CAUSEB_IP; cp0_compare_irq = (read_c0_intctl() >> INTCTLB_IPTI) & 7; -- cgit v0.10.2 From d260d97e64c0d988eab3c420ab1497037d1af26f Mon Sep 17 00:00:00 2001 From: James Hogan Date: Thu, 1 Sep 2016 17:30:10 +0100 Subject: MIPS: c-r4k: Drop bc_wback_inv() from icache flush The EVA conditional bc_wback_inv() at the end of flush_icache_range() to flush the modified code all the way back to RAM was apparently there for debug purposes and to accommodate the Malta EVA configuration which makes use of a physical alias, and didn't use the CP0_EBase.WG (Write Gate) bit to put the exception vector in the same physical alias where the exception vector code is written and is being flushed. Now that CP0_EBase.WG is used, lets drop this flush. Signed-off-by: James Hogan Cc: Leonid Yegoshin Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/14151/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index fa7d8d3..bbb7dfe 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -752,17 +752,6 @@ static inline void __local_r4k_flush_icache_range(unsigned long start, break; } } -#ifdef CONFIG_EVA - /* - * Due to all possible segment mappings, there might cache aliases - * caused by the bootloader being in non-EVA mode, and the CPU switching - * to EVA during early kernel init. It's best to flush the scache - * to avoid having secondary cores fetching stale data and lead to - * kernel crashes. - */ - bc_wback_inv(start, (end - start)); - __sync(); -#endif } static inline void local_r4k_flush_icache_range(unsigned long start, -- cgit v0.10.2 From 01882b4d5eae2800c8e86a29d279020f87e5d4f3 Mon Sep 17 00:00:00 2001 From: James Hogan Date: Thu, 1 Sep 2016 17:30:11 +0100 Subject: MIPS: c-r4k: Split user/kernel flush_icache_range() flush_icache_range() is used for both user addresses (i.e. cacheflush(2)), and kernel addresses (as the API documentation describes). This isn't really suitable however for Enhanced Virtual Addressing (EVA) where cache operations on usermode addresses must use a different instruction, and the protected cache ops assume user addresses, making flush_icache_range() ineffective on kernel addresses. Split out a new __flush_icache_user_range() and __local_flush_icache_user_range() for users which actually want to flush usermode addresses (note that flush_icache_user_range() already exists on various architectures but with different arguments). The implementation of flush_icache_range() will be changed in an upcoming commit to use unprotected normal cache ops so as to always work on the kernel mode address space. Signed-off-by: James Hogan Cc: Leonid Yegoshin Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/14152/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/include/asm/cacheflush.h b/arch/mips/include/asm/cacheflush.h index 34ed22e..4812d1f 100644 --- a/arch/mips/include/asm/cacheflush.h +++ b/arch/mips/include/asm/cacheflush.h @@ -28,6 +28,7 @@ * - flush_cache_sigtramp() flush signal trampoline * - flush_icache_all() flush the entire instruction cache * - flush_data_cache_page() flushes a page from the data cache + * - __flush_icache_user_range(start, end) flushes range of user instructions */ /* @@ -80,6 +81,10 @@ static inline void flush_icache_page(struct vm_area_struct *vma, extern void (*flush_icache_range)(unsigned long start, unsigned long end); extern void (*local_flush_icache_range)(unsigned long start, unsigned long end); +extern void (*__flush_icache_user_range)(unsigned long start, + unsigned long end); +extern void (*__local_flush_icache_user_range)(unsigned long start, + unsigned long end); extern void (*__flush_cache_vmap)(void); diff --git a/arch/mips/mm/c-octeon.c b/arch/mips/mm/c-octeon.c index 05b1d7c..0e45b06 100644 --- a/arch/mips/mm/c-octeon.c +++ b/arch/mips/mm/c-octeon.c @@ -294,6 +294,8 @@ void octeon_cache_init(void) flush_data_cache_page = octeon_flush_data_cache_page; flush_icache_range = octeon_flush_icache_range; local_flush_icache_range = local_octeon_flush_icache_range; + __flush_icache_user_range = octeon_flush_icache_range; + __local_flush_icache_user_range = local_octeon_flush_icache_range; __flush_kernel_vmap_range = octeon_flush_kernel_vmap_range; diff --git a/arch/mips/mm/c-r3k.c b/arch/mips/mm/c-r3k.c index 135ec31..21e4e66 100644 --- a/arch/mips/mm/c-r3k.c +++ b/arch/mips/mm/c-r3k.c @@ -325,6 +325,8 @@ void r3k_cache_init(void) flush_cache_page = r3k_flush_cache_page; flush_icache_range = r3k_flush_icache_range; local_flush_icache_range = r3k_flush_icache_range; + __flush_icache_user_range = r3k_flush_icache_range; + __local_flush_icache_user_range = r3k_flush_icache_range; __flush_kernel_vmap_range = r3k_flush_kernel_vmap_range; diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index bbb7dfe..5e0a44a 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -1904,6 +1904,8 @@ void r4k_cache_init(void) flush_data_cache_page = r4k_flush_data_cache_page; flush_icache_range = r4k_flush_icache_range; local_flush_icache_range = local_r4k_flush_icache_range; + __flush_icache_user_range = r4k_flush_icache_range; + __local_flush_icache_user_range = local_r4k_flush_icache_range; #if defined(CONFIG_DMA_NONCOHERENT) || defined(CONFIG_DMA_MAYBE_COHERENT) if (coherentio) { diff --git a/arch/mips/mm/c-tx39.c b/arch/mips/mm/c-tx39.c index 596e184..5c28258 100644 --- a/arch/mips/mm/c-tx39.c +++ b/arch/mips/mm/c-tx39.c @@ -411,6 +411,9 @@ void tx39_cache_init(void) break; } + __flush_icache_user_range = flush_icache_range; + __local_flush_icache_user_range = local_flush_icache_range; + current_cpu_data.icache.waysize = icache_size / current_cpu_data.icache.ways; current_cpu_data.dcache.waysize = dcache_size / current_cpu_data.dcache.ways; diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c index bf04c6c..5a644c3 100644 --- a/arch/mips/mm/cache.c +++ b/arch/mips/mm/cache.c @@ -33,6 +33,10 @@ void (*flush_icache_range)(unsigned long start, unsigned long end); EXPORT_SYMBOL_GPL(flush_icache_range); void (*local_flush_icache_range)(unsigned long start, unsigned long end); EXPORT_SYMBOL_GPL(local_flush_icache_range); +void (*__flush_icache_user_range)(unsigned long start, unsigned long end); +EXPORT_SYMBOL_GPL(__flush_icache_user_range); +void (*__local_flush_icache_user_range)(unsigned long start, unsigned long end); +EXPORT_SYMBOL_GPL(__local_flush_icache_user_range); void (*__flush_cache_vmap)(void); void (*__flush_cache_vunmap)(void); -- cgit v0.10.2 From 8e3a9f4c3ab6dd0da5e8a89bd252518ff2ee5e3a Mon Sep 17 00:00:00 2001 From: James Hogan Date: Thu, 1 Sep 2016 17:30:12 +0100 Subject: MIPS: cacheflush: Use __flush_icache_user_range() The cacheflush(2) system call uses flush_icache_range() to flush a range of usermode addresses from the icache, so change it to utilise the new __flush_icache_user_range() API to allow the more generic flush_icache_range() to be changed to work on kernel addresses only. Signed-off-by: James Hogan Cc: Leonid Yegoshin Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/14153/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c index 5a644c3..7ec0847 100644 --- a/arch/mips/mm/cache.c +++ b/arch/mips/mm/cache.c @@ -78,7 +78,7 @@ SYSCALL_DEFINE3(cacheflush, unsigned long, addr, unsigned long, bytes, if (!access_ok(VERIFY_WRITE, (void __user *) addr, bytes)) return -EFAULT; - flush_icache_range(addr, addr + bytes); + __flush_icache_user_range(addr, addr + bytes); return 0; } -- cgit v0.10.2 From d99a043a9a506290a0aac6746a8e412df3dafbfb Mon Sep 17 00:00:00 2001 From: James Hogan Date: Thu, 1 Sep 2016 17:30:13 +0100 Subject: MIPS: uprobes: Flush icache via kernel address Update arch_uprobe_copy_ixol() to use the kmap_atomic() based kernel address to flush the icache with flush_icache_range(), rather than the user mapping. We have the kernel mapping available anyway and this avoids having to switch to using the new __flush_icache_user_range() for the sake of Enhanced Virtual Addressing (EVA) where flush_icache_range() will become ineffective on user addresses. Signed-off-by: James Hogan Cc: Leonid Yegoshin Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/14154/ Patchwork: https://patchwork.linux-mips.org/patch/14308/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/kernel/uprobes.c b/arch/mips/kernel/uprobes.c index 4c7c155..15ad17c 100644 --- a/arch/mips/kernel/uprobes.c +++ b/arch/mips/kernel/uprobes.c @@ -282,19 +282,14 @@ int __weak set_swbp(struct arch_uprobe *auprobe, struct mm_struct *mm, void __weak arch_uprobe_copy_ixol(struct page *page, unsigned long vaddr, void *src, unsigned long len) { - void *kaddr; + unsigned long kaddr, kstart; /* Initialize the slot */ - kaddr = kmap_atomic(page); - memcpy(kaddr + (vaddr & ~PAGE_MASK), src, len); - kunmap_atomic(kaddr); - - /* - * The MIPS version of flush_icache_range will operate safely on - * user space addresses and more importantly, it doesn't require a - * VMA argument. - */ - flush_icache_range(vaddr, vaddr + len); + kaddr = (unsigned long)kmap_atomic(page); + kstart = kaddr + (vaddr & ~PAGE_MASK); + memcpy((void *)kstart, src, len); + flush_icache_range(kstart, kstart + len); + kunmap_atomic((void *)kaddr); } /** -- cgit v0.10.2 From 24d1a6e63e8f4045551f4dce3d75724f765c5069 Mon Sep 17 00:00:00 2001 From: James Hogan Date: Thu, 1 Sep 2016 17:30:14 +0100 Subject: MIPS: KVM: Use __local_flush_icache_user_range() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Convert KVM dynamic translation of guest instructions to flush icache for guest mapped addresses using the new __local_flush_icache_user_range() API to allow the more generic flush_icache_range() to be changed to work on kernel addresses only. Signed-off-by: James Hogan Cc: Ralf Baechle Cc: Paolo Bonzini Cc: "Radim Krčmář" Cc: linux-mips@linux-mips.org Cc: kvm@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14155/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/kvm/dyntrans.c b/arch/mips/kvm/dyntrans.c index d280894..5317ed2 100644 --- a/arch/mips/kvm/dyntrans.c +++ b/arch/mips/kvm/dyntrans.c @@ -45,8 +45,8 @@ static int kvm_mips_trans_replace(struct kvm_vcpu *vcpu, u32 *opc, } else if (KVM_GUEST_KSEGX((unsigned long) opc) == KVM_GUEST_KSEG23) { local_irq_save(flags); memcpy((void *)opc, (void *)&replace, sizeof(u32)); - local_flush_icache_range((unsigned long)opc, - (unsigned long)opc + 32); + __local_flush_icache_user_range((unsigned long)opc, + (unsigned long)opc + 32); local_irq_restore(flags); } else { kvm_err("%s: Invalid address: %p\n", __func__, opc); -- cgit v0.10.2 From b2ff71718e6025fed33a693a1772e2ed39f25d6c Mon Sep 17 00:00:00 2001 From: James Hogan Date: Thu, 1 Sep 2016 17:30:15 +0100 Subject: MIPS: c-r4k: Fix flush_icache_range() for EVA flush_icache_range() flushes icache lines in a protected fashion for kernel addresses, however this isn't correct with EVA where protected cache ops only operate on user addresses, making flush_icache_range() ineffective. Split the implementations of __flush_icache_user_range() from flush_icache_range(), changing the normal flush_icache_range() to use unprotected normal cache ops. Signed-off-by: James Hogan Cc: Leonid Yegoshin Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/14156/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index 5e0a44a..c643b1e 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -722,11 +722,13 @@ struct flush_icache_range_args { unsigned long start; unsigned long end; unsigned int type; + bool user; }; static inline void __local_r4k_flush_icache_range(unsigned long start, unsigned long end, - unsigned int type) + unsigned int type, + bool user) { if (!cpu_has_ic_fills_f_dc) { if (type == R4K_INDEX || @@ -734,7 +736,10 @@ static inline void __local_r4k_flush_icache_range(unsigned long start, r4k_blast_dcache(); } else { R4600_HIT_CACHEOP_WAR_IMPL; - protected_blast_dcache_range(start, end); + if (user) + protected_blast_dcache_range(start, end); + else + blast_dcache_range(start, end); } } @@ -748,7 +753,10 @@ static inline void __local_r4k_flush_icache_range(unsigned long start, break; default: - protected_blast_icache_range(start, end); + if (user) + protected_blast_icache_range(start, end); + else + blast_icache_range(start, end); break; } } @@ -757,7 +765,13 @@ static inline void __local_r4k_flush_icache_range(unsigned long start, static inline void local_r4k_flush_icache_range(unsigned long start, unsigned long end) { - __local_r4k_flush_icache_range(start, end, R4K_HIT | R4K_INDEX); + __local_r4k_flush_icache_range(start, end, R4K_HIT | R4K_INDEX, false); +} + +static inline void local_r4k_flush_icache_user_range(unsigned long start, + unsigned long end) +{ + __local_r4k_flush_icache_range(start, end, R4K_HIT | R4K_INDEX, true); } static inline void local_r4k_flush_icache_range_ipi(void *args) @@ -766,11 +780,13 @@ static inline void local_r4k_flush_icache_range_ipi(void *args) unsigned long start = fir_args->start; unsigned long end = fir_args->end; unsigned int type = fir_args->type; + bool user = fir_args->user; - __local_r4k_flush_icache_range(start, end, type); + __local_r4k_flush_icache_range(start, end, type, user); } -static void r4k_flush_icache_range(unsigned long start, unsigned long end) +static void __r4k_flush_icache_range(unsigned long start, unsigned long end, + bool user) { struct flush_icache_range_args args; unsigned long size, cache_size; @@ -778,6 +794,7 @@ static void r4k_flush_icache_range(unsigned long start, unsigned long end) args.start = start; args.end = end; args.type = R4K_HIT | R4K_INDEX; + args.user = user; /* * Indexed cache ops require an SMP call. @@ -803,6 +820,16 @@ static void r4k_flush_icache_range(unsigned long start, unsigned long end) instruction_hazard(); } +static void r4k_flush_icache_range(unsigned long start, unsigned long end) +{ + return __r4k_flush_icache_range(start, end, false); +} + +static void r4k_flush_icache_user_range(unsigned long start, unsigned long end) +{ + return __r4k_flush_icache_range(start, end, true); +} + #if defined(CONFIG_DMA_NONCOHERENT) || defined(CONFIG_DMA_MAYBE_COHERENT) static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size) @@ -1904,8 +1931,8 @@ void r4k_cache_init(void) flush_data_cache_page = r4k_flush_data_cache_page; flush_icache_range = r4k_flush_icache_range; local_flush_icache_range = local_r4k_flush_icache_range; - __flush_icache_user_range = r4k_flush_icache_range; - __local_flush_icache_user_range = local_r4k_flush_icache_range; + __flush_icache_user_range = r4k_flush_icache_user_range; + __local_flush_icache_user_range = local_r4k_flush_icache_user_range; #if defined(CONFIG_DMA_NONCOHERENT) || defined(CONFIG_DMA_MAYBE_COHERENT) if (coherentio) { -- cgit v0.10.2 From e710d6668309d227cc7a46e9c222d97d4a502b9e Mon Sep 17 00:00:00 2001 From: Matt Redfearn Date: Tue, 20 Sep 2016 09:47:25 +0100 Subject: MIPS: tlb-r4k: If there are wired entries, don't use TLBINVF When adding a wired entry to the TLB via add_wired_entry, the tlb is flushed with local_flush_tlb_all, which on CPUs with TLBINV results in the new wired entry being flushed again. Behavior of the TLBINV instruction applies to all applicable TLB entries and is unaffected by the setting of the Wired register. Therefore if the TLB has any wired entries, fall back to iterating over the entries rather than blasting them all using TLBINVF. Signed-off-by: Matt Redfearn Cc: Bjorn Andersson Cc: Ohad Ben-Cohen Cc: Thomas Gleixner Cc: lisa.parratt@imgtec.com Cc: Hugh Dickins Cc: Huacai Chen Cc: David S. Miller Cc: James Hogan Cc: Paul Burton Cc: Andrew Morton Cc: linux-mips@linux-mips.org Cc: linux-remoteproc@vger.kernel.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14283/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c index e8b335c..4953c1a 100644 --- a/arch/mips/mm/tlb-r4k.c +++ b/arch/mips/mm/tlb-r4k.c @@ -67,8 +67,11 @@ void local_flush_tlb_all(void) entry = read_c0_wired(); - /* Blast 'em all away. */ - if (cpu_has_tlbinv) { + /* + * Blast 'em all away. + * If there are any wired entries, fall back to iterating + */ + if (cpu_has_tlbinv && !entry) { if (current_cpu_data.tlbsizevtlb) { write_c0_index(0); mtc0_tlbw_hazard(); -- cgit v0.10.2 From 7688c5391038e60377275f078e6d7043dc115efc Mon Sep 17 00:00:00 2001 From: Matt Redfearn Date: Tue, 20 Sep 2016 09:47:26 +0100 Subject: MIPS: smp.c: Introduce mechanism for freeing and allocating IPIs For the MIPS remote processor implementation, we need additional IPIs to talk to the remote processor. Since MIPS GIC reserves exactly the right number of IPI IRQs required by Linux for the number of VPs in the system, this is not possible without releasing some recources. This commit introduces mips_smp_ipi_allocate() which allocates IPIs to a given cpumask. It is called as normal with the cpu_possible_mask at bootup to initialise IPIs to all CPUs. mips_smp_ipi_free() may then be used to free IPIs to a subset of those CPUs so that their hardware resources can be reused. Signed-off-by: Matt Redfearn Cc: Bjorn Andersson Cc: Ohad Ben-Cohen Cc: Thomas Gleixner Cc: Lisa Parratt Cc: James Hogan Cc: Qais Yousef Cc: Paul Burton Cc: linux-mips@linux-mips.org Cc: linux-remoteproc@vger.kernel.org Cc: lisa.parratt@imgtec.com Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14285/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/include/asm/smp.h b/arch/mips/include/asm/smp.h index 8bc6c70..060f23f 100644 --- a/arch/mips/include/asm/smp.h +++ b/arch/mips/include/asm/smp.h @@ -85,6 +85,20 @@ static inline void __cpu_die(unsigned int cpu) extern void play_dead(void); #endif +/* + * This function will set up the necessary IPIs for Linux to communicate + * with the CPUs in mask. + * Return 0 on success. + */ +int mips_smp_ipi_allocate(const struct cpumask *mask); + +/* + * This function will free up IPIs allocated with mips_smp_ipi_allocate to the + * CPUs in mask, which must be a subset of the IPIs that have been configured. + * Return 0 on success. + */ +int mips_smp_ipi_free(const struct cpumask *mask); + static inline void arch_send_call_function_single_ipi(int cpu) { extern struct plat_smp_ops *mp_ops; /* private */ diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index cb02df2..0e131c9 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c @@ -231,7 +231,7 @@ static struct irqaction irq_call = { .name = "IPI call" }; -static __init void smp_ipi_init_one(unsigned int virq, +static void smp_ipi_init_one(unsigned int virq, struct irqaction *action) { int ret; @@ -241,9 +241,11 @@ static __init void smp_ipi_init_one(unsigned int virq, BUG_ON(ret); } -static int __init mips_smp_ipi_init(void) +static unsigned int call_virq, sched_virq; + +int mips_smp_ipi_allocate(const struct cpumask *mask) { - unsigned int call_virq, sched_virq; + int virq; struct irq_domain *ipidomain; struct device_node *node; @@ -270,16 +272,20 @@ static int __init mips_smp_ipi_init(void) if (!ipidomain) return 0; - call_virq = irq_reserve_ipi(ipidomain, cpu_possible_mask); - BUG_ON(!call_virq); + virq = irq_reserve_ipi(ipidomain, mask); + BUG_ON(!virq); + if (!call_virq) + call_virq = virq; - sched_virq = irq_reserve_ipi(ipidomain, cpu_possible_mask); - BUG_ON(!sched_virq); + virq = irq_reserve_ipi(ipidomain, mask); + BUG_ON(!virq); + if (!sched_virq) + sched_virq = virq; if (irq_domain_is_ipi_per_cpu(ipidomain)) { int cpu; - for_each_cpu(cpu, cpu_possible_mask) { + for_each_cpu(cpu, mask) { smp_ipi_init_one(call_virq + cpu, &irq_call); smp_ipi_init_one(sched_virq + cpu, &irq_resched); } @@ -288,6 +294,45 @@ static int __init mips_smp_ipi_init(void) smp_ipi_init_one(sched_virq, &irq_resched); } + return 0; +} + +int mips_smp_ipi_free(const struct cpumask *mask) +{ + struct irq_domain *ipidomain; + struct device_node *node; + + node = of_irq_find_parent(of_root); + ipidomain = irq_find_matching_host(node, DOMAIN_BUS_IPI); + + /* + * Some platforms have half DT setup. So if we found irq node but + * didn't find an ipidomain, try to search for one that is not in the + * DT. + */ + if (node && !ipidomain) + ipidomain = irq_find_matching_host(NULL, DOMAIN_BUS_IPI); + + BUG_ON(!ipidomain); + + if (irq_domain_is_ipi_per_cpu(ipidomain)) { + int cpu; + + for_each_cpu(cpu, mask) { + remove_irq(call_virq + cpu, &irq_call); + remove_irq(sched_virq + cpu, &irq_resched); + } + } + irq_destroy_ipi(call_virq, mask); + irq_destroy_ipi(sched_virq, mask); + return 0; +} + + +static int __init mips_smp_ipi_init(void) +{ + mips_smp_ipi_allocate(cpu_possible_mask); + call_desc = irq_to_desc(call_virq); sched_desc = irq_to_desc(sched_virq); -- cgit v0.10.2 From 74abd4e9b100d68a9114c845c6c5b70aa8e4e52e Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Mon, 26 Sep 2016 11:34:24 +0200 Subject: mailmap: Canonicalize to Qais' current email address. Signed-off-by: Ralf Baechle diff --git a/.mailmap b/.mailmap index 1dab0a1..d410bcd 100644 --- a/.mailmap +++ b/.mailmap @@ -125,6 +125,7 @@ Peter Oruba Peter Oruba Pratyush Anand Praveen BP +Qais Yousef Rajesh Shah Ralf Baechle Ralf Wildenhues -- cgit v0.10.2 From d9d5417755eda87db8e370e4dd2175fbd8814acc Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Sun, 21 Aug 2016 15:58:13 -0400 Subject: MIPS: kernel: Audit and remove any unnecessary uses of module.h Historically a lot of these existed because we did not have a distinction between what was modular code and what was providing support to modules via EXPORT_SYMBOL and friends. That changed when we forked out support for the latter into the export.h file. This means we should be able to reduce the usage of module.h in code that is obj-y Makefile or bool Kconfig. The advantage in doing so is that module.h itself sources about 15 other headers; adding significantly to what we feed cpp, and it can obscure what headers we are effectively using. Since module.h was the source for init.h (for __init) and for export.h (for EXPORT_SYMBOL) we consider each obj-y/bool instance for the presence of either and replace as needed. In the case of the n32/o32 files, we have to get rid of a couple no-op MODULE_ tags to facilitate the module.h removal. They piggy back off the fs/ elf binary support, which is also a bool Kconfig. Signed-off-by: Paul Gortmaker Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/14032/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/kernel/binfmt_elfn32.c b/arch/mips/kernel/binfmt_elfn32.c index 58ad63d..9c7f3e1 100644 --- a/arch/mips/kernel/binfmt_elfn32.c +++ b/arch/mips/kernel/binfmt_elfn32.c @@ -1,5 +1,6 @@ /* * Support for n32 Linux/MIPS ELF binaries. + * Author: Ralf Baechle (ralf@linux-mips.org) * * Copyright (C) 1999, 2001 Ralf Baechle * Copyright (C) 1999, 2001 Silicon Graphics, Inc. @@ -37,7 +38,6 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2) #include -#include #include #include #include @@ -96,12 +96,6 @@ jiffies_to_compat_timeval(unsigned long jiffies, struct compat_timeval *value) #define ELF_CORE_EFLAGS EF_MIPS_ABI2 -MODULE_DESCRIPTION("Binary format loader for compatibility with n32 Linux/MIPS binaries"); -MODULE_AUTHOR("Ralf Baechle (ralf@linux-mips.org)"); - -#undef MODULE_DESCRIPTION -#undef MODULE_AUTHOR - #undef TASK_SIZE #define TASK_SIZE TASK_SIZE32 diff --git a/arch/mips/kernel/binfmt_elfo32.c b/arch/mips/kernel/binfmt_elfo32.c index 49fb881..1ab3432 100644 --- a/arch/mips/kernel/binfmt_elfo32.c +++ b/arch/mips/kernel/binfmt_elfo32.c @@ -1,5 +1,6 @@ /* * Support for o32 Linux/MIPS ELF binaries. + * Author: Ralf Baechle (ralf@linux-mips.org) * * Copyright (C) 1999, 2001 Ralf Baechle * Copyright (C) 1999, 2001 Silicon Graphics, Inc. @@ -42,7 +43,6 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; #include -#include #include #include #include @@ -99,12 +99,6 @@ jiffies_to_compat_timeval(unsigned long jiffies, struct compat_timeval *value) value->tv_usec = rem / NSEC_PER_USEC; } -MODULE_DESCRIPTION("Binary format loader for compatibility with o32 Linux/MIPS binaries"); -MODULE_AUTHOR("Ralf Baechle (ralf@linux-mips.org)"); - -#undef MODULE_DESCRIPTION -#undef MODULE_AUTHOR - #undef TASK_SIZE #define TASK_SIZE TASK_SIZE32 diff --git a/arch/mips/kernel/branch.c b/arch/mips/kernel/branch.c index 46c227f..f5c6848 100644 --- a/arch/mips/kernel/branch.c +++ b/arch/mips/kernel/branch.c @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c index 0b29646..50fb625 100644 --- a/arch/mips/kernel/linux32.c +++ b/arch/mips/kernel/linux32.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/mips/kernel/mips-r2-to-r6-emul.c b/arch/mips/kernel/mips-r2-to-r6-emul.c index 0a7e10b..22dedd6 100644 --- a/arch/mips/kernel/mips-r2-to-r6-emul.c +++ b/arch/mips/kernel/mips-r2-to-r6-emul.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index 0e131c9..7ebb191 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include #include -- cgit v0.10.2 From d9ba57780637bfde6ac1efb65a8685231ffbc715 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Sun, 21 Aug 2016 15:58:14 -0400 Subject: MIPS: mm: Audit and remove any unnecessary uses of module.h Historically a lot of these existed because we did not have a distinction between what was modular code and what was providing support to modules via EXPORT_SYMBOL and friends. That changed when we forked out support for the latter into the export.h file. This means we should be able to reduce the usage of module.h in code that is obj-y Makefile or bool Kconfig. The advantage in doing so is that module.h itself sources about 15 other headers; adding significantly to what we feed cpp, and it can obscure what headers we are effectively using. Since module.h was the source for init.h (for __init) and for export.h (for EXPORT_SYMBOL) we consider each obj-y/bool instance for the presence of either and replace as needed. Signed-off-by: Paul Gortmaker Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/14033/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index c643b1e..1fc1118 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c index 7ec0847..6db3413 100644 --- a/arch/mips/mm/cache.c +++ b/arch/mips/mm/cache.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index b2eadd6..755259c 100644 --- a/arch/mips/mm/dma-default.c +++ b/arch/mips/mm/dma-default.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c index 9560ad7..d56a855 100644 --- a/arch/mips/mm/fault.c +++ b/arch/mips/mm/fault.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/mips/mm/highmem.c b/arch/mips/mm/highmem.c index d7258a1..f13f510 100644 --- a/arch/mips/mm/highmem.c +++ b/arch/mips/mm/highmem.c @@ -1,5 +1,6 @@ #include -#include +#include +#include #include #include #include diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index 72f7478..3a6edec 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c @@ -10,7 +10,7 @@ */ #include #include -#include +#include #include #include #include diff --git a/arch/mips/mm/ioremap.c b/arch/mips/mm/ioremap.c index 8d5008c..1f18962 100644 --- a/arch/mips/mm/ioremap.c +++ b/arch/mips/mm/ioremap.c @@ -6,7 +6,7 @@ * (C) Copyright 1995 1996 Linus Torvalds * (C) Copyright 2001, 2002 Ralf Baechle */ -#include +#include #include #include #include diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c index 3530376..d08ea3f 100644 --- a/arch/mips/mm/mmap.c +++ b/arch/mips/mm/mmap.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/mips/mm/page.c b/arch/mips/mm/page.c index c41953c..6f804f5 100644 --- a/arch/mips/mm/page.c +++ b/arch/mips/mm/page.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c index 4953c1a..bba9c14 100644 --- a/arch/mips/mm/tlb-r4k.c +++ b/arch/mips/mm/tlb-r4k.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include -- cgit v0.10.2 From 527581b9cf6ec560502eea91a82f511a2db77cde Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Sun, 21 Aug 2016 15:58:15 -0400 Subject: MIPS: lib: Audit and remove any unnecessary uses of module.h Historically a lot of these existed because we did not have a distinction between what was modular code and what was providing support to modules via EXPORT_SYMBOL and friends. That changed when we forked out support for the latter into the export.h file. This means we should be able to reduce the usage of module.h in code that is obj-y Makefile or bool Kconfig. The advantage in doing so is that module.h itself sources about 15 other headers; adding significantly to what we feed cpp, and it can obscure what headers we are effectively using. Since module.h was the source for init.h (for __init) and for export.h (for EXPORT_SYMBOL) we consider each obj-y/bool instance for the presence of either and replace as needed. The compiler.h additions are for an implict presence of the "notrace" which module.h brought in but export.h does not. Signed-off-by: Paul Gortmaker Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/14034/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/lib/ashldi3.c b/arch/mips/lib/ashldi3.c index 927dc94..c3e2205 100644 --- a/arch/mips/lib/ashldi3.c +++ b/arch/mips/lib/ashldi3.c @@ -1,4 +1,4 @@ -#include +#include #include "libgcc.h" diff --git a/arch/mips/lib/ashrdi3.c b/arch/mips/lib/ashrdi3.c index 9fdf1a5..1745602 100644 --- a/arch/mips/lib/ashrdi3.c +++ b/arch/mips/lib/ashrdi3.c @@ -1,4 +1,4 @@ -#include +#include #include "libgcc.h" diff --git a/arch/mips/lib/bswapdi.c b/arch/mips/lib/bswapdi.c index e3e77aa..a811414 100644 --- a/arch/mips/lib/bswapdi.c +++ b/arch/mips/lib/bswapdi.c @@ -1,4 +1,5 @@ -#include +#include +#include unsigned long long notrace __bswapdi2(unsigned long long u) { diff --git a/arch/mips/lib/bswapsi.c b/arch/mips/lib/bswapsi.c index 530a8af..106fd97 100644 --- a/arch/mips/lib/bswapsi.c +++ b/arch/mips/lib/bswapsi.c @@ -1,4 +1,5 @@ -#include +#include +#include unsigned int notrace __bswapsi2(unsigned int u) { diff --git a/arch/mips/lib/cmpdi2.c b/arch/mips/lib/cmpdi2.c index 06857da..9d849d8 100644 --- a/arch/mips/lib/cmpdi2.c +++ b/arch/mips/lib/cmpdi2.c @@ -1,4 +1,4 @@ -#include +#include #include "libgcc.h" diff --git a/arch/mips/lib/delay.c b/arch/mips/lib/delay.c index 21d27c6..2307a3c 100644 --- a/arch/mips/lib/delay.c +++ b/arch/mips/lib/delay.c @@ -8,7 +8,7 @@ * Copyright (C) 1999, 2000 Silicon Graphics, Inc. * Copyright (C) 2007, 2014 Maciej W. Rozycki */ -#include +#include #include #include #include diff --git a/arch/mips/lib/iomap-pci.c b/arch/mips/lib/iomap-pci.c index fd35daa..a629077 100644 --- a/arch/mips/lib/iomap-pci.c +++ b/arch/mips/lib/iomap-pci.c @@ -7,7 +7,7 @@ * written by Ralf Baechle */ #include -#include +#include #include void __iomem *__pci_ioport_map(struct pci_dev *dev, diff --git a/arch/mips/lib/iomap.c b/arch/mips/lib/iomap.c index 8e7e378..9daa924 100644 --- a/arch/mips/lib/iomap.c +++ b/arch/mips/lib/iomap.c @@ -6,7 +6,7 @@ * (C) Copyright 2007 MIPS Technologies, Inc. * written by Ralf Baechle */ -#include +#include #include /* diff --git a/arch/mips/lib/lshrdi3.c b/arch/mips/lib/lshrdi3.c index 3645474..221167c 100644 --- a/arch/mips/lib/lshrdi3.c +++ b/arch/mips/lib/lshrdi3.c @@ -1,4 +1,4 @@ -#include +#include #include "libgcc.h" diff --git a/arch/mips/lib/ucmpdi2.c b/arch/mips/lib/ucmpdi2.c index bd599f5..08067fa 100644 --- a/arch/mips/lib/ucmpdi2.c +++ b/arch/mips/lib/ucmpdi2.c @@ -1,4 +1,4 @@ -#include +#include #include "libgcc.h" -- cgit v0.10.2 From 2722090af4f8988ecce1b22c667fa03ee0f473ca Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Sun, 21 Aug 2016 15:58:16 -0400 Subject: MIPS: pci: Audit and remove any unnecessary uses of module.h Historically a lot of these existed because we did not have a distinction between what was modular code and what was providing support to modules via EXPORT_SYMBOL and friends. That changed when we forked out support for the latter into the export.h file. This means we should be able to reduce the usage of module.h in code that is obj-y Makefile or bool Kconfig. The advantage in doing so is that module.h itself sources about 15 other headers; adding significantly to what we feed cpp, and it can obscure what headers we are effectively using. Since module.h was the source for init.h (for __init) and for export.h (for EXPORT_SYMBOL) we consider each obj-y/bool instance for the presence of either and replace as needed. We also needed to remove the no-op MODULE_DEVICE_TABLE usage in several instances to permit removal of the module.h include. The files in these instances were all controlled by bool Kconfig. In one instance, module_param was being used so we transition the module.h include onto a moduleparam.h include. Signed-off-by: Paul Gortmaker Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/14035/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/pci/pci-ar71xx.c b/arch/mips/pci/pci-ar71xx.c index 7db963d..bdf87b4 100644 --- a/arch/mips/pci/pci-ar71xx.c +++ b/arch/mips/pci/pci-ar71xx.c @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/mips/pci/pci-ar724x.c b/arch/mips/pci/pci-ar724x.c index 2013dad..1e23c8d 100644 --- a/arch/mips/pci/pci-ar724x.c +++ b/arch/mips/pci/pci-ar724x.c @@ -11,7 +11,7 @@ #include #include -#include +#include #include #include #include diff --git a/arch/mips/pci/pci-lantiq.c b/arch/mips/pci/pci-lantiq.c index b9deab1..f18f887 100644 --- a/arch/mips/pci/pci-lantiq.c +++ b/arch/mips/pci/pci-lantiq.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -234,7 +233,6 @@ static const struct of_device_id ltq_pci_match[] = { { .compatible = "lantiq,pci-xway" }, {}, }; -MODULE_DEVICE_TABLE(of, ltq_pci_match); static struct platform_driver ltq_pci_driver = { .probe = ltq_pci_probe, diff --git a/arch/mips/pci/pci-mt7620.c b/arch/mips/pci/pci-mt7620.c index eb39826..628c513 100644 --- a/arch/mips/pci/pci-mt7620.c +++ b/arch/mips/pci/pci-mt7620.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -407,7 +406,6 @@ static const struct of_device_id mt7620_pci_ids[] = { { .compatible = "mediatek,mt7620-pci" }, {}, }; -MODULE_DEVICE_TABLE(of, mt7620_pci_ids); static struct platform_driver mt7620_pci_driver = { .probe = mt7620_pci_probe, diff --git a/arch/mips/pci/pci-rt2880.c b/arch/mips/pci/pci-rt2880.c index f2a1050..d6360fe 100644 --- a/arch/mips/pci/pci-rt2880.c +++ b/arch/mips/pci/pci-rt2880.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -260,7 +259,6 @@ static const struct of_device_id rt288x_pci_match[] = { { .compatible = "ralink,rt288x-pci" }, {}, }; -MODULE_DEVICE_TABLE(of, rt288x_pci_match); static struct platform_driver rt288x_pci_driver = { .probe = rt288x_pci_probe, diff --git a/arch/mips/pci/pci-rt3883.c b/arch/mips/pci/pci-rt3883.c index 53a42b0..3520e9b 100644 --- a/arch/mips/pci/pci-rt3883.c +++ b/arch/mips/pci/pci-rt3883.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -580,7 +579,6 @@ static const struct of_device_id rt3883_pci_ids[] = { { .compatible = "ralink,rt3883-pci" }, {}, }; -MODULE_DEVICE_TABLE(of, rt3883_pci_ids); static struct platform_driver rt3883_pci_driver = { .probe = rt3883_pci_probe, diff --git a/arch/mips/pci/pcie-octeon.c b/arch/mips/pci/pcie-octeon.c index 99f3db4..9f672ce 100644 --- a/arch/mips/pci/pcie-octeon.c +++ b/arch/mips/pci/pcie-octeon.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include -- cgit v0.10.2 From cd14c92bbd095fdc2d0b78f7dac920769ff06a9f Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Sun, 21 Aug 2016 15:58:17 -0400 Subject: MIPS: kvm: Audit and remove any unnecessary uses of module.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Historically a lot of these existed because we did not have a distinction between what was modular code and what was providing support to modules via EXPORT_SYMBOL and friends. That changed when we forked out support for the latter into the export.h file. This means we should be able to reduce the usage of module.h in code that is obj-y Makefile or bool Kconfig. In the case of kvm where it is modular, we can extend that to also include files that are building basic support functionality but not related to loading or registering the final module; such files also have no need whatsoever for module.h The advantage in removing such instances is that module.h itself sources about 15 other headers; adding significantly to what we feed cpp, and it can obscure what headers we are effectively using. Since module.h was the source for init.h (for __init) and for export.h (for EXPORT_SYMBOL) we consider each instance for the presence of either and replace as needed. In this case, we did not need to add either to any files. Signed-off-by: Paul Gortmaker Acked-by: James Hogan Acked-by: Paolo Bonzini Cc: "Radim Krčmář" Cc: kvm@vger.kernel.org Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/14036/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/kvm/commpage.c b/arch/mips/kvm/commpage.c index a36b77e..f436299 100644 --- a/arch/mips/kvm/commpage.c +++ b/arch/mips/kvm/commpage.c @@ -12,7 +12,6 @@ #include #include -#include #include #include #include diff --git a/arch/mips/kvm/dyntrans.c b/arch/mips/kvm/dyntrans.c index 5317ed2..010cef2 100644 --- a/arch/mips/kvm/dyntrans.c +++ b/arch/mips/kvm/dyntrans.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/mips/kvm/emulate.c b/arch/mips/kvm/emulate.c index e788515..68fd666 100644 --- a/arch/mips/kvm/emulate.c +++ b/arch/mips/kvm/emulate.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/mips/kvm/interrupt.c b/arch/mips/kvm/interrupt.c index ad28dac..e88403b 100644 --- a/arch/mips/kvm/interrupt.c +++ b/arch/mips/kvm/interrupt.c @@ -11,7 +11,6 @@ #include #include -#include #include #include #include diff --git a/arch/mips/kvm/trap_emul.c b/arch/mips/kvm/trap_emul.c index 0915539..21d8027 100644 --- a/arch/mips/kvm/trap_emul.c +++ b/arch/mips/kvm/trap_emul.c @@ -11,7 +11,6 @@ #include #include -#include #include #include -- cgit v0.10.2 From ba7505022c8b7c7366b905262631b293ac60c863 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Wed, 14 Sep 2016 11:00:27 +0100 Subject: MIPS: pm-cps: Generate idle state entry code when CPUs are onlined The MIPS Coherent Processing System (CPS) power management code has previously generated code used to enter low power idle states once during boot for all CPUs. This has the drawback that if a CPU is present in the system but not being used (for example due to the maxcpus kernel parameter) then we encounter problems due to not having probed that CPU for information about its type & properties. The result of this is that we generate entry code which is both unused, potentially entirely invalid & likely to be unsuitable for the CPU in question anyway. Avoid this by generating idle state entry code only when a CPU is brought online. This way we only ever generate code for CPUs that we know we've probed the properties of, and that will actually be used. [ralf@linux-mips.org: Resolve merge conflict.] Signed-off-by: Paul Burton Cc: Adam Buchbinder Cc: Masahiro Yamada Cc: Markos Chandras Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14259/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/kernel/pm-cps.c b/arch/mips/kernel/pm-cps.c index 05bcded..7cf653e 100644 --- a/arch/mips/kernel/pm-cps.c +++ b/arch/mips/kernel/pm-cps.c @@ -8,6 +8,7 @@ * option) any later version. */ +#include #include #include #include @@ -70,8 +71,8 @@ static DEFINE_PER_CPU_ALIGNED(atomic_t, pm_barrier); DEFINE_PER_CPU_ALIGNED(struct mips_static_suspend_state, cps_cpu_state); /* A somewhat arbitrary number of labels & relocs for uasm */ -static struct uasm_label labels[32] __initdata; -static struct uasm_reloc relocs[32] __initdata; +static struct uasm_label labels[32]; +static struct uasm_reloc relocs[32]; enum mips_reg { zero, at, v0, v1, a0, a1, a2, a3, @@ -193,10 +194,10 @@ int cps_pm_enter_state(enum cps_pm_state state) return 0; } -static void __init cps_gen_cache_routine(u32 **pp, struct uasm_label **pl, - struct uasm_reloc **pr, - const struct cache_desc *cache, - unsigned op, int lbl) +static void cps_gen_cache_routine(u32 **pp, struct uasm_label **pl, + struct uasm_reloc **pr, + const struct cache_desc *cache, + unsigned op, int lbl) { unsigned cache_size = cache->ways << cache->waybit; unsigned i; @@ -237,10 +238,10 @@ static void __init cps_gen_cache_routine(u32 **pp, struct uasm_label **pl, uasm_i_nop(pp); } -static int __init cps_gen_flush_fsb(u32 **pp, struct uasm_label **pl, - struct uasm_reloc **pr, - const struct cpuinfo_mips *cpu_info, - int lbl) +static int cps_gen_flush_fsb(u32 **pp, struct uasm_label **pl, + struct uasm_reloc **pr, + const struct cpuinfo_mips *cpu_info, + int lbl) { unsigned i, fsb_size = 8; unsigned num_loads = (fsb_size * 3) / 2; @@ -330,9 +331,9 @@ static int __init cps_gen_flush_fsb(u32 **pp, struct uasm_label **pl, return 0; } -static void __init cps_gen_set_top_bit(u32 **pp, struct uasm_label **pl, - struct uasm_reloc **pr, - unsigned r_addr, int lbl) +static void cps_gen_set_top_bit(u32 **pp, struct uasm_label **pl, + struct uasm_reloc **pr, + unsigned r_addr, int lbl) { uasm_i_lui(pp, t0, uasm_rel_hi(0x80000000)); uasm_build_label(pl, *pp, lbl); @@ -343,7 +344,7 @@ static void __init cps_gen_set_top_bit(u32 **pp, struct uasm_label **pl, uasm_i_nop(pp); } -static void * __init cps_gen_entry_code(unsigned cpu, enum cps_pm_state state) +static void *cps_gen_entry_code(unsigned cpu, enum cps_pm_state state) { struct uasm_label *l = labels; struct uasm_reloc *r = relocs; @@ -637,7 +638,7 @@ out_err: return NULL; } -static int __init cps_gen_core_entries(unsigned cpu) +static int cps_pm_online_cpu(unsigned int cpu) { enum cps_pm_state state; unsigned core = cpu_data[cpu].core; @@ -679,13 +680,10 @@ static int __init cps_gen_core_entries(unsigned cpu) static int __init cps_pm_init(void) { - unsigned cpu; - int err; - /* A CM is required for all non-coherent states */ if (!mips_cm_present()) { pr_warn("pm-cps: no CM, non-coherent states unavailable\n"); - goto out; + return 0; } /* @@ -715,12 +713,7 @@ static int __init cps_pm_init(void) pr_warn("pm-cps: no CPC, clock & power gating unavailable\n"); } - for_each_present_cpu(cpu) { - err = cps_gen_core_entries(cpu); - if (err) - return err; - } -out: - return 0; + return cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "AP_PM_CPS_CPU_ONLINE", + cps_pm_online_cpu, NULL); } arch_initcall(cps_pm_init); -- cgit v0.10.2 From 0a15273666aa18a45985e6419afa05ec24ecfeb4 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Fri, 26 Aug 2016 15:17:33 +0100 Subject: MIPS: SEAD3: Split obj-y entries across lines Split the obj-y entries for SEAD3 onto a line each, so that they're more independent & can be modified more clearly by later commits. Signed-off-by: Paul Burton Cc: Jacek Anaszewski Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14046/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/mti-sead3/Makefile b/arch/mips/mti-sead3/Makefile index 7a584e0..8b03cfb 100644 --- a/arch/mips/mti-sead3/Makefile +++ b/arch/mips/mti-sead3/Makefile @@ -8,8 +8,13 @@ # Copyright (C) 2012 MIPS Technoligies, Inc. All rights reserved. # Steven J. Hill # -obj-y := sead3-lcd.o sead3-display.o sead3-init.o \ - sead3-int.o sead3-platform.o sead3-reset.o \ - sead3-setup.o sead3-time.o +obj-y := sead3-lcd.o +obj-y += sead3-display.o +obj-y += sead3-init.o +obj-y += sead3-int.o +obj-y += sead3-platform.o +obj-y += sead3-reset.o +obj-y += sead3-setup.o +obj-y += sead3-time.o obj-$(CONFIG_EARLY_PRINTK) += sead3-console.o -- cgit v0.10.2 From b6d5e47e67292542a41c3fe367bacb364eb4e601 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Fri, 26 Aug 2016 15:17:34 +0100 Subject: MIPS: SEAD3: Probe interrupt controllers using DT Probe the CPU interrupt controller & optional Global Interrupt Controller (GIC) using devicetree rather than platform code. Because the bootloader on SEAD3 does not provide a device tree to the kernel & the device tree is always built in, we patch out the GIC node during boot if we detect that a GIC is not present in the system. The appropriate IRQ domain is discovered by platform code setting up device IRQ numbers temporarily. It will be removed by further patches which move the devices towards being probed via device tree. No behavioural change is intended by this patch. Signed-off-by: Paul Burton Cc: Matt Redfearn Cc: Kefeng Wang Cc: Jacek Anaszewski Cc: Rob Herring Cc: Mark Rutland Cc: linux-mips@linux-mips.org Cc: devicetree@vger.kernel.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14047/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/boot/dts/mti/sead3.dts b/arch/mips/boot/dts/mti/sead3.dts index e4b317d..051b3a9 100644 --- a/arch/mips/boot/dts/mti/sead3.dts +++ b/arch/mips/boot/dts/mti/sead3.dts @@ -4,10 +4,13 @@ /memreserve/ 0x00001000 0x000ef000; // ROM data /memreserve/ 0x000f0000 0x004cc000; // reserved +#include + / { #address-cells = <1>; #size-cells = <1>; compatible = "mti,sead-3"; + interrupt-parent = <&gic>; cpus { cpu@0 { @@ -19,4 +22,32 @@ device_type = "memory"; reg = <0x0 0x08000000>; }; + + cpu_intc: interrupt-controller { + compatible = "mti,cpu-interrupt-controller"; + + interrupt-controller; + #interrupt-cells = <1>; + }; + + gic: interrupt-controller@1b1c0000 { + compatible = "mti,gic"; + reg = <0x1b1c0000 0x20000>; + + interrupt-controller; + #interrupt-cells = <3>; + + /* + * Declare the interrupt-parent even though the mti,gic + * binding doesn't require it, such that the kernel can + * figure out that cpu_intc is the root interrupt + * controller & should be probed first. + */ + interrupt-parent = <&cpu_intc>; + + timer { + compatible = "mti,gic-timer"; + interrupts = ; + }; + }; }; diff --git a/arch/mips/include/asm/mach-sead3/sead3-dtshim.h b/arch/mips/include/asm/mach-sead3/sead3-dtshim.h new file mode 100644 index 0000000..f5d7d9c --- /dev/null +++ b/arch/mips/include/asm/mach-sead3/sead3-dtshim.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2016 Imagination Technologies + * Author: Paul Burton + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __MIPS_SEAD3_DTSHIM_H__ +#define __MIPS_SEAD3_DTSHIM_H__ + +#include + +#ifdef CONFIG_MIPS_SEAD3 + +extern void __init *sead3_dt_shim(void *fdt); + +#else /* !CONFIG_MIPS_SEAD3 */ + +static inline void *sead3_dt_shim(void *fdt) +{ + return fdt; +} + +#endif /* !CONFIG_MIPS_SEAD3 */ + +#endif /* __MIPS_SEAD3_DTSHIM_H__ */ diff --git a/arch/mips/include/asm/mips-boards/sead3int.h b/arch/mips/include/asm/mips-boards/sead3int.h index 8932c7d..bd85da3 100644 --- a/arch/mips/include/asm/mips-boards/sead3int.h +++ b/arch/mips/include/asm/mips-boards/sead3int.h @@ -12,12 +12,7 @@ #include -/* SEAD-3 GIC address space definitions. */ -#define GIC_BASE_ADDR 0x1b1c0000 -#define GIC_ADDRSPACE_SZ (128 * 1024) - /* CPU interrupt offsets */ -#define CPU_INT_GIC 2 #define CPU_INT_EHCI 2 #define CPU_INT_UART0 4 #define CPU_INT_UART1 4 diff --git a/arch/mips/mti-sead3/Makefile b/arch/mips/mti-sead3/Makefile index 8b03cfb..aad67aa 100644 --- a/arch/mips/mti-sead3/Makefile +++ b/arch/mips/mti-sead3/Makefile @@ -10,6 +10,7 @@ # obj-y := sead3-lcd.o obj-y += sead3-display.o +obj-y += sead3-dtshim.o obj-y += sead3-init.o obj-y += sead3-int.o obj-y += sead3-platform.o diff --git a/arch/mips/mti-sead3/sead3-dtshim.c b/arch/mips/mti-sead3/sead3-dtshim.c new file mode 100644 index 0000000..3283a7e --- /dev/null +++ b/arch/mips/mti-sead3/sead3-dtshim.c @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2016 Imagination Technologies + * Author: Paul Burton + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#define pr_fmt(fmt) "sead3-dtshim: " fmt + +#include +#include +#include + +#include + +#define SEAD_CONFIG CKSEG1ADDR(0x1b100110) +#define SEAD_CONFIG_GIC_PRESENT BIT(1) + +static unsigned char fdt_buf[16 << 10] __initdata; + +static int remove_gic(void *fdt) +{ + int gic_off, cpu_off, err; + uint32_t cfg, cpu_phandle; + + /* leave the GIC node intact if a GIC is present */ + cfg = __raw_readl((uint32_t *)SEAD_CONFIG); + if (cfg & SEAD_CONFIG_GIC_PRESENT) + return 0; + + gic_off = fdt_node_offset_by_compatible(fdt, -1, "mti,gic"); + if (gic_off < 0) { + pr_err("unable to find DT GIC node: %d\n", gic_off); + return gic_off; + } + + err = fdt_nop_node(fdt, gic_off); + if (err) { + pr_err("unable to nop GIC node\n"); + return err; + } + + cpu_off = fdt_node_offset_by_compatible(fdt, -1, + "mti,cpu-interrupt-controller"); + if (cpu_off < 0) { + pr_err("unable to find CPU intc node: %d\n", cpu_off); + return cpu_off; + } + + cpu_phandle = fdt_get_phandle(fdt, cpu_off); + if (!cpu_phandle) { + pr_err("unable to get CPU intc phandle\n"); + return -EINVAL; + } + + err = fdt_setprop_u32(fdt, 0, "interrupt-parent", cpu_phandle); + if (err) { + pr_err("unable to set root interrupt-parent: %d\n", err); + return err; + } + + return 0; +} + +void __init *sead3_dt_shim(void *fdt) +{ + int err; + + if (fdt_check_header(fdt)) + panic("Corrupt DT"); + + /* if this isn't SEAD3, leave the DT alone */ + if (fdt_node_check_compatible(fdt, 0, "mti,sead-3")) + return fdt; + + err = fdt_open_into(fdt, fdt_buf, sizeof(fdt_buf)); + if (err) + panic("Unable to open FDT: %d", err); + + err = remove_gic(fdt_buf); + if (err) + panic("Unable to patch FDT: %d", err); + + err = fdt_pack(fdt_buf); + if (err) + panic("Unable to pack FDT: %d\n", err); + + return fdt_buf; +} diff --git a/arch/mips/mti-sead3/sead3-int.c b/arch/mips/mti-sead3/sead3-int.c index e31e17f..2e6b732 100644 --- a/arch/mips/mti-sead3/sead3-int.c +++ b/arch/mips/mti-sead3/sead3-int.c @@ -6,37 +6,18 @@ * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. */ #include -#include +#include #include -#include -#include -#include - -#include - -#define SEAD_CONFIG_GIC_PRESENT_SHF 1 -#define SEAD_CONFIG_GIC_PRESENT_MSK (1 << SEAD_CONFIG_GIC_PRESENT_SHF) -#define SEAD_CONFIG_BASE 0x1b100110 -#define SEAD_CONFIG_SIZE 4 - -static void __iomem *sead3_config_reg; +#include +#include void __init arch_init_irq(void) { - if (!cpu_has_veic) - mips_cpu_irq_init(); + irqchip_init(); - sead3_config_reg = ioremap_nocache(SEAD_CONFIG_BASE, SEAD_CONFIG_SIZE); - gic_present = (__raw_readl(sead3_config_reg) & - SEAD_CONFIG_GIC_PRESENT_MSK) >> - SEAD_CONFIG_GIC_PRESENT_SHF; pr_info("GIC: %spresent\n", (gic_present) ? "" : "not "); pr_info("EIC: %s\n", (current_cpu_data.options & MIPS_CPU_VEIC) ? "on" : "off"); - - if (gic_present) - gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, CPU_INT_GIC, - MIPS_GIC_IRQ_BASE); } diff --git a/arch/mips/mti-sead3/sead3-platform.c b/arch/mips/mti-sead3/sead3-platform.c index 73b73ef..d6be029 100644 --- a/arch/mips/mti-sead3/sead3-platform.c +++ b/arch/mips/mti-sead3/sead3-platform.c @@ -9,8 +9,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -204,16 +206,41 @@ static struct platform_device *sead3_platform_devices[] __initdata = { static int __init sead3_platforms_device_init(void) { + const char *intc_compat; + struct device_node *node; + struct irq_domain *irqd; + + if (gic_present) + intc_compat = "mti,gic"; + else + intc_compat = "mti,cpu-interrupt-controller"; + + node = of_find_compatible_node(NULL, NULL, intc_compat); + if (!node) { + pr_err("unable to find interrupt controller DT node\n"); + return -ENODEV; + } + + irqd = irq_find_host(node); + if (!irqd) { + pr_err("unable to find interrupt controller IRQ domain\n"); + return -ENODEV; + } + if (gic_present) { - uart8250_data[0].irq = MIPS_GIC_IRQ_BASE + GIC_INT_UART0; - uart8250_data[1].irq = MIPS_GIC_IRQ_BASE + GIC_INT_UART1; - ehci_resources[1].start = MIPS_GIC_IRQ_BASE + GIC_INT_EHCI; - sead3_net_resources[1].start = MIPS_GIC_IRQ_BASE + GIC_INT_NET; + uart8250_data[0].irq = irq_create_mapping(irqd, GIC_INT_UART0); + uart8250_data[1].irq = irq_create_mapping(irqd, GIC_INT_UART1); + ehci_resources[1].start = + irq_create_mapping(irqd, GIC_INT_EHCI); + sead3_net_resources[1].start = + irq_create_mapping(irqd, GIC_INT_NET); } else { - uart8250_data[0].irq = MIPS_CPU_IRQ_BASE + CPU_INT_UART0; - uart8250_data[1].irq = MIPS_CPU_IRQ_BASE + CPU_INT_UART1; - ehci_resources[1].start = MIPS_CPU_IRQ_BASE + CPU_INT_EHCI; - sead3_net_resources[1].start = MIPS_CPU_IRQ_BASE + CPU_INT_NET; + uart8250_data[0].irq = irq_create_mapping(irqd, CPU_INT_UART0); + uart8250_data[1].irq = irq_create_mapping(irqd, CPU_INT_UART1); + ehci_resources[1].start = + irq_create_mapping(irqd, CPU_INT_EHCI); + sead3_net_resources[1].start = + irq_create_mapping(irqd, CPU_INT_NET); } return platform_add_devices(sead3_platform_devices, diff --git a/arch/mips/mti-sead3/sead3-setup.c b/arch/mips/mti-sead3/sead3-setup.c index edfcaf0..c4fc0c6 100644 --- a/arch/mips/mti-sead3/sead3-setup.c +++ b/arch/mips/mti-sead3/sead3-setup.c @@ -13,6 +13,7 @@ #include #include +#include #include const char *get_system_type(void) @@ -89,20 +90,16 @@ void __init *plat_get_fdt(void) void __init plat_mem_setup(void) { + void *fdt = plat_get_fdt(); + /* allow command line/bootloader env to override memory size in DT */ parse_memsize_param(); - /* - * Load the builtin devicetree. This causes the chosen node to be - * parsed resulting in our memory appearing - */ - __dt_setup_arch(__dtb_start); + fdt = sead3_dt_shim(fdt); + __dt_setup_arch(fdt); } void __init device_tree_init(void) { - if (!initial_boot_params) - return; - unflatten_and_copy_device_tree(); } -- cgit v0.10.2 From c11e3b48dbc367e38dfaea6e8a61d3b39f476685 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Fri, 26 Aug 2016 15:17:35 +0100 Subject: MIPS: SEAD3: Probe UARTs using DT Probe the UARTs on SEAD3 boards using device tree rather than platform code, in order to reduce the amount of the latter. This requires that CONFIG_SERIAL_OF_PLATFORM be enabled, so enable it in sead3_defconfig. The SEAD3 DT shim code is extended to read bootloader environment variables to determine the appropriate UART & mode for kernel console output & set the stdout-path property of the chosen node accordingly. In contrast to the old platform code, which appears to have only ever set "console=ttyS0,38400n8r" with the code in console_config never having an effect, this will honor the "yamontty" environment variable to select between the 2 UARTs on the board and then check the "modetty0" or "modetty1" variable as appropriate to determine the UART configuration. Signed-off-by: Paul Burton Cc: Rob Herring Cc: Mark Rutland Cc: linux-mips@linux-mips.org Cc: devicetree@vger.kernel.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14048/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/boot/dts/mti/sead3.dts b/arch/mips/boot/dts/mti/sead3.dts index 051b3a9..3f681c5 100644 --- a/arch/mips/boot/dts/mti/sead3.dts +++ b/arch/mips/boot/dts/mti/sead3.dts @@ -12,6 +12,15 @@ compatible = "mti,sead-3"; interrupt-parent = <&gic>; + chosen { + stdout-path = "uart1:115200"; + }; + + aliases { + uart0 = &uart0; + uart1 = &uart1; + }; + cpus { cpu@0 { compatible = "mti,mips14KEc", "mti,mips14Kc"; @@ -50,4 +59,32 @@ interrupts = ; }; }; + + /* UART connected to FTDI & miniUSB socket */ + uart0: uart@1f000900 { + compatible = "ns16550a"; + reg = <0x1f000900 0x20>; + reg-io-width = <4>; + reg-shift = <2>; + + clock-frequency = <14745600>; + + interrupts = <3>; /* GIC 3 or CPU 4 */ + + no-loopback-test; + }; + + /* UART connected to RS232 socket */ + uart1: uart@1f000800 { + compatible = "ns16550a"; + reg = <0x1f000800 0x20>; + reg-io-width = <4>; + reg-shift = <2>; + + clock-frequency = <14745600>; + + interrupts = <2>; /* GIC 2 or CPU 4 */ + + no-loopback-test; + }; }; diff --git a/arch/mips/configs/sead3_defconfig b/arch/mips/configs/sead3_defconfig index dae9354..deb48fb 100644 --- a/arch/mips/configs/sead3_defconfig +++ b/arch/mips/configs/sead3_defconfig @@ -39,6 +39,7 @@ CONFIG_MTD_CFI_INTELEXT=y CONFIG_MTD_PHYSMAP=y CONFIG_MTD_UBI=y CONFIG_MTD_UBI_GLUEBI=y +CONFIG_OF=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_CRYPTOLOOP=m CONFIG_SCSI=y @@ -70,6 +71,7 @@ CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_NR_UARTS=2 CONFIG_SERIAL_8250_RUNTIME_UARTS=2 +CONFIG_SERIAL_OF_PLATFORM=y # CONFIG_HW_RANDOM is not set CONFIG_I2C=y # CONFIG_I2C_COMPAT is not set diff --git a/arch/mips/include/asm/mips-boards/sead3int.h b/arch/mips/include/asm/mips-boards/sead3int.h index bd85da3..3a5e079 100644 --- a/arch/mips/include/asm/mips-boards/sead3int.h +++ b/arch/mips/include/asm/mips-boards/sead3int.h @@ -14,14 +14,10 @@ /* CPU interrupt offsets */ #define CPU_INT_EHCI 2 -#define CPU_INT_UART0 4 -#define CPU_INT_UART1 4 #define CPU_INT_NET 6 /* GIC interrupt offsets */ #define GIC_INT_NET GIC_SHARED_TO_HWIRQ(0) -#define GIC_INT_UART1 GIC_SHARED_TO_HWIRQ(2) -#define GIC_INT_UART0 GIC_SHARED_TO_HWIRQ(3) #define GIC_INT_EHCI GIC_SHARED_TO_HWIRQ(5) #endif /* !(_MIPS_SEAD3INT_H) */ diff --git a/arch/mips/mti-sead3/sead3-dtshim.c b/arch/mips/mti-sead3/sead3-dtshim.c index 3283a7e..b462f65 100644 --- a/arch/mips/mti-sead3/sead3-dtshim.c +++ b/arch/mips/mti-sead3/sead3-dtshim.c @@ -14,6 +14,7 @@ #include #include +#include #include #define SEAD_CONFIG CKSEG1ADDR(0x1b100110) @@ -23,7 +24,8 @@ static unsigned char fdt_buf[16 << 10] __initdata; static int remove_gic(void *fdt) { - int gic_off, cpu_off, err; + const unsigned int cpu_uart_int = 4; + int gic_off, cpu_off, uart_off, err; uint32_t cfg, cpu_phandle; /* leave the GIC node intact if a GIC is present */ @@ -62,6 +64,103 @@ static int remove_gic(void *fdt) return err; } + uart_off = fdt_node_offset_by_compatible(fdt, -1, "ns16550a"); + while (uart_off >= 0) { + err = fdt_setprop_u32(fdt, uart_off, "interrupts", + cpu_uart_int); + if (err) { + pr_err("unable to set UART interrupts property: %d\n", + err); + return err; + } + + uart_off = fdt_node_offset_by_compatible(fdt, uart_off, + "ns16550a"); + } + if (uart_off != -FDT_ERR_NOTFOUND) { + pr_err("error searching for UART DT node: %d\n", uart_off); + return uart_off; + } + + return 0; +} + +static int serial_config(void *fdt) +{ + const char *yamontty, *mode_var; + char mode_var_name[9], path[18], parity; + unsigned int uart, baud, stop_bits; + bool hw_flow; + int chosen_off, err; + + yamontty = fw_getenv("yamontty"); + if (!yamontty || !strcmp(yamontty, "tty0")) { + uart = 0; + } else if (!strcmp(yamontty, "tty1")) { + uart = 1; + } else { + pr_warn("yamontty environment variable '%s' invalid\n", + yamontty); + uart = 0; + } + + baud = stop_bits = 0; + parity = 0; + hw_flow = false; + + snprintf(mode_var_name, sizeof(mode_var_name), "modetty%u", uart); + mode_var = fw_getenv(mode_var_name); + if (mode_var) { + while (mode_var[0] >= '0' && mode_var[0] <= '9') { + baud *= 10; + baud += mode_var[0] - '0'; + mode_var++; + } + if (mode_var[0] == ',') + mode_var++; + if (mode_var[0]) + parity = mode_var[0]; + if (mode_var[0] == ',') + mode_var++; + if (mode_var[0]) + stop_bits = mode_var[0] - '0'; + if (mode_var[0] == ',') + mode_var++; + if (!strcmp(mode_var, "hw")) + hw_flow = true; + } + + if (!baud) + baud = 38400; + + if (parity != 'e' && parity != 'n' && parity != 'o') + parity = 'n'; + + if (stop_bits != 7 && stop_bits != 8) + stop_bits = 8; + + WARN_ON(snprintf(path, sizeof(path), "uart%u:%u%c%u%s", + uart, baud, parity, stop_bits, + hw_flow ? "r" : "") >= sizeof(path)); + + /* find or add chosen node */ + chosen_off = fdt_path_offset(fdt, "/chosen"); + if (chosen_off == -FDT_ERR_NOTFOUND) + chosen_off = fdt_path_offset(fdt, "/chosen@0"); + if (chosen_off == -FDT_ERR_NOTFOUND) + chosen_off = fdt_add_subnode(fdt, 0, "chosen"); + if (chosen_off < 0) { + pr_err("Unable to find or add DT chosen node: %d\n", + chosen_off); + return chosen_off; + } + + err = fdt_setprop_string(fdt, chosen_off, "stdout-path", path); + if (err) { + pr_err("Unable to set stdout-path property: %d\n", err); + return err; + } + return 0; } @@ -84,6 +183,10 @@ void __init *sead3_dt_shim(void *fdt) if (err) panic("Unable to patch FDT: %d", err); + err = serial_config(fdt_buf); + if (err) + panic("Unable to patch FDT: %d", err); + err = fdt_pack(fdt_buf); if (err) panic("Unable to pack FDT: %d\n", err); diff --git a/arch/mips/mti-sead3/sead3-init.c b/arch/mips/mti-sead3/sead3-init.c index 3572ea3..e81f5b7 100644 --- a/arch/mips/mti-sead3/sead3-init.c +++ b/arch/mips/mti-sead3/sead3-init.c @@ -17,47 +17,6 @@ extern char except_vec_nmi; extern char except_vec_ejtag_debug; -#ifdef CONFIG_SERIAL_8250_CONSOLE -static void __init console_config(void) -{ - char console_string[40]; - int baud = 0; - char parity = '\0', bits = '\0', flow = '\0'; - char *s; - - if ((strstr(fw_getcmdline(), "console=")) == NULL) { - s = fw_getenv("modetty0"); - if (s) { - while (*s >= '0' && *s <= '9') - baud = baud*10 + *s++ - '0'; - if (*s == ',') - s++; - if (*s) - parity = *s++; - if (*s == ',') - s++; - if (*s) - bits = *s++; - if (*s == ',') - s++; - if (*s == 'h') - flow = 'r'; - } - if (baud == 0) - baud = 38400; - if (parity != 'n' && parity != 'o' && parity != 'e') - parity = 'n'; - if (bits != '7' && bits != '8') - bits = '8'; - if (flow == '\0') - flow = 'r'; - sprintf(console_string, " console=ttyS0,%d%c%c%c", baud, - parity, bits, flow); - strcat(fw_getcmdline(), console_string); - } -} -#endif - static void __init mips_nmi_setup(void) { void *base; @@ -140,11 +99,6 @@ void __init prom_init(void) else if ((strstr(fw_getcmdline(), "console=ttyS1")) != NULL) fw_init_early_console(1); #endif -#ifdef CONFIG_SERIAL_8250_CONSOLE - if ((strstr(fw_getcmdline(), "console=")) == NULL) - strcat(fw_getcmdline(), " console=ttyS0,38400n8r"); - console_config(); -#endif } void __init prom_free_prom_memory(void) diff --git a/arch/mips/mti-sead3/sead3-platform.c b/arch/mips/mti-sead3/sead3-platform.c index d6be029..538a6f8 100644 --- a/arch/mips/mti-sead3/sead3-platform.c +++ b/arch/mips/mti-sead3/sead3-platform.c @@ -14,35 +14,10 @@ #include #include #include -#include #include #include -#define UART(base) \ -{ \ - .mapbase = base, \ - .irq = -1, \ - .uartclk = 14745600, \ - .iotype = UPIO_MEM32, \ - .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP, \ - .regshift = 2, \ -} - -static struct plat_serial8250_port uart8250_data[] = { - UART(0x1f000900), /* ttyS0 = USB */ - UART(0x1f000800), /* ttyS1 = RS232 */ - { }, -}; - -static struct platform_device uart8250_device = { - .name = "serial8250", - .id = PLAT8250_DEV_PLATFORM2, - .dev = { - .platform_data = uart8250_data, - }, -}; - static struct smsc911x_platform_config sead3_smsc911x_data = { .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL, @@ -195,7 +170,6 @@ static struct platform_device ehci_device = { }; static struct platform_device *sead3_platform_devices[] __initdata = { - &uart8250_device, &sead3_flash, &pled_device, &fled_device, @@ -228,15 +202,11 @@ static int __init sead3_platforms_device_init(void) } if (gic_present) { - uart8250_data[0].irq = irq_create_mapping(irqd, GIC_INT_UART0); - uart8250_data[1].irq = irq_create_mapping(irqd, GIC_INT_UART1); ehci_resources[1].start = irq_create_mapping(irqd, GIC_INT_EHCI); sead3_net_resources[1].start = irq_create_mapping(irqd, GIC_INT_NET); } else { - uart8250_data[0].irq = irq_create_mapping(irqd, CPU_INT_UART0); - uart8250_data[1].irq = irq_create_mapping(irqd, CPU_INT_UART1); ehci_resources[1].start = irq_create_mapping(irqd, CPU_INT_EHCI); sead3_net_resources[1].start = -- cgit v0.10.2 From 53f37d1d306927d21e0256fe6c48fa517d889cf7 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Fri, 26 Aug 2016 15:17:36 +0100 Subject: MIPS: SEAD3: Use generic ns16550a earlycon support Stop selecting SYS_HAS_EARLY_PRINTK & remove the custom support for early output to the ns16550a UARTs, instead relying upon generic ns16550a earlycon support. This reduces the amount of platform code required for SEAD3 without losing any functionality. Signed-off-by: Paul Burton Cc: Jacek Anaszewski Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14049/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 6fba0ef..7ec9ed7 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -514,7 +514,6 @@ config MIPS_SEAD3 select SYS_HAS_CPU_MIPS32_R2 select SYS_HAS_CPU_MIPS32_R6 select SYS_HAS_CPU_MIPS64_R1 - select SYS_HAS_EARLY_PRINTK select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_64BIT_KERNEL select SYS_SUPPORTS_BIG_ENDIAN diff --git a/arch/mips/configs/sead3_defconfig b/arch/mips/configs/sead3_defconfig index deb48fb..23cce81 100644 --- a/arch/mips/configs/sead3_defconfig +++ b/arch/mips/configs/sead3_defconfig @@ -15,6 +15,8 @@ CONFIG_PROFILING=y CONFIG_OPROFILE=y CONFIG_MODULES=y # CONFIG_BLK_DEV_BSG is not set +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="earlycon" # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_NET=y CONFIG_PACKET=y diff --git a/arch/mips/mti-sead3/Makefile b/arch/mips/mti-sead3/Makefile index aad67aa..a58b6d9 100644 --- a/arch/mips/mti-sead3/Makefile +++ b/arch/mips/mti-sead3/Makefile @@ -17,5 +17,3 @@ obj-y += sead3-platform.o obj-y += sead3-reset.o obj-y += sead3-setup.o obj-y += sead3-time.o - -obj-$(CONFIG_EARLY_PRINTK) += sead3-console.o diff --git a/arch/mips/mti-sead3/sead3-console.c b/arch/mips/mti-sead3/sead3-console.c deleted file mode 100644 index 031f47d..0000000 --- a/arch/mips/mti-sead3/sead3-console.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. - */ -#include -#include -#include -#include - -#define SEAD_UART1_REGS_BASE 0xbf000800 /* ttyS1 = DB9 port */ -#define SEAD_UART0_REGS_BASE 0xbf000900 /* ttyS0 = USB port */ -#define PORT(base_addr, offset) ((unsigned int __iomem *)(base_addr+(offset)*4)) - -static char console_port = 1; - -static inline unsigned int serial_in(int offset, unsigned int base_addr) -{ - return __raw_readl(PORT(base_addr, offset)) & 0xff; -} - -static inline void serial_out(int offset, int value, unsigned int base_addr) -{ - __raw_writel(value, PORT(base_addr, offset)); -} - -void __init fw_init_early_console(char port) -{ - console_port = port; -} - -int prom_putchar(char c) -{ - unsigned int base_addr; - - base_addr = console_port ? SEAD_UART1_REGS_BASE : SEAD_UART0_REGS_BASE; - - while ((serial_in(UART_LSR, base_addr) & UART_LSR_THRE) == 0) - ; - - serial_out(UART_TX, c, base_addr); - - return 1; -} diff --git a/arch/mips/mti-sead3/sead3-init.c b/arch/mips/mti-sead3/sead3-init.c index e81f5b7..50f3fcb 100644 --- a/arch/mips/mti-sead3/sead3-init.c +++ b/arch/mips/mti-sead3/sead3-init.c @@ -93,12 +93,6 @@ void __init prom_init(void) board_ejtag_handler_setup = mips_ejtag_setup; fw_init_cmdline(); -#ifdef CONFIG_EARLY_PRINTK - if ((strstr(fw_getcmdline(), "console=ttyS0")) != NULL) - fw_init_early_console(0); - else if ((strstr(fw_getcmdline(), "console=ttyS1")) != NULL) - fw_init_early_console(1); -#endif } void __init prom_free_prom_memory(void) -- cgit v0.10.2 From a34e93882de4e50e349d2d23b20dde5257d42f94 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Fri, 26 Aug 2016 15:17:37 +0100 Subject: MIPS: SEAD3: Probe ethernet controller using DT Probe the smsc911x ethernet controller using device tree rather than platform code, reducing the amount of the latter. Signed-off-by: Paul Burton Cc: Rob Herring Cc: Mark Rutland Cc: linux-mips@linux-mips.org Cc: devicetree@vger.kernel.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14050/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/boot/dts/mti/sead3.dts b/arch/mips/boot/dts/mti/sead3.dts index 3f681c5..29ed194 100644 --- a/arch/mips/boot/dts/mti/sead3.dts +++ b/arch/mips/boot/dts/mti/sead3.dts @@ -87,4 +87,16 @@ no-loopback-test; }; + + eth@1f010000 { + compatible = "smsc,lan9115"; + reg = <0x1f010000 0x10000>; + reg-io-width = <4>; + + interrupts = <0>; /* GIC 0 or CPU 6 */ + + phy-mode = "mii"; + smsc,irq-push-pull; + smsc,save-mac-address; + }; }; diff --git a/arch/mips/include/asm/mips-boards/sead3int.h b/arch/mips/include/asm/mips-boards/sead3int.h index 3a5e079..7fdb9d4 100644 --- a/arch/mips/include/asm/mips-boards/sead3int.h +++ b/arch/mips/include/asm/mips-boards/sead3int.h @@ -14,10 +14,8 @@ /* CPU interrupt offsets */ #define CPU_INT_EHCI 2 -#define CPU_INT_NET 6 /* GIC interrupt offsets */ -#define GIC_INT_NET GIC_SHARED_TO_HWIRQ(0) #define GIC_INT_EHCI GIC_SHARED_TO_HWIRQ(5) #endif /* !(_MIPS_SEAD3INT_H) */ diff --git a/arch/mips/mti-sead3/sead3-dtshim.c b/arch/mips/mti-sead3/sead3-dtshim.c index b462f65..279d8d4 100644 --- a/arch/mips/mti-sead3/sead3-dtshim.c +++ b/arch/mips/mti-sead3/sead3-dtshim.c @@ -25,7 +25,8 @@ static unsigned char fdt_buf[16 << 10] __initdata; static int remove_gic(void *fdt) { const unsigned int cpu_uart_int = 4; - int gic_off, cpu_off, uart_off, err; + const unsigned int cpu_eth_int = 6; + int gic_off, cpu_off, uart_off, eth_off, err; uint32_t cfg, cpu_phandle; /* leave the GIC node intact if a GIC is present */ @@ -82,6 +83,18 @@ static int remove_gic(void *fdt) return uart_off; } + eth_off = fdt_node_offset_by_compatible(fdt, -1, "smsc,lan9115"); + if (eth_off < 0) { + pr_err("unable to find ethernet DT node: %d\n", eth_off); + return eth_off; + } + + err = fdt_setprop_u32(fdt, eth_off, "interrupts", cpu_eth_int); + if (err) { + pr_err("unable to set ethernet interrupts property: %d\n", err); + return err; + } + return 0; } diff --git a/arch/mips/mti-sead3/sead3-platform.c b/arch/mips/mti-sead3/sead3-platform.c index 538a6f8..9f9e914 100644 --- a/arch/mips/mti-sead3/sead3-platform.c +++ b/arch/mips/mti-sead3/sead3-platform.c @@ -14,37 +14,9 @@ #include #include #include -#include #include -static struct smsc911x_platform_config sead3_smsc911x_data = { - .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, - .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL, - .flags = SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS, - .phy_interface = PHY_INTERFACE_MODE_MII, -}; - -static struct resource sead3_net_resources[] = { - { - .start = 0x1f010000, - .end = 0x1f01ffff, - .flags = IORESOURCE_MEM - }, { - .flags = IORESOURCE_IRQ - } -}; - -static struct platform_device sead3_net_device = { - .name = "smsc911x", - .id = 0, - .dev = { - .platform_data = &sead3_smsc911x_data, - }, - .num_resources = ARRAY_SIZE(sead3_net_resources), - .resource = sead3_net_resources -}; - static struct mtd_partition sead3_mtd_partitions[] = { { .name = "User FS", @@ -175,7 +147,6 @@ static struct platform_device *sead3_platform_devices[] __initdata = { &fled_device, &sead3_led_device, &ehci_device, - &sead3_net_device, }; static int __init sead3_platforms_device_init(void) @@ -204,13 +175,9 @@ static int __init sead3_platforms_device_init(void) if (gic_present) { ehci_resources[1].start = irq_create_mapping(irqd, GIC_INT_EHCI); - sead3_net_resources[1].start = - irq_create_mapping(irqd, GIC_INT_NET); } else { ehci_resources[1].start = irq_create_mapping(irqd, CPU_INT_EHCI); - sead3_net_resources[1].start = - irq_create_mapping(irqd, CPU_INT_NET); } return platform_add_devices(sead3_platform_devices, -- cgit v0.10.2 From 7afd2a5aec2ea27ba87b3a423c5d782fe0f2b96b Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Fri, 26 Aug 2016 15:17:38 +0100 Subject: MIPS: SEAD3: Probe EHCI controller using DT Probe the SEAD3 EHCI controller using the generic-ehci driver & device tree rather than platform code, in order to reduce the amount of the latter. Now that no devices probed from platform code require interrupts, remove the retrieval of the IRQ domain & sead3int.h. Signed-off-by: Paul Burton Cc: Rob Herring Cc: Mark Rutland Cc: linux-mips@linux-mips.org Cc: devicetree@vger.kernel.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14051/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/boot/dts/mti/sead3.dts b/arch/mips/boot/dts/mti/sead3.dts index 29ed194..49f57c2 100644 --- a/arch/mips/boot/dts/mti/sead3.dts +++ b/arch/mips/boot/dts/mti/sead3.dts @@ -60,6 +60,15 @@ }; }; + ehci@1b200000 { + compatible = "generic-ehci"; + reg = <0x1b200000 0x1000>; + + interrupts = <0>; /* GIC 0 or CPU 6 */ + + has-transaction-translator; + }; + /* UART connected to FTDI & miniUSB socket */ uart0: uart@1f000900 { compatible = "ns16550a"; diff --git a/arch/mips/include/asm/mips-boards/sead3int.h b/arch/mips/include/asm/mips-boards/sead3int.h deleted file mode 100644 index 7fdb9d4..0000000 --- a/arch/mips/include/asm/mips-boards/sead3int.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2000,2012 MIPS Technologies, Inc. All rights reserved. - * Douglas Leung - * Steven J. Hill - */ -#ifndef _MIPS_SEAD3INT_H -#define _MIPS_SEAD3INT_H - -#include - -/* CPU interrupt offsets */ -#define CPU_INT_EHCI 2 - -/* GIC interrupt offsets */ -#define GIC_INT_EHCI GIC_SHARED_TO_HWIRQ(5) - -#endif /* !(_MIPS_SEAD3INT_H) */ diff --git a/arch/mips/mti-sead3/sead3-dtshim.c b/arch/mips/mti-sead3/sead3-dtshim.c index 279d8d4..6e32ceb 100644 --- a/arch/mips/mti-sead3/sead3-dtshim.c +++ b/arch/mips/mti-sead3/sead3-dtshim.c @@ -24,9 +24,10 @@ static unsigned char fdt_buf[16 << 10] __initdata; static int remove_gic(void *fdt) { + const unsigned int cpu_ehci_int = 2; const unsigned int cpu_uart_int = 4; const unsigned int cpu_eth_int = 6; - int gic_off, cpu_off, uart_off, eth_off, err; + int gic_off, cpu_off, uart_off, eth_off, ehci_off, err; uint32_t cfg, cpu_phandle; /* leave the GIC node intact if a GIC is present */ @@ -95,6 +96,18 @@ static int remove_gic(void *fdt) return err; } + ehci_off = fdt_node_offset_by_compatible(fdt, -1, "mti,sead3-ehci"); + if (ehci_off < 0) { + pr_err("unable to find EHCI DT node: %d\n", ehci_off); + return ehci_off; + } + + err = fdt_setprop_u32(fdt, ehci_off, "interrupts", cpu_ehci_int); + if (err) { + pr_err("unable to set EHCI interrupts property: %d\n", err); + return err; + } + return 0; } diff --git a/arch/mips/mti-sead3/sead3-platform.c b/arch/mips/mti-sead3/sead3-platform.c index 9f9e914..21047b5 100644 --- a/arch/mips/mti-sead3/sead3-platform.c +++ b/arch/mips/mti-sead3/sead3-platform.c @@ -7,16 +7,10 @@ */ #include #include -#include -#include -#include #include #include -#include #include -#include - static struct mtd_partition sead3_mtd_partitions[] = { { .name = "User FS", @@ -118,68 +112,15 @@ static struct platform_device sead3_led_device = { .id = -1, }; -static struct resource ehci_resources[] = { - { - .start = 0x1b200000, - .end = 0x1b200fff, - .flags = IORESOURCE_MEM - }, { - .flags = IORESOURCE_IRQ - } -}; - -static u64 sead3_usbdev_dma_mask = DMA_BIT_MASK(32); - -static struct platform_device ehci_device = { - .name = "sead3-ehci", - .id = 0, - .dev = { - .dma_mask = &sead3_usbdev_dma_mask, - .coherent_dma_mask = DMA_BIT_MASK(32) - }, - .num_resources = ARRAY_SIZE(ehci_resources), - .resource = ehci_resources -}; - static struct platform_device *sead3_platform_devices[] __initdata = { &sead3_flash, &pled_device, &fled_device, &sead3_led_device, - &ehci_device, }; static int __init sead3_platforms_device_init(void) { - const char *intc_compat; - struct device_node *node; - struct irq_domain *irqd; - - if (gic_present) - intc_compat = "mti,gic"; - else - intc_compat = "mti,cpu-interrupt-controller"; - - node = of_find_compatible_node(NULL, NULL, intc_compat); - if (!node) { - pr_err("unable to find interrupt controller DT node\n"); - return -ENODEV; - } - - irqd = irq_find_host(node); - if (!irqd) { - pr_err("unable to find interrupt controller IRQ domain\n"); - return -ENODEV; - } - - if (gic_present) { - ehci_resources[1].start = - irq_create_mapping(irqd, GIC_INT_EHCI); - } else { - ehci_resources[1].start = - irq_create_mapping(irqd, CPU_INT_EHCI); - } - return platform_add_devices(sead3_platform_devices, ARRAY_SIZE(sead3_platform_devices)); } -- cgit v0.10.2 From 63c8d90ca967c7e87006dbd363a8724ba31f1b57 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Fri, 26 Aug 2016 15:17:39 +0100 Subject: USB: host: ehci-sead3: Remove SEAD-3 EHCI code The SEAD-3 board is now probing its EHCI controller using the generic EHCI driver & its generic-ehci device tree binding. Remove the unused SEAD-3 specific EHCI code. Signed-off-by: Paul Burton Acked-by: Alan Stern Cc: Greg Kroah-Hartman Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Cc: linux-usb@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14052/ Signed-off-by: Ralf Baechle diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 1e5f529..0630648 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1308,11 +1308,6 @@ MODULE_LICENSE ("GPL"); #define PLATFORM_DRIVER ehci_mv_driver #endif -#ifdef CONFIG_MIPS_SEAD3 -#include "ehci-sead3.c" -#define PLATFORM_DRIVER ehci_hcd_sead3_driver -#endif - static int __init ehci_hcd_init(void) { int retval = 0; diff --git a/drivers/usb/host/ehci-sead3.c b/drivers/usb/host/ehci-sead3.c deleted file mode 100644 index 3d86cc2..0000000 --- a/drivers/usb/host/ehci-sead3.c +++ /dev/null @@ -1,185 +0,0 @@ -/* - * MIPS CI13320A EHCI Host Controller driver - * Based on "ehci-au1xxx.c" by K.Boge - * - * Copyright (C) 2012 MIPS Technologies, Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include - -static int ehci_sead3_setup(struct usb_hcd *hcd) -{ - int ret; - struct ehci_hcd *ehci = hcd_to_ehci(hcd); - - ehci->caps = hcd->regs + 0x100; - -#ifdef __BIG_ENDIAN - ehci->big_endian_mmio = 1; - ehci->big_endian_desc = 1; -#endif - - ret = ehci_setup(hcd); - if (ret) - return ret; - - ehci->need_io_watchdog = 0; - - /* Set burst length to 16 words. */ - ehci_writel(ehci, 0x1010, &ehci->regs->reserved1[1]); - - return ret; -} - -const struct hc_driver ehci_sead3_hc_driver = { - .description = hcd_name, - .product_desc = "SEAD-3 EHCI", - .hcd_priv_size = sizeof(struct ehci_hcd), - - /* - * generic hardware linkage - */ - .irq = ehci_irq, - .flags = HCD_MEMORY | HCD_USB2 | HCD_BH, - - /* - * basic lifecycle operations - * - */ - .reset = ehci_sead3_setup, - .start = ehci_run, - .stop = ehci_stop, - .shutdown = ehci_shutdown, - - /* - * managing i/o requests and associated device resources - */ - .urb_enqueue = ehci_urb_enqueue, - .urb_dequeue = ehci_urb_dequeue, - .endpoint_disable = ehci_endpoint_disable, - .endpoint_reset = ehci_endpoint_reset, - - /* - * scheduling support - */ - .get_frame_number = ehci_get_frame, - - /* - * root hub support - */ - .hub_status_data = ehci_hub_status_data, - .hub_control = ehci_hub_control, - .bus_suspend = ehci_bus_suspend, - .bus_resume = ehci_bus_resume, - .relinquish_port = ehci_relinquish_port, - .port_handed_over = ehci_port_handed_over, - - .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, -}; - -static int ehci_hcd_sead3_drv_probe(struct platform_device *pdev) -{ - struct usb_hcd *hcd; - struct resource *res; - int ret; - - if (usb_disabled()) - return -ENODEV; - - if (pdev->resource[1].flags != IORESOURCE_IRQ) { - pr_debug("resource[1] is not IORESOURCE_IRQ"); - return -ENOMEM; - } - hcd = usb_create_hcd(&ehci_sead3_hc_driver, &pdev->dev, "SEAD-3"); - if (!hcd) - return -ENOMEM; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - hcd->regs = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(hcd->regs)) { - ret = PTR_ERR(hcd->regs); - goto err1; - } - hcd->rsrc_start = res->start; - hcd->rsrc_len = resource_size(res); - - /* Root hub has integrated TT. */ - hcd->has_tt = 1; - - ret = usb_add_hcd(hcd, pdev->resource[1].start, - IRQF_SHARED); - if (ret == 0) { - platform_set_drvdata(pdev, hcd); - device_wakeup_enable(hcd->self.controller); - return ret; - } - -err1: - usb_put_hcd(hcd); - return ret; -} - -static int ehci_hcd_sead3_drv_remove(struct platform_device *pdev) -{ - struct usb_hcd *hcd = platform_get_drvdata(pdev); - - usb_remove_hcd(hcd); - usb_put_hcd(hcd); - - return 0; -} - -#ifdef CONFIG_PM -static int ehci_hcd_sead3_drv_suspend(struct device *dev) -{ - struct usb_hcd *hcd = dev_get_drvdata(dev); - bool do_wakeup = device_may_wakeup(dev); - - return ehci_suspend(hcd, do_wakeup); -} - -static int ehci_hcd_sead3_drv_resume(struct device *dev) -{ - struct usb_hcd *hcd = dev_get_drvdata(dev); - - ehci_resume(hcd, false); - return 0; -} - -static const struct dev_pm_ops sead3_ehci_pmops = { - .suspend = ehci_hcd_sead3_drv_suspend, - .resume = ehci_hcd_sead3_drv_resume, -}; - -#define SEAD3_EHCI_PMOPS (&sead3_ehci_pmops) - -#else -#define SEAD3_EHCI_PMOPS NULL -#endif - -static struct platform_driver ehci_hcd_sead3_driver = { - .probe = ehci_hcd_sead3_drv_probe, - .remove = ehci_hcd_sead3_drv_remove, - .shutdown = usb_hcd_platform_shutdown, - .driver = { - .name = "sead3-ehci", - .pm = SEAD3_EHCI_PMOPS, - } -}; - -MODULE_ALIAS("platform:sead3-ehci"); -- cgit v0.10.2 From 3aefc6554ad95f64de5ab384a959f96eb188f273 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Fri, 26 Aug 2016 15:17:40 +0100 Subject: MIPS: SEAD3: Probe parallel flash via DT Probe the system parallel flash using device tree rather than platform code, in order to reduce the amount of the latter. Signed-off-by: Paul Burton Cc: Rob Herring Cc: Mark Rutland Cc: linux-mips@linux-mips.org Cc: devicetree@vger.kernel.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14053/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/boot/dts/mti/sead3.dts b/arch/mips/boot/dts/mti/sead3.dts index 49f57c2..8844cc0 100644 --- a/arch/mips/boot/dts/mti/sead3.dts +++ b/arch/mips/boot/dts/mti/sead3.dts @@ -69,6 +69,30 @@ has-transaction-translator; }; + flash@1c000000 { + compatible = "intel,28f128j3", "cfi-flash"; + reg = <0x1c000000 0x2000000>; + #address-cells = <1>; + #size-cells = <1>; + bank-width = <4>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + user-fs@0 { + label = "User FS"; + reg = <0x0 0x1fc0000>; + }; + + board-config@3e0000 { + label = "Board Config"; + reg = <0x1fc0000 0x40000>; + }; + }; + }; + /* UART connected to FTDI & miniUSB socket */ uart0: uart@1f000900 { compatible = "ns16550a"; diff --git a/arch/mips/mti-sead3/sead3-platform.c b/arch/mips/mti-sead3/sead3-platform.c index 21047b5..5c1f42a 100644 --- a/arch/mips/mti-sead3/sead3-platform.c +++ b/arch/mips/mti-sead3/sead3-platform.c @@ -8,44 +8,8 @@ #include #include #include -#include #include -static struct mtd_partition sead3_mtd_partitions[] = { - { - .name = "User FS", - .offset = 0x00000000, - .size = 0x01fc0000, - }, { - .name = "Board Config", - .offset = 0x01fc0000, - .size = 0x00040000, - .mask_flags = MTD_WRITEABLE - }, -}; - -static struct physmap_flash_data sead3_flash_data = { - .width = 4, - .nr_parts = ARRAY_SIZE(sead3_mtd_partitions), - .parts = sead3_mtd_partitions -}; - -static struct resource sead3_flash_resource = { - .start = 0x1c000000, - .end = 0x1dffffff, - .flags = IORESOURCE_MEM -}; - -static struct platform_device sead3_flash = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &sead3_flash_data, - }, - .num_resources = 1, - .resource = &sead3_flash_resource, -}; - #define LEDFLAGS(bits, shift) \ ((bits << 8) | (shift << 8)) @@ -113,7 +77,6 @@ static struct platform_device sead3_led_device = { }; static struct platform_device *sead3_platform_devices[] __initdata = { - &sead3_flash, &pled_device, &fled_device, &sead3_led_device, -- cgit v0.10.2 From c764583f40b8d3cde3a3a0b4a40a7d2fa3987bed Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Fri, 26 Aug 2016 15:17:41 +0100 Subject: MIPS: SEAD3: Use register-bit-led driver via DT for LEDs Probe a driver for the PLED & FLED LEDs found on the SEAD3 board using the register-bit-led driver via device tree, rather than a custom driver via platform code. Enable support for the register-bit-led driver & its prerequisite syscon in sead3_defconfig. Signed-off-by: Paul Burton Cc: Jacek Anaszewski Cc: Rob Herring Cc: Mark Rutland Cc: linux-mips@linux-mips.org Cc: devicetree@vger.kernel.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14054/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/boot/dts/mti/sead3.dts b/arch/mips/boot/dts/mti/sead3.dts index 8844cc0..0159450 100644 --- a/arch/mips/boot/dts/mti/sead3.dts +++ b/arch/mips/boot/dts/mti/sead3.dts @@ -93,6 +93,109 @@ }; }; + system-controller@1f000200 { + compatible = "mti,sead3-cpld", "syscon", "simple-mfd"; + reg = <0x1f000200 0x300>; + + led@10.0 { + compatible = "register-bit-led"; + offset = <0x10>; + mask = <0x1>; + label = "pled0"; + }; + led@10.1 { + compatible = "register-bit-led"; + offset = <0x10>; + mask = <0x2>; + label = "pled1"; + }; + led@10.2 { + compatible = "register-bit-led"; + offset = <0x10>; + mask = <0x4>; + label = "pled2"; + }; + led@10.3 { + compatible = "register-bit-led"; + offset = <0x10>; + mask = <0x8>; + label = "pled3"; + }; + led@10.4 { + compatible = "register-bit-led"; + offset = <0x10>; + mask = <0x10>; + label = "pled4"; + }; + led@10.5 { + compatible = "register-bit-led"; + offset = <0x10>; + mask = <0x20>; + label = "pled5"; + }; + led@10.6 { + compatible = "register-bit-led"; + offset = <0x10>; + mask = <0x40>; + label = "pled6"; + }; + led@10.7 { + compatible = "register-bit-led"; + offset = <0x10>; + mask = <0x80>; + label = "pled7"; + }; + + led@18.0 { + compatible = "register-bit-led"; + offset = <0x18>; + mask = <0x1>; + label = "fled0"; + }; + led@18.1 { + compatible = "register-bit-led"; + offset = <0x18>; + mask = <0x2>; + label = "fled1"; + }; + led@18.2 { + compatible = "register-bit-led"; + offset = <0x18>; + mask = <0x4>; + label = "fled2"; + }; + led@18.3 { + compatible = "register-bit-led"; + offset = <0x18>; + mask = <0x8>; + label = "fled3"; + }; + led@18.4 { + compatible = "register-bit-led"; + offset = <0x18>; + mask = <0x10>; + label = "fled4"; + }; + led@18.5 { + compatible = "register-bit-led"; + offset = <0x18>; + mask = <0x20>; + label = "fled5"; + }; + led@18.6 { + compatible = "register-bit-led"; + offset = <0x18>; + mask = <0x40>; + label = "fled6"; + }; + led@18.7 { + compatible = "register-bit-led"; + offset = <0x18>; + mask = <0x80>; + label = "fled7"; + }; + }; + /* UART connected to FTDI & miniUSB socket */ uart0: uart@1f000900 { compatible = "ns16550a"; diff --git a/arch/mips/configs/sead3_defconfig b/arch/mips/configs/sead3_defconfig index 23cce81..e1c6582 100644 --- a/arch/mips/configs/sead3_defconfig +++ b/arch/mips/configs/sead3_defconfig @@ -81,6 +81,7 @@ CONFIG_I2C_CHARDEV=y # CONFIG_I2C_HELPER_AUTO is not set CONFIG_SPI=y CONFIG_SENSORS_ADT7475=y +CONFIG_MFD_SYSCON=y CONFIG_BACKLIGHT_LCD_SUPPORT=y CONFIG_LCD_CLASS_DEVICE=y CONFIG_BACKLIGHT_CLASS_DEVICE=y @@ -95,6 +96,7 @@ CONFIG_MMC_DEBUG=y CONFIG_MMC_SPI=y CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y +CONFIG_LEDS_SYSCON=y CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_HEARTBEAT=y CONFIG_RTC_CLASS=y diff --git a/arch/mips/mti-sead3/Makefile b/arch/mips/mti-sead3/Makefile index a58b6d9..04ea002 100644 --- a/arch/mips/mti-sead3/Makefile +++ b/arch/mips/mti-sead3/Makefile @@ -13,7 +13,6 @@ obj-y += sead3-display.o obj-y += sead3-dtshim.o obj-y += sead3-init.o obj-y += sead3-int.o -obj-y += sead3-platform.o obj-y += sead3-reset.o obj-y += sead3-setup.o obj-y += sead3-time.o diff --git a/arch/mips/mti-sead3/sead3-platform.c b/arch/mips/mti-sead3/sead3-platform.c deleted file mode 100644 index 5c1f42a..0000000 --- a/arch/mips/mti-sead3/sead3-platform.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. - */ -#include -#include -#include -#include - -#define LEDFLAGS(bits, shift) \ - ((bits << 8) | (shift << 8)) - -#define LEDBITS(id, shift, bits) \ - .name = id #shift, \ - .flags = LEDFLAGS(bits, shift) - -static struct led_info led_data_info[] = { - { LEDBITS("bit", 0, 1) }, - { LEDBITS("bit", 1, 1) }, - { LEDBITS("bit", 2, 1) }, - { LEDBITS("bit", 3, 1) }, - { LEDBITS("bit", 4, 1) }, - { LEDBITS("bit", 5, 1) }, - { LEDBITS("bit", 6, 1) }, - { LEDBITS("bit", 7, 1) }, - { LEDBITS("all", 0, 8) }, -}; - -static struct led_platform_data led_data = { - .num_leds = ARRAY_SIZE(led_data_info), - .leds = led_data_info -}; - -static struct resource pled_resources[] = { - { - .start = 0x1f000210, - .end = 0x1f000217, - .flags = IORESOURCE_MEM - } -}; - -static struct platform_device pled_device = { - .name = "sead3::pled", - .id = 0, - .dev = { - .platform_data = &led_data, - }, - .num_resources = ARRAY_SIZE(pled_resources), - .resource = pled_resources -}; - - -static struct resource fled_resources[] = { - { - .start = 0x1f000218, - .end = 0x1f00021f, - .flags = IORESOURCE_MEM - } -}; - -static struct platform_device fled_device = { - .name = "sead3::fled", - .id = 0, - .dev = { - .platform_data = &led_data, - }, - .num_resources = ARRAY_SIZE(fled_resources), - .resource = fled_resources -}; - -static struct platform_device sead3_led_device = { - .name = "sead3-led", - .id = -1, -}; - -static struct platform_device *sead3_platform_devices[] __initdata = { - &pled_device, - &fled_device, - &sead3_led_device, -}; - -static int __init sead3_platforms_device_init(void) -{ - return platform_add_devices(sead3_platform_devices, - ARRAY_SIZE(sead3_platform_devices)); -} - -device_initcall(sead3_platforms_device_init); -- cgit v0.10.2 From 70bfdcec9ad9bcd3217f85fd422012777d86e168 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Fri, 26 Aug 2016 15:17:43 +0100 Subject: MIPS: SEAD3: Reset via generic syscon-reboot driver & DT Remove the SEAD3 implementation of _machine_restart & instead make use of the generic syscon-reboot driver probed via device tree. Signed-off-by: Paul Burton Cc: Rob Herring Cc: Mark Rutland Cc: linux-mips@linux-mips.org Cc: devicetree@vger.kernel.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14056/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/boot/dts/mti/sead3.dts b/arch/mips/boot/dts/mti/sead3.dts index 0159450..047ff7a 100644 --- a/arch/mips/boot/dts/mti/sead3.dts +++ b/arch/mips/boot/dts/mti/sead3.dts @@ -93,6 +93,18 @@ }; }; + fpga_regs: system-controller@1f000000 { + compatible = "mti,sead3-fpga", "syscon", "simple-mfd"; + reg = <0x1f000000 0x200>; + + reboot { + compatible = "syscon-reboot"; + regmap = <&fpga_regs>; + offset = <0x50>; + mask = <0x4d>; + }; + }; + system-controller@1f000200 { compatible = "mti,sead3-cpld", "syscon", "simple-mfd"; reg = <0x1f000200 0x300>; diff --git a/arch/mips/configs/sead3_defconfig b/arch/mips/configs/sead3_defconfig index e1c6582..055af30 100644 --- a/arch/mips/configs/sead3_defconfig +++ b/arch/mips/configs/sead3_defconfig @@ -80,8 +80,9 @@ CONFIG_I2C=y CONFIG_I2C_CHARDEV=y # CONFIG_I2C_HELPER_AUTO is not set CONFIG_SPI=y +CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_SYSCON=y CONFIG_SENSORS_ADT7475=y -CONFIG_MFD_SYSCON=y CONFIG_BACKLIGHT_LCD_SUPPORT=y CONFIG_LCD_CLASS_DEVICE=y CONFIG_BACKLIGHT_CLASS_DEVICE=y diff --git a/arch/mips/mti-sead3/sead3-reset.c b/arch/mips/mti-sead3/sead3-reset.c index e6fb244..8f548f0 100644 --- a/arch/mips/mti-sead3/sead3-reset.c +++ b/arch/mips/mti-sead3/sead3-reset.c @@ -13,14 +13,6 @@ #define SOFTRES_REG 0x1f000050 #define GORESET 0x4d -static void mips_machine_restart(char *command) -{ - unsigned int __iomem *softres_reg = - ioremap(SOFTRES_REG, sizeof(unsigned int)); - - __raw_writel(GORESET, softres_reg); -} - static void mips_machine_halt(void) { unsigned int __iomem *softres_reg = @@ -31,7 +23,6 @@ static void mips_machine_halt(void) static int __init mips_reboot_setup(void) { - _machine_restart = mips_machine_restart; _machine_halt = mips_machine_halt; pm_power_off = mips_machine_halt; -- cgit v0.10.2 From a1ec6003f21547199f57ab529d0eff742917d637 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Fri, 26 Aug 2016 15:17:44 +0100 Subject: MIPS: SEAD3: Use generic restart-poweroff driver Remove the custom platform code to restart when instructed to power off, instead relying upon the generic restart-poweroff driver probed via DT to do the same thing. Remove also the halt implementation, which is incorrect. The generic MIPS version will hang the system as halt should. Signed-off-by: Paul Burton Cc: Jacek Anaszewski Cc: Rob Herring Cc: Mark Rutland Cc: linux-mips@linux-mips.org Cc: devicetree@vger.kernel.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14057/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/boot/dts/mti/sead3.dts b/arch/mips/boot/dts/mti/sead3.dts index 047ff7a..32a5ab9 100644 --- a/arch/mips/boot/dts/mti/sead3.dts +++ b/arch/mips/boot/dts/mti/sead3.dts @@ -103,6 +103,10 @@ offset = <0x50>; mask = <0x4d>; }; + + poweroff { + compatible = "restart-poweroff"; + }; }; system-controller@1f000200 { diff --git a/arch/mips/configs/sead3_defconfig b/arch/mips/configs/sead3_defconfig index 055af30..ab4c465 100644 --- a/arch/mips/configs/sead3_defconfig +++ b/arch/mips/configs/sead3_defconfig @@ -81,6 +81,7 @@ CONFIG_I2C_CHARDEV=y # CONFIG_I2C_HELPER_AUTO is not set CONFIG_SPI=y CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_RESTART=y CONFIG_POWER_RESET_SYSCON=y CONFIG_SENSORS_ADT7475=y CONFIG_BACKLIGHT_LCD_SUPPORT=y diff --git a/arch/mips/mti-sead3/Makefile b/arch/mips/mti-sead3/Makefile index 04ea002..ad722c8 100644 --- a/arch/mips/mti-sead3/Makefile +++ b/arch/mips/mti-sead3/Makefile @@ -13,6 +13,5 @@ obj-y += sead3-display.o obj-y += sead3-dtshim.o obj-y += sead3-init.o obj-y += sead3-int.o -obj-y += sead3-reset.o obj-y += sead3-setup.o obj-y += sead3-time.o diff --git a/arch/mips/mti-sead3/sead3-reset.c b/arch/mips/mti-sead3/sead3-reset.c deleted file mode 100644 index 8f548f0..0000000 --- a/arch/mips/mti-sead3/sead3-reset.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. - */ -#include -#include - -#include - -#define SOFTRES_REG 0x1f000050 -#define GORESET 0x4d - -static void mips_machine_halt(void) -{ - unsigned int __iomem *softres_reg = - ioremap(SOFTRES_REG, sizeof(unsigned int)); - - __raw_writel(GORESET, softres_reg); -} - -static int __init mips_reboot_setup(void) -{ - _machine_halt = mips_machine_halt; - pm_power_off = mips_machine_halt; - - return 0; -} -arch_initcall(mips_reboot_setup); -- cgit v0.10.2 From fd4d740427080f67c52e16d4fa639b30ccf1ccde Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Fri, 26 Aug 2016 15:17:45 +0100 Subject: MIPS: SEAD3: Parse memsize in DT shim Parse the memsize argument provided by the bootloader in the DT shim code, allowing the user to override it on the command line. This places all of the DT manipulation code into sead3-dtshim.c. Signed-off-by: Paul Burton Cc: Matt Redfearn Cc: Rob Herring Cc: Kefeng Wang Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14058/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/mti-sead3/sead3-dtshim.c b/arch/mips/mti-sead3/sead3-dtshim.c index 6e32ceb..d6b0708 100644 --- a/arch/mips/mti-sead3/sead3-dtshim.c +++ b/arch/mips/mti-sead3/sead3-dtshim.c @@ -22,6 +22,73 @@ static unsigned char fdt_buf[16 << 10] __initdata; +static int append_memory(void *fdt) +{ + unsigned long phys_memsize, memsize; + __be32 mem_array[2]; + int err, mem_off; + char *var; + + /* find memory size from the bootloader environment */ + var = fw_getenv("memsize"); + if (var) { + err = kstrtoul(var, 0, &phys_memsize); + if (err) { + pr_err("Failed to read memsize env variable '%s'\n", + var); + return -EINVAL; + } + } else { + pr_warn("The bootloader didn't provide memsize: defaulting to 32MB\n"); + phys_memsize = 32 << 20; + } + + /* default to using all available RAM */ + memsize = phys_memsize; + + /* allow the user to override the usable memory */ + var = strstr(arcs_cmdline, "memsize="); + if (var) + memsize = memparse(var + strlen("memsize="), NULL); + + /* if the user says there's more RAM than we thought, believe them */ + phys_memsize = max_t(unsigned long, phys_memsize, memsize); + + /* find or add a memory node */ + mem_off = fdt_path_offset(fdt, "/memory"); + if (mem_off == -FDT_ERR_NOTFOUND) + mem_off = fdt_add_subnode(fdt, 0, "memory"); + if (mem_off < 0) { + pr_err("Unable to find or add memory DT node: %d\n", mem_off); + return mem_off; + } + + err = fdt_setprop_string(fdt, mem_off, "device_type", "memory"); + if (err) { + pr_err("Unable to set memory node device_type: %d\n", err); + return err; + } + + mem_array[0] = 0; + mem_array[1] = cpu_to_be32(phys_memsize); + err = fdt_setprop(fdt, mem_off, "reg", mem_array, sizeof(mem_array)); + if (err) { + pr_err("Unable to set memory regs property: %d\n", err); + return err; + } + + mem_array[0] = 0; + mem_array[1] = cpu_to_be32(memsize); + err = fdt_setprop(fdt, mem_off, "linux,usable-memory", + mem_array, sizeof(mem_array)); + if (err) { + pr_err("Unable to set linux,usable-memory property: %d\n", err); + return err; + } + + return 0; +} + static int remove_gic(void *fdt) { const unsigned int cpu_ehci_int = 2; @@ -205,6 +272,10 @@ void __init *sead3_dt_shim(void *fdt) if (err) panic("Unable to open FDT: %d", err); + err = append_memory(fdt_buf); + if (err) + panic("Unable to patch FDT: %d", err); + err = remove_gic(fdt_buf); if (err) panic("Unable to patch FDT: %d", err); diff --git a/arch/mips/mti-sead3/sead3-setup.c b/arch/mips/mti-sead3/sead3-setup.c index c4fc0c6..c915e54 100644 --- a/arch/mips/mti-sead3/sead3-setup.c +++ b/arch/mips/mti-sead3/sead3-setup.c @@ -11,7 +11,6 @@ #include #include -#include #include #include @@ -21,68 +20,6 @@ const char *get_system_type(void) return "MIPS SEAD3"; } -static uint32_t get_memsize_from_cmdline(void) -{ - int memsize = 0; - char *p = arcs_cmdline; - char *s = "memsize="; - - p = strstr(p, s); - if (p) { - p += strlen(s); - memsize = memparse(p, NULL); - } - - return memsize; -} - -static uint32_t get_memsize_from_env(void) -{ - int memsize = 0; - char *p; - - p = fw_getenv("memsize"); - if (p) - memsize = memparse(p, NULL); - - return memsize; -} - -static uint32_t get_memsize(void) -{ - uint32_t memsize; - - memsize = get_memsize_from_cmdline(); - if (memsize) - return memsize; - - return get_memsize_from_env(); -} - -static void __init parse_memsize_param(void) -{ - int offset; - const uint64_t *prop_value; - int prop_len; - uint32_t memsize = get_memsize(); - - if (!memsize) - return; - - offset = fdt_path_offset(__dtb_start, "/memory"); - if (offset > 0) { - uint64_t new_value; - /* - * reg contains 2 32-bits BE values, offset and size. We just - * want to replace the size value without affecting the offset - */ - prop_value = fdt_getprop(__dtb_start, offset, "reg", &prop_len); - new_value = be64_to_cpu(*prop_value); - new_value = (new_value & ~0xffffffffllu) | memsize; - fdt_setprop_inplace_u64(__dtb_start, offset, "reg", new_value); - } -} - void __init *plat_get_fdt(void) { return (void *)__dtb_start; @@ -92,9 +29,6 @@ void __init plat_mem_setup(void) { void *fdt = plat_get_fdt(); - /* allow command line/bootloader env to override memory size in DT */ - parse_memsize_param(); - fdt = sead3_dt_shim(fdt); __dt_setup_arch(fdt); } -- cgit v0.10.2 From ec5218a23c470aad28be13362d11fd7886445866 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Fri, 26 Aug 2016 15:17:46 +0100 Subject: MIPS: SEAD3: Drop use of cobalt fbdev driver The 2 line * 16 character LCD display on the SEAD3 board has no real use as a framebuffer device. It's far too small to produce any meaningful output if used as the kernel console, SEAD3 is a development board that will essentially always have a far more useful UART connection & the code in sead3-display.c will overwrite whatever's on the display every second anyway. Remove this unused code. Signed-off-by: Paul Burton Cc: Jacek Anaszewski Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14059/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/mti-sead3/Makefile b/arch/mips/mti-sead3/Makefile index ad722c8..cb6d620 100644 --- a/arch/mips/mti-sead3/Makefile +++ b/arch/mips/mti-sead3/Makefile @@ -8,8 +8,7 @@ # Copyright (C) 2012 MIPS Technoligies, Inc. All rights reserved. # Steven J. Hill # -obj-y := sead3-lcd.o -obj-y += sead3-display.o +obj-y := sead3-display.o obj-y += sead3-dtshim.o obj-y += sead3-init.o obj-y += sead3-int.o diff --git a/arch/mips/mti-sead3/sead3-lcd.c b/arch/mips/mti-sead3/sead3-lcd.c deleted file mode 100644 index 10b10ed2..0000000 --- a/arch/mips/mti-sead3/sead3-lcd.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. - */ -#include -#include - -static struct resource __initdata sead3_lcd_resource = { - .start = 0x1f000400, - .end = 0x1f00041f, - .flags = IORESOURCE_MEM, -}; - -static __init int sead3_lcd_add(void) -{ - struct platform_device *pdev; - int retval; - - /* SEAD-3 and Cobalt platforms use same display type. */ - pdev = platform_device_alloc("cobalt-lcd", -1); - if (!pdev) - return -ENOMEM; - - retval = platform_device_add_resources(pdev, &sead3_lcd_resource, 1); - if (retval) - goto err_free_device; - - retval = platform_device_add(pdev); - if (retval) - goto err_free_device; - - return 0; - -err_free_device: - platform_device_put(pdev); - - return retval; -} - -device_initcall(sead3_lcd_add); -- cgit v0.10.2 From eb42d760db2ea8ab16f10e320a7a8bfff331307f Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Fri, 26 Aug 2016 15:17:47 +0100 Subject: FBDEV: cobalt_lcdfb: Drop SEAD3 support The SEAD3 board no longer uses the cobalt_lcdfb driver, so remove the SEAD3-specific code from it. Signed-off-by: Paul Burton Acked-by: Tomi Valkeinen Cc: Ondrej Zary Cc: Arnd Bergmann Cc: Robert Jarzmik Cc: Maciej W. Rozycki Cc: Ezequiel Garcia Cc: Tomi Valkeinen Cc: Jean-Christophe Plagniol-Villard Cc: Geert Uytterhoeven Cc: Simon Horman Cc: linux-mips@linux-mips.org Cc: linux-fbdev@vger.kernel.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14060/ Signed-off-by: Ralf Baechle diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 88b008f..914bfb2 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -2183,7 +2183,7 @@ config FB_GOLDFISH config FB_COBALT tristate "Cobalt server LCD frame buffer support" - depends on FB && (MIPS_COBALT || MIPS_SEAD3) + depends on FB && MIPS_COBALT config FB_SH7760 bool "SH7760/SH7763/SH7720/SH7721 LCDC support" diff --git a/drivers/video/fbdev/cobalt_lcdfb.c b/drivers/video/fbdev/cobalt_lcdfb.c index 07675d6..2d3b691 100644 --- a/drivers/video/fbdev/cobalt_lcdfb.c +++ b/drivers/video/fbdev/cobalt_lcdfb.c @@ -63,7 +63,6 @@ #define LCD_CUR_POS(x) ((x) & LCD_CUR_POS_MASK) #define LCD_TEXT_POS(x) ((x) | LCD_TEXT_MODE) -#ifdef CONFIG_MIPS_COBALT static inline void lcd_write_control(struct fb_info *info, u8 control) { writel((u32)control << 24, info->screen_base); @@ -83,47 +82,6 @@ static inline u8 lcd_read_data(struct fb_info *info) { return readl(info->screen_base + LCD_DATA_REG_OFFSET) >> 24; } -#else - -#define LCD_CTL 0x00 -#define LCD_DATA 0x08 -#define CPLD_STATUS 0x10 -#define CPLD_DATA 0x18 - -static inline void cpld_wait(struct fb_info *info) -{ - do { - } while (readl(info->screen_base + CPLD_STATUS) & 1); -} - -static inline void lcd_write_control(struct fb_info *info, u8 control) -{ - cpld_wait(info); - writel(control, info->screen_base + LCD_CTL); -} - -static inline u8 lcd_read_control(struct fb_info *info) -{ - cpld_wait(info); - readl(info->screen_base + LCD_CTL); - cpld_wait(info); - return readl(info->screen_base + CPLD_DATA) & 0xff; -} - -static inline void lcd_write_data(struct fb_info *info, u8 data) -{ - cpld_wait(info); - writel(data, info->screen_base + LCD_DATA); -} - -static inline u8 lcd_read_data(struct fb_info *info) -{ - cpld_wait(info); - readl(info->screen_base + LCD_DATA); - cpld_wait(info); - return readl(info->screen_base + CPLD_DATA) & 0xff; -} -#endif static int lcd_busy_wait(struct fb_info *info) { -- cgit v0.10.2 From 8ef3ff2723f8cbaec4fee3c7fa807bf8d6ccd2e5 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Fri, 26 Aug 2016 15:17:48 +0100 Subject: dt-bindings: img-ascii-lcd: Document a binding for simple ASCII LCDs Add documentation for a devicetree binding for the simple ASCII LCD displays found on development boards such as the MIPS Boston, MIPS Malta & MIPS SEAD3 from Imagination Technologies. Signed-off-by: Paul Burton Acked-by: Rob Herring Cc: Mauro Carvalho Chehab Cc: Guenter Roeck Cc: David S. Miller Cc: Greg Kroah-Hartman Cc: Geert Uytterhoeven Cc: Mark Rutland Cc: Andrew Morton Cc: linux-mips@linux-mips.org Cc: devicetree@vger.kernel.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14061/ Signed-off-by: Ralf Baechle diff --git a/Documentation/devicetree/bindings/auxdisplay/img-ascii-lcd.txt b/Documentation/devicetree/bindings/auxdisplay/img-ascii-lcd.txt new file mode 100644 index 0000000..b69bb68 --- /dev/null +++ b/Documentation/devicetree/bindings/auxdisplay/img-ascii-lcd.txt @@ -0,0 +1,17 @@ +Binding for ASCII LCD displays on Imagination Technologies boards + +Required properties: +- compatible : should be one of: + "img,boston-lcd" + "mti,malta-lcd" + "mti,sead3-lcd" + +Required properties for "img,boston-lcd": +- reg : memory region locating the device registers + +Required properties for "mti,malta-lcd" or "mti,sead3-lcd": +- regmap: phandle of the system controller containing the LCD registers +- offset: offset in bytes to the LCD registers within the system controller + +The layout of the registers & properties of the display are determined +from the compatible string, making this binding somewhat trivial. diff --git a/MAINTAINERS b/MAINTAINERS index f593300..7b24f9f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5964,6 +5964,11 @@ M: Stanislaw Gruszka S: Maintained F: drivers/usb/atm/ueagle-atm.c +IMGTEC ASCII LCD DRIVER +M: Paul Burton +S: Maintained +F: Documentation/devicetree/bindings/auxdisplay/img-ascii-lcd.txt + INA209 HARDWARE MONITOR DRIVER M: Guenter Roeck L: linux-hwmon@vger.kernel.org -- cgit v0.10.2 From 0cad855fbd083ee5fd0584a47c2aaa7dca936fd4 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Fri, 26 Aug 2016 15:17:49 +0100 Subject: auxdisplay: img-ascii-lcd: driver for simple ASCII LCD displays Add a driver for simple ASCII LCD displays found on the MIPS Boston, Malta & SEAD3 development boards. The Boston display is an independent memory mapped device with a simple memory mapped 8 byte register space containing the 8 ASCII characters to display. The Malta display is exposed as part of the Malta board registers, and provides 8 registers each of which corresponds to one of the ASCII characters to display. The SEAD3 display is slightly more complex, exposing an interface to an S6A0069 LCD controller via registers provided by the boards CPLD. However although the displays differ in their register interface, we require similar functionality on each board so abstracting away the differences within a single driver allows us to share a significant amount of code & ensure consistent behaviour. The driver displays the Linux kernel version as the default message, but allows the message to be changed via a character device. Messages longer then the number of characters that the display can show will scroll. This provides different behaviour to the existing LCD display code for the MIPS Malta or MIPS SEAD3 platforms in the following ways: - The default string to display is not "LINUX ON MALTA" or "LINUX ON SEAD3" but "Linux" followed by the version number of the kernel (UTS_RELEASE). - Since that string tends to be significantly longer it scrolls twice as fast, moving every 500ms rather than every 1s. - The LCD won't be updated until the driver is probed, so it doesn't provide the early "LINUX" string. Signed-off-by: Paul Burton Cc: Mauro Carvalho Chehab Cc: Miguel Ojeda Sandonis Cc: Guenter Roeck Cc: David S. Miller Cc: Greg Kroah-Hartman Cc: Geert Uytterhoeven Cc: Andrew Morton Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14062/ Signed-off-by: Ralf Baechle diff --git a/MAINTAINERS b/MAINTAINERS index 7b24f9f..1f17900 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5968,6 +5968,7 @@ IMGTEC ASCII LCD DRIVER M: Paul Burton S: Maintained F: Documentation/devicetree/bindings/auxdisplay/img-ascii-lcd.txt +F: drivers/auxdisplay/img-ascii-lcd.c INA209 HARDWARE MONITOR DRIVER M: Guenter Roeck diff --git a/drivers/auxdisplay/Kconfig b/drivers/auxdisplay/Kconfig index c07e725..10e1b9e 100644 --- a/drivers/auxdisplay/Kconfig +++ b/drivers/auxdisplay/Kconfig @@ -119,4 +119,13 @@ config CFAG12864B_RATE If you compile this as a module, you can still override this value using the module parameters. +config IMG_ASCII_LCD + tristate "Imagination Technologies ASCII LCD Display" + default y if MIPS_MALTA || MIPS_SEAD3 + select SYSCON + help + Enable this to support the simple ASCII LCD displays found on + development boards such as the MIPS Boston, MIPS Malta & MIPS SEAD3 + from Imagination Technologies. + endif # AUXDISPLAY diff --git a/drivers/auxdisplay/Makefile b/drivers/auxdisplay/Makefile index 8a8936a..3127175 100644 --- a/drivers/auxdisplay/Makefile +++ b/drivers/auxdisplay/Makefile @@ -4,3 +4,4 @@ obj-$(CONFIG_KS0108) += ks0108.o obj-$(CONFIG_CFAG12864B) += cfag12864b.o cfag12864bfb.o +obj-$(CONFIG_IMG_ASCII_LCD) += img-ascii-lcd.o diff --git a/drivers/auxdisplay/img-ascii-lcd.c b/drivers/auxdisplay/img-ascii-lcd.c new file mode 100644 index 0000000..bf43b5d --- /dev/null +++ b/drivers/auxdisplay/img-ascii-lcd.c @@ -0,0 +1,443 @@ +/* + * Copyright (C) 2016 Imagination Technologies + * Author: Paul Burton + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct img_ascii_lcd_ctx; + +/** + * struct img_ascii_lcd_config - Configuration information about an LCD model + * @num_chars: the number of characters the LCD can display + * @external_regmap: true if registers are in a system controller, else false + * @update: function called to update the LCD + */ +struct img_ascii_lcd_config { + unsigned int num_chars; + bool external_regmap; + void (*update)(struct img_ascii_lcd_ctx *ctx); +}; + +/** + * struct img_ascii_lcd_ctx - Private data structure + * @pdev: the ASCII LCD platform device + * @base: the base address of the LCD registers + * @regmap: the regmap through which LCD registers are accessed + * @offset: the offset within regmap to the start of the LCD registers + * @cfg: pointer to the LCD model configuration + * @message: the full message to display or scroll on the LCD + * @message_len: the length of the @message string + * @scroll_pos: index of the first character of @message currently displayed + * @scroll_rate: scroll interval in jiffies + * @timer: timer used to implement scrolling + * @curr: the string currently displayed on the LCD + */ +struct img_ascii_lcd_ctx { + struct platform_device *pdev; + union { + void __iomem *base; + struct regmap *regmap; + }; + u32 offset; + const struct img_ascii_lcd_config *cfg; + char *message; + unsigned int message_len; + unsigned int scroll_pos; + unsigned int scroll_rate; + struct timer_list timer; + char curr[] __aligned(8); +}; + +/* + * MIPS Boston development board + */ + +static void boston_update(struct img_ascii_lcd_ctx *ctx) +{ + ulong val; + +#if BITS_PER_LONG == 64 + val = *((u64 *)&ctx->curr[0]); + __raw_writeq(val, ctx->base); +#elif BITS_PER_LONG == 32 + val = *((u32 *)&ctx->curr[0]); + __raw_writel(val, ctx->base); + val = *((u32 *)&ctx->curr[4]); + __raw_writel(val, ctx->base + 4); +#else +# error Not 32 or 64 bit +#endif +} + +static struct img_ascii_lcd_config boston_config = { + .num_chars = 8, + .update = boston_update, +}; + +/* + * MIPS Malta development board + */ + +static void malta_update(struct img_ascii_lcd_ctx *ctx) +{ + unsigned int i; + int err; + + for (i = 0; i < ctx->cfg->num_chars; i++) { + err = regmap_write(ctx->regmap, + ctx->offset + (i * 8), ctx->curr[i]); + if (err) + break; + } + + if (unlikely(err)) + pr_err_ratelimited("Failed to update LCD display: %d\n", err); +} + +static struct img_ascii_lcd_config malta_config = { + .num_chars = 8, + .external_regmap = true, + .update = malta_update, +}; + +/* + * MIPS SEAD3 development board + */ + +enum { + SEAD3_REG_LCD_CTRL = 0x00, +#define SEAD3_REG_LCD_CTRL_SETDRAM BIT(7) + SEAD3_REG_LCD_DATA = 0x08, + SEAD3_REG_CPLD_STATUS = 0x10, +#define SEAD3_REG_CPLD_STATUS_BUSY BIT(0) + SEAD3_REG_CPLD_DATA = 0x18, +#define SEAD3_REG_CPLD_DATA_BUSY BIT(7) +}; + +static int sead3_wait_sm_idle(struct img_ascii_lcd_ctx *ctx) +{ + unsigned int status; + int err; + + do { + err = regmap_read(ctx->regmap, + ctx->offset + SEAD3_REG_CPLD_STATUS, + &status); + if (err) + return err; + } while (status & SEAD3_REG_CPLD_STATUS_BUSY); + + return 0; + +} + +static int sead3_wait_lcd_idle(struct img_ascii_lcd_ctx *ctx) +{ + unsigned int cpld_data; + int err; + + err = sead3_wait_sm_idle(ctx); + if (err) + return err; + + do { + err = regmap_read(ctx->regmap, + ctx->offset + SEAD3_REG_LCD_CTRL, + &cpld_data); + if (err) + return err; + + err = sead3_wait_sm_idle(ctx); + if (err) + return err; + + err = regmap_read(ctx->regmap, + ctx->offset + SEAD3_REG_CPLD_DATA, + &cpld_data); + if (err) + return err; + } while (cpld_data & SEAD3_REG_CPLD_DATA_BUSY); + + return 0; +} + +static void sead3_update(struct img_ascii_lcd_ctx *ctx) +{ + unsigned int i; + int err; + + for (i = 0; i < ctx->cfg->num_chars; i++) { + err = sead3_wait_lcd_idle(ctx); + if (err) + break; + + err = regmap_write(ctx->regmap, + ctx->offset + SEAD3_REG_LCD_CTRL, + SEAD3_REG_LCD_CTRL_SETDRAM | i); + if (err) + break; + + err = sead3_wait_lcd_idle(ctx); + if (err) + break; + + err = regmap_write(ctx->regmap, + ctx->offset + SEAD3_REG_LCD_DATA, + ctx->curr[i]); + if (err) + break; + } + + if (unlikely(err)) + pr_err_ratelimited("Failed to update LCD display: %d\n", err); +} + +static struct img_ascii_lcd_config sead3_config = { + .num_chars = 16, + .external_regmap = true, + .update = sead3_update, +}; + +static const struct of_device_id img_ascii_lcd_matches[] = { + { .compatible = "img,boston-lcd", .data = &boston_config }, + { .compatible = "mti,malta-lcd", .data = &malta_config }, + { .compatible = "mti,sead3-lcd", .data = &sead3_config }, +}; + +/** + * img_ascii_lcd_scroll() - scroll the display by a character + * @arg: really a pointer to the private data structure + * + * Scroll the current message along the LCD by one character, rearming the + * timer if required. + */ +static void img_ascii_lcd_scroll(unsigned long arg) +{ + struct img_ascii_lcd_ctx *ctx = (struct img_ascii_lcd_ctx *)arg; + unsigned int i, ch = ctx->scroll_pos; + unsigned int num_chars = ctx->cfg->num_chars; + + /* update the current message string */ + for (i = 0; i < num_chars;) { + /* copy as many characters from the string as possible */ + for (; i < num_chars && ch < ctx->message_len; i++, ch++) + ctx->curr[i] = ctx->message[ch]; + + /* wrap around to the start of the string */ + ch = 0; + } + + /* update the LCD */ + ctx->cfg->update(ctx); + + /* move on to the next character */ + ctx->scroll_pos++; + ctx->scroll_pos %= ctx->message_len; + + /* rearm the timer */ + if (ctx->message_len > ctx->cfg->num_chars) + mod_timer(&ctx->timer, jiffies + ctx->scroll_rate); +} + +/** + * img_ascii_lcd_display() - set the message to be displayed + * @ctx: pointer to the private data structure + * @msg: the message to display + * @count: length of msg, or -1 + * + * Display a new message @msg on the LCD. @msg can be longer than the number of + * characters the LCD can display, in which case it will begin scrolling across + * the LCD display. + * + * Return: 0 on success, -ENOMEM on memory allocation failure + */ +static int img_ascii_lcd_display(struct img_ascii_lcd_ctx *ctx, + const char *msg, ssize_t count) +{ + char *new_msg; + + /* stop the scroll timer */ + del_timer_sync(&ctx->timer); + + if (count == -1) + count = strlen(msg); + + /* if the string ends with a newline, trim it */ + if (msg[count - 1] == '\n') + count--; + + new_msg = devm_kmalloc(&ctx->pdev->dev, count + 1, GFP_KERNEL); + if (!new_msg) + return -ENOMEM; + + memcpy(new_msg, msg, count); + new_msg[count] = 0; + + if (ctx->message) + devm_kfree(&ctx->pdev->dev, ctx->message); + + ctx->message = new_msg; + ctx->message_len = count; + ctx->scroll_pos = 0; + + /* update the LCD */ + img_ascii_lcd_scroll((unsigned long)ctx); + + return 0; +} + +/** + * message_show() - read message via sysfs + * @dev: the LCD device + * @attr: the LCD message attribute + * @buf: the buffer to read the message into + * + * Read the current message being displayed or scrolled across the LCD display + * into @buf, for reads from sysfs. + * + * Return: the number of characters written to @buf + */ +static ssize_t message_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct img_ascii_lcd_ctx *ctx = dev_get_drvdata(dev); + + return sprintf(buf, "%s\n", ctx->message); +} + +/** + * message_store() - write a new message via sysfs + * @dev: the LCD device + * @attr: the LCD message attribute + * @buf: the buffer containing the new message + * @count: the size of the message in @buf + * + * Write a new message to display or scroll across the LCD display from sysfs. + * + * Return: the size of the message on success, else -ERRNO + */ +static ssize_t message_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct img_ascii_lcd_ctx *ctx = dev_get_drvdata(dev); + int err; + + err = img_ascii_lcd_display(ctx, buf, count); + return err ?: count; +} + +static DEVICE_ATTR_RW(message); + +/** + * img_ascii_lcd_probe() - probe an LCD display device + * @pdev: the LCD platform device + * + * Probe an LCD display device, ensuring that we have the required resources in + * order to access the LCD & setting up private data as well as sysfs files. + * + * Return: 0 on success, else -ERRNO + */ +static int img_ascii_lcd_probe(struct platform_device *pdev) +{ + const struct of_device_id *match; + const struct img_ascii_lcd_config *cfg; + struct img_ascii_lcd_ctx *ctx; + struct resource *res; + int err; + + match = of_match_device(img_ascii_lcd_matches, &pdev->dev); + if (!match) + return -ENODEV; + + cfg = match->data; + ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx) + cfg->num_chars, + GFP_KERNEL); + if (!ctx) + return -ENOMEM; + + if (cfg->external_regmap) { + ctx->regmap = syscon_node_to_regmap(pdev->dev.parent->of_node); + if (IS_ERR(ctx->regmap)) + return PTR_ERR(ctx->regmap); + + if (of_property_read_u32(pdev->dev.of_node, "offset", + &ctx->offset)) + return -EINVAL; + } else { + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + ctx->base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(ctx->base)) + return PTR_ERR(ctx->base); + } + + ctx->pdev = pdev; + ctx->cfg = cfg; + ctx->message = NULL; + ctx->scroll_pos = 0; + ctx->scroll_rate = HZ / 2; + + /* initialise a timer for scrolling the message */ + init_timer(&ctx->timer); + ctx->timer.function = img_ascii_lcd_scroll; + ctx->timer.data = (unsigned long)ctx; + + platform_set_drvdata(pdev, ctx); + + /* display a default message */ + err = img_ascii_lcd_display(ctx, "Linux " UTS_RELEASE " ", -1); + if (err) + goto out_del_timer; + + err = device_create_file(&pdev->dev, &dev_attr_message); + if (err) + goto out_del_timer; + + return 0; +out_del_timer: + del_timer_sync(&ctx->timer); + return err; +} + +/** + * img_ascii_lcd_remove() - remove an LCD display device + * @pdev: the LCD platform device + * + * Remove an LCD display device, freeing private resources & ensuring that the + * driver stops using the LCD display registers. + * + * Return: 0 + */ +static int img_ascii_lcd_remove(struct platform_device *pdev) +{ + struct img_ascii_lcd_ctx *ctx = platform_get_drvdata(pdev); + + device_remove_file(&pdev->dev, &dev_attr_message); + del_timer_sync(&ctx->timer); + return 0; +} + +static struct platform_driver img_ascii_lcd_driver = { + .driver = { + .name = "img-ascii-lcd", + .of_match_table = img_ascii_lcd_matches, + }, + .probe = img_ascii_lcd_probe, + .remove = img_ascii_lcd_remove, +}; +module_platform_driver(img_ascii_lcd_driver); -- cgit v0.10.2 From 5e189564d574541c6f149ab3a1081d25eec06fd0 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Fri, 26 Aug 2016 15:17:50 +0100 Subject: MIPS: SEAD3: Use img-ascii-lcd driver Probe the img-ascii-lcd driver using device tree in order to display a message on the SEAD3 board's LCD display, and remove the platform code that was formerly performing this function. This removes more platform code and moves SEAD3 further towards being entirely DT-based. Signed-off-by: Paul Burton Cc: Jacek Anaszewski Cc: Rob Herring Cc: Mark Rutland Cc: linux-mips@linux-mips.org Cc: devicetree@vger.kernel.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14063/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/boot/dts/mti/sead3.dts b/arch/mips/boot/dts/mti/sead3.dts index 32a5ab9..2579ca5 100644 --- a/arch/mips/boot/dts/mti/sead3.dts +++ b/arch/mips/boot/dts/mti/sead3.dts @@ -210,6 +210,11 @@ mask = <0x80>; label = "fled7"; }; + + lcd@200 { + compatible = "mti,sead3-lcd"; + offset = <0x200>; + }; }; /* UART connected to FTDI & miniUSB socket */ diff --git a/arch/mips/mti-sead3/Makefile b/arch/mips/mti-sead3/Makefile index cb6d620..1674b9c 100644 --- a/arch/mips/mti-sead3/Makefile +++ b/arch/mips/mti-sead3/Makefile @@ -8,8 +8,7 @@ # Copyright (C) 2012 MIPS Technoligies, Inc. All rights reserved. # Steven J. Hill # -obj-y := sead3-display.o -obj-y += sead3-dtshim.o +obj-y := sead3-dtshim.o obj-y += sead3-init.o obj-y += sead3-int.o obj-y += sead3-setup.o diff --git a/arch/mips/mti-sead3/sead3-display.c b/arch/mips/mti-sead3/sead3-display.c deleted file mode 100644 index 9487599..0000000 --- a/arch/mips/mti-sead3/sead3-display.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. - */ -#include -#include -#include - -static unsigned int display_count; -static unsigned int max_display_count; - -#define LCD_DISPLAY_POS_BASE 0x1f000400 -#define DISPLAY_LCDINSTRUCTION (0*2) -#define DISPLAY_LCDDATA (1*2) -#define DISPLAY_CPLDSTATUS (2*2) -#define DISPLAY_CPLDDATA (3*2) -#define LCD_SETDDRAM 0x80 -#define LCD_IR_BF 0x80 - -const char display_string[] = " LINUX ON SEAD3 "; - -static void scroll_display_message(unsigned long data); -static DEFINE_TIMER(mips_scroll_timer, scroll_display_message, HZ, 0); - -static void lcd_wait(unsigned int __iomem *display) -{ - /* Wait for CPLD state machine to become idle. */ - do { } while (__raw_readl(display + DISPLAY_CPLDSTATUS) & 1); - - do { - __raw_readl(display + DISPLAY_LCDINSTRUCTION); - - /* Wait for CPLD state machine to become idle. */ - do { } while (__raw_readl(display + DISPLAY_CPLDSTATUS) & 1); - } while (__raw_readl(display + DISPLAY_CPLDDATA) & LCD_IR_BF); -} - -void mips_display_message(const char *str) -{ - static unsigned int __iomem *display; - char ch; - int i; - - if (unlikely(display == NULL)) - display = ioremap_nocache(LCD_DISPLAY_POS_BASE, - (8 * sizeof(int))); - - for (i = 0; i < 16; i++) { - if (*str) - ch = *str++; - else - ch = ' '; - lcd_wait(display); - __raw_writel((LCD_SETDDRAM | i), - (display + DISPLAY_LCDINSTRUCTION)); - lcd_wait(display); - __raw_writel(ch, display + DISPLAY_LCDDATA); - } -} - -static void scroll_display_message(unsigned long data) -{ - mips_display_message(&display_string[display_count++]); - if (display_count == max_display_count) - display_count = 0; - mod_timer(&mips_scroll_timer, jiffies + HZ); -} - -void mips_scroll_message(void) -{ - del_timer_sync(&mips_scroll_timer); - max_display_count = strlen(display_string) + 1 - 16; - mod_timer(&mips_scroll_timer, jiffies + 1); -} diff --git a/arch/mips/mti-sead3/sead3-time.c b/arch/mips/mti-sead3/sead3-time.c index a120b7a..10b0bf3 100644 --- a/arch/mips/mti-sead3/sead3-time.c +++ b/arch/mips/mti-sead3/sead3-time.c @@ -94,6 +94,4 @@ void __init plat_time_init(void) pr_debug("CPU frequency %d.%02d MHz\n", (est_freq / 1000000), (est_freq % 1000000) * 100 / 1000000); - - mips_scroll_message(); } -- cgit v0.10.2 From e6a54ba304b15275884b029c2234ea74c4e591d0 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Fri, 26 Aug 2016 15:17:51 +0100 Subject: MIPS: SEAD3: Remove custom read_persistent_clock The SEAD3 board defines a custom implementation of read_persistent_clock which does exactly the same dummy operation as the generic weak version. Remove the not really implemented custom version. Signed-off-by: Paul Burton Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14064/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/mti-sead3/sead3-time.c b/arch/mips/mti-sead3/sead3-time.c index 10b0bf3..71feb51 100644 --- a/arch/mips/mti-sead3/sead3-time.c +++ b/arch/mips/mti-sead3/sead3-time.c @@ -63,12 +63,6 @@ static unsigned int __init estimate_cpu_frequency(void) return freq ; } -void read_persistent_clock(struct timespec *ts) -{ - ts->tv_sec = 0; - ts->tv_nsec = 0; -} - int get_c0_perfcount_int(void) { if (gic_present) -- cgit v0.10.2 From 690803acca14e8aa101ca5204f0a23c24d7ad8c3 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Mon, 19 Sep 2016 22:21:18 +0100 Subject: irqchip: i8259: Add domain before mapping parent irq Mapping the parent IRQ will use a virq number which may conflict with the hardcoded I8259A_IRQ_BASE..I8259A_IRQ_BASE+15 range that the i8259 driver expects to be free. If this occurs then we'll hit errors when adding the i8259 IRQ domain, since one of its virq numbers will already be in use. Avoid this by adding the i8259 domain before mapping the parent IRQ, such that the i8259 virq numbers become used before the parent interrupt controller gets a chance to use any of them. Signed-off-by: Paul Burton Acked-by: Thomas Gleixner Cc: Marc Zyngier Cc: Jason Cooper Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14269/ Signed-off-by: Ralf Baechle diff --git a/drivers/irqchip/irq-i8259.c b/drivers/irqchip/irq-i8259.c index 6b304eb..85897fd 100644 --- a/drivers/irqchip/irq-i8259.c +++ b/drivers/irqchip/irq-i8259.c @@ -370,13 +370,15 @@ int __init i8259_of_init(struct device_node *node, struct device_node *parent) struct irq_domain *domain; unsigned int parent_irq; + domain = __init_i8259_irqs(node); + parent_irq = irq_of_parse_and_map(node, 0); if (!parent_irq) { pr_err("Failed to map i8259 parent IRQ\n"); + irq_domain_remove(domain); return -ENODEV; } - domain = __init_i8259_irqs(node); irq_set_chained_handler_and_data(parent_irq, i8259_irq_dispatch, domain); return 0; -- cgit v0.10.2 From 19afc3d269fe66137ddb030b8ffdb8553066ba4a Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Mon, 19 Sep 2016 22:21:19 +0100 Subject: irqchip: i8259: Allow platforms to override poll function The default i8259 polling function (i8259_irq) is nicely generic but is fairly costly. Platforms often provide an alternative means of polling for an i8259 interrupt, and when using the i8259 without device tree have typically just chained its parent interrupt to their own handler function. In order to allow for platform-specific polling functions to be used in cases where the driver is probed via device tree, provide an i8259_set_poll function that accepts a pointer to an alternative poll function that will override the default. Signed-off-by: Paul Burton Acked-by: Thomas Gleixner Cc: Jason Cooper Cc: Marc Zyngier Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14270/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/include/asm/i8259.h b/arch/mips/include/asm/i8259.h index a7fbcd6..b27fcc4 100644 --- a/arch/mips/include/asm/i8259.h +++ b/arch/mips/include/asm/i8259.h @@ -43,6 +43,17 @@ extern void make_8259A_irq(unsigned int irq); extern void init_i8259_irqs(void); extern int i8259_of_init(struct device_node *node, struct device_node *parent); +/** + * i8159_set_poll() - Override the i8259 polling function + * @poll: pointer to platform-specific polling function + * + * Call this to override the generic i8259 polling function, which directly + * accesses i8259 registers, with a platform specific one which may be faster + * in cases where hardware provides a more optimal means of polling for an + * interrupt. + */ +extern void i8259_set_poll(int (*poll)(void)); + /* * Do the traditional i8259 interrupt polling thing. This is for the few * cases where no better interrupt acknowledge method is available and we diff --git a/drivers/irqchip/irq-i8259.c b/drivers/irqchip/irq-i8259.c index 85897fd..1f4a344 100644 --- a/drivers/irqchip/irq-i8259.c +++ b/drivers/irqchip/irq-i8259.c @@ -38,6 +38,7 @@ static void disable_8259A_irq(struct irq_data *d); static void enable_8259A_irq(struct irq_data *d); static void mask_and_ack_8259A(struct irq_data *d); static void init_8259A(int auto_eoi); +static int (*i8259_poll)(void) = i8259_irq; static struct irq_chip i8259A_chip = { .name = "XT-PIC", @@ -51,6 +52,11 @@ static struct irq_chip i8259A_chip = { * 8259A PIC functions to handle ISA devices: */ +void i8259_set_poll(int (*poll)(void)) +{ + i8259_poll = poll; +} + /* * This contains the irq mask for both 8259A irq controllers, */ @@ -355,7 +361,7 @@ void __init init_i8259_irqs(void) static void i8259_irq_dispatch(struct irq_desc *desc) { struct irq_domain *domain = irq_desc_get_handler_data(desc); - int hwirq = i8259_irq(); + int hwirq = i8259_poll(); unsigned int irq; if (hwirq < 0) -- cgit v0.10.2 From 5d2949ec86a54b73a6fc2557ef784e76c0d2cba9 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Mon, 19 Sep 2016 22:21:20 +0100 Subject: irqchip: i8259: Remove unused i8259A_irq_pending The i8259A_irq_pending function is unused. Remove the dead code. Signed-off-by: Paul Burton Acked-by: Thomas Gleixner Cc: Jason Cooper Cc: Marc Zyngier Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14271/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/include/asm/i8259.h b/arch/mips/include/asm/i8259.h index b27fcc4..32229c7 100644 --- a/arch/mips/include/asm/i8259.h +++ b/arch/mips/include/asm/i8259.h @@ -37,7 +37,6 @@ extern raw_spinlock_t i8259A_lock; -extern int i8259A_irq_pending(unsigned int irq); extern void make_8259A_irq(unsigned int irq); extern void init_i8259_irqs(void); diff --git a/drivers/irqchip/irq-i8259.c b/drivers/irqchip/irq-i8259.c index 1f4a344..1aec12c 100644 --- a/drivers/irqchip/irq-i8259.c +++ b/drivers/irqchip/irq-i8259.c @@ -95,24 +95,6 @@ static void enable_8259A_irq(struct irq_data *d) raw_spin_unlock_irqrestore(&i8259A_lock, flags); } -int i8259A_irq_pending(unsigned int irq) -{ - unsigned int mask; - unsigned long flags; - int ret; - - irq -= I8259A_IRQ_BASE; - mask = 1 << irq; - raw_spin_lock_irqsave(&i8259A_lock, flags); - if (irq < 8) - ret = inb(PIC_MASTER_CMD) & mask; - else - ret = inb(PIC_SLAVE_CMD) & (mask >> 8); - raw_spin_unlock_irqrestore(&i8259A_lock, flags); - - return ret; -} - void make_8259A_irq(unsigned int irq) { disable_irq_nosync(irq); -- cgit v0.10.2 From 422dd256642b75808cbf447040481cac11ccbefc Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Mon, 19 Sep 2016 22:21:21 +0100 Subject: MIPS: Malta: Allow PCI devices DMA to lower 2GB physical Set the PCI_BAR0 register in all configurations such that PCI devices can perform DMA to all of the bottom 2GB of the physical address space. This is imperfect if we make use of the legacy Malta memory map, but it is an improvement on the inconsistent values setup before. Signed-off-by: Paul Burton Cc: Alexander Sverdlin Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14272/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/mti-malta/malta-init.c b/arch/mips/mti-malta/malta-init.c index dc2c521..0f3b881 100644 --- a/arch/mips/mti-malta/malta-init.c +++ b/arch/mips/mti-malta/malta-init.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -242,23 +243,19 @@ mips_pci_controller: MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_MEM_SHF | MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_BAR0_SHF); #endif -#ifndef CONFIG_EVA - /* Fix up target memory mapping. */ - MSC_READ(MSC01_PCI_BAR0, mask); - MSC_WRITE(MSC01_PCI_P2SCMSKL, mask & MSC01_PCI_BAR0_SIZE_MSK); -#else + /* * Setup the Malta max (2GB) memory for PCI DMA in host bridge - * in transparent addressing mode, starting from 0x80000000. + * in transparent addressing mode. */ - mask = PHYS_OFFSET | (1<<3); + mask = PHYS_OFFSET | PCI_BASE_ADDRESS_MEM_PREFETCH; MSC_WRITE(MSC01_PCI_BAR0, mask); - - mask = PHYS_OFFSET; MSC_WRITE(MSC01_PCI_HEAD4, mask); + + mask &= MSC01_PCI_BAR0_SIZE_MSK; MSC_WRITE(MSC01_PCI_P2SCMSKL, mask); MSC_WRITE(MSC01_PCI_P2SCMAPL, mask); -#endif + /* Don't handle target retries indefinitely. */ if ((data & MSC01_PCI_CFG_MAXRTRY_MSK) == MSC01_PCI_CFG_MAXRTRY_MSK) -- cgit v0.10.2 From 0051fc2e7b84500c4ecf66cda4ac0879340600ef Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Mon, 19 Sep 2016 22:21:22 +0100 Subject: MIPS: Malta: Use all available DDR by default Malta boards can have more than 256MB DDR available, but we have previously only made use of up to 256MB (ie. the DDR accessible via kseg0) by default, without the user manually specifying mem= kernel parameters. This patch causes all available DDR, as reported by the bootloader via the ememsize or memsize environment variables or optionally on the command line, to be used when possible without the user needing to manually provide the memory ranges. Malta now has 2 subtly different memory maps which have to be taken into account when setting this up. The original memory map (referred to by the code as v1) has up to 2GB of DDR aliased in both the upper & lower halves of the 32 bit physical address space, with a 256MB I/O region obscuring 0x10000000-0x1fffffff only in the lower alias. The revised v2 memory map is flat with up to 4GB DDR starting from 0x0, and the I/O region obscures 256MB of DDR which becomes inacessible. The memory map in use is indicated by a register provided by the rocit2 system controller, which is checked in order to set up the kernels memory ranges accordingly. Signed-off-by: Paul Burton Cc: Masahiro Yamada Cc: Kees Cook Cc: Andrew Morton Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14273/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/mti-malta/malta-dtshim.c b/arch/mips/mti-malta/malta-dtshim.c index 151f488..bdda3cb 100644 --- a/arch/mips/mti-malta/malta-dtshim.c +++ b/arch/mips/mti-malta/malta-dtshim.c @@ -13,18 +13,64 @@ #include #include #include +#include #include #include +#include #include +#define ROCIT_REG_BASE 0x1f403000 +#define ROCIT_CONFIG_GEN1 (ROCIT_REG_BASE + 0x04) +#define ROCIT_CONFIG_GEN1_MEMMAP_SHIFT 8 +#define ROCIT_CONFIG_GEN1_MEMMAP_MASK (0xf << 8) + static unsigned char fdt_buf[16 << 10] __initdata; /* determined physical memory size, not overridden by command line args */ extern unsigned long physical_memsize; -#define MAX_MEM_ARRAY_ENTRIES 1 +enum mem_map { + MEM_MAP_V1 = 0, + MEM_MAP_V2, +}; + +#define MAX_MEM_ARRAY_ENTRIES 2 + +static __init int malta_scon(void) +{ + int scon = MIPS_REVISION_SCONID; + + if (scon != MIPS_REVISION_SCON_OTHER) + return scon; + + switch (MIPS_REVISION_CORID) { + case MIPS_REVISION_CORID_QED_RM5261: + case MIPS_REVISION_CORID_CORE_LV: + case MIPS_REVISION_CORID_CORE_FPGA: + case MIPS_REVISION_CORID_CORE_FPGAR2: + return MIPS_REVISION_SCON_GT64120; + + case MIPS_REVISION_CORID_CORE_EMUL_BON: + case MIPS_REVISION_CORID_BONITO64: + case MIPS_REVISION_CORID_CORE_20K: + return MIPS_REVISION_SCON_BONITO; + + case MIPS_REVISION_CORID_CORE_MSC: + case MIPS_REVISION_CORID_CORE_FPGA2: + case MIPS_REVISION_CORID_CORE_24K: + return MIPS_REVISION_SCON_SOCIT; + + case MIPS_REVISION_CORID_CORE_FPGA3: + case MIPS_REVISION_CORID_CORE_FPGA4: + case MIPS_REVISION_CORID_CORE_FPGA5: + case MIPS_REVISION_CORID_CORE_EMUL_MSC: + default: + return MIPS_REVISION_SCON_ROCIT; + } +} -static unsigned __init gen_fdt_mem_array(__be32 *mem_array, unsigned long size) +static unsigned __init gen_fdt_mem_array(__be32 *mem_array, unsigned long size, + enum mem_map map) { unsigned long size_preio; unsigned entries; @@ -39,11 +85,47 @@ static unsigned __init gen_fdt_mem_array(__be32 *mem_array, unsigned long size) * DDR but limits it to 2GB. */ mem_array[1] = cpu_to_be32(size); + goto done; + } + + size_preio = min_t(unsigned long, size, SZ_256M); + mem_array[1] = cpu_to_be32(size_preio); + size -= size_preio; + if (!size) + goto done; + + if (map == MEM_MAP_V2) { + /* + * We have a flat 32 bit physical memory map with DDR filling + * all 4GB of the memory map, apart from the I/O region which + * obscures 256MB from 0x10000000-0x1fffffff. + * + * Therefore we discard the 256MB behind the I/O region. + */ + if (size <= SZ_256M) + goto done; + size -= SZ_256M; + + /* Make use of the memory following the I/O region */ + entries++; + mem_array[2] = cpu_to_be32(PHYS_OFFSET + SZ_512M); + mem_array[3] = cpu_to_be32(size); } else { - size_preio = min_t(unsigned long, size, SZ_256M); - mem_array[1] = cpu_to_be32(size_preio); + /* + * We have a 32 bit physical memory map with a 2GB DDR region + * aliased in the upper & lower halves of it. The I/O region + * obscures 256MB from 0x10000000-0x1fffffff in the low alias + * but the DDR it obscures is accessible via the high alias. + * + * Simply access everything beyond the lowest 256MB of DDR using + * the high alias. + */ + entries++; + mem_array[2] = cpu_to_be32(PHYS_OFFSET + SZ_2G + SZ_256M); + mem_array[3] = cpu_to_be32(size); } +done: BUG_ON(entries > MAX_MEM_ARRAY_ENTRIES); return entries; } @@ -54,6 +136,8 @@ static void __init append_memory(void *fdt, int root_off) unsigned long memsize; unsigned mem_entries; int i, err, mem_off; + enum mem_map mem_map; + u32 config; char *var, param_name[10], *var_names[] = { "ememsize", "memsize", }; @@ -106,6 +190,20 @@ static void __init append_memory(void *fdt, int root_off) /* if the user says there's more RAM than we thought, believe them */ physical_memsize = max_t(unsigned long, physical_memsize, memsize); + /* detect the memory map in use */ + if (malta_scon() == MIPS_REVISION_SCON_ROCIT) { + /* ROCit has a register indicating the memory map in use */ + config = readl((void __iomem *)CKSEG1ADDR(ROCIT_CONFIG_GEN1)); + mem_map = config & ROCIT_CONFIG_GEN1_MEMMAP_MASK; + mem_map >>= ROCIT_CONFIG_GEN1_MEMMAP_SHIFT; + } else { + /* if not using ROCit, presume the v1 memory map */ + mem_map = MEM_MAP_V1; + } + if (mem_map > MEM_MAP_V2) + panic("Unsupported physical memory map v%u detected", + (unsigned int)mem_map); + /* append memory to the DT */ mem_off = fdt_add_subnode(fdt, root_off, "memory"); if (mem_off < 0) @@ -115,13 +213,13 @@ static void __init append_memory(void *fdt, int root_off) if (err) panic("Unable to set memory node device_type: %d", err); - mem_entries = gen_fdt_mem_array(mem_array, physical_memsize); + mem_entries = gen_fdt_mem_array(mem_array, physical_memsize, mem_map); err = fdt_setprop(fdt, mem_off, "reg", mem_array, mem_entries * 2 * sizeof(mem_array[0])); if (err) panic("Unable to set memory regs property: %d", err); - mem_entries = gen_fdt_mem_array(mem_array, memsize); + mem_entries = gen_fdt_mem_array(mem_array, memsize, mem_map); err = fdt_setprop(fdt, mem_off, "linux,usable-memory", mem_array, mem_entries * 2 * sizeof(mem_array[0])); if (err) -- cgit v0.10.2 From 38ec82fe21cd99ad4d7f0dc883ef7ce9e9837176 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Mon, 19 Sep 2016 22:21:23 +0100 Subject: MIPS: Malta: Probe interrupt controllers via DT Probe the CPU, GIC & i8259 interrupt controllers present in the Malta system using device tree. This enables interrupts to be provided to devices using device tree as they are moved over to being probed using it. Since Malta is very configurable it's unknown whether a GIC will be present at compile time. In order to support both cases the malta_dt_shim code is added in order to detect whether a GIC is present, adjusting the DT to route interrupts correctly and nop out the GIC node if no GIC is found. Signed-off-by: Paul Burton Cc: Masahiro Yamada Cc: Kees Cook Cc: Rob Herring Cc: Mark Rutland Cc: Andrew Morton Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Cc: devicetree@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14274/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 7ec9ed7..400cd36 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -479,6 +479,7 @@ config MIPS_MALTA select SYS_SUPPORTS_ZBOOT select SYS_SUPPORTS_RELOCATABLE select USE_OF + select LIBFDT select ZONE_DMA32 if 64BIT select BUILTIN_DTB select LIBFDT diff --git a/arch/mips/boot/dts/mti/malta.dts b/arch/mips/boot/dts/mti/malta.dts index b18c466..af765af 100644 --- a/arch/mips/boot/dts/mti/malta.dts +++ b/arch/mips/boot/dts/mti/malta.dts @@ -1,5 +1,8 @@ /dts-v1/; +#include +#include + /memreserve/ 0x00000000 0x00001000; /* YAMON exception vectors */ /memreserve/ 0x00001000 0x000ef000; /* YAMON */ /memreserve/ 0x000f0000 0x00010000; /* PIIX4 ISA memory */ @@ -8,4 +11,42 @@ #address-cells = <1>; #size-cells = <1>; compatible = "mti,malta"; + + cpu_intc: interrupt-controller { + compatible = "mti,cpu-interrupt-controller"; + + interrupt-controller; + #interrupt-cells = <1>; + }; + + gic: interrupt-controller@1bdc0000 { + compatible = "mti,gic"; + reg = <0x1bdc0000 0x20000>; + + interrupt-controller; + #interrupt-cells = <3>; + + /* + * Declare the interrupt-parent even though the mti,gic + * binding doesn't require it, such that the kernel can + * figure out that cpu_intc is the root interrupt + * controller & should be probed first. + */ + interrupt-parent = <&cpu_intc>; + + timer { + compatible = "mti,gic-timer"; + interrupts = ; + }; + }; + + i8259: interrupt-controller@20 { + compatible = "intel,i8259"; + + interrupt-controller; + #interrupt-cells = <1>; + + interrupt-parent = <&gic>; + interrupts = ; + }; }; diff --git a/arch/mips/mti-malta/malta-dtshim.c b/arch/mips/mti-malta/malta-dtshim.c index bdda3cb..c398582 100644 --- a/arch/mips/mti-malta/malta-dtshim.c +++ b/arch/mips/mti-malta/malta-dtshim.c @@ -17,6 +17,8 @@ #include #include #include +#include +#include #include #define ROCIT_REG_BASE 0x1f403000 @@ -226,6 +228,80 @@ static void __init append_memory(void *fdt, int root_off) panic("Unable to set linux,usable-memory property: %d", err); } +static void __init remove_gic(void *fdt) +{ + int err, gic_off, i8259_off, cpu_off; + void __iomem *biu_base; + uint32_t cpu_phandle, sc_cfg; + + /* if we have a CM which reports a GIC is present, leave the DT alone */ + err = mips_cm_probe(); + if (!err && (read_gcr_gic_status() & CM_GCR_GIC_STATUS_GICEX_MSK)) + return; + + if (malta_scon() == MIPS_REVISION_SCON_ROCIT) { + /* + * On systems using the RocIT system controller a GIC may be + * present without a CM. Detect whether that is the case. + */ + biu_base = ioremap_nocache(MSC01_BIU_REG_BASE, + MSC01_BIU_ADDRSPACE_SZ); + sc_cfg = __raw_readl(biu_base + MSC01_SC_CFG_OFS); + if (sc_cfg & MSC01_SC_CFG_GICPRES_MSK) { + /* enable the GIC at the system controller level */ + sc_cfg |= BIT(MSC01_SC_CFG_GICENA_SHF); + __raw_writel(sc_cfg, biu_base + MSC01_SC_CFG_OFS); + return; + } + } + + gic_off = fdt_node_offset_by_compatible(fdt, -1, "mti,gic"); + if (gic_off < 0) { + pr_warn("malta-dtshim: unable to find DT GIC node: %d\n", + gic_off); + return; + } + + err = fdt_nop_node(fdt, gic_off); + if (err) + pr_warn("malta-dtshim: unable to nop GIC node\n"); + + i8259_off = fdt_node_offset_by_compatible(fdt, -1, "intel,i8259"); + if (i8259_off < 0) { + pr_warn("malta-dtshim: unable to find DT i8259 node: %d\n", + i8259_off); + return; + } + + cpu_off = fdt_node_offset_by_compatible(fdt, -1, + "mti,cpu-interrupt-controller"); + if (cpu_off < 0) { + pr_warn("malta-dtshim: unable to find CPU intc node: %d\n", + cpu_off); + return; + } + + cpu_phandle = fdt_get_phandle(fdt, cpu_off); + if (!cpu_phandle) { + pr_warn("malta-dtshim: unable to get CPU intc phandle\n"); + return; + } + + err = fdt_setprop_u32(fdt, i8259_off, "interrupt-parent", cpu_phandle); + if (err) { + pr_warn("malta-dtshim: unable to set i8259 interrupt-parent: %d\n", + err); + return; + } + + err = fdt_setprop_u32(fdt, i8259_off, "interrupts", 2); + if (err) { + pr_warn("malta-dtshim: unable to set i8259 interrupts: %d\n", + err); + return; + } +} + void __init *malta_dt_shim(void *fdt) { int root_off, len, err; @@ -251,6 +327,7 @@ void __init *malta_dt_shim(void *fdt) return fdt; append_memory(fdt_buf, root_off); + remove_gic(fdt_buf); err = fdt_pack(fdt_buf); if (err) diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c index c6a6c7a..9f83224 100644 --- a/arch/mips/mti-malta/malta-int.c +++ b/arch/mips/mti-malta/malta-int.c @@ -14,11 +14,13 @@ */ #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -37,10 +39,6 @@ #include #include -static void __iomem *_msc01_biu_base; - -static DEFINE_RAW_SPINLOCK(mips_irq_lock); - static inline int mips_pcibios_iack(void) { int irq; @@ -85,49 +83,6 @@ static inline int mips_pcibios_iack(void) return irq; } -static inline int get_int(void) -{ - unsigned long flags; - int irq; - raw_spin_lock_irqsave(&mips_irq_lock, flags); - - irq = mips_pcibios_iack(); - - /* - * The only way we can decide if an interrupt is spurious - * is by checking the 8259 registers. This needs a spinlock - * on an SMP system, so leave it up to the generic code... - */ - - raw_spin_unlock_irqrestore(&mips_irq_lock, flags); - - return irq; -} - -static void malta_hw0_irqdispatch(void) -{ - int irq; - - irq = get_int(); - if (irq < 0) { - /* interrupt has already been cleared */ - return; - } - - do_IRQ(MALTA_INT_BASE + irq); - -#ifdef CONFIG_MIPS_VPE_APSP_API_MT - if (aprp_hook) - aprp_hook(); -#endif -} - -static irqreturn_t i8259_handler(int irq, void *dev_id) -{ - malta_hw0_irqdispatch(); - return IRQ_HANDLED; -} - static void corehi_irqdispatch(void) { unsigned int intedge, intsteer, pcicmd, pcibadaddr; @@ -240,12 +195,6 @@ static struct irqaction irq_call = { }; #endif /* CONFIG_MIPS_MT_SMP */ -static struct irqaction i8259irq = { - .handler = i8259_handler, - .name = "XT-PIC cascade", - .flags = IRQF_NO_THREAD, -}; - static struct irqaction corehi_irqaction = { .handler = corehi_handler, .name = "CoreHi", @@ -281,28 +230,10 @@ void __init arch_init_ipiirq(int irq, struct irqaction *action) void __init arch_init_irq(void) { - int corehi_irq, i8259_irq; + int corehi_irq; - init_i8259_irqs(); - - if (!cpu_has_veic) - mips_cpu_irq_init(); - - if (mips_cm_present()) { - write_gcr_gic_base(GIC_BASE_ADDR | CM_GCR_GIC_BASE_GICEN_MSK); - gic_present = 1; - } else { - if (mips_revision_sconid == MIPS_REVISION_SCON_ROCIT) { - _msc01_biu_base = ioremap_nocache(MSC01_BIU_REG_BASE, - MSC01_BIU_ADDRSPACE_SZ); - gic_present = - (__raw_readl(_msc01_biu_base + MSC01_SC_CFG_OFS) & - MSC01_SC_CFG_GICPRES_MSK) >> - MSC01_SC_CFG_GICPRES_SHF; - } - } - if (gic_present) - pr_debug("GIC present\n"); + i8259_set_poll(mips_pcibios_iack); + irqchip_init(); switch (mips_revision_sconid) { case MIPS_REVISION_SCON_SOCIT: @@ -330,18 +261,6 @@ void __init arch_init_irq(void) } if (gic_present) { - int i; - - gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, MIPSCPU_INT_GIC, - MIPS_GIC_IRQ_BASE); - if (!mips_cm_present()) { - /* Enable the GIC */ - i = __raw_readl(_msc01_biu_base + MSC01_SC_CFG_OFS); - __raw_writel(i | (0x1 << MSC01_SC_CFG_GICENA_SHF), - _msc01_biu_base + MSC01_SC_CFG_OFS); - pr_debug("GIC Enabled\n"); - } - i8259_irq = MIPS_GIC_IRQ_BASE + GIC_INT_I8259A; corehi_irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_COREHI; } else { #if defined(CONFIG_MIPS_MT_SMP) @@ -361,19 +280,14 @@ void __init arch_init_irq(void) arch_init_ipiirq(cpu_ipi_call_irq, &irq_call); #endif if (cpu_has_veic) { - set_vi_handler(MSC01E_INT_I8259A, - malta_hw0_irqdispatch); set_vi_handler(MSC01E_INT_COREHI, corehi_irqdispatch); - i8259_irq = MSC01E_INT_BASE + MSC01E_INT_I8259A; corehi_irq = MSC01E_INT_BASE + MSC01E_INT_COREHI; } else { - i8259_irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_I8259A; corehi_irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_COREHI; } } - setup_irq(i8259_irq, &i8259irq); setup_irq(corehi_irq, &corehi_irqaction); } -- cgit v0.10.2 From ecd76eded07d1ba58bba410ec4bcbd8630fb9b16 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Mon, 19 Sep 2016 22:21:24 +0100 Subject: of/platform: Probe "isa" busses by default Since commit 44a7185c2ae6 ("of/platform: Add common method to populate default bus") platforms calling of_platform_bus_probe from an initcall is either a rather unsafe race with of_platform_default_populate_init or a no-op. The MIPS Malta board needs to probe devices under an ISA bus, which we do support in the of_busses array but until now haven't included in of_default_bus_match_table. Add an "isa" entry to of_default_bus_match_table such that we can just accept use of of_platform_default_populate_init & remove the Malta-specific match table in a later patch. Signed-off-by: Paul Burton Acked-by: Rob Herring Cc: Frank Rowand Cc: linux-mips@linux-mips.org Cc: devicetree@vger.kernel.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14275/ Signed-off-by: Ralf Baechle diff --git a/drivers/of/platform.c b/drivers/of/platform.c index f39ccd5..d85e431 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -29,6 +29,7 @@ const struct of_device_id of_default_bus_match_table[] = { { .compatible = "simple-bus", }, { .compatible = "simple-mfd", }, + { .compatible = "isa", }, #ifdef CONFIG_ARM_AMBA { .compatible = "arm,amba-bus", }, #endif /* CONFIG_ARM_AMBA */ -- cgit v0.10.2 From eea1645bb8645cdf40b788dc6f2cbe2309e82411 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Mon, 19 Sep 2016 22:21:25 +0100 Subject: MIPS: Malta: Remove custom DT match table Since commit 44a7185c2ae6 ("of/platform: Add common method to populate default bus") the Malta publish_devices initcall has essentially been a no-op. Remove it. Signed-off-by: Paul Burton Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14276/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/mti-malta/malta-dt.c b/arch/mips/mti-malta/malta-dt.c index 47a2288..4822943 100644 --- a/arch/mips/mti-malta/malta-dt.c +++ b/arch/mips/mti-malta/malta-dt.c @@ -17,18 +17,3 @@ void __init device_tree_init(void) { unflatten_and_copy_device_tree(); } - -static const struct of_device_id bus_ids[] __initconst = { - { .compatible = "simple-bus", }, - { .compatible = "isa", }, - {}, -}; - -static int __init publish_devices(void) -{ - if (!of_have_populated_dt()) - return 0; - - return of_platform_bus_probe(NULL, bus_ids, NULL); -} -device_initcall(publish_devices); -- cgit v0.10.2 From 0a46ffa3604ec64b6a6784f134267c49ec224b75 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Mon, 19 Sep 2016 22:21:26 +0100 Subject: MIPS: Malta: Probe RTC via DT Add the DT node required to probe the RTC, and remove the platform code that was previously doing it. Signed-off-by: Paul Burton Cc: Rob Herring Cc: Mark Rutland Cc: linux-mips@linux-mips.org Cc: devicetree@vger.kernel.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14277/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/boot/dts/mti/malta.dts b/arch/mips/boot/dts/mti/malta.dts index af765af..fecbca8 100644 --- a/arch/mips/boot/dts/mti/malta.dts +++ b/arch/mips/boot/dts/mti/malta.dts @@ -49,4 +49,19 @@ interrupt-parent = <&gic>; interrupts = ; }; + + isa { + compatible = "isa"; + #address-cells = <2>; + #size-cells = <1>; + ranges = <1 0 0 0x1000>; + + rtc@70 { + compatible = "motorola,mc146818"; + reg = <1 0x70 0x8>; + + interrupt-parent = <&i8259>; + interrupts = <8>; + }; + }; }; diff --git a/arch/mips/mti-malta/malta-platform.c b/arch/mips/mti-malta/malta-platform.c index 20a53e7..4e003b9 100644 --- a/arch/mips/mti-malta/malta-platform.c +++ b/arch/mips/mti-malta/malta-platform.c @@ -23,7 +23,6 @@ */ #include #include -#include #include #include #include @@ -68,25 +67,6 @@ static struct platform_device malta_uart8250_device = { }, }; -struct resource malta_rtc_resources[] = { - { - .start = RTC_PORT(0), - .end = RTC_PORT(7), - .flags = IORESOURCE_IO, - }, { - .start = RTC_IRQ, - .end = RTC_IRQ, - .flags = IORESOURCE_IRQ, - } -}; - -static struct platform_device malta_rtc_device = { - .name = "rtc_cmos", - .id = -1, - .resource = malta_rtc_resources, - .num_resources = ARRAY_SIZE(malta_rtc_resources), -}; - static struct mtd_partition malta_mtd_partitions[] = { { .name = "YAMON", @@ -129,7 +109,6 @@ static struct platform_device malta_flash_device = { static struct platform_device *malta_devices[] __initdata = { &malta_uart8250_device, - &malta_rtc_device, &malta_flash_device, }; -- cgit v0.10.2 From 97af8e1cb31870c6f4ca175d5eada7be5cc65e0f Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Mon, 19 Sep 2016 22:21:27 +0100 Subject: MIPS: Malta: Probe pflash via DT Add the DT nodes required to probe the CFI compatible parallel monitor flash found on the Malta development board, and remove the platform code that was previously doing it. Delete the now-empty malta-platform.c file. Adjust the Malta defconfigs that enable MTD & the pflash/CFI driver to enable CONFIG_MTD_PHYSMAP_OF rather than CONFIG_MTD_PHYSMAP in order to preserve their behaviour. Signed-off-by: Paul Burton Cc: Bartlomiej Zolnierkiewicz Cc: Rob Herring Cc: Mark Rutland Cc: linux-mips@linux-mips.org Cc: devicetree@vger.kernel.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14278/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/boot/dts/mti/malta.dts b/arch/mips/boot/dts/mti/malta.dts index fecbca8..48783b1 100644 --- a/arch/mips/boot/dts/mti/malta.dts +++ b/arch/mips/boot/dts/mti/malta.dts @@ -50,6 +50,37 @@ interrupts = ; }; + flash@1e000000 { + compatible = "intel,dt28f160", "cfi-flash"; + reg = <0x1e000000 0x400000>; + bank-width = <4>; + #address-cells = <1>; + #size-cells = <1>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + yamon@0 { + label = "YAMON"; + reg = <0x0 0x100000>; + read-only; + }; + + user-fs@100000 { + label = "User FS"; + reg = <0x100000 0x2e0000>; + }; + + board-config@3e0000 { + label = "Board Config"; + reg = <0x3e0000 0x20000>; + read-only; + }; + }; + }; + isa { compatible = "isa"; #address-cells = <2>; diff --git a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig index 5afb484..d5d4816 100644 --- a/arch/mips/configs/malta_defconfig +++ b/arch/mips/configs/malta_defconfig @@ -230,7 +230,7 @@ CONFIG_MTD_CFI=y CONFIG_MTD_CFI_INTELEXT=y CONFIG_MTD_CFI_AMDSTD=y CONFIG_MTD_CFI_STAA=y -CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_OF=y CONFIG_MTD_UBI=m CONFIG_MTD_UBI_GLUEBI=m CONFIG_BLK_DEV_FD=m diff --git a/arch/mips/configs/malta_kvm_defconfig b/arch/mips/configs/malta_kvm_defconfig index 98f1387..ef6ef24 100644 --- a/arch/mips/configs/malta_kvm_defconfig +++ b/arch/mips/configs/malta_kvm_defconfig @@ -235,7 +235,7 @@ CONFIG_MTD_CFI=y CONFIG_MTD_CFI_INTELEXT=y CONFIG_MTD_CFI_AMDSTD=y CONFIG_MTD_CFI_STAA=y -CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_OF=y CONFIG_MTD_UBI=m CONFIG_MTD_UBI_GLUEBI=m CONFIG_BLK_DEV_FD=m diff --git a/arch/mips/configs/malta_kvm_guest_defconfig b/arch/mips/configs/malta_kvm_guest_defconfig index 3b5d591..3a49a77 100644 --- a/arch/mips/configs/malta_kvm_guest_defconfig +++ b/arch/mips/configs/malta_kvm_guest_defconfig @@ -234,7 +234,7 @@ CONFIG_MTD_CFI=y CONFIG_MTD_CFI_INTELEXT=y CONFIG_MTD_CFI_AMDSTD=y CONFIG_MTD_CFI_STAA=y -CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_OF=y CONFIG_MTD_UBI=m CONFIG_MTD_UBI_GLUEBI=m CONFIG_BLK_DEV_FD=m diff --git a/arch/mips/configs/maltaup_xpa_defconfig b/arch/mips/configs/maltaup_xpa_defconfig index 7322157..62e05eb 100644 --- a/arch/mips/configs/maltaup_xpa_defconfig +++ b/arch/mips/configs/maltaup_xpa_defconfig @@ -231,7 +231,7 @@ CONFIG_MTD_CFI=y CONFIG_MTD_CFI_INTELEXT=y CONFIG_MTD_CFI_AMDSTD=y CONFIG_MTD_CFI_STAA=y -CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_OF=y CONFIG_MTD_UBI=m CONFIG_MTD_UBI_GLUEBI=m CONFIG_BLK_DEV_FD=m diff --git a/arch/mips/mti-malta/malta-platform.c b/arch/mips/mti-malta/malta-platform.c index 4e003b9..516e123 100644 --- a/arch/mips/mti-malta/malta-platform.c +++ b/arch/mips/mti-malta/malta-platform.c @@ -25,11 +25,8 @@ #include #include #include -#include -#include #include #include -#include #define SMC_PORT(base, int) \ { \ @@ -67,49 +64,8 @@ static struct platform_device malta_uart8250_device = { }, }; -static struct mtd_partition malta_mtd_partitions[] = { - { - .name = "YAMON", - .offset = 0x0, - .size = 0x100000, - .mask_flags = MTD_WRITEABLE - }, { - .name = "User FS", - .offset = 0x100000, - .size = 0x2e0000 - }, { - .name = "Board Config", - .offset = 0x3e0000, - .size = 0x020000, - .mask_flags = MTD_WRITEABLE - } -}; - -static struct physmap_flash_data malta_flash_data = { - .width = 4, - .nr_parts = ARRAY_SIZE(malta_mtd_partitions), - .parts = malta_mtd_partitions -}; - -static struct resource malta_flash_resource = { - .start = 0x1e000000, - .end = 0x1e3fffff, - .flags = IORESOURCE_MEM -}; - -static struct platform_device malta_flash_device = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &malta_flash_data, - }, - .num_resources = 1, - .resource = &malta_flash_resource, -}; - static struct platform_device *malta_devices[] __initdata = { &malta_uart8250_device, - &malta_flash_device, }; static int __init malta_add_devices(void) -- cgit v0.10.2 From 10b6ea0959de2c42b9f105c88b51a54c4dd961c2 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Mon, 19 Sep 2016 22:21:28 +0100 Subject: MIPS: Malta: Use syscon-reboot driver to reboot Make use of the generic syscon-reboot driver to reboot the Malta board, reducing the amount of platform code it requires. Signed-off-by: Paul Burton Cc: Stephan Linz Cc: Jacek Anaszewski Cc: Bartlomiej Zolnierkiewicz Cc: Rob Herring Cc: Mark Rutland Cc: linux-mips@linux-mips.org Cc: devicetree@vger.kernel.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14279/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/boot/dts/mti/malta.dts b/arch/mips/boot/dts/mti/malta.dts index 48783b1..f604a27 100644 --- a/arch/mips/boot/dts/mti/malta.dts +++ b/arch/mips/boot/dts/mti/malta.dts @@ -81,6 +81,18 @@ }; }; + fpga_regs: system-controller@1f000000 { + compatible = "mti,malta-fpga", "syscon", "simple-mfd"; + reg = <0x1f000000 0x1000>; + + reboot { + compatible = "syscon-reboot"; + regmap = <&fpga_regs>; + offset = <0x500>; + mask = <0x4d>; + }; + }; + isa { compatible = "isa"; #address-cells = <2>; diff --git a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig index d5d4816..58d43f3 100644 --- a/arch/mips/configs/malta_defconfig +++ b/arch/mips/configs/malta_defconfig @@ -318,6 +318,8 @@ CONFIG_LIBERTAS=m # CONFIG_SERIO_I8042 is not set CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_SYSCON=y # CONFIG_HWMON is not set CONFIG_FB=y CONFIG_FB_CIRRUS=y diff --git a/arch/mips/configs/malta_kvm_defconfig b/arch/mips/configs/malta_kvm_defconfig index ef6ef24..c8f7e28 100644 --- a/arch/mips/configs/malta_kvm_defconfig +++ b/arch/mips/configs/malta_kvm_defconfig @@ -331,6 +331,8 @@ CONFIG_LIBERTAS=m # CONFIG_SERIO_I8042 is not set CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_SYSCON=y # CONFIG_HWMON is not set CONFIG_FB=y CONFIG_FB_CIRRUS=y diff --git a/arch/mips/configs/malta_kvm_guest_defconfig b/arch/mips/configs/malta_kvm_guest_defconfig index 3a49a77..d2f54e5 100644 --- a/arch/mips/configs/malta_kvm_guest_defconfig +++ b/arch/mips/configs/malta_kvm_guest_defconfig @@ -331,6 +331,8 @@ CONFIG_LIBERTAS=m # CONFIG_SERIO_I8042 is not set CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_SYSCON=y # CONFIG_HWMON is not set CONFIG_FB=y CONFIG_FB_CIRRUS=y diff --git a/arch/mips/configs/malta_qemu_32r6_defconfig b/arch/mips/configs/malta_qemu_32r6_defconfig index 65f140e..cbf37dd 100644 --- a/arch/mips/configs/malta_qemu_32r6_defconfig +++ b/arch/mips/configs/malta_qemu_32r6_defconfig @@ -132,6 +132,8 @@ CONFIG_LEGACY_PTY_COUNT=4 CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_HW_RANDOM=y +CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_SYSCON=y # CONFIG_HWMON is not set CONFIG_FB=y CONFIG_FIRMWARE_EDID=y diff --git a/arch/mips/configs/maltaaprp_defconfig b/arch/mips/configs/maltaaprp_defconfig index 799c433..35f6ba2 100644 --- a/arch/mips/configs/maltaaprp_defconfig +++ b/arch/mips/configs/maltaaprp_defconfig @@ -132,6 +132,8 @@ CONFIG_LEGACY_PTY_COUNT=16 CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_HW_RANDOM=y +CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_SYSCON=y # CONFIG_HWMON is not set CONFIG_VIDEO_OUTPUT_CONTROL=m CONFIG_FB=y diff --git a/arch/mips/configs/maltasmvp_defconfig b/arch/mips/configs/maltasmvp_defconfig index ac0eb4d..900f145 100644 --- a/arch/mips/configs/maltasmvp_defconfig +++ b/arch/mips/configs/maltasmvp_defconfig @@ -134,6 +134,8 @@ CONFIG_LEGACY_PTY_COUNT=4 CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_HW_RANDOM=y +CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_SYSCON=y # CONFIG_HWMON is not set CONFIG_FB=y CONFIG_FIRMWARE_EDID=y diff --git a/arch/mips/configs/maltasmvp_eva_defconfig b/arch/mips/configs/maltasmvp_eva_defconfig index 3184600..8e2738b 100644 --- a/arch/mips/configs/maltasmvp_eva_defconfig +++ b/arch/mips/configs/maltasmvp_eva_defconfig @@ -137,6 +137,8 @@ CONFIG_LEGACY_PTY_COUNT=4 CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_HW_RANDOM=y +CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_SYSCON=y # CONFIG_HWMON is not set CONFIG_VIDEO_OUTPUT_CONTROL=m CONFIG_FB=y diff --git a/arch/mips/configs/maltaup_defconfig b/arch/mips/configs/maltaup_defconfig index a79107d..6dc4e30 100644 --- a/arch/mips/configs/maltaup_defconfig +++ b/arch/mips/configs/maltaup_defconfig @@ -131,6 +131,8 @@ CONFIG_LEGACY_PTY_COUNT=16 CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_HW_RANDOM=y +CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_SYSCON=y # CONFIG_HWMON is not set CONFIG_VIDEO_OUTPUT_CONTROL=m CONFIG_FB=y diff --git a/arch/mips/configs/maltaup_xpa_defconfig b/arch/mips/configs/maltaup_xpa_defconfig index 62e05eb..3d0d9cb 100644 --- a/arch/mips/configs/maltaup_xpa_defconfig +++ b/arch/mips/configs/maltaup_xpa_defconfig @@ -326,6 +326,8 @@ CONFIG_LIBERTAS=m # CONFIG_SERIO_I8042 is not set CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_SYSCON=y # CONFIG_HWMON is not set CONFIG_FB=y CONFIG_FB_CIRRUS=y diff --git a/arch/mips/mti-malta/malta-reset.c b/arch/mips/mti-malta/malta-reset.c index 2fd2cc2..04d6b9c 100644 --- a/arch/mips/mti-malta/malta-reset.c +++ b/arch/mips/mti-malta/malta-reset.c @@ -8,21 +8,11 @@ */ #include #include +#include #include #include -#define SOFTRES_REG 0x1f000500 -#define GORESET 0x42 - -static void mips_machine_restart(char *command) -{ - unsigned int __iomem *softres_reg = - ioremap(SOFTRES_REG, sizeof(unsigned int)); - - __raw_writel(GORESET, softres_reg); -} - static void mips_machine_halt(void) { while (true); @@ -33,12 +23,11 @@ static void mips_machine_power_off(void) mips_pm_suspend(PIIX4_FUNC3IO_PMCNTRL_SUS_TYP_SOFF); pr_info("Failed to power down, resetting\n"); - mips_machine_restart(NULL); + machine_restart(NULL); } static int __init mips_reboot_setup(void) { - _machine_restart = mips_machine_restart; _machine_halt = mips_machine_halt; pm_power_off = mips_machine_power_off; -- cgit v0.10.2 From c834469b88cd0a54b313012e9f023937c68a5704 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Mon, 19 Sep 2016 22:21:29 +0100 Subject: MIPS: Malta: Remove custom halt implementation The arch code will hang the machine with an infinite loop if the board doesn't provide an impelementation of halt - let it, rather than duplicating it. Signed-off-by: Paul Burton Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14280/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/mti-malta/malta-reset.c b/arch/mips/mti-malta/malta-reset.c index 04d6b9c..dd6f62a 100644 --- a/arch/mips/mti-malta/malta-reset.c +++ b/arch/mips/mti-malta/malta-reset.c @@ -13,11 +13,6 @@ #include #include -static void mips_machine_halt(void) -{ - while (true); -} - static void mips_machine_power_off(void) { mips_pm_suspend(PIIX4_FUNC3IO_PMCNTRL_SUS_TYP_SOFF); @@ -28,7 +23,6 @@ static void mips_machine_power_off(void) static int __init mips_reboot_setup(void) { - _machine_halt = mips_machine_halt; pm_power_off = mips_machine_power_off; return 0; -- cgit v0.10.2 From 7bbe59ddbb9fae90eef0248416976d4e5f6b1a2d Mon Sep 17 00:00:00 2001 From: Jaedon Shin Date: Fri, 19 Aug 2016 11:52:26 +0900 Subject: MIPS: BMIPS: Add support PWM device nodes Adds PWM device nodes to BCM7xxx MIPS based SoCs. Signed-off-by: Jaedon Shin Reviewed-by: Florian Fainelli Cc: Jonas Gorski Cc: Kevin Cernekee Cc: Rob Herring Cc: MIPS Mailing List Cc: devicetree@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14000/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/boot/dts/brcm/bcm7125.dtsi b/arch/mips/boot/dts/brcm/bcm7125.dtsi index 550e1d9..97191f6 100644 --- a/arch/mips/boot/dts/brcm/bcm7125.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7125.dtsi @@ -40,6 +40,12 @@ #clock-cells = <0>; clock-frequency = <81000000>; }; + + upg_clk: upg_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <27000000>; + }; }; rdb { @@ -183,6 +189,14 @@ status = "disabled"; }; + pwma: pwm@406580 { + compatible = "brcm,bcm7038-pwm"; + reg = <0x406580 0x28>; + #pwm-cells = <2>; + clocks = <&upg_clk>; + status = "disabled"; + }; + ehci0: usb@488300 { compatible = "brcm,bcm7125-ehci", "generic-ehci"; reg = <0x488300 0x100>; diff --git a/arch/mips/boot/dts/brcm/bcm7346.dtsi b/arch/mips/boot/dts/brcm/bcm7346.dtsi index ec95906..eb7b19a 100644 --- a/arch/mips/boot/dts/brcm/bcm7346.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7346.dtsi @@ -40,6 +40,12 @@ #clock-cells = <0>; clock-frequency = <81000000>; }; + + upg_clk: upg_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <27000000>; + }; }; rdb { @@ -210,6 +216,22 @@ status = "disabled"; }; + pwma: pwm@406580 { + compatible = "brcm,bcm7038-pwm"; + reg = <0x406580 0x28>; + #pwm-cells = <2>; + clocks = <&upg_clk>; + status = "disabled"; + }; + + pwmb: pwm@406800 { + compatible = "brcm,bcm7038-pwm"; + reg = <0x406800 0x28>; + #pwm-cells = <2>; + clocks = <&upg_clk>; + status = "disabled"; + }; + enet0: ethernet@430000 { phy-mode = "internal"; phy-handle = <&phy1>; diff --git a/arch/mips/boot/dts/brcm/bcm7358.dtsi b/arch/mips/boot/dts/brcm/bcm7358.dtsi index ca57fb5..b2276b1 100644 --- a/arch/mips/boot/dts/brcm/bcm7358.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7358.dtsi @@ -34,6 +34,12 @@ #clock-cells = <0>; clock-frequency = <81000000>; }; + + upg_clk: upg_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <27000000>; + }; }; rdb { @@ -194,6 +200,22 @@ status = "disabled"; }; + pwma: pwm@406400 { + compatible = "brcm,bcm7038-pwm"; + reg = <0x406400 0x28>; + #pwm-cells = <2>; + clocks = <&upg_clk>; + status = "disabled"; + }; + + pwmb: pwm@406700 { + compatible = "brcm,bcm7038-pwm"; + reg = <0x406700 0x28>; + #pwm-cells = <2>; + clocks = <&upg_clk>; + status = "disabled"; + }; + enet0: ethernet@430000 { phy-mode = "internal"; phy-handle = <&phy1>; diff --git a/arch/mips/boot/dts/brcm/bcm7360.dtsi b/arch/mips/boot/dts/brcm/bcm7360.dtsi index 1c0c3d4..e414af1 100644 --- a/arch/mips/boot/dts/brcm/bcm7360.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7360.dtsi @@ -34,6 +34,12 @@ #clock-cells = <0>; clock-frequency = <81000000>; }; + + upg_clk: upg_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <27000000>; + }; }; rdb { @@ -194,6 +200,14 @@ status = "disabled"; }; + pwma: pwm@406400 { + compatible = "brcm,bcm7038-pwm"; + reg = <0x406400 0x28>; + #pwm-cells = <2>; + clocks = <&upg_clk>; + status = "disabled"; + }; + enet0: ethernet@430000 { phy-mode = "internal"; phy-handle = <&phy1>; diff --git a/arch/mips/boot/dts/brcm/bcm7362.dtsi b/arch/mips/boot/dts/brcm/bcm7362.dtsi index 6b4713a..3bd1c01 100644 --- a/arch/mips/boot/dts/brcm/bcm7362.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7362.dtsi @@ -40,6 +40,12 @@ #clock-cells = <0>; clock-frequency = <81000000>; }; + + upg_clk: upg_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <27000000>; + }; }; rdb { @@ -190,6 +196,14 @@ status = "disabled"; }; + pwma: pwm@406400 { + compatible = "brcm,bcm7038-pwm"; + reg = <0x406400 0x28>; + #pwm-cells = <2>; + clocks = <&upg_clk>; + status = "disabled"; + }; + enet0: ethernet@430000 { phy-mode = "internal"; phy-handle = <&phy1>; diff --git a/arch/mips/boot/dts/brcm/bcm7420.dtsi b/arch/mips/boot/dts/brcm/bcm7420.dtsi index 0586bf6..27c3d45 100644 --- a/arch/mips/boot/dts/brcm/bcm7420.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7420.dtsi @@ -40,6 +40,12 @@ #clock-cells = <0>; clock-frequency = <81000000>; }; + + upg_clk: upg_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <27000000>; + }; }; rdb { @@ -191,6 +197,22 @@ status = "disabled"; }; + pwma: pwm@406580 { + compatible = "brcm,bcm7038-pwm"; + reg = <0x406580 0x28>; + #pwm-cells = <2>; + clocks = <&upg_clk>; + status = "disabled"; + }; + + pwmb: pwm@406880 { + compatible = "brcm,bcm7038-pwm"; + reg = <0x406880 0x28>; + #pwm-cells = <2>; + clocks = <&upg_clk>; + status = "disabled"; + }; + enet0: ethernet@468000 { phy-mode = "internal"; phy-handle = <&phy1>; diff --git a/arch/mips/boot/dts/brcm/bcm7425.dtsi b/arch/mips/boot/dts/brcm/bcm7425.dtsi index c1c15ed..9ab65d64 100644 --- a/arch/mips/boot/dts/brcm/bcm7425.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7425.dtsi @@ -40,6 +40,12 @@ #clock-cells = <0>; clock-frequency = <81000000>; }; + + upg_clk: upg_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <27000000>; + }; }; rdb { @@ -209,6 +215,22 @@ status = "disabled"; }; + pwma: pwm@406580 { + compatible = "brcm,bcm7038-pwm"; + reg = <0x406580 0x28>; + #pwm-cells = <2>; + clocks = <&upg_clk>; + status = "disabled"; + }; + + pwmb: pwm@406800 { + compatible = "brcm,bcm7038-pwm"; + reg = <0x406800 0x28>; + #pwm-cells = <2>; + clocks = <&upg_clk>; + status = "disabled"; + }; + enet0: ethernet@b80000 { phy-mode = "internal"; phy-handle = <&phy1>; diff --git a/arch/mips/boot/dts/brcm/bcm7435.dtsi b/arch/mips/boot/dts/brcm/bcm7435.dtsi index a874d3a..7801169 100644 --- a/arch/mips/boot/dts/brcm/bcm7435.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7435.dtsi @@ -52,6 +52,12 @@ #clock-cells = <0>; clock-frequency = <81000000>; }; + + upg_clk: upg_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <27000000>; + }; }; rdb { @@ -224,6 +230,22 @@ status = "disabled"; }; + pwma: pwm@406580 { + compatible = "brcm,bcm7038-pwm"; + reg = <0x406580 0x28>; + #pwm-cells = <2>; + clocks = <&upg_clk>; + status = "disabled"; + }; + + pwmb: pwm@406800 { + compatible = "brcm,bcm7038-pwm"; + reg = <0x406800 0x28>; + #pwm-cells = <2>; + clocks = <&upg_clk>; + status = "disabled"; + }; + enet0: ethernet@b80000 { phy-mode = "internal"; phy-handle = <&phy1>; diff --git a/arch/mips/boot/dts/brcm/bcm97125cbmb.dts b/arch/mips/boot/dts/brcm/bcm97125cbmb.dts index f2449d1..5c24eac 100644 --- a/arch/mips/boot/dts/brcm/bcm97125cbmb.dts +++ b/arch/mips/boot/dts/brcm/bcm97125cbmb.dts @@ -45,6 +45,10 @@ status = "okay"; }; +&pwma { + status = "okay"; +}; + /* FIXME: USB is wonky; disable it for now */ &ehci0 { status = "disabled"; diff --git a/arch/mips/boot/dts/brcm/bcm97346dbsmb.dts b/arch/mips/boot/dts/brcm/bcm97346dbsmb.dts index d3d2881..2c55ab0 100644 --- a/arch/mips/boot/dts/brcm/bcm97346dbsmb.dts +++ b/arch/mips/boot/dts/brcm/bcm97346dbsmb.dts @@ -49,6 +49,14 @@ status = "okay"; }; +&pwma { + status = "okay"; +}; + +&pwmb { + status = "okay"; +}; + &enet0 { status = "okay"; }; diff --git a/arch/mips/boot/dts/brcm/bcm97358svmb.dts b/arch/mips/boot/dts/brcm/bcm97358svmb.dts index 02ce6b4..757fe9d 100644 --- a/arch/mips/boot/dts/brcm/bcm97358svmb.dts +++ b/arch/mips/boot/dts/brcm/bcm97358svmb.dts @@ -45,6 +45,14 @@ status = "okay"; }; +&pwma { + status = "okay"; +}; + +&pwmb { + status = "okay"; +}; + &enet0 { status = "okay"; }; diff --git a/arch/mips/boot/dts/brcm/bcm97360svmb.dts b/arch/mips/boot/dts/brcm/bcm97360svmb.dts index 73124be..496e6ed 100644 --- a/arch/mips/boot/dts/brcm/bcm97360svmb.dts +++ b/arch/mips/boot/dts/brcm/bcm97360svmb.dts @@ -45,6 +45,10 @@ status = "okay"; }; +&pwma { + status = "okay"; +}; + &enet0 { status = "okay"; }; diff --git a/arch/mips/boot/dts/brcm/bcm97362svmb.dts b/arch/mips/boot/dts/brcm/bcm97362svmb.dts index 3cfcaeb..b880c01 100644 --- a/arch/mips/boot/dts/brcm/bcm97362svmb.dts +++ b/arch/mips/boot/dts/brcm/bcm97362svmb.dts @@ -41,6 +41,10 @@ status = "okay"; }; +&pwma { + status = "okay"; +}; + &enet0 { status = "okay"; }; diff --git a/arch/mips/boot/dts/brcm/bcm97420c.dts b/arch/mips/boot/dts/brcm/bcm97420c.dts index 600d57a..e66271a 100644 --- a/arch/mips/boot/dts/brcm/bcm97420c.dts +++ b/arch/mips/boot/dts/brcm/bcm97420c.dts @@ -51,6 +51,14 @@ status = "okay"; }; +&pwma { + status = "okay"; +}; + +&pwmb { + status = "okay"; +}; + /* FIXME: MAC driver comes up but cannot attach to PHY */ &enet0 { status = "disabled"; diff --git a/arch/mips/boot/dts/brcm/bcm97425svmb.dts b/arch/mips/boot/dts/brcm/bcm97425svmb.dts index 119c714..f091e91 100644 --- a/arch/mips/boot/dts/brcm/bcm97425svmb.dts +++ b/arch/mips/boot/dts/brcm/bcm97425svmb.dts @@ -51,6 +51,14 @@ status = "okay"; }; +&pwma { + status = "okay"; +}; + +&pwmb { + status = "okay"; +}; + &enet0 { status = "okay"; }; diff --git a/arch/mips/boot/dts/brcm/bcm97435svmb.dts b/arch/mips/boot/dts/brcm/bcm97435svmb.dts index 43e3ba2..9db84f2 100644 --- a/arch/mips/boot/dts/brcm/bcm97435svmb.dts +++ b/arch/mips/boot/dts/brcm/bcm97435svmb.dts @@ -51,6 +51,14 @@ status = "okay"; }; +&pwma { + status = "okay"; +}; + +&pwmb { + status = "okay"; +}; + &enet0 { status = "okay"; }; -- cgit v0.10.2 From c707844d4b876f74f2adf036f98f6787d76d2905 Mon Sep 17 00:00:00 2001 From: Jaedon Shin Date: Fri, 19 Aug 2016 11:52:27 +0900 Subject: MIPS: BMIPS: Add support GPIO device nodes Adds GPIO device nodes to BCM7xxx MIPS based SoCs. Signed-off-by: Jaedon Shin Cc: Florian Fainelli Cc: Jonas Gorski Cc: Kevin Cernekee Cc: Rob Herring Cc: MIPS Mailing List Cc: devicetree@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14001/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/boot/dts/brcm/bcm7125.dtsi b/arch/mips/boot/dts/brcm/bcm7125.dtsi index 97191f6..746ed06 100644 --- a/arch/mips/boot/dts/brcm/bcm7125.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7125.dtsi @@ -197,6 +197,18 @@ status = "disabled"; }; + upg_gio: gpio@406700 { + compatible = "brcm,brcmstb-gpio"; + reg = <0x406700 0x80>; + #gpio-cells = <2>; + #interrupt-cells = <2>; + gpio-controller; + interrupt-controller; + interrupt-parent = <&upg_irq0_intc>; + interrupts = <6>; + brcm,gpio-bank-widths = <32 32 32 18>; + }; + ehci0: usb@488300 { compatible = "brcm,bcm7125-ehci", "generic-ehci"; reg = <0x488300 0x100>; diff --git a/arch/mips/boot/dts/brcm/bcm7346.dtsi b/arch/mips/boot/dts/brcm/bcm7346.dtsi index eb7b19a..0105e4e 100644 --- a/arch/mips/boot/dts/brcm/bcm7346.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7346.dtsi @@ -232,6 +232,43 @@ status = "disabled"; }; + aon_pm_l2_intc: interrupt-controller@408440 { + compatible = "brcm,l2-intc"; + reg = <0x408440 0x30>; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&periph_intc>; + interrupts = <53>; + brcm,irq-can-wake; + }; + + upg_gio: gpio@406700 { + compatible = "brcm,brcmstb-gpio"; + reg = <0x406700 0x60>; + #gpio-cells = <2>; + #interrupt-cells = <2>; + gpio-controller; + interrupt-controller; + interrupt-parent = <&upg_irq0_intc>; + interrupts = <6>; + brcm,gpio-bank-widths = <32 32 16>; + }; + + upg_gio_aon: gpio@408c00 { + compatible = "brcm,brcmstb-gpio"; + reg = <0x408c00 0x60>; + #gpio-cells = <2>; + #interrupt-cells = <2>; + gpio-controller; + interrupt-controller; + interrupt-parent = <&upg_aon_irq0_intc>; + interrupts = <6>; + interrupts-extended = <&upg_aon_irq0_intc 6>, + <&aon_pm_l2_intc 5>; + wakeup-source; + brcm,gpio-bank-widths = <27 32 2>; + }; + enet0: ethernet@430000 { phy-mode = "internal"; phy-handle = <&phy1>; diff --git a/arch/mips/boot/dts/brcm/bcm7358.dtsi b/arch/mips/boot/dts/brcm/bcm7358.dtsi index b2276b1..aec1b2e 100644 --- a/arch/mips/boot/dts/brcm/bcm7358.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7358.dtsi @@ -216,6 +216,43 @@ status = "disabled"; }; + aon_pm_l2_intc: interrupt-controller@408240 { + compatible = "brcm,l2-intc"; + reg = <0x408240 0x30>; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&periph_intc>; + interrupts = <50>; + brcm,irq-can-wake; + }; + + upg_gio: gpio@406500 { + compatible = "brcm,brcmstb-gpio"; + reg = <0x406500 0xa0>; + #gpio-cells = <2>; + #interrupt-cells = <2>; + gpio-controller; + interrupt-controller; + interrupt-parent = <&upg_irq0_intc>; + interrupts = <6>; + brcm,gpio-bank-widths = <32 32 32 29 4>; + }; + + upg_gio_aon: gpio@408c00 { + compatible = "brcm,brcmstb-gpio"; + reg = <0x408c00 0x60>; + #gpio-cells = <2>; + #interrupt-cells = <2>; + gpio-controller; + interrupt-controller; + interrupt-parent = <&upg_aon_irq0_intc>; + interrupts = <6>; + interrupts-extended = <&upg_aon_irq0_intc 6>, + <&aon_pm_l2_intc 5>; + wakeup-source; + brcm,gpio-bank-widths = <21 32 2>; + }; + enet0: ethernet@430000 { phy-mode = "internal"; phy-handle = <&phy1>; diff --git a/arch/mips/boot/dts/brcm/bcm7360.dtsi b/arch/mips/boot/dts/brcm/bcm7360.dtsi index e414af1..f0f63cb 100644 --- a/arch/mips/boot/dts/brcm/bcm7360.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7360.dtsi @@ -208,6 +208,43 @@ status = "disabled"; }; + aon_pm_l2_intc: interrupt-controller@408440 { + compatible = "brcm,l2-intc"; + reg = <0x408440 0x30>; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&periph_intc>; + interrupts = <50>; + brcm,irq-can-wake; + }; + + upg_gio: gpio@406500 { + compatible = "brcm,brcmstb-gpio"; + reg = <0x406500 0xa0>; + #gpio-cells = <2>; + #interrupt-cells = <2>; + gpio-controller; + interrupt-controller; + interrupt-parent = <&upg_irq0_intc>; + interrupts = <6>; + brcm,gpio-bank-widths = <32 32 32 29 4>; + }; + + upg_gio_aon: gpio@408c00 { + compatible = "brcm,brcmstb-gpio"; + reg = <0x408c00 0x60>; + #gpio-cells = <2>; + #interrupt-cells = <2>; + gpio-controller; + interrupt-controller; + interrupt-parent = <&upg_aon_irq0_intc>; + interrupts = <6>; + interrupts-extended = <&upg_aon_irq0_intc 6>, + <&aon_pm_l2_intc 5>; + wakeup-source; + brcm,gpio-bank-widths = <21 32 2>; + }; + enet0: ethernet@430000 { phy-mode = "internal"; phy-handle = <&phy1>; diff --git a/arch/mips/boot/dts/brcm/bcm7362.dtsi b/arch/mips/boot/dts/brcm/bcm7362.dtsi index 3bd1c01..ac42b98 100644 --- a/arch/mips/boot/dts/brcm/bcm7362.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7362.dtsi @@ -204,6 +204,43 @@ status = "disabled"; }; + aon_pm_l2_intc: interrupt-controller@408440 { + compatible = "brcm,l2-intc"; + reg = <0x408440 0x30>; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&periph_intc>; + interrupts = <50>; + brcm,irq-can-wake; + }; + + upg_gio: gpio@406500 { + compatible = "brcm,brcmstb-gpio"; + reg = <0x406500 0xa0>; + #gpio-cells = <2>; + #interrupt-cells = <2>; + gpio-controller; + interrupt-controller; + interrupt-parent = <&upg_irq0_intc>; + interrupts = <6>; + brcm,gpio-bank-widths = <32 32 32 29 4>; + }; + + upg_gio_aon: gpio@408c00 { + compatible = "brcm,brcmstb-gpio"; + reg = <0x408c00 0x60>; + #gpio-cells = <2>; + #interrupt-cells = <2>; + gpio-controller; + interrupt-controller; + interrupt-parent = <&upg_aon_irq0_intc>; + interrupts = <6>; + interrupts-extended = <&upg_aon_irq0_intc 6>, + <&aon_pm_l2_intc 5>; + wakeup-source; + brcm,gpio-bank-widths = <21 32 2>; + }; + enet0: ethernet@430000 { phy-mode = "internal"; phy-handle = <&phy1>; diff --git a/arch/mips/boot/dts/brcm/bcm7420.dtsi b/arch/mips/boot/dts/brcm/bcm7420.dtsi index 27c3d45..0d391d7 100644 --- a/arch/mips/boot/dts/brcm/bcm7420.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7420.dtsi @@ -213,6 +213,18 @@ status = "disabled"; }; + upg_gio: gpio@406700 { + compatible = "brcm,brcmstb-gpio"; + reg = <0x406700 0x80>; + #gpio-cells = <2>; + #interrupt-cells = <2>; + gpio-controller; + interrupt-controller; + interrupt-parent = <&upg_irq0_intc>; + interrupts = <6>; + brcm,gpio-bank-widths = <32 32 32 27>; + }; + enet0: ethernet@468000 { phy-mode = "internal"; phy-handle = <&phy1>; diff --git a/arch/mips/boot/dts/brcm/bcm7425.dtsi b/arch/mips/boot/dts/brcm/bcm7425.dtsi index 9ab65d64..8b05b98f 100644 --- a/arch/mips/boot/dts/brcm/bcm7425.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7425.dtsi @@ -231,6 +231,43 @@ status = "disabled"; }; + aon_pm_l2_intc: interrupt-controller@408440 { + compatible = "brcm,l2-intc"; + reg = <0x408440 0x30>; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&periph_intc>; + interrupts = <49>; + brcm,irq-can-wake; + }; + + upg_gio: gpio@406700 { + compatible = "brcm,brcmstb-gpio"; + reg = <0x406700 0x80>; + #gpio-cells = <2>; + #interrupt-cells = <2>; + gpio-controller; + interrupt-controller; + interrupt-parent = <&upg_irq0_intc>; + interrupts = <6>; + brcm,gpio-bank-widths = <32 32 32 21>; + }; + + upg_gio_aon: gpio@4094c0 { + compatible = "brcm,brcmstb-gpio"; + reg = <0x4094c0 0x40>; + #gpio-cells = <2>; + #interrupt-cells = <2>; + gpio-controller; + interrupt-controller; + interrupt-parent = <&upg_aon_irq0_intc>; + interrupts = <6>; + interrupts-extended = <&upg_aon_irq0_intc 6>, + <&aon_pm_l2_intc 5>; + wakeup-source; + brcm,gpio-bank-widths = <18 4>; + }; + enet0: ethernet@b80000 { phy-mode = "internal"; phy-handle = <&phy1>; diff --git a/arch/mips/boot/dts/brcm/bcm7435.dtsi b/arch/mips/boot/dts/brcm/bcm7435.dtsi index 7801169..b7bb102 100644 --- a/arch/mips/boot/dts/brcm/bcm7435.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7435.dtsi @@ -246,6 +246,43 @@ status = "disabled"; }; + aon_pm_l2_intc: interrupt-controller@408440 { + compatible = "brcm,l2-intc"; + reg = <0x408440 0x30>; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&periph_intc>; + interrupts = <54>; + brcm,irq-can-wake; + }; + + upg_gio: gpio@406700 { + compatible = "brcm,brcmstb-gpio"; + reg = <0x406700 0x80>; + #gpio-cells = <2>; + #interrupt-cells = <2>; + gpio-controller; + interrupt-controller; + interrupt-parent = <&upg_irq0_intc>; + interrupts = <6>; + brcm,gpio-bank-widths = <32 32 32 21>; + }; + + upg_gio_aon: gpio@4094c0 { + compatible = "brcm,brcmstb-gpio"; + reg = <0x4094c0 0x40>; + #gpio-cells = <2>; + #interrupt-cells = <2>; + gpio-controller; + interrupt-controller; + interrupt-parent = <&upg_aon_irq0_intc>; + interrupts = <6>; + interrupts-extended = <&upg_aon_irq0_intc 6>, + <&aon_pm_l2_intc 5>; + wakeup-source; + brcm,gpio-bank-widths = <18 4>; + }; + enet0: ethernet@b80000 { phy-mode = "internal"; phy-handle = <&phy1>; -- cgit v0.10.2 From b2420e2762e36ec3aab0c0b6b9ee277f7b1b48e2 Mon Sep 17 00:00:00 2001 From: Jaedon Shin Date: Fri, 19 Aug 2016 11:52:28 +0900 Subject: MIPS: BMIPS: Add support SDHCI device nodes Adds SDHCI device nodes to BCM7xxx MIPS based SoCs. Signed-off-by: Jaedon Shin Reviewed-by: Florian Fainelli Cc: Jonas Gorski Cc: Kevin Cernekee Cc: Rob Herring Cc: MIPS Mailing List Cc: devicetree@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14002/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/boot/dts/brcm/bcm7346.dtsi b/arch/mips/boot/dts/brcm/bcm7346.dtsi index 0105e4e..0da4f8a 100644 --- a/arch/mips/boot/dts/brcm/bcm7346.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7346.dtsi @@ -411,5 +411,13 @@ #phy-cells = <0>; }; }; + + sdhci0: sdhci@413500 { + compatible = "brcm,bcm7425-sdhci"; + reg = <0x413500 0x100>; + interrupt-parent = <&periph_intc>; + interrupts = <85>; + status = "disabled"; + }; }; }; diff --git a/arch/mips/boot/dts/brcm/bcm7360.dtsi b/arch/mips/boot/dts/brcm/bcm7360.dtsi index f0f63cb..9f72d34 100644 --- a/arch/mips/boot/dts/brcm/bcm7360.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7360.dtsi @@ -330,5 +330,13 @@ #phy-cells = <0>; }; }; + + sdhci0: sdhci@410000 { + compatible = "brcm,bcm7425-sdhci"; + reg = <0x410000 0x100>; + interrupt-parent = <&periph_intc>; + interrupts = <82>; + status = "disabled"; + }; }; }; diff --git a/arch/mips/boot/dts/brcm/bcm7362.dtsi b/arch/mips/boot/dts/brcm/bcm7362.dtsi index ac42b98..ff734f4 100644 --- a/arch/mips/boot/dts/brcm/bcm7362.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7362.dtsi @@ -326,5 +326,13 @@ #phy-cells = <0>; }; }; + + sdhci0: sdhci@410000 { + compatible = "brcm,bcm7425-sdhci"; + reg = <0x410000 0x100>; + interrupt-parent = <&periph_intc>; + interrupts = <82>; + status = "disabled"; + }; }; }; diff --git a/arch/mips/boot/dts/brcm/bcm7425.dtsi b/arch/mips/boot/dts/brcm/bcm7425.dtsi index 8b05b98f..1c8d3b4 100644 --- a/arch/mips/boot/dts/brcm/bcm7425.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7425.dtsi @@ -410,5 +410,25 @@ #phy-cells = <0>; }; }; + + sdhci0: sdhci@419000 { + compatible = "brcm,bcm7425-sdhci"; + reg = <0x419000 0x100>; + interrupt-parent = <&periph_intc>; + interrupts = <43>; + sd-uhs-sdr50; + mmc-hs200-1_8v; + status = "disabled"; + }; + + sdhci1: sdhci@419200 { + compatible = "brcm,bcm7425-sdhci"; + reg = <0x419200 0x100>; + interrupt-parent = <&periph_intc>; + interrupts = <44>; + sd-uhs-sdr50; + mmc-hs200-1_8v; + status = "disabled"; + }; }; }; diff --git a/arch/mips/boot/dts/brcm/bcm7435.dtsi b/arch/mips/boot/dts/brcm/bcm7435.dtsi index b7bb102..2b28d91 100644 --- a/arch/mips/boot/dts/brcm/bcm7435.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7435.dtsi @@ -425,5 +425,25 @@ #phy-cells = <0>; }; }; + + sdhci0: sdhci@41a000 { + compatible = "brcm,bcm7425-sdhci"; + reg = <0x41a000 0x100>; + interrupt-parent = <&periph_intc>; + interrupts = <47>; + sd-uhs-sdr50; + mmc-hs200-1_8v; + status = "disabled"; + }; + + sdhci1: sdhci@41a200 { + compatible = "brcm,bcm7425-sdhci"; + reg = <0x41a200 0x100>; + interrupt-parent = <&periph_intc>; + interrupts = <48>; + sd-uhs-sdr50; + mmc-hs200-1_8v; + status = "disabled"; + }; }; }; diff --git a/arch/mips/boot/dts/brcm/bcm97346dbsmb.dts b/arch/mips/boot/dts/brcm/bcm97346dbsmb.dts index 2c55ab0..27c9f12 100644 --- a/arch/mips/boot/dts/brcm/bcm97346dbsmb.dts +++ b/arch/mips/boot/dts/brcm/bcm97346dbsmb.dts @@ -100,3 +100,7 @@ &sata_phy { status = "okay"; }; + +&sdhci0 { + status = "okay"; +}; diff --git a/arch/mips/boot/dts/brcm/bcm97360svmb.dts b/arch/mips/boot/dts/brcm/bcm97360svmb.dts index 496e6ed..bed821b 100644 --- a/arch/mips/boot/dts/brcm/bcm97360svmb.dts +++ b/arch/mips/boot/dts/brcm/bcm97360svmb.dts @@ -68,3 +68,7 @@ &sata_phy { status = "okay"; }; + +&sdhci0 { + status = "okay"; +}; diff --git a/arch/mips/boot/dts/brcm/bcm97362svmb.dts b/arch/mips/boot/dts/brcm/bcm97362svmb.dts index b880c01..1b9bc4b 100644 --- a/arch/mips/boot/dts/brcm/bcm97362svmb.dts +++ b/arch/mips/boot/dts/brcm/bcm97362svmb.dts @@ -64,3 +64,7 @@ &sata_phy { status = "okay"; }; + +&sdhci0 { + status = "okay"; +}; diff --git a/arch/mips/boot/dts/brcm/bcm97425svmb.dts b/arch/mips/boot/dts/brcm/bcm97425svmb.dts index f091e91..1c6b74d 100644 --- a/arch/mips/boot/dts/brcm/bcm97425svmb.dts +++ b/arch/mips/boot/dts/brcm/bcm97425svmb.dts @@ -94,3 +94,11 @@ &ohci3 { status = "okay"; }; + +&sdhci0 { + status = "okay"; +}; + +&sdhci1 { + status = "okay"; +}; diff --git a/arch/mips/boot/dts/brcm/bcm97435svmb.dts b/arch/mips/boot/dts/brcm/bcm97435svmb.dts index 9db84f2..64bb198 100644 --- a/arch/mips/boot/dts/brcm/bcm97435svmb.dts +++ b/arch/mips/boot/dts/brcm/bcm97435svmb.dts @@ -102,3 +102,11 @@ &sata_phy { status = "okay"; }; + +&sdhci0 { + status = "okay"; +}; + +&sdhci1 { + status = "okay"; +}; -- cgit v0.10.2 From cfc8be04c36a1a6546b6f9cb8f02fd9f215c9d38 Mon Sep 17 00:00:00 2001 From: Jaedon Shin Date: Fri, 19 Aug 2016 11:52:29 +0900 Subject: MIPS: BMIPS: Add support NAND device nodes Adds NAND device nodes to BCM7xxx MIPS based SoCs. Signed-off-by: Jaedon Shin Cc: Florian Fainelli Cc: Jonas Gorski Cc: Kevin Cernekee Cc: Rob Herring Cc: MIPS Mailing List Cc: devicetree@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14003/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/boot/dts/brcm/bcm7346.dtsi b/arch/mips/boot/dts/brcm/bcm7346.dtsi index 0da4f8a..72d9cff 100644 --- a/arch/mips/boot/dts/brcm/bcm7346.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7346.dtsi @@ -372,6 +372,26 @@ status = "disabled"; }; + hif_l2_intc: interrupt-controller@411000 { + compatible = "brcm,l2-intc"; + reg = <0x411000 0x30>; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&periph_intc>; + interrupts = <30>; + }; + + nand: nand@412800 { + compatible = "brcm,brcmnand-v5.0", "brcm,brcmnand"; + #address-cells = <1>; + #size-cells = <0>; + reg-names = "nand"; + reg = <0x412800 0x400>; + interrupt-parent = <&hif_l2_intc>; + interrupts = <24>; + status = "disabled"; + }; + sata: sata@181000 { compatible = "brcm,bcm7425-ahci", "brcm,sata3-ahci"; reg-names = "ahci", "top-ctrl"; diff --git a/arch/mips/boot/dts/brcm/bcm7358.dtsi b/arch/mips/boot/dts/brcm/bcm7358.dtsi index aec1b2e..7f78bfa 100644 --- a/arch/mips/boot/dts/brcm/bcm7358.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7358.dtsi @@ -298,5 +298,25 @@ interrupts = <66>; status = "disabled"; }; + + hif_l2_intc: interrupt-controller@411000 { + compatible = "brcm,l2-intc"; + reg = <0x411000 0x30>; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&periph_intc>; + interrupts = <30>; + }; + + nand: nand@412800 { + compatible = "brcm,brcmnand-v5.0", "brcm,brcmnand"; + #address-cells = <1>; + #size-cells = <0>; + reg-names = "nand"; + reg = <0x412800 0x400>; + interrupt-parent = <&hif_l2_intc>; + interrupts = <24>; + status = "disabled"; + }; }; }; diff --git a/arch/mips/boot/dts/brcm/bcm7360.dtsi b/arch/mips/boot/dts/brcm/bcm7360.dtsi index 9f72d34..64b9fd9 100644 --- a/arch/mips/boot/dts/brcm/bcm7360.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7360.dtsi @@ -291,6 +291,26 @@ status = "disabled"; }; + hif_l2_intc: interrupt-controller@411000 { + compatible = "brcm,l2-intc"; + reg = <0x411000 0x30>; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&periph_intc>; + interrupts = <30>; + }; + + nand: nand@412800 { + compatible = "brcm,brcmnand-v5.0", "brcm,brcmnand"; + #address-cells = <1>; + #size-cells = <0>; + reg-names = "nand"; + reg = <0x412800 0x400>; + interrupt-parent = <&hif_l2_intc>; + interrupts = <24>; + status = "disabled"; + }; + sata: sata@181000 { compatible = "brcm,bcm7425-ahci", "brcm,sata3-ahci"; reg-names = "ahci", "top-ctrl"; diff --git a/arch/mips/boot/dts/brcm/bcm7362.dtsi b/arch/mips/boot/dts/brcm/bcm7362.dtsi index ff734f4..784d587 100644 --- a/arch/mips/boot/dts/brcm/bcm7362.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7362.dtsi @@ -287,6 +287,26 @@ status = "disabled"; }; + hif_l2_intc: interrupt-controller@411000 { + compatible = "brcm,l2-intc"; + reg = <0x411000 0x30>; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&periph_intc>; + interrupts = <30>; + }; + + nand: nand@412800 { + compatible = "brcm,brcmnand-v5.0", "brcm,brcmnand"; + #address-cells = <1>; + #size-cells = <0>; + reg-names = "nand"; + reg = <0x412800 0x400>; + interrupt-parent = <&hif_l2_intc>; + interrupts = <24>; + status = "disabled"; + }; + sata: sata@181000 { compatible = "brcm,bcm7425-ahci", "brcm,sata3-ahci"; reg-names = "ahci", "top-ctrl"; diff --git a/arch/mips/boot/dts/brcm/bcm7425.dtsi b/arch/mips/boot/dts/brcm/bcm7425.dtsi index 1c8d3b4..7124c98 100644 --- a/arch/mips/boot/dts/brcm/bcm7425.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7425.dtsi @@ -371,6 +371,26 @@ status = "disabled"; }; + hif_l2_intc: interrupt-controller@41a000 { + compatible = "brcm,l2-intc"; + reg = <0x41a000 0x30>; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&periph_intc>; + interrupts = <24>; + }; + + nand: nand@41b800 { + compatible = "brcm,brcmnand-v5.0", "brcm,brcmnand"; + #address-cells = <1>; + #size-cells = <0>; + reg-names = "nand"; + reg = <0x41b800 0x400>; + interrupt-parent = <&hif_l2_intc>; + interrupts = <24>; + status = "disabled"; + }; + sata: sata@181000 { compatible = "brcm,bcm7425-ahci", "brcm,sata3-ahci"; reg-names = "ahci", "top-ctrl"; diff --git a/arch/mips/boot/dts/brcm/bcm7435.dtsi b/arch/mips/boot/dts/brcm/bcm7435.dtsi index 2b28d91..a364896 100644 --- a/arch/mips/boot/dts/brcm/bcm7435.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7435.dtsi @@ -386,6 +386,26 @@ status = "disabled"; }; + hif_l2_intc: interrupt-controller@41b000 { + compatible = "brcm,l2-intc"; + reg = <0x41b000 0x30>; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&periph_intc>; + interrupts = <24>; + }; + + nand: nand@41c800 { + compatible = "brcm,brcmnand-v6.2", "brcm,brcmnand"; + #address-cells = <1>; + #size-cells = <0>; + reg-names = "nand", "flash-dma"; + reg = <0x41c800 0x600>, <0x41d000 0x100>; + interrupt-parent = <&hif_l2_intc>; + interrupts = <24>, <4>; + status = "disabled"; + }; + sata: sata@181000 { compatible = "brcm,bcm7425-ahci", "brcm,sata3-ahci"; reg-names = "ahci", "top-ctrl"; diff --git a/arch/mips/boot/dts/brcm/bcm97346dbsmb.dts b/arch/mips/boot/dts/brcm/bcm97346dbsmb.dts index 27c9f12..e67eaf3 100644 --- a/arch/mips/boot/dts/brcm/bcm97346dbsmb.dts +++ b/arch/mips/boot/dts/brcm/bcm97346dbsmb.dts @@ -1,6 +1,7 @@ /dts-v1/; /include/ "bcm7346.dtsi" +/include/ "bcm97xxx-nand-cs1-bch24.dtsi" / { compatible = "brcm,bcm97346dbsmb", "brcm,bcm7346"; @@ -93,6 +94,10 @@ status = "okay"; }; +&nand { + status = "okay"; +}; + &sata { status = "okay"; }; diff --git a/arch/mips/boot/dts/brcm/bcm97358svmb.dts b/arch/mips/boot/dts/brcm/bcm97358svmb.dts index 757fe9d..ee4607f 100644 --- a/arch/mips/boot/dts/brcm/bcm97358svmb.dts +++ b/arch/mips/boot/dts/brcm/bcm97358svmb.dts @@ -1,6 +1,7 @@ /dts-v1/; /include/ "bcm7358.dtsi" +/include/ "bcm97xxx-nand-cs1-bch4.dtsi" / { compatible = "brcm,bcm97358svmb", "brcm,bcm7358"; @@ -64,3 +65,7 @@ &ohci0 { status = "okay"; }; + +&nand { + status = "okay"; +}; diff --git a/arch/mips/boot/dts/brcm/bcm97362svmb.dts b/arch/mips/boot/dts/brcm/bcm97362svmb.dts index 1b9bc4b..68fd823 100644 --- a/arch/mips/boot/dts/brcm/bcm97362svmb.dts +++ b/arch/mips/boot/dts/brcm/bcm97362svmb.dts @@ -1,6 +1,7 @@ /dts-v1/; /include/ "bcm7362.dtsi" +/include/ "bcm97xxx-nand-cs1-bch4.dtsi" / { compatible = "brcm,bcm97362svmb", "brcm,bcm7362"; @@ -57,6 +58,10 @@ status = "okay"; }; +&nand { + status = "okay"; +}; + &sata { status = "okay"; }; diff --git a/arch/mips/boot/dts/brcm/bcm97425svmb.dts b/arch/mips/boot/dts/brcm/bcm97425svmb.dts index 1c6b74d..f95ba1b 100644 --- a/arch/mips/boot/dts/brcm/bcm97425svmb.dts +++ b/arch/mips/boot/dts/brcm/bcm97425svmb.dts @@ -1,6 +1,7 @@ /dts-v1/; /include/ "bcm7425.dtsi" +/include/ "bcm97xxx-nand-cs1-bch24.dtsi" / { compatible = "brcm,bcm97425svmb", "brcm,bcm7425"; @@ -95,6 +96,10 @@ status = "okay"; }; +&nand { + status = "okay"; +}; + &sdhci0 { status = "okay"; }; diff --git a/arch/mips/boot/dts/brcm/bcm97435svmb.dts b/arch/mips/boot/dts/brcm/bcm97435svmb.dts index 64bb198..fb37b71 100644 --- a/arch/mips/boot/dts/brcm/bcm97435svmb.dts +++ b/arch/mips/boot/dts/brcm/bcm97435svmb.dts @@ -1,6 +1,7 @@ /dts-v1/; /include/ "bcm7435.dtsi" +/include/ "bcm97xxx-nand-cs1-bch24.dtsi" / { compatible = "brcm,bcm97435svmb", "brcm,bcm7435"; @@ -95,6 +96,10 @@ status = "okay"; }; +&nand { + status = "okay"; +}; + &sata { status = "okay"; }; diff --git a/arch/mips/boot/dts/brcm/bcm97xxx-nand-cs1-bch24.dtsi b/arch/mips/boot/dts/brcm/bcm97xxx-nand-cs1-bch24.dtsi new file mode 100644 index 0000000..3c24f97 --- /dev/null +++ b/arch/mips/boot/dts/brcm/bcm97xxx-nand-cs1-bch24.dtsi @@ -0,0 +1,25 @@ +&nand { + nandcs@1 { + compatible = "brcm,nandcs"; + reg = <1>; + nand-on-flash-bbt; + + nand-ecc-strength = <24>; + nand-ecc-step-size = <1024>; + brcm,nand-oob-sector-size = <27>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + flash1.rootfs@0 { + reg = <0x0 0x10000000>; + }; + + flash1.kernel@10000000 { + reg = <0x10000000 0x400000>; + }; + }; + }; +}; diff --git a/arch/mips/boot/dts/brcm/bcm97xxx-nand-cs1-bch4.dtsi b/arch/mips/boot/dts/brcm/bcm97xxx-nand-cs1-bch4.dtsi new file mode 100644 index 0000000..cb53181 --- /dev/null +++ b/arch/mips/boot/dts/brcm/bcm97xxx-nand-cs1-bch4.dtsi @@ -0,0 +1,25 @@ +&nand { + nandcs@1 { + compatible = "brcm,nandcs"; + reg = <1>; + nand-on-flash-bbt; + + nand-ecc-strength = <4>; + nand-ecc-step-size = <512>; + brcm,nand-oob-sector-size = <16>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + flash1.rootfs@0 { + reg = <0x0 0x10000000>; + }; + + flash1.kernel@10000000 { + reg = <0x10000000 0x400000>; + }; + }; + }; +}; -- cgit v0.10.2 From a2c510a2d0418ce15cd739d0a177ce53b06e5695 Mon Sep 17 00:00:00 2001 From: Jaedon Shin Date: Fri, 19 Aug 2016 11:52:30 +0900 Subject: MIPS: BMIPS: Use interrupt-controller node name Changes node names of the interrupt-controller device nodes to interrupt-controller instead of label strings. Signed-off-by: Jaedon Shin Cc: Florian Fainelli Cc: Jonas Gorski Cc: Kevin Cernekee Cc: Rob Herring Cc: MIPS Mailing List Cc: devicetree@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14004/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/boot/dts/brcm/bcm7125.dtsi b/arch/mips/boot/dts/brcm/bcm7125.dtsi index 746ed06..bbd00f6 100644 --- a/arch/mips/boot/dts/brcm/bcm7125.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7125.dtsi @@ -26,7 +26,7 @@ uart0 = &uart0; }; - cpu_intc: cpu_intc { + cpu_intc: interrupt-controller { #address-cells = <0>; compatible = "mti,cpu-interrupt-controller"; @@ -55,7 +55,7 @@ compatible = "simple-bus"; ranges = <0 0x10000000 0x01000000>; - periph_intc: periph_intc@441400 { + periph_intc: interrupt-controller@441400 { compatible = "brcm,bcm7038-l1-intc"; reg = <0x441400 0x30>, <0x441600 0x30>; @@ -66,7 +66,7 @@ interrupts = <2>, <3>; }; - sun_l2_intc: sun_l2_intc@401800 { + sun_l2_intc: interrupt-controller@401800 { compatible = "brcm,l2-intc"; reg = <0x401800 0x30>; interrupt-controller; @@ -87,7 +87,7 @@ "avd_0", "jtag_0"; }; - upg_irq0_intc: upg_irq0_intc@406780 { + upg_irq0_intc: interrupt-controller@406780 { compatible = "brcm,bcm7120-l2-intc"; reg = <0x406780 0x8>; diff --git a/arch/mips/boot/dts/brcm/bcm7346.dtsi b/arch/mips/boot/dts/brcm/bcm7346.dtsi index 72d9cff..4bbcc95 100644 --- a/arch/mips/boot/dts/brcm/bcm7346.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7346.dtsi @@ -26,7 +26,7 @@ uart0 = &uart0; }; - cpu_intc: cpu_intc { + cpu_intc: interrupt-controller { #address-cells = <0>; compatible = "mti,cpu-interrupt-controller"; @@ -55,7 +55,7 @@ compatible = "simple-bus"; ranges = <0 0x10000000 0x01000000>; - periph_intc: periph_intc@411400 { + periph_intc: interrupt-controller@411400 { compatible = "brcm,bcm7038-l1-intc"; reg = <0x411400 0x30>, <0x411600 0x30>; @@ -66,7 +66,7 @@ interrupts = <2>, <3>; }; - sun_l2_intc: sun_l2_intc@403000 { + sun_l2_intc: interrupt-controller@403000 { compatible = "brcm,l2-intc"; reg = <0x403000 0x30>; interrupt-controller; @@ -87,7 +87,7 @@ "jtag_0", "svd_0"; }; - upg_irq0_intc: upg_irq0_intc@406780 { + upg_irq0_intc: interrupt-controller@406780 { compatible = "brcm,bcm7120-l2-intc"; reg = <0x406780 0x8>; @@ -102,7 +102,7 @@ interrupt-names = "upg_main", "upg_bsc"; }; - upg_aon_irq0_intc: upg_aon_irq0_intc@408b80 { + upg_aon_irq0_intc: interrupt-controller@408b80 { compatible = "brcm,bcm7120-l2-intc"; reg = <0x408b80 0x8>; diff --git a/arch/mips/boot/dts/brcm/bcm7358.dtsi b/arch/mips/boot/dts/brcm/bcm7358.dtsi index 7f78bfa..3e42535 100644 --- a/arch/mips/boot/dts/brcm/bcm7358.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7358.dtsi @@ -20,7 +20,7 @@ uart0 = &uart0; }; - cpu_intc: cpu_intc { + cpu_intc: interrupt-controller { #address-cells = <0>; compatible = "mti,cpu-interrupt-controller"; @@ -49,7 +49,7 @@ compatible = "simple-bus"; ranges = <0 0x10000000 0x01000000>; - periph_intc: periph_intc@411400 { + periph_intc: interrupt-controller@411400 { compatible = "brcm,bcm7038-l1-intc"; reg = <0x411400 0x30>; @@ -60,7 +60,7 @@ interrupts = <2>; }; - sun_l2_intc: sun_l2_intc@403000 { + sun_l2_intc: interrupt-controller@403000 { compatible = "brcm,l2-intc"; reg = <0x403000 0x30>; interrupt-controller; @@ -81,7 +81,7 @@ "avd_0", "jtag_0"; }; - upg_irq0_intc: upg_irq0_intc@406600 { + upg_irq0_intc: interrupt-controller@406600 { compatible = "brcm,bcm7120-l2-intc"; reg = <0x406600 0x8>; @@ -96,7 +96,7 @@ interrupt-names = "upg_main", "upg_bsc"; }; - upg_aon_irq0_intc: upg_aon_irq0_intc@408b80 { + upg_aon_irq0_intc: interrupt-controller@408b80 { compatible = "brcm,bcm7120-l2-intc"; reg = <0x408b80 0x8>; diff --git a/arch/mips/boot/dts/brcm/bcm7360.dtsi b/arch/mips/boot/dts/brcm/bcm7360.dtsi index 64b9fd9..112a557 100644 --- a/arch/mips/boot/dts/brcm/bcm7360.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7360.dtsi @@ -20,7 +20,7 @@ uart0 = &uart0; }; - cpu_intc: cpu_intc { + cpu_intc: interrupt-controller { #address-cells = <0>; compatible = "mti,cpu-interrupt-controller"; @@ -49,7 +49,7 @@ compatible = "simple-bus"; ranges = <0 0x10000000 0x01000000>; - periph_intc: periph_intc@411400 { + periph_intc: interrupt-controller@411400 { compatible = "brcm,bcm7038-l1-intc"; reg = <0x411400 0x30>; @@ -60,7 +60,7 @@ interrupts = <2>; }; - sun_l2_intc: sun_l2_intc@403000 { + sun_l2_intc: interrupt-controller@403000 { compatible = "brcm,l2-intc"; reg = <0x403000 0x30>; interrupt-controller; @@ -81,7 +81,7 @@ "avd_0", "jtag_0"; }; - upg_irq0_intc: upg_irq0_intc@406600 { + upg_irq0_intc: interrupt-controller@406600 { compatible = "brcm,bcm7120-l2-intc"; reg = <0x406600 0x8>; @@ -96,7 +96,7 @@ interrupt-names = "upg_main", "upg_bsc"; }; - upg_aon_irq0_intc: upg_aon_irq0_intc@408b80 { + upg_aon_irq0_intc: interrupt-controller@408b80 { compatible = "brcm,bcm7120-l2-intc"; reg = <0x408b80 0x8>; diff --git a/arch/mips/boot/dts/brcm/bcm7362.dtsi b/arch/mips/boot/dts/brcm/bcm7362.dtsi index 784d587..34abfb0 100644 --- a/arch/mips/boot/dts/brcm/bcm7362.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7362.dtsi @@ -26,7 +26,7 @@ uart0 = &uart0; }; - cpu_intc: cpu_intc { + cpu_intc: interrupt-controller { #address-cells = <0>; compatible = "mti,cpu-interrupt-controller"; @@ -55,7 +55,7 @@ compatible = "simple-bus"; ranges = <0 0x10000000 0x01000000>; - periph_intc: periph_intc@411400 { + periph_intc: interrupt-controller@411400 { compatible = "brcm,bcm7038-l1-intc"; reg = <0x411400 0x30>, <0x411600 0x30>; @@ -66,7 +66,7 @@ interrupts = <2>, <3>; }; - sun_l2_intc: sun_l2_intc@403000 { + sun_l2_intc: interrupt-controller@403000 { compatible = "brcm,l2-intc"; reg = <0x403000 0x30>; interrupt-controller; @@ -87,7 +87,7 @@ "avd_0", "jtag_0"; }; - upg_irq0_intc: upg_irq0_intc@406600 { + upg_irq0_intc: interrupt-controller@406600 { compatible = "brcm,bcm7120-l2-intc"; reg = <0x406600 0x8>; @@ -102,7 +102,7 @@ interrupt-names = "upg_main", "upg_bsc"; }; - upg_aon_irq0_intc: upg_aon_irq0_intc@408b80 { + upg_aon_irq0_intc: interrupt-controller@408b80 { compatible = "brcm,bcm7120-l2-intc"; reg = <0x408b80 0x8>; diff --git a/arch/mips/boot/dts/brcm/bcm7420.dtsi b/arch/mips/boot/dts/brcm/bcm7420.dtsi index 0d391d7..b143723 100644 --- a/arch/mips/boot/dts/brcm/bcm7420.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7420.dtsi @@ -26,7 +26,7 @@ uart0 = &uart0; }; - cpu_intc: cpu_intc { + cpu_intc: interrupt-controller { #address-cells = <0>; compatible = "mti,cpu-interrupt-controller"; @@ -55,7 +55,7 @@ compatible = "simple-bus"; ranges = <0 0x10000000 0x01000000>; - periph_intc: periph_intc@441400 { + periph_intc: interrupt-controller@441400 { compatible = "brcm,bcm7038-l1-intc"; reg = <0x441400 0x30>, <0x441600 0x30>; @@ -66,7 +66,7 @@ interrupts = <2>, <3>; }; - sun_l2_intc: sun_l2_intc@401800 { + sun_l2_intc: interrupt-controller@401800 { compatible = "brcm,l2-intc"; reg = <0x401800 0x30>; interrupt-controller; @@ -88,7 +88,7 @@ "jtag_0"; }; - upg_irq0_intc: upg_irq0_intc@406780 { + upg_irq0_intc: interrupt-controller@406780 { compatible = "brcm,bcm7120-l2-intc"; reg = <0x406780 0x8>; diff --git a/arch/mips/boot/dts/brcm/bcm7425.dtsi b/arch/mips/boot/dts/brcm/bcm7425.dtsi index 7124c98..2488d2f 100644 --- a/arch/mips/boot/dts/brcm/bcm7425.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7425.dtsi @@ -26,7 +26,7 @@ uart0 = &uart0; }; - cpu_intc: cpu_intc { + cpu_intc: interrupt-controller { #address-cells = <0>; compatible = "mti,cpu-interrupt-controller"; @@ -55,7 +55,7 @@ compatible = "simple-bus"; ranges = <0 0x10000000 0x01000000>; - periph_intc: periph_intc@41a400 { + periph_intc: interrupt-controller@41a400 { compatible = "brcm,bcm7038-l1-intc"; reg = <0x41a400 0x30>, <0x41a600 0x30>; @@ -66,7 +66,7 @@ interrupts = <2>, <3>; }; - sun_l2_intc: sun_l2_intc@403000 { + sun_l2_intc: interrupt-controller@403000 { compatible = "brcm,l2-intc"; reg = <0x403000 0x30>; interrupt-controller; @@ -89,7 +89,7 @@ "vice_0"; }; - upg_irq0_intc: upg_irq0_intc@406780 { + upg_irq0_intc: interrupt-controller@406780 { compatible = "brcm,bcm7120-l2-intc"; reg = <0x406780 0x8>; @@ -104,7 +104,7 @@ interrupt-names = "upg_main", "upg_bsc"; }; - upg_aon_irq0_intc: upg_aon_irq0_intc@409480 { + upg_aon_irq0_intc: interrupt-controller@409480 { compatible = "brcm,bcm7120-l2-intc"; reg = <0x409480 0x8>; diff --git a/arch/mips/boot/dts/brcm/bcm7435.dtsi b/arch/mips/boot/dts/brcm/bcm7435.dtsi index a364896..19fa259 100644 --- a/arch/mips/boot/dts/brcm/bcm7435.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7435.dtsi @@ -38,7 +38,7 @@ uart0 = &uart0; }; - cpu_intc: cpu_intc { + cpu_intc: interrupt-controller { #address-cells = <0>; compatible = "mti,cpu-interrupt-controller"; @@ -67,7 +67,7 @@ compatible = "simple-bus"; ranges = <0 0x10000000 0x01000000>; - periph_intc: periph_intc@41b500 { + periph_intc: interrupt-controller@41b500 { compatible = "brcm,bcm7038-l1-intc"; reg = <0x41b500 0x40>, <0x41b600 0x40>, <0x41b700 0x40>, <0x41b800 0x40>; @@ -79,7 +79,7 @@ interrupts = <2>, <3>, <2>, <3>; }; - sun_l2_intc: sun_l2_intc@403000 { + sun_l2_intc: interrupt-controller@403000 { compatible = "brcm,l2-intc"; reg = <0x403000 0x30>; interrupt-controller; @@ -104,7 +104,7 @@ "scpu"; }; - upg_irq0_intc: upg_irq0_intc@406780 { + upg_irq0_intc: interrupt-controller@406780 { compatible = "brcm,bcm7120-l2-intc"; reg = <0x406780 0x8>; @@ -119,7 +119,7 @@ interrupt-names = "upg_main", "upg_bsc"; }; - upg_aon_irq0_intc: upg_aon_irq0_intc@409480 { + upg_aon_irq0_intc: interrupt-controller@409480 { compatible = "brcm,bcm7120-l2-intc"; reg = <0x409480 0x8>; -- cgit v0.10.2 From d66698e0834657161314050b6c99c3eba36b180a Mon Sep 17 00:00:00 2001 From: Jaedon Shin Date: Fri, 30 Sep 2016 23:17:34 +0900 Subject: MIPS: BMIPS: Support APPENDED_DTB Use appended DTB when available. Signed-off-by: Jaedon Shin Cc: Kevin Cernekee Cc: Florian Fainelli Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/14337/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/bmips/setup.c b/arch/mips/bmips/setup.c index edf1b31..3b6f687 100644 --- a/arch/mips/bmips/setup.c +++ b/arch/mips/bmips/setup.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -152,6 +153,8 @@ void __init plat_time_init(void) mips_hpt_frequency = freq; } +extern const char __appended_dtb; + void __init plat_mem_setup(void) { void *dtb; @@ -161,6 +164,11 @@ void __init plat_mem_setup(void) ioport_resource.start = 0; ioport_resource.end = ~0; +#ifdef CONFIG_MIPS_ELF_APPENDED_DTB + if (!fdt_check_header(&__appended_dtb)) + dtb = (void *)&__appended_dtb; + else +#endif /* intended to somewhat resemble ARM; see Documentation/arm/Booting */ if (fw_arg0 == 0 && fw_arg1 == 0xffffffff) dtb = phys_to_virt(fw_arg2); -- cgit v0.10.2 From e3031b32840c1bee228c58bb284ebc05f97249c7 Mon Sep 17 00:00:00 2001 From: Marcin Nowakowski Date: Fri, 30 Sep 2016 11:33:45 +0200 Subject: MIPS: tracing: move insn_has_delay_slot to a shared header Currently both kprobes and uprobes code have definitions of the insn_has_delay_slot method. Move it to a separate header as an inline method that each probe-specific method can later use. No functional change intended, although the methods slightly varied in the constraints they set for the methods - the uprobes one was chosen as it is slightly more specific when filtering opcode fields. Signed-off-by: Marcin Nowakowski Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/14335/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/kernel/kprobes.c b/arch/mips/kernel/kprobes.c index 212f46f..747e3bf 100644 --- a/arch/mips/kernel/kprobes.c +++ b/arch/mips/kernel/kprobes.c @@ -32,7 +32,8 @@ #include #include #include -#include + +#include "probes-common.h" static const union mips_instruction breakpoint_insn = { .b_format = { @@ -55,63 +56,7 @@ DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); static int __kprobes insn_has_delayslot(union mips_instruction insn) { - switch (insn.i_format.opcode) { - - /* - * This group contains: - * jr and jalr are in r_format format. - */ - case spec_op: - switch (insn.r_format.func) { - case jr_op: - case jalr_op: - break; - default: - goto insn_ok; - } - - /* - * This group contains: - * bltz_op, bgez_op, bltzl_op, bgezl_op, - * bltzal_op, bgezal_op, bltzall_op, bgezall_op. - */ - case bcond_op: - - /* - * These are unconditional and in j_format. - */ - case jal_op: - case j_op: - - /* - * These are conditional and in i_format. - */ - case beq_op: - case beql_op: - case bne_op: - case bnel_op: - case blez_op: - case blezl_op: - case bgtz_op: - case bgtzl_op: - - /* - * These are the FPA/cp1 branch instructions. - */ - case cop1_op: - -#ifdef CONFIG_CPU_CAVIUM_OCTEON - case lwc2_op: /* This is bbit0 on Octeon */ - case ldc2_op: /* This is bbit032 on Octeon */ - case swc2_op: /* This is bbit1 on Octeon */ - case sdc2_op: /* This is bbit132 on Octeon */ -#endif - return 1; - default: - break; - } -insn_ok: - return 0; + return __insn_has_delay_slot(insn); } /* diff --git a/arch/mips/kernel/probes-common.h b/arch/mips/kernel/probes-common.h new file mode 100644 index 0000000..c979c37 --- /dev/null +++ b/arch/mips/kernel/probes-common.h @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2016 Imagination Technologies + * Author: Marcin Nowakowski + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __PROBES_COMMON_H +#define __PROBES_COMMON_H + +#include + +static inline int __insn_has_delay_slot(const union mips_instruction insn) +{ + switch (insn.i_format.opcode) { + /* + * jr and jalr are in r_format format. + */ + case spec_op: + switch (insn.r_format.func) { + case jalr_op: + case jr_op: + return 1; + } + break; + + /* + * This group contains: + * bltz_op, bgez_op, bltzl_op, bgezl_op, + * bltzal_op, bgezal_op, bltzall_op, bgezall_op. + */ + case bcond_op: + switch (insn.i_format.rt) { + case bltz_op: + case bltzl_op: + case bgez_op: + case bgezl_op: + case bltzal_op: + case bltzall_op: + case bgezal_op: + case bgezall_op: + case bposge32_op: + return 1; + } + break; + + /* + * These are unconditional and in j_format. + */ + case jal_op: + case j_op: + case beq_op: + case beql_op: + case bne_op: + case bnel_op: + case blez_op: /* not really i_format */ + case blezl_op: + case bgtz_op: + case bgtzl_op: + return 1; + + /* + * And now the FPA/cp1 branch instructions. + */ + case cop1_op: +#ifdef CONFIG_CPU_CAVIUM_OCTEON + case lwc2_op: /* This is bbit0 on Octeon */ + case ldc2_op: /* This is bbit032 on Octeon */ + case swc2_op: /* This is bbit1 on Octeon */ + case sdc2_op: /* This is bbit132 on Octeon */ +#endif + return 1; + } + + return 0; +} + +#endif /* __PROBES_COMMON_H */ diff --git a/arch/mips/kernel/uprobes.c b/arch/mips/kernel/uprobes.c index 15ad17c..1161c93 100644 --- a/arch/mips/kernel/uprobes.c +++ b/arch/mips/kernel/uprobes.c @@ -8,71 +8,12 @@ #include #include #include -#include + +#include "probes-common.h" static inline int insn_has_delay_slot(const union mips_instruction insn) { - switch (insn.i_format.opcode) { - /* - * jr and jalr are in r_format format. - */ - case spec_op: - switch (insn.r_format.func) { - case jalr_op: - case jr_op: - return 1; - } - break; - - /* - * This group contains: - * bltz_op, bgez_op, bltzl_op, bgezl_op, - * bltzal_op, bgezal_op, bltzall_op, bgezall_op. - */ - case bcond_op: - switch (insn.i_format.rt) { - case bltz_op: - case bltzl_op: - case bgez_op: - case bgezl_op: - case bltzal_op: - case bltzall_op: - case bgezal_op: - case bgezall_op: - case bposge32_op: - return 1; - } - break; - - /* - * These are unconditional and in j_format. - */ - case jal_op: - case j_op: - case beq_op: - case beql_op: - case bne_op: - case bnel_op: - case blez_op: /* not really i_format */ - case blezl_op: - case bgtz_op: - case bgtzl_op: - return 1; - - /* - * And now the FPA/cp1 branch instructions. - */ - case cop1_op: -#ifdef CONFIG_CPU_CAVIUM_OCTEON - case lwc2_op: /* This is bbit0 on Octeon */ - case ldc2_op: /* This is bbit032 on Octeon */ - case swc2_op: /* This is bbit1 on Octeon */ - case sdc2_op: /* This is bbit132 on Octeon */ -#endif - return 1; - } - - return 0; + return __insn_has_delay_slot(insn); } /** -- cgit v0.10.2 From d05c513069f15be5de766026a4192998688ffff1 Mon Sep 17 00:00:00 2001 From: Marcin Nowakowski Date: Fri, 30 Sep 2016 11:33:46 +0200 Subject: MIPS: tracing: disable uprobe/kprobe on compact branch instructions Current instruction decoder for uprobe/kprobe handler only handles branches with delay slots. For compact branches the behaviour is rather unpredictable - and depending on the encoding of a compact branch instruction may result in one (or more) of: - executing an instruction that follows a branch which wasn't in a delay slot and shouldn't have been executed - incorrectly emulating a branch leading to a jump to a wrong location - unexpected branching out of the single-stepped code and never reaching the breakpoint that should terminate the probe handler Results of these actions are generally unpredictable, but can end up with a probed application or kernel crash, so disable placing probes on compact branches until they are handled properly. Signed-off-by: Marcin Nowakowski Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/14336/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/kernel/branch.c b/arch/mips/kernel/branch.c index f5c6848..12c7181 100644 --- a/arch/mips/kernel/branch.c +++ b/arch/mips/kernel/branch.c @@ -866,3 +866,37 @@ unaligned: force_sig(SIGBUS, current); return -EFAULT; } + +#if (defined CONFIG_KPROBES) || (defined CONFIG_UPROBES) + +int __insn_is_compact_branch(union mips_instruction insn) +{ + if (!cpu_has_mips_r6) + return 0; + + switch (insn.i_format.opcode) { + case blezl_op: + case bgtzl_op: + case blez_op: + case bgtz_op: + /* + * blez[l] and bgtz[l] opcodes with non-zero rt + * are MIPS R6 compact branches + */ + if (insn.i_format.rt) + return 1; + break; + case bc6_op: + case balc6_op: + case pop10_op: + case pop30_op: + case pop66_op: + case pop76_op: + return 1; + } + + return 0; +} +EXPORT_SYMBOL_GPL(__insn_is_compact_branch); + +#endif /* CONFIG_KPROBES || CONFIG_UPROBES */ diff --git a/arch/mips/kernel/kprobes.c b/arch/mips/kernel/kprobes.c index 747e3bf..f5c8bce 100644 --- a/arch/mips/kernel/kprobes.c +++ b/arch/mips/kernel/kprobes.c @@ -106,6 +106,12 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p) goto out; } + if (__insn_is_compact_branch(insn)) { + pr_notice("Kprobes for compact branches are not supported\n"); + ret = -EINVAL; + goto out; + } + /* insn: must be on special executable page on mips. */ p->ainsn.insn = get_insn_slot(); if (!p->ainsn.insn) { diff --git a/arch/mips/kernel/probes-common.h b/arch/mips/kernel/probes-common.h index c979c37..dd08e41 100644 --- a/arch/mips/kernel/probes-common.h +++ b/arch/mips/kernel/probes-common.h @@ -13,6 +13,8 @@ #include +int __insn_is_compact_branch(union mips_instruction insn); + static inline int __insn_has_delay_slot(const union mips_instruction insn) { switch (insn.i_format.opcode) { diff --git a/arch/mips/kernel/uprobes.c b/arch/mips/kernel/uprobes.c index 1161c93..dbb9174 100644 --- a/arch/mips/kernel/uprobes.c +++ b/arch/mips/kernel/uprobes.c @@ -36,6 +36,12 @@ int arch_uprobe_analyze_insn(struct arch_uprobe *aup, return -EINVAL; inst.word = aup->insn[0]; + + if (__insn_is_compact_branch(inst)) { + pr_notice("Uprobes for compact branches are not supported\n"); + return -EINVAL; + } + aup->ixol[0] = aup->insn[insn_has_delay_slot(inst)]; aup->ixol[1] = UPROBE_BRK_UPROBE_XOL; /* NOP */ -- cgit v0.10.2 From 23dac14d058fcd7cb2b4e6389139ca065855afe7 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Wed, 5 Oct 2016 18:18:07 +0100 Subject: MIPS: PCI: Use struct list_head lists Rather than open-coding a linked list implementation, make use of the one in linux/list.h. Signed-off-by: Paul Burton Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/14340/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/include/asm/pci.h b/arch/mips/include/asm/pci.h index 9b63cd4..547e113 100644 --- a/arch/mips/include/asm/pci.h +++ b/arch/mips/include/asm/pci.h @@ -17,6 +17,7 @@ */ #include +#include #include /* @@ -25,7 +26,7 @@ * single controller supporting multiple channels. */ struct pci_controller { - struct pci_controller *next; + struct list_head list; struct pci_bus *bus; struct device_node *of_node; diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c index b4c02f2..644ae96 100644 --- a/arch/mips/pci/pci.c +++ b/arch/mips/pci/pci.c @@ -28,8 +28,7 @@ /* * The PCI controller list. */ - -static struct pci_controller *hose_head, **hose_tail = &hose_head; +static LIST_HEAD(controllers); unsigned long PCIBIOS_MIN_IO; unsigned long PCIBIOS_MIN_MEM; @@ -193,8 +192,8 @@ void register_pci_controller(struct pci_controller *hose) goto out; } - *hose_tail = hose; - hose_tail = &hose->next; + INIT_LIST_HEAD(&hose->list); + list_add(&hose->list, &controllers); /* * Do not panic here but later - this might happen before console init. @@ -248,7 +247,7 @@ static int __init pcibios_init(void) pcibios_set_cache_line_size(); /* Scan all of the recorded PCI controllers. */ - for (hose = hose_head; hose; hose = hose->next) + list_for_each_entry(hose, &controllers, list) pcibios_scanbus(hose); pci_fixup_irqs(pci_common_swizzle, pcibios_map_irq); -- cgit v0.10.2 From 88555b481958083b1b928a4ba5c6e3bc606ce34b Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Wed, 5 Oct 2016 18:18:08 +0100 Subject: MIPS: PCI: Support for CONFIG_PCI_DOMAINS_GENERIC Introduce support for CONFIG_PCI_DOMAINS_GENERIC, allowing for platforms to make use of generic PCI domains instead of the MIPS-specific implementation. The set_pci_need_domain_info function is introduced to abstract away the removed need_domain_info field in struct pci_controller, and pcibios_scanbus is adjusted to use the pci_domain_nr accessor instead of directly accessing the index field. Signed-off-by: Paul Burton Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/14341/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 400cd36..7a75215 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -2995,6 +2995,9 @@ config HT_PCI config PCI_DOMAINS bool +config PCI_DOMAINS_GENERIC + bool + source "drivers/pci/Kconfig" # diff --git a/arch/mips/include/asm/pci.h b/arch/mips/include/asm/pci.h index 547e113..0564692 100644 --- a/arch/mips/include/asm/pci.h +++ b/arch/mips/include/asm/pci.h @@ -39,10 +39,12 @@ struct pci_controller { struct resource *busn_resource; unsigned long busn_offset; +#ifndef CONFIG_PCI_DOMAINS_GENERIC unsigned int index; /* For compatibility with current (as of July 2003) pciutils and XFree86. Eventually will be removed. */ unsigned int need_domain_info; +#endif /* Optional access methods for reading/writing the bus number of the PCI controller */ @@ -101,7 +103,18 @@ struct pci_dev; */ #define PCI_DMA_BUS_IS_PHYS (1) -#ifdef CONFIG_PCI_DOMAINS +#ifdef CONFIG_PCI_DOMAINS_GENERIC +static inline int pci_proc_domain(struct pci_bus *bus) +{ + return pci_domain_nr(bus); +} + +static inline void set_pci_need_domain_info(struct pci_controller *hose, + int need_domain_info) +{ + /* nothing to do */ +} +#elif defined(CONFIG_PCI_DOMAINS) #define pci_domain_nr(bus) ((struct pci_controller *)(bus)->sysdata)->index static inline int pci_proc_domain(struct pci_bus *bus) @@ -109,6 +122,12 @@ static inline int pci_proc_domain(struct pci_bus *bus) struct pci_controller *hose = bus->sysdata; return hose->need_domain_info; } + +static inline void set_pci_need_domain_info(struct pci_controller *hose, + int need_domain_info) +{ + hose->need_domain_info = need_domain_info; +} #endif /* CONFIG_PCI_DOMAINS */ #endif /* __KERNEL__ */ diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c index 644ae96..5207c04 100644 --- a/arch/mips/pci/pci.c +++ b/arch/mips/pci/pci.c @@ -95,8 +95,8 @@ static void pcibios_scanbus(struct pci_controller *hose) &resources); hose->bus = bus; - need_domain_info = need_domain_info || hose->index; - hose->need_domain_info = need_domain_info; + need_domain_info = need_domain_info || pci_domain_nr(bus); + set_pci_need_domain_info(hose, need_domain_info); if (!bus) { pci_free_resource_list(&resources); -- cgit v0.10.2 From f474ba9d9f275fc3bfe459b48bfc17ddd8e1f4cb Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Wed, 5 Oct 2016 18:18:09 +0100 Subject: MIPS: PCI: Make pcibios_set_cache_line_size an initcall In preparation for allowing configurations in which pcibios_init is not included, make pcibios_set_cache_line_size an initcall. arch_initcall is used such that it runs before the pcibios_init subsys_initcall for platforms that continue to use it. Signed-off-by: Paul Burton Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/14342/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c index 5207c04..30320a4 100644 --- a/arch/mips/pci/pci.c +++ b/arch/mips/pci/pci.c @@ -220,7 +220,7 @@ out: "Skipping PCI bus scan due to resource conflict\n"); } -static void __init pcibios_set_cache_line_size(void) +static int __init pcibios_set_cache_line_size(void) { struct cpuinfo_mips *c = ¤t_cpu_data; unsigned int lsize; @@ -238,14 +238,14 @@ static void __init pcibios_set_cache_line_size(void) pci_dfl_cache_line_size = lsize >> 2; pr_debug("PCI: pci_cache_line_size set to %d bytes\n", lsize); + return 0; } +arch_initcall(pcibios_set_cache_line_size); static int __init pcibios_init(void) { struct pci_controller *hose; - pcibios_set_cache_line_size(); - /* Scan all of the recorded PCI controllers. */ list_for_each_entry(hose, &controllers, list) pcibios_scanbus(hose); -- cgit v0.10.2 From ab96b03144c5392b8c0c427cc37df34daa84c5d0 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Wed, 5 Oct 2016 18:18:10 +0100 Subject: MIPS: PCI: Inline pcibios_assign_all_busses The MIPS implementation of pcibios_assign_all_busses trivially returns 1. Implement it as a static function in asm/pci.h such that the compiler can inline it & optimise out never-taken paths. Signed-off-by: Paul Burton Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/14343/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/include/asm/pci.h b/arch/mips/include/asm/pci.h index 0564692..acc651e 100644 --- a/arch/mips/include/asm/pci.h +++ b/arch/mips/include/asm/pci.h @@ -66,8 +66,10 @@ extern int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin); /* Can be used to override the logic in pci_scan_bus for skipping already-configured bus numbers - to be used for buggy BIOSes or architectures with incomplete PCI setup by the loader */ - -extern unsigned int pcibios_assign_all_busses(void); +static inline unsigned int pcibios_assign_all_busses(void) +{ + return 1; +} extern unsigned long PCIBIOS_MIN_IO; extern unsigned long PCIBIOS_MIN_MEM; diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c index 30320a4..8cc6ea4 100644 --- a/arch/mips/pci/pci.c +++ b/arch/mips/pci/pci.c @@ -297,11 +297,6 @@ static int pcibios_enable_resources(struct pci_dev *dev, int mask) return 0; } -unsigned int pcibios_assign_all_busses(void) -{ - return 1; -} - int pcibios_enable_device(struct pci_dev *dev, int mask) { int err; -- cgit v0.10.2 From f8091a88978b68df8ee6095eed0de2177eac3c69 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Wed, 5 Oct 2016 18:18:11 +0100 Subject: MIPS: PCI: Split pci.c into pci.c & pci-legacy.c Split out the parts of pci.c that are used by existing systems with MIPS-style PCI drivers but that will not be used by systems with more generic PCI drivers such as pcie-xilinx. This is done in preparation for allowing configurations where the code moved to pci-legacy.c is not built. Signed-off-by: Paul Burton Cc: linux-mips@linux-mips.org Cc: Paul Burton Patchwork: https://patchwork.linux-mips.org/patch/14344/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index 139ad1d..5666637 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile @@ -3,6 +3,7 @@ # obj-y += pci.o +obj-y += pci-legacy.o # # PCI bus host bridge specific code diff --git a/arch/mips/pci/pci-legacy.c b/arch/mips/pci/pci-legacy.c new file mode 100644 index 0000000..014649b --- /dev/null +++ b/arch/mips/pci/pci-legacy.c @@ -0,0 +1,302 @@ +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * Copyright (C) 2003, 04, 11 Ralf Baechle (ralf@linux-mips.org) + * Copyright (C) 2011 Wind River Systems, + * written by Ralf Baechle (ralf@linux-mips.org) + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* + * If PCI_PROBE_ONLY in pci_flags is set, we don't change any PCI resource + * assignments. + */ + +/* + * The PCI controller list. + */ +static LIST_HEAD(controllers); + +static int pci_initialized; + +/* + * We need to avoid collisions with `mirrored' VGA ports + * and other strange ISA hardware, so we always want the + * addresses to be allocated in the 0x000-0x0ff region + * modulo 0x400. + * + * Why? Because some silly external IO cards only decode + * the low 10 bits of the IO address. The 0x00-0xff region + * is reserved for motherboard devices that decode all 16 + * bits, so it's ok to allocate at, say, 0x2800-0x28ff, + * but we want to try to avoid allocating at 0x2900-0x2bff + * which might have be mirrored at 0x0100-0x03ff.. + */ +resource_size_t +pcibios_align_resource(void *data, const struct resource *res, + resource_size_t size, resource_size_t align) +{ + struct pci_dev *dev = data; + struct pci_controller *hose = dev->sysdata; + resource_size_t start = res->start; + + if (res->flags & IORESOURCE_IO) { + /* Make sure we start at our min on all hoses */ + if (start < PCIBIOS_MIN_IO + hose->io_resource->start) + start = PCIBIOS_MIN_IO + hose->io_resource->start; + + /* + * Put everything into 0x00-0xff region modulo 0x400 + */ + if (start & 0x300) + start = (start + 0x3ff) & ~0x3ff; + } else if (res->flags & IORESOURCE_MEM) { + /* Make sure we start at our min on all hoses */ + if (start < PCIBIOS_MIN_MEM + hose->mem_resource->start) + start = PCIBIOS_MIN_MEM + hose->mem_resource->start; + } + + return start; +} + +static void pcibios_scanbus(struct pci_controller *hose) +{ + static int next_busno; + static int need_domain_info; + LIST_HEAD(resources); + struct pci_bus *bus; + + if (hose->get_busno && pci_has_flag(PCI_PROBE_ONLY)) + next_busno = (*hose->get_busno)(); + + pci_add_resource_offset(&resources, + hose->mem_resource, hose->mem_offset); + pci_add_resource_offset(&resources, + hose->io_resource, hose->io_offset); + pci_add_resource_offset(&resources, + hose->busn_resource, hose->busn_offset); + bus = pci_scan_root_bus(NULL, next_busno, hose->pci_ops, hose, + &resources); + hose->bus = bus; + + need_domain_info = need_domain_info || pci_domain_nr(bus); + set_pci_need_domain_info(hose, need_domain_info); + + if (!bus) { + pci_free_resource_list(&resources); + return; + } + + next_busno = bus->busn_res.end + 1; + /* Don't allow 8-bit bus number overflow inside the hose - + reserve some space for bridges. */ + if (next_busno > 224) { + next_busno = 0; + need_domain_info = 1; + } + + /* + * We insert PCI resources into the iomem_resource and + * ioport_resource trees in either pci_bus_claim_resources() + * or pci_bus_assign_resources(). + */ + if (pci_has_flag(PCI_PROBE_ONLY)) { + pci_bus_claim_resources(bus); + } else { + pci_bus_size_bridges(bus); + pci_bus_assign_resources(bus); + } + pci_bus_add_devices(bus); +} + +#ifdef CONFIG_OF +void pci_load_of_ranges(struct pci_controller *hose, struct device_node *node) +{ + struct of_pci_range range; + struct of_pci_range_parser parser; + + pr_info("PCI host bridge %s ranges:\n", node->full_name); + hose->of_node = node; + + if (of_pci_range_parser_init(&parser, node)) + return; + + for_each_of_pci_range(&parser, &range) { + struct resource *res = NULL; + + switch (range.flags & IORESOURCE_TYPE_BITS) { + case IORESOURCE_IO: + pr_info(" IO 0x%016llx..0x%016llx\n", + range.cpu_addr, + range.cpu_addr + range.size - 1); + hose->io_map_base = + (unsigned long)ioremap(range.cpu_addr, + range.size); + res = hose->io_resource; + break; + case IORESOURCE_MEM: + pr_info(" MEM 0x%016llx..0x%016llx\n", + range.cpu_addr, + range.cpu_addr + range.size - 1); + res = hose->mem_resource; + break; + } + if (res != NULL) + of_pci_range_to_resource(&range, node, res); + } +} + +struct device_node *pcibios_get_phb_of_node(struct pci_bus *bus) +{ + struct pci_controller *hose = bus->sysdata; + + return of_node_get(hose->of_node); +} +#endif + +static DEFINE_MUTEX(pci_scan_mutex); + +void register_pci_controller(struct pci_controller *hose) +{ + struct resource *parent; + + parent = hose->mem_resource->parent; + if (!parent) + parent = &iomem_resource; + + if (request_resource(parent, hose->mem_resource) < 0) + goto out; + + parent = hose->io_resource->parent; + if (!parent) + parent = &ioport_resource; + + if (request_resource(parent, hose->io_resource) < 0) { + release_resource(hose->mem_resource); + goto out; + } + + INIT_LIST_HEAD(&hose->list); + list_add(&hose->list, &controllers); + + /* + * Do not panic here but later - this might happen before console init. + */ + if (!hose->io_map_base) { + printk(KERN_WARNING + "registering PCI controller with io_map_base unset\n"); + } + + /* + * Scan the bus if it is register after the PCI subsystem + * initialization. + */ + if (pci_initialized) { + mutex_lock(&pci_scan_mutex); + pcibios_scanbus(hose); + mutex_unlock(&pci_scan_mutex); + } + + return; + +out: + printk(KERN_WARNING + "Skipping PCI bus scan due to resource conflict\n"); +} + +static int __init pcibios_init(void) +{ + struct pci_controller *hose; + + /* Scan all of the recorded PCI controllers. */ + list_for_each_entry(hose, &controllers, list) + pcibios_scanbus(hose); + + pci_fixup_irqs(pci_common_swizzle, pcibios_map_irq); + + pci_initialized = 1; + + return 0; +} + +subsys_initcall(pcibios_init); + +static int pcibios_enable_resources(struct pci_dev *dev, int mask) +{ + u16 cmd, old_cmd; + int idx; + struct resource *r; + + pci_read_config_word(dev, PCI_COMMAND, &cmd); + old_cmd = cmd; + for (idx=0; idx < PCI_NUM_RESOURCES; idx++) { + /* Only set up the requested stuff */ + if (!(mask & (1<resource[idx]; + if (!(r->flags & (IORESOURCE_IO | IORESOURCE_MEM))) + continue; + if ((idx == PCI_ROM_RESOURCE) && + (!(r->flags & IORESOURCE_ROM_ENABLE))) + continue; + if (!r->start && r->end) { + printk(KERN_ERR "PCI: Device %s not available " + "because of resource collisions\n", + pci_name(dev)); + return -EINVAL; + } + if (r->flags & IORESOURCE_IO) + cmd |= PCI_COMMAND_IO; + if (r->flags & IORESOURCE_MEM) + cmd |= PCI_COMMAND_MEMORY; + } + if (cmd != old_cmd) { + printk("PCI: Enabling device %s (%04x -> %04x)\n", + pci_name(dev), old_cmd, cmd); + pci_write_config_word(dev, PCI_COMMAND, cmd); + } + return 0; +} + +int pcibios_enable_device(struct pci_dev *dev, int mask) +{ + int err; + + if ((err = pcibios_enable_resources(dev, mask)) < 0) + return err; + + return pcibios_plat_dev_init(dev); +} + +void pcibios_fixup_bus(struct pci_bus *bus) +{ + struct pci_dev *dev = bus->self; + + if (pci_has_flag(PCI_PROBE_ONLY) && dev && + (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { + pci_read_bridge_bases(bus); + } +} + +char * (*pcibios_plat_setup)(char *str) __initdata; + +char *__init pcibios_setup(char *str) +{ + if (pcibios_plat_setup) + return pcibios_plat_setup(str); + return str; +} diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c index 8cc6ea4..f6325fa 100644 --- a/arch/mips/pci/pci.c +++ b/arch/mips/pci/pci.c @@ -20,205 +20,11 @@ #include -/* - * If PCI_PROBE_ONLY in pci_flags is set, we don't change any PCI resource - * assignments. - */ - -/* - * The PCI controller list. - */ -static LIST_HEAD(controllers); - unsigned long PCIBIOS_MIN_IO; -unsigned long PCIBIOS_MIN_MEM; - -static int pci_initialized; - -/* - * We need to avoid collisions with `mirrored' VGA ports - * and other strange ISA hardware, so we always want the - * addresses to be allocated in the 0x000-0x0ff region - * modulo 0x400. - * - * Why? Because some silly external IO cards only decode - * the low 10 bits of the IO address. The 0x00-0xff region - * is reserved for motherboard devices that decode all 16 - * bits, so it's ok to allocate at, say, 0x2800-0x28ff, - * but we want to try to avoid allocating at 0x2900-0x2bff - * which might have be mirrored at 0x0100-0x03ff.. - */ -resource_size_t -pcibios_align_resource(void *data, const struct resource *res, - resource_size_t size, resource_size_t align) -{ - struct pci_dev *dev = data; - struct pci_controller *hose = dev->sysdata; - resource_size_t start = res->start; - - if (res->flags & IORESOURCE_IO) { - /* Make sure we start at our min on all hoses */ - if (start < PCIBIOS_MIN_IO + hose->io_resource->start) - start = PCIBIOS_MIN_IO + hose->io_resource->start; - - /* - * Put everything into 0x00-0xff region modulo 0x400 - */ - if (start & 0x300) - start = (start + 0x3ff) & ~0x3ff; - } else if (res->flags & IORESOURCE_MEM) { - /* Make sure we start at our min on all hoses */ - if (start < PCIBIOS_MIN_MEM + hose->mem_resource->start) - start = PCIBIOS_MIN_MEM + hose->mem_resource->start; - } - - return start; -} - -static void pcibios_scanbus(struct pci_controller *hose) -{ - static int next_busno; - static int need_domain_info; - LIST_HEAD(resources); - struct pci_bus *bus; - - if (hose->get_busno && pci_has_flag(PCI_PROBE_ONLY)) - next_busno = (*hose->get_busno)(); - - pci_add_resource_offset(&resources, - hose->mem_resource, hose->mem_offset); - pci_add_resource_offset(&resources, - hose->io_resource, hose->io_offset); - pci_add_resource_offset(&resources, - hose->busn_resource, hose->busn_offset); - bus = pci_scan_root_bus(NULL, next_busno, hose->pci_ops, hose, - &resources); - hose->bus = bus; - - need_domain_info = need_domain_info || pci_domain_nr(bus); - set_pci_need_domain_info(hose, need_domain_info); - - if (!bus) { - pci_free_resource_list(&resources); - return; - } - - next_busno = bus->busn_res.end + 1; - /* Don't allow 8-bit bus number overflow inside the hose - - reserve some space for bridges. */ - if (next_busno > 224) { - next_busno = 0; - need_domain_info = 1; - } - - /* - * We insert PCI resources into the iomem_resource and - * ioport_resource trees in either pci_bus_claim_resources() - * or pci_bus_assign_resources(). - */ - if (pci_has_flag(PCI_PROBE_ONLY)) { - pci_bus_claim_resources(bus); - } else { - pci_bus_size_bridges(bus); - pci_bus_assign_resources(bus); - } - pci_bus_add_devices(bus); -} - -#ifdef CONFIG_OF -void pci_load_of_ranges(struct pci_controller *hose, struct device_node *node) -{ - struct of_pci_range range; - struct of_pci_range_parser parser; - - pr_info("PCI host bridge %s ranges:\n", node->full_name); - hose->of_node = node; - - if (of_pci_range_parser_init(&parser, node)) - return; - - for_each_of_pci_range(&parser, &range) { - struct resource *res = NULL; - - switch (range.flags & IORESOURCE_TYPE_BITS) { - case IORESOURCE_IO: - pr_info(" IO 0x%016llx..0x%016llx\n", - range.cpu_addr, - range.cpu_addr + range.size - 1); - hose->io_map_base = - (unsigned long)ioremap(range.cpu_addr, - range.size); - res = hose->io_resource; - break; - case IORESOURCE_MEM: - pr_info(" MEM 0x%016llx..0x%016llx\n", - range.cpu_addr, - range.cpu_addr + range.size - 1); - res = hose->mem_resource; - break; - } - if (res != NULL) - of_pci_range_to_resource(&range, node, res); - } -} - -struct device_node *pcibios_get_phb_of_node(struct pci_bus *bus) -{ - struct pci_controller *hose = bus->sysdata; - - return of_node_get(hose->of_node); -} -#endif - -static DEFINE_MUTEX(pci_scan_mutex); - -void register_pci_controller(struct pci_controller *hose) -{ - struct resource *parent; - - parent = hose->mem_resource->parent; - if (!parent) - parent = &iomem_resource; - - if (request_resource(parent, hose->mem_resource) < 0) - goto out; - - parent = hose->io_resource->parent; - if (!parent) - parent = &ioport_resource; - - if (request_resource(parent, hose->io_resource) < 0) { - release_resource(hose->mem_resource); - goto out; - } - - INIT_LIST_HEAD(&hose->list); - list_add(&hose->list, &controllers); - - /* - * Do not panic here but later - this might happen before console init. - */ - if (!hose->io_map_base) { - printk(KERN_WARNING - "registering PCI controller with io_map_base unset\n"); - } - - /* - * Scan the bus if it is register after the PCI subsystem - * initialization. - */ - if (pci_initialized) { - mutex_lock(&pci_scan_mutex); - pcibios_scanbus(hose); - mutex_unlock(&pci_scan_mutex); - } - - return; +EXPORT_SYMBOL(PCIBIOS_MIN_IO); -out: - printk(KERN_WARNING - "Skipping PCI bus scan due to resource conflict\n"); -} +unsigned long PCIBIOS_MIN_MEM; +EXPORT_SYMBOL(PCIBIOS_MIN_MEM); static int __init pcibios_set_cache_line_size(void) { @@ -242,84 +48,6 @@ static int __init pcibios_set_cache_line_size(void) } arch_initcall(pcibios_set_cache_line_size); -static int __init pcibios_init(void) -{ - struct pci_controller *hose; - - /* Scan all of the recorded PCI controllers. */ - list_for_each_entry(hose, &controllers, list) - pcibios_scanbus(hose); - - pci_fixup_irqs(pci_common_swizzle, pcibios_map_irq); - - pci_initialized = 1; - - return 0; -} - -subsys_initcall(pcibios_init); - -static int pcibios_enable_resources(struct pci_dev *dev, int mask) -{ - u16 cmd, old_cmd; - int idx; - struct resource *r; - - pci_read_config_word(dev, PCI_COMMAND, &cmd); - old_cmd = cmd; - for (idx=0; idx < PCI_NUM_RESOURCES; idx++) { - /* Only set up the requested stuff */ - if (!(mask & (1<resource[idx]; - if (!(r->flags & (IORESOURCE_IO | IORESOURCE_MEM))) - continue; - if ((idx == PCI_ROM_RESOURCE) && - (!(r->flags & IORESOURCE_ROM_ENABLE))) - continue; - if (!r->start && r->end) { - printk(KERN_ERR "PCI: Device %s not available " - "because of resource collisions\n", - pci_name(dev)); - return -EINVAL; - } - if (r->flags & IORESOURCE_IO) - cmd |= PCI_COMMAND_IO; - if (r->flags & IORESOURCE_MEM) - cmd |= PCI_COMMAND_MEMORY; - } - if (cmd != old_cmd) { - printk("PCI: Enabling device %s (%04x -> %04x)\n", - pci_name(dev), old_cmd, cmd); - pci_write_config_word(dev, PCI_COMMAND, cmd); - } - return 0; -} - -int pcibios_enable_device(struct pci_dev *dev, int mask) -{ - int err; - - if ((err = pcibios_enable_resources(dev, mask)) < 0) - return err; - - return pcibios_plat_dev_init(dev); -} - -void pcibios_fixup_bus(struct pci_bus *bus) -{ - struct pci_dev *dev = bus->self; - - if (pci_has_flag(PCI_PROBE_ONLY) && dev && - (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { - pci_read_bridge_bases(bus); - } -} - -EXPORT_SYMBOL(PCIBIOS_MIN_IO); -EXPORT_SYMBOL(PCIBIOS_MIN_MEM); - void pci_resource_to_user(const struct pci_dev *dev, int bar, const struct resource *rsrc, resource_size_t *start, resource_size_t *end) @@ -353,12 +81,3 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, vma->vm_end - vma->vm_start, vma->vm_page_prot); } - -char * (*pcibios_plat_setup)(char *str) __initdata; - -char *__init pcibios_setup(char *str) -{ - if (pcibios_plat_setup) - return pcibios_plat_setup(str); - return str; -} -- cgit v0.10.2 From c5611df968047fb0b38156497b4242730ef66108 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Wed, 5 Oct 2016 18:18:12 +0100 Subject: MIPS: PCI: Introduce CONFIG_PCI_DRIVERS_LEGACY Introduce 2 Kconfig symbols, CONFIG_PCI_DRIVERS_GENERIC & CONFIG_PCI_DRIVERS_LEGACY, which indicate whether the system should be built to for PCI drivers using the MIPS-specific struct pci_controller API (hereafter "legacy" drivers) or more generic drivers using only functionality provided by the PCI core (hereafter "generic" drivers). The Kconfig entries are created such that platforms have to select CONFIG_PCI_DRIVERS_GENERIC if they wish to use it - that is, the default is CONFIG_PCI_DRIVERS_LEGACY so that existing platforms need no modification. The functions declared in pci.h are rearranged with those provided only by pci-legacy.c being guarded by an #ifdef CONFIG_PCI_DRIVERS_LEGACY to ensure they are only used in configurations where they are implemented. Signed-off-by: Paul Burton Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/14345/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 7a75215..d31f839 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -2974,7 +2974,6 @@ config PCI bool "Support for PCI controller" depends on HW_HAS_PCI select PCI_DOMAINS - select NO_GENERIC_PCI_IOPORT_MAP help Find out whether you have a PCI motherboard. PCI is the name of a bus system, i.e. the way the CPU talks to the other stuff inside @@ -2998,6 +2997,13 @@ config PCI_DOMAINS config PCI_DOMAINS_GENERIC bool +config PCI_DRIVERS_GENERIC + bool + +config PCI_DRIVERS_LEGACY + def_bool !PCI_DRIVERS_GENERIC + select NO_GENERIC_PCI_IOPORT_MAP + source "drivers/pci/Kconfig" # diff --git a/arch/mips/include/asm/pci.h b/arch/mips/include/asm/pci.h index acc651e..30d1129 100644 --- a/arch/mips/include/asm/pci.h +++ b/arch/mips/include/asm/pci.h @@ -20,6 +20,8 @@ #include #include +#ifdef CONFIG_PCI_DRIVERS_LEGACY + /* * Each pci channel is a top-level PCI bus seem by CPU. A machine with * multiple PCI channels may have multiple PCI host controllers or a @@ -62,6 +64,35 @@ extern void register_pci_controller(struct pci_controller *hose); */ extern int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin); +/* Do platform specific device initialization at pci_enable_device() time */ +extern int pcibios_plat_dev_init(struct pci_dev *dev); + +extern char * (*pcibios_plat_setup)(char *str); + +#ifdef CONFIG_OF +/* this function parses memory ranges from a device node */ +extern void pci_load_of_ranges(struct pci_controller *hose, + struct device_node *node); +#else +static inline void pci_load_of_ranges(struct pci_controller *hose, + struct device_node *node) {} +#endif + +#ifdef CONFIG_PCI_DOMAINS_GENERIC +static inline void set_pci_need_domain_info(struct pci_controller *hose, + int need_domain_info) +{ + /* nothing to do */ +} +#elif defined(CONFIG_PCI_DOMAINS) +static inline void set_pci_need_domain_info(struct pci_controller *hose, + int need_domain_info) +{ + hose->need_domain_info = need_domain_info; +} +#endif /* CONFIG_PCI_DOMAINS */ + +#endif /* Can be used to override the logic in pci_scan_bus for skipping already-configured bus numbers - to be used for buggy BIOSes @@ -110,12 +141,6 @@ static inline int pci_proc_domain(struct pci_bus *bus) { return pci_domain_nr(bus); } - -static inline void set_pci_need_domain_info(struct pci_controller *hose, - int need_domain_info) -{ - /* nothing to do */ -} #elif defined(CONFIG_PCI_DOMAINS) #define pci_domain_nr(bus) ((struct pci_controller *)(bus)->sysdata)->index @@ -124,12 +149,6 @@ static inline int pci_proc_domain(struct pci_bus *bus) struct pci_controller *hose = bus->sysdata; return hose->need_domain_info; } - -static inline void set_pci_need_domain_info(struct pci_controller *hose, - int need_domain_info) -{ - hose->need_domain_info = need_domain_info; -} #endif /* CONFIG_PCI_DOMAINS */ #endif /* __KERNEL__ */ @@ -143,15 +162,4 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) return channel ? 15 : 14; } -extern char * (*pcibios_plat_setup)(char *str); - -#ifdef CONFIG_OF -/* this function parses memory ranges from a device node */ -extern void pci_load_of_ranges(struct pci_controller *hose, - struct device_node *node); -#else -static inline void pci_load_of_ranges(struct pci_controller *hose, - struct device_node *node) {} -#endif - #endif /* _ASM_PCI_H */ diff --git a/arch/mips/lib/iomap-pci.c b/arch/mips/lib/iomap-pci.c index a629077..8ed3f25 100644 --- a/arch/mips/lib/iomap-pci.c +++ b/arch/mips/lib/iomap-pci.c @@ -10,6 +10,8 @@ #include #include +#ifdef CONFIG_PCI_DRIVERS_LEGACY + void __iomem *__pci_ioport_map(struct pci_dev *dev, unsigned long port, unsigned int nr) { @@ -40,6 +42,8 @@ void __iomem *__pci_ioport_map(struct pci_dev *dev, return (void __iomem *) (ctrl->io_map_base + port); } +#endif /* CONFIG_PCI_DRIVERS_LEGACY */ + void pci_iounmap(struct pci_dev *dev, void __iomem * addr) { iounmap(addr); diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index 5666637..8478210 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile @@ -3,7 +3,7 @@ # obj-y += pci.o -obj-y += pci-legacy.o +obj-$(CONFIG_PCI_DRIVERS_LEGACY)+= pci-legacy.o # # PCI bus host bridge specific code -- cgit v0.10.2 From 87dd9a4de421f052fd9be58c7da08a453f340d5e Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Wed, 5 Oct 2016 18:18:13 +0100 Subject: MIPS: PCI: Support generic drivers Introduce support for PCI drivers using only functionality provided generically by the PCI subsystem, by adding the minimum arch-provided functions required. The driver this has been developed for & tested with the xilinx-pcie on a MIPS Boston development board. Signed-off-by: Paul Burton Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/14346/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index d31f839..86d5b39 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -2998,6 +2998,7 @@ config PCI_DOMAINS_GENERIC bool config PCI_DRIVERS_GENERIC + select PCI_DOMAINS_GENERIC if PCI_DOMAINS bool config PCI_DRIVERS_LEGACY diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index 8478210..4b82148 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile @@ -4,6 +4,7 @@ obj-y += pci.o obj-$(CONFIG_PCI_DRIVERS_LEGACY)+= pci-legacy.o +obj-$(CONFIG_PCI_DRIVERS_GENERIC)+= pci-generic.o # # PCI bus host bridge specific code diff --git a/arch/mips/pci/pci-generic.c b/arch/mips/pci/pci-generic.c new file mode 100644 index 0000000..dce304d --- /dev/null +++ b/arch/mips/pci/pci-generic.c @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2016 Imagination Technologies + * Author: Paul Burton + * + * pcibios_align_resource taken from arch/arm/kernel/bios32.c. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include + +/* + * We need to avoid collisions with `mirrored' VGA ports + * and other strange ISA hardware, so we always want the + * addresses to be allocated in the 0x000-0x0ff region + * modulo 0x400. + * + * Why? Because some silly external IO cards only decode + * the low 10 bits of the IO address. The 0x00-0xff region + * is reserved for motherboard devices that decode all 16 + * bits, so it's ok to allocate at, say, 0x2800-0x28ff, + * but we want to try to avoid allocating at 0x2900-0x2bff + * which might have be mirrored at 0x0100-0x03ff.. + */ +resource_size_t pcibios_align_resource(void *data, const struct resource *res, + resource_size_t size, resource_size_t align) +{ + struct pci_dev *dev = data; + resource_size_t start = res->start; + struct pci_host_bridge *host_bridge; + + if (res->flags & IORESOURCE_IO && start & 0x300) + start = (start + 0x3ff) & ~0x3ff; + + start = (start + align - 1) & ~(align - 1); + + host_bridge = pci_find_host_bridge(dev->bus); + + if (host_bridge->align_resource) + return host_bridge->align_resource(dev, res, + start, size, align); + + return start; +} + +void pcibios_fixup_bus(struct pci_bus *bus) +{ + pci_read_bridge_bases(bus); +} -- cgit v0.10.2 From f23020230e682a43cc4706cabb041bba469df2d6 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Wed, 5 Oct 2016 18:18:14 +0100 Subject: MIPS: Sanitise coherentio semantics The coherentio variable has previously been used as a boolean value, indicating whether the user specified that coherent I/O should be enabled or disabled. It failed to take into account the case where the user does not specify any preference, in which case it makes sense that we should default to coherent I/O if the hardware supports it (hw_coherentio is non-zero). Introduce an enum to clarify the 3 different values of coherentio & use it throughout the code, modifying plat_device_is_coherent() & r4k_cache_init() to take into account the default case. Signed-off-by: Paul Burton Cc: linux-mips@linux-mips.org Cc: Paul Burton Patchwork: https://patchwork.linux-mips.org/patch/14347/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/alchemy/common/setup.c b/arch/mips/alchemy/common/setup.c index 2902138..7faaa6d 100644 --- a/arch/mips/alchemy/common/setup.c +++ b/arch/mips/alchemy/common/setup.c @@ -48,17 +48,17 @@ void __init plat_mem_setup(void) clear_c0_config(1 << 19); /* Clear Config[OD] */ hw_coherentio = 0; - coherentio = 1; + coherentio = IO_COHERENCE_ENABLED; switch (alchemy_get_cputype()) { case ALCHEMY_CPU_AU1000: case ALCHEMY_CPU_AU1500: case ALCHEMY_CPU_AU1100: - coherentio = 0; + coherentio = IO_COHERENCE_DISABLED; break; case ALCHEMY_CPU_AU1200: /* Au1200 AB USB does not support coherent memory */ if (0 == (read_c0_prid() & PRID_REV_MASK)) - coherentio = 0; + coherentio = IO_COHERENCE_DISABLED; break; } diff --git a/arch/mips/include/asm/dma-coherence.h b/arch/mips/include/asm/dma-coherence.h index bc5e85d..4fbce79 100644 --- a/arch/mips/include/asm/dma-coherence.h +++ b/arch/mips/include/asm/dma-coherence.h @@ -9,14 +9,20 @@ #ifndef __ASM_DMA_COHERENCE_H #define __ASM_DMA_COHERENCE_H +enum coherent_io_user_state { + IO_COHERENCE_DEFAULT, + IO_COHERENCE_ENABLED, + IO_COHERENCE_DISABLED, +}; + #ifdef CONFIG_DMA_MAYBE_COHERENT -extern int coherentio; +extern enum coherent_io_user_state coherentio; extern int hw_coherentio; #else #ifdef CONFIG_DMA_COHERENT -#define coherentio 1 +#define coherentio IO_COHERENCE_ENABLED #else -#define coherentio 0 +#define coherentio IO_COHERENCE_DISABLED #endif #define hw_coherentio 0 #endif /* CONFIG_DMA_MAYBE_COHERENT */ diff --git a/arch/mips/include/asm/mach-generic/dma-coherence.h b/arch/mips/include/asm/mach-generic/dma-coherence.h index 0f8a354..8484f82 100644 --- a/arch/mips/include/asm/mach-generic/dma-coherence.h +++ b/arch/mips/include/asm/mach-generic/dma-coherence.h @@ -49,7 +49,15 @@ static inline int plat_dma_supported(struct device *dev, u64 mask) static inline int plat_device_is_coherent(struct device *dev) { - return coherentio; + switch (coherentio) { + default: + case IO_COHERENCE_DEFAULT: + return hw_coherentio; + case IO_COHERENCE_ENABLED: + return 1; + case IO_COHERENCE_DISABLED: + return 0; + } } #ifndef plat_post_dma_flush diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index 1fc1118..78ac033 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -1935,7 +1935,8 @@ void r4k_cache_init(void) __local_flush_icache_user_range = local_r4k_flush_icache_user_range; #if defined(CONFIG_DMA_NONCOHERENT) || defined(CONFIG_DMA_MAYBE_COHERENT) - if (coherentio) { + if ((coherentio == IO_COHERENCE_ENABLED) || + ((coherentio == IO_COHERENCE_DEFAULT) && hw_coherentio)) { _dma_cache_wback_inv = (void *)cache_noop; _dma_cache_wback = (void *)cache_noop; _dma_cache_inv = (void *)cache_noop; diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index 755259c..8b86c61 100644 --- a/arch/mips/mm/dma-default.c +++ b/arch/mips/mm/dma-default.c @@ -25,13 +25,14 @@ #include #ifdef CONFIG_DMA_MAYBE_COHERENT -int coherentio = 0; /* User defined DMA coherency from command line. */ +/* User defined DMA coherency from command line. */ +enum coherent_io_user_state coherentio = IO_COHERENCE_DEFAULT; EXPORT_SYMBOL_GPL(coherentio); int hw_coherentio = 0; /* Actual hardware supported DMA coherency setting. */ static int __init setcoherentio(char *str) { - coherentio = 1; + coherentio = IO_COHERENCE_ENABLED; pr_info("Hardware DMA cache coherency (command line)\n"); return 0; } @@ -39,7 +40,7 @@ early_param("coherentio", setcoherentio); static int __init setnocoherentio(char *str) { - coherentio = 0; + coherentio = IO_COHERENCE_DISABLED; pr_info("Software DMA cache coherency (command line)\n"); return 0; } diff --git a/arch/mips/mti-malta/malta-setup.c b/arch/mips/mti-malta/malta-setup.c index 7e7364b..f1b60748 100644 --- a/arch/mips/mti-malta/malta-setup.c +++ b/arch/mips/mti-malta/malta-setup.c @@ -154,12 +154,12 @@ static void __init plat_setup_iocoherency(void) * coherency instead. */ if (plat_enable_iocoherency()) { - if (coherentio == 0) + if (coherentio == IO_COHERENCE_DISABLED) pr_info("Hardware DMA cache coherency disabled\n"); else pr_info("Hardware DMA cache coherency enabled\n"); } else { - if (coherentio == 1) + if (coherentio == IO_COHERENCE_ENABLED) pr_info("Hardware DMA cache coherency unsupported, but enabled from command line!\n"); else pr_info("Software DMA cache coherency enabled\n"); diff --git a/arch/mips/pci/pci-alchemy.c b/arch/mips/pci/pci-alchemy.c index c8994c1..e99ca77 100644 --- a/arch/mips/pci/pci-alchemy.c +++ b/arch/mips/pci/pci-alchemy.c @@ -429,7 +429,8 @@ static int alchemy_pci_probe(struct platform_device *pdev) /* Au1500 revisions older than AD have borked coherent PCI */ if ((alchemy_get_cputype() == ALCHEMY_CPU_AU1500) && - (read_c0_prid() < 0x01030202) && !coherentio) { + (read_c0_prid() < 0x01030202) && + (coherentio == IO_COHERENCE_DISABLED)) { val = __raw_readl(ctx->regs + PCI_REG_CONFIG); val |= PCI_CONFIG_NC; __raw_writel(val, ctx->regs + PCI_REG_CONFIG); -- cgit v0.10.2 From cfa93fb9c2eae805f2c16d72bad04ca49b6e16d2 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Wed, 5 Oct 2016 18:18:15 +0100 Subject: MIPS: dma-default: Don't check hw_coherentio if device is non-coherent There are no cases where plat_device_is_coherent() will return zero whilst hw_coherentio is non-zero, and acting any differently in such a case doesn't make much sense - if a device is non-coherent with the CPU caches then access to memory "coherent" with DMA must be uncached. Clean up the nonsensical case. Signed-off-by: Paul Burton Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/14348/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index 8b86c61..7ae4c55 100644 --- a/arch/mips/mm/dma-default.c +++ b/arch/mips/mm/dma-default.c @@ -161,8 +161,7 @@ static void *mips_dma_alloc_coherent(struct device *dev, size_t size, *dma_handle = plat_map_dma_mem(dev, ret, size); if (!plat_device_is_coherent(dev)) { dma_cache_wback_inv((unsigned long) ret, size); - if (!hw_coherentio) - ret = UNCAC_ADDR(ret); + ret = UNCAC_ADDR(ret); } return ret; @@ -190,7 +189,7 @@ static void mips_dma_free_coherent(struct device *dev, size_t size, void *vaddr, plat_unmap_dma_mem(dev, dma_handle, size, DMA_BIDIRECTIONAL); - if (!plat_device_is_coherent(dev) && !hw_coherentio) + if (!plat_device_is_coherent(dev)) addr = CAC_ADDR(addr); page = virt_to_page((void *) addr); @@ -210,7 +209,7 @@ static int mips_dma_mmap(struct device *dev, struct vm_area_struct *vma, unsigned long pfn; int ret = -ENXIO; - if (!plat_device_is_coherent(dev) && !hw_coherentio) + if (!plat_device_is_coherent(dev)) addr = CAC_ADDR(addr); pfn = page_to_pfn(virt_to_page((void *)addr)); -- cgit v0.10.2 From 20d330645cfb8cfecfb82b369e4d3084e429e68a Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Wed, 5 Oct 2016 18:18:16 +0100 Subject: MIPS: Support per-device DMA coherence On some MIPS systems, a subset of devices may have DMA coherent with CPU caches. For example in systems including a MIPS I/O Coherence Unit (IOCU), some devices may be connected to that IOCU whilst others are not. Prior to this patch, we have a plat_device_is_coherent() function but no implementation which does anything besides return a global true or false, optionally chosen at runtime. For devices such as those described above this is insufficient. Fix this by tracking DMA coherence on a per-device basis with a dma_coherent field in struct dev_archdata. Setting this from arch_setup_dma_ops() takes care of devices which set the dma-coherent property via device tree, and any PCI devices beneath a bridge described in DT, automatically. Signed-off-by: Paul Burton Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/14349/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 86d5b39..2356439 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -1099,6 +1099,10 @@ config DMA_MAYBE_COHERENT select DMA_NONCOHERENT bool +config DMA_PERDEV_COHERENT + bool + select DMA_MAYBE_COHERENT + config DMA_COHERENT bool diff --git a/arch/mips/include/asm/device.h b/arch/mips/include/asm/device.h index c94fafb..21c2082 100644 --- a/arch/mips/include/asm/device.h +++ b/arch/mips/include/asm/device.h @@ -11,6 +11,11 @@ struct dma_map_ops; struct dev_archdata { /* DMA operations on that device */ struct dma_map_ops *dma_ops; + +#ifdef CONFIG_DMA_PERDEV_COHERENT + /* Non-zero if DMA is coherent with CPU caches */ + bool dma_coherent; +#endif }; struct pdev_archdata { diff --git a/arch/mips/include/asm/dma-coherence.h b/arch/mips/include/asm/dma-coherence.h index 4fbce79..72d0eab 100644 --- a/arch/mips/include/asm/dma-coherence.h +++ b/arch/mips/include/asm/dma-coherence.h @@ -15,7 +15,9 @@ enum coherent_io_user_state { IO_COHERENCE_DISABLED, }; -#ifdef CONFIG_DMA_MAYBE_COHERENT +#if defined(CONFIG_DMA_PERDEV_COHERENT) +/* Don't provide (hw_)coherentio to avoid misuse */ +#elif defined(CONFIG_DMA_MAYBE_COHERENT) extern enum coherent_io_user_state coherentio; extern int hw_coherentio; #else diff --git a/arch/mips/include/asm/dma-mapping.h b/arch/mips/include/asm/dma-mapping.h index 12fa79e..7aa71b9 100644 --- a/arch/mips/include/asm/dma-mapping.h +++ b/arch/mips/include/asm/dma-mapping.h @@ -32,4 +32,14 @@ static inline void dma_mark_clean(void *addr, size_t size) {} extern void dma_cache_sync(struct device *dev, void *vaddr, size_t size, enum dma_data_direction direction); +#define arch_setup_dma_ops arch_setup_dma_ops +static inline void arch_setup_dma_ops(struct device *dev, u64 dma_base, + u64 size, const struct iommu_ops *iommu, + bool coherent) +{ +#ifdef CONFIG_DMA_PERDEV_COHERENT + dev->archdata.dma_coherent = coherent; +#endif +} + #endif /* _ASM_DMA_MAPPING_H */ diff --git a/arch/mips/include/asm/mach-generic/dma-coherence.h b/arch/mips/include/asm/mach-generic/dma-coherence.h index 8484f82..61addb1 100644 --- a/arch/mips/include/asm/mach-generic/dma-coherence.h +++ b/arch/mips/include/asm/mach-generic/dma-coherence.h @@ -49,6 +49,9 @@ static inline int plat_dma_supported(struct device *dev, u64 mask) static inline int plat_device_is_coherent(struct device *dev) { +#ifdef CONFIG_DMA_PERDEV_COHERENT + return dev->archdata.dma_coherent; +#else switch (coherentio) { default: case IO_COHERENCE_DEFAULT: @@ -58,6 +61,7 @@ static inline int plat_device_is_coherent(struct device *dev) case IO_COHERENCE_DISABLED: return 0; } +#endif } #ifndef plat_post_dma_flush diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index 78ac033..88cfaf8 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -1935,8 +1935,12 @@ void r4k_cache_init(void) __local_flush_icache_user_range = local_r4k_flush_icache_user_range; #if defined(CONFIG_DMA_NONCOHERENT) || defined(CONFIG_DMA_MAYBE_COHERENT) +# if defined(CONFIG_DMA_PERDEV_COHERENT) + if (0) { +# else if ((coherentio == IO_COHERENCE_ENABLED) || ((coherentio == IO_COHERENCE_DEFAULT) && hw_coherentio)) { +# endif _dma_cache_wback_inv = (void *)cache_noop; _dma_cache_wback = (void *)cache_noop; _dma_cache_inv = (void *)cache_noop; diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index 7ae4c55..46d5696 100644 --- a/arch/mips/mm/dma-default.c +++ b/arch/mips/mm/dma-default.c @@ -24,7 +24,7 @@ #include -#ifdef CONFIG_DMA_MAYBE_COHERENT +#if defined(CONFIG_DMA_MAYBE_COHERENT) && !defined(CONFIG_DMA_PERDEV_COHERENT) /* User defined DMA coherency from command line. */ enum coherent_io_user_state coherentio = IO_COHERENCE_DEFAULT; EXPORT_SYMBOL_GPL(coherentio); -- cgit v0.10.2 From dabdc1853d59b355eaa679b8856016a7366da9af Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Wed, 5 Oct 2016 18:18:17 +0100 Subject: MIPS: Print CM error reports upon bus errors If a bus error occurs on a system with a MIPS Coherence Manager (CM) then the CM may hold useful diagnostic information. Printing this out has so far been left up to boards, with the requirement that they register a board_be_handler function & call mips_cm_error_decode() from there. In order to avoid boards other than Malta needing to duplicate this code, call mips_cm_error_decode() automatically if the board registers no board_be_handler, and remove the Malta implementation of that. This patch results in no functional change, but removes a further piece of platform-specific code. Signed-off-by: Paul Burton Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/14350/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 0c0270c..1f5fdee 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -445,6 +446,8 @@ asmlinkage void do_be(struct pt_regs *regs) if (board_be_handler) action = board_be_handler(regs, fixup != NULL); + else + mips_cm_error_report(); switch (action) { case MIPS_BE_DISCARD: diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c index 9f83224..cb675ec 100644 --- a/arch/mips/mti-malta/malta-int.c +++ b/arch/mips/mti-malta/malta-int.c @@ -290,18 +290,3 @@ void __init arch_init_irq(void) setup_irq(corehi_irq, &corehi_irqaction); } - -void malta_be_init(void) -{ - /* Could change CM error mask register. */ -} - -int malta_be_handler(struct pt_regs *regs, int is_fixup) -{ - /* This duplicates the handling in do_be which seems wrong */ - int retval = is_fixup ? MIPS_BE_FIXUP : MIPS_BE_FATAL; - - mips_cm_error_report(); - - return retval; -} diff --git a/arch/mips/mti-malta/malta-setup.c b/arch/mips/mti-malta/malta-setup.c index f1b60748..a01d5de 100644 --- a/arch/mips/mti-malta/malta-setup.c +++ b/arch/mips/mti-malta/malta-setup.c @@ -42,9 +42,6 @@ #define ROCIT_CONFIG_GEN0 0x1f403000 #define ROCIT_CONFIG_GEN0_PCI_IOCU BIT(7) -extern void malta_be_init(void); -extern int malta_be_handler(struct pt_regs *regs, int is_fixup); - static struct resource standard_io_resources[] = { { .name = "dma1", @@ -301,7 +298,4 @@ void __init plat_mem_setup(void) #if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE) screen_info_setup(); #endif - - board_be_init = malta_be_init; - board_be_handler = malta_be_handler; } -- cgit v0.10.2 From 3ffc17d8768be705e292ac4c2e3ab1f18dc06047 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Wed, 5 Oct 2016 18:18:18 +0100 Subject: MIPS: Adjust MIPS64 CAC_BASE to reflect Config.K0 On MIPS64 we define the default CAC_BASE as one of the xkphys regions of the virtual address space. Since the CCA is encoded in bits 61:59 of xkphys addresses, fixing CAC_BASE to any particular one prevents us from dynamically changing the CCA as we do for MIPS32 where CAC_BASE is placed within kseg0. In order to make the kernel more generic, drop the current kludge that gives CAC_BASE CCA=3 if CONFIG_DMA_NONCOHERENT is selected (disregarding CONFIG_DMA_MAYBE_COHERENT) & CCA=5 (which is not standardised by the architecture) otherwise. Instead read Config.K0 and generate the appropriate offset into xkphys, presuming that either the bootloader or early kernel code will have configured Config.K0 appropriately. This seems like the best option for a generic implementation. The ip27 spaces.h is adjusted to set its former value of CAC_BASE, since it's the only user of CAC_BASE from assembly (in its smp_slave_setup macro). This allows the generic case to focus solely on C code without breaking ip27. Signed-off-by: Paul Burton Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/14351/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/include/asm/addrspace.h b/arch/mips/include/asm/addrspace.h index c5b04e7..4856adc 100644 --- a/arch/mips/include/asm/addrspace.h +++ b/arch/mips/include/asm/addrspace.h @@ -126,8 +126,7 @@ #define PHYS_TO_XKSEG_UNCACHED(p) PHYS_TO_XKPHYS(K_CALG_UNCACHED, (p)) #define PHYS_TO_XKSEG_CACHED(p) PHYS_TO_XKPHYS(K_CALG_COH_SHAREABLE, (p)) #define XKPHYS_TO_PHYS(p) ((p) & TO_PHYS_MASK) -#define PHYS_TO_XKPHYS(cm, a) (_CONST64_(0x8000000000000000) | \ - (_CONST64_(cm) << 59) | (a)) +#define PHYS_TO_XKPHYS(cm, a) (XKPHYS | (_ACAST64_(cm) << 59) | (a)) /* * The ultimate limited of the 64-bit MIPS architecture: 2 bits for selecting diff --git a/arch/mips/include/asm/mach-generic/spaces.h b/arch/mips/include/asm/mach-generic/spaces.h index afc96ec..952b0fd 100644 --- a/arch/mips/include/asm/mach-generic/spaces.h +++ b/arch/mips/include/asm/mach-generic/spaces.h @@ -12,6 +12,8 @@ #include +#include + /* * This gives the physical RAM offset. */ @@ -52,11 +54,7 @@ #ifdef CONFIG_64BIT #ifndef CAC_BASE -#ifdef CONFIG_DMA_NONCOHERENT -#define CAC_BASE _AC(0x9800000000000000, UL) -#else -#define CAC_BASE _AC(0xa800000000000000, UL) -#endif +#define CAC_BASE PHYS_TO_XKPHYS(read_c0_config() & CONF_CM_CMASK, 0) #endif #ifndef IO_BASE diff --git a/arch/mips/include/asm/mach-ip27/spaces.h b/arch/mips/include/asm/mach-ip27/spaces.h index b18802a..4775a11 100644 --- a/arch/mips/include/asm/mach-ip27/spaces.h +++ b/arch/mips/include/asm/mach-ip27/spaces.h @@ -19,6 +19,7 @@ #define IO_BASE 0x9200000000000000 #define MSPEC_BASE 0x9400000000000000 #define UNCAC_BASE 0x9600000000000000 +#define CAC_BASE 0xa800000000000000 #define TO_MSPEC(x) (MSPEC_BASE | ((x) & TO_PHYS_MASK)) #define TO_HSPEC(x) (HSPEC_BASE | ((x) & TO_PHYS_MASK)) -- cgit v0.10.2 From cf2a5e0bb4c66e8c43caf9f1be93a1bd7fd07b17 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Wed, 5 Oct 2016 18:18:19 +0100 Subject: MIPS: Support generating Flattened Image Trees (.itb) Add support for generating kernel images in the Flattened Image Tree (.itb) format as supported by U-Boot. This format is essentially a Flattened Device Tree binary containing images (kernels, DTBs, ramdisks) and configurations which link those images together. The big advantages of FIT images over the uImage format are: - We can include FDTs in the kernel image in a way that the bootloader can extract it & manipulate it before providing it to the kernel. Thus we can ship FDTs as part of the kernel giving us the advantages of being able to develop & maintain the DT within the kernel tree, but also have the benefits of the bootloader being able to manipulate the FDT. Example uses for this would be to inject the kernel command line into the chosen node, or to fill in the correct memory size. - We can include multiple configurations in a single kernel image. This means that a single FIT image can, given appropriate bootloaders, be booted on different boards with the bootloader selecting an appropriate configuration & providing the correct FDT to the kernel. - We can support a multitude of hashes over the data. Signed-off-by: Paul Burton Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/14352/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 598ab29..691a6e1 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -262,7 +262,8 @@ KBUILD_CPPFLAGS += -DVMLINUX_LOAD_ADDRESS=$(load-y) KBUILD_CPPFLAGS += -DDATAOFFSET=$(if $(dataoffset-y),$(dataoffset-y),0) bootvars-y = VMLINUX_LOAD_ADDRESS=$(load-y) \ - VMLINUX_ENTRY_ADDRESS=$(entry-y) + VMLINUX_ENTRY_ADDRESS=$(entry-y) \ + PLATFORM=$(platform-y) LDFLAGS += -m $(ld-emul) @@ -302,6 +303,11 @@ boot-y += uImage.gz boot-y += uImage.lzma boot-y += uImage.lzo endif +boot-y += vmlinux.itb +boot-y += vmlinux.gz.itb +boot-y += vmlinux.bz2.itb +boot-y += vmlinux.lzma.itb +boot-y += vmlinux.lzo.itb # compressed boot image targets (arch/mips/boot/compressed/) bootz-y := vmlinuz diff --git a/arch/mips/boot/Makefile b/arch/mips/boot/Makefile index acb1988..ed65663 100644 --- a/arch/mips/boot/Makefile +++ b/arch/mips/boot/Makefile @@ -100,3 +100,60 @@ $(obj)/uImage.lzo: $(obj)/vmlinux.bin.lzo FORCE $(obj)/uImage: $(obj)/uImage.$(suffix-y) @ln -sf $(notdir $<) $@ @echo ' Image $@ is ready' + +# +# Flattened Image Tree (.itb) images +# + +targets += vmlinux.itb +targets += vmlinux.gz.itb +targets += vmlinux.bz2.itb +targets += vmlinux.lzma.itb +targets += vmlinux.lzo.itb + +quiet_cmd_cpp_its_S = ITS $@ + cmd_cpp_its_S = $(CPP) $(cpp_flags) -P -C -o $@ $< \ + -DKERNEL_NAME="\"Linux $(KERNELRELEASE)\"" \ + -DVMLINUX_BINARY="\"$(3)\"" \ + -DVMLINUX_COMPRESSION="\"$(2)\"" \ + -DVMLINUX_LOAD_ADDRESS=$(VMLINUX_LOAD_ADDRESS) \ + -DVMLINUX_ENTRY_ADDRESS=$(VMLINUX_ENTRY_ADDRESS) + +$(obj)/vmlinux.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S FORCE + $(call if_changed_dep,cpp_its_S,none,vmlinux.bin) + +$(obj)/vmlinux.gz.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S FORCE + $(call if_changed_dep,cpp_its_S,gzip,vmlinux.bin.gz) + +$(obj)/vmlinux.bz2.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S FORCE + $(call if_changed_dep,cpp_its_S,bzip2,vmlinux.bin.bz2) + +$(obj)/vmlinux.lzma.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S FORCE + $(call if_changed_dep,cpp_its_S,lzma,vmlinux.bin.lzma) + +$(obj)/vmlinux.lzo.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S FORCE + $(call if_changed_dep,cpp_its_S,lzo,vmlinux.bin.lzo) + +quiet_cmd_itb-image = ITB $@ + cmd_itb-image = \ + env PATH="$(objtree)/scripts/dtc:$(PATH)" \ + $(CONFIG_SHELL) $(MKIMAGE) \ + -D "-I dts -O dtb -p 500 \ + --include $(objtree)/arch/mips \ + --warning no-unit_address_vs_reg" \ + -f $(2) $@ + +$(obj)/vmlinux.itb: $(obj)/vmlinux.its $(obj)/vmlinux.bin FORCE + $(call if_changed,itb-image,$<) + +$(obj)/vmlinux.gz.itb: $(obj)/vmlinux.gz.its $(obj)/vmlinux.bin.gz FORCE + $(call if_changed,itb-image,$<) + +$(obj)/vmlinux.bz2.itb: $(obj)/vmlinux.bz2.its $(obj)/vmlinux.bin.bz2 FORCE + $(call if_changed,itb-image,$<) + +$(obj)/vmlinux.lzma.itb: $(obj)/vmlinux.lzma.its $(obj)/vmlinux.bin.lzma FORCE + $(call if_changed,itb-image,$<) + +$(obj)/vmlinux.lzo.itb: $(obj)/vmlinux.lzo.its $(obj)/vmlinux.bin.lzo FORCE + $(call if_changed,itb-image,$<) -- cgit v0.10.2 From eed0eabd12ef061821cbfa20d903476e07645320 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Wed, 5 Oct 2016 18:18:20 +0100 Subject: MIPS: generic: Introduce generic DT-based board support Introduce a "generic" platform, which aims to be board-agnostic by making use of device trees passed by the boot protocol defined in the MIPS UHI (Universal Hosting Interface) specification. Provision is made for supporting boards which use a legacy boot protocol that can't be changed, but adding support for such boards or any others is left to followon patches. Right now the built kernels expect to be loaded to 0x80100000, ie. in kseg0. This is fine for the vast majority of MIPS platforms, but nevertheless it would be good to remove this limitation in the future by mapping the kernel via the TLB such that it can be loaded anywhere & map itself appropriately. Configuration is handled by dynamically generating configs using scripts/kconfig/merge_config.sh, somewhat similar to the way powerpc makes use of it. This allows for variations upon the configuration, eg. differing architecture revisions or subsets of driver support for differing boards, to be handled without having a large number of defconfig files. Signed-off-by: Paul Burton Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/14353/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/Kbuild.platforms b/arch/mips/Kbuild.platforms index c5cd63a..9c1e8f9 100644 --- a/arch/mips/Kbuild.platforms +++ b/arch/mips/Kbuild.platforms @@ -11,6 +11,7 @@ platforms += cavium-octeon platforms += cobalt platforms += dec platforms += emma +platforms += generic platforms += jazz platforms += jz4740 platforms += lantiq diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 2356439..82b45dc 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -73,6 +73,57 @@ choice prompt "System type" default SGI_IP22 +config MIPS_GENERIC + bool "Generic board-agnostic MIPS kernel" + select BOOT_RAW + select BUILTIN_DTB + select CEVT_R4K + select CLKSRC_MIPS_GIC + select COMMON_CLK + select CPU_MIPSR2_IRQ_VI + select CPU_MIPSR2_IRQ_EI + select CSRC_R4K + select DMA_PERDEV_COHERENT + select HW_HAS_PCI + select IRQ_MIPS_CPU + select LIBFDT + select MIPS_CPU_SCACHE + select MIPS_GIC + select MIPS_L1_CACHE_SHIFT_7 + select NO_EXCEPT_FILL + select PCI_DRIVERS_GENERIC + select PINCTRL + select SMP_UP if SMP + select SYS_HAS_CPU_MIPS32_R1 + select SYS_HAS_CPU_MIPS32_R2 + select SYS_HAS_CPU_MIPS32_R6 + select SYS_HAS_CPU_MIPS64_R1 + select SYS_HAS_CPU_MIPS64_R2 + select SYS_HAS_CPU_MIPS64_R6 + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_64BIT_KERNEL + select SYS_SUPPORTS_BIG_ENDIAN + select SYS_SUPPORTS_HIGHMEM + select SYS_SUPPORTS_LITTLE_ENDIAN + select SYS_SUPPORTS_MICROMIPS + select SYS_SUPPORTS_MIPS_CPS + select SYS_SUPPORTS_MIPS16 + select SYS_SUPPORTS_MULTITHREADING + select SYS_SUPPORTS_RELOCATABLE + select SYS_SUPPORTS_SMARTMIPS + select USB_EHCI_BIG_ENDIAN_DESC if BIG_ENDIAN + select USB_EHCI_BIG_ENDIAN_MMIO if BIG_ENDIAN + select USB_OHCI_BIG_ENDIAN_DESC if BIG_ENDIAN + select USB_OHCI_BIG_ENDIAN_MMIO if BIG_ENDIAN + select USB_UHCI_BIG_ENDIAN_DESC if BIG_ENDIAN + select USB_UHCI_BIG_ENDIAN_MMIO if BIG_ENDIAN + select USE_OF + help + Select this to build a kernel which aims to support multiple boards, + generally using a flattened device tree passed from the bootloader + using the boot protocol defined in the UHI (Unified Hosting + Interface) specification. + config MIPS_ALCHEMY bool "Alchemy processor based machines" select ARCH_PHYS_ADDR_T_64BIT @@ -989,6 +1040,7 @@ source "arch/mips/ath79/Kconfig" source "arch/mips/bcm47xx/Kconfig" source "arch/mips/bcm63xx/Kconfig" source "arch/mips/bmips/Kconfig" +source "arch/mips/generic/Kconfig" source "arch/mips/jazz/Kconfig" source "arch/mips/jz4740/Kconfig" source "arch/mips/lantiq/Kconfig" diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 691a6e1..f3e768a 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -264,6 +264,12 @@ KBUILD_CPPFLAGS += -DDATAOFFSET=$(if $(dataoffset-y),$(dataoffset-y),0) bootvars-y = VMLINUX_LOAD_ADDRESS=$(load-y) \ VMLINUX_ENTRY_ADDRESS=$(entry-y) \ PLATFORM=$(platform-y) +ifdef CONFIG_32BIT +bootvars-y += ADDR_BITS=32 +endif +ifdef CONFIG_64BIT +bootvars-y += ADDR_BITS=64 +endif LDFLAGS += -m $(ld-emul) @@ -431,4 +437,54 @@ define archhelp echo ' dtbs_install - Install dtbs to $(INSTALL_DTBS_PATH)' echo echo ' These will be default as appropriate for a configured platform.' + echo + echo ' If you are targeting a system supported by generic kernels you may' + echo ' configure the kernel for a given architecture target like so:' + echo + echo ' {micro32,32,64}{r1,r2,r6}{el,}_defconfig ' + echo + echo ' Otherwise, the following default configurations are available:' endef + +generic_config_dir = $(srctree)/arch/$(ARCH)/configs/generic +generic_defconfigs := + +# +# If the user generates a generic kernel configuration without specifying a +# list of boards to include the config fragments for, default to including all +# available board config fragments. +# +ifeq ($(BOARDS),) +BOARDS = $(patsubst board-%.config,%,$(notdir $(wildcard $(generic_config_dir)/board-*.config))) +endif + +# +# Generic kernel configurations which merge generic_defconfig with the +# appropriate config fragments from arch/mips/configs/generic/, resulting in +# the ability to easily configure the kernel for a given architecture, +# endianness & set of boards without duplicating the needed configuration in +# hundreds of defconfig files. +# +define gen_generic_defconfigs +$(foreach bits,$(1),$(foreach rev,$(2),$(foreach endian,$(3), +target := $(bits)$(rev)$(filter el,$(endian))_defconfig +generic_defconfigs += $$(target) +$$(target): $(generic_config_dir)/$(bits)$(rev).config +$$(target): $(generic_config_dir)/$(endian).config +))) +endef + +$(eval $(call gen_generic_defconfigs,32 64,r1 r2 r6,eb el)) +$(eval $(call gen_generic_defconfigs,micro32,r2,eb el)) + +.PHONY: $(generic_defconfigs) +$(generic_defconfigs): + $(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh \ + -m -O $(objtree) $(srctree)/arch/$(ARCH)/configs/generic_defconfig $^ \ + $(foreach board,$(BOARDS),$(generic_config_dir)/board-$(board).config) + $(Q)$(MAKE) olddefconfig + +# +# Prevent generic merge_config rules attempting to merge single fragments +# +$(generic_config_dir)/%.config: ; diff --git a/arch/mips/boot/Makefile b/arch/mips/boot/Makefile index ed65663..2728a9a 100644 --- a/arch/mips/boot/Makefile +++ b/arch/mips/boot/Makefile @@ -111,13 +111,22 @@ targets += vmlinux.bz2.itb targets += vmlinux.lzma.itb targets += vmlinux.lzo.itb +ifeq ($(ADDR_BITS),32) + itb_addr_cells = 1 +endif +ifeq ($(ADDR_BITS),64) + itb_addr_cells = 2 +endif + quiet_cmd_cpp_its_S = ITS $@ cmd_cpp_its_S = $(CPP) $(cpp_flags) -P -C -o $@ $< \ -DKERNEL_NAME="\"Linux $(KERNELRELEASE)\"" \ -DVMLINUX_BINARY="\"$(3)\"" \ -DVMLINUX_COMPRESSION="\"$(2)\"" \ -DVMLINUX_LOAD_ADDRESS=$(VMLINUX_LOAD_ADDRESS) \ - -DVMLINUX_ENTRY_ADDRESS=$(VMLINUX_ENTRY_ADDRESS) + -DVMLINUX_ENTRY_ADDRESS=$(VMLINUX_ENTRY_ADDRESS) \ + -DADDR_BITS=$(ADDR_BITS) \ + -DADDR_CELLS=$(itb_addr_cells) $(obj)/vmlinux.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S FORCE $(call if_changed_dep,cpp_its_S,none,vmlinux.bin) diff --git a/arch/mips/configs/generic/32r1.config b/arch/mips/configs/generic/32r1.config new file mode 100644 index 0000000..a11cd87 --- /dev/null +++ b/arch/mips/configs/generic/32r1.config @@ -0,0 +1,2 @@ +CONFIG_CPU_MIPS32_R1=y +CONFIG_HIGHMEM=y diff --git a/arch/mips/configs/generic/32r2.config b/arch/mips/configs/generic/32r2.config new file mode 100644 index 0000000..9570672 --- /dev/null +++ b/arch/mips/configs/generic/32r2.config @@ -0,0 +1,3 @@ +CONFIG_CPU_MIPS32_R2=y +CONFIG_MIPS_O32_FP64_SUPPORT=y +CONFIG_HIGHMEM=y diff --git a/arch/mips/configs/generic/32r6.config b/arch/mips/configs/generic/32r6.config new file mode 100644 index 0000000..ca606e7 --- /dev/null +++ b/arch/mips/configs/generic/32r6.config @@ -0,0 +1,2 @@ +CONFIG_CPU_MIPS32_R6=y +CONFIG_HIGHMEM=y diff --git a/arch/mips/configs/generic/64r1.config b/arch/mips/configs/generic/64r1.config new file mode 100644 index 0000000..7c1ea7e --- /dev/null +++ b/arch/mips/configs/generic/64r1.config @@ -0,0 +1,4 @@ +CONFIG_CPU_MIPS64_R1=y +CONFIG_64BIT=y +CONFIG_MIPS32_O32=y +CONFIG_MIPS32_N32=y diff --git a/arch/mips/configs/generic/64r2.config b/arch/mips/configs/generic/64r2.config new file mode 100644 index 0000000..b4d31ae --- /dev/null +++ b/arch/mips/configs/generic/64r2.config @@ -0,0 +1,5 @@ +CONFIG_CPU_MIPS64_R2=y +CONFIG_MIPS_O32_FP64_SUPPORT=y +CONFIG_64BIT=y +CONFIG_MIPS32_O32=y +CONFIG_MIPS32_N32=y diff --git a/arch/mips/configs/generic/64r6.config b/arch/mips/configs/generic/64r6.config new file mode 100644 index 0000000..7cac033 --- /dev/null +++ b/arch/mips/configs/generic/64r6.config @@ -0,0 +1,4 @@ +CONFIG_CPU_MIPS64_R6=y +CONFIG_64BIT=y +CONFIG_MIPS32_O32=y +CONFIG_MIPS32_N32=y diff --git a/arch/mips/configs/generic/eb.config b/arch/mips/configs/generic/eb.config new file mode 100644 index 0000000..c5cdc99 --- /dev/null +++ b/arch/mips/configs/generic/eb.config @@ -0,0 +1 @@ +CONFIG_CPU_BIG_ENDIAN=y diff --git a/arch/mips/configs/generic/el.config b/arch/mips/configs/generic/el.config new file mode 100644 index 0000000..ee43fdb --- /dev/null +++ b/arch/mips/configs/generic/el.config @@ -0,0 +1 @@ +CONFIG_CPU_LITTLE_ENDIAN=y diff --git a/arch/mips/configs/generic/micro32r2.config b/arch/mips/configs/generic/micro32r2.config new file mode 100644 index 0000000..b701fe7 --- /dev/null +++ b/arch/mips/configs/generic/micro32r2.config @@ -0,0 +1,4 @@ +CONFIG_CPU_MIPS32_R2=y +CONFIG_CPU_MICROMIPS=y +CONFIG_MIPS_O32_FP64_SUPPORT=y +CONFIG_HIGHMEM=y diff --git a/arch/mips/configs/generic_defconfig b/arch/mips/configs/generic_defconfig new file mode 100644 index 0000000..c95d94c --- /dev/null +++ b/arch/mips/configs/generic_defconfig @@ -0,0 +1,96 @@ +CONFIG_MIPS_GENERIC=y +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_MIPS_CPS=y +CONFIG_CPU_HAS_MSA=y +CONFIG_HIGHMEM=y +CONFIG_NR_CPUS=2 +CONFIG_MIPS_O32_FP64_SUPPORT=y +CONFIG_SYSVIPC=y +CONFIG_NO_HZ_IDLE=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_MEMCG=y +CONFIG_MEMCG_SWAP=y +CONFIG_BLK_CGROUP=y +CONFIG_CFS_BANDWIDTH=y +CONFIG_RT_GROUP_SCHED=y +CONFIG_CGROUP_PIDS=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CPUSETS=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_NAMESPACES=y +CONFIG_USER_NS=y +CONFIG_SCHED_AUTOGROUP=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_BPF_SYSCALL=y +CONFIG_USERFAULTFD=y +CONFIG_EMBEDDED=y +# CONFIG_SLUB_DEBUG is not set +# CONFIG_COMPAT_BRK is not set +CONFIG_CC_STACKPROTECTOR_REGULAR=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_TRIM_UNUSED_KSYMS=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_NETFILTER=y +# CONFIG_WIRELESS is not set +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_SCSI=y +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_SERIO is not set +CONFIG_HW_RANDOM=y +# CONFIG_HWMON is not set +CONFIG_MFD_SYSCON=y +CONFIG_HID_A4TECH=y +CONFIG_HID_APPLE=y +CONFIG_HID_BELKIN=y +CONFIG_HID_CHERRY=y +CONFIG_HID_CHICONY=y +CONFIG_HID_CYPRESS=y +CONFIG_HID_EZKEY=y +CONFIG_HID_KENSINGTON=y +CONFIG_HID_LOGITECH=y +CONFIG_HID_MICROSOFT=y +CONFIG_HID_MONTEREY=y +# CONFIG_USB_SUPPORT is not set +# CONFIG_MIPS_PLATFORM_DEVICES is not set +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_EXT4_ENCRYPTION=y +CONFIG_FANOTIFY=y +CONFIG_FUSE_FS=y +CONFIG_CUSE=y +CONFIG_OVERLAY_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +# CONFIG_MISC_FILESYSTEMS is not set +CONFIG_NFS_FS=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_NFS_V4_1=y +CONFIG_NFS_V4_2=y +CONFIG_PRINTK_TIME=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_INFO_REDUCED=y +CONFIG_DEBUG_FS=y +# CONFIG_SCHED_DEBUG is not set +# CONFIG_FTRACE is not set +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="earlycon" +# CONFIG_XZ_DEC_X86 is not set +# CONFIG_XZ_DEC_POWERPC is not set +# CONFIG_XZ_DEC_IA64 is not set +# CONFIG_XZ_DEC_ARM is not set +# CONFIG_XZ_DEC_ARMTHUMB is not set +# CONFIG_XZ_DEC_SPARC is not set diff --git a/arch/mips/generic/Kconfig b/arch/mips/generic/Kconfig new file mode 100644 index 0000000..baddb06 --- /dev/null +++ b/arch/mips/generic/Kconfig @@ -0,0 +1,12 @@ +if MIPS_GENERIC + +config LEGACY_BOARDS + bool + help + Select this from your board if the board must use a legacy, non-UHI, + boot protocol. This will cause the kernel to scan through the list of + supported machines calling their detect functions in turn if the + kernel is booted without being provided with an FDT via the UHI + boot protocol. + +endif diff --git a/arch/mips/generic/Makefile b/arch/mips/generic/Makefile new file mode 100644 index 0000000..26e6420 --- /dev/null +++ b/arch/mips/generic/Makefile @@ -0,0 +1,13 @@ +# +# Copyright (C) 2016 Imagination Technologies +# Author: Paul Burton +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# + +obj-y += init.o +obj-y += irq.o +obj-y += proc.o diff --git a/arch/mips/generic/Platform b/arch/mips/generic/Platform new file mode 100644 index 0000000..9a30d69 --- /dev/null +++ b/arch/mips/generic/Platform @@ -0,0 +1,14 @@ +# +# Copyright (C) 2016 Imagination Technologies +# Author: Paul Burton +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# + +platform-$(CONFIG_MIPS_GENERIC) += generic/ +cflags-$(CONFIG_MIPS_GENERIC) += -I$(srctree)/arch/mips/include/asm/mach-generic +load-$(CONFIG_MIPS_GENERIC) += 0xffffffff80100000 +all-$(CONFIG_MIPS_GENERIC) := vmlinux.gz.itb diff --git a/arch/mips/generic/init.c b/arch/mips/generic/init.c new file mode 100644 index 0000000..0ea73e8 --- /dev/null +++ b/arch/mips/generic/init.c @@ -0,0 +1,176 @@ +/* + * Copyright (C) 2016 Imagination Technologies + * Author: Paul Burton + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +static __initdata const void *fdt; +static __initdata const struct mips_machine *mach; +static __initdata const void *mach_match_data; + +void __init prom_init(void) +{ + const struct mips_machine *check_mach; + const struct of_device_id *match; + + if ((fw_arg0 == -2) && !fdt_check_header((void *)fw_arg1)) { + /* + * We booted using the UHI boot protocol, so we have been + * provided with the appropriate device tree for the board. + * Make use of it & search for any machine struct based upon + * the root compatible string. + */ + fdt = (void *)fw_arg1; + + for_each_mips_machine(check_mach) { + match = mips_machine_is_compatible(check_mach, fdt); + if (match) { + mach = check_mach; + mach_match_data = match->data; + break; + } + } + } else if (IS_ENABLED(CONFIG_LEGACY_BOARDS)) { + /* + * We weren't booted using the UHI boot protocol, but do + * support some number of boards with legacy boot protocols. + * Attempt to find the right one. + */ + for_each_mips_machine(check_mach) { + if (!check_mach->detect) + continue; + + if (!check_mach->detect()) + continue; + + mach = check_mach; + } + + /* + * If we don't recognise the machine then we can't continue, so + * die here. + */ + BUG_ON(!mach); + + /* Retrieve the machine's FDT */ + fdt = mach->fdt; + } + + BUG_ON(!fdt); +} + +void __init *plat_get_fdt(void) +{ + return (void *)fdt; +} + +void __init plat_mem_setup(void) +{ + if (mach && mach->fixup_fdt) + fdt = mach->fixup_fdt(fdt, mach_match_data); + + strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE); + __dt_setup_arch((void *)fdt); +} + +void __init device_tree_init(void) +{ + int err; + + unflatten_and_copy_device_tree(); + mips_cpc_probe(); + + err = register_cps_smp_ops(); + if (err) + err = register_up_smp_ops(); +} + +void __init plat_time_init(void) +{ + struct device_node *np; + struct clk *clk; + + of_clk_init(NULL); + + if (!cpu_has_counter) { + mips_hpt_frequency = 0; + } else if (mach && mach->measure_hpt_freq) { + mips_hpt_frequency = mach->measure_hpt_freq(); + } else { + np = of_get_cpu_node(0, NULL); + if (!np) { + pr_err("Failed to get CPU node\n"); + return; + } + + clk = of_clk_get(np, 0); + if (IS_ERR(clk)) { + pr_err("Failed to get CPU clock: %ld\n", PTR_ERR(clk)); + return; + } + + mips_hpt_frequency = clk_get_rate(clk); + clk_put(clk); + + switch (boot_cpu_type()) { + case CPU_20KC: + case CPU_25KF: + /* The counter runs at the CPU clock rate */ + break; + default: + /* The counter runs at half the CPU clock rate */ + mips_hpt_frequency /= 2; + break; + } + } + + clocksource_probe(); +} + +void __init arch_init_irq(void) +{ + struct device_node *intc_node; + + intc_node = of_find_compatible_node(NULL, NULL, + "mti,cpu-interrupt-controller"); + if (!cpu_has_veic && !intc_node) + mips_cpu_irq_init(); + + irqchip_init(); +} + +static int __init publish_devices(void) +{ + if (!of_have_populated_dt()) + panic("Device-tree not present"); + + if (of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL)) + panic("Failed to populate DT"); + + return 0; +} +arch_initcall(publish_devices); + +void __init prom_free_prom_memory(void) +{ +} diff --git a/arch/mips/generic/irq.c b/arch/mips/generic/irq.c new file mode 100644 index 0000000..14064bd --- /dev/null +++ b/arch/mips/generic/irq.c @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2016 Imagination Technologies + * Author: Paul Burton + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include + +#include + +int get_c0_fdc_int(void) +{ + int mips_cpu_fdc_irq; + + if (cpu_has_veic) + panic("Unimplemented!"); + else if (gic_present) + mips_cpu_fdc_irq = gic_get_c0_fdc_int(); + else if (cp0_fdc_irq >= 0) + mips_cpu_fdc_irq = MIPS_CPU_IRQ_BASE + cp0_fdc_irq; + else + mips_cpu_fdc_irq = -1; + + return mips_cpu_fdc_irq; +} + +int get_c0_perfcount_int(void) +{ + int mips_cpu_perf_irq; + + if (cpu_has_veic) + panic("Unimplemented!"); + else if (gic_present) + mips_cpu_perf_irq = gic_get_c0_perfcount_int(); + else if (cp0_perfcount_irq >= 0) + mips_cpu_perf_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; + else + mips_cpu_perf_irq = -1; + + return mips_cpu_perf_irq; +} + +unsigned int get_c0_compare_int(void) +{ + int mips_cpu_timer_irq; + + if (cpu_has_veic) + panic("Unimplemented!"); + else if (gic_present) + mips_cpu_timer_irq = gic_get_c0_compare_int(); + else + mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; + + return mips_cpu_timer_irq; +} diff --git a/arch/mips/generic/proc.c b/arch/mips/generic/proc.c new file mode 100644 index 0000000..42b3325 --- /dev/null +++ b/arch/mips/generic/proc.c @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2016 Imagination Technologies + * Author: Paul Burton + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include + +#include + +const char *get_system_type(void) +{ + const char *str; + int err; + + err = of_property_read_string(of_root, "model", &str); + if (!err) + return str; + + err = of_property_read_string_index(of_root, "compatible", 0, &str); + if (!err) + return str; + + return "Unknown"; +} diff --git a/arch/mips/generic/vmlinux.its.S b/arch/mips/generic/vmlinux.its.S new file mode 100644 index 0000000..f67fbf1 --- /dev/null +++ b/arch/mips/generic/vmlinux.its.S @@ -0,0 +1,31 @@ +/dts-v1/; + +/ { + description = KERNEL_NAME; + #address-cells = ; + + images { + kernel@0 { + description = KERNEL_NAME; + data = /incbin/(VMLINUX_BINARY); + type = "kernel"; + arch = "mips"; + os = "linux"; + compression = VMLINUX_COMPRESSION; + load = /bits/ ADDR_BITS ; + entry = /bits/ ADDR_BITS ; + hash@0 { + algo = "sha1"; + }; + }; + }; + + configurations { + default = "conf@default"; + + conf@default { + description = "Generic Linux kernel"; + kernel = "kernel@0"; + }; + }; +}; diff --git a/arch/mips/include/asm/machine.h b/arch/mips/include/asm/machine.h new file mode 100644 index 0000000..6b444cd --- /dev/null +++ b/arch/mips/include/asm/machine.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2016 Imagination Technologies + * Author: Paul Burton + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __MIPS_ASM_MACHINE_H__ +#define __MIPS_ASM_MACHINE_H__ + +#include +#include + +struct mips_machine { + const struct of_device_id *matches; + const void *fdt; + bool (*detect)(void); + const void *(*fixup_fdt)(const void *fdt, const void *match_data); + unsigned int (*measure_hpt_freq)(void); +}; + +extern long __mips_machines_start; +extern long __mips_machines_end; + +#define MIPS_MACHINE(name) \ + static const struct mips_machine __mips_mach_##name \ + __used __section(.mips.machines.init) + +#define for_each_mips_machine(mach) \ + for ((mach) = (struct mips_machine *)&__mips_machines_start; \ + (mach) < (struct mips_machine *)&__mips_machines_end; \ + (mach)++) + +/** + * mips_machine_is_compatible() - check if a machine is compatible with an FDT + * @mach: the machine struct to check + * @fdt: the FDT to check for compatibility with + * + * Check whether the given machine @mach is compatible with the given flattened + * device tree @fdt, based upon the compatibility property of the root node. + * + * Return: the device id matched if any, else NULL + */ +static inline const struct of_device_id * +mips_machine_is_compatible(const struct mips_machine *mach, const void *fdt) +{ + const struct of_device_id *match; + + if (!mach->matches) + return NULL; + + for (match = mach->matches; match->compatible; match++) { + if (fdt_node_check_compatible(fdt, 0, match->compatible) == 0) + return match; + } + + return NULL; +} + +#endif /* __MIPS_ASM_MACHINE_H__ */ -- cgit v0.10.2 From 3f5f0a4475e13345326061f00c68f428232ba2bc Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Wed, 5 Oct 2016 18:18:21 +0100 Subject: MIPS: generic: Convert SEAD-3 to a generic board Convert the MIPS SEAD-3 board support to be a generic board, supported by generic kernels. Because the SEAD-3 boot protocol was defined long ago and we don't want to force a switch to the UHI protocol, SEAD-3 is added as a legacy board which is detected by reading the REVISION register. This may technically not be a valid memory read & future work will include attempting to handle that gracefully. In practice since SEAD-3 is the only legacy board supported by the generic kernel so far the read will only happen on SEAD-3 boards, and even once Malta is converted the same REVISION register exists there too. Other boards such as Boston, Ci20 & Ci40 will use the UHI boot protocol & thus not run any of the legacy board detect functions. Signed-off-by: Paul Burton Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/14354/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/Kbuild.platforms b/arch/mips/Kbuild.platforms index 9c1e8f9..f5f1bdb 100644 --- a/arch/mips/Kbuild.platforms +++ b/arch/mips/Kbuild.platforms @@ -19,7 +19,6 @@ platforms += lasat platforms += loongson32 platforms += loongson64 platforms += mti-malta -platforms += mti-sead3 platforms += netlogic platforms += paravirt platforms += pic32 diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 82b45dc..a7d9224 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -546,41 +546,6 @@ config MACH_PIC32 Microchip PIC32 is a family of general-purpose 32 bit MIPS core microcontrollers. -config MIPS_SEAD3 - bool "MIPS SEAD3 board" - select BOOT_ELF32 - select BOOT_RAW - select BUILTIN_DTB - select CEVT_R4K - select CSRC_R4K - select CLKSRC_MIPS_GIC - select COMMON_CLK - select CPU_MIPSR2_IRQ_VI - select CPU_MIPSR2_IRQ_EI - select DMA_NONCOHERENT - select IRQ_MIPS_CPU - select MIPS_GIC - select LIBFDT - select MIPS_MSC - select SYS_HAS_CPU_MIPS32_R1 - select SYS_HAS_CPU_MIPS32_R2 - select SYS_HAS_CPU_MIPS32_R6 - select SYS_HAS_CPU_MIPS64_R1 - select SYS_SUPPORTS_32BIT_KERNEL - select SYS_SUPPORTS_64BIT_KERNEL - select SYS_SUPPORTS_BIG_ENDIAN - select SYS_SUPPORTS_LITTLE_ENDIAN - select SYS_SUPPORTS_SMARTMIPS - select SYS_SUPPORTS_MICROMIPS - select SYS_SUPPORTS_MIPS16 - select SYS_SUPPORTS_RELOCATABLE - select USB_EHCI_BIG_ENDIAN_DESC - select USB_EHCI_BIG_ENDIAN_MMIO - select USE_OF - help - This enables support for the MIPS Technologies SEAD3 evaluation - board. - config NEC_MARKEINS bool "NEC EMMA2RH Mark-eins board" select SOC_EMMA2RH @@ -2976,7 +2941,7 @@ endchoice choice prompt "Kernel command line type" if !CMDLINE_OVERRIDE default MIPS_CMDLINE_FROM_DTB if USE_OF && !ATH79 && !MACH_INGENIC && \ - !MIPS_MALTA && !MIPS_SEAD3 && \ + !MIPS_MALTA && \ !CAVIUM_OCTEON_SOC default MIPS_CMDLINE_FROM_BOOTLOADER diff --git a/arch/mips/Makefile b/arch/mips/Makefile index f3e768a..fbf40d3 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -488,3 +488,16 @@ $(generic_defconfigs): # Prevent generic merge_config rules attempting to merge single fragments # $(generic_config_dir)/%.config: ; + +# +# Legacy defconfig compatibility - these targets used to be real defconfigs but +# now that the boards have been converted to use the generic kernel they are +# wrappers around the generic rules above. +# +.PHONY: sead3_defconfig +sead3_defconfig: + $(Q)$(MAKE) 32r2el_defconfig BOARDS=sead-3 + +.PHONY: sead3micro_defconfig +sead3micro_defconfig: + $(Q)$(MAKE) micro32r2el_defconfig BOARDS=sead-3 diff --git a/arch/mips/boot/dts/mti/Makefile b/arch/mips/boot/dts/mti/Makefile index 144d776..fcabd69 100644 --- a/arch/mips/boot/dts/mti/Makefile +++ b/arch/mips/boot/dts/mti/Makefile @@ -1,5 +1,5 @@ dtb-$(CONFIG_MIPS_MALTA) += malta.dtb -dtb-$(CONFIG_MIPS_SEAD3) += sead3.dtb +dtb-$(CONFIG_LEGACY_BOARD_SEAD3) += sead3.dtb obj-y += $(patsubst %.dtb, %.dtb.o, $(dtb-y)) diff --git a/arch/mips/boot/dts/mti/sead3.dts b/arch/mips/boot/dts/mti/sead3.dts index 2579ca5..b112879 100644 --- a/arch/mips/boot/dts/mti/sead3.dts +++ b/arch/mips/boot/dts/mti/sead3.dts @@ -10,6 +10,7 @@ #address-cells = <1>; #size-cells = <1>; compatible = "mti,sead-3"; + model = "MIPS SEAD-3"; interrupt-parent = <&gic>; chosen { diff --git a/arch/mips/configs/generic/board-sead-3.config b/arch/mips/configs/generic/board-sead-3.config new file mode 100644 index 0000000..3b5e1ac --- /dev/null +++ b/arch/mips/configs/generic/board-sead-3.config @@ -0,0 +1,32 @@ +CONFIG_LEGACY_BOARD_SEAD3=y + +CONFIG_AUXDISPLAY=y +CONFIG_IMG_ASCII_LCD=y + +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_SYSCON=y + +CONFIG_MMC=y +CONFIG_MMC_SPI=y + +CONFIG_MTD=y +CONFIG_MTD_BLOCK=y +CONFIG_MTD_CFI=y +CONFIG_MTD_CFI_INTELEXT=y +CONFIG_MTD_OF_PARTS=y +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_OF=y +CONFIG_MTD_UBI=y +CONFIG_MTD_UBI_GLUEBI=y + +CONFIG_NETDEVICES=y +CONFIG_SMSC911X=y +CONFIG_SMSC_PHY=y + +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_OF_PLATFORM=y + +CONFIG_USB=y +CONFIG_USB_EHCI_HCD=y diff --git a/arch/mips/configs/sead3_defconfig b/arch/mips/configs/sead3_defconfig deleted file mode 100644 index ab4c465..0000000 --- a/arch/mips/configs/sead3_defconfig +++ /dev/null @@ -1,129 +0,0 @@ -CONFIG_MIPS_SEAD3=y -CONFIG_CPU_LITTLE_ENDIAN=y -CONFIG_CPU_MIPS32_R2=y -CONFIG_HZ_100=y -CONFIG_SYSVIPC=y -CONFIG_POSIX_MQUEUE=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=15 -CONFIG_EMBEDDED=y -CONFIG_SLAB=y -CONFIG_PROFILING=y -CONFIG_OPROFILE=y -CONFIG_MODULES=y -# CONFIG_BLK_DEV_BSG is not set -CONFIG_CMDLINE_BOOL=y -CONFIG_CMDLINE="earlycon" -# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_INET=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET_XFRM_MODE_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set -# CONFIG_INET_DIAG is not set -# CONFIG_IPV6 is not set -# CONFIG_WIRELESS is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -CONFIG_DEVTMPFS=y -CONFIG_MTD=y -CONFIG_MTD_BLOCK=y -CONFIG_MTD_CFI=y -CONFIG_MTD_CFI_INTELEXT=y -CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_UBI=y -CONFIG_MTD_UBI_GLUEBI=y -CONFIG_OF=y -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_CRYPTOLOOP=m -CONFIG_SCSI=y -# CONFIG_SCSI_PROC_FS is not set -CONFIG_BLK_DEV_SD=y -CONFIG_CHR_DEV_SG=y -# CONFIG_SCSI_LOWLEVEL is not set -CONFIG_NETDEVICES=y -CONFIG_SMSC911X=y -# CONFIG_NET_VENDOR_WIZNET is not set -CONFIG_MARVELL_PHY=y -CONFIG_DAVICOM_PHY=y -CONFIG_QSEMI_PHY=y -CONFIG_LXT_PHY=y -CONFIG_CICADA_PHY=y -CONFIG_VITESSE_PHY=y -CONFIG_SMSC_PHY=y -CONFIG_BROADCOM_PHY=y -CONFIG_ICPLUS_PHY=y -# CONFIG_WLAN is not set -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_SERIO is not set -# CONFIG_CONSOLE_TRANSLATIONS is not set -CONFIG_VT_HW_CONSOLE_BINDING=y -CONFIG_LEGACY_PTY_COUNT=32 -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=2 -CONFIG_SERIAL_8250_RUNTIME_UARTS=2 -CONFIG_SERIAL_OF_PLATFORM=y -# CONFIG_HW_RANDOM is not set -CONFIG_I2C=y -# CONFIG_I2C_COMPAT is not set -CONFIG_I2C_CHARDEV=y -# CONFIG_I2C_HELPER_AUTO is not set -CONFIG_SPI=y -CONFIG_POWER_RESET=y -CONFIG_POWER_RESET_RESTART=y -CONFIG_POWER_RESET_SYSCON=y -CONFIG_SENSORS_ADT7475=y -CONFIG_BACKLIGHT_LCD_SUPPORT=y -CONFIG_LCD_CLASS_DEVICE=y -CONFIG_BACKLIGHT_CLASS_DEVICE=y -# CONFIG_VGA_CONSOLE is not set -CONFIG_USB=y -CONFIG_USB_ANNOUNCE_NEW_DEVICES=y -CONFIG_USB_EHCI_HCD=y -CONFIG_USB_EHCI_ROOT_HUB_TT=y -CONFIG_USB_STORAGE=y -CONFIG_MMC=y -CONFIG_MMC_DEBUG=y -CONFIG_MMC_SPI=y -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=y -CONFIG_LEDS_SYSCON=y -CONFIG_LEDS_TRIGGERS=y -CONFIG_LEDS_TRIGGER_HEARTBEAT=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_M41T80=y -CONFIG_EXT3_FS=y -# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set -CONFIG_XFS_FS=y -CONFIG_XFS_QUOTA=y -CONFIG_XFS_POSIX_ACL=y -CONFIG_QUOTA=y -# CONFIG_PRINT_QUOTA_WARNING is not set -CONFIG_MSDOS_FS=m -CONFIG_VFAT_FS=m -CONFIG_TMPFS=y -CONFIG_JFFS2_FS=y -CONFIG_NFS_FS=y -CONFIG_ROOT_NFS=y -CONFIG_NLS_CODEPAGE_437=y -CONFIG_NLS_ASCII=y -CONFIG_NLS_ISO8859_1=y -CONFIG_NLS_ISO8859_15=y -CONFIG_NLS_UTF8=y -# CONFIG_FTRACE is not set -CONFIG_CRYPTO_CBC=y -CONFIG_CRYPTO_ECB=y -CONFIG_CRYPTO_ARC4=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set -# CONFIG_CRYPTO_HW is not set diff --git a/arch/mips/configs/sead3micro_defconfig b/arch/mips/configs/sead3micro_defconfig deleted file mode 100644 index cd91a77..0000000 --- a/arch/mips/configs/sead3micro_defconfig +++ /dev/null @@ -1,122 +0,0 @@ -CONFIG_MIPS_SEAD3=y -CONFIG_CPU_LITTLE_ENDIAN=y -CONFIG_CPU_MIPS32_R2=y -CONFIG_CPU_MICROMIPS=y -CONFIG_HZ_100=y -CONFIG_SYSVIPC=y -CONFIG_POSIX_MQUEUE=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=15 -CONFIG_EMBEDDED=y -CONFIG_SLAB=y -CONFIG_PROFILING=y -CONFIG_OPROFILE=y -CONFIG_MODULES=y -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_INET=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET_XFRM_MODE_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set -# CONFIG_INET_DIAG is not set -# CONFIG_IPV6 is not set -# CONFIG_WIRELESS is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -CONFIG_DEVTMPFS=y -CONFIG_MTD=y -CONFIG_MTD_BLOCK=y -CONFIG_MTD_CFI=y -CONFIG_MTD_CFI_INTELEXT=y -CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_UBI=y -CONFIG_MTD_UBI_GLUEBI=y -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_CRYPTOLOOP=m -CONFIG_SCSI=y -# CONFIG_SCSI_PROC_FS is not set -CONFIG_BLK_DEV_SD=y -CONFIG_CHR_DEV_SG=y -# CONFIG_SCSI_LOWLEVEL is not set -CONFIG_NETDEVICES=y -CONFIG_SMSC911X=y -# CONFIG_NET_VENDOR_WIZNET is not set -CONFIG_MARVELL_PHY=y -CONFIG_DAVICOM_PHY=y -CONFIG_QSEMI_PHY=y -CONFIG_LXT_PHY=y -CONFIG_CICADA_PHY=y -CONFIG_VITESSE_PHY=y -CONFIG_SMSC_PHY=y -CONFIG_BROADCOM_PHY=y -CONFIG_ICPLUS_PHY=y -# CONFIG_WLAN is not set -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_SERIO is not set -# CONFIG_CONSOLE_TRANSLATIONS is not set -CONFIG_VT_HW_CONSOLE_BINDING=y -CONFIG_LEGACY_PTY_COUNT=32 -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=2 -CONFIG_SERIAL_8250_RUNTIME_UARTS=2 -# CONFIG_HW_RANDOM is not set -CONFIG_I2C=y -# CONFIG_I2C_COMPAT is not set -CONFIG_I2C_CHARDEV=y -# CONFIG_I2C_HELPER_AUTO is not set -CONFIG_SPI=y -CONFIG_SENSORS_ADT7475=y -CONFIG_BACKLIGHT_LCD_SUPPORT=y -CONFIG_LCD_CLASS_DEVICE=y -CONFIG_BACKLIGHT_CLASS_DEVICE=y -# CONFIG_VGA_CONSOLE is not set -CONFIG_USB=y -CONFIG_USB_ANNOUNCE_NEW_DEVICES=y -CONFIG_USB_EHCI_HCD=y -CONFIG_USB_EHCI_ROOT_HUB_TT=y -CONFIG_USB_STORAGE=y -CONFIG_MMC=y -CONFIG_MMC_DEBUG=y -CONFIG_MMC_SPI=y -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=y -CONFIG_LEDS_TRIGGERS=y -CONFIG_LEDS_TRIGGER_HEARTBEAT=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_M41T80=y -CONFIG_EXT3_FS=y -# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set -CONFIG_XFS_FS=y -CONFIG_XFS_QUOTA=y -CONFIG_XFS_POSIX_ACL=y -CONFIG_QUOTA=y -# CONFIG_PRINT_QUOTA_WARNING is not set -CONFIG_MSDOS_FS=m -CONFIG_VFAT_FS=m -CONFIG_TMPFS=y -CONFIG_JFFS2_FS=y -CONFIG_NFS_FS=y -CONFIG_ROOT_NFS=y -CONFIG_NLS_CODEPAGE_437=y -CONFIG_NLS_ASCII=y -CONFIG_NLS_ISO8859_1=y -CONFIG_NLS_ISO8859_15=y -CONFIG_NLS_UTF8=y -# CONFIG_FTRACE is not set -CONFIG_CRYPTO_CBC=y -CONFIG_CRYPTO_ECB=y -CONFIG_CRYPTO_ARC4=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set -# CONFIG_CRYPTO_HW is not set diff --git a/arch/mips/generic/Kconfig b/arch/mips/generic/Kconfig index baddb06..a606b3f 100644 --- a/arch/mips/generic/Kconfig +++ b/arch/mips/generic/Kconfig @@ -9,4 +9,11 @@ config LEGACY_BOARDS kernel is booted without being provided with an FDT via the UHI boot protocol. +config LEGACY_BOARD_SEAD3 + bool "Support MIPS SEAD-3 boards" + select LEGACY_BOARDS + help + Enable this to include support for booting on MIPS SEAD-3 FPGA-based + development boards, which boot using a legacy boot protocol. + endif diff --git a/arch/mips/generic/Makefile b/arch/mips/generic/Makefile index 26e6420..7c66494 100644 --- a/arch/mips/generic/Makefile +++ b/arch/mips/generic/Makefile @@ -11,3 +11,5 @@ obj-y += init.o obj-y += irq.o obj-y += proc.o + +obj-$(CONFIG_LEGACY_BOARD_SEAD3) += board-sead3.o diff --git a/arch/mips/generic/board-sead3.c b/arch/mips/generic/board-sead3.c new file mode 100644 index 0000000..f4ae058 --- /dev/null +++ b/arch/mips/generic/board-sead3.c @@ -0,0 +1,376 @@ +/* + * Copyright (C) 2016 Imagination Technologies + * Author: Paul Burton + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#define pr_fmt(fmt) "sead3: " fmt + +#include +#include +#include + +#include +#include +#include + +#define SEAD_CONFIG CKSEG1ADDR(0x1b100110) +#define SEAD_CONFIG_GIC_PRESENT BIT(1) + +#define MIPS_REVISION CKSEG1ADDR(0x1fc00010) +#define MIPS_REVISION_MACHINE (0xf << 4) +#define MIPS_REVISION_MACHINE_SEAD3 (0x4 << 4) + +static __init bool sead3_detect(void) +{ + uint32_t rev; + + rev = __raw_readl((void *)MIPS_REVISION); + return (rev & MIPS_REVISION_MACHINE) == MIPS_REVISION_MACHINE_SEAD3; +} + +static __init int append_cmdline(void *fdt) +{ + int err, chosen_off; + + /* find or add chosen node */ + chosen_off = fdt_path_offset(fdt, "/chosen"); + if (chosen_off == -FDT_ERR_NOTFOUND) + chosen_off = fdt_path_offset(fdt, "/chosen@0"); + if (chosen_off == -FDT_ERR_NOTFOUND) + chosen_off = fdt_add_subnode(fdt, 0, "chosen"); + if (chosen_off < 0) { + pr_err("Unable to find or add DT chosen node: %d\n", + chosen_off); + return chosen_off; + } + + err = fdt_setprop_string(fdt, chosen_off, "bootargs", fw_getcmdline()); + if (err) { + pr_err("Unable to set bootargs property: %d\n", err); + return err; + } + + return 0; +} + +static __init int append_memory(void *fdt) +{ + unsigned long phys_memsize, memsize; + __be32 mem_array[2]; + int err, mem_off; + char *var; + + /* find memory size from the bootloader environment */ + var = fw_getenv("memsize"); + if (var) { + err = kstrtoul(var, 0, &phys_memsize); + if (err) { + pr_err("Failed to read memsize env variable '%s'\n", + var); + return -EINVAL; + } + } else { + pr_warn("The bootloader didn't provide memsize: defaulting to 32MB\n"); + phys_memsize = 32 << 20; + } + + /* default to using all available RAM */ + memsize = phys_memsize; + + /* allow the user to override the usable memory */ + var = strstr(arcs_cmdline, "memsize="); + if (var) + memsize = memparse(var + strlen("memsize="), NULL); + + /* if the user says there's more RAM than we thought, believe them */ + phys_memsize = max_t(unsigned long, phys_memsize, memsize); + + /* find or add a memory node */ + mem_off = fdt_path_offset(fdt, "/memory"); + if (mem_off == -FDT_ERR_NOTFOUND) + mem_off = fdt_add_subnode(fdt, 0, "memory"); + if (mem_off < 0) { + pr_err("Unable to find or add memory DT node: %d\n", mem_off); + return mem_off; + } + + err = fdt_setprop_string(fdt, mem_off, "device_type", "memory"); + if (err) { + pr_err("Unable to set memory node device_type: %d\n", err); + return err; + } + + mem_array[0] = 0; + mem_array[1] = cpu_to_be32(phys_memsize); + err = fdt_setprop(fdt, mem_off, "reg", mem_array, sizeof(mem_array)); + if (err) { + pr_err("Unable to set memory regs property: %d\n", err); + return err; + } + + mem_array[0] = 0; + mem_array[1] = cpu_to_be32(memsize); + err = fdt_setprop(fdt, mem_off, "linux,usable-memory", + mem_array, sizeof(mem_array)); + if (err) { + pr_err("Unable to set linux,usable-memory property: %d\n", err); + return err; + } + + return 0; +} + +static __init int remove_gic(void *fdt) +{ + const unsigned int cpu_ehci_int = 2; + const unsigned int cpu_uart_int = 4; + const unsigned int cpu_eth_int = 6; + int gic_off, cpu_off, uart_off, eth_off, ehci_off, err; + uint32_t cfg, cpu_phandle; + + /* leave the GIC node intact if a GIC is present */ + cfg = __raw_readl((uint32_t *)SEAD_CONFIG); + if (cfg & SEAD_CONFIG_GIC_PRESENT) + return 0; + + gic_off = fdt_node_offset_by_compatible(fdt, -1, "mti,gic"); + if (gic_off < 0) { + pr_err("unable to find DT GIC node: %d\n", gic_off); + return gic_off; + } + + err = fdt_nop_node(fdt, gic_off); + if (err) { + pr_err("unable to nop GIC node\n"); + return err; + } + + cpu_off = fdt_node_offset_by_compatible(fdt, -1, + "mti,cpu-interrupt-controller"); + if (cpu_off < 0) { + pr_err("unable to find CPU intc node: %d\n", cpu_off); + return cpu_off; + } + + cpu_phandle = fdt_get_phandle(fdt, cpu_off); + if (!cpu_phandle) { + pr_err("unable to get CPU intc phandle\n"); + return -EINVAL; + } + + err = fdt_setprop_u32(fdt, 0, "interrupt-parent", cpu_phandle); + if (err) { + pr_err("unable to set root interrupt-parent: %d\n", err); + return err; + } + + uart_off = fdt_node_offset_by_compatible(fdt, -1, "ns16550a"); + while (uart_off >= 0) { + err = fdt_setprop_u32(fdt, uart_off, "interrupts", + cpu_uart_int); + if (err) { + pr_err("unable to set UART interrupts property: %d\n", + err); + return err; + } + + uart_off = fdt_node_offset_by_compatible(fdt, uart_off, + "ns16550a"); + } + if (uart_off != -FDT_ERR_NOTFOUND) { + pr_err("error searching for UART DT node: %d\n", uart_off); + return uart_off; + } + + eth_off = fdt_node_offset_by_compatible(fdt, -1, "smsc,lan9115"); + if (eth_off < 0) { + pr_err("unable to find ethernet DT node: %d\n", eth_off); + return eth_off; + } + + err = fdt_setprop_u32(fdt, eth_off, "interrupts", cpu_eth_int); + if (err) { + pr_err("unable to set ethernet interrupts property: %d\n", err); + return err; + } + + ehci_off = fdt_node_offset_by_compatible(fdt, -1, "generic-ehci"); + if (ehci_off < 0) { + pr_err("unable to find EHCI DT node: %d\n", ehci_off); + return ehci_off; + } + + err = fdt_setprop_u32(fdt, ehci_off, "interrupts", cpu_ehci_int); + if (err) { + pr_err("unable to set EHCI interrupts property: %d\n", err); + return err; + } + + return 0; +} + +static __init int serial_config(void *fdt) +{ + const char *yamontty, *mode_var; + char mode_var_name[9], path[18], parity; + unsigned int uart, baud, stop_bits; + bool hw_flow; + int chosen_off, err; + + yamontty = fw_getenv("yamontty"); + if (!yamontty || !strcmp(yamontty, "tty0")) { + uart = 0; + } else if (!strcmp(yamontty, "tty1")) { + uart = 1; + } else { + pr_warn("yamontty environment variable '%s' invalid\n", + yamontty); + uart = 0; + } + + baud = stop_bits = 0; + parity = 0; + hw_flow = false; + + snprintf(mode_var_name, sizeof(mode_var_name), "modetty%u", uart); + mode_var = fw_getenv(mode_var_name); + if (mode_var) { + while (mode_var[0] >= '0' && mode_var[0] <= '9') { + baud *= 10; + baud += mode_var[0] - '0'; + mode_var++; + } + if (mode_var[0] == ',') + mode_var++; + if (mode_var[0]) + parity = mode_var[0]; + if (mode_var[0] == ',') + mode_var++; + if (mode_var[0]) + stop_bits = mode_var[0] - '0'; + if (mode_var[0] == ',') + mode_var++; + if (!strcmp(mode_var, "hw")) + hw_flow = true; + } + + if (!baud) + baud = 38400; + + if (parity != 'e' && parity != 'n' && parity != 'o') + parity = 'n'; + + if (stop_bits != 7 && stop_bits != 8) + stop_bits = 8; + + WARN_ON(snprintf(path, sizeof(path), "uart%u:%u%c%u%s", + uart, baud, parity, stop_bits, + hw_flow ? "r" : "") >= sizeof(path)); + + /* find or add chosen node */ + chosen_off = fdt_path_offset(fdt, "/chosen"); + if (chosen_off == -FDT_ERR_NOTFOUND) + chosen_off = fdt_path_offset(fdt, "/chosen@0"); + if (chosen_off == -FDT_ERR_NOTFOUND) + chosen_off = fdt_add_subnode(fdt, 0, "chosen"); + if (chosen_off < 0) { + pr_err("Unable to find or add DT chosen node: %d\n", + chosen_off); + return chosen_off; + } + + err = fdt_setprop_string(fdt, chosen_off, "stdout-path", path); + if (err) { + pr_err("Unable to set stdout-path property: %d\n", err); + return err; + } + + return 0; +} + +static __init const void *sead3_fixup_fdt(const void *fdt, + const void *match_data) +{ + static unsigned char fdt_buf[16 << 10] __initdata; + int err; + + if (fdt_check_header(fdt)) + panic("Corrupt DT"); + + /* if this isn't SEAD3, something went wrong */ + BUG_ON(fdt_node_check_compatible(fdt, 0, "mti,sead-3")); + + fw_init_cmdline(); + + err = fdt_open_into(fdt, fdt_buf, sizeof(fdt_buf)); + if (err) + panic("Unable to open FDT: %d", err); + + err = append_cmdline(fdt_buf); + if (err) + panic("Unable to patch FDT: %d", err); + + err = append_memory(fdt_buf); + if (err) + panic("Unable to patch FDT: %d", err); + + err = remove_gic(fdt_buf); + if (err) + panic("Unable to patch FDT: %d", err); + + err = serial_config(fdt_buf); + if (err) + panic("Unable to patch FDT: %d", err); + + err = fdt_pack(fdt_buf); + if (err) + panic("Unable to pack FDT: %d\n", err); + + return fdt_buf; +} + +static __init unsigned int sead3_measure_hpt_freq(void) +{ + void __iomem *status_reg = (void __iomem *)0xbf000410; + unsigned int freq, orig, tick = 0; + unsigned long flags; + + local_irq_save(flags); + + orig = readl(status_reg) & 0x2; /* get original sample */ + /* wait for transition */ + while ((readl(status_reg) & 0x2) == orig) + ; + orig = orig ^ 0x2; /* flip the bit */ + + write_c0_count(0); + + /* wait 1 second (the sampling clock transitions every 10ms) */ + while (tick < 100) { + /* wait for transition */ + while ((readl(status_reg) & 0x2) == orig) + ; + orig = orig ^ 0x2; /* flip the bit */ + tick++; + } + + freq = read_c0_count(); + + local_irq_restore(flags); + + return freq; +} + +extern char __dtb_sead3_begin[]; + +MIPS_MACHINE(sead3) = { + .fdt = __dtb_sead3_begin, + .detect = sead3_detect, + .fixup_fdt = sead3_fixup_fdt, + .measure_hpt_freq = sead3_measure_hpt_freq, +}; diff --git a/arch/mips/include/asm/mach-sead3/cpu-feature-overrides.h b/arch/mips/include/asm/mach-sead3/cpu-feature-overrides.h deleted file mode 100644 index bfbd703..0000000 --- a/arch/mips/include/asm/mach-sead3/cpu-feature-overrides.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2003, 2004 Chris Dearman - * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org) - */ -#ifndef __ASM_MACH_MIPS_CPU_FEATURE_OVERRIDES_H -#define __ASM_MACH_MIPS_CPU_FEATURE_OVERRIDES_H - - -/* - * CPU feature overrides for MIPS boards - */ -#ifdef CONFIG_CPU_MIPS32 -#define cpu_has_tlb 1 -#define cpu_has_4kex 1 -#define cpu_has_4k_cache 1 -/* #define cpu_has_fpu ? */ -/* #define cpu_has_32fpr ? */ -#define cpu_has_counter 1 -/* #define cpu_has_watch ? */ -#define cpu_has_divec 1 -#define cpu_has_vce 0 -/* #define cpu_has_cache_cdex_p ? */ -/* #define cpu_has_cache_cdex_s ? */ -/* #define cpu_has_prefetch ? */ -#define cpu_has_mcheck 1 -/* #define cpu_has_ejtag ? */ -#ifdef CONFIG_CPU_MICROMIPS -#define cpu_has_llsc 0 -#else -#define cpu_has_llsc 1 -#endif -/* #define cpu_has_vtag_icache ? */ -/* #define cpu_has_dc_aliases ? */ -/* #define cpu_has_ic_fills_f_dc ? */ -#define cpu_has_nofpuex 0 -/* #define cpu_has_64bits ? */ -/* #define cpu_has_64bit_zero_reg ? */ -/* #define cpu_has_inclusive_pcaches ? */ -#define cpu_icache_snoops_remote_store 1 -#endif - -#ifdef CONFIG_CPU_MIPS64 -#define cpu_has_tlb 1 -#define cpu_has_4kex 1 -#define cpu_has_4k_cache 1 -/* #define cpu_has_fpu ? */ -/* #define cpu_has_32fpr ? */ -#define cpu_has_counter 1 -/* #define cpu_has_watch ? */ -#define cpu_has_divec 1 -#define cpu_has_vce 0 -/* #define cpu_has_cache_cdex_p ? */ -/* #define cpu_has_cache_cdex_s ? */ -/* #define cpu_has_prefetch ? */ -#define cpu_has_mcheck 1 -/* #define cpu_has_ejtag ? */ -#define cpu_has_llsc 1 -/* #define cpu_has_vtag_icache ? */ -/* #define cpu_has_dc_aliases ? */ -/* #define cpu_has_ic_fills_f_dc ? */ -#define cpu_has_nofpuex 0 -/* #define cpu_has_64bits ? */ -/* #define cpu_has_64bit_zero_reg ? */ -/* #define cpu_has_inclusive_pcaches ? */ -#define cpu_icache_snoops_remote_store 1 -#endif - -#endif /* __ASM_MACH_MIPS_CPU_FEATURE_OVERRIDES_H */ diff --git a/arch/mips/include/asm/mach-sead3/irq.h b/arch/mips/include/asm/mach-sead3/irq.h deleted file mode 100644 index 5d154cf..0000000 --- a/arch/mips/include/asm/mach-sead3/irq.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef __ASM_MACH_MIPS_IRQ_H -#define __ASM_MACH_MIPS_IRQ_H - -#define NR_IRQS 256 - - -#include_next - -#endif /* __ASM_MACH_MIPS_IRQ_H */ diff --git a/arch/mips/include/asm/mach-sead3/kernel-entry-init.h b/arch/mips/include/asm/mach-sead3/kernel-entry-init.h deleted file mode 100644 index 6cccd4d..0000000 --- a/arch/mips/include/asm/mach-sead3/kernel-entry-init.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Chris Dearman (chris@mips.com) - * Copyright (C) 2007 Mips Technologies, Inc. - */ -#ifndef __ASM_MACH_MIPS_KERNEL_ENTRY_INIT_H -#define __ASM_MACH_MIPS_KERNEL_ENTRY_INIT_H - - .macro kernel_entry_setup - .endm - -/* - * Do SMP slave processor setup necessary before we can safely execute C code. - */ - .macro smp_slave_setup - .endm - -#endif /* __ASM_MACH_MIPS_KERNEL_ENTRY_INIT_H */ diff --git a/arch/mips/include/asm/mach-sead3/sead3-dtshim.h b/arch/mips/include/asm/mach-sead3/sead3-dtshim.h deleted file mode 100644 index f5d7d9c..0000000 --- a/arch/mips/include/asm/mach-sead3/sead3-dtshim.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2016 Imagination Technologies - * Author: Paul Burton - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#ifndef __MIPS_SEAD3_DTSHIM_H__ -#define __MIPS_SEAD3_DTSHIM_H__ - -#include - -#ifdef CONFIG_MIPS_SEAD3 - -extern void __init *sead3_dt_shim(void *fdt); - -#else /* !CONFIG_MIPS_SEAD3 */ - -static inline void *sead3_dt_shim(void *fdt) -{ - return fdt; -} - -#endif /* !CONFIG_MIPS_SEAD3 */ - -#endif /* __MIPS_SEAD3_DTSHIM_H__ */ diff --git a/arch/mips/include/asm/mach-sead3/war.h b/arch/mips/include/asm/mach-sead3/war.h deleted file mode 100644 index d068fc4..0000000 --- a/arch/mips/include/asm/mach-sead3/war.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2002, 2004, 2007 by Ralf Baechle - */ -#ifndef __ASM_MIPS_MACH_MIPS_WAR_H -#define __ASM_MIPS_MACH_MIPS_WAR_H - -#define R4600_V1_INDEX_ICACHEOP_WAR 0 -#define R4600_V1_HIT_CACHEOP_WAR 0 -#define R4600_V2_HIT_CACHEOP_WAR 0 -#define R5432_CP0_INTERRUPT_WAR 0 -#define BCM1250_M3_WAR 0 -#define SIBYTE_1956_WAR 0 -#define MIPS4K_ICACHE_REFILL_WAR 1 -#define MIPS_CACHE_SYNC_WAR 1 -#define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define ICACHE_REFILLS_WORKAROUND_WAR 1 -#define R10000_LLSC_WAR 0 -#define MIPS34K_MISSED_ITLB_WAR 0 - -#endif /* __ASM_MIPS_MACH_MIPS_WAR_H */ diff --git a/arch/mips/mti-sead3/Makefile b/arch/mips/mti-sead3/Makefile deleted file mode 100644 index 1674b9c..0000000 --- a/arch/mips/mti-sead3/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -# -# Carsten Langgaard, carstenl@mips.com -# Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. -# -# Copyright (C) 2008 Wind River Systems, Inc. -# written by Ralf Baechle -# -# Copyright (C) 2012 MIPS Technoligies, Inc. All rights reserved. -# Steven J. Hill -# -obj-y := sead3-dtshim.o -obj-y += sead3-init.o -obj-y += sead3-int.o -obj-y += sead3-setup.o -obj-y += sead3-time.o diff --git a/arch/mips/mti-sead3/Platform b/arch/mips/mti-sead3/Platform deleted file mode 100644 index 3870924..0000000 --- a/arch/mips/mti-sead3/Platform +++ /dev/null @@ -1,7 +0,0 @@ -# -# MIPS SEAD-3 board -# -platform-$(CONFIG_MIPS_SEAD3) += mti-sead3/ -cflags-$(CONFIG_MIPS_SEAD3) += -I$(srctree)/arch/mips/include/asm/mach-sead3 -load-$(CONFIG_MIPS_SEAD3) += 0xffffffff80100000 -all-$(CONFIG_MIPS_SEAD3) := $(COMPRESSION_FNAME).srec diff --git a/arch/mips/mti-sead3/sead3-dtshim.c b/arch/mips/mti-sead3/sead3-dtshim.c deleted file mode 100644 index d6b0708..0000000 --- a/arch/mips/mti-sead3/sead3-dtshim.c +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Copyright (C) 2016 Imagination Technologies - * Author: Paul Burton - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#define pr_fmt(fmt) "sead3-dtshim: " fmt - -#include -#include -#include - -#include -#include - -#define SEAD_CONFIG CKSEG1ADDR(0x1b100110) -#define SEAD_CONFIG_GIC_PRESENT BIT(1) - -static unsigned char fdt_buf[16 << 10] __initdata; - -static int append_memory(void *fdt) -{ - unsigned long phys_memsize, memsize; - __be32 mem_array[2]; - int err, mem_off; - char *var; - - /* find memory size from the bootloader environment */ - var = fw_getenv("memsize"); - if (var) { - err = kstrtoul(var, 0, &phys_memsize); - if (err) { - pr_err("Failed to read memsize env variable '%s'\n", - var); - return -EINVAL; - } - } else { - pr_warn("The bootloader didn't provide memsize: defaulting to 32MB\n"); - phys_memsize = 32 << 20; - } - - /* default to using all available RAM */ - memsize = phys_memsize; - - /* allow the user to override the usable memory */ - var = strstr(arcs_cmdline, "memsize="); - if (var) - memsize = memparse(var + strlen("memsize="), NULL); - - /* if the user says there's more RAM than we thought, believe them */ - phys_memsize = max_t(unsigned long, phys_memsize, memsize); - - /* find or add a memory node */ - mem_off = fdt_path_offset(fdt, "/memory"); - if (mem_off == -FDT_ERR_NOTFOUND) - mem_off = fdt_add_subnode(fdt, 0, "memory"); - if (mem_off < 0) { - pr_err("Unable to find or add memory DT node: %d\n", mem_off); - return mem_off; - } - - err = fdt_setprop_string(fdt, mem_off, "device_type", "memory"); - if (err) { - pr_err("Unable to set memory node device_type: %d\n", err); - return err; - } - - mem_array[0] = 0; - mem_array[1] = cpu_to_be32(phys_memsize); - err = fdt_setprop(fdt, mem_off, "reg", mem_array, sizeof(mem_array)); - if (err) { - pr_err("Unable to set memory regs property: %d\n", err); - return err; - } - - mem_array[0] = 0; - mem_array[1] = cpu_to_be32(memsize); - err = fdt_setprop(fdt, mem_off, "linux,usable-memory", - mem_array, sizeof(mem_array)); - if (err) { - pr_err("Unable to set linux,usable-memory property: %d\n", err); - return err; - } - - return 0; -} - -static int remove_gic(void *fdt) -{ - const unsigned int cpu_ehci_int = 2; - const unsigned int cpu_uart_int = 4; - const unsigned int cpu_eth_int = 6; - int gic_off, cpu_off, uart_off, eth_off, ehci_off, err; - uint32_t cfg, cpu_phandle; - - /* leave the GIC node intact if a GIC is present */ - cfg = __raw_readl((uint32_t *)SEAD_CONFIG); - if (cfg & SEAD_CONFIG_GIC_PRESENT) - return 0; - - gic_off = fdt_node_offset_by_compatible(fdt, -1, "mti,gic"); - if (gic_off < 0) { - pr_err("unable to find DT GIC node: %d\n", gic_off); - return gic_off; - } - - err = fdt_nop_node(fdt, gic_off); - if (err) { - pr_err("unable to nop GIC node\n"); - return err; - } - - cpu_off = fdt_node_offset_by_compatible(fdt, -1, - "mti,cpu-interrupt-controller"); - if (cpu_off < 0) { - pr_err("unable to find CPU intc node: %d\n", cpu_off); - return cpu_off; - } - - cpu_phandle = fdt_get_phandle(fdt, cpu_off); - if (!cpu_phandle) { - pr_err("unable to get CPU intc phandle\n"); - return -EINVAL; - } - - err = fdt_setprop_u32(fdt, 0, "interrupt-parent", cpu_phandle); - if (err) { - pr_err("unable to set root interrupt-parent: %d\n", err); - return err; - } - - uart_off = fdt_node_offset_by_compatible(fdt, -1, "ns16550a"); - while (uart_off >= 0) { - err = fdt_setprop_u32(fdt, uart_off, "interrupts", - cpu_uart_int); - if (err) { - pr_err("unable to set UART interrupts property: %d\n", - err); - return err; - } - - uart_off = fdt_node_offset_by_compatible(fdt, uart_off, - "ns16550a"); - } - if (uart_off != -FDT_ERR_NOTFOUND) { - pr_err("error searching for UART DT node: %d\n", uart_off); - return uart_off; - } - - eth_off = fdt_node_offset_by_compatible(fdt, -1, "smsc,lan9115"); - if (eth_off < 0) { - pr_err("unable to find ethernet DT node: %d\n", eth_off); - return eth_off; - } - - err = fdt_setprop_u32(fdt, eth_off, "interrupts", cpu_eth_int); - if (err) { - pr_err("unable to set ethernet interrupts property: %d\n", err); - return err; - } - - ehci_off = fdt_node_offset_by_compatible(fdt, -1, "mti,sead3-ehci"); - if (ehci_off < 0) { - pr_err("unable to find EHCI DT node: %d\n", ehci_off); - return ehci_off; - } - - err = fdt_setprop_u32(fdt, ehci_off, "interrupts", cpu_ehci_int); - if (err) { - pr_err("unable to set EHCI interrupts property: %d\n", err); - return err; - } - - return 0; -} - -static int serial_config(void *fdt) -{ - const char *yamontty, *mode_var; - char mode_var_name[9], path[18], parity; - unsigned int uart, baud, stop_bits; - bool hw_flow; - int chosen_off, err; - - yamontty = fw_getenv("yamontty"); - if (!yamontty || !strcmp(yamontty, "tty0")) { - uart = 0; - } else if (!strcmp(yamontty, "tty1")) { - uart = 1; - } else { - pr_warn("yamontty environment variable '%s' invalid\n", - yamontty); - uart = 0; - } - - baud = stop_bits = 0; - parity = 0; - hw_flow = false; - - snprintf(mode_var_name, sizeof(mode_var_name), "modetty%u", uart); - mode_var = fw_getenv(mode_var_name); - if (mode_var) { - while (mode_var[0] >= '0' && mode_var[0] <= '9') { - baud *= 10; - baud += mode_var[0] - '0'; - mode_var++; - } - if (mode_var[0] == ',') - mode_var++; - if (mode_var[0]) - parity = mode_var[0]; - if (mode_var[0] == ',') - mode_var++; - if (mode_var[0]) - stop_bits = mode_var[0] - '0'; - if (mode_var[0] == ',') - mode_var++; - if (!strcmp(mode_var, "hw")) - hw_flow = true; - } - - if (!baud) - baud = 38400; - - if (parity != 'e' && parity != 'n' && parity != 'o') - parity = 'n'; - - if (stop_bits != 7 && stop_bits != 8) - stop_bits = 8; - - WARN_ON(snprintf(path, sizeof(path), "uart%u:%u%c%u%s", - uart, baud, parity, stop_bits, - hw_flow ? "r" : "") >= sizeof(path)); - - /* find or add chosen node */ - chosen_off = fdt_path_offset(fdt, "/chosen"); - if (chosen_off == -FDT_ERR_NOTFOUND) - chosen_off = fdt_path_offset(fdt, "/chosen@0"); - if (chosen_off == -FDT_ERR_NOTFOUND) - chosen_off = fdt_add_subnode(fdt, 0, "chosen"); - if (chosen_off < 0) { - pr_err("Unable to find or add DT chosen node: %d\n", - chosen_off); - return chosen_off; - } - - err = fdt_setprop_string(fdt, chosen_off, "stdout-path", path); - if (err) { - pr_err("Unable to set stdout-path property: %d\n", err); - return err; - } - - return 0; -} - -void __init *sead3_dt_shim(void *fdt) -{ - int err; - - if (fdt_check_header(fdt)) - panic("Corrupt DT"); - - /* if this isn't SEAD3, leave the DT alone */ - if (fdt_node_check_compatible(fdt, 0, "mti,sead-3")) - return fdt; - - err = fdt_open_into(fdt, fdt_buf, sizeof(fdt_buf)); - if (err) - panic("Unable to open FDT: %d", err); - - err = append_memory(fdt_buf); - if (err) - panic("Unable to patch FDT: %d", err); - - err = remove_gic(fdt_buf); - if (err) - panic("Unable to patch FDT: %d", err); - - err = serial_config(fdt_buf); - if (err) - panic("Unable to patch FDT: %d", err); - - err = fdt_pack(fdt_buf); - if (err) - panic("Unable to pack FDT: %d\n", err); - - return fdt_buf; -} diff --git a/arch/mips/mti-sead3/sead3-init.c b/arch/mips/mti-sead3/sead3-init.c deleted file mode 100644 index 50f3fcb..0000000 --- a/arch/mips/mti-sead3/sead3-init.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. - */ -#include -#include - -#include -#include -#include -#include -#include - -extern char except_vec_nmi; -extern char except_vec_ejtag_debug; - -static void __init mips_nmi_setup(void) -{ - void *base; - - base = cpu_has_veic ? - (void *)(CAC_BASE + 0xa80) : - (void *)(CAC_BASE + 0x380); -#ifdef CONFIG_CPU_MICROMIPS - /* - * Decrement the exception vector address by one for microMIPS. - */ - memcpy(base, (&except_vec_nmi - 1), 0x80); - - /* - * This is a hack. We do not know if the boot loader was built with - * microMIPS instructions or not. If it was not, the NMI exception - * code at 0x80000a80 will be taken in MIPS32 mode. The hand coded - * assembly below forces us into microMIPS mode if we are a pure - * microMIPS kernel. The assembly instructions are: - * - * 3C1A8000 lui k0,0x8000 - * 375A0381 ori k0,k0,0x381 - * 03400008 jr k0 - * 00000000 nop - * - * The mode switch occurs by jumping to the unaligned exception - * vector address at 0x80000381 which would have been 0x80000380 - * in MIPS32 mode. The jump to the unaligned address transitions - * us into microMIPS mode. - */ - if (!cpu_has_veic) { - void *base2 = (void *)(CAC_BASE + 0xa80); - *((unsigned int *)base2) = 0x3c1a8000; - *((unsigned int *)base2 + 1) = 0x375a0381; - *((unsigned int *)base2 + 2) = 0x03400008; - *((unsigned int *)base2 + 3) = 0x00000000; - flush_icache_range((unsigned long)base2, - (unsigned long)base2 + 0x10); - } -#else - memcpy(base, &except_vec_nmi, 0x80); -#endif - flush_icache_range((unsigned long)base, (unsigned long)base + 0x80); -} - -static void __init mips_ejtag_setup(void) -{ - void *base; - - base = cpu_has_veic ? - (void *)(CAC_BASE + 0xa00) : - (void *)(CAC_BASE + 0x300); -#ifdef CONFIG_CPU_MICROMIPS - /* Deja vu... */ - memcpy(base, (&except_vec_ejtag_debug - 1), 0x80); - if (!cpu_has_veic) { - void *base2 = (void *)(CAC_BASE + 0xa00); - *((unsigned int *)base2) = 0x3c1a8000; - *((unsigned int *)base2 + 1) = 0x375a0301; - *((unsigned int *)base2 + 2) = 0x03400008; - *((unsigned int *)base2 + 3) = 0x00000000; - flush_icache_range((unsigned long)base2, - (unsigned long)base2 + 0x10); - } -#else - memcpy(base, &except_vec_ejtag_debug, 0x80); -#endif - flush_icache_range((unsigned long)base, (unsigned long)base + 0x80); -} - -void __init prom_init(void) -{ - board_nmi_handler_setup = mips_nmi_setup; - board_ejtag_handler_setup = mips_ejtag_setup; - - fw_init_cmdline(); -} - -void __init prom_free_prom_memory(void) -{ -} diff --git a/arch/mips/mti-sead3/sead3-int.c b/arch/mips/mti-sead3/sead3-int.c deleted file mode 100644 index 2e6b732..0000000 --- a/arch/mips/mti-sead3/sead3-int.c +++ /dev/null @@ -1,23 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. - */ -#include -#include -#include - -#include -#include - -void __init arch_init_irq(void) -{ - irqchip_init(); - - pr_info("GIC: %spresent\n", (gic_present) ? "" : "not "); - pr_info("EIC: %s\n", - (current_cpu_data.options & MIPS_CPU_VEIC) ? "on" : "off"); -} - diff --git a/arch/mips/mti-sead3/sead3-setup.c b/arch/mips/mti-sead3/sead3-setup.c deleted file mode 100644 index c915e54..0000000 --- a/arch/mips/mti-sead3/sead3-setup.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. - * Copyright (C) 2013 Imagination Technologies Ltd. - */ -#include -#include -#include - -#include - -#include -#include - -const char *get_system_type(void) -{ - return "MIPS SEAD3"; -} - -void __init *plat_get_fdt(void) -{ - return (void *)__dtb_start; -} - -void __init plat_mem_setup(void) -{ - void *fdt = plat_get_fdt(); - - fdt = sead3_dt_shim(fdt); - __dt_setup_arch(fdt); -} - -void __init device_tree_init(void) -{ - unflatten_and_copy_device_tree(); -} diff --git a/arch/mips/mti-sead3/sead3-time.c b/arch/mips/mti-sead3/sead3-time.c deleted file mode 100644 index 71feb51..0000000 --- a/arch/mips/mti-sead3/sead3-time.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. - */ -#include -#include - -#include -#include -#include -#include -#include - -static void __iomem *status_reg = (void __iomem *)0xbf000410; - -/* - * Estimate CPU frequency. Sets mips_hpt_frequency as a side-effect. - */ -static unsigned int __init estimate_cpu_frequency(void) -{ - unsigned int prid = read_c0_prid() & (PRID_COMP_MASK | PRID_IMP_MASK); - unsigned int tick = 0; - unsigned int freq; - unsigned int orig; - unsigned long flags; - - local_irq_save(flags); - - orig = readl(status_reg) & 0x2; /* get original sample */ - /* wait for transition */ - while ((readl(status_reg) & 0x2) == orig) - ; - orig = orig ^ 0x2; /* flip the bit */ - - write_c0_count(0); - - /* wait 1 second (the sampling clock transitions every 10ms) */ - while (tick < 100) { - /* wait for transition */ - while ((readl(status_reg) & 0x2) == orig) - ; - orig = orig ^ 0x2; /* flip the bit */ - tick++; - } - - freq = read_c0_count(); - - local_irq_restore(flags); - - mips_hpt_frequency = freq; - - /* Adjust for processor */ - if ((prid != (PRID_COMP_MIPS | PRID_IMP_20KC)) && - (prid != (PRID_COMP_MIPS | PRID_IMP_25KF))) - freq *= 2; - - freq += 5000; /* rounding */ - freq -= freq%10000; - - return freq ; -} - -int get_c0_perfcount_int(void) -{ - if (gic_present) - return gic_get_c0_perfcount_int(); - if (cp0_perfcount_irq >= 0) - return MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; - return -1; -} -EXPORT_SYMBOL_GPL(get_c0_perfcount_int); - -unsigned int get_c0_compare_int(void) -{ - if (gic_present) - return gic_get_c0_compare_int(); - return MIPS_CPU_IRQ_BASE + cp0_compare_irq; -} - -void __init plat_time_init(void) -{ - unsigned int est_freq; - - est_freq = estimate_cpu_frequency(); - - pr_debug("CPU frequency %d.%02d MHz\n", (est_freq / 1000000), - (est_freq % 1000000) * 100 / 1000000); -} -- cgit v0.10.2 From cabca8c098f00c91aeb59170e86e5c5fa4f494c2 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Sat, 8 Oct 2016 22:47:14 +0100 Subject: MIPS: Enable hardened usercopy Enable CONFIG_HARDENED_USERCOPY checks for MIPS, calling check_object size in all of copy_{to,from}_user(), __copy_{to,from}_user() & __copy_{to,from}_user_inatomic(). Signed-off-by: Paul Burton Cc: Kees Cook Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/14371/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index a7d9224..7f6da2c8 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -66,6 +66,7 @@ config MIPS select HANDLE_DOMAIN_IRQ select HAVE_EXIT_THREAD select HAVE_REGS_AND_STACK_ACCESS_API + select HAVE_ARCH_HARDENED_USERCOPY menu "Machine selection" diff --git a/arch/mips/include/asm/uaccess.h b/arch/mips/include/asm/uaccess.h index 21a2aab..c65707d 100644 --- a/arch/mips/include/asm/uaccess.h +++ b/arch/mips/include/asm/uaccess.h @@ -858,7 +858,10 @@ extern size_t __copy_user(void *__to, const void *__from, size_t __n); __cu_to = (to); \ __cu_from = (from); \ __cu_len = (n); \ + \ + check_object_size(__cu_from, __cu_len, true); \ might_fault(); \ + \ if (eva_kernel_access()) \ __cu_len = __invoke_copy_to_kernel(__cu_to, __cu_from, \ __cu_len); \ @@ -879,6 +882,9 @@ extern size_t __copy_user_inatomic(void *__to, const void *__from, size_t __n); __cu_to = (to); \ __cu_from = (from); \ __cu_len = (n); \ + \ + check_object_size(__cu_from, __cu_len, true); \ + \ if (eva_kernel_access()) \ __cu_len = __invoke_copy_to_kernel(__cu_to, __cu_from, \ __cu_len); \ @@ -897,6 +903,9 @@ extern size_t __copy_user_inatomic(void *__to, const void *__from, size_t __n); __cu_to = (to); \ __cu_from = (from); \ __cu_len = (n); \ + \ + check_object_size(__cu_to, __cu_len, false); \ + \ if (eva_kernel_access()) \ __cu_len = __invoke_copy_from_kernel_inatomic(__cu_to, \ __cu_from,\ @@ -931,6 +940,9 @@ extern size_t __copy_user_inatomic(void *__to, const void *__from, size_t __n); __cu_to = (to); \ __cu_from = (from); \ __cu_len = (n); \ + \ + check_object_size(__cu_from, __cu_len, true); \ + \ if (eva_kernel_access()) { \ __cu_len = __invoke_copy_to_kernel(__cu_to, \ __cu_from, \ @@ -1123,6 +1135,9 @@ extern size_t __copy_in_user_eva(void *__to, const void *__from, size_t __n); __cu_to = (to); \ __cu_from = (from); \ __cu_len = (n); \ + \ + check_object_size(__cu_to, __cu_len, false); \ + \ if (eva_kernel_access()) { \ __cu_len = __invoke_copy_from_kernel(__cu_to, \ __cu_from, \ @@ -1161,6 +1176,9 @@ extern size_t __copy_in_user_eva(void *__to, const void *__from, size_t __n); __cu_to = (to); \ __cu_from = (from); \ __cu_len = (n); \ + \ + check_object_size(__cu_to, __cu_len, false); \ + \ if (eva_kernel_access()) { \ __cu_len = __invoke_copy_from_kernel(__cu_to, \ __cu_from, \ -- cgit v0.10.2 From 034827c727f7f3946a18355b63995b402c226c82 Mon Sep 17 00:00:00 2001 From: James Hogan Date: Thu, 6 Oct 2016 23:10:41 +0100 Subject: MIPS: Fix -mabi=64 build of vdso.lds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The native ABI vDSO linker script vdso.lds is built by preprocessing vdso.lds.S, with the native -mabi flag passed in to get the correct ABI definitions. Unfortunately however certain toolchains choke on -mabi=64 without a corresponding compatible -march flag, for example: cc1: error: ‘-march=mips32r2’ is not compatible with the selected ABI scripts/Makefile.build:338: recipe for target 'arch/mips/vdso/vdso.lds' failed Fix this by including ccflags-vdso in the KBUILD_CPPFLAGS for vdso.lds, which includes the appropriate -march flag. Fixes: ebb5e78cc634 ("MIPS: Initial implementation of a VDSO") Signed-off-by: James Hogan Reviewed-by: Maciej W. Rozycki Cc: linux-mips@linux-mips.org Cc: stable@vger.kernel.org # 4.4.x- Patchwork: https://patchwork.linux-mips.org/patch/14368/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/vdso/Makefile b/arch/mips/vdso/Makefile index 3b4538e..de9e8836 100644 --- a/arch/mips/vdso/Makefile +++ b/arch/mips/vdso/Makefile @@ -82,7 +82,7 @@ obj-vdso := $(obj-vdso-y:%.o=$(obj)/%.o) $(obj-vdso): KBUILD_CFLAGS := $(cflags-vdso) $(native-abi) $(obj-vdso): KBUILD_AFLAGS := $(aflags-vdso) $(native-abi) -$(obj)/vdso.lds: KBUILD_CPPFLAGS := $(native-abi) +$(obj)/vdso.lds: KBUILD_CPPFLAGS := $(ccflags-vdso) $(native-abi) $(obj)/vdso.so.dbg.raw: $(obj)/vdso.lds $(obj-vdso) FORCE $(call if_changed,vdsold) -- cgit v0.10.2 From 9445622cfbc38c980f1755fc1132a3a460b5a529 Mon Sep 17 00:00:00 2001 From: James Hogan Date: Fri, 7 Oct 2016 10:23:46 +0100 Subject: MIPS: VDSO: Drop duplicated -I*/-E* aflags The aflags-vdso is based on ccflags-vdso, which already contains the -I* and -EL/-EB flags from KBUILD_CFLAGS, but those flags are needlessly added again to aflags-vdso. Drop the duplication. Signed-off-by: James Hogan Reported-by: Maciej W. Rozycki Reviewed-by: Maciej W. Rozycki Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/14369/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/vdso/Makefile b/arch/mips/vdso/Makefile index de9e8836..c3dc12a 100644 --- a/arch/mips/vdso/Makefile +++ b/arch/mips/vdso/Makefile @@ -13,8 +13,6 @@ cflags-vdso := $(ccflags-vdso) \ -DDISABLE_BRANCH_PROFILING \ $(call cc-option, -fno-stack-protector) aflags-vdso := $(ccflags-vdso) \ - $(filter -I%,$(KBUILD_CFLAGS)) \ - $(filter -E%,$(KBUILD_CFLAGS)) \ -D__ASSEMBLY__ -Wa,-gdwarf-2 # -- cgit v0.10.2 From 74f1077b5b783e7bf4fa3007cefdc8dbd6c07518 Mon Sep 17 00:00:00 2001 From: Marcin Nowakowski Date: Wed, 12 Oct 2016 09:32:56 +0200 Subject: MIPS: ptrace: Fix regs_return_value for kernel context Currently regs_return_value always negates reg[2] if it determines the syscall has failed, but when called in kernel context this check is invalid and may result in returning a wrong value. This fixes errors reported by CONFIG_KPROBES_SANITY_TEST Fixes: d7e7528bcd45 ("Audit: push audit success and retcode into arch ptrace.h") Signed-off-by: Marcin Nowakowski Cc: linux-mips@linux-mips.org Cc: stable@vger.kernel.org # 3.3+ Patchwork: https://patchwork.linux-mips.org/patch/14381/ Signed-off-by: Ralf Baechle diff --git a/arch/mips/include/asm/ptrace.h b/arch/mips/include/asm/ptrace.h index f6fc6aa..b657861 100644 --- a/arch/mips/include/asm/ptrace.h +++ b/arch/mips/include/asm/ptrace.h @@ -152,7 +152,7 @@ static inline int is_syscall_success(struct pt_regs *regs) static inline long regs_return_value(struct pt_regs *regs) { - if (is_syscall_success(regs)) + if (is_syscall_success(regs) || !user_mode(regs)) return regs->regs[2]; else return -regs->regs[2]; -- cgit v0.10.2 From 38b8767462120c62a5046b529c80b06861f9ac85 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 13 Oct 2016 17:09:36 +0200 Subject: Documentation: MIPS supports HAVE_REGS_AND_STACK_ACCESS_API This should have been part of 40e084a506eb ('MIPS: Add uprobes support.'). Signed-off-by: Ralf Baechle Fixes: 40e084a506eb ("MIPS: Add uprobes support.") Acked-by: Jonathan Corbet Cc: linux-mips@linux-mips.org Cc: linux-doc@vger.kernel.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14392/ Signed-off-by: Ralf Baechle diff --git a/Documentation/features/perf/kprobes-event/arch-support.txt b/Documentation/features/perf/kprobes-event/arch-support.txt index 9855ad0..4660bf2 100644 --- a/Documentation/features/perf/kprobes-event/arch-support.txt +++ b/Documentation/features/perf/kprobes-event/arch-support.txt @@ -22,7 +22,7 @@ | m68k: | TODO | | metag: | TODO | | microblaze: | TODO | - | mips: | TODO | + | mips: | ok | | mn10300: | TODO | | nios2: | TODO | | openrisc: | TODO | -- cgit v0.10.2