diff options
Diffstat (limited to 'target/linux/ramips/patches-3.8/0204-owrt-MIPS-ralink-add-usb-platform-support.patch')
-rw-r--r-- | target/linux/ramips/patches-3.8/0204-owrt-MIPS-ralink-add-usb-platform-support.patch | 328 |
1 files changed, 328 insertions, 0 deletions
diff --git a/target/linux/ramips/patches-3.8/0204-owrt-MIPS-ralink-add-usb-platform-support.patch b/target/linux/ramips/patches-3.8/0204-owrt-MIPS-ralink-add-usb-platform-support.patch new file mode 100644 index 0000000000..7b9e1a366a --- /dev/null +++ b/target/linux/ramips/patches-3.8/0204-owrt-MIPS-ralink-add-usb-platform-support.patch @@ -0,0 +1,328 @@ +From d7e679017ec92824145b275572f6ef83d461f076 Mon Sep 17 00:00:00 2001 +From: John Crispin <blogic@openwrt.org> +Date: Tue, 19 Mar 2013 09:26:22 +0100 +Subject: [PATCH 204/208] owrt: MIPS: ralink: add usb platform support + +Add code to load the platform ehci/ohci driver on Ralink SoC. For the usb core +to work we need to populate the platform_data during boot, prior to the usb +driver being loaded. + +Signed-off-by: John Crispin <blogic@openwrt.org> +--- + arch/mips/ralink/Makefile | 4 +- + arch/mips/ralink/common.h | 1 + + arch/mips/ralink/mt7620.c | 5 ++ + arch/mips/ralink/of.c | 1 + + arch/mips/ralink/rt305x-usb.c | 120 +++++++++++++++++++++++++++++++++++++++++ + arch/mips/ralink/rt3883-usb.c | 118 ++++++++++++++++++++++++++++++++++++++++ + 6 files changed, 247 insertions(+), 2 deletions(-) + create mode 100644 arch/mips/ralink/rt305x-usb.c + create mode 100644 arch/mips/ralink/rt3883-usb.c + +diff --git a/arch/mips/ralink/Makefile b/arch/mips/ralink/Makefile +index cae7d88..8572538 100644 +--- a/arch/mips/ralink/Makefile ++++ b/arch/mips/ralink/Makefile +@@ -9,8 +9,8 @@ + obj-y := prom.o of.o reset.o clk.o irq.o pinmux.o timer.o + + obj-$(CONFIG_SOC_RT288X) += rt288x.o +-obj-$(CONFIG_SOC_RT305X) += rt305x.o +-obj-$(CONFIG_SOC_RT3883) += rt3883.o ++obj-$(CONFIG_SOC_RT305X) += rt305x.o rt305x-usb.o ++obj-$(CONFIG_SOC_RT3883) += rt3883.o rt3883-usb.o + obj-$(CONFIG_SOC_MT7620) += mt7620.o + + obj-$(CONFIG_EARLY_PRINTK) += early_printk.o +diff --git a/arch/mips/ralink/common.h b/arch/mips/ralink/common.h +index ed99f23..14a101c 100644 +--- a/arch/mips/ralink/common.h ++++ b/arch/mips/ralink/common.h +@@ -43,5 +43,6 @@ extern void prom_soc_init(struct ralink_soc_info *soc_info); + __iomem void *plat_of_remap_node(const char *node); + + void ralink_pinmux(void); ++void ralink_usb_platform(void); + + #endif /* _RALINK_COMMON_H__ */ +diff --git a/arch/mips/ralink/mt7620.c b/arch/mips/ralink/mt7620.c +index 9d0dc8b..19b28c5 100644 +--- a/arch/mips/ralink/mt7620.c ++++ b/arch/mips/ralink/mt7620.c +@@ -146,6 +146,11 @@ struct ralink_pinmux rt_pinmux = { + // .wdt_reset = rt305x_wdt_reset, + }; + ++void ralink_usb_platform(void) ++{ ++ ++} ++ + void __init ralink_clk_init(void) + { + unsigned long cpu_rate, sys_rate; +diff --git a/arch/mips/ralink/of.c b/arch/mips/ralink/of.c +index ecf1482..f438145 100644 +--- a/arch/mips/ralink/of.c ++++ b/arch/mips/ralink/of.c +@@ -102,6 +102,7 @@ static int __init plat_of_setup(void) + panic("failed to populate DT\n"); + + ralink_pinmux(); ++ ralink_usb_platform(); + + return 0; + } +diff --git a/arch/mips/ralink/rt305x-usb.c b/arch/mips/ralink/rt305x-usb.c +new file mode 100644 +index 0000000..793fc82 +--- /dev/null ++++ b/arch/mips/ralink/rt305x-usb.c +@@ -0,0 +1,120 @@ ++/* ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ * ++ * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> ++ * Copyright (C) 2013 John Crispin <blogic@openwrt.org> ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/init.h> ++#include <linux/module.h> ++ ++#include <linux/delay.h> ++#include <linux/of_platform.h> ++#include <linux/dma-mapping.h> ++#include <linux/usb/ehci_pdriver.h> ++#include <linux/usb/ohci_pdriver.h> ++ ++#include <asm/mach-ralink/ralink_regs.h> ++#include <asm/mach-ralink/rt305x.h> ++ ++static atomic_t rt3352_usb_pwr_ref = ATOMIC_INIT(0); ++ ++static int rt3352_usb_power_on(struct platform_device *pdev) ++{ ++ ++ if (atomic_inc_return(&rt3352_usb_pwr_ref) == 1) { ++ u32 t; ++ ++ t = rt_sysc_r32(RT3352_SYSC_REG_USB_PS); ++ ++ /* enable clock for port0's and port1's phys */ ++ t = rt_sysc_r32(RT3352_SYSC_REG_CLKCFG1); ++ t |= RT3352_CLKCFG1_UPHY0_CLK_EN | RT3352_CLKCFG1_UPHY1_CLK_EN; ++ rt_sysc_w32(t, RT3352_SYSC_REG_CLKCFG1); ++ mdelay(500); ++ ++ /* pull USBHOST and USBDEV out from reset */ ++ t = rt_sysc_r32(RT3352_SYSC_REG_RSTCTRL); ++ t &= ~(RT3352_RSTCTRL_UHST | RT3352_RSTCTRL_UDEV); ++ rt_sysc_w32(t, RT3352_SYSC_REG_RSTCTRL); ++ mdelay(500); ++ ++ /* enable host mode */ ++ t = rt_sysc_r32(RT3352_SYSC_REG_SYSCFG1); ++ t |= RT3352_SYSCFG1_USB0_HOST_MODE; ++ rt_sysc_w32(t, RT3352_SYSC_REG_SYSCFG1); ++ ++ t = rt_sysc_r32(RT3352_SYSC_REG_USB_PS); ++ } ++ ++ return 0; ++} ++ ++static void rt3352_usb_power_off(struct platform_device *pdev) ++{ ++ if (atomic_dec_return(&rt3352_usb_pwr_ref) == 0) { ++ u32 t; ++ ++ /* put USBHOST and USBDEV into reset */ ++ t = rt_sysc_r32(RT3352_SYSC_REG_RSTCTRL); ++ t |= RT3352_RSTCTRL_UHST | RT3352_RSTCTRL_UDEV; ++ rt_sysc_w32(t, RT3352_SYSC_REG_RSTCTRL); ++ udelay(10000); ++ ++ /* disable clock for port0's and port1's phys*/ ++ t = rt_sysc_r32(RT3352_SYSC_REG_CLKCFG1); ++ t &= ~(RT3352_CLKCFG1_UPHY0_CLK_EN | RT3352_CLKCFG1_UPHY1_CLK_EN); ++ rt_sysc_w32(t, RT3352_SYSC_REG_CLKCFG1); ++ udelay(10000); ++ } ++} ++ ++static struct usb_ehci_pdata rt3352_ehci_data = { ++ .power_on = rt3352_usb_power_on, ++ .power_off = rt3352_usb_power_off, ++}; ++ ++static struct usb_ohci_pdata rt3352_ohci_data = { ++ .power_on = rt3352_usb_power_on, ++ .power_off = rt3352_usb_power_off, ++}; ++ ++static void ralink_add_usb(char *name, void *pdata, u64 *mask) ++{ ++ struct device_node *node; ++ struct platform_device *pdev; ++ ++ node = of_find_compatible_node(NULL, NULL, name); ++ if (!node) ++ return; ++ ++ pdev = of_find_device_by_node(node); ++ if (!pdev) ++ goto error_out; ++ ++ if (pdata) ++ pdev->dev.platform_data = pdata; ++ if (mask) { ++ pdev->dev.dma_mask = mask; ++ pdev->dev.coherent_dma_mask = *mask; ++ } ++ ++error_out: ++ of_node_put(node); ++} ++ ++static u64 rt3352_ohci_dmamask = DMA_BIT_MASK(32); ++static u64 rt3352_ehci_dmamask = DMA_BIT_MASK(32); ++ ++void ralink_usb_platform(void) ++{ ++ if (soc_is_rt3352() || soc_is_rt5350()) { ++ ralink_add_usb("ohci-platform", ++ &rt3352_ohci_data, &rt3352_ohci_dmamask); ++ ralink_add_usb("ehci-platform", ++ &rt3352_ehci_data, &rt3352_ehci_dmamask); ++ } ++} +diff --git a/arch/mips/ralink/rt3883-usb.c b/arch/mips/ralink/rt3883-usb.c +new file mode 100644 +index 0000000..1d948a9 +--- /dev/null ++++ b/arch/mips/ralink/rt3883-usb.c +@@ -0,0 +1,118 @@ ++/* ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ * ++ * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> ++ * Copyright (C) 2013 John Crispin <blogic@openwrt.org> ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/init.h> ++#include <linux/module.h> ++ ++#include <linux/delay.h> ++#include <linux/of_platform.h> ++#include <linux/dma-mapping.h> ++#include <linux/usb/ehci_pdriver.h> ++#include <linux/usb/ohci_pdriver.h> ++ ++#include <asm/mach-ralink/ralink_regs.h> ++#include <asm/mach-ralink/rt3883.h> ++ ++static atomic_t rt3883_usb_pwr_ref = ATOMIC_INIT(0); ++ ++static int rt3883_usb_power_on(struct platform_device *pdev) ++{ ++ if (atomic_inc_return(&rt3883_usb_pwr_ref) == 1) { ++ u32 t; ++ ++ t = rt_sysc_r32(RT3883_SYSC_REG_USB_PS); ++ ++ /* enable clock for port0's and port1's phys */ ++ t = rt_sysc_r32(RT3883_SYSC_REG_CLKCFG1); ++ t |= RT3883_CLKCFG1_UPHY0_CLK_EN | RT3883_CLKCFG1_UPHY1_CLK_EN; ++ rt_sysc_w32(t, RT3883_SYSC_REG_CLKCFG1); ++ mdelay(500); ++ ++ /* pull USBHOST and USBDEV out from reset */ ++ t = rt_sysc_r32(RT3883_SYSC_REG_RSTCTRL); ++ t &= ~(RT3883_RSTCTRL_UHST | RT3883_RSTCTRL_UDEV); ++ rt_sysc_w32(t, RT3883_SYSC_REG_RSTCTRL); ++ mdelay(500); ++ ++ /* enable host mode */ ++ t = rt_sysc_r32(RT3883_SYSC_REG_SYSCFG1); ++ t |= RT3883_SYSCFG1_USB0_HOST_MODE; ++ rt_sysc_w32(t, RT3883_SYSC_REG_SYSCFG1); ++ ++ t = rt_sysc_r32(RT3883_SYSC_REG_USB_PS); ++ } ++ ++ return 0; ++} ++ ++static void rt3883_usb_power_off(struct platform_device *pdev) ++{ ++ if (atomic_dec_return(&rt3883_usb_pwr_ref) == 0) { ++ u32 t; ++ ++ /* put USBHOST and USBDEV into reset */ ++ t = rt_sysc_r32(RT3883_SYSC_REG_RSTCTRL); ++ t |= RT3883_RSTCTRL_UHST | RT3883_RSTCTRL_UDEV; ++ rt_sysc_w32(t, RT3883_SYSC_REG_RSTCTRL); ++ udelay(10000); ++ ++ /* disable clock for port0's and port1's phys*/ ++ t = rt_sysc_r32(RT3883_SYSC_REG_CLKCFG1); ++ t &= ~(RT3883_CLKCFG1_UPHY0_CLK_EN | ++ RT3883_CLKCFG1_UPHY1_CLK_EN); ++ rt_sysc_w32(t, RT3883_SYSC_REG_CLKCFG1); ++ udelay(10000); ++ } ++} ++ ++static struct usb_ohci_pdata rt3883_ohci_data = { ++ .power_on = rt3883_usb_power_on, ++ .power_off = rt3883_usb_power_off, ++}; ++ ++static struct usb_ehci_pdata rt3883_ehci_data = { ++ .power_on = rt3883_usb_power_on, ++ .power_off = rt3883_usb_power_off, ++}; ++ ++static void ralink_add_usb(char *name, void *pdata, u64 *mask) ++{ ++ struct device_node *node; ++ struct platform_device *pdev; ++ ++ node = of_find_compatible_node(NULL, NULL, name); ++ if (!node) ++ return; ++ ++ pdev = of_find_device_by_node(node); ++ if (!pdev) ++ goto error_out; ++ ++ if (pdata) ++ pdev->dev.platform_data = pdata; ++ if (mask) { ++ pdev->dev.dma_mask = mask; ++ pdev->dev.coherent_dma_mask = *mask; ++ } ++ ++error_out: ++ of_node_put(node); ++} ++ ++static u64 rt3883_ohci_dmamask = DMA_BIT_MASK(32); ++static u64 rt3883_ehci_dmamask = DMA_BIT_MASK(32); ++ ++void ralink_usb_platform(void) ++{ ++ ralink_add_usb("ohci-platform", ++ &rt3883_ohci_data, &rt3883_ohci_dmamask); ++ ralink_add_usb("ehci-platform", ++ &rt3883_ehci_data, &rt3883_ehci_dmamask); ++} +-- +1.7.10.4 + |