9
0
Fork 0

Merge branch 'pu/usb' into for-next/imx

Conflicts:
	arch/arm/mach-imx/include/mach/devices-imx31.h
This commit is contained in:
Sascha Hauer 2012-12-17 08:45:49 +01:00
commit 40bd757243
34 changed files with 775 additions and 122 deletions

View File

@ -21,34 +21,12 @@
#include <mach/weim.h>
#include <mach/gpio.h>
#include <mach/devices-imx27.h>
#include <usb/ulpi.h>
#include <usb/chipidea-imx.h>
#define GPIO_IDE_POWER (GPIO_PORTE + 18)
#define GPIO_IDE_PCOE (GPIO_PORTF + 7)
#define GPIO_IDE_RESET (GPIO_PORTF + 10)
#ifdef CONFIG_USB
static void pcm970_usbh2_init(void)
{
uint32_t temp;
temp = readl(MX27_USB_OTG_BASE_ADDR + 0x600);
temp &= ~((3 << 21) | 1);
temp |= (1 << 5) | (1 << 16) | (1 << 19) | (1 << 20);
writel(temp, MX27_USB_OTG_BASE_ADDR + 0x600);
temp = readl(MX27_USB_OTG_BASE_ADDR + 0x584);
temp &= ~(3 << 30);
temp |= 2 << 30;
writel(temp, MX27_USB_OTG_BASE_ADDR + 0x584);
mdelay(10);
if (!ulpi_setup((void *)(MX27_USB_OTG_BASE_ADDR + 0x570), 1))
add_generic_usb_ehci_device(DEVICE_ID_DYNAMIC, MX27_USB_OTG_BASE_ADDR + 0x400, NULL);
}
#endif
#ifdef CONFIG_DISK_INTF_PLATFORM_IDE
static struct resource pcm970_ide_resources[] = {
{
@ -168,6 +146,11 @@ static void pcm970_mmc_init(void)
imx27_add_mmc1(NULL);
}
struct imxusb_platformdata pcm970_usbh2_pdata = {
.flags = MXC_EHCI_MODE_ULPI | MXC_EHCI_INTERFACE_DIFF_UNI,
.mode = IMX_USB_MODE_HOST,
};
static int pcm970_init(void)
{
int i;
@ -177,7 +160,7 @@ static int pcm970_init(void)
PA1_PF_USBH2_DIR,
PA2_PF_USBH2_DATA7,
PA3_PF_USBH2_NXT,
PA4_PF_USBH2_STP,
4 | GPIO_PORTA | GPIO_GPIO | GPIO_OUT,
PD19_AF_USBH2_DATA4,
PD20_AF_USBH2_DATA3,
PD21_AF_USBH2_DATA6,
@ -193,9 +176,14 @@ static int pcm970_init(void)
/* Configure SJA1000 on cs4 */
imx27_setup_weimcs(4, 0x0000DCF6, 0x444A0301, 0x44443302);
#ifdef CONFIG_USB
pcm970_usbh2_init();
#endif
if (IS_ENABLED(CONFIG_USB)) {
/* Stop ULPI */
gpio_direction_output(4, 1);
mdelay(1);
imx_gpio_mode(PA4_PF_USBH2_STP);
imx27_add_usbh2(&pcm970_usbh2_pdata);
}
#ifdef CONFIG_DISK_INTF_PLATFORM_IDE
pcm970_ide_init();

View File

@ -2,7 +2,6 @@ CONFIG_ARCH_IMX=y
CONFIG_ARCH_IMX_EXTERNAL_BOOT_NAND=y
CONFIG_ARCH_IMX27=y
CONFIG_MACH_PCM038=y
CONFIG_IMX_CLKO=y
CONFIG_AEABI=y
CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
CONFIG_ARM_UNWIND=y
@ -16,8 +15,6 @@ CONFIG_HUSH_FANCY_PROMPT=y
CONFIG_CMDLINE_EDITING=y
CONFIG_AUTO_COMPLETE=y
CONFIG_MENU=y
CONFIG_PARTITION=y
CONFIG_PARTITION_DISK=y
CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y
CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/pcm038/env"
CONFIG_CMD_EDIT=y
@ -32,7 +29,6 @@ CONFIG_CMD_TIME=y
CONFIG_CMD_ECHO_E=y
CONFIG_CMD_MEMINFO=y
CONFIG_CMD_IOMEM=y
CONFIG_CMD_MTEST=y
CONFIG_CMD_FLASH=y
CONFIG_CMD_BOOTM_SHOW_TYPE=y
CONFIG_CMD_BOOTM_VERBOSE=y
@ -40,16 +36,16 @@ CONFIG_CMD_BOOTM_INITRD=y
CONFIG_CMD_BOOTM_OFTREE=y
CONFIG_CMD_BOOTM_OFTREE_UIMAGE=y
CONFIG_CMD_UIMAGE=y
# CONFIG_CMD_BOOTZ is not set
# CONFIG_CMD_BOOTU is not set
CONFIG_CMD_RESET=y
CONFIG_CMD_GO=y
CONFIG_CMD_OFTREE=y
CONFIG_CMD_MTEST=y
CONFIG_CMD_SPLASH=y
CONFIG_CMD_TIMEOUT=y
CONFIG_CMD_PARTITION=y
CONFIG_CMD_MAGICVAR=y
CONFIG_CMD_MAGICVAR_HELP=y
CONFIG_CMD_SPLASH=y
CONFIG_CMD_GPIO=y
CONFIG_CMD_UNCOMPRESS=y
CONFIG_NET=y
@ -68,8 +64,10 @@ CONFIG_NAND=y
# CONFIG_NAND_ECC_HW_SYNDROME is not set
CONFIG_NAND_IMX=y
CONFIG_USB=y
CONFIG_USB_IMX_CHIPIDEA=y
CONFIG_USB_EHCI=y
CONFIG_USB_ULPI=y
CONFIG_USB_STORAGE=y
CONFIG_VIDEO=y
CONFIG_DRIVER_VIDEO_IMX=y
CONFIG_IMXFB_DRIVER_VIDEO_IMX_OVERLAY=y

View File

@ -72,3 +72,8 @@ struct device_d *imx_add_pata(void *base)
{
return imx_add_device("imx-pata", -1, base, 0x1000, NULL);
}
struct device_d *imx_add_usb(void *base, int id, struct imxusb_platformdata *pdata)
{
return imx_add_device("imx-usb", id, base, 0x200, pdata);
}

View File

@ -118,6 +118,7 @@ static int imx27_init(void)
add_generic_device("imx1-gpio", 5, NULL, MX27_GPIO6_BASE_ADDR, 0x100, IORESOURCE_MEM, NULL);
add_generic_device("imx21-wdt", 0, NULL, MX27_WDOG_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
add_generic_device("imx27-esdctl", 0, NULL, MX27_ESDCTL_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
add_generic_device("imx27-usb-misc", 0, NULL, MX27_USB_OTG_BASE_ADDR + 0x600, 0x100, IORESOURCE_MEM, NULL);
return 0;
}

View File

@ -39,6 +39,7 @@ static int imx31_init(void)
add_generic_device("imx31-gpio", 2, NULL, MX31_GPIO3_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
add_generic_device("imx21-wdt", 0, NULL, MX31_WDOG_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
add_generic_device("imx31-esdctl", 0, NULL, MX31_ESDCTL_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
add_generic_device("imx31-usb-misc", 0, NULL, MX31_USB_OTG_BASE_ADDR + 0x600, 0x100, IORESOURCE_MEM, NULL);
return 0;
}

View File

@ -70,6 +70,7 @@ static int imx51_init(void)
add_generic_device("imx31-gpio", 3, NULL, MX51_GPIO4_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
add_generic_device("imx21-wdt", 0, NULL, MX51_WDOG_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
add_generic_device("imx51-esdctl", 0, NULL, MX51_ESDCTL_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
add_generic_device("imx51-usb-misc", 0, NULL, MX51_OTG_BASE_ADDR + 0x800, 0x100, IORESOURCE_MEM, NULL);
return 0;
}

View File

@ -70,3 +70,18 @@ static inline struct device_d *imx27_add_mmc2(void *pdata)
{
return imx_add_mmc((void *)MX27_SDHC3_BASE_ADDR, 2, pdata);
}
static inline struct device_d *imx27_add_usbotg(void *pdata)
{
return imx_add_usb((void *)MX27_USB_OTG_BASE_ADDR, 0, pdata);
}
static inline struct device_d *imx27_add_usbh1(void *pdata)
{
return imx_add_usb((void *)MX27_USB_OTG_BASE_ADDR + 0x200, 1, pdata);
}
static inline struct device_d *imx27_add_usbh2(void *pdata)
{
return imx_add_usb((void *)MX27_USB_OTG_BASE_ADDR + 0x400, 2, pdata);
}

View File

@ -61,3 +61,18 @@ static inline struct device_d *imx31_add_mmc1(void *pdata)
{
return imx_add_mmc((void *)MX31_SDHC2_BASE_ADDR, 1, pdata);
}
static inline struct device_d *imx31_add_usbotg(void *pdata)
{
return imx_add_usb((void *)MX31_USB_OTG_BASE_ADDR, 0, pdata);
}
static inline struct device_d *imx31_add_usbh1(void *pdata)
{
return imx_add_usb((void *)MX31_USB_OTG_BASE_ADDR + 0x200, 1, pdata);
}
static inline struct device_d *imx31_add_usbh2(void *pdata)
{
return imx_add_usb((void *)MX31_USB_OTG_BASE_ADDR + 0x400, 2, pdata);
}

View File

@ -98,3 +98,18 @@ static inline struct device_d *imx51_add_pata(void)
{
return imx_add_pata((void *)MX51_ATA_BASE_ADDR);
}
static inline struct device_d *imx51_add_usbotg(void *pdata)
{
return imx_add_usb((void *)MX51_OTG_BASE_ADDR, 0, pdata);
}
static inline struct device_d *imx51_add_usbh1(void *pdata)
{
return imx_add_usb((void *)MX51_OTG_BASE_ADDR + 0x200, 1, pdata);
}
static inline struct device_d *imx51_add_usbh2(void *pdata)
{
return imx_add_usb((void *)MX51_OTG_BASE_ADDR + 0x400, 2, pdata);
}

View File

@ -7,6 +7,7 @@
#include <mach/imxfb.h>
#include <mach/imx-ipu-fb.h>
#include <mach/esdhc.h>
#include <usb/chipidea-imx.h>
struct device_d *imx_add_fec_imx27(void *base, struct fec_platform_data *pdata);
struct device_d *imx_add_fec_imx6(void *base, struct fec_platform_data *pdata);
@ -21,3 +22,4 @@ struct device_d *imx_add_mmc(void *base, int id, void *pdata);
struct device_d *imx_add_esdhc(void *base, int id, struct esdhc_platform_data *pdata);
struct device_d *imx_add_kpp(void *base, struct matrix_keymap_data *pdata);
struct device_d *imx_add_pata(void *base);
struct device_d *imx_add_usb(void *base, int id, struct imxusb_platformdata *pdata);

View File

@ -151,7 +151,7 @@ int console_register(struct console_device *newcdev)
dev->id = DEVICE_ID_DYNAMIC;
strcpy(dev->name, "cs");
if (newcdev->dev)
dev_add_child(newcdev->dev, dev);
dev->parent = newcdev->dev;
platform_device_register(dev);
if (newcdev->setbrg) {

View File

@ -133,20 +133,20 @@ int register_device(struct device_d *new_device)
INIT_LIST_HEAD(&new_device->parameters);
INIT_LIST_HEAD(&new_device->active);
if (!new_device->bus)
return 0;
if (new_device->bus) {
if (!new_device->parent)
new_device->parent = &new_device->bus->dev;
if (!new_device->parent) {
new_device->parent = &new_device->bus->dev;
dev_add_child(new_device->parent, new_device);
list_add_tail(&new_device->bus_list, &new_device->bus->device_list);
bus_for_each_driver(new_device->bus, drv) {
if (!match(drv, new_device))
break;
}
}
list_add_tail(&new_device->bus_list, &new_device->bus->device_list);
bus_for_each_driver(new_device->bus, drv) {
if (!match(drv, new_device))
break;
}
if (new_device->parent)
list_add_tail(&new_device->sibling, &new_device->parent->children);
return 0;
}
@ -186,16 +186,6 @@ int unregister_device(struct device_d *old_dev)
}
EXPORT_SYMBOL(unregister_device);
int dev_add_child(struct device_d *dev, struct device_d *child)
{
child->parent = dev;
list_add_tail(&child->sibling, &dev->children);
return 0;
}
EXPORT_SYMBOL(dev_add_child);
struct driver_d *get_driver_by_name(const char *name)
{
struct driver_d *drv;

View File

@ -258,7 +258,6 @@ struct i2c_client *i2c_new_device(struct i2c_adapter *adapter,
client->addr = chip->addr;
client->dev.parent = &adapter->dev;
dev_add_child(client->dev.parent, &client->dev);
status = register_device(&client->dev);
@ -403,9 +402,6 @@ int i2c_add_numbered_adapter(struct i2c_adapter *adapter)
adapter->dev.id = adapter->nr;
strcpy(adapter->dev.name, "i2c");
if (adapter->dev.parent)
dev_add_child(adapter->dev.parent, &adapter->dev);
ret = register_device(&adapter->dev);
if (ret)
return ret;

View File

@ -1557,7 +1557,7 @@ int mci_register(struct mci_host *host)
mci_dev->id = DEVICE_ID_DYNAMIC;
strcpy(mci_dev->name, mci_driver.name);
mci_dev->platform_data = host;
dev_add_child(host->hw_dev, mci_dev);
mci_dev->parent = host->hw_dev;
return platform_device_register(mci_dev);
}

View File

@ -184,10 +184,8 @@ int add_mtd_device(struct mtd_info *mtd, char *devname)
devname = "mtd";
strcpy(mtd->class_dev.name, devname);
mtd->class_dev.id = DEVICE_ID_DYNAMIC;
if (mtd->parent) {
if (mtd->parent)
mtd->class_dev.parent = mtd->parent;
dev_add_child(mtd->class_dev.parent, &mtd->class_dev);
}
register_device(&mtd->class_dev);
mtd->cdev.ops = &mtd_ops;

View File

@ -47,8 +47,6 @@ int mdiobus_register(struct mii_bus *bus)
bus->dev.id = DEVICE_ID_DYNAMIC;
strcpy(bus->dev.name, "miibus");
bus->dev.parent = bus->parent;
if (bus->parent)
dev_add_child(bus->parent, &bus->dev);
err = register_device(&bus->dev);
if (err) {
@ -157,8 +155,6 @@ static int mdio_bus_probe(struct device_d *_dev)
char str[16];
dev->attached_dev->phydev = dev;
dev->dev.parent = &dev->attached_dev->dev;
dev_add_child(dev->dev.parent, _dev);
if (drv->probe) {
ret = drv->probe(dev);

View File

@ -157,7 +157,6 @@ static struct phy_device *phy_device_create(struct mii_bus *bus, int addr, int p
dev->phy_id = phy_id;
dev->bus = bus;
dev->dev.parent = bus->parent;
dev->dev.bus = &mdio_bus_type;
strcpy(dev->dev.name, "phy");
@ -229,6 +228,8 @@ static int phy_register_device(struct phy_device* dev)
{
int ret;
dev->dev.parent = &dev->attached_dev->dev;
ret = register_device(&dev->dev);
if (ret)
return ret;
@ -400,11 +401,14 @@ int genphy_setup_forced(struct phy_device *phydev)
return err;
}
static int phy_aneg_done(struct phy_device *phydev)
int phy_wait_aneg_done(struct phy_device *phydev)
{
uint64_t start = get_time_ns();
int ctl;
if (phydev->autoneg == AUTONEG_DISABLE)
return 0;
while (!is_timeout(start, PHY_AN_TIMEOUT * SECOND)) {
ctl = phy_read(phydev, MII_BMSR);
if (ctl & BMSR_ANEGCOMPLETE) {
@ -451,7 +455,7 @@ int genphy_restart_aneg(struct phy_device *phydev)
if (ctl < 0)
return ctl;
return phy_aneg_done(phydev);
return 0;
}
/**

View File

@ -81,7 +81,7 @@ struct spi_device *spi_new_device(struct spi_master *master,
proxy->dev.id = DEVICE_ID_DYNAMIC;
proxy->dev.type_data = proxy;
proxy->dev.device_node = chip->device_node;
dev_add_child(master->dev, &proxy->dev);
proxy->dev.parent = master->dev;
/* drivers may modify this initial i/o setup */
status = master->setup(proxy);

View File

@ -3,6 +3,8 @@ menuconfig USB
if USB
source drivers/usb/imx/Kconfig
source drivers/usb/host/Kconfig
source drivers/usb/otg/Kconfig

View File

@ -1,4 +1,5 @@
obj-$(CONFIG_USB) += core/
obj-$(CONFIG_USB_IMX_CHIPIDEA) += imx/
obj-$(CONFIG_USB_GADGET) += gadget/
obj-$(CONFIG_USB_STORAGE) += storage/
obj-y += host/

View File

@ -807,32 +807,18 @@ submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
return -1;
}
static int ehci_probe(struct device_d *dev)
int ehci_register(struct device_d *dev, struct ehci_data *data)
{
struct usb_host *host;
struct ehci_priv *ehci;
uint32_t reg;
struct ehci_platform_data *pdata = dev->platform_data;
ehci = xzalloc(sizeof(struct ehci_priv));
host = &ehci->host;
dev->priv = ehci;
/* default to EHCI_HAS_TT to not change behaviour of boards
* without platform_data
*/
if (pdata)
ehci->flags = pdata->flags;
else
ehci->flags = EHCI_HAS_TT;
if (dev->num_resources < 2) {
printf("echi: need 2 resources base and data");
return -ENODEV;
}
ehci->hccr = dev_request_mem_region(dev, 0);
ehci->hcor = dev_request_mem_region(dev, 1);
ehci->flags = data->flags;
ehci->hccr = data->hccr;
ehci->hcor = data->hcor;
ehci->qh_list = dma_alloc_coherent(sizeof(struct QH) * NUM_TD);
ehci->td = dma_alloc_coherent(sizeof(struct qTD) * NUM_TD);
@ -854,6 +840,30 @@ static int ehci_probe(struct device_d *dev)
return 0;
}
static int ehci_probe(struct device_d *dev)
{
struct ehci_data data;
struct ehci_platform_data *pdata = dev->platform_data;
/* default to EHCI_HAS_TT to not change behaviour of boards
* without platform_data
*/
if (pdata)
data.flags = pdata->flags;
else
data.flags = EHCI_HAS_TT;
if (dev->num_resources < 2) {
printf("echi: need 2 resources base and data");
return -ENODEV;
}
data.hccr = dev_request_mem_region(dev, 0);
data.hcor = dev_request_mem_region(dev, 1);
return ehci_register(dev, &data);
}
static void ehci_remove(struct device_d *dev)
{
struct ehci_priv *ehci = dev->priv;

15
drivers/usb/imx/Kconfig Normal file
View File

@ -0,0 +1,15 @@
config USB_IMX_CHIPIDEA
bool "i.MX USB support (read help)"
depends on ARCH_IMX
help
The Freescale i.MX SoCs have a variant of the chipidea ci13xxx for
USB support. Traditionally in barebox this is supported through the
EHCI driver for USB host and the ARC USB gadget driver for device.
This option instead enables support for i.MX chipidea support which
acts as a toplevel driver for the i.MX USB support. The chipidea
support also configures the usbmisc registers which traditionally
are configured in the board file.
This driver is recommended for new designs, but it needs board
support to work.
It's safe to say yes here. Also select EHCI support for USB host.

1
drivers/usb/imx/Makefile Normal file
View File

@ -0,0 +1 @@
obj-$(CONFIG_USB_IMX_CHIPIDEA) += imx-usb-misc.o chipidea-imx.o

View File

@ -0,0 +1,91 @@
/*
* Copyright (c) 2012 Sascha Hauer <s.hauer@pengutronix.de>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include <common.h>
#include <init.h>
#include <io.h>
#include <driver.h>
#include <usb/ehci.h>
#include <usb/chipidea-imx.h>
#include <usb/ulpi.h>
#define MXC_EHCI_PORTSC_MASK (0xf << 28)
static int imx_chipidea_probe(struct device_d *dev)
{
struct imxusb_platformdata *pdata = dev->platform_data;
int ret;
void __iomem *base;
struct ehci_data data;
uint32_t portsc;
if (!pdata) {
dev_err(dev, "no pdata!\n");
return -EINVAL;
}
base = dev_request_mem_region(dev, 0);
if (!base)
return -ENODEV;
portsc = readl(base + 0x184);
portsc &= ~MXC_EHCI_PORTSC_MASK;
portsc |= pdata->flags & MXC_EHCI_PORTSC_MASK;
writel(portsc, base + 0x184);
ret = imx_usbmisc_port_init(dev->id, pdata->flags);
if (ret) {
dev_err(dev, "failed to init misc regs: %s\n", strerror(-ret));
return ret;
}
if ((pdata->flags & MXC_EHCI_PORTSC_MASK) == MXC_EHCI_MODE_ULPI) {
dev_dbg(dev, "using ULPI phy\n");
if (IS_ENABLED(CONFIG_USB_ULPI)) {
ret = ulpi_setup(base + 0x170, 1);
} else {
dev_err(dev, "no ULPI support available\n");
ret = -ENODEV;
}
if (ret)
return ret;
}
data.hccr = base + 0x100;
data.hcor = base + 0x140;
data.flags = EHCI_HAS_TT;
if (pdata->mode == IMX_USB_MODE_HOST) {
ret = ehci_register(dev, &data);
} else {
/*
* Not yet implemented. Register USB gadget driver here.
*/
ret = -ENOSYS;
}
return ret;
};
static struct driver_d imx_chipidea_driver = {
.name = "imx-usb",
.probe = imx_chipidea_probe,
};
static int imx_chipidea_init(void)
{
return platform_driver_register(&imx_chipidea_driver);
}
device_initcall(imx_chipidea_init);

View File

@ -0,0 +1,410 @@
/*
* Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
* Copyright (C) 2010 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include <common.h>
#include <init.h>
#include <io.h>
#include <usb/chipidea-imx.h>
#define MX25_OTG_SIC_SHIFT 29
#define MX25_OTG_SIC_MASK (0x3 << MX25_OTG_SIC_SHIFT)
#define MX25_OTG_PM_BIT (1 << 24)
#define MX25_OTG_PP_BIT (1 << 11)
#define MX25_OTG_OCPOL_BIT (1 << 3)
#define MX25_H1_SIC_SHIFT 21
#define MX25_H1_SIC_MASK (0x3 << MX25_H1_SIC_SHIFT)
#define MX25_H1_PP_BIT (1 << 18)
#define MX25_H1_PM_BIT (1 << 8)
#define MX25_H1_IPPUE_UP_BIT (1 << 7)
#define MX25_H1_IPPUE_DOWN_BIT (1 << 6)
#define MX25_H1_TLL_BIT (1 << 5)
#define MX25_H1_USBTE_BIT (1 << 4)
#define MX25_H1_OCPOL_BIT (1 << 2)
static __maybe_unused int mx25_initialize_usb_hw(void __iomem *base, int port, unsigned int flags)
{
unsigned int v;
v = readl(base);
switch (port) {
case 0: /* OTG port */
v &= ~(MX25_OTG_SIC_MASK | MX25_OTG_PM_BIT | MX25_OTG_PP_BIT |
MX25_OTG_OCPOL_BIT);
v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX25_OTG_SIC_SHIFT;
if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
v |= MX25_OTG_PM_BIT;
if (flags & MXC_EHCI_PWR_PIN_ACTIVE_HIGH)
v |= MX25_OTG_PP_BIT;
if (!(flags & MXC_EHCI_OC_PIN_ACTIVE_LOW))
v |= MX25_OTG_OCPOL_BIT;
break;
case 1: /* H1 port */
v &= ~(MX25_H1_SIC_MASK | MX25_H1_PM_BIT | MX25_H1_PP_BIT |
MX25_H1_OCPOL_BIT | MX25_H1_TLL_BIT | MX25_H1_USBTE_BIT |
MX25_H1_IPPUE_DOWN_BIT | MX25_H1_IPPUE_UP_BIT);
v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX25_H1_SIC_SHIFT;
if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
v |= MX25_H1_PM_BIT;
if (flags & MXC_EHCI_PWR_PIN_ACTIVE_HIGH)
v |= MX25_H1_PP_BIT;
if (!(flags & MXC_EHCI_OC_PIN_ACTIVE_LOW))
v |= MX25_H1_OCPOL_BIT;
if (!(flags & MXC_EHCI_TLL_ENABLED))
v |= MX25_H1_TLL_BIT;
if (flags & MXC_EHCI_INTERNAL_PHY)
v |= MX25_H1_USBTE_BIT;
if (flags & MXC_EHCI_IPPUE_DOWN)
v |= MX25_H1_IPPUE_DOWN_BIT;
if (flags & MXC_EHCI_IPPUE_UP)
v |= MX25_H1_IPPUE_UP_BIT;
break;
default:
return -EINVAL;
}
writel(v, base);
return 0;
}
#define MX27_OTG_SIC_SHIFT 29
#define MX27_OTG_SIC_MASK (0x3 << MX27_OTG_SIC_SHIFT)
#define MX27_OTG_PM_BIT (1 << 24)
#define MX27_H2_SIC_SHIFT 21
#define MX27_H2_SIC_MASK (0x3 << MX27_H2_SIC_SHIFT)
#define MX27_H2_PM_BIT (1 << 16)
#define MX27_H2_DT_BIT (1 << 5)
#define MX27_H1_SIC_SHIFT 13
#define MX27_H1_SIC_MASK (0x3 << MX27_H1_SIC_SHIFT)
#define MX27_H1_PM_BIT (1 << 8)
#define MX27_H1_DT_BIT (1 << 4)
static __maybe_unused int mx27_mx31_initialize_usb_hw(void __iomem *base, int port, unsigned int flags)
{
unsigned int v;
v = readl(base);
switch (port) {
case 0: /* OTG port */
v &= ~(MX27_OTG_SIC_MASK | MX27_OTG_PM_BIT);
v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX27_OTG_SIC_SHIFT;
if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
v |= MX27_OTG_PM_BIT;
break;
case 1: /* H1 port */
v &= ~(MX27_H1_SIC_MASK | MX27_H1_PM_BIT | MX27_H1_DT_BIT);
v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX27_H1_SIC_SHIFT;
if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
v |= MX27_H1_PM_BIT;
if (!(flags & MXC_EHCI_TLL_ENABLED))
v |= MX27_H1_DT_BIT;
break;
case 2: /* H2 port */
v &= ~(MX27_H2_SIC_MASK | MX27_H2_PM_BIT | MX27_H2_DT_BIT);
v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX27_H2_SIC_SHIFT;
if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
v |= MX27_H2_PM_BIT;
if (!(flags & MXC_EHCI_TLL_ENABLED))
v |= MX27_H2_DT_BIT;
break;
default:
return -EINVAL;
}
writel(v, base);
return 0;
}
#define USBCTRL_OTGBASE_OFFSET 0x600
#define MX35_OTG_SIC_SHIFT 29
#define MX35_OTG_SIC_MASK (0x3 << MX35_OTG_SIC_SHIFT)
#define MX35_OTG_PM_BIT (1 << 24)
#define MX35_OTG_PP_BIT (1 << 11)
#define MX35_OTG_OCPOL_BIT (1 << 3)
#define MX35_H1_SIC_SHIFT 21
#define MX35_H1_SIC_MASK (0x3 << MX35_H1_SIC_SHIFT)
#define MX35_H1_PP_BIT (1 << 18)
#define MX35_H1_PM_BIT (1 << 8)
#define MX35_H1_IPPUE_UP_BIT (1 << 7)
#define MX35_H1_IPPUE_DOWN_BIT (1 << 6)
#define MX35_H1_TLL_BIT (1 << 5)
#define MX35_H1_USBTE_BIT (1 << 4)
#define MX35_H1_OCPOL_BIT (1 << 2)
static __maybe_unused int mx35_initialize_usb_hw(void __iomem *base, int port, unsigned int flags)
{
unsigned int v;
v = readl(base);
switch (port) {
case 0: /* OTG port */
v &= ~(MX35_OTG_SIC_MASK | MX35_OTG_PM_BIT | MX35_OTG_PP_BIT |
MX35_OTG_OCPOL_BIT);
v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX35_OTG_SIC_SHIFT;
if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
v |= MX35_OTG_PM_BIT;
if (flags & MXC_EHCI_PWR_PIN_ACTIVE_HIGH)
v |= MX35_OTG_PP_BIT;
if (!(flags & MXC_EHCI_OC_PIN_ACTIVE_LOW))
v |= MX35_OTG_OCPOL_BIT;
break;
case 1: /* H1 port */
v &= ~(MX35_H1_SIC_MASK | MX35_H1_PM_BIT | MX35_H1_PP_BIT |
MX35_H1_OCPOL_BIT | MX35_H1_TLL_BIT | MX35_H1_USBTE_BIT |
MX35_H1_IPPUE_DOWN_BIT | MX35_H1_IPPUE_UP_BIT);
v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX35_H1_SIC_SHIFT;
if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
v |= MX35_H1_PM_BIT;
if (flags & MXC_EHCI_PWR_PIN_ACTIVE_HIGH)
v |= MX35_H1_PP_BIT;
if (!(flags & MXC_EHCI_OC_PIN_ACTIVE_LOW))
v |= MX35_H1_OCPOL_BIT;
if (!(flags & MXC_EHCI_TLL_ENABLED))
v |= MX35_H1_TLL_BIT;
if (flags & MXC_EHCI_INTERNAL_PHY)
v |= MX35_H1_USBTE_BIT;
if (flags & MXC_EHCI_IPPUE_DOWN)
v |= MX35_H1_IPPUE_DOWN_BIT;
if (flags & MXC_EHCI_IPPUE_UP)
v |= MX35_H1_IPPUE_UP_BIT;
break;
default:
return -EINVAL;
}
writel(v, base);
return 0;
}
/* USB_CTRL */
#define MX5_OTG_UCTRL_OWIE_BIT (1 << 27) /* OTG wakeup intr enable */
#define MX5_OTG_UCTRL_OPM_BIT (1 << 24) /* OTG power mask */
#define MX5_H1_UCTRL_H1UIE_BIT (1 << 12) /* Host1 ULPI interrupt enable */
#define MX5_H1_UCTRL_H1WIE_BIT (1 << 11) /* HOST1 wakeup intr enable */
#define MX5_H1_UCTRL_H1PM_BIT (1 << 8) /* HOST1 power mask */
/* USB_PHY_CTRL_FUNC */
#define MX5_OTG_PHYCTRL_OC_POL_BIT (1 << 9) /* OTG Polarity of Overcurrent */
#define MX5_OTG_PHYCTRL_OC_DIS_BIT (1 << 8) /* OTG Disable Overcurrent Event */
#define MX5_H1_OC_POL_BIT (1 << 6) /* UH1 Polarity of Overcurrent */
#define MX5_H1_OC_DIS_BIT (1 << 5) /* UH1 Disable Overcurrent Event */
#define MX5_OTG_PHYCTRL_PWR_POL_BIT (1 << 3) /* OTG Power Pin Polarity */
/* USBH2CTRL */
#define MX5_H2_UCTRL_H2UIE_BIT (1 << 8)
#define MX5_H2_UCTRL_H2WIE_BIT (1 << 7)
#define MX5_H2_UCTRL_H2PM_BIT (1 << 4)
#define MX5_USBCTRL_OFFSET 0x0
#define MX5_UTMI_PHY_CTRL_0 0x8
#define MX5_UTMI_PHY_CTRL_1 0xc
#define MX5_USBH2CTRL_OFFSET 0x14
static __maybe_unused int mx5_initialize_usb_hw(void __iomem *base, int port,
unsigned int flags)
{
unsigned int v;
switch (port) {
case 0: /* OTG port */
if (!(flags & MXC_EHCI_INTERNAL_PHY))
return 0;
/* Adjust UTMI PHY frequency to 24MHz */
v = readl(base + MX5_UTMI_PHY_CTRL_1);
v = (v & ~0x3) | 0x01;
writel(v, base + MX5_UTMI_PHY_CTRL_1);
v = readl(base + MX5_UTMI_PHY_CTRL_0);
v &= ~MX5_OTG_PHYCTRL_OC_POL_BIT;
v &= ~MX5_OTG_PHYCTRL_OC_DIS_BIT;
v &= ~MX5_OTG_PHYCTRL_PWR_POL_BIT;
if (flags & MXC_EHCI_OC_PIN_ACTIVE_LOW)
v |= MX5_OTG_PHYCTRL_OC_POL_BIT;
if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
v |= MX5_OTG_PHYCTRL_OC_DIS_BIT;
if (flags & MXC_EHCI_PWR_PIN_ACTIVE_HIGH)
v |= MX5_OTG_PHYCTRL_PWR_POL_BIT;
writel(v, base + MX5_UTMI_PHY_CTRL_0);
v = readl(base + MX5_USBCTRL_OFFSET);
v &= ~MX5_OTG_UCTRL_OWIE_BIT;
v &= ~MX5_OTG_UCTRL_OPM_BIT;
if (flags & MXC_EHCI_WAKEUP_ENABLED)
v |= MX5_OTG_UCTRL_OWIE_BIT;
if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
v |= MX5_OTG_UCTRL_OPM_BIT;
writel(v, base + MX5_USBCTRL_OFFSET);
break;
case 1: /* H1 port */
v = readl(base + MX5_USBCTRL_OFFSET);
v &= ~MX5_H1_UCTRL_H1PM_BIT;
if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
v |= MX5_H1_UCTRL_H1PM_BIT;
writel(v, base + MX5_USBCTRL_OFFSET);
break;
case 2: /* H2 port */
v = readl(base + MX5_USBH2CTRL_OFFSET);
v &= ~MX5_H2_UCTRL_H2PM_BIT;
if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
v |= MX5_H2_UCTRL_H2PM_BIT;
writel(v, base + MX5_USBH2CTRL_OFFSET);
break;
default:
return -EINVAL;
}
return 0;
}
static struct platform_device_id imx_usbmisc_ids[] = {
#ifdef CONFIG_ARCH_IMX25
{
.name = "imx25-usb-misc",
.driver_data = (unsigned long)&mx25_initialize_usb_hw,
},
#endif
#ifdef CONFIG_ARCH_IMX27
{
.name = "imx27-usb-misc",
.driver_data = (unsigned long)&mx27_mx31_initialize_usb_hw,
},
#endif
#ifdef CONFIG_ARCH_IMX31
{
.name = "imx31-usb-misc",
.driver_data = (unsigned long)&mx27_mx31_initialize_usb_hw,
},
#endif
#ifdef CONFIG_ARCH_IMX35
{
.name = "imx35-usb-misc",
.driver_data = (unsigned long)&mx35_initialize_usb_hw,
},
#endif
#ifdef CONFIG_ARCH_IMX51
{
.name = "imx51-usb-misc",
.driver_data = (unsigned long)&mx5_initialize_usb_hw,
},
#endif
#ifdef CONFIG_ARCH_IMX53
{
.name = "imx53-usb-misc",
.driver_data = (unsigned long)&mx5_initialize_usb_hw,
},
#endif
{
/* sentinel */
},
};
static int (*__imx_usbmisc_port_init)(void __iomem *base, int port, unsigned flags);
static void __iomem *usbmisc_base;
int imx_usbmisc_port_init(int port, unsigned flags)
{
if (!__imx_usbmisc_port_init)
return -ENODEV;
return __imx_usbmisc_port_init(usbmisc_base, port, flags);
}
static int imx_usbmisc_probe(struct device_d *dev)
{
struct imx_serial_devtype_data *devtype;
int ret;
ret = dev_get_drvdata(dev, (unsigned long *)&devtype);
if (ret)
return ret;
usbmisc_base = dev_request_mem_region(dev, 0);
if (!usbmisc_base)
return -ENOMEM;
__imx_usbmisc_port_init = (void *)devtype;
return 0;
}
static struct driver_d imx_usbmisc_driver = {
.name = "imx-usbmisc",
.probe = imx_usbmisc_probe,
.id_table = imx_usbmisc_ids,
};
static int imx_usbmisc_init(void)
{
platform_driver_register(&imx_usbmisc_driver);
return 0;
}
coredevice_initcall(imx_usbmisc_init);

View File

@ -111,6 +111,23 @@ int ulpi_clear(u8 bits, int reg, void __iomem *view)
}
EXPORT_SYMBOL(ulpi_clear);
int ulpi_write(u8 bits, int reg, void __iomem *view)
{
int ret;
writel((ULPIVW_RUN | ULPIVW_WRITE |
(reg << ULPIVW_ADDR_SHIFT) |
((bits & ULPIVW_WDATA_MASK) << ULPIVW_WDATA_SHIFT)),
view);
/* wait for completion */
ret = ulpi_poll(view, ULPIVW_RUN);
if (ret < 0)
return ret;
return 0;
}
EXPORT_SYMBOL(ulpi_write);
struct ulpi_info {
uint32_t id;
char *name;
@ -161,18 +178,18 @@ int ulpi_set_vbus(void __iomem *view, int on)
int ret;
if (on) {
ret = ulpi_set(DRV_VBUS_EXT | /* enable external Vbus */
DRV_VBUS | /* enable internal Vbus */
USE_EXT_VBUS_IND | /* use external indicator */
CHRG_VBUS, /* charge Vbus */
ret = ulpi_set(ULPI_OTG_DRV_VBUS_EXT | /* enable external Vbus */
ULPI_OTG_DRV_VBUS | /* enable internal Vbus */
ULPI_OTG_USE_EXT_VBUS_IND | /* use external indicator */
ULPI_OTG_CHRG_VBUS, /* charge Vbus */
ULPI_OTGCTL, view);
} else {
ret = ulpi_clear(DRV_VBUS_EXT | /* disable external Vbus */
DRV_VBUS, /* disable internal Vbus */
ret = ulpi_clear(ULPI_OTG_DRV_VBUS_EXT | /* disable external Vbus */
ULPI_OTG_DRV_VBUS, /* disable internal Vbus */
ULPI_OTGCTL, view);
ret |= ulpi_set(USE_EXT_VBUS_IND | /* use external indicator */
DISCHRG_VBUS, /* discharge Vbus */
ret |= ulpi_set(ULPI_OTG_USE_EXT_VBUS_IND | /* use external indicator */
ULPI_OTG_DISCHRG_VBUS, /* discharge Vbus */
ULPI_OTGCTL, view);
}

View File

@ -413,7 +413,6 @@ static int w1_device_register(struct w1_bus *bus, struct w1_device *dev)
dev->bus = bus;
dev->dev.parent = &bus->dev;
dev_add_child(dev->dev.parent, &dev->dev);
ret = register_device(&dev->dev);
if (ret)
@ -600,10 +599,7 @@ int w1_bus_register(struct w1_bus *bus)
strcpy(bus->dev.name, "w1_bus");
bus->dev.id = DEVICE_ID_DYNAMIC;
bus->dev.parent = bus->parent;
if (bus->parent)
dev_add_child(bus->parent, &bus->dev);
ret = register_device(&bus->dev);
if (ret)

10
fs/fs.c
View File

@ -1107,11 +1107,6 @@ static int fs_probe(struct device_d *dev)
if (ret)
return ret;
if (fsdev->cdev) {
dev_add_child(fsdev->cdev->dev, &fsdev->dev);
fsdev->parent_device = fsdev->cdev->dev;
}
fsdev->driver = fsdrv;
list_add_tail(&fsdev->list, &fs_device_list);
@ -1231,6 +1226,11 @@ int mount(const char *device, const char *fsname, const char *_path)
if (!strncmp(device, "/dev/", 5))
fsdev->cdev = cdev_by_name(device + 5);
if (fsdev->cdev) {
fsdev->dev.parent = fsdev->cdev->dev;
fsdev->parent_device = fsdev->cdev->dev;
}
ret = register_device(&fsdev->dev);
if (ret)
goto err_register;

View File

@ -158,11 +158,6 @@ int device_probe(struct device_d *dev);
*/
int unregister_device(struct device_d *);
/* Organize devices in a tree. These functions do _not_ register or
* unregister a device. Only registered devices are allowed here.
*/
int dev_add_child(struct device_d *dev, struct device_d *child);
/* Iterate over a devices children
*/
#define device_for_each_child(dev, child) \

View File

@ -267,6 +267,7 @@ int phy_device_connect(struct eth_device *dev, struct mii_bus *bus, int addr,
u32 flags, phy_interface_t interface);
int phy_update_status(struct phy_device *phydev);
int phy_wait_aneg_done(struct phy_device *phydev);
/* Generic PHY support and helper functions */
int genphy_restart_aneg(struct phy_device *phydev);

View File

@ -0,0 +1,46 @@
#ifndef __USB_CHIPIDEA_IMX_H
#define __USB_CHIPIDEA_IMX_H
/*
* POTSC flags
*/
#define MXC_EHCI_SERIAL (1 << 29)
#define MXC_EHCI_MODE_UTMI_8BIT (0 << 30)
#define MXC_EHCI_MODE_UTMI_16_BIT ((0 << 30) | (1 << 28))
#define MXC_EHCI_MODE_PHILIPS (1 << 30)
#define MXC_EHCI_MODE_ULPI (2 << 30)
#define MXC_EHCI_MODE_SERIAL (3 << 30)
/*
* USB misc flags
*/
#define MXC_EHCI_INTERFACE_DIFF_UNI (0 << 0)
#define MXC_EHCI_INTERFACE_DIFF_BI (1 << 0)
#define MXC_EHCI_INTERFACE_SINGLE_UNI (2 << 0)
#define MXC_EHCI_INTERFACE_SINGLE_BI (3 << 0)
#define MXC_EHCI_INTERFACE_MASK (0xf)
#define MXC_EHCI_POWER_PINS_ENABLED (1 << 5)
#define MXC_EHCI_PWR_PIN_ACTIVE_HIGH (1 << 6)
#define MXC_EHCI_OC_PIN_ACTIVE_LOW (1 << 7)
#define MXC_EHCI_TLL_ENABLED (1 << 8)
#define MXC_EHCI_INTERNAL_PHY (1 << 9)
#define MXC_EHCI_IPPUE_DOWN (1 << 10)
#define MXC_EHCI_IPPUE_UP (1 << 11)
#define MXC_EHCI_WAKEUP_ENABLED (1 << 12)
#define MXC_EHCI_ITC_NO_THRESHOLD (1 << 13)
enum imx_usb_mode {
IMX_USB_MODE_HOST,
IMX_USB_MODE_DEVICE,
};
struct imxusb_platformdata {
unsigned long flags;
enum imx_usb_mode mode;
};
int imx_usbmisc_port_init(int port, unsigned flags);
#endif /* __USB_CHIPIDEA_IMX_H */

View File

@ -5,8 +5,21 @@
struct ehci_platform_data {
unsigned long flags;
unsigned long hccr_offset;
unsigned long hcor_offset;
};
struct ehci_data {
void __iomem *hccr;
void __iomem *hcor;
unsigned long flags;
};
#ifdef CONFIG_USB_EHCI
int ehci_register(struct device_d *dev, struct ehci_data *data);
#else
static inline int ehci_register(struct device_d *dev, struct ehci_data *data)
{
return -ENOSYS;
}
#endif
#endif /* __USB_EHCI_H */

View File

@ -1,6 +1,7 @@
#ifndef __MACH_ULPI_H
#define __MACH_ULPI_H
int ulpi_write(u8 bits, int reg, void __iomem *view);
int ulpi_set(u8 bits, int reg, void __iomem *view);
int ulpi_clear(u8 bits, int reg, void __iomem *view);
int ulpi_read(int reg, void __iomem *view);
@ -11,6 +12,7 @@ int ulpi_setup(void __iomem *view, int on);
#define ULPI_VID_HIGH 0x01 /* Vendor ID high */
#define ULPI_PID_LOW 0x02 /* Product ID low */
#define ULPI_PID_HIGH 0x03 /* Product ID high */
#define ULPI_FUNCTION_CTRL 0x04
#define ULPI_ITFCTL 0x07 /* Interface Control */
#define ULPI_OTGCTL 0x0A /* OTG Control */
@ -18,15 +20,40 @@ int ulpi_setup(void __iomem *view, int on);
#define ULPI_REG_SET 0x01
#define ULPI_REG_CLEAR 0x02
/* Function Control */
#define ULPI_FC_XCVRSEL_MASK (3 << 0)
#define ULPI_FC_HIGH_SPEED (0 << 0)
#define ULPI_FC_FULL_SPEED (1 << 0)
#define ULPI_FC_LOW_SPEED (2 << 0)
#define ULPI_FC_FS4LS (3 << 0)
#define ULPI_FC_TERMSELECT (1 << 2)
#define ULPI_FC_OPMODE_MASK (3 << 3)
#define ULPI_FC_OPMODE_NORMAL (0 << 3)
#define ULPI_FC_OPMODE_NONDRIVING (1 << 3)
#define ULPI_FC_OPMODE_DISABLE_NRZI (2 << 3)
#define ULPI_FC_OPMODE_NOSYNC_NOEOP (3 << 3)
#define ULPI_FC_RESET (1 << 5)
#define ULPI_FC_SUSPENDM (1 << 6)
/* Interface Control */
#define ULPI_IFACE_6_PIN_SERIAL_MODE (1 << 0)
#define ULPI_IFACE_3_PIN_SERIAL_MODE (1 << 1)
#define ULPI_IFACE_CARKITMODE (1 << 2)
#define ULPI_IFACE_CLOCKSUSPENDM (1 << 3)
#define ULPI_IFACE_AUTORESUME (1 << 4)
#define ULPI_IFACE_EXTVBUS_COMPLEMENT (1 << 5)
#define ULPI_IFACE_PASSTHRU (1 << 6)
#define ULPI_IFACE_PROTECT_IFC_DISABLE (1 << 7)
/* ULPI OTG Control Register bits */
#define USE_EXT_VBUS_IND (1 << 7) /* Use ext. Vbus indicator */
#define DRV_VBUS_EXT (1 << 6) /* Drive Vbus external */
#define DRV_VBUS (1 << 5) /* Drive Vbus */
#define CHRG_VBUS (1 << 4) /* Charge Vbus */
#define DISCHRG_VBUS (1 << 3) /* Discharge Vbus */
#define DM_PULL_DOWN (1 << 2) /* enable DM Pull Down */
#define DP_PULL_DOWN (1 << 1) /* enable DP Pull Down */
#define ID_PULL_UP (1 << 0) /* enable ID Pull Up */
#define ULPI_OTG_USE_EXT_VBUS_IND (1 << 7) /* Use ext. Vbus indicator */
#define ULPI_OTG_DRV_VBUS_EXT (1 << 6) /* Drive Vbus external */
#define ULPI_OTG_DRV_VBUS (1 << 5) /* Drive Vbus */
#define ULPI_OTG_CHRG_VBUS (1 << 4) /* Charge Vbus */
#define ULPI_OTG_DISCHRG_VBUS (1 << 3) /* Discharge Vbus */
#define ULPI_OTG_DM_PULL_DOWN (1 << 2) /* enable DM Pull Down */
#define ULPI_OTG_DP_PULL_DOWN (1 << 1) /* enable DP Pull Down */
#define ULPI_OTG_ID_PULL_UP (1 << 0) /* enable ID Pull Up */
#endif /* __MACH_ULPI_H */

View File

@ -138,6 +138,9 @@ static int eth_carrier_check(int force)
if (!eth_current->phydev)
return 0;
if (force)
phy_wait_aneg_done(eth_current->phydev);
if (force || is_timeout(last_link_check, 5 * SECOND) ||
!eth_current->phydev->link) {
ret = phy_update_status(eth_current->phydev);
@ -260,7 +263,7 @@ int eth_register(struct eth_device *edev)
edev->dev.id = DEVICE_ID_DYNAMIC;
if (edev->parent)
dev_add_child(edev->parent, &edev->dev);
edev->dev.parent = edev->parent;
register_device(&edev->dev);