CONFIG_BAYCOM_SER_FDX=m
CONFIG_BAYCOM_SER_HDX=m
CONFIG_BINFMT_MISC=m
+# CONFIG_BT_HCIBCM203X is not set
+# CONFIG_BT_HCIBFUSB is not set
+# CONFIG_BT_HCIBPA10X is not set
+# CONFIG_BT_HCIUSB is not set
CONFIG_CIFS_DEBUG2=y
CONFIG_CIFS_EXPERIMENTAL=y
CONFIG_CIFS_STATS2=y
# CONFIG_SIBYTE_RHONE is not set
# CONFIG_SIBYTE_SENTOSA is not set
# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SND_USB_AUDIO is not set
CONFIG_SOFT_WATCHDOG=m
# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_SYN_COOKIES=y
# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_TRAD_SIGNALS=y
# CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_USB is not set
+CONFIG_USB=y
+# CONFIG_USBPCWATCHDOG is not set
+# CONFIG_USB_ACM is not set
+CONFIG_USB_ADM5120_HCD=y
+# CONFIG_USB_ATM is not set
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_SERIAL is not set
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_USB_USBNET_MII is not set
+# CONFIG_USB_ZD1201 is not set
CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_ZD1211RW is not set
# Makefile for the ADMtek ADM5120 SoC specific parts of the kernel
#
-obj-y := setup.o prom.o irq.o memory.o mipsIRQ.o adm5120_info.o
+obj-y := setup.o prom.o irq.o memory.o int-handler.o adm5120_info.o
EXTRA_AFLAGS := $(CFLAGS)
*/
static void __init detect_board_type(void)
{
- /* FIXME: not yet implemented */
+ switch(adm5120_info.boot_loader) {
+ case BOOT_LOADER_CFE:
+ adm5120_info.board_type = BOARD_TYPE_WP54G_WRT;
+ adm5120_info.iface_num = 2;
+ adm5120_info.has_usb = 0;
+ printk("Board is a Compex WP54G-WRT\n");
+ default:
+ adm5120_info.board_type = BOARD_TYPE_UNKNOWN;
+ printk("Board type is unknown\n");
+ }
}
void __init adm5120_info_show(void)
--- /dev/null
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999, 2000 MIPS Technologies, Inc. All rights reserved.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ *
+ * Interrupt exception dispatch code.
+ *
+ */
+#include <linux/autoconf.h>
+
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+#define STATUS_IE 0x00000001
+
+/* A lot of complication here is taken away because:
+ *
+ * 1) We handle one interrupt and return, sitting in a loop and moving across
+ * all the pending IRQ bits in the cause register is _NOT_ the answer, the
+ * common case is one pending IRQ so optimize in that direction.
+ *
+ * 2) We need not check against bits in the status register IRQ mask, that
+ * would make this routine slow as hell.
+ *
+ * 3) Linux only thinks in terms of all IRQs on or all IRQs off, nothing in
+ * between like BSD spl() brain-damage.
+ *
+ * Furthermore, the IRQs on the MIPS board look basically (barring software
+ * IRQs which we don't use at all and all external interrupt sources are
+ * combined together on hardware interrupt 0 (MIPS IRQ 2)) like:
+ *
+ * MIPS IRQ Source
+ * -------- ------
+ * 0 Software (ignored)
+ * 1 Software (ignored)
+ * 2 Combined hardware interrupt (hw0)
+ * 3 Hardware (ignored)
+ * 4 Hardware (ignored)
+ * 5 Hardware (ignored)
+ * 6 Hardware (ignored)
+ * 7 R4k timer (what we use)
+ *
+ * Note: On the SEAD board thing are a little bit different.
+ * Here IRQ 2 (hw0) is wired to the UART0 and IRQ 3 (hw1) is wired
+ * wired to UART1.
+ *
+ * We handle the IRQ according to _our_ priority which is:
+ *
+ * Highest ---- R4k Timer
+ * Lowest ---- Combined hardware interrupt
+ *
+ * then we just return, if multiple IRQs are pending then we will just take
+ * another exception, big deal.
+ */
+
+ .text
+ .set noreorder
+ .set noat
+ .align 5
+
+NESTED(mipsIRQ, PT_SIZE, sp)
+ SAVE_ALL
+ CLI
+ .set at
+
+ mfc0 s0, CP0_CAUSE
+ mfc0 s1, CP0_STATUS
+ and s0, s0, s1
+
+ /* First we check for r4k counter/timer IRQ. */
+ andi a0, s0, CAUSEF_IP7
+ beq a0, zero, 1f
+ nop
+
+ move a0, sp
+ jal mips_timer_interrupt
+ nop
+
+ j ret_from_irq
+ nop
+
+1:
+ andi a0, s0, CAUSEF_IP2
+ beq a0, zero, 1f
+ nop
+
+ move a0, sp
+ jal adm5120_hw0_irqdispatch
+ nop
+1:
+ j ret_from_irq
+ nop
+
+END(mipsIRQ)
+
+
+LEAF(mips_int_lock)
+ .set noreorder
+ mfc0 v0, CP0_STATUS
+ li v1, ~STATUS_IE
+ and v1, v1, v0
+ mtc0 v1, CP0_STATUS
+ j ra
+ and v0, v0, STATUS_IE
+ .set reorder
+END(mips_int_lock)
+
+
+LEAF(mips_int_unlock)
+ mfc0 v0, CP0_STATUS
+ and a0, a0, STATUS_IE
+ or v0, v0, a0
+ mtc0 v0, CP0_STATUS
+ j ra
+ nop
+END(mips_int_unlock)
+
+++ /dev/null
-/*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 1999, 2000 MIPS Technologies, Inc. All rights reserved.
- *
- * ########################################################################
- *
- * This program is free software; you can distribute it and/or modify it
- * under the terms of the GNU General Public License (Version 2) as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- *
- * Interrupt exception dispatch code.
- *
- */
-#include <linux/autoconf.h>
-
-#include <asm/asm.h>
-#include <asm/mipsregs.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-
-#define STATUS_IE 0x00000001
-
-/* A lot of complication here is taken away because:
- *
- * 1) We handle one interrupt and return, sitting in a loop and moving across
- * all the pending IRQ bits in the cause register is _NOT_ the answer, the
- * common case is one pending IRQ so optimize in that direction.
- *
- * 2) We need not check against bits in the status register IRQ mask, that
- * would make this routine slow as hell.
- *
- * 3) Linux only thinks in terms of all IRQs on or all IRQs off, nothing in
- * between like BSD spl() brain-damage.
- *
- * Furthermore, the IRQs on the MIPS board look basically (barring software
- * IRQs which we don't use at all and all external interrupt sources are
- * combined together on hardware interrupt 0 (MIPS IRQ 2)) like:
- *
- * MIPS IRQ Source
- * -------- ------
- * 0 Software (ignored)
- * 1 Software (ignored)
- * 2 Combined hardware interrupt (hw0)
- * 3 Hardware (ignored)
- * 4 Hardware (ignored)
- * 5 Hardware (ignored)
- * 6 Hardware (ignored)
- * 7 R4k timer (what we use)
- *
- * Note: On the SEAD board thing are a little bit different.
- * Here IRQ 2 (hw0) is wired to the UART0 and IRQ 3 (hw1) is wired
- * wired to UART1.
- *
- * We handle the IRQ according to _our_ priority which is:
- *
- * Highest ---- R4k Timer
- * Lowest ---- Combined hardware interrupt
- *
- * then we just return, if multiple IRQs are pending then we will just take
- * another exception, big deal.
- */
-
- .text
- .set noreorder
- .set noat
- .align 5
-
-NESTED(mipsIRQ, PT_SIZE, sp)
- SAVE_ALL
- CLI
- .set at
-
- mfc0 s0, CP0_CAUSE
- mfc0 s1, CP0_STATUS
- and s0, s0, s1
-
- /* First we check for r4k counter/timer IRQ. */
- andi a0, s0, CAUSEF_IP7
- beq a0, zero, 1f
- nop
-
- move a0, sp
- jal mips_timer_interrupt
- nop
-
- j ret_from_irq
- nop
-
-1:
- andi a0, s0, CAUSEF_IP2
- beq a0, zero, 1f
- nop
-
- move a0, sp
- jal adm5120_hw0_irqdispatch
- nop
-1:
- j ret_from_irq
- nop
-
-END(mipsIRQ)
-
-
-LEAF(mips_int_lock)
- .set noreorder
- mfc0 v0, CP0_STATUS
- li v1, ~STATUS_IE
- and v1, v1, v0
- mtc0 v1, CP0_STATUS
- j ra
- and v0, v0, STATUS_IE
- .set reorder
-END(mips_int_lock)
-
-
-LEAF(mips_int_unlock)
- mfc0 v0, CP0_STATUS
- and a0, a0, STATUS_IE
- or v0, v0, a0
- mtc0 v0, CP0_STATUS
- j ra
- nop
-END(mips_int_unlock)
-
* Which again was based on the ohci and uhci drivers.
*/
-#include <linux/autoconf.h>
-#include <linux/moduleparam.h>
-#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
#include <linux/errno.h>
-#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/list.h>
#include <linux/usb.h>
#include <linux/platform_device.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/byteorder.h>
+#include <asm/mach-adm5120/adm5120_info.h>
+
#include "../core/hcd.h"
MODULE_DESCRIPTION("ADM5120 USB Host Controller Driver");
#define ED(ed) ((struct admhcd_ed *)(((u32)(ed)) & ~0xf))
struct admhcd {
+ spinlock_t lock;
+
+ void __iomem *addr_reg;
+ void __iomem *data_reg;
+ /* Root hub registers */
+ u32 rhdesca;
+ u32 rhdescb;
+ u32 rhstatus;
+ u32 rhport[2];
+
+ /* async schedule: control, bulk */
+ struct list_head async;
u32 base;
u32 dma_en;
- spinlock_t lock;
unsigned long flags;
+
};
-#define hcd_to_admhcd(hcd) ((struct admhcd *)(hcd)->hcd_priv)
+static inline struct admhcd *hcd_to_admhcd(struct usb_hcd *hcd)
+{
+ return (struct admhcd *)(hcd->hcd_priv);
+}
+
+static inline struct usb_hcd *admhcd_to_hcd(struct admhcd *admhcd)
+{
+ return container_of((void *)admhcd, struct usb_hcd, hcd_priv);
+}
static char hcd_name[] = "adm5120-hcd";
.hub_control = admhcd_hub_control,
};
+#define resource_len(r) (((r)->end - (r)->start) + 1)
+
static int __init adm5120hcd_probe(struct platform_device *pdev)
{
struct usb_hcd *hcd;
struct admhcd *ahcd;
struct usb_device *udev;
- int err = 0;
+ struct resource *addr, *data;
+ void __iomem *addr_reg;
+ void __iomem *data_reg;
+ int irq, err = 0;
- if (!request_mem_region(pdev->resource[0].start,
- pdev->resource[0].end - pdev->resource[0].start, hcd_name)) {
- pr_debug("couldn't request mem\n");
- err = -EBUSY;
+ if (pdev->num_resources < 3) {
+ err = -ENODEV;
goto out;
}
- //hcd = usb_create_hcd(&adm5120_hc_driver, pdev, pdev->bus_id);
- if (!hcd)
- goto out_mem;
+ data = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ addr = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ irq = platform_get_irq(pdev, 0);
- ahcd = hcd_to_admhcd(hcd);
- dev_set_drvdata(pdev, ahcd);
- hcd->self.controller = pdev;
- //hcd->self.bus_name = pdev->bus_id;
- hcd->irq = pdev->resource[1].start;
- hcd->regs = (void *)pdev->resource[0].start;
- hcd->product_desc = hcd_name;
- ahcd->base = pdev->resource[0].start;
-
- if (request_irq(pdev->resource[1].start, adm5120hcd_irq, 0, hcd_name,
- hcd)) {
- pr_debug("couldn't request irq\n");
+ if (!addr || !data || irq < 0) {
+ err = -ENODEV;
+ goto out;
+ }
+
+ if (pdev->dev.dma_mask) {
+ printk(KERN_DEBUG "DMA not supported\n");
+ err = -EINVAL;
+ goto out;
+ }
+
+ if (!request_mem_region(addr->start, 2, hcd_name)) {
+ err = -EBUSY;
+ goto out;
+ }
+ addr_reg = ioremap(addr->start, resource_len(addr));
+ if (addr_reg == NULL) {
+ err = -ENOMEM;
+ goto out_mem;
+ }
+ if (!request_mem_region(data->start, 2, hcd_name)) {
err = -EBUSY;
- goto out_hcd;
+ goto out_unmap;
+ }
+ data_reg = ioremap(data->start, resource_len(data));
+ if (data_reg == NULL) {
+ err = -ENOMEM;
+ goto out_mem;
}
+
- //err = usb_register_bus(&hcd->self);
- //if (err < 0)
- // goto out_irq;
+ hcd = usb_create_hcd(&adm5120_hc_driver, &pdev->dev, pdev->dev.bus_id);
+ if (!hcd)
+ goto out_mem;
+ ahcd = hcd_to_admhcd(hcd);
+ ahcd->data_reg = data_reg;
+ ahcd->addr_reg = addr_reg;
spin_lock_init(&ahcd->lock);
+ INIT_LIST_HEAD(&ahcd->async);
+ /* Initialise the HCD registers */
admhcd_reg_set(ahcd, ADMHCD_REG_INTENABLE, 0);
mdelay(10);
admhcd_reg_set(ahcd, ADMHCD_REG_CONTROL, ADMHCD_SW_RESET);
admhcd_reg_set(ahcd, ADMHCD_REG_RHDESCR, ADMHCD_NPS | ADMHCD_LPSC);
admhcd_reg_set(ahcd, ADMHCD_REG_HOSTCONTROL, ADMHCD_STATE_OP);
- udev = usb_alloc_dev(NULL, &hcd->self, 0);
- if (!udev) {
- err = -ENOMEM;
- goto out_bus;
- }
-
- udev->speed = USB_SPEED_FULL;
- hcd->state = HC_STATE_RUNNING;
-
- //err = hcd_register_root(udev, hcd);
- //if (err != 0) {
- // usb_put_dev(udev);
- // goto out_dev;
- //}
+ err = usb_add_hcd(hcd, irq, IRQF_DISABLED);
+ if (err)
+ goto out_dev;
return 0;
out_dev:
- usb_put_dev(udev);
-out_bus:
- //usb_deregister_bus(&hcd->self);
+ usb_put_hcd(hcd);
out_irq:
free_irq(pdev->resource[1].start, hcd);
+out_unmap:
+ iounmap(addr_reg);
out_hcd:
usb_put_hcd(hcd);
out_mem:
- release_mem_region(pdev->resource[0].start,
- pdev->resource[0].end - pdev->resource[0].start);
+ release_mem_region(addr->start, 2);
out:
return err;
}
static int __init_or_module adm5120hcd_remove(struct platform_device *pdev)
{
- device_init_wakeup(&pdev->dev, 0);
+ struct usb_hcd *hcd = platform_get_drvdata(pdev);
+ struct admhcd *ahcd;
+ struct resource *res;
+
+ if (!hcd)
+ return 0;
+ ahcd = hcd_to_admhcd(hcd);
+ usb_remove_hcd(hcd);
+
+ usb_put_hcd(hcd);
+ return 0;
}
static struct platform_driver adm5120hcd_driver = {
{
if (usb_disabled())
return -ENODEV;
+ if (!adm5120_info.has_usb)
+ return -ENODEV;
return platform_driver_register(&adm5120hcd_driver);
}