# # Patch managed by http://www.holgerschurig.de/patcher.html # --- linux-2.4.27/arch/arm/mach-sa1100/sa1100_usb.h~sa1100-usb +++ linux-2.4.27/arch/arm/mach-sa1100/sa1100_usb.h @@ -10,6 +10,11 @@ #define _SA1100_USB_H #include +#define SA1100_USB_DEBUG +#ifdef SA1100_USB_DEBUG +extern int sa1100_usb_debug; +#endif + typedef void (*usb_callback_t)(int flag, int size); /* in usb_ctl.c (see also descriptor methods at bottom of file) */ --- linux-2.4.27/arch/arm/mach-sa1100/usb_ctl.c~sa1100-usb +++ linux-2.4.27/arch/arm/mach-sa1100/usb_ctl.c @@ -28,6 +28,12 @@ #include "sa1100_usb.h" #include "usb_ctl.h" +// Toby Churchill Ltd modification to re assert Ser0UDCOMP when it gets corrupted (why?) +// Identified by Chris Jones for TCL. +// Added 25/3/2004 N C Bane for balloon board. +#define TCL_FIX + + ////////////////////////////////////////////////////////////////////////////// // Prototypes ////////////////////////////////////////////////////////////////////////////// @@ -109,6 +115,45 @@ ////////////////////////////////////////////////////////////////////////////// // Async ////////////////////////////////////////////////////////////////////////////// + +#ifdef CONFIG_SA1100_USB_HOTPLUG +// user space notification support for sa1100 usb state change +// Copyright (c) 2003 N C Bane +#include +#include +//static int usb_hotplug_state=USB_STATE_DEFAULT; + +static void do_usb_helper (void *status) +{ + char *argv [3], *envp [3]; + int v; + + argv [0] = "/sbin/sausb-hotplug"; + + argv [1] = device_state_names[(int)status]; + argv [2] = NULL; + + envp [0] = "HOME=/"; + envp [1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin"; + envp [2] = NULL; + + v = call_usermodehelper (argv [0], argv, envp); + + if (v != 0) + printk ("sausb hotplug returned 0x%x", v); +} + +static struct tq_struct usb_task; + +static void usb_helper (int status) { +// usb_hotplug_state = status; + usb_task.routine=do_usb_helper; + usb_task.data=(void *)status; + schedule_task(&usb_task); +} + +#endif + static void core_kicker(void); static inline void enable_resume_mask_suspend( void ); @@ -119,6 +164,7 @@ { __u32 status = Ser0UDCSR; +//static int reset; /* ReSeT Interrupt Request - UDC has been reset */ if ( status & UDCSR_RSTIR ) { @@ -133,6 +179,7 @@ // mask reset ints, they flood during sequence, enable // suspend and resume Ser0UDCCR |= UDCCR_REM; // mask reset +//reset=true; Ser0UDCCR &= ~(UDCCR_SUSIM | UDCCR_RESIM); // enable suspend and resume UDC_flip( Ser0UDCSR, status ); // clear all pending sources return; // <-- no reason to continue if resetting @@ -160,6 +207,13 @@ if (status & UDCSR_EIR) ep0_int_hndlr(); +#ifdef TCL_FIX + if (Ser0UDCOMP!=63) { + printk("%s: Ser0UDCOMP = %d. Reset to 63\n",__FUNCTION__,Ser0UDCOMP); + Ser0UDCOMP=63; + } +#endif + if (status & UDCSR_RIR) ep1_int_hndlr(status); @@ -443,6 +497,12 @@ ) { configured_callback(); } +#ifdef CONFIG_SA1100_USB_HOTPLUG + if (next_device_state == USB_STATE_CONFIGURED) + usb_helper(next_device_state); + if ((next_device_state == USB_STATE_SUSPENDED) && (usbd_info.state == USB_STATE_CONFIGURED)) + usb_helper(next_device_state); +#endif usbd_info.state = next_device_state; ep1_state_change_notify( next_device_state ); ep2_state_change_notify( next_device_state ); @@ -683,6 +743,43 @@ return len; } +#ifdef SA1100_USB_DEBUG +#include /* to copy to/from userspace */ +struct proc_dir_entry *debug_entry; + +static int proc_debug_read (struct file * file, char * buf, + size_t nbytes, loff_t *ppos) +{ + char outputbuf[8]; + int count; + // read completed? + if (*ppos) + return 0; + count=sprintf(outputbuf, "%d\n",sa1100_usb_debug); + if (copy_to_user(buf, outputbuf, count)) + return -EFAULT; + return count; +} + +static ssize_t proc_debug_write(struct file * file, const char * buffer, + size_t count, loff_t *ppos) +{ + char *endp; + if (*ppos) + return -EINVAL; + sa1100_usb_debug = simple_strtoul(buffer,&endp,0); + // we claim all is read + return count; +} + + + +static struct file_operations proc_debug_operations = { + read: proc_debug_read, + write: proc_debug_write +}; + +#endif #endif /* CONFIG_PROC_FS */ ////////////////////////////////////////////////////////////////////////////// @@ -703,6 +800,15 @@ #if CONFIG_PROC_FS create_proc_read_entry ( PROC_NODE_NAME, 0, NULL, usbctl_read_proc, NULL); +#ifdef SA1100_USB_DEBUG + { + debug_entry = create_proc_entry("sa1100_usb_debug", + S_IWUSR |S_IRUSR | S_IRGRP | S_IROTH, + &proc_root); + if (debug_entry) + debug_entry->proc_fops = &proc_debug_operations; + } +#endif #endif /* setup rx dma */ @@ -751,6 +857,9 @@ #if CONFIG_PROC_FS remove_proc_entry ( PROC_NODE_NAME, NULL); +#ifdef SA1100_USB_DEBUG + remove_proc_entry("sa1100_usb_debug",&proc_root); +#endif #endif sa1100_free_dma(usbd_info.dmach_rx); @@ -769,6 +878,10 @@ EXPORT_SYMBOL( sa1100_usb_get_string_descriptor ); EXPORT_SYMBOL( sa1100_usb_kmalloc_string_descriptor ); +#ifdef SA1100_USB_DEBUG +int sa1100_usb_debug=0; +EXPORT_SYMBOL(sa1100_usb_debug); +#endif module_init( usbctl_init ); module_exit( usbctl_exit ); --- linux-2.4.27/arch/arm/config.in~sa1100-usb +++ linux-2.4.27/arch/arm/config.in @@ -138,6 +138,9 @@ dep_bool ' Yopy' CONFIG_SA1100_YOPY $CONFIG_ARCH_SA1100 dep_tristate 'SA1100 USB function support' CONFIG_SA1100_USB $CONFIG_ARCH_SA1100 +if [ "$CONFIG_SA1100_USB" != "n" ]; then + bool ' Support for SA11x0 USB usb-hotplug' CONFIG_SA1100_USB_HOTPLUG +fi dep_tristate ' Support for SA11x0 USB network link function' CONFIG_SA1100_USB_NETLINK $CONFIG_SA1100_USB dep_tristate ' Support for SA11x0 USB character device emulation' CONFIG_SA1100_USB_CHAR $CONFIG_SA1100_USB