diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-09 14:28:38 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-09 14:28:38 -0800 |
commit | dfc1ebe76663d582a01c9dc572395cf8086d01de (patch) | |
tree | 54a5ac91214a90f82c27b6e38099a4470837729e /drivers/usb/host | |
parent | acc952c1f373bf3f66cc7a10680eee1762bed40b (diff) | |
parent | b001befe58691ef3627458cd814e8cee7f845c5f (diff) |
Merge tag 'dt' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Device tree conversions for samsung and tegra
Both platforms had some initial device tree support, but this adds
much more to actually make it usable.
* tag 'dt' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (45 commits)
ARM: dts: Add intial dts file for EXYNOS4210 SoC, SMDKV310 and ORIGEN
ARM: EXYNOS: Add Exynos4 device tree enabled board file
rtc: rtc-s3c: Add device tree support
input: samsung-keypad: Add device tree support
ARM: S5PV210: Modify platform data for pl330 driver
ARM: S5PC100: Modify platform data for pl330 driver
ARM: S5P64x0: Modify platform data for pl330 driver
ARM: EXYNOS: Add a alias for pdma clocks
ARM: EXYNOS: Limit usage of pl330 device instance to non-dt build
ARM: SAMSUNG: Add device tree support for pl330 dma engine wrappers
DMA: PL330: Add device tree support
ARM: EXYNOS: Modify platform data for pl330 driver
DMA: PL330: Infer transfer direction from transfer request instead of platform data
DMA: PL330: move filter function into driver
serial: samsung: Fix build for non-Exynos4210 devices
serial: samsung: add device tree support
serial: samsung: merge probe() function from all SoC specific extensions
serial: samsung: merge all SoC specific port reset functions
ARM: SAMSUNG: register uart clocks to clock lookup list
serial: samsung: remove all uses of get_clksrc and set_clksrc
...
Fix up fairly trivial conflicts in arch/arm/mach-s3c2440/clock.c and
drivers/tty/serial/Kconfig both due to just adding code close to
changes.
Diffstat (limited to 'drivers/usb/host')
-rw-r--r-- | drivers/usb/host/ehci-tegra.c | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index db9d1b4bfbd..dbc7fe8ca9e 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -21,7 +21,12 @@ #include <linux/platform_data/tegra_usb.h> #include <linux/irq.h> #include <linux/usb/otg.h> +#include <linux/gpio.h> +#include <linux/of.h> +#include <linux/of_gpio.h> + #include <mach/usb_phy.h> +#include <mach/iomap.h> #define TEGRA_USB_DMA_ALIGN 32 @@ -574,6 +579,35 @@ static const struct hc_driver tegra_ehci_hc_driver = { .port_handed_over = ehci_port_handed_over, }; +static int setup_vbus_gpio(struct platform_device *pdev) +{ + int err = 0; + int gpio; + + if (!pdev->dev.of_node) + return 0; + + gpio = of_get_named_gpio(pdev->dev.of_node, "nvidia,vbus-gpio", 0); + if (!gpio_is_valid(gpio)) + return 0; + + err = gpio_request(gpio, "vbus_gpio"); + if (err) { + dev_err(&pdev->dev, "can't request vbus gpio %d", gpio); + return err; + } + err = gpio_direction_output(gpio, 1); + if (err) { + dev_err(&pdev->dev, "can't enable vbus\n"); + return err; + } + gpio_set_value(gpio, 1); + + return err; +} + +static u64 tegra_ehci_dma_mask = DMA_BIT_MASK(32); + static int tegra_ehci_probe(struct platform_device *pdev) { struct resource *res; @@ -590,6 +624,15 @@ static int tegra_ehci_probe(struct platform_device *pdev) return -EINVAL; } + /* Right now device-tree probed devices don't get dma_mask set. + * Since shared usb code relies on it, set it here for now. + * Once we have dma capability bindings this can go away. + */ + if (!pdev->dev.dma_mask) + pdev->dev.dma_mask = &tegra_ehci_dma_mask; + + setup_vbus_gpio(pdev); + tegra = kzalloc(sizeof(struct tegra_ehci_hcd), GFP_KERNEL); if (!tegra) return -ENOMEM; @@ -640,6 +683,28 @@ static int tegra_ehci_probe(struct platform_device *pdev) goto fail_io; } + /* This is pretty ugly and needs to be fixed when we do only + * device-tree probing. Old code relies on the platform_device + * numbering that we lack for device-tree-instantiated devices. + */ + if (instance < 0) { + switch (res->start) { + case TEGRA_USB_BASE: + instance = 0; + break; + case TEGRA_USB2_BASE: + instance = 1; + break; + case TEGRA_USB3_BASE: + instance = 2; + break; + default: + err = -ENODEV; + dev_err(&pdev->dev, "unknown usb instance\n"); + goto fail_phy; + } + } + tegra->phy = tegra_usb_phy_open(instance, hcd->regs, pdata->phy_config, TEGRA_USB_PHY_MODE_HOST); if (IS_ERR(tegra->phy)) { @@ -773,6 +838,11 @@ static void tegra_ehci_hcd_shutdown(struct platform_device *pdev) hcd->driver->shutdown(hcd); } +static struct of_device_id tegra_ehci_of_match[] __devinitdata = { + { .compatible = "nvidia,tegra20-ehci", }, + { }, +}; + static struct platform_driver tegra_ehci_driver = { .probe = tegra_ehci_probe, .remove = tegra_ehci_remove, @@ -783,5 +853,6 @@ static struct platform_driver tegra_ehci_driver = { .shutdown = tegra_ehci_hcd_shutdown, .driver = { .name = "tegra-ehci", + .of_match_table = tegra_ehci_of_match, } }; |