mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-22 06:57:51 +00:00
OMAP4 USB driver
This commit is contained in:
parent
1030ac1c67
commit
e23c334b90
@ -7,7 +7,7 @@ CONTRIB_DIR = contrib
|
||||
DOWNLOAD_DIR = download
|
||||
VERBOSE ?= @
|
||||
ECHO = @echo
|
||||
PATCHES = $(shell find patches -name *.patch)
|
||||
PATCHES := $(shell find patches -name \*.patch)
|
||||
|
||||
LINUX = linux-3.2.2
|
||||
LINUX_TBZ2 = $(LINUX).tar.bz2
|
||||
@ -31,7 +31,7 @@ CONTENT += include/linux/usbdevice_fs.h include/asm-generic/ioctl.h
|
||||
|
||||
# USB host-controller driver
|
||||
CONTENT_USB_HOST := ehci.h ehci-hcd.c ehci-hub.c ehci-dbg.c ehci-mem.c \
|
||||
ehci-q.c ehci-pci.c ehci-sched.c ehci-sysfs.c
|
||||
ehci-omap.c ehci-q.c ehci-pci.c ehci-sched.c ehci-sysfs.c
|
||||
CONTENT_USB_HOST += ohci.h ohci-hcd.c ohci-hub.c ohci-dbg.c ohci-mem.c \
|
||||
ohci-q.c ohci-pci.c ehci-lpm.c
|
||||
CONTENT_USB_HOST += uhci-hcd.h uhci-hcd.c uhci-debug.c uhci-q.c uhci-hub.c \
|
||||
@ -57,7 +57,12 @@ CONTENT += $(addprefix drivers/input/,$(CONTENT_INPUT))
|
||||
CONTENT += include/linux/input/mt.h
|
||||
|
||||
|
||||
CONTRIB_CONTENT := $(addprefix $(CONTRIB_DIR)/,$(CONTENT))
|
||||
# Panda board
|
||||
#CONTENT += drivers/mfd/omap-usb-host.c
|
||||
#CONTENT += arch/arm/plat-omap/include/plat/usb.h
|
||||
#CONTENT_ARCH = usb-host.c mux.h mux2420.h mux2430.h mux34xx.h mux44xx.h
|
||||
#CONTENT += $(addprefix arch/arm/mach-omap2/,$(CONTENT_ARCH))
|
||||
#CONTRIB_CONTENT := $(addprefix $(CONTRIB_DIR)/,$(CONTENT))
|
||||
#
|
||||
#
|
||||
# Utility to check if a tool is installed
|
||||
@ -100,7 +105,7 @@ $(DOWNLOAD_DIR)/$(LINUX_TBZ2): $(DOWNLOAD_DIR)
|
||||
$(VERBOSE)touch $@
|
||||
|
||||
clean:
|
||||
$(VERBOSE)rm -f $(CONTRIB_DIR)
|
||||
$(VERBOSE)rm -rf $(CONTRIB_DIR)
|
||||
|
||||
cleanall: clean
|
||||
$(VERBOSE)rm -rf $(DOWNLOAD_DIR)
|
||||
|
178
dde_linux/src/drivers/usb/arm/platform/lx_emul.h
Normal file
178
dde_linux/src/drivers/usb/arm/platform/lx_emul.h
Normal file
@ -0,0 +1,178 @@
|
||||
/*
|
||||
* \brief Platform specific part of the Linux API emulation
|
||||
* \author Sebastian Sumpf
|
||||
* \date 2012-06-18
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
#ifndef _ARM__PLATFORM__LX_EMUL_H_
|
||||
#define _ARM__PLATFORM__LX_EMUL_H_
|
||||
|
||||
/*************************
|
||||
** asm-generic/sizes.h **
|
||||
*************************/
|
||||
|
||||
enum {
|
||||
SZ_1K = 0x00000400,
|
||||
SZ_4K = 0x00001000a,
|
||||
};
|
||||
|
||||
struct platform_device
|
||||
{
|
||||
const char *name;
|
||||
int id;
|
||||
struct device dev;
|
||||
u32 num_resources;
|
||||
struct resource *resource;
|
||||
};
|
||||
|
||||
|
||||
/**********************
|
||||
** linux/usb/ulpi.h **
|
||||
**********************/
|
||||
|
||||
enum {
|
||||
ULPI_FUNC_CTRL_RESET = (1 << 5),
|
||||
ULPI_FUNC_CTRL = (1 << 2),
|
||||
};
|
||||
|
||||
/*
|
||||
* Macros for Set and Clear
|
||||
* See ULPI 1.1 specification to find the registers with Set and Clear offsets
|
||||
*/
|
||||
|
||||
#define ULPI_SET(a) (a + 1)
|
||||
|
||||
/*******************************************
|
||||
** arch/arm/plat-omap/include/plat/usb.h **
|
||||
*******************************************/
|
||||
|
||||
enum { OMAP3_HS_USB_PORTS = 2 };
|
||||
|
||||
enum usbhs_omap_port_mode
|
||||
{
|
||||
OMAP_EHCI_PORT_MODE_NONE,
|
||||
OMAP_EHCI_PORT_MODE_PHY,
|
||||
};
|
||||
|
||||
|
||||
struct ehci_hcd_omap_platform_data
|
||||
{
|
||||
enum usbhs_omap_port_mode port_mode[OMAP3_HS_USB_PORTS];
|
||||
struct regulator *regulator[OMAP3_HS_USB_PORTS];
|
||||
};
|
||||
|
||||
struct regulator;
|
||||
/*********************************************
|
||||
** arch/arm/plat-omap/include/plat/board.h **
|
||||
*********************************************/
|
||||
|
||||
struct omap_usb_config;
|
||||
|
||||
|
||||
/************************************************
|
||||
** arch/arm/plat-omap/include/plat/omap34xx.h **
|
||||
************************************************/
|
||||
|
||||
#define OMAP34XX_UHH_CONFIG_BASE 0
|
||||
#define OMAP34XX_EHCI_BASE 0
|
||||
#define OMAP34XX_USBTLL_BASE 0
|
||||
#define INT_34XX_EHCI_IRQ 0
|
||||
#define OMAP34XX_OHCI_BASE 0
|
||||
#define INT_34XX_OHCI_IRQ 0
|
||||
#define OMAP3430_REV_ES2_1 0
|
||||
|
||||
|
||||
static inline int cpu_is_omap34xx(void) { return 0; }
|
||||
static inline int cpu_is_omap3430(void) { return 0; }
|
||||
|
||||
/***************************************************
|
||||
** platform definition os for OMAP44xx all under **
|
||||
** 'arch/arm/plat-omap/include **
|
||||
***************************************************/
|
||||
|
||||
enum {
|
||||
OMAP44XX_IRQ_GIC_START = 32,
|
||||
OMAP44XX_IRQ_EHCI = 77 + OMAP44XX_IRQ_GIC_START,
|
||||
OMAP44XX_IRQ_OHCI =76 + OMAP44XX_IRQ_GIC_START,
|
||||
};
|
||||
|
||||
enum {
|
||||
L4_44XX_BASE = 0x4a000000,
|
||||
OMAP44XX_USBTLL_BASE = L4_44XX_BASE + 0x62000,
|
||||
OMAP44XX_UHH_CONFIG_BASE = L4_44XX_BASE + 0x64000,
|
||||
OMAP44XX_HSUSB_OHCI_BASE = L4_44XX_BASE + 0x64800,
|
||||
OMAP44XX_HSUSB_EHCI_BASE = L4_44XX_BASE + 0x64C00,
|
||||
};
|
||||
|
||||
static inline int cpu_is_omap44xx(void) { return 1; }
|
||||
|
||||
/*****************************
|
||||
** linux/platform_device.h **
|
||||
*****************************/
|
||||
|
||||
struct platform_driver {
|
||||
int (*probe)(struct platform_device *);
|
||||
int (*remove)(struct platform_device *);
|
||||
void (*shutdown)(struct platform_device *);
|
||||
int (*suspend)(struct platform_device *, pm_message_t state);
|
||||
int (*resume)(struct platform_device *);
|
||||
struct device_driver driver;
|
||||
const struct platform_device_id *id_table;
|
||||
};
|
||||
|
||||
struct resource *platform_get_resource_byname(struct platform_device *, unsigned int, const char *);
|
||||
int platform_get_irq_byname(struct platform_device *, const char *);
|
||||
|
||||
int platform_driver_register(struct platform_driver *);
|
||||
int platform_device_register(struct platform_device *);
|
||||
|
||||
/**********************
|
||||
** asm/generic/io.h **
|
||||
**********************/
|
||||
|
||||
static inline u32 __raw_readl(const volatile void __iomem *addr)
|
||||
{
|
||||
return *(const volatile u32 __force *) addr;
|
||||
}
|
||||
|
||||
static inline void __raw_writel(u32 b, volatile void __iomem *addr)
|
||||
{
|
||||
*(volatile u32 __force *) addr = b;
|
||||
}
|
||||
|
||||
|
||||
static inline u8 __raw_readb(const volatile void __iomem *addr)
|
||||
{
|
||||
return *(const volatile u8 __force *) addr;
|
||||
}
|
||||
|
||||
static inline void __raw_writeb(u8 b, volatile void __iomem *addr)
|
||||
{
|
||||
*(volatile u8 __force *) addr = b;
|
||||
}
|
||||
|
||||
|
||||
/********************************
|
||||
** linux/regulator/consumer.h **
|
||||
********************************/
|
||||
|
||||
int regulator_enable(struct regulator *);
|
||||
int regulator_disable(struct regulator *);
|
||||
void regulator_put(struct regulator *regulator);
|
||||
struct regulator *regulator_get(struct device *dev, const char *id);
|
||||
|
||||
|
||||
/*******************************************
|
||||
** arch/arm/plat-omap/include/plat/usb.h **
|
||||
*******************************************/
|
||||
|
||||
int omap_usbhs_enable(struct device *dev);
|
||||
void omap_usbhs_disable(struct device *dev);
|
||||
|
||||
#endif /* _ARM__PLATFORM__LX_EMUL_H_ */
|
395
dde_linux/src/drivers/usb/arm/platform/platform.cc
Normal file
395
dde_linux/src/drivers/usb/arm/platform/platform.cc
Normal file
@ -0,0 +1,395 @@
|
||||
/**
|
||||
* \brief EHCI for OMAP4
|
||||
* \author Sebastian Sumpf <sebastian.sumpf@genode-labs.com>
|
||||
* \date 2012-06-20
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#include <platform/platform.h>
|
||||
|
||||
#include <io_mem_session/connection.h>
|
||||
#include <util/mmio.h>
|
||||
|
||||
#include <lx_emul.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
/**
|
||||
* Base addresses
|
||||
*/
|
||||
enum {
|
||||
EHCI_BASE = 0x4a064c00,
|
||||
UHH_BASE = 0x4a064000,
|
||||
TLL_BASE = 0x4a062000,
|
||||
SCRM_BASE = 0x4a30a000,
|
||||
CAM_BASE = 0x4a009000, /* used for L3INIT_CM2 */
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Inerrupt numbers
|
||||
*/
|
||||
enum {
|
||||
IRQ_GIC_START = 32,
|
||||
IRQ_EHCI = IRQ_GIC_START + 77,
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Resources for platform device
|
||||
*/
|
||||
static resource _ehci[] =
|
||||
{
|
||||
{ EHCI_BASE, EHCI_BASE + 0x400 - 1, "ehci", IORESOURCE_MEM },
|
||||
{ IRQ_EHCI, IRQ_EHCI, "ehci-irq", IORESOURCE_IRQ },
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Port informations for platform device
|
||||
*/
|
||||
static struct ehci_hcd_omap_platform_data _ehci_data
|
||||
{
|
||||
{ OMAP_EHCI_PORT_MODE_PHY, OMAP_EHCI_PORT_MODE_NONE },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
extern "C" void module_ehci_hcd_init();
|
||||
|
||||
|
||||
/**
|
||||
* Enables USB clocks
|
||||
*/
|
||||
struct Clocks : Genode::Mmio
|
||||
{
|
||||
Clocks(Genode::addr_t const mmio_base) : Mmio(mmio_base)
|
||||
{
|
||||
write<Usb_phy_clk>(0x101);
|
||||
write<Usb_host_clk>(0x1008002);
|
||||
write<Usb_tll_clk>(0x1);
|
||||
}
|
||||
|
||||
struct Usb_host_clk : Register<0x358, 32> { };
|
||||
struct Usb_tll_clk : Register<0x368, 32> { };
|
||||
struct Usb_phy_clk : Register<0x3e0, 32> { };
|
||||
|
||||
template <typename T> void update(unsigned val)
|
||||
{
|
||||
typename T::access_t access = read<T>();
|
||||
access |= val;
|
||||
write<T>(access);
|
||||
};
|
||||
|
||||
void dump()
|
||||
{
|
||||
Usb_host_clk::access_t a1 = read<Usb_host_clk>();
|
||||
PDBG("Host clock %x", a1);
|
||||
Usb_tll_clk::access_t a3 = read<Usb_tll_clk>();
|
||||
PDBG("TLL: %x", a3);
|
||||
Usb_phy_clk::access_t a4 = read<Usb_phy_clk>();
|
||||
PDBG("Phy: %x", a4);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Panda board reference USB clock
|
||||
*/
|
||||
struct Aux3 : Genode::Mmio
|
||||
{
|
||||
Aux3(addr_t const mmio_base) : Mmio(mmio_base)
|
||||
{
|
||||
enable();
|
||||
}
|
||||
|
||||
/* the clock register */
|
||||
struct Aux3_clk : Register<0x31c, 32>
|
||||
{
|
||||
struct Src_select : Bitfield<1, 2> { };
|
||||
struct Div : Bitfield<16, 4> { enum { DIV_2 = 1 }; };
|
||||
struct Enable : Bitfield<8, 1> { enum { ON = 1 }; };
|
||||
};
|
||||
|
||||
/* clock source register */
|
||||
struct Aux_src : Register<0x110, 32, true> { };
|
||||
|
||||
void enable()
|
||||
{
|
||||
/* select system clock */
|
||||
write<Aux3_clk::Src_select>(0);
|
||||
|
||||
/* set to 19.2 Mhz */
|
||||
write<Aux3_clk::Div>(Aux3_clk::Div::DIV_2);
|
||||
|
||||
/* enable clock */
|
||||
write<Aux3_clk::Enable>(Aux3_clk::Enable::ON);
|
||||
|
||||
/* enable_ext = 1 | enable_int = 1| mode = 0x01 */
|
||||
write<Aux_src>(0xd);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* ULPI transceiverless link
|
||||
*/
|
||||
struct Tll : Genode::Mmio
|
||||
{
|
||||
Tll(addr_t const mmio_base) : Mmio(mmio_base)
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
struct Sys_config : Register<0x10, 32>
|
||||
{
|
||||
struct Soft_reset : Bitfield<1, 1> { };
|
||||
struct Cactivity : Bitfield<8, 1> { };
|
||||
struct Sidle_mode : Bitfield<3, 2> { };
|
||||
struct Ena_wakeup : Bitfield<2, 1> { };
|
||||
};
|
||||
|
||||
struct Sys_status : Register<0x14, 32> { };
|
||||
|
||||
void reset()
|
||||
{
|
||||
write<Sys_config>(0x0);
|
||||
|
||||
/* reset */
|
||||
write<Sys_config::Soft_reset>(0x1);
|
||||
|
||||
while(!read<Sys_status>())
|
||||
msleep(1);
|
||||
|
||||
/* disable IDLE, enable wake up, enable auto gating */
|
||||
write<Sys_config::Cactivity>(1);
|
||||
write<Sys_config::Sidle_mode>(1);
|
||||
write<Sys_config::Ena_wakeup>(1);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* USB high-speed host
|
||||
*/
|
||||
struct Uhh : Genode::Mmio
|
||||
{
|
||||
Uhh(addr_t const mmio_base) : Mmio(mmio_base)
|
||||
{
|
||||
/* diable idle and standby */
|
||||
write<Sys_config::Idle>(1);
|
||||
write<Sys_config::Standby>(1);
|
||||
|
||||
/* set ports to external phy */
|
||||
write<Host_config::P1_mode>(0);
|
||||
write<Host_config::P2_mode>(0);
|
||||
}
|
||||
|
||||
struct Sys_config : Register<0x10, 32>
|
||||
{
|
||||
struct Idle : Bitfield<2, 2> { };
|
||||
struct Standby : Bitfield<4, 2> { };
|
||||
};
|
||||
|
||||
struct Host_config : Register<0x40, 32>
|
||||
{
|
||||
struct P1_mode : Bitfield<16, 2> { };
|
||||
struct P2_mode : Bitfield<18, 2> { };
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* EHCI controller
|
||||
*/
|
||||
struct Ehci : Genode::Mmio
|
||||
{
|
||||
Ehci(addr_t const mmio_base) : Mmio(mmio_base)
|
||||
{
|
||||
write<Cmd>(0);
|
||||
|
||||
/* reset */
|
||||
write<Cmd::Reset>(1);
|
||||
|
||||
while(read<Cmd::Reset>())
|
||||
msleep(1);
|
||||
}
|
||||
|
||||
struct Cmd : Register<0x10, 32>
|
||||
{
|
||||
struct Reset : Bitfield<1, 1> { };
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Panda board GPIO bases 1 - 6
|
||||
*/
|
||||
static addr_t omap44xx_gpio_base[] =
|
||||
{
|
||||
0x4A310000, 0x48055000, 0x48057000, 0x48059000, 0x4805B000, 0x4805D000
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* General purpose I/O
|
||||
*/
|
||||
struct Gpio
|
||||
{
|
||||
enum { GPIO = 6 };
|
||||
|
||||
addr_t _io[GPIO];
|
||||
Io_mem_session_capability _cap[GPIO];
|
||||
|
||||
void map()
|
||||
{
|
||||
for (int i = 0; i < GPIO; i++) {
|
||||
Io_mem_connection io(omap44xx_gpio_base[i], 0x1000);
|
||||
io.on_destruction(Io_mem_connection::KEEP_OPEN);
|
||||
_io[i] = (addr_t)env()->rm_session()->attach(io.dataspace());
|
||||
_cap[i] = io.cap();
|
||||
}
|
||||
}
|
||||
|
||||
Gpio()
|
||||
{
|
||||
map();
|
||||
}
|
||||
|
||||
~Gpio()
|
||||
{
|
||||
for (int i = 0; i < GPIO; i++) {
|
||||
env()->rm_session()->detach(_io[i]);
|
||||
env()->parent()->close(_cap[i]);
|
||||
}
|
||||
}
|
||||
|
||||
addr_t base(unsigned gpio) { return _io[gpio >> 5]; }
|
||||
int index(unsigned gpio) { return gpio & 0x1f; }
|
||||
|
||||
void _set_data_out(addr_t base, unsigned gpio, bool enable)
|
||||
{
|
||||
enum { SETDATAOUT = 0x194, CLEARDATAOUT = 0x190 };
|
||||
writel(1U << gpio, base + (enable ? SETDATAOUT : CLEARDATAOUT));
|
||||
}
|
||||
|
||||
void _set_gpio_direction(addr_t base, unsigned gpio, bool input)
|
||||
{
|
||||
enum { OE = 0x134 };
|
||||
base += OE;
|
||||
|
||||
u32 val = readl(base);
|
||||
|
||||
if (input)
|
||||
val |= 1U << gpio;
|
||||
else
|
||||
val &= ~(1U << gpio);
|
||||
|
||||
writel(val, base);
|
||||
}
|
||||
|
||||
void direction_output(unsigned gpio, bool enable)
|
||||
{
|
||||
_set_data_out(base(gpio), index(gpio), enable);
|
||||
_set_gpio_direction(base(gpio), index(gpio), false);
|
||||
}
|
||||
|
||||
void direction_input(unsigned gpio)
|
||||
{
|
||||
_set_gpio_direction(base(gpio), index(gpio), true);
|
||||
}
|
||||
|
||||
void set_value(unsigned gpio, int val)
|
||||
{
|
||||
_set_data_out(base(gpio), index(gpio), val);
|
||||
}
|
||||
|
||||
unsigned get_value(int gpio)
|
||||
{
|
||||
enum { DATAIN = 0x138 };
|
||||
return (readl(base(gpio) + DATAIN) & (1 << index(gpio))) != 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Initialize the USB controller from scratch, since the boot loader might not
|
||||
* do it or even disable USB.
|
||||
*/
|
||||
static void omap_ehci_init()
|
||||
{
|
||||
/* taken from the Panda board manual */
|
||||
enum { HUB_POWER = 1, HUB_NRESET = 62, ULPI_PHY_TYPE = 182 };
|
||||
|
||||
/* SCRM */
|
||||
Io_mem_connection io_scrm(SCRM_BASE, 0x1000);
|
||||
addr_t scrm_base = (addr_t)env()->rm_session()->attach(io_scrm.dataspace());
|
||||
|
||||
/* enable reference clock */
|
||||
Aux3 aux3(scrm_base);
|
||||
|
||||
/* init GPIO */
|
||||
Gpio gpio;
|
||||
/* disable the hub power and reset before init */
|
||||
gpio.direction_output(HUB_POWER, false);
|
||||
gpio.direction_output(HUB_NRESET, false);
|
||||
gpio.set_value(HUB_POWER, 0);
|
||||
gpio.set_value(HUB_NRESET, 1);
|
||||
|
||||
/* enable clocks */
|
||||
Io_mem_connection io_clock(CAM_BASE, 0x1000);
|
||||
addr_t clock_base = (addr_t)env()->rm_session()->attach(io_clock.dataspace());
|
||||
Clocks c(clock_base);
|
||||
|
||||
/* reset TLL */
|
||||
Io_mem_connection io_tll(TLL_BASE, 0x1000);
|
||||
addr_t tll_base = (addr_t)env()->rm_session()->attach(io_tll.dataspace());
|
||||
Tll t(tll_base);
|
||||
|
||||
/* reset host */
|
||||
Io_mem_connection io_uhh(UHH_BASE, 0x1000);
|
||||
addr_t uhh_base = (addr_t)env()->rm_session()->attach(io_uhh.dataspace());
|
||||
Uhh uhh(uhh_base);
|
||||
|
||||
/* enable hub power */
|
||||
gpio.set_value(HUB_POWER, 1);
|
||||
|
||||
/* reset EHCI */
|
||||
addr_t ehci_base = uhh_base + 0xc00;
|
||||
Ehci ehci(ehci_base);
|
||||
|
||||
addr_t base[] = { scrm_base, clock_base, tll_base, uhh_base, 0 };
|
||||
for (int i = 0; base[i]; i++)
|
||||
env()->rm_session()->detach(base[i]);
|
||||
}
|
||||
|
||||
|
||||
void platform_hcd_init(void)
|
||||
{
|
||||
module_ehci_hcd_init();
|
||||
omap_ehci_init();
|
||||
|
||||
/* setup EHCI-controller platform device */
|
||||
platform_device *pdev = (platform_device *)kzalloc(sizeof(platform_device), 0);
|
||||
pdev->name = "ehci-omap";
|
||||
pdev->id = 0;
|
||||
pdev->num_resources = 2;
|
||||
pdev->resource = _ehci;
|
||||
pdev->dev.platform_data = &_ehci_data;
|
||||
|
||||
/*
|
||||
* Needed for DMA buffer allocation. See 'hcd_buffer_alloc' in 'buffer.c'
|
||||
*/
|
||||
static u64 dma_mask = ~(u32)0;
|
||||
pdev->dev.dma_mask = &dma_mask;
|
||||
pdev->dev.coherent_dma_mask = ~0;
|
||||
|
||||
platform_device_register(pdev);
|
||||
}
|
||||
|
38
dde_linux/src/drivers/usb/arm/platform/platform.h
Normal file
38
dde_linux/src/drivers/usb/arm/platform/platform.h
Normal file
@ -0,0 +1,38 @@
|
||||
/**
|
||||
* \brief Platform specific code
|
||||
* \author Sebastian Sumpf
|
||||
* \date 2012-06-10
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _ARM__PLATFORM_H_
|
||||
#define _ARM__PLATFORM_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static inline
|
||||
void platform_execute(void *sp, void *func, void *arg)
|
||||
{
|
||||
asm volatile ("mov r0, %2;" /* set arg */
|
||||
"mov sp, %0;" /* set stack */
|
||||
"mov pc, %1;" /* call func */
|
||||
""
|
||||
: : "r"(sp), "r"(func), "r"(arg) : "r0");
|
||||
}
|
||||
|
||||
|
||||
void platform_hcd_init(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ARM__PLATFORM_H_ */
|
88
dde_linux/src/drivers/usb/arm/platform/platform_device.c
Normal file
88
dde_linux/src/drivers/usb/arm/platform/platform_device.c
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* \brief Linux platform_device emulation
|
||||
* \author Sebastian Sumpf
|
||||
* \date 2012-06-18
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#include <lx_emul.h>
|
||||
|
||||
#define to_platform_driver(drv) (container_of((drv), struct platform_driver, \
|
||||
driver))
|
||||
#define to_platform_device(x) container_of((x), struct platform_device, dev)
|
||||
|
||||
|
||||
static int platform_match(struct device *dev, struct device_driver *drv)
|
||||
{
|
||||
if (!dev->name)
|
||||
return 0;
|
||||
|
||||
return (strcmp(dev->name, drv->name) == 0);
|
||||
}
|
||||
|
||||
|
||||
static int platform_drv_probe(struct device *_dev)
|
||||
{
|
||||
struct platform_driver *drv = to_platform_driver(_dev->driver);
|
||||
struct platform_device *dev = to_platform_device(_dev);
|
||||
|
||||
return drv->probe(dev);
|
||||
}
|
||||
|
||||
|
||||
struct bus_type platform_bus_type = {
|
||||
.name = "platform",
|
||||
.match = platform_match,
|
||||
.probe = platform_drv_probe
|
||||
};
|
||||
|
||||
|
||||
int platform_driver_register(struct platform_driver *drv)
|
||||
{
|
||||
drv->driver.bus = &platform_bus_type;
|
||||
if (drv->probe)
|
||||
drv->driver.probe = platform_drv_probe;
|
||||
|
||||
return driver_register(&drv->driver);
|
||||
}
|
||||
|
||||
|
||||
struct resource *platform_get_resource_byname(struct platform_device *dev,
|
||||
unsigned int type,
|
||||
const char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < dev->num_resources; i++) {
|
||||
struct resource *r = &dev->resource[i];
|
||||
|
||||
if (type == r->flags && !strcmp(r->name, name))
|
||||
return r;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int platform_get_irq_byname(struct platform_device *dev, const char *name)
|
||||
{
|
||||
struct resource *r = platform_get_resource_byname(dev, IORESOURCE_IRQ, name);
|
||||
return r ? r->start : -1;
|
||||
}
|
||||
|
||||
|
||||
int platform_device_register(struct platform_device *pdev)
|
||||
{
|
||||
pdev->dev.bus = &platform_bus_type;
|
||||
pdev->dev.name = pdev->name;
|
||||
/* XXX: Fill with magic value to see page fault */
|
||||
pdev->dev.parent = (struct device *)0xaaaaaaaa;
|
||||
device_add(&pdev->dev);
|
||||
return 0;
|
||||
}
|
94
dde_linux/src/drivers/usb/dma.h
Normal file
94
dde_linux/src/drivers/usb/dma.h
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* \brief DMA memory pool
|
||||
* \author Sebastian Sumpf
|
||||
* \date 2012-06-18
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _DMA_H_
|
||||
#define _DMA_H_
|
||||
|
||||
#include <base/allocator_avl.h>
|
||||
#include <dataspace/client.h>
|
||||
#include <lx_emul.h>
|
||||
|
||||
/*********************
|
||||
** linux/dmapool.h **
|
||||
*********************/
|
||||
|
||||
namespace Genode {
|
||||
|
||||
/**
|
||||
* Dma-pool manager
|
||||
*/
|
||||
class Dma
|
||||
{
|
||||
private:
|
||||
|
||||
enum { SIZE = 1024 * 1024 };
|
||||
|
||||
addr_t _base; /* virt base of pool */
|
||||
addr_t _base_phys; /* phys base of pool */
|
||||
Allocator_avl _range; /* range allocator for pool */
|
||||
|
||||
Dma() : _range(env()->heap())
|
||||
{
|
||||
Ram_dataspace_capability cap = env()->ram_session()->alloc(SIZE);
|
||||
_base_phys = Dataspace_client(cap).phys_addr();
|
||||
_base = (addr_t)env()->rm_session()->attach(cap);
|
||||
dde_kit_log(DEBUG_DMA, "New DMA range [%lx-%lx)", _base, _base + SIZE);
|
||||
_range.add_range(_base, SIZE);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
static Dma* pool()
|
||||
{
|
||||
static Dma _p;
|
||||
return &_p;
|
||||
}
|
||||
|
||||
addr_t base() const { return _base; };
|
||||
addr_t end() const { return _base + SIZE -1; }
|
||||
|
||||
/**
|
||||
* Alloc 'size' bytes of DMA memory
|
||||
*/
|
||||
void *alloc(size_t size, int align = 12)
|
||||
{
|
||||
void *addr;
|
||||
if (!_range.alloc_aligned(size, &addr, align)) {
|
||||
PERR("DMA of %zu bytes allocation failed", size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Free DMA memory
|
||||
*/
|
||||
void free(void *addr) { _range.free(addr); }
|
||||
|
||||
/**
|
||||
* Get phys for virt address
|
||||
*/
|
||||
addr_t phys_addr(void *addr)
|
||||
{
|
||||
addr_t a = (addr_t)addr;
|
||||
if (a < _base || a >= _base + SIZE) {
|
||||
PERR("No DMA phys addr for %lx", a);
|
||||
return 0;
|
||||
}
|
||||
return (a - _base) + _base_phys;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _DMA_H_ */
|
@ -66,7 +66,7 @@ char *kasprintf(gfp_t gfp, const char *fmt, ...) { TRACE; return NULL; }
|
||||
int kstrtouint(const char *s, unsigned int base, unsigned int *res) { TRACE; return 0; }
|
||||
int sprintf(char *buf, const char *fmt, ...) { TRACE; return 0; }
|
||||
int sscanf(const char *b, const char *s, ...) { TRACE; return 0; }
|
||||
int scnprintf(char *buf, size_t size, const char *fmt, ...) { TRACE; return 0; }
|
||||
int scnprintf(char *buf, size_t size, const char *fmt, ...);
|
||||
int strict_strtoul(const char *s, unsigned int base, unsigned long *res) { TRACE; return 0; }
|
||||
long simple_strtoul(const char *cp, char **endp, unsigned int base) { TRACE; return 0; }
|
||||
|
||||
@ -100,7 +100,6 @@ int ffs(int x) { TRACE; return 0; }
|
||||
|
||||
int memcmp(const void *dst, const void *src, size_t s) { TRACE; return 0; }
|
||||
char *strcat(char *dest, const char *src) { TRACE; return 0; }
|
||||
int strcmp(const char *s1, const char *s2) { TRACE; return 0; }
|
||||
int strncmp(const char *cs, const char *ct, size_t count) { TRACE; return 0; }
|
||||
char *strncpy(char *dst, const char *src, size_t s) { TRACE; return NULL; }
|
||||
char *strchr(const char *s, int n) { TRACE; return NULL; }
|
||||
@ -236,7 +235,7 @@ void __set_current_state(int state) { TRACE; }
|
||||
int signal_pending(struct task_struct *p) { TRACE; return 0; }
|
||||
void schedule(void) { TRACE; }
|
||||
void yield(void) { TRACE; }
|
||||
void cpu_relax(void) { TRACE; }
|
||||
void cpu_relax(void) { TRACE; udelay(1); }
|
||||
|
||||
struct task_struct *current;
|
||||
|
||||
@ -321,7 +320,6 @@ bool device_can_wakeup(struct device *dev) { TRACE; return 0; }
|
||||
********************/
|
||||
|
||||
int dev_set_name(struct device *dev, const char *name, ...) { TRACE; return 0; }
|
||||
const char *dev_name(const struct device *dev) { TRACE; return NULL; }
|
||||
int dev_to_node(struct device *dev) { TRACE; return 0; }
|
||||
void set_dev_node(struct device *dev, int node) { TRACE; }
|
||||
|
||||
@ -523,7 +521,6 @@ void kunmap(struct page *page) { TRACE; }
|
||||
** asm-generic/io.h **
|
||||
**********************/
|
||||
|
||||
void *ioremap(resource_size_t offset, unsigned long size) { TRACE; return NULL; }
|
||||
void iounmap(volatile void *addr) { TRACE; }
|
||||
void native_io_delay(void) { TRACE; }
|
||||
|
||||
@ -780,3 +777,19 @@ void scsi_host_put(struct Scsi_Host *shost) { TRACE; }
|
||||
struct scsi_device *scsi_get_host_dev(struct Scsi_Host *shost) { TRACE; return 0; }
|
||||
|
||||
|
||||
/********************************
|
||||
** linux/regulator/consumer.h **
|
||||
********************************/
|
||||
struct regulator;
|
||||
int regulator_enable(struct regulator *r) { TRACE; return 0; }
|
||||
int regulator_disable(struct regulator *r) { TRACE; return 0; }
|
||||
void regulator_put(struct regulator *r) { TRACE; }
|
||||
struct regulator *regulator_get(struct device *dev, const char *id) { TRACE; return 0; }
|
||||
|
||||
|
||||
/*******************************************
|
||||
** arch/arm/plat-omap/include/plat/usb.h **
|
||||
*******************************************/
|
||||
|
||||
int omap_usbhs_enable(struct device *dev) { TRACE; return 0; }
|
||||
void omap_usbhs_disable(struct device *dev) { TRACE; }
|
||||
|
@ -10,6 +10,13 @@
|
||||
* the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009-2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Linux */
|
||||
#include <linux/input.h>
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <util/string.h>
|
||||
|
||||
/* Local includes */
|
||||
#include "dma.h"
|
||||
#include "routine.h"
|
||||
#include "signal.h"
|
||||
#include "lx_emul.h"
|
||||
@ -198,15 +199,32 @@ int snprintf(char *buf, size_t size, const char *fmt, ...)
|
||||
}
|
||||
|
||||
|
||||
int scnprintf(char *buf, size_t size, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
Genode::String_console sc(buf, size);
|
||||
sc.vprintf(fmt, args);
|
||||
va_end(args);
|
||||
|
||||
return sc.len();
|
||||
}
|
||||
|
||||
int strcmp(const char *s1, const char *s2) { return Genode::strcmp(s1, s2); }
|
||||
size_t strlen(const char *s) { return Genode::strlen(s); }
|
||||
|
||||
|
||||
size_t strlcat(char *dest, const char *src, size_t n)
|
||||
{
|
||||
size_t len = strlen(dest);
|
||||
Genode::strncpy(dest + len, src, n);
|
||||
dest[len + n] = 0;
|
||||
return n;
|
||||
|
||||
if (len >= n)
|
||||
len = n - 1;
|
||||
|
||||
memcpy(dest, src, len);
|
||||
dest[len] = 0;
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
@ -320,10 +338,10 @@ void kmem_cache_free(struct kmem_cache *cache, void *objp)
|
||||
** asm-generic/io.h **
|
||||
**********************/
|
||||
|
||||
void *ioremap_wc(resource_size_t phys_addr, unsigned long size)
|
||||
void *_ioremap(resource_size_t phys_addr, unsigned long size, int wc)
|
||||
{
|
||||
dde_kit_addr_t map_addr;
|
||||
if (dde_kit_request_mem(phys_addr, size, 1, &map_addr)) {
|
||||
if (dde_kit_request_mem(phys_addr, size, wc, &map_addr)) {
|
||||
PERR("Failed to request I/O memory: [%x,%lx)", phys_addr, phys_addr + size);
|
||||
return 0;
|
||||
}
|
||||
@ -332,6 +350,18 @@ void *ioremap_wc(resource_size_t phys_addr, unsigned long size)
|
||||
}
|
||||
|
||||
|
||||
void *ioremap_wc(resource_size_t phys_addr, unsigned long size)
|
||||
{
|
||||
return _ioremap(phys_addr, size, 1);
|
||||
}
|
||||
|
||||
|
||||
void *ioremap(resource_size_t offset, unsigned long size)
|
||||
{
|
||||
return _ioremap(offset, size, 0);
|
||||
}
|
||||
|
||||
|
||||
/********************
|
||||
** linux/device.h **
|
||||
********************/
|
||||
@ -438,6 +468,7 @@ int dev_set_drvdata(struct device *dev, void *data)
|
||||
|
||||
|
||||
struct device *get_device(struct device *dev) { TRACE; return dev; }
|
||||
const char *dev_name(const struct device *dev) { return dev->name; }
|
||||
|
||||
|
||||
long find_next_zero_bit_le(const void *addr,
|
||||
@ -527,78 +558,9 @@ enum { JIFFIES_TICK_MS = 1000 / DDE_KIT_HZ };
|
||||
|
||||
unsigned long msecs_to_jiffies(const unsigned int m) { return m / JIFFIES_TICK_MS; }
|
||||
long time_after_eq(long a, long b) { return (a - b) >= 0; }
|
||||
long time_after(long a, long b) { return (b - a) > 0; }
|
||||
long time_after(long a, long b) { return (b - a) < 0; }
|
||||
|
||||
|
||||
/*********************
|
||||
** linux/dmapool.h **
|
||||
*********************/
|
||||
|
||||
namespace Genode {
|
||||
|
||||
/**
|
||||
* Dma-pool manager
|
||||
*/
|
||||
class Dma
|
||||
{
|
||||
private:
|
||||
|
||||
enum { SIZE = 1024 * 1024 };
|
||||
|
||||
addr_t _base; /* virt base of pool */
|
||||
addr_t _base_phys; /* phys base of pool */
|
||||
Allocator_avl _range; /* range allocator for pool */
|
||||
|
||||
Dma() : _range(env()->heap())
|
||||
{
|
||||
Ram_dataspace_capability cap = env()->ram_session()->alloc(SIZE);
|
||||
_base_phys = Dataspace_client(cap).phys_addr();
|
||||
_base = (addr_t)env()->rm_session()->attach(cap);
|
||||
dde_kit_log(DEBUG_DMA, "New DMA range [%lx-%lx)", _base, _base + SIZE);
|
||||
_range.add_range(_base, SIZE);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
static Dma* pool()
|
||||
{
|
||||
static Dma _p;
|
||||
return &_p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alloc 'size' bytes of DMA memory
|
||||
*/
|
||||
void *alloc(size_t size, int align = PAGE_SHIFT)
|
||||
{
|
||||
void *addr;
|
||||
if (!_range.alloc_aligned(size, &addr, align)) {
|
||||
PERR("DMA of %zu bytes allocation failed", size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Free DMA memory
|
||||
*/
|
||||
void free(void *addr) { _range.free(addr); }
|
||||
|
||||
/**
|
||||
* Get phys for virt address
|
||||
*/
|
||||
addr_t phys_addr(void *addr)
|
||||
{
|
||||
addr_t a = (addr_t)addr;
|
||||
if (a < _base || a >= _base + SIZE) {
|
||||
PERR("No DMA phys addr for %lx", a);
|
||||
return 0;
|
||||
}
|
||||
return (a - _base) + _base_phys;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
struct dma_pool
|
||||
@ -611,7 +573,7 @@ struct dma_pool
|
||||
struct dma_pool *dma_pool_create(const char *name, struct device *d, size_t size,
|
||||
size_t align, size_t alloc)
|
||||
{
|
||||
dde_kit_log(DEBUG_DMA, "size: %zx align:%zx", size, align);
|
||||
dde_kit_log(DEBUG_DMA, "size: %zx align:%zx %p", size, align, __builtin_return_address((0)));
|
||||
|
||||
if (align & (align - 1))
|
||||
return 0;
|
||||
@ -633,12 +595,13 @@ void dma_pool_destroy(struct dma_pool *d)
|
||||
static void* _alloc(size_t size, int align, dma_addr_t *dma)
|
||||
{
|
||||
void *addr = Genode::Dma::pool()->alloc(size, align);
|
||||
dde_kit_log(DEBUG_DMA, "addr: %p size %zx align: %d", addr, size, align);
|
||||
|
||||
if (!addr)
|
||||
return 0;
|
||||
|
||||
*dma = (dma_addr_t)Genode::Dma::pool()->phys_addr(addr);
|
||||
dde_kit_log(DEBUG_DMA, "DMA pool alloc addr: %p size %zx align: %d, pysh: %lx", addr, size, align, *dma);
|
||||
memset(addr, 0, size);
|
||||
return addr;
|
||||
}
|
||||
|
||||
@ -646,6 +609,8 @@ static void* _alloc(size_t size, int align, dma_addr_t *dma)
|
||||
void *dma_pool_alloc(struct dma_pool *d, gfp_t f, dma_addr_t *dma)
|
||||
{
|
||||
return _alloc(d->size, d->align, dma);
|
||||
// return _alloc(0x1000, 12, dma);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -768,3 +733,13 @@ void *sg_virt(struct scatterlist *sg)
|
||||
struct page *page = (struct page *)sg->page_link;
|
||||
return (void *)((unsigned long)page->virt + sg->offset);
|
||||
}
|
||||
|
||||
|
||||
/********************
|
||||
** linux/ioport.h **
|
||||
********************/
|
||||
|
||||
resource_size_t resource_size(const struct resource *res)
|
||||
{
|
||||
return res->end - res->start + 1;
|
||||
}
|
||||
|
@ -37,15 +37,15 @@ extern "C" {
|
||||
|
||||
|
||||
#if VERBOSE_LX_EMUL
|
||||
#define DEBUG_COMPLETION 1
|
||||
#define DEBUG_COMPLETION 0
|
||||
#define DEBUG_DMA 0
|
||||
#define DEBUG_DRIVER 1
|
||||
#define DEBUG_IRQ 1
|
||||
#define DEBUG_DRIVER 0
|
||||
#define DEBUG_IRQ 0
|
||||
#define DEBUG_KREF 0
|
||||
#define DEBUG_PCI 1
|
||||
#define DEBUG_PCI 0
|
||||
#define DEBUG_SLAB 0
|
||||
#define DEBUG_TIMER 1
|
||||
#define DEBUG_THREAD 1
|
||||
#define DEBUG_TIMER 0
|
||||
#define DEBUG_THREAD 0
|
||||
#else
|
||||
#define DEBUG_COMPLETION 0
|
||||
#define DEBUG_DRIVER 0
|
||||
@ -661,10 +661,14 @@ int isprint(int);
|
||||
******************/
|
||||
|
||||
#define __init
|
||||
#define __initdata
|
||||
#define __devinit
|
||||
#define __devinitconst
|
||||
#define __devexit
|
||||
#define __exit
|
||||
|
||||
#define __exit_p(x) x
|
||||
|
||||
#define subsys_initcall(fn) void subsys_##fn(void) { fn(); }
|
||||
|
||||
|
||||
@ -679,6 +683,7 @@ int isprint(int);
|
||||
#define MODULE_LICENSE(x)
|
||||
#define MODULE_PARM_DESC(x, y)
|
||||
//#define MODULE_ALIAS_MISCDEV(x) /* needed by agp/backend.c */
|
||||
#define MODULE_ALIAS(x)
|
||||
|
||||
#define THIS_MODULE 0
|
||||
|
||||
@ -1239,7 +1244,12 @@ bool device_can_wakeup(struct device *dev);
|
||||
#define dev_WARN(dev, format, arg...) dde_kit_printf("dev_WARN: " format, ## arg)
|
||||
#define dev_err( dev, format, arg...) dde_kit_printf("dev_error: " format, ## arg)
|
||||
#define dev_notice(dev, format, arg...) dde_kit_printf("dev_notice: " format, ## arg)
|
||||
|
||||
#if VERBOSE_LX_EMUL
|
||||
#define dev_dbg(dev, format, arg...) dde_kit_printf("dev_dbg: " format, ## arg)
|
||||
#else
|
||||
#define dev_dbg( dev, format, arg...)
|
||||
#endif
|
||||
|
||||
#define dev_printk(level, dev, format, arg...) \
|
||||
dde_kit_printf("dev_printk: " format, ## arg)
|
||||
@ -1284,12 +1294,16 @@ struct class
|
||||
char *(*devnode)(struct device *dev, mode_t *mode);
|
||||
};
|
||||
|
||||
/* DEVICE */
|
||||
struct device {
|
||||
const char *name;
|
||||
struct device *parent;
|
||||
struct kobject kobj;
|
||||
const struct device_type *type;
|
||||
struct device_driver *driver;
|
||||
void *platform_data;
|
||||
u64 *dma_mask; /* needed by usb/hcd.h */
|
||||
u64 coherent_dma_mask; /* omap driver */
|
||||
struct dev_pm_info power;
|
||||
dev_t devt;
|
||||
const struct attribute_group **groups;
|
||||
@ -1826,12 +1840,15 @@ static inline u32 inl_p(u32 port) { u32 ret = inl(port); native_io_delay(); retu
|
||||
** linux/ioport.h **
|
||||
********************/
|
||||
|
||||
#define IORESOURCE_IO 0x00000100
|
||||
#define IORESOURCE_IO 0x00000100
|
||||
#define IORESOURCE_MEM 0x00000200
|
||||
#define IORESOURCE_IRQ 0x00000400
|
||||
|
||||
struct resource
|
||||
{
|
||||
resource_size_t start;
|
||||
resource_size_t end;
|
||||
const char *name;
|
||||
unsigned long flags;
|
||||
};
|
||||
|
||||
@ -1843,6 +1860,7 @@ struct resource *request_mem_region(resource_size_t start, resource_size_t n,
|
||||
void release_region(resource_size_t start, resource_size_t n);
|
||||
void release_mem_region(resource_size_t start, resource_size_t n);
|
||||
|
||||
resource_size_t resource_size(const struct resource *res);
|
||||
|
||||
/***********************
|
||||
** linux/interrupt.h **
|
||||
@ -2577,6 +2595,12 @@ struct scsi_driver
|
||||
};
|
||||
|
||||
|
||||
/**********************************
|
||||
** Platform specific defintions **
|
||||
*********************************/
|
||||
#include <platform/lx_emul.h>
|
||||
|
||||
|
||||
/**********
|
||||
** misc **
|
||||
**********/
|
||||
|
@ -32,13 +32,11 @@ extern "C" {
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
extern "C" void subsys_usb_init();
|
||||
extern "C" int subsys_usb_init();
|
||||
extern "C" void subsys_input_init();
|
||||
extern "C" void module_ehci_hcd_init();
|
||||
extern "C" void module_evdev_init();
|
||||
extern "C" void module_hid_init();
|
||||
extern "C" void module_hid_init_core();
|
||||
extern "C" void module_uhci_hcd_init();
|
||||
extern "C" void module_usb_mouse_init();
|
||||
extern "C" void module_usb_kbd_init();
|
||||
extern "C" void module_usb_stor_init();
|
||||
@ -74,10 +72,8 @@ static void init(bool hid, bool stor)
|
||||
/*
|
||||
* Host controller.
|
||||
*
|
||||
* ehci_hcd should always be loaded before uhci_hcd and ohci_hcd, not after
|
||||
*/
|
||||
module_ehci_hcd_init();
|
||||
module_uhci_hcd_init();
|
||||
platform_hcd_init();
|
||||
|
||||
/* storage */
|
||||
if (stor)
|
||||
|
@ -22,6 +22,8 @@ extern "C" {
|
||||
#include <dde_kit/memory.h>
|
||||
}
|
||||
|
||||
#include <platform/platform.h>
|
||||
|
||||
static const bool verbose = false;
|
||||
|
||||
|
||||
@ -69,11 +71,7 @@ class Routine : public Genode::List<Routine>::Element
|
||||
/* XXX move to platform code */
|
||||
|
||||
/* switch stack and call '_func(_arg)' */
|
||||
asm volatile ("movl %2, 0(%0);"
|
||||
"movl %1, -0x4(%0);"
|
||||
"movl %0, %%esp;"
|
||||
"call *-4(%%esp);"
|
||||
: : "r" (_stack + STACK_SIZE), "r" (_func), "r" (_arg));
|
||||
platform_execute((void *)(_stack + STACK_SIZE), (void *)_func, _arg);
|
||||
}
|
||||
|
||||
/* restore old state */
|
||||
|
@ -31,6 +31,8 @@ class Driver_context : public Genode::Signal_context
|
||||
* Perform context operation
|
||||
*/
|
||||
virtual void handle() = 0;
|
||||
|
||||
virtual char const *debug() = 0;
|
||||
};
|
||||
|
||||
|
||||
|
@ -43,6 +43,8 @@ class Event_context : public Driver_context
|
||||
|
||||
void handle() {
|
||||
Routine::schedule_all(); }
|
||||
|
||||
char const *debug() { return "Event_context"; }
|
||||
};
|
||||
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
#include <signal.h>
|
||||
#include <lx_emul.h>
|
||||
|
||||
#include <dma.h>
|
||||
extern "C" {
|
||||
#include <dde_kit/interrupt.h>
|
||||
}
|
||||
@ -93,18 +93,13 @@ class Irq_context : public Driver_context,
|
||||
/* report IRQ to all clients */
|
||||
for (Irq_handler *h = _handler_list.first(); h; h = h->next()) {
|
||||
irqreturn_t rc;
|
||||
do {
|
||||
rc = h->handler(_irq, h->dev);
|
||||
}
|
||||
while (rc == IRQ_HANDLED);
|
||||
dde_kit_log(DEBUG_IRQ, "IRQ: %u ret: %u", _irq, rc);
|
||||
if (rc == IRQ_HANDLED) {
|
||||
if ((rc = h->handler(_irq, h->dev)) == IRQ_HANDLED)
|
||||
Routine::schedule_all();
|
||||
return;
|
||||
}
|
||||
dde_kit_log(DEBUG_IRQ, "IRQ: %u ret: %u", _irq, rc);
|
||||
}
|
||||
}
|
||||
|
||||
const char *debug() { return "Irq_context"; }
|
||||
/**
|
||||
* Request an IRQ
|
||||
*/
|
||||
|
@ -59,6 +59,7 @@ class Timer_context : public Driver_context
|
||||
dde_kit_timer_schedule_absolute(_dde_timer, expires);
|
||||
}
|
||||
|
||||
char const *debug() { return "Timer_context"; }
|
||||
/**
|
||||
* Return true if timer is pending
|
||||
*/
|
||||
|
@ -73,6 +73,7 @@ namespace Block {
|
||||
~Signal_dispatcher() { sig_rec->dissolve(this); }
|
||||
|
||||
void handle() { (obj.*member)(); }
|
||||
char const *debug() { return "Block_context"; }
|
||||
};
|
||||
|
||||
|
||||
|
@ -27,6 +27,13 @@
|
||||
* scsi_scan_host
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009-2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#include <lx_emul.h>
|
||||
|
||||
#include "scsi.h"
|
||||
|
@ -1,7 +1,6 @@
|
||||
TARGET = usb_drv
|
||||
REQUIRES = x86 32bit
|
||||
LIBS = cxx env dde_kit server libc-setjmp signal
|
||||
SRC_CC = main.cc lx_emul.cc pci_driver.cc irq.cc timer.cc event.cc storage.cc \
|
||||
SRC_CC = main.cc lx_emul.cc irq.cc timer.cc event.cc storage.cc \
|
||||
input_component.cc
|
||||
SRC_C = dummies.c scsi.c evdev.c
|
||||
|
||||
@ -18,7 +17,7 @@ INC_DIR += $(CONTRIB_DIR)/include
|
||||
INC_DIR += $(shell pwd)
|
||||
|
||||
CC_OPT += -U__linux__ -D__KERNEL__
|
||||
CC_OPT += -DCONFIG_USB_DEVICEFS -DCONFIG_HOTPLUG -DCONFIG_PCI -DDEBUG
|
||||
CC_OPT += -DCONFIG_USB_DEVICEFS -DCONFIG_HOTPLUG -DDEBUG
|
||||
|
||||
CC_WARN = -Wall -Wno-unused-variable -Wno-uninitialized \
|
||||
-Wno-unused-function \
|
||||
@ -37,8 +36,7 @@ SRC_C += $(addprefix usb/core/,$(notdir $(wildcard $(USB_DIR)/core/*.c)))
|
||||
SRC_C += usb/usb-common.c
|
||||
|
||||
# USB host-controller driver
|
||||
#SRC_C += $(addprefix usb/host/,uhci-hcd.c pci-quirks.c ehci-hcd.c ohci-hcd.c)
|
||||
SRC_C += $(addprefix usb/host/,pci-quirks.c uhci-hcd.c ehci-hcd.c)
|
||||
SRC_C += $(addprefix usb/host/, ehci-hcd.c)
|
||||
|
||||
# USB hid
|
||||
SRC_C += $(addprefix hid/usbhid/,hid-core.c hid-quirks.c usbmouse.c usbkbd.c)
|
||||
@ -61,13 +59,48 @@ GEN_INCLUDES := $(shell grep -rh "^\#include .*\/" $(CONTRIB_DIR) |\
|
||||
#
|
||||
# Filter out some black-listed headers
|
||||
#
|
||||
NO_GEN_INCLUDES := ../../scsi/sd.h
|
||||
|
||||
|
||||
########################
|
||||
## Platform specifics ##
|
||||
########################
|
||||
|
||||
SUPPORTED = x86_32 platform_panda
|
||||
|
||||
#
|
||||
# x86_32
|
||||
#
|
||||
ifeq ($(filter-out $(SPECS),x86_32),)
|
||||
INC_DIR += $(PRG_DIR)/x86_32
|
||||
CC_OPT += -DCONFIG_PCI
|
||||
SRC_C += $(addprefix usb/host/,pci-quirks.c uhci-hcd.c)
|
||||
SRC_CC += pci_driver.cc
|
||||
|
||||
#
|
||||
# Panda board
|
||||
#
|
||||
else ifeq ($(filter-out $(SPECS),platform_panda),)
|
||||
CC_OPT += -DCONFIG_USB_EHCI_HCD_OMAP -DCONFIG_USB_EHCI_TT_NEWSCHED -DVERBOSE_DEBUG
|
||||
INC_DIR += $(PRG_DIR)/arm
|
||||
INC_DIR += $(CONTRIB_DIR)/arch/arm/plat-omap/include
|
||||
SRC_C += platform_device.c
|
||||
SRC_CC += platform.cc
|
||||
#SRC_C += $(CONTRIB_DIR)/arch/arm/mach-omap2/usb-host.c
|
||||
#SRC_C += $(DRIVERS_DIR)/mfd/omap-usb-host.c
|
||||
vpath %.c $(PRG_DIR)/arm/platform
|
||||
vpath %.cc $(PRG_DIR)/arm/platform
|
||||
#
|
||||
# Unsupported
|
||||
#
|
||||
else
|
||||
$(error Skip USB because it requires one of the following: $(SUPPORTED))
|
||||
endif
|
||||
|
||||
#
|
||||
# Filter out original Linux headers that exist in the contrib directory
|
||||
#
|
||||
NO_GEN_INCLUDES := $(shell cd $(CONTRIB_DIR)/include; find -name "*.h" | sed "s/.\///")
|
||||
GEN_INCLUDES := $(filter-out $(NO_GEN_INCLUDES),$(GEN_INCLUDES))
|
||||
GEN_INCLUDES := $(filter-out $(NO_GEN_INCLUDES),$(GEN_INCLUDES))
|
||||
|
||||
#
|
||||
# Make sure to create the header symlinks prior building
|
||||
|
18
dde_linux/src/drivers/usb/x86_32/platform/lx_emul.h
Normal file
18
dde_linux/src/drivers/usb/x86_32/platform/lx_emul.h
Normal file
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* \brief Platform specific part of the Linux API emulation
|
||||
* \author Sebastian Sumpf
|
||||
* \date 2012-06-18
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _X86_32__PLATFORM__LX_EMUL_
|
||||
#define _X86_32__PLATFORM__LX_EMUL_
|
||||
|
||||
|
||||
#endif /* _X86_32__PLATFORM__LX_EMUL_ */
|
38
dde_linux/src/drivers/usb/x86_32/platform/platform.h
Normal file
38
dde_linux/src/drivers/usb/x86_32/platform/platform.h
Normal file
@ -0,0 +1,38 @@
|
||||
/**
|
||||
* \brief Platform specific code
|
||||
* \author Sebastian Sumpf
|
||||
* \date 2012-06-10
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _X86_32__PLATFORM_H_
|
||||
#define _X86_32__PLATFORM_H_
|
||||
|
||||
static inline
|
||||
void platform_execute(void *sp, void *func, void *arg)
|
||||
{
|
||||
asm volatile ("movl %2, 0(%0);"
|
||||
"movl %1, -0x4(%0);"
|
||||
"movl %0, %%esp;"
|
||||
"call *-4(%%esp);"
|
||||
: : "r" (sp), "r" (func), "r" (arg));
|
||||
}
|
||||
|
||||
extern "C" void module_ehci_hcd_init();
|
||||
extern "C" void module_uhci_hcd_init();
|
||||
|
||||
static inline void platform_hcd_init(void)
|
||||
{
|
||||
|
||||
/* ehci_hcd should always be loaded before uhci_hcd and ohci_hcd, not after */
|
||||
module_ehci_hcd_init();
|
||||
module_uhci_hcd_init();
|
||||
}
|
||||
|
||||
#endif /* _X86_32__PLATFORM_H_ */
|
@ -1,6 +1,11 @@
|
||||
LIBC_GEN_ARM_DIR = $(LIBC_DIR)/libc/arm/gen
|
||||
|
||||
SRC_S = _setjmp.S setjmp.S
|
||||
SRC_S = _setjmp.S setjmp.S
|
||||
|
||||
#
|
||||
# Remove 'longjmperror' call
|
||||
#
|
||||
CC_OPT += -D_STANDALONE
|
||||
|
||||
include $(REP_DIR)/lib/mk/libc-common.inc
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user