Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1291644 > unrolled thread
| Started by | Joshua Henderson <joshua.henderson@microchip.com> |
|---|---|
| First post | 2015-12-14 23:40 +0100 |
| Last post | 2015-12-14 23:50 +0100 |
| Articles | 18 — 6 participants |
Back to article view | Back to linux.kernel
[PATCH v2 00/14] Initial Microchip PIC32MZDA Support Joshua Henderson <joshua.henderson@microchip.com> - 2015-12-14 23:40 +0100
[PATCH v2 03/14] DEVICETREE: Add PIC32 clock binding documentation Joshua Henderson <joshua.henderson@microchip.com> - 2015-12-14 23:40 +0100
Re: [PATCH v2 03/14] DEVICETREE: Add PIC32 clock binding documentation Rob Herring <robh@kernel.org> - 2015-12-18 16:50 +0100
Re: [PATCH v2 03/14] DEVICETREE: Add PIC32 clock binding documentation Purna Chandra Mandal <purna.mandal@microchip.com> - 2015-12-19 13:00 +0100
[PATCH v2 01/14] DEVICETREE: Add bindings for PIC32 interrupt controller Joshua Henderson <joshua.henderson@microchip.com> - 2015-12-14 23:50 +0100
Re: [PATCH v2 01/14] DEVICETREE: Add bindings for PIC32 interrupt controller Rob Herring <robh@kernel.org> - 2015-12-15 00:40 +0100
[PATCH v2 13/14] MIPS: dts: Add initial DTS for the PIC32MZDA Starter Kit Joshua Henderson <joshua.henderson@microchip.com> - 2015-12-14 23:50 +0100
[PATCH v2 09/14] DEVICETREE: Add bindings for PIC32 UART driver Joshua Henderson <joshua.henderson@microchip.com> - 2015-12-14 23:50 +0100
Re: [PATCH v2 09/14] DEVICETREE: Add bindings for PIC32 UART driver Rob Herring <robh@kernel.org> - 2015-12-15 21:10 +0100
[PATCH v2 11/14] DEVICETREE: Add bindings for PIC32 SDHCI host controller Joshua Henderson <joshua.henderson@microchip.com> - 2015-12-14 23:50 +0100
Re: [PATCH v2 11/14] DEVICETREE: Add bindings for PIC32 SDHCI host controller Rob Herring <robh@kernel.org> - 2015-12-15 21:10 +0100
[PATCH v2 12/14] mmc: sdhci-pic32: Add PIC32 SDHCI host controller driver Joshua Henderson <joshua.henderson@microchip.com> - 2015-12-14 23:50 +0100
Re: [PATCH v2 12/14] mmc: sdhci-pic32: Add PIC32 SDHCI host controller driver Andy Green <andy.green@linaro.org> - 2015-12-15 01:40 +0100
RE: [PATCH v2 12/14] mmc: sdhci-pic32: Add PIC32 SDHCI host controller driver <Paul.Thacker@microchip.com> - 2015-12-16 18:40 +0100
Re: [PATCH v2 12/14] mmc: sdhci-pic32: Add PIC32 SDHCI host controller driver Ulf Hansson <ulf.hansson@linaro.org> - 2015-12-16 11:50 +0100
RE: [PATCH v2 12/14] mmc: sdhci-pic32: Add PIC32 SDHCI host controller driver <Paul.Thacker@microchip.com> - 2015-12-17 19:10 +0100
[PATCH v2 10/14] serial: pic32_uart: Add PIC32 UART driver Joshua Henderson <joshua.henderson@microchip.com> - 2015-12-14 23:50 +0100
[PATCH v2 14/14] MIPS: pic32mzda: Add initial PIC32MZDA Starter Kit defconfig Joshua Henderson <joshua.henderson@microchip.com> - 2015-12-14 23:50 +0100
| From | Joshua Henderson <joshua.henderson@microchip.com> |
|---|---|
| Date | 2015-12-14 23:40 +0100 |
| Subject | [PATCH v2 00/14] Initial Microchip PIC32MZDA Support |
| Message-ID | <qFJWF-3Ss-7@gated-at.bofh.it> |
This patch series adds support for the Microchip PIC32MZDA MIPS platform. All drivers required to boot from a MMC uSD card are included. Clock, external interrupt controller, serial, SDHCI, and pinctrl drivers are included. This has been tested on a PIC32MZDA Starter Kit. A tree with these changes is available at [0]. [0] https://github.com/joshua-henderson/linux/tree/pic32-upstream-v2 Changes since v1 (https://lkml.org/lkml/2015/11/20/848): + Rename all DT compatible properties to be chip specific. + Remove hardware interrupt priorities from interrupt controller DT bindings. + Remove all dependencies on include headers used by PIC32 DTS files. + Remove arch/mips/include/asm/mach-pic32/gpio.h + Drop usage of the following, mostly non-standard, properties in DT bindings: device_type piomode no-1-8-v uart-has-rtscts clock-frequency => assigned-clock-rate + Remove PIC32 memory PLL support from DT. + Replace empty 'ranges' with populated one for clock tree node. + Rename all instances of "USART" to "UART". + Remove 'interrupts' property from FSCM of PIC32 clock tree node. + Add default REFCLK rate initialization required for SDHCI in DTS. + Remove default frequency setup for REFOSC clocks in -clk DTS. + Address missing static on local functions and other sparse warnings in several drivers. + Update pinctrl driver to address major binding and architectural issues. + Remove redundant probing 'pb7_clk' to find CPU clock. + Remove unused PIC32 MPLL support. + Remove support for initializing default parent/rate for REFOSC clocks. + Be consistent and use only "SDHCI" when refering to SD host controller + Remove unecessary PIC32 sdhci_ops min clock function. + Make platform PIC32[_CLR|_SET|_INV] register macros safer. Andrei Pistirica (4): DEVICETREE: Add bindings for PIC32 UART driver serial: pic32_uart: Add PIC32 UART driver DEVICETREE: Add bindings for PIC32 SDHCI host controller mmc: sdhci-pic32: Add PIC32 SDHCI host controller driver Cristian Birsan (2): DEVICETREE: Add bindings for PIC32 interrupt controller irqchip: irq-pic32-evic: Add support for PIC32 interrupt controller Joshua Henderson (6): DEVICETREE: Add bindings for PIC32/MZDA platforms MIPS: Add support for PIC32MZDA platform DEVICETREE: Add bindings for PIC32 pin control and GPIO pinctrl: pinctrl-pic32: Add PIC32 pin control driver MIPS: dts: Add initial DTS for the PIC32MZDA Starter Kit MIPS: pic32mzda: Add initial PIC32MZDA Starter Kit defconfig Purna Chandra Mandal (2): DEVICETREE: Add PIC32 clock binding documentation clk: clk-pic32: Add PIC32 clock driver .../devicetree/bindings/clock/microchip,pic32.txt | 256 +++ .../bindings/gpio/microchip,pic32-gpio.txt | 32 + .../interrupt-controller/microchip,pic32-evic.txt | 58 + .../bindings/mips/pic32/microchip,pic32mzda.txt | 33 + .../bindings/mmc/microchip,sdhci-pic32.txt | 29 + .../bindings/pinctrl/microchip,pic32-pinctrl.txt | 93 + .../bindings/serial/microchip,pic32-uart.txt | 29 + arch/mips/Kbuild.platforms | 1 + arch/mips/Kconfig | 9 + arch/mips/boot/dts/Makefile | 1 + arch/mips/boot/dts/pic32/Makefile | 12 + arch/mips/boot/dts/pic32/pic32mzda-clk.dtsi | 235 ++ arch/mips/boot/dts/pic32/pic32mzda.dtsi | 275 +++ arch/mips/boot/dts/pic32/pic32mzda_sk.dts | 151 ++ arch/mips/configs/pic32mzda_defconfig | 88 + .../include/asm/mach-pic32/cpu-feature-overrides.h | 32 + arch/mips/include/asm/mach-pic32/irq.h | 22 + arch/mips/include/asm/mach-pic32/pic32.h | 44 + arch/mips/include/asm/mach-pic32/spaces.h | 24 + arch/mips/pic32/Kconfig | 50 + arch/mips/pic32/Makefile | 6 + arch/mips/pic32/Platform | 7 + arch/mips/pic32/common/Makefile | 5 + arch/mips/pic32/common/irq.c | 21 + arch/mips/pic32/common/reset.c | 62 + arch/mips/pic32/pic32mzda/Makefile | 9 + arch/mips/pic32/pic32mzda/config.c | 126 ++ arch/mips/pic32/pic32mzda/early_clk.c | 106 + arch/mips/pic32/pic32mzda/early_console.c | 171 ++ arch/mips/pic32/pic32mzda/early_pin.c | 275 +++ arch/mips/pic32/pic32mzda/early_pin.h | 241 ++ arch/mips/pic32/pic32mzda/init.c | 156 ++ arch/mips/pic32/pic32mzda/pic32mzda.h | 29 + arch/mips/pic32/pic32mzda/time.c | 44 + drivers/clk/Kconfig | 3 + drivers/clk/Makefile | 1 + drivers/clk/clk-pic32.c | 1804 +++++++++++++++ drivers/irqchip/Makefile | 1 + drivers/irqchip/irq-pic32-evic.c | 321 +++ drivers/mmc/host/Kconfig | 11 + drivers/mmc/host/Makefile | 1 + drivers/mmc/host/sdhci-pic32.c | 291 +++ drivers/pinctrl/Kconfig | 17 + drivers/pinctrl/Makefile | 1 + drivers/pinctrl/pinctrl-pic32.c | 2339 ++++++++++++++++++++ drivers/pinctrl/pinctrl-pic32.h | 141 ++ drivers/tty/serial/Kconfig | 21 + drivers/tty/serial/Makefile | 1 + drivers/tty/serial/pic32_uart.c | 927 ++++++++ drivers/tty/serial/pic32_uart.h | 198 ++ include/linux/irqchip/pic32-evic.h | 19 + include/linux/platform_data/sdhci-pic32.h | 22 + include/uapi/linux/serial_core.h | 3 + 53 files changed, 8854 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/microchip,pic32.txt create mode 100644 Documentation/devicetree/bindings/gpio/microchip,pic32-gpio.txt create mode 100644 Documentation/devicetree/bindings/interrupt-controller/microchip,pic32-evic.txt create mode 100644 Documentation/devicetree/bindings/mips/pic32/microchip,pic32mzda.txt create mode 100644 Documentation/devicetree/bindings/mmc/microchip,sdhci-pic32.txt create mode 100644 Documentation/devicetree/bindings/pinctrl/microchip,pic32-pinctrl.txt create mode 100644 Documentation/devicetree/bindings/serial/microchip,pic32-uart.txt create mode 100644 arch/mips/boot/dts/pic32/Makefile create mode 100644 arch/mips/boot/dts/pic32/pic32mzda-clk.dtsi create mode 100644 arch/mips/boot/dts/pic32/pic32mzda.dtsi create mode 100644 arch/mips/boot/dts/pic32/pic32mzda_sk.dts create mode 100644 arch/mips/configs/pic32mzda_defconfig create mode 100644 arch/mips/include/asm/mach-pic32/cpu-feature-overrides.h create mode 100644 arch/mips/include/asm/mach-pic32/irq.h create mode 100644 arch/mips/include/asm/mach-pic32/pic32.h create mode 100644 arch/mips/include/asm/mach-pic32/spaces.h create mode 100644 arch/mips/pic32/Kconfig create mode 100644 arch/mips/pic32/Makefile create mode 100644 arch/mips/pic32/Platform create mode 100644 arch/mips/pic32/common/Makefile create mode 100644 arch/mips/pic32/common/irq.c create mode 100644 arch/mips/pic32/common/reset.c create mode 100644 arch/mips/pic32/pic32mzda/Makefile create mode 100644 arch/mips/pic32/pic32mzda/config.c create mode 100644 arch/mips/pic32/pic32mzda/early_clk.c create mode 100644 arch/mips/pic32/pic32mzda/early_console.c create mode 100644 arch/mips/pic32/pic32mzda/early_pin.c create mode 100644 arch/mips/pic32/pic32mzda/early_pin.h create mode 100644 arch/mips/pic32/pic32mzda/init.c create mode 100644 arch/mips/pic32/pic32mzda/pic32mzda.h create mode 100644 arch/mips/pic32/pic32mzda/time.c create mode 100644 drivers/clk/clk-pic32.c create mode 100644 drivers/irqchip/irq-pic32-evic.c create mode 100644 drivers/mmc/host/sdhci-pic32.c create mode 100644 drivers/pinctrl/pinctrl-pic32.c create mode 100644 drivers/pinctrl/pinctrl-pic32.h create mode 100644 drivers/tty/serial/pic32_uart.c create mode 100644 drivers/tty/serial/pic32_uart.h create mode 100644 include/linux/irqchip/pic32-evic.h create mode 100644 include/linux/platform_data/sdhci-pic32.h -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [next] | [standalone]
| From | Joshua Henderson <joshua.henderson@microchip.com> |
|---|---|
| Date | 2015-12-14 23:40 +0100 |
| Subject | [PATCH v2 03/14] DEVICETREE: Add PIC32 clock binding documentation |
| Message-ID | <qFJWI-3Ss-75@gated-at.bofh.it> |
| In reply to | #1291644 |
From: Purna Chandra Mandal <purna.mandal@microchip.com>
Document the devicetree bindings for the clock driver found on Microchip
PIC32 class devices.
Signed-off-by: Purna Chandra Mandal <purna.mandal@microchip.com>
Signed-off-by: Joshua Henderson <joshua.henderson@microchip.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
---
.../devicetree/bindings/clock/microchip,pic32.txt | 256 ++++++++++++++++++++
1 file changed, 256 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/microchip,pic32.txt
diff --git a/Documentation/devicetree/bindings/clock/microchip,pic32.txt b/Documentation/devicetree/bindings/clock/microchip,pic32.txt
new file mode 100644
index 0000000..f50c653
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/microchip,pic32.txt
@@ -0,0 +1,256 @@
+Binding for a Clock hardware block found on
+certain Microchip PIC32 MCU devices.
+
+Microchip SoC clocks-node consists of few oscillators, PLL, multiplexer
+and few divider nodes.
+
+We will find only the base address of the clock tree, this base
+address is common for some of the subnodes, not all. If no address is
+specified for any of subnode base address of the clock tree will be
+treated as its base. Each of subnodes follow the same common clock
+binding with some additional optional properties.
+
+ clocks_node {
+ reg = <>;
+
+ spll_node {
+ ...
+ };
+
+ frcdiv_node {
+ ...
+ };
+
+ sysclk_mux_node {
+ ...
+ };
+
+ pbdiv_node {
+ ...
+ };
+
+ refoclk_node {
+ ...
+ };
+ ...
+ };
+
+This binding uses the common clock binding[1].
+
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+Required properties:
+- compatible : should be one of "microchip,pic32mzda-clk",
+ "microchip,pic32mzda-sosc", "microchip,pic32mzda-frcdivclk",
+ "microchip,pic32mzda-syspll", "microchip,pic32mzda-sysclk-v2",
+ "microchip,pic32mzda-pbclk", "microchip,pic32mzda-refoclk".
+- reg : A Base address and length of the register set.
+- interrupts : source of interrupt.
+
+Optional properties (for subnodes):
+- #clock-cells: From common clock binding, should be 0.
+- microchip,clock-indices: in multiplexer node clock sources always aren't linear
+ and contiguous. This property helps define clock-sources with respect to
+ the mux clock node.
+- microchip,ignore-unused : ignore gate request even if the gated clock is unused.
+- microchip,status-bit-mask: bitmask for status check. This will be used to confirm
+ particular operation by clock sub-node is completed. It is dependent sub-node.
+- microchip,bit-mask: enable mask, similar to microchip,status-bit-mask.
+- microchip,slew-step: enable frequency slewing(stepping) during rate change;
+ applicable only to sys-clock subnode.
+
+Example:
+
+/* PIC32 specific clks */
+pic32_clktree {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x1f801200 0x200>;
+ compatible = "microchip,pic32mzda-clk";
+ ranges = <0 0x1f801200 0x200>;
+
+ /* secondary oscillator; external input on SOSCI pin */
+ SOSC:sosc_clk {
+ #clock-cells = <0>;
+ compatible = "microchip,pic32mzda-sosc";
+ clock-frequency = <32768>;
+ reg = <0x000 0x10>, /* enable reg */
+ <0x1d0 0x10>; /* status reg */
+ microchip,bit-mask = <0x02>; /* enable mask */
+ microchip,status-bit-mask = <0x10>; /* status-mask*/
+ };
+
+ FRCDIV:frcdiv_clk {
+ #clock-cells = <0>;
+ compatible = "microchip,pic32mzda-frcdivclk";
+ clocks = <&FRC>;
+ clock-output-names = "frcdiv_clk";
+ };
+
+ /* System PLL clock */
+ SYSPLL:spll_clk {
+ #clock-cells = <0>;
+ compatible = "microchip,pic32mzda-syspll";
+ reg = <0x020 0x10>, /* SPLL register */
+ <0x1d0 0x10>; /* CLKSTAT register */
+ clocks = <&POSC>, <&FRC>;
+ clock-output-names = "sys_pll";
+ microchip,status-bit-mask = <0x80>; /* SPLLRDY */
+ };
+
+ /* system clock; mux with postdiv & slew */
+ SYSCLK:sys_clk {
+ #clock-cells = <0>;
+ compatible = "microchip,pic32mzda-sysclk-v2";
+ reg = <0x1c0 0x04>; /* SLEWCON */
+ clocks = <&FRCDIV>, <&SYSPLL>, <&POSC>, <&SOSC>,
+ <&LPRC>, <&FRCDIV>;
+ microchip,clock-indices = <0>, <1>, <2>, <4>, <5>, <7>;
+ clock-output-names = "sys_clk";
+ };
+
+ /* UPLL is integral part of USB PHY; UTMI clk for USBCORE */
+ UPLL:usb_phy_clk {
+ #clock-cells = <0>;
+ compatible = "fixed-clocks";
+ clock-frequency = <24000000>;
+ clock-output-names = "usbphy_clk";
+ };
+
+ /* Peripheral bus1 clock */
+ PBCLK1:pb1_clk {
+ reg = <0x140 0x10>;
+ #clock-cells = <0>;
+ compatible = "microchip,pic32mzda-pbclk";
+ clocks = <&SYSCLK>;
+ clock-output-names = "pb1_clk";
+ /* used by system modules, not gateable */
+ microchip,ignore-unused;
+ };
+
+ /* Peripheral bus2 clock */
+ PBCLK2:pb2_clk {
+ reg = <0x150 0x10>;
+ #clock-cells = <0>;
+ compatible = "microchip,pic32mzda-pbclk";
+ clocks = <&SYSCLK>;
+ clock-output-names = "pb2_clk";
+ /* avoid gating even if unused */
+ microchip,ignore-unused;
+ };
+
+ /* Peripheral bus3 clock */
+ PBCLK3:pb3_clk {
+ reg = <0x160 0x10>;
+ #clock-cells = <0>;
+ compatible = "microchip,pic32mzda-pbclk";
+ clocks = <&SYSCLK>;
+ clock-output-names = "pb3_clk";
+ };
+
+ /* Peripheral bus4 clock(I/O ports, GPIO) */
+ PBCLK4:pb4_clk {
+ reg = <0x170 0x10>;
+ #clock-cells = <0>;
+ compatible = "microchip,pic32mzda-pbclk";
+ clocks = <&SYSCLK>;
+ clock-output-names = "pb4_clk";
+ };
+
+ /* Peripheral bus clock */
+ PBCLK5:pb5_clk {
+ reg = <0x180 0x10>;
+ #clock-cells = <0>;
+ compatible = "microchip,pic32mzda-pbclk";
+ clocks = <&SYSCLK>;
+ clock-output-names = "pb5_clk";
+ };
+
+ /* Peripheral Bus6 clock; */
+ PBCLK6:pb6_clk {
+ reg = <0x190 0x10>;
+ compatible = "microchip,pic32mzda-pbclk";
+ clocks = <&SYSCLK>;
+ #clock-cells = <0>;
+ };
+
+ /* Peripheral bus7 clock */
+ PBCLK7:pb7_clk {
+ reg = <0x1A0 0x10>;
+ #clock-cells = <0>;
+ compatible = "microchip,pic32mzda-pbclk";
+ /* CPU is driven by this clock; so named */
+ clock-output-names = "cpu_clk";
+ clocks = <&SYSCLK>;
+ };
+
+ /* Reference Oscillator clock for SPI/I2S */
+ REFCLKO1:refo1_clk {
+ reg = <0x080 0x20>;
+ #clock-cells = <0>;
+ compatible = "microchip,pic32mzda-refoclk";
+ clocks = <&SYSCLK>, <&PBCLK1>, <&POSC>, <&FRC>, <&LPRC>,
+ <&SOSC>, <&SYSPLL>, <&REFIx>, <&BFRC>;
+ microchip,clock-indices = <0>, <1>, <2>, <3>, <4>, <5>,
+ <7>, <8>, <9>;
+ clock-output-names = "refo1_clk";
+ };
+
+ /* Reference Oscillator clock for SQI */
+ REFCLKO2:refo2_clk {
+ reg = <0x0A0 0x20>;
+ #clock-cells = <0>;
+ compatible = "microchip,pic32mzda-refoclk";
+ clocks = <&SYSCLK>, <&PBCLK1>, <&POSC>, <&FRC>, <&LPRC>,
+ <&SOSC>, <&SYSPLL>, <&REFIx>, <&BFRC>;
+ microchip,clock-indices = <0>, <1>, <2>, <3>, <4>, <5>,
+ <7>, <8>, <9>;
+ clock-output-names = "refo2_clk";
+ };
+
+ /* Reference Oscillator clock, ADC */
+ REFCLKO3:refo3_clk {
+ reg = <0x0C0 0x20>;
+ compatible = "microchip,pic32mzda-refoclk";
+ clocks = <&SYSCLK>, <&PBCLK1>, <&POSC>, <&FRC>, <&LPRC>,
+ <&SOSC>, <&SYSPLL>, <&REFIx>, <&BFRC>;
+ microchip,clock-indices = <0>, <1>, <2>, <3>, <4>, <5>,
+ <7>, <8>, <9>;
+ #clock-cells = <0>;
+ clock-output-names = "refo3_clk";
+ };
+
+ /* Reference Oscillator clock */
+ REFCLKO4:refo4_clk {
+ reg = <0x0E0 0x20>;
+ compatible = "microchip,pic32mzda-refoclk";
+ clocks = <&SYSCLK>, <&PBCLK1>, <&POSC>, <&FRC>, <&LPRC>,
+ <&SOSC>, <&SYSPLL>, <&REFIx>, <&BFRC>;
+ microchip,clock-indices = <0>,<1>,<2>,<3>,<4>,<5>,<7>,
+ <8>,<9>;
+ #clock-cells = <0>;
+ clock-output-names = "refo4_clk";
+ };
+
+ /* Reference Oscillator clock, LCD */
+ REFCLKO5:refo5_clk {
+ reg = <0x100 0x20>;
+ compatible = "microchip,pic32mzda-refoclk";
+ clocks = <&SYSCLK>,<&PBCLK1>,<&POSC>,<&FRC>,<&LPRC>,
+ <&SOSC>,<&SYSPLL>,<&REFIx>,<&BFRC>;
+ microchip,clock-indices = <0>, <1>, <2>, <3>, <4>, <5>,
+ <7>, <8>,<9>;
+ #clock-cells = <0>;
+ clock-output-names = "refo5_clk";
+ };
+};
+
+The clock consumer should specify the desired clock by having the clocks in its
+"clock" phandle cell. For example for UART:
+
+uart2: serial@<> {
+ compatible = "microchip,pic32mzda-uart";
+ reg = <>;
+ interrupts = <>;
+ clocks = <&PBCLK2>;
+}
--
1.7.9.5
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Rob Herring <robh@kernel.org> |
|---|---|
| Date | 2015-12-18 16:50 +0100 |
| Subject | Re: [PATCH v2 03/14] DEVICETREE: Add PIC32 clock binding documentation |
| Message-ID | <qH5s5-7vm-11@gated-at.bofh.it> |
| In reply to | #1291650 |
On Mon, Dec 14, 2015 at 03:42:05PM -0700, Joshua Henderson wrote:
> From: Purna Chandra Mandal <purna.mandal@microchip.com>
>
> Document the devicetree bindings for the clock driver found on Microchip
> PIC32 class devices.
>
> Signed-off-by: Purna Chandra Mandal <purna.mandal@microchip.com>
> Signed-off-by: Joshua Henderson <joshua.henderson@microchip.com>
> Cc: Ralf Baechle <ralf@linux-mips.org>
A couple of nits on the example, otherwise:
Acked-by: Rob Herring <robh@kernel.org>
> ---
> .../devicetree/bindings/clock/microchip,pic32.txt | 256 ++++++++++++++++++++
> 1 file changed, 256 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/clock/microchip,pic32.txt
>
> diff --git a/Documentation/devicetree/bindings/clock/microchip,pic32.txt b/Documentation/devicetree/bindings/clock/microchip,pic32.txt
> new file mode 100644
> index 0000000..f50c653
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/microchip,pic32.txt
> @@ -0,0 +1,256 @@
> +Binding for a Clock hardware block found on
> +certain Microchip PIC32 MCU devices.
> +
> +Microchip SoC clocks-node consists of few oscillators, PLL, multiplexer
> +and few divider nodes.
> +
> +We will find only the base address of the clock tree, this base
> +address is common for some of the subnodes, not all. If no address is
> +specified for any of subnode base address of the clock tree will be
> +treated as its base. Each of subnodes follow the same common clock
> +binding with some additional optional properties.
> +
> + clocks_node {
> + reg = <>;
> +
> + spll_node {
> + ...
> + };
> +
> + frcdiv_node {
> + ...
> + };
> +
> + sysclk_mux_node {
> + ...
> + };
> +
> + pbdiv_node {
> + ...
> + };
> +
> + refoclk_node {
> + ...
> + };
> + ...
> + };
> +
> +This binding uses the common clock binding[1].
> +
> +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
> +
> +Required properties:
> +- compatible : should be one of "microchip,pic32mzda-clk",
> + "microchip,pic32mzda-sosc", "microchip,pic32mzda-frcdivclk",
> + "microchip,pic32mzda-syspll", "microchip,pic32mzda-sysclk-v2",
> + "microchip,pic32mzda-pbclk", "microchip,pic32mzda-refoclk".
> +- reg : A Base address and length of the register set.
> +- interrupts : source of interrupt.
> +
> +Optional properties (for subnodes):
> +- #clock-cells: From common clock binding, should be 0.
> +- microchip,clock-indices: in multiplexer node clock sources always aren't linear
> + and contiguous. This property helps define clock-sources with respect to
> + the mux clock node.
> +- microchip,ignore-unused : ignore gate request even if the gated clock is unused.
> +- microchip,status-bit-mask: bitmask for status check. This will be used to confirm
> + particular operation by clock sub-node is completed. It is dependent sub-node.
> +- microchip,bit-mask: enable mask, similar to microchip,status-bit-mask.
> +- microchip,slew-step: enable frequency slewing(stepping) during rate change;
> + applicable only to sys-clock subnode.
> +
> +Example:
> +
> +/* PIC32 specific clks */
> +pic32_clktree {
> + #address-cells = <1>;
> + #size-cells = <1>;
> + reg = <0x1f801200 0x200>;
> + compatible = "microchip,pic32mzda-clk";
> + ranges = <0 0x1f801200 0x200>;
> +
> + /* secondary oscillator; external input on SOSCI pin */
> + SOSC:sosc_clk {
For the ones with reg property, do clock@0 instead of sosc_clk.
> + #clock-cells = <0>;
> + compatible = "microchip,pic32mzda-sosc";
> + clock-frequency = <32768>;
> + reg = <0x000 0x10>, /* enable reg */
> + <0x1d0 0x10>; /* status reg */
> + microchip,bit-mask = <0x02>; /* enable mask */
> + microchip,status-bit-mask = <0x10>; /* status-mask*/
> + };
> +
> + FRCDIV:frcdiv_clk {
> + #clock-cells = <0>;
> + compatible = "microchip,pic32mzda-frcdivclk";
> + clocks = <&FRC>;
> + clock-output-names = "frcdiv_clk";
> + };
> +
> + /* System PLL clock */
> + SYSPLL:spll_clk {
> + #clock-cells = <0>;
> + compatible = "microchip,pic32mzda-syspll";
> + reg = <0x020 0x10>, /* SPLL register */
> + <0x1d0 0x10>; /* CLKSTAT register */
> + clocks = <&POSC>, <&FRC>;
> + clock-output-names = "sys_pll";
> + microchip,status-bit-mask = <0x80>; /* SPLLRDY */
> + };
> +
> + /* system clock; mux with postdiv & slew */
> + SYSCLK:sys_clk {
> + #clock-cells = <0>;
> + compatible = "microchip,pic32mzda-sysclk-v2";
> + reg = <0x1c0 0x04>; /* SLEWCON */
> + clocks = <&FRCDIV>, <&SYSPLL>, <&POSC>, <&SOSC>,
> + <&LPRC>, <&FRCDIV>;
> + microchip,clock-indices = <0>, <1>, <2>, <4>, <5>, <7>;
> + clock-output-names = "sys_clk";
> + };
> +
> + /* UPLL is integral part of USB PHY; UTMI clk for USBCORE */
> + UPLL:usb_phy_clk {
> + #clock-cells = <0>;
> + compatible = "fixed-clocks";
> + clock-frequency = <24000000>;
> + clock-output-names = "usbphy_clk";
> + };
> +
> + /* Peripheral bus1 clock */
> + PBCLK1:pb1_clk {
> + reg = <0x140 0x10>;
> + #clock-cells = <0>;
> + compatible = "microchip,pic32mzda-pbclk";
> + clocks = <&SYSCLK>;
> + clock-output-names = "pb1_clk";
> + /* used by system modules, not gateable */
> + microchip,ignore-unused;
> + };
> +
> + /* Peripheral bus2 clock */
> + PBCLK2:pb2_clk {
> + reg = <0x150 0x10>;
> + #clock-cells = <0>;
> + compatible = "microchip,pic32mzda-pbclk";
> + clocks = <&SYSCLK>;
> + clock-output-names = "pb2_clk";
> + /* avoid gating even if unused */
> + microchip,ignore-unused;
> + };
> +
> + /* Peripheral bus3 clock */
> + PBCLK3:pb3_clk {
> + reg = <0x160 0x10>;
> + #clock-cells = <0>;
> + compatible = "microchip,pic32mzda-pbclk";
> + clocks = <&SYSCLK>;
> + clock-output-names = "pb3_clk";
> + };
> +
> + /* Peripheral bus4 clock(I/O ports, GPIO) */
> + PBCLK4:pb4_clk {
> + reg = <0x170 0x10>;
> + #clock-cells = <0>;
> + compatible = "microchip,pic32mzda-pbclk";
> + clocks = <&SYSCLK>;
> + clock-output-names = "pb4_clk";
> + };
> +
> + /* Peripheral bus clock */
> + PBCLK5:pb5_clk {
> + reg = <0x180 0x10>;
> + #clock-cells = <0>;
> + compatible = "microchip,pic32mzda-pbclk";
> + clocks = <&SYSCLK>;
> + clock-output-names = "pb5_clk";
> + };
> +
> + /* Peripheral Bus6 clock; */
> + PBCLK6:pb6_clk {
> + reg = <0x190 0x10>;
> + compatible = "microchip,pic32mzda-pbclk";
> + clocks = <&SYSCLK>;
> + #clock-cells = <0>;
> + };
> +
> + /* Peripheral bus7 clock */
> + PBCLK7:pb7_clk {
> + reg = <0x1A0 0x10>;
lower case
> + #clock-cells = <0>;
> + compatible = "microchip,pic32mzda-pbclk";
> + /* CPU is driven by this clock; so named */
> + clock-output-names = "cpu_clk";
> + clocks = <&SYSCLK>;
> + };
> +
> + /* Reference Oscillator clock for SPI/I2S */
> + REFCLKO1:refo1_clk {
> + reg = <0x080 0x20>;
> + #clock-cells = <0>;
> + compatible = "microchip,pic32mzda-refoclk";
> + clocks = <&SYSCLK>, <&PBCLK1>, <&POSC>, <&FRC>, <&LPRC>,
> + <&SOSC>, <&SYSPLL>, <&REFIx>, <&BFRC>;
> + microchip,clock-indices = <0>, <1>, <2>, <3>, <4>, <5>,
> + <7>, <8>, <9>;
> + clock-output-names = "refo1_clk";
> + };
> +
> + /* Reference Oscillator clock for SQI */
> + REFCLKO2:refo2_clk {
> + reg = <0x0A0 0x20>;
lower case
> + #clock-cells = <0>;
> + compatible = "microchip,pic32mzda-refoclk";
> + clocks = <&SYSCLK>, <&PBCLK1>, <&POSC>, <&FRC>, <&LPRC>,
> + <&SOSC>, <&SYSPLL>, <&REFIx>, <&BFRC>;
> + microchip,clock-indices = <0>, <1>, <2>, <3>, <4>, <5>,
> + <7>, <8>, <9>;
> + clock-output-names = "refo2_clk";
> + };
> +
> + /* Reference Oscillator clock, ADC */
> + REFCLKO3:refo3_clk {
> + reg = <0x0C0 0x20>;
lower case
> + compatible = "microchip,pic32mzda-refoclk";
> + clocks = <&SYSCLK>, <&PBCLK1>, <&POSC>, <&FRC>, <&LPRC>,
> + <&SOSC>, <&SYSPLL>, <&REFIx>, <&BFRC>;
> + microchip,clock-indices = <0>, <1>, <2>, <3>, <4>, <5>,
> + <7>, <8>, <9>;
> + #clock-cells = <0>;
> + clock-output-names = "refo3_clk";
> + };
> +
> + /* Reference Oscillator clock */
> + REFCLKO4:refo4_clk {
> + reg = <0x0E0 0x20>;
> + compatible = "microchip,pic32mzda-refoclk";
> + clocks = <&SYSCLK>, <&PBCLK1>, <&POSC>, <&FRC>, <&LPRC>,
> + <&SOSC>, <&SYSPLL>, <&REFIx>, <&BFRC>;
> + microchip,clock-indices = <0>,<1>,<2>,<3>,<4>,<5>,<7>,
> + <8>,<9>;
> + #clock-cells = <0>;
> + clock-output-names = "refo4_clk";
> + };
> +
> + /* Reference Oscillator clock, LCD */
> + REFCLKO5:refo5_clk {
> + reg = <0x100 0x20>;
> + compatible = "microchip,pic32mzda-refoclk";
> + clocks = <&SYSCLK>,<&PBCLK1>,<&POSC>,<&FRC>,<&LPRC>,
> + <&SOSC>,<&SYSPLL>,<&REFIx>,<&BFRC>;
> + microchip,clock-indices = <0>, <1>, <2>, <3>, <4>, <5>,
> + <7>, <8>,<9>;
> + #clock-cells = <0>;
> + clock-output-names = "refo5_clk";
> + };
> +};
> +
> +The clock consumer should specify the desired clock by having the clocks in its
> +"clock" phandle cell. For example for UART:
> +
> +uart2: serial@<> {
> + compatible = "microchip,pic32mzda-uart";
> + reg = <>;
> + interrupts = <>;
> + clocks = <&PBCLK2>;
> +}
> --
> 1.7.9.5
>
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Purna Chandra Mandal <purna.mandal@microchip.com> |
|---|---|
| Date | 2015-12-19 13:00 +0100 |
| Subject | Re: [PATCH v2 03/14] DEVICETREE: Add PIC32 clock binding documentation |
| Message-ID | <qHol3-2HU-3@gated-at.bofh.it> |
| In reply to | #1294984 |
On 12/18/2015 09:14 PM, Rob Herring wrote:
> On Mon, Dec 14, 2015 at 03:42:05PM -0700, Joshua Henderson wrote:
>> From: Purna Chandra Mandal <purna.mandal@microchip.com>
>>
>> Document the devicetree bindings for the clock driver found on Microchip
>> PIC32 class devices.
>>
>> Signed-off-by: Purna Chandra Mandal <purna.mandal@microchip.com>
>> Signed-off-by: Joshua Henderson <joshua.henderson@microchip.com>
>> Cc: Ralf Baechle <ralf@linux-mips.org>
> A couple of nits on the example, otherwise:
>
> Acked-by: Rob Herring <robh@kernel.org>
>
>> ---
>> .../devicetree/bindings/clock/microchip,pic32.txt | 256 ++++++++++++++++++++
>> 1 file changed, 256 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/clock/microchip,pic32.txt
>>
>> diff --git a/Documentation/devicetree/bindings/clock/microchip,pic32.txt b/Documentation/devicetree/bindings/clock/microchip,pic32.txt
>> new file mode 100644
>> index 0000000..f50c653
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/clock/microchip,pic32.txt
>> @@ -0,0 +1,256 @@
>> +Binding for a Clock hardware block found on
>> +certain Microchip PIC32 MCU devices.
>> +
>> +Microchip SoC clocks-node consists of few oscillators, PLL, multiplexer
>> +and few divider nodes.
>> +
>> +We will find only the base address of the clock tree, this base
>> +address is common for some of the subnodes, not all. If no address is
>> +specified for any of subnode base address of the clock tree will be
>> +treated as its base. Each of subnodes follow the same common clock
>> +binding with some additional optional properties.
>> +
>> + clocks_node {
>> + reg = <>;
>> +
>> + spll_node {
>> + ...
>> + };
>> +
>> + frcdiv_node {
>> + ...
>> + };
>> +
>> + sysclk_mux_node {
>> + ...
>> + };
>> +
>> + pbdiv_node {
>> + ...
>> + };
>> +
>> + refoclk_node {
>> + ...
>> + };
>> + ...
>> + };
>> +
>> +This binding uses the common clock binding[1].
>> +
>> +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
>> +
>> +Required properties:
>> +- compatible : should be one of "microchip,pic32mzda-clk",
>> + "microchip,pic32mzda-sosc", "microchip,pic32mzda-frcdivclk",
>> + "microchip,pic32mzda-syspll", "microchip,pic32mzda-sysclk-v2",
>> + "microchip,pic32mzda-pbclk", "microchip,pic32mzda-refoclk".
>> +- reg : A Base address and length of the register set.
>> +- interrupts : source of interrupt.
>> +
>> +Optional properties (for subnodes):
>> +- #clock-cells: From common clock binding, should be 0.
>> +- microchip,clock-indices: in multiplexer node clock sources always aren't linear
>> + and contiguous. This property helps define clock-sources with respect to
>> + the mux clock node.
>> +- microchip,ignore-unused : ignore gate request even if the gated clock is unused.
>> +- microchip,status-bit-mask: bitmask for status check. This will be used to confirm
>> + particular operation by clock sub-node is completed. It is dependent sub-node.
>> +- microchip,bit-mask: enable mask, similar to microchip,status-bit-mask.
>> +- microchip,slew-step: enable frequency slewing(stepping) during rate change;
>> + applicable only to sys-clock subnode.
>> +
>> +Example:
>> +
>> +/* PIC32 specific clks */
>> +pic32_clktree {
>> + #address-cells = <1>;
>> + #size-cells = <1>;
>> + reg = <0x1f801200 0x200>;
>> + compatible = "microchip,pic32mzda-clk";
>> + ranges = <0 0x1f801200 0x200>;
>> +
>> + /* secondary oscillator; external input on SOSCI pin */
>> + SOSC:sosc_clk {
> For the ones with reg property, do clock@0 instead of sosc_clk.
ack. Will update.
>> + #clock-cells = <0>;
>> + compatible = "microchip,pic32mzda-sosc";
>> + clock-frequency = <32768>;
>> + reg = <0x000 0x10>, /* enable reg */
>> + <0x1d0 0x10>; /* status reg */
>> + microchip,bit-mask = <0x02>; /* enable mask */
>> + microchip,status-bit-mask = <0x10>; /* status-mask*/
>> + };
>> +
>> + FRCDIV:frcdiv_clk {
>> + #clock-cells = <0>;
>> + compatible = "microchip,pic32mzda-frcdivclk";
>> + clocks = <&FRC>;
>> + clock-output-names = "frcdiv_clk";
>> + };
>> +
>> + /* System PLL clock */
>> + SYSPLL:spll_clk {
>> + #clock-cells = <0>;
>> + compatible = "microchip,pic32mzda-syspll";
>> + reg = <0x020 0x10>, /* SPLL register */
>> + <0x1d0 0x10>; /* CLKSTAT register */
>> + clocks = <&POSC>, <&FRC>;
>> + clock-output-names = "sys_pll";
>> + microchip,status-bit-mask = <0x80>; /* SPLLRDY */
>> + };
>> +
>> + /* system clock; mux with postdiv & slew */
>> + SYSCLK:sys_clk {
>> + #clock-cells = <0>;
>> + compatible = "microchip,pic32mzda-sysclk-v2";
>> + reg = <0x1c0 0x04>; /* SLEWCON */
>> + clocks = <&FRCDIV>, <&SYSPLL>, <&POSC>, <&SOSC>,
>> + <&LPRC>, <&FRCDIV>;
>> + microchip,clock-indices = <0>, <1>, <2>, <4>, <5>, <7>;
>> + clock-output-names = "sys_clk";
>> + };
>> +
>> + /* UPLL is integral part of USB PHY; UTMI clk for USBCORE */
>> + UPLL:usb_phy_clk {
>> + #clock-cells = <0>;
>> + compatible = "fixed-clocks";
>> + clock-frequency = <24000000>;
>> + clock-output-names = "usbphy_clk";
>> + };
>> +
>> + /* Peripheral bus1 clock */
>> + PBCLK1:pb1_clk {
>> + reg = <0x140 0x10>;
>> + #clock-cells = <0>;
>> + compatible = "microchip,pic32mzda-pbclk";
>> + clocks = <&SYSCLK>;
>> + clock-output-names = "pb1_clk";
>> + /* used by system modules, not gateable */
>> + microchip,ignore-unused;
>> + };
>> +
>> + /* Peripheral bus2 clock */
>> + PBCLK2:pb2_clk {
>> + reg = <0x150 0x10>;
>> + #clock-cells = <0>;
>> + compatible = "microchip,pic32mzda-pbclk";
>> + clocks = <&SYSCLK>;
>> + clock-output-names = "pb2_clk";
>> + /* avoid gating even if unused */
>> + microchip,ignore-unused;
>> + };
>> +
>> + /* Peripheral bus3 clock */
>> + PBCLK3:pb3_clk {
>> + reg = <0x160 0x10>;
>> + #clock-cells = <0>;
>> + compatible = "microchip,pic32mzda-pbclk";
>> + clocks = <&SYSCLK>;
>> + clock-output-names = "pb3_clk";
>> + };
>> +
>> + /* Peripheral bus4 clock(I/O ports, GPIO) */
>> + PBCLK4:pb4_clk {
>> + reg = <0x170 0x10>;
>> + #clock-cells = <0>;
>> + compatible = "microchip,pic32mzda-pbclk";
>> + clocks = <&SYSCLK>;
>> + clock-output-names = "pb4_clk";
>> + };
>> +
>> + /* Peripheral bus clock */
>> + PBCLK5:pb5_clk {
>> + reg = <0x180 0x10>;
>> + #clock-cells = <0>;
>> + compatible = "microchip,pic32mzda-pbclk";
>> + clocks = <&SYSCLK>;
>> + clock-output-names = "pb5_clk";
>> + };
>> +
>> + /* Peripheral Bus6 clock; */
>> + PBCLK6:pb6_clk {
>> + reg = <0x190 0x10>;
>> + compatible = "microchip,pic32mzda-pbclk";
>> + clocks = <&SYSCLK>;
>> + #clock-cells = <0>;
>> + };
>> +
>> + /* Peripheral bus7 clock */
>> + PBCLK7:pb7_clk {
>> + reg = <0x1A0 0x10>;
> lower case
ack.
>> + #clock-cells = <0>;
>> + compatible = "microchip,pic32mzda-pbclk";
>> + /* CPU is driven by this clock; so named */
>> + clock-output-names = "cpu_clk";
>> + clocks = <&SYSCLK>;
>> + };
>> +
>> + /* Reference Oscillator clock for SPI/I2S */
>> + REFCLKO1:refo1_clk {
>> + reg = <0x080 0x20>;
>> + #clock-cells = <0>;
>> + compatible = "microchip,pic32mzda-refoclk";
>> + clocks = <&SYSCLK>, <&PBCLK1>, <&POSC>, <&FRC>, <&LPRC>,
>> + <&SOSC>, <&SYSPLL>, <&REFIx>, <&BFRC>;
>> + microchip,clock-indices = <0>, <1>, <2>, <3>, <4>, <5>,
>> + <7>, <8>, <9>;
>> + clock-output-names = "refo1_clk";
>> + };
>> +
>> + /* Reference Oscillator clock for SQI */
>> + REFCLKO2:refo2_clk {
>> + reg = <0x0A0 0x20>;
> lower case
ack.
>> + #clock-cells = <0>;
>> + compatible = "microchip,pic32mzda-refoclk";
>> + clocks = <&SYSCLK>, <&PBCLK1>, <&POSC>, <&FRC>, <&LPRC>,
>> + <&SOSC>, <&SYSPLL>, <&REFIx>, <&BFRC>;
>> + microchip,clock-indices = <0>, <1>, <2>, <3>, <4>, <5>,
>> + <7>, <8>, <9>;
>> + clock-output-names = "refo2_clk";
>> + };
>> +
>> + /* Reference Oscillator clock, ADC */
>> + REFCLKO3:refo3_clk {
>> + reg = <0x0C0 0x20>;
> lower case
ack.
>> + compatible = "microchip,pic32mzda-refoclk";
>> + clocks = <&SYSCLK>, <&PBCLK1>, <&POSC>, <&FRC>, <&LPRC>,
>> + <&SOSC>, <&SYSPLL>, <&REFIx>, <&BFRC>;
>> + microchip,clock-indices = <0>, <1>, <2>, <3>, <4>, <5>,
>> + <7>, <8>, <9>;
>> + #clock-cells = <0>;
>> + clock-output-names = "refo3_clk";
>> + };
>> +
>> + /* Reference Oscillator clock */
>> + REFCLKO4:refo4_clk {
>> + reg = <0x0E0 0x20>;
>> + compatible = "microchip,pic32mzda-refoclk";
>> + clocks = <&SYSCLK>, <&PBCLK1>, <&POSC>, <&FRC>, <&LPRC>,
>> + <&SOSC>, <&SYSPLL>, <&REFIx>, <&BFRC>;
>> + microchip,clock-indices = <0>,<1>,<2>,<3>,<4>,<5>,<7>,
>> + <8>,<9>;
>> + #clock-cells = <0>;
>> + clock-output-names = "refo4_clk";
>> + };
>> +
>> + /* Reference Oscillator clock, LCD */
>> + REFCLKO5:refo5_clk {
>> + reg = <0x100 0x20>;
>> + compatible = "microchip,pic32mzda-refoclk";
>> + clocks = <&SYSCLK>,<&PBCLK1>,<&POSC>,<&FRC>,<&LPRC>,
>> + <&SOSC>,<&SYSPLL>,<&REFIx>,<&BFRC>;
>> + microchip,clock-indices = <0>, <1>, <2>, <3>, <4>, <5>,
>> + <7>, <8>,<9>;
>> + #clock-cells = <0>;
>> + clock-output-names = "refo5_clk";
>> + };
>> +};
>> +
>> +The clock consumer should specify the desired clock by having the clocks in its
>> +"clock" phandle cell. For example for UART:
>> +
>> +uart2: serial@<> {
>> + compatible = "microchip,pic32mzda-uart";
>> + reg = <>;
>> + interrupts = <>;
>> + clocks = <&PBCLK2>;
>> +}
>> --
>> 1.7.9.5
>>
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Joshua Henderson <joshua.henderson@microchip.com> |
|---|---|
| Date | 2015-12-14 23:50 +0100 |
| Subject | [PATCH v2 01/14] DEVICETREE: Add bindings for PIC32 interrupt controller |
| Message-ID | <qFK6m-3W4-13@gated-at.bofh.it> |
| In reply to | #1291644 |
From: Cristian Birsan <cristian.birsan@microchip.com>
Document the devicetree bindings for the interrupt controller on
Microchip PIC32 class devices.
Signed-off-by: Cristian Birsan <cristian.birsan@microchip.com>
Signed-off-by: Joshua Henderson <joshua.henderson@microchip.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
---
.../interrupt-controller/microchip,pic32-evic.txt | 58 ++++++++++++++++++++
1 file changed, 58 insertions(+)
create mode 100644 Documentation/devicetree/bindings/interrupt-controller/microchip,pic32-evic.txt
diff --git a/Documentation/devicetree/bindings/interrupt-controller/microchip,pic32-evic.txt b/Documentation/devicetree/bindings/interrupt-controller/microchip,pic32-evic.txt
new file mode 100644
index 0000000..6f4389a
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/microchip,pic32-evic.txt
@@ -0,0 +1,58 @@
+Microchip PIC32 Interrupt Controller
+====================================
+
+The Microchip PIC32 contains an Enhanced Vectored Interrupt Controller
+(EVIC). It handles internal and external interrupts and provides support for
+irq type and polarity.
+
+Required properties
+-------------------
+
+- compatible: Should be "microchip,pic32mzda-evic"
+
+- reg: Specifies physical base address and size of register range.
+
+- interrupt-controller: Identifies the node as an interrupt controller.
+
+- #interrupt cells: Specifies the number of cells used to encode an interrupt
+source connected to this controller. The value shall be 2 and interrupt
+descriptor shall have the following format:
+ <hw_irq irq_type>
+
+hw_irq - represents the hardware interrupt number as in the data sheet.
+
+irq_type - is used to describe the type and polarity of an interrupt. For
+internal interrupts use IRQ_TYPE_EDGE_RISING for non persistent interrupts and
+IRQ_TYPE_LEVEL_HIGH for persistent interrupts. For external interrupts use
+IRQ_TYPE_EDGE_RISING or IRQ_TYPE_EDGE_FALLING to select the desired polarity.
+
+Example
+-------
+
+evic: interrupt-controller@1f810000 {
+ compatible = "microchip,pic32mzda-evic";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x1f810000 0x1000>;
+};
+
+Each device must request his interrupt line with the associated priority and
+polarity
+
+Internal interrupt DTS snippet
+------------------------------
+
+device@1f800000 {
+ ...
+ interrupts = <113 IRQ_TYPE_LEVEL_HIGH>;
+ ...
+};
+
+External interrupt DTS snippet
+------------------------------
+
+device@1f800000 {
+ ...
+ interrupts = <3 IRQ_TYPE_EDGE_RISING>;
+ ...
+};
--
1.7.9.5
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Rob Herring <robh@kernel.org> |
|---|---|
| Date | 2015-12-15 00:40 +0100 |
| Subject | Re: [PATCH v2 01/14] DEVICETREE: Add bindings for PIC32 interrupt controller |
| Message-ID | <qFKSL-4sB-51@gated-at.bofh.it> |
| In reply to | #1291653 |
On Mon, Dec 14, 2015 at 03:42:03PM -0700, Joshua Henderson wrote: > From: Cristian Birsan <cristian.birsan@microchip.com> > > Document the devicetree bindings for the interrupt controller on > Microchip PIC32 class devices. > > Signed-off-by: Cristian Birsan <cristian.birsan@microchip.com> > Signed-off-by: Joshua Henderson <joshua.henderson@microchip.com> > Cc: Ralf Baechle <ralf@linux-mips.org> Acked-by: Rob Herring <robh@kernel.org> -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Joshua Henderson <joshua.henderson@microchip.com> |
|---|---|
| Date | 2015-12-14 23:50 +0100 |
| Subject | [PATCH v2 13/14] MIPS: dts: Add initial DTS for the PIC32MZDA Starter Kit |
| Message-ID | <qFK6m-3W4-29@gated-at.bofh.it> |
| In reply to | #1291644 |
This adds basic DTS configuration for the PIC32MZDA chip and in turn the
PIC32MZDA Starter Kit.
Signed-off-by: Joshua Henderson <joshua.henderson@microchip.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
---
arch/mips/boot/dts/Makefile | 1 +
arch/mips/boot/dts/pic32/Makefile | 12 ++
arch/mips/boot/dts/pic32/pic32mzda-clk.dtsi | 235 +++++++++++++++++++++++
arch/mips/boot/dts/pic32/pic32mzda.dtsi | 275 +++++++++++++++++++++++++++
arch/mips/boot/dts/pic32/pic32mzda_sk.dts | 151 +++++++++++++++
arch/mips/pic32/Kconfig | 16 ++
6 files changed, 690 insertions(+)
create mode 100644 arch/mips/boot/dts/pic32/Makefile
create mode 100644 arch/mips/boot/dts/pic32/pic32mzda-clk.dtsi
create mode 100644 arch/mips/boot/dts/pic32/pic32mzda.dtsi
create mode 100644 arch/mips/boot/dts/pic32/pic32mzda_sk.dts
diff --git a/arch/mips/boot/dts/Makefile b/arch/mips/boot/dts/Makefile
index a0bf516..fc7a0a9 100644
--- a/arch/mips/boot/dts/Makefile
+++ b/arch/mips/boot/dts/Makefile
@@ -4,6 +4,7 @@ dts-dirs += ingenic
dts-dirs += lantiq
dts-dirs += mti
dts-dirs += netlogic
+dts-dirs += pic32
dts-dirs += qca
dts-dirs += ralink
dts-dirs += xilfpga
diff --git a/arch/mips/boot/dts/pic32/Makefile b/arch/mips/boot/dts/pic32/Makefile
new file mode 100644
index 0000000..7ac7905
--- /dev/null
+++ b/arch/mips/boot/dts/pic32/Makefile
@@ -0,0 +1,12 @@
+dtb-$(CONFIG_DTB_PIC32_MZDA_SK) += pic32mzda_sk.dtb
+
+dtb-$(CONFIG_DTB_PIC32_NONE) += \
+ pic32mzda_sk.dtb
+
+obj-y += $(patsubst %.dtb, %.dtb.o, $(dtb-y))
+
+# Force kbuild to make empty built-in.o if necessary
+obj- += dummy.o
+
+always := $(dtb-y)
+clean-files := *.dtb *.dtb.S
diff --git a/arch/mips/boot/dts/pic32/pic32mzda-clk.dtsi b/arch/mips/boot/dts/pic32/pic32mzda-clk.dtsi
new file mode 100644
index 0000000..9ab4df8
--- /dev/null
+++ b/arch/mips/boot/dts/pic32/pic32mzda-clk.dtsi
@@ -0,0 +1,235 @@
+/*
+ * Device Tree Source for PIC32MZDA clock data
+ *
+ * Purna Chandra Mandal <purna.mandal@microchip.com>
+ * Copyright (C) 2015 Microchip Technology Inc. All rights reserved.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+/* all fixed rate clocks */
+
+/ {
+ POSC:posc_clk { /* On-chip primary oscillator */
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ };
+
+ FRC:frc_clk { /* internal FRC oscillator */
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <8000000>;
+ };
+
+ BFRC:bfrc_clk { /* internal backup FRC oscillator */
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <8000000>;
+ };
+
+ LPRC:lprc_clk { /* internal low-power FRC oscillator */
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <32000>;
+ };
+
+ /* UPLL provides UTMI clock to USBCORE */
+ UPLL:usb_phy_clk {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ clock-output-names = "usbphy_clk";
+ };
+
+ TxCKI:txcki_clk { /* external clock input on TxCLKI pin */
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <4000000>;
+ status = "disabled";
+ };
+
+ /* external clock input on REFCLKIx pin */
+ REFIx:refix_clk {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ status = "disabled";
+ };
+
+ /* PIC32 specific clks */
+ pic32_clktree {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x1f801200 0x200>;
+ compatible = "microchip,pic32mzda-clk";
+ ranges = <0 0x1f801200 0x200>;
+
+ /* secondary oscillator; external input on SOSCI pin */
+ SOSC:sosc_clk {
+ #clock-cells = <0>;
+ compatible = "microchip,pic32mzda-sosc";
+ clock-frequency = <32768>;
+ reg = <0x000 0x10>, /* enable reg */
+ <0x1d0 0x10>; /* status reg */
+ microchip,bit-mask = <0x02>; /* enable mask */
+ microchip,status-bit-mask = <0x10>; /* status-mask*/
+ };
+
+ FRCDIV:frcdiv_clk {
+ #clock-cells = <0>;
+ compatible = "microchip,pic32mzda-frcdivclk";
+ clocks = <&FRC>;
+ clock-output-names = "frcdiv_clk";
+ };
+
+ /* System PLL clock */
+ SYSPLL:spll_clk {
+ #clock-cells = <0>;
+ compatible = "microchip,pic32mzda-syspll";
+ reg = <0x020 0x10>, /* SPLL register */
+ <0x1d0 0x10>; /* CLKSTAT register */
+ clocks = <&POSC>, <&FRC>;
+ clock-output-names = "sys_pll";
+ microchip,status-bit-mask = <0x80>; /* SPLLRDY */
+ };
+
+ /* system clock; mux with postdiv & slew */
+ SYSCLK:sys_clk {
+ #clock-cells = <0>;
+ compatible = "microchip,pic32mzda-sysclk-v2";
+ reg = <0x1c0 0x04>; /* SLEWCON */
+ clocks = <&FRCDIV>, <&SYSPLL>, <&POSC>, <&SOSC>,
+ <&LPRC>, <&FRCDIV>;
+ microchip,clock-indices = <0>, <1>, <2>, <4>, <5>, <7>;
+ clock-output-names = "sys_clk";
+ };
+
+ /* Peripheral bus1 clock */
+ PBCLK1:pb1_clk {
+ reg = <0x140 0x10>;
+ #clock-cells = <0>;
+ compatible = "microchip,pic32mzda-pbclk";
+ clocks = <&SYSCLK>;
+ clock-output-names = "pb1_clk";
+ /* used by system modules, not gateable */
+ microchip,ignore-unused;
+ };
+
+ /* Peripheral bus2 clock */
+ PBCLK2:pb2_clk {
+ reg = <0x150 0x10>;
+ #clock-cells = <0>;
+ compatible = "microchip,pic32mzda-pbclk";
+ clocks = <&SYSCLK>;
+ clock-output-names = "pb2_clk";
+ /* avoid gating even if unused */
+ microchip,ignore-unused;
+ };
+
+ /* Peripheral bus3 clock */
+ PBCLK3:pb3_clk {
+ reg = <0x160 0x10>;
+ #clock-cells = <0>;
+ compatible = "microchip,pic32mzda-pbclk";
+ clocks = <&SYSCLK>;
+ clock-output-names = "pb3_clk";
+ };
+
+ /* Peripheral bus4 clock(I/O ports, GPIO) */
+ PBCLK4:pb4_clk {
+ reg = <0x170 0x10>;
+ #clock-cells = <0>;
+ compatible = "microchip,pic32mzda-pbclk";
+ clocks = <&SYSCLK>;
+ clock-output-names = "pb4_clk";
+ };
+
+ /* Peripheral bus clock */
+ PBCLK5:pb5_clk {
+ reg = <0x180 0x10>;
+ #clock-cells = <0>;
+ compatible = "microchip,pic32mzda-pbclk";
+ clocks = <&SYSCLK>;
+ clock-output-names = "pb5_clk";
+ };
+
+ /* Peripheral Bus6 clock; */
+ PBCLK6:pb6_clk {
+ reg = <0x190 0x10>;
+ compatible = "microchip,pic32mzda-pbclk";
+ clocks = <&SYSCLK>;
+ #clock-cells = <0>;
+ };
+
+ /* Peripheral bus7 clock */
+ PBCLK7:pb7_clk {
+ reg = <0x1A0 0x10>;
+ #clock-cells = <0>;
+ compatible = "microchip,pic32mzda-pbclk";
+ /* CPU is driven by this clock; so named */
+ clock-output-names = "cpu_clk";
+ clocks = <&SYSCLK>;
+ };
+
+ /* Reference Oscillator clock for SPI/I2S */
+ REFCLKO1:refo1_clk {
+ reg = <0x080 0x20>;
+ #clock-cells = <0>;
+ compatible = "microchip,pic32mzda-refoclk";
+ clocks = <&SYSCLK>, <&PBCLK1>, <&POSC>, <&FRC>, <&LPRC>,
+ <&SOSC>, <&SYSPLL>, <&REFIx>, <&BFRC>;
+ microchip,clock-indices = <0>, <1>, <2>, <3>, <4>,
+ <5>, <7>, <8>, <9>;
+ clock-output-names = "refo1_clk";
+ };
+
+ /* Reference Oscillator clock for SQI */
+ REFCLKO2:refo2_clk {
+ reg = <0x0A0 0x20>;
+ #clock-cells = <0>;
+ compatible = "microchip,pic32mzda-refoclk";
+ clocks = <&SYSCLK>, <&PBCLK1>, <&POSC>, <&FRC>, <&LPRC>,
+ <&SOSC>, <&SYSPLL>, <&REFIx>, <&BFRC>;
+ microchip,clock-indices = <0>, <1>, <2>, <3>, <4>,
+ <5>, <7>, <8>, <9>;
+ clock-output-names = "refo2_clk";
+ };
+
+ /* Reference Oscillator clock, ADC */
+ REFCLKO3:refo3_clk {
+ reg = <0x0C0 0x20>;
+ compatible = "microchip,pic32mzda-refoclk";
+ clocks = <&SYSCLK>, <&PBCLK1>, <&POSC>, <&FRC>, <&LPRC>,
+ <&SOSC>, <&SYSPLL>, <&REFIx>, <&BFRC>;
+ microchip,clock-indices = <0>, <1>, <2>, <3>, <4>,
+ <5>, <7>, <8>, <9>;
+ #clock-cells = <0>;
+ clock-output-names = "refo3_clk";
+ };
+
+ /* Reference Oscillator clock */
+ REFCLKO4:refo4_clk {
+ reg = <0x0E0 0x20>;
+ compatible = "microchip,pic32mzda-refoclk";
+ clocks = <&SYSCLK>, <&PBCLK1>, <&POSC>, <&FRC>, <&LPRC>,
+ <&SOSC>, <&SYSPLL>, <&REFIx>, <&BFRC>;
+ microchip,clock-indices = <0>, <1>, <2>, <3>, <4>,
+ <5>, <7>, <8>, <9>;
+ #clock-cells = <0>;
+ clock-output-names = "refo4_clk";
+ };
+
+ /* Reference Oscillator clock, LCD */
+ REFCLKO5:refo5_clk {
+ reg = <0x100 0x20>;
+ compatible = "microchip,pic32mzda-refoclk";
+ clocks = <&SYSCLK>,<&PBCLK1>,<&POSC>,<&FRC>,<&LPRC>,
+ <&SOSC>,<&SYSPLL>,<&REFIx>,<&BFRC>;
+ microchip,clock-indices = <0>, <1>, <2>, <3>, <4>,
+ <5>, <7>, <8>, <9>;
+ #clock-cells = <0>;
+ clock-output-names = "refo5_clk";
+ };
+ };
+};
diff --git a/arch/mips/boot/dts/pic32/pic32mzda.dtsi b/arch/mips/boot/dts/pic32/pic32mzda.dtsi
new file mode 100644
index 0000000..3eee106
--- /dev/null
+++ b/arch/mips/boot/dts/pic32/pic32mzda.dtsi
@@ -0,0 +1,275 @@
+/*
+ * Copyright (C) 2015 Microchip Technology Inc. All rights reserved.
+ *
+ * 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 <dt-bindings/interrupt-controller/irq.h>
+
+#include "pic32mzda-clk.dtsi"
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&evic>;
+
+ aliases {
+ gpio0 = &gpio0;
+ gpio1 = &gpio1;
+ gpio2 = &gpio2;
+ gpio3 = &gpio3;
+ gpio4 = &gpio4;
+ gpio5 = &gpio5;
+ gpio6 = &gpio6;
+ gpio7 = &gpio7;
+ gpio8 = &gpio8;
+ gpio9 = &gpio9;
+ serial0 = &uart1;
+ serial1 = &uart2;
+ serial2 = &uart3;
+ serial3 = &uart4;
+ serial4 = &uart5;
+ serial5 = &uart6;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ compatible = "mti,mips14KEc";
+ device_type = "cpu";
+ };
+ };
+
+ evic: interrupt-controller@1f810000 {
+ compatible = "microchip,pic32mzda-evic";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x1f810000 0x1000>;
+ };
+
+ pic32_pinctrl: pinctrl@1f801400{
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "microchip,pic32mzda-pinctrl";
+ reg = <0x1f801400 0x400>;
+ clocks = <&PBCLK1>;
+ };
+
+ /* PORTA */
+ gpio0: gpio0@1f860000 {
+ compatible = "microchip,pic32mzda-gpio";
+ reg = <0x1f860000 0x100>;
+ interrupts = <118 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&PBCLK4>;
+ microchip,gpio-bank = <0>;
+ gpio-ranges = <&pic32_pinctrl 0 0 16>;
+ };
+
+ /* PORTB */
+ gpio1: gpio1@1f860100 {
+ compatible = "microchip,pic32mzda-gpio";
+ reg = <0x1f860100 0x100>;
+ interrupts = <119 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&PBCLK4>;
+ microchip,gpio-bank = <1>;
+ gpio-ranges = <&pic32_pinctrl 0 16 16>;
+ };
+
+ /* PORTC */
+ gpio2: gpio2@1f860200 {
+ compatible = "microchip,pic32mzda-gpio";
+ reg = <0x1f860200 0x100>;
+ interrupts = <120 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&PBCLK4>;
+ microchip,gpio-bank = <2>;
+ gpio-ranges = <&pic32_pinctrl 0 32 16>;
+ };
+
+ /* PORTD */
+ gpio3: gpio3@1f860300 {
+ compatible = "microchip,pic32mzda-gpio";
+ reg = <0x1f860300 0x100>;
+ interrupts = <121 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&PBCLK4>;
+ microchip,gpio-bank = <3>;
+ gpio-ranges = <&pic32_pinctrl 0 48 16>;
+ };
+
+ /* PORTE */
+ gpio4: gpio4@1f860400 {
+ compatible = "microchip,pic32mzda-gpio";
+ reg = <0x1f860400 0x100>;
+ interrupts = <122 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&PBCLK4>;
+ microchip,gpio-bank = <4>;
+ gpio-ranges = <&pic32_pinctrl 0 64 16>;
+ };
+
+ /* PORTF */
+ gpio5: gpio5@1f860500 {
+ compatible = "microchip,pic32mzda-gpio";
+ reg = <0x1f860500 0x100>;
+ interrupts = <123 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&PBCLK4>;
+ microchip,gpio-bank = <5>;
+ gpio-ranges = <&pic32_pinctrl 0 80 16>;
+ };
+
+ /* PORTG */
+ gpio6: gpio6@1f860600 {
+ compatible = "microchip,pic32mzda-gpio";
+ reg = <0x1f860600 0x100>;
+ interrupts = <124 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&PBCLK4>;
+ microchip,gpio-bank = <6>;
+ gpio-ranges = <&pic32_pinctrl 0 96 16>;
+ };
+
+ /* PORTH */
+ gpio7: gpio7@1f860700 {
+ compatible = "microchip,pic32mzda-gpio";
+ reg = <0x1f860700 0x100>;
+ interrupts = <125 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&PBCLK4>;
+ microchip,gpio-bank = <7>;
+ gpio-ranges = <&pic32_pinctrl 0 112 16>;
+ };
+
+ /* PORTI does not exist */
+
+ /* PORTJ */
+ gpio8: gpio8@1f860800 {
+ compatible = "microchip,pic32mzda-gpio";
+ reg = <0x1f860800 0x100>;
+ interrupts = <126 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&PBCLK4>;
+ microchip,gpio-bank = <8>;
+ gpio-ranges = <&pic32_pinctrl 0 128 16>;
+ };
+
+ /* PORTK */
+ gpio9: gpio9@1f860900 {
+ compatible = "microchip,pic32mzda-gpio";
+ reg = <0x1f860900 0x100>;
+ interrupts = <127 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&PBCLK4>;
+ microchip,gpio-bank = <9>;
+ gpio-ranges = <&pic32_pinctrl 0 144 16>;
+ };
+
+ sdhci: sdhci@1f8ec000 {
+ compatible = "microchip,pic32mzda-sdhci";
+ reg = <0x1f8ec000 0x100>;
+ interrupts = <191 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&REFCLKO4>, <&PBCLK5>;
+ clock-names = "base_clk", "sys_clk";
+ bus-width = <4>;
+ cap-sd-highspeed;
+ status = "disabled";
+ };
+
+ uart1: serial@1f822000 {
+ compatible = "microchip,pic32mzda-uart";
+ reg = <0x1f822000 0x50>;
+ interrupts = <112 IRQ_TYPE_LEVEL_HIGH>,
+ <113 IRQ_TYPE_LEVEL_HIGH>,
+ <114 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&PBCLK2>;
+ status = "disabled";
+ };
+
+ uart2: serial@1f822200 {
+ compatible = "microchip,pic32mzda-uart";
+ reg = <0x1f822200 0x50>;
+ interrupts = <145 IRQ_TYPE_LEVEL_HIGH>,
+ <146 IRQ_TYPE_LEVEL_HIGH>,
+ <147 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&PBCLK2>;
+ status = "disabled";
+ };
+
+ uart3: serial@1f822400 {
+ compatible = "microchip,pic32mzda-uart";
+ reg = <0x1f822400 0x50>;
+ interrupts = <157 IRQ_TYPE_LEVEL_HIGH>,
+ <158 IRQ_TYPE_LEVEL_HIGH>,
+ <159 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&PBCLK2>;
+ status = "disabled";
+ };
+
+ uart4: serial@1f822600 {
+ compatible = "microchip,pic32mzda-uart";
+ reg = <0x1f822600 0x50>;
+ interrupts = <170 IRQ_TYPE_LEVEL_HIGH>,
+ <171 IRQ_TYPE_LEVEL_HIGH>,
+ <172 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&PBCLK2>;
+ status = "disabled";
+ };
+
+ uart5: serial@1f822800 {
+ compatible = "microchip,pic32mzda-uart";
+ reg = <0x1f822800 0x50>;
+ interrupts = <179 IRQ_TYPE_LEVEL_HIGH>,
+ <180 IRQ_TYPE_LEVEL_HIGH>,
+ <181 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&PBCLK2>;
+ status = "disabled";
+ };
+
+ uart6: serial@1f822A00 {
+ compatible = "microchip,pic32mzda-uart";
+ reg = <0x1f822A00 0x50>;
+ interrupts = <188 IRQ_TYPE_LEVEL_HIGH>,
+ <189 IRQ_TYPE_LEVEL_HIGH>,
+ <190 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&PBCLK2>;
+ status = "disabled";
+ };
+};
diff --git a/arch/mips/boot/dts/pic32/pic32mzda_sk.dts b/arch/mips/boot/dts/pic32/pic32mzda_sk.dts
new file mode 100644
index 0000000..3fd2307
--- /dev/null
+++ b/arch/mips/boot/dts/pic32/pic32mzda_sk.dts
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2015 Microchip Technology Inc. All rights reserved.
+ *
+ * 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.
+ *
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+#include "pic32mzda.dtsi"
+
+/ {
+ compatible = "microchip,pic32mzda-sk", "microchip,pic32mzda";
+ model = "Microchip PIC32MZDA Starter Kit";
+
+ memory {
+ device_type = "memory";
+ reg = <0x08000000 0x08000000>;
+ };
+
+ chosen {
+ bootargs = "earlyprintk=ttyS1,115200n8r console=ttyS1,115200n8";
+ };
+
+ leds0 {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&user_leds_s0>;
+
+ led@1 {
+ label = "pic32mzda_sk:red:led1";
+ gpios = <&gpio7 0 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ };
+
+ led@2 {
+ label = "pic32mzda_sk:yellow:led2";
+ gpios = <&gpio7 1 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "mmc0";
+ };
+
+ led@3 {
+ label = "pic32mzda_sk:green:led3";
+ gpios = <&gpio7 2 GPIO_ACTIVE_HIGH>;
+ default-state = "on";
+ };
+ };
+
+ keys0 {
+ compatible = "gpio-keys";
+ pinctrl-0 = <&user_buttons_s0>;
+ pinctrl-names = "default";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ button@sw1 {
+ label = "ESC";
+ linux,code = <1>;
+ gpios = <&gpio1 12 0>;
+ };
+
+ button@sw2 {
+ label = "Home";
+ linux,code = <102>;
+ gpios = <&gpio1 13 0>;
+ };
+
+ button@sw3 {
+ label = "Menu";
+ linux,code = <139>;
+ gpios = <&gpio1 14 0>;
+ };
+ };
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ status = "okay";
+};
+
+&uart4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart4>;
+ status = "okay";
+};
+
+&sdhci {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sdhc1>;
+ status = "okay";
+ assigned-clocks = <&REFCLKO2>,<&REFCLKO4>,<&REFCLKO5>;
+ assigned-clock-rates = <50000000>,<25000000>,<40000000>;
+};
+
+&pic32_pinctrl {
+
+ pinctrl_sdhc1: sdhc1_pins0 {
+ pins = "A6", "D4", "G13", "G12", "G14", "A7", "A0";
+ microchip,digital;
+ };
+
+ user_leds_s0: user_leds_s0 {
+ pins = "H0", "H1", "H2";
+ output-low;
+ microchip,digital;
+ };
+
+ user_buttons_s0: user_buttons_s0 {
+ pins = "B12", "B13", "B14";
+ microchip,digital;
+ input-enable;
+ bias-pull-up;
+ };
+
+ pinctrl_uart2: pinctrl_uart2 {
+ uart2-tx {
+ pins = "G9";
+ function = "U2TX";
+ microchip,digital;
+ output-low;
+ };
+ uart2-rx {
+ pins = "B0";
+ function = "U2RX";
+ microchip,digital;
+ input-enable;
+ };
+ };
+
+ pinctrl_uart4: uart4-0 {
+ uart4-tx {
+ pins = "C3";
+ function = "U4TX";
+ microchip,digital;
+ output-low;
+ };
+ uart4-rx {
+ pins = "E8";
+ function = "U4RX";
+ microchip,digital;
+ input-enable;
+ };
+ };
+};
diff --git a/arch/mips/pic32/Kconfig b/arch/mips/pic32/Kconfig
index 0161f09..b1bd7ba 100644
--- a/arch/mips/pic32/Kconfig
+++ b/arch/mips/pic32/Kconfig
@@ -31,4 +31,20 @@ config PIC32MZDA
endchoice
+choice
+ prompt "Devicetree selection"
+ default DTB_PIC32_NONE
+ help
+ Select the devicetree.
+
+config DTB_PIC32_NONE
+ bool "None"
+
+config DTB_PIC32_MZDA_SK
+ bool "PIC32MZDA Starter Kit"
+ depends on PIC32MZDA
+ select BUILTIN_DTB
+
+endchoice
+
endif # MACH_PIC32
--
1.7.9.5
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Joshua Henderson <joshua.henderson@microchip.com> |
|---|---|
| Date | 2015-12-14 23:50 +0100 |
| Subject | [PATCH v2 09/14] DEVICETREE: Add bindings for PIC32 UART driver |
| Message-ID | <qFK6m-3W4-31@gated-at.bofh.it> |
| In reply to | #1291644 |
From: Andrei Pistirica <andrei.pistirica@microchip.com>
Document the devicetree bindings for the UART peripheral found on
Microchip PIC32 class devices.
Signed-off-by: Andrei Pistirica <andrei.pistirica@microchip.com>
Signed-off-by: Joshua Henderson <joshua.henderson@microchip.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
---
.../bindings/serial/microchip,pic32-uart.txt | 29 ++++++++++++++++++++
1 file changed, 29 insertions(+)
create mode 100644 Documentation/devicetree/bindings/serial/microchip,pic32-uart.txt
diff --git a/Documentation/devicetree/bindings/serial/microchip,pic32-uart.txt b/Documentation/devicetree/bindings/serial/microchip,pic32-uart.txt
new file mode 100644
index 0000000..65b38bf6
--- /dev/null
+++ b/Documentation/devicetree/bindings/serial/microchip,pic32-uart.txt
@@ -0,0 +1,29 @@
+* Microchip Universal Asynchronous Receiver Transmitter (UART)
+
+Required properties:
+- compatible: Should be "microchip,pic32mzda-uart"
+- reg: Should contain registers location and length
+- interrupts: Should contain interrupt
+- clocks: Phandle to the clock.
+ See: Documentation/devicetree/bindings/clock/clock-bindings.txt
+- pinctrl-names: A pinctrl state names "default" must be defined.
+- pinctrl-0: Phandle referencing pin configuration of the UART peripheral.
+ See: Documentation/devicetree/bindings/pinctrl/pinctrl-binding.txt
+
+Optional properties:
+- cts-gpios: CTS pin for UART
+
+Example:
+ uart1: serial@1f822000 {
+ compatible = "microchip,pic32mzda-uart";
+ reg = <0x1f822000 0x50>;
+ interrupts = <112 IRQ_TYPE_LEVEL_HIGH>,
+ <113 IRQ_TYPE_LEVEL_HIGH>,
+ <114 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&PBCLK2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1
+ &pinctrl_uart1_cts
+ &pinctrl_uart1_rts>;
+ cts-gpios = <&gpio1 15 0>;
+ };
--
1.7.9.5
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Rob Herring <robh@kernel.org> |
|---|---|
| Date | 2015-12-15 21:10 +0100 |
| Subject | Re: [PATCH v2 09/14] DEVICETREE: Add bindings for PIC32 UART driver |
| Message-ID | <qG453-tz-9@gated-at.bofh.it> |
| In reply to | #1291658 |
On Mon, Dec 14, 2015 at 03:42:11PM -0700, Joshua Henderson wrote:
> From: Andrei Pistirica <andrei.pistirica@microchip.com>
>
> Document the devicetree bindings for the UART peripheral found on
> Microchip PIC32 class devices.
>
> Signed-off-by: Andrei Pistirica <andrei.pistirica@microchip.com>
> Signed-off-by: Joshua Henderson <joshua.henderson@microchip.com>
> Cc: Ralf Baechle <ralf@linux-mips.org>
Acked-by: Rob Herring <robh@kernel.org>
> ---
> .../bindings/serial/microchip,pic32-uart.txt | 29 ++++++++++++++++++++
> 1 file changed, 29 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/serial/microchip,pic32-uart.txt
>
> diff --git a/Documentation/devicetree/bindings/serial/microchip,pic32-uart.txt b/Documentation/devicetree/bindings/serial/microchip,pic32-uart.txt
> new file mode 100644
> index 0000000..65b38bf6
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/serial/microchip,pic32-uart.txt
> @@ -0,0 +1,29 @@
> +* Microchip Universal Asynchronous Receiver Transmitter (UART)
> +
> +Required properties:
> +- compatible: Should be "microchip,pic32mzda-uart"
> +- reg: Should contain registers location and length
> +- interrupts: Should contain interrupt
> +- clocks: Phandle to the clock.
> + See: Documentation/devicetree/bindings/clock/clock-bindings.txt
> +- pinctrl-names: A pinctrl state names "default" must be defined.
> +- pinctrl-0: Phandle referencing pin configuration of the UART peripheral.
> + See: Documentation/devicetree/bindings/pinctrl/pinctrl-binding.txt
> +
> +Optional properties:
> +- cts-gpios: CTS pin for UART
> +
> +Example:
> + uart1: serial@1f822000 {
> + compatible = "microchip,pic32mzda-uart";
> + reg = <0x1f822000 0x50>;
> + interrupts = <112 IRQ_TYPE_LEVEL_HIGH>,
> + <113 IRQ_TYPE_LEVEL_HIGH>,
> + <114 IRQ_TYPE_LEVEL_HIGH>;
> + clocks = <&PBCLK2>;
> + pinctrl-names = "default";
> + pinctrl-0 = <&pinctrl_uart1
> + &pinctrl_uart1_cts
> + &pinctrl_uart1_rts>;
> + cts-gpios = <&gpio1 15 0>;
> + };
> --
> 1.7.9.5
>
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Joshua Henderson <joshua.henderson@microchip.com> |
|---|---|
| Date | 2015-12-14 23:50 +0100 |
| Subject | [PATCH v2 11/14] DEVICETREE: Add bindings for PIC32 SDHCI host controller |
| Message-ID | <qFK6n-3W4-37@gated-at.bofh.it> |
| In reply to | #1291644 |
From: Andrei Pistirica <andrei.pistirica@microchip.com>
Document the devicetree bindings for the SDHCI peripheral found on
Microchip PIC32 class devices.
Signed-off-by: Andrei Pistirica <andrei.pistirica@microchip.com>
Signed-off-by: Joshua Henderson <joshua.henderson@microchip.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
---
.../bindings/mmc/microchip,sdhci-pic32.txt | 29 ++++++++++++++++++++
1 file changed, 29 insertions(+)
create mode 100644 Documentation/devicetree/bindings/mmc/microchip,sdhci-pic32.txt
diff --git a/Documentation/devicetree/bindings/mmc/microchip,sdhci-pic32.txt b/Documentation/devicetree/bindings/mmc/microchip,sdhci-pic32.txt
new file mode 100644
index 0000000..71ad57e
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/microchip,sdhci-pic32.txt
@@ -0,0 +1,29 @@
+* Microchip PIC32 SDHCI Controller
+
+This file documents differences between the core properties in mmc.txt
+and the properties used by the sdhci-pic32 driver.
+
+Required properties:
+- compatible: Should be "microchip,pic32mzda-sdhci"
+- interrupts: Should contain interrupt
+- clock-names: Should be "base_clk", "sys_clk".
+ See: Documentation/devicetree/bindings/resource-names.txt
+- clocks: Phandle to the clock.
+ See: Documentation/devicetree/bindings/clock/clock-bindings.txt
+- pinctrl-names: A pinctrl state names "default" must be defined.
+- pinctrl-0: Phandle referencing pin configuration of the SDHCI controller.
+ See: Documentation/devicetree/bindings/pinctrl/pinctrl-binding.txt
+
+Example:
+
+ sdhci@1f8ec000 {
+ compatible = "microchip,pic32mzda-sdhci";
+ reg = <0x1f8ec000 0x100>;
+ interrupts = <191 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&REFCLKO4>, <&PBCLK5>;
+ clock-names = "base_clk", "sys_clk";
+ bus-width = <4>;
+ cap-sd-highspeed;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sdhc1>;
+ };
--
1.7.9.5
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Rob Herring <robh@kernel.org> |
|---|---|
| Date | 2015-12-15 21:10 +0100 |
| Subject | Re: [PATCH v2 11/14] DEVICETREE: Add bindings for PIC32 SDHCI host controller |
| Message-ID | <qG453-tz-17@gated-at.bofh.it> |
| In reply to | #1291659 |
On Mon, Dec 14, 2015 at 03:42:13PM -0700, Joshua Henderson wrote:
> From: Andrei Pistirica <andrei.pistirica@microchip.com>
>
> Document the devicetree bindings for the SDHCI peripheral found on
> Microchip PIC32 class devices.
>
> Signed-off-by: Andrei Pistirica <andrei.pistirica@microchip.com>
> Signed-off-by: Joshua Henderson <joshua.henderson@microchip.com>
> Cc: Ralf Baechle <ralf@linux-mips.org>
Acked-by: Rob Herring <robh@kernel.org>
> ---
> .../bindings/mmc/microchip,sdhci-pic32.txt | 29 ++++++++++++++++++++
> 1 file changed, 29 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/mmc/microchip,sdhci-pic32.txt
>
> diff --git a/Documentation/devicetree/bindings/mmc/microchip,sdhci-pic32.txt b/Documentation/devicetree/bindings/mmc/microchip,sdhci-pic32.txt
> new file mode 100644
> index 0000000..71ad57e
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mmc/microchip,sdhci-pic32.txt
> @@ -0,0 +1,29 @@
> +* Microchip PIC32 SDHCI Controller
> +
> +This file documents differences between the core properties in mmc.txt
> +and the properties used by the sdhci-pic32 driver.
> +
> +Required properties:
> +- compatible: Should be "microchip,pic32mzda-sdhci"
> +- interrupts: Should contain interrupt
> +- clock-names: Should be "base_clk", "sys_clk".
> + See: Documentation/devicetree/bindings/resource-names.txt
> +- clocks: Phandle to the clock.
> + See: Documentation/devicetree/bindings/clock/clock-bindings.txt
> +- pinctrl-names: A pinctrl state names "default" must be defined.
> +- pinctrl-0: Phandle referencing pin configuration of the SDHCI controller.
> + See: Documentation/devicetree/bindings/pinctrl/pinctrl-binding.txt
> +
> +Example:
> +
> + sdhci@1f8ec000 {
> + compatible = "microchip,pic32mzda-sdhci";
> + reg = <0x1f8ec000 0x100>;
> + interrupts = <191 IRQ_TYPE_LEVEL_HIGH>;
> + clocks = <&REFCLKO4>, <&PBCLK5>;
> + clock-names = "base_clk", "sys_clk";
> + bus-width = <4>;
> + cap-sd-highspeed;
> + pinctrl-names = "default";
> + pinctrl-0 = <&pinctrl_sdhc1>;
> + };
> --
> 1.7.9.5
>
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Joshua Henderson <joshua.henderson@microchip.com> |
|---|---|
| Date | 2015-12-14 23:50 +0100 |
| Subject | [PATCH v2 12/14] mmc: sdhci-pic32: Add PIC32 SDHCI host controller driver |
| Message-ID | <qFK6n-3W4-41@gated-at.bofh.it> |
| In reply to | #1291644 |
From: Andrei Pistirica <andrei.pistirica@microchip.com>
This driver supports the SDHCI host controller found on a PIC32.
Signed-off-by: Andrei Pistirica <andrei.pistirica@microchip.com>
Signed-off-by: Joshua Henderson <joshua.henderson@microchip.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
---
drivers/mmc/host/Kconfig | 11 ++
drivers/mmc/host/Makefile | 1 +
drivers/mmc/host/sdhci-pic32.c | 291 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 303 insertions(+)
create mode 100644 drivers/mmc/host/sdhci-pic32.c
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 1dee533..1a3a42b 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -785,3 +785,14 @@ config MMC_MTK
If you have a machine with a integrated SD/MMC card reader, say Y or M here.
This is needed if support for any SD/SDIO/MMC devices is required.
If unsure, say N.
+
+config MMC_SDHCI_MICROCHIP_PIC32
+ tristate "Microchip PIC32MZDA SDHCI support"
+ depends on MMC_SDHCI && PIC32MZDA
+ help
+ This selects the Secure Digital Host Controller Interface (SDHCI)
+ for PIC32MZDA platform.
+
+ If you have a controller with this interface, say Y or M here.
+
+ If unsure, say N.
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index 3595f83..af918d2 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -75,6 +75,7 @@ obj-$(CONFIG_MMC_SDHCI_BCM2835) += sdhci-bcm2835.o
obj-$(CONFIG_MMC_SDHCI_IPROC) += sdhci-iproc.o
obj-$(CONFIG_MMC_SDHCI_MSM) += sdhci-msm.o
obj-$(CONFIG_MMC_SDHCI_ST) += sdhci-st.o
+obj-$(CONFIG_MMC_SDHCI_MICROCHIP_PIC32) += sdhci-pic32.o
ifeq ($(CONFIG_CB710_DEBUG),y)
CFLAGS-cb710-mmc += -DDEBUG
diff --git a/drivers/mmc/host/sdhci-pic32.c b/drivers/mmc/host/sdhci-pic32.c
new file mode 100644
index 0000000..b7d7da2
--- /dev/null
+++ b/drivers/mmc/host/sdhci-pic32.c
@@ -0,0 +1,291 @@
+/*
+ * Support of SDHCI platform devices for Microchip PIC32.
+ *
+ * Copyright (C) 2015 Microchip
+ * Andrei Pistirica, Paul Thacker
+ *
+ * Inspired by sdhci-pltfm.c
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/highmem.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/slab.h>
+#include <linux/mmc/host.h>
+#include <linux/io.h>
+#include "sdhci.h"
+#include <linux/platform_data/sdhci-pic32.h>
+
+#define SDH_SHARED_BUS_CTRL 0x000000E0
+#define SDH_SHARED_BUS_NR_CLK_PINS_MASK 0x7
+#define SDH_SHARED_BUS_NR_IRQ_PINS_MASK 0x30
+#define SDH_SHARED_BUS_CLK_PINS 0x10
+#define SDH_SHARED_BUS_IRQ_PINS 0x14
+#define SDH_CAPS_SDH_SLOT_TYPE_MASK 0xC0000000
+#define SDH_SLOT_TYPE_REMOVABLE 0x0
+#define SDH_SLOT_TYPE_EMBEDDED 0x1
+#define SDH_SLOT_TYPE_SHARED_BUS 0x2
+#define SDHCI_CTRL_CDSSEL 0x80
+#define SDHCI_CTRL_CDTLVL 0x40
+
+#define ADMA_FIFO_RD_THSHLD 512
+#define ADMA_FIFO_WR_THSHLD 512
+
+#define DEV_NAME "pic32-sdhci"
+
+struct pic32_sdhci_pdata {
+ struct platform_device *pdev;
+ struct clk *sys_clk;
+ struct clk *base_clk;
+};
+
+static unsigned int pic32_sdhci_get_max_clock(struct sdhci_host *host)
+{
+ struct pic32_sdhci_pdata *sdhci_pdata = sdhci_priv(host);
+
+ return clk_get_rate(sdhci_pdata->base_clk);
+}
+
+static void pic32_sdhci_set_bus_width(struct sdhci_host *host, int width)
+{
+ u8 ctrl;
+
+ ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
+ if (width == MMC_BUS_WIDTH_8) {
+ ctrl &= ~SDHCI_CTRL_4BITBUS;
+ if (host->version >= SDHCI_SPEC_300)
+ ctrl |= SDHCI_CTRL_8BITBUS;
+ } else {
+ if (host->version >= SDHCI_SPEC_300)
+ ctrl &= ~SDHCI_CTRL_8BITBUS;
+ if (width == MMC_BUS_WIDTH_4)
+ ctrl |= SDHCI_CTRL_4BITBUS;
+ else
+ ctrl &= ~SDHCI_CTRL_4BITBUS;
+ }
+ /*
+ * SDHCI will not work if JTAG is not Connected.As a workaround fix,
+ * set Card Detect Signal Selection bit in SDHCI Host Control
+ * register and clear Card Detect Test Level bit in SDHCI Host
+ * Control register.
+ */
+ ctrl &= ~SDHCI_CTRL_CDTLVL;
+ ctrl |= SDHCI_CTRL_CDSSEL;
+ sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
+}
+
+static unsigned int pic32_sdhci_get_ro(struct sdhci_host *host)
+{
+ /*
+ * The SDHCI_WRITE_PROTECT bit is unstable on current hardware so we
+ * can't depend on its value in any way.
+ */
+ return 0;
+}
+
+static const struct sdhci_ops pic32_sdhci_ops = {
+ .get_max_clock = pic32_sdhci_get_max_clock,
+ .set_clock = sdhci_set_clock,
+ .set_bus_width = pic32_sdhci_set_bus_width,
+ .reset = sdhci_reset,
+ .set_uhs_signaling = sdhci_set_uhs_signaling,
+ .get_ro = pic32_sdhci_get_ro,
+};
+
+static void pic32_sdhci_shared_bus(struct platform_device *pdev)
+{
+ struct sdhci_host *host = platform_get_drvdata(pdev);
+ u32 bus = readl(host->ioaddr + SDH_SHARED_BUS_CTRL);
+ u32 clk_pins = (bus & SDH_SHARED_BUS_NR_CLK_PINS_MASK) >> 0;
+ u32 irq_pins = (bus & SDH_SHARED_BUS_NR_IRQ_PINS_MASK) >> 4;
+
+ /* select first clock */
+ if (clk_pins & 0x1)
+ bus |= (0x1 << SDH_SHARED_BUS_CLK_PINS);
+
+ /* select first interrupt */
+ if (irq_pins & 0x1)
+ bus |= (0x1 << SDH_SHARED_BUS_IRQ_PINS);
+
+ writel(bus, host->ioaddr + SDH_SHARED_BUS_CTRL);
+}
+
+static int pic32_sdhci_probe_platform(struct platform_device *pdev,
+ struct pic32_sdhci_pdata *pdata)
+{
+ int ret = 0;
+ u32 caps_slot_type;
+ struct sdhci_host *host = platform_get_drvdata(pdev);
+
+ /* Check card slot connected on shared bus. */
+ host->caps = readl(host->ioaddr + SDHCI_CAPABILITIES);
+ caps_slot_type = (host->caps & SDH_CAPS_SDH_SLOT_TYPE_MASK) >> 30;
+ if (caps_slot_type == SDH_SLOT_TYPE_SHARED_BUS)
+ pic32_sdhci_shared_bus(pdev);
+
+ return ret;
+}
+
+static int pic32_sdhci_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct sdhci_host *host;
+ struct resource *iomem;
+ struct pic32_sdhci_pdata *sdhci_pdata;
+ struct pic32_sdhci_platform_data *plat_data;
+ unsigned int clk_rate = 0;
+ int ret;
+ struct pinctrl *pinctrl;
+
+ host = sdhci_alloc_host(dev, sizeof(*sdhci_pdata));
+ if (IS_ERR(host)) {
+ ret = PTR_ERR(host);
+ dev_err(&pdev->dev, "cannot allocate memory for sdhci\n");
+ goto err;
+ }
+
+ sdhci_pdata = sdhci_priv(host);
+ sdhci_pdata->pdev = pdev;
+ platform_set_drvdata(pdev, host);
+
+ iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ host->ioaddr = devm_ioremap_resource(&pdev->dev, iomem);
+ if (IS_ERR(host->ioaddr)) {
+ ret = PTR_ERR(host->ioaddr);
+ dev_err(&pdev->dev, "unable to map iomem: %d\n", ret);
+ goto err_host;
+ }
+
+ plat_data = pdev->dev.platform_data;
+ if (plat_data && plat_data->setup_dma) {
+ ret = plat_data->setup_dma(ADMA_FIFO_RD_THSHLD,
+ ADMA_FIFO_WR_THSHLD);
+ if (ret)
+ goto err_host;
+ }
+
+ pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
+ if (IS_ERR(pinctrl)) {
+ ret = PTR_ERR(pinctrl);
+ dev_warn(&pdev->dev, "No pinctrl provided %d\n", ret);
+ if (ret == -EPROBE_DEFER)
+ goto err_host;
+ }
+
+ host->ops = &pic32_sdhci_ops;
+ host->irq = platform_get_irq(pdev, 0);
+
+ sdhci_pdata->sys_clk = devm_clk_get(&pdev->dev, "sys_clk");
+ if (IS_ERR(sdhci_pdata->sys_clk)) {
+ ret = PTR_ERR(sdhci_pdata->sys_clk);
+ dev_err(&pdev->dev, "Error getting clock\n");
+ goto err_host;
+ }
+
+ /* Enable clock when available! */
+ ret = clk_prepare_enable(sdhci_pdata->sys_clk);
+ if (ret) {
+ dev_dbg(&pdev->dev, "Error enabling clock\n");
+ goto err_host;
+ }
+
+ /* SDH CLK enable */
+ sdhci_pdata->base_clk = devm_clk_get(&pdev->dev, "base_clk");
+ if (IS_ERR(sdhci_pdata->base_clk)) {
+ ret = PTR_ERR(sdhci_pdata->base_clk);
+ dev_err(&pdev->dev, "Error getting clock\n");
+ goto err_host;
+ }
+
+ /* Enable clock when available! */
+ ret = clk_prepare_enable(sdhci_pdata->base_clk);
+ if (ret) {
+ dev_dbg(&pdev->dev, "Error enabling clock\n");
+ goto err_host;
+ }
+
+ clk_rate = clk_get_rate(sdhci_pdata->base_clk);
+ dev_dbg(&pdev->dev, "base clock at: %u\n", clk_rate);
+ clk_rate = clk_get_rate(sdhci_pdata->sys_clk);
+ dev_dbg(&pdev->dev, "sys clock at: %u\n", clk_rate);
+
+ host->quirks2 |= SDHCI_QUIRK2_NO_1_8_V;
+
+ host->quirks |= SDHCI_QUIRK_NO_HISPD_BIT;
+
+ ret = mmc_of_parse(host->mmc);
+ if (ret)
+ goto err_host;
+
+ ret = pic32_sdhci_probe_platform(pdev, sdhci_pdata);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to probe platform!\n");
+ goto err_host;
+ }
+
+ ret = sdhci_add_host(host);
+ if (ret) {
+ dev_dbg(&pdev->dev, "error adding host\n");
+ goto err_host;
+ }
+
+ dev_info(&pdev->dev, "Successfully added sdhci host\n");
+ return 0;
+
+err_host:
+ sdhci_free_host(host);
+err:
+ dev_err(&pdev->dev, "pic32-sdhci probe failed: %d\n", ret);
+ return ret;
+}
+
+static int pic32_sdhci_remove(struct platform_device *pdev)
+{
+ struct sdhci_host *host = platform_get_drvdata(pdev);
+ struct pic32_sdhci_pdata *sdhci_pdata = sdhci_priv(host);
+ int dead = 0;
+ u32 scratch;
+
+ scratch = readl(host->ioaddr + SDHCI_INT_STATUS);
+ if (scratch == (u32)-1)
+ dead = 1;
+
+ sdhci_remove_host(host, dead);
+ clk_disable_unprepare(sdhci_pdata->base_clk);
+ clk_disable_unprepare(sdhci_pdata->sys_clk);
+ sdhci_free_host(host);
+
+ return 0;
+}
+
+static const struct of_device_id pic32_sdhci_id_table[] = {
+ { .compatible = "microchip,pic32mzda-sdhci" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, pic32_sdhci_id_table);
+
+static struct platform_driver pic32_sdhci_driver = {
+ .driver = {
+ .name = DEV_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(pic32_sdhci_id_table),
+ },
+ .probe = pic32_sdhci_probe,
+ .remove = pic32_sdhci_remove,
+};
+
+module_platform_driver(pic32_sdhci_driver);
+
+MODULE_DESCRIPTION("Microchip PIC32 SDHCI driver");
+MODULE_AUTHOR("Pistirica Sorin Andrei & Sandeep Sheriker");
+MODULE_LICENSE("GPL v2");
--
1.7.9.5
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Andy Green <andy.green@linaro.org> |
|---|---|
| Date | 2015-12-15 01:40 +0100 |
| Subject | Re: [PATCH v2 12/14] mmc: sdhci-pic32: Add PIC32 SDHCI host controller driver |
| Message-ID | <qFLON-56v-19@gated-at.bofh.it> |
| In reply to | #1291661 |
Hi... looks good, just some small general comments.
On 15 December 2015 at 06:42, Joshua Henderson
<joshua.henderson@microchip.com> wrote:
> From: Andrei Pistirica <andrei.pistirica@microchip.com>
>
> This driver supports the SDHCI host controller found on a PIC32.
>
> Signed-off-by: Andrei Pistirica <andrei.pistirica@microchip.com>
> Signed-off-by: Joshua Henderson <joshua.henderson@microchip.com>
> Cc: Ralf Baechle <ralf@linux-mips.org>
> ---
> drivers/mmc/host/Kconfig | 11 ++
> drivers/mmc/host/Makefile | 1 +
> drivers/mmc/host/sdhci-pic32.c | 291 ++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 303 insertions(+)
> create mode 100644 drivers/mmc/host/sdhci-pic32.c
>
> diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
> index 1dee533..1a3a42b 100644
> --- a/drivers/mmc/host/Kconfig
> +++ b/drivers/mmc/host/Kconfig
> @@ -785,3 +785,14 @@ config MMC_MTK
> If you have a machine with a integrated SD/MMC card reader, say Y or M here.
> This is needed if support for any SD/SDIO/MMC devices is required.
> If unsure, say N.
> +
> +config MMC_SDHCI_MICROCHIP_PIC32
> + tristate "Microchip PIC32MZDA SDHCI support"
> + depends on MMC_SDHCI && PIC32MZDA
> + help
> + This selects the Secure Digital Host Controller Interface (SDHCI)
> + for PIC32MZDA platform.
> +
> + If you have a controller with this interface, say Y or M here.
> +
> + If unsure, say N.
> diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
> index 3595f83..af918d2 100644
> --- a/drivers/mmc/host/Makefile
> +++ b/drivers/mmc/host/Makefile
> @@ -75,6 +75,7 @@ obj-$(CONFIG_MMC_SDHCI_BCM2835) += sdhci-bcm2835.o
> obj-$(CONFIG_MMC_SDHCI_IPROC) += sdhci-iproc.o
> obj-$(CONFIG_MMC_SDHCI_MSM) += sdhci-msm.o
> obj-$(CONFIG_MMC_SDHCI_ST) += sdhci-st.o
> +obj-$(CONFIG_MMC_SDHCI_MICROCHIP_PIC32) += sdhci-pic32.o
>
> ifeq ($(CONFIG_CB710_DEBUG),y)
> CFLAGS-cb710-mmc += -DDEBUG
> diff --git a/drivers/mmc/host/sdhci-pic32.c b/drivers/mmc/host/sdhci-pic32.c
> new file mode 100644
> index 0000000..b7d7da2
> --- /dev/null
> +++ b/drivers/mmc/host/sdhci-pic32.c
> @@ -0,0 +1,291 @@
> +/*
> + * Support of SDHCI platform devices for Microchip PIC32.
> + *
> + * Copyright (C) 2015 Microchip
> + * Andrei Pistirica, Paul Thacker
> + *
> + * Inspired by sdhci-pltfm.c
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2. This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/highmem.h>
> +#include <linux/module.h>
> +#include <linux/interrupt.h>
> +#include <linux/irq.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm.h>
> +#include <linux/slab.h>
> +#include <linux/mmc/host.h>
> +#include <linux/io.h>
> +#include "sdhci.h"
> +#include <linux/platform_data/sdhci-pic32.h>
> +
> +#define SDH_SHARED_BUS_CTRL 0x000000E0
> +#define SDH_SHARED_BUS_NR_CLK_PINS_MASK 0x7
> +#define SDH_SHARED_BUS_NR_IRQ_PINS_MASK 0x30
> +#define SDH_SHARED_BUS_CLK_PINS 0x10
> +#define SDH_SHARED_BUS_IRQ_PINS 0x14
> +#define SDH_CAPS_SDH_SLOT_TYPE_MASK 0xC0000000
> +#define SDH_SLOT_TYPE_REMOVABLE 0x0
> +#define SDH_SLOT_TYPE_EMBEDDED 0x1
> +#define SDH_SLOT_TYPE_SHARED_BUS 0x2
> +#define SDHCI_CTRL_CDSSEL 0x80
> +#define SDHCI_CTRL_CDTLVL 0x40
> +
> +#define ADMA_FIFO_RD_THSHLD 512
> +#define ADMA_FIFO_WR_THSHLD 512
> +
> +#define DEV_NAME "pic32-sdhci"
Is there any point defining this when it only has one use in the driver?
> +struct pic32_sdhci_pdata {
> + struct platform_device *pdev;
> + struct clk *sys_clk;
> + struct clk *base_clk;
> +};
> +
> +static unsigned int pic32_sdhci_get_max_clock(struct sdhci_host *host)
> +{
> + struct pic32_sdhci_pdata *sdhci_pdata = sdhci_priv(host);
> +
> + return clk_get_rate(sdhci_pdata->base_clk);
> +}
> +
> +static void pic32_sdhci_set_bus_width(struct sdhci_host *host, int width)
> +{
> + u8 ctrl;
> +
> + ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
> + if (width == MMC_BUS_WIDTH_8) {
> + ctrl &= ~SDHCI_CTRL_4BITBUS;
> + if (host->version >= SDHCI_SPEC_300)
> + ctrl |= SDHCI_CTRL_8BITBUS;
> + } else {
> + if (host->version >= SDHCI_SPEC_300)
> + ctrl &= ~SDHCI_CTRL_8BITBUS;
> + if (width == MMC_BUS_WIDTH_4)
> + ctrl |= SDHCI_CTRL_4BITBUS;
> + else
> + ctrl &= ~SDHCI_CTRL_4BITBUS;
> + }
> + /*
> + * SDHCI will not work if JTAG is not Connected.As a workaround fix,
> + * set Card Detect Signal Selection bit in SDHCI Host Control
> + * register and clear Card Detect Test Level bit in SDHCI Host
> + * Control register.
> + */
Isn't this a clearer explanation, if I understood?
"Without setting CD select and test bits now, SDHCI only works with
JTAG connected."
> + ctrl &= ~SDHCI_CTRL_CDTLVL;
> + ctrl |= SDHCI_CTRL_CDSSEL;
> + sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
Also... is that a feature of the SDHCI IP or this particular chip's
implementation of it? I guess if there is only one implementation
right now that has that restriction worry about making it selectable
later. But if the implementation, it might make sense to also put the
affected implementation name in the comment to make it clear.
> +}
> +
> +static unsigned int pic32_sdhci_get_ro(struct sdhci_host *host)
> +{
> + /*
> + * The SDHCI_WRITE_PROTECT bit is unstable on current hardware so we
> + * can't depend on its value in any way.
> + */
> + return 0;
> +}
> +
> +static const struct sdhci_ops pic32_sdhci_ops = {
> + .get_max_clock = pic32_sdhci_get_max_clock,
> + .set_clock = sdhci_set_clock,
> + .set_bus_width = pic32_sdhci_set_bus_width,
> + .reset = sdhci_reset,
> + .set_uhs_signaling = sdhci_set_uhs_signaling,
> + .get_ro = pic32_sdhci_get_ro,
> +};
> +
> +static void pic32_sdhci_shared_bus(struct platform_device *pdev)
> +{
> + struct sdhci_host *host = platform_get_drvdata(pdev);
> + u32 bus = readl(host->ioaddr + SDH_SHARED_BUS_CTRL);
> + u32 clk_pins = (bus & SDH_SHARED_BUS_NR_CLK_PINS_MASK) >> 0;
> + u32 irq_pins = (bus & SDH_SHARED_BUS_NR_IRQ_PINS_MASK) >> 4;
> +
> + /* select first clock */
> + if (clk_pins & 0x1)
BIT(0)? Also a couple of lines down.
> + bus |= (0x1 << SDH_SHARED_BUS_CLK_PINS);
I know it's popular but there is no meaning or use in "0x1" where you
could just say "1".
> + /* select first interrupt */
> + if (irq_pins & 0x1)
> + bus |= (0x1 << SDH_SHARED_BUS_IRQ_PINS);
As above.
> + writel(bus, host->ioaddr + SDH_SHARED_BUS_CTRL);
> +}
> +
> +static int pic32_sdhci_probe_platform(struct platform_device *pdev,
> + struct pic32_sdhci_pdata *pdata)
> +{
> + int ret = 0;
> + u32 caps_slot_type;
> + struct sdhci_host *host = platform_get_drvdata(pdev);
> +
> + /* Check card slot connected on shared bus. */
> + host->caps = readl(host->ioaddr + SDHCI_CAPABILITIES);
> + caps_slot_type = (host->caps & SDH_CAPS_SDH_SLOT_TYPE_MASK) >> 30;
> + if (caps_slot_type == SDH_SLOT_TYPE_SHARED_BUS)
> + pic32_sdhci_shared_bus(pdev);
> +
> + return ret;
> +}
> +
> +static int pic32_sdhci_probe(struct platform_device *pdev)
> +{
> + struct device *dev = &pdev->dev;
> + struct sdhci_host *host;
> + struct resource *iomem;
> + struct pic32_sdhci_pdata *sdhci_pdata;
> + struct pic32_sdhci_platform_data *plat_data;
> + unsigned int clk_rate = 0;
> + int ret;
> + struct pinctrl *pinctrl;
It's hardly critical but for extra gold star arranging local vars in
length order (longest first) is nice.
> +
> + host = sdhci_alloc_host(dev, sizeof(*sdhci_pdata));
> + if (IS_ERR(host)) {
> + ret = PTR_ERR(host);
> + dev_err(&pdev->dev, "cannot allocate memory for sdhci\n");
> + goto err;
> + }
> +
> + sdhci_pdata = sdhci_priv(host);
> + sdhci_pdata->pdev = pdev;
> + platform_set_drvdata(pdev, host);
> +
> + iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + host->ioaddr = devm_ioremap_resource(&pdev->dev, iomem);
> + if (IS_ERR(host->ioaddr)) {
> + ret = PTR_ERR(host->ioaddr);
> + dev_err(&pdev->dev, "unable to map iomem: %d\n", ret);
> + goto err_host;
> + }
> +
> + plat_data = pdev->dev.platform_data;
> + if (plat_data && plat_data->setup_dma) {
> + ret = plat_data->setup_dma(ADMA_FIFO_RD_THSHLD,
> + ADMA_FIFO_WR_THSHLD);
> + if (ret)
> + goto err_host;
> + }
> +
> + pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
> + if (IS_ERR(pinctrl)) {
> + ret = PTR_ERR(pinctrl);
> + dev_warn(&pdev->dev, "No pinctrl provided %d\n", ret);
> + if (ret == -EPROBE_DEFER)
> + goto err_host;
> + }
> +
> + host->ops = &pic32_sdhci_ops;
> + host->irq = platform_get_irq(pdev, 0);
> +
> + sdhci_pdata->sys_clk = devm_clk_get(&pdev->dev, "sys_clk");
> + if (IS_ERR(sdhci_pdata->sys_clk)) {
> + ret = PTR_ERR(sdhci_pdata->sys_clk);
> + dev_err(&pdev->dev, "Error getting clock\n");
> + goto err_host;
> + }
> +
> + /* Enable clock when available! */
> + ret = clk_prepare_enable(sdhci_pdata->sys_clk);
> + if (ret) {
> + dev_dbg(&pdev->dev, "Error enabling clock\n");
Shouldn't this be dev_err()? You don't survive not having the clock
in the stanza above. So if you have the clock, you would want to know
if it didn't deal with the clk_prepare_enable().
The comment 4 lines above is also wrong if so.
> + goto err_host;
> + }
> +
> + /* SDH CLK enable */
> + sdhci_pdata->base_clk = devm_clk_get(&pdev->dev, "base_clk");
> + if (IS_ERR(sdhci_pdata->base_clk)) {
> + ret = PTR_ERR(sdhci_pdata->base_clk);
> + dev_err(&pdev->dev, "Error getting clock\n");
> + goto err_host;
> + }
> +
> + /* Enable clock when available! */
> + ret = clk_prepare_enable(sdhci_pdata->base_clk);
Again the comment seems wrong.
> + if (ret) {
> + dev_dbg(&pdev->dev, "Error enabling clock\n");
And if I understood it, dev_err() needed.
> + goto err_host;
> + }
> +
> + clk_rate = clk_get_rate(sdhci_pdata->base_clk);
> + dev_dbg(&pdev->dev, "base clock at: %u\n", clk_rate);
> + clk_rate = clk_get_rate(sdhci_pdata->sys_clk);
> + dev_dbg(&pdev->dev, "sys clock at: %u\n", clk_rate);
> +
> + host->quirks2 |= SDHCI_QUIRK2_NO_1_8_V;
> +
Probably can lose the blank line.
> + host->quirks |= SDHCI_QUIRK_NO_HISPD_BIT;
> +
> + ret = mmc_of_parse(host->mmc);
> + if (ret)
> + goto err_host;
> +
> + ret = pic32_sdhci_probe_platform(pdev, sdhci_pdata);
> + if (ret) {
> + dev_err(&pdev->dev, "failed to probe platform!\n");
> + goto err_host;
> + }
> +
> + ret = sdhci_add_host(host);
> + if (ret) {
> + dev_dbg(&pdev->dev, "error adding host\n");
> + goto err_host;
> + }
> +
> + dev_info(&pdev->dev, "Successfully added sdhci host\n");
> + return 0;
> +
> +err_host:
> + sdhci_free_host(host);
> +err:
> + dev_err(&pdev->dev, "pic32-sdhci probe failed: %d\n", ret);
> + return ret;
> +}
> +
> +static int pic32_sdhci_remove(struct platform_device *pdev)
> +{
> + struct sdhci_host *host = platform_get_drvdata(pdev);
> + struct pic32_sdhci_pdata *sdhci_pdata = sdhci_priv(host);
> + int dead = 0;
> + u32 scratch;
> +
> + scratch = readl(host->ioaddr + SDHCI_INT_STATUS);
> + if (scratch == (u32)-1)
Since it's not actually related to signed, (u32)~0 might be clearer.
> + dead = 1;
> +
> + sdhci_remove_host(host, dead);
You could get rid of "dead" and have
sdhci_remove_host(host, scratch == (u32)~0);
> + clk_disable_unprepare(sdhci_pdata->base_clk);
> + clk_disable_unprepare(sdhci_pdata->sys_clk);
> + sdhci_free_host(host);
> +
> + return 0;
> +}
> +
> +static const struct of_device_id pic32_sdhci_id_table[] = {
> + { .compatible = "microchip,pic32mzda-sdhci" },
> + {}
> +};
> +MODULE_DEVICE_TABLE(of, pic32_sdhci_id_table);
> +
> +static struct platform_driver pic32_sdhci_driver = {
> + .driver = {
> + .name = DEV_NAME,
> + .owner = THIS_MODULE,
> + .of_match_table = of_match_ptr(pic32_sdhci_id_table),
> + },
> + .probe = pic32_sdhci_probe,
> + .remove = pic32_sdhci_remove,
> +};
> +
> +module_platform_driver(pic32_sdhci_driver);
> +
> +MODULE_DESCRIPTION("Microchip PIC32 SDHCI driver");
> +MODULE_AUTHOR("Pistirica Sorin Andrei & Sandeep Sheriker");
> +MODULE_LICENSE("GPL v2");
> --
> 1.7.9.5
>
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | <Paul.Thacker@microchip.com> |
|---|---|
| Date | 2015-12-16 18:40 +0100 |
| Subject | RE: [PATCH v2 12/14] mmc: sdhci-pic32: Add PIC32 SDHCI host controller driver |
| Message-ID | <qGods-4KL-9@gated-at.bofh.it> |
| In reply to | #1291729 |
T24gMTIvMTQvMjAxNSA1OjMzIFBNLCBBbmR5IEdyZWVuIHdyb3RlOg0KPiBIaS4uLiBsb29rcyBn b29kLCBqdXN0IHNvbWUgc21hbGwgZ2VuZXJhbCBjb21tZW50cy4NCj4gDQo+IE9uIDE1IERlY2Vt YmVyIDIwMTUgYXQgMDY6NDIsIEpvc2h1YSBIZW5kZXJzb24NCj4gPGpvc2h1YS5oZW5kZXJzb25A bWljcm9jaGlwLmNvbT4gd3JvdGU6DQo+ID4gRnJvbTogQW5kcmVpIFBpc3RpcmljYSA8YW5kcmVp LnBpc3RpcmljYUBtaWNyb2NoaXAuY29tPg0KPiA+DQo+ID4gVGhpcyBkcml2ZXIgc3VwcG9ydHMg dGhlIFNESENJIGhvc3QgY29udHJvbGxlciBmb3VuZCBvbiBhIFBJQzMyLg0KPiA+DQo+ID4gU2ln bmVkLW9mZi1ieTogQW5kcmVpIFBpc3RpcmljYSA8YW5kcmVpLnBpc3RpcmljYUBtaWNyb2NoaXAu Y29tPg0KPiA+IFNpZ25lZC1vZmYtYnk6IEpvc2h1YSBIZW5kZXJzb24gPGpvc2h1YS5oZW5kZXJz b25AbWljcm9jaGlwLmNvbT4NCj4gPiBDYzogUmFsZiBCYWVjaGxlIDxyYWxmQGxpbnV4LW1pcHMu b3JnPg0KPiA+IC0tLQ0KPiA+ICBkcml2ZXJzL21tYy9ob3N0L0tjb25maWcgICAgICAgfCAgIDEx ICsrDQo+ID4gIGRyaXZlcnMvbW1jL2hvc3QvTWFrZWZpbGUgICAgICB8ICAgIDEgKw0KPiA+ICBk cml2ZXJzL21tYy9ob3N0L3NkaGNpLXBpYzMyLmMgfCAgMjkxDQo+ID4gKysrKysrKysrKysrKysr KysrKysrKysrKysrKysrKysrKysrKysrKw0KPiA+ICAzIGZpbGVzIGNoYW5nZWQsIDMwMyBpbnNl cnRpb25zKCspDQo+ID4gIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL21tYy9ob3N0L3NkaGNp LXBpYzMyLmMNCj4gPg0KPiA+IGRpZmYgLS1naXQgYS9kcml2ZXJzL21tYy9ob3N0L0tjb25maWcg Yi9kcml2ZXJzL21tYy9ob3N0L0tjb25maWcgaW5kZXgNCj4gPiAxZGVlNTMzLi4xYTNhNDJiIDEw MDY0NA0KPiA+IC0tLSBhL2RyaXZlcnMvbW1jL2hvc3QvS2NvbmZpZw0KPiA+ICsrKyBiL2RyaXZl cnMvbW1jL2hvc3QvS2NvbmZpZw0KPiA+IEBAIC03ODUsMyArNzg1LDE0IEBAIGNvbmZpZyBNTUNf TVRLDQo+ID4gICAgICAgICAgIElmIHlvdSBoYXZlIGEgbWFjaGluZSB3aXRoIGEgaW50ZWdyYXRl ZCBTRC9NTUMgY2FyZCByZWFkZXIsIHNheSBZIG9yIE0NCj4gaGVyZS4NCj4gPiAgICAgICAgICAg VGhpcyBpcyBuZWVkZWQgaWYgc3VwcG9ydCBmb3IgYW55IFNEL1NESU8vTU1DIGRldmljZXMgaXMg cmVxdWlyZWQuDQo+ID4gICAgICAgICAgIElmIHVuc3VyZSwgc2F5IE4uDQo+ID4gKw0KPiA+ICtj b25maWcgTU1DX1NESENJX01JQ1JPQ0hJUF9QSUMzMg0KPiA+ICsgICAgICAgIHRyaXN0YXRlICJN aWNyb2NoaXAgUElDMzJNWkRBIFNESENJIHN1cHBvcnQiDQo+ID4gKyAgICAgICAgZGVwZW5kcyBv biBNTUNfU0RIQ0kgJiYgUElDMzJNWkRBDQo+ID4gKyAgICAgICAgaGVscA0KPiA+ICsgICAgICAg ICAgVGhpcyBzZWxlY3RzIHRoZSBTZWN1cmUgRGlnaXRhbCBIb3N0IENvbnRyb2xsZXIgSW50ZXJm YWNlIChTREhDSSkNCj4gPiArICAgICAgICAgIGZvciBQSUMzMk1aREEgcGxhdGZvcm0uDQo+ID4g Kw0KPiA+ICsgICAgICAgICAgSWYgeW91IGhhdmUgYSBjb250cm9sbGVyIHdpdGggdGhpcyBpbnRl cmZhY2UsIHNheSBZIG9yIE0gaGVyZS4NCj4gPiArDQo+ID4gKyAgICAgICAgICBJZiB1bnN1cmUs IHNheSBOLg0KPiA+IGRpZmYgLS1naXQgYS9kcml2ZXJzL21tYy9ob3N0L01ha2VmaWxlIGIvZHJp dmVycy9tbWMvaG9zdC9NYWtlZmlsZQ0KPiA+IGluZGV4IDM1OTVmODMuLmFmOTE4ZDIgMTAwNjQ0 DQo+ID4gLS0tIGEvZHJpdmVycy9tbWMvaG9zdC9NYWtlZmlsZQ0KPiA+ICsrKyBiL2RyaXZlcnMv bW1jL2hvc3QvTWFrZWZpbGUNCj4gPiBAQCAtNzUsNiArNzUsNyBAQCBvYmotJChDT05GSUdfTU1D X1NESENJX0JDTTI4MzUpICAgICAgICAgICAgICAgKz0gc2RoY2ktDQo+IGJjbTI4MzUubw0KPiA+ ICBvYmotJChDT05GSUdfTU1DX1NESENJX0lQUk9DKSAgICAgICAgICArPSBzZGhjaS1pcHJvYy5v DQo+ID4gIG9iai0kKENPTkZJR19NTUNfU0RIQ0lfTVNNKSAgICAgICAgICAgICs9IHNkaGNpLW1z bS5vDQo+ID4gIG9iai0kKENPTkZJR19NTUNfU0RIQ0lfU1QpICAgICAgICAgICAgICs9IHNkaGNp LXN0Lm8NCj4gPiArb2JqLSQoQ09ORklHX01NQ19TREhDSV9NSUNST0NISVBfUElDMzIpICAgICAg ICArPSBzZGhjaS1waWMzMi5vDQo+ID4NCj4gPiAgaWZlcSAoJChDT05GSUdfQ0I3MTBfREVCVUcp LHkpDQo+ID4gICAgICAgICBDRkxBR1MtY2I3MTAtbW1jICAgICAgICArPSAtRERFQlVHDQo+ID4g ZGlmZiAtLWdpdCBhL2RyaXZlcnMvbW1jL2hvc3Qvc2RoY2ktcGljMzIuYw0KPiA+IGIvZHJpdmVy cy9tbWMvaG9zdC9zZGhjaS1waWMzMi5jIG5ldyBmaWxlIG1vZGUgMTAwNjQ0IGluZGV4DQo+ID4g MDAwMDAwMC4uYjdkN2RhMg0KPiA+IC0tLSAvZGV2L251bGwNCj4gPiArKysgYi9kcml2ZXJzL21t Yy9ob3N0L3NkaGNpLXBpYzMyLmMNCj4gPiBAQCAtMCwwICsxLDI5MSBAQA0KPiA+ICsvKg0KPiA+ ICsgKiBTdXBwb3J0IG9mIFNESENJIHBsYXRmb3JtIGRldmljZXMgZm9yIE1pY3JvY2hpcCBQSUMz Mi4NCj4gPiArICoNCj4gPiArICogQ29weXJpZ2h0IChDKSAyMDE1IE1pY3JvY2hpcA0KPiA+ICsg KiBBbmRyZWkgUGlzdGlyaWNhLCBQYXVsIFRoYWNrZXINCj4gPiArICoNCj4gPiArICogSW5zcGly ZWQgYnkgc2RoY2ktcGx0Zm0uYw0KPiA+ICsgKg0KPiA+ICsgKiBUaGlzIGZpbGUgaXMgbGljZW5z ZWQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMNCj4gPiArICogTGlj ZW5zZSB2ZXJzaW9uIDIuIFRoaXMgcHJvZ3JhbSBpcyBsaWNlbnNlZCAiYXMgaXMiIHdpdGhvdXQg YW55DQo+ID4gKyAqIHdhcnJhbnR5IG9mIGFueSBraW5kLCB3aGV0aGVyIGV4cHJlc3Mgb3IgaW1w bGllZC4NCj4gPiArICovDQo+ID4gKw0KPiA+ICsjaW5jbHVkZSA8bGludXgvY2xrLmg+DQo+ID4g KyNpbmNsdWRlIDxsaW51eC9kZWxheS5oPg0KPiA+ICsjaW5jbHVkZSA8bGludXgvaGlnaG1lbS5o Pg0KPiA+ICsjaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+DQo+ID4gKyNpbmNsdWRlIDxsaW51eC9p bnRlcnJ1cHQuaD4NCj4gPiArI2luY2x1ZGUgPGxpbnV4L2lycS5oPg0KPiA+ICsjaW5jbHVkZSA8 bGludXgvb2YuaD4NCj4gPiArI2luY2x1ZGUgPGxpbnV4L3BsYXRmb3JtX2RldmljZS5oPg0KPiA+ ICsjaW5jbHVkZSA8bGludXgvcG0uaD4NCj4gPiArI2luY2x1ZGUgPGxpbnV4L3NsYWIuaD4NCj4g PiArI2luY2x1ZGUgPGxpbnV4L21tYy9ob3N0Lmg+DQo+ID4gKyNpbmNsdWRlIDxsaW51eC9pby5o Pg0KPiA+ICsjaW5jbHVkZSAic2RoY2kuaCINCj4gPiArI2luY2x1ZGUgPGxpbnV4L3BsYXRmb3Jt X2RhdGEvc2RoY2ktcGljMzIuaD4NCj4gPiArDQo+ID4gKyNkZWZpbmUgU0RIX1NIQVJFRF9CVVNf Q1RSTCAgICAgICAgICAgIDB4MDAwMDAwRTANCj4gPiArI2RlZmluZSBTREhfU0hBUkVEX0JVU19O Ul9DTEtfUElOU19NQVNLICAgICAgICAweDcNCj4gPiArI2RlZmluZSBTREhfU0hBUkVEX0JVU19O Ul9JUlFfUElOU19NQVNLICAgICAgICAweDMwDQo+ID4gKyNkZWZpbmUgU0RIX1NIQVJFRF9CVVNf Q0xLX1BJTlMgICAgICAgICAgICAgICAgMHgxMA0KPiA+ICsjZGVmaW5lIFNESF9TSEFSRURfQlVT X0lSUV9QSU5TICAgICAgICAgICAgICAgIDB4MTQNCj4gPiArI2RlZmluZSBTREhfQ0FQU19TREhf U0xPVF9UWVBFX01BU0sgICAgMHhDMDAwMDAwMA0KPiA+ICsjZGVmaW5lIFNESF9TTE9UX1RZUEVf UkVNT1ZBQkxFICAgICAgICAgICAgICAgIDB4MA0KPiA+ICsjZGVmaW5lIFNESF9TTE9UX1RZUEVf RU1CRURERUQgICAgICAgICAweDENCj4gPiArI2RlZmluZSBTREhfU0xPVF9UWVBFX1NIQVJFRF9C VVMgICAgICAgMHgyDQo+ID4gKyNkZWZpbmUgU0RIQ0lfQ1RSTF9DRFNTRUwgICAgICAgICAgICAg IDB4ODANCj4gPiArI2RlZmluZSBTREhDSV9DVFJMX0NEVExWTCAgICAgICAgICAgICAgMHg0MA0K PiA+ICsNCj4gPiArI2RlZmluZSBBRE1BX0ZJRk9fUkRfVEhTSExEICAgIDUxMg0KPiA+ICsjZGVm aW5lIEFETUFfRklGT19XUl9USFNITEQgICAgNTEyDQo+ID4gKw0KPiA+ICsjZGVmaW5lIERFVl9O QU1FICJwaWMzMi1zZGhjaSINCj4gDQo+IElzIHRoZXJlIGFueSBwb2ludCBkZWZpbmluZyB0aGlz IHdoZW4gaXQgb25seSBoYXMgb25lIHVzZSBpbiB0aGUgZHJpdmVyPw0KDQpBY2suIFdpbGwgcmVt b3ZlLg0KDQo+IA0KPiA+ICtzdHJ1Y3QgcGljMzJfc2RoY2lfcGRhdGEgew0KPiA+ICsgICAgICAg c3RydWN0IHBsYXRmb3JtX2RldmljZSAgKnBkZXY7DQo+ID4gKyAgICAgICBzdHJ1Y3QgY2xrICpz eXNfY2xrOw0KPiA+ICsgICAgICAgc3RydWN0IGNsayAqYmFzZV9jbGs7DQo+ID4gK307DQo+ID4g Kw0KPiA+ICtzdGF0aWMgdW5zaWduZWQgaW50IHBpYzMyX3NkaGNpX2dldF9tYXhfY2xvY2soc3Ry dWN0IHNkaGNpX2hvc3QNCj4gPiArKmhvc3QpIHsNCj4gPiArICAgICAgIHN0cnVjdCBwaWMzMl9z ZGhjaV9wZGF0YSAqc2RoY2lfcGRhdGEgPSBzZGhjaV9wcml2KGhvc3QpOw0KPiA+ICsNCj4gPiAr ICAgICAgIHJldHVybiBjbGtfZ2V0X3JhdGUoc2RoY2lfcGRhdGEtPmJhc2VfY2xrKTsNCj4gPiAr fQ0KPiA+ICsNCj4gPiArc3RhdGljIHZvaWQgcGljMzJfc2RoY2lfc2V0X2J1c193aWR0aChzdHJ1 Y3Qgc2RoY2lfaG9zdCAqaG9zdCwgaW50DQo+ID4gK3dpZHRoKSB7DQo+ID4gKyAgICAgICB1OCBj dHJsOw0KPiA+ICsNCj4gPiArICAgICAgIGN0cmwgPSBzZGhjaV9yZWFkYihob3N0LCBTREhDSV9I T1NUX0NPTlRST0wpOw0KPiA+ICsgICAgICAgaWYgKHdpZHRoID09IE1NQ19CVVNfV0lEVEhfOCkg ew0KPiA+ICsgICAgICAgICAgICAgICBjdHJsICY9IH5TREhDSV9DVFJMXzRCSVRCVVM7DQo+ID4g KyAgICAgICAgICAgICAgIGlmIChob3N0LT52ZXJzaW9uID49IFNESENJX1NQRUNfMzAwKQ0KPiA+ ICsgICAgICAgICAgICAgICAgICAgICAgIGN0cmwgfD0gU0RIQ0lfQ1RSTF84QklUQlVTOw0KPiA+ ICsgICAgICAgfSBlbHNlIHsNCj4gPiArICAgICAgICAgICAgICAgaWYgKGhvc3QtPnZlcnNpb24g Pj0gU0RIQ0lfU1BFQ18zMDApDQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgY3RybCAmPSB+ U0RIQ0lfQ1RSTF84QklUQlVTOw0KPiA+ICsgICAgICAgICAgICAgICBpZiAod2lkdGggPT0gTU1D X0JVU19XSURUSF80KQ0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgIGN0cmwgfD0gU0RIQ0lf Q1RSTF80QklUQlVTOw0KPiA+ICsgICAgICAgICAgICAgICBlbHNlDQo+ID4gKyAgICAgICAgICAg ICAgICAgICAgICAgY3RybCAmPSB+U0RIQ0lfQ1RSTF80QklUQlVTOw0KPiA+ICsgICAgICAgfQ0K PiA+ICsgICAgICAgLyoNCj4gPiArICAgICAgICAqIFNESENJIHdpbGwgbm90IHdvcmsgaWYgSlRB RyBpcyBub3QgQ29ubmVjdGVkLkFzIGEgd29ya2Fyb3VuZCBmaXgsDQo+ID4gKyAgICAgICAgKiBz ZXQgQ2FyZCBEZXRlY3QgU2lnbmFsIFNlbGVjdGlvbiBiaXQgaW4gU0RIQ0kgSG9zdCBDb250cm9s DQo+ID4gKyAgICAgICAgKiByZWdpc3RlciBhbmQgY2xlYXIgQ2FyZCBEZXRlY3QgVGVzdCBMZXZl bCBiaXQgaW4gU0RIQ0kgSG9zdA0KPiA+ICsgICAgICAgICogQ29udHJvbCByZWdpc3Rlci4NCj4g PiArICAgICAgICAqLw0KPiANCj4gSXNuJ3QgdGhpcyBhIGNsZWFyZXIgZXhwbGFuYXRpb24sIGlm IEkgdW5kZXJzdG9vZD8NCj4gDQo+ICJXaXRob3V0IHNldHRpbmcgQ0Qgc2VsZWN0IGFuZCB0ZXN0 IGJpdHMgbm93LCBTREhDSSBvbmx5IHdvcmtzIHdpdGggSlRBRw0KPiBjb25uZWN0ZWQuIg0KPiAN Cj4gPiArICAgICAgIGN0cmwgJj0gflNESENJX0NUUkxfQ0RUTFZMOw0KPiA+ICsgICAgICAgY3Ry bCB8PSBTREhDSV9DVFJMX0NEU1NFTDsNCj4gPiArICAgICAgIHNkaGNpX3dyaXRlYihob3N0LCBj dHJsLCBTREhDSV9IT1NUX0NPTlRST0wpOw0KPiANCj4gQWxzby4uLiBpcyB0aGF0IGEgZmVhdHVy ZSBvZiB0aGUgU0RIQ0kgSVAgb3IgdGhpcyBwYXJ0aWN1bGFyIGNoaXAncyBpbXBsZW1lbnRhdGlv bg0KPiBvZiBpdD8gIEkgZ3Vlc3MgaWYgdGhlcmUgaXMgb25seSBvbmUgaW1wbGVtZW50YXRpb24g cmlnaHQgbm93IHRoYXQgaGFzIHRoYXQNCj4gcmVzdHJpY3Rpb24gd29ycnkgYWJvdXQgbWFraW5n IGl0IHNlbGVjdGFibGUgbGF0ZXIuICBCdXQgaWYgdGhlIGltcGxlbWVudGF0aW9uLCBpdA0KPiBt aWdodCBtYWtlIHNlbnNlIHRvIGFsc28gcHV0IHRoZSBhZmZlY3RlZCBpbXBsZW1lbnRhdGlvbiBu YW1lIGluIHRoZQ0KPiBjb21tZW50IHRvIG1ha2UgaXQgY2xlYXIuDQoNClRoaXMgaXMgYSBjaGlw IGVycmF0YS4gSGF2aW5nIEpUQUcgY29ubmVjdGVkIG1hc2tzIHRoZSBwcm9ibGVtLCBidXQgaXMg b3RoZXJ3aXNlIGlycmVsZXZhbnQuIENvbW1lbnQgd2lsbCBiZSBjaGFuZ2VkIHRvOiAiQ0Qgc2Vs ZWN0IGFuZCB0ZXN0IGJpdHMgbXVzdCBiZSBzZXQgZm9yIGVycmF0YSB3b3JrYXJvdW5kLiINCg0K PiANCj4gPiArfQ0KPiA+ICsNCj4gPiArc3RhdGljIHVuc2lnbmVkIGludCBwaWMzMl9zZGhjaV9n ZXRfcm8oc3RydWN0IHNkaGNpX2hvc3QgKmhvc3QpIHsNCj4gPiArICAgICAgIC8qDQo+ID4gKyAg ICAgICAgKiBUaGUgU0RIQ0lfV1JJVEVfUFJPVEVDVCBiaXQgaXMgdW5zdGFibGUgb24gY3VycmVu dCBoYXJkd2FyZSBzbyB3ZQ0KPiA+ICsgICAgICAgICogY2FuJ3QgZGVwZW5kIG9uIGl0cyB2YWx1 ZSBpbiBhbnkgd2F5Lg0KPiA+ICsgICAgICAgICovDQo+ID4gKyAgICAgICByZXR1cm4gMDsNCj4g PiArfQ0KPiA+ICsNCj4gPiArc3RhdGljIGNvbnN0IHN0cnVjdCBzZGhjaV9vcHMgcGljMzJfc2Ro Y2lfb3BzID0gew0KPiA+ICsgICAgICAgLmdldF9tYXhfY2xvY2sgPSBwaWMzMl9zZGhjaV9nZXRf bWF4X2Nsb2NrLA0KPiA+ICsgICAgICAgLnNldF9jbG9jayA9IHNkaGNpX3NldF9jbG9jaywNCj4g PiArICAgICAgIC5zZXRfYnVzX3dpZHRoID0gcGljMzJfc2RoY2lfc2V0X2J1c193aWR0aCwNCj4g PiArICAgICAgIC5yZXNldCA9IHNkaGNpX3Jlc2V0LA0KPiA+ICsgICAgICAgLnNldF91aHNfc2ln bmFsaW5nID0gc2RoY2lfc2V0X3Voc19zaWduYWxpbmcsDQo+ID4gKyAgICAgICAuZ2V0X3JvID0g cGljMzJfc2RoY2lfZ2V0X3JvLA0KPiA+ICt9Ow0KPiA+ICsNCj4gPiArc3RhdGljIHZvaWQgcGlj MzJfc2RoY2lfc2hhcmVkX2J1cyhzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2KSB7DQo+ID4g KyAgICAgICBzdHJ1Y3Qgc2RoY2lfaG9zdCAqaG9zdCA9IHBsYXRmb3JtX2dldF9kcnZkYXRhKHBk ZXYpOw0KPiA+ICsgICAgICAgdTMyIGJ1cyA9IHJlYWRsKGhvc3QtPmlvYWRkciArIFNESF9TSEFS RURfQlVTX0NUUkwpOw0KPiA+ICsgICAgICAgdTMyIGNsa19waW5zID0gKGJ1cyAmIFNESF9TSEFS RURfQlVTX05SX0NMS19QSU5TX01BU0spID4+IDA7DQo+ID4gKyAgICAgICB1MzIgaXJxX3BpbnMg PSAoYnVzICYgU0RIX1NIQVJFRF9CVVNfTlJfSVJRX1BJTlNfTUFTSykgPj4gNDsNCj4gPiArDQo+ ID4gKyAgICAgICAvKiBzZWxlY3QgZmlyc3QgY2xvY2sgKi8NCj4gPiArICAgICAgIGlmIChjbGtf cGlucyAmIDB4MSkNCj4gDQo+IEJJVCgwKT8gIEFsc28gYSBjb3VwbGUgb2YgbGluZXMgZG93bi4N Cj4gDQo+ID4gKyAgICAgICAgICAgICAgIGJ1cyB8PSAoMHgxIDw8IFNESF9TSEFSRURfQlVTX0NM S19QSU5TKTsNCj4gDQo+IEkga25vdyBpdCdzIHBvcHVsYXIgYnV0IHRoZXJlIGlzIG5vIG1lYW5p bmcgb3IgdXNlIGluICIweDEiIHdoZXJlIHlvdSBjb3VsZCBqdXN0DQo+IHNheSAiMSIuDQo+IA0K PiA+ICsgICAgICAgLyogc2VsZWN0IGZpcnN0IGludGVycnVwdCAqLw0KPiA+ICsgICAgICAgaWYg KGlycV9waW5zICYgMHgxKQ0KPiA+ICsgICAgICAgICAgICAgICBidXMgfD0gKDB4MSA8PCBTREhf U0hBUkVEX0JVU19JUlFfUElOUyk7DQo+IA0KPiBBcyBhYm92ZS4NCg0KQWNrLiBXaWxsIGNoYW5n ZS4NCg0KPiANCj4gPiArICAgICAgIHdyaXRlbChidXMsIGhvc3QtPmlvYWRkciArIFNESF9TSEFS RURfQlVTX0NUUkwpOyB9DQo+ID4gKw0KPiA+ICtzdGF0aWMgaW50IHBpYzMyX3NkaGNpX3Byb2Jl X3BsYXRmb3JtKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYsDQo+ID4gKyAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJ1Y3QgcGljMzJfc2RoY2lfcGRhdGEgKnBkYXRh KQ0KPiA+ICt7DQo+ID4gKyAgICAgICBpbnQgcmV0ID0gMDsNCj4gPiArICAgICAgIHUzMiBjYXBz X3Nsb3RfdHlwZTsNCj4gPiArICAgICAgIHN0cnVjdCBzZGhjaV9ob3N0ICpob3N0ID0gcGxhdGZv cm1fZ2V0X2RydmRhdGEocGRldik7DQo+ID4gKw0KPiA+ICsgICAgICAgLyogQ2hlY2sgY2FyZCBz bG90IGNvbm5lY3RlZCBvbiBzaGFyZWQgYnVzLiAqLw0KPiA+ICsgICAgICAgaG9zdC0+Y2FwcyA9 IHJlYWRsKGhvc3QtPmlvYWRkciArIFNESENJX0NBUEFCSUxJVElFUyk7DQo+ID4gKyAgICAgICBj YXBzX3Nsb3RfdHlwZSA9IChob3N0LT5jYXBzICYgU0RIX0NBUFNfU0RIX1NMT1RfVFlQRV9NQVNL KSA+Pg0KPiAzMDsNCj4gPiArICAgICAgIGlmIChjYXBzX3Nsb3RfdHlwZSA9PSBTREhfU0xPVF9U WVBFX1NIQVJFRF9CVVMpDQo+ID4gKyAgICAgICAgICAgICAgIHBpYzMyX3NkaGNpX3NoYXJlZF9i dXMocGRldik7DQo+ID4gKw0KPiA+ICsgICAgICAgcmV0dXJuIHJldDsNCj4gPiArfQ0KPiA+ICsN Cj4gPiArc3RhdGljIGludCBwaWMzMl9zZGhjaV9wcm9iZShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNl ICpwZGV2KSB7DQo+ID4gKyAgICAgICBzdHJ1Y3QgZGV2aWNlICpkZXYgPSAmcGRldi0+ZGV2Ow0K PiA+ICsgICAgICAgc3RydWN0IHNkaGNpX2hvc3QgKmhvc3Q7DQo+ID4gKyAgICAgICBzdHJ1Y3Qg cmVzb3VyY2UgKmlvbWVtOw0KPiA+ICsgICAgICAgc3RydWN0IHBpYzMyX3NkaGNpX3BkYXRhICpz ZGhjaV9wZGF0YTsNCj4gPiArICAgICAgIHN0cnVjdCBwaWMzMl9zZGhjaV9wbGF0Zm9ybV9kYXRh ICpwbGF0X2RhdGE7DQo+ID4gKyAgICAgICB1bnNpZ25lZCBpbnQgY2xrX3JhdGUgPSAwOw0KPiA+ ICsgICAgICAgaW50IHJldDsNCj4gPiArICAgICAgIHN0cnVjdCBwaW5jdHJsICpwaW5jdHJsOw0K PiANCj4gSXQncyBoYXJkbHkgY3JpdGljYWwgYnV0IGZvciBleHRyYSBnb2xkIHN0YXIgYXJyYW5n aW5nIGxvY2FsIHZhcnMgaW4gbGVuZ3RoIG9yZGVyDQo+IChsb25nZXN0IGZpcnN0KSBpcyBuaWNl Lg0KDQpBY2suDQoNCj4gDQo+ID4gKw0KPiA+ICsgICAgICAgaG9zdCA9IHNkaGNpX2FsbG9jX2hv c3QoZGV2LCBzaXplb2YoKnNkaGNpX3BkYXRhKSk7DQo+ID4gKyAgICAgICBpZiAoSVNfRVJSKGhv c3QpKSB7DQo+ID4gKyAgICAgICAgICAgICAgIHJldCA9IFBUUl9FUlIoaG9zdCk7DQo+ID4gKyAg ICAgICAgICAgICAgIGRldl9lcnIoJnBkZXYtPmRldiwgImNhbm5vdCBhbGxvY2F0ZSBtZW1vcnkg Zm9yIHNkaGNpXG4iKTsNCj4gPiArICAgICAgICAgICAgICAgZ290byBlcnI7DQo+ID4gKyAgICAg ICB9DQo+ID4gKw0KPiA+ICsgICAgICAgc2RoY2lfcGRhdGEgPSBzZGhjaV9wcml2KGhvc3QpOw0K PiA+ICsgICAgICAgc2RoY2lfcGRhdGEtPnBkZXYgPSBwZGV2Ow0KPiA+ICsgICAgICAgcGxhdGZv cm1fc2V0X2RydmRhdGEocGRldiwgaG9zdCk7DQo+ID4gKw0KPiA+ICsgICAgICAgaW9tZW0gPSBw bGF0Zm9ybV9nZXRfcmVzb3VyY2UocGRldiwgSU9SRVNPVVJDRV9NRU0sIDApOw0KPiA+ICsgICAg ICAgaG9zdC0+aW9hZGRyID0gZGV2bV9pb3JlbWFwX3Jlc291cmNlKCZwZGV2LT5kZXYsIGlvbWVt KTsNCj4gPiArICAgICAgIGlmIChJU19FUlIoaG9zdC0+aW9hZGRyKSkgew0KPiA+ICsgICAgICAg ICAgICAgICByZXQgPSBQVFJfRVJSKGhvc3QtPmlvYWRkcik7DQo+ID4gKyAgICAgICAgICAgICAg IGRldl9lcnIoJnBkZXYtPmRldiwgInVuYWJsZSB0byBtYXAgaW9tZW06ICVkXG4iLCByZXQpOw0K PiA+ICsgICAgICAgICAgICAgICBnb3RvIGVycl9ob3N0Ow0KPiA+ICsgICAgICAgfQ0KPiA+ICsN Cj4gPiArICAgICAgIHBsYXRfZGF0YSA9IHBkZXYtPmRldi5wbGF0Zm9ybV9kYXRhOw0KPiA+ICsg ICAgICAgaWYgKHBsYXRfZGF0YSAmJiBwbGF0X2RhdGEtPnNldHVwX2RtYSkgew0KPiA+ICsgICAg ICAgICAgICAgICByZXQgPSBwbGF0X2RhdGEtPnNldHVwX2RtYShBRE1BX0ZJRk9fUkRfVEhTSExE LA0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBRE1BX0ZJ Rk9fV1JfVEhTSExEKTsNCj4gPiArICAgICAgICAgICAgICAgaWYgKHJldCkNCj4gPiArICAgICAg ICAgICAgICAgICAgICAgICBnb3RvIGVycl9ob3N0Ow0KPiA+ICsgICAgICAgfQ0KPiA+ICsNCj4g PiArICAgICAgIHBpbmN0cmwgPSBkZXZtX3BpbmN0cmxfZ2V0X3NlbGVjdF9kZWZhdWx0KCZwZGV2 LT5kZXYpOw0KPiA+ICsgICAgICAgaWYgKElTX0VSUihwaW5jdHJsKSkgew0KPiA+ICsgICAgICAg ICAgICAgICByZXQgPSBQVFJfRVJSKHBpbmN0cmwpOw0KPiA+ICsgICAgICAgICAgICAgICBkZXZf d2FybigmcGRldi0+ZGV2LCAiTm8gcGluY3RybCBwcm92aWRlZCAlZFxuIiwgcmV0KTsNCj4gPiAr ICAgICAgICAgICAgICAgaWYgKHJldCA9PSAtRVBST0JFX0RFRkVSKQ0KPiA+ICsgICAgICAgICAg ICAgICAgICAgICAgIGdvdG8gZXJyX2hvc3Q7DQo+ID4gKyAgICAgICB9DQo+ID4gKw0KPiA+ICsg ICAgICAgaG9zdC0+b3BzID0gJnBpYzMyX3NkaGNpX29wczsNCj4gPiArICAgICAgIGhvc3QtPmly cSA9IHBsYXRmb3JtX2dldF9pcnEocGRldiwgMCk7DQo+ID4gKw0KPiA+ICsgICAgICAgc2RoY2lf cGRhdGEtPnN5c19jbGsgPSBkZXZtX2Nsa19nZXQoJnBkZXYtPmRldiwgInN5c19jbGsiKTsNCj4g PiArICAgICAgIGlmIChJU19FUlIoc2RoY2lfcGRhdGEtPnN5c19jbGspKSB7DQo+ID4gKyAgICAg ICAgICAgICAgIHJldCA9IFBUUl9FUlIoc2RoY2lfcGRhdGEtPnN5c19jbGspOw0KPiA+ICsgICAg ICAgICAgICAgICBkZXZfZXJyKCZwZGV2LT5kZXYsICJFcnJvciBnZXR0aW5nIGNsb2NrXG4iKTsN Cj4gPiArICAgICAgICAgICAgICAgZ290byBlcnJfaG9zdDsNCj4gPiArICAgICAgIH0NCj4gPiAr DQo+ID4gKyAgICAgICAvKiBFbmFibGUgY2xvY2sgd2hlbiBhdmFpbGFibGUhICovDQo+ID4gKyAg ICAgICByZXQgPSBjbGtfcHJlcGFyZV9lbmFibGUoc2RoY2lfcGRhdGEtPnN5c19jbGspOw0KPiA+ ICsgICAgICAgaWYgKHJldCkgew0KPiA+ICsgICAgICAgICAgICAgICBkZXZfZGJnKCZwZGV2LT5k ZXYsICJFcnJvciBlbmFibGluZyBjbG9ja1xuIik7DQo+IA0KPiBTaG91bGRuJ3QgdGhpcyBiZSBk ZXZfZXJyKCk/ICBZb3UgZG9uJ3Qgc3Vydml2ZSBub3QgaGF2aW5nIHRoZSBjbG9jayBpbiB0aGUg c3RhbnphDQo+IGFib3ZlLiAgU28gaWYgeW91IGhhdmUgdGhlIGNsb2NrLCB5b3Ugd291bGQgd2Fu dCB0byBrbm93IGlmIGl0IGRpZG4ndCBkZWFsIHdpdGgNCj4gdGhlIGNsa19wcmVwYXJlX2VuYWJs ZSgpLg0KPiANCj4gVGhlIGNvbW1lbnQgNCBsaW5lcyBhYm92ZSBpcyBhbHNvIHdyb25nIGlmIHNv Lg0KDQpBY2suIA0KDQo+IA0KPiA+ICsgICAgICAgICAgICAgICBnb3RvIGVycl9ob3N0Ow0KPiA+ ICsgICAgICAgfQ0KPiA+ICsNCj4gPiArICAgICAgIC8qIFNESCBDTEsgZW5hYmxlICovDQo+ID4g KyAgICAgICBzZGhjaV9wZGF0YS0+YmFzZV9jbGsgPSBkZXZtX2Nsa19nZXQoJnBkZXYtPmRldiwg ImJhc2VfY2xrIik7DQo+ID4gKyAgICAgICBpZiAoSVNfRVJSKHNkaGNpX3BkYXRhLT5iYXNlX2Ns aykpIHsNCj4gPiArICAgICAgICAgICAgICAgcmV0ID0gUFRSX0VSUihzZGhjaV9wZGF0YS0+YmFz ZV9jbGspOw0KPiA+ICsgICAgICAgICAgICAgICBkZXZfZXJyKCZwZGV2LT5kZXYsICJFcnJvciBn ZXR0aW5nIGNsb2NrXG4iKTsNCj4gPiArICAgICAgICAgICAgICAgZ290byBlcnJfaG9zdDsNCj4g PiArICAgICAgIH0NCj4gPiArDQo+ID4gKyAgICAgICAvKiBFbmFibGUgY2xvY2sgd2hlbiBhdmFp bGFibGUhICovDQo+ID4gKyAgICAgICByZXQgPSBjbGtfcHJlcGFyZV9lbmFibGUoc2RoY2lfcGRh dGEtPmJhc2VfY2xrKTsNCj4gDQo+IEFnYWluIHRoZSBjb21tZW50IHNlZW1zIHdyb25nLg0KDQpB Y2suDQoNCj4gDQo+ID4gKyAgICAgICBpZiAocmV0KSB7DQo+ID4gKyAgICAgICAgICAgICAgIGRl dl9kYmcoJnBkZXYtPmRldiwgIkVycm9yIGVuYWJsaW5nIGNsb2NrXG4iKTsNCj4gDQo+IEFuZCBp ZiBJIHVuZGVyc3Rvb2QgaXQsIGRldl9lcnIoKSBuZWVkZWQuDQoNCkFjay4NCg0KPiANCj4gPiAr ICAgICAgICAgICAgICAgZ290byBlcnJfaG9zdDsNCj4gPiArICAgICAgIH0NCj4gPiArDQo+ID4g KyAgICAgICBjbGtfcmF0ZSA9IGNsa19nZXRfcmF0ZShzZGhjaV9wZGF0YS0+YmFzZV9jbGspOw0K PiA+ICsgICAgICAgZGV2X2RiZygmcGRldi0+ZGV2LCAiYmFzZSBjbG9jayBhdDogJXVcbiIsIGNs a19yYXRlKTsNCj4gPiArICAgICAgIGNsa19yYXRlID0gY2xrX2dldF9yYXRlKHNkaGNpX3BkYXRh LT5zeXNfY2xrKTsNCj4gPiArICAgICAgIGRldl9kYmcoJnBkZXYtPmRldiwgInN5cyBjbG9jayBh dDogJXVcbiIsIGNsa19yYXRlKTsNCj4gPiArDQo+ID4gKyAgICAgICBob3N0LT5xdWlya3MyIHw9 IFNESENJX1FVSVJLMl9OT18xXzhfVjsNCj4gPiArDQo+IA0KPiBQcm9iYWJseSBjYW4gbG9zZSB0 aGUgYmxhbmsgbGluZS4NCg0KQWNrLg0KDQo+IA0KPiA+ICsgICAgICAgaG9zdC0+cXVpcmtzIHw9 IFNESENJX1FVSVJLX05PX0hJU1BEX0JJVDsNCj4gPiArDQo+ID4gKyAgICAgICByZXQgPSBtbWNf b2ZfcGFyc2UoaG9zdC0+bW1jKTsNCj4gPiArICAgICAgIGlmIChyZXQpDQo+ID4gKyAgICAgICAg ICAgICAgIGdvdG8gZXJyX2hvc3Q7DQo+ID4gKw0KPiA+ICsgICAgICAgcmV0ID0gcGljMzJfc2Ro Y2lfcHJvYmVfcGxhdGZvcm0ocGRldiwgc2RoY2lfcGRhdGEpOw0KPiA+ICsgICAgICAgaWYgKHJl dCkgew0KPiA+ICsgICAgICAgICAgICAgICBkZXZfZXJyKCZwZGV2LT5kZXYsICJmYWlsZWQgdG8g cHJvYmUgcGxhdGZvcm0hXG4iKTsNCj4gPiArICAgICAgICAgICAgICAgZ290byBlcnJfaG9zdDsN Cj4gPiArICAgICAgIH0NCj4gPiArDQo+ID4gKyAgICAgICByZXQgPSBzZGhjaV9hZGRfaG9zdCho b3N0KTsNCj4gPiArICAgICAgIGlmIChyZXQpIHsNCj4gPiArICAgICAgICAgICAgICAgZGV2X2Ri ZygmcGRldi0+ZGV2LCAiZXJyb3IgYWRkaW5nIGhvc3RcbiIpOw0KPiA+ICsgICAgICAgICAgICAg ICBnb3RvIGVycl9ob3N0Ow0KPiA+ICsgICAgICAgfQ0KPiA+ICsNCj4gPiArICAgICAgIGRldl9p bmZvKCZwZGV2LT5kZXYsICJTdWNjZXNzZnVsbHkgYWRkZWQgc2RoY2kgaG9zdFxuIik7DQo+ID4g KyAgICAgICByZXR1cm4gMDsNCj4gPiArDQo+ID4gK2Vycl9ob3N0Og0KPiA+ICsgICAgICAgc2Ro Y2lfZnJlZV9ob3N0KGhvc3QpOw0KPiA+ICtlcnI6DQo+ID4gKyAgICAgICBkZXZfZXJyKCZwZGV2 LT5kZXYsICJwaWMzMi1zZGhjaSBwcm9iZSBmYWlsZWQ6ICVkXG4iLCByZXQpOw0KPiA+ICsgICAg ICAgcmV0dXJuIHJldDsNCj4gPiArfQ0KPiA+ICsNCj4gPiArc3RhdGljIGludCBwaWMzMl9zZGhj aV9yZW1vdmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikgew0KPiA+ICsgICAgICAgc3Ry dWN0IHNkaGNpX2hvc3QgKmhvc3QgPSBwbGF0Zm9ybV9nZXRfZHJ2ZGF0YShwZGV2KTsNCj4gPiAr ICAgICAgIHN0cnVjdCBwaWMzMl9zZGhjaV9wZGF0YSAqc2RoY2lfcGRhdGEgPSBzZGhjaV9wcml2 KGhvc3QpOw0KPiA+ICsgICAgICAgaW50IGRlYWQgPSAwOw0KPiA+ICsgICAgICAgdTMyIHNjcmF0 Y2g7DQo+ID4gKw0KPiA+ICsgICAgICAgc2NyYXRjaCA9IHJlYWRsKGhvc3QtPmlvYWRkciArIFNE SENJX0lOVF9TVEFUVVMpOw0KPiA+ICsgICAgICAgaWYgKHNjcmF0Y2ggPT0gKHUzMiktMSkNCj4g DQo+IFNpbmNlIGl0J3Mgbm90IGFjdHVhbGx5IHJlbGF0ZWQgdG8gc2lnbmVkLCAodTMyKX4wIG1p Z2h0IGJlIGNsZWFyZXIuDQoNCkFjay4NCg0KPiANCj4gPiArICAgICAgICAgICAgICAgZGVhZCA9 IDE7DQo+ID4gKw0KPiA+ICsgICAgICAgc2RoY2lfcmVtb3ZlX2hvc3QoaG9zdCwgZGVhZCk7DQo+ IA0KPiBZb3UgY291bGQgZ2V0IHJpZCBvZiAiZGVhZCIgYW5kIGhhdmUNCj4gDQo+ICAgICAgICAg IHNkaGNpX3JlbW92ZV9ob3N0KGhvc3QsIHNjcmF0Y2ggPT0gKHUzMil+MCk7DQoNCkFjay4gDQoN Cj4gDQo+ID4gKyAgICAgICBjbGtfZGlzYWJsZV91bnByZXBhcmUoc2RoY2lfcGRhdGEtPmJhc2Vf Y2xrKTsNCj4gPiArICAgICAgIGNsa19kaXNhYmxlX3VucHJlcGFyZShzZGhjaV9wZGF0YS0+c3lz X2Nsayk7DQo+ID4gKyAgICAgICBzZGhjaV9mcmVlX2hvc3QoaG9zdCk7DQo+ID4gKw0KPiA+ICsg ICAgICAgcmV0dXJuIDA7DQo+ID4gK30NCj4gPiArDQo+ID4gK3N0YXRpYyBjb25zdCBzdHJ1Y3Qg b2ZfZGV2aWNlX2lkIHBpYzMyX3NkaGNpX2lkX3RhYmxlW10gPSB7DQo+ID4gKyAgICAgICB7IC5j b21wYXRpYmxlID0gIm1pY3JvY2hpcCxwaWMzMm16ZGEtc2RoY2kiIH0sDQo+ID4gKyAgICAgICB7 fQ0KPiA+ICt9Ow0KPiA+ICtNT0RVTEVfREVWSUNFX1RBQkxFKG9mLCBwaWMzMl9zZGhjaV9pZF90 YWJsZSk7DQo+ID4gKw0KPiA+ICtzdGF0aWMgc3RydWN0IHBsYXRmb3JtX2RyaXZlciBwaWMzMl9z ZGhjaV9kcml2ZXIgPSB7DQo+ID4gKyAgICAgICAuZHJpdmVyID0gew0KPiA+ICsgICAgICAgICAg ICAgICAubmFtZSAgID0gREVWX05BTUUsDQo+ID4gKyAgICAgICAgICAgICAgIC5vd25lciAgPSBU SElTX01PRFVMRSwNCj4gPiArICAgICAgICAgICAgICAgLm9mX21hdGNoX3RhYmxlID0gb2ZfbWF0 Y2hfcHRyKHBpYzMyX3NkaGNpX2lkX3RhYmxlKSwNCj4gPiArICAgICAgIH0sDQo+ID4gKyAgICAg ICAucHJvYmUgICAgICAgICAgPSBwaWMzMl9zZGhjaV9wcm9iZSwNCj4gPiArICAgICAgIC5yZW1v dmUgICAgICAgICA9IHBpYzMyX3NkaGNpX3JlbW92ZSwNCj4gPiArfTsNCj4gPiArDQo+ID4gK21v ZHVsZV9wbGF0Zm9ybV9kcml2ZXIocGljMzJfc2RoY2lfZHJpdmVyKTsNCj4gPiArDQo+ID4gK01P RFVMRV9ERVNDUklQVElPTigiTWljcm9jaGlwIFBJQzMyIFNESENJIGRyaXZlciIpOw0KPiA+ICtN T0RVTEVfQVVUSE9SKCJQaXN0aXJpY2EgU29yaW4gQW5kcmVpICYgU2FuZGVlcCBTaGVyaWtlciIp Ow0KPiA+ICtNT0RVTEVfTElDRU5TRSgiR1BMIHYyIik7DQo+ID4gLS0NCj4gPiAxLjcuOS41DQo+ ID4NCg0KVGhhbmtzLA0KUGF1bA0K -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Ulf Hansson <ulf.hansson@linaro.org> |
|---|---|
| Date | 2015-12-16 11:50 +0100 |
| Subject | Re: [PATCH v2 12/14] mmc: sdhci-pic32: Add PIC32 SDHCI host controller driver |
| Message-ID | <qGhOF-De-3@gated-at.bofh.it> |
| In reply to | #1291661 |
[...]
> +static int pic32_sdhci_probe(struct platform_device *pdev)
> +{
> + struct device *dev = &pdev->dev;
> + struct sdhci_host *host;
> + struct resource *iomem;
> + struct pic32_sdhci_pdata *sdhci_pdata;
> + struct pic32_sdhci_platform_data *plat_data;
> + unsigned int clk_rate = 0;
> + int ret;
> + struct pinctrl *pinctrl;
> +
> + host = sdhci_alloc_host(dev, sizeof(*sdhci_pdata));
> + if (IS_ERR(host)) {
> + ret = PTR_ERR(host);
> + dev_err(&pdev->dev, "cannot allocate memory for sdhci\n");
> + goto err;
> + }
> +
> + sdhci_pdata = sdhci_priv(host);
> + sdhci_pdata->pdev = pdev;
> + platform_set_drvdata(pdev, host);
> +
> + iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + host->ioaddr = devm_ioremap_resource(&pdev->dev, iomem);
> + if (IS_ERR(host->ioaddr)) {
> + ret = PTR_ERR(host->ioaddr);
> + dev_err(&pdev->dev, "unable to map iomem: %d\n", ret);
> + goto err_host;
> + }
> +
> + plat_data = pdev->dev.platform_data;
> + if (plat_data && plat_data->setup_dma) {
> + ret = plat_data->setup_dma(ADMA_FIFO_RD_THSHLD,
> + ADMA_FIFO_WR_THSHLD);
> + if (ret)
> + goto err_host;
> + }
> +
> + pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
This isn't need as it's already handled by the PM core.
> + if (IS_ERR(pinctrl)) {
> + ret = PTR_ERR(pinctrl);
> + dev_warn(&pdev->dev, "No pinctrl provided %d\n", ret);
> + if (ret == -EPROBE_DEFER)
> + goto err_host;
> + }
> +
> + host->ops = &pic32_sdhci_ops;
> + host->irq = platform_get_irq(pdev, 0);
> +
> + sdhci_pdata->sys_clk = devm_clk_get(&pdev->dev, "sys_clk");
> + if (IS_ERR(sdhci_pdata->sys_clk)) {
> + ret = PTR_ERR(sdhci_pdata->sys_clk);
> + dev_err(&pdev->dev, "Error getting clock\n");
> + goto err_host;
> + }
> +
> + /* Enable clock when available! */
> + ret = clk_prepare_enable(sdhci_pdata->sys_clk);
> + if (ret) {
> + dev_dbg(&pdev->dev, "Error enabling clock\n");
> + goto err_host;
> + }
> +
> + /* SDH CLK enable */
> + sdhci_pdata->base_clk = devm_clk_get(&pdev->dev, "base_clk");
> + if (IS_ERR(sdhci_pdata->base_clk)) {
> + ret = PTR_ERR(sdhci_pdata->base_clk);
> + dev_err(&pdev->dev, "Error getting clock\n");
> + goto err_host;
> + }
> +
> + /* Enable clock when available! */
> + ret = clk_prepare_enable(sdhci_pdata->base_clk);
> + if (ret) {
> + dev_dbg(&pdev->dev, "Error enabling clock\n");
> + goto err_host;
> + }
> +
> + clk_rate = clk_get_rate(sdhci_pdata->base_clk);
> + dev_dbg(&pdev->dev, "base clock at: %u\n", clk_rate);
> + clk_rate = clk_get_rate(sdhci_pdata->sys_clk);
> + dev_dbg(&pdev->dev, "sys clock at: %u\n", clk_rate);
This looks like some leftover from a debugging task. Can you remove them?
> +
> + host->quirks2 |= SDHCI_QUIRK2_NO_1_8_V;
> +
> + host->quirks |= SDHCI_QUIRK_NO_HISPD_BIT;
> +
> + ret = mmc_of_parse(host->mmc);
> + if (ret)
From this point, the error handling doesn't undo clk_prepare_enable().
Please add that.
> + goto err_host;
> +
> + ret = pic32_sdhci_probe_platform(pdev, sdhci_pdata);
> + if (ret) {
> + dev_err(&pdev->dev, "failed to probe platform!\n");
> + goto err_host;
> + }
> +
> + ret = sdhci_add_host(host);
> + if (ret) {
> + dev_dbg(&pdev->dev, "error adding host\n");
> + goto err_host;
> + }
> +
> + dev_info(&pdev->dev, "Successfully added sdhci host\n");
> + return 0;
> +
> +err_host:
> + sdhci_free_host(host);
> +err:
> + dev_err(&pdev->dev, "pic32-sdhci probe failed: %d\n", ret);
> + return ret;
A general comment for the ->probe() and the below ->remove() callback,
is that you should probably be able to convert to use
sdhci_pltfm_init() and sdhci_pltfm_free() in favor of
sdhci_alloc_host() and sdhci_free_host().
I think that could simplify the code a bit.
> +}
> +
> +static int pic32_sdhci_remove(struct platform_device *pdev)
> +{
> + struct sdhci_host *host = platform_get_drvdata(pdev);
> + struct pic32_sdhci_pdata *sdhci_pdata = sdhci_priv(host);
> + int dead = 0;
> + u32 scratch;
> +
> + scratch = readl(host->ioaddr + SDHCI_INT_STATUS);
> + if (scratch == (u32)-1)
> + dead = 1;
> +
> + sdhci_remove_host(host, dead);
> + clk_disable_unprepare(sdhci_pdata->base_clk);
> + clk_disable_unprepare(sdhci_pdata->sys_clk);
> + sdhci_free_host(host);
> +
> + return 0;
> +}
> +
> +static const struct of_device_id pic32_sdhci_id_table[] = {
> + { .compatible = "microchip,pic32mzda-sdhci" },
> + {}
> +};
> +MODULE_DEVICE_TABLE(of, pic32_sdhci_id_table);
> +
> +static struct platform_driver pic32_sdhci_driver = {
> + .driver = {
> + .name = DEV_NAME,
> + .owner = THIS_MODULE,
> + .of_match_table = of_match_ptr(pic32_sdhci_id_table),
> + },
> + .probe = pic32_sdhci_probe,
> + .remove = pic32_sdhci_remove,
> +};
> +
> +module_platform_driver(pic32_sdhci_driver);
> +
> +MODULE_DESCRIPTION("Microchip PIC32 SDHCI driver");
> +MODULE_AUTHOR("Pistirica Sorin Andrei & Sandeep Sheriker");
> +MODULE_LICENSE("GPL v2");
> --
> 1.7.9.5
>
Kind regards
Uffe
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | <Paul.Thacker@microchip.com> |
|---|---|
| Date | 2015-12-17 19:10 +0100 |
| Subject | RE: [PATCH v2 12/14] mmc: sdhci-pic32: Add PIC32 SDHCI host controller driver |
| Message-ID | <qGLa2-2TY-13@gated-at.bofh.it> |
| In reply to | #1292885 |
T24gMTIvMTYvMjAxNSAzOjQ4IEFNLCBVbGYgSGFuc3NvbiB3cm90ZToNCj4gDQo+IFsuLi5dDQo+ IA0KPiA+ICtzdGF0aWMgaW50IHBpYzMyX3NkaGNpX3Byb2JlKHN0cnVjdCBwbGF0Zm9ybV9kZXZp Y2UgKnBkZXYpIHsNCj4gPiArICAgICAgIHN0cnVjdCBkZXZpY2UgKmRldiA9ICZwZGV2LT5kZXY7 DQo+ID4gKyAgICAgICBzdHJ1Y3Qgc2RoY2lfaG9zdCAqaG9zdDsNCj4gPiArICAgICAgIHN0cnVj dCByZXNvdXJjZSAqaW9tZW07DQo+ID4gKyAgICAgICBzdHJ1Y3QgcGljMzJfc2RoY2lfcGRhdGEg KnNkaGNpX3BkYXRhOw0KPiA+ICsgICAgICAgc3RydWN0IHBpYzMyX3NkaGNpX3BsYXRmb3JtX2Rh dGEgKnBsYXRfZGF0YTsNCj4gPiArICAgICAgIHVuc2lnbmVkIGludCBjbGtfcmF0ZSA9IDA7DQo+ ID4gKyAgICAgICBpbnQgcmV0Ow0KPiA+ICsgICAgICAgc3RydWN0IHBpbmN0cmwgKnBpbmN0cmw7 DQo+ID4gKw0KPiA+ICsgICAgICAgaG9zdCA9IHNkaGNpX2FsbG9jX2hvc3QoZGV2LCBzaXplb2Yo KnNkaGNpX3BkYXRhKSk7DQo+ID4gKyAgICAgICBpZiAoSVNfRVJSKGhvc3QpKSB7DQo+ID4gKyAg ICAgICAgICAgICAgIHJldCA9IFBUUl9FUlIoaG9zdCk7DQo+ID4gKyAgICAgICAgICAgICAgIGRl dl9lcnIoJnBkZXYtPmRldiwgImNhbm5vdCBhbGxvY2F0ZSBtZW1vcnkgZm9yIHNkaGNpXG4iKTsN Cj4gPiArICAgICAgICAgICAgICAgZ290byBlcnI7DQo+ID4gKyAgICAgICB9DQo+ID4gKw0KPiA+ ICsgICAgICAgc2RoY2lfcGRhdGEgPSBzZGhjaV9wcml2KGhvc3QpOw0KPiA+ICsgICAgICAgc2Ro Y2lfcGRhdGEtPnBkZXYgPSBwZGV2Ow0KPiA+ICsgICAgICAgcGxhdGZvcm1fc2V0X2RydmRhdGEo cGRldiwgaG9zdCk7DQo+ID4gKw0KPiA+ICsgICAgICAgaW9tZW0gPSBwbGF0Zm9ybV9nZXRfcmVz b3VyY2UocGRldiwgSU9SRVNPVVJDRV9NRU0sIDApOw0KPiA+ICsgICAgICAgaG9zdC0+aW9hZGRy ID0gZGV2bV9pb3JlbWFwX3Jlc291cmNlKCZwZGV2LT5kZXYsIGlvbWVtKTsNCj4gPiArICAgICAg IGlmIChJU19FUlIoaG9zdC0+aW9hZGRyKSkgew0KPiA+ICsgICAgICAgICAgICAgICByZXQgPSBQ VFJfRVJSKGhvc3QtPmlvYWRkcik7DQo+ID4gKyAgICAgICAgICAgICAgIGRldl9lcnIoJnBkZXYt PmRldiwgInVuYWJsZSB0byBtYXAgaW9tZW06ICVkXG4iLCByZXQpOw0KPiA+ICsgICAgICAgICAg ICAgICBnb3RvIGVycl9ob3N0Ow0KPiA+ICsgICAgICAgfQ0KPiA+ICsNCj4gPiArICAgICAgIHBs YXRfZGF0YSA9IHBkZXYtPmRldi5wbGF0Zm9ybV9kYXRhOw0KPiA+ICsgICAgICAgaWYgKHBsYXRf ZGF0YSAmJiBwbGF0X2RhdGEtPnNldHVwX2RtYSkgew0KPiA+ICsgICAgICAgICAgICAgICByZXQg PSBwbGF0X2RhdGEtPnNldHVwX2RtYShBRE1BX0ZJRk9fUkRfVEhTSExELA0KPiA+ICsgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBRE1BX0ZJRk9fV1JfVEhTSExEKTsN Cj4gPiArICAgICAgICAgICAgICAgaWYgKHJldCkNCj4gPiArICAgICAgICAgICAgICAgICAgICAg ICBnb3RvIGVycl9ob3N0Ow0KPiA+ICsgICAgICAgfQ0KPiA+ICsNCj4gPiArICAgICAgIHBpbmN0 cmwgPSBkZXZtX3BpbmN0cmxfZ2V0X3NlbGVjdF9kZWZhdWx0KCZwZGV2LT5kZXYpOw0KPiANCj4g VGhpcyBpc24ndCBuZWVkIGFzIGl0J3MgYWxyZWFkeSBoYW5kbGVkIGJ5IHRoZSBQTSBjb3JlLg0K DQpBY2suIFdpbGwgcmVtb3ZlLg0KDQo+IA0KPiA+ICsgICAgICAgaWYgKElTX0VSUihwaW5jdHJs KSkgew0KPiA+ICsgICAgICAgICAgICAgICByZXQgPSBQVFJfRVJSKHBpbmN0cmwpOw0KPiA+ICsg ICAgICAgICAgICAgICBkZXZfd2FybigmcGRldi0+ZGV2LCAiTm8gcGluY3RybCBwcm92aWRlZCAl ZFxuIiwgcmV0KTsNCj4gPiArICAgICAgICAgICAgICAgaWYgKHJldCA9PSAtRVBST0JFX0RFRkVS KQ0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgIGdvdG8gZXJyX2hvc3Q7DQo+ID4gKyAgICAg ICB9DQo+ID4gKw0KPiA+ICsgICAgICAgaG9zdC0+b3BzID0gJnBpYzMyX3NkaGNpX29wczsNCj4g PiArICAgICAgIGhvc3QtPmlycSA9IHBsYXRmb3JtX2dldF9pcnEocGRldiwgMCk7DQo+ID4gKw0K PiA+ICsgICAgICAgc2RoY2lfcGRhdGEtPnN5c19jbGsgPSBkZXZtX2Nsa19nZXQoJnBkZXYtPmRl diwgInN5c19jbGsiKTsNCj4gPiArICAgICAgIGlmIChJU19FUlIoc2RoY2lfcGRhdGEtPnN5c19j bGspKSB7DQo+ID4gKyAgICAgICAgICAgICAgIHJldCA9IFBUUl9FUlIoc2RoY2lfcGRhdGEtPnN5 c19jbGspOw0KPiA+ICsgICAgICAgICAgICAgICBkZXZfZXJyKCZwZGV2LT5kZXYsICJFcnJvciBn ZXR0aW5nIGNsb2NrXG4iKTsNCj4gPiArICAgICAgICAgICAgICAgZ290byBlcnJfaG9zdDsNCj4g PiArICAgICAgIH0NCj4gPiArDQo+ID4gKyAgICAgICAvKiBFbmFibGUgY2xvY2sgd2hlbiBhdmFp bGFibGUhICovDQo+ID4gKyAgICAgICByZXQgPSBjbGtfcHJlcGFyZV9lbmFibGUoc2RoY2lfcGRh dGEtPnN5c19jbGspOw0KPiA+ICsgICAgICAgaWYgKHJldCkgew0KPiA+ICsgICAgICAgICAgICAg ICBkZXZfZGJnKCZwZGV2LT5kZXYsICJFcnJvciBlbmFibGluZyBjbG9ja1xuIik7DQo+ID4gKyAg ICAgICAgICAgICAgIGdvdG8gZXJyX2hvc3Q7DQo+ID4gKyAgICAgICB9DQo+ID4gKw0KPiA+ICsg ICAgICAgLyogU0RIIENMSyBlbmFibGUgKi8NCj4gPiArICAgICAgIHNkaGNpX3BkYXRhLT5iYXNl X2NsayA9IGRldm1fY2xrX2dldCgmcGRldi0+ZGV2LCAiYmFzZV9jbGsiKTsNCj4gPiArICAgICAg IGlmIChJU19FUlIoc2RoY2lfcGRhdGEtPmJhc2VfY2xrKSkgew0KPiA+ICsgICAgICAgICAgICAg ICByZXQgPSBQVFJfRVJSKHNkaGNpX3BkYXRhLT5iYXNlX2Nsayk7DQo+ID4gKyAgICAgICAgICAg ICAgIGRldl9lcnIoJnBkZXYtPmRldiwgIkVycm9yIGdldHRpbmcgY2xvY2tcbiIpOw0KPiA+ICsg ICAgICAgICAgICAgICBnb3RvIGVycl9ob3N0Ow0KPiA+ICsgICAgICAgfQ0KPiA+ICsNCj4gPiAr ICAgICAgIC8qIEVuYWJsZSBjbG9jayB3aGVuIGF2YWlsYWJsZSEgKi8NCj4gPiArICAgICAgIHJl dCA9IGNsa19wcmVwYXJlX2VuYWJsZShzZGhjaV9wZGF0YS0+YmFzZV9jbGspOw0KPiA+ICsgICAg ICAgaWYgKHJldCkgew0KPiA+ICsgICAgICAgICAgICAgICBkZXZfZGJnKCZwZGV2LT5kZXYsICJF cnJvciBlbmFibGluZyBjbG9ja1xuIik7DQo+ID4gKyAgICAgICAgICAgICAgIGdvdG8gZXJyX2hv c3Q7DQo+ID4gKyAgICAgICB9DQo+ID4gKw0KPiA+ICsgICAgICAgY2xrX3JhdGUgPSBjbGtfZ2V0 X3JhdGUoc2RoY2lfcGRhdGEtPmJhc2VfY2xrKTsNCj4gPiArICAgICAgIGRldl9kYmcoJnBkZXYt PmRldiwgImJhc2UgY2xvY2sgYXQ6ICV1XG4iLCBjbGtfcmF0ZSk7DQo+ID4gKyAgICAgICBjbGtf cmF0ZSA9IGNsa19nZXRfcmF0ZShzZGhjaV9wZGF0YS0+c3lzX2Nsayk7DQo+ID4gKyAgICAgICBk ZXZfZGJnKCZwZGV2LT5kZXYsICJzeXMgY2xvY2sgYXQ6ICV1XG4iLCBjbGtfcmF0ZSk7DQo+IA0K PiBUaGlzIGxvb2tzIGxpa2Ugc29tZSBsZWZ0b3ZlciBmcm9tIGEgZGVidWdnaW5nIHRhc2suIENh biB5b3UgcmVtb3ZlIHRoZW0/DQo+IA0KDQpZZXMsIHRoZXNlIGFyZSBub3QgbmVlZGVkIGFuZCB3 aWxsIGJlIHJlbW92ZWQuDQoNCj4gPiArDQo+ID4gKyAgICAgICBob3N0LT5xdWlya3MyIHw9IFNE SENJX1FVSVJLMl9OT18xXzhfVjsNCj4gPiArDQo+ID4gKyAgICAgICBob3N0LT5xdWlya3MgfD0g U0RIQ0lfUVVJUktfTk9fSElTUERfQklUOw0KPiA+ICsNCj4gPiArICAgICAgIHJldCA9IG1tY19v Zl9wYXJzZShob3N0LT5tbWMpOw0KPiA+ICsgICAgICAgaWYgKHJldCkNCj4gDQo+IEZyb20gdGhp cyBwb2ludCwgdGhlIGVycm9yIGhhbmRsaW5nIGRvZXNuJ3QgdW5kbyBjbGtfcHJlcGFyZV9lbmFi bGUoKS4NCj4gUGxlYXNlIGFkZCB0aGF0Lg0KDQpBY2suIFdpbGwgZG8uDQoNCj4gDQo+ID4gKyAg ICAgICAgICAgICAgIGdvdG8gZXJyX2hvc3Q7DQo+ID4gKw0KPiA+ICsgICAgICAgcmV0ID0gcGlj MzJfc2RoY2lfcHJvYmVfcGxhdGZvcm0ocGRldiwgc2RoY2lfcGRhdGEpOw0KPiA+ICsgICAgICAg aWYgKHJldCkgew0KPiA+ICsgICAgICAgICAgICAgICBkZXZfZXJyKCZwZGV2LT5kZXYsICJmYWls ZWQgdG8gcHJvYmUgcGxhdGZvcm0hXG4iKTsNCj4gPiArICAgICAgICAgICAgICAgZ290byBlcnJf aG9zdDsNCj4gPiArICAgICAgIH0NCj4gPiArDQo+ID4gKyAgICAgICByZXQgPSBzZGhjaV9hZGRf aG9zdChob3N0KTsNCj4gPiArICAgICAgIGlmIChyZXQpIHsNCj4gPiArICAgICAgICAgICAgICAg ZGV2X2RiZygmcGRldi0+ZGV2LCAiZXJyb3IgYWRkaW5nIGhvc3RcbiIpOw0KPiA+ICsgICAgICAg ICAgICAgICBnb3RvIGVycl9ob3N0Ow0KPiA+ICsgICAgICAgfQ0KPiA+ICsNCj4gPiArICAgICAg IGRldl9pbmZvKCZwZGV2LT5kZXYsICJTdWNjZXNzZnVsbHkgYWRkZWQgc2RoY2kgaG9zdFxuIik7 DQo+ID4gKyAgICAgICByZXR1cm4gMDsNCj4gPiArDQo+ID4gK2Vycl9ob3N0Og0KPiA+ICsgICAg ICAgc2RoY2lfZnJlZV9ob3N0KGhvc3QpOw0KPiA+ICtlcnI6DQo+ID4gKyAgICAgICBkZXZfZXJy KCZwZGV2LT5kZXYsICJwaWMzMi1zZGhjaSBwcm9iZSBmYWlsZWQ6ICVkXG4iLCByZXQpOw0KPiA+ ICsgICAgICAgcmV0dXJuIHJldDsNCj4gDQo+IEEgZ2VuZXJhbCBjb21tZW50IGZvciB0aGUgLT5w cm9iZSgpIGFuZCB0aGUgYmVsb3cgLT5yZW1vdmUoKSBjYWxsYmFjaywgaXMgdGhhdA0KPiB5b3Ug c2hvdWxkIHByb2JhYmx5IGJlIGFibGUgdG8gY29udmVydCB0byB1c2UNCj4gc2RoY2lfcGx0Zm1f aW5pdCgpIGFuZCBzZGhjaV9wbHRmbV9mcmVlKCkgaW4gZmF2b3Igb2YNCj4gc2RoY2lfYWxsb2Nf aG9zdCgpIGFuZCBzZGhjaV9mcmVlX2hvc3QoKS4NCj4gDQo+IEkgdGhpbmsgdGhhdCBjb3VsZCBz aW1wbGlmeSB0aGUgY29kZSBhIGJpdC4NCg0KT2suIFdpbGwgZG8uDQoNCj4gDQo+ID4gK30NCj4g PiArDQo+ID4gK3N0YXRpYyBpbnQgcGljMzJfc2RoY2lfcmVtb3ZlKHN0cnVjdCBwbGF0Zm9ybV9k ZXZpY2UgKnBkZXYpIHsNCj4gPiArICAgICAgIHN0cnVjdCBzZGhjaV9ob3N0ICpob3N0ID0gcGxh dGZvcm1fZ2V0X2RydmRhdGEocGRldik7DQo+ID4gKyAgICAgICBzdHJ1Y3QgcGljMzJfc2RoY2lf cGRhdGEgKnNkaGNpX3BkYXRhID0gc2RoY2lfcHJpdihob3N0KTsNCj4gPiArICAgICAgIGludCBk ZWFkID0gMDsNCj4gPiArICAgICAgIHUzMiBzY3JhdGNoOw0KPiA+ICsNCj4gPiArICAgICAgIHNj cmF0Y2ggPSByZWFkbChob3N0LT5pb2FkZHIgKyBTREhDSV9JTlRfU1RBVFVTKTsNCj4gPiArICAg ICAgIGlmIChzY3JhdGNoID09ICh1MzIpLTEpDQo+ID4gKyAgICAgICAgICAgICAgIGRlYWQgPSAx Ow0KPiA+ICsNCj4gPiArICAgICAgIHNkaGNpX3JlbW92ZV9ob3N0KGhvc3QsIGRlYWQpOw0KPiA+ ICsgICAgICAgY2xrX2Rpc2FibGVfdW5wcmVwYXJlKHNkaGNpX3BkYXRhLT5iYXNlX2Nsayk7DQo+ ID4gKyAgICAgICBjbGtfZGlzYWJsZV91bnByZXBhcmUoc2RoY2lfcGRhdGEtPnN5c19jbGspOw0K PiA+ICsgICAgICAgc2RoY2lfZnJlZV9ob3N0KGhvc3QpOw0KPiA+ICsNCj4gPiArICAgICAgIHJl dHVybiAwOw0KPiA+ICt9DQo+ID4gKw0KPiA+ICtzdGF0aWMgY29uc3Qgc3RydWN0IG9mX2Rldmlj ZV9pZCBwaWMzMl9zZGhjaV9pZF90YWJsZVtdID0gew0KPiA+ICsgICAgICAgeyAuY29tcGF0aWJs ZSA9ICJtaWNyb2NoaXAscGljMzJtemRhLXNkaGNpIiB9LA0KPiA+ICsgICAgICAge30NCj4gPiAr fTsNCj4gPiArTU9EVUxFX0RFVklDRV9UQUJMRShvZiwgcGljMzJfc2RoY2lfaWRfdGFibGUpOw0K PiA+ICsNCj4gPiArc3RhdGljIHN0cnVjdCBwbGF0Zm9ybV9kcml2ZXIgcGljMzJfc2RoY2lfZHJp dmVyID0gew0KPiA+ICsgICAgICAgLmRyaXZlciA9IHsNCj4gPiArICAgICAgICAgICAgICAgLm5h bWUgICA9IERFVl9OQU1FLA0KPiA+ICsgICAgICAgICAgICAgICAub3duZXIgID0gVEhJU19NT0RV TEUsDQo+ID4gKyAgICAgICAgICAgICAgIC5vZl9tYXRjaF90YWJsZSA9IG9mX21hdGNoX3B0cihw aWMzMl9zZGhjaV9pZF90YWJsZSksDQo+ID4gKyAgICAgICB9LA0KPiA+ICsgICAgICAgLnByb2Jl ICAgICAgICAgID0gcGljMzJfc2RoY2lfcHJvYmUsDQo+ID4gKyAgICAgICAucmVtb3ZlICAgICAg ICAgPSBwaWMzMl9zZGhjaV9yZW1vdmUsDQo+ID4gK307DQo+ID4gKw0KPiA+ICttb2R1bGVfcGxh dGZvcm1fZHJpdmVyKHBpYzMyX3NkaGNpX2RyaXZlcik7DQo+ID4gKw0KPiA+ICtNT0RVTEVfREVT Q1JJUFRJT04oIk1pY3JvY2hpcCBQSUMzMiBTREhDSSBkcml2ZXIiKTsNCj4gPiArTU9EVUxFX0FV VEhPUigiUGlzdGlyaWNhIFNvcmluIEFuZHJlaSAmIFNhbmRlZXAgU2hlcmlrZXIiKTsNCj4gPiAr TU9EVUxFX0xJQ0VOU0UoIkdQTCB2MiIpOw0KPiA+IC0tDQo+ID4gMS43LjkuNQ0KDQpUaGFua3Ms DQpQYXVsDQo= -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Joshua Henderson <joshua.henderson@microchip.com> |
|---|---|
| Date | 2015-12-14 23:50 +0100 |
| Subject | [PATCH v2 10/14] serial: pic32_uart: Add PIC32 UART driver |
| Message-ID | <qFK6n-3W4-35@gated-at.bofh.it> |
| In reply to | #1291644 |
From: Andrei Pistirica <andrei.pistirica@microchip.com>
This adds UART and a serial console driver for Microchip PIC32 class
devices.
Signed-off-by: Andrei Pistirica <andrei.pistirica@microchip.com>
Signed-off-by: Joshua Henderson <joshua.henderson@microchip.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
---
drivers/tty/serial/Kconfig | 21 +
drivers/tty/serial/Makefile | 1 +
drivers/tty/serial/pic32_uart.c | 927 ++++++++++++++++++++++++++++++++++++++
drivers/tty/serial/pic32_uart.h | 198 ++++++++
include/uapi/linux/serial_core.h | 3 +
5 files changed, 1150 insertions(+)
create mode 100644 drivers/tty/serial/pic32_uart.c
create mode 100644 drivers/tty/serial/pic32_uart.h
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index f38beb2..8853b1e 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -901,6 +901,27 @@ config SERIAL_SGI_L1_CONSOLE
controller serial port as your console (you want this!),
say Y. Otherwise, say N.
+config SERIAL_PIC32
+ tristate "Microchip PIC32 serial support"
+ depends on MACH_PIC32
+ select SERIAL_CORE
+ help
+ If you have a PIC32, this driver supports the serial ports.
+
+ Say Y or M to use PIC32 serial ports, otherwise say N. Note that
+ to use a serial port as a console, this must be included in kernel and
+ not as a module.
+
+config SERIAL_PIC32_CONSOLE
+ bool "PIC32 serial console support"
+ depends on SERIAL_PIC32
+ select SERIAL_CORE_CONSOLE
+ help
+ If you have a PIC32, this driver supports the putting a console on one
+ of the serial ports.
+
+ Say Y to use the PIC32 console, otherwise say N.
+
config SERIAL_MPC52xx
tristate "Freescale MPC52xx/MPC512x family PSC serial support"
depends on PPC_MPC52xx || PPC_MPC512x
diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile
index 5ab4111..bc5e354 100644
--- a/drivers/tty/serial/Makefile
+++ b/drivers/tty/serial/Makefile
@@ -93,6 +93,7 @@ obj-$(CONFIG_SERIAL_CONEXANT_DIGICOLOR) += digicolor-usart.o
obj-$(CONFIG_SERIAL_MEN_Z135) += men_z135_uart.o
obj-$(CONFIG_SERIAL_SPRD) += sprd_serial.o
obj-$(CONFIG_SERIAL_STM32) += stm32-usart.o
+obj-$(CONFIG_SERIAL_PIC32) += pic32_uart.o
# GPIOLIB helpers for modem control lines
obj-$(CONFIG_SERIAL_MCTRL_GPIO) += serial_mctrl_gpio.o
diff --git a/drivers/tty/serial/pic32_uart.c b/drivers/tty/serial/pic32_uart.c
new file mode 100644
index 0000000..5c05c11
--- /dev/null
+++ b/drivers/tty/serial/pic32_uart.c
@@ -0,0 +1,927 @@
+/*
+ * PIC32 Integrated Serial Driver.
+ *
+ * Copyright (C) 2015 Microchip Technology, Inc.
+ *
+ * Authors:
+ * Steve Scott <steve.scott@microchip.com>,
+ * Sorin-Andrei Pistirica <andrei.pistirica@microchip.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
+#include <linux/of_gpio.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/console.h>
+#include <linux/clk-provider.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/sysrq.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+#include <uapi/linux/serial_core.h>
+#include <linux/delay.h>
+
+#include "pic32_uart.h"
+
+/* UART name and device definitions */
+#define PIC32_DEV_NAME "pic32-uart"
+#define PIC32_MAX_UARTS 6
+
+#define PIC32_SDEV_NAME "ttyS"
+#define PIC32_SDEV_MAJOR TTY_MAJOR
+#define PIC32_SDEV_MINOR 64
+
+/* pic32_sport pointer for console use */
+static struct pic32_sport *pic32_sports[PIC32_MAX_UARTS];
+
+static inline int pic32_enable_clock(struct pic32_sport *sport)
+{
+ sport->ref_clk++;
+
+ return clk_prepare_enable(sport->clk);
+}
+
+static inline void pic32_disable_clock(struct pic32_sport *sport)
+{
+ sport->ref_clk--;
+ clk_disable_unprepare(sport->clk);
+}
+
+/* serial core request to check if uart tx buffer is empty */
+static unsigned int pic32_uart_tx_empty(struct uart_port *port)
+{
+ struct pic32_sport *sport = to_pic32_sport(port);
+ u32 val = pic32_uart_read(sport, PIC32_UART_STA);
+
+ return (val & PIC32_UART_STA_TRMT) ? 1 : 0;
+}
+
+/* serial core request to set UART outputs */
+static void pic32_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+ struct pic32_sport *sport = to_pic32_sport(port);
+
+ /* set loopback mode */
+ if (mctrl & TIOCM_LOOP)
+ pic32_uart_rset(PIC32_UART_MODE_LPBK, sport, PIC32_UART_MODE);
+ else
+ pic32_uart_rclr(PIC32_UART_MODE_LPBK, sport, PIC32_UART_MODE);
+}
+
+/* get the state of CTS input pin for this port */
+static unsigned int get_cts_state(struct pic32_sport *sport)
+{
+ /* default state must be asserted */
+ int val = 1;
+
+ /* read and invert UxCTS */
+ if (gpio_is_valid(sport->cts_gpio))
+ val = !gpio_get_value(sport->cts_gpio);
+
+ return val;
+}
+
+/* serial core request to return the state of misc UART input pins */
+static unsigned int pic32_uart_get_mctrl(struct uart_port *port)
+{
+ struct pic32_sport *sport = to_pic32_sport(port);
+ unsigned int mctrl = 0;
+
+ if (!sport->hw_flow_ctrl) {
+ mctrl |= TIOCM_CTS;
+ goto ret;
+ }
+
+ if (get_cts_state(sport))
+ mctrl |= TIOCM_CTS;
+
+ret:
+ /* DSR and CD are not supported in PIC32, so return 1
+ * RI is not supported in PIC32, so return 0
+ */
+ mctrl |= TIOCM_CD;
+ mctrl |= TIOCM_DSR;
+
+ return mctrl;
+}
+
+/* stop tx and start tx are not called in pairs, therefore a flag indicates
+ * the status of irq to control the irq-depth.
+ */
+static inline void pic32_uart_irqtxen(struct pic32_sport *sport, u8 en)
+{
+ if (en && !tx_irq_enabled(sport)) {
+ enable_irq(sport->irq_tx);
+ tx_irq_enabled(sport) = 1;
+ } else if (!en && tx_irq_enabled(sport)) {
+ /* use disable_irq_nosync() and not disable_irq() to avoid self
+ * imposed deadlock by not waiting for irq handler to end,
+ * since this callback is called from interrupt context.
+ */
+ disable_irq_nosync(sport->irq_tx);
+ tx_irq_enabled(sport) = 0;
+ }
+}
+
+/* serial core request to disable tx ASAP (used for flow control) */
+static void pic32_uart_stop_tx(struct uart_port *port)
+{
+ struct pic32_sport *sport = to_pic32_sport(port);
+
+ if (!(pic32_uart_read(sport, PIC32_UART_MODE) & PIC32_UART_MODE_ON))
+ return;
+
+ if (!(pic32_uart_read(sport, PIC32_UART_STA) & PIC32_UART_STA_UTXEN))
+ return;
+
+ /* wait for tx empty */
+ while (!(pic32_uart_read(sport, PIC32_UART_STA) & PIC32_UART_STA_TRMT))
+ udelay(1);
+
+ pic32_uart_rclr(PIC32_UART_STA_UTXEN, sport, PIC32_UART_STA);
+ pic32_uart_irqtxen(sport, 0);
+}
+
+/* serial core request to (re)enable tx */
+static void pic32_uart_start_tx(struct uart_port *port)
+{
+ struct pic32_sport *sport = to_pic32_sport(port);
+
+ pic32_uart_irqtxen(sport, 1);
+ pic32_uart_rset(PIC32_UART_STA_UTXEN, sport, PIC32_UART_STA);
+}
+
+/* serial core request to stop rx, called before port shutdown */
+static void pic32_uart_stop_rx(struct uart_port *port)
+{
+ struct pic32_sport *sport = to_pic32_sport(port);
+
+ /* disable rx interrupts */
+ disable_irq(sport->irq_rx);
+
+ /* receiver Enable bit OFF */
+ pic32_uart_rclr(PIC32_UART_STA_URXEN, sport, PIC32_UART_STA);
+}
+
+/* serial core request to start/stop emitting break char */
+static void pic32_uart_break_ctl(struct uart_port *port, int ctl)
+{
+ struct pic32_sport *sport = to_pic32_sport(port);
+ unsigned long flags = 0;
+
+ spin_lock_irqsave(&port->lock, flags);
+
+ if (ctl)
+ pic32_uart_rset(PIC32_UART_STA_UTXBRK, sport, PIC32_UART_STA);
+ else
+ pic32_uart_rclr(PIC32_UART_STA_UTXBRK, sport, PIC32_UART_STA);
+
+ spin_unlock_irqrestore(&port->lock, flags);
+}
+
+/* get port type in string format */
+static const char *pic32_uart_type(struct uart_port *port)
+{
+ return (port->type == PORT_PIC32) ? PIC32_DEV_NAME : NULL;
+}
+
+/* read all chars in rx fifo and send them to core */
+static void pic32_uart_do_rx(struct uart_port *port)
+{
+ struct pic32_sport *sport = to_pic32_sport(port);
+ struct tty_port *tty;
+ unsigned int max_count;
+
+ /* limit number of char read in interrupt, should not be
+ * higher than fifo size anyway since we're much faster than
+ * serial port
+ */
+ max_count = PIC32_UART_RX_FIFO_DEPTH;
+
+ spin_lock(&port->lock);
+
+ tty = &port->state->port;
+
+ do {
+ u32 sta_reg, c;
+ char flag;
+
+ /* get overrun/fifo empty information from status register */
+ sta_reg = pic32_uart_read(sport, PIC32_UART_STA);
+ if (unlikely(sta_reg & PIC32_UART_STA_OERR)) {
+
+ /* fifo reset is required to clear interrupt */
+ pic32_uart_rclr(PIC32_UART_STA_OERR, sport,
+ PIC32_UART_STA);
+
+ port->icount.overrun++;
+ tty_insert_flip_char(tty, 0, TTY_OVERRUN);
+ }
+
+ /* Can at least one more character can be read? */
+ if (!(sta_reg & PIC32_UART_STA_URXDA))
+ break;
+
+ /* read the character and increment the rx counter */
+ c = pic32_uart_read(sport, PIC32_UART_RX);
+
+ port->icount.rx++;
+ flag = TTY_NORMAL;
+ c &= 0xff;
+
+ if (unlikely((sta_reg & PIC32_UART_STA_PERR) ||
+ (sta_reg & PIC32_UART_STA_FERR))) {
+
+ /* do stats first */
+ if (sta_reg & PIC32_UART_STA_PERR)
+ port->icount.parity++;
+ if (sta_reg & PIC32_UART_STA_FERR)
+ port->icount.frame++;
+
+ /* update flag wrt read_status_mask */
+ sta_reg &= port->read_status_mask;
+
+ if (sta_reg & PIC32_UART_STA_FERR)
+ flag = TTY_FRAME;
+ if (sta_reg & PIC32_UART_STA_PERR)
+ flag = TTY_PARITY;
+ }
+
+ if (uart_handle_sysrq_char(port, c))
+ continue;
+
+ if ((sta_reg & port->ignore_status_mask) == 0)
+ tty_insert_flip_char(tty, c, flag);
+
+ } while (--max_count);
+
+ spin_unlock(&port->lock);
+
+ tty_flip_buffer_push(tty);
+}
+
+/* fill tx fifo with chars to send, stop when fifo is about to be full
+ * or when all chars have been sent.
+ */
+static void pic32_uart_do_tx(struct uart_port *port)
+{
+ struct pic32_sport *sport = to_pic32_sport(port);
+ struct circ_buf *xmit = &port->state->xmit;
+ unsigned int max_count = PIC32_UART_TX_FIFO_DEPTH;
+
+ if (port->x_char) {
+ pic32_uart_write(port->x_char, sport, PIC32_UART_TX);
+ port->icount.tx++;
+ port->x_char = 0;
+ return;
+ }
+
+ if (uart_tx_stopped(port)) {
+ pic32_uart_stop_tx(port);
+ return;
+ }
+
+ if (uart_circ_empty(xmit))
+ goto txq_empty;
+
+ /* keep stuffing chars into uart tx buffer
+ * 1) until uart fifo is full
+ * or
+ * 2) until the circ buffer is empty
+ * (all chars have been sent)
+ * or
+ * 3) until the max count is reached
+ * (prevents lingering here for too long in certain cases)
+ */
+ while (!(PIC32_UART_STA_UTXBF &
+ pic32_uart_rval(sport, PIC32_UART_STA))) {
+ unsigned int c = xmit->buf[xmit->tail];
+
+ pic32_uart_write(c, sport, PIC32_UART_TX);
+
+ xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+ port->icount.tx++;
+ --max_count;
+ if (uart_circ_empty(xmit))
+ break;
+ if (max_count == 0)
+ break;
+ }
+
+ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+ uart_write_wakeup(port);
+
+ if (uart_circ_empty(xmit))
+ goto txq_empty;
+
+ return;
+
+txq_empty:
+ pic32_uart_irqtxen(sport, 0);
+}
+
+/* RX interrupt handler */
+static irqreturn_t pic32_uart_rx_interrupt(int irq, void *dev_id)
+{
+ struct uart_port *port = dev_id;
+
+ pic32_uart_do_rx(port);
+
+ return IRQ_HANDLED;
+}
+
+/* TX interrupt handler */
+static irqreturn_t pic32_uart_tx_interrupt(int irq, void *dev_id)
+{
+ struct uart_port *port = dev_id;
+ unsigned long flags;
+
+ spin_lock_irqsave(&port->lock, flags);
+ pic32_uart_do_tx(port);
+ spin_unlock_irqrestore(&port->lock, flags);
+
+ return IRQ_HANDLED;
+}
+
+/* FAULT interrupt handler */
+static irqreturn_t pic32_uart_fault_interrupt(int irq, void *dev_id)
+{
+ /* do nothing: pic32_uart_do_rx() handles faults. */
+ return IRQ_HANDLED;
+}
+
+/* enable rx & tx operation on uart */
+static void pic32_uart_en_and_unmask(struct uart_port *port)
+{
+ struct pic32_sport *sport = to_pic32_sport(port);
+
+ pic32_uart_rset(PIC32_UART_STA_UTXEN | PIC32_UART_STA_URXEN,
+ sport, PIC32_UART_STA);
+ pic32_uart_rset(PIC32_UART_MODE_ON, sport, PIC32_UART_MODE);
+}
+
+/* disable rx & tx operation on uart */
+static void pic32_uart_dsbl_and_mask(struct uart_port *port)
+{
+ struct pic32_sport *sport = to_pic32_sport(port);
+
+ pic32_uart_rclr(PIC32_UART_MODE_ON, sport, PIC32_UART_MODE);
+ pic32_uart_rclr(PIC32_UART_STA_UTXEN | PIC32_UART_STA_URXEN,
+ sport, PIC32_UART_STA);
+}
+
+/* serial core request to initialize uart and start rx operation */
+static int pic32_uart_startup(struct uart_port *port)
+{
+ struct pic32_sport *sport = to_pic32_sport(port);
+ u32 dflt_baud = ((port->uartclk / PIC32_UART_DFLT_BRATE) / 16) - 1;
+ unsigned long flags;
+ int ret = 0;
+
+ local_irq_save(flags);
+
+ ret = pic32_enable_clock(sport);
+ if (ret)
+ goto out_unlock;
+
+ /* clear status and mode registers */
+ pic32_uart_write(0, sport, PIC32_UART_MODE);
+ pic32_uart_write(0, sport, PIC32_UART_STA);
+
+ /* disable uart and mask all interrupts */
+ pic32_uart_dsbl_and_mask(port);
+
+ /* set default baud */
+ pic32_uart_write(dflt_baud, sport, PIC32_UART_BRG);
+
+ local_irq_restore(flags);
+
+ /* Each UART of a PIC32 has three interrupts therefore,
+ * we setup driver to register the 3 irqs for the device.
+ *
+ * For each irq request_irq() is called with interrupt disabled.
+ * And the irq is enabled as soon as we are ready to handle them.
+ */
+ tx_irq_enabled(sport) = 0;
+
+ sport->irq_fault_name = kasprintf(GFP_KERNEL, "%s%d-fault",
+ pic32_uart_type(port),
+ sport->idx);
+ irq_set_status_flags(sport->irq_fault, IRQ_NOAUTOEN);
+ ret = request_irq(sport->irq_fault, pic32_uart_fault_interrupt,
+ sport->irqflags_fault, sport->irq_fault_name, port);
+ if (ret) {
+ dev_err(port->dev, "%s: request irq(%d) err! ret:%d name:%s\n",
+ __func__, sport->irq_fault, ret,
+ pic32_uart_type(port));
+ goto out_done;
+ }
+
+ sport->irq_rx_name = kasprintf(GFP_KERNEL, "%s%d-rx",
+ pic32_uart_type(port),
+ sport->idx);
+ irq_set_status_flags(sport->irq_rx, IRQ_NOAUTOEN);
+ ret = request_irq(sport->irq_rx, pic32_uart_rx_interrupt,
+ sport->irqflags_rx, sport->irq_rx_name, port);
+ if (ret) {
+ dev_err(port->dev, "%s: request irq(%d) err! ret:%d name:%s\n",
+ __func__, sport->irq_rx, ret,
+ pic32_uart_type(port));
+ goto out_done;
+ }
+
+ sport->irq_tx_name = kasprintf(GFP_KERNEL, "%s%d-tx",
+ pic32_uart_type(port),
+ sport->idx);
+ irq_set_status_flags(sport->irq_tx, IRQ_NOAUTOEN);
+ ret = request_irq(sport->irq_tx, pic32_uart_tx_interrupt,
+ sport->irqflags_tx, sport->irq_tx_name, port);
+ if (ret) {
+ dev_err(port->dev, "%s: request irq(%d) err! ret:%d name:%s\n",
+ __func__, sport->irq_tx, ret,
+ pic32_uart_type(port));
+ goto out_done;
+ }
+
+ local_irq_save(flags);
+
+ /* set rx interrupt on first receive */
+ pic32_uart_rclr(PIC32_UART_STA_URXISEL1 | PIC32_UART_STA_URXISEL0,
+ sport, PIC32_UART_STA);
+
+ /* set interrupt on empty */
+ pic32_uart_rclr(PIC32_UART_STA_UTXISEL1, sport, PIC32_UART_STA);
+
+ /* enable all interrupts and eanable uart */
+ pic32_uart_en_and_unmask(port);
+
+ enable_irq(sport->irq_fault);
+ enable_irq(sport->irq_rx);
+
+out_unlock:
+ local_irq_restore(flags);
+
+out_done:
+ return ret;
+}
+
+/* serial core request to flush & disable uart */
+static void pic32_uart_shutdown(struct uart_port *port)
+{
+ struct pic32_sport *sport = to_pic32_sport(port);
+ unsigned long flags;
+
+ /* disable uart */
+ spin_lock_irqsave(&port->lock, flags);
+ pic32_uart_dsbl_and_mask(port);
+ spin_unlock_irqrestore(&port->lock, flags);
+ pic32_disable_clock(sport);
+
+ /* free all 3 interrupts for this UART */
+ free_irq(sport->irq_fault, port);
+ free_irq(sport->irq_tx, port);
+ free_irq(sport->irq_rx, port);
+}
+
+/* serial core request to change current uart setting */
+static void pic32_uart_set_termios(struct uart_port *port,
+ struct ktermios *new,
+ struct ktermios *old)
+{
+ struct pic32_sport *sport = to_pic32_sport(port);
+ unsigned int baud;
+ unsigned int quot;
+ unsigned long flags;
+
+ spin_lock_irqsave(&port->lock, flags);
+
+ /* disable uart and mask all interrupts while changing speed */
+ pic32_uart_dsbl_and_mask(port);
+
+ /* stop bit options */
+ if (new->c_cflag & CSTOPB)
+ pic32_uart_rset(PIC32_UART_MODE_STSEL, sport, PIC32_UART_MODE);
+ else
+ pic32_uart_rclr(PIC32_UART_MODE_STSEL, sport, PIC32_UART_MODE);
+
+ /* parity options */
+ if (new->c_cflag & PARENB) {
+ if (new->c_cflag & PARODD) {
+ pic32_uart_rset(PIC32_UART_MODE_PDSEL1, sport,
+ PIC32_UART_MODE);
+ pic32_uart_rclr(PIC32_UART_MODE_PDSEL0, sport,
+ PIC32_UART_MODE);
+ } else {
+ pic32_uart_rset(PIC32_UART_MODE_PDSEL0, sport,
+ PIC32_UART_MODE);
+ pic32_uart_rclr(PIC32_UART_MODE_PDSEL1, sport,
+ PIC32_UART_MODE);
+ }
+ } else {
+ pic32_uart_rclr(PIC32_UART_MODE_PDSEL1 | PIC32_UART_MODE_PDSEL0,
+ sport, PIC32_UART_MODE);
+ }
+ /* if hw flow ctrl, then the pins must be specified in device tree */
+ if ((new->c_cflag & CRTSCTS) && sport->hw_flow_ctrl) {
+ /* enable hardware flow control */
+ pic32_uart_rset(PIC32_UART_MODE_UEN1, sport, PIC32_UART_MODE);
+ pic32_uart_rclr(PIC32_UART_MODE_UEN0, sport, PIC32_UART_MODE);
+ pic32_uart_rclr(PIC32_UART_MODE_RTSMD, sport, PIC32_UART_MODE);
+ } else {
+ /* disable hardware flow control */
+ pic32_uart_rclr(PIC32_UART_MODE_UEN1, sport, PIC32_UART_MODE);
+ pic32_uart_rclr(PIC32_UART_MODE_UEN0, sport, PIC32_UART_MODE);
+ pic32_uart_rclr(PIC32_UART_MODE_RTSMD, sport, PIC32_UART_MODE);
+ }
+
+ /* update baud */
+ baud = uart_get_baud_rate(port, new, old, 0, port->uartclk / 16);
+ quot = uart_get_divisor(port, baud) - 1;
+ pic32_uart_write(quot, sport, PIC32_UART_BRG);
+ uart_update_timeout(port, new->c_cflag, baud);
+
+ /* enable uart */
+ pic32_uart_en_and_unmask(port);
+
+ spin_unlock_irqrestore(&port->lock, flags);
+}
+
+/* serial core request to claim uart iomem */
+static int pic32_uart_request_port(struct uart_port *port)
+{
+ struct platform_device *pdev = to_platform_device(port->dev);
+ struct resource *res_mem;
+ unsigned int res_size;
+
+ res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (unlikely(!res_mem))
+ return -EINVAL;
+ res_size = resource_size(res_mem);
+
+ if (!request_mem_region(port->mapbase, res_size, "pic32_uart_mem")) {
+ dev_err(port->dev, "Memory region busy\n");
+ return -EBUSY;
+ }
+
+ port->membase = devm_ioremap_nocache(port->dev,
+ port->mapbase, res_size);
+ if (!port->membase) {
+ dev_err(port->dev, "Unable to map registers\n");
+ release_mem_region(port->mapbase, res_size);
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+/* serial core request to release uart iomem */
+static void pic32_uart_release_port(struct uart_port *port)
+{
+ struct platform_device *pdev = to_platform_device(port->dev);
+ struct resource *res_mem;
+ unsigned int res_size;
+
+ res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (unlikely(!res_mem))
+ return;
+ res_size = resource_size(res_mem);
+
+ release_mem_region(port->mapbase, res_size);
+ devm_iounmap(port->dev, port->membase);
+}
+
+/* serial core request to do any port required auto-configuration */
+static void pic32_uart_config_port(struct uart_port *port, int flags)
+{
+ if (flags & UART_CONFIG_TYPE) {
+ if (pic32_uart_request_port(port))
+ return;
+ port->type = PORT_PIC32;
+ }
+}
+
+/* serial core request to check that port information in serinfo are suitable */
+static int pic32_uart_verify_port(struct uart_port *port,
+ struct serial_struct *serinfo)
+{
+ if (port->type != PORT_PIC32)
+ return -EINVAL;
+ if (port->irq != serinfo->irq)
+ return -EINVAL;
+ if (port->iotype != serinfo->io_type)
+ return -EINVAL;
+ if (port->mapbase != (unsigned long)serinfo->iomem_base)
+ return -EINVAL;
+
+ return 0;
+}
+
+/* serial core callbacks */
+static const struct uart_ops pic32_uart_ops = {
+ .tx_empty = pic32_uart_tx_empty,
+ .get_mctrl = pic32_uart_get_mctrl,
+ .set_mctrl = pic32_uart_set_mctrl,
+ .start_tx = pic32_uart_start_tx,
+ .stop_tx = pic32_uart_stop_tx,
+ .stop_rx = pic32_uart_stop_rx,
+ .break_ctl = pic32_uart_break_ctl,
+ .startup = pic32_uart_startup,
+ .shutdown = pic32_uart_shutdown,
+ .set_termios = pic32_uart_set_termios,
+ .type = pic32_uart_type,
+ .release_port = pic32_uart_release_port,
+ .request_port = pic32_uart_request_port,
+ .config_port = pic32_uart_config_port,
+ .verify_port = pic32_uart_verify_port,
+};
+
+#ifdef CONFIG_SERIAL_PIC32_CONSOLE
+/* output given char */
+static void pic32_console_putchar(struct uart_port *port, int ch)
+{
+ struct pic32_sport *sport = to_pic32_sport(port);
+
+ if (!(pic32_uart_read(sport, PIC32_UART_MODE) & PIC32_UART_MODE_ON))
+ return;
+
+ if (!(pic32_uart_read(sport, PIC32_UART_STA) & PIC32_UART_STA_UTXEN))
+ return;
+
+ /* wait for tx empty */
+ while (!(pic32_uart_read(sport, PIC32_UART_STA) & PIC32_UART_STA_TRMT))
+ udelay(1);
+
+ pic32_uart_write(ch & 0xff, sport, PIC32_UART_TX);
+}
+
+/* console core request to output given string */
+static void pic32_console_write(struct console *co, const char *s,
+ unsigned int count)
+{
+ struct pic32_sport *sport = pic32_sports[co->index];
+ struct uart_port *port = pic32_get_port(sport);
+
+ /* call uart helper to deal with \r\n */
+ uart_console_write(port, s, count, pic32_console_putchar);
+}
+
+/* console core request to setup given console, find matching uart
+ * port and setup it.
+ */
+static int pic32_console_setup(struct console *co, char *options)
+{
+ struct pic32_sport *sport;
+ struct uart_port *port = NULL;
+ int baud = 115200;
+ int bits = 8;
+ int parity = 'n';
+ int flow = 'n';
+ int ret = 0;
+
+ if (unlikely(co->index < 0 || co->index >= PIC32_MAX_UARTS))
+ return -ENODEV;
+
+ sport = pic32_sports[co->index];
+ if (!sport)
+ return -ENODEV;
+ port = pic32_get_port(sport);
+
+ ret = pic32_enable_clock(sport);
+ if (ret)
+ return ret;
+
+ if (options)
+ uart_parse_options(options, &baud, &parity, &bits, &flow);
+
+ return uart_set_options(port, co, baud, parity, bits, flow);
+}
+
+static struct uart_driver pic32_uart_driver;
+static struct console pic32_console = {
+ .name = PIC32_SDEV_NAME,
+ .write = pic32_console_write,
+ .device = uart_console_device,
+ .setup = pic32_console_setup,
+ .flags = CON_PRINTBUFFER,
+ .index = -1,
+ .data = &pic32_uart_driver,
+};
+#define PIC32_SCONSOLE (&pic32_console)
+
+static int __init pic32_console_init(void)
+{
+ register_console(&pic32_console);
+ return 0;
+}
+console_initcall(pic32_console_init);
+
+static inline bool is_pic32_console_port(struct uart_port *port)
+{
+ return (port->cons && port->cons->index == port->line);
+}
+
+/*
+ * Late console initialization.
+ */
+static int __init pic32_late_console_init(void)
+{
+ if (!(pic32_console.flags & CON_ENABLED))
+ register_console(&pic32_console);
+
+ return 0;
+}
+
+core_initcall(pic32_late_console_init);
+
+#else
+#define PIC32_SCONSOLE NULL
+#endif
+
+static struct uart_driver pic32_uart_driver = {
+ .owner = THIS_MODULE,
+ .driver_name = PIC32_DEV_NAME,
+ .dev_name = PIC32_SDEV_NAME,
+ .major = PIC32_SDEV_MAJOR,
+ .minor = PIC32_SDEV_MINOR,
+ .nr = PIC32_MAX_UARTS,
+ .cons = PIC32_SCONSOLE,
+};
+
+static int pic32_uart_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct pic32_sport *sport;
+ int uart_idx = 0;
+ struct resource *res_mem;
+ struct uart_port *port;
+ int ret = 0;
+
+ uart_idx = of_alias_get_id(np, "serial");
+ if (uart_idx < 0 || uart_idx >= PIC32_MAX_UARTS)
+ return -EINVAL;
+
+ res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res_mem)
+ return -EINVAL;
+
+ sport = devm_kzalloc(&pdev->dev, sizeof(*sport), GFP_KERNEL);
+ if (!sport)
+ return -ENOMEM;
+
+ sport->idx = uart_idx;
+ sport->irq_fault = irq_of_parse_and_map(np, 0);
+ sport->irqflags_fault = IRQF_NO_THREAD;
+ sport->irq_rx = irq_of_parse_and_map(np, 1);
+ sport->irqflags_rx = IRQF_NO_THREAD;
+ sport->irq_tx = irq_of_parse_and_map(np, 2);
+ sport->irqflags_tx = IRQF_NO_THREAD;
+ sport->clk = devm_clk_get(&pdev->dev, NULL);
+ sport->cts_gpio = -EINVAL;
+ sport->dev = &pdev->dev;
+
+ ret = pic32_enable_clock(sport);
+ if (ret) {
+ dev_err(&pdev->dev, "clk enable ?\n");
+ goto err;
+ }
+
+ /* Hardware flow control: gpios
+ * !Note: Basically, CTS is needed for reading the status.
+ */
+ sport->hw_flow_ctrl = false;
+ sport->cts_gpio = of_get_named_gpio(np, "cts-gpios", 0);
+ if (gpio_is_valid(sport->cts_gpio)) {
+ sport->hw_flow_ctrl = true;
+
+ ret = devm_gpio_request(sport->dev,
+ sport->cts_gpio, "CTS");
+ if (ret) {
+ dev_err(&pdev->dev,
+ "error requesting CTS GPIO\n");
+ goto err_disable_clk;
+ }
+
+ ret = gpio_direction_input(sport->cts_gpio);
+ if (ret) {
+ dev_err(&pdev->dev, "error setting CTS GPIO\n");
+ goto err_disable_clk;
+ }
+ }
+
+ pic32_sports[uart_idx] = sport;
+ port = &sport->port;
+ memset(port, 0, sizeof(*port));
+ port->iotype = UPIO_MEM;
+ port->mapbase = res_mem->start;
+ port->ops = &pic32_uart_ops;
+ port->flags = UPF_BOOT_AUTOCONF;
+ port->dev = &pdev->dev;
+ port->fifosize = PIC32_UART_TX_FIFO_DEPTH;
+ port->uartclk = clk_get_rate(sport->clk);
+ port->line = uart_idx;
+
+ ret = uart_add_one_port(&pic32_uart_driver, port);
+ if (ret) {
+ port->membase = NULL;
+ dev_err(port->dev, "%s: uart add port error!\n", __func__);
+ goto err_disable_clk;
+ }
+
+#ifdef CONFIG_SERIAL_PIC32_CONSOLE
+ if (is_pic32_console_port(port) &&
+ (pic32_console.flags & CON_ENABLED)) {
+ /* The peripheral clock has been enabled by console_setup,
+ * so disable it till the port is used.
+ */
+ pic32_disable_clock(sport);
+ }
+#endif
+
+ platform_set_drvdata(pdev, port);
+
+ dev_info(&pdev->dev, "%s: uart(%d) driver initialized.\n",
+ __func__, uart_idx);
+ ret = 0;
+
+err_disable_clk:
+ /* disable clock till the port is used. */
+ pic32_disable_clock(sport);
+err:
+ /* automatic unroll of sport and gpios */
+ return ret;
+}
+
+static int pic32_uart_remove(struct platform_device *pdev)
+{
+ struct uart_port *port = platform_get_drvdata(pdev);
+ struct pic32_sport *sport = to_pic32_sport(port);
+
+ uart_remove_one_port(&pic32_uart_driver, port);
+ pic32_disable_clock(sport);
+ platform_set_drvdata(pdev, NULL);
+ pic32_sports[sport->idx] = NULL;
+
+ /* automatic unroll of sport and gpios */
+ return 0;
+}
+
+static const struct of_device_id pic32_serial_dt_ids[] = {
+ { .compatible = "microchip,pic32mzda-uart" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, pic32_serial_dt_ids);
+
+static struct platform_driver pic32_uart_platform_driver = {
+ .probe = pic32_uart_probe,
+ .remove = pic32_uart_remove,
+ .driver = {
+ .name = PIC32_DEV_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(pic32_serial_dt_ids),
+ },
+};
+
+static int __init pic32_uart_init(void)
+{
+ int ret;
+
+ ret = uart_register_driver(&pic32_uart_driver);
+ if (ret) {
+ pr_err("failed to register %s:%d\n",
+ pic32_uart_driver.driver_name, ret);
+ return ret;
+ }
+
+ ret = platform_driver_register(&pic32_uart_platform_driver);
+ if (ret) {
+ pr_err("fail to register pic32 uart\n");
+ uart_unregister_driver(&pic32_uart_driver);
+ }
+
+ return ret;
+}
+arch_initcall(pic32_uart_init);
+
+static void __exit pic32_uart_exit(void)
+{
+#ifdef CONFIG_SERIAL_PIC32_CONSOLE
+ unregister_console(&pic32_console);
+#endif
+ platform_driver_unregister(&pic32_uart_platform_driver);
+ uart_unregister_driver(&pic32_uart_driver);
+}
+module_exit(pic32_uart_exit);
+
+MODULE_AUTHOR("Steve Scott <steve.scott@microchip.com>");
+MODULE_DESCRIPTION("Microchip PIC32 integrated serial port driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/tty/serial/pic32_uart.h b/drivers/tty/serial/pic32_uart.h
new file mode 100644
index 0000000..b2f6960
--- /dev/null
+++ b/drivers/tty/serial/pic32_uart.h
@@ -0,0 +1,198 @@
+/*
+ * PIC32 Integrated Serial Driver.
+ *
+ * Copyright (C) 2015 Microchip Technology, Inc.
+ *
+ * Authors:
+ * Sorin-Andrei Pistirica <andrei.pistirica@microchip.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+#ifndef __DT_PIC32_UART_H__
+#define __DT_PIC32_UART_H__
+
+#define PIC32_UART_DFLT_BRATE (9600)
+#define PIC32_UART_TX_FIFO_DEPTH (8)
+#define PIC32_UART_RX_FIFO_DEPTH (8)
+
+struct pic32_console_opt {
+ int baud;
+ int parity;
+ int bits;
+ int flow;
+};
+/* struct pic32_sport - pic32 serial port descriptor
+ * @port: uart port descriptor
+ * @idx: port index
+ * @irq_fault: virtual fault interrupt number
+ * @irqflags_fault: flags related to fault irq
+ * @irq_fault_name: irq fault name
+ * @irq_rx: virtual rx interrupt number
+ * @irqflags_rx: flags related to rx irq
+ * @irq_rx_name: irq rx name
+ * @irq_tx: virtual tx interrupt number
+ * @irqflags_tx: : flags related to tx irq
+ * @irq_tx_name: irq tx name
+ * @cts_gpio: clear to send gpio
+ * @dev: device descriptor
+ **/
+struct pic32_sport {
+ struct uart_port port;
+ struct pic32_console_opt opt;
+ int idx;
+
+ int irq_fault;
+ int irqflags_fault;
+ const char *irq_fault_name;
+ int irq_rx;
+ int irqflags_rx;
+ const char *irq_rx_name;
+ int irq_tx;
+ int irqflags_tx;
+ const char *irq_tx_name;
+ u8 enable_tx_irq;
+
+ bool hw_flow_ctrl;
+ int cts_gpio;
+
+ int ref_clk;
+ struct clk *clk;
+
+ struct device *dev;
+};
+#define to_pic32_sport(c) container_of(c, struct pic32_sport, port)
+#define pic32_get_port(sport) (&sport->port)
+#define pic32_get_opt(sport) (&sport->opt)
+#define tx_irq_enabled(sport) (sport->enable_tx_irq)
+
+struct pic32_reg {
+ u32 val;
+ u32 clr;
+ u32 set;
+ u32 inv;
+} __packed;
+#define PIC32_REGS 4
+#define PIC32_REG_SIZE 4
+
+enum pic32_uart_regs {
+ PIC32_UART_UNKNOWN = 0,
+ PIC32_UART_MODE = 1,
+ PIC32_UART_STA = 2,
+ PIC32_UART_TX = 3,
+ PIC32_UART_RX = 4,
+ PIC32_UART_BRG = 5,
+
+ /* add above this line */
+ PIC32_UART_LAST
+};
+
+/* uart register offsets */
+static u32 pic32_uart_lookup_reg[PIC32_UART_LAST] = {
+ [PIC32_UART_MODE] = 0 * PIC32_REGS * PIC32_REG_SIZE,
+ [PIC32_UART_STA] = 1 * PIC32_REGS * PIC32_REG_SIZE,
+ [PIC32_UART_TX] = 2 * PIC32_REGS * PIC32_REG_SIZE,
+ [PIC32_UART_RX] = 3 * PIC32_REGS * PIC32_REG_SIZE,
+ [PIC32_UART_BRG] = 4 * PIC32_REGS * PIC32_REG_SIZE,
+};
+
+static inline void __iomem *pic32_uart_get_reg(struct pic32_sport *sport,
+ enum pic32_uart_regs reg)
+{
+ struct uart_port *port = pic32_get_port(sport);
+
+ return port->membase + pic32_uart_lookup_reg[reg];
+}
+
+static inline u32 pic32_uart_rval(struct pic32_sport *sport,
+ enum pic32_uart_regs reg)
+{
+ void __iomem *addr = pic32_uart_get_reg(sport, reg);
+ struct pic32_reg __iomem *reg_addr = (struct pic32_reg __iomem *)addr;
+
+ return readl(®_addr->val);
+}
+
+static inline void pic32_uart_rset(u32 val,
+ struct pic32_sport *sport,
+ enum pic32_uart_regs reg)
+{
+ void __iomem *addr = pic32_uart_get_reg(sport, reg);
+ struct pic32_reg __iomem *reg_addr = (struct pic32_reg __iomem *)addr;
+
+ writel(val, ®_addr->set);
+}
+
+static inline void pic32_uart_rclr(u32 val,
+ struct pic32_sport *sport,
+ enum pic32_uart_regs reg)
+{
+ void __iomem *addr = pic32_uart_get_reg(sport, reg);
+ struct pic32_reg __iomem *reg_addr = (struct pic32_reg __iomem *)addr;
+
+ writel(val, ®_addr->clr);
+}
+
+static inline void pic32_uart_rinv(u32 val,
+ struct pic32_sport *sport,
+ enum pic32_uart_regs reg)
+{
+ void __iomem *addr = pic32_uart_get_reg(sport, reg);
+ struct pic32_reg __iomem *reg_addr = (struct pic32_reg __iomem *)addr;
+
+ writel(val, ®_addr->inv);
+}
+
+static inline void pic32_uart_write(u32 val,
+ struct pic32_sport *sport,
+ enum pic32_uart_regs reg)
+{
+ void __iomem *addr = pic32_uart_get_reg(sport, reg);
+
+ writel(val, addr);
+}
+
+static inline u32 pic32_uart_read(struct pic32_sport *sport,
+ enum pic32_uart_regs reg)
+{
+ void __iomem *addr = pic32_uart_get_reg(sport, reg);
+
+ return readl(addr);
+}
+
+/* pic32 uart mode register bits */
+#define PIC32_UART_MODE_ON (1 << 15)
+#define PIC32_UART_MODE_FRZ (1 << 14)
+#define PIC32_UART_MODE_SIDL (1 << 13)
+#define PIC32_UART_MODE_IREN (1 << 12)
+#define PIC32_UART_MODE_RTSMD (1 << 11)
+#define PIC32_UART_MODE_RESV1 (1 << 10)
+#define PIC32_UART_MODE_UEN1 (1 << 9)
+#define PIC32_UART_MODE_UEN0 (1 << 8)
+#define PIC32_UART_MODE_WAKE (1 << 7)
+#define PIC32_UART_MODE_LPBK (1 << 6)
+#define PIC32_UART_MODE_ABAUD (1 << 5)
+#define PIC32_UART_MODE_RXINV (1 << 4)
+#define PIC32_UART_MODE_BRGH (1 << 3)
+#define PIC32_UART_MODE_PDSEL1 (1 << 2)
+#define PIC32_UART_MODE_PDSEL0 (1 << 1)
+#define PIC32_UART_MODE_STSEL (1 << 0)
+
+/* pic32 uart status register bits */
+#define PIC32_UART_STA_UTXISEL1 (1 << 15)
+#define PIC32_UART_STA_UTXISEL0 (1 << 14)
+#define PIC32_UART_STA_UTXINV (1 << 13)
+#define PIC32_UART_STA_URXEN (1 << 12)
+#define PIC32_UART_STA_UTXBRK (1 << 11)
+#define PIC32_UART_STA_UTXEN (1 << 10)
+#define PIC32_UART_STA_UTXBF (1 << 9)
+#define PIC32_UART_STA_TRMT (1 << 8)
+#define PIC32_UART_STA_URXISEL1 (1 << 7)
+#define PIC32_UART_STA_URXISEL0 (1 << 6)
+#define PIC32_UART_STA_ADDEN (1 << 5)
+#define PIC32_UART_STA_RIDLE (1 << 4)
+#define PIC32_UART_STA_PERR (1 << 3)
+#define PIC32_UART_STA_FERR (1 << 2)
+#define PIC32_UART_STA_OERR (1 << 1)
+#define PIC32_UART_STA_URXDA (1 << 0)
+
+#endif /* __DT_PIC32_UART_H__ */
diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h
index 93ba148..9df0a98 100644
--- a/include/uapi/linux/serial_core.h
+++ b/include/uapi/linux/serial_core.h
@@ -261,4 +261,7 @@
/* STM32 USART */
#define PORT_STM32 113
+/* Microchip PIC32 UART */
+#define PORT_PIC32 114
+
#endif /* _UAPILINUX_SERIAL_CORE_H */
--
1.7.9.5
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Joshua Henderson <joshua.henderson@microchip.com> |
|---|---|
| Date | 2015-12-14 23:50 +0100 |
| Subject | [PATCH v2 14/14] MIPS: pic32mzda: Add initial PIC32MZDA Starter Kit defconfig |
| Message-ID | <qFK6n-3W4-53@gated-at.bofh.it> |
| In reply to | #1291644 |
This adds an initial default config that enables all available PIC32 drivers and is enough for booting a PIC32MZDA Starter Kit. Signed-off-by: Joshua Henderson <joshua.henderson@microchip.com> Cc: Ralf Baechle <ralf@linux-mips.org> --- arch/mips/configs/pic32mzda_defconfig | 88 +++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 arch/mips/configs/pic32mzda_defconfig diff --git a/arch/mips/configs/pic32mzda_defconfig b/arch/mips/configs/pic32mzda_defconfig new file mode 100644 index 0000000..17014ca --- /dev/null +++ b/arch/mips/configs/pic32mzda_defconfig @@ -0,0 +1,88 @@ +CONFIG_MACH_PIC32=y +CONFIG_DTB_PIC32_MZDA_SK=y +CONFIG_HZ_100=y +CONFIG_PREEMPT_VOLUNTARY=y +# CONFIG_SECCOMP is not set +CONFIG_SYSVIPC=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_RELAY=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_EMBEDDED=y +# CONFIG_COMPAT_BRK is not set +CONFIG_SLAB=y +CONFIG_JUMP_LABEL=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_BLK_DEV_BSGLIB=y +CONFIG_PARTITION_ADVANCED=y +CONFIG_SGI_PARTITION=y +CONFIG_BINFMT_MISC=m +# CONFIG_SUSPEND is not set +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +# CONFIG_FIRMWARE_IN_KERNEL is not set +# CONFIG_ALLOW_DEV_COREDUMP is not set +CONFIG_BLK_DEV_LOOP=m +CONFIG_SCSI=y +CONFIG_BLK_DEV_SD=y +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_SCAN_ASYNC=y +# CONFIG_SCSI_LOWLEVEL is not set +CONFIG_INPUT_LEDS=m +CONFIG_INPUT_POLLDEV=y +CONFIG_INPUT_MOUSEDEV=m +CONFIG_INPUT_EVDEV=y +CONFIG_INPUT_EVBUG=m +# CONFIG_KEYBOARD_ATKBD is not set +CONFIG_KEYBOARD_GPIO=m +CONFIG_KEYBOARD_GPIO_POLLED=m +# CONFIG_MOUSE_PS2 is not set +# CONFIG_SERIO is not set +CONFIG_SERIAL_PIC32=y +CONFIG_SERIAL_PIC32_CONSOLE=y +CONFIG_HW_RANDOM=y +CONFIG_RAW_DRIVER=m +CONFIG_GPIO_SYSFS=y +# CONFIG_HWMON is not set +CONFIG_HIDRAW=y +# CONFIG_USB_SUPPORT is not set +CONFIG_MMC=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_MICROCHIP_PIC32=y +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=m +CONFIG_LEDS_TRIGGER_ONESHOT=m +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_GPIO=m +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y +# 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_AUTOFS4_FS=m +CONFIG_FUSE_FS=m +CONFIG_FSCACHE=m +CONFIG_ISO9660_FS=m +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_UDF_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_PROC_KCORE=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_SQUASHFS=m +CONFIG_SQUASHFS_XATTR=y +CONFIG_SQUASHFS_LZ4=y +CONFIG_SQUASHFS_LZO=y +CONFIG_SQUASHFS_XZ=y -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web