Skip to content

Commit

Permalink
Merge branch 'samsung/ohci' into next/drivers
Browse files Browse the repository at this point in the history
* samsung/ohci:
  ARM: EXYNOS: Add USB OHCI support to ORIGEN board
  USB: Add Samsung Exynos OHCI diver
  ARM: EXYNOS: Add USB OHCI support to SMDKV310 board
  ARM: EXYNOS: Add USB OHCI device
  • Loading branch information
Arnd Bergmann committed Dec 27, 2011
2 parents 4551ae0 + fcf9323 commit e814fb6
Show file tree
Hide file tree
Showing 13 changed files with 410 additions and 0 deletions.
7 changes: 7 additions & 0 deletions arch/arm/mach-exynos/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ config EXYNOS4_DEV_DWMCI
help
Compile in platform device definitions for DWMCI

config EXYNOS4_DEV_USB_OHCI
bool
help
Compile in platform device definition for USB OHCI

config EXYNOS4_SETUP_I2C1
bool
help
Expand Down Expand Up @@ -179,6 +184,7 @@ config MACH_SMDKV310
select SAMSUNG_DEV_KEYPAD
select EXYNOS4_DEV_PD
select SAMSUNG_DEV_PWM
select EXYNOS4_DEV_USB_OHCI
select EXYNOS4_DEV_SYSMMU
select EXYNOS4_SETUP_FIMD0
select EXYNOS4_SETUP_I2C1
Expand Down Expand Up @@ -288,6 +294,7 @@ config MACH_ORIGEN
select SAMSUNG_DEV_BACKLIGHT
select SAMSUNG_DEV_PWM
select EXYNOS4_DEV_PD
select EXYNOS4_DEV_USB_OHCI
select EXYNOS4_SETUP_FIMD0
select EXYNOS4_SETUP_SDHCI
select EXYNOS4_SETUP_USB_PHY
Expand Down
1 change: 1 addition & 0 deletions arch/arm/mach-exynos/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ obj-$(CONFIG_EXYNOS4_DEV_AHCI) += dev-ahci.o
obj-$(CONFIG_EXYNOS4_DEV_PD) += dev-pd.o
obj-$(CONFIG_EXYNOS4_DEV_SYSMMU) += dev-sysmmu.o
obj-$(CONFIG_EXYNOS4_DEV_DWMCI) += dev-dwmci.o
obj-$(CONFIG_EXYNOS4_DEV_USB_OHCI) += dev-ohci.o

obj-$(CONFIG_EXYNOS4_SETUP_FIMC) += setup-fimc.o
obj-$(CONFIG_EXYNOS4_SETUP_FIMD0) += setup-fimd0.o
Expand Down
52 changes: 52 additions & 0 deletions arch/arm/mach-exynos/dev-ohci.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/* linux/arch/arm/mach-exynos/dev-ohci.c
*
* Copyright (c) 2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* EXYNOS - OHCI support
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/

#include <linux/dma-mapping.h>
#include <linux/platform_device.h>

#include <mach/irqs.h>
#include <mach/map.h>
#include <mach/ohci.h>

#include <plat/devs.h>
#include <plat/usb-phy.h>

static struct resource exynos4_ohci_resource[] = {
[0] = DEFINE_RES_MEM(EXYNOS4_PA_OHCI, SZ_256),
[1] = DEFINE_RES_IRQ(IRQ_USB_HOST),
};

static u64 exynos4_ohci_dma_mask = DMA_BIT_MASK(32);

struct platform_device exynos4_device_ohci = {
.name = "exynos-ohci",
.id = -1,
.num_resources = ARRAY_SIZE(exynos4_ohci_resource),
.resource = exynos4_ohci_resource,
.dev = {
.dma_mask = &exynos4_ohci_dma_mask,
.coherent_dma_mask = DMA_BIT_MASK(32),
}
};

void __init exynos4_ohci_set_platdata(struct exynos4_ohci_platdata *pd)
{
struct exynos4_ohci_platdata *npd;

npd = s3c_set_platdata(pd, sizeof(struct exynos4_ohci_platdata),
&exynos4_device_ohci);

if (!npd->phy_init)
npd->phy_init = s5p_usb_phy_init;
if (!npd->phy_exit)
npd->phy_exit = s5p_usb_phy_exit;
}
1 change: 1 addition & 0 deletions arch/arm/mach-exynos/include/mach/map.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
#define EXYNOS4_PA_SROMC 0x12570000

#define EXYNOS4_PA_EHCI 0x12580000
#define EXYNOS4_PA_OHCI 0x12590000
#define EXYNOS4_PA_HSPHY 0x125B0000
#define EXYNOS4_PA_MFC 0x13400000

Expand Down
21 changes: 21 additions & 0 deletions arch/arm/mach-exynos/include/mach/ohci.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Copyright (C) 2011 Samsung Electronics Co.Ltd
* http://www.samsung.com/
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/

#ifndef __MACH_EXYNOS_OHCI_H
#define __MACH_EXYNOS_OHCI_H

struct exynos4_ohci_platdata {
int (*phy_init)(struct platform_device *pdev, int type);
int (*phy_exit)(struct platform_device *pdev, int type);
};

extern void exynos4_ohci_set_platdata(struct exynos4_ohci_platdata *pd);

#endif /* __MACH_EXYNOS_OHCI_H */
13 changes: 13 additions & 0 deletions arch/arm/mach-exynos/mach-origen.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#include <plat/fb.h>
#include <plat/mfc.h>

#include <mach/ohci.h>
#include <mach/map.h>

/* Following are default values for UCON, ULCON and UFCON UART registers */
Expand Down Expand Up @@ -483,6 +484,16 @@ static void __init origen_ehci_init(void)
s5p_ehci_set_platdata(pdata);
}

/* USB OHCI */
static struct exynos4_ohci_platdata origen_ohci_pdata;

static void __init origen_ohci_init(void)
{
struct exynos4_ohci_platdata *pdata = &origen_ohci_pdata;

exynos4_ohci_set_platdata(pdata);
}

static struct gpio_keys_button origen_gpio_keys_table[] = {
{
.code = KEY_MENU,
Expand Down Expand Up @@ -606,6 +617,7 @@ static struct platform_device *origen_devices[] __initdata = {
&s5p_device_mfc_l,
&s5p_device_mfc_r,
&s5p_device_mixer,
&exynos4_device_ohci,
&exynos4_device_pd[PD_LCD0],
&exynos4_device_pd[PD_TV],
&exynos4_device_pd[PD_G3D],
Expand Down Expand Up @@ -670,6 +682,7 @@ static void __init origen_machine_init(void)
s3c_sdhci0_set_platdata(&origen_hsmmc0_pdata);

origen_ehci_init();
origen_ohci_init();
clk_xusbxti.rate = 24000000;

s5p_tv_setup();
Expand Down
13 changes: 13 additions & 0 deletions arch/arm/mach-exynos/mach-smdkv310.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#include <plat/clock.h>

#include <mach/map.h>
#include <mach/ohci.h>

/* Following are default values for UCON, ULCON and UFCON UART registers */
#define SMDKV310_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
Expand Down Expand Up @@ -245,6 +246,16 @@ static void __init smdkv310_ehci_init(void)
s5p_ehci_set_platdata(pdata);
}

/* USB OHCI */
static struct exynos4_ohci_platdata smdkv310_ohci_pdata;

static void __init smdkv310_ohci_init(void)
{
struct exynos4_ohci_platdata *pdata = &smdkv310_ohci_pdata;

exynos4_ohci_set_platdata(pdata);
}

static struct platform_device *smdkv310_devices[] __initdata = {
&s3c_device_hsmmc0,
&s3c_device_hsmmc1,
Expand All @@ -261,6 +272,7 @@ static struct platform_device *smdkv310_devices[] __initdata = {
&s5p_device_fimc3,
&exynos4_device_ac97,
&exynos4_device_i2s0,
&exynos4_device_ohci,
&samsung_device_keypad,
&s5p_device_mfc,
&s5p_device_mfc_l,
Expand Down Expand Up @@ -363,6 +375,7 @@ static void __init smdkv310_machine_init(void)
s5p_fimd0_set_platdata(&smdkv310_lcd0_pdata);

smdkv310_ehci_init();
smdkv310_ohci_init();
clk_xusbxti.rate = 24000000;

platform_add_devices(smdkv310_devices, ARRAY_SIZE(smdkv310_devices));
Expand Down
15 changes: 15 additions & 0 deletions arch/arm/mach-exynos/setup-usb-phy.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@
#include <plat/cpu.h>
#include <plat/usb-phy.h>

static atomic_t host_usage;

static int exynos4_usb_host_phy_is_on(void)
{
return (readl(EXYNOS4_PHYPWR) & PHY1_STD_ANALOG_POWERDOWN) ? 0 : 1;
}

static int exynos4_usb_phy1_init(struct platform_device *pdev)
{
struct clk *otg_clk;
Expand All @@ -27,6 +34,8 @@ static int exynos4_usb_phy1_init(struct platform_device *pdev)
u32 rstcon;
int err;

atomic_inc(&host_usage);

otg_clk = clk_get(&pdev->dev, "otg");
if (IS_ERR(otg_clk)) {
dev_err(&pdev->dev, "Failed to get otg clock\n");
Expand All @@ -39,6 +48,9 @@ static int exynos4_usb_phy1_init(struct platform_device *pdev)
return err;
}

if (exynos4_usb_host_phy_is_on())
return 0;

writel(readl(S5P_USBHOST_PHY_CONTROL) | S5P_USBHOST_PHY_ENABLE,
S5P_USBHOST_PHY_CONTROL);

Expand Down Expand Up @@ -95,6 +107,9 @@ static int exynos4_usb_phy1_exit(struct platform_device *pdev)
struct clk *otg_clk;
int err;

if (atomic_dec_return(&host_usage) > 0)
return 0;

otg_clk = clk_get(&pdev->dev, "otg");
if (IS_ERR(otg_clk)) {
dev_err(&pdev->dev, "Failed to get otg clock\n");
Expand Down
1 change: 1 addition & 0 deletions arch/arm/plat-samsung/include/plat/devs.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ extern struct platform_device exynos4_device_dwmci;
extern struct platform_device exynos4_device_i2s0;
extern struct platform_device exynos4_device_i2s1;
extern struct platform_device exynos4_device_i2s2;
extern struct platform_device exynos4_device_ohci;
extern struct platform_device exynos4_device_pcm0;
extern struct platform_device exynos4_device_pcm1;
extern struct platform_device exynos4_device_pcm2;
Expand Down
1 change: 1 addition & 0 deletions drivers/usb/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ config USB_ARCH_HAS_OHCI
default y if ARCH_DAVINCI_DA8XX
default y if ARCH_CNS3XXX
default y if PLAT_SPEAR
default y if ARCH_EXYNOS
# PPC:
default y if STB03xxx
default y if PPC_MPC52xx
Expand Down
6 changes: 6 additions & 0 deletions drivers/usb/host/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,12 @@ config USB_OHCI_SH
Enables support for the on-chip OHCI controller on the SuperH.
If you use the PCI OHCI controller, this option is not necessary.

config USB_OHCI_EXYNOS
boolean "OHCI support for Samsung EXYNOS SoC Series"
depends on USB_OHCI_HCD && ARCH_EXYNOS
help
Enable support for the Samsung Exynos SOC's on-chip OHCI controller.

config USB_CNS3XXX_OHCI
bool "Cavium CNS3XXX OHCI Module"
depends on USB_OHCI_HCD && ARCH_CNS3XXX
Expand Down
Loading

0 comments on commit e814fb6

Please sign in to comment.